drivers/usb/gadget/function/uvc_queue.c
Source file repositories/reference/linux-study-clean/drivers/usb/gadget/function/uvc_queue.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/gadget/function/uvc_queue.c- Extension
.c- Size
- 10206 bytes
- Lines
- 369
- Domain
- Driver Families
- Bucket
- drivers/usb
- 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.
- 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/atomic.hlinux/kernel.hlinux/mm.hlinux/list.hlinux/module.hlinux/usb.hlinux/videodev2.hlinux/vmalloc.hlinux/wait.hmedia/v4l2-common.hmedia/videobuf2-dma-sg.hmedia/videobuf2-vmalloc.huvc.huvc_video.h
Detected Declarations
function Copyrightfunction uvc_buffer_preparefunction uvc_buffer_queuefunction uvcg_queue_initfunction uvcg_free_buffersfunction uvcg_alloc_buffersfunction uvcg_query_bufferfunction uvcg_queue_bufferfunction uvcg_dequeue_bufferfunction uvcg_queue_pollfunction uvcg_queue_mmapfunction uvcg_queue_get_unmapped_areafunction uvcg_queue_cancelfunction parametersfunction uvcg_complete_buffer
Annotated Snippet
vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n");
return -EINVAL;
}
if (unlikely(queue->flags & UVC_QUEUE_DISCONNECTED))
return -ENODEV;
buf->state = UVC_BUF_STATE_QUEUED;
if (queue->use_sg) {
buf->sgt = vb2_dma_sg_plane_desc(vb, 0);
buf->sg = buf->sgt->sgl;
} else {
buf->mem = vb2_plane_vaddr(vb, 0);
}
buf->length = vb2_plane_size(vb, 0);
if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
buf->bytesused = 0;
} else {
buf->bytesused = vb2_get_plane_payload(vb, 0);
if (video->reqs_per_frame != 0) {
buf->req_payload_size =
DIV_ROUND_UP(buf->bytesused +
(video->reqs_per_frame * UVCG_REQUEST_HEADER_LEN),
video->reqs_per_frame);
if (buf->req_payload_size > video->req_size)
buf->req_payload_size = video->req_size;
} else {
buf->req_payload_size = video->max_req_size;
}
}
return 0;
}
static void uvc_buffer_queue(struct vb2_buffer *vb)
{
struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf);
unsigned long flags;
spin_lock_irqsave(&queue->irqlock, flags);
if (likely(!(queue->flags & UVC_QUEUE_DISCONNECTED))) {
list_add_tail(&buf->queue, &queue->irqqueue);
} else {
/*
* If the device is disconnected return the buffer to userspace
* directly. The next QBUF call will fail with -ENODEV.
*/
buf->state = UVC_BUF_STATE_ERROR;
vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
}
spin_unlock_irqrestore(&queue->irqlock, flags);
}
static const struct vb2_ops uvc_queue_qops = {
.queue_setup = uvc_queue_setup,
.buf_prepare = uvc_buffer_prepare,
.buf_queue = uvc_buffer_queue,
};
int uvcg_queue_init(struct uvc_video_queue *queue, struct device *dev, enum v4l2_buf_type type,
struct mutex *lock)
{
struct uvc_video *video = container_of(queue, struct uvc_video, queue);
struct usb_composite_dev *cdev = video->uvc->func.config->cdev;
int ret;
queue->queue.type = type;
queue->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
queue->queue.drv_priv = queue;
queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
queue->queue.ops = &uvc_queue_qops;
queue->queue.lock = lock;
if (cdev->gadget->sg_supported) {
queue->queue.mem_ops = &vb2_dma_sg_memops;
queue->use_sg = 1;
} else {
queue->queue.mem_ops = &vb2_vmalloc_memops;
}
queue->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY
| V4L2_BUF_FLAG_TSTAMP_SRC_EOF;
queue->queue.dev = dev;
ret = vb2_queue_init(&queue->queue);
Annotation
- Immediate include surface: `linux/atomic.h`, `linux/kernel.h`, `linux/mm.h`, `linux/list.h`, `linux/module.h`, `linux/usb.h`, `linux/videodev2.h`, `linux/vmalloc.h`.
- Detected declarations: `function Copyright`, `function uvc_buffer_prepare`, `function uvc_buffer_queue`, `function uvcg_queue_init`, `function uvcg_free_buffers`, `function uvcg_alloc_buffers`, `function uvcg_query_buffer`, `function uvcg_queue_buffer`, `function uvcg_dequeue_buffer`, `function uvcg_queue_poll`.
- Atlas domain: Driver Families / drivers/usb.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.