<div class="socmaildefaultfont" dir="ltr" style="font-family:Arial;font-size:10.5pt" ><div dir="ltr" >what makes SoftPowerOff different enough to have its own dbus object?  Shouldn't the soft power off simple be another method in the /or/openbmc/chassis/chassis0 interface?
<div> </div>
<div> 
<div><br>Chris Austen<br>POWER Systems Enablement Manager<br>(512) 286-5184 (T/L: 363-5184)
<div> </div>
<div> </div>
<blockquote data-history-content-modified="1" style="border-left:solid #aaaaaa 2px; margin-left:5px; padding-left:5px; direction:ltr; margin-right:0px" >----- Original message -----<br>From: OpenBMC Patches <openbmc-patches@stwcx.xyz><br>Sent by: "openbmc" <openbmc-bounces+austenc=us.ibm.com@lists.ozlabs.org><br>To: openbmc@lists.ozlabs.org<br>Cc:<br>Subject: [PATCH phosphor-host-ipmid v2] IPMI soft power off<br>Date: Sat, Nov 21, 2015 12:10 PM<br> 
<div><font size="2" face="Default Monospace,Courier New,Courier,monospace" >From: vishwa <vishwanath@in.ibm.com><br><br>---<br> Makefile         |   5 +--<br> apphandler.C     |  67 +++++++++++++++++++++++++++++--<br> apphandler.h     |  33 ++++++++++++++-<br> chassishandler.C |  85 ++++++++++++++++++++++++++++++++++++++-<br> chassishandler.h |  15 +++++++<br> host-services.c  | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++<br> host-services.h  |   3 ++<br> ipmid-api.h      |   4 +-<br> ipmid.C          |   6 ++-<br> ipmid.H          |   1 +<br> 10 files changed, 325 insertions(+), 13 deletions(-)<br> create mode 100644 host-services.c<br> create mode 100644 host-services.h<br><br>diff --git a/Makefile b/Makefile<br>index 1a37c0f..1851c9f 100644<br>--- a/Makefile<br>+++ b/Makefile<br>@@ -5,8 +5,7 @@ TESTER = testit<br> TESTADDSEL = testaddsel<br> <br> DAEMON = ipmid<br>-DAEMON_OBJ  = $(DAEMON).o<br>-<br>+DAEMON_OBJ  = ipmid.o host-services.o<br> <br> LIB_APP_OBJ = apphandler.o     \<br>               sensorhandler.o  \<br>@@ -28,7 +27,7 @@ LIB_APP     = libapphandler.so<br> INSTALLED_LIBS += $(LIB_APP)<br> INSTALLED_HEADERS = ipmid-api.h<br> <br>-INC_FLAG += $(shell pkg-config --cflags --libs libsystemd) -I. -O2<br>+INC_FLAG += $(shell pkg-config --cflags --libs libsystemd) -I. -O2<br> LIB_FLAG += $(shell pkg-config  --libs libsystemd) -rdynamic<br> IPMID_PATH ?= -DHOST_IPMI_LIB_PATH=\"/usr/lib/host-ipmid/\"<br> <br>diff --git a/apphandler.C b/apphandler.C<br>index 6467397..d3df330 100644<br>--- a/apphandler.C<br>+++ b/apphandler.C<br>@@ -10,19 +10,75 @@ extern sd_bus *bus;<br> <br> void register_netfn_app_functions() __attribute__((constructor));<br> <br>+//---------------------------------------------------------------------<br>+// Called by Host on seeing a SMS_ATN bit set. Return a hardcoded<br>+// value of 0x2 indicating we need Host read some data.<br>+//-------------------------------------------------------------------<br>+ipmi_ret_t ipmi_app_get_msg_flags(ipmi_netfn_t netfn, ipmi_cmd_t cmd,<br>+                             ipmi_request_t request, ipmi_response_t response,<br>+                             ipmi_data_len_t data_len, ipmi_context_t context)<br>+{<br>+ // Generic return from IPMI commands.<br>+    ipmi_ret_t rc = IPMI_CC_OK;<br>+<br>+    printf("IPMI APP GET MSG FLAGS returning with [bit:2] set\n");<br>+<br>+ // From IPMI spec V2.0 for Get Message Flags Command :<br>+ // bit:[1] from LSB : 1b = Event Message Buffer Full.<br>+ // Return as 0 if Event Message Buffer is not supported,<br>+ // or when the Event Message buffer is disabled.<br>+ // TODO. For now. assume its not disabled and send "0x2" anyway:<br>+<br>+ uint8_t set_event_msg_buffer_full = 0x2;<br>+    *data_len = sizeof(set_event_msg_buffer_full);<br>+<br>+    // Pack the actual response<br>+    memcpy(response, &set_event_msg_buffer_full, *data_len);<br>+<br>+    return rc;<br>+}<br> <br>+//-------------------------------------------------------------------<br>+// Called by Host post response from Get_Message_Flags<br>+//-------------------------------------------------------------------<br> ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t netfn, ipmi_cmd_t cmd,<br>                              ipmi_request_t request, ipmi_response_t response,<br>                              ipmi_data_len_t data_len, ipmi_context_t context)<br> {<br>     ipmi_ret_t rc = IPMI_CC_OK;<br>-    *data_len = 0;<br>+    printf("IPMI APP READ EVENT command received\n");<br> <br>-    printf("IPMI APP READ EVENT Ignoring for now\n");<br>-    return rc;<br>+ // TODO : For now, this is catering only to the Soft Power Off via OEM SEL<br>+ //        mechanism. If we need to make this generically used for some<br>+ //        other conditions, then we can take advantage of context pointer.<br> <br>-}<br>+ struct oem_sel_timestamped soft_off = {0};<br>+    *data_len = sizeof(struct oem_sel_timestamped);<br>+<br>+ // either id[0] -or- id[1] can be filled in. We will use id[0]<br>+ soft_off.id[0] = SEL_OEM_ID_0;<br>+ soft_off.id[1] = SEL_OEM_ID_0;<br>+ soft_off.type = SEL_RECORD_TYPE_OEM;<br>+<br>+ // Following 3 bytes are from IANA Manufactre_Id field. See below<br>+ soft_off.manuf_id[0]= 0x41;<br>+ soft_off.manuf_id[1]= 0xA7;<br>+ soft_off.manuf_id[2]= 0x00;<br>+<br>+ // per IPMI spec NetFuntion for OEM<br>+ soft_off.netfun = 0x3A;<br> <br>+ // Mechanism to kick start soft shutdown.<br>+ soft_off.cmd = CMD_POWER;<br>+ soft_off.data[0] = SOFT_OFF;<br>+<br>+ // All '0xFF' since unused.<br>+ memset(&soft_off.data[1], 0xFF, 3);<br>+<br>+    // Pack the actual response<br>+    memcpy(response, &soft_off, *data_len);<br>+    return rc;<br>+}<br> <br> ipmi_ret_t ipmi_app_set_acpi_power_state(ipmi_netfn_t netfn, ipmi_cmd_t cmd,<br>                              ipmi_request_t request, ipmi_response_t response,<br>@@ -359,6 +415,9 @@ void register_netfn_app_functions()<br>     ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_BMC_GLOBAL_ENABLES, NULL,<br>                                             ipmi_app_set_bmc_global_enables);<br> <br>+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_MSG_FLAGS);<br>+    ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_MSG_FLAGS, NULL, ipmi_app_get_msg_flags);<br>+<br>     return;<br> }<br> <br>diff --git a/apphandler.h b/apphandler.h<br>index 35a2b20..aa2a55d 100644<br>--- a/apphandler.h<br>+++ b/apphandler.h<br>@@ -1,6 +1,19 @@<br> #ifndef __HOST_IPMI_APP_HANDLER_H__<br> #define __HOST_IPMI_APP_HANDLER_H__<br> <br>+#include <stdint.h><br>+<br>+// These are per skiboot ipmi-sel code<br>+<br>+// OEM_SEL type with Timestamp<br>+#define SEL_OEM_ID_0 0x55<br>+// SEL type is OEM and -not- general SEL<br>+#define SEL_RECORD_TYPE_OEM 0xC0<br>+// Minor command for soft shurdown<br>+#define SOFT_OFF 0x00<br>+// Major command for Any kind of power ops<br>+#define CMD_POWER 0x04<br>+<br> // IPMI commands for App net functions.<br> enum ipmi_netfn_app_cmds<br> {<br>@@ -11,9 +24,27 @@ enum ipmi_netfn_app_cmds<br>     IPMI_CMD_RESET_WD               = 0x22,<br>     IPMI_CMD_SET_WD                 = 0x24,<br>     IPMI_CMD_SET_BMC_GLOBAL_ENABLES = 0x2E,<br>+    IPMI_CMD_GET_MSG_FLAGS          = 0x31,<br>     IPMI_CMD_READ_EVENT             = 0x35,<br>     IPMI_CMD_GET_CAP_BIT            = 0x36,<br>-<br> };<br> <br>+// A Mechanism to tell host to shtudown hosts by sending this PEM SEL. Really<br>+// the only used fields by skiboot are:<br>+// id[0] / id[1] for ID_0 , ID_1<br>+// type : SEL_RECORD_TYPE_OEM as standard SELs are ignored by skiboot<br>+// cmd : CMD_POWER for power functions<br>+// data[0], specific commands.  example Soft power off. power cycle, etc.<br>+struct oem_sel_timestamped<br>+{<br>+ /* SEL header */<br>+ uint8_t id[2];<br>+ uint8_t type;<br>+ uint8_t manuf_id[3];<br>+ uint8_t timestamp[4];<br>+ /* OEM SEL data (6 bytes) follows */<br>+ uint8_t netfun;<br>+ uint8_t cmd;<br>+ uint8_t data[4];<br>+};<br> #endif<br>diff --git a/chassishandler.C b/chassishandler.C<br>index d00a124..56b8375 100644<br>--- a/chassishandler.C<br>+++ b/chassishandler.C<br>@@ -4,6 +4,11 @@<br> #include <string.h><br> #include <stdint.h><br> <br>+// OpenBMC Chassis Manager dbus framework<br>+const char  *chassis_bus_name      =  "org.openbmc.control.Chassis";<br>+const char  *chassis_object_name   =  "/org/openbmc/control/chassis0";<br>+const char  *chassis_intf_name     =  "org.openbmc.control.Chassis";<br>+<br> void register_netfn_chassis_functions() __attribute__((constructor));<br> <br> struct get_sys_boot_options_t {<br>@@ -23,6 +28,82 @@ ipmi_ret_t ipmi_chassis_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,<br>     return rc;<br> }<br> <br>+//------------------------------------------------------------<br>+// Calls into Chassis Control Dbus object to do the power off<br>+//------------------------------------------------------------<br>+int ipmi_chassis_power_off()<br>+{<br>+ // sd_bus error<br>+ int rc = 0;<br>+<br>+    // SD Bus error report mechanism.<br>+    sd_bus_error bus_error = SD_BUS_ERROR_NULL;<br>+<br>+ // Response from the call. Although there is no response for this call,<br>+ // obligated to mention this to make compiler happy.<br>+ sd_bus_message *response = NULL;<br>+<br>+ // Gets a hook onto either a SYSTEM or SESSION bus<br>+ sd_bus *bus_type = ipmid_get_sd_bus_connection();<br>+<br>+ rc = sd_bus_call_method(bus_type,         // On the System Bus<br>+ chassis_bus_name,        // Service to contact<br>+ chassis_object_name,     // Object path<br>+ chassis_intf_name,       // Interface name<br>+ "powerOff",       // Method to be called<br>+ &bus_error,       // object to return error<br>+ &response, // Response buffer if any<br>+ NULL); // No input arguments<br>+ if(rc < 0)<br>+ {<br>+ fprintf(stderr,"ERROR initiating Power Off:[%s]\n",bus_error.message);<br>+ }<br>+ else<br>+ {<br>+ printf("Chassis Power Off initiated successfully\n");<br>+ }<br>+<br>+    sd_bus_error_free(&bus_error);<br>+    sd_bus_message_unref(response);<br>+<br>+ return rc;<br>+}<br>+<br>+//----------------------------------------------------------------------<br>+// Chassis Control commands<br>+//----------------------------------------------------------------------<br>+ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd,<br>+                        ipmi_request_t request, ipmi_response_t response,<br>+                        ipmi_data_len_t data_len, ipmi_context_t context)<br>+{<br>+ // Error from power off.<br>+ int rc = 0;<br>+<br>+ // No response for this command.<br>+    *data_len = 0;<br>+<br>+ // Catch the actual operaton by peeking into request buffer<br>+ uint8_t chassis_ctrl_cmd = *(uint8_t *)request;<br>+ printf("Chassis Control Command: Operation:[0x%X]\n",chassis_ctrl_cmd);<br>+<br>+ switch(chassis_ctrl_cmd)<br>+ {<br>+ case CMD_POWER_OFF:<br>+ case CMD_HARD_RESET:<br>+ {<br>+ rc = ipmi_chassis_power_off();<br>+ break;<br>+ }<br>+ default:<br>+ {<br>+ fprintf(stderr, "Invalid Chassis Control command:[0x%X] received\n",chassis_ctrl_cmd);<br>+ rc = -1;<br>+ }<br>+ }<br>+<br>+ return ( (rc < 0) ? IPMI_CC_INVALID : IPMI_CC_OK);<br>+}<br>+<br> ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,<br>                               ipmi_request_t request, ipmi_response_t response,<br>                               ipmi_data_len_t data_len, ipmi_context_t context)<br>@@ -58,5 +139,7 @@ void register_netfn_chassis_functions()<br> <br>     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS);<br>     ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS, NULL, ipmi_chassis_get_sys_boot_options);<br>-}<br> <br>+    printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL);<br>+    ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL, NULL, ipmi_chassis_control);<br>+}<br>diff --git a/chassishandler.h b/chassishandler.h<br>index 99ed366..1a26411 100644<br>--- a/chassishandler.h<br>+++ b/chassishandler.h<br>@@ -1,9 +1,13 @@<br> #ifndef __HOST_IPMI_CHASSIS_HANDLER_H__<br> #define __HOST_IPMI_CHASSIS_HANDLER_H__<br> <br>+#include <stdint.h><br>+<br> // IPMI commands for Chassis net functions.<br> enum ipmi_netfn_app_cmds<br> {<br>+ // Chassis Control<br>+ IPMI_CMD_CHASSIS_CONTROL  = 0x02,<br>     // Get capability bits<br>     IPMI_CMD_GET_SYS_BOOT_OPTIONS = 0x09,<br> };<br>@@ -14,4 +18,15 @@ enum ipmi_chassis_return_codes<br>     IPMI_CC_PARM_NOT_SUPPORTED = 0x80,<br> };<br> <br>+// Various Chassis operations under a single command.<br>+enum ipmi_chassis_control_cmds : uint8_t<br>+{<br>+ CMD_POWER_OFF   = 0x00,<br>+ CMD_POWER_ON   = 0x01,<br>+ CMD_POWER_CYCLE   = 0x02,<br>+ CMD_HARD_RESET   = 0x03,<br>+ CMD_PULSE_DIAGNOSTIC_INTR  = 0x04,<br>+ CMD_SOFT_OFF_VIA_OVER_TEMP = 0x05,<br>+};<br>+<br> #endif<br>diff --git a/host-services.c b/host-services.c<br>new file mode 100644<br>index 0000000..89f0b6c<br>--- /dev/null<br>+++ b/host-services.c<br>@@ -0,0 +1,119 @@<br>+#include <stdio.h><br>+#include <stdlib.h><br>+#include <errno.h><br>+#include <systemd/sd-bus.h><br>+<br>+// OpenBMC Host IPMI dbus framework<br>+const char  *bus_name      =  "org.openbmc.HostIpmi";<br>+const char  *object_name   =  "/org/openbmc/HostIpmi/1";<br>+const char  *intf_name     =  "org.openbmc.HostIpmi";<br>+<br>+//-------------------------------------------------------------------<br>+// Gets called by PowerOff handler when a Soft Power off is requested<br>+//-------------------------------------------------------------------<br>+static int soft_power_off(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)<br>+{<br>+ int64_t bt_resp = -1;<br>+ int rc = 0;<br>+<br>+ // Steps to be taken when we get this.<br>+ // 1: Send a SMS_ATN to the Host<br>+ // 2: Host receives it and sends a GetMsgFlags IPMI command<br>+ // 3: IPMID app handler will respond to that with a MSgFlag with bit:0x2<br>+ //   set indicating we have a message for Host<br>+ // 4: Host sends a GetMsgBuffer command and app handler will respond to<br>+ //   that with a OEM-SEL with certain fields packed indicating to the<br>+ //   host that it do a shutdown of the partitions.  <br>+ // 5: Host does the partition shutdown and calls Chassis Power off command<br>+ // 6: App handler handles the command by making a call to ChassisManager<br>+ //   Dbus<br>+<br>+ // Now the job is to send the SMS_ATTN.<br>+<br>+    // Req message contains the specifics about which method etc that we want to<br>+    // access on which bus, object<br>+    sd_bus_message *response = NULL;<br>+<br>+ // Error return mechanism<br>+    sd_bus_error bus_error = SD_BUS_ERROR_NULL;<br>+<br>+ // Gets a hook onto either a SYSTEM or SESSION bus<br>+ sd_bus *bus = (sd_bus *)ipmid_get_sd_bus_connection();<br>+<br>+ rc = sd_bus_call_method(bus,        // On the System Bus<br>+ bus_name,        // Service to contact<br>+ object_name,     // Object path<br>+ intf_name,       // Interface name<br>+ "setAttention",  // Method to be called<br>+ &bus_error,      // object to return error<br>+ &response, // Response buffer if any<br>+ NULL); // No input arguments<br>+ if(rc < 0)<br>+ {<br>+ fprintf(stderr,"ERROR initiating Power Off:[%s]\n",bus_error.message);<br>+ goto finish;<br>+ }<br>+<br>+ // See if we were able to successfully raise SMS_ATN<br>+    rc = sd_bus_message_read(response, "x", &bt_resp);<br>+    if (rc < 0)<br>+ {<br>+ fprintf(stderr, "Failed to get a rc from BT for SMS_ATN: %s\n", strerror(-rc));<br>+ goto finish;<br>+    }<br>+<br>+finish:<br>+    sd_bus_error_free(&bus_error);<br>+    sd_bus_message_unref(response);<br>+<br>+ if(rc < 0)<br>+ {<br>+ return sd_bus_reply_method_return(m, "x", rc);<br>+ }<br>+ else<br>+ {<br>+ return sd_bus_reply_method_return(m, "x", bt_resp);<br>+ }<br>+}<br>+<br>+//-------------------------------------------<br>+// Function pointer of APIs exposed via Dbus<br>+//-------------------------------------------<br>+static const sd_bus_vtable host_services_vtable[] =<br>+{<br>+ SD_BUS_VTABLE_START(0),<br>+ // Takes No("") arguments -but- returns a value of type 64 bit integer("x")<br>+ SD_BUS_METHOD("SoftPowerOff", "", "x", &soft_power_off, SD_BUS_VTABLE_UNPRIVILEGED),<br>+ SD_BUS_VTABLE_END,<br>+};<br>+<br>+//------------------------------------------------------<br>+// Called by IPMID as part of the start up<br>+// -----------------------------------------------------<br>+int start_host_service(sd_bus *bus, sd_bus_slot *slot)<br>+{<br>+ int rc = 0;<br>+<br>+ /* Install the object */<br>+ rc = sd_bus_add_object_vtable(bus,<br>+ &slot,<br>+ "/org/openbmc/HostServices",  /* object path */<br>+ "org.openbmc.HostServices",   /* interface name */<br>+ host_services_vtable,<br>+ NULL);<br>+ if (rc < 0)<br>+ {<br>+ fprintf(stderr, "Failed to issue method call: %s\n", strerror(-rc));<br>+ }<br>+ else<br>+ {<br>+ /* Take one in OpenBmc */<br>+ rc = sd_bus_request_name(bus, "org.openbmc.HostServices", 0);<br>+ if (rc < 0)<br>+ {<br>+ fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-rc));<br>+ }<br>+ }<br>+<br>+ return rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS;<br>+}<br>diff --git a/host-services.h b/host-services.h<br>new file mode 100644<br>index 0000000..0d93480<br>--- /dev/null<br>+++ b/host-services.h<br>@@ -0,0 +1,3 @@<br>+#include <systemd/sd-bus.h><br>+<br>+extern "C" int start_host_service(sd_bus *, sd_bus_slot *);<br>diff --git a/ipmid-api.h b/ipmid-api.h<br>index 34d3bbe..952dd3f 100644<br>--- a/ipmid-api.h<br>+++ b/ipmid-api.h<br>@@ -53,7 +53,7 @@ typedef ipmi_ret_t (*ipmid_callback_t)(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,<br> // information of netfn, cmd, callback handler pointer and context data.<br> // Making this a extern "C" so that plugin libraries written in C can also use<br> // it.<br>-extern "C" void ipmi_register_callback(ipmi_netfn_t, ipmi_cmd_t,<br>+extern "C" void ipmi_register_callback(ipmi_netfn_t, ipmi_cmd_t,<br>                                        ipmi_context_t, ipmid_callback_t);<br> <br> // These are the command network functions, the response<br>@@ -94,5 +94,5 @@ enum ipmi_return_codes<br>     IPMI_CC_UNSPECIFIED_ERROR = 0xFF,<br> };<br> <br>-sd_bus *ipmid_get_sd_bus_connection(void);<br>+extern "C" sd_bus* ipmid_get_sd_bus_connection(void);<br> #endif<br>diff --git a/ipmid.C b/ipmid.C<br>index 6b1eacc..440705c 100644<br>--- a/ipmid.C<br>+++ b/ipmid.C<br>@@ -40,7 +40,6 @@ typedef std::pair<ipmid_callback_t, ipmi_context_t> ipmi_fn_context_t;<br> std::map<ipmi_fn_cmd_t, ipmi_fn_context_t> g_ipmid_router_map;<br> <br> <br>-<br> #ifndef HEXDUMP_COLS<br> #define HEXDUMP_COLS 16<br> #endif<br>@@ -418,6 +417,10 @@ int main(int argc, char *argv[])<br>     // Register all the handlers that provider implementation to IPMI commands.<br>     ipmi_register_callback_handlers(HOST_IPMI_LIB_PATH);<br> <br>+ // Start the Host Services Dbus Objects<br>+ start_host_service(bus, slot);<br>+<br>+ // Watch for BT messages<br>     r = sd_bus_add_match(bus, &slot, FILTER, handle_ipmi_command, NULL);<br>     if (r < 0) {<br>         fprintf(stderr, "Failed: sd_bus_add_match: %s : %s\n", strerror(-r), FILTER);<br>@@ -427,7 +430,6 @@ int main(int argc, char *argv[])<br> <br>     for (;;) {<br>         /* Process requests */<br>-<br>         r = sd_bus_process(bus, NULL);<br>         if (r < 0) {<br>             fprintf(stderr, "Failed to process bus: %s\n", strerror(-r));<br>diff --git a/ipmid.H b/ipmid.H<br>index 73b60e6..3de2c8c 100644<br>--- a/ipmid.H<br>+++ b/ipmid.H<br>@@ -2,6 +2,7 @@<br> #define __HOST_IPMID_IPMI_H__<br> #include "ipmid-api.h"<br> #include <stdio.h><br>+#include "host-services.h"<br> <br> // When the requester sends in a netfn and a command along with data, this<br> // function will look for registered handlers that will handle that [netfn,cmd]<br>--<br>2.6.3<br><br><br>_______________________________________________<br>openbmc mailing list<br>openbmc@lists.ozlabs.org<br><a href="https://lists.ozlabs.org/listinfo/openbmc" target="_blank" >https://lists.ozlabs.org/listinfo/openbmc</a></font></div></blockquote></div></div></div></div><BR>