drivers/usb/typec/ucsi/ucsi.c | 81 +++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+)
Some firmware implementations incorrectly return the same altmode
multiple times at different offsets when queried via UCSI_GET_ALTERNATE_MODES.
This causes sysfs duplicate filename errors and kernel call traces when
the driver attempts to register the same altmode twice:
sysfs: cannot create duplicate filename '/devices/.../typec/port0/port0.0/partner'
typec-thunderbolt port0-partner.1: failed to create symlinks
typec-thunderbolt port0-partner.1: probe with driver typec-thunderbolt failed with error -17
Detect duplicate altmodes by comparing SVID and VDO before registration.
If a duplicate is detected, skip it and print a single clean warning
message instead of generating a kernel call trace:
ucsi_acpi USBC000:00: con0: Firmware bug: duplicate partner altmode SVID 0x8087 at offset 1, ignoring. Please update your system firmware.
This makes the error handling more user-friendly while still alerting
users to the firmware bug.
The fix applies to all three recipient types: partner (SOP), port (CON),
and plug (SOP_P) altmodes.
Fixes: a79f16efcd00 ("usb: typec: ucsi: Add support for the partner USB Modes")
Cc: stable@vger.kernel.org
Signed-off-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>
---
drivers/usb/typec/ucsi/ucsi.c | 81 +++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index 3f568f790f39..ebe7e0a223d7 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -602,9 +602,90 @@ static int ucsi_register_altmodes(struct ucsi_connector *con, u8 recipient)
i += num;
for (j = 0; j < num; j++) {
+ bool duplicate = false;
+ int k;
+
if (!alt[j].svid)
return 0;
+ /*
+ * Check if this altmode is already registered or is a duplicate
+ * within the current batch.
+ * Some firmware implementations incorrectly return the same
+ * altmode multiple times, either:
+ * 1. At different offsets in separate queries
+ * 2. Within the same query response (in alt[] array)
+ * Both cause sysfs duplicate errors during registration.
+ *
+ * We check for duplicates by comparing SVID and VDO (mid),
+ * which uniquely identify an altmode. If we find a match,
+ * skip registration to avoid kernel errors.
+ */
+
+ /* Check for duplicates in current batch first */
+ for (k = 0; k < j; k++) {
+ if (alt[k].svid == alt[j].svid && alt[k].mid == alt[j].mid) {
+ dev_warn_once(con->ucsi->dev,
+ "con%d: Firmware bug: duplicate altmode SVID 0x%04x in same response at offset %d, ignoring. Please update your system firmware.\n",
+ con->num, alt[j].svid, i - num + j);
+ duplicate = true;
+ break;
+ }
+ }
+
+ if (duplicate)
+ continue;
+
+ /* Check for duplicates in already registered altmodes */
+ if (recipient == UCSI_RECIPIENT_SOP) {
+ for (k = 0; k < UCSI_MAX_ALTMODES; k++) {
+ if (!con->partner_altmode[k])
+ break;
+ /*
+ * Some buggy firmware returns the same SVID multiple times
+ * with different VDOs. This causes duplicate device registration
+ * and sysfs errors. Check SVID only for partner altmodes.
+ */
+ if (con->partner_altmode[k]->svid == alt[j].svid) {
+ dev_warn(con->ucsi->dev,
+ "con%d: Firmware bug: duplicate partner altmode SVID 0x%04x (VDO 0x%08x vs 0x%08x) at offset %d, ignoring. Please update your system firmware.\n",
+ con->num, alt[j].svid, con->partner_altmode[k]->vdo,
+ alt[j].mid, i - num + j);
+ duplicate = true;
+ break;
+ }
+ }
+ } else if (recipient == UCSI_RECIPIENT_CON) {
+ for (k = 0; k < UCSI_MAX_ALTMODES; k++) {
+ if (!con->port_altmode[k])
+ break;
+ if (con->port_altmode[k]->svid == alt[j].svid &&
+ con->port_altmode[k]->vdo == alt[j].mid) {
+ dev_warn_once(con->ucsi->dev,
+ "con%d: Firmware bug: duplicate port altmode SVID 0x%04x at offset %d, ignoring. Please update your system firmware.\n",
+ con->num, alt[j].svid, i - num + j);
+ duplicate = true;
+ break;
+ }
+ }
+ } else if (recipient == UCSI_RECIPIENT_SOP_P) {
+ for (k = 0; k < UCSI_MAX_ALTMODES; k++) {
+ if (!con->plug_altmode[k])
+ break;
+ if (con->plug_altmode[k]->svid == alt[j].svid &&
+ con->plug_altmode[k]->vdo == alt[j].mid) {
+ dev_warn_once(con->ucsi->dev,
+ "con%d: Firmware bug: duplicate plug altmode SVID 0x%04x at offset %d, ignoring. Please update your system firmware.\n",
+ con->num, alt[j].svid, i - num + j);
+ duplicate = true;
+ break;
+ }
+ }
+ }
+
+ if (duplicate)
+ continue;
+
memset(&desc, 0, sizeof(desc));
desc.vdo = alt[j].mid;
desc.svid = alt[j].svid;
--
2.43.0
On Thu, Oct 16, 2025 at 01:53:32PM +0800, Chia-Lin Kao (AceLan) wrote: > Some firmware implementations incorrectly return the same altmode > multiple times at different offsets when queried via UCSI_GET_ALTERNATE_MODES. > This causes sysfs duplicate filename errors and kernel call traces when > the driver attempts to register the same altmode twice: > > sysfs: cannot create duplicate filename '/devices/.../typec/port0/port0.0/partner' > typec-thunderbolt port0-partner.1: failed to create symlinks > typec-thunderbolt port0-partner.1: probe with driver typec-thunderbolt failed with error -17 > > Detect duplicate altmodes by comparing SVID and VDO before registration. > If a duplicate is detected, skip it and print a single clean warning > message instead of generating a kernel call trace: > > ucsi_acpi USBC000:00: con0: Firmware bug: duplicate partner altmode SVID 0x8087 at offset 1, ignoring. Please update your system firmware. Is this firmware in devices you can buy, or was it just in devices that were pre-production? thanks, greg k-h
+Antony
On Thu, Oct 16, 2025 at 01:53:32PM +0800, Chia-Lin Kao (AceLan) wrote:
> Some firmware implementations incorrectly return the same altmode
> multiple times at different offsets when queried via UCSI_GET_ALTERNATE_MODES.
> This causes sysfs duplicate filename errors and kernel call traces when
> the driver attempts to register the same altmode twice:
>
> sysfs: cannot create duplicate filename '/devices/.../typec/port0/port0.0/partner'
> typec-thunderbolt port0-partner.1: failed to create symlinks
> typec-thunderbolt port0-partner.1: probe with driver typec-thunderbolt failed with error -17
>
> Detect duplicate altmodes by comparing SVID and VDO before registration.
> If a duplicate is detected, skip it and print a single clean warning
> message instead of generating a kernel call trace:
>
> ucsi_acpi USBC000:00: con0: Firmware bug: duplicate partner altmode SVID 0x8087 at offset 1, ignoring. Please update your system firmware.
>
> This makes the error handling more user-friendly while still alerting
> users to the firmware bug.
>
> The fix applies to all three recipient types: partner (SOP), port (CON),
> and plug (SOP_P) altmodes.
>
> Fixes: a79f16efcd00 ("usb: typec: ucsi: Add support for the partner USB Modes")
> Cc: stable@vger.kernel.org
> Signed-off-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>
Thank you for the patch. Before going forward with this, I would like
to make sure that Dell is not using the GET_ALTERNATE_MODES command in
some customised way deliberately, and that this really is a bug in the
EC firmware.
After seeing the trace output when this happens, it looked to me as
the first response to the GET_ALTERNATE_MODES fills the MID field in
the response data structure with different SVIDs for some reason
(maybe with all supported SVIDs)? If that's deliberate it means we
should drop the first response, and start registering from the second
one.
If I've understood correctly, we have people contacting Dell about
this.
thanks,
--
heikki
On Mon, Oct 20, 2025 at 12:18:31PM +0300, Heikki Krogerus wrote:
> +Antony
>
> On Thu, Oct 16, 2025 at 01:53:32PM +0800, Chia-Lin Kao (AceLan) wrote:
> > Some firmware implementations incorrectly return the same altmode
> > multiple times at different offsets when queried via UCSI_GET_ALTERNATE_MODES.
> > This causes sysfs duplicate filename errors and kernel call traces when
> > the driver attempts to register the same altmode twice:
> >
> > sysfs: cannot create duplicate filename '/devices/.../typec/port0/port0.0/partner'
> > typec-thunderbolt port0-partner.1: failed to create symlinks
> > typec-thunderbolt port0-partner.1: probe with driver typec-thunderbolt failed with error -17
> >
> > Detect duplicate altmodes by comparing SVID and VDO before registration.
> > If a duplicate is detected, skip it and print a single clean warning
> > message instead of generating a kernel call trace:
> >
> > ucsi_acpi USBC000:00: con0: Firmware bug: duplicate partner altmode SVID 0x8087 at offset 1, ignoring. Please update your system firmware.
> >
> > This makes the error handling more user-friendly while still alerting
> > users to the firmware bug.
> >
> > The fix applies to all three recipient types: partner (SOP), port (CON),
> > and plug (SOP_P) altmodes.
> >
> > Fixes: a79f16efcd00 ("usb: typec: ucsi: Add support for the partner USB Modes")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>
>
> Thank you for the patch. Before going forward with this, I would like
> to make sure that Dell is not using the GET_ALTERNATE_MODES command in
> some customised way deliberately, and that this really is a bug in the
> EC firmware.
Just to point out, we have had a similar issue with Lenovo Yoga c630,
see yoga_c630_ucsi_update_altmodes(), the EC was ignoring offset field.
>
> After seeing the trace output when this happens, it looked to me as
> the first response to the GET_ALTERNATE_MODES fills the MID field in
> the response data structure with different SVIDs for some reason
> (maybe with all supported SVIDs)? If that's deliberate it means we
> should drop the first response, and start registering from the second
> one.
>
> If I've understood correctly, we have people contacting Dell about
> this.
>
> thanks,
>
> --
> heikki
--
With best wishes
Dmitry
Hi Chia-Lin,
Mon, Oct 20, 2025 at 12:36:51PM +0300, Dmitry Baryshkov kirjoitti:
> On Mon, Oct 20, 2025 at 12:18:31PM +0300, Heikki Krogerus wrote:
> > +Antony
> >
> > On Thu, Oct 16, 2025 at 01:53:32PM +0800, Chia-Lin Kao (AceLan) wrote:
> > > Some firmware implementations incorrectly return the same altmode
> > > multiple times at different offsets when queried via UCSI_GET_ALTERNATE_MODES.
> > > This causes sysfs duplicate filename errors and kernel call traces when
> > > the driver attempts to register the same altmode twice:
> > >
> > > sysfs: cannot create duplicate filename '/devices/.../typec/port0/port0.0/partner'
> > > typec-thunderbolt port0-partner.1: failed to create symlinks
> > > typec-thunderbolt port0-partner.1: probe with driver typec-thunderbolt failed with error -17
> > >
> > > Detect duplicate altmodes by comparing SVID and VDO before registration.
> > > If a duplicate is detected, skip it and print a single clean warning
> > > message instead of generating a kernel call trace:
> > >
> > > ucsi_acpi USBC000:00: con0: Firmware bug: duplicate partner altmode SVID 0x8087 at offset 1, ignoring. Please update your system firmware.
> > >
> > > This makes the error handling more user-friendly while still alerting
> > > users to the firmware bug.
> > >
> > > The fix applies to all three recipient types: partner (SOP), port (CON),
> > > and plug (SOP_P) altmodes.
> > >
> > > Fixes: a79f16efcd00 ("usb: typec: ucsi: Add support for the partner USB Modes")
> > > Cc: stable@vger.kernel.org
> > > Signed-off-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>
> >
> > Thank you for the patch. Before going forward with this, I would like
> > to make sure that Dell is not using the GET_ALTERNATE_MODES command in
> > some customised way deliberately, and that this really is a bug in the
> > EC firmware.
>
>
> Just to point out, we have had a similar issue with Lenovo Yoga c630,
> see yoga_c630_ucsi_update_altmodes(), the EC was ignoring offset field.
I think we can reuse that function like Dmitry pointed out. Can you
check that?
thanks,
--
heikki
© 2016 - 2026 Red Hat, Inc.