sound/usb/6fire/midi.c
Source file repositories/reference/linux-study-clean/sound/usb/6fire/midi.c
File Facts
- System
- Linux kernel
- Corpus path
sound/usb/6fire/midi.c- Extension
.c- Size
- 4648 bytes
- Lines
- 203
- 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
sound/rawmidi.hmidi.hchip.hcomm.h
Detected Declarations
function usb6fire_midi_out_handlerfunction usb6fire_midi_in_receivedfunction usb6fire_midi_out_openfunction usb6fire_midi_out_closefunction usb6fire_midi_out_triggerfunction usb6fire_midi_out_drainfunction usb6fire_midi_in_openfunction usb6fire_midi_in_closefunction usb6fire_midi_in_triggerfunction usb6fire_midi_initfunction usb6fire_midi_abortfunction usb6fire_midi_destroy
Annotated Snippet
if (ret > 0) { /* more data available, send next packet */
rt->out_buffer[1] = ret + 2;
rt->out_buffer[3] = rt->out_serial++;
urb->transfer_buffer_length = ret + 4;
ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret < 0)
dev_err(&urb->dev->dev,
"midi out urb submit failed: %d\n",
ret);
} else /* no more data to transmit */
rt->out = NULL;
}
}
static void usb6fire_midi_in_received(
struct midi_runtime *rt, u8 *data, int length)
{
guard(spinlock_irqsave)(&rt->in_lock);
if (rt->in)
snd_rawmidi_receive(rt->in, data, length);
}
static int usb6fire_midi_out_open(struct snd_rawmidi_substream *alsa_sub)
{
return 0;
}
static int usb6fire_midi_out_close(struct snd_rawmidi_substream *alsa_sub)
{
return 0;
}
static void usb6fire_midi_out_trigger(
struct snd_rawmidi_substream *alsa_sub, int up)
{
struct midi_runtime *rt = alsa_sub->rmidi->private_data;
struct urb *urb = &rt->out_urb;
__s8 ret;
guard(spinlock_irqsave)(&rt->out_lock);
if (up) { /* start transfer */
if (rt->out) /* we are already transmitting so just return */
return;
ret = snd_rawmidi_transmit(alsa_sub, rt->out_buffer + 4,
MIDI_BUFSIZE - 4);
if (ret > 0) {
rt->out_buffer[1] = ret + 2;
rt->out_buffer[3] = rt->out_serial++;
urb->transfer_buffer_length = ret + 4;
ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret < 0)
dev_err(&urb->dev->dev,
"midi out urb submit failed: %d\n",
ret);
else
rt->out = alsa_sub;
}
} else if (rt->out == alsa_sub)
rt->out = NULL;
}
static void usb6fire_midi_out_drain(struct snd_rawmidi_substream *alsa_sub)
{
struct midi_runtime *rt = alsa_sub->rmidi->private_data;
int retry = 0;
while (rt->out && retry++ < 100)
msleep(10);
}
static int usb6fire_midi_in_open(struct snd_rawmidi_substream *alsa_sub)
{
return 0;
}
static int usb6fire_midi_in_close(struct snd_rawmidi_substream *alsa_sub)
{
return 0;
}
static void usb6fire_midi_in_trigger(
struct snd_rawmidi_substream *alsa_sub, int up)
{
struct midi_runtime *rt = alsa_sub->rmidi->private_data;
guard(spinlock_irqsave)(&rt->in_lock);
if (up)
Annotation
- Immediate include surface: `sound/rawmidi.h`, `midi.h`, `chip.h`, `comm.h`.
- Detected declarations: `function usb6fire_midi_out_handler`, `function usb6fire_midi_in_received`, `function usb6fire_midi_out_open`, `function usb6fire_midi_out_close`, `function usb6fire_midi_out_trigger`, `function usb6fire_midi_out_drain`, `function usb6fire_midi_in_open`, `function usb6fire_midi_in_close`, `function usb6fire_midi_in_trigger`, `function usb6fire_midi_init`.
- 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.