File Index
Files and directories
Sign in
FILE

uvc_queue.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/usb/uvc/uvc_queue.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 *      uvc_queue.c  --  USB Video Class driver - Buffers management
  4 *
  5 *      Copyright (C) 2005-2010
  6 *          Laurent Pinchart (laurent.pinchart@ideasonboard.com)
  7 */
  8
  9#include <linux/atomic.h>
 10#include <linux/kernel.h>
 11#include <linux/mm.h>
 12#include <linux/list.h>
 13#include <linux/module.h>
 14#include <linux/usb.h>
 15#include <linux/videodev2.h>
 16#include <linux/vmalloc.h>
 17#include <linux/wait.h>
 18#include <media/videobuf2-v4l2.h>
 19#include <media/videobuf2-vmalloc.h>
 20
 21#include "uvcvideo.h"
 22
 23/* ------------------------------------------------------------------------
 24 * Video buffers queue management.
 25 *
 26 * Video queues is initialized by uvc_queue_init(). The function performs
 27 * basic initialization of the uvc_video_queue struct and never fails.
 28 *
 29 * Video buffers are managed by videobuf2. The driver uses a mutex to protect
 30 * the videobuf2 queue operations by serializing calls to videobuf2 and a
 31 * spinlock to protect the IRQ queue that holds the buffers to be processed by
 32 * the driver.
 33 */
 34
 35static inline struct uvc_buffer *uvc_vbuf_to_buffer(struct vb2_v4l2_buffer *buf)
 36{
 37	return container_of(buf, struct uvc_buffer, buf);
 38}
 39
 40/*
 41 * Return all queued buffers to videobuf2 in the requested state.
 42 *
 43 * This function must be called with the queue spinlock held.
 44 */
 45static void __uvc_queue_return_buffers(struct uvc_video_queue *queue,
 46				       enum uvc_buffer_state state)
 47{
 48	enum vb2_buffer_state vb2_state = state == UVC_BUF_STATE_ERROR
 49					? VB2_BUF_STATE_ERROR
 50					: VB2_BUF_STATE_QUEUED;
 51
 52	lockdep_assert_held(&queue->irqlock);
 53
 54	while (!list_empty(&queue->irqqueue)) {
 55		struct uvc_buffer *buf = list_first_entry(&queue->irqqueue,
 56							  struct uvc_buffer,
 57							  queue);
 58		list_del(&buf->queue);
 59		buf->state = state;
 60		vb2_buffer_done(&buf->buf.vb2_buf, vb2_state);
 61	}
 62}
 63
 64static void uvc_queue_return_buffers(struct uvc_video_queue *queue,
 65				     enum uvc_buffer_state state)
 66{
 67	spin_lock_irq(&queue->irqlock);
 68	__uvc_queue_return_buffers(queue, state);
 69	spin_unlock_irq(&queue->irqlock);
 70}
 71
 72/* -----------------------------------------------------------------------------
 73 * videobuf2 queue operations
 74 */
 75
 76static int uvc_queue_setup(struct vb2_queue *vq,
 77			   unsigned int *nbuffers, unsigned int *nplanes,
 78			   unsigned int sizes[], struct device *alloc_devs[])
 79{
 80	struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
 81	struct uvc_streaming *stream;
 82	unsigned int size;
 83
 84	switch (vq->type) {
 85	case V4L2_BUF_TYPE_META_CAPTURE:
 86		size = UVC_METADATA_BUF_SIZE;
 87		break;
 88
 89	default:
 90		stream = uvc_queue_to_stream(queue);
 91		size = stream->ctrl.dwMaxVideoFrameSize;
 92		break;
 93	}
 94
 95	/*
 96	 * When called with plane sizes, validate them. The driver supports
 97	 * single planar formats only, and requires buffers to be large enough
 98	 * to store a complete frame.
 99	 */
100	if (*nplanes)
101		return *nplanes != 1 || sizes[0] < size ? -EINVAL : 0;
102
103	*nplanes = 1;
104	sizes[0] = size;
105	return 0;
106}
107
108static int uvc_buffer_prepare(struct vb2_buffer *vb)
109{
110	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
111	struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
112	struct uvc_buffer *buf = uvc_vbuf_to_buffer(vbuf);
113
114	if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
115	    vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
116		uvc_dbg(uvc_queue_to_stream(queue)->dev, CAPTURE,
117			"[E] Bytes used out of bounds\n");
118		return -EINVAL;
119	}
120
121	if (unlikely(queue->flags & UVC_QUEUE_DISCONNECTED))
122		return -ENODEV;
123
124	buf->state = UVC_BUF_STATE_QUEUED;
125	buf->error = 0;
126	buf->mem = vb2_plane_vaddr(vb, 0);
127	buf->length = vb2_plane_size(vb, 0);
128	if (vb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
129		buf->bytesused = 0;
130	else
131		buf->bytesused = vb2_get_plane_payload(vb, 0);
132
133	return 0;
134}
135
136static void uvc_buffer_queue(struct vb2_buffer *vb)
137{
138	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
139	struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
140	struct uvc_buffer *buf = uvc_vbuf_to_buffer(vbuf);
141	unsigned long flags;
142
143	spin_lock_irqsave(&queue->irqlock, flags);
144	if (likely(!(queue->flags & UVC_QUEUE_DISCONNECTED))) {
145		kref_init(&buf->ref);
146		list_add_tail(&buf->queue, &queue->irqqueue);
147	} else {
148		/*
149		 * If the device is disconnected return the buffer to userspace
150		 * directly. The next QBUF call will fail with -ENODEV.
151		 */
152		buf->state = UVC_BUF_STATE_ERROR;
153		vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
154	}
155
156	spin_unlock_irqrestore(&queue->irqlock, flags);
157}
158
159static void uvc_buffer_finish(struct vb2_buffer *vb)
160{
161	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
162	struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
163	struct uvc_streaming *stream = uvc_queue_to_stream(queue);
164	struct uvc_buffer *buf = uvc_vbuf_to_buffer(vbuf);
165
166	if (vb->state == VB2_BUF_STATE_DONE)
167		uvc_video_clock_update(stream, vbuf, buf);
168}
169
170static int uvc_start_streaming_video(struct vb2_queue *vq, unsigned int count)
171{
172	struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
173	struct uvc_streaming *stream = uvc_queue_to_stream(queue);
174	int ret;
175
176	lockdep_assert_irqs_enabled();
177
178	ret = uvc_pm_get(stream->dev);
179	if (ret)
180		goto err_buffers;
181
182	queue->buf_used = 0;
183
184	ret = uvc_video_start_streaming(stream);
185	if (ret)
186		goto err_pm;
187
188	return 0;
189
190err_pm:
191	uvc_pm_put(stream->dev);
192err_buffers:
193	uvc_queue_return_buffers(queue, UVC_BUF_STATE_QUEUED);
194	return ret;
195}
196
197static void uvc_stop_streaming_video(struct vb2_queue *vq)
198{
199	struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
200	struct uvc_streaming *stream = uvc_queue_to_stream(queue);
201
202	lockdep_assert_irqs_enabled();
203
204	uvc_video_stop_streaming(uvc_queue_to_stream(queue));
205
206	uvc_pm_put(stream->dev);
207
208	uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
209}
210
211static void uvc_stop_streaming_meta(struct vb2_queue *vq)
212{
213	struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
214
215	lockdep_assert_irqs_enabled();
216
217	uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
218}
219
220static const struct vb2_ops uvc_queue_qops = {
221	.queue_setup = uvc_queue_setup,
222	.buf_prepare = uvc_buffer_prepare,
223	.buf_queue = uvc_buffer_queue,
224	.buf_finish = uvc_buffer_finish,
225	.start_streaming = uvc_start_streaming_video,
226	.stop_streaming = uvc_stop_streaming_video,
227};
228
229static const struct vb2_ops uvc_meta_queue_qops = {
230	.queue_setup = uvc_queue_setup,
231	.buf_prepare = uvc_buffer_prepare,
232	.buf_queue = uvc_buffer_queue,
233	/*
234	 * .start_streaming is not provided here. Metadata relies on video
235	 * streaming being active. If video isn't streaming, then no metadata
236	 * will arrive either.
237	 */
238	.stop_streaming = uvc_stop_streaming_meta,
239};
240
241int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
242{
243	int ret;
244
245	queue->queue.type = type;
246	queue->queue.io_modes = VB2_MMAP | VB2_USERPTR;
247	queue->queue.drv_priv = queue;
248	queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
249	queue->queue.mem_ops = &vb2_vmalloc_memops;
250	queue->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
251		| V4L2_BUF_FLAG_TSTAMP_SRC_SOE;
252	queue->queue.lock = &queue->mutex;
253
254	switch (type) {
255	case V4L2_BUF_TYPE_META_CAPTURE:
256		queue->queue.ops = &uvc_meta_queue_qops;
257		break;
258	default:
259		queue->queue.io_modes |= VB2_DMABUF;
260		queue->queue.ops = &uvc_queue_qops;
261		break;
262	}
263
264	ret = vb2_queue_init(&queue->queue);
265	if (ret)
266		return ret;
267
268	mutex_init(&queue->mutex);
269	spin_lock_init(&queue->irqlock);
270	INIT_LIST_HEAD(&queue->irqqueue);
271
272	return 0;
273}
274
275/* -----------------------------------------------------------------------------
276 *
277 */
278
279/*
280 * Cancel the video buffers queue.
281 *
282 * Cancelling the queue marks all buffers on the irq queue as erroneous,
283 * wakes them up and removes them from the queue.
284 *
285 * If the disconnect parameter is set, further calls to uvc_queue_buffer will
286 * fail with -ENODEV.
287 *
288 * This function acquires the irq spinlock and can be called from interrupt
289 * context.
290 */
291void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect)
292{
293	unsigned long flags;
294
295	spin_lock_irqsave(&queue->irqlock, flags);
296	__uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
297	/*
298	 * This must be protected by the irqlock spinlock to avoid race
299	 * conditions between uvc_buffer_queue and the disconnection event that
300	 * could result in an interruptible wait in uvc_dequeue_buffer. Do not
301	 * blindly replace this logic by checking for the UVC_QUEUE_DISCONNECTED
302	 * state outside the queue code.
303	 */
304	if (disconnect)
305		queue->flags |= UVC_QUEUE_DISCONNECTED;
306	spin_unlock_irqrestore(&queue->irqlock, flags);
307}
308
309/*
310 * uvc_queue_get_current_buffer: Obtain the current working output buffer
311 *
312 * Buffers may span multiple packets, and even URBs, therefore the active buffer
313 * remains on the queue until the EOF marker.
314 */
315static struct uvc_buffer *
316__uvc_queue_get_current_buffer(struct uvc_video_queue *queue)
317{
318	if (list_empty(&queue->irqqueue))
319		return NULL;
320
321	return list_first_entry(&queue->irqqueue, struct uvc_buffer, queue);
322}
323
324struct uvc_buffer *uvc_queue_get_current_buffer(struct uvc_video_queue *queue)
325{
326	struct uvc_buffer *nextbuf;
327	unsigned long flags;
328
329	spin_lock_irqsave(&queue->irqlock, flags);
330	nextbuf = __uvc_queue_get_current_buffer(queue);
331	spin_unlock_irqrestore(&queue->irqlock, flags);
332
333	return nextbuf;
334}
335
336/*
337 * uvc_queue_buffer_requeue: Requeue a buffer on our internal irqqueue
338 *
339 * Reuse a buffer through our internal queue without the need to 'prepare'.
340 * The buffer will be returned to userspace through the uvc_buffer_queue call if
341 * the device has been disconnected.
342 */
343static void uvc_queue_buffer_requeue(struct uvc_video_queue *queue,
344		struct uvc_buffer *buf)
345{
346	buf->error = 0;
347	buf->state = UVC_BUF_STATE_QUEUED;
348	buf->bytesused = 0;
349	vb2_set_plane_payload(&buf->buf.vb2_buf, 0, 0);
350
351	uvc_buffer_queue(&buf->buf.vb2_buf);
352}
353
354static void uvc_queue_buffer_complete(struct kref *ref)
355{
356	struct uvc_buffer *buf = container_of(ref, struct uvc_buffer, ref);
357	struct vb2_buffer *vb = &buf->buf.vb2_buf;
358	struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
359
360	if (buf->error && !uvc_no_drop_param) {
361		uvc_queue_buffer_requeue(queue, buf);
362		return;
363	}
364
365	buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
366	vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused);
367	vb2_buffer_done(&buf->buf.vb2_buf, buf->error ? VB2_BUF_STATE_ERROR :
368							VB2_BUF_STATE_DONE);
369}
370
371/*
372 * Release a reference on the buffer. Complete the buffer when the last
373 * reference is released.
374 */
375void uvc_queue_buffer_release(struct uvc_buffer *buf)
376{
377	kref_put(&buf->ref, uvc_queue_buffer_complete);
378}
379
380/*
381 * Remove this buffer from the queue. Lifetime will persist while async actions
382 * are still running (if any), and uvc_queue_buffer_release will give the buffer
383 * back to VB2 when all users have completed.
384 */
385struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
386		struct uvc_buffer *buf)
387{
388	struct uvc_buffer *nextbuf;
389	unsigned long flags;
390
391	spin_lock_irqsave(&queue->irqlock, flags);
392	list_del(&buf->queue);
393	nextbuf = __uvc_queue_get_current_buffer(queue);
394	spin_unlock_irqrestore(&queue->irqlock, flags);
395
396	uvc_queue_buffer_release(buf);
397
398	return nextbuf;
399}
~/ Read-only file preview.