Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Cornelia Huck and committed by
Linus Torvalds
3ba1998e 3d1712c9

+12
+12
drivers/s390/cio/device_fsm.c
··· 827 827 } 828 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 841 /* Add basic sense info to irb. */ 831 842 ccw_device_accumulate_basic_sense(cdev, irb); 832 843 if (cdev->private->flags.dosense) { ··· 845 834 ccw_device_do_sense(cdev, irb); 846 835 return; 847 836 } 837 + call_handler: 848 838 cdev->private->state = DEV_STATE_ONLINE; 849 839 /* Call the handler. */ 850 840 if (ccw_device_call_handler(cdev) && cdev->private->flags.doverify)