drivers/media/pci/ivtv/ivtv-yuv.c
Source file repositories/reference/linux-study-clean/drivers/media/pci/ivtv/ivtv-yuv.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/pci/ivtv/ivtv-yuv.c- Extension
.c- Size
- 38534 bytes
- Lines
- 1294
- Domain
- Driver Families
- Bucket
- drivers/media
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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
ivtv-driver.hivtv-udma.hivtv-yuv.h
Detected Declarations
function ivtv_yuv_prep_user_dmafunction ivtv_yuv_filter_checkfunction ivtv_yuv_filterfunction ivtv_yuv_handle_horizontalfunction ivtv_yuv_handle_verticalfunction ivtv_yuv_window_setupfunction ivtv_yuv_work_handlerfunction ivtv_yuv_initfunction ivtv_yuv_next_freefunction ivtv_yuv_setup_framefunction ivtv_yuv_frame_completefunction ivtv_yuv_udma_framefunction test_bitfunction ivtv_yuv_setup_stream_framefunction ivtv_yuv_udma_stream_framefunction ivtv_yuv_prep_framefunction ivtv_yuv_close
Annotated Snippet
if (y_pages == y_dma.page_count) {
IVTV_DEBUG_WARN
("failed to map uv user pages, returned %d expecting %d\n",
uv_pages, uv_dma.page_count);
if (uv_pages >= 0) {
unpin_user_pages(&dma->map[y_pages], uv_pages);
rc = -EFAULT;
} else {
rc = uv_pages;
}
} else {
IVTV_DEBUG_WARN
("failed to map y user pages, returned %d expecting %d\n",
y_pages, y_dma.page_count);
}
if (y_pages >= 0) {
unpin_user_pages(dma->map, y_pages);
/*
* Inherit the -EFAULT from rc's
* initialization, but allow it to be
* overridden by uv_pages above if it was an
* actual errno.
*/
} else {
rc = y_pages;
}
return rc;
}
dma->page_count = y_pages + uv_pages;
/* Fill & map SG List */
if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) {
IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n");
unpin_user_pages(dma->map, dma->page_count);
dma->page_count = 0;
return -ENOMEM;
}
dma->SG_length = dma_map_sg(&itv->pdev->dev, dma->SGlist,
dma->page_count, DMA_TO_DEVICE);
if (!dma->SG_length) {
IVTV_DEBUG_WARN("%s: DMA map error, SG_length is 0\n", __func__);
unpin_user_pages(dma->map, dma->page_count);
dma->page_count = 0;
return -EINVAL;
}
/* Fill SG Array with new values */
ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
/* If we've offset the y plane, ensure top area is blanked */
if (f->offset_y && yi->blanking_ptr) {
dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16);
dma->SGarray[dma->SG_length].src = cpu_to_le32(yi->blanking_dmaptr);
dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DECODER_OFFSET + yuv_offset[frame]);
dma->SG_length++;
}
/* Tag SG Array with Interrupt Bit */
dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000);
ivtv_udma_sync_for_device(itv);
return 0;
}
/* We rely on a table held in the firmware - Quick check. */
int ivtv_yuv_filter_check(struct ivtv *itv)
{
int i, y, uv;
for (i = 0, y = 16, uv = 4; i < 16; i++, y += 24, uv += 12) {
if ((read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + y) != i << 16) ||
(read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + uv) != i << 16)) {
IVTV_WARN ("YUV filter table not found in firmware.\n");
return -1;
}
}
return 0;
}
static void ivtv_yuv_filter(struct ivtv *itv, int h_filter, int v_filter_1, int v_filter_2)
{
u32 i, line;
/* If any filter is -1, then don't update it */
if (h_filter > -1) {
if (h_filter > 4)
h_filter = 4;
i = IVTV_YUV_HORIZONTAL_FILTER_OFFSET + (h_filter * 384);
Annotation
- Immediate include surface: `ivtv-driver.h`, `ivtv-udma.h`, `ivtv-yuv.h`.
- Detected declarations: `function ivtv_yuv_prep_user_dma`, `function ivtv_yuv_filter_check`, `function ivtv_yuv_filter`, `function ivtv_yuv_handle_horizontal`, `function ivtv_yuv_handle_vertical`, `function ivtv_yuv_window_setup`, `function ivtv_yuv_work_handler`, `function ivtv_yuv_init`, `function ivtv_yuv_next_free`, `function ivtv_yuv_setup_frame`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.