Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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: Mauro Carvalho Chehab <mchehab@redhat.com>

+28 -3
+28 -3
drivers/media/video/em28xx/em28xx-video.c
··· 1387 1387 return -EINVAL; 1388 1388 } 1389 1389 1390 + /* 1391 + * FIXME: This is an indirect way to check if a control exists at a 1392 + * subdev. Instead of that hack, maybe the better would be to change all 1393 + * subdevs to return -ENOIOCTLCMD, if an ioctl is not supported. 1394 + */ 1395 + static int check_subdev_ctrl(struct em28xx *dev, int id) 1396 + { 1397 + struct v4l2_queryctrl qc; 1398 + 1399 + memset(&qc, 0, sizeof(qc)); 1400 + qc.id = id; 1401 + 1402 + /* enumerate V4L2 device controls */ 1403 + v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, &qc); 1404 + 1405 + if (qc.type) 1406 + return 0; 1407 + else 1408 + return -EINVAL; 1409 + } 1410 + 1390 1411 static int vidioc_g_ctrl(struct file *file, void *priv, 1391 1412 struct v4l2_control *ctrl) 1392 1413 { ··· 1420 1399 return rc; 1421 1400 rc = 0; 1422 1401 1423 - 1424 1402 /* Set an AC97 control */ 1425 1403 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) 1426 1404 rc = ac97_get_ctrl(dev, ctrl); ··· 1428 1408 1429 1409 /* It were not an AC97 control. Sends it to the v4l2 dev interface */ 1430 1410 if (rc == 1) { 1411 + if (check_subdev_ctrl(dev, ctrl->id)) 1412 + return -EINVAL; 1413 + 1431 1414 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl); 1432 1415 rc = 0; 1433 1416 } ··· 1457 1434 1458 1435 /* It isn't an AC97 control. Sends it to the v4l2 dev interface */ 1459 1436 if (rc == 1) { 1460 - rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0, core, s_ctrl, ctrl); 1461 - 1437 + rc = check_subdev_ctrl(dev, ctrl->id); 1438 + if (!rc) 1439 + v4l2_device_call_all(&dev->v4l2_dev, 0, 1440 + core, s_ctrl, ctrl); 1462 1441 /* 1463 1442 * In the case of non-AC97 volume controls, we still need 1464 1443 * to do some setups at em28xx, in order to mute/unmute