summaryrefslogtreecommitdiff
path: root/drivers/scsi/hisi_sas
diff options
context:
space:
mode:
authorJohn Garry <john.garry@huawei.com>2017-03-22 20:25:25 +0300
committerMartin K. Petersen <martin.petersen@oracle.com>2017-03-23 18:12:02 +0300
commitc35279f2f1eef8f7f91b2b529fc22f01b25a244f (patch)
treecbba7f92a95b4edb851b56583d49054ea5b88d74 /drivers/scsi/hisi_sas
parentfc8669514426b21b7aaa73e40a22fb1e1eb39259 (diff)
downloadlinux-c35279f2f1eef8f7f91b2b529fc22f01b25a244f.tar.xz
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: John Garry <john.garry@huawei.com> Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/hisi_sas')
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_main.c28
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v2_hw.c2
2 files changed, 19 insertions, 11 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 00068d25ba48..36d4e5a6d2c9 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -935,6 +935,7 @@ static int hisi_sas_abort_task(struct sas_task *task)
struct scsi_cmnd *cmnd = task->uldd_task;
struct hisi_sas_slot *slot = task->lldd_task;
u32 tag = slot->idx;
+ int rc2;
int_to_scsilun(cmnd->device->lun, &lun);
tmf_task.tmf = TMF_ABORT_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,
&tmf_task);
- /* if successful, clear the task and callback forwards.*/
- if (rc == TMF_RESP_FUNC_COMPLETE) {
+ rc2 = hisi_sas_internal_task_abort(hisi_hba, device,
+ 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) {
- 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);
- hisi_hba->hw->slot_complete(hisi_hba, slot);
+ hisi_sas_do_release_task(hisi_hba, task, slot);
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 ||
task->task_proto & SAS_PROTOCOL_STP) {
if (task->dev->dev_type == SAS_SATA_DEV) {
@@ -1220,6 +1222,12 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
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. */
if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index a35f8811edcb..ad5a7e697043 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -1766,7 +1766,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
goto out;
case STAT_IO_COMPLETE:
/* internal abort command complete */
- ts->stat = TMF_RESP_FUNC_COMPLETE;
+ ts->stat = TMF_RESP_FUNC_SUCC;
goto out;
case STAT_IO_NO_DEVICE:
ts->stat = TMF_RESP_FUNC_COMPLETE;