scsi: ufs: Add quirk to fix abnormal ocs fatal error
authorKiwoong Kim <kwmad.kim@samsung.com>
Thu, 28 May 2020 01:16:53 +0000 (06:46 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 15 Jun 2020 18:04:10 +0000 (14:04 -0400)
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>
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshcd.h

index 52206d5c2ca20933034fc3476c8d8be2d5eed1d1..e83afcc56f88e30ddc27b9318018990bcfcd85b6 100644 (file)
@@ -4819,6 +4819,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);
index 519a9e82ab958cbf528844aecf3ec101327248ad..84842003c7ac0645b71116e22f5289943bcd599c 100644 (file)
@@ -543,6 +543,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 {