summaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/uvc
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-03-08 11:31:28 +0100
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2021-04-06 14:26:31 +0200
commit4ca052b4ea621d0002a5e5feace51f60ad5e6b23 (patch)
tree17f2b75d751f8aca3d6eeb55b7a5fb18900c7d81 /drivers/media/usb/uvc
parent3293448632ff2ae8c7cde4c3475da96138e24ca7 (diff)
downloadlinux-4ca052b4ea621d0002a5e5feace51f60ad5e6b23.tar.bz2
media: uvcvideo: Support devices that report an OT as an entity source
Some devices reference an output terminal as the source of extension units. This is incorrect, as output terminals only have an input pin, and thus can't be connected to any entity in the forward direction. The resulting topology would cause issues when registering the media controller graph. To avoid this problem, connect the extension unit to the source of the output terminal instead. While at it, and while no device has been reported to be affected by this issue, also handle forward scans where two output terminals would be connected together, and skip the terminals found through such an invalid connection. Reported-and-tested-by: John Nealy <jnealy3@yahoo.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/media/usb/uvc')
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index e55cf02baad6..9a791d8ef200 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1716,6 +1716,31 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
return -EINVAL;
}
+ /*
+ * Some devices reference an output terminal as the
+ * source of extension units. This is incorrect, as
+ * output terminals only have an input pin, and thus
+ * can't be connected to any entity in the forward
+ * direction. The resulting topology would cause issues
+ * when registering the media controller graph. To
+ * avoid this problem, connect the extension unit to
+ * the source of the output terminal instead.
+ */
+ if (UVC_ENTITY_IS_OTERM(entity)) {
+ struct uvc_entity *source;
+
+ source = uvc_entity_by_id(chain->dev,
+ entity->baSourceID[0]);
+ if (!source) {
+ uvc_dbg(chain->dev, DESCR,
+ "Can't connect extension unit %u in chain\n",
+ forward->id);
+ break;
+ }
+
+ forward->baSourceID[0] = source->id;
+ }
+
list_add_tail(&forward->chain, &chain->entities);
if (!found)
uvc_dbg_cont(PROBE, " (->");
@@ -1735,6 +1760,13 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
return -EINVAL;
}
+ if (UVC_ENTITY_IS_OTERM(entity)) {
+ uvc_dbg(chain->dev, DESCR,
+ "Unsupported connection between output terminals %u and %u\n",
+ entity->id, forward->id);
+ break;
+ }
+
list_add_tail(&forward->chain, &chain->entities);
if (!found)
uvc_dbg_cont(PROBE, " (->");