Message ID | 20210708141404.14826-1-hdegoede@redhat.com |
---|---|
State | New |
Headers | show |
Series | [for,5.10.y] media: uvcvideo: Support devices that report an OT as an entity source | expand |
On Thu, Jul 08, 2021 at 04:14:04PM +0200, Hans de Goede wrote: > From: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > > [ Upstream commit 4ca052b4ea621d0002a5e5feace51f60ad5e6b23 ] > > 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. > > Cc: stable@vger.kernel.org # v5.10 > Reported-by: Hans de Goede <hdegoede@redhat.com> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > Signed-off-by: Hans de Goede <hdegoede@redhat.com> > --- > drivers/media/usb/uvc/uvc_driver.c | 32 ++++++++++++++++++++++++++++++ > 1 file changed, 32 insertions(+) now applied, thanks. greg k-h
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 5ad528264135..282f3d2388cc 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1588,6 +1588,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_trace(UVC_TRACE_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 (uvc_trace_param & UVC_TRACE_PROBE) { if (!found) @@ -1608,6 +1633,13 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain, return -EINVAL; } + if (UVC_ENTITY_IS_OTERM(entity)) { + uvc_trace(UVC_TRACE_DESCR, + "Unsupported connection between output terminals %u and %u\n", + entity->id, forward->id); + break; + } + list_add_tail(&forward->chain, &chain->entities); if (uvc_trace_param & UVC_TRACE_PROBE) { if (!found)