Skip to content

Commit d3849d5

Browse files
dwmw2James Bottomley
authored andcommitted
[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 <[email protected]> Acked by: Brian King <[email protected]> Signed-off-by: Paul Mackerras <[email protected]> Signed-off-by: James Bottomley <[email protected]>
1 parent 5307b1e commit d3849d5

File tree

5 files changed

+130
-100
lines changed

5 files changed

+130
-100
lines changed

drivers/scsi/ibmvscsi/Makefile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o
22

33
ibmvscsic-y += ibmvscsi.o
4-
ifndef CONFIG_PPC_PSERIES
54
ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o
6-
endif
75
ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o
86

97
obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o

drivers/scsi/ibmvscsi/ibmvscsi.c

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
#include <linux/moduleparam.h>
7171
#include <linux/dma-mapping.h>
7272
#include <linux/delay.h>
73+
#include <asm/firmware.h>
7374
#include <asm/vio.h>
7475
#include <scsi/scsi.h>
7576
#include <scsi/scsi_cmnd.h>
@@ -92,6 +93,8 @@ static struct scsi_transport_template *ibmvscsi_transport_template;
9293

9394
#define IBMVSCSI_VERSION "1.5.8"
9495

96+
static struct ibmvscsi_ops *ibmvscsi_ops;
97+
9598
MODULE_DESCRIPTION("IBM Virtual SCSI");
9699
MODULE_AUTHOR("Dave Boutcher");
97100
MODULE_LICENSE("GPL");
@@ -509,8 +512,8 @@ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata)
509512
atomic_set(&hostdata->request_limit, 0);
510513

511514
purge_requests(hostdata, DID_ERROR);
512-
if ((ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata)) ||
513-
(ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0)) ||
515+
if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue, hostdata)) ||
516+
(ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0)) ||
514517
(vio_enable_interrupts(to_vio_dev(hostdata->dev)))) {
515518
atomic_set(&hostdata->request_limit, -1);
516519
dev_err(hostdata->dev, "error after reset\n");
@@ -615,7 +618,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
615618
}
616619

