aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd.c
diff options
context:
space:
mode:
authorStefan Weinhuber <wein@de.ibm.com>2010-10-25 16:10:47 +0200
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-10-25 16:10:20 +0200
commita5a0061fb3a22bbd9b108af8382142fd0f41ebee (patch)
tree03e643e12b634b201201cddb162de46aa744595b /drivers/s390/block/dasd.c
parent26cffecf84c8cb33787dd13a72bd2124d107d413 (diff)
downloadkernel_samsung_smdk4412-a5a0061fb3a22bbd9b108af8382142fd0f41ebee.zip
kernel_samsung_smdk4412-a5a0061fb3a22bbd9b108af8382142fd0f41ebee.tar.gz
kernel_samsung_smdk4412-a5a0061fb3a22bbd9b108af8382142fd0f41ebee.tar.bz2
[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 aa95f10..80e45de 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);