Linux kernel -stable discussions
 help / color / mirror / Atom feed
* [PATCH v5] usb: pci-quirks: always assert xHCI OS ownership
  2026-09-02  3:26 [PATCH v4] " Michal Pecio
@ 2026-09-02  5:39 ` Rishabh Jain
  2026-10-12 20:14   ` Mario Limonciello
  2026-10-30 16:52   ` Maciej Zonski
  0 siblings, 2 replies; 6+ messages in thread
From: Rishabh Jain @ 2026-09-02  5:39 UTC (permalink / raw)
  To: Mathias Nyman
  Cc: Greg Kroah-Hartman, Mario Limonciello, Michal Pecio, linux-usb,
	linux-kernel, stable, Rishabh Jain

The xHCI ownership protocol requires the OS driver to assert the HC OS
Owned semaphore before using the host controller, then wait for HC BIOS
Owned to clear if firmware owns it.

quirk_usb_handoff_xhci() currently asserts OS Owned only when BIOS Owned
is already set. If firmware leaves BIOS Owned clear, Linux uses the xHC
while both ownership semaphores remain clear.

The timeout fallback also clears BIOS Owned using the original register
value, which can clear OS Owned at the same time.

On an AMD PROM21 xHCI controller (1022:43fc), this caused every S3
resume to terminate Controller Restore State with USBSTS 0x401. Linux
then reset the host controller, both root hubs and the USB Bluetooth
adapter.

The controller entered resume ready and halted with USBSTS 0x1.
Endpoint state, 100 ms save/restore delays, scratchpads, the DCBAA,
device contexts and command, event and transfer rings were verified not
to cause the restore error.

Across four S3 cycles, asserting only HC OS Owned changed USBLEGSUP from
0x00000801 to 0x01000801 and eliminated the restore failure. Testing
included the unmodified 7.1.8-ogc1.1.fc44.x86_64 distribution kernel
using a test module that set the HC OS Owned semaphore. The same test
was repeated after review with the same result. Clearing USBLEGCTLSTS
was independently verified to be unnecessary.

Always assert OS Owned for controllers using the standard xHCI handoff,
and leave the existing TI/Renesas forced handoff unchanged. Keep OS
Owned asserted after the standard handoff, including when forcing BIOS
Owned clear after a timeout, to prevent firmware from reclaiming the
controller during subsequent suspends.

Fixes: 66d4eadd8d06 ("USB: xhci: BIOS handoff and HW initialization.")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Rishabh Jain <rishabh.jain1198@gmail.com>
---
I kept val unchanged for the error log, restored the original handshake
formatting, and explicitly preserve OS Owned when forcing BIOS Owned
clear after a timeout. Documented timeout issue in commit message.

I repeated the same S3 test on the unmodified
7.1.8-ogc1.1.fc44.x86_64 distribution kernel using the test module, with
the same successful result.

Changes in v5:
- Preserve the original ownership value for error logging.
- Restore the original handshake formatting.
- Explicitly retain OS Owned in the timeout fallback.

 drivers/usb/host/pci-quirks.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 0404489c2f6a..2b12a35e6f10 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -1193,10 +1193,11 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev)
 			 && pdev->device == 0x0014)) {
 		val = (val | XHCI_HC_OS_OWNED) & ~XHCI_HC_BIOS_OWNED;
 		writel(val, base + ext_cap_offset);
-	}
-
-	/* If the BIOS owns the HC, signal that the OS wants it, and wait */
-	if (val & XHCI_HC_BIOS_OWNED) {
+	} else {
+		/*
+		 * Perform the standard handoff and leave OS ownership set to
+		 * keep the BIOS at bay during subsequent suspends.
+		 */
 		writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset);
 
 		/* Wait for 1 second with 10 microsecond polling interval */
@@ -1208,7 +1209,9 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev)
 			dev_warn(&pdev->dev,
 				 "xHCI BIOS handoff failed (BIOS bug ?) %08x\n",
 				 val);
-			writel(val & ~XHCI_HC_BIOS_OWNED, base + ext_cap_offset);
+			writel((val | XHCI_HC_OS_OWNED) &
+			       ~XHCI_HC_BIOS_OWNED,
+			       base + ext_cap_offset);
 		}
 	}
 
-- 
2.50.1 (Apple Git-155)


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v5] usb: pci-quirks: always assert xHCI OS ownership
@ 2026-09-11 15:13 McKenna Fan
  0 siblings, 0 replies; 6+ messages in thread
From: McKenna Fan @ 2026-09-11 15:13 UTC (permalink / raw)
  To: Rishabh Jain
  Cc: Mathias Nyman, Greg Kroah-Hartman, Mario Limonciello,
	Michal Pecio, Linux Usb, Linux Kernel, Stable


This is an independent test report for [PATCH v5] usb: pci-quirks: always assert xHCI OS ownership.


I independently reproduced the problem and tested the proposed ownership behavior on a different AMD Promontory xHCI controller.

My affected controller is:

AMD B550 / Promontory-19 xHCIPCI 1022:43ee0000:02:00.0

The machine runs Manjaro and uses ACPI deep/S3 suspend.


I ended up collecting what is, frankly, an absurd amount of evidence while chasing this, including firmware analysis and repeated A/B testing, but the shortest useful version is:


Stock Manjaro 7.2.4 kernel, no helper module loaded:

EXTCAP_USBLEGSUP = 0x00000801EXTCAP_USBLEGCTLSTS = 0x40000000HC BIOS Owned = 0
HC OS Owned = 0




After entering deep S3:

xhci_hcd 0000:02:00.0: xHC error in resume, USBSTS 0x401, Reinit

After the failed resume:

EXTCAP_USBLEGSUP = 0x00000801EXTCAP_USBLEGCTLSTS = 0xc0000000

So HC OS Owned remained clear.


I then booted a custom build of the same Manjaro 7.2.4 kernel implementing the proposed behavior of asserting HC OS Owned in the xHCI handoff path. No ownership helper module was loaded.


Before S3:

EXTCAP_USBLEGSUP = 0x01000801EXTCAP_USBLEGCTLSTS = 0x40000000

HC BIOS Owned = 0

HC OS Owned = 1




I performed five consecutive deep-S3 suspend/resume cycles, including one approximately four-minute S3 residency.


All five resumed without:

xHC error in resumeUSBSTS 0x401Reinit

After the final resume:

EXTCAP_USBLEGSUP = 0x01000801EXTCAP_USBLEGCTLSTS = 0xc0000000

HC OS Owned remained asserted.


I then immediately rebooted back into the otherwise matching unmodified Manjaro 7.2.4 kernel. With no helper loaded, USBLEGSUP returned to 0x00000801, and the very first deep-S3 cycle reproduced:

xhci_hcd 0000:02:00.0: xHC error in resume, USBSTS 0x401, Reinit

This also agrees with earlier reversible testing using a very small test module which changed only HC OS Owned in USBLEGSUP:

0x00000801 -> 0x01000801

It did not reset or unbind the controller, clear USBLEGCTLSTS, or make other xHCI MMIO changes. With OS Owned asserted, repeated S3 resumes succeeded; clearing OS Owned again caused the resume failure to return.


So on this 1022:43ee controller I can independently reproduce the same causal relationship:

OS Owned clear    -> USBSTS 0x401 / controller reinitOS Owned asserted -> clean S3 resumeOS Owned clear    -> failure returnskernel asserts it -> 5/5 clean resumesstock kernel      -> first S3 fails again

One potentially useful detail is that USBLEGCTLSTS changed from 0x40000000 to 0xc0000000 after resume in both the successful and failed cases. That status change therefore does not distinguish the two outcomes here; HC OS Owned does.


This appears to extend the observed problem beyond the 1022:43fc controller in the original report to at least the related 1022:43ee Promontory controller.


I have complete logs from the positive and negative-control boots and can provide the longer A/B history or firmware findings if useful.


AI assistance disclosure: ChatGPT 5.6 Sol and Astra-medium were used during the investigation for source/code analysis, experimental planning, log comparison, and assistance preparing this report. All commands, kernel builds, suspend/resume experiments, register reads, and reported results were executed and verified on the physical system by me.


P.S. If Rishabh happens to enjoy following journalctl warnings farther than is probably reasonable, I have another USB rabbit hole which may be of interest: a kernel.org Bugzilla report on a USB3 Type-C peer-collision / port-power-management warning. The useful part is comment #1, where the issue gets reframed after more investigation:


https://bugzilla.kernel.org/show_bug.cgi?id=221987#c1


Different bug, but another fairly innocent-looking USB warning that turned out to have considerably more behind it than expected.

--
Secured with Tuta Mail:
https://tuta.com/free-email

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v5] usb: pci-quirks: always assert xHCI OS ownership
  2026-09-02  5:39 ` [PATCH v5] " Rishabh Jain
