diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2009-08-07 12:28:16 +0200 |
---|---|---|
committer | Hans Verkuil <hverkuil@xs4all.nl> | 2009-08-07 12:28:16 +0200 |
commit | f4002f575cdc4c826c424b19d21b8979de737d64 (patch) | |
tree | 7833f15aa255f71bf8c3e121b3965dba16390863 | |
parent | 84ca12cecb8b0b28efb9403b9ea6da6a9589caec (diff) | |
download | mediapointer-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.c | 15 |
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); |