Skip to content

Commit

Permalink
[S390] dasd: forward internal errors to dasd_sleep_on caller
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Stefan Weinhuber authored and Martin Schwidefsky committed Jun 12, 2009
1 parent 736e6ea commit 6cc7f16
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 9 deletions.
30 changes: 24 additions & 6 deletions drivers/s390/block/dasd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -915,6 +917,7 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
BUG();
break;
}
cqr->intrc = rc;
return rc;
}

Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down
1 change: 1 addition & 0 deletions drivers/s390/block/dasd_diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ dasd_start_diag(struct dasd_ccw_req * cqr)
rc = -EIO;
break;
}
cqr->intrc = rc;
return rc;
}

Expand Down
8 changes: 5 additions & 3 deletions drivers/s390/block/dasd_eckd.c
Original file line number Diff line number Diff line change
Expand Up @@ -3017,8 +3017,9 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
" I/O status report for device %s:\n",
dev_name(&device->cdev->dev));
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" in req: %p CS: 0x%02X DS: 0x%02X\n", req,
scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw));
" in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d\n",
req, scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
scsw_cc(&irb->scsw), req->intrc);
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" device %s: Failing CCW: %p\n",
dev_name(&device->cdev->dev),
Expand Down Expand Up @@ -3119,9 +3120,10 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
" I/O status report for device %s:\n",
dev_name(&device->cdev->dev));
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" in req: %p CS: 0x%02X DS: 0x%02X "
" in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d "
"fcxs: 0x%02X schxs: 0x%02X\n", req,
scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
scsw_cc(&irb->scsw), req->intrc,
irb->scsw.tm.fcxs, irb->scsw.tm.schxs);
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" device %s: Failing TCW: %p\n",
Expand Down
1 change: 1 addition & 0 deletions drivers/s390/block/dasd_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ struct dasd_ccw_req {
void *data; /* pointer to data area */

/* these are important for recovering erroneous requests */
int intrc; /* internal error, e.g. from start_IO */
struct irb irb; /* device status in case of an error */
struct dasd_ccw_req *refers; /* ERP-chain queueing. */
void *function; /* originating ERP action */
Expand Down

0 comments on commit 6cc7f16

Please sign in to comment.