drivers/media/common/videobuf2/videobuf2-dma-sg.c
Source file repositories/reference/linux-study-clean/drivers/media/common/videobuf2/videobuf2-dma-sg.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/common/videobuf2/videobuf2-dma-sg.c- Extension
.c- Size
- 16246 bytes
- Lines
- 681
- Domain
- Driver Families
- Bucket
- drivers/media
- 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 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/module.hlinux/mm.hlinux/refcount.hlinux/scatterlist.hlinux/sched.hlinux/slab.hlinux/vmalloc.hmedia/videobuf2-v4l2.hmedia/videobuf2-memops.hmedia/videobuf2-dma-sg.h
Detected Declarations
struct vb2_dma_sg_bufstruct vb2_dma_sg_attachmentfunction vb2_dma_sg_alloc_compactedfunction vb2_dma_sg_putfunction vb2_dma_sg_preparefunction vb2_dma_sg_finishfunction vb2_dma_sg_put_userptrfunction vb2_dma_sg_num_usersfunction vb2_dma_sg_mmapfunction vb2_dma_sg_dmabuf_ops_attachfunction vb2_dma_sg_dmabuf_ops_detachfunction vb2_dma_sg_dmabuf_ops_unmapfunction vb2_dma_sg_dmabuf_ops_begin_cpu_accessfunction vb2_dma_sg_dmabuf_ops_end_cpu_accessfunction vb2_dma_sg_dmabuf_ops_vmapfunction vb2_dma_sg_dmabuf_ops_mmapfunction vb2_dma_sg_map_dmabuffunction vb2_dma_sg_unmap_dmabuffunction vb2_dma_sg_detach_dmabufexport vb2_dma_sg_memops
Annotated Snippet
struct vb2_dma_sg_buf {
struct device *dev;
void *vaddr;
struct page **pages;
struct frame_vector *vec;
int offset;
enum dma_data_direction dma_dir;
struct sg_table sg_table;
/*
* This will point to sg_table when used with the MMAP or USERPTR
* memory model, and to the dma_buf sglist when used with the
* DMABUF memory model.
*/
struct sg_table *dma_sgt;
size_t size;
unsigned int num_pages;
refcount_t refcount;
struct vb2_vmarea_handler handler;
struct dma_buf_attachment *db_attach;
struct vb2_buffer *vb;
};
static void vb2_dma_sg_put(void *buf_priv);
static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf,
gfp_t gfp_flags)
{
unsigned int last_page = 0;
unsigned long size = buf->size;
while (size > 0) {
struct page *pages;
int order;
int i;
order = get_order(size);
/* Don't over allocate*/
if ((PAGE_SIZE << order) > size)
order--;
pages = NULL;
while (!pages) {
pages = alloc_pages(GFP_KERNEL | __GFP_ZERO |
__GFP_NOWARN | gfp_flags, order);
if (pages)
break;
if (order == 0) {
while (last_page--)
__free_page(buf->pages[last_page]);
return -ENOMEM;
}
order--;
}
split_page(pages, order);
for (i = 0; i < (1 << order); i++)
buf->pages[last_page++] = &pages[i];
size -= PAGE_SIZE << order;
}
return 0;
}
static void *vb2_dma_sg_alloc(struct vb2_buffer *vb, struct device *dev,
unsigned long size)
{
struct vb2_dma_sg_buf *buf;
struct sg_table *sgt;
int ret;
int num_pages;
if (WARN_ON(!dev) || WARN_ON(!size))
return ERR_PTR(-EINVAL);
buf = kzalloc_obj(*buf);
if (!buf)
return ERR_PTR(-ENOMEM);
buf->vaddr = NULL;
buf->dma_dir = vb->vb2_queue->dma_dir;
buf->offset = 0;
buf->size = size;
/* size is already page aligned */
buf->num_pages = size >> PAGE_SHIFT;
buf->dma_sgt = &buf->sg_table;
Annotation
- Immediate include surface: `linux/module.h`, `linux/mm.h`, `linux/refcount.h`, `linux/scatterlist.h`, `linux/sched.h`, `linux/slab.h`, `linux/vmalloc.h`, `media/videobuf2-v4l2.h`.
- Detected declarations: `struct vb2_dma_sg_buf`, `struct vb2_dma_sg_attachment`, `function vb2_dma_sg_alloc_compacted`, `function vb2_dma_sg_put`, `function vb2_dma_sg_prepare`, `function vb2_dma_sg_finish`, `function vb2_dma_sg_put_userptr`, `function vb2_dma_sg_num_users`, `function vb2_dma_sg_mmap`, `function vb2_dma_sg_dmabuf_ops_attach`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: integration 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.