blob: fbb98c2480bc827fff78f2720ca3615e9aaa0bca [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>
Deepak Kodihalli02ba9ec2017-03-18 02:57:43 -05005#include <phosphor-logging/log.hpp>
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +05306#include <phosphor-logging/elog.hpp>
7#include <org/open_power/OCC/PassThrough/error.hpp>
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -05008#include "occ_pass_through.hpp"
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +05309#include "elog-errors.hpp"
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050010namespace open_power
11{
12namespace occ
13{
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050014
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050015PassThrough::PassThrough(
16 sdbusplus::bus::bus& bus,
17 const char* path) :
18 Iface(bus, path),
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053019 path(path),
20 fd(openDevice())
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050021{
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053022 // Nothing to do.
23}
24
25int PassThrough::openDevice()
26{
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053027 using namespace phosphor::logging;
28 using namespace sdbusplus::org::open_power::OCC::PassThrough::Error;
29
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053030 // Device instance number starts from 1.
Vishwanatha Subbannaafd21a62017-04-13 20:17:13 +053031 devicePath.append(std::to_string((this->path.back() - '0') + 1));
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053032
33 int fd = open(devicePath.c_str(), O_RDWR | O_NONBLOCK);
34 if (fd < 0)
35 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053036 // This would log and terminate since its not handled.
37 elog<OpenFailure>(
38 phosphor::logging::org::open_power::OCC::PassThrough::
39 OpenFailure::CALLOUT_ERRNO(errno),
40 phosphor::logging::org::open_power::OCC::PassThrough::
41 OpenFailure::CALLOUT_DEVICE_PATH(devicePath.c_str()));
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053042 }
43 return fd;
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050044}
45
46std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
47{
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053048 using namespace phosphor::logging;
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053049 using namespace sdbusplus::org::open_power::OCC::PassThrough::Error;
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053050
51 std::vector<int32_t> response {};
52
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053053 // OCC only understands [bytes] so need array of bytes. Doing this
54 // because rest-server currently treats all int* as 32 bit integer.
55 std::vector<uint8_t> cmdInBytes;
56 cmdInBytes.resize(command.size());
57
58 // Populate uint8_t version of vector.
59 std::transform(command.begin(), command.end(), cmdInBytes.begin(),
60 [](decltype(cmdInBytes)::value_type x){return x;});
61
62 ssize_t size = cmdInBytes.size() * sizeof(decltype(cmdInBytes)::value_type);
63 auto rc = write((fd)(), cmdInBytes.data(), size);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053064 if (rc < 0 || (rc != size))
65 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053066 // This would log and terminate since its not handled.
67 elog<WriteFailure>(
68 phosphor::logging::org::open_power::OCC::PassThrough::
69 WriteFailure::CALLOUT_ERRNO(errno),
70 phosphor::logging::org::open_power::OCC::PassThrough::
71 WriteFailure::CALLOUT_DEVICE_PATH(devicePath.c_str()));
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053072 }
73
74 // Now read the response. This would be the content of occ-sram
75 while(1)
76 {
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053077 uint8_t data {};
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053078 auto len = read((fd)(), &data, sizeof(data));
79 if (len > 0)
80 {
81 response.emplace_back(data);
82 }
83 else if (len < 0 && errno == EAGAIN)
84 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053085 // We may have data coming still.
86 // This driver does not need a sleep for a retry.
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053087 continue;
88 }
89 else if (len == 0)
90 {
91 // We have read all that we can.
92 break;
93 }
94 else
95 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053096 // This would log and terminate since its not handled.
97 elog<ReadFailure>(
98 phosphor::logging::org::open_power::OCC::PassThrough::
99 ReadFailure::CALLOUT_ERRNO(errno),
100 phosphor::logging::org::open_power::OCC::PassThrough::
101 ReadFailure::CALLOUT_DEVICE_PATH(devicePath.c_str()));
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530102 }
103 }
104
105 return response;
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500106}
107
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500108} // namespace occ
109} // namespace open_power