mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 09:01:35 +00:00
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>
This commit is contained in:
committed by
chrome-bot
parent
2f4fd74df5
commit
e3c1e2265c
@@ -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;
|
||||
|
||||
@@ -107,8 +107,7 @@ int hid_iface_request(usb_uint *ep0_buf_rx, usb_uint *ep0_buf_tx,
|
||||
return report_left ? 1 : 0;
|
||||
} else if (ep0_buf_rx[1] == (USB_HID_DT_HID << 8)) {
|
||||
/* Setup : HID specific : Get HID descriptor */
|
||||
memcpy_to_usbram((void *) usb_sram_addr(ep0_buf_tx),
|
||||
hid_desc, sizeof(*hid_desc));
|
||||
memcpy_to_usbram_ep0_patch(hid_desc, sizeof(*hid_desc));
|
||||
btable_ep[0].tx_count = sizeof(*hid_desc);
|
||||
STM32_TOGGLE_EP(0, EP_TX_RX_MASK, EP_TX_RX_VALID,
|
||||
EP_STATUS_OUT);
|
||||
|
||||
@@ -63,6 +63,27 @@ void usb_read_setup_packet(usb_uint *buffer, struct usb_setup_packet *packet);
|
||||
void *memcpy_to_usbram(void *dest, const void *src, size_t n);
|
||||
void *memcpy_from_usbram(void *dest, const void *src, size_t n);
|
||||
|
||||
/*
|
||||
* Descriptor patching support, useful to change a few values in the descriptor
|
||||
* (typically, length or bitfields) without having to move descriptors to RAM.
|
||||
*/
|
||||
|
||||
enum usb_desc_patch_type {
|
||||
USB_DESC_PATCH_COUNT,
|
||||
};
|
||||
|
||||
/*
|
||||
* Set patch in table: replace uint16_t at address (STM32 flash) with data.
|
||||
*
|
||||
* The patches need to be setup before _before_ usb_init is executed (or, at
|
||||
* least, before the first call to memcpy_to_usbram_ep0_patch).
|
||||
*/
|
||||
void set_descriptor_patch(enum usb_desc_patch_type type,
|
||||
const void *address, uint16_t data);
|
||||
|
||||
/* Copy to USB ram, applying patches to src as required. */
|
||||
void *memcpy_to_usbram_ep0_patch(const void *src, size_t n);
|
||||
|
||||
/* Compute the address inside dedicate SRAM for the USB controller */
|
||||
#define usb_sram_addr(x) ((x - __usb_ram_start) * sizeof(uint16_t))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user