Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 1 | #pragma once |
| 2 | |
Tony Lee | 84d430c | 2019-06-13 15:26:15 +0800 | [diff] [blame] | 3 | #include "config.h" |
| 4 | |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 5 | #include "nvmes.hpp" |
Tony Lee | 8965921 | 2019-06-21 17:34:14 +0800 | [diff] [blame] | 6 | #include "sdbusplus.hpp" |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 7 | |
Tony Lee | 84d430c | 2019-06-13 15:26:15 +0800 | [diff] [blame] | 8 | #include <sdbusplus/bus.hpp> |
| 9 | #include <sdbusplus/server.hpp> |
| 10 | #include <sdbusplus/server/object.hpp> |
| 11 | #include <sdeventplus/clock.hpp> |
| 12 | #include <sdeventplus/event.hpp> |
| 13 | #include <sdeventplus/utility/timer.hpp> |
| 14 | |
Patrick Williams | 7da9858 | 2023-05-10 07:50:46 -0500 | [diff] [blame] | 15 | #include <fstream> |
| 16 | |
Tony Lee | 84d430c | 2019-06-13 15:26:15 +0800 | [diff] [blame] | 17 | namespace phosphor |
| 18 | { |
| 19 | namespace nvme |
| 20 | { |
| 21 | |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 22 | /** @class Nvme |
| 23 | * @brief Nvme manager implementation. |
| 24 | */ |
Tony Lee | 84d430c | 2019-06-13 15:26:15 +0800 | [diff] [blame] | 25 | class Nvme |
| 26 | { |
| 27 | public: |
| 28 | Nvme() = delete; |
| 29 | Nvme(const Nvme&) = delete; |
| 30 | Nvme& operator=(const Nvme&) = delete; |
| 31 | Nvme(Nvme&&) = delete; |
| 32 | Nvme& operator=(Nvme&&) = delete; |
| 33 | |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 34 | /** @brief Constructs Nvme |
| 35 | * |
| 36 | * @param[in] bus - Handle to system dbus |
Tony Lee | 8965921 | 2019-06-21 17:34:14 +0800 | [diff] [blame] | 37 | * @param[in] objPath - The dbus path of nvme |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 38 | */ |
Patrick Williams | 7ce68bc | 2022-07-22 19:26:55 -0500 | [diff] [blame] | 39 | Nvme(sdbusplus::bus_t& bus) : |
Tony Lee | 84d430c | 2019-06-13 15:26:15 +0800 | [diff] [blame] | 40 | bus(bus), _event(sdeventplus::Event::get_default()), |
| 41 | _timer(_event, std::bind(&Nvme::read, this)) |
| 42 | { |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 43 | // read json file |
| 44 | configs = getNvmeConfig(); |
Tony Lee | 84d430c | 2019-06-13 15:26:15 +0800 | [diff] [blame] | 45 | } |
| 46 | |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 47 | /** |
| 48 | * Structure for keeping nvme configure data required by nvme monitoring |
| 49 | */ |
| 50 | struct NVMeConfig |
| 51 | { |
| 52 | std::string index; |
| 53 | uint8_t busID; |
Tony Lee | 8965921 | 2019-06-21 17:34:14 +0800 | [diff] [blame] | 54 | std::string faultLedGroupPath; |
George Hung | 873b5b3 | 2020-06-20 14:56:15 +0800 | [diff] [blame] | 55 | uint16_t presentPin; |
| 56 | uint16_t pwrGoodPin; |
Tony Lee | 8965921 | 2019-06-21 17:34:14 +0800 | [diff] [blame] | 57 | std::string locateLedControllerBusName; |
| 58 | std::string locateLedControllerPath; |
| 59 | std::string locateLedGroupPath; |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 60 | int8_t criticalHigh; |
| 61 | int8_t criticalLow; |
| 62 | int8_t maxValue; |
| 63 | int8_t minValue; |
| 64 | int8_t warningHigh; |
| 65 | int8_t warningLow; |
| 66 | }; |
| 67 | |
| 68 | /** |
| 69 | * Structure for keeping nvme data required by nvme monitoring |
| 70 | */ |
| 71 | struct NVMeData |
| 72 | { |
| 73 | bool present; /* Whether or not the nvme is present */ |
| 74 | std::string vendor; /* The nvme manufacturer */ |
| 75 | std::string serialNumber; /* The nvme serial number */ |
George Hung | 92a15ba | 2020-09-14 17:14:52 +0800 | [diff] [blame] | 76 | std::string modelNumber; /* The nvme model number */ |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 77 | std::string smartWarnings; /* Indicates smart warnings for the state */ |
| 78 | std::string statusFlags; /* Indicates the status of the drives */ |
| 79 | std::string |
| 80 | driveLifeUsed; /* A vendor specific estimate of the percentage */ |
| 81 | int8_t sensorValue; /* Sensor value, if sensor value didn't be |
| 82 | update, means sensor failure, default set to |
Manojkiran Eda | 3b2e5a9 | 2024-06-17 14:47:39 +0530 | [diff] [blame] | 83 | 129(0x81) according to NVMe-MI SPEC*/ |
George Hung | 9345533 | 2021-01-06 20:57:04 +0800 | [diff] [blame] | 84 | int8_t wcTemp; /* Indicates over temperature warning threshold. |
| 85 | This is intended to initially match the temperature |
| 86 | reported in the WCTEMP field in the NVMe Identify |
| 87 | Controller data structure */ |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 88 | }; |
| 89 | |
| 90 | /** @brief Setup polling timer in a sd event loop and attach to D-Bus |
| 91 | * event loop. |
| 92 | */ |
Tony Lee | 84d430c | 2019-06-13 15:26:15 +0800 | [diff] [blame] | 93 | void run(); |
| 94 | |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 95 | /** @brief Get GPIO value of nvme by sysfs */ |
| 96 | std::string getGPIOValueOfNvme(const std::string& fullPath); |
| 97 | /** @brief Map of the object NvmeSSD */ |
| 98 | std::unordered_map<std::string, std::shared_ptr<phosphor::nvme::NvmeSSD>> |
| 99 | nvmes; |
Tony Lee | 84d430c | 2019-06-13 15:26:15 +0800 | [diff] [blame] | 100 | |
Tony Lee | 8965921 | 2019-06-21 17:34:14 +0800 | [diff] [blame] | 101 | /** @brief Set locate and fault LED status of SSD |
| 102 | * |
| 103 | * @param[in] config - Nvme configure data |
| 104 | * @param[in] success - Success or not that get NVMe Info by SMbus |
| 105 | * @param[in] nvmeData - Nvme information |
| 106 | */ |
| 107 | void setLEDsStatus(const phosphor::nvme::Nvme::NVMeConfig& config, |
| 108 | bool success, |
| 109 | const phosphor::nvme::Nvme::NVMeData& nvmeData); |
| 110 | |
| 111 | /** @brief Set SSD fault LED status */ |
| 112 | void setFaultLED(const std::string& locateLedGroupPath, |
| 113 | const std::string& ledPath, bool request); |
| 114 | /** @brief Set SSD locate LED status */ |
| 115 | void setLocateLED(const std::string& ledPath, |
| 116 | const std::string& locateLedBusName, |
| 117 | const std::string& locateLedPath, bool ispresent); |
| 118 | /** @brief Get Identify State*/ |
| 119 | bool getLEDGroupState(const std::string& ledPath); |
| 120 | |
| 121 | /** @brief Set inventory properties of nvme */ |
| 122 | void setNvmeInventoryProperties( |
Chanh Nguyen | e528b0a | 2021-07-14 16:57:57 +0700 | [diff] [blame] | 123 | NVMeConfig& config, bool present, |
| 124 | const phosphor::nvme::Nvme::NVMeData& nvmeData, |
Tony Lee | 8965921 | 2019-06-21 17:34:14 +0800 | [diff] [blame] | 125 | const std::string& inventoryPath); |
| 126 | |
| 127 | void createNVMeInventory(); |
| 128 | |
George Hung | 5e23bcd | 2021-07-01 12:16:11 +0800 | [diff] [blame] | 129 | /** @brief read NVMe information via Smbus */ |
| 130 | bool getNVMeInfobyBusID(int busID, |
| 131 | phosphor::nvme::Nvme::NVMeData& nvmeData); |
| 132 | |
Vijay Khemka | e41b2e4 | 2020-04-21 09:23:10 -0700 | [diff] [blame] | 133 | /** @brief read and update NVME data to dbus */ |
Potin Lai | 0314473 | 2023-02-14 22:20:38 +0800 | [diff] [blame] | 134 | void readNvmeData(NVMeConfig& config, bool isPwrGood); |
Vijay Khemka | e41b2e4 | 2020-04-21 09:23:10 -0700 | [diff] [blame] | 135 | |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 136 | private: |
| 137 | /** @brief sdbusplus bus client connection. */ |
Patrick Williams | 7ce68bc | 2022-07-22 19:26:55 -0500 | [diff] [blame] | 138 | sdbusplus::bus_t& bus; |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 139 | /** @brief the Event Loop structure */ |
Tony Lee | 84d430c | 2019-06-13 15:26:15 +0800 | [diff] [blame] | 140 | sdeventplus::Event _event; |
| 141 | /** @brief Read Timer */ |
| 142 | sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> _timer; |
| 143 | |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 144 | std::vector<phosphor::nvme::Nvme::NVMeConfig> configs; |
| 145 | |
George Hung | 5e23bcd | 2021-07-01 12:16:11 +0800 | [diff] [blame] | 146 | /** @brief error status for Smbus */ |
| 147 | std::unordered_map<int, bool> isErrorSmbus; |
| 148 | /** @brief error status for LED */ |
| 149 | std::unordered_map<std::string, bool> isError; |
| 150 | /** @brief error status for NVMe power*/ |
| 151 | std::unordered_map<std::string, bool> isErrorPower; |
| 152 | |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 153 | /** @brief Set up initial configuration value of NVMe */ |
Tony Lee | 84d430c | 2019-06-13 15:26:15 +0800 | [diff] [blame] | 154 | void init(); |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 155 | /** @brief Monitor NVMe drives every one second */ |
Tony Lee | 84d430c | 2019-06-13 15:26:15 +0800 | [diff] [blame] | 156 | void read(); |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 157 | |
| 158 | std::vector<phosphor::nvme::Nvme::NVMeConfig> getNvmeConfig(); |
Potin Lai | bcae087 | 2022-10-20 15:29:17 +0800 | [diff] [blame] | 159 | |
| 160 | /** @brief Monitor interval in second */ |
| 161 | size_t monitorIntervalSec; |
Potin Lai | 6e149e9 | 2022-11-23 10:04:05 +0800 | [diff] [blame] | 162 | /** @brief Maximum smbus error retry */ |
| 163 | uint16_t maxSmbusErrorRetry; |
| 164 | /** @brief Map of each NVMe smbus error count */ |
| 165 | std::unordered_map<int, uint16_t> nvmeSmbusErrCnt; |
Tony Lee | 84d430c | 2019-06-13 15:26:15 +0800 | [diff] [blame] | 166 | }; |
| 167 | } // namespace nvme |
Tony Lee | 6c59501 | 2019-06-19 10:54:59 +0800 | [diff] [blame] | 168 | } // namespace phosphor |