diff options
author | Stefan Weinhuber <wein@de.ibm.com> | 2010-10-25 16:10:47 +0200 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-10-25 16:10:20 +0200 |
commit | a5a0061fb3a22bbd9b108af8382142fd0f41ebee (patch) | |
tree | 03e643e12b634b201201cddb162de46aa744595b /drivers/s390/block/dasd.c | |
parent | 26cffecf84c8cb33787dd13a72bd2124d107d413 (diff) |
[S390] dasd: fix unsolicited interrupt recognition
The dasd interrupt handler needs to distinguish solicited from
unsolicited interrupts, as unsolicited interrupts may require special
handling (e.g. summary unit checks) and solicited interrupts require
proper error recovery for the failed I/O request.
The interrupt handler needs to check several bit fields in the
interrupt response block (irb) to make this distinction.
So far our check of the status control bits has not been specific
enough, which may lead to a failed request getting just retried
instead of the necessary error recovery.
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 | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index aa95f1001761..80e45de096a9 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -1099,11 +1099,20 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, cqr = (struct dasd_ccw_req *) intparm; if (!cqr || ((scsw_cc(&irb->scsw) == 1) && (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) && - (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))) { + ((scsw_stctl(&irb->scsw) == SCSW_STCTL_STATUS_PEND) || + (scsw_stctl(&irb->scsw) == (SCSW_STCTL_STATUS_PEND | + SCSW_STCTL_ALERT_STATUS))))) { if (cqr && cqr->status == DASD_CQR_IN_IO) cqr->status = DASD_CQR_QUEUED; + if (cqr) + memcpy(&cqr->irb, irb, sizeof(*irb)); device = dasd_device_from_cdev_locked(cdev); if (!IS_ERR(device)) { + device->discipline->dump_sense_dbf(device, irb, + "unsolicited"); + if ((device->features & DASD_FEATURE_ERPLOG)) + device->discipline->dump_sense(device, cqr, + irb); dasd_device_clear_timer(device); device->discipline->handle_unsolicited_interrupt(device, irb); |