diff options
author | Robert Jennings <rcj@linux.vnet.ibm.com> | 2008-07-23 14:35:27 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-07-25 01:44:44 -0400 |
commit | 7912a0ac5907df1f8b214b3ca15ccf96129daae0 (patch) | |
tree | 1e281da81b4f7cac8394306303d9129ba4a2051e /drivers/scsi/ibmvscsi/ibmvscsi.c | |
parent | 1096d63d8e7d226630706e15648705d0187787e4 (diff) |
ibmvscsi: driver enablement for CMO
Enable the driver to function in a Cooperative Memory Overcommitment (CMO)
environment.
The following changes are made to enable the driver for CMO:
* DMA mapping errors will not result in error messages if entitlement has
been exceeded and resources were not available.
* The driver has a get_desired_dma function defined to function
in a CMO environment. It will indicate how much IO memory it would like
to function.
Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>
Acked by: Brian King <brking@linux.vnet.ibm.com>
Acked-by: Paul Mackerras <paulus@samba.org>
Acked-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'drivers/scsi/ibmvscsi/ibmvscsi.c')
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.c | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 5d23368a1bce..20000ec79b04 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
@@ -72,6 +72,7 @@ | |||
72 | #include <linux/delay.h> | 72 | #include <linux/delay.h> |
73 | #include <asm/firmware.h> | 73 | #include <asm/firmware.h> |
74 | #include <asm/vio.h> | 74 | #include <asm/vio.h> |
75 | #include <asm/firmware.h> | ||
75 | #include <scsi/scsi.h> | 76 | #include <scsi/scsi.h> |
76 | #include <scsi/scsi_cmnd.h> | 77 | #include <scsi/scsi_cmnd.h> |
77 | #include <scsi/scsi_host.h> | 78 | #include <scsi/scsi_host.h> |
@@ -426,8 +427,10 @@ static int map_sg_data(struct scsi_cmnd *cmd, | |||
426 | SG_ALL * sizeof(struct srp_direct_buf), | 427 | SG_ALL * sizeof(struct srp_direct_buf), |
427 | &evt_struct->ext_list_token, 0); | 428 | &evt_struct->ext_list_token, 0); |
428 | if (!evt_struct->ext_list) { | 429 | if (!evt_struct->ext_list) { |
429 | sdev_printk(KERN_ERR, cmd->device, | 430 | if (!firmware_has_feature(FW_FEATURE_CMO)) |
430 | "Can't allocate memory for indirect table\n"); | 431 | sdev_printk(KERN_ERR, cmd->device, |
432 | "Can't allocate memory " | ||
433 | "for indirect table\n"); | ||
431 | return 0; | 434 | return 0; |
432 | } | 435 | } |
433 | } | 436 | } |
@@ -743,7 +746,9 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd, | |||
743 | srp_cmd->lun = ((u64) lun) << 48; | 746 | srp_cmd->lun = ((u64) lun) << 48; |
744 | 747 | ||
745 | if (!map_data_for_srp_cmd(cmnd, evt_struct, srp_cmd, hostdata->dev)) { | 748 | if (!map_data_for_srp_cmd(cmnd, evt_struct, srp_cmd, hostdata->dev)) { |
746 | sdev_printk(KERN_ERR, cmnd->device, "couldn't convert cmd to srp_cmd\n"); | 749 | if (!firmware_has_feature(FW_FEATURE_CMO)) |
750 | sdev_printk(KERN_ERR, cmnd->device, | ||
751 | "couldn't convert cmd to srp_cmd\n"); | ||
747 | free_event_struct(&hostdata->pool, evt_struct); | 752 | free_event_struct(&hostdata->pool, evt_struct); |
748 | return SCSI_MLQUEUE_HOST_BUSY; | 753 | return SCSI_MLQUEUE_HOST_BUSY; |
749 | } | 754 | } |
@@ -855,7 +860,10 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata) | |||
855 | DMA_BIDIRECTIONAL); | 860 | DMA_BIDIRECTIONAL); |
856 | 861 | ||
857 | if (dma_mapping_error(req->buffer)) { | 862 | if (dma_mapping_error(req->buffer)) { |
858 | dev_err(hostdata->dev, "Unable to map request_buffer for adapter_info!\n"); | 863 | if (!firmware_has_feature(FW_FEATURE_CMO)) |
864 | dev_err(hostdata->dev, | ||
865 | "Unable to map request_buffer for " | ||
866 | "adapter_info!\n"); | ||
859 | free_event_struct(&hostdata->pool, evt_struct); | 867 | free_event_struct(&hostdata->pool, evt_struct); |
860 | return; | 868 | return; |
861 | } | 869 | } |
@@ -1400,7 +1408,9 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, | |||
1400 | DMA_BIDIRECTIONAL); | 1408 | DMA_BIDIRECTIONAL); |
1401 | 1409 | ||
1402 | if (dma_mapping_error(host_config->buffer)) { | 1410 | if (dma_mapping_error(host_config->buffer)) { |
1403 | dev_err(hostdata->dev, "dma_mapping error getting host config\n"); | 1411 | if (!firmware_has_feature(FW_FEATURE_CMO)) |
1412 | dev_err(hostdata->dev, | ||
1413 | "dma_mapping error getting host config\n"); | ||
1404 | free_event_struct(&hostdata->pool, evt_struct); | 1414 | free_event_struct(&hostdata->pool, evt_struct); |
1405 | return -1; | 1415 | return -1; |
1406 | } | 1416 | } |
@@ -1604,7 +1614,7 @@ static struct scsi_host_template driver_template = { | |||
1604 | .eh_host_reset_handler = ibmvscsi_eh_host_reset_handler, | 1614 | .eh_host_reset_handler = ibmvscsi_eh_host_reset_handler, |
1605 | .slave_configure = ibmvscsi_slave_configure, | 1615 | .slave_configure = ibmvscsi_slave_configure, |
1606 | .change_queue_depth = ibmvscsi_change_queue_depth, | 1616 | .change_queue_depth = ibmvscsi_change_queue_depth, |
1607 | .cmd_per_lun = 16, | 1617 | .cmd_per_lun = IBMVSCSI_CMDS_PER_LUN_DEFAULT, |
1608 | .can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT, | 1618 | .can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT, |
1609 | .this_id = -1, | 1619 | .this_id = -1, |
1610 | .sg_tablesize = SG_ALL, | 1620 | .sg_tablesize = SG_ALL, |
@@ -1613,6 +1623,26 @@ static struct scsi_host_template driver_template = { | |||
1613 | }; | 1623 | }; |
1614 | 1624 | ||
1615 | /** | 1625 | /** |
1626 | * ibmvscsi_get_desired_dma - Calculate IO memory desired by the driver | ||
1627 | * | ||
1628 | * @vdev: struct vio_dev for the device whose desired IO mem is to be returned | ||
1629 | * | ||
1630 | * Return value: | ||
1631 | * Number of bytes of IO data the driver will need to perform well. | ||
1632 | */ | ||
1633 | static unsigned long ibmvscsi_get_desired_dma(struct vio_dev *vdev) | ||
1634 | { | ||
1635 | /* iu_storage data allocated in initialize_event_pool */ | ||
1636 | unsigned long desired_io = max_requests * sizeof(union viosrp_iu); | ||
1637 | |||
1638 | /* add io space for sg data */ | ||
1639 | desired_io += (IBMVSCSI_MAX_SECTORS_DEFAULT * | ||
1640 | IBMVSCSI_CMDS_PER_LUN_DEFAULT); | ||
1641 | |||
1642 | return desired_io; | ||
1643 | } | ||
1644 | |||
1645 | /** | ||
1616 | * Called by bus code for each adapter | 1646 | * Called by bus code for each adapter |
1617 | */ | 1647 | */ |
1618 | static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | 1648 | static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) |
@@ -1641,7 +1671,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1641 | hostdata->host = host; | 1671 | hostdata->host = host; |
1642 | hostdata->dev = dev; | 1672 | hostdata->dev = dev; |
1643 | atomic_set(&hostdata->request_limit, -1); | 1673 | atomic_set(&hostdata->request_limit, -1); |
1644 | hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */ | 1674 | hostdata->host->max_sectors = IBMVSCSI_MAX_SECTORS_DEFAULT; |
1645 | 1675 | ||
1646 | rc = ibmvscsi_ops->init_crq_queue(&hostdata->queue, hostdata, max_requests); | 1676 | rc = ibmvscsi_ops->init_crq_queue(&hostdata->queue, hostdata, max_requests); |
1647 | if (rc != 0 && rc != H_RESOURCE) { | 1677 | if (rc != 0 && rc != H_RESOURCE) { |
@@ -1735,6 +1765,7 @@ static struct vio_driver ibmvscsi_driver = { | |||
1735 | .id_table = ibmvscsi_device_table, | 1765 | .id_table = ibmvscsi_device_table, |
1736 | .probe = ibmvscsi_probe, | 1766 | .probe = ibmvscsi_probe, |
1737 | .remove = ibmvscsi_remove, | 1767 | .remove = ibmvscsi_remove, |
1768 | .get_desired_dma = ibmvscsi_get_desired_dma, | ||
1738 | .driver = { | 1769 | .driver = { |
1739 | .name = "ibmvscsi", | 1770 | .name = "ibmvscsi", |
1740 | .owner = THIS_MODULE, | 1771 | .owner = THIS_MODULE, |