+++ /dev/null
-From: Gerald Schaefer <geraldsc@de.ibm.com>
-Subject: cio: Properly disable not operational subchannel.
-References: bnc#477666,LTC#51619
-
-Symptom: Kernel BUG at drivers/s390/cio/device_fsm.c:1241!
-Problem: After deferred cc=3 was received on all paths, a
- device was set to not operational to prepare for
- re-evaluation. An unsolicited interrupt indicating
- that the device became accessible again triggered
- an invalid event in the state machine (interrupt in
- not operational state).
-Solution: Properly disable the subchannel before setting the
- device not operational. To be able to disable the
- subchannel reliably, pending status needs to be
- collected.
-
-Acked-by: John Jolly <jjolly@suse.de>
-
----
- drivers/s390/cio/cio.c | 19 +++++--------------
- drivers/s390/cio/device_fsm.c | 4 ++--
- 2 files changed, 7 insertions(+), 16 deletions(-)
-
-Index: linux-sles11/drivers/s390/cio/device_fsm.c
-===================================================================
---- linux-sles11.orig/drivers/s390/cio/device_fsm.c
-+++ linux-sles11/drivers/s390/cio/device_fsm.c
-@@ -726,7 +726,7 @@ static void ccw_device_generic_notoper(s
- {
- struct subchannel *sch;
-
-- cdev->private->state = DEV_STATE_NOT_OPER;
-+ ccw_device_set_notoper(cdev);
- sch = to_subchannel(cdev->dev.parent);
- css_schedule_eval(sch->schid);
- }
-@@ -1048,7 +1048,7 @@ ccw_device_offline_irq(struct ccw_device
- sch = to_subchannel(cdev->dev.parent);
- /*
- * An interrupt in state offline means a previous disable was not
-- * successful. Try again.
-+ * successful - should not happen, but we try to disable again.
- */
- cio_disable_subchannel(sch);
- }
-Index: linux-sles11/drivers/s390/cio/cio.c
-===================================================================
---- linux-sles11.orig/drivers/s390/cio/cio.c
-+++ linux-sles11/drivers/s390/cio/cio.c
-@@ -464,25 +464,16 @@ int cio_disable_subchannel(struct subcha
- if (ccode == 3) /* Not operational. */
- return -ENODEV;
-
-- if (scsw_actl(&sch->schib.scsw) != 0)
-- /*
-- * the disable function must not be called while there are
-- * requests pending for completion !
-- */
-- return -EBUSY;
--
- for (retry = 5, ret = 0; retry > 0; retry--) {
- sch->schib.pmcw.ena = 0;
- ret = cio_modify(sch);
- if (ret == -ENODEV)
- break;
-- if (ret == -EBUSY)
-- /*
-- * The subchannel is busy or status pending.
-- * We'll disable when the next interrupt was delivered
-- * via the state machine.
-- */
-- break;
-+ if (ret == -EBUSY) {
-+ struct irb irb;
-+ if (tsch(sch->schid, &irb) != 0)
-+ break;
-+ }
- if (ret == 0) {
- stsch (sch->schid, &sch->schib);
- if (!sch->schib.pmcw.ena)