diff options
Diffstat (limited to 'drivers/scsi/ibmvscsi')
-rw-r--r-- | drivers/scsi/ibmvscsi/Makefile | 2 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.c | 81 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.h | 32 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvstgt.c | 61 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/iseries_vscsi.c | 37 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/rpa_vscsi.c | 113 |
6 files changed, 217 insertions, 109 deletions
diff --git a/drivers/scsi/ibmvscsi/Makefile b/drivers/scsi/ibmvscsi/Makefile index f67d9efc7a99..6ac0633d5452 100644 --- a/drivers/scsi/ibmvscsi/Makefile +++ b/drivers/scsi/ibmvscsi/Makefile | |||
@@ -1,9 +1,7 @@ | |||
1 | obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o | 1 | obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o |
2 | 2 | ||
3 | ibmvscsic-y += ibmvscsi.o | 3 | ibmvscsic-y += ibmvscsi.o |
4 | ifndef CONFIG_PPC_PSERIES | ||
5 | ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o | 4 | ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o |
6 | endif | ||
7 | ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o | 5 | ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o |
8 | 6 | ||
9 | obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o | 7 | obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o |
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; | |||
87 | static int init_timeout = 5; | 89 | static int init_timeout = 5; |
88 | static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT; | 90 | static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT; |
89 | 91 | ||
92 | static struct scsi_transport_template *ibmvscsi_transport_template; | ||
93 | |||
90 | #define IBMVSCSI_VERSION "1.5.8" | 94 | #define IBMVSCSI_VERSION "1.5.8" |
91 | 95 | ||
96 | static struct ibmvscsi_ops *ibmvscsi_ops; | ||
97 | |||
92 | MODULE_DESCRIPTION("IBM Virtual SCSI"); | 98 | MODULE_DESCRIPTION("IBM Virtual SCSI"); |
93 | MODULE_AUTHOR("Dave Boutcher"); | 99 | MODULE_AUTHOR("Dave Boutcher"); |
94 | MODULE_LICENSE("GPL"); | 100 | MODULE_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 | ||
1683 | static struct srp_function_template ibmvscsi_transport_functions = { | ||
1684 | }; | ||
1685 | |||
1663 | int __init ibmvscsi_module_init(void) | 1686 | int __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 | ||
1668 | void __exit ibmvscsi_module_exit(void) | 1708 | void __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 | ||
1673 | module_init(ibmvscsi_module_init); | 1714 | module_init(ibmvscsi_module_init); |
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index b19c2e26c2a5..46e850e302c7 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h | |||
@@ -98,21 +98,25 @@ struct ibmvscsi_host_data { | |||
98 | }; | 98 | }; |
99 | 99 | ||
100 | /* routines for managing a command/response queue */ | 100 | /* routines for managing a command/response queue */ |
101 | int ibmvscsi_init_crq_queue(struct crq_queue *queue, | ||
102 | struct ibmvscsi_host_data *hostdata, | ||
103 | int max_requests); | ||
104 | void ibmvscsi_release_crq_queue(struct crq_queue *queue, | ||
105 | struct ibmvscsi_host_data *hostdata, | ||
106 | int max_requests); | ||
107 | int ibmvscsi_reset_crq_queue(struct crq_queue *queue, | ||
108 | struct ibmvscsi_host_data *hostdata); | ||
109 | |||
110 | int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, | ||
111 | struct ibmvscsi_host_data *hostdata); | ||
112 | |||
113 | void ibmvscsi_handle_crq(struct viosrp_crq *crq, | 101 | void ibmvscsi_handle_crq(struct viosrp_crq *crq, |
114 | struct ibmvscsi_host_data *hostdata); | 102 | struct ibmvscsi_host_data *hostdata); |
115 | int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, | 103 | |
116 | u64 word1, u64 word2); | 104 | struct ibmvscsi_ops { |
105 | int (*init_crq_queue)(struct crq_queue *queue, | ||
106 | struct ibmvscsi_host_data *hostdata, | ||
107 | int max_requests); | ||
108 | void (*release_crq_queue)(struct crq_queue *queue, | ||
109 | struct ibmvscsi_host_data *hostdata, | ||
110 | int max_requests); | ||
111 | int (*reset_crq_queue)(struct crq_queue *queue, | ||
112 | struct ibmvscsi_host_data *hostdata); | ||
113 | int (*reenable_crq_queue)(struct crq_queue *queue, | ||
114 | struct ibmvscsi_host_data *hostdata); | ||
115 | int (*send_crq)(struct ibmvscsi_host_data *hostdata, | ||
116 | u64 word1, u64 word2); | ||
117 | }; | ||
118 | |||
119 | extern struct ibmvscsi_ops iseriesvscsi_ops; | ||
120 | extern struct ibmvscsi_ops rpavscsi_ops; | ||
117 | 121 | ||
118 | #endif /* IBMVSCSI_H */ | 122 | #endif /* IBMVSCSI_H */ |
diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index 8ba7dd09d01d..82bcab688b44 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <scsi/scsi.h> | 26 | #include <scsi/scsi.h> |
27 | #include <scsi/scsi_host.h> | 27 | #include <scsi/scsi_host.h> |
28 | #include <scsi/scsi_transport_srp.h> | ||
28 | #include <scsi/scsi_tgt.h> | 29 | #include <scsi/scsi_tgt.h> |
29 | #include <scsi/libsrp.h> | 30 | #include <scsi/libsrp.h> |
30 | #include <asm/hvcall.h> | 31 | #include <asm/hvcall.h> |
@@ -68,9 +69,12 @@ struct vio_port { | |||
68 | unsigned long liobn; | 69 | unsigned long liobn; |
69 | unsigned long riobn; | 70 | unsigned long riobn; |
70 | struct srp_target *target; | 71 | struct srp_target *target; |
72 | |||
73 | struct srp_rport *rport; | ||
71 | }; | 74 | }; |
72 | 75 | ||
73 | static struct workqueue_struct *vtgtd; | 76 | static struct workqueue_struct *vtgtd; |
77 | static struct scsi_transport_template *ibmvstgt_transport_template; | ||
74 | 78 | ||
75 | /* | 79 | /* |
76 | * These are fixed for the system and come from the Open Firmware device tree. | 80 | * These are fixed for the system and come from the Open Firmware device tree. |
@@ -188,6 +192,7 @@ static int send_rsp(struct iu_entry *iue, struct scsi_cmnd *sc, | |||
188 | static void handle_cmd_queue(struct srp_target *target) | 192 | static void handle_cmd_queue(struct srp_target *target) |
189 | { | 193 | { |
190 | struct Scsi_Host *shost = target->shost; | 194 | struct Scsi_Host *shost = target->shost; |
195 | struct srp_rport *rport = target_to_port(target)->rport; | ||
191 | struct iu_entry *iue; | 196 | struct iu_entry *iue; |
192 | struct srp_cmd *cmd; | 197 | struct srp_cmd *cmd; |
193 | unsigned long flags; | 198 | unsigned long flags; |
@@ -200,7 +205,8 @@ retry: | |||
200 | if (!test_and_set_bit(V_FLYING, &iue->flags)) { | 205 | if (!test_and_set_bit(V_FLYING, &iue->flags)) { |
201 | spin_unlock_irqrestore(&target->lock, flags); | 206 | spin_unlock_irqrestore(&target->lock, flags); |
202 | cmd = iue->sbuf->buf; | 207 | cmd = iue->sbuf->buf; |
203 | err = srp_cmd_queue(shost, cmd, iue, 0); | 208 | err = srp_cmd_queue(shost, cmd, iue, |
209 | (unsigned long)rport, 0); | ||
204 | if (err) { | 210 | if (err) { |
205 | eprintk("cannot queue cmd %p %d\n", cmd, err); | 211 | eprintk("cannot queue cmd %p %d\n", cmd, err); |
206 | srp_iu_put(iue); | 212 | srp_iu_put(iue); |
@@ -359,6 +365,16 @@ static void process_login(struct iu_entry *iue) | |||
359 | union viosrp_iu *iu = vio_iu(iue); | 365 | union viosrp_iu *iu = vio_iu(iue); |
360 | struct srp_login_rsp *rsp = &iu->srp.login_rsp; | 366 | struct srp_login_rsp *rsp = &iu->srp.login_rsp; |
361 | uint64_t tag = iu->srp.rsp.tag; | 367 | uint64_t tag = iu->srp.rsp.tag; |
368 | struct Scsi_Host *shost = iue->target->shost; | ||
369 | struct srp_target *target = host_to_srp_target(shost); | ||
370 | struct vio_port *vport = target_to_port(target); | ||
371 | struct srp_rport_identifiers ids; | ||
372 | |||
373 | memset(&ids, 0, sizeof(ids)); | ||
374 | sprintf(ids.port_id, "%x", vport->dma_dev->unit_address); | ||
375 | ids.roles = SRP_RPORT_ROLE_INITIATOR; | ||
376 | if (!vport->rport) | ||
377 | vport->rport = srp_rport_add(shost, &ids); | ||
362 | 378 | ||
363 | /* TODO handle case that requested size is wrong and | 379 | /* TODO handle case that requested size is wrong and |
364 | * buffer format is wrong | 380 | * buffer format is wrong |
@@ -412,7 +428,9 @@ static int process_tsk_mgmt(struct iu_entry *iue) | |||
412 | fn = 0; | 428 | fn = 0; |
413 | } | 429 | } |
414 | if (fn) | 430 | if (fn) |
415 | scsi_tgt_tsk_mgmt_request(iue->target->shost, fn, | 431 | scsi_tgt_tsk_mgmt_request(iue->target->shost, |
432 | (unsigned long)iue->target->shost, | ||
433 | fn, | ||
416 | iu->srp.tsk_mgmt.task_tag, | 434 | iu->srp.tsk_mgmt.task_tag, |
417 | (struct scsi_lun *) &iu->srp.tsk_mgmt.lun, | 435 | (struct scsi_lun *) &iu->srp.tsk_mgmt.lun, |
418 | iue); | 436 | iue); |
@@ -721,7 +739,8 @@ static int ibmvstgt_eh_abort_handler(struct scsi_cmnd *sc) | |||
721 | return 0; | 739 | return 0; |
722 | } | 740 | } |
723 | 741 | ||
724 | static int ibmvstgt_tsk_mgmt_response(u64 mid, int result) | 742 | static int ibmvstgt_tsk_mgmt_response(struct Scsi_Host *shost, |
743 | u64 itn_id, u64 mid, int result) | ||
725 | { | 744 | { |
726 | struct iu_entry *iue = (struct iu_entry *) ((void *) mid); | 745 | struct iu_entry *iue = (struct iu_entry *) ((void *) mid); |
727 | union viosrp_iu *iu = vio_iu(iue); | 746 | union viosrp_iu *iu = vio_iu(iue); |
@@ -747,6 +766,20 @@ static int ibmvstgt_tsk_mgmt_response(u64 mid, int result) | |||
747 | return 0; | 766 | return 0; |
748 | } | 767 | } |
749 | 768 | ||
769 | static int ibmvstgt_it_nexus_response(struct Scsi_Host *shost, u64 itn_id, | ||
770 | int result) | ||
771 | { | ||
772 | struct srp_target *target = host_to_srp_target(shost); | ||
773 | struct vio_port *vport = target_to_port(target); | ||
774 | |||
775 | if (result) { | ||
776 | eprintk("%p %d\n", shost, result); | ||
777 | srp_rport_del(vport->rport); | ||
778 | vport->rport = NULL; | ||
779 | } | ||
780 | return 0; | ||
781 | } | ||
782 | |||
750 | static ssize_t system_id_show(struct class_device *cdev, char *buf) | 783 | static ssize_t system_id_show(struct class_device *cdev, char *buf) |
751 | { | 784 | { |
752 | return snprintf(buf, PAGE_SIZE, "%s\n", system_id); | 785 | return snprintf(buf, PAGE_SIZE, "%s\n", system_id); |
@@ -785,9 +818,9 @@ static struct scsi_host_template ibmvstgt_sht = { | |||
785 | .max_sectors = DEFAULT_MAX_SECTORS, | 818 | .max_sectors = DEFAULT_MAX_SECTORS, |
786 | .transfer_response = ibmvstgt_cmd_done, | 819 | .transfer_response = ibmvstgt_cmd_done, |
787 | .eh_abort_handler = ibmvstgt_eh_abort_handler, | 820 | .eh_abort_handler = ibmvstgt_eh_abort_handler, |
788 | .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, | ||
789 | .shost_attrs = ibmvstgt_attrs, | 821 | .shost_attrs = ibmvstgt_attrs, |
790 | .proc_name = TGT_NAME, | 822 | .proc_name = TGT_NAME, |
823 | .supported_mode = MODE_TARGET, | ||
791 | }; | 824 | }; |
792 | 825 | ||
793 | static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) | 826 | static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) |
@@ -804,6 +837,7 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) | |||
804 | shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target)); | 837 | shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target)); |
805 | if (!shost) | 838 | if (!shost) |
806 | goto free_vport; | 839 | goto free_vport; |
840 | shost->transportt = ibmvstgt_transport_template; | ||
807 | err = scsi_tgt_alloc_queue(shost); | 841 | err = scsi_tgt_alloc_queue(shost); |
808 | if (err) | 842 | if (err) |
809 | goto put_host; | 843 | goto put_host; |
@@ -837,8 +871,8 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) | |||
837 | err = scsi_add_host(shost, target->dev); | 871 | err = scsi_add_host(shost, target->dev); |
838 | if (err) | 872 | if (err) |
839 | goto destroy_queue; | 873 | goto destroy_queue; |
840 | return 0; | ||
841 | 874 | ||
875 | return 0; | ||
842 | destroy_queue: | 876 | destroy_queue: |
843 | crq_queue_destroy(target); | 877 | crq_queue_destroy(target); |
844 | free_srp_target: | 878 | free_srp_target: |
@@ -857,6 +891,7 @@ static int ibmvstgt_remove(struct vio_dev *dev) | |||
857 | struct vio_port *vport = target->ldata; | 891 | struct vio_port *vport = target->ldata; |
858 | 892 | ||
859 | crq_queue_destroy(target); | 893 | crq_queue_destroy(target); |
894 | srp_remove_host(shost); | ||
860 | scsi_remove_host(shost); | 895 | scsi_remove_host(shost); |
861 | scsi_tgt_free_queue(shost); | 896 | scsi_tgt_free_queue(shost); |
862 | srp_target_free(target); | 897 | srp_target_free(target); |
@@ -909,15 +944,25 @@ static int get_system_info(void) | |||
909 | return 0; | 944 | return 0; |
910 | } | 945 | } |
911 | 946 | ||
947 | static struct srp_function_template ibmvstgt_transport_functions = { | ||
948 | .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, | ||
949 | .it_nexus_response = ibmvstgt_it_nexus_response, | ||
950 | }; | ||
951 | |||
912 | static int ibmvstgt_init(void) | 952 | static int ibmvstgt_init(void) |
913 | { | 953 | { |
914 | int err = -ENOMEM; | 954 | int err = -ENOMEM; |
915 | 955 | ||
916 | printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n"); | 956 | printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n"); |
917 | 957 | ||
958 | ibmvstgt_transport_template = | ||
959 | srp_attach_transport(&ibmvstgt_transport_functions); | ||
960 | if (!ibmvstgt_transport_template) | ||
961 | return err; | ||
962 | |||
918 | vtgtd = create_workqueue("ibmvtgtd"); | 963 | vtgtd = create_workqueue("ibmvtgtd"); |
919 | if (!vtgtd) | 964 | if (!vtgtd) |
920 | return err; | 965 | goto release_transport; |
921 | 966 | ||
922 | err = get_system_info(); | 967 | err = get_system_info(); |
923 | if (err) | 968 | if (err) |
@@ -928,9 +973,10 @@ static int ibmvstgt_init(void) | |||
928 | goto destroy_wq; | 973 | goto destroy_wq; |
929 | 974 | ||
930 | return 0; | 975 | return 0; |
931 | |||
932 | destroy_wq: | 976 | destroy_wq: |
933 | destroy_workqueue(vtgtd); | 977 | destroy_workqueue(vtgtd); |
978 | release_transport: | ||
979 | srp_release_transport(ibmvstgt_transport_template); | ||
934 | return err; | 980 | return err; |
935 | } | 981 | } |
936 | 982 | ||
@@ -940,6 +986,7 @@ static void ibmvstgt_exit(void) | |||
940 | 986 | ||
941 | destroy_workqueue(vtgtd); | 987 | destroy_workqueue(vtgtd); |
942 | vio_unregister_driver(&ibmvstgt_driver); | 988 | vio_unregister_driver(&ibmvstgt_driver); |
989 | srp_release_transport(ibmvstgt_transport_template); | ||
943 | } | 990 | } |
944 | 991 | ||
945 | MODULE_DESCRIPTION("IBM Virtual SCSI Target"); | 992 | MODULE_DESCRIPTION("IBM Virtual SCSI Target"); |
diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c index 6aeb5f003c3c..0775fdee5fa8 100644 --- a/drivers/scsi/ibmvscsi/iseries_vscsi.c +++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c | |||
@@ -53,7 +53,7 @@ struct srp_lp_event { | |||
53 | /** | 53 | /** |
54 | * standard interface for handling logical partition events. | 54 | * standard interface for handling logical partition events. |
55 | */ | 55 | */ |
56 | static void ibmvscsi_handle_event(struct HvLpEvent *lpevt) | 56 | static void iseriesvscsi_handle_event(struct HvLpEvent *lpevt) |
57 | { | 57 | { |
58 | struct srp_lp_event *evt = (struct srp_lp_event *)lpevt; | 58 | struct srp_lp_event *evt = (struct srp_lp_event *)lpevt; |
59 | 59 | ||
@@ -74,9 +74,9 @@ static void ibmvscsi_handle_event(struct HvLpEvent *lpevt) | |||
74 | /* ------------------------------------------------------------ | 74 | /* ------------------------------------------------------------ |
75 | * Routines for driver initialization | 75 | * Routines for driver initialization |
76 | */ | 76 | */ |
77 | int ibmvscsi_init_crq_queue(struct crq_queue *queue, | 77 | static int iseriesvscsi_init_crq_queue(struct crq_queue *queue, |
78 | struct ibmvscsi_host_data *hostdata, | 78 | struct ibmvscsi_host_data *hostdata, |
79 | int max_requests) | 79 | int max_requests) |
80 | { | 80 | { |
81 | int rc; | 81 | int rc; |
82 | 82 | ||
@@ -88,7 +88,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
88 | goto viopath_open_failed; | 88 | goto viopath_open_failed; |
89 | } | 89 | } |
90 | 90 | ||
91 | rc = vio_setHandler(viomajorsubtype_scsi, ibmvscsi_handle_event); | 91 | rc = vio_setHandler(viomajorsubtype_scsi, iseriesvscsi_handle_event); |
92 | if (rc < 0) { | 92 | if (rc < 0) { |
93 | printk("vio_setHandler failed with rc %d in open_event_path\n", | 93 | printk("vio_setHandler failed with rc %d in open_event_path\n", |
94 | rc); | 94 | rc); |
@@ -102,9 +102,9 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
102 | return -1; | 102 | return -1; |
103 | } | 103 | } |
104 | 104 | ||
105 | void ibmvscsi_release_crq_queue(struct crq_queue *queue, | 105 | static void iseriesvscsi_release_crq_queue(struct crq_queue *queue, |
106 | struct ibmvscsi_host_data *hostdata, | 106 | struct ibmvscsi_host_data *hostdata, |
107 | int max_requests) | 107 | int max_requests) |
108 | { | 108 | { |
109 | vio_clearHandler(viomajorsubtype_scsi); | 109 | vio_clearHandler(viomajorsubtype_scsi); |
110 | viopath_close(viopath_hostLp, viomajorsubtype_scsi, max_requests); | 110 | viopath_close(viopath_hostLp, viomajorsubtype_scsi, max_requests); |
@@ -117,8 +117,8 @@ void ibmvscsi_release_crq_queue(struct crq_queue *queue, | |||
117 | * | 117 | * |
118 | * no-op for iSeries | 118 | * no-op for iSeries |
119 | */ | 119 | */ |
120 | int ibmvscsi_reset_crq_queue(struct crq_queue *queue, | 120 | static int iseriesvscsi_reset_crq_queue(struct crq_queue *queue, |
121 | struct ibmvscsi_host_data *hostdata) | 121 | struct ibmvscsi_host_data *hostdata) |
122 | { | 122 | { |
123 | return 0; | 123 | return 0; |
124 | } | 124 | } |
@@ -130,19 +130,20 @@ int ibmvscsi_reset_crq_queue(struct crq_queue *queue, | |||
130 | * | 130 | * |
131 | * no-op for iSeries | 131 | * no-op for iSeries |
132 | */ | 132 | */ |
133 | int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, | 133 | static int iseriesvscsi_reenable_crq_queue(struct crq_queue *queue, |
134 | struct ibmvscsi_host_data *hostdata) | 134 | struct ibmvscsi_host_data *hostdata) |
135 | { | 135 | { |
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | 138 | ||
139 | /** | 139 | /** |
140 | * ibmvscsi_send_crq: - Send a CRQ | 140 | * iseriesvscsi_send_crq: - Send a CRQ |
141 | * @hostdata: the adapter | 141 | * @hostdata: the adapter |
142 | * @word1: the first 64 bits of the data | 142 | * @word1: the first 64 bits of the data |
143 | * @word2: the second 64 bits of the data | 143 | * @word2: the second 64 bits of the data |
144 | */ | 144 | */ |
145 | int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) | 145 | static int iseriesvscsi_send_crq(struct ibmvscsi_host_data *hostdata, |
146 | u64 word1, u64 word2) | ||
146 | { | 147 | { |
147 | single_host_data = hostdata; | 148 | single_host_data = hostdata; |
148 | return HvCallEvent_signalLpEventFast(viopath_hostLp, | 149 | return HvCallEvent_signalLpEventFast(viopath_hostLp, |
@@ -156,3 +157,11 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) | |||
156 | VIOVERSION << 16, word1, word2, 0, | 157 | VIOVERSION << 16, word1, word2, 0, |
157 | 0); | 158 | 0); |
158 | } | 159 | } |
160 | |||
161 | struct ibmvscsi_ops iseriesvscsi_ops = { | ||
162 | .init_crq_queue = iseriesvscsi_init_crq_queue, | ||
163 | .release_crq_queue = iseriesvscsi_release_crq_queue, | ||
164 | .reset_crq_queue = iseriesvscsi_reset_crq_queue, | ||
165 | .reenable_crq_queue = iseriesvscsi_reenable_crq_queue, | ||
166 | .send_crq = iseriesvscsi_send_crq, | ||
167 | }; | ||
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 9c14e789df5f..182146100dc1 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c | |||
@@ -42,14 +42,14 @@ static unsigned int partition_number = -1; | |||
42 | * Routines for managing the command/response queue | 42 | * Routines for managing the command/response queue |
43 | */ | 43 | */ |
44 | /** | 44 | /** |
45 | * ibmvscsi_handle_event: - Interrupt handler for crq events | 45 | * rpavscsi_handle_event: - Interrupt handler for crq events |
46 | * @irq: number of irq to handle, not used | 46 | * @irq: number of irq to handle, not used |
47 | * @dev_instance: ibmvscsi_host_data of host that received interrupt | 47 | * @dev_instance: ibmvscsi_host_data of host that received interrupt |
48 | * | 48 | * |
49 | * Disables interrupts and schedules srp_task | 49 | * Disables interrupts and schedules srp_task |
50 | * Always returns IRQ_HANDLED | 50 | * Always returns IRQ_HANDLED |
51 | */ | 51 | */ |
52 | static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance) | 52 | static irqreturn_t rpavscsi_handle_event(int irq, void *dev_instance) |
53 | { | 53 | { |
54 | struct ibmvscsi_host_data *hostdata = | 54 | struct ibmvscsi_host_data *hostdata = |
55 | (struct ibmvscsi_host_data *)dev_instance; | 55 | (struct ibmvscsi_host_data *)dev_instance; |
@@ -66,9 +66,9 @@ static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance) | |||
66 | * Frees irq, deallocates a page for messages, unmaps dma, and unregisters | 66 | * Frees irq, deallocates a page for messages, unmaps dma, and unregisters |
67 | * the crq with the hypervisor. | 67 | * the crq with the hypervisor. |
68 | */ | 68 | */ |
69 | void ibmvscsi_release_crq_queue(struct crq_queue *queue, | 69 | static void rpavscsi_release_crq_queue(struct crq_queue *queue, |
70 | struct ibmvscsi_host_data *hostdata, | 70 | struct ibmvscsi_host_data *hostdata, |
71 | int max_requests) | 71 | int max_requests) |
72 | { | 72 | { |
73 | long rc; | 73 | long rc; |
74 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | 74 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); |
@@ -108,12 +108,13 @@ static struct viosrp_crq *crq_queue_next_crq(struct crq_queue *queue) | |||
108 | } | 108 | } |
109 | 109 | ||
110 | /** | 110 | /** |
111 | * ibmvscsi_send_crq: - Send a CRQ | 111 | * rpavscsi_send_crq: - Send a CRQ |
112 | * @hostdata: the adapter | 112 | * @hostdata: the adapter |
113 | * @word1: the first 64 bits of the data | 113 | * @word1: the first 64 bits of the data |
114 | * @word2: the second 64 bits of the data | 114 | * @word2: the second 64 bits of the data |
115 | */ | 115 | */ |
116 | int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) | 116 | static int rpavscsi_send_crq(struct ibmvscsi_host_data *hostdata, |
117 | u64 word1, u64 word2) | ||
117 | { | 118 | { |
118 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | 119 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); |
119 | 120 | ||
@@ -121,10 +122,10 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) | |||
121 | } | 122 | } |
122 | 123 | ||
123 | /** | 124 | /** |
124 | * ibmvscsi_task: - Process srps asynchronously | 125 | * rpavscsi_task: - Process srps asynchronously |
125 | * @data: ibmvscsi_host_data of host | 126 | * @data: ibmvscsi_host_data of host |
126 | */ | 127 | */ |
127 | static void ibmvscsi_task(void *data) | 128 | static void rpavscsi_task(void *data) |
128 | { | 129 | { |
129 | struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data; | 130 | struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data; |
130 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | 131 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); |
@@ -190,6 +191,42 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata) | |||
190 | } | 191 | } |
191 | 192 | ||
192 | /** | 193 | /** |
194 | * reset_crq_queue: - resets a crq after a failure | ||
195 | * @queue: crq_queue to initialize and register | ||
196 | * @hostdata: ibmvscsi_host_data of host | ||
197 | * | ||
198 | */ | ||
199 | static int rpavscsi_reset_crq_queue(struct crq_queue *queue, | ||
200 | struct ibmvscsi_host_data *hostdata) | ||
201 | { | ||
202 | int rc; | ||
203 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | ||
204 | |||
205 | /* Close the CRQ */ | ||
206 | do { | ||
207 | rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); | ||
208 | } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); | ||
209 | |||
210 | /* Clean out the queue */ | ||
211 | memset(queue->msgs, 0x00, PAGE_SIZE); | ||
212 | queue->cur = 0; | ||
213 | |||
214 | set_adapter_info(hostdata); | ||
215 | |||
216 | /* And re-open it again */ | ||
217 | rc = plpar_hcall_norets(H_REG_CRQ, | ||
218 | vdev->unit_address, | ||
219 | queue->msg_token, PAGE_SIZE); | ||
220 | if (rc == 2) { | ||
221 | /* Adapter is good, but other end is not ready */ | ||
222 | dev_warn(hostdata->dev, "Partner adapter not ready\n"); | ||
223 | } else if (rc != 0) { | ||
224 | dev_warn(hostdata->dev, "couldn't register crq--rc 0x%x\n", rc); | ||
225 | } | ||
226 | return rc; | ||
227 | } | ||
228 | |||
229 | /** | ||
193 | * initialize_crq_queue: - Initializes and registers CRQ with hypervisor | 230 | * initialize_crq_queue: - Initializes and registers CRQ with hypervisor |
194 | * @queue: crq_queue to initialize and register | 231 | * @queue: crq_queue to initialize and register |
195 | * @hostdata: ibmvscsi_host_data of host | 232 | * @hostdata: ibmvscsi_host_data of host |
@@ -198,9 +235,9 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata) | |||
198 | * the crq with the hypervisor. | 235 | * the crq with the hypervisor. |
199 | * Returns zero on success. | 236 | * Returns zero on success. |
200 | */ | 237 | */ |
201 | int ibmvscsi_init_crq_queue(struct crq_queue *queue, | 238 | static int rpavscsi_init_crq_queue(struct crq_queue *queue, |
202 | struct ibmvscsi_host_data *hostdata, | 239 | struct ibmvscsi_host_data *hostdata, |
203 | int max_requests) | 240 | int max_requests) |
204 | { | 241 | { |
205 | int rc; | 242 | int rc; |
206 | int retrc; | 243 | int retrc; |
@@ -227,7 +264,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
227 | queue->msg_token, PAGE_SIZE); | 264 | queue->msg_token, PAGE_SIZE); |
228 | if (rc == H_RESOURCE) | 265 | if (rc == H_RESOURCE) |
229 | /* maybe kexecing and resource is busy. try a reset */ | 266 | /* maybe kexecing and resource is busy. try a reset */ |
230 | rc = ibmvscsi_reset_crq_queue(queue, | 267 | rc = rpavscsi_reset_crq_queue(queue, |
231 | hostdata); | 268 | hostdata); |
232 | 269 | ||
233 | if (rc == 2) { | 270 | if (rc == 2) { |
@@ -240,7 +277,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
240 | } | 277 | } |
241 | 278 | ||
242 | if (request_irq(vdev->irq, | 279 | if (request_irq(vdev->irq, |
243 | ibmvscsi_handle_event, | 280 | rpavscsi_handle_event, |
244 | 0, "ibmvscsi", (void *)hostdata) != 0) { | 281 | 0, "ibmvscsi", (void *)hostdata) != 0) { |
245 | dev_err(hostdata->dev, "couldn't register irq 0x%x\n", | 282 | dev_err(hostdata->dev, "couldn't register irq 0x%x\n", |
246 | vdev->irq); | 283 | vdev->irq); |
@@ -256,7 +293,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
256 | queue->cur = 0; | 293 | queue->cur = 0; |
257 | spin_lock_init(&queue->lock); | 294 | spin_lock_init(&queue->lock); |
258 | 295 | ||
259 | tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task, | 296 | tasklet_init(&hostdata->srp_task, (void *)rpavscsi_task, |
260 | (unsigned long)hostdata); | 297 | (unsigned long)hostdata); |
261 | 298 | ||
262 | return retrc; | 299 | return retrc; |
@@ -281,8 +318,8 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
281 | * @hostdata: ibmvscsi_host_data of host | 318 | * @hostdata: ibmvscsi_host_data of host |
282 | * | 319 | * |
283 | */ | 320 | */ |
284 | int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, | 321 | static int rpavscsi_reenable_crq_queue(struct crq_queue *queue, |
285 | struct ibmvscsi_host_data *hostdata) | 322 | struct ibmvscsi_host_data *hostdata) |
286 | { | 323 | { |
287 | int rc; | 324 | int rc; |
288 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | 325 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); |
@@ -297,38 +334,10 @@ int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, | |||
297 | return rc; | 334 | return rc; |
298 | } | 335 | } |
299 | 336 | ||
300 | /** | 337 | struct ibmvscsi_ops rpavscsi_ops = { |
301 | * reset_crq_queue: - resets a crq after a failure | 338 | .init_crq_queue = rpavscsi_init_crq_queue, |
302 | * @queue: crq_queue to initialize and register | 339 | .release_crq_queue = rpavscsi_release_crq_queue, |
303 | * @hostdata: ibmvscsi_host_data of host | 340 | .reset_crq_queue = rpavscsi_reset_crq_queue, |
304 | * | 341 | .reenable_crq_queue = rpavscsi_reenable_crq_queue, |
305 | */ | 342 | .send_crq = rpavscsi_send_crq, |
306 | int ibmvscsi_reset_crq_queue(struct crq_queue *queue, | 343 | }; |
307 | struct ibmvscsi_host_data *hostdata) | ||
308 | { | ||
309 | int rc; | ||
310 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | ||
311 | |||
312 | /* Close the CRQ */ | ||
313 | do { | ||
314 | rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); | ||
315 | } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); | ||
316 | |||
317 | /* Clean out the queue */ | ||
318 | memset(queue->msgs, 0x00, PAGE_SIZE); | ||
319 | queue->cur = 0; | ||
320 | |||
321 | set_adapter_info(hostdata); | ||
322 | |||
323 | /* And re-open it again */ | ||
324 | rc = plpar_hcall_norets(H_REG_CRQ, | ||
325 | vdev->unit_address, | ||
326 | queue->msg_token, PAGE_SIZE); | ||
327 | if (rc == 2) { | ||
328 | /* Adapter is good, but other end is not ready */ | ||
329 | dev_warn(hostdata->dev, "Partner adapter not ready\n"); | ||
330 | } else if (rc != 0) { | ||
331 | dev_warn(hostdata->dev, "couldn't register crq--rc 0x%x\n", rc); | ||
332 | } | ||
333 | return rc; | ||
334 | } | ||