diff options
Diffstat (limited to 'drivers/scsi/isci/remote_device.c')
-rw-r--r-- | drivers/scsi/isci/remote_device.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index 68ab4fb9032e..48765aa84328 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c @@ -72,8 +72,8 @@ const char *dev_state_name(enum sci_remote_device_states state) } #undef C -static enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev, - enum sci_remote_node_suspension_reasons reason) +enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev, + enum sci_remote_node_suspension_reasons reason) { return sci_remote_node_context_suspend(&idev->rnc, reason, SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT); @@ -565,6 +565,8 @@ enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev, u32 event_code) { enum sci_status status; + struct sci_base_state_machine *sm = &idev->sm; + enum sci_remote_device_states state = sm->current_state_id; switch (scu_get_event_type(event_code)) { case SCU_EVENT_TYPE_RNC_OPS_MISC: @@ -603,6 +605,30 @@ enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev, if (status != SCI_SUCCESS) return status; + /* Decode device-specific states that may require an RNC resume during + * normal operation. When the abort path is active, these resumes are + * managed when the abort path exits. + */ + if (state == SCI_STP_DEV_ATAPI_ERROR) { + /* For ATAPI error state resume the RNC right away. */ + if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX || + scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) { + return sci_remote_node_context_resume(&idev->rnc, + atapi_remote_device_resume_done, + idev); + } + } + + if (state == SCI_STP_DEV_IDLE) { + + /* We pick up suspension events to handle specifically to this + * state. We resume the RNC right away. + */ + if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX || + scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) + status = sci_remote_node_context_resume(&idev->rnc, NULL, NULL); + } + return status; } @@ -1137,21 +1163,6 @@ static void sci_stp_remote_device_ready_ncq_error_substate_enter(struct sci_base idev->not_ready_reason); } -static void sci_stp_remote_device_atapi_error_substate_enter( - struct sci_base_state_machine *sm) -{ - struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm); - - /* This state is entered when an I/O is decoded with an error - * condition. By this point the RNC expected suspension state is set. - * The error conditions suspend the device, so unsuspend here if - * possible. - */ - sci_remote_node_context_resume(&idev->rnc, - atapi_remote_device_resume_done, - idev); -} - static void sci_smp_remote_device_ready_idle_substate_enter(struct sci_base_state_machine *sm) { struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm); @@ -1202,9 +1213,7 @@ static const struct sci_base_state sci_remote_device_state_table[] = { [SCI_STP_DEV_NCQ_ERROR] = { .enter_state = sci_stp_remote_device_ready_ncq_error_substate_enter, }, - [SCI_STP_DEV_ATAPI_ERROR] = { - .enter_state = sci_stp_remote_device_atapi_error_substate_enter, - }, + [SCI_STP_DEV_ATAPI_ERROR] = { }, [SCI_STP_DEV_AWAIT_RESET] = { }, [SCI_SMP_DEV_IDLE] = { .enter_state = sci_smp_remote_device_ready_idle_substate_enter, |