@ 2026-10-12 20:14   ` Mario Limonciello
  2026-10-15  9:17     ` Michal Pecio
  2026-10-30 16:52   ` Maciej Zonski
  1 sibling, 1 reply; 6+ messages in thread
From: Mario Limonciello @ 2026-10-12 20:14 UTC (permalink / raw)
  To: Rishabh Jain, Mathias Nyman
  Cc: Greg Kroah-Hartman, Michal Pecio, linux-usb, linux-kernel, stable

On 9/2/26 00:39, Rishabh Jain wrote:
> The xHCI ownership protocol requires the OS driver to assert the HC OS
> Owned semaphore before using the host controller, then wait for HC BIOS
> Owned to clear if firmware owns it.
> 
> quirk_usb_handoff_xhci() currently asserts OS Owned only when BIOS Owned
> is already set. If firmware leaves BIOS Owned clear, Linux uses the xHC
> while both ownership semaphores remain clear.
> 
> The timeout fallback also clears BIOS Owned using the original register
> value, which can clear OS Owned at the same time.
> 
> On an AMD PROM21 xHCI controller (1022:43fc), this caused every S3
> resume to terminate Controller Restore State with USBSTS 0x401. Linux
> then reset the host controller, both root hubs and the USB Bluetooth
> adapter.
> 
> The controller entered resume ready and halted with USBSTS 0x1.
> Endpoint state, 100 ms save/restore delays, scratchpads, the DCBAA,
> device contexts and command, event and transfer rings were verified not
> to cause the restore error.
> 
> Across four S3 cycles, asserting only HC OS Owned changed USBLEGSUP from
> 0x00000801 to 0x01000801 and eliminated the restore failure. Testing
> included the unmodified 7.1.8-ogc1.1.fc44.x86_64 distribution kernel
> using a test module that set the HC OS Owned semaphore. The same test
> was repeated after review with the same result. Clearing USBLEGCTLSTS
> was independently verified to be unnecessary.
> 
> Always assert OS Owned for controllers using the standard xHCI handoff,
> and leave the existing TI/Renesas forced handoff unchanged. Keep OS
> Owned asserted after the standard handoff, including when forcing BIOS
> Owned clear after a timeout, to prevent firmware from reclaiming the
> controller during subsequent suspends.
> 
> Fixes: 66d4eadd8d06 ("USB: xhci: BIOS handoff and HW initialization.")
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Rishabh Jain <rishabh.jain1198@gmail.com>
> ---

Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>

> I kept val unchanged for the error log, restored the original handshake
> formatting, and explicitly preserve OS Owned when forcing BIOS Owned
> clear after a timeout. Documented timeout issue in commit message.
> 
> I repeated the same S3 test on the unmodified
> 7.1.8-ogc1.1.fc44.x86_64 distribution kernel using the test module, with
> the same successful result.
> 
> Changes in v5:
> - Preserve the original ownership value for error logging.
> - Restore the original handshake formatting.
> - Explicitly retain OS Owned in the timeout fallback.
> 
>   drivers/usb/host/pci-quirks.c | 13 ++++++++-----
>   1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
> index 0404489c2f6a..2b12a35e6f10 100644
> --- a/drivers/usb/host/pci-quirks.c
> +++ b/drivers/usb/host/pci-quirks.c
> @@ -1193,10 +1193,11 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev)
>   			 && pdev->device == 0x0014)) {
>   		val = (val | XHCI_HC_OS_OWNED) & ~XHCI_HC_BIOS_OWNED;
>   		writel(val, base + ext_cap_offset);
> -	}
> -
> -	/* If the BIOS owns the HC, signal that the OS wants it, and wait */
> -	if (val & XHCI_HC_BIOS_OWNED) {
> +	} else {
> +		/*
> +		 * Perform the standard handoff and leave OS ownership set to
> +		 * keep the BIOS at bay during subsequent suspends.
> +		 */
>   		writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset);
>   
>   		/* Wait for 1 second with 10 microsecond polling interval */
> @@ -1208,7 +1209,9 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev)
>   			dev_warn(&pdev->dev,
>   				 "xHCI BIOS handoff failed (BIOS bug ?) %08x\n",
>   				 val);
> -			writel(val & ~XHCI_HC_BIOS_OWNED, base + ext_cap_offset);
> +			writel((val | XHCI_HC_OS_OWNED) &
> +			       ~XHCI_HC_BIOS_OWNED,
> +			       base + ext_cap_offset);
>   		}
>   	}
>   


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v5] usb: pci-quirks: always assert xHCI OS ownership
  2026-10-12 20:14   ` Mario Limonciello
