sound/core/rawmidi.c
Source file repositories/reference/linux-study-clean/sound/core/rawmidi.c
File Facts
- System
- Linux kernel
- Corpus path
sound/core/rawmidi.c- Extension
.c- Size
- 59616 bytes
- Lines
- 2137
- Domain
- Driver Families
- Bucket
- sound/core
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/core.hlinux/major.hlinux/init.hlinux/sched/signal.hlinux/slab.hlinux/time.hlinux/wait.hlinux/mutex.hlinux/module.hlinux/delay.hlinux/mm.hlinux/nospec.hsound/rawmidi.hsound/info.hsound/control.hsound/minors.hsound/initval.hsound/ump.hrawmidi_compat.c
Detected Declarations
struct snd_rawmidi_status32struct snd_rawmidi_status64function snd_rawmidi_file_flagsfunction __snd_rawmidi_readyfunction snd_rawmidi_readyfunction snd_rawmidi_ready_appendfunction snd_rawmidi_input_event_workfunction snd_rawmidi_buffer_reffunction snd_rawmidi_buffer_unreffunction snd_rawmidi_buffer_ref_syncfunction snd_rawmidi_runtime_createfunction get_alignfunction snd_rawmidi_runtime_freefunction snd_rawmidi_output_triggerfunction snd_rawmidi_input_triggerfunction __reset_runtime_ptrsfunction reset_runtime_ptrsfunction snd_rawmidi_drop_outputfunction snd_rawmidi_drain_outputfunction scoped_guardfunction scoped_guardfunction snd_rawmidi_drain_inputfunction assign_substreamfunction list_for_each_entryfunction open_substreamfunction rawmidi_open_privfunction snd_rawmidi_kernel_openfunction snd_rawmidi_openfunction close_substreamfunction rawmidi_release_privfunction snd_rawmidi_kernel_releasefunction snd_rawmidi_releasefunction snd_rawmidi_infofunction snd_rawmidi_info_userfunction __snd_rawmidi_info_selectfunction snd_rawmidi_info_selectfunction snd_rawmidi_info_select_userfunction resize_runtime_bufferfunction snd_rawmidi_output_paramsfunction snd_rawmidi_input_paramsfunction snd_rawmidi_output_statusfunction snd_rawmidi_input_statusfunction snd_rawmidi_ioctl_status32function snd_rawmidi_ioctl_status64function snd_rawmidi_ioctlfunction snd_rawmidi_next_devicefunction snd_rawmidi_call_ump_ioctlfunction snd_rawmidi_control_ioctl
Annotated Snippet
static const struct file_operations snd_rawmidi_f_ops = {
.owner = THIS_MODULE,
.read = snd_rawmidi_read,
.write = snd_rawmidi_write,
.open = snd_rawmidi_open,
.release = snd_rawmidi_release,
.poll = snd_rawmidi_poll,
.unlocked_ioctl = snd_rawmidi_ioctl,
.compat_ioctl = snd_rawmidi_ioctl_compat,
};
static int snd_rawmidi_alloc_substreams(struct snd_rawmidi *rmidi,
struct snd_rawmidi_str *stream,
int direction,
int count)
{
struct snd_rawmidi_substream *substream;
int idx;
for (idx = 0; idx < count; idx++) {
substream = kzalloc_obj(*substream);
if (!substream)
return -ENOMEM;
substream->stream = direction;
substream->number = idx;
substream->rmidi = rmidi;
substream->pstr = stream;
spin_lock_init(&substream->lock);
list_add_tail(&substream->list, &stream->substreams);
stream->substream_count++;
}
return 0;
}
/* used for both rawmidi and ump */
int snd_rawmidi_init(struct snd_rawmidi *rmidi,
struct snd_card *card, char *id, int device,
int output_count, int input_count,
unsigned int info_flags)
{
int err;
static const struct snd_device_ops ops = {
.dev_free = snd_rawmidi_dev_free,
.dev_register = snd_rawmidi_dev_register,
.dev_disconnect = snd_rawmidi_dev_disconnect,
};
rmidi->card = card;
rmidi->device = device;
mutex_init(&rmidi->open_mutex);
init_waitqueue_head(&rmidi->open_wait);
INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams);
INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams);
rmidi->info_flags = info_flags;
if (id != NULL)
strscpy(rmidi->id, id, sizeof(rmidi->id));
err = snd_device_alloc(&rmidi->dev, card);
if (err < 0)
return err;
if (rawmidi_is_ump(rmidi))
dev_set_name(rmidi->dev, "umpC%iD%i", card->number, device);
else
dev_set_name(rmidi->dev, "midiC%iD%i", card->number, device);
err = snd_rawmidi_alloc_substreams(rmidi,
&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT],
SNDRV_RAWMIDI_STREAM_INPUT,
input_count);
if (err < 0)
return err;
err = snd_rawmidi_alloc_substreams(rmidi,
&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT],
SNDRV_RAWMIDI_STREAM_OUTPUT,
output_count);
if (err < 0)
return err;
err = snd_device_new(card, SNDRV_DEV_RAWMIDI, rmidi, &ops);
if (err < 0)
return err;
return 0;
}
EXPORT_SYMBOL_GPL(snd_rawmidi_init);
/**
* snd_rawmidi_new - create a rawmidi instance
* @card: the card instance
* @id: the id string
* @device: the device index
Annotation
- Immediate include surface: `sound/core.h`, `linux/major.h`, `linux/init.h`, `linux/sched/signal.h`, `linux/slab.h`, `linux/time.h`, `linux/wait.h`, `linux/mutex.h`.
- Detected declarations: `struct snd_rawmidi_status32`, `struct snd_rawmidi_status64`, `function snd_rawmidi_file_flags`, `function __snd_rawmidi_ready`, `function snd_rawmidi_ready`, `function snd_rawmidi_ready_append`, `function snd_rawmidi_input_event_work`, `function snd_rawmidi_buffer_ref`, `function snd_rawmidi_buffer_unref`, `function snd_rawmidi_buffer_ref_sync`.
- Atlas domain: Driver Families / sound/core.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.