From nobody Wed Jun 10 14:50:01 2026 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 39BAC40FDAD; Wed, 29 Apr 2026 16:33:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777480433; cv=none; b=Dm6JtaheYsK8g6DJDz3QP+tdcIubvMMl/X+TxKHSkLEupWUqHMn05Pt5dgUZmT81yldn84qC0vKO/m3hhyDHBajWGzVVebFqdXx8qC2hs6D95WXZGcwh3293szw/ZeHTM7NOZqSL660Rfa6QEz5HQ5jPjBqYb8CM05jkIvgeJ0Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777480433; c=relaxed/simple; bh=TPw9Tlmk/HUNTH+k14Sst3x2LqwRzkqqBfUqJ/gKRhY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=QRJRg6R2SgVl+TGjs1QwCC2Nw3HiBgm4qU7Ms3eJL/BkTzUzcs0sNGttQUw3x9DA3S0euVUS44WjKSi/Cg47CLQ3lygwIOlnyhc+lCtFmrrXazFYkUlvlKW5ddcnb7CX5F5ObWNbNFvvenAxuzHBOB1SZn1ZSUI6fI0xuaw3kmM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=Zb6YMZx7; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="Zb6YMZx7" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1777480428; bh=TPw9Tlmk/HUNTH+k14Sst3x2LqwRzkqqBfUqJ/gKRhY=; h=From:Date:Subject:To:Cc:From; b=Zb6YMZx7hAYDO5yWIAQ6eQid1P98fhIVyxJmcqiH8CgISPnbGcHX9ByAZLcc0LiWP dX17BzFdelAL/G0Z1cG+RBKC3tkgAD09DWVCZRXPIwu0F8YXLQzxMytv5Gf1nDDc6H 1FGibuCdmAc3oytECwNOrIlqvNuCYs5JLbxHdrKdPx8NC16kyd+tZLUpKXMjh1udRg MfrkQ1TCBmE5iUSzHvytn3ZeYlLcw2n54uJBMsCXNWHIb/Ok1/1OGf6cv8IBcGhxJh KBnnCjfr6mpIGFF7k1QtNgjdWAMJ83uveMdhhSpLUDhjbC9OQsdSJmqIH0EYMQQpFj AnoRuG61j+vkQ== Received: from jupiter.universe (unknown [100.64.1.62]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: sre) by bali.collaboradmins.com (Postfix) with ESMTPSA id 289D917E12E5; Wed, 29 Apr 2026 18:33:48 +0200 (CEST) Received: by jupiter.universe (Postfix, from userid 1000) id DA16E48002C; Wed, 29 Apr 2026 18:33:47 +0200 (CEST) From: Sebastian Reichel Date: Wed, 29 Apr 2026 18:33:32 +0200 Subject: [PATCH v4] usb: typec: tcpm: improve handling of DISCOVER_MODES failures Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260429-tcpm-discover-modes-nak-fix-v4-1-75945d0ed30f@collabora.com> X-B4-Tracking: v=1; b=H4sIANsy8mkC/43OTQrCMBCG4atI1o5M/ip15T3ERTJNNWibkkhQp Hc37UYRUZfvt3hm7iy56F1im8WdRZd98qEvoZYLRkfTHxz4pjQTKCoUXMKFhg4anyhkF6ELjUv QmxO0/gpY4xqt1aImzYowRFfmWd/tSx99uoR4m49lPq3/uZkDQm3JatNY5dpqS+F8NjZEs6LQs cnO4ulJ/OEJ4KBNJbH8i0KbT5589ervniyeUUqtW02cKv7ujeP4AEtwS49qAQAA X-Change-ID: 20260213-tcpm-discover-modes-nak-fix-09070bb529c5 To: Badhri Jagan Sridharan , Heikki Krogerus , Greg Kroah-Hartman , RD Babiera Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, kernel@collabora.com, stable@vger.kernel.org, Sebastian Reichel X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=7586; i=sebastian.reichel@collabora.com; h=from:subject:message-id; bh=TPw9Tlmk/HUNTH+k14Sst3x2LqwRzkqqBfUqJ/gKRhY=; b=owJ4nAFtApL9kA0DAAoB2O7X88g7+poByyZiAGnyMut94DhHgxstmZH78bwxYzj8zj0oVfIMx z1v+pwri18TwIkCMwQAAQoAHRYhBO9mDQdGP4tyanlUE9ju1/PIO/qaBQJp8jLrAAoJENju1/PI O/qaJ7QP/iA0uLcT6HreKlWmsvBmRPq2EF0Z6Wmjeb/L/D2d7HjMgZYyFydo3RSBGbrlyIB7Yj9 e2GeHXkDdq+e9gdctz9quRY2aq2DB7aPZJBzbWl4vzdQyowPUzU4Xe/wMUyV7S1NRtQQetKyZJY daxbhkL/Ll6z+XpPXQzUDvql2EMxs6rXhQ4i6hNO0TUpsunDFV7aBuDaqmBN0OBhO2bVl6NvjFO g7vyGU9PqKGP8DwxTs5tvY5EmQBGdqPrj+1O/FlyHcF//bVPmkhSAJdG049G7+rVbCTxEw4t2/e p9LDvvXzGr7vUlPtPHZVcjStUckDfdZCb93E+Kthk7wjcH59IbQJs8snj5ERoRVBT6VaIKSf3sO Yh9UZcVRi1e8GWlxv6HAR8ZPdvR1XtYY8bD/jYnjzcr9xsyhz2tu7ePrQLhanXl7tWdZoc9QTqZ uJRtm0rCVaIocZKkD95YTFiNNgnkkG3ShVjh6MG97vSSfNx37iXCATun5es96qJcHpppP5EqjA5 EtgHiVT0GpkFL7NOyE1v5+ca6jIIw2HDzBz+SQGv2qqDCVfzYYX5hxx55S3CZxvpp+/+OjnY/Kn DjwKOSXFlIqoYJwXM5QOutTqJK4v/swC209dIY1at86tIhziQCd2baATDafndY2JNzpQCmhstb+ lQQeaKH1lpMd6L4QI1kYt5Q== X-Developer-Key: i=sebastian.reichel@collabora.com; a=openpgp; fpr=EF660D07463F8B726A795413D8EED7F3C83BFA9A 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. Before this change, the TCPM log ends like this: (more log entries before this) [ 5.028287] AMS DISCOVER_SVIDS finished [ 5.028291] cc:=3D4 [ 5.040040] SVID 1: 0xff01 [ 5.040054] SVID 2: 0x1d5c [ 5.040082] AMS DISCOVER_MODES start [ 5.040096] PD TX, header: 0x1b6f [ 5.050946] PD TX complete, status: 0 [ 5.059609] PD RX, header: 0x264f [1] [ 5.059626] Rx VDM cmd 0xff018043 type 1 cmd 3 len 2 [ 5.059640] AMS DISCOVER_MODES finished [ 5.059644] cc:=3D4 [ 5.069994] Alternate mode 0: SVID 0xff01, VDO 1: 0x000c0045 [ 5.070029] AMS DISCOVER_MODES start [ 5.070043] PD TX, header: 0x1d6f [ 5.081139] PD TX complete, status: 0 [ 5.087498] PD RX, header: 0x184f [1] [ 5.087515] Rx VDM cmd 0x1d5c8083 type 2 cmd 3 len 1 [ 5.087529] AMS DISCOVER_MODES finished [ 5.087534] cc:=3D4 (no further log entries after this point) After this patch the TCPM log looks exactly the same, but then continues like this: [ 5.100222] Skip SVID 0x1d5c (failed to discover mode) [ 5.101699] AMS DFP_TO_UFP_ENTER_MODE start (log goes on as the system initializes DP AltMode) Cc: stable@vger.kernel.org Fixes: 41d9d75344d9 ("usb: typec: tcpm: add discover svids and discover mod= es support for sop'") Reviewed-by: Heikki Krogerus Signed-off-by: Sebastian Reichel Reviewed-by: Badhri Jagan Sridharan Reviewed-by: RD Babiera --- Changes in v4: - Link to v3: https://lore.kernel.org/r/20260309-tcpm-discover-modes-nak-fi= x-v3-1-a4447f5c1c61@collabora.com - Rebase to v7.1-rc1 - Collect Reviewed-by from Heikki Krogerus Changes in v3: - Link to v2: https://lore.kernel.org/r/20260303-tcpm-discover-modes-nak-fi= x-v2-1-5a630070025a@collabora.com - Move svdm_consume_modes() out of tcpm_handle_discover_mode() (Heikki Krog= erus) - Move rlen return pointer argument into proper return code (Heikki Krogeru= s) - Drop multiple tcpm_handle_discover_mode() arguments by re-getting them in the function (Heikki Krogerus) - Restructure if/else branches after these changes to make checkpatch happy - Did not pick up R-b tag from Badhri Jagan Sridharan due to the amount of changes Changes in v2: - Link to v1: https://lore.kernel.org/r/20260213-tcpm-discover-modes-nak-fi= x-v1-0-9bcb5adb4ef6@collabora.com - Squash patches (Badhri Jagan Sridharan) - Add Fixes tag (Badhri Jagan Sridharan) - Move common svdm_consume_modes out of conditional statement (Badhri Jagan= Sridharan) - Add TCPM log to commit message (Badhri Jagan Sridharan) --- drivers/usb/typec/tcpm/tcpm.c | 97 +++++++++++++++++++++++++++------------= ---- 1 file changed, 61 insertions(+), 36 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index dfbb94ddc98a..44ab7e0e5d50 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -2142,6 +2142,55 @@ static bool tcpm_cable_vdm_supported(struct tcpm_por= t *port) tcpm_can_communicate_sop_prime(port); } =20 +static int tcpm_handle_discover_mode(struct tcpm_port *port, u32 *response, + enum tcpm_transmit_type rx_sop_type, + enum tcpm_transmit_type *response_tx_sop_type) +{ + struct typec_port *typec =3D port->typec_port; + struct pd_mode_data *modep; + + if (rx_sop_type =3D=3D TCPC_TX_SOP) { + modep =3D &port->mode_data; + modep->svid_index++; + + if (modep->svid_index < modep->nsvids) { + u16 svid =3D modep->svids[modep->svid_index]; + *response_tx_sop_type =3D TCPC_TX_SOP; + response[0] =3D VDO(svid, 1, + typec_get_negotiated_svdm_version(typec), + CMD_DISCOVER_MODES); + return 1; + } + + if (tcpm_cable_vdm_supported(port)) { + *response_tx_sop_type =3D TCPC_TX_SOP_PRIME; + response[0] =3D VDO(USB_SID_PD, 1, + typec_get_cable_svdm_version(typec), + CMD_DISCOVER_SVID); + return 1; + } + + tcpm_register_partner_altmodes(port); + } else if (rx_sop_type =3D=3D TCPC_TX_SOP_PRIME) { + modep =3D &port->mode_data_prime; + modep->svid_index++; + + if (modep->svid_index < modep->nsvids) { + u16 svid =3D modep->svids[modep->svid_index]; + *response_tx_sop_type =3D TCPC_TX_SOP_PRIME; + response[0] =3D VDO(svid, 1, + typec_get_cable_svdm_version(typec), + CMD_DISCOVER_MODES); + return 1; + } + + tcpm_register_plug_altmodes(port); + tcpm_register_partner_altmodes(port); + } + + return 0; +} + static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev, const u32 *p, int cnt, u32 *response, enum adev_actions *adev_action, @@ -2399,41 +2448,11 @@ static int tcpm_pd_svdm(struct tcpm_port *port, str= uct typec_altmode *adev, } break; case CMD_DISCOVER_MODES: - if (rx_sop_type =3D=3D TCPC_TX_SOP) { - /* 6.4.4.3.3 */ - svdm_consume_modes(port, p, cnt, rx_sop_type); - modep->svid_index++; - if (modep->svid_index < modep->nsvids) { - u16 svid =3D modep->svids[modep->svid_index]; - *response_tx_sop_type =3D TCPC_TX_SOP; - response[0] =3D VDO(svid, 1, svdm_version, - CMD_DISCOVER_MODES); - rlen =3D 1; - } else if (tcpm_cable_vdm_supported(port)) { - *response_tx_sop_type =3D TCPC_TX_SOP_PRIME; - response[0] =3D VDO(USB_SID_PD, 1, - typec_get_cable_svdm_version(typec), - CMD_DISCOVER_SVID); - rlen =3D 1; - } else { - tcpm_register_partner_altmodes(port); - } - } else if (rx_sop_type =3D=3D TCPC_TX_SOP_PRIME) { - /* 6.4.4.3.3 */ - svdm_consume_modes(port, p, cnt, rx_sop_type); - modep_prime->svid_index++; - if (modep_prime->svid_index < modep_prime->nsvids) { - u16 svid =3D modep_prime->svids[modep_prime->svid_index]; - *response_tx_sop_type =3D TCPC_TX_SOP_PRIME; - response[0] =3D VDO(svid, 1, - typec_get_cable_svdm_version(typec), - CMD_DISCOVER_MODES); - rlen =3D 1; - } else { - tcpm_register_plug_altmodes(port); - tcpm_register_partner_altmodes(port); - } - } + /* 6.4.4.3.3 */ + svdm_consume_modes(port, p, cnt, rx_sop_type); + rlen =3D tcpm_handle_discover_mode(port, response, + rx_sop_type, + response_tx_sop_type); break; case CMD_ENTER_MODE: *response_tx_sop_type =3D rx_sop_type; @@ -2476,9 +2495,15 @@ static int tcpm_pd_svdm(struct tcpm_port *port, stru= ct 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])); + rlen =3D tcpm_handle_discover_mode(port, response, + rx_sop_type, + response_tx_sop_type); + break; case CMD_ENTER_MODE: /* Back to USB Operation */ *adev_action =3D ADEV_NOTIFY_USB_AND_QUEUE_VDM; --- base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731 change-id: 20260213-tcpm-discover-modes-nak-fix-09070bb529c5 Best regards, --=20 Sebastian Reichel