aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device_fsm.c
diff options
context:
space:
mode:
authorPeter Oberparleiter <peter.oberparleiter@de.ibm.com>2009-12-07 06:51:27 -0500
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2009-12-07 06:51:31 -0500
commit9679baaf85b6e4dc662160bbbca344287ea6580d (patch)
tree20cf246830da783a122064b3525d954df4bd4e1c /drivers/s390/cio/device_fsm.c
parent39f5360b3d68a8e96d280481d9c442e7c005c317 (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.c100
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
397static 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
408static 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 */
678static void
679ccw_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 */
699static void ccw_device_generic_notoper(struct ccw_device *cdev, 618static 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] = {