From: Hans Verkuil Date: Fri, 7 Aug 2009 10:28:16 +0000 (-0300) Subject: V4L/DVB (12429): v4l2-ioctl: fix G_STD and G_PARM default handlers X-Git-Tag: MMI-PSA29.97-13-9~27154^2~6 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=9bedc7f7fe803c17d26b5fcf5786b50a7cf40def;p=GitHub%2FMotorolaMobilityLLC%2Fkernel-slsi.git V4L/DVB (12429): v4l2-ioctl: fix G_STD and G_PARM default handlers 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. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index be64a502ea27..f2afc4e08379 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -1081,8 +1081,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); @@ -1553,12 +1555,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);