blob: c969734ed74a89fd631fd1a0922ef248e7bbe0f4 [file] [log] [blame]
Brandon Wyman24e422f2017-07-25 19:40:14 -05001#pragma once
Brandon Wyman10295542017-08-09 18:20:44 -05002#include <sdbusplus/bus/match.hpp>
Brandon Wyman1db9a9e2017-07-26 18:50:22 -05003#include "device.hpp"
Brandon Wyman442035f2017-08-08 15:58:45 -05004#include "pmbus.hpp"
Brandon Wyman431fbe42017-08-18 16:22:09 -05005#include "timer.hpp"
Brandon Wymana1e96342017-09-25 16:47:44 -05006#include "names_values.hpp"
Brandon Wyman24e422f2017-07-25 19:40:14 -05007
Brandon Wyman1db9a9e2017-07-26 18:50:22 -05008namespace witherspoon
Brandon Wyman24e422f2017-07-25 19:40:14 -05009{
10namespace power
11{
12namespace psu
13{
14
Brandon Wyman10295542017-08-09 18:20:44 -050015namespace sdbusRule = sdbusplus::bus::match::rules;
16
Brandon Wyman593d24f2017-10-13 18:15:23 -050017constexpr auto FAULT_COUNT = 3;
18
Brandon Wyman24e422f2017-07-25 19:40:14 -050019/**
20 * @class PowerSupply
Brandon Wyman1db9a9e2017-07-26 18:50:22 -050021 * Represents a PMBus power supply device.
Brandon Wyman24e422f2017-07-25 19:40:14 -050022 */
Brandon Wyman1db9a9e2017-07-26 18:50:22 -050023class PowerSupply : public Device
Brandon Wyman24e422f2017-07-25 19:40:14 -050024{
25 public:
26 PowerSupply() = delete;
27 PowerSupply(const PowerSupply&) = delete;
Brandon Wyman24e422f2017-07-25 19:40:14 -050028 PowerSupply(PowerSupply&&) = default;
Brandon Wyman1db9a9e2017-07-26 18:50:22 -050029 PowerSupply& operator=(const PowerSupply&) = default;
Brandon Wyman24e422f2017-07-25 19:40:14 -050030 PowerSupply& operator=(PowerSupply&&) = default;
31 ~PowerSupply() = default;
32
Brandon Wyman1db9a9e2017-07-26 18:50:22 -050033 /**
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
Brandon Wyman442035f2017-08-08 15:58:45 -050040 * @param[in] bus - D-Bus bus object
Brandon Wyman431fbe42017-08-18 16:22:09 -050041 * @param[in] e - event object
42 * @param[in] t - time to allow power supply to assert PG#
Brandon Wyman590fc282017-11-01 18:22:25 -050043 * @param[in] p - time to allow power supply presence state to
44 * settle/deglitch and allow for application of power
45 * prior to fault checking
Brandon Wyman1db9a9e2017-07-26 18:50:22 -050046 */
47 PowerSupply(const std::string& name, size_t inst,
Brandon Wyman442035f2017-08-08 15:58:45 -050048 const std::string& objpath,
49 const std::string& invpath,
Brandon Wyman431fbe42017-08-18 16:22:09 -050050 sdbusplus::bus::bus& bus,
51 event::Event& e,
Brandon Wyman590fc282017-11-01 18:22:25 -050052 std::chrono::seconds& t,
53 std::chrono::seconds& p);
Brandon Wyman1db9a9e2017-07-26 18:50:22 -050054
55 /**
56 * Power supply specific function to analyze for faults/errors.
57 *
58 * Various PMBus status bits will be checked for fault conditions.
59 * If a certain fault bits are on, the appropriate error will be
60 * committed.
61 */
62 void analyze() override;
63
64 /**
65 * Write PMBus CLEAR_FAULTS
66 *
67 * This function will be called in various situations in order to clear
68 * any fault status bits that may have been set, in order to start over
69 * with a clean state. Presence changes and power state changes will
70 * want to clear any faults logged.
71 */
72 void clearFaults() override;
73
Brandon Wyman43ce2082017-11-30 17:24:01 -060074 /**
75 * Mark error for specified callout and message as resolved.
76 *
77 * @param[in] callout - The callout to be resolved (inventory path)
78 * @parma[in] message - The message for the fault to be resolved
79 */
80 void resolveError(const std::string& callout,
81 const std::string& message);
82
Brandon Wyman1db9a9e2017-07-26 18:50:22 -050083 private:
84 /**
85 * The path to use for reading various PMBus bits/words.
86 */
87 std::string monitorPath;
88
89 /**
Brandon Wyman442035f2017-08-08 15:58:45 -050090 * @brief Pointer to the PMBus interface
91 *
92 * Used to read out of or write to the /sysfs tree(s) containing files
93 * that a device driver monitors the PMBus interface to the power
94 * supplies.
95 */
96 witherspoon::pmbus::PMBus pmbusIntf;
97
98 /**
Brandon Wyman431fbe42017-08-18 16:22:09 -050099 * @brief D-Bus path to use for this power supply's inventory status.
Brandon Wyman10295542017-08-09 18:20:44 -0500100 */
Brandon Wyman431fbe42017-08-18 16:22:09 -0500101 std::string inventoryPath;
102
103 /** @brief Connection for sdbusplus bus */
104 sdbusplus::bus::bus& bus;
105
106 /** @brief True if the power supply is present. */
Brandon Wyman10295542017-08-09 18:20:44 -0500107 bool present = false;
108
Brandon Wyman875b3632017-09-13 18:46:03 -0500109 /** @brief Used to subscribe to D-Bus property changes for Present */
Brandon Wyman10295542017-08-09 18:20:44 -0500110 std::unique_ptr<sdbusplus::bus::match_t> presentMatch;
111
Brandon Wyman590fc282017-11-01 18:22:25 -0500112 /** @brief The sd_event structure used by the power on and present
113 * timers. */
114 event::Event& event;
115
116 /**
117 * @brief Interval for setting present to true.
118 *
119 * The amount of time to wait from not present to present change before
120 * updating the internal present indicator. Allows person servicing
121 * the power supply some time to plug in the cable.
122 */
123 std::chrono::seconds presentInterval;
124
125 /**
126 * @brief Timer used to delay setting the internal present state.
127 *
128 * The timer used to do the callback after the present property has
129 * changed.
130 */
131 Timer presentTimer;
132
Brandon Wyman3343e822017-11-03 16:54:11 -0500133 /** @brief True if a fault has already been found and not cleared */
134 bool faultFound = false;
135
Brandon Wyman431fbe42017-08-18 16:22:09 -0500136 /** @brief True if the power is on. */
137 bool powerOn = false;
138
Brandon Wyman593d24f2017-10-13 18:15:23 -0500139 /**
140 * @brief Equal to FAULT_COUNT if power on fault has been
141 * detected.
142 */
143 size_t powerOnFault = 0;
Brandon Wyman764c7972017-08-22 17:05:36 -0500144
Brandon Wyman431fbe42017-08-18 16:22:09 -0500145 /**
146 * @brief Interval to setting powerOn to true.
147 *
148 * The amount of time to wait from power state on to setting the
149 * internal powerOn state to true. The amount of time the power supply
150 * is allowed to delay setting DGood/PG#.
151 */
152 std::chrono::seconds powerOnInterval;
153
154 /**
155 * @brief Timer used to delay setting the internal powerOn state.
156 *
157 * The timer used to do the callback after the power state has been on
158 * long enough.
159 */
160 Timer powerOnTimer;
161
Brandon Wyman875b3632017-09-13 18:46:03 -0500162 /** @brief Used to subscribe to D-Bus power on state changes */
Brandon Wyman431fbe42017-08-18 16:22:09 -0500163 std::unique_ptr<sdbusplus::bus::match_t> powerOnMatch;
164
Brandon Wymane4af9802017-11-13 15:58:33 -0600165 /** @brief Indicates that a read failure has occurred.
166 *
167 * @details This will be incremented each time a read failure is
168 * encountered. If it is incremented to FAULT_COUNT, an error
169 * will be logged.
170 */
171 size_t readFail = 0;
172
Brandon Wyman764c7972017-08-22 17:05:36 -0500173 /** @brief Has a PMBus read failure already been logged? */
Brandon Wyman442035f2017-08-08 15:58:45 -0500174 bool readFailLogged = false;
175
176 /**
Brandon Wymana3c675c2017-11-14 14:54:54 -0600177 * @brief Indicates an input fault or warning if equal to FAULT_COUNT.
Brandon Wyman442035f2017-08-08 15:58:45 -0500178 *
Brandon Wymana3c675c2017-11-14 14:54:54 -0600179 * @details This is the "INPUT FAULT OR WARNING" bit in the high byte,
180 * or the VIN_UV_FAULT bit in the low byte in the STATUS_WORD
181 * command response. If either of those bits are on, this will
182 * be incremented.
Brandon Wyman442035f2017-08-08 15:58:45 -0500183 */
Brandon Wymana3c675c2017-11-14 14:54:54 -0600184 size_t inputFault = 0;
Brandon Wyman10295542017-08-09 18:20:44 -0500185
Brandon Wyman764c7972017-08-22 17:05:36 -0500186 /**
Brandon Wymandd61be42017-11-07 18:38:54 -0600187 * @brief Indicates output over current fault if equal to FAULT_COUNT
Brandon Wymanb165c252017-08-25 18:59:54 -0500188 *
Brandon Wymandd61be42017-11-07 18:38:54 -0600189 * @details This is incremented when the "IOUT_OC_FAULT" bit in the low
190 * byte from the STATUS_WORD command response is on.
Brandon Wymanb165c252017-08-25 18:59:54 -0500191 */
Brandon Wymandd61be42017-11-07 18:38:54 -0600192 size_t outputOCFault = 0;
Brandon Wymanb165c252017-08-25 18:59:54 -0500193
194 /**
Brandon Wyman2ab319b2017-11-08 17:34:59 -0600195 * @brief Indicates output overvoltage fault if equal to FAULT_COUNT.
196 *
197 * @details This is incremented when the "VOUT_OV_FAULT" bit in the
198 * STATUS_WORD command response is on.
Brandon Wymanab05c072017-08-30 18:26:41 -0500199 */
Brandon Wyman2ab319b2017-11-08 17:34:59 -0600200 size_t outputOVFault = 0;
Brandon Wymanab05c072017-08-30 18:26:41 -0500201
202 /**
Brandon Wymanba255532017-11-08 17:44:10 -0600203 * @brief Indicates a fan fault or warning condition was detected if
204 * equal to FAULT_COUNT.
205 *
206 * @details This is incremented when the 'FAN_FAULT' bit in the
207 * STATUS_WORD command response is on.
Brandon Wyman12661f12017-08-31 15:28:21 -0500208 */
Brandon Wymanba255532017-11-08 17:44:10 -0600209 size_t fanFault = 0;
Brandon Wyman12661f12017-08-31 15:28:21 -0500210
211 /**
Brandon Wyman50044ea2017-11-08 17:58:56 -0600212 * @brief Indicates a temperature fault or warn condition was detected
213 * if equal to FAULT_COUNT.
214 *
215 * @details This is incremented when the 'TEMPERATURE_FAULT_WARN' bit
216 * in the STATUS_WORD command response is on, or if the
217 * 'OT_FAULT' bit in the STATUS_TEMPERATURE command response
218 * is on.
Brandon Wyman875b3632017-09-13 18:46:03 -0500219 */
Brandon Wyman50044ea2017-11-08 17:58:56 -0600220 size_t temperatureFault = 0;
Brandon Wyman875b3632017-09-13 18:46:03 -0500221
222 /**
Brandon Wyman764c7972017-08-22 17:05:36 -0500223 * @brief Callback for inventory property changes
Brandon Wyman10295542017-08-09 18:20:44 -0500224 *
225 * Process change of Present property for power supply.
226 *
227 * @param[in] msg - Data associated with Present change signal
228 *
229 */
230 void inventoryChanged(sdbusplus::message::message& msg);
231
232 /**
233 * Updates the presence status by querying D-Bus
234 *
235 * The D-Bus inventory properties for this power supply will be read to
236 * determine if the power supply is present or not and update this
237 * objects present member variable to reflect current status.
238 */
239 void updatePresence();
Brandon Wyman431fbe42017-08-18 16:22:09 -0500240
241 /**
242 * @brief Updates the poweredOn status by querying D-Bus
243 *
Brandon Wyman875b3632017-09-13 18:46:03 -0500244 * The D-Bus property for the system power state will be read to
Brandon Wyman431fbe42017-08-18 16:22:09 -0500245 * determine if the system is powered on or not.
246 */
247 void updatePowerState();
248
Brandon Wyman764c7972017-08-22 17:05:36 -0500249 /**
250 * @brief Callback for power state property changes
251 *
Brandon Wyman431fbe42017-08-18 16:22:09 -0500252 * Process changes to the powered on stat property for the system.
253 *
254 * @param[in] msg - Data associated with the power state signal
255 */
256 void powerStateChanged(sdbusplus::message::message& msg);
257
Brandon Wyman603cc002017-08-28 18:17:58 -0500258 /**
Brandon Wymana1e96342017-09-25 16:47:44 -0500259 * @brief Wrapper for PMBus::read() and adding metadata
260 *
261 * @param[out] nv - NamesValues instance to store cmd string and value
262 * @param[in] cmd - String for the command to read data from.
263 * @param[in] type - The type of file to read the command from.
264 */
265 void captureCmd(util::NamesValues& nv, const std::string& cmd,
266 witherspoon::pmbus::Type type);
267
268 /**
Brandon Wyman603cc002017-08-28 18:17:58 -0500269 * @brief Checks for input voltage faults and logs error if needed.
270 *
271 * Check for voltage input under voltage fault (VIN_UV_FAULT) and/or
272 * input fault or warning (INPUT_FAULT), and logs appropriate error(s).
273 *
274 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs
275 */
276 void checkInputFault(const uint16_t statusWord);
277
278 /**
279 * @brief Checks for power good negated or unit is off in wrong state
280 *
281 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs
282 */
283 void checkPGOrUnitOffFault(const uint16_t statusWord);
284
285 /**
286 * @brief Checks for output current over current fault.
287 *
288 * IOUT_OC_FAULT is checked, if on, appropriate error is logged.
289 *
290 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs
291 */
292 void checkCurrentOutOverCurrentFault(const uint16_t statusWord);
293
Brandon Wymanab05c072017-08-30 18:26:41 -0500294 /**
295 * @brief Checks for output overvoltage fault.
296 *
297 * VOUT_OV_FAULT is checked, if on, appropriate error is logged.
298 *
299 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs
300 */
301 void checkOutputOvervoltageFault(const uint16_t statusWord);
302
Brandon Wyman12661f12017-08-31 15:28:21 -0500303 /**
304 * @brief Checks for a fan fault or warning condition.
305 *
306 * The high byte of STATUS_WORD is checked to see if the "FAN FAULT OR
307 * WARNING" bit is turned on. If it is on, log an error.
308 *
309 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs
310 */
311 void checkFanFault(const uint16_t statusWord);
312
Brandon Wyman875b3632017-09-13 18:46:03 -0500313 /**
314 * @brief Checks for a temperature fault or warning condition.
315 *
316 * The low byte of STATUS_WORD is checked to see if the "TEMPERATURE
317 * FAULT OR WARNING" bit is turned on. If it is on, log an error,
318 * call out the power supply indicating the fault/warning condition.
319 *
320 * @parma[in] statusWord - 2 byte STATUS_WORD value read from sysfs
321 */
322 void checkTemperatureFault(const uint16_t statusWord);
323
Brandon Wyman24e422f2017-07-25 19:40:14 -0500324};
325
326}
327}
328}