Stop reading devices that don't like it
Attempting to read devices that don't respond well
to reading causes the fru device scan time to go up,
stop doing that.
Tested: Scan time went down, less messages like
failed to read bus X address XX
Change-Id: I56847f957b7c6bf88ad158ecb4c6a621599c11ab
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/src/FruDevice.cpp b/src/FruDevice.cpp
index 48cec11..42ca311 100644
--- a/src/FruDevice.cpp
+++ b/src/FruDevice.cpp
@@ -78,6 +78,8 @@
std::pair<size_t, size_t>, std::shared_ptr<sdbusplus::asio::dbus_interface>>
foundDevices;
+static boost::container::flat_map<size_t, std::set<size_t>> failedAddresses;
+
boost::asio::io_service io;
auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
auto objServer = sdbusplus::asio::object_server(systemBus);
@@ -248,6 +250,27 @@
return read(fd, buf, len);
}
+static int getRootBus(size_t bus)
+{
+ auto ec = std::error_code();
+ auto path = std::filesystem::read_symlink(
+ std::filesystem::path("/sys/bus/i2c/devices/i2c-" +
+ std::to_string(bus) + "/mux_device"),
+ ec);
+ if (ec)
+ {
+ return -1;
+ }
+
+ std::string filename = path.filename();
+ auto findBus = filename.find("-");
+ if (findBus == std::string::npos)
+ {
+ return -1;
+ }
+ return std::stoi(filename.substr(0, findBus));
+}
+
static bool isMuxBus(size_t bus)
{
return is_symlink(std::filesystem::path(
@@ -467,6 +490,15 @@
// Scan for i2c eeproms loaded on this bus.
std::set<int> skipList = findI2CEeproms(bus, devices);
+ std::set<size_t>& failedItems = failedAddresses[bus];
+
+ std::set<size_t>* rootFailures = nullptr;
+ int rootBus = getRootBus(bus);
+
+ if (rootBus >= 0)
+ {
+ rootFailures = &(failedAddresses[rootBus]);
+ }
for (int ii = first; ii <= last; ii++)
{
@@ -496,12 +528,27 @@
makeProbeInterface(bus, ii);
+ if (failedItems.find(ii) != failedItems.end())
+ {
+ // if we failed to read it once, unlikely we can read it later
+ continue;
+ }
+
+ if (rootFailures != nullptr)
+ {
+ if (rootFailures->find(ii) != rootFailures->end())
+ {
+ continue;
+ }
+ }
+
/* Check for Device type if it is 8 bit or 16 bit */
int flag = isDevice16Bit(file);
if (flag < 0)
{
std::cerr << "failed to read bus " << bus << " address " << ii
<< "\n";
+ failedItems.insert(ii);
continue;
}