summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKiwoong Kim <kwmad.kim@samsung.com>2020-05-28 06:46:53 +0530
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-08-26 11:42:20 +0200
commita190bf059dd6e8e6d0efad481d87e11224687e50 (patch)
tree62742034aea25239a02541f7aaf637690a3e48c7
parent239e626e10b082e15fbc96d2a242db2fef9019c6 (diff)
scsi: ufs: Add quirk to fix abnormal ocs fatal error
[ Upstream commit d779a6e90e189f4883ce6f900da02995fb000df5 ] Some controller like Exynos determines if FATAL ERROR (0x7) in OCS field in UTRD occurs for values other than GOOD (0x0) in STATUS field in response upiu as well as errors that a host controller can't cover. This patch is to prevent from reporting command results in those cases. Link: https://lore.kernel.org/r/20200528011658.71590-6-alim.akhtar@samsung.com Reviewed-by: Avri Altman <avri.altman@wdc.com> Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/scsi/ufs/ufshcd.c6
-rw-r--r--drivers/scsi/ufs/ufshcd.h6
2 files changed, 12 insertions, 0 deletions
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 4d5e8f6a3143..7298adbcdec8 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -4799,6 +4799,12 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
/* overall command status of utrd */
ocs = ufshcd_get_tr_ocs(lrbp);
+ if (hba->quirks & UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR) {
+ if (be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_1) &
+ MASK_RSP_UPIU_RESULT)
+ ocs = OCS_SUCCESS;
+ }
+
switch (ocs) {
case OCS_SUCCESS:
result = ufshcd_get_req_rsp(lrbp->ucd_rsp_ptr);
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index b3b2d09d8fff..59ca93b64bb0 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -541,6 +541,12 @@ enum ufshcd_quirks {
* resolution of the values of PRDTO and PRDTL in UTRD as byte.
*/
UFSHCD_QUIRK_PRDT_BYTE_GRAN = 1 << 9,
+
+ /*
+ * This quirk needs to be enabled if the host controller reports
+ * OCS FATAL ERROR with device error through sense data
+ */
+ UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR = 1 << 10,
};
enum ufshcd_caps {