aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/v4l2-dev.c16
-rw-r--r--drivers/media/video/v4l2-ioctl.c31
-rw-r--r--include/media/v4l2-dev.h3
-rw-r--r--include/media/v4l2-ioctl.h5
-rw-r--r--include/media/videobuf2-core.h13
5 files changed, 49 insertions, 19 deletions
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index c2122e53f051..b82778174eef 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -348,20 +348,14 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
348 int ret = -ENODEV; 348 int ret = -ENODEV;
349 349
350 if (vdev->fops->unlocked_ioctl) { 350 if (vdev->fops->unlocked_ioctl) {
351 bool locked = false; 351 struct mutex *lock = v4l2_ioctl_get_lock(vdev, cmd);
352 352
353 if (vdev->lock) { 353 if (lock && mutex_lock_interruptible(lock))
354 /* always lock unless the cmd is marked as "don't use lock" */ 354 return -ERESTARTSYS;
355 locked = !v4l2_is_known_ioctl(cmd) ||
356 !test_bit(_IOC_NR(cmd), vdev->disable_locking);
357
358 if (locked && mutex_lock_interruptible(vdev->lock))
359 return -ERESTARTSYS;
360 }
361 if (video_is_registered(vdev)) 355 if (video_is_registered(vdev))
362 ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); 356 ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
363 if (locked) 357 if (lock)
364 mutex_unlock(vdev->lock); 358 mutex_unlock(lock);
365 } else if (vdev->fops->ioctl) { 359 } else if (vdev->fops->ioctl) {
366 /* This code path is a replacement for the BKL. It is a major 360 /* This code path is a replacement for the BKL. It is a major
367 * hack but it will have to do for those drivers that are not 361 * hack but it will have to do for those drivers that are not
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index fd6436edde70..70e0efb127a6 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -27,6 +27,7 @@
27#include <media/v4l2-event.h> 27#include <media/v4l2-event.h>
28#include <media/v4l2-device.h> 28#include <media/v4l2-device.h>
29#include <media/v4l2-chip-ident.h> 29#include <media/v4l2-chip-ident.h>
30#include <media/videobuf2-core.h>
30 31
31/* Zero out the end of the struct pointed to by p. Everything after, but 32/* Zero out the end of the struct pointed to by p. Everything after, but
32 * not including, the specified field is cleared. */ 33 * not including, the specified field is cleared. */
@@ -1817,6 +1818,8 @@ struct v4l2_ioctl_info {
1817#define INFO_FL_STD (1 << 2) 1818#define INFO_FL_STD (1 << 2)
1818/* This is ioctl has its own function */ 1819/* This is ioctl has its own function */
1819#define INFO_FL_FUNC (1 << 3) 1820#define INFO_FL_FUNC (1 << 3)
1821/* Queuing ioctl */
1822#define INFO_FL_QUEUE (1 << 4)
1820/* Zero struct from after the field to the end */ 1823/* Zero struct from after the field to the end */
1821#define INFO_FL_CLEAR(v4l2_struct, field) \ 1824#define INFO_FL_CLEAR(v4l2_struct, field) \
1822 ((offsetof(struct v4l2_struct, field) + \ 1825 ((offsetof(struct v4l2_struct, field) + \
@@ -1846,15 +1849,15 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
1846 IOCTL_INFO_FNC(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)), 1849 IOCTL_INFO_FNC(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)),
1847 IOCTL_INFO_FNC(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, INFO_FL_CLEAR(v4l2_format, type)), 1850 IOCTL_INFO_FNC(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, INFO_FL_CLEAR(v4l2_format, type)),
1848 IOCTL_INFO_FNC(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO), 1851 IOCTL_INFO_FNC(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
1849 IOCTL_INFO_FNC(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO), 1852 IOCTL_INFO_FNC(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
1850 IOCTL_INFO_FNC(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_CLEAR(v4l2_buffer, length)), 1853 IOCTL_INFO_FNC(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
1851 IOCTL_INFO_STD(VIDIOC_G_FBUF, vidioc_g_fbuf, v4l_print_framebuffer, 0), 1854 IOCTL_INFO_STD(VIDIOC_G_FBUF, vidioc_g_fbuf, v4l_print_framebuffer, 0),
1852 IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO), 1855 IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
1853 IOCTL_INFO_STD(VIDIOC_OVERLAY, vidioc_overlay, v4l_print_u32, INFO_FL_PRIO), 1856 IOCTL_INFO_STD(VIDIOC_OVERLAY, vidioc_overlay, v4l_print_u32, INFO_FL_PRIO),
1854 IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, 0), 1857 IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
1855 IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, 0), 1858 IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
1856 IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO), 1859 IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
1857 IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO), 1860 IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
1858 IOCTL_INFO_FNC(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)), 1861 IOCTL_INFO_FNC(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
1859 IOCTL_INFO_FNC(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO), 1862 IOCTL_INFO_FNC(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
1860 IOCTL_INFO_FNC(VIDIOC_G_STD, v4l_g_std, v4l_print_std, 0), 1863 IOCTL_INFO_FNC(VIDIOC_G_STD, v4l_g_std, v4l_print_std, 0),
@@ -1918,8 +1921,8 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
1918 IOCTL_INFO_FNC(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0), 1921 IOCTL_INFO_FNC(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
1919 IOCTL_INFO_FNC(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0), 1922 IOCTL_INFO_FNC(VIDIOC_SUBSCRIBE_EVENT, v4l_subscribe_event, v4l_print_event_subscription, 0),
1920 IOCTL_INFO_FNC(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0), 1923 IOCTL_INFO_FNC(VIDIOC_UNSUBSCRIBE_EVENT, v4l_unsubscribe_event, v4l_print_event_subscription, 0),
1921 IOCTL_INFO_FNC(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO), 1924 IOCTL_INFO_FNC(VIDIOC_CREATE_BUFS, v4l_create_bufs, v4l_print_create_buffers, INFO_FL_PRIO | INFO_FL_QUEUE),
1922 IOCTL_INFO_FNC(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, 0), 1925 IOCTL_INFO_FNC(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE),
1923 IOCTL_INFO_STD(VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings, v4l_print_enum_dv_timings, 0), 1926 IOCTL_INFO_STD(VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings, v4l_print_enum_dv_timings, 0),
1924 IOCTL_INFO_STD(VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings, v4l_print_dv_timings, 0), 1927 IOCTL_INFO_STD(VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings, v4l_print_dv_timings, 0),
1925 IOCTL_INFO_STD(VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap, v4l_print_dv_timings_cap, 0), 1928 IOCTL_INFO_STD(VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap, v4l_print_dv_timings_cap, 0),
@@ -1933,6 +1936,18 @@ bool v4l2_is_known_ioctl(unsigned int cmd)
1933 return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd; 1936 return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
1934} 1937}
1935 1938
1939struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd)
1940{
1941 if (_IOC_NR(cmd) >= V4L2_IOCTLS)
1942 return vdev->lock;
1943 if (test_bit(_IOC_NR(cmd), vdev->disable_locking))
1944 return NULL;
1945 if (vdev->queue && vdev->queue->lock &&
1946 (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
1947 return vdev->queue->lock;
1948 return vdev->lock;
1949}
1950
1936/* Common ioctl debug function. This function can be used by 1951/* Common ioctl debug function. This function can be used by
1937 external ioctl messages as well as internal V4L ioctl */ 1952 external ioctl messages as well as internal V4L ioctl */
1938void v4l_printk_ioctl(const char *prefix, unsigned int cmd) 1953void v4l_printk_ioctl(const char *prefix, unsigned int cmd)
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index a056e6ee1b68..5c416cdc88d5 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -100,6 +100,9 @@ struct video_device
100 /* Control handler associated with this device node. May be NULL. */ 100 /* Control handler associated with this device node. May be NULL. */
101 struct v4l2_ctrl_handler *ctrl_handler; 101 struct v4l2_ctrl_handler *ctrl_handler;
102 102
103 /* vb2_queue associated with this device node. May be NULL. */
104 struct vb2_queue *queue;
105
103 /* Priority state. If NULL, then v4l2_dev->prio will be used. */ 106 /* Priority state. If NULL, then v4l2_dev->prio will be used. */
104 struct v4l2_prio_state *prio; 107 struct v4l2_prio_state *prio;
105 108
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index dfd984f10d42..19e93523c2d8 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -304,6 +304,11 @@ extern int v4l2_video_std_construct(struct v4l2_standard *vs,
304 then do printk(KERN_DEBUG "%s: ", prefix) first. */ 304 then do printk(KERN_DEBUG "%s: ", prefix) first. */
305extern void v4l_printk_ioctl(const char *prefix, unsigned int cmd); 305extern void v4l_printk_ioctl(const char *prefix, unsigned int cmd);
306 306
307/* Internal use only: get the mutex (if any) that we need to lock for the
308 given command. */
309struct video_device;
310extern struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd);
311
307/* names for fancy debug output */ 312/* names for fancy debug output */
308extern const char *v4l2_field_names[]; 313extern const char *v4l2_field_names[];
309extern const char *v4l2_type_names[]; 314extern const char *v4l2_type_names[];
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index a15d1f1b319e..924e95e0a0a6 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -244,12 +244,23 @@ struct vb2_ops {
244 void (*buf_queue)(struct vb2_buffer *vb); 244 void (*buf_queue)(struct vb2_buffer *vb);
245}; 245};
246 246
247struct v4l2_fh;
248
247/** 249/**
248 * struct vb2_queue - a videobuf queue 250 * struct vb2_queue - a videobuf queue
249 * 251 *
250 * @type: queue type (see V4L2_BUF_TYPE_* in linux/videodev2.h 252 * @type: queue type (see V4L2_BUF_TYPE_* in linux/videodev2.h
251 * @io_modes: supported io methods (see vb2_io_modes enum) 253 * @io_modes: supported io methods (see vb2_io_modes enum)
252 * @io_flags: additional io flags (see vb2_fileio_flags enum) 254 * @io_flags: additional io flags (see vb2_fileio_flags enum)
255 * @lock: pointer to a mutex that protects the vb2_queue struct. The
256 * driver can set this to a mutex to let the v4l2 core serialize
257 * the queuing ioctls. If the driver wants to handle locking
258 * itself, then this should be set to NULL. This lock is not used
259 * by the videobuf2 core API.
260 * @owner: The filehandle that 'owns' the buffers, i.e. the filehandle
261 * that called reqbufs, create_buffers or started fileio.
262 * This field is not used by the videobuf2 core API, but it allows
263 * drivers to easily associate an owner filehandle with the queue.
253 * @ops: driver-specific callbacks 264 * @ops: driver-specific callbacks
254 * @mem_ops: memory allocator specific callbacks 265 * @mem_ops: memory allocator specific callbacks
255 * @drv_priv: driver private data 266 * @drv_priv: driver private data
@@ -273,6 +284,8 @@ struct vb2_queue {
273 enum v4l2_buf_type type; 284 enum v4l2_buf_type type;
274 unsigned int io_modes; 285 unsigned int io_modes;
275 unsigned int io_flags; 286 unsigned int io_flags;
287 struct mutex *lock;
288 struct v4l2_fh *owner;
276 289
277 const struct vb2_ops *ops; 290 const struct vb2_ops *ops;
278 const struct vb2_mem_ops *mem_ops; 291 const struct vb2_mem_ops *mem_ops;