aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/port.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/isci/port.c')
-rw-r--r--drivers/scsi/isci/port.c409
1 files changed, 189 insertions, 220 deletions
diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c
index e386066825b2..2ea3d0fe091d 100644
--- a/drivers/scsi/isci/port.c
+++ b/drivers/scsi/isci/port.c
@@ -61,6 +61,8 @@
61#define SCIC_SDS_PORT_HARD_RESET_TIMEOUT (1000) 61#define SCIC_SDS_PORT_HARD_RESET_TIMEOUT (1000)
62#define SCU_DUMMY_INDEX (0xFFFF) 62#define SCU_DUMMY_INDEX (0xFFFF)
63 63
64static struct scic_sds_port_state_handler scic_sds_port_state_handler_table[];
65
64static void isci_port_change_state(struct isci_port *iport, enum isci_status status) 66static void isci_port_change_state(struct isci_port *iport, enum isci_status status)
65{ 67{
66 unsigned long flags; 68 unsigned long flags;
@@ -856,6 +858,40 @@ static void scic_sds_port_invalid_link_up(struct scic_sds_port *sci_port,
856 } 858 }
857} 859}
858 860
861static bool is_port_ready_state(enum scic_sds_port_states state)
862{
863 switch (state) {
864 case SCI_BASE_PORT_STATE_READY:
865 case SCIC_SDS_PORT_READY_SUBSTATE_WAITING:
866 case SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL:
867 case SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING:
868 return true;
869 default:
870 return false;
871 }
872}
873
874/* flag dummy rnc hanling when exiting a ready state */
875static void port_state_machine_change(struct scic_sds_port *sci_port,
876 enum scic_sds_port_states state)
877{
878 struct sci_base_state_machine *sm = &sci_port->state_machine;
879 enum scic_sds_port_states old_state = sm->current_state_id;
880
881 if (is_port_ready_state(old_state) && !is_port_ready_state(state))
882 sci_port->ready_exit = true;
883
884 sci_base_state_machine_change_state(sm, state);
885 sci_port->ready_exit = false;
886}
887
888static void port_state_machine_stop(struct scic_sds_port *sci_port)
889{
890 sci_port->ready_exit = true;
891 sci_base_state_machine_stop(&sci_port->state_machine);
892 sci_port->ready_exit = false;
893}
894
859/** 895/**
860 * scic_sds_port_general_link_up_handler - phy can be assigned to port? 896 * scic_sds_port_general_link_up_handler - phy can be assigned to port?
861 * @sci_port: scic_sds_port object for which has a phy that has gone link up. 897 * @sci_port: scic_sds_port object for which has a phy that has gone link up.
@@ -891,7 +927,7 @@ static void scic_sds_port_general_link_up_handler(struct scic_sds_port *sci_port
891 927
892 scic_sds_port_activate_phy(sci_port, sci_phy, do_notify_user); 928 scic_sds_port_activate_phy(sci_port, sci_phy, do_notify_user);
893 if (sm->current_state_id == SCI_BASE_PORT_STATE_RESETTING) 929 if (sm->current_state_id == SCI_BASE_PORT_STATE_RESETTING)
894 sci_base_state_machine_change_state(sm, SCI_BASE_PORT_STATE_READY); 930 port_state_machine_change(sci_port, SCI_BASE_PORT_STATE_READY);
895 } else 931 } else
896 scic_sds_port_invalid_link_up(sci_port, sci_phy); 932 scic_sds_port_invalid_link_up(sci_port, sci_phy);
897} 933}
@@ -1025,46 +1061,33 @@ static void scic_sds_port_timeout_handler(void *port)
1025 struct scic_sds_port *sci_port = port; 1061 struct scic_sds_port *sci_port = port;
1026 u32 current_state; 1062 u32 current_state;
1027 1063
1028 current_state = sci_base_state_machine_get_state( 1064 current_state = sci_base_state_machine_get_state(&sci_port->state_machine);
1029 &sci_port->state_machine);
1030 1065
1031 if (current_state == SCI_BASE_PORT_STATE_RESETTING) { 1066 if (current_state == SCI_BASE_PORT_STATE_RESETTING) {
1032 /* 1067 /* if the port is still in the resetting state then the timeout
1033 * if the port is still in the resetting state then the 1068 * fired before the reset completed.
1034 * timeout fired before the reset completed.
1035 */ 1069 */
1036 sci_base_state_machine_change_state( 1070 port_state_machine_change(sci_port, SCI_BASE_PORT_STATE_FAILED);
1037 &sci_port->state_machine,
1038 SCI_BASE_PORT_STATE_FAILED);
1039 } else if (current_state == SCI_BASE_PORT_STATE_STOPPED) { 1071 } else if (current_state == SCI_BASE_PORT_STATE_STOPPED) {
1040 /* 1072 /* if the port is stopped then the start request failed In this
1041 * if the port is stopped then the start request failed 1073 * case stay in the stopped state.
1042 * In this case stay in the stopped state.
1043 */ 1074 */
1044 dev_err(sciport_to_dev(sci_port), 1075 dev_err(sciport_to_dev(sci_port),
1045 "%s: SCIC Port 0x%p failed to stop before tiemout.\n", 1076 "%s: SCIC Port 0x%p failed to stop before tiemout.\n",
1046 __func__, 1077 __func__,
1047 sci_port); 1078 sci_port);
1048 } else if (current_state == SCI_BASE_PORT_STATE_STOPPING) { 1079 } else if (current_state == SCI_BASE_PORT_STATE_STOPPING) {
1049 /* 1080 /* if the port is still stopping then the stop has not completed */
1050 * if the port is still stopping then the stop has not 1081 isci_port_stop_complete(sci_port->owning_controller,
1051 * completed 1082 sci_port,
1052 */ 1083 SCI_FAILURE_TIMEOUT);
1053 isci_port_stop_complete(
1054 scic_sds_port_get_controller(sci_port),
1055 sci_port,
1056 SCI_FAILURE_TIMEOUT);
1057 } else { 1084 } else {
1058 /* 1085 /* The port is in the ready state and we have a timer
1059 * The port is in the ready state and we have a timer
1060 * reporting a timeout this should not happen. 1086 * reporting a timeout this should not happen.
1061 */ 1087 */
1062 dev_err(sciport_to_dev(sci_port), 1088 dev_err(sciport_to_dev(sci_port),
1063 "%s: SCIC Port 0x%p is processing a timeout operation " 1089 "%s: SCIC Port 0x%p is processing a timeout operation "
1064 "in state %d.\n", 1090 "in state %d.\n", __func__, sci_port, current_state);
1065 __func__,
1066 sci_port,
1067 current_state);
1068 } 1091 }
1069} 1092}
1070 1093
@@ -1160,14 +1183,9 @@ static void scic_port_enable_broadcast_change_notification(struct scic_sds_port
1160 * object. This function will transition the ready substate machine to its 1183 * object. This function will transition the ready substate machine to its
1161 * final state. enum sci_status SCI_SUCCESS 1184 * final state. enum sci_status SCI_SUCCESS
1162 */ 1185 */
1163static enum sci_status scic_sds_port_ready_substate_stop_handler( 1186static enum sci_status scic_sds_port_ready_substate_stop_handler(struct scic_sds_port *sci_port)
1164 struct scic_sds_port *port)
1165{ 1187{
1166 sci_base_state_machine_change_state( 1188 port_state_machine_change(sci_port, SCI_BASE_PORT_STATE_STOPPING);
1167 &port->state_machine,
1168 SCI_BASE_PORT_STATE_STOPPING
1169 );
1170
1171 return SCI_SUCCESS; 1189 return SCI_SUCCESS;
1172} 1190}
1173 1191
@@ -1186,48 +1204,40 @@ static enum sci_status scic_sds_port_ready_substate_complete_io_handler(
1186 return SCI_SUCCESS; 1204 return SCI_SUCCESS;
1187} 1205}
1188 1206
1189static enum sci_status scic_sds_port_ready_substate_add_phy_handler( 1207static enum sci_status scic_sds_port_ready_substate_add_phy_handler(struct scic_sds_port *sci_port,
1190 struct scic_sds_port *port, 1208 struct scic_sds_phy *sci_phy)
1191 struct scic_sds_phy *phy)
1192{ 1209{
1193 enum sci_status status; 1210 enum sci_status status;
1194 1211
1195 status = scic_sds_port_set_phy(port, phy); 1212 status = scic_sds_port_set_phy(sci_port, sci_phy);
1196 1213
1197 if (status == SCI_SUCCESS) { 1214 if (status != SCI_SUCCESS)
1198 scic_sds_port_general_link_up_handler(port, phy, true); 1215 return status;
1199
1200 port->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
1201 1216
1202 sci_base_state_machine_change_state( 1217 scic_sds_port_general_link_up_handler(sci_port, sci_phy, true);
1203 &port->ready_substate_machine, 1218 sci_port->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
1204 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING 1219 port_state_machine_change(sci_port, SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING);
1205 );
1206 }
1207 1220
1208 return status; 1221 return status;
1209} 1222}
1210 1223
1211 1224
1212static enum sci_status scic_sds_port_ready_substate_remove_phy_handler( 1225static enum sci_status scic_sds_port_ready_substate_remove_phy_handler(struct scic_sds_port *port,
1213 struct scic_sds_port *port, 1226 struct scic_sds_phy *phy)
1214 struct scic_sds_phy *phy)
1215{ 1227{
1216 enum sci_status status; 1228 enum sci_status status;
1217 1229
1218 status = scic_sds_port_clear_phy(port, phy); 1230 status = scic_sds_port_clear_phy(port, phy);
1219 1231
1220 if (status == SCI_SUCCESS) { 1232 if (status != SCI_SUCCESS)
1221 scic_sds_port_deactivate_phy(port, phy, true); 1233 return status;
1222 1234
1223 port->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING; 1235 scic_sds_port_deactivate_phy(port, phy, true);
1224 1236
1225 sci_base_state_machine_change_state( 1237 port->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
1226 &port->ready_substate_machine,
1227 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1228 );
1229 }
1230 1238
1239 port_state_machine_change(port,
1240 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING);
1231 return status; 1241 return status;
1232} 1242}
1233 1243
@@ -1255,10 +1265,8 @@ static void scic_sds_port_ready_waiting_substate_link_up_handler(
1255 * it and continue. */ 1265 * it and continue. */
1256 scic_sds_port_activate_phy(sci_port, sci_phy, true); 1266 scic_sds_port_activate_phy(sci_port, sci_phy, true);
1257 1267
1258 sci_base_state_machine_change_state( 1268 port_state_machine_change(sci_port,
1259 &sci_port->ready_substate_machine, 1269 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL);
1260 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1261 );
1262} 1270}
1263 1271
1264/* 1272/*
@@ -1317,9 +1325,8 @@ sci_status scic_sds_port_ready_operational_substate_reset_handler(
1317 port->not_ready_reason = 1325 port->not_ready_reason =
1318 SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED; 1326 SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED;
1319 1327
1320 sci_base_state_machine_change_state( 1328 port_state_machine_change(port,
1321 &port->state_machine, 1329 SCI_BASE_PORT_STATE_RESETTING);
1322 SCI_BASE_PORT_STATE_RESETTING);
1323 } 1330 }
1324 } 1331 }
1325 1332
@@ -1365,8 +1372,8 @@ static void scic_sds_port_ready_operational_substate_link_down_handler(
1365 * the port to the WAITING state until such time as a phy goes 1372 * the port to the WAITING state until such time as a phy goes
1366 * link up. */ 1373 * link up. */
1367 if (sci_port->active_phy_mask == 0) 1374 if (sci_port->active_phy_mask == 0)
1368 sci_base_state_machine_change_state(&sci_port->ready_substate_machine, 1375 port_state_machine_change(sci_port,
1369 SCIC_SDS_PORT_READY_SUBSTATE_WAITING); 1376 SCIC_SDS_PORT_READY_SUBSTATE_WAITING);
1370} 1377}
1371 1378
1372/* 1379/*
@@ -1406,10 +1413,8 @@ static enum sci_status scic_sds_port_ready_configuring_substate_add_phy_handler(
1406 /* 1413 /*
1407 * Re-enter the configuring state since this may be the last phy in 1414 * Re-enter the configuring state since this may be the last phy in
1408 * the port. */ 1415 * the port. */
1409 sci_base_state_machine_change_state( 1416 port_state_machine_change(port,
1410 &port->ready_substate_machine, 1417 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING);
1411 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1412 );
1413 } 1418 }
1414 1419
1415 return status; 1420 return status;
@@ -1427,17 +1432,15 @@ static enum sci_status scic_sds_port_ready_configuring_substate_remove_phy_handl
1427 1432
1428 status = scic_sds_port_clear_phy(port, phy); 1433 status = scic_sds_port_clear_phy(port, phy);
1429 1434
1430 if (status == SCI_SUCCESS) { 1435 if (status != SCI_SUCCESS)
1431 scic_sds_port_deactivate_phy(port, phy, true); 1436 return status;
1437 scic_sds_port_deactivate_phy(port, phy, true);
1432 1438
1433 /* 1439 /* Re-enter the configuring state since this may be the last phy in
1434 * Re-enter the configuring state since this may be the last phy in 1440 * the port
1435 * the port. */ 1441 */
1436 sci_base_state_machine_change_state( 1442 port_state_machine_change(port,
1437 &port->ready_substate_machine, 1443 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING);
1438 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1439 );
1440 }
1441 1444
1442 return status; 1445 return status;
1443} 1446}
@@ -1460,10 +1463,8 @@ scic_sds_port_ready_configuring_substate_complete_io_handler(
1460 scic_sds_port_decrement_request_count(port); 1463 scic_sds_port_decrement_request_count(port);
1461 1464
1462 if (port->started_request_count == 0) { 1465 if (port->started_request_count == 0) {
1463 sci_base_state_machine_change_state( 1466 port_state_machine_change(port,
1464 &port->ready_substate_machine, 1467 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL);
1465 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1466 );
1467 } 1468 }
1468 1469
1469 return SCI_SUCCESS; 1470 return SCI_SUCCESS;
@@ -1567,61 +1568,6 @@ static enum sci_status scic_sds_port_default_complete_io_handler(struct scic_sds
1567 return default_port_handler(sci_port, __func__); 1568 return default_port_handler(sci_port, __func__);
1568} 1569}
1569 1570
1570static struct scic_sds_port_state_handler scic_sds_port_ready_substate_handler_table[] = {
1571 [SCIC_SDS_PORT_READY_SUBSTATE_WAITING] = {
1572 .start_handler = scic_sds_port_default_start_handler,
1573 .stop_handler = scic_sds_port_ready_substate_stop_handler,
1574 .destruct_handler = scic_sds_port_default_destruct_handler,
1575 .reset_handler = scic_sds_port_default_reset_handler,
1576 .add_phy_handler = scic_sds_port_ready_substate_add_phy_handler,
1577 .remove_phy_handler = scic_sds_port_default_remove_phy_handler,
1578 .frame_handler = scic_sds_port_default_frame_handler,
1579 .event_handler = scic_sds_port_default_event_handler,
1580 .link_up_handler = scic_sds_port_ready_waiting_substate_link_up_handler,
1581 .link_down_handler = scic_sds_port_default_link_down_handler,
1582 .start_io_handler = scic_sds_port_ready_waiting_substate_start_io_handler,
1583 .complete_io_handler = scic_sds_port_ready_substate_complete_io_handler,
1584 },
1585 [SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL] = {
1586 .start_handler = scic_sds_port_default_start_handler,
1587 .stop_handler = scic_sds_port_ready_substate_stop_handler,
1588 .destruct_handler = scic_sds_port_default_destruct_handler,
1589 .reset_handler = scic_sds_port_ready_operational_substate_reset_handler,
1590 .add_phy_handler = scic_sds_port_ready_substate_add_phy_handler,
1591 .remove_phy_handler = scic_sds_port_ready_substate_remove_phy_handler,
1592 .frame_handler = scic_sds_port_default_frame_handler,
1593 .event_handler = scic_sds_port_default_event_handler,
1594 .link_up_handler = scic_sds_port_ready_operational_substate_link_up_handler,
1595 .link_down_handler = scic_sds_port_ready_operational_substate_link_down_handler,
1596 .start_io_handler = scic_sds_port_ready_operational_substate_start_io_handler,
1597 .complete_io_handler = scic_sds_port_ready_substate_complete_io_handler,
1598 },
1599 [SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING] = {
1600 .start_handler = scic_sds_port_default_start_handler,
1601 .stop_handler = scic_sds_port_ready_substate_stop_handler,
1602 .destruct_handler = scic_sds_port_default_destruct_handler,
1603 .reset_handler = scic_sds_port_default_reset_handler,
1604 .add_phy_handler = scic_sds_port_ready_configuring_substate_add_phy_handler,
1605 .remove_phy_handler = scic_sds_port_ready_configuring_substate_remove_phy_handler,
1606 .frame_handler = scic_sds_port_default_frame_handler,
1607 .event_handler = scic_sds_port_default_event_handler,
1608 .link_up_handler = scic_sds_port_default_link_up_handler,
1609 .link_down_handler = scic_sds_port_default_link_down_handler,
1610 .start_io_handler = scic_sds_port_default_start_io_handler,
1611 .complete_io_handler = scic_sds_port_ready_configuring_substate_complete_io_handler
1612 }
1613};
1614
1615/**
1616 * scic_sds_port_set_ready_state_handlers() -
1617 *
1618 * This macro sets the port ready substate handlers.
1619 */
1620#define scic_sds_port_set_ready_state_handlers(port, state_id) \
1621 scic_sds_port_set_state_handlers(\
1622 port, &scic_sds_port_ready_substate_handler_table[(state_id)] \
1623 )
1624
1625/* 1571/*
1626 * ****************************************************************************** 1572 * ******************************************************************************
1627 * * PORT STATE PRIVATE METHODS 1573 * * PORT STATE PRIVATE METHODS
@@ -1729,7 +1675,7 @@ static void scic_sds_port_ready_substate_waiting_enter(void *object)
1729{ 1675{
1730 struct scic_sds_port *sci_port = object; 1676 struct scic_sds_port *sci_port = object;
1731 1677
1732 scic_sds_port_set_ready_state_handlers( 1678 scic_sds_port_set_base_state_handlers(
1733 sci_port, SCIC_SDS_PORT_READY_SUBSTATE_WAITING 1679 sci_port, SCIC_SDS_PORT_READY_SUBSTATE_WAITING
1734 ); 1680 );
1735 1681
@@ -1739,10 +1685,8 @@ static void scic_sds_port_ready_substate_waiting_enter(void *object)
1739 1685
1740 if (sci_port->active_phy_mask != 0) { 1686 if (sci_port->active_phy_mask != 0) {
1741 /* At least one of the phys on the port is ready */ 1687 /* At least one of the phys on the port is ready */
1742 sci_base_state_machine_change_state( 1688 port_state_machine_change(sci_port,
1743 &sci_port->ready_substate_machine, 1689 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL);
1744 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1745 );
1746 } 1690 }
1747} 1691}
1748 1692
@@ -1763,7 +1707,7 @@ static void scic_sds_port_ready_substate_operational_enter(void *object)
1763 struct isci_host *ihost = scic_to_ihost(scic); 1707 struct isci_host *ihost = scic_to_ihost(scic);
1764 struct isci_port *iport = sci_port_to_iport(sci_port); 1708 struct isci_port *iport = sci_port_to_iport(sci_port);
1765 1709
1766 scic_sds_port_set_ready_state_handlers( 1710 scic_sds_port_set_base_state_handlers(
1767 sci_port, 1711 sci_port,
1768 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL); 1712 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL);
1769 1713
@@ -1788,6 +1732,31 @@ static void scic_sds_port_ready_substate_operational_enter(void *object)
1788 scic_sds_port_post_dummy_request(sci_port); 1732 scic_sds_port_post_dummy_request(sci_port);
1789} 1733}
1790 1734
1735static void scic_sds_port_invalidate_dummy_remote_node(struct scic_sds_port *sci_port)
1736{
1737 struct scic_sds_controller *scic = sci_port->owning_controller;
1738 u8 phys_index = sci_port->physical_port_index;
1739 union scu_remote_node_context *rnc;
1740 u16 rni = sci_port->reserved_rni;
1741 u32 command;
1742
1743 rnc = &scic->remote_node_context_table[rni];
1744
1745 rnc->ssp.is_valid = false;
1746
1747 /* ensure the preceding tc abort request has reached the
1748 * controller and give it ample time to act before posting the rnc
1749 * invalidate
1750 */
1751 readl(&scic->smu_registers->interrupt_status); /* flush */
1752 udelay(10);
1753
1754 command = SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE |
1755 phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;
1756
1757 scic_sds_controller_post_request(scic, command);
1758}
1759
1791/** 1760/**
1792 * 1761 *
1793 * @object: This is the object which is cast to a struct scic_sds_port object. 1762 * @object: This is the object which is cast to a struct scic_sds_port object.
@@ -1811,6 +1780,9 @@ static void scic_sds_port_ready_substate_operational_exit(void *object)
1811 scic_sds_port_abort_dummy_request(sci_port); 1780 scic_sds_port_abort_dummy_request(sci_port);
1812 1781
1813 isci_port_not_ready(ihost, iport); 1782 isci_port_not_ready(ihost, iport);
1783
1784 if (sci_port->ready_exit)
1785 scic_sds_port_invalidate_dummy_remote_node(sci_port);
1814} 1786}
1815 1787
1816/* 1788/*
@@ -1833,20 +1805,18 @@ static void scic_sds_port_ready_substate_configuring_enter(void *object)
1833 struct isci_host *ihost = scic_to_ihost(scic); 1805 struct isci_host *ihost = scic_to_ihost(scic);
1834 struct isci_port *iport = sci_port_to_iport(sci_port); 1806 struct isci_port *iport = sci_port_to_iport(sci_port);
1835 1807
1836 scic_sds_port_set_ready_state_handlers( 1808 scic_sds_port_set_base_state_handlers(
1837 sci_port, 1809 sci_port,
1838 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING); 1810 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING);
1839 1811
1840 if (sci_port->active_phy_mask == 0) { 1812 if (sci_port->active_phy_mask == 0) {
1841 isci_port_not_ready(ihost, iport); 1813 isci_port_not_ready(ihost, iport);
1842 1814
1843 sci_base_state_machine_change_state( 1815 port_state_machine_change(sci_port,
1844 &sci_port->ready_substate_machine, 1816 SCIC_SDS_PORT_READY_SUBSTATE_WAITING);
1845 SCIC_SDS_PORT_READY_SUBSTATE_WAITING);
1846 } else if (sci_port->started_request_count == 0) 1817 } else if (sci_port->started_request_count == 0)
1847 sci_base_state_machine_change_state( 1818 port_state_machine_change(sci_port,
1848 &sci_port->ready_substate_machine, 1819 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL);
1849 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL);
1850} 1820}
1851 1821
1852static void scic_sds_port_ready_substate_configuring_exit(void *object) 1822static void scic_sds_port_ready_substate_configuring_exit(void *object)
@@ -1854,24 +1824,12 @@ static void scic_sds_port_ready_substate_configuring_exit(void *object)
1854 struct scic_sds_port *sci_port = object; 1824 struct scic_sds_port *sci_port = object;
1855 1825
1856 scic_sds_port_suspend_port_task_scheduler(sci_port); 1826 scic_sds_port_suspend_port_task_scheduler(sci_port);
1827 if (sci_port->ready_exit)
1828 scic_sds_port_invalidate_dummy_remote_node(sci_port);
1857} 1829}
1858 1830
1859/* --------------------------------------------------------------------------- */ 1831/* --------------------------------------------------------------------------- */
1860 1832
1861static const struct sci_base_state scic_sds_port_ready_substate_table[] = {
1862 [SCIC_SDS_PORT_READY_SUBSTATE_WAITING] = {
1863 .enter_state = scic_sds_port_ready_substate_waiting_enter,
1864 },
1865 [SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL] = {
1866 .enter_state = scic_sds_port_ready_substate_operational_enter,
1867 .exit_state = scic_sds_port_ready_substate_operational_exit
1868 },
1869 [SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING] = {
1870 .enter_state = scic_sds_port_ready_substate_configuring_enter,
1871 .exit_state = scic_sds_port_ready_substate_configuring_exit
1872 },
1873};
1874
1875/** 1833/**
1876 * 1834 *
1877 * @port: This is the struct scic_sds_port object on which the io request count will 1835 * @port: This is the struct scic_sds_port object on which the io request count will
@@ -1970,9 +1928,8 @@ scic_sds_port_stopped_state_start_handler(struct scic_sds_port *sci_port)
1970 * silicon. 1928 * silicon.
1971 */ 1929 */
1972 if (scic_sds_port_is_phy_mask_valid(sci_port, phy_mask) == true) { 1930 if (scic_sds_port_is_phy_mask_valid(sci_port, phy_mask) == true) {
1973 sci_base_state_machine_change_state( 1931 port_state_machine_change(sci_port,
1974 &sci_port->state_machine, 1932 SCI_BASE_PORT_STATE_READY);
1975 SCI_BASE_PORT_STATE_READY);
1976 1933
1977 return SCI_SUCCESS; 1934 return SCI_SUCCESS;
1978 } else 1935 } else
@@ -2003,10 +1960,9 @@ static enum sci_status scic_sds_port_stopped_state_stop_handler(
2003 * struct scic_sds_port can be destroyed. This function causes the port object to 1960 * struct scic_sds_port can be destroyed. This function causes the port object to
2004 * transition to the SCI_BASE_PORT_STATE_FINAL. enum sci_status SCI_SUCCESS 1961 * transition to the SCI_BASE_PORT_STATE_FINAL. enum sci_status SCI_SUCCESS
2005 */ 1962 */
2006static enum sci_status scic_sds_port_stopped_state_destruct_handler( 1963static enum sci_status scic_sds_port_stopped_state_destruct_handler(struct scic_sds_port *port)
2007 struct scic_sds_port *port)
2008{ 1964{
2009 sci_base_state_machine_stop(&port->state_machine); 1965 port_state_machine_stop(port);
2010 1966
2011 return SCI_SUCCESS; 1967 return SCI_SUCCESS;
2012} 1968}
@@ -2087,10 +2043,9 @@ static enum sci_status scic_sds_port_stopping_state_complete_io_handler(
2087{ 2043{
2088 scic_sds_port_decrement_request_count(sci_port); 2044 scic_sds_port_decrement_request_count(sci_port);
2089 2045
2090 if (sci_port->started_request_count == 0) { 2046 if (sci_port->started_request_count == 0)
2091 sci_base_state_machine_change_state(&sci_port->state_machine, 2047 port_state_machine_change(sci_port,
2092 SCI_BASE_PORT_STATE_STOPPED); 2048 SCI_BASE_PORT_STATE_STOPPED);
2093 }
2094 2049
2095 return SCI_SUCCESS; 2050 return SCI_SUCCESS;
2096} 2051}
@@ -2110,10 +2065,8 @@ static enum sci_status scic_sds_port_stopping_state_complete_io_handler(
2110static enum sci_status scic_sds_port_reset_state_stop_handler( 2065static enum sci_status scic_sds_port_reset_state_stop_handler(
2111 struct scic_sds_port *port) 2066 struct scic_sds_port *port)
2112{ 2067{
2113 sci_base_state_machine_change_state( 2068 port_state_machine_change(port,
2114 &port->state_machine, 2069 SCI_BASE_PORT_STATE_STOPPING);
2115 SCI_BASE_PORT_STATE_STOPPING
2116 );
2117 2070
2118 return SCI_SUCCESS; 2071 return SCI_SUCCESS;
2119} 2072}
@@ -2201,6 +2154,48 @@ static struct scic_sds_port_state_handler scic_sds_port_state_handler_table[] =
2201 .start_io_handler = scic_sds_port_default_start_io_handler, 2154 .start_io_handler = scic_sds_port_default_start_io_handler,
2202 .complete_io_handler = scic_sds_port_general_complete_io_handler 2155 .complete_io_handler = scic_sds_port_general_complete_io_handler
2203 }, 2156 },
2157 [SCIC_SDS_PORT_READY_SUBSTATE_WAITING] = {
2158 .start_handler = scic_sds_port_default_start_handler,
2159 .stop_handler = scic_sds_port_ready_substate_stop_handler,
2160 .destruct_handler = scic_sds_port_default_destruct_handler,
2161 .reset_handler = scic_sds_port_default_reset_handler,
2162 .add_phy_handler = scic_sds_port_ready_substate_add_phy_handler,
2163 .remove_phy_handler = scic_sds_port_default_remove_phy_handler,
2164 .frame_handler = scic_sds_port_default_frame_handler,
2165 .event_handler = scic_sds_port_default_event_handler,
2166 .link_up_handler = scic_sds_port_ready_waiting_substate_link_up_handler,
2167 .link_down_handler = scic_sds_port_default_link_down_handler,
2168 .start_io_handler = scic_sds_port_ready_waiting_substate_start_io_handler,
2169 .complete_io_handler = scic_sds_port_ready_substate_complete_io_handler,
2170 },
2171 [SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL] = {
2172 .start_handler = scic_sds_port_default_start_handler,
2173 .stop_handler = scic_sds_port_ready_substate_stop_handler,
2174 .destruct_handler = scic_sds_port_default_destruct_handler,
2175 .reset_handler = scic_sds_port_ready_operational_substate_reset_handler,
2176 .add_phy_handler = scic_sds_port_ready_substate_add_phy_handler,
2177 .remove_phy_handler = scic_sds_port_ready_substate_remove_phy_handler,
2178 .frame_handler = scic_sds_port_default_frame_handler,
2179 .event_handler = scic_sds_port_default_event_handler,
2180 .link_up_handler = scic_sds_port_ready_operational_substate_link_up_handler,
2181 .link_down_handler = scic_sds_port_ready_operational_substate_link_down_handler,
2182 .start_io_handler = scic_sds_port_ready_operational_substate_start_io_handler,
2183 .complete_io_handler = scic_sds_port_ready_substate_complete_io_handler,
2184 },
2185 [SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING] = {
2186 .start_handler = scic_sds_port_default_start_handler,
2187 .stop_handler = scic_sds_port_ready_substate_stop_handler,
2188 .destruct_handler = scic_sds_port_default_destruct_handler,
2189 .reset_handler = scic_sds_port_default_reset_handler,
2190 .add_phy_handler = scic_sds_port_ready_configuring_substate_add_phy_handler,
2191 .remove_phy_handler = scic_sds_port_ready_configuring_substate_remove_phy_handler,
2192 .frame_handler = scic_sds_port_default_frame_handler,
2193 .event_handler = scic_sds_port_default_event_handler,
2194 .link_up_handler = scic_sds_port_default_link_up_handler,
2195 .link_down_handler = scic_sds_port_default_link_down_handler,
2196 .start_io_handler = scic_sds_port_default_start_io_handler,
2197 .complete_io_handler = scic_sds_port_ready_configuring_substate_complete_io_handler
2198 },
2204 [SCI_BASE_PORT_STATE_RESETTING] = { 2199 [SCI_BASE_PORT_STATE_RESETTING] = {
2205 .start_handler = scic_sds_port_default_start_handler, 2200 .start_handler = scic_sds_port_default_start_handler,
2206 .stop_handler = scic_sds_port_reset_state_stop_handler, 2201 .stop_handler = scic_sds_port_reset_state_stop_handler,
@@ -2299,31 +2294,6 @@ static void scic_sds_port_post_dummy_remote_node(struct scic_sds_port *sci_port)
2299 scic_sds_controller_post_request(scic, command); 2294 scic_sds_controller_post_request(scic, command);
2300} 2295}
2301 2296
2302static void scic_sds_port_invalidate_dummy_remote_node(struct scic_sds_port *sci_port)
2303{
2304 struct scic_sds_controller *scic = sci_port->owning_controller;
2305 u8 phys_index = sci_port->physical_port_index;
2306 union scu_remote_node_context *rnc;
2307 u16 rni = sci_port->reserved_rni;
2308 u32 command;
2309
2310 rnc = &scic->remote_node_context_table[rni];
2311
2312 rnc->ssp.is_valid = false;
2313
2314 /* ensure the preceding tc abort request has reached the
2315 * controller and give it ample time to act before posting the rnc
2316 * invalidate
2317 */
2318 readl(&scic->smu_registers->interrupt_status); /* flush */
2319 udelay(10);
2320
2321 command = SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE |
2322 phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;
2323
2324 scic_sds_controller_post_request(scic, command);
2325}
2326
2327/* 2297/*
2328 * ****************************************************************************** 2298 * ******************************************************************************
2329 * * PORT STATE METHODS 2299 * * PORT STATE METHODS
@@ -2404,15 +2374,8 @@ static void scic_sds_port_ready_state_enter(void *object)
2404 scic_sds_port_post_dummy_remote_node(sci_port); 2374 scic_sds_port_post_dummy_remote_node(sci_port);
2405 2375
2406 /* Start the ready substate machine */ 2376 /* Start the ready substate machine */
2407 sci_base_state_machine_start(&sci_port->ready_substate_machine); 2377 port_state_machine_change(sci_port,
2408} 2378 SCIC_SDS_PORT_READY_SUBSTATE_WAITING);
2409
2410static void scic_sds_port_ready_state_exit(void *object)
2411{
2412 struct scic_sds_port *sci_port = object;
2413
2414 sci_base_state_machine_stop(&sci_port->ready_substate_machine);
2415 scic_sds_port_invalidate_dummy_remote_node(sci_port);
2416} 2379}
2417 2380
2418/** 2381/**
@@ -2516,7 +2479,17 @@ static const struct sci_base_state scic_sds_port_state_table[] = {
2516 }, 2479 },
2517 [SCI_BASE_PORT_STATE_READY] = { 2480 [SCI_BASE_PORT_STATE_READY] = {
2518 .enter_state = scic_sds_port_ready_state_enter, 2481 .enter_state = scic_sds_port_ready_state_enter,
2519 .exit_state = scic_sds_port_ready_state_exit 2482 },
2483 [SCIC_SDS_PORT_READY_SUBSTATE_WAITING] = {
2484 .enter_state = scic_sds_port_ready_substate_waiting_enter,
2485 },
2486 [SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL] = {
2487 .enter_state = scic_sds_port_ready_substate_operational_enter,
2488 .exit_state = scic_sds_port_ready_substate_operational_exit
2489 },
2490 [SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING] = {
2491 .enter_state = scic_sds_port_ready_substate_configuring_enter,
2492 .exit_state = scic_sds_port_ready_substate_configuring_exit
2520 }, 2493 },
2521 [SCI_BASE_PORT_STATE_RESETTING] = { 2494 [SCI_BASE_PORT_STATE_RESETTING] = {
2522 .enter_state = scic_sds_port_resetting_state_enter, 2495 .enter_state = scic_sds_port_resetting_state_enter,
@@ -2537,14 +2510,10 @@ void scic_sds_port_construct(struct scic_sds_port *sci_port, u8 index,
2537 2510
2538 sci_base_state_machine_start(&sci_port->state_machine); 2511 sci_base_state_machine_start(&sci_port->state_machine);
2539 2512
2540 sci_base_state_machine_construct(&sci_port->ready_substate_machine,
2541 sci_port,
2542 scic_sds_port_ready_substate_table,
2543 SCIC_SDS_PORT_READY_SUBSTATE_WAITING);
2544
2545 sci_port->logical_port_index = SCIC_SDS_DUMMY_PORT; 2513 sci_port->logical_port_index = SCIC_SDS_DUMMY_PORT;
2546 sci_port->physical_port_index = index; 2514 sci_port->physical_port_index = index;
2547 sci_port->active_phy_mask = 0; 2515 sci_port->active_phy_mask = 0;
2516 sci_port->ready_exit = false;
2548 2517
2549 sci_port->owning_controller = scic; 2518 sci_port->owning_controller = scic;
2550 2519