Commit c35279f2 authored by John Garry's avatar John Garry Committed by Martin K. Petersen

scsi: hisi_sas: modify hisi_sas_abort_task() for SSP

Currently an internal abort is executed regardless of the result of the
TMF. We should also check the result of the internal abort to see if we
should free the slot.

So change the status code STAT_IO_COMPLETE to TMF_RESP_FUNC_SUCC,
meaning the slot has been successfully aborted.
Signed-off-by: default avatarJohn Garry <john.garry@huawei.com>
Signed-off-by: default avatarXiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent fc866951
...@@ -935,6 +935,7 @@ static int hisi_sas_abort_task(struct sas_task *task) ...@@ -935,6 +935,7 @@ static int hisi_sas_abort_task(struct sas_task *task)
struct scsi_cmnd *cmnd = task->uldd_task; struct scsi_cmnd *cmnd = task->uldd_task;
struct hisi_sas_slot *slot = task->lldd_task; struct hisi_sas_slot *slot = task->lldd_task;
u32 tag = slot->idx; u32 tag = slot->idx;
int rc2;
int_to_scsilun(cmnd->device->lun, &lun); int_to_scsilun(cmnd->device->lun, &lun);
tmf_task.tmf = TMF_ABORT_TASK; tmf_task.tmf = TMF_ABORT_TASK;
...@@ -943,21 +944,22 @@ static int hisi_sas_abort_task(struct sas_task *task) ...@@ -943,21 +944,22 @@ static int hisi_sas_abort_task(struct sas_task *task)
rc = hisi_sas_debug_issue_ssp_tmf(task->dev, lun.scsi_lun, rc = hisi_sas_debug_issue_ssp_tmf(task->dev, lun.scsi_lun,
&tmf_task); &tmf_task);
/* if successful, clear the task and callback forwards.*/ rc2 = hisi_sas_internal_task_abort(hisi_hba, device,
if (rc == TMF_RESP_FUNC_COMPLETE) { HISI_SAS_INT_ABT_CMD, tag);
/*
* If the TMF finds that the IO is not in the device and also
* the internal abort does not succeed, then it is safe to
* free the slot.
* Note: if the internal abort succeeds then the slot
* will have already been completed
*/
if (rc == TMF_RESP_FUNC_COMPLETE && rc2 != TMF_RESP_FUNC_SUCC) {
if (task->lldd_task) { if (task->lldd_task) {
struct hisi_sas_slot *slot;
slot = &hisi_hba->slot_info
[tmf_task.tag_of_task_to_be_managed];
spin_lock_irqsave(&hisi_hba->lock, flags); spin_lock_irqsave(&hisi_hba->lock, flags);
hisi_hba->hw->slot_complete(hisi_hba, slot); hisi_sas_do_release_task(hisi_hba, task, slot);
spin_unlock_irqrestore(&hisi_hba->lock, flags); spin_unlock_irqrestore(&hisi_hba->lock, flags);
} }
} }
hisi_sas_internal_task_abort(hisi_hba, device,
HISI_SAS_INT_ABT_CMD, tag);
} else if (task->task_proto & SAS_PROTOCOL_SATA || } else if (task->task_proto & SAS_PROTOCOL_SATA ||
task->task_proto & SAS_PROTOCOL_STP) { task->task_proto & SAS_PROTOCOL_STP) {
if (task->dev->dev_type == SAS_SATA_DEV) { if (task->dev->dev_type == SAS_SATA_DEV) {
...@@ -1220,6 +1222,12 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, ...@@ -1220,6 +1222,12 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
goto exit; goto exit;
} }
if (task->task_status.resp == SAS_TASK_COMPLETE &&
task->task_status.stat == TMF_RESP_FUNC_SUCC) {
res = TMF_RESP_FUNC_SUCC;
goto exit;
}
/* TMF timed out, return direct. */ /* TMF timed out, return direct. */
if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
......
...@@ -1766,7 +1766,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) ...@@ -1766,7 +1766,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
goto out; goto out;
case STAT_IO_COMPLETE: case STAT_IO_COMPLETE:
/* internal abort command complete */ /* internal abort command complete */
ts->stat = TMF_RESP_FUNC_COMPLETE; ts->stat = TMF_RESP_FUNC_SUCC;
goto out; goto out;
case STAT_IO_NO_DEVICE: case STAT_IO_NO_DEVICE:
ts->stat = TMF_RESP_FUNC_COMPLETE; ts->stat = TMF_RESP_FUNC_COMPLETE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment