1*bb90afc7SBen Tyner #include <libpldm/platform.h> 2*bb90afc7SBen Tyner #include <libpldm/pldm.h> 3*bb90afc7SBen Tyner #include <libpldm/state_set_oem_ibm.h> 4*bb90afc7SBen Tyner 5*bb90afc7SBen Tyner #include <util/dbus.hpp> 6*bb90afc7SBen Tyner #include <util/trace.hpp> 7*bb90afc7SBen Tyner 8*bb90afc7SBen Tyner namespace util 9*bb90afc7SBen Tyner { 10*bb90afc7SBen Tyner namespace pldm 11*bb90afc7SBen Tyner { 12*bb90afc7SBen Tyner /** @brief Send PLDM request 13*bb90afc7SBen Tyner * 14*bb90afc7SBen Tyner * @param[in] request - the request data 15*bb90afc7SBen Tyner * @param[in] mcptEid - the mctp endpoint ID 16*bb90afc7SBen Tyner * @param[out] pldmFd - pldm socket file descriptor 17*bb90afc7SBen Tyner * 18*bb90afc7SBen Tyner * @pre a mctp instance must have been 19*bb90afc7SBen Tyner * @return true if send is successful false otherwise 20*bb90afc7SBen Tyner */ 21*bb90afc7SBen Tyner bool sendPldm(const std::vector<uint8_t>& request, uint8_t mctpEid, int& pldmFd) 22*bb90afc7SBen Tyner { 23*bb90afc7SBen Tyner // connect to socket 24*bb90afc7SBen Tyner pldmFd = pldm_open(); 25*bb90afc7SBen Tyner if (-1 == pldmFd) 26*bb90afc7SBen Tyner { 27*bb90afc7SBen Tyner trace::err("failed to connect to pldm"); 28*bb90afc7SBen Tyner return false; 29*bb90afc7SBen Tyner } 30*bb90afc7SBen Tyner 31*bb90afc7SBen Tyner // send PLDM request 32*bb90afc7SBen Tyner auto pldmRc = pldm_send(mctpEid, pldmFd, request.data(), request.size()); 33*bb90afc7SBen Tyner 34*bb90afc7SBen Tyner trace::inf("sent pldm request"); 35*bb90afc7SBen Tyner 36*bb90afc7SBen Tyner return pldmRc == PLDM_REQUESTER_SUCCESS ? true : false; 37*bb90afc7SBen Tyner } 38*bb90afc7SBen Tyner 39*bb90afc7SBen Tyner /** @brief Prepare a request for SetStateEffecterStates 40*bb90afc7SBen Tyner * 41*bb90afc7SBen Tyner * @param[in] effecterId - the effecter ID 42*bb90afc7SBen Tyner * @param[in] effecterCount - composite effecter count 43*bb90afc7SBen Tyner * @param[in] stateIdPos - position of the state set 44*bb90afc7SBen Tyner * @param[in] stateSetValue - the value to set the state 45*bb90afc7SBen Tyner * @param[in] mcptEid - the MCTP endpoint ID 46*bb90afc7SBen Tyner * 47*bb90afc7SBen Tyner * @return PLDM request message to be sent to host, empty message on error 48*bb90afc7SBen Tyner */ 49*bb90afc7SBen Tyner std::vector<uint8_t> prepareSetEffecterReq(uint16_t effecterId, 50*bb90afc7SBen Tyner uint8_t effecterCount, 51*bb90afc7SBen Tyner uint8_t stateIdPos, 52*bb90afc7SBen Tyner uint8_t stateSetValue, 53*bb90afc7SBen Tyner uint8_t mctpEid) 54*bb90afc7SBen Tyner { 55*bb90afc7SBen Tyner // get mctp instance associated with the endpoint ID 56*bb90afc7SBen Tyner uint8_t mctpInstance; 57*bb90afc7SBen Tyner if (!util::dbus::getMctpInstance(mctpInstance, mctpEid)) 58*bb90afc7SBen Tyner { 59*bb90afc7SBen Tyner return std::vector<uint8_t>(); 60*bb90afc7SBen Tyner } 61*bb90afc7SBen Tyner 62*bb90afc7SBen Tyner // form the request message 63*bb90afc7SBen Tyner std::vector<uint8_t> request( 64*bb90afc7SBen Tyner sizeof(pldm_msg_hdr) + sizeof(effecterId) + sizeof(effecterCount) + 65*bb90afc7SBen Tyner (effecterCount * sizeof(set_effecter_state_field))); 66*bb90afc7SBen Tyner 67*bb90afc7SBen Tyner // encode the state data with the change we want to elicit 68*bb90afc7SBen Tyner std::vector<set_effecter_state_field> stateField; 69*bb90afc7SBen Tyner for (uint8_t effecterPos = 0; effecterPos < effecterCount; effecterPos++) 70*bb90afc7SBen Tyner { 71*bb90afc7SBen Tyner if (effecterPos == stateIdPos) 72*bb90afc7SBen Tyner { 73*bb90afc7SBen Tyner stateField.emplace_back( 74*bb90afc7SBen Tyner set_effecter_state_field{PLDM_REQUEST_SET, stateSetValue}); 75*bb90afc7SBen Tyner } 76*bb90afc7SBen Tyner else 77*bb90afc7SBen Tyner { 78*bb90afc7SBen Tyner stateField.emplace_back( 79*bb90afc7SBen Tyner set_effecter_state_field{PLDM_NO_CHANGE, 0}); 80*bb90afc7SBen Tyner } 81*bb90afc7SBen Tyner } 82*bb90afc7SBen Tyner 83*bb90afc7SBen Tyner // encode the message with state data 84*bb90afc7SBen Tyner auto requestMsg = reinterpret_cast<pldm_msg*>(request.data()); 85*bb90afc7SBen Tyner auto rc = encode_set_state_effecter_states_req( 86*bb90afc7SBen Tyner mctpInstance, effecterId, effecterCount, stateField.data(), requestMsg); 87*bb90afc7SBen Tyner 88*bb90afc7SBen Tyner if (rc != PLDM_SUCCESS) 89*bb90afc7SBen Tyner { 90*bb90afc7SBen Tyner trace::err("encode set effecter states request failed"); 91*bb90afc7SBen Tyner request.clear(); 92*bb90afc7SBen Tyner } 93*bb90afc7SBen Tyner 94*bb90afc7SBen Tyner return request; 95*bb90afc7SBen Tyner } 96*bb90afc7SBen Tyner 97*bb90afc7SBen Tyner /** @brief Return map of sensor ID to SBE instance 98*bb90afc7SBen Tyner * 99*bb90afc7SBen Tyner * @param[in] stateSetId - the state set ID of interest 100*bb90afc7SBen Tyner * @param[out] sensorInstanceMap - map of sensor to SBE instance 101*bb90afc7SBen Tyner * @param[out] sensorOffset - position of sensor with state set ID within map 102*bb90afc7SBen Tyner * 103*bb90afc7SBen Tyner * @return true if sensor info is available false otherwise 104*bb90afc7SBen Tyner */ 105*bb90afc7SBen Tyner bool fetchSensorInfo(uint16_t stateSetId, 106*bb90afc7SBen Tyner std::map<uint16_t, unsigned int>& sensorInstanceMap, 107*bb90afc7SBen Tyner uint8_t& sensorOffset) 108*bb90afc7SBen Tyner { 109*bb90afc7SBen Tyner // get state sensor PDRs 110*bb90afc7SBen Tyner std::vector<std::vector<uint8_t>> pdrs{}; 111*bb90afc7SBen Tyner if (!util::dbus::getStateSensorPdrs(pdrs, stateSetId)) 112*bb90afc7SBen Tyner { 113*bb90afc7SBen Tyner return false; 114*bb90afc7SBen Tyner } 115*bb90afc7SBen Tyner 116*bb90afc7SBen Tyner // check for any PDRs available 117*bb90afc7SBen Tyner if (!pdrs.size()) 118*bb90afc7SBen Tyner { 119*bb90afc7SBen Tyner trace::err("state sensor PDRs not present"); 120*bb90afc7SBen Tyner return false; 121*bb90afc7SBen Tyner } 122*bb90afc7SBen Tyner 123*bb90afc7SBen Tyner // find the offset of specified sensor withing PDRs 124*bb90afc7SBen Tyner bool offsetFound = false; 125*bb90afc7SBen Tyner auto stateSensorPDR = 126*bb90afc7SBen Tyner reinterpret_cast<const pldm_state_sensor_pdr*>(pdrs.front().data()); 127*bb90afc7SBen Tyner auto possibleStatesPtr = stateSensorPDR->possible_states; 128*bb90afc7SBen Tyner 129*bb90afc7SBen Tyner for (auto offset = 0; offset < stateSensorPDR->composite_sensor_count; 130*bb90afc7SBen Tyner offset++) 131*bb90afc7SBen Tyner { 132*bb90afc7SBen Tyner auto possibleStates = 133*bb90afc7SBen Tyner reinterpret_cast<const state_sensor_possible_states*>( 134*bb90afc7SBen Tyner possibleStatesPtr); 135*bb90afc7SBen Tyner 136*bb90afc7SBen Tyner if (possibleStates->state_set_id == stateSetId) 137*bb90afc7SBen Tyner { 138*bb90afc7SBen Tyner sensorOffset = offset; 139*bb90afc7SBen Tyner offsetFound = true; 140*bb90afc7SBen Tyner break; 141*bb90afc7SBen Tyner } 142*bb90afc7SBen Tyner possibleStatesPtr += sizeof(possibleStates->state_set_id) + 143*bb90afc7SBen Tyner sizeof(possibleStates->possible_states_size) + 144*bb90afc7SBen Tyner possibleStates->possible_states_size; 145*bb90afc7SBen Tyner } 146*bb90afc7SBen Tyner 147*bb90afc7SBen Tyner if (!offsetFound) 148*bb90afc7SBen Tyner { 149*bb90afc7SBen Tyner trace::err("state sensor not found"); 150*bb90afc7SBen Tyner return false; 151*bb90afc7SBen Tyner } 152*bb90afc7SBen Tyner 153*bb90afc7SBen Tyner // map sensor ID to equivelent 16 bit value 154*bb90afc7SBen Tyner std::map<uint32_t, uint16_t> entityInstMap{}; 155*bb90afc7SBen Tyner for (auto& pdr : pdrs) 156*bb90afc7SBen Tyner { 157*bb90afc7SBen Tyner auto pdrPtr = 158*bb90afc7SBen Tyner reinterpret_cast<const pldm_state_sensor_pdr*>(pdr.data()); 159*bb90afc7SBen Tyner uint32_t key = pdrPtr->sensor_id; 160*bb90afc7SBen Tyner entityInstMap.emplace(key, static_cast<uint16_t>(pdrPtr->sensor_id)); 161*bb90afc7SBen Tyner } 162*bb90afc7SBen Tyner 163*bb90afc7SBen Tyner // map sensor ID to zero based SBE instance 164*bb90afc7SBen Tyner unsigned int position = 0; 165*bb90afc7SBen Tyner for (auto const& pair : entityInstMap) 166*bb90afc7SBen Tyner { 167*bb90afc7SBen Tyner sensorInstanceMap.emplace(pair.second, position); 168*bb90afc7SBen Tyner position++; 169*bb90afc7SBen Tyner } 170*bb90afc7SBen Tyner 171*bb90afc7SBen Tyner return true; 172*bb90afc7SBen Tyner } 173*bb90afc7SBen Tyner 174*bb90afc7SBen Tyner /** @brief Return map of SBE instance to effecter ID 175*bb90afc7SBen Tyner * 176*bb90afc7SBen Tyner * @param[in] stateSetId - the state set ID of interest 177*bb90afc7SBen Tyner * @param[out] instanceToEffecterMap - map of sbe instance to effecter ID 178*bb90afc7SBen Tyner * @param[out] effecterCount - composite effecter count 179*bb90afc7SBen Tyner * @param[out] stateIdPos - position of effecter with state set ID within map 180*bb90afc7SBen Tyner * 181*bb90afc7SBen Tyner * @return true if effector info is available false otherwise 182*bb90afc7SBen Tyner */ 183*bb90afc7SBen Tyner bool fetchEffecterInfo(uint16_t stateSetId, 184*bb90afc7SBen Tyner std::map<unsigned int, uint16_t>& instanceToEffecterMap, 185*bb90afc7SBen Tyner uint8_t& effecterCount, uint8_t& stateIdPos) 186*bb90afc7SBen Tyner { 187*bb90afc7SBen Tyner // get state effecter PDRs 188*bb90afc7SBen Tyner std::vector<std::vector<uint8_t>> pdrs{}; 189*bb90afc7SBen Tyner if (!util::dbus::getStateEffecterPdrs(pdrs, stateSetId)) 190*bb90afc7SBen Tyner { 191*bb90afc7SBen Tyner return false; 192*bb90afc7SBen Tyner } 193*bb90afc7SBen Tyner 194*bb90afc7SBen Tyner // check for any PDRs available 195*bb90afc7SBen Tyner if (!pdrs.size()) 196*bb90afc7SBen Tyner { 197*bb90afc7SBen Tyner trace::err("state effecter PDRs not present"); 198*bb90afc7SBen Tyner return false; 199*bb90afc7SBen Tyner } 200*bb90afc7SBen Tyner 201*bb90afc7SBen Tyner // find the offset of specified effector within PDRs 202*bb90afc7SBen Tyner bool offsetFound = false; 203*bb90afc7SBen Tyner auto stateEffecterPDR = 204*bb90afc7SBen Tyner reinterpret_cast<const pldm_state_effecter_pdr*>(pdrs.front().data()); 205*bb90afc7SBen Tyner auto possibleStatesPtr = stateEffecterPDR->possible_states; 206*bb90afc7SBen Tyner 207*bb90afc7SBen Tyner for (auto offset = 0; offset < stateEffecterPDR->composite_effecter_count; 208*bb90afc7SBen Tyner offset++) 209*bb90afc7SBen Tyner { 210*bb90afc7SBen Tyner auto possibleStates = 211*bb90afc7SBen Tyner reinterpret_cast<const state_effecter_possible_states*>( 212*bb90afc7SBen Tyner possibleStatesPtr); 213*bb90afc7SBen Tyner 214*bb90afc7SBen Tyner if (possibleStates->state_set_id == stateSetId) 215*bb90afc7SBen Tyner { 216*bb90afc7SBen Tyner stateIdPos = offset; 217*bb90afc7SBen Tyner effecterCount = stateEffecterPDR->composite_effecter_count; 218*bb90afc7SBen Tyner offsetFound = true; 219*bb90afc7SBen Tyner break; 220*bb90afc7SBen Tyner } 221*bb90afc7SBen Tyner possibleStatesPtr += sizeof(possibleStates->state_set_id) + 222*bb90afc7SBen Tyner sizeof(possibleStates->possible_states_size) + 223*bb90afc7SBen Tyner possibleStates->possible_states_size; 224*bb90afc7SBen Tyner } 225*bb90afc7SBen Tyner 226*bb90afc7SBen Tyner if (!offsetFound) 227*bb90afc7SBen Tyner { 228*bb90afc7SBen Tyner trace::err("state set effecter not found"); 229*bb90afc7SBen Tyner return false; 230*bb90afc7SBen Tyner } 231*bb90afc7SBen Tyner 232*bb90afc7SBen Tyner // map effecter ID to equivelent 16 bit value 233*bb90afc7SBen Tyner std::map<uint32_t, uint16_t> entityInstMap{}; 234*bb90afc7SBen Tyner for (auto& pdr : pdrs) 235*bb90afc7SBen Tyner { 236*bb90afc7SBen Tyner auto pdrPtr = 237*bb90afc7SBen Tyner reinterpret_cast<const pldm_state_effecter_pdr*>(pdr.data()); 238*bb90afc7SBen Tyner uint32_t key = pdrPtr->effecter_id; 239*bb90afc7SBen Tyner entityInstMap.emplace(key, static_cast<uint16_t>(pdrPtr->effecter_id)); 240*bb90afc7SBen Tyner } 241*bb90afc7SBen Tyner 242*bb90afc7SBen Tyner // map zero based SBE instance to effecter ID 243*bb90afc7SBen Tyner unsigned int position = 0; 244*bb90afc7SBen Tyner for (auto const& pair : entityInstMap) 245*bb90afc7SBen Tyner { 246*bb90afc7SBen Tyner instanceToEffecterMap.emplace(position, pair.second); 247*bb90afc7SBen Tyner position++; 248*bb90afc7SBen Tyner } 249*bb90afc7SBen Tyner 250*bb90afc7SBen Tyner return true; 251*bb90afc7SBen Tyner } 252*bb90afc7SBen Tyner 253*bb90afc7SBen Tyner /** @brief Reset SBE using HBRT PLDM interface */ 254*bb90afc7SBen Tyner bool hresetSbe(unsigned int sbeInstance) 255*bb90afc7SBen Tyner { 256*bb90afc7SBen Tyner trace::inf("requesting sbe hreset"); 257*bb90afc7SBen Tyner 258*bb90afc7SBen Tyner // get effecter info 259*bb90afc7SBen Tyner std::map<unsigned int, uint16_t> sbeInstanceToEffecter; 260*bb90afc7SBen Tyner uint8_t SBEEffecterCount = 0; 261*bb90afc7SBen Tyner uint8_t sbeMaintenanceStatePosition = 0; 262*bb90afc7SBen Tyner 263*bb90afc7SBen Tyner if (!fetchEffecterInfo(PLDM_OEM_IBM_SBE_MAINTENANCE_STATE, 264*bb90afc7SBen Tyner sbeInstanceToEffecter, SBEEffecterCount, 265*bb90afc7SBen Tyner sbeMaintenanceStatePosition)) 266*bb90afc7SBen Tyner { 267*bb90afc7SBen Tyner return false; 268*bb90afc7SBen Tyner } 269*bb90afc7SBen Tyner 270*bb90afc7SBen Tyner // find the state effecter ID for the given SBE instance 271*bb90afc7SBen Tyner auto effecterEntry = sbeInstanceToEffecter.find(sbeInstance); 272*bb90afc7SBen Tyner if (effecterEntry == sbeInstanceToEffecter.end()) 273*bb90afc7SBen Tyner { 274*bb90afc7SBen Tyner trace::err("failed to find effecter for SBE"); 275*bb90afc7SBen Tyner return false; 276*bb90afc7SBen Tyner } 277*bb90afc7SBen Tyner 278*bb90afc7SBen Tyner // create request to HRESET the SBE 279*bb90afc7SBen Tyner constexpr uint8_t hbrtMctpEid = 10; // HBRT MCTP EID 280*bb90afc7SBen Tyner 281*bb90afc7SBen Tyner auto request = prepareSetEffecterReq( 282*bb90afc7SBen Tyner effecterEntry->second, SBEEffecterCount, sbeMaintenanceStatePosition, 283*bb90afc7SBen Tyner SBE_RETRY_REQUIRED, hbrtMctpEid); 284*bb90afc7SBen Tyner 285*bb90afc7SBen Tyner if (request.empty()) 286*bb90afc7SBen Tyner { 287*bb90afc7SBen Tyner trace::err("HRESET effecter request empty"); 288*bb90afc7SBen Tyner return false; 289*bb90afc7SBen Tyner } 290*bb90afc7SBen Tyner 291*bb90afc7SBen Tyner // get sensor info for validating sensor change 292*bb90afc7SBen Tyner std::map<uint16_t, unsigned int> sensorToSbeInstance; 293*bb90afc7SBen Tyner uint8_t sbeSensorOffset = 0; 294*bb90afc7SBen Tyner if (!fetchSensorInfo(PLDM_OEM_IBM_SBE_HRESET_STATE, sensorToSbeInstance, 295*bb90afc7SBen Tyner sbeSensorOffset)) 296*bb90afc7SBen Tyner { 297*bb90afc7SBen Tyner return false; 298*bb90afc7SBen Tyner } 299*bb90afc7SBen Tyner 300*bb90afc7SBen Tyner // register signal change listener 301*bb90afc7SBen Tyner std::string hresetStatus = "requested"; 302*bb90afc7SBen Tyner constexpr auto interface = "xyz.openbmc_project.PLDM.Event"; 303*bb90afc7SBen Tyner constexpr auto path = "/xyz/openbmc_project/pldm"; 304*bb90afc7SBen Tyner constexpr auto member = "StateSensorEvent"; 305*bb90afc7SBen Tyner 306*bb90afc7SBen Tyner auto bus = sdbusplus::bus::new_default(); 307*bb90afc7SBen Tyner std::unique_ptr<sdbusplus::bus::match_t> match = 308*bb90afc7SBen Tyner std::make_unique<sdbusplus::bus::match_t>( 309*bb90afc7SBen Tyner bus, 310*bb90afc7SBen Tyner sdbusplus::bus::match::rules::type::signal() + 311*bb90afc7SBen Tyner sdbusplus::bus::match::rules::member(member) + 312*bb90afc7SBen Tyner sdbusplus::bus::match::rules::path(path) + 313*bb90afc7SBen Tyner sdbusplus::bus::match::rules::interface(interface), 314*bb90afc7SBen Tyner [&](auto& msg) { 315*bb90afc7SBen Tyner uint8_t sensorTid{}; 316*bb90afc7SBen Tyner uint16_t sensorId{}; 317*bb90afc7SBen Tyner uint8_t msgSensorOffset{}; 318*bb90afc7SBen Tyner uint8_t eventState{}; 319*bb90afc7SBen Tyner uint8_t previousEventState{}; 320*bb90afc7SBen Tyner 321*bb90afc7SBen Tyner // get sensor event details 322*bb90afc7SBen Tyner msg.read(sensorTid, sensorId, msgSensorOffset, eventState, 323*bb90afc7SBen Tyner previousEventState); 324*bb90afc7SBen Tyner 325*bb90afc7SBen Tyner // does sensor offset match? 326*bb90afc7SBen Tyner if (sbeSensorOffset == msgSensorOffset) 327*bb90afc7SBen Tyner { 328*bb90afc7SBen Tyner // does sensor ID match? 329*bb90afc7SBen Tyner auto sensorEntry = sensorToSbeInstance.find(sensorId); 330*bb90afc7SBen Tyner if (sensorEntry != sensorToSbeInstance.end()) 331*bb90afc7SBen Tyner { 332*bb90afc7SBen Tyner const uint8_t instance = sensorEntry->second; 333*bb90afc7SBen Tyner 334*bb90afc7SBen Tyner // if instances matche check status 335*bb90afc7SBen Tyner if (instance == sbeInstance) 336*bb90afc7SBen Tyner { 337*bb90afc7SBen Tyner if (eventState == 338*bb90afc7SBen Tyner static_cast<uint8_t>(SBE_HRESET_READY)) 339*bb90afc7SBen Tyner { 340*bb90afc7SBen Tyner hresetStatus = "success"; 341*bb90afc7SBen Tyner } 342*bb90afc7SBen Tyner else if (eventState == 343*bb90afc7SBen Tyner static_cast<uint8_t>(SBE_HRESET_FAILED)) 344*bb90afc7SBen Tyner { 345*bb90afc7SBen Tyner hresetStatus = "fail"; 346*bb90afc7SBen Tyner } 347*bb90afc7SBen Tyner } 348*bb90afc7SBen Tyner } 349*bb90afc7SBen Tyner } 350*bb90afc7SBen Tyner }); 351*bb90afc7SBen Tyner 352*bb90afc7SBen Tyner // send request to issue hreset of sbe 353*bb90afc7SBen Tyner int pldmFd = -1; // mctp socket file descriptor 354*bb90afc7SBen Tyner if (!sendPldm(request, hbrtMctpEid, pldmFd)) 355*bb90afc7SBen Tyner { 356*bb90afc7SBen Tyner trace::err("send pldm request failed"); 357*bb90afc7SBen Tyner if (-1 != pldmFd) 358*bb90afc7SBen Tyner { 359*bb90afc7SBen Tyner close(pldmFd); 360*bb90afc7SBen Tyner } 361*bb90afc7SBen Tyner return false; 362*bb90afc7SBen Tyner } 363*bb90afc7SBen Tyner 364*bb90afc7SBen Tyner // keep track of elapsed time 365*bb90afc7SBen Tyner uint64_t timeRemaining = 60000000; // microseconds, 1 minute 366*bb90afc7SBen Tyner std::chrono::steady_clock::time_point begin = 367*bb90afc7SBen Tyner std::chrono::steady_clock::now(); 368*bb90afc7SBen Tyner 369*bb90afc7SBen Tyner // wait for status update or timeout 370*bb90afc7SBen Tyner trace::inf("waiting on sbe hreset"); 371*bb90afc7SBen Tyner while ("requested" == hresetStatus && 0 != timeRemaining) 372*bb90afc7SBen Tyner { 373*bb90afc7SBen Tyner bus.wait(timeRemaining); 374*bb90afc7SBen Tyner uint64_t timeElapsed = 375*bb90afc7SBen Tyner std::chrono::duration_cast<std::chrono::microseconds>( 376*bb90afc7SBen Tyner std::chrono::steady_clock::now() - begin) 377*bb90afc7SBen Tyner .count(); 378*bb90afc7SBen Tyner 379*bb90afc7SBen Tyner timeRemaining = 380*bb90afc7SBen Tyner timeElapsed > timeRemaining ? 0 : timeRemaining - timeElapsed; 381*bb90afc7SBen Tyner 382*bb90afc7SBen Tyner bus.process_discard(); 383*bb90afc7SBen Tyner } 384*bb90afc7SBen Tyner 385*bb90afc7SBen Tyner if (0 == timeRemaining) 386*bb90afc7SBen Tyner { 387*bb90afc7SBen Tyner trace::err("hreset timed out"); 388*bb90afc7SBen Tyner } 389*bb90afc7SBen Tyner 390*bb90afc7SBen Tyner close(pldmFd); // close pldm socket 391*bb90afc7SBen Tyner 392*bb90afc7SBen Tyner return hresetStatus == "success" ? true : false; 393*bb90afc7SBen Tyner } 394*bb90afc7SBen Tyner 395*bb90afc7SBen Tyner } // namespace pldm 396*bb90afc7SBen Tyner } // namespace util 397