[libcamera-devel] [PATCH v3] libcamera: media_device: Fallback to legacy ioctls on older kernels
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Sat Jan 26 09:55:02 CET 2019
Hi Kieran,
On Sat, Jan 26, 2019 at 07:46:17AM +0000, Kieran Bingham wrote:
> On 25/01/2019 23:09, Laurent Pinchart wrote:
> > 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.
> >
>
> This does indeed fix my issue.
>
> Tested-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
>
> Is a 'fixes' tag appropriate here? Perhaps not, because it's not so much
> a bug in the original code, as a missing feature.
I think it makes sense to add a fixes tag pointing to the patch that
broke the test. Done, addressed the issue pointed out below, and pushed.
> Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
>
> Please push this as soon as you're ready.
>
> > Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > Reviewed-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> > ---
> > 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
>
> (Very) minor nit :
>
> s/using legacy/using the legacy/
>
> > + * \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
> >
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list