diff options
Diffstat (limited to 'drivers/s390/cio/device_fsm.c')
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 46 |
1 files changed, 25 insertions, 21 deletions
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 10bc03940fb3..8df5eaafc5ab 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -140,8 +140,7 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev) | |||
140 | int ret; | 140 | int ret; |
141 | 141 | ||
142 | sch = to_subchannel(cdev->dev.parent); | 142 | sch = to_subchannel(cdev->dev.parent); |
143 | ret = stsch(sch->schid, &sch->schib); | 143 | if (cio_update_schib(sch)) |
144 | if (ret || !sch->schib.pmcw.dnv) | ||
145 | return -ENODEV; | 144 | return -ENODEV; |
146 | if (!sch->schib.pmcw.ena) | 145 | if (!sch->schib.pmcw.ena) |
147 | /* Not operational -> done. */ | 146 | /* Not operational -> done. */ |
@@ -245,11 +244,13 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
245 | * through ssch() and the path information is up to date. | 244 | * through ssch() and the path information is up to date. |
246 | */ | 245 | */ |
247 | old_lpm = sch->lpm; | 246 | old_lpm = sch->lpm; |
248 | stsch(sch->schid, &sch->schib); | 247 | |
249 | sch->lpm = sch->schib.pmcw.pam & sch->opm; | ||
250 | /* Check since device may again have become not operational. */ | 248 | /* Check since device may again have become not operational. */ |
251 | if (!sch->schib.pmcw.dnv) | 249 | if (cio_update_schib(sch)) |
252 | state = DEV_STATE_NOT_OPER; | 250 | state = DEV_STATE_NOT_OPER; |
251 | else | ||
252 | sch->lpm = sch->schib.pmcw.pam & sch->opm; | ||
253 | |||
253 | if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) | 254 | if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) |
254 | /* Force reprobe on all chpids. */ | 255 | /* Force reprobe on all chpids. */ |
255 | old_lpm = 0; | 256 | old_lpm = 0; |
@@ -399,9 +400,6 @@ ccw_device_done(struct ccw_device *cdev, int state) | |||
399 | ccw_device_oper_notify(cdev); | 400 | ccw_device_oper_notify(cdev); |
400 | } | 401 | } |
401 | wake_up(&cdev->private->wait_q); | 402 | wake_up(&cdev->private->wait_q); |
402 | |||
403 | if (css_init_done && state != DEV_STATE_ONLINE) | ||
404 | put_device (&cdev->dev); | ||
405 | } | 403 | } |
406 | 404 | ||
407 | static int cmp_pgid(struct pgid *p1, struct pgid *p2) | 405 | static int cmp_pgid(struct pgid *p1, struct pgid *p2) |
@@ -552,7 +550,11 @@ ccw_device_verify_done(struct ccw_device *cdev, int err) | |||
552 | 550 | ||
553 | sch = to_subchannel(cdev->dev.parent); | 551 | sch = to_subchannel(cdev->dev.parent); |
554 | /* Update schib - pom may have changed. */ | 552 | /* Update schib - pom may have changed. */ |
555 | stsch(sch->schid, &sch->schib); | 553 | if (cio_update_schib(sch)) { |
554 | cdev->private->flags.donotify = 0; | ||
555 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); | ||
556 | return; | ||
557 | } | ||
556 | /* Update lpm with verified path mask. */ | 558 | /* Update lpm with verified path mask. */ |
557 | sch->lpm = sch->vpm; | 559 | sch->lpm = sch->vpm; |
558 | /* Repeat path verification? */ | 560 | /* Repeat path verification? */ |
@@ -611,8 +613,6 @@ ccw_device_online(struct ccw_device *cdev) | |||
611 | (cdev->private->state != DEV_STATE_BOXED)) | 613 | (cdev->private->state != DEV_STATE_BOXED)) |
612 | return -EINVAL; | 614 | return -EINVAL; |
613 | sch = to_subchannel(cdev->dev.parent); | 615 | sch = to_subchannel(cdev->dev.parent); |
614 | if (css_init_done && !get_device(&cdev->dev)) | ||
615 | return -ENODEV; | ||
616 | ret = cio_enable_subchannel(sch, (u32)(addr_t)sch); | 616 | ret = cio_enable_subchannel(sch, (u32)(addr_t)sch); |
617 | if (ret != 0) { | 617 | if (ret != 0) { |
618 | /* Couldn't enable the subchannel for i/o. Sick device. */ | 618 | /* Couldn't enable the subchannel for i/o. Sick device. */ |
@@ -672,7 +672,7 @@ ccw_device_offline(struct ccw_device *cdev) | |||
672 | return 0; | 672 | return 0; |
673 | } | 673 | } |
674 | sch = to_subchannel(cdev->dev.parent); | 674 | sch = to_subchannel(cdev->dev.parent); |
675 | if (stsch(sch->schid, &sch->schib) || !sch->schib.pmcw.dnv) | 675 | if (cio_update_schib(sch)) |
676 | return -ENODEV; | 676 | return -ENODEV; |
677 | if (scsw_actl(&sch->schib.scsw) != 0) | 677 | if (scsw_actl(&sch->schib.scsw) != 0) |
678 | return -EBUSY; | 678 | return -EBUSY; |
@@ -750,7 +750,10 @@ ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event) | |||
750 | * Since we might not just be coming from an interrupt from the | 750 | * Since we might not just be coming from an interrupt from the |
751 | * subchannel we have to update the schib. | 751 | * subchannel we have to update the schib. |
752 | */ | 752 | */ |
753 | stsch(sch->schid, &sch->schib); | 753 | if (cio_update_schib(sch)) { |
754 | ccw_device_verify_done(cdev, -ENODEV); | ||
755 | return; | ||
756 | } | ||
754 | 757 | ||
755 | if (scsw_actl(&sch->schib.scsw) != 0 || | 758 | if (scsw_actl(&sch->schib.scsw) != 0 || |
756 | (scsw_stctl(&sch->schib.scsw) & SCSW_STCTL_STATUS_PEND) || | 759 | (scsw_stctl(&sch->schib.scsw) & SCSW_STCTL_STATUS_PEND) || |
@@ -1016,20 +1019,21 @@ void ccw_device_trigger_reprobe(struct ccw_device *cdev) | |||
1016 | 1019 | ||
1017 | sch = to_subchannel(cdev->dev.parent); | 1020 | sch = to_subchannel(cdev->dev.parent); |
1018 | /* Update some values. */ | 1021 | /* Update some values. */ |
1019 | if (stsch(sch->schid, &sch->schib)) | 1022 | if (cio_update_schib(sch)) |
1020 | return; | ||
1021 | if (!sch->schib.pmcw.dnv) | ||
1022 | return; | 1023 | return; |
1023 | /* | 1024 | /* |
1024 | * The pim, pam, pom values may not be accurate, but they are the best | 1025 | * The pim, pam, pom values may not be accurate, but they are the best |
1025 | * we have before performing device selection :/ | 1026 | * we have before performing device selection :/ |
1026 | */ | 1027 | */ |
1027 | sch->lpm = sch->schib.pmcw.pam & sch->opm; | 1028 | sch->lpm = sch->schib.pmcw.pam & sch->opm; |
1028 | /* Re-set some bits in the pmcw that were lost. */ | 1029 | /* |
1029 | sch->schib.pmcw.csense = 1; | 1030 | * Use the initial configuration since we can't be shure that the old |
1030 | sch->schib.pmcw.ena = 0; | 1031 | * paths are valid. |
1031 | if ((sch->lpm & (sch->lpm - 1)) != 0) | 1032 | */ |
1032 | sch->schib.pmcw.mp = 1; | 1033 | io_subchannel_init_config(sch); |
1034 | if (cio_commit_config(sch)) | ||
1035 | return; | ||
1036 | |||
1033 | /* We should also udate ssd info, but this has to wait. */ | 1037 | /* We should also udate ssd info, but this has to wait. */ |
1034 | /* Check if this is another device which appeared on the same sch. */ | 1038 | /* Check if this is another device which appeared on the same sch. */ |
1035 | if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) { | 1039 | if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) { |