Hi, On 14-Nov-24 8:10 PM, Ricardo Ribalda wrote: > From: Yunke Cao <yunkec@xxxxxxxxxx> > > This patch adds support for compound controls. This is required to > support controls that cannot be represented with a s64 data, such as the > Region of Interest. > > Signed-off-by: Yunke Cao <yunkec@xxxxxxxxxx> > Signed-off-by: Ricardo Ribalda <ribalda@xxxxxxxxxxxx> > --- > drivers/media/usb/uvc/uvc_ctrl.c | 224 ++++++++++++++++++++++++++++++++------- > drivers/media/usb/uvc/uvcvideo.h | 5 + > 2 files changed, 192 insertions(+), 37 deletions(-) > > diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c > index 893d12cd3f90..e51cd0a2228a 100644 > --- a/drivers/media/usb/uvc/uvc_ctrl.c > +++ b/drivers/media/usb/uvc/uvc_ctrl.c <snip> > @@ -1971,19 +2009,59 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, > return ret; > } > > -int uvc_ctrl_get(struct uvc_video_chain *chain, u32 which, > - struct v4l2_ext_control *xctrl) > +static int uvc_mapping_get_xctrl_compound(struct uvc_video_chain *chain, > + struct uvc_control *ctrl, > + struct uvc_control_mapping *mapping, > + u32 which, > + struct v4l2_ext_control *xctrl) > { > - struct uvc_control *ctrl; > - struct uvc_control_mapping *mapping; > - > - if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0) > - return -EACCES; > + u8 *data __free(kfree) = NULL; > + size_t size; > + u8 query; > + int ret; > + int id; > > - ctrl = uvc_find_control(chain, xctrl->id, &mapping); > - if (ctrl == NULL) > + switch (which) { > + case V4L2_CTRL_WHICH_CUR_VAL: > + ret = __uvc_ctrl_load_cur(chain, ctrl); > + if (ret < 0) > + return ret; > + id = UVC_CTRL_DATA_CURRENT; > + query = UVC_GET_CUR; > + break; > + case V4L2_CTRL_WHICH_DEF_VAL: > + ret = uvc_ctrl_populate_cache(chain, ctrl); > + if (ret < 0) > + return ret; > + id = UVC_CTRL_DATA_DEF; > + query = UVC_GET_DEF; > + break; > + default: > return -EINVAL; > + } > + > + size = DIV_ROUND_UP(mapping->size, 8); > + if (xctrl->size < size) { > + xctrl->size = size; > + return -ENOSPC; > + } > + > + data = kmalloc(size, GFP_KERNEL); > + if (!data) > + return -ENOMEM; > + > + ret = mapping->get(mapping, query, uvc_ctrl_data(ctrl, id), size, data); > + if (ret < 0) > + return ret; > + > + return copy_to_user(xctrl->ptr, data, size) ? -EFAULT : 0; > +} While reviewing "[PATCH v15 14/19] media: uvcvideo: Use the camera to clamp compound controls" I realized that this copy_to_user() is somewhat unexpected. Normally we let the v4l2 core ioctl wrapper take care of this. Since there is no room in struct v4l2_ext_control to store the data I guess this is ok, but IMHO this does at least need a comment explaining how this is a special case. Regards, Hans