@ 2026-10-15  9:17     ` Michal Pecio
  2026-10-15 13:01       ` Mario Limonciello
  0 siblings, 1 reply; 6+ messages in thread
From: Michal Pecio @ 2026-10-15  9:17 UTC (permalink / raw)
  To: Mario Limonciello
  Cc: Rishabh Jain, Mathias Nyman, Greg Kroah-Hartman, linux-usb,
	linux-kernel, stable

On Mon, 12 Oct 2026 15:14:14 -0500, Mario Limonciello wrote:
> On 9/2/26 00:39, Rishabh Jain wrote:
> > The xHCI ownership protocol requires the OS driver to assert the HC OS
> > Owned semaphore before using the host controller, then wait for HC BIOS
> > Owned to clear if firmware owns it.
> > 
> > quirk_usb_handoff_xhci() currently asserts OS Owned only when BIOS Owned
> > is already set. If firmware leaves BIOS Owned clear, Linux uses the xHC
> > while both ownership semaphores remain clear.
> > 
> > The timeout fallback also clears BIOS Owned using the original register
> > value, which can clear OS Owned at the same time.
> > 
> > On an AMD PROM21 xHCI controller (1022:43fc), this caused every S3
> > resume to terminate Controller Restore State with USBSTS 0x401. Linux
> > then reset the host controller, both root hubs and the USB Bluetooth
> > adapter.
> > 
> > The controller entered resume ready and halted with USBSTS 0x1.
> > Endpoint state, 100 ms save/restore delays, scratchpads, the DCBAA,
> > device contexts and command, event and transfer rings were verified not
> > to cause the restore error.
> > 
> > Across four S3 cycles, asserting only HC OS Owned changed USBLEGSUP from
> > 0x00000801 to 0x01000801 and eliminated the restore failure. Testing
> > included the unmodified 7.1.8-ogc1.1.fc44.x86_64 distribution kernel
> > using a test module that set the HC OS Owned semaphore. The same test
> > was repeated after review with the same result. Clearing USBLEGCTLSTS
> > was independently verified to be unnecessary.
> > 
> > Always assert OS Owned for controllers using the standard xHCI handoff,
> > and leave the existing TI/Renesas forced handoff unchanged. Keep OS
> > Owned asserted after the standard handoff, including when forcing BIOS
> > Owned clear after a timeout, to prevent firmware from reclaiming the
> > controller during subsequent suspends.
> > 
> > Fixes: 66d4eadd8d06 ("USB: xhci: BIOS handoff and HW initialization.")
> > Cc: stable@vger.kernel.org
> > Assisted-by: LLM
> > Signed-off-by: Rishabh Jain <rishabh.jain1198@gmail.com>
> > ---  
> 
> Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>

