blob: 911dd855ba7404e0f661077c8f614486b1af7250 [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{
14namespace pass_through
15{
16
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050017PassThrough::PassThrough(
18 sdbusplus::bus::bus& bus,
19 const char* path) :
20 Iface(bus, path),
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053021 path(path),
22 fd(openDevice())
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050023{
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053024 // Nothing to do.
25}
26
27int PassThrough::openDevice()
28{
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053029 using namespace phosphor::logging;
30 using namespace sdbusplus::org::open_power::OCC::PassThrough::Error;
31
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053032 // Device instance number starts from 1.
Vishwanatha Subbannaafd21a62017-04-13 20:17:13 +053033 devicePath.append(std::to_string((this->path.back() - '0') + 1));
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053034
35 int fd = open(devicePath.c_str(), O_RDWR | O_NONBLOCK);
36 if (fd < 0)
37 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053038 // This would log and terminate since its not handled.
39 elog<OpenFailure>(
40 phosphor::logging::org::open_power::OCC::PassThrough::
41 OpenFailure::CALLOUT_ERRNO(errno),
42 phosphor::logging::org::open_power::OCC::PassThrough::
43 OpenFailure::CALLOUT_DEVICE_PATH(devicePath.c_str()));
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053044 }
45 return fd;
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050046}
47
48std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
49{
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053050 using namespace phosphor::logging;
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053051 using namespace sdbusplus::org::open_power::OCC::PassThrough::Error;
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053052
53 std::vector<int32_t> response {};
54
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053055 // OCC only understands [bytes] so need array of bytes. Doing this
56 // because rest-server currently treats all int* as 32 bit integer.
57 std::vector<uint8_t> cmdInBytes;
58 cmdInBytes.resize(command.size());
59
60 // Populate uint8_t version of vector.
61 std::transform(command.begin(), command.end(), cmdInBytes.begin(),
62 [](decltype(cmdInBytes)::value_type x){return x;});
63
64 ssize_t size = cmdInBytes.size() * sizeof(decltype(cmdInBytes)::value_type);
65 auto rc = write((fd)(), cmdInBytes.data(), size);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053066 if (rc < 0 || (rc != size))
67 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053068 // This would log and terminate since its not handled.
69 elog<WriteFailure>(
70 phosphor::logging::org::open_power::OCC::PassThrough::
71 WriteFailure::CALLOUT_ERRNO(errno),
72 phosphor::logging::org::open_power::OCC::PassThrough::
73 WriteFailure::CALLOUT_DEVICE_PATH(devicePath.c_str()));
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053074 }
75
76 // Now read the response. This would be the content of occ-sram
77 while(1)
78 {
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053079 uint8_t data {};
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053080 auto len = read((fd)(), &data, sizeof(data));
81 if (len > 0)
82 {
83 response.emplace_back(data);
84 }
85 else if (len < 0 && errno == EAGAIN)
86 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053087 // We may have data coming still.
88 // This driver does not need a sleep for a retry.
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053089 continue;
90 }
91 else if (len == 0)
92 {
93 // We have read all that we can.
94 break;
95 }
96 else
97 {
Vishwanatha Subbanna9bb065b2017-04-18 14:25:26 +053098 // This would log and terminate since its not handled.
99 elog<ReadFailure>(
100 phosphor::logging::org::open_power::OCC::PassThrough::
101 ReadFailure::CALLOUT_ERRNO(errno),
102 phosphor::logging::org::open_power::OCC::PassThrough::
103 ReadFailure::CALLOUT_DEVICE_PATH(devicePath.c_str()));
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530104 }
105 }
106
107 return response;
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500108}
109
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500110} // namespace pass_through
111} // namespace occ
112} // namespace open_power