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