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

usb: gadget: uvc: default the ctrl request interface offsets

For the userspace it is needed to distinguish between requests for the
control or streaming interface. The userspace would have to parse the
configfs to know which interface index it has to compare the ctrl
requests against. Since the interface numbers are not fixed, e.g. for
composite gadgets, the interface offset depends on the setup.

The kernel has this information when handing over the ctrl request to
the userspace. This patch removes the offset from the interface numbers
and expose the default interface defines in the uapi g_uvc.h.

Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
Link: https://lore.kernel.org/r/20221011075348.1786897-1-m.grzeschik@pengutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Michael Grzeschik and committed by
Greg Kroah-Hartman
d182bf15 9b6447e0

+15 -3
+12 -3
drivers/usb/gadget/function/f_uvc.c
··· 39 39 40 40 /* string IDs are assigned dynamically */ 41 41 42 - #define UVC_STRING_CONTROL_IDX 0 43 - #define UVC_STRING_STREAMING_IDX 1 44 - 45 42 static struct usb_string uvc_en_us_strings[] = { 46 43 /* [UVC_STRING_CONTROL_IDX].s = DYNAMIC, */ 47 44 [UVC_STRING_STREAMING_IDX].s = "Video Streaming", ··· 225 228 struct uvc_device *uvc = to_uvc(f); 226 229 struct v4l2_event v4l2_event; 227 230 struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; 231 + unsigned int interface = le16_to_cpu(ctrl->wIndex) & 0xff; 232 + struct usb_ctrlrequest *mctrl; 228 233 229 234 if ((ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) { 230 235 uvcg_info(f, "invalid request type\n"); ··· 247 248 memset(&v4l2_event, 0, sizeof(v4l2_event)); 248 249 v4l2_event.type = UVC_EVENT_SETUP; 249 250 memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req)); 251 + 252 + /* check for the interface number, fixup the interface number in 253 + * the ctrl request so the userspace doesn't have to bother with 254 + * offset and configfs parsing 255 + */ 256 + mctrl = &uvc_event->req; 257 + mctrl->wIndex &= ~cpu_to_le16(0xff); 258 + if (interface == uvc->streaming_intf) 259 + mctrl->wIndex = cpu_to_le16(UVC_STRING_STREAMING_IDX); 260 + 250 261 v4l2_event_queue(&uvc->vdev, &v4l2_event); 251 262 252 263 return 0;
+3
include/uapi/linux/usb/g_uvc.h
··· 21 21 #define UVC_EVENT_DATA (V4L2_EVENT_PRIVATE_START + 5) 22 22 #define UVC_EVENT_LAST (V4L2_EVENT_PRIVATE_START + 5) 23 23 24 + #define UVC_STRING_CONTROL_IDX 0 25 + #define UVC_STRING_STREAMING_IDX 1 26 + 24 27 struct uvc_request_data { 25 28 __s32 length; 26 29 __u8 data[60];