Yes, this fixes a legit issue and would be worth getting in mainline.
Two users confirmed the patch works for them, though no one could be
bothered to post proper Tested-by here :(

https://lore.kernel.org/linux-usb/P1FsfbW--F-9@tuta.io/
https://lore.kernel.org/linux-usb/CY8PR14MB59803EC0F6C7FD39A6D3C42FA0BF2@CY8PR14MB5980.namprd14.prod.outlook.com/

> 
> > I kept val unchanged for the error log, restored the original handshake
> > formatting, and explicitly preserve OS Owned when forcing BIOS Owned
> > clear after a timeout. Documented timeout issue in commit message.
> > 
> > I repeated the same S3 test on the unmodified
> > 7.1.8-ogc1.1.fc44.x86_64 distribution kernel using the test module, with
> > the same successful result.
> > 
> > Changes in v5:
> > - Preserve the original ownership value for error logging.
> > - Restore the original handshake formatting.
> > - Explicitly retain OS Owned in the timeout fallback.
> > 
> >   drivers/usb/host/pci-quirks.c | 13 ++++++++-----
> >   1 file changed, 8 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
> > index 0404489c2f6a..2b12a35e6f10 100644
> > --- a/drivers/usb/host/pci-quirks.c
> > +++ b/drivers/usb/host/pci-quirks.c
> > @@ -1193,10 +1193,11 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev)
> >   			 && pdev->device == 0x0014)) {
> >   		val = (val | XHCI_HC_OS_OWNED) & ~XHCI_HC_BIOS_OWNED;
> >   		writel(val, base + ext_cap_offset);
> > -	}
> > -
> > -	/* If the BIOS owns the HC, signal that the OS wants it, and wait */
> > -	if (val & XHCI_HC_BIOS_OWNED) {
> > +	} else {
> > +		/*
> > +		 * Perform the standard handoff and leave OS ownership set to
> > +		 * keep the BIOS at bay during subsequent suspends.
> > +		 */
> >   		writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset);
> >   
> >   		/* Wait for 1 second with 10 microsecond polling interval */
> > @@ -1208,7 +1209,9 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev)
> >   			dev_warn(&pdev->dev,
> >   				 "xHCI BIOS handoff failed (BIOS bug ?) %08x\n",
> >   				 val);
> > -			writel(val & ~XHCI_HC_BIOS_OWNED, base + ext_cap_offset);
> > +			writel((val | XHCI_HC_OS_OWNED) &
> > +			       ~XHCI_HC_BIOS_OWNED,
> > +			       base + ext_cap_offset);
> >   		}
> >   	}
> >     
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v5] usb: pci-quirks: always assert xHCI OS ownership
  2026-10-15  9:17     ` Michal Pecio
@ 2026-10-15 13:01       ` Mario Limonciello
  0 siblings, 0 replies; 6+ messages in thread
