summaryrefslogtreecommitdiff
path: root/chip/stm32/usb.c
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2017-09-12 15:47:31 +0200
committerchrome-bot <chrome-bot@chromium.org>2017-09-22 10:18:50 -0700
commit77f011206c87a7a3e8cd93d3635c6c4f0ea3e32d (patch)
tree75d281c3355aa9c1918e29c31a63037d81768add /chip/stm32/usb.c
parente3333972d5bcf110fd2c51de92097a546694d0a1 (diff)
downloadchrome-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.c59
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 */