pd: finitely sending of SNK_CAP in SRC_READY

Even a decent type-C device SHALL respond SNK_CAP query message when we are in
SRC_READY state, but in the case its mal implementation shouldn't get us being
trapped in an infinite loop of SRC_READY / SRC_GET_SNK_CAP states.

Introduce a counter to give up sending of SNK_CAP and just print a ERR
indication log when the partner device ignores SNK_CAP query.

BUG=none
BRANCH=samus
TEST=make buildall
     manual testing against the failing USB-C device

Change-Id: I4c4251b2264230d7dd30bd2b9fc2b56027ff0d5a
Signed-off-by: Bernard Shyu <bernard_shyu@bizlinktech.com>
Reviewed-on: https://chromium-review.googlesource.com/284035
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Commit-Queue: Alec Berg <alecaberg@chromium.org>
This commit is contained in:
Bernard Shyu
2015-07-08 19:28:01 +08:00
committed by ChromeOS Commit Bot
parent 0a8c6c0396
commit c08e3b2113
2 changed files with 15 additions and 11 deletions

View File

@@ -68,6 +68,7 @@ static const uint8_t pd_comm_enabled = 1;
#define PD_MESSAGE_ID_COUNT 7
#define PD_HARD_RESET_COUNT 2
#define PD_CAPS_COUNT 50
#define PD_SNK_CAP_RETRIES 3
enum vdm_states {
VDM_STATE_ERR_BUSY = -3,
@@ -1339,6 +1340,7 @@ void pd_task(void)
enum pd_cc_states new_cc_state;
timestamp_t now;
int caps_count = 0, hard_reset_sent = 0;
int snk_cap_count;
int evt;
/* Ensure the power supply is in the default state */
@@ -1602,6 +1604,7 @@ void pd_task(void)
/* reset various counters */
caps_count = 0;
pd[port].msg_id = 0;
snk_cap_count = 0;
set_state_timeout(
port,
#ifdef CONFIG_USBC_BACKWARDS_COMPATIBLE_DFP
@@ -1703,9 +1706,6 @@ void pd_task(void)
case PD_STATE_SRC_READY:
timeout = PD_T_SOURCE_ACTIVITY;
if (pd[port].last_state != pd[port].task_state)
pd[port].flags |= PD_FLAGS_GET_SNK_CAP_SENT;
/*
* Don't send any PD traffic if we woke up due to
* incoming packet or if VDO response pending to avoid
@@ -1716,13 +1716,17 @@ void pd_task(void)
break;
/* Send get sink cap if haven't received it yet */
if ((pd[port].flags & PD_FLAGS_GET_SNK_CAP_SENT) &&
if (pd[port].last_state != pd[port].task_state &&
!(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;
if (++snk_cap_count <= PD_SNK_CAP_RETRIES) {
/* 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);
break;
} else if (debug_level >= 1 &&
snk_cap_count == PD_SNK_CAP_RETRIES+1) {
CPRINTF("ERR SNK_CAP\n");
}
}
/* Check power role policy, which may trigger a swap */
@@ -2229,6 +2233,8 @@ void pd_task(void)
break;
}
/* Don't send GET_SINK_CAP on swap */
snk_cap_count = PD_SNK_CAP_RETRIES+1;
caps_count = 0;
pd[port].msg_id = 0;
pd[port].power_role = PD_ROLE_SOURCE;

View File

@@ -695,7 +695,6 @@ enum pd_states {
#define PD_FLAGS_PARTNER_DR_DATA (1 << 2) /* port partner is dualrole data */
#define PD_FLAGS_DATA_SWAPPED (1 << 3) /* data swap complete */
#define PD_FLAGS_SNK_CAP_RECVD (1 << 4) /* sink capabilities received */
#define PD_FLAGS_GET_SNK_CAP_SENT (1 << 5) /* get sink cap sent */
#define PD_FLAGS_EXPLICIT_CONTRACT (1 << 6) /* explicit pwr contract in place */
#define PD_FLAGS_SFT_RST_DIS_COMM (1 << 7) /* disable comms after soft reset */
#define PD_FLAGS_PREVIOUS_PD_CONN (1 << 8) /* previously PD connected */
@@ -709,7 +708,6 @@ enum pd_states {
PD_FLAGS_PARTNER_DR_DATA | \
PD_FLAGS_DATA_SWAPPED | \
PD_FLAGS_SNK_CAP_RECVD | \
PD_FLAGS_GET_SNK_CAP_SENT | \
PD_FLAGS_EXPLICIT_CONTRACT | \
PD_FLAGS_PREVIOUS_PD_CONN | \
PD_FLAGS_CHECK_PR_ROLE | \