sound/core/init.c
Source file repositories/reference/linux-study-clean/sound/core/init.c
File Facts
- System
- Linux kernel
- Corpus path
sound/core/init.c- Extension
.c- Size
- 31225 bytes
- Lines
- 1182
- 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.
- 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/sched.hlinux/module.hlinux/device.hlinux/file.hlinux/slab.hlinux/time.hlinux/ctype.hlinux/pm.hlinux/debugfs.hlinux/completion.hlinux/interrupt.hsound/core.hsound/control.hsound/info.h
Detected Declarations
struct snd_monitor_filefunction module_slot_matchfunction check_empty_slotfunction get_slot_from_bitmaskfunction default_release_allocfunction snd_device_allocfunction release_card_devicefunction snd_card_newfunction __snd_card_releasefunction snd_devm_card_newfunction snd_card_freefunction snd_card_initfunction snd_card_unreffunction snd_card_lockedfunction snd_disconnect_llseekfunction snd_disconnect_readfunction snd_disconnect_writefunction snd_disconnect_releasefunction scoped_guardfunction snd_disconnect_pollfunction snd_disconnect_ioctlfunction snd_disconnect_mmapfunction snd_disconnect_fasyncfunction operationsfunction scoped_guardfunction list_for_each_entryfunction snd_card_disconnectfunction snd_card_do_freefunction snd_card_freefunction snd_card_freefunction safe_ascii_charfunction card_id_okfunction copy_valid_id_stringfunction snd_card_set_id_no_lockfunction snd_card_set_idfunction id_showfunction id_storefunction number_showfunction snd_card_add_dev_attrfunction trigger_card_freefunction snd_card_registerfunction snd_card_info_readfunction snd_card_info_read_ossfunction snd_card_module_info_readfunction snd_card_info_initfunction snd_component_addfunction snd_card_file_addfunction snd_card_file_add
Annotated Snippet
const struct file_operations *disconnected_f_op;
struct list_head shutdown_list; /* still need to shutdown */
struct list_head list; /* link of monitor files */
};
static DEFINE_SPINLOCK(shutdown_lock);
static LIST_HEAD(shutdown_files);
static const struct file_operations snd_shutdown_f_ops;
/* locked for registering/using */
static DECLARE_BITMAP(snd_cards_lock, SNDRV_CARDS);
static struct snd_card *snd_cards[SNDRV_CARDS];
static DEFINE_MUTEX(snd_card_mutex);
static char *slots[SNDRV_CARDS];
module_param_array(slots, charp, NULL, 0444);
MODULE_PARM_DESC(slots, "Module names assigned to the slots.");
/* return non-zero if the given index is reserved for the given
* module via slots option
*/
static int module_slot_match(struct module *module, int idx)
{
int match = 1;
#ifdef CONFIG_MODULES
const char *s1, *s2;
if (!module || !*module->name || !slots[idx])
return 0;
s1 = module->name;
s2 = slots[idx];
if (*s2 == '!') {
match = 0; /* negative match */
s2++;
}
/* compare module name strings
* hyphens are handled as equivalent with underscore
*/
for (;;) {
char c1 = *s1++;
char c2 = *s2++;
if (c1 == '-')
c1 = '_';
if (c2 == '-')
c2 = '_';
if (c1 != c2)
return !match;
if (!c1)
break;
}
#endif /* CONFIG_MODULES */
return match;
}
#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag);
EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
#endif
static int check_empty_slot(struct module *module, int slot)
{
return !slots[slot] || !*slots[slot];
}
/* return an empty slot number (>= 0) found in the given bitmask @mask.
* @mask == -1 == 0xffffffff means: take any free slot up to 32
* when no slot is available, return the original @mask as is.
*/
static int get_slot_from_bitmask(int mask, int (*check)(struct module *, int),
struct module *module)
{
int slot;
for (slot = 0; slot < SNDRV_CARDS; slot++) {
if (slot < 32 && !(mask & (1U << slot)))
continue;
if (!test_bit(slot, snd_cards_lock)) {
if (check(module, slot))
return slot; /* found */
}
}
return mask; /* unchanged */
}
/* the default release callback set in snd_device_alloc() */
static void default_release_alloc(struct device *dev)
{
Annotation
- Immediate include surface: `linux/init.h`, `linux/sched.h`, `linux/module.h`, `linux/device.h`, `linux/file.h`, `linux/slab.h`, `linux/time.h`, `linux/ctype.h`.
- Detected declarations: `struct snd_monitor_file`, `function module_slot_match`, `function check_empty_slot`, `function get_slot_from_bitmask`, `function default_release_alloc`, `function snd_device_alloc`, `function release_card_device`, `function snd_card_new`, `function __snd_card_release`, `function snd_devm_card_new`.
- Atlas domain: Driver Families / sound/core.
- Implementation status: pattern 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.