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/v4l2-ctl: more device detection improvements
Author:  Hans Verkuil <hans.verk...@cisco.com>
Date:    Sun Feb 4 16:52:03 2018 +0100

More improvements in detecting the type of a device.

Also fix a bug introduced in commit ce29414c85
("v4l2-ctl/v4l2-compliance: reuse media info code") that broke
the v4l-subdev tests in v4l2-compliance.

Signed-off-by: Hans Verkuil <hans.verk...@cisco.com>

 utils/common/media-info.cpp               | 35 +++++++------
 utils/common/media-info.h                 |  3 +-
 utils/common/v4l2-info.cpp                | 49 +++++++++---------
 utils/common/v4l2-info.h                  | 19 ++++++-
 utils/v4l2-compliance/v4l2-compliance.cpp | 86 +++++++++++++++++++------------
 utils/v4l2-ctl/v4l2-ctl.cpp               | 15 +++++-
 6 files changed, 128 insertions(+), 79 deletions(-)

---

http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=0b0cb3188d953c3a8f706ebf49da83b98be5dce6
diff --git a/utils/common/media-info.cpp b/utils/common/media-info.cpp
index 2ca042909822..0588b3467302 100644
--- a/utils/common/media-info.cpp
+++ b/utils/common/media-info.cpp
@@ -223,14 +223,14 @@ static std::string linkflags2s(__u32 flags)
        }
 }
 
-static bool read_topology(int media_fd, __u32 major, __u32 minor)
+static __u32 read_topology(int media_fd, __u32 major, __u32 minor)
 {
        media_v2_topology topology;
        unsigned i, j;
 
        memset(&topology, 0, sizeof(topology));
        if (ioctl(media_fd, MEDIA_IOC_G_TOPOLOGY, &topology))
-               return false;
+               return 0;
 
        media_v2_entity v2_ents[topology.num_entities];
        media_v2_interface v2_ifaces[topology.num_interfaces];
@@ -242,7 +242,7 @@ static bool read_topology(int media_fd, __u32 major, __u32 
minor)
        topology.ptr_pads = (__u64)v2_pads;
        topology.ptr_links = (__u64)v2_links;
        if (ioctl(media_fd, MEDIA_IOC_G_TOPOLOGY, &topology))
-               return false;
+               return 0;
        for (i = 0; i < topology.num_interfaces; i++)
                if (v2_ifaces[i].devnode.major == major &&
                    v2_ifaces[i].devnode.minor == minor)
@@ -250,7 +250,7 @@ static bool read_topology(int media_fd, __u32 major, __u32 
minor)
        if (i == topology.num_interfaces) {
                fprintf(stderr, "could not find %d:%d device in topology\n",
                        major, minor);
-               return false;
+               return 0;
        }
        media_v2_interface &iface = v2_ifaces[i];
        for (i = 0; i < topology.num_links; i++) {
@@ -264,7 +264,7 @@ static bool read_topology(int media_fd, __u32 major, __u32 
minor)
        if (i == topology.num_links) {
                fprintf(stderr, "could not find link for interface %u in 
topology\n",
                        iface.id);
-               return false;
+               return 0;
        }
        __u32 ent_id = v2_links[i].sink_id;
        for (i = 0; i < topology.num_entities; i++) {
@@ -274,7 +274,7 @@ static bool read_topology(int media_fd, __u32 major, __u32 
minor)
        if (i == topology.num_entities) {
                fprintf(stderr, "could not find entity %u in topology\n",
                        ent_id);
-               return false;
+               return 0;
        }
        media_v2_entity &ent = v2_ents[i];
 
@@ -317,7 +317,7 @@ static bool read_topology(int media_fd, __u32 major, __u32 
minor)
                        if (!remote_ent_id) {
                                fprintf(stderr, "could not find remote pad 
0x%08x in topology\n",
                                        remote_pad);
-                               return true;
+                               return ent.id;
                        }
                        for (unsigned k = 0; k < topology.num_entities; k++)
                                if (v2_ents[k].id == remote_ent_id) {
@@ -327,23 +327,24 @@ static bool read_topology(int media_fd, __u32 major, 
__u32 minor)
                        if (!remote_ent) {
                                fprintf(stderr, "could not find remote entity 
0x%08x in topology\n",
                                        remote_ent_id);
-                               return true;
+                               return ent.id;
                        }
                        printf("\t  Link 0x%08x: %s remote pad 0x%x of entity 
'%s': %s\n",
                               link.id, is_sink ? "from" : "to", remote_pad,
                               remote_ent->name, 
linkflags2s(link.flags).c_str());
                }
        }
-       return true;
+       return ent.id;
 }
 
-void mi_media_info_for_fd(int media_fd, int fd)
+__u32 mi_media_info_for_fd(int media_fd, int fd)
 {
        struct media_device_info mdinfo;
        struct stat sb;
+       __u32 ent_id = 0;
 
        if (ioctl(media_fd, MEDIA_IOC_DEVICE_INFO, &mdinfo))
-               return;
+               return 0;
 
        struct media_entity_desc ent;
        bool found = false;
@@ -365,15 +366,16 @@ void mi_media_info_for_fd(int media_fd, int fd)
               mdinfo.driver_version & 0xff);
 
        if (fd < 0)
-               return;
+               return 0;
 
        if (fstat(fd, &sb) == -1) {
                fprintf(stderr, "failed to stat file\n");
                exit(1);
        }
 
-       if (read_topology(media_fd, major(sb.st_rdev), minor(sb.st_rdev)))
-               return;
+       ent_id = read_topology(media_fd, major(sb.st_rdev), minor(sb.st_rdev));
+       if (ent_id)
+               return ent_id;
 
        memset(&ent, 0, sizeof(ent));
        ent.id = MEDIA_ENT_ID_FLAG_NEXT;
@@ -386,7 +388,7 @@ void mi_media_info_for_fd(int media_fd, int fd)
                ent.id |= MEDIA_ENT_ID_FLAG_NEXT;
        }
        if (!found)
