16b492fbfSDeepak Kodihalli #include <memory>
202ba9eccSDeepak Kodihalli #include <algorithm>
338b08d79SVishwanatha Subbanna #include <fcntl.h>
4*67d50ad6SVishwanatha Subbanna #include <errno.h>
502ba9eccSDeepak Kodihalli #include <phosphor-logging/log.hpp>
66b492fbfSDeepak Kodihalli #include "occ_pass_through.hpp"
76b492fbfSDeepak Kodihalli #include "occ_finder.hpp"
86b492fbfSDeepak Kodihalli namespace open_power
96b492fbfSDeepak Kodihalli {
106b492fbfSDeepak Kodihalli namespace occ
116b492fbfSDeepak Kodihalli {
126b492fbfSDeepak Kodihalli namespace pass_through
136b492fbfSDeepak Kodihalli {
146b492fbfSDeepak Kodihalli 
156b492fbfSDeepak Kodihalli void run()
166b492fbfSDeepak Kodihalli {
176b492fbfSDeepak Kodihalli     auto bus = sdbusplus::bus::new_default();
186b492fbfSDeepak Kodihalli     sdbusplus::server::manager::manager objManager(bus,
196b492fbfSDeepak Kodihalli                                                    OCC_PASS_THROUGH_ROOT);
206b492fbfSDeepak Kodihalli 
216b492fbfSDeepak Kodihalli     std::vector<std::unique_ptr<PassThrough>> objects;
226b492fbfSDeepak Kodihalli     auto occs = open_power::occ::finder::get();
236b492fbfSDeepak Kodihalli 
246b492fbfSDeepak Kodihalli     for (const auto& occ : occs)
256b492fbfSDeepak Kodihalli     {
266b492fbfSDeepak Kodihalli         auto occPassThrough = object(occ);
276b492fbfSDeepak Kodihalli         objects.emplace_back(
286b492fbfSDeepak Kodihalli             std::make_unique<PassThrough>(bus, occPassThrough.c_str()));
296b492fbfSDeepak Kodihalli     }
306b492fbfSDeepak Kodihalli     bus.request_name(OCC_PASS_THROUGH_BUSNAME);
316b492fbfSDeepak Kodihalli 
326b492fbfSDeepak Kodihalli     while (true)
336b492fbfSDeepak Kodihalli     {
346b492fbfSDeepak Kodihalli         bus.process_discard();
356b492fbfSDeepak Kodihalli         bus.wait();
366b492fbfSDeepak Kodihalli     }
376b492fbfSDeepak Kodihalli }
386b492fbfSDeepak Kodihalli 
396b492fbfSDeepak Kodihalli PassThrough::PassThrough(
406b492fbfSDeepak Kodihalli     sdbusplus::bus::bus& bus,
416b492fbfSDeepak Kodihalli     const char* path) :
426b492fbfSDeepak Kodihalli     Iface(bus, path),
4338b08d79SVishwanatha Subbanna     path(path),
4438b08d79SVishwanatha Subbanna     fd(openDevice())
456b492fbfSDeepak Kodihalli {
4638b08d79SVishwanatha Subbanna     // Nothing to do.
4738b08d79SVishwanatha Subbanna }
4838b08d79SVishwanatha Subbanna 
4938b08d79SVishwanatha Subbanna int PassThrough::openDevice()
5038b08d79SVishwanatha Subbanna {
5138b08d79SVishwanatha Subbanna     // Device instance number starts from 1.
52afd21a65SVishwanatha Subbanna     devicePath.append(std::to_string((this->path.back() - '0') + 1));
5338b08d79SVishwanatha Subbanna 
5438b08d79SVishwanatha Subbanna     int fd = open(devicePath.c_str(), O_RDWR | O_NONBLOCK);
5538b08d79SVishwanatha Subbanna     if (fd < 0)
5638b08d79SVishwanatha Subbanna     {
5738b08d79SVishwanatha Subbanna         // This is for completion. This is getting replaced by elog
5838b08d79SVishwanatha Subbanna         // in the next commit
5938b08d79SVishwanatha Subbanna         throw std::runtime_error("Error opening " + devicePath);
6038b08d79SVishwanatha Subbanna     }
6138b08d79SVishwanatha Subbanna     return fd;
626b492fbfSDeepak Kodihalli }
636b492fbfSDeepak Kodihalli 
646b492fbfSDeepak Kodihalli std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
656b492fbfSDeepak Kodihalli {
66*67d50ad6SVishwanatha Subbanna     using namespace phosphor::logging;
67*67d50ad6SVishwanatha Subbanna 
68*67d50ad6SVishwanatha Subbanna     std::vector<int32_t> response {};
69*67d50ad6SVishwanatha Subbanna 
70*67d50ad6SVishwanatha Subbanna     // Amester packs data in 4 bytes
71*67d50ad6SVishwanatha Subbanna     ssize_t size = command.size() * sizeof(int32_t);
72*67d50ad6SVishwanatha Subbanna     auto rc = write((fd)(), command.data(), size);
73*67d50ad6SVishwanatha Subbanna     if (rc < 0 || (rc != size))
74*67d50ad6SVishwanatha Subbanna     {
75*67d50ad6SVishwanatha Subbanna         log<level::ERR>("Error writing to OCC");
76*67d50ad6SVishwanatha Subbanna 
77*67d50ad6SVishwanatha Subbanna         // In the next commit, it will have exceptions.
78*67d50ad6SVishwanatha Subbanna         return response;
796b492fbfSDeepak Kodihalli     }
806b492fbfSDeepak Kodihalli 
81*67d50ad6SVishwanatha Subbanna     // Now read the response. This would be the content of occ-sram
82*67d50ad6SVishwanatha Subbanna     while(1)
83*67d50ad6SVishwanatha Subbanna     {
84*67d50ad6SVishwanatha Subbanna         errno = 0;
85*67d50ad6SVishwanatha Subbanna         int32_t data {};
86*67d50ad6SVishwanatha Subbanna         auto len = read((fd)(), &data, sizeof(data));
87*67d50ad6SVishwanatha Subbanna         if (len > 0)
88*67d50ad6SVishwanatha Subbanna         {
89*67d50ad6SVishwanatha Subbanna             response.emplace_back(data);
90*67d50ad6SVishwanatha Subbanna         }
91*67d50ad6SVishwanatha Subbanna         else if (len < 0 && errno == EAGAIN)
92*67d50ad6SVishwanatha Subbanna         {
93*67d50ad6SVishwanatha Subbanna             // We may have data coming still
94*67d50ad6SVishwanatha Subbanna             continue;
95*67d50ad6SVishwanatha Subbanna         }
96*67d50ad6SVishwanatha Subbanna         else if (len == 0)
97*67d50ad6SVishwanatha Subbanna         {
98*67d50ad6SVishwanatha Subbanna             // We have read all that we can.
99*67d50ad6SVishwanatha Subbanna             break;
100*67d50ad6SVishwanatha Subbanna         }
101*67d50ad6SVishwanatha Subbanna         else
102*67d50ad6SVishwanatha Subbanna         {
103*67d50ad6SVishwanatha Subbanna             // Will have exception in the next commit.
104*67d50ad6SVishwanatha Subbanna             log<level::ERR>("Error reading from OCC");
105*67d50ad6SVishwanatha Subbanna             break;
106*67d50ad6SVishwanatha Subbanna         }
107*67d50ad6SVishwanatha Subbanna     }
108*67d50ad6SVishwanatha Subbanna 
109*67d50ad6SVishwanatha Subbanna     return response;
110*67d50ad6SVishwanatha Subbanna }
111*67d50ad6SVishwanatha Subbanna 
112*67d50ad6SVishwanatha Subbanna 
1136b492fbfSDeepak Kodihalli } // namespace pass_through
1146b492fbfSDeepak Kodihalli } // namespace occ
1156b492fbfSDeepak Kodihalli } // namespace open_power
116