drivers/usb/gadget/function/f_midi.c
Source file repositories/reference/linux-study-clean/drivers/usb/gadget/function/f_midi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/gadget/function/f_midi.c- Extension
.c- Size
- 36282 bytes
- Lines
- 1415
- Domain
- Driver Families
- Bucket
- drivers/usb
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/slab.hlinux/device.hlinux/kfifo.hlinux/spinlock.hsound/core.hsound/initval.hsound/rawmidi.hlinux/usb/ch9.hlinux/usb/func_utils.hlinux/usb/gadget.hlinux/usb/audio.hlinux/usb/midi.hu_midi.h
Detected Declarations
struct gmidi_in_portstruct f_midifunction f_midi_read_datafunction f_midi_handle_out_datafunction f_midi_completefunction f_midi_drop_out_substreamsfunction f_midi_start_epfunction f_midi_set_altfunction f_midi_disablefunction f_midi_snd_freefunction f_midi_transmit_bytefunction f_midi_do_transmitfunction f_midi_transmitfunction f_midi_in_workfunction f_midi_in_openfunction f_midi_in_closefunction f_midi_in_triggerfunction f_midi_out_openfunction f_midi_out_closefunction f_midi_out_triggerfunction f_midi_unregister_cardfunction f_midi_register_cardfunction f_midi_bindfunction midi_attr_releasefunction f_midi_free_instfunction f_midi_freefunction f_midi_rmidi_freefunction f_midi_unbind
Annotated Snippet
struct gmidi_in_port {
struct snd_rawmidi_substream *substream;
int active;
uint8_t cable;
uint8_t state;
uint8_t data[2];
};
struct f_midi {
struct usb_function func;
struct usb_gadget *gadget;
struct usb_ep *in_ep, *out_ep;
struct snd_card *card;
struct snd_rawmidi *rmidi;
u8 ms_id;
struct snd_rawmidi_substream *out_substream[MAX_PORTS];
unsigned long out_triggered;
struct work_struct work;
unsigned int in_ports;
unsigned int out_ports;
int index;
char *id;
unsigned int buflen, qlen;
/* This fifo is used as a buffer ring for pre-allocated IN usb_requests */
DECLARE_KFIFO_PTR(in_req_fifo, struct usb_request *);
spinlock_t transmit_lock;
unsigned int in_last_port;
unsigned char free_ref;
struct gmidi_in_port in_ports_array[] __counted_by(in_ports);
};
static inline struct f_midi *func_to_midi(struct usb_function *f)
{
return container_of(f, struct f_midi, func);
}
static void f_midi_transmit(struct f_midi *midi);
static void f_midi_rmidi_free(struct snd_rawmidi *rmidi);
static void f_midi_free_inst(struct usb_function_instance *f);
DECLARE_UAC_AC_HEADER_DESCRIPTOR(1);
DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1);
DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16);
/* B.3.1 Standard AC Interface Descriptor */
static struct usb_interface_descriptor ac_interface_desc = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
/* .bInterfaceNumber = DYNAMIC */
/* .bNumEndpoints = DYNAMIC */
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
/* .iInterface = DYNAMIC */
};
/* B.3.2 Class-Specific AC Interface Descriptor */
static struct uac1_ac_header_descriptor_1 ac_header_desc = {
.bLength = UAC_DT_AC_HEADER_SIZE(1),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = USB_MS_HEADER,
.bcdADC = cpu_to_le16(0x0100),
.wTotalLength = cpu_to_le16(UAC_DT_AC_HEADER_SIZE(1)),
.bInCollection = 1,
/* .baInterfaceNr = DYNAMIC */
};
/* B.4.1 Standard MS Interface Descriptor */
static struct usb_interface_descriptor ms_interface_desc = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
/* .bInterfaceNumber = DYNAMIC */
.bNumEndpoints = 2,
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_MIDISTREAMING,
/* .iInterface = DYNAMIC */
};
/* B.4.2 Class-Specific MS Interface Descriptor */
static struct usb_ms_header_descriptor ms_header_desc = {
.bLength = USB_DT_MS_HEADER_SIZE,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = USB_MS_HEADER,
.bcdMSC = cpu_to_le16(0x0100),
/* .wTotalLength = DYNAMIC */
};
/* B.5.1 Standard Bulk OUT Endpoint Descriptor */
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/slab.h`, `linux/device.h`, `linux/kfifo.h`, `linux/spinlock.h`, `sound/core.h`, `sound/initval.h`.
- Detected declarations: `struct gmidi_in_port`, `struct f_midi`, `function f_midi_read_data`, `function f_midi_handle_out_data`, `function f_midi_complete`, `function f_midi_drop_out_substreams`, `function f_midi_start_ep`, `function f_midi_set_alt`, `function f_midi_disable`, `function f_midi_snd_free`.
- Atlas domain: Driver Families / drivers/usb.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.