-               return;
+               return 0;
 
        printf("Entity Info:\n");
        printf("\tID               : %u\n", ent.id);
@@ -408,7 +410,7 @@ void mi_media_info_for_fd(int media_fd, int fd)
        links_enum.pads = pads;
        links_enum.links = links;
        if (ioctl(media_fd, MEDIA_IOC_ENUM_LINKS, &links_enum))
-               return;
+               return ent.id;
 
        for (unsigned i = 0; i < ent.pads; i++)
                printf("\tPad              : %u: %s\n", pads[i].index,
@@ -418,4 +420,5 @@ void mi_media_info_for_fd(int media_fd, int fd)
                       links[i].source.entity,
                       links[i].sink.entity,
                       linkflags2s(links[i].flags).c_str());
+       return ent.id;
 }
diff --git a/utils/common/media-info.h b/utils/common/media-info.h
index 5716e951a981..f0636091b728 100644
--- a/utils/common/media-info.h
+++ b/utils/common/media-info.h
@@ -27,7 +27,8 @@ int mi_get_media_fd(int fd);
 /*
  * Show media controller information media_fd and (if >= 0) the
  * corresponsing entity/interface information for the fd.
+ * Return the entity ID of fd.
  */
-void mi_media_info_for_fd(int media_fd, int fd);
+__u32 mi_media_info_for_fd(int media_fd, int fd);
 
 #endif
diff --git a/utils/common/v4l2-info.cpp b/utils/common/v4l2-info.cpp
index 73f5b8f2750c..58feb4de0725 100644
--- a/utils/common/v4l2-info.cpp
+++ b/utils/common/v4l2-info.cpp
@@ -30,7 +30,7 @@
 #include <sys/sysmacros.h>
 #include <dirent.h>
 
-#include <linux/videodev2.h>
+#include <v4l2-info.h>
 
 #include <fstream>
 
