summaryrefslogtreecommitdiffstats
path: root/chassishandler.cpp
diff options
context:
space:
mode:
authorYong Li <yong.b.li@linux.intel.com>2018-09-12 12:35:13 +0800
committerVernon Mauery <vernon.mauery@linux.intel.com>2018-09-25 15:17:24 +0000
commitc6713cff6f28a6d78146a7406123e66ce1d5d320 (patch)
tree1edf33dc342edb279aaa1c085e2ad7032165efc1 /chassishandler.cpp
parent069db2fd856db744a254120ed3054d49f241ae80 (diff)
downloadphosphor-host-ipmid-c6713cff6f28a6d78146a7406123e66ce1d5d320.tar.gz
phosphor-host-ipmid-c6713cff6f28a6d78146a7406123e66ce1d5d320.zip
Implement chassis set power restore policy command
Implement the IPMI set power restore policy command 0x06. This command can be used to configure the power restore policy. This configuration parameter is kept in nonvolatile storage. The power restore policy determines how the system or chassis behaves when AC power returns after an AC power loss Tested: Run the below command to check the current Power Restore Policy: ipmitool -H <IP> -P 0penBmc -I lanplus chassis status Run the below command to change it: ipmitool -H <IP> -P 0penBmc -I lanplus chassis policy always-off Change-Id: I224912890f9a9e8b4dc98f840cd6f223c9f7dfe5 Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
Diffstat (limited to 'chassishandler.cpp')
-rw-r--r--chassishandler.cpp91
1 files changed, 91 insertions, 0 deletions
diff --git a/chassishandler.cpp b/chassishandler.cpp
index 6002e7a..bfc079d 100644
--- a/chassishandler.cpp
+++ b/chassishandler.cpp
@@ -775,6 +775,10 @@ std::map<DbusValue, IpmiValue> dbusToIpmi = {
{RestorePolicy::Policy::Restore, 0x01},
{RestorePolicy::Policy::AlwaysOn, 0x02}};
+static constexpr uint8_t noChange = 0x03;
+static constexpr uint8_t allSupport = 0x01 | 0x02 | 0x04;
+static constexpr uint8_t policyBitMask = 0x07;
+static constexpr uint8_t setPolicyReqLen = 1;
} // namespace power_policy
//----------------------------------------------------------------------
@@ -1616,6 +1620,88 @@ ipmi_ret_t ipmiGetPOHCounter(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
return rc;
}
+ipmi_ret_t ipmi_chassis_set_power_restore_policy(
+ ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
+ ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
+{
+ auto* reqptr = reinterpret_cast<uint8_t*>(request);
+ auto* resptr = reinterpret_cast<uint8_t*>(response);
+ uint8_t reqPolicy = 0;
+
+ power_policy::DbusValue value =
+ power_policy::RestorePolicy::Policy::AlwaysOff;
+
+ if (*data_len != power_policy::setPolicyReqLen)
+ {
+ phosphor::logging::log<level::ERR>("Unsupported request length",
+ entry("LEN=0x%x", *data_len));
+ *data_len = 0;
+ return IPMI_CC_REQ_DATA_LEN_INVALID;
+ }
+
+ reqPolicy = *reqptr & power_policy::policyBitMask;
+ if (reqPolicy > power_policy::noChange)
+ {
+ phosphor::logging::log<level::ERR>("Reserved request parameter",
+ entry("REQ=0x%x", reqPolicy));
+ *data_len = 0;
+ return IPMI_CC_PARM_NOT_SUPPORTED;
+ }
+
+ if (reqPolicy == power_policy::noChange)
+ {
+ // just return the supported policy
+ *resptr = power_policy::allSupport;
+ *data_len = power_policy::setPolicyReqLen;
+ return IPMI_CC_OK;
+ }
+
+ for (auto const& it : power_policy::dbusToIpmi)
+ {
+ if (it.second == reqPolicy)
+ {
+ value = it.first;
+ break;
+ }
+ }
+
+ try
+ {
+ const settings::Path& powerRestoreSetting =
+ chassis::internal::cache::objects.map
+ .at(chassis::internal::powerRestoreIntf)
+ .front();
+ sdbusplus::message::variant<std::string> property =
+ convertForMessage(value);
+
+ auto method = chassis::internal::dbus.new_method_call(
+ chassis::internal::cache::objects
+ .service(powerRestoreSetting,
+ chassis::internal::powerRestoreIntf)
+ .c_str(),
+ powerRestoreSetting.c_str(), ipmi::PROP_INTF, "Set");
+
+ method.append(chassis::internal::powerRestoreIntf, "PowerRestorePolicy",
+ property);
+ auto reply = chassis::internal::dbus.call(method);
+ if (reply.is_method_error())
+ {
+ phosphor::logging::log<level::ERR>("Unspecified Error");
+ *data_len = 0;
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+ }
+ catch (InternalFailure& e)
+ {
+ report<InternalFailure>();
+ *data_len = 0;
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+
+ *data_len = power_policy::setPolicyReqLen;
+ return IPMI_CC_OK;
+}
+
void register_netfn_chassis_functions()
{
createIdentifyTimer();
@@ -1652,4 +1738,9 @@ void register_netfn_chassis_functions()
// <Get POH Counter>
ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_POH_COUNTER, NULL,
ipmiGetPOHCounter, PRIVILEGE_USER);
+
+ // <Set Power Restore Policy>
+ ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_RESTORE_POLICY, NULL,
+ ipmi_chassis_set_power_restore_policy,
+ PRIVILEGE_OPERATOR);
}
OpenPOWER on IntegriCloud