Add in support for power supply fan fault
If the FAN FAULT OR WARN bit in the STATUS_WORD turns on, log an error
calling out the power supply, include the contents from STATUS_WORD,
MFR_SPECIFIC, STATUS_TEMPERATURE, and STATUS_FANS_1_2 in the metadata.
Change-Id: Ic9261cf08517344f594a4616a91dbec47bb07d7e
Signed-off-by: Brandon Wyman <bjwyman@gmail.com>
diff --git a/elog-errors.hpp b/elog-errors.hpp
index 892ce20..3f3e073 100644
--- a/elog-errors.hpp
+++ b/elog-errors.hpp
@@ -201,6 +201,26 @@
{
namespace Error
{
+ struct PowerSupplyFanFault;
+} // namespace Error
+} // namespace Fault
+} // namespace Power
+} // namespace openbmc_project
+} // namespace xyz
+} // namespace sdbusplus
+
+namespace sdbusplus
+{
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Power
+{
+namespace Fault
+{
+namespace Error
+{
struct PowerSupplyInputFault;
} // namespace Error
} // namespace Fault
@@ -859,6 +879,54 @@
{
namespace Fault
{
+namespace _PowerSupplyFanFault
+{
+
+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 _PowerSupplyFanFault
+
+struct PowerSupplyFanFault
+{
+ static constexpr auto L = level::ERR;
+ using RAW_STATUS = _PowerSupplyFanFault::RAW_STATUS;
+ using CALLOUT_INVENTORY_PATH = xyz::openbmc_project::Common::Callout::Inventory::CALLOUT_INVENTORY_PATH;
+ using metadata_types = std::tuple<RAW_STATUS, CALLOUT_INVENTORY_PATH>;
+
+};
+
+} // namespace Fault
+} // namespace Power
+} // namespace openbmc_project
+} // namespace xyz
+
+
+namespace details
+{
+
+template <>
+struct map_exception_type<sdbusplus::xyz::openbmc_project::Power::Fault::Error::PowerSupplyFanFault>
+{
+ using type = xyz::openbmc_project::Power::Fault::PowerSupplyFanFault;
+};
+
+}
+
+namespace xyz
+{
+namespace openbmc_project
+{
+namespace Power
+{
+namespace Fault
+{
namespace _Shutdown
{
diff --git a/pmbus.hpp b/pmbus.hpp
index 23121b9..a2572f7 100644
--- a/pmbus.hpp
+++ b/pmbus.hpp
@@ -29,6 +29,13 @@
// Manufacturing specific status bits
constexpr auto STATUS_MFR = "status0_mfr";
+// Reports on the status of any fans installed in position 1 and 2.
+constexpr auto STATUS_FANS_1_2 = "status0_fans12";
+
+// Reports on temperature faults or warnings. Overtemperature fault,
+// overtemperature warning, undertemperature warning, undertemperature fault.
+constexpr auto STATUS_TEMPERATURE = "status0_temp";
+
namespace status_word
{
constexpr auto VOUT_FAULT = 0x8000;
@@ -42,6 +49,10 @@
// The bit mask representing the POWER_GOOD Negated bit of the STATUS_WORD.
constexpr auto POWER_GOOD_NEGATED = 0x0800;
+// The bit mask representing the FAN FAULT or WARNING bit of the STATUS_WORD.
+// Bit 2 of the high byte of STATUS_WORD.
+constexpr auto FAN_FAULT = 0x0400;
+
// The bit mask representing the UNITI_IS_OFF bit of the STATUS_WORD.
constexpr auto UNIT_IS_OFF = 0x0040;
diff --git a/power-supply/power_supply.cpp b/power-supply/power_supply.cpp
index b3d556c..d9e870c 100644
--- a/power-supply/power_supply.cpp
+++ b/power-supply/power_supply.cpp
@@ -109,6 +109,7 @@
checkPGOrUnitOffFault(statusWord);
checkCurrentOutOverCurrentFault(statusWord);
checkOutputOvervoltageFault(statusWord);
+ checkFanFault(statusWord);
}
}
}
@@ -143,6 +144,7 @@
inputFault = false;
outputOCFault = false;
outputOVFault = false;
+ fanFault = false;
}
}
@@ -194,6 +196,7 @@
powerOnFault = false;
outputOCFault = false;
outputOVFault = false;
+ fanFault = false;
powerOnTimer.start(powerOnInterval, Timer::TimerType::oneshot);
}
else
@@ -418,6 +421,39 @@
}
}
+void PowerSupply::checkFanFault(const uint16_t statusWord)
+{
+ using namespace witherspoon::pmbus;
+
+ std::uint8_t statusMFR = 0;
+ std::uint8_t statusTemperature = 0;
+ std::uint8_t statusFans12 = 0;
+
+ // Check for an output overcurrent fault.
+ if ((statusWord & status_word::FAN_FAULT) &&
+ !fanFault)
+ {
+ statusMFR = pmbusIntf.read(STATUS_MFR, Type::Debug);
+ statusTemperature = pmbusIntf.read(STATUS_TEMPERATURE, Type::Debug);
+ statusFans12 = pmbusIntf.read(STATUS_FANS_1_2, Type::Debug);
+
+ util::NamesValues nv;
+ nv.add("STATUS_WORD", statusWord);
+ nv.add("MFR_SPECIFIC", statusMFR);
+ nv.add("STATUS_TEMPERATURE", statusTemperature);
+ nv.add("STATUS_FANS_1_2", statusFans12);
+
+ using metadata = xyz::openbmc_project::Power::Fault::
+ PowerSupplyFanFault;
+
+ report<PowerSupplyFanFault>(
+ metadata::RAW_STATUS(nv.get().c_str()),
+ metadata::CALLOUT_INVENTORY_PATH(inventoryPath.c_str()));
+
+ fanFault = true;
+ }
+}
+
void PowerSupply::clearFaults()
{
//TODO - Clear faults at pre-poweron. openbmc/openbmc#1736
diff --git a/power-supply/power_supply.hpp b/power-supply/power_supply.hpp
index 98c4c0b..a3cea2d 100644
--- a/power-supply/power_supply.hpp
+++ b/power-supply/power_supply.hpp
@@ -155,6 +155,11 @@
bool outputOVFault = false;
/**
+ * @brief Set to true when a fan fault or warning condition is detected
+ */
+ bool fanFault = false;
+
+ /**
* @brief Callback for inventory property changes
*
* Process change of Present property for power supply.
@@ -225,6 +230,16 @@
*/
void checkOutputOvervoltageFault(const uint16_t statusWord);
+ /**
+ * @brief Checks for a fan fault or warning condition.
+ *
+ * The high byte of STATUS_WORD is checked to see if the "FAN FAULT OR
+ * WARNING" bit is turned on. If it is on, log an error.
+ *
+ * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs
+ */
+ void checkFanFault(const uint16_t statusWord);
+
};
}
diff --git a/xyz/openbmc_project/Power/Fault.errors.yaml b/xyz/openbmc_project/Power/Fault.errors.yaml
index b08bfa1..9f2e770 100644
--- a/xyz/openbmc_project/Power/Fault.errors.yaml
+++ b/xyz/openbmc_project/Power/Fault.errors.yaml
@@ -8,6 +8,8 @@
description: The power supply detected an output overcurrent fault condition.
- name: PowerSupplyOutputOvervoltage
description: The power supply detected an output overvoltage fault condition.
+- name: PowerSupplyFanFault
+ description: The power supply detected bad fan operation.
- name: Shutdown
description: A power off was issued because a power fault was detected
diff --git a/xyz/openbmc_project/Power/Fault.metadata.yaml b/xyz/openbmc_project/Power/Fault.metadata.yaml
index ab7eccb..b92da35 100644
--- a/xyz/openbmc_project/Power/Fault.metadata.yaml
+++ b/xyz/openbmc_project/Power/Fault.metadata.yaml
@@ -29,6 +29,13 @@
type: string
inherits:
- xyz.openbmc_project.Common.Callout.Inventory
+- name: PowerSupplyFanFault
+ level: ERR
+ meta:
+ - str: "RAW_STATUS=%s"
+ type: string
+ inherits:
+ - xyz.openbmc_project.Common.Callout.Inventory
- name: Shutdown
level: ERR