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

Configure Feed

Select the types of activity you want to include in your feed.

usb: gadget: uvc: fix interval_duration calculation

According to USB specification:

For full-/high-speed isochronous endpoints, the bInterval value is
used as the exponent for a 2^(bInterval-1) value.

To correctly convert bInterval as interval_duration:
interval_duration = 2^(bInterval-1) * frame_interval

Because the unit of video->interval is 100ns, add a comment info to
make it clear.

Fixes: 48dbe731171e ("usb: gadget: uvc: set req_size and n_requests based on the frame interval")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Link: https://patch.msgid.link/20260113-uvc-gadget-fix-patch-v2-2-62950ef5bcb5@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Xu Yang and committed by
Greg Kroah-Hartman
010dc57c 2edc1acb

+6 -3
+1 -1
drivers/usb/gadget/function/uvc.h
··· 107 107 unsigned int width; 108 108 unsigned int height; 109 109 unsigned int imagesize; 110 - unsigned int interval; 110 + unsigned int interval; /* in 100ns units */ 111 111 struct mutex mutex; /* protects frame parameters */ 112 112 113 113 unsigned int uvc_num_requests;
+5 -2
drivers/usb/gadget/function/uvc_video.c
··· 499 499 { 500 500 struct uvc_device *uvc = container_of(video, struct uvc_device, video); 501 501 struct usb_composite_dev *cdev = uvc->func.config->cdev; 502 - unsigned int interval_duration = video->ep->desc->bInterval * 1250; 502 + unsigned int interval_duration; 503 503 unsigned int max_req_size, req_size, header_size; 504 504 unsigned int nreq; 505 505 ··· 513 513 return; 514 514 } 515 515 516 + interval_duration = 2 << (video->ep->desc->bInterval - 1); 516 517 if (cdev->gadget->speed < USB_SPEED_HIGH) 517 - interval_duration = video->ep->desc->bInterval * 10000; 518 + interval_duration *= 10000; 519 + else 520 + interval_duration *= 1250; 518 521 519 522 nreq = DIV_ROUND_UP(video->interval, interval_duration); 520 523