diff options
author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2017-04-27 18:07:13 +0300 |
---|---|---|
committer | Karl Palsson <karlp@tweak.net.au> | 2017-06-09 02:01:45 +0300 |
commit | 58f2ee34fa7b6fc04c41acff221d7e916467f7b9 (patch) | |
tree | 896cdb69261492bfe84600d9eddae4287642ae52 /lib/usb | |
parent | d97c1b04359e396d730c99f58ba2609444025ad9 (diff) |
usb: Ensure control events are handled in order
Use EP0 OUT flow control to NAK OUT packets when we're not yet expecting
any. This prevents the status OUT event from arriving while the control
state machine is still expecting the data IN completion event.
Diffstat (limited to 'lib/usb')
-rw-r--r-- | lib/usb/usb_control.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/lib/usb/usb_control.c b/lib/usb/usb_control.c index 9d5884f3..5bd45a35 100644 --- a/lib/usb/usb_control.c +++ b/lib/usb/usb_control.c @@ -211,6 +211,8 @@ static void usb_control_setup_write(usbd_device *usbd_dev, } else { usbd_dev->control_state.state = LAST_DATA_OUT; } + + usbd_ep_nak_set(usbd_dev, 0, 0); } /* Do not appear to belong to the API, so are omitted from docs */ @@ -223,6 +225,8 @@ void _usbd_control_setup(usbd_device *usbd_dev, uint8_t ea) usbd_dev->control_state.complete = NULL; + usbd_ep_nak_set(usbd_dev, 0, 1); + if (usbd_ep_read_packet(usbd_dev, 0, req, 8) != 8) { stall_transaction(usbd_dev); return; @@ -294,6 +298,7 @@ void _usbd_control_in(usbd_device *usbd_dev, uint8_t ea) break; case LAST_DATA_IN: usbd_dev->control_state.state = STATUS_OUT; + usbd_ep_nak_set(usbd_dev, 0, 0); break; case STATUS_IN: if (usbd_dev->control_state.complete) { |