blob: 1b3bffad87913ca2720ef98350fc89b7b0adceda [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>
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -05006#include "occ_pass_through.hpp"
7#include "occ_finder.hpp"
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -05008namespace open_power
9{
10namespace occ
11{
12namespace pass_through
13{
14
15void run()
16{
17 auto bus = sdbusplus::bus::new_default();
18 sdbusplus::server::manager::manager objManager(bus,
19 OCC_PASS_THROUGH_ROOT);
20
21 std::vector<std::unique_ptr<PassThrough>> objects;
22 auto occs = open_power::occ::finder::get();
23
24 for (const auto& occ : occs)
25 {
26 auto occPassThrough = object(occ);
27 objects.emplace_back(
28 std::make_unique<PassThrough>(bus, occPassThrough.c_str()));
29 }
30 bus.request_name(OCC_PASS_THROUGH_BUSNAME);
31
32 while (true)
33 {
34 bus.process_discard();
35 bus.wait();
36 }
37}
38
39PassThrough::PassThrough(
40 sdbusplus::bus::bus& bus,
41 const char* path) :
42 Iface(bus, path),
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053043 path(path),
44 fd(openDevice())
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050045{
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053046 // Nothing to do.
47}
48
49int PassThrough::openDevice()
50{
51 // Device instance number starts from 1.
Vishwanatha Subbannaafd21a62017-04-13 20:17:13 +053052 devicePath.append(std::to_string((this->path.back() - '0') + 1));
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053053
54 int fd = open(devicePath.c_str(), O_RDWR | O_NONBLOCK);
55 if (fd < 0)
56 {
57 // This is for completion. This is getting replaced by elog
58 // in the next commit
59 throw std::runtime_error("Error opening " + devicePath);
60 }
61 return fd;
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050062}
63
64std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
65{
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053066 using namespace phosphor::logging;
67
68 std::vector<int32_t> response {};
69
70 // Amester packs data in 4 bytes
71 ssize_t size = command.size() * sizeof(int32_t);
72 auto rc = write((fd)(), command.data(), size);
73 if (rc < 0 || (rc != size))
74 {
75 log<level::ERR>("Error writing to OCC");
76
77 // In the next commit, it will have exceptions.
78 return response;
79 }
80
81 // Now read the response. This would be the content of occ-sram
82 while(1)
83 {
84 errno = 0;
85 int32_t data {};
86 auto len = read((fd)(), &data, sizeof(data));
87 if (len > 0)
88 {
89 response.emplace_back(data);
90 }
91 else if (len < 0 && errno == EAGAIN)
92 {
93 // We may have data coming still
94 continue;
95 }
96 else if (len == 0)
97 {
98 // We have read all that we can.
99 break;
100 }
101 else
102 {
103 // Will have exception in the next commit.
104 log<level::ERR>("Error reading from OCC");
105 break;
106 }
107 }
108
109 return response;
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500110}
111
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530112
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500113} // namespace pass_through
114} // namespace occ
115} // namespace open_power