sound/usb/midi2.c
Source file repositories/reference/linux-study-clean/sound/usb/midi2.c
File Facts
- System
- Linux kernel
- Corpus path
sound/usb/midi2.c- Extension
.c- Size
- 33450 bytes
- Lines
- 1235
- Domain
- Driver Families
- Bucket
- sound/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/bitops.hlinux/string.hlinux/init.hlinux/slab.hlinux/usb.hlinux/wait.hlinux/module.hlinux/moduleparam.hlinux/usb/audio.hlinux/usb/midi.hlinux/usb/midi-v2.hsound/core.hsound/control.hsound/ump.husbaudio.hmidi.hmidi2.hhelper.h
Detected Declarations
struct snd_usb_midi2_urbstruct snd_usb_midi2_endpointstruct snd_usb_midi2_umpstruct snd_usb_midi2_interfacestruct snd_usb_midi2_urbstruct snd_usb_midi2_endpointstruct snd_usb_midi2_umpstruct snd_usb_midi2_interfacefunction do_submit_urbs_lockedfunction prepare_output_urbfunction submit_output_urbs_lockedfunction output_urb_completefunction prepare_input_urbfunction submit_input_urbs_lockedfunction input_urb_completefunction submit_io_urbsfunction kill_midi_urbsfunction drain_urb_queuefunction free_midi_urbsfunction alloc_midi_urbsfunction ump_to_endpointfunction snd_usb_midi_v2_openfunction snd_usb_midi_v2_closefunction snd_usb_midi_v2_triggerfunction snd_usb_midi_v2_drainfunction start_input_streamsfunction list_for_each_entryfunction list_for_each_entryfunction create_midi2_endpointfunction free_midi2_endpointfunction free_all_midi2_endpointsfunction get_group_terminal_block_descsfunction find_group_terminal_blockfunction parse_group_terminal_blockfunction parse_group_terminal_blocksfunction list_for_each_entryfunction parse_midi_2_0_endpointsfunction free_all_midi2_umpsfunction create_midi2_umpfunction find_midi2_umpfunction list_for_each_entryfunction find_matching_ep_partnerfunction parse_ump_endpointsfunction list_for_each_entryfunction create_gtb_blockfunction create_blocks_from_gtbfunction list_for_each_entryfunction attach_legacy_rawmidi
Annotated Snippet
struct snd_usb_midi2_urb {
struct urb *urb;
struct snd_usb_midi2_endpoint *ep;
unsigned int index; /* array index */
};
/* A USB MIDI input/output endpoint */
struct snd_usb_midi2_endpoint {
struct usb_device *dev;
const struct usb_ms20_endpoint_descriptor *ms_ep; /* reference to EP descriptor */
struct snd_usb_midi2_endpoint *pair; /* bidirectional pair EP */
struct snd_usb_midi2_ump *rmidi; /* assigned UMP EP pair */
struct snd_ump_endpoint *ump; /* assigned UMP EP */
int direction; /* direction (STR_IN/OUT) */
unsigned int endpoint; /* EP number */
unsigned int pipe; /* URB pipe */
unsigned int packets; /* packet buffer size in bytes */
unsigned int interval; /* interval for INT EP */
wait_queue_head_t wait; /* URB waiter */
spinlock_t lock; /* URB locking */
struct snd_rawmidi_substream *substream; /* NULL when closed */
unsigned int num_urbs; /* number of allocated URBs */
unsigned long urb_free; /* bitmap for free URBs */
unsigned long urb_free_mask; /* bitmask for free URBs */
atomic_t running; /* running status */
atomic_t suspended; /* saved running status for suspend */
bool disconnected; /* shadow of umidi->disconnected */
struct list_head list; /* list to umidi->ep_list */
struct snd_usb_midi2_urb urbs[NUM_URBS];
};
/* A UMP endpoint - one or two USB MIDI endpoints are assigned */
struct snd_usb_midi2_ump {
struct usb_device *dev;
struct snd_usb_midi2_interface *umidi; /* reference to MIDI iface */
struct snd_ump_endpoint *ump; /* assigned UMP EP object */
struct snd_usb_midi2_endpoint *eps[2]; /* USB MIDI endpoints */
int index; /* rawmidi device index */
unsigned char usb_block_id; /* USB GTB id used for finding a pair */
bool ump_parsed; /* Parsed UMP 1.1 EP/FB info*/
struct list_head list; /* list to umidi->rawmidi_list */
};
/* top-level instance per USB MIDI interface */
struct snd_usb_midi2_interface {
struct snd_usb_audio *chip; /* assigned USB-audio card */
struct usb_interface *iface; /* assigned USB interface */
struct usb_host_interface *hostif;
const char *blk_descs; /* group terminal block descriptors */
unsigned int blk_desc_size; /* size of GTB descriptors */
bool disconnected;
struct list_head ep_list; /* list of endpoints */
struct list_head rawmidi_list; /* list of UMP rawmidis */
struct list_head list; /* list to chip->midi_v2_list */
};
/* submit URBs as much as possible; used for both input and output */
static void do_submit_urbs_locked(struct snd_usb_midi2_endpoint *ep,
int (*prepare)(struct snd_usb_midi2_endpoint *,
struct urb *))
{
struct snd_usb_midi2_urb *ctx;
int index, err = 0;
if (ep->disconnected)
return;
while (ep->urb_free) {
index = find_first_bit(&ep->urb_free, ep->num_urbs);
if (index >= ep->num_urbs)
return;
ctx = &ep->urbs[index];
err = prepare(ep, ctx->urb);
if (err < 0)
return;
if (!ctx->urb->transfer_buffer_length)
return;
ctx->urb->dev = ep->dev;
err = usb_submit_urb(ctx->urb, GFP_ATOMIC);
if (err < 0) {
dev_dbg(&ep->dev->dev,
"usb_submit_urb error %d\n", err);
return;
}
clear_bit(index, &ep->urb_free);
}
}
/* prepare for output submission: copy from rawmidi buffer to urb packet */
static int prepare_output_urb(struct snd_usb_midi2_endpoint *ep,
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/string.h`, `linux/init.h`, `linux/slab.h`, `linux/usb.h`, `linux/wait.h`, `linux/module.h`, `linux/moduleparam.h`.
- Detected declarations: `struct snd_usb_midi2_urb`, `struct snd_usb_midi2_endpoint`, `struct snd_usb_midi2_ump`, `struct snd_usb_midi2_interface`, `struct snd_usb_midi2_urb`, `struct snd_usb_midi2_endpoint`, `struct snd_usb_midi2_ump`, `struct snd_usb_midi2_interface`, `function do_submit_urbs_locked`, `function prepare_output_urb`.
- Atlas domain: Driver Families / sound/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.