Add STATUS_WORD to metadata for VIN_UV_FAULT
Change-Id: Iaa6001f7c5d0c558ad3bc01e209dc316236fea93
Signed-off-by: Brandon Wyman <bjwyman@gmail.com>
diff --git a/elog-errors.hpp b/elog-errors.hpp
index 7ea5cf3..5a6fad8 100644
--- a/elog-errors.hpp
+++ b/elog-errors.hpp
@@ -544,13 +544,22 @@
namespace _PowerSupplyUnderVoltageFault
{
+struct RAW_STATUS
+{
+ static constexpr auto str = "RAW_STATUS=%s";
+ static constexpr auto str_short = "RAW_STATUS";
+ using type = std::tuple<std::decay_t<decltype(str)>,const char*>;
+ explicit constexpr RAW_STATUS(const char* a) : _entry(entry(str, a)) {};
+ type _entry;
+};
} // namespace _PowerSupplyUnderVoltageFault
struct PowerSupplyUnderVoltageFault
{
static constexpr auto L = level::ERR;
- using metadata_types = std::tuple<>;
+ using RAW_STATUS = _PowerSupplyUnderVoltageFault::RAW_STATUS;
+ using metadata_types = std::tuple<RAW_STATUS>;
};
diff --git a/pmbus.hpp b/pmbus.hpp
index bbe32e4..9254fe7 100644
--- a/pmbus.hpp
+++ b/pmbus.hpp
@@ -11,7 +11,9 @@
namespace fs = std::experimental::filesystem;
+// The file name Linux uses to capture the STATUS_WORD from pmbus.
constexpr auto STATUS_WORD = "status0";
+
// The file name Linux uses to capture the VIN_UV_FAULT bit from the STATUS_WORD
constexpr auto VIN_UV_FAULT = "in1_alarm";
diff --git a/power-supply/main.cpp b/power-supply/main.cpp
index e36bd24..af6bb9a 100644
--- a/power-supply/main.cpp
+++ b/power-supply/main.cpp
@@ -82,16 +82,12 @@
//handle both sd_events (for the timers) and dbus signals.
bus.attach_event(eventPtr.get(), SD_EVENT_PRIORITY_NORMAL);
- // TODO: Use inventory path to subscribe to signal change for power supply presence.
-
//Attach the event object to the bus object so we can
//handle both sd_events (for the timers) and dbus signals.
bus.attach_event(eventPtr.get(), SD_EVENT_PRIORITY_NORMAL);
// TODO: Get power state on startup.
- // TODO: Get presence state on startup and subscribe to presence changes.
- // TODO - set to vinUVFault to false on presence change & start of poweron
- // TODO - set readFailLogged to false on presence change and start of poweron
+
auto pollInterval = std::chrono::milliseconds(1000);
DeviceMonitor mainloop(std::move(psuDevice), eventPtr, pollInterval);
mainloop.run();
diff --git a/power-supply/power_supply.cpp b/power-supply/power_supply.cpp
index 8dd4c3e..f70b79d 100644
--- a/power-supply/power_supply.cpp
+++ b/power-supply/power_supply.cpp
@@ -19,6 +19,7 @@
#include <xyz/openbmc_project/Control/Device/error.hpp>
#include <xyz/openbmc_project/Power/Fault/error.hpp>
#include "elog-errors.hpp"
+#include "names_values.hpp"
#include "power_supply.hpp"
#include "pmbus.hpp"
#include "utility.hpp"
@@ -35,6 +36,29 @@
namespace psu
{
+constexpr auto INVENTORY_OBJ_PATH = "/xyz/openbmc_project/inventory";
+constexpr auto INVENTORY_INTERFACE = "xyz.openbmc_project.Inventory.Item";
+constexpr auto PRESENT_PROP = "Present";
+
+PowerSupply::PowerSupply(const std::string& name, size_t inst,
+ const std::string& objpath, const std::string& invpath,
+ sdbusplus::bus::bus& bus)
+ : Device(name, inst), monitorPath(objpath), inventoryPath(invpath),
+ bus(bus), pmbusIntf(objpath)
+{
+ updatePresence();
+
+ using namespace sdbusplus::bus;
+ auto present_obj_path = INVENTORY_OBJ_PATH + inventoryPath;
+ presentMatch = std::make_unique<match_t>(bus,
+ match::rules::propertiesChanged(
+ present_obj_path,
+ INVENTORY_INTERFACE),
+ [this](auto& msg)
+ {
+ this->inventoryChanged(msg);
+ });
+}
void PowerSupply::analyze()
{
@@ -42,29 +66,45 @@
try
{
- auto curUVFault = pmbusIntf.readBit(VIN_UV_FAULT, Type::Hwmon);
- //TODO: 3 consecutive reads should be performed.
- // If 3 consecutive reads are seen, log the fault.
- // Driver gives cached value, read once a second.
- // increment for fault on, decrement for fault off, to deglitch.
- // If count reaches 3, we have fault. If count reaches 0, fault is
- // cleared.
-
- //TODO: INPUT FAULT or WARNING bit to check from STATUS_WORD
- // pmbus-core update to read high byte of STATUS_WORD?
-
- if ((curUVFault != vinUVFault) || inputFault)
+ if (present)
{
- if (curUVFault)
+ auto curUVFault = pmbusIntf.readBit(VIN_UV_FAULT, Type::Hwmon);
+ //TODO: 3 consecutive reads should be performed.
+ // If 3 consecutive reads are seen, log the fault.
+ // Driver gives cached value, read once a second.
+ // increment for fault on, decrement for fault off, to deglitch.
+ // If count reaches 3, we have fault. If count reaches 0, fault is
+ // cleared.
+
+ //TODO: INPUT FAULT or WARNING bit to check from STATUS_WORD
+ // pmbus-core update to read high byte of STATUS_WORD?
+
+ if ((curUVFault != vinUVFault) || inputFault)
{
- //FIXME - metadata
- report<PowerSupplyUnderVoltageFault>();
- vinUVFault = true;
- }
- else
- {
- log<level::INFO>("VIN_UV_FAULT cleared");
- vinUVFault = false;
+
+ if (curUVFault)
+ {
+ std::uint16_t statusWord = 0;
+ statusWord = pmbusIntf.read(STATUS_WORD, Type::Debug);
+
+ util::NamesValues nv;
+ nv.add("STATUS_WORD", statusWord);
+
+ using metadata = xyz::openbmc_project::Power::Fault::
+ PowerSupplyUnderVoltageFault;
+
+ report<PowerSupplyUnderVoltageFault>(
+ metadata::RAW_STATUS(nv.get().c_str()));
+
+ vinUVFault = true;
+ }
+ else
+ {
+ log<level::INFO>("VIN_UV_FAULT cleared",
+ entry("POWERSUPPLY=%s",
+ inventoryPath.c_str()));
+ vinUVFault = false;
+ }
}
}
}
@@ -82,9 +122,40 @@
return;
}
+void PowerSupply::inventoryChanged(sdbusplus::message::message& msg)
+{
+ std::string msgSensor;
+ std::map<std::string, sdbusplus::message::variant<uint32_t, bool>> msgData;
+ msg.read(msgSensor, msgData);
+
+ // Check if it was the Present property that changed.
+ auto valPropMap = msgData.find(PRESENT_PROP);
+ if (valPropMap != msgData.end())
+ {
+ present = sdbusplus::message::variant_ns::get<bool>(valPropMap->second);
+
+ if (present)
+ {
+ readFailLogged = false;
+ vinUVFault = false;
+ }
+ }
+
+ return;
+}
+
+void PowerSupply::updatePresence()
+{
+ // Use getProperty utility function to get presence status.
+ std::string path = INVENTORY_OBJ_PATH + inventoryPath;
+ std::string service = "xyz.openbmc_project.Inventory.Manager";
+ util::getProperty(INVENTORY_INTERFACE, PRESENT_PROP, path,
+ service, bus, this->present);
+}
+
void PowerSupply::clearFaults()
{
- //TODO - Clear faults at pre-poweron.
+ //TODO - Clear faults at pre-poweron. openbmc/openbmc#1736
return;
}
diff --git a/power-supply/power_supply.hpp b/power-supply/power_supply.hpp
index 43489d2..496218f 100644
--- a/power-supply/power_supply.hpp
+++ b/power-supply/power_supply.hpp
@@ -1,4 +1,5 @@
#pragma once
+#include <sdbusplus/bus/match.hpp>
#include "device.hpp"
#include "pmbus.hpp"
@@ -9,6 +10,8 @@
namespace psu
{
+namespace sdbusRule = sdbusplus::bus::match::rules;
+
/**
* @class PowerSupply
* Represents a PMBus power supply device.
@@ -35,11 +38,7 @@
PowerSupply(const std::string& name, size_t inst,
const std::string& objpath,
const std::string& invpath,
- sdbusplus::bus::bus& bus)
- : Device(name, inst), monitorPath(objpath), inventoryPath(invpath),
- bus(bus), pmbusIntf(objpath)
- {
- }
+ sdbusplus::bus::bus& bus);
/**
* Power supply specific function to analyze for faults/errors.
@@ -84,6 +83,14 @@
witherspoon::pmbus::PMBus pmbusIntf;
/**
+ * @brief True if the power supply is present.
+ */
+ bool present = false;
+
+ /** @brief Used to subscribe to dbus pcap propety changes **/
+ std::unique_ptr<sdbusplus::bus::match_t> presentMatch;
+
+ /**
* @brief Has a PMBus read failure already been logged?
*/
bool readFailLogged = false;
@@ -103,6 +110,24 @@
* STATUS_WORD command response.
*/
bool inputFault = false;
+
+ /** @brief Callback for inventory property changes
+ *
+ * Process change of Present property for power supply.
+ *
+ * @param[in] msg - Data associated with Present change signal
+ *
+ */
+ void inventoryChanged(sdbusplus::message::message& msg);
+
+ /**
+ * Updates the presence status by querying D-Bus
+ *
+ * The D-Bus inventory properties for this power supply will be read to
+ * determine if the power supply is present or not and update this
+ * objects present member variable to reflect current status.
+ */
+ void updatePresence();
};
}
diff --git a/xyz/openbmc_project/Power/Fault.metadata.yaml b/xyz/openbmc_project/Power/Fault.metadata.yaml
index 0274523..5f02864 100644
--- a/xyz/openbmc_project/Power/Fault.metadata.yaml
+++ b/xyz/openbmc_project/Power/Fault.metadata.yaml
@@ -1,5 +1,8 @@
- name: PowerSupplyUnderVoltageFault
level: ERR
+ meta:
+ - str: "RAW_STATUS=%s"
+ type: string
- name: Shutdown
level: ERR