From: Mario Limonciello @ 2026-10-15 13:01 UTC (permalink / raw)
  To: Michal Pecio
  Cc: Rishabh Jain, Mathias Nyman, Greg Kroah-Hartman, linux-usb,
	linux-kernel, stable

On 10/15/26 04:17, Michal Pecio wrote:
> On Mon, 12 Oct 2026 15:14:14 -0500, Mario Limonciello wrote:
>> On 9/2/26 00:39, Rishabh Jain wrote:
>>> The xHCI ownership protocol requires the OS driver to assert the HC OS
>>> Owned semaphore before using the host controller, then wait for HC BIOS
>>> Owned to clear if firmware owns it.
>>>
>>> quirk_usb_handoff_xhci() currently asserts OS Owned only when BIOS Owned
>>> is already set. If firmware leaves BIOS Owned clear, Linux uses the xHC
>>> while both ownership semaphores remain clear.
>>>
>>> The timeout fallback also clears BIOS Owned using the original register
>>> value, which can clear OS Owned at the same time.
>>>
>>> On an AMD PROM21 xHCI controller (1022:43fc), this caused every S3
>>> resume to terminate Controller Restore State with USBSTS 0x401. Linux
>>> then reset the host controller, both root hubs and the USB Bluetooth
>>> adapter.
>>>
>>> The controller entered resume ready and halted with USBSTS 0x1.
>>> Endpoint state, 100 ms save/restore delays, scratchpads, the DCBAA,
>>> device contexts and command, event and transfer rings were verified not
>>> to cause the restore error.
>>>
>>> Across four S3 cycles, asserting only HC OS Owned changed USBLEGSUP from
>>> 0x00000801 to 0x01000801 and eliminated the restore failure. Testing
>>> included the unmodified 7.1.8-ogc1.1.fc44.x86_64 distribution kernel
>>> using a test module that set the HC OS Owned semaphore. The same test
>>> was repeated after review with the same result. Clearing USBLEGCTLSTS
>>> was independently verified to be unnecessary.
>>>
>>> Always assert OS Owned for controllers using the standard xHCI handoff,
>>> and leave the existing TI/Renesas forced handoff unchanged. Keep OS
>>> Owned asserted after the standard handoff, including when forcing BIOS
>>> Owned clear after a timeout, to prevent firmware from reclaiming the
>>> controller during subsequent suspends.
>>>
>>> Fixes: 66d4eadd8d06 ("USB: xhci: BIOS handoff and HW initialization.")
>>> Cc: stable@vger.kernel.org
>>> Assisted-by: LLM
>>> Signed-off-by: Rishabh Jain <rishabh.jain1198@gmail.com>
>>> ---
>>
>> Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
> 
> Yes, this fixes a legit issue and would be worth getting in mainline.
> Two users confirmed the patch works for them, though no one could be
> bothered to post proper Tested-by here :(
> 
> https://lore.kernel.org/linux-usb/P1FsfbW--F-9@tuta.io/
> https://lore.kernel.org/linux-usb/CY8PR14MB59803EC0F6C7FD39A6D3C42FA0BF2@CY8PR14MB5980.namprd14.prod.outlook.com/

They're public assertions, let's just put T-b tags for them so b4 can 
pick them up from this thread.

Tested-by: McKenna Fan <blue_sun@tuta.io>
Tested-by: Quinn Schive <quinnschive@hotmail.com>
> 
>>
>>> I kept val unchanged for the error log, restored the original handshake
>>> formatting, and explicitly preserve OS Owned when forcing BIOS Owned
>>> clear after a timeout. Documented timeout issue in commit message.
>>>
>>> I repeated the same S3 test on the unmodified
>>> 7.1.8-ogc1.1.fc44.x86_64 distribution kernel using the test module, with
>>> the same successful result.
>>>
>>> Changes in v5:
>>> - Preserve the original ownership value for error logging.
>>> - Restore the original handshake formatting.
>>> - Explicitly retain OS Owned in the timeout fallback.
>>>
>>>    drivers/usb/host/pci-quirks.c | 13 ++++++++-----
>>>    1 file changed, 8 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
>>> index 0404489c2f6a..2b12a35e6f10 100644
>>> --- a/drivers/usb/host/pci-quirks.c
>>> +++ b/drivers/usb/host/pci-quirks.c
>>> @@ -1193,10 +1193,11 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev)
>>>    			 && pdev->device == 0x0014)) {
>>>    		val = (val | XHCI_HC_OS_OWNED) & ~XHCI_HC_BIOS_OWNED;
>>>    		writel(val, base + ext_cap_offset);
>>> -	}
>>> -
>>> -	/* If the BIOS owns the HC, signal that the OS wants it, and wait */
>>> -	if (val & XHCI_HC_BIOS_OWNED) {
>>> +	} else {
>>> +		/*
>>> +		 * Perform the standard handoff and leave OS ownership set to
>>> +		 * keep the BIOS at bay during subsequent suspends.
>>> +		 */
>>>    		writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset);
>>>    
>>>    		/* Wait for 1 second with 10 microsecond polling interval */
>>> @@ -1208,7 +1209,9 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev)
>>>    			dev_warn(&pdev->dev,
>>>    				 "xHCI BIOS handoff failed (BIOS bug ?) %08x\n",
>>>    				 val);
>>> -			writel(val & ~XHCI_HC_BIOS_OWNED, base + ext_cap_offset);
>>> +			writel((val | XHCI_HC_OS_OWNED) &
>>> +			       ~XHCI_HC_BIOS_OWNED,
>>> +			       base + ext_cap_offset);
>>>    		}
>>>    	}
>>>      
>>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v5] usb: pci-quirks: always assert xHCI OS ownership
  2026-09-02  5:39 ` [PATCH v5] " Rishabh Jain
  2026-10-12 20:14   ` Mario Limonciello
