This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/cgit.cgi/v4l-utils.git tree:

Subject: v4l2-compliance: the -z/-u options failed to find the media device
Author:  Hans Verkuil <[email protected]>
Date:    Thu Jul 16 09:37:55 2026 +0200

Finding the right media device based on the bus_info and the
/dev/v4l-subdevX device failed since it tried to rely on sysfs
information instead of just walking the /dev/mediaX devices and
finding the media device with a matching bus_info.

Fix this.

Signed-off-by: Hans Verkuil <[email protected]>
Tested-by: Laurent Pinchart <[email protected]>

 utils/common/media-info.cpp                 | 38 ++++++++++++++++++++++++++---
 utils/common/media-info.h                   | 13 ++++++----
 utils/v4l2-compliance/v4l2-compliance.cpp   | 18 +++++++++++---
 utils/v4l2-compliance/v4l2-test-buffers.cpp |  6 ++---
 utils/v4l2-ctl/v4l2-ctl-streaming.cpp       |  4 +--
 utils/v4l2-ctl/v4l2-ctl.cpp                 |  5 +++-
 6 files changed, 65 insertions(+), 19 deletions(-)

---

http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=3b412f2890e7554a5be67c434c61c01c34173c30
diff --git a/utils/common/media-info.cpp b/utils/common/media-info.cpp
index 95e4c74f84bd..6d6d79047c8c 100644
--- a/utils/common/media-info.cpp
+++ b/utils/common/media-info.cpp
@@ -216,7 +216,7 @@ std::string mi_get_devpath_from_dev_t(dev_t dev)
        return devpath;
 }
 
