sound/core/control.c
Source file repositories/reference/linux-study-clean/sound/core/control.c
File Facts
- System
- Linux kernel
- Corpus path
sound/core/control.c- Extension
.c- Size
- 68331 bytes
- Lines
- 2531
- 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
linux/threads.hlinux/interrupt.hlinux/module.hlinux/moduleparam.hlinux/slab.hlinux/vmalloc.hlinux/time.hlinux/mm.hlinux/math64.hlinux/sched/signal.hsound/core.hsound/minors.hsound/info.hsound/control.hcontrol_trace.hcontrol_compat.c
Detected Declarations
struct snd_kctl_ioctlstruct user_elementenum snd_ctl_add_modefunction snd_ctl_openfunction snd_ctl_empty_read_queuefunction snd_ctl_releasefunction scoped_guardfunction snd_ctl_notifyfunction scoped_guardfunction snd_ctl_notifyfunction numberfunction snd_ctl_newfunction snd_ctl_remove_numid_conflictfunction list_for_each_entryfunction snd_ctl_find_holefunction elem_id_matchesfunction get_ctl_id_hashfunction add_hash_entriesfunction remove_hash_entriesfunction add_hash_entriesfunction __snd_ctl_add_replacefunction scoped_guardfunction snd_ctl_add_replacefunction snd_ctl_newfunction snd_ctl_replacefunction __snd_ctl_removefunction scoped_guardfunction snd_ctl_remove_lockedfunction snd_ctl_removefunction snd_ctl_remove_idfunction snd_ctl_remove_user_ctlfunction snd_ctl_activate_idfunction snd_ctl_rename_idfunction snd_ctl_renamefunction snd_ctl_find_numid_slowfunction snd_ctl_card_infofunction snd_ctl_elem_listfunction snd_ctl_elem_list_userfunction snd_ctl_check_elem_infofunction fill_remaining_elem_valuefunction sanity_check_int_valuefunction sanity_check_input_valuesfunction sanity_check_elem_valuefunction __snd_ctl_elem_infofunction snd_ctl_elem_infofunction snd_ctl_elem_info_userfunction snd_ctl_elem_readfunction sanity_check_elem_value
Annotated Snippet
static const struct file_operations snd_ctl_f_ops =
{
.owner = THIS_MODULE,
.read = snd_ctl_read,
.open = snd_ctl_open,
.release = snd_ctl_release,
.poll = snd_ctl_poll,
.unlocked_ioctl = snd_ctl_ioctl,
.compat_ioctl = snd_ctl_ioctl_compat,
.fasync = snd_ctl_fasync,
};
/* call lops under rwsems; called from snd_ctl_dev_*() below() */
#define call_snd_ctl_lops(_card, _op) \
do { \
struct snd_ctl_layer_ops *lops; \
guard(rwsem_read)(&(_card)->controls_rwsem); \
guard(rwsem_read)(&snd_ctl_layer_rwsem); \
for (lops = snd_ctl_layer; lops; lops = lops->next) \
lops->_op(_card); \
} while (0)
/*
* registration of the control device
*/
static int snd_ctl_dev_register(struct snd_device *device)
{
struct snd_card *card = device->device_data;
int err;
err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1,
&snd_ctl_f_ops, card, card->ctl_dev);
if (err < 0)
return err;
call_snd_ctl_lops(card, lregister);
return 0;
}
/*
* disconnection of the control device
*/
static int snd_ctl_dev_disconnect(struct snd_device *device)
{
struct snd_card *card = device->device_data;
struct snd_ctl_file *ctl;
scoped_guard(read_lock_irqsave, &card->controls_rwlock) {
list_for_each_entry(ctl, &card->ctl_files, list) {
wake_up(&ctl->change_sleep);
snd_kill_fasync(ctl->fasync, SIGIO, POLL_ERR);
}
}
call_snd_ctl_lops(card, ldisconnect);
return snd_unregister_device(card->ctl_dev);
}
/*
* free all controls
*/
static int snd_ctl_dev_free(struct snd_device *device)
{
struct snd_card *card = device->device_data;
struct snd_kcontrol *control;
scoped_guard(rwsem_write, &card->controls_rwsem) {
while (!list_empty(&card->controls)) {
control = snd_kcontrol(card->controls.next);
__snd_ctl_remove(card, control, false);
}
#ifdef CONFIG_SND_CTL_FAST_LOOKUP
xa_destroy(&card->ctl_numids);
xa_destroy(&card->ctl_hash);
#endif
}
put_device(card->ctl_dev);
return 0;
}
/*
* create control core:
* called from init.c
*/
int snd_ctl_create(struct snd_card *card)
{
static const struct snd_device_ops ops = {
.dev_free = snd_ctl_dev_free,
.dev_register = snd_ctl_dev_register,
.dev_disconnect = snd_ctl_dev_disconnect,
Annotation
- Immediate include surface: `linux/threads.h`, `linux/interrupt.h`, `linux/module.h`, `linux/moduleparam.h`, `linux/slab.h`, `linux/vmalloc.h`, `linux/time.h`, `linux/mm.h`.
- Detected declarations: `struct snd_kctl_ioctl`, `struct user_element`, `enum snd_ctl_add_mode`, `function snd_ctl_open`, `function snd_ctl_empty_read_queue`, `function snd_ctl_release`, `function scoped_guard`, `function snd_ctl_notify`, `function scoped_guard`, `function snd_ctl_notify`.
- 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.