From 3e5422ed1a67bb37cd4dcb0159c803badf98c9fa Mon Sep 17 00:00:00 2001 From: Vishwanatha Subbanna Date: Thu, 10 Aug 2017 18:25:26 +0530 Subject: Delay opening OCC device until bind Fixes openbmc/openbmc#2118 Change-Id: If9e2610fe7443daa2196b0e5989f81bc544266b2 Signed-off-by: Vishwanatha Subbanna --- configure.ac | 4 ++++ occ_pass_through.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++--------- occ_pass_through.hpp | 40 +++++++++++++++++++++++++++++--------- 3 files changed, 80 insertions(+), 18 deletions(-) diff --git a/configure.ac b/configure.ac index 098a0eb..24191c8 100644 --- a/configure.ac +++ b/configure.ac @@ -101,6 +101,10 @@ AC_ARG_VAR(FSI_SCAN_FILE, [The File to write for initiating FSI rescan]) AS_IF([test "x$FSI_SCAN_FILE" == "x"], [FSI_SCAN_FILE="/sys/devices/platform/gpio-fsi/fsi0/slave@00:00/00:00:00:0a/fsi1/rescan"]) AC_DEFINE_UNQUOTED([FSI_SCAN_FILE], ["$FSI_SCAN_FILE"], [The File to write for initiating FSI rescan]) +AC_ARG_VAR(OCC_DEV_PATH, [The OCC device path in /dev]) +AS_IF([test "x$OCC_DEV_PATH" == "x"], [OCC_DEV_PATH="/dev/occ"]) +AC_DEFINE_UNQUOTED([OCC_DEV_PATH], ["$OCC_DEV_PATH"], [The OCC device path in /dev]) + AC_ARG_VAR(PS_DERATING_FACTOR, [The power supply derating factor]) AS_IF([test "x$PS_DERATING_FACTOR" == "x"], [PS_DERATING_FACTOR=90]) AC_DEFINE_UNQUOTED([PS_DERATING_FACTOR], [$PS_DERATING_FACTOR], [The power supply derating factor]) diff --git a/occ_pass_through.cpp b/occ_pass_through.cpp index 2846dda..4a7057b 100644 --- a/occ_pass_through.cpp +++ b/occ_pass_through.cpp @@ -2,11 +2,14 @@ #include #include #include +#include +#include #include #include #include #include "occ_pass_through.hpp" #include "elog-errors.hpp" +#include "config.h" namespace open_power { namespace occ @@ -17,20 +20,22 @@ PassThrough::PassThrough( const char* path) : Iface(bus, path), path(path), - fd(openDevice()) + devicePath(OCC_DEV_PATH + std::to_string((this->path.back() - '0') + 1)), + activeStatusSignal( + bus, + sdbusRule::propertiesChanged(path, "org.open_power.OCC.Status"), + std::bind(std::mem_fn(&PassThrough::activeStatusEvent), + this, std::placeholders::_1)) { // Nothing to do. } -int PassThrough::openDevice() +void PassThrough::openDevice() { using namespace phosphor::logging; using namespace sdbusplus::org::open_power::OCC::Device::Error; - // Device instance number starts from 1. - devicePath.append(std::to_string((this->path.back() - '0') + 1)); - - int fd = open(devicePath.c_str(), O_RDWR | O_NONBLOCK); + fd = open(devicePath.c_str(), O_RDWR | O_NONBLOCK); if (fd < 0) { // This would log and terminate since its not handled. @@ -40,7 +45,15 @@ int PassThrough::openDevice() phosphor::logging::org::open_power::OCC::Device:: OpenFailure::CALLOUT_DEVICE_PATH(devicePath.c_str())); } - return fd; + return; +} + +void PassThrough::closeDevice() +{ + if (fd >= 0) + { + close(fd); + } } std::vector PassThrough::send(std::vector command) @@ -60,7 +73,7 @@ std::vector PassThrough::send(std::vector command) [](decltype(cmdInBytes)::value_type x){return x;}); ssize_t size = cmdInBytes.size() * sizeof(decltype(cmdInBytes)::value_type); - auto rc = write((fd)(), cmdInBytes.data(), size); + auto rc = write(fd, cmdInBytes.data(), size); if (rc < 0 || (rc != size)) { // This would log and terminate since its not handled. @@ -75,7 +88,7 @@ std::vector PassThrough::send(std::vector command) while(1) { uint8_t data {}; - auto len = read((fd)(), &data, sizeof(data)); + auto len = read(fd, &data, sizeof(data)); if (len > 0) { response.emplace_back(data); @@ -105,5 +118,28 @@ std::vector PassThrough::send(std::vector command) return response; } +// Called at OCC Status change signal +void PassThrough::activeStatusEvent(sdbusplus::message::message& msg) +{ + std::string statusInterface; + std::map> msgData; + msg.read(statusInterface, msgData); + + auto propertyMap = msgData.find("OccActive"); + if (propertyMap != msgData.end()) + { + // Extract the OccActive property + if (sdbusplus::message::variant_ns::get(propertyMap->second)) + { + this->openDevice(); + } + else + { + this->closeDevice(); + } + } + return; +} + } // namespace occ } // namespace open_power diff --git a/occ_pass_through.hpp b/occ_pass_through.hpp index f2f78c7..205fc04 100644 --- a/occ_pass_through.hpp +++ b/occ_pass_through.hpp @@ -4,7 +4,6 @@ #include #include #include -#include "file.hpp" namespace open_power { @@ -14,6 +13,9 @@ namespace occ using Iface = sdbusplus::server::object::object< sdbusplus::org::open_power::OCC::server::PassThrough>; +// For waiting on signals +namespace sdbusRule = sdbusplus::bus::match::rules; + /** @class PassThrough * @brief Implements org.open_power.OCC.PassThrough */ @@ -21,7 +23,6 @@ class PassThrough : public Iface { public: PassThrough() = delete; - ~PassThrough() = default; PassThrough(const PassThrough&) = delete; PassThrough& operator=(const PassThrough&) = delete; PassThrough(PassThrough&&) = default; @@ -34,6 +35,11 @@ class PassThrough : public Iface PassThrough(sdbusplus::bus::bus& bus, const char* path); + ~PassThrough() + { + closeDevice(); + } + /** @brief Pass through command to OCC * @param[in] command - command to pass-through * @returns OCC response as an array @@ -48,17 +54,33 @@ class PassThrough : public Iface /** @brief OCC device path * For now, here is the hard-coded mapping until * the udev rule is in. - * occ0 --> /dev/occfifo1 - * occ1 --> /dev/occfifo2 + * occ0 --> /dev/occ1 + * occ1 --> /dev/occ2 * ... */ - std::string devicePath = "/dev/occ"; + std::string devicePath; - /** @brief File descriptor manager */ - FileDescriptor fd; + /** brief file descriptor associated with occ device */ + int fd = -1; + + /** @brief Subscribe to OCC Status signal + * + * Once the OCC status gets to active, only then we will get /dev/occ2 + * populated and hence need to wait on that before opening that + */ + sdbusplus::bus::match_t activeStatusSignal; - /** Opens devicePath and returns file descritor */ - int openDevice(); + /** Opens devicePath and populates file descritor */ + void openDevice(); + + /** Closed the fd associated with opened device */ + void closeDevice(); + + /** @brief Callback function on OCC Status change signals + * + * @param[in] msg - Data associated with subscribed signal + */ + void activeStatusEvent(sdbusplus::message::message& msg); }; } // namespace occ -- cgit v1.2.1