aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKieran Bingham <kieran.bingham@ideasonboard.com>2018-03-21 11:43:08 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-06-05 09:33:51 -0400
commit0dc68cabdb626e33d02561529e6a4c681b72a784 (patch)
tree700e5bfc8627f1ddb20c8c754032777a2ea14188
parenta00031c159748f322f771f3c1d5ed944cba4bd30 (diff)
media: uvcvideo: Prevent setting unavailable flags
The addition of an extra operation to use the GET_INFO command overwrites all existing flags from the uvc_ctrls table. This includes setting all controls as supporting GET_MIN, GET_MAX, GET_RES, and GET_DEF regardless of whether they do or not. Move the initialisation of these control capabilities directly to the uvc_ctrl_fill_xu_info() call where they were originally located in that use case, and ensure that the new functionality in uvc_ctrl_get_flags() will only set flags based on their reported capability from the GET_INFO call. Fixes: 859086ae3636 ("media: uvcvideo: Apply flags from device to actual properties") Cc: stable@vger.kernel.org Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Tested-by: Guennadi Liakhovetski <guennadi.liakhovetski@intel.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
-rw-r--r--drivers/media/usb/uvc/uvc_ctrl.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index 102594ec3e97..a36b4fb949fa 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -1607,14 +1607,12 @@ static int uvc_ctrl_get_flags(struct uvc_device *dev,
1607 ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum, 1607 ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum,
1608 info->selector, data, 1); 1608 info->selector, data, 1);
1609 if (!ret) 1609 if (!ret)
1610 info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX 1610 info->flags |= (data[0] & UVC_CONTROL_CAP_GET ?
1611 | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF 1611 UVC_CTRL_FLAG_GET_CUR : 0)
1612 | (data[0] & UVC_CONTROL_CAP_GET ? 1612 | (data[0] & UVC_CONTROL_CAP_SET ?
1613 UVC_CTRL_FLAG_GET_CUR : 0) 1613 UVC_CTRL_FLAG_SET_CUR : 0)
1614 | (data[0] & UVC_CONTROL_CAP_SET ? 1614 | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?
1615 UVC_CTRL_FLAG_SET_CUR : 0) 1615 UVC_CTRL_FLAG_AUTO_UPDATE : 0);
1616 | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?
1617 UVC_CTRL_FLAG_AUTO_UPDATE : 0);
1618 1616
1619 kfree(data); 1617 kfree(data);
1620 return ret; 1618 return ret;
@@ -1689,6 +1687,9 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
1689 1687
1690 info->size = le16_to_cpup((__le16 *)data); 1688 info->size = le16_to_cpup((__le16 *)data);
1691 1689
1690 info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
1691 | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF;
1692
1692 ret = uvc_ctrl_get_flags(dev, ctrl, info); 1693 ret = uvc_ctrl_get_flags(dev, ctrl, info);
1693 if (ret < 0) { 1694 if (ret < 0) {
1694 uvc_trace(UVC_TRACE_CONTROL, 1695 uvc_trace(UVC_TRACE_CONTROL,