Linux USB
 help / color / mirror / Atom feed
From: Mathias Nyman <mathias.nyman@linux.intel.com>
To: Jie Deng <dengjie03@kylinos.cn>, mathias.nyman@intel.com
Cc: linux-usb@vger.kernel.org, gregkh@linuxfoundation.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] usb: xhci: Restore MSI/MSI-X reinitialization on resume for RESET_ON_RESUME hosts
Date: Mon, 27 Jul 2026 17:19:43 +0300	[thread overview]
Message-ID: <2fd4299c-c455-497b-a122-5f94eeb9d1bd@linux.intel.com> (raw)
In-Reply-To: <20260714090210.1201964-1-dengjie03@kylinos.cn>

Hi

On 7/14/26 12:02, Jie Deng wrote:
> Commit 944e7deb4238 ("xhci: Avoid PCI MSI/MSIX interrupt
> reinitialization at resume") moved MSI/MSI-X setup out of xhci_run()
> into a PCI-specific xhci_pci_run() that is only invoked at probe time,
> and removed the xhci_cleanup_msix() call from xhci_resume().
> 
> The rationale (avoid redundant MSI reconfiguration on every resume) is
> sound for controllers that preserve state across suspend.  It is however
> *harmful* for controllers carrying XHCI_RESET_ON_RESUME: those hosts are
> fully reset on every S3 resume, and on some of them (e.g. ASMedia 3042)
> the MSI/MSI-X delivery path is no longer functional after the controller
> reset + D3->D0 transition.  Because the MSI vectors are now kept around
> unchanged across resume, the first post-resume command-completion event
> (ENABLE_SLOT) is delivered to a stale MSI channel and never reaches the
> CPU, which surfaces as:
>    xhci_hcd 0000:05:00.0: Error while assigning device slot ID: Command Aborted
>    xhci_hcd 0000:05:00.0: Max number of devices this xHCI host supports is 127.
>    usb 1-2: device not accepting address 3, error -22
>    xhci_hcd 0000:05:00.0: Error while assigning device slot ID: Command Aborted
>    xhci_hcd 0000:05:00.0: Max number of devices this xHCI host supports is 127.
>    usb 1-2: device not accepting address 3, error -22
>    xhci_hcd 0000:05:00.0: Error while assigning device slot ID: Command Aborted
>    xhci_hcd 0000:05:00.0: Max number of devices this xHCI host supports is 127.
>    usb 2-2: device not accepting address 3, error -22
> 

Thanks for reporting and debugging this.

Is this also an issue in runtime resume where system stays in S0 while
xHC transitions from D3 to D0, and is then reset?

Or is it only in system suspend, or in hibernate?
Does it matter if xHC was in D3hot or D3cold before resume?

Not sure if gating with XHCI_RESET_ON_RESUME is the right way as some of those
xHCI PCI hosts may just need to be reset in resume, but retain their MSI settings.
(xhci specs states that resetting xHC should not touch PCI config space)

This may just be a ASMedia PCI xHCI issue.


> Up to v6.3 the resume reset path did xhci_cleanup_msix() and, through
> xhci_run() -> xhci_try_enable_msi(), re-allocated the vectors, which
> incidentally re-armed the MSI delivery path and masked the hardware
> issue.  Work it around by restoring that behaviour, but only for hosts
> marked XHCI_RESET_ON_RESUME and only for PCI devices (platform/RCAR
> hosts using the same quirk must not be touched).
> 
> Fix: 944e7deb4238 ("xhci: Avoid PCI MSI/MSIX interrupt reinitialization at resume")
> Signed-off-by: Jie Deng <dengjie03@kylinos.cn>
> ---
>   drivers/usb/host/xhci-pci.c |  6 ++++--
>   drivers/usb/host/xhci.c     | 19 +++++++++++++++++++
>   drivers/usb/host/xhci.h     |  2 ++
>   3 files changed, 25 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
> index 6b3fcba44b08..77b3215c95f3 100644
> --- a/drivers/usb/host/xhci-pci.c
> +++ b/drivers/usb/host/xhci-pci.c
> @@ -126,7 +126,7 @@ static void xhci_msix_sync_irqs(struct xhci_hcd *xhci)
>   }
>   
>   /* Legacy IRQ is freed by usb_remove_hcd() or usb_hcd_pci_shutdown() */
> -static void xhci_cleanup_msix(struct xhci_hcd *xhci)
> +void xhci_cleanup_msix(struct xhci_hcd *xhci)
>   {
>   	struct usb_hcd *hcd = xhci_to_hcd(xhci);
>   	struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
> @@ -138,9 +138,10 @@ static void xhci_cleanup_msix(struct xhci_hcd *xhci)
>   	pci_free_irq_vectors(pdev);
>   	hcd->msix_enabled = 0;
>   }
> +EXPORT_SYMBOL_GPL(xhci_cleanup_msix);
>   
>   /* Try enabling MSI-X with MSI and legacy IRQ as fallback */
> -static int xhci_try_enable_msi(struct usb_hcd *hcd)
> +int xhci_try_enable_msi(struct usb_hcd *hcd)
>   {
>   	struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
>   	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
> @@ -207,6 +208,7 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
>   	hcd->irq = pdev->irq;
>   	return 0;
>   }
> +EXPORT_SYMBOL_GPL(xhci_try_enable_msi);
>   
>   static int xhci_pci_run(struct usb_hcd *hcd)
>   {
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 091c82ca8ee2..7dd3afcf6b2e 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -1190,10 +1190,29 @@ int xhci_resume(struct xhci_hcd *xhci, bool power_lost, bool is_auto_resume)
>   		xhci_for_each_ring_seg(xhci->cmd_ring->first_seg, seg)
>   			memset(seg->trbs, 0, sizeof(union xhci_trb) * TRBS_PER_SEGMENT);
>   
> +		/* XHCI_RESET_ON_RESUME hosts are fully reset on every resume.
> +		 * On some of them (e.g. ASMedia 3042) the MSI/MSI-X delivery
> +		 * path is no longer valid after the reset + D3->D0 cycle, so
> +		 * tear the vectors down here and let xhci_try_enable_msi()
> +		 * re-allocate them below, matching pre-6.4 behaviour.
> +		 */
> +		if (xhci->quirks & XHCI_RESET_ON_RESUME)
> +			xhci_cleanup_msix(xhci);

Ideally all PCI related xHCI code should be done in xhci-pci.c, like xhci_pci_resume()

In this case it's a bit tricky as msi cleanup and enabling is done mid xhci_resume(),
and would require a lot of refactoring to get it done.

Might need to do it this way first to get the ASMedia host working, and then refactor later.

> +
>   		xhci_debugfs_exit(xhci);
>   
>   		xhci_init(hcd);
>   
> +		/* Re-arm the MSI/MSI-X delivery path for RESET_ON_RESUME PCI
> +		 * hosts. xhci_run() no longer does this (it was moved to the
> +		 * probe-only xhci_pci_run()), and the stale vectors left over
> +		 * from before suspend cannot carry the first post-resume
> +		 * command-completion event on affected hardware.
> +		 */
> +		if ((xhci->quirks & XHCI_RESET_ON_RESUME) &&
> +		    dev_is_pci(hcd->self.controller))
> +			xhci_try_enable_msi(hcd);

Same comment as above

Thanks
Mathias


  reply	other threads:[~2026-07-27 14:19 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-14  9:02 [PATCH] usb: xhci: Restore MSI/MSI-X reinitialization on resume for RESET_ON_RESUME hosts Jie Deng
2026-07-27 14:19 ` Mathias Nyman [this message]
2026-07-30  2:24   ` Jie Deng
2026-07-30  4:48     ` 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=2fd4299c-c455-497b-a122-5f94eeb9d1bd@linux.intel.com \
    --to=mathias.nyman@linux.intel.com \
    --cc=dengjie03@kylinos.cn \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@intel.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