summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/v4l2-dev.c14
-rw-r--r--drivers/media/video/v4l2-ioctl.c189
2 files changed, 113 insertions, 90 deletions
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 70bec548d904..e4a9ed67bb2e 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -322,11 +322,19 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
int ret = -ENODEV;
if (vdev->fops->unlocked_ioctl) {
- if (vdev->lock && mutex_lock_interruptible(vdev->lock))
- return -ERESTARTSYS;
+ bool locked = false;
+
+ if (vdev->lock) {
+ /* always lock unless the cmd is marked as "don't use lock" */
+ locked = !v4l2_is_known_ioctl(cmd) ||
+ !test_bit(_IOC_NR(cmd), vdev->dont_use_lock);
+
+ if (locked && mutex_lock_interruptible(vdev->lock))
+ return -ERESTARTSYS;
+ }
if (video_is_registered(vdev))
ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
- if (vdev->lock)
+ if (locked)
mutex_unlock(vdev->lock);
} else if (vdev->fops->ioctl) {
/* This code path is a replacement for the BKL. It is a major
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 5b2ec1fd2d0a..ef44b084132a 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -195,93 +195,106 @@ static const char *v4l2_memory_names[] = {
/* ------------------------------------------------------------------ */
/* debug help functions */
-static const char *v4l2_ioctls[] = {
- [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
- [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
- [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
- [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
- [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
- [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
- [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
- [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
- [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
- [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
- [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
- [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
- [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
- [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
- [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
- [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
- [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
- [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
- [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
- [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
- [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
- [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
- [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
- [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
- [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
- [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
- [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
- [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
- [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
- [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
- [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
- [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
- [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
- [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
- [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
- [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
- [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
- [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
- [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
- [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
- [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
- [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
- [_IOC_NR(VIDIOC_G_SELECTION)] = "VIDIOC_G_SELECTION",
- [_IOC_NR(VIDIOC_S_SELECTION)] = "VIDIOC_S_SELECTION",
- [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
- [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
- [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
- [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
- [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
- [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
- [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
- [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
- [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
- [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
- [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
- [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
- [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
-#if 1
- [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
- [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
- [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
- [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
- [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
-
- [_IOC_NR(VIDIOC_DECODER_CMD)] = "VIDIOC_DECODER_CMD",
- [_IOC_NR(VIDIOC_TRY_DECODER_CMD)] = "VIDIOC_TRY_DECODER_CMD",
- [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
- [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
-
- [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT",
- [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK",
-#endif
- [_IOC_NR(VIDIOC_ENUM_DV_PRESETS)] = "VIDIOC_ENUM_DV_PRESETS",
- [_IOC_NR(VIDIOC_S_DV_PRESET)] = "VIDIOC_S_DV_PRESET",
- [_IOC_NR(VIDIOC_G_DV_PRESET)] = "VIDIOC_G_DV_PRESET",
- [_IOC_NR(VIDIOC_QUERY_DV_PRESET)] = "VIDIOC_QUERY_DV_PRESET",
- [_IOC_NR(VIDIOC_S_DV_TIMINGS)] = "VIDIOC_S_DV_TIMINGS",
- [_IOC_NR(VIDIOC_G_DV_TIMINGS)] = "VIDIOC_G_DV_TIMINGS",
- [_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT",
- [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT",
- [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
- [_IOC_NR(VIDIOC_CREATE_BUFS)] = "VIDIOC_CREATE_BUFS",
- [_IOC_NR(VIDIOC_PREPARE_BUF)] = "VIDIOC_PREPARE_BUF",
+
+struct v4l2_ioctl_info {
+ unsigned int ioctl;
+ const char * const name;
+};
+
+#define IOCTL_INFO(_ioctl) [_IOC_NR(_ioctl)] = { \
+ .ioctl = _ioctl, \
+ .name = #_ioctl, \
+}
+
+static struct v4l2_ioctl_info v4l2_ioctls[] = {
+ IOCTL_INFO(VIDIOC_QUERYCAP),
+ IOCTL_INFO(VIDIOC_ENUM_FMT),
+ IOCTL_INFO(VIDIOC_G_FMT),
+ IOCTL_INFO(VIDIOC_S_FMT),
+ IOCTL_INFO(VIDIOC_REQBUFS),
+ IOCTL_INFO(VIDIOC_QUERYBUF),
+ IOCTL_INFO(VIDIOC_G_FBUF),
+ IOCTL_INFO(VIDIOC_S_FBUF),
+ IOCTL_INFO(VIDIOC_OVERLAY),
+ IOCTL_INFO(VIDIOC_QBUF),
+ IOCTL_INFO(VIDIOC_DQBUF),
+ IOCTL_INFO(VIDIOC_STREAMON),
+ IOCTL_INFO(VIDIOC_STREAMOFF),
+ IOCTL_INFO(VIDIOC_G_PARM),
+ IOCTL_INFO(VIDIOC_S_PARM),
+ IOCTL_INFO(VIDIOC_G_STD),
+ IOCTL_INFO(VIDIOC_S_STD),
+ IOCTL_INFO(VIDIOC_ENUMSTD),
+ IOCTL_INFO(VIDIOC_ENUMINPUT),
+ IOCTL_INFO(VIDIOC_G_CTRL),
+ IOCTL_INFO(VIDIOC_S_CTRL),
+ IOCTL_INFO(VIDIOC_G_TUNER),
+ IOCTL_INFO(VIDIOC_S_TUNER),
+ IOCTL_INFO(VIDIOC_G_AUDIO),
+ IOCTL_INFO(VIDIOC_S_AUDIO),
+ IOCTL_INFO(VIDIOC_QUERYCTRL),
+ IOCTL_INFO(VIDIOC_QUERYMENU),
+ IOCTL_INFO(VIDIOC_G_INPUT),
+ IOCTL_INFO(VIDIOC_S_INPUT),
+ IOCTL_INFO(VIDIOC_G_OUTPUT),
+ IOCTL_INFO(VIDIOC_S_OUTPUT),
+ IOCTL_INFO(VIDIOC_ENUMOUTPUT),
+ IOCTL_INFO(VIDIOC_G_AUDOUT),
+ IOCTL_INFO(VIDIOC_S_AUDOUT),
+ IOCTL_INFO(VIDIOC_G_MODULATOR),
+ IOCTL_INFO(VIDIOC_S_MODULATOR),
+ IOCTL_INFO(VIDIOC_G_FREQUENCY),
+ IOCTL_INFO(VIDIOC_S_FREQUENCY),
+ IOCTL_INFO(VIDIOC_CROPCAP),
+ IOCTL_INFO(VIDIOC_G_CROP),
+ IOCTL_INFO(VIDIOC_S_CROP),
+ IOCTL_INFO(VIDIOC_G_SELECTION),
+ IOCTL_INFO(VIDIOC_S_SELECTION),
+ IOCTL_INFO(VIDIOC_G_JPEGCOMP),
+ IOCTL_INFO(VIDIOC_S_JPEGCOMP),
+ IOCTL_INFO(VIDIOC_QUERYSTD),
+ IOCTL_INFO(VIDIOC_TRY_FMT),
+ IOCTL_INFO(VIDIOC_ENUMAUDIO),
+ IOCTL_INFO(VIDIOC_ENUMAUDOUT),
+ IOCTL_INFO(VIDIOC_G_PRIORITY),
+ IOCTL_INFO(VIDIOC_S_PRIORITY),
+ IOCTL_INFO(VIDIOC_G_SLICED_VBI_CAP),
+ IOCTL_INFO(VIDIOC_LOG_STATUS),
+ IOCTL_INFO(VIDIOC_G_EXT_CTRLS),
+ IOCTL_INFO(VIDIOC_S_EXT_CTRLS),
+ IOCTL_INFO(VIDIOC_TRY_EXT_CTRLS),
+ IOCTL_INFO(VIDIOC_ENUM_FRAMESIZES),
+ IOCTL_INFO(VIDIOC_ENUM_FRAMEINTERVALS),
+ IOCTL_INFO(VIDIOC_G_ENC_INDEX),
+ IOCTL_INFO(VIDIOC_ENCODER_CMD),
+ IOCTL_INFO(VIDIOC_TRY_ENCODER_CMD),
+ IOCTL_INFO(VIDIOC_DECODER_CMD),
+ IOCTL_INFO(VIDIOC_TRY_DECODER_CMD),
+ IOCTL_INFO(VIDIOC_DBG_S_REGISTER),
+ IOCTL_INFO(VIDIOC_DBG_G_REGISTER),
+ IOCTL_INFO(VIDIOC_DBG_G_CHIP_IDENT),
+ IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK),
+ IOCTL_INFO(VIDIOC_ENUM_DV_PRESETS),
+ IOCTL_INFO(VIDIOC_S_DV_PRESET),
+ IOCTL_INFO(VIDIOC_G_DV_PRESET),
+ IOCTL_INFO(VIDIOC_QUERY_DV_PRESET),
+ IOCTL_INFO(VIDIOC_S_DV_TIMINGS),
+ IOCTL_INFO(VIDIOC_G_DV_TIMINGS),
+ IOCTL_INFO(VIDIOC_DQEVENT),
+ IOCTL_INFO(VIDIOC_SUBSCRIBE_EVENT),
+ IOCTL_INFO(VIDIOC_UNSUBSCRIBE_EVENT),
+ IOCTL_INFO(VIDIOC_CREATE_BUFS),
+ IOCTL_INFO(VIDIOC_PREPARE_BUF),
};
#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
+bool v4l2_is_known_ioctl(unsigned int cmd)
+{
+ if (_IOC_NR(cmd) >= V4L2_IOCTLS)
+ return false;
+ return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
+}
+
/* Common ioctl debug function. This function can be used by
external ioctl messages as well as internal V4L ioctl */
void v4l_printk_ioctl(unsigned int cmd)
@@ -297,7 +310,7 @@ void v4l_printk_ioctl(unsigned int cmd)
type = "v4l2";
break;
}
- printk("%s", v4l2_ioctls[_IOC_NR(cmd)]);
+ printk("%s", v4l2_ioctls[_IOC_NR(cmd)].name);
return;
default:
type = "unknown";
@@ -1948,9 +1961,9 @@ static long __video_do_ioctl(struct file *file,
vfd->v4l2_dev->name);
break;
}
-#ifdef CONFIG_VIDEO_ADV_DEBUG
case VIDIOC_DBG_G_REGISTER:
{
+#ifdef CONFIG_VIDEO_ADV_DEBUG
struct v4l2_dbg_register *p = arg;
if (ops->vidioc_g_register) {
@@ -1959,10 +1972,12 @@ static long __video_do_ioctl(struct file *file,
else
ret = ops->vidioc_g_register(file, fh, p);
}
+#endif
break;
}
case VIDIOC_DBG_S_REGISTER:
{
+#ifdef CONFIG_VIDEO_ADV_DEBUG
struct v4l2_dbg_register *p = arg;
if (ops->vidioc_s_register) {
@@ -1971,9 +1986,9 @@ static long __video_do_ioctl(struct file *file,
else
ret = ops->vidioc_s_register(file, fh, p);
}
+#endif
break;
}
-#endif
case VIDIOC_DBG_G_CHIP_IDENT:
{
struct v4l2_dbg_chip_ident *p = arg;