blob: a56e2e24542678b40754d2ab55cf2e8dff01e282 [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>
William A. Kennington III1a0c9172018-10-18 17:57:49 -07003#include <sdeventplus/clock.hpp>
William A. Kennington IIIe5a8b472018-10-18 00:40:04 -07004#include <sdeventplus/event.hpp>
William A. Kennington III1a0c9172018-10-18 17:57:49 -07005#include <sdeventplus/utility/timer.hpp>
Matt Spinler82384142018-01-18 14:15:03 -06006#include "average.hpp"
Brandon Wyman1db9a9e2017-07-26 18:50:22 -05007#include "device.hpp"
Matt Spinler82384142018-01-18 14:15:03 -06008#include "maximum.hpp"
Brandon Wymana1e96342017-09-25 16:47:44 -05009#include "names_values.hpp"
Matt Spinler82384142018-01-18 14:15:03 -060010#include "pmbus.hpp"
11#include "record_manager.hpp"
Brandon Wyman24e422f2017-07-25 19:40:14 -050012
Brandon Wyman1db9a9e2017-07-26 18:50:22 -050013namespace witherspoon
Brandon Wyman24e422f2017-07-25 19:40:14 -050014{
15namespace power
16{
17namespace psu
18{
19
Brandon Wyman10295542017-08-09 18:20:44 -050020namespace sdbusRule = sdbusplus::bus::match::rules;
21
Brandon Wyman593d24f2017-10-13 18:15:23 -050022constexpr auto FAULT_COUNT = 3;
23
Brandon Wyman24e422f2017-07-25 19:40:14 -050024/**
25 * @class PowerSupply
Brandon Wyman1db9a9e2017-07-26 18:50:22 -050026 * Represents a PMBus power supply device.
Brandon Wyman24e422f2017-07-25 19:40:14 -050027 */
Brandon Wyman1db9a9e2017-07-26 18:50:22 -050028class PowerSupply : public Device
Brandon Wyman24e422f2017-07-25 19:40:14 -050029{
30 public:
31 PowerSupply() = delete;
32 PowerSupply(const PowerSupply&) = delete;
Brandon Wyman24e422f2017-07-25 19:40:14 -050033 PowerSupply(PowerSupply&&) = default;
Brandon Wyman1db9a9e2017-07-26 18:50:22 -050034 PowerSupply& operator=(const PowerSupply&) = default;
Brandon Wyman24e422f2017-07-25 19:40:14 -050035 PowerSupply& operator=(PowerSupply&&) = default;
36 ~PowerSupply() = default;
37
Brandon Wyman1db9a9e2017-07-26 18:50:22 -050038 /**
39 * Constructor
40 *
41 * @param[in] name - the device name
42 * @param[in] inst - the device instance
43 * @param[in] objpath - the path to monitor
44 * @param[in] invpath - the inventory path to use
Brandon Wyman442035f2017-08-08 15:58:45 -050045 * @param[in] bus - D-Bus bus object
Brandon Wyman431fbe42017-08-18 16:22:09 -050046 * @param[in] e - event object
47 * @param[in] t - time to allow power supply to assert PG#
Brandon Wyman590fc282017-11-01 18:22:25 -050048 * @param[in] p - time to allow power supply presence state to
49 * settle/deglitch and allow for application of power
50 * prior to fault checking
Brandon Wyman1db9a9e2017-07-26 18:50:22 -050051 */
52 PowerSupply(const std::string& name, size_t inst,
Brandon Wyman442035f2017-08-08 15:58:45 -050053 const std::string& objpath,
54 const std::string& invpath,
Brandon Wyman431fbe42017-08-18 16:22:09 -050055 sdbusplus::bus::bus& bus,
William A. Kennington IIIe5a8b472018-10-18 00:40:04 -070056 const sdeventplus::Event& e,
Brandon Wyman590fc282017-11-01 18:22:25 -050057 std::chrono::seconds& t,
58 std::chrono::seconds& p);
Brandon Wyman1db9a9e2017-07-26 18:50:22 -050059
60 /**
61 * Power supply specific function to analyze for faults/errors.
62 *
63 * Various PMBus status bits will be checked for fault conditions.
64 * If a certain fault bits are on, the appropriate error will be
65 * committed.
66 */
67 void analyze() override;
68
69 /**
70 * Write PMBus CLEAR_FAULTS
71 *
72 * This function will be called in various situations in order to clear
73 * any fault status bits that may have been set, in order to start over
74 * with a clean state. Presence changes and power state changes will
75 * want to clear any faults logged.
76 */
77 void clearFaults() override;
78
Brandon Wyman43ce2082017-11-30 17:24:01 -060079 /**
80 * Mark error for specified callout and message as resolved.
81 *
82 * @param[in] callout - The callout to be resolved (inventory path)
83 * @parma[in] message - The message for the fault to be resolved
84 */
85 void resolveError(const std::string& callout,
86 const std::string& message);
87
Matt Spinler82384142018-01-18 14:15:03 -060088 /**
89 * Enables making the input power history available on D-Bus
90 *
91 * @param[in] objectPath - the D-Bus object path to use
92 * @param[in] maxRecords - the number of history records to keep
93 * @param[in] syncGPIOPath - The gpiochip device path to use for
94 * sending the sync command
95 * @paramp[in] syncGPIONum - the GPIO number for the sync command
96 */
97 void enableHistory(const std::string& objectPath,
98 size_t numRecords,
99 const std::string& syncGPIOPath,
100 size_t syncGPIONum);
101
Brandon Wyman1db9a9e2017-07-26 18:50:22 -0500102 private:
103 /**
104 * The path to use for reading various PMBus bits/words.
105 */
106 std::string monitorPath;
107
108 /**
Brandon Wyman442035f2017-08-08 15:58:45 -0500109 * @brief Pointer to the PMBus interface
110 *
111 * Used to read out of or write to the /sysfs tree(s) containing files
112 * that a device driver monitors the PMBus interface to the power
113 * supplies.
114 */
115 witherspoon::pmbus::PMBus pmbusIntf;
116
117 /**
Brandon Wyman431fbe42017-08-18 16:22:09 -0500118 * @brief D-Bus path to use for this power supply's inventory status.
Brandon Wyman10295542017-08-09 18:20:44 -0500119 */
Brandon Wyman431fbe42017-08-18 16:22:09 -0500120 std::string inventoryPath;
121
122 /** @brief Connection for sdbusplus bus */
123 sdbusplus::bus::bus& bus;
124
125 /** @brief True if the power supply is present. */
Brandon Wyman10295542017-08-09 18:20:44 -0500126 bool present = false;
127
Brandon Wyman875b3632017-09-13 18:46:03 -0500128 /** @brief Used to subscribe to D-Bus property changes for Present */
Brandon Wyman10295542017-08-09 18:20:44 -0500129 std::unique_ptr<sdbusplus::bus::match_t> presentMatch;
130
Brandon Wyman590fc282017-11-01 18:22:25 -0500131 /**
132 * @brief Interval for setting present to true.
133 *
134 * The amount of time to wait from not present to present change before
135 * updating the internal present indicator. Allows person servicing
136 * the power supply some time to plug in the cable.
137 */
138 std::chrono::seconds presentInterval;
139
140 /**
141 * @brief Timer used to delay setting the internal present state.
142 *
143 * The timer used to do the callback after the present property has
144 * changed.
145 */
William A. Kennington III1a0c9172018-10-18 17:57:49 -0700146 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> presentTimer;
Brandon Wyman590fc282017-11-01 18:22:25 -0500147
Brandon Wyman3343e822017-11-03 16:54:11 -0500148 /** @brief True if a fault has already been found and not cleared */
149 bool faultFound = false;
150
Brandon Wyman431fbe42017-08-18 16:22:09 -0500151 /** @brief True if the power is on. */
152 bool powerOn = false;
153
Brandon Wyman593d24f2017-10-13 18:15:23 -0500154 /**
155 * @brief Equal to FAULT_COUNT if power on fault has been
156 * detected.
157 */
158 size_t powerOnFault = 0;
Brandon Wyman764c7972017-08-22 17:05:36 -0500159
Brandon Wyman431fbe42017-08-18 16:22:09 -0500160 /**
161 * @brief Interval to setting powerOn to true.
162 *
163 * The amount of time to wait from power state on to setting the
164 * internal powerOn state to true. The amount of time the power supply
165 * is allowed to delay setting DGood/PG#.
166 */
167 std::chrono::seconds powerOnInterval;
168
169 /**
170 * @brief Timer used to delay setting the internal powerOn state.
171 *
172 * The timer used to do the callback after the power state has been on
173 * long enough.
174 */
William A. Kennington III1a0c9172018-10-18 17:57:49 -0700175 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> powerOnTimer;
Brandon Wyman431fbe42017-08-18 16:22:09 -0500176
Brandon Wyman875b3632017-09-13 18:46:03 -0500177 /** @brief Used to subscribe to D-Bus power on state changes */
Brandon Wyman431fbe42017-08-18 16:22:09 -0500178 std::unique_ptr<sdbusplus::bus::match_t> powerOnMatch;
179
Brandon Wymane4af9802017-11-13 15:58:33 -0600180 /** @brief Indicates that a read failure has occurred.
181 *
182 * @details This will be incremented each time a read failure is
183 * encountered. If it is incremented to FAULT_COUNT, an error
184 * will be logged.
185 */
186 size_t readFail = 0;
187
Brandon Wyman764c7972017-08-22 17:05:36 -0500188 /** @brief Has a PMBus read failure already been logged? */
Brandon Wyman442035f2017-08-08 15:58:45 -0500189 bool readFailLogged = false;
190
191 /**
Brandon Wymana3c675c2017-11-14 14:54:54 -0600192 * @brief Indicates an input fault or warning if equal to FAULT_COUNT.
Brandon Wyman442035f2017-08-08 15:58:45 -0500193 *
Brandon Wymana3c675c2017-11-14 14:54:54 -0600194 * @details This is the "INPUT FAULT OR WARNING" bit in the high byte,
195 * or the VIN_UV_FAULT bit in the low byte in the STATUS_WORD
196 * command response. If either of those bits are on, this will
197 * be incremented.
Brandon Wyman442035f2017-08-08 15:58:45 -0500198 */
Brandon Wymana3c675c2017-11-14 14:54:54 -0600199 size_t inputFault = 0;
Brandon Wyman10295542017-08-09 18:20:44 -0500200
Brandon Wyman764c7972017-08-22 17:05:36 -0500201 /**
Brandon Wymandd61be42017-11-07 18:38:54 -0600202 * @brief Indicates output over current fault if equal to FAULT_COUNT
Brandon Wymanb165c252017-08-25 18:59:54 -0500203 *
Brandon Wymandd61be42017-11-07 18:38:54 -0600204 * @details This is incremented when the "IOUT_OC_FAULT" bit in the low
205 * byte from the STATUS_WORD command response is on.
Brandon Wymanb165c252017-08-25 18:59:54 -0500206 */
Brandon Wymandd61be42017-11-07 18:38:54 -0600207 size_t outputOCFault = 0;
Brandon Wymanb165c252017-08-25 18:59:54 -0500208
209 /**
Brandon Wyman2ab319b2017-11-08 17:34:59 -0600210 * @brief Indicates output overvoltage fault if equal to FAULT_COUNT.
211 *
212 * @details This is incremented when the "VOUT_OV_FAULT" bit in the
213 * STATUS_WORD command response is on.
Brandon Wymanab05c072017-08-30 18:26:41 -0500214 */
Brandon Wyman2ab319b2017-11-08 17:34:59 -0600215 size_t outputOVFault = 0;
Brandon Wymanab05c072017-08-30 18:26:41 -0500216
217 /**
Brandon Wymanba255532017-11-08 17:44:10 -0600218 * @brief Indicates a fan fault or warning condition was detected if
219 * equal to FAULT_COUNT.
220 *
221 * @details This is incremented when the 'FAN_FAULT' bit in the
222 * STATUS_WORD command response is on.
Brandon Wyman12661f12017-08-31 15:28:21 -0500223 */
Brandon Wymanba255532017-11-08 17:44:10 -0600224 size_t fanFault = 0;
Brandon Wyman12661f12017-08-31 15:28:21 -0500225
226 /**
Brandon Wyman50044ea2017-11-08 17:58:56 -0600227 * @brief Indicates a temperature fault or warn condition was detected
228 * if equal to FAULT_COUNT.
229 *
230 * @details This is incremented when the 'TEMPERATURE_FAULT_WARN' bit
231 * in the STATUS_WORD command response is on, or if the
232 * 'OT_FAULT' bit in the STATUS_TEMPERATURE command response
233 * is on.
Brandon Wyman875b3632017-09-13 18:46:03 -0500234 */
Brandon Wyman50044ea2017-11-08 17:58:56 -0600235 size_t temperatureFault = 0;
Brandon Wyman875b3632017-09-13 18:46:03 -0500236
237 /**
Matt Spinler82384142018-01-18 14:15:03 -0600238 * @brief Class that manages the input power history records.
239 */
240 std::unique_ptr<history::RecordManager> recordManager;
241
242 /**
243 * @brief The D-Bus object for the average input power history
244 */
245 std::unique_ptr<history::Average> average;
246
247 /**
248 * @brief The D-Bus object for the maximum input power history
249 */
250 std::unique_ptr<history::Maximum> maximum;
251
252 /**
253 * @brief The base D-Bus object path to use for the average
254 * and maximum objects.
255 */
256 std::string historyObjectPath;
257
258 /**
259 * @brief The GPIO device path to use for sending the 'sync'
260 * command to the PS.
261 */
262 std::string syncGPIODevPath;
263
264 /**
265 * @brief The GPIO number to use for sending the 'sync'
266 * command to the PS.
267 */
268 size_t syncGPIONumber = 0;
269
270 /**
Brandon Wyman764c7972017-08-22 17:05:36 -0500271 * @brief Callback for inventory property changes
Brandon Wyman10295542017-08-09 18:20:44 -0500272 *
273 * Process change of Present property for power supply.
274 *
275 * @param[in] msg - Data associated with Present change signal
276 *
277 */
278 void inventoryChanged(sdbusplus::message::message& msg);
279
280 /**
281 * Updates the presence status by querying D-Bus
282 *
283 * The D-Bus inventory properties for this power supply will be read to
284 * determine if the power supply is present or not and update this
285 * objects present member variable to reflect current status.
286 */
287 void updatePresence();
Brandon Wyman431fbe42017-08-18 16:22:09 -0500288
289 /**
290 * @brief Updates the poweredOn status by querying D-Bus
291 *
Brandon Wyman875b3632017-09-13 18:46:03 -0500292 * The D-Bus property for the system power state will be read to
Brandon Wyman431fbe42017-08-18 16:22:09 -0500293 * determine if the system is powered on or not.
294 */
295 void updatePowerState();
296
Brandon Wyman764c7972017-08-22 17:05:36 -0500297 /**
298 * @brief Callback for power state property changes
299 *
Brandon Wyman431fbe42017-08-18 16:22:09 -0500300 * Process changes to the powered on stat property for the system.
301 *
302 * @param[in] msg - Data associated with the power state signal
303 */
304 void powerStateChanged(sdbusplus::message::message& msg);
305
Brandon Wyman603cc002017-08-28 18:17:58 -0500306 /**
Brandon Wymana1e96342017-09-25 16:47:44 -0500307 * @brief Wrapper for PMBus::read() and adding metadata
308 *
309 * @param[out] nv - NamesValues instance to store cmd string and value
310 * @param[in] cmd - String for the command to read data from.
311 * @param[in] type - The type of file to read the command from.
312 */
313 void captureCmd(util::NamesValues& nv, const std::string& cmd,
314 witherspoon::pmbus::Type type);
315
316 /**
Brandon Wyman603cc002017-08-28 18:17:58 -0500317 * @brief Checks for input voltage faults and logs error if needed.
318 *
319 * Check for voltage input under voltage fault (VIN_UV_FAULT) and/or
320 * input fault or warning (INPUT_FAULT), and logs appropriate error(s).
321 *
322 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs
323 */
324 void checkInputFault(const uint16_t statusWord);
325
326 /**
327 * @brief Checks for power good negated or unit is off in wrong state
328 *
329 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs
330 */
331 void checkPGOrUnitOffFault(const uint16_t statusWord);
332
333 /**
334 * @brief Checks for output current over current fault.
335 *
336 * IOUT_OC_FAULT is checked, if on, appropriate error is logged.
337 *
338 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs
339 */
340 void checkCurrentOutOverCurrentFault(const uint16_t statusWord);
341
Brandon Wymanab05c072017-08-30 18:26:41 -0500342 /**
343 * @brief Checks for output overvoltage fault.
344 *
345 * VOUT_OV_FAULT is checked, if on, appropriate error is logged.
346 *
347 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs
348 */
349 void checkOutputOvervoltageFault(const uint16_t statusWord);
350
Brandon Wyman12661f12017-08-31 15:28:21 -0500351 /**
352 * @brief Checks for a fan fault or warning condition.
353 *
354 * The high byte of STATUS_WORD is checked to see if the "FAN FAULT OR
355 * WARNING" bit is turned on. If it is on, log an error.
356 *
357 * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs
358 */
359 void checkFanFault(const uint16_t statusWord);
360
Brandon Wyman875b3632017-09-13 18:46:03 -0500361 /**
362 * @brief Checks for a temperature fault or warning condition.
363 *
364 * The low byte of STATUS_WORD is checked to see if the "TEMPERATURE
365 * FAULT OR WARNING" bit is turned on. If it is on, log an error,
366 * call out the power supply indicating the fault/warning condition.
367 *
368 * @parma[in] statusWord - 2 byte STATUS_WORD value read from sysfs
369 */
370 void checkTemperatureFault(const uint16_t statusWord);
371
Matt Spinler234ce0d2018-01-04 15:06:57 -0600372 /**
373 * @brief Adds properties to the inventory.
374 *
375 * Reads the values from the device and writes them to the
376 * associated power supply D-Bus inventory object.
377 *
378 * This needs to be done on startup, and each time the presence
379 * state changes.
380 *
381 * Properties added:
382 * - Serial Number
383 * - Part Number
384 * - CCIN (Customer Card Identification Number) - added as the Model
385 * - Firmware version
386 */
387 void updateInventory();
388
Matt Spinlereb169fd2018-01-18 14:19:08 -0600389 /**
Matt Spinlerd734e652018-01-18 14:31:15 -0600390 * @brief Toggles the GPIO to sync power supply input history readings
391 *
392 * This GPIO is connected to all supplies. This will clear the
393 * previous readings out of the supplies and restart them both at the
394 * same time zero and at record ID 0. The supplies will return 0
395 * bytes of data for the input history command right after this until
396 * a new entry shows up.
397 *
398 * This will cause the code to delete all previous history data and
399 * start fresh.
400 */
401 void syncHistory();
402
403 /**
Matt Spinlereb169fd2018-01-18 14:19:08 -0600404 * @brief Reads the most recent input history record from the power
405 * supply and updates the average and maximum properties in
406 * D-Bus if there is a new reading available.
407 *
408 * This will still run every time analyze() is called so code can
409 * post new data as soon as possible and the timestamp will more
410 * accurately reflect the correct time.
411 *
412 * D-Bus is only updated if there is a change and the oldest record
413 * will be pruned if the property already contains the max number of
414 * records.
415 */
416 void updateHistory();
Brandon Wyman24e422f2017-07-25 19:40:14 -0500417};
418
419}
420}
421}