blob: 4a7057b10ed87d4e4e27ccccc819e889d61db1ca [file] [log] [blame]
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -05001#include <memory>
Deepak Kodihalli02ba9ec2017-03-18 02:57:43 -05002#include <algorithm>
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +05303#include <fcntl.h>
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +05304#include <errno.h>
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +05305#include <string>
6#include <unistd.h>
Deepak Kodihalli02ba9ec2017-03-18 02:57:43 -05007#include <phosphor-logging/log.hpp>
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +05308#include <phosphor-logging/elog.hpp>
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +05309#include <org/open_power/OCC/Device/error.hpp>
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050010#include "occ_pass_through.hpp"
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053011#include "elog-errors.hpp"
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053012#include "config.h"
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050013namespace open_power
14{
15namespace occ
16{
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050017
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050018PassThrough::PassThrough(
19 sdbusplus::bus::bus& bus,
20 const char* path) :
21 Iface(bus, path),
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053022 path(path),
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053023 devicePath(OCC_DEV_PATH + std::to_string((this->path.back() - '0') + 1)),
24 activeStatusSignal(
25 bus,
26 sdbusRule::propertiesChanged(path, "org.open_power.OCC.Status"),
27 std::bind(std::mem_fn(&PassThrough::activeStatusEvent),
28 this, 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
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053038 fd = open(devicePath.c_str(), O_RDWR | O_NONBLOCK);
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053039 if (fd < 0)
40 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053041 // This would log and terminate since its not handled.
42 elog<OpenFailure>(
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053043 phosphor::logging::org::open_power::OCC::Device::
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053044 OpenFailure::CALLOUT_ERRNO(errno),
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053045 phosphor::logging::org::open_power::OCC::Device::
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053046 OpenFailure::CALLOUT_DEVICE_PATH(devicePath.c_str()));
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053047 }
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053048 return;
49}
50
51void PassThrough::closeDevice()
52{
53 if (fd >= 0)
54 {
55 close(fd);
56 }
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050057}
58
59std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
60{
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053061 using namespace phosphor::logging;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053062 using namespace sdbusplus::org::open_power::OCC::Device::Error;
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053063
64 std::vector<int32_t> response {};
65
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053066 // OCC only understands [bytes] so need array of bytes. Doing this
67 // because rest-server currently treats all int* as 32 bit integer.
68 std::vector<uint8_t> cmdInBytes;
69 cmdInBytes.resize(command.size());
70
71 // Populate uint8_t version of vector.
72 std::transform(command.begin(), command.end(), cmdInBytes.begin(),
73 [](decltype(cmdInBytes)::value_type x){return x;});
74
75 ssize_t size = cmdInBytes.size() * sizeof(decltype(cmdInBytes)::value_type);
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053076 auto rc = write(fd, cmdInBytes.data(), size);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053077 if (rc < 0 || (rc != size))
78 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053079 // This would log and terminate since its not handled.
80 elog<WriteFailure>(
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053081 phosphor::logging::org::open_power::OCC::Device::
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053082 WriteFailure::CALLOUT_ERRNO(errno),
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053083 phosphor::logging::org::open_power::OCC::Device::
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053084 WriteFailure::CALLOUT_DEVICE_PATH(devicePath.c_str()));
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053085 }
86
87 // Now read the response. This would be the content of occ-sram
88 while(1)
89 {
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053090 uint8_t data {};
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053091 auto len = read(fd, &data, sizeof(data));
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053092 if (len > 0)
93 {
94 response.emplace_back(data);
95 }
96 else if (len < 0 && errno == EAGAIN)
97 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053098 // We may have data coming still.
99 // This driver does not need a sleep for a retry.
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530100 continue;
101 }
102 else if (len == 0)
103 {
104 // We have read all that we can.
105 break;
106 }
107 else
108 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +0530109 // This would log and terminate since its not handled.
110 elog<ReadFailure>(
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530111 phosphor::logging::org::open_power::OCC::Device::
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +0530112 ReadFailure::CALLOUT_ERRNO(errno),
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530113 phosphor::logging::org::open_power::OCC::Device::
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +0530114 ReadFailure::CALLOUT_DEVICE_PATH(devicePath.c_str()));
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530115 }
116 }
117
118 return response;
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500119}
120
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530121// Called at OCC Status change signal
122void PassThrough::activeStatusEvent(sdbusplus::message::message& msg)
123{
124 std::string statusInterface;
125 std::map<std::string, sdbusplus::message::variant<bool>> msgData;
126 msg.read(statusInterface, msgData);
127
128 auto propertyMap = msgData.find("OccActive");
129 if (propertyMap != msgData.end())
130 {
131 // Extract the OccActive property
132 if (sdbusplus::message::variant_ns::get<bool>(propertyMap->second))
133 {
134 this->openDevice();
135 }
136 else
137 {
138 this->closeDevice();
139 }
140 }
141 return;
142}
143
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500144} // namespace occ
145} // namespace open_power