diff options
author | Stefan Haberland <stefan.haberland@de.ibm.com> | 2010-05-26 17:27:09 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-05-26 17:27:09 -0400 |
commit | a23ed009a726feeafdbabeaf5f0bde1a3f04d121 (patch) | |
tree | cd2448ca9544f23acacc40e5ab2b95b4636ef923 | |
parent | 094f2100d6bb16ef0c4f82167cc55173ca22ee93 (diff) |
[S390] dasd: unit check handling during internal cio I/O
React on unit checks during cio internal I/O.
Handle as unsolicited interrupt and advice cio to retry.
Signed-off-by: Stefan Haberland <stefan.haberland@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | drivers/s390/block/dasd.c | 23 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 1 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 1 |
3 files changed, 25 insertions, 0 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 0e86247d791e..33975e922d65 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -1186,6 +1186,29 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
1186 | dasd_schedule_device_bh(device); | 1186 | dasd_schedule_device_bh(device); |
1187 | } | 1187 | } |
1188 | 1188 | ||
1189 | enum uc_todo dasd_generic_uc_handler(struct ccw_device *cdev, struct irb *irb) | ||
1190 | { | ||
1191 | struct dasd_device *device; | ||
1192 | |||
1193 | device = dasd_device_from_cdev_locked(cdev); | ||
1194 | |||
1195 | if (IS_ERR(device)) | ||
1196 | goto out; | ||
1197 | if (test_bit(DASD_FLAG_OFFLINE, &device->flags) || | ||
1198 | device->state != device->target || | ||
1199 | !device->discipline->handle_unsolicited_interrupt){ | ||
1200 | dasd_put_device(device); | ||
1201 | goto out; | ||
1202 | } | ||
1203 | |||
1204 | dasd_device_clear_timer(device); | ||
1205 | device->discipline->handle_unsolicited_interrupt(device, irb); | ||
1206 | dasd_put_device(device); | ||
1207 | out: | ||
1208 | return UC_TODO_RETRY; | ||
1209 | } | ||
1210 | EXPORT_SYMBOL_GPL(dasd_generic_uc_handler); | ||
1211 | |||
1189 | /* | 1212 | /* |
1190 | * If we have an error on a dasd_block layer request then we cancel | 1213 | * If we have an error on a dasd_block layer request then we cancel |
1191 | * and return all further requests from the same dasd_block as well. | 1214 | * and return all further requests from the same dasd_block as well. |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 5b1cd8d6e971..ab84da5592e8 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -3436,6 +3436,7 @@ static struct ccw_driver dasd_eckd_driver = { | |||
3436 | .freeze = dasd_generic_pm_freeze, | 3436 | .freeze = dasd_generic_pm_freeze, |
3437 | .thaw = dasd_generic_restore_device, | 3437 | .thaw = dasd_generic_restore_device, |
3438 | .restore = dasd_generic_restore_device, | 3438 | .restore = dasd_generic_restore_device, |
3439 | .uc_handler = dasd_generic_uc_handler, | ||
3439 | }; | 3440 | }; |
3440 | 3441 | ||
3441 | /* | 3442 | /* |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 32fac186ba3f..49b431d135e0 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -617,6 +617,7 @@ int dasd_generic_notify(struct ccw_device *, int); | |||
617 | void dasd_generic_handle_state_change(struct dasd_device *); | 617 | void dasd_generic_handle_state_change(struct dasd_device *); |
618 | int dasd_generic_pm_freeze(struct ccw_device *); | 618 | int dasd_generic_pm_freeze(struct ccw_device *); |
619 | int dasd_generic_restore_device(struct ccw_device *); | 619 | int dasd_generic_restore_device(struct ccw_device *); |
620 | enum uc_todo dasd_generic_uc_handler(struct ccw_device *, struct irb *); | ||
620 | 621 | ||
621 | int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int); | 622 | int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int); |
622 | char *dasd_get_sense(struct irb *); | 623 | char *dasd_get_sense(struct irb *); |