diff options
author | Stefan Weinhuber <wein@de.ibm.com> | 2009-06-12 10:26:39 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-06-12 10:27:36 +0200 |
commit | 6cc7f168954fe8b3d8988a90b2478a9c11c5ebcb (patch) | |
tree | de3ee836f75f4cd1010a78c49d42393198b6f955 /drivers/s390/block/dasd.c | |
parent | 736e6ea0bf97ec79521f88704ce8506e5d60d078 (diff) |
[S390] dasd: forward internal errors to dasd_sleep_on caller
If a DASD requests is started with dasd_sleep_on and fails, then the
calling function may need to know the reason for the failure.
In cases of hardware errors it can inspect the sense data in the irb,
but when the reason is internal (e.g. start_IO failed) then it needs
a meaningfull return code.
Signed-off-by: Stefan Weinhuber <wein@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block/dasd.c')
-rw-r--r-- | drivers/s390/block/dasd.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 35f43bea5d0..442bb98a282 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -851,8 +851,10 @@ int dasd_start_IO(struct dasd_ccw_req *cqr) /* Check the cqr */ rc = dasd_check_cqr(cqr); - if (rc) + if (rc) { + cqr->intrc = rc; return rc; + } device = (struct dasd_device *) cqr->startdev; if (cqr->retries < 0) { /* internal error 14 - start_IO run out of retries */ @@ -915,6 +917,7 @@ int dasd_start_IO(struct dasd_ccw_req *cqr) BUG(); break; } + cqr->intrc = rc; return rc; } @@ -1454,8 +1457,12 @@ int dasd_sleep_on(struct dasd_ccw_req *cqr) dasd_add_request_tail(cqr); wait_event(generic_waitq, _wait_for_wakeup(cqr)); - /* Request status is either done or failed. */ - rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; + if (cqr->status == DASD_CQR_DONE) + rc = 0; + else if (cqr->intrc) + rc = cqr->intrc; + else + rc = -EIO; return rc; } @@ -1477,8 +1484,15 @@ int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr) dasd_cancel_req(cqr); /* wait (non-interruptible) for final status */ wait_event(generic_waitq, _wait_for_wakeup(cqr)); + cqr->intrc = rc; } - rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; + + if (cqr->status == DASD_CQR_DONE) + rc = 0; + else if (cqr->intrc) + rc = cqr->intrc; + else + rc = -EIO; return rc; } @@ -1523,8 +1537,12 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr) wait_event(generic_waitq, _wait_for_wakeup(cqr)); - /* Request status is either done or failed. */ - rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; + if (cqr->status == DASD_CQR_DONE) + rc = 0; + else if (cqr->intrc) + rc = cqr->intrc; + else + rc = -EIO; return rc; } |