aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Sawicki <piotr.sawicki@intel.com>2011-05-11 19:52:21 -0400
committerDan Williams <dan.j.williams@intel.com>2011-07-03 07:04:49 -0400
commite91f41ef809a2d1b8cdba52ac380aecd706c93dd (patch)
tree3b3a82136e398355f0b7e07215741798a6007233
parentc777c26ca2a06164e1b8c8ccf4cd76cd645a9bbb (diff)
isci: merge port ready substates into primary state machine
This conversion was complicated by the fact that the ready state exit routine took unconditional action beyond just stopping the substate machine (like in previous conversions). In order to ensure identical behaviour every state transition needs to be instrumented to catch ready-->!ready transitions and execute scic_sds_port_invalidate_dummy_remote_node() Reported-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Piotr Sawicki <piotr.sawicki@intel.com> [fix ready state exit handling] Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/scsi/isci/port.c409
-rw-r--r--drivers/scsi/isci/port.h57
2 files changed, 210 insertions, 256 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
diff --git a/drivers/scsi/isci/port.h b/drivers/scsi/isci/port.h
index ea41dcead3ae..e63c34d02b7d 100644
--- a/drivers/scsi/isci/port.h
+++ b/drivers/scsi/isci/port.h
@@ -81,12 +81,13 @@ enum isci_status {
81 * The core port object provides the the abstraction for an SCU port. 81 * The core port object provides the the abstraction for an SCU port.
82 */ 82 */
83struct scic_sds_port { 83struct scic_sds_port {
84
85 /** 84 /**
86 * This field contains the information for the base port state machine. 85 * This field contains the information for the base port state machine.
87 */ 86 */
88 struct sci_base_state_machine state_machine; 87 struct sci_base_state_machine state_machine;
89 88
89 bool ready_exit;
90
90 /** 91 /**
91 * This field is the port index that is reported to the SCI USER. 92 * This field is the port index that is reported to the SCI USER.
92 * This allows the actual hardware physical port to change without 93 * This allows the actual hardware physical port to change without
@@ -150,11 +151,6 @@ struct scic_sds_port {
150 */ 151 */
151 struct scic_sds_port_state_handler *state_handlers; 152 struct scic_sds_port_state_handler *state_handlers;
152 153
153 /**
154 * This field is the ready substate machine for the port.
155 */
156 struct sci_base_state_machine ready_substate_machine;
157
158 /* / Memory mapped hardware register space */ 154 /* / Memory mapped hardware register space */
159 155
160 /** 156 /**
@@ -175,7 +171,6 @@ struct scic_sds_port {
175 * This field is the VIIT register space for ths port object. 171 * This field is the VIIT register space for ths port object.
176 */ 172 */
177 struct scu_viit_entry __iomem *viit_registers; 173 struct scu_viit_entry __iomem *viit_registers;
178
179}; 174};
180 175
181 176
@@ -229,35 +224,6 @@ struct scic_port_properties {
229}; 224};
230 225
231/** 226/**
232 * enum SCIC_SDS_PORT_READY_SUBSTATES -
233 *
234 * This enumeration depicts all of the states for the core port ready substate
235 * machine.
236 */
237enum scic_sds_port_ready_substates {
238 /**
239 * The substate where the port is started and ready but has no
240 * active phys.
241 */
242 SCIC_SDS_PORT_READY_SUBSTATE_WAITING,
243
244 /**
245 * The substate where the port is started and ready and there is
246 * at least one phy operational.
247 */
248 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL,
249
250 /**
251 * The substate where the port is started and there was an
252 * add/remove phy event. This state is only used in Automatic
253 * Port Configuration Mode (APC)
254 */
255 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING,
256
257 SCIC_SDS_PORT_READY_MAX_SUBSTATES
258};
259
260/**
261 * enum scic_sds_port_states - This enumeration depicts all the states for the 227 * enum scic_sds_port_states - This enumeration depicts all the states for the
262 * common port state machine. 228 * common port state machine.
263 * 229 *
@@ -287,6 +253,25 @@ enum scic_sds_port_states {
287 SCI_BASE_PORT_STATE_READY, 253 SCI_BASE_PORT_STATE_READY,
288 254
289 /** 255 /**
256 * The substate where the port is started and ready but has no
257 * active phys.
258 */
259 SCIC_SDS_PORT_READY_SUBSTATE_WAITING,
260
261 /**
262 * The substate where the port is started and ready and there is
263 * at least one phy operational.
264 */
265 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL,
266
267 /**
268 * The substate where the port is started and there was an
269 * add/remove phy event. This state is only used in Automatic
270 * Port Configuration Mode (APC)
271 */
272 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING,
273
274 /**
290 * This state indicates the port is in the process of performing a hard 275 * This state indicates the port is in the process of performing a hard
291 * reset. Thus, the user is unable to perform IO operations on this 276 * reset. Thus, the user is unable to perform IO operations on this
292 * port. 277 * port.