From a60d7ef436871453822088c2cb0544f2d3acb4d5 Mon Sep 17 00:00:00 2001 From: hgchu Date: Fri, 12 Jan 2018 11:07:49 +0900 Subject: [PATCH] scsi: ufs: detect data link error and recovery Change-Id: I7418d2c071e737b1a4de5248e97bb0735af65975 Signed-off-by: hgchu --- drivers/scsi/ufs/ufshcd.c | 14 ++++++++++++++ drivers/scsi/ufs/ufshcd.h | 3 +++ 2 files changed, 17 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 5d0b203856ec..9686aa31ffaa 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -136,6 +136,7 @@ enum { UFSHCD_UIC_NL_ERROR = (1 << 3), /* Network layer error */ UFSHCD_UIC_TL_ERROR = (1 << 4), /* Transport Layer error */ UFSHCD_UIC_DME_ERROR = (1 << 5), /* DME error */ + UFSHCD_UIC_DL_ERROR = (1 << 6), /* Data link layer error */ }; #define ufshcd_set_eh_in_progress(h) \ @@ -3873,6 +3874,9 @@ static int ufshcd_link_hibern8_ctrl(struct ufs_hba *hba, bool en) if (hba->vops && hba->vops->hibern8_notify) hba->vops->hibern8_notify(hba, en, POST_CHANGE); out: + hba->tcx_replay_timer_expired_cnt = 0; + hba->fcx_protection_timer_expired_cnt = 0; + return ret; } @@ -5370,6 +5374,16 @@ static void ufshcd_update_uic_error(struct ufs_hba *hba) hba->uic_error |= UFSHCD_UIC_DL_TCx_REPLAY_ERROR; } + if (reg & UIC_DATA_LINK_LAYER_ERROR_TCX_REP_TIMER_EXP) + hba->tcx_replay_timer_expired_cnt++; + + if (reg & UIC_DATA_LINK_LAYER_ERROR_FCX_PRO_TIMER_EXP) + hba->fcx_protection_timer_expired_cnt++; + + if (hba->tcx_replay_timer_expired_cnt >= 2 || + hba->fcx_protection_timer_expired_cnt >= 2) + hba->uic_error |= UFSHCD_UIC_DL_ERROR; + /* UIC NL/TL/DME errors needs software retry */ reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_NETWORK_LAYER); if (reg) { diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index d824d6796947..b2669823fa0c 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -634,6 +634,9 @@ struct ufs_hba { u32 saved_uic_err; struct ufs_stats ufs_stats; + u32 tcx_replay_timer_expired_cnt; + u32 fcx_protection_timer_expired_cnt; + /* Device management request data */ struct ufs_dev_cmd dev_cmd; ktime_t last_dme_cmd_tstamp; -- 2.20.1