From 5534cf5793aa4142b9b3fc1d4c6605e4dba337ba Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 24 Jul 2025 09:12:47 +0200 Subject: [PATCH] 5.4-stable patches added patches: usb-hub-fix-detection-of-high-tier-usb3-devices-behind-suspended-hubs.patch --- queue-5.4/series | 1 + ...r-usb3-devices-behind-suspended-hubs.patch | 126 ++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 queue-5.4/usb-hub-fix-detection-of-high-tier-usb3-devices-behind-suspended-hubs.patch diff --git a/queue-5.4/series b/queue-5.4/series index f83ae43b7a..05a8f9e202 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -51,3 +51,4 @@ net_sched-sch_sfq-don-t-allow-1-packet-limit.patch net_sched-sch_sfq-use-a-temporary-work-area-for-validating-configuration.patch net_sched-sch_sfq-move-the-limit-validation.patch net_sched-sch_sfq-reject-invalid-perturb-period.patch +usb-hub-fix-detection-of-high-tier-usb3-devices-behind-suspended-hubs.patch diff --git a/queue-5.4/usb-hub-fix-detection-of-high-tier-usb3-devices-behind-suspended-hubs.patch b/queue-5.4/usb-hub-fix-detection-of-high-tier-usb3-devices-behind-suspended-hubs.patch new file mode 100644 index 0000000000..b2f9cbd17c --- /dev/null +++ b/queue-5.4/usb-hub-fix-detection-of-high-tier-usb3-devices-behind-suspended-hubs.patch @@ -0,0 +1,126 @@ +From 8f5b7e2bec1c36578fdaa74a6951833541103e27 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Wed, 11 Jun 2025 14:24:41 +0300 +Subject: usb: hub: fix detection of high tier USB3 devices behind suspended hubs + +From: Mathias Nyman + +commit 8f5b7e2bec1c36578fdaa74a6951833541103e27 upstream. + +USB3 devices connected behind several external suspended hubs may not +be detected when plugged in due to aggressive hub runtime pm suspend. + +The hub driver immediately runtime-suspends hubs if there are no +active children or port activity. + +There is a delay between the wake signal causing hub resume, and driver +visible port activity on the hub downstream facing ports. +Most of the LFPS handshake, resume signaling and link training done +on the downstream ports is not visible to the hub driver until completed, +when device then will appear fully enabled and running on the port. + +This delay between wake signal and detectable port change is even more +significant with chained suspended hubs where the wake signal will +propagate upstream first. Suspended hubs will only start resuming +downstream ports after upstream facing port resumes. + +The hub driver may resume a USB3 hub, read status of all ports, not +yet see any activity, and runtime suspend back the hub before any +port activity is visible. + +This exact case was seen when conncting USB3 devices to a suspended +Thunderbolt dock. + +USB3 specification defines a 100ms tU3WakeupRetryDelay, indicating +USB3 devices expect to be resumed within 100ms after signaling wake. +if not then device will resend the wake signal. + +Give the USB3 hubs twice this time (200ms) to detect any port +changes after resume, before allowing hub to runtime suspend again. + +Cc: stable +Fixes: 2839f5bcfcfc ("USB: Turn on auto-suspend for USB 3.0 hubs.") +Acked-by: Alan Stern +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250611112441.2267883-1-mathias.nyman@linux.intel.com +[ replaced hub_get/hub_put wrapper functions with direct kref_get/kref_put calls ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/hub.c | 33 ++++++++++++++++++++++++++++++++- + 1 file changed, 32 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -51,6 +51,12 @@ + #define USB_TP_TRANSMISSION_DELAY_MAX 65535 /* ns */ + #define USB_PING_RESPONSE_TIME 400 /* ns */ + ++/* ++ * Give SS hubs 200ms time after wake to train downstream links before ++ * assuming no port activity and allowing hub to runtime suspend back. ++ */ ++#define USB_SS_PORT_U0_WAKE_TIME 200 /* ms */ ++ + /* Protect struct usb_device->state and ->children members + * Note: Both are also protected by ->dev.sem, except that ->state can + * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ +@@ -1024,11 +1030,12 @@ int usb_remove_device(struct usb_device + + enum hub_activation_type { + HUB_INIT, HUB_INIT2, HUB_INIT3, /* INITs must come first */ +- HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME, ++ HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME, HUB_POST_RESUME, + }; + + static void hub_init_func2(struct work_struct *ws); + static void hub_init_func3(struct work_struct *ws); ++static void hub_post_resume(struct work_struct *ws); + + static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) + { +@@ -1051,6 +1058,13 @@ static void hub_activate(struct usb_hub + goto init2; + goto init3; + } ++ ++ if (type == HUB_POST_RESUME) { ++ usb_autopm_put_interface_async(to_usb_interface(hub->intfdev)); ++ kref_put(&hub->kref, hub_release); ++ return; ++ } ++ + kref_get(&hub->kref); + + /* The superspeed hub except for root hub has to use Hub Depth +@@ -1299,6 +1313,16 @@ static void hub_activate(struct usb_hub + device_unlock(&hdev->dev); + } + ++ if (type == HUB_RESUME && hub_is_superspeed(hub->hdev)) { ++ /* give usb3 downstream links training time after hub resume */ ++ INIT_DELAYED_WORK(&hub->init_work, hub_post_resume); ++ queue_delayed_work(system_power_efficient_wq, &hub->init_work, ++ msecs_to_jiffies(USB_SS_PORT_U0_WAKE_TIME)); ++ usb_autopm_get_interface_no_resume( ++ to_usb_interface(hub->intfdev)); ++ return; ++ } ++ + kref_put(&hub->kref, hub_release); + } + +@@ -1317,6 +1341,13 @@ static void hub_init_func3(struct work_s + hub_activate(hub, HUB_INIT3); + } + ++static void hub_post_resume(struct work_struct *ws) ++{ ++ struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work); ++ ++ hub_activate(hub, HUB_POST_RESUME); ++} ++ + enum hub_quiescing_type { + HUB_DISCONNECT, HUB_PRE_RESET, HUB_SUSPEND + }; -- 2.47.2