aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device_fsm.c
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2006-03-24 06:15:12 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-24 10:33:15 -0500
commit3ba1998e90239ed0d7af918998bc866fa77303eb (patch)
tree6417c281e7121149b86246a26ac136c9973e2b7d /drivers/s390/cio/device_fsm.c
parent3d1712c91df01d2573b934e972e231e8edb102c7 (diff)
[PATCH] s390: wrong interrupt delivered for hsch() or csch()
When cio waits for the interrupt for a basic sense, interrupts for hsch() or csch() issued in the meantime are wrongly counted as interrupts for the basic sense and the accumulated irb is passed to the device driver. In ccw_device_w4sense(), check for clear or halt function in the irb and pass the irb for the csch() or hsch() to the device driver. Signed-off-by: Cornelia Huck <cornelia.huck@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/cio/device_fsm.c')
-rw-r--r--drivers/s390/cio/device_fsm.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index b302779e7cff..180b3bf8b90d 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -827,6 +827,17 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
827 } 827 }
828 return; 828 return;
829 } 829 }
830 /*
831 * Check if a halt or clear has been issued in the meanwhile. If yes,
832 * only deliver the halt/clear interrupt to the device driver as if it
833 * had killed the original request.
834 */
835 if (irb->scsw.fctl & (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) {
836 cdev->private->flags.dosense = 0;
837 memset(&cdev->private->irb, 0, sizeof(struct irb));
838 ccw_device_accumulate_irb(cdev, irb);
839 goto call_handler;
840 }
830 /* Add basic sense info to irb. */ 841 /* Add basic sense info to irb. */
831 ccw_device_accumulate_basic_sense(cdev, irb); 842 ccw_device_accumulate_basic_sense(cdev, irb);
832 if (cdev->private->flags.dosense) { 843 if (cdev->private->flags.dosense) {
@@ -834,6 +845,7 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
834 ccw_device_do_sense(cdev, irb); 845 ccw_device_do_sense(cdev, irb);
835 return; 846 return;
836 } 847 }
848call_handler:
837 cdev->private->state = DEV_STATE_ONLINE; 849 cdev->private->state = DEV_STATE_ONLINE;
838 /* Call the handler. */ 850 /* Call the handler. */
839 if (ccw_device_call_handler(cdev) && cdev->private->flags.doverify) 851 if (ccw_device_call_handler(cdev) && cdev->private->flags.doverify)