[S390] ccwreq: add ability to use all paths
authorSebastian Ott <sebott@linux.vnet.ibm.com>
Mon, 9 Aug 2010 16:12:53 +0000 (18:12 +0200)
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>
Mon, 9 Aug 2010 16:12:54 +0000 (18:12 +0200)
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>
drivers/s390/cio/ccwreq.c
drivers/s390/cio/device_id.c
drivers/s390/cio/device_pgid.c
drivers/s390/cio/io_sch.h

index fd0368785ee0f5b201e687576d20577b57601cc1..d15f8b4d78bd5f67476dafd0d6e320093a75d59c 100644 (file)
@@ -38,9 +38,13 @@ static u16 ccwreq_next_path(struct ccw_device *cdev)
 {
        struct ccw_request *req = &cdev->private->req;
 
+       if (!req->singlepath) {
+               req->mask = 0;
+               goto out;
+       }
        req->retries    = req->maxretries;
        req->mask       = lpm_adjust(req->mask >>= 1, req->lpm);
-
+out:
        return req->mask;
 }
 
@@ -113,8 +117,12 @@ void ccw_request_start(struct ccw_device *cdev)
 {
        struct ccw_request *req = &cdev->private->req;
 
-       /* Try all paths twice to counter link flapping. */
-       req->mask       = 0x8080;
+       if (req->singlepath) {
+               /* Try all paths twice to counter link flapping. */
+               req->mask = 0x8080;
+       } else
+               req->mask = req->lpm;
+
        req->retries    = req->maxretries;
        req->mask       = lpm_adjust(req->mask, req->lpm);
        req->drc        = 0;
index 78a0b43862c5feb41c0888812c978f686f5f4891..0d7fe4dab3b6ba9736dcfeaca66dbca9f611509f 100644 (file)
@@ -216,6 +216,7 @@ void ccw_device_sense_id_start(struct ccw_device *cdev)
        req->timeout    = SENSE_ID_TIMEOUT;
        req->maxretries = SENSE_ID_RETRIES;
        req->lpm        = sch->schib.pmcw.pam & sch->opm;
+       req->singlepath = 1;
        req->check      = snsid_check;
        req->callback   = snsid_callback;
        ccw_request_start(cdev);
index 6facb5499a6529dd3fbafe725d69457c302dcc04..f1fdf0ec7f0307d5c398904995891814a0e90215 100644 (file)
@@ -208,6 +208,7 @@ static void spid_start(struct ccw_device *cdev)
        req->timeout    = PGID_TIMEOUT;
        req->maxretries = PGID_RETRIES;
        req->lpm        = 0x80;
+       req->singlepath = 1;
        req->callback   = spid_callback;
        spid_do(cdev);
 }
@@ -420,6 +421,7 @@ static void verify_start(struct ccw_device *cdev)
        req->timeout    = PGID_TIMEOUT;
        req->maxretries = PGID_RETRIES;
        req->lpm        = 0x80;
+       req->singlepath = 1;
        if (cdev->private->flags.pgroup) {
                CIO_TRACE_EVENT(4, "snid");
                CIO_HEX_EVENT(4, devid, sizeof(*devid));
@@ -507,6 +509,7 @@ void ccw_device_disband_start(struct ccw_device *cdev)
        req->timeout    = PGID_TIMEOUT;
        req->maxretries = PGID_RETRIES;
        req->lpm        = sch->schib.pmcw.pam & sch->opm;
+       req->singlepath = 1;
        req->callback   = disband_callback;
        fn = SPID_FUNC_DISBAND;
        if (cdev->private->flags.mpath)
@@ -560,6 +563,7 @@ void ccw_device_stlck_start(struct ccw_device *cdev, void *data, void *buf1,
        req->timeout    = PGID_TIMEOUT;
        req->maxretries = PGID_RETRIES;
        req->lpm        = sch->schib.pmcw.pam & sch->opm;
+       req->singlepath = 1;
        req->data       = data;
        req->callback   = stlck_callback;
        stlck_build_cp(cdev, buf1, buf2);
index b9ce712a7f25847fcd752585c256273ab28f323a..469ef93f2302128da21cb6ce6f75751c04f957d3 100644 (file)
@@ -92,11 +92,12 @@ enum io_status {
  * @filter: optional callback to adjust request status based on IRB data
  * @callback: final callback
  * @data: user-defined pointer passed to all callbacks
+ * @singlepath: if set, use only one path from @lpm per start I/O
+ * @cancel: non-zero if request was cancelled
+ * @done: non-zero if request was finished
  * @mask: current path mask
  * @retries: current number of retries
  * @drc: delayed return code
- * @cancel: non-zero if request was cancelled
- * @done: non-zero if request was finished
  */
 struct ccw_request {
        struct ccw1 *cp;
@@ -108,12 +109,13 @@ struct ccw_request {
                                 enum io_status);
        void (*callback)(struct ccw_device *, void *, int);
        void *data;
+       unsigned int singlepath:1;
        /* These fields are used internally. */
+       unsigned int cancel:1;
+       unsigned int done:1;
        u16 mask;
        u16 retries;
        int drc;
-       int cancel:1;
-       int done:1;
 } __attribute__((packed));
 
 /*