summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Feist <james.feist@linux.intel.com>2019-10-09 23:15:13 +0300
committerFeist, James <james.feist@intel.com>2019-10-15 20:14:03 +0300
commit9fecb52a7a5cd0afebb98efcffac1359289914fd (patch)
tree81e6758b0cae083958d3978f8f5027fe74a5e7cf
parent342bc446a047313000529538a8250ab2955c5ddf (diff)
downloadprovingground-9fecb52a7a5cd0afebb98efcffac1359289914fd.tar.xz
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 <james.feist@linux.intel.com>
-rw-r--r--hsbp-manager/include/utils.hpp96
-rw-r--r--hsbp-manager/src/hsbp_manager.cpp16
2 files changed, 112 insertions, 0 deletions
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 <boost/algorithm/string/predicate.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <boost/container/flat_map.hpp>
#include <cstdint>
+#include <iostream>
+#include <sdbusplus/asio/connection.hpp>
#include <string>
#include <variant>
#include <vector>
@@ -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<sdbusplus::bus::match::match> 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<sdbusplus::asio::connection>& 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<sdbusplus::bus::match::match>(
+ static_cast<sdbusplus::bus::bus&>(*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<std::string, std::variant<std::string>>
+ values;
+ message.read(objectName, values);
+ auto findState = values.find(power::property);
+ if (findState != values.end())
+ {
+ bool on = boost::ends_with(
+ std::get<std::string>(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<std::string>& state) {
+ if (ec)
+ {
+ // we commonly come up before power control, we'll capture the
+ // property change later
+ return;
+ }
+ powerStatusOn =
+ boost::ends_with(std::get<std::string>(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<Led>
{
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();
}