From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
To: "Chia-Lin Kao (AceLan)" <acelan.kao@canonical.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>,
Fedor Pchelkin <boddah8794@gmail.com>,
Andrei Kuchynski <akuchynski@chromium.org>,
Venkat Jayaraman <venkat.jayaraman@intel.com>,
Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>,
linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 1/3] usb: typec: ucsi: Detect and skip duplicate altmodes from buggy firmware
Date: Mon, 17 Nov 2025 11:00:29 +0200 [thread overview]
Message-ID: <aRrkLczHJzONnxtT@kuha.fi.intel.com> (raw)
In-Reply-To: <20251111010541.145421-1-acelan.kao@canonical.com>
Hi,
Tue, Nov 11, 2025 at 09:05:39AM +0800, Chia-Lin Kao (AceLan) kirjoitti:
> 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: con2: Firmware bug: duplicate partner altmode SVID 0x8087 (VDO 0x8087a043 vs 0x00000001) 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 duplicate detection logic is implemented in a reusable helper
> function ucsi_altmode_is_duplicate() and used in ucsi_register_altmodes().
> 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 | 77 +++++++++++++++++++++++++++++++++++
> 1 file changed, 77 insertions(+)
>
> diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
> index 3f568f790f39..7b79e7491094 100644
> --- a/drivers/usb/typec/ucsi/ucsi.c
> +++ b/drivers/usb/typec/ucsi/ucsi.c
> @@ -556,6 +556,74 @@ ucsi_register_altmodes_nvidia(struct ucsi_connector *con, u8 recipient)
> return 0;
> }
>
> +/*
> + * Check if an altmode is a duplicate. Some firmware implementations
> + * incorrectly return the same altmode multiple times, causing sysfs errors.
> + * Returns true if the altmode should be skipped.
> + */
> +static bool ucsi_altmode_is_duplicate(struct ucsi_connector *con, u8 recipient,
> + const struct ucsi_altmode *alt_batch, int batch_idx,
> + u16 svid, u32 vdo, int offset)
> +{
> + int k;
> +
> + /* Check for duplicates within the current batch first */
> + for (k = 0; k < batch_idx; k++) {
> + if (alt_batch[k].svid == svid && alt_batch[k].mid == vdo) {
> + 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, svid, offset);
> + return true;
> + }
> + }
> +
> + /* 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 == svid) {
I'm not sure this works. Some vendor specific modes always come in
pairs. Check Apple for example. I think you always need to check the
VID on top of the 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, svid, con->partner_altmode[k]->vdo,
> + vdo, offset);
> + return true;
> + }
> + }
> + } 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 == svid &&
> + con->port_altmode[k]->vdo == vdo) {
> + 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, svid, offset);
> + return true;
> + }
> + }
> + } 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 == svid &&
> + con->plug_altmode[k]->vdo == vdo) {
> + 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, svid, offset);
> + return true;
> + }
> + }
> + }
struct typec_altmode *altmodes;
switch (recipient) {
case UCSI_RECIPIENT_CON:
altmodes = con->port->altmode;
break;
case UCSI_RECIPIENT_SOP_P:
altmodes = con->plug_altmode;
break;
...
> +
> + return false;
> +}
> +
> static int ucsi_register_altmodes(struct ucsi_connector *con, u8 recipient)
> {
> int max_altmodes = UCSI_MAX_ALTMODES;
> @@ -605,6 +673,15 @@ static int ucsi_register_altmodes(struct ucsi_connector *con, u8 recipient)
> if (!alt[j].svid)
> return 0;
>
> + /*
> + * Check for duplicates in current batch and already
> + * registered altmodes. Skip if duplicate found.
> + */
> + if (ucsi_altmode_is_duplicate(con, recipient, alt, j,
> + alt[j].svid, alt[j].mid,
> + i - num + j))
> + continue;
> +
> memset(&desc, 0, sizeof(desc));
> desc.vdo = alt[j].mid;
> desc.svid = alt[j].svid;
> --
> 2.43.0
thanks,
--
heikki
next prev parent reply other threads:[~2025-11-17 9:00 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-11 1:05 [PATCH v2 1/3] usb: typec: ucsi: Detect and skip duplicate altmodes from buggy firmware Chia-Lin Kao (AceLan)
2025-11-11 1:05 ` [PATCH v2 2/3] usb: typec: ucsi: Add duplicate detection to nvidia registration path Chia-Lin Kao (AceLan)
2025-11-11 16:54 ` kernel test robot
2025-11-11 1:05 ` [PATCH v2 3/3] usb: typec: ucsi: yoga_c630: Remove redundant duplicate altmode handling Chia-Lin Kao (AceLan)
2025-11-17 9:00 ` Heikki Krogerus [this message]
2025-12-04 3:08 ` [PATCH v2 1/3] usb: typec: ucsi: Detect and skip duplicate altmodes from buggy firmware Chia-Lin Kao (AceLan)
2025-12-23 9:43 ` Heikki Krogerus
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aRrkLczHJzONnxtT@kuha.fi.intel.com \
--to=heikki.krogerus@linux.intel.com \
--cc=acelan.kao@canonical.com \
--cc=akuchynski@chromium.org \
--cc=boddah8794@gmail.com \
--cc=dmitry.baryshkov@oss.qualcomm.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=myrrhperiwinkle@qtmlabs.xyz \
--cc=venkat.jayaraman@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox