summaryrefslogtreecommitdiff
path: root/hw/usb/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/usb/core.c')
-rw-r--r--hw/usb/core.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/hw/usb/core.c b/hw/usb/core.c
index 67ba7d6018..328f2f926a 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -115,6 +115,10 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
value = (s->setup_buf[3] << 8) | s->setup_buf[2];
index = (s->setup_buf[5] << 8) | s->setup_buf[4];
+ // TODO: per wiki.osdev.org/USB, if setup_len is 0, then there is no data
+ // stage and the direction must be ignored. It should always go to the
+ // status stage, expecting an IN token. Perhaps fake stuff and set
+ // setup_buf = (setup_buf[0] & ~USB_DIR_IN)? Is this actually a problem?
if (s->setup_buf[0] & USB_DIR_IN) {
usb_device_handle_control(s, p, request, value, index,
s->setup_len, s->data_buf);
@@ -351,6 +355,10 @@ static void usb_process_one(USBPacket *p)
*/
p->status = USB_RET_SUCCESS;
+ /* Default Control Pipe (EP 0) is a message pipe (not stream pipe), so there
+ * must be request (setup) / data / status stages. Flow is bi-directional.
+ * XXX: Can there be other endpoints using the control transfer that can
+ * also use these control data? */
if (p->ep->nr == 0) {
/* control pipe */
if (p->parameter) {