summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0055-Implement-set-front-panel-button-enables-command.patch
blob: fd7cf18519971db972fdbd98bb66e9df6b8eb98a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
From b8b88a5c0f9e9cb6023cb8d5453e5cfadaa1a375 Mon Sep 17 00:00:00 2001
From: Kuiying Wang <kuiying.wang@intel.com>
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 <kuiying.wang@intel.com>
---
 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;
 static constexpr const char* powerButtonIntf =
     "xyz.openbmc_project.Chassis.Buttons.Power";
 static constexpr const char* powerButtonPath =
@@ -140,6 +142,19 @@ struct GetPOHCountResponse
     uint8_t front_panel_button_cap_status;
 } __attribute__((packed)) ipmi_get_chassis_status_t;
 
+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;
 
@@ -1721,6 +1738,82 @@ ipmi_ret_t ipmi_chassis_set_power_restore_policy(
     return ipmi::responseSuccess(power_policy::allSupport);
 }
 
+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<IPMISetFrontPanelButtonEnablesReq*>(request);
+    if (*data_len != 1)
+    {
+        *data_len = 0;
+        log<level::ERR>("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<level::ERR>(e.what());
+        log<level::ERR>("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<level::ERR>(e.what());
+        log<level::ERR>("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
     IPMI_CMD_GET_SYS_RESTART_CAUSE = 0x07,
     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:0x07    //<Chassis>:<Get System Restart Cause>
 0x00:0x08    //<Chassis>:<Set System Boot Options>
 0x00:0x09    //<Chassis>:<Get System Boot Options>
+0x00:0x0A    //<Chassis>:<Set Front Panel Button Enables>
 0x00:0x0F    //<Chassis>:<Get POH Counter Command>
 0x04:0x02    //<Sensor/Event>:<Platform event>
 0x04:0x2D    //<Sensor/Event>:<Get Sensor Reading>
-- 
2.19.1