617620
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) {
619622
list_del(&evt_struct->list);
620623
del_timer(&evt_struct->timer);
621624

@@ -1214,8 +1217,8 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
12141217
case 0x01: /* Initialization message */
12151218
dev_info(hostdata->dev, "partner initialized\n");
12161219
/* Send back a response */
1217-
if ((rc = ibmvscsi_send_crq(hostdata,
1218-
0xC002000000000000LL, 0)) == 0) {
1220+
if ((rc = ibmvscsi_ops->send_crq(hostdata,
1221+
0xC002000000000000LL, 0)) == 0) {
12191222
/* Now login */
12201223
send_srp_login(hostdata);
12211224
} else {
@@ -1240,10 +1243,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
12401243
/* We need to re-setup the interpartition connection */
12411244
dev_info(hostdata->dev, "Re-enabling adapter!\n");
12421245
purge_requests(hostdata, DID_REQUEUE);
1243-
if ((ibmvscsi_reenable_crq_queue(&hostdata->queue,
1244-
hostdata)) ||
1245-
(ibmvscsi_send_crq(hostdata,
1246-
0xC001000000000000LL, 0))) {
1246+
if ((ibmvscsi_ops->reenable_crq_queue(&hostdata->queue,
1247+
hostdata)) ||
1248+
(ibmvscsi_ops->send_crq(hostdata,
1249+
0xC001000000000000LL, 0))) {
12471250
atomic_set(&hostdata->request_limit,
12481251
-1);
12491252
dev_err(hostdata->dev, "error after enable\n");
@@ -1253,10 +1256,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
12531256
crq->format);
12541257

12551258
purge_requests(hostdata, DID_ERROR);
1256-
if ((ibmvscsi_reset_crq_queue(&hostdata->queue,
1257-
hostdata)) ||
1258-
(ibmvscsi_send_crq(hostdata,
1259-
0xC001000000000000LL, 0))) {
1259+
if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue,
1260+
hostdata)) ||
1261+
(ibmvscsi_ops->send_crq(hostdata,
1262+
0xC001000000000000LL, 0))) {
12601263
atomic_set(&hostdata->request_limit,
12611264
-1);
12621265
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)
15791582
atomic_set(&hostdata->request_limit, -1);
15801583
hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */
15811584

1582-
rc = ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, max_requests);
1585+
rc = ibmvscsi_ops->init_crq_queue(&hostdata->queue, hostdata, max_requests);
15831586
if (rc != 0 && rc != H_RESOURCE) {
15841587
dev_err(&vdev->dev, "couldn't initialize crq. rc=%d\n", rc);
15851588
goto init_crq_failed;
@@ -1608,7 +1611,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
16081611
* to fail if the other end is not acive. In that case we don't
16091612
* want to scan
16101613
*/
1611-
if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0
1614+
if (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0) == 0
16121615
|| rc == H_RESOURCE) {
16131616
/*
16141617
* 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)
16361639
add_host_failed:
16371640
release_event_pool(&hostdata->pool, hostdata);
16381641
init_pool_failed:
1639-
ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, max_requests);
1642+
ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata, max_requests);
16401643
init_crq_failed:
16411644
scsi_host_put(host);
16421645
scsi_host_alloc_failed:
@@ -1647,8 +1650,8 @@ static int ibmvscsi_remove(struct vio_dev *vdev)
16471650
{
16481651
struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data;
16491652
release_event_pool(&hostdata->pool, hostdata);
1650-
ibmvscsi_release_crq_queue(&hostdata->queue, hostdata,
1651-
max_requests);
1653+
ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata,
1654+
max_requests);
16521655

16531656
srp_remove_host(hostdata->host);
16541657
scsi_remove_host(hostdata->host);
@@ -1684,6 +1687,13 @@ int __init ibmvscsi_module_init(void)
16841687
{
16851688
int ret;
16861689

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+
16871697
ibmvscsi_transport_template =
16881698
srp_attach_transport(&ibmvscsi_transport_functions);
16891699
if (!ibmvscsi_transport_template)

drivers/scsi/ibmvscsi/ibmvscsi.h

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -98,21 +98,25 @@ struct ibmvscsi_host_data {
9898
};
9999

100100
/* 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-
113101
void ibmvscsi_handle_crq(struct viosrp_crq *crq,
114102
struct ibmvscsi_host_data *hostdata);
115-
int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata,
116-
u64 word1, u64 word2);
103+
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;
117121

118122
#endif /* IBMVSCSI_H */

drivers/scsi/ibmvscsi/iseries_vscsi.c

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ struct srp_lp_event {
5353
/**
5454
* standard interface for handling logical partition events.
5555
*/
56-
static void ibmvscsi_handle_event(struct HvLpEvent *lpevt)
56+
static void iseriesvscsi_handle_event(struct HvLpEvent *lpevt)
5757
{
5858
struct srp_lp_event *evt = (struct srp_lp_event *)lpevt;
5959

@@ -74,9 +74,9 @@ static void ibmvscsi_handle_event(struct HvLpEvent *lpevt)
7474
/* ------------------------------------------------------------
7575
* Routines for driver initialization
7676
*/
77-
int ibmvscsi_init_crq_queue(struct crq_queue *queue,
78-
struct ibmvscsi_host_data *hostdata,
79-
int max_requests)
77+
static int iseriesvscsi_init_crq_queue(struct crq_queue *queue,
78+
struct ibmvscsi_host_data *hostdata,
79+
int max_requests)
8080
{
8181
int rc;
8282

@@ -88,7 +88,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
8888
goto viopath_open_failed;
8989
}
9090

91-
rc = vio_setHandler(viomajorsubtype_scsi, ibmvscsi_handle_event);
91+
rc = vio_setHandler(viomajorsubtype_scsi, iseriesvscsi_handle_event);
9292
if (rc < 0) {
9393
printk("vio_setHandler failed with rc %d in open_event_path\n",
9494
rc);
@@ -102,9 +102,9 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
102102
return -1;
103103
}
104104

105-
void ibmvscsi_release_crq_queue(struct crq_queue *queue,
106-
struct ibmvscsi_host_data *hostdata,
107-
int max_requests)
105+
static void iseriesvscsi_release_crq_queue(struct crq_queue *queue,
106+
struct ibmvscsi_host_data *hostdata,
107+
int max_requests)
108108
{
109109
vio_clearHandler(viomajorsubtype_scsi);
110110
viopath_close(viopath_hostLp, viomajorsubtype_scsi, max_requests);
@@ -117,8 +117,8 @@ void ibmvscsi_release_crq_queue(struct crq_queue *queue,
117117
*
118118
* no-op for iSeries
119119
*/
120-
int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
121-
struct ibmvscsi_host_data *hostdata)
120+
static int iseriesvscsi_reset_crq_queue(struct crq_queue *queue,
121+
struct ibmvscsi_host_data *hostdata)
122122
{
123123
return 0;
124124
}
@@ -130,19 +130,20 @@ int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
130130
*
131131
* no-op for iSeries
132132
*/
133-
int ibmvscsi_reenable_crq_queue(struct crq_queue *queue,
134-
struct ibmvscsi_host_data *hostdata)
133+
static int iseriesvscsi_reenable_crq_queue(struct crq_queue *queue,
134+
struct ibmvscsi_host_data *hostdata)
135135
{
136136
return 0;
137137
}
138138

139139
/**
140-
* ibmvscsi_send_crq: - Send a CRQ
140+
* iseriesvscsi_send_crq: - Send a CRQ
141141
* @hostdata: the adapter
142142
* @word1: the first 64 bits of the data
143143
* @word2: the second 64 bits of the data
144144
*/
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)
146147
{
147148
single_host_data = hostdata;
148149
return HvCallEvent_signalLpEventFast(viopath_hostLp,
@@ -156,3 +157,11 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2)
156157
VIOVERSION << 16, word1, word2, 0,
157158
0);
158159
}
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+
};

0 commit comments

Comments
 (0)