diff options
author | Nan Li <william.bjlinan@hotmail.com> | 2016-08-28 03:57:40 +0800 |
---|---|---|
committer | Nan Li <william.bjlinan@hotmail.com> | 2016-10-31 10:06:56 +0800 |
commit | fdd8ec557e9cb7048af3b63f2b2c3b8bc70fc0cb (patch) | |
tree | a0d286382eb56ee78bc46845b1735aa6fdc020e9 /chassishandler.cpp | |
parent | 30be0f700ed7259c8b20c50e4fc84ef696d98483 (diff) | |
download | phosphor-host-ipmid-fdd8ec557e9cb7048af3b63f2b2c3b8bc70fc0cb.tar.gz phosphor-host-ipmid-fdd8ec557e9cb7048af3b63f2b2c3b8bc70fc0cb.zip |
Add support for IPMI GetChassisStatus command
* Factor response to explicitly commented fields
* Add GetChassisStatus command to whilelist
Note: some fields need furture work.
Resolves openbmc/openbmc#439
Change-Id: I7a8d6bfe384f2621c157db379680921db4756fcc
Signed-off-by: Nan Li <william.bjlinan@hotmail.com>
Diffstat (limited to 'chassishandler.cpp')
-rw-r--r-- | chassishandler.cpp | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/chassishandler.cpp b/chassishandler.cpp index a20d062..6d5a5fd 100644 --- a/chassishandler.cpp +++ b/chassishandler.cpp @@ -65,6 +65,14 @@ typedef struct uint8_t bridge_dev_addr; }__attribute__((packed)) ipmi_chassis_cap_t; +typedef struct +{ + uint8_t cur_power_state; + uint8_t last_power_event; + uint8_t misc_power_state; + uint8_t front_panel_button_cap_status; +}__attribute__((packed)) ipmi_get_chassis_status_t; + int dbus_get_property(const char *name, char **buf) { sd_bus_error error = SD_BUS_ERROR_NULL; @@ -603,6 +611,178 @@ finish: return rc; } +struct hostPowerPolicyTypeMap_t { + uint8_t policyNum; + char policyName[19]; +}; + +hostPowerPolicyTypeMap_t g_hostPowerPolicyTypeMap_t[] = { + + {0x00, "LEAVE_OFF"}, + {0x01, "RESTORE_LAST_STATE"}, + {0x02, "ALWAYS_POWER_ON"}, + {0x03, "UNKNOWN"} +}; + +uint8_t get_host_power_policy(char *p) { + + hostPowerPolicyTypeMap_t *s = g_hostPowerPolicyTypeMap_t; + + while (s->policyNum != 0x03) { + if (!strcmp(s->policyName,p)) + break; + s++; + } + + return s->policyNum; +} + +//---------------------------------------------------------------------- +// Get Chassis Status commands +//---------------------------------------------------------------------- +ipmi_ret_t ipmi_get_chassis_status(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) +{ + const char *objname = "/org/openbmc/control/power0"; + const char *intf = "org.openbmc.control.Power"; + + sd_bus *bus = NULL; + sd_bus_message *reply = NULL; + int r = 0; + int pgood = 0; + char *busname = NULL; + ipmi_ret_t rc = IPMI_CC_OK; + ipmi_get_chassis_status_t chassis_status{}; + + char *p = NULL; + uint8_t s = 0; + + // Get the system bus where most system services are provided. + bus = ipmid_get_sd_bus_connection(); + + *data_len = 4; + + r = mapper_get_service(bus, objname, &busname); + if (r < 0) { + fprintf(stderr, "Failed to get bus name, return value: %s.\n", strerror(-r)); + rc = IPMI_CC_UNSPECIFIED_ERROR; + goto finish; + } + + r = sd_bus_get_property(bus, busname, objname, intf, "pgood", NULL, &reply, "i"); + if (r < 0) { + fprintf(stderr, "Failed to call sd_bus_get_property:%d, %s\n", r, strerror(-r)); + fprintf(stderr, "Bus: %s, Path: %s, Interface: %s\n", + busname, objname, intf); + rc = IPMI_CC_UNSPECIFIED_ERROR; + goto finish; + } + + r = sd_bus_message_read(reply, "i", &pgood); + if (r < 0) { + fprintf(stderr, "Failed to read sensor: %s\n", strerror(-r)); + rc = IPMI_CC_UNSPECIFIED_ERROR; + goto finish; + } + + printf("pgood is 0x%02x\n", pgood); + + // Get Power Policy + r = dbus_get_property("power_policy",&p); + + if (r < 0) { + fprintf(stderr, "Dbus get property(power_policy) failed for get_sys_boot_options.\n"); + rc = IPMI_CC_UNSPECIFIED_ERROR; + } else { + s = get_host_power_policy(p); + } + + if (p) + { + free(p); + p = NULL; + } + + // Current Power State + // [7] reserved + // [6..5] power restore policy + // 00b = chassis stays powered off after AC/mains returns + // 01b = after AC returns, power is restored to the state that was + // in effect when AC/mains was lost. + // 10b = chassis always powers up after AC/mains returns + // 11b = unknow + // Set to 00b, by observing the hardware behavior. + // Do we need to define a dbus property to identify the restore policy? + + // [4] power control fault + // 1b = controller attempted to turn system power on or off, but + // system did not enter desired state. + // Set to 0b, since We don't support it.. + + // [3] power fault + // 1b = fault detected in main power subsystem. + // set to 0b. for we don't support it. + + // [2] 1b = interlock (chassis is presently shut down because a chassis + // panel interlock switch is active). (IPMI 1.5) + // set to 0b, for we don't support it. + + // [1] power overload + // 1b = system shutdown because of power overload condition. + // set to 0b, for we don't support it. + + // [0] power is on + // 1b = system power is on + // 0b = system power is off(soft-off S4/S5, or mechanical off) + + chassis_status.cur_power_state = ((s & 0x3)<<5) | (pgood & 0x1); + + // Last Power Event + // [7..5] – reserved + // [4] – 1b = last ‘Power is on’ state was entered via IPMI command + // [3] – 1b = last power down caused by power fault + // [2] – 1b = last power down caused by a power interlock being activated + // [1] – 1b = last power down caused by a Power overload + // [0] – 1b = AC failed + // set to 0x0, for we don't support these fields. + + chassis_status.last_power_event = 0; + + // Misc. Chassis State + // [7] – reserved + // [6] – 1b = Chassis Identify command and state info supported (Optional) + // 0b = Chassis Identify command support unspecified via this command. + // (The Get Command Support command , if implemented, would still + // indicate support for the Chassis Identify command) + // [5..4] – Chassis Identify State. Mandatory when bit[6] =1b, reserved (return + // as 00b) otherwise. Returns the present chassis identify state. + // Refer to the Chassis Identify command for more info. + // 00b = chassis identify state = Off + // 01b = chassis identify state = Temporary(timed) On + // 10b = chassis identify state = Indefinite On + // 11b = reserved + // [3] – 1b = Cooling/fan fault detected + // [2] – 1b = Drive Fault + // [1] – 1b = Front Panel Lockout active (power off and reset via chassis + // push-buttons disabled.) + // [0] – 1b = Chassis Intrusion active + // set to 0, for we don't support them. + chassis_status.misc_power_state = 0; + + // Front Panel Button Capabilities and disable/enable status(Optional) + // set to 0, for we don't support them. + chassis_status.front_panel_button_cap_status = 0; + + // Pack the actual response + memcpy(response, &chassis_status, *data_len); + +finish: + free(busname); + reply = sd_bus_message_unref(reply); + + return rc; +} //---------------------------------------------------------------------- // Chassis Control commands @@ -869,6 +1049,9 @@ void register_netfn_chassis_functions() printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS); ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS, NULL, ipmi_chassis_get_sys_boot_options); + printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS); + ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_STATUS, NULL, ipmi_get_chassis_status); + printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL); ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL, NULL, ipmi_chassis_control); |