aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device.c
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2008-12-25 07:39:12 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-12-25 07:39:10 -0500
commitcdb912a40df8b8507ab60b3d52f9980c0ba1f44d (patch)
tree52d693b3515b71b4f84b539d41571facb75498db /drivers/s390/cio/device.c
parentd6a30761d8116b8de8a5b5e79e68cce81d36414b (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.c13
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
1351static int check_for_io_on_path(struct subchannel *sch, int mask) 1351static 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;