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