1 #include <phosphor-logging/log.hpp> 2 #include "occ_status.hpp" 3 #include "occ_sensor.hpp" 4 #include "utils.hpp" 5 namespace open_power 6 { 7 namespace occ 8 { 9 10 // Handles updates to occActive property 11 bool Status::occActive(bool value) 12 { 13 if (value != this->occActive()) 14 { 15 if (value) 16 { 17 // Bind the device 18 device.bind(); 19 20 // Call into Manager to let know that we have bound 21 // TODO: openbmc/openbmc#2285 22 /* if (this->callBack) 23 { 24 this->callBack(value); 25 }*/ 26 } 27 else 28 { 29 // Call into Manager to let know that we will unbind. 30 // Need to do this before doing un-bind since it will 31 // result in slave error if Master is un-bound 32 /*if (this->callBack) 33 { 34 this->callBack(value); 35 }*/ 36 37 // Do the unbind. 38 device.unBind(); 39 } 40 } 41 else if (value && !device.bound()) 42 { 43 // Existing error watch is on a dead file descriptor. 44 // TODO: openbmc/openbmc#2285 45 // removeErrorWatch(); 46 47 /* 48 * In it's constructor, Status checks Device::bound() to see if OCC is 49 * active or not. 50 * Device::bound() checks for occX-dev0 directory. 51 * We will lose occX-dev0 directories during FSI rescan. 52 * So, if we start this application (and construct Status), and then 53 * later do FSI rescan, we will end up with occActive = true and device 54 * NOT bound. Lets correct that situation here. 55 */ 56 device.bind(); 57 58 // Add error watch again 59 // TODO: openbmc/openbmc#2285 60 // addErrorWatch(); 61 } 62 return Base::Status::occActive(value); 63 } 64 65 // Callback handler when a device error is reported. 66 void Status::deviceErrorHandler() 67 { 68 // This would deem OCC inactive 69 this->occActive(false); 70 71 // Reset the OCC 72 this->resetOCC(); 73 } 74 75 // Sends message to host control command handler to reset OCC 76 void Status::resetOCC() 77 { 78 using namespace phosphor::logging; 79 constexpr auto CONTROL_HOST_PATH = "/org/open_power/control/host0"; 80 constexpr auto CONTROL_HOST_INTF = "org.open_power.Control.Host"; 81 82 // This will throw exception on failure 83 auto service = getService(bus, CONTROL_HOST_PATH, CONTROL_HOST_INTF); 84 85 auto method = bus.new_method_call(service.c_str(), 86 CONTROL_HOST_PATH, 87 CONTROL_HOST_INTF, 88 "Execute"); 89 // OCC Reset control command 90 method.append(convertForMessage( 91 Control::Host::Command::OCCReset).c_str()); 92 93 // OCC Sensor ID for callout reasons 94 method.append(sdbusplus::message::variant<uint8_t>( 95 sensorMap.at(instance))); 96 bus.call_noreply(method); 97 return; 98 } 99 100 // Handler called by Host control command handler to convey the 101 // status of the executed command 102 void Status::hostControlEvent(sdbusplus::message::message& msg) 103 { 104 using namespace phosphor::logging; 105 106 std::string cmdCompleted{}; 107 std::string cmdStatus{}; 108 109 msg.read(cmdCompleted, cmdStatus); 110 111 log<level::DEBUG>("Host control signal values", 112 entry("COMMAND=%s",cmdCompleted.c_str()), 113 entry("STATUS=%s",cmdStatus.c_str())); 114 115 if(Control::Host::convertResultFromString(cmdStatus) != 116 Control::Host::Result::Success) 117 { 118 if(Control::Host::convertCommandFromString(cmdCompleted) == 119 Control::Host::Command::OCCReset) 120 { 121 // Must be a Timeout. Log an Erorr trace 122 log<level::ERR>("Error resetting the OCC.", 123 entry("PATH=%s", path.c_str()), 124 entry("SENSORID=0x%X",sensorMap.at(instance))); 125 } 126 } 127 return; 128 } 129 130 } // namespace occ 131 } // namespace open_power 132