diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-12-09 02:20:44 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-29 16:13:40 -0500 |
commit | 43a5ab151f0268459c4368292c2ddb2266b8f243 (patch) | |
tree | e8ee97e0d49bc0c454ca90f16a836fd01830b11f /drivers | |
parent | 9277699121b81891e303ada0a53fa1d04b7ffe72 (diff) |
[SCSI] isci: stop interpreting ->lldd_lu_reset() as an ata soft-reset
Driving resets from libsas-eh is pre-mature as libata will make a
decision about performing a softreset. Currently libata determines
whether to perform a softreset based on ata_eh_followup_srst_needed(),
and none of those conditions apply to isci.
Remove the srst implementation and translate ->lldd_lu_reset() for ata
devices as a request to drive a reset via libata-eh.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/isci/request.c | 195 | ||||
-rw-r--r-- | drivers/scsi/isci/request.h | 9 | ||||
-rw-r--r-- | drivers/scsi/isci/task.c | 93 | ||||
-rw-r--r-- | drivers/scsi/isci/task.h | 2 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_ata.c | 2 |
5 files changed, 15 insertions, 286 deletions
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 788daeedc89f..1a39ce50529d 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
@@ -666,18 +666,12 @@ sci_io_request_construct_sata(struct isci_request *ireq, | |||
666 | if (test_bit(IREQ_TMF, &ireq->flags)) { | 666 | if (test_bit(IREQ_TMF, &ireq->flags)) { |
667 | struct isci_tmf *tmf = isci_request_access_tmf(ireq); | 667 | struct isci_tmf *tmf = isci_request_access_tmf(ireq); |
668 | 668 | ||
669 | if (tmf->tmf_code == isci_tmf_sata_srst_high || | 669 | dev_err(&ireq->owning_controller->pdev->dev, |
670 | tmf->tmf_code == isci_tmf_sata_srst_low) { | 670 | "%s: Request 0x%p received un-handled SAT " |
671 | scu_stp_raw_request_construct_task_context(ireq); | 671 | "management protocol 0x%x.\n", |
672 | return SCI_SUCCESS; | 672 | __func__, ireq, tmf->tmf_code); |
673 | } else { | ||
674 | dev_err(&ireq->owning_controller->pdev->dev, | ||
675 | "%s: Request 0x%p received un-handled SAT " | ||
676 | "management protocol 0x%x.\n", | ||
677 | __func__, ireq, tmf->tmf_code); | ||
678 | 673 | ||
679 | return SCI_FAILURE; | 674 | return SCI_FAILURE; |
680 | } | ||
681 | } | 675 | } |
682 | 676 | ||
683 | if (!sas_protocol_ata(task->task_proto)) { | 677 | if (!sas_protocol_ata(task->task_proto)) { |
@@ -774,34 +768,6 @@ static enum sci_status sci_io_request_construct_basic_sata(struct isci_request * | |||
774 | return status; | 768 | return status; |
775 | } | 769 | } |
776 | 770 | ||
777 | enum sci_status sci_task_request_construct_sata(struct isci_request *ireq) | ||
778 | { | ||
779 | enum sci_status status = SCI_SUCCESS; | ||
780 | |||
781 | /* check for management protocols */ | ||
782 | if (test_bit(IREQ_TMF, &ireq->flags)) { | ||
783 | struct isci_tmf *tmf = isci_request_access_tmf(ireq); | ||
784 | |||
785 | if (tmf->tmf_code == isci_tmf_sata_srst_high || | ||
786 | tmf->tmf_code == isci_tmf_sata_srst_low) { | ||
787 | scu_stp_raw_request_construct_task_context(ireq); | ||
788 | } else { | ||
789 | dev_err(&ireq->owning_controller->pdev->dev, | ||
790 | "%s: Request 0x%p received un-handled SAT " | ||
791 | "Protocol 0x%x.\n", | ||
792 | __func__, ireq, tmf->tmf_code); | ||
793 | |||
794 | return SCI_FAILURE; | ||
795 | } | ||
796 | } | ||
797 | |||
798 | if (status != SCI_SUCCESS) | ||
799 | return status; | ||
800 | sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED); | ||
801 | |||
802 | return status; | ||
803 | } | ||
804 | |||
805 | /** | 771 | /** |
806 | * sci_req_tx_bytes - bytes transferred when reply underruns request | 772 | * sci_req_tx_bytes - bytes transferred when reply underruns request |
807 | * @ireq: request that was terminated early | 773 | * @ireq: request that was terminated early |
@@ -903,9 +869,6 @@ sci_io_request_terminate(struct isci_request *ireq) | |||
903 | case SCI_REQ_STP_PIO_WAIT_FRAME: | 869 | case SCI_REQ_STP_PIO_WAIT_FRAME: |
904 | case SCI_REQ_STP_PIO_DATA_IN: | 870 | case SCI_REQ_STP_PIO_DATA_IN: |
905 | case SCI_REQ_STP_PIO_DATA_OUT: | 871 | case SCI_REQ_STP_PIO_DATA_OUT: |
906 | case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED: | ||
907 | case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG: | ||
908 | case SCI_REQ_STP_SOFT_RESET_WAIT_D2H: | ||
909 | case SCI_REQ_ATAPI_WAIT_H2D: | 872 | case SCI_REQ_ATAPI_WAIT_H2D: |
910 | case SCI_REQ_ATAPI_WAIT_PIO_SETUP: | 873 | case SCI_REQ_ATAPI_WAIT_PIO_SETUP: |
911 | case SCI_REQ_ATAPI_WAIT_D2H: | 874 | case SCI_REQ_ATAPI_WAIT_D2H: |
@@ -2085,59 +2048,6 @@ sci_io_request_frame_handler(struct isci_request *ireq, | |||
2085 | return status; | 2048 | return status; |
2086 | } | 2049 | } |
2087 | 2050 | ||
2088 | case SCI_REQ_STP_SOFT_RESET_WAIT_D2H: { | ||
2089 | struct dev_to_host_fis *frame_header; | ||
2090 | u32 *frame_buffer; | ||
2091 | |||
2092 | status = sci_unsolicited_frame_control_get_header(&ihost->uf_control, | ||
2093 | frame_index, | ||
2094 | (void **)&frame_header); | ||
2095 | if (status != SCI_SUCCESS) { | ||
2096 | dev_err(&ihost->pdev->dev, | ||
2097 | "%s: SCIC IO Request 0x%p could not get frame " | ||
2098 | "header for frame index %d, status %x\n", | ||
2099 | __func__, | ||
2100 | stp_req, | ||
2101 | frame_index, | ||
2102 | status); | ||
2103 | return status; | ||
2104 | } | ||
2105 | |||
2106 | switch (frame_header->fis_type) { | ||
2107 | case FIS_REGD2H: | ||
2108 | sci_unsolicited_frame_control_get_buffer(&ihost->uf_control, | ||
2109 | frame_index, | ||
2110 | (void **)&frame_buffer); | ||
2111 | |||
2112 | sci_controller_copy_sata_response(&ireq->stp.rsp, | ||
2113 | frame_header, | ||
2114 | frame_buffer); | ||
2115 | |||
2116 | /* The command has completed with error */ | ||
2117 | ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE; | ||
2118 | ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID; | ||
2119 | break; | ||
2120 | |||
2121 | default: | ||
2122 | dev_warn(&ihost->pdev->dev, | ||
2123 | "%s: IO Request:0x%p Frame Id:%d protocol " | ||
2124 | "violation occurred\n", | ||
2125 | __func__, | ||
2126 | stp_req, | ||
2127 | frame_index); | ||
2128 | |||
2129 | ireq->scu_status = SCU_TASK_DONE_UNEXP_FIS; | ||
2130 | ireq->sci_status = SCI_FAILURE_PROTOCOL_VIOLATION; | ||
2131 | break; | ||
2132 | } | ||
2133 | |||
2134 | sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); | ||
2135 | |||
2136 | /* Frame has been decoded return it to the controller */ | ||
2137 | sci_controller_release_frame(ihost, frame_index); | ||
2138 | |||
2139 | return status; | ||
2140 | } | ||
2141 | case SCI_REQ_ATAPI_WAIT_PIO_SETUP: { | 2051 | case SCI_REQ_ATAPI_WAIT_PIO_SETUP: { |
2142 | struct sas_task *task = isci_request_access_task(ireq); | 2052 | struct sas_task *task = isci_request_access_task(ireq); |
2143 | 2053 | ||
@@ -2235,57 +2145,6 @@ static enum sci_status stp_request_udma_await_tc_event(struct isci_request *ireq | |||
2235 | return status; | 2145 | return status; |
2236 | } | 2146 | } |
2237 | 2147 | ||
2238 | static enum sci_status | ||
2239 | stp_request_soft_reset_await_h2d_asserted_tc_event(struct isci_request *ireq, | ||
2240 | u32 completion_code) | ||
2241 | { | ||
2242 | switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) { | ||
2243 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): | ||
2244 | ireq->scu_status = SCU_TASK_DONE_GOOD; | ||
2245 | ireq->sci_status = SCI_SUCCESS; | ||
2246 | sci_change_state(&ireq->sm, SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG); | ||
2247 | break; | ||
2248 | |||
2249 | default: | ||
2250 | /* | ||
2251 | * All other completion status cause the IO to be complete. | ||
2252 | * If a NAK was received, then it is up to the user to retry | ||
2253 | * the request. | ||
2254 | */ | ||
2255 | ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code); | ||
2256 | ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR; | ||
2257 | sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); | ||
2258 | break; | ||
2259 | } | ||
2260 | |||
2261 | return SCI_SUCCESS; | ||
2262 | } | ||
2263 | |||
2264 | static enum sci_status | ||
2265 | stp_request_soft_reset_await_h2d_diagnostic_tc_event(struct isci_request *ireq, | ||
2266 | u32 completion_code) | ||
2267 | { | ||
2268 | switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) { | ||
2269 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): | ||
2270 | ireq->scu_status = SCU_TASK_DONE_GOOD; | ||
2271 | ireq->sci_status = SCI_SUCCESS; | ||
2272 | sci_change_state(&ireq->sm, SCI_REQ_STP_SOFT_RESET_WAIT_D2H); | ||
2273 | break; | ||
2274 | |||
2275 | default: | ||
2276 | /* All other completion status cause the IO to be complete. If | ||
2277 | * a NAK was received, then it is up to the user to retry the | ||
2278 | * request. | ||
2279 | */ | ||
2280 | ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code); | ||
2281 | ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR; | ||
2282 | sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); | ||
2283 | break; | ||
2284 | } | ||
2285 | |||
2286 | return SCI_SUCCESS; | ||
2287 | } | ||
2288 | |||
2289 | static enum sci_status atapi_raw_completion(struct isci_request *ireq, u32 completion_code, | 2148 | static enum sci_status atapi_raw_completion(struct isci_request *ireq, u32 completion_code, |
2290 | enum sci_base_request_states next) | 2149 | enum sci_base_request_states next) |
2291 | { | 2150 | { |
@@ -2431,14 +2290,6 @@ sci_io_request_tc_completion(struct isci_request *ireq, | |||
2431 | case SCI_REQ_STP_PIO_DATA_OUT: | 2290 | case SCI_REQ_STP_PIO_DATA_OUT: |
2432 | return pio_data_out_tx_done_tc_event(ireq, completion_code); | 2291 | return pio_data_out_tx_done_tc_event(ireq, completion_code); |
2433 | 2292 | ||
2434 | case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED: | ||
2435 | return stp_request_soft_reset_await_h2d_asserted_tc_event(ireq, | ||
2436 | completion_code); | ||
2437 | |||
2438 | case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG: | ||
2439 | return stp_request_soft_reset_await_h2d_diagnostic_tc_event(ireq, | ||
2440 | completion_code); | ||
2441 | |||
2442 | case SCI_REQ_ABORTING: | 2293 | case SCI_REQ_ABORTING: |
2443 | return request_aborting_state_tc_event(ireq, | 2294 | return request_aborting_state_tc_event(ireq, |
2444 | completion_code); | 2295 | completion_code); |
@@ -3212,10 +3063,6 @@ static void sci_request_started_state_enter(struct sci_base_state_machine *sm) | |||
3212 | */ | 3063 | */ |
3213 | if (!task && dev->dev_type == SAS_END_DEV) { | 3064 | if (!task && dev->dev_type == SAS_END_DEV) { |
3214 | state = SCI_REQ_TASK_WAIT_TC_COMP; | 3065 | state = SCI_REQ_TASK_WAIT_TC_COMP; |
3215 | } else if (!task && | ||
3216 | (isci_request_access_tmf(ireq)->tmf_code == isci_tmf_sata_srst_high || | ||
3217 | isci_request_access_tmf(ireq)->tmf_code == isci_tmf_sata_srst_low)) { | ||
3218 | state = SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED; | ||
3219 | } else if (task && task->task_proto == SAS_PROTOCOL_SMP) { | 3066 | } else if (task && task->task_proto == SAS_PROTOCOL_SMP) { |
3220 | state = SCI_REQ_SMP_WAIT_RESP; | 3067 | state = SCI_REQ_SMP_WAIT_RESP; |
3221 | } else if (task && sas_protocol_ata(task->task_proto) && | 3068 | } else if (task && sas_protocol_ata(task->task_proto) && |
@@ -3272,31 +3119,6 @@ static void sci_stp_request_started_pio_await_h2d_completion_enter(struct sci_ba | |||
3272 | ireq->target_device->working_request = ireq; | 3119 | ireq->target_device->working_request = ireq; |
3273 | } | 3120 | } |
3274 | 3121 | ||
3275 | static void sci_stp_request_started_soft_reset_await_h2d_asserted_completion_enter(struct sci_base_state_machine *sm) | ||
3276 | { | ||
3277 | struct isci_request *ireq = container_of(sm, typeof(*ireq), sm); | ||
3278 | |||
3279 | ireq->target_device->working_request = ireq; | ||
3280 | } | ||
3281 | |||
3282 | static void sci_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter(struct sci_base_state_machine *sm) | ||
3283 | { | ||
3284 | struct isci_request *ireq = container_of(sm, typeof(*ireq), sm); | ||
3285 | struct scu_task_context *tc = ireq->tc; | ||
3286 | struct host_to_dev_fis *h2d_fis; | ||
3287 | enum sci_status status; | ||
3288 | |||
3289 | /* Clear the SRST bit */ | ||
3290 | h2d_fis = &ireq->stp.cmd; | ||
3291 | h2d_fis->control = 0; | ||
3292 | |||
3293 | /* Clear the TC control bit */ | ||
3294 | tc->control_frame = 0; | ||
3295 | |||
3296 | status = sci_controller_continue_io(ireq); | ||
3297 | WARN_ONCE(status != SCI_SUCCESS, "isci: continue io failure\n"); | ||
3298 | } | ||
3299 | |||
3300 | static const struct sci_base_state sci_request_state_table[] = { | 3122 | static const struct sci_base_state sci_request_state_table[] = { |
3301 | [SCI_REQ_INIT] = { }, | 3123 | [SCI_REQ_INIT] = { }, |
3302 | [SCI_REQ_CONSTRUCTED] = { }, | 3124 | [SCI_REQ_CONSTRUCTED] = { }, |
@@ -3315,13 +3137,6 @@ static const struct sci_base_state sci_request_state_table[] = { | |||
3315 | [SCI_REQ_STP_PIO_DATA_OUT] = { }, | 3137 | [SCI_REQ_STP_PIO_DATA_OUT] = { }, |
3316 | [SCI_REQ_STP_UDMA_WAIT_TC_COMP] = { }, | 3138 | [SCI_REQ_STP_UDMA_WAIT_TC_COMP] = { }, |
3317 | [SCI_REQ_STP_UDMA_WAIT_D2H] = { }, | 3139 | [SCI_REQ_STP_UDMA_WAIT_D2H] = { }, |
3318 | [SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED] = { | ||
3319 | .enter_state = sci_stp_request_started_soft_reset_await_h2d_asserted_completion_enter, | ||
3320 | }, | ||
3321 | [SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG] = { | ||
3322 | .enter_state = sci_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter, | ||
3323 | }, | ||
3324 | [SCI_REQ_STP_SOFT_RESET_WAIT_D2H] = { }, | ||
3325 | [SCI_REQ_TASK_WAIT_TC_COMP] = { }, | 3140 | [SCI_REQ_TASK_WAIT_TC_COMP] = { }, |
3326 | [SCI_REQ_TASK_WAIT_TC_RESP] = { }, | 3141 | [SCI_REQ_TASK_WAIT_TC_RESP] = { }, |
3327 | [SCI_REQ_SMP_WAIT_RESP] = { }, | 3142 | [SCI_REQ_SMP_WAIT_RESP] = { }, |
diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h index be38933dd6df..bcf2f37f23e1 100644 --- a/drivers/scsi/isci/request.h +++ b/drivers/scsi/isci/request.h | |||
@@ -211,10 +211,6 @@ enum sci_base_request_states { | |||
211 | SCI_REQ_STP_NON_DATA_WAIT_H2D, | 211 | SCI_REQ_STP_NON_DATA_WAIT_H2D, |
212 | SCI_REQ_STP_NON_DATA_WAIT_D2H, | 212 | SCI_REQ_STP_NON_DATA_WAIT_D2H, |
213 | 213 | ||
214 | SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED, | ||
215 | SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG, | ||
216 | SCI_REQ_STP_SOFT_RESET_WAIT_D2H, | ||
217 | |||
218 | /* | 214 | /* |
219 | * While in this state the IO request object is waiting for the TC | 215 | * While in this state the IO request object is waiting for the TC |
220 | * completion notification for the H2D Register FIS | 216 | * completion notification for the H2D Register FIS |
@@ -446,10 +442,7 @@ sci_task_request_construct(struct isci_host *ihost, | |||
446 | struct isci_remote_device *idev, | 442 | struct isci_remote_device *idev, |
447 | u16 io_tag, | 443 | u16 io_tag, |
448 | struct isci_request *ireq); | 444 | struct isci_request *ireq); |
449 | enum sci_status | 445 | enum sci_status sci_task_request_construct_ssp(struct isci_request *ireq); |
450 | sci_task_request_construct_ssp(struct isci_request *ireq); | ||
451 | enum sci_status | ||
452 | sci_task_request_construct_sata(struct isci_request *ireq); | ||
453 | void sci_smp_request_copy_response(struct isci_request *ireq); | 446 | void sci_smp_request_copy_response(struct isci_request *ireq); |
454 | 447 | ||
455 | static inline int isci_task_is_ncq_recovery(struct sas_task *task) | 448 | static inline int isci_task_is_ncq_recovery(struct sas_task *task) |
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index c4d324ccee11..3f04e97128a6 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c | |||
@@ -247,46 +247,6 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) | |||
247 | return 0; | 247 | return 0; |
248 | } | 248 | } |
249 | 249 | ||
250 | static enum sci_status isci_sata_management_task_request_build(struct isci_request *ireq) | ||
251 | { | ||
252 | struct isci_tmf *isci_tmf; | ||
253 | enum sci_status status; | ||
254 | |||
255 | if (!test_bit(IREQ_TMF, &ireq->flags)) | ||
256 | return SCI_FAILURE; | ||
257 | |||
258 | isci_tmf = isci_request_access_tmf(ireq); | ||
259 | |||
260 | switch (isci_tmf->tmf_code) { | ||
261 | |||
262 | case isci_tmf_sata_srst_high: | ||
263 | case isci_tmf_sata_srst_low: { | ||
264 | struct host_to_dev_fis *fis = &ireq->stp.cmd; | ||
265 | |||
266 | memset(fis, 0, sizeof(*fis)); | ||
267 | |||
268 | fis->fis_type = 0x27; | ||
269 | fis->flags &= ~0x80; | ||
270 | fis->flags &= 0xF0; | ||
271 | if (isci_tmf->tmf_code == isci_tmf_sata_srst_high) | ||
272 | fis->control |= ATA_SRST; | ||
273 | else | ||
274 | fis->control &= ~ATA_SRST; | ||
275 | break; | ||
276 | } | ||
277 | /* other management commnd go here... */ | ||
278 | default: | ||
279 | return SCI_FAILURE; | ||
280 | } | ||
281 | |||
282 | /* core builds the protocol specific request | ||
283 | * based on the h2d fis. | ||
284 | */ | ||
285 | status = sci_task_request_construct_sata(ireq); | ||
286 | |||
287 | return status; | ||
288 | } | ||
289 | |||
290 | static struct isci_request *isci_task_request_build(struct isci_host *ihost, | 250 | static struct isci_request *isci_task_request_build(struct isci_host *ihost, |
291 | struct isci_remote_device *idev, | 251 | struct isci_remote_device *idev, |
292 | u16 tag, struct isci_tmf *isci_tmf) | 252 | u16 tag, struct isci_tmf *isci_tmf) |
@@ -326,13 +286,6 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost, | |||
326 | return NULL; | 286 | return NULL; |
327 | } | 287 | } |
328 | 288 | ||
329 | if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { | ||
330 | isci_tmf->proto = SAS_PROTOCOL_SATA; | ||
331 | status = isci_sata_management_task_request_build(ireq); | ||
332 | |||
333 | if (status != SCI_SUCCESS) | ||
334 | return NULL; | ||
335 | } | ||
336 | return ireq; | 289 | return ireq; |
337 | } | 290 | } |
338 | 291 | ||
@@ -871,53 +824,20 @@ static int isci_task_send_lu_reset_sas( | |||
871 | return ret; | 824 | return ret; |
872 | } | 825 | } |
873 | 826 | ||
874 | static int isci_task_send_lu_reset_sata(struct isci_host *ihost, | 827 | int isci_task_lu_reset(struct domain_device *dev, u8 *lun) |
875 | struct isci_remote_device *idev, u8 *lun) | ||
876 | { | 828 | { |
877 | int ret = TMF_RESP_FUNC_FAILED; | 829 | struct isci_host *isci_host = dev_to_ihost(dev); |
878 | struct isci_tmf tmf; | ||
879 | |||
880 | /* Send the soft reset to the target */ | ||
881 | #define ISCI_SRST_TIMEOUT_MS 25000 /* 25 second timeout. */ | ||
882 | isci_task_build_tmf(&tmf, isci_tmf_sata_srst_high, NULL, NULL); | ||
883 | |||
884 | ret = isci_task_execute_tmf(ihost, idev, &tmf, ISCI_SRST_TIMEOUT_MS); | ||
885 | |||
886 | if (ret != TMF_RESP_FUNC_COMPLETE) { | ||
887 | dev_dbg(&ihost->pdev->dev, | ||
888 | "%s: Assert SRST failed (%p) = %x", | ||
889 | __func__, idev, ret); | ||
890 | |||
891 | /* Return the failure so that the LUN reset is escalated | ||
892 | * to a target reset. | ||
893 | */ | ||
894 | } | ||
895 | return ret; | ||
896 | } | ||
897 | |||
898 | /** | ||
899 | * isci_task_lu_reset() - This function is one of the SAS Domain Template | ||
900 | * functions. This is one of the Task Management functoins called by libsas, | ||
901 | * to reset the given lun. Note the assumption that while this call is | ||
902 | * executing, no I/O will be sent by the host to the device. | ||
903 | * @lun: This parameter specifies the lun to be reset. | ||
904 | * | ||
905 | * status, zero indicates success. | ||
906 | */ | ||
907 | int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun) | ||
908 | { | ||
909 | struct isci_host *isci_host = dev_to_ihost(domain_device); | ||
910 | struct isci_remote_device *isci_device; | 830 | struct isci_remote_device *isci_device; |
911 | unsigned long flags; | 831 | unsigned long flags; |
912 | int ret; | 832 | int ret; |
913 | 833 | ||
914 | spin_lock_irqsave(&isci_host->scic_lock, flags); | 834 | spin_lock_irqsave(&isci_host->scic_lock, flags); |
915 | isci_device = isci_lookup_device(domain_device); | 835 | isci_device = isci_lookup_device(dev); |
916 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); | 836 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); |
917 | 837 | ||
918 | dev_dbg(&isci_host->pdev->dev, | 838 | dev_dbg(&isci_host->pdev->dev, |
919 | "%s: domain_device=%p, isci_host=%p; isci_device=%p\n", | 839 | "%s: domain_device=%p, isci_host=%p; isci_device=%p\n", |
920 | __func__, domain_device, isci_host, isci_device); | 840 | __func__, dev, isci_host, isci_device); |
921 | 841 | ||
922 | if (!isci_device) { | 842 | if (!isci_device) { |
923 | /* If the device is gone, stop the escalations. */ | 843 | /* If the device is gone, stop the escalations. */ |
@@ -929,8 +849,9 @@ int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun) | |||
929 | set_bit(IDEV_EH, &isci_device->flags); | 849 | set_bit(IDEV_EH, &isci_device->flags); |
930 | 850 | ||
931 | /* Send the task management part of the reset. */ | 851 | /* Send the task management part of the reset. */ |
932 | if (sas_protocol_ata(domain_device->tproto)) { | 852 | if (dev_is_sata(dev)) { |
933 | ret = isci_task_send_lu_reset_sata(isci_host, isci_device, lun); | 853 | sas_ata_schedule_reset(dev); |
854 | ret = TMF_RESP_FUNC_COMPLETE; | ||
934 | } else | 855 | } else |
935 | ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun); | 856 | ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun); |
936 | 857 | ||
diff --git a/drivers/scsi/isci/task.h b/drivers/scsi/isci/task.h index bb472c339523..5ba00c3081f4 100644 --- a/drivers/scsi/isci/task.h +++ b/drivers/scsi/isci/task.h | |||
@@ -86,8 +86,6 @@ enum isci_tmf_function_codes { | |||
86 | isci_tmf_func_none = 0, | 86 | isci_tmf_func_none = 0, |
87 | isci_tmf_ssp_task_abort = TMF_ABORT_TASK, | 87 | isci_tmf_ssp_task_abort = TMF_ABORT_TASK, |
88 | isci_tmf_ssp_lun_reset = TMF_LU_RESET, | 88 | isci_tmf_ssp_lun_reset = TMF_LU_RESET, |
89 | isci_tmf_sata_srst_high = TMF_LU_RESET + 0x100, /* Non SCSI */ | ||
90 | isci_tmf_sata_srst_low = TMF_LU_RESET + 0x101 /* Non SCSI */ | ||
91 | }; | 89 | }; |
92 | /** | 90 | /** |
93 | * struct isci_tmf - This class represents the task management object which | 91 | * struct isci_tmf - This class represents the task management object which |
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 0cb538f8478a..37a9e73870d4 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/scatterlist.h> | 24 | #include <linux/scatterlist.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/async.h> | 26 | #include <linux/async.h> |
27 | #include <linux/export.h> | ||
27 | 28 | ||
28 | #include <scsi/sas_ata.h> | 29 | #include <scsi/sas_ata.h> |
29 | #include "sas_internal.h" | 30 | #include "sas_internal.h" |
@@ -757,6 +758,7 @@ void sas_ata_schedule_reset(struct domain_device *dev) | |||
757 | ata_port_schedule_eh(ap); | 758 | ata_port_schedule_eh(ap); |
758 | spin_unlock_irqrestore(ap->lock, flags); | 759 | spin_unlock_irqrestore(ap->lock, flags); |
759 | } | 760 | } |
761 | EXPORT_SYMBOL_GPL(sas_ata_schedule_reset); | ||
760 | 762 | ||
761 | void sas_ata_wait_eh(struct domain_device *dev) | 763 | void sas_ata_wait_eh(struct domain_device *dev) |
762 | { | 764 | { |