sound/core/misc.c
Source file repositories/reference/linux-study-clean/sound/core/misc.c
File Facts
- System
- Linux kernel
- Corpus path
sound/core/misc.c- Extension
.c- Size
- 4830 bytes
- Lines
- 201
- Domain
- Driver Families
- Bucket
- sound/core
- 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/init.hlinux/export.hlinux/moduleparam.hlinux/time.hlinux/slab.hlinux/ioport.hlinux/fs.hsound/core.hlinux/pci.h
Detected Declarations
struct snd_fasyncfunction Copyrightfunction snd_pci_quirk_lookup_idfunction snd_pci_quirk_lookupfunction snd_fasync_work_fnfunction snd_fasync_helperfunction scoped_guardfunction snd_kill_fasyncfunction snd_fasync_freefunction scoped_guardfunction snd_refcount_initfunction snd_refcount_putfunction snd_refcount_syncexport release_and_free_resourceexport snd_pci_quirk_lookup_idexport snd_pci_quirk_lookupexport snd_fasync_helperexport snd_kill_fasyncexport snd_fasync_freeexport snd_refcount_initexport snd_refcount_putexport snd_refcount_sync
Annotated Snippet
struct snd_fasync {
struct fasync_struct *fasync;
int signal;
int poll;
int on;
struct list_head list;
};
static DEFINE_SPINLOCK(snd_fasync_lock);
static LIST_HEAD(snd_fasync_list);
static void snd_fasync_work_fn(struct work_struct *work)
{
struct snd_fasync *fasync;
int signal, poll;
spin_lock_irq(&snd_fasync_lock);
while (!list_empty(&snd_fasync_list)) {
fasync = list_first_entry(&snd_fasync_list, struct snd_fasync, list);
list_del_init(&fasync->list);
if (!fasync->on)
continue;
signal = fasync->signal;
poll = fasync->poll;
spin_unlock_irq(&snd_fasync_lock);
kill_fasync(&fasync->fasync, signal, poll);
spin_lock_irq(&snd_fasync_lock);
}
spin_unlock_irq(&snd_fasync_lock);
}
static DECLARE_WORK(snd_fasync_work, snd_fasync_work_fn);
int snd_fasync_helper(int fd, struct file *file, int on,
struct snd_fasync **fasyncp)
{
struct snd_fasync *fasync = NULL;
if (on) {
fasync = kzalloc(sizeof(*fasync), GFP_KERNEL);
if (!fasync)
return -ENOMEM;
INIT_LIST_HEAD(&fasync->list);
}
scoped_guard(spinlock_irq, &snd_fasync_lock) {
if (*fasyncp) {
kfree(fasync);
fasync = *fasyncp;
} else {
if (!fasync)
return 0;
*fasyncp = fasync;
}
fasync->on = on;
}
return fasync_helper(fd, file, on, &fasync->fasync);
}
EXPORT_SYMBOL_GPL(snd_fasync_helper);
void snd_kill_fasync(struct snd_fasync *fasync, int signal, int poll)
{
if (!fasync)
return;
guard(spinlock_irqsave)(&snd_fasync_lock);
if (!fasync->on)
return;
fasync->signal = signal;
fasync->poll = poll;
list_move(&fasync->list, &snd_fasync_list);
schedule_work(&snd_fasync_work);
}
EXPORT_SYMBOL_GPL(snd_kill_fasync);
void snd_fasync_free(struct snd_fasync *fasync)
{
if (!fasync)
return;
scoped_guard(spinlock_irq, &snd_fasync_lock) {
fasync->on = 0;
list_del_init(&fasync->list);
}
flush_work(&snd_fasync_work);
kfree(fasync);
}
EXPORT_SYMBOL_GPL(snd_fasync_free);
/*
Annotation
- Immediate include surface: `linux/init.h`, `linux/export.h`, `linux/moduleparam.h`, `linux/time.h`, `linux/slab.h`, `linux/ioport.h`, `linux/fs.h`, `sound/core.h`.
- Detected declarations: `struct snd_fasync`, `function Copyright`, `function snd_pci_quirk_lookup_id`, `function snd_pci_quirk_lookup`, `function snd_fasync_work_fn`, `function snd_fasync_helper`, `function scoped_guard`, `function snd_kill_fasync`, `function snd_fasync_free`, `function scoped_guard`.
- Atlas domain: Driver Families / sound/core.
- 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.