FreeBSD/usr.sbin/camdd/camdd.c
/*
 * Execute one command from the run queue.  Returns 0 for success, 1 for
 * stop processing, and -1 for error.
 */
Execute one command from the run queue.  Returns 0 for success, 1 for
stop processing, and -1 for error.
Execute one command from the run queue . Returns 0 for success 1 for stop processing and - 1 for error .
int
camdd_pass_run(struct camdd_dev *dev)
{
	struct camdd_buf *buf = NULL;
	struct camdd_dev_pass *pass_dev = &dev->dev_spec.pass;
	struct camdd_buf_data *data;
	uint32_t num_blocks, sectors_used = 0;
	union ccb *ccb;
	int retval = 0, is_write = dev->write_dev;
	int double_buf_needed = 0;
	buf = STAILQ_FIRST(&dev->run_queue);
	if (buf == NULL) {
		retval = 1;
		goto bailout;
	}
	if (is_write != 0) {
		retval = camdd_buf_sg_create(buf,  0,dev->sector_size,
		    &sectors_used, &double_buf_needed);
		if (retval != 0) {
			retval = -1;
			goto bailout;
		}
	}
	STAILQ_REMOVE(&dev->run_queue, buf, camdd_buf, links);
	dev->num_run_queue--;
	data = &buf->buf_type_spec.data;
	ccb = &data->ccb;
	CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
	if (is_write != 0)
		num_blocks = sectors_used;
	else
		num_blocks = data->fill_len / pass_dev->block_len;
	scsi_read_write(&ccb->csio,
			 dev->retry_count,
			 NULL,
			 MSG_SIMPLE_Q_TAG,
			 (dev->write_dev == 0) ? SCSI_RW_READ :
				   SCSI_RW_WRITE,
			 0,
			 dev->min_cmd_size,
			 buf->lba,
			 num_blocks,
			 (data->sg_count != 0) ?
				     (uint8_t *)data->segs : data->buf,
			 (num_blocks * pass_dev->block_len),
			 SSD_FULL_SIZE,
			 dev->io_timeout);
	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
	if (dev->retry_count != 0)
		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
	if (data->sg_count != 0) {
		ccb->csio.sglist_cnt = data->sg_count;
		ccb->ccb_h.flags |= CAM_DATA_SG;
	}
	ccb->ccb_h.ccb_buf = buf;
	pthread_mutex_unlock(&dev->mutex);
	if (ioctl(pass_dev->dev->fd, CAMIOQUEUE, ccb) == -1) {
		pthread_mutex_lock(&dev->mutex);
		warn("%s: error sending CAMIOQUEUE ioctl to %s%u", __func__,
		     pass_dev->dev->device_name, pass_dev->dev->dev_unit_num);
		warn("%s: CCB address is %p", __func__, ccb);
		retval = -1;
		STAILQ_INSERT_TAIL(&dev->free_queue, buf, links);
	} else {
		pthread_mutex_lock(&dev->mutex);
		dev->cur_active_io++;
		STAILQ_INSERT_TAIL(&dev->active_queue, buf, links);
	}
bailout:
	return (retval);
}
int camdd_pass_run ( struct camdd_dev * dev ) { struct camdd_buf * buf = NULL ; struct camdd_dev_pass * pass_dev = & dev -> dev_spec . pass ; struct camdd_buf_data * data ; uint32_t num_blocks , sectors_used = 0 ; union ccb * ccb ; int retval = 0 , is_write = dev -> write_dev ; int double_buf_needed = 0 ; buf = STAILQ_FIRST ( & dev -> run_queue ) ; if ( buf == NULL ) { retval = 1 ; goto bailout ; } if ( is_write != 0 ) { retval = camdd_buf_sg_create ( buf , 0 , dev -> sector_size , & sectors_used , & double_buf_needed ) ; if ( retval != 0 ) { retval = -1 ; goto bailout ; } } STAILQ_REMOVE ( & dev -> run_queue , buf , camdd_buf , links ) ; dev -> num_run_queue -- ; data = & buf -> buf_type_spec . data ; ccb = & data -> ccb ; CCB_CLEAR_ALL_EXCEPT_HDR ( & ccb -> csio ) ; if ( is_write != 0 ) num_blocks = sectors_used ; else num_blocks = data -> fill_len / pass_dev -> block_len ; scsi_read_write ( & ccb -> csio , dev -> retry_count , NULL , MSG_SIMPLE_Q_TAG , ( dev -> write_dev == 0 ) ? SCSI_RW_READ : SCSI_RW_WRITE , 0 , dev -> min_cmd_size , buf -> lba , num_blocks , ( data -> sg_count != 0 ) ? ( uint8_t * ) data -> segs : data -> buf , ( num_blocks * pass_dev -> block_len ) , SSD_FULL_SIZE , dev -> io_timeout ) ; ccb -> ccb_h . flags |= CAM_DEV_QFRZDIS ; if ( dev -> retry_count != 0 ) ccb -> ccb_h . flags |= CAM_PASS_ERR_RECOVER ; if ( data -> sg_count != 0 ) { ccb -> csio . sglist_cnt = data -> sg_count ; ccb -> ccb_h . flags |= CAM_DATA_SG ; } ccb -> ccb_h . ccb_buf = buf ; pthread_mutex_unlock ( & dev -> mutex ) ; if ( ioctl ( pass_dev -> dev -> fd , CAMIOQUEUE , ccb ) == -1 ) { pthread_mutex_lock ( & dev -> mutex ) ; warn ( " " , __func__ , pass_dev -> dev -> device_name , pass_dev -> dev -> dev_unit_num ) ; warn ( " " , __func__ , ccb ) ; retval = -1 ; STAILQ_INSERT_TAIL ( & dev -> free_queue , buf , links ) ; } else { pthread_mutex_lock ( & dev -> mutex ) ; dev -> cur_active_io ++ ; STAILQ_INSERT_TAIL ( & dev -> active_queue , buf , links ) ; } bailout : return ( retval ) ; }
Execute one command from the run queue.
Execute one command from the run queue .
/*
	 * If we're writing, we need to go through the source buffer list
	 * and create an S/G list.
	 */ /*iovec*/ /*
	 * In almost every case the number of blocks should be the device
	 * block size.  The exception may be at the end of an I/O stream
	 * for a partial block or at the end of a device.
	 */ /*retries*/ /*cbfcnp*/ /*tag_action*/ /*readop*/ /*byte2*/ /*minimum_cmd_size*/ /*lba*/ /*block_count*/ /*data_ptr*/ /*dxfer_len*/ /*sense_len*/ /*timeout*/ /* Disable freezing the device queue */ /*
	 * Store a pointer to the buffer in the CCB.  The kernel will
	 * restore this when we get it back, and we'll use it to identify
	 * the buffer this CCB came from.
	 */ /*
	 * Unlock our mutex in preparation for issuing the ioctl.
	 */ /*
	 * Queue the CCB to the pass(4) driver.
	 */