From b8b88a5c0f9e9cb6023cb8d5453e5cfadaa1a375 Mon Sep 17 00:00:00 2001 From: Kuiying Wang Date: Fri, 4 Jan 2019 10:50:21 +0800 Subject: [PATCH] Implement set front panel button enables command Through modify buttons' property "Enabled" to disable/enable corresponding button. Currently support power and reset button. Test-By: ipmitool raw 0x0 0xa 0x2 //disable reset button ipmitool raw 0x0 0xa 0x1 //disable power button ipmitool raw 0x0 0xa 0x0 //enable all buttons Change-Id: Ice6f58edb898689f7a7fa08ad078d25fccaab27e Signed-off-by: Kuiying Wang --- chassishandler.cpp | 98 +++++++++++++++++++++++++++++++++++++++ chassishandler.hpp | 1 + host-ipmid-whitelist.conf | 1 + 3 files changed, 100 insertions(+) diff --git a/chassishandler.cpp b/chassishandler.cpp index 4b42b3c..1a5b805 100644 --- a/chassishandler.cpp +++ b/chassishandler.cpp @@ -112,6 +112,8 @@ const static constexpr char chassisSMDevAddrProp[] = "SMDeviceAddress"; const static constexpr char chassisBridgeDevAddrProp[] = "BridgeDeviceAddress"; static constexpr uint8_t chassisCapFlagMask = 0x0f; static constexpr uint8_t chassisCapAddrMask = 0xfe; +static constexpr uint8_t disableResetButton = 0x2; +static constexpr uint8_t disablePowerButton = 0x1; typedef struct { @@ -140,6 +142,19 @@ struct GetPOHCountResponse uint8_t counterReading[4]; ///< Counter reading } __attribute__((packed)); +typedef struct +{ + uint8_t disables; // Front Panel Button Enables + //[7:4] - reserved + //[3] - 1b = disable Standby (sleep) button for entering standby (sleep) + //(control can still be used to wake the system) + //[2] - 1b = disable Diagnostic Interrupt button + //[1] - 1b = disable Reset button + //[0] - 1b = disable Power off button for power off only (in the case there + // is a single combined power/standby (sleep) button, then this also + // disables sleep requests via that button) +} __attribute__((packed)) IPMISetFrontPanelButtonEnablesReq; + // Phosphor Host State manager namespace State = sdbusplus::xyz::openbmc_project::State::server; @@ -948,6 +963,8 @@ ipmi_ret_t ipmi_get_chassis_status(ipmi_netfn_t netfn, ipmi_cmd_t cmd, // Front Panel Button Capabilities and disable/enable status(Optional) // set to 0, for we don't support them. + // TODO, it is tracked by an issue: + // https://github.com/openbmc/phosphor-host-ipmid/issues/122 chassis_status.front_panel_button_cap_status = 0; // Pack the actual response @@ -1721,6 +1738,82 @@ ipmi_ret_t ipmi_chassis_set_power_restore_policy( return IPMI_CC_OK; } +ipmi_ret_t ipmiSetFrontPanelButtonEnables(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) +{ + bool enable = false; + constexpr const char* powerButtonIntf = + "xyz.openbmc_project.Chassis.Buttons.Power"; + constexpr const char* powerButtonPath = + "/xyz/openbmc_project/Chassis/Buttons/Power0"; + constexpr const char* resetButtonIntf = + "xyz.openbmc_project.Chassis.Buttons.Reset"; + constexpr const char* resetButtonPath = + "/xyz/openbmc_project/Chassis/Buttons/Reset0"; + using namespace chassis::internal; + + IPMISetFrontPanelButtonEnablesReq* req = + static_cast(request); + if (*data_len != 1) + { + *data_len = 0; + log("IPMI request len is invalid"); + return IPMI_CC_REQ_DATA_LEN_INVALID; + } + *data_len = 0; + if (req->disables & disablePowerButton) + { + // Disable power button + enable = false; + } + else + { + // Enable power button + enable = true; + } + // set power button Enabled property + try + { + auto service = ipmi::getService(dbus, powerButtonIntf, powerButtonPath); + ipmi::setDbusProperty(dbus, service, powerButtonPath, powerButtonIntf, + "Enabled", enable); + } + catch (sdbusplus::exception::SdBusError& e) + { + log(e.what()); + log("Fail to set power button Enabled property"); + return IPMI_CC_UNSPECIFIED_ERROR; + } + + if (req->disables & disableResetButton) + { + // disable reset button + enable = false; + } + else + { + // enable reset button + enable = true; + } + // set reset button Enabled property + try + { + auto service = ipmi::getService(dbus, resetButtonIntf, resetButtonPath); + ipmi::setDbusProperty(dbus, service, resetButtonPath, resetButtonIntf, + "Enabled", enable); + } + catch (sdbusplus::exception::SdBusError& e) + { + log(e.what()); + log("Fail to set reset button Enabled property"); + return IPMI_CC_UNSPECIFIED_ERROR; + } + return IPMI_CC_OK; +} + void register_netfn_chassis_functions() { createIdentifyTimer(); @@ -1733,6 +1826,11 @@ void register_netfn_chassis_functions() ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_CHASSIS_CAP, NULL, ipmi_get_chassis_cap, PRIVILEGE_USER); + // Set Front Panel Button Enables + ipmi_register_callback(NETFUN_CHASSIS, + IPMI_CMD_SET_FRONT_PANEL_BUTTON_ENABLES, NULL, + ipmiSetFrontPanelButtonEnables, PRIVILEGE_ADMIN); + // Set Chassis Capabilities ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_CHASSIS_CAP, NULL, ipmi_set_chassis_cap, PRIVILEGE_USER); diff --git a/chassishandler.hpp b/chassishandler.hpp index 49b5ef8..f4a6bff 100644 --- a/chassishandler.hpp +++ b/chassishandler.hpp @@ -19,6 +19,7 @@ enum ipmi_netfn_chassis_cmds // Get capability bits IPMI_CMD_SET_SYS_BOOT_OPTIONS = 0x08, IPMI_CMD_GET_SYS_BOOT_OPTIONS = 0x09, + IPMI_CMD_SET_FRONT_PANEL_BUTTON_ENABLES = 0x0A, IPMI_CMD_GET_POH_COUNTER = 0x0F, }; diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf index e5cd0b5..d96d9ed 100644 --- a/host-ipmid-whitelist.conf +++ b/host-ipmid-whitelist.conf @@ -6,6 +6,7 @@ 0x00:0x06 //: 0x00:0x08 //: 0x00:0x09 //: +0x00:0x0A //: 0x00:0x0F //: 0x04:0x2D //: 0x04:0x2F //: -- 2.19.1