diff options
author | Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com> | 2017-01-25 18:41:51 +0530 |
---|---|---|
committer | Patrick Williams <patrick@stwcx.xyz> | 2017-03-24 21:30:44 +0000 |
commit | 83b5c1c0520cb1c405d34fb75cbd8950addb4494 (patch) | |
tree | 744f135b22d0d87d1bfde9efd7a502d21861ac7c | |
parent | bcb76886797f6c85c4052a72c07156f398c3e142 (diff) | |
download | phosphor-host-ipmid-83b5c1c0520cb1c405d34fb75cbd8950addb4494.tar.gz phosphor-host-ipmid-83b5c1c0520cb1c405d34fb75cbd8950addb4494.zip |
Make IPMI changes to stop timer that is started by SoftPowerOff
As part of Soft Power Off, there may be a timer that would be
running. This patch will stop the timer when IPMI daemon receives
response from host for SoftPowerOff sequence of commands.
Change-Id: Idacbff36444629623f8754de3d81d292ca19bb85
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
-rw-r--r-- | chassishandler.cpp | 50 | ||||
-rw-r--r-- | systemintfcmds.cpp | 38 |
2 files changed, 88 insertions, 0 deletions
diff --git a/chassishandler.cpp b/chassishandler.cpp index b2a1e7c..39b2994 100644 --- a/chassishandler.cpp +++ b/chassishandler.cpp @@ -798,6 +798,46 @@ finish: return rc; } +//------------------------------------------------------------- +// Send a command to SoftPowerOff application to stop any timer +//------------------------------------------------------------- +int stop_soft_off_timer() +{ + constexpr auto objname = "/xyz/openbmc_project/ipmi/internal/" + "softpoweroff"; + constexpr auto iface = "org.freedesktop.DBus.Properties"; + constexpr auto soft_off_iface = "xyz.openbmc_project.Ipmi.Internal." + "SoftPowerOff"; + + constexpr auto property = "ResponseReceived"; + constexpr auto value = "xyz.openbmc_project.Ipmi.Internal." + "SoftPowerOff.HostResponse.HostShutdown"; + char *busname = nullptr; + + // Get the system bus where most system services are provided. + auto bus = ipmid_get_sd_bus_connection(); + + // Get the service name + auto r = mapper_get_service(bus, objname, &busname); + if (r < 0) { + fprintf(stderr, "Failed to get %s bus name: %s\n", + objname, strerror(-r)); + return r; + } + + // No error object or reply expected. + int rc = sd_bus_call_method(bus, busname, objname, iface, + "Set", nullptr, nullptr, "ssv", + soft_off_iface, property, "s", value); + if (rc < 0) + { + fprintf(stderr, "Failed to set property in SoftPowerOff object: %s\n", + strerror(-rc)); + } + free(busname); + return rc; +} + //---------------------------------------------------------------------- // Chassis Control commands //---------------------------------------------------------------------- @@ -821,8 +861,18 @@ ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd, rc = initiate_state_transition(State::Host::Transition::On); break; case CMD_POWER_OFF: + // Need to Nudge SoftPowerOff application that it needs to stop the + // watchdog timer if running. + rc = stop_soft_off_timer(); + if (!rc) + { + fprintf(stderr, "Error stopping watchdog timer"); + } + // Does not matter if we are able to stop the timer, + // just get going and do the hard power off rc = initiate_state_transition(State::Host::Transition::Off); break; + case CMD_HARD_RESET: case CMD_POWER_CYCLE: // SPEC has a section that says certain implementations can trigger diff --git a/systemintfcmds.cpp b/systemintfcmds.cpp index f9a2dda..07ecec8 100644 --- a/systemintfcmds.cpp +++ b/systemintfcmds.cpp @@ -2,6 +2,7 @@ #include "host-ipmid/ipmid-api.h" #include <stdio.h> +#include <mapper.h> void register_netfn_app_functions() __attribute__((constructor)); @@ -13,15 +14,52 @@ ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_data_len_t data_len, ipmi_context_t context) { ipmi_ret_t rc = IPMI_CC_OK; + printf("IPMI APP READ EVENT command received\n"); // TODO : For now, this is catering only to the Soft Power Off via OEM SEL // mechanism. If we need to make this generically used for some // other conditions, then we can take advantage of context pointer. + constexpr auto objname = "/xyz/openbmc_project/ipmi/internal/" + "softpoweroff"; + constexpr auto iface = "org.freedesktop.DBus.Properties"; + constexpr auto soft_off_iface = "xyz.openbmc_project.Ipmi.Internal." + "SoftPowerOff"; + + constexpr auto property = "ResponseReceived"; + constexpr auto value = "xyz.openbmc_project.Ipmi.Internal." + "SoftPowerOff.HostResponse.SoftOffReceived"; + char *busname = nullptr; + struct oem_sel_timestamped soft_off = {0}; *data_len = sizeof(struct oem_sel_timestamped); + // Get the system bus where most system services are provided. + auto bus = ipmid_get_sd_bus_connection(); + + // Nudge the SoftPowerOff application that it needs to stop the + // initial watchdog timer. If we have some errors talking to Soft Off + // object, get going and do our regular job + mapper_get_service(bus, objname, &busname); + if (busname) + { + // No error object or reply expected. + auto r = sd_bus_call_method(bus, busname, objname, iface, + "Set", nullptr, nullptr, "ssv", + soft_off_iface, property, "s", value); + if (r < 0) + { + fprintf(stderr, "Failed to set property in SoftPowerOff object: %s\n", + strerror(-r)); + } + free (busname); + } + else + { + printf("Soft Power Off object is not available. Ignoring watchdog refresh"); + } + // either id[0] -or- id[1] can be filled in. We will use id[0] soft_off.id[0] = SEL_OEM_ID_0; soft_off.id[1] = SEL_OEM_ID_0; |