1*abf8da36SMatt Spinler #pragma once 2*abf8da36SMatt Spinler 3*abf8da36SMatt Spinler #include <sdbusplus/bus.hpp> 4*abf8da36SMatt Spinler #include <tuple> 5*abf8da36SMatt Spinler #include <vector> 6*abf8da36SMatt Spinler #include "tach_sensor.hpp" 7*abf8da36SMatt Spinler #include "types.hpp" 8*abf8da36SMatt Spinler 9*abf8da36SMatt Spinler namespace phosphor 10*abf8da36SMatt Spinler { 11*abf8da36SMatt Spinler namespace fan 12*abf8da36SMatt Spinler { 13*abf8da36SMatt Spinler namespace monitor 14*abf8da36SMatt Spinler { 15*abf8da36SMatt Spinler 16*abf8da36SMatt Spinler 17*abf8da36SMatt Spinler /** 18*abf8da36SMatt Spinler * @class Fan 19*abf8da36SMatt Spinler * 20*abf8da36SMatt Spinler * Represents a fan, which can contain 1 or more sensors which 21*abf8da36SMatt Spinler * loosely correspond to rotors. See below. 22*abf8da36SMatt Spinler * 23*abf8da36SMatt Spinler * There is a sensor when hwmon exposes one, which means there is a 24*abf8da36SMatt Spinler * speed value to be read. Sometimes there is a sensor per rotor, 25*abf8da36SMatt Spinler * and other times multiple rotors just use 1 sensor total where 26*abf8da36SMatt Spinler * the sensor reports the slowest speed of all of the rotors. 27*abf8da36SMatt Spinler * 28*abf8da36SMatt Spinler * A rotor's speed is set by writing the Target value of a sensor. 29*abf8da36SMatt Spinler * Sometimes each sensor in a fan supports having a Target, and other 30*abf8da36SMatt Spinler * times not all of them do. A TachSensor object knows if it supports 31*abf8da36SMatt Spinler * the Target property. 32*abf8da36SMatt Spinler * 33*abf8da36SMatt Spinler * The strategy for monitoring fan speeds is as follows: 34*abf8da36SMatt Spinler * 35*abf8da36SMatt Spinler * Every time a Target (new speed written) or Input (actual speed read) 36*abf8da36SMatt Spinler * sensor changes, check if the input value is within some range of the target 37*abf8da36SMatt Spinler * value. If it isn't, start a timer at the end of which the sensor will be 38*abf8da36SMatt Spinler * set to not functional. If enough sensors in the fan are now nonfunctional, 39*abf8da36SMatt Spinler * set the whole fan to nonfunctional in the inventory. 40*abf8da36SMatt Spinler * 41*abf8da36SMatt Spinler * When sensor inputs come back within a specified range of the target, 42*abf8da36SMatt Spinler * stop its timer if running, make the sensor functional again if it wasn't, 43*abf8da36SMatt Spinler * and if enough sensors in the fan are now functional set the whole fan 44*abf8da36SMatt Spinler * back to functional in the inventory. 45*abf8da36SMatt Spinler */ 46*abf8da36SMatt Spinler class Fan 47*abf8da36SMatt Spinler { 48*abf8da36SMatt Spinler 49*abf8da36SMatt Spinler public: 50*abf8da36SMatt Spinler 51*abf8da36SMatt Spinler Fan() = delete; 52*abf8da36SMatt Spinler Fan(const Fan&) = delete; 53*abf8da36SMatt Spinler Fan(Fan&&) = default; 54*abf8da36SMatt Spinler Fan& operator=(const Fan&) = delete; 55*abf8da36SMatt Spinler Fan& operator=(Fan&&) = default; 56*abf8da36SMatt Spinler ~Fan() = default; 57*abf8da36SMatt Spinler 58*abf8da36SMatt Spinler /** 59*abf8da36SMatt Spinler * @brief Constructor 60*abf8da36SMatt Spinler * 61*abf8da36SMatt Spinler * @param bus - the dbus object 62*abf8da36SMatt Spinler * @param events - pointer to sd_event object 63*abf8da36SMatt Spinler * @param def - the fan definition structure 64*abf8da36SMatt Spinler */ 65*abf8da36SMatt Spinler Fan(sdbusplus::bus::bus& bus, 66*abf8da36SMatt Spinler std::shared_ptr<sd_event>& events, 67*abf8da36SMatt Spinler const FanDefinition& def); 68*abf8da36SMatt Spinler 69*abf8da36SMatt Spinler 70*abf8da36SMatt Spinler private: 71*abf8da36SMatt Spinler 72*abf8da36SMatt Spinler /** 73*abf8da36SMatt Spinler * @brief Returns the target speed of the sensor 74*abf8da36SMatt Spinler * 75*abf8da36SMatt Spinler * If the sensor itself doesn't have a target, it finds 76*abf8da36SMatt Spinler * the target speed from another sensor. 77*abf8da36SMatt Spinler * 78*abf8da36SMatt Spinler * @param[in] sensor - the sensor to get the target speed for 79*abf8da36SMatt Spinler */ 80*abf8da36SMatt Spinler uint64_t getTargetSpeed(const TachSensor& sensor); 81*abf8da36SMatt Spinler 82*abf8da36SMatt Spinler /** 83*abf8da36SMatt Spinler * @brief Returns true if the sensor input is not within 84*abf8da36SMatt Spinler * some deviation of the target. 85*abf8da36SMatt Spinler * 86*abf8da36SMatt Spinler * @param[in] sensor - the sensor to check 87*abf8da36SMatt Spinler */ 88*abf8da36SMatt Spinler bool outOfRange(const TachSensor& sensor); 89*abf8da36SMatt Spinler 90*abf8da36SMatt Spinler /** 91*abf8da36SMatt Spinler * @brief Returns true if too many sensors are nonfunctional 92*abf8da36SMatt Spinler * as defined by _numSensorFailsForNonFunc 93*abf8da36SMatt Spinler */ 94*abf8da36SMatt Spinler bool tooManySensorsNonfunctional(); 95*abf8da36SMatt Spinler 96*abf8da36SMatt Spinler 97*abf8da36SMatt Spinler /** 98*abf8da36SMatt Spinler * @brief the dbus object 99*abf8da36SMatt Spinler */ 100*abf8da36SMatt Spinler sdbusplus::bus::bus& _bus; 101*abf8da36SMatt Spinler 102*abf8da36SMatt Spinler /** 103*abf8da36SMatt Spinler * @brief The inventory name of the fan 104*abf8da36SMatt Spinler */ 105*abf8da36SMatt Spinler const std::string _name; 106*abf8da36SMatt Spinler 107*abf8da36SMatt Spinler /** 108*abf8da36SMatt Spinler * @brief The percentage that the input speed must be below 109*abf8da36SMatt Spinler * the target speed to be considered an error. 110*abf8da36SMatt Spinler * Between 0 and 100. 111*abf8da36SMatt Spinler */ 112*abf8da36SMatt Spinler const size_t _deviation; 113*abf8da36SMatt Spinler 114*abf8da36SMatt Spinler /** 115*abf8da36SMatt Spinler * The number of sensors that must be nonfunctional at the 116*abf8da36SMatt Spinler * same time in order for the fan to be set to nonfunctional 117*abf8da36SMatt Spinler * in the inventory. 118*abf8da36SMatt Spinler */ 119*abf8da36SMatt Spinler const size_t _numSensorFailsForNonFunc; 120*abf8da36SMatt Spinler 121*abf8da36SMatt Spinler /** 122*abf8da36SMatt Spinler * @brief The current functional state of the fan 123*abf8da36SMatt Spinler */ 124*abf8da36SMatt Spinler bool _functional = true; 125*abf8da36SMatt Spinler 126*abf8da36SMatt Spinler /** 127*abf8da36SMatt Spinler * The sensor objects for the fan 128*abf8da36SMatt Spinler */ 129*abf8da36SMatt Spinler std::vector<std::unique_ptr<TachSensor>> _sensors; 130*abf8da36SMatt Spinler }; 131*abf8da36SMatt Spinler 132*abf8da36SMatt Spinler } 133*abf8da36SMatt Spinler } 134*abf8da36SMatt Spinler } 135