summaryrefslogtreecommitdiffstats
path: root/presence
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2017-09-01 11:03:02 -0500
committerMatt Spinler <spinler@us.ibm.com>2017-09-05 08:19:06 -0500
commit902d1c37916af10cf2a2d7e2928186e9efe48436 (patch)
treef72a5664ae4e93147ff161c5701898329da8cdfa /presence
parent5d89f18a92ceeead129729811208ee13a9daf721 (diff)
downloadphosphor-gpio-monitor-902d1c37916af10cf2a2d7e2928186e9efe48436.tar.gz
phosphor-gpio-monitor-902d1c37916af10cf2a2d7e2928186e9efe48436.zip
gpio-presence: Add function to bind/unbind drivers
The cards that this app is doing presence detection for may have devices with drivers that need to be bound and unbound when the card is added and removed, respectively. The drivers to do this to will be passed into the app on startup (in a future commit). Then when presence detect changes the proper binds/unbinds will be done. This commit adds the code in the Presence class to do so. Change-Id: I32827e45b88ddb7586aba6b819cc591b49aa9c51 Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Diffstat (limited to 'presence')
-rw-r--r--presence/Makefile.am1
-rw-r--r--presence/gpio_presence.cpp55
-rw-r--r--presence/gpio_presence.hpp31
-rw-r--r--presence/main.cpp7
4 files changed, 90 insertions, 4 deletions
diff --git a/presence/Makefile.am b/presence/Makefile.am
index 7cc80d4..6c2e564 100644
--- a/presence/Makefile.am
+++ b/presence/Makefile.am
@@ -16,6 +16,7 @@ phosphor_gpio_presence_CXXFLAGS = \
$(LIBEVDEV_CFLAGS)
phosphor_gpio_presence_LDADD = \
+ -lstdc++fs \
$(PHOSPHOR_LOGGING_LIBS) \
$(PHOSPHOR_DBUS_INTERFACES_LIBS) \
$(LIBEVDEV_LIBS)
diff --git a/presence/gpio_presence.cpp b/presence/gpio_presence.cpp
index b87e139..ecc4813 100644
--- a/presence/gpio_presence.cpp
+++ b/presence/gpio_presence.cpp
@@ -1,5 +1,6 @@
-#include <libevdev/libevdev.h>
#include <fcntl.h>
+#include <fstream>
+#include <libevdev/libevdev.h>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/log.hpp>
#include <phosphor-logging/elog-errors.hpp>
@@ -128,6 +129,7 @@ void Presence::analyzeEvent()
present = true;
}
updateInventory(present);
+ bindOrUnbindDrivers(present);
}
}
}
@@ -173,6 +175,57 @@ void Presence::updateInventory(bool present)
"Error in inventory manager call to update inventory");
elog<InternalFailure>();
}
+
+}
+
+void Presence::bindOrUnbindDrivers(bool present)
+{
+ auto action = (present) ? "bind" : "unbind";
+
+ for (auto& driver : drivers)
+ {
+ auto path = std::get<pathField>(driver) / action;
+ auto device = std::get<deviceField>(driver);
+
+ if (present)
+ {
+ log<level::INFO>(
+ "Binding a device driver",
+ entry("PATH=%s", path.c_str()),
+ entry("DEVICE=%s", device.c_str()));
+ }
+ else
+ {
+ log<level::INFO>(
+ "Unbinding a device driver",
+ entry("PATH=%s", path.c_str()),
+ entry("DEVICE=%s", device.c_str()));
+ }
+
+ std::ofstream file;
+
+ file.exceptions(
+ std::ofstream::failbit |
+ std::ofstream::badbit |
+ std::ofstream::eofbit);
+
+ try
+ {
+ file.open(path);
+ file << device;
+ file.close();
+ }
+ catch (std::exception& e)
+ {
+ auto err = errno;
+
+ log<level::ERR>("Failed binding or unbinding a device "
+ "after a card was removed or added",
+ entry("PATH=%s", path.c_str()),
+ entry("DEVICE=%s", device.c_str()),
+ entry("ERRNO=%d", err));
+ }
+ }
}
diff --git a/presence/gpio_presence.hpp b/presence/gpio_presence.hpp
index 986dbe6..b5feddd 100644
--- a/presence/gpio_presence.hpp
+++ b/presence/gpio_presence.hpp
@@ -1,4 +1,5 @@
#pragma once
+#include <experimental/filesystem>
#include <string>
#include <systemd/sd-event.h>
#include "evdev.hpp"
@@ -10,6 +11,12 @@ namespace gpio
namespace presence
{
+static constexpr auto deviceField = 0;
+static constexpr auto pathField = 1;
+using Device = std::string;
+using Path = std::experimental::filesystem::path;
+using Driver = std::tuple<Device, Path>;
+
/** @class Presence
* @brief Responsible for determining and monitoring presence,
* by monitoring GPIO state changes, of inventory items and
@@ -47,6 +54,7 @@ class Presence : public Evdev
* @param[in] key - GPIO key to monitor
* @param[in] name - Pretty name of the inventory item
* @param[in] event - sd_event handler
+ * @param[in] drivers - list of device drivers to bind and unbind
* @param[in] handler - IO callback handler. Defaults to one in this
* class
*/
@@ -56,11 +64,13 @@ class Presence : public Evdev
const unsigned int key,
const std::string& name,
EventPtr& event,
+ const std::vector<Driver>& drivers,
sd_event_io_handler_t handler = Presence::processEvents) :
Evdev(path, key, event, handler, true),
bus(bus),
inventory(inventory),
- name(name)
+ name(name),
+ drivers(drivers)
{
determinePresence();
}
@@ -101,7 +111,7 @@ class Presence : public Evdev
/**
* @brief Read the GPIO device to determine initial presence and set
* present property at D-Bus path.
- **/
+ */
void determinePresence();
/** @brief Object path under inventory to display this inventory item */
@@ -112,6 +122,23 @@ class Presence : public Evdev
/** @brief Analyzes the GPIO event and update present property*/
void analyzeEvent();
+
+ /** @brief Vector of path and device tuples to bind/unbind*/
+ const std::vector<Driver> drivers;
+
+ /**
+ * @brief Binds or unbinds drivers
+ *
+ * Called when a presence change is detected to either
+ * bind the drivers for the new card or unbind them for
+ * the just removed card. Operates on the drivers vector.
+ *
+ * Writes <device> to <path>/bind (or unbind)
+ *
+ * @param present - when true, will bind the drivers
+ * when false, will unbind them
+ */
+ void bindOrUnbindDrivers(bool present);
};
/**
diff --git a/presence/main.cpp b/presence/main.cpp
index 6116540..5808c34 100644
--- a/presence/main.cpp
+++ b/presence/main.cpp
@@ -39,6 +39,10 @@ int main(int argc, char* argv[])
options.usage(argv);
}
+ std::vector<Driver> driverList;
+
+ //TODO: next commit, fill in driverList
+
auto bus = sdbusplus::bus::new_default();
auto rc = 0;
sd_event* event = nullptr;
@@ -52,7 +56,8 @@ int main(int argc, char* argv[])
event = nullptr;
auto name = options["name"];
- Presence presence(bus, inventory, path, std::stoul(key), name, eventP);
+ Presence presence(
+ bus, inventory, path, std::stoul(key), name, eventP, driverList);
while (true)
{
OpenPOWER on IntegriCloud