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