diff options
author | Michael Holzheu <holzheu@de.ibm.com> | 2006-03-24 12:15:28 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-24 16:33:18 +0100 |
commit | 5f38433885245dce82aa53c20a6b2efbe81ae350 (patch) | |
tree | 1731a5e3b9092f3ff060ac6aa652be8ec6dde890 /drivers/s390/char/tape_std.c | |
parent | [PATCH] s390: tape operation abortion leads to panic (diff) | |
download | linux-5f38433885245dce82aa53c20a6b2efbe81ae350.tar.xz linux-5f38433885245dce82aa53c20a6b2efbe81ae350.zip |
[PATCH] s390: fix endless retry loop in tape driver
If a tape device is assigned to another host, the interrupt for the assign
operation comes back with deferred condition code 1. Under some conditions
this can lead to an endless loop of retries. Check if the current request is
still in IO in deferred condition code handling and prevent retries when the
request has already been cancelled.
Signed-off-by: Michael Holzheu <holzheu@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/s390/char/tape_std.c')
-rw-r--r-- | drivers/s390/char/tape_std.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c index 2f9fe30989a7..99cf881f41db 100644 --- a/drivers/s390/char/tape_std.c +++ b/drivers/s390/char/tape_std.c @@ -37,20 +37,19 @@ tape_std_assign_timeout(unsigned long data) { struct tape_request * request; struct tape_device * device; + int rc; request = (struct tape_request *) data; if ((device = request->device) == NULL) BUG(); - spin_lock_irq(get_ccwdev_lock(device->cdev)); - if (request->callback != NULL) { - DBF_EVENT(3, "%08x: Assignment timeout. Device busy.\n", + DBF_EVENT(3, "%08x: Assignment timeout. Device busy.\n", device->cdev_id); - PRINT_ERR("%s: Assignment timeout. Device busy.\n", - device->cdev->dev.bus_id); - ccw_device_clear(device->cdev, (long) request); - } - spin_unlock_irq(get_ccwdev_lock(device->cdev)); + rc = tape_cancel_io(device, request); + if(rc) + PRINT_ERR("(%s): Assign timeout: Cancel failed with rc = %i\n", + device->cdev->dev.bus_id, rc); + } int |