diff options
author | Alec Berg <alecaberg@chromium.org> | 2015-01-02 14:06:54 -0800 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-01-03 02:26:42 +0000 |
commit | 71fb0f9e11d3d1b4a7b2026994f2003815dd2799 (patch) | |
tree | 1e2c3640706ac76f1d99c736a1a125e39e8dc342 | |
parent | 017f151ea36a3309aec05ace79916ab3dae35ac1 (diff) | |
download | chrome-ec-71fb0f9e11d3d1b4a7b2026994f2003815dd2799.tar.gz |
pd: add new state to wait for getSinkCap response
Add new state to wait for getSinkCap response. We use the READY states
in the PD state machine to indicate that we are not waiting on a response.
This assumption is necessary for VDMs to know whether or not it is ok
to send. This CL fixes a bug in that assumption.
BUG=chrome-os-partner:33861
BRANCH=samus
TEST=load onto zinger. without this change, under the right circumstances
it was possible for a collision between a VDM (response to discover identity)
and an incoming response to the getSinkCap. This would cause the discovery
identity response to get dropped. with this change, when discover identity
response is queued it is delayed until after the getSinkCap response.
Change-Id: I16f4d5272e68bf699d0aecba12bdf6d6b8ff7fc7
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/238239
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | common/usb_pd_protocol.c | 13 | ||||
-rw-r--r-- | include/usb_pd.h | 1 |
2 files changed, 13 insertions, 1 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 4ae13bd127..dae4ae789f 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -938,6 +938,8 @@ static void handle_data_request(int port, uint16_t head, pd[port].flags |= PD_FLAGS_SNK_CAP_RECVD; /* snk cap 0 should be fixed PDO */ pd_update_pdo_flags(port, payload[0]); + if (pd[port].task_state == PD_STATE_SRC_GET_SINK_CAP) + set_state(port, PD_STATE_SRC_READY); break; case PD_DATA_VENDOR_DEF: handle_vdm_request(port, cnt, payload); @@ -1821,6 +1823,7 @@ void pd_task(void) !(pd[port].flags & PD_FLAGS_SNK_CAP_RECVD)) { /* Get sink cap to know if dual-role device */ send_control(port, PD_CTRL_GET_SINK_CAP); + set_state(port, PD_STATE_SRC_GET_SINK_CAP); pd[port].flags &= ~PD_FLAGS_GET_SNK_CAP_SENT; break; } @@ -1861,6 +1864,13 @@ void pd_task(void) set_state(port, PD_STATE_SOFT_RESET); timeout = 10 * MSEC; break; + case PD_STATE_SRC_GET_SINK_CAP: + if (pd[port].last_state != pd[port].task_state) + set_state_timeout(port, + get_time().val + + PD_T_SENDER_RESPONSE, + PD_STATE_SRC_READY); + break; case PD_STATE_SRC_DR_SWAP: if (pd[port].last_state != pd[port].task_state) { res = send_control(port, PD_CTRL_DR_SWAP); @@ -2747,7 +2757,8 @@ static int command_pd(int argc, char **argv) "SRC_DISCONNECTED", "SRC_HARD_RESET_RECOVER", "SRC_STARTUP", "SRC_DISCOVERY", "SRC_NEGOCIATE", "SRC_ACCEPTED", "SRC_POWERED", - "SRC_TRANSITION", "SRC_READY", "SRC_DR_SWAP", + "SRC_TRANSITION", "SRC_READY", "SRC_GET_SNK_CAP", + "SRC_DR_SWAP", #ifdef CONFIG_USB_PD_DUAL_ROLE "SRC_SWAP_INIT", "SRC_SWAP_SNK_DISABLE", "SRC_SWAP_SRC_DISABLE", "SRC_SWAP_STANDBY", diff --git a/include/usb_pd.h b/include/usb_pd.h index 13e8a982e2..f04281140e 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -576,6 +576,7 @@ enum pd_states { PD_STATE_SRC_POWERED, PD_STATE_SRC_TRANSITION, PD_STATE_SRC_READY, + PD_STATE_SRC_GET_SINK_CAP, PD_STATE_SRC_DR_SWAP, #ifdef CONFIG_USB_PD_DUAL_ROLE |