drivers/media/pci/cx18/cx18-queue.c
Source file repositories/reference/linux-study-clean/drivers/media/pci/cx18/cx18-queue.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/pci/cx18/cx18-queue.c- Extension
.c- Size
- 11409 bytes
- Lines
- 435
- 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
cx18-driver.hcx18-queue.hcx18-streams.hcx18-scb.hcx18-io.h
Detected Declarations
function Copyrightfunction _cx18_mdl_swapfunction list_for_each_entryfunction cx18_queue_initfunction _cx18_mdl_update_bufs_for_cpufunction list_for_each_entryfunction cx18_mdl_update_bufs_for_cpufunction cx18_queue_flushfunction cx18_flush_queuesfunction cx18_unload_queuesfunction cx18_load_queuesfunction _cx18_mdl_sync_for_devicefunction cx18_stream_allocfunction cx18_stream_free
Annotated Snippet
if (bytesused >= buf_size) {
buf->bytesused = buf_size;
bytesused -= buf_size;
} else {
buf->bytesused = bytesused;
bytesused = 0;
}
cx18_buf_sync_for_cpu(s, buf);
}
}
static inline void cx18_mdl_update_bufs_for_cpu(struct cx18_stream *s,
struct cx18_mdl *mdl)
{
struct cx18_buffer *buf;
if (list_is_singular(&mdl->buf_list)) {
buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
list);
buf->bytesused = mdl->bytesused;
buf->readpos = 0;
cx18_buf_sync_for_cpu(s, buf);
} else {
_cx18_mdl_update_bufs_for_cpu(s, mdl);
}
}
struct cx18_mdl *cx18_queue_get_mdl(struct cx18_stream *s, u32 id,
u32 bytesused)
{
struct cx18 *cx = s->cx;
struct cx18_mdl *mdl;
struct cx18_mdl *tmp;
struct cx18_mdl *ret = NULL;
LIST_HEAD(sweep_up);
/*
* We don't have to acquire multiple q locks here, because we are
* serialized by the single threaded work handler.
* MDLs from the firmware will thus remain in order as
* they are moved from q_busy to q_full or to the dvb ring buffer.
*/
spin_lock(&s->q_busy.lock);
list_for_each_entry_safe(mdl, tmp, &s->q_busy.list, list) {
/*
* We should find what the firmware told us is done,
* right at the front of the queue. If we don't, we likely have
* missed an mdl done message from the firmware.
* Once we skip an mdl repeatedly, relative to the size of
* q_busy, we have high confidence we've missed it.
*/
if (mdl->id != id) {
mdl->skipped++;
if (mdl->skipped >= atomic_read(&s->q_busy.depth)-1) {
/* mdl must have fallen out of rotation */
CX18_WARN("Skipped %s, MDL %d, %d times - it must have dropped out of rotation\n",
s->name, mdl->id,
mdl->skipped);
/* Sweep it up to put it back into rotation */
list_move_tail(&mdl->list, &sweep_up);
atomic_dec(&s->q_busy.depth);
}
continue;
}
/*
* We pull the desired mdl off of the queue here. Something
* will have to put it back on a queue later.
*/
list_del_init(&mdl->list);
atomic_dec(&s->q_busy.depth);
ret = mdl;
break;
}
spin_unlock(&s->q_busy.lock);
/*
* We found the mdl for which we were looking. Get it ready for
* the caller to put on q_full or in the dvb ring buffer.
*/
if (ret != NULL) {
ret->bytesused = bytesused;
ret->skipped = 0;
/* 0'ed readpos, m_flags & curr_buf when mdl went on q_busy */
cx18_mdl_update_bufs_for_cpu(s, ret);
if (s->type != CX18_ENC_STREAM_TYPE_TS)
set_bit(CX18_F_M_NEED_SWAP, &ret->m_flags);
}
/* Put any mdls the firmware is ignoring back into normal rotation */
list_for_each_entry_safe(mdl, tmp, &sweep_up, list) {
Annotation
- Immediate include surface: `cx18-driver.h`, `cx18-queue.h`, `cx18-streams.h`, `cx18-scb.h`, `cx18-io.h`.
- Detected declarations: `function Copyright`, `function _cx18_mdl_swap`, `function list_for_each_entry`, `function cx18_queue_init`, `function _cx18_mdl_update_bufs_for_cpu`, `function list_for_each_entry`, `function cx18_mdl_update_bufs_for_cpu`, `function cx18_queue_flush`, `function cx18_flush_queues`, `function cx18_unload_queues`.
- 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.