blob: 7e0fefdfd79c380c527520283bbc3186143f28b1 [file] [log] [blame]
Tony Lee84d430c2019-06-13 15:26:15 +08001#include "nvme_manager.hpp"
2
Tony Lee6c595012019-06-19 10:54:59 +08003#include "smbus.hpp"
4
5#include <filesystem>
6#include <map>
7#include <nlohmann/json.hpp>
Tony Lee84d430c2019-06-13 15:26:15 +08008#include <phosphor-logging/elog-errors.hpp>
9#include <phosphor-logging/log.hpp>
Tony Lee89659212019-06-21 17:34:14 +080010#include <sdbusplus/message.hpp>
Tony Lee6c595012019-06-19 10:54:59 +080011#include <sstream>
12#include <string>
Tony Lee89659212019-06-21 17:34:14 +080013#include <xyz/openbmc_project/Led/Physical/server.hpp>
Tony Lee84d430c2019-06-13 15:26:15 +080014
Tony Lee6c595012019-06-19 10:54:59 +080015#include "i2c.h"
Tony Lee84d430c2019-06-13 15:26:15 +080016#define MONITOR_INTERVAL_SECONDS 1
Tony Lee6c595012019-06-19 10:54:59 +080017#define NVME_SSD_SLAVE_ADDRESS 0x6a
18#define GPIO_BASE_PATH "/sys/class/gpio/gpio"
19#define IS_PRESENT "0"
20#define POWERGD "1"
Tony Lee89659212019-06-21 17:34:14 +080021#define NOWARNING_STRING "ff"
Tony Lee6c595012019-06-19 10:54:59 +080022
23static constexpr auto configFile = "/etc/nvme/nvme_config.json";
24static constexpr auto delay = std::chrono::milliseconds{100};
25using Json = nlohmann::json;
26
27static constexpr const uint8_t COMMAND_CODE_0 = 0;
28static constexpr const uint8_t COMMAND_CODE_8 = 8;
29
Tony Lee89659212019-06-21 17:34:14 +080030static constexpr int CapacityFaultMask = 1;
31static constexpr int temperatureFaultMask = 1 << 1;
32static constexpr int DegradesFaultMask = 1 << 2;
33static constexpr int MediaFaultMask = 1 << 3;
34static constexpr int BackupDeviceFaultMask = 1 << 4;
35static constexpr int NOWARNING = 255;
36
Tony Lee6c595012019-06-19 10:54:59 +080037static constexpr int SERIALNUMBER_START_INDEX = 3;
38static constexpr int SERIALNUMBER_END_INDEX = 23;
39
40static constexpr const int TEMPERATURE_SENSOR_FAILURE = 0x81;
41
George Hung69b96182020-08-20 17:19:56 +080042static std::map<std::string, std::string> map_vendor = {{"80 86", "Intel"},
43 {"14 4d", "Samsung"}};
44
Tony Lee6c595012019-06-19 10:54:59 +080045namespace fs = std::filesystem;
46
Tony Lee84d430c2019-06-13 15:26:15 +080047namespace phosphor
48{
49namespace nvme
50{
51
52using namespace std;
53using namespace phosphor::logging;
54
Tony Lee89659212019-06-21 17:34:14 +080055void Nvme::setNvmeInventoryProperties(
56 bool present, const phosphor::nvme::Nvme::NVMeData& nvmeData,
57 const std::string& inventoryPath)
58{
59 util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
60 ITEM_IFACE, "Present", present);
61 util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
62 ASSET_IFACE, "Manufacturer", nvmeData.vendor);
63 util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
64 ASSET_IFACE, "SerialNumber",
65 nvmeData.serialNumber);
66 util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
67 NVME_STATUS_IFACE, "SmartWarnings",
68 nvmeData.smartWarnings);
69 util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
70 NVME_STATUS_IFACE, "StatusFlags",
71 nvmeData.statusFlags);
72 util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
73 NVME_STATUS_IFACE, "DriveLifeUsed",
74 nvmeData.driveLifeUsed);
75
76 auto smartWarning = (!nvmeData.smartWarnings.empty())
77 ? std::stoi(nvmeData.smartWarnings, 0, 16)
78 : NOWARNING;
79
80 util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
81 NVME_STATUS_IFACE, "CapacityFault",
82 !(smartWarning & CapacityFaultMask));
83
84 util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
85 NVME_STATUS_IFACE, "TemperatureFault",
86 !(smartWarning & temperatureFaultMask));
87
88 util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
89 NVME_STATUS_IFACE, "DegradesFault",
90 !(smartWarning & DegradesFaultMask));
91
92 util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
93 NVME_STATUS_IFACE, "MediaFault",
94 !(smartWarning & MediaFaultMask));
95
96 util::SDBusPlus::setProperty(bus, INVENTORY_BUSNAME, inventoryPath,
97 NVME_STATUS_IFACE, "BackupDeviceFault",
98 !(smartWarning & BackupDeviceFaultMask));
99}
100
101void Nvme::setFaultLED(const std::string& locateLedGroupPath,
102 const std::string& faultLedGroupPath, bool request)
103{
104 if (locateLedGroupPath.empty() || faultLedGroupPath.empty())
105 {
106 return;
107 }
108
109 // Before toggle LED, check whether is Identify or not.
110 if (!getLEDGroupState(locateLedGroupPath))
111 {
112 util::SDBusPlus::setProperty(bus, LED_GROUP_BUSNAME, faultLedGroupPath,
113 LED_GROUP_IFACE, "Asserted", request);
114 }
115}
116
117void Nvme::setLocateLED(const std::string& locateLedGroupPath,
118 const std::string& locateLedBusName,
119 const std::string& locateLedPath, bool isPresent)
120{
121 if (locateLedGroupPath.empty() || locateLedBusName.empty() ||
122 locateLedPath.empty())
123 {
124 return;
125 }
126
127 namespace server = sdbusplus::xyz::openbmc_project::Led::server;
128
129 if (!getLEDGroupState(locateLedGroupPath))
130 {
131 if (isPresent)
132 util::SDBusPlus::setProperty(
133 bus, locateLedBusName, locateLedPath, LED_CONTROLLER_IFACE,
134 "State",
135 server::convertForMessage(server::Physical::Action::On));
136 else
137 util::SDBusPlus::setProperty(
138 bus, locateLedBusName, locateLedPath, LED_CONTROLLER_IFACE,
139 "State",
140 server::convertForMessage(server::Physical::Action::Off));
141 }
142}
143
144bool Nvme::getLEDGroupState(const std::string& ledPath)
145{
146 auto asserted = util::SDBusPlus::getProperty<bool>(
147 bus, LED_GROUP_BUSNAME, ledPath, LED_GROUP_IFACE, "Asserted");
148
149 return asserted;
150}
151
152void Nvme::setLEDsStatus(const phosphor::nvme::Nvme::NVMeConfig& config,
153 bool success,
154 const phosphor::nvme::Nvme::NVMeData& nvmeData)
155{
156 static std::unordered_map<std::string, bool> isError;
157
158 if (success)
159 {
160 if (!nvmeData.smartWarnings.empty())
161 {
162 auto request =
163 (strcmp(nvmeData.smartWarnings.c_str(), NOWARNING_STRING) == 0)
164 ? false
165 : true;
166
167 setFaultLED(config.locateLedGroupPath, config.faultLedGroupPath,
168 request);
169 setLocateLED(config.locateLedGroupPath,
170 config.locateLedControllerBusName,
171 config.locateLedControllerPath, !request);
172 }
173 isError[config.index] = false;
174 }
175 else
176 {
177 if (isError[config.index] != true)
178 {
179 // Drive is present but can not get data, turn on fault LED.
180 log<level::ERR>("Drive status is good but can not get data.",
181 entry("objPath = %s", config.index.c_str()));
182 isError[config.index] = true;
183 }
184
185 setFaultLED(config.locateLedGroupPath, config.faultLedGroupPath, true);
186 setLocateLED(config.locateLedGroupPath,
187 config.locateLedControllerBusName,
188 config.locateLedControllerPath, false);
189 }
190}
191
Tony Lee6c595012019-06-19 10:54:59 +0800192std::string intToHex(int input)
193{
194 std::stringstream tmp;
195 tmp << std::hex << input;
196
197 return tmp.str();
198}
199
200/** @brief Get NVMe info over smbus */
201bool getNVMeInfobyBusID(int busID, phosphor::nvme::Nvme::NVMeData& nvmeData)
202{
203 nvmeData.present = true;
204 nvmeData.vendor = "";
205 nvmeData.serialNumber = "";
206 nvmeData.smartWarnings = "";
207 nvmeData.statusFlags = "";
208 nvmeData.driveLifeUsed = "";
209 nvmeData.sensorValue = (int8_t)TEMPERATURE_SENSOR_FAILURE;
210
211 phosphor::smbus::Smbus smbus;
212
213 unsigned char rsp_data_command_0[I2C_DATA_MAX] = {0};
214 unsigned char rsp_data_command_8[I2C_DATA_MAX] = {0};
215
216 uint8_t tx_data = COMMAND_CODE_0;
217
218 auto init = smbus.smbusInit(busID);
219
220 static std::unordered_map<int, bool> isErrorSmbus;
221
222 if (init == -1)
223 {
224 if (isErrorSmbus[busID] != true)
225 {
226 log<level::ERR>("smbusInit fail!");
227 isErrorSmbus[busID] = true;
228 }
229
230 nvmeData.present = false;
231
232 return nvmeData.present;
233 }
234
235 auto res_int =
236 smbus.SendSmbusRWBlockCmdRAW(busID, NVME_SSD_SLAVE_ADDRESS, &tx_data,
237 sizeof(tx_data), rsp_data_command_0);
238
239 if (res_int < 0)
240 {
241 if (isErrorSmbus[busID] != true)
242 {
243 log<level::ERR>("Send command code 0 fail!");
244 isErrorSmbus[busID] = true;
245 }
246
247 smbus.smbusClose(busID);
248 nvmeData.present = false;
249 return nvmeData.present;
250 }
251
252 tx_data = COMMAND_CODE_8;
253
254 res_int =
255 smbus.SendSmbusRWBlockCmdRAW(busID, NVME_SSD_SLAVE_ADDRESS, &tx_data,
256 sizeof(tx_data), rsp_data_command_8);
257
258 if (res_int < 0)
259 {
260 if (isErrorSmbus[busID] != true)
261 {
262 log<level::ERR>("Send command code 8 fail!");
263 isErrorSmbus[busID] = true;
264 }
265
266 smbus.smbusClose(busID);
267 nvmeData.present = false;
268 return nvmeData.present;
269 }
270
271 nvmeData.vendor =
272 intToHex(rsp_data_command_8[1]) + " " + intToHex(rsp_data_command_8[2]);
273
George Hung69b96182020-08-20 17:19:56 +0800274 for (auto iter = map_vendor.begin(); iter != map_vendor.end(); iter++)
275 {
276 if (iter->first == nvmeData.vendor)
277 {
278 nvmeData.vendor = iter->second;
279 break;
280 }
281 }
282
Tony Lee6c595012019-06-19 10:54:59 +0800283 for (int offset = SERIALNUMBER_START_INDEX; offset < SERIALNUMBER_END_INDEX;
284 offset++)
285 {
George Hung69b96182020-08-20 17:19:56 +0800286 if (rsp_data_command_8[offset] != ' ')
287 nvmeData.serialNumber +=
288 static_cast<char>(rsp_data_command_8[offset]);
Tony Lee6c595012019-06-19 10:54:59 +0800289 }
290
291 nvmeData.statusFlags = intToHex(rsp_data_command_0[1]);
292 nvmeData.smartWarnings = intToHex(rsp_data_command_0[2]);
293 nvmeData.driveLifeUsed = intToHex(rsp_data_command_0[4]);
294 nvmeData.sensorValue = (int8_t)rsp_data_command_0[3];
295
296 smbus.smbusClose(busID);
297
298 isErrorSmbus[busID] = false;
299
300 return nvmeData.present;
301}
302
Tony Lee84d430c2019-06-13 15:26:15 +0800303void Nvme::run()
304{
Tony Lee89659212019-06-21 17:34:14 +0800305 init();
306
Tony Lee84d430c2019-06-13 15:26:15 +0800307 std::function<void()> callback(std::bind(&Nvme::read, this));
308 try
309 {
310 u_int64_t interval = MONITOR_INTERVAL_SECONDS * 1000000;
311 _timer.restart(std::chrono::microseconds(interval));
312 }
313 catch (const std::exception& e)
314 {
315 log<level::ERR>("Error in polling loop. "),
316 entry("ERROR = %s", e.what());
317 }
318}
319
Tony Lee6c595012019-06-19 10:54:59 +0800320/** @brief Parsing NVMe config JSON file */
321Json parseSensorConfig()
Tony Lee84d430c2019-06-13 15:26:15 +0800322{
Tony Lee6c595012019-06-19 10:54:59 +0800323 std::ifstream jsonFile(configFile);
324 if (!jsonFile.is_open())
325 {
326 log<level::ERR>("NVMe config JSON file not found");
327 }
328
329 auto data = Json::parse(jsonFile, nullptr, false);
330 if (data.is_discarded())
331 {
332 log<level::ERR>("NVMe config readings JSON parser failure");
333 }
334
335 return data;
Tony Lee84d430c2019-06-13 15:26:15 +0800336}
337
Tony Lee6c595012019-06-19 10:54:59 +0800338/** @brief Obtain the initial configuration value of NVMe */
339std::vector<phosphor::nvme::Nvme::NVMeConfig> Nvme::getNvmeConfig()
340{
341
342 phosphor::nvme::Nvme::NVMeConfig nvmeConfig;
343 std::vector<phosphor::nvme::Nvme::NVMeConfig> nvmeConfigs;
344 int8_t criticalHigh = 0;
345 int8_t criticalLow = 0;
346 int8_t maxValue = 0;
347 int8_t minValue = 0;
348 int8_t warningHigh = 0;
349 int8_t warningLow = 0;
350
351 try
352 {
353 auto data = parseSensorConfig();
354 static const std::vector<Json> empty{};
355 std::vector<Json> readings = data.value("config", empty);
356 std::vector<Json> thresholds = data.value("threshold", empty);
357 if (!thresholds.empty())
358 {
359 for (const auto& instance : thresholds)
360 {
361 criticalHigh = instance.value("criticalHigh", 0);
362 criticalLow = instance.value("criticalLow", 0);
363 maxValue = instance.value("maxValue", 0);
364 minValue = instance.value("minValue", 0);
365 warningHigh = instance.value("warningHigh", 0);
366 warningLow = instance.value("warningLow", 0);
367 }
368 }
369 else
370 {
371 log<level::ERR>(
372 "Invalid NVMe config file, thresholds dosen't exist");
373 }
374
375 if (!readings.empty())
376 {
377 for (const auto& instance : readings)
378 {
379 uint8_t index = instance.value("NVMeDriveIndex", 0);
380 uint8_t busID = instance.value("NVMeDriveBusID", 0);
Tony Lee89659212019-06-21 17:34:14 +0800381 std::string faultLedGroupPath =
382 instance.value("NVMeDriveFaultLEDGroupPath", "");
383 std::string locateLedGroupPath =
384 instance.value("NVMeDriveLocateLEDGroupPath", "");
George Hung873b5b32020-06-20 14:56:15 +0800385 uint16_t presentPin = instance.value("NVMeDrivePresentPin", 0);
386 uint16_t pwrGoodPin = instance.value("NVMeDrivePwrGoodPin", 0);
Tony Lee89659212019-06-21 17:34:14 +0800387 std::string locateLedControllerBusName =
388 instance.value("NVMeDriveLocateLEDControllerBusName", "");
389 std::string locateLedControllerPath =
390 instance.value("NVMeDriveLocateLEDControllerPath", "");
Tony Lee6c595012019-06-19 10:54:59 +0800391
392 nvmeConfig.index = std::to_string(index);
393 nvmeConfig.busID = busID;
Tony Lee89659212019-06-21 17:34:14 +0800394 nvmeConfig.faultLedGroupPath = faultLedGroupPath;
Tony Lee6c595012019-06-19 10:54:59 +0800395 nvmeConfig.presentPin = presentPin;
396 nvmeConfig.pwrGoodPin = pwrGoodPin;
Tony Lee89659212019-06-21 17:34:14 +0800397 nvmeConfig.locateLedControllerBusName =
398 locateLedControllerBusName;
399 nvmeConfig.locateLedControllerPath = locateLedControllerPath;
400 nvmeConfig.locateLedGroupPath = locateLedGroupPath;
Tony Lee6c595012019-06-19 10:54:59 +0800401 nvmeConfig.criticalHigh = criticalHigh;
402 nvmeConfig.criticalLow = criticalLow;
403 nvmeConfig.warningHigh = warningHigh;
404 nvmeConfig.warningLow = warningLow;
405 nvmeConfig.maxValue = maxValue;
406 nvmeConfig.minValue = minValue;
407 nvmeConfigs.push_back(nvmeConfig);
408 }
409 }
410 else
411 {
412 log<level::ERR>("Invalid NVMe config file, config dosen't exist");
413 }
414 }
415 catch (const Json::exception& e)
416 {
417 log<level::ERR>("Json Exception caught."), entry("MSG: %s", e.what());
418 }
419
420 return nvmeConfigs;
421}
422
423std::string Nvme::getGPIOValueOfNvme(const std::string& fullPath)
424{
425 std::string val;
426 std::ifstream ifs;
427 auto retries = 3;
428
429 while (retries != 0)
430 {
431 try
432 {
433 if (!ifs.is_open())
434 ifs.open(fullPath);
435 ifs.clear();
436 ifs.seekg(0);
437 ifs >> val;
438 }
439 catch (const std::exception& e)
440 {
441 --retries;
442 std::this_thread::sleep_for(delay);
443 log<level::ERR>("Can not open gpio path.",
444 entry("MSG: %s", e.what()));
445 continue;
446 }
447 break;
448 }
449
450 ifs.close();
451 return val;
452}
453
Tony Lee89659212019-06-21 17:34:14 +0800454void Nvme::createNVMeInventory()
455{
Patrick Williams05eedaa2020-05-13 17:58:42 -0500456 using Properties = std::map<std::string, std::variant<std::string, bool>>;
Tony Lee89659212019-06-21 17:34:14 +0800457 using Interfaces = std::map<std::string, Properties>;
458
459 std::string inventoryPath;
460 std::map<sdbusplus::message::object_path, Interfaces> obj;
461
462 for (const auto config : configs)
463 {
464 inventoryPath = "/system/chassis/motherboard/nvme" + config.index;
465
466 obj = {{
467 inventoryPath,
468 {{ITEM_IFACE, {}}, {NVME_STATUS_IFACE, {}}, {ASSET_IFACE, {}}},
469 }};
470 util::SDBusPlus::CallMethod(bus, INVENTORY_BUSNAME, INVENTORY_NAMESPACE,
471 INVENTORY_MANAGER_IFACE, "Notify", obj);
472 }
473}
474
475void Nvme::init()
476{
477 createNVMeInventory();
478}
479
Vijay Khemkae41b2e42020-04-21 09:23:10 -0700480void Nvme::readNvmeData(NVMeConfig& config)
481{
482 std::string inventoryPath = NVME_INVENTORY_PATH + config.index;
483 NVMeData nvmeData;
484
485 // get NVMe information through i2c by busID.
486 auto success = getNVMeInfobyBusID(config.busID, nvmeData);
487 auto iter = nvmes.find(config.index);
488
489 // can not find. create dbus
490 if (iter == nvmes.end())
491 {
492 log<level::INFO>("SSD plug.",
493 entry("index = %s", config.index.c_str()));
494
495 std::string objPath = NVME_OBJ_PATH + config.index;
496 auto nvmeSSD =
497 std::make_shared<phosphor::nvme::NvmeSSD>(bus, objPath.c_str());
498 nvmes.emplace(config.index, nvmeSSD);
499
500 setNvmeInventoryProperties(true, nvmeData, inventoryPath);
501 nvmeSSD->setSensorValueToDbus(nvmeData.sensorValue);
502 nvmeSSD->setSensorThreshold(config.criticalHigh, config.criticalLow,
503 config.maxValue, config.minValue,
504 config.warningHigh, config.warningLow);
505
506 nvmeSSD->checkSensorThreshold();
507 setLEDsStatus(config, success, nvmeData);
508 }
509 else
510 {
511 setNvmeInventoryProperties(true, nvmeData, inventoryPath);
512 iter->second->setSensorValueToDbus(nvmeData.sensorValue);
513 iter->second->checkSensorThreshold();
514 setLEDsStatus(config, success, nvmeData);
515 }
516}
517
Tony Lee6c595012019-06-19 10:54:59 +0800518/** @brief Monitor NVMe drives every one second */
Tony Lee84d430c2019-06-13 15:26:15 +0800519void Nvme::read()
520{
Tony Lee6c595012019-06-19 10:54:59 +0800521 std::string devPresentPath;
522 std::string devPwrGoodPath;
Tony Lee89659212019-06-21 17:34:14 +0800523 std::string inventoryPath;
Tony Lee6c595012019-06-19 10:54:59 +0800524
525 static std::unordered_map<std::string, bool> isErrorPower;
526
527 for (auto config : configs)
528 {
529 NVMeData nvmeData;
Tony Lee6c595012019-06-19 10:54:59 +0800530
Tony Lee89659212019-06-21 17:34:14 +0800531 inventoryPath = NVME_INVENTORY_PATH + config.index;
532
Vijay Khemkae41b2e42020-04-21 09:23:10 -0700533 if (config.presentPin)
Tony Lee6c595012019-06-19 10:54:59 +0800534 {
Vijay Khemkae41b2e42020-04-21 09:23:10 -0700535 devPresentPath =
536 GPIO_BASE_PATH + std::to_string(config.presentPin) + "/value";
537
538 if (getGPIOValueOfNvme(devPresentPath) != IS_PRESENT)
Tony Lee6c595012019-06-19 10:54:59 +0800539 {
Vijay Khemkae41b2e42020-04-21 09:23:10 -0700540 // Drive not present, remove nvme d-bus path ,
541 // clean all properties in inventory
542 // and turn off fault and locate LED
Tony Lee89659212019-06-21 17:34:14 +0800543
544 setFaultLED(config.locateLedGroupPath, config.faultLedGroupPath,
Vijay Khemkae41b2e42020-04-21 09:23:10 -0700545 false);
Tony Lee89659212019-06-21 17:34:14 +0800546 setLocateLED(config.locateLedGroupPath,
547 config.locateLedControllerBusName,
548 config.locateLedControllerPath, false);
549
Tony Lee6c595012019-06-19 10:54:59 +0800550 nvmeData = NVMeData();
Tony Lee89659212019-06-21 17:34:14 +0800551 setNvmeInventoryProperties(false, nvmeData, inventoryPath);
Tony Lee6c595012019-06-19 10:54:59 +0800552 nvmes.erase(config.index);
George Hung188ad952020-06-20 16:28:06 +0800553 continue;
Vijay Khemkae41b2e42020-04-21 09:23:10 -0700554 }
555 else if (config.pwrGoodPin)
556 {
557 devPwrGoodPath = GPIO_BASE_PATH +
558 std::to_string(config.pwrGoodPin) + "/value";
Tony Lee6c595012019-06-19 10:54:59 +0800559
Vijay Khemkae41b2e42020-04-21 09:23:10 -0700560 if (getGPIOValueOfNvme(devPwrGoodPath) != POWERGD)
Tony Lee6c595012019-06-19 10:54:59 +0800561 {
Tony Lee6c595012019-06-19 10:54:59 +0800562
Vijay Khemkae41b2e42020-04-21 09:23:10 -0700563 // Present pin is true but power good pin is false
564 // remove nvme d-bus path, clean all properties in inventory
565 // and turn on fault LED
566
567 setFaultLED(config.locateLedGroupPath,
568 config.faultLedGroupPath, true);
569 setLocateLED(config.locateLedGroupPath,
570 config.locateLedControllerBusName,
571 config.locateLedControllerPath, false);
572
573 nvmeData = NVMeData();
574 setNvmeInventoryProperties(false, nvmeData, inventoryPath);
575 nvmes.erase(config.index);
576
577 if (isErrorPower[config.index] != true)
578 {
579 log<level::ERR>(
580 "Present pin is true but power good pin is false.",
581 entry("index = %s", config.index.c_str()));
582 log<level::ERR>(
583 "Erase SSD from map and d-bus.",
584 entry("index = %s", config.index.c_str()));
585
586 isErrorPower[config.index] = true;
587 }
George Hung188ad952020-06-20 16:28:06 +0800588 continue;
Tony Lee6c595012019-06-19 10:54:59 +0800589 }
590 }
591 }
Vijay Khemkae41b2e42020-04-21 09:23:10 -0700592 // Drive status is good, update value or create d-bus and update
593 // value.
594 readNvmeData(config);
Tony Lee89659212019-06-21 17:34:14 +0800595
Vijay Khemkae41b2e42020-04-21 09:23:10 -0700596 isErrorPower[config.index] = false;
Tony Lee6c595012019-06-19 10:54:59 +0800597 }
Tony Lee84d430c2019-06-13 15:26:15 +0800598}
599} // namespace nvme
600} // namespace phosphor