aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device_fsm.c
diff options
context:
space:
mode:
authorPeter Oberparleiter <peter.oberparleiter@de.ibm.com>2006-09-20 09:59:59 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-09-20 09:59:59 -0400
commit28bdc6f6233f380ddc0b430cabd88ffeafea34c7 (patch)
treebe2c8e7943dab4328fcbe18cd6e03c50a82e0f34 /drivers/s390/cio/device_fsm.c
parente0e32c8eba86fd5ea79eefad6f2c0b4988dfd02a (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.c39
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)
556void 553void
557ccw_device_verify_done(struct ccw_device *cdev, int err) 554ccw_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
1045static void 1055static void
1046ccw_device_wait4io_verify(struct ccw_device *cdev, enum dev_event dev_event) 1056ccw_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,