diff options
-rw-r--r-- | drivers/scsi/isci/core/scic_config_parameters.h | 3 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_controller.c | 271 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_controller.h | 30 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_port_configuration_agent.c | 2 | ||||
-rw-r--r-- | drivers/scsi/isci/firmware/create_fw.h | 7 | ||||
-rw-r--r-- | drivers/scsi/isci/probe_roms.h | 14 | ||||
-rw-r--r-- | firmware/isci/isci_firmware.bin.ihex | 4 |
7 files changed, 176 insertions, 155 deletions
diff --git a/drivers/scsi/isci/core/scic_config_parameters.h b/drivers/scsi/isci/core/scic_config_parameters.h index 5e1345daf014..f64f24fad5a3 100644 --- a/drivers/scsi/isci/core/scic_config_parameters.h +++ b/drivers/scsi/isci/core/scic_config_parameters.h | |||
@@ -224,6 +224,8 @@ union scic_user_parameters { | |||
224 | */ | 224 | */ |
225 | #define SCIC_SDS_PARM_PHY_MASK_MAX 0xF | 225 | #define SCIC_SDS_PARM_PHY_MASK_MAX 0xF |
226 | 226 | ||
227 | #define MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT 4 | ||
228 | |||
227 | /** | 229 | /** |
228 | * This structure/union specifies the various different OEM parameter sets | 230 | * This structure/union specifies the various different OEM parameter sets |
229 | * available. Each type is specific to a hardware controller version. | 231 | * available. Each type is specific to a hardware controller version. |
@@ -237,7 +239,6 @@ union scic_oem_parameters { | |||
237 | * 1. | 239 | * 1. |
238 | */ | 240 | */ |
239 | struct scic_sds_oem_params sds1; | 241 | struct scic_sds_oem_params sds1; |
240 | |||
241 | }; | 242 | }; |
242 | 243 | ||
243 | /** | 244 | /** |
diff --git a/drivers/scsi/isci/core/scic_sds_controller.c b/drivers/scsi/isci/core/scic_sds_controller.c index e7f3711b4afc..12b2ad5a28b0 100644 --- a/drivers/scsi/isci/core/scic_sds_controller.c +++ b/drivers/scsi/isci/core/scic_sds_controller.c | |||
@@ -293,6 +293,7 @@ void scic_sds_controller_initialize_power_control( | |||
293 | ); | 293 | ); |
294 | 294 | ||
295 | this_controller->power_control.phys_waiting = 0; | 295 | this_controller->power_control.phys_waiting = 0; |
296 | this_controller->power_control.phys_granted_power = 0; | ||
296 | } | 297 | } |
297 | 298 | ||
298 | /* --------------------------------------------------------------------------- */ | 299 | /* --------------------------------------------------------------------------- */ |
@@ -770,31 +771,6 @@ void scic_sds_controller_timeout_handler( | |||
770 | __func__); | 771 | __func__); |
771 | } | 772 | } |
772 | 773 | ||
773 | /** | ||
774 | * scic_sds_controller_get_port_configuration_mode | ||
775 | * @this_controller: This is the controller to use to determine if we are using | ||
776 | * manual or automatic port configuration. | ||
777 | * | ||
778 | * SCIC_PORT_CONFIGURATION_MODE | ||
779 | */ | ||
780 | enum SCIC_PORT_CONFIGURATION_MODE scic_sds_controller_get_port_configuration_mode( | ||
781 | struct scic_sds_controller *this_controller) | ||
782 | { | ||
783 | u32 index; | ||
784 | enum SCIC_PORT_CONFIGURATION_MODE mode; | ||
785 | |||
786 | mode = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE; | ||
787 | |||
788 | for (index = 0; index < SCI_MAX_PORTS; index++) { | ||
789 | if (this_controller->oem_parameters.sds1.ports[index].phy_mask != 0) { | ||
790 | mode = SCIC_PORT_MANUAL_CONFIGURATION_MODE; | ||
791 | break; | ||
792 | } | ||
793 | } | ||
794 | |||
795 | return mode; | ||
796 | } | ||
797 | |||
798 | enum sci_status scic_sds_controller_stop_ports(struct scic_sds_controller *scic) | 774 | enum sci_status scic_sds_controller_stop_ports(struct scic_sds_controller *scic) |
799 | { | 775 | { |
800 | u32 index; | 776 | u32 index; |
@@ -859,7 +835,7 @@ void scic_sds_controller_phy_timer_stop( | |||
859 | 835 | ||
860 | /** | 836 | /** |
861 | * This method is called internally by the controller object to start the next | 837 | * This method is called internally by the controller object to start the next |
862 | * phy on the controller. If all the phys have been starte, then this | 838 | * phy on the controller. If all the phys have been started, then this |
863 | * method will attempt to transition the controller to the READY state and | 839 | * method will attempt to transition the controller to the READY state and |
864 | * inform the user (scic_cb_controller_start_complete()). | 840 | * inform the user (scic_cb_controller_start_complete()). |
865 | * @this_controller: This parameter specifies the controller object for which | 841 | * @this_controller: This parameter specifies the controller object for which |
@@ -867,101 +843,88 @@ void scic_sds_controller_phy_timer_stop( | |||
867 | * | 843 | * |
868 | * enum sci_status | 844 | * enum sci_status |
869 | */ | 845 | */ |
870 | enum sci_status scic_sds_controller_start_next_phy( | 846 | enum sci_status scic_sds_controller_start_next_phy(struct scic_sds_controller *scic) |
871 | struct scic_sds_controller *this_controller) | ||
872 | { | 847 | { |
848 | struct scic_sds_oem_params *oem = &scic->oem_parameters.sds1; | ||
849 | struct scic_sds_phy *sci_phy; | ||
873 | enum sci_status status; | 850 | enum sci_status status; |
874 | 851 | ||
875 | status = SCI_SUCCESS; | 852 | status = SCI_SUCCESS; |
876 | 853 | ||
877 | if (this_controller->phy_startup_timer_pending == false) { | 854 | if (scic->phy_startup_timer_pending) |
878 | if (this_controller->next_phy_to_start == SCI_MAX_PHYS) { | 855 | return status; |
879 | bool is_controller_start_complete = true; | ||
880 | struct scic_sds_phy *the_phy; | ||
881 | u8 index; | ||
882 | 856 | ||
883 | for (index = 0; index < SCI_MAX_PHYS; index++) { | 857 | if (scic->next_phy_to_start >= SCI_MAX_PHYS) { |
884 | the_phy = &this_controller->phy_table[index]; | 858 | bool is_controller_start_complete = true; |
885 | 859 | u32 state; | |
886 | if (scic_sds_phy_get_port(the_phy) != NULL) { | 860 | u8 index; |
887 | /** | ||
888 | * The controller start operation is complete if and only | ||
889 | * if: | ||
890 | * - all links have been given an opportunity to start | ||
891 | * - have no indication of a connected device | ||
892 | * - have an indication of a connected device and it has | ||
893 | * finished the link training process. | ||
894 | */ | ||
895 | if ( | ||
896 | ( | ||
897 | (the_phy->is_in_link_training == false) | ||
898 | && (the_phy->parent.state_machine.current_state_id | ||
899 | == SCI_BASE_PHY_STATE_INITIAL) | ||
900 | ) | ||
901 | || ( | ||
902 | (the_phy->is_in_link_training == false) | ||
903 | && (the_phy->parent.state_machine.current_state_id | ||
904 | == SCI_BASE_PHY_STATE_STOPPED) | ||
905 | ) | ||
906 | || ( | ||
907 | (the_phy->is_in_link_training == true) | ||
908 | && (the_phy->parent.state_machine.current_state_id | ||
909 | == SCI_BASE_PHY_STATE_STARTING) | ||
910 | ) | ||
911 | ) { | ||
912 | is_controller_start_complete = false; | ||
913 | break; | ||
914 | } | ||
915 | } | ||
916 | } | ||
917 | 861 | ||
918 | /* | 862 | for (index = 0; index < SCI_MAX_PHYS; index++) { |
919 | * The controller has successfully finished the start process. | 863 | sci_phy = &scic->phy_table[index]; |
920 | * Inform the SCI Core user and transition to the READY state. */ | 864 | state = sci_phy->parent.state_machine.current_state_id; |
921 | if (is_controller_start_complete == true) { | 865 | |
922 | scic_sds_controller_transition_to_ready( | 866 | if (!scic_sds_phy_get_port(sci_phy)) |
923 | this_controller, SCI_SUCCESS | 867 | continue; |
924 | ); | 868 | |
925 | scic_sds_controller_phy_timer_stop(this_controller); | 869 | /* The controller start operation is complete iff: |
870 | * - all links have been given an opportunity to start | ||
871 | * - have no indication of a connected device | ||
872 | * - have an indication of a connected device and it has | ||
873 | * finished the link training process. | ||
874 | */ | ||
875 | if ((sci_phy->is_in_link_training == false && | ||
876 | state == SCI_BASE_PHY_STATE_INITIAL) || | ||
877 | (sci_phy->is_in_link_training == false && | ||
878 | state == SCI_BASE_PHY_STATE_STOPPED) || | ||
879 | (sci_phy->is_in_link_training == true && | ||
880 | state == SCI_BASE_PHY_STATE_STARTING)) { | ||
881 | is_controller_start_complete = false; | ||
882 | break; | ||
926 | } | 883 | } |
927 | } else { | 884 | } |
928 | struct scic_sds_phy *the_phy; | ||
929 | |||
930 | the_phy = &this_controller->phy_table[this_controller->next_phy_to_start]; | ||
931 | 885 | ||
932 | if ( | 886 | /* |
933 | scic_sds_controller_get_port_configuration_mode(this_controller) | 887 | * The controller has successfully finished the start process. |
934 | == SCIC_PORT_MANUAL_CONFIGURATION_MODE | 888 | * Inform the SCI Core user and transition to the READY state. */ |
935 | ) { | 889 | if (is_controller_start_complete == true) { |
936 | if (scic_sds_phy_get_port(the_phy) == NULL) { | 890 | scic_sds_controller_transition_to_ready(scic, SCI_SUCCESS); |
937 | this_controller->next_phy_to_start++; | 891 | scic_sds_controller_phy_timer_stop(scic); |
938 | 892 | } | |
939 | /* | 893 | } else { |
940 | * Caution recursion ahead be forwarned | 894 | sci_phy = &scic->phy_table[scic->next_phy_to_start]; |
941 | * | 895 | |
942 | * The PHY was never added to a PORT in MPC mode so start the next phy in sequence | 896 | if (oem->controller.mode_type == SCIC_PORT_MANUAL_CONFIGURATION_MODE) { |
943 | * This phy will never go link up and will not draw power the OEM parameters either | 897 | if (scic_sds_phy_get_port(sci_phy) == NULL) { |
944 | * configured the phy incorrectly for the PORT or it was never assigned to a PORT */ | 898 | scic->next_phy_to_start++; |
945 | return scic_sds_controller_start_next_phy(this_controller); | 899 | |
946 | } | 900 | /* Caution recursion ahead be forwarned |
901 | * | ||
902 | * The PHY was never added to a PORT in MPC mode | ||
903 | * so start the next phy in sequence This phy | ||
904 | * will never go link up and will not draw power | ||
905 | * the OEM parameters either configured the phy | ||
906 | * incorrectly for the PORT or it was never | ||
907 | * assigned to a PORT | ||
908 | */ | ||
909 | return scic_sds_controller_start_next_phy(scic); | ||
947 | } | 910 | } |
911 | } | ||
948 | 912 | ||
949 | status = scic_sds_phy_start(the_phy); | 913 | status = scic_sds_phy_start(sci_phy); |
950 | 914 | ||
951 | if (status == SCI_SUCCESS) { | 915 | if (status == SCI_SUCCESS) { |
952 | scic_sds_controller_phy_timer_start(this_controller); | 916 | scic_sds_controller_phy_timer_start(scic); |
953 | } else { | 917 | } else { |
954 | dev_warn(scic_to_dev(this_controller), | 918 | dev_warn(scic_to_dev(scic), |
955 | "%s: Controller stop operation failed " | 919 | "%s: Controller stop operation failed " |
956 | "to stop phy %d because of status " | 920 | "to stop phy %d because of status " |
957 | "%d.\n", | 921 | "%d.\n", |
958 | __func__, | 922 | __func__, |
959 | this_controller->phy_table[this_controller->next_phy_to_start].phy_index, | 923 | scic->phy_table[scic->next_phy_to_start].phy_index, |
960 | status); | 924 | status); |
961 | } | ||
962 | |||
963 | this_controller->next_phy_to_start++; | ||
964 | } | 925 | } |
926 | |||
927 | scic->next_phy_to_start++; | ||
965 | } | 928 | } |
966 | 929 | ||
967 | return status; | 930 | return status; |
@@ -1059,6 +1022,31 @@ static void scic_sds_controller_power_control_timer_start( | |||
1059 | } | 1022 | } |
1060 | 1023 | ||
1061 | /** | 1024 | /** |
1025 | * This method stops the power control timer for this controller object. | ||
1026 | * | ||
1027 | * @param scic | ||
1028 | */ | ||
1029 | void scic_sds_controller_power_control_timer_stop(struct scic_sds_controller *scic) | ||
1030 | { | ||
1031 | if (scic->power_control.timer_started) { | ||
1032 | isci_event_timer_stop(scic, scic->power_control.timer); | ||
1033 | scic->power_control.timer_started = false; | ||
1034 | } | ||
1035 | } | ||
1036 | |||
1037 | /** | ||
1038 | * This method stops and starts the power control timer for this controller object. | ||
1039 | * | ||
1040 | * @param scic | ||
1041 | */ | ||
1042 | void scic_sds_controller_power_control_timer_restart( | ||
1043 | struct scic_sds_controller *scic) | ||
1044 | { | ||
1045 | scic_sds_controller_power_control_timer_stop(scic); | ||
1046 | scic_sds_controller_power_control_timer_start(scic); | ||
1047 | } | ||
1048 | |||
1049 | /** | ||
1062 | * | 1050 | * |
1063 | * | 1051 | * |
1064 | * | 1052 | * |
@@ -1070,6 +1058,8 @@ static void scic_sds_controller_power_control_timer_handler( | |||
1070 | 1058 | ||
1071 | this_controller = (struct scic_sds_controller *)controller; | 1059 | this_controller = (struct scic_sds_controller *)controller; |
1072 | 1060 | ||
1061 | this_controller->power_control.phys_granted_power = 0; | ||
1062 | |||
1073 | if (this_controller->power_control.phys_waiting == 0) { | 1063 | if (this_controller->power_control.phys_waiting == 0) { |
1074 | this_controller->power_control.timer_started = false; | 1064 | this_controller->power_control.timer_started = false; |
1075 | } else { | 1065 | } else { |
@@ -1081,19 +1071,24 @@ static void scic_sds_controller_power_control_timer_handler( | |||
1081 | && (this_controller->power_control.phys_waiting != 0); | 1071 | && (this_controller->power_control.phys_waiting != 0); |
1082 | i++) { | 1072 | i++) { |
1083 | if (this_controller->power_control.requesters[i] != NULL) { | 1073 | if (this_controller->power_control.requesters[i] != NULL) { |
1084 | the_phy = this_controller->power_control.requesters[i]; | 1074 | if (this_controller->power_control.phys_granted_power < |
1085 | this_controller->power_control.requesters[i] = NULL; | 1075 | this_controller->oem_parameters.sds1.controller.max_concurrent_dev_spin_up) { |
1086 | this_controller->power_control.phys_waiting--; | 1076 | the_phy = this_controller->power_control.requesters[i]; |
1087 | break; | 1077 | this_controller->power_control.requesters[i] = NULL; |
1078 | this_controller->power_control.phys_waiting--; | ||
1079 | this_controller->power_control.phys_granted_power++; | ||
1080 | scic_sds_phy_consume_power_handler(the_phy); | ||
1081 | } else { | ||
1082 | break; | ||
1083 | } | ||
1088 | } | 1084 | } |
1089 | } | 1085 | } |
1090 | 1086 | ||
1091 | /* | 1087 | /* |
1092 | * It doesn't matter if the power list is empty, we need to start the | 1088 | * It doesn't matter if the power list is empty, we need to start the |
1093 | * timer in case another phy becomes ready. */ | 1089 | * timer in case another phy becomes ready. |
1090 | */ | ||
1094 | scic_sds_controller_power_control_timer_start(this_controller); | 1091 | scic_sds_controller_power_control_timer_start(this_controller); |
1095 | |||
1096 | scic_sds_phy_consume_power_handler(the_phy); | ||
1097 | } | 1092 | } |
1098 | } | 1093 | } |
1099 | 1094 | ||
@@ -1109,15 +1104,20 @@ void scic_sds_controller_power_control_queue_insert( | |||
1109 | { | 1104 | { |
1110 | BUG_ON(the_phy == NULL); | 1105 | BUG_ON(the_phy == NULL); |
1111 | 1106 | ||
1112 | if ( | 1107 | if (this_controller->power_control.phys_granted_power < |
1113 | (this_controller->power_control.timer_started) | 1108 | this_controller->oem_parameters.sds1.controller.max_concurrent_dev_spin_up) { |
1114 | && (this_controller->power_control.requesters[the_phy->phy_index] == NULL) | 1109 | this_controller->power_control.phys_granted_power++; |
1115 | ) { | 1110 | scic_sds_phy_consume_power_handler(the_phy); |
1111 | |||
1112 | /* | ||
1113 | * stop and start the power_control timer. When the timer fires, the | ||
1114 | * no_of_phys_granted_power will be set to 0 | ||
1115 | */ | ||
1116 | scic_sds_controller_power_control_timer_restart(this_controller); | ||
1117 | } else { | ||
1118 | /* Add the phy in the waiting list */ | ||
1116 | this_controller->power_control.requesters[the_phy->phy_index] = the_phy; | 1119 | this_controller->power_control.requesters[the_phy->phy_index] = the_phy; |
1117 | this_controller->power_control.phys_waiting++; | 1120 | this_controller->power_control.phys_waiting++; |
1118 | } else { | ||
1119 | scic_sds_controller_power_control_timer_start(this_controller); | ||
1120 | scic_sds_phy_consume_power_handler(the_phy); | ||
1121 | } | 1121 | } |
1122 | } | 1122 | } |
1123 | 1123 | ||
@@ -2021,7 +2021,7 @@ void scic_sds_controller_release_frame( | |||
2021 | * This method sets user parameters and OEM parameters to default values. | 2021 | * This method sets user parameters and OEM parameters to default values. |
2022 | * Users can override these values utilizing the scic_user_parameters_set() | 2022 | * Users can override these values utilizing the scic_user_parameters_set() |
2023 | * and scic_oem_parameters_set() methods. | 2023 | * and scic_oem_parameters_set() methods. |
2024 | * @controller: This parameter specifies the controller for which to set the | 2024 | * @scic: This parameter specifies the controller for which to set the |
2025 | * configuration parameters to their default values. | 2025 | * configuration parameters to their default values. |
2026 | * | 2026 | * |
2027 | */ | 2027 | */ |
@@ -2029,6 +2029,12 @@ static void scic_sds_controller_set_default_config_parameters(struct scic_sds_co | |||
2029 | { | 2029 | { |
2030 | u16 index; | 2030 | u16 index; |
2031 | 2031 | ||
2032 | /* Default to APC mode. */ | ||
2033 | scic->oem_parameters.sds1.controller.mode_type = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE; | ||
2034 | |||
2035 | /* Default to APC mode. */ | ||
2036 | scic->oem_parameters.sds1.controller.max_concurrent_dev_spin_up = 1; | ||
2037 | |||
2032 | /* Default to no SSC operation. */ | 2038 | /* Default to no SSC operation. */ |
2033 | scic->oem_parameters.sds1.controller.do_enable_ssc = false; | 2039 | scic->oem_parameters.sds1.controller.do_enable_ssc = false; |
2034 | 2040 | ||
@@ -2607,6 +2613,7 @@ enum sci_status scic_oem_parameters_set( | |||
2607 | == SCI_BASE_CONTROLLER_STATE_INITIALIZED) | 2613 | == SCI_BASE_CONTROLLER_STATE_INITIALIZED) |
2608 | ) { | 2614 | ) { |
2609 | u16 index; | 2615 | u16 index; |
2616 | u8 combined_phy_mask = 0; | ||
2610 | 2617 | ||
2611 | /* | 2618 | /* |
2612 | * Validate the oem parameters. If they are not legal, then | 2619 | * Validate the oem parameters. If they are not legal, then |
@@ -2626,6 +2633,24 @@ enum sci_status scic_oem_parameters_set( | |||
2626 | } | 2633 | } |
2627 | } | 2634 | } |
2628 | 2635 | ||
2636 | if (scic_parms->sds1.controller.mode_type == SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE) { | ||
2637 | for (index = 0; index < SCI_MAX_PHYS; index++) { | ||
2638 | if (scic_parms->sds1.ports[index].phy_mask != 0) | ||
2639 | return SCI_FAILURE_INVALID_PARAMETER_VALUE; | ||
2640 | } | ||
2641 | } else if (scic_parms->sds1.controller.mode_type == SCIC_PORT_MANUAL_CONFIGURATION_MODE) { | ||
2642 | for (index = 0; index < SCI_MAX_PHYS; index++) | ||
2643 | combined_phy_mask |= scic_parms->sds1.ports[index].phy_mask; | ||
2644 | |||
2645 | if (combined_phy_mask == 0) | ||
2646 | return SCI_FAILURE_INVALID_PARAMETER_VALUE; | ||
2647 | } else { | ||
2648 | return SCI_FAILURE_INVALID_PARAMETER_VALUE; | ||
2649 | } | ||
2650 | |||
2651 | if (scic_parms->sds1.controller.max_concurrent_dev_spin_up > MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT) | ||
2652 | return SCI_FAILURE_INVALID_PARAMETER_VALUE; | ||
2653 | |||
2629 | memcpy(&scic->oem_parameters, scic_parms, sizeof(*scic_parms)); | 2654 | memcpy(&scic->oem_parameters, scic_parms, sizeof(*scic_parms)); |
2630 | return SCI_SUCCESS; | 2655 | return SCI_SUCCESS; |
2631 | } | 2656 | } |
diff --git a/drivers/scsi/isci/core/scic_sds_controller.h b/drivers/scsi/isci/core/scic_sds_controller.h index 9b8e55d62910..6386a64896c0 100644 --- a/drivers/scsi/isci/core/scic_sds_controller.h +++ b/drivers/scsi/isci/core/scic_sds_controller.h | |||
@@ -122,23 +122,6 @@ enum SCIC_SDS_CONTROLLER_MEMORY_DESCRIPTORS { | |||
122 | 122 | ||
123 | 123 | ||
124 | /** | 124 | /** |
125 | * | ||
126 | * | ||
127 | * Allowed PORT configuration modes APC Automatic PORT configuration mode is | ||
128 | * defined by the OEM configuration parameters providing no PHY_MASK parameters | ||
129 | * for any PORT. i.e. There are no phys assigned to any of the ports at start. | ||
130 | * MPC Manual PORT configuration mode is defined by the OEM configuration | ||
131 | * parameters providing a PHY_MASK value for any PORT. It is assumed that any | ||
132 | * PORT with no PHY_MASK is an invalid port and not all PHYs must be assigned. | ||
133 | * A PORT_PHY mask that assigns just a single PHY to a port and no other PHYs | ||
134 | * being assigned is sufficient to declare manual PORT configuration. | ||
135 | */ | ||
136 | enum SCIC_PORT_CONFIGURATION_MODE { | ||
137 | SCIC_PORT_MANUAL_CONFIGURATION_MODE, | ||
138 | SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE | ||
139 | }; | ||
140 | |||
141 | /** | ||
142 | * struct scic_power_control - | 125 | * struct scic_power_control - |
143 | * | 126 | * |
144 | * This structure defines the fields for managing power control for direct | 127 | * This structure defines the fields for managing power control for direct |
@@ -164,6 +147,11 @@ struct scic_power_control { | |||
164 | u8 phys_waiting; | 147 | u8 phys_waiting; |
165 | 148 | ||
166 | /** | 149 | /** |
150 | * This field is used to keep track of how many phys have been granted to consume power | ||
151 | */ | ||
152 | u8 phys_granted_power; | ||
153 | |||
154 | /** | ||
167 | * This field is an array of phys that we are waiting on. The phys are direct | 155 | * This field is an array of phys that we are waiting on. The phys are direct |
168 | * mapped into requesters via struct scic_sds_phy.phy_index | 156 | * mapped into requesters via struct scic_sds_phy.phy_index |
169 | */ | 157 | */ |
@@ -560,14 +548,6 @@ u32 scic_sds_controller_get_object_size(void); | |||
560 | 548 | ||
561 | /* --------------------------------------------------------------------------- */ | 549 | /* --------------------------------------------------------------------------- */ |
562 | 550 | ||
563 | |||
564 | /* --------------------------------------------------------------------------- */ | ||
565 | |||
566 | enum SCIC_PORT_CONFIGURATION_MODE scic_sds_controller_get_port_configuration_mode( | ||
567 | struct scic_sds_controller *this_controller); | ||
568 | |||
569 | /* --------------------------------------------------------------------------- */ | ||
570 | |||
571 | void scic_sds_controller_post_request( | 551 | void scic_sds_controller_post_request( |
572 | struct scic_sds_controller *this_controller, | 552 | struct scic_sds_controller *this_controller, |
573 | u32 request); | 553 | u32 request); |
diff --git a/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c b/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c index e26a4e69b3ac..7c9521049ae7 100644 --- a/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c +++ b/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c | |||
@@ -822,7 +822,7 @@ enum sci_status scic_sds_port_configuration_agent_initialize( | |||
822 | enum sci_status status = SCI_SUCCESS; | 822 | enum sci_status status = SCI_SUCCESS; |
823 | enum SCIC_PORT_CONFIGURATION_MODE mode; | 823 | enum SCIC_PORT_CONFIGURATION_MODE mode; |
824 | 824 | ||
825 | mode = scic_sds_controller_get_port_configuration_mode(controller); | 825 | mode = controller->oem_parameters.sds1.controller.mode_type; |
826 | 826 | ||
827 | if (mode == SCIC_PORT_MANUAL_CONFIGURATION_MODE) { | 827 | if (mode == SCIC_PORT_MANUAL_CONFIGURATION_MODE) { |
828 | status = scic_sds_mpc_agent_validate_phy_configuration(controller, port_agent); | 828 | status = scic_sds_mpc_agent_validate_phy_configuration(controller, port_agent); |
diff --git a/drivers/scsi/isci/firmware/create_fw.h b/drivers/scsi/isci/firmware/create_fw.h index bedbe4fad181..788a8de0c2bc 100644 --- a/drivers/scsi/isci/firmware/create_fw.h +++ b/drivers/scsi/isci/firmware/create_fw.h | |||
@@ -1,5 +1,6 @@ | |||
1 | #ifndef _CREATE_FW_H_ | 1 | #ifndef _CREATE_FW_H_ |
2 | #define _CREATE_FW_H_ | 2 | #define _CREATE_FW_H_ |
3 | #include "../probe_roms.h" | ||
3 | 4 | ||
4 | 5 | ||
5 | /* we are configuring for 2 SCUs */ | 6 | /* we are configuring for 2 SCUs */ |
@@ -24,16 +25,16 @@ static const int num_elements = 2; | |||
24 | * if there is a port/phy on which you do not wish to override the default | 25 | * if there is a port/phy on which you do not wish to override the default |
25 | * values, use the value assigned to UNINIT_PARAM (255). | 26 | * values, use the value assigned to UNINIT_PARAM (255). |
26 | */ | 27 | */ |
28 | /* discovery mode type (port auto config mode by default ) */ | ||
27 | #ifdef MPC | 29 | #ifdef MPC |
30 | static const int mode_type = SCIC_PORT_MANUAL_CONFIGURATION_MODE; | ||
28 | static const __u8 phy_mask[2][4] = { {1, 2, 4, 8}, | 31 | static const __u8 phy_mask[2][4] = { {1, 2, 4, 8}, |
29 | {1, 2, 4, 8} }; | 32 | {1, 2, 4, 8} }; |
30 | #else /* APC (default) */ | 33 | #else /* APC (default) */ |
34 | static const int mode_type = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE; | ||
31 | static const __u8 phy_mask[2][4]; | 35 | static const __u8 phy_mask[2][4]; |
32 | #endif | 36 | #endif |
33 | 37 | ||
34 | /* discovery mode type (port auto config mode by default ) */ | ||
35 | static const int mode_type; | ||
36 | |||
37 | /* Maximum number of concurrent device spin up */ | 38 | /* Maximum number of concurrent device spin up */ |
38 | static const int max_num_concurrent_dev_spin_up = 1; | 39 | static const int max_num_concurrent_dev_spin_up = 1; |
39 | 40 | ||
diff --git a/drivers/scsi/isci/probe_roms.h b/drivers/scsi/isci/probe_roms.h index 96d8b9212457..69526ffa8474 100644 --- a/drivers/scsi/isci/probe_roms.h +++ b/drivers/scsi/isci/probe_roms.h | |||
@@ -86,6 +86,20 @@ struct isci_orom *isci_get_efi_var(struct pci_dev *pdev); | |||
86 | #define ISCI_EFI_ATTRIBUTES 0 | 86 | #define ISCI_EFI_ATTRIBUTES 0 |
87 | #define ISCI_EFI_VAR_NAME "isci_oemb" | 87 | #define ISCI_EFI_VAR_NAME "isci_oemb" |
88 | 88 | ||
89 | /* Allowed PORT configuration modes APC Automatic PORT configuration mode is | ||
90 | * defined by the OEM configuration parameters providing no PHY_MASK parameters | ||
91 | * for any PORT. i.e. There are no phys assigned to any of the ports at start. | ||
92 | * MPC Manual PORT configuration mode is defined by the OEM configuration | ||
93 | * parameters providing a PHY_MASK value for any PORT. It is assumed that any | ||
94 | * PORT with no PHY_MASK is an invalid port and not all PHYs must be assigned. | ||
95 | * A PORT_PHY mask that assigns just a single PHY to a port and no other PHYs | ||
96 | * being assigned is sufficient to declare manual PORT configuration. | ||
97 | */ | ||
98 | enum SCIC_PORT_CONFIGURATION_MODE { | ||
99 | SCIC_PORT_MANUAL_CONFIGURATION_MODE = 0, | ||
100 | SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE = 1 | ||
101 | }; | ||
102 | |||
89 | struct sci_bios_oem_param_block_hdr { | 103 | struct sci_bios_oem_param_block_hdr { |
90 | uint8_t signature[ISCI_ROM_SIG_SIZE]; | 104 | uint8_t signature[ISCI_ROM_SIG_SIZE]; |
91 | uint16_t total_block_length; | 105 | uint16_t total_block_length; |
diff --git a/firmware/isci/isci_firmware.bin.ihex b/firmware/isci/isci_firmware.bin.ihex index 7f12b39e7910..b1bb5cf4499c 100644 --- a/firmware/isci/isci_firmware.bin.ihex +++ b/firmware/isci/isci_firmware.bin.ihex | |||
@@ -1,11 +1,11 @@ | |||
1 | :10000000495343554F454D42E70017100002000089 | 1 | :10000000495343554F454D42E70017100002000089 |
2 | :10001000000000000000000001000000000000FFE0 | 2 | :10001000000000000000000101000000000000FFDF |
3 | :10002000FFCF5F000000F0000000000000000000B3 | 3 | :10002000FFCF5F000000F0000000000000000000B3 |
4 | :1000300000000000000000FFFFCF5F000000F100A3 | 4 | :1000300000000000000000FFFFCF5F000000F100A3 |
5 | :10004000000000000000000000000000000000FFB1 | 5 | :10004000000000000000000000000000000000FFB1 |
6 | :10005000FFCF5F000000F200000000000000000081 | 6 | :10005000FFCF5F000000F200000000000000000081 |
7 | :1000600000000000000000FFFFCF5F000000F30071 | 7 | :1000600000000000000000FFFFCF5F000000F30071 |
8 | :100070000000000000000000000000000000000080 | 8 | :10007000000000000000000000000000000000017F |
9 | :1000800001000000000000FFFFCF5F000000F4004F | 9 | :1000800001000000000000FFFFCF5F000000F4004F |
10 | :10009000000000000000000000000000000000FF61 | 10 | :10009000000000000000000000000000000000FF61 |
11 | :1000A000FFCF5F000000F50000000000000000002E | 11 | :1000A000FFCF5F000000F50000000000000000002E |