kmem_cache_free(host_dev->request_pool, cmd_request);
}
+
+/*
+ * storvsc_queuecommand - Initiate command processing
+ */
+static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd,
+ void (*done)(struct scsi_cmnd *))
+{
+ int ret;
+ struct hv_host_device *host_dev =
+ (struct hv_host_device *)scmnd->device->host->hostdata;
+ struct hv_device *dev = host_dev->dev;
+ struct storvsc_driver *storvsc_drv_obj =
+ drv_to_stordrv(dev->device.driver);
+ struct hv_storvsc_request *request;
+ struct storvsc_cmd_request *cmd_request;
+ unsigned int request_size = 0;
+ int i;
+ struct scatterlist *sgl;
+ unsigned int sg_count = 0;
+ struct vmscsi_request *vm_srb;
+
+
+ /* If retrying, no need to prep the cmd */
+ if (scmnd->host_scribble) {
+ /* ASSERT(scmnd->scsi_done != NULL); */
+
+ cmd_request =
+ (struct storvsc_cmd_request *)scmnd->host_scribble;
+ DPRINT_INFO(STORVSC_DRV, "retrying scmnd %p cmd_request %p",
+ scmnd, cmd_request);
+
+ goto retry_request;
+ }
+
+ /* ASSERT(scmnd->scsi_done == NULL); */
+ /* ASSERT(scmnd->host_scribble == NULL); */
+
+ scmnd->scsi_done = done;
+
+ request_size = sizeof(struct storvsc_cmd_request);
+
+ cmd_request = kmem_cache_zalloc(host_dev->request_pool,
+ GFP_ATOMIC);
+ if (!cmd_request) {
+ scmnd->scsi_done = NULL;
+ return SCSI_MLQUEUE_DEVICE_BUSY;
+ }
+
+ /* Setup the cmd request */
+ cmd_request->bounce_sgl_count = 0;
+ cmd_request->bounce_sgl = NULL;
+ cmd_request->cmd = scmnd;
+
+ scmnd->host_scribble = (unsigned char *)cmd_request;
+
+ request = &cmd_request->request;
+ vm_srb = &request->vstor_packet.vm_srb;
+
+
+ /* Build the SRB */
+ switch (scmnd->sc_data_direction) {
+ case DMA_TO_DEVICE:
+ vm_srb->data_in = WRITE_TYPE;
+ break;
+ case DMA_FROM_DEVICE:
+ vm_srb->data_in = READ_TYPE;
+ break;
+ default:
+ vm_srb->data_in = UNKNOWN_TYPE;
+ break;
+ }
+
+ request->on_io_completion = storvsc_commmand_completion;
+ request->context = cmd_request;/* scmnd; */
+
+ /* request->PortId = scmnd->device->channel; */
+ vm_srb->port_number = host_dev->port;
+ vm_srb->path_id = scmnd->device->channel;
+ vm_srb->target_id = scmnd->device->id;
+ vm_srb->lun = scmnd->device->lun;
+
+ /* ASSERT(scmnd->cmd_len <= 16); */
+ vm_srb->cdb_length = scmnd->cmd_len;
+
+ memcpy(vm_srb->cdb, scmnd->cmnd, vm_srb->cdb_length);
+
+ request->sense_buffer = scmnd->sense_buffer;
+
+
+ request->data_buffer.len = scsi_bufflen(scmnd);
+ if (scsi_sg_count(scmnd)) {
+ sgl = (struct scatterlist *)scsi_sglist(scmnd);
+ sg_count = scsi_sg_count(scmnd);
+
+ /* check if we need to bounce the sgl */
+ if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
+ cmd_request->bounce_sgl =
+ create_bounce_buffer(sgl, scsi_sg_count(scmnd),
+ scsi_bufflen(scmnd));
+ if (!cmd_request->bounce_sgl) {
+ scmnd->scsi_done = NULL;
+ scmnd->host_scribble = NULL;
+ kmem_cache_free(host_dev->request_pool,
+ cmd_request);
+
+ return SCSI_MLQUEUE_HOST_BUSY;
+ }
+
+ cmd_request->bounce_sgl_count =
+ ALIGN(scsi_bufflen(scmnd), PAGE_SIZE) >>
+ PAGE_SHIFT;
+
+ /*
+ * FIXME: We can optimize on reads by just skipping
+ * this
+ */
+ copy_to_bounce_buffer(sgl, cmd_request->bounce_sgl,
+ scsi_sg_count(scmnd));
+
+ sgl = cmd_request->bounce_sgl;
+ sg_count = cmd_request->bounce_sgl_count;
+ }
+
+ request->data_buffer.offset = sgl[0].offset;
+
+ for (i = 0; i < sg_count; i++)
+ request->data_buffer.pfn_array[i] =
+ page_to_pfn(sg_page((&sgl[i])));
+
+ } else if (scsi_sglist(scmnd)) {
+ /* ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); */
+ request->data_buffer.offset =
+ virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1);
+ request->data_buffer.pfn_array[0] =
+ virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT;
+ }
+
+retry_request:
+ /* Invokes the vsc to start an IO */
+ ret = storvsc_drv_obj->on_io_request(dev,
+ &cmd_request->request);
+ if (ret == -1) {
+ /* no more space */
+
+ if (cmd_request->bounce_sgl_count) {
+ /*
+ * FIXME: We can optimize on writes by just skipping
+ * this
+ */
+ copy_from_bounce_buffer(scsi_sglist(scmnd),
+ cmd_request->bounce_sgl,
+ scsi_sg_count(scmnd));
+ destroy_bounce_buffer(cmd_request->bounce_sgl,
+ cmd_request->bounce_sgl_count);
+ }
+
+ kmem_cache_free(host_dev->request_pool, cmd_request);
+
+ scmnd->scsi_done = NULL;
+ scmnd->host_scribble = NULL;
+
+ ret = SCSI_MLQUEUE_DEVICE_BUSY;
+ }
+
+ return ret;
+}
+
+static DEF_SCSI_QCMD(storvsc_queuecommand)
+
/* Static decl */
static int storvsc_probe(struct hv_device *dev);
-static int storvsc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd);
/* The one and only one */
static struct storvsc_driver g_storvsc_drv;
return ret;
}
-/*
- * storvsc_queuecommand - Initiate command processing
- */
-static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd,
- void (*done)(struct scsi_cmnd *))
-{
- int ret;
- struct hv_host_device *host_dev =
- (struct hv_host_device *)scmnd->device->host->hostdata;
- struct hv_device *dev = host_dev->dev;
- struct storvsc_driver *storvsc_drv_obj =
- drv_to_stordrv(dev->device.driver);
- struct hv_storvsc_request *request;
- struct storvsc_cmd_request *cmd_request;
- unsigned int request_size = 0;
- int i;
- struct scatterlist *sgl;
- unsigned int sg_count = 0;
- struct vmscsi_request *vm_srb;
-
-
- /* If retrying, no need to prep the cmd */
- if (scmnd->host_scribble) {
- /* ASSERT(scmnd->scsi_done != NULL); */
-
- cmd_request =
- (struct storvsc_cmd_request *)scmnd->host_scribble;
- DPRINT_INFO(STORVSC_DRV, "retrying scmnd %p cmd_request %p",
- scmnd, cmd_request);
-
- goto retry_request;
- }
-
- /* ASSERT(scmnd->scsi_done == NULL); */
- /* ASSERT(scmnd->host_scribble == NULL); */
-
- scmnd->scsi_done = done;
-
- request_size = sizeof(struct storvsc_cmd_request);
-
- cmd_request = kmem_cache_zalloc(host_dev->request_pool,
- GFP_ATOMIC);
- if (!cmd_request) {
- scmnd->scsi_done = NULL;
- return SCSI_MLQUEUE_DEVICE_BUSY;
- }
-
- /* Setup the cmd request */
- cmd_request->bounce_sgl_count = 0;
- cmd_request->bounce_sgl = NULL;
- cmd_request->cmd = scmnd;
-
- scmnd->host_scribble = (unsigned char *)cmd_request;
-
- request = &cmd_request->request;
- vm_srb = &request->vstor_packet.vm_srb;
-
-
- /* Build the SRB */
- switch (scmnd->sc_data_direction) {
- case DMA_TO_DEVICE:
- vm_srb->data_in = WRITE_TYPE;
- break;
- case DMA_FROM_DEVICE:
- vm_srb->data_in = READ_TYPE;
- break;
- default:
- vm_srb->data_in = UNKNOWN_TYPE;
- break;
- }
-
- request->on_io_completion = storvsc_commmand_completion;
- request->context = cmd_request;/* scmnd; */
-
- /* request->PortId = scmnd->device->channel; */
- vm_srb->port_number = host_dev->port;
- vm_srb->path_id = scmnd->device->channel;
- vm_srb->target_id = scmnd->device->id;
- vm_srb->lun = scmnd->device->lun;
-
- /* ASSERT(scmnd->cmd_len <= 16); */
- vm_srb->cdb_length = scmnd->cmd_len;
-
- memcpy(vm_srb->cdb, scmnd->cmnd, vm_srb->cdb_length);
-
- request->sense_buffer = scmnd->sense_buffer;
-
-
- request->data_buffer.len = scsi_bufflen(scmnd);
- if (scsi_sg_count(scmnd)) {
- sgl = (struct scatterlist *)scsi_sglist(scmnd);
- sg_count = scsi_sg_count(scmnd);
-
- /* check if we need to bounce the sgl */
- if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
- cmd_request->bounce_sgl =
- create_bounce_buffer(sgl, scsi_sg_count(scmnd),
- scsi_bufflen(scmnd));
- if (!cmd_request->bounce_sgl) {
- scmnd->scsi_done = NULL;
- scmnd->host_scribble = NULL;
- kmem_cache_free(host_dev->request_pool,
- cmd_request);
-
- return SCSI_MLQUEUE_HOST_BUSY;
- }
-
- cmd_request->bounce_sgl_count =
- ALIGN(scsi_bufflen(scmnd), PAGE_SIZE) >>
- PAGE_SHIFT;
-
- /*
- * FIXME: We can optimize on reads by just skipping
- * this
- */
- copy_to_bounce_buffer(sgl, cmd_request->bounce_sgl,
- scsi_sg_count(scmnd));
-
- sgl = cmd_request->bounce_sgl;
- sg_count = cmd_request->bounce_sgl_count;
- }
-
- request->data_buffer.offset = sgl[0].offset;
-
- for (i = 0; i < sg_count; i++)
- request->data_buffer.pfn_array[i] =
- page_to_pfn(sg_page((&sgl[i])));
-
- } else if (scsi_sglist(scmnd)) {
- /* ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); */
- request->data_buffer.offset =
- virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1);
- request->data_buffer.pfn_array[0] =
- virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT;
- }
-
-retry_request:
- /* Invokes the vsc to start an IO */
- ret = storvsc_drv_obj->on_io_request(dev,
- &cmd_request->request);
- if (ret == -1) {
- /* no more space */
-
- if (cmd_request->bounce_sgl_count) {
- /*
- * FIXME: We can optimize on writes by just skipping
- * this
- */
- copy_from_bounce_buffer(scsi_sglist(scmnd),
- cmd_request->bounce_sgl,
- scsi_sg_count(scmnd));
- destroy_bounce_buffer(cmd_request->bounce_sgl,
- cmd_request->bounce_sgl_count);
- }
-
- kmem_cache_free(host_dev->request_pool, cmd_request);
-
- scmnd->scsi_done = NULL;
- scmnd->host_scribble = NULL;
-
- ret = SCSI_MLQUEUE_DEVICE_BUSY;
- }
-
- return ret;
-}
-
-static DEF_SCSI_QCMD(storvsc_queuecommand)
-
static int __init storvsc_init(void)
{
int ret;