diff options
Diffstat (limited to 'drivers/scsi/isci/request.c')
-rw-r--r-- | drivers/scsi/isci/request.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index a46e07ac789f..b5d3a8c4d329 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
@@ -732,12 +732,20 @@ sci_io_request_terminate(struct isci_request *ireq) | |||
732 | sci_change_state(&ireq->sm, SCI_REQ_ABORTING); | 732 | sci_change_state(&ireq->sm, SCI_REQ_ABORTING); |
733 | return SCI_SUCCESS; | 733 | return SCI_SUCCESS; |
734 | case SCI_REQ_TASK_WAIT_TC_RESP: | 734 | case SCI_REQ_TASK_WAIT_TC_RESP: |
735 | /* The task frame was already confirmed to have been | ||
736 | * sent by the SCU HW. Since the state machine is | ||
737 | * now only waiting for the task response itself, | ||
738 | * abort the request and complete it immediately | ||
739 | * and don't wait for the task response. | ||
740 | */ | ||
735 | sci_change_state(&ireq->sm, SCI_REQ_ABORTING); | 741 | sci_change_state(&ireq->sm, SCI_REQ_ABORTING); |
736 | sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); | 742 | sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); |
737 | return SCI_SUCCESS; | 743 | return SCI_SUCCESS; |
738 | case SCI_REQ_ABORTING: | 744 | case SCI_REQ_ABORTING: |
739 | sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); | 745 | /* If a request has a termination requested twice, return |
740 | return SCI_SUCCESS; | 746 | * a failure indication, since HW confirmation of the first |
747 | * abort is still outstanding. | ||
748 | */ | ||
741 | case SCI_REQ_COMPLETED: | 749 | case SCI_REQ_COMPLETED: |
742 | default: | 750 | default: |
743 | dev_warn(&ireq->owning_controller->pdev->dev, | 751 | dev_warn(&ireq->owning_controller->pdev->dev, |
@@ -2399,22 +2407,19 @@ static void isci_task_save_for_upper_layer_completion( | |||
2399 | } | 2407 | } |
2400 | } | 2408 | } |
2401 | 2409 | ||
2402 | static void isci_request_process_stp_response(struct sas_task *task, | 2410 | static void isci_process_stp_response(struct sas_task *task, struct dev_to_host_fis *fis) |
2403 | void *response_buffer) | ||
2404 | { | 2411 | { |
2405 | struct dev_to_host_fis *d2h_reg_fis = response_buffer; | ||
2406 | struct task_status_struct *ts = &task->task_status; | 2412 | struct task_status_struct *ts = &task->task_status; |
2407 | struct ata_task_resp *resp = (void *)&ts->buf[0]; | 2413 | struct ata_task_resp *resp = (void *)&ts->buf[0]; |
2408 | 2414 | ||
2409 | resp->frame_len = le16_to_cpu(*(__le16 *)(response_buffer + 6)); | 2415 | resp->frame_len = sizeof(*fis); |
2410 | memcpy(&resp->ending_fis[0], response_buffer + 16, 24); | 2416 | memcpy(resp->ending_fis, fis, sizeof(*fis)); |
2411 | ts->buf_valid_size = sizeof(*resp); | 2417 | ts->buf_valid_size = sizeof(*resp); |
2412 | 2418 | ||
2413 | /** | 2419 | /* If the device fault bit is set in the status register, then |
2414 | * If the device fault bit is set in the status register, then | ||
2415 | * set the sense data and return. | 2420 | * set the sense data and return. |
2416 | */ | 2421 | */ |
2417 | if (d2h_reg_fis->status & ATA_DF) | 2422 | if (fis->status & ATA_DF) |
2418 | ts->stat = SAS_PROTO_RESPONSE; | 2423 | ts->stat = SAS_PROTO_RESPONSE; |
2419 | else | 2424 | else |
2420 | ts->stat = SAM_STAT_GOOD; | 2425 | ts->stat = SAM_STAT_GOOD; |
@@ -2428,7 +2433,6 @@ static void isci_request_io_request_complete(struct isci_host *ihost, | |||
2428 | { | 2433 | { |
2429 | struct sas_task *task = isci_request_access_task(request); | 2434 | struct sas_task *task = isci_request_access_task(request); |
2430 | struct ssp_response_iu *resp_iu; | 2435 | struct ssp_response_iu *resp_iu; |
2431 | void *resp_buf; | ||
2432 | unsigned long task_flags; | 2436 | unsigned long task_flags; |
2433 | struct isci_remote_device *idev = isci_lookup_device(task->dev); | 2437 | struct isci_remote_device *idev = isci_lookup_device(task->dev); |
2434 | enum service_response response = SAS_TASK_UNDELIVERED; | 2438 | enum service_response response = SAS_TASK_UNDELIVERED; |
@@ -2565,9 +2569,7 @@ static void isci_request_io_request_complete(struct isci_host *ihost, | |||
2565 | task); | 2569 | task); |
2566 | 2570 | ||
2567 | if (sas_protocol_ata(task->task_proto)) { | 2571 | if (sas_protocol_ata(task->task_proto)) { |
2568 | resp_buf = &request->stp.rsp; | 2572 | isci_process_stp_response(task, &request->stp.rsp); |
2569 | isci_request_process_stp_response(task, | ||
2570 | resp_buf); | ||
2571 | } else if (SAS_PROTOCOL_SSP == task->task_proto) { | 2573 | } else if (SAS_PROTOCOL_SSP == task->task_proto) { |
2572 | 2574 | ||
2573 | /* crack the iu response buffer. */ | 2575 | /* crack the iu response buffer. */ |