summaryrefslogtreecommitdiff
path: root/drivers/s390/cio
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2009-03-26 15:24:06 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-03-26 15:24:12 +0100
commited04b892e28ae96662fbb3f4c961df5ff3385d28 (patch)
tree0cdfe7d22f306157eaa91162dd04b722ffe1bbeb /drivers/s390/cio
parenteb32ae8d0e052d1a287f99f93130ea2ad9af317e (diff)
downloadlinux-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.c18
-rw-r--r--drivers/s390/cio/device_fsm.c2
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);
}