diff options
author | James Feist <james.feist@linux.intel.com> | 2019-10-09 19:29:03 +0300 |
---|---|---|
committer | Feist, James <james.feist@intel.com> | 2019-10-15 20:14:03 +0300 |
commit | 342bc446a047313000529538a8250ab2955c5ddf (patch) | |
tree | 72a436aea32144faff95457e3a68d3b64250a65b | |
parent | 4a229a0675852c295b3e1639946be524017572fb (diff) | |
download | provingground-342bc446a047313000529538a8250ab2955c5ddf.tar.xz |
Add LED hooks to hsbp manager
This adds the led group interface so that they can
be activiated by NVMe daemon.
Tested: Set using dbus, went and saw drive flashing
Change-Id: I2e1aa3f9338609370d9758a7c4874428dac5d4ea
Signed-off-by: James Feist <james.feist@linux.intel.com>
-rw-r--r-- | hsbp-manager/include/utils.hpp | 6 | ||||
-rw-r--r-- | hsbp-manager/src/hsbp_manager.cpp | 82 |
2 files changed, 83 insertions, 5 deletions
diff --git a/hsbp-manager/include/utils.hpp b/hsbp-manager/include/utils.hpp index 8e63bfe..986c3b2 100644 --- a/hsbp-manager/include/utils.hpp +++ b/hsbp-manager/include/utils.hpp @@ -45,6 +45,12 @@ namespace inventory constexpr const char* interface = "xyz.openbmc_project.Inventory.Item"; } // namespace inventory +namespace ledGroup +{ +constexpr const char* interface = "xyz.openbmc_project.Led.Group"; +constexpr const char* asserted = "Asserted"; +} // namespace ledGroup + namespace hsbp { enum class registers : uint8_t diff --git a/hsbp-manager/src/hsbp_manager.cpp b/hsbp-manager/src/hsbp_manager.cpp index 5b34872..08874e9 100644 --- a/hsbp-manager/src/hsbp_manager.cpp +++ b/hsbp-manager/src/hsbp_manager.cpp @@ -57,6 +57,73 @@ struct Mux size_t bus; size_t address; }; + +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 + Led(const std::string& path, size_t index, int fd) : + address(static_cast<uint8_t>(index + 0x10)), file(fd), + ledInterface(objServer.add_interface(path, ledGroup::interface)) + { + if (index >= maxDrives) + { + throw std::runtime_error("Invalid drive index"); + } + + if (!set(BlinkPattern::off)) + { + std::cerr << "Cannot initialize LED " << path << "\n"; + } + } + + // this has to be called outside the constructor for shared_from_this to + // work + void createInterface(void) + { + std::shared_ptr<Led> self = shared_from_this(); + + ledInterface->register_property( + ledGroup::asserted, false, [self](const bool req, bool& val) { + if (req == val) + { + return 1; + } + BlinkPattern pattern = + req ? BlinkPattern::error : BlinkPattern::terminate; + if (!self->set(pattern)) + { + throw std::runtime_error("Cannot set blink pattern"); + } + val = req; + return 1; + }); + ledInterface->initialize(); + } + + virtual ~Led() + { + objServer.remove_interface(ledInterface); + } + + bool set(BlinkPattern pattern) + { + int ret = i2c_smbus_write_byte_data(file, address, + static_cast<uint8_t>(pattern)); + return ret >= 0; + } + + uint8_t address; + int file; + std::shared_ptr<sdbusplus::asio::dbus_interface> ledInterface; +}; + struct Drive { Drive(size_t driveIndex, bool isPresent, bool isOperational, bool nvme, @@ -81,7 +148,7 @@ struct Drive rebuildingIface->register_property("Rebuilding", rebuilding); rebuildingIface->initialize(); } - ~Drive() + virtual ~Drive() { objServer.remove_interface(itemIface); objServer.remove_interface(operationalIface); @@ -150,7 +217,8 @@ struct Backplane } void run() { - file = open(("/dev/i2c-" + std::to_string(bus)).c_str(), O_RDWR); + file = open(("/dev/i2c-" + std::to_string(bus)).c_str(), + O_RDWR | O_CLOEXEC); if (file < 0) { std::cerr << "unable to open bus " << bus << "\n"; @@ -248,8 +316,11 @@ struct Backplane // +1 to convert from 0 based to 1 based size_t driveIndex = (backplaneIndex * maxDrives) + ii + 1; - drives.emplace_back(driveIndex, isPresent, !isFailed, isNvme, - isRebuilding); + Drive& drive = drives.emplace_back(driveIndex, isPresent, !isFailed, + isNvme, isRebuilding); + std::shared_ptr<Led> led = leds.emplace_back(std::make_shared<Led>( + drive.itemIface->get_object_path(), ii, file)); + led->createInterface(); } } @@ -395,7 +466,7 @@ struct Backplane return true; } - ~Backplane() + virtual ~Backplane() { objServer.remove_interface(hsbpItemIface); objServer.remove_interface(versionIface); @@ -429,6 +500,7 @@ struct Backplane std::shared_ptr<sdbusplus::asio::dbus_interface> versionIface; std::vector<Drive> drives; + std::vector<std::shared_ptr<Led>> leds; std::shared_ptr<std::vector<Mux>> muxes; }; |