isci: merge phy substates
authorAdam Gruchala <adam.gruchala@intel.com>
Tue, 10 May 2011 23:54:23 +0000 (23:54 +0000)
committerDan Williams <dan.j.williams@intel.com>
Sun, 3 Jul 2011 11:04:48 +0000 (04:04 -0700)
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>
drivers/scsi/isci/host.c
drivers/scsi/isci/phy.c
drivers/scsi/isci/phy.h

index 2bb9f10..675eddd 100644 (file)
@@ -932,6 +932,28 @@ static void scic_sds_controller_phy_timer_start(struct scic_sds_controller *scic
        scic->phy_startup_timer_pending = true;
 }
 
+static bool is_phy_starting(struct scic_sds_phy *sci_phy)
+{
+       enum scic_sds_phy_states state;
+
+       state = sci_phy->state_machine.current_state_id;
+       switch (state) {
+       case SCI_BASE_PHY_STATE_STARTING:
+       case SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL:
+       case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN:
+       case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF:
+       case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER:
+       case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER:
+       case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN:
+       case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN:
+       case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF:
+       case SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL:
+               return true;
+       default:
+               return false;
+       }
+}
+
 /**
  * scic_sds_controller_start_next_phy - start phy
  * @scic: controller
@@ -975,7 +997,7 @@ static enum sci_status scic_sds_controller_start_next_phy(struct scic_sds_contro
                            (sci_phy->is_in_link_training == false &&
                             state == SCI_BASE_PHY_STATE_STOPPED) ||
                            (sci_phy->is_in_link_training == true &&
-                            state == SCI_BASE_PHY_STATE_STARTING)) {
+                            is_phy_starting(sci_phy))) {
                                is_controller_start_complete = false;
                                break;
                        }
index 0f64605..e5ae676 100644 (file)
@@ -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)
index f180036..bf02964 100644 (file)
@@ -142,8 +142,6 @@ struct scic_sds_phy {
 
        const struct scic_sds_phy_state_handler *state_handlers;
 
-       struct sci_base_state_machine starting_substate_machine;
-
        /**
         * This field is the pointer to the transport layer register for the SCU
         * hardware.
@@ -435,34 +433,6 @@ enum scic_sds_phy_states {
         */
        SCI_BASE_PHY_STATE_STARTING,
 
-       /**
-        * This state indicates the the phy is now ready.  Thus, the user
-        * is able to perform IO operations utilizing this phy as long as it
-        * is currently part of a valid port.
-        * This state is entered from the STARTING state.
-        */
-       SCI_BASE_PHY_STATE_READY,
-
-       /**
-        * This state indicates that the phy is in the process of being reset.
-        * In this state no new IO operations are permitted on this phy.
-        * This state is entered from the READY state.
-        */
-       SCI_BASE_PHY_STATE_RESETTING,
-
-       /**
-        * Simply the final state for the base phy state machine.
-        */
-       SCI_BASE_PHY_STATE_FINAL,
-};
-
-
-/**
- * enum scic_sds_phy_starting_substates -
- *
- *
- */
-enum scic_sds_phy_starting_substates {
        /**
         * Initial state
         */
@@ -512,8 +482,27 @@ enum scic_sds_phy_starting_substates {
         * Exit state for this state machine
         */
        SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL,
-};
 
+       /**
+        * This state indicates the the phy is now ready.  Thus, the user
+        * is able to perform IO operations utilizing this phy as long as it
+        * is currently part of a valid port.
+        * This state is entered from the STARTING state.
+        */
+       SCI_BASE_PHY_STATE_READY,
+
+       /**
+        * This state indicates that the phy is in the process of being reset.
+        * In this state no new IO operations are permitted on this phy.
+        * This state is entered from the READY state.
+        */
+       SCI_BASE_PHY_STATE_RESETTING,
+
+       /**
+        * Simply the final state for the base phy state machine.
+        */
+       SCI_BASE_PHY_STATE_FINAL,
+};
 
 
 typedef enum sci_status (*scic_sds_phy_handler_t)(struct scic_sds_phy *);