From 3c10b21c10ca1c0f888ae30696e9a791199ded0d Mon Sep 17 00:00:00 2001 From: mojyack Date: Fri, 19 Dec 2025 21:23:52 +0900 Subject: [PATCH] usb: hold class_driver instance in each driver Change-Id: Ia2f857bffcc6c3cca4dee59791c48c628082595b --- firmware/usbstack/usb_audio.c | 109 +++++++++++++-- firmware/usbstack/usb_audio.h | 110 +--------------- firmware/usbstack/usb_charging_only.c | 11 +- firmware/usbstack/usb_charging_only.h | 8 +- firmware/usbstack/usb_core.c | 183 +++++--------------------- firmware/usbstack/usb_hid.c | 32 +++-- firmware/usbstack/usb_hid.h | 13 +- firmware/usbstack/usb_iap.c | 44 +++++-- firmware/usbstack/usb_iap.h | 17 +-- firmware/usbstack/usb_serial.c | 36 +++-- firmware/usbstack/usb_serial.h | 13 +- firmware/usbstack/usb_storage.c | 37 ++++-- firmware/usbstack/usb_storage.h | 14 +- 13 files changed, 258 insertions(+), 369 deletions(-) diff --git a/firmware/usbstack/usb_audio.c b/firmware/usbstack/usb_audio.c index fd135cf7a3..9dc96579e7 100644 --- a/firmware/usbstack/usb_audio.c +++ b/firmware/usbstack/usb_audio.c @@ -297,15 +297,15 @@ static int usb_as_playback_intf_alt; /* playback streaming interface alternate s static int as_playback_freq_idx; /* audio playback streaming frequency index (in hw_freq_sampr) */ -struct usb_class_driver_ep_allocation usb_audio_ep_allocs[2] = { +static struct usb_class_driver_ep_allocation ep_allocs[2] = { /* output isochronous endpoint */ {.type = USB_ENDPOINT_XFER_ISOC, .dir = DIR_OUT, .optional = false}, /* input feedback isochronous endpoint */ {.type = USB_ENDPOINT_XFER_ISOC, .dir = DIR_IN, .optional = false}, }; -#define EP_ISO_OUT (usb_audio_ep_allocs[0].ep) -#define EP_ISO_FEEDBACK_IN (usb_audio_ep_allocs[1].ep) +#define EP_ISO_OUT (ep_allocs[0].ep) +#define EP_ISO_FEEDBACK_IN (ep_allocs[1].ep) /* small buffer used for control transfers */ static unsigned char usb_buffer[128] USB_DEVBSS_ATTR; @@ -501,7 +501,12 @@ unsigned long usb_audio_get_playback_sampling_frequency(void) return hw_freq_sampr[as_playback_freq_idx]; } -void usb_audio_init(void) +/* + * Initialize the driver. Called by usb_core_init(). + * Currently initializes the sampling frequency values available + * to the AudioStreaming interface. + */ +static void usb_audio_init(void) { unsigned int i; /* initialized tSamFreq array */ @@ -577,14 +582,34 @@ unsigned int usb_audio_get_in_ep(void) return EP_ISO_FEEDBACK_IN; } -int usb_audio_set_first_interface(int interface) +/* + * Required function for the class driver. + * + * Called by allocate_interfaces_and_endpoints() to + * tell the class driver what its first interface number is. + * Returns the number of the interface available for the next + * class driver to use. + * + * We need 2 interfaces, AudioControl and AudioStreaming. + * Return interface+2. + */ +static int usb_audio_set_first_interface(int interface) { usb_interface = interface; logf("usbaudio: usb_interface=%d", usb_interface); return interface + 2; /* Audio Control and Audio Streaming */ } -int usb_audio_get_config_descriptor(unsigned char *dest, int max_packet_size) +/* + * Required function for the class driver. + * + * Called by request_handler_device_get_descriptor(), which expects + * this function to fill *dest with the configuration descriptor for this + * class driver. + * + * Return the size of this descriptor in bytes. + */ +static int usb_audio_get_config_descriptor(unsigned char *dest, int max_packet_size) { (void)max_packet_size; unsigned int i; @@ -721,7 +746,13 @@ static void usb_audio_stop_playback(void) send_fb = false; } -int usb_audio_set_interface(int intf, int alt) +/* + * Called by control_request_handler_drivers(). + * Deal with changing the interface between control and streaming. + * + * Return 0 for success, -1 otherwise. + */ +static int usb_audio_set_interface(int intf, int alt) { if(intf == usb_interface) { @@ -757,7 +788,13 @@ int usb_audio_set_interface(int intf, int alt) } } -int usb_audio_get_interface(int intf) +/* + * Called by control_request_handler_drivers(). + * Get the alternate of the given interface. + * + * Return the alternate of the given interface, -1 if unknown. + */ +static int usb_audio_get_interface(int intf) { if(intf == usb_interface) { @@ -1139,7 +1176,13 @@ static bool usb_audio_interface_request(struct usb_ctrlrequest* req, void *reqda } } -bool usb_audio_control_request(struct usb_ctrlrequest* req, void *reqdata, unsigned char* dest) +/* + * Called by control_request_handler_drivers(). + * Pass control requests down to the appropriate functions. + * + * Return true if this driver handles the request, false otherwise. + */ +static bool usb_audio_control_request(struct usb_ctrlrequest* req, void *reqdata, unsigned char* dest) { (void) reqdata; (void) dest; @@ -1156,7 +1199,12 @@ bool usb_audio_control_request(struct usb_ctrlrequest* req, void *reqdata, unsig } } -void usb_audio_init_connection(void) +/* + * Called by usb_core_do_set_config() when the + * connection is ready to be used. Currently just sets + * the audio sample rate to default. + */ +static void usb_audio_init_connection(void) { logf("usbaudio: init connection"); @@ -1181,7 +1229,13 @@ void usb_audio_init_connection(void) usb_audio_playing = false; } -void usb_audio_disconnect(void) +/* + * Called by usb_core_exit() AND usb_core_do_set_config(). + * + * Indicates to the Class driver that the connection is no + * longer active. Currently just calls usb_audio_stop_playback(). + */ +static void usb_audio_disconnect(void) { logf("usbaudio: disconnect"); @@ -1258,7 +1312,12 @@ int usb_audio_get_frames_dropped(void) return frames_dropped; } -void usb_audio_transfer_complete(int ep, int dir, int status, int length) +/* + * Dummy function. + * + * The fast_transfer_complete() function needs to be used instead. + */ +static void usb_audio_transfer_complete(int ep, int dir, int status, int length) { /* normal handler is too slow to handle the completion rate, because * of the low thread schedule rate */ @@ -1268,7 +1327,14 @@ void usb_audio_transfer_complete(int ep, int dir, int status, int length) (void) length; } -bool usb_audio_fast_transfer_complete(int ep, int dir, int status, int length) +/* + * Called by usb_core_transfer_complete(). + * The normal transfer complete handler system is too slow to deal with + * ISO data at the rate required, so this is required. + * + * Return true if the transfer is handled, false otherwise. + */ +static bool usb_audio_fast_transfer_complete(int ep, int dir, int status, int length) { (void) dir; bool retval = false; @@ -1428,3 +1494,20 @@ bool usb_audio_fast_transfer_complete(int ep, int dir, int status, int length) return retval; } + +struct usb_class_driver usb_cdrv_audio = { + .needs_exclusive_storage = false, + .config = 1, + .ep_allocs_size = ARRAYLEN(ep_allocs), + .ep_allocs = ep_allocs, + .set_first_interface = usb_audio_set_first_interface, + .get_config_descriptor = usb_audio_get_config_descriptor, + .init_connection = usb_audio_init_connection, + .init = usb_audio_init, + .disconnect = usb_audio_disconnect, + .transfer_complete = usb_audio_transfer_complete, + .fast_transfer_complete = usb_audio_fast_transfer_complete, + .control_request = usb_audio_control_request, + .set_interface = usb_audio_set_interface, + .get_interface = usb_audio_get_interface, +}; diff --git a/firmware/usbstack/usb_audio.h b/firmware/usbstack/usb_audio.h index b6cd2461d7..a610fbe90a 100644 --- a/firmware/usbstack/usb_audio.h +++ b/firmware/usbstack/usb_audio.h @@ -30,64 +30,6 @@ * Relevant specifications are USB 2.0 and USB Audio Class 1.0. */ -extern struct usb_class_driver_ep_allocation usb_audio_ep_allocs[2]; - -/* - * usb_audio_set_first_interface(): - * - * Required function for the class driver. - * - * Called by allocate_interfaces_and_endpoints() to - * tell the class driver what its first interface number is. - * Returns the number of the interface available for the next - * class driver to use. - * - * We need 2 interfaces, AudioControl and AudioStreaming. - * Return interface+2. - */ -int usb_audio_set_first_interface(int interface); - -/* - * usb_audio_get_config_descriptor(): - * - * Required function for the class driver. - * - * Called by request_handler_device_get_descriptor(), which expects - * this function to fill *dest with the configuration descriptor for this - * class driver. - * - * Return the size of this descriptor in bytes. - */ -int usb_audio_get_config_descriptor(unsigned char *dest,int max_packet_size); - -/* - * usb_audio_init_connection(): - * - * Called by usb_core_do_set_config() when the - * connection is ready to be used. Currently just sets - * the audio sample rate to default. - */ -void usb_audio_init_connection(void); - -/* - * usb_audio_init(): - * - * Initialize the driver. Called by usb_core_init(). - * Currently initializes the sampling frequency values available - * to the AudioStreaming interface. - */ -void usb_audio_init(void); - -/* - * usb_audio_disconnect(): - * - * Called by usb_core_exit() AND usb_core_do_set_config(). - * - * Indicates to the Class driver that the connection is no - * longer active. Currently just calls usb_audio_stop_playback(). - */ -void usb_audio_disconnect(void); - /* * usb_audio_get_playing(): * @@ -103,56 +45,6 @@ bool usb_audio_get_playing(void); */ bool usb_audio_get_alloc_failed(void); -/* - * usb_audio_transfer_complete(): - * - * Dummy function. - * - * The fast_transfer_complete() function needs to be used instead. - */ -void usb_audio_transfer_complete(int ep,int dir, int status, int length); - -/* - * usb_audio_fast_transfer_complete(): - * - * Called by usb_core_transfer_complete(). - * The normal transfer complete handler system is too slow to deal with - * ISO data at the rate required, so this is required. - * - * Return true if the transfer is handled, false otherwise. - */ -bool usb_audio_fast_transfer_complete(int ep,int dir, int status, int length); - -/* - * usb_audio_control_request(): - * - * Called by control_request_handler_drivers(). - * Pass control requests down to the appropriate functions. - * - * Return true if this driver handles the request, false otherwise. - */ -bool usb_audio_control_request(struct usb_ctrlrequest* req, void* reqdata, unsigned char* dest); - -/* - * usb_audio_set_interface(): - * - * Called by control_request_handler_drivers(). - * Deal with changing the interface between control and streaming. - * - * Return 0 for success, -1 otherwise. - */ -int usb_audio_set_interface(int intf, int alt); - -/* - * usb_audio_get_interface(): - * - * Called by control_request_handler_drivers(). - * Get the alternate of the given interface. - * - * Return the alternate of the given interface, -1 if unknown. - */ -int usb_audio_get_interface(int intf); - /* * usb_audio_get_playback_sampling_frequency(): * @@ -266,4 +158,6 @@ int usb_audio_get_cur_volume(void); bool usb_audio_get_active(void); +extern struct usb_class_driver usb_cdrv_audio; + #endif diff --git a/firmware/usbstack/usb_charging_only.c b/firmware/usbstack/usb_charging_only.c index 3fa384cfec..23d285923c 100644 --- a/firmware/usbstack/usb_charging_only.c +++ b/firmware/usbstack/usb_charging_only.c @@ -46,13 +46,13 @@ static struct usb_interface_descriptor __attribute__((aligned(2))) static int usb_interface; -int usb_charging_only_set_first_interface(int interface) +static int usb_charging_only_set_first_interface(int interface) { usb_interface = interface; return interface + 1; } -int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size) +static int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size) { (void)max_packet_size; unsigned char *orig_dest = dest; @@ -62,3 +62,10 @@ int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_s return (dest-orig_dest); } + +struct usb_class_driver usb_cdrv_charging_only = { + .needs_exclusive_storage = false, + .config = 1, + .set_first_interface = usb_charging_only_set_first_interface, + .get_config_descriptor = usb_charging_only_get_config_descriptor, +}; diff --git a/firmware/usbstack/usb_charging_only.h b/firmware/usbstack/usb_charging_only.h index 68b60956e2..1c49c9788c 100644 --- a/firmware/usbstack/usb_charging_only.h +++ b/firmware/usbstack/usb_charging_only.h @@ -21,12 +21,8 @@ #ifndef USB_CHARGING_ONLY_H #define USB_CHARGING_ONLY_H -#include "usb_ch9.h" +#include "usb_class_driver.h" -void usb_charging_only_init(void); -int usb_charging_only_set_first_interface(int interface); -int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size); -bool usb_charging_only_control_request(struct usb_ctrlrequest* req); +extern struct usb_class_driver usb_cdrv_charging_only; #endif - diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c index f6b48a3185..3f1dee129c 100644 --- a/firmware/usbstack/usb_core.c +++ b/firmware/usbstack/usb_core.c @@ -201,141 +201,25 @@ struct ep_alloc_state { static struct ep_alloc_state ep_alloc_states[NUM_CONFIGS][USB_NUM_ENDPOINTS]; -static struct usb_class_driver drivers[USB_NUM_DRIVERS] = +static struct usb_class_driver* drivers[USB_NUM_DRIVERS] = { #ifdef USB_ENABLE_STORAGE - [USB_DRIVER_MASS_STORAGE] = { - .enabled = false, - .needs_exclusive_storage = true, - .config = 1, - .first_interface = 0, - .last_interface = 0, - .ep_allocs_size = ARRAYLEN(usb_storage_ep_allocs), - .ep_allocs = usb_storage_ep_allocs, - .set_first_interface = usb_storage_set_first_interface, - .get_config_descriptor = usb_storage_get_config_descriptor, - .init_connection = usb_storage_init_connection, - .init = usb_storage_init, - .disconnect = usb_storage_disconnect, - .transfer_complete = usb_storage_transfer_complete, - .control_request = usb_storage_control_request, -#ifdef HAVE_HOTSWAP - .notify_hotswap = usb_storage_notify_hotswap, -#endif - }, + [USB_DRIVER_MASS_STORAGE] = &usb_cdrv_storage, #endif #ifdef USB_ENABLE_SERIAL - [USB_DRIVER_SERIAL] = { - .enabled = false, - .needs_exclusive_storage = false, - .config = 1, - .first_interface = 0, - .last_interface = 0, - .ep_allocs_size = ARRAYLEN(usb_serial_ep_allocs), - .ep_allocs = usb_serial_ep_allocs, - .set_first_interface = usb_serial_set_first_interface, - .get_config_descriptor = usb_serial_get_config_descriptor, - .init_connection = usb_serial_init_connection, - .init = usb_serial_init, - .disconnect = usb_serial_disconnect, - .transfer_complete = usb_serial_transfer_complete, - .control_request = usb_serial_control_request, -#ifdef HAVE_HOTSWAP - .notify_hotswap = NULL, -#endif - }, + [USB_DRIVER_SERIAL] = &usb_cdrv_serial, #endif #ifdef USB_ENABLE_CHARGING_ONLY - [USB_DRIVER_CHARGING_ONLY] = { - .enabled = false, - .needs_exclusive_storage = false, - .config = 1, - .first_interface = 0, - .last_interface = 0, - .ep_allocs_size = 0, - .ep_allocs = NULL, - .set_first_interface = usb_charging_only_set_first_interface, - .get_config_descriptor = usb_charging_only_get_config_descriptor, - .init_connection = NULL, - .init = NULL, - .disconnect = NULL, - .transfer_complete = NULL, - .control_request = NULL, -#ifdef HAVE_HOTSWAP - .notify_hotswap = NULL, -#endif - }, + [USB_DRIVER_CHARGING_ONLY] = &usb_cdrv_charging_only, #endif #ifdef USB_ENABLE_HID - [USB_DRIVER_HID] = { - .enabled = false, - .needs_exclusive_storage = false, - .config = 1, - .first_interface = 0, - .last_interface = 0, - .ep_allocs_size = ARRAYLEN(usb_hid_ep_allocs), - .ep_allocs = usb_hid_ep_allocs, - .set_first_interface = usb_hid_set_first_interface, - .get_config_descriptor = usb_hid_get_config_descriptor, - .init_connection = usb_hid_init_connection, - .init = usb_hid_init, - .disconnect = usb_hid_disconnect, - .transfer_complete = usb_hid_transfer_complete, - .control_request = usb_hid_control_request, -#ifdef HAVE_HOTSWAP - .notify_hotswap = NULL, -#endif - }, + [USB_DRIVER_HID] = &usb_cdrv_hid, #endif #ifdef USB_ENABLE_AUDIO - [USB_DRIVER_AUDIO] = { - .enabled = false, - .needs_exclusive_storage = false, - .config = 1, - .first_interface = 0, - .last_interface = 0, - .ep_allocs_size = ARRAYLEN(usb_audio_ep_allocs), - .ep_allocs = usb_audio_ep_allocs, - .set_first_interface = usb_audio_set_first_interface, - .get_config_descriptor = usb_audio_get_config_descriptor, - .init_connection = usb_audio_init_connection, - .init = usb_audio_init, - .disconnect = usb_audio_disconnect, - .transfer_complete = usb_audio_transfer_complete, - .fast_transfer_complete = usb_audio_fast_transfer_complete, - .control_request = usb_audio_control_request, -#ifdef HAVE_HOTSWAP - .notify_hotswap = NULL, -#endif - .set_interface = usb_audio_set_interface, - .get_interface = usb_audio_get_interface, - }, + [USB_DRIVER_AUDIO] = &usb_cdrv_audio, #endif #ifdef USB_ENABLE_IAP - [USB_DRIVER_IAP] = { - .enabled = false, - .needs_exclusive_storage = false, - .config = 2, - .first_interface = 0, - .last_interface = 0, - .ep_allocs_size = ARRAYLEN(usb_iap_ep_allocs), - .ep_allocs = usb_iap_ep_allocs, - .set_first_interface = usb_iap_set_first_interface, - .get_config_descriptor = usb_iap_get_config_descriptor, - .init_connection = usb_iap_init_connection, - .init = usb_iap_init, - .disconnect = usb_iap_disconnect, - .transfer_complete = usb_iap_transfer_complete, - .fast_transfer_complete = usb_iap_fast_transfer_complete, - .control_request = usb_iap_control_request, -#ifdef HAVE_HOTSWAP - .notify_hotswap = NULL, -#endif - .set_interface = usb_iap_set_interface, - .get_interface = usb_iap_get_interface, - .get_max_packet_size = usb_iap_get_max_packet_size, - .notify_event = usb_iap_notify_event, - }, + [USB_DRIVER_IAP] = &usb_cdrv_iap, #endif }; @@ -352,8 +236,8 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req, void* static unsigned char response_data[256] USB_DEVBSS_ATTR; -#define is_active(driver) ((driver).enabled && (driver).config == usb_config) -#define has_if(driver, interface) ((interface) >= (driver).first_interface && (interface) < (driver).last_interface) +#define is_active(driver) ((driver)->enabled && (driver)->config == usb_config) +#define has_if(driver, interface) ((interface) >= (driver)->first_interface && (interface) < (driver)->last_interface) /** NOTE Serial Number * The serial number string is split into two parts: @@ -513,9 +397,14 @@ void usb_core_init(void) /* class driver init functions should be safe to call even if the driver * won't be used. This simplifies other logic (i.e. we don't need to know * yet which drivers will be enabled */ - for(i = 0; i < USB_NUM_DRIVERS; i++) - if(drivers[i].init != NULL) - drivers[i].init(); + for(i = 0; i < USB_NUM_DRIVERS; i++) { + drivers[i]->enabled = false; + drivers[i]->first_interface = 0; + drivers[i]->last_interface = 0; + if(drivers[i]->init != NULL) { + drivers[i]->init(); + } + } /* clear endpoint allocation state */ memset(ep_alloc_states, 0, sizeof(ep_alloc_states)); @@ -570,12 +459,12 @@ void usb_core_handle_transfer_completion( void usb_core_enable_driver(int driver, bool enabled) { - drivers[driver].enabled = enabled; + drivers[driver]->enabled = enabled; } bool usb_core_driver_enabled(int driver) { - return drivers[driver].enabled; + return drivers[driver]->enabled; } #ifdef HAVE_HOTSWAP @@ -583,8 +472,8 @@ void usb_core_hotswap_event(int volume, bool inserted) { int i; for(i = 0; i < USB_NUM_DRIVERS; i++) - if(drivers[i].enabled && drivers[i].notify_hotswap != NULL) - drivers[i].notify_hotswap(volume, inserted); + if(drivers[i]->enabled && drivers[i]->notify_hotswap != NULL) + drivers[i]->notify_hotswap(volume, inserted); } #endif @@ -651,7 +540,7 @@ static void usb_core_set_serial_function_id(void) int i, id = 0; for(i = 0; i < USB_NUM_DRIVERS; i++) - if(drivers[i].enabled) + if(drivers[i]->enabled) id |= 1 << i; usb_string_iSerial.wString[0] = hex[id]; @@ -700,7 +589,7 @@ static void allocate_interfaces_and_endpoints(void) int interface[NUM_CONFIGS] = {0}; for(int i = 0; i < USB_NUM_DRIVERS; i++) { - struct usb_class_driver* driver = &drivers[i]; + struct usb_class_driver* driver = drivers[i]; const uint8_t conf_index = driver->config - 1; if(!driver->enabled) { @@ -785,8 +674,8 @@ static void control_request_handler_drivers(struct usb_ctrlrequest* req, void* r bool handled = false; for(i = 0; i < USB_NUM_DRIVERS; i++) { - struct usb_class_driver* driver = &drivers[i]; - if(!is_active(*driver) || !has_if(*driver, interface) || driver->control_request == NULL) { + struct usb_class_driver* driver = drivers[i]; + if(!is_active(driver) || !has_if(driver, interface) || driver->control_request == NULL) { continue; } @@ -804,8 +693,8 @@ static void control_request_handler_drivers(struct usb_ctrlrequest* req, void* r int alt = -1; logf("usb_core: GET INTERFACE 0x%x", req->wIndex); - if(drivers[i].get_interface) - alt = drivers[i].get_interface(req->wIndex); + if(driver->get_interface) + alt = driver->get_interface(req->wIndex); if(alt >= 0 && alt < 255) { response_data[0] = alt; @@ -870,8 +759,8 @@ static void request_handler_device_get_descriptor(struct usb_ctrlrequest* req, v size = sizeof(struct usb_config_descriptor); for(i = 0; i < USB_NUM_DRIVERS; i++) { - if(drivers[i].enabled && drivers[i].config == index + 1 && drivers[i].get_config_descriptor) { - size += drivers[i].get_config_descriptor(&response_data[size], max_packet_size); + if(drivers[i]->enabled && drivers[i]->config == index + 1 && drivers[i]->get_config_descriptor) { + size += drivers[i]->get_config_descriptor(&response_data[size], max_packet_size); } } @@ -945,8 +834,8 @@ static int usb_core_do_set_config(uint8_t new_config) /* deactivate old config */ if(usb_config != 0) { for(int i = 0; i < USB_NUM_DRIVERS; i++) { - if(is_active(drivers[i]) && drivers[i].disconnect != NULL) { - drivers[i].disconnect(); + if(is_active(drivers[i]) && drivers[i]->disconnect != NULL) { + drivers[i]->disconnect(); } } init_deinit_endpoints(usb_config - 1, false); @@ -967,9 +856,9 @@ static int usb_core_do_set_config(uint8_t new_config) if(usb_config != 0) { init_deinit_endpoints(usb_config - 1, true); for(int i = 0; i < USB_NUM_DRIVERS; i++) { - if(is_active(drivers[i]) && drivers[i].init_connection != NULL) { - drivers[i].init_connection(); - require_exclusive |= drivers[i].needs_exclusive_storage; + if(is_active(drivers[i]) && drivers[i]->init_connection != NULL) { + drivers[i]->init_connection(); + require_exclusive |= drivers[i]->needs_exclusive_storage; } } } @@ -1302,8 +1191,8 @@ void usb_core_handle_notify(long id, intptr_t data) 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); + if(is_active(drivers[index]) && drivers[index]->notify_event != NULL) { + drivers[index]->notify_event(data & 0x00ffffff); } } break; default: diff --git a/firmware/usbstack/usb_hid.c b/firmware/usbstack/usb_hid.c index ee99e29fdc..3b231cfa8c 100644 --- a/firmware/usbstack/usb_hid.c +++ b/firmware/usbstack/usb_hid.c @@ -121,11 +121,11 @@ static bool active = false; static bool currently_sending = false; static int usb_interface; -struct usb_class_driver_ep_allocation usb_hid_ep_allocs[1] = { +static struct usb_class_driver_ep_allocation ep_allocs[1] = { {.type = USB_ENDPOINT_XFER_INT, .dir = DIR_IN, .optional = false}, }; -#define EP_IN (usb_hid_ep_allocs[0].ep) +#define EP_IN (ep_allocs[0].ep) static void usb_hid_try_send_drv(void); @@ -173,7 +173,7 @@ static void pack_parameter(unsigned char **dest, bool is_signed, bool mark_size, } } -int usb_hid_set_first_interface(int interface) +static int usb_hid_set_first_interface(int interface) { usb_interface = interface; @@ -519,7 +519,7 @@ static void descriptor_hid_get(unsigned char **dest) PACK_DATA(dest, hid_descriptor); } -int usb_hid_get_config_descriptor(unsigned char *dest, int max_packet_size) +static int usb_hid_get_config_descriptor(unsigned char *dest, int max_packet_size) { (void)max_packet_size; @@ -543,7 +543,7 @@ int usb_hid_get_config_descriptor(unsigned char *dest, int max_packet_size) return (int)(dest - orig_dest); } -void usb_hid_init_connection(void) +static void usb_hid_init_connection(void) { logf("hid: init connection"); active = true; @@ -551,7 +551,7 @@ void usb_hid_init_connection(void) } /* called by usb_core_init() */ -void usb_hid_init(void) +static void usb_hid_init(void) { logf("hid: init"); @@ -565,7 +565,7 @@ void usb_hid_init(void) currently_sending = false; } -void usb_hid_disconnect(void) +static void usb_hid_disconnect(void) { logf("hid: disconnect"); active = false; @@ -573,7 +573,7 @@ void usb_hid_disconnect(void) } /* called by usb_core_transfer_complete() */ -void usb_hid_transfer_complete(int ep, int dir, int status, int length) +static void usb_hid_transfer_complete(int ep, int dir, int status, int length) { (void)ep; (void)length; @@ -678,7 +678,7 @@ static int usb_hid_get_report(struct usb_ctrlrequest *req, unsigned char* dest) } /* called by usb_core_control_request() */ -bool usb_hid_control_request(struct usb_ctrlrequest *req, void *reqdata, unsigned char *dest) +static bool usb_hid_control_request(struct usb_ctrlrequest *req, void *reqdata, unsigned char *dest) { (void)reqdata; @@ -828,3 +828,17 @@ void usb_hid_send(usage_page_t usage_page, int id) usb_hid_try_send_drv(); } + +struct usb_class_driver usb_cdrv_hid = { + .needs_exclusive_storage = false, + .config = 1, + .ep_allocs_size = ARRAYLEN(ep_allocs), + .ep_allocs = ep_allocs, + .set_first_interface = usb_hid_set_first_interface, + .get_config_descriptor = usb_hid_get_config_descriptor, + .init_connection = usb_hid_init_connection, + .init = usb_hid_init, + .disconnect = usb_hid_disconnect, + .transfer_complete = usb_hid_transfer_complete, + .control_request = usb_hid_control_request, +}; diff --git a/firmware/usbstack/usb_hid.h b/firmware/usbstack/usb_hid.h index 379b17d2bf..7a62b4e353 100644 --- a/firmware/usbstack/usb_hid.h +++ b/firmware/usbstack/usb_hid.h @@ -25,17 +25,8 @@ #include "usb_class_driver.h" #include "usb_hid_usage_tables.h" -extern struct usb_class_driver_ep_allocation usb_hid_ep_allocs[1]; - -int usb_hid_set_first_interface(int interface); -int usb_hid_get_config_descriptor(unsigned char *dest, int max_packet_size); -void usb_hid_init_connection(void); -void usb_hid_init(void); -void usb_hid_disconnect(void); -void usb_hid_transfer_complete(int ep, int dir, int status, int length); -bool usb_hid_control_request(struct usb_ctrlrequest* req, void* reqdata, unsigned char* dest); - void usb_hid_send(usage_page_t usage_page, int id); -#endif +extern struct usb_class_driver usb_cdrv_hid; +#endif diff --git a/firmware/usbstack/usb_iap.c b/firmware/usbstack/usb_iap.c index bf6889e66e..99492f791b 100644 --- a/firmware/usbstack/usb_iap.c +++ b/firmware/usbstack/usb_iap.c @@ -23,6 +23,7 @@ #include "playback.h" #include "powermgmt.h" #include "timefuncs.h" +#include "usb_core.h" #include "usb_drv.h" #include "panic.h" @@ -320,7 +321,7 @@ static int tick_callback(struct timeout* tmo) { return HZ / 10; } -int usb_iap_set_first_interface(int interface) { +static int usb_iap_set_first_interface(int interface) { ctrl.interface = interface + 0; stream.interface = interface + 1; hid.interface = interface + 2; @@ -329,7 +330,7 @@ int usb_iap_set_first_interface(int interface) { #define PACK_DESC(desc) pack_data(&dest, &desc, ((struct usb_descriptor_header*)&desc)->bLength) -int usb_iap_get_config_descriptor(unsigned char* dest, int max_packet_size) { +static int usb_iap_get_config_descriptor(unsigned char* dest, int max_packet_size) { (void)max_packet_size; unsigned char* orig_dest = dest; @@ -372,7 +373,7 @@ int usb_iap_get_config_descriptor(unsigned char* dest, int max_packet_size) { return dest - orig_dest; } -void usb_iap_init_connection(void) { +static void usb_iap_init_connection(void) { stream.sample_rate = 48000; last_charge_state = -1; last_minute = -1; @@ -422,7 +423,7 @@ cleanup_audio: iap_audio_deinit(); } -int usb_iap_set_interface(int intf, int alt) { +static int usb_iap_set_interface(int intf, int alt) { LOG("set interface interface=%d alt=%d", intf, alt); check_act(intf == stream.interface, return -1); if(alt == 0) { @@ -436,13 +437,13 @@ int usb_iap_set_interface(int intf, int alt) { return 0; } -int usb_iap_get_interface(int intf) { +static int usb_iap_get_interface(int intf) { LOG("get interface interface=%d", intf); check_act(intf == stream.interface, return -1); return stream.alt; } -int usb_iap_get_max_packet_size(int ep) { +static int usb_iap_get_max_packet_size(int ep) { if(ep == AS_EP_IN) { return 1024; } else if(ep == HID_EP_IN) { @@ -453,11 +454,11 @@ int usb_iap_get_max_packet_size(int ep) { } } -void usb_iap_init(void) { +static void usb_iap_init(void) { LOG("init"); } -void usb_iap_disconnect(void) { +static void usb_iap_disconnect(void) { iap_initialized = false; audio_pause(); mixer_switch_sink(PCM_SINK_BUILTIN); @@ -472,7 +473,7 @@ void usb_iap_disconnect(void) { LOG("disconnected"); } -void usb_iap_transfer_complete(int ep, int dir, int status, int length) { +static void usb_iap_transfer_complete(int ep, int dir, int status, int length) { (void)length; if((ep | dir) == HID_EP_IN) { @@ -486,7 +487,7 @@ void usb_iap_transfer_complete(int ep, int dir, int status, int length) { } } -bool usb_iap_fast_transfer_complete(int ep, int dir, int status, int length) { +static bool usb_iap_fast_transfer_complete(int ep, int dir, int status, int length) { (void)status; (void)length; return (ep | dir) == AS_EP_IN; @@ -634,7 +635,7 @@ static bool control_request_if_endpoint(struct usb_ctrlrequest* req, void* reqda return false; } -bool usb_iap_control_request(struct usb_ctrlrequest* req, void* reqdata, unsigned char* dest) { +static bool usb_iap_control_request(struct usb_ctrlrequest* req, void* reqdata, unsigned char* dest) { const uint8_t req_recipient = req->bRequestType & USB_RECIP_MASK; const uint8_t req_type = req->bRequestType & USB_TYPE_MASK; #if 0 @@ -651,7 +652,7 @@ bool usb_iap_control_request(struct usb_ctrlrequest* req, void* reqdata, unsigne return false; } -void usb_iap_notify_event(intptr_t data) { +static void usb_iap_notify_event(intptr_t data) { switch(data) { case Notify_Tick: { struct IAPContext* ctx = _iap_acquire_ctx(true); @@ -689,3 +690,22 @@ void usb_iap_notify_event(intptr_t data) { } break; } } + +struct usb_class_driver usb_cdrv_iap = { + .needs_exclusive_storage = false, + .config = 2, + .ep_allocs_size = ARRAYLEN(usb_iap_ep_allocs), + .ep_allocs = usb_iap_ep_allocs, + .set_first_interface = usb_iap_set_first_interface, + .get_config_descriptor = usb_iap_get_config_descriptor, + .init_connection = usb_iap_init_connection, + .init = usb_iap_init, + .disconnect = usb_iap_disconnect, + .transfer_complete = usb_iap_transfer_complete, + .fast_transfer_complete = usb_iap_fast_transfer_complete, + .control_request = usb_iap_control_request, + .set_interface = usb_iap_set_interface, + .get_interface = usb_iap_get_interface, + .get_max_packet_size = usb_iap_get_max_packet_size, + .notify_event = usb_iap_notify_event, +}; diff --git a/firmware/usbstack/usb_iap.h b/firmware/usbstack/usb_iap.h index c1990bc8d3..dcf1336f2d 100644 --- a/firmware/usbstack/usb_iap.h +++ b/firmware/usbstack/usb_iap.h @@ -18,7 +18,6 @@ * ****************************************************************************/ #pragma once -#include "usb_core.h" #include "usb_class_driver.h" /* [2] P.32 Table 2-8 USB Device Vendor Request to set available current from accessory (USB Device Mode only) */ @@ -26,18 +25,4 @@ extern struct usb_class_driver_ep_allocation usb_iap_ep_allocs[2]; -int usb_iap_request_endpoints(struct usb_class_driver*); -int usb_iap_set_first_interface(int interface); -int usb_iap_get_config_descriptor(unsigned char* dest, int max_packet_size); -void usb_iap_init_connection(void); -bool usb_iap_set_alt_interface(int interface, int alt); -int usb_iap_get_alt_interface(int interface); -void usb_iap_init(void); -void usb_iap_disconnect(void); -void usb_iap_transfer_complete(int ep, int dir, int state, int length); -bool usb_iap_fast_transfer_complete(int ep, int dir, int status, int length); -bool usb_iap_control_request(struct usb_ctrlrequest* req, void* reqdata, unsigned char* dest); -int usb_iap_set_interface(int intf, int alt); -int usb_iap_get_interface(int intf); -int usb_iap_get_max_packet_size(int ep); -void usb_iap_notify_event(intptr_t data); +extern struct usb_class_driver usb_cdrv_iap; diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c index 5c3b084b4b..80aaaaef5d 100644 --- a/firmware/usbstack/usb_serial.c +++ b/firmware/usbstack/usb_serial.c @@ -206,26 +206,26 @@ static int buffer_length; static int buffer_transitlength; static bool active = false; -struct usb_class_driver_ep_allocation usb_serial_ep_allocs[3] = { +static struct usb_class_driver_ep_allocation ep_allocs[3] = { {.type = USB_ENDPOINT_XFER_BULK, .dir = DIR_IN, .optional = false}, {.type = USB_ENDPOINT_XFER_BULK, .dir = DIR_OUT, .optional = false}, {.type = USB_ENDPOINT_XFER_INT, .dir = DIR_IN, .optional = true}, }; -#define EP_IN (usb_serial_ep_allocs[0].ep) -#define EP_OUT (usb_serial_ep_allocs[1].ep) -#define EP_INT (usb_serial_ep_allocs[2].ep) +#define EP_IN (ep_allocs[0].ep) +#define EP_OUT (ep_allocs[1].ep) +#define EP_INT (ep_allocs[2].ep) static int control_interface, data_interface; -int usb_serial_set_first_interface(int interface) +static int usb_serial_set_first_interface(int interface) { control_interface = interface; data_interface = interface + 1; return interface + 2; } -int usb_serial_get_config_descriptor(unsigned char *dest, int max_packet_size) +static int usb_serial_get_config_descriptor(unsigned char *dest, int max_packet_size) { unsigned char *orig_dest = dest; @@ -270,7 +270,7 @@ int usb_serial_get_config_descriptor(unsigned char *dest, int max_packet_size) } /* called by usb_core_control_request() */ -bool usb_serial_control_request(struct usb_ctrlrequest* req, void* reqdata, unsigned char* dest) +static bool usb_serial_control_request(struct usb_ctrlrequest* req, void* reqdata, unsigned char* dest) { bool handled = false; @@ -329,7 +329,7 @@ bool usb_serial_control_request(struct usb_ctrlrequest* req, void* reqdata, unsi return handled; } -void usb_serial_init_connection(void) +static void usb_serial_init_connection(void) { /* prime rx endpoint */ usb_drv_recv_nonblocking(EP_OUT, receive_buffer, RECV_BUFFER_SIZE); @@ -344,7 +344,7 @@ void usb_serial_init_connection(void) } /* called by usb_code_init() */ -void usb_serial_init(void) +static void usb_serial_init(void) { logf("serial: init"); buffer_start = 0; @@ -352,7 +352,7 @@ void usb_serial_init(void) buffer_transitlength = 0; } -void usb_serial_disconnect(void) +static void usb_serial_disconnect(void) { active = false; } @@ -412,7 +412,7 @@ void usb_serial_send(const unsigned char *data,int length) } /* called by usb_core_transfer_complete() */ -void usb_serial_transfer_complete(int ep,int dir, int status, int length) +static void usb_serial_transfer_complete(int ep,int dir, int status, int length) { (void)ep; (void)length; @@ -441,3 +441,17 @@ void usb_serial_transfer_complete(int ep,int dir, int status, int length) break; } } + +struct usb_class_driver usb_cdrv_serial = { + .needs_exclusive_storage = false, + .config = 1, + .ep_allocs_size = ARRAYLEN(ep_allocs), + .ep_allocs = ep_allocs, + .set_first_interface = usb_serial_set_first_interface, + .get_config_descriptor = usb_serial_get_config_descriptor, + .init_connection = usb_serial_init_connection, + .init = usb_serial_init, + .disconnect = usb_serial_disconnect, + .transfer_complete = usb_serial_transfer_complete, + .control_request = usb_serial_control_request, +}; diff --git a/firmware/usbstack/usb_serial.h b/firmware/usbstack/usb_serial.h index e78273cb8e..a71e91b920 100644 --- a/firmware/usbstack/usb_serial.h +++ b/firmware/usbstack/usb_serial.h @@ -23,17 +23,8 @@ #include "usb_class_driver.h" -extern struct usb_class_driver_ep_allocation usb_serial_ep_allocs[3]; - -int usb_serial_set_first_interface(int interface); -int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size); -void usb_serial_init_connection(void); -void usb_serial_init(void); -void usb_serial_disconnect(void); -void usb_serial_transfer_complete(int ep,int dir, int status, int length); -bool usb_serial_control_request(struct usb_ctrlrequest* req, void* reqdata, unsigned char *dest); - void usb_serial_send(const unsigned char *data, int length); -#endif +extern struct usb_class_driver usb_cdrv_serial; +#endif diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index 4aadf1e0f1..17677c44cd 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c @@ -322,13 +322,13 @@ static bool locked[NUM_DRIVES]; static int usb_interface; -struct usb_class_driver_ep_allocation usb_storage_ep_allocs[2] = { +static struct usb_class_driver_ep_allocation ep_allocs[2] = { {.type = USB_ENDPOINT_XFER_BULK, .dir = DIR_IN, .optional = false}, {.type = USB_ENDPOINT_XFER_BULK, .dir = DIR_OUT, .optional = false}, }; -#define EP_IN (usb_storage_ep_allocs[0].ep) -#define EP_OUT (usb_storage_ep_allocs[1].ep) +#define EP_IN (ep_allocs[0].ep) +#define EP_OUT (ep_allocs[1].ep) #if defined(HAVE_MULTIDRIVE) static bool skip_first = 0; @@ -378,7 +378,7 @@ static bool check_disk_present(IF_MD_NONVOID(int volume)) } #ifdef HAVE_HOTSWAP -void usb_storage_notify_hotswap(int volume,bool inserted) +static void usb_storage_notify_hotswap(int volume,bool inserted) { logf("notify %d",inserted); if(inserted && check_disk_present(IF_MD(volume))) { @@ -401,18 +401,18 @@ void usb_set_skip_first_drive(bool skip) #endif /* called by usb_core_init() */ -void usb_storage_init(void) +static void usb_storage_init(void) { logf("usb_storage_init done"); } -int usb_storage_set_first_interface(int interface) +static int usb_storage_set_first_interface(int interface) { usb_interface = interface; return interface + 1; } -int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size) +static int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size) { unsigned char *orig_dest = dest; @@ -436,7 +436,7 @@ int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size) #else static int usb_handle = 0; #endif -void usb_storage_init_connection(void) +static void usb_storage_init_connection(void) { logf("ums: set config"); /* prime rx endpoint. We only need room for commands */ @@ -493,7 +493,7 @@ void usb_storage_disconnect(void) } /* called by usb_core_transfer_complete() */ -void usb_storage_transfer_complete(int ep,int dir,int status,int length) +static void usb_storage_transfer_complete(int ep,int dir,int status,int length) { (void)ep; struct command_block_wrapper* cbw = (void*)cbw_buffer; @@ -694,7 +694,7 @@ static void usb_storage_send_smart(uint8_t cmd) #endif /* STORAGE_ATA */ /* called by usb_core_control_request() */ -bool usb_storage_control_request(struct usb_ctrlrequest* req, void* reqdata, unsigned char* dest) +static bool usb_storage_control_request(struct usb_ctrlrequest* req, void* reqdata, unsigned char* dest) { bool handled = false; @@ -1479,3 +1479,20 @@ static void fill_inquiry(IF_MD_NONVOID(int lun)) tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; } + +struct usb_class_driver usb_cdrv_storage = { + .needs_exclusive_storage = true, + .config = 1, + .ep_allocs_size = ARRAYLEN(ep_allocs), + .ep_allocs = ep_allocs, + .set_first_interface = usb_storage_set_first_interface, + .get_config_descriptor = usb_storage_get_config_descriptor, + .init_connection = usb_storage_init_connection, + .init = usb_storage_init, + .disconnect = usb_storage_disconnect, + .transfer_complete = usb_storage_transfer_complete, + .control_request = usb_storage_control_request, +#ifdef HAVE_HOTSWAP + .notify_hotswap = usb_storage_notify_hotswap, +#endif +}; diff --git a/firmware/usbstack/usb_storage.h b/firmware/usbstack/usb_storage.h index 8dbe965882..16bc172ce5 100644 --- a/firmware/usbstack/usb_storage.h +++ b/firmware/usbstack/usb_storage.h @@ -23,18 +23,6 @@ #include "usb_class_driver.h" -extern struct usb_class_driver_ep_allocation usb_storage_ep_allocs[2]; - -int usb_storage_set_first_interface(int interface); -int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size); -void usb_storage_init_connection(void); -void usb_storage_disconnect(void); -void usb_storage_init(void); -void usb_storage_transfer_complete(int ep,int dir,int state,int length); -bool usb_storage_control_request(struct usb_ctrlrequest* req, void* reqdata, unsigned char* dest); -#ifdef HAVE_HOTSWAP -void usb_storage_notify_hotswap(int volume,bool inserted); -#endif - +extern struct usb_class_driver usb_cdrv_storage; #endif