Hi Laurent On Sun, 15 Jan 2023 at 22:17, Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx> wrote: > > From: Ai Chao <aichao@xxxxxxxxxx> > > The Alcor Corp. Slave camera (1b17:6684 and 2017:0011) returns a wrong > dwMaxPayloadTransferSize value for compressed formats. Valid values are > typically up to 3072 bytes per interval (for high-speed, high-bandwidth > devices), and those faulty devices request 2752512 bytes per interval. > This is a firmware issue, but the manufacturer cannot provide a fixed > firmware. > > Fix this by checking the dwMaxPayloadTransferSize field, and hardcoding > a value of 1024 if it exceeds 3072 for compressed formats transferred > over isochronous endpoints. While at it, document the other quirk that > handles a bandwidth issue for uncompressed formats. > > Signed-off-by: Ai Chao <aichao@xxxxxxxxxx> > --- > I have dropped the Reviewed-by tags as the patch has changed > significantly. > > Ricardo, do you know if the 3072 bytes limit is fine with super-speed > devices, or does it need to be increased ? We have enough documentation to let ChatGPT make the code for us :) I am going to try tonight on two superspeed cameras. Will let you know tomorow. > --- > drivers/media/usb/uvc/uvc_video.c | 31 +++++++++++++++++++++++++++++++ > 1 file changed, 31 insertions(+) > > diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c > index d4b023d4de7c..c6351d3b24cf 100644 > --- a/drivers/media/usb/uvc/uvc_video.c > +++ b/drivers/media/usb/uvc/uvc_video.c > @@ -200,6 +200,20 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, > if ((ctrl->dwMaxPayloadTransferSize & 0xffff0000) == 0xffff0000) > ctrl->dwMaxPayloadTransferSize &= ~0xffff0000; > > + /* > + * Many devices report an incorrect dwMaxPayloadTransferSize value. The > + * most common issue is devices requesting the maximum possible USB > + * bandwidth (3072 bytes per interval for high-speed, high-bandwidth > + * isochronous endpoints) while they actually require less, preventing > + * multiple cameras from being used at the same time due to bandwidth > + * overallocation. > + * > + * For those devices, replace the dwMaxPayloadTransferSize value based > + * on an estimation calculated from the frame format and size. This is > + * only possible for uncompressed formats, as not enough information is > + * available to reliably estimate the bandwidth requirements for > + * compressed formats. > + */ > if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) && > stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH && > stream->intf->num_altsetting > 1) { > @@ -236,6 +250,23 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, > > ctrl->dwMaxPayloadTransferSize = bandwidth; > } > + > + /* > + * Another issue is with devices that report a transfer size that > + * greatly exceeds the maximum supported by any existing USB version > + * for isochronous transfers. For instance, the "Slave camera" devices > + * from Alcor Corp. (2017:0011 and 1b17:66B8) request 2752512 bytes per > + * interval. > + * > + * For uncompressed formats, this can be addressed by the FIX_BANDWIDTH > + * quirk, but for compressed format we can't meaningfully estimate the > + * required bandwidth. Just hardcode it to 1024 bytes per interval, > + * which should be large enough for compressed formats. > + */ > + if ((format->flags & UVC_FMT_FLAG_COMPRESSED) && > + ctrl->dwMaxPayloadTransferSize > 3072 && > + stream->intf->num_altsetting > 1) > + ctrl->dwMaxPayloadTransferSize = 1024; - Maybe we should add a debug message if we are doing this? - Also I do not like that the value that we use as trigger (3072) is different than the quirked value (1024) Something like: value = min(3072, value) makes more sense Thanks! > } > > static size_t uvc_video_ctrl_size(struct uvc_streaming *stream) > -- > Regards, > > Laurent Pinchart > -- Ricardo Ribalda