drivers/media/usb/uvc/uvc_driver.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
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")
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
---
I have managed to get my hands into a Grandstream GUV3100 and
implemented a new heuristics. (Thanks Yunke and Hidenori!).
With this heuristics we can use this camera again (see the /dev/video0
in the topology).
I have tested this change in a 6.6 kernel. Because the notebook that I
used for testing has some issues running master. But for the purpose of
this change this test should work.
~ # media-ctl --print-topology
Media controller API version 6.6.99
Media device information
------------------------
driver uvcvideo
model GRANDSTREAM GUV3100: GRANDSTREA
serial
bus info usb-0000:00:14.0-9
hw revision 0x409
driver version 6.6.99
Device topology
- entity 1: GRANDSTREAM GUV3100: GRANDSTREA (1 pad, 1 link)
type Node subtype V4L flags 1
device node name /dev/video0
pad0: SINK
<- "Extension 3":1 [ENABLED,IMMUTABLE]
- entity 4: GRANDSTREAM GUV3100: GRANDSTREA (0 pad, 0 link)
type Node subtype V4L flags 0
device node name /dev/video1
- entity 8: Extension 3 (2 pads, 2 links, 0 routes)
type V4L2 subdev subtype Unknown flags 0
pad0: SINK
<- "Processing 2":1 [ENABLED,IMMUTABLE]
pad1: SOURCE
-> "GRANDSTREAM GUV3100: GRANDSTREA":0 [ENABLED,IMMUTABLE]
- entity 11: Processing 2 (2 pads, 3 links, 0 routes)
type V4L2 subdev subtype Unknown flags 0
pad0: SINK
<- "Camera 1":0 [ENABLED,IMMUTABLE]
pad1: SOURCE
-> "Extension 3":0 [ENABLED,IMMUTABLE]
-> "Extension 4":0 [ENABLED,IMMUTABLE]
- entity 14: Extension 4 (2 pads, 1 link, 0 routes)
type V4L2 subdev subtype Unknown flags 0
pad0: SINK
<- "Processing 2":1 [ENABLED,IMMUTABLE]
pad1: SOURCE
- entity 17: Camera 1 (1 pad, 1 link, 0 routes)
type V4L2 subdev subtype Sensor flags 0
pad0: SOURCE
-> "Processing 2":0 [ENABLED,IMMUTABLE]
---
drivers/media/usb/uvc/uvc_driver.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index fb6afb8e84f00961f86fd8f840fba48d706d7a9a..4a8712d2d663ab0c31a1586ed7da6fd42f3ad3cc 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -168,12 +168,24 @@ 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;
+ unsigned int count = 0;
list_for_each_entry(stream, &dev->streams, list) {
+ count += 1;
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 stream;
+ }
+
return NULL;
}
---
base-commit: ea299a2164262ff787c9d33f46049acccd120672
change-id: 20251021-uvc-grandstream-05ecf0288f62
Best regards,
--
Ricardo Ribalda <ribalda@chromium.org>
© 2016 - 2026 Red Hat, Inc.