diff options
author | Diana Z <dzigterman@chromium.org> | 2021-07-13 16:22:02 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-07-27 17:27:30 +0000 |
commit | 07ecd26158f67190ff36dd550220160e684aaa33 (patch) | |
tree | 0af6f75a4386e00b1ccab3b94ac61ff8d2eeb84b /common | |
parent | c3bb0a19b8d66bbbf514cafce7df97606593417a (diff) | |
download | chrome-ec-07ecd26158f67190ff36dd550220160e684aaa33.tar.gz |
TCPMv2: Register Get_Source_Cap failures
When an attempt to gather source capabilities fails, we should avoid
probing for them again by internally tracking the number of capabilities
as -1. This saves us traffic on resets with partners that have no
source capabilities, and also prevents looping with buggy partners who
reply with an unexpected message.
BRANCH=None
BUG=b:191229962
TEST=on guybrush, ensure we only query a sink-only dongle once
Signed-off-by: Diana Z <dzigterman@chromium.org>
Change-Id: Iea56619d7aca5df7d1b38d8f0d6a69cac4a825a9
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3025865
Reviewed-by: Abe Levkoy <alevkoy@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/usbc/usb_pe_drp_sm.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index 9d0522f7ff..05d498f0d9 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -642,7 +642,7 @@ static struct policy_engine { /* Last received source cap */ uint32_t src_caps[PDO_MAX_OBJECTS]; - int src_cap_cnt; + int src_cap_cnt; /* -1 on error retrieving source caps */ /* Last received sink cap */ uint32_t snk_caps[PDO_MAX_OBJECTS]; @@ -2526,9 +2526,11 @@ static void pe_src_transition_supply_run(int port) /* * Setup to get Device Policy Manager to request * Source Capabilities, if needed, for possible - * PR_Swap + * PR_Swap. Get the number directly to avoid re-probing + * if the partner generated an error and left -1 for the + * count. */ - if (pd_get_src_cap_cnt(port) == 0) + if (pe[port].src_cap_cnt == 0) pd_dpm_request(port, DPM_REQUEST_GET_SRC_CAPS); set_state_pe(port, PE_SRC_READY); @@ -6916,13 +6918,23 @@ static void pe_dr_src_get_source_cap_run(int port) CAP_DUALROLE); set_state_pe(port, PE_SRC_READY); - } else if (type == PD_CTRL_REJECT || - type == PD_CTRL_NOT_SUPPORTED) { + } else if ((cnt == 0) && (type == PD_CTRL_REJECT || + type == PD_CTRL_NOT_SUPPORTED)) { + pd_set_src_caps(port, -1, NULL); set_state_pe(port, PE_SRC_READY); } else { + /* + * On protocol error, consider source cap + * retrieval a failure + */ + pd_set_src_caps(port, -1, NULL); set_state_pe(port, PE_SEND_SOFT_RESET); } return; + } else { + pd_set_src_caps(port, -1, NULL); + set_state_pe(port, PE_SEND_SOFT_RESET); + return; } } @@ -6958,7 +6970,10 @@ void pd_set_src_caps(int port, int cnt, uint32_t *src_caps) uint8_t pd_get_src_cap_cnt(int port) { - return pe[port].src_cap_cnt; + if (pe[port].src_cap_cnt > 0) + return pe[port].src_cap_cnt; + + return 0; } /* Track access to the PD discovery structures during HC execution */ |