ANDROID: scsi: ufs: Improve MCQ error handling

Changes
- Add new android vendor hook: android_vh_ufs_mcq_retry_complete()
- Retry mcq complete on reset in error handling flow
- Check mcq oustanding reqs instead of DB reg under MCQ mode

Bug: 248447556
Change-Id: Ie658edcef0f9b155eefb4462c99f40557cb64c68
Signed-off-by: Po-Wen Kao <powen.kao@mediatek.com>
Signed-off-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
This commit is contained in:
Eddie Huang
2022-09-21 17:33:38 +08:00
committed by Treehugger Robot
parent 9dcd74deff
commit afa76a1c3a
3 changed files with 31 additions and 6 deletions

View File

@@ -206,6 +206,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_mcq_get_outstanding_reqs);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_mcq_abort);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_mcq_clear_cmd);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_mcq_clear_pending);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_mcq_retry_complete);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cgroup_attach);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_iommu_setup_dma_ops);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_iommu_iovad_alloc_iova);

View File

@@ -1097,6 +1097,7 @@ static int ufshcd_wait_for_doorbell_clr(struct ufs_hba *hba,
u32 tr_doorbell;
bool timeout = false, do_last_check = false;
ktime_t start;
bool has_outstanding = false;
ufshcd_hold(hba, false);
spin_lock_irqsave(hba->host->host_lock, flags);
@@ -1112,7 +1113,12 @@ static int ufshcd_wait_for_doorbell_clr(struct ufs_hba *hba,
}
tm_doorbell = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
if (ufshcd_use_mcq_hooks(hba)) {
trace_android_vh_ufs_mcq_has_oustanding_reqs(hba, &has_outstanding);
tr_doorbell = has_outstanding ? 1 : 0;
} else {
tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
}
if (!tm_doorbell && !tr_doorbell) {
timeout = false;
break;
@@ -6294,6 +6300,7 @@ do_reset:
if (needs_reset) {
hba->force_reset = false;
spin_unlock_irqrestore(hba->host->host_lock, flags);
trace_android_vh_ufs_mcq_retry_complete(hba);
err = ufshcd_reset_and_restore(hba);
if (err)
dev_err(hba->dev, "%s: reset and restore failed with err %d\n",
@@ -7000,6 +7007,7 @@ static int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag)
int poll_cnt;
u8 resp = 0xF;
u32 reg;
unsigned long *outstanding_reqs;
for (poll_cnt = 100; poll_cnt; poll_cnt--) {
err = ufshcd_issue_tm_cmd(hba, lrbp->lun, lrbp->task_tag,
@@ -7016,12 +7024,24 @@ static int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag)
*/
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;
if (ufshcd_use_mcq_hooks(hba)) {
trace_android_vh_ufs_mcq_get_outstanding_reqs(hba,
&outstanding_reqs, NULL);
if (test_bit(tag, outstanding_reqs)) {
/* sleep for max. 200us to stabilize */
usleep_range(100, 200);
continue;
}
} else {
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);

View File

@@ -128,6 +128,10 @@ DECLARE_HOOK(android_vh_ufs_mcq_clear_pending,
TP_PROTO(struct ufs_hba *hba, int *ret),
TP_ARGS(hba, ret));
DECLARE_HOOK(android_vh_ufs_mcq_retry_complete,
TP_PROTO(struct ufs_hba *hba),
TP_ARGS(hba));
#endif /* _TRACE_HOOK_UFSHCD_H */
/* This part must be outside protection */
#include <trace/define_trace.h>