mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2] media: uvcvideo: Use heuristic to find stream entity
@ 2025-10-21 10:36 Ricardo Ribalda
  2025-10-21 16:07 ` Hans de Goede
  2025-10-21 16:44 ` Laurent Pinchart
  0 siblings, 2 replies; 8+ messages in thread
From: Ricardo Ribalda @ 2025-10-21 10:36 UTC (permalink / raw)
  To: Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab,
	Hans Verkuil, Thadeu Lima de Souza Cascardo, Angel4005
  Cc: linux-media, linux-kernel, Ricardo Ribalda

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]
---
Changes in v2:
- Fix : invalid reference to the index variable of the iterator.
- Link to v1: https://lore.kernel.org/r/20251021-uvc-grandstream-v1-1-801e3d08b271@chromium.org
---
 drivers/media/usb/uvc/uvc_driver.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index fb6afb8e84f00961f86fd8f840fba48d706d7a9a..ee4f54d6834962414979a046afc59c5036455124 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -167,13 +167,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;
 }
 

---
base-commit: ea299a2164262ff787c9d33f46049acccd120672
change-id: 20251021-uvc-grandstream-05ecf0288f62

Best regards,
-- 
Ricardo Ribalda <ribalda@chromium.org>


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-10-21 18:42 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-10-21 10:36 [PATCH v2] media: uvcvideo: Use heuristic to find stream entity Ricardo Ribalda
2025-10-21 16:07 ` Hans de Goede
2025-10-21 16:15   ` Ricardo Ribalda
2025-10-21 16:45     ` Laurent Pinchart
2025-10-21 16:44 ` Laurent Pinchart
2025-10-21 16:57   ` Ricardo Ribalda
2025-10-21 17:06     ` Laurent Pinchart
2025-10-21 18:42       ` Laurent Pinchart

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®