util: add i2c->pcie map build method
Move method to util that handles creating a mapping between i2c-bus
numbers and their pci-e slot names. It's done as a list of tuples.
Tested: Only ran unit-tests.
Change-Id: Ie09d193add63245eebcf3806255311232a7c4c9a
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/pcie_i2c.cpp b/pcie_i2c.cpp
index 88eb66c..6f93d01 100644
--- a/pcie_i2c.cpp
+++ b/pcie_i2c.cpp
@@ -21,9 +21,6 @@
#include <cstdint>
#include <cstring>
-#include <filesystem>
-#include <fstream>
-#include <regex>
#include <sstream>
#include <string>
#include <system_error>
@@ -33,7 +30,6 @@
{
namespace ipmi
{
-namespace fs = std::filesystem;
namespace
{
@@ -82,49 +78,7 @@
}
// If there are already entries in the vector, clear them.
- if (!pcie_i2c_map.empty())
- pcie_i2c_map.clear();
-
- // Build a vector with i2c bus to pcie slot mapping.
- // Iterate through all the devices under "/sys/bus/i2c/devices".
- for (auto& i2c_dev : fs::directory_iterator("/sys/bus/i2c/devices"))
- {
- std::string i2c_dev_path = i2c_dev.path();
- std::smatch i2c_dev_string_number;
- std::regex e("(i2c-)(\\d+)");
- // Check if the device has "i2c-" in its path.
- if (std::regex_search(i2c_dev_path, i2c_dev_string_number, e))
- {
- // Check if the i2c device has "pcie-slot" file under "of-node" dir.
- std::string pcie_slot_path = i2c_dev_path + "/of_node/pcie-slot";
- std::string pcie_slot;
- // Read the "pcie-slot" name from the "pcie-slot" file.
- pcie_slot = readPropertyFile(pcie_slot_path);
- if (pcie_slot.empty())
- {
- continue;
- }
- std::string pcie_slot_name;
- std::string pcie_slot_full_path;
- // Append the "pcie-slot" name to dts base.
- pcie_slot_full_path.append("/proc/device-tree");
- pcie_slot_full_path.append(pcie_slot);
- // Read the "label" which contains the pcie slot name.
- pcie_slot_full_path.append("/label");
- pcie_slot_name = readPropertyFile(pcie_slot_full_path);
- if (pcie_slot_name.empty())
- {
- continue;
- }
- // Get the i2c bus number from the i2c device path.
- uint32_t i2c_bus_number = i2c_dev_string_number[2].matched
- ? std::stoi(i2c_dev_string_number[2])
- : 0;
- // Store the i2c bus number and the pcie slot name in the vector.
- pcie_i2c_map.push_back(
- std::make_tuple(i2c_bus_number, pcie_slot_name));
- }
- }
+ pcie_i2c_map = buildPcieMap();
struct PcieSlotCountReply reply;
reply.subcommand = SysPcieSlotCount;
diff --git a/util.cpp b/util.cpp
index 34b0f9b..eebc84e 100644
--- a/util.cpp
+++ b/util.cpp
@@ -1,17 +1,22 @@
#include "util.hpp"
+#include <cstdint>
#include <cstdio>
+#include <filesystem>
#include <fstream>
#include <nlohmann/json.hpp>
#include <phosphor-logging/elog-errors.hpp>
+#include <regex>
#include <string>
+#include <tuple>
+#include <vector>
#include <xyz/openbmc_project/Common/error.hpp>
namespace google
{
namespace ipmi
{
-
+namespace fs = std::filesystem;
using namespace phosphor::logging;
using InternalFailure =
sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
@@ -67,5 +72,60 @@
return "";
}
+std::vector<std::tuple<std::uint32_t, std::string>> buildPcieMap()
+{
+ std::vector<std::tuple<std::uint32_t, std::string>> pcie_i2c_map;
+
+ // Build a vector with i2c bus to pcie slot mapping.
+ // Iterate through all the devices under "/sys/bus/i2c/devices".
+ for (const auto& i2c_dev : fs::directory_iterator("/sys/bus/i2c/devices"))
+ {
+ std::string i2c_dev_path = i2c_dev.path();
+ std::smatch i2c_dev_string_number;
+ std::regex e("(i2c-)(\\d+)");
+
+ // Check if the device has "i2c-" in its path.
+ if (std::regex_search(i2c_dev_path, i2c_dev_string_number, e))
+ {
+ // Check if the i2c device has "pcie-slot" file under "of-node" dir.
+ std::string pcie_slot_path = i2c_dev_path + "/of_node/pcie-slot";
+ std::string pcie_slot;
+
+ // Read the "pcie-slot" name from the "pcie-slot" file.
+ pcie_slot = readPropertyFile(pcie_slot_path);
+ if (pcie_slot.empty())
+ {
+ continue;
+ }
+ std::string pcie_slot_name;
+ std::string pcie_slot_full_path;
+
+ // Append the "pcie-slot" name to dts base.
+ pcie_slot_full_path.append("/proc/device-tree");
+ pcie_slot_full_path.append(pcie_slot);
+
+ // Read the "label" which contains the pcie slot name.
+ pcie_slot_full_path.append("/label");
+ pcie_slot_name = readPropertyFile(pcie_slot_full_path);
+
+ if (pcie_slot_name.empty())
+ {
+ continue;
+ }
+
+ // Get the i2c bus number from the i2c device path.
+ std::uint32_t i2c_bus_number =
+ i2c_dev_string_number[2].matched
+ ? std::stoi(i2c_dev_string_number[2])
+ : 0;
+ // Store the i2c bus number and the pcie slot name in the vector.
+ pcie_i2c_map.push_back(
+ std::make_tuple(i2c_bus_number, pcie_slot_name));
+ }
+ }
+
+ return pcie_i2c_map;
+}
+
} // namespace ipmi
} // namespace google
diff --git a/util.hpp b/util.hpp
index 760a1b2..d8c8bbd 100644
--- a/util.hpp
+++ b/util.hpp
@@ -1,7 +1,10 @@
#pragma once
+#include <cstdint>
#include <nlohmann/json.hpp>
#include <string>
+#include <tuple>
+#include <vector>
namespace google
{
@@ -25,5 +28,12 @@
*/
std::string readPropertyFile(const std::string& fileName);
+/**
+ * Build a map of the i2c bus numbers to their PCIe slot names.
+ *
+ * @return list of pairs of i2c bus with their corresponding slot names.
+ */
+std::vector<std::tuple<std::uint32_t, std::string>> buildPcieMap();
+
} // namespace ipmi
} // namespace google