diff --git a/hsbp-manager/src/hsbp_manager.cpp b/hsbp-manager/src/hsbp_manager.cpp
index 9bb1367..bc92a32 100644
--- a/hsbp-manager/src/hsbp_manager.cpp
+++ b/hsbp-manager/src/hsbp_manager.cpp
@@ -16,12 +16,14 @@
 
 #include "utils.hpp"
 
+#include <algorithm>
 #include <bitset>
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/asio/posix/stream_descriptor.hpp>
 #include <boost/asio/steady_timer.hpp>
 #include <boost/container/flat_set.hpp>
 #include <filesystem>
+#include <forward_list>
 #include <fstream>
 #include <gpiod.hpp>
 #include <iostream>
@@ -36,28 +38,545 @@
 #include <linux/i2c-dev.h>
 }
 
-constexpr const char* configType =
+/****************************************************************************/
+/******************** Global Constants/Type Declarations ********************/
+/****************************************************************************/
+constexpr const char* hsbpCpldInft =
     "xyz.openbmc_project.Configuration.Intel_HSBP_CPLD";
+constexpr const char* hsbpConfigIntf =
+    "xyz.openbmc_project.Configuration.HSBPConfiguration";
+constexpr const char* nvmeIntf = "xyz.openbmc_project.Inventory.Item.NVMe";
 constexpr const char* busName = "xyz.openbmc_project.HsbpManager";
 
 constexpr size_t scanRateSeconds = 5;
 constexpr size_t maxDrives = 8; // only 1 byte alloted
 
