sysfs: refactor findCallout
- Export findCalloutPath so other modules can use it.
- Change parameter to hwmon instance path to avoid
fs::canonical outside sysfs.cpp.
- Check for the iio-hwmon driver instead of relying on
DT nodes having 'iio-hwmon' in them.
- For iio devices, provide a /sys/devices path rather
than a DT path.
- Use existing application indenting and doxygen style.
Change-Id: I16c2dc7417eb68f7cbef44243f481df8040ec1fd
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/sysfs.cpp b/sysfs.cpp
index 4117b2f..6d52029 100644
--- a/sysfs.cpp
+++ b/sysfs.cpp
@@ -83,31 +83,83 @@
return emptyString;
}
-/**
- * @brief Return the path to use for a call out.
- *
- * If the path does not contain iio-hwmon, assume passed in path is the call
- * out path.
- *
- * @param[in] ofPath - Open firmware path to search for matching phandle value
- *
- * @return Path to use for call out
- */
-std::string findCalloutPath(const std::string& ofPath)
+std::string findCalloutPath(const std::string& instancePath)
{
- static constexpr auto iioHwmonStr = "iio-hwmon";
+ // Follow the hwmon instance (/sys/class/hwmon/hwmon<N>)
+ // /sys/devices symlink.
+ fs::path devPath{instancePath};
+ devPath /= "device";
- if (ofPath.find(iioHwmonStr) != std::string::npos)
+ try
{
- auto matchpath = findPhandleMatch(ofPath, ofRoot);
- auto n = matchpath.rfind('/');
+ devPath = fs::canonical(devPath);
+ }
+ catch (const std::system_error& e)
+ {
+ return emptyString;
+ }
+
+ // See if the device is backed by the iio-hwmon driver.
+ fs::path p{devPath};
+ p /= "driver";
+ p = fs::canonical(p);
+
+ if (p.filename() != "iio_hwmon")
+ {
+ // Not backed by iio-hwmon. The device pointed to
+ // is the callout device.
+ return devPath;
+ }
+
+ // Find the DT path to the iio-hwmon platform device.
+ fs::path ofDevPath{devPath};
+ ofDevPath /= "of_node";
+
+ try
+ {
+ ofDevPath = fs::canonical(ofDevPath);
+ }
+ catch (const std::system_error& e)
+ {
+ return emptyString;
+ }
+
+ // Search /sys/bus/iio/devices for the phandle in io-channels.
+ // If a match is found, use the corresponding /sys/devices
+ // iio device as the callout device.
+ static constexpr auto iioDevices = "/sys/bus/iio/devices";
+ for (const auto& iioDev: fs::recursive_directory_iterator(iioDevices))
+ {
+ p = iioDev.path();
+ p /= "of_node";
+
+ try
+ {
+ p = fs::canonical(p);
+ }
+ catch (const std::system_error& e)
+ {
+ continue;
+ }
+
+ auto match = findPhandleMatch(ofDevPath, p);
+ auto n = match.rfind('/');
if (n != std::string::npos)
{
- return matchpath.substr(0, n);
+ // This is the iio device referred to by io-channels.
+ // Remove iio:device<N>.
+ try
+ {
+ return fs::canonical(iioDev).parent_path();
+ }
+ catch (const std::system_error& e)
+ {
+ return emptyString;
+ }
}
}
- return ofPath;
+ return emptyString;
}
std::string findHwmon(const std::string& ofNode)
@@ -201,7 +253,7 @@
exit(0);
}
instancePath /= "device";
- auto callOutPath = findCalloutPath(fs::canonical(instancePath));
+ auto callOutPath = findCalloutPath(instancePath);
using namespace sdbusplus::xyz::openbmc_project::Sensor::Device::Error;
// this throws a ReadFailure.
@@ -209,8 +261,7 @@
xyz::openbmc_project::Sensor::Device::
ReadFailure::CALLOUT_ERRNO(rc),
xyz::openbmc_project::Sensor::Device::
- ReadFailure::CALLOUT_DEVICE_PATH(
- fs::canonical(callOutPath).c_str()));
+ ReadFailure::CALLOUT_DEVICE_PATH(callOutPath.c_str()));
}
return value;
@@ -246,14 +297,13 @@
// or write system calls that got us here.
auto rc = errno;
instancePath /= "device";
- auto callOutPath = findCalloutPath(fs::canonical(instancePath));
+ auto callOutPath = findCalloutPath(instancePath);
using namespace sdbusplus::xyz::openbmc_project::Control::Device::Error;
report<WriteFailure>(
xyz::openbmc_project::Control::Device::
WriteFailure::CALLOUT_ERRNO(rc),
xyz::openbmc_project::Control::Device::
- WriteFailure::CALLOUT_DEVICE_PATH(
- fs::canonical(callOutPath).c_str()));
+ WriteFailure::CALLOUT_DEVICE_PATH(callOutPath.c_str()));
exit(EXIT_FAILURE);
}
diff --git a/sysfs.hpp b/sysfs.hpp
index 9a8211d..f0e92db 100644
--- a/sysfs.hpp
+++ b/sysfs.hpp
@@ -64,6 +64,17 @@
*/
std::string findHwmon(const std::string& ofNode);
+/** @brief Return the path to use for a call out.
+ *
+ * Return an empty string if a callout path cannot be
+ * found.
+ *
+ * @param[in] instancePath - /sys/class/hwmon/hwmon<N> path.
+ *
+ * @return Path to use for call out
+ */
+std::string findCalloutPath(const std::string& instancePath);
+
/** @brief Read an hwmon sysfs value.
*
* Calls exit(3) with bad status on failure.