From: Heiko Carstens From: Cornelia Huck common i/o layer changes: - Cope with changed cdev->handler. - Split clearing of subchannels from reipl function and declare it in header. Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton --- 25-akpm/drivers/s390/cio/cio.c | 19 +++++++++++++------ 25-akpm/drivers/s390/cio/qdio.c | 11 ++++++++++- 25-akpm/include/asm-s390/cio.h | 2 ++ 3 files changed, 25 insertions(+), 7 deletions(-) diff -puN drivers/s390/cio/cio.c~s390-common-i-o-layer drivers/s390/cio/cio.c --- 25/drivers/s390/cio/cio.c~s390-common-i-o-layer 2004-12-28 00:39:16.642311576 -0800 +++ 25-akpm/drivers/s390/cio/cio.c 2004-12-28 00:39:16.649310512 -0800 @@ -1,7 +1,7 @@ /* * drivers/s390/cio/cio.c * S/390 common I/O routines -- low level i/o calls - * $Revision: 1.128 $ + * $Revision: 1.130 $ * * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, * IBM Corporation @@ -813,9 +813,10 @@ __clear_subchannel_easy(unsigned int sch } extern void do_reipl(unsigned long devno); -/* Make sure all subchannels are quiet before we re-ipl an lpar. */ + +/* Clear all subchannels. */ void -reipl(unsigned long devno) +clear_all_subchannels(void) { unsigned int schid; @@ -823,7 +824,7 @@ reipl(unsigned long devno) for (schid=0;schid<=highest_subchannel;schid++) { struct schib schib; if (stsch(schid, &schib)) - goto out; + break; /* break out of the loop */ if (!schib.pmcw.ena) continue; switch(__disable_subchannel_easy(schid, &schib)) { @@ -832,11 +833,17 @@ reipl(unsigned long devno) break; default: /* -EBUSY */ if (__clear_subchannel_easy(schid)) - break; /* give up... */ + break; /* give up... jump out of switch */ stsch(schid, &schib); __disable_subchannel_easy(schid, &schib); } } -out: +} + +/* Make sure all subchannels are quiet before we re-ipl an lpar. */ +void +reipl(unsigned long devno) +{ + clear_all_subchannels(); do_reipl(devno); } diff -puN drivers/s390/cio/qdio.c~s390-common-i-o-layer drivers/s390/cio/qdio.c --- 25/drivers/s390/cio/qdio.c~s390-common-i-o-layer 2004-12-28 00:39:16.643311424 -0800 +++ 25-akpm/drivers/s390/cio/qdio.c 2004-12-28 00:39:16.652310056 -0800 @@ -56,7 +56,7 @@ #include "ioasm.h" #include "chsc.h" -#define VERSION_QDIO_C "$Revision: 1.93 $" +#define VERSION_QDIO_C "$Revision: 1.94 $" /****************** MODULE PARAMETER VARIABLES ********************/ MODULE_AUTHOR("Utz Bacher "); @@ -2321,6 +2321,15 @@ qdio_shutdown(struct ccw_device *cdev, i /* No need to wait for device no longer present. */ qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); + } else if (((void *)cdev->handler != (void *)qdio_handler) && rc == 0) { + /* + * Whoever put another handler there, has to cope with the + * interrupt theirself. Might happen if qdio_shutdown was + * called on already shutdown queues, but this shouldn't have + * bad side effects. + */ + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); + spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); } else if (rc == 0) { qdio_set_state(irq_ptr, QDIO_IRQ_STATE_CLEANUP); ccw_device_set_timeout(cdev, timeout); diff -puN include/asm-s390/cio.h~s390-common-i-o-layer include/asm-s390/cio.h --- 25/include/asm-s390/cio.h~s390-common-i-o-layer 2004-12-28 00:39:16.645311120 -0800 +++ 25-akpm/include/asm-s390/cio.h 2004-12-28 00:39:16.652310056 -0800 @@ -274,6 +274,8 @@ extern int diag210(struct diag210 *addr) extern void wait_cons_dev(void); +extern void clear_all_subchannels(void); + #endif #endif _