]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: uvcvideo: Use heuristic to find stream entity
authorRicardo Ribalda <ribalda@chromium.org>
Tue, 21 Oct 2025 10:36:17 +0000 (10:36 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 18 Apr 2026 08:35:56 +0000 (10:35 +0200)
[ Upstream commit 758dbc756aad429da11c569c0d067f7fd032bcf7 ]

Some devices, like the Grandstream GUV3100 webcam, have an invalid UVC
descriptor where multiple entities share the same ID, this is invalid
and makes it impossible to make a proper entity tree without heuristics.

We have recently introduced a change in the way that we handle invalid
entities that has caused a regression on broken devices.

Implement a new heuristic to handle these devices properly.

Reported-by: Angel4005 <ooara1337@gmail.com>
Closes: https://lore.kernel.org/linux-media/CAOzBiVuS7ygUjjhCbyWg-KiNx+HFTYnqH5+GJhd6cYsNLT=DaA@mail.gmail.com/
Fixes: 0e2ee70291e6 ("media: uvcvideo: Mark invalid entities with id UVC_INVALID_ENTITY_ID")
Cc: stable@vger.kernel.org
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Reviewed-by: Hans de Goede <hansg@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/media/usb/uvc/uvc_driver.c

index f81bddd20bc09004d87cb21de0cc0067651219d6..a1c6ae97a2b930db60c5b5f423d41bb3b23d71fd 100644 (file)
@@ -164,13 +164,26 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
 
 static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id)
 {
-       struct uvc_streaming *stream;
+       struct uvc_streaming *stream, *last_stream;
+       unsigned int count = 0;
 
        list_for_each_entry(stream, &dev->streams, list) {
+               count += 1;
+               last_stream = stream;
                if (stream->header.bTerminalLink == id)
                        return stream;
        }
 
+       /*
+        * If the streaming entity is referenced by an invalid ID, notify the
+        * user and use heuristics to guess the correct entity.
+        */
+       if (count == 1 && id == UVC_INVALID_ENTITY_ID) {
+               dev_warn(&dev->intf->dev,
+                        "UVC non compliance: Invalid USB header. The streaming entity has an invalid ID, guessing the correct one.");
+               return last_stream;
+       }
+
        return NULL;
 }