diff options
author | Nicolas Boichat <drinkcat@google.com> | 2016-11-09 18:45:51 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-11-22 18:36:36 -0800 |
commit | 67473cb5b4834d57c2544229913dd06331df7530 (patch) | |
tree | f411d34156ec3d755220b4d1a95e2317c723e9d0 /chip/stm32/usb.c | |
parent | 0e4776ec287ce92ce61ef9abae179330f4120aad (diff) | |
download | chrome-ec-67473cb5b4834d57c2544229913dd06331df7530.tar.gz |
chip/stm32/usb: Allow interface handler to reply with more than 64 bytes
For example, when a HID descriptor is longer than 64 bytes, we need
to split it in multiple packets.
BRANCH=none
BUG=chrome-os-partner:59083
TEST=make buildall -j
TEST=make BOARD=hammer -j && util/flash_ec --board=hammer
Change-Id: I25a05eabaf9413e332fe3cd70695a0d53639713d
Reviewed-on: https://chromium-review.googlesource.com/409316
Commit-Ready: Nicolas Boichat <drinkcat@chromium.org>
Tested-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'chip/stm32/usb.c')
-rw-r--r-- | chip/stm32/usb.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/chip/stm32/usb.c b/chip/stm32/usb.c index dbbc800ffe..2afab3f415 100644 --- a/chip/stm32/usb.c +++ b/chip/stm32/usb.c @@ -99,7 +99,8 @@ static int set_addr; static int desc_left; /* pointer to descriptor data if any */ static const uint8_t *desc_ptr; - +/* interface that should handle the next tx transaction */ +static uint8_t iface_next = USB_IFACE_COUNT; void usb_read_setup_packet(usb_uint *buffer, struct usb_setup_packet *packet) @@ -118,14 +119,21 @@ static void ep0_rx(void) /* reset any incomplete descriptor transfer */ desc_ptr = NULL; + iface_next = USB_IFACE_COUNT; /* interface specific requests */ if ((req & USB_RECIP_MASK) == USB_RECIP_INTERFACE) { uint8_t iface = ep0_buf_rx[2] & 0xff; - if (iface < USB_IFACE_COUNT && - usb_iface_request[iface](ep0_buf_rx, ep0_buf_tx)) - goto unknown_req; - return; + if (iface < USB_IFACE_COUNT) { + int ret; + + ret = usb_iface_request[iface](ep0_buf_rx, ep0_buf_tx); + if (ret < 0) + goto unknown_req; + if (ret == 1) + iface_next = iface; + return; + } } /* TODO check setup bit ? */ @@ -241,6 +249,18 @@ static void ep0_tx(void) /* send the null OUT transaction if the transfer is complete */ return; } + if (iface_next < USB_IFACE_COUNT) { + int ret; + + ret = usb_iface_request[iface_next](NULL, ep0_buf_tx); + if (ret < 0) + goto error; + if (ret == 0) + iface_next = USB_IFACE_COUNT; + return; + } + +error: STM32_TOGGLE_EP(0, EP_TX_MASK, EP_TX_VALID, 0); } |