Skip to content

Commit c93d73c

Browse files
committed
media: uvcvideo: Use vb2 ioctl and fop helpers
When uvc was written the vb2 ioctl and file operation helpers didn't exist. This patch switches uvc over to those helpers, which removes a lot of boilerplate code and allows us to drop the 'privileges' scheme, since that's now handled inside the vb2 helpers. This makes it possible for uvc to fix the v4l2-compliance streaming tests: warn: v4l2-test-formats.cpp(1075): Could not set fmt2 This patch introduces a change on behavior on the uvcdriver to be aligned with the rest of the subsystem. Now S_INPUT, S_PARM and S_FORMAT do no grant exclusive ownership of the device. There are other side effects, some better than others: - Locking is now more coarse than before, the queue is locked for almost every ioctl. - vidioc_querybuf() can now work when the queue is busy. Future patches should look into the locking architecture of UVC to remove one of stream->mutex or queue->mutex. Reviewed-by: Hans de Goede <hansg@kernel.org> Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl> Co-developed-by: Ricardo Ribalda <ribalda@chromium.org> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org> Link: https://lore.kernel.org/r/20250616-uvc-fop-v4-1-250286570ee7@chromium.org Signed-off-by: Hans de Goede <hansg@kernel.org> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
1 parent cee06ca commit c93d73c

5 files changed

Lines changed: 34 additions & 442 deletions

File tree

drivers/media/usb/uvc/uvc_driver.c

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1961,31 +1961,7 @@ static void uvc_unregister_video(struct uvc_device *dev)
19611961
if (!video_is_registered(&stream->vdev))
19621962
continue;
19631963

1964-
/*
1965-
* For stream->vdev we follow the same logic as:
1966-
* vb2_video_unregister_device().
1967-
*/
1968-
1969-
/* 1. Take a reference to vdev */
1970-
get_device(&stream->vdev.dev);
1971-
1972-
/* 2. Ensure that no new ioctls can be called. */
1973-
video_unregister_device(&stream->vdev);
1974-
1975-
/* 3. Wait for old ioctls to finish. */
1976-
mutex_lock(&stream->mutex);
1977-
1978-
/* 4. Stop streaming. */
1979-
uvc_queue_release(&stream->queue);
1980-
1981-
mutex_unlock(&stream->mutex);
1982-
1983-
put_device(&stream->vdev.dev);
1984-
1985-
/*
1986-
* For stream->meta.vdev we can directly call:
1987-
* vb2_video_unregister_device().
1988-
*/
1964+
vb2_video_unregister_device(&stream->vdev);
19891965
vb2_video_unregister_device(&stream->meta.vdev);
19901966

19911967
/*
@@ -2033,6 +2009,8 @@ int uvc_register_video_device(struct uvc_device *dev,
20332009
vdev->ioctl_ops = ioctl_ops;
20342010
vdev->release = uvc_release;
20352011
vdev->prio = &stream->chain->prio;
2012+
vdev->queue = &queue->queue;
2013+
vdev->lock = &queue->mutex;
20362014
if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
20372015
vdev->vfl_dir = VFL_DIR_TX;
20382016
else
@@ -2397,9 +2375,12 @@ static int __uvc_resume(struct usb_interface *intf, int reset)
23972375
list_for_each_entry(stream, &dev->streams, list) {
23982376
if (stream->intf == intf) {
23992377
ret = uvc_video_resume(stream, reset);
2400-
if (ret < 0)
2401-
uvc_queue_streamoff(&stream->queue,
2402-
stream->queue.queue.type);
2378+
if (ret < 0) {
2379+
mutex_lock(&stream->queue.mutex);
2380+
vb2_streamoff(&stream->queue.queue,
2381+
stream->queue.queue.type);
2382+
mutex_unlock(&stream->queue.mutex);
2383+
}
24032384
return ret;
24042385
}
24052386
}

drivers/media/usb/uvc/uvc_metadata.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ static int uvc_meta_v4l2_set_format(struct file *file, void *fh,
9696
*/
9797
mutex_lock(&stream->mutex);
9898

99-
if (uvc_queue_allocated(&stream->queue))
99+
if (vb2_is_busy(&stream->meta.queue.queue))
100100
ret = -EBUSY;
101101
else
102102
stream->meta.format = fmt->dataformat;
@@ -164,12 +164,6 @@ int uvc_meta_register(struct uvc_streaming *stream)
164164

165165
stream->meta.format = V4L2_META_FMT_UVC;
166166

167-
/*
168-
* The video interface queue uses manual locking and thus does not set
169-
* the queue pointer. Set it manually here.
170-
*/
171-
vdev->queue = &queue->queue;
172-
173167
return uvc_register_video_device(dev, stream, vdev, queue,
174168
V4L2_BUF_TYPE_META_CAPTURE,
175169
&uvc_meta_fops, &uvc_meta_ioctl_ops);

