diff options
Diffstat (limited to 'drivers/s390/cio/device_fsm.c')
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 35e162ba6d54..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; |
@@ -267,6 +264,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
267 | notify = 1; | 264 | notify = 1; |
268 | } | 265 | } |
269 | /* fill out sense information */ | 266 | /* fill out sense information */ |
267 | memset(&cdev->id, 0, sizeof(cdev->id)); | ||
270 | cdev->id.cu_type = cdev->private->senseid.cu_type; | 268 | cdev->id.cu_type = cdev->private->senseid.cu_type; |
271 | cdev->id.cu_model = cdev->private->senseid.cu_model; | 269 | cdev->id.cu_model = cdev->private->senseid.cu_model; |
272 | cdev->id.dev_type = cdev->private->senseid.dev_type; | 270 | cdev->id.dev_type = cdev->private->senseid.dev_type; |
@@ -454,8 +452,8 @@ ccw_device_sense_pgid_done(struct ccw_device *cdev, int err) | |||
454 | return; | 452 | return; |
455 | } | 453 | } |
456 | /* Start Path Group verification. */ | 454 | /* Start Path Group verification. */ |
457 | sch->vpm = 0; /* Start with no path groups set. */ | ||
458 | cdev->private->state = DEV_STATE_VERIFY; | 455 | cdev->private->state = DEV_STATE_VERIFY; |
456 | cdev->private->flags.doverify = 0; | ||
459 | ccw_device_verify_start(cdev); | 457 | ccw_device_verify_start(cdev); |
460 | } | 458 | } |
461 | 459 | ||
@@ -555,7 +553,19 @@ ccw_device_nopath_notify(void *data) | |||
555 | void | 553 | void |
556 | ccw_device_verify_done(struct ccw_device *cdev, int err) | 554 | ccw_device_verify_done(struct ccw_device *cdev, int err) |
557 | { | 555 | { |
558 | 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 | } | ||
559 | switch (err) { | 569 | switch (err) { |
560 | case -EOPNOTSUPP: /* path grouping not supported, just set online. */ | 570 | case -EOPNOTSUPP: /* path grouping not supported, just set online. */ |
561 | cdev->private->options.pgroup = 0; | 571 | cdev->private->options.pgroup = 0; |
@@ -613,6 +623,7 @@ ccw_device_online(struct ccw_device *cdev) | |||
613 | if (!cdev->private->options.pgroup) { | 623 | if (!cdev->private->options.pgroup) { |
614 | /* Start initial path verification. */ | 624 | /* Start initial path verification. */ |
615 | cdev->private->state = DEV_STATE_VERIFY; | 625 | cdev->private->state = DEV_STATE_VERIFY; |
626 | cdev->private->flags.doverify = 0; | ||
616 | ccw_device_verify_start(cdev); | 627 | ccw_device_verify_start(cdev); |
617 | return 0; | 628 | return 0; |
618 | } | 629 | } |
@@ -659,7 +670,6 @@ ccw_device_offline(struct ccw_device *cdev) | |||
659 | /* Are we doing path grouping? */ | 670 | /* Are we doing path grouping? */ |
660 | if (!cdev->private->options.pgroup) { | 671 | if (!cdev->private->options.pgroup) { |
661 | /* No, set state offline immediately. */ | 672 | /* No, set state offline immediately. */ |
662 | sch->vpm = 0; | ||
663 | ccw_device_done(cdev, DEV_STATE_OFFLINE); | 673 | ccw_device_done(cdev, DEV_STATE_OFFLINE); |
664 | return 0; | 674 | return 0; |
665 | } | 675 | } |
@@ -780,6 +790,7 @@ ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event) | |||
780 | } | 790 | } |
781 | /* Device is idle, we can do the path verification. */ | 791 | /* Device is idle, we can do the path verification. */ |
782 | cdev->private->state = DEV_STATE_VERIFY; | 792 | cdev->private->state = DEV_STATE_VERIFY; |
793 | cdev->private->flags.doverify = 0; | ||
783 | ccw_device_verify_start(cdev); | 794 | ccw_device_verify_start(cdev); |
784 | } | 795 | } |
785 | 796 | ||
@@ -1042,9 +1053,9 @@ ccw_device_wait4io_timeout(struct ccw_device *cdev, enum dev_event dev_event) | |||
1042 | } | 1053 | } |
1043 | 1054 | ||
1044 | static void | 1055 | static void |
1045 | 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) |
1046 | { | 1057 | { |
1047 | /* When the I/O has terminated, we have to start verification. */ | 1058 | /* Start verification after current task finished. */ |
1048 | cdev->private->flags.doverify = 1; | 1059 | cdev->private->flags.doverify = 1; |
1049 | } | 1060 | } |
1050 | 1061 | ||
@@ -1110,10 +1121,7 @@ device_trigger_reprobe(struct subchannel *sch) | |||
1110 | * 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 |
1111 | * we have before performing device selection :/ | 1122 | * we have before performing device selection :/ |
1112 | */ | 1123 | */ |
1113 | sch->lpm = sch->schib.pmcw.pim & | 1124 | sch->lpm = sch->schib.pmcw.pam & sch->opm; |
1114 | sch->schib.pmcw.pam & | ||
1115 | sch->schib.pmcw.pom & | ||
1116 | sch->opm; | ||
1117 | /* Re-set some bits in the pmcw that were lost. */ | 1125 | /* Re-set some bits in the pmcw that were lost. */ |
1118 | sch->schib.pmcw.isc = 3; | 1126 | sch->schib.pmcw.isc = 3; |
1119 | sch->schib.pmcw.csense = 1; | 1127 | sch->schib.pmcw.csense = 1; |
@@ -1237,7 +1245,7 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1237 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, | 1245 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, |
1238 | [DEV_EVENT_INTERRUPT] = ccw_device_verify_irq, | 1246 | [DEV_EVENT_INTERRUPT] = ccw_device_verify_irq, |
1239 | [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, | 1247 | [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, |
1240 | [DEV_EVENT_VERIFY] = ccw_device_nop, | 1248 | [DEV_EVENT_VERIFY] = ccw_device_delay_verify, |
1241 | }, | 1249 | }, |
1242 | [DEV_STATE_ONLINE] = { | 1250 | [DEV_STATE_ONLINE] = { |
1243 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, | 1251 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, |
@@ -1280,7 +1288,7 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1280 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, | 1288 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, |
1281 | [DEV_EVENT_INTERRUPT] = ccw_device_wait4io_irq, | 1289 | [DEV_EVENT_INTERRUPT] = ccw_device_wait4io_irq, |
1282 | [DEV_EVENT_TIMEOUT] = ccw_device_wait4io_timeout, | 1290 | [DEV_EVENT_TIMEOUT] = ccw_device_wait4io_timeout, |
1283 | [DEV_EVENT_VERIFY] = ccw_device_wait4io_verify, | 1291 | [DEV_EVENT_VERIFY] = ccw_device_delay_verify, |
1284 | }, | 1292 | }, |
1285 | [DEV_STATE_QUIESCE] = { | 1293 | [DEV_STATE_QUIESCE] = { |
1286 | [DEV_EVENT_NOTOPER] = ccw_device_quiesce_done, | 1294 | [DEV_EVENT_NOTOPER] = ccw_device_quiesce_done, |
@@ -1293,7 +1301,7 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1293 | [DEV_EVENT_NOTOPER] = ccw_device_nop, | 1301 | [DEV_EVENT_NOTOPER] = ccw_device_nop, |
1294 | [DEV_EVENT_INTERRUPT] = ccw_device_start_id, | 1302 | [DEV_EVENT_INTERRUPT] = ccw_device_start_id, |
1295 | [DEV_EVENT_TIMEOUT] = ccw_device_bug, | 1303 | [DEV_EVENT_TIMEOUT] = ccw_device_bug, |
1296 | [DEV_EVENT_VERIFY] = ccw_device_nop, | 1304 | [DEV_EVENT_VERIFY] = ccw_device_start_id, |
1297 | }, | 1305 | }, |
1298 | [DEV_STATE_DISCONNECTED_SENSE_ID] = { | 1306 | [DEV_STATE_DISCONNECTED_SENSE_ID] = { |
1299 | [DEV_EVENT_NOTOPER] = ccw_device_recog_notoper, | 1307 | [DEV_EVENT_NOTOPER] = ccw_device_recog_notoper, |