-int mi_get_media_fd(int fd, const char *bus_info)
+int mi_get_media_fd(int fd)
 {
        int media_fd = -1;
        dev_t dev;
@@ -243,9 +243,39 @@ int mi_get_media_fd(int fd, const char *bus_info)
                        devname += ep->d_name;
                        media_fd = open(devname.c_str(), O_RDWR);
 
-                       if (bus_info &&
-                           (ioctl(media_fd, MEDIA_IOC_DEVICE_INFO, &mdinfo) ||
-                            strcmp(mdinfo.bus_info, bus_info))) {
+                       if (ioctl(media_fd, MEDIA_IOC_DEVICE_INFO, &mdinfo)) {
+                               close(media_fd);
+                               continue;
+                       }
+                       break;
+               }
+       }
+       closedir(dp);
+       return media_fd;
+}
+
+int mi_get_media_bus_info(const char *bus_info)
+{
+       int media_fd = -1;
+       DIR *dp;
+       struct dirent *ep;
+
+       if (!bus_info)
+               return -1;
+
+       dp = opendir("/dev");
+       if (dp == nullptr)
+               return -1;
+       while ((ep = readdir(dp))) {
+               if (!memcmp(ep->d_name, "media", 5) && isdigit(ep->d_name[5])) {
+                       struct media_device_info mdinfo;
+                       std::string devname("/dev/");
+
+                       devname += ep->d_name;
+                       media_fd = open(devname.c_str(), O_RDWR);
+
+                       if (ioctl(media_fd, MEDIA_IOC_DEVICE_INFO, &mdinfo) ||
+                           strcmp(mdinfo.bus_info, bus_info)) {
                                close(media_fd);
                                continue;
                        }
diff --git a/utils/common/media-info.h b/utils/common/media-info.h
index c0dd63043d8f..75eb29b4e22a 100644
--- a/utils/common/media-info.h
+++ b/utils/common/media-info.h
@@ -51,12 +51,15 @@ std::string mi_get_devpath_from_dev_t(dev_t dev);
 
 /*
  * For a given device fd return the corresponding media device
- * or -1 if there is none.
- *
- * If bus_info is not NULL, then find the media device that
- * matches the given bus_info.
+ * or -1 if there is none. This only works if the media device
+ * is discoverable from where fd sits in /sys.
+ */
+int mi_get_media_fd(int fd);
+
+/*
+ * Find the media device that matches the given bus_info.
  */
-int mi_get_media_fd(int fd, const char *bus_info = NULL);
+int mi_get_media_bus_info(const char *bus_info);
 
 /* Return entity flags description */
 std::string mi_entflags2s(__u32 flags);
diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp 
b/utils/v4l2-compliance/v4l2-compliance.cpp
index 9e0b5c3f9fa1..d6c2f61d61ff 100644
--- a/utils/v4l2-compliance/v4l2-compliance.cpp
+++ b/utils/v4l2-compliance/v4l2-compliance.cpp
@@ -1000,8 +1000,7 @@ void testNode(struct node &node, struct node 
&node_m2m_cap, struct node &expbuf_
                driver = reinterpret_cast<const char *>(vcap.driver);
                is_uvcvideo = driver == "uvcvideo";
                is_vivid = driver == "vivid";
-               if (is_vivid)
-                       node.bus_info = reinterpret_cast<const char 
*>(vcap.bus_info);
+               node.bus_info = reinterpret_cast<const char *>(vcap.bus_info);
                determine_codec_mask(node);
        } else if (node.is_subdev()) {
                doioctl(&node, VIDIOC_SUBDEV_QUERYCAP, &subdevcap);
@@ -1016,7 +1015,7 @@ void testNode(struct node &node, struct node 
&node_m2m_cap, struct node &expbuf_
                if (parent_media_fd >= 0)
                        media_fd = parent_media_fd;
                else
-                       media_fd = mi_get_media_fd(node.g_fd(), node.bus_info);
+                       media_fd = mi_get_media_bus_info(node.bus_info);
        }
 
        int fd = node.is_media() ? node.g_fd() : media_fd;
@@ -1662,6 +1661,7 @@ int main(int argc, char **argv)
        std::string media_bus_info;
        struct node expbuf_node;
        std::string expbuf_media_bus_info;
+       int media_fd = -1;
        const char *env_media_apps_color = getenv("MEDIA_APPS_COLOR");
 
        /* command args */
@@ -1910,6 +1910,16 @@ int main(int argc, char **argv)
                        strerror(errno));
                std::exit(EXIT_FAILURE);
        }
+       if (type != MEDIA_TYPE_MEDIA && !media_bus_info.empty()) {
+               std::string media_devname;
+
+               media_fd = open_media_bus_info(media_bus_info, media_devname);
+               if (media_fd < 0) {
+                       fprintf(stderr, "Failed to find media device for %s: 
%s\n",
+                               media_bus_info.c_str(), strerror(errno));
+                       std::exit(EXIT_FAILURE);
+               }
+       }
 
        if (!expbuf_device.empty()) {
                expbuf_node.s_trace(options[OptTrace]);
@@ -1922,7 +1932,7 @@ int main(int argc, char **argv)
                }
        }
 
-       testNode(node, node, expbuf_node, type, frame_count, 
all_fmt_frame_count);
+       testNode(node, node, expbuf_node, type, frame_count, 
all_fmt_frame_count, media_fd);
 
        if (!expbuf_device.empty())
                expbuf_node.close();
diff --git a/utils/v4l2-compliance/v4l2-test-buffers.cpp 
b/utils/v4l2-compliance/v4l2-test-buffers.cpp
index 1d4fdf6d7337..dba471e5b488 100644
--- a/utils/v4l2-compliance/v4l2-test-buffers.cpp
+++ b/utils/v4l2-compliance/v4l2-test-buffers.cpp
@@ -2312,7 +2312,7 @@ int testDmaBuf(struct node *expbuf_node, struct node 
*node, struct node *node_m2
 int testRequests(struct node *node, bool test_streaming)
 {
        filehandles fhs;
-       int media_fd = fhs.add(mi_get_media_fd(node->g_fd(), node->bus_info));
+       int media_fd = fhs.add(mi_get_media_bus_info(node->bus_info));
        int req_fd;
        struct test_query_ext_ctrl valid_qctrl;
        v4l2_ext_controls ctrls;
@@ -2448,7 +2448,7 @@ int testRequests(struct node *node, bool test_streaming)
        fail_on_test(doioctl_fd(req_fd, MEDIA_REQUEST_IOC_REINIT, nullptr) != 
EBADF);
 
        // Open media_fd and alloc a request again
-       media_fd = fhs.add(mi_get_media_fd(node->g_fd(), node->bus_info));
+       media_fd = fhs.add(mi_get_media_bus_info(node->bus_info));
        fail_on_test(doioctl_fd(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd));
        fhs.add(req_fd);
        ctrls.count = 1;
@@ -2523,7 +2523,7 @@ int testRequests(struct node *node, bool test_streaming)
        unsigned num_requests = 2 * num_bufs;
        last_seq.init();
 
-       media_fd = fhs.add(mi_get_media_fd(node->g_fd(), node->bus_info));
+       media_fd = fhs.add(mi_get_media_bus_info(node->bus_info));
 
        // Allocate the requests
        for (unsigned i = 0; i < num_requests; i++) {
diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp 
b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
index 517fc7f209f5..fe5d0dfee397 100644
--- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
@@ -1346,10 +1346,10 @@ static int do_setup_out_buffers(cv4l_fd &fd, cv4l_queue 
&q, FILE *fin, bool qbuf
                if (fmt.g_pixelformat() == V4L2_PIX_FMT_FWHT_STATELESS) {
                        struct v4l2_capability vcap = {};
                        fd.querycap(vcap);
-                       int media_fd = mi_get_media_fd(fd.g_fd(), (const char 
*)vcap.bus_info);
+                       int media_fd = mi_get_media_bus_info((const char 
*)vcap.bus_info);
 
                        if (media_fd < 0) {
-                               fprintf(stderr, "%s: mi_get_media_fd failed\n", 
__func__);
+                               fprintf(stderr, "%s: mi_get_media_bus_info 
failed\n", __func__);
                                return media_fd;
                        }
 
diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
index 842e22fd939a..14f5c51fc070 100644
--- a/utils/v4l2-ctl/v4l2-ctl.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl.cpp
@@ -1382,7 +1382,10 @@ int main(int argc, char **argv)
                        capabilities = vcap.device_caps;
        }
 
-       media_fd = mi_get_media_fd(fd, is_subdev ? 0 : (const char 
*)vcap.bus_info);
+       if (is_subdev)
+               media_fd = mi_get_media_fd(fd);
+       else
+               media_fd = mi_get_media_bus_info((const char *)vcap.bus_info);
 
        priv_magic = (capabilities & V4L2_CAP_EXT_PIX_FORMAT) ?
                        V4L2_PIX_FMT_PRIV_MAGIC : 0;
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to