1 #pragma once 2 #include <sdbusplus/bus/match.hpp> 3 #include "device.hpp" 4 #include "pmbus.hpp" 5 #include "timer.hpp" 6 #include "names_values.hpp" 7 8 namespace witherspoon 9 { 10 namespace power 11 { 12 namespace psu 13 { 14 15 namespace sdbusRule = sdbusplus::bus::match::rules; 16 17 constexpr auto FAULT_COUNT = 3; 18 19 /** 20 * @class PowerSupply 21 * Represents a PMBus power supply device. 22 */ 23 class PowerSupply : public Device 24 { 25 public: 26 PowerSupply() = delete; 27 PowerSupply(const PowerSupply&) = delete; 28 PowerSupply(PowerSupply&&) = default; 29 PowerSupply& operator=(const PowerSupply&) = default; 30 PowerSupply& operator=(PowerSupply&&) = default; 31 ~PowerSupply() = default; 32 33 /** 34 * Constructor 35 * 36 * @param[in] name - the device name 37 * @param[in] inst - the device instance 38 * @param[in] objpath - the path to monitor 39 * @param[in] invpath - the inventory path to use 40 * @param[in] bus - D-Bus bus object 41 * @param[in] e - event object 42 * @param[in] t - time to allow power supply to assert PG# 43 */ 44 PowerSupply(const std::string& name, size_t inst, 45 const std::string& objpath, 46 const std::string& invpath, 47 sdbusplus::bus::bus& bus, 48 event::Event& e, 49 std::chrono::seconds& t); 50 51 /** 52 * Power supply specific function to analyze for faults/errors. 53 * 54 * Various PMBus status bits will be checked for fault conditions. 55 * If a certain fault bits are on, the appropriate error will be 56 * committed. 57 */ 58 void analyze() override; 59 60 /** 61 * Write PMBus CLEAR_FAULTS 62 * 63 * This function will be called in various situations in order to clear 64 * any fault status bits that may have been set, in order to start over 65 * with a clean state. Presence changes and power state changes will 66 * want to clear any faults logged. 67 */ 68 void clearFaults() override; 69 70 private: 71 /** 72 * The path to use for reading various PMBus bits/words. 73 */ 74 std::string monitorPath; 75 76 /** 77 * @brief Pointer to the PMBus interface 78 * 79 * Used to read out of or write to the /sysfs tree(s) containing files 80 * that a device driver monitors the PMBus interface to the power 81 * supplies. 82 */ 83 witherspoon::pmbus::PMBus pmbusIntf; 84 85 /** 86 * @brief D-Bus path to use for this power supply's inventory status. 87 */ 88 std::string inventoryPath; 89 90 /** @brief Connection for sdbusplus bus */ 91 sdbusplus::bus::bus& bus; 92 93 /** @brief True if the power supply is present. */ 94 bool present = false; 95 96 /** @brief Used to subscribe to D-Bus property changes for Present */ 97 std::unique_ptr<sdbusplus::bus::match_t> presentMatch; 98 99 /** @brief True if the power is on. */ 100 bool powerOn = false; 101 102 /** 103 * @brief Equal to FAULT_COUNT if power on fault has been 104 * detected. 105 */ 106 size_t powerOnFault = 0; 107 108 /** @brief The sd_event structure used by the power on timer. */ 109 event::Event& event; 110 111 /** 112 * @brief Interval to setting powerOn to true. 113 * 114 * The amount of time to wait from power state on to setting the 115 * internal powerOn state to true. The amount of time the power supply 116 * is allowed to delay setting DGood/PG#. 117 */ 118 std::chrono::seconds powerOnInterval; 119 120 /** 121 * @brief Timer used to delay setting the internal powerOn state. 122 * 123 * The timer used to do the callback after the power state has been on 124 * long enough. 125 */ 126 Timer powerOnTimer; 127 128 /** @brief Used to subscribe to D-Bus power on state changes */ 129 std::unique_ptr<sdbusplus::bus::match_t> powerOnMatch; 130 131 /** @brief Has a PMBus read failure already been logged? */ 132 bool readFailLogged = false; 133 134 /** 135 * @brief Set to true when an input fault or warning is detected 136 * 137 * This is the "INPUT FAULT OR WARNING" bit in the high byte from the 138 * STATUS_WORD command response. 139 */ 140 bool inputFault = false; 141 142 /** 143 * @brief Set to true when an output over current fault is detected 144 * 145 * This is the "IOUT_OC_FAULT" bit in the low byte from the STATUS_WORD 146 * command response. 147 */ 148 bool outputOCFault = false; 149 150 /** 151 * @brief Set to true when the output overvoltage fault is detected 152 */ 153 bool outputOVFault = false; 154 155 /** 156 * @brief Set to true when a fan fault or warning condition is detected 157 */ 158 bool fanFault = false; 159 160 /** 161 * @brief Set to true during a temperature fault or warn condition. 162 */ 163 bool temperatureFault = false; 164 165 /** 166 * @brief Callback for inventory property changes 167 * 168 * Process change of Present property for power supply. 169 * 170 * @param[in] msg - Data associated with Present change signal 171 * 172 */ 173 void inventoryChanged(sdbusplus::message::message& msg); 174 175 /** 176 * Updates the presence status by querying D-Bus 177 * 178 * The D-Bus inventory properties for this power supply will be read to 179 * determine if the power supply is present or not and update this 180 * objects present member variable to reflect current status. 181 */ 182 void updatePresence(); 183 184 /** 185 * @brief Updates the poweredOn status by querying D-Bus 186 * 187 * The D-Bus property for the system power state will be read to 188 * determine if the system is powered on or not. 189 */ 190 void updatePowerState(); 191 192 /** 193 * @brief Callback for power state property changes 194 * 195 * Process changes to the powered on stat property for the system. 196 * 197 * @param[in] msg - Data associated with the power state signal 198 */ 199 void powerStateChanged(sdbusplus::message::message& msg); 200 201 /** 202 * @brief Wrapper for PMBus::read() and adding metadata 203 * 204 * @param[out] nv - NamesValues instance to store cmd string and value 205 * @param[in] cmd - String for the command to read data from. 206 * @param[in] type - The type of file to read the command from. 207 */ 208 void captureCmd(util::NamesValues& nv, const std::string& cmd, 209 witherspoon::pmbus::Type type); 210 211 /** 212 * @brief Checks for input voltage faults and logs error if needed. 213 * 214 * Check for voltage input under voltage fault (VIN_UV_FAULT) and/or 215 * input fault or warning (INPUT_FAULT), and logs appropriate error(s). 216 * 217 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs 218 */ 219 void checkInputFault(const uint16_t statusWord); 220 221 /** 222 * @brief Checks for power good negated or unit is off in wrong state 223 * 224 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs 225 */ 226 void checkPGOrUnitOffFault(const uint16_t statusWord); 227 228 /** 229 * @brief Checks for output current over current fault. 230 * 231 * IOUT_OC_FAULT is checked, if on, appropriate error is logged. 232 * 233 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs 234 */ 235 void checkCurrentOutOverCurrentFault(const uint16_t statusWord); 236 237 /** 238 * @brief Checks for output overvoltage fault. 239 * 240 * VOUT_OV_FAULT is checked, if on, appropriate error is logged. 241 * 242 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs 243 */ 244 void checkOutputOvervoltageFault(const uint16_t statusWord); 245 246 /** 247 * @brief Checks for a fan fault or warning condition. 248 * 249 * The high byte of STATUS_WORD is checked to see if the "FAN FAULT OR 250 * WARNING" bit is turned on. If it is on, log an error. 251 * 252 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs 253 */ 254 void checkFanFault(const uint16_t statusWord); 255 256 /** 257 * @brief Checks for a temperature fault or warning condition. 258 * 259 * The low byte of STATUS_WORD is checked to see if the "TEMPERATURE 260 * FAULT OR WARNING" bit is turned on. If it is on, log an error, 261 * call out the power supply indicating the fault/warning condition. 262 * 263 * @parma[in] statusWord - 2 byte STATUS_WORD value read from sysfs 264 */ 265 void checkTemperatureFault(const uint16_t statusWord); 266 267 }; 268 269 } 270 } 271 } 272