diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-05-12 07:27:29 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:04:48 -0400 |
commit | 23506a69e2ee761824c266f6e2cd541a7287c2a5 (patch) | |
tree | 91d6769163a741a238c66848241690fab34873d0 | |
parent | c4441abc25a33ab259f01dce4b4d63721013f86d (diff) |
isci: unify phy event handlers
Unify the implementations in scic_sds_phy_event_handler(), and kill the state handler
Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r-- | drivers/scsi/isci/phy.c | 1021 | ||||
-rw-r--r-- | drivers/scsi/isci/phy.h | 5 |
2 files changed, 384 insertions, 642 deletions
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c index 433ea605f70b..0ffb5d5a860e 100644 --- a/drivers/scsi/isci/phy.c +++ b/drivers/scsi/isci/phy.c | |||
@@ -506,116 +506,6 @@ enum sci_status scic_sds_phy_reset(struct scic_sds_phy *sci_phy) | |||
506 | } | 506 | } |
507 | 507 | ||
508 | /** | 508 | /** |
509 | * This method will process the event code received. | ||
510 | * @sci_phy: | ||
511 | * @event_code: | ||
512 | * | ||
513 | * enum sci_status | ||
514 | */ | ||
515 | enum sci_status scic_sds_phy_event_handler( | ||
516 | struct scic_sds_phy *sci_phy, | ||
517 | u32 event_code) | ||
518 | { | ||
519 | return sci_phy->state_handlers->event_handler(sci_phy, event_code); | ||
520 | } | ||
521 | |||
522 | enum sci_status scic_sds_phy_frame_handler(struct scic_sds_phy *sci_phy, | ||
523 | u32 frame_index) | ||
524 | { | ||
525 | enum scic_sds_phy_states state = sci_phy->state_machine.current_state_id; | ||
526 | struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller; | ||
527 | enum sci_status result; | ||
528 | |||
529 | switch (state) { | ||
530 | case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF: { | ||
531 | u32 *frame_words; | ||
532 | struct sas_identify_frame iaf; | ||
533 | struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); | ||
534 | |||
535 | result = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, | ||
536 | frame_index, | ||
537 | (void **)&frame_words); | ||
538 | |||
539 | if (result != SCI_SUCCESS) | ||
540 | return result; | ||
541 | |||
542 | sci_swab32_cpy(&iaf, frame_words, sizeof(iaf) / sizeof(u32)); | ||
543 | if (iaf.frame_type == 0) { | ||
544 | u32 state; | ||
545 | |||
546 | memcpy(&iphy->frame_rcvd.iaf, &iaf, sizeof(iaf)); | ||
547 | if (iaf.smp_tport) { | ||
548 | /* We got the IAF for an expander PHY go to the final | ||
549 | * state since there are no power requirements for | ||
550 | * expander phys. | ||
551 | */ | ||
552 | state = SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL; | ||
553 | } else { | ||
554 | /* We got the IAF we can now go to the await spinup | ||
555 | * semaphore state | ||
556 | */ | ||
557 | state = SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER; | ||
558 | } | ||
559 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
560 | state); | ||
561 | result = SCI_SUCCESS; | ||
562 | } else | ||
563 | dev_warn(sciphy_to_dev(sci_phy), | ||
564 | "%s: PHY starting substate machine received " | ||
565 | "unexpected frame id %x\n", | ||
566 | __func__, frame_index); | ||
567 | |||
568 | scic_sds_controller_release_frame(scic, frame_index); | ||
569 | return result; | ||
570 | } | ||
571 | case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF: { | ||
572 | struct dev_to_host_fis *frame_header; | ||
573 | u32 *fis_frame_data; | ||
574 | struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); | ||
575 | |||
576 | result = scic_sds_unsolicited_frame_control_get_header( | ||
577 | &(scic_sds_phy_get_controller(sci_phy)->uf_control), | ||
578 | frame_index, | ||
579 | (void **)&frame_header); | ||
580 | |||
581 | if (result != SCI_SUCCESS) | ||
582 | return result; | ||
583 | |||
584 | if ((frame_header->fis_type == FIS_REGD2H) && | ||
585 | !(frame_header->status & ATA_BUSY)) { | ||
586 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
587 | frame_index, | ||
588 | (void **)&fis_frame_data); | ||
589 | |||
590 | scic_sds_controller_copy_sata_response(&iphy->frame_rcvd.fis, | ||
591 | frame_header, | ||
592 | fis_frame_data); | ||
593 | |||
594 | /* got IAF we can now go to the await spinup semaphore state */ | ||
595 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
596 | SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL); | ||
597 | |||
598 | result = SCI_SUCCESS; | ||
599 | } else | ||
600 | dev_warn(sciphy_to_dev(sci_phy), | ||
601 | "%s: PHY starting substate machine received " | ||
602 | "unexpected frame id %x\n", | ||
603 | __func__, frame_index); | ||
604 | |||
605 | /* Regardless of the result we are done with this frame with it */ | ||
606 | scic_sds_controller_release_frame(scic, frame_index); | ||
607 | |||
608 | return result; | ||
609 | } | ||
610 | default: | ||
611 | dev_dbg(sciphy_to_dev(sci_phy), | ||
612 | "%s: in wrong state: %d\n", __func__, state); | ||
613 | return SCI_FAILURE_INVALID_STATE; | ||
614 | } | ||
615 | |||
616 | } | ||
617 | |||
618 | /** | ||
619 | * This method will give the phy permission to consume power | 509 | * This method will give the phy permission to consume power |
620 | * @sci_phy: | 510 | * @sci_phy: |
621 | * | 511 | * |
@@ -702,455 +592,6 @@ static void scic_sds_phy_complete_link_training( | |||
702 | next_state); | 592 | next_state); |
703 | } | 593 | } |
704 | 594 | ||
705 | static void scic_sds_phy_restart_starting_state( | ||
706 | struct scic_sds_phy *sci_phy) | ||
707 | { | ||
708 | /* Re-enter the base state machine starting state */ | ||
709 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
710 | SCI_BASE_PHY_STATE_STARTING); | ||
711 | } | ||
712 | |||
713 | /** | ||
714 | * | ||
715 | * @phy: This struct scic_sds_phy object which has received an event. | ||
716 | * @event_code: This is the event code which the phy object is to decode. | ||
717 | * | ||
718 | * This method is called when an event notification is received for the phy | ||
719 | * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. - | ||
720 | * decode the event - sas phy detected causes a state transition to the wait | ||
721 | * for speed event notification. - any other events log a warning message and | ||
722 | * set a failure status enum sci_status SCI_SUCCESS on any valid event notification | ||
723 | * SCI_FAILURE on any unexpected event notifation | ||
724 | */ | ||
725 | static enum sci_status scic_sds_phy_starting_substate_await_ossp_event_handler( | ||
726 | struct scic_sds_phy *sci_phy, | ||
727 | u32 event_code) | ||
728 | { | ||
729 | u32 result = SCI_SUCCESS; | ||
730 | |||
731 | switch (scu_get_event_code(event_code)) { | ||
732 | case SCU_EVENT_SAS_PHY_DETECTED: | ||
733 | scic_sds_phy_start_sas_link_training(sci_phy); | ||
734 | sci_phy->is_in_link_training = true; | ||
735 | break; | ||
736 | |||
737 | case SCU_EVENT_SATA_SPINUP_HOLD: | ||
738 | scic_sds_phy_start_sata_link_training(sci_phy); | ||
739 | sci_phy->is_in_link_training = true; | ||
740 | break; | ||
741 | |||
742 | default: | ||
743 | dev_dbg(sciphy_to_dev(sci_phy), | ||
744 | "%s: PHY starting substate machine received " | ||
745 | "unexpected event_code %x\n", | ||
746 | __func__, | ||
747 | event_code); | ||
748 | |||
749 | result = SCI_FAILURE; | ||
750 | break; | ||
751 | } | ||
752 | |||
753 | return result; | ||
754 | } | ||
755 | |||
756 | /** | ||
757 | * | ||
758 | * @phy: This struct scic_sds_phy object which has received an event. | ||
759 | * @event_code: This is the event code which the phy object is to decode. | ||
760 | * | ||
761 | * This method is called when an event notification is received for the phy | ||
762 | * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. - | ||
763 | * decode the event - sas phy detected returns us back to this state. - speed | ||
764 | * event detected causes a state transition to the wait for iaf. - identify | ||
765 | * timeout is an un-expected event and the state machine is restarted. - link | ||
766 | * failure events restart the starting state machine - any other events log a | ||
767 | * warning message and set a failure status enum sci_status SCI_SUCCESS on any valid | ||
768 | * event notification SCI_FAILURE on any unexpected event notifation | ||
769 | */ | ||
770 | static enum sci_status scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler( | ||
771 | struct scic_sds_phy *sci_phy, | ||
772 | u32 event_code) | ||
773 | { | ||
774 | u32 result = SCI_SUCCESS; | ||
775 | |||
776 | switch (scu_get_event_code(event_code)) { | ||
777 | case SCU_EVENT_SAS_PHY_DETECTED: | ||
778 | /* | ||
779 | * Why is this being reported again by the controller? | ||
780 | * We would re-enter this state so just stay here */ | ||
781 | break; | ||
782 | |||
783 | case SCU_EVENT_SAS_15: | ||
784 | case SCU_EVENT_SAS_15_SSC: | ||
785 | scic_sds_phy_complete_link_training( | ||
786 | sci_phy, | ||
787 | SAS_LINK_RATE_1_5_GBPS, | ||
788 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF); | ||
789 | break; | ||
790 | |||
791 | case SCU_EVENT_SAS_30: | ||
792 | case SCU_EVENT_SAS_30_SSC: | ||
793 | scic_sds_phy_complete_link_training( | ||
794 | sci_phy, | ||
795 | SAS_LINK_RATE_3_0_GBPS, | ||
796 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF); | ||
797 | break; | ||
798 | |||
799 | case SCU_EVENT_SAS_60: | ||
800 | case SCU_EVENT_SAS_60_SSC: | ||
801 | scic_sds_phy_complete_link_training( | ||
802 | sci_phy, | ||
803 | SAS_LINK_RATE_6_0_GBPS, | ||
804 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF); | ||
805 | break; | ||
806 | |||
807 | case SCU_EVENT_SATA_SPINUP_HOLD: | ||
808 | /* | ||
809 | * We were doing SAS PHY link training and received a SATA PHY event | ||
810 | * continue OOB/SN as if this were a SATA PHY */ | ||
811 | scic_sds_phy_start_sata_link_training(sci_phy); | ||
812 | break; | ||
813 | |||
814 | case SCU_EVENT_LINK_FAILURE: | ||
815 | /* Link failure change state back to the starting state */ | ||
816 | scic_sds_phy_restart_starting_state(sci_phy); | ||
817 | break; | ||
818 | |||
819 | default: | ||
820 | dev_warn(sciphy_to_dev(sci_phy), | ||
821 | "%s: PHY starting substate machine received " | ||
822 | "unexpected event_code %x\n", | ||
823 | __func__, | ||
824 | event_code); | ||
825 | |||
826 | result = SCI_FAILURE; | ||
827 | break; | ||
828 | } | ||
829 | |||
830 | return result; | ||
831 | } | ||
832 | |||
833 | /** | ||
834 | * | ||
835 | * @phy: This struct scic_sds_phy object which has received an event. | ||
836 | * @event_code: This is the event code which the phy object is to decode. | ||
837 | * | ||
838 | * This method is called when an event notification is received for the phy | ||
839 | * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. - | ||
840 | * decode the event - sas phy detected event backs up the state machine to the | ||
841 | * await speed notification. - identify timeout is an un-expected event and the | ||
842 | * state machine is restarted. - link failure events restart the starting state | ||
843 | * machine - any other events log a warning message and set a failure status | ||
844 | * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any | ||
845 | * unexpected event notifation | ||
846 | */ | ||
847 | static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_event_handler( | ||
848 | struct scic_sds_phy *sci_phy, | ||
849 | u32 event_code) | ||
850 | { | ||
851 | u32 result = SCI_SUCCESS; | ||
852 | |||
853 | switch (scu_get_event_code(event_code)) { | ||
854 | case SCU_EVENT_SAS_PHY_DETECTED: | ||
855 | /* Backup the state machine */ | ||
856 | scic_sds_phy_start_sas_link_training(sci_phy); | ||
857 | break; | ||
858 | |||
859 | case SCU_EVENT_SATA_SPINUP_HOLD: | ||
860 | /* | ||
861 | * We were doing SAS PHY link training and received a SATA PHY event | ||
862 | * continue OOB/SN as if this were a SATA PHY */ | ||
863 | scic_sds_phy_start_sata_link_training(sci_phy); | ||
864 | break; | ||
865 | |||
866 | case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT: | ||
867 | case SCU_EVENT_LINK_FAILURE: | ||
868 | case SCU_EVENT_HARD_RESET_RECEIVED: | ||
869 | /* Start the oob/sn state machine over again */ | ||
870 | scic_sds_phy_restart_starting_state(sci_phy); | ||
871 | break; | ||
872 | |||
873 | default: | ||
874 | dev_warn(sciphy_to_dev(sci_phy), | ||
875 | "%s: PHY starting substate machine received " | ||
876 | "unexpected event_code %x\n", | ||
877 | __func__, | ||
878 | event_code); | ||
879 | |||
880 | result = SCI_FAILURE; | ||
881 | break; | ||
882 | } | ||
883 | |||
884 | return result; | ||
885 | } | ||
886 | |||
887 | /** | ||
888 | * | ||
889 | * @phy: This struct scic_sds_phy object which has received an event. | ||
890 | * @event_code: This is the event code which the phy object is to decode. | ||
891 | * | ||
892 | * This method is called when an event notification is received for the phy | ||
893 | * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_POWER. - | ||
894 | * decode the event - link failure events restart the starting state machine - | ||
895 | * any other events log a warning message and set a failure status enum sci_status | ||
896 | * SCI_SUCCESS on a link failure event SCI_FAILURE on any unexpected event | ||
897 | * notifation | ||
898 | */ | ||
899 | static enum sci_status scic_sds_phy_starting_substate_await_sas_power_event_handler( | ||
900 | struct scic_sds_phy *sci_phy, | ||
901 | u32 event_code) | ||
902 | { | ||
903 | u32 result = SCI_SUCCESS; | ||
904 | |||
905 | switch (scu_get_event_code(event_code)) { | ||
906 | case SCU_EVENT_LINK_FAILURE: | ||
907 | /* Link failure change state back to the starting state */ | ||
908 | scic_sds_phy_restart_starting_state(sci_phy); | ||
909 | break; | ||
910 | |||
911 | default: | ||
912 | dev_warn(sciphy_to_dev(sci_phy), | ||
913 | "%s: PHY starting substate machine received unexpected " | ||
914 | "event_code %x\n", | ||
915 | __func__, | ||
916 | event_code); | ||
917 | |||
918 | result = SCI_FAILURE; | ||
919 | break; | ||
920 | } | ||
921 | |||
922 | return result; | ||
923 | } | ||
924 | |||
925 | /** | ||
926 | * | ||
927 | * @phy: This struct scic_sds_phy object which has received an event. | ||
928 | * @event_code: This is the event code which the phy object is to decode. | ||
929 | * | ||
930 | * This method is called when an event notification is received for the phy | ||
931 | * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. - | ||
932 | * decode the event - link failure events restart the starting state machine - | ||
933 | * sata spinup hold events are ignored since they are expected - any other | ||
934 | * events log a warning message and set a failure status enum sci_status SCI_SUCCESS | ||
935 | * on a link failure event SCI_FAILURE on any unexpected event notifation | ||
936 | */ | ||
937 | static enum sci_status scic_sds_phy_starting_substate_await_sata_power_event_handler( | ||
938 | struct scic_sds_phy *sci_phy, | ||
939 | u32 event_code) | ||
940 | { | ||
941 | u32 result = SCI_SUCCESS; | ||
942 | |||
943 | switch (scu_get_event_code(event_code)) { | ||
944 | case SCU_EVENT_LINK_FAILURE: | ||
945 | /* Link failure change state back to the starting state */ | ||
946 | scic_sds_phy_restart_starting_state(sci_phy); | ||
947 | break; | ||
948 | |||
949 | case SCU_EVENT_SATA_SPINUP_HOLD: | ||
950 | /* These events are received every 10ms and are expected while in this state */ | ||
951 | break; | ||
952 | |||
953 | case SCU_EVENT_SAS_PHY_DETECTED: | ||
954 | /* | ||
955 | * There has been a change in the phy type before OOB/SN for the | ||
956 | * SATA finished start down the SAS link traning path. */ | ||
957 | scic_sds_phy_start_sas_link_training(sci_phy); | ||
958 | break; | ||
959 | |||
960 | default: | ||
961 | dev_warn(sciphy_to_dev(sci_phy), | ||
962 | "%s: PHY starting substate machine received " | ||
963 | "unexpected event_code %x\n", | ||
964 | __func__, | ||
965 | event_code); | ||
966 | |||
967 | result = SCI_FAILURE; | ||
968 | break; | ||
969 | } | ||
970 | |||
971 | return result; | ||
972 | } | ||
973 | |||
974 | /** | ||
975 | * scic_sds_phy_starting_substate_await_sata_phy_event_handler - | ||
976 | * @phy: This struct scic_sds_phy object which has received an event. | ||
977 | * @event_code: This is the event code which the phy object is to decode. | ||
978 | * | ||
979 | * This method is called when an event notification is received for the phy | ||
980 | * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. - | ||
981 | * decode the event - link failure events restart the starting state machine - | ||
982 | * sata spinup hold events are ignored since they are expected - sata phy | ||
983 | * detected event change to the wait speed event - any other events log a | ||
984 | * warning message and set a failure status enum sci_status SCI_SUCCESS on a link | ||
985 | * failure event SCI_FAILURE on any unexpected event notifation | ||
986 | */ | ||
987 | static enum sci_status scic_sds_phy_starting_substate_await_sata_phy_event_handler( | ||
988 | struct scic_sds_phy *sci_phy, u32 event_code) | ||
989 | { | ||
990 | u32 result = SCI_SUCCESS; | ||
991 | |||
992 | switch (scu_get_event_code(event_code)) { | ||
993 | case SCU_EVENT_LINK_FAILURE: | ||
994 | /* Link failure change state back to the starting state */ | ||
995 | scic_sds_phy_restart_starting_state(sci_phy); | ||
996 | break; | ||
997 | |||
998 | case SCU_EVENT_SATA_SPINUP_HOLD: | ||
999 | /* These events might be received since we dont know how many may be in | ||
1000 | * the completion queue while waiting for power | ||
1001 | */ | ||
1002 | break; | ||
1003 | |||
1004 | case SCU_EVENT_SATA_PHY_DETECTED: | ||
1005 | sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA; | ||
1006 | |||
1007 | /* We have received the SATA PHY notification change state */ | ||
1008 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
1009 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN); | ||
1010 | break; | ||
1011 | |||
1012 | case SCU_EVENT_SAS_PHY_DETECTED: | ||
1013 | /* There has been a change in the phy type before OOB/SN for the | ||
1014 | * SATA finished start down the SAS link traning path. | ||
1015 | */ | ||
1016 | scic_sds_phy_start_sas_link_training(sci_phy); | ||
1017 | break; | ||
1018 | |||
1019 | default: | ||
1020 | dev_warn(sciphy_to_dev(sci_phy), | ||
1021 | "%s: PHY starting substate machine received " | ||
1022 | "unexpected event_code %x\n", | ||
1023 | __func__, | ||
1024 | event_code); | ||
1025 | |||
1026 | result = SCI_FAILURE; | ||
1027 | break; | ||
1028 | } | ||
1029 | |||
1030 | return result; | ||
1031 | } | ||
1032 | |||
1033 | /** | ||
1034 | * | ||
1035 | * @phy: This struct scic_sds_phy object which has received an event. | ||
1036 | * @event_code: This is the event code which the phy object is to decode. | ||
1037 | * | ||
1038 | * This method is called when an event notification is received for the phy | ||
1039 | * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. | ||
1040 | * - decode the event - sata phy detected returns us back to this state. - | ||
1041 | * speed event detected causes a state transition to the wait for signature. - | ||
1042 | * link failure events restart the starting state machine - any other events | ||
1043 | * log a warning message and set a failure status enum sci_status SCI_SUCCESS on any | ||
1044 | * valid event notification SCI_FAILURE on any unexpected event notifation | ||
1045 | */ | ||
1046 | static enum sci_status scic_sds_phy_starting_substate_await_sata_speed_event_handler( | ||
1047 | struct scic_sds_phy *sci_phy, | ||
1048 | u32 event_code) | ||
1049 | { | ||
1050 | u32 result = SCI_SUCCESS; | ||
1051 | |||
1052 | switch (scu_get_event_code(event_code)) { | ||
1053 | case SCU_EVENT_SATA_PHY_DETECTED: | ||
1054 | /* | ||
1055 | * The hardware reports multiple SATA PHY detected events | ||
1056 | * ignore the extras */ | ||
1057 | break; | ||
1058 | |||
1059 | case SCU_EVENT_SATA_15: | ||
1060 | case SCU_EVENT_SATA_15_SSC: | ||
1061 | scic_sds_phy_complete_link_training( | ||
1062 | sci_phy, | ||
1063 | SAS_LINK_RATE_1_5_GBPS, | ||
1064 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF); | ||
1065 | break; | ||
1066 | |||
1067 | case SCU_EVENT_SATA_30: | ||
1068 | case SCU_EVENT_SATA_30_SSC: | ||
1069 | scic_sds_phy_complete_link_training( | ||
1070 | sci_phy, | ||
1071 | SAS_LINK_RATE_3_0_GBPS, | ||
1072 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF); | ||
1073 | break; | ||
1074 | |||
1075 | case SCU_EVENT_SATA_60: | ||
1076 | case SCU_EVENT_SATA_60_SSC: | ||
1077 | scic_sds_phy_complete_link_training( | ||
1078 | sci_phy, | ||
1079 | SAS_LINK_RATE_6_0_GBPS, | ||
1080 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF); | ||
1081 | break; | ||
1082 | |||
1083 | case SCU_EVENT_LINK_FAILURE: | ||
1084 | /* Link failure change state back to the starting state */ | ||
1085 | scic_sds_phy_restart_starting_state(sci_phy); | ||
1086 | break; | ||
1087 | |||
1088 | case SCU_EVENT_SAS_PHY_DETECTED: | ||
1089 | /* | ||
1090 | * There has been a change in the phy type before OOB/SN for the | ||
1091 | * SATA finished start down the SAS link traning path. */ | ||
1092 | scic_sds_phy_start_sas_link_training(sci_phy); | ||
1093 | break; | ||
1094 | |||
1095 | default: | ||
1096 | dev_warn(sciphy_to_dev(sci_phy), | ||
1097 | "%s: PHY starting substate machine received " | ||
1098 | "unexpected event_code %x\n", | ||
1099 | __func__, | ||
1100 | event_code); | ||
1101 | |||
1102 | result = SCI_FAILURE; | ||
1103 | break; | ||
1104 | } | ||
1105 | |||
1106 | return result; | ||
1107 | } | ||
1108 | |||
1109 | /** | ||
1110 | * scic_sds_phy_starting_substate_await_sig_fis_event_handler - | ||
1111 | * @phy: This struct scic_sds_phy object which has received an event. | ||
1112 | * @event_code: This is the event code which the phy object is to decode. | ||
1113 | * | ||
1114 | * This method is called when an event notification is received for the phy | ||
1115 | * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - | ||
1116 | * decode the event - sas phy detected event backs up the state machine to the | ||
1117 | * await speed notification. - identify timeout is an un-expected event and the | ||
1118 | * state machine is restarted. - link failure events restart the starting state | ||
1119 | * machine - any other events log a warning message and set a failure status | ||
1120 | * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any | ||
1121 | * unexpected event notifation | ||
1122 | */ | ||
1123 | static enum sci_status scic_sds_phy_starting_substate_await_sig_fis_event_handler( | ||
1124 | struct scic_sds_phy *sci_phy, u32 event_code) | ||
1125 | { | ||
1126 | u32 result = SCI_SUCCESS; | ||
1127 | |||
1128 | switch (scu_get_event_code(event_code)) { | ||
1129 | case SCU_EVENT_SATA_PHY_DETECTED: | ||
1130 | /* Backup the state machine */ | ||
1131 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
1132 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN); | ||
1133 | break; | ||
1134 | |||
1135 | case SCU_EVENT_LINK_FAILURE: | ||
1136 | /* Link failure change state back to the starting state */ | ||
1137 | scic_sds_phy_restart_starting_state(sci_phy); | ||
1138 | break; | ||
1139 | |||
1140 | default: | ||
1141 | dev_warn(sciphy_to_dev(sci_phy), | ||
1142 | "%s: PHY starting substate machine received " | ||
1143 | "unexpected event_code %x\n", | ||
1144 | __func__, | ||
1145 | event_code); | ||
1146 | |||
1147 | result = SCI_FAILURE; | ||
1148 | break; | ||
1149 | } | ||
1150 | |||
1151 | return result; | ||
1152 | } | ||
1153 | |||
1154 | /* | 595 | /* |
1155 | * This method is called by the struct scic_sds_controller when the phy object is | 596 | * This method is called by the struct scic_sds_controller when the phy object is |
1156 | * granted power. - The notify enable spinups are turned on for this phy object | 597 | * granted power. - The notify enable spinups are turned on for this phy object |
@@ -1215,154 +656,460 @@ static enum sci_status default_phy_handler(struct scic_sds_phy *sci_phy, | |||
1215 | } | 656 | } |
1216 | 657 | ||
1217 | static enum sci_status | 658 | static enum sci_status |
1218 | scic_sds_phy_default_event_handler(struct scic_sds_phy *sci_phy, | ||
1219 | u32 event_code) | ||
1220 | { | ||
1221 | return default_phy_handler(sci_phy, __func__); | ||
1222 | } | ||
1223 | |||
1224 | static enum sci_status | ||
1225 | scic_sds_phy_default_consume_power_handler(struct scic_sds_phy *sci_phy) | 659 | scic_sds_phy_default_consume_power_handler(struct scic_sds_phy *sci_phy) |
1226 | { | 660 | { |
1227 | return default_phy_handler(sci_phy, __func__); | 661 | return default_phy_handler(sci_phy, __func__); |
1228 | } | 662 | } |
1229 | 663 | ||
1230 | /** | 664 | |
1231 | * scic_sds_phy_ready_state_event_handler - | 665 | enum sci_status scic_sds_phy_event_handler(struct scic_sds_phy *sci_phy, |
1232 | * @phy: This is the struct scic_sds_phy object which has received the event. | 666 | u32 event_code) |
1233 | * | ||
1234 | * This method request the struct scic_sds_phy handle the received event. The only | ||
1235 | * event that we are interested in while in the ready state is the link failure | ||
1236 | * event. - decoded event is a link failure - transition the struct scic_sds_phy back | ||
1237 | * to the SCI_BASE_PHY_STATE_STARTING state. - any other event received will | ||
1238 | * report a warning message enum sci_status SCI_SUCCESS if the event received is a | ||
1239 | * link failure SCI_FAILURE_INVALID_STATE for any other event received. | ||
1240 | */ | ||
1241 | static enum sci_status scic_sds_phy_ready_state_event_handler(struct scic_sds_phy *sci_phy, | ||
1242 | u32 event_code) | ||
1243 | { | 667 | { |
1244 | enum sci_status result = SCI_FAILURE; | 668 | enum scic_sds_phy_states state = sci_phy->state_machine.current_state_id; |
1245 | 669 | ||
1246 | switch (scu_get_event_code(event_code)) { | 670 | switch (state) { |
1247 | case SCU_EVENT_LINK_FAILURE: | 671 | case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN: |
1248 | /* Link failure change state back to the starting state */ | 672 | switch (scu_get_event_code(event_code)) { |
1249 | sci_base_state_machine_change_state(&sci_phy->state_machine, | 673 | case SCU_EVENT_SAS_PHY_DETECTED: |
1250 | SCI_BASE_PHY_STATE_STARTING); | 674 | scic_sds_phy_start_sas_link_training(sci_phy); |
1251 | result = SCI_SUCCESS; | 675 | sci_phy->is_in_link_training = true; |
1252 | break; | 676 | break; |
677 | case SCU_EVENT_SATA_SPINUP_HOLD: | ||
678 | scic_sds_phy_start_sata_link_training(sci_phy); | ||
679 | sci_phy->is_in_link_training = true; | ||
680 | break; | ||
681 | default: | ||
682 | dev_dbg(sciphy_to_dev(sci_phy), | ||
683 | "%s: PHY starting substate machine received " | ||
684 | "unexpected event_code %x\n", | ||
685 | __func__, | ||
686 | event_code); | ||
687 | return SCI_FAILURE; | ||
688 | } | ||
689 | return SCI_SUCCESS; | ||
690 | case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN: | ||
691 | switch (scu_get_event_code(event_code)) { | ||
692 | case SCU_EVENT_SAS_PHY_DETECTED: | ||
693 | /* | ||
694 | * Why is this being reported again by the controller? | ||
695 | * We would re-enter this state so just stay here */ | ||
696 | break; | ||
697 | case SCU_EVENT_SAS_15: | ||
698 | case SCU_EVENT_SAS_15_SSC: | ||
699 | scic_sds_phy_complete_link_training( | ||
700 | sci_phy, | ||
701 | SAS_LINK_RATE_1_5_GBPS, | ||
702 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF); | ||
703 | break; | ||
704 | case SCU_EVENT_SAS_30: | ||
705 | case SCU_EVENT_SAS_30_SSC: | ||
706 | scic_sds_phy_complete_link_training( | ||
707 | sci_phy, | ||
708 | SAS_LINK_RATE_3_0_GBPS, | ||
709 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF); | ||
710 | break; | ||
711 | case SCU_EVENT_SAS_60: | ||
712 | case SCU_EVENT_SAS_60_SSC: | ||
713 | scic_sds_phy_complete_link_training( | ||
714 | sci_phy, | ||
715 | SAS_LINK_RATE_6_0_GBPS, | ||
716 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF); | ||
717 | break; | ||
718 | case SCU_EVENT_SATA_SPINUP_HOLD: | ||
719 | /* | ||
720 | * We were doing SAS PHY link training and received a SATA PHY event | ||
721 | * continue OOB/SN as if this were a SATA PHY */ | ||
722 | scic_sds_phy_start_sata_link_training(sci_phy); | ||
723 | break; | ||
724 | case SCU_EVENT_LINK_FAILURE: | ||
725 | /* Link failure change state back to the starting state */ | ||
726 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
727 | SCI_BASE_PHY_STATE_STARTING); | ||
728 | break; | ||
729 | default: | ||
730 | dev_warn(sciphy_to_dev(sci_phy), | ||
731 | "%s: PHY starting substate machine received " | ||
732 | "unexpected event_code %x\n", | ||
733 | __func__, event_code); | ||
734 | |||
735 | return SCI_FAILURE; | ||
736 | break; | ||
737 | } | ||
738 | return SCI_SUCCESS; | ||
739 | case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF: | ||
740 | switch (scu_get_event_code(event_code)) { | ||
741 | case SCU_EVENT_SAS_PHY_DETECTED: | ||
742 | /* Backup the state machine */ | ||
743 | scic_sds_phy_start_sas_link_training(sci_phy); | ||
744 | break; | ||
745 | case SCU_EVENT_SATA_SPINUP_HOLD: | ||
746 | /* We were doing SAS PHY link training and received a | ||
747 | * SATA PHY event continue OOB/SN as if this were a | ||
748 | * SATA PHY | ||
749 | */ | ||
750 | scic_sds_phy_start_sata_link_training(sci_phy); | ||
751 | break; | ||
752 | case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT: | ||
753 | case SCU_EVENT_LINK_FAILURE: | ||
754 | case SCU_EVENT_HARD_RESET_RECEIVED: | ||
755 | /* Start the oob/sn state machine over again */ | ||
756 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
757 | SCI_BASE_PHY_STATE_STARTING); | ||
758 | break; | ||
759 | default: | ||
760 | dev_warn(sciphy_to_dev(sci_phy), | ||
761 | "%s: PHY starting substate machine received " | ||
762 | "unexpected event_code %x\n", | ||
763 | __func__, event_code); | ||
764 | return SCI_FAILURE; | ||
765 | } | ||
766 | return SCI_SUCCESS; | ||
767 | case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER: | ||
768 | switch (scu_get_event_code(event_code)) { | ||
769 | case SCU_EVENT_LINK_FAILURE: | ||
770 | /* Link failure change state back to the starting state */ | ||
771 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
772 | SCI_BASE_PHY_STATE_STARTING); | ||
773 | break; | ||
774 | default: | ||
775 | dev_warn(sciphy_to_dev(sci_phy), | ||
776 | "%s: PHY starting substate machine received unexpected " | ||
777 | "event_code %x\n", | ||
778 | __func__, | ||
779 | event_code); | ||
780 | return SCI_FAILURE; | ||
781 | } | ||
782 | return SCI_SUCCESS; | ||
783 | case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER: | ||
784 | switch (scu_get_event_code(event_code)) { | ||
785 | case SCU_EVENT_LINK_FAILURE: | ||
786 | /* Link failure change state back to the starting state */ | ||
787 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
788 | SCI_BASE_PHY_STATE_STARTING); | ||
789 | break; | ||
790 | case SCU_EVENT_SATA_SPINUP_HOLD: | ||
791 | /* These events are received every 10ms and are | ||
792 | * expected while in this state | ||
793 | */ | ||
794 | break; | ||
795 | |||
796 | case SCU_EVENT_SAS_PHY_DETECTED: | ||
797 | /* There has been a change in the phy type before OOB/SN for the | ||
798 | * SATA finished start down the SAS link traning path. | ||
799 | */ | ||
800 | scic_sds_phy_start_sas_link_training(sci_phy); | ||
801 | break; | ||
802 | |||
803 | default: | ||
804 | dev_warn(sciphy_to_dev(sci_phy), | ||
805 | "%s: PHY starting substate machine received " | ||
806 | "unexpected event_code %x\n", | ||
807 | __func__, event_code); | ||
1253 | 808 | ||
1254 | case SCU_EVENT_BROADCAST_CHANGE: | 809 | return SCI_FAILURE; |
1255 | /* Broadcast change received. Notify the port. */ | 810 | } |
1256 | if (scic_sds_phy_get_port(sci_phy) != NULL) | 811 | return SCI_SUCCESS; |
1257 | scic_sds_port_broadcast_change_received(sci_phy->owning_port, sci_phy); | 812 | case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN: |
1258 | else | 813 | switch (scu_get_event_code(event_code)) { |
1259 | sci_phy->bcn_received_while_port_unassigned = true; | 814 | case SCU_EVENT_LINK_FAILURE: |
1260 | break; | 815 | /* Link failure change state back to the starting state */ |
816 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
817 | SCI_BASE_PHY_STATE_STARTING); | ||
818 | break; | ||
819 | case SCU_EVENT_SATA_SPINUP_HOLD: | ||
820 | /* These events might be received since we dont know how many may be in | ||
821 | * the completion queue while waiting for power | ||
822 | */ | ||
823 | break; | ||
824 | case SCU_EVENT_SATA_PHY_DETECTED: | ||
825 | sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA; | ||
826 | |||
827 | /* We have received the SATA PHY notification change state */ | ||
828 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
829 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN); | ||
830 | break; | ||
831 | case SCU_EVENT_SAS_PHY_DETECTED: | ||
832 | /* There has been a change in the phy type before OOB/SN for the | ||
833 | * SATA finished start down the SAS link traning path. | ||
834 | */ | ||
835 | scic_sds_phy_start_sas_link_training(sci_phy); | ||
836 | break; | ||
837 | default: | ||
838 | dev_warn(sciphy_to_dev(sci_phy), | ||
839 | "%s: PHY starting substate machine received " | ||
840 | "unexpected event_code %x\n", | ||
841 | __func__, | ||
842 | event_code); | ||
1261 | 843 | ||
1262 | default: | 844 | return SCI_FAILURE;; |
1263 | dev_warn(sciphy_to_dev(sci_phy), | 845 | } |
1264 | "%sP SCIC PHY 0x%p ready state machine received " | 846 | return SCI_SUCCESS; |
1265 | "unexpected event_code %x\n", | 847 | case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN: |
1266 | __func__, sci_phy, event_code); | 848 | switch (scu_get_event_code(event_code)) { |
849 | case SCU_EVENT_SATA_PHY_DETECTED: | ||
850 | /* | ||
851 | * The hardware reports multiple SATA PHY detected events | ||
852 | * ignore the extras */ | ||
853 | break; | ||
854 | case SCU_EVENT_SATA_15: | ||
855 | case SCU_EVENT_SATA_15_SSC: | ||
856 | scic_sds_phy_complete_link_training( | ||
857 | sci_phy, | ||
858 | SAS_LINK_RATE_1_5_GBPS, | ||
859 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF); | ||
860 | break; | ||
861 | case SCU_EVENT_SATA_30: | ||
862 | case SCU_EVENT_SATA_30_SSC: | ||
863 | scic_sds_phy_complete_link_training( | ||
864 | sci_phy, | ||
865 | SAS_LINK_RATE_3_0_GBPS, | ||
866 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF); | ||
867 | break; | ||
868 | case SCU_EVENT_SATA_60: | ||
869 | case SCU_EVENT_SATA_60_SSC: | ||
870 | scic_sds_phy_complete_link_training( | ||
871 | sci_phy, | ||
872 | SAS_LINK_RATE_6_0_GBPS, | ||
873 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF); | ||
874 | break; | ||
875 | case SCU_EVENT_LINK_FAILURE: | ||
876 | /* Link failure change state back to the starting state */ | ||
877 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
878 | SCI_BASE_PHY_STATE_STARTING); | ||
879 | break; | ||
880 | case SCU_EVENT_SAS_PHY_DETECTED: | ||
881 | /* | ||
882 | * There has been a change in the phy type before OOB/SN for the | ||
883 | * SATA finished start down the SAS link traning path. */ | ||
884 | scic_sds_phy_start_sas_link_training(sci_phy); | ||
885 | break; | ||
886 | default: | ||
887 | dev_warn(sciphy_to_dev(sci_phy), | ||
888 | "%s: PHY starting substate machine received " | ||
889 | "unexpected event_code %x\n", | ||
890 | __func__, event_code); | ||
1267 | 891 | ||
1268 | result = SCI_FAILURE_INVALID_STATE; | 892 | return SCI_FAILURE; |
1269 | break; | 893 | } |
1270 | } | 894 | |
895 | return SCI_SUCCESS; | ||
896 | case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF: | ||
897 | switch (scu_get_event_code(event_code)) { | ||
898 | case SCU_EVENT_SATA_PHY_DETECTED: | ||
899 | /* Backup the state machine */ | ||
900 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
901 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN); | ||
902 | break; | ||
903 | |||
904 | case SCU_EVENT_LINK_FAILURE: | ||
905 | /* Link failure change state back to the starting state */ | ||
906 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
907 | SCI_BASE_PHY_STATE_STARTING); | ||
908 | break; | ||
1271 | 909 | ||
1272 | return result; | 910 | default: |
911 | dev_warn(sciphy_to_dev(sci_phy), | ||
912 | "%s: PHY starting substate machine received " | ||
913 | "unexpected event_code %x\n", | ||
914 | __func__, | ||
915 | event_code); | ||
916 | |||
917 | return SCI_FAILURE; | ||
918 | } | ||
919 | return SCI_SUCCESS; | ||
920 | case SCI_BASE_PHY_STATE_READY: | ||
921 | switch (scu_get_event_code(event_code)) { | ||
922 | case SCU_EVENT_LINK_FAILURE: | ||
923 | /* Link failure change state back to the starting state */ | ||
924 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
925 | SCI_BASE_PHY_STATE_STARTING); | ||
926 | break; | ||
927 | case SCU_EVENT_BROADCAST_CHANGE: | ||
928 | /* Broadcast change received. Notify the port. */ | ||
929 | if (scic_sds_phy_get_port(sci_phy) != NULL) | ||
930 | scic_sds_port_broadcast_change_received(sci_phy->owning_port, sci_phy); | ||
931 | else | ||
932 | sci_phy->bcn_received_while_port_unassigned = true; | ||
933 | break; | ||
934 | default: | ||
935 | dev_warn(sciphy_to_dev(sci_phy), | ||
936 | "%sP SCIC PHY 0x%p ready state machine received " | ||
937 | "unexpected event_code %x\n", | ||
938 | __func__, sci_phy, event_code); | ||
939 | return SCI_FAILURE_INVALID_STATE; | ||
940 | } | ||
941 | return SCI_SUCCESS; | ||
942 | case SCI_BASE_PHY_STATE_RESETTING: | ||
943 | switch (scu_get_event_code(event_code)) { | ||
944 | case SCU_EVENT_HARD_RESET_TRANSMITTED: | ||
945 | /* Link failure change state back to the starting state */ | ||
946 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
947 | SCI_BASE_PHY_STATE_STARTING); | ||
948 | break; | ||
949 | default: | ||
950 | dev_warn(sciphy_to_dev(sci_phy), | ||
951 | "%s: SCIC PHY 0x%p resetting state machine received " | ||
952 | "unexpected event_code %x\n", | ||
953 | __func__, sci_phy, event_code); | ||
954 | |||
955 | return SCI_FAILURE_INVALID_STATE; | ||
956 | break; | ||
957 | } | ||
958 | return SCI_SUCCESS; | ||
959 | default: | ||
960 | dev_dbg(sciphy_to_dev(sci_phy), | ||
961 | "%s: in wrong state: %d\n", __func__, state); | ||
962 | return SCI_FAILURE_INVALID_STATE; | ||
963 | } | ||
1273 | } | 964 | } |
1274 | 965 | ||
1275 | static enum sci_status scic_sds_phy_resetting_state_event_handler(struct scic_sds_phy *sci_phy, | 966 | enum sci_status scic_sds_phy_frame_handler(struct scic_sds_phy *sci_phy, |
1276 | u32 event_code) | 967 | u32 frame_index) |
1277 | { | 968 | { |
1278 | enum sci_status result = SCI_FAILURE; | 969 | enum scic_sds_phy_states state = sci_phy->state_machine.current_state_id; |
970 | struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller; | ||
971 | enum sci_status result; | ||
1279 | 972 | ||
1280 | switch (scu_get_event_code(event_code)) { | 973 | switch (state) { |
1281 | case SCU_EVENT_HARD_RESET_TRANSMITTED: | 974 | case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF: { |
1282 | /* Link failure change state back to the starting state */ | 975 | u32 *frame_words; |
1283 | sci_base_state_machine_change_state(&sci_phy->state_machine, | 976 | struct sas_identify_frame iaf; |
1284 | SCI_BASE_PHY_STATE_STARTING); | 977 | struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); |
1285 | result = SCI_SUCCESS; | ||
1286 | break; | ||
1287 | 978 | ||
1288 | default: | 979 | result = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, |
1289 | dev_warn(sciphy_to_dev(sci_phy), | 980 | frame_index, |
1290 | "%s: SCIC PHY 0x%p resetting state machine received " | 981 | (void **)&frame_words); |
1291 | "unexpected event_code %x\n", | ||
1292 | __func__, sci_phy, event_code); | ||
1293 | 982 | ||
1294 | result = SCI_FAILURE_INVALID_STATE; | 983 | if (result != SCI_SUCCESS) |
1295 | break; | 984 | return result; |
985 | |||
986 | sci_swab32_cpy(&iaf, frame_words, sizeof(iaf) / sizeof(u32)); | ||
987 | if (iaf.frame_type == 0) { | ||
988 | u32 state; | ||
989 | |||
990 | memcpy(&iphy->frame_rcvd.iaf, &iaf, sizeof(iaf)); | ||
991 | if (iaf.smp_tport) { | ||
992 | /* We got the IAF for an expander PHY go to the final | ||
993 | * state since there are no power requirements for | ||
994 | * expander phys. | ||
995 | */ | ||
996 | state = SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL; | ||
997 | } else { | ||
998 | /* We got the IAF we can now go to the await spinup | ||
999 | * semaphore state | ||
1000 | */ | ||
1001 | state = SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER; | ||
1002 | } | ||
1003 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
1004 | state); | ||
1005 | result = SCI_SUCCESS; | ||
1006 | } else | ||
1007 | dev_warn(sciphy_to_dev(sci_phy), | ||
1008 | "%s: PHY starting substate machine received " | ||
1009 | "unexpected frame id %x\n", | ||
1010 | __func__, frame_index); | ||
1011 | |||
1012 | scic_sds_controller_release_frame(scic, frame_index); | ||
1013 | return result; | ||
1296 | } | 1014 | } |
1015 | case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF: { | ||
1016 | struct dev_to_host_fis *frame_header; | ||
1017 | u32 *fis_frame_data; | ||
1018 | struct isci_phy *iphy = sci_phy_to_iphy(sci_phy); | ||
1019 | |||
1020 | result = scic_sds_unsolicited_frame_control_get_header( | ||
1021 | &(scic_sds_phy_get_controller(sci_phy)->uf_control), | ||
1022 | frame_index, | ||
1023 | (void **)&frame_header); | ||
1024 | |||
1025 | if (result != SCI_SUCCESS) | ||
1026 | return result; | ||
1297 | 1027 | ||
1298 | return result; | 1028 | if ((frame_header->fis_type == FIS_REGD2H) && |
1029 | !(frame_header->status & ATA_BUSY)) { | ||
1030 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
1031 | frame_index, | ||
1032 | (void **)&fis_frame_data); | ||
1033 | |||
1034 | scic_sds_controller_copy_sata_response(&iphy->frame_rcvd.fis, | ||
1035 | frame_header, | ||
1036 | fis_frame_data); | ||
1037 | |||
1038 | /* got IAF we can now go to the await spinup semaphore state */ | ||
1039 | sci_base_state_machine_change_state(&sci_phy->state_machine, | ||
1040 | SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL); | ||
1041 | |||
1042 | result = SCI_SUCCESS; | ||
1043 | } else | ||
1044 | dev_warn(sciphy_to_dev(sci_phy), | ||
1045 | "%s: PHY starting substate machine received " | ||
1046 | "unexpected frame id %x\n", | ||
1047 | __func__, frame_index); | ||
1048 | |||
1049 | /* Regardless of the result we are done with this frame with it */ | ||
1050 | scic_sds_controller_release_frame(scic, frame_index); | ||
1051 | |||
1052 | return result; | ||
1053 | } | ||
1054 | default: | ||
1055 | dev_dbg(sciphy_to_dev(sci_phy), | ||
1056 | "%s: in wrong state: %d\n", __func__, state); | ||
1057 | return SCI_FAILURE_INVALID_STATE; | ||
1058 | } | ||
1059 | |||
1299 | } | 1060 | } |
1300 | 1061 | ||
1062 | |||
1063 | |||
1301 | /* --------------------------------------------------------------------------- */ | 1064 | /* --------------------------------------------------------------------------- */ |
1302 | 1065 | ||
1303 | static const struct scic_sds_phy_state_handler scic_sds_phy_state_handler_table[] = { | 1066 | static const struct scic_sds_phy_state_handler scic_sds_phy_state_handler_table[] = { |
1304 | [SCI_BASE_PHY_STATE_INITIAL] = { | 1067 | [SCI_BASE_PHY_STATE_INITIAL] = { |
1305 | .event_handler = scic_sds_phy_default_event_handler, | ||
1306 | .consume_power_handler = scic_sds_phy_default_consume_power_handler | 1068 | .consume_power_handler = scic_sds_phy_default_consume_power_handler |
1307 | }, | 1069 | }, |
1308 | [SCI_BASE_PHY_STATE_STOPPED] = { | 1070 | [SCI_BASE_PHY_STATE_STOPPED] = { |
1309 | .event_handler = scic_sds_phy_default_event_handler, | ||
1310 | .consume_power_handler = scic_sds_phy_default_consume_power_handler | 1071 | .consume_power_handler = scic_sds_phy_default_consume_power_handler |
1311 | }, | 1072 | }, |
1312 | [SCI_BASE_PHY_STATE_STARTING] = { | 1073 | [SCI_BASE_PHY_STATE_STARTING] = { |
1313 | .event_handler = scic_sds_phy_default_event_handler, | ||
1314 | .consume_power_handler = scic_sds_phy_default_consume_power_handler | 1074 | .consume_power_handler = scic_sds_phy_default_consume_power_handler |
1315 | }, | 1075 | }, |
1316 | [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = { | 1076 | [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = { |
1317 | .event_handler = scic_sds_phy_default_event_handler, | ||
1318 | .consume_power_handler = scic_sds_phy_default_consume_power_handler | 1077 | .consume_power_handler = scic_sds_phy_default_consume_power_handler |
1319 | }, | 1078 | }, |
1320 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN] = { | 1079 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN] = { |
1321 | .event_handler = scic_sds_phy_starting_substate_await_ossp_event_handler, | ||
1322 | .consume_power_handler = scic_sds_phy_default_consume_power_handler | 1080 | .consume_power_handler = scic_sds_phy_default_consume_power_handler |
1323 | }, | 1081 | }, |
1324 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN] = { | 1082 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN] = { |
1325 | .event_handler = scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler, | ||
1326 | .consume_power_handler = scic_sds_phy_default_consume_power_handler | 1083 | .consume_power_handler = scic_sds_phy_default_consume_power_handler |
1327 | }, | 1084 | }, |
1328 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF] = { | 1085 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF] = { |
1329 | .event_handler = scic_sds_phy_starting_substate_await_iaf_uf_event_handler, | ||
1330 | .consume_power_handler = scic_sds_phy_default_consume_power_handler | 1086 | .consume_power_handler = scic_sds_phy_default_consume_power_handler |
1331 | }, | 1087 | }, |
1332 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER] = { | 1088 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER] = { |
1333 | .event_handler = scic_sds_phy_starting_substate_await_sas_power_event_handler, | ||
1334 | .consume_power_handler = scic_sds_phy_starting_substate_await_sas_power_consume_power_handler | 1089 | .consume_power_handler = scic_sds_phy_starting_substate_await_sas_power_consume_power_handler |
1335 | }, | 1090 | }, |
1336 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER] = { | 1091 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER] = { |
1337 | .event_handler = scic_sds_phy_starting_substate_await_sata_power_event_handler, | ||
1338 | .consume_power_handler = scic_sds_phy_starting_substate_await_sata_power_consume_power_handler | 1092 | .consume_power_handler = scic_sds_phy_starting_substate_await_sata_power_consume_power_handler |
1339 | }, | 1093 | }, |
1340 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN] = { | 1094 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN] = { |
1341 | .event_handler = scic_sds_phy_starting_substate_await_sata_phy_event_handler, | ||
1342 | .consume_power_handler = scic_sds_phy_default_consume_power_handler | 1095 | .consume_power_handler = scic_sds_phy_default_consume_power_handler |
1343 | }, | 1096 | }, |
1344 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN] = { | 1097 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN] = { |
1345 | .event_handler = scic_sds_phy_starting_substate_await_sata_speed_event_handler, | ||
1346 | .consume_power_handler = scic_sds_phy_default_consume_power_handler | 1098 | .consume_power_handler = scic_sds_phy_default_consume_power_handler |
1347 | }, | 1099 | }, |
1348 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF] = { | 1100 | [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF] = { |
1349 | .event_handler = scic_sds_phy_starting_substate_await_sig_fis_event_handler, | ||
1350 | .consume_power_handler = scic_sds_phy_default_consume_power_handler | 1101 | .consume_power_handler = scic_sds_phy_default_consume_power_handler |
1351 | }, | 1102 | }, |
1352 | [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL] = { | 1103 | [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL] = { |
1353 | .event_handler = scic_sds_phy_default_event_handler, | ||
1354 | .consume_power_handler = scic_sds_phy_default_consume_power_handler | 1104 | .consume_power_handler = scic_sds_phy_default_consume_power_handler |
1355 | }, | 1105 | }, |
1356 | [SCI_BASE_PHY_STATE_READY] = { | 1106 | [SCI_BASE_PHY_STATE_READY] = { |
1357 | .event_handler = scic_sds_phy_ready_state_event_handler, | ||
1358 | .consume_power_handler = scic_sds_phy_default_consume_power_handler | 1107 | .consume_power_handler = scic_sds_phy_default_consume_power_handler |
1359 | }, | 1108 | }, |
1360 | [SCI_BASE_PHY_STATE_RESETTING] = { | 1109 | [SCI_BASE_PHY_STATE_RESETTING] = { |
1361 | .event_handler = scic_sds_phy_resetting_state_event_handler, | ||
1362 | .consume_power_handler = scic_sds_phy_default_consume_power_handler | 1110 | .consume_power_handler = scic_sds_phy_default_consume_power_handler |
1363 | }, | 1111 | }, |
1364 | [SCI_BASE_PHY_STATE_FINAL] = { | 1112 | [SCI_BASE_PHY_STATE_FINAL] = { |
1365 | .event_handler = scic_sds_phy_default_event_handler, | ||
1366 | .consume_power_handler = scic_sds_phy_default_consume_power_handler | 1113 | .consume_power_handler = scic_sds_phy_default_consume_power_handler |
1367 | } | 1114 | } |
1368 | }; | 1115 | }; |
diff --git a/drivers/scsi/isci/phy.h b/drivers/scsi/isci/phy.h index e7f4b71b1158..a95c74e58695 100644 --- a/drivers/scsi/isci/phy.h +++ b/drivers/scsi/isci/phy.h | |||
@@ -512,11 +512,6 @@ typedef enum sci_status (*scic_sds_phy_power_handler_t)(struct scic_sds_phy *); | |||
512 | 512 | ||
513 | struct scic_sds_phy_state_handler { | 513 | struct scic_sds_phy_state_handler { |
514 | /** | 514 | /** |
515 | * The state handler for events received from the SCU hardware. | ||
516 | */ | ||
517 | scic_sds_phy_event_handler_t event_handler; | ||
518 | |||
519 | /** | ||
520 | * The state handler for staggered spinup. | 515 | * The state handler for staggered spinup. |
521 | */ | 516 | */ |
522 | scic_sds_phy_power_handler_t consume_power_handler; | 517 | scic_sds_phy_power_handler_t consume_power_handler; |