summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ipmitool/Makefile.am2
-rw-r--r--include/ipmitool/ipmi_intf.h1
-rw-r--r--include/ipmitool/ipmi_vita.h49
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/ipmi_main.c32
-rw-r--r--lib/ipmi_picmg.c64
-rw-r--r--lib/ipmi_vita.c1006
-rw-r--r--src/ipmitool.c2
8 files changed, 1119 insertions, 39 deletions
diff --git a/include/ipmitool/Makefile.am b/include/ipmitool/Makefile.am
index 925881e..5a9062c 100644
--- a/include/ipmitool/Makefile.am
+++ b/include/ipmitool/Makefile.am
@@ -38,5 +38,5 @@ noinst_HEADERS = log.h bswap.h hpm2.h helper.h ipmi.h ipmi_cc.h ipmi_intf.h \
ipmi_oem.h ipmi_sdradd.h ipmi_isol.h ipmi_sunoem.h ipmi_picmg.h \
ipmi_fwum.h ipmi_main.h ipmi_tsol.h ipmi_firewall.h \
ipmi_kontronoem.h ipmi_ekanalyzer.h ipmi_gendev.h ipmi_ime.h \
- ipmi_delloem.h ipmi_dcmi.h
+ ipmi_delloem.h ipmi_dcmi.h ipmi_vita.h
diff --git a/include/ipmitool/ipmi_intf.h b/include/ipmitool/ipmi_intf.h
index f9f6592..6b6e247 100644
--- a/include/ipmitool/ipmi_intf.h
+++ b/include/ipmitool/ipmi_intf.h
@@ -168,6 +168,7 @@ struct ipmi_intf {
int abort;
int noanswer;
int picmg_avail;
+ int vita_avail;
IPMI_OEM manufacturer_id;
struct ipmi_session * session;
diff --git a/include/ipmitool/ipmi_vita.h b/include/ipmitool/ipmi_vita.h
new file mode 100644
index 0000000..71d471a
--- /dev/null
+++ b/include/ipmitool/ipmi_vita.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) Pigeon Point Systems. All right reserved
+ */
+
+#ifndef _IPMI_VITA_H_
+#define _IPMI_VITA_H_
+
+/* VITA 46.11 commands */
+#define VITA_GET_VSO_CAPABILITIES_CMD 0x00
+#define VITA_FRU_CONTROL_CMD 0x04
+#define VITA_GET_FRU_LED_PROPERTIES_CMD 0x05
+#define VITA_GET_LED_COLOR_CAPABILITIES_CMD 0x06
+#define VITA_SET_FRU_LED_STATE_CMD 0x07
+#define VITA_GET_FRU_LED_STATE_CMD 0x08
+#define VITA_SET_FRU_STATE_POLICY_BITS_CMD 0x0A
+#define VITA_GET_FRU_STATE_POLICY_BITS_CMD 0x0B
+#define VITA_SET_FRU_ACTIVATION_CMD 0x0C
+#define VITA_GET_FRU_ADDRESS_INFO_CMD 0x40
+
+/* VITA 46.11 site types */
+#define VITA_FRONT_VPX_MODULE 0x00
+#define VITA_POWER_ENTRY 0x01
+#define VITA_CHASSIS_FRU 0x02
+#define VITA_DEDICATED_CHMC 0x03
+#define VITA_FAN_TRAY 0x04
+#define VITA_FAN_TRAY_FILTER 0x05
+#define VITA_ALARM_PANEL 0x06
+#define VITA_XMC 0x07
+#define VITA_VPX_RTM 0x09
+#define VITA_FRONT_VME_MODULE 0x0A
+#define VITA_FRONT_VXS_MODULE 0x0B
+#define VITA_POWER_SUPPLY 0x0C
+#define VITA_FRONT_VITA62_MODULE 0x0D
+#define VITA_71_MODULE 0x0E
+#define VITA_FMC 0x0F
+
+
+#define GROUP_EXT_VITA 0x03
+
+extern uint8_t
+vita_discover(struct ipmi_intf *intf);
+
+extern uint8_t
+ipmi_vita_ipmb_address(struct ipmi_intf *intf);
+
+extern int
+ipmi_vita_main(struct ipmi_intf * intf, int argc, char ** argv);
+
+#endif /* _IPMI_VITA_H_ */
diff --git a/lib/Makefile.am b/lib/Makefile.am
index d878b11..2a316db 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -39,7 +39,7 @@ libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \
ipmi_oem.c ipmi_isol.c ipmi_sunoem.c ipmi_fwum.c ipmi_picmg.c \
ipmi_main.c ipmi_tsol.c ipmi_firewall.c ipmi_kontronoem.c \
ipmi_hpmfwupg.c ipmi_sdradd.c ipmi_ekanalyzer.c ipmi_gendev.c \
- ipmi_ime.c ipmi_delloem.c ipmi_dcmi.c hpm2.c \
+ ipmi_ime.c ipmi_delloem.c ipmi_dcmi.c hpm2.c ipmi_vita.c \
../src/plugins/lan/md5.c ../src/plugins/lan/md5.h
libipmitool_la_LDFLAGS = -export-dynamic
diff --git a/lib/ipmi_main.c b/lib/ipmi_main.c
index 26f3457..0f01001 100644
--- a/lib/ipmi_main.c
+++ b/lib/ipmi_main.c
@@ -344,6 +344,18 @@ ipmi_parse_hex(const char *str)
return out;
}
+static uint8_t
+ipmi_acquire_ipmb_address(struct ipmi_intf * intf)
+{
+ if (intf->picmg_avail) {
+ return ipmi_picmg_ipmb_address(intf);
+ } else if (intf->vita_avail) {
+ return ipmi_vita_ipmb_address(intf);
+ } else {
+ return 0;
+ }
+}
+
/* ipmi_parse_options - helper function to handle parsing command line options
*
* @argc: count of options
@@ -907,14 +919,22 @@ ipmi_main(int argc, char ** argv,
}
}
/*
- * Attempt picmg discovery of the actual interface address unless
+ * Attempt picmg/vita discovery of the actual interface address unless
* the users specified an address.
* Address specification always overrides discovery
*/
- if (picmg_discover(ipmi_main_intf) && !arg_addr) {
- lprintf(LOG_DEBUG, "Running PICMG Get Address Info");
- addr = ipmi_picmg_ipmb_address(ipmi_main_intf);
- lprintf(LOG_INFO, "Discovered IPMB-0 address 0x%x", addr);
+ if (picmg_discover(ipmi_main_intf)) {
+ ipmi_main_intf->picmg_avail = 1;
+ } else if (vita_discover(ipmi_main_intf)) {
+ ipmi_main_intf->vita_avail = 1;
+ }
+
+ if (arg_addr) {
+ addr = arg_addr;
+ } else {
+ lprintf(LOG_DEBUG, "Acquire IPMB address");
+ addr = ipmi_acquire_ipmb_address(ipmi_main_intf);
+ lprintf(LOG_INFO, "Discovered IPMB address 0x%x", addr);
}
/*
@@ -956,7 +976,7 @@ ipmi_main(int argc, char ** argv,
ipmi_intf_session_set_privlvl(ipmi_main_intf, IPMI_SESSION_PRIV_ADMIN);
/* Get the ipmb address of the targeted entity */
ipmi_main_intf->target_ipmb_addr =
- ipmi_picmg_ipmb_address(ipmi_main_intf);
+ ipmi_acquire_ipmb_address(ipmi_main_intf);
lprintf(LOG_DEBUG, "Specified addressing Target %#x:%#x Transit %#x:%#x",
ipmi_main_intf->target_addr,
ipmi_main_intf->target_channel,
diff --git a/lib/ipmi_picmg.c b/lib/ipmi_picmg.c
index 914d11d..9dfa0d1 100644
--- a/lib/ipmi_picmg.c
+++ b/lib/ipmi_picmg.c
@@ -2325,37 +2325,39 @@ picmg_discover(struct ipmi_intf *intf) {
struct ipmi_rq req;
struct ipmi_rs *rsp;
char msg_data;
+ uint8_t picmg_avail = 0;
- if (intf->picmg_avail == 0) {
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
- msg_data = 0x00;
- req.msg.data = &msg_data;
- req.msg.data_len = 1;
- msg_data = 0;
-
- lprintf(LOG_DEBUG, "Running Get PICMG Properties my_addr %#x, transit %#x, target %#x",
- intf->my_addr, intf->transit_addr, intf->target_addr);
- rsp = intf->sendrecv(intf, &req);
- if (rsp && !rsp->ccode) {
- if ( (rsp->data[0] == 0) &&
- ((rsp->data[1] & 0x0F) == PICMG_ATCA_MAJOR_VERSION
- || (rsp->data[1] & 0x0F) == PICMG_AMC_MAJOR_VERSION) ) {
- intf->picmg_avail = 1;
- lprintf(LOG_DEBUG, "Discovered PICMG Extension %d.%d",
- (rsp->data[1] & 0x0f), (rsp->data[1] >> 4));
- }
- } else {
- if (rsp == NULL) {
- lprintf(LOG_DEBUG,"No Response from Get PICMG Properties");
- } else {
- lprintf(LOG_DEBUG,"Error Response %#x from Get PICMG Properities", rsp->ccode);
- }
- }
- }
- if (intf->picmg_avail == 0) {
- lprintf(LOG_DEBUG, "No PICMG Extenstion discovered");
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
+ msg_data = 0x00;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+ msg_data = 0;
+
+ lprintf(LOG_INFO, "Running Get PICMG Properties my_addr %#x, transit %#x, target %#x",
+ intf->my_addr, intf->transit_addr, intf->target_addr);
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_INFO,"No response from Get PICMG Properties");
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_INFO,"Error response %#x from Get PICMG Properities",
+ rsp->ccode);
+ } else if (rsp->data_len < 4) {
+ lprintf(LOG_INFO,"Invalid Get PICMG Properties response length %d",
+ rsp->data_len);
+ } else if (rsp->data[0] != 0) {
+ lprintf(LOG_INFO,"Invalid Get PICMG Properties group extension %#x",
+ rsp->data[0]);
+ } else if ((rsp->data[1] & 0x0F) != PICMG_ATCA_MAJOR_VERSION
+ && (rsp->data[1] & 0x0F) != PICMG_AMC_MAJOR_VERSION) {
+ lprintf(LOG_INFO,"Unknown PICMG Extension Version %d.%d",
+ (rsp->data[1] & 0x0F), (rsp->data[1] >> 4));
+ } else {
+ picmg_avail = 1;
+ lprintf(LOG_INFO, "Discovered PICMG Extension Version %d.%d",
+ (rsp->data[1] & 0x0f), (rsp->data[1] >> 4));
}
- return intf->picmg_avail;
+
+ return picmg_avail;
}
diff --git a/lib/ipmi_vita.c b/lib/ipmi_vita.c
new file mode 100644
index 0000000..4f8b522
--- /dev/null
+++ b/lib/ipmi_vita.c
@@ -0,0 +1,1006 @@
+/*
+ * Copyright (c) 2014 Pigeon Point Systems. All right reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Pigeon Point Systems, or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS, " without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
+ * PIGEON POINT SYSTEMS ("PPS") AND ITS LICENSORS SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
+ * PPS OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
+ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
+ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
+ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF PPS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <ipmitool/ipmi_intf.h>
+#include <ipmitool/ipmi_picmg.h>
+#include <ipmitool/ipmi_vita.h>
+#include <ipmitool/ipmi_fru.h>
+#include <ipmitool/ipmi_strings.h>
+#include <ipmitool/log.h>
+
+/* Handled VITA 46.11 commands */
+#define VITA_CMD_HELP 0
+#define VITA_CMD_PROPERTIES 1
+#define VITA_CMD_FRUCONTROL 2
+#define VITA_CMD_ADDRINFO 3
+#define VITA_CMD_ACTIVATE 4
+#define VITA_CMD_DEACTIVATE 5
+#define VITA_CMD_POLICY_GET 6
+#define VITA_CMD_POLICY_SET 7
+#define VITA_CMD_LED_PROP 8
+#define VITA_CMD_LED_CAP 9
+#define VITA_CMD_LED_GET 10
+#define VITA_CMD_LED_SET 11
+#define VITA_CMD_UNKNOWN 255
+
+/* VITA 46.11 Site Type strings */
+static struct valstr vita_site_types[] = {
+ { VITA_FRONT_VPX_MODULE, "Front Loading VPX Plug-In Module" },
+ { VITA_POWER_ENTRY, "Power Entry Module" },
+ { VITA_CHASSIS_FRU, "Chassic FRU Information Module" },
+ { VITA_DEDICATED_CHMC, "Dedicated Chassis Manager" },
+ { VITA_FAN_TRAY, "Fan Tray" },
+ { VITA_FAN_TRAY_FILTER, "Fan Tray Filter" },
+ { VITA_ALARM_PANEL, "Alarm Panel" },
+ { VITA_XMC, "XMC" },
+ { VITA_VPX_RTM, "VPX Rear Transition Module" },
+ { VITA_FRONT_VME_MODULE, "Front Loading VME Plug-In Module" },
+ { VITA_FRONT_VXS_MODULE, "Front Loading VXS Plug-In Module" },
+ { VITA_POWER_SUPPLY, "Power Supply" },
+ { VITA_FRONT_VITA62_MODULE, "Front Loading VITA 62 Module\n" },
+ { VITA_71_MODULE, "VITA 71 Module\n" },
+ { VITA_FMC, "FMC\n" },
+ { 0, NULL }
+};
+
+/* VITA 46.11 command help strings */
+static struct valstr vita_help_strings[] = {
+ {
+ VITA_CMD_HELP,
+ "VITA commands:\n"
+ " properties - get VSO properties\n"
+ " frucontrol - FRU control\n"
+ " addrinfo - get address information\n"
+ " activate - activate a FRU\n"
+ " deactivate - deactivate a FRU\n"
+ " policy get - get the FRU activation policy\n"
+ " policy set - set the FRU activation policy\n"
+ " led prop - get led properties\n"
+ " led cap - get led color capabilities\n"
+ " led get - get led state\n"
+ " led set - set led state"
+ },
+ {
+ VITA_CMD_FRUCONTROL,
+ "usage: frucontrol <FRU-ID> <OPTION>\n"
+ " OPTION: 0 - Cold Reset\n"
+ " 1 - Warm Reset\n"
+ " 2 - Graceful Reboot\n"
+ " 3 - Issue Diagnostic Interrupt"
+ },
+ {
+ VITA_CMD_ADDRINFO,
+ "usage: addrinfo [<FRU-ID>]"
+ },
+ {
+ VITA_CMD_ACTIVATE,
+ "usage: activate <FRU-ID>"
+ },
+ {
+ VITA_CMD_DEACTIVATE,
+ "usage: deactivate <FRU-ID>"
+ },
+ {
+ VITA_CMD_POLICY_GET,
+ "usage: policy get <FRU-ID>"
+ },
+ {
+ VITA_CMD_POLICY_SET,
+ "usage: policy set <FRU-ID> <MASK> <VALUE>\n"
+ " MASK: [3] affect the Default-Activation-Locked Policy Bit\n"
+ " [2] affect the Commanded-Deactivation-Ignored Policy Bit\n"
+ " [1] affect the Deactivation-Locked Policy Bit\n"
+ " [0] affect the Activation-Locked Policy Bit\n"
+ " VALUE: [3] value for the Default-Activation-Locked Policy Bit\n"
+ " [2] value for the Commanded-Deactivation-Ignored Policy Bit\n"
+ " [1] value for the Deactivation-Locked Policy Bit\n"
+ " [0] value for the Activation-Locked Policy Bit"
+ },
+ {
+ VITA_CMD_LED_PROP,
+ "usage: led prop <FRU-ID>"
+ },
+ {
+ VITA_CMD_LED_CAP,
+ "usage: led cap <FRU-ID> <LED-ID"
+ },
+ {
+ VITA_CMD_LED_GET,
+ "usage: led get <FRU-ID> <LED-ID",
+ },
+ {
+ VITA_CMD_LED_SET,
+ "usage: led set <FRU-ID> <LED-ID> <FUNCTION> <DURATION> <COLOR>\n"
+ " <FRU-ID>\n"
+ " <LED-ID> 0-0xFE: Specified LED\n"
+ " 0xFF: All LEDs under management control\n"
+ " <FUNCTION> 0: LED OFF override\n"
+ " 1 - 250: LED blinking override (off duration)\n"
+ " 251: LED Lamp Test\n"
+ " 252: LED restore to local control\n"
+ " 255: LED ON override\n"
+ " <DURATION> 1 - 127: LED Lamp Test / on duration\n"
+ " <COLOR> 1: BLUE\n"
+ " 2: RED\n"
+ " 3: GREEN\n"
+ " 4: AMBER\n"
+ " 5: ORANGE\n"
+ " 6: WHITE\n"
+ " 0xE: do not change\n"
+ " 0xF: use default color"
+ },
+ {
+ VITA_CMD_UNKNOWN,
+ "Unknown command"
+ },
+ { 0, NULL }
+};
+
+/* check if VITA 46.11 is supported */
+uint8_t
+vita_discover(struct ipmi_intf *intf)
+{
+ struct ipmi_rq req;
+ struct ipmi_rs *rsp;
+ unsigned char msg_data;
+ int vita_avail = 0;
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_VSO_CAPABILITIES_CMD;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+
+ msg_data = GROUP_EXT_VITA;
+
+ lprintf(LOG_INFO, "Running Get VSO Capabilities my_addr %#x, "
+ "transit %#x, target %#x",
+ intf->my_addr, intf->transit_addr, intf->target_addr);
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "No valid response received");
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Invalid completion code received: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ } else if (rsp->data_len < 5) {
+ lprintf(LOG_ERR, "Invalid response length %d",
+ rsp->data_len);
+ } else if (rsp->data[0] != GROUP_EXT_VITA) {
+ lprintf(LOG_ERR, "Invalid group extension %#x",
+ rsp->data[0]);
+ } else if ((rsp->data[3] & 0x03) != 0) {
+ lprintf(LOG_ERR, "Unknown VSO Standard %d",
+ (rsp->data[3] & 0x03));
+ } else if ((rsp->data[4] & 0x0F) != 1) {
+ lprintf(LOG_ERR, "Unknown VSO Specification Revision %d.%d",
+ (rsp->data[4] & 0x0F), (rsp->data[4] >> 4));
+ } else {
+ vita_avail = 1;
+ lprintf(LOG_INFO, "Discovered VITA 46.11 Revision %d.%d",
+ (rsp->data[4] & 0x0F), (rsp->data[4] >> 4));
+ }
+
+ return vita_avail;
+}
+
+uint8_t
+ipmi_vita_ipmb_address(struct ipmi_intf *intf)
+{
+ struct ipmi_rq req;
+ struct ipmi_rs *rsp;
+ unsigned char msg_data;
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_ADDRESS_INFO_CMD;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+
+ msg_data = GROUP_EXT_VITA;
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "No valid response received");
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Invalid completion code received: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ } else if (rsp->data_len < 7) {
+ lprintf(LOG_ERR, "Invalid response length %d",
+ rsp->data_len);
+ } else if (rsp->data[0] != GROUP_EXT_VITA) {
+ lprintf(LOG_ERR, "Invalid group extension %#x",
+ rsp->data[0]);
+ } else {
+ return rsp->data[2];
+ }
+
+ return 0;
+}
+
+static int
+ipmi_vita_getaddr(struct ipmi_intf *intf, int argc, char **argv)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[2];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_ADDRESS_INFO_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 2;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = 0; /* default FRU ID */
+
+ if (argc > 0) {
+ /* validate and get FRU Device ID */
+ if (is_fru_id(argv[0], &msg_data[1]) != 0) {
+ return -1;
+ }
+ }
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "No valid response received");
+ return -1;
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Invalid completion code received: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ return -1;
+ } else if (rsp->data_len < 7) {
+ lprintf(LOG_ERR, "Invalid response length %d",
+ rsp->data_len);
+ return -1;
+ } else if (rsp->data[0] != GROUP_EXT_VITA) {
+ lprintf(LOG_ERR, "Invalid group extension %#x",
+ rsp->data[0]);
+ return -1;
+ }
+
+ printf("Hardware Address : 0x%02x\n", rsp->data[1]);
+ printf("IPMB-0 Address : 0x%02x\n", rsp->data[2]);
+ printf("FRU ID : 0x%02x\n", rsp->data[4]);
+ printf("Site ID : 0x%02x\n", rsp->data[5]);
+ printf("Site Type : %s\n", val2str(rsp->data[6],
+ vita_site_types));
+ if (rsp->data_len > 8) {
+ printf("Channel 7 Address: 0x%02x\n", rsp->data[8]);
+ }
+
+ return 0;
+}
+
+static int
+ipmi_vita_get_vso_capabilities(struct ipmi_intf *intf)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data, tmp;
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_VSO_CAPABILITIES_CMD;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+
+ msg_data = GROUP_EXT_VITA; /* VITA identifier */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "No valid response received.");
+ return -1;
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Invalid completion code received: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ return -1;
+ } else if (rsp->data_len < 5) {
+ lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
+ return -1;
+ } else if (rsp->data[0] != GROUP_EXT_VITA) {
+ lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
+ return -1;
+ }
+
+ printf("VSO Identifier : 0x%02x\n", rsp->data[0]);
+ printf("IPMC Identifier : 0x%02x\n", rsp->data[1]);
+ printf(" Tier %d\n", (rsp->data[1] & 0x03) + 1);
+ printf(" Layer %d\n", ((rsp->data[1] & 0x30) >> 4) + 1);
+
+ printf("IPMB Capabilities : 0x%02x\n", rsp->data[2]);
+
+ tmp = (rsp->data[2] & 0x30) >> 4;
+
+ printf(" Frequency %skHz\n",
+ tmp == 0 ? "100" : tmp == 1 ? "400" : "RESERVED");
+
+ tmp = rsp->data[2] & 3;
+
+ if (tmp == 1) {
+ printf(" 2 IPMB interfaces supported\n");
+ } else if (tmp == 0) {
+ printf(" 1 IPMB interface supported\n");
+ }
+
+ printf("VSO Standard : %s\n",
+ (rsp->data[3] & 0x3) == 0 ? "VITA 46.11" : "RESERVED");
+
+ printf("VSO Spec Revision : %d.%d\n", rsp->data[4] & 0xf,
+ rsp->data[4] >> 4);
+
+ printf("Max FRU Device ID : 0x%02x\n", rsp->data[5]);
+ printf("FRU Device ID : 0x%02x\n", rsp->data[6]);
+
+ return 0;
+}
+
+static int
+ipmi_vita_set_fru_activation(struct ipmi_intf *intf,
+ char **argv, unsigned char command)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[3];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_SET_FRU_ACTIVATION_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 3;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
+ return -1;
+ }
+ msg_data[2] = command; /* command */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "No valid response received.");
+ return -1;
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Invalid completion code received: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ return -1;
+ } else if (rsp->data_len < 1) {
+ lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
+ return -1;
+ } else if (rsp->data[0] != GROUP_EXT_VITA) {
+ lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
+ return -1;
+ }
+
+ printf("FRU has been successfully %s\n",
+ command ? "activated" : "deactivated");
+
+ return 0;
+}
+
+static int
+ipmi_vita_get_fru_state_policy_bits(struct ipmi_intf *intf, char **argv)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[2];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_STATE_POLICY_BITS_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 2;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
+ return -1;
+ }
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "No valid response received.");
+ return -1;
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Invalid completion code received: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ return -1;
+ } else if (rsp->data_len < 2) {
+ lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
+ return -1;
+ } else if (rsp->data[0] != GROUP_EXT_VITA) {
+ lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
+ return -1;
+ }
+
+ printf("FRU State Policy Bits: %xh\n", rsp->data[1]);
+ printf(" Default-Activation-Locked Policy Bit is %d\n",
+ rsp->data[1] & 0x08 ? 1 : 0);
+ printf(" Commanded-Deactivation-Ignored Policy Bit is %d\n",
+ rsp->data[1] & 0x04 ? 1 : 0);
+ printf(" Deactivation-Locked Policy Bit is %d\n",
+ rsp->data[1] & 0x02 ? 1 : 0);
+ printf(" Activation-Locked Policy Bit is %d\n",
+ rsp->data[1] & 0x01);
+
+ return 0;
+}
+
+static int
+ipmi_vita_set_fru_state_policy_bits(struct ipmi_intf *intf, char **argv)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[4];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_SET_FRU_STATE_POLICY_BITS_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 4;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
+ return -1;
+ }
+ if (str2uchar(argv[1], &msg_data[2]) != 0) { /* bits mask */
+ return -1;
+ }
+ if (str2uchar(argv[2], &msg_data[3]) != 0) { /* bits */
+ return -1;
+ }
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "No valid response received.");
+ return -1;
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Invalid completion code received: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ return -1;
+ } else if (rsp->data_len < 1) {
+ lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
+ return -1;
+ } else if (rsp->data[0] != GROUP_EXT_VITA) {
+ lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
+ return -1;
+ }
+
+ printf("FRU state policy bits have been updated\n");
+
+ return 0;
+}
+
+static int
+ipmi_vita_get_led_properties(struct ipmi_intf *intf, char **argv)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[2];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_LED_PROPERTIES_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 2;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
+ return -1;
+ }
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "No valid response received.");
+ return -1;
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Invalid completion code received: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ return -1;
+ } else if (rsp->data_len < 3) {
+ lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
+ return -1;
+ } else if (rsp->data[0] != GROUP_EXT_VITA) {
+ lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
+ return -1;
+ }
+
+ printf("LED Count: %#x\n", rsp->data[2]);
+
+ return 0;
+}
+
+static int
+ipmi_vita_get_led_color_capabilities(struct ipmi_intf *intf, char **argv)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[3];
+ int i;
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_LED_COLOR_CAPABILITIES_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 3;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
+ return -1;
+ }
+ if (str2uchar(argv[1], &msg_data[2]) != 0) { /* LED-ID */
+ return -1;
+ }
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "No valid response received.");
+ return -1;
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Invalid completion code received: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ return -1;
+ } else if (rsp->data_len < 5) {
+ lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
+ return -1;
+ } else if (rsp->data[0] != GROUP_EXT_VITA) {
+ lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
+ return -1;
+ }
+
+ printf("LED Color Capabilities: ");
+ for (i = 0; i < 8; i++) {
+ if (rsp->data[1] & (0x01 << i)) {
+ printf("%s, ", led_color_str[i]);
+ }
+ }
+ putchar('\n');
+
+ printf("Default LED Color in\n");
+ printf(" LOCAL control: %s\n", led_color_str[rsp->data[2]]);
+ printf(" OVERRIDE state: %s\n", led_color_str[rsp->data[3]]);
+
+ if (rsp->data_len == 5) {
+ printf("LED flags:\n");
+ if (rsp->data[4] & 2) {
+ printf(" [HW RESTRICT]\n");
+ }
+ if (rsp->data[4] & 1) {
+ printf(" [PAYLOAD PWR]\n");
+ }
+ }
+
+ return 0;
+}
+
+static int
+ipmi_vita_get_led_state(struct ipmi_intf *intf, char **argv)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[3];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_LED_STATE_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 3;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
+ return -1;
+ }
+ if (str2uchar(argv[1], &msg_data[2]) != 0) { /* LED-ID */
+ return -1;
+ }
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "No valid response received.");
+ return -1;
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Invalid completion code received: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ return -1;
+ } else if (rsp->data_len < 5
+ || ((rsp->data[1] & 0x2) && rsp->data_len < 8)
+ || ((rsp->data[1] & 0x4) && rsp->data_len < 9)) {
+ lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
+ return -1;
+ } else if (rsp->data[0] != GROUP_EXT_VITA) {
+ lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
+ return -1;
+ }
+
+ printf("LED states: %x\t", rsp->data[1]);
+ if (rsp->data[1] & 0x1) {
+ printf("[LOCAL CONTROL] ");
+ }
+ if (rsp->data[1] & 0x2) {
+ printf("[OVERRIDE] ");
+ }
+ if (rsp->data[1] & 0x4) {
+ printf("[LAMPTEST] ");
+ }
+ if (rsp->data[1] & 0x8) {
+ printf("[HW RESTRICT] ");
+ }
+ putchar('\n');
+
+ if (rsp->data[1] & 1) {
+ printf(" Local Control function: %x\t", rsp->data[2]);
+ if (rsp->data[2] == 0x0) {
+ printf("[OFF]\n");
+ } else if (rsp->data[2] == 0xff) {
+ printf("[ON]\n");
+ } else {
+ printf("[BLINKING]\n");
+ }
+ printf(" Local Control On-Duration: %x\n", rsp->data[3]);
+ printf(" Local Control Color: %x\t[%s]\n",
+ rsp->data[4], led_color_str[rsp->data[4] & 7]);
+ }
+
+ /* override state or lamp test */
+ if (rsp->data[1] & 0x06) {
+ printf(" Override function: %x\t", rsp->data[5]);
+ if (rsp->data[5] == 0x0) {
+ printf("[OFF]\n");
+ } else if (rsp->data[5] == 0xff) {
+ printf("[ON]\n");
+ } else {
+ printf("[BLINKING]\n");
+ }
+ printf(" Override On-Duration: %x\n", rsp->data[6]);
+ printf(" Override Color: %x\t[%s]\n",
+ rsp->data[7], led_color_str[rsp->data[7] & 7]);
+ if (rsp->data[1] == 0x04) {
+ printf(" Lamp test duration: %x\n", rsp->data[8]);
+ }
+ }
+
+ return 0;
+}
+
+static int
+ipmi_vita_set_led_state(struct ipmi_intf *intf, char **argv)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[6];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_SET_FRU_LED_STATE_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 6;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
+ return -1;
+ }
+ if (str2uchar(argv[1], &msg_data[2]) != 0) { /* LED-ID */
+ return -1;
+ }
+ if (str2uchar(argv[2], &msg_data[3]) != 0) { /* LED function */
+ return -1;
+ }
+ if (str2uchar(argv[3], &msg_data[4]) != 0) { /* LED on duration */
+ return -1;
+ }
+ if (str2uchar(argv[4], &msg_data[5]) != 0) { /* LED color */
+ return -1;
+ }
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "No valid response received.");
+ return -1;
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Invalid completion code received: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ return -1;
+ } else if (rsp->data_len < 1) {
+ lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
+ return -1;
+ } else if (rsp->data[0] != GROUP_EXT_VITA) {
+ lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
+ return -1;
+ }
+
+ printf("LED state has been updated\n");
+
+ return 0;
+}
+
+static int
+ipmi_vita_fru_control(struct ipmi_intf *intf, char **argv)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[3];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_FRU_CONTROL_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 3;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
+ return -1;
+ }
+ if (str2uchar(argv[1], &msg_data[2]) != 0) { /* control option */
+ return -1;
+ }
+
+ printf("FRU Device Id: %d FRU Control Option: %s\n", msg_data[1],
+ val2str(msg_data[2], picmg_frucontrol_vals));
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "No valid response received.");
+ return -1;
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Invalid completion code received: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ return -1;
+ } else if (rsp->data_len < 1) {
+ lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
+ return -1;
+ } else if (rsp->data[0] != GROUP_EXT_VITA) {
+ lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
+ return -1;
+ }
+
+ printf("FRU Control: ok\n");
+
+ return 0;
+}
+
+static int
+ipmi_vita_get_cmd(int argc, char **argv)
+{
+ if (argc < 1 || !strncmp(argv[0], "help", 4)) {
+ return VITA_CMD_HELP;
+ }
+
+ /* Get VSO Properties */
+ if (!strncmp(argv[0], "properties", 10)) {
+ return VITA_CMD_PROPERTIES;
+ }
+
+ /* FRU Control command */
+ if (!strncmp(argv[0], "frucontrol", 10)) {
+ return VITA_CMD_FRUCONTROL;
+ }
+
+ /* Get FRU Address Info command */
+ if (!strncmp(argv[0], "addrinfo", 8)) {
+ return VITA_CMD_ADDRINFO;
+ }
+
+ /* Set FRU Activation (activate) command */
+ if (!strncmp(argv[0], "activate", 8)) {
+ return VITA_CMD_ACTIVATE;
+ }
+
+ /* Set FRU Activation (deactivate) command */
+ if (!strncmp(argv[0], "deactivate", 10)) {
+ return VITA_CMD_DEACTIVATE;
+ }
+
+ /* FRU State Policy Bits commands */
+ if (!strncmp(argv[0], "policy", 6)) {
+ if (argc < 2) {
+ return VITA_CMD_UNKNOWN;
+ }
+
+ /* Get FRU State Policy Bits command */
+ if (!strncmp(argv[1], "get", 3)) {
+ return VITA_CMD_POLICY_GET;
+ }
+
+ /* Set FRU State Policy Bits command */
+ if (!strncmp(argv[1], "set", 3)) {
+ return VITA_CMD_POLICY_SET;
+ }
+
+ /* unknown command */
+ return VITA_CMD_UNKNOWN;
+ }
+
+ /* FRU LED commands */
+ if (!strncmp(argv[0], "led", 3)) {
+ if (argc < 2) {
+ return VITA_CMD_UNKNOWN;
+ }
+
+ /* FRU LED Get Properties */
+ if (!strncmp(argv[1], "prop", 4)) {
+ return VITA_CMD_LED_PROP;
+ }
+
+ /* FRU LED Get Capabilities */
+ if (!strncmp(argv[1], "cap", 3)) {
+ return VITA_CMD_LED_CAP;
+ }
+
+ /* FRU LED Get State */
+ if (!strncmp(argv[1], "get", 3)) {
+ return VITA_CMD_LED_GET;
+ }
+
+ /* FRU LED Set State */
+ if (!strncmp(argv[1], "set", 3)) {
+ return VITA_CMD_LED_SET;
+ }
+
+ /* unknown command */
+ return VITA_CMD_UNKNOWN;
+ }
+
+ /* unknown command */
+ return VITA_CMD_UNKNOWN;
+}
+
+int
+ipmi_vita_main (struct ipmi_intf *intf, int argc, char **argv)
+{
+ int rc = -1, show_help = 0;
+ int cmd = ipmi_vita_get_cmd(argc, argv);
+
+ switch (cmd) {
+ case VITA_CMD_HELP:
+ cmd = ipmi_vita_get_cmd(argc - 1, &argv[1]);
+ show_help = 1;
+ rc = 0;
+ break;
+
+ case VITA_CMD_PROPERTIES:
+ rc = ipmi_vita_get_vso_capabilities(intf);
+ break;
+
+ case VITA_CMD_FRUCONTROL:
+ if (argc > 2) {
+ rc = ipmi_vita_fru_control(intf, &argv[1]);
+ } else {
+ show_help = 1;
+ }
+ break;
+
+ case VITA_CMD_ADDRINFO:
+ rc = ipmi_vita_getaddr(intf, argc - 1, &argv[1]);
+ break;
+
+ case VITA_CMD_ACTIVATE:
+ if (argc > 1) {
+ rc = ipmi_vita_set_fru_activation(intf, &argv[1], 1);
+ } else {
+ show_help = 1;
+ }
+ break;
+
+ case VITA_CMD_DEACTIVATE:
+ if (argc > 1) {
+ rc = ipmi_vita_set_fru_activation(intf, &argv[1], 0);
+ } else {
+ show_help = 1;
+ }
+ break;
+
+ case VITA_CMD_POLICY_GET:
+ if (argc > 2) {
+ rc = ipmi_vita_get_fru_state_policy_bits(intf,
+ &argv[2]);
+ } else {
+ show_help = 1;
+ }
+ break;
+
+ case VITA_CMD_POLICY_SET:
+ if (argc > 4) {
+ rc = ipmi_vita_set_fru_state_policy_bits(intf,
+ &argv[2]);
+ } else {
+ show_help = 1;
+ }
+ break;
+
+ case VITA_CMD_LED_PROP:
+ if (argc > 2) {
+ rc = ipmi_vita_get_led_properties(intf, &argv[2]);
+ } else {
+ show_help = 1;
+ }
+ break;
+
+ case VITA_CMD_LED_CAP:
+ if (argc > 3) {
+ rc = ipmi_vita_get_led_color_capabilities(intf,
+ &argv[2]);
+ } else {
+ show_help = 1;
+ }
+ break;
+
+ case VITA_CMD_LED_GET:
+ if (argc > 3) {
+ rc = ipmi_vita_get_led_state(intf, &argv[2]);
+ } else {
+ show_help = 1;
+ }
+ break;
+
+ case VITA_CMD_LED_SET:
+ if (argc > 6) {
+ rc = ipmi_vita_set_led_state(intf, &argv[2]);
+ } else {
+ show_help = 1;
+ }
+ break;
+ default:
+ lprintf(LOG_NOTICE, "Unknown command");
+ cmd = VITA_CMD_HELP;
+ show_help = 1;
+ break;
+ }
+
+ if (show_help) {
+ lprintf(LOG_NOTICE, "%s", val2str(cmd, vita_help_strings));
+ }
+
+ return rc;
+}
diff --git a/src/ipmitool.c b/src/ipmitool.c
index e368cc7..164fd44 100644
--- a/src/ipmitool.c
+++ b/src/ipmitool.c
@@ -65,6 +65,7 @@
#include <ipmitool/ipmi_ekanalyzer.h>
#include <ipmitool/ipmi_ime.h>
#include <ipmitool/ipmi_dcmi.h>
+#include <ipmitool/ipmi_vita.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -120,6 +121,7 @@ struct ipmi_cmd ipmitool_cmd_list[] = {
{ ipmi_hpmfwupg_main,"hpm", "Update HPM components using PICMG HPM.1 file"},
{ ipmi_ekanalyzer_main,"ekanalyzer", "run FRU-Ekeying analyzer using FRU files"},
{ ipmi_ime_main, "ime", "Update Intel Manageability Engine Firmware"},
+ { ipmi_vita_main, "vita", "Run a VITA 46.11 extended cmd"},
{ NULL },
};