From patchwork Fri Jan 25 21:37:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 397 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4BF1960C65 for ; Fri, 25 Jan 2019 22:37:08 +0100 (CET) Received: from pendragon.lan (unknown [IPv6:2a02:a03f:3c6a:b300:cba4:9bfe:2eae:a6b4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AAAD9325 for ; Fri, 25 Jan 2019 22:37:07 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1548452227; bh=Vdo882y4gOlTUPBUFMKvF4nHiy4YqxgJmpGvgJHhw9A=; h=From:To:Subject:Date:From; b=DojmP4mkxuez/Yqu5RAGFmuQWKZX6Po+kyHz0r5YqGOOCehRfIB6GjbWOFFlE4Rnq 3jj/Pi78N5MipH438979z9lUOsbVfbWY8oroZ0iwQlSlxLaea0So2Pdso6aS8HPRrl ZFN5IIwRuQszmaxPLoGSEy5p6Af566U6Lr7KoZxc= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Jan 2019 23:37:03 +0200 Message-Id: <20190125213703.6148-1-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.19.2 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH] 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 21:37:08 -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 --- src/libcamera/include/media_device.h | 3 ++ src/libcamera/media_device.cpp | 44 ++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/libcamera/include/media_device.h b/src/libcamera/include/media_device.h index 27a2b46a4392..31413b9e4605 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 fixupEntity(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..715ba8263436 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,24 @@ 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]; + + fixupEntity(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 +662,39 @@ bool MediaDevice::populateLinks(const struct media_v2_topology &topology) return true; } +/** + * \brief Fixup entity information using legacy API + * \param[in] entity The entity + * + * This function is used as a fallback to query entity information using the + * legacy MEDIA_IOC_ENUM_ENTITIES ioctl when running on a kernel version that + * doesn't provide all the information needed through the MEDIA_IOC_G_TOPOLOGY + * ioctl. + */ +void MediaDevice::fixupEntity(struct media_v2_entity *entity) +{ + /* + * The media_v2_entity structure was missing the flag field before + * v4.19. + */ + if (MEDIA_V2_ENTITY_HAS_FLAGS(version_)) + return; + + 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