diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-09-21 18:29:36 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-10-12 14:49:26 -0400 |
commit | d3849d512fb0ca1e369e3efcaec910a949f55f62 (patch) | |
tree | 52b79dd6cd4fe8835ad46b35083edf803c5180b5 /drivers/scsi/ibmvscsi/ibmvscsi.c | |
parent | 5307b1e8b050f309901acc9c6121061206a70ba5 (diff) |
[SCSI] Fix ibmvscsi client for multiplatform iSeries+pSeries kernel
If you build a multiplatform kernel for iSeries and pSeries, with
ibmvscsic support, the resulting client doesn't work on iSeries.
This fixes that, using the appropriate low-level operations
for the machine detected at runtime.
[jejb: fixed up rejections around the srp transport patch]
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Acked by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/ibmvscsi/ibmvscsi.c')
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.c | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 93bd01b1e4b..cda0cc3d182 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
@@ -70,6 +70,7 @@ | |||
70 | #include <linux/moduleparam.h> | 70 | #include <linux/moduleparam.h> |
71 | #include <linux/dma-mapping.h> | 71 | #include <linux/dma-mapping.h> |
72 | #include <linux/delay.h> | 72 | #include <linux/delay.h> |
73 | #include <asm/firmware.h> | ||
73 | #include <asm/vio.h> | 74 | #include <asm/vio.h> |
74 | #include <scsi/scsi.h> | 75 | #include <scsi/scsi.h> |
75 | #include <scsi/scsi_cmnd.h> | 76 | #include <scsi/scsi_cmnd.h> |
@@ -92,6 +93,8 @@ static struct scsi_transport_template *ibmvscsi_transport_template; | |||
92 | 93 | ||
93 | #define IBMVSCSI_VERSION "1.5.8" | 94 | #define IBMVSCSI_VERSION "1.5.8" |
94 | 95 | ||
96 | static struct ibmvscsi_ops *ibmvscsi_ops; | ||
97 | |||
95 | MODULE_DESCRIPTION("IBM Virtual SCSI"); | 98 | MODULE_DESCRIPTION("IBM Virtual SCSI"); |
96 | MODULE_AUTHOR("Dave Boutcher"); | 99 | MODULE_AUTHOR("Dave Boutcher"); |
97 | MODULE_LICENSE("GPL"); | 100 | MODULE_LICENSE("GPL"); |
@@ -509,8 +512,8 @@ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata) | |||
509 | atomic_set(&hostdata->request_limit, 0); | 512 | atomic_set(&hostdata->request_limit, 0); |
510 | 513 | ||
511 | purge_requests(hostdata, DID_ERROR); | 514 | purge_requests(hostdata, DID_ERROR); |
512 | if ((ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata)) || | 515 | if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue, hostdata)) || |
513 | (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0)) || | 516 | (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0)) || |
514 | (vio_enable_interrupts(to_vio_dev(hostdata->dev)))) { | 517 | (vio_enable_interrupts(to_vio_dev(hostdata->dev)))) { |
515 | atomic_set(&hostdata->request_limit, -1); | 518 | atomic_set(&hostdata->request_limit, -1); |
516 | dev_err(hostdata->dev, "error after reset\n"); | 519 | dev_err(hostdata->dev, "error after reset\n"); |
@@ -615,7 +618,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, | |||
615 | } | 618 | } |
616 | 619 | ||
617 | if ((rc = | 620 | if ((rc = |
618 | ibmvscsi_send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) { | 621 | ibmvscsi_ops->send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) { |
619 | list_del(&evt_struct->list); | 622 | list_del(&evt_struct->list); |
620 | del_timer(&evt_struct->timer); | 623 | del_timer(&evt_struct->timer); |
621 | 624 | ||
@@ -1214,8 +1217,8 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, | |||
1214 | case 0x01: /* Initialization message */ | 1217 | case 0x01: /* Initialization message */ |
1215 | dev_info(hostdata->dev, "partner initialized\n"); | 1218 | dev_info(hostdata->dev, "partner initialized\n"); |
1216 | /* Send back a response */ | 1219 | /* Send back a response */ |
1217 | if ((rc = ibmvscsi_send_crq(hostdata, | 1220 | if ((rc = ibmvscsi_ops->send_crq(hostdata, |
1218 | 0xC002000000000000LL, 0)) == 0) { | 1221 | 0xC002000000000000LL, 0)) == 0) { |
1219 | /* Now login */ | 1222 | /* Now login */ |
1220 | send_srp_login(hostdata); | 1223 | send_srp_login(hostdata); |
1221 | } else { | 1224 | } else { |
@@ -1240,10 +1243,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, | |||
1240 | /* We need to re-setup the interpartition connection */ | 1243 | /* We need to re-setup the interpartition connection */ |
1241 | dev_info(hostdata->dev, "Re-enabling adapter!\n"); | 1244 | dev_info(hostdata->dev, "Re-enabling adapter!\n"); |
1242 | purge_requests(hostdata, DID_REQUEUE); | 1245 | purge_requests(hostdata, DID_REQUEUE); |
1243 | if ((ibmvscsi_reenable_crq_queue(&hostdata->queue, | 1246 | if ((ibmvscsi_ops->reenable_crq_queue(&hostdata->queue, |
1244 | hostdata)) || | 1247 | hostdata)) || |
1245 | (ibmvscsi_send_crq(hostdata, | 1248 | (ibmvscsi_ops->send_crq(hostdata, |
1246 | 0xC001000000000000LL, 0))) { | 1249 | 0xC001000000000000LL, 0))) { |
1247 | atomic_set(&hostdata->request_limit, | 1250 | atomic_set(&hostdata->request_limit, |
1248 | -1); | 1251 | -1); |
1249 | dev_err(hostdata->dev, "error after enable\n"); | 1252 | dev_err(hostdata->dev, "error after enable\n"); |
@@ -1253,10 +1256,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, | |||
1253 | crq->format); | 1256 | crq->format); |
1254 | 1257 | ||
1255 | purge_requests(hostdata, DID_ERROR); | 1258 | purge_requests(hostdata, DID_ERROR); |
1256 | if ((ibmvscsi_reset_crq_queue(&hostdata->queue, | 1259 | if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue, |
1257 | hostdata)) || | 1260 | hostdata)) || |
1258 | (ibmvscsi_send_crq(hostdata, | 1261 | (ibmvscsi_ops->send_crq(hostdata, |
1259 | 0xC001000000000000LL, 0))) { | 1262 | 0xC001000000000000LL, 0))) { |
1260 | atomic_set(&hostdata->request_limit, | 1263 | atomic_set(&hostdata->request_limit, |
1261 | -1); | 1264 | -1); |
1262 | dev_err(hostdata->dev, "error after reset\n"); | 1265 | dev_err(hostdata->dev, "error after reset\n"); |
@@ -1579,7 +1582,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1579 | atomic_set(&hostdata->request_limit, -1); | 1582 | atomic_set(&hostdata->request_limit, -1); |
1580 | hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */ | 1583 | hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */ |
1581 | 1584 | ||
1582 | rc = ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, max_requests); | 1585 | rc = ibmvscsi_ops->init_crq_queue(&hostdata->queue, hostdata, max_requests); |
1583 | if (rc != 0 && rc != H_RESOURCE) { | 1586 | if (rc != 0 && rc != H_RESOURCE) { |
1584 | dev_err(&vdev->dev, "couldn't initialize crq. rc=%d\n", rc); | 1587 | dev_err(&vdev->dev, "couldn't initialize crq. rc=%d\n", rc); |
1585 | goto init_crq_failed; | 1588 | goto init_crq_failed; |
@@ -1608,7 +1611,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1608 | * to fail if the other end is not acive. In that case we don't | 1611 | * to fail if the other end is not acive. In that case we don't |
1609 | * want to scan | 1612 | * want to scan |
1610 | */ | 1613 | */ |
1611 | if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0 | 1614 | if (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0) == 0 |
1612 | || rc == H_RESOURCE) { | 1615 | || rc == H_RESOURCE) { |
1613 | /* | 1616 | /* |
1614 | * Wait around max init_timeout secs for the adapter to finish | 1617 | * Wait around max init_timeout secs for the adapter to finish |
@@ -1636,7 +1639,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1636 | add_host_failed: | 1639 | add_host_failed: |
1637 | release_event_pool(&hostdata->pool, hostdata); | 1640 | release_event_pool(&hostdata->pool, hostdata); |
1638 | init_pool_failed: | 1641 | init_pool_failed: |
1639 | ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, max_requests); | 1642 | ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata, max_requests); |
1640 | init_crq_failed: | 1643 | init_crq_failed: |
1641 | scsi_host_put(host); | 1644 | scsi_host_put(host); |
1642 | scsi_host_alloc_failed: | 1645 | scsi_host_alloc_failed: |
@@ -1647,8 +1650,8 @@ static int ibmvscsi_remove(struct vio_dev *vdev) | |||
1647 | { | 1650 | { |
1648 | struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data; | 1651 | struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data; |
1649 | release_event_pool(&hostdata->pool, hostdata); | 1652 | release_event_pool(&hostdata->pool, hostdata); |
1650 | ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, | 1653 | ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata, |
1651 | max_requests); | 1654 | max_requests); |
1652 | 1655 | ||
1653 | srp_remove_host(hostdata->host); | 1656 | srp_remove_host(hostdata->host); |
1654 | scsi_remove_host(hostdata->host); | 1657 | scsi_remove_host(hostdata->host); |
@@ -1684,6 +1687,13 @@ int __init ibmvscsi_module_init(void) | |||
1684 | { | 1687 | { |
1685 | int ret; | 1688 | int ret; |
1686 | 1689 | ||
1690 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
1691 | ibmvscsi_ops = &iseriesvscsi_ops; | ||
1692 | else if (firmware_has_feature(FW_FEATURE_VIO)) | ||
1693 | ibmvscsi_ops = &rpavscsi_ops; | ||
1694 | else | ||
1695 | return -ENODEV; | ||
1696 | |||
1687 | ibmvscsi_transport_template = | 1697 | ibmvscsi_transport_template = |
1688 | srp_attach_transport(&ibmvscsi_transport_functions); | 1698 | srp_attach_transport(&ibmvscsi_transport_functions); |
1689 | if (!ibmvscsi_transport_template) | 1699 | if (!ibmvscsi_transport_template) |