summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorJett Rink <jettrink@chromium.org>2018-10-18 13:52:45 -0600
committerchrome-bot <chrome-bot@chromium.org>2018-10-28 13:54:11 -0700
commit149190dd3a823d835be71ec4b4e4ae9e5120c774 (patch)
tree8f734d2d0b3c71ff0b24f6078739b881febb9ec3 /common
parente5e282e43718b7acd706a717dc0fa9a821505dfd (diff)
downloadchrome-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.c72
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