Esempio n. 1
0
File: 53c8xx.c Progetto: DonCN/haiku
/* When an inquiry succeeds the negotiator gets the option to attempt to
** request a better transfer agreement with the target.
*/
static void negotiator(Symbios *s, SymTarg *targ, uchar *ident, uchar *msg)
{
	if(ident[7] & 0x20){ /* wide supported */
		if(targ->flags & tf_ask_wide){
			uchar cmd[6] = { 0, 0, 0, 0, 0, 0 };
			targ->flags &= (~tf_ask_wide); /* only ask once */

			dprintf("symbios%ld: negotiating wide xfer with target %ld\n",
			s->num,targ->id);

			msg[1] = 0x01; /* extended message */
			msg[2] = 0x02; /* length           */
			msg[3] = 0x03; /* sync negotiate   */
			msg[4] = 0x01; /* 16 bit wide      */

			exec_io(targ, cmd, 6, msg, 5, NULL, 0, 0);
		}
	}

	if(ident[7] & 0x10){ /* sync supported */
		if(targ->flags & tf_ask_sync) {
			uchar cmd[6] = { 0, 0, 0, 0, 0, 0 };

			targ->flags &= (~tf_ask_sync); /* only ask once */

			dprintf("symbios%ld: negotiating sync xfer with target %ld\n",
			s->num,targ->id);

			msg[1] = 0x01; /* extended message */
			msg[2] = 0x03; /* length           */
			msg[3] = 0x01; /* sync negotiate   */
			msg[4] = s->syncinfo[0].period / 4; /* sync period / 4  */
			msg[5] = s->maxoffset;

			exec_io(targ, cmd, 6, msg, 6, NULL, 0, 0);
		}
	}
}
Esempio n. 2
0
File: 53c8xx.c Progetto: DonCN/haiku
/* Convert a CCB_SCSIIO into a BL_CCB32 and (possibly SG array).
**
*/
static long sim_execute_scsi_io(Symbios *s, CCB_HEADER *ccbh)
{
	CCB_SCSIIO *ccb = (CCB_SCSIIO *) ccbh;
	uchar *cdb;
	physical_entry pe[2];
	SymTarg *targ;
	uchar msg[8];

	targ = s->targ + ccb->cam_ch.cam_target_id;

	if(targ->flags & tf_ignore){
		ccbh->cam_status = CAM_SEL_TIMEOUT;
		return B_OK;
	}

	if(ccb->cam_ch.cam_flags & CAM_CDB_POINTER) {
		cdb = ccb->cam_cdb_io.cam_cdb_ptr;
	} else {
		cdb = ccb->cam_cdb_io.cam_cdb_bytes;
	}

	get_memory_map((void*) (ccb->cam_sim_priv), 1536, pe, 2);

	/* identify message */
	msg[0] = 0xC0 | (ccb->cam_ch.cam_target_lun & 0x07);

	/* fill out table */
	prep_io((SymPriv *) ccb->cam_sim_priv, (uint32) pe[0].address);

	/* insure only one transaction at a time for any given target */
	acquire_sem(targ->sem_targ);

	targ->priv = (SymPriv *) ccb->cam_sim_priv;;
	targ->priv_phys = (uint32 ) pe[0].address;

	targ->inbound = (ccb->cam_ch.cam_flags & CAM_DIR_IN) ? 1 : 0;

	if(ccb->cam_ch.cam_flags & CAM_SCATTER_VALID){
		exec_io(targ, cdb, ccb->cam_cdb_len, msg, 1,
				ccb->cam_data_ptr, ccb->cam_sglist_cnt, 1);
	} else {
		exec_io(targ, cdb, ccb->cam_cdb_len, msg, 1,
				ccb->cam_data_ptr, ccb->cam_dxfer_len, 0);
	}

/*	dprintf("symbios%d: state = 0x%02x, status = 0x%02x\n",
			s->num,targ->state,targ->priv->status[0]);*/

	/* decode status */
	switch(targ->status){
	case status_complete:
		if((ccb->cam_scsi_status=targ->priv->_status[0]) != 0) {
			ccbh->cam_status = CAM_REQ_CMP_ERR;

			/* nonzero status is an error ... 0x02 = check condition */
			if((ccb->cam_scsi_status == 0x02) &&
			   !(ccb->cam_ch.cam_flags & CAM_DIS_AUTOSENSE) &&
			   ccb->cam_sense_ptr && ccb->cam_sense_len){
				   uchar command[6];

				   command[0] = 0x03;		/* request_sense */
				   command[1] = ccb->cam_ch.cam_target_lun << 5;
				   command[2] = 0;
				   command[3] = 0;
				   command[4] = ccb->cam_sense_len;
				   command[5] = 0;

				   targ->inbound = 1;
				   exec_io(targ, command, 6, msg, 1,
						   ccb->cam_sense_ptr, ccb->cam_sense_len, 0);

				   if(targ->priv->_status[0]){
					   ccb->cam_ch.cam_status |= CAM_AUTOSENSE_FAIL;
				   } else {
					   ccb->cam_ch.cam_status |= CAM_AUTOSNS_VALID;
				   }
			}
		} else {
			ccbh->cam_status = CAM_REQ_CMP;

			if(cdb[0] == 0x12) {
				/* inquiry just succeeded ... is it non SG and with enough data to
				   snoop the support bits? */
				if(!(ccb->cam_ch.cam_flags & CAM_SCATTER_VALID) && (ccb->cam_dxfer_len>7)){
					negotiator(s, targ, ccb->cam_data_ptr, msg);
				}
			}
		}
		break;

	case status_timeout:
		ccbh->cam_status = CAM_SEL_TIMEOUT;
		break;

	default: // XXX
		ccbh->cam_status = CAM_SEL_TIMEOUT;
	}

	targ->status = status_inactive;
//	dprintf("symbios%d: releasing targ @ 0x%08x\n",s->num,targ);
	release_sem(targ->sem_targ);
	return B_OK;
}
Esempio n. 3
0
/*
 * Fetches the resource denoted by |uri|.
 */
