diff options
author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2009-03-26 15:24:06 +0100 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-03-26 15:24:12 +0100 |
commit | ed04b892e28ae96662fbb3f4c961df5ff3385d28 (patch) | |
tree | 0cdfe7d22f306157eaa91162dd04b722ffe1bbeb /drivers/s390/cio | |
parent | eb32ae8d0e052d1a287f99f93130ea2ad9af317e (diff) | |
download | linux-3.10-ed04b892e28ae96662fbb3f4c961df5ff3385d28.tar.gz linux-3.10-ed04b892e28ae96662fbb3f4c961df5ff3385d28.tar.bz2 linux-3.10-ed04b892e28ae96662fbb3f4c961df5ff3385d28.zip |
[S390] cio: Try harder to disable subchannel.
Acting upon the assumption that cio_disable_subchannel()
is only called when we really want to disable the subchannel
(a) remove the check for activity (it is already done in
ccw_device_offline(), which is the place where it matters)
(b) collect pending status via tsch() and ignore it (it
can't matter anymore since the subchannel will be disabled).
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r-- | drivers/s390/cio/cio.c | 18 | ||||
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 2 |
2 files changed, 11 insertions, 9 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 73135c5e9df..2aebb982304 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -472,6 +472,7 @@ EXPORT_SYMBOL_GPL(cio_enable_subchannel); int cio_disable_subchannel(struct subchannel *sch) { char dbf_txt[15]; + int retry; int ret; CIO_TRACE_EVENT (2, "dissch"); @@ -482,16 +483,17 @@ int cio_disable_subchannel(struct subchannel *sch) if (cio_update_schib(sch)) 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; - sch->config.ena = 0; - ret = cio_commit_config(sch); + for (retry = 0; retry < 3; retry++) { + ret = cio_commit_config(sch); + if (ret == -EBUSY) { + struct irb irb; + if (tsch(sch->schid, &irb) != 0) + break; + } else + break; + } sprintf (dbf_txt, "ret:%d", ret); CIO_TRACE_EVENT (2, dbf_txt); return ret; diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 95f2f352cb9..301d27bf944 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -1052,7 +1052,7 @@ ccw_device_offline_irq(struct ccw_device *cdev, enum dev_event dev_event) 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); } |