@@ -45,13 +45,12 @@ static std::string num2s(unsigned num, bool is_hex = true)
        return buf;
 }
 
-bool v4l2_is_subdevice(int fd)
+v4l2_type v4l2_detect_type(const char *device)
 {
        struct stat sb;
-       if (fstat(fd, &sb) == -1) {
-               fprintf(stderr, "failed to stat file\n");
-               exit(1);
-       }
+
+       if (stat(device, &sb) == -1)
+               return V4L2_TYPE_CANT_STAT;
 
        std::string uevent_path("/sys/dev/char/");
 
@@ -59,10 +58,8 @@ bool v4l2_is_subdevice(int fd)
                num2s(minor(sb.st_rdev), false) + "/uevent";
 
        std::ifstream uevent_file(uevent_path);
-       if (uevent_file.fail()) {
-               fprintf(stderr, "failed to open %s\n", uevent_path.c_str());
-               exit(1);
-       }
+       if (uevent_file.fail())
+               return V4L2_TYPE_UNKNOWN;
 
        std::string line;
 
@@ -70,30 +67,32 @@ bool v4l2_is_subdevice(int fd)
                if (line.compare(0, 8, "DEVNAME="))
                        continue;
 
-               static const char *devnames[] = {
-                       "v4l-subdev",
-                       "video",
-                       "vbi",
-                       "radio",
-                       "swradio",
-                       "v4l-touch",
-                       NULL
+               static struct {
+                       const char *devname;
+                       enum v4l2_type type;
+               } devtypes[] = {
+                       { "video", V4L2_TYPE_VIDEO },
+                       { "vbi", V4L2_TYPE_VBI },
+                       { "radio", V4L2_TYPE_RADIO },
+                       { "swradio", V4L2_TYPE_SDR },
+                       { "v4l-subdev", V4L2_TYPE_SUBDEV },
+                       { "v4l-touch", V4L2_TYPE_TOUCH },
+                       { NULL, V4L2_TYPE_UNKNOWN }
                };
 
-               for (size_t i = 0; devnames[i]; i++) {
-                       size_t len = strlen(devnames[i]);
+               for (size_t i = 0; devtypes[i].devname; i++) {
+                       const char *devname = devtypes[i].devname;
+                       size_t len = strlen(devname);
 
-                       if (!line.compare(8, len, devnames[i]) && 
isdigit(line[8+len])) {
+                       if (!line.compare(8, len, devname) && 
isdigit(line[8+len])) {
                                uevent_file.close();
-                               return i == 0;
+                               return devtypes[i].type;
                        }
                }
        }
 
        uevent_file.close();
-
-       fprintf(stderr, "unknown device name\n");
-       exit(1);
+       return V4L2_TYPE_UNKNOWN;
 }
 
 typedef struct {
diff --git a/utils/common/v4l2-info.h b/utils/common/v4l2-info.h
index 455a6719acd1..ac6451adce3b 100644
--- a/utils/common/v4l2-info.h
+++ b/utils/common/v4l2-info.h
@@ -18,10 +18,25 @@
 #ifndef _V4L2_INFO_H
 #define _V4L2_INFO_H
 
+#include <string>
+#include <linux/videodev2.h>
+
+enum v4l2_type {
+       V4L2_TYPE_CANT_STAT,
+       V4L2_TYPE_UNKNOWN,
+       V4L2_TYPE_VIDEO,
+       V4L2_TYPE_VBI,
+       V4L2_TYPE_RADIO,
+       V4L2_TYPE_SDR,
+       V4L2_TYPE_TOUCH,
+       V4L2_TYPE_SUBDEV,
+       V4L2_TYPE_MEDIA,
+};
+
 /*
- * Test if the given fd corresponds to a sub-device.
+ * Detect what type the device is.
  */
-bool v4l2_is_subdevice(int fd);
+v4l2_type v4l2_detect_type(const char *device);
 
 /* Print capability information */
 void v4l2_info_capability(const v4l2_capability &cap);
diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp 
b/utils/v4l2-compliance/v4l2-compliance.cpp
index ec5b9385f071..11b54a1c09f3 100644
--- a/utils/v4l2-compliance/v4l2-compliance.cpp
+++ b/utils/v4l2-compliance/v4l2-compliance.cpp
@@ -626,28 +626,17 @@ static const char *make_devname(const char *device, const 
char *devname)
        return device;
 }
 
-enum node_type {
-       TYPE_UNKNOWN,
-       TYPE_VIDEO,
-       TYPE_VBI,
-       TYPE_RADIO,
-       TYPE_SDR,
-       TYPE_TOUCH,
-       TYPE_SUBDEV,
-       TYPE_MEDIA,
-};
-
-static void test(struct node &node, struct node &expbuf_node, node_type type,
+static void test(struct node &node, struct node &expbuf_node, v4l2_type type,
                 unsigned frame_count)
 {
        struct node node2;
        struct v4l2_capability vcap;            /* list_cap */
 
-       node.is_video = type == TYPE_VIDEO;
-       node.is_vbi = type == TYPE_VBI;
-       node.is_radio = type == TYPE_RADIO;
-       node.is_sdr = type == TYPE_SDR;
-       node.is_touch = type == TYPE_TOUCH;
+       node.is_video = type == V4L2_TYPE_VIDEO;
+       node.is_vbi = type == V4L2_TYPE_VBI;
+       node.is_radio = type == V4L2_TYPE_RADIO;
+       node.is_sdr = type == V4L2_TYPE_SDR;
+       node.is_touch = type == V4L2_TYPE_TOUCH;
 
        if (node.is_v4l2())
                doioctl(&node, VIDIOC_QUERYCAP, &vcap);
@@ -704,10 +693,32 @@ static void test(struct node &node, struct node 
&expbuf_node, node_type type,
                        }
                }
        }
+
+       __u32 ent_id = 0;
+
        if (node.is_media())
-               mi_media_info_for_fd(node.g_fd(), -1);
+               ent_id = mi_media_info_for_fd(node.g_fd(), -1);
        else if (media_fd >= 0)
-               mi_media_info_for_fd(media_fd, node.g_fd());
+               ent_id = mi_media_info_for_fd(media_fd, node.g_fd());
+
+       if (ent_id) {
+               memset(&node.entity, 0, sizeof(node.entity));
+               node.entity.id = ent_id;
+               if (!ioctl(media_fd, MEDIA_IOC_ENUM_ENTITIES, &node.entity)) {
+                       struct media_links_enum links_enum;
+
+                       node.pads = new media_pad_desc[node.entity.pads];
+                       node.links = new media_link_desc[node.entity.links];    
+                       memset(&links_enum, 0, sizeof(links_enum));
+                       links_enum.entity = ent_id;
+                       links_enum.pads = node.pads;
+                       links_enum.links = node.links;
+                       if (ioctl(media_fd, MEDIA_IOC_ENUM_LINKS, &links_enum))
+                               node.entity.id = 0;
+               } else {
+                       node.entity.id = 0;
+               }
+       }
 
        printf("\nCompliance test for device %s%s:\n\n",
                        node.device, node.g_direct() ? "" : " (using libv4l2)");
@@ -732,11 +743,11 @@ static void test(struct node &node, struct node 
&expbuf_node, node_type type,
        printf("Allow for multiple opens:\n");
        node2 = node;
        switch (type) {
-       case TYPE_SUBDEV:
+       case V4L2_TYPE_SUBDEV:
                printf("\ttest second %s open: %s\n", node.device,
                       ok(node2.subdev_open(node.device, false) >= 0 ? 0 : 
errno));
                break;
-       case TYPE_MEDIA:
+       case V4L2_TYPE_MEDIA:
                printf("\ttest second %s open: %s\n", node.device,
                       ok(node2.media_open(node.device, false) >= 0 ? 0 : 
errno));
                if (node2.g_fd() >= 0)
@@ -1038,7 +1049,7 @@ int main(int argc, char **argv)
 {
        int i;
        struct node node;
-       enum node_type type = TYPE_UNKNOWN;
+       v4l2_type type = V4L2_TYPE_UNKNOWN;
        struct node expbuf_node;
 
        /* command args */
@@ -1077,31 +1088,25 @@ int main(int argc, char **argv)
                        return 0;
                case OptSetDevice:
                        device = make_devname(optarg, "video");
-                       type = TYPE_VIDEO;
                        break;
                case OptSetVbiDevice:
                        device = make_devname(optarg, "vbi");
-                       type = TYPE_VBI;
                        break;
                case OptSetRadioDevice:
                        device = make_devname(optarg, "radio");
-                       type = TYPE_RADIO;
                        break;
                case OptSetSWRadioDevice:
                        device = make_devname(optarg, "swradio");
-                       type = TYPE_SDR;
                        break;
                case OptSetTouchDevice:
                        device = make_devname(optarg, "v4l-touch");
-                       type = TYPE_TOUCH;
                        break;
                case OptSetSubDevDevice:
                        device = make_devname(optarg, "v4l-subdev");
-                       type = TYPE_SUBDEV;
                        break;
                case OptSetMediaDevice:
                        device = make_devname(optarg, "media");
-                       type = TYPE_MEDIA;
+                       type = V4L2_TYPE_MEDIA;
                        break;
                case OptSetExpBufDevice:
                        expbuf_device = optarg;
@@ -1174,24 +1179,37 @@ int main(int argc, char **argv)
                }
        }
        if (optind < argc) {
-               printf("unknown arguments: ");
+               fprintf(stderr, "unknown arguments: ");
                while (optind < argc)
-                       printf("%s ", argv[optind++]);
-               printf("\n");
+                       fprintf(stderr, "%s ", argv[optind++]);
+               fprintf(stderr, "\n");
                usage();
                return 1;
        }
        bool direct = !options[OptUseWrapper];
        int fd;
 
+       if (type == V4L2_TYPE_UNKNOWN)
+               type = v4l2_detect_type(device);
+       if (type == V4L2_TYPE_CANT_STAT) {
+               fprintf(stderr, "Cannot open device %s, exiting.\n",
+                       device);
+               exit(1);
+       }
+       if (type == V4L2_TYPE_UNKNOWN) {
+               fprintf(stderr, "Unable to detect what device %s is, 
exiting.\n",
+                       device);
+               exit(1);
+       }
+
        node.device = device;
        node.s_trace(options[OptTrace]);
        switch (type) {
-       case TYPE_MEDIA:
+       case V4L2_TYPE_MEDIA:
                node.s_direct(true);
                fd = node.media_open(device, false);
                break;
-       case TYPE_SUBDEV:
+       case V4L2_TYPE_SUBDEV:
                node.s_direct(true);
                fd = node.subdev_open(device, false);
                break;
diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
index 64293059aadc..78bf4fb7401e 100644
--- a/utils/v4l2-ctl/v4l2-ctl.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl.cpp
@@ -976,13 +976,26 @@ int main(int argc, char **argv)
                return 1;
        }
 
+       v4l2_type type = v4l2_detect_type(device);
+       if (type == V4L2_TYPE_CANT_STAT) {
+               fprintf(stderr, "Cannot open device %s, exiting.\n",
+                       device);
+               exit(1);
+       }
+       if (type == V4L2_TYPE_UNKNOWN) {
+               fprintf(stderr, "Unable to detect what device %s is, 
exiting.\n",
+                       device);
+               exit(1);
+       }
+       is_subdev = type == V4L2_TYPE_SUBDEV;
+
        if ((fd = open(device, O_RDWR)) < 0) {
                fprintf(stderr, "Failed to open %s: %s\n", device,
                        strerror(errno));
                exit(1);
        }
        verbose = options[OptVerbose];
-       is_subdev = v4l2_is_subdevice(fd);
+
        if (is_subdev)
                options[OptUseWrapper] = 0;
 

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
https://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to