diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2008-12-25 07:39:12 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-12-25 07:39:10 -0500 |
commit | cdb912a40df8b8507ab60b3d52f9980c0ba1f44d (patch) | |
tree | 52d693b3515b71b4f84b539d41571facb75498db /drivers/s390/cio/device.c | |
parent | d6a30761d8116b8de8a5b5e79e68cce81d36414b (diff) |
[S390] cio: introduce cio_update_schib
There is the chance that we get condition code 0 for a stsch but
the resulting schib is not vaild. In the current code there are
2 cases:
* we do a check for validity of the schib after stsch, but at this
time we have already stored the invaild schib in the subchannel
structure. This may lead to problems.
* we don't do a check for validity, which is not that good either.
The patch addresses both issues by introducing the stsch wrapper
cio_update_schib which performs stsch on a local schib. This schib
is only written back to the subchannel if it's valid.
side note: For some functions (chp_events) the return codes are
different now (-ENXIO vs -ENODEV) but this shouldn't do harm
since the caller doesn't check for _specific_ errors.
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/device.c')
-rw-r--r-- | drivers/s390/cio/device.c | 13 |
1 files changed, 4 insertions, 9 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 868aa1915380..51e94212bf66 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -1350,10 +1350,7 @@ static void io_subchannel_verify(struct subchannel *sch) | |||
1350 | 1350 | ||
1351 | static int check_for_io_on_path(struct subchannel *sch, int mask) | 1351 | static int check_for_io_on_path(struct subchannel *sch, int mask) |
1352 | { | 1352 | { |
1353 | int cc; | 1353 | if (cio_update_schib(sch)) |
1354 | |||
1355 | cc = stsch(sch->schid, &sch->schib); | ||
1356 | if (cc) | ||
1357 | return 0; | 1354 | return 0; |
1358 | if (scsw_actl(&sch->schib.scsw) && sch->schib.pmcw.lpum == mask) | 1355 | if (scsw_actl(&sch->schib.scsw) && sch->schib.pmcw.lpum == mask) |
1359 | return 1; | 1356 | return 1; |
@@ -1422,15 +1419,13 @@ static int io_subchannel_chp_event(struct subchannel *sch, | |||
1422 | io_subchannel_verify(sch); | 1419 | io_subchannel_verify(sch); |
1423 | break; | 1420 | break; |
1424 | case CHP_OFFLINE: | 1421 | case CHP_OFFLINE: |
1425 | if (stsch(sch->schid, &sch->schib)) | 1422 | if (cio_update_schib(sch)) |
1426 | return -ENXIO; | ||
1427 | if (!css_sch_is_valid(&sch->schib)) | ||
1428 | return -ENODEV; | 1423 | return -ENODEV; |
1429 | io_subchannel_terminate_path(sch, mask); | 1424 | io_subchannel_terminate_path(sch, mask); |
1430 | break; | 1425 | break; |
1431 | case CHP_ONLINE: | 1426 | case CHP_ONLINE: |
1432 | if (stsch(sch->schid, &sch->schib)) | 1427 | if (cio_update_schib(sch)) |
1433 | return -ENXIO; | 1428 | return -ENODEV; |
1434 | sch->lpm |= mask & sch->opm; | 1429 | sch->lpm |= mask & sch->opm; |
1435 | io_subchannel_verify(sch); | 1430 | io_subchannel_verify(sch); |
1436 | break; | 1431 | break; |