From: Heiko Carstens <heiko.carstens@de.ibm.com>

From: Cornelia Huck <cohuck@de.ibm.com>

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 <heiko.carstens@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 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 <utz.bacher@de.ibm.com>");
@@ -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
_