sound/usb/line6/midi.c
Source file repositories/reference/linux-study-clean/sound/usb/line6/midi.c
File Facts
- System
- Linux kernel
- Corpus path
sound/usb/line6/midi.c- Extension
.c- Size
- 6799 bytes
- Lines
- 290
- Domain
- Driver Families
- Bucket
- sound/usb
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/slab.hlinux/usb.hlinux/export.hsound/core.hsound/rawmidi.hdriver.hmidi.h
Detected Declarations
function line6_midi_receivefunction line6_midi_transmitfunction midi_sentfunction send_midi_asyncfunction line6_midi_output_openfunction line6_midi_output_closefunction line6_midi_output_triggerfunction line6_midi_output_drainfunction line6_midi_input_openfunction line6_midi_input_closefunction line6_midi_input_triggerfunction snd_line6_new_midifunction snd_line6_midi_freefunction line6_init_midiexport line6_init_midi
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0-only
/*
* Line 6 Linux USB driver
*
* Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
*/
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/export.h>
#include <sound/core.h>
#include <sound/rawmidi.h>
#include "driver.h"
#include "midi.h"
#define line6_rawmidi_substream_midi(substream) \
((struct snd_line6_midi *)((substream)->rmidi->private_data))
static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
int length);
/*
Pass data received via USB to MIDI.
*/
void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
int length)
{
if (line6->line6midi->substream_receive)
snd_rawmidi_receive(line6->line6midi->substream_receive,
data, length);
}
/*
Read data from MIDI buffer and transmit them via USB.
*/
static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
{
struct usb_line6 *line6 =
line6_rawmidi_substream_midi(substream)->line6;
struct snd_line6_midi *line6midi = line6->line6midi;
struct midi_buffer *mb = &line6midi->midibuf_out;
unsigned char chunk[LINE6_FALLBACK_MAXPACKETSIZE];
int req, done;
for (;;) {
req = min3(line6_midibuf_bytes_free(mb), line6->max_packet_size,
LINE6_FALLBACK_MAXPACKETSIZE);
done = snd_rawmidi_transmit_peek(substream, chunk, req);
if (done == 0)
break;
line6_midibuf_write(mb, chunk, done);
snd_rawmidi_transmit_ack(substream, done);
}
for (;;) {
done = line6_midibuf_read(mb, chunk,
LINE6_FALLBACK_MAXPACKETSIZE,
LINE6_MIDIBUF_READ_TX);
if (done == 0)
break;
send_midi_async(line6, chunk, done);
}
}
/*
Notification of completion of MIDI transmission.
*/
static void midi_sent(struct urb *urb)
{
int status;
int num;
struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
status = urb->status;
kfree(urb->transfer_buffer);
usb_free_urb(urb);
if (status == -ESHUTDOWN)
return;
guard(spinlock_irqsave)(&line6->line6midi->lock);
num = --line6->line6midi->num_active_send_urbs;
if (num == 0) {
line6_midi_transmit(line6->line6midi->substream_transmit);
Annotation
- Immediate include surface: `linux/slab.h`, `linux/usb.h`, `linux/export.h`, `sound/core.h`, `sound/rawmidi.h`, `driver.h`, `midi.h`.
- Detected declarations: `function line6_midi_receive`, `function line6_midi_transmit`, `function midi_sent`, `function send_midi_async`, `function line6_midi_output_open`, `function line6_midi_output_close`, `function line6_midi_output_trigger`, `function line6_midi_output_drain`, `function line6_midi_input_open`, `function line6_midi_input_close`.
- Atlas domain: Driver Families / sound/usb.
- Implementation status: integration 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.