diff options
author | Jeff Skirvin <jeffrey.d.skirvin@intel.com> | 2012-03-09 01:42:09 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2012-05-17 17:33:43 -0400 |
commit | 87805162b6af20d2ad386a49aec13b753cca523a (patch) | |
tree | bfe5b09eaa3943636263d8695c946550b883b236 | |
parent | 1f05388933cb6e57ed9e51768c194ff145002f3b (diff) |
isci: Restore the ATAPI device RNC management code.
The ATAPI specific and STP general RNC suspension code had been
incorrectly removed from the remote device code.
Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r-- | drivers/scsi/isci/remote_device.c | 49 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_device.h | 2 | ||||
-rw-r--r-- | drivers/scsi/isci/request.c | 3 |
3 files changed, 34 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) | |||
72 | } | 72 | } |
73 | #undef C | 73 | #undef C |
74 | 74 | ||
75 | static enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev, | 75 | enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev, |
76 | enum sci_remote_node_suspension_reasons reason) | 76 | enum sci_remote_node_suspension_reasons reason) |
77 | { | 77 | { |
78 | return sci_remote_node_context_suspend(&idev->rnc, reason, | 78 | return sci_remote_node_context_suspend(&idev->rnc, reason, |
79 | SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT); | 79 | SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT); |
@@ -565,6 +565,8 @@ enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev, | |||
565 | u32 event_code) | 565 | u32 event_code) |
566 | { | 566 | { |
567 | enum sci_status status; | 567 | enum sci_status status; |
568 | struct sci_base_state_machine *sm = &idev->sm; | ||
569 | enum sci_remote_device_states state = sm->current_state_id; | ||
568 | 570 | ||
569 | switch (scu_get_event_type(event_code)) { | 571 | switch (scu_get_event_type(event_code)) { |
570 | case SCU_EVENT_TYPE_RNC_OPS_MISC: | 572 | case SCU_EVENT_TYPE_RNC_OPS_MISC: |
@@ -603,6 +605,30 @@ enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev, | |||
603 | if (status != SCI_SUCCESS) | 605 | if (status != SCI_SUCCESS) |
604 | return status; | 606 | return status; |
605 | 607 | ||
608 | /* Decode device-specific states that may require an RNC resume during | ||
609 | * normal operation. When the abort path is active, these resumes are | ||
610 | * managed when the abort path exits. | ||
611 | */ | ||
612 | if (state == SCI_STP_DEV_ATAPI_ERROR) { | ||
613 | /* For ATAPI error state resume the RNC right away. */ | ||
614 | if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX || | ||
615 | scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) { | ||
616 | return sci_remote_node_context_resume(&idev->rnc, | ||
617 | atapi_remote_device_resume_done, | ||
618 | idev); | ||
619 | } | ||
620 | } | ||
621 | |||
622 | if (state == SCI_STP_DEV_IDLE) { | ||
623 | |||
624 | /* We pick up suspension events to handle specifically to this | ||
625 | * state. We resume the RNC right away. | ||
626 | */ | ||
627 | if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX || | ||
628 | scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) | ||
629 | status = sci_remote_node_context_resume(&idev->rnc, NULL, NULL); | ||
630 | } | ||
631 | |||
606 | return status; | 632 | return status; |
607 | } | 633 | } |
608 | 634 | ||
@@ -1137,21 +1163,6 @@ static void sci_stp_remote_device_ready_ncq_error_substate_enter(struct sci_base | |||
1137 | idev->not_ready_reason); | 1163 | idev->not_ready_reason); |
1138 | } | 1164 | } |
1139 | 1165 | ||
1140 | static void sci_stp_remote_device_atapi_error_substate_enter( | ||
1141 | struct sci_base_state_machine *sm) | ||
1142 | { | ||
1143 | struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm); | ||
1144 | |||
1145 | /* This state is entered when an I/O is decoded with an error | ||
1146 | * condition. By this point the RNC expected suspension state is set. | ||
1147 | * The error conditions suspend the device, so unsuspend here if | ||
1148 | * possible. | ||
1149 | */ | ||
1150 | sci_remote_node_context_resume(&idev->rnc, | ||
1151 | atapi_remote_device_resume_done, | ||
1152 | idev); | ||
1153 | } | ||
1154 | |||
1155 | static void sci_smp_remote_device_ready_idle_substate_enter(struct sci_base_state_machine *sm) | 1166 | static void sci_smp_remote_device_ready_idle_substate_enter(struct sci_base_state_machine *sm) |
1156 | { | 1167 | { |
1157 | struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm); | 1168 | 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[] = { | |||
1202 | [SCI_STP_DEV_NCQ_ERROR] = { | 1213 | [SCI_STP_DEV_NCQ_ERROR] = { |
1203 | .enter_state = sci_stp_remote_device_ready_ncq_error_substate_enter, | 1214 | .enter_state = sci_stp_remote_device_ready_ncq_error_substate_enter, |
1204 | }, | 1215 | }, |
1205 | [SCI_STP_DEV_ATAPI_ERROR] = { | 1216 | [SCI_STP_DEV_ATAPI_ERROR] = { }, |
1206 | .enter_state = sci_stp_remote_device_atapi_error_substate_enter, | ||
1207 | }, | ||
1208 | [SCI_STP_DEV_AWAIT_RESET] = { }, | 1217 | [SCI_STP_DEV_AWAIT_RESET] = { }, |
1209 | [SCI_SMP_DEV_IDLE] = { | 1218 | [SCI_SMP_DEV_IDLE] = { |
1210 | .enter_state = sci_smp_remote_device_ready_idle_substate_enter, | 1219 | .enter_state = sci_smp_remote_device_ready_idle_substate_enter, |
diff --git a/drivers/scsi/isci/remote_device.h b/drivers/scsi/isci/remote_device.h index ff34c4e8c1b1..7674caae1d88 100644 --- a/drivers/scsi/isci/remote_device.h +++ b/drivers/scsi/isci/remote_device.h | |||
@@ -382,4 +382,6 @@ enum sci_status isci_remote_device_terminate_requests( | |||
382 | struct isci_host *ihost, | 382 | struct isci_host *ihost, |
383 | struct isci_remote_device *idev, | 383 | struct isci_remote_device *idev, |
384 | struct isci_request *ireq); | 384 | struct isci_request *ireq); |
385 | enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev, | ||
386 | enum sci_remote_node_suspension_reasons reason); | ||
385 | #endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */ | 387 | #endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */ |
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 415d5f55d1c6..6c530e4275e2 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
@@ -2118,6 +2118,9 @@ static enum sci_status stp_request_udma_await_tc_event(struct isci_request *ireq | |||
2118 | * completion. | 2118 | * completion. |
2119 | */ | 2119 | */ |
2120 | if (ireq->stp.rsp.fis_type == FIS_REGD2H) { | 2120 | if (ireq->stp.rsp.fis_type == FIS_REGD2H) { |
2121 | sci_remote_device_suspend(ireq->target_device, | ||
2122 | SCI_SW_SUSPEND_NORMAL); | ||
2123 | |||
2121 | ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE; | 2124 | ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE; |
2122 | ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID; | 2125 | ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID; |
2123 | sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); | 2126 | sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); |