[libcamera-devel] [PATCH v6 4/9] libcamera: utils: Add method to lookup firmware ID in sysfs
Jacopo Mondi
jacopo at jmondi.org
Tue Aug 4 09:49:11 CEST 2020
Hi Niklas,
On Mon, Aug 03, 2020 at 11:17:28PM +0200, Niklas Söderlund wrote:
> A devices firmware description is recorded differently in sysfs
> depending on if the devices uses OF or ACPI. Add a helper to abstract
s/on if/if/
s/devices/device (and that's more likely a system decision, not a
device one)
> this, allowing users to not care which of the two are used.
users not to care
>
> For OF-based systems the ID is the full path of the device in the
> device tree description. For ACPI-based systems the ID is the ACPI
> firmware nodes path. Both ID sources are guaranteed to be unique and
> persistent as long as the firmware of the system is not changed.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> ---
> include/libcamera/internal/utils.h | 2 +
> src/libcamera/utils.cpp | 61 ++++++++++++++++++++++++++++++
> 2 files changed, 63 insertions(+)
>
> diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h
> index 45cd6f120c51586b..69977340e2593db6 100644
> --- a/include/libcamera/internal/utils.h
> +++ b/include/libcamera/internal/utils.h
> @@ -200,6 +200,8 @@ details::StringSplitter split(const std::string &str, const std::string &delim);
> std::string libcameraBuildPath();
> std::string libcameraSourcePath();
>
> +int tryLookupFirmwareID(const std::string &devPath, std::string *id);
> +
> constexpr unsigned int alignDown(unsigned int value, unsigned int alignment)
> {
> return value / alignment * alignment;
> diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp
> index 615df46ac142a2a9..07ebce61f230e5f0 100644
> --- a/src/libcamera/utils.cpp
> +++ b/src/libcamera/utils.cpp
> @@ -9,6 +9,7 @@
>
> #include <dlfcn.h>
> #include <elf.h>
> +#include <fstream>
> #include <iomanip>
> #include <limits.h>
> #include <link.h>
> @@ -444,6 +445,66 @@ std::string libcameraSourcePath()
> return path + "/";
> }
>
> +/**
> + * \brief Try to read a device firmware ID from sysfs
> + * \param[in] devPath Path in sysfs to search
> + * \param[out] id Location to store ID if found
> + *
> + * The ID recorded in the devices firmware description is recorded differently
> + * in sysfs depending on if the devices uses OF or ACPI. This helper abstracts
> + * this away, allowing callers to not care which of the two are used.
Same comments as for the commit message
> + *
> + * For OF-based systems the ID is the full path of the device in the device tree
> + * description. For ACPI-based systems the ID is the ACPI firmware nodes path.
> + * Both ID sources are guaranteed to be unique and persistent as long as the
> + * firmware of the system is not changed.
> + *
> + * \return 0 on success or a negative error code otherwise
> + * \retval -ENOMEM \a id is nullptr
> + * \retval -EINVAL Error when looking up firmware ID
> + * \retval -ENODEV No firmware ID aviable for device
available
> + */
> +int tryLookupFirmwareID(const std::string &devPath, std::string *id)
I'm going to be picky on names, I know, but why 'try' ? Beause this
function can fail ? Can't the other ones ? I would just 'firwareId()'
> +{
> + struct stat statbuf;
> + std::string path;
> +
> + if (!id)
> + return -EINVAL;
How can you pass a null string pointer ? By calling this method with
nullptr explicitely only, isn't it ? Is this worth this check ?
> +
> + /* Try to lookup ID as if the system where OF-based. */
I don't get what this comment means. Maybe 'as is the system was
OF-based' ? Why not 'ID lookup for OF-based systems' ?
> + path = devPath + "/of_node";
> + if (stat(path.c_str(), &statbuf) == 0) {
Can stat fail for other reasons and not just because the file is not
there ? Should be check the return value and propagate errors which
are not caused by the file not being there ? Looking at the stat man
page it's not trivial though as I see both ENOENT and ENODIR could be
returned..
> + char *ofPath = realpath(path.c_str(), nullptr);
> + if (!ofPath)
> + return -EINVAL;
> +
> + *id = ofPath;
> + free(ofPath);
> +
> + static const std::string dropStr = "/sys/firmware/devicetree/";
> + if (id->find(dropStr) == 0)
> + id->erase(0, dropStr.length());
> +
> + return 0;
> + }
> +
> + /* Try to lookup ID as if the system where ACPI-based. */
Same
> + path = devPath + "/firmware_node/path";
> + if (stat(path.c_str(), &statbuf) == 0) {
And same here as well :)
> + std::ifstream file(path.c_str());
> + if (!file.is_open())
> + return -EINVAL;
> +
> + std::getline(file, *id);
> + file.close();
> +
> + return 0;
> + }
> +
> + return -ENODEV;
> +}
> +
> /**
> * \fn alignDown(unsigned int value, unsigned int alignment)
> * \brief Align \a value down to \a alignment
> --
> 2.28.0
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
More information about the libcamera-devel
mailing list