Re: [PATCH RESEND v2] scsi: ufs: clear doorbell for hibern8 errors when using ah8

From: Can Guo
Date: Thu Oct 21 2021 - 02:10:43 EST


On 2021-10-19 12:57, Kiwoong Kim wrote:
Changes from v1:
* Change the time to requeue pended commands

When an scsi command is dispatched right after host complete
all the pended requests and ufs driver tries to ring a doorbell,
host might be still during entering into hibern8.
If the hibern8 error occurrs during that period, the doorbell
might not be zero and clearing it should have done.
But, current ufshcd_err_handler goes directly to reset
w/o clearing the doorbell when the driver's link state is broken.

/*
* Stop the host controller and complete the requests
* cleared by h/w
*/
ufshcd_hba_stop(hba);
hba->silence_err_logs = true;
ufshcd_complete_requests(hba);

Same ask as Adrian did, ufshcd_hba_stop() should clear all doorbell
bits as it disables UFS host controller, then ufshcd_complete_requests()
completes any pending requests, no?

This patch is to requeue pended commands after host reset.

Here's an actual symptom that I've faced. At the time, tag #17
is still pended even after host reset. And then the block timer
is expired.

exynos-ufs 11100000.ufs: ufshcd_check_errors: Auto Hibern8
Enter failed - status: 0x00000040, upmcrs: 0x00000001
..
host_regs: 00000050: b8671000 00000008 00020000 00000000
..
exynos-ufs 11100000.ufs: ufshcd_abort: Device abort task at tag 17

Signed-off-by: Kiwoong Kim <kwmad.kim@xxxxxxxxxxx>
---
drivers/scsi/ufs/ufshcd.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 9faf02c..e5d4ef7 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -7136,8 +7136,10 @@ static int ufshcd_host_reset_and_restore(struct
ufs_hba *hba)
err = ufshcd_hba_enable(hba);

/* Establish the link again and restore the device */
- if (!err)
+ if (!err) {
+ ufshcd_retry_aborted_requests(hba);
err = ufshcd_probe_hba(hba, false);
+ }

if (err)
dev_err(hba->dev, "%s: Host init failed %d\n", __func__, err);