summaryrefslogtreecommitdiff
path: root/common/usb_pd_alt_mode_dfp.c
diff options
context:
space:
mode:
authorEric Yilun Lin <yllin@chromium.org>2021-01-13 15:07:27 +0800
committerCommit Bot <commit-bot@chromium.org>2021-01-14 05:08:36 +0000
commitc4ad6ccf5d64e1af3abbaba257781ff02ee2a7ef (patch)
tree11e2d517b8dc1f9c7122882d212a3a744863df02 /common/usb_pd_alt_mode_dfp.c
parente26814fbbfb2c89ae4971b4707bbc836f3e8aa3f (diff)
downloadchrome-ec-c4ad6ccf5d64e1af3abbaba257781ff02ee2a7ef.tar.gz
USB-PD: filter duplicated SVID
We have seen some peripherals may broadcast duplicated SVID, and this might cause the SM in a weird state in that the SVID disocvering traverses sequentially by pd_get_next_mode(), and this cause the SM discovering SVID modes over and over again. We filter out the duplicated SVID to prevent such scenario. BUG=b:177285652 TEST=Plug adapter ADLX65YCC3A, and ensure no repeated discover_mode for NAKed SVIDs. BRANCH=none Change-Id: I68811be039e214c5045fb71bb7025bcc6226a051 Signed-off-by: Eric Yilun Lin <yllin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2626795 Reviewed-by: Diana Z <dzigterman@chromium.org>
Diffstat (limited to 'common/usb_pd_alt_mode_dfp.c')
-rw-r--r--common/usb_pd_alt_mode_dfp.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/common/usb_pd_alt_mode_dfp.c b/common/usb_pd_alt_mode_dfp.c
index 8f2643ff1d..5a7ed7052b 100644
--- a/common/usb_pd_alt_mode_dfp.c
+++ b/common/usb_pd_alt_mode_dfp.c
@@ -302,6 +302,23 @@ int pd_dfp_exit_mode(int port, enum tcpm_transmit_type type, uint16_t svid,
return 1;
}
+/*
+ * Check if the SVID has been recorded previously. Some peripherals provide
+ * duplicated SVID.
+ */
+static bool is_svid_duplicated(const struct pd_discovery *disc, uint16_t svid)
+{
+ int i;
+
+ for (i = 0; i < disc->svid_cnt; ++i)
+ if (disc->svids[i].svid == svid) {
+ CPRINTF("ERR:SVIDDUP\n");
+ return true;
+ }
+
+ return false;
+}
+
void dfp_consume_attention(int port, uint32_t *payload)
{
uint16_t svid = PD_VDO_VID(payload[0]);
@@ -383,14 +400,17 @@ void dfp_consume_svids(int port, enum tcpm_transmit_type type, int cnt,
svid0 = PD_VDO_SVID_SVID0(*ptr);
if (!svid0)
break;
- disc->svids[i].svid = svid0;
- disc->svid_cnt++;
+
+ if (!is_svid_duplicated(disc, svid0))
+ disc->svids[disc->svid_cnt++].svid = svid0;
svid1 = PD_VDO_SVID_SVID1(*ptr);
if (!svid1)
break;
- disc->svids[i + 1].svid = svid1;
- disc->svid_cnt++;
+
+ if (!is_svid_duplicated(disc, svid1))
+ disc->svids[disc->svid_cnt++].svid = svid1;
+
ptr++;
vdo++;
}