usb: fix random "null ctrl req" panic when switching usb config

rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]>
Newsgroups gmane.comp.systems.archos.rockbox.cvs
Message-ID <[email protected]>
commit 75edff78801711dca40ef6273a26fd9a140d8a03
Author: mojyack <[email protected]>
Date:   Sun Dec 7 21:02:58 2025 +0900

    usb: fix random "null ctrl req" panic when switching usb config
    
    Change-Id: I7839edb99461abfbff03460d63343691085ef34f

diff --git a/firmware/export/usb.h b/firmware/export/usb.h
index 35d525e304..13271652f9 100644
--- a/firmware/export/usb.h
+++ b/firmware/export/usb.h
@@ -240,6 +240,8 @@ void usb_set_mode(int mode);
 /* USB driver call this function to notify that a transfer has completed */
 void usb_signal_transfer_completion(
     struct usb_transfer_completion_event_data *event_data);
+/* Clear all signaled transfer completion events from event queue */
+void usb_clear_pending_transfer_completion_events(void);
 /* notify the USB code that some important event has occurred which influences the
  * USB state (like USB_NOTIFY_SET_ADDR). USB drivers should call usb_core_notify_*
  * functions and not this function. */
diff --git a/firmware/usb.c b/firmware/usb.c
index df87919892..7f4c61a573 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -305,6 +305,13 @@ void usb_signal_transfer_completion(
     queue_post(&usb_queue, USB_TRANSFER_COMPLETION, (intptr_t)event_data);
 }
 
+void usb_clear_pending_transfer_completion_events(void)
+{
+    while (queue_peek_ex(&usb_queue, NULL,
+                         1 | QPEEK_REMOVE_EVENTS,
+                         QPEEK_FILTER1(USB_TRANSFER_COMPLETION)));
+}
+
 void usb_signal_notify(long id, intptr_t data)
 {
     queue_post(&usb_queue, id, data);
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
index 4cf4e1b137..3f2aff4310 100644
--- a/firmware/usbstack/usb_core.c
+++ b/firmware/usbstack/usb_core.c
@@ -863,9 +863,14 @@ static int usb_core_do_set_config(uint8_t new_config)
             }
         }
         init_deinit_endpoints(usb_config - 1, false);
+
+        /* clear any pending transfer completions,
+         * because they are depend on contents of ep_data */
+        usb_clear_pending_transfer_completion_events();
+        /* reset endpoint states */
+        memset(ep_data, 0, sizeof(ep_data));
     }
 
-    memset(ep_data, 0, sizeof(ep_data));
     usb_config = new_config;
     usb_state = usb_config == 0 ? ADDRESS : CONFIGURED;
 
-- 
rockbox-cvs mailing list
[email protected]
https://lists.haxx.se/mailman/listinfo/rockbox-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.