aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/phy.c
diff options
context:
space:
mode:
authorAdam Gruchala <adam.gruchala@intel.com>2011-05-10 23:54:23 +0000
committerDan Williams <dan.j.williams@intel.com>2011-07-03 04:04:48 -0700
commit4a33c525f0e94b57602abd1e43644cbf6f5418f4 (patch)
tree4f42dccac26c36af150322c6b7e152d31efe4aa1 /drivers/scsi/isci/phy.c
parentisci: remove the completion and event state handlers (diff)
downloadlinux-dev-4a33c525f0e94b57602abd1e43644cbf6f5418f4.tar.xz
linux-dev-4a33c525f0e94b57602abd1e43644cbf6f5418f4.zip
isci: merge phy substates
Merged states and substates into one state machine, as we always unconditionally transitioned to the substate machine it was straightforward to enter that substate from the starting state. Reported-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Adam Gruchala <adam.gruchala@intel.com> [fixed construction, starting_state_enter, and starting check] Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/phy.c')
-rw-r--r--drivers/scsi/isci/phy.c500
1 files changed, 233 insertions, 267 deletions
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c
index 0f64605200ff..e5ae676926f2 100644
--- a/drivers/scsi/isci/phy.c
+++ b/drivers/scsi/isci/phy.c
@@ -271,8 +271,6 @@ static void scic_sds_phy_sata_timeout(void *phy)
__func__,
sci_phy);
- sci_base_state_machine_stop(&sci_phy->starting_substate_machine);
-
sci_base_state_machine_change_state(&sci_phy->state_machine,
SCI_BASE_PHY_STATE_STARTING);
}
@@ -546,7 +544,7 @@ static void scic_sds_phy_start_sas_link_training(
&sci_phy->link_layer_registers->phy_configuration);
sci_base_state_machine_change_state(
- &sci_phy->starting_substate_machine,
+ &sci_phy->state_machine,
SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
);
@@ -565,7 +563,7 @@ static void scic_sds_phy_start_sata_link_training(
struct scic_sds_phy *sci_phy)
{
sci_base_state_machine_change_state(
- &sci_phy->starting_substate_machine,
+ &sci_phy->state_machine,
SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
);
@@ -590,16 +588,13 @@ static void scic_sds_phy_complete_link_training(
{
sci_phy->max_negotiated_speed = max_link_rate;
- sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
+ sci_base_state_machine_change_state(&sci_phy->state_machine,
next_state);
}
static void scic_sds_phy_restart_starting_state(
struct scic_sds_phy *sci_phy)
{
- /* Stop the current substate machine */
- sci_base_state_machine_stop(&sci_phy->starting_substate_machine);
-
/* Re-enter the base state machine starting state */
sci_base_state_machine_change_state(&sci_phy->state_machine,
SCI_BASE_PHY_STATE_STARTING);
@@ -611,8 +606,6 @@ static void scic_sds_phy_restart_starting_state(
static enum sci_status scic_sds_phy_starting_substate_general_stop_handler(
struct scic_sds_phy *phy)
{
- sci_base_state_machine_stop(&phy->starting_substate_machine);
-
sci_base_state_machine_change_state(&phy->state_machine,
SCI_BASE_PHY_STATE_STOPPED);
@@ -919,7 +912,7 @@ static enum sci_status scic_sds_phy_starting_substate_await_sata_phy_event_handl
sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
/* We have received the SATA PHY notification change state */
- sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
+ sci_base_state_machine_change_state(&sci_phy->state_machine,
SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN);
break;
@@ -1042,7 +1035,7 @@ static enum sci_status scic_sds_phy_starting_substate_await_sig_fis_event_handle
switch (scu_get_event_code(event_code)) {
case SCU_EVENT_SATA_PHY_DETECTED:
/* Backup the state machine */
- sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
+ sci_base_state_machine_change_state(&sci_phy->state_machine,
SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN);
break;
@@ -1118,7 +1111,7 @@ static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_frame_handler
state = SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER;
}
sci_base_state_machine_change_state(
- &sci_phy->starting_substate_machine,
+ &sci_phy->state_machine,
state);
result = SCI_SUCCESS;
} else
@@ -1177,7 +1170,7 @@ static enum sci_status scic_sds_phy_starting_substate_await_sig_fis_frame_handle
fis_frame_data);
/* got IAF we can now go to the await spinup semaphore state */
- sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
+ sci_base_state_machine_change_state(&sci_phy->state_machine,
SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL);
result = SCI_SUCCESS;
@@ -1216,7 +1209,7 @@ static enum sci_status scic_sds_phy_starting_substate_await_sas_power_consume_po
writel(enable_spinup, &sci_phy->link_layer_registers->notify_enable_spinup_control);
/* Change state to the final state this substate machine has run to completion */
- sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
+ sci_base_state_machine_change_state(&sci_phy->state_machine,
SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL);
return SCI_SUCCESS;
@@ -1248,7 +1241,7 @@ static enum sci_status scic_sds_phy_starting_substate_await_sata_power_consume_p
&sci_phy->link_layer_registers->phy_configuration);
/* Change state to the final state this substate machine has run to completion */
- sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
+ sci_base_state_machine_change_state(&sci_phy->state_machine,
SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN);
return SCI_SUCCESS;
@@ -1312,9 +1305,156 @@ scic_sds_phy_default_consume_power_handler(struct scic_sds_phy *sci_phy)
return default_phy_handler(sci_phy, __func__);
}
+/*
+ * This method takes the struct scic_sds_phy from a stopped state and
+ * attempts to start it. - The phy state machine is transitioned to the
+ * SCI_BASE_PHY_STATE_STARTING. enum sci_status SCI_SUCCESS
+ */
+static enum sci_status
+scic_sds_phy_stopped_state_start_handler(struct scic_sds_phy *sci_phy)
+{
+ struct isci_host *ihost;
+ struct scic_sds_controller *scic;
+
+ scic = scic_sds_phy_get_controller(sci_phy),
+ ihost = scic_to_ihost(scic);
+ /* Create the SIGNATURE FIS Timeout timer for this phy */
+ sci_phy->sata_timeout_timer = isci_timer_create(ihost, sci_phy,
+ scic_sds_phy_sata_timeout);
+
+ if (sci_phy->sata_timeout_timer)
+ sci_base_state_machine_change_state(&sci_phy->state_machine,
+ SCI_BASE_PHY_STATE_STARTING);
+
+ return SCI_SUCCESS;
+}
+
+static enum sci_status
+scic_sds_phy_stopped_state_destroy_handler(struct scic_sds_phy *sci_phy)
+{
+ return SCI_SUCCESS;
+}
+
+static enum sci_status
+scic_sds_phy_ready_state_stop_handler(struct scic_sds_phy *sci_phy)
+{
+ sci_base_state_machine_change_state(&sci_phy->state_machine,
+ SCI_BASE_PHY_STATE_STOPPED);
+
+ return SCI_SUCCESS;
+}
+
+static enum sci_status
+scic_sds_phy_ready_state_reset_handler(struct scic_sds_phy *sci_phy)
+{
+ sci_base_state_machine_change_state(&sci_phy->state_machine,
+ SCI_BASE_PHY_STATE_RESETTING);
+
+ return SCI_SUCCESS;
+}
-static const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_table[] = {
+/**
+ * scic_sds_phy_ready_state_event_handler -
+ * @phy: This is the struct scic_sds_phy object which has received the event.
+ *
+ * This method request the struct scic_sds_phy handle the received event. The only
+ * event that we are interested in while in the ready state is the link failure
+ * event. - decoded event is a link failure - transition the struct scic_sds_phy back
+ * to the SCI_BASE_PHY_STATE_STARTING state. - any other event received will
+ * report a warning message enum sci_status SCI_SUCCESS if the event received is a
+ * link failure SCI_FAILURE_INVALID_STATE for any other event received.
+ */
+static enum sci_status scic_sds_phy_ready_state_event_handler(struct scic_sds_phy *sci_phy,
+ u32 event_code)
+{
+ enum sci_status result = SCI_FAILURE;
+
+ switch (scu_get_event_code(event_code)) {
+ case SCU_EVENT_LINK_FAILURE:
+ /* Link failure change state back to the starting state */
+ sci_base_state_machine_change_state(&sci_phy->state_machine,
+ SCI_BASE_PHY_STATE_STARTING);
+ result = SCI_SUCCESS;
+ break;
+
+ case SCU_EVENT_BROADCAST_CHANGE:
+ /* Broadcast change received. Notify the port. */
+ if (scic_sds_phy_get_port(sci_phy) != NULL)
+ scic_sds_port_broadcast_change_received(sci_phy->owning_port, sci_phy);
+ else
+ sci_phy->bcn_received_while_port_unassigned = true;
+ break;
+
+ default:
+ dev_warn(sciphy_to_dev(sci_phy),
+ "%sP SCIC PHY 0x%p ready state machine received "
+ "unexpected event_code %x\n",
+ __func__, sci_phy, event_code);
+
+ result = SCI_FAILURE_INVALID_STATE;
+ break;
+ }
+
+ return result;
+}
+
+static enum sci_status scic_sds_phy_resetting_state_event_handler(struct scic_sds_phy *sci_phy,
+ u32 event_code)
+{
+ enum sci_status result = SCI_FAILURE;
+
+ switch (scu_get_event_code(event_code)) {
+ case SCU_EVENT_HARD_RESET_TRANSMITTED:
+ /* Link failure change state back to the starting state */
+ sci_base_state_machine_change_state(&sci_phy->state_machine,
+ SCI_BASE_PHY_STATE_STARTING);
+ result = SCI_SUCCESS;
+ break;
+
+ default:
+ dev_warn(sciphy_to_dev(sci_phy),
+ "%s: SCIC PHY 0x%p resetting state machine received "
+ "unexpected event_code %x\n",
+ __func__, sci_phy, event_code);
+
+ result = SCI_FAILURE_INVALID_STATE;
+ break;
+ }
+
+ return result;
+}
+
+/* --------------------------------------------------------------------------- */
+
+static const struct scic_sds_phy_state_handler scic_sds_phy_state_handler_table[] = {
+ [SCI_BASE_PHY_STATE_INITIAL] = {
+ .start_handler = scic_sds_phy_default_start_handler,
+ .stop_handler = scic_sds_phy_default_stop_handler,
+ .reset_handler = scic_sds_phy_default_reset_handler,
+ .destruct_handler = scic_sds_phy_default_destroy_handler,
+ .frame_handler = scic_sds_phy_default_frame_handler,
+ .event_handler = scic_sds_phy_default_event_handler,
+ .consume_power_handler = scic_sds_phy_default_consume_power_handler
+ },
+ [SCI_BASE_PHY_STATE_STOPPED] = {
+ .start_handler = scic_sds_phy_stopped_state_start_handler,
+ .stop_handler = scic_sds_phy_default_stop_handler,
+ .reset_handler = scic_sds_phy_default_reset_handler,
+ .destruct_handler = scic_sds_phy_stopped_state_destroy_handler,
+ .frame_handler = scic_sds_phy_default_frame_handler,
+ .event_handler = scic_sds_phy_default_event_handler,
+ .consume_power_handler = scic_sds_phy_default_consume_power_handler
+ },
+ [SCI_BASE_PHY_STATE_STARTING] = {
+ .start_handler = scic_sds_phy_default_start_handler,
+ .stop_handler = scic_sds_phy_default_stop_handler,
+ .reset_handler = scic_sds_phy_default_reset_handler,
+ .destruct_handler = scic_sds_phy_default_destroy_handler,
+ .frame_handler = scic_sds_phy_default_frame_handler,
+ .event_handler = scic_sds_phy_default_event_handler,
+ .consume_power_handler = scic_sds_phy_default_consume_power_handler
+ },
[SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = {
.start_handler = scic_sds_phy_default_start_handler,
.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
@@ -1404,20 +1544,36 @@ static const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_ha
.frame_handler = scic_sds_phy_default_frame_handler,
.event_handler = scic_sds_phy_default_event_handler,
.consume_power_handler = scic_sds_phy_default_consume_power_handler
+ },
+ [SCI_BASE_PHY_STATE_READY] = {
+ .start_handler = scic_sds_phy_default_start_handler,
+ .stop_handler = scic_sds_phy_ready_state_stop_handler,
+ .reset_handler = scic_sds_phy_ready_state_reset_handler,
+ .destruct_handler = scic_sds_phy_default_destroy_handler,
+ .frame_handler = scic_sds_phy_default_frame_handler,
+ .event_handler = scic_sds_phy_ready_state_event_handler,
+ .consume_power_handler = scic_sds_phy_default_consume_power_handler
+ },
+ [SCI_BASE_PHY_STATE_RESETTING] = {
+ .start_handler = scic_sds_phy_default_start_handler,
+ .stop_handler = scic_sds_phy_default_stop_handler,
+ .reset_handler = scic_sds_phy_default_reset_handler,
+ .destruct_handler = scic_sds_phy_default_destroy_handler,
+ .frame_handler = scic_sds_phy_default_frame_handler,
+ .event_handler = scic_sds_phy_resetting_state_event_handler,
+ .consume_power_handler = scic_sds_phy_default_consume_power_handler
+ },
+ [SCI_BASE_PHY_STATE_FINAL] = {
+ .start_handler = scic_sds_phy_default_start_handler,
+ .stop_handler = scic_sds_phy_default_stop_handler,
+ .reset_handler = scic_sds_phy_default_reset_handler,
+ .destruct_handler = scic_sds_phy_default_destroy_handler,
+ .frame_handler = scic_sds_phy_default_frame_handler,
+ .event_handler = scic_sds_phy_default_event_handler,
+ .consume_power_handler = scic_sds_phy_default_consume_power_handler
}
};
-/**
- * scic_sds_phy_set_starting_substate_handlers() -
- *
- * This macro sets the starting substate handlers by state_id
- */
-#define scic_sds_phy_set_starting_substate_handlers(phy, state_id) \
- scic_sds_phy_set_state_handlers(\
- (phy), \
- &scic_sds_phy_starting_substate_handler_table[(state_id)] \
- )
-
/*
* ****************************************************************************
* * PHY STARTING SUBSTATE METHODS
@@ -1436,11 +1592,11 @@ static void scic_sds_phy_starting_initial_substate_enter(void *object)
{
struct scic_sds_phy *sci_phy = object;
- scic_sds_phy_set_starting_substate_handlers(
+ scic_sds_phy_set_base_state_handlers(
sci_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL);
/* This is just an temporary state go off to the starting state */
- sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
+ sci_base_state_machine_change_state(&sci_phy->state_machine,
SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN);
}
@@ -1456,7 +1612,7 @@ static void scic_sds_phy_starting_await_ossp_en_substate_enter(void *object)
{
struct scic_sds_phy *sci_phy = object;
- scic_sds_phy_set_starting_substate_handlers(
+ scic_sds_phy_set_base_state_handlers(
sci_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
);
}
@@ -1474,7 +1630,7 @@ static void scic_sds_phy_starting_await_sas_speed_en_substate_enter(
{
struct scic_sds_phy *sci_phy = object;
- scic_sds_phy_set_starting_substate_handlers(
+ scic_sds_phy_set_base_state_handlers(
sci_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
);
}
@@ -1491,7 +1647,7 @@ static void scic_sds_phy_starting_await_iaf_uf_substate_enter(void *object)
{
struct scic_sds_phy *sci_phy = object;
- scic_sds_phy_set_starting_substate_handlers(
+ scic_sds_phy_set_base_state_handlers(
sci_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
);
}
@@ -1509,7 +1665,7 @@ static void scic_sds_phy_starting_await_sas_power_substate_enter(void *object)
{
struct scic_sds_phy *sci_phy = object;
- scic_sds_phy_set_starting_substate_handlers(
+ scic_sds_phy_set_base_state_handlers(
sci_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
);
@@ -1549,7 +1705,7 @@ static void scic_sds_phy_starting_await_sata_power_substate_enter(void *object)
{
struct scic_sds_phy *sci_phy = object;
- scic_sds_phy_set_starting_substate_handlers(
+ scic_sds_phy_set_base_state_handlers(
sci_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
);
@@ -1589,7 +1745,7 @@ static void scic_sds_phy_starting_await_sata_phy_substate_enter(void *object)
{
struct scic_sds_phy *sci_phy = object;
- scic_sds_phy_set_starting_substate_handlers(
+ scic_sds_phy_set_base_state_handlers(
sci_phy,
SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN);
@@ -1626,7 +1782,7 @@ static void scic_sds_phy_starting_await_sata_speed_substate_enter(void *object)
{
struct scic_sds_phy *sci_phy = object;
- scic_sds_phy_set_starting_substate_handlers(
+ scic_sds_phy_set_base_state_handlers(
sci_phy,
SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN);
@@ -1666,7 +1822,7 @@ static void scic_sds_phy_starting_await_sig_fis_uf_substate_enter(void *object)
bool continue_to_ready_state;
struct scic_sds_phy *sci_phy = object;
- scic_sds_phy_set_starting_substate_handlers(
+ scic_sds_phy_set_base_state_handlers(
sci_phy,
SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF);
@@ -1719,7 +1875,7 @@ static void scic_sds_phy_starting_final_substate_enter(void *object)
{
struct scic_sds_phy *sci_phy = object;
- scic_sds_phy_set_starting_substate_handlers(sci_phy,
+ scic_sds_phy_set_base_state_handlers(sci_phy,
SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL);
/* State machine has run to completion so exit out and change
@@ -1729,225 +1885,6 @@ static void scic_sds_phy_starting_final_substate_enter(void *object)
SCI_BASE_PHY_STATE_READY);
}
-/* --------------------------------------------------------------------------- */
-
-static const struct sci_base_state scic_sds_phy_starting_substates[] = {
- [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = {
- .enter_state = scic_sds_phy_starting_initial_substate_enter,
- },
- [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN] = {
- .enter_state = scic_sds_phy_starting_await_ossp_en_substate_enter,
- },
- [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN] = {
- .enter_state = scic_sds_phy_starting_await_sas_speed_en_substate_enter,
- },
- [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF] = {
- .enter_state = scic_sds_phy_starting_await_iaf_uf_substate_enter,
- },
- [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER] = {
- .enter_state = scic_sds_phy_starting_await_sas_power_substate_enter,
- .exit_state = scic_sds_phy_starting_await_sas_power_substate_exit,
- },
- [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER] = {
- .enter_state = scic_sds_phy_starting_await_sata_power_substate_enter,
- .exit_state = scic_sds_phy_starting_await_sata_power_substate_exit
- },
- [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN] = {
- .enter_state = scic_sds_phy_starting_await_sata_phy_substate_enter,
- .exit_state = scic_sds_phy_starting_await_sata_phy_substate_exit
- },
- [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN] = {
- .enter_state = scic_sds_phy_starting_await_sata_speed_substate_enter,
- .exit_state = scic_sds_phy_starting_await_sata_speed_substate_exit
- },
- [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF] = {
- .enter_state = scic_sds_phy_starting_await_sig_fis_uf_substate_enter,
- .exit_state = scic_sds_phy_starting_await_sig_fis_uf_substate_exit
- },
- [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL] = {
- .enter_state = scic_sds_phy_starting_final_substate_enter,
- }
-};
-
-/*
- * This method takes the struct scic_sds_phy from a stopped state and
- * attempts to start it. - The phy state machine is transitioned to the
- * SCI_BASE_PHY_STATE_STARTING. enum sci_status SCI_SUCCESS
- */
-static enum sci_status
-scic_sds_phy_stopped_state_start_handler(struct scic_sds_phy *sci_phy)
-{
- struct isci_host *ihost;
- struct scic_sds_controller *scic;
-
- scic = scic_sds_phy_get_controller(sci_phy),
- ihost = scic_to_ihost(scic);
-
- /* Create the SIGNATURE FIS Timeout timer for this phy */
- sci_phy->sata_timeout_timer = isci_timer_create(ihost, sci_phy,
- scic_sds_phy_sata_timeout);
-
- if (sci_phy->sata_timeout_timer)
- sci_base_state_machine_change_state(&sci_phy->state_machine,
- SCI_BASE_PHY_STATE_STARTING);
-
- return SCI_SUCCESS;
-}
-
-static enum sci_status
-scic_sds_phy_stopped_state_destroy_handler(struct scic_sds_phy *sci_phy)
-{
- return SCI_SUCCESS;
-}
-
-static enum sci_status
-scic_sds_phy_ready_state_stop_handler(struct scic_sds_phy *sci_phy)
-{
- sci_base_state_machine_change_state(&sci_phy->state_machine,
- SCI_BASE_PHY_STATE_STOPPED);
-
- return SCI_SUCCESS;
-}
-
-static enum sci_status
-scic_sds_phy_ready_state_reset_handler(struct scic_sds_phy *sci_phy)
-{
- sci_base_state_machine_change_state(&sci_phy->state_machine,
- SCI_BASE_PHY_STATE_RESETTING);
-
- return SCI_SUCCESS;
-}
-
-/**
- * scic_sds_phy_ready_state_event_handler -
- * @phy: This is the struct scic_sds_phy object which has received the event.
- *
- * This method request the struct scic_sds_phy handle the received event. The only
- * event that we are interested in while in the ready state is the link failure
- * event. - decoded event is a link failure - transition the struct scic_sds_phy back
- * to the SCI_BASE_PHY_STATE_STARTING state. - any other event received will
- * report a warning message enum sci_status SCI_SUCCESS if the event received is a
- * link failure SCI_FAILURE_INVALID_STATE for any other event received.
- */
-static enum sci_status scic_sds_phy_ready_state_event_handler(struct scic_sds_phy *sci_phy,
- u32 event_code)
-{
- enum sci_status result = SCI_FAILURE;
-
- switch (scu_get_event_code(event_code)) {
- case SCU_EVENT_LINK_FAILURE:
- /* Link failure change state back to the starting state */
- sci_base_state_machine_change_state(&sci_phy->state_machine,
- SCI_BASE_PHY_STATE_STARTING);
- result = SCI_SUCCESS;
- break;
-
- case SCU_EVENT_BROADCAST_CHANGE:
- /* Broadcast change received. Notify the port. */
- if (scic_sds_phy_get_port(sci_phy) != NULL)
- scic_sds_port_broadcast_change_received(sci_phy->owning_port, sci_phy);
- else
- sci_phy->bcn_received_while_port_unassigned = true;
- break;
-
- default:
- dev_warn(sciphy_to_dev(sci_phy),
- "%sP SCIC PHY 0x%p ready state machine received "
- "unexpected event_code %x\n",
- __func__, sci_phy, event_code);
-
- result = SCI_FAILURE_INVALID_STATE;
- break;
- }
-
- return result;
-}
-
-static enum sci_status scic_sds_phy_resetting_state_event_handler(struct scic_sds_phy *sci_phy,
- u32 event_code)
-{
- enum sci_status result = SCI_FAILURE;
-
- switch (scu_get_event_code(event_code)) {
- case SCU_EVENT_HARD_RESET_TRANSMITTED:
- /* Link failure change state back to the starting state */
- sci_base_state_machine_change_state(&sci_phy->state_machine,
- SCI_BASE_PHY_STATE_STARTING);
- result = SCI_SUCCESS;
- break;
-
- default:
- dev_warn(sciphy_to_dev(sci_phy),
- "%s: SCIC PHY 0x%p resetting state machine received "
- "unexpected event_code %x\n",
- __func__, sci_phy, event_code);
-
- result = SCI_FAILURE_INVALID_STATE;
- break;
- }
-
- return result;
-}
-
-/* --------------------------------------------------------------------------- */
-
-static const struct scic_sds_phy_state_handler scic_sds_phy_state_handler_table[] = {
- [SCI_BASE_PHY_STATE_INITIAL] = {
- .start_handler = scic_sds_phy_default_start_handler,
- .stop_handler = scic_sds_phy_default_stop_handler,
- .reset_handler = scic_sds_phy_default_reset_handler,
- .destruct_handler = scic_sds_phy_default_destroy_handler,
- .frame_handler = scic_sds_phy_default_frame_handler,
- .event_handler = scic_sds_phy_default_event_handler,
- .consume_power_handler = scic_sds_phy_default_consume_power_handler
- },
- [SCI_BASE_PHY_STATE_STOPPED] = {
- .start_handler = scic_sds_phy_stopped_state_start_handler,
- .stop_handler = scic_sds_phy_default_stop_handler,
- .reset_handler = scic_sds_phy_default_reset_handler,
- .destruct_handler = scic_sds_phy_stopped_state_destroy_handler,
- .frame_handler = scic_sds_phy_default_frame_handler,
- .event_handler = scic_sds_phy_default_event_handler,
- .consume_power_handler = scic_sds_phy_default_consume_power_handler
- },
- [SCI_BASE_PHY_STATE_STARTING] = {
- .start_handler = scic_sds_phy_default_start_handler,
- .stop_handler = scic_sds_phy_default_stop_handler,
- .reset_handler = scic_sds_phy_default_reset_handler,
- .destruct_handler = scic_sds_phy_default_destroy_handler,
- .frame_handler = scic_sds_phy_default_frame_handler,
- .event_handler = scic_sds_phy_default_event_handler,
- .consume_power_handler = scic_sds_phy_default_consume_power_handler
- },
- [SCI_BASE_PHY_STATE_READY] = {
- .start_handler = scic_sds_phy_default_start_handler,
- .stop_handler = scic_sds_phy_ready_state_stop_handler,
- .reset_handler = scic_sds_phy_ready_state_reset_handler,
- .destruct_handler = scic_sds_phy_default_destroy_handler,
- .frame_handler = scic_sds_phy_default_frame_handler,
- .event_handler = scic_sds_phy_ready_state_event_handler,
- .consume_power_handler = scic_sds_phy_default_consume_power_handler
- },
- [SCI_BASE_PHY_STATE_RESETTING] = {
- .start_handler = scic_sds_phy_default_start_handler,
- .stop_handler = scic_sds_phy_default_stop_handler,
- .reset_handler = scic_sds_phy_default_reset_handler,
- .destruct_handler = scic_sds_phy_default_destroy_handler,
- .frame_handler = scic_sds_phy_default_frame_handler,
- .event_handler = scic_sds_phy_resetting_state_event_handler,
- .consume_power_handler = scic_sds_phy_default_consume_power_handler
- },
- [SCI_BASE_PHY_STATE_FINAL] = {
- .start_handler = scic_sds_phy_default_start_handler,
- .stop_handler = scic_sds_phy_default_stop_handler,
- .reset_handler = scic_sds_phy_default_reset_handler,
- .destruct_handler = scic_sds_phy_default_destroy_handler,
- .frame_handler = scic_sds_phy_default_frame_handler,
- .event_handler = scic_sds_phy_default_event_handler,
- .consume_power_handler = scic_sds_phy_default_consume_power_handler
- }
-};
-
/*
* ****************************************************************************
* * PHY STATE PRIVATE METHODS
@@ -2118,9 +2055,6 @@ static void scic_sds_phy_starting_state_enter(void *object)
sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
sci_phy->bcn_received_while_port_unassigned = false;
- /* Change over to the starting substate machine to continue */
- sci_base_state_machine_start(&sci_phy->starting_substate_machine);
-
if (sci_phy->state_machine.previous_state_id
== SCI_BASE_PHY_STATE_READY) {
scic_sds_controller_link_down(
@@ -2129,6 +2063,9 @@ static void scic_sds_phy_starting_state_enter(void *object)
sci_phy
);
}
+
+ sci_base_state_machine_change_state(&sci_phy->state_machine,
+ SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL);
}
/**
@@ -2231,6 +2168,41 @@ static const struct sci_base_state scic_sds_phy_state_table[] = {
[SCI_BASE_PHY_STATE_STARTING] = {
.enter_state = scic_sds_phy_starting_state_enter,
},
+ [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = {
+ .enter_state = scic_sds_phy_starting_initial_substate_enter,
+ },
+ [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN] = {
+ .enter_state = scic_sds_phy_starting_await_ossp_en_substate_enter,
+ },
+ [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN] = {
+ .enter_state = scic_sds_phy_starting_await_sas_speed_en_substate_enter,
+ },
+ [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF] = {
+ .enter_state = scic_sds_phy_starting_await_iaf_uf_substate_enter,
+ },
+ [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER] = {
+ .enter_state = scic_sds_phy_starting_await_sas_power_substate_enter,
+ .exit_state = scic_sds_phy_starting_await_sas_power_substate_exit,
+ },
+ [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER] = {
+ .enter_state = scic_sds_phy_starting_await_sata_power_substate_enter,
+ .exit_state = scic_sds_phy_starting_await_sata_power_substate_exit
+ },
+ [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN] = {
+ .enter_state = scic_sds_phy_starting_await_sata_phy_substate_enter,
+ .exit_state = scic_sds_phy_starting_await_sata_phy_substate_exit
+ },
+ [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN] = {
+ .enter_state = scic_sds_phy_starting_await_sata_speed_substate_enter,
+ .exit_state = scic_sds_phy_starting_await_sata_speed_substate_exit
+ },
+ [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF] = {
+ .enter_state = scic_sds_phy_starting_await_sig_fis_uf_substate_enter,
+ .exit_state = scic_sds_phy_starting_await_sig_fis_uf_substate_exit
+ },
+ [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL] = {
+ .enter_state = scic_sds_phy_starting_final_substate_enter,
+ },
[SCI_BASE_PHY_STATE_READY] = {
.enter_state = scic_sds_phy_ready_state_enter,
.exit_state = scic_sds_phy_ready_state_exit,
@@ -2261,12 +2233,6 @@ void scic_sds_phy_construct(struct scic_sds_phy *sci_phy,
sci_phy->link_layer_registers = NULL;
sci_phy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;
sci_phy->sata_timeout_timer = NULL;
-
- /* Initialize the the substate machines */
- sci_base_state_machine_construct(&sci_phy->starting_substate_machine,
- sci_phy,
- scic_sds_phy_starting_substates,
- SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL);
}
void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index)