drivers/media/pci/ivtv/ivtv-queue.c
Source file repositories/reference/linux-study-clean/drivers/media/pci/ivtv/ivtv-queue.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/pci/ivtv/ivtv-queue.c- Extension
.c- Size
- 8379 bytes
- Lines
- 288
- 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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-queue.h
Detected Declarations
function Copyrightfunction ivtv_buf_swapfunction ivtv_queue_initfunction ivtv_enqueuefunction ivtv_queue_move_buffunction ivtv_queue_movefunction ivtv_flush_queuesfunction ivtv_stream_allocfunction ivtv_stream_free
Annotated Snippet
while (dma_xfer_cnt == buf->dma_xfer_cnt) {
list_move_tail(steal->list.prev, &from->list);
rc++;
steal->buffers--;
steal->length -= s->buf_size;
steal->bytesused -= buf->bytesused - buf->readpos;
buf->bytesused = buf->readpos = buf->b_flags = buf->dma_xfer_cnt = 0;
from->buffers++;
from->length += s->buf_size;
bytes_available += s->buf_size;
if (list_empty(&steal->list))
break;
buf = list_entry(steal->list.prev, struct ivtv_buffer, list);
}
}
if (from_free) {
u32 old_length = to->length;
while (to->length - old_length < needed_bytes) {
ivtv_queue_move_buf(s, from, to, 1);
}
}
else {
u32 old_bytesused = to->bytesused;
while (to->bytesused - old_bytesused < needed_bytes) {
ivtv_queue_move_buf(s, from, to, to_free);
}
}
spin_unlock_irqrestore(&s->qlock, flags);
return rc;
}
void ivtv_flush_queues(struct ivtv_stream *s)
{
ivtv_queue_move(s, &s->q_io, NULL, &s->q_free, 0);
ivtv_queue_move(s, &s->q_full, NULL, &s->q_free, 0);
ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
ivtv_queue_move(s, &s->q_predma, NULL, &s->q_free, 0);
}
int ivtv_stream_alloc(struct ivtv_stream *s)
{
struct ivtv *itv = s->itv;
int SGsize = sizeof(struct ivtv_sg_host_element) * s->buffers;
int i;
if (s->buffers == 0)
return 0;
IVTV_DEBUG_INFO("Allocate %s%s stream: %d x %d buffers (%dkB total)\n",
s->dma != DMA_NONE ? "DMA " : "",
s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
s->sg_pending = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
if (s->sg_pending == NULL) {
IVTV_ERR("Could not allocate sg_pending for %s stream\n", s->name);
return -ENOMEM;
}
s->sg_pending_size = 0;
s->sg_processing = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
if (s->sg_processing == NULL) {
IVTV_ERR("Could not allocate sg_processing for %s stream\n", s->name);
kfree(s->sg_pending);
s->sg_pending = NULL;
return -ENOMEM;
}
s->sg_processing_size = 0;
s->sg_dma = kzalloc_obj(struct ivtv_sg_element,
GFP_KERNEL | __GFP_NOWARN);
if (s->sg_dma == NULL) {
IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name);
kfree(s->sg_pending);
s->sg_pending = NULL;
kfree(s->sg_processing);
s->sg_processing = NULL;
return -ENOMEM;
}
if (ivtv_might_use_dma(s)) {
s->sg_handle = dma_map_single(&itv->pdev->dev, s->sg_dma,
sizeof(struct ivtv_sg_element),
DMA_TO_DEVICE);
ivtv_stream_sync_for_cpu(s);
}
/* allocate stream buffers. Initially all buffers are in q_free. */
for (i = 0; i < s->buffers; i++) {
struct ivtv_buffer *buf = kzalloc_obj(struct ivtv_buffer,
Annotation
- Immediate include surface: `ivtv-driver.h`, `ivtv-queue.h`.
- Detected declarations: `function Copyright`, `function ivtv_buf_swap`, `function ivtv_queue_init`, `function ivtv_enqueue`, `function ivtv_queue_move_buf`, `function ivtv_queue_move`, `function ivtv_flush_queues`, `function ivtv_stream_alloc`, `function ivtv_stream_free`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.