4.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Schaefer dhs@frame.work
[ Upstream commit 86419686e66da5b90a07fb8a40ab138fe97189b5 ]
When the UVC device has a control that is readonly it doesn't set the SET_CUR flag. For example the privacy control has SET_CUR flag set in the defaults in the `uvc_ctrls` variable. Even if the device does not have it set, it's not cleared by uvc_ctrl_get_flags().
Originally written with assignment in commit 859086ae3636 ("media: uvcvideo: Apply flags from device to actual properties"). But changed to |= in commit 0dc68cabdb62 ("media: uvcvideo: Prevent setting unavailable flags"). It would not clear the default flags.
With this patch applied the correct flags are reported to user space. Tested with:
```
v4l2-ctl --list-ctrls | grep privacy
privacy 0x009a0910 (bool) : default=0 value=0 flags=read-only ```
Signed-off-by: Daniel Schaefer dhs@frame.work Fixes: 0dc68cabdb62 ("media: uvcvideo: Prevent setting unavailable flags") Reviewed-by: Ricardo Ribalda ribalda@chromium.org Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Link: https://lore.kernel.org/r/20240602065053.36850-1-dhs@frame.work Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/uvc/uvc_ctrl.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 5d437e33c5902..dee07b0572c6f 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1739,7 +1739,13 @@ static int uvc_ctrl_get_flags(struct uvc_device *dev, else ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum, info->selector, data, 1); - if (!ret) + + if (!ret) { + info->flags &= ~(UVC_CTRL_FLAG_GET_CUR | + UVC_CTRL_FLAG_SET_CUR | + UVC_CTRL_FLAG_AUTO_UPDATE | + UVC_CTRL_FLAG_ASYNCHRONOUS); + info->flags |= (data[0] & UVC_CONTROL_CAP_GET ? UVC_CTRL_FLAG_GET_CUR : 0) | (data[0] & UVC_CONTROL_CAP_SET ? @@ -1748,6 +1754,7 @@ static int uvc_ctrl_get_flags(struct uvc_device *dev, UVC_CTRL_FLAG_AUTO_UPDATE : 0) | (data[0] & UVC_CONTROL_CAP_ASYNCHRONOUS ? UVC_CTRL_FLAG_ASYNCHRONOUS : 0); + }
kfree(data); return ret;