diff options
Diffstat (limited to 'drivers/scsi/isci/phy.c')
-rw-r--r-- | drivers/scsi/isci/phy.c | 171 |
1 files changed, 103 insertions, 68 deletions
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c index fe18acfd6eb3..fab3586840b5 100644 --- a/drivers/scsi/isci/phy.c +++ b/drivers/scsi/isci/phy.c | |||
@@ -59,6 +59,16 @@ | |||
59 | #include "scu_event_codes.h" | 59 | #include "scu_event_codes.h" |
60 | #include "probe_roms.h" | 60 | #include "probe_roms.h" |
61 | 61 | ||
62 | #undef C | ||
63 | #define C(a) (#a) | ||
64 | static const char *phy_state_name(enum sci_phy_states state) | ||
65 | { | ||
66 | static const char * const strings[] = PHY_STATES; | ||
67 | |||
68 | return strings[state]; | ||
69 | } | ||
70 | #undef C | ||
71 | |||
62 | /* Maximum arbitration wait time in micro-seconds */ | 72 | /* Maximum arbitration wait time in micro-seconds */ |
63 | #define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME (700) | 73 | #define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME (700) |
64 | 74 | ||
@@ -67,6 +77,19 @@ enum sas_linkrate sci_phy_linkrate(struct isci_phy *iphy) | |||
67 | return iphy->max_negotiated_speed; | 77 | return iphy->max_negotiated_speed; |
68 | } | 78 | } |
69 | 79 | ||
80 | static struct isci_host *phy_to_host(struct isci_phy *iphy) | ||
81 | { | ||
82 | struct isci_phy *table = iphy - iphy->phy_index; | ||
83 | struct isci_host *ihost = container_of(table, typeof(*ihost), phys[0]); | ||
84 | |||
85 | return ihost; | ||
86 | } | ||
87 | |||
88 | static struct device *sciphy_to_dev(struct isci_phy *iphy) | ||
89 | { | ||
90 | return &phy_to_host(iphy)->pdev->dev; | ||
91 | } | ||
92 | |||
70 | static enum sci_status | 93 | static enum sci_status |
71 | sci_phy_transport_layer_initialization(struct isci_phy *iphy, | 94 | sci_phy_transport_layer_initialization(struct isci_phy *iphy, |
72 | struct scu_transport_layer_registers __iomem *reg) | 95 | struct scu_transport_layer_registers __iomem *reg) |
@@ -446,8 +469,8 @@ enum sci_status sci_phy_start(struct isci_phy *iphy) | |||
446 | enum sci_phy_states state = iphy->sm.current_state_id; | 469 | enum sci_phy_states state = iphy->sm.current_state_id; |
447 | 470 | ||
448 | if (state != SCI_PHY_STOPPED) { | 471 | if (state != SCI_PHY_STOPPED) { |
449 | dev_dbg(sciphy_to_dev(iphy), | 472 | dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n", |
450 | "%s: in wrong state: %d\n", __func__, state); | 473 | __func__, phy_state_name(state)); |
451 | return SCI_FAILURE_INVALID_STATE; | 474 | return SCI_FAILURE_INVALID_STATE; |
452 | } | 475 | } |
453 | 476 | ||
@@ -472,8 +495,8 @@ enum sci_status sci_phy_stop(struct isci_phy *iphy) | |||
472 | case SCI_PHY_READY: | 495 | case SCI_PHY_READY: |
473 | break; | 496 | break; |
474 | default: | 497 | default: |
475 | dev_dbg(sciphy_to_dev(iphy), | 498 | dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n", |
476 | "%s: in wrong state: %d\n", __func__, state); | 499 | __func__, phy_state_name(state)); |
477 | return SCI_FAILURE_INVALID_STATE; | 500 | return SCI_FAILURE_INVALID_STATE; |
478 | } | 501 | } |
479 | 502 | ||
@@ -486,8 +509,8 @@ enum sci_status sci_phy_reset(struct isci_phy *iphy) | |||
486 | enum sci_phy_states state = iphy->sm.current_state_id; | 509 | enum sci_phy_states state = iphy->sm.current_state_id; |
487 | 510 | ||
488 | if (state != SCI_PHY_READY) { | 511 | if (state != SCI_PHY_READY) { |
489 | dev_dbg(sciphy_to_dev(iphy), | 512 | dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n", |
490 | "%s: in wrong state: %d\n", __func__, state); | 513 | __func__, phy_state_name(state)); |
491 | return SCI_FAILURE_INVALID_STATE; | 514 | return SCI_FAILURE_INVALID_STATE; |
492 | } | 515 | } |
493 | 516 | ||
@@ -536,8 +559,8 @@ enum sci_status sci_phy_consume_power_handler(struct isci_phy *iphy) | |||
536 | return SCI_SUCCESS; | 559 | return SCI_SUCCESS; |
537 | } | 560 | } |
538 | default: | 561 | default: |
539 | dev_dbg(sciphy_to_dev(iphy), | 562 | dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n", |
540 | "%s: in wrong state: %d\n", __func__, state); | 563 | __func__, phy_state_name(state)); |
541 | return SCI_FAILURE_INVALID_STATE; | 564 | return SCI_FAILURE_INVALID_STATE; |
542 | } | 565 | } |
543 | } | 566 | } |
@@ -591,6 +614,60 @@ static void sci_phy_complete_link_training(struct isci_phy *iphy, | |||
591 | sci_change_state(&iphy->sm, next_state); | 614 | sci_change_state(&iphy->sm, next_state); |
592 | } | 615 | } |
593 | 616 | ||
617 | static const char *phy_event_name(u32 event_code) | ||
618 | { | ||
619 | switch (scu_get_event_code(event_code)) { | ||
620 | case SCU_EVENT_PORT_SELECTOR_DETECTED: | ||
621 | return "port selector"; | ||
622 | case SCU_EVENT_SENT_PORT_SELECTION: | ||
623 | return "port selection"; | ||
624 | case SCU_EVENT_HARD_RESET_TRANSMITTED: | ||
625 | return "tx hard reset"; | ||
626 | case SCU_EVENT_HARD_RESET_RECEIVED: | ||
627 | return "rx hard reset"; | ||
628 | case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT: | ||
629 | return "identify timeout"; | ||
630 | case SCU_EVENT_LINK_FAILURE: | ||
631 | return "link fail"; | ||
632 | case SCU_EVENT_SATA_SPINUP_HOLD: | ||
633 | return "sata spinup hold"; | ||
634 | case SCU_EVENT_SAS_15_SSC: | ||
635 | case SCU_EVENT_SAS_15: | ||
636 | return "sas 1.5"; | ||
637 | case SCU_EVENT_SAS_30_SSC: | ||
638 | case SCU_EVENT_SAS_30: | ||
639 | return "sas 3.0"; | ||
640 | case SCU_EVENT_SAS_60_SSC: | ||
641 | case SCU_EVENT_SAS_60: | ||
642 | return "sas 6.0"; | ||
643 | case SCU_EVENT_SATA_15_SSC: | ||
644 | case SCU_EVENT_SATA_15: | ||
645 | return "sata 1.5"; | ||
646 | case SCU_EVENT_SATA_30_SSC: | ||
647 | case SCU_EVENT_SATA_30: | ||
648 | return "sata 3.0"; | ||
649 | case SCU_EVENT_SATA_60_SSC: | ||
650 | case SCU_EVENT_SATA_60: | ||
651 | return "sata 6.0"; | ||
652 | case SCU_EVENT_SAS_PHY_DETECTED: | ||
653 | return "sas detect"; | ||
654 | case SCU_EVENT_SATA_PHY_DETECTED: | ||
655 | return "sata detect"; | ||
656 | default: | ||
657 | return "unknown"; | ||
658 | } | ||
659 | } | ||
660 | |||
661 | #define phy_event_dbg(iphy, state, code) \ | ||
662 | dev_dbg(sciphy_to_dev(iphy), "phy-%d:%d: %s event: %s (%x)\n", \ | ||
663 | phy_to_host(iphy)->id, iphy->phy_index, \ | ||
664 | phy_state_name(state), phy_event_name(code), code) | ||
665 | |||
666 | #define phy_event_warn(iphy, state, code) \ | ||
667 | dev_warn(sciphy_to_dev(iphy), "phy-%d:%d: %s event: %s (%x)\n", \ | ||
668 | phy_to_host(iphy)->id, iphy->phy_index, \ | ||
669 | phy_state_name(state), phy_event_name(code), code) | ||
670 | |||
594 | enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) | 671 | enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) |
595 | { | 672 | { |
596 | enum sci_phy_states state = iphy->sm.current_state_id; | 673 | enum sci_phy_states state = iphy->sm.current_state_id; |
@@ -607,11 +684,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) | |||
607 | iphy->is_in_link_training = true; | 684 | iphy->is_in_link_training = true; |
608 | break; | 685 | break; |
609 | default: | 686 | default: |
610 | dev_dbg(sciphy_to_dev(iphy), | 687 | phy_event_dbg(iphy, state, event_code); |
611 | "%s: PHY starting substate machine received " | ||
612 | "unexpected event_code %x\n", | ||
613 | __func__, | ||
614 | event_code); | ||
615 | return SCI_FAILURE; | 688 | return SCI_FAILURE; |
616 | } | 689 | } |
617 | return SCI_SUCCESS; | 690 | return SCI_SUCCESS; |
@@ -648,11 +721,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) | |||
648 | sci_change_state(&iphy->sm, SCI_PHY_STARTING); | 721 | sci_change_state(&iphy->sm, SCI_PHY_STARTING); |
649 | break; | 722 | break; |
650 | default: | 723 | default: |
651 | dev_warn(sciphy_to_dev(iphy), | 724 | phy_event_warn(iphy, state, event_code); |
652 | "%s: PHY starting substate machine received " | ||
653 | "unexpected event_code %x\n", | ||
654 | __func__, event_code); | ||
655 | |||
656 | return SCI_FAILURE; | 725 | return SCI_FAILURE; |
657 | break; | 726 | break; |
658 | } | 727 | } |
@@ -677,10 +746,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) | |||
677 | sci_change_state(&iphy->sm, SCI_PHY_STARTING); | 746 | sci_change_state(&iphy->sm, SCI_PHY_STARTING); |
678 | break; | 747 | break; |
679 | default: | 748 | default: |
680 | dev_warn(sciphy_to_dev(iphy), | 749 | phy_event_warn(iphy, state, event_code); |
681 | "%s: PHY starting substate machine received " | ||
682 | "unexpected event_code %x\n", | ||
683 | __func__, event_code); | ||
684 | return SCI_FAILURE; | 750 | return SCI_FAILURE; |
685 | } | 751 | } |
686 | return SCI_SUCCESS; | 752 | return SCI_SUCCESS; |
@@ -691,11 +757,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) | |||
691 | sci_change_state(&iphy->sm, SCI_PHY_STARTING); | 757 | sci_change_state(&iphy->sm, SCI_PHY_STARTING); |
692 | break; | 758 | break; |
693 | default: | 759 | default: |
694 | dev_warn(sciphy_to_dev(iphy), | 760 | phy_event_warn(iphy, state, event_code); |
695 | "%s: PHY starting substate machine received unexpected " | ||
696 | "event_code %x\n", | ||
697 | __func__, | ||
698 | event_code); | ||
699 | return SCI_FAILURE; | 761 | return SCI_FAILURE; |
700 | } | 762 | } |
701 | return SCI_SUCCESS; | 763 | return SCI_SUCCESS; |
@@ -719,11 +781,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) | |||
719 | break; | 781 | break; |
720 | 782 | ||
721 | default: | 783 | default: |
722 | dev_warn(sciphy_to_dev(iphy), | 784 | phy_event_warn(iphy, state, event_code); |
723 | "%s: PHY starting substate machine received " | ||
724 | "unexpected event_code %x\n", | ||
725 | __func__, event_code); | ||
726 | |||
727 | return SCI_FAILURE; | 785 | return SCI_FAILURE; |
728 | } | 786 | } |
729 | return SCI_SUCCESS; | 787 | return SCI_SUCCESS; |
@@ -751,12 +809,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) | |||
751 | sci_phy_start_sas_link_training(iphy); | 809 | sci_phy_start_sas_link_training(iphy); |
752 | break; | 810 | break; |
753 | default: | 811 | default: |
754 | dev_warn(sciphy_to_dev(iphy), | 812 | phy_event_warn(iphy, state, event_code); |
755 | "%s: PHY starting substate machine received " | ||
756 | "unexpected event_code %x\n", | ||
757 | __func__, | ||
758 | event_code); | ||
759 | |||
760 | return SCI_FAILURE; | 813 | return SCI_FAILURE; |
761 | } | 814 | } |
762 | return SCI_SUCCESS; | 815 | return SCI_SUCCESS; |
@@ -793,11 +846,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) | |||
793 | sci_phy_start_sas_link_training(iphy); | 846 | sci_phy_start_sas_link_training(iphy); |
794 | break; | 847 | break; |
795 | default: | 848 | default: |
796 | dev_warn(sciphy_to_dev(iphy), | 849 | phy_event_warn(iphy, state, event_code); |
797 | "%s: PHY starting substate machine received " | ||
798 | "unexpected event_code %x\n", | ||
799 | __func__, event_code); | ||
800 | |||
801 | return SCI_FAILURE; | 850 | return SCI_FAILURE; |
802 | } | 851 | } |
803 | 852 | ||
@@ -815,12 +864,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) | |||
815 | break; | 864 | break; |
816 | 865 | ||
817 | default: | 866 | default: |
818 | dev_warn(sciphy_to_dev(iphy), | 867 | phy_event_warn(iphy, state, event_code); |
819 | "%s: PHY starting substate machine received " | ||
820 | "unexpected event_code %x\n", | ||
821 | __func__, | ||
822 | event_code); | ||
823 | |||
824 | return SCI_FAILURE; | 868 | return SCI_FAILURE; |
825 | } | 869 | } |
826 | return SCI_SUCCESS; | 870 | return SCI_SUCCESS; |
@@ -838,10 +882,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) | |||
838 | iphy->bcn_received_while_port_unassigned = true; | 882 | iphy->bcn_received_while_port_unassigned = true; |
839 | break; | 883 | break; |
840 | default: | 884 | default: |
841 | dev_warn(sciphy_to_dev(iphy), | 885 | phy_event_warn(iphy, state, event_code); |
842 | "%sP SCIC PHY 0x%p ready state machine received " | ||
843 | "unexpected event_code %x\n", | ||
844 | __func__, iphy, event_code); | ||
845 | return SCI_FAILURE_INVALID_STATE; | 886 | return SCI_FAILURE_INVALID_STATE; |
846 | } | 887 | } |
847 | return SCI_SUCCESS; | 888 | return SCI_SUCCESS; |
@@ -852,18 +893,14 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) | |||
852 | sci_change_state(&iphy->sm, SCI_PHY_STARTING); | 893 | sci_change_state(&iphy->sm, SCI_PHY_STARTING); |
853 | break; | 894 | break; |
854 | default: | 895 | default: |
855 | dev_warn(sciphy_to_dev(iphy), | 896 | phy_event_warn(iphy, state, event_code); |
856 | "%s: SCIC PHY 0x%p resetting state machine received " | ||
857 | "unexpected event_code %x\n", | ||
858 | __func__, iphy, event_code); | ||
859 | |||
860 | return SCI_FAILURE_INVALID_STATE; | 897 | return SCI_FAILURE_INVALID_STATE; |
861 | break; | 898 | break; |
862 | } | 899 | } |
863 | return SCI_SUCCESS; | 900 | return SCI_SUCCESS; |
864 | default: | 901 | default: |
865 | dev_dbg(sciphy_to_dev(iphy), | 902 | dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n", |
866 | "%s: in wrong state: %d\n", __func__, state); | 903 | __func__, phy_state_name(state)); |
867 | return SCI_FAILURE_INVALID_STATE; | 904 | return SCI_FAILURE_INVALID_STATE; |
868 | } | 905 | } |
869 | } | 906 | } |
@@ -956,8 +993,8 @@ enum sci_status sci_phy_frame_handler(struct isci_phy *iphy, u32 frame_index) | |||
956 | return result; | 993 | return result; |
957 | } | 994 | } |
958 | default: | 995 | default: |
959 | dev_dbg(sciphy_to_dev(iphy), | 996 | dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n", |
960 | "%s: in wrong state: %d\n", __func__, state); | 997 | __func__, phy_state_name(state)); |
961 | return SCI_FAILURE_INVALID_STATE; | 998 | return SCI_FAILURE_INVALID_STATE; |
962 | } | 999 | } |
963 | 1000 | ||
@@ -1299,7 +1336,6 @@ void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index) | |||
1299 | sas_addr = cpu_to_be64(sci_sas_addr); | 1336 | sas_addr = cpu_to_be64(sci_sas_addr); |
1300 | memcpy(iphy->sas_addr, &sas_addr, sizeof(sas_addr)); | 1337 | memcpy(iphy->sas_addr, &sas_addr, sizeof(sas_addr)); |
1301 | 1338 | ||
1302 | iphy->isci_port = NULL; | ||
1303 | iphy->sas_phy.enabled = 0; | 1339 | iphy->sas_phy.enabled = 0; |
1304 | iphy->sas_phy.id = index; | 1340 | iphy->sas_phy.id = index; |
1305 | iphy->sas_phy.sas_addr = &iphy->sas_addr[0]; | 1341 | iphy->sas_phy.sas_addr = &iphy->sas_addr[0]; |
@@ -1333,13 +1369,13 @@ int isci_phy_control(struct asd_sas_phy *sas_phy, | |||
1333 | { | 1369 | { |
1334 | int ret = 0; | 1370 | int ret = 0; |
1335 | struct isci_phy *iphy = sas_phy->lldd_phy; | 1371 | struct isci_phy *iphy = sas_phy->lldd_phy; |
1336 | struct isci_port *iport = iphy->isci_port; | 1372 | struct asd_sas_port *port = sas_phy->port; |
1337 | struct isci_host *ihost = sas_phy->ha->lldd_ha; | 1373 | struct isci_host *ihost = sas_phy->ha->lldd_ha; |
1338 | unsigned long flags; | 1374 | unsigned long flags; |
1339 | 1375 | ||
1340 | dev_dbg(&ihost->pdev->dev, | 1376 | dev_dbg(&ihost->pdev->dev, |
1341 | "%s: phy %p; func %d; buf %p; isci phy %p, port %p\n", | 1377 | "%s: phy %p; func %d; buf %p; isci phy %p, port %p\n", |
1342 | __func__, sas_phy, func, buf, iphy, iport); | 1378 | __func__, sas_phy, func, buf, iphy, port); |
1343 | 1379 | ||
1344 | switch (func) { | 1380 | switch (func) { |
1345 | case PHY_FUNC_DISABLE: | 1381 | case PHY_FUNC_DISABLE: |
@@ -1356,11 +1392,10 @@ int isci_phy_control(struct asd_sas_phy *sas_phy, | |||
1356 | break; | 1392 | break; |
1357 | 1393 | ||
1358 | case PHY_FUNC_HARD_RESET: | 1394 | case PHY_FUNC_HARD_RESET: |
1359 | if (!iport) | 1395 | if (!port) |
1360 | return -ENODEV; | 1396 | return -ENODEV; |
1361 | 1397 | ||
1362 | /* Perform the port reset. */ | 1398 | ret = isci_port_perform_hard_reset(ihost, port->lldd_port, iphy); |
1363 | ret = isci_port_perform_hard_reset(ihost, iport, iphy); | ||
1364 | 1399 | ||
1365 | break; | 1400 | break; |
1366 | case PHY_FUNC_GET_EVENTS: { | 1401 | case PHY_FUNC_GET_EVENTS: { |