summaryrefslogtreecommitdiff
path: root/chip/stm32/usb.c
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@chromium.org>2017-11-15 15:00:12 +0800
committerchrome-bot <chrome-bot@chromium.org>2017-12-12 03:57:19 -0800
commite3c1e2265c732d465f3df90e5ea64bd02f02234f (patch)
tree7a6db56d522a6ff448f78691ad696901792e47d8 /chip/stm32/usb.c
parent2f4fd74df5af5885a24d2c1ddc9deb71dd874315 (diff)
downloadchrome-ec-e3c1e2265c732d465f3df90e5ea64bd02f02234f.tar.gz
stm32/usb: Patching framework for USB descriptors
In some cases, we want to be able to dynamically modify a few bytes in the USB descriptor (in our case, length of referenced items), but it could also be other things like flags. These 2 new functions allow to keep all the USB descriptor in flash, and modify these few bytes before writing them in the USB buffer. BRANCH=none BUG=b:37447752 TEST=Flash hammer, USB descriptors are valid. Change-Id: I8624255fa43f52a0aaa21d20e963f3974f236912 Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/771057 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'chip/stm32/usb.c')
-rw-r--r--chip/stm32/usb.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/chip/stm32/usb.c b/chip/stm32/usb.c
index 27ea117de5..c97c68f03c 100644
--- a/chip/stm32/usb.c
+++ b/chip/stm32/usb.c
@@ -119,6 +119,40 @@ void usb_read_setup_packet(usb_uint *buffer, struct usb_setup_packet *packet)
packet->wLength = buffer[3];
}
+struct usb_descriptor_patch {
+ const void *address;
+ uint16_t data;
+};
+
+static struct usb_descriptor_patch desc_patches[USB_DESC_PATCH_COUNT];
+
+void set_descriptor_patch(enum usb_desc_patch_type type,
+ const void *address, uint16_t data)
+{
+ desc_patches[type].address = address;
+ desc_patches[type].data = data;
+}
+
+void *memcpy_to_usbram_ep0_patch(const void *src, size_t n)
+{
+ int i;
+ void *ret;
+
+ ret = memcpy_to_usbram((void *)usb_sram_addr(ep0_buf_tx), src, n);
+
+ for (i = 0; i < USB_DESC_PATCH_COUNT; i++) {
+ unsigned int offset = desc_patches[i].address - src;
+
+ if (offset >= n)
+ continue;
+
+ memcpy_to_usbram((void *)(usb_sram_addr(ep0_buf_tx) + offset),
+ &desc_patches[i].data, sizeof(desc_patches[i].data));
+ }
+
+ return ret;
+}
+
static void ep0_send_descriptor(const uint8_t *desc, int len,
uint16_t fixup_size)
{
@@ -133,7 +167,7 @@ static void ep0_send_descriptor(const uint8_t *desc, int len,
desc_ptr = desc + USB_MAX_PACKET_SIZE;
len = USB_MAX_PACKET_SIZE;
}
- memcpy_to_usbram(EP0_BUF_TX_SRAM_ADDR, desc, len);
+ memcpy_to_usbram_ep0_patch(desc, len);
if (fixup_size) /* set the real descriptor size */
ep0_buf_tx[1] = fixup_size;
btable_ep[0].tx_count = len;