diff options
author | Todd Broch <tbroch@chromium.org> | 2014-09-05 15:03:02 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-09-11 20:00:07 +0000 |
commit | 7698c323eae7da62890a7d01447894629d29b22b (patch) | |
tree | b643b71dbe4e6cc74aa379d40fa3f5b6f8910d20 | |
parent | 5bb0fd6b053c8f62993ce521c43daffb50b69a66 (diff) | |
download | chrome-ec-7698c323eae7da62890a7d01447894629d29b22b.tar.gz |
samus: Add host command to query USB type-C accessory attached.
PD accessories that are RW update-able will broadcast their rw_hash
SHA1 digest upon connection to the PD MCU which will store it.
For update purposes, the host needs that accessories device id and
rw_hash to determine its proper firmware update payload.
This CL creates a host command that requests the type-C accessory info
attached to a particular port. It also implements an ectool command
to expose the host command.
BRANCH=none
BUG=chrome-os-partner:31361
TEST=manual,
# connect zinger to port 1 on samus
ectool --dev=1 --interface=lpc infopddev 1
Port:0 Device:1 Hash: 0x7f4d7a13 0xf07b65b9 0x41181e10 0xb99b3d5f 0x9dee1206
ectool --dev=1 --interface=lpc infopddev 0
Port:0 has no valid device
Also do the same on port 0 with similar results.
Change-Id: Id63c7edad77a43d43c14d8cd6bd96e08d0d9b501
Signed-off-by: Todd Broch <tbroch@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/216814
Reviewed-by: Alec Berg <alecaberg@chromium.org>
-rw-r--r-- | board/fruitpie/usb_pd_policy.c | 16 | ||||
-rw-r--r-- | board/samus_pd/usb_pd_policy.c | 16 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 55 | ||||
-rw-r--r-- | include/ec_commands.h | 7 | ||||
-rw-r--r-- | include/usb_pd.h | 5 | ||||
-rw-r--r-- | util/ectool.c | 40 |
6 files changed, 115 insertions, 24 deletions
diff --git a/board/fruitpie/usb_pd_policy.c b/board/fruitpie/usb_pd_policy.c index 0a4b1be7ee..e9f32efb20 100644 --- a/board/fruitpie/usb_pd_policy.c +++ b/board/fruitpie/usb_pd_policy.c @@ -139,6 +139,7 @@ int pd_board_checks(void) int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) { int cmd = PD_VDO_CMD(payload[0]); + uint8_t dev_id = 0; ccprintf("VDM/%d [%d] %08x\n", cnt, cmd, payload[0]); /* make sure we have some payload */ @@ -152,16 +153,17 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) ccprintf("version: %s\n", (char *)(payload+1)); break; case VDO_CMD_READ_INFO: - /* copy hash */ - if (cnt >= 6) - pd_dev_store_rw_hash(port, payload + 1); - /* if last word is present, it contains lots of info */ - if (cnt == 7) - ccprintf("Dev:%d SW:%d RW:%d\n", - VDO_INFO_HW_DEV_ID(payload[6]), + if (cnt == 7) { + dev_id = VDO_INFO_HW_DEV_ID(payload[6]); + ccprintf("Dev:%d SW:%d RW:%d\n", dev_id, VDO_INFO_SW_DBG_VER(payload[6]), VDO_INFO_IS_RW(payload[6])); + } + /* copy hash */ + if (cnt >= 6) + pd_dev_store_rw_hash(port, dev_id, payload + 1); + break; } diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c index bf24b2eb07..97bab9338f 100644 --- a/board/samus_pd/usb_pd_policy.c +++ b/board/samus_pd/usb_pd_policy.c @@ -154,6 +154,7 @@ int pd_board_checks(void) int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) { int cmd = PD_VDO_CMD(payload[0]); + uint8_t dev_id = 0; ccprintf("VDM/%d [%d] %08x\n", cnt, cmd, payload[0]); /* make sure we have some payload */ @@ -167,16 +168,17 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload) ccprintf("version: %s\n", (char *)(payload+1)); break; case VDO_CMD_READ_INFO: - /* copy hash */ - if (cnt >= 6) - pd_dev_store_rw_hash(port, payload + 1); - /* if last word is present, it contains lots of info */ - if (cnt == 7) - ccprintf("Dev:%d SW:%d RW:%d\n", - VDO_INFO_HW_DEV_ID(payload[6]), + if (cnt == 7) { + dev_id = VDO_INFO_HW_DEV_ID(payload[6]); + ccprintf("Dev:%d SW:%d RW:%d\n", dev_id, VDO_INFO_SW_DBG_VER(payload[6]), VDO_INFO_IS_RW(payload[6])); + } + /* copy hash */ + if (cnt >= 6) + pd_dev_store_rw_hash(port, dev_id, payload + 1); + break; case VDO_CMD_CURRENT: ccprintf("Current: %dmA\n", payload[1]); diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 5923164746..55f17a0eb0 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -253,7 +253,8 @@ static struct pd_protocol { uint32_t vdo_data[VDO_MAX_SIZE]; uint8_t vdo_count; - /* Attached ChromeOS device RW hash */ + /* Attached ChromeOS device id & RW hash */ + uint8_t dev_id; uint32_t dev_rw_hash[SHA1_DIGEST_SIZE/4]; } pd[PD_PORT_COUNT]; @@ -290,9 +291,11 @@ static inline void set_state(int port, enum pd_states next_state) pd[port].task_state = next_state; #ifdef CONFIG_USBC_SS_MUX - if (next_state == PD_STATE_SRC_DISCONNECTED) + if (next_state == PD_STATE_SRC_DISCONNECTED) { + pd[port].dev_id = 0; board_set_usb_mux(port, TYPEC_MUX_NONE, pd[port].polarity); + } #endif /* Log state transition, except for toggling between sink and source */ @@ -1083,9 +1086,21 @@ static void pd_vdm_send_state_machine(int port) } } -void pd_dev_store_rw_hash(int port, uint32_t *rw_hash) +static inline void pd_dev_dump_info(uint8_t dev_id, uint32_t *hash) { + int j; + ccprintf("Device:%d Hash:", dev_id); + for (j = 0; j < SHA1_DIGEST_SIZE/4; j++) + ccprintf(" 0x%08x", hash[j]); + ccprintf("\n"); +} + +void pd_dev_store_rw_hash(int port, uint8_t dev_id, uint32_t *rw_hash) +{ + pd[port].dev_id = dev_id; memcpy(pd[port].dev_rw_hash, rw_hash, SHA1_DIGEST_SIZE); + if (debug_level >= 1) + pd_dev_dump_info(dev_id, rw_hash); } #ifdef CONFIG_USB_PD_DUAL_ROLE @@ -1700,14 +1715,11 @@ static int command_pd(int argc, char **argv) ccprintf("Ports %s\n", enable ? "enabled" : "disabled"); return EC_SUCCESS; } else if (!strncasecmp(argv[1], "rwhashtable", 3)) { - int i, j; + int i; struct ec_params_usb_pd_rw_hash_entry *p; for (i = 0; i < RW_HASH_ENTRIES; i++) { p = &rw_hash_table[i]; - ccprintf("Device:%d Hash:", p->dev_id); - for (j = 0; j < SHA1_DIGEST_SIZE/4; j++) - ccprintf(" 0x%08x", p->dev_rw_hash.w[j]); - ccprintf("\n"); + pd_dev_dump_info(p->dev_id, p->dev_rw_hash.w); } return EC_SUCCESS; } @@ -2028,4 +2040,31 @@ DECLARE_HOST_COMMAND(EC_CMD_USB_PD_RW_HASH_ENTRY, hc_remote_rw_hash_entry, EC_VER_MASK(0)); +static int hc_remote_pd_dev_info(struct host_cmd_handler_args *args) +{ + const uint8_t *port = args->params; + struct ec_params_usb_pd_rw_hash_entry *r = args->response; + + if (*port >= PD_PORT_COUNT) { + ccprintf("PD DEV_INFO - Port:%d >= %d (max ports)\n", + *port, PD_PORT_COUNT); + return EC_RES_INVALID_PARAM; + } + r->dev_id = pd[*port].dev_id; + ccprintf("PD DEV_INFO - requested Port:%d has Device:%d\n", + *port, r->dev_id); + + if (r->dev_id) { + memcpy(r->dev_rw_hash.b, pd[*port].dev_rw_hash, + SHA1_DIGEST_SIZE); + } + + args->response_size = sizeof(*r); + return EC_RES_SUCCESS; +} + +DECLARE_HOST_COMMAND(EC_CMD_USB_PD_DEV_INFO, + hc_remote_pd_dev_info, + EC_VER_MASK(0)); + #endif /* CONFIG_COMMON_RUNTIME */ diff --git a/include/ec_commands.h b/include/ec_commands.h index 27b3107c16..6cbfe4fd4c 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -2637,6 +2637,13 @@ struct ec_params_usb_pd_rw_hash_entry { uint32_t w[DIV_ROUND_UP(SHA1_DIGEST_SIZE, sizeof(uint32_t))]; } dev_rw_hash; } __packed; + +/* Read USB-PD Accessory info */ +#define EC_CMD_USB_PD_DEV_INFO 0x112 + +struct ec_params_usb_pd_info_request { + uint8_t port; +} __packed; /*****************************************************************************/ /* * Passthru commands diff --git a/include/usb_pd.h b/include/usb_pd.h index 507a81fe7f..08c8038b3a 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -307,12 +307,13 @@ int pd_board_checks(void); int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload); /** - * Store RW hash of device + * Store Device ID & RW hash of device * * @param port USB-C port number + * @param dev_id device identifier * @param rw_hash pointer to sha1 rw_hash */ -void pd_dev_store_rw_hash(int port, uint32_t *rw_hash); +void pd_dev_store_rw_hash(int port, uint8_t dev_id, uint32_t *rw_hash); /** * Send Vendor Defined Message diff --git a/util/ectool.c b/util/ectool.c index 0d380c0e78..822a418260 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -118,6 +118,8 @@ const char help_str[] = " Write I2C bus\n" " i2cxfer <port> <slave_addr> <read_count> [write bytes...]\n" " Perform I2C transfer on EC's I2C bus\n" + " infopddev <port>\n" + " Get info about USB type-C accessory attached to port\n" " keyscan <beat_us> <filename>\n" " Test low-level key scanning\n" " led <name> <query | auto | off | <color> | <color>=<value>...>\n" @@ -812,6 +814,43 @@ int cmd_rw_hash_pd(int argc, char *argv[]) } +int cmd_pd_device_info(int argc, char *argv[]) +{ + int i, rv; + char *e; + struct ec_params_usb_pd_info_request *p = + (struct ec_params_usb_pd_info_request *)ec_outbuf; + struct ec_params_usb_pd_rw_hash_entry *r = + (struct ec_params_usb_pd_rw_hash_entry *)ec_inbuf; + + if (argc < 2) { + fprintf(stderr, "Usage: %s <port>\n", argv[0]); + return -1; + } + + p->port = strtol(argv[1], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad port\n"); + return -1; + } + + rv = ec_command(EC_CMD_USB_PD_DEV_INFO, 0, p, sizeof(*p), + ec_inbuf, ec_max_insize); + if (rv < 0) + return rv; + + if (!r->dev_id) + printf("Port:%d has no valid device\n", p->port); + else { + printf("Port:%d Device:%d Hash: ", p->port, r->dev_id); + for (i = 0; i < 5; i++) + printf(" 0x%08x", r->dev_rw_hash.w[i]); + printf("\n"); + } + return rv; +} + + /* PD image size is 16k minus 32 bits for the RW hash */ #define PD_RW_IMAGE_SIZE (16 * 1024 - 32) static struct sha1_ctx ctx; @@ -4742,6 +4781,7 @@ const struct command commands[] = { {"i2cread", cmd_i2c_read}, {"i2cwrite", cmd_i2c_write}, {"i2cxfer", cmd_i2c_xfer}, + {"infopddev", cmd_pd_device_info}, {"led", cmd_led}, {"lightbar", cmd_lightbar}, {"keyconfig", cmd_keyconfig}, |