summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-11-13 17:16:28 +0000
committerAidan MacDonald <amachronic@protonmail.com>2021-11-13 18:37:33 +0000
commitf8810be6decfabce76d2fc64940dc4ef442c0f9f (patch)
tree51ac450bdd3400d62cdf0408055b520627abd7f1
parenta4e422db9ec27dffa8099b21822c90e0637ed834 (diff)
downloadrockbox-f8810be6decfabce76d2fc64940dc4ef442c0f9f.tar.gz
rockbox-f8810be6decfabce76d2fc64940dc4ef442c0f9f.zip
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
-rw-r--r--firmware/usbstack/usb_core.c19
1 files 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)
950 struct usb_transfer_completion_event_data* completion_event = 950 struct usb_transfer_completion_event_data* completion_event =
951 &ep_data[endpoint].completion_event[EP_DIR(dir)]; 951 &ep_data[endpoint].completion_event[EP_DIR(dir)];
952 952
953 completion_event->endpoint = endpoint; 953 void* data0 = NULL;
954 completion_event->dir = dir; 954 void* data1 = NULL;
955 completion_event->data[0] = NULL;
956 completion_event->data[1] = NULL;
957 completion_event->status = status;
958 completion_event->length = length;
959 955
960#ifdef USB_LEGACY_CONTROL_API 956#ifdef USB_LEGACY_CONTROL_API
961 if(endpoint == EP_CONTROL) { 957 if(endpoint == EP_CONTROL) {
@@ -963,14 +959,21 @@ void usb_core_transfer_complete(int endpoint, int dir, int status, int length)
963 struct usb_ctrlrequest* req = active_request; 959 struct usb_ctrlrequest* req = active_request;
964 960
965 if(dir == USB_DIR_OUT && req && cwdd) { 961 if(dir == USB_DIR_OUT && req && cwdd) {
966 completion_event->data[0] = req; 962 data0 = req;
967 completion_event->data[1] = control_write_data; 963 data1 = control_write_data;
968 } else { 964 } else {
969 return; 965 return;
970 } 966 }
971 } 967 }
972#endif 968#endif
973 969
970 completion_event->endpoint = endpoint;
971 completion_event->dir = dir;
972 completion_event->data[0] = data0;
973 completion_event->data[1] = data1;
974 completion_event->status = status;
975 completion_event->length = length;
976
974 usb_signal_transfer_completion(completion_event); 977 usb_signal_transfer_completion(completion_event);
975} 978}
976 979