From patchwork Fri Jan 25 23:09:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 399 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7A59860B1B for ; Sat, 26 Jan 2019 00:09:47 +0100 (CET) Received: from pendragon.lan (unknown [IPv6:2a02:a03f:3c6a:b300:cba4:9bfe:2eae:a6b4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 11660325 for ; Sat, 26 Jan 2019 00:09:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1548457787; bh=QGnQMcKT1mEKnzAg9c88RrdT96SmHpyQlnjBjWea/UI=; h=From:To:Subject:Date:From; b=Y6SoZI2wo8vIGP+ZGHCHavLjNQsDlsP0rLDvogqf50CMw9pP/fxnWPSLIUsxlH6xj PV4fDijGnDudx/eMzWWfw+c+zTKExvcEvp+Zdpl1rV/lThAcv1J4XPnuFyKJMTcjdS SKCK6l+LOhA9BKe3F2IJz9Mk5JcCzypFYfAAyf6w= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 26 Jan 2019 01:09:42 +0200 Message-Id: <20190125230942.17521-1-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.19.2 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3] libcamera: media_device: Fallback to legacy ioctls on older kernels X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Jan 2019 23:09:47 -0000 Prior to kernel v4.19, the MEDIA_IOC_G_TOPOLOGY ioctl didn't expose entity flags. Fallback to calling MEDIA_IOC_ENUM_ENTITIES for each entity to retrieve the flags in that case. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Tested-by: Kieran Bingham Reviewed-by: Kieran Bingham --- Changes since v1: - Move MEDIA_V2_ENTITY_HAS_FLAGS() test to populateEntities() - Rename fixupEntity() to fixupEntityFlag() --- src/libcamera/include/media_device.h | 3 ++ src/libcamera/media_device.cpp | 41 ++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/libcamera/include/media_device.h b/src/libcamera/include/media_device.h index 27a2b46a4392..9f038093b2b2 100644 --- a/src/libcamera/include/media_device.h +++ b/src/libcamera/include/media_device.h @@ -56,6 +56,8 @@ private: std::string driver_; std::string deviceNode_; std::string model_; + unsigned int version_; + int fd_; bool valid_; bool acquired_; @@ -72,6 +74,7 @@ private: bool populateEntities(const struct media_v2_topology &topology); bool populatePads(const struct media_v2_topology &topology); bool populateLinks(const struct media_v2_topology &topology); + void fixupEntityFlags(struct media_v2_entity *entity); friend int MediaLink::setEnabled(bool enable); int setupLink(const MediaLink *link, unsigned int flags); diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp index be81bd8c4c23..a4995b996601 100644 --- a/src/libcamera/media_device.cpp +++ b/src/libcamera/media_device.cpp @@ -167,6 +167,7 @@ int MediaDevice::open() driver_ = info.driver; model_ = info.model; + version_ = info.media_version; return 0; } @@ -553,20 +554,29 @@ bool MediaDevice::populateEntities(const struct media_v2_topology &topology) (topology.ptr_entities); for (unsigned int i = 0; i < topology.num_entities; ++i) { + struct media_v2_entity *ent = &mediaEntities[i]; + + /* + * The media_v2_entity structure was missing the flag field before + * v4.19. + */ + if (!MEDIA_V2_ENTITY_HAS_FLAGS(version_)) + fixupEntityFlags(ent); + /* * Find the interface linked to this entity to get the device * node major and minor numbers. */ struct media_v2_interface *iface = - findInterface(topology, mediaEntities[i].id); + findInterface(topology, ent->id); MediaEntity *entity; if (iface) - entity = new MediaEntity(this, &mediaEntities[i], + entity = new MediaEntity(this, ent, iface->devnode.major, iface->devnode.minor); else - entity = new MediaEntity(this, &mediaEntities[i]); + entity = new MediaEntity(this, ent); if (!addObject(entity)) { delete entity; @@ -657,6 +667,31 @@ bool MediaDevice::populateLinks(const struct media_v2_topology &topology) return true; } +/** + * \brief Fixup entity flags using legacy API + * \param[in] entity The entity + * + * This function is used as a fallback to query entity flags using the legacy + * MEDIA_IOC_ENUM_ENTITIES ioctl when running on a kernel version that doesn't + * provide them through the MEDIA_IOC_G_TOPOLOGY ioctl. + */ +void MediaDevice::fixupEntityFlags(struct media_v2_entity *entity) +{ + struct media_entity_desc desc = {}; + desc.id = entity->id; + + int ret = ioctl(fd_, MEDIA_IOC_ENUM_ENTITIES, &desc); + if (ret < 0) { + ret = -errno; + LOG(MediaDevice, Debug) + << "Failed to retrieve information for entity " + << entity->id << ": " << strerror(-ret); + return; + } + + entity->flags = desc.flags; +} + /** * \brief Apply \a flags to a link between two pads * \param link The link to apply flags to