From f6bc2a3b294b3d6b298cf5a625e9923459d64edd Mon Sep 17 00:00:00 2001 From: Semih Baskan Date: Mon, 3 Aug 2026 05:44:59 +0300 Subject: [PATCH] kernel: xhci: fix USB3 port events with a single roothub 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 Link: https://github.com/openwrt/openwrt/pull/24547 Signed-off-by: Hauke Mehrtens --- ...ort-events-when-there-is-one-roothub.patch | 39 +++++++++++++++++++ ...ort-events-when-there-is-one-roothub.patch | 39 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 target/linux/generic/pending-6.12/891-usb-xhci-handle-port-events-when-there-is-one-roothub.patch create mode 100644 target/linux/generic/pending-6.18/891-usb-xhci-handle-port-events-when-there-is-one-roothub.patch 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 index 00000000000..d5c01eb1a58 --- /dev/null +++ b/target/linux/generic/pending-6.12/891-usb-xhci-handle-port-events-when-there-is-one-roothub.patch @@ -0,0 +1,39 @@ +From eb8cfe27aef67b30299aaf2a1ac538cf905135f2 Mon Sep 17 00:00:00 2001 +From: Semih Baskan +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 +--- +--- 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 index 00000000000..6916953dd78 --- /dev/null +++ b/target/linux/generic/pending-6.18/891-usb-xhci-handle-port-events-when-there-is-one-roothub.patch @@ -0,0 +1,39 @@ +From eb8cfe27aef67b30299aaf2a1ac538cf905135f2 Mon Sep 17 00:00:00 2001 +From: Semih Baskan +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 +--- +--- 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; -- 2.47.3