@ 2026-10-30 16:52   ` Maciej Zonski
  1 sibling, 0 replies; 6+ messages in thread
From: Maciej Zonski @ 2026-10-30 16:52 UTC (permalink / raw)
  To: Rishabh Jain, Mathias Nyman
  Cc: Greg Kroah-Hartman, Mario Limonciello, Michal Pecio, linux-usb,
	linux-kernel, stable

Hi,

I tested v5 of this patch on an ASUS ROG STRIX X870-I GAMING WIFI
(AMD 800 series chipset). It fixes the failed xHCI state restore on S3
resume and no USB device is reset any more.

Tested-by: Maciej Zonski <me@zonni.pl>

Hardware
--------
  Board:   ASUS ROG STRIX X870-I GAMING WIFI, BIOS 1805 (09/18/2026)
  CPU:     AMD Ryzen 9 9950X3D
  Sleep:   S3 ("deep"); /sys/power/mem_sleep is "s2idle [deep]"

  6f:00.0 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD]
          800 Series Chipset USB 3.x XHCI Controller [1022:43fc] (rev 01)
          driver: xhci-pci-prom21
          path:   00:02.1 -> 03:00.0 -> 04:0c.0 -> 6f:00.0
                  (behind the chipset PCIe switch)

  Devices on that controller: Intel AX210 Bluetooth (8087:0032), a
  Logitech Logi Bolt receiver (046d:c548), a YubiKey, and several
  HID devices.

  The CPU xHCI controllers (72:00.3, 72:00.4, 73:00.0) and the ASMedia
  ASM4242 controller (6b:00.0) resume fine with and without the patch.
  Only 6f:00.0 is affected.

Kernel
------
  7.2.8 (NixOS, CachyOS flavour, so v7.2.8 plus the CachyOS patch set).
  v5 applied cleanly (drivers/usb/host/pci-quirks.c only).

Before the patch
----------------
Every S3 resume I looked at showed this (shortened):

  xhci-pci-prom21 0000:6f:00.0: xHC error in resume, USBSTS 0x401, Reinit
  usb usb8: root hub lost power or was reset
  usb usb9: root hub lost power or was reset
  usb 8-7: WARN: invalid context state for evaluate context command.
  usb 8-8: reset full-speed USB device number 6 using xhci-pci-prom21
  usb 8-4: reset high-speed USB device number 2 using xhci-pci-prom21
  usb 8-11: reset high-speed USB device number 7 using xhci-pci-prom21
  usb 8-7: reset full-speed USB device number 5 using xhci-pci-prom21
  usb 8-6: reset full-speed USB device number 4 using xhci-pci-prom21
  usb 8-5: USB disconnect, device number 10
  Bluetooth: hci0: Found device firmware: intel/ibt-0041-0041.sfi

USBSTS 0x401 is HCH | SRE (halted, save/restore error). btusb then
re-probed the AX210, so bluetoothd lost and re-created the adapter, and
the USB devices on that controller were reset or re-enumerated.

The disconnect was also visible: on every resume the desktop showed a
"YubiKey connected" notification, because the key was re-enumerated as
a new device (device number 10 -> 11 in the log).

With v5 applied
---------------
I analyzed three S3 suspend/resume cycles on the patched kernel:

  - two short ones in a row on one boot (about 13 s asleep each),
  - one long one on a later boot: 07:29:58 -> 16:19:29, about 8 h 49 min
    asleep.

In all three, the kernel log between "PM: suspend entry (deep)" and
"PM: suspend exit" contains none of the lines above: no "xHC error in
resume", no "root hub lost power or was reset", no "reset ... USB
device", no USB disconnect, and no hci0 firmware/probe lines. The
Bluetooth adapter stayed bound to btusb, and the YubiKey and the AX210
were still enumerated after the long sleep.

The "YubiKey connected" notification that appeared after every resume
before the patch has not appeared since the patch was applied.

The patch also fixed a problem I had given up on: my Logitech Bolt
receiver (046d:c548, port 8-6 on this controller) was reset and
re-enumerated on every resume, which made it unreliable, so I had
stopped using Logitech devices to wake the machine. With v5 applied the
Bolt Receiver works consistently across many suspend/resume cycles (this
is what I observed in daily use; the three cycles above are the ones I
checked in the kernel log).

Thanks for the fix.

Maciej Zonski

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-10-30 16:52 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-11 15:13 [PATCH v5] usb: pci-quirks: always assert xHCI OS ownership McKenna Fan
  -- strict thread matches above, loose matches on Subject: below --
2026-09-02  3:26 [PATCH v4] " Michal Pecio
2026-09-02  5:39 ` [PATCH v5] " Rishabh Jain
2026-10-12 20:14   ` Mario Limonciello
2026-10-15  9:17     ` Michal Pecio
2026-10-15 13:01       ` Mario Limonciello
2026-10-30 16:52   ` Maciej Zonski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox