blob: cf20b0a8dbff14ad9420e73dd66b716a927da1c7 [file] [log] [blame]
SunnySrivastava1984b59fd092020-02-03 09:58:56 -06001#include "config.h"
2
3#include "manager.hpp"
4
Santosh Puranikf2d3b532022-04-19 06:44:07 -05005#include "bios_handler.hpp"
Santosh Puranikbf78ed82022-04-20 13:17:04 +05306#include "common_utility.hpp"
SunnySrivastava1984d076da82020-03-05 05:33:35 -06007#include "editor_impl.hpp"
Alpana Kumarib17dd3b2020-10-01 00:18:10 -05008#include "gpioMonitor.hpp"
Sunny Srivastava6c71c9d2021-04-15 04:43:54 -05009#include "ibm_vpd_utils.hpp"
SunnySrivastava1984e12b1812020-05-26 02:23:11 -050010#include "ipz_parser.hpp"
Santosh Puranik6b2b5372022-06-02 20:49:02 +053011#include "parser_factory.hpp"
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050012#include "reader_impl.hpp"
SunnySrivastava19849a195542020-09-07 06:04:50 -050013#include "vpd_exceptions.hpp"
14
Santosh Puranikd40e42d2022-03-23 13:58:06 +053015#include <filesystem>
SunnySrivastava19849a195542020-09-07 06:04:50 -050016#include <phosphor-logging/elog-errors.hpp>
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060017
Alpana Kumarib17dd3b2020-10-01 00:18:10 -050018using namespace openpower::vpd::manager;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060019using namespace openpower::vpd::constants;
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050020using namespace openpower::vpd::inventory;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060021using namespace openpower::vpd::manager::editor;
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050022using namespace openpower::vpd::manager::reader;
SunnySrivastava19849a195542020-09-07 06:04:50 -050023using namespace std;
24using namespace openpower::vpd::parser;
Santosh Puranik6b2b5372022-06-02 20:49:02 +053025using namespace openpower::vpd::parser::factory;
26using namespace openpower::vpd::ipz::parser;
SunnySrivastava19849a195542020-09-07 06:04:50 -050027using namespace openpower::vpd::exceptions;
28using namespace phosphor::logging;
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060029
30namespace openpower
31{
32namespace vpd
33{
34namespace manager
35{
Patrick Williams2eb01762022-07-22 19:26:56 -050036Manager::Manager(sdbusplus::bus_t&& bus, const char* busName,
Priyanga Ramasamy9d149342020-07-16 23:41:26 +053037 const char* objPath, const char* /*iFace*/) :
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060038 ServerObject<ManagerIface>(bus, objPath),
39 _bus(std::move(bus)), _manager(_bus, objPath)
40{
41 _bus.request_name(busName);
Sunny Srivastavafdf9ff22022-06-15 11:15:54 -050042 sd_bus_default(&sdBus);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060043}
44
45void Manager::run()
46{
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -060047 try
48 {
49 processJSON();
Santosh Puranik6b2b5372022-06-02 20:49:02 +053050 restoreSystemVpd();
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -050051 listenHostState();
Santosh Puranikb62f6052022-04-06 18:37:54 +053052 listenAssetTag();
Alpana Kumarib17dd3b2020-10-01 00:18:10 -050053
Santosh Puranikf2d3b532022-04-19 06:44:07 -050054 // Create an instance of the BIOS handler
55 BiosHandler biosHandler{_bus, *this};
56
Alpana Kumarib17dd3b2020-10-01 00:18:10 -050057 auto event = sdeventplus::Event::get_default();
58 GpioMonitor gpioMon1(jsonFile, event);
59
60 _bus.attach_event(event.get(), SD_EVENT_PRIORITY_IMPORTANT);
61 cout << "VPD manager event loop started\n";
62 event.loop();
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -060063 }
64 catch (const std::exception& e)
65 {
66 std::cerr << e.what() << "\n";
67 }
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -060068}
69
Santosh Puranik6b2b5372022-06-02 20:49:02 +053070/**
71 * @brief An api to get list of blank system VPD properties.
72 * @param[in] vpdMap - IPZ vpd map.
73 * @param[in] objectPath - Object path for the FRU.
74 * @param[out] blankPropertyList - Properties which are blank in System VPD and
75 * needs to be updated as standby.
76 */
77static void
78 getListOfBlankSystemVpd(Parsed& vpdMap, const string& objectPath,
79 std::vector<RestoredEeproms>& blankPropertyList)
80{
81 for (const auto& systemRecKwdPair : svpdKwdMap)
82 {
83 auto it = vpdMap.find(systemRecKwdPair.first);
84
85 // check if record is found in map we got by parser
86 if (it != vpdMap.end())
87 {
88 const auto& kwdListForRecord = systemRecKwdPair.second;
89 for (const auto& keyword : kwdListForRecord)
90 {
91 DbusPropertyMap& kwdValMap = it->second;
92 auto iterator = kwdValMap.find(keyword);
93
94 if (iterator != kwdValMap.end())
95 {
96 string& kwdValue = iterator->second;
97
98 // check bus data
99 const string& recordName = systemRecKwdPair.first;
100 const string& busValue = readBusProperty(
101 objectPath, ipzVpdInf + recordName, keyword);
102
103 if (busValue.find_first_not_of(' ') != string::npos)
104 {
105 if (kwdValue.find_first_not_of(' ') == string::npos)
106 {
107 // implies data is blank on EEPROM but not on cache.
108 // So EEPROM vpd update is required.
109 Binary busData(busValue.begin(), busValue.end());
110
111 blankPropertyList.push_back(std::make_tuple(
112 objectPath, recordName, keyword, busData));
113 }
114 }
115 }
116 }
117 }
118 }
119}
120
121void Manager::restoreSystemVpd()
122{
123 std::cout << "Attempting system VPD restore" << std::endl;
124 ParserInterface* parser = nullptr;
125 try
126 {
127 auto vpdVector = getVpdDataInVector(jsonFile, systemVpdFilePath);
Sunny Srivastavaf31a91b2022-06-09 08:11:29 -0500128 const auto& inventoryPath =
129 jsonFile["frus"][systemVpdFilePath][0]["inventoryPath"]
130 .get_ref<const nlohmann::json::string_t&>();
131
132 parser = ParserFactory::getParser(vpdVector, (pimPath + inventoryPath));
Santosh Puranik6b2b5372022-06-02 20:49:02 +0530133 auto parseResult = parser->parse();
134
135 if (auto pVal = std::get_if<Store>(&parseResult))
136 {
137 // map to hold all the keywords whose value is blank and
138 // needs to be updated at standby.
139 std::vector<RestoredEeproms> blankSystemVpdProperties{};
140 getListOfBlankSystemVpd(pVal->getVpdMap(), SYSTEM_OBJECT,
141 blankSystemVpdProperties);
142
143 // if system VPD restore is required, update the
144 // EEPROM
145 for (const auto& item : blankSystemVpdProperties)
146 {
147 std::cout << "Restoring keyword: " << std::get<2>(item)
148 << std::endl;
149 writeKeyword(std::get<0>(item), std::get<1>(item),
150 std::get<2>(item), std::get<3>(item));
151 }
152 }
153 else
154 {
155 std::cerr << "Not a valid format to restore system VPD"
156 << std::endl;
157 }
158 }
159 catch (const std::exception& e)
160 {
161 std::cerr << "Failed to restore system VPD due to exception: "
162 << e.what() << std::endl;
163 }
164 // release the parser object
165 ParserFactory::freeParser(parser);
166}
167
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500168void Manager::listenHostState()
169{
Patrick Williams2eb01762022-07-22 19:26:56 -0500170 static std::shared_ptr<sdbusplus::bus::match_t> hostState =
171 std::make_shared<sdbusplus::bus::match_t>(
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500172 _bus,
173 sdbusplus::bus::match::rules::propertiesChanged(
174 "/xyz/openbmc_project/state/host0",
175 "xyz.openbmc_project.State.Host"),
Patrick Williams2eb01762022-07-22 19:26:56 -0500176 [this](sdbusplus::message_t& msg) { hostStateCallBack(msg); });
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500177}
178
Sunny Srivastavafdf9ff22022-06-15 11:15:54 -0500179void Manager::checkEssentialFrus()
180{
181 for (const auto& invPath : essentialFrus)
182 {
183 const auto res = readBusProperty(invPath, invItemIntf, "Present");
184
185 // implies the essential FRU is missing. Log PEL.
186 if (res == "false")
187 {
188 auto rc = sd_bus_call_method_async(
189 sdBus, NULL, loggerService, loggerObjectPath,
190 loggerCreateInterface, "Create", NULL, NULL, "ssa{ss}",
191 errIntfForEssentialFru,
192 "xyz.openbmc_project.Logging.Entry.Level.Warning", 2,
193 "DESCRIPTION", "Essential fru missing from the system.",
194 "CALLOUT_INVENTORY_PATH", (pimPath + invPath).c_str());
195
196 if (rc < 0)
197 {
198 log<level::ERR>("Error calling sd_bus_call_method_async",
199 entry("RC=%d", rc),
200 entry("MSG=%s", strerror(-rc)));
201 }
202 }
203 }
204}
205
Patrick Williams7a975f02022-12-07 03:19:53 -0600206void Manager::hostStateCallBack(sdbusplus::message_t& msg)
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500207{
208 if (msg.is_method_error())
209 {
210 std::cerr << "Error in reading signal " << std::endl;
211 }
212
213 Path object;
214 PropertyMap propMap;
215 msg.read(object, propMap);
216 const auto itr = propMap.find("CurrentHostState");
217 if (itr != propMap.end())
218 {
219 if (auto hostState = std::get_if<std::string>(&(itr->second)))
220 {
221 // implies system is moving from standby to power on state
222 if (*hostState == "xyz.openbmc_project.State.Host.HostState."
223 "TransitioningToRunning")
224 {
Sunny Srivastavafdf9ff22022-06-15 11:15:54 -0500225 // detect if essential frus are present in the system.
226 checkEssentialFrus();
227
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500228 // check and perfrom recollection for FRUs replaceable at
229 // standby.
230 performVPDRecollection();
231 return;
232 }
233 }
234 std::cerr << "Failed to read Host state" << std::endl;
235 }
236}
237
Santosh Puranikb62f6052022-04-06 18:37:54 +0530238void Manager::listenAssetTag()
239{
Patrick Williams2eb01762022-07-22 19:26:56 -0500240 static std::shared_ptr<sdbusplus::bus::match_t> assetMatcher =
241 std::make_shared<sdbusplus::bus::match_t>(
Santosh Puranikb62f6052022-04-06 18:37:54 +0530242 _bus,
243 sdbusplus::bus::match::rules::propertiesChanged(
244 "/xyz/openbmc_project/inventory/system",
245 "xyz.openbmc_project.Inventory.Decorator.AssetTag"),
Patrick Williams2eb01762022-07-22 19:26:56 -0500246 [this](sdbusplus::message_t& msg) { assetTagCallback(msg); });
Santosh Puranikb62f6052022-04-06 18:37:54 +0530247}
248
Patrick Williams2eb01762022-07-22 19:26:56 -0500249void Manager::assetTagCallback(sdbusplus::message_t& msg)
Santosh Puranikb62f6052022-04-06 18:37:54 +0530250{
251 if (msg.is_method_error())
252 {
253 std::cerr << "Error in reading signal " << std::endl;
254 }
255
256 Path object;
257 PropertyMap propMap;
258 msg.read(object, propMap);
259 const auto itr = propMap.find("AssetTag");
260 if (itr != propMap.end())
261 {
262 if (auto assetTag = std::get_if<std::string>(&(itr->second)))
263 {
264 // Call Notify to persist the AssetTag
265 inventory::ObjectMap objectMap = {
266 {std::string{"/system"},
267 {{"xyz.openbmc_project.Inventory.Decorator.AssetTag",
268 {{"AssetTag", *assetTag}}}}}};
269
270 common::utility::callPIM(std::move(objectMap));
271 }
272 else
273 {
274 std::cerr << "Failed to read asset tag" << std::endl;
275 }
276 }
277}
278
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -0600279void Manager::processJSON()
280{
Santosh Puranik0246a4d2020-11-04 16:57:39 +0530281 std::ifstream json(INVENTORY_JSON_SYM_LINK, std::ios::binary);
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -0600282
283 if (!json)
284 {
285 throw std::runtime_error("json file not found");
286 }
287
288 jsonFile = nlohmann::json::parse(json);
289 if (jsonFile.find("frus") == jsonFile.end())
290 {
291 throw std::runtime_error("frus group not found in json");
292 }
293
294 const nlohmann::json& groupFRUS =
295 jsonFile["frus"].get_ref<const nlohmann::json::object_t&>();
296 for (const auto& itemFRUS : groupFRUS.items())
297 {
298 const std::vector<nlohmann::json>& groupEEPROM =
299 itemFRUS.value().get_ref<const nlohmann::json::array_t&>();
300 for (const auto& itemEEPROM : groupEEPROM)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600301 {
SunnySrivastava198443306542020-04-01 02:50:20 -0500302 bool isMotherboard = false;
Santosh Puranika0b23912022-02-10 13:37:09 +0530303 std::string redundantPath;
304
SunnySrivastava198443306542020-04-01 02:50:20 -0500305 if (itemEEPROM["extraInterfaces"].find(
306 "xyz.openbmc_project.Inventory.Item.Board.Motherboard") !=
307 itemEEPROM["extraInterfaces"].end())
308 {
309 isMotherboard = true;
310 }
Santosh Puranika0b23912022-02-10 13:37:09 +0530311 if (itemEEPROM.find("redundantEeprom") != itemEEPROM.end())
312 {
313 redundantPath = itemEEPROM["redundantEeprom"]
314 .get_ref<const nlohmann::json::string_t&>();
315 }
316 frus.emplace(
317 itemEEPROM["inventoryPath"]
318 .get_ref<const nlohmann::json::string_t&>(),
319 std::make_tuple(itemFRUS.key(), redundantPath, isMotherboard));
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -0500320
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000321 if (itemEEPROM["extraInterfaces"].find(IBM_LOCATION_CODE_INF) !=
Alpana Kumari920408d2020-05-14 00:07:03 -0500322 itemEEPROM["extraInterfaces"].end())
323 {
324 fruLocationCode.emplace(
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000325 itemEEPROM["extraInterfaces"][IBM_LOCATION_CODE_INF]
Alpana Kumari920408d2020-05-14 00:07:03 -0500326 ["LocationCode"]
327 .get_ref<const nlohmann::json::string_t&>(),
328 itemEEPROM["inventoryPath"]
329 .get_ref<const nlohmann::json::string_t&>());
330 }
SunnySrivastava19849a195542020-09-07 06:04:50 -0500331
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500332 if (itemEEPROM.value("replaceableAtStandby", false))
SunnySrivastava19849a195542020-09-07 06:04:50 -0500333 {
334 replaceableFrus.emplace_back(itemFRUS.key());
335 }
Sunny Srivastavafdf9ff22022-06-15 11:15:54 -0500336
337 if (itemEEPROM.value("essentialFru", false))
338 {
339 essentialFrus.emplace_back(itemEEPROM["inventoryPath"]);
340 }
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600341 }
342 }
343}
344
345void Manager::writeKeyword(const sdbusplus::message::object_path path,
346 const std::string recordName,
347 const std::string keyword, const Binary value)
348{
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600349 try
350 {
Santosh Puranik8c796812021-12-01 19:17:56 +0530351 std::string objPath{path};
352 // Strip any inventory prefix in path
353 if (objPath.find(INVENTORY_PATH) == 0)
354 {
355 objPath = objPath.substr(sizeof(INVENTORY_PATH) - 1);
356 }
357
358 if (frus.find(objPath) == frus.end())
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600359 {
360 throw std::runtime_error("Inventory path not found");
361 }
362
Santosh Puranika0b23912022-02-10 13:37:09 +0530363 inventory::Path vpdFilePath = std::get<0>(frus.find(objPath)->second);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600364
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500365 // instantiate editor class to update the data
Santosh Puranik8c796812021-12-01 19:17:56 +0530366 EditorImpl edit(vpdFilePath, jsonFile, recordName, keyword, objPath);
Santosh Puranika0b23912022-02-10 13:37:09 +0530367
368 uint32_t offset = 0;
369 // Setup offset, if any
370 for (const auto& item : jsonFile["frus"][vpdFilePath])
371 {
372 if (item.find("offset") != item.end())
373 {
374 offset = item["offset"];
375 break;
376 }
377 }
378
379 edit.updateKeyword(value, offset, true);
380
381 // If we have a redundant EEPROM to update, then update just the EEPROM,
382 // not the cache since that is already done when we updated the primary
383 if (!std::get<1>(frus.find(objPath)->second).empty())
384 {
385 EditorImpl edit(std::get<1>(frus.find(objPath)->second), jsonFile,
Sunny Srivastavaf31a91b2022-06-09 08:11:29 -0500386 recordName, keyword, objPath);
Santosh Puranika0b23912022-02-10 13:37:09 +0530387 edit.updateKeyword(value, offset, false);
388 }
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600389
SunnySrivastava198443306542020-04-01 02:50:20 -0500390 // if it is a motehrboard FRU need to check for location expansion
Santosh Puranika0b23912022-02-10 13:37:09 +0530391 if (std::get<2>(frus.find(objPath)->second))
SunnySrivastava198443306542020-04-01 02:50:20 -0500392 {
393 if (recordName == "VCEN" && (keyword == "FC" || keyword == "SE"))
394 {
395 edit.expandLocationCode("fcs");
396 }
397 else if (recordName == "VSYS" &&
398 (keyword == "TM" || keyword == "SE"))
399 {
400 edit.expandLocationCode("mts");
401 }
402 }
403
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500404 return;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600405 }
406 catch (const std::exception& e)
407 {
408 std::cerr << e.what() << std::endl;
409 }
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600410}
411
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500412ListOfPaths
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500413 Manager::getFRUsByUnexpandedLocationCode(const LocationCode locationCode,
414 const NodeNumber nodeNumber)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600415{
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500416 ReaderImpl read;
417 return read.getFrusAtLocation(locationCode, nodeNumber, fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600418}
419
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500420ListOfPaths
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500421 Manager::getFRUsByExpandedLocationCode(const LocationCode locationCode)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600422{
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500423 ReaderImpl read;
424 return read.getFRUsByExpandedLocationCode(locationCode, fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600425}
426
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500427LocationCode Manager::getExpandedLocationCode(const LocationCode locationCode,
428 const NodeNumber nodeNumber)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600429{
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -0500430 ReaderImpl read;
431 return read.getExpandedLocationCode(locationCode, nodeNumber,
432 fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600433}
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -0600434
SunnySrivastava19849a195542020-09-07 06:04:50 -0500435void Manager::performVPDRecollection()
436{
437 // get list of FRUs replaceable at standby
438 for (const auto& item : replaceableFrus)
439 {
440 const vector<nlohmann::json>& groupEEPROM = jsonFile["frus"][item];
441 const nlohmann::json& singleFru = groupEEPROM[0];
442
443 const string& inventoryPath =
444 singleFru["inventoryPath"]
445 .get_ref<const nlohmann::json::string_t&>();
446
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530447 bool prePostActionRequired = false;
448
449 if ((jsonFile["frus"][item].at(0)).find("preAction") !=
450 jsonFile["frus"][item].at(0).end())
451 {
Sunny Srivastavaa2ddc962022-06-29 08:53:16 -0500452 try
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530453 {
Sunny Srivastavaa2ddc962022-06-29 08:53:16 -0500454 if (!executePreAction(jsonFile, item))
455 {
456 // if the FRU has preAction defined then its execution
457 // should pass to ensure bind/unbind of data.
458 // preAction execution failed. should not call
459 // bind/unbind.
460 log<level::ERR>(
461 "Pre-Action execution failed for the FRU",
462 entry("ERROR=%s",
463 ("Inventory path: " + inventoryPath).c_str()));
464 continue;
465 }
466 }
467 catch (const GpioException& e)
468 {
469 log<level::ERR>(e.what());
470 PelAdditionalData additionalData{};
471 additionalData.emplace("DESCRIPTION", e.what());
472 createPEL(additionalData, PelSeverity::WARNING,
473 errIntfForGpioError, sdBus);
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530474 continue;
475 }
476 prePostActionRequired = true;
477 }
478
SunnySrivastava19849a195542020-09-07 06:04:50 -0500479 if ((singleFru.find("devAddress") == singleFru.end()) ||
480 (singleFru.find("driverType") == singleFru.end()) ||
481 (singleFru.find("busType") == singleFru.end()))
482 {
483 // The FRUs is marked for replacement but missing mandatory
484 // fields for recollection. Skip to another replaceable fru.
485 log<level::ERR>(
486 "Recollection Failed as mandatory field missing in Json",
487 entry("ERROR=%s",
488 ("Recollection failed for " + inventoryPath).c_str()));
489 continue;
490 }
491
492 string str = "echo ";
493 string deviceAddress = singleFru["devAddress"];
494 const string& driverType = singleFru["driverType"];
495 const string& busType = singleFru["busType"];
496
497 // devTreeStatus flag is present in json as false to mention
498 // that the EEPROM is not mentioned in device tree. If this flag
499 // is absent consider the value to be true, i.e EEPROM is
500 // mentioned in device tree
501 if (!singleFru.value("devTreeStatus", true))
502 {
503 auto pos = deviceAddress.find('-');
504 if (pos != string::npos)
505 {
506 string busNum = deviceAddress.substr(0, pos);
507 deviceAddress =
508 "0x" + deviceAddress.substr(pos + 1, string::npos);
509
510 string deleteDevice = str + deviceAddress + " > /sys/bus/" +
511 busType + "/devices/" + busType + "-" +
512 busNum + "/delete_device";
513 executeCmd(deleteDevice);
514
515 string addDevice = str + driverType + " " + deviceAddress +
516 " > /sys/bus/" + busType + "/devices/" +
517 busType + "-" + busNum + "/new_device";
518 executeCmd(addDevice);
519 }
520 else
521 {
522 log<level::ERR>(
523 "Wrong format of device address in Json",
524 entry(
525 "ERROR=%s",
526 ("Recollection failed for " + inventoryPath).c_str()));
527 continue;
528 }
529 }
530 else
531 {
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500532 executeCmd(createBindUnbindDriverCmnd(deviceAddress, busType,
533 driverType, "/unbind"));
534 executeCmd(createBindUnbindDriverCmnd(deviceAddress, busType,
535 driverType, "/bind"));
SunnySrivastava19849a195542020-09-07 06:04:50 -0500536 }
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530537
538 // this check is added to avoid file system expensive call in case not
539 // required.
540 if (prePostActionRequired)
541 {
542 // Check if device showed up (test for file)
543 if (!filesystem::exists(item))
544 {
Sunny Srivastavaa2ddc962022-06-29 08:53:16 -0500545 try
546 {
547 // If not, then take failure postAction
548 executePostFailAction(jsonFile, item);
549 }
550 catch (const GpioException& e)
551 {
552 PelAdditionalData additionalData{};
553 additionalData.emplace("DESCRIPTION", e.what());
554 createPEL(additionalData, PelSeverity::WARNING,
555 errIntfForGpioError, sdBus);
556 }
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530557 }
558 }
SunnySrivastava19849a195542020-09-07 06:04:50 -0500559 }
560}
561
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600562} // namespace manager
563} // namespace vpd
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500564} // namespace openpower