From: Martin K. Petersen Date: Tue, 15 Sep 2020 15:24:32 +0000 (-0400) Subject: Merge branch '5.9/scsi-fixes' into 5.10/scsi-ufs X-Git-Tag: v5.10.7~1329^2~130 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=02f7415054d7054955fd3c43902ad79437b09fbc;p=platform%2Fkernel%2Flinux-rpi.git Merge branch '5.9/scsi-fixes' into 5.10/scsi-ufs Resolve UFS discrepancies between fixes and queue. Signed-off-by: Martin K. Petersen --- 02f7415054d7054955fd3c43902ad79437b09fbc diff --cc drivers/scsi/ufs/ufshcd.c index ef210f8,da199fa..1d8134e --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@@ -6739,22 -6459,87 +6736,25 @@@ static int ufshcd_abort(struct scsi_cmn } hba->req_abort_count++; - /* Skip task abort in case previous aborts failed and report failure */ - if (lrbp->req_abort_skip) { - err = -EIO; - goto out; + if (!(reg & (1 << tag))) { + dev_err(hba->dev, + "%s: cmd was completed, but without a notifying intr, tag = %d", + __func__, tag); + goto cleanup; } - err = ufshcd_try_to_abort_task(hba, tag); - if (err) - goto out; - - spin_lock_irqsave(host->host_lock, flags); - __ufshcd_transfer_req_compl(hba, (1UL << tag)); - spin_unlock_irqrestore(host->host_lock, flags); + /* Skip task abort in case previous aborts failed and report failure */ - if (lrbp->req_abort_skip) { ++ if (lrbp->req_abort_skip) + err = -EIO; - goto out; - } - - for (poll_cnt = 100; poll_cnt; poll_cnt--) { - err = ufshcd_issue_tm_cmd(hba, lrbp->lun, lrbp->task_tag, - UFS_QUERY_TASK, &resp); - if (!err && resp == UPIU_TASK_MANAGEMENT_FUNC_SUCCEEDED) { - /* cmd pending in the device */ - dev_err(hba->dev, "%s: cmd pending in the device. tag = %d\n", - __func__, tag); - break; - } else if (!err && resp == UPIU_TASK_MANAGEMENT_FUNC_COMPL) { - /* - * cmd not pending in the device, check if it is - * in transition. - */ - dev_err(hba->dev, "%s: cmd at tag %d not pending in the device.\n", - __func__, tag); - reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); - if (reg & (1 << tag)) { - /* sleep for max. 200us to stabilize */ - usleep_range(100, 200); - continue; - } - /* command completed already */ - dev_err(hba->dev, "%s: cmd at tag %d successfully cleared from DB.\n", - __func__, tag); - goto cleanup; - } else { - dev_err(hba->dev, - "%s: no response from device. tag = %d, err %d\n", - __func__, tag, err); - if (!err) - err = resp; /* service response error */ - goto out; - } - } - - if (!poll_cnt) { - err = -EBUSY; - goto out; - } - - err = ufshcd_issue_tm_cmd(hba, lrbp->lun, lrbp->task_tag, - UFS_ABORT_TASK, &resp); - if (err || resp != UPIU_TASK_MANAGEMENT_FUNC_COMPL) { - if (!err) { - err = resp; /* service response error */ - dev_err(hba->dev, "%s: issued. tag = %d, err %d\n", - __func__, tag, err); - } - goto out; - } - - err = ufshcd_clear_cmd(hba, tag); - if (err) { - dev_err(hba->dev, "%s: Failed clearing cmd at tag %d, err %d\n", - __func__, tag, err); - goto out; - } ++ else ++ err = ufshcd_try_to_abort_task(hba, tag); - out: + if (!err) { + cleanup: - scsi_dma_unmap(cmd); - - spin_lock_irqsave(host->host_lock, flags); - ufshcd_outstanding_req_clear(hba, tag); - hba->lrb[tag].cmd = NULL; - spin_unlock_irqrestore(host->host_lock, flags); - ++ spin_lock_irqsave(host->host_lock, flags); ++ __ufshcd_transfer_req_compl(hba, (1UL << tag)); ++ spin_unlock_irqrestore(host->host_lock, flags); + out: - if (!err) { err = SUCCESS; } else { dev_err(hba->dev, "%s: failed with err %d\n", __func__, err); diff --cc drivers/scsi/ufs/ufshcd.h index 8011fdc,363589c..47eb143 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@@ -532,9 -522,10 +532,16 @@@ enum ufshcd_quirks UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR = 1 << 10, /* + * This quirk needs to be enabled if the host controller has + * auto-hibernate capability but it doesn't work. + */ + UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8 = 1 << 11, ++ ++ /* + * This quirk needs to disable manual flush for write booster + */ - UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL = 1 << 11, ++ UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL = 1 << 12, ++ }; enum ufshcd_caps {