diff options
Diffstat (limited to 'drivers/scsi/hisi_sas')
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_main.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 1b9c48c99968..302da84bf9ef 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1238,12 +1238,29 @@ out: static int hisi_sas_abort_task_set(struct domain_device *device, u8 *lun) { + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + struct device *dev = hisi_hba->dev; struct hisi_sas_tmf_task tmf_task; int rc = TMF_RESP_FUNC_FAILED; + unsigned long flags; + + rc = hisi_sas_internal_task_abort(hisi_hba, device, + HISI_SAS_INT_ABT_DEV, 0); + if (rc < 0) { + dev_err(dev, "abort task set: internal abort rc=%d\n", rc); + return TMF_RESP_FUNC_FAILED; + } + hisi_sas_dereg_device(hisi_hba, device); tmf_task.tmf = TMF_ABORT_TASK_SET; rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task); + if (rc == TMF_RESP_FUNC_COMPLETE) { + spin_lock_irqsave(&hisi_hba->lock, flags); + hisi_sas_release_task(hisi_hba, device); + spin_unlock_irqrestore(&hisi_hba->lock, flags); + } + return rc; } @@ -1333,6 +1350,14 @@ static int hisi_sas_lu_reset(struct domain_device *device, u8 *lun) } else { struct hisi_sas_tmf_task tmf_task = { .tmf = TMF_LU_RESET }; + rc = hisi_sas_internal_task_abort(hisi_hba, device, + HISI_SAS_INT_ABT_DEV, 0); + if (rc < 0) { + dev_err(dev, "lu_reset: internal abort failed\n"); + goto out; + } + hisi_sas_dereg_device(hisi_hba, device); + rc = hisi_sas_debug_issue_ssp_tmf(device, lun, &tmf_task); if (rc == TMF_RESP_FUNC_COMPLETE) { spin_lock_irqsave(&hisi_hba->lock, flags); |