static void fetch_uri(const struct URI *uri)
{
  spdylay_session_callbacks callbacks;
  int fd;
  SSL_CTX *ssl_ctx;
  SSL *ssl;
  struct Request req;
  struct Connection connection;
  int rv;
  nfds_t npollfds = 1;
  struct pollfd pollfds[1];
  uint16_t spdy_proto_version;

  request_init(&req, uri);

  setup_spdylay_callbacks(&callbacks);

  /* Establish connection and setup SSL */
  fd = connect_to(req.host, req.port);
  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
  if(ssl_ctx == NULL) {
    dief("SSL_CTX_new", ERR_error_string(ERR_get_error(), NULL));
  }
  init_ssl_ctx(ssl_ctx, &spdy_proto_version);
  ssl = SSL_new(ssl_ctx);
  if(ssl == NULL) {
    dief("SSL_new", ERR_error_string(ERR_get_error(), NULL));
  }
  /* To simplify the program, we perform SSL/TLS handshake in blocking
     I/O. */
  ssl_handshake(ssl, fd);

  connection.ssl = ssl;
  connection.want_io = IO_NONE;

  /* Here make file descriptor non-block */
  make_non_block(fd);
  set_tcp_nodelay(fd);

  printf("[INFO] SPDY protocol version = %d\n", spdy_proto_version);
  rv = spdylay_session_client_new(&connection.session, spdy_proto_version,
                                  &callbacks, &connection);
  if(rv != 0) {
    diec("spdylay_session_client_new", rv);
  }

  /* Submit the HTTP request to the outbound queue. */
  submit_request(&connection, &req);

  pollfds[0].fd = fd;
  ctl_poll(pollfds, &connection);

  /* Event loop */
  while(spdylay_session_want_read(connection.session) ||
        spdylay_session_want_write(connection.session)) {
    int nfds = poll(pollfds, npollfds, -1);
    if(nfds == -1) {
      dief("poll", strerror(errno));
    }
    if(pollfds[0].revents & (POLLIN | POLLOUT)) {
      exec_io(&connection);
    }
    if((pollfds[0].revents & POLLHUP) || (pollfds[0].revents & POLLERR)) {
      die("Connection error");
    }
    ctl_poll(pollfds, &connection);
  }

  /* Resource cleanup */
  spdylay_session_del(connection.session);
  SSL_shutdown(ssl);
  SSL_free(ssl);
  SSL_CTX_free(ssl_ctx);
  shutdown(fd, SHUT_WR);
  close(fd);
  request_free(&req);
}
Esempio n. 4
0
/*
 * Fetches the resource denoted by |uri|.
 */
static void fetch_uri(const struct URI *uri)
{
  spdylay_session_callbacks callbacks;
  int fd;
  struct Request req;
  struct Connection connection;
  int rv;
  nfds_t npollfds = 1;
  struct pollfd pollfds[1];
  uint16_t spdy_proto_version = 3;

  request_init(&req, uri);

  setup_spdylay_callbacks(&callbacks);

  /* Establish connection and setup SSL */
  fd = connect_to(req.host, req.port);
  if (-1 == fd)
    abort ();

  connection.fd = fd;
  connection.want_io = IO_NONE;

  /* Here make file descriptor non-block */
  make_non_block(fd);
  set_tcp_nodelay(fd);

  printf("[INFO] SPDY protocol version = %d\n", spdy_proto_version);
  rv = spdylay_session_client_new(&connection.session, spdy_proto_version,
                                  &callbacks, &connection);
  if(rv != 0) {
    diec("spdylay_session_client_new", rv);
  }

  /* Submit the HTTP request to the outbound queue. */
  submit_request(&connection, &req);

  pollfds[0].fd = fd;
  ctl_poll(pollfds, &connection);

  /* Event loop */
  while(spdylay_session_want_read(connection.session) ||
        spdylay_session_want_write(connection.session)) {
    int nfds = poll(pollfds, npollfds, -1);
    if(nfds == -1) {
      dief("poll", strerror(errno));
    }
    if(pollfds[0].revents & (POLLIN | POLLOUT)) {
      exec_io(&connection);
    }
    if((pollfds[0].revents & POLLHUP) || (pollfds[0].revents & POLLERR)) {
      die("Connection error");
    }
    ctl_poll(pollfds, &connection);
  }

  /* Resource cleanup */
  spdylay_session_del(connection.session);
  shutdown(fd, SHUT_WR);
  MHD_socket_close_(fd);
  request_free(&req);
}