[PATCH v5] media: uvcvideo: Fix bandwidth error for Alcor camera

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 ?
---
 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;
 }
 
 static size_t uvc_video_ctrl_size(struct uvc_streaming *stream)
-- 
Regards,

Laurent Pinchart




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux