16b492fbfSDeepak Kodihalli #include <memory> 202ba9eccSDeepak Kodihalli #include <algorithm> 338b08d79SVishwanatha Subbanna #include <fcntl.h> 467d50ad6SVishwanatha Subbanna #include <errno.h> 502ba9eccSDeepak Kodihalli #include <phosphor-logging/log.hpp> 69bb065b8SVishwanatha Subbanna #include <phosphor-logging/elog.hpp> 7*ee4d83dfSVishwanatha Subbanna #include <org/open_power/OCC/Device/error.hpp> 86b492fbfSDeepak Kodihalli #include "occ_pass_through.hpp" 99bb065b8SVishwanatha Subbanna #include "elog-errors.hpp" 106b492fbfSDeepak Kodihalli namespace open_power 116b492fbfSDeepak Kodihalli { 126b492fbfSDeepak Kodihalli namespace occ 136b492fbfSDeepak Kodihalli { 146b492fbfSDeepak Kodihalli 156b492fbfSDeepak Kodihalli PassThrough::PassThrough( 166b492fbfSDeepak Kodihalli sdbusplus::bus::bus& bus, 176b492fbfSDeepak Kodihalli const char* path) : 186b492fbfSDeepak Kodihalli Iface(bus, path), 1938b08d79SVishwanatha Subbanna path(path), 2038b08d79SVishwanatha Subbanna fd(openDevice()) 216b492fbfSDeepak Kodihalli { 2238b08d79SVishwanatha Subbanna // Nothing to do. 2338b08d79SVishwanatha Subbanna } 2438b08d79SVishwanatha Subbanna 2538b08d79SVishwanatha Subbanna int PassThrough::openDevice() 2638b08d79SVishwanatha Subbanna { 279bb065b8SVishwanatha Subbanna using namespace phosphor::logging; 28*ee4d83dfSVishwanatha Subbanna using namespace sdbusplus::org::open_power::OCC::Device::Error; 299bb065b8SVishwanatha Subbanna 3038b08d79SVishwanatha Subbanna // Device instance number starts from 1. 31afd21a65SVishwanatha Subbanna devicePath.append(std::to_string((this->path.back() - '0') + 1)); 3238b08d79SVishwanatha Subbanna 3338b08d79SVishwanatha Subbanna int fd = open(devicePath.c_str(), O_RDWR | O_NONBLOCK); 3438b08d79SVishwanatha Subbanna if (fd < 0) 3538b08d79SVishwanatha Subbanna { 369bb065b8SVishwanatha Subbanna // This would log and terminate since its not handled. 379bb065b8SVishwanatha Subbanna elog<OpenFailure>( 38*ee4d83dfSVishwanatha Subbanna phosphor::logging::org::open_power::OCC::Device:: 399bb065b8SVishwanatha Subbanna OpenFailure::CALLOUT_ERRNO(errno), 40*ee4d83dfSVishwanatha Subbanna phosphor::logging::org::open_power::OCC::Device:: 419bb065b8SVishwanatha Subbanna OpenFailure::CALLOUT_DEVICE_PATH(devicePath.c_str())); 4238b08d79SVishwanatha Subbanna } 4338b08d79SVishwanatha Subbanna return fd; 446b492fbfSDeepak Kodihalli } 456b492fbfSDeepak Kodihalli 466b492fbfSDeepak Kodihalli std::vector<int32_t> PassThrough::send(std::vector<int32_t> command) 476b492fbfSDeepak Kodihalli { 4867d50ad6SVishwanatha Subbanna using namespace phosphor::logging; 49*ee4d83dfSVishwanatha Subbanna using namespace sdbusplus::org::open_power::OCC::Device::Error; 5067d50ad6SVishwanatha Subbanna 5167d50ad6SVishwanatha Subbanna std::vector<int32_t> response {}; 5267d50ad6SVishwanatha Subbanna 537d700e26SVishwanatha Subbanna // OCC only understands [bytes] so need array of bytes. Doing this 547d700e26SVishwanatha Subbanna // because rest-server currently treats all int* as 32 bit integer. 557d700e26SVishwanatha Subbanna std::vector<uint8_t> cmdInBytes; 567d700e26SVishwanatha Subbanna cmdInBytes.resize(command.size()); 577d700e26SVishwanatha Subbanna 587d700e26SVishwanatha Subbanna // Populate uint8_t version of vector. 597d700e26SVishwanatha Subbanna std::transform(command.begin(), command.end(), cmdInBytes.begin(), 607d700e26SVishwanatha Subbanna [](decltype(cmdInBytes)::value_type x){return x;}); 617d700e26SVishwanatha Subbanna 627d700e26SVishwanatha Subbanna ssize_t size = cmdInBytes.size() * sizeof(decltype(cmdInBytes)::value_type); 637d700e26SVishwanatha Subbanna auto rc = write((fd)(), cmdInBytes.data(), size); 6467d50ad6SVishwanatha Subbanna if (rc < 0 || (rc != size)) 6567d50ad6SVishwanatha Subbanna { 669bb065b8SVishwanatha Subbanna // This would log and terminate since its not handled. 679bb065b8SVishwanatha Subbanna elog<WriteFailure>( 68*ee4d83dfSVishwanatha Subbanna phosphor::logging::org::open_power::OCC::Device:: 699bb065b8SVishwanatha Subbanna WriteFailure::CALLOUT_ERRNO(errno), 70*ee4d83dfSVishwanatha Subbanna phosphor::logging::org::open_power::OCC::Device:: 719bb065b8SVishwanatha Subbanna WriteFailure::CALLOUT_DEVICE_PATH(devicePath.c_str())); 726b492fbfSDeepak Kodihalli } 736b492fbfSDeepak Kodihalli 7467d50ad6SVishwanatha Subbanna // Now read the response. This would be the content of occ-sram 7567d50ad6SVishwanatha Subbanna while(1) 7667d50ad6SVishwanatha Subbanna { 777d700e26SVishwanatha Subbanna uint8_t data {}; 7867d50ad6SVishwanatha Subbanna auto len = read((fd)(), &data, sizeof(data)); 7967d50ad6SVishwanatha Subbanna if (len > 0) 8067d50ad6SVishwanatha Subbanna { 8167d50ad6SVishwanatha Subbanna response.emplace_back(data); 8267d50ad6SVishwanatha Subbanna } 8367d50ad6SVishwanatha Subbanna else if (len < 0 && errno == EAGAIN) 8467d50ad6SVishwanatha Subbanna { 859bb065b8SVishwanatha Subbanna // We may have data coming still. 869bb065b8SVishwanatha Subbanna // This driver does not need a sleep for a retry. 8767d50ad6SVishwanatha Subbanna continue; 8867d50ad6SVishwanatha Subbanna } 8967d50ad6SVishwanatha Subbanna else if (len == 0) 9067d50ad6SVishwanatha Subbanna { 9167d50ad6SVishwanatha Subbanna // We have read all that we can. 9267d50ad6SVishwanatha Subbanna break; 9367d50ad6SVishwanatha Subbanna } 9467d50ad6SVishwanatha Subbanna else 9567d50ad6SVishwanatha Subbanna { 969bb065b8SVishwanatha Subbanna // This would log and terminate since its not handled. 979bb065b8SVishwanatha Subbanna elog<ReadFailure>( 98*ee4d83dfSVishwanatha Subbanna phosphor::logging::org::open_power::OCC::Device:: 999bb065b8SVishwanatha Subbanna ReadFailure::CALLOUT_ERRNO(errno), 100*ee4d83dfSVishwanatha Subbanna phosphor::logging::org::open_power::OCC::Device:: 1019bb065b8SVishwanatha Subbanna ReadFailure::CALLOUT_DEVICE_PATH(devicePath.c_str())); 10267d50ad6SVishwanatha Subbanna } 10367d50ad6SVishwanatha Subbanna } 10467d50ad6SVishwanatha Subbanna 10567d50ad6SVishwanatha Subbanna return response; 10667d50ad6SVishwanatha Subbanna } 10767d50ad6SVishwanatha Subbanna 1086b492fbfSDeepak Kodihalli } // namespace occ 1096b492fbfSDeepak Kodihalli } // namespace open_power 110