blob: a92d824a5d7f887b9df2faff4e69660d5870ece8 [file] [log] [blame]
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +05301#include "config.h"
Gunnar Mills94df8c92018-09-14 14:50:03 -05002
3#include "occ_pass_through.hpp"
4
5#include "elog-errors.hpp"
6
7#include <errno.h>
8#include <fcntl.h>
9#include <unistd.h>
10
11#include <algorithm>
12#include <memory>
13#include <org/open_power/OCC/Device/error.hpp>
14#include <phosphor-logging/elog.hpp>
15#include <phosphor-logging/log.hpp>
16#include <string>
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050017namespace open_power
18{
19namespace occ
20{
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050021
Gunnar Mills94df8c92018-09-14 14:50:03 -050022PassThrough::PassThrough(sdbusplus::bus::bus& bus, const char* path) :
23 Iface(bus, path), path(path),
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053024 devicePath(OCC_DEV_PATH + std::to_string((this->path.back() - '0') + 1)),
25 activeStatusSignal(
Gunnar Mills94df8c92018-09-14 14:50:03 -050026 bus, sdbusRule::propertiesChanged(path, "org.open_power.OCC.Status"),
27 std::bind(std::mem_fn(&PassThrough::activeStatusEvent), this,
28 std::placeholders::_1))
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050029{
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053030 // Nothing to do.
31}
32
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053033void PassThrough::openDevice()
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053034{
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053035 using namespace phosphor::logging;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053036 using namespace sdbusplus::org::open_power::OCC::Device::Error;
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053037
Eddie James4f4712d2018-06-21 15:57:02 -050038 if (!occActive)
39 {
Gunnar Mills94df8c92018-09-14 14:50:03 -050040 log<level::INFO>("OCC is inactive; cannot perform pass-through");
41 return;
Eddie James4f4712d2018-06-21 15:57:02 -050042 }
43
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053044 fd = open(devicePath.c_str(), O_RDWR | O_NONBLOCK);
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053045 if (fd < 0)
46 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053047 // This would log and terminate since its not handled.
48 elog<OpenFailure>(
Gunnar Mills94df8c92018-09-14 14:50:03 -050049 phosphor::logging::org::open_power::OCC::Device::OpenFailure::
50 CALLOUT_ERRNO(errno),
51 phosphor::logging::org::open_power::OCC::Device::OpenFailure::
52 CALLOUT_DEVICE_PATH(devicePath.c_str()));
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053053 }
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053054 return;
55}
56
57void PassThrough::closeDevice()
58{
59 if (fd >= 0)
60 {
61 close(fd);
Eddie James4f4712d2018-06-21 15:57:02 -050062 fd = -1;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053063 }
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050064}
65
66std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
67{
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053068 using namespace phosphor::logging;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053069 using namespace sdbusplus::org::open_power::OCC::Device::Error;
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053070
Gunnar Mills94df8c92018-09-14 14:50:03 -050071 std::vector<int32_t> response{};
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053072
Eddie James4f4712d2018-06-21 15:57:02 -050073 openDevice();
74
75 if (fd < 0)
76 {
77 // OCC is inactive; empty response
78 return response;
79 }
80
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053081 // OCC only understands [bytes] so need array of bytes. Doing this
82 // because rest-server currently treats all int* as 32 bit integer.
83 std::vector<uint8_t> cmdInBytes;
84 cmdInBytes.resize(command.size());
85
86 // Populate uint8_t version of vector.
87 std::transform(command.begin(), command.end(), cmdInBytes.begin(),
Gunnar Mills94df8c92018-09-14 14:50:03 -050088 [](decltype(cmdInBytes)::value_type x) { return x; });
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053089
90 ssize_t size = cmdInBytes.size() * sizeof(decltype(cmdInBytes)::value_type);
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053091 auto rc = write(fd, cmdInBytes.data(), size);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053092 if (rc < 0 || (rc != size))
93 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053094 // This would log and terminate since its not handled.
95 elog<WriteFailure>(
Gunnar Mills94df8c92018-09-14 14:50:03 -050096 phosphor::logging::org::open_power::OCC::Device::WriteFailure::
97 CALLOUT_ERRNO(errno),
98 phosphor::logging::org::open_power::OCC::Device::WriteFailure::
99 CALLOUT_DEVICE_PATH(devicePath.c_str()));
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530100 }
101
102 // Now read the response. This would be the content of occ-sram
Gunnar Mills94df8c92018-09-14 14:50:03 -0500103 while (1)
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530104 {
Gunnar Mills94df8c92018-09-14 14:50:03 -0500105 uint8_t data{};
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530106 auto len = read(fd, &data, sizeof(data));
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530107 if (len > 0)
108 {
109 response.emplace_back(data);
110 }
111 else if (len < 0 && errno == EAGAIN)
112 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +0530113 // We may have data coming still.
114 // This driver does not need a sleep for a retry.
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530115 continue;
116 }
117 else if (len == 0)
118 {
119 // We have read all that we can.
120 break;
121 }
122 else
123 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +0530124 // This would log and terminate since its not handled.
125 elog<ReadFailure>(
Gunnar Mills94df8c92018-09-14 14:50:03 -0500126 phosphor::logging::org::open_power::OCC::Device::ReadFailure::
127 CALLOUT_ERRNO(errno),
128 phosphor::logging::org::open_power::OCC::Device::ReadFailure::
129 CALLOUT_DEVICE_PATH(devicePath.c_str()));
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530130 }
131 }
132
Eddie James4f4712d2018-06-21 15:57:02 -0500133 closeDevice();
134
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530135 return response;
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500136}
137
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530138// Called at OCC Status change signal
139void PassThrough::activeStatusEvent(sdbusplus::message::message& msg)
140{
141 std::string statusInterface;
142 std::map<std::string, sdbusplus::message::variant<bool>> msgData;
143 msg.read(statusInterface, msgData);
144
145 auto propertyMap = msgData.find("OccActive");
146 if (propertyMap != msgData.end())
147 {
148 // Extract the OccActive property
149 if (sdbusplus::message::variant_ns::get<bool>(propertyMap->second))
150 {
Eddie James4f4712d2018-06-21 15:57:02 -0500151 occActive = true;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530152 }
153 else
154 {
Eddie James4f4712d2018-06-21 15:57:02 -0500155 occActive = false;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530156 this->closeDevice();
157 }
158 }
159 return;
160}
161
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500162} // namespace occ
163} // namespace open_power