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