blob: 23e629025c6c8a77d7bec7be397e605dc7c32f34 [file] [log] [blame]
SunnySrivastava1984b59fd092020-02-03 09:58:56 -06001#include "config.h"
2
3#include "manager.hpp"
4
Santosh Puranikbf78ed82022-04-20 13:17:04 +05305#include "common_utility.hpp"
SunnySrivastava1984d076da82020-03-05 05:33:35 -06006#include "editor_impl.hpp"
Sunny Srivastava6c71c9d2021-04-15 04:43:54 -05007#include "ibm_vpd_utils.hpp"
SunnySrivastava1984e12b1812020-05-26 02:23:11 -05008#include "ipz_parser.hpp"
Santosh Puranik6b2b5372022-06-02 20:49:02 +05309#include "parser_factory.hpp"
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050010#include "reader_impl.hpp"
SunnySrivastava19849a195542020-09-07 06:04:50 -050011#include "vpd_exceptions.hpp"
12
Santosh Puranikd40e42d2022-03-23 13:58:06 +053013#include <filesystem>
SunnySrivastava19849a195542020-09-07 06:04:50 -050014#include <phosphor-logging/elog-errors.hpp>
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060015
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060016using namespace openpower::vpd::constants;
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050017using namespace openpower::vpd::inventory;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060018using namespace openpower::vpd::manager::editor;
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050019using namespace openpower::vpd::manager::reader;
SunnySrivastava19849a195542020-09-07 06:04:50 -050020using namespace std;
21using namespace openpower::vpd::parser;
Santosh Puranik6b2b5372022-06-02 20:49:02 +053022using namespace openpower::vpd::parser::factory;
23using namespace openpower::vpd::ipz::parser;
SunnySrivastava19849a195542020-09-07 06:04:50 -050024using namespace openpower::vpd::exceptions;
25using namespace phosphor::logging;
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060026
27namespace openpower
28{
29namespace vpd
30{
31namespace manager
32{
Sunny Srivastava523af2e2022-02-14 07:30:10 -060033Manager::Manager(std::shared_ptr<boost::asio::io_context>& ioCon,
34 std::shared_ptr<sdbusplus::asio::dbus_interface>& iFace,
35 std::shared_ptr<sdbusplus::asio::connection>& conn) :
36 ioContext(ioCon),
37 interface(iFace), conn(conn)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060038{
Sunny Srivastava523af2e2022-02-14 07:30:10 -060039 interface->register_method(
40 "WriteKeyword",
41 [this](const sdbusplus::message::object_path& path,
42 const std::string& recordName, const std::string& keyword,
43 const Binary& value) {
44 this->writeKeyword(path, recordName, keyword, value);
45 });
46
47 interface->register_method(
48 "GetFRUsByUnexpandedLocationCode",
49 [this](const std::string& locationCode,
50 const uint16_t nodeNumber) -> inventory::ListOfPaths {
51 return this->getFRUsByUnexpandedLocationCode(locationCode,
52 nodeNumber);
53 });
54
55 interface->register_method(
56 "GetFRUsByExpandedLocationCode",
57 [this](const std::string& locationCode) -> inventory::ListOfPaths {
58 return this->getFRUsByExpandedLocationCode(locationCode);
59 });
60
61 interface->register_method(
62 "GetExpandedLocationCode",
63 [this](const std::string& locationCode,
64 const uint16_t nodeNumber) -> std::string {
65 return this->getExpandedLocationCode(locationCode, nodeNumber);
66 });
67
68 interface->register_method("PerformVPDRecollection",
69 [this]() { this->performVPDRecollection(); });
70
Sunny Srivastavafdf9ff22022-06-15 11:15:54 -050071 sd_bus_default(&sdBus);
Sunny Srivastava523af2e2022-02-14 07:30:10 -060072 initManager();
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060073}
74
Sunny Srivastava523af2e2022-02-14 07:30:10 -060075void Manager::initManager()
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060076{
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -060077 try
78 {
79 processJSON();
Santosh Puranik6b2b5372022-06-02 20:49:02 +053080 restoreSystemVpd();
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -050081 listenHostState();
Santosh Puranikb62f6052022-04-06 18:37:54 +053082 listenAssetTag();
Alpana Kumarib17dd3b2020-10-01 00:18:10 -050083
Santosh Puranikf2d3b532022-04-19 06:44:07 -050084 // Create an instance of the BIOS handler
Sunny Srivastava523af2e2022-02-14 07:30:10 -060085 biosHandler = std::make_shared<BiosHandler>(conn, *this);
Santosh Puranikf2d3b532022-04-19 06:44:07 -050086
Sunny Srivastava523af2e2022-02-14 07:30:10 -060087 // instantiate gpioMonitor class
88 gpioMon = std::make_shared<GpioMonitor>(jsonFile, ioContext);
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -060089 }
90 catch (const std::exception& e)
91 {
92 std::cerr << e.what() << "\n";
93 }
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -060094}
95
Santosh Puranik6b2b5372022-06-02 20:49:02 +053096/**
97 * @brief An api to get list of blank system VPD properties.
98 * @param[in] vpdMap - IPZ vpd map.
99 * @param[in] objectPath - Object path for the FRU.
100 * @param[out] blankPropertyList - Properties which are blank in System VPD and
101 * needs to be updated as standby.
102 */
103static void
104 getListOfBlankSystemVpd(Parsed& vpdMap, const string& objectPath,
105 std::vector<RestoredEeproms>& blankPropertyList)
106{
107 for (const auto& systemRecKwdPair : svpdKwdMap)
108 {
109 auto it = vpdMap.find(systemRecKwdPair.first);
110
111 // check if record is found in map we got by parser
112 if (it != vpdMap.end())
113 {
114 const auto& kwdListForRecord = systemRecKwdPair.second;
115 for (const auto& keyword : kwdListForRecord)
116 {
117 DbusPropertyMap& kwdValMap = it->second;
118 auto iterator = kwdValMap.find(keyword);
119
120 if (iterator != kwdValMap.end())
121 {
122 string& kwdValue = iterator->second;
123
124 // check bus data
125 const string& recordName = systemRecKwdPair.first;
126 const string& busValue = readBusProperty(
127 objectPath, ipzVpdInf + recordName, keyword);
128
129 if (busValue.find_first_not_of(' ') != string::npos)
130 {
131 if (kwdValue.find_first_not_of(' ') == string::npos)
132 {
133 // implies data is blank on EEPROM but not on cache.
134 // So EEPROM vpd update is required.
135 Binary busData(busValue.begin(), busValue.end());
136
137 blankPropertyList.push_back(std::make_tuple(
138 objectPath, recordName, keyword, busData));
139 }
140 }
141 }
142 }
143 }
144 }
145}
146
147void Manager::restoreSystemVpd()
148{
149 std::cout << "Attempting system VPD restore" << std::endl;
150 ParserInterface* parser = nullptr;
151 try
152 {
153 auto vpdVector = getVpdDataInVector(jsonFile, systemVpdFilePath);
Sunny Srivastavaf31a91b2022-06-09 08:11:29 -0500154 const auto& inventoryPath =
155 jsonFile["frus"][systemVpdFilePath][0]["inventoryPath"]
156 .get_ref<const nlohmann::json::string_t&>();
157
158 parser = ParserFactory::getParser(vpdVector, (pimPath + inventoryPath));
Santosh Puranik6b2b5372022-06-02 20:49:02 +0530159 auto parseResult = parser->parse();
160
161 if (auto pVal = std::get_if<Store>(&parseResult))
162 {
163 // map to hold all the keywords whose value is blank and
164 // needs to be updated at standby.
165 std::vector<RestoredEeproms> blankSystemVpdProperties{};
166 getListOfBlankSystemVpd(pVal->getVpdMap(), SYSTEM_OBJECT,
167 blankSystemVpdProperties);
168
169 // if system VPD restore is required, update the
170 // EEPROM
171 for (const auto& item : blankSystemVpdProperties)
172 {
173 std::cout << "Restoring keyword: " << std::get<2>(item)
174 << std::endl;
175 writeKeyword(std::get<0>(item), std::get<1>(item),
176 std::get<2>(item), std::get<3>(item));
177 }
178 }
179 else
180 {
181 std::cerr << "Not a valid format to restore system VPD"
182 << std::endl;
183 }
184 }
185 catch (const std::exception& e)
186 {
187 std::cerr << "Failed to restore system VPD due to exception: "
188 << e.what() << std::endl;
189 }
190 // release the parser object
191 ParserFactory::freeParser(parser);
192}
193
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500194void Manager::listenHostState()
195{
Patrick Williams2eb01762022-07-22 19:26:56 -0500196 static std::shared_ptr<sdbusplus::bus::match_t> hostState =
197 std::make_shared<sdbusplus::bus::match_t>(
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600198 *conn,
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500199 sdbusplus::bus::match::rules::propertiesChanged(
200 "/xyz/openbmc_project/state/host0",
201 "xyz.openbmc_project.State.Host"),
Patrick Williams2eb01762022-07-22 19:26:56 -0500202 [this](sdbusplus::message_t& msg) { hostStateCallBack(msg); });
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500203}
204
Sunny Srivastavafdf9ff22022-06-15 11:15:54 -0500205void Manager::checkEssentialFrus()
206{
207 for (const auto& invPath : essentialFrus)
208 {
209 const auto res = readBusProperty(invPath, invItemIntf, "Present");
210
211 // implies the essential FRU is missing. Log PEL.
212 if (res == "false")
213 {
214 auto rc = sd_bus_call_method_async(
215 sdBus, NULL, loggerService, loggerObjectPath,
216 loggerCreateInterface, "Create", NULL, NULL, "ssa{ss}",
217 errIntfForEssentialFru,
218 "xyz.openbmc_project.Logging.Entry.Level.Warning", 2,
219 "DESCRIPTION", "Essential fru missing from the system.",
220 "CALLOUT_INVENTORY_PATH", (pimPath + invPath).c_str());
221
222 if (rc < 0)
223 {
224 log<level::ERR>("Error calling sd_bus_call_method_async",
225 entry("RC=%d", rc),
226 entry("MSG=%s", strerror(-rc)));
227 }
228 }
229 }
230}
231
Patrick Williams7a975f02022-12-07 03:19:53 -0600232void Manager::hostStateCallBack(sdbusplus::message_t& msg)
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500233{
234 if (msg.is_method_error())
235 {
236 std::cerr << "Error in reading signal " << std::endl;
237 }
238
239 Path object;
240 PropertyMap propMap;
241 msg.read(object, propMap);
242 const auto itr = propMap.find("CurrentHostState");
243 if (itr != propMap.end())
244 {
245 if (auto hostState = std::get_if<std::string>(&(itr->second)))
246 {
247 // implies system is moving from standby to power on state
248 if (*hostState == "xyz.openbmc_project.State.Host.HostState."
249 "TransitioningToRunning")
250 {
Sunny Srivastavafdf9ff22022-06-15 11:15:54 -0500251 // detect if essential frus are present in the system.
252 checkEssentialFrus();
253
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500254 // check and perfrom recollection for FRUs replaceable at
255 // standby.
256 performVPDRecollection();
257 return;
258 }
259 }
260 std::cerr << "Failed to read Host state" << std::endl;
261 }
262}
263
Santosh Puranikb62f6052022-04-06 18:37:54 +0530264void Manager::listenAssetTag()
265{
Patrick Williams2eb01762022-07-22 19:26:56 -0500266 static std::shared_ptr<sdbusplus::bus::match_t> assetMatcher =
267 std::make_shared<sdbusplus::bus::match_t>(
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600268 *conn,
Santosh Puranikb62f6052022-04-06 18:37:54 +0530269 sdbusplus::bus::match::rules::propertiesChanged(
270 "/xyz/openbmc_project/inventory/system",
271 "xyz.openbmc_project.Inventory.Decorator.AssetTag"),
Patrick Williams2eb01762022-07-22 19:26:56 -0500272 [this](sdbusplus::message_t& msg) { assetTagCallback(msg); });
Santosh Puranikb62f6052022-04-06 18:37:54 +0530273}
274
Patrick Williams2eb01762022-07-22 19:26:56 -0500275void Manager::assetTagCallback(sdbusplus::message_t& msg)
Santosh Puranikb62f6052022-04-06 18:37:54 +0530276{
277 if (msg.is_method_error())
278 {
279 std::cerr << "Error in reading signal " << std::endl;
280 }
281
282 Path object;
283 PropertyMap propMap;
284 msg.read(object, propMap);
285 const auto itr = propMap.find("AssetTag");
286 if (itr != propMap.end())
287 {
288 if (auto assetTag = std::get_if<std::string>(&(itr->second)))
289 {
290 // Call Notify to persist the AssetTag
291 inventory::ObjectMap objectMap = {
292 {std::string{"/system"},
293 {{"xyz.openbmc_project.Inventory.Decorator.AssetTag",
294 {{"AssetTag", *assetTag}}}}}};
295
296 common::utility::callPIM(std::move(objectMap));
297 }
298 else
299 {
300 std::cerr << "Failed to read asset tag" << std::endl;
301 }
302 }
303}
304
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -0600305void Manager::processJSON()
306{
Santosh Puranik0246a4d2020-11-04 16:57:39 +0530307 std::ifstream json(INVENTORY_JSON_SYM_LINK, std::ios::binary);
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -0600308
309 if (!json)
310 {
311 throw std::runtime_error("json file not found");
312 }
313
314 jsonFile = nlohmann::json::parse(json);
315 if (jsonFile.find("frus") == jsonFile.end())
316 {
317 throw std::runtime_error("frus group not found in json");
318 }
319
320 const nlohmann::json& groupFRUS =
321 jsonFile["frus"].get_ref<const nlohmann::json::object_t&>();
322 for (const auto& itemFRUS : groupFRUS.items())
323 {
324 const std::vector<nlohmann::json>& groupEEPROM =
325 itemFRUS.value().get_ref<const nlohmann::json::array_t&>();
326 for (const auto& itemEEPROM : groupEEPROM)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600327 {
SunnySrivastava198443306542020-04-01 02:50:20 -0500328 bool isMotherboard = false;
Santosh Puranika0b23912022-02-10 13:37:09 +0530329 std::string redundantPath;
330
SunnySrivastava198443306542020-04-01 02:50:20 -0500331 if (itemEEPROM["extraInterfaces"].find(
332 "xyz.openbmc_project.Inventory.Item.Board.Motherboard") !=
333 itemEEPROM["extraInterfaces"].end())
334 {
335 isMotherboard = true;
336 }
Santosh Puranika0b23912022-02-10 13:37:09 +0530337 if (itemEEPROM.find("redundantEeprom") != itemEEPROM.end())
338 {
339 redundantPath = itemEEPROM["redundantEeprom"]
340 .get_ref<const nlohmann::json::string_t&>();
341 }
342 frus.emplace(
343 itemEEPROM["inventoryPath"]
344 .get_ref<const nlohmann::json::string_t&>(),
345 std::make_tuple(itemFRUS.key(), redundantPath, isMotherboard));
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -0500346
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000347 if (itemEEPROM["extraInterfaces"].find(IBM_LOCATION_CODE_INF) !=
Alpana Kumari920408d2020-05-14 00:07:03 -0500348 itemEEPROM["extraInterfaces"].end())
349 {
350 fruLocationCode.emplace(
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000351 itemEEPROM["extraInterfaces"][IBM_LOCATION_CODE_INF]
Alpana Kumari920408d2020-05-14 00:07:03 -0500352 ["LocationCode"]
353 .get_ref<const nlohmann::json::string_t&>(),
354 itemEEPROM["inventoryPath"]
355 .get_ref<const nlohmann::json::string_t&>());
356 }
SunnySrivastava19849a195542020-09-07 06:04:50 -0500357
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500358 if (itemEEPROM.value("replaceableAtStandby", false))
SunnySrivastava19849a195542020-09-07 06:04:50 -0500359 {
360 replaceableFrus.emplace_back(itemFRUS.key());
361 }
Sunny Srivastavafdf9ff22022-06-15 11:15:54 -0500362
363 if (itemEEPROM.value("essentialFru", false))
364 {
365 essentialFrus.emplace_back(itemEEPROM["inventoryPath"]);
366 }
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600367 }
368 }
369}
370
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600371void Manager::writeKeyword(const sdbusplus::message::object_path& path,
372 const std::string& recordName,
373 const std::string& keyword, const Binary& value)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600374{
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600375 try
376 {
Santosh Puranik8c796812021-12-01 19:17:56 +0530377 std::string objPath{path};
378 // Strip any inventory prefix in path
379 if (objPath.find(INVENTORY_PATH) == 0)
380 {
381 objPath = objPath.substr(sizeof(INVENTORY_PATH) - 1);
382 }
383
384 if (frus.find(objPath) == frus.end())
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600385 {
386 throw std::runtime_error("Inventory path not found");
387 }
388
Santosh Puranika0b23912022-02-10 13:37:09 +0530389 inventory::Path vpdFilePath = std::get<0>(frus.find(objPath)->second);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600390
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500391 // instantiate editor class to update the data
Santosh Puranik8c796812021-12-01 19:17:56 +0530392 EditorImpl edit(vpdFilePath, jsonFile, recordName, keyword, objPath);
Santosh Puranika0b23912022-02-10 13:37:09 +0530393
394 uint32_t offset = 0;
395 // Setup offset, if any
396 for (const auto& item : jsonFile["frus"][vpdFilePath])
397 {
398 if (item.find("offset") != item.end())
399 {
400 offset = item["offset"];
401 break;
402 }
403 }
404
405 edit.updateKeyword(value, offset, true);
406
407 // If we have a redundant EEPROM to update, then update just the EEPROM,
408 // not the cache since that is already done when we updated the primary
409 if (!std::get<1>(frus.find(objPath)->second).empty())
410 {
411 EditorImpl edit(std::get<1>(frus.find(objPath)->second), jsonFile,
Sunny Srivastavaf31a91b2022-06-09 08:11:29 -0500412 recordName, keyword, objPath);
Santosh Puranika0b23912022-02-10 13:37:09 +0530413 edit.updateKeyword(value, offset, false);
414 }
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600415
SunnySrivastava198443306542020-04-01 02:50:20 -0500416 // if it is a motehrboard FRU need to check for location expansion
Santosh Puranika0b23912022-02-10 13:37:09 +0530417 if (std::get<2>(frus.find(objPath)->second))
SunnySrivastava198443306542020-04-01 02:50:20 -0500418 {
419 if (recordName == "VCEN" && (keyword == "FC" || keyword == "SE"))
420 {
421 edit.expandLocationCode("fcs");
422 }
423 else if (recordName == "VSYS" &&
424 (keyword == "TM" || keyword == "SE"))
425 {
426 edit.expandLocationCode("mts");
427 }
428 }
429
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500430 return;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600431 }
432 catch (const std::exception& e)
433 {
434 std::cerr << e.what() << std::endl;
435 }
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600436}
437
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500438ListOfPaths
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600439 Manager::getFRUsByUnexpandedLocationCode(const LocationCode& locationCode,
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500440 const NodeNumber nodeNumber)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600441{
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500442 ReaderImpl read;
443 return read.getFrusAtLocation(locationCode, nodeNumber, fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600444}
445
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500446ListOfPaths
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600447 Manager::getFRUsByExpandedLocationCode(const LocationCode& locationCode)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600448{
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500449 ReaderImpl read;
450 return read.getFRUsByExpandedLocationCode(locationCode, fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600451}
452
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600453LocationCode Manager::getExpandedLocationCode(const LocationCode& locationCode,
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500454 const NodeNumber nodeNumber)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600455{
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -0500456 ReaderImpl read;
457 return read.getExpandedLocationCode(locationCode, nodeNumber,
458 fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600459}
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -0600460
SunnySrivastava19849a195542020-09-07 06:04:50 -0500461void Manager::performVPDRecollection()
462{
463 // get list of FRUs replaceable at standby
464 for (const auto& item : replaceableFrus)
465 {
466 const vector<nlohmann::json>& groupEEPROM = jsonFile["frus"][item];
467 const nlohmann::json& singleFru = groupEEPROM[0];
468
469 const string& inventoryPath =
470 singleFru["inventoryPath"]
471 .get_ref<const nlohmann::json::string_t&>();
472
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530473 bool prePostActionRequired = false;
474
475 if ((jsonFile["frus"][item].at(0)).find("preAction") !=
476 jsonFile["frus"][item].at(0).end())
477 {
Sunny Srivastavaa2ddc962022-06-29 08:53:16 -0500478 try
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530479 {
Sunny Srivastavaa2ddc962022-06-29 08:53:16 -0500480 if (!executePreAction(jsonFile, item))
481 {
482 // if the FRU has preAction defined then its execution
483 // should pass to ensure bind/unbind of data.
484 // preAction execution failed. should not call
485 // bind/unbind.
486 log<level::ERR>(
487 "Pre-Action execution failed for the FRU",
488 entry("ERROR=%s",
489 ("Inventory path: " + inventoryPath).c_str()));
490 continue;
491 }
492 }
493 catch (const GpioException& e)
494 {
495 log<level::ERR>(e.what());
496 PelAdditionalData additionalData{};
497 additionalData.emplace("DESCRIPTION", e.what());
498 createPEL(additionalData, PelSeverity::WARNING,
499 errIntfForGpioError, sdBus);
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530500 continue;
501 }
502 prePostActionRequired = true;
503 }
504
SunnySrivastava19849a195542020-09-07 06:04:50 -0500505 if ((singleFru.find("devAddress") == singleFru.end()) ||
506 (singleFru.find("driverType") == singleFru.end()) ||
507 (singleFru.find("busType") == singleFru.end()))
508 {
509 // The FRUs is marked for replacement but missing mandatory
510 // fields for recollection. Skip to another replaceable fru.
511 log<level::ERR>(
512 "Recollection Failed as mandatory field missing in Json",
513 entry("ERROR=%s",
514 ("Recollection failed for " + inventoryPath).c_str()));
515 continue;
516 }
517
518 string str = "echo ";
519 string deviceAddress = singleFru["devAddress"];
520 const string& driverType = singleFru["driverType"];
521 const string& busType = singleFru["busType"];
522
523 // devTreeStatus flag is present in json as false to mention
524 // that the EEPROM is not mentioned in device tree. If this flag
525 // is absent consider the value to be true, i.e EEPROM is
526 // mentioned in device tree
527 if (!singleFru.value("devTreeStatus", true))
528 {
529 auto pos = deviceAddress.find('-');
530 if (pos != string::npos)
531 {
532 string busNum = deviceAddress.substr(0, pos);
533 deviceAddress =
534 "0x" + deviceAddress.substr(pos + 1, string::npos);
535
536 string deleteDevice = str + deviceAddress + " > /sys/bus/" +
537 busType + "/devices/" + busType + "-" +
538 busNum + "/delete_device";
539 executeCmd(deleteDevice);
540
541 string addDevice = str + driverType + " " + deviceAddress +
542 " > /sys/bus/" + busType + "/devices/" +
543 busType + "-" + busNum + "/new_device";
544 executeCmd(addDevice);
545 }
546 else
547 {
548 log<level::ERR>(
549 "Wrong format of device address in Json",
550 entry(
551 "ERROR=%s",
552 ("Recollection failed for " + inventoryPath).c_str()));
553 continue;
554 }
555 }
556 else
557 {
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500558 executeCmd(createBindUnbindDriverCmnd(deviceAddress, busType,
559 driverType, "/unbind"));
560 executeCmd(createBindUnbindDriverCmnd(deviceAddress, busType,
561 driverType, "/bind"));
SunnySrivastava19849a195542020-09-07 06:04:50 -0500562 }
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530563
564 // this check is added to avoid file system expensive call in case not
565 // required.
566 if (prePostActionRequired)
567 {
568 // Check if device showed up (test for file)
569 if (!filesystem::exists(item))
570 {
Sunny Srivastavaa2ddc962022-06-29 08:53:16 -0500571 try
572 {
573 // If not, then take failure postAction
574 executePostFailAction(jsonFile, item);
575 }
576 catch (const GpioException& e)
577 {
578 PelAdditionalData additionalData{};
579 additionalData.emplace("DESCRIPTION", e.what());
580 createPEL(additionalData, PelSeverity::WARNING,
581 errIntfForGpioError, sdBus);
582 }
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530583 }
584 }
SunnySrivastava19849a195542020-09-07 06:04:50 -0500585 }
586}
587
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600588} // namespace manager
589} // namespace vpd
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500590} // namespace openpower