summaryrefslogtreecommitdiffstats
path: root/chassishandler.cpp
diff options
context:
space:
mode:
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