diff options
Diffstat (limited to 'drivers/s390/cio/device_pgid.c')
-rw-r--r-- | drivers/s390/cio/device_pgid.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index ce493144b054..3323042ba755 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c | |||
@@ -30,8 +30,8 @@ static void verify_done(struct ccw_device *cdev, int rc) | |||
30 | { | 30 | { |
31 | struct subchannel *sch = to_subchannel(cdev->dev.parent); | 31 | struct subchannel *sch = to_subchannel(cdev->dev.parent); |
32 | struct ccw_dev_id *id = &cdev->private->dev_id; | 32 | struct ccw_dev_id *id = &cdev->private->dev_id; |
33 | int mpath = !cdev->private->flags.pgid_single; | 33 | int mpath = cdev->private->flags.mpath; |
34 | int pgroup = cdev->private->options.pgroup; | 34 | int pgroup = cdev->private->flags.pgroup; |
35 | 35 | ||
36 | if (rc) | 36 | if (rc) |
37 | goto out; | 37 | goto out; |
@@ -150,7 +150,7 @@ static void spid_do(struct ccw_device *cdev) | |||
150 | fn = SPID_FUNC_ESTABLISH; | 150 | fn = SPID_FUNC_ESTABLISH; |
151 | else | 151 | else |
152 | fn = SPID_FUNC_RESIGN; | 152 | fn = SPID_FUNC_RESIGN; |
153 | if (!cdev->private->flags.pgid_single) | 153 | if (cdev->private->flags.mpath) |
154 | fn |= SPID_FUNC_MULTI_PATH; | 154 | fn |= SPID_FUNC_MULTI_PATH; |
155 | spid_build_cp(cdev, fn); | 155 | spid_build_cp(cdev, fn); |
156 | ccw_request_start(cdev); | 156 | ccw_request_start(cdev); |
@@ -177,13 +177,13 @@ static void spid_callback(struct ccw_device *cdev, void *data, int rc) | |||
177 | case -EACCES: | 177 | case -EACCES: |
178 | break; | 178 | break; |
179 | case -EOPNOTSUPP: | 179 | case -EOPNOTSUPP: |
180 | if (!cdev->private->flags.pgid_single) { | 180 | if (cdev->private->flags.mpath) { |
181 | /* Try without multipathing. */ | 181 | /* Try without multipathing. */ |
182 | cdev->private->flags.pgid_single = 1; | 182 | cdev->private->flags.mpath = 0; |
183 | goto out_restart; | 183 | goto out_restart; |
184 | } | 184 | } |
185 | /* Try without pathgrouping. */ | 185 | /* Try without pathgrouping. */ |
186 | cdev->private->options.pgroup = 0; | 186 | cdev->private->flags.pgroup = 0; |
187 | goto out_restart; | 187 | goto out_restart; |
188 | default: | 188 | default: |
189 | goto err; | 189 | goto err; |
@@ -374,7 +374,7 @@ static void verify_start(struct ccw_device *cdev) | |||
374 | req->timeout = PGID_TIMEOUT; | 374 | req->timeout = PGID_TIMEOUT; |
375 | req->maxretries = PGID_RETRIES; | 375 | req->maxretries = PGID_RETRIES; |
376 | req->lpm = 0x80; | 376 | req->lpm = 0x80; |
377 | if (cdev->private->options.pgroup) { | 377 | if (cdev->private->flags.pgroup) { |
378 | req->callback = spid_callback; | 378 | req->callback = spid_callback; |
379 | spid_do(cdev); | 379 | spid_do(cdev); |
380 | } else { | 380 | } else { |
@@ -400,10 +400,17 @@ void ccw_device_verify_start(struct ccw_device *cdev) | |||
400 | CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id)); | 400 | CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id)); |
401 | if (!cdev->private->flags.pgid_rdy) { | 401 | if (!cdev->private->flags.pgid_rdy) { |
402 | /* No pathgrouping possible. */ | 402 | /* No pathgrouping possible. */ |
403 | cdev->private->options.pgroup = 0; | 403 | cdev->private->flags.pgroup = 0; |
404 | cdev->private->flags.pgid_single = 1; | 404 | cdev->private->flags.mpath = 0; |
405 | } else | 405 | } else { |
406 | cdev->private->flags.pgid_single = 0; | 406 | /* |
407 | * Initialize pathgroup and multipath state with target values. | ||
408 | * They may change in the course of path verification. | ||
409 | */ | ||
410 | cdev->private->flags.pgroup = cdev->private->options.pgroup; | ||
411 | cdev->private->flags.mpath = cdev->private->options.mpath; | ||
412 | |||
413 | } | ||
407 | cdev->private->flags.doverify = 0; | 414 | cdev->private->flags.doverify = 0; |
408 | verify_start(cdev); | 415 | verify_start(cdev); |
409 | } | 416 | } |
@@ -419,7 +426,7 @@ static void disband_callback(struct ccw_device *cdev, void *data, int rc) | |||
419 | if (rc) | 426 | if (rc) |
420 | goto out; | 427 | goto out; |
421 | /* Ensure consistent multipathing state at device and channel. */ | 428 | /* Ensure consistent multipathing state at device and channel. */ |
422 | cdev->private->flags.pgid_single = 1; | 429 | cdev->private->flags.mpath = 0; |
423 | if (sch->config.mp) { | 430 | if (sch->config.mp) { |
424 | sch->config.mp = 0; | 431 | sch->config.mp = 0; |
425 | rc = cio_commit_config(sch); | 432 | rc = cio_commit_config(sch); |
@@ -453,7 +460,7 @@ void ccw_device_disband_start(struct ccw_device *cdev) | |||
453 | req->lpm = sch->schib.pmcw.pam & sch->opm; | 460 | req->lpm = sch->schib.pmcw.pam & sch->opm; |
454 | req->callback = disband_callback; | 461 | req->callback = disband_callback; |
455 | fn = SPID_FUNC_DISBAND; | 462 | fn = SPID_FUNC_DISBAND; |
456 | if (!cdev->private->flags.pgid_single) | 463 | if (cdev->private->flags.mpath) |
457 | fn |= SPID_FUNC_MULTI_PATH; | 464 | fn |= SPID_FUNC_MULTI_PATH; |
458 | spid_build_cp(cdev, fn); | 465 | spid_build_cp(cdev, fn); |
459 | ccw_request_start(cdev); | 466 | ccw_request_start(cdev); |