drivers/misc/bcm-vk/bcm_vk_sg.c
Source file repositories/reference/linux-study-clean/drivers/misc/bcm-vk/bcm_vk_sg.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/misc/bcm-vk/bcm_vk_sg.c- Extension
.c- Size
- 6446 bytes
- Lines
- 274
- Domain
- Driver Families
- Bucket
- drivers/misc
- 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 user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/dma-mapping.hlinux/mm.hlinux/pagemap.hlinux/pgtable.hlinux/vmalloc.hasm/page.hlinux/unaligned.huapi/linux/misc/bcm_vk.hbcm_vk.hbcm_vk_msg.hbcm_vk_sg.h
Detected Declarations
function bcm_vk_dma_allocfunction bcm_vk_sg_allocfunction bcm_vk_dma_freefunction bcm_vk_sg_free
Annotated Snippet
if (unlikely(dma_mapping_error(dev, addr))) {
__free_page(dma->pages[i]);
return -EIO;
}
/*
* Compress SG list entry when pages are contiguous
* and transfer size less or equal to BCM_VK_MAX_SGL_CHUNK
*/
if ((addr == (sg_addr + transfer_size)) &&
((transfer_size + size) <= BCM_VK_MAX_SGL_CHUNK)) {
/* pages are contiguous, add to same sg entry */
transfer_size += size;
} else {
/* pages are not contiguous, write sg entry */
sgdata->size = transfer_size;
put_unaligned(sg_addr, (u64 *)&sgdata->address);
dma->sglist[SGLIST_NUM_SG]++;
/* start new sg entry */
sgdata++;
sg_addr = addr;
transfer_size = size;
}
}
/* Write last sg list entry */
sgdata->size = transfer_size;
put_unaligned(sg_addr, (u64 *)&sgdata->address);
dma->sglist[SGLIST_NUM_SG]++;
/* Update pointers and size field to point to sglist */
put_unaligned((u64)dma->handle, &vkdata->address);
vkdata->size = (dma->sglist[SGLIST_NUM_SG] * sizeof(*sgdata)) +
(sizeof(u32) * SGLIST_VKDATA_START);
#ifdef BCM_VK_DUMP_SGLIST
dev_dbg(dev,
"sgl 0x%llx handle 0x%llx, sglen: 0x%x sgsize: 0x%x\n",
(u64)dma->sglist,
dma->handle,
dma->sglen,
vkdata->size);
for (i = 0; i < vkdata->size / sizeof(u32); i++)
dev_dbg(dev, "i:0x%x 0x%x\n", i, dma->sglist[i]);
#endif
return 0;
}
int bcm_vk_sg_alloc(struct device *dev,
struct bcm_vk_dma *dma,
int dir,
struct _vk_data *vkdata,
int num)
{
int i;
int rc = -EINVAL;
/* Convert user addresses to DMA SG List */
for (i = 0; i < num; i++) {
if (vkdata[i].size && vkdata[i].address) {
/*
* If both size and address are non-zero
* then DMA alloc.
*/
rc = bcm_vk_dma_alloc(dev,
&dma[i],
dir,
&vkdata[i]);
} else if (vkdata[i].size ||
vkdata[i].address) {
/*
* If one of size and address are zero
* there is a problem.
*/
dev_err(dev,
"Invalid vkdata %x 0x%x 0x%llx\n",
i, vkdata[i].size, vkdata[i].address);
rc = -EINVAL;
} else {
/*
* If size and address are both zero
* don't convert, but return success.
*/
rc = 0;
}
if (rc)
goto fail_alloc;
}
Annotation
- Immediate include surface: `linux/dma-mapping.h`, `linux/mm.h`, `linux/pagemap.h`, `linux/pgtable.h`, `linux/vmalloc.h`, `asm/page.h`, `linux/unaligned.h`, `uapi/linux/misc/bcm_vk.h`.
- Detected declarations: `function bcm_vk_dma_alloc`, `function bcm_vk_sg_alloc`, `function bcm_vk_dma_free`, `function bcm_vk_sg_free`.
- Atlas domain: Driver Families / drivers/misc.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.