drivers/media/usb/uvc/uvc_queue.c

Lines changed: 0 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -242,153 +242,10 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
242242
return 0;
243243
}
244244

245-
void uvc_queue_release(struct uvc_video_queue *queue)
246-
{
247-
mutex_lock(&queue->mutex);
248-
vb2_queue_release(&queue->queue);
249-
mutex_unlock(&queue->mutex);
250-
}
251-
252-
/* -----------------------------------------------------------------------------
253-
* V4L2 queue operations
254-
*/
255-
256-
int uvc_request_buffers(struct uvc_video_queue *queue,
257-
struct v4l2_requestbuffers *rb)
258-
{
259-
int ret;
260-
261-
mutex_lock(&queue->mutex);
262-
ret = vb2_reqbufs(&queue->queue, rb);
263-
mutex_unlock(&queue->mutex);
264-
265-
return ret ? ret : rb->count;
266-
}
267-
268-
int uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf)
269-
{
270-
int ret;
271-
272-
mutex_lock(&queue->mutex);
273-
ret = vb2_querybuf(&queue->queue, buf);
274-
mutex_unlock(&queue->mutex);
275-
276-
return ret;
277-
}
278-
279-
int uvc_create_buffers(struct uvc_video_queue *queue,
280-
struct v4l2_create_buffers *cb)
281-
{
282-
int ret;
283-
284-
mutex_lock(&queue->mutex);
285-
ret = vb2_create_bufs(&queue->queue, cb);
286-
mutex_unlock(&queue->mutex);
287-
288-
return ret;
289-
}
290-
291-
int uvc_queue_buffer(struct uvc_video_queue *queue,
292-
struct media_device *mdev, struct v4l2_buffer *buf)
293-
{
294-
int ret;
295-
296-
mutex_lock(&queue->mutex);
297-
ret = vb2_qbuf(&queue->queue, mdev, buf);
298-
mutex_unlock(&queue->mutex);
299-
300-
return ret;
301-
}
302-
303-
int uvc_export_buffer(struct uvc_video_queue *queue,
304-
struct v4l2_exportbuffer *exp)
305-
{
306-
int ret;
307-
308-
mutex_lock(&queue->mutex);
309-
ret = vb2_expbuf(&queue->queue, exp);
310-
mutex_unlock(&queue->mutex);
311-
312-
return ret;
313-
}
314-
315-
int uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf,
316-
int nonblocking)
317-
{
318-
int ret;
319-
320-
mutex_lock(&queue->mutex);
321-
ret = vb2_dqbuf(&queue->queue, buf, nonblocking);
322-
mutex_unlock(&queue->mutex);
323-
324-
return ret;
325-
}
326-
327-
int uvc_queue_streamon(struct uvc_video_queue *queue, enum v4l2_buf_type type)
328-
{
329-
int ret;
330-
331-
mutex_lock(&queue->mutex);
332-
ret = vb2_streamon(&queue->queue, type);
333-
mutex_unlock(&queue->mutex);
334-
335-
return ret;
336-
}
337-
338-
int uvc_queue_streamoff(struct uvc_video_queue *queue, enum v4l2_buf_type type)
339-
{
340-
int ret;
341-
342-
mutex_lock(&queue->mutex);
343-
ret = vb2_streamoff(&queue->queue, type);
344-
mutex_unlock(&queue->mutex);
345-
346-
return ret;
347-
}
348-
349-
int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
350-
{
351-
return vb2_mmap(&queue->queue, vma);
352-
}
353-
354-
#ifndef CONFIG_MMU
355-
unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
356-
unsigned long pgoff)
357-
{
358-
return vb2_get_unmapped_area(&queue->queue, 0, 0, pgoff, 0);
359-
}
360-
#endif
361-
362-
__poll_t uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
363-
poll_table *wait)
364-
{
365-
__poll_t ret;
366-
367-
mutex_lock(&queue->mutex);
368-
ret = vb2_poll(&queue->queue, file, wait);
369-
mutex_unlock(&queue->mutex);
370-
371-
return ret;
372-
}
373-
374245
/* -----------------------------------------------------------------------------
375246
*
376247
*/
377248

378-
/*
379-
* Check if buffers have been allocated.
380-
*/
381-
int uvc_queue_allocated(struct uvc_video_queue *queue)
382-
{
383-
int allocated;
384-
385-
mutex_lock(&queue->mutex);
386-
allocated = vb2_is_busy(&queue->queue);
387-
mutex_unlock(&queue->mutex);
388-
389-
return allocated;
390-
}
391-
392249
/*
393250
* Cancel the video buffers queue.
394251
*

0 commit comments

Comments
 (0)