summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVishwanatha Subbanna <vishwa@linux.vnet.ibm.com>2017-02-01 18:02:38 +0530
committerPatrick Williams <patrick@stwcx.xyz>2017-03-27 13:27:01 -0500
commitd27e71e23cbe02dad145419c46c064d212420836 (patch)
treecc8743ab9bc4f69b0d0a7908e7a74c2a06feb351
parent072482986dfa60a905392c2dc49031ad7296bf2a (diff)
downloadphosphor-host-ipmid-d27e71e23cbe02dad145419c46c064d212420836.tar.gz
phosphor-host-ipmid-d27e71e23cbe02dad145419c46c064d212420836.zip
Add routines to start and stop the sd_event timer
Change-Id: I738be7b70554125e544aa59fe1770e909d3dffb1 Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
-rw-r--r--configure.ac4
-rw-r--r--softoff/softoff.cpp12
-rw-r--r--softoff/timer.cpp50
-rw-r--r--softoff/timer.hpp13
4 files changed, 75 insertions, 4 deletions
diff --git a/configure.ac b/configure.ac
index 68e0dc9..7112ca7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -90,6 +90,10 @@ AS_IF([test "x$enable_softoff" != "xno"],
AS_IF([test "x$SOFTOFF_OBJPATH" == "x"],
[SOFTOFF_OBJPATH="/xyz/openbmc_project/ipmi/internal/softpoweroff"])
[AC_DEFINE_UNQUOTED([SOFTOFF_OBJPATH], ["$SOFTOFF_OBJPATH"], [The SoftPowerOff Dbus root])]
+
+ # Timeouts in SECONDS for SoftPowerOff protocol
+ [AC_ARG_VAR(IPMI_SMS_ATN_ACK_TIMEOUT_SECS, [Initial timeout for host to ack SMS_ATN from BMC])]
+ [AC_DEFINE_UNQUOTED([IPMI_SMS_ATN_ACK_TIMEOUT_SECS], [3], [Initial timeout for host to ack SMS_ATN from BMC])]
)
# Create configured output
diff --git a/softoff/softoff.cpp b/softoff/softoff.cpp
index 11298ab..49b6f26 100644
--- a/softoff/softoff.cpp
+++ b/softoff/softoff.cpp
@@ -13,7 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <chrono>
+#include <phosphor-logging/log.hpp>
#include "softoff.hpp"
+#include "config.h"
namespace phosphor
{
namespace ipmi
@@ -22,6 +25,7 @@ namespace ipmi
/** @brief Send the SMS_ATN to host if value is set */
void SoftPowerOff::sendSMSAttn()
{
+ using namespace std::chrono;
auto method = bus.new_method_call(HOST_IPMI_BUS,
HOST_IPMI_OBJ,
HOST_IPMI_INTF,
@@ -31,6 +35,14 @@ void SoftPowerOff::sendSMSAttn()
// BT returns '0' on success and bus_error on failure.
bus.call_noreply(method);
+ // Start the timer
+ auto time = duration_cast<microseconds>(
+ seconds(IPMI_SMS_ATN_ACK_TIMEOUT_SECS));
+ auto r = timer.startTimer(time);
+ if (r < 0)
+ {
+ throw std::runtime_error("Error starting timer");
+ }
return;
}
diff --git a/softoff/timer.cpp b/softoff/timer.cpp
index 9e722f1..c626536 100644
--- a/softoff/timer.cpp
+++ b/softoff/timer.cpp
@@ -1,3 +1,4 @@
+#include <chrono>
#include <phosphor-logging/log.hpp>
#include "timer.hpp"
namespace phosphor
@@ -19,7 +20,7 @@ void Timer::initialize()
// Add infinite expiration time
auto r = sd_event_add_time(timeEvent, &eventSource,
CLOCK_MONOTONIC, // Time base
- UINT64_MAX, // Expire time - way long enough time
+ UINT64_MAX, // Expire time - way long time
0, // Use default event accuracy
timeoutHandler, // Callback handler on timeout
this); // User data
@@ -32,13 +33,13 @@ void Timer::initialize()
}
// Disable the timer for now
- r = sd_event_source_set_enabled(eventSource, SD_EVENT_OFF);
+ r = setTimer(SD_EVENT_OFF);
if (r < 0)
{
log<level::ERR>("Failure to disable timer",
entry("ERROR=%s", strerror(-r)));
- throw std::runtime_error("Setting initial timer value failed");
+ throw std::runtime_error("Disabling the timer failed");
}
return;
}
@@ -54,5 +55,48 @@ int Timer::timeoutHandler(sd_event_source* eventSource,
return 0;
}
+// Gets the time from steady_clock
+std::chrono::microseconds Timer::getTime()
+{
+ using namespace std::chrono;
+ auto usec = steady_clock::now().time_since_epoch();
+ return duration_cast<microseconds>(usec);
+}
+
+// Enables or disables the timer
+int Timer::setTimer(int action)
+{
+ return sd_event_source_set_enabled(eventSource, action);
+}
+
+// Sets the time and arms the timer
+int Timer::startTimer(std::chrono::microseconds timeValue)
+{
+ // Disable the timer
+ setTimer(SD_EVENT_OFF);
+
+ // Get the current MONOTONIC time and add the delta
+ auto expireTime = getTime() + timeValue;
+
+ // Set the time
+ auto r = sd_event_source_set_time(eventSource, expireTime.count());
+ if (r < 0)
+ {
+ log<level::ERR>("Failure to set timer",
+ entry("ERROR=%s", strerror(-r)));
+ return r;
+ }
+
+ // A ONESHOT timer means that when the timer goes off,
+ // its moves to disabled state.
+ r = setTimer(SD_EVENT_ONESHOT);
+ if (r < 0)
+ {
+ log<level::ERR>("Failure to start timer",
+ entry("ERROR=%s", strerror(-r)));
+ }
+ return r;
+}
+
} // namespace ipmi
} // namespace phosphor
diff --git a/softoff/timer.hpp b/softoff/timer.hpp
index 7c3bac2..9d597f8 100644
--- a/softoff/timer.hpp
+++ b/softoff/timer.hpp
@@ -38,11 +38,19 @@ class Timer
}
}
- inline auto isExpired()
+ inline auto isExpired() const
{
return expired;
}
+ /** @brief Starts the timer with specified expiration value.
+ * input is an offset from the current steady_clock
+ */
+ int startTimer(std::chrono::microseconds usec);
+
+ /** @brief Enables / disables the timer */
+ int setTimer(int action);
+
private:
/** @brief the sd_event structure */
sd_event* timeEvent = nullptr;
@@ -76,6 +84,9 @@ class Timer
*/
static int timeoutHandler(sd_event_source* eventSource,
uint64_t usec, void* userData);
+
+ /** @brief Gets the current time from steady clock */
+ static std::chrono::microseconds getTime();
};
} // namespace ipmi
OpenPOWER on IntegriCloud