diff options
| author | HOYOUNG SEO <hy50.seo@samsung.com> | 2026-10-27 20:03:57 +0900 |
|---|---|---|
| committer | Martin K. Petersen (Oracle) <mkp@kernel.org> | 2026-10-28 21:27:48 -0400 |
| commit | 6b2ff2b3eafa381db9b4c8a6ed98b353b2a09f39 (patch) | |
| tree | 203651380adfe6fa1e2e2054dd78caa3de2e5518 /drivers | |
| parent | 8a832fb632da303cdf0704e0d56722ec47799f19 (diff) | |
scsi: ufs: core: Change the error check sequence for auto hibern8
Auto-hibern8 enter and exit are performed by the host controller without a
UIC command, and the auto-hibern8 idle timer only runs while no UIC command
is outstanding. An auto-hibern8 error (IS.UHES or IS.UHXS) is therefore
usually reported while hba->active_uic_cmd is NULL.
Since commit fcd8b0450a9a ("scsi: ufs: core: Make ufshcd_uic_cmd_compl()
easier to analyze"), ufshcd_uic_cmd_compl() returns early when
hba->active_uic_cmd is NULL, before ufshcd_is_auto_hibern8_error() is
called. Such auto-hibern8 errors are no longer recorded in hba->errors, so
ufshcd_check_errors() is not called for them and the error handler is not
scheduled.
Check for auto-hibern8 errors before checking for an active UIC command, as
was done before that commit, but keep returning early when there is no
active UIC command so that a NULL cmd is never dereferenced. Only report
the missing UIC command if no auto-hibern8 error was found.
Fixes: fcd8b0450a9a ("scsi: ufs: core: Make ufshcd_uic_cmd_compl() easier to analyze")
Cc: stable@vger.kernel.org # v6.13+
Signed-off-by: HOYOUNG SEO <hy50.seo@samsung.com>
Reviewed-by: Stanley Jhu <stanleyjhu@google.com>
Reviewed-by: Bean Huo <beanhuo@micron.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20261027110357.3649301-1-hy50.seo@samsung.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/ufs/core/ufshcd.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index ee643830a57a..fd52deb72d21 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -5931,18 +5931,26 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) { irqreturn_t retval = IRQ_NONE; struct uic_command *cmd; + bool ah8_err; guard(spinlock_irqsave)(&hba->host->host_lock); + + /* + * Auto-hibern8 is performed without a UIC command, so check for + * auto-hibern8 errors before checking for an active UIC command. + */ + ah8_err = ufshcd_is_auto_hibern8_error(hba, intr_status); + if (ah8_err) + hba->errors |= (UFSHCD_UIC_HIBERN8_MASK & intr_status); + cmd = hba->active_uic_cmd; if (!cmd) { - dev_err(hba->dev, - "No active UIC command. Maybe a timeout occurred?\n"); + if (!ah8_err) + dev_err(hba->dev, + "No active UIC command. Maybe a timeout occurred?\n"); return retval; } - if (ufshcd_is_auto_hibern8_error(hba, intr_status)) - hba->errors |= (UFSHCD_UIC_HIBERN8_MASK & intr_status); - if (intr_status & UIC_COMMAND_COMPL) { /* * Store the UIC command result in the lowest byte of |
