Commit 9bedc7f7 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

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: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 99362e1e
...@@ -1081,8 +1081,10 @@ static long __video_do_ioctl(struct file *file, ...@@ -1081,8 +1081,10 @@ static long __video_do_ioctl(struct file *file,
/* Calls the specific handler */ /* Calls the specific handler */
if (ops->vidioc_g_std) if (ops->vidioc_g_std)
ret = ops->vidioc_g_std(file, fh, id); ret = ops->vidioc_g_std(file, fh, id);
else else if (vfd->current_norm)
*id = vfd->current_norm; *id = vfd->current_norm;
else
ret = -EINVAL;
if (!ret) if (!ret)
dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id); dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
...@@ -1553,12 +1555,19 @@ static long __video_do_ioctl(struct file *file, ...@@ -1553,12 +1555,19 @@ static long __video_do_ioctl(struct file *file,
break; break;
ret = ops->vidioc_g_parm(file, fh, p); ret = ops->vidioc_g_parm(file, fh, p);
} else { } else {
v4l2_std_id std = vfd->current_norm;
if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL; return -EINVAL;
v4l2_video_std_frame_period(vfd->current_norm,
&p->parm.capture.timeperframe);
ret = 0; 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); dbgarg(cmd, "type=%d\n", p->type);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment