sound/pci/ctxfi/ctvmem.c
Source file repositories/reference/linux-study-clean/sound/pci/ctxfi/ctvmem.c
File Facts
- System
- Linux kernel
- Corpus path
sound/pci/ctxfi/ctvmem.c- Extension
.c- Size
- 5452 bytes
- Lines
- 239
- Domain
- Driver Families
- Bucket
- sound/pci
- 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.
- 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
ctvmem.hctatc.hlinux/slab.hlinux/mm.hlinux/io.hsound/pcm.h
Detected Declarations
function Copyrightfunction put_vm_blockfunction list_for_eachfunction ct_vm_mapfunction ct_vm_unmapfunction ct_get_ptp_physfunction ct_vm_createfunction ct_vm_destroy
Annotated Snippet
if ((block->addr + block->size) == entry->addr) {
entry->addr = block->addr;
entry->size += block->size;
kfree(block);
} else {
__list_add(&block->list, pos->prev, pos);
entry = block;
}
}
pos = &entry->list;
pre = pos->prev;
while (pre != &vm->unused) {
entry = list_entry(pos, struct ct_vm_block, list);
pre_ent = list_entry(pre, struct ct_vm_block, list);
if ((pre_ent->addr + pre_ent->size) > entry->addr)
break;
pre_ent->size += entry->size;
list_del(pos);
kfree(entry);
pos = pre;
pre = pos->prev;
}
}
/* Map host addr (kmalloced/vmalloced) to device logical addr. */
static struct ct_vm_block *
ct_vm_map(struct ct_vm *vm, struct snd_pcm_substream *substream, int size)
{
struct ct_vm_block *block;
unsigned int pte_start;
unsigned i, pages;
unsigned long *ptp;
struct ct_atc *atc = snd_pcm_substream_chip(substream);
block = get_vm_block(vm, size, atc);
if (block == NULL) {
dev_err(atc->card->dev,
"No virtual memory block that is big enough to allocate!\n");
return NULL;
}
ptp = (unsigned long *)vm->ptp[0].area;
pte_start = (block->addr >> CT_PAGE_SHIFT);
pages = block->size >> CT_PAGE_SHIFT;
for (i = 0; i < pages; i++) {
unsigned long addr;
addr = snd_pcm_sgbuf_get_addr(substream, i << CT_PAGE_SHIFT);
ptp[pte_start + i] = addr;
}
block->size = size;
return block;
}
static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block)
{
/* do unmapping */
put_vm_block(vm, block);
}
/* *
* return the host physical addr of the @index-th device
* page table page on success, or ~0UL on failure.
* The first returned ~0UL indicates the termination.
* */
static dma_addr_t
ct_get_ptp_phys(struct ct_vm *vm, int index)
{
return (index >= CT_PTP_NUM) ? ~0UL : vm->ptp[index].addr;
}
int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci)
{
struct ct_vm *vm;
struct ct_vm_block *block;
int i, err = 0;
*rvm = NULL;
vm = kzalloc_obj(*vm);
if (!vm)
return -ENOMEM;
mutex_init(&vm->lock);
/* Allocate page table pages */
for (i = 0; i < CT_PTP_NUM; i++) {
err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
Annotation
- Immediate include surface: `ctvmem.h`, `ctatc.h`, `linux/slab.h`, `linux/mm.h`, `linux/io.h`, `sound/pcm.h`.
- Detected declarations: `function Copyright`, `function put_vm_block`, `function list_for_each`, `function ct_vm_map`, `function ct_vm_unmap`, `function ct_get_ptp_phys`, `function ct_vm_create`, `function ct_vm_destroy`.
- Atlas domain: Driver Families / sound/pci.
- Implementation status: source 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.