From 4a33c525f0e94b57602abd1e43644cbf6f5418f4 Mon Sep 17 00:00:00 2001 From: Adam Gruchala Date: Tue, 10 May 2011 23:54:23 +0000 Subject: [PATCH] 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 Signed-off-by: Adam Gruchala [fixed construction, starting_state_enter, and starting check] Signed-off-by: Dan Williams --- drivers/scsi/isci/host.c | 24 +- drivers/scsi/isci/phy.c | 500 ++++++++++++++++++--------------------- drivers/scsi/isci/phy.h | 51 ++-- 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. @@ -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 *); -- 2.20.1