sound/core/pcm_memory.c
Source file repositories/reference/linux-study-clean/sound/core/pcm_memory.c
File Facts
- System
- Linux kernel
- Corpus path
sound/core/pcm_memory.c- Extension
.c- Size
- 15438 bytes
- Lines
- 502
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/io.hlinux/time.hlinux/init.hlinux/slab.hlinux/moduleparam.hlinux/export.hsound/core.hsound/pcm.hsound/info.hsound/initval.hpcm_local.h
Detected Declarations
function __update_allocated_sizefunction update_allocated_sizefunction decrease_allocated_sizefunction do_alloc_pagesfunction do_free_pagesfunction preallocate_pcm_pagesfunction snd_pcm_lib_preallocate_freefunction snd_pcm_lib_preallocate_free_for_allfunction snd_pcm_lib_preallocate_proc_readfunction snd_pcm_lib_preallocate_max_proc_readfunction snd_pcm_lib_preallocate_proc_writefunction preallocate_info_initfunction preallocate_info_initfunction preallocate_pages_for_allfunction for_each_pcm_substreamfunction snd_pcm_lib_preallocate_pagesfunction snd_pcm_lib_preallocate_pages_for_allfunction snd_pcm_set_managed_bufferfunction snd_pcm_set_managed_buffer_allfunction snd_pcm_lib_preallocate_xxx_pagesfunction snd_pcm_lib_malloc_pagesexport snd_pcm_lib_preallocate_free_for_allexport snd_pcm_lib_preallocate_pagesexport snd_pcm_lib_preallocate_pages_for_allexport snd_pcm_set_managed_bufferexport snd_pcm_set_managed_buffer_allexport snd_pcm_lib_malloc_pagesexport snd_pcm_lib_free_pages
Annotated Snippet
if ((size != 0 && size < 8192) || size > substream->dma_max) {
buffer->error = -EINVAL;
return;
}
if (substream->dma_buffer.bytes == size)
return;
memset(&new_dmab, 0, sizeof(new_dmab));
new_dmab.dev = substream->dma_buffer.dev;
if (size > 0) {
if (do_alloc_pages(card,
substream->dma_buffer.dev.type,
substream->dma_buffer.dev.dev,
substream->stream,
size, &new_dmab) < 0) {
buffer->error = -ENOMEM;
pr_debug("ALSA pcmC%dD%d%c,%d:%s: cannot preallocate for size %lu\n",
substream->pcm->card->number, substream->pcm->device,
substream->stream ? 'c' : 'p', substream->number,
substream->pcm->name, size);
return;
}
substream->buffer_bytes_max = size;
} else {
substream->buffer_bytes_max = UINT_MAX;
}
if (substream->dma_buffer.area)
do_free_pages(card, &substream->dma_buffer);
substream->dma_buffer = new_dmab;
} else {
buffer->error = -EINVAL;
}
}
static inline void preallocate_info_init(struct snd_pcm_substream *substream)
{
struct snd_info_entry *entry;
entry = snd_info_create_card_entry(substream->pcm->card, "prealloc",
substream->proc_root);
if (entry) {
snd_info_set_text_ops(entry, substream,
snd_pcm_lib_preallocate_proc_read);
entry->c.text.write = snd_pcm_lib_preallocate_proc_write;
entry->mode |= 0200;
}
entry = snd_info_create_card_entry(substream->pcm->card, "prealloc_max",
substream->proc_root);
if (entry)
snd_info_set_text_ops(entry, substream,
snd_pcm_lib_preallocate_max_proc_read);
}
#else /* !CONFIG_SND_VERBOSE_PROCFS */
static inline void preallocate_info_init(struct snd_pcm_substream *substream)
{
}
#endif /* CONFIG_SND_VERBOSE_PROCFS */
/*
* pre-allocate the buffer and create a proc file for the substream
*/
static int preallocate_pages(struct snd_pcm_substream *substream,
int type, struct device *data,
size_t size, size_t max, bool managed)
{
int err;
if (snd_BUG_ON(substream->dma_buffer.dev.type))
return -EINVAL;
substream->dma_buffer.dev.type = type;
substream->dma_buffer.dev.dev = data;
if (size > 0) {
if (!max) {
/* no fallback, only also inform -ENOMEM */
err = preallocate_pcm_pages(substream, size, true);
if (err < 0)
return err;
} else if (preallocate_dma &&
substream->number < maximum_substreams) {
err = preallocate_pcm_pages(substream, size, false);
if (err < 0 && err != -ENOMEM)
return err;
}
}
if (substream->dma_buffer.bytes > 0)
substream->buffer_bytes_max = substream->dma_buffer.bytes;
substream->dma_max = max;
Annotation
- Immediate include surface: `linux/io.h`, `linux/time.h`, `linux/init.h`, `linux/slab.h`, `linux/moduleparam.h`, `linux/export.h`, `sound/core.h`, `sound/pcm.h`.
- Detected declarations: `function __update_allocated_size`, `function update_allocated_size`, `function decrease_allocated_size`, `function do_alloc_pages`, `function do_free_pages`, `function preallocate_pcm_pages`, `function snd_pcm_lib_preallocate_free`, `function snd_pcm_lib_preallocate_free_for_all`, `function snd_pcm_lib_preallocate_proc_read`, `function snd_pcm_lib_preallocate_max_proc_read`.
- Atlas domain: Driver Families / sound/core.
- Implementation status: integration implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.