summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/isci/host.c24
-rw-r--r--drivers/scsi/isci/phy.c500
-rw-r--r--drivers/scsi/isci/phy.h51
3 files changed, 276 insertions, 299 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 2bb9f1073e73..675eddd3963e 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -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;
}
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)
diff --git a/drivers/scsi/isci/phy.h b/drivers/scsi/isci/phy.h
index f1800368eda5..bf0296463c80 100644
--- a/drivers/scsi/isci/phy.h
+++ b/drivers/scsi/isci/phy.h
@@ -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.
@@ -436,34 +434,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
*/
SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL,
@@ -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 *);