diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2017-09-12 15:47:31 +0200 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-09-22 10:18:50 -0700 |
commit | 77f011206c87a7a3e8cd93d3635c6c4f0ea3e32d (patch) | |
tree | 75d281c3355aa9c1918e29c31a63037d81768add /chip/stm32/usb.c | |
parent | e3333972d5bcf110fd2c51de92097a546694d0a1 (diff) | |
download | chrome-ec-77f011206c87a7a3e8cd93d3635c6c4f0ea3e32d.tar.gz |
Add WebUSB descriptor support
The WebUSB specification defines a specific Platform Descriptor in the
Binary Object Store:
https://wicg.github.io/webusb/#webusb-platform-capability-descriptor
This descriptor provides a special 'Landing page' URL to the host
browser and associated privileges for it.
Bump the USB version for BOS descriptors to 2.1 to be compatible with
Chrome implementation.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BUG=none
BRANCH=twinkie
TEST=manual: on Twinkie (chip/stm32) and HG proto2 (chip/g), enumerate
WebUSB descriptors with lsusb and connect to a WebUSB page in Chrome
R61+.
Change-Id: I7211ab554f4a6c156c1e8e79a3d9f0d6644217c6
Reviewed-on: https://chromium-review.googlesource.com/664813
Commit-Ready: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'chip/stm32/usb.c')
-rw-r--r-- | chip/stm32/usb.c | 59 |
1 files changed, 40 insertions, 19 deletions
diff --git a/chip/stm32/usb.c b/chip/stm32/usb.c index 26890cadff..c1f39b598d 100644 --- a/chip/stm32/usb.c +++ b/chip/stm32/usb.c @@ -119,6 +119,29 @@ void usb_read_setup_packet(usb_uint *buffer, struct usb_setup_packet *packet) packet->wLength = buffer[3]; } +static void ep0_send_descriptor(const uint8_t *desc, int len, + uint16_t fixup_size) +{ + /* do not send more than what the host asked for */ + len = MIN(ep0_buf_rx[3], len); + /* + * if we cannot transmit everything at once, + * keep the remainder for the next IN packet + */ + if (len >= USB_MAX_PACKET_SIZE) { + desc_left = len - USB_MAX_PACKET_SIZE; + desc_ptr = desc + USB_MAX_PACKET_SIZE; + len = USB_MAX_PACKET_SIZE; + } + memcpy_to_usbram(EP0_BUF_TX_SRAM_ADDR, desc, len); + if (fixup_size) /* set the real descriptor size */ + ep0_buf_tx[1] = fixup_size; + btable_ep[0].tx_count = len; + /* send the null OUT transaction if the transfer is complete */ + STM32_TOGGLE_EP(0, EP_TX_RX_MASK, EP_TX_RX_VALID, + desc_left ? 0 : EP_STATUS_OUT); +} + /* Requests on the control endpoint (aka EP0) */ static void ep0_rx(void) { @@ -142,6 +165,21 @@ static void ep0_rx(void) return; } } + /* vendor specific request */ + if ((req & USB_TYPE_MASK) == USB_TYPE_VENDOR) { +#ifdef CONFIG_WEBUSB_URL + uint8_t b_req = req >> 8; /* bRequest in the transfer */ + uint16_t idx = ep0_buf_rx[2]; /* wIndex in the transfer */ + + if (b_req == 0x01 && idx == WEBUSB_REQ_GET_URL) { + int len = *(uint8_t *)webusb_url; + + ep0_send_descriptor(webusb_url, len, 0); + return; + } +#endif + goto unknown_req; + } /* TODO check setup bit ? */ if (req == (USB_DIR_IN | (USB_REQ_GET_DESCRIPTOR << 8))) { @@ -183,25 +221,8 @@ static void ep0_rx(void) default: /* unhandled descriptor */ goto unknown_req; } - /* do not send more than what the host asked for */ - len = MIN(ep0_buf_rx[3], len); - /* - * if we cannot transmit everything at once, - * keep the remainder for the next IN packet - */ - if (len >= USB_MAX_PACKET_SIZE) { - desc_left = len - USB_MAX_PACKET_SIZE; - desc_ptr = desc + USB_MAX_PACKET_SIZE; - len = USB_MAX_PACKET_SIZE; - } - memcpy_to_usbram(EP0_BUF_TX_SRAM_ADDR, desc, len); - if (type == USB_DT_CONFIGURATION) - /* set the real descriptor size */ - ep0_buf_tx[1] = USB_DESC_SIZE; - btable_ep[0].tx_count = len; - STM32_TOGGLE_EP(0, EP_TX_RX_MASK, EP_TX_RX_VALID, - desc_left ? 0 : EP_STATUS_OUT); - /* send the null OUT transaction if the transfer is complete */ + ep0_send_descriptor(desc, len, type == USB_DT_CONFIGURATION ? + USB_DESC_SIZE : 0); } else if (req == (USB_DIR_IN | (USB_REQ_GET_STATUS << 8))) { uint16_t data = 0; /* Get status */ |