From f8810be6decfabce76d2fc64940dc4ef442c0f9f Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Sat, 13 Nov 2021 17:16:28 +0000 Subject: usb_core: More legacy control API fixes In the old API, usb_core_transfer_complete() would ignore any completions on EP0. The legacy control API will also ignore most completions on EP0, but it only did so after filling in the completion event. If the driver submits a spurious completion on EP0, then this could clobber a previously queued completion event. Fix this by deciding whether to ignore the completion *before* modifying the event data. Change-Id: I68526898a96efa594ada4e94bb6851aaaf12e92a --- firmware/usbstack/usb_core.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c index 738b92ed4d..8e32e3501f 100644 --- a/firmware/usbstack/usb_core.c +++ b/firmware/usbstack/usb_core.c @@ -950,12 +950,8 @@ void usb_core_transfer_complete(int endpoint, int dir, int status, int length) struct usb_transfer_completion_event_data* completion_event = &ep_data[endpoint].completion_event[EP_DIR(dir)]; - completion_event->endpoint = endpoint; - completion_event->dir = dir; - completion_event->data[0] = NULL; - completion_event->data[1] = NULL; - completion_event->status = status; - completion_event->length = length; + void* data0 = NULL; + void* data1 = NULL; #ifdef USB_LEGACY_CONTROL_API if(endpoint == EP_CONTROL) { @@ -963,14 +959,21 @@ void usb_core_transfer_complete(int endpoint, int dir, int status, int length) struct usb_ctrlrequest* req = active_request; if(dir == USB_DIR_OUT && req && cwdd) { - completion_event->data[0] = req; - completion_event->data[1] = control_write_data; + data0 = req; + data1 = control_write_data; } else { return; } } #endif + completion_event->endpoint = endpoint; + completion_event->dir = dir; + completion_event->data[0] = data0; + completion_event->data[1] = data1; + completion_event->status = status; + completion_event->length = length; + usb_signal_transfer_completion(completion_event); } -- cgit