From e3890838a448db5ac7b4a11252d5aff5213f34ca Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Mon, 16 Sep 2019 00:56:30 -0700 Subject: usb_pd: Send SOP' DiscIdent messages on SOP NAKs Currently, the only scenario where an SOP' message is sent is when we receive a SOP DiscIdentity Response from the UFP. However, we should be able to query the cable characteristics even if the UFP responds with a NAK. So, add handling to send a SOP' DiscIdentity even if we receive a NAK. This will not otherwise disrupt the PD connection flow. Note that there may be other situations where SOP' messages can be sent, but aren't currently being sent. BUG=chromium:1005941 BRANCH=None TEST=make -j buildall; Test on a hatch with a Pixel 2 DUT. Cable correctly responds with Cable information even after the EC receives a UFP DiscIdentity NAK. Change-Id: Ia856f2eb1547f09ae1dc0318021ad9f2458fc25a Signed-off-by: Prashant Malani Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1808057 Reviewed-by: Daisuke Nojiri --- common/usb_pd_policy.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'common/usb_pd_policy.c') diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c index 74291e1e23..f8499cba0f 100644 --- a/common/usb_pd_policy.c +++ b/common/usb_pd_policy.c @@ -264,6 +264,9 @@ static void dfp_consume_identity(int port, int cnt, uint32_t *payload) static void dfp_consume_cable_response(int port, int cnt, uint32_t *payload) { + if (cable[port].is_identified) + return; + if (is_vdo_present(cnt, VDO_INDEX_IDH)) { cable[port].type = PD_IDH_PTYPE(payload[VDO_INDEX_IDH]); if (is_vdo_present(cnt, VDO_INDEX_PTYPE_CABLE1)) @@ -280,6 +283,7 @@ static void dfp_consume_cable_response(int port, int cnt, uint32_t *payload) cable[port].rev = PD_REV30; cable[port].attr2.raw_value = payload[VDO_INDEX_PTYPE_CABLE2]; } + cable[port].is_identified = 1; } static int dfp_discover_ident(uint32_t *payload) @@ -726,9 +730,11 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) /* Received a SOP Discover Ident Message */ } else if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) { dfp_consume_identity(port, cnt, payload); - rsize = dfp_discover_ident(payload); /* Send SOP' Discover Ident message */ - enable_transmit_sop_prime(port); + if (!cable[port].is_identified) { + rsize = dfp_discover_ident(payload); + enable_transmit_sop_prime(port); + } } else { dfp_consume_identity(port, cnt, payload); rsize = dfp_discover_svids(payload); @@ -820,8 +826,13 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) rsize = 0; } } else if (cmd_type == CMDT_RSP_NAK) { - /* nothing to do */ rsize = 0; + /* Send SOP' Discover Ident message, if not already received. */ + if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP) && + !cable[port].is_identified && (cmd == CMD_DISCOVER_IDENT)) { + rsize = dfp_discover_ident(payload); + enable_transmit_sop_prime(port); + } #endif /* CONFIG_USB_PD_ALT_MODE_DFP */ } else { CPRINTF("ERR:CMDT:%d\n", cmd); @@ -881,6 +892,11 @@ static int command_cable(int argc, char **argv) if (*e || port >= CONFIG_USB_PD_PORT_COUNT) return EC_ERROR_PARAM2; + if (!cable[port].is_identified) { + ccprintf("Cable not identified.\n"); + return EC_SUCCESS; + } + ccprintf("Cable Type: "); if (cable[port].type != IDH_PTYPE_PCABLE && cable[port].type != IDH_PTYPE_ACABLE) { -- cgit v1.2.1