diff options
-rw-r--r-- | drivers/scsi/isci/host.c | 24 | ||||
-rw-r--r-- | drivers/scsi/isci/phy.c | 500 | ||||
-rw-r--r-- | 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 2bb9f10..675eddd 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 0f64605..e5ae676 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 f180036..bf02964 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 *); |