소스 검색

V4L/DVB (10192): em28xx: fix input selection

em28xx were trying to access the third input entry, even for boards that
don't support it.

This patch reviews the input mux selection fixing this bug and a few
other troubles, like not validating the input on one userspace ioctl.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Mauro Carvalho Chehab 16 년 전
부모
커밋
24c3c41584
1개의 변경된 파일23개의 추가작업 그리고 18개의 파일을 삭제
  1. 23 18
      drivers/media/video/em28xx/em28xx-video.c

+ 23 - 18
drivers/media/video/em28xx/em28xx-video.c

@@ -886,10 +886,10 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
 	if (0 == INPUT(i)->type)
 		return -EINVAL;
 
-	mutex_lock(&dev->lock);
-
-	video_mux(dev, i);
+	dev->ctl_input = i;
 
+	mutex_lock(&dev->lock);
+	video_mux(dev, dev->ctl_input);
 	mutex_unlock(&dev->lock);
 	return 0;
 }
@@ -939,6 +939,12 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
 	struct em28xx_fh   *fh  = priv;
 	struct em28xx      *dev = fh->dev;
 
+
+	if (a->index >= MAX_EM28XX_INPUT)
+		return -EINVAL;
+	if (0 == INPUT(a->index)->type)
+		return -EINVAL;
+
 	mutex_lock(&dev->lock);
 
 	dev->ctl_ainput = INPUT(a->index)->amux;
@@ -1957,9 +1963,22 @@ int em28xx_register_analog_devices(struct em28xx *dev)
 		(EM28XX_VERSION_CODE >> 16) & 0xff,
 		(EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
 
+	/* set default norm */
+	dev->norm = em28xx_video_template.current_norm;
+	dev->width = norm_maxw(dev);
+	dev->height = norm_maxh(dev);
+	dev->interlaced = EM28XX_INTERLACED_DEFAULT;
+	dev->hscale = 0;
+	dev->vscale = 0;
+	dev->ctl_input = 0;
+
 	/* Analog specific initialization */
 	dev->format = &format[0];
-	video_mux(dev, 0);
+	video_mux(dev, dev->ctl_input);
+
+	/* Audio defaults */
+	dev->mute = 1;
+	dev->volume = 0x1f;
 
 	/* enable vbi capturing */
 
@@ -1967,24 +1986,10 @@ int em28xx_register_analog_devices(struct em28xx *dev)
 /*	em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */
 	em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
 
-	dev->mute = 1;		/* maybe not the right place... */
-	dev->volume = 0x1f;
-
 	em28xx_set_outfmt(dev);
 	em28xx_colorlevels_set_default(dev);
 	em28xx_compression_disable(dev);
 
-	/* set default norm */
-	dev->norm = em28xx_video_template.current_norm;
-	dev->width = norm_maxw(dev);
-	dev->height = norm_maxh(dev);
-	dev->interlaced = EM28XX_INTERLACED_DEFAULT;
-	dev->hscale = 0;
-	dev->vscale = 0;
-
-	/* FIXME: This is a very bad hack! Not all devices have TV on input 2 */
-	dev->ctl_input = 2;
-
 	/* allocate and fill video video_device struct */
 	dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
 	if (!dev->vdev) {