aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd.c
diff options
context:
space:
mode:
authorStefan Weinhuber <wein@de.ibm.com>2010-10-25 10:10:47 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-10-25 10:10:20 -0400
commita5a0061fb3a22bbd9b108af8382142fd0f41ebee (patch)
tree03e643e12b634b201201cddb162de46aa744595b /drivers/s390/block/dasd.c
parent26cffecf84c8cb33787dd13a72bd2124d107d413 (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.c11
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,
1099 cqr = (struct dasd_ccw_req *) intparm; 1099 cqr = (struct dasd_ccw_req *) intparm;
1100 if (!cqr || ((scsw_cc(&irb->scsw) == 1) && 1100 if (!cqr || ((scsw_cc(&irb->scsw) == 1) &&
1101 (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) && 1101 (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
1102 (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))) { 1102 ((scsw_stctl(&irb->scsw) == SCSW_STCTL_STATUS_PEND) ||
1103 (scsw_stctl(&irb->scsw) == (SCSW_STCTL_STATUS_PEND |
1104 SCSW_STCTL_ALERT_STATUS))))) {
1103 if (cqr && cqr->status == DASD_CQR_IN_IO) 1105 if (cqr && cqr->status == DASD_CQR_IN_IO)
1104 cqr->status = DASD_CQR_QUEUED; 1106 cqr->status = DASD_CQR_QUEUED;
1107 if (cqr)
1108 memcpy(&cqr->irb, irb, sizeof(*irb));
1105 device = dasd_device_from_cdev_locked(cdev); 1109 device = dasd_device_from_cdev_locked(cdev);
1106 if (!IS_ERR(device)) { 1110 if (!IS_ERR(device)) {
1111 device->discipline->dump_sense_dbf(device, irb,
1112 "unsolicited");
1113 if ((device->features & DASD_FEATURE_ERPLOG))
1114 device->discipline->dump_sense(device, cqr,
1115 irb);
1107 dasd_device_clear_timer(device); 1116 dasd_device_clear_timer(device);
1108 device->discipline->handle_unsolicited_interrupt(device, 1117 device->discipline->handle_unsolicited_interrupt(device,
1109 irb); 1118 irb);