* [PATCH] thunderbolt: Reset downstream port after failed link restore
@ 2026-08-29 23:57 Amaan Lalani
2026-08-31 13:42 ` Mika Westerberg
0 siblings, 1 reply; 3+ messages in thread
From: Amaan Lalani @ 2026-08-29 23:57 UTC (permalink / raw)
To: Andreas Noever, Mika Westerberg, Yehezkel Bernat
Cc: linux-usb, linux-kernel, Amaan Lalani
A directly connected Thunderbolt device may fail to restore
its link after a runtime suspend, therefore leaving the connection
unusable.
Reset the downstream port when the link restoration fails. This drives
SBTX low, causing the partner to observe a USB4 disconnect and allowing
the Type-C/PD firmware to renegotiate the connection. For dual-mode
devices, this may allow the connection to fall back to native USB3.x.
Tested on a Microsoft Surface Pro 11 with a UGreen Thunderbolt
4 external NVMe enclosure, where the device successfully reconnects as a
USB3 device when the Thunderbolt 4 link fails to recover.
Signed-off-by: Amaan Lalani <zlzzm2014@outlook.com>
---
drivers/thunderbolt/switch.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index 404c0693df50..7b88aa75a07a 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -3600,7 +3600,27 @@ int tb_switch_resume(struct tb_switch *sw, bool runtime)
if (tb_wait_for_port(port, true) <= 0) {
tb_port_warn(port,
- "lost during suspend, disconnecting\n");
+ "lost during suspend, disconnecting\n");
+ /*
+ * If a directly connected USB4/thunderbolt device did not restore
+ * its link after a runtime suspend, assert a downstream
+ * port reset. This drives SBTX low and makes the partner
+ * observe a real USB4 disconnect. A dual-mode device and
+ * the Type-C/PD firmware will then try to renegotiate
+ * the connection in a native USB 3.x mode.
+ *
+ * Restrict this to the host router's downstream port.
+ * Resetting an intermediate router would not cause the Type-C
+ * to be renegotiated.
+ */
+ if (runtime && !tb_route(sw) &&
+ tb_switch_is_usb4(sw) && port->cap_usb4) {
+ err = tb_port_reset(port);
+ if (err)
+ tb_port_warn(port,
+ "failed to reset port for USB3 fallback: %d\n",
+ err);
+ }
if (tb_port_has_remote(port))
tb_sw_set_unplugged(port->remote->sw);
else if (port->xdomain)
--
2.55.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] thunderbolt: Reset downstream port after failed link restore
2026-08-29 23:57 [PATCH] thunderbolt: Reset downstream port after failed link restore Amaan Lalani
@ 2026-08-31 13:42 ` Mika Westerberg
2026-08-31 13:46 ` Mika Westerberg
0 siblings, 1 reply; 3+ messages in thread
From: Mika Westerberg @ 2026-08-31 13:42 UTC (permalink / raw)
To: Amaan Lalani
Cc: Andreas Noever, Mika Westerberg, Yehezkel Bernat, linux-usb,
linux-kernel
Hi,
On Sat, Aug 29, 2026 at 04:57:05PM -0700, Amaan Lalani wrote:
> A directly connected Thunderbolt device may fail to restore
> its link after a runtime suspend, therefore leaving the connection
> unusable.
How does it show up? Can you share more details, like full dmesg with
thunderbolt.dyndbg=+p in the command line?
> Reset the downstream port when the link restoration fails. This drives
> SBTX low, causing the partner to observe a USB4 disconnect and allowing
> the Type-C/PD firmware to renegotiate the connection. For dual-mode
> devices, this may allow the connection to fall back to native USB3.x.
>
> Tested on a Microsoft Surface Pro 11 with a UGreen Thunderbolt
> 4 external NVMe enclosure, where the device successfully reconnects as a
> USB3 device when the Thunderbolt 4 link fails to recover.
>
> Signed-off-by: Amaan Lalani <zlzzm2014@outlook.com>
> ---
> drivers/thunderbolt/switch.c | 22 +++++++++++++++++++++-
> 1 file changed, 21 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
> index 404c0693df50..7b88aa75a07a 100644
> --- a/drivers/thunderbolt/switch.c
> +++ b/drivers/thunderbolt/switch.c
> @@ -3600,7 +3600,27 @@ int tb_switch_resume(struct tb_switch *sw, bool runtime)
>
> if (tb_wait_for_port(port, true) <= 0) {
> tb_port_warn(port,
> - "lost during suspend, disconnecting\n");
> + "lost during suspend, disconnecting\n");
> + /*
> + * If a directly connected USB4/thunderbolt device did not restore
> + * its link after a runtime suspend, assert a downstream
> + * port reset. This drives SBTX low and makes the partner
> + * observe a real USB4 disconnect. A dual-mode device and
> + * the Type-C/PD firmware will then try to renegotiate
> + * the connection in a native USB 3.x mode.
> + *
> + * Restrict this to the host router's downstream port.
> + * Resetting an intermediate router would not cause the Type-C
> + * to be renegotiated.
> + */
> + if (runtime && !tb_route(sw) &&
> + tb_switch_is_usb4(sw) && port->cap_usb4) {
Yea I'm not entirely sure we want to add hacks like this to the driver to
be honest.
The link should re-negotiate as USB4 so something is wrong there. Have you
checked if you have the latest firmwares on both sides?
> + err = tb_port_reset(port);
> + if (err)
> + tb_port_warn(port,
> + "failed to reset port for USB3 fallback: %d\n",
> + err);
> + }
> if (tb_port_has_remote(port))
> tb_sw_set_unplugged(port->remote->sw);
> else if (port->xdomain)
> --
> 2.55.0
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] thunderbolt: Reset downstream port after failed link restore
2026-08-31 13:42 ` Mika Westerberg
@ 2026-08-31 13:46 ` Mika Westerberg
0 siblings, 0 replies; 3+ messages in thread
From: Mika Westerberg @ 2026-08-31 13:46 UTC (permalink / raw)
To: Amaan Lalani
Cc: Andreas Noever, Mika Westerberg, Yehezkel Bernat, linux-usb,
linux-kernel
On Mon, Aug 31, 2026 at 03:42:39PM +0200, Mika Westerberg wrote:
> Hi,
>
> On Sat, Aug 29, 2026 at 04:57:05PM -0700, Amaan Lalani wrote:
> > A directly connected Thunderbolt device may fail to restore
> > its link after a runtime suspend, therefore leaving the connection
> > unusable.
>
> How does it show up? Can you share more details, like full dmesg with
> thunderbolt.dyndbg=+p in the command line?
>
> > Reset the downstream port when the link restoration fails. This drives
> > SBTX low, causing the partner to observe a USB4 disconnect and allowing
> > the Type-C/PD firmware to renegotiate the connection. For dual-mode
> > devices, this may allow the connection to fall back to native USB3.x.
> >
> > Tested on a Microsoft Surface Pro 11 with a UGreen Thunderbolt
> > 4 external NVMe enclosure, where the device successfully reconnects as a
> > USB3 device when the Thunderbolt 4 link fails to recover.
> >
> > Signed-off-by: Amaan Lalani <zlzzm2014@outlook.com>
> > ---
> > drivers/thunderbolt/switch.c | 22 +++++++++++++++++++++-
> > 1 file changed, 21 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
> > index 404c0693df50..7b88aa75a07a 100644
> > --- a/drivers/thunderbolt/switch.c
> > +++ b/drivers/thunderbolt/switch.c
> > @@ -3600,7 +3600,27 @@ int tb_switch_resume(struct tb_switch *sw, bool runtime)
> >
> > if (tb_wait_for_port(port, true) <= 0) {
> > tb_port_warn(port,
> > - "lost during suspend, disconnecting\n");
> > + "lost during suspend, disconnecting\n");
> > + /*
> > + * If a directly connected USB4/thunderbolt device did not restore
> > + * its link after a runtime suspend, assert a downstream
> > + * port reset. This drives SBTX low and makes the partner
> > + * observe a real USB4 disconnect. A dual-mode device and
> > + * the Type-C/PD firmware will then try to renegotiate
> > + * the connection in a native USB 3.x mode.
> > + *
> > + * Restrict this to the host router's downstream port.
> > + * Resetting an intermediate router would not cause the Type-C
> > + * to be renegotiated.
> > + */
> > + if (runtime && !tb_route(sw) &&
> > + tb_switch_is_usb4(sw) && port->cap_usb4) {
>
> Yea I'm not entirely sure we want to add hacks like this to the driver to
> be honest.
>
> The link should re-negotiate as USB4 so something is wrong there. Have you
> checked if you have the latest firmwares on both sides?
And if you want to do the DPR you can trigger this from userspace via udev
rule and run something like:
https://github.com/intel/tbtools/blob/main/scripts/reset-port.sh
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-08-31 13:46 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-29 23:57 [PATCH] thunderbolt: Reset downstream port after failed link restore Amaan Lalani
2026-08-31 13:42 ` Mika Westerberg
2026-08-31 13:46 ` Mika Westerberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox