{"id":128,"url":"https://patchwork.libcamera.org/api/1.1/patches/128/?format=json","web_url":"https://patchwork.libcamera.org/patch/128/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20190102004903.24190-2-laurent.pinchart@ideasonboard.com>","date":"2019-01-02T00:49:02","name":"[libcamera-devel,2/3] libcamera: MediaDevice: Create entities with major and minor numbers","commit_ref":null,"pull_url":null,"state":"rejected","archived":false,"hash":"615090bb52da178d1d00c1b6d73675b815c0c5b0","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/1.1/people/2/?format=json","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/128/mbox/","series":[{"id":47,"url":"https://patchwork.libcamera.org/api/1.1/series/47/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=47","date":"2019-01-02T00:49:01","name":"[libcamera-devel,1/3] libcamera: media_device: Add DeviceInfo features","version":1,"mbox":"https://patchwork.libcamera.org/series/47/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/128/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/128/checks/","tags":{},"headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7B3C560B30\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  2 Jan 2019 01:48:08 +0100 (CET)","from avalon.bb.dnainternet.fi\n\t(dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 07C5C537\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  2 Jan 2019 01:48:07 +0100 (CET)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1546390088;\n\tbh=e8hkoztoWKXaxDWSisshkyI0Or3dA00sgdccn5X+DtE=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=KDx7UfVak1W3RasTW97mcExM8rMDWRMy6qd9uilkLgmu4l+QI/4emlenwOcQu5li7\n\tCjMpnBHdk5ev2HvLwW+4XZ3PjWlYNqYuE8G866rvs7+8ebb3w/3RVglJyoBu5fL7Rw\n\tZAnGNLtRmcWAsnlRKZf0VPQ/Cm9iexy57v9fWuGw=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Date":"Wed,  2 Jan 2019 02:49:02 +0200","Message-Id":"<20190102004903.24190-2-laurent.pinchart@ideasonboard.com>","X-Mailer":"git-send-email 2.19.2","In-Reply-To":"<20190102004903.24190-1-laurent.pinchart@ideasonboard.com>","References":"<20190102004903.24190-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH 2/3] libcamera: MediaDevice: Create\n\tentities with major and minor numbers","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Wed, 02 Jan 2019 00:48:08 -0000"},"content":"From: Jacopo Mondi <jacopo@jmondi.org>\n\nExtend the MediaEntity object with device node major and minor numbers,\nand retrieve them from the media graph using interfaces. They will be\nused by the DeviceEnumerator to retrieve the devnode path.\n\nSigned-off-by: Jacopo Mondi <jacopo@jmondi.org>\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n src/libcamera/include/media_device.h |  2 +\n src/libcamera/include/media_object.h |  9 +++-\n src/libcamera/media_device.cpp       | 65 +++++++++++++++++++++++++++-\n src/libcamera/media_object.cpp       | 46 ++++++++++++++++++--\n 4 files changed, 116 insertions(+), 6 deletions(-)","diff":"diff --git a/src/libcamera/include/media_device.h b/src/libcamera/include/media_device.h\nindex 3fcdb4b4d5f8..8d491a87867c 100644\n--- a/src/libcamera/include/media_device.h\n+++ b/src/libcamera/include/media_device.h\n@@ -54,6 +54,8 @@ private:\n \n \tstd::vector<MediaEntity *> entities_;\n \n+\tstruct media_v2_interface *findInterface(const struct media_v2_topology &topology,\n+\t\t\t\t\t\t unsigned int entityId);\n \tbool populateEntities(const struct media_v2_topology &topology);\n \tbool populatePads(const struct media_v2_topology &topology);\n \tbool populateLinks(const struct media_v2_topology &topology);\ndiff --git a/src/libcamera/include/media_object.h b/src/libcamera/include/media_object.h\nindex 65b55085a3b0..950a33286690 100644\n--- a/src/libcamera/include/media_object.h\n+++ b/src/libcamera/include/media_object.h\n@@ -80,21 +80,28 @@ class MediaEntity : public MediaObject\n {\n public:\n \tconst std::string &name() const { return name_; }\n+\tunsigned int major() const { return major_; }\n+\tunsigned int minor() const { return minor_; }\n \n \tconst std::vector<MediaPad *> &pads() const { return pads_; }\n \n \tconst MediaPad *getPadByIndex(unsigned int index) const;\n \tconst MediaPad *getPadById(unsigned int id) const;\n \n+\tint setDeviceNode(const std::string &devnode);\n+\n private:\n \tfriend class MediaDevice;\n \n-\tMediaEntity(const struct media_v2_entity *entity);\n+\tMediaEntity(const struct media_v2_entity *entity,\n+\t\t    unsigned int major = 0, unsigned int minor = 0);\n \tMediaEntity(const MediaEntity &) = delete;\n \t~MediaEntity();\n \n \tstd::string name_;\n \tstd::string devnode_;\n+\tunsigned int major_;\n+\tunsigned int minor_;\n \n \tstd::vector<MediaPad *> pads_;\n \ndiff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp\nindex 605e504be124..70b3fff3f492 100644\n--- a/src/libcamera/media_device.cpp\n+++ b/src/libcamera/media_device.cpp\n@@ -208,6 +208,7 @@ int MediaDevice::populate()\n \tstruct media_v2_entity *ents = nullptr;\n \tstruct media_v2_link *links = nullptr;\n \tstruct media_v2_pad *pads = nullptr;\n+\tstruct media_v2_interface *interfaces = nullptr;\n \t__u64 version = -1;\n \tint ret;\n \n@@ -221,6 +222,7 @@ int MediaDevice::populate()\n \t\ttopology.ptr_entities = reinterpret_cast<__u64>(ents);\n \t\ttopology.ptr_links = reinterpret_cast<__u64>(links);\n \t\ttopology.ptr_pads = reinterpret_cast<__u64>(pads);\n+\t\ttopology.ptr_interfaces = reinterpret_cast<__u64>(interfaces);\n \n \t\tret = ioctl(fd_, MEDIA_IOC_G_TOPOLOGY, &topology);\n \t\tif (ret < 0) {\n@@ -236,10 +238,12 @@ int MediaDevice::populate()\n \t\tdelete[] links;\n \t\tdelete[] ents;\n \t\tdelete[] pads;\n+\t\tdelete[] interfaces;\n \n \t\tents = new media_v2_entity[topology.num_entities];\n \t\tlinks = new media_v2_link[topology.num_links];\n \t\tpads = new media_v2_pad[topology.num_pads];\n+\t\tinterfaces = new media_v2_interface[topology.num_interfaces];\n \n \t\tversion = topology.topology_version;\n \t}\n@@ -253,6 +257,7 @@ int MediaDevice::populate()\n \tdelete[] links;\n \tdelete[] ents;\n \tdelete[] pads;\n+\tdelete[] interfaces;\n \n \tif (!valid_) {\n \t\tclear();\n@@ -367,6 +372,45 @@ void MediaDevice::clear()\n  * \\brief Global list of media entities in the media graph\n  */\n \n+/**\n+ * \\brief Find the interface associated with an entity\n+ * \\param topology The media topology as returned by MEDIA_IOC_G_TOPOLOGY\n+ * \\param entityId The entity id\n+ * \\return A pointer to the interface if found, or nullptr otherwise\n+ */\n+struct media_v2_interface *MediaDevice::findInterface(const struct media_v2_topology &topology,\n+\t\t\t       unsigned int entityId)\n+{\n+\tstruct media_v2_link *links = reinterpret_cast<struct media_v2_link *>\n+\t\t\t\t\t\t(topology.ptr_links);\n+\tunsigned int ifaceId = -1;\n+\n+\tfor (unsigned int i = 0; i < topology.num_links; ++i) {\n+\t\t/* Search for the interface to entity link. */\n+\t\tif (links[i].sink_id != entityId)\n+\t\t\tcontinue;\n+\n+\t\tif ((links[i].flags & MEDIA_LNK_FL_LINK_TYPE) !=\n+\t\t    MEDIA_LNK_FL_INTERFACE_LINK)\n+\t\t\tcontinue;\n+\n+\t\tifaceId = links[i].source_id;\n+\t}\n+\n+\tif (ifaceId == static_cast<unsigned int>(-1))\n+\t\treturn nullptr;\n+\n+\tstruct media_v2_interface *ifaces = reinterpret_cast<struct media_v2_interface *>\n+\t\t\t\t\t\t(topology.ptr_interfaces);\n+\n+\tfor (unsigned int i = 0; i < topology.num_interfaces; ++i) {\n+\t\tif (ifaces[i].id == ifaceId)\n+\t\t\treturn &ifaces[i];\n+\t}\n+\n+\treturn nullptr;\n+}\n+\n /*\n  * For each entity in the media graph create a MediaEntity and store a\n  * reference in the media device objects map and entities list.\n@@ -377,7 +421,26 @@ bool MediaDevice::populateEntities(const struct media_v2_topology &topology)\n \t\t\t\t\t (topology.ptr_entities);\n \n \tfor (unsigned int i = 0; i < topology.num_entities; ++i) {\n-\t\tMediaEntity *entity = new MediaEntity(&mediaEntities[i]);\n+\t\t/*\n+\t\t * Find the interface linked to this entity to get the device\n+\t\t * node major and minor numbers.\n+\t\t */\n+\t\tstruct media_v2_interface *iface =\n+\t\t\tfindInterface(topology, mediaEntities[i].id);\n+\t\tif (!iface) {\n+\t\t\tLOG(Error) << \"Failed to find interface link for \"\n+\t\t\t\t   << \"entity with id: \" << mediaEntities[i].id;\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\tMediaEntity *entity;\n+\t\tif (iface)\n+\t\t\tentity = new MediaEntity(&mediaEntities[i],\n+\t\t\t\t\t\t iface->devnode.major,\n+\t\t\t\t\t\t iface->devnode.minor);\n+\t\telse\n+\t\t\tentity = new MediaEntity(&mediaEntities[i]);\n+\n \t\tif (!addObject(entity)) {\n \t\t\tdelete entity;\n \t\t\treturn false;\ndiff --git a/src/libcamera/media_object.cpp b/src/libcamera/media_object.cpp\nindex b64dcc3c8fb4..69e5cc74264d 100644\n--- a/src/libcamera/media_object.cpp\n+++ b/src/libcamera/media_object.cpp\n@@ -6,9 +6,8 @@\n  */\n \n #include <errno.h>\n-#include <fcntl.h>\n #include <string.h>\n-#include <sys/stat.h>\n+#include <unistd.h>\n \n #include <string>\n #include <vector>\n@@ -212,6 +211,20 @@ void MediaPad::addLink(MediaLink *link)\n  * \\return The entity name\n  */\n \n+/**\n+ * \\fn MediaEntity::major()\n+ * \\brief Retrieve the major number of the interface associated with the entity\n+ * \\return The interface major number, or 0 if the entity isn't associated with\n+ * an interface\n+ */\n+\n+/**\n+ * \\fn MediaEntity::minor()\n+ * \\brief Retrieve the minor number of the interface associated with the entity\n+ * \\return The interface minor number, or 0 if the entity isn't associated with\n+ * an interface\n+ */\n+\n /**\n  * \\fn MediaEntity::pads()\n  * \\brief Retrieve all pads of the entity\n@@ -238,6 +251,7 @@ const MediaPad *MediaEntity::getPadByIndex(unsigned int index) const\n  * \\param id The pad id\n  * \\return The pad identified by \\a id, or nullptr if no such pad exist\n  */\n+\n const MediaPad *MediaEntity::getPadById(unsigned int id) const\n {\n \tfor (MediaPad *p : pads_) {\n@@ -248,12 +262,36 @@ const MediaPad *MediaEntity::getPadById(unsigned int id) const\n \treturn nullptr;\n }\n \n+/**\n+ * \\brief Set the path to the device node for the associated interface\n+ * \\param devnode The interface device node path associated with this entity\n+ * \\return 0 on success, or a negative error code if the device node can't be\n+ * accessed\n+ */\n+int MediaEntity::setDeviceNode(const std::string &devnode)\n+{\n+\t/* Make sure the device node can be accessed. */\n+\tint ret = ::access(devnode.c_str(), R_OK | W_OK);\n+\tif (ret < 0) {\n+\t\tret = -errno;\n+\t\tLOG(Error) << \"Device node \" << devnode << \" can't be accessed: \"\n+\t\t\t   << strerror(-ret);\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n /**\n  * \\brief Construct a MediaEntity\n  * \\param entity The media entity kernel data\n+ * \\param major The major number of the entity associated interface\n+ * \\param minor The minor number of the entity associated interface\n  */\n-MediaEntity::MediaEntity(const struct media_v2_entity *entity)\n-\t: MediaObject(entity->id), name_(entity->name)\n+MediaEntity::MediaEntity(const struct media_v2_entity *entity,\n+\t\t\t unsigned int major, unsigned int minor)\n+\t: MediaObject(entity->id), name_(entity->name),\n+\t  major_(major), minor_(minor)\n {\n }\n \n","prefixes":["libcamera-devel","2/3"]}