sizeof(struct vstor_packet) + sizeof(u64),
sizeof(u64)));
- DPRINT_INFO(STORVSC, "max io %u, currently %u\n",
- stor_driver->max_outstanding_req_per_channel,
- STORVSC_MAX_IO_REQUESTS);
-
- /* Setup the dispatch table */
- stor_driver->base.dev_add = storvsc_dev_add;
- stor_driver->base.dev_rm = storvsc_dev_remove;
-
- stor_driver->on_io_request = storvsc_do_io;
return 0;
}
blk_queue_merge_bvec(sdevice->request_queue, storvsc_merge_bvec);
blk_queue_bounce_limit(sdevice->request_queue, BLK_BOUNCE_ANY);
- /* sdevice->timeout = (2000 * HZ);//(75 * HZ); */
return 0;
}
*/
static int storvsc_remove(struct hv_device *dev)
{
- struct storvsc_driver *storvsc_drv_obj =
- drv_to_stordrv(dev->device.driver);
struct Scsi_Host *host = dev_get_drvdata(&dev->device);
struct hv_host_device *host_dev =
(struct hv_host_device *)host->hostdata;
* Call to the vsc driver to let it know that the device is being
* removed
*/
- storvsc_drv_obj->base.dev_rm(dev);
+ storvsc_dev_remove(dev);
if (host_dev->request_pool) {
kmem_cache_destroy(host_dev->request_pool);
static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
sector_t capacity, int *info)
{
- sector_t total_sectors = capacity;
- sector_t cylinder_times_heads = 0;
- sector_t temp = 0;
-
- int sectors_per_track = 0;
- int heads = 0;
- int cylinders = 0;
- int rem = 0;
-
- if (total_sectors > (65535 * 16 * 255))
- total_sectors = (65535 * 16 * 255);
-
- if (total_sectors >= (65535 * 16 * 63)) {
- sectors_per_track = 255;
- heads = 16;
-
- cylinder_times_heads = total_sectors;
- /* sector_div stores the quotient in cylinder_times_heads */
- rem = sector_div(cylinder_times_heads, sectors_per_track);
- } else {
- sectors_per_track = 17;
-
- cylinder_times_heads = total_sectors;
- /* sector_div stores the quotient in cylinder_times_heads */
- rem = sector_div(cylinder_times_heads, sectors_per_track);
-
- temp = cylinder_times_heads + 1023;
- /* sector_div stores the quotient in temp */
- rem = sector_div(temp, 1024);
-
- heads = temp;
-
- if (heads < 4)
- heads = 4;
-
- if (cylinder_times_heads >= (heads * 1024) || (heads > 16)) {
- sectors_per_track = 31;
- heads = 16;
-
- cylinder_times_heads = total_sectors;
- /*
- * sector_div stores the quotient in
- * cylinder_times_heads
- */
- rem = sector_div(cylinder_times_heads,
- sectors_per_track);
- }
-
- if (cylinder_times_heads >= (heads * 1024)) {
- sectors_per_track = 63;
- heads = 16;
+ sector_t nsect = capacity;
+ sector_t cylinders = nsect;
+ int heads, sectors_pt;
- cylinder_times_heads = total_sectors;
- /*
- * sector_div stores the quotient in
- * cylinder_times_heads
- */
- rem = sector_div(cylinder_times_heads,
- sectors_per_track);
- }
- }
-
- temp = cylinder_times_heads;
- /* sector_div stores the quotient in temp */
- rem = sector_div(temp, heads);
- cylinders = temp;
+ /*
+ * We are making up these values; let us keep it simple.
+ */
+ heads = 0xff;
+ sectors_pt = 0x3f; /* Sectors per track */
+ sector_div(cylinders, heads * sectors_pt);
+ if ((sector_t)(cylinders + 1) * heads * sectors_pt < nsect)
+ cylinders = 0xffff;
info[0] = heads;
- info[1] = sectors_per_track;
- info[2] = cylinders;
+ info[1] = sectors_pt;
+ info[2] = (int)cylinders;
- DPRINT_INFO(STORVSC_DRV, "CHS (%d, %d, %d)", cylinders, heads,
- sectors_per_track);
+ DPRINT_INFO(STORVSC_DRV, "CHS (%d, %d, %d)", (int)cylinders, heads,
+ sectors_pt);
return 0;
}
struct scsi_sense_hdr sense_hdr;
struct vmscsi_request *vm_srb;
- /* ASSERT(request == &cmd_request->request); */
- /* ASSERT(scmnd); */
- /* ASSERT((unsigned long)scmnd->host_scribble == */
- /* (unsigned long)cmd_request); */
- /* ASSERT(scmnd->scsi_done); */
-
if (cmd_request->bounce_sgl_count) {
- /* using bounce buffer */
- /* printk("copy_from_bounce_buffer\n"); */
/* FIXME: We can optimize on writes by just skipping this */
copy_from_bounce_buffer(scsi_sglist(scmnd),
scsi_print_sense_hdr("storvsc", &sense_hdr);
}
- /* ASSERT(request->BytesXfer <= request->data_buffer.Length); */
scsi_set_resid(scmnd,
request->data_buffer.len -
vm_srb->data_transfer_length);
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;
/* 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;
goto retry_request;
}
- /* ASSERT(scmnd->scsi_done == NULL); */
- /* ASSERT(scmnd->host_scribble == NULL); */
-
scmnd->scsi_done = done;
request_size = sizeof(struct storvsc_cmd_request);
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);
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] =
retry_request:
/* Invokes the vsc to start an IO */
- ret = storvsc_drv_obj->on_io_request(dev,
- &cmd_request->request);
+ ret = storvsc_do_io(dev, &cmd_request->request);
+
if (ret == -1) {
/* no more space */
static int storvsc_probe(struct hv_device *device)
{
int ret;
- struct storvsc_driver *storvsc_drv_obj =
- drv_to_stordrv(device->device.driver);
struct Scsi_Host *host;
struct hv_host_device *host_dev;
struct storvsc_device_info device_info;
- if (!storvsc_drv_obj->base.dev_add)
- return -1;
-
host = scsi_host_alloc(&scsi_driver,
sizeof(struct hv_host_device));
if (!host)
device_info.port_number = host->host_no;
/* Call to the vsc driver to add the device */
- ret = storvsc_drv_obj->base.dev_add(device, (void *)&device_info);
+ ret = storvsc_dev_add(device, (void *)&device_info);
if (ret != 0) {
kmem_cache_destroy(host_dev->request_pool);
ret = scsi_add_host(host, &device->device);
if (ret != 0) {
- storvsc_drv_obj->base.dev_rm(device);
+ storvsc_dev_remove(device);
kmem_cache_destroy(host_dev->request_pool);
scsi_host_put(host);
/* The one and only one */
-static struct storvsc_driver storvsc_drv;
+static struct storvsc_driver storvsc_drv = {
+ .base.probe = storvsc_probe,
+ .base.remove = storvsc_remove,
+};
/*
/* Callback to client driver to complete the initialization */
storvsc_initialize(&storvsc_drv_obj->base);
- DPRINT_INFO(STORVSC_DRV,
- "max outstanding reqs %u",
- storvsc_drv_obj->max_outstanding_req_per_channel);
-
if (storvsc_drv_obj->max_outstanding_req_per_channel <
STORVSC_MAX_IO_REQUESTS)
return -1;
drv->driver.name = storvsc_drv_obj->base.name;
- drv->probe = storvsc_probe;
- drv->remove = storvsc_remove;
/* The driver belongs to vmbus */
ret = vmbus_child_driver_register(&drv->driver);
static void storvsc_drv_exit(void)
{
- struct storvsc_driver *storvsc_drv_obj = &storvsc_drv;
struct hv_driver *drv = &storvsc_drv.base;
struct device *current_dev = NULL;
int ret;
device_unregister(current_dev);
}
- if (storvsc_drv_obj->base.cleanup)
- storvsc_drv_obj->base.cleanup(&storvsc_drv_obj->base);
-
vmbus_child_driver_unregister(&drv->driver);
return;
}