diff options
author | Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 2009-12-07 06:51:27 -0500 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2009-12-07 06:51:31 -0500 |
commit | 9679baaf85b6e4dc662160bbbca344287ea6580d (patch) | |
tree | 20cf246830da783a122064b3525d954df4bd4e1c /drivers/s390/cio/device_fsm.c | |
parent | 39f5360b3d68a8e96d280481d9c442e7c005c317 (diff) |
[S390] cio: use ccw request infrastructure for pgid
Use the newly introduced ccw request infrastructure to implement
pgid related operations: sense pgid, set pgid and disband pg.
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 | 100 |
1 files changed, 9 insertions, 91 deletions
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 6247d07d395e..c7439f5500f8 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -394,58 +394,6 @@ ccw_device_done(struct ccw_device *cdev, int state) | |||
394 | wake_up(&cdev->private->wait_q); | 394 | wake_up(&cdev->private->wait_q); |
395 | } | 395 | } |
396 | 396 | ||
397 | static int cmp_pgid(struct pgid *p1, struct pgid *p2) | ||
398 | { | ||
399 | char *c1; | ||
400 | char *c2; | ||
401 | |||
402 | c1 = (char *)p1; | ||
403 | c2 = (char *)p2; | ||
404 | |||
405 | return memcmp(c1 + 1, c2 + 1, sizeof(struct pgid) - 1); | ||
406 | } | ||
407 | |||
408 | static void __ccw_device_get_common_pgid(struct ccw_device *cdev) | ||
409 | { | ||
410 | int i; | ||
411 | int last; | ||
412 | |||
413 | last = 0; | ||
414 | for (i = 0; i < 8; i++) { | ||
415 | if (cdev->private->pgid[i].inf.ps.state1 == SNID_STATE1_RESET) | ||
416 | /* No PGID yet */ | ||
417 | continue; | ||
418 | if (cdev->private->pgid[last].inf.ps.state1 == | ||
419 | SNID_STATE1_RESET) { | ||
420 | /* First non-zero PGID */ | ||
421 | last = i; | ||
422 | continue; | ||
423 | } | ||
424 | if (cmp_pgid(&cdev->private->pgid[i], | ||
425 | &cdev->private->pgid[last]) == 0) | ||
426 | /* Non-conflicting PGIDs */ | ||
427 | continue; | ||
428 | |||
429 | /* PGID mismatch, can't pathgroup. */ | ||
430 | CIO_MSG_EVENT(0, "SNID - pgid mismatch for device " | ||
431 | "0.%x.%04x, can't pathgroup\n", | ||
432 | cdev->private->dev_id.ssid, | ||
433 | cdev->private->dev_id.devno); | ||
434 | cdev->private->options.pgroup = 0; | ||
435 | return; | ||
436 | } | ||
437 | if (cdev->private->pgid[last].inf.ps.state1 == | ||
438 | SNID_STATE1_RESET) | ||
439 | /* No previous pgid found */ | ||
440 | memcpy(&cdev->private->pgid[0], | ||
441 | &channel_subsystems[0]->global_pgid, | ||
442 | sizeof(struct pgid)); | ||
443 | else | ||
444 | /* Use existing pgid */ | ||
445 | memcpy(&cdev->private->pgid[0], &cdev->private->pgid[last], | ||
446 | sizeof(struct pgid)); | ||
447 | } | ||
448 | |||
449 | /* | 397 | /* |
450 | * Function called from device_pgid.c after sense path ground has completed. | 398 | * Function called from device_pgid.c after sense path ground has completed. |
451 | */ | 399 | */ |
@@ -457,12 +405,8 @@ ccw_device_sense_pgid_done(struct ccw_device *cdev, int err) | |||
457 | sch = to_subchannel(cdev->dev.parent); | 405 | sch = to_subchannel(cdev->dev.parent); |
458 | switch (err) { | 406 | switch (err) { |
459 | case -EOPNOTSUPP: /* path grouping not supported, use nop instead. */ | 407 | case -EOPNOTSUPP: /* path grouping not supported, use nop instead. */ |
460 | cdev->private->options.pgroup = 0; | ||
461 | break; | ||
462 | case 0: /* success */ | 408 | case 0: /* success */ |
463 | case -EACCES: /* partial success, some paths not operational */ | 409 | case -EACCES: /* partial success, some paths not operational */ |
464 | /* Check if all pgids are equal or 0. */ | ||
465 | __ccw_device_get_common_pgid(cdev); | ||
466 | break; | 410 | break; |
467 | case -ETIME: /* Sense path group id stopped by timeout. */ | 411 | case -ETIME: /* Sense path group id stopped by timeout. */ |
468 | case -EUSERS: /* device is reserved for someone else. */ | 412 | case -EUSERS: /* device is reserved for someone else. */ |
@@ -474,7 +418,6 @@ ccw_device_sense_pgid_done(struct ccw_device *cdev, int err) | |||
474 | } | 418 | } |
475 | /* Start Path Group verification. */ | 419 | /* Start Path Group verification. */ |
476 | cdev->private->state = DEV_STATE_VERIFY; | 420 | cdev->private->state = DEV_STATE_VERIFY; |
477 | cdev->private->flags.doverify = 0; | ||
478 | ccw_device_verify_start(cdev); | 421 | ccw_device_verify_start(cdev); |
479 | } | 422 | } |
480 | 423 | ||
@@ -537,7 +480,6 @@ ccw_device_verify_done(struct ccw_device *cdev, int err) | |||
537 | sch->lpm = sch->vpm; | 480 | sch->lpm = sch->vpm; |
538 | /* Repeat path verification? */ | 481 | /* Repeat path verification? */ |
539 | if (cdev->private->flags.doverify) { | 482 | if (cdev->private->flags.doverify) { |
540 | cdev->private->flags.doverify = 0; | ||
541 | ccw_device_verify_start(cdev); | 483 | ccw_device_verify_start(cdev); |
542 | return; | 484 | return; |
543 | } | 485 | } |
@@ -602,7 +544,6 @@ ccw_device_online(struct ccw_device *cdev) | |||
602 | if (!cdev->private->options.pgroup) { | 544 | if (!cdev->private->options.pgroup) { |
603 | /* Start initial path verification. */ | 545 | /* Start initial path verification. */ |
604 | cdev->private->state = DEV_STATE_VERIFY; | 546 | cdev->private->state = DEV_STATE_VERIFY; |
605 | cdev->private->flags.doverify = 0; | ||
606 | ccw_device_verify_start(cdev); | 547 | ccw_device_verify_start(cdev); |
607 | return 0; | 548 | return 0; |
608 | } | 549 | } |
@@ -624,7 +565,6 @@ ccw_device_disband_done(struct ccw_device *cdev, int err) | |||
624 | break; | 565 | break; |
625 | default: | 566 | default: |
626 | cdev->private->flags.donotify = 0; | 567 | cdev->private->flags.donotify = 0; |
627 | dev_fsm_event(cdev, DEV_EVENT_NOTOPER); | ||
628 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); | 568 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); |
629 | break; | 569 | break; |
630 | } | 570 | } |
@@ -673,27 +613,6 @@ ccw_device_offline(struct ccw_device *cdev) | |||
673 | } | 613 | } |
674 | 614 | ||
675 | /* | 615 | /* |
676 | * Handle timeout in device online/offline process. | ||
677 | */ | ||
678 | static void | ||
679 | ccw_device_onoff_timeout(struct ccw_device *cdev, enum dev_event dev_event) | ||
680 | { | ||
681 | int ret; | ||
682 | |||
683 | ret = ccw_device_cancel_halt_clear(cdev); | ||
684 | switch (ret) { | ||
685 | case 0: | ||
686 | ccw_device_done(cdev, DEV_STATE_BOXED); | ||
687 | break; | ||
688 | case -ENODEV: | ||
689 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); | ||
690 | break; | ||
691 | default: | ||
692 | ccw_device_set_timeout(cdev, 3*HZ); | ||
693 | } | ||
694 | } | ||
695 | |||
696 | /* | ||
697 | * Handle not operational event in non-special state. | 616 | * Handle not operational event in non-special state. |
698 | */ | 617 | */ |
699 | static void ccw_device_generic_notoper(struct ccw_device *cdev, | 618 | static void ccw_device_generic_notoper(struct ccw_device *cdev, |
@@ -751,7 +670,6 @@ ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event) | |||
751 | } | 670 | } |
752 | /* Device is idle, we can do the path verification. */ | 671 | /* Device is idle, we can do the path verification. */ |
753 | cdev->private->state = DEV_STATE_VERIFY; | 672 | cdev->private->state = DEV_STATE_VERIFY; |
754 | cdev->private->flags.doverify = 0; | ||
755 | ccw_device_verify_start(cdev); | 673 | ccw_device_verify_start(cdev); |
756 | } | 674 | } |
757 | 675 | ||
@@ -1103,9 +1021,9 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1103 | [DEV_EVENT_VERIFY] = ccw_device_nop, | 1021 | [DEV_EVENT_VERIFY] = ccw_device_nop, |
1104 | }, | 1022 | }, |
1105 | [DEV_STATE_SENSE_PGID] = { | 1023 | [DEV_STATE_SENSE_PGID] = { |
1106 | [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, | 1024 | [DEV_EVENT_NOTOPER] = ccw_device_request_event, |
1107 | [DEV_EVENT_INTERRUPT] = ccw_device_sense_pgid_irq, | 1025 | [DEV_EVENT_INTERRUPT] = ccw_device_request_event, |
1108 | [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, | 1026 | [DEV_EVENT_TIMEOUT] = ccw_device_request_event, |
1109 | [DEV_EVENT_VERIFY] = ccw_device_nop, | 1027 | [DEV_EVENT_VERIFY] = ccw_device_nop, |
1110 | }, | 1028 | }, |
1111 | [DEV_STATE_SENSE_ID] = { | 1029 | [DEV_STATE_SENSE_ID] = { |
@@ -1121,9 +1039,9 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1121 | [DEV_EVENT_VERIFY] = ccw_device_offline_verify, | 1039 | [DEV_EVENT_VERIFY] = ccw_device_offline_verify, |
1122 | }, | 1040 | }, |
1123 | [DEV_STATE_VERIFY] = { | 1041 | [DEV_STATE_VERIFY] = { |
1124 | [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, | 1042 | [DEV_EVENT_NOTOPER] = ccw_device_request_event, |
1125 | [DEV_EVENT_INTERRUPT] = ccw_device_verify_irq, | 1043 | [DEV_EVENT_INTERRUPT] = ccw_device_request_event, |
1126 | [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, | 1044 | [DEV_EVENT_TIMEOUT] = ccw_device_request_event, |
1127 | [DEV_EVENT_VERIFY] = ccw_device_delay_verify, | 1045 | [DEV_EVENT_VERIFY] = ccw_device_delay_verify, |
1128 | }, | 1046 | }, |
1129 | [DEV_STATE_ONLINE] = { | 1047 | [DEV_STATE_ONLINE] = { |
@@ -1139,9 +1057,9 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1139 | [DEV_EVENT_VERIFY] = ccw_device_online_verify, | 1057 | [DEV_EVENT_VERIFY] = ccw_device_online_verify, |
1140 | }, | 1058 | }, |
1141 | [DEV_STATE_DISBAND_PGID] = { | 1059 | [DEV_STATE_DISBAND_PGID] = { |
1142 | [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, | 1060 | [DEV_EVENT_NOTOPER] = ccw_device_request_event, |
1143 | [DEV_EVENT_INTERRUPT] = ccw_device_disband_irq, | 1061 | [DEV_EVENT_INTERRUPT] = ccw_device_request_event, |
1144 | [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, | 1062 | [DEV_EVENT_TIMEOUT] = ccw_device_request_event, |
1145 | [DEV_EVENT_VERIFY] = ccw_device_nop, | 1063 | [DEV_EVENT_VERIFY] = ccw_device_nop, |
1146 | }, | 1064 | }, |
1147 | [DEV_STATE_BOXED] = { | 1065 | [DEV_STATE_BOXED] = { |