aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ibmvscsi/ibmvscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ibmvscsi/ibmvscsi.c')
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c81
1 files changed, 61 insertions, 20 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 5ecc63d1b436..cda0cc3d182f 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -70,11 +70,13 @@
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>
76#include <scsi/scsi_host.h> 77#include <scsi/scsi_host.h>
77#include <scsi/scsi_device.h> 78#include <scsi/scsi_device.h>
79#include <scsi/scsi_transport_srp.h>
78#include "ibmvscsi.h" 80#include "ibmvscsi.h"
79 81
80/* The values below are somewhat arbitrary default values, but 82/* The values below are somewhat arbitrary default values, but
@@ -87,8 +89,12 @@ static int max_channel = 3;
87static int init_timeout = 5; 89static int init_timeout = 5;
88static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT; 90static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT;
89 91
92static struct scsi_transport_template *ibmvscsi_transport_template;
93
90#define IBMVSCSI_VERSION "1.5.8" 94#define IBMVSCSI_VERSION "1.5.8"
91 95
96static struct ibmvscsi_ops *ibmvscsi_ops;
97
92MODULE_DESCRIPTION("IBM Virtual SCSI"); 98MODULE_DESCRIPTION("IBM Virtual SCSI");
93MODULE_AUTHOR("Dave Boutcher"); 99MODULE_AUTHOR("Dave Boutcher");
94MODULE_LICENSE("GPL"); 100MODULE_LICENSE("GPL");
@@ -506,8 +512,8 @@ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata)
506 atomic_set(&hostdata->request_limit, 0); 512 atomic_set(&hostdata->request_limit, 0);
507 513
508 purge_requests(hostdata, DID_ERROR); 514 purge_requests(hostdata, DID_ERROR);
509 if ((ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata)) || 515 if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue, hostdata)) ||
510 (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0)) || 516 (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0)) ||
511 (vio_enable_interrupts(to_vio_dev(hostdata->dev)))) { 517 (vio_enable_interrupts(to_vio_dev(hostdata->dev)))) {
512 atomic_set(&hostdata->request_limit, -1); 518 atomic_set(&hostdata->request_limit, -1);
513 dev_err(hostdata->dev, "error after reset\n"); 519 dev_err(hostdata->dev, "error after reset\n");
@@ -612,7 +618,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
612 } 618 }
613 619
614 if ((rc = 620 if ((rc =
615 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) {
616 list_del(&evt_struct->list); 622 list_del(&evt_struct->list);
617 del_timer(&evt_struct->timer); 623 del_timer(&evt_struct->timer);
618 624
@@ -1211,8 +1217,8 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
1211 case 0x01: /* Initialization message */ 1217 case 0x01: /* Initialization message */
1212 dev_info(hostdata->dev, "partner initialized\n"); 1218 dev_info(hostdata->dev, "partner initialized\n");
1213 /* Send back a response */ 1219 /* Send back a response */
1214 if ((rc = ibmvscsi_send_crq(hostdata, 1220 if ((rc = ibmvscsi_ops->send_crq(hostdata,
1215 0xC002000000000000LL, 0)) == 0) { 1221 0xC002000000000000LL, 0)) == 0) {
1216 /* Now login */ 1222 /* Now login */
1217 send_srp_login(hostdata); 1223 send_srp_login(hostdata);
1218 } else { 1224 } else {
@@ -1237,10 +1243,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
1237 /* We need to re-setup the interpartition connection */ 1243 /* We need to re-setup the interpartition connection */
1238 dev_info(hostdata->dev, "Re-enabling adapter!\n"); 1244 dev_info(hostdata->dev, "Re-enabling adapter!\n");
1239 purge_requests(hostdata, DID_REQUEUE); 1245 purge_requests(hostdata, DID_REQUEUE);
1240 if ((ibmvscsi_reenable_crq_queue(&hostdata->queue, 1246 if ((ibmvscsi_ops->reenable_crq_queue(&hostdata->queue,
1241 hostdata)) || 1247 hostdata)) ||
1242 (ibmvscsi_send_crq(hostdata, 1248 (ibmvscsi_ops->send_crq(hostdata,
1243 0xC001000000000000LL, 0))) { 1249 0xC001000000000000LL, 0))) {
1244 atomic_set(&hostdata->request_limit, 1250 atomic_set(&hostdata->request_limit,
1245 -1); 1251 -1);
1246 dev_err(hostdata->dev, "error after enable\n"); 1252 dev_err(hostdata->dev, "error after enable\n");
@@ -1250,10 +1256,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
1250 crq->format); 1256 crq->format);
1251 1257
1252 purge_requests(hostdata, DID_ERROR); 1258 purge_requests(hostdata, DID_ERROR);
1253 if ((ibmvscsi_reset_crq_queue(&hostdata->queue, 1259 if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue,
1254 hostdata)) || 1260 hostdata)) ||
1255 (ibmvscsi_send_crq(hostdata, 1261 (ibmvscsi_ops->send_crq(hostdata,
1256 0xC001000000000000LL, 0))) { 1262 0xC001000000000000LL, 0))) {
1257 atomic_set(&hostdata->request_limit, 1263 atomic_set(&hostdata->request_limit,
1258 -1); 1264 -1);
1259 dev_err(hostdata->dev, "error after reset\n"); 1265 dev_err(hostdata->dev, "error after reset\n");
@@ -1553,6 +1559,8 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
1553 struct ibmvscsi_host_data *hostdata; 1559 struct ibmvscsi_host_data *hostdata;
1554 struct Scsi_Host *host; 1560 struct Scsi_Host *host;
1555 struct device *dev = &vdev->dev; 1561 struct device *dev = &vdev->dev;
1562 struct srp_rport_identifiers ids;
1563 struct srp_rport *rport;
1556 unsigned long wait_switch = 0; 1564 unsigned long wait_switch = 0;
1557 int rc; 1565 int rc;
1558 1566
@@ -1565,6 +1573,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
1565 goto scsi_host_alloc_failed; 1573 goto scsi_host_alloc_failed;
1566 } 1574 }
1567 1575
1576 host->transportt = ibmvscsi_transport_template;
1568 hostdata = shost_priv(host); 1577 hostdata = shost_priv(host);
1569 memset(hostdata, 0x00, sizeof(*hostdata)); 1578 memset(hostdata, 0x00, sizeof(*hostdata));
1570 INIT_LIST_HEAD(&hostdata->sent); 1579 INIT_LIST_HEAD(&hostdata->sent);
@@ -1573,7 +1582,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
1573 atomic_set(&hostdata->request_limit, -1); 1582 atomic_set(&hostdata->request_limit, -1);
1574 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 */
1575 1584
1576 rc = ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, max_requests); 1585 rc = ibmvscsi_ops->init_crq_queue(&hostdata->queue, hostdata, max_requests);
1577 if (rc != 0 && rc != H_RESOURCE) { 1586 if (rc != 0 && rc != H_RESOURCE) {
1578 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);
1579 goto init_crq_failed; 1588 goto init_crq_failed;
@@ -1590,11 +1599,19 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
1590 if (scsi_add_host(hostdata->host, hostdata->dev)) 1599 if (scsi_add_host(hostdata->host, hostdata->dev))
1591 goto add_host_failed; 1600 goto add_host_failed;
1592 1601
1602 /* we don't have a proper target_port_id so let's use the fake one */
1603 memcpy(ids.port_id, hostdata->madapter_info.partition_name,
1604 sizeof(ids.port_id));
1605 ids.roles = SRP_RPORT_ROLE_TARGET;
1606 rport = srp_rport_add(host, &ids);
1607 if (IS_ERR(rport))
1608 goto add_srp_port_failed;
1609
1593 /* Try to send an initialization message. Note that this is allowed 1610 /* Try to send an initialization message. Note that this is allowed
1594 * 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
1595 * want to scan 1612 * want to scan
1596 */ 1613 */
1597 if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0 1614 if (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0) == 0
1598 || rc == H_RESOURCE) { 1615 || rc == H_RESOURCE) {
1599 /* 1616 /*
1600 * Wait around max init_timeout secs for the adapter to finish 1617 * Wait around max init_timeout secs for the adapter to finish
@@ -1617,10 +1634,12 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
1617 vdev->dev.driver_data = hostdata; 1634 vdev->dev.driver_data = hostdata;
1618 return 0; 1635 return 0;
1619 1636
1637 add_srp_port_failed:
1638 scsi_remove_host(hostdata->host);
1620 add_host_failed: 1639 add_host_failed:
1621 release_event_pool(&hostdata->pool, hostdata); 1640 release_event_pool(&hostdata->pool, hostdata);
1622 init_pool_failed: 1641 init_pool_failed:
1623 ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, max_requests); 1642 ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata, max_requests);
1624 init_crq_failed: 1643 init_crq_failed:
1625 scsi_host_put(host); 1644 scsi_host_put(host);
1626 scsi_host_alloc_failed: 1645 scsi_host_alloc_failed:
@@ -1631,9 +1650,10 @@ static int ibmvscsi_remove(struct vio_dev *vdev)
1631{ 1650{
1632 struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data; 1651 struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data;
1633 release_event_pool(&hostdata->pool, hostdata); 1652 release_event_pool(&hostdata->pool, hostdata);
1634 ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, 1653 ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata,
1635 max_requests); 1654 max_requests);
1636 1655
1656 srp_remove_host(hostdata->host);
1637 scsi_remove_host(hostdata->host); 1657 scsi_remove_host(hostdata->host);
1638 scsi_host_put(hostdata->host); 1658 scsi_host_put(hostdata->host);
1639 1659
@@ -1660,14 +1680,35 @@ static struct vio_driver ibmvscsi_driver = {
1660 } 1680 }
1661}; 1681};
1662 1682
1683static struct srp_function_template ibmvscsi_transport_functions = {
1684};
1685
1663int __init ibmvscsi_module_init(void) 1686int __init ibmvscsi_module_init(void)
1664{ 1687{
1665 return vio_register_driver(&ibmvscsi_driver); 1688 int ret;
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
1697 ibmvscsi_transport_template =
1698 srp_attach_transport(&ibmvscsi_transport_functions);
1699 if (!ibmvscsi_transport_template)
1700 return -ENOMEM;
1701
1702 ret = vio_register_driver(&ibmvscsi_driver);
1703 if (ret)
1704 srp_release_transport(ibmvscsi_transport_template);
1705 return ret;
1666} 1706}
1667 1707
1668void __exit ibmvscsi_module_exit(void) 1708void __exit ibmvscsi_module_exit(void)
1669{ 1709{
1670 vio_unregister_driver(&ibmvscsi_driver); 1710 vio_unregister_driver(&ibmvscsi_driver);
1711 srp_release_transport(ibmvscsi_transport_template);
1671} 1712}
1672 1713
1673module_init(ibmvscsi_module_init); 1714module_init(ibmvscsi_module_init);