diff options
author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2009-03-26 10:24:06 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-03-26 10:24:12 -0400 |
commit | ed04b892e28ae96662fbb3f4c961df5ff3385d28 (patch) | |
tree | 0cdfe7d22f306157eaa91162dd04b722ffe1bbeb /drivers/s390/cio | |
parent | eb32ae8d0e052d1a287f99f93130ea2ad9af317e (diff) |
[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 73135c5e9dfb..2aebb9823044 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -472,6 +472,7 @@ EXPORT_SYMBOL_GPL(cio_enable_subchannel); | |||
472 | int cio_disable_subchannel(struct subchannel *sch) | 472 | int cio_disable_subchannel(struct subchannel *sch) |
473 | { | 473 | { |
474 | char dbf_txt[15]; | 474 | char dbf_txt[15]; |
475 | int retry; | ||
475 | int ret; | 476 | int ret; |
476 | 477 | ||
477 | CIO_TRACE_EVENT (2, "dissch"); | 478 | CIO_TRACE_EVENT (2, "dissch"); |
@@ -482,16 +483,17 @@ int cio_disable_subchannel(struct subchannel *sch) | |||
482 | if (cio_update_schib(sch)) | 483 | if (cio_update_schib(sch)) |
483 | return -ENODEV; | 484 | return -ENODEV; |
484 | 485 | ||
485 | if (scsw_actl(&sch->schib.scsw) != 0) | ||
486 | /* | ||
487 | * the disable function must not be called while there are | ||
488 | * requests pending for completion ! | ||
489 | */ | ||
490 | return -EBUSY; | ||
491 | |||
492 | sch->config.ena = 0; | 486 | sch->config.ena = 0; |
493 | ret = cio_commit_config(sch); | ||
494 | 487 | ||
488 | for (retry = 0; retry < 3; retry++) { | ||
489 | ret = cio_commit_config(sch); | ||
490 | if (ret == -EBUSY) { | ||
491 | struct irb irb; | ||
492 | if (tsch(sch->schid, &irb) != 0) | ||
493 | break; | ||
494 | } else | ||
495 | break; | ||
496 | } | ||
495 | sprintf (dbf_txt, "ret:%d", ret); | 497 | sprintf (dbf_txt, "ret:%d", ret); |
496 | CIO_TRACE_EVENT (2, dbf_txt); | 498 | CIO_TRACE_EVENT (2, dbf_txt); |
497 | return ret; | 499 | return ret; |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 95f2f352cb9d..301d27bf944e 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) | |||
1052 | sch = to_subchannel(cdev->dev.parent); | 1052 | sch = to_subchannel(cdev->dev.parent); |
1053 | /* | 1053 | /* |
1054 | * An interrupt in state offline means a previous disable was not | 1054 | * An interrupt in state offline means a previous disable was not |
1055 | * successful. Try again. | 1055 | * successful - should not happen, but we try to disable again. |
1056 | */ | 1056 | */ |
1057 | cio_disable_subchannel(sch); | 1057 | cio_disable_subchannel(sch); |
1058 | } | 1058 | } |