Re: [PATCH 1/2] usb: typec: tcpm: improve handling of DISCOVER_MODES failures

From: Badhri Jagan Sridharan

Date: Tue Feb 17 2026 - 21:51:06 EST


On Fri, Feb 13, 2026 at 11:48 AM Sebastian Reichel
<sebastian.reichel@xxxxxxxxxxxxx> wrote:
>
> UGREEN USB-C Multifunction Adapter Model CM512 (AKA "Revodok 107")
> exposes two SVIDs: 0xff01 (DP Alt Mode) and 0x1d5c. The DISCOVER_MODES
> step succeeds for 0xff01 and gets a NAK for 0x1d5c. Currently this
> results in DP Alt Mode not being registered either, since the modes are
> only registered once all of them have been discovered. The NAK results
> in the processing being stopped and thus no Alt modes being registered.
>
> Improve the situation by handling the NAK gracefully and continue
> processing the other modes.
>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@xxxxxxxxxxxxx>

In v2, dont forget to add "Fixes:" and "Cc: stable@xxxxxxxxxxxxxxx"

Thanks,
Badhri

> ---
> drivers/usb/typec/tcpm/tcpm.c | 40 +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 39 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
> index be49a976428f..88cc27ad9514 100644
> --- a/drivers/usb/typec/tcpm/tcpm.c
> +++ b/drivers/usb/typec/tcpm/tcpm.c
> @@ -2329,8 +2329,46 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev,
> switch (cmd) {
> case CMD_DISCOVER_IDENT:
> case CMD_DISCOVER_SVID:
> - case CMD_DISCOVER_MODES:
> case VDO_CMD_VENDOR(0) ... VDO_CMD_VENDOR(15):
> + break;
> + case CMD_DISCOVER_MODES:
> + tcpm_log(port, "Skip SVID 0x%04x (failed to discover mode)",
> + PD_VDO_SVID_SVID0(p[0]));
> +
> + if (rx_sop_type == TCPC_TX_SOP) {
> + /* 6.4.4.3.3 */
> + modep->svid_index++;
> + if (modep->svid_index < modep->nsvids) {
> + u16 svid = modep->svids[modep->svid_index];
> + *response_tx_sop_type = TCPC_TX_SOP;
> + response[0] = VDO(svid, 1, svdm_version,
> + CMD_DISCOVER_MODES);
> + rlen = 1;
> + } else if (tcpm_cable_vdm_supported(port)) {
> + *response_tx_sop_type = TCPC_TX_SOP_PRIME;
> + response[0] = VDO(USB_SID_PD, 1,
> + typec_get_cable_svdm_version(typec),
> + CMD_DISCOVER_SVID);
> + rlen = 1;
> + } else {
> + tcpm_register_partner_altmodes(port);
> + }
> + } else if (rx_sop_type == TCPC_TX_SOP_PRIME) {
> + /* 6.4.4.3.3 */
> + modep_prime->svid_index++;
> + if (modep_prime->svid_index < modep_prime->nsvids) {
> + u16 svid = modep_prime->svids[modep_prime->svid_index];
> + *response_tx_sop_type = TCPC_TX_SOP_PRIME;
> + response[0] = VDO(svid, 1,
> + typec_get_cable_svdm_version(typec),
> + CMD_DISCOVER_MODES);
> + rlen = 1;
> + } else {
> + tcpm_register_plug_altmodes(port);
> + tcpm_register_partner_altmodes(port);
> + }
> + }
> +
> break;
> case CMD_ENTER_MODE:
> /* Back to USB Operation */
>
> --
> 2.51.0
>