diff options
author | Alec Berg <alecaberg@chromium.org> | 2015-01-04 10:38:19 -0800 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-01-06 23:43:12 +0000 |
commit | 563e7bed1ee5ec4b86b13d759507b5f185706c09 (patch) | |
tree | 5a14e0ffe85fa3df5774d8987b94a92d4ccc6c5e | |
parent | 5348dff126127a1fbecc38b8605017ff1b2a4e5a (diff) | |
download | chrome-ec-563e7bed1ee5ec4b86b13d759507b5f185706c09.tar.gz |
pd: fix timeouts during power swap and send soft reset on no CRC
Change behavior on timeouts during a power swap. If a power swap
fails in the final stages, go to disconnected state instead of
simply sending a hard reset.
When we fail to receive goodCRC to power swap or data swap commands,
send a soft reset instead of a hard reset.
BUG=chrome-os-partner:34989, chrome-os-partner:34980
BRANCH=samus
TEST=make -j buildall
Change-Id: I3fa9f1475e42c2754fb7eb15a75bc0b67ed1e2c0
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/238301
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | common/usb_pd_protocol.c | 79 |
1 files changed, 60 insertions, 19 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 610283ce0e..b231655080 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -538,7 +538,6 @@ static int send_validate_message(int port, uint16_t header, } } /* we failed all the re-transmissions */ - /* TODO: try HardReset */ if (debug_level >= 1) CPRINTF("TX NO ACK %04x/%d\n", header, cnt); return -1; @@ -1902,9 +1901,18 @@ void pd_task(void) case PD_STATE_SRC_DR_SWAP: if (pd[port].last_state != pd[port].task_state) { res = send_control(port, PD_CTRL_DR_SWAP); - if (res < 0) - set_state(port, - PD_STATE_HARD_RESET_SEND); + if (res < 0) { + timeout = 10*MSEC; + /* + * If failed to get goodCRC, send + * soft reset, otherwise ignore + * failure. + */ + set_state(port, res == -1 ? + PD_STATE_SOFT_RESET : + PD_STATE_SRC_READY); + break; + } /* Wait for accept or reject */ set_state_timeout(port, get_time().val + @@ -1916,9 +1924,18 @@ void pd_task(void) case PD_STATE_SRC_SWAP_INIT: if (pd[port].last_state != pd[port].task_state) { res = send_control(port, PD_CTRL_PR_SWAP); - if (res < 0) - set_state(port, - PD_STATE_HARD_RESET_SEND); + if (res < 0) { + timeout = 10*MSEC; + /* + * If failed to get goodCRC, send + * soft reset, otherwise ignore + * failure. + */ + set_state(port, res == -1 ? + PD_STATE_SOFT_RESET : + PD_STATE_SRC_READY); + break; + } /* Wait for accept or reject */ set_state_timeout(port, get_time().val + @@ -1949,16 +1966,19 @@ void pd_task(void) if (pd[port].last_state != pd[port].task_state) { /* Send PS_RDY */ res = send_control(port, PD_CTRL_PS_RDY); - if (res < 0) + if (res < 0) { + timeout = 10*MSEC; set_state(port, - PD_STATE_HARD_RESET_SEND); + PD_STATE_SRC_DISCONNECTED); + break; + } /* Switch to Rd */ pd_set_host_mode(port, 0); - /* Wait for PS_RDY from sink */ + /* Wait for PS_RDY from new source */ set_state_timeout(port, get_time().val + PD_T_PS_SOURCE_ON, - PD_STATE_HARD_RESET_EXECUTE); + PD_STATE_SNK_DISCONNECTED); } break; case PD_STATE_SUSPENDED: @@ -2220,9 +2240,18 @@ void pd_task(void) case PD_STATE_SNK_DR_SWAP: if (pd[port].last_state != pd[port].task_state) { res = send_control(port, PD_CTRL_DR_SWAP); - if (res < 0) - set_state(port, - PD_STATE_HARD_RESET_SEND); + if (res < 0) { + timeout = 10*MSEC; + /* + * If failed to get goodCRC, send + * soft reset, otherwise ignore + * failure. + */ + set_state(port, res == -1 ? + PD_STATE_SOFT_RESET : + PD_STATE_SNK_READY); + break; + } /* Wait for accept or reject */ set_state_timeout(port, get_time().val + @@ -2233,9 +2262,18 @@ void pd_task(void) case PD_STATE_SNK_SWAP_INIT: if (pd[port].last_state != pd[port].task_state) { res = send_control(port, PD_CTRL_PR_SWAP); - if (res < 0) - set_state(port, - PD_STATE_HARD_RESET_SEND); + if (res < 0) { + timeout = 10*MSEC; + /* + * If failed to get goodCRC, send + * soft reset, otherwise ignore + * failure. + */ + set_state(port, res == -1 ? + PD_STATE_SOFT_RESET : + PD_STATE_SNK_READY); + break; + } /* Wait for accept or reject */ set_state_timeout(port, get_time().val + @@ -2268,8 +2306,9 @@ void pd_task(void) if (pd_set_power_supply_ready(port)) { /* Restore Rd */ pd_set_host_mode(port, 0); + timeout = 10*MSEC; set_state(port, - PD_STATE_HARD_RESET_SEND); + PD_STATE_SNK_DISCONNECTED); break; } /* Wait for power supply to turn on */ @@ -2286,7 +2325,9 @@ void pd_task(void) if (res < 0) { /* Restore Rd */ pd_set_host_mode(port, 0); - set_state(port, PD_STATE_HARD_RESET_SEND); + timeout = 10 * MSEC; + set_state(port, PD_STATE_SNK_DISCONNECTED); + break; } caps_count = 0; |