blob: f4bf8a9dca5437c255027deee1361d90f0dccf4f [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
Chris Caina8857c52021-01-27 11:53:05 -06006#include <fmt/core.h>
7
Gunnar Mills94df8c92018-09-14 14:50:03 -05008#include <phosphor-logging/log.hpp>
Vishwanatha Subbanna307d80b2017-06-28 15:56:09 +05309namespace open_power
10{
11namespace occ
12{
Chris Caina8857c52021-01-27 11:53:05 -060013using namespace phosphor::logging;
Vishwanatha Subbanna307d80b2017-06-28 15:56:09 +053014
15// Handles updates to occActive property
16bool Status::occActive(bool value)
17{
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053018 if (value != this->occActive())
19 {
Chris Caina8857c52021-01-27 11:53:05 -060020 log<level::INFO>(fmt::format("Status::occActive OCC{} changed to {}",
21 instance, value)
22 .c_str());
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053023 if (value)
24 {
25 // Bind the device
26 device.bind();
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053027
Edward A. James9fd2bdc2017-11-08 16:18:57 -060028 // Start watching for errors
29 addErrorWatch();
30
Chris Caina8857c52021-01-27 11:53:05 -060031 // Reset last OCC state
32 lastState = 0;
33
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +053034 // Call into Manager to let know that we have bound
Edward A. James9fd2bdc2017-11-08 16:18:57 -060035 if (this->callBack)
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +053036 {
37 this->callBack(value);
Edward A. James9fd2bdc2017-11-08 16:18:57 -060038 }
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053039 }
40 else
41 {
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +053042 // Call into Manager to let know that we will unbind.
Edward A. James9fd2bdc2017-11-08 16:18:57 -060043 if (this->callBack)
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +053044 {
45 this->callBack(value);
Edward A. James9fd2bdc2017-11-08 16:18:57 -060046 }
47
48 // Stop watching for errors
49 removeErrorWatch();
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053050
51 // Do the unbind.
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053052 device.unBind();
53 }
54 }
Edward A. James5e177972017-10-25 15:50:31 -050055 else if (value && !device.bound())
56 {
57 // Existing error watch is on a dead file descriptor.
Edward A. James9fd2bdc2017-11-08 16:18:57 -060058 removeErrorWatch();
Edward A. James5e177972017-10-25 15:50:31 -050059
60 /*
61 * In it's constructor, Status checks Device::bound() to see if OCC is
62 * active or not.
63 * Device::bound() checks for occX-dev0 directory.
64 * We will lose occX-dev0 directories during FSI rescan.
65 * So, if we start this application (and construct Status), and then
66 * later do FSI rescan, we will end up with occActive = true and device
67 * NOT bound. Lets correct that situation here.
68 */
69 device.bind();
70
71 // Add error watch again
Edward A. James9fd2bdc2017-11-08 16:18:57 -060072 addErrorWatch();
Edward A. James5e177972017-10-25 15:50:31 -050073 }
Eddie James6d6d1b32019-04-22 10:45:08 -050074 else if (!value && device.bound())
75 {
76 removeErrorWatch();
77
78 // In the event that the application never receives the active signal
79 // even though the OCC is active (this can occur if the BMC is rebooted
80 // with the host on, since the initial OCC driver probe will discover
81 // the OCCs), this application needs to be able to unbind the device
82 // when we get the OCC inactive signal.
83 device.unBind();
84 }
Vishwanatha Subbanna307d80b2017-06-28 15:56:09 +053085 return Base::Status::occActive(value);
86}
87
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053088// Callback handler when a device error is reported.
Eddie James482e31f2017-09-14 13:17:17 -050089void Status::deviceErrorHandler(bool error)
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053090{
Eddie James482e31f2017-09-14 13:17:17 -050091 // Make sure we have an error
92 if (error)
93 {
94 // This would deem OCC inactive
95 this->occActive(false);
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +053096
Eddie James482e31f2017-09-14 13:17:17 -050097 // Reset the OCC
98 this->resetOCC();
99 }
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530100}
101
102// Sends message to host control command handler to reset OCC
103void Status::resetOCC()
104{
Chris Caina8857c52021-01-27 11:53:05 -0600105 log<level::INFO>(
106 fmt::format(">>Status::resetOCC() - requesting reset for OCC{}",
107 instance)
108 .c_str());
Tom Joseph00325232020-07-29 17:51:48 +0530109#ifdef PLDM
110 if (resetCallBack)
111 {
112 this->resetCallBack(instance);
113 }
114#else
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530115 constexpr auto CONTROL_HOST_PATH = "/org/open_power/control/host0";
116 constexpr auto CONTROL_HOST_INTF = "org.open_power.Control.Host";
117
118 // This will throw exception on failure
George Liuf3b75142021-06-10 11:22:50 +0800119 auto service = utils::getService(CONTROL_HOST_PATH, CONTROL_HOST_INTF);
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530120
George Liuf3b75142021-06-10 11:22:50 +0800121 auto& bus = utils::getBus();
Gunnar Mills94df8c92018-09-14 14:50:03 -0500122 auto method = bus.new_method_call(service.c_str(), CONTROL_HOST_PATH,
123 CONTROL_HOST_INTF, "Execute");
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530124 // OCC Reset control command
Gunnar Mills94df8c92018-09-14 14:50:03 -0500125 method.append(convertForMessage(Control::Host::Command::OCCReset).c_str());
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530126
127 // OCC Sensor ID for callout reasons
Patrick Williamse0962702020-05-13 17:50:22 -0500128 method.append(std::variant<uint8_t>(std::get<0>(sensorMap.at(instance))));
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530129 bus.call_noreply(method);
130 return;
Tom Joseph00325232020-07-29 17:51:48 +0530131#endif
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530132}
133
134// Handler called by Host control command handler to convey the
135// status of the executed command
136void Status::hostControlEvent(sdbusplus::message::message& msg)
137{
138 using namespace phosphor::logging;
139
140 std::string cmdCompleted{};
141 std::string cmdStatus{};
142
143 msg.read(cmdCompleted, cmdStatus);
144
145 log<level::DEBUG>("Host control signal values",
Gunnar Mills94df8c92018-09-14 14:50:03 -0500146 entry("COMMAND=%s", cmdCompleted.c_str()),
147 entry("STATUS=%s", cmdStatus.c_str()));
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530148
Gunnar Mills94df8c92018-09-14 14:50:03 -0500149 if (Control::Host::convertResultFromString(cmdStatus) !=
150 Control::Host::Result::Success)
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530151 {
Gunnar Mills94df8c92018-09-14 14:50:03 -0500152 if (Control::Host::convertCommandFromString(cmdCompleted) ==
153 Control::Host::Command::OCCReset)
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530154 {
Gunnar Mills85e65202018-04-08 15:01:54 -0500155 // Must be a Timeout. Log an Error trace
Alexander Filippov1d69e192019-03-21 18:12:07 +0300156 log<level::ERR>(
157 "Error resetting the OCC.", entry("PATH=%s", path.c_str()),
158 entry("SENSORID=0x%X", std::get<0>(sensorMap.at(instance))));
Vishwanatha Subbanna30e329a2017-07-24 23:13:14 +0530159 }
160 }
161 return;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530162}
163
Chris Caina8857c52021-01-27 11:53:05 -0600164void Status::readOccState()
165{
166 unsigned int state;
167 const fs::path filename =
168 fs::path(DEV_PATH) /
169 fs::path(sysfsName + "." + std::to_string(instance + 1)) / "occ_state";
170
171 log<level::DEBUG>(
172 fmt::format("Status::readOccState: reading OCC{} state from {}",
173 instance, filename.c_str())
174 .c_str());
175
176 std::ifstream file(filename, std::ios::in);
177 const int open_errno = errno;
178 if (file)
179 {
180 file >> state;
181 if (state != lastState)
182 {
183 // Trace OCC state changes
184 log<level::INFO>(
185 fmt::format("Status::readOccState: OCC{} state 0x{:02X}",
186 instance, state)
187 .c_str());
188 lastState = state;
189 }
190 file.close();
191 }
192 else
193 {
194 // If not able to read, OCC may be offline
195 log<level::DEBUG>(
196 fmt::format("Status::readOccState: open failed (errno={})",
197 open_errno)
198 .c_str());
199 lastState = 0;
200 }
201}
202
Vishwanatha Subbanna307d80b2017-06-28 15:56:09 +0530203} // namespace occ
204} // namespace open_power