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

Change-Id: I7839edb99461abfbff03460d63343691085ef34f
This commit is contained in:
mojyack 2025-12-07 21:02:58 +09:00
parent d395520cd0
commit 75edff7880
3 changed files with 15 additions and 1 deletions

View file

@ -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. */

View file

@ -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);

View file

@ -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;