diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2010-08-09 12:12:53 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-08-09 12:12:54 -0400 |
commit | 982bdf814616bec77c920e16ea4108d409f144ed (patch) | |
tree | 7aee4e1dde2001ca5415103778fb95e93c3d2065 | |
parent | 7cd403142d5dbffa354b7dd369b1069e01b1ae19 (diff) |
[S390] ccwreq: add ability to use all paths
Change the ccwrequest infrastructure to use more than one channel
path per start I/O. A flag "singlepath" is added to struct
ccw_request - if set, the old behavior is used. This flag is set
for all exploiters of the ccwrequest infrastructure - so there
is no functional change through this patch.
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | drivers/s390/cio/ccwreq.c | 14 | ||||
-rw-r--r-- | drivers/s390/cio/device_id.c | 1 | ||||
-rw-r--r-- | drivers/s390/cio/device_pgid.c | 4 | ||||
-rw-r--r-- | drivers/s390/cio/io_sch.h | 10 |
4 files changed, 22 insertions, 7 deletions
diff --git a/drivers/s390/cio/ccwreq.c b/drivers/s390/cio/ccwreq.c index fd0368785ee0..d15f8b4d78bd 100644 --- a/drivers/s390/cio/ccwreq.c +++ b/drivers/s390/cio/ccwreq.c | |||
@@ -38,9 +38,13 @@ static u16 ccwreq_next_path(struct ccw_device *cdev) | |||
38 | { | 38 | { |
39 | struct ccw_request *req = &cdev->private->req; | 39 | struct ccw_request *req = &cdev->private->req; |
40 | 40 | ||
41 | if (!req->singlepath) { | ||
42 | req->mask = 0; | ||
43 | goto out; | ||
44 | } | ||
41 | req->retries = req->maxretries; | 45 | req->retries = req->maxretries; |
42 | req->mask = lpm_adjust(req->mask >>= 1, req->lpm); | 46 | req->mask = lpm_adjust(req->mask >>= 1, req->lpm); |
43 | 47 | out: | |
44 | return req->mask; | 48 | return req->mask; |
45 | } | 49 | } |
46 | 50 | ||
@@ -113,8 +117,12 @@ void ccw_request_start(struct ccw_device *cdev) | |||
113 | { | 117 | { |
114 | struct ccw_request *req = &cdev->private->req; | 118 | struct ccw_request *req = &cdev->private->req; |
115 | 119 | ||
116 | /* Try all paths twice to counter link flapping. */ | 120 | if (req->singlepath) { |
117 | req->mask = 0x8080; | 121 | /* Try all paths twice to counter link flapping. */ |
122 | req->mask = 0x8080; | ||
123 | } else | ||
124 | req->mask = req->lpm; | ||
125 | |||
118 | req->retries = req->maxretries; | 126 | req->retries = req->maxretries; |
119 | req->mask = lpm_adjust(req->mask, req->lpm); | 127 | req->mask = lpm_adjust(req->mask, req->lpm); |
120 | req->drc = 0; | 128 | req->drc = 0; |
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 78a0b43862c5..0d7fe4dab3b6 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c | |||
@@ -216,6 +216,7 @@ void ccw_device_sense_id_start(struct ccw_device *cdev) | |||
216 | req->timeout = SENSE_ID_TIMEOUT; | 216 | req->timeout = SENSE_ID_TIMEOUT; |
217 | req->maxretries = SENSE_ID_RETRIES; | 217 | req->maxretries = SENSE_ID_RETRIES; |
218 | req->lpm = sch->schib.pmcw.pam & sch->opm; | 218 | req->lpm = sch->schib.pmcw.pam & sch->opm; |
219 | req->singlepath = 1; | ||
219 | req->check = snsid_check; | 220 | req->check = snsid_check; |
220 | req->callback = snsid_callback; | 221 | req->callback = snsid_callback; |
221 | ccw_request_start(cdev); | 222 | ccw_request_start(cdev); |
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index 6facb5499a65..f1fdf0ec7f03 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c | |||
@@ -208,6 +208,7 @@ static void spid_start(struct ccw_device *cdev) | |||
208 | req->timeout = PGID_TIMEOUT; | 208 | req->timeout = PGID_TIMEOUT; |
209 | req->maxretries = PGID_RETRIES; | 209 | req->maxretries = PGID_RETRIES; |
210 | req->lpm = 0x80; | 210 | req->lpm = 0x80; |
211 | req->singlepath = 1; | ||
211 | req->callback = spid_callback; | 212 | req->callback = spid_callback; |
212 | spid_do(cdev); | 213 | spid_do(cdev); |
213 | } | 214 | } |
@@ -420,6 +421,7 @@ static void verify_start(struct ccw_device *cdev) | |||
420 | req->timeout = PGID_TIMEOUT; | 421 | req->timeout = PGID_TIMEOUT; |
421 | req->maxretries = PGID_RETRIES; | 422 | req->maxretries = PGID_RETRIES; |
422 | req->lpm = 0x80; | 423 | req->lpm = 0x80; |
424 | req->singlepath = 1; | ||
423 | if (cdev->private->flags.pgroup) { | 425 | if (cdev->private->flags.pgroup) { |
424 | CIO_TRACE_EVENT(4, "snid"); | 426 | CIO_TRACE_EVENT(4, "snid"); |
425 | CIO_HEX_EVENT(4, devid, sizeof(*devid)); | 427 | CIO_HEX_EVENT(4, devid, sizeof(*devid)); |
@@ -507,6 +509,7 @@ void ccw_device_disband_start(struct ccw_device *cdev) | |||
507 | req->timeout = PGID_TIMEOUT; | 509 | req->timeout = PGID_TIMEOUT; |
508 | req->maxretries = PGID_RETRIES; | 510 | req->maxretries = PGID_RETRIES; |
509 | req->lpm = sch->schib.pmcw.pam & sch->opm; | 511 | req->lpm = sch->schib.pmcw.pam & sch->opm; |
512 | req->singlepath = 1; | ||
510 | req->callback = disband_callback; | 513 | req->callback = disband_callback; |
511 | fn = SPID_FUNC_DISBAND; | 514 | fn = SPID_FUNC_DISBAND; |
512 | if (cdev->private->flags.mpath) | 515 | if (cdev->private->flags.mpath) |
@@ -560,6 +563,7 @@ void ccw_device_stlck_start(struct ccw_device *cdev, void *data, void *buf1, | |||
560 | req->timeout = PGID_TIMEOUT; | 563 | req->timeout = PGID_TIMEOUT; |
561 | req->maxretries = PGID_RETRIES; | 564 | req->maxretries = PGID_RETRIES; |
562 | req->lpm = sch->schib.pmcw.pam & sch->opm; | 565 | req->lpm = sch->schib.pmcw.pam & sch->opm; |
566 | req->singlepath = 1; | ||
563 | req->data = data; | 567 | req->data = data; |
564 | req->callback = stlck_callback; | 568 | req->callback = stlck_callback; |
565 | stlck_build_cp(cdev, buf1, buf2); | 569 | stlck_build_cp(cdev, buf1, buf2); |
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index b9ce712a7f25..469ef93f2302 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h | |||
@@ -92,11 +92,12 @@ enum io_status { | |||
92 | * @filter: optional callback to adjust request status based on IRB data | 92 | * @filter: optional callback to adjust request status based on IRB data |
93 | * @callback: final callback | 93 | * @callback: final callback |
94 | * @data: user-defined pointer passed to all callbacks | 94 | * @data: user-defined pointer passed to all callbacks |
95 | * @singlepath: if set, use only one path from @lpm per start I/O | ||
96 | * @cancel: non-zero if request was cancelled | ||
97 | * @done: non-zero if request was finished | ||
95 | * @mask: current path mask | 98 | * @mask: current path mask |
96 | * @retries: current number of retries | 99 | * @retries: current number of retries |
97 | * @drc: delayed return code | 100 | * @drc: delayed return code |
98 | * @cancel: non-zero if request was cancelled | ||
99 | * @done: non-zero if request was finished | ||
100 | */ | 101 | */ |
101 | struct ccw_request { | 102 | struct ccw_request { |
102 | struct ccw1 *cp; | 103 | struct ccw1 *cp; |
@@ -108,12 +109,13 @@ struct ccw_request { | |||
108 | enum io_status); | 109 | enum io_status); |
109 | void (*callback)(struct ccw_device *, void *, int); | 110 | void (*callback)(struct ccw_device *, void *, int); |
110 | void *data; | 111 | void *data; |
112 | unsigned int singlepath:1; | ||
111 | /* These fields are used internally. */ | 113 | /* These fields are used internally. */ |
114 | unsigned int cancel:1; | ||
115 | unsigned int done:1; | ||
112 | u16 mask; | 116 | u16 mask; |
113 | u16 retries; | 117 | u16 retries; |
114 | int drc; | 118 | int drc; |
115 | int cancel:1; | ||
116 | int done:1; | ||
117 | } __attribute__((packed)); | 119 | } __attribute__((packed)); |
118 | 120 | ||
119 | /* | 121 | /* |