浏览代码

V4L/DVB (8116): videodev: allow PRIVATE_BASE controls when called through VIDIOC_G/S_CTRL.

V4L2_CID_PRIVATE_BASE controls are not allowed when called from
VIDIOC_S/G_EXT_CTRL as extended controls use a better mechanism
for private controls. But still allow it when called from the
VIDIOC_G/S_CTRL to extended control conversion in video_ioctl2()
for backwards compatibility.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Hans Verkuil 17 年之前
父节点
当前提交
6264c80661
共有 1 个文件被更改,包括 11 次插入8 次删除
  1. 11 8
      drivers/media/video/videodev.c

+ 11 - 8
drivers/media/video/videodev.c

@@ -710,7 +710,7 @@ static inline void v4l_print_ext_ctrls(unsigned int cmd,
 	printk(KERN_CONT "\n");
 	printk(KERN_CONT "\n");
 };
 };
 
 
-static inline int check_ext_ctrls(struct v4l2_ext_controls *c)
+static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
 {
 {
 	__u32 i;
 	__u32 i;
 
 
@@ -721,8 +721,11 @@ static inline int check_ext_ctrls(struct v4l2_ext_controls *c)
 		c->controls[i].reserved2[1] = 0;
 		c->controls[i].reserved2[1] = 0;
 	}
 	}
 	/* V4L2_CID_PRIVATE_BASE cannot be used as control class
 	/* V4L2_CID_PRIVATE_BASE cannot be used as control class
-	 * when using extended controls. */
-	if (c->ctrl_class == V4L2_CID_PRIVATE_BASE)
+	   when using extended controls.
+	   Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
+	   is it allowed for backwards compatibility.
+	 */
+	if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
 		return 0;
 		return 0;
 	/* Check that all controls are from the same control class. */
 	/* Check that all controls are from the same control class. */
 	for (i = 0; i < c->count; i++) {
 	for (i = 0; i < c->count; i++) {
@@ -1426,7 +1429,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
 			ctrls.controls = &ctrl;
 			ctrls.controls = &ctrl;
 			ctrl.id = p->id;
 			ctrl.id = p->id;
 			ctrl.value = p->value;
 			ctrl.value = p->value;
-			if (check_ext_ctrls(&ctrls)) {
+			if (check_ext_ctrls(&ctrls, 1)) {
 				ret = vfd->vidioc_g_ext_ctrls(file, fh, &ctrls);
 				ret = vfd->vidioc_g_ext_ctrls(file, fh, &ctrls);
 				if (ret == 0)
 				if (ret == 0)
 					p->value = ctrl.value;
 					p->value = ctrl.value;
@@ -1462,7 +1465,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
 		ctrls.controls = &ctrl;
 		ctrls.controls = &ctrl;
 		ctrl.id = p->id;
 		ctrl.id = p->id;
 		ctrl.value = p->value;
 		ctrl.value = p->value;
-		if (check_ext_ctrls(&ctrls))
+		if (check_ext_ctrls(&ctrls, 1))
 			ret = vfd->vidioc_s_ext_ctrls(file, fh, &ctrls);
 			ret = vfd->vidioc_s_ext_ctrls(file, fh, &ctrls);
 		break;
 		break;
 	}
 	}
@@ -1473,7 +1476,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
 		p->error_idx = p->count;
 		p->error_idx = p->count;
 		if (!vfd->vidioc_g_ext_ctrls)
 		if (!vfd->vidioc_g_ext_ctrls)
 			break;
 			break;
-		if (check_ext_ctrls(p))
+		if (check_ext_ctrls(p, 0))
 			ret = vfd->vidioc_g_ext_ctrls(file, fh, p);
 			ret = vfd->vidioc_g_ext_ctrls(file, fh, p);
 		v4l_print_ext_ctrls(cmd, vfd, p, !ret);
 		v4l_print_ext_ctrls(cmd, vfd, p, !ret);
 		break;
 		break;
@@ -1486,7 +1489,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
 		if (!vfd->vidioc_s_ext_ctrls)
 		if (!vfd->vidioc_s_ext_ctrls)
 			break;
 			break;
 		v4l_print_ext_ctrls(cmd, vfd, p, 1);
 		v4l_print_ext_ctrls(cmd, vfd, p, 1);
-		if (check_ext_ctrls(p))
+		if (check_ext_ctrls(p, 0))
 			ret = vfd->vidioc_s_ext_ctrls(file, fh, p);
 			ret = vfd->vidioc_s_ext_ctrls(file, fh, p);
 		break;
 		break;
 	}
 	}
@@ -1498,7 +1501,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
 		if (!vfd->vidioc_try_ext_ctrls)
 		if (!vfd->vidioc_try_ext_ctrls)
 			break;
 			break;
 		v4l_print_ext_ctrls(cmd, vfd, p, 1);
 		v4l_print_ext_ctrls(cmd, vfd, p, 1);
-		if (check_ext_ctrls(p))
+		if (check_ext_ctrls(p, 0))
 			ret = vfd->vidioc_try_ext_ctrls(file, fh, p);
 			ret = vfd->vidioc_try_ext_ctrls(file, fh, p);
 		break;
 		break;
 	}
 	}