提交 fb8decfa 编写于 作者: M Mauro Carvalho Chehab

[media] em28xx: properly handle subdev controls

Subdev controls return codes are evil, as they return -EINVAL to mean
both unsupported and invalid arguments. Due to that, we need to use a
trick to identify what controls are supported by a subdev.
Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
上级 78e51566
...@@ -1387,6 +1387,27 @@ static int vidioc_queryctrl(struct file *file, void *priv, ...@@ -1387,6 +1387,27 @@ static int vidioc_queryctrl(struct file *file, void *priv,
return -EINVAL; return -EINVAL;
} }
/*
* FIXME: This is an indirect way to check if a control exists at a
* subdev. Instead of that hack, maybe the better would be to change all
* subdevs to return -ENOIOCTLCMD, if an ioctl is not supported.
*/
static int check_subdev_ctrl(struct em28xx *dev, int id)
{
struct v4l2_queryctrl qc;
memset(&qc, 0, sizeof(qc));
qc.id = id;
/* enumerate V4L2 device controls */
v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, &qc);
if (qc.type)
return 0;
else
return -EINVAL;
}
static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl) struct v4l2_control *ctrl)
{ {
...@@ -1399,7 +1420,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv, ...@@ -1399,7 +1420,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
return rc; return rc;
rc = 0; rc = 0;
/* Set an AC97 control */ /* Set an AC97 control */
if (dev->audio_mode.ac97 != EM28XX_NO_AC97) if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
rc = ac97_get_ctrl(dev, ctrl); rc = ac97_get_ctrl(dev, ctrl);
...@@ -1408,6 +1428,9 @@ static int vidioc_g_ctrl(struct file *file, void *priv, ...@@ -1408,6 +1428,9 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
/* It were not an AC97 control. Sends it to the v4l2 dev interface */ /* It were not an AC97 control. Sends it to the v4l2 dev interface */
if (rc == 1) { if (rc == 1) {
if (check_subdev_ctrl(dev, ctrl->id))
return -EINVAL;
v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl); v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
rc = 0; rc = 0;
} }
...@@ -1434,8 +1457,10 @@ static int vidioc_s_ctrl(struct file *file, void *priv, ...@@ -1434,8 +1457,10 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
/* It isn't an AC97 control. Sends it to the v4l2 dev interface */ /* It isn't an AC97 control. Sends it to the v4l2 dev interface */
if (rc == 1) { if (rc == 1) {
rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0, core, s_ctrl, ctrl); rc = check_subdev_ctrl(dev, ctrl->id);
if (!rc)
v4l2_device_call_all(&dev->v4l2_dev, 0,
core, s_ctrl, ctrl);
/* /*
* In the case of non-AC97 volume controls, we still need * In the case of non-AC97 volume controls, we still need
* to do some setups at em28xx, in order to mute/unmute * to do some setups at em28xx, in order to mute/unmute
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册