usb: do not call usb_core_do_set_config(0) inside bus reset isr

Change-Id: Ic06719ef92cd1fae42c7155ab72029466826a59b
This commit is contained in:
mojyack 2025-12-17 15:12:13 +09:00
parent 6db1e937e9
commit e3bb80384d
3 changed files with 29 additions and 12 deletions

View file

@ -118,6 +118,7 @@ enum
USB_TRANSFER_COMPLETION, /* Event */
USB_NOTIFY_SET_ADDR, /* Event */
USB_NOTIFY_SET_CONFIG, /* Event */
USB_NOTIFY_BUS_RESET, /* Event */
#endif
#ifdef USB_FIREWIRE_HANDLING
USB_REQUEST_REBOOT, /* Event */

View file

@ -477,6 +477,7 @@ static void NORETURN_ATTR usb_thread(void)
#ifdef HAVE_USBSTACK
case USB_NOTIFY_SET_ADDR:
case USB_NOTIFY_SET_CONFIG:
case USB_NOTIFY_BUS_RESET:
if(usb_state <= USB_EXTRACTED)
break;
usb_core_handle_notify(ev.id, ev.data);

View file

@ -153,6 +153,7 @@ static const struct usb_string_descriptor* const usb_strings[USB_STRING_INDEX_MA
static int usb_address = 0;
static int usb_config = 0;
static bool initialized = false;
static volatile bool bus_reset_pending = false;
static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
#ifdef HAVE_USB_CHARGING_ENABLE
@ -1094,22 +1095,29 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req, void*
}
}
static void do_bus_reset(void) {
usb_address = 0;
usb_state = DEFAULT;
#ifdef USB_LEGACY_CONTROL_API
num_active_requests = 0;
#endif
bus_reset_pending = false;
}
/* called by usb_drv_int() */
void usb_core_bus_reset(void)
{
logf("usb_core: bus reset");
usb_core_do_set_config(0);
usb_address = 0;
usb_state = DEFAULT;
#ifdef HAVE_USB_CHARGING_ENABLE
#ifdef HAVE_USB_CHARGING_IN_THREAD
/* On some targets usb_charging_maxcurrent_change() cannot be called
* from an interrupt handler; get the USB thread to do it instead. */
usb_charger_update();
#else
usb_charging_maxcurrent_change(usb_charging_maxcurrent());
#endif
#endif
if(bus_reset_pending) {
return;
}
bus_reset_pending = true;
if(usb_config == 0) {
do_bus_reset();
} else {
/* need to disconnect class drivers, defer it to usb thread */
usb_signal_notify(USB_NOTIFY_BUS_RESET, 0);
}
}
/* called by usb_drv_transfer_completed() */
@ -1159,6 +1167,13 @@ void usb_core_handle_notify(long id, intptr_t data)
case USB_NOTIFY_SET_CONFIG:
usb_core_do_set_config(data);
break;
case USB_NOTIFY_BUS_RESET:
usb_core_do_set_config(0);
do_bus_reset();
#ifdef HAVE_USB_CHARGING_ENABLE
usb_charging_maxcurrent_change(usb_charging_maxcurrent());
#endif
break;
default:
break;
}