usb: hold class_driver instance in each driver

rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]> Sun, 3 May 2026 15:18:52 -0400
Newsgroups gmane.comp.systems.archos.rockbox.cvs
Message-ID <[email protected]>
commit 3c10b21c10ca1c0f888ae30696e9a791199ded0d
Author: mojyack <[email protected]>
Date:   Fri Dec 19 21:23:52 2025 +0900

    usb: hold class_driver instance in each driver
    
    Change-Id: Ia2f857bffcc6c3cca4dee59791c48c628082595b

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
 
-- 
rockbox-cvs mailing list
[email protected]
https://lists.haxx.se/mailman/listinfo/rockbox-cvs