aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/v4l2-core/v4l2-ioctl.c
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-03-10 12:12:25 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-24 11:01:26 -0400
commit73f35418a1e921443b5c9f4c58ae70df8b9d1bb6 (patch)
tree16c3041e01fd356b9bf7ff65b890d9a86f0d45f6 /drivers/media/v4l2-core/v4l2-ioctl.c
parent2180f92def1921397f422f278b3cc65751b749cc (diff)
[media] v4l2-ioctl: check if an ioctl is valid
Just checking if the op exists isn't correct, you should check if the ioctl is valid (which implies that the op exists as well). One exception is g_std: if current_norm is non-zero, then the g_std op may be absent. This sort of weird behavior is one of the reasons why I am trying to get rid of current_norm. This patch fixes the case where the g/s_std op is set, but these ioctls are disabled. This can happen in drivers supporting multiple models, some that have TV input (and support the STD API) and some that have a sensor (and do not support the STD API). In the latter case qv4l2 would still show the Standards combobox. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-ioctl.c')
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 168b51e193cd..72c22fde2b69 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -35,6 +35,8 @@
35 memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \ 35 memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
36 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field)) 36 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
37 37
38#define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls)
39
38struct std_descr { 40struct std_descr {
39 v4l2_std_id std; 41 v4l2_std_id std;
40 const char *descr; 42 const char *descr;
@@ -1005,6 +1007,7 @@ static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
1005static int v4l_enuminput(const struct v4l2_ioctl_ops *ops, 1007static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
1006 struct file *file, void *fh, void *arg) 1008 struct file *file, void *fh, void *arg)
1007{ 1009{
1010 struct video_device *vfd = video_devdata(file);
1008 struct v4l2_input *p = arg; 1011 struct v4l2_input *p = arg;
1009 1012
1010 /* 1013 /*
@@ -1013,11 +1016,11 @@ static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
1013 * driver. If the driver doesn't support these 1016 * driver. If the driver doesn't support these
1014 * for a specific input, it must override these flags. 1017 * for a specific input, it must override these flags.
1015 */ 1018 */
1016 if (ops->vidioc_s_std) 1019 if (is_valid_ioctl(vfd, VIDIOC_S_STD))
1017 p->capabilities |= V4L2_IN_CAP_STD; 1020 p->capabilities |= V4L2_IN_CAP_STD;
1018 if (ops->vidioc_s_dv_preset) 1021 if (is_valid_ioctl(vfd, VIDIOC_S_DV_PRESET))
1019 p->capabilities |= V4L2_IN_CAP_PRESETS; 1022 p->capabilities |= V4L2_IN_CAP_PRESETS;
1020 if (ops->vidioc_s_dv_timings) 1023 if (is_valid_ioctl(vfd, VIDIOC_S_DV_TIMINGS))
1021 p->capabilities |= V4L2_IN_CAP_DV_TIMINGS; 1024 p->capabilities |= V4L2_IN_CAP_DV_TIMINGS;
1022 1025
1023 return ops->vidioc_enum_input(file, fh, p); 1026 return ops->vidioc_enum_input(file, fh, p);
@@ -1026,6 +1029,7 @@ static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
1026static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops, 1029static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
1027 struct file *file, void *fh, void *arg) 1030 struct file *file, void *fh, void *arg)
1028{ 1031{
1032 struct video_device *vfd = video_devdata(file);
1029 struct v4l2_output *p = arg; 1033 struct v4l2_output *p = arg;
1030 1034
1031 /* 1035 /*
@@ -1034,11 +1038,11 @@ static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
1034 * driver. If the driver doesn't support these 1038 * driver. If the driver doesn't support these
1035 * for a specific output, it must override these flags. 1039 * for a specific output, it must override these flags.
1036 */ 1040 */
1037 if (ops->vidioc_s_std) 1041 if (is_valid_ioctl(vfd, VIDIOC_S_STD))
1038 p->capabilities |= V4L2_OUT_CAP_STD; 1042 p->capabilities |= V4L2_OUT_CAP_STD;
1039 if (ops->vidioc_s_dv_preset) 1043 if (is_valid_ioctl(vfd, VIDIOC_S_DV_PRESET))
1040 p->capabilities |= V4L2_OUT_CAP_PRESETS; 1044 p->capabilities |= V4L2_OUT_CAP_PRESETS;
1041 if (ops->vidioc_s_dv_timings) 1045 if (is_valid_ioctl(vfd, VIDIOC_S_DV_TIMINGS))
1042 p->capabilities |= V4L2_OUT_CAP_DV_TIMINGS; 1046 p->capabilities |= V4L2_OUT_CAP_DV_TIMINGS;
1043 1047
1044 return ops->vidioc_enum_output(file, fh, p); 1048 return ops->vidioc_enum_output(file, fh, p);
@@ -1521,7 +1525,7 @@ static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
1521 p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 1525 p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1522 return -EINVAL; 1526 return -EINVAL;
1523 p->parm.capture.readbuffers = 2; 1527 p->parm.capture.readbuffers = 2;
1524 if (ops->vidioc_g_std) 1528 if (is_valid_ioctl(vfd, VIDIOC_G_STD) && ops->vidioc_g_std)
1525 ret = ops->vidioc_g_std(file, fh, &std); 1529 ret = ops->vidioc_g_std(file, fh, &std);
1526 if (ret == 0) 1530 if (ret == 0)
1527 v4l2_video_std_frame_period(std, 1531 v4l2_video_std_frame_period(std,
@@ -1881,7 +1885,7 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
1881 return -EINVAL; 1885 return -EINVAL;
1882 if (ops->vidioc_enum_freq_bands) 1886 if (ops->vidioc_enum_freq_bands)
1883 return ops->vidioc_enum_freq_bands(file, fh, p); 1887 return ops->vidioc_enum_freq_bands(file, fh, p);
1884 if (ops->vidioc_g_tuner) { 1888 if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
1885 struct v4l2_tuner t = { 1889 struct v4l2_tuner t = {
1886 .index = p->tuner, 1890 .index = p->tuner,
1887 .type = type, 1891 .type = type,
@@ -1899,7 +1903,7 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
1899 V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB; 1903 V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
1900 return 0; 1904 return 0;
1901 } 1905 }
1902 if (ops->vidioc_g_modulator) { 1906 if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) {
1903 struct v4l2_modulator m = { 1907 struct v4l2_modulator m = {
1904 .index = p->tuner, 1908 .index = p->tuner,
1905 }; 1909 };