blob: 407b0ce1b4b6d193536507dcf536ce9d4ba70c9e [file] [log] [blame]
Vishwanatha Subbanna307d80b2017-06-28 15:56:09 +05301#include "occ_status.hpp"
Gunnar Mills94df8c92018-09-14 14:50:03 -05002
Vishwanatha Subbanna6add0b82017-07-21 19:02:37 +05303#include "occ_sensor.hpp"
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +05304#include "utils.hpp"
Gunnar Mills94df8c92018-09-14 14:50:03 -05005
6#include <phosphor-logging/log.hpp>
Vishwanatha Subbanna307d80b2017-06-28 15:56:09 +05307namespace open_power
8{
9namespace occ
10{
11
12// Handles updates to occActive property
13bool Status::occActive(bool value)
14{
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053015 if (value != this->occActive())
16 {
17 if (value)
18 {
19 // Bind the device
20 device.bind();
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053021
Edward A. James9fd2bdc2017-11-08 16:18:57 -060022 // Start watching for errors
23 addErrorWatch();
24
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +053025 // Call into Manager to let know that we have bound
Edward A. James9fd2bdc2017-11-08 16:18:57 -060026 if (this->callBack)
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +053027 {
28 this->callBack(value);
Edward A. James9fd2bdc2017-11-08 16:18:57 -060029 }
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053030 }
31 else
32 {
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +053033 // Call into Manager to let know that we will unbind.
Edward A. James9fd2bdc2017-11-08 16:18:57 -060034 if (this->callBack)
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +053035 {
36 this->callBack(value);
Edward A. James9fd2bdc2017-11-08 16:18:57 -060037 }
38
39 // Stop watching for errors
40 removeErrorWatch();
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053041
42 // Do the unbind.
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053043 device.unBind();
44 }
45 }
Edward A. James5e177972017-10-25 15:50:31 -050046 else if (value && !device.bound())
47 {
48 // Existing error watch is on a dead file descriptor.
Edward A. James9fd2bdc2017-11-08 16:18:57 -060049 removeErrorWatch();
Edward A. James5e177972017-10-25 15:50:31 -050050
51 /*
52 * In it's constructor, Status checks Device::bound() to see if OCC is
53 * active or not.
54 * Device::bound() checks for occX-dev0 directory.
55 * We will lose occX-dev0 directories during FSI rescan.
56 * So, if we start this application (and construct Status), and then
57 * later do FSI rescan, we will end up with occActive = true and device
58 * NOT bound. Lets correct that situation here.
59 */
60 device.bind();
61
62 // Add error watch again
Edward A. James9fd2bdc2017-11-08 16:18:57 -060063 addErrorWatch();
Edward A. James5e177972017-10-25 15:50:31 -050064 }
Eddie James6d6d1b32019-04-22 10:45:08 -050065 else if (!value && device.bound())
66 {
67 removeErrorWatch();
68
69 // In the event that the application never receives the active signal
70 // even though the OCC is active (this can occur if the BMC is rebooted
71 // with the host on, since the initial OCC driver probe will discover
72 // the OCCs), this application needs to be able to unbind the device
73 // when we get the OCC inactive signal.
74 device.unBind();
75 }
Vishwanatha Subbanna307d80b2017-06-28 15:56:09 +053076 return Base::Status::occActive(value);
77}
78
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053079// Callback handler when a device error is reported.
Eddie James482e31f2017-09-14 13:17:17 -050080void Status::deviceErrorHandler(bool error)
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053081{
Eddie James482e31f2017-09-14 13:17:17 -050082 // Make sure we have an error
83 if (error)
84 {
85 // This would deem OCC inactive
86 this->occActive(false);
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053087
Eddie James482e31f2017-09-14 13:17:17 -050088 // Reset the OCC
89 this->resetOCC();
90 }
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053091}
92
93// Sends message to host control command handler to reset OCC
94void Status::resetOCC()
95{
96 using namespace phosphor::logging;
97 constexpr auto CONTROL_HOST_PATH = "/org/open_power/control/host0";
98 constexpr auto CONTROL_HOST_INTF = "org.open_power.Control.Host";
99
100 // This will throw exception on failure
101 auto service = getService(bus, CONTROL_HOST_PATH, CONTROL_HOST_INTF);
102
Gunnar Mills94df8c92018-09-14 14:50:03 -0500103 auto method = bus.new_method_call(service.c_str(), CONTROL_HOST_PATH,
104 CONTROL_HOST_INTF, "Execute");
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530105 // OCC Reset control command
Gunnar Mills94df8c92018-09-14 14:50:03 -0500106 method.append(convertForMessage(Control::Host::Command::OCCReset).c_str());
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530107
108 // OCC Sensor ID for callout reasons
Alexander Filippov1d69e192019-03-21 18:12:07 +0300109 method.append(sdbusplus::message::variant<uint8_t>(
110 std::get<0>(sensorMap.at(instance))));
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530111 bus.call_noreply(method);
112 return;
113}
114
115// Handler called by Host control command handler to convey the
116// status of the executed command
117void Status::hostControlEvent(sdbusplus::message::message& msg)
118{
119 using namespace phosphor::logging;
120
121 std::string cmdCompleted{};
122 std::string cmdStatus{};
123
124 msg.read(cmdCompleted, cmdStatus);
125
126 log<level::DEBUG>("Host control signal values",
Gunnar Mills94df8c92018-09-14 14:50:03 -0500127 entry("COMMAND=%s", cmdCompleted.c_str()),
128 entry("STATUS=%s", cmdStatus.c_str()));
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530129
Gunnar Mills94df8c92018-09-14 14:50:03 -0500130 if (Control::Host::convertResultFromString(cmdStatus) !=
131 Control::Host::Result::Success)
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530132 {
Gunnar Mills94df8c92018-09-14 14:50:03 -0500133 if (Control::Host::convertCommandFromString(cmdCompleted) ==
134 Control::Host::Command::OCCReset)
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530135 {
Gunnar Mills85e65202018-04-08 15:01:54 -0500136 // Must be a Timeout. Log an Error trace
Alexander Filippov1d69e192019-03-21 18:12:07 +0300137 log<level::ERR>(
138 "Error resetting the OCC.", entry("PATH=%s", path.c_str()),
139 entry("SENSORID=0x%X", std::get<0>(sensorMap.at(instance))));
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530140 }
141 }
142 return;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530143}
144
Vishwanatha Subbanna307d80b2017-06-28 15:56:09 +0530145} // namespace occ
146} // namespace open_power