From 982bdf814616bec77c920e16ea4108d409f144ed Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 9 Aug 2010 18:12:53 +0200 Subject: [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 Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/ccwreq.c | 14 +++++++++++--- drivers/s390/cio/device_id.c | 1 + drivers/s390/cio/device_pgid.c | 4 ++++ drivers/s390/cio/io_sch.h | 10 ++++++---- 4 files changed, 22 insertions(+), 7 deletions(-) (limited to 'drivers/s390/cio') 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) { 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; 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) 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); 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) 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); 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 { * @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)); /* -- cgit v1.2.2