From: Michal Pecio <michal.pecio@gmail.com>
To: Niklas Neronin <niklas.neronin@linux.intel.com>
Cc: mathias.nyman@linux.intel.com, linux-usb@vger.kernel.org,
raoxu@uniontech.com
Subject: Re: [PATCH 8/9] usb: xhci: improve debug messages during suspend
Date: Mon, 30 Mar 2026 11:14:21 +0200 [thread overview]
Message-ID: <20260330111421.65c2eb06.michal.pecio@gmail.com> (raw)
In-Reply-To: <20260327123441.806564-9-niklas.neronin@linux.intel.com>
On Fri, 27 Mar 2026 13:34:39 +0100, Niklas Neronin wrote:
> Improve debug output for suspend failures, particularly when the
> controller handshake does not complete. This will become important as
> upcoming patches significantly rework the resume path, making more
> detailed suspend-side messages valuable for debugging.
As an aside, I think that if this series will cause any problems,
it will be some stale data structures surviving after resume, not
anything going wrong here.
> Add an explicit check of the Save/Restore Error (SRE) flag after a
> successful Save State (CSS) operation. The xHCI specification
> (note in section 4.23.2) states:
>
> "After a Save or Restore State operation completes, the
> Save/Restore Error (SRE) flag in USBSTS should be checked to
> ensure the operation completed successfully."
>
> Currently, the SRE error is only observed and warning is printed.
> This patch does not introduce deeper error handling, as the correct
> response is unclear and changes to suspend behavior may risk
> regressions once the resume path is updated.
I think patch 10/9 should add setting xhci->broken_suspend if this is
detected. It's ridiculous to try State Restore after State Save error.
At best, it should fail. At worst, it might not fail...
>
> Additionally, simplify and clean up the suspend USBSTS CSS/SSS
> handling code, improving readability and quirk handling for AMD
> SNPS xHC controllers that occasionally do not clear the SSS bit.
>
> Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
> ---
> drivers/usb/host/xhci.c | 65 +++++++++++++++++++++++------------------
> 1 file changed, 37 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 658419eb6827..232e6143ac4b 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -957,11 +957,11 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci)
> */
> int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
> {
> - int rc = 0;
> + int err;
> unsigned int delay = XHCI_MAX_HALT_USEC * 2;
> struct usb_hcd *hcd = xhci_to_hcd(xhci);
> u32 command;
> - u32 res;
> + u32 usbsts;
>
> if (!hcd->state)
> return 0;
> @@ -1007,11 +1007,10 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
> /* Some chips from Fresco Logic need an extraordinary delay */
> delay *= (xhci->quirks & XHCI_SLOW_SUSPEND) ? 10 : 1;
>
> - if (xhci_handshake(&xhci->op_regs->status,
> - STS_HALT, STS_HALT, delay)) {
> - xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n");
> - spin_unlock_irq(&xhci->lock);
> - return -ETIMEDOUT;
> + err = xhci_handshake(&xhci->op_regs->status, STS_HALT, STS_HALT, delay);
> + if (err) {
> + xhci_warn(xhci, "Clearing Run/Stop bit failed %d\n", err);
> + goto handshake_error;
> }
> xhci_clear_command_ring(xhci);
>
> @@ -1022,28 +1021,34 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
> command = readl(&xhci->op_regs->command);
> command |= CMD_CSS;
> writel(command, &xhci->op_regs->command);
> +
> + err = xhci_handshake(&xhci->op_regs->status, STS_SAVE, 0, 20 * USEC_PER_MSEC);
> + usbsts = readl(&xhci->op_regs->status);
> xhci->broken_suspend = 0;
> - if (xhci_handshake(&xhci->op_regs->status,
> - STS_SAVE, 0, 20 * 1000)) {
> - /*
> - * AMD SNPS xHC 3.0 occasionally does not clear the
> - * SSS bit of USBSTS and when driver tries to poll
> - * to see if the xHC clears BIT(8) which never happens
> - * and driver assumes that controller is not responding
> - * and times out. To workaround this, its good to check
> - * if SRE and HCE bits are not set (as per xhci
> - * Section 5.4.2) and bypass the timeout.
> - */
> - res = readl(&xhci->op_regs->status);
> - if ((xhci->quirks & XHCI_SNPS_BROKEN_SUSPEND) &&
> - (((res & STS_SRE) == 0) &&
> - ((res & STS_HCE) == 0))) {
> - xhci->broken_suspend = 1;
> - } else {
> - xhci_warn(xhci, "WARN: xHC save state timeout\n");
> - spin_unlock_irq(&xhci->lock);
> - return -ETIMEDOUT;
> + if (err) {
> + /*
> + * AMD SNPS xHC 3.0 occasionally does not clear the
> + * SSS bit of USBSTS and when driver tries to poll
> + * to see if the xHC clears BIT(8) which never happens
> + * and driver assumes that controller is not responding
> + * and times out. To workaround this, its good to check
> + * if SRE and HCE bits are not set (as per xhci
> + * Section 5.4.2) and bypass the timeout.
> + */
> + if (!(xhci->quirks & XHCI_SNPS_BROKEN_SUSPEND)) {
> + xhci_warn(xhci, "Controller Save State failed %d\n", err);
> + goto handshake_error;
> }
> +
> + if (usbsts & (STS_SRE | STS_HCE)) {
> + xhci_warn(xhci, "Controller Save State failed, USBSTS 0x%08x\n", usbsts);
> + goto handshake_error;
> + }
> +
> + xhci_dbg(xhci, "SNPS broken suspend, save state unreliable\n");
> + xhci->broken_suspend = 1;
> + } else if (usbsts & STS_SRE) {
> + xhci_warn(xhci, "Suspend Save Error (SRE), USBSTS 0x%08x\n", usbsts);
> }
This is a bit complicated and those warns are almost identical.
Would it be a problem to simply:
if (SRE | HCE)
xhci_warn("Save State error USBSTS %x")
// patch 10/9: set broken_suspend here
// patch 11/9: add HSE to this list
if (err)
if (quirk)
xhci->broken_suspend = 1;
else
xhci_warn("Save State timeout")
goto handshake_error
This may sometimes print both warnings, but not a big deal.
> spin_unlock_irq(&xhci->lock);
>
> @@ -1059,7 +1064,11 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
> __func__);
> }
>
> - return rc;
> + return 0;
> +
> +handshake_error:
> + spin_unlock_irq(&xhci->lock);
> + return -ETIMEDOUT;
> }
> EXPORT_SYMBOL_GPL(xhci_suspend);
>
> --
> 2.50.1
>
next prev parent reply other threads:[~2026-03-30 9:14 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-27 12:34 [PATCH 0/9] xhci: usb: optimize resuming from S4 (suspend-to-disk) Niklas Neronin
2026-03-27 12:34 ` [PATCH 1/9] usb: xhci: simplify CMRT initialization logic Niklas Neronin
2026-03-27 12:34 ` [PATCH 2/9] usb: xhci: relocate Restore/Controller error check Niklas Neronin
2026-03-27 12:34 ` [PATCH 3/9] usb: xhci: factor out roothub bandwidth cleanup Niklas Neronin
2026-03-30 8:29 ` Michal Pecio
2026-03-27 12:34 ` [PATCH 4/9] usb: xhci: move reserving command ring trb Niklas Neronin
2026-03-27 12:34 ` [PATCH 5/9] usb: xhci: move ring initialization Niklas Neronin
2026-03-30 8:42 ` Michal Pecio
2026-03-30 8:53 ` Neronin, Niklas
2026-03-27 12:34 ` [PATCH 6/9] usb: xhci: move initialization for lifetime objects Niklas Neronin
2026-03-30 8:49 ` Michal Pecio
2026-03-27 12:34 ` [PATCH 7/9] usb: xhci: split core allocation and initialization Niklas Neronin
2026-03-30 8:57 ` Michal Pecio
2026-03-27 12:34 ` [PATCH 8/9] usb: xhci: improve debug messages during suspend Niklas Neronin
2026-03-30 9:14 ` Michal Pecio [this message]
2026-03-30 11:44 ` Neronin, Niklas
2026-03-27 12:34 ` [PATCH 9/9] usb: xhci: optimize resuming from S4 (suspend-to-disk) Niklas Neronin
2026-03-30 9:45 ` Michal Pecio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260330111421.65c2eb06.michal.pecio@gmail.com \
--to=michal.pecio@gmail.com \
--cc=linux-usb@vger.kernel.org \
--cc=mathias.nyman@linux.intel.com \
--cc=niklas.neronin@linux.intel.com \
--cc=raoxu@uniontech.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox