Add reading FRU support from different MUX channel

If the same FRU content is available in different MUX channels under
same bus, the current implementation will reject it. Also fixed
second layer MUX buses (buses from MUX which is already behind a MUX)
is not treating the FRU from parent buses as a new FRU.

Tested:
The fix was tested on a platform with HSBP FRUs pupulated on both
channels of same MUX and found working fine.

Signed-off-by: AKSHAY RAVEENDRAN K <akshay.raveendran.k@intel.com>
Signed-off-by: Zhikui Ren <zhikui.ren@intel.com>
Change-Id: I0e541f3047de7122540633619987976b3d51a8e8
diff --git a/src/fru_device.cpp b/src/fru_device.cpp
index 50f1e4b..d2af2a2 100644
--- a/src/fru_device.cpp
+++ b/src/fru_device.cpp
@@ -79,6 +79,7 @@
     foundDevices;
 
 static boost::container::flat_map<size_t, std::set<size_t>> failedAddresses;
+static boost::container::flat_map<size_t, std::set<size_t>> fruAddresses;
 
 boost::asio::io_service io;
 
@@ -377,6 +378,8 @@
         // 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>& foundItems = fruAddresses[bus];
+        foundItems.clear();
 
         std::set<size_t>* rootFailures = nullptr;
         int rootBus = getRootBus(bus);
@@ -384,6 +387,7 @@
         if (rootBus >= 0)
         {
             rootFailures = &(failedAddresses[rootBus]);
+            foundItems = fruAddresses[rootBus];
         }
 
         constexpr int startSkipSlaveAddr = 0;
@@ -391,6 +395,10 @@
 
         for (int ii = first; ii <= last; ii++)
         {
+            if (foundItems.find(ii) != foundItems.end())
+            {
+                continue;
+            }
             if (skipList.find(ii) != skipList.end())
             {
                 continue;
@@ -464,6 +472,7 @@
             }
 
             devices->emplace(ii, device);
+            fruAddresses[bus].insert(ii);
         }
         return 1;
     });
@@ -695,18 +704,6 @@
             std::string path = busIface.second->get_object_path();
             if (std::regex_match(path, std::regex(productName + "(_\\d+|)$")))
             {
-                if (isMuxBus(bus) && bus != busIface.first.first &&
-                    address == busIface.first.second &&
-                    (getFRUInfo(static_cast<uint8_t>(busIface.first.first),
-                                static_cast<uint8_t>(busIface.first.second)) ==
-                     getFRUInfo(static_cast<uint8_t>(bus),
-                                static_cast<uint8_t>(address))))
-                {
-                    // This device is already added to the lower numbered bus,
-                    // do not replicate it.
-                    return;
-                }
-
                 // Check if the match named has extra information.
                 found = true;
                 std::smatch baseMatch;
@@ -1108,7 +1105,8 @@
         return false;
     }
 
-    struct FruArea fruAreaParams{};
+    struct FruArea fruAreaParams
+    {};
     size_t fruDataIter = 0;
 
     if (!findFruAreaLocationAndField(fruData, propertyName, fruAreaParams,