+using NvmeMapping = std::vector<std::string>;
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/**************************** Enums Definitions *****************************/
+/****************************************************************************/
+enum class AppState : uint8_t
+{
+    idle,
+    loadingHsbpConfig,
+    hsbpConfigLoaded,
+    loadingComponents,
+    componentsLoaded,
+    loadingBackplanes,
+    backplanesLoaded,
+    loadingDrives,
+    drivesLoaded
+};
+
+enum class BlinkPattern : uint8_t
+{
+    off = 0x0,
+    error = 0x2,
+    terminate = 0x3
+};
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/************ HSBP Configuration related struct/class Definitions ***********/
+/****************************************************************************/
+struct HsbpConfig
+{
+    size_t rootBus;
+    std::vector<std::string> supportedHsbps;
+    std::unordered_map<std::string, NvmeMapping> hsbpNvmeMap;
+    std::vector<std::string> clockBufferTypes;
+    std::vector<std::string> ioExpanderTypes;
+
+    void clearConfig()
+    {
+        rootBus = -1;
+        supportedHsbps.clear();
+        hsbpNvmeMap.clear();
+        clockBufferTypes.clear();
+        ioExpanderTypes.clear();
+    }
+};
+
+class ClockBuffer
+{
+    size_t bus;
+    size_t address;
+    std::string modeOfOperation;
+    size_t outCtrlBaseAddr;
+    size_t outCtrlByteCount;
+    std::unordered_map<std::string, std::vector<std::string>> byteMap;
+    std::string name;
+    std::string type;
+
+    int file = -1;
+    bool initialized = false;
+
+    void initialize()
+    {
+        /* Execute below operation only when mode of operation is SMBus. By
+         * default the clock buffer is configured to follow OE pin output, so we
+         * need to set the output value to 0 to disable the clock outputs. If
+         * mode of operation is IO, then the IO value will determine the
+         * disable/enable of clock output */
+        if (modeOfOperation == "SMBus")
+        {
+            if (file < 0)
+            {
+                file = open(("/dev/i2c-" + std::to_string(bus)).c_str(),
+                            O_RDWR | O_CLOEXEC);
+                if (file < 0)
+                {
+                    std::cerr << "ClockBuffer : \"" << name
+                              << "\" - Unable to open bus : " << bus << "\n";
+                    return;
+                }
+            }
+
+            if (ioctl(file, I2C_SLAVE_FORCE, address) < 0)
+            {
+                std::cerr << "ClockBuffer : \"" << name
+                          << "\" - Unable to set address to " << address
+                          << "\n";
+                return;
+            }
+
+            for (uint8_t i = 0; i < outCtrlByteCount; i++)
+            {
+                std::string byteName = "Byte" + std::to_string(i);
+
+                auto byte = byteMap.find(byteName);
+                if (byte == byteMap.end())
+                {
+                    std::cerr << "ClockBuffer : \"" << name
+                              << "\" - Byte map error ! Unable to find "
+                              << byteName << "\n";
+                    return;
+                }
+
+                /* Get current value of output control register */
+                int read = i2c_smbus_read_byte_data(
+                    file, static_cast<uint8_t>(outCtrlBaseAddr + i));
+                if (read < 0)
+                {
+                    std::cerr << "ClockBuffer : \"" << name
+                              << "\" - Error: Unable to read data from clock "
+                                 "buffer register\n";
+                    return;
+                }
+
+                std::bitset<8> currByte(read);
+
+                /* Set zero only at bit position that we have a NVMe drive (i.e.
+                 * ignore where byteMap is "-"). We do not want to touch other
+                 * bits */
+                for (uint8_t bit = 0; bit < 8; bit++)
+                {
+                    if (byte->second.at(bit) != "-")
+                    {
+                        currByte.reset(bit);
+                    }
+                }
+
+                int ret = i2c_smbus_write_byte_data(
+                    file, static_cast<uint8_t>(outCtrlBaseAddr + i),
+                    static_cast<uint8_t>(currByte.to_ulong()));
+
+                if (ret < 0)
+                {
+                    std::cerr << "ClockBuffer : \"" << name
+                              << "\" - Error: Unable to write data to clock "
+                                 "buffer register\n";
+                    return;
+                }
+            }
+        }
+        initialized = true;
+        std::cerr << "ClockBuffer : \"" << name << "\" initialized\n";
+    }
+
+  public:
+    ClockBuffer(
+        size_t busIn, size_t addressIn, std::string& modeOfOperationIn,
+        size_t outCtrlBaseAddrIn, size_t outCtrlByteCountIn,
+        std::unordered_map<std::string, std::vector<std::string>>& byteMapIn,
+        std::string& nameIn, std::string& typeIn) :
+        bus(busIn),
+        address(addressIn), modeOfOperation(std::move(modeOfOperationIn)),
+        outCtrlBaseAddr(outCtrlBaseAddrIn),
+        outCtrlByteCount(outCtrlByteCountIn), byteMap(std::move(byteMapIn)),
+        name(std::move(nameIn)), type(std::move(typeIn))
+    {
+        initialize();
+    }
+
+    bool isInitialized()
+    {
+        if (!initialized)
+        {
+            /* There was an issue with the initialization of this component. Try
+             * to invoke initialization again */
+            initialize();
+        }
+        return initialized;
+    }
+
+    std::string getName()
+    {
+        return name;
+    }
+
+    bool enableDisableClock(std::forward_list<std::string>& nvmeDrivesInserted,
+                            std::forward_list<std::string>& nvmeDrivesRemoved)
+    {
+        if (modeOfOperation != "SMBus")
+        {
+            /* The clock is enabled using IO expander. No action needed from
+             * here */
+            return true;
+        }
+
+        if (nvmeDrivesInserted.empty() && nvmeDrivesRemoved.empty())
+        {
+            /* There are no drives to update */
+            return true;
+        }
+
+        for (uint8_t i = 0; i < outCtrlByteCount; i++)
+        {
+            std::string byteName = "Byte" + std::to_string(i);
+
+            auto byte = byteMap.find(byteName);
+            if (byte == byteMap.end())
+            {
+                std::cerr << "ClockBuffer : \"" << name
+                          << "\" - Byte map error ! Unable to find " << byteName
+                          << "\n";
+                return false;
+            }
+
+            /* Get current value of output control register */
+            int read = i2c_smbus_read_byte_data(
+                file, static_cast<uint8_t>(outCtrlBaseAddr + i));
+            if (read < 0)
+            {
+                std::cerr << "ClockBuffer : \"" << name
+                          << "\" - Error: Unable to read data from clock "
+                             "buffer register\n";
+                return false;
+            }
+
+            std::bitset<8> currByte(read);
+            bool writeRequired = false;
+
+            /* Set the bit if the NVMe drive is found in nvmeDrivesInserted, and
+             * reset the bit if found in nvmeDrivesRemoved */
+            for (uint8_t bit = 0; bit < 8; bit++)
+            {
+                /* The remove function returns number of elements removed from
+                 * list indicating the presence of the drive and also removing
+                 * it form the list */
+                if (nvmeDrivesInserted.remove(byte->second.at(bit)))
+                {
+                    writeRequired = true;
+                    currByte.set(bit);
+                    continue;
+                }
+
+                if (nvmeDrivesRemoved.remove(byte->second.at(bit)))
+                {
+                    writeRequired = true;
+                    currByte.reset(bit);
+                }
+            }
+
+            if (!writeRequired)
+            {
+                /* No Write is required as there are no changes */
+                continue;
+            }
+
+            int ret = i2c_smbus_write_byte_data(
+                file, static_cast<uint8_t>(outCtrlBaseAddr + i),
+                static_cast<uint8_t>(currByte.to_ulong()));
+            if (ret < 0)
+            {
+                std::cerr << "ClockBuffer : \"" << name
+                          << "\" - Error: Unable to write data to clock "
+                             "buffer register\n";
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    ~ClockBuffer()
+    {
+        if (file >= 0)
+        {
+            close(file);
+        }
+    }
+};
+
+class IoExpander
+{
+    size_t bus;
+    size_t address;
+    size_t confIORegAddr;
+    size_t outCtrlBaseAddr;
+    size_t outCtrlByteCount;
+    std::unordered_map<std::string, std::vector<std::string>> ioMap;
+    std::string name;
+    std::string type;
+
+    int file = -1;
+    bool initialized = false;
+
+    void initialize()
+    {
+        /* Initialize the IO expander Control register to configure the IO ports
+         * as outputs and set the output to low by default */
+        if (file < 0)
+        {
+            file = open(("/dev/i2c-" + std::to_string(bus)).c_str(),
+                        O_RDWR | O_CLOEXEC);
+            if (file < 0)
+            {
+                std::cerr << "IoExpander : " << name
+                          << " - Unable to open bus : " << bus << "\n";
+                return;
+            }
+        }
+
+        if (ioctl(file, I2C_SLAVE_FORCE, address) < 0)
+        {
+            std::cerr << "IoExpander : \"" << name
+                      << "\" - Unable to set address to " << address << "\n";
+            return;
+        }
+
+        for (uint8_t i = 0; i < outCtrlByteCount; i++)
+        {
+            std::string ioName = "IO" + std::to_string(i);
+
+            auto io = ioMap.find(ioName);
+            if (io == ioMap.end())
+            {
+                std::cerr << "IoExpander : \"" << name
+                          << "\" - IO map error ! Unable to find " << ioName
+                          << "\n";
+                return;
+            }
+
+            /* Get current value of IO configuration register */
+            int read1 = i2c_smbus_read_byte_data(
+                file, static_cast<uint8_t>(confIORegAddr + i));
+            if (read1 < 0)
+            {
+                std::cerr << "IoExpander : \"" << name
+                          << "\" - Error: Unable to read data from io expander "
+                             "IO control register\n";
+                return;
+            }
+
+            /* Get current value of IO Ouput register */
+            int read2 = i2c_smbus_read_byte_data(
+                file, static_cast<uint8_t>(confIORegAddr + i));
+            if (read2 < 0)
+            {
+                std::cerr << "IoExpander : \"" << name
+                          << "\" - Error: Unable to read data from io expander "
+                             "IO output register\n";
+                return;
+            }
+
+            std::bitset<8> currCtrlVal(read1);
+            std::bitset<8> currOutVal(read2);
+
+            /* Set zero only at bit position that we have a NVMe drive (i.e.
+             * ignore where ioMap is "-"). We do not want to touch other
+             * bits */
+            for (uint8_t bit = 0; bit < 8; bit++)
+            {
+                if (io->second.at(bit) != "-")
+                {
+                    currCtrlVal.reset(bit);
+                    currOutVal.reset(bit);
+                }
+            }
+
+            int ret1 = i2c_smbus_write_byte_data(
+                file, static_cast<uint8_t>(confIORegAddr + i),
+                static_cast<uint8_t>(currCtrlVal.to_ulong()));
+            if (ret1 < 0)
+            {
+                std::cerr << "IoExpander : \"" << name
+                          << "\" - Error: Unable to write data to IO expander "
+                             "IO control register\n";
+                return;
+            }
+
+            int ret2 = i2c_smbus_write_byte_data(
+                file, static_cast<uint8_t>(outCtrlBaseAddr + i),
+                static_cast<uint8_t>(currOutVal.to_ulong()));
+            if (ret2 < 0)
+            {
+                std::cerr << "IoExpander : \"" << name
+                          << "\" - Error: Unable to write data to IO expander "
+                             "IO output register\n";
+                return;
+            }
+        }
+        initialized = true;
+        std::cerr << "IoExpander : \"" << name << "\" initialized\n";
+    }
+
+  public:
+    IoExpander(
+        size_t busIn, size_t addressIn, size_t confIORegAddrIn,
+        size_t outCtrlBaseAddrIn, size_t outCtrlByteCountIn,
+        std::unordered_map<std::string, std::vector<std::string>>& ioMapIn,
+        std::string& nameIn, std::string& typeIn) :
+        bus(busIn),
+        address(addressIn), confIORegAddr(confIORegAddrIn),
+        outCtrlBaseAddr(outCtrlBaseAddrIn),
+        outCtrlByteCount(outCtrlByteCountIn), ioMap(std::move(ioMapIn)),
+        name(std::move(nameIn)), type(std::move(typeIn))
+    {
+        initialize();
+    }
+
+    bool isInitialized()
+    {
+        if (!initialized)
+        {
+            /* There was an issue with the initialization of this component. Try
+             * to invoke initialization again */
+            initialize();
+        }
+        return initialized;
+    }
+
+    std::string getName()
+    {
+        return name;
+    }
+
+    bool enableDisableOuput(std::forward_list<std::string>& nvmeDrivesInserted,
+                            std::forward_list<std::string>& nvmeDrivesRemoved)
+    {
+        if (nvmeDrivesInserted.empty() && nvmeDrivesRemoved.empty())
+        {
+            /* There are no drives to update */
+            return true;
+        }
+
+        for (uint8_t i = 0; i < outCtrlByteCount; i++)
+        {
+            std::string ioName = "IO" + std::to_string(i);
+
+            auto io = ioMap.find(ioName);
+            if (io == ioMap.end())
+            {
+                std::cerr << "IoExpander : \"" << name
+                          << "\" - IO map error ! Unable to find " << ioName
+                          << "\n";
+                return false;
+            }
+
+            /* Get current value of IO output register */
+            int read = i2c_smbus_read_byte_data(
+                file, static_cast<uint8_t>(outCtrlBaseAddr + i));
+            if (read < 0)
+            {
+                std::cerr << "IoExpander : \"" << name
+                          << "\" - Error: Unable to read data from io expander "
+                             "register\n";
+                return false;
+            }
+
+            std::bitset<8> currVal(read);
+            bool writeRequired = false;
+
+            /* Set the bit if the NVMe drive is found in nvmeDrivesInserted, and
+             * reset the bit if found in nvmeDrivesRemoved */
+            for (uint8_t bit = 0; bit < 8; bit++)
+            {
+                /* The remove function returns number of elements removed from
+                 * list indicating the presence of the drive and also removing
+                 * it form the list */
+                if (nvmeDrivesInserted.remove(io->second.at(bit)))
+                {
+                    writeRequired = true;
+                    currVal.set(bit);
+                    continue;
+                }
+
+                if (nvmeDrivesRemoved.remove(io->second.at(bit)))
+                {
+                    writeRequired = true;
+                    currVal.reset(bit);
+                }
+            }
+
+            if (!writeRequired)
+            {
+                /* No Write is required as there are no changes */
+                continue;
+            }
+
+            int ret = i2c_smbus_write_byte_data(
+                file, static_cast<uint8_t>(outCtrlBaseAddr + i),
+                static_cast<uint8_t>(currVal.to_ulong()));
+            if (ret < 0)
+            {
+                std::cerr << "IoExpander : \"" << name
+                          << "\" - Error: Unable to write data to IO expander "
+                             "register\n";
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    ~IoExpander()
+    {
+        if (file >= 0)
+        {
+            close(file);
+        }
+    }
+};
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/*********************** Global Variables Declarations **********************/
+/****************************************************************************/
+/* State os Application */
+static AppState appState = AppState::idle;
+
+/* Configuration and Components */
+static HsbpConfig hsbpConfig;
+std::forward_list<ClockBuffer> clockBuffers;
+std::forward_list<IoExpander> ioExpanders;
+
+/* Boost IO context and Dbus variables */
 boost::asio::io_context io;
 auto conn = std::make_shared<sdbusplus::asio::connection>(io);
 sdbusplus::asio::object_server objServer(conn);
 
-// GPIO Lines and Event Descriptors
+/* GPIO Lines and GPIO Event Descriptors */
 static gpiod::line nvmeLvc3AlertLine;
 static boost::asio::posix::stream_descriptor nvmeLvc3AlertEvent(io);
+/***************************** End of Section *******************************/
 
-static std::string zeroPad(const uint8_t val)
-{
-    std::ostringstream version;
-    version << std::setw(2) << std::setfill('0') << static_cast<size_t>(val);
-    return version.str();
-}
-
+/****************************************************************************/
+/********** HSBP Backplane related struct and Global definitions ************/
+/****************************************************************************/
 struct Mux
 {
     Mux(size_t busIn, size_t addressIn, size_t channelsIn, size_t indexIn) :
@@ -76,13 +595,6 @@
     }
 };
 
-enum class BlinkPattern : uint8_t
-{
-    off = 0x0,
-    error = 0x2,
-    terminate = 0x3
-};
-
 struct Led : std::enable_shared_from_this<Led>
 {
     // led pattern addresses start at 0x10
@@ -152,18 +664,17 @@
 
 struct Drive
 {
-    Drive(size_t driveIndex, bool present, bool isOperational, bool nvme,
+    Drive(std::string driveName, bool present, bool isOperational, bool nvme,
           bool rebuilding) :
         isNvme(nvme),
-        isPresent(present), index(driveIndex)
+        isPresent(present), name(driveName)
     {
         constexpr const char* basePath =
-            "/xyz/openbmc_project/inventory/item/drive/Drive_";
-        itemIface = objServer.add_interface(
-            basePath + std::to_string(driveIndex), inventory::interface);
+            "/xyz/openbmc_project/inventory/item/drive/";
+        itemIface =
+            objServer.add_interface(basePath + driveName, inventory::interface);
         itemIface->register_property("Present", isPresent);
-        itemIface->register_property("PrettyName",
-                                     "Drive " + std::to_string(driveIndex));
+        itemIface->register_property("PrettyName", driveName);
         itemIface->initialize();
         operationalIface = objServer.add_interface(
             itemIface->get_object_path(),
@@ -263,7 +774,7 @@
         std::vector<Association> warning = {
             {"", "warning", globalInventoryPath}};
         associations->set_property("Associations", warning);
-        logDriveError("Drive " + std::to_string(index));
+        logDriveError("Drive " + name);
     }
 
     void clearFailed(void)
@@ -295,7 +806,7 @@
         if (!isPresent && loggedPresent)
         {
             loggedPresent = false;
-            logDeviceRemoved("Drive", std::to_string(index), serialNumber);
+            logDeviceRemoved("Drive", name, serialNumber);
             serialNumber = "N/A";
             serialNumberInitialized = false;
             removeAsset();
@@ -303,7 +814,7 @@
         else if (isPresent && !loggedPresent)
         {
             loggedPresent = true;
-            logDeviceAdded("Drive", std::to_string(index), serialNumber);
+            logDeviceAdded("Drive", name, serialNumber);
         }
     }
 
@@ -316,7 +827,7 @@
 
     bool isNvme;
     bool isPresent;
-    size_t index;
+    std::string name;
     std::string serialNumber = "N/A";
     bool serialNumberInitialized = false;
     bool loggedPresent = false;
@@ -365,6 +876,14 @@
             assetTag);
     }
 
+    static std::string zeroPad(const uint8_t val)
+    {
+        std::ostringstream version;
+        version << std::setw(2) << std::setfill('0')
+                << static_cast<size_t>(val);
+        return version.str();
+    }
+
     void run(const std::string& rootPath, const std::string& busname)
     {
         file = open(("/dev/i2c-" + std::to_string(bus)).c_str(),
@@ -489,8 +1008,9 @@
             bool isRebuilding = !isPresent && (rebuilding & driveSlot);
 
             // +1 to convert from 0 based to 1 based
-            size_t driveIndex = (backplaneIndex * maxDrives) + ii + 1;
-            Drive& drive = drives.emplace_back(driveIndex, isPresent, !isFailed,
+            std::string driveName = boost::replace_all_copy(name, " ", "_") +
+                                    "_Drive_" + std::to_string(ii + 1);
+            Drive& drive = drives.emplace_back(driveName, isPresent, !isFailed,
                                                isNvme, isRebuilding);
             std::shared_ptr<Led> led = leds.emplace_back(std::make_shared<Led>(
                 drive.itemIface->get_object_path(), ii, file));
@@ -650,11 +1170,86 @@
         return true;
     }
 
+    bool getInsertedAndRemovedNvmeDrives(
+        std::forward_list<std::string>& nvmeDrivesInserted,
+        std::forward_list<std::string>& nvmeDrivesRemoved)
+    {
+        /* Get the current drives status */
+        std::bitset<8> currDriveStatus;
+        uint8_t nPresence;
+        uint8_t nIfdet;
+
+        if (!getPresence(nPresence) || !getIFDET(nIfdet))
+        {
+            /* Error getting value. Return */
+            std::cerr << "Backplane " << name
+                      << " failed to get drive status\n";
+            return false;
+        }
+
+        std::string dbusHsbpName = boost::replace_all_copy(name, " ", "_");
+        auto nvmeMap = hsbpConfig.hsbpNvmeMap.find(dbusHsbpName);
+        if (nvmeMap == hsbpConfig.hsbpNvmeMap.end())
+        {
+            std::cerr << "Couldn't get the NVMe Map for the backplane : "
+                      << name << "\n";
+            return false;
+        }
+
+        /* NVMe drives do not assert PRSNTn, and as such do not get reported in
+         * "presence" register, but assert ifdet low. This implies for a NVMe
+         * drive to be present, corresponding precense bit has to be 0 and idfet
+         * has to be 1 (as the values of these regosters are negated: check
+         * getPresence() and getIfdet() functions) */
+        for (uint8_t bit = 0; bit < 8; bit++)
+        {
+            if ((nPresence & (1U << bit)) == 0)
+            {
+                if (nIfdet & (1U << bit))
+                {
+                    currDriveStatus.set(bit);
+                }
+            }
+        }
+
+        /* Determine Inserted and Removed Drives
+         * Prev Bit | Curr Bit | Status
+         *    0     |    0     | No Change
+         *    0     |    1     | Inserted
+         *    1     |    0     | Removed
+         *    1     |    1     | No Change
+         */
+        for (uint8_t index = 0; index < 8; index++)
+        {
+            /* Inserted */
+            if (!prevDriveStatus.test(index) && currDriveStatus.test(index))
+            {
+                nvmeDrivesInserted.emplace_front(nvmeMap->second.at(index));
+                std::cerr << name << " : " << nvmeDrivesInserted.front()
+                          << " Inserted !\n";
+            }
+
+            /* Removed */
+            else if (prevDriveStatus.test(index) &&
+                     !currDriveStatus.test(index))
+            {
+                nvmeDrivesRemoved.emplace_front(nvmeMap->second.at(index));
+                std::cerr << name << " : " << nvmeDrivesRemoved.front()
+                          << " Removed !\n";
+            }
+        }
+
+        prevDriveStatus = currDriveStatus;
+        return true;
+    }
+
     virtual ~Backplane()
     {
+        timer.cancel();
         objServer.remove_interface(hsbpItemIface);
         objServer.remove_interface(versionIface);
-        timer.cancel();
+        objServer.remove_interface(storageInterface);
+        objServer.remove_interface(assetInterface);
         if (file >= 0)
         {
             close(file);
@@ -676,6 +1271,7 @@
     uint8_t ifdet = 0;
     uint8_t failed = 0;
     uint8_t rebuilding = 0;
+    std::bitset<8> prevDriveStatus;
 
     int file = -1;
 
@@ -691,9 +1287,232 @@
     std::shared_ptr<boost::container::flat_set<Mux>> muxes;
 };
 
+/* Global HSBP backplanes and NVMe drives collection */
 std::unordered_map<std::string, std::shared_ptr<Backplane>> backplanes;
 std::list<Drive> ownerlessDrives; // drives without a backplane
+/***************************** End of Section *******************************/
 
+/****************************************************************************/
+/***************** Miscellaneous Class/Function Definitions *****************/
+/****************************************************************************/
+/* The purpose of this class is to sync the code flow. Often times there could
+ * be multiple dbus calls which are async, and upon completely finishing all
+ * Dbus calls, we need to call next function, or handle the error.
+ * When an object of this class goes out of scope, the respective handlers
+ * will be called */
+class AsyncCallbackHandler
+{
+    bool errorOccurred = false;
+    std::function<void()> onSuccess = nullptr;
+    std::function<void()> onError = nullptr;
+
+  public:
+    explicit AsyncCallbackHandler(std::function<void()> onSuccessIn,
+                                  std::function<void()> onErrorIn) :
+        onSuccess(std::move(onSuccessIn)),
+        onError(std::move(onErrorIn))
+    {
+    }
+
+    void setError()
+    {
+        errorOccurred = true;
+    }
+
+    ~AsyncCallbackHandler()
+    {
+        /* If error occurred flag was set, execute the error handler */
+        if (errorOccurred)
+        {
+            /* Check if Error Handler is defined */
+            if (onError)
+            {
+                onError();
+            }
+
+            return;
+        }
+
+        /* If Success Handler is present, execute Success Handler */
+        if (onSuccess)
+        {
+            onSuccess();
+        }
+    }
+};
+
+void stopHsbpManager()
+{
+    std::cerr << __FUNCTION__ << ": Stopping hsbp-manager\n";
+    appState = AppState::idle;
+    hsbpConfig.clearConfig();
+    clockBuffers.clear();
+    ioExpanders.clear();
+    backplanes.clear();
+
+    io.stop();
+}
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/********* HSBP clock enable/disable related Function Definitions ***********/
+/****************************************************************************/
+void updateHsbpClocks(std::forward_list<std::string>& nvmeDrivesInserted,
+                      std::forward_list<std::string>& nvmeDrivesRemoved)
+{
+    if (appState < AppState::backplanesLoaded)
+    {
+        std::cerr << "HSBP not initialized ! Cancelling Clock Update ! \n";
+        return;
+    }
+
+    std::cerr << "Updating HSBP drive clocks ...\n";
+
+    /* Loop through all clock buffers and try to update the clocks (this will be
+     * done if the mode of operation of the clock buffer is SMBus) */
+    for (auto& clockBuffer : clockBuffers)
+    {
+        if (!clockBuffer.enableDisableClock(nvmeDrivesInserted,
+                                            nvmeDrivesRemoved))
+        {
+            std::cerr << "Error Occurred while setting the clock in \""
+                      << clockBuffer.getName() << "\"\n";
+        }
+    }
+
+    /* If there are drives yet to be updated, check all the IO Expanders in case
+     * they are mapped to the drives and enable the respective IO */
+    if (!nvmeDrivesInserted.empty() || !nvmeDrivesRemoved.empty())
+    {
+        for (auto& ioExpander : ioExpanders)
+        {
+            if (!ioExpander.enableDisableOuput(nvmeDrivesInserted,
+                                               nvmeDrivesRemoved))
+            {
+                std::cerr << "Error Occurred while setting the IO in \""
+                          << ioExpander.getName() << "\"\n";
+            }
+        }
+    }
+
+    /* If there are drives still left, then one or more drives clock
+     * enable/diable failed. There is a possibility of improper mapping or
+     * current communication with the device failed */
+    if (!nvmeDrivesInserted.empty() || !nvmeDrivesRemoved.empty())
+    {
+        std::cerr << "Critical Error !!!\nMapping issue detected !\n";
+
+        if (!nvmeDrivesInserted.empty())
+        {
+            std::cerr << "The clock enable failed for : ";
+            for (auto& nvme1 : nvmeDrivesInserted)
+            {
+                std::cerr << nvme1 << ", ";
+            }
+            std::cerr << "\n";
+        }
+
+        if (!nvmeDrivesRemoved.empty())
+        {
+            std::cerr << "The clock disable failed for : ";
+            for (auto& nvme1 : nvmeDrivesRemoved)
+            {
+                std::cerr << nvme1 << ", ";
+            }
+            std::cerr << "\n";
+        }
+    }
+}
+
+void scanHsbpDrives(bool& hsbpDriveScanInProgress)
+{
+    std::cerr << __FUNCTION__ << ": Scanning HSBP drives status ...\n";
+
+    /* List variables to store the drives Inserted/Removed */
+    std::forward_list<std::string> nvmeDrivesInserted;
+    std::forward_list<std::string> nvmeDrivesRemoved;
+
+    /* Loop through each backplane present and get the list of inserted/removed
+     * drives */
+    for (auto& [name, backplane] : backplanes)
+    {
+        backplane->getInsertedAndRemovedNvmeDrives(nvmeDrivesInserted,
+                                                   nvmeDrivesRemoved);
+    }
+
+    if (!nvmeDrivesInserted.empty() || !nvmeDrivesRemoved.empty())
+    {
+        updateHsbpClocks(nvmeDrivesInserted, nvmeDrivesRemoved);
+    }
+
+    std::cerr << __FUNCTION__ << ": Scanning HSBP drives Completed\n";
+
+    hsbpDriveScanInProgress = false;
+}
+
+void checkHsbpDrivesStatus()
+{
+    static bool hsbpDriveScanInProgress = false;
+    static bool hsbpDriveRescanInQueue = false;
+
+    if (appState < AppState::backplanesLoaded)
+    {
+        std::cerr << __FUNCTION__
+                  << ": HSBP not initialized ! Cancelling scan of HSBP drives "
+                     "status ! \n";
+        return;
+    }
+
+    if (hsbpDriveScanInProgress)
+    {
+        /* Scan and Clock Update already in progress. Try again after sometime.
+         * This event can occur due to the GPIO interrupt */
+        std::cerr << __FUNCTION__
+                  << ": HSBP Drives Scan is already in progress\n";
+        if (hsbpDriveRescanInQueue)
+        {
+            /* There is already a Re-Scan in queue. No need to create multiple
+             * rescans */
+            return;
+        }
+
+        hsbpDriveRescanInQueue = true;
+
+        std::cerr << __FUNCTION__ << ": Queuing the Scan \n";
+
+        auto driveScanTimer = std::make_shared<boost::asio::steady_timer>(io);
+        driveScanTimer->expires_after(std::chrono::seconds(1));
+        driveScanTimer->async_wait(
+            [driveScanTimer](const boost::system::error_code ec) {
+                if (ec == boost::asio::error::operation_aborted)
+                {
+                    // Timer was Aborted
+                    return;
+                }
+                else if (ec)
+                {
+                    std::cerr << "driveScanTimer: Timer error" << ec.message()
+                              << "\n";
+                    return;
+                }
+                hsbpDriveRescanInQueue = false;
+                checkHsbpDrivesStatus();
+            });
+
+        return;
+    }
+
+    hsbpDriveScanInProgress = true;
+
+    /* Post the scan to IO queue and return from here. This enables capturing
+     * next GPIO event if any */
+    boost::asio::post(io, []() { scanHsbpDrives(hsbpDriveScanInProgress); });
+}
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/********** Backplanes and NVMe drives related Function Definitions *********/
+/****************************************************************************/
 static size_t getDriveCount()
 {
     size_t count = 0;
@@ -706,14 +1525,29 @@
 
 void updateAssets()
 {
-    static constexpr const char* nvmeType =
-        "xyz.openbmc_project.Inventory.Item.NVMe";
+    appState = AppState::loadingDrives;
+
+    /* Setup a callback to be called once the assets are populated completely or
+     * fallback to error handler */
+    auto drivesLoadedCallback = std::make_shared<AsyncCallbackHandler>(
+        []() {
+            appState = AppState::drivesLoaded;
+            std::cerr << "Drives Updated !\n";
+        },
+        []() {
+            // TODO: Handle this error if needed
+            appState = AppState::backplanesLoaded;
+            std::cerr << "An error occured ! Drives load failed \n";
+        });
 
     conn->async_method_call(
-        [](const boost::system::error_code ec, const GetSubTreeType& subtree) {
+        [drivesLoadedCallback](const boost::system::error_code ec,
+                               const GetSubTreeType& subtree) {
             if (ec)
             {
-                std::cerr << "Error contacting mapper " << ec.message() << "\n";
+                std::cerr << __FUNCTION__ << ": Error contacting mapper "
+                          << ec.message() << "\n";
+                drivesLoadedCallback->setError();
                 return;
             }
 
@@ -742,23 +1576,28 @@
                 }
 
                 conn->async_method_call(
-                    [path](const boost::system::error_code ec2,
-                           const boost::container::flat_map<
-                               std::string,
-                               std::variant<uint64_t, std::string>>& values) {
+                    [path, drivesLoadedCallback](
+                        const boost::system::error_code ec2,
+                        const boost::container::flat_map<
+                            std::string, std::variant<uint64_t, std::string>>&
+                            values) {
                         if (ec2)
                         {
-                            std::cerr << "Error Getting Config "
-                                      << ec2.message() << " " << __FUNCTION__
+                            std::cerr << __FUNCTION__
+                                      << ": Error Getting Config "
+                                      << ec2.message() << " "
                                       << "\n";
+                            drivesLoadedCallback->setError();
                             return;
                         }
                         auto findBus = values.find("Bus");
 
                         if (findBus == values.end())
                         {
-                            std::cerr << "Illegal interface at " << path
+                            std::cerr << __FUNCTION__
+                                      << ": Illegal interface at " << path
                                       << "\n";
+                            drivesLoadedCallback->setError();
                             return;
                         }
 
@@ -771,6 +1610,7 @@
                         if (!std::filesystem::is_symlink(muxPath))
                         {
                             std::cerr << path << " mux does not exist\n";
+                            drivesLoadedCallback->setError();
                             return;
                         }
 
@@ -784,6 +1624,7 @@
                             findDash + 1 >= fname.size())
                         {
                             std::cerr << path << " mux path invalid\n";
+                            drivesLoadedCallback->setError();
                             return;
                         }
 
@@ -801,8 +1642,10 @@
                                                "/name");
                         if (!nameFile)
                         {
-                            std::cerr << "Unable to open name file of bus "
+                            std::cerr << __FUNCTION__
+                                      << ": Unable to open name file of bus "
                                       << muxBus << "\n";
+                            drivesLoadedCallback->setError();
                             return;
                         }
 
@@ -816,7 +1659,8 @@
                         if (findId == std::string::npos ||
                             findId + 1 >= nameStr.size())
                         {
-                            std::cerr << "Illegal name file on bus " << muxBus
+                            std::cerr << __FUNCTION__
+                                      << ": Illegal name file on bus " << muxBus
                                       << "\n";
                         }
 
@@ -825,20 +1669,6 @@
 
                         size_t driveIndex = std::stoi(indexStr);
 
-                        Backplane* parent = nullptr;
-                        for (auto& [name, backplane] : backplanes)
-                        {
-                            muxIndex = 0;
-                            for (const Mux& mux : *(backplane->muxes))
-                            {
-                                if (bus == mux.bus && addr == mux.address)
-                                {
-                                    parent = backplane.get();
-                                    break;
-                                }
-                                muxIndex += mux.channels;
-                            }
-                        }
                         boost::container::flat_map<std::string, std::string>
                             assetInventory;
                         const std::array<const char*, 4> assetKeys = {
@@ -854,11 +1684,34 @@
                             assetInventory[key] = std::get<std::string>(value);
                         }
 
+                        Backplane* parent = nullptr;
+                        for (auto& [name, backplane] : backplanes)
+                        {
+                            muxIndex = 0;
+                            for (const Mux& mux : *(backplane->muxes))
+                            {
+                                if (bus == mux.bus && addr == mux.address)
+                                {
+                                    parent = backplane.get();
+                                    break;
+                                }
+                                muxIndex += mux.channels;
+                            }
+                            if (parent)
+                            {
+                                /* Found the backplane. No need to proceed
+                                 * further */
+                                break;
+                            }
+                        }
+
                         // assume its a M.2 or something without a hsbp
                         if (parent == nullptr)
                         {
+                            std::string driveName =
+                                "Drive_" + std::to_string(getDriveCount() + 1);
                             auto& drive = ownerlessDrives.emplace_back(
-                                getDriveCount() + 1, true, true, true, false);
+                                driveName, true, true, true, false);
                             drive.createAsset(assetInventory);
                             return;
                         }
@@ -867,8 +1720,10 @@
 
                         if (parent->drives.size() <= driveIndex)
                         {
-                            std::cerr << "Illegal drive index at " << path
+                            std::cerr << __FUNCTION__
+                                      << ": Illegal drive index at " << path
                                       << " " << driveIndex << "\n";
+                            drivesLoadedCallback->setError();
                             return;
                         }
                         auto it = parent->drives.begin();
@@ -881,7 +1736,7 @@
             }
         },
         mapper::busName, mapper::path, mapper::interface, mapper::subtree, "/",
-        0, std::array<const char*, 1>{nvmeType});
+        0, std::array<const char*, 1>{nvmeIntf});
 }
 
 void populateMuxes(std::shared_ptr<boost::container::flat_set<Mux>> muxes,
@@ -892,17 +1747,16 @@
         "xyz.openbmc_project.Configuration.PCA9544Mux",
         "xyz.openbmc_project.Configuration.PCA9545Mux",
         "xyz.openbmc_project.Configuration.PCA9546Mux"};
+
     conn->async_method_call(
         [muxes](const boost::system::error_code ec,
                 const GetSubTreeType& subtree) {
             if (ec)
             {
-                std::cerr << "Error contacting mapper " << ec.message() << "\n";
+                std::cerr << __FUNCTION__ << ": Error contacting mapper "
+                          << ec.message() << "\n";
                 return;
             }
-            std::shared_ptr<std::function<void()>> callback =
-                std::make_shared<std::function<void()>>(
-                    []() { updateAssets(); });
             size_t index = 0; // as we use a flat map, these are sorted
             for (const auto& [path, objDict] : subtree)
             {
@@ -925,14 +1779,15 @@
                         break;
                     }
                 }
+
                 if (interface == nullptr)
                 {
-                    std::cerr << "Cannot get mux type\n";
+                    std::cerr << __FUNCTION__ << ": Cannot get mux type\n";
                     continue;
                 }
 
                 conn->async_method_call(
-                    [path, muxes, callback, index](
+                    [path, muxes, index](
                         const boost::system::error_code ec2,
                         const boost::container::flat_map<
                             std::string,
@@ -940,9 +1795,9 @@
                             values) {
                         if (ec2)
                         {
-                            std::cerr << "Error Getting Config "
-                                      << ec2.message() << " " << __FUNCTION__
-                                      << "\n";
+                            std::cerr << __FUNCTION__
+                                      << ": Error Getting Config "
+                                      << ec2.message() << "\n";
                             return;
                         }
                         auto findBus = values.find("Bus");
@@ -951,7 +1806,8 @@
                         if (findBus == values.end() ||
                             findAddress == values.end())
                         {
-                            std::cerr << "Illegal configuration at " << path
+                            std::cerr << __FUNCTION__
+                                      << ": Illegal configuration at " << path
                                       << "\n";
                             return;
                         }
@@ -963,10 +1819,6 @@
                             std::get<std::vector<std::string>>(
                                 findChannelNames->second);
                         muxes->emplace(bus, address, channels.size(), index);
-                        if (callback.use_count() == 1)
-                        {
-                            (*callback)();
-                        }
                     },
                     owner, path, "org.freedesktop.DBus.Properties", "GetAll",
                     *interface);
@@ -977,32 +1829,57 @@
         rootPath, 1, muxTypes);
 }
 
-void populate()
+void populateHsbpBackplanes(
+    const std::shared_ptr<AsyncCallbackHandler>& backplanesLoadedCallback)
 {
+    std::cerr << __FUNCTION__ << ": Scanning Backplanes ...\n";
+    appState = AppState::loadingBackplanes;
     backplanes.clear();
+
     conn->async_method_call(
-        [](const boost::system::error_code ec, const GetSubTreeType& subtree) {
+        [backplanesLoadedCallback](const boost::system::error_code ec,
+                                   const GetSubTreeType& subtree) {
             if (ec)
             {
-                std::cerr << "Error contacting mapper " << ec.message() << "\n";
+                std::cerr << __FUNCTION__ << ": Error contacting mapper "
+                          << ec.message() << "\n";
+                backplanesLoadedCallback->setError();
                 return;
             }
+
+            if (subtree.empty())
+            {
+                /* There wer no HSBP's detected. set teh state back to
+                 * componentsLoaded so that on backplane match event, the
+                 * process can start again */
+                appState = AppState::componentsLoaded;
+                std::cerr << __FUNCTION__ << ": No HSBPs Detected....\n";
+                return;
+            }
+
             for (const auto& [path, objDict] : subtree)
             {
                 if (objDict.empty())
                 {
-                    continue;
+                    std::cerr << __FUNCTION__
+                              << ": Subtree data "
+                                 "corrupted !\n";
+                    backplanesLoadedCallback->setError();
+                    return;
                 }
 
                 const std::string& owner = objDict.begin()->first;
                 conn->async_method_call(
-                    [path, owner](const boost::system::error_code ec2,
-                                  const boost::container::flat_map<
-                                      std::string, BasicVariantType>& resp) {
+                    [backplanesLoadedCallback, path,
+                     owner](const boost::system::error_code ec2,
+                            const boost::container::flat_map<
+                                std::string, BasicVariantType>& resp) {
                         if (ec2)
                         {
-                            std::cerr << "Error Getting Config "
+                            std::cerr << __FUNCTION__
+                                      << ": Error Getting Config "
                                       << ec2.message() << "\n";
+                            backplanesLoadedCallback->setError();
                             return;
                         }
                         std::optional<size_t> bus;
@@ -1030,8 +1907,10 @@
                         }
                         if (!bus || !address || !name || !backplaneIndex)
                         {
-                            std::cerr << "Illegal configuration at " << path
+                            std::cerr << __FUNCTION__
+                                      << ": Illegal configuration at " << path
                                       << "\n";
+                            backplanesLoadedCallback->setError();
                             return;
                         }
                         std::string parentPath =
@@ -1043,11 +1922,861 @@
                         populateMuxes(backplane->second->muxes, parentPath);
                     },
                     owner, path, "org.freedesktop.DBus.Properties", "GetAll",
-                    configType);
+                    hsbpCpldInft);
             }
         },
         mapper::busName, mapper::path, mapper::interface, mapper::subtree, "/",
-        0, std::array<const char*, 1>{configType});
+        0, std::array<const char*, 1>{hsbpCpldInft});
+}
+
+void setUpBackplanesAndDrives()
+{
+    static bool backplanesScanInProgress = false;
+    static bool backplanesRescanInQueue = false;
+
+    if (appState < AppState::componentsLoaded)
+    {
+        std::cerr << __FUNCTION__
+                  << ": Components are not initialized ! Cancelling scan of "
+                     "Backplanes ! \n";
+        return;
+    }
+
+    if (backplanesScanInProgress)
+    {
+        std::cerr << __FUNCTION__
+                  << ": Backplanes Scan is already in progress\n";
+        if (backplanesRescanInQueue)
+        {
+            /* There is already a Re-Scan in queue. No need to create multiple
+             * rescans */
+            return;
+        }
+
+        backplanesRescanInQueue = true;
+
+        std::cerr << __FUNCTION__ << ": Queuing the Backplane Scan \n";
+
+        auto backplaneScanTimer =
+            std::make_shared<boost::asio::steady_timer>(io);
+        backplaneScanTimer->expires_after(std::chrono::seconds(1));
+        backplaneScanTimer->async_wait(
+            [backplaneScanTimer](const boost::system::error_code ec) {
+                if (ec == boost::asio::error::operation_aborted)
+                {
+                    // Timer was Aborted
+                    return;
+                }
+                else if (ec)
+                {
+                    std::cerr << "backplaneScanTimer: Timer error"
+                              << ec.message() << "\n";
+                    return;
+                }
+                backplanesRescanInQueue = false;
+                setUpBackplanesAndDrives();
+            });
+
+        return;
+    }
+
+    backplanesScanInProgress = true;
+
+    /* Set Callback to be called once backplanes are populated to call
+     * updateAssets() and checkHsbpDrivesStatus() or handle error scnenario */
+    auto backplanesLoadedCallback = std::make_shared<AsyncCallbackHandler>(
+        []() {
+            /* If no HSBP's were detected, the state changes to
+             * componentsLoaded. Proceed further only if state was
+             * loadingBackplanes */
+            if (appState != AppState::loadingBackplanes)
+            {
+                backplanesScanInProgress = false;
+                return;
+            }
+
+            /* If there is a ReScan in the Queue, dont proceed further. Load the
+             * Backplanes again and then proceed further */
+            if (backplanesRescanInQueue)
+            {
+                backplanesScanInProgress = false;
+                return;
+            }
+
+            appState = AppState::backplanesLoaded;
+            std::cerr << __FUNCTION__ << ": Backplanes Loaded...\n";
+
+            checkHsbpDrivesStatus();
+            updateAssets();
+            backplanesScanInProgress = false;
+        },
+        []() {
+            /* Loading Backplanes is an important step. If the load failed due
+             * to an error, stop the app so that restart cant be triggerred */
+            std::cerr << "Backplanes couldn't be loaded due to an error !...\n";
+            appState = AppState::idle;
+            backplanesScanInProgress = false;
+            stopHsbpManager();
+        });
+
+    populateHsbpBackplanes(backplanesLoadedCallback);
+}
+
+void setupBackplanesAndDrivesMatch()
+{
+    static auto backplaneMatch = std::make_unique<sdbusplus::bus::match_t>(
+        *conn,
+        "sender='xyz.openbmc_project.EntityManager', type='signal', "
+        "member='PropertiesChanged', "
+        "interface='org.freedesktop.DBus.Properties', "
+        "path_namespace='/xyz/openbmc_project/inventory/system/board', arg0='" +
+            std::string(hsbpCpldInft) + "'",
+        [](sdbusplus::message_t& msg) {
+            std::string intfName;
+            boost::container::flat_map<std::string, BasicVariantType> values;
+            msg.read(intfName, values);
+
+            /* This match will be triggered for each of the property being set
+             * under the hsbpCpldInft interface. Call the loader only on one
+             * property say "name". This will avoid multiple calls to populate
+             * function
+             */
+            for (const auto& [key, value] : values)
+            {
+                if (key == "Name")
+                {
+                    /* This match will be triggered when ever there is a
+                     * addition/removal of HSBP backplane. At this stage, all
+                     * the HSBP's need to be populated again and also assets
+                     * have to be re-discovered. So, setting state to
+                     * componentsLoaded and calling setUpBackplanesAndDrives()
+                     * only if configuration and components loading was
+                     * completed */
+                    if (appState < AppState::componentsLoaded)
+                    {
+                        /* Configuration is not loaded yet. Backplanes will be
+                         * loaded
+                         * once configuration and components are loaded. */
+                        std::cerr << __FUNCTION__
+                                  << ": Discarding Backplane match\n";
+                        return;
+                    }
+
+                    appState = AppState::componentsLoaded;
+
+                    /* We will call the function after a small delay to let all
+                     * the properties to be intialized */
+                    auto backplaneTimer =
+                        std::make_shared<boost::asio::steady_timer>(io);
+                    backplaneTimer->expires_after(std::chrono::seconds(2));
+                    backplaneTimer->async_wait(
+                        [backplaneTimer](const boost::system::error_code ec) {
+                            if (ec == boost::asio::error::operation_aborted)
+                            {
+                                return;
+                            }
+                            else if (ec)
+                            {
+                                std::cerr << "backplaneTimer: Timer error"
+                                          << ec.message() << "\n";
+                                return;
+                            }
+                            setUpBackplanesAndDrives();
+                        });
+                }
+            }
+        });
+
+    static auto drivesMatch = std::make_unique<sdbusplus::bus::match_t>(
+        *conn,
+        "sender='xyz.openbmc_project.EntityManager', type='signal', "
+        "member='PropertiesChanged', "
+        "interface='org.freedesktop.DBus.Properties', arg0='" +
+            std::string(nvmeIntf) + "'",
+        [](sdbusplus::message_t& msg) {
+            std::string intfName;
+            boost::container::flat_map<std::string, BasicVariantType> values;
+            msg.read(intfName, values);
+
+            /* This match will be triggered for each of the property being set
+             * under the nvmeIntf interface. Call the loader only on one
+             * property say "name". This will avoid multiple calls to populate
+             * function
+             */
+            for (const auto& [key, value] : values)
+            {
+                if (key == "Name")
+                {
+                    /* This match will be triggered when ever there is a
+                     * addition/removal of drives. At this stage only assets
+                     * have to be re-discovered. So, setting state to
+                     * backplanesLoaded and calling updateAssets() only if all
+                     * previous states are completed */
+                    if (appState < AppState::backplanesLoaded)
+                    {
+                        /* Configuration is not loaded yet. Drives will be
+                         * loaded once
+                         * configuration, components and backplanes are loaded.
+                         */
+                        std::cerr << __FUNCTION__
+                                  << ": Discarding Drive match\n";
+                        return;
+                    }
+
+                    appState = AppState::backplanesLoaded;
+
+                    /* We will call the function after a small delay to let all
+                     * the properties to be intialized */
+                    auto driveTimer =
+                        std::make_shared<boost::asio::steady_timer>(io);
+                    driveTimer->expires_after(std::chrono::seconds(2));
+                    driveTimer->async_wait(
+                        [driveTimer](const boost::system::error_code ec) {
+                            if (ec == boost::asio::error::operation_aborted)
+                            {
+                                return;
+                            }
+                            else if (ec)
+                            {
+                                std::cerr << "driveTimer: Timer error"
+                                          << ec.message() << "\n";
+                                return;
+                            }
+                            updateAssets();
+                        });
+                }
+            }
+        });
+}
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/******************* Components related Function Definitions ****************/
+/****************************************************************************/
+bool verifyComponentsLoaded()
+{
+    std::cerr << __FUNCTION__ << ": Verifying all Components...\n";
+
+    /* Loop through all clock buffers */
+    for (auto& clockBuffer : clockBuffers)
+    {
+        if (!clockBuffer.isInitialized())
+        {
+            std::cerr << "Critical Error: Initializing \""
+                      << clockBuffer.getName() << "\" failed\n";
+            return false;
+        }
+    }
+
+    /* Loop through all IO Expanders */
+    for (auto& ioExpander : ioExpanders)
+    {
+        if (!ioExpander.isInitialized())
+        {
+            std::cerr << "Critical Error: Initializing \""
+                      << ioExpander.getName() << "\" failed\n";
+            return false;
+        }
+    }
+
+    std::cerr << __FUNCTION__ << ": Verifying Components Complete\n";
+
+    return true;
+}
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/****************** IO expander related Function Definitions ****************/
+/****************************************************************************/
+void loadIoExpanderInfo(
+    const std::shared_ptr<AsyncCallbackHandler>& componentsLoadedCallback)
+{
+    appState = AppState::loadingComponents;
+
+    /* Clear global ioExpanders to start off */
+    ioExpanders.clear();
+
+    conn->async_method_call(
+        [componentsLoadedCallback](const boost::system::error_code ec,
+                                   const GetSubTreeType& subtree) {
+            if (ec)
+            {
+                std::cerr << __FUNCTION__ << ": Error contacting mapper "
+                          << ec.message() << "\n";
+                componentsLoadedCallback->setError();
+                return;
+            }
+
+            for (auto& [path, objDict] : subtree)
+            {
+
+                if (objDict.empty())
+                {
+                    std::cerr << __FUNCTION__ << ": Subtree data corrupted !\n";
+                    componentsLoadedCallback->setError();
+                    return;
+                }
+
+                /* Ideally there would be only one element in objDict as only
+                 * one service exposes it and there would be only one interface
+                 * so it is safe to directly read them without loop */
+                const std::string& service = objDict.begin()->first;
+                const std::string& intf = objDict.begin()->second.front();
+
+                conn->async_method_call(
+                    [componentsLoadedCallback](
+                        const boost::system::error_code er,
+                        const boost::container::flat_map<
+                            std::string, BasicVariantType>& resp) {
+                        if (er)
+                        {
+                            std::cerr << __FUNCTION__
+                                      << ": Error Getting "
+                                         "Config "
+                                      << er.message() << "\n";
+                            componentsLoadedCallback->setError();
+                            return;
+                        }
+
+                        std::optional<uint64_t> bus;
+                        std::optional<uint64_t> address;
+                        std::optional<uint64_t> confIORegAddr;
+                        std::optional<uint64_t> outCtrlBaseAddr;
+                        std::optional<uint64_t> outCtrlByteCount;
+                        std::unordered_map<std::string,
+                                           std::vector<std::string>>
+                            ioMap;
+                        std::optional<std::string> name;
+                        std::optional<std::string> type;
+
+                        /* Loop through to get all IO Expander properties */
+                        for (const auto& [key, value] : resp)
+                        {
+                            if (key == "Bus")
+                            {
+                                bus = std::get<uint64_t>(value);
+                            }
+                            else if (key == "Address")
+                            {
+                                address = std::get<uint64_t>(value);
+                            }
+                            else if (key == "ConfIORegAddr")
+                            {
+                                confIORegAddr = std::get<uint64_t>(value);
+                            }
+                            else if (key == "OutCtrlBaseAddr")
+                            {
+                                outCtrlBaseAddr = std::get<uint64_t>(value);
+                            }
+                            else if (key == "OutCtrlByteCount")
+                            {
+                                outCtrlByteCount = std::get<uint64_t>(value);
+                            }
+                            else if (key == "Name")
+                            {
+                                name = std::get<std::string>(value);
+                            }
+                            else if (key == "Type")
+                            {
+                                type = std::get<std::string>(value);
+                            }
+                            else if (key.starts_with("IO"))
+                            {
+                                std::optional<std::vector<std::string>> outList;
+                                outList = std::get<NvmeMapping>(value);
+                                if (!outList)
+                                {
+                                    break;
+                                }
+                                ioMap.try_emplace(key, *outList);
+                            }
+                        }
+
+                        /* Verify if all properties were defined */
+                        if (!bus || !address || !confIORegAddr ||
+                            !outCtrlBaseAddr || !outCtrlByteCount || !name)
+                        {
+                            std::cerr << __FUNCTION__
+                                      << ": Incomplete "
+                                         "Clock Buffer definition !! \n";
+                            componentsLoadedCallback->setError();
+                            return;
+                        }
+
+                        /* Check if we were able to get byteMap correctly */
+                        if ((*outCtrlByteCount) != ioMap.size())
+                        {
+                            std::cerr << "loadIoExpanderInfo(): Incomplete "
+                                         "IO Map !! \n";
+                            componentsLoadedCallback->setError();
+                            return;
+                        }
+
+                        /* Create IO expander object and add it to global
+                         * ioExpanders vector */
+                        ioExpanders.emplace_front(
+                            *bus, *address, *confIORegAddr, *outCtrlBaseAddr,
+                            *outCtrlByteCount, ioMap, *name, *type);
+                    },
+                    service, path, "org.freedesktop.DBus.Properties", "GetAll",
+                    intf);
+            }
+        },
+        mapper::busName, mapper::path, mapper::interface, mapper::subtree, "/",
+        0, hsbpConfig.ioExpanderTypes);
+}
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/***************** Clock buffer related Function Definitions ****************/
+/****************************************************************************/
+void loadClockBufferInfo(
+    const std::shared_ptr<AsyncCallbackHandler>& componentsLoadedCallback)
+{
+    appState = AppState::loadingComponents;
+
+    /* Clear global clockBuffers to start off */
+    clockBuffers.clear();
+
+    conn->async_method_call(
+        [componentsLoadedCallback](const boost::system::error_code ec,
+                                   const GetSubTreeType& subtree) {
+            if (ec)
+            {
+                std::cerr << __FUNCTION__ << ": Error contacting mapper "
+                          << ec.message() << "\n";
+                componentsLoadedCallback->setError();
+                return;
+            }
+
+            for (auto& [path, objDict] : subtree)
+            {
+
+                if (objDict.empty())
+                {
+                    std::cerr << __FUNCTION__ << ": Subtree data corrupted !\n";
+                    componentsLoadedCallback->setError();
+                    return;
+                }
+
+                /* Ideally there would be only one element in objDict as only
+                 * one service exposes it and there would be only one interface
+                 * so it is safe to directly read them without loop */
+                const std::string& service = objDict.begin()->first;
+                const std::string& intf = objDict.begin()->second.front();
+
+                conn->async_method_call(
+                    [componentsLoadedCallback](
+                        const boost::system::error_code er,
+                        const boost::container::flat_map<
+                            std::string, BasicVariantType>& resp) {
+                        if (er)
+                        {
+                            std::cerr << __FUNCTION__
+                                      << ": Error Getting "
+                                         "Config "
+                                      << er.message() << "\n";
+                            componentsLoadedCallback->setError();
+                            return;
+                        }
+
+                        std::optional<uint64_t> bus;
+                        std::optional<uint64_t> address;
+                        std::optional<std::string> mode;
+                        std::optional<uint64_t> outCtrlBaseAddr;
+                        std::optional<uint64_t> outCtrlByteCount;
+                        std::unordered_map<std::string,
+                                           std::vector<std::string>>
+                            byteMap;
+                        std::optional<std::string> name;
+                        std::optional<std::string> type;
+
+                        /* Loop through to get all Clock Buffer properties */
+                        for (const auto& [key, value] : resp)
+                        {
+                            if (key == "Bus")
+                            {
+                                bus = std::get<uint64_t>(value);
+                            }
+                            else if (key == "Address")
+                            {
+                                address = std::get<uint64_t>(value);
+                            }
+                            else if (key == "Mode")
+                            {
+                                mode = std::get<std::string>(value);
+                            }
+                            else if (key == "OutCtrlBaseAddr")
+                            {
+                                outCtrlBaseAddr = std::get<uint64_t>(value);
+                            }
+                            else if (key == "OutCtrlByteCount")
+                            {
+                                outCtrlByteCount = std::get<uint64_t>(value);
+                            }
+                            else if (key == "Name")
+                            {
+                                name = std::get<std::string>(value);
+                            }
+                            else if (key == "Type")
+                            {
+                                type = std::get<std::string>(value);
+                            }
+                            else if (key.starts_with("Byte"))
+                            {
+                                std::optional<std::vector<std::string>>
+                                    byteList;
+                                byteList = std::get<NvmeMapping>(value);
+                                if (!byteList)
+                                {
+                                    break;
+                                }
+                                byteMap.try_emplace(key, *byteList);
+                            }
+                        }
+
+                        /* Verify if all properties were defined */
+                        if (!bus || !address || !mode || !outCtrlBaseAddr ||
+                            !outCtrlByteCount || !name)
+                        {
+                            std::cerr << __FUNCTION__
+                                      << ": Incomplete "
+                                         "Clock Buffer definition !! \n";
+                            componentsLoadedCallback->setError();
+                            return;
+                        }
+
+                        /* Check if we were able to get byteMap correctly */
+                        if ((*outCtrlByteCount) != byteMap.size())
+                        {
+                            std::cerr << __FUNCTION__
+                                      << ": Incomplete "
+                                         "Byte Map !! \n";
+                            componentsLoadedCallback->setError();
+                            return;
+                        }
+
+                        /* Create clock buffer object and add it to global
+                         * clockBuffers vector */
+                        clockBuffers.emplace_front(
+                            *bus, *address, *mode, *outCtrlBaseAddr,
+                            *outCtrlByteCount, byteMap, *name, *type);
+                    },
+                    service, path, "org.freedesktop.DBus.Properties", "GetAll",
+                    intf);
+            }
+        },
+        mapper::busName, mapper::path, mapper::interface, mapper::subtree, "/",
+        0, hsbpConfig.clockBufferTypes);
+}
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/***************** HSBP Config related Function Definitions *****************/
+/****************************************************************************/
+void loadHsbpConfig()
+{
+    appState = AppState::loadingHsbpConfig;
+
+    conn->async_method_call(
+        [](const boost::system::error_code ec, const GetSubTreeType& subtree) {
+            if (ec)
+            {
+                std::cerr << __FUNCTION__ << ": Error contacting mapper "
+                          << ec.message() << "\n";
+                return;
+            }
+
+            if (subtree.empty())
+            {
+                /* Entity manager is either still loading the configuration or
+                 * failed to load. In either way, return from here as the dbus
+                 * match will take care */
+                std::cerr << __FUNCTION__ << ": No configuration detected !!\n";
+                return;
+            }
+
+            /* There should be only one HSBP Configureation exposed */
+            if (subtree.size() != 1)
+            {
+                std::cerr << __FUNCTION__
+                          << ": Multiple configurations "
+                             "detected !!\n";
+                /* Critical Error. Stop Application */
+                stopHsbpManager();
+                return;
+            }
+
+            auto& path = subtree.begin()->first;
+            auto& objDict = subtree.begin()->second;
+
+            if (objDict.empty())
+            {
+                /* Critical Error. Stop Application */
+                std::cerr << __FUNCTION__ << ": Subtree data corrupted !\n";
+                stopHsbpManager();
+                return;
+            }
+
+            const std::string& service = objDict.begin()->first;
+
+            conn->async_method_call(
+                [](const boost::system::error_code er,
+                   const boost::container::flat_map<std::string,
+                                                    BasicVariantType>& resp) {
+                    if (er)
+                    {
+                        std::cerr << __FUNCTION__ << ": Error Getting Config "
+                                  << er.message() << "\n";
+                        /* Critical Error. Stop Application */
+                        stopHsbpManager();
+                        return;
+                    }
+
+                    std::optional<uint64_t> rootI2cBus;
+                    std::optional<std::vector<std::string>> supportedHsbps;
+                    std::optional<std::vector<std::string>> clockBufferTypes;
+                    std::optional<std::vector<std::string>> ioExpanderTypes;
+
+                    /* Loop through to get root i2c bus and list of supported
+                     * HSBPs */
+                    for (const auto& [key, value] : resp)
+                    {
+                        if (key == "HsbpSupported")
+                        {
+                            supportedHsbps =
+                                std::get<std::vector<std::string>>(value);
+                        }
+                        else if (key == "RootI2cBus")
+                        {
+                            rootI2cBus = std::get<uint64_t>(value);
+                        }
+                        else if (key == "ClockBuffer")
+                        {
+                            clockBufferTypes =
+                                std::get<std::vector<std::string>>(value);
+                        }
+                        else if (key == "IoExpander")
+                        {
+                            ioExpanderTypes =
+                                std::get<std::vector<std::string>>(value);
+                        }
+                    }
+
+                    /* Verify if i2c bus, supported HSBP's and clock buffers
+                     * were defined (IO Expanders are optional) */
+                    if (!rootI2cBus || !supportedHsbps || !clockBufferTypes)
+                    {
+                        std::cerr << __FUNCTION__
+                                  << ": Incomplete HSBP "
+                                     "configuration !! \n";
+                        /* Critical Error. Stop Application */
+                        stopHsbpManager();
+                        return;
+                    }
+
+                    /* Clear and Load all details to global hsbp configuration
+                     * variable */
+                    hsbpConfig.clearConfig();
+                    hsbpConfig.rootBus = *rootI2cBus;
+                    hsbpConfig.supportedHsbps = std::move(*supportedHsbps);
+
+                    for (auto& clkBuffType : *clockBufferTypes)
+                    {
+                        hsbpConfig.clockBufferTypes.emplace_back(
+                            "xyz.openbmc_project.Configuration." + clkBuffType);
+                    }
+
+                    if (ioExpanderTypes)
+                    {
+                        for (auto& ioCntrType : *ioExpanderTypes)
+                        {
+                            hsbpConfig.ioExpanderTypes.emplace_back(
+                                "xyz.openbmc_project.Configuration." +
+                                ioCntrType);
+                        }
+                    }
+
+                    /* Loop through to get HSBP-NVME map and Components map
+                     * details */
+                    uint8_t hsbpMapCount = 0;
+                    for (const auto& [key, value] : resp)
+                    {
+                        if (std::find(hsbpConfig.supportedHsbps.begin(),
+                                      hsbpConfig.supportedHsbps.end(),
+                                      key) != hsbpConfig.supportedHsbps.end())
+                        {
+                            std::optional<std::vector<std::string>> hsbpMap;
+                            hsbpMap = std::get<NvmeMapping>(value);
+                            if (!hsbpMap)
+                            {
+                                break;
+                            }
+                            hsbpConfig.hsbpNvmeMap.try_emplace(key, *hsbpMap);
+                            hsbpMapCount++;
+                        }
+                    }
+
+                    /* Check if we were able to get all the HSBP-NVMe maps */
+                    if (hsbpConfig.supportedHsbps.size() != hsbpMapCount)
+                    {
+                        std::cerr << __FUNCTION__
+                                  << ": Incomplete HSBP Map "
+                                     "details !! \n";
+                        /* Critical Error. Stop Application */
+                        stopHsbpManager();
+                        return;
+                    }
+
+                    /* HSBP configuration is loaded */
+                    appState = AppState::hsbpConfigLoaded;
+                    std::cerr << "HSBP Config loaded !\n";
+
+                    /* Get Clock buffers and IO expander details. Create shared
+                     * object of AsyncCallbackHandler with success and error
+                     * callback */
+                    auto componentsLoadedCallback = std::make_shared<
+                        AsyncCallbackHandler>(
+                        []() {
+                            /* Verify if all components were initialized without
+                             * errors */
+                            if (!verifyComponentsLoaded())
+                            {
+                                /* The application cannot proceed further as
+                                 * components initialization failed. App needs
+                                 * Restart */
+                                appState = AppState::idle;
+                                std::cerr
+                                    << "One or more Componenets initialization "
+                                       "failed !! Restart Required !\n";
+                                stopHsbpManager();
+                            }
+
+                            appState = AppState::componentsLoaded;
+                            setUpBackplanesAndDrives();
+                        },
+                        []() {
+                            /* The application cannot proceed further as
+                             * components load failed. App needs Restart */
+                            appState = AppState::idle;
+                            std::cerr << "Loading Componenets failed !! "
+                                         "Restart Required !\n";
+                            stopHsbpManager();
+                        });
+
+                    loadClockBufferInfo(componentsLoadedCallback);
+
+                    if (ioExpanderTypes)
+                    {
+                        loadIoExpanderInfo(componentsLoadedCallback);
+                    }
+                },
+                service, path, "org.freedesktop.DBus.Properties", "GetAll",
+                hsbpConfigIntf);
+        },
+        mapper::busName, mapper::path, mapper::interface, mapper::subtree, "/",
+        0, std::array<const char*, 1>{hsbpConfigIntf});
+}
+
+void setupHsbpConfigMatch()
+{
+    static auto hsbpConfigMatch = std::make_unique<sdbusplus::bus::match_t>(
+        *conn,
+        "sender='xyz.openbmc_project.EntityManager', type='signal', "
+        "member='PropertiesChanged', "
+        "interface='org.freedesktop.DBus.Properties', "
+        "path_namespace='/xyz/openbmc_project/inventory/system/board', arg0='" +
+            std::string(hsbpConfigIntf) + "'",
+        [](sdbusplus::message_t& msg) {
+            std::string intfName;
+            boost::container::flat_map<std::string, BasicVariantType> values;
+            msg.read(intfName, values);
+
+            /* This match will be triggered for each of the property being set
+             * under the hsbpConfig interface. "HsbpSupported" is one of the
+             * important property which will enable us to read other properties.
+             * So, when the match event occurs for "HsbpSupported" property
+             * being set, we will call "loadHsbpConfig()" If the control has
+             * come here, its either the first initialization or entity-manager
+             * reload. So, we will reset the state to uninitialized
+             */
+            for (const auto& [key, value] : values)
+            {
+                if (key == "HsbpSupported")
+                {
+                    /* Configuration change detected, change the state to stop
+                     * other processing */
+                    appState = AppState::idle;
+
+                    /* We will call the function after a small delay to let all
+                     * the properties to be intialized */
+                    auto loadTimer =
+                        std::make_shared<boost::asio::steady_timer>(io);
+                    loadTimer->expires_after(std::chrono::seconds(1));
+                    loadTimer->async_wait(
+                        [loadTimer](const boost::system::error_code ec) {
+                            if (ec == boost::asio::error::operation_aborted)
+                            {
+                                return;
+                            }
+                            else if (ec)
+                            {
+                                std::cerr << __FUNCTION__ << ": Timer error"
+                                          << ec.message() << "\n";
+                                if (hsbpConfig.supportedHsbps.empty())
+                                {
+                                    /* Critical Error as none of the
+                                     * configuration was loaded and timer
+                                     * failed. Stop the application */
+                                    stopHsbpManager();
+                                }
+                                return;
+                            }
+                            loadHsbpConfig();
+                        });
+                }
+            }
+        });
+}
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/***************** GPIO Events related Function Definitions *****************/
+/****************************************************************************/
+static void nvmeLvc3AlertHandler()
+{
+    /* If the state is not backplanesLoaded, we ignore the GPIO event as we
+     * cannot communicate to the backplanes yet */
+    if (appState < AppState::backplanesLoaded)
+    {
+        std::cerr << __FUNCTION__
+                  << ": HSBP not initialized ! Dropping the interrupt ! \n";
+        return;
+    }
+
+    /* This GPIO event only indicates the addition or removal of drive to either
+     * of CPU. The backplanes detected need to be scanned and detect which drive
+     * has been added/removed and enable/diable clock accordingly */
+    gpiod::line_event gpioLineEvent = nvmeLvc3AlertLine.event_read();
+
+    if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
+    {
+        /* Check for HSBP Drives status to determine if any new drive has been
+         * added/removed and update clocks accordingly */
+        checkHsbpDrivesStatus();
+    }
+
+    nvmeLvc3AlertEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << __FUNCTION__
+                          << ": nvmealert event error: " << ec.message()
+                          << "\n";
+            }
+            nvmeLvc3AlertHandler();
+        });
 }
 
 static bool hsbpRequestAlertGpioEvents(
@@ -1059,7 +2788,8 @@
     gpioLine = gpiod::find_line(name);
     if (!gpioLine)
     {
-        std::cerr << "Failed to find the " << name << " line\n";
+        std::cerr << __FUNCTION__ << ": Failed to find the " << name
+                  << " line\n";
         return false;
     }
 
@@ -1070,14 +2800,15 @@
     }
     catch (std::exception&)
     {
-        std::cerr << "Failed to request events for " << name << "\n";
+        std::cerr << __FUNCTION__ << ": Failed to request events for " << name
+                  << "\n";
         return false;
     }
 
     int gpioLineFd = gpioLine.event_get_fd();
     if (gpioLineFd < 0)
     {
-        std::cerr << "Failed to get " << name << " fd\n";
+        std::cerr << __FUNCTION__ << ": Failed to get " << name << " fd\n";
         return false;
     }
 
@@ -1088,439 +2819,70 @@
         [&name, handler](const boost::system::error_code ec) {
             if (ec)
             {
-                std::cerr << name << " fd handler error: " << ec.message()
-                          << "\n";
+                std::cerr << __FUNCTION__ << ": " << name
+                          << " fd handler error: " << ec.message() << "\n";
                 return;
             }
             handler();
         });
     return true;
 }
-
-/******************************************************************************************
- *   HSBP Position           CPLD SMB Address
- *        1                   0xD0(0x68 7 bit)
- *        2                   0xD2(0x69 7 bit)
- *  we have max 2 HSBP per system. Closed chassis systems will either have 0 or
- *  2 HSBP's.
- *******************************************************************************************/
-static constexpr uint8_t hsbpI2cBus = 4;
-static constexpr uint8_t allDrivesWithStatusBit = 17;
-static constexpr uint8_t statusAllDrives = (allDrivesWithStatusBit - 1);
-static constexpr uint8_t allClockBitsDb2000 = 25;
-static constexpr uint8_t statusAllClocksDb2000 = (allClockBitsDb2000 - 1);
-static constexpr uint8_t singleDriveWithStatusBit = 9;
-static constexpr uint8_t statusSingleDrive = (singleDriveWithStatusBit - 1);
-static constexpr uint8_t maxDrivesPerHsbp = 8;
-
-static std::bitset<allDrivesWithStatusBit> drivePresenceStatus;
-static std::bitset<allClockBitsDb2000> driveClockStatus;
-static constexpr uint8_t hsbpCpldSmbaddr1 = 0x68;
-static constexpr uint8_t hsbpCpldSmbaddr2 = 0x69;
-static constexpr uint8_t hsbpCpldReg8 = 0x8;
-static constexpr uint8_t hsbpCpldReg9 = 0x9;
-static constexpr uint8_t db2000SlaveAddr = 0x6d;
-static constexpr uint8_t db2000RegByte0 = 0x80;
-static constexpr uint8_t db2000RegByte1 = 0x81;
-static constexpr uint8_t db2000RegByte2 = 0x82;
-static int hsbpFd;
-
-/********************************************************************
- *  DB2000 Programming guide for PCIe Clocks enable/disable
- *  CPU 0
- * =================================================================
- *  slot        Byte        bit number
- *  Position   position
- * =================================================================
- *  7            0           5
- *  6            0           4
- *  5            0           3
- *  4            2           7
- *  3            1           3
- *  2            1           2
- *  1            1           1
- *  0            1           0
- *
- *  CPU 1
- * =================================================================
- *  slot        Byte        bit number
- *  Position   position
- * =================================================================
- *  7            1           6
- *  6            1           7
- *  5            2           0
- *  4            2           1
- *  3            1           5
- *  2            2           4
- *  1            2           2
- *  0            2           3
- *********************************************************************/
-std::optional<int>
-    updateClocksStatus(std::bitset<allDrivesWithStatusBit> nvmeDriveStatus)
-{
-    std::bitset<allClockBitsDb2000> nvmeClockStatus;
-    /* mapping table for nvme drive index(0-15) to DB2000 register bit fields */
-    constexpr std::array<int, statusAllDrives> slotToClockTable = {
-        8, 9, 10, 11, 23, 3, 4, 5, 19, 18, 20, 13, 17, 16, 15, 14};
-
-    /* scan through all drives(except the status bit) and update corresponding
-     * clock bit */
-    for (std::size_t i = 0; i < (nvmeDriveStatus.size() - 1); i++)
-    {
-        if (nvmeDriveStatus.test(i))
-        {
-            nvmeClockStatus.set(slotToClockTable[i]);
-        }
-        else
-        {
-            nvmeClockStatus.reset(slotToClockTable[i]);
-        }
-    }
-
-    if (ioctl(hsbpFd, I2C_SLAVE_FORCE, db2000SlaveAddr) < 0)
-    {
-        std::cerr << "unable to set DB2000 address to " << db2000SlaveAddr
-                  << "\n";
-        return std::nullopt;
-    }
-    int ret = i2c_smbus_write_byte_data(
-        hsbpFd, db2000RegByte0,
-        static_cast<unsigned char>(nvmeClockStatus.to_ulong()));
-
-    if (ret < 0)
-    {
-        std::cerr << "Error: unable to write data to clock register "
-                  << __FUNCTION__ << __LINE__ << "\n";
-        return ret;
-    }
-
-    ret = i2c_smbus_write_byte_data(
-        hsbpFd, db2000RegByte1,
-        static_cast<unsigned char>((nvmeClockStatus >> 8).to_ulong()));
-
-    if (ret < 0)
-    {
-        std::cerr << "Error: unable to write data to clock register "
-                  << __FUNCTION__ << __LINE__ << "\n";
-        return ret;
-    }
-
-    ret = i2c_smbus_write_byte_data(
-        hsbpFd, db2000RegByte2,
-        static_cast<unsigned char>((nvmeClockStatus >> 16).to_ulong()));
-
-    if (ret < 0)
-    {
-        std::cerr << "Error: unable to write data to clock register "
-                  << __FUNCTION__ << __LINE__ << "\n";
-        return ret;
-    }
-    // Update global clock status
-    driveClockStatus = nvmeClockStatus;
-    driveClockStatus.set(statusAllClocksDb2000, 1);
-    return 0;
-}
-
-std::bitset<singleDriveWithStatusBit>
-    getSingleHsbpDriveStatus(const uint8_t cpldSmbaddr)
-{
-    std::bitset<singleDriveWithStatusBit> singleDriveStatus;
-
-    // probe
-    if (ioctl(hsbpFd, I2C_SLAVE_FORCE, cpldSmbaddr) < 0)
-    {
-        std::cerr << "Failed to talk to cpldSmbaddr :  " << cpldSmbaddr << "\n";
-        return singleDriveStatus;
-    }
-
-    // read status of lower four drive connectivity
-    int valueReg8 = i2c_smbus_read_byte_data(hsbpFd, hsbpCpldReg8);
-    if (valueReg8 < 0)
-    {
-        std::cerr << "Error: Unable to read cpld reg 0x8 " << __FUNCTION__
-                  << __LINE__ << "\n";
-        return singleDriveStatus;
-    }
-
-    // read status of upper four drive connectivity
-    int valueReg9 = i2c_smbus_read_byte_data(hsbpFd, hsbpCpldReg9);
-    if (valueReg9 < 0)
-    {
-        std::cerr << "Error: Unable to read cpld reg 0x9 " << __FUNCTION__
-                  << __LINE__ << "\n";
-        return singleDriveStatus;
-    }
-
-    // Find drives which have NVMe drive connected
-    for (int loop = 0; loop < (singleDriveWithStatusBit - 1); loop++)
-    {
-        // Check if NVME drive detected(corresponding bit numbers of reg8 and
-        // reg9 are 1 and 0 resp)
-        if (valueReg8 & (1U << loop))
-        {
-            if ((valueReg9 & (1U << loop)) == 0)
-            {
-                singleDriveStatus.set(loop, 1);
-            }
-        }
-    }
-
-    // Reading successful, set the statusok bit
-    singleDriveStatus.set(statusSingleDrive, 1);
-    return singleDriveStatus;
-}
-
-/* Try reading both HSBP and report back if atleast one of them is found to be
-   connected. Status bit is set by the function even if one HSBP is responding
- */
-std::bitset<allDrivesWithStatusBit> getCompleteDriveStatus(void)
-{
-    std::bitset<singleDriveWithStatusBit> singleDrvStatus;
-    std::bitset<allDrivesWithStatusBit> currDriveStatus;
-
-    singleDrvStatus = getSingleHsbpDriveStatus(hsbpCpldSmbaddr1);
-
-    if (singleDrvStatus[statusSingleDrive] == 1)
-    {
-        for (int i = 0; i < maxDrivesPerHsbp; i++)
-        {
-            currDriveStatus[i] = singleDrvStatus[i];
-        }
-        // set valid bit if a single hsbp drive status is valid
-        currDriveStatus.set(statusAllDrives);
-    }
-    else
-    {
-        currDriveStatus &= (~0xFF);
-    }
-
-    singleDrvStatus = getSingleHsbpDriveStatus(hsbpCpldSmbaddr2);
-    if (singleDrvStatus[statusSingleDrive] == 1)
-    {
-        for (int i = maxDrivesPerHsbp, j = 0; i < (allDrivesWithStatusBit - 1);
-             i++, j++)
-        {
-            currDriveStatus[i] = singleDrvStatus[j];
-        }
-        // set valid bit if a single hsbp drive status is valid
-        currDriveStatus.set(statusAllDrives);
-    }
-    else
-    {
-        currDriveStatus &= (~(0xFF << maxDrivesPerHsbp));
-    }
-    return currDriveStatus;
-}
-
-void cpldReadingInit(void)
-{
-    hsbpFd = open(("/dev/i2c-" + std::to_string(hsbpI2cBus)).c_str(),
-                  O_RDWR | O_CLOEXEC);
-    if (hsbpFd < 0)
-    {
-        std::cerr << "unable to open hsbpI2cBus " << hsbpI2cBus << "\n";
-        return;
-    }
-
-    std::bitset<allDrivesWithStatusBit> currDrvStatus =
-        getCompleteDriveStatus();
-    if (currDrvStatus[statusAllDrives] == 1)
-    {
-        // update global drive presence for next time comparison
-        drivePresenceStatus = currDrvStatus;
-        std::optional<int> updateStatus =
-            updateClocksStatus(drivePresenceStatus);
-        if (updateStatus.has_value())
-        {
-            if (updateStatus == -1)
-            {
-                std::cerr << "error: DB2000 register read issue "
-                          << "\n";
-                close(hsbpFd);
-                hsbpFd = -1;
-            }
-        }
-        else
-        {
-            std::cerr << "error: DB2000 i2c access issue "
-                      << "\n";
-            close(hsbpFd);
-            hsbpFd = -1;
-        }
-    }
-    else
-    {
-        close(hsbpFd);
-        hsbpFd = -1;
-    }
-}
-
-// Callback handler passed to hsbpRequestAlertGpioEvents:
-static void nvmeLvc3AlertHandler()
-{
-    if (hsbpFd >= 0)
-    {
-        gpiod::line_event gpioLineEvent = nvmeLvc3AlertLine.event_read();
-
-        if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
-        {
-            /* Step 1: Either drive is removed or inserted; read the CPLD reg 8
-               and 9 to determine if drive is added or removed. Need to compare
-                    current number of drives with previous state to determine
-               it.
-            */
-            std::bitset<allDrivesWithStatusBit> currDrvStat =
-                getCompleteDriveStatus();
-            if (currDrvStat[statusAllDrives] == 1)
-            {
-                if (drivePresenceStatus != currDrvStat)
-                {
-                    uint32_t tmpVar = static_cast<uint32_t>(
-                        (drivePresenceStatus ^ currDrvStat).to_ulong());
-                    uint32_t indexDrive = 0;
-                    while (tmpVar > 0)
-                    {
-                        if (tmpVar & 1)
-                        {
-                            if (drivePresenceStatus[indexDrive] == 0)
-                            {
-                                logDeviceAdded(
-                                    "Drive", std::to_string(indexDrive), "N/A");
-                            }
-                            else
-                            {
-                                logDeviceRemoved(
-                                    "Drive", std::to_string(indexDrive), "N/A");
-                            }
-                        }
-                        indexDrive++;
-                        tmpVar >>= 1;
-                    }
-                    // update global drive presence for next time comparison
-                    drivePresenceStatus = currDrvStat;
-
-                    // Step 2: disable or enable the pcie clock for
-                    // corresponding drive
-                    std::optional<int> tmpUpdStatus =
-                        updateClocksStatus(currDrvStat);
-                    if (tmpUpdStatus.has_value())
-                    {
-                        if (tmpUpdStatus == -1)
-                        {
-                            std::cerr << "error: DB2000 register read issue "
-                                      << "\n";
-                            close(hsbpFd);
-                            hsbpFd = -1;
-                        }
-                    }
-                    else
-                    {
-                        std::cerr << "error: DB2000 i2c access issue "
-                                  << "\n";
-                        close(hsbpFd);
-                        hsbpFd = -1;
-                    }
-                }
-                // false alarm
-                else
-                {
-                    std::cerr
-                        << "False alarm detected by HSBP; no action taken \n";
-                }
-            }
-            else
-            {
-                close(hsbpFd);
-                hsbpFd = -1;
-            }
-        }
-
-        nvmeLvc3AlertEvent.async_wait(
-            boost::asio::posix::stream_descriptor::wait_read,
-            [](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    std::cerr << "nvmealert handler error: " << ec.message()
-                              << "\n";
-                    return;
-                }
-                nvmeLvc3AlertHandler();
-            });
-    }
-}
+/***************************** End of Section *******************************/
 
 int main()
 {
-    boost::asio::steady_timer callbackTimer(io);
+    std::cerr << "******* Starting hsbp-manager *******\n";
 
+    /* Set the Dbus name */
     conn->request_name(busName);
 
-    sdbusplus::bus::match_t match(
-        *conn,
-        "type='signal',member='PropertiesChanged',arg0='" +
-            std::string(configType) + "'",
-        [&callbackTimer](sdbusplus::message_t&) {
-            callbackTimer.expires_after(std::chrono::seconds(2));
-            callbackTimer.async_wait([](const boost::system::error_code ec) {
-                if (ec == boost::asio::error::operation_aborted)
-                {
-                    // timer was restarted
-                    return;
-                }
-                else if (ec)
-                {
-                    std::cerr << "Timer error" << ec.message() << "\n";
-                    return;
-                }
-                populate();
-            });
-        });
+    /* Add interface for storage inventory */
+    objServer.add_interface("/xyz/openbmc_project/inventory/item/storage",
+                            "xyz.openbmc_project.inventory.item.storage");
 
-    sdbusplus::bus::match_t drive(
-        *conn,
-        "type='signal',member='PropertiesChanged',arg0='xyz.openbmc_project."
-        "Inventory.Item.NVMe'",
-        [&callbackTimer](sdbusplus::message_t& message) {
-            callbackTimer.expires_after(std::chrono::seconds(2));
-            if (message.get_sender() == conn->get_unique_name())
-            {
-                return;
-            }
-            callbackTimer.async_wait([](const boost::system::error_code ec) {
-                if (ec == boost::asio::error::operation_aborted)
-                {
-                    // timer was restarted
-                    return;
-                }
-                else if (ec)
-                {
-                    std::cerr << "Timer error" << ec.message() << "\n";
-                    return;
-                }
-                updateAssets();
-            });
-        });
+    /* HSBP initializtion flow:
+     * 1. Register GPIO event callback on FM_SMB_BMC_NVME_LVC3_ALERT_N line
+     * 2. Set up Dbus match for power - determine if host is up and running
+     *    or powered off
+     * 3. Set up Dbus match for HSBP backplanes and Drives
+     * 4. Load HSBP config exposed by entity manager
+     *    - Also setup a match to capture HSBP configuation in case
+     *      entity-manager restarts
+     * 5. Load Clock buffer and IO expander (and other peripherals if any
+     *    related to HSBP functionality)
+     *    - Reload the info each time HSBP configuration is changed
+     * 6. Populate all Backpanes (HSBP's)
+     * 7. Load all NVMe drive's and associate with HSBP Backpane
+     */
 
-    cpldReadingInit();
-
-    if (hsbpFd >= 0)
+    /* Register GPIO Events on FM_SMB_BMC_NVME_LVC3_ALERT_N */
+    if (!hsbpRequestAlertGpioEvents("FM_SMB_BMC_NVME_LVC3_ALERT_N",
+                                    nvmeLvc3AlertHandler, nvmeLvc3AlertLine,
+                                    nvmeLvc3AlertEvent))
     {
-        if (!hsbpRequestAlertGpioEvents("FM_SMB_BMC_NVME_LVC3_ALERT_N",
-                                        nvmeLvc3AlertHandler, nvmeLvc3AlertLine,
-                                        nvmeLvc3AlertEvent))
-        {
-            std::cerr << "error: Unable to monitor events on HSBP Alert line "
-                      << "\n";
-        }
+        std::cerr << __FUNCTION__
+                  << ": error: Unable to monitor events on HSBP "
+                     "Alert line\n";
+        return -1;
     }
 
-    auto iface =
-        objServer.add_interface("/xyz/openbmc_project/inventory/item/storage",
-                                "xyz.openbmc_project.inventory.item.storage");
-
-    io.post([]() { populate(); });
+    /* Setup Dbus-match for power */
     setupPowerMatch(conn);
+
+    /* Setup Dbus-match for HSBP backplanes and Drives */
+    setupBackplanesAndDrivesMatch();
+
+    /* Setup HSBP Config match and load config
+     * In the event of entity-manager reboot, the match will help catch new
+     * configuration.
+     * In the event of hsbp-manager reboot, loadHsbpConfig will get all
+     * config details and will take care of remaining config's to be
+     * loaded
+     */
+    setupHsbpConfigMatch();
+    loadHsbpConfig();
+
     io.run();
-    close(hsbpFd);
-    hsbpFd = -1;
+    std::cerr << __FUNCTION__ << ": Aborting hsbp-manager !\n";
+    return -1;
 }
