]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
kernel: xhci: fix USB3 port events with a single roothub 24547/head
authorSemih Baskan <strst.gs@gmail.com>
Mon, 3 Aug 2026 02:44:59 +0000 (05:44 +0300)
committerHauke Mehrtens <hauke@hauke-m.de>
Fri, 14 Aug 2026 00:05:25 +0000 (02:05 +0200)
USB3 port events are dropped whenever the controller has only one roothub.
The check that guards them treats a missing shared hcd as proof the hcd was
removed, which stopped being true with upstream commit 4736ebd7fcaf ("usb:
host: xhci-plat: omit shared hcd if either root hub has no ports"). A
controller whose USB2 root hub has no ports gets a single roothub and never
has a shared one, so every SuperSpeed event is thrown away and nothing
enumerates even though the port reports the device:

  0x006a1203 Powered Connected Enabled Link:U0 PortSpeed:4

Broadcom Northstar is such a controller. USB3 works there up to 5.15 and
stops from 5.19 onwards.

Tested on an Asus RT-N18U with kernel 6.18, seven SuperSpeed enumerations,
USB2 unaffected on both ports.

Link: https://github.com/openwrt/openwrt/issues/19592
Signed-off-by: Semih Baskan <strst.gs@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/24547
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/generic/pending-6.12/891-usb-xhci-handle-port-events-when-there-is-one-roothub.patch [new file with mode: 0644]
target/linux/generic/pending-6.18/891-usb-xhci-handle-port-events-when-there-is-one-roothub.patch [new file with mode: 0644]

diff --git a/target/linux/generic/pending-6.12/891-usb-xhci-handle-port-events-when-there-is-one-roothub.patch b/target/linux/generic/pending-6.12/891-usb-xhci-handle-port-events-when-there-is-one-roothub.patch
new file mode 100644 (file)
index 0000000..d5c01eb
--- /dev/null
@@ -0,0 +1,39 @@
+From eb8cfe27aef67b30299aaf2a1ac538cf905135f2 Mon Sep 17 00:00:00 2001
+From: Semih Baskan <strst.gs@gmail.com>
+Date: Mon, 3 Aug 2026 07:08:11 +0300
+Subject: [PATCH] usb: xhci: Handle USB3 port events when there is one roothub
+
+handle_port_status() drops every USB3 port event when xhci->shared_hcd is
+NULL. The check dates from a time when xhci-plat always created a shared
+hcd, so a NULL one could only mean the hcd had been removed.
+
+Since commit 4736ebd7fcaf ("usb: host: xhci-plat: omit shared hcd if
+either root hub has no ports") that is no longer true. A controller whose
+USB2 root hub has no ports gets a single roothub, the USB3 rhub is served
+by the main hcd, and shared_hcd stays NULL for the lifetime of the device.
+Every SuperSpeed port event is then thrown away as bogus behind a debug
+message, so devices never enumerate even though the port reports them:
+
+  0x006a1203 Powered Connected Enabled Link:U0 PortSpeed:4
+
+Broadcom Northstar is such a controller. USB3 works there up to 5.15 and
+stops working from 5.19 onwards.
+
+Ask xhci_get_usb3_hcd() instead. It returns the shared hcd when there is
+one, the main hcd when the USB2 root hub has no ports, and NULL once the
+shared hcd is gone, which keeps the original meaning of the check.
+
+Fixes: 4736ebd7fcaf ("usb: host: xhci-plat: omit shared hcd if either root hub has no ports")
+Signed-off-by: Semih Baskan <strst.gs@gmail.com>
+---
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1986,7 +1986,7 @@ static void handle_port_status(struct xh
+               vdev = xhci->devs[port->slot_id];
+       /* We might get interrupts after shared_hcd is removed */
+-      if (port->rhub == &xhci->usb3_rhub && xhci->shared_hcd == NULL) {
++      if (port->rhub == &xhci->usb3_rhub && xhci_get_usb3_hcd(xhci) == NULL) {
+               xhci_dbg(xhci, "ignore port event for removed USB3 hcd\n");
+               bogus_port_status = true;
+               goto cleanup;
diff --git a/target/linux/generic/pending-6.18/891-usb-xhci-handle-port-events-when-there-is-one-roothub.patch b/target/linux/generic/pending-6.18/891-usb-xhci-handle-port-events-when-there-is-one-roothub.patch
new file mode 100644 (file)
index 0000000..6916953
--- /dev/null
@@ -0,0 +1,39 @@
+From eb8cfe27aef67b30299aaf2a1ac538cf905135f2 Mon Sep 17 00:00:00 2001
+From: Semih Baskan <strst.gs@gmail.com>
+Date: Mon, 3 Aug 2026 07:08:11 +0300
+Subject: [PATCH] usb: xhci: Handle USB3 port events when there is one roothub
+
+handle_port_status() drops every USB3 port event when xhci->shared_hcd is
+NULL. The check dates from a time when xhci-plat always created a shared
+hcd, so a NULL one could only mean the hcd had been removed.
+
+Since commit 4736ebd7fcaf ("usb: host: xhci-plat: omit shared hcd if
+either root hub has no ports") that is no longer true. A controller whose
+USB2 root hub has no ports gets a single roothub, the USB3 rhub is served
+by the main hcd, and shared_hcd stays NULL for the lifetime of the device.
+Every SuperSpeed port event is then thrown away as bogus behind a debug
+message, so devices never enumerate even though the port reports them:
+
+  0x006a1203 Powered Connected Enabled Link:U0 PortSpeed:4
+
+Broadcom Northstar is such a controller. USB3 works there up to 5.15 and
+stops working from 5.19 onwards.
+
+Ask xhci_get_usb3_hcd() instead. It returns the shared hcd when there is
+one, the main hcd when the USB2 root hub has no ports, and NULL once the
+shared hcd is gone, which keeps the original meaning of the check.
+
+Fixes: 4736ebd7fcaf ("usb: host: xhci-plat: omit shared hcd if either root hub has no ports")
+Signed-off-by: Semih Baskan <strst.gs@gmail.com>
+---
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2026,7 +2026,7 @@ static void handle_port_status(struct xh
+               vdev = xhci->devs[port->slot_id];
+       /* We might get interrupts after shared_hcd is removed */
+-      if (port->rhub == &xhci->usb3_rhub && xhci->shared_hcd == NULL) {
++      if (port->rhub == &xhci->usb3_rhub && xhci_get_usb3_hcd(xhci) == NULL) {
+               xhci_dbg(xhci, "ignore port event for removed USB3 hcd\n");
+               bogus_port_status = true;
+               goto cleanup;