From 9fecb52a7a5cd0afebb98efcffac1359289914fd Mon Sep 17 00:00:00 2001 From: James Feist Date: Wed, 9 Oct 2019 13:15:13 -0700 Subject: Handle power state changes We need to check if power is on as the hsbp goes away during power off. This copies the power logic from dbus-sensors and uses it to avoid scanning when power is off. Tested: Warnings go away Change-Id: Ie949e7a98eb70592318710f3eecdfe766f71f110 Signed-off-by: James Feist --- hsbp-manager/include/utils.hpp | 96 +++++++++++++++++++++++++++++++++++++++ hsbp-manager/src/hsbp_manager.cpp | 16 +++++++ 2 files changed, 112 insertions(+) diff --git a/hsbp-manager/include/utils.hpp b/hsbp-manager/include/utils.hpp index 986c3b2..0b47a54 100644 --- a/hsbp-manager/include/utils.hpp +++ b/hsbp-manager/include/utils.hpp @@ -14,7 +14,13 @@ // limitations under the License. */ +#include +#include +#include +#include #include +#include +#include #include #include #include @@ -51,6 +57,20 @@ constexpr const char* interface = "xyz.openbmc_project.Led.Group"; constexpr const char* asserted = "Asserted"; } // namespace ledGroup +namespace properties +{ +constexpr const char* interface = "org.freedesktop.DBus.Properties"; +constexpr const char* get = "Get"; +} // namespace properties + +namespace power +{ +const static constexpr char* busname = "xyz.openbmc_project.State.Host"; +const static constexpr char* interface = "xyz.openbmc_project.State.Host"; +const static constexpr char* path = "/xyz/openbmc_project/state/host0"; +const static constexpr char* property = "CurrentHostState"; +} // namespace power + namespace hsbp { enum class registers : uint8_t @@ -82,3 +102,79 @@ enum class registers : uint8_t }; } // namespace hsbp + +static std::unique_ptr powerMatch = nullptr; +static bool powerStatusOn = false; + +bool isPowerOn(void) +{ + if (!powerMatch) + { + throw std::runtime_error("Power Match Not Created"); + } + return powerStatusOn; +} + +void setupPowerMatch(const std::shared_ptr& conn) +{ + static boost::asio::steady_timer timer(conn->get_io_context()); + // create a match for powergood changes, first time do a method call to + // cache the correct value + if (powerMatch) + { + return; + } + + powerMatch = std::make_unique( + static_cast(*conn), + "type='signal',interface='" + std::string(properties::interface) + + "',path='" + std::string(power::path) + "',arg0='" + + std::string(power::interface) + "'", + [](sdbusplus::message::message& message) { + std::string objectName; + boost::container::flat_map> + values; + message.read(objectName, values); + auto findState = values.find(power::property); + if (findState != values.end()) + { + bool on = boost::ends_with( + std::get(findState->second), "Running"); + if (!on) + { + timer.cancel(); + powerStatusOn = false; + return; + } + // on comes too quickly + timer.expires_after(std::chrono::seconds(10)); + timer.async_wait([](boost::system::error_code ec) { + if (ec == boost::asio::error::operation_aborted) + { + return; + } + else if (ec) + { + std::cerr << "Timer error " << ec.message() << "\n"; + return; + } + powerStatusOn = true; + }); + } + }); + + conn->async_method_call( + [](boost::system::error_code ec, + const std::variant& state) { + if (ec) + { + // we commonly come up before power control, we'll capture the + // property change later + return; + } + powerStatusOn = + boost::ends_with(std::get(state), "Running"); + }, + power::busname, power::path, properties::interface, properties::get, + power::interface, power::property); +} diff --git a/hsbp-manager/src/hsbp_manager.cpp b/hsbp-manager/src/hsbp_manager.cpp index 08874e9..83ebdf3 100644 --- a/hsbp-manager/src/hsbp_manager.cpp +++ b/hsbp-manager/src/hsbp_manager.cpp @@ -95,10 +95,18 @@ struct Led : std::enable_shared_from_this { return 1; } + + if (!isPowerOn()) + { + std::cerr << "Can't change blink state when power is off\n"; + throw std::runtime_error( + "Can't change blink state when power is off"); + } BlinkPattern pattern = req ? BlinkPattern::error : BlinkPattern::terminate; if (!self->set(pattern)) { + std::cerr << "Can't change blink pattern\n"; throw std::runtime_error("Cannot set blink pattern"); } val = req; @@ -281,6 +289,13 @@ struct Backplane std::cerr << "timer error " << ec.message() << "\n"; return; } + + if (!isPowerOn()) + { + // can't access hsbp when power is off + runTimer(); + return; + } uint8_t curPresence = 0; uint8_t curIFDET = 0; uint8_t curFailed = 0; @@ -857,5 +872,6 @@ int main() }); io.post([]() { populate(); }); + setupPowerMatch(conn); io.run(); } -- cgit v1.2.3