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 /** @brief Returns true if the number of failed reads exceeds limit 430 * TODO: or CML bit on. 431 */ 432 bool hasCommFault() const 433 { 434 return ((readFail >= LOG_LIMIT) || (cmlFault >= DEGLITCH_LIMIT)); 435 } 436 437 /** 438 * @brief Reads the pmbus input voltage and returns that actual voltage 439 * reading and the calculated input voltage based on thresholds. 440 * @param[out] actualInputVoltage - The actual voltage reading, in Volts. 441 * @param[out] inputVoltage - A rounded up/down value of the actual input 442 * voltage based on thresholds, in Volts. 443 */ 444 void getInputVoltage(double& actualInputVoltage, int& inputVoltage) const; 445 446 /** 447 * @brief Check if the PS is considered to be available or not 448 * 449 * It is unavailable if any of: 450 * - not present 451 * - input fault active 452 * - Vin UV fault active 453 * - PS KILL fault active 454 * - Iout OC fault active 455 * 456 * Other faults will, through creating error logs with callouts, already 457 * be setting the Functional property to false. 458 * 459 * On changes, the Available property is updated in the inventory. 460 */ 461 void checkAvailability(); 462 463 /** 464 * @brief Setup for power supply input history. 465 * 466 * This will setup the variables and interfaces needed to get the power 467 * supply input history data over to D-Bus. The only known support for this 468 * at this time is the INPUT_HISTORY command implemented by the IBM Common 469 * Form Factor Power Suppplies (ibm-cffps). The INPUT_HISTORY command for 470 * ibm-cffps is implemented via a manufacturing specific PMBus command. 471 */ 472 void setupInputHistory(); 473 474 /** 475 * @brief Returns true if this power supply has input history (supported). 476 */ 477 bool hasInputHistory() const 478 { 479 return inputHistorySupported; 480 } 481 482 /** 483 * @brief Returns the number of input history records 484 * 485 * PowerSupply wrapper to getNumRecords() from RecordManager. 486 */ 487 size_t getNumInputHistoryRecords() const 488 { 489 if (recordManager) 490 { 491 return recordManager->getNumRecords(); 492 } 493 else 494 { 495 return 0; 496 } 497 } 498 499 /** 500 * @brief Returns true when INPUT_HISTORY sync is required. 501 */ 502 bool isSyncHistoryRequired() const 503 { 504 return syncHistoryRequired; 505 } 506 507 /** 508 * @brief Clears the indicator that sync required for INPUT_HISTORY. 509 * 510 * Sets variable to false to indicate that the sync is no longer required. 511 * This can be used after the PSUManager has reacted to the need for the 512 * INPUT_HISTORY data to be synchronized. 513 */ 514 void clearSyncHistoryRequired() 515 { 516 syncHistoryRequired = false; 517 } 518 519 private: 520 /** @brief systemd bus member */ 521 sdbusplus::bus_t& bus; 522 523 /** @brief Will be updated to the latest/lastvalue read from STATUS_WORD.*/ 524 uint64_t statusWord = 0; 525 526 /** @brief Will be set to the last read value of STATUS_WORD. */ 527 uint64_t statusWordOld = 0; 528 529 /** @brief Will be updated to the latest/lastvalue read from STATUS_INPUT.*/ 530 uint64_t statusInput = 0; 531 532 /** @brief Will be updated to the latest/lastvalue read from STATUS_MFR.*/ 533 uint64_t statusMFR = 0; 534 535 /** @brief Will be updated to the latest/last value read from STATUS_CML.*/ 536 uint64_t statusCML = 0; 537 538 /** @brief Will be updated to the latest/last value read from STATUS_VOUT.*/ 539 uint64_t statusVout = 0; 540 541 /** @brief Will be updated to the latest/last value read from STATUS_IOUT.*/ 542 uint64_t statusIout = 0; 543 544 /** @brief Will be updated to the latest/last value read from 545 * STATUS_FANS_1_2. */ 546 uint64_t statusFans12 = 0; 547 548 /** @brief Will be updated to the latest/last value read from 549 * STATUS_TEMPERATURE.*/ 550 uint64_t statusTemperature = 0; 551 552 /** @brief Will be updated with latest converted value read from READ_VIN */ 553 int inputVoltage = phosphor::pmbus::in_input::VIN_VOLTAGE_0; 554 555 /** @brief Will be updated with the actual voltage last read from READ_VIN 556 */ 557 double actualInputVoltage = 0; 558 559 /** @brief True if an error for a fault has already been logged. */ 560 bool faultLogged = false; 561 562 /** @brief Incremented if bit 1 of STATUS_WORD low byte is on. 563 * 564 * Considered faulted if reaches DEGLITCH_LIMIT. 565 */ 566 size_t cmlFault = 0; 567 568 /** @brief Incremented if bit 5 of STATUS_WORD high byte is on. 569 * 570 * Considered faulted if reaches DEGLITCH_LIMIT. 571 */ 572 size_t inputFault = 0; 573 574 /** @brief Incremented if bit 4 of STATUS_WORD high byte is on. 575 * 576 * Considered faulted if reaches DEGLITCH_LIMIT. 577 */ 578 size_t mfrFault = 0; 579 580 /** @brief Incremented if bit 3 of STATUS_WORD low byte is on. 581 * 582 * Considered faulted if reaches DEGLITCH_LIMIT. 583 */ 584 size_t vinUVFault = 0; 585 586 /** @brief Incremented if bit 5 of STATUS_WORD low byte is on. 587 * 588 * Considered faulted if reaches DEGLITCH_LIMIT. 589 */ 590 size_t voutOVFault = 0; 591 592 /** @brief Incremented if bit 4 of STATUS_WORD low byte is on. 593 * 594 * Considered faulted if reaches DEGLITCH_LIMIT. 595 */ 596 size_t ioutOCFault = 0; 597 598 /** @brief Incremented if bit 7 of STATUS_WORD high byte is on and bit 5 599 * (VOUT_OV) of low byte is off. 600 * 601 * Considered faulted if reaches DEGLITCH_LIMIT. 602 */ 603 size_t voutUVFault = 0; 604 605 /** @brief Incremented if FANS fault/warn bit on in STATUS_WORD. 606 * 607 * Considered faulted if reaches DEGLITCH_LIMIT. 608 */ 609 size_t fanFault = 0; 610 611 /** @brief Incremented if bit 2 of STATUS_WORD low byte is on. 612 * 613 * Considered faulted if reaches DEGLITCH_LIMIT. */ 614 size_t tempFault = 0; 615 616 /** 617 * @brief Incremented if bit 11 or 6 of STATUS_WORD is on. PGOOD# is 618 * inactive, or the unit is off. 619 * 620 * Considered faulted if reaches DEGLITCH_LIMIT. 621 */ 622 size_t pgoodFault = 0; 623 624 /** 625 * @brief Power Supply Kill fault. 626 * 627 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use 628 * bit 4 to indicate this fault. Considered faulted if it reaches 629 * DEGLITCH_LIMIT. 630 */ 631 size_t psKillFault = 0; 632 633 /** 634 * @brief Power Supply 12Vcs fault (standby power). 635 * 636 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use 637 * bit 6 to indicate this fault. Considered faulted if it reaches 638 * DEGLITCH_LIMIT. 639 */ 640 size_t ps12VcsFault = 0; 641 642 /** 643 * @brief Power Supply Current-Share fault in 12V domain. 644 * 645 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use 646 * bit 7 to indicate this fault. Considered faulted if it reaches 647 * DEGLITCH_LIMIT. 648 */ 649 size_t psCS12VFault = 0; 650 651 /** @brief Count of the number of read failures. */ 652 size_t readFail = 0; 653 654 /** 655 * @brief Examine STATUS_WORD for CML (communication, memory, logic fault). 656 */ 657 void analyzeCMLFault(); 658 659 /** 660 * @brief Examine STATUS_WORD for INPUT bit on. 661 * 662 * "An input voltage, input current, or input power fault or warning has 663 * occurred." 664 */ 665 void analyzeInputFault(); 666 667 /** 668 * @brief Examine STATUS_WORD for VOUT being set. 669 * 670 * If VOUT is on, "An output voltage fault or warning has occurred.", and 671 * VOUT_OV_FAULT is on, there is an output over-voltage fault. 672 */ 673 void analyzeVoutOVFault(); 674 675 /* 676 * @brief Examine STATUS_WORD value read for IOUT_OC_FAULT. 677 * 678 * "An output overcurrent fault has occurred." If it is on, and fault not 679 * set, trace STATUS_WORD, STATUS_MFR_SPECIFIC, and STATUS_IOUT values. 680 */ 681 void analyzeIoutOCFault(); 682 683 /** 684 * @brief Examines STATUS_WORD value read to see if there is a UV fault. 685 * 686 * Checks if the VOUT bit is on, indicating "An output voltage fault or 687 * warning has occurred", if it is on, but VOUT_OV_FAULT is off, it is 688 * determined to be an indication of an output under-voltage fault. 689 */ 690 void analyzeVoutUVFault(); 691 692 /** 693 * @brief Examine STATUS_WORD for the fan fault/warning bit. 694 * 695 * If fanFault is not on, trace that the bit now came on, include 696 * STATUS_WORD, STATUS_MFR_SPECIFIC, and STATUS_FANS_1_2 values as well, to 697 * help with understanding what may have caused it to be set. 698 */ 699 void analyzeFanFault(); 700 701 /** 702 * @brief Examine STATUS_WORD for temperature fault. 703 */ 704 void analyzeTemperatureFault(); 705 706 /** 707 * @brief Examine STATUS_WORD for pgood or unit off faults. 708 */ 709 void analyzePgoodFault(); 710 711 /** 712 * @brief Determine possible manufacturer-specific faults from bits in 713 * STATUS_MFR. 714 * 715 * The bits in the STATUS_MFR_SPECIFIC command response have "Manufacturer 716 * Defined" meanings. Determine which faults, if any, are present based on 717 * the power supply (device driver) type. 718 */ 719 void determineMFRFault(); 720 721 /** 722 * @brief Examine STATUS_WORD value read for MFRSPECIFIC bit on. 723 * 724 * "A manufacturer specific fault or warning has occurred." 725 * 726 * If it is on, call the determineMFRFault() helper function to examine the 727 * value read from STATUS_MFR_SPECIFIC. 728 */ 729 void analyzeMFRFault(); 730 731 /** 732 * @brief Analyzes the STATUS_WORD for a VIN_UV_FAULT indicator. 733 */ 734 void analyzeVinUVFault(); 735 736 /** 737 * @brief D-Bus path to use for this power supply's inventory status. 738 **/ 739 std::string inventoryPath; 740 741 /** 742 * @brief Store the short name to avoid string processing. 743 * 744 * The short name will be something like powersupply1, the last part of the 745 * inventoryPath. 746 */ 747 std::string shortName; 748 749 /** 750 * @brief Given a full inventory path, returns the last node of the path as 751 * the "short name" 752 */ 753 std::string findShortName(const std::string& invPath) 754 { 755 auto const lastSlashPos = invPath.find_last_of('/'); 756 757 if ((lastSlashPos == std::string::npos) || 758 ((lastSlashPos + 1) == invPath.size())) 759 { 760 return invPath; 761 } 762 else 763 { 764 return invPath.substr(lastSlashPos + 1); 765 } 766 } 767 768 /** 769 * @brief The libgpiod object for monitoring PSU presence 770 */ 771 std::unique_ptr<GPIOInterfaceBase> presenceGPIO = nullptr; 772 773 /** @brief True if the power supply is present. */ 774 bool present = false; 775 776 /** @brief Power supply model name. */ 777 std::string modelName; 778 779 /** @brief D-Bus match variable used to subscribe to Present property 780 * changes. 781 **/ 782 std::unique_ptr<sdbusplus::bus::match_t> presentMatch; 783 784 /** @brief D-Bus match variable used to subscribe for Present property 785 * interface added. 786 */ 787 std::unique_ptr<sdbusplus::bus::match_t> presentAddedMatch; 788 789 /** 790 * @brief Pointer to the PMBus interface 791 * 792 * Used to read or write to/from PMBus power supply devices. 793 */ 794 std::unique_ptr<phosphor::pmbus::PMBusBase> pmbusIntf = nullptr; 795 796 /** @brief Stored copy of the firmware version/revision string */ 797 std::string fwVersion; 798 799 /** 800 * @brief The file system path used for binding the device driver. 801 */ 802 const std::filesystem::path bindPath; 803 804 /* @brief The string to pass in for binding the device driver. */ 805 std::string bindDevice; 806 807 /** 808 * @brief The result of the most recent availability check 809 * 810 * Saved on the object so changes can be detected. 811 */ 812 bool available = false; 813 814 /** 815 * @brief Binds or unbinds the power supply device driver 816 * 817 * Called when a presence change is detected to either bind the device 818 * driver for the power supply when it is installed, or unbind the device 819 * driver when the power supply is removed. 820 * 821 * Writes <device> to <path>/bind (or unbind) 822 * 823 * @param present - when true, will bind the device driver 824 * when false, will unbind the device driver 825 */ 826 void bindOrUnbindDriver(bool present); 827 828 /** 829 * @brief Updates the presence status by querying D-Bus 830 * 831 * The D-Bus inventory properties for this power supply will be read to 832 * determine if the power supply is present or not and update this 833 * object's present member variable to reflect current status. 834 **/ 835 void updatePresence(); 836 837 /** 838 * @brief Updates the power supply presence by reading the GPIO line. 839 */ 840 void updatePresenceGPIO(); 841 842 /** 843 * @brief Callback for inventory property changes 844 * 845 * Process change of Present property for power supply. 846 * 847 * This is used if we are watching the D-Bus properties instead of reading 848 * the GPIO presence line ourselves. 849 * 850 * @param[in] msg - Data associated with Present change signal 851 **/ 852 void inventoryChanged(sdbusplus::message_t& msg); 853 854 /** 855 * @brief Callback for inventory property added. 856 * 857 * Process add of the interface with the Present property for power supply. 858 * 859 * This is used if we are watching the D-Bus properties instead of reading 860 * the GPIO presence line ourselves. 861 * 862 * @param[in] msg - Data associated with Present add signal 863 **/ 864 void inventoryAdded(sdbusplus::message_t& msg); 865 866 /** 867 * @brief Reads the pmbus MFR_POUT_MAX value. 868 * 869 * "The MFR_POUT_MAX command sets or retrieves the maximum rated output 870 * power, in watts, that the unit is rated to supply." 871 * 872 * @return max_power_out value converted from string. 873 */ 874 auto getMaxPowerOut() const; 875 876 /* @brief Reads a VPD value from PMBus and corrects for size. 877 * 878 * @param[in] vpdName - The name of the sysfs "file" to read data from. 879 * @param[in] type - The HWMON file type to read from. 880 * @param[in] vpdSize - The expacted size of the data for this VPD/property 881 * 882 * @return A string containing the VPD data read, resized if necessary 883 */ 884 auto readVPDValue(const std::string& vpdName, 885 const phosphor::pmbus::Type& type, 886 const std::size_t& vpdSize); 887 888 /** 889 * @brief Reads the most recent input history record from the power supply 890 * and updates the average and maximum properties in D-Bus if there is a new 891 * reading available. 892 * 893 * This will still run every time analyze() is called so code can post new 894 * data as soon as possible and the timestamp will more accurately reflect 895 * the correct time. 896 * 897 * D-Bus is only updated if there is a change and the oldest record will be 898 * pruned if the property already contains the max number of records. 899 */ 900 void updateHistory(); 901 902 /** 903 * @brief Set to true if INPUT_HISTORY command supported. 904 * 905 * Not all power supplies will support the INPUT_HISTORY command. The IBM 906 * Common Form Factor power supplies do support this command. 907 */ 908 bool inputHistorySupported{false}; 909 910 /** 911 * @brief Set to true when INPUT_HISTORY sync is required. 912 * 913 * A power supply will need to synchronize its INPUT_HISTORY data with the 914 * other power supplies installed in the system when it goes from missing to 915 * present. 916 */ 917 bool syncHistoryRequired{false}; 918 919 /** 920 * @brief Class that manages the input power history records. 921 **/ 922 std::unique_ptr<history::RecordManager> recordManager; 923 924 /** 925 * @brief The D-Bus object for the average input power history 926 **/ 927 std::unique_ptr<history::Average> average; 928 929 /** 930 * @brief The D-Bus object for the maximum input power history 931 **/ 932 std::unique_ptr<history::Maximum> maximum; 933 934 /** 935 * @brief The base D-Bus object path to use for the average and maximum 936 * objects. 937 **/ 938 std::string historyObjectPath; 939 }; 940 941 } // namespace phosphor::power::psu 942