usb: hold class_driver instance in each driver

Change-Id: Ia2f857bffcc6c3cca4dee59791c48c628082595b
This commit is contained in:
mojyack 2025-12-19 21:23:52 +09:00 committed by Solomon Peachy
parent 82a0921399
commit 3c10b21c10
13 changed files with 258 additions and 369 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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