diff options
author | Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 2006-09-20 09:59:59 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-09-20 09:59:59 -0400 |
commit | 28bdc6f6233f380ddc0b430cabd88ffeafea34c7 (patch) | |
tree | be2c8e7943dab4328fcbe18cd6e03c50a82e0f34 /drivers/s390/cio/device_fsm.c | |
parent | e0e32c8eba86fd5ea79eefad6f2c0b4988dfd02a (diff) |
[S390] cio: always query all paths on path verification.
Reappearing channel paths are sometimes not utilized by CCW devices
because path verification incorrectly relies on path-operational-mask
information which is not updated until a channel path has been used
again.
Modify path verification procedure to always query all available paths
to a device.
Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/device_fsm.c')
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 7756f324fb6f..dace46fc32e8 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -232,10 +232,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
232 | */ | 232 | */ |
233 | old_lpm = sch->lpm; | 233 | old_lpm = sch->lpm; |
234 | stsch(sch->schid, &sch->schib); | 234 | stsch(sch->schid, &sch->schib); |
235 | sch->lpm = sch->schib.pmcw.pim & | 235 | sch->lpm = sch->schib.pmcw.pam & sch->opm; |
236 | sch->schib.pmcw.pam & | ||
237 | sch->schib.pmcw.pom & | ||
238 | sch->opm; | ||
239 | /* Check since device may again have become not operational. */ | 236 | /* Check since device may again have become not operational. */ |
240 | if (!sch->schib.pmcw.dnv) | 237 | if (!sch->schib.pmcw.dnv) |
241 | state = DEV_STATE_NOT_OPER; | 238 | state = DEV_STATE_NOT_OPER; |
@@ -455,8 +452,8 @@ ccw_device_sense_pgid_done(struct ccw_device *cdev, int err) | |||
455 | return; | 452 | return; |
456 | } | 453 | } |
457 | /* Start Path Group verification. */ | 454 | /* Start Path Group verification. */ |
458 | sch->vpm = 0; /* Start with no path groups set. */ | ||
459 | cdev->private->state = DEV_STATE_VERIFY; | 455 | cdev->private->state = DEV_STATE_VERIFY; |
456 | cdev->private->flags.doverify = 0; | ||
460 | ccw_device_verify_start(cdev); | 457 | ccw_device_verify_start(cdev); |
461 | } | 458 | } |
462 | 459 | ||
@@ -556,7 +553,19 @@ ccw_device_nopath_notify(void *data) | |||
556 | void | 553 | void |
557 | ccw_device_verify_done(struct ccw_device *cdev, int err) | 554 | ccw_device_verify_done(struct ccw_device *cdev, int err) |
558 | { | 555 | { |
559 | cdev->private->flags.doverify = 0; | 556 | struct subchannel *sch; |
557 | |||
558 | sch = to_subchannel(cdev->dev.parent); | ||
559 | /* Update schib - pom may have changed. */ | ||
560 | stsch(sch->schid, &sch->schib); | ||
561 | /* Update lpm with verified path mask. */ | ||
562 | sch->lpm = sch->vpm; | ||
563 | /* Repeat path verification? */ | ||
564 | if (cdev->private->flags.doverify) { | ||
565 | cdev->private->flags.doverify = 0; | ||
566 | ccw_device_verify_start(cdev); | ||
567 | return; | ||
568 | } | ||
560 | switch (err) { | 569 | switch (err) { |
561 | case -EOPNOTSUPP: /* path grouping not supported, just set online. */ | 570 | case -EOPNOTSUPP: /* path grouping not supported, just set online. */ |
562 | cdev->private->options.pgroup = 0; | 571 | cdev->private->options.pgroup = 0; |
@@ -614,6 +623,7 @@ ccw_device_online(struct ccw_device *cdev) | |||
614 | if (!cdev->private->options.pgroup) { | 623 | if (!cdev->private->options.pgroup) { |
615 | /* Start initial path verification. */ | 624 | /* Start initial path verification. */ |
616 | cdev->private->state = DEV_STATE_VERIFY; | 625 | cdev->private->state = DEV_STATE_VERIFY; |
626 | cdev->private->flags.doverify = 0; | ||
617 | ccw_device_verify_start(cdev); | 627 | ccw_device_verify_start(cdev); |
618 | return 0; | 628 | return 0; |
619 | } | 629 | } |
@@ -660,7 +670,6 @@ ccw_device_offline(struct ccw_device *cdev) | |||
660 | /* Are we doing path grouping? */ | 670 | /* Are we doing path grouping? */ |
661 | if (!cdev->private->options.pgroup) { | 671 | if (!cdev->private->options.pgroup) { |
662 | /* No, set state offline immediately. */ | 672 | /* No, set state offline immediately. */ |
663 | sch->vpm = 0; | ||
664 | ccw_device_done(cdev, DEV_STATE_OFFLINE); | 673 | ccw_device_done(cdev, DEV_STATE_OFFLINE); |
665 | return 0; | 674 | return 0; |
666 | } | 675 | } |
@@ -781,6 +790,7 @@ ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event) | |||
781 | } | 790 | } |
782 | /* Device is idle, we can do the path verification. */ | 791 | /* Device is idle, we can do the path verification. */ |
783 | cdev->private->state = DEV_STATE_VERIFY; | 792 | cdev->private->state = DEV_STATE_VERIFY; |
793 | cdev->private->flags.doverify = 0; | ||
784 | ccw_device_verify_start(cdev); | 794 | ccw_device_verify_start(cdev); |
785 | } | 795 | } |
786 | 796 | ||
@@ -1043,9 +1053,9 @@ ccw_device_wait4io_timeout(struct ccw_device *cdev, enum dev_event dev_event) | |||
1043 | } | 1053 | } |
1044 | 1054 | ||
1045 | static void | 1055 | static void |
1046 | ccw_device_wait4io_verify(struct ccw_device *cdev, enum dev_event dev_event) | 1056 | ccw_device_delay_verify(struct ccw_device *cdev, enum dev_event dev_event) |
1047 | { | 1057 | { |
1048 | /* When the I/O has terminated, we have to start verification. */ | 1058 | /* Start verification after current task finished. */ |
1049 | cdev->private->flags.doverify = 1; | 1059 | cdev->private->flags.doverify = 1; |
1050 | } | 1060 | } |
1051 | 1061 | ||
@@ -1111,10 +1121,7 @@ device_trigger_reprobe(struct subchannel *sch) | |||
1111 | * The pim, pam, pom values may not be accurate, but they are the best | 1121 | * The pim, pam, pom values may not be accurate, but they are the best |
1112 | * we have before performing device selection :/ | 1122 | * we have before performing device selection :/ |
1113 | */ | 1123 | */ |
1114 | sch->lpm = sch->schib.pmcw.pim & | 1124 | sch->lpm = sch->schib.pmcw.pam & sch->opm; |
1115 | sch->schib.pmcw.pam & | ||
1116 | sch->schib.pmcw.pom & | ||
1117 | sch->opm; | ||
1118 | /* Re-set some bits in the pmcw that were lost. */ | 1125 | /* Re-set some bits in the pmcw that were lost. */ |
1119 | sch->schib.pmcw.isc = 3; | 1126 | sch->schib.pmcw.isc = 3; |
1120 | sch->schib.pmcw.csense = 1; | 1127 | sch->schib.pmcw.csense = 1; |
@@ -1238,7 +1245,7 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1238 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, | 1245 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, |
1239 | [DEV_EVENT_INTERRUPT] = ccw_device_verify_irq, | 1246 | [DEV_EVENT_INTERRUPT] = ccw_device_verify_irq, |
1240 | [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, | 1247 | [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, |
1241 | [DEV_EVENT_VERIFY] = ccw_device_nop, | 1248 | [DEV_EVENT_VERIFY] = ccw_device_delay_verify, |
1242 | }, | 1249 | }, |
1243 | [DEV_STATE_ONLINE] = { | 1250 | [DEV_STATE_ONLINE] = { |
1244 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, | 1251 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, |
@@ -1281,7 +1288,7 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1281 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, | 1288 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, |
1282 | [DEV_EVENT_INTERRUPT] = ccw_device_wait4io_irq, | 1289 | [DEV_EVENT_INTERRUPT] = ccw_device_wait4io_irq, |
1283 | [DEV_EVENT_TIMEOUT] = ccw_device_wait4io_timeout, | 1290 | [DEV_EVENT_TIMEOUT] = ccw_device_wait4io_timeout, |
1284 | [DEV_EVENT_VERIFY] = ccw_device_wait4io_verify, | 1291 | [DEV_EVENT_VERIFY] = ccw_device_delay_verify, |
1285 | }, | 1292 | }, |
1286 | [DEV_STATE_QUIESCE] = { | 1293 | [DEV_STATE_QUIESCE] = { |
1287 | [DEV_EVENT_NOTOPER] = ccw_device_quiesce_done, | 1294 | [DEV_EVENT_NOTOPER] = ccw_device_quiesce_done, |
@@ -1294,7 +1301,7 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1294 | [DEV_EVENT_NOTOPER] = ccw_device_nop, | 1301 | [DEV_EVENT_NOTOPER] = ccw_device_nop, |
1295 | [DEV_EVENT_INTERRUPT] = ccw_device_start_id, | 1302 | [DEV_EVENT_INTERRUPT] = ccw_device_start_id, |
1296 | [DEV_EVENT_TIMEOUT] = ccw_device_bug, | 1303 | [DEV_EVENT_TIMEOUT] = ccw_device_bug, |
1297 | [DEV_EVENT_VERIFY] = ccw_device_nop, | 1304 | [DEV_EVENT_VERIFY] = ccw_device_start_id, |
1298 | }, | 1305 | }, |
1299 | [DEV_STATE_DISCONNECTED_SENSE_ID] = { | 1306 | [DEV_STATE_DISCONNECTED_SENSE_ID] = { |
1300 | [DEV_EVENT_NOTOPER] = ccw_device_recog_notoper, | 1307 | [DEV_EVENT_NOTOPER] = ccw_device_recog_notoper, |