1abf8da36SMatt Spinler #pragma once 2abf8da36SMatt Spinler 3abf8da36SMatt Spinler #include <sdbusplus/bus.hpp> 4abf8da36SMatt Spinler #include <tuple> 5abf8da36SMatt Spinler #include <vector> 6e824f985SMatt Spinler #include "event.hpp" 7abf8da36SMatt Spinler #include "tach_sensor.hpp" 8c39e859bSMatt Spinler #include "trust_manager.hpp" 9abf8da36SMatt Spinler #include "types.hpp" 10abf8da36SMatt Spinler 11abf8da36SMatt Spinler namespace phosphor 12abf8da36SMatt Spinler { 13abf8da36SMatt Spinler namespace fan 14abf8da36SMatt Spinler { 15abf8da36SMatt Spinler namespace monitor 16abf8da36SMatt Spinler { 17abf8da36SMatt Spinler 18edaeb31cSBrad Bishop /** 196ad28430SMatthew Barth * The mode fan monitor will run in: 206ad28430SMatthew Barth * - init - only do the initialization steps 216ad28430SMatthew Barth * - monitor - run normal monitoring algorithm 226ad28430SMatthew Barth */ 236ad28430SMatthew Barth enum class Mode 246ad28430SMatthew Barth { 256ad28430SMatthew Barth init, 266ad28430SMatthew Barth monitor 276ad28430SMatthew Barth }; 286ad28430SMatthew Barth 296ad28430SMatthew Barth /** 30edaeb31cSBrad Bishop * @class InvalidSensorError 31edaeb31cSBrad Bishop * 32edaeb31cSBrad Bishop * An exception type for sensors that don't exist or 33edaeb31cSBrad Bishop * are otherwise inaccessible. 34edaeb31cSBrad Bishop */ 35edaeb31cSBrad Bishop class InvalidSensorError : public std::exception {}; 36abf8da36SMatt Spinler 37abf8da36SMatt Spinler /** 38abf8da36SMatt Spinler * @class Fan 39abf8da36SMatt Spinler * 40abf8da36SMatt Spinler * Represents a fan, which can contain 1 or more sensors which 41abf8da36SMatt Spinler * loosely correspond to rotors. See below. 42abf8da36SMatt Spinler * 43abf8da36SMatt Spinler * There is a sensor when hwmon exposes one, which means there is a 44abf8da36SMatt Spinler * speed value to be read. Sometimes there is a sensor per rotor, 45abf8da36SMatt Spinler * and other times multiple rotors just use 1 sensor total where 46abf8da36SMatt Spinler * the sensor reports the slowest speed of all of the rotors. 47abf8da36SMatt Spinler * 48abf8da36SMatt Spinler * A rotor's speed is set by writing the Target value of a sensor. 49abf8da36SMatt Spinler * Sometimes each sensor in a fan supports having a Target, and other 50abf8da36SMatt Spinler * times not all of them do. A TachSensor object knows if it supports 51abf8da36SMatt Spinler * the Target property. 52abf8da36SMatt Spinler * 53abf8da36SMatt Spinler * The strategy for monitoring fan speeds is as follows: 54abf8da36SMatt Spinler * 55abf8da36SMatt Spinler * Every time a Target (new speed written) or Input (actual speed read) 56abf8da36SMatt Spinler * sensor changes, check if the input value is within some range of the target 57abf8da36SMatt Spinler * value. If it isn't, start a timer at the end of which the sensor will be 58abf8da36SMatt Spinler * set to not functional. If enough sensors in the fan are now nonfunctional, 59abf8da36SMatt Spinler * set the whole fan to nonfunctional in the inventory. 60abf8da36SMatt Spinler * 61abf8da36SMatt Spinler * When sensor inputs come back within a specified range of the target, 62abf8da36SMatt Spinler * stop its timer if running, make the sensor functional again if it wasn't, 63abf8da36SMatt Spinler * and if enough sensors in the fan are now functional set the whole fan 64abf8da36SMatt Spinler * back to functional in the inventory. 65abf8da36SMatt Spinler */ 66abf8da36SMatt Spinler class Fan 67abf8da36SMatt Spinler { 68b1e18514SMatt Spinler using Property = std::string; 69b1e18514SMatt Spinler using Value = sdbusplus::message::variant<bool>; 70b1e18514SMatt Spinler using PropertyMap = std::map<Property, Value>; 71b1e18514SMatt Spinler 72b1e18514SMatt Spinler using Interface = std::string; 73b1e18514SMatt Spinler using InterfaceMap = std::map<Interface, PropertyMap>; 74b1e18514SMatt Spinler 75b1e18514SMatt Spinler using Object = sdbusplus::message::object_path; 76b1e18514SMatt Spinler using ObjectMap = std::map<Object, InterfaceMap>; 77abf8da36SMatt Spinler 78abf8da36SMatt Spinler public: 79abf8da36SMatt Spinler 80abf8da36SMatt Spinler Fan() = delete; 81abf8da36SMatt Spinler Fan(const Fan&) = delete; 82abf8da36SMatt Spinler Fan(Fan&&) = default; 83abf8da36SMatt Spinler Fan& operator=(const Fan&) = delete; 84abf8da36SMatt Spinler Fan& operator=(Fan&&) = default; 85abf8da36SMatt Spinler ~Fan() = default; 86abf8da36SMatt Spinler 87abf8da36SMatt Spinler /** 88abf8da36SMatt Spinler * @brief Constructor 89abf8da36SMatt Spinler * 906ad28430SMatthew Barth * @param mode - mode of fan monitor 91abf8da36SMatt Spinler * @param bus - the dbus object 92abf8da36SMatt Spinler * @param events - pointer to sd_event object 93c39e859bSMatt Spinler * @param trust - the tach trust manager 94abf8da36SMatt Spinler * @param def - the fan definition structure 95abf8da36SMatt Spinler */ 966ad28430SMatthew Barth Fan(Mode mode, 976ad28430SMatthew Barth sdbusplus::bus::bus& bus, 98e824f985SMatt Spinler phosphor::fan::event::EventPtr& events, 99c39e859bSMatt Spinler std::unique_ptr<trust::Manager>& trust, 100abf8da36SMatt Spinler const FanDefinition& def); 101abf8da36SMatt Spinler 102ebaae611SMatt Spinler /** 103ebaae611SMatt Spinler * @brief Callback function for when an input sensor changes 104ebaae611SMatt Spinler * 105ebaae611SMatt Spinler * Starts a timer, where if it expires then the sensor 106a9406a77SMatt Spinler * was out of range for too long and can be considered not functional. 107ebaae611SMatt Spinler */ 108ebaae611SMatt Spinler void tachChanged(TachSensor& sensor); 109ebaae611SMatt Spinler 110ebaae611SMatt Spinler /** 111ebaae611SMatt Spinler * @brief Calls tachChanged(sensor) on each sensor 112ebaae611SMatt Spinler */ 113ebaae611SMatt Spinler void tachChanged(); 114abf8da36SMatt Spinler 115a9406a77SMatt Spinler /** 116a9406a77SMatt Spinler * @brief The callback function for the timer 117a9406a77SMatt Spinler * 118a9406a77SMatt Spinler * Sets the sensor to not functional. 119a9406a77SMatt Spinler * If enough sensors are now not functional, 120a9406a77SMatt Spinler * updates the functional status of the whole 121a9406a77SMatt Spinler * fan in the inventory. 122a9406a77SMatt Spinler * 123a9406a77SMatt Spinler * @param[in] sensor - the sensor whose timer expired 124a9406a77SMatt Spinler */ 125a9406a77SMatt Spinler void timerExpired(TachSensor& sensor); 126a9406a77SMatt Spinler 127*4d982856SMatthew Barth /** 128*4d982856SMatthew Barth * @brief Get the name of the fan 129*4d982856SMatthew Barth * 130*4d982856SMatthew Barth * @return - The fan name 131*4d982856SMatthew Barth */ 132*4d982856SMatthew Barth inline const std::string& getName() const 133*4d982856SMatthew Barth { 134*4d982856SMatthew Barth return _name; 135*4d982856SMatthew Barth } 136*4d982856SMatthew Barth 137abf8da36SMatt Spinler private: 138abf8da36SMatt Spinler 139abf8da36SMatt Spinler /** 140abf8da36SMatt Spinler * @brief Returns the target speed of the sensor 141abf8da36SMatt Spinler * 142abf8da36SMatt Spinler * If the sensor itself doesn't have a target, it finds 143abf8da36SMatt Spinler * the target speed from another sensor. 144abf8da36SMatt Spinler * 145abf8da36SMatt Spinler * @param[in] sensor - the sensor to get the target speed for 146abf8da36SMatt Spinler */ 147abf8da36SMatt Spinler uint64_t getTargetSpeed(const TachSensor& sensor); 148abf8da36SMatt Spinler 149abf8da36SMatt Spinler /** 150abf8da36SMatt Spinler * @brief Returns true if the sensor input is not within 151abf8da36SMatt Spinler * some deviation of the target. 152abf8da36SMatt Spinler * 153abf8da36SMatt Spinler * @param[in] sensor - the sensor to check 154abf8da36SMatt Spinler */ 155abf8da36SMatt Spinler bool outOfRange(const TachSensor& sensor); 156abf8da36SMatt Spinler 157abf8da36SMatt Spinler /** 158abf8da36SMatt Spinler * @brief Returns true if too many sensors are nonfunctional 159abf8da36SMatt Spinler * as defined by _numSensorFailsForNonFunc 160abf8da36SMatt Spinler */ 161abf8da36SMatt Spinler bool tooManySensorsNonfunctional(); 162abf8da36SMatt Spinler 163b1e18514SMatt Spinler /** 164b1e18514SMatt Spinler * @brief Updates the Functional property in the inventory 165b1e18514SMatt Spinler * for the fan based on the value passed in. 166b1e18514SMatt Spinler * 167b1e18514SMatt Spinler * @param[in] functional - If the Functional property should 168b1e18514SMatt Spinler * be set to true or false. 169b1e18514SMatt Spinler */ 170b1e18514SMatt Spinler void updateInventory(bool functional); 171b1e18514SMatt Spinler 172b1e18514SMatt Spinler /** 173abf8da36SMatt Spinler * @brief the dbus object 174abf8da36SMatt Spinler */ 175abf8da36SMatt Spinler sdbusplus::bus::bus& _bus; 176abf8da36SMatt Spinler 177abf8da36SMatt Spinler /** 178abf8da36SMatt Spinler * @brief The inventory name of the fan 179abf8da36SMatt Spinler */ 180abf8da36SMatt Spinler const std::string _name; 181abf8da36SMatt Spinler 182abf8da36SMatt Spinler /** 183abf8da36SMatt Spinler * @brief The percentage that the input speed must be below 184abf8da36SMatt Spinler * the target speed to be considered an error. 185abf8da36SMatt Spinler * Between 0 and 100. 186abf8da36SMatt Spinler */ 187abf8da36SMatt Spinler const size_t _deviation; 188abf8da36SMatt Spinler 189abf8da36SMatt Spinler /** 190abf8da36SMatt Spinler * The number of sensors that must be nonfunctional at the 191abf8da36SMatt Spinler * same time in order for the fan to be set to nonfunctional 192abf8da36SMatt Spinler * in the inventory. 193abf8da36SMatt Spinler */ 194abf8da36SMatt Spinler const size_t _numSensorFailsForNonFunc; 195abf8da36SMatt Spinler 196abf8da36SMatt Spinler /** 197abf8da36SMatt Spinler * @brief The current functional state of the fan 198abf8da36SMatt Spinler */ 199abf8da36SMatt Spinler bool _functional = true; 200abf8da36SMatt Spinler 201abf8da36SMatt Spinler /** 202abf8da36SMatt Spinler * The sensor objects for the fan 203abf8da36SMatt Spinler */ 204abf8da36SMatt Spinler std::vector<std::unique_ptr<TachSensor>> _sensors; 205c39e859bSMatt Spinler 206c39e859bSMatt Spinler /** 207c39e859bSMatt Spinler * The tach trust manager object 208c39e859bSMatt Spinler */ 209c39e859bSMatt Spinler std::unique_ptr<trust::Manager>& _trustManager; 210abf8da36SMatt Spinler }; 211abf8da36SMatt Spinler 212abf8da36SMatt Spinler } 213abf8da36SMatt Spinler } 214abf8da36SMatt Spinler } 215