1 #pragma once 2 3 #include "average.hpp" 4 #include "maximum.hpp" 5 #include "pmbus.hpp" 6 #include "record_manager.hpp" 7 #include "types.hpp" 8 #include "util.hpp" 9 #include "utility.hpp" 10 11 #include <gpiod.hpp> 12 #include <sdbusplus/bus/match.hpp> 13 #include <xyz/openbmc_project/Sensor/Value/server.hpp> 14 15 #include <filesystem> 16 #include <stdexcept> 17 18 namespace phosphor::power::psu 19 { 20 21 #if IBM_VPD 22 // PMBus device driver "file name" to read for CCIN value. 23 constexpr auto CCIN = "ccin"; 24 constexpr auto PART_NUMBER = "mfr_revision"; 25 constexpr auto FRU_NUMBER = "mfr_model"; 26 constexpr auto SERIAL_HEADER = "mfr_location"; 27 constexpr auto SERIAL_NUMBER = "mfr_serial"; 28 constexpr auto FW_VERSION = "fw_version"; 29 30 // The D-Bus property name to update with the CCIN value. 31 constexpr auto MODEL_PROP = "Model"; 32 constexpr auto PN_PROP = "PartNumber"; 33 constexpr auto SPARE_PN_PROP = "SparePartNumber"; 34 constexpr auto SN_PROP = "SerialNumber"; 35 constexpr auto VERSION_PROP = "Version"; 36 37 // ipzVPD Keyword sizes 38 static constexpr auto FL_KW_SIZE = 20; 39 static constexpr auto FN_KW_SIZE = 7; 40 static constexpr auto PN_KW_SIZE = 7; 41 // For IBM power supplies, the SN is 6-byte header + 6-byte serial. 42 static constexpr auto SN_KW_SIZE = 12; 43 static constexpr auto CC_KW_SIZE = 4; 44 #endif 45 46 constexpr auto LOG_LIMIT = 3; 47 constexpr auto DEGLITCH_LIMIT = 3; 48 constexpr auto PGOOD_DEGLITCH_LIMIT = 5; 49 // Number of polls to remember that an AC fault occured. Should remain greater 50 // than PGOOD_DEGLITCH_LIMIT. 51 constexpr auto AC_FAULT_LIMIT = 6; 52 53 constexpr auto IBMCFFPS_DD_NAME = "ibm-cffps"; 54 constexpr auto ACBEL_FSG032_DD_NAME = "acbel-fsg032"; 55 56 using SensorInterface = sdbusplus::xyz::openbmc_project::Sensor::server::Value; 57 using SensorObject = sdbusplus::server::object_t<SensorInterface>; 58 59 /** 60 * @class PowerSupply 61 * Represents a PMBus power supply device. 62 */ 63 class PowerSupply 64 { 65 public: 66 PowerSupply() = delete; 67 PowerSupply(const PowerSupply&) = delete; 68 PowerSupply(PowerSupply&&) = delete; 69 PowerSupply& operator=(const PowerSupply&) = delete; 70 PowerSupply& operator=(PowerSupply&&) = delete; 71 ~PowerSupply() = default; 72 73 /** 74 * @param[in] invpath - String for inventory path to use 75 * @param[in] i2cbus - The bus number this power supply is on 76 * @param[in] i2caddr - The 16-bit I2C address of the power supply 77 * @param[in] driver - i2c driver name for power supply 78 * @param[in] gpioLineName - The gpio-line-name to read for presence. See 79 * https://github.com/openbmc/docs/blob/master/designs/device-tree-gpio-naming.md 80 * @param[in] callback - Get the power on status of the psu manager class 81 */ 82 PowerSupply(sdbusplus::bus_t& bus, const std::string& invpath, 83 std::uint8_t i2cbus, const std::uint16_t i2caddr, 84 const std::string& driver, const std::string& gpioLineName, 85 std::function<bool()>&& callback); 86 87 phosphor::pmbus::PMBusBase& getPMBus() 88 { 89 return *pmbusIntf; 90 } 91 92 GPIOInterfaceBase* getPresenceGPIO() 93 { 94 return presenceGPIO.get(); 95 } 96 97 std::string getPresenceGPIOName() const 98 { 99 if (presenceGPIO != nullptr) 100 { 101 return presenceGPIO->getName(); 102 } 103 else 104 { 105 return std::string(); 106 } 107 } 108 109 /** 110 * Power supply specific function to analyze for faults/errors. 111 * 112 * Various PMBus status bits will be checked for fault conditions. 113 * If a certain fault bits are on, the appropriate error will be 114 * committed. 115 */ 116 void analyze(); 117 118 /** 119 * Write PMBus ON_OFF_CONFIG 120 * 121 * This function will be called to cause the PMBus device driver to send the 122 * ON_OFF_CONFIG command. Takes one byte of data. 123 * 124 * @param[in] data - The ON_OFF_CONFIG data byte mask. 125 */ 126 void onOffConfig(uint8_t data); 127 128 /** 129 * Clears all the member variables that indicate if a fault bit was seen as 130 * on in the STATUS_WORD or STATUS_MFR_SPECIFIC response. 131 */ 132 void clearFaultFlags() 133 { 134 inputFault = 0; 135 mfrFault = 0; 136 statusMFR = 0; 137 vinUVFault = 0; 138 cmlFault = 0; 139 voutOVFault = 0; 140 ioutOCFault = 0; 141 voutUVFault = 0; 142 fanFault = 0; 143 tempFault = 0; 144 pgoodFault = 0; 145 psKillFault = 0; 146 ps12VcsFault = 0; 147 psCS12VFault = 0; 148 faultLogged = false; 149 } 150 151 /** 152 * @brief Function to specifically clear VIN_UV/OFF fault(s). 153 * 154 * The PMBus HWMON device driver has various alarm "files" to read out of 155 * sysfs. Reading those files will indicate if various alarms are active or 156 * not, and then specifically clear those faults that go with that alarm. 157 * 158 * The VIN_UV fault, indicated in STATUS_INPUT, goes with in1_lcrit_alarm. 159 * When a VIN_UV fault occurs, the "Unit Off For Insufficient Input Voltage" 160 * may also be active. Reading in1_lcrit_alarm should clear both fault bits, 161 * resulting in the corresponding fault bits in STATUS_WORD also clearing. 162 * 163 * See: https://www.kernel.org/doc/html/latest/hwmon/pmbus.html 164 */ 165 void clearVinUVFault(); 166 167 /** 168 * Write PMBus CLEAR_FAULTS 169 * 170 * This function will be called in various situations in order to clear 171 * any fault status bits that may have been set, in order to start over 172 * with a clean state. Presence changes and power state changes will 173 * want to clear any faults logged. 174 */ 175 void clearFaults(); 176 177 /** 178 * @brief Adds properties to the inventory. 179 * 180 * Reads the values from the device and writes them to the 181 * associated power supply D-Bus inventory object. 182 * 183 * This needs to be done on startup, and each time the presence 184 * state changes. 185 * 186 * Properties added: 187 * - Serial Number 188 * - Part Number 189 * - CCIN (Customer Card Identification Number) - added as the Model 190 * - Firmware version 191 */ 192 void updateInventory(); 193 194 /** 195 * @brief Accessor function to indicate present status 196 */ 197 bool isPresent() const 198 { 199 return present; 200 } 201 202 /** 203 * @brief Returns the last read value from STATUS_WORD. 204 */ 205 uint64_t getStatusWord() const 206 { 207 return statusWord; 208 } 209 210 /** 211 * @brief Returns the last read value from STATUS_INPUT. 212 */ 213 uint64_t getStatusInput() const 214 { 215 return statusInput; 216 } 217 218 /** 219 * @brief Returns the last read value from STATUS_MFR. 220 */ 221 uint64_t getMFRFault() const 222 { 223 return statusMFR; 224 } 225 226 /** 227 * @brief Returns the last read value from STATUS_CML. 228 */ 229 uint64_t getStatusCML() const 230 { 231 return statusCML; 232 } 233 234 /** 235 * @brief Returns the last read value from STATUS_VOUT. 236 */ 237 uint64_t getStatusVout() const 238 { 239 return statusVout; 240 } 241 242 /** 243 * @brief Returns the last value read from STATUS_IOUT. 244 */ 245 uint64_t getStatusIout() const 246 { 247 return statusIout; 248 } 249 250 /** 251 * @brief Returns the last value read from STATUS_FANS_1_2. 252 */ 253 uint64_t getStatusFans12() const 254 { 255 return statusFans12; 256 } 257 258 /** 259 * @brief Returns the last value read from STATUS_TEMPERATURE. 260 */ 261 uint64_t getStatusTemperature() const 262 { 263 return statusTemperature; 264 } 265 266 /** 267 * @brief Returns true if a fault was found. 268 */ 269 bool isFaulted() const 270 { 271 return (hasCommFault() || (vinUVFault >= DEGLITCH_LIMIT) || 272 (inputFault >= DEGLITCH_LIMIT) || 273 (voutOVFault >= DEGLITCH_LIMIT) || 274 (ioutOCFault >= DEGLITCH_LIMIT) || 275 (voutUVFault >= DEGLITCH_LIMIT) || 276 (fanFault >= DEGLITCH_LIMIT) || (tempFault >= DEGLITCH_LIMIT) || 277 (pgoodFault >= PGOOD_DEGLITCH_LIMIT) || 278 (mfrFault >= DEGLITCH_LIMIT)); 279 } 280 281 /** 282 * @brief Return whether a fault has been logged for this power supply 283 */ 284 bool isFaultLogged() const 285 { 286 return faultLogged; 287 } 288 289 /** 290 * @brief Called when a fault for this power supply has been logged. 291 */ 292 void setFaultLogged() 293 { 294 faultLogged = true; 295 } 296 297 /** 298 * @brief Returns true if INPUT fault occurred. 299 */ 300 bool hasInputFault() const 301 { 302 return (inputFault >= DEGLITCH_LIMIT); 303 } 304 305 /** 306 * @brief Returns true if MFRSPECIFIC occurred. 307 */ 308 bool hasMFRFault() const 309 { 310 return (mfrFault >= DEGLITCH_LIMIT); 311 } 312 313 /** 314 * @brief Returns true if VIN_UV_FAULT occurred. 315 */ 316 bool hasVINUVFault() const 317 { 318 return (vinUVFault >= DEGLITCH_LIMIT); 319 } 320 321 /** 322 * @brief Returns true if VOUT_OV_FAULT occurred. 323 */ 324 bool hasVoutOVFault() const 325 { 326 return (voutOVFault >= DEGLITCH_LIMIT); 327 } 328 329 /** 330 * @brief Returns true if IOUT_OC fault occurred (bit 4 STATUS_BYTE). 331 */ 332 bool hasIoutOCFault() const 333 { 334 return (ioutOCFault >= DEGLITCH_LIMIT); 335 } 336 337 /** 338 * @brief Returns true if VOUT_UV_FAULT occurred. 339 */ 340 bool hasVoutUVFault() const 341 { 342 return (voutUVFault >= DEGLITCH_LIMIT); 343 } 344 345 /** 346 *@brief Returns true if fan fault occurred. 347 */ 348 bool hasFanFault() const 349 { 350 return (fanFault >= DEGLITCH_LIMIT); 351 } 352 353 /** 354 * @brief Returns true if TEMPERATURE fault occurred. 355 */ 356 bool hasTempFault() const 357 { 358 return (tempFault >= DEGLITCH_LIMIT); 359 } 360 361 /** 362 * @brief Returns true if there is a PGood fault (PGOOD# inactive, or OFF 363 * bit on). 364 */ 365 bool hasPgoodFault() const 366 { 367 return (pgoodFault >= PGOOD_DEGLITCH_LIMIT); 368 } 369 370 /** 371 * @brief Return true if there is a PS_Kill fault. 372 */ 373 bool hasPSKillFault() const 374 { 375 return (psKillFault >= DEGLITCH_LIMIT); 376 } 377 378 /** 379 * @brief Returns true if there is a 12Vcs (standy power) fault. 380 */ 381 bool hasPS12VcsFault() const 382 { 383 return (ps12VcsFault >= DEGLITCH_LIMIT); 384 } 385 386 /** 387 * @brief Returns true if there is a 12V current-share fault. 388 */ 389 bool hasPSCS12VFault() const 390 { 391 return (psCS12VFault >= DEGLITCH_LIMIT); 392 } 393 394 /** 395 * @brief Returns true if an AC fault has occurred in the window of 396 * interest. 397 */ 398 bool hasACFault() const 399 { 400 return acFault != 0; 401 } 402 403 /** 404 * @brief Returns the device path 405 * 406 * This can be used for error call outs. 407 * Example: /sys/bus/i2c/devices/3-0068 408 */ 409 const std::string getDevicePath() const 410 { 411 return pmbusIntf->path(); 412 } 413 414 /** 415 * @brief Returns this power supply's inventory path. 416 * 417 * This can be used for error call outs. 418 * Example: 419 * /xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply1 420 */ 421 const std::string& getInventoryPath() const 422 { 423 return inventoryPath; 424 } 425 426 /** 427 * @brief Returns the short name (last part of inventoryPath). 428 */ 429 const std::string& getShortName() const 430 { 431 return shortName; 432 } 433 434 /** 435 * @brief Returns the firmware revision version read from the power supply 436 */ 437 const std::string& getFWVersion() const 438 { 439 return fwVersion; 440 } 441 442 /** 443 * @brief Returns the model name of the power supply 444 */ 445 const std::string& getModelName() const 446 { 447 return modelName; 448 } 449 450 /** 451 * @brief Returns true if the number of failed reads exceeds limit 452 * TODO: or CML bit on. 453 */ 454 bool hasCommFault() const 455 { 456 return ((readFail >= LOG_LIMIT) || (cmlFault >= DEGLITCH_LIMIT)); 457 } 458 459 /** 460 * @brief Reads the pmbus input voltage and returns that actual voltage 461 * reading and the calculated input voltage based on thresholds. 462 * @param[out] actualInputVoltage - The actual voltage reading, in Volts. 463 * @param[out] inputVoltage - A rounded up/down value of the actual input 464 * voltage based on thresholds, in Volts. 465 */ 466 void getInputVoltage(double& actualInputVoltage, int& inputVoltage) const; 467 468 /** 469 * @brief Check if the PS is considered to be available or not 470 * 471 * It is unavailable if any of: 472 * - not present 473 * - input fault active 474 * - Vin UV fault active 475 * - PS KILL fault active 476 * - Iout OC fault active 477 * 478 * Other faults will, through creating error logs with callouts, already 479 * be setting the Functional property to false. 480 * 481 * On changes, the Available property is updated in the inventory. 482 */ 483 void checkAvailability(); 484 485 /** 486 * @brief Setup for power supply input history. 487 * 488 * This will setup the variables and interfaces needed to get the power 489 * supply input history data over to D-Bus. The only known support for this 490 * at this time is the INPUT_HISTORY command implemented by the IBM Common 491 * Form Factor Power Suppplies (ibm-cffps). The INPUT_HISTORY command for 492 * ibm-cffps is implemented via a manufacturing specific PMBus command. 493 */ 494 void setupInputHistory(); 495 496 /** 497 * @brief Returns true if this power supply has input history (supported). 498 */ 499 bool hasInputHistory() const 500 { 501 return inputHistorySupported; 502 } 503 504 /** 505 * @brief Returns the number of input history records 506 * 507 * PowerSupply wrapper to getNumRecords() from RecordManager. 508 */ 509 size_t getNumInputHistoryRecords() const 510 { 511 if (recordManager) 512 { 513 return recordManager->getNumRecords(); 514 } 515 else 516 { 517 return 0; 518 } 519 } 520 521 /** 522 * @brief Returns true when INPUT_HISTORY sync is required. 523 */ 524 bool isSyncHistoryRequired() const 525 { 526 return syncHistoryRequired; 527 } 528 529 /** 530 * @brief Clears the indicator that sync required for INPUT_HISTORY. 531 * 532 * Sets variable to false to indicate that the sync is no longer required. 533 * This can be used after the PSUManager has reacted to the need for the 534 * INPUT_HISTORY data to be synchronized. 535 */ 536 void clearSyncHistoryRequired() 537 { 538 syncHistoryRequired = false; 539 } 540 541 /** 542 * @brief Puts the input voltage rating on D-Bus. 543 * 544 * The rating is like 0, 110, 220. 545 */ 546 void setInputVoltageRating(); 547 548 private: 549 /** 550 * @brief Examine STATUS_WORD for CML (communication, memory, logic fault). 551 */ 552 void analyzeCMLFault(); 553 554 /** 555 * @brief Examine STATUS_WORD for INPUT bit on. 556 * 557 * "An input voltage, input current, or input power fault or warning has 558 * occurred." 559 */ 560 void analyzeInputFault(); 561 562 /** 563 * @brief Examine STATUS_WORD for VOUT being set. 564 * 565 * If VOUT is on, "An output voltage fault or warning has occurred.", and 566 * VOUT_OV_FAULT is on, there is an output over-voltage fault. 567 */ 568 void analyzeVoutOVFault(); 569 570 /** 571 * @brief Examine STATUS_WORD value read for IOUT_OC_FAULT. 572 * 573 * "An output overcurrent fault has occurred." If it is on, and fault not 574 * set, trace STATUS_WORD, STATUS_MFR_SPECIFIC, and STATUS_IOUT values. 575 */ 576 void analyzeIoutOCFault(); 577 578 /** 579 * @brief Examines STATUS_WORD value read to see if there is a UV fault. 580 * 581 * Checks if the VOUT bit is on, indicating "An output voltage fault or 582 * warning has occurred", if it is on, but VOUT_OV_FAULT is off, it is 583 * determined to be an indication of an output under-voltage fault. 584 */ 585 void analyzeVoutUVFault(); 586 587 /** 588 * @brief Examine STATUS_WORD for the fan fault/warning bit. 589 * 590 * If fanFault is not on, trace that the bit now came on, include 591 * STATUS_WORD, STATUS_MFR_SPECIFIC, and STATUS_FANS_1_2 values as well, to 592 * help with understanding what may have caused it to be set. 593 */ 594 void analyzeFanFault(); 595 596 /** 597 * @brief Examine STATUS_WORD for temperature fault. 598 */ 599 void analyzeTemperatureFault(); 600 601 /** 602 * @brief Examine STATUS_WORD for pgood or unit off faults. 603 */ 604 void analyzePgoodFault(); 605 606 /** 607 * @brief Determine possible manufacturer-specific faults from bits in 608 * STATUS_MFR. 609 * 610 * The bits in the STATUS_MFR_SPECIFIC command response have "Manufacturer 611 * Defined" meanings. Determine which faults, if any, are present based on 612 * the power supply (device driver) type. 613 */ 614 void determineMFRFault(); 615 616 /** 617 * @brief Examine STATUS_WORD value read for MFRSPECIFIC bit on. 618 * 619 * "A manufacturer specific fault or warning has occurred." 620 * 621 * If it is on, call the determineMFRFault() helper function to examine the 622 * value read from STATUS_MFR_SPECIFIC. 623 */ 624 void analyzeMFRFault(); 625 626 /** 627 * @brief Analyzes the STATUS_WORD for a VIN_UV_FAULT indicator. 628 */ 629 void analyzeVinUVFault(); 630 631 /** 632 * @brief Given a full inventory path, returns the last node of the path as 633 * the "short name" 634 */ 635 std::string findShortName(const std::string& invPath) 636 { 637 const auto lastSlashPos = invPath.find_last_of('/'); 638 639 if ((lastSlashPos == std::string::npos) || 640 ((lastSlashPos + 1) == invPath.size())) 641 { 642 return invPath; 643 } 644 else 645 { 646 return invPath.substr(lastSlashPos + 1); 647 } 648 } 649 650 /** 651 * @brief Binds or unbinds the power supply device driver 652 * 653 * Called when a presence change is detected to either bind the device 654 * driver for the power supply when it is installed, or unbind the device 655 * driver when the power supply is removed. 656 * 657 * Writes <device> to <path>/bind (or unbind) 658 * 659 * @param present - when true, will bind the device driver 660 * when false, will unbind the device driver 661 */ 662 void bindOrUnbindDriver(bool present); 663 664 /** 665 * @brief Updates the presence status by querying D-Bus 666 * 667 * The D-Bus inventory properties for this power supply will be read to 668 * determine if the power supply is present or not and update this 669 * object's present member variable to reflect current status. 670 **/ 671 void updatePresence(); 672 673 /** 674 * @brief Updates the power supply presence by reading the GPIO line. 675 */ 676 void updatePresenceGPIO(); 677 678 /** 679 * @brief Callback for inventory property changes 680 * 681 * Process change of Present property for power supply. 682 * 683 * This is used if we are watching the D-Bus properties instead of reading 684 * the GPIO presence line ourselves. 685 * 686 * @param[in] msg - Data associated with Present change signal 687 **/ 688 void inventoryChanged(sdbusplus::message_t& msg); 689 690 /** 691 * @brief Callback for inventory property added. 692 * 693 * Process add of the interface with the Present property for power supply. 694 * 695 * This is used if we are watching the D-Bus properties instead of reading 696 * the GPIO presence line ourselves. 697 * 698 * @param[in] msg - Data associated with Present add signal 699 **/ 700 void inventoryAdded(sdbusplus::message_t& msg); 701 702 /** 703 * @brief Reads the pmbus MFR_POUT_MAX value. 704 * 705 * "The MFR_POUT_MAX command sets or retrieves the maximum rated output 706 * power, in watts, that the unit is rated to supply." 707 * 708 * @return max_power_out value converted from string. 709 */ 710 auto getMaxPowerOut() const; 711 712 /** 713 * @brief Reads a VPD value from PMBus, correct size, and contents. 714 * 715 * If the VPD data read is not the passed in size, resize and fill with 716 * spaces. If the data contains a non-alphanumeric value, replace any of 717 * those values with spaces. 718 * 719 * @param[in] vpdName - The name of the sysfs "file" to read data from. 720 * @param[in] type - The HWMON file type to read from. 721 * @param[in] vpdSize - The expacted size of the data for this VPD/property 722 * 723 * @return A string containing the VPD data read, resized if necessary 724 */ 725 auto readVPDValue(const std::string& vpdName, 726 const phosphor::pmbus::Type& type, 727 const std::size_t& vpdSize); 728 729 /** 730 * @brief Reads the most recent input history record from the power supply 731 * and updates the average and maximum properties in D-Bus if there is a new 732 * reading available. 733 * 734 * This will still run every time analyze() is called so code can post new 735 * data as soon as possible and the timestamp will more accurately reflect 736 * the correct time. 737 * 738 * D-Bus is only updated if there is a change and the oldest record will be 739 * pruned if the property already contains the max number of records. 740 */ 741 void updateHistory(); 742 743 /** 744 * @brief Retrieve PSU VPD keyword from D-Bus 745 * 746 * It retrieves PSU VPD keyword from D-Bus and assign the associated 747 * string to vpdStr. 748 * @param[in] keyword - The VPD search keyword 749 * @param[out] vpdStr - The VPD string associated with the keyword. 750 */ 751 void getPsuVpdFromDbus(const std::string& keyword, std::string& vpdStr); 752 753 /** 754 * @brief systemd bus member 755 */ 756 sdbusplus::bus_t& bus; 757 758 /** 759 * @brief D-Bus path to use for this power supply's inventory status. 760 **/ 761 std::string inventoryPath; 762 763 /** 764 * @brief The file system path used for binding the device driver. 765 */ 766 const std::filesystem::path bindPath; 767 768 /** 769 * @brief Get the power on status of the psu manager class. 770 * 771 * This is a callback method used to get the power on status of the psu 772 * manager class. 773 */ 774 std::function<bool()> isPowerOn; 775 776 /** 777 * @brief Set to true if INPUT_HISTORY command supported. 778 * 779 * Not all power supplies will support the INPUT_HISTORY command. The IBM 780 * Common Form Factor power supplies do support this command. 781 */ 782 bool inputHistorySupported{false}; 783 784 /** 785 * @brief Set to true when INPUT_HISTORY sync is required. 786 * 787 * A power supply will need to synchronize its INPUT_HISTORY data with the 788 * other power supplies installed in the system when it goes from missing to 789 * present. 790 */ 791 bool syncHistoryRequired{false}; 792 793 /** 794 * @brief Store the short name to avoid string processing. 795 * 796 * The short name will be something like powersupply1, the last part of the 797 * inventoryPath. 798 */ 799 std::string shortName; 800 801 /** 802 * @brief The libgpiod object for monitoring PSU presence 803 */ 804 std::unique_ptr<GPIOInterfaceBase> presenceGPIO = nullptr; 805 806 /** 807 * @brief True if the power supply is present. 808 */ 809 bool present = false; 810 811 /** 812 * @brief Power supply model name. 813 */ 814 std::string modelName; 815 816 /** 817 * @brief D-Bus match variable used to subscribe to Present property 818 * changes. 819 **/ 820 std::unique_ptr<sdbusplus::bus::match_t> presentMatch; 821 822 /** 823 * @brief D-Bus match variable used to subscribe for Present property 824 * interface added. 825 */ 826 std::unique_ptr<sdbusplus::bus::match_t> presentAddedMatch; 827 828 /** 829 * @brief Pointer to the PMBus interface 830 * 831 * Used to read or write to/from PMBus power supply devices. 832 */ 833 std::unique_ptr<phosphor::pmbus::PMBusBase> pmbusIntf = nullptr; 834 835 /** 836 * @brief Stored copy of the firmware version/revision string 837 */ 838 std::string fwVersion; 839 840 /** 841 * @brief The string to pass in for binding the device driver. 842 */ 843 std::string bindDevice; 844 845 /** 846 * @brief The result of the most recent availability check 847 * 848 * Saved on the object so changes can be detected. 849 */ 850 bool available = false; 851 852 /** 853 * @brief Will be updated to the latest/lastvalue read from STATUS_WORD. 854 */ 855 uint64_t statusWord = 0; 856 857 /** 858 * @brief Will be set to the last read value of STATUS_WORD. 859 */ 860 uint64_t statusWordOld = 0; 861 862 /** 863 * @brief Will be updated to the latest/lastvalue read from STATUS_INPUT. 864 */ 865 uint64_t statusInput = 0; 866 867 /** 868 * @brief Will be updated to the latest/lastvalue read from STATUS_MFR. 869 */ 870 uint64_t statusMFR = 0; 871 872 /** 873 * @brief Will be updated to the latest/last value read from STATUS_CML. 874 */ 875 uint64_t statusCML = 0; 876 877 /** 878 * @brief Will be updated to the latest/last value read from STATUS_VOUT. 879 */ 880 uint64_t statusVout = 0; 881 882 /** 883 * @brief Will be updated to the latest/last value read from STATUS_IOUT. 884 */ 885 uint64_t statusIout = 0; 886 887 /** 888 * @brief Will be updated to the latest/last value read from 889 * STATUS_FANS_1_2. 890 */ 891 uint64_t statusFans12 = 0; 892 893 /** 894 * @brief Will be updated to the latest/last value read from 895 * STATUS_TEMPERATURE. 896 */ 897 uint64_t statusTemperature = 0; 898 899 /** 900 * @brief Will be updated with latest converted value read from READ_VIN 901 */ 902 int inputVoltage = phosphor::pmbus::in_input::VIN_VOLTAGE_0; 903 904 /** 905 * @brief Will be updated with the actual voltage last read from READ_VIN 906 */ 907 double actualInputVoltage = 0; 908 909 /** 910 * @brief True if an error for a fault has already been logged. 911 */ 912 bool faultLogged = false; 913 914 /** 915 * @brief Incremented if bit 1 of STATUS_WORD low byte is on. 916 * 917 * Considered faulted if reaches DEGLITCH_LIMIT. 918 */ 919 size_t cmlFault = 0; 920 921 /** 922 * @brief Incremented if bit 5 of STATUS_WORD high byte is on. 923 * 924 * Considered faulted if reaches DEGLITCH_LIMIT. 925 */ 926 size_t inputFault = 0; 927 928 /** 929 * @brief Incremented if bit 4 of STATUS_WORD high byte is on. 930 * 931 * Considered faulted if reaches DEGLITCH_LIMIT. 932 */ 933 size_t mfrFault = 0; 934 935 /** 936 * @brief Incremented if bit 3 of STATUS_WORD low byte is on. 937 * 938 * Considered faulted if reaches DEGLITCH_LIMIT. 939 */ 940 size_t vinUVFault = 0; 941 942 /** 943 * @brief Incremented if bit 5 of STATUS_WORD low byte is on. 944 * 945 * Considered faulted if reaches DEGLITCH_LIMIT. 946 */ 947 size_t voutOVFault = 0; 948 949 /** 950 * @brief Incremented if bit 4 of STATUS_WORD low byte is on. 951 * 952 * Considered faulted if reaches DEGLITCH_LIMIT. 953 */ 954 size_t ioutOCFault = 0; 955 956 /** 957 * @brief Incremented if bit 7 of STATUS_WORD high byte is on and bit 5 958 * (VOUT_OV) of low byte is off. 959 * 960 * Considered faulted if reaches DEGLITCH_LIMIT. 961 */ 962 size_t voutUVFault = 0; 963 964 /** 965 * @brief Incremented if FANS fault/warn bit on in STATUS_WORD. 966 * 967 * Considered faulted if reaches DEGLITCH_LIMIT. 968 */ 969 size_t fanFault = 0; 970 971 /** 972 * @brief Incremented if bit 2 of STATUS_WORD low byte is on. 973 * 974 * Considered faulted if reaches DEGLITCH_LIMIT. 975 */ 976 size_t tempFault = 0; 977 978 /** 979 * @brief Incremented if bit 11 or 6 of STATUS_WORD is on. PGOOD# is 980 * inactive, or the unit is off. 981 * 982 * Considered faulted if reaches DEGLITCH_LIMIT. 983 */ 984 size_t pgoodFault = 0; 985 986 /** 987 * @brief Power Supply Kill fault. 988 * 989 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use 990 * bit 4 to indicate this fault. Considered faulted if it reaches 991 * DEGLITCH_LIMIT. 992 */ 993 size_t psKillFault = 0; 994 995 /** 996 * @brief Power Supply 12Vcs fault (standby power). 997 * 998 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use 999 * bit 6 to indicate this fault. Considered faulted if it reaches 1000 * DEGLITCH_LIMIT. 1001 */ 1002 size_t ps12VcsFault = 0; 1003 1004 /** 1005 * @brief Power Supply Current-Share fault in 12V domain. 1006 * 1007 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use 1008 * bit 7 to indicate this fault. Considered faulted if it reaches 1009 * DEGLITCH_LIMIT. 1010 */ 1011 size_t psCS12VFault = 0; 1012 1013 /** 1014 * @brief Set to AC_FAULT_LIMIT when AC fault is detected, decremented when 1015 * AC fault has cleared. Effectively forms a timer since last AC failure. 1016 * Zero indicates being outside the window of concern. 1017 */ 1018 size_t acFault = 0; 1019 1020 /** 1021 * @brief Count of the number of read failures. 1022 */ 1023 size_t readFail = 0; 1024 1025 /** 1026 * @brief Class that manages the input power history records. 1027 **/ 1028 std::unique_ptr<history::RecordManager> recordManager; 1029 1030 /** 1031 * @brief The D-Bus object for the average input power history 1032 **/ 1033 std::unique_ptr<history::Average> average; 1034 1035 /** 1036 * @brief The D-Bus object for the maximum input power history 1037 **/ 1038 std::unique_ptr<history::Maximum> maximum; 1039 1040 /** 1041 * @brief The base D-Bus object path to use for the average and maximum 1042 * objects. 1043 **/ 1044 std::string historyObjectPath; 1045 1046 /** 1047 * @brief The D-Bus object for the input voltage rating 1048 * 1049 * It is updated at startup and power on. If a power supply is 1050 * added or removed after that, it does not need to be updated 1051 * again (though that could be done as a future improvement). 1052 */ 1053 std::unique_ptr<SensorObject> inputVoltageRatingIface; 1054 1055 /** 1056 * @brief The device driver name 1057 */ 1058 std::string driverName; 1059 }; 1060 1061 } // namespace phosphor::power::psu 1062