diff options
Diffstat (limited to 'drivers/scsi/isci/port.c')
-rw-r--r-- | drivers/scsi/isci/port.c | 241 |
1 files changed, 72 insertions, 169 deletions
diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c index d58001cb0bcf..61ba37da437d 100644 --- a/drivers/scsi/isci/port.c +++ b/drivers/scsi/isci/port.c | |||
@@ -929,36 +929,6 @@ bool scic_sds_port_link_detected( | |||
929 | } | 929 | } |
930 | 930 | ||
931 | /** | 931 | /** |
932 | * This method is the entry point for the phy to inform the port that it is now | ||
933 | * in a ready state | ||
934 | * @sci_port: | ||
935 | * | ||
936 | * | ||
937 | */ | ||
938 | void scic_sds_port_link_up( | ||
939 | struct scic_sds_port *sci_port, | ||
940 | struct scic_sds_phy *sci_phy) | ||
941 | { | ||
942 | sci_phy->is_in_link_training = false; | ||
943 | |||
944 | sci_port->state_handlers->link_up_handler(sci_port, sci_phy); | ||
945 | } | ||
946 | |||
947 | /** | ||
948 | * This method is the entry point for the phy to inform the port that it is no | ||
949 | * longer in a ready state | ||
950 | * @sci_port: | ||
951 | * | ||
952 | * | ||
953 | */ | ||
954 | void scic_sds_port_link_down( | ||
955 | struct scic_sds_port *sci_port, | ||
956 | struct scic_sds_phy *sci_phy) | ||
957 | { | ||
958 | sci_port->state_handlers->link_down_handler(sci_port, sci_phy); | ||
959 | } | ||
960 | |||
961 | /** | ||
962 | * This method is called to start an IO request on this port. | 932 | * This method is called to start an IO request on this port. |
963 | * @sci_port: | 933 | * @sci_port: |
964 | * @sci_dev: | 934 | * @sci_dev: |
@@ -1135,29 +1105,6 @@ static enum sci_status scic_sds_port_ready_substate_complete_io_handler( | |||
1135 | return SCI_SUCCESS; | 1105 | return SCI_SUCCESS; |
1136 | } | 1106 | } |
1137 | 1107 | ||
1138 | /** | ||
1139 | * | ||
1140 | * @sci_port: This is the struct scic_sds_port object that which has a phy that has | ||
1141 | * gone link up. | ||
1142 | * @sci_phy: This is the struct scic_sds_phy object that has gone link up. | ||
1143 | * | ||
1144 | * This method is the ready waiting substate link up handler for the | ||
1145 | * struct scic_sds_port object. This methos will report the link up condition for | ||
1146 | * this port and will transition to the ready operational substate. none | ||
1147 | */ | ||
1148 | static void scic_sds_port_ready_waiting_substate_link_up_handler( | ||
1149 | struct scic_sds_port *sci_port, | ||
1150 | struct scic_sds_phy *sci_phy) | ||
1151 | { | ||
1152 | /* | ||
1153 | * Since this is the first phy going link up for the port we can just enable | ||
1154 | * it and continue. */ | ||
1155 | scic_sds_port_activate_phy(sci_port, sci_phy, true); | ||
1156 | |||
1157 | port_state_machine_change(sci_port, | ||
1158 | SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL); | ||
1159 | } | ||
1160 | |||
1161 | /* | 1108 | /* |
1162 | * This method is the ready waiting substate start io handler for the | 1109 | * This method is the ready waiting substate start io handler for the |
1163 | * struct scic_sds_port object. The port object can not accept new requests so the | 1110 | * struct scic_sds_port object. The port object can not accept new requests so the |
@@ -1171,49 +1118,6 @@ static enum sci_status scic_sds_port_ready_waiting_substate_start_io_handler( | |||
1171 | return SCI_FAILURE_INVALID_STATE; | 1118 | return SCI_FAILURE_INVALID_STATE; |
1172 | } | 1119 | } |
1173 | 1120 | ||
1174 | /** | ||
1175 | * scic_sds_port_ready_operational_substate_link_up_handler() - | ||
1176 | * @sci_port: This is the struct scic_sds_port object that which has a phy that has | ||
1177 | * gone link up. | ||
1178 | * @sci_phy: This is the struct scic_sds_phy object that has gone link up. | ||
1179 | * | ||
1180 | * This method is the ready operational substate link up handler for the | ||
1181 | * struct scic_sds_port object. This function notifies the SCI User that the phy has | ||
1182 | * gone link up. none | ||
1183 | */ | ||
1184 | static void scic_sds_port_ready_operational_substate_link_up_handler( | ||
1185 | struct scic_sds_port *sci_port, | ||
1186 | struct scic_sds_phy *sci_phy) | ||
1187 | { | ||
1188 | scic_sds_port_general_link_up_handler(sci_port, sci_phy, true); | ||
1189 | } | ||
1190 | |||
1191 | /** | ||
1192 | * scic_sds_port_ready_operational_substate_link_down_handler() - | ||
1193 | * @sci_port: This is the struct scic_sds_port object that which has a phy that has | ||
1194 | * gone link down. | ||
1195 | * @sci_phy: This is the struct scic_sds_phy object that has gone link down. | ||
1196 | * | ||
1197 | * This method is the ready operational substate link down handler for the | ||
1198 | * struct scic_sds_port object. This function notifies the SCI User that the phy has | ||
1199 | * gone link down and if this is the last phy in the port the port will change | ||
1200 | * state to the ready waiting substate. none | ||
1201 | */ | ||
1202 | static void scic_sds_port_ready_operational_substate_link_down_handler( | ||
1203 | struct scic_sds_port *sci_port, | ||
1204 | struct scic_sds_phy *sci_phy) | ||
1205 | { | ||
1206 | scic_sds_port_deactivate_phy(sci_port, sci_phy, true); | ||
1207 | |||
1208 | /* | ||
1209 | * If there are no active phys left in the port, then transition | ||
1210 | * the port to the WAITING state until such time as a phy goes | ||
1211 | * link up. */ | ||
1212 | if (sci_port->active_phy_mask == 0) | ||
1213 | port_state_machine_change(sci_port, | ||
1214 | SCIC_SDS_PORT_READY_SUBSTATE_WAITING); | ||
1215 | } | ||
1216 | |||
1217 | /* | 1121 | /* |
1218 | * This method is the ready operational substate start io handler for the | 1122 | * This method is the ready operational substate start io handler for the |
1219 | * struct scic_sds_port object. This function incremetns the outstanding request | 1123 | * struct scic_sds_port object. This function incremetns the outstanding request |
@@ -1262,18 +1166,6 @@ static enum sci_status default_port_handler(struct scic_sds_port *sci_port, | |||
1262 | return SCI_FAILURE_INVALID_STATE; | 1166 | return SCI_FAILURE_INVALID_STATE; |
1263 | } | 1167 | } |
1264 | 1168 | ||
1265 | static void scic_sds_port_default_link_up_handler(struct scic_sds_port *sci_port, | ||
1266 | struct scic_sds_phy *sci_phy) | ||
1267 | { | ||
1268 | default_port_handler(sci_port, __func__); | ||
1269 | } | ||
1270 | |||
1271 | static void scic_sds_port_default_link_down_handler(struct scic_sds_port *sci_port, | ||
1272 | struct scic_sds_phy *sci_phy) | ||
1273 | { | ||
1274 | default_port_handler(sci_port, __func__); | ||
1275 | } | ||
1276 | |||
1277 | static enum sci_status scic_sds_port_default_start_io_handler(struct scic_sds_port *sci_port, | 1169 | static enum sci_status scic_sds_port_default_start_io_handler(struct scic_sds_port *sci_port, |
1278 | struct scic_sds_remote_device *sci_dev, | 1170 | struct scic_sds_remote_device *sci_dev, |
1279 | struct scic_sds_request *sci_req) | 1171 | struct scic_sds_request *sci_req) |
@@ -1592,51 +1484,6 @@ static enum sci_status scic_sds_port_stopping_state_complete_io_handler( | |||
1592 | return SCI_SUCCESS; | 1484 | return SCI_SUCCESS; |
1593 | } | 1485 | } |
1594 | 1486 | ||
1595 | /* | ||
1596 | * **************************************************************************** | ||
1597 | * * RESETTING STATE HANDLERS | ||
1598 | * **************************************************************************** */ | ||
1599 | |||
1600 | /* | ||
1601 | * This method will transition a failed port to its ready state. The port | ||
1602 | * failed because a hard reset request timed out but at some time later one or | ||
1603 | * more phys in the port became ready. enum sci_status SCI_SUCCESS | ||
1604 | */ | ||
1605 | static void scic_sds_port_reset_state_link_up_handler( | ||
1606 | struct scic_sds_port *port, | ||
1607 | struct scic_sds_phy *phy) | ||
1608 | { | ||
1609 | /* | ||
1610 | * / @todo We should make sure that the phy that has gone link up is the same | ||
1611 | * / one on which we sent the reset. It is possible that the phy on | ||
1612 | * / which we sent the reset is not the one that has gone link up and we | ||
1613 | * / want to make sure that phy being reset comes back. Consider the | ||
1614 | * / case where a reset is sent but before the hardware processes the | ||
1615 | * / reset it get a link up on the port because of a hot plug event. | ||
1616 | * / because of the reset request this phy will go link down almost | ||
1617 | * / immediately. */ | ||
1618 | |||
1619 | /* | ||
1620 | * In the resetting state we don't notify the user regarding | ||
1621 | * link up and link down notifications. */ | ||
1622 | scic_sds_port_general_link_up_handler(port, phy, false); | ||
1623 | } | ||
1624 | |||
1625 | /* | ||
1626 | * This method process link down notifications that occur during a port reset | ||
1627 | * operation. Link downs can occur during the reset operation. enum sci_status | ||
1628 | * SCI_SUCCESS | ||
1629 | */ | ||
1630 | static void scic_sds_port_reset_state_link_down_handler( | ||
1631 | struct scic_sds_port *port, | ||
1632 | struct scic_sds_phy *phy) | ||
1633 | { | ||
1634 | /* | ||
1635 | * In the resetting state we don't notify the user regarding | ||
1636 | * link up and link down notifications. */ | ||
1637 | scic_sds_port_deactivate_phy(port, phy, false); | ||
1638 | } | ||
1639 | |||
1640 | enum sci_status scic_sds_port_start(struct scic_sds_port *sci_port) | 1487 | enum sci_status scic_sds_port_start(struct scic_sds_port *sci_port) |
1641 | { | 1488 | { |
1642 | struct scic_sds_controller *scic = sci_port->owning_controller; | 1489 | struct scic_sds_controller *scic = sci_port->owning_controller; |
@@ -1890,7 +1737,79 @@ enum sci_status scic_sds_port_remove_phy(struct scic_sds_port *sci_port, | |||
1890 | */ | 1737 | */ |
1891 | port_state_machine_change(sci_port, | 1738 | port_state_machine_change(sci_port, |
1892 | SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING); | 1739 | SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING); |
1740 | return SCI_SUCCESS; | ||
1741 | default: | ||
1742 | dev_warn(sciport_to_dev(sci_port), | ||
1743 | "%s: in wrong state: %d\n", __func__, state); | ||
1744 | return SCI_FAILURE_INVALID_STATE; | ||
1745 | } | ||
1746 | } | ||
1893 | 1747 | ||
1748 | enum sci_status scic_sds_port_link_up(struct scic_sds_port *sci_port, | ||
1749 | struct scic_sds_phy *sci_phy) | ||
1750 | { | ||
1751 | enum scic_sds_port_states state; | ||
1752 | |||
1753 | state = sci_port->state_machine.current_state_id; | ||
1754 | switch (state) { | ||
1755 | case SCIC_SDS_PORT_READY_SUBSTATE_WAITING: | ||
1756 | /* Since this is the first phy going link up for the port we | ||
1757 | * can just enable it and continue | ||
1758 | */ | ||
1759 | scic_sds_port_activate_phy(sci_port, sci_phy, true); | ||
1760 | |||
1761 | port_state_machine_change(sci_port, | ||
1762 | SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL); | ||
1763 | return SCI_SUCCESS; | ||
1764 | case SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL: | ||
1765 | scic_sds_port_general_link_up_handler(sci_port, sci_phy, true); | ||
1766 | return SCI_SUCCESS; | ||
1767 | case SCI_BASE_PORT_STATE_RESETTING: | ||
1768 | /* TODO We should make sure that the phy that has gone | ||
1769 | * link up is the same one on which we sent the reset. It is | ||
1770 | * possible that the phy on which we sent the reset is not the | ||
1771 | * one that has gone link up and we want to make sure that | ||
1772 | * phy being reset comes back. Consider the case where a | ||
1773 | * reset is sent but before the hardware processes the reset it | ||
1774 | * get a link up on the port because of a hot plug event. | ||
1775 | * because of the reset request this phy will go link down | ||
1776 | * almost immediately. | ||
1777 | */ | ||
1778 | |||
1779 | /* In the resetting state we don't notify the user regarding | ||
1780 | * link up and link down notifications. | ||
1781 | */ | ||
1782 | scic_sds_port_general_link_up_handler(sci_port, sci_phy, false); | ||
1783 | return SCI_SUCCESS; | ||
1784 | default: | ||
1785 | dev_warn(sciport_to_dev(sci_port), | ||
1786 | "%s: in wrong state: %d\n", __func__, state); | ||
1787 | return SCI_FAILURE_INVALID_STATE; | ||
1788 | } | ||
1789 | } | ||
1790 | |||
1791 | enum sci_status scic_sds_port_link_down(struct scic_sds_port *sci_port, | ||
1792 | struct scic_sds_phy *sci_phy) | ||
1793 | { | ||
1794 | enum scic_sds_port_states state; | ||
1795 | |||
1796 | state = sci_port->state_machine.current_state_id; | ||
1797 | switch (state) { | ||
1798 | case SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL: | ||
1799 | scic_sds_port_deactivate_phy(sci_port, sci_phy, true); | ||
1800 | |||
1801 | /* If there are no active phys left in the port, then | ||
1802 | * transition the port to the WAITING state until such time | ||
1803 | * as a phy goes link up | ||
1804 | */ | ||
1805 | if (sci_port->active_phy_mask == 0) | ||
1806 | port_state_machine_change(sci_port, | ||
1807 | SCIC_SDS_PORT_READY_SUBSTATE_WAITING); | ||
1808 | return SCI_SUCCESS; | ||
1809 | case SCI_BASE_PORT_STATE_RESETTING: | ||
1810 | /* In the resetting state we don't notify the user regarding | ||
1811 | * link up and link down notifications. */ | ||
1812 | scic_sds_port_deactivate_phy(sci_port, sci_phy, false); | ||
1894 | return SCI_SUCCESS; | 1813 | return SCI_SUCCESS; |
1895 | default: | 1814 | default: |
1896 | dev_warn(sciport_to_dev(sci_port), | 1815 | dev_warn(sciport_to_dev(sci_port), |
@@ -1901,50 +1820,34 @@ enum sci_status scic_sds_port_remove_phy(struct scic_sds_port *sci_port, | |||
1901 | 1820 | ||
1902 | static struct scic_sds_port_state_handler scic_sds_port_state_handler_table[] = { | 1821 | static struct scic_sds_port_state_handler scic_sds_port_state_handler_table[] = { |
1903 | [SCI_BASE_PORT_STATE_STOPPED] = { | 1822 | [SCI_BASE_PORT_STATE_STOPPED] = { |
1904 | .link_up_handler = scic_sds_port_default_link_up_handler, | ||
1905 | .link_down_handler = scic_sds_port_default_link_down_handler, | ||
1906 | .start_io_handler = scic_sds_port_default_start_io_handler, | 1823 | .start_io_handler = scic_sds_port_default_start_io_handler, |
1907 | .complete_io_handler = scic_sds_port_default_complete_io_handler | 1824 | .complete_io_handler = scic_sds_port_default_complete_io_handler |
1908 | }, | 1825 | }, |
1909 | [SCI_BASE_PORT_STATE_STOPPING] = { | 1826 | [SCI_BASE_PORT_STATE_STOPPING] = { |
1910 | .link_up_handler = scic_sds_port_default_link_up_handler, | ||
1911 | .link_down_handler = scic_sds_port_default_link_down_handler, | ||
1912 | .start_io_handler = scic_sds_port_default_start_io_handler, | 1827 | .start_io_handler = scic_sds_port_default_start_io_handler, |
1913 | .complete_io_handler = scic_sds_port_stopping_state_complete_io_handler | 1828 | .complete_io_handler = scic_sds_port_stopping_state_complete_io_handler |
1914 | }, | 1829 | }, |
1915 | [SCI_BASE_PORT_STATE_READY] = { | 1830 | [SCI_BASE_PORT_STATE_READY] = { |
1916 | .link_up_handler = scic_sds_port_default_link_up_handler, | ||
1917 | .link_down_handler = scic_sds_port_default_link_down_handler, | ||
1918 | .start_io_handler = scic_sds_port_default_start_io_handler, | 1831 | .start_io_handler = scic_sds_port_default_start_io_handler, |
1919 | .complete_io_handler = scic_sds_port_general_complete_io_handler | 1832 | .complete_io_handler = scic_sds_port_general_complete_io_handler |
1920 | }, | 1833 | }, |
1921 | [SCIC_SDS_PORT_READY_SUBSTATE_WAITING] = { | 1834 | [SCIC_SDS_PORT_READY_SUBSTATE_WAITING] = { |
1922 | .link_up_handler = scic_sds_port_ready_waiting_substate_link_up_handler, | ||
1923 | .link_down_handler = scic_sds_port_default_link_down_handler, | ||
1924 | .start_io_handler = scic_sds_port_ready_waiting_substate_start_io_handler, | 1835 | .start_io_handler = scic_sds_port_ready_waiting_substate_start_io_handler, |
1925 | .complete_io_handler = scic_sds_port_ready_substate_complete_io_handler, | 1836 | .complete_io_handler = scic_sds_port_ready_substate_complete_io_handler, |
1926 | }, | 1837 | }, |
1927 | [SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL] = { | 1838 | [SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL] = { |
1928 | .link_up_handler = scic_sds_port_ready_operational_substate_link_up_handler, | ||
1929 | .link_down_handler = scic_sds_port_ready_operational_substate_link_down_handler, | ||
1930 | .start_io_handler = scic_sds_port_ready_operational_substate_start_io_handler, | 1839 | .start_io_handler = scic_sds_port_ready_operational_substate_start_io_handler, |
1931 | .complete_io_handler = scic_sds_port_ready_substate_complete_io_handler, | 1840 | .complete_io_handler = scic_sds_port_ready_substate_complete_io_handler, |
1932 | }, | 1841 | }, |
1933 | [SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING] = { | 1842 | [SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING] = { |
1934 | .link_up_handler = scic_sds_port_default_link_up_handler, | ||
1935 | .link_down_handler = scic_sds_port_default_link_down_handler, | ||
1936 | .start_io_handler = scic_sds_port_default_start_io_handler, | 1843 | .start_io_handler = scic_sds_port_default_start_io_handler, |
1937 | .complete_io_handler = scic_sds_port_ready_configuring_substate_complete_io_handler | 1844 | .complete_io_handler = scic_sds_port_ready_configuring_substate_complete_io_handler |
1938 | }, | 1845 | }, |
1939 | [SCI_BASE_PORT_STATE_RESETTING] = { | 1846 | [SCI_BASE_PORT_STATE_RESETTING] = { |
1940 | .link_up_handler = scic_sds_port_reset_state_link_up_handler, | ||
1941 | .link_down_handler = scic_sds_port_reset_state_link_down_handler, | ||
1942 | .start_io_handler = scic_sds_port_default_start_io_handler, | 1847 | .start_io_handler = scic_sds_port_default_start_io_handler, |
1943 | .complete_io_handler = scic_sds_port_general_complete_io_handler | 1848 | .complete_io_handler = scic_sds_port_general_complete_io_handler |
1944 | }, | 1849 | }, |
1945 | [SCI_BASE_PORT_STATE_FAILED] = { | 1850 | [SCI_BASE_PORT_STATE_FAILED] = { |
1946 | .link_up_handler = scic_sds_port_default_link_up_handler, | ||
1947 | .link_down_handler = scic_sds_port_default_link_down_handler, | ||
1948 | .start_io_handler = scic_sds_port_default_start_io_handler, | 1851 | .start_io_handler = scic_sds_port_default_start_io_handler, |
1949 | .complete_io_handler = scic_sds_port_general_complete_io_handler | 1852 | .complete_io_handler = scic_sds_port_general_complete_io_handler |
1950 | } | 1853 | } |