usb: introduce USB_NOTIFY_CLASS_DRIVER

this invokes specified class driver's notify_event method.
initial purpose is to trigger a callback from isr, like a timer event.

Change-Id: Id600e9f0d8840a12da779d5a15783edf14bd76b5
This commit is contained in:
mojyack 2025-12-19 15:22:25 +09:00
parent fce8248267
commit eb69211791
4 changed files with 28 additions and 1 deletions

View file

@ -119,6 +119,7 @@ enum
USB_NOTIFY_SET_ADDR, /* Event */
USB_NOTIFY_SET_CONFIG, /* Event */
USB_NOTIFY_BUS_RESET, /* Event */
USB_NOTIFY_CLASS_DRIVER, /* Event - notify_event() of specified class driver */
#endif
#ifdef USB_FIREWIRE_HANDLING
USB_REQUEST_REBOOT, /* Event */
@ -238,12 +239,23 @@ 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. */
* functions and not this function.
* for USB_NOTIFY_CLASS_DRIVER, use usb_signal_class_notify() instead */
void usb_signal_notify(long id, intptr_t data);
/* wrapper for usb_signal_notify(USB_NOTIFY_CLASS_DRIVER)
* class_num: target driver. USB_DRIVER_*
* data: optional data. note that its upper 8 bits will be masked */
static inline void usb_signal_class_notify(int8_t class_num, uint32_t data) {
usb_signal_notify(USB_NOTIFY_CLASS_DRIVER, class_num << 24 | (data & 0x00ffffff));
}
/* returns whether a USB_DRIVER_* is enabled (like HID, mass storage, ...) */
bool usb_driver_enabled(int driver);
/* returns whether exclusive storage is available for USB */

View file

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

View file

@ -118,6 +118,10 @@ struct usb_class_driver {
* Returns value on success and -1 on error.
* Mandatory function if alternate interface support is needed */
int (*get_interface)(int interface);
/* Invoked by USB_NOTIFY_CLASS_DRIVER
Optional function */
void (*notify_event)(intptr_t data);
};
#define PACK_DATA(dest, data) pack_data(dest, &(data), sizeof(data))

View file

@ -1181,6 +1181,16 @@ void usb_core_handle_notify(long id, intptr_t data)
usb_charging_maxcurrent_change(usb_charging_maxcurrent());
#endif
break;
case USB_NOTIFY_CLASS_DRIVER: {
uint8_t index = data >> 24;
if(index >= USB_NUM_DRIVERS) {
logf("usb_core: invalid notification destination index=%u", index);
return;
}
if(is_active(drivers[index]) && drivers[index].notify_event != NULL) {
drivers[index].notify_event(data & 0x00ffffff);
}
} break;
default:
break;
}