diff options
author | Nick Sanders <nsanders@chromium.org> | 2016-04-06 14:25:45 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-05-26 16:17:26 -0700 |
commit | 56ee8aefc33505a7df4e4148001a11ac461907a3 (patch) | |
tree | 9aa84b4f26d7396878757bb7ed79bebaa18f59a2 /chip | |
parent | 5cc3cac589d3e869266c18ed7e538a769496478f (diff) | |
download | chrome-ec-56ee8aefc33505a7df4e4148001a11ac461907a3.tar.gz |
servo_micro: add programmable serial number
This change provides a console command for setting,
and loading a usb serial number from flash. This
feature adds CONFIG_USB_SERIALNO, and currently only
has a useful implementation when PSTATE is present.
BUG=chromium:571477
TEST=serialno set abcdef; serialno load; reboot
BRANCH=none
Change-Id: I3b24cfa2d52d54118bc3fd54b276e3d95412d245
Signed-off-by: Nick Sanders <nsanders@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/337359
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/stm32/usb.c | 112 |
1 files changed, 110 insertions, 2 deletions
diff --git a/chip/stm32/usb.c b/chip/stm32/usb.c index ca82fbd4a4..85e2320642 100644 --- a/chip/stm32/usb.c +++ b/chip/stm32/usb.c @@ -7,6 +7,7 @@ #include "common.h" #include "config.h" #include "console.h" +#include "flash.h" #include "gpio.h" #include "hooks.h" #include "link_defs.h" @@ -34,6 +35,12 @@ #define CONFIG_USB_BCD_DEV 0x0100 /* 1.00 */ #endif +#ifndef CONFIG_USB_SERIALNO +#define USB_STR_SERIALNO 0 +#else +static int usb_load_serial(void); +#endif + /* USB Standard Device Descriptor */ static const struct usb_device_descriptor dev_desc = { .bLength = USB_DT_DEVICE_SIZE, @@ -48,7 +55,7 @@ static const struct usb_device_descriptor dev_desc = { .bcdDevice = CONFIG_USB_BCD_DEV, .iManufacturer = USB_STR_VENDOR, .iProduct = USB_STR_PRODUCT, - .iSerialNumber = 0, + .iSerialNumber = USB_STR_SERIALNO, .bNumConfigurations = 1 }; @@ -85,6 +92,8 @@ static int desc_left; /* pointer to descriptor data if any */ static const uint8_t *desc_ptr; + + void usb_read_setup_packet(usb_uint *buffer, struct usb_setup_packet *packet) { packet->bmRequestType = buffer[0] & 0xff; @@ -137,7 +146,12 @@ static void ep0_rx(void) if (idx >= USB_STR_COUNT) /* The string does not exist : STALL */ goto unknown_req; - desc = usb_strings[idx]; +#ifdef CONFIG_USB_SERIALNO + if (idx == USB_STR_SERIALNO) + desc = (uint8_t *)usb_serialno_desc; + else +#endif + desc = usb_strings[idx]; len = desc[0]; break; case USB_DT_DEVICE_QUALIFIER: /* Get device qualifier desc */ @@ -307,6 +321,9 @@ void usb_init(void) /* set interrupts mask : reset/correct tranfer/errors */ STM32_USB_CNTR = 0xe400; +#ifdef CONFIG_USB_SERIALNO + usb_load_serial(); +#endif #ifndef CONFIG_USB_INHIBIT_CONNECT usb_connect(); #endif @@ -402,3 +419,94 @@ void *memcpy_from_usbram(void *dest, const void *src, size_t n) return dest; } + +#ifdef CONFIG_USB_SERIALNO +/* This will be subbed into USB_STR_SERIALNO. */ +struct usb_string_desc *usb_serialno_desc = + USB_WR_STRING_DESC(DEFAULT_SERIALNO); + +/* Update serial number */ +static int usb_set_serial(const char *serialno) +{ + struct usb_string_desc *sd = usb_serialno_desc; + int i; + + if (!serialno) + return EC_ERROR_INVAL; + + /* Convert into unicode usb string desc. */ + for (i = 0; i < USB_STRING_LEN; i++) { + sd->_data[i] = serialno[i]; + if (serialno[i] == 0) + break; + } + /* Count wchars (w/o null terminator) plus size & type bytes. */ + sd->_len = (i * 2) + 2; + sd->_type = USB_DT_STRING; + + return EC_SUCCESS; +} + +/* Retrieve serial number from pstate flash. */ +static int usb_load_serial(void) +{ + const char *serialno; + int rv; + + serialno = flash_read_serial(); + if (!serialno) + return EC_ERROR_ACCESS_DENIED; + + rv = usb_set_serial(serialno); + return rv; +} + +/* Save serial number into pstate region. */ +static int usb_save_serial(const char *serialno) +{ + int rv; + + if (!serialno) + return EC_ERROR_INVAL; + + /* Save this new serial number to flash. */ + rv = flash_write_serial(serialno); + if (rv) + return rv; + + /* Load this new serial number to memory. */ + rv = usb_load_serial(); + return rv; +} + +static int command_serialno(int argc, char **argv) +{ + struct usb_string_desc *sd = usb_serialno_desc; + char buf[USB_STRING_LEN]; + int rv = EC_SUCCESS; + int i; + + if (argc != 1) { + if ((strcasecmp(argv[1], "set") == 0) && + (argc == 3)) { + ccprintf("Saving serial number\n"); + rv = usb_save_serial(argv[2]); + } else if ((strcasecmp(argv[1], "load") == 0) && + (argc == 2)) { + ccprintf("Loading serial number\n"); + rv = usb_load_serial(); + } else + return EC_ERROR_INVAL; + } + + for (i = 0; i < USB_STRING_LEN; i++) + buf[i] = sd->_data[i]; + ccprintf("Serial number: %s\n", buf); + return rv; +} + +DECLARE_CONSOLE_COMMAND(serialno, command_serialno, + "load/set [value]", + "Read and write USB serial number", + NULL); +#endif |