summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-08-07 12:28:16 +0200
committerHans Verkuil <hverkuil@xs4all.nl>2009-08-07 12:28:16 +0200
commitf4002f575cdc4c826c424b19d21b8979de737d64 (patch)
tree7833f15aa255f71bf8c3e121b3965dba16390863
parent84ca12cecb8b0b28efb9403b9ea6da6a9589caec (diff)
downloadmediapointer-dvb-s2-f4002f575cdc4c826c424b19d21b8979de737d64.tar.gz
mediapointer-dvb-s2-f4002f575cdc4c826c424b19d21b8979de737d64.tar.bz2
v4l2-ioctl: fix G_STD and G_PARM default handlers
From: Hans Verkuil <hverkuil@xs4all.nl> The v4l core supplies default handlers for G_STD and G_PARM. However, both default handlers are buggy. This patch fixes the following: 1) If no g_std is supplied and current_norm == 0, then this driver does not support TV video standards (e.g. a radio or webcam driver). Return -EINVAL. This ensures that there is no bogus VIDIOC_G_STD support for such drivers. 2) The default VIDIOC_G_PARM handler used current_norm instead of first checking if the driver supported g_std and calling that to get the norm. It also didn't check if current_norm was 0, since in that case the driver does not support TV standards (or no standard was set at all) and the default handler should return -EINVAL. Note that I am very unhappy with these default handlers: I think they basically behave like some very strange and unexpected side-effect. Priority: normal Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
-rw-r--r--linux/drivers/media/video/v4l2-ioctl.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/linux/drivers/media/video/v4l2-ioctl.c b/linux/drivers/media/video/v4l2-ioctl.c
index 80c94dc5a..d746d9555 100644
--- a/linux/drivers/media/video/v4l2-ioctl.c
+++ b/linux/drivers/media/video/v4l2-ioctl.c
@@ -1088,8 +1088,10 @@ static long __video_do_ioctl(struct file *file,
/* Calls the specific handler */
if (ops->vidioc_g_std)
ret = ops->vidioc_g_std(file, fh, id);
- else
+ else if (vfd->current_norm)
*id = vfd->current_norm;
+ else
+ ret = -EINVAL;
if (!ret)
dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
@@ -1560,12 +1562,19 @@ static long __video_do_ioctl(struct file *file,
break;
ret = ops->vidioc_g_parm(file, fh, p);
} else {
+ v4l2_std_id std = vfd->current_norm;
+
if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- v4l2_video_std_frame_period(vfd->current_norm,
- &p->parm.capture.timeperframe);
ret = 0;
+ if (ops->vidioc_g_std)
+ ret = ops->vidioc_g_std(file, fh, &std);
+ else if (std == 0)
+ ret = -EINVAL;
+ if (ret == 0)
+ v4l2_video_std_frame_period(std,
+ &p->parm.capture.timeperframe);
}
dbgarg(cmd, "type=%d\n", p->type);