From: John Garry Date: Wed, 22 Mar 2017 17:25:27 +0000 (+0800) Subject: scsi: hisi_sas: check for SAS_TASK_STATE_ABORTED in slot complete X-Git-Tag: v4.12-rc1~99^2~130 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=a305f33775c0b7202fe77cbd4cc3d7f2048efc52;p=karo-tx-linux.git scsi: hisi_sas: check for SAS_TASK_STATE_ABORTED in slot complete Check in slot_complete_v2_hw() for whether a task has already been completed by upper layer. Signed-off-by: John Garry Reviewed-by: Xiang Chen Signed-off-by: Martin K. Petersen --- diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index ad5a7e697043..f4d8200ae7e2 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -1737,6 +1737,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) hisi_hba->complete_hdr[slot->cmplt_queue]; struct hisi_sas_complete_v2_hdr *complete_hdr = &complete_queue[slot->cmplt_queue_slot]; + int aborted; if (unlikely(!task || !task->lldd_task || !task->dev)) return -EINVAL; @@ -1745,12 +1746,21 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) device = task->dev; sas_dev = device->lldd_dev; + spin_lock(&task->task_state_lock); + aborted = task->task_state_flags & SAS_TASK_STATE_ABORTED; task->task_state_flags &= ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR); + spin_unlock(&task->task_state_lock); memset(ts, 0, sizeof(*ts)); ts->resp = SAS_TASK_COMPLETE; + if (unlikely(aborted)) { + ts->stat = SAS_ABORTED_TASK; + hisi_sas_slot_task_free(hisi_hba, task, slot); + return -1; + } + if (unlikely(!sas_dev)) { dev_dbg(dev, "slot complete: port has no device\n"); ts->stat = SAS_PHY_DOWN;