diff options
author | Jett Rink <jettrink@chromium.org> | 2018-10-18 13:52:45 -0600 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-10-28 13:54:11 -0700 |
commit | 149190dd3a823d835be71ec4b4e4ae9e5120c774 (patch) | |
tree | 8f734d2d0b3c71ff0b24f6078739b881febb9ec3 /common | |
parent | e5e282e43718b7acd706a717dc0fa9a821505dfd (diff) | |
download | chrome-ec-149190dd3a823d835be71ec4b4e4ae9e5120c774.tar.gz |
usb-pd: send more request after wait
When we are not in an explicit contract, we still need to send more
requests attempts when we receive a WAIT control command. Otherwise,
the port partner can issue a hard reset.
BRANCH=none
BUG=b:117498337
TEST=hard reset boot loop goes away with this CL.
Change-Id: Iabe8f086659dc0d7a405fa9f17495fb1c61494cc
Signed-off-by: Jett Rink <jettrink@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1289311
Commit-Ready: Edward Hill <ecgh@chromium.org>
Reviewed-by: Edward Hill <ecgh@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/usb_pd_protocol.c | 72 |
1 files changed, 35 insertions, 37 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index e9e86be32b..988443aba1 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -1381,6 +1381,7 @@ static void handle_data_request(int port, uint16_t head, case PD_DATA_SOURCE_CAP: if ((pd[port].task_state == PD_STATE_SNK_DISCOVERY) || (pd[port].task_state == PD_STATE_SNK_TRANSITION) + || (pd[port].task_state == PD_STATE_SNK_REQUESTED) #ifdef CONFIG_USB_PD_VBUS_DETECT_NONE || (pd[port].task_state == PD_STATE_SNK_HARD_RESET_RECOVER) @@ -1650,49 +1651,46 @@ static void handle_ctrl_request(int port, uint16_t head, set_state(port, PD_STATE_SNK_READY); else if (pd[port].task_state == PD_STATE_SNK_REQUESTED) { /* - * Explicit Contract in place + * On reception of a WAIT message, transition to + * PD_STATE_SNK_READY after PD_T_SINK_REQUEST ms to + * send another request. * - * On reception of a WAIT message, transition to - * PD_STATE_SNK_READY after PD_T_SINK_REQUEST ms to - * send another reqest. + * On reception of a REJECT message, transition to + * PD_STATE_SNK_READY but don't resend the request if + * we already have a contract in place. * - * On reception of a REJECT messag, transition to - * PD_STATE_SNK_READY but don't resend the request. - * - * NO Explicit Contract in place - * - * On reception of a WAIT or REJECT message, - * transition to PD_STATE_SNK_DISCOVERY + * On reception of a REJECT message without a contract, + * transition to PD_STATE_SNK_DISCOVERY instead. */ - if (pd[port].flags & PD_FLAGS_EXPLICIT_CONTRACT) { - /* We have an explicit contract */ - if (type == PD_CTRL_WAIT) { - /* - * Trigger a new power request when - * we enter PD_STATE_SNK_READY - */ - pd[port].new_power_request = 1; + if (type == PD_CTRL_WAIT) { + /* + * Trigger a new power request when + * we enter PD_STATE_SNK_READY + */ + pd[port].new_power_request = 1; - /* - * After the request is triggered, - * make sure the request is sent. - */ - pd[port].prev_request_mv = 0; + /* + * After the request is triggered, + * make sure the request is sent. + */ + pd[port].prev_request_mv = 0; - /* - * Transition to PD_STATE_SNK_READY - * after PD_T_SINK_REQUEST ms. - */ - set_state_timeout(port, get_time().val + - PD_T_SINK_REQUEST, - PD_STATE_SNK_READY); - } else { - /* The request was rejected */ - set_state(port, PD_STATE_SNK_READY); - } + /* + * Transition to PD_STATE_SNK_READY + * after PD_T_SINK_REQUEST ms. + */ + set_state_timeout(port, + get_time().val + + PD_T_SINK_REQUEST, + PD_STATE_SNK_READY); } else { - /* No explicit contract */ - set_state(port, PD_STATE_SNK_DISCOVERY); + /* The request was rejected */ + const int in_contract = + pd[port].flags & + PD_FLAGS_EXPLICIT_CONTRACT; + set_state(port, + in_contract ? PD_STATE_SNK_READY + : PD_STATE_SNK_DISCOVERY); } } #endif |