summaryrefslogtreecommitdiff
path: root/chip/stm32/usb.c
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@google.com>2016-11-09 18:45:51 +0800
committerchrome-bot <chrome-bot@chromium.org>2016-11-22 18:36:36 -0800
commit67473cb5b4834d57c2544229913dd06331df7530 (patch)
treef411d34156ec3d755220b4d1a95e2317c723e9d0 /chip/stm32/usb.c
parent0e4776ec287ce92ce61ef9abae179330f4120aad (diff)
downloadchrome-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.c30
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);
}