sound/core/seq/oss/seq_oss_midi.c
Source file repositories/reference/linux-study-clean/sound/core/seq/oss/seq_oss_midi.c
File Facts
- System
- Linux kernel
- Corpus path
sound/core/seq/oss/seq_oss_midi.c- Extension
.c- Size
- 15409 bytes
- Lines
- 673
- Domain
- Driver Families
- Bucket
- sound/core
- 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.
- 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/asoundef.hseq_oss_midi.hseq_oss_readq.hseq_oss_timer.hseq_oss_event.hsound/seq_midi_event.h../seq_lock.hlinux/init.hlinux/slab.hlinux/nospec.h
Detected Declarations
struct seq_oss_midifunction snd_seq_oss_midi_lookup_portsfunction get_mdevfunction find_slotfunction snd_seq_oss_midi_check_new_portfunction snd_seq_oss_midi_check_exit_portfunction scoped_guardfunction snd_seq_oss_midi_clear_allfunction snd_seq_oss_midi_setupfunction snd_seq_oss_midi_cleanupfunction snd_seq_oss_midi_open_allfunction get_mididevfunction snd_seq_oss_midi_openfunction snd_seq_oss_midi_closefunction snd_seq_oss_midi_filemodefunction snd_seq_oss_midi_resetfunction snd_seq_oss_midi_get_addrfunction snd_seq_oss_midi_inputfunction send_synth_eventfunction send_midi_eventfunction snd_seq_oss_midi_putcfunction snd_seq_oss_midi_make_infofunction capmode_strfunction snd_seq_oss_midi_info_read
Annotated Snippet
struct seq_oss_midi {
int seq_device; /* device number */
int client; /* sequencer client number */
int port; /* sequencer port number */
unsigned int flags; /* port capability */
int opened; /* flag for opening */
unsigned char name[SNDRV_SEQ_OSS_MAX_MIDI_NAME];
struct snd_midi_event *coder; /* MIDI event coder */
struct seq_oss_devinfo *devinfo; /* assigned OSSseq device */
snd_use_lock_t use_lock;
struct mutex open_mutex;
};
DEFINE_FREE(seq_oss_midi, struct seq_oss_midi *, if (!IS_ERR_OR_NULL(_T)) snd_use_lock_free(&(_T)->use_lock))
/*
* midi device table
*/
static int max_midi_devs;
static struct seq_oss_midi *midi_devs[SNDRV_SEQ_OSS_MAX_MIDI_DEVS];
static DEFINE_SPINLOCK(register_lock);
/*
* prototypes
*/
static struct seq_oss_midi *get_mdev(int dev);
static struct seq_oss_midi *get_mididev(struct seq_oss_devinfo *dp, int dev);
static int send_synth_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int dev);
static int send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq_oss_midi *mdev);
/*
* look up the existing ports
* this looks a very exhausting job.
*/
int
snd_seq_oss_midi_lookup_ports(int client)
{
struct snd_seq_client_info *clinfo __free(kfree) =
kzalloc_obj(*clinfo);
struct snd_seq_port_info *pinfo __free(kfree) =
kzalloc_obj(*pinfo);
if (!clinfo || !pinfo)
return -ENOMEM;
clinfo->client = -1;
while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, clinfo) == 0) {
if (clinfo->client == client)
continue; /* ignore myself */
pinfo->addr.client = clinfo->client;
pinfo->addr.port = -1;
while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, pinfo) == 0)
snd_seq_oss_midi_check_new_port(pinfo);
}
return 0;
}
/*
*/
static struct seq_oss_midi *
get_mdev(int dev)
{
struct seq_oss_midi *mdev;
guard(spinlock_irqsave)(®ister_lock);
mdev = midi_devs[dev];
if (mdev)
snd_use_lock_use(&mdev->use_lock);
return mdev;
}
/*
* look for the identical slot
*/
static struct seq_oss_midi *
find_slot(int client, int port)
{
int i;
struct seq_oss_midi *mdev;
guard(spinlock_irqsave)(®ister_lock);
for (i = 0; i < max_midi_devs; i++) {
mdev = midi_devs[i];
if (mdev && mdev->client == client && mdev->port == port) {
/* found! */
snd_use_lock_use(&mdev->use_lock);
return mdev;
}
}
Annotation
- Immediate include surface: `sound/asoundef.h`, `seq_oss_midi.h`, `seq_oss_readq.h`, `seq_oss_timer.h`, `seq_oss_event.h`, `sound/seq_midi_event.h`, `../seq_lock.h`, `linux/init.h`.
- Detected declarations: `struct seq_oss_midi`, `function snd_seq_oss_midi_lookup_ports`, `function get_mdev`, `function find_slot`, `function snd_seq_oss_midi_check_new_port`, `function snd_seq_oss_midi_check_exit_port`, `function scoped_guard`, `function snd_seq_oss_midi_clear_all`, `function snd_seq_oss_midi_setup`, `function snd_seq_oss_midi_cleanup`.
- Atlas domain: Driver Families / sound/core.
- Implementation status: source implementation candidate.
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.