1 /** 2 * Copyright © 2021 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include "../zone.hpp" 19 #include "action.hpp" 20 #include "group.hpp" 21 #include "utils/pcie_card_metadata.hpp" 22 23 #include <nlohmann/json.hpp> 24 25 namespace phosphor::fan::control::json 26 { 27 28 using json = nlohmann::json; 29 30 class Manager; 31 32 /** 33 * @class PCIeCardFloors - Action to set the PCIe card floor index parameter 34 * based on the PCIe cards plugged in the system. 35 * 36 * - Loads PCIe card metadata files using the PCIeCardMetadata class. 37 * - Watches for PCIe slots to be powered on (or off). 38 * - Reads four properties off of the PCIeDevice interface on the powered 39 * on cards. 40 * - Looks up the floor index for the card by calling PCIeCardMetadata::lookup 41 * and passing in the PCIeDevice properties. 42 * - Sets the pcie_floor_index parameter with the highest floor index found. 43 * - If no PCIe cards are found, it removes the parameter. 44 * - If a card isn't recognized, it's ignored since it isn't considered a 45 * hot card. 46 * - If a powered on card has its own temperature sensor, then it doesn't 47 * have a floor index. 48 * - Since the slot powered on indications are all sent at once, it has a 49 * small delay that gets started in each run() call that must expire 50 * before the body of the action is run, so it only runs once. 51 * 52 * The JSON configuration has two entries: 53 * { 54 * "settle_time": <time in s> 55 * "use_config_specific_files": <true/false> 56 * } 57 * 58 * settle_time: 59 * - Specifies how long to wait after run() is called before actually 60 * running the action as a flurry of propertiesChanged signals 61 * that trigger the action tend to come at once. 62 * - Optional. If not specified it defaults to zero. 63 * 64 * use_config_specific_files: 65 * - If true, will look for 'pcie_cards.json' files in the system 66 * specific directories. 67 * - See PCIeCardMetadata for details. 68 */ 69 class PCIeCardFloors : public ActionBase, public ActionRegister<PCIeCardFloors> 70 { 71 public: 72 /* Name of this action */ 73 static constexpr auto name = "pcie_card_floors"; 74 75 PCIeCardFloors() = delete; 76 PCIeCardFloors(const PCIeCardFloors&) = delete; 77 PCIeCardFloors(PCIeCardFloors&&) = delete; 78 PCIeCardFloors& operator=(const PCIeCardFloors&) = delete; 79 PCIeCardFloors& operator=(PCIeCardFloors&&) = delete; 80 ~PCIeCardFloors() = default; 81 82 /** 83 * @brief Read in the action configuration 84 * 85 * @param[in] jsonObj - JSON configuration of this action 86 * @param[in] groups - Groups of dbus objects the action uses 87 */ 88 PCIeCardFloors(const json& jsonObj, const std::vector<Group>& groups); 89 90 /** 91 * @brief Run the action. 92 * 93 * Starts/restarts the settle timer and then calls execute() 94 * when it expires. Done to handle the flood of slot powered 95 * on/off signals. 96 * 97 * @param[in] zone - Zone to run the action on 98 */ 99 void run(Zone& zone) override; 100 101 private: 102 /** 103 * @brief Runs the contents of the action when the settle timer expires. 104 * 105 * @param[in] zone - Zone to run the action on 106 */ 107 void execute(Zone& zone); 108 109 /** 110 * @brief Constructs the PCIeCardMetadata object to load the PCIe card 111 * JSON files. 112 * 113 * @param[in] jsonObj - JSON configuration of this action 114 */ 115 void loadCardJSON(const json& jsonObj); 116 117 /** 118 * @brief Returns the D-Bus object path of the card plugged into 119 * the slot represented by the slotPath D-Bus path. 120 * 121 * @param[in] slotPath - The D-Bus path of the PCIe slot object. 122 * 123 * @return const std::string& - The card object path. 124 */ 125 const std::string& getCardFromSlot(const std::string& slotPath); 126 127 /** 128 * @brief Returns the floor index (or temp sensor name) for the 129 * card in the passed in slot. 130 * 131 * @param[in] slotPath - The D-Bus path of the PCIe slot object. 132 * 133 * @return optional<variant<int32_t, string>> 134 * - The floor index or true for has temp sensor if found, 135 * std::nullopt else. 136 */ 137 std::optional<std::variant<int32_t, bool>> 138 getFloorIndexFromSlot(const std::string& slotPath); 139 140 /** 141 * @brief Gets the hex PCIeDevice property value from the 142 * manager object cache. 143 * 144 * @param[in] objectPath - The card object path 145 * @param[in] propertyName - The property to read 146 * 147 * @return uint16_t The property value 148 */ 149 uint16_t getPCIeDeviceProperty(const std::string& objectPath, 150 const std::string& propertyName); 151 152 /* The PCIe card metadata manager */ 153 std::unique_ptr<PCIeCardMetadata> _cardMetadata; 154 155 /* Cache map of PCIe slot paths to their plugged card paths */ 156 std::unordered_map<std::string, std::string> _cards; 157 158 /* Cache of all objects with a PCIeDevice interface. */ 159 std::vector<std::string> _pcieDevices; 160 161 std::chrono::seconds _settleTime{0}; 162 163 /* Timer to wait for slot plugs to settle down before running action */ 164 std::unique_ptr<Timer> _settleTimer; 165 166 /* Last status printed so only new messages get recorded */ 167 std::string _lastStatus; 168 }; 169 170 } // namespace phosphor::fan::control::json 171