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