summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Wang <frank.wang@rock-chips.com>2023-03-16 16:11:49 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-05-24 17:32:41 +0100
commit6a4cef8244de439f203c5f2216d8ec3d015f8c4b (patch)
tree3f5ca0e0c0a98702228747b8a3a4c5461be4e730
parent1edff076cc41b8106b84f6c0a5011e8a440c489f (diff)
downloadlinux-stable-6a4cef8244de439f203c5f2216d8ec3d015f8c4b.tar.gz
linux-stable-6a4cef8244de439f203c5f2216d8ec3d015f8c4b.tar.bz2
linux-stable-6a4cef8244de439f203c5f2216d8ec3d015f8c4b.zip
usb: typec: tcpm: fix multiple times discover svids error
[ Upstream commit dac3b192107b978198e89ec0f77375738352e0c8 ] PD3.0 Spec 6.4.4.3.2 say that only Responder supports 12 or more SVIDs, the Discover SVIDs Command Shall be executed multiple times until a Discover SVIDs VDO is returned ending either with a SVID value of 0x0000 in the last part of the last VDO or with a VDO containing two SVIDs with values of 0x0000. In the current implementation, if the last VDO does not find that the Discover SVIDs Command would be executed multiple times even if the Responder SVIDs are less than 12, and we found some odd dockers just meet this case. So fix it. Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Frank Wang <frank.wang@rock-chips.com> Link: https://lore.kernel.org/r/20230316081149.24519-1-frank.wang@rock-chips.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/usb/typec/tcpm/tcpm.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index 032d21a96779..524099634a1d 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -1514,7 +1514,21 @@ static bool svdm_consume_svids(struct tcpm_port *port, const u32 *p, int cnt)
pmdata->svids[pmdata->nsvids++] = svid;
tcpm_log(port, "SVID %d: 0x%x", pmdata->nsvids, svid);
}
- return true;
+
+ /*
+ * PD3.0 Spec 6.4.4.3.2: The SVIDs are returned 2 per VDO (see Table
+ * 6-43), and can be returned maximum 6 VDOs per response (see Figure
+ * 6-19). If the Respondersupports 12 or more SVID then the Discover
+ * SVIDs Command Shall be executed multiple times until a Discover
+ * SVIDs VDO is returned ending either with a SVID value of 0x0000 in
+ * the last part of the last VDO or with a VDO containing two SVIDs
+ * with values of 0x0000.
+ *
+ * However, some odd dockers support SVIDs less than 12 but without
+ * 0x0000 in the last VDO, so we need to break the Discover SVIDs
+ * request and return false here.
+ */
+ return cnt == 7;
abort:
tcpm_log(port, "SVID_DISCOVERY_MAX(%d) too low!", SVID_DISCOVERY_MAX);
return false;