summaryrefslogtreecommitdiff
path: root/chip/stm32/usb.c
diff options
context:
space:
mode:
authorNick Sanders <nsanders@chromium.org>2016-04-06 14:25:45 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-05-26 16:17:26 -0700
commit56ee8aefc33505a7df4e4148001a11ac461907a3 (patch)
tree9aa84b4f26d7396878757bb7ed79bebaa18f59a2 /chip/stm32/usb.c
parent5cc3cac589d3e869266c18ed7e538a769496478f (diff)
downloadchrome-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/stm32/usb.c')
-rw-r--r--chip/stm32/usb.c112
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