diff options
author | Kieran Bingham <kieran.bingham@ideasonboard.com> | 2018-03-21 11:43:08 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-06-05 09:33:51 -0400 |
commit | 0dc68cabdb626e33d02561529e6a4c681b72a784 (patch) | |
tree | 700e5bfc8627f1ddb20c8c754032777a2ea14188 | |
parent | a00031c159748f322f771f3c1d5ed944cba4bd30 (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.c | 17 |
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, |