ipmitool/ipmitool_update_to_git_head_31_01_2014_b0aad15d67007c74b.patch

13829 lines
433 KiB
Diff

diff --git a/ipmitool/AUTHORS b/ipmitool/AUTHORS
index 80ec56b..9589d87 100644
--- a/ipmitool/AUTHORS
+++ b/ipmitool/AUTHORS
@@ -2,3 +2,4 @@ Duncan Laurie <duncan@iceblink.org>
Fredrik Öhrn <ohrn@chl.chalmers.se>
Jon Cassorla <jon.cassorla@newisys.com>
Jeremy Ellington <jeremy@jeremye.net>
+Petter Reinholdtsen <pere@hungry.com>
diff --git a/ipmitool/README b/ipmitool/README
index ebcb188..cc5915c 100644
--- a/ipmitool/README
+++ b/ipmitool/README
@@ -410,3 +410,5 @@ http://www.intel.com/design/servers/ipmi/spec.htm
OpenIPMI project: Linux IPMI kernel driver and userland library
http://openipmi.sourceforge.net
+IPMItool commit archive
+https://lists.sourceforge.net/lists/listinfo/ipmitool-cvs
diff --git a/ipmitool/configure.in b/ipmitool/configure.in
index d98d754..a42e158 100644
--- a/ipmitool/configure.in
+++ b/ipmitool/configure.in
@@ -29,7 +29,7 @@ AC_C_BIGENDIAN
AC_FUNC_MALLOC
AC_FUNC_SELECT_ARGTYPES
AC_FUNC_STRTOD
-AC_CHECK_FUNCS([alarm gethostbyname socket select])
+AC_CHECK_FUNCS([alarm gethostbyname getaddrinfo getifaddrs socket select])
AC_CHECK_FUNCS([memmove memset strchr strdup strerror])
AC_CHECK_FUNCS([getpassphrase])
@@ -39,6 +39,8 @@ AM_PROG_LIBTOOL
LIBTOOL="$LIBTOOL --silent"
AC_SEARCH_LIBS([gethostbyname], [nsl])
+AC_SEARCH_LIBS([getaddrinfo], [nsl])
+AC_SEARCH_LIBS([getifaddrs], [nsl])
AC_SEARCH_LIBS([socket], [socket], [],
[AC_CHECK_LIB([nsl], [socket],
[LIBS="$LIBS -lsocket -lnsl"], [], [-lsocket])])
@@ -60,6 +62,7 @@ xenable_intf_imb=yes
xenable_intf_open=yes
xenable_intf_lipmi=yes
#xenable_intf_serial=yes
+xenable_intf_dummy=no
xenable_all_options=yes
xenable_ipmishell=yes
@@ -106,6 +109,11 @@ solaris*)
xenable_intf_bmc=no
xenable_intf_open=no
;;
+gnu*)
+ # disable the linux and solaris-specific interfaces on Hurd
+ xenable_intf_imb=no
+ xenable_intf_open=no
+ ;;
esac
AC_SUBST(ARCH, $host_cpu)
@@ -503,6 +511,18 @@ if test "x$xenable_intf_bmc" = "xyes"; then
IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB bmc/libintf_bmc.la"
fi
+dnl enable Dummy interface for testing
+AC_ARG_ENABLE([intf-dummy],
+ [AC_HELP_STRING([--enable-intf-dummy],
+ [enable Dummy(test) interface [default=no]])],
+ [xenable_intf_dummy=$enableval], [xenable_intf_dummy=no])
+if test "x$xenable_intf_dummy" = "xyes"; then
+ AC_DEFINE(IPMI_INTF_DUMMY, [1], [Define to 1 to enable Dummy interface.])
+ AC_SUBST(INTF_DUMMY, [dummy])
+ AC_SUBST(INTF_DUMMY_LIB, [libintf_dummy.la])
+ IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB dummy/libintf_dummy.la"
+fi
+
AC_SUBST(IPMITOOL_INTF_LIB)
if test "x$xenable_ipmishell" = "xyes"; then
@@ -602,7 +622,8 @@ AC_CONFIG_FILES([Makefile
src/plugins/imb/Makefile
src/plugins/bmc/Makefile
src/plugins/lipmi/Makefile
- src/plugins/serial/Makefile])
+ src/plugins/serial/Makefile
+ src/plugins/dummy/Makefile])
AC_OUTPUT
@@ -618,6 +639,7 @@ AC_MSG_RESULT([ imb : $xenable_intf_imb])
AC_MSG_RESULT([ bmc : $xenable_intf_bmc])
AC_MSG_RESULT([ lipmi : $xenable_intf_lipmi])
AC_MSG_RESULT([ serial : $xenable_intf_serial])
+AC_MSG_RESULT([ dummy : $xenable_intf_dummy])
AC_MSG_RESULT([])
AC_MSG_RESULT([Extra tools])
AC_MSG_RESULT([ ipmievd : yes])
diff --git a/ipmitool/contrib/Makefile.am b/ipmitool/contrib/Makefile.am
index a04f92f..c067dcb 100644
--- a/ipmitool/contrib/Makefile.am
+++ b/ipmitool/contrib/Makefile.am
@@ -34,6 +34,8 @@ dist_pkgdata_DATA = oem_ibm_sel_map
EXTRA_DIST = README \
bmclanconf ipmi.init.basic ipmi.init.redhat \
+ exchange-bmc-os-info.init.redhat exchange-bmc-os-info.service.redhat \
+ exchange-bmc-os-info.sysconf \
ipmievd.init.redhat ipmievd.init.suse ipmievd.init.debian \
collect_data.sh create_rrds.sh create_webpage_compact.sh create_webpage.sh \
bmc-snmp-proxy bmc-snmp-proxy.service bmc-snmp-proxy.sysconf
diff --git a/ipmitool/contrib/exchange-bmc-os-info.init.redhat b/ipmitool/contrib/exchange-bmc-os-info.init.redhat
new file mode 100644
index 0000000..b7ec43f
--- /dev/null
+++ b/ipmitool/contrib/exchange-bmc-os-info.init.redhat
@@ -0,0 +1,326 @@
+#!/bin/sh
+#############################################################################
+#
+# exchange-bmc-os-info: Set OS and BMC (Baseboard Management Controller)
+# parameters during system startup.
+#
+# version: 0.72
+#
+# Authors: Charles Rose <charles_rose@dell.com>
+# Jordan Hargrave <jordan_hargrave@dell.com>
+#
+# Description: Script to set OS information in the BMC; fetch BMC IP/URL
+# and set in the OS for use by other scripts/user.
+#
+# BMC IP and URL are made available in /var/run/bmc-info
+#
+# Example to launch BMC web-interface:
+# # . /var/run/bmc-info
+# # xdg-open $BMC_URL
+#
+# See here for details:
+# https://fedoraproject.org/wiki/Features/AgentFreeManagement
+#
+# OEM Specific: OEM specific ipmi commands go in:
+# 'oem_set_os_version' and 'oem_get_bmc_url'
+#############################################################################
+#
+# chkconfig: 345 99 00
+# description: Set OS name, hostname in BMC; make BMC IP/URL available in OS
+# processname: exchange-bmc-os-info
+# config: /etc/sysconfig/exchange-bmc-os-info
+#
+### BEGIN INIT INFO
+# Provides: exchange-bmc-os-info
+# Required-Start: ipmi
+# Default-Start: 3 4 5
+# Default-Stop: 0 1 2 6
+
+
+#############################################################################
+# GLOBALS
+#############################################################################
+CONFIGFILE=/etc/sysconfig/exchange-bmc-os-info
+IPMI_TOOL=/usr/bin/ipmitool
+BMC_INFO=/var/run/bmc-info
+
+# BMC Manufacturer ID used in 'oem_set_os_version' and 'oem_get_bmc_url'
+DELL="674"
+#OTHER_OEM="123"
+
+# Defaults for ${CONFIGFILE}
+SET_OS_INFO="yes"
+RESET_OS_INFO="no"
+SET_BMC_INFO="yes"
+
+# getsysinfo and setsysinfo commands
+IPMI_SET_SYSINFO="${IPMI_TOOL} mc setsysinfo"
+IPMI_GET_SYSINFO="${IPMI_TOOL} mc getsysinfo"
+#############################################################################
+SCRIPT_NAME=$(basename $0)
+
+# source config
+[ -r ${CONFIGFILE} ] && . ${CONFIGFILE}
+
+RETVAL=0
+
+if [ -f /bin/gettext.sh ]; then
+ GETTEXT=1
+ . /bin/gettext.sh
+ OUTPUT="eval_gettext"
+else
+ GETTEXT=0
+ OUTPUT="echo"
+fi
+
+#############################################################################
+# Get Vendor ID of BMC for use in 'oem_set_os_version' and 'oem_get_bmc_url'
+#
+get_bmc_vendor_id()
+{
+ BMC_VENDOR=$(${IPMI_TOOL} mc info 2>/dev/null | \
+ sed -n "s#^Manufacturer ID.*: ##p")
+ [ -z "${BMC_VENDOR}" ] && RETVAL=4
+}
+
+check_ipmitool()
+{
+ if [ -x ${IPMI_TOOL} ]; then
+ # v1.8.12 plus patches are required for set/getsysinfo support
+ # http://sourceforge.net/mailarchive/message.php?msg_id=29647222
+ [ ! ${IPMI_GET_SYSINFO} >/dev/null 2>&1 ] && \
+ RETVAL=3
+ else
+ RETVAL=2
+ fi
+}
+
+bmc_exists()
+{
+ check_ipmitool
+ [ $RETVAL -eq 0 ] && get_bmc_vendor_id
+ return $RETVAL
+}
+#############################################################################
+
+get_os_info()
+{
+ OS_HOSTNAME=$(hostname)
+ KERNEL_VERSION=$(uname -r -m)
+
+ if [ -e /etc/lsb-release ] ; then
+ . /etc/lsb-release
+ NAME=${DISTRIB_ID}
+ VERSION="${DISTRIB_RELEASE} ${DISTRIB_CODENAME}"
+ fi
+
+ # we prefer systemd's /etc/os-release over other sources
+ [ -e /etc/os-release ] && . /etc/os-release
+
+ OS_NAME=${NAME}
+ OS_VERSION="${VERSION} kernel ${KERNEL_VERSION}"
+}
+
+oem_set_os_version()
+{
+ # OS Version setting is not standard yet
+ # we need per vendor oem commands
+ case "${BMC_VENDOR}" in
+ $DELL) ${IPMI_SET_SYSINFO} delloem_os_version \
+ "${OS_VERSION}" > /dev/null 2>&1
+ return $?
+ ;;
+# Add OEM specific commands.
+# Example:
+# $OTHER_OEM) ${IPMI_SET_SYSINFO} otheroem_os_version \
+# "${OS_VERSION}" > /dev/null 2>&1
+# return $?
+# ;;
+ *) return 0
+ ;;
+ esac
+}
+
+set_os_info()
+{
+ # Set and reset OS info in the BMC
+ if [ "$1" = "reset" ]; then
+ OS_NAME=""
+ OS_HOSTNAME=""
+ OS_VERSION=""
+ fi
+
+ ${IPMI_SET_SYSINFO} os_name "${OS_NAME}" >/dev/null 2>&1 \
+ || RETVAL=6
+ ${IPMI_SET_SYSINFO} primary_os_name "${OS_NAME}" >/dev/null 2>&1 \
+ || RETVAL=6
+ ${IPMI_SET_SYSINFO} system_name "${OS_HOSTNAME}" >/dev/null 2>&1 \
+ || RETVAL=6
+ oem_set_os_version || RETVAL=6
+}
+
+#############################################################################
+valid_url()
+{
+ url="(https?|http)://[a-z0-9-]+(\.[a-z0-9-]+)+([/?].*)?"
+ printf -- "%s" "${TMP_URL}"| grep -Eq "^${url}"
+ return $?
+}
+
+oem_get_bmc_url()
+{
+ # BMC URL is not standard yet
+ # we need per vendor oem commands
+ case "$BMC_VENDOR" in
+ $DELL) TMP_URL=$(${IPMI_GET_SYSINFO} delloem_url 2> /dev/null)
+ ;;
+# Add OEM specific commands
+# Example:
+# $OTHER_OEM)
+# TMP_URL=$(${IPMI_GET_SYSINFO} otheroem_url 2> /dev/null)
+# ;;
+ *) TMP_URL="" ;;
+ esac
+
+ valid_url && BMC_URL=${TMP_URL} || BMC_URL=""
+}
+
+valid_ip()
+{
+ #Thanks to mkyong.com
+ octet="([01]?[[:digit:]][[:digit:]]?|2[0-4][[:digit:]]|25[0-5])"
+
+ printf -- "%s" "${TMP_IPv4}"| grep -Eq "^${octet}\\.${octet}\\.${octet}\\.${octet}$"
+ return $?
+}
+
+get_bmc_ip()
+{
+ #Thanks to http://ingvar.blog.redpill-linpro.com
+ for CHANNEL in `seq 1 14`
+ do
+ [ $(${IPMI_TOOL} lan print ${CHANNEL} 2>/dev/null \
+ | grep -q "^Set") ] || break
+ done
+
+ # Get BMC_IPv4 and BMC_URL from BMC
+ TMP_IPv4=$(${IPMI_TOOL} lan print ${CHANNEL} 2>/dev/null \
+ | sed -n "s#^IP Address .*: ##p")
+
+ valid_ip && BMC_IPv4=${TMP_IPv4} || BMC_IPv4=""
+}
+
+get_bmc_info()
+{
+ get_bmc_ip
+ if [ -z "${BMC_IPv4}" ] || [ "${BMC_IPv4}" = "0.0.0.0" ]; then
+ BMC_IPv4=""
+ RETVAL=5
+ else
+ # URL makes sense only if there is an IP
+ oem_get_bmc_url
+ fi
+}
+
+set_bmc_info()
+{
+ if [ ! $(touch "${BMC_INFO}" && chmod 600 "${BMC_INFO}") ]; then
+ printf "BMC_IPv4=%s\n" "${BMC_IPv4}" > "${BMC_INFO}"
+ [ -n "${BMC_URL}" ] && \
+ printf "BMC_URL=%s\n" "${BMC_URL}" >> "${BMC_INFO}"
+ else
+ RETVAL=5
+ fi
+}
+
+unset_bmc_info()
+{
+ [ -f ${BMC_INFO} ] && rm -f ${BMC_INFO} > /dev/null 2>&1
+}
+
+#############################################################################
+start()
+{
+ if bmc_exists; then
+ [ "${SET_OS_INFO}" = "yes" ] && \
+ get_os_info && set_os_info
+
+ if [ "${SET_BMC_INFO}" = "yes" ]; then
+ get_bmc_info
+ if [ ${RETVAL} -eq 0 ]; then
+ set_bmc_info
+ fi
+ fi
+ fi
+}
+
+#############################################################################
+stop()
+{
+ if bmc_exists; then
+ # reset OS info while system reboots
+ # aids with debugging OS boot-up issues
+ if [ "${RESET_OS_INFO}" = "yes" ]; then
+ set_os_info reset
+ fi
+ unset_bmc_info
+ fi
+}
+
+#############################################################################
+restart()
+{
+ stop
+ [ $RETVAL -eq 0 ] && start
+}
+
+#############################################################################
+status()
+{
+ [ -r ${BMC_INFO} ] && \
+ grep -q "BMC_IPv4" "${BMC_INFO}" >/dev/null 1>&2 && \
+ BMC_STATUS="ok" || BMC_STATUS="inactive"
+ ${OUTPUT} "${SCRIPT_NAME}: ${BMC_STATUS}" 1>&2
+ [ ${GETTEXT} -eq 1 ] && echo
+}
+
+#############################################################################
+usage()
+{
+ ${OUTPUT} "Usage: ${SCRIPT_NAME} {start|stop|restart|status}" 1>&2
+ [ ${GETTEXT} -eq 1 ] && echo
+ RETVAL=1
+}
+
+#############################################################################
+# MAIN
+#############################################################################
+case "$1" in
+ start) start ;;
+ stop) stop ;;
+ restart) restart ;;
+ status) status ;;
+ *) usage ;;
+esac
+
+case "$RETVAL" in
+ 0|1) ;;
+ 2) ${OUTPUT} "${SCRIPT_NAME}: ipmitool(1) not found." 1>&2 ;;
+ 3) ${OUTPUT} "${SCRIPT_NAME}: this version of ipmitool does not support getsysinfo." 1>&2 ;;
+ 4) ${OUTPUT} "${SCRIPT_NAME}: failed to communicate with BMC." 1>&2 ;;
+ 5) ${OUTPUT} "${SCRIPT_NAME}: failed to set OS information in BMC." 1>&2 ;;
+ 6) ${OUTPUT} "${SCRIPT_NAME}: failed to get BMC information." 1>&2 ;;
+ *) ${OUTPUT} "${SCRIPT_NAME}: unexpected error." 1>&2 ;;
+esac
+
+if [ ${RETVAL} -gt 1 ]; then
+ ${OUTPUT} " Return code: ${RETVAL}" 1>&2
+ [ ${GETTEXT} -eq 1 ] && echo
+fi
+
+
+exit ${RETVAL}
+
+#############################################################################
+# end of file
+#############################################################################
diff --git a/ipmitool/contrib/exchange-bmc-os-info.service.redhat b/ipmitool/contrib/exchange-bmc-os-info.service.redhat
new file mode 100644
index 0000000..100493b
--- /dev/null
+++ b/ipmitool/contrib/exchange-bmc-os-info.service.redhat
@@ -0,0 +1,13 @@
+[Unit]
+Description=Exchange Information between BMC and OS
+After=ipmi.service network.target
+Requires=ipmi.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/libexec/exchange-bmc-os-info start
+ExecStop=/usr/libexec/exchange-bmc-os-info stop
+
+[Install]
+WantedBy=multi-user.target
diff --git a/ipmitool/contrib/exchange-bmc-os-info.sysconf b/ipmitool/contrib/exchange-bmc-os-info.sysconf
new file mode 100644
index 0000000..2f0e675
--- /dev/null
+++ b/ipmitool/contrib/exchange-bmc-os-info.sysconf
@@ -0,0 +1,26 @@
+# exchange-bmc-os-info
+#
+# Config file to control Exchange of information between
+# the OS and Service Processor/Baseboard Management Controller (BMC)
+#
+# See here for details
+# https://fedoraproject.org/wiki/Features/AgentFreeManagement
+
+### Set OS Info in BMC/Service Processor ###
+# Name: SET_OS_INFO
+# Description: Set OS Name, Version and Hostname in the Service Processor (BMC)
+# Default: yes
+SET_OS_INFO="yes"
+
+### Reset OS Info in BMC/Service Processor ###
+# Name: RESET_OS_INFO
+# Description: Reset OS Name, Version and Hostname in the Service Processor (BMC).
+# Useful when the OS Name/Hostname should be empty on reboot
+# Default: no
+RESET_OS_INFO="no"
+
+### Set BMC/Service Processor Info in OS ###
+# Name; SET_BMC_INFO
+# Description: Set IP Address and URL of Service Processor/BMC in /run/bmc-info
+# Default: yes
+SET_BMC_INFO="yes"
diff --git a/ipmitool/include/ipmitool/helper.h b/ipmitool/include/ipmitool/helper.h
index 4b80058..b6ee7fa 100644
--- a/ipmitool/include/ipmitool/helper.h
+++ b/ipmitool/include/ipmitool/helper.h
@@ -99,6 +99,7 @@ void printbuf(const uint8_t * buf, int len, const char * desc);
uint8_t ipmi_csum(uint8_t * d, int s);
FILE * ipmi_open_file(const char * file, int rw);
void ipmi_start_daemon(struct ipmi_intf *intf);
+uint16_t ipmi_get_oem_id(struct ipmi_intf *intf);
#define ipmi_open_file_read(file) ipmi_open_file(file, 0)
#define ipmi_open_file_write(file) ipmi_open_file(file, 1)
diff --git a/ipmitool/include/ipmitool/ipmi.h b/ipmitool/include/ipmitool/ipmi.h
index e74c252..1fd3e2a 100644
--- a/ipmitool/include/ipmitool/ipmi.h
+++ b/ipmitool/include/ipmitool/ipmi.h
@@ -281,7 +281,8 @@ typedef enum IPMI_OEM {
IPMI_OEM_KONTRON = 15000,
IPMI_OEM_PPS = 16394,
IPMI_OEM_AMI = 20974,
- IPMI_OEM_NOKIA_SIEMENS_NETWORKS = 28458
+ IPMI_OEM_NOKIA_SIEMENS_NETWORKS = 28458,
+ IPMI_OEM_SUPERMICRO_47488 = 47488
} IPMI_OEM;
extern const struct valstr completion_code_vals[];
diff --git a/ipmitool/include/ipmitool/ipmi_fru.h b/ipmitool/include/ipmitool/ipmi_fru.h
index 6833dd4..4d255a8 100644
--- a/ipmitool/include/ipmitool/ipmi_fru.h
+++ b/ipmitool/include/ipmitool/ipmi_fru.h
@@ -63,6 +63,8 @@ enum {
struct fru_info {
uint16_t size;
uint8_t access:1;
+ uint8_t max_read_size;
+ uint8_t max_write_size;
};
#ifdef HAVE_PRAGMA_PACK
@@ -70,13 +72,16 @@ struct fru_info {
#endif
struct fru_header {
uint8_t version;
- struct {
- uint8_t internal;
- uint8_t chassis;
- uint8_t board;
- uint8_t product;
- uint8_t multi;
- } offset;
+ union {
+ struct {
+ uint8_t internal;
+ uint8_t chassis;
+ uint8_t board;
+ uint8_t product;
+ uint8_t multi;
+ } offset;
+ uint8_t offsets[5];
+ };
uint8_t pad;
uint8_t checksum;
}ATTRIBUTE_PACKING;
@@ -598,6 +603,20 @@ static const char * chassis_type_desc[] __attribute__((unused)) = {
"AdvancedTCA", "Blade", "Blade Enclosure"
};
+typedef struct ipmi_fru_bloc {
+ struct ipmi_fru_bloc * next;
+ uint16_t start;
+ uint16_t size;
+ uint8_t blocId[32];
+} t_ipmi_fru_bloc;
+
+static const char *section_id[4] = {
+ "Internal Use Section",
+ "Chassis Section",
+ "Board Section",
+ "Product Section"
+};
+
int ipmi_fru_main(struct ipmi_intf *intf, int argc, char **argv);
int ipmi_fru_print(struct ipmi_intf *intf, struct sdr_record_fru_locator *fru);
diff --git a/ipmitool/include/ipmitool/ipmi_fwum.h b/ipmitool/include/ipmitool/ipmi_fwum.h
index 712428f..c19a582 100644
--- a/ipmitool/include/ipmitool/ipmi_fwum.h
+++ b/ipmitool/include/ipmitool/ipmi_fwum.h
@@ -31,12 +31,213 @@
*/
#ifndef IPMI_KFWUM_H
-#define IPMI_KFWUM_H
+# define IPMI_KFWUM_H
#include <inttypes.h>
#include <ipmitool/ipmi.h>
+/* KFWUM Version */
+# define VER_MAJOR 1
+# define VER_MINOR 3
+/* Minimum size (IPMB/IOL/old protocol) */
+# define KFWUM_SMALL_BUFFER 32
+/* Maximum size on KCS interface */
+# define KFWUM_BIG_BUFFER 32
+# define MAX_BUFFER_SIZE 1024*16
+
+/* 3 address + 1 size + 1 checksum + 1 command */
+# define KFWUM_OLD_CMD_OVERHEAD 6
+/* 1 sequence + 1 size + 1 checksum + 1 command */
+# define KFWUM_NEW_CMD_OVERHEAD 4
+# define KFWUM_PAGE_SIZE 256
+
+# define FWUM_SAVE_FIRMWARE_NO_RESPONSE_LIMIT 6
+# define FWUM_MAX_UPLOAD_RETRY 6
+
+# define TRACE_LOG_CHUNK_COUNT 7
+# define TRACE_LOG_CHUNK_SIZE 7
+# define TRACE_LOG_ATT_COUNT 3
+
+# define IN_FIRMWARE_INFO_OFFSET_LOCATION 0x5a0
+# define IN_FIRMWARE_INFO_SIZE 20
+# define IN_FIRMWARE_INFO_OFFSET_FILE_SIZE 0
+# define IN_FIRMWARE_INFO_OFFSET_CHECKSUM 4
+# define IN_FIRMWARE_INFO_OFFSET_BOARD_ID 6
+# define IN_FIRMWARE_INFO_OFFSET_DEVICE_ID 8
+# define IN_FIRMWARE_INFO_OFFSET_TABLE_VERSION 9
+# define IN_FIRMWARE_INFO_OFFSET_IMPLEMENT_REV 10
+# define IN_FIRMWARE_INFO_OFFSET_VER_MAJOROR 11
+# define IN_FIRMWARE_INFO_OFFSET_VER_MINORSUB 12
+# define IN_FIRMWARE_INFO_OFFSET_SDR_REV 13
+# define IN_FIRMWARE_INFO_OFFSET_IANA0 14
+# define IN_FIRMWARE_INFO_OFFSET_IANA1 15
+# define IN_FIRMWARE_INFO_OFFSET_IANA2 16
+
+# define KWUM_GET_BYTE_AT_OFFSET(pBuffer,os) pBuffer[os]
int ipmi_fwum_main(struct ipmi_intf *, int, char **);
+typedef enum eKFWUM_BoardList
+{
+ KFWUM_BOARD_KONTRON_UNKNOWN = 0,
+ KFWUM_BOARD_KONTRON_5002 = 5002,
+} tKFWUM_BoardList;
+
+typedef struct sKFWUM_BoardInfo
+{
+ tKFWUM_BoardList boardId;
+ IPMI_OEM iana;
+} tKFWUM_BoardInfo;
+
+typedef enum eKFWUM_DownloadType
+{
+ KFWUM_DOWNLOAD_TYPE_ADDRESS = 0,
+ KFWUM_DOWNLOAD_TYPE_SEQUENCE,
+} tKFWUM_DownloadType;
+
+typedef enum eKFWUM_DownloadBuffferType
+{
+ KFWUM_SMALL_BUFFER_TYPE = 0,
+ KFUMW_BIG_BUFFER_TYPE
+} tKFWUM_DownloadBuffferType;
+
+typedef struct sKFWUM_InFirmwareInfo
+{
+ unsigned long fileSize;
+ unsigned short checksum;
+ unsigned short sumToRemoveFromChecksum;
+ /* Since the checksum is added in the bin
+ * after the checksum is calculated, we
+ * need to remove the each byte value. This
+ * byte will contain the addition of both bytes
+ */
+ tKFWUM_BoardList boardId;
+ unsigned char deviceId;
+ unsigned char tableVers;
+ unsigned char implRev;
+ unsigned char versMajor;
+ unsigned char versMinor;
+ unsigned char versSubMinor;
+ unsigned char sdrRev;
+ IPMI_OEM iana;
+} tKFWUM_InFirmwareInfo;
+
+typedef struct sKFWUM_SaveFirmwareInfo
+{
+ tKFWUM_DownloadType downloadType;
+ unsigned char bufferSize;
+ unsigned char overheadSize;
+} tKFWUM_SaveFirmwareInfo;
+
+/* COMMANDS */
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+# endif
+struct KfwumGetInfoResp {
+ unsigned char protocolRevision;
+ unsigned char controllerDeviceId;
+ struct {
+ unsigned char mode:1;
+ unsigned char seqAdd:1;
+ unsigned char res : 6;
+ } byte;
+ unsigned char firmRev1;
+ unsigned char firmRev2;
+ unsigned char numBank;
+} ATTRIBUTE_PACKING;
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+# endif
+
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+# endif
+struct KfwumGetStatusResp {
+ unsigned char bankState;
+ unsigned char firmLengthLSB;
+ unsigned char firmLengthMid;
+ unsigned char firmLengthMSB;
+ unsigned char firmRev1;
+ unsigned char firmRev2;
+ unsigned char firmRev3;
+} ATTRIBUTE_PACKING;
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+# endif
+
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+# endif
+struct KfwumManualRollbackReq {
+ unsigned char type;
+} ATTRIBUTE_PACKING;
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+# endif
+
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+# endif
+struct KfwumStartFirmwareDownloadReq {
+ unsigned char lengthLSB;
+ unsigned char lengthMid;
+ unsigned char lengthMSB;
+ unsigned char paddingLSB;
+ unsigned char paddingMSB;
+ unsigned char useSequence;
+} ATTRIBUTE_PACKING;
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+# endif
+
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+# endif
+struct KfwumStartFirmwareDownloadResp {
+ unsigned char bank;
+} ATTRIBUTE_PACKING;
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+# endif
+
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+# endif
+struct KfwumSaveFirmwareAddressReq
+{
+ unsigned char addressLSB;
+ unsigned char addressMid;
+ unsigned char addressMSB;
+ unsigned char numBytes;
+ unsigned char txBuf[KFWUM_SMALL_BUFFER-KFWUM_OLD_CMD_OVERHEAD];
+} ATTRIBUTE_PACKING;
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+# endif
+
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+# endif
+struct KfwumSaveFirmwareSequenceReq
+{
+ unsigned char sequenceNumber;
+ unsigned char txBuf[KFWUM_BIG_BUFFER];
+} ATTRIBUTE_PACKING;
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+# endif
+
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+# endif
+struct KfwumFinishFirmwareDownloadReq {
+ unsigned char versionMaj;
+ unsigned char versionMinSub;
+ unsigned char versionSdr;
+ unsigned char reserved;
+} ATTRIBUTE_PACKING;
+# ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+# endif
+
#endif /* IPMI_KFWUM_H */
diff --git a/ipmitool/include/ipmitool/ipmi_hpmfwupg.h b/ipmitool/include/ipmitool/ipmi_hpmfwupg.h
index c464ad4..305091e 100644
--- a/ipmitool/include/ipmitool/ipmi_hpmfwupg.h
+++ b/ipmitool/include/ipmitool/ipmi_hpmfwupg.h
@@ -38,4 +38,771 @@
int ipmi_hpmfwupg_main(struct ipmi_intf *, int, char **);
+/* Agent version */
+#define HPMFWUPG_VERSION_MAJOR 1
+#define HPMFWUPG_VERSION_MINOR 0
+#define HPMFWUPG_VERSION_SUBMINOR 9
+
+/* HPM.1 FIRMWARE UPGRADE COMMANDS (part of PICMG) */
+#define HPMFWUPG_GET_TARGET_UPG_CAPABILITIES 0x2E
+#define HPMFWUPG_GET_COMPONENT_PROPERTIES 0x2F
+#define HPMFWUPG_ABORT_UPGRADE 0x30
+#define HPMFWUPG_INITIATE_UPGRADE_ACTION 0x31
+#define HPMFWUPG_UPLOAD_FIRMWARE_BLOCK 0x32
+#define HPMFWUPG_FINISH_FIRMWARE_UPLOAD 0x33
+#define HPMFWUPG_GET_UPGRADE_STATUS 0x34
+#define HPMFWUPG_ACTIVATE_FIRMWARE 0x35
+#define HPMFWUPG_QUERY_SELFTEST_RESULT 0x36
+#define HPMFWUPG_QUERY_ROLLBACK_STATUS 0x37
+#define HPMFWUPG_MANUAL_FIRMWARE_ROLLBACK 0x38
+
+/* HPM.1 SPECIFIC COMPLETION CODES */
+#define HPMFWUPG_ROLLBACK_COMPLETED 0x00
+#define HPMFWUPG_COMMAND_IN_PROGRESS 0x80
+#define HPMFWUPG_NOT_SUPPORTED 0x81
+#define HPMFWUPG_SIZE_MISMATCH 0x81
+#define HPMFWUPG_ROLLBACK_FAILURE 0x81
+#define HPMFWUPG_INV_COMP_MASK 0x81
+#define HPMFWUPG__ABORT_FAILURE 0x81
+#define HPMFWUPG_INV_COMP_ID 0x82
+#define HPMFWUPG_INT_CHECKSUM_ERROR 0x82
+#define HPMFWUPG_INV_UPLOAD_MODE 0x82
+#define HPMFWUPG_ROLLBACK_OVERRIDE 0x82
+#define HPMFWUPG_INV_COMP_PROP 0x83
+#define HPMFWUPG_FW_MISMATCH 0x83
+#define HPMFWUPG_ROLLBACK_DENIED 0x83
+
+/*
+ * This error code is used as a temporary PATCH to
+ * the latest Open ipmi driver. This PATCH
+ * will be removed once a new Open IPMI driver is released.
+ * (Buggy version = 39)
+ */
+#define ENABLE_OPENIPMI_V39_PATCH
+
+#ifdef ENABLE_OPENIPMI_V39_PATCH
+# define RETRY_COUNT_MAX 3
+static int errorCount;
+# define HPMFWUPG_IS_RETRYABLE(error) \
+ ((((error==0x83)||(error==0x82)||(error==0x80)) && (errorCount++<RETRY_COUNT_MAX))?TRUE:FALSE)
+#else
+# define HPMFWUPG_IS_RETRYABLE(error) FALSE
+#endif
+
+/* HPM FIRMWARE UPGRADE GENERAL DEFINITIONS */
+#define HPMFWUPG_PICMG_IDENTIFIER 0
+#define HPMFWUPG_VERSION_SIZE 6
+#define HPMFWUPG_DESC_STRING_LENGTH 12
+#define HPMFWUPG_DEFAULT_INACCESS_TIMEOUT 60 /* sec */
+#define HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT 60 /* sec */
+#define HPMFWUPG_MD5_SIGNATURE_LENGTH 16
+
+/* Component IDs */
+typedef enum eHpmfwupgComponentId {
+ HPMFWUPG_COMPONENT_ID_0 = 0,
+ HPMFWUPG_COMPONENT_ID_1,
+ HPMFWUPG_COMPONENT_ID_2,
+ HPMFWUPG_COMPONENT_ID_3,
+ HPMFWUPG_COMPONENT_ID_4,
+ HPMFWUPG_COMPONENT_ID_5,
+ HPMFWUPG_COMPONENT_ID_6,
+ HPMFWUPG_COMPONENT_ID_7,
+ HPMFWUPG_COMPONENT_ID_MAX
+} tHpmfwupgComponentId;
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgComponentBitMask {
+ union {
+ unsigned char byte;
+ struct {
+#ifdef WORDS_BIGENDIAN
+ unsigned char component7 : 1;
+ unsigned char component6 : 1;
+ unsigned char component5 : 1;
+ unsigned char component4 : 1;
+ unsigned char component3 : 1;
+ unsigned char component2 : 1;
+ unsigned char component1 : 1;
+ unsigned char component0 : 1;
+#else
+ unsigned char component0 : 1;
+ unsigned char component1 : 1;
+ unsigned char component2 : 1;
+ unsigned char component3 : 1;
+ unsigned char component4 : 1;
+ unsigned char component5 : 1;
+ unsigned char component6 : 1;
+ unsigned char component7 : 1;
+#endif
+ } ATTRIBUTE_PACKING bitField;
+ } ATTRIBUTE_PACKING ComponentBits;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+
+static const int HPMFWUPG_SUCCESS = 0;
+static const int HPMFWUPG_ERROR = -1;
+/* Upload firmware specific error codes */
+static const int HPMFWUPG_UPLOAD_BLOCK_LENGTH = 1;
+static const int HPMFWUPG_UPLOAD_RETRY = 2;
+
+
+/* TARGET UPGRADE CAPABILITIES DEFINITIONS */
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetTargetUpgCapabilitiesReq {
+ unsigned char picmgId;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetTargetUpgCapabilitiesResp {
+ unsigned char picmgId;
+ unsigned char hpmVersion;
+ union {
+ unsigned char byte;
+ struct {
+#if WORDS_BIGENDIAN
+ unsigned char fwUpgUndesirable : 1;
+ unsigned char autRollbackOverride : 1;
+ unsigned char ipmcDegradedDurinUpg: 1;
+ unsigned char deferActivation : 1;
+ unsigned char servAffectDuringUpg : 1;
+ unsigned char manualRollback : 1;
+ unsigned char autRollback : 1;
+ unsigned char ipmcSelftestCap : 1;
+#else
+ unsigned char ipmcSelftestCap : 1;
+ unsigned char autRollback : 1;
+ unsigned char manualRollback : 1;
+ unsigned char servAffectDuringUpg : 1;
+ unsigned char deferActivation : 1;
+ unsigned char ipmcDegradedDurinUpg: 1;
+ unsigned char autRollbackOverride : 1;
+ unsigned char fwUpgUndesirable : 1;
+#endif
+ } ATTRIBUTE_PACKING bitField;
+ } ATTRIBUTE_PACKING GlobalCapabilities;
+ unsigned char upgradeTimeout;
+ unsigned char selftestTimeout;
+ unsigned char rollbackTimeout;
+ unsigned char inaccessTimeout;
+ struct HpmfwupgComponentBitMask componentsPresent;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetTargetUpgCapabilitiesCtx {
+ struct HpmfwupgGetTargetUpgCapabilitiesReq req;
+ struct HpmfwupgGetTargetUpgCapabilitiesResp resp;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+/* COMPONENT PROPERTIES DEFINITIONS */
+typedef enum eHpmfwupgCompPropertiesSelect {
+ HPMFWUPG_COMP_GEN_PROPERTIES = 0,
+ HPMFWUPG_COMP_CURRENT_VERSION,
+ HPMFWUPG_COMP_DESCRIPTION_STRING,
+ HPMFWUPG_COMP_ROLLBACK_FIRMWARE_VERSION,
+ HPMFWUPG_COMP_DEFERRED_FIRMWARE_VERSION,
+ HPMFWUPG_COMP_RESERVED,
+ HPMFWUPG_COMP_OEM_PROPERTIES = 192
+} tHpmfwupgCompPropertiesSelect;
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetComponentPropertiesReq {
+ unsigned char picmgId;
+ unsigned char componentId;
+ unsigned char selector;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetGeneralPropResp {
+ unsigned char picmgId;
+ union {
+ unsigned char byte;
+ struct {
+#if WORDS_BIGENDIAN
+ unsigned char reserved : 2;
+ unsigned char payloadColdReset : 1;
+ unsigned char deferredActivation : 1;
+ unsigned char comparisonSupport : 1;
+ unsigned char preparationSupport : 1;
+ unsigned char rollbackBackup : 2;
+#else
+ unsigned char rollbackBackup : 2;
+ unsigned char preparationSupport : 1;
+ unsigned char comparisonSupport : 1;
+ unsigned char deferredActivation : 1;
+ unsigned char payloadColdReset : 1;
+ unsigned char reserved : 2;
+#endif
+ } ATTRIBUTE_PACKING bitfield;
+ } ATTRIBUTE_PACKING GeneralCompProperties;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetCurrentVersionResp {
+ unsigned char picmgId;
+ unsigned char currentVersion[HPMFWUPG_VERSION_SIZE];
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetDescStringResp {
+ unsigned char picmgId;
+ char descString[HPMFWUPG_DESC_STRING_LENGTH];
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetRollbackFwVersionResp {
+ unsigned char picmgId;
+ unsigned char rollbackFwVersion[HPMFWUPG_VERSION_SIZE];
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetDeferredFwVersionResp {
+ unsigned char picmgId;
+ unsigned char deferredFwVersion[HPMFWUPG_VERSION_SIZE];
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+/* GetComponentProperties - OEM properties (192) */
+#define HPMFWUPG_OEM_LENGTH 4
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetOemProperties {
+ unsigned char picmgId;
+ unsigned char oemRspData[HPMFWUPG_OEM_LENGTH];
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetComponentPropertiesResp {
+ union {
+ struct HpmfwupgGetGeneralPropResp generalPropResp;
+ struct HpmfwupgGetCurrentVersionResp currentVersionResp;
+ struct HpmfwupgGetDescStringResp descStringResp;
+ struct HpmfwupgGetRollbackFwVersionResp rollbackFwVersionResp;
+ struct HpmfwupgGetDeferredFwVersionResp deferredFwVersionResp;
+ struct HpmfwupgGetOemProperties oemProperties;
+ } ATTRIBUTE_PACKING Response;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetComponentPropertiesCtx {
+ struct HpmfwupgGetComponentPropertiesReq req;
+ struct HpmfwupgGetComponentPropertiesResp resp;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+/* ABORT UPGRADE DEFINITIONS */
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgAbortUpgradeReq {
+ unsigned char picmgId;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgAbortUpgradeResp {
+ unsigned char picmgId;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgAbortUpgradeCtx {
+ struct HpmfwupgAbortUpgradeReq req;
+ struct HpmfwupgAbortUpgradeResp resp;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+/* UPGRADE ACTIONS DEFINITIONS */
+typedef enum eHpmfwupgUpgradeAction {
+ HPMFWUPG_UPGRADE_ACTION_BACKUP = 0,
+ HPMFWUPG_UPGRADE_ACTION_PREPARE,
+ HPMFWUPG_UPGRADE_ACTION_UPGRADE,
+ HPMFWUPG_UPGRADE_ACTION_COMPARE,
+ HPMFWUPG_UPGRADE_ACTION_INVALID = 0xff
+} tHpmfwupgUpgradeAction;
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgInitiateUpgradeActionReq {
+ unsigned char picmgId;
+ struct HpmfwupgComponentBitMask componentsMask;
+ unsigned char upgradeAction;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgInitiateUpgradeActionResp {
+ unsigned char picmgId;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgInitiateUpgradeActionCtx {
+ struct HpmfwupgInitiateUpgradeActionReq req;
+ struct HpmfwupgInitiateUpgradeActionResp resp;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+/* UPLOAD FIRMWARE BLOCK DEFINITIONS */
+#define HPMFWUPG_SEND_DATA_COUNT_KCS 30
+#define HPMFWUPG_SEND_DATA_COUNT_LAN 25
+#define HPMFWUPG_SEND_DATA_COUNT_IPMB 26
+#define HPMFWUPG_SEND_DATA_COUNT_IPMBL 26
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgUploadFirmwareBlockReq {
+ unsigned char picmgId;
+ unsigned char blockNumber;
+ unsigned char data[0];
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgUploadFirmwareBlockResp {
+ unsigned char picmgId;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgUploadFirmwareBlockCtx {
+ struct HpmfwupgUploadFirmwareBlockReq * req;
+ struct HpmfwupgUploadFirmwareBlockResp resp;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+/* FINISH FIRMWARE UPLOAD DEFINITIONS */
+#define HPMFWUPG_IMAGE_SIZE_BYTE_COUNT 4
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgFinishFirmwareUploadReq {
+ unsigned char picmgId;
+ unsigned char componentId;
+ unsigned char imageLength[HPMFWUPG_IMAGE_SIZE_BYTE_COUNT];
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgFinishFirmwareUploadResp {
+ unsigned char picmgId;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgFinishFirmwareUploadCtx {
+ struct HpmfwupgFinishFirmwareUploadReq req;
+ struct HpmfwupgFinishFirmwareUploadResp resp;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+/* ACTIVATE FW DEFINITIONS */
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgActivateFirmwareReq {
+ unsigned char picmgId;
+ unsigned char rollback_override;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgActivateFirmwareResp {
+ unsigned char picmgId;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgActivateFirmwareCtx {
+ struct HpmfwupgActivateFirmwareReq req;
+ struct HpmfwupgActivateFirmwareResp resp;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+/* GET UPGRADE STATUS DEFINITIONS */
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetUpgradeStatusReq {
+ unsigned char picmgId;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetUpgradeStatusResp {
+ unsigned char picmgId;
+ unsigned char cmdInProcess;
+ unsigned char lastCmdCompCode;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgGetUpgradeStatusCtx {
+ struct HpmfwupgGetUpgradeStatusReq req;
+ struct HpmfwupgGetUpgradeStatusResp resp;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+/* MANUAL FW ROLLBACK DEFINITIONS */
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgManualFirmwareRollbackReq {
+ unsigned char picmgId;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgManualFirmwareRollbackResp {
+ unsigned char picmgId;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+struct HpmfwupgManualFirmwareRollbackCtx {
+ struct HpmfwupgManualFirmwareRollbackReq req;
+ struct HpmfwupgManualFirmwareRollbackResp resp;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+/* QUERY ROLLBACK STATUS DEFINITIONS */
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgQueryRollbackStatusReq {
+ unsigned char picmgId;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgQueryRollbackStatusResp {
+ unsigned char picmgId;
+ struct HpmfwupgComponentBitMask rollbackComp;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgQueryRollbackStatusCtx {
+ struct HpmfwupgQueryRollbackStatusReq req;
+ struct HpmfwupgQueryRollbackStatusResp resp;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+/* QUERY SELF TEST RESULT DEFINITIONS */
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgQuerySelftestResultReq {
+ unsigned char picmgId;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgQuerySelftestResultResp {
+ unsigned char picmgId;
+ unsigned char result1;
+ unsigned char result2;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgQuerySelftestResultCtx {
+ struct HpmfwupgQuerySelftestResultReq req;
+ struct HpmfwupgQuerySelftestResultResp resp;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+/* HPM.1 IMAGE DEFINITIONS */
+#define HPMFWUPG_HEADER_SIGNATURE_LENGTH 8
+#define HPMFWUPG_MANUFATURER_ID_LENGTH 3
+#define HPMFWUPG_PRODUCT_ID_LENGTH 2
+#define HPMFWUPG_TIME_LENGTH 4
+#define HPMFWUPG_TIMEOUT_LENGTH 1
+#define HPMFWUPG_COMP_REVISION_LENGTH 2
+#define HPMFWUPG_FIRM_REVISION_LENGTH 6
+#define HPMFWUPG_IMAGE_HEADER_VERSION 0
+#define HPMFWUPG_IMAGE_SIGNATURE "PICMGFWU"
+
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(1)
+#endif
+struct HpmfwupgImageHeader {
+ char signature[HPMFWUPG_HEADER_SIGNATURE_LENGTH];
+ unsigned char formatVersion;
+ unsigned char deviceId;
+ unsigned char manId[HPMFWUPG_MANUFATURER_ID_LENGTH];
+ unsigned char prodId[HPMFWUPG_PRODUCT_ID_LENGTH];
+ unsigned char time[HPMFWUPG_TIME_LENGTH];
+ union {
+ struct {
+#if WORDS_BIGENDIAN
+ unsigned char imageSelfTest : 1;
+ unsigned char autRollback : 1;
+ unsigned char manRollback : 1;
+ unsigned char servAffected : 1;
+ unsigned char reserved : 4;
+#else
+ unsigned char reserved : 4;
+ unsigned char servAffected : 1;
+ unsigned char manRollback : 1;
+ unsigned char autRollback : 1;
+ unsigned char imageSelfTest : 1;
+#endif
+ } ATTRIBUTE_PACKING bitField;
+ unsigned char byte;
+ }ATTRIBUTE_PACKING imageCapabilities;
+ struct HpmfwupgComponentBitMask components;
+ unsigned char selfTestTimeout;
+ unsigned char rollbackTimeout;
+ unsigned char inaccessTimeout;
+ unsigned char compRevision[HPMFWUPG_COMP_REVISION_LENGTH];
+ unsigned char firmRevision[HPMFWUPG_FIRM_REVISION_LENGTH];
+ unsigned short oemDataLength;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#define HPMFWUPG_DESCRIPTION_LENGTH 21
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgActionRecord {
+ unsigned char actionType;
+ struct HpmfwupgComponentBitMask components;
+ unsigned char checksum;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#define HPMFWUPG_FIRMWARE_SIZE_LENGTH 4
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgFirmwareImage {
+ unsigned char version[HPMFWUPG_FIRM_REVISION_LENGTH];
+ char desc[HPMFWUPG_DESCRIPTION_LENGTH];
+ unsigned char length[HPMFWUPG_FIRMWARE_SIZE_LENGTH];
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(1)
+#endif
+struct HpmfwupgUpgradeCtx {
+ struct HpmfwupgComponentBitMask compUpdateMask;
+ unsigned int imageSize;
+ unsigned char* pImageData;
+ unsigned char componentId;
+ struct HpmfwupgGetTargetUpgCapabilitiesResp targetCap;
+ struct HpmfwupgGetGeneralPropResp genCompProp[HPMFWUPG_COMPONENT_ID_MAX];
+ struct ipm_devid_rsp devId;
+} ATTRIBUTE_PACKING;
+#ifdef HAVE_PRAGMA_PACK
+# pragma pack(0)
+#endif
+
+typedef enum eHpmfwupgActionType {
+ HPMFWUPG_ACTION_BACKUP_COMPONENTS = 0,
+ HPMFWUPG_ACTION_PREPARE_COMPONENTS,
+ HPMFWUPG_ACTION_UPLOAD_FIRMWARE,
+ HPMFWUPG_ACTION_RESERVED = 0xFF
+} tHpmfwupgActionType;
+
+/* FUNCTIONS PROTOTYPES */
+#define HPMFWUPG_MAJORMINOR_VERSION_SIZE 2
+
+/* Options added for user to check the version and to view both the FILE and
+ * TARGET Version
+ */
+#define VIEW_MODE 0x01
+#define DEBUG_MODE 0x02
+#define FORCE_MODE 0x04
+#define COMPARE_MODE 0x08
+
+typedef struct _VERSIONINFO {
+ unsigned char componentId;
+ unsigned char targetMajor;
+ unsigned char targetMinor;
+ unsigned char targetAux[4];
+ unsigned char rollbackMajor;
+ unsigned char rollbackMinor;
+ unsigned char rollbackAux[4];
+ unsigned char deferredMajor;
+ unsigned char deferredMinor;
+ unsigned char deferredAux[4];
+ unsigned char imageMajor;
+ unsigned char imageMinor;
+ unsigned char imageAux[4];
+ unsigned char coldResetRequired;
+ unsigned char rollbackSupported;
+ char descString[HPMFWUPG_DESC_STRING_LENGTH + 1];
+}VERSIONINFO, *PVERSIONINFO;
+
+VERSIONINFO gVersionInfo[HPMFWUPG_COMPONENT_ID_MAX];
+
+#define TARGET_VER (0x01)
+#define ROLLBACK_VER (0x02)
+#define IMAGE_VER (0x04)
+
#endif /* IPMI_KFWUM_H */
diff --git a/ipmitool/include/ipmitool/ipmi_intf.h b/ipmitool/include/ipmitool/ipmi_intf.h
index 7ab2b13..774c6b2 100644
--- a/ipmitool/include/ipmitool/ipmi_intf.h
+++ b/ipmitool/include/ipmitool/ipmi_intf.h
@@ -89,8 +89,9 @@ struct ipmi_session {
uint32_t out_seq;
uint32_t timeout;
- struct sockaddr_in addr;
+ struct sockaddr_storage addr;
socklen_t addrlen;
+ int ai_family; /* Protocol family for socket. */
/*
* This struct holds state data specific to IPMI v2 / RMCP+ sessions
@@ -211,4 +212,7 @@ void ipmi_intf_session_set_timeout(struct ipmi_intf * intf, uint32_t timeout);
void ipmi_intf_session_set_retry(struct ipmi_intf * intf, int retry);
void ipmi_cleanup(struct ipmi_intf * intf);
+#if defined(IPMI_INTF_LAN) || defined (IPMI_INTF_LANPLUS)
+int ipmi_intf_socket_connect(struct ipmi_intf * intf);
+#endif
#endif /* IPMI_INTF_H */
diff --git a/ipmitool/include/ipmitool/ipmi_sel.h b/ipmitool/include/ipmitool/ipmi_sel.h
index 3077eb9..a125f85 100644
--- a/ipmitool/include/ipmitool/ipmi_sel.h
+++ b/ipmitool/include/ipmitool/ipmi_sel.h
@@ -107,6 +107,7 @@ struct standard_spec_sel_rec{
#define SENSOR_TYPE_OEM_NFATAL_ERROR 0xC2
#define SENSOR_TYPE_OEM_FATAL_ERROR 0xC3
#define SENSOR_TYPE_TXT_CMD_ERROR 0x20
+#define SENSOR_TYPE_SUPERMICRO_OEM 0xD0
/* End of Macro for DELL Specific */
#define SEL_OEM_TS_DATA_LEN 6
#define SEL_OEM_NOTS_DATA_LEN 13
@@ -676,6 +677,56 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x00, 0x00, 0x00, 0x00, NULL, NULL },
};
+static uint16_t supermicro_x9dal[] = {
+ 0x0635
+};
+
+static uint16_t supermicro_x9db[] = {
+ 0x0733, 0x0722, 0x0703, 0x0721, 0x0716, 0x0637
+};
+
+static uint16_t supermicro_x9sb[] = {
+ 0x0651
+};
+
+static uint16_t supermicro_x9[] = {
+ 0x0635, 0x0733, 0x0722, 0x0703, 0x0721, 0x0716, 0x0637, 0x0651
+};
+
+static uint16_t supermicro_b8[] = {
+ 0x000A, 0x061c, 0x0620, 0x0101, 0x061f, 0x0612, 0x061e
+};
+
+static uint16_t supermicro_h8[] = {
+ 0xa111, 0x0408, 0x0811, 0x1411, 0x0911, 0x1211, 0x1011, 0xcd11, 0x1111, 0xbe11, 0xce11, 0xbd11,
+ 0xbc11, 0xa911, 0xaa11, 0xbd11, 0xcb11, 0xad11, 0xa811, 0xac11, 0xaf11, 0xa511, 0xa011, 0x1611,
+ 0x2511, 0xbf11, 0x1511, 0x2211, 0x2411, 0x1911, 0xab11, 0xd011, 0xae11, 0xca11, 0x0409, 0xa211,
+ 0xa311, 0x1311, 0xba11, 0xa711, 0xd111, 0x1711, 0xcf11, 0x2011, 0x1811
+};
+
+static uint16_t supermicro_p8[] = {
+ 0x6480, 0x7380, 0x6280, 0x7480, 0x5980
+};
+
+static uint16_t supermicro_x8[] = {
+ 0xa880, 0x0403, 0x0100, 0x0601, 0x0001, 0x0404, 0x0606, 0x0608, 0x0632, 0x0400, 0x0401, 0x0006,
+ 0x040a, 0xf280, 0x060f, 0x0609, 0x0008, 0x0613, 0x061b, 0x0007, 0x0600, 0x060c, 0x060d, 0x0614,
+ 0x060c, 0x0003, 0x040b, 0x0621, 0x0610, 0x0638, 0xf380, 0x060b, 0x040d, 0x0605, 0x062d, 0x060e,
+ 0x061a, 0xf580, 0x062e, 0x0009
+};
+
+static uint16_t supermicro_X8[] = {
+ 0x000A, 0x061c, 0x0620, 0x0101, 0x061f, 0x0612, 0x061e, 0xa111, 0x0408, 0x0811, 0x1411, 0x0911,
+ 0x1211, 0x1011, 0xcd11, 0x1111, 0xbe11, 0xce11, 0xbd11, 0xbc11, 0xa911, 0xaa11, 0xbd11, 0xcb11,
+ 0xad11, 0xa811, 0xac11, 0xaf11, 0xa511, 0xa011, 0x1611, 0x2511, 0xbf11, 0x1511, 0x2211, 0x2411,
+ 0x1911, 0xab11, 0xd011, 0xae11, 0xca11, 0x0409, 0xa211, 0xa311, 0x1311, 0xba11, 0xa711, 0xd111,
+ 0x1711, 0xcf11, 0x2011, 0x1811, 0x6480, 0x7380, 0x6280, 0x7480, 0x5980, 0xa880, 0x0403, 0x0100,
+ 0x0601, 0x0001, 0x0404, 0x0606, 0x0608, 0x0632, 0x0400, 0x0401, 0x0006, 0x040a, 0xf280, 0x060f,
+ 0x0609, 0x0008, 0x0613, 0x061b, 0x0007, 0x0600, 0x060c, 0x060d, 0x0614, 0x060c, 0x0003, 0x040b,
+ 0x0621, 0x0610, 0x0638, 0xf380, 0x060b, 0x040d, 0x0605, 0x062d, 0x060e, 0x061a, 0xf580, 0x062e,
+ 0x0009
+};
+
int ipmi_sel_main(struct ipmi_intf *, int, char **);
void ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt);
void ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_record * evt);
diff --git a/ipmitool/lib/helper.c b/ipmitool/lib/helper.c
index f795a34..4b903b0 100644
--- a/ipmitool/lib/helper.c
+++ b/ipmitool/lib/helper.c
@@ -44,6 +44,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#include <assert.h>
#if HAVE_CONFIG_H
# include <config.h>
@@ -663,9 +664,10 @@ ipmi_start_daemon(struct ipmi_intf *intf)
close(fd);
}
- open("/dev/null", O_RDWR);
- dup(0);
- dup(0);
+ fd = open("/dev/null", O_RDWR);
+ assert(0 == fd);
+ dup(fd);
+ dup(fd);
}
/* is_fru_id - wrapper for str-2-int FRU ID conversion. Message is printed
@@ -756,3 +758,32 @@ is_ipmi_user_id(const char *argv_ptr, uint8_t *ipmi_uid_ptr)
IPMI_UID_MIN, IPMI_UID_MAX);
return (-1);
}
+
+uint16_t
+ipmi_get_oem_id(struct ipmi_intf *intf)
+{
+ /* Execute a Get Board ID command to determine the board */
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ uint16_t oem_id;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_TSOL;
+ req.msg.cmd = 0x21;
+ req.msg.data_len = 0;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Get Board ID command failed");
+ return 0;
+ }
+ if (rsp->ccode > 0) {
+ lprintf(LOG_ERR, "Get Board ID command failed: %#x %s",
+ rsp->ccode, val2str(rsp->ccode, completion_code_vals));
+ return 0;
+ }
+ oem_id = rsp->data[0] | (rsp->data[1] << 8);
+ lprintf(LOG_DEBUG,"Board ID: %x", oem_id);
+
+ return oem_id;
+}
diff --git a/ipmitool/lib/ipmi_dcmi.c b/ipmitool/lib/ipmi_dcmi.c
index ff9646c..0cce769 100755
--- a/ipmitool/lib/ipmi_dcmi.c
+++ b/ipmitool/lib/ipmi_dcmi.c
@@ -481,44 +481,14 @@ ipmi_dcmi_prnt_oobDiscover(struct ipmi_intf * intf)
intf->abort = 1;
intf->session->sol_data.sequence_number = 1;
- /* open port to BMC */
- memset(&s->addr, 0, sizeof(struct sockaddr_in));
- s->addr.sin_family = AF_INET;
- s->addr.sin_port = htons(s->port);
-
- rc = inet_pton(AF_INET, (const char *)s->hostname, &s->addr.sin_addr);
- if (rc <= 0) {
- struct hostent *host = gethostbyname((const char *)s->hostname);
- if (host == NULL) {
- lprintf(LOG_ERR, "Address lookup for %s failed",
- s->hostname);
- return -1;
- }
- if (host->h_addrtype != AF_INET) {
- lprintf(LOG_ERR,
- "Address lookup for %s failed. Got %s, expected IPv4 address.",
- s->hostname,
- (host->h_addrtype == AF_INET6) ? "IPv6" : "Unknown");
- return (-1);
- }
- s->addr.sin_family = host->h_addrtype;
- memcpy(&s->addr.sin_addr, host->h_addr, host->h_length);
- }
-
- lprintf(LOG_DEBUG, "IPMI LAN host %s port %d",
- s->hostname, ntohs(s->addr.sin_port));
-
- intf->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (intf->fd < 0) {
- lperror(LOG_ERR, "Socket failed");
+ if (ipmi_intf_socket_connect(intf) == -1) {
+ lprintf(LOG_ERR, "Could not open socket!");
return -1;
}
- /* connect to UDP socket so we get async errors */
- rc = connect(intf->fd, (struct sockaddr *)&s->addr,
- sizeof(struct sockaddr_in));
- if (rc < 0) {
- lperror(LOG_ERR, "Connect failed");
+ if (intf->fd < 0) {
+ lperror(LOG_ERR, "Connect to %s failed",
+ s->hostname);
intf->close(intf);
return -1;
}
diff --git a/ipmitool/lib/ipmi_delloem.c b/ipmitool/lib/ipmi_delloem.c
index b4e541a..e190cd4 100644
--- a/ipmitool/lib/ipmi_delloem.c
+++ b/ipmitool/lib/ipmi_delloem.c
@@ -3232,7 +3232,7 @@ ipmi_get_avgpower_consmpt_history(struct ipmi_intf * intf,
if (verbose > 1) {
rdata = (void *)pavgpower;
printf("Average power consumption history data"
- " :%x %x %x %x %x %x %x\n\n",
+ " :%x %x %x %x %x %x %x %x\n\n",
rdata[0], rdata[1], rdata[2], rdata[3],
rdata[4], rdata[5], rdata[6], rdata[7]);
}
@@ -3281,7 +3281,7 @@ ipmi_get_peakpower_consmpt_history(struct ipmi_intf * intf,
rdata = (void *)pstPeakpower;
printf("Peak power consmhistory Data : "
"%x %x %x %x %x %x %x %x %x %x\n "
- "%x %x %x %x %x %x %x %x %x %x %x %x %x\n\n",
+ "%x %x %x %x %x %x %x %x %x %x %x %x %x %x\n\n",
rdata[0], rdata[1], rdata[2], rdata[3],
rdata[4], rdata[5], rdata[6], rdata[7],
rdata[8], rdata[9], rdata[10], rdata[11],
@@ -3633,7 +3633,7 @@ ipmi_set_power_cap(struct ipmi_intf * intf, int unit, int val)
}
if (verbose > 1) {
rdata = (void *)&ipmipowercap;
- printf("power cap Data :%x %x %x %x %x %x %x %x %x %x ",
+ printf("power cap Data :%x %x %x %x %x %x %x %x %x %x %x ",
rdata[1], rdata[2], rdata[3],
rdata[4], rdata[5], rdata[6], rdata[7],
rdata[8], rdata[9], rdata[10],rdata[11]);
diff --git a/ipmitool/lib/ipmi_ekanalyzer.c b/ipmitool/lib/ipmi_ekanalyzer.c
index f2c9c82..2ac1012 100644
--- a/ipmitool/lib/ipmi_ekanalyzer.c
+++ b/ipmitool/lib/ipmi_ekanalyzer.c
@@ -2745,6 +2745,8 @@ ipmi_ek_display_board_info_area(FILE * input_file, char * board_type,
ret = fread(data, size_board, 1, input_file);
if ((ret != 1) || ferror(input_file)) {
lprintf(LOG_ERR, "Invalid board type size!");
+ free(data);
+ data = NULL;
goto out;
}
printf("%s type: 0x%02x\n", board_type, len);
@@ -2761,6 +2763,7 @@ ipmi_ek_display_board_info_area(FILE * input_file, char * board_type,
}
printf("\n");
free(data);
+ data = NULL;
(*board_length) -= size_board;
goto out;
}
@@ -2807,6 +2810,7 @@ ipmi_ek_display_board_info_area(FILE * input_file, char * board_type,
}
printf("\n");
free(additional_data);
+ additional_data = NULL;
(*board_length) -= size_board;
}
else {
@@ -2843,7 +2847,7 @@ out:
static int
ipmi_ek_display_product_info_area(FILE * input_file, long offset)
{
- size_t file_offset = ftell(input_file);
+ size_t file_offset;
int ret = 0;
unsigned char ch_len = 0;
unsigned char data = 0;
@@ -2853,6 +2857,7 @@ ipmi_ek_display_product_info_area(FILE * input_file, long offset)
lprintf(LOG_ERR, "No file stream to read.");
return (-1);
}
+ file_offset = ftell(input_file);
printf("%s\n", EQUAL_LINE_LIMITER);
printf("Product Info Area\n");
printf("%s\n", EQUAL_LINE_LIMITER);
diff --git a/ipmitool/lib/ipmi_fru.c b/ipmitool/lib/ipmi_fru.c
index 6ba2ada..09d5abe 100644
--- a/ipmitool/lib/ipmi_fru.c
+++ b/ipmitool/lib/ipmi_fru.c
@@ -48,16 +48,6 @@
# include <config.h>
#endif
-/*
-* Apparently some systems have problems with FRU access greater than 16 bytes
-* at a time, even when using byte (not word) access. In order to ensure we
-* work with the widest variety of hardware request size is capped at 16 bytes.
-* Since this may result in slowdowns on some systems with lots of FRU data you
-* can undefine this to enable larger (up to 32 bytes at a time) access.
-*
-* TODO: make this a command line option
-*/
-#define LIMIT_ALL_REQUEST_SIZE 1
#define FRU_MULTIREC_CHUNK_SIZE (255 + sizeof(struct fru_multirec_header))
extern int verbose;
@@ -71,7 +61,7 @@ static int ipmi_fru_get_multirec_location_from_fru(struct ipmi_intf * intf, uint
static int ipmi_fru_get_multirec_from_file(char * pFileName, uint8_t * pBufArea,
uint32_t size, uint32_t offset);
static int ipmi_fru_get_multirec_size_from_file(char * pFileName, uint32_t * pSize, uint32_t * pOffset);
-int ipmi_fru_get_adjust_size_from_buffer(uint8_t * pBufArea, uint32_t *pSize);
+int ipmi_fru_get_adjust_size_from_buffer(uint8_t *pBufArea, uint32_t *pSize);
static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length);
static int ipmi_fru_set_field_string(struct ipmi_intf * intf, unsigned
@@ -87,6 +77,7 @@ fru_area_print_multirec_bloc(struct ipmi_intf * intf, struct fru_info * fru,
int
read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
uint32_t offset, uint32_t length, uint8_t *frubuf);
+void free_fru_bloc(t_ipmi_fru_bloc *bloc);
/* get_fru_area_str - Parse FRU area string from raw data
*
@@ -235,30 +226,17 @@ is_valid_filename(const char *input_filename)
* returns -1 on error
*/
#define FRU_NUM_BLOC_COMMON_HEADER 6
-typedef struct ipmi_fru_bloc
-{
- uint16_t start;
- uint16_t size;
- uint8_t blocId[32];
-}t_ipmi_fru_bloc;
-
t_ipmi_fru_bloc *
-build_fru_bloc(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
- /* OUT */uint16_t * ptr_number_bloc)
+build_fru_bloc(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id)
{
- t_ipmi_fru_bloc * p_bloc;
+ t_ipmi_fru_bloc * p_first, * p_bloc, * p_new;
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct fru_header header;
- uint8_t * fru_data = NULL;
+ struct fru_multirec_header rec_hdr;
uint8_t msg_data[4];
- uint16_t num_bloc;
- uint16_t bloc_count;
-
- (* ptr_number_bloc) = 0;
-
- /*memset(&fru, 0, sizeof(struct fru_info));*/
- memset(&header, 0, sizeof(struct fru_header));
+ uint32_t off;
+ uint16_t i;
/*
* get COMMON Header format
@@ -274,464 +252,322 @@ build_fru_bloc(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
req.msg.data = msg_data;
req.msg.data_len = 4;
-
rsp = intf->sendrecv(intf, &req);
+
if (rsp == NULL) {
- lprintf(LOG_ERR, " Device not present (No Response)\n");
+ lprintf(LOG_ERR, " Device not present (No Response)");
return NULL;
}
+
if (rsp->ccode > 0) {
- lprintf(LOG_ERR," Device not present (%s)\n",
- val2str(rsp->ccode, completion_code_vals));
+ lprintf(LOG_ERR," Device not present (%s)",
+ val2str(rsp->ccode, completion_code_vals));
return NULL;
}
- if (verbose > 1)
+ if (verbose > 1) {
printbuf(rsp->data, rsp->data_len, "FRU DATA");
+ }
memcpy(&header, rsp->data + 1, 8);
+ /* verify header checksum */
+ if (ipmi_csum((uint8_t *)&header, 8)) {
+ lprintf(LOG_ERR, " Bad header checksum");
+ return NULL;
+ }
+
if (header.version != 1) {
- lprintf(LOG_ERR, " Unknown FRU header version 0x%02x",
- header.version);
+ lprintf(LOG_ERR, " Unknown FRU header version 0x%02x", header.version);
return NULL;
}
/******************************************
- Count the number of bloc
+ Malloc and fill up the bloc contents
*******************************************/
// Common header
- num_bloc = 1;
- // Internal
- if( header.offset.internal )
- num_bloc ++;
- // Chassis
- if( header.offset.chassis )
- num_bloc ++;
- // Board
- if( header.offset.board )
- num_bloc ++;
- // Product
- if( header.offset.product )
- num_bloc ++;
-
- // Multi
- if( header.offset.multi )
- {
-
- uint32_t i;
- struct fru_multirec_header * h;
- uint32_t last_off, len;
-
- i = last_off = (header.offset.multi*8);
- //fru_len = 0;
-
- fru_data = malloc(fru->size + 1);
- if (fru_data == NULL) {
- lprintf(LOG_ERR, " Out of memory!");
- return NULL;
- }
-
- memset(fru_data, 0, fru->size + 1);
-
- do {
- h = (struct fru_multirec_header *) (fru_data + i);
-
- // read area in (at most) FRU_MULTIREC_CHUNK_SIZE bytes at a time
- if ((last_off < (i + sizeof(*h))) || (last_off < (i + h->len)))
- {
- len = fru->size - last_off;
- if (len > FRU_MULTIREC_CHUNK_SIZE)
- len = FRU_MULTIREC_CHUNK_SIZE;
+ p_first = malloc(sizeof(struct ipmi_fru_bloc));
+ if (!p_first) {
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
+ return NULL;
+ }
- if (read_fru_area(intf, fru, id, last_off, len, fru_data) < 0)
- break;
+ p_bloc = p_first;
+ p_bloc->next = NULL;
+ p_bloc->start= 0;
+ p_bloc->size = fru->size;
+ strcpy((char *)p_bloc->blocId, "Common Header Section");
- last_off += len;
+ for (i = 0; i < 4; i++) {
+ if (header.offsets[i]) {
+ p_new = malloc(sizeof(struct ipmi_fru_bloc));
+ if (!p_new) {
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
+ free_fru_bloc(p_first);
+ return NULL;
}
- num_bloc++;
- //printf("Bloc Numb : %i\n", counter);
- //printf("Bloc Start: %i\n", i);
- //printf("Bloc Size : %i\n", h->len);
- //printf("\n");
- i += h->len + sizeof (struct fru_multirec_header);
- } while (!(h->format & 0x80) && ( last_off < fru->size));
+ p_new->next = NULL;
+ p_new->start = header.offsets[i] * 8;
+ p_new->size = fru->size - p_new->start;
- lprintf(LOG_DEBUG ,"Multi-Record area ends at: %i (%xh)",i,i);
+ strncpy((char *)p_new->blocId, section_id[i], sizeof(p_new->blocId));
+ /* Make sure string is null terminated */
+ p_new->blocId[sizeof(p_new->blocId)-1] = 0;
- if(fru->size > i)
- {
- // Bloc for remaining space
- num_bloc ++;
+ p_bloc->next = p_new;
+ p_bloc->size = p_new->start - p_bloc->start;
+ p_bloc = p_new;
}
}
- else
- {
- /* Since there is no multi-rec area and no end delimiter, the remaining
- space will be added to the last bloc */
- }
-
-
- /******************************************
- Malloc and fill up the bloc contents
- *******************************************/
- p_bloc = malloc( sizeof( t_ipmi_fru_bloc ) * num_bloc );
- if(!p_bloc)
- {
- lprintf(LOG_ERR, " Unable to get memory to build Fru bloc");
+ // Multi
+ if (header.offset.multi) {
+ off = header.offset.multi * 8;
- if (fru_data != NULL) {
- free(fru_data);
- fru_data = NULL;
- }
+ do {
+ /*
+ * check for odd offset for the case of fru devices
+ * accessed by words
+ */
+ if (fru->access && (off & 1)) {
+ lprintf(LOG_ERR, " Unaligned offset for a block: %d", off);
+ /* increment offset */
+ off++;
+ break;
+ }
- return NULL;
- }
+ if (read_fru_area(intf, fru, id, off, 5,
+ (uint8_t *) &rec_hdr) < 0) {
+ break;
+ }
- // Common header
- bloc_count = 0;
+ p_new = malloc(sizeof(struct ipmi_fru_bloc));
+ if (!p_new) {
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
+ free_fru_bloc(p_first);
+ return NULL;
+ }
- p_bloc[bloc_count].start= 0;
- p_bloc[bloc_count].size = 8;
- strcpy((char *)p_bloc[bloc_count].blocId, "Common Header Section");
- bloc_count ++;
+ p_new->next = NULL;
+ p_new->start = off;
+ p_new->size = fru->size - p_new->start;
+ sprintf((char *)p_new->blocId, "Multi-Rec Area: Type %i",
+ rec_hdr.type);
- // Internal
- if( header.offset.internal )
- {
- p_bloc[bloc_count].start = (header.offset.internal * 8);
- p_bloc[bloc_count].size = 0; // Will be fillup later
- strcpy((char *)p_bloc[bloc_count].blocId, "Internal Use Section");
- bloc_count ++;
- }
- // Chassis
- if( header.offset.chassis )
- {
- p_bloc[bloc_count].start = (header.offset.chassis * 8);
- p_bloc[bloc_count].size = 0; // Will be fillup later
- strcpy((char *)p_bloc[bloc_count].blocId, "Chassis Section");
- bloc_count ++;
- }
- // Board
- if( header.offset.board )
- {
- p_bloc[bloc_count].start = (header.offset.board * 8);
- p_bloc[bloc_count].size = 0; // Will be fillup later
- strcpy((char *)p_bloc[bloc_count].blocId, "Board Section");
- bloc_count ++;
- }
- // Product
- if( header.offset.product )
- {
- p_bloc[bloc_count].start = (header.offset.product * 8);
- p_bloc[bloc_count].size = 0; // Will be fillup later
- strcpy((char *)p_bloc[bloc_count].blocId, "Product Section");
- bloc_count ++;
- }
-
- // Multi-Record Area
- if(
- ( header.offset.multi )
- &&
- ( fru_data )
- )
- {
- uint32_t i = (header.offset.multi*8);
- struct fru_multirec_header * h;
+ p_bloc->next = p_new;
+ p_bloc->size = p_new->start - p_bloc->start;
+ p_bloc = p_new;
- do {
- h = (struct fru_multirec_header *) (fru_data + i);
+ off += rec_hdr.len + sizeof(struct fru_multirec_header);
- p_bloc[bloc_count].start = i;
- p_bloc[bloc_count].size = h->len + sizeof (struct fru_multirec_header);
- sprintf((char *)p_bloc[bloc_count].blocId, "Multi-Rec Aread: Type %i", h->type);
- bloc_count ++;
- /*printf("Bloc Start: %i\n", i);
- printf("Bloc Size : %i\n", h->len);
- printf("\n");*/
+ /* verify record header */
+ if (ipmi_csum((uint8_t *)&rec_hdr,
+ sizeof(struct fru_multirec_header))) {
+ /* can't reliably judge for the rest space */
+ break;
+ }
+ } while (!(rec_hdr.format & 0x80) && (off < fru->size));
- i += h->len + sizeof (struct fru_multirec_header);
+ lprintf(LOG_DEBUG,"Multi-Record area ends at: %i (%xh)", off, off);
- } while (!(h->format & 0x80) && ( bloc_count < num_bloc ) );
+ if (fru->size > off) {
+ // Bloc for remaining space
+ p_new = malloc(sizeof(struct ipmi_fru_bloc));
+ if (!p_new) {
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
+ free_fru_bloc(p_first);
+ return NULL;
+ }
- lprintf(LOG_DEBUG ,"Multi-Record area ends at: %i (%xh)",i,i);
- /* If last bloc size was defined and is not until the end, create a
- last bloc with the remaining unused space */
+ p_new->next = NULL;
+ p_new->start = off;
+ p_new->size = fru->size - p_new->start;
+ strcpy((char *)p_new->blocId, "Unused space");
- if((fru->size > i) && (bloc_count < num_bloc))
- {
- // Bloc for remaining space
- p_bloc[bloc_count].start = i;
- p_bloc[bloc_count].size = (fru->size - i);
- sprintf((char *)p_bloc[bloc_count].blocId, "Unused space");
- bloc_count ++;
+ p_bloc->next = p_new;
+ p_bloc->size = p_new->start - p_bloc->start;
}
-
}
- if (fru_data != NULL) {
- free(fru_data);
- fru_data = NULL;
+ /* Dump blocs */
+ for(p_bloc = p_first, i = 0; p_bloc; p_bloc = p_bloc->next) {
+ lprintf(LOG_DEBUG ,"Bloc Numb : %i", i++);
+ lprintf(LOG_DEBUG ,"Bloc Id : %s", p_bloc->blocId);
+ lprintf(LOG_DEBUG ,"Bloc Start: %i", p_bloc->start);
+ lprintf(LOG_DEBUG ,"Bloc Size : %i", p_bloc->size);
+ lprintf(LOG_DEBUG ,"");
}
- /* Fill up size for first bloc */
- {
- unsigned short counter;
- lprintf(LOG_DEBUG ,"\nNumber Bloc : %i\n", num_bloc);
- for(counter = 0; counter < (num_bloc); counter ++)
- {
- /* If size where not initialized, do it. */
- if( p_bloc[counter].size == 0)
- {
- /* If not the last bloc, use the next bloc to determine the end */
- if((counter+1) < num_bloc)
- {
- p_bloc[counter].size = (p_bloc[counter+1].start - p_bloc[counter].start);
- }
- else
- {
- p_bloc[counter].size = (fru->size - p_bloc[counter].start);
- }
- }
- lprintf(LOG_DEBUG ,"Bloc Numb : %i\n", counter);
- lprintf(LOG_DEBUG ,"Bloc Id : %s\n", p_bloc[counter].blocId);
- lprintf(LOG_DEBUG ,"Bloc Start: %i\n", p_bloc[counter].start);
- lprintf(LOG_DEBUG ,"Bloc Size : %i\n", p_bloc[counter].size);
- lprintf(LOG_DEBUG ,"\n");
- }
- }
+ return p_first;
+}
- (* ptr_number_bloc) = num_bloc;
+void
+free_fru_bloc(t_ipmi_fru_bloc *bloc)
+{
+ t_ipmi_fru_bloc * del;
- return p_bloc;
+ while (bloc) {
+ del = bloc;
+ bloc = bloc->next;
+ free(del);
+ del = NULL;
+ }
}
-
+/*
+ * write FRU[doffset:length] from the pFrubuf[soffset:length]
+ * rc=1 on success
+**/
int
write_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
uint16_t soffset, uint16_t doffset,
uint16_t length, uint8_t *pFrubuf)
-{ /*
- // fill in frubuf[offset:length] from the FRU[offset:length]
- // rc=1 on success
- */
- static uint16_t fru_data_rqst_size = 32;
- uint16_t off=0, tmp, finish;
+{
+ uint16_t tmp, finish;
struct ipmi_rs * rsp;
struct ipmi_rq req;
- uint8_t msg_data[256];
- uint8_t writeLength;
- uint16_t num_bloc;
+ uint8_t msg_data[255+3];
+ uint16_t writeLength;
+ uint16_t found_bloc = 0;
finish = doffset + length; /* destination offset */
if (finish > fru->size)
{
- lprintf(LOG_ERROR, "Return error\n");
+ lprintf(LOG_ERROR, "Return error");
return -1;
}
- t_ipmi_fru_bloc * fru_bloc = build_fru_bloc(intf, fru, id, &num_bloc);
-
- if (fru_bloc == NULL) {
- lprintf(LOG_ERROR, "Failed to build FRU bloc.");
+ if (fru->access && ((doffset & 1) || (length & 1))) {
+ lprintf(LOG_ERROR, "Odd offset or length specified");
return (-1);
}
+ t_ipmi_fru_bloc * fru_bloc = build_fru_bloc(intf, fru, id);
+ t_ipmi_fru_bloc * saved_fru_bloc = fru_bloc;
+
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_STORAGE;
req.msg.cmd = SET_FRU_DATA;
req.msg.data = msg_data;
-#ifdef LIMIT_ALL_REQUEST_SIZE
- if (fru_data_rqst_size > 16)
-#else
- if (fru->access && fru_data_rqst_size > 16)
-#endif
- fru_data_rqst_size = 16;
+ /* initialize request size only once */
+ if (fru->max_write_size == 0) {
+ if (intf->channel_buf_size != 0) {
+ /* subtract 1 byte for FRU ID an 2 bytes for offset */
+ fru->max_write_size = intf->channel_buf_size - 3;
+ } else {
+ /* subtract 1 byte for FRU ID an 2 bytes for offset */
+ fru->max_write_size = 32 - 3;
+ }
- /* Check if we receive size in parameters */
- if(intf->channel_buf_size != 0)
- {
- fru_data_rqst_size = intf->channel_buf_size - 5; /* Plan for overhead */
+ /* check word access */
+ if (fru->access) {
+ fru->max_write_size &= ~1;
+ }
}
do {
- /* Temp init end_bloc to the end, if not found */
- uint16_t end_bloc = finish;
+ uint16_t end_bloc;
uint8_t protected_bloc = 0;
- uint16_t found_bloc = 0xffff;
-
- /* real destination offset */
- tmp = fru->access ? (doffset+off) >> 1 : (doffset+off);
- msg_data[0] = id;
- msg_data[1] = (uint8_t)tmp;
- msg_data[2] = (uint8_t)(tmp >> 8);
/* Write per bloc, try to find the end of a bloc*/
- {
- uint16_t counter;
- for(counter = 0; counter < (num_bloc); counter ++)
- {
- if(
- (tmp >= fru_bloc[counter].start)
- &&
- (tmp < (fru_bloc[counter].start + fru_bloc[counter].size))
- )
- {
- found_bloc = counter;
- end_bloc = (fru_bloc[counter].start + fru_bloc[counter].size);
- counter = num_bloc;
- }
- }
+ while (fru_bloc && fru_bloc->start + fru_bloc->size <= doffset) {
+ fru_bloc = fru_bloc->next;
+ found_bloc++;
}
- tmp = end_bloc - (doffset+off); /* bytes remaining for the bloc */
- if (tmp > fru_data_rqst_size) {
- memcpy(&msg_data[3], pFrubuf + soffset + off, fru_data_rqst_size);
- req.msg.data_len = fru_data_rqst_size + 3;
- }
- else {
- memcpy(&msg_data[3], pFrubuf + soffset + off, (uint8_t)tmp);
- req.msg.data_len = tmp + 3;
- }
- if(found_bloc == 0)
- {
- lprintf(LOG_INFO,"Writing %d bytes", (req.msg.data_len-3));
- }
- else if(found_bloc != 0xFFFF)
- {
- lprintf(LOG_INFO,"Writing %d bytes (Bloc #%i: %s)",
- (req.msg.data_len-3),
- found_bloc, fru_bloc[found_bloc].blocId);
+ if (fru_bloc && fru_bloc->start + fru_bloc->size < finish) {
+ end_bloc = fru_bloc->start + fru_bloc->size;
+ } else {
+ end_bloc = finish;
}
- writeLength = req.msg.data_len-3;
+ /* calculate write length */
+ tmp = end_bloc - doffset;
- rsp = intf->sendrecv(intf, &req);
- if (!rsp) {
- break;
+ /* check that write length is more than maximum request size */
+ if (tmp > fru->max_write_size) {
+ writeLength = fru->max_write_size;
+ } else {
+ writeLength = tmp;
}
- if(rsp->ccode==0x80) // Write protected section
- {
- protected_bloc = 1;
- }
- else if ((rsp->ccode==0xc7 || rsp->ccode==0xc8 || rsp->ccode==0xca ) &&
- --fru_data_rqst_size > 8) {
- lprintf(LOG_NOTICE,"Bad CC -> %x\n", rsp->ccode);
- break; /*continue;*/
- }
- else if (rsp->ccode > 0)
- break;
+ /* copy fru data */
+ memcpy(&msg_data[3], pFrubuf + soffset, writeLength);
- if(protected_bloc == 0)
- {
- lprintf(LOG_INFO,"Wrote %d bytes", writeLength);
- off += writeLength; // Write OK, bloc not protected, continue
+ /* check word access */
+ if (fru->access) {
+ writeLength &= ~1;
}
- else
- {
- if(found_bloc != 0xffff)
- {
- // Bloc protected, advise user and jump over protected bloc
- lprintf(LOG_INFO,"Bloc [%s] protected at offset: %i (size %i bytes)",
- fru_bloc[found_bloc].blocId,
- fru_bloc[found_bloc].start,
- fru_bloc[found_bloc].size);
- lprintf(LOG_INFO,"Jumping over this bloc");
- }
- else
- {
- lprintf(LOG_INFO,"Remaining FRU is protected following offset: %i",
- off);
- }
- off = end_bloc;
+ tmp = doffset;
+ if (fru->access) {
+ tmp >>= 1;
}
- } while ((doffset+off) < finish);
-
- free(fru_bloc);
- fru_bloc = NULL;
-
- return ((doffset+off) >= finish);
-}
-
-
-#if 0
-int
-write_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
- uint16_t soffset, uint16_t doffset,
- uint16_t length, uint8_t *pFrubuf)
-{ /*
- // fill in frubuf[offset:length] from the FRU[offset:length]
- // rc=1 on success
- */
- static uint16_t fru_data_rqst_size = 32;
- uint16_t off=0, tmp, finish;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- uint8_t msg_data[25];
- uint8_t writeLength;
-
- finish = doffset + length; /* destination offset */
- if (finish > fru->size)
- {
- printf("Return error\n");
- return -1;
- }
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_STORAGE;
- req.msg.cmd = SET_FRU_DATA;
- req.msg.data = msg_data;
-
-#ifdef LIMIT_ALL_REQUEST_SIZE
- if (fru_data_rqst_size > 16)
-#else
- if (fru->access && fru_data_rqst_size > 16)
-#endif
- fru_data_rqst_size = 16;
- do {
- /* real destination offset */
- tmp = fru->access ? (doffset+off) >> 1 : (doffset+off);
msg_data[0] = id;
msg_data[1] = (uint8_t)tmp;
msg_data[2] = (uint8_t)(tmp >> 8);
- tmp = finish - (doffset+off); /* bytes remaining */
- if (tmp > 16) {
- lprintf(LOG_INFO,"Writing 16 bytes");
- memcpy(&msg_data[3], pFrubuf + soffset + off, 16);
- req.msg.data_len = 16 + 3;
- }
- else {
- lprintf(LOG_INFO,"Writing %d bytes", tmp);
- memcpy(&msg_data[3], pFrubuf + soffset + off, (uint8_t)tmp);
- req.msg.data_len = tmp + 3;
- }
+ req.msg.data_len = writeLength + 3;
- writeLength = req.msg.data_len-3;
+ if(fru_bloc) {
+ lprintf(LOG_INFO,"Writing %d bytes (Bloc #%i: %s)",
+ writeLength, found_bloc, fru_bloc->blocId);
+ } else {
+ lprintf(LOG_INFO,"Writing %d bytes", writeLength);
+ }
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
break;
}
- if ((rsp->ccode==0xc7 || rsp->ccode==0xc8 || rsp->ccode==0xca ) &&
- --fru_data_rqst_size > 8) {
- lprintf(LOG_NOTICE,"Bad CC -> %x\n", rsp->ccode);
- break; /*continue;*/
+
+ if (rsp->ccode == 0xc7 || rsp->ccode == 0xc8 || rsp->ccode == 0xca) {
+ if (fru->max_write_size > 8) {
+ fru->max_write_size -= 8;
+ lprintf(LOG_INFO, "Retrying FRU write with request size %d",
+ fru->max_write_size);
+ continue;
+ }
+ } else if(rsp->ccode == 0x80) {
+ rsp->ccode = 0;
+ // Write protected section
+ protected_bloc = 1;
}
+
if (rsp->ccode > 0)
break;
- off += writeLength;
- } while ((doffset+off) < finish);
+ if (protected_bloc == 0) {
+ // Write OK, bloc not protected, continue
+ lprintf(LOG_INFO,"Wrote %d bytes", writeLength);
+ doffset += writeLength;
+ soffset += writeLength;
+ } else {
+ if(fru_bloc) {
+ // Bloc protected, advise user and jump over protected bloc
+ lprintf(LOG_INFO,
+ "Bloc [%s] protected at offset: %i (size %i bytes)",
+ fru_bloc->blocId, fru_bloc->start, fru_bloc->size);
+ lprintf(LOG_INFO,"Jumping over this bloc");
+ } else {
+ lprintf(LOG_INFO,
+ "Remaining FRU is protected following offset: %i",
+ doffset);
+ }
+ soffset += end_bloc - doffset;
+ doffset = end_bloc;
+ }
+ } while (doffset < finish);
+
+ if (saved_fru_bloc) {
+ free_fru_bloc(saved_fru_bloc);
+ }
- return ((doffset+off) >= finish);
+ return doffset >= finish;
}
-#endif
/* read_fru_area - fill in frubuf[offset:length] from the FRU[offset:length]
*
@@ -749,7 +585,6 @@ int
read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
uint32_t offset, uint32_t length, uint8_t *frubuf)
{
- static uint32_t fru_data_rqst_size = 20;
uint32_t off = offset, tmp, finish;
struct ipmi_rs * rsp;
struct ipmi_rq req;
@@ -775,29 +610,24 @@ read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
req.msg.data = msg_data;
req.msg.data_len = 4;
-#ifdef LIMIT_ALL_REQUEST_SIZE
- if (fru_data_rqst_size > 16)
-#else
- if (fru->access && fru_data_rqst_size > 16)
-#endif
- fru_data_rqst_size = 16;
-
+ if (fru->max_read_size == 0) {
+ /* subtract 1 byte for completion code and 1 for byte count */
+ fru->max_read_size = 32 - 2;
- /* Check if we receive size in parameters */
- if(intf->channel_buf_size != 0)
- {
- fru_data_rqst_size = intf->channel_buf_size - 9; /* Plan for overhead */
+ /* check word access */
+ if (fru->access) {
+ fru->max_read_size &= ~1;
+ }
}
-
do {
tmp = fru->access ? off >> 1 : off;
msg_data[0] = id;
msg_data[1] = (uint8_t)(tmp & 0xff);
msg_data[2] = (uint8_t)(tmp >> 8);
tmp = finish - off;
- if (tmp > fru_data_rqst_size)
- msg_data[3] = (uint8_t)fru_data_rqst_size;
+ if (tmp > fru->max_read_size)
+ msg_data[3] = (uint8_t)fru->max_read_size;
else
msg_data[3] = (uint8_t)tmp;
@@ -807,33 +637,43 @@ read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
break;
}
if (rsp->ccode > 0) {
- /* if we get C7 or C8 or CA return code then we requested too
+ /* if we get C8h or CAh completion code then we requested too
* many bytes at once so try again with smaller size */
- if ((rsp->ccode == 0xc7 || rsp->ccode == 0xc8 || rsp->ccode == 0xca) &&
- (--fru_data_rqst_size > 8)) {
+ if ((rsp->ccode == 0xc8 || rsp->ccode == 0xca)
+ && fru->max_read_size > 8) {
+ if (fru->max_read_size > 32) {
+ /* subtract read length more aggressively */
+ fru->max_read_size -= 8;
+ } else {
+ /* subtract length less aggressively */
+ fru->max_read_size--;
+ }
+
lprintf(LOG_INFO, "Retrying FRU read with request size %d",
- fru_data_rqst_size);
+ fru->max_read_size);
continue;
}
+
lprintf(LOG_NOTICE, "FRU Read failed: %s",
val2str(rsp->ccode, completion_code_vals));
break;
}
tmp = fru->access ? rsp->data[0] << 1 : rsp->data[0];
- memcpy((frubuf + off), rsp->data + 1, tmp);
+ memcpy(frubuf, rsp->data + 1, tmp);
off += tmp;
-
+ frubuf += tmp;
/* sometimes the size returned in the Info command
* is too large. return 0 so higher level function
* still attempts to parse what was returned */
- if (tmp == 0 && off < finish)
+ if (tmp == 0 && off < finish) {
return 0;
-
+ }
} while (off < finish);
- if (off < finish)
+ if (off < finish) {
return -1;
+ }
return 0;
}
@@ -1009,40 +849,48 @@ fru_area_print_chassis(struct ipmi_intf * intf, struct fru_info * fru,
uint8_t id, uint32_t offset)
{
char * fru_area;
- uint8_t * fru_data = NULL;
- uint32_t fru_len, area_len, i;
+ uint8_t * fru_data;
+ uint32_t fru_len, i;
+ uint8_t tmp[2];
- i = offset;
fru_len = 0;
- fru_data = malloc(fru->size + 1);
- if (fru_data == NULL) {
- lprintf(LOG_ERR, " Out of memory!");
+ /* read enough to check length field */
+ if (read_fru_area(intf, fru, id, offset, 2, tmp) == 0) {
+ fru_len = 8 * tmp[1];
+ }
+
+ if (fru_len == 0) {
return;
}
- memset(fru_data, 0, fru->size + 1);
- /* read enough to check length field */
- if (read_fru_area(intf, fru, id, i, 2, fru_data) == 0)
- fru_len = 8 * fru_data[i + 1];
- if (fru_len <= 0) {
- free(fru_data);
- fru_data = NULL;
+ fru_data = malloc(fru_len);
+ if (fru_data == NULL) {
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
return;
}
+ memset(fru_data, 0, fru_len);
+
/* read in the full fru */
- if (read_fru_area(intf, fru, id, i, fru_len, fru_data) < 0) {
+ if (read_fru_area(intf, fru, id, offset, fru_len, fru_data) < 0) {
free(fru_data);
fru_data = NULL;
return;
}
- i++; /* skip fru area version */
- area_len = fru_data[i++] * 8; /* fru area length */
+ /*
+ * skip first two bytes which specify
+ * fru area version and fru area length
+ */
+ i = 2;
printf(" Chassis Type : %s\n",
- chassis_type_desc[fru_data[i++]]);
+ chassis_type_desc[fru_data[i] >
+ (sizeof(chassis_type_desc)/sizeof(chassis_type_desc[0])) - 1 ?
+ 2 : fru_data[i]]);
+
+ i++;
fru_area = get_fru_area_str(fru_data, &i);
if (fru_area != NULL) {
@@ -1063,7 +911,7 @@ fru_area_print_chassis(struct ipmi_intf * intf, struct fru_info * fru,
}
/* read any extra fields */
- while ((fru_data[i] != 0xc1) && (i < offset + area_len))
+ while ((fru_data[i] != 0xc1) && (i < fru_len))
{
int j = i;
fru_area = get_fru_area_str(fru_data, &i);
@@ -1074,8 +922,10 @@ fru_area_print_chassis(struct ipmi_intf * intf, struct fru_info * fru,
free(fru_area);
fru_area = NULL;
}
- if (i == j)
+
+ if (i == j) {
break;
+ }
}
if (fru_area != NULL) {
@@ -1096,39 +946,45 @@ fru_area_print_board(struct ipmi_intf * intf, struct fru_info * fru,
uint8_t id, uint32_t offset)
{
char * fru_area;
- uint8_t * fru_data = NULL;
- uint32_t fru_len, area_len, i;
+ uint8_t * fru_data;
+ uint32_t fru_len;
+ uint32_t i;
time_t tval;
+ uint8_t tmp[2];
- i = offset;
fru_len = 0;
- fru_data = malloc(fru->size + 1);
- if (fru_data == NULL) {
- lprintf(LOG_ERR, " Out of memory!");
- return;
+ /* read enough to check length field */
+ if (read_fru_area(intf, fru, id, offset, 2, tmp) == 0) {
+ fru_len = 8 * tmp[1];
}
- memset(fru_data, 0, fru->size + 1);
- /* read enough to check length field */
- if (read_fru_area(intf, fru, id, i, 2, fru_data) == 0)
- fru_len = 8 * fru_data[i + 1];
if (fru_len <= 0) {
- free(fru_data);
- fru_data = NULL;
return;
}
+ fru_data = malloc(fru_len);
+ if (fru_data == NULL) {
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
+ return;
+ }
+
+ memset(fru_data, 0, fru_len);
+
/* read in the full fru */
- if (read_fru_area(intf, fru, id, i, fru_len, fru_data) < 0) {
+ if (read_fru_area(intf, fru, id, offset, fru_len, fru_data) < 0) {
free(fru_data);
fru_data = NULL;
return;
}
- i++; /* skip fru area version */
- area_len = fru_data[i++] * 8; /* fru area length */
- i++; /* skip fru board language */
+ /*
+ * skip first three bytes which specify
+ * fru area version, fru area length
+ * and fru board language
+ */
+ i = 3;
+
tval=((fru_data[i+2] << 16) + (fru_data[i+1] << 8) + (fru_data[i]));
tval=tval * 60;
tval=tval + secs_from_1970_1996;
@@ -1181,7 +1037,7 @@ fru_area_print_board(struct ipmi_intf * intf, struct fru_info * fru,
}
/* read any extra fields */
- while ((fru_data[i] != 0xc1) && (i < offset + area_len))
+ while ((fru_data[i] != 0xc1) && (i < fru_len))
{
int j = i;
fru_area = get_fru_area_str(fru_data, &i);
@@ -1213,39 +1069,44 @@ static void
fru_area_print_product(struct ipmi_intf * intf, struct fru_info * fru,
uint8_t id, uint32_t offset)
{
- char * fru_area = NULL;
- uint8_t * fru_data = NULL;
- uint32_t fru_len, area_len, i;
+ char * fru_area;
+ uint8_t * fru_data;
+ uint32_t fru_len, i;
+ uint8_t tmp[2];
- i = offset;
fru_len = 0;
- fru_data = malloc(fru->size + 1);
- if (fru_data == NULL) {
- lprintf(LOG_ERR, " Out of memory!");
+ /* read enough to check length field */
+ if (read_fru_area(intf, fru, id, offset, 2, tmp) == 0) {
+ fru_len = 8 * tmp[1];
+ }
+
+ if (fru_len == 0) {
return;
}
- memset(fru_data, 0, fru->size + 1);
- /* read enough to check length field */
- if (read_fru_area(intf, fru, id, i, 2, fru_data) == 0)
- fru_len = 8 * fru_data[i + 1];
- if (fru_len <= 0) {
- free(fru_data);
- fru_data = NULL;
+ fru_data = malloc(fru_len);
+ if (fru_data == NULL) {
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
return;
}
+ memset(fru_data, 0, fru_len);
+
+
/* read in the full fru */
- if (read_fru_area(intf, fru, id, i, fru_len, fru_data) < 0) {
+ if (read_fru_area(intf, fru, id, offset, fru_len, fru_data) < 0) {
free(fru_data);
fru_data = NULL;
return;
}
- i++; /* skip fru area version */
- area_len = fru_data[i++] * 8; /* fru area length */
- i++; /* skip fru board language */
+ /*
+ * skip first three bytes which specify
+ * fru area version, fru area length
+ * and fru board language
+ */
+ i = 3;
fru_area = get_fru_area_str(fru_data, &i);
if (fru_area != NULL) {
@@ -1311,7 +1172,7 @@ fru_area_print_product(struct ipmi_intf * intf, struct fru_info * fru,
}
/* read any extra fields */
- while ((fru_data[i] != 0xc1) && (i < offset + area_len))
+ while ((fru_data[i] != 0xc1) && (i < fru_len))
{
int j = i;
fru_area = get_fru_area_str(fru_data, &i);
@@ -1344,46 +1205,42 @@ fru_area_print_multirec(struct ipmi_intf * intf, struct fru_info * fru,
uint8_t id, uint32_t offset)
{
uint8_t * fru_data;
- uint32_t fru_len, i;
struct fru_multirec_header * h;
struct fru_multirec_powersupply * ps;
struct fru_multirec_dcoutput * dc;
struct fru_multirec_dcload * dl;
uint16_t peak_capacity;
uint8_t peak_hold_up_time;
- uint32_t last_off, len;
+ uint32_t last_off;
- i = last_off = offset;
- fru_len = 0;
+ last_off = offset;
- fru_data = malloc(fru->size + 1);
+ fru_data = malloc(FRU_MULTIREC_CHUNK_SIZE);
if (fru_data == NULL) {
- lprintf(LOG_ERR, " Out of memory!");
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
return;
}
- memset(fru_data, 0, fru->size + 1);
- do {
- h = (struct fru_multirec_header *) (fru_data + i);
+ memset(fru_data, 0, FRU_MULTIREC_CHUNK_SIZE);
- /* read area in (at most) FRU_MULTIREC_CHUNK_SIZE bytes at a time */
- if ((last_off < (i + sizeof(*h))) || (last_off < (i + h->len)))
- {
- len = fru->size - last_off;
- if (len > FRU_MULTIREC_CHUNK_SIZE)
- len = FRU_MULTIREC_CHUNK_SIZE;
+ h = (struct fru_multirec_header *) (fru_data);
- if (read_fru_area(intf, fru, id, last_off, len, fru_data) < 0)
- break;
+ do {
+ if (read_fru_area(intf, fru, id, last_off, sizeof(*h), fru_data) < 0) {
+ break;
+ }
- last_off += len;
+ if (h->len && read_fru_area(intf, fru, id,
+ last_off + sizeof(*h), h->len, fru_data + sizeof(*h)) < 0) {
+ break;
}
- switch (h->type)
- {
+ last_off += h->len + sizeof(*h);
+
+ switch (h->type) {
case FRU_RECORD_TYPE_POWER_SUPPLY_INFORMATION:
ps = (struct fru_multirec_powersupply *)
- (fru_data + i + sizeof (struct fru_multirec_header));
+ (fru_data + sizeof(struct fru_multirec_header));
#if WORDS_BIGENDIAN
ps->capacity = BSWAP_16(ps->capacity);
@@ -1441,7 +1298,7 @@ fru_area_print_multirec(struct ipmi_intf * intf, struct fru_info * fru,
case FRU_RECORD_TYPE_DC_OUTPUT:
dc = (struct fru_multirec_dcoutput *)
- (fru_data + i + sizeof (struct fru_multirec_header));
+ (fru_data + sizeof(struct fru_multirec_header));
#if WORDS_BIGENDIAN
dc->nominal_voltage = BSWAP_16(dc->nominal_voltage);
@@ -1473,7 +1330,7 @@ fru_area_print_multirec(struct ipmi_intf * intf, struct fru_info * fru,
case FRU_RECORD_TYPE_DC_LOAD:
dl = (struct fru_multirec_dcload *)
- (fru_data + i + sizeof (struct fru_multirec_header));
+ (fru_data + sizeof(struct fru_multirec_header));
#if WORDS_BIGENDIAN
dl->nominal_voltage = BSWAP_16(dl->nominal_voltage);
@@ -1503,7 +1360,7 @@ fru_area_print_multirec(struct ipmi_intf * intf, struct fru_info * fru,
case FRU_RECORD_TYPE_OEM_EXTENSION:
{
struct fru_multirec_oem_header *oh=(struct fru_multirec_oem_header *)
- &fru_data[i + sizeof(struct fru_multirec_header)];
+ &fru_data[sizeof(struct fru_multirec_header)];
uint32_t iana = oh->mfg_id[0] | oh->mfg_id[1]<<8 | oh->mfg_id[2]<<16;
/* Now makes sure this is really PICMG record */
@@ -1511,7 +1368,7 @@ fru_area_print_multirec(struct ipmi_intf * intf, struct fru_info * fru,
if( iana == IPMI_OEM_PICMG ){
printf(" PICMG Extension Record\n");
ipmi_fru_picmg_ext_print(fru_data,
- i + sizeof(struct fru_multirec_header),
+ sizeof(struct fru_multirec_header),
h->len);
}
/* FIXME: Add OEM record support here */
@@ -1521,13 +1378,11 @@ fru_area_print_multirec(struct ipmi_intf * intf, struct fru_info * fru,
}
break;
}
- i += h->len + sizeof (struct fru_multirec_header);
} while (!(h->format & 0x80));
- lprintf(LOG_DEBUG ,"Multi-Record area ends at: %i (%xh)",i,i);
+ lprintf(LOG_DEBUG ,"Multi-Record area ends at: %i (%xh)", last_off, last_off);
free(fru_data);
- fru_data = NULL;
}
/* ipmi_fru_query_new_value - Query new values to replace original FRU content
@@ -2309,7 +2164,7 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
minexp / 2, (minexp % 2) * 5);
} else {
printf(
- " Min Expected Voltage: -36V (actual invalid value 0x%x)\n",
+ " Min Expected Voltage: -%dV (actual invalid value 0x%x)\n",
36, minexp);
}
for (j=0; j < entries; j++) {
@@ -2986,6 +2841,7 @@ __ipmi_fru_print(struct ipmi_intf * intf, uint8_t id)
return -1;
}
+ memset(&fru, 0, sizeof(fru));
fru.size = (rsp->data[1] << 8) | rsp->data[0];
fru.access = rsp->data[2] & 0x1;
@@ -3088,7 +2944,8 @@ int
ipmi_fru_print(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru)
{
char desc[17];
- uint32_t save_addr = 0;
+ uint8_t bridged_request = 0;
+ uint32_t save_addr;
uint32_t save_channel;
int rc = 0;
@@ -3131,6 +2988,7 @@ ipmi_fru_print(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru)
case 0x02:
if (BRIDGE_TO_SENSOR(intf, fru->dev_slave_addr,
fru->channel_num)) {
+ bridged_request = 1;
save_addr = intf->target_addr;
intf->target_addr = fru->dev_slave_addr;
save_channel = intf->target_channel;
@@ -3138,7 +2996,7 @@ ipmi_fru_print(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru)
}
/* print FRU */
rc = __ipmi_fru_print(intf, fru->device_id);
- if (save_addr) {
+ if (bridged_request) {
intf->target_addr = save_addr;
intf->target_channel = save_channel;
}
@@ -3316,6 +3174,8 @@ ipmi_fru_read_to_bin(struct ipmi_intf * intf,
printf (" Timeout accessing FRU info. (Device not present?)\n");
return;
}
+
+ memset(&fru, 0, sizeof(fru));
fru.size = (rsp->data[1] << 8) | rsp->data[0];
fru.access = rsp->data[2] & 0x1;
@@ -3382,6 +3242,8 @@ ipmi_fru_write_from_bin(struct ipmi_intf * intf,
printf(" Timeout accessing FRU info. (Device not present?)\n");
return;
}
+
+ memset(&fru, 0, sizeof(fru));
fru.size = (rsp->data[1] << 8) | rsp->data[0];
fru.access = rsp->data[2] & 0x1;
@@ -3501,6 +3363,7 @@ ipmi_fru_edit_multirec(struct ipmi_intf * intf, uint8_t id ,
return -1;
}
+ memset(&fru, 0, sizeof(fru));
fru.size = (rsp->data[1] << 8) | rsp->data[0];
fru.access = rsp->data[2] & 0x1;
@@ -3524,6 +3387,7 @@ ipmi_fru_edit_multirec(struct ipmi_intf * intf, uint8_t id ,
i = last_off = offset;
fru_len = 0;
+ memset(&fru, 0, sizeof(fru));
fru_data = malloc(fru.size + 1);
if (fru_data == NULL) {
lprintf(LOG_ERR, " Out of memory!");
@@ -3702,6 +3566,7 @@ ipmi_fru_get_multirec(struct ipmi_intf * intf, uint8_t id ,
return -1;
}
+ memset(&fru, 0, sizeof(fru));
fru.size = (rsp->data[1] << 8) | rsp->data[0];
fru.access = rsp->data[2] & 0x1;
@@ -4171,6 +4036,7 @@ ipmi_fru_get_internal_use_info( struct ipmi_intf * intf,
return -1;
}
+ memset(&fru, 0, sizeof(fru));
fru->size = (rsp->data[1] << 8) | rsp->data[0];
fru->access = rsp->data[2] & 0x1;
@@ -4755,6 +4621,7 @@ f_type, uint8_t f_index, char *f_string)
goto ipmi_fru_set_field_string_out;
}
+ memset(&fru, 0, sizeof(fru));
fru.size = (rsp->data[1] << 8) | rsp->data[0];
fru.access = rsp->data[2] & 0x1;
diff --git a/ipmitool/lib/ipmi_fwum.c b/ipmitool/lib/ipmi_fwum.c
index d9b562c..b666a2b 100644
--- a/ipmitool/lib/ipmi_fwum.c
+++ b/ipmitool/lib/ipmi_fwum.c
@@ -19,7 +19,7 @@
* 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.
+ * 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.
@@ -33,7 +33,6 @@
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
-
#include <string.h>
#include <math.h>
#include <time.h>
@@ -46,421 +45,259 @@
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_mc.h>
-/******************************************************************************
-* HISTORY
-* ===========================================================================
-* 2007-01-11 [FI]
-* - Incremented to version 1.3
-* - Added lan packet size reduction mechanism to workaround fact
-* that lan iface will not return C7 on excessive length
-*
-*****************************************************************************/
-
-#define VERSION_MAJ 1
-#define VERSION_MIN 3
-
-
-typedef enum eKFWUM_Task
-{
- KFWUM_TASK_INFO,
- KFWUM_TASK_STATUS,
- KFWUM_TASK_DOWNLOAD,
- KFWUM_TASK_UPGRADE,
- KFWUM_TASK_START_UPGRADE,
- KFWUM_TASK_ROLLBACK,
- KFWUM_TASK_TRACELOG
-}tKFWUM_Task;
-
-typedef enum eKFWUM_BoardList
-{
- KFWUM_BOARD_KONTRON_UNKNOWN = 0,
- KFWUM_BOARD_KONTRON_5002 = 5002,
-}tKFWUM_BoardList;
-
-typedef enum eKFWUM_IanaList
-{
- KFWUM_IANA_KONTRON = 15000,
-}tKFWUM_IanaList;
-
-typedef struct sKFWUM_BoardInfo
-{
- tKFWUM_BoardList boardId;
- tKFWUM_IanaList iana;
-}tKFWUM_BoardInfo;
-
-typedef enum eKFWUM_Status
-{
- KFWUM_STATUS_OK,
- KFWUM_STATUS_ERROR
-}tKFWUM_Status;
-
-typedef enum eKFWUM_DownloadType
-{
- KFWUM_DOWNLOAD_TYPE_ADDRESS = 0,
- KFWUM_DOWNLOAD_TYPE_SEQUENCE,
-}tKFWUM_DownloadType;
+extern int verbose;
+unsigned char firmBuf[1024*512];
+tKFWUM_SaveFirmwareInfo save_fw_nfo;
+
+int KfwumGetFileSize(const char *pFileName,
+ unsigned long *pFileSize);
+int KfwumSetupBuffersFromFile(const char *pFileName,
+ unsigned long fileSize);
+void KfwumShowProgress(const char *task, unsigned long current,
+ unsigned long total);
+unsigned short KfwumCalculateChecksumPadding(unsigned char *pBuffer,
+ unsigned long totalSize);
+int KfwumGetInfo(struct ipmi_intf *intf, unsigned char output,
+ unsigned char *pNumBank);
+int KfwumGetDeviceInfo(struct ipmi_intf *intf,
+ unsigned char output, tKFWUM_BoardInfo *pBoardInfo);
+int KfwumGetStatus(struct ipmi_intf *intf);
+int KfwumManualRollback(struct ipmi_intf *intf);
+int KfwumStartFirmwareImage(struct ipmi_intf *intf,
+ unsigned long length, unsigned short padding);
+int KfwumSaveFirmwareImage(struct ipmi_intf *intf,
+ unsigned char sequenceNumber, unsigned long address,
+ unsigned char *pFirmBuf, unsigned char *pInBufLength);
+int KfwumFinishFirmwareImage(struct ipmi_intf *intf,
+ tKFWUM_InFirmwareInfo firmInfo);
+int KfwumUploadFirmware(struct ipmi_intf *intf,
+ unsigned char *pBuffer, unsigned long totalSize);
+int KfwumStartFirmwareUpgrade(struct ipmi_intf *intf);
+int KfwumGetInfoFromFirmware(unsigned char *pBuf,
+ unsigned long bufSize, tKFWUM_InFirmwareInfo *pInfo);
+void KfwumFixTableVersionForOldFirmware(tKFWUM_InFirmwareInfo *pInfo);
+int KfwumGetTraceLog(struct ipmi_intf *intf);
+int ipmi_kfwum_checkfwcompat(tKFWUM_BoardInfo boardInfo,
+ tKFWUM_InFirmwareInfo firmInfo);
+
+int ipmi_fwum_fwupgrade(struct ipmi_intf *intf, char *file, int action);
+int ipmi_fwum_info(struct ipmi_intf *intf);
+int ipmi_fwum_status(struct ipmi_intf *intf);
+void printf_kfwum_help(void);
+void printf_kfwum_info(tKFWUM_BoardInfo boardInfo,
+ tKFWUM_InFirmwareInfo firmInfo);
-typedef enum eKFWUM_DownloadBuffferType
-{
- KFWUM_SMALL_BUFFER_TYPE = 0,
- KFUMW_BIG_BUFFER_TYPE
-}tKFWUM_DownloadBuffferType;
+/* String table */
+/* Must match eFWUM_CmdId */
+const char *CMD_ID_STRING[] = {
+ "GetFwInfo",
+ "KickWatchdog",
+ "GetLastAnswer",
+ "BootHandshake",
+ "ReportStatus",
+ "CtrlIPMBLine",
+ "SetFwState",
+ "GetFwStatus",
+ "GetSpiMemStatus",
+ "StartFwUpdate",
+ "StartFwImage",
+ "SaveFwImage",
+ "FinishFwImage",
+ "ReadFwImage",
+ "ManualRollback",
+ "GetTraceLog"
+};
-typedef struct sKFWUM_InFirmwareInfo
-{
- unsigned long fileSize;
- unsigned short checksum;
- unsigned short sumToRemoveFromChecksum;
- /* Since the checksum is added in the bin
- after the checksum is calculated, we
- need to remove the each byte value. This
- byte will contain the addition of both bytes*/
- tKFWUM_BoardList boardId;
- unsigned char deviceId;
- unsigned char tableVers;
- unsigned char implRev;
- unsigned char versMajor;
- unsigned char versMinor;
- unsigned char versSubMinor;
- unsigned char sdrRev;
- tKFWUM_IanaList iana;
-}tKFWUM_InFirmwareInfo;
-
-typedef struct sKFWUM_SaveFirmwareInfo
-{
- tKFWUM_DownloadType downloadType;
- unsigned char bufferSize;
- unsigned char overheadSize;
-}tKFWUM_SaveFirmwareInfo;
-
-#define KFWUM_SMALL_BUFFER 32 /* Minimum size (IPMB/IOL/old protocol) */
-#define KFWUM_BIG_BUFFER 32 /* Maximum size on KCS interface */
-
-#define KFWUM_OLD_CMD_OVERHEAD 6 /*3 address + 1 size + 1 checksum + 1 command*/
-#define KFWUM_NEW_CMD_OVERHEAD 4 /*1 sequence+ 1 size + 1 checksum + 1 command*/
-#define KFWUM_PAGE_SIZE 256
+const char *EXT_CMD_ID_STRING[] = {
+ "FwUpgradeLock",
+ "ProcessFwUpg",
+ "ProcessFwRb",
+ "WaitHSAfterUpg",
+ "WaitFirstHSUpg",
+ "FwInfoStateChange"
+};
-extern int verbose;
-static unsigned char fileName[512];
-static unsigned char firmBuf[1024*512];
-static tKFWUM_SaveFirmwareInfo saveFirmwareInfo;
-
-static void KfwumOutputHelp(void);
-static void KfwumMain(struct ipmi_intf * intf, tKFWUM_Task task);
-static tKFWUM_Status KfwumGetFileSize(unsigned char * pFileName,
- unsigned long * pFileSize);
-static tKFWUM_Status KfwumSetupBuffersFromFile(unsigned char * pFileName,
- unsigned long fileSize);
-static void KfwumShowProgress( const unsigned char * task,
- unsigned long current, unsigned long total);
-static unsigned short KfwumCalculateChecksumPadding(unsigned char * pBuffer,
- unsigned long totalSize);
-
-
-static tKFWUM_Status KfwumGetInfo(struct ipmi_intf * intf, unsigned char output,
- unsigned char *pNumBank);
-static tKFWUM_Status KfwumGetDeviceInfo(struct ipmi_intf * intf,
- unsigned char output, tKFWUM_BoardInfo * pBoardInfo);
-static tKFWUM_Status KfwumGetStatus(struct ipmi_intf * intf);
-static tKFWUM_Status KfwumManualRollback(struct ipmi_intf * intf);
-static tKFWUM_Status KfwumStartFirmwareImage(struct ipmi_intf * intf,
- unsigned long length,unsigned short padding);
-static tKFWUM_Status KfwumSaveFirmwareImage(struct ipmi_intf * intf,
- unsigned char sequenceNumber, unsigned long address,
- unsigned char *pFirmBuf, unsigned char * pInBufLength);
-static tKFWUM_Status KfwumFinishFirmwareImage(struct ipmi_intf * intf,
- tKFWUM_InFirmwareInfo firmInfo);
-static tKFWUM_Status KfwumUploadFirmware(struct ipmi_intf * intf,
- unsigned char * pBuffer, unsigned long totalSize);
-static tKFWUM_Status KfwumStartFirmwareUpgrade(struct ipmi_intf * intf);
-
-static tKFWUM_Status KfwumGetInfoFromFirmware(unsigned char * pBuf,
- unsigned long bufSize, tKFWUM_InFirmwareInfo * pInfo);
-static void KfwumFixTableVersionForOldFirmware(tKFWUM_InFirmwareInfo * pInfo);
-
-static tKFWUM_Status KfwumGetTraceLog(struct ipmi_intf * intf);
-
-tKFWUM_Status KfwumValidFirmwareForBoard(tKFWUM_BoardInfo boardInfo,
- tKFWUM_InFirmwareInfo firmInfo);
-static void KfwumOutputInfo(tKFWUM_BoardInfo boardInfo,
- tKFWUM_InFirmwareInfo firmInfo);
+const char *CMD_STATE_STRING[] = {
+ "Invalid",
+ "Begin",
+ "Progress",
+ "Completed"
+};
+const struct valstr bankStateValS[] = {
+ { 0x00, "Not programmed" },
+ { 0x01, "New firmware" },
+ { 0x02, "Wait for validation" },
+ { 0x03, "Last Known Good" },
+ { 0x04, "Previous Good" }
+};
/* ipmi_fwum_main - entry point for this ipmitool mode
*
- * @intf: ipmi interface
- * @arc : number of arguments
- * @argv : point to argument array
+ * @intf: ipmi interface
+ * @arc: number of arguments
+ * @argv: point to argument array
*
* returns 0 on success
* returns -1 on error
*/
-int ipmi_fwum_main(struct ipmi_intf * intf, int argc, char ** argv)
+int
+ipmi_fwum_main(struct ipmi_intf *intf, int argc, char **argv)
{
- printf("FWUM extension Version %d.%d\n", VERSION_MAJ, VERSION_MIN);
- if ((!argc) || ( !strncmp(argv[0], "help", 4)))
- {
- KfwumOutputHelp();
- }
- else
- {
- if (!strncmp(argv[0], "info", 4))
- {
- KfwumMain(intf, KFWUM_TASK_INFO);
- }
- else if (!strncmp(argv[0], "status", 6))
- {
- KfwumMain(intf, KFWUM_TASK_STATUS);
- }
- else if (!strncmp(argv[0], "rollback", 8))
- {
- KfwumMain(intf, KFWUM_TASK_ROLLBACK);
- }
- else if (!strncmp(argv[0], "download", 8))
- {
- if((argc >= 2) && (strlen(argv[1]) > 0))
- {
- /* There is a file name in the parameters */
- if(strlen(argv[1]) < 512)
- {
- strcpy((char *)fileName, argv[1]);
- printf("Firmware File Name : %s\n", fileName);
-
- KfwumMain(intf, KFWUM_TASK_DOWNLOAD);
- }
- else
- {
- fprintf(stderr,"File name must be smaller than 512 bytes\n");
- }
- }
- else
- {
- fprintf(stderr,"A path and a file name must be specified\n");
- }
- }
- else if (!strncmp(argv[0], "upgrade", 7))
- {
- if((argc >= 2) && (strlen(argv[1]) > 0))
- {
- /* There is a file name in the parameters */
- if(strlen(argv[1]) < 512)
- {
- strcpy((char *)fileName, argv[1]);
- printf("Upgrading using file name %s\n", fileName);
- KfwumMain(intf, KFWUM_TASK_UPGRADE);
- }
- else
- {
- fprintf(stderr,"File name must be smaller than 512 bytes\n");
- }
- }
- else
- {
- KfwumMain(intf, KFWUM_TASK_START_UPGRADE);
- }
-
- }
- else if (!strncmp(argv[0], "tracelog", 8))
- {
- KfwumMain(intf, KFWUM_TASK_TRACELOG);
- }
- else
- {
- printf("Invalid KFWUM command: %s\n", argv[0]);
- }
- }
- return 0;
+ int rc = 0;
+ printf("FWUM extension Version %d.%d\n", VER_MAJOR, VER_MINOR);
+ if (argc < 1) {
+ lprintf(LOG_ERR, "Not enough parameters given.");
+ printf_kfwum_help();
+ return (-1);
+ }
+ if (strncmp(argv[0], "help", 4) == 0) {
+ printf_kfwum_help();
+ rc = 0;
+ } else if (strncmp(argv[0], "info", 4) == 0) {
+ rc = ipmi_fwum_info(intf);
+ } else if (strncmp(argv[0], "status", 6) == 0) {
+ rc = ipmi_fwum_status(intf);
+ } else if (strncmp(argv[0], "rollback", 8) == 0) {
+ rc = KfwumManualRollback(intf);
+ } else if (strncmp(argv[0], "download", 8) == 0) {
+ if ((argc < 2) || (strlen(argv[1]) < 1)) {
+ lprintf(LOG_ERR,
+ "Path and file name must be specified.");
+ return (-1);
+ }
+ printf("Firmware File Name : %s\n", argv[1]);
+ rc = ipmi_fwum_fwupgrade(intf, argv[1], 0);
+ } else if (strncmp(argv[0], "upgrade", 7) == 0) {
+ if ((argc >= 2) && (strlen(argv[1]) > 0)) {
+ printf("Upgrading using file name %s\n", argv[1]);
+ rc = ipmi_fwum_fwupgrade(intf, argv[1], 1);
+ } else {
+ rc = KfwumStartFirmwareUpgrade(intf);
+ }
+ } else if (strncmp(argv[0], "tracelog", 8) == 0) {
+ rc = KfwumGetTraceLog(intf);
+ } else {
+ lprintf(LOG_ERR, "Invalid KFWUM command: %s", argv[0]);
+ printf_kfwum_help();
+ rc = (-1);
+ }
+ return rc;
}
-
-static void KfwumOutputHelp(void)
+void
+printf_kfwum_help(void)
{
- printf("KFWUM Commands: info status download upgrade rollback tracelog\n");
+ lprintf(LOG_NOTICE,
+"KFWUM Commands: info status download upgrade rollback tracelog");
}
-
-/****************************************/
-/** private definitions and macros **/
-/****************************************/
+/* private definitions and macros */
typedef enum eFWUM_CmdId
{
- KFWUM_CMD_ID_GET_FIRMWARE_INFO = 0,
- KFWUM_CMD_ID_KICK_IPMC_WATCHDOG = 1,
- KFWUM_CMD_ID_GET_LAST_ANSWER = 2,
- KFWUM_CMD_ID_BOOT_HANDSHAKE = 3,
- KFWUM_CMD_ID_REPORT_STATUS = 4,
- KFWUM_CMD_ID_GET_FIRMWARE_STATUS = 7,
- KFWUM_CMD_ID_START_FIRMWARE_UPDATE = 9,
- KFWUM_CMD_ID_START_FIRMWARE_IMAGE = 0x0a,
- KFWUM_CMD_ID_SAVE_FIRMWARE_IMAGE = 0x0b,
- KFWUM_CMD_ID_FINISH_FIRMWARE_IMAGE = 0x0c,
- KFWUM_CMD_ID_READ_FIRMWARE_IMAGE = 0x0d,
- KFWUM_CMD_ID_MANUAL_ROLLBACK = 0x0e,
- KFWUM_CMD_ID_GET_TRACE_LOG = 0x0f,
- KFWUM_CMD_ID_STD_MAX_CMD,
- KFWUM_CMD_ID_EXTENDED_CMD = 0xC0
+ KFWUM_CMD_ID_GET_FIRMWARE_INFO = 0,
+ KFWUM_CMD_ID_KICK_IPMC_WATCHDOG = 1,
+ KFWUM_CMD_ID_GET_LAST_ANSWER = 2,
+ KFWUM_CMD_ID_BOOT_HANDSHAKE = 3,
+ KFWUM_CMD_ID_REPORT_STATUS = 4,
+ KFWUM_CMD_ID_GET_FIRMWARE_STATUS = 7,
+ KFWUM_CMD_ID_START_FIRMWARE_UPDATE = 9,
+ KFWUM_CMD_ID_START_FIRMWARE_IMAGE = 0x0a,
+ KFWUM_CMD_ID_SAVE_FIRMWARE_IMAGE = 0x0b,
+ KFWUM_CMD_ID_FINISH_FIRMWARE_IMAGE = 0x0c,
+ KFWUM_CMD_ID_READ_FIRMWARE_IMAGE = 0x0d,
+ KFWUM_CMD_ID_MANUAL_ROLLBACK = 0x0e,
+ KFWUM_CMD_ID_GET_TRACE_LOG = 0x0f,
+ KFWUM_CMD_ID_STD_MAX_CMD,
+ KFWUM_CMD_ID_EXTENDED_CMD = 0xC0
} tKFWUM_CmdId;
-
-
-/****************************************/
-/** global/static variables definition **/
-/****************************************/
-
-/****************************************/
-/** functions definition **/
-/****************************************/
-
-/*******************************************************************************
-*
-* Function Name: KfwumMain
-*
-* Description: This function implements the upload of the firware data
-* received as parameters.
-*
-* Restriction: Called only from main
-*
-* Input: unsigned char * pBuffer[] : The buffers
-* unsigned long bufSize : The size of the buffers
-*
-* Output: None
-*
-* Global: none
-*
-* Return: tIFWU_Status (success or failure)
-*
-*******************************************************************************/
-static void KfwumMain(struct ipmi_intf * intf, tKFWUM_Task task)
+int
+ipmi_fwum_info(struct ipmi_intf *intf)
{
- tKFWUM_Status status = KFWUM_STATUS_OK;
- tKFWUM_BoardInfo boardInfo;
- tKFWUM_InFirmwareInfo firmInfo = { 0 };
- unsigned long fileSize = 0;
- static unsigned short padding;
-
- if((status == KFWUM_STATUS_OK) && (task == KFWUM_TASK_INFO))
- {
- unsigned char notUsed;
- if(verbose)
- {
- printf("Getting Kontron FWUM Info\n");
- }
- KfwumGetDeviceInfo(intf, 1, &boardInfo);
- KfwumGetInfo(intf, 1, &notUsed);
-
- }
-
-
- if((status == KFWUM_STATUS_OK) && (task == KFWUM_TASK_STATUS))
- {
- if(verbose)
- {
- printf("Getting Kontron FWUM Status\n");
- }
- KfwumGetStatus(intf);
- }
-
- if( (status == KFWUM_STATUS_OK) && (task == KFWUM_TASK_ROLLBACK) )
- {
- status = KfwumManualRollback(intf);
- }
-
- if(
- (status == KFWUM_STATUS_OK) &&
- (
- (task == KFWUM_TASK_UPGRADE) || (task == KFWUM_TASK_DOWNLOAD)
- )
- )
- {
- status = KfwumGetFileSize(fileName, &fileSize);
- if(status == KFWUM_STATUS_OK)
- {
- status = KfwumSetupBuffersFromFile(fileName, fileSize);
- if(status == KFWUM_STATUS_OK)
- {
- padding = KfwumCalculateChecksumPadding(firmBuf, fileSize);
- }
- }
- if(status == KFWUM_STATUS_OK)
- {
- status = KfwumGetInfoFromFirmware(firmBuf, fileSize, &firmInfo);
- }
- if(status == KFWUM_STATUS_OK)
- {
- status = KfwumGetDeviceInfo(intf, 0, &boardInfo);
- }
-
- if(status == KFWUM_STATUS_OK)
- {
- status = KfwumValidFirmwareForBoard(boardInfo,firmInfo);
- }
-
- if (status == KFWUM_STATUS_OK)
- {
- unsigned char notUsed;
- KfwumGetInfo(intf, 0, &notUsed);
- }
-
- KfwumOutputInfo(boardInfo,firmInfo);
- }
-
- if(
- (status == KFWUM_STATUS_OK) &&
- (
- (task == KFWUM_TASK_UPGRADE) || (task == KFWUM_TASK_DOWNLOAD)
- )
- )
- {
- status = KfwumStartFirmwareImage(intf, fileSize, padding);
- }
-
-
- if(
- (status == KFWUM_STATUS_OK) &&
- (
- (task == KFWUM_TASK_UPGRADE) || (task == KFWUM_TASK_DOWNLOAD)
- )
- )
- {
- status = KfwumUploadFirmware(intf, firmBuf, fileSize);
- }
-
- if(
- (status == KFWUM_STATUS_OK) &&
- (
- (task == KFWUM_TASK_UPGRADE) || (task == KFWUM_TASK_DOWNLOAD)
- )
- )
- {
- status = KfwumFinishFirmwareImage(intf, firmInfo);
- }
-
- if(
- (status == KFWUM_STATUS_OK) &&
- (
- (task == KFWUM_TASK_UPGRADE) || (task == KFWUM_TASK_DOWNLOAD)
- )
- )
- {
- status = KfwumGetStatus(intf);
- }
-
- if(
- (status == KFWUM_STATUS_OK) &&
- (
- (task == KFWUM_TASK_UPGRADE) || (task == KFWUM_TASK_START_UPGRADE)
- )
- )
- {
- status = KfwumStartFirmwareUpgrade(intf);
- }
-
- if((status == KFWUM_STATUS_OK) && (task == KFWUM_TASK_TRACELOG))
- {
- status = KfwumGetTraceLog(intf);
- }
+ tKFWUM_BoardInfo b_info;
+ int rc = 0;
+ unsigned char not_used;
+ if (verbose) {
+ printf("Getting Kontron FWUM Info\n");
+ }
+ if (KfwumGetDeviceInfo(intf, 1, &b_info) != 0) {
+ rc = (-1);
+ }
+ if (KfwumGetInfo(intf, 1, &not_used) != 0) {
+ rc = (-1);
+ }
+ return rc;
+}
+int
+ipmi_fwum_status(struct ipmi_intf *intf)
+{
+ if (verbose) {
+ printf("Getting Kontron FWUM Status\n");
+ }
+ if (KfwumGetStatus(intf) != 0) {
+ return (-1);
+ }
+ return 0;
+}
+/* ipmi_fwum_fwupgrade - function implements download/upload of the firmware
+ * data received as parameters
+ *
+ * @file: fw file
+ * @action: 0 = download, 1 = upload/start upload
+ *
+ * returns 0 on success, otherwise (-1)
+ */
+int
+ipmi_fwum_fwupgrade(struct ipmi_intf *intf, char *file, int action)
+{
+ tKFWUM_BoardInfo b_info;
+ tKFWUM_InFirmwareInfo fw_info = { 0 };
+ unsigned short padding;
+ unsigned long fsize = 0;
+ unsigned char not_used;
+ if (file == NULL) {
+ lprintf(LOG_ERR, "No file given.");
+ return (-1);
+ }
+ if (KfwumGetFileSize(file, &fsize) != 0) {
+ return (-1);
+ }
+ if (KfwumSetupBuffersFromFile(file, fsize) != 0) {
+ return (-1);
+ }
+ padding = KfwumCalculateChecksumPadding(firmBuf, fsize);
+ if (KfwumGetInfoFromFirmware(firmBuf, fsize, &fw_info) != 0) {
+ return (-1);
+ }
+ if (KfwumGetDeviceInfo(intf, 0, &b_info) != 0) {
+ return (-1);
+ }
+ if (ipmi_kfwum_checkfwcompat(b_info, fw_info) != 0) {
+ return (-1);
+ }
+ KfwumGetInfo(intf, 0, &not_used);
+ printf_kfwum_info(b_info, fw_info);
+ if (KfwumStartFirmwareImage(intf, fsize, padding) != 0) {
+ return (-1);
+ }
+ if (KfwumUploadFirmware(intf, firmBuf, fsize) != 0) {
+ return (-1);
+ }
+ if (KfwumFinishFirmwareImage(intf, fw_info) != 0) {
+ return (-1);
+ }
+ if (KfwumGetStatus(intf) != 0) {
+ return (-1);
+ }
+ if (action != 0) {
+ if (KfwumStartFirmwareUpgrade(intf) != 0) {
+ return (-1);
+ }
+ }
+ return 0;
}
/* KfwumGetFileSize - gets the file size
@@ -468,31 +305,24 @@ static void KfwumMain(struct ipmi_intf * intf, tKFWUM_Task task)
* @pFileName : filename ptr
* @pFileSize : output ptr for filesize
*
- * returns KFWUM_STATUS_OK or KFWUM_STATUS_ERROR
+ * returns 0 on success, otherwise (-1)
*/
-static tKFWUM_Status KfwumGetFileSize(unsigned char * pFileName,
- unsigned long * pFileSize)
+int
+KfwumGetFileSize(const char *pFileName, unsigned long *pFileSize)
{
- tKFWUM_Status status = KFWUM_STATUS_ERROR;
- FILE * pFileHandle;
-
- pFileHandle = fopen((const char *)pFileName, "rb");
-
- if(pFileHandle)
- {
- if (fseek(pFileHandle, 0L , SEEK_END) == 0)
- {
- *pFileSize = ftell(pFileHandle);
-
- if( *pFileSize != 0)
- {
- status = KFWUM_STATUS_OK;
- }
- }
- fclose(pFileHandle);
- }
-
- return(status);
+ FILE *pFileHandle = NULL;
+ pFileHandle = fopen(pFileName, "rb");
+ if (pFileHandle == NULL) {
+ return (-1);
+ }
+ if (fseek(pFileHandle, 0L , SEEK_END) == 0) {
+ *pFileSize = ftell(pFileHandle);
+ }
+ fclose(pFileHandle);
+ if (*pFileSize != 0) {
+ return 0;
+ }
+ return (-1);
}
/* KfwumSetupBuffersFromFile - small buffers are used to store the file data
@@ -500,1182 +330,803 @@ static tKFWUM_Status KfwumGetFileSize(unsigned char * pFileName,
* @pFileName : filename ptr
* unsigned long : filesize
*
- * returns KFWUM_STATUS_OK or KFWUM_STATUS_ERROR
+ * returns 0 on success, otherwise (-1)
*/
-#define MAX_BUFFER_SIZE 1024*16
-static tKFWUM_Status KfwumSetupBuffersFromFile(unsigned char * pFileName,
- unsigned long fileSize)
+int
+KfwumSetupBuffersFromFile(const char *pFileName, unsigned long fileSize)
{
- tKFWUM_Status status = KFWUM_STATUS_ERROR;
+ int rc = (-1);
FILE *pFileHandle = NULL;
int count;
int modulus;
int qty = 0;
- pFileHandle = fopen((const char *)pFileName, "rb");
+ pFileHandle = fopen(pFileName, "rb");
if (pFileHandle == NULL) {
lprintf(LOG_ERR, "Failed to open '%s' for reading.",
- (char *)pFileName);
- return KFWUM_STATUS_ERROR;
+ pFileName);
+ return (-1);
}
count = fileSize / MAX_BUFFER_SIZE;
modulus = fileSize % MAX_BUFFER_SIZE;
rewind(pFileHandle);
- for (qty=0; qty < count; qty++) {
- KfwumShowProgress((const unsigned char *)"Reading Firmware from File",
+ for (qty = 0; qty < count; qty++) {
+ KfwumShowProgress("Reading Firmware from File",
qty, count);
if (fread(&firmBuf[qty * MAX_BUFFER_SIZE], 1,
MAX_BUFFER_SIZE,
pFileHandle) == MAX_BUFFER_SIZE) {
- status = KFWUM_STATUS_OK;
+ rc = 0;
}
}
if (modulus) {
if (fread(&firmBuf[qty * MAX_BUFFER_SIZE], 1,
modulus, pFileHandle) == modulus) {
- status = KFWUM_STATUS_OK;
+ rc = 0;
}
}
- if (status == KFWUM_STATUS_OK) {
- KfwumShowProgress((const unsigned char *)"Reading Firmware from File",
- 100, 100);
+ if (rc == 0) {
+ KfwumShowProgress("Reading Firmware from File", 100, 100);
}
fclose(pFileHandle);
- return status;
+ return rc;
}
/* KfwumShowProgress - helper routine to display progress bar
*
* Converts current/total in percent
- *
+ *
* *task : string identifying current operation
* current: progress
- * total : limit
+ * total : limit
*/
-#define PROG_LENGTH 42
-void KfwumShowProgress( const unsigned char * task, unsigned long current ,
- unsigned long total)
+void
+KfwumShowProgress(const char *task, unsigned long current, unsigned long total)
{
- static unsigned long staticProgress=0xffffffff;
-
- unsigned char spaces[PROG_LENGTH + 1];
- unsigned short hash;
- float percent = ((float)current/total);
- unsigned long progress = 100*(percent);
-
- if(staticProgress == progress)
- {
- /* We displayed the same last time.. so don't do it */
- }
- else
- {
- staticProgress = progress;
-
-
- printf("%-25s : ",task); /* total 20 bytes */
-
- hash = ( percent * PROG_LENGTH );
- memset(spaces,'#', hash);
- spaces[ hash ] = '\0';
- printf("%s", spaces );
-
- memset(spaces,' ',( PROG_LENGTH - hash ) );
- spaces[ ( PROG_LENGTH - hash ) ] = '\0';
- printf("%s", spaces );
-
-
- printf(" %3ld %%\r",progress); /* total 7 bytes */
-
- if( progress == 100 )
- {
- printf("\n");
- }
- fflush(stdout);
- }
+# define PROG_LENGTH 42
+ static unsigned long staticProgress=0xffffffff;
+ unsigned char spaces[PROG_LENGTH + 1];
+ unsigned short hash;
+ float percent = ((float)current / total);
+ unsigned long progress = 100 * (percent);
+
+ if (staticProgress == progress) {
+ /* We displayed the same last time.. so don't do it */
+ return;
+ }
+ staticProgress = progress;
+ printf("%-25s : ", task); /* total 20 bytes */
+ hash = (percent * PROG_LENGTH);
+ memset(spaces, '#', hash);
+ spaces[hash] = '\0';
+
+ printf("%s", spaces);
+ memset(spaces, ' ', (PROG_LENGTH - hash));
+ spaces[(PROG_LENGTH - hash)] = '\0';
+ printf("%s", spaces );
+
+ printf(" %3ld %%\r", progress); /* total 7 bytes */
+ if (progress == 100) {
+ printf("\n");
+ }
+ fflush(stdout);
}
-/* KfwumCalculateChecksumPadding
- *
- * TBD
- *
+/* KfwumCalculateChecksumPadding - TBD
*/
-static unsigned short KfwumCalculateChecksumPadding(unsigned char * pBuffer,
- unsigned long totalSize)
+unsigned short
+KfwumCalculateChecksumPadding(unsigned char *pBuffer, unsigned long totalSize)
{
- unsigned short sumOfBytes = 0;
- unsigned short padding;
- unsigned long counter;
-
- for(counter = 0; counter < totalSize; counter ++ )
- {
- sumOfBytes += pBuffer[counter];
- }
-
- padding = 0 - sumOfBytes;
- return padding;
+ unsigned short sumOfBytes = 0;
+ unsigned short padding;
+ unsigned long counter;
+ for (counter = 0; counter < totalSize; counter ++) {
+ sumOfBytes += pBuffer[counter];
+ }
+ padding = 0 - sumOfBytes;
+ return padding;
}
-/******************************************************************************
-******************************* COMMANDS **************************************
-******************************************************************************/
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct KfwumGetInfoResp {
- unsigned char protocolRevision;
- unsigned char controllerDeviceId;
- struct
- {
- unsigned char mode:1;
- unsigned char seqAdd:1;
- unsigned char res : 6;
- } byte;
- unsigned char firmRev1;
- unsigned char firmRev2;
- unsigned char numBank;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-
-
/* KfwumGetInfo - Get Firmware Update Manager (FWUM) information
- *
- * * intf : IPMI interface
+ *
+ * *intf : IPMI interface
* output : when set to non zero, queried information is displayed
* pNumBank: output ptr for number of banks
+ *
+ * returns 0 on success, otherwise (-1)
*/
-static tKFWUM_Status KfwumGetInfo(struct ipmi_intf * intf, unsigned char output,
- unsigned char *pNumBank)
+int
+KfwumGetInfo(struct ipmi_intf *intf, unsigned char output,
+ unsigned char *pNumBank)
{
- tKFWUM_Status status = KFWUM_STATUS_OK;
- static struct KfwumGetInfoResp *pGetInfo;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_FIRMWARE;
- req.msg.cmd = KFWUM_CMD_ID_GET_FIRMWARE_INFO;
- req.msg.data_len = 0;
-
- rsp = intf->sendrecv(intf, &req);
-
- if (!rsp)
- {
- printf("Error in FWUM Firmware Get Info Command\n");
- status = KFWUM_STATUS_ERROR;
- }
- else if (rsp->ccode)
- {
- printf("FWUM Firmware Get Info returned %x\n", rsp->ccode);
- status = KFWUM_STATUS_ERROR;
- }
-
- if(status == KFWUM_STATUS_OK)
- {
- pGetInfo = (struct KfwumGetInfoResp *) rsp->data;
- if(output)
- {
- printf("\nFWUM info\n");
- printf("=========\n");
- printf("Protocol Revision : %02Xh\n",
- pGetInfo->protocolRevision);
- printf("Controller Device Id : %02Xh\n",
- pGetInfo->controllerDeviceId);
- printf("Firmware Revision : %u.%u%u",
- pGetInfo->firmRev1, pGetInfo->firmRev2 >> 4,
- pGetInfo->firmRev2 & 0x0f);
- if(pGetInfo->byte.mode != 0)
- {
- printf(" - DEBUG BUILD\n");
- }
- else
- {
- printf("\n");
- }
- printf("Number Of Memory Bank : %u\n",pGetInfo->numBank);
- }
- * pNumBank = pGetInfo->numBank;
-
- /* Determine wich type of download to use: */
- /* Old FWUM or Old IPMC fw (data_len < 7) -->
- Address with small buffer size */
- if ( (pGetInfo->protocolRevision) <= 0x05 || (rsp->data_len < 7 ) )
- {
- saveFirmwareInfo.downloadType = KFWUM_DOWNLOAD_TYPE_ADDRESS;
- saveFirmwareInfo.bufferSize = KFWUM_SMALL_BUFFER;
- saveFirmwareInfo.overheadSize = KFWUM_OLD_CMD_OVERHEAD;
-
- if(verbose)
- {
- printf("Protocol Revision :");
- printf(" <= 5 detected, adjusting buffers\n");
- }
- }
- else /* Both fw are using the new protocol */
- {
- saveFirmwareInfo.downloadType = KFWUM_DOWNLOAD_TYPE_SEQUENCE;
- saveFirmwareInfo.overheadSize = KFWUM_NEW_CMD_OVERHEAD;
- /* Buffer size depending on access type (Local or remote) */
- /* Look if we run remote or locally */
-
- if(verbose)
- {
- printf("Protocol Revision :");
- printf(" > 5 optimizing buffers\n");
- }
-
- if(strstr(intf->name,"lan")!= NULL) /* also covers lanplus */
- {
- saveFirmwareInfo.bufferSize = KFWUM_SMALL_BUFFER;
- if(verbose)
- {
- printf("IOL payload size : %d\n" ,
- saveFirmwareInfo.bufferSize);
- }
- }
- else if
- (
- (strstr(intf->name,"open")!= NULL)
- &&
- intf->target_addr != IPMI_BMC_SLAVE_ADDR
- &&
- (
- intf->target_addr != intf->my_addr
- )
- )
- {
- saveFirmwareInfo.bufferSize = KFWUM_SMALL_BUFFER;
- if(verbose)
- {
- printf("IPMB payload size : %d\n" ,
- saveFirmwareInfo.bufferSize);
- }
- }
- else
- {
- saveFirmwareInfo.bufferSize = KFWUM_BIG_BUFFER;
- if(verbose)
- {
- printf("SMI payload size : %d\n",
- saveFirmwareInfo.bufferSize);
- }
- }
- }
- }
- return status;
+ int rc = 0;
+ static struct KfwumGetInfoResp *pGetInfo;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_FIRMWARE;
+ req.msg.cmd = KFWUM_CMD_ID_GET_FIRMWARE_INFO;
+ req.msg.data_len = 0;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (!rsp) {
+ lprintf(LOG_ERR, "Error in FWUM Firmware Get Info Command.");
+ return (-1);
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "FWUM Firmware Get Info returned %x",
+ rsp->ccode);
+ return (-1);
+ }
+
+ pGetInfo = (struct KfwumGetInfoResp *)rsp->data;
+ if (output) {
+ printf("\nFWUM info\n");
+ printf("=========\n");
+ printf("Protocol Revision : %02Xh\n",
+ pGetInfo->protocolRevision);
+ printf("Controller Device Id : %02Xh\n",
+ pGetInfo->controllerDeviceId);
+ printf("Firmware Revision : %u.%u%u",
+ pGetInfo->firmRev1, pGetInfo->firmRev2 >> 4,
+ pGetInfo->firmRev2 & 0x0f);
+ if (pGetInfo->byte.mode != 0) {
+ printf(" - DEBUG BUILD\n");
+ } else {
+ printf("\n");
+ }
+ printf("Number Of Memory Bank : %u\n", pGetInfo->numBank);
+ }
+ *pNumBank = pGetInfo->numBank;
+ /* Determine wich type of download to use: */
+ /* Old FWUM or Old IPMC fw (data_len < 7)
+ * --> Address with small buffer size
+ */
+ if ((pGetInfo->protocolRevision) <= 0x05 || (rsp->data_len < 7 )) {
+ save_fw_nfo.downloadType = KFWUM_DOWNLOAD_TYPE_ADDRESS;
+ save_fw_nfo.bufferSize = KFWUM_SMALL_BUFFER;
+ save_fw_nfo.overheadSize = KFWUM_OLD_CMD_OVERHEAD;
+ if (verbose) {
+ printf("Protocol Revision :");
+ printf(" <= 5 detected, adjusting buffers\n");
+ }
+ } else {
+ /* Both fw are using the new protocol */
+ save_fw_nfo.downloadType = KFWUM_DOWNLOAD_TYPE_SEQUENCE;
+ save_fw_nfo.overheadSize = KFWUM_NEW_CMD_OVERHEAD;
+ /* Buffer size depending on access type (Local or remote) */
+ /* Look if we run remote or locally */
+ if (verbose) {
+ printf("Protocol Revision :");
+ printf(" > 5 optimizing buffers\n");
+ }
+ if (strstr(intf->name,"lan") != NULL) {
+ /* also covers lanplus */
+ save_fw_nfo.bufferSize = KFWUM_SMALL_BUFFER;
+ if (verbose) {
+ printf("IOL payload size : %d\n",
+ save_fw_nfo.bufferSize);
+ }
+ } else if ((strstr(intf->name,"open")!= NULL)
+ && intf->target_addr != IPMI_BMC_SLAVE_ADDR
+ && (intf->target_addr != intf->my_addr)) {
+ save_fw_nfo.bufferSize = KFWUM_SMALL_BUFFER;
+ if (verbose) {
+ printf("IPMB payload size : %d\n",
+ save_fw_nfo.bufferSize);
+ }
+ } else {
+ save_fw_nfo.bufferSize = KFWUM_BIG_BUFFER;
+ if (verbose) {
+ printf("SMI payload size : %d\n",
+ save_fw_nfo.bufferSize);
+ }
+ }
+ }
+ return rc;
}
-/* KfwumGetDeviceInfo - Get IPMC/Board information
- *
- * * intf : IPMI interface
- * output : when set to non zero, queried information is displayed
+/* KfwumGetDeviceInfo - Get IPMC/Board information
+ *
+ * *intf: IPMI interface
+ * output: when set to non zero, queried information is displayed
* tKFWUM_BoardInfo: output ptr for IPMC/Board information
+ *
+ * returns 0 on success, otherwise (-1)
*/
-static tKFWUM_Status KfwumGetDeviceInfo(struct ipmi_intf * intf,
- unsigned char output, tKFWUM_BoardInfo * pBoardInfo)
+int
+KfwumGetDeviceInfo(struct ipmi_intf *intf, unsigned char output,
+ tKFWUM_BoardInfo *pBoardInfo)
{
- struct ipm_devid_rsp *pGetDevId;
- tKFWUM_Status status = KFWUM_STATUS_OK;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
-
- /* Send Get Device Id */
- if(status == KFWUM_STATUS_OK)
- {
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_APP;
- req.msg.cmd = BMC_GET_DEVICE_ID;
- req.msg.data_len = 0;
-
- rsp = intf->sendrecv(intf, &req);
- if (!rsp)
- {
- printf("Error in Get Device Id Command\n");
- status = KFWUM_STATUS_ERROR;
- }
- else if (rsp->ccode)
- {
- printf("Get Device Id returned %x\n", rsp->ccode);
- status = KFWUM_STATUS_ERROR;
- }
- }
-
- if(status == KFWUM_STATUS_OK)
- {
- pGetDevId = (struct ipm_devid_rsp *) rsp->data;
- pBoardInfo->iana = IPM_DEV_MANUFACTURER_ID(pGetDevId->manufacturer_id);
- pBoardInfo->boardId = buf2short(pGetDevId->product_id);
- if(output)
- {
- printf("\nIPMC Info\n");
- printf("=========\n");
- printf("Manufacturer Id : %u\n",pBoardInfo->iana);
- printf("Board Id : %u\n",pBoardInfo->boardId);
- printf("Firmware Revision : %u.%u%u",
- pGetDevId->fw_rev1, pGetDevId->fw_rev2 >> 4,
- pGetDevId->fw_rev2 & 0x0f);
- if(
- (
- ( pBoardInfo->iana == KFWUM_IANA_KONTRON)
- &&
- (pBoardInfo->boardId = KFWUM_BOARD_KONTRON_5002)
- )
- )
- {
- printf(" SDR %u\n", pGetDevId->aux_fw_rev[0]);
- }
- else
- {
- printf("\n");
- }
- }
- }
-
- return status;
+ struct ipm_devid_rsp *pGetDevId;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ /* Send Get Device Id */
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_APP;
+ req.msg.cmd = BMC_GET_DEVICE_ID;
+ req.msg.data_len = 0;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Error in Get Device Id Command");
+ return (-1);
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Get Device Id returned %x",
+ rsp->ccode);
+ return (-1);
+ }
+ pGetDevId = (struct ipm_devid_rsp *)rsp->data;
+ pBoardInfo->iana = IPM_DEV_MANUFACTURER_ID(pGetDevId->manufacturer_id);
+ pBoardInfo->boardId = buf2short(pGetDevId->product_id);
+ if (output) {
+ printf("\nIPMC Info\n");
+ printf("=========\n");
+ printf("Manufacturer Id : %u\n",
+ pBoardInfo->iana);
+ printf("Board Id : %u\n",
+ pBoardInfo->boardId);
+ printf("Firmware Revision : %u.%u%u",
+ pGetDevId->fw_rev1, pGetDevId->fw_rev2 >> 4,
+ pGetDevId->fw_rev2 & 0x0f);
+ if (((pBoardInfo->iana == IPMI_OEM_KONTRON)
+ && (pBoardInfo->boardId = KFWUM_BOARD_KONTRON_5002))) {
+ printf(" SDR %u", pGetDevId->aux_fw_rev[0]);
+ }
+ printf("\n");
+ }
+ return 0;
}
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct KfwumGetStatusResp {
- unsigned char bankState;
- unsigned char firmLengthLSB;
- unsigned char firmLengthMid;
- unsigned char firmLengthMSB;
- unsigned char firmRev1;
- unsigned char firmRev2;
- unsigned char firmRev3;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-
-const struct valstr bankStateValS[] = {
- { 0x00, "Not programmed" },
- { 0x01, "New firmware" },
- { 0x02, "Wait for validation" },
- { 0x03, "Last Known Good" },
- { 0x04, "Previous Good" }
-};
-
/* KfwumGetStatus - Get (and prints) FWUM banks information
- *
- * * intf : IPMI interface
+ *
+ * *intf : IPMI interface
+ *
+ * returns 0 on success, otherwise (-1)
*/
-static tKFWUM_Status KfwumGetStatus(struct ipmi_intf * intf)
+int
+KfwumGetStatus(struct ipmi_intf * intf)
{
- tKFWUM_Status status = KFWUM_STATUS_OK;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- struct KfwumGetStatusResp *pGetStatus;
- unsigned char numBank;
- unsigned char counter;
-
- if(verbose)
- {
- printf(" Getting Status!\n");
- }
-
- /* Retreive the number of bank */
- status = KfwumGetInfo(intf, 0, &numBank);
-
- for(
- counter = 0;
- (counter < numBank) && (status == KFWUM_STATUS_OK);
- counter ++
- )
- {
- /* Retreive the status of each bank */
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_FIRMWARE;
- req.msg.cmd = KFWUM_CMD_ID_GET_FIRMWARE_STATUS;
- req.msg.data = &counter;
- req.msg.data_len = 1;
-
- rsp = intf->sendrecv(intf, &req);
-
- if (!rsp)
- {
- printf("Error in FWUM Firmware Get Status Command\n");
- status = KFWUM_STATUS_ERROR;
- }
- else if (rsp->ccode)
- {
- printf("FWUM Firmware Get Status returned %x\n", rsp->ccode);
- status = KFWUM_STATUS_ERROR;
- }
-
-
- if(status == KFWUM_STATUS_OK)
- {
- pGetStatus = (struct KfwumGetStatusResp *) rsp->data;
- printf("\nBank State %d : %s\n", counter, val2str(
- pGetStatus->bankState, bankStateValS));
- if(pGetStatus->bankState)
- {
- unsigned long firmLength;
- firmLength = pGetStatus->firmLengthMSB;
- firmLength = firmLength << 8;
- firmLength |= pGetStatus->firmLengthMid;
- firmLength = firmLength << 8;
- firmLength |= pGetStatus->firmLengthLSB;
-
- printf("Firmware Length : %ld bytes\n", firmLength);
- printf("Firmware Revision : %u.%u%u SDR %u\n",
- pGetStatus->firmRev1, pGetStatus->firmRev2 >> 4,
- pGetStatus->firmRev2 & 0x0f, pGetStatus->firmRev3);
- }
- }
- }
- printf("\n");
- return status;
+ int rc = 0;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ struct KfwumGetStatusResp *pGetStatus;
+ unsigned char numBank;
+ unsigned char counter;
+ unsigned long firmLength;
+ if (verbose) {
+ printf(" Getting Status!\n");
+ }
+ /* Retreive the number of bank */
+ rc = KfwumGetInfo(intf, 0, &numBank);
+ for(counter = 0;
+ (counter < numBank) && (rc == 0);
+ counter ++) {
+ /* Retreive the status of each bank */
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_FIRMWARE;
+ req.msg.cmd = KFWUM_CMD_ID_GET_FIRMWARE_STATUS;
+ req.msg.data = &counter;
+ req.msg.data_len = 1;
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR,
+ "Error in FWUM Firmware Get Status Command.");
+ rc = (-1);
+ break;
+ } else if (rsp->ccode) {
+ lprintf(LOG_ERR,
+ "FWUM Firmware Get Status returned %x",
+ rsp->ccode);
+ rc = (-1);
+ break;
+ }
+ pGetStatus = (struct KfwumGetStatusResp *) rsp->data;
+ printf("\nBank State %d : %s\n",
+ counter,
+ val2str(pGetStatus->bankState, bankStateValS));
+ if (!pGetStatus->bankState) {
+ continue;
+ }
+ firmLength = pGetStatus->firmLengthMSB;
+ firmLength = firmLength << 8;
+ firmLength |= pGetStatus->firmLengthMid;
+ firmLength = firmLength << 8;
+ firmLength |= pGetStatus->firmLengthLSB;
+ printf("Firmware Length : %ld bytes\n",
+ firmLength);
+ printf("Firmware Revision : %u.%u%u SDR %u\n",
+ pGetStatus->firmRev1,
+ pGetStatus->firmRev2 >> 4,
+ pGetStatus->firmRev2 & 0x0f,
+ pGetStatus->firmRev3);
+ }
+ printf("\n");
+ return rc;
}
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct KfwumManualRollbackReq{
- unsigned char type;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-
/* KfwumManualRollback - Ask IPMC to rollback to previous version
- *
- * * intf : IPMI interface
+ *
+ * *intf : IPMI interface
+ *
+ * returns 0 on success
+ * returns (-1) on error
*/
-static tKFWUM_Status KfwumManualRollback(struct ipmi_intf * intf)
+int
+KfwumManualRollback(struct ipmi_intf *intf)
{
- tKFWUM_Status status = KFWUM_STATUS_OK;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- struct KfwumManualRollbackReq thisReq;
-
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_FIRMWARE;
- req.msg.cmd = KFWUM_CMD_ID_MANUAL_ROLLBACK;
-
- thisReq.type = 0; /* Wait BMC shutdown */
-
- req.msg.data = (unsigned char *) &thisReq;
- req.msg.data_len = 1;
-
- rsp = intf->sendrecv(intf, &req);
-
- if (!rsp)
- {
- printf("Error in FWUM Manual Rollback Command\n");
- status = KFWUM_STATUS_ERROR;
- }
- else if (rsp->ccode)
- {
- printf("Error in FWUM Manual Rollback Command returned %x\n",
- rsp->ccode);
- status = KFWUM_STATUS_ERROR;
- }
-
- if(status == KFWUM_STATUS_OK)
- {
- printf("FWUM Starting Manual Rollback \n");
- }
- return status;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ struct KfwumManualRollbackReq thisReq;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_FIRMWARE;
+ req.msg.cmd = KFWUM_CMD_ID_MANUAL_ROLLBACK;
+ thisReq.type = 0; /* Wait BMC shutdown */
+ req.msg.data = (unsigned char *)&thisReq;
+ req.msg.data_len = 1;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Error in FWUM Manual Rollback Command.");
+ return (-1);
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR,
+ "Error in FWUM Manual Rollback Command returned %x",
+ rsp->ccode);
+ return (-1);
+ }
+ printf("FWUM Starting Manual Rollback \n");
+ return 0;
}
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct KfwumStartFirmwareDownloadReq{
- unsigned char lengthLSB;
- unsigned char lengthMid;
- unsigned char lengthMSB;
- unsigned char paddingLSB;
- unsigned char paddingMSB;
- unsigned char useSequence;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct KfwumStartFirmwareDownloadResp {
- unsigned char bank;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-static tKFWUM_Status KfwumStartFirmwareImage(struct ipmi_intf * intf,
- unsigned long length,unsigned short padding)
+int
+KfwumStartFirmwareImage(struct ipmi_intf *intf, unsigned long length,
+ unsigned short padding)
{
- tKFWUM_Status status = KFWUM_STATUS_OK;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- struct KfwumStartFirmwareDownloadResp *pResp;
- struct KfwumStartFirmwareDownloadReq thisReq;
-
- thisReq.lengthLSB = length & 0x000000ff;
- thisReq.lengthMid = (length >> 8) & 0x000000ff;
- thisReq.lengthMSB = (length >> 16) & 0x000000ff;
- thisReq.paddingLSB = padding & 0x00ff;
- thisReq.paddingMSB = (padding>> 8) & 0x00ff;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ struct KfwumStartFirmwareDownloadResp *pResp;
+ struct KfwumStartFirmwareDownloadReq thisReq;
+
+ thisReq.lengthLSB = length & 0x000000ff;
+ thisReq.lengthMid = (length >> 8) & 0x000000ff;
+ thisReq.lengthMSB = (length >> 16) & 0x000000ff;
+ thisReq.paddingLSB = padding & 0x00ff;
+ thisReq.paddingMSB = (padding>> 8) & 0x00ff;
thisReq.useSequence = 0x01;
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_FIRMWARE;
- req.msg.cmd = KFWUM_CMD_ID_START_FIRMWARE_IMAGE;
- req.msg.data = (unsigned char *) &thisReq;
-
- /* Look for download type */
- if ( saveFirmwareInfo.downloadType == KFWUM_DOWNLOAD_TYPE_ADDRESS )
- {
- req.msg.data_len = 5;
- }
- else
- {
- req.msg.data_len = 6;
- }
-
- rsp = intf->sendrecv(intf, &req);
-
- if (!rsp)
- {
- printf("Error in FWUM Firmware Start Firmware Image Download Command\n");
- status = KFWUM_STATUS_ERROR;
- }
- else if (rsp->ccode)
- {
- printf("FWUM Firmware Start Firmware Image Download returned %x\n",
- rsp->ccode);
- status = KFWUM_STATUS_ERROR;
- }
-
- if(status == KFWUM_STATUS_OK)
- {
- pResp = (struct KfwumStartFirmwareDownloadResp *) rsp->data;
- printf("Bank holding new firmware : %d\n", pResp->bank);
- sleep(5);
- }
- return status;
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_FIRMWARE;
+ req.msg.cmd = KFWUM_CMD_ID_START_FIRMWARE_IMAGE;
+ req.msg.data = (unsigned char *) &thisReq;
+ /* Look for download type */
+ if (save_fw_nfo.downloadType == KFWUM_DOWNLOAD_TYPE_ADDRESS) {
+ req.msg.data_len = 5;
+ } else {
+ req.msg.data_len = 6;
+ }
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR,
+ "Error in FWUM Firmware Start Firmware Image Download Command.");
+ return (-1);
+ } else if (rsp->ccode) {
+ lprintf(LOG_ERR,
+ "FWUM Firmware Start Firmware Image Download returned %x",
+ rsp->ccode);
+ return (-1);
+ }
+ pResp = (struct KfwumStartFirmwareDownloadResp *)rsp->data;
+ printf("Bank holding new firmware : %d\n", pResp->bank);
+ sleep(5);
+ return 0;
}
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct KfwumSaveFirmwareAddressReq
+int
+KfwumSaveFirmwareImage(struct ipmi_intf *intf, unsigned char sequenceNumber,
+ unsigned long address, unsigned char *pFirmBuf,
+ unsigned char *pInBufLength)
{
- unsigned char addressLSB;
- unsigned char addressMid;
- unsigned char addressMSB;
- unsigned char numBytes;
- unsigned char txBuf[KFWUM_SMALL_BUFFER-KFWUM_OLD_CMD_OVERHEAD];
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct KfwumSaveFirmwareSequenceReq
-{
- unsigned char sequenceNumber;
- unsigned char txBuf[KFWUM_BIG_BUFFER];
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-
-#define FWUM_SAVE_FIRMWARE_NO_RESPONSE_LIMIT ((unsigned char)6)
+ int rc = 0;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ struct KfwumSaveFirmwareAddressReq addr_req;
+ struct KfwumSaveFirmwareSequenceReq seq_req;
+ int retry = 0;
+ int no_rsp = 0;
+ do {
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_FIRMWARE;
+ req.msg.cmd = KFWUM_CMD_ID_SAVE_FIRMWARE_IMAGE;
+ if (save_fw_nfo.downloadType == KFWUM_DOWNLOAD_TYPE_ADDRESS) {
+ addr_req.addressLSB = address & 0x000000ff;
+ addr_req.addressMid = (address >> 8) & 0x000000ff;
+ addr_req.addressMSB = (address >> 16) & 0x000000ff;
+ addr_req.numBytes = *pInBufLength;
+ memcpy(addr_req.txBuf, pFirmBuf, *pInBufLength);
+ req.msg.data = (unsigned char *)&addr_req;
+ req.msg.data_len = *pInBufLength + 4;
+ } else {
+ seq_req.sequenceNumber = sequenceNumber;
+ memcpy(seq_req.txBuf, pFirmBuf, *pInBufLength);
+ req.msg.data = (unsigned char *)&seq_req;
+ req.msg.data_len = *pInBufLength + sizeof(unsigned char);
+ /* + 1 => sequenceNumber*/
+ }
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR,
+ "Error in FWUM Firmware Save Firmware Image Download Command.");
+ /* We don't receive "C7" on errors with IOL,
+ * instead we receive nothing
+ */
+ if (strstr(intf->name, "lan") != NULL) {
+ no_rsp++;
+ if (no_rsp < FWUM_SAVE_FIRMWARE_NO_RESPONSE_LIMIT) {
+ *pInBufLength -= 1;
+ continue;
+ }
+ lprintf(LOG_ERR,
+ "Error, too many commands without response.");
+ *pInBufLength = 0;
+ break;
+ } /* For other interface keep trying */
+ } else if (rsp->ccode != 0) {
+ if (rsp->ccode == 0xc0) {
+ sleep(1);
+ } else if ((rsp->ccode == 0xc7)
+ || ((rsp->ccode == 0xc3)
+ && (sequenceNumber == 0))) {
+ *pInBufLength -= 1;
+ retry = 1;
+ } else if (rsp->ccode == 0x82) {
+ /* Double sent, continue */
+ rc = 0;
+ break;
+ } else if (rsp->ccode == 0x83) {
+ if (retry == 0) {
+ retry = 1;
+ continue;
+ }
+ rc = (-1);
+ break;
+ } else if (rsp->ccode == 0xcf) {
+ /* Ok if receive duplicated request */
+ retry = 1;
+ } else if (rsp->ccode == 0xc3) {
+ if (retry == 0) {
+ retry = 1;
+ continue;
+ }
+ rc = (-1);
+ break;
+ } else {
+ lprintf(LOG_ERR,
+ "FWUM Firmware Save Firmware Image Download returned %x",
+ rsp->ccode);
+ rc = (-1);
+ break;
+ }
+ } else {
+ break;
+ }
+ } while (1);
+ return rc;
+}
-static tKFWUM_Status KfwumSaveFirmwareImage(struct ipmi_intf * intf,
- unsigned char sequenceNumber, unsigned long address, unsigned char *pFirmBuf,
- unsigned char * pInBufLength)
+int
+KfwumFinishFirmwareImage(struct ipmi_intf *intf, tKFWUM_InFirmwareInfo firmInfo)
{
- tKFWUM_Status status = KFWUM_STATUS_OK;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- unsigned char out = 0;
- unsigned char retry = 0;
- unsigned char noResponse = 0 ;
-
- struct KfwumSaveFirmwareAddressReq addressReq;
- struct KfwumSaveFirmwareSequenceReq sequenceReq;
-
- do
- {
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_FIRMWARE;
- req.msg.cmd = KFWUM_CMD_ID_SAVE_FIRMWARE_IMAGE;
-
- if (saveFirmwareInfo.downloadType == KFWUM_DOWNLOAD_TYPE_ADDRESS )
- {
- addressReq.addressLSB = address & 0x000000ff;
- addressReq.addressMid = (address >> 8) & 0x000000ff;
- addressReq.addressMSB = (address >> 16) & 0x000000ff;
- addressReq.numBytes = (* pInBufLength);
- memcpy(addressReq.txBuf, pFirmBuf, (* pInBufLength));
- req.msg.data = (unsigned char *) &addressReq;
- req.msg.data_len = (* pInBufLength)+4;
- }
- else
- {
- sequenceReq.sequenceNumber = sequenceNumber;
- memcpy(sequenceReq.txBuf, pFirmBuf, (* pInBufLength));
- req.msg.data = (unsigned char *) &sequenceReq;
- req.msg.data_len = (* pInBufLength)+sizeof(unsigned char); /* + 1 => sequenceNumber*/
- }
-
- rsp = intf->sendrecv(intf, &req);
-
- if (!rsp)
- {
- printf("Error in FWUM Firmware Save Firmware Image Download Command\n");
-
- out = 0;
- status = KFWUM_STATUS_OK;
-
- /* With IOL, we don't receive "C7" on errors, instead we receive
- nothing */
- if(strstr(intf->name,"lan")!= NULL)
- {
- noResponse++;
-
- if(noResponse < FWUM_SAVE_FIRMWARE_NO_RESPONSE_LIMIT )
- {
- (* pInBufLength) -= 1;
- out = 0;
- }
- else
- {
- printf("Error, too many commands without response\n");
- (* pInBufLength) = 0 ;
- out = 1;
- }
- } /* For other interface keep trying */
- }
- else if (rsp->ccode)
- {
- if(rsp->ccode == 0xc0)
- {
- status = KFWUM_STATUS_OK;
- sleep(1);
- }
- else if(
- (rsp->ccode == 0xc7)
- ||
- (
- (rsp->ccode == 0xC3) &&
- (sequenceNumber == 0)
- )
- )
- {
- (* pInBufLength) -= 1;
- status = KFWUM_STATUS_OK;
- retry = 1;
- }
- else if(rsp->ccode == 0x82)
- {
- /* Double sent, continue */
- status = KFWUM_STATUS_OK;
- out = 1;
- }
- else if(rsp->ccode == 0x83)
- {
- if(retry == 0)
- {
- retry = 1;
- status = KFWUM_STATUS_OK;
- }
- else
- {
- status = KFWUM_STATUS_ERROR;
- out = 1;
- }
- }
- else if(rsp->ccode == 0xcf) /* Ok if receive duplicated request */
- {
- retry = 1;
- status = KFWUM_STATUS_OK;
- }
- else if(rsp->ccode == 0xC3)
- {
- if(retry == 0)
- {
- retry = 1;
- status = KFWUM_STATUS_OK;
- }
- else
- {
- status = KFWUM_STATUS_ERROR;
- out = 1;
- }
- }
- else
- {
- printf("FWUM Firmware Save Firmware Image Download returned %x\n",
- rsp->ccode);
- status = KFWUM_STATUS_ERROR;
- out = 1;
- }
- }
- else
- {
- out = 1;
- }
- }while(out == 0);
- return status;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ struct KfwumFinishFirmwareDownloadReq thisReq;
+
+ thisReq.versionMaj = firmInfo.versMajor;
+ thisReq.versionMinSub = ((firmInfo.versMinor <<4)
+ | firmInfo.versSubMinor);
+ thisReq.versionSdr = firmInfo.sdrRev;
+ thisReq.reserved = 0;
+ /* Byte 4 reserved, write 0 */
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_FIRMWARE;
+ req.msg.cmd = KFWUM_CMD_ID_FINISH_FIRMWARE_IMAGE;
+ req.msg.data = (unsigned char *)&thisReq;
+ req.msg.data_len = 4;
+ /* Infinite loop if BMC doesn't reply or replies 0xc0 every time. */
+ do {
+ rsp = intf->sendrecv(intf, &req);
+ } while (rsp == NULL || rsp->ccode == 0xc0);
+ if (!rsp) {
+ lprintf(LOG_ERR,
+ "Error in FWUM Firmware Finish Firmware Image Download Command.");
+ return (-1);
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR,
+ "FWUM Firmware Finish Firmware Image Download returned %x",
+ rsp->ccode);
+ return (-1);
+ }
+ return 0;
}
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct KfwumFinishFirmwareDownloadReq{
- unsigned char versionMaj;
- unsigned char versionMinSub;
- unsigned char versionSdr;
- unsigned char reserved;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-static tKFWUM_Status KfwumFinishFirmwareImage(struct ipmi_intf * intf,
- tKFWUM_InFirmwareInfo firmInfo)
+int
+KfwumUploadFirmware(struct ipmi_intf *intf, unsigned char *pBuffer,
+ unsigned long totalSize)
{
- tKFWUM_Status status = KFWUM_STATUS_OK;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- struct KfwumFinishFirmwareDownloadReq thisReq;
-
- thisReq.versionMaj = firmInfo.versMajor;
- thisReq.versionMinSub = ((firmInfo.versMinor <<4) | firmInfo.versSubMinor);
- thisReq.versionSdr = firmInfo.sdrRev;
- thisReq.reserved = 0;
- /* Byte 4 reserved, write 0 */
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_FIRMWARE;
- req.msg.cmd = KFWUM_CMD_ID_FINISH_FIRMWARE_IMAGE;
- req.msg.data = (unsigned char *) &thisReq;
- req.msg.data_len = 4;
-
- do
- {
- rsp = intf->sendrecv(intf, &req);
- }while (rsp == NULL || rsp->ccode == 0xc0);
-
- if (!rsp)
- {
- printf("Error in FWUM Firmware Finish Firmware Image Download Command\n");
- status = KFWUM_STATUS_ERROR;
- }
- else if (rsp->ccode)
- {
- printf("FWUM Firmware Finish Firmware Image Download returned %x\n",
- rsp->ccode);
- status = KFWUM_STATUS_ERROR;
- }
-
- return status;
+ int rc = (-1);
+ unsigned long address = 0x0;
+ unsigned char writeSize;
+ unsigned char oldWriteSize;
+ unsigned long lastAddress = 0;
+ unsigned char sequenceNumber = 0;
+ unsigned char retry = FWUM_MAX_UPLOAD_RETRY;
+ unsigned char isLengthValid = 1;
+ do {
+ writeSize = save_fw_nfo.bufferSize - save_fw_nfo.overheadSize;
+ /* Reach the end */
+ if (address + writeSize > totalSize) {
+ writeSize = (totalSize - address);
+ } else if (((address % KFWUM_PAGE_SIZE)
+ + writeSize) > KFWUM_PAGE_SIZE) {
+ /* Reach boundary end */
+ writeSize = (KFWUM_PAGE_SIZE - (address % KFWUM_PAGE_SIZE));
+ }
+ oldWriteSize = writeSize;
+ rc = KfwumSaveFirmwareImage(intf, sequenceNumber,
+ address, &pBuffer[address], &writeSize);
+ if ((rc != 0) && (retry-- != 0)) {
+ address = lastAddress;
+ rc = 0;
+ } else if ( writeSize == 0) {
+ rc = (-1);
+ } else {
+ if (writeSize != oldWriteSize) {
+ printf("Adjusting length to %d bytes \n",
+ writeSize);
+ save_fw_nfo.bufferSize -= (oldWriteSize - writeSize);
+ }
+ retry = FWUM_MAX_UPLOAD_RETRY;
+ lastAddress = address;
+ address+= writeSize;
+ }
+ if (rc == 0) {
+ if ((address % 1024) == 0) {
+ KfwumShowProgress("Writting Firmware in Flash",
+ address, totalSize);
+ }
+ sequenceNumber++;
+ }
+ } while ((rc == 0) && (address < totalSize));
+ if (rc == 0) {
+ KfwumShowProgress("Writting Firmware in Flash",
+ 100, 100);
+ }
+ return rc;
}
-
-#define FWUM_MAX_UPLOAD_RETRY 6
-static tKFWUM_Status KfwumUploadFirmware(struct ipmi_intf * intf,
- unsigned char * pBuffer, unsigned long totalSize)
+int
+KfwumStartFirmwareUpgrade(struct ipmi_intf *intf)
{
- tKFWUM_Status status = KFWUM_STATUS_ERROR;
- unsigned long address = 0x0;
- unsigned char writeSize;
- unsigned char oldWriteSize;
- unsigned long lastAddress = 0;
- unsigned char sequenceNumber = 0;
- unsigned char retry = FWUM_MAX_UPLOAD_RETRY;
- unsigned char isLengthValid = 1;
-
- do
- {
- writeSize = saveFirmwareInfo.bufferSize - saveFirmwareInfo.overheadSize;
-
- /* Reach the end */
- if( address + writeSize > totalSize )
- {
- writeSize = (totalSize - address);
- }
- /* Reach boundary end */
- else if(((address % KFWUM_PAGE_SIZE) + writeSize) > KFWUM_PAGE_SIZE)
- {
- writeSize = (KFWUM_PAGE_SIZE - (address % KFWUM_PAGE_SIZE));
- }
-
- oldWriteSize = writeSize;
- status = KfwumSaveFirmwareImage(intf, sequenceNumber, address,
- &pBuffer[address], &writeSize);
-
- if((status != KFWUM_STATUS_OK) && (retry-- != 0))
- {
- address = lastAddress;
- status = KFWUM_STATUS_OK;
- }
- else if( writeSize == 0 )
- {
- status = KFWUM_STATUS_ERROR;
- }
- else
- {
- if(writeSize != oldWriteSize)
- {
- printf("Adjusting length to %d bytes \n", writeSize);
- saveFirmwareInfo.bufferSize -= (oldWriteSize - writeSize);
- }
-
- retry = FWUM_MAX_UPLOAD_RETRY;
- lastAddress = address;
- address+= writeSize;
- }
-
- if(status == KFWUM_STATUS_OK)
- {
- if((address % 1024) == 0)
- {
- KfwumShowProgress((const unsigned char *)\
- "Writting Firmware in Flash",address,totalSize);
- }
- sequenceNumber++;
- }
-
- }while((status == KFWUM_STATUS_OK) && (address < totalSize ));
-
- if(status == KFWUM_STATUS_OK)
- {
- KfwumShowProgress((const unsigned char *)\
- "Writting Firmware in Flash", 100 , 100 );
- }
-
- return(status);
+ int rc = 0;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ /* Upgrade type, wait BMC shutdown */
+ unsigned char upgType = 0 ;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_FIRMWARE;
+ req.msg.cmd = KFWUM_CMD_ID_START_FIRMWARE_UPDATE;
+ req.msg.data = (unsigned char *) &upgType;
+ req.msg.data_len = 1;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR,
+ "Error in FWUM Firmware Start Firmware Upgrade Command");
+ rc = (-1);
+ } else if (rsp->ccode) {
+ if (rsp->ccode == 0xd5) {
+ lprintf(LOG_ERR,
+ "No firmware available for upgrade. Download Firmware first.");
+ } else {
+ lprintf(LOG_ERR,
+ "FWUM Firmware Start Firmware Upgrade returned %x",
+ rsp->ccode);
+ }
+ rc = (-1);
+ }
+ return rc;
}
-static tKFWUM_Status KfwumStartFirmwareUpgrade(struct ipmi_intf * intf)
+int
+KfwumGetTraceLog(struct ipmi_intf *intf)
{
- tKFWUM_Status status = KFWUM_STATUS_OK;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- unsigned char upgType = 0 ; /* Upgrade type, wait BMC shutdown */
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_FIRMWARE;
- req.msg.cmd = KFWUM_CMD_ID_START_FIRMWARE_UPDATE;
- req.msg.data = (unsigned char *) &upgType;
- req.msg.data_len = 1;
-
- rsp = intf->sendrecv(intf, &req);
-
- if (!rsp)
- {
- printf("Error in FWUM Firmware Start Firmware Upgrade Command\n");
- status = KFWUM_STATUS_ERROR;
- }
- else if (rsp->ccode)
- {
- if(rsp->ccode == 0xd5)
- {
- printf("No firmware available for upgrade. Download Firmware first\n");
- }
- else
- {
- printf("FWUM Firmware Start Firmware Upgrade returned %x\n",
- rsp->ccode);
- }
- status = KFWUM_STATUS_ERROR;
- }
-
- return status;
+ int rc = 0;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ unsigned char chunkIdx;
+ unsigned char cmdIdx;
+ if (verbose) {
+ printf(" Getting Trace Log!\n");
+ }
+ for (chunkIdx = 0;
+ (chunkIdx < TRACE_LOG_CHUNK_COUNT)
+ && (rc == 0);
+ chunkIdx++) {
+ /* Retreive each log chunk and print it */
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_FIRMWARE;
+ req.msg.cmd = KFWUM_CMD_ID_GET_TRACE_LOG;
+ req.msg.data = &chunkIdx;
+ req.msg.data_len = 1;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR,
+ "Error in FWUM Firmware Get Trace Log Command");
+ rc = (-1);
+ break;
+ } else if (rsp->ccode) {
+ lprintf(LOG_ERR,
+ "FWUM Firmware Get Trace Log returned %x",
+ rsp->ccode);
+ rc = (-1);
+ break;
+ }
+ for (cmdIdx=0; cmdIdx < TRACE_LOG_CHUNK_SIZE; cmdIdx++) {
+ /* Don't diplay commands with an invalid state */
+ if ((rsp->data[TRACE_LOG_ATT_COUNT * cmdIdx + 1] != 0)
+ && (rsp->data[TRACE_LOG_ATT_COUNT * cmdIdx] < KFWUM_CMD_ID_STD_MAX_CMD)) {
+ printf(" Cmd ID: %17s -- CmdState: %10s -- CompCode: %2x\n",
+ CMD_ID_STRING[rsp->data[TRACE_LOG_ATT_COUNT * cmdIdx]],
+ CMD_STATE_STRING[rsp->data[TRACE_LOG_ATT_COUNT * cmdIdx + 1]],
+ rsp->data[TRACE_LOG_ATT_COUNT * cmdIdx + 2]);
+ } else if ((rsp->data[TRACE_LOG_ATT_COUNT * cmdIdx + 1] != 0)
+ && (rsp->data[TRACE_LOG_ATT_COUNT*cmdIdx] >= KFWUM_CMD_ID_EXTENDED_CMD)) {
+ printf(" Cmd ID: %17s -- CmdState: %10s -- CompCode: %2x\n",
+ EXT_CMD_ID_STRING[rsp->data[TRACE_LOG_ATT_COUNT * cmdIdx] - KFWUM_CMD_ID_EXTENDED_CMD],
+ CMD_STATE_STRING[rsp->data[TRACE_LOG_ATT_COUNT * cmdIdx + 1]],
+ rsp->data[TRACE_LOG_ATT_COUNT * cmdIdx + 2]);
+ }
+ }
+ }
+ printf("\n");
+ return rc;
}
-#define TRACE_LOG_CHUNK_COUNT 7
-#define TRACE_LOG_CHUNK_SIZE 7
-#define TRACE_LOG_ATT_COUNT 3
-/* String table */
-/* Must match eFWUM_CmdId */
-static const char* CMD_ID_STRING[] = {
- "GetFwInfo",
- "KickWatchdog",
- "GetLastAnswer",
- "BootHandshake",
- "ReportStatus",
- "CtrlIPMBLine",
- "SetFwState",
- "GetFwStatus",
- "GetSpiMemStatus",
- "StartFwUpdate",
- "StartFwImage",
- "SaveFwImage",
- "FinishFwImage",
- "ReadFwImage",
- "ManualRollback",
- "GetTraceLog" };
-
-static const char* EXT_CMD_ID_STRING[] = {
- "FwUpgradeLock",
- "ProcessFwUpg",
- "ProcessFwRb",
- "WaitHSAfterUpg",
- "WaitFirstHSUpg",
- "FwInfoStateChange" };
-
-
-static const char* CMD_STATE_STRING[] = {
- "Invalid",
- "Begin",
- "Progress",
- "Completed" };
-
-
-static tKFWUM_Status KfwumGetTraceLog(struct ipmi_intf * intf)
+int
+KfwumGetInfoFromFirmware(unsigned char *pBuf, unsigned long bufSize,
+ tKFWUM_InFirmwareInfo *pInfo)
{
- tKFWUM_Status status = KFWUM_STATUS_OK;
- struct ipmi_rs *rsp;
- struct ipmi_rq req;
- unsigned char chunkIdx;
- unsigned char cmdIdx;
-
- if(verbose)
- {
- printf(" Getting Trace Log!\n");
- }
-
- for( chunkIdx = 0; (chunkIdx < TRACE_LOG_CHUNK_COUNT) && (status == KFWUM_STATUS_OK); chunkIdx++ )
- {
- /* Retreive each log chunk and print it */
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_FIRMWARE;
- req.msg.cmd = KFWUM_CMD_ID_GET_TRACE_LOG;
- req.msg.data = &chunkIdx;
- req.msg.data_len = 1;
-
- rsp = intf->sendrecv(intf, &req);
-
- if (!rsp)
- {
- printf("Error in FWUM Firmware Get Trace Log Command\n");
- status = KFWUM_STATUS_ERROR;
- }
- else if (rsp->ccode)
- {
- printf("FWUM Firmware Get Trace Log returned %x\n", rsp->ccode);
- status = KFWUM_STATUS_ERROR;
- }
-
- if(status == KFWUM_STATUS_OK)
- {
- for (cmdIdx=0; cmdIdx < TRACE_LOG_CHUNK_SIZE; cmdIdx++)
- {
- /* Don't diplay commands with an invalid state */
- if ( (rsp->data[TRACE_LOG_ATT_COUNT*cmdIdx+1] != 0) &&
- (rsp->data[TRACE_LOG_ATT_COUNT*cmdIdx] < KFWUM_CMD_ID_STD_MAX_CMD))
- {
- printf(" Cmd ID: %17s -- CmdState: %10s -- CompCode: %2x\n",
- CMD_ID_STRING[rsp->data[TRACE_LOG_ATT_COUNT*cmdIdx]],
- CMD_STATE_STRING[rsp->data[TRACE_LOG_ATT_COUNT*cmdIdx+1]],
- rsp->data[TRACE_LOG_ATT_COUNT*cmdIdx+2]);
- }
- else if ( (rsp->data[TRACE_LOG_ATT_COUNT*cmdIdx+1] != 0) &&
- (rsp->data[TRACE_LOG_ATT_COUNT*cmdIdx] >= KFWUM_CMD_ID_EXTENDED_CMD))
- {
- printf(" Cmd ID: %17s -- CmdState: %10s -- CompCode: %2x\n",
- EXT_CMD_ID_STRING[rsp->data[TRACE_LOG_ATT_COUNT*cmdIdx] - KFWUM_CMD_ID_EXTENDED_CMD],
- CMD_STATE_STRING[rsp->data[TRACE_LOG_ATT_COUNT*cmdIdx+1]],
- rsp->data[TRACE_LOG_ATT_COUNT*cmdIdx+2]);
- }
- }
- }
- }
- printf("\n");
- return status;
-}
+ unsigned long offset = 0;
+ if (bufSize < (IN_FIRMWARE_INFO_OFFSET_LOCATION + IN_FIRMWARE_INFO_SIZE)) {
+ return (-1);
+ }
+ offset = IN_FIRMWARE_INFO_OFFSET_LOCATION;
+ /* Now, fill the structure with read informations */
+ pInfo->checksum = (unsigned short)KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + 0 + IN_FIRMWARE_INFO_OFFSET_CHECKSUM ) << 8;
-/*******************************************************************************
-* Function Name: KfwumGetInfoFromFirmware
-*
-* Description: This function retreive from the firmare the following info :
-*
-* o Checksum
-* o File size (expected)
-* o Board Id
-* o Device Id
-*
-* Restriction: None
-*
-* Input: char * fileName - File to get info from
-*
-* Output: pInfo - container that will hold all the informations gattered.
-* see structure for all details
-*
-* Global: None
-*
-* Return: IFWU_SUCCESS - file ok
-* IFWU_ERROR - file error
-*
-*******************************************************************************/
-#define IN_FIRMWARE_INFO_OFFSET_LOCATION 0x5a0
-#define IN_FIRMWARE_INFO_SIZE 20
-#define IN_FIRMWARE_INFO_OFFSET_FILE_SIZE 0
-#define IN_FIRMWARE_INFO_OFFSET_CHECKSUM 4
-#define IN_FIRMWARE_INFO_OFFSET_BOARD_ID 6
-#define IN_FIRMWARE_INFO_OFFSET_DEVICE_ID 8
-#define IN_FIRMWARE_INFO_OFFSET_TABLE_VERSION 9
-#define IN_FIRMWARE_INFO_OFFSET_IMPLEMENT_REV 10
-#define IN_FIRMWARE_INFO_OFFSET_VERSION_MAJOR 11
-#define IN_FIRMWARE_INFO_OFFSET_VERSION_MINSUB 12
-#define IN_FIRMWARE_INFO_OFFSET_SDR_REV 13
-#define IN_FIRMWARE_INFO_OFFSET_IANA0 14
-#define IN_FIRMWARE_INFO_OFFSET_IANA1 15
-#define IN_FIRMWARE_INFO_OFFSET_IANA2 16
-
-#define KWUM_GET_BYTE_AT_OFFSET(pBuffer,os) pBuffer[os]
-
-tKFWUM_Status KfwumGetInfoFromFirmware(unsigned char * pBuf,
- unsigned long bufSize, tKFWUM_InFirmwareInfo * pInfo)
-{
- tKFWUM_Status status = KFWUM_STATUS_ERROR;
-
- if(bufSize >= (IN_FIRMWARE_INFO_OFFSET_LOCATION + IN_FIRMWARE_INFO_SIZE))
- {
- unsigned long offset = IN_FIRMWARE_INFO_OFFSET_LOCATION;
-
- /* Now, fill the structure with read informations */
- pInfo->checksum = (unsigned short)KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+0+IN_FIRMWARE_INFO_OFFSET_CHECKSUM ) << 8;
- pInfo->checksum |= (unsigned short)KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+1+IN_FIRMWARE_INFO_OFFSET_CHECKSUM );
-
-
- pInfo->sumToRemoveFromChecksum=
- KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_CHECKSUM);
-
- pInfo->sumToRemoveFromChecksum+=
- KWUM_GET_BYTE_AT_OFFSET(pBuf ,
- offset+IN_FIRMWARE_INFO_OFFSET_CHECKSUM+1);
-
- pInfo->fileSize =
- KWUM_GET_BYTE_AT_OFFSET(pBuf ,
- offset+IN_FIRMWARE_INFO_OFFSET_FILE_SIZE+0) << 24;
- pInfo->fileSize |=
- (unsigned long)KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_FILE_SIZE+1) << 16;
- pInfo->fileSize |=
- (unsigned long)KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_FILE_SIZE+2) << 8;
- pInfo->fileSize |=
- (unsigned long)KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_FILE_SIZE+3);
-
- pInfo->boardId =
- KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_BOARD_ID+0) << 8;
- pInfo->boardId |=
- KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_BOARD_ID+1);
-
- pInfo->deviceId =
- KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_DEVICE_ID);
-
- pInfo->tableVers =
- KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_TABLE_VERSION);
- pInfo->implRev =
- KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_IMPLEMENT_REV);
- pInfo->versMajor =
- (KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_VERSION_MAJOR)) & 0x0f;
- pInfo->versMinor =
- (KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_VERSION_MINSUB)>>4) & 0x0f;
- pInfo->versSubMinor =
- (KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_VERSION_MINSUB)) & 0x0f;
- pInfo->sdrRev =
- KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_SDR_REV);
- pInfo->iana =
- KWUM_GET_BYTE_AT_OFFSET(pBuf ,
- offset+IN_FIRMWARE_INFO_OFFSET_IANA2) << 16;
- pInfo->iana |=
- (unsigned long)KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_IANA1) << 8;
- pInfo->iana |=
- (unsigned long)KWUM_GET_BYTE_AT_OFFSET(pBuf,
- offset+IN_FIRMWARE_INFO_OFFSET_IANA0);
-
- KfwumFixTableVersionForOldFirmware(pInfo);
-
- status = KFWUM_STATUS_OK;
- }
- return(status);
-}
+ pInfo->checksum|= (unsigned short)KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + 1 + IN_FIRMWARE_INFO_OFFSET_CHECKSUM);
+ pInfo->sumToRemoveFromChecksum = KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_CHECKSUM);
-void KfwumFixTableVersionForOldFirmware(tKFWUM_InFirmwareInfo * pInfo)
-{
- switch(pInfo->boardId)
- {
- case KFWUM_BOARD_KONTRON_UNKNOWN:
- pInfo->tableVers = 0xff;
- break;
- default:
- /* pInfo->tableVers is already set for the right version */
- break;
- }
-}
+ pInfo->sumToRemoveFromChecksum+= KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_CHECKSUM + 1);
+
+ pInfo->fileSize = KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_FILE_SIZE + 0) << 24;
+
+ pInfo->fileSize|= (unsigned long)KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_FILE_SIZE + 1) << 16;
+
+ pInfo->fileSize|= (unsigned long)KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_FILE_SIZE + 2) << 8;
+
+ pInfo->fileSize|= (unsigned long)KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_FILE_SIZE + 3);
+
+ pInfo->boardId = KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_BOARD_ID + 0) << 8;
+ pInfo->boardId|= KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_BOARD_ID + 1);
-tKFWUM_Status KfwumValidFirmwareForBoard(tKFWUM_BoardInfo boardInfo,
- tKFWUM_InFirmwareInfo firmInfo)
+ pInfo->deviceId = KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_DEVICE_ID);
+
+ pInfo->tableVers = KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_TABLE_VERSION);
+
+ pInfo->implRev = KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_IMPLEMENT_REV);
+
+ pInfo->versMajor = (KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset
+ + IN_FIRMWARE_INFO_OFFSET_VER_MAJOROR)) & 0x0f;
+
+ pInfo->versMinor = (KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset
+ + IN_FIRMWARE_INFO_OFFSET_VER_MINORSUB) >> 4) & 0x0f;
+
+ pInfo->versSubMinor = (KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_VER_MINORSUB)) & 0x0f;
+
+ pInfo->sdrRev = KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_SDR_REV);
+
+ pInfo->iana = KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_IANA2) << 16;
+
+ pInfo->iana|= (unsigned long)KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_IANA1) << 8;
+
+ pInfo->iana|= (unsigned long)KWUM_GET_BYTE_AT_OFFSET(pBuf,
+ offset + IN_FIRMWARE_INFO_OFFSET_IANA0);
+
+ KfwumFixTableVersionForOldFirmware(pInfo);
+ return 0;
+}
+
+void
+KfwumFixTableVersionForOldFirmware(tKFWUM_InFirmwareInfo * pInfo)
{
- tKFWUM_Status status = KFWUM_STATUS_OK;
-
- if(boardInfo.iana != firmInfo.iana)
- {
- printf("Board IANA does not match firmware IANA\n");
- status = KFWUM_STATUS_ERROR;
- }
-
- if(boardInfo.boardId != firmInfo.boardId)
- {
- printf("Board IANA does not match firmware IANA\n");
- status = KFWUM_STATUS_ERROR;
- }
-
-
- if(status == KFWUM_STATUS_ERROR)
- {
- printf("Firmware invalid for target board. Download of upgrade aborted\n");
- }
- return status;
+ switch(pInfo->boardId) {
+ case KFWUM_BOARD_KONTRON_UNKNOWN:
+ pInfo->tableVers = 0xff;
+ break;
+ default:
+ /* pInfo->tableVers is already set for
+ * the right version
+ */
+ break;
+ }
}
+/* ipmi_kfwum_checkfwcompat - check whether firmware we're about to upload is
+ * compatible with board.
+ *
+ * @boardInfo:
+ * @firmInfo:
+ *
+ * returns 0 if compatible, otherwise (-1)
+ */
+int
+ipmi_kfwum_checkfwcompat(tKFWUM_BoardInfo boardInfo,
+ tKFWUM_InFirmwareInfo firmInfo)
+{
+ int compatible = 0;
+ if (boardInfo.iana != firmInfo.iana) {
+ lprintf(LOG_ERR,
+ "Board IANA does not match firmware IANA.");
+ compatible = (-1);
+ }
+ if (boardInfo.boardId != firmInfo.boardId) {
+ lprintf(LOG_ERR,
+ "Board IANA does not match firmware IANA.");
+ compatible = (-1);
+ }
+ if (compatible != 0) {
+ lprintf(LOG_ERR,
+ "Firmware invalid for target board. Download of upgrade aborted.");
+ }
+ return compatible;
+}
-static void KfwumOutputInfo(tKFWUM_BoardInfo boardInfo,
- tKFWUM_InFirmwareInfo firmInfo)
+void
+printf_kfwum_info(tKFWUM_BoardInfo boardInfo, tKFWUM_InFirmwareInfo firmInfo)
{
- printf("Target Board Id : %u\n",boardInfo.boardId);
- printf("Target IANA number : %u\n",boardInfo.iana);
- printf("File Size : %lu bytes\n",firmInfo.fileSize);
- printf("Firmware Version : %d.%d%d SDR %d\n",firmInfo.versMajor,
- firmInfo.versMinor, firmInfo.versSubMinor, firmInfo.sdrRev);
+ printf(
+"Target Board Id : %u\n", boardInfo.boardId);
+ printf(
+"Target IANA number : %u\n", boardInfo.iana);
+ printf(
+"File Size : %lu bytes\n", firmInfo.fileSize);
+ printf(
+"Firmware Version : %d.%d%d SDR %d\n", firmInfo.versMajor,
+firmInfo.versMinor, firmInfo.versSubMinor, firmInfo.sdrRev);
}
diff --git a/ipmitool/lib/ipmi_hpmfwupg.c b/ipmitool/lib/ipmi_hpmfwupg.c
index 630c0e7..0a56857 100644
--- a/ipmitool/lib/ipmi_hpmfwupg.c
+++ b/ipmitool/lib/ipmi_hpmfwupg.c
@@ -17,7 +17,7 @@
* 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.
+ * 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.
@@ -40,3940 +40,2605 @@
#include "../src/plugins/lan/md5.h"
#include <stdio.h>
#include <time.h>
+#include <sys/param.h>
#if HAVE_CONFIG_H
- #include <config.h>
+# include <config.h>
#endif
-/****************************************************************************
-*
-* Copyright (c) 2006 Kontron Canada, Inc. All Rights Reserved.
-*
-* HPM.1
-* Hardware Platform Management
-* IPM Controller Firmware Upgrade Procedure
-*
-* This module implements an Upgrade Agent for the IPM Controller
-* Firmware Upgrade Procedure (HPM.1) specification version 1.0.
-*
-* author:
-* Frederic.Lelievre@ca.kontron.com
-* Francois.Isabelle@ca.kontron.com
-* Jean-Michel.Audet@ca.kontron.com
-* MarieJosee.Blais@ca.kontron.com
-*
-*****************************************************************************
-*
-* HISTORY
-* ===========================================================================
-* 2007-01-11
-*
-* - Incremented to version 0.2
-* - Added lan packet size reduction mechanism to workaround fact
-* that lan iface will not return C7 on excessive length
-* - Fixed some typos
-* - now uses lprintf()
-*
-* - Incremented to version 0.3
-* - added patch for openipmi si driver V39 (send message in driver does not
-* retry on 82/83 completion code and return 82/83 as response from target
-* [conditionnaly built with ENABLE_OPENIPMI_V39_PATCH]
-*
-* see: ipmi-fix-send-msg-retry.pacth in openipmi-developer mailing list
-*
-* 2007-01-16
-*
-* - Incremented to version 0.4
-* - Fixed lan iface inaccesiblity timeout handling. Waiting for firmware
-* activation completion (fixed sleep) before re-opening a session and
-* get the final firmware upgrade status.
-* - Fixed some user interface stuff.
-*
-* 2007-05-09
-*
-* - Incremented to version 1.0
-* - Modifications for compliancy with HPM.1 specification version 1.0
-*
-* 2007-06-05
-*
-* - Modified the display of upgrade of Firmware version.
-* - Added new options like "check" and "component" and "all" to hpm commands.
-* - By default we skip the upgrade if we have the same firmware version
-* as compared to the Image file (*.hpm).This will ensure that user does
-* not update the target incase its already been updated
-*
-* 2008-01-25
-* - Reduce buffer length more aggressively when no response from iol.
-* - Incremented version to 1.02
-*
-* 2009-02-11
-* - With multi-component HPM file, if one component need to be skipped because
-* the component is already up-to-date, ipmitool sends "Initiate upgrade
-* action / Upload for upgrade" anyway.
-*
-* If the component needs to be skipped, ipmitool will not send "Initiate
-* upgrade action / Upload for upgrade"
-*
-* - Incremented version to 1.03
-*
-* 2009-02-11
-* - Fixed side effect introduced by last version, "forced" update didn't
-* work anymore
-* - Incremented version to 1.04
-*
-* 2009-03-25
-* - Fix the case where ipmitool loses the iol connection during the upload
-* block process. Once IPMITool was successfully sent the first byte,
-* IPMITool will not resize the block size.
-*
-* 2009-03-26
-* - Fix the problem when we try to upgrade specific component and the component
-* is already updated, IPMITool sends a "prepare action" but IPMITool skips
-* the upload firmware block process.
-* So, if we specify a specific component, we want to force to upload this
-* specific component.
-* - Incremented version to 1.05
-*
-* 2009-04-20
-* - Reworked previous update, when 'component' is specified, the other
-* components are now skipped.
-* - Incremented version to 1.06
-*
-* ===========================================================================
-* TODO
-* ===========================================================================
-* 2007-01-11
-* - Add interpretation of GetSelftestResults
-* - Add interpretation of component ID string
-*
-*****************************************************************************/
-
extern int verbose;
-/*
- * Agent version
- */
-#define HPMFWUPG_VERSION_MAJOR 1
-#define HPMFWUPG_VERSION_MINOR 0
-#define HPMFWUPG_VERSION_SUBMINOR 8
-
-/*
- * HPM.1 FIRMWARE UPGRADE COMMANDS (part of PICMG)
- */
-
-#define HPMFWUPG_GET_TARGET_UPG_CAPABILITIES 0x2E
-#define HPMFWUPG_GET_COMPONENT_PROPERTIES 0x2F
-#define HPMFWUPG_ABORT_UPGRADE 0x30
-#define HPMFWUPG_INITIATE_UPGRADE_ACTION 0x31
-#define HPMFWUPG_UPLOAD_FIRMWARE_BLOCK 0x32
-#define HPMFWUPG_FINISH_FIRMWARE_UPLOAD 0x33
-#define HPMFWUPG_GET_UPGRADE_STATUS 0x34
-#define HPMFWUPG_ACTIVATE_FIRMWARE 0x35
-#define HPMFWUPG_QUERY_SELFTEST_RESULT 0x36
-#define HPMFWUPG_QUERY_ROLLBACK_STATUS 0x37
-#define HPMFWUPG_MANUAL_FIRMWARE_ROLLBACK 0x38
-
-/*
- * HPM.1 SPECIFIC COMPLETION CODES
- */
-#define HPMFWUPG_ROLLBACK_COMPLETED 0x00
-#define HPMFWUPG_COMMAND_IN_PROGRESS 0x80
-#define HPMFWUPG_NOT_SUPPORTED 0x81
-#define HPMFWUPG_SIZE_MISMATCH 0x81
-#define HPMFWUPG_ROLLBACK_FAILURE 0x81
-#define HPMFWUPG_INV_COMP_MASK 0x81
-#define HPMFWUPG__ABORT_FAILURE 0x81
-#define HPMFWUPG_INV_COMP_ID 0x82
-#define HPMFWUPG_INT_CHECKSUM_ERROR 0x82
-#define HPMFWUPG_INV_UPLOAD_MODE 0x82
-#define HPMFWUPG_ROLLBACK_OVERRIDE 0x82
-#define HPMFWUPG_INV_COMP_PROP 0x83
-#define HPMFWUPG_FW_MISMATCH 0x83
-#define HPMFWUPG_ROLLBACK_DENIED 0x83
-
-/*
- * This error code is used as a temporary PATCH to
- * the latest Open ipmi driver. This PATCH
- * will be removed once a new Open IPMI driver is released.
- * (Buggy version = 39)
- */
-#define ENABLE_OPENIPMI_V39_PATCH
-
-#ifdef ENABLE_OPENIPMI_V39_PATCH
-
-#define RETRY_COUNT_MAX 3
-
-static int errorCount;
-
-#define HPMFWUPG_IS_RETRYABLE(error) \
-((((error==0x83)||(error==0x82)||(error==0x80)) && (errorCount++<RETRY_COUNT_MAX))?TRUE:FALSE)
-#else
-#define HPMFWUPG_IS_RETRYABLE(error) FALSE
-#endif
-
-/*
- * HPM FIRMWARE UPGRADE GENERAL DEFINITIONS
- */
-
-#define HPMFWUPG_PICMG_IDENTIFIER 0
-#define HPMFWUPG_VERSION_SIZE 6
-#define HPMFWUPG_DESC_STRING_LENGTH 12
-#define HPMFWUPG_DEFAULT_INACCESS_TIMEOUT 60 /* sec */
-#define HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT 60 /* sec */
-#define HPMFWUPG_MD5_SIGNATURE_LENGTH 16
-
-/* Component IDs */
-typedef enum eHpmfwupgComponentId
-{
- HPMFWUPG_COMPONENT_ID_0 = 0,
- HPMFWUPG_COMPONENT_ID_1,
- HPMFWUPG_COMPONENT_ID_2,
- HPMFWUPG_COMPONENT_ID_3,
- HPMFWUPG_COMPONENT_ID_4,
- HPMFWUPG_COMPONENT_ID_5,
- HPMFWUPG_COMPONENT_ID_6,
- HPMFWUPG_COMPONENT_ID_7,
- HPMFWUPG_COMPONENT_ID_MAX
-} tHpmfwupgComponentId;
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgComponentBitMask
-{
- union
- {
- unsigned char byte;
- struct
- {
- #ifdef WORDS_BIGENDIAN
- unsigned char component7 : 1;
- unsigned char component6 : 1;
- unsigned char component5 : 1;
- unsigned char component4 : 1;
- unsigned char component3 : 1;
- unsigned char component2 : 1;
- unsigned char component1 : 1;
- unsigned char component0 : 1;
- #else
- unsigned char component0 : 1;
- unsigned char component1 : 1;
- unsigned char component2 : 1;
- unsigned char component3 : 1;
- unsigned char component4 : 1;
- unsigned char component5 : 1;
- unsigned char component6 : 1;
- unsigned char component7 : 1;
- #endif
- }ATTRIBUTE_PACKING bitField;
- }ATTRIBUTE_PACKING ComponentBits;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-
-static const int HPMFWUPG_SUCCESS = 0;
-static const int HPMFWUPG_ERROR = -1;
-/* Upload firmware specific error codes */
-static const int HPMFWUPG_UPLOAD_BLOCK_LENGTH = 1;
-static const int HPMFWUPG_UPLOAD_RETRY = 2;
-
-
-/*
- * TARGET UPGRADE CAPABILITIES DEFINITIONS
- */
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetTargetUpgCapabilitiesReq
-{
- unsigned char picmgId;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetTargetUpgCapabilitiesResp
-{
- unsigned char picmgId;
- unsigned char hpmVersion;
- union
- {
- unsigned char byte;
- struct
- {
- #if WORDS_BIGENDIAN
- unsigned char fwUpgUndesirable : 1;
- unsigned char autRollbackOverride : 1;
- unsigned char ipmcDegradedDurinUpg: 1;
- unsigned char deferActivation : 1;
- unsigned char servAffectDuringUpg : 1;
- unsigned char manualRollback : 1;
- unsigned char autRollback : 1;
- unsigned char ipmcSelftestCap : 1;
- #else
- unsigned char ipmcSelftestCap : 1;
- unsigned char autRollback : 1;
- unsigned char manualRollback : 1;
- unsigned char servAffectDuringUpg : 1;
- unsigned char deferActivation : 1;
- unsigned char ipmcDegradedDurinUpg: 1;
- unsigned char autRollbackOverride : 1;
- unsigned char fwUpgUndesirable : 1;
- #endif
- }ATTRIBUTE_PACKING bitField;
- }ATTRIBUTE_PACKING GlobalCapabilities;
- unsigned char upgradeTimeout;
- unsigned char selftestTimeout;
- unsigned char rollbackTimeout;
- unsigned char inaccessTimeout;
- struct HpmfwupgComponentBitMask componentsPresent;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetTargetUpgCapabilitiesCtx
-{
- struct HpmfwupgGetTargetUpgCapabilitiesReq req;
- struct HpmfwupgGetTargetUpgCapabilitiesResp resp;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-/*
- * COMPONENT PROPERTIES DEFINITIONS
- */
-
-typedef enum eHpmfwupgCompPropertiesSelect
-{
- HPMFWUPG_COMP_GEN_PROPERTIES = 0,
- HPMFWUPG_COMP_CURRENT_VERSION,
- HPMFWUPG_COMP_DESCRIPTION_STRING,
- HPMFWUPG_COMP_ROLLBACK_FIRMWARE_VERSION,
- HPMFWUPG_COMP_DEFERRED_FIRMWARE_VERSION,
- HPMFWUPG_COMP_RESERVED,
- HPMFWUPG_COMP_OEM_PROPERTIES = 192
-} tHpmfwupgCompPropertiesSelect;
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetComponentPropertiesReq
-{
- unsigned char picmgId;
- unsigned char componentId;
- unsigned char selector;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetGeneralPropResp
-{
- unsigned char picmgId;
- union
- {
- unsigned char byte;
- struct
- {
- #if WORDS_BIGENDIAN
- unsigned char reserved : 2;
- unsigned char payloadColdReset : 1;
- unsigned char deferredActivation : 1;
- unsigned char comparisonSupport : 1;
- unsigned char preparationSupport : 1;
- unsigned char rollbackBackup : 2;
- #else
- unsigned char rollbackBackup : 2;
- unsigned char preparationSupport : 1;
- unsigned char comparisonSupport : 1;
- unsigned char deferredActivation : 1;
- unsigned char payloadColdReset : 1;
- unsigned char reserved : 2;
- #endif
- }ATTRIBUTE_PACKING bitfield;
- }ATTRIBUTE_PACKING GeneralCompProperties;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetCurrentVersionResp
-{
- unsigned char picmgId;
- unsigned char currentVersion[HPMFWUPG_VERSION_SIZE];
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetDescStringResp
-{
- unsigned char picmgId;
- char descString[HPMFWUPG_DESC_STRING_LENGTH];
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetRollbackFwVersionResp
-{
- unsigned char picmgId;
- unsigned char rollbackFwVersion[HPMFWUPG_VERSION_SIZE];
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetDeferredFwVersionResp
-{
- unsigned char picmgId;
- unsigned char deferredFwVersion[HPMFWUPG_VERSION_SIZE];
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-/*
- * GetComponentProperties - OEM properties (192)
- */
-#define HPMFWUPG_OEM_LENGTH 4
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetOemProperties
-{
- unsigned char picmgId;
- unsigned char oemRspData[HPMFWUPG_OEM_LENGTH];
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetComponentPropertiesResp
-{
- union
- {
- struct HpmfwupgGetGeneralPropResp generalPropResp;
- struct HpmfwupgGetCurrentVersionResp currentVersionResp;
- struct HpmfwupgGetDescStringResp descStringResp;
- struct HpmfwupgGetRollbackFwVersionResp rollbackFwVersionResp;
- struct HpmfwupgGetDeferredFwVersionResp deferredFwVersionResp;
- struct HpmfwupgGetOemProperties oemProperties;
- }ATTRIBUTE_PACKING Response;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetComponentPropertiesCtx
-{
- struct HpmfwupgGetComponentPropertiesReq req;
- struct HpmfwupgGetComponentPropertiesResp resp;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-
-/*
- * ABORT UPGRADE DEFINITIONS
- */
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgAbortUpgradeReq
-{
- unsigned char picmgId;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgAbortUpgradeResp
-{
- unsigned char picmgId;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgAbortUpgradeCtx
-{
- struct HpmfwupgAbortUpgradeReq req;
- struct HpmfwupgAbortUpgradeResp resp;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-/*
- * UPGRADE ACTIONS DEFINITIONS
- */
-typedef enum eHpmfwupgUpgradeAction
-{
- HPMFWUPG_UPGRADE_ACTION_BACKUP = 0,
- HPMFWUPG_UPGRADE_ACTION_PREPARE,
- HPMFWUPG_UPGRADE_ACTION_UPGRADE,
- HPMFWUPG_UPGRADE_ACTION_COMPARE,
- HPMFWUPG_UPGRADE_ACTION_INVALID = 0xff
-} tHpmfwupgUpgradeAction;
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgInitiateUpgradeActionReq
-{
- unsigned char picmgId;
- struct HpmfwupgComponentBitMask componentsMask;
- unsigned char upgradeAction;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgInitiateUpgradeActionResp
-{
- unsigned char picmgId;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgInitiateUpgradeActionCtx
-{
- struct HpmfwupgInitiateUpgradeActionReq req;
- struct HpmfwupgInitiateUpgradeActionResp resp;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-/*
- * UPLOAD FIRMWARE BLOCK DEFINITIONS
- */
-
-#define HPMFWUPG_SEND_DATA_COUNT_MAX 256
-#define HPMFWUPG_SEND_DATA_COUNT_KCS 30
-#define HPMFWUPG_SEND_DATA_COUNT_LAN 25
-#define HPMFWUPG_SEND_DATA_COUNT_IPMB 26
-#define HPMFWUPG_SEND_DATA_COUNT_IPMBL 26
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgUploadFirmwareBlockReq
-{
- unsigned char picmgId;
- unsigned char blockNumber;
- unsigned char data[HPMFWUPG_SEND_DATA_COUNT_MAX];
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgUploadFirmwareBlockResp
-{
- unsigned char picmgId;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgUploadFirmwareBlockCtx
-{
- struct HpmfwupgUploadFirmwareBlockReq req;
- struct HpmfwupgUploadFirmwareBlockResp resp;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-
-/*
- * FINISH FIRMWARE UPLOAD DEFINITIONS
- */
-
-#define HPMFWUPG_IMAGE_SIZE_BYTE_COUNT 4
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgFinishFirmwareUploadReq
-{
- unsigned char picmgId;
- unsigned char componentId;
- unsigned char imageLength[HPMFWUPG_IMAGE_SIZE_BYTE_COUNT];
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgFinishFirmwareUploadResp
-{
- unsigned char picmgId;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgFinishFirmwareUploadCtx
-{
- struct HpmfwupgFinishFirmwareUploadReq req;
- struct HpmfwupgFinishFirmwareUploadResp resp;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-/*
- * ACTIVATE FW DEFINITIONS
- */
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgActivateFirmwareReq
-{
- unsigned char picmgId;
- unsigned char rollback_override;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgActivateFirmwareResp
-{
- unsigned char picmgId;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgActivateFirmwareCtx
-{
- struct HpmfwupgActivateFirmwareReq req;
- struct HpmfwupgActivateFirmwareResp resp;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-
-/*
- * GET UPGRADE STATUS DEFINITIONS
- */
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetUpgradeStatusReq
-{
- unsigned char picmgId;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetUpgradeStatusResp
-{
- unsigned char picmgId;
- unsigned char cmdInProcess;
- unsigned char lastCmdCompCode;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgGetUpgradeStatusCtx
-{
- struct HpmfwupgGetUpgradeStatusReq req;
- struct HpmfwupgGetUpgradeStatusResp resp;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-/*
- * MANUAL FW ROLLBACK DEFINITIONS
- */
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgManualFirmwareRollbackReq
-{
- unsigned char picmgId;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgManualFirmwareRollbackResp
-{
- unsigned char picmgId;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-struct HpmfwupgManualFirmwareRollbackCtx
-{
- struct HpmfwupgManualFirmwareRollbackReq req;
- struct HpmfwupgManualFirmwareRollbackResp resp;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-/*
- * QUERY ROLLBACK STATUS DEFINITIONS
- */
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgQueryRollbackStatusReq
-{
- unsigned char picmgId;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgQueryRollbackStatusResp
-{
- unsigned char picmgId;
- struct HpmfwupgComponentBitMask rollbackComp;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgQueryRollbackStatusCtx
-{
- struct HpmfwupgQueryRollbackStatusReq req;
- struct HpmfwupgQueryRollbackStatusResp resp;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-/*
- * QUERY SELF TEST RESULT DEFINITIONS
- */
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgQuerySelftestResultReq
-{
- unsigned char picmgId;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgQuerySelftestResultResp
-{
- unsigned char picmgId;
- unsigned char result1;
- unsigned char result2;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgQuerySelftestResultCtx
-{
- struct HpmfwupgQuerySelftestResultReq req;
- struct HpmfwupgQuerySelftestResultResp resp;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-/*
- * HPM.1 IMAGE DEFINITIONS
+int HpmfwupgUpgrade(struct ipmi_intf *intf, char *imageFilename,
+ int activate, int, int);
+int HpmfwupgValidateImageIntegrity(struct HpmfwupgUpgradeCtx *pFwupgCtx);
+int HpmfwupgPreparationStage(struct ipmi_intf *intf,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx, int option);
+int HpmfwupgUpgradeStage(struct ipmi_intf *intf,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx, int option);
+int HpmfwupgActivationStage(struct ipmi_intf *intf,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx);
+int HpmfwupgGetTargetUpgCapabilities(struct ipmi_intf *intf,
+ struct HpmfwupgGetTargetUpgCapabilitiesCtx *pCtx);
+int HpmfwupgGetComponentProperties(struct ipmi_intf *intf,
+ struct HpmfwupgGetComponentPropertiesCtx *pCtx);
+int HpmfwupgQuerySelftestResult(struct ipmi_intf *intf,
+ struct HpmfwupgQuerySelftestResultCtx *pCtx,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx);
+int HpmfwupgQueryRollbackStatus(struct ipmi_intf *intf,
+ struct HpmfwupgQueryRollbackStatusCtx *pCtx,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx);
+int HpmfwupgAbortUpgrade(struct ipmi_intf *intf,
+ struct HpmfwupgAbortUpgradeCtx *pCtx);
+int HpmfwupgInitiateUpgradeAction(struct ipmi_intf *intf,
+ struct HpmfwupgInitiateUpgradeActionCtx *pCtx,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx);
+int HpmfwupgUploadFirmwareBlock(struct ipmi_intf *intf,
+ struct HpmfwupgUploadFirmwareBlockCtx *pCtx,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx, int count,
+ unsigned int *pOffset, unsigned int *blockLen);
+int HpmfwupgFinishFirmwareUpload(struct ipmi_intf *intf,
+ struct HpmfwupgFinishFirmwareUploadCtx *pCtx,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx, int option);
+int HpmfwupgActivateFirmware(struct ipmi_intf *intf,
+ struct HpmfwupgActivateFirmwareCtx *pCtx,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx);
+int HpmfwupgGetUpgradeStatus(struct ipmi_intf *intf,
+ struct HpmfwupgGetUpgradeStatusCtx *pCtxstruct,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx, int silent);
+int HpmfwupgManualFirmwareRollback(struct ipmi_intf *intf,
+ struct HpmfwupgManualFirmwareRollbackCtx *pCtx);
+void HpmfwupgPrintUsage(void);
+unsigned char HpmfwupgCalculateChecksum(unsigned char *pData,
+ unsigned int length);
+int HpmfwupgGetDeviceId(struct ipmi_intf *intf,
+ struct ipm_devid_rsp *pGetDevId);
+int HpmfwupgGetBufferFromFile(char *imageFilename,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx);
+int HpmfwupgWaitLongDurationCmd(struct ipmi_intf *intf,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx);
+struct ipmi_rs *HpmfwupgSendCmd(struct ipmi_intf *intf,
+ struct ipmi_rq req, struct HpmfwupgUpgradeCtx* pFwupgCtx);
+
+
+int HpmFwupgActionUploadFirmware(struct HpmfwupgComponentBitMask components,
+ struct HpmfwupgUpgradeCtx* pFwupgCtx,
+ unsigned char **pImagePtr,
+ struct ipmi_intf *intf,
+ int option,
+ int *pFlagColdReset);
+
+/* HpmGetuserInput - get input from user
+ *
+ * returns TRUE if its Yes or FALSE if its No
*/
-
-#define HPMFWUPG_HEADER_SIGNATURE_LENGTH 8
-#define HPMFWUPG_MANUFATURER_ID_LENGTH 3
-#define HPMFWUPG_PRODUCT_ID_LENGTH 2
-#define HPMFWUPG_TIME_LENGTH 4
-#define HPMFWUPG_TIMEOUT_LENGTH 1
-#define HPMFWUPG_COMP_REVISION_LENGTH 2
-#define HPMFWUPG_FIRM_REVISION_LENGTH 6
-#define HPMFWUPG_IMAGE_HEADER_VERSION 0
-#define HPMFWUPG_IMAGE_SIGNATURE "PICMGFWU"
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgImageHeader
+int
+HpmGetUserInput(char *str)
{
- char signature[HPMFWUPG_HEADER_SIGNATURE_LENGTH];
- unsigned char formatVersion;
- unsigned char deviceId;
- unsigned char manId[HPMFWUPG_MANUFATURER_ID_LENGTH];
- unsigned char prodId[HPMFWUPG_PRODUCT_ID_LENGTH];
- unsigned char time[HPMFWUPG_TIME_LENGTH];
- union
- {
- struct
- {
- #if WORDS_BIGENDIAN
- unsigned char imageSelfTest : 1;
- unsigned char autRollback : 1;
- unsigned char manRollback : 1;
- unsigned char servAffected : 1;
- unsigned char reserved : 4;
- #else
- unsigned char reserved : 4;
- unsigned char servAffected : 1;
- unsigned char manRollback : 1;
- unsigned char autRollback : 1;
- unsigned char imageSelfTest : 1;
- #endif
- } ATTRIBUTE_PACKING bitField;
- unsigned char byte;
- }ATTRIBUTE_PACKING imageCapabilities;
- struct HpmfwupgComponentBitMask components;
- unsigned char selfTestTimeout;
- unsigned char rollbackTimeout;
- unsigned char inaccessTimeout;
- unsigned char compRevision[HPMFWUPG_COMP_REVISION_LENGTH];
- unsigned char firmRevision[HPMFWUPG_FIRM_REVISION_LENGTH];
- unsigned short oemDataLength;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
+ char userInput[2];
+ int ret;
-#define HPMFWUPG_DESCRIPTION_LENGTH 21
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgActionRecord
-{
- unsigned char actionType;
- struct HpmfwupgComponentBitMask components;
- unsigned char checksum;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#define HPMFWUPG_FIRMWARE_SIZE_LENGTH 4
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgFirmwareImage
-{
- unsigned char version[HPMFWUPG_FIRM_REVISION_LENGTH];
- char desc[HPMFWUPG_DESCRIPTION_LENGTH];
- unsigned char length[HPMFWUPG_FIRMWARE_SIZE_LENGTH];
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-struct HpmfwupgUpgradeCtx
-{
- struct HpmfwupgComponentBitMask compUpdateMask;
- unsigned int imageSize;
- unsigned char* pImageData;
- unsigned char componentId;
- struct HpmfwupgGetTargetUpgCapabilitiesResp targetCap;
- struct HpmfwupgGetGeneralPropResp genCompProp[HPMFWUPG_COMPONENT_ID_MAX];
- struct ipm_devid_rsp devId;
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-typedef enum eHpmfwupgActionType
-{
- HPMFWUPG_ACTION_BACKUP_COMPONENTS = 0,
- HPMFWUPG_ACTION_PREPARE_COMPONENTS,
- HPMFWUPG_ACTION_UPLOAD_FIRMWARE,
- HPMFWUPG_ACTION_RESERVED = 0xFF
-} tHpmfwupgActionType;
-
-/*
- * FUNCTIONS PROTOTYPES
- */
-#define HPMFWUPG_MAJORMINOR_VERSION_SIZE 2
-
-
-#define DEFAULT_COMPONENT_UPLOAD 0x0F
+ printf("%s", str);
+ ret = scanf("%s", userInput);
+ if (!ret) {
+ return 1;
+ }
+ if (toupper(userInput[0]) == 'Y') {
+ return 1;
+ }
+ return 0;
+}
-/*
- * Options added for user to check the version and to view both the FILE and TARGET Version
+/* HpmDisplayLine - display the line with the given character
*/
-#define VERSIONCHECK_MODE 0x01
-#define VIEW_MODE 0x02
-#define DEBUG_MODE 0x04
-#define FORCE_MODE_ALL 0x08
-#define FORCE_MODE_COMPONENT 0x10
-#define FORCE_MODE (FORCE_MODE_ALL|FORCE_MODE_COMPONENT)
-
-typedef struct _VERSIONINFO
-{
- unsigned char componentId;
- unsigned char targetMajor;
- unsigned char targetMinor;
- unsigned char targetAux[4];
- unsigned char rollbackMajor;
- unsigned char rollbackMinor;
- unsigned char rollbackAux[4];
- unsigned char deferredMajor;
- unsigned char deferredMinor;
- unsigned char deferredAux[4];
- unsigned char imageMajor;
- unsigned char imageMinor;
- unsigned char imageAux[4];
- unsigned char coldResetRequired;
- unsigned char rollbackSupported;
- char descString[15];
-}VERSIONINFO, *PVERSIONINFO;
-
-VERSIONINFO gVersionInfo[HPMFWUPG_COMPONENT_ID_MAX];
-
-#define TARGET_VER (0x01)
-#define ROLLBACK_VER (0x02)
-#define IMAGE_VER (0x04)
-
-
-
-
-static int HpmfwupgUpgrade(struct ipmi_intf *intf, char* imageFilename, int activate, int,int);
-static int HpmfwupgValidateImageIntegrity(struct HpmfwupgUpgradeCtx* pFwupgCtx);
-static int HpmfwupgPreparationStage( struct ipmi_intf *intf,
- struct HpmfwupgUpgradeCtx* pFwupgCtx, int option);
-static int HpmfwupgUpgradeStage ( struct ipmi_intf *intf,
- struct HpmfwupgUpgradeCtx* pFwupgCtx, int compToUpload ,int option);
-static int HpmfwupgActivationStage(struct ipmi_intf *intf,
- struct HpmfwupgUpgradeCtx* pFwupgCtx);
-static int HpmfwupgGetTargetUpgCapabilities(struct ipmi_intf *intf,
- struct HpmfwupgGetTargetUpgCapabilitiesCtx* pCtx);
-static int HpmfwupgGetComponentProperties(struct ipmi_intf *intf,
- struct HpmfwupgGetComponentPropertiesCtx* pCtx);
-static int HpmfwupgQuerySelftestResult(struct ipmi_intf *intf,
- struct HpmfwupgQuerySelftestResultCtx* pCtx,
- struct HpmfwupgUpgradeCtx* pFwupgCtx);
-static int HpmfwupgQueryRollbackStatus(struct ipmi_intf *intf,
- struct HpmfwupgQueryRollbackStatusCtx* pCtx,
- struct HpmfwupgUpgradeCtx* pFwupgCtx);
-static int HpmfwupgAbortUpgrade(struct ipmi_intf *intf,
- struct HpmfwupgAbortUpgradeCtx* pCtx);
-static int HpmfwupgInitiateUpgradeAction(struct ipmi_intf *intf,
- struct HpmfwupgInitiateUpgradeActionCtx* pCtx,
- struct HpmfwupgUpgradeCtx* pFwupgCtx);
-static int HpmfwupgUploadFirmwareBlock(struct ipmi_intf *intf,
- struct HpmfwupgUploadFirmwareBlockCtx* pCtx,
- struct HpmfwupgUpgradeCtx* pFwupgCtx, int count ,
- unsigned int *pOffset, unsigned int *blockLen);
-static int HpmfwupgFinishFirmwareUpload(struct ipmi_intf *intf,
- struct HpmfwupgFinishFirmwareUploadCtx* pCtx,
- struct HpmfwupgUpgradeCtx* pFwupgCtx);
-static int HpmfwupgActivateFirmware(struct ipmi_intf *intf,
- struct HpmfwupgActivateFirmwareCtx* pCtx,
- struct HpmfwupgUpgradeCtx* pFwupgCtx);
-static int HpmfwupgGetUpgradeStatus(struct ipmi_intf *intf, struct HpmfwupgGetUpgradeStatusCtx* pCtxstruct, struct HpmfwupgUpgradeCtx* pFwupgCtx, int silent);
-static int HpmfwupgManualFirmwareRollback(struct ipmi_intf *intf,
- struct HpmfwupgManualFirmwareRollbackCtx* pCtx,
- struct HpmfwupgUpgradeCtx* pFwupgCtx);
-static void HpmfwupgPrintUsage(void);
-static unsigned char HpmfwupgCalculateChecksum(unsigned char* pData, unsigned int length);
-static int HpmfwupgGetDeviceId(struct ipmi_intf *intf, struct ipm_devid_rsp* pGetDevId);
-static int HpmfwupgGetBufferFromFile(char* imageFilename, struct HpmfwupgUpgradeCtx* pFwupgCtx);
-static int HpmfwupgWaitLongDurationCmd(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx);
-
-static struct ipmi_rs * HpmfwupgSendCmd(struct ipmi_intf *intf, struct ipmi_rq req,
- struct HpmfwupgUpgradeCtx* pFwupgCtx);
-
-
-static int HpmFwupgActionUploadFirmware
-(
- struct HpmfwupgComponentBitMask components,
- struct HpmfwupgUpgradeCtx* pFwupgCtx,
- unsigned char** pImagePtr,
- int componentToUpload,
- struct ipmi_intf *intf,
- int option,
- int* pFlagColdReset
-);
-
-/****************************************************************************
-*
-* Function Name: HpmGetuserInput
-*
-* Description: This function gets input from user and returns TRUE if its Yes
-* or FALSE if its No
-*
-*****************************************************************************/
-int HpmGetUserInput(char *str)
-{
- char userInput[2];
- int ret;
-
- printf("%s", str);
- ret = scanf("%s", userInput);
- if (!ret) {
- return 1;
- }
-
- if (toupper(userInput[0]) == 'Y')
- {
- return 1;
- }
- return 0;
-}
-/****************************************************************************
-*
-* Function Name: HpmDisplayLine
-*
-* Description: This is to display the line with the given character.
-*
-*****************************************************************************/
-void HpmDisplayLine(char *s, int n)
+void
+HpmDisplayLine(char *s, int n)
{
- while (n--) printf ("%c",*s);
- printf("\n");
+ while (n--) {
+ printf ("%c", *s);
+ }
+ printf("\n");
}
-/****************************************************************************
-*
-* Function Name: HpmDisplayUpgradeHeader
-*
-* Description: This function the displays the Upgrade header information
-*
-*****************************************************************************/
-void HpmDisplayUpgradeHeader(void)
-{
- printf("\n");
- HpmDisplayLine("-",79 );
- printf(
- "|ID | Name | Versions | %% |\n");
- printf(
- "| | | Active | Backup | File | |\n");
- printf(
- "|----|-------------|-----------------|-----------------|-----------------|----|\n");
+/* HpmDisplayUpgradeHeader - display the Upgrade header information
+ */
+void
+HpmDisplayUpgradeHeader(void)
+{
+ printf("\n");
+ HpmDisplayLine("-", 79);
+ printf(
+"|ID | Name | Versions | %% |\n");
+ printf(
+"| | | Active | Backup | File | |\n");
+ printf(
+"|----|-------------|-----------------|-----------------|-----------------|----|\n");
}
-/****************************************************************************
-*
-* Function Name: HpmDisplayUpgrade
-*
-* Description: This function displays the progress of the upgrade it prints the "."
-* every 5% of its completion.
-*
-*****************************************************************************/
-void HpmDisplayUpgrade( int skip, unsigned int totalSent,
- unsigned int displayFWLength,time_t timeElapsed)
-{
- int percent;
- static int old_percent=1;
- if (skip)
- {
- printf("Skip|\n");
- return;
- }
- fflush(stdout);
-
- percent = ((float)totalSent/displayFWLength)*100;
- if (percent != old_percent)
- {
- if ( percent == 0 ) printf(" 0%%|");
- else if (percent == 100) printf("\b\b\b\b\b100%%|\n");
- else printf("\b\b\b\b\b%3d%%|", percent);
- old_percent = percent;
- }
+/* HpmDisplayUpgrade - display the progress of the upgrade; prints the "."
+ * for every 5% of its completion.
+ */
+void
+HpmDisplayUpgrade(int skip, unsigned int totalSent,
+ unsigned int displayFWLength, time_t timeElapsed)
+{
+ int percent;
+ static int old_percent = -1;
+ if (skip) {
+ printf("Skip|\n");
+ return;
+ }
+ fflush(stdout);
- if (totalSent== displayFWLength)
- {
- /* Display the time taken to complete the upgrade */
- printf(
- "| |Upload Time: %02ld:%02ld | Image Size: %7d bytes |\n",
- timeElapsed/60,timeElapsed%60,totalSent);
- }
+ percent = ((float)totalSent / displayFWLength) * 100;
+ if (percent != old_percent) {
+ if (old_percent != -1) {
+ printf("\b\b\b\b\b");
+ }
+ printf("%3d%%|", percent);
+ old_percent = percent;
+ }
+ if (totalSent == displayFWLength) {
+ /* Display the time taken to complete the upgrade */
+ printf(
+"\n| |Upload Time: %02ld:%02ld | Image Size: %7d bytes |\n",
+ timeElapsed / 60, timeElapsed % 60, totalSent);
+ old_percent = -1;
+ }
}
-/****************************************************************************
-*
-* Function Name: HpmDisplayVersionHeader
-*
-* Description: This function displays the information about version header
-*
-*****************************************************************************/
-void HpmDisplayVersionHeader(int mode)
-{
- if ( mode & IMAGE_VER)
- {
- HpmDisplayLine("-",74 );
- printf(
- "|ID | Name | Versions |\n");
- printf(
- "| | | Active | Backup | File |\n");
- HpmDisplayLine("-",74 );
- }
- else
- {
- HpmDisplayLine("-",74 );
- printf(
- "|ID | Name | Versions |\n");
- printf(
- "| | | Active | Backup | Deferred |\n");
- HpmDisplayLine("-",74 );
- }
+/* HpmDisplayVersionHeader - display the information about version header
+ */
+void
+HpmDisplayVersionHeader(int mode)
+{
+ if (mode & IMAGE_VER) {
+ HpmDisplayLine("-", 74);
+ printf(
+"|ID | Name | Versions |\n");
+ printf(
+"| | | Active | Backup | File |\n");
+ HpmDisplayLine("-", 74);
+ } else {
+ HpmDisplayLine("-",74 );
+ printf(
+"|ID | Name | Versions |\n");
+ printf(
+"| | | Active | Backup | Deferred |\n");
+ HpmDisplayLine("-", 74);
+ }
}
-/****************************************************************************
-*
-* Function Name: HpmDisplayVersion
-*
-* Description: This function displays the version of the image and target
-*
-*****************************************************************************/
-void HpmDisplayVersion(int mode, VERSIONINFO *pVersion, int upgradable)
+/* HpmDisplayVersion - display the version of the image and target
+ */
+void
+HpmDisplayVersion(int mode, VERSIONINFO *pVersion, int upgradable)
{
- char descString[16];
-
- memset(&descString,0x00,sizeof(descString));
- /*
- * Added this to ensure that even if the description string
- * is more than required it does not give problem in displaying it
- */
- strncpy(descString,pVersion->descString,13);
-
/*
* If the cold reset is required then we can display * on it
* so that user is aware that he needs to do payload power
* cycle after upgrade
*/
printf("|%c%c%2d|%-13s|",
- pVersion->coldResetRequired?'*':' ',
- upgradable ? '^': ' ',
- pVersion->componentId,descString);
-
- if (mode & TARGET_VER)
- {
- if ((pVersion->targetMajor == 0xFF ||
- (pVersion->targetMajor == 0x7F)) &&
- pVersion->targetMinor == 0xFF)
+ pVersion->coldResetRequired ? '*' : ' ',
+ upgradable ? '^' : ' ',
+ pVersion->componentId, pVersion->descString);
+
+ if (mode & TARGET_VER) {
+ if ((pVersion->targetMajor == 0xFF
+ || (pVersion->targetMajor == 0x7F))
+ && pVersion->targetMinor == 0xFF) {
printf(" ---.-- -------- |");
- else
+ } else {
printf(" %3d.%02x %02X%02X%02X%02X |",
- pVersion->targetMajor,
- pVersion->targetMinor,
- pVersion->targetAux[0],
- pVersion->targetAux[1],
- pVersion->targetAux[2],
- pVersion->targetAux[3]);
-
- if (mode & ROLLBACK_VER)
- {
- if ((pVersion->rollbackMajor == 0xFF ||
- (pVersion->rollbackMajor == 0x7F)) &&
- pVersion->rollbackMinor == 0xFF)
+ pVersion->targetMajor,
+ pVersion->targetMinor,
+ pVersion->targetAux[0],
+ pVersion->targetAux[1],
+ pVersion->targetAux[2],
+ pVersion->targetAux[3]);
+ }
+ if (mode & ROLLBACK_VER) {
+ if ((pVersion->rollbackMajor == 0xFF
+ || (pVersion->rollbackMajor == 0x7F))
+ && pVersion->rollbackMinor == 0xFF) {
printf(" ---.-- -------- |");
- else
+ } else {
printf(" %3d.%02x %02X%02X%02X%02X |",
- pVersion->rollbackMajor,
- pVersion->rollbackMinor,
- pVersion->rollbackAux[0],
- pVersion->rollbackAux[1],
- pVersion->rollbackAux[2],
- pVersion->rollbackAux[3]);
+ pVersion->rollbackMajor,
+ pVersion->rollbackMinor,
+ pVersion->rollbackAux[0],
+ pVersion->rollbackAux[1],
+ pVersion->rollbackAux[2],
+ pVersion->rollbackAux[3]);
}
- else
+ } else {
printf(" ---.-- -------- |");
}
-
- if (mode & IMAGE_VER)
- {
- if ((pVersion->imageMajor == 0xFF ||
- (pVersion->imageMajor == 0x7F)) &&
- pVersion->imageMinor == 0xFF)
+ }
+ if (mode & IMAGE_VER) {
+ if ((pVersion->imageMajor == 0xFF
+ || (pVersion->imageMajor == 0x7F))
+ && pVersion->imageMinor == 0xFF) {
printf(" ---.-- |");
- else
+ } else {
printf(" %3d.%02x %02X%02X%02X%02X |",
- pVersion->imageMajor,
- pVersion->imageMinor,
- pVersion->imageAux[0],
- pVersion->imageAux[1],
- pVersion->imageAux[2],
- pVersion->imageAux[3]);
- }
- else
- {
- if ((pVersion->deferredMajor == 0xFF ||
- (pVersion->deferredMajor == 0x7F)) &&
- pVersion->deferredMinor == 0xFF)
+ pVersion->imageMajor,
+ pVersion->imageMinor,
+ pVersion->imageAux[0],
+ pVersion->imageAux[1],
+ pVersion->imageAux[2],
+ pVersion->imageAux[3]);
+ }
+ } else {
+ if ((pVersion->deferredMajor == 0xFF
+ || (pVersion->deferredMajor == 0x7F))
+ && pVersion->deferredMinor == 0xFF) {
printf(" ---.-- -------- |");
- else
+ } else {
printf(" %3d.%02x %02X%02X%02X%02X |",
- pVersion->deferredMajor,
- pVersion->deferredMinor,
- pVersion->deferredAux[0],
- pVersion->deferredAux[1],
- pVersion->deferredAux[2],
- pVersion->deferredAux[3]);
+ pVersion->deferredMajor,
+ pVersion->deferredMinor,
+ pVersion->deferredAux[0],
+ pVersion->deferredAux[1],
+ pVersion->deferredAux[2],
+ pVersion->deferredAux[3]);
}
-}
-
-
-/****************************************************************************
-*
-* Function Name: HpmfwupgTargerCheck
-*
-* Description: This function gets the target information and displays it on the
-* screen
-*
-*****************************************************************************/
-int HpmfwupgTargetCheck(struct ipmi_intf * intf, int option)
-{
- struct HpmfwupgUpgradeCtx fwupgCtx;
- struct HpmfwupgGetTargetUpgCapabilitiesCtx targetCapCmd;
- int rc = HPMFWUPG_SUCCESS;
- int componentId = 0;
- int flagColdReset = FALSE;
- struct ipm_devid_rsp devIdrsp;
- struct HpmfwupgGetComponentPropertiesCtx getCompProp;
- int mode = 0;
-
-
- rc = HpmfwupgGetDeviceId(intf, &devIdrsp);
-
- if (rc != HPMFWUPG_SUCCESS)
- {
- lprintf(LOG_NOTICE,"Verify whether the Target board is present \n");
- return HPMFWUPG_ERROR;
- }
-
- rc = HpmfwupgGetTargetUpgCapabilities(intf, &targetCapCmd);
- if (rc != HPMFWUPG_SUCCESS)
- {
- /*
- * That indicates the target is not responding to the command
- * May be that there is no HPM support
- */
- lprintf(LOG_NOTICE,"Board might not be supporting the HPM.1 Standards\n");
- return rc;
- }
- if (option & VIEW_MODE)
- {
- lprintf(LOG_NOTICE,"-------Target Information-------");
- lprintf(LOG_NOTICE,"Device Id : 0x%x", devIdrsp.device_id);
- lprintf(LOG_NOTICE,"Device Revision : 0x%x", devIdrsp.device_revision);
- lprintf(LOG_NOTICE,"Product Id : 0x%04x", buf2short(devIdrsp.product_id));
- lprintf(LOG_NOTICE,"Manufacturer Id : 0x%04x (%s)\n\n", buf2short(devIdrsp.manufacturer_id),
- val2str(buf2short(devIdrsp.manufacturer_id),ipmi_oem_info));
- HpmDisplayVersionHeader(TARGET_VER|ROLLBACK_VER);
- }
-
- for ( componentId = HPMFWUPG_COMPONENT_ID_0; componentId < HPMFWUPG_COMPONENT_ID_MAX;
- componentId++ )
- {
- /* If the component is supported */
- if ( ((1 << componentId) & targetCapCmd.resp.componentsPresent.ComponentBits.byte) )
- {
- memset((PVERSIONINFO)&gVersionInfo[componentId],0x00,sizeof(VERSIONINFO));
-
- getCompProp.req.componentId = componentId;
- getCompProp.req.selector = HPMFWUPG_COMP_GEN_PROPERTIES;
- rc = HpmfwupgGetComponentProperties(intf, &getCompProp);
- if (rc != HPMFWUPG_SUCCESS)
- {
- lprintf(LOG_NOTICE,"Get CompGenProp Failed for component Id %d\n",componentId);
- return rc;
- }
-
- gVersionInfo[componentId].rollbackSupported = getCompProp.resp.Response.
- generalPropResp.GeneralCompProperties.bitfield.rollbackBackup;
- gVersionInfo[componentId].coldResetRequired = getCompProp.resp.Response.
- generalPropResp.GeneralCompProperties.bitfield.payloadColdReset;
-
- getCompProp.req.selector = HPMFWUPG_COMP_DESCRIPTION_STRING;
- rc = HpmfwupgGetComponentProperties(intf, &getCompProp);
- if (rc != HPMFWUPG_SUCCESS)
- {
- lprintf(LOG_NOTICE,"Get CompDescString Failed for component Id %d\n",componentId);
- return rc;
- }
- strcpy((char *)&gVersionInfo[componentId].descString,
- getCompProp.resp.Response.descStringResp.descString);
-
- getCompProp.req.selector = HPMFWUPG_COMP_CURRENT_VERSION;
- rc = HpmfwupgGetComponentProperties(intf, &getCompProp);
- if (rc != HPMFWUPG_SUCCESS)
- {
- lprintf(LOG_NOTICE,"Get CompCurrentVersion Failed for component Id %d\n",componentId);
- return rc;
- }
-
- gVersionInfo[componentId].componentId = componentId;
- gVersionInfo[componentId].targetMajor = getCompProp.resp.Response.
- currentVersionResp.currentVersion[0];
- gVersionInfo[componentId].targetMinor = getCompProp.resp.Response.
- currentVersionResp.currentVersion[1];
- gVersionInfo[componentId].targetAux[0] = getCompProp.resp.Response.
- currentVersionResp.currentVersion[2];
- gVersionInfo[componentId].targetAux[1] = getCompProp.resp.Response.
- currentVersionResp.currentVersion[3];
- gVersionInfo[componentId].targetAux[2] = getCompProp.resp.Response.
- currentVersionResp.currentVersion[4];
- gVersionInfo[componentId].targetAux[3] = getCompProp.resp.Response.
- currentVersionResp.currentVersion[5];
- mode = TARGET_VER;
-
- if (gVersionInfo[componentId].rollbackSupported)
- {
- getCompProp.req.selector = HPMFWUPG_COMP_ROLLBACK_FIRMWARE_VERSION;
- rc = HpmfwupgGetComponentProperties(intf, &getCompProp);
- if (rc != HPMFWUPG_SUCCESS)
- {
- lprintf(LOG_NOTICE,"Get CompRollbackVersion Failed for component Id %d\n",componentId);
- } else {
- gVersionInfo[componentId].rollbackMajor = getCompProp.resp
- .Response.rollbackFwVersionResp.rollbackFwVersion[0];
- gVersionInfo[componentId].rollbackMinor = getCompProp.resp
- .Response.rollbackFwVersionResp.rollbackFwVersion[1];
- gVersionInfo[componentId].rollbackAux[0] = getCompProp.resp.Response.rollbackFwVersionResp.rollbackFwVersion[2];
- gVersionInfo[componentId].rollbackAux[1] = getCompProp.resp.Response.rollbackFwVersionResp.rollbackFwVersion[3];
- gVersionInfo[componentId].rollbackAux[2] = getCompProp.resp.Response.rollbackFwVersionResp.rollbackFwVersion[4];
- gVersionInfo[componentId].rollbackAux[3] = getCompProp.resp.Response.rollbackFwVersionResp.rollbackFwVersion[5];
- }
-
- getCompProp.req.selector = HPMFWUPG_COMP_DEFERRED_FIRMWARE_VERSION;
- rc = HpmfwupgGetComponentProperties(intf, &getCompProp);
- if (rc != HPMFWUPG_SUCCESS)
- {
- lprintf(LOG_NOTICE,"Get CompRollbackVersion Failed for component Id %d\n",componentId);
- } else {
- gVersionInfo[componentId].deferredMajor = getCompProp.resp
- .Response.deferredFwVersionResp.deferredFwVersion[0];
- gVersionInfo[componentId].deferredMinor = getCompProp.resp
- .Response.deferredFwVersionResp.deferredFwVersion[1];
- gVersionInfo[componentId].deferredAux[0] = getCompProp.resp.Response.deferredFwVersionResp.deferredFwVersion[2];
- gVersionInfo[componentId].deferredAux[1] = getCompProp.resp.Response.deferredFwVersionResp.deferredFwVersion[3];
- gVersionInfo[componentId].deferredAux[2] = getCompProp.resp.Response.deferredFwVersionResp.deferredFwVersion[4];
- gVersionInfo[componentId].deferredAux[3] = getCompProp.resp.Response.deferredFwVersionResp.deferredFwVersion[5];
- }
- mode |= ROLLBACK_VER;
- }
- else
- {
- gVersionInfo[componentId].rollbackMajor = 0xff;
- gVersionInfo[componentId].rollbackMinor = 0xff;
- gVersionInfo[componentId].rollbackAux[0] = 0xff;
- gVersionInfo[componentId].rollbackAux[1] = 0xff;
- gVersionInfo[componentId].rollbackAux[2] = 0xff;
- gVersionInfo[componentId].rollbackAux[3] = 0xff;
-
- gVersionInfo[componentId].deferredMajor = 0xff;
- gVersionInfo[componentId].deferredMinor = 0xff;
- gVersionInfo[componentId].deferredAux[0] = 0xff;
- gVersionInfo[componentId].deferredAux[1] = 0xff;
- gVersionInfo[componentId].deferredAux[2] = 0xff;
- gVersionInfo[componentId].deferredAux[3] = 0xff;
- }
-
- if (gVersionInfo[componentId].coldResetRequired)
- {
- /*
- * If any of the component indicates that the Payload Cold reset is required
- * then set the flag
- */
- flagColdReset = TRUE;
- }
- if (option & VIEW_MODE)
- {
- HpmDisplayVersion(mode,&gVersionInfo[componentId], 0);
- printf("\n");
- }
- }
- }
-
- if (option & VIEW_MODE)
- {
- HpmDisplayLine("-",74 );
- fflush(stdout);
- lprintf(LOG_NOTICE,"(*) Component requires Payload Cold Reset");
- printf("\n\n");
- }
- return HPMFWUPG_SUCCESS;
-}
-
-/*****************************************************************************
-* Function Name: HpmfwupgUpgrade
-*
-* Description: This function performs the HPM.1 firmware upgrade procedure as
-* defined the IPM Controller Firmware Upgrade Specification
-* version 1.0
-*
-*****************************************************************************/
-int HpmfwupgUpgrade(struct ipmi_intf *intf, char* imageFilename,
- int activate,int componentToUpload, int option)
-{
- int rc = HPMFWUPG_SUCCESS;
- struct HpmfwupgImageHeader imageHeader;
- struct HpmfwupgUpgradeCtx fwupgCtx;
-
- /*
- * GET IMAGE BUFFER FROM FILE
- */
-
- rc = HpmfwupgGetBufferFromFile(imageFilename, &fwupgCtx);
-
- /*
- * VALIDATE IMAGE INTEGRITY
- */
-
- if ( rc == HPMFWUPG_SUCCESS )
- {
- printf("Validating firmware image integrity...");
- fflush(stdout);
- rc = HpmfwupgValidateImageIntegrity(&fwupgCtx);
- if ( rc == HPMFWUPG_SUCCESS )
- {
- printf("OK\n");
- fflush(stdout);
- }
- else
- {
- free(fwupgCtx.pImageData);
- fwupgCtx.pImageData = NULL;
- }
- }
-
- /*
- * PREPARATION STAGE
- */
-
- if ( rc == HPMFWUPG_SUCCESS )
- {
- printf("Performing preparation stage...");
- fflush(stdout);
- rc = HpmfwupgPreparationStage(intf, &fwupgCtx, option);
- if ( rc == HPMFWUPG_SUCCESS )
- {
- printf("OK\n");
- fflush(stdout);
- }
- else
- {
- free(fwupgCtx.pImageData);
- fwupgCtx.pImageData = NULL;
- }
- }
-
- /*
- * UPGRADE STAGE
- */
-
- if ( rc == HPMFWUPG_SUCCESS )
- {
- if (option & VIEW_MODE)
- {
- lprintf(LOG_NOTICE,"\nComparing Target & Image File version");
- }
- else
- {
- lprintf(LOG_NOTICE,"\nPerforming upgrade stage:");
- }
- if (option & VIEW_MODE)
- {
- rc = HpmfwupgPreUpgradeCheck(intf, &fwupgCtx,componentToUpload,VIEW_MODE);
- }
- else
- {
- rc = HpmfwupgPreUpgradeCheck(intf, &fwupgCtx,componentToUpload,option);
- if (rc == HPMFWUPG_SUCCESS )
- {
- if( verbose ) {
- printf("Component update mask : 0x%02x\n", fwupgCtx.compUpdateMask.ComponentBits.byte);
- }
- rc = HpmfwupgUpgradeStage(intf, &fwupgCtx,componentToUpload,option);
- }
- }
-
- if ( rc != HPMFWUPG_SUCCESS )
- {
- free(fwupgCtx.pImageData);
- fwupgCtx.pImageData = NULL;
- }
- }
-
- /*
- * ACTIVATION STAGE
- */
- if ( rc == HPMFWUPG_SUCCESS && activate )
- {
- lprintf(LOG_NOTICE,"Performing activation stage: ");
- rc = HpmfwupgActivationStage(intf, &fwupgCtx);
- if ( rc != HPMFWUPG_SUCCESS )
- {
- free(fwupgCtx.pImageData);
- fwupgCtx.pImageData = NULL;
- }
- }
+ }
+}
- if ( rc == HPMFWUPG_SUCCESS )
- {
- if (option & VIEW_MODE)
- {
- // Dont display anything here in case we are just viewing it
- lprintf(LOG_NOTICE," ");
- }
- else
- {
- lprintf(LOG_NOTICE,"\nFirmware upgrade procedure successful\n");
- }
- free(fwupgCtx.pImageData);
- fwupgCtx.pImageData = NULL;
- }
- else
- {
- lprintf(LOG_NOTICE,"Firmware upgrade procedure failed\n");
- }
+/* HpmfwupgTargerCheck - get target information and displays it on the screen
+ */
+int
+HpmfwupgTargetCheck(struct ipmi_intf *intf, int option)
+{
+ struct HpmfwupgGetTargetUpgCapabilitiesCtx targetCapCmd;
+ int rc = HPMFWUPG_SUCCESS;
+ int componentId = 0;
+ int flagColdReset = FALSE;
+ struct ipm_devid_rsp devIdrsp;
+ struct HpmfwupgGetComponentPropertiesCtx getCompProp;
+ int mode = 0;
+ rc = HpmfwupgGetDeviceId(intf, &devIdrsp);
+ if (rc != HPMFWUPG_SUCCESS) {
+ lprintf(LOG_NOTICE,
+ "Verify whether the Target board is present \n");
+ return HPMFWUPG_ERROR;
+ }
+ rc = HpmfwupgGetTargetUpgCapabilities(intf, &targetCapCmd);
+ if (rc != HPMFWUPG_SUCCESS) {
+ /* That indicates the target is not responding to the command
+ * May be that there is no HPM support
+ */
+ lprintf(LOG_NOTICE,
+ "Board might not be supporting the HPM.1 Standards\n");
+ return rc;
+ }
+ if (option & VIEW_MODE) {
+ lprintf(LOG_NOTICE, "-------Target Information-------");
+ lprintf(LOG_NOTICE, "Device Id : 0x%x",
+ devIdrsp.device_id);
+ lprintf(LOG_NOTICE, "Device Revision : 0x%x",
+ devIdrsp.device_revision);
+ lprintf(LOG_NOTICE, "Product Id : 0x%04x",
+ buf2short(devIdrsp.product_id));
+ lprintf(LOG_NOTICE, "Manufacturer Id : 0x%04x (%s)\n\n",
+ buf2short(devIdrsp.manufacturer_id),
+ val2str(buf2short(devIdrsp.manufacturer_id),ipmi_oem_info));
+ HpmDisplayVersionHeader(TARGET_VER|ROLLBACK_VER);
+ }
+ for (componentId = HPMFWUPG_COMPONENT_ID_0;
+ componentId < HPMFWUPG_COMPONENT_ID_MAX;
+ componentId++ ) {
+ /* If the component is supported */
+ if (((1 << componentId) & targetCapCmd.resp.componentsPresent.ComponentBits.byte)) {
+ memset((PVERSIONINFO)&gVersionInfo[componentId], 0x00, sizeof(VERSIONINFO));
+ getCompProp.req.componentId = componentId;
+ getCompProp.req.selector = HPMFWUPG_COMP_GEN_PROPERTIES;
+ rc = HpmfwupgGetComponentProperties(intf, &getCompProp);
+ if (rc != HPMFWUPG_SUCCESS) {
+ lprintf(LOG_NOTICE, "Get CompGenProp Failed for component Id %d\n",
+ componentId);
+ return rc;
+ }
+ gVersionInfo[componentId].rollbackSupported = getCompProp.resp.Response.
+ generalPropResp.GeneralCompProperties.bitfield.rollbackBackup;
+ gVersionInfo[componentId].coldResetRequired = getCompProp.resp.Response.
+ generalPropResp.GeneralCompProperties.bitfield.payloadColdReset;
+ getCompProp.req.selector = HPMFWUPG_COMP_DESCRIPTION_STRING;
+ rc = HpmfwupgGetComponentProperties(intf, &getCompProp);
+ if (rc != HPMFWUPG_SUCCESS) {
+ lprintf(LOG_NOTICE,
+ "Get CompDescString Failed for component Id %d\n",
+ componentId);
+ return rc;
+ }
+ memcpy(gVersionInfo[componentId].descString,
+ getCompProp.resp.Response.descStringResp.descString,
+ HPMFWUPG_DESC_STRING_LENGTH);
+ gVersionInfo[componentId].descString[HPMFWUPG_DESC_STRING_LENGTH] = '\0';
+ getCompProp.req.selector = HPMFWUPG_COMP_CURRENT_VERSION;
+ rc = HpmfwupgGetComponentProperties(intf, &getCompProp);
+ if (rc != HPMFWUPG_SUCCESS) {
+ lprintf(LOG_NOTICE,
+ "Get CompCurrentVersion Failed for component Id %d\n",
+ componentId);
+ return rc;
+ }
+ gVersionInfo[componentId].componentId = componentId;
+ gVersionInfo[componentId].targetMajor = getCompProp.resp.Response.
+ currentVersionResp.currentVersion[0];
+ gVersionInfo[componentId].targetMinor = getCompProp.resp.Response.
+ currentVersionResp.currentVersion[1];
+ gVersionInfo[componentId].targetAux[0] = getCompProp.resp.Response.
+ currentVersionResp.currentVersion[2];
+ gVersionInfo[componentId].targetAux[1] = getCompProp.resp.Response.
+ currentVersionResp.currentVersion[3];
+ gVersionInfo[componentId].targetAux[2] = getCompProp.resp.Response.
+ currentVersionResp.currentVersion[4];
+ gVersionInfo[componentId].targetAux[3] = getCompProp.resp.Response.
+ currentVersionResp.currentVersion[5];
+ mode = TARGET_VER;
+ if (gVersionInfo[componentId].rollbackSupported) {
+ getCompProp.req.selector = HPMFWUPG_COMP_ROLLBACK_FIRMWARE_VERSION;
+ rc = HpmfwupgGetComponentProperties(intf, &getCompProp);
+ if (rc != HPMFWUPG_SUCCESS) {
+ lprintf(LOG_NOTICE,
+ "Get CompRollbackVersion Failed for component Id %d\n",
+ componentId);
+ } else {
+ gVersionInfo[componentId].rollbackMajor = getCompProp.resp
+ .Response.rollbackFwVersionResp.rollbackFwVersion[0];
+ gVersionInfo[componentId].rollbackMinor = getCompProp.resp
+ .Response.rollbackFwVersionResp.rollbackFwVersion[1];
+ gVersionInfo[componentId].rollbackAux[0] = getCompProp.resp.Response.rollbackFwVersionResp.rollbackFwVersion[2];
+ gVersionInfo[componentId].rollbackAux[1] = getCompProp.resp.Response.rollbackFwVersionResp.rollbackFwVersion[3];
+ gVersionInfo[componentId].rollbackAux[2] = getCompProp.resp.Response.rollbackFwVersionResp.rollbackFwVersion[4];
+ gVersionInfo[componentId].rollbackAux[3] = getCompProp.resp.Response.rollbackFwVersionResp.rollbackFwVersion[5];
+ }
+ getCompProp.req.selector = HPMFWUPG_COMP_DEFERRED_FIRMWARE_VERSION;
+ rc = HpmfwupgGetComponentProperties(intf, &getCompProp);
+ if (rc != HPMFWUPG_SUCCESS) {
+ lprintf(LOG_NOTICE,
+ "Get CompRollbackVersion Failed for component Id %d\n",
+ componentId);
+ } else {
+ gVersionInfo[componentId].deferredMajor = getCompProp.resp
+ .Response.deferredFwVersionResp.deferredFwVersion[0];
+ gVersionInfo[componentId].deferredMinor = getCompProp.resp
+ .Response.deferredFwVersionResp.deferredFwVersion[1];
+ gVersionInfo[componentId].deferredAux[0] = getCompProp.resp.Response.deferredFwVersionResp.deferredFwVersion[2];
+ gVersionInfo[componentId].deferredAux[1] = getCompProp.resp.Response.deferredFwVersionResp.deferredFwVersion[3];
+ gVersionInfo[componentId].deferredAux[2] = getCompProp.resp.Response.deferredFwVersionResp.deferredFwVersion[4];
+ gVersionInfo[componentId].deferredAux[3] = getCompProp.resp.Response.deferredFwVersionResp.deferredFwVersion[5];
+ }
+ mode |= ROLLBACK_VER;
+ } else {
+ gVersionInfo[componentId].rollbackMajor = 0xff;
+ gVersionInfo[componentId].rollbackMinor = 0xff;
+ gVersionInfo[componentId].rollbackAux[0] = 0xff;
+ gVersionInfo[componentId].rollbackAux[1] = 0xff;
+ gVersionInfo[componentId].rollbackAux[2] = 0xff;
+ gVersionInfo[componentId].rollbackAux[3] = 0xff;
+ gVersionInfo[componentId].deferredMajor = 0xff;
+ gVersionInfo[componentId].deferredMinor = 0xff;
+ gVersionInfo[componentId].deferredAux[0] = 0xff;
+ gVersionInfo[componentId].deferredAux[1] = 0xff;
+ gVersionInfo[componentId].deferredAux[2] = 0xff;
+ gVersionInfo[componentId].deferredAux[3] = 0xff;
+ }
+ if (gVersionInfo[componentId].coldResetRequired) {
+ /*
+ * If any of the component indicates that the Payload Cold reset is required
+ * then set the flag
+ */
+ flagColdReset = TRUE;
+ }
+ if (option & VIEW_MODE) {
+ HpmDisplayVersion(mode,
+ &gVersionInfo[componentId],
+ 0);
+ printf("\n");
+ }
+ }
+ }
+ if (option & VIEW_MODE) {
+ HpmDisplayLine("-",74 );
+ fflush(stdout);
+ lprintf(LOG_NOTICE,
+ "(*) Component requires Payload Cold Reset");
+ printf("\n\n");
+ }
+ return HPMFWUPG_SUCCESS;
+}
- return rc;
+/* HpmfwupgUpgrade - perform the HPM.1 firmware upgrade procedure as defined
+ * the IPM Controller Firmware Upgrade Specification version 1.0
+ */
+int
+HpmfwupgUpgrade(struct ipmi_intf *intf, char *imageFilename, int activate,
+ int componentMask, int option)
+{
+ int rc = HPMFWUPG_SUCCESS;
+ struct HpmfwupgUpgradeCtx fwupgCtx;
+ /* INITIALIZE UPGRADE CONTEXT */
+ memset(&fwupgCtx, 0, sizeof (fwupgCtx));
+ /* GET IMAGE BUFFER FROM FILE */
+ rc = HpmfwupgGetBufferFromFile(imageFilename, &fwupgCtx);
+ /* VALIDATE IMAGE INTEGRITY */
+ if (rc == HPMFWUPG_SUCCESS) {
+ printf("Validating firmware image integrity...");
+ fflush(stdout);
+ rc = HpmfwupgValidateImageIntegrity(&fwupgCtx);
+ if (rc == HPMFWUPG_SUCCESS) {
+ printf("OK\n");
+ fflush(stdout);
+ }
+ }
+ /* PREPARATION STAGE */
+ if (rc == HPMFWUPG_SUCCESS) {
+ printf("Performing preparation stage...");
+ fflush(stdout);
+ rc = HpmfwupgPreparationStage(intf, &fwupgCtx, option);
+ if (rc == HPMFWUPG_SUCCESS) {
+ printf("OK\n");
+ fflush(stdout);
+ }
+ }
+ /* UPGRADE STAGE */
+ if (rc == HPMFWUPG_SUCCESS) {
+ if (option & VIEW_MODE) {
+ lprintf(LOG_NOTICE,
+ "\nComparing Target & Image File version");
+ } else if (option & COMPARE_MODE) {
+ lprintf(LOG_NOTICE,
+ "\nPerforming upload for compare stage:");
+ } else {
+ lprintf(LOG_NOTICE, "\nPerforming upgrade stage:");
+ }
+ if (option & VIEW_MODE) {
+ rc = HpmfwupgPreUpgradeCheck(intf,
+ &fwupgCtx,componentMask, VIEW_MODE);
+ } else {
+ rc = HpmfwupgPreUpgradeCheck(intf, &fwupgCtx,
+ componentMask, option);
+ if (rc == HPMFWUPG_SUCCESS) {
+ if (verbose) {
+ printf("Component update mask : 0x%02x\n",
+ fwupgCtx.compUpdateMask.ComponentBits.byte);
+ }
+ rc = HpmfwupgUpgradeStage(intf, &fwupgCtx, option);
+ }
+ }
+ }
+ /* ACTIVATION STAGE */
+ if (rc == HPMFWUPG_SUCCESS && activate) {
+ /* check if upgrade components mask is non-zero */
+ if (fwupgCtx.compUpdateMask.ComponentBits.byte) {
+ lprintf(LOG_NOTICE, "Performing activation stage: ");
+ rc = HpmfwupgActivationStage(intf, &fwupgCtx);
+ } else {
+ lprintf(LOG_NOTICE,
+ "No components updated. Skipping activation stage.\n");
+ }
+ }
+ if (rc == HPMFWUPG_SUCCESS) {
+ if (option & VIEW_MODE) {
+ /* Dont display anything here in case we are just viewing it */
+ lprintf(LOG_NOTICE," ");
+ } else if (option & COMPARE_MODE) {
+ lprintf(LOG_NOTICE,
+ "\nFirmware comparison procedure complete\n");
+ } else {
+ lprintf(LOG_NOTICE,
+ "\nFirmware upgrade procedure successful\n");
+ }
+ } else if (option & VIEW_MODE) {
+ /* Dont display anything here in case we are just viewing it */
+ lprintf(LOG_NOTICE," ");
+ } else if (option & COMPARE_MODE) {
+ lprintf(LOG_NOTICE,
+ "Firmware comparison procedure failed\n");
+ } else {
+ lprintf(LOG_NOTICE, "Firmware upgrade procedure failed\n");
+ }
+ if (fwupgCtx.pImageData) {
+ free(fwupgCtx.pImageData);
+ fwupgCtx.pImageData = NULL;
+ }
+ return rc;
}
-/****************************************************************************
-*
-* Function Name: HpmfwupgValidateImageIntegrity
-*
-* Description: This function validates a HPM.1 firmware image file as defined
-* in section 4 of the IPM Controller Firmware Upgrade
-* Specification version 1.0
-*
-*****************************************************************************/
-int HpmfwupgValidateImageIntegrity(struct HpmfwupgUpgradeCtx* pFwupgCtx)
+/* HpmfwupgValidateImageIntegrity - validate a HPM.1 firmware image file as
+ * defined in section 4 of the IPM Controller Firmware Upgrade Specification
+ * version 1.0
+ */
+int
+HpmfwupgValidateImageIntegrity(struct HpmfwupgUpgradeCtx *pFwupgCtx)
{
- int rc = HPMFWUPG_SUCCESS;
- struct HpmfwupgImageHeader* pImageHeader = (struct HpmfwupgImageHeader*)
- pFwupgCtx->pImageData;
- md5_state_t ctx;
+ struct HpmfwupgImageHeader *pImageHeader = (struct HpmfwupgImageHeader*)pFwupgCtx->pImageData;
+ md5_state_t ctx;
static unsigned char md[HPMFWUPG_MD5_SIGNATURE_LENGTH];
- unsigned char* pMd5Sig = pFwupgCtx->pImageData +
- (pFwupgCtx->imageSize -
- HPMFWUPG_MD5_SIGNATURE_LENGTH);
-
- /* Validate MD5 checksum */
- memset(md, 0, HPMFWUPG_MD5_SIGNATURE_LENGTH);
- memset(&ctx, 0, sizeof(md5_state_t));
- md5_init(&ctx);
- md5_append(&ctx, pFwupgCtx->pImageData, pFwupgCtx->imageSize -
- HPMFWUPG_MD5_SIGNATURE_LENGTH);
- md5_finish(&ctx, md);
- if ( memcmp(md, pMd5Sig,HPMFWUPG_MD5_SIGNATURE_LENGTH) != 0 )
- {
- lprintf(LOG_NOTICE,"\n Invalid MD5 signature");
- rc = HPMFWUPG_ERROR;
- }
-
- if ( rc == HPMFWUPG_SUCCESS )
- {
- /* Validate Header signature */
- if( strncmp(pImageHeader->signature, HPMFWUPG_IMAGE_SIGNATURE, HPMFWUPG_HEADER_SIGNATURE_LENGTH) == 0 )
- {
- /* Validate Header image format version */
- if ( pImageHeader->formatVersion == HPMFWUPG_IMAGE_HEADER_VERSION )
- {
- /* Validate header checksum */
- if ( HpmfwupgCalculateChecksum((unsigned char*)pImageHeader,
- sizeof(struct HpmfwupgImageHeader) +
- pImageHeader->oemDataLength +
- sizeof(unsigned char)/*checksum*/) != 0 )
- {
- lprintf(LOG_NOTICE,"\n Invalid header checksum");
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"\n Unrecognized image version");
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"\n Invalid image signature");
- rc = HPMFWUPG_ERROR;
- }
- }
- return rc;
+ unsigned char *pMd5Sig = pFwupgCtx->pImageData
+ + (pFwupgCtx->imageSize - HPMFWUPG_MD5_SIGNATURE_LENGTH);
+ /* Validate MD5 checksum */
+ memset(md, 0, HPMFWUPG_MD5_SIGNATURE_LENGTH);
+ memset(&ctx, 0, sizeof(md5_state_t));
+ md5_init(&ctx);
+ md5_append(&ctx, pFwupgCtx->pImageData,
+ pFwupgCtx->imageSize - HPMFWUPG_MD5_SIGNATURE_LENGTH);
+ md5_finish(&ctx, md);
+ if (memcmp(md, pMd5Sig, HPMFWUPG_MD5_SIGNATURE_LENGTH) != 0) {
+ lprintf(LOG_NOTICE, "\n Invalid MD5 signature");
+ return HPMFWUPG_ERROR;
+ }
+ /* Validate Header signature */
+ if(strncmp(pImageHeader->signature,
+ HPMFWUPG_IMAGE_SIGNATURE,
+ HPMFWUPG_HEADER_SIGNATURE_LENGTH) != 0) {
+ lprintf(LOG_NOTICE,"\n Invalid image signature");
+ return HPMFWUPG_ERROR;
+ }
+ /* Validate Header image format version */
+ if (pImageHeader->formatVersion != HPMFWUPG_IMAGE_HEADER_VERSION) {
+ lprintf(LOG_NOTICE,"\n Unrecognized image version");
+ return HPMFWUPG_ERROR;
+ }
+ /* Validate header checksum */
+ if (HpmfwupgCalculateChecksum((unsigned char*)pImageHeader,
+ sizeof(struct HpmfwupgImageHeader)
+ + pImageHeader->oemDataLength
+ + sizeof(unsigned char)/*checksum*/) != 0) {
+ lprintf(LOG_NOTICE,"\n Invalid header checksum");
+ return HPMFWUPG_ERROR;
+ }
+ return HPMFWUPG_SUCCESS;
}
-/****************************************************************************
-*
-* Function Name: HpmfwupgPreparationStage
-*
-* Description: This function the preperation stage of a firmware upgrade
-* procedure as defined in section 3.2 of the IPM Controller
-* Firmware Upgrade Specification version 1.0
-*
-*****************************************************************************/
-int HpmfwupgPreparationStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx, int option)
-{
- int rc = HPMFWUPG_SUCCESS;
- struct HpmfwupgImageHeader* pImageHeader = (struct HpmfwupgImageHeader*)
- pFwupgCtx->pImageData;
-
- /* Get device ID */
- rc = HpmfwupgGetDeviceId(intf, &pFwupgCtx->devId);
-
- /* Match current IPMC IDs with upgrade image */
- if ( rc == HPMFWUPG_SUCCESS )
- {
- /* Validate device ID */
- if ( pImageHeader->deviceId == pFwupgCtx->devId.device_id )
- {
- /* Validate product ID */
- if ( memcmp(pImageHeader->prodId, pFwupgCtx->devId.product_id, HPMFWUPG_PRODUCT_ID_LENGTH ) == 0 )
- {
- /* Validate man ID */
- if ( memcmp(pImageHeader->manId, pFwupgCtx->devId.manufacturer_id,
- HPMFWUPG_MANUFATURER_ID_LENGTH ) != 0 )
- {
- lprintf(LOG_NOTICE,"\n Invalid image file for manufacturer %u",
- buf2short(pFwupgCtx->devId.manufacturer_id));
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"\n Invalid image file for product %u",
- buf2short(pFwupgCtx->devId.product_id));
- rc = HPMFWUPG_ERROR;
- }
-
- }
- else
- {
- lprintf(LOG_NOTICE,"\n Invalid device ID %x", pFwupgCtx->devId.device_id);
- rc = HPMFWUPG_ERROR;
- }
-
- if (rc != HPMFWUPG_SUCCESS)
- {
- /*
- * Giving one more chance to user to check whether its OK to continue even if the
- * product ID does not match. This is helpful as sometimes we just want to update
- * and dont care whether we have a different product Id. If the user says NO then
- * we need to just bail out from here
- */
- if ( (option & FORCE_MODE) || (option & VIEW_MODE) )
- {
- printf("\n Image Information");
- printf("\n Device Id : 0x%x",pImageHeader->deviceId);
- printf("\n Prod Id : 0x%02x%02x",pImageHeader->prodId[1], pImageHeader->prodId[0]);
- printf("\n Manuf Id : 0x%02x%02x%02x",pImageHeader->manId[2],
- pImageHeader->manId[1],pImageHeader->manId[0]);
- printf("\n Board Information");
- printf("\n Device Id : 0x%x", pFwupgCtx->devId.device_id);
- printf("\n Prod Id : 0x%02x%02x",pFwupgCtx->devId.product_id[1], pFwupgCtx->devId.product_id[0]);
- printf("\n Manuf Id : 0x%02x%02x%02x",pFwupgCtx->devId.manufacturer_id[2],
- pFwupgCtx->devId.manufacturer_id[1],pFwupgCtx->devId.manufacturer_id[0]);
- if (HpmGetUserInput("\n Continue ignoring DeviceID/ProductID/ManufacturingID (Y/N) :"))
- rc = HPMFWUPG_SUCCESS;
- }
- else
- {
- printf("\n\n Use \"force\" option for copying all the components\n");
- }
- }
- }
-
- /* Validate earliest compatible revision */
- if ( rc == HPMFWUPG_SUCCESS )
- {
- /* Validate major & minor revision */
- if ( pImageHeader->compRevision[0] < pFwupgCtx->devId.fw_rev1 )
- {
- /* Do nothing, upgrade accepted */
- }
- else if ( pImageHeader->compRevision[0] == pFwupgCtx->devId.fw_rev1 )
- {
- /* Must validate minor revision */
- if ( pImageHeader->compRevision[1] > pFwupgCtx->devId.fw_rev2 )
- {
- /* Version not compatible for upgrade */
- lprintf(LOG_NOTICE,"\n Version: Major: %d", pImageHeader->compRevision[0]);
- lprintf(LOG_NOTICE," Minor: %x", pImageHeader->compRevision[1]);
- lprintf(LOG_NOTICE," Not compatible with ");
- lprintf(LOG_NOTICE," Version: Major: %d", pFwupgCtx->devId.fw_rev1);
- lprintf(LOG_NOTICE," Minor: %x", pFwupgCtx->devId.fw_rev2);
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- /* Version not compatible for upgrade */
- lprintf(LOG_NOTICE,"\n Version: Major: %d", pImageHeader->compRevision[0]);
- lprintf(LOG_NOTICE," Minor: %x", pImageHeader->compRevision[1]);
- lprintf(LOG_NOTICE," Not compatible with ");
- lprintf(LOG_NOTICE," Version: Major: %d", pFwupgCtx->devId.fw_rev1);
- lprintf(LOG_NOTICE," Minor: %x", pFwupgCtx->devId.fw_rev2);
- rc = HPMFWUPG_ERROR;
- }
-
- if (rc != HPMFWUPG_SUCCESS)
- {
- /* Confirming it once again */
- if ( (option & FORCE_MODE) || (option & VIEW_MODE) )
- {
- if( HpmGetUserInput("\n Continue IGNORING Earliest compatibility (Y/N) :"))
- rc = HPMFWUPG_SUCCESS;
- }
- }
- }
-
- /* Get target upgrade capabilities */
- if ( rc == HPMFWUPG_SUCCESS )
- {
- struct HpmfwupgGetTargetUpgCapabilitiesCtx targetCapCmd;
-
- rc = HpmfwupgGetTargetUpgCapabilities(intf, &targetCapCmd);
-
- if ( rc == HPMFWUPG_SUCCESS )
- {
- /* Copy response to context */
- memcpy(&pFwupgCtx->targetCap,
- &targetCapCmd.resp,
- sizeof(struct HpmfwupgGetTargetUpgCapabilitiesResp));
-
- if (option & VIEW_MODE)
- {
- return rc;
- }
- else
- {
- /* Make sure all component IDs defined in the upgrade
- image are supported by the IPMC */
- if ( (pImageHeader->components.ComponentBits.byte &
- pFwupgCtx->targetCap.componentsPresent.ComponentBits.byte ) !=
- pImageHeader->components.ComponentBits.byte )
- {
- lprintf(LOG_NOTICE,"\n Some components present in the image file are not supported by the IPMC");
- rc = HPMFWUPG_ERROR;
- }
-
- /* Make sure the upgrade is desirable rigth now */
- if ( pFwupgCtx->targetCap.GlobalCapabilities.bitField.fwUpgUndesirable == 1 )
- {
- lprintf(LOG_NOTICE,"\n Upgrade undesirable at this moment");
- rc = HPMFWUPG_ERROR;
- }
-
- /* Get confimation from the user if he wants to continue when service
- affected during upgrade */
- if ( pFwupgCtx->targetCap.GlobalCapabilities.bitField.servAffectDuringUpg == 1 ||
- pImageHeader->imageCapabilities.bitField.servAffected == 1 )
- {
- if (HpmGetUserInput("\nServices may be affected during upgrade. Do you wish to continue? y/n "))
- {
- rc = HPMFWUPG_SUCCESS;
- }
- else
- {
- rc = HPMFWUPG_ERROR;
- }
- }
- }
- }
- }
-
- /* Get the general properties of each component present in image */
- if ( rc == HPMFWUPG_SUCCESS )
- {
- int componentId;
-
- for ( componentId = HPMFWUPG_COMPONENT_ID_0;
- componentId < HPMFWUPG_COMPONENT_ID_MAX;
- componentId++ )
- {
- /* Reset component properties */
- memset(&pFwupgCtx->genCompProp[componentId], 0, sizeof (struct HpmfwupgGetGeneralPropResp));
-
- if ( (1 << componentId & pImageHeader->components.ComponentBits.byte) )
- {
- struct HpmfwupgGetComponentPropertiesCtx getCompPropCmd;
-
- /* Get general component properties */
- getCompPropCmd.req.componentId = componentId;
- getCompPropCmd.req.selector = HPMFWUPG_COMP_GEN_PROPERTIES;
-
- rc = HpmfwupgGetComponentProperties(intf, &getCompPropCmd);
-
- if ( rc == HPMFWUPG_SUCCESS )
- {
- /* Copy response to context */
- memcpy(&pFwupgCtx->genCompProp[componentId],
- &getCompPropCmd.resp,
- sizeof(struct HpmfwupgGetGeneralPropResp));
- }
- }
- }
- }
-
- return rc;
+/* HpmfwupgPreparationStage - prepere stage of a firmware upgrade procedure as
+ * defined in section 3.2 of the IPM Controller Firmware Upgrade Specification
+ * version 1.0
+ */
+int
+HpmfwupgPreparationStage(struct ipmi_intf *intf,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx, int option)
+{
+ int componentId;
+ int rc = HPMFWUPG_SUCCESS;
+ struct HpmfwupgGetTargetUpgCapabilitiesCtx targetCapCmd;
+ struct HpmfwupgImageHeader *pImageHeader = (struct HpmfwupgImageHeader*)
+ pFwupgCtx->pImageData;
+ /* Get device ID */
+ rc = HpmfwupgGetDeviceId(intf, &pFwupgCtx->devId);
+ /* Match current IPMC IDs with upgrade image */
+ if (rc != HPMFWUPG_SUCCESS) {
+ return HPMFWUPG_ERROR;
+ }
+ /* Validate device ID */
+ if (pImageHeader->deviceId == pFwupgCtx->devId.device_id) {
+ /* Validate product ID */
+ if (memcmp(pImageHeader->prodId,
+ pFwupgCtx->devId.product_id,
+ HPMFWUPG_PRODUCT_ID_LENGTH ) == 0) {
+ /* Validate man ID */
+ if (memcmp(pImageHeader->manId,
+ pFwupgCtx->devId.manufacturer_id,
+ HPMFWUPG_MANUFATURER_ID_LENGTH) != 0) {
+ lprintf(LOG_NOTICE,
+ "\n Invalid image file for manufacturer %u",
+ buf2short(pFwupgCtx->devId.manufacturer_id));
+ rc = HPMFWUPG_ERROR;
+ }
+ } else {
+ lprintf(LOG_NOTICE,
+ "\n Invalid image file for product %u",
+ buf2short(pFwupgCtx->devId.product_id));
+ rc = HPMFWUPG_ERROR;
+ }
+ } else {
+ lprintf(LOG_NOTICE, "\n Invalid device ID %x",
+ pFwupgCtx->devId.device_id);
+ rc = HPMFWUPG_ERROR;
+ }
+ if (rc != HPMFWUPG_SUCCESS) {
+ /* Giving one more chance to user to check whether its OK to continue even if the
+ * product ID does not match. This is helpful as sometimes we just want to update
+ * and dont care whether we have a different product Id. If the user says NO then
+ * we need to just bail out from here
+ */
+ if (!((option & FORCE_MODE) || (option & VIEW_MODE))) {
+ printf("\n\n Use \"force\" option for copying all the components\n");
+ return HPMFWUPG_ERROR;
+ }
+ printf("\n Image Information");
+ printf("\n Device Id : 0x%x", pImageHeader->deviceId);
+ printf("\n Prod Id : 0x%02x%02x",
+ pImageHeader->prodId[1], pImageHeader->prodId[0]);
+ printf("\n Manuf Id : 0x%02x%02x%02x",
+ pImageHeader->manId[2],
+ pImageHeader->manId[1],
+ pImageHeader->manId[0]);
+ printf("\n Board Information");
+ printf("\n Device Id : 0x%x", pFwupgCtx->devId.device_id);
+ printf("\n Prod Id : 0x%02x%02x",
+ pFwupgCtx->devId.product_id[1], pFwupgCtx->devId.product_id[0]);
+ printf("\n Manuf Id : 0x%02x%02x%02x",
+ pFwupgCtx->devId.manufacturer_id[2],
+ pFwupgCtx->devId.manufacturer_id[1],
+ pFwupgCtx->devId.manufacturer_id[0]);
+ if (HpmGetUserInput("\n Continue ignoring DeviceID/ProductID/ManufacturingID (Y/N): ")) {
+ rc = HPMFWUPG_SUCCESS;
+ } else {
+ return HPMFWUPG_ERROR;
+ }
+ }
+ /* Validate earliest compatible revision */
+ /* Validate major & minor revision */
+ if (pImageHeader->compRevision[0] > pFwupgCtx->devId.fw_rev1
+ || (pImageHeader->compRevision[0] == pFwupgCtx->devId.fw_rev1
+ && pImageHeader->compRevision[1] > pFwupgCtx->devId.fw_rev2)) {
+ /* Version not compatible for upgrade */
+ lprintf(LOG_NOTICE, "\n Version: Major: %d", pImageHeader->compRevision[0]);
+ lprintf(LOG_NOTICE, " Minor: %x", pImageHeader->compRevision[1]);
+ lprintf(LOG_NOTICE, " Not compatible with ");
+ lprintf(LOG_NOTICE, " Version: Major: %d", pFwupgCtx->devId.fw_rev1);
+ lprintf(LOG_NOTICE, " Minor: %x", pFwupgCtx->devId.fw_rev2);
+ /* Confirming it once again */
+ if (!((option & FORCE_MODE) || (option & VIEW_MODE))) {
+ return HPMFWUPG_ERROR;
+ }
+ if (HpmGetUserInput("\n Continue IGNORING Earliest compatibility (Y/N): ")) {
+ rc = HPMFWUPG_SUCCESS;
+ } else {
+ return HPMFWUPG_ERROR;
+ }
+ }
+ /* Get target upgrade capabilities */
+ rc = HpmfwupgGetTargetUpgCapabilities(intf, &targetCapCmd);
+ if (rc != HPMFWUPG_SUCCESS) {
+ return HPMFWUPG_ERROR;
+ }
+ /* Copy response to context */
+ memcpy(&pFwupgCtx->targetCap,
+ &targetCapCmd.resp,
+ sizeof(struct HpmfwupgGetTargetUpgCapabilitiesResp));
+ if (option & VIEW_MODE) {
+ /* do nothing */
+ } else {
+ /* Make sure all component IDs defined in the
+ * upgrade image are supported by the IPMC
+ */
+ if ((pImageHeader->components.ComponentBits.byte &
+ pFwupgCtx->targetCap.componentsPresent.ComponentBits.byte) !=
+ pImageHeader->components.ComponentBits.byte) {
+ lprintf(LOG_NOTICE,
+ "\n Some components present in the image file are not supported by the IPMC");
+ return HPMFWUPG_ERROR;
+ }
+ /* Make sure the upgrade is desirable rigth now */
+ if (pFwupgCtx->targetCap.GlobalCapabilities.bitField.fwUpgUndesirable == 1) {
+ lprintf(LOG_NOTICE, "\n Upgrade undesirable at this moment");
+ return HPMFWUPG_ERROR;
+ }
+ /* Get confimation from the user if he wants to continue when
+ * service affected during upgrade
+ */
+ if (!(option & COMPARE_MODE)
+ && (pFwupgCtx->targetCap.GlobalCapabilities.bitField.servAffectDuringUpg == 1
+ || pImageHeader->imageCapabilities.bitField.servAffected == 1)) {
+ if (HpmGetUserInput("\nServices may be affected during upgrade. Do you wish to continue? (y/n): ")) {
+ rc = HPMFWUPG_SUCCESS;
+ } else {
+ return HPMFWUPG_ERROR;
+ }
+ }
+ }
+ /* Get the general properties of each component present in image */
+ for (componentId = HPMFWUPG_COMPONENT_ID_0;
+ componentId < HPMFWUPG_COMPONENT_ID_MAX;
+ componentId++) {
+ /* Reset component properties */
+ memset(&pFwupgCtx->genCompProp[componentId], 0,
+ sizeof (struct HpmfwupgGetGeneralPropResp));
+ if ((1 << componentId & pImageHeader->components.ComponentBits.byte)) {
+ struct HpmfwupgGetComponentPropertiesCtx getCompPropCmd;
+ /* Get general component properties */
+ getCompPropCmd.req.componentId = componentId;
+ getCompPropCmd.req.selector = HPMFWUPG_COMP_GEN_PROPERTIES;
+ rc = HpmfwupgGetComponentProperties(intf, &getCompPropCmd);
+ if (rc == HPMFWUPG_SUCCESS) {
+ /* Copy response to context */
+ memcpy(&pFwupgCtx->genCompProp[componentId],
+ &getCompPropCmd.resp,
+ sizeof(struct HpmfwupgGetGeneralPropResp));
+ }
+ }
+ }
+ return rc;
}
-static int image_version_upgradable(VERSIONINFO *pVersionInfo)
+int
+image_version_upgradable(VERSIONINFO *pVersionInfo)
{
/* If the image and active target versions are different, then
* upgrade */
- if ((pVersionInfo->imageMajor != pVersionInfo->targetMajor) ||
- (pVersionInfo->imageMinor != pVersionInfo->targetMinor) ||
- (pVersionInfo->imageAux[0] != pVersionInfo->targetAux[0]) ||
- (pVersionInfo->imageAux[1] != pVersionInfo->targetAux[1]) ||
- (pVersionInfo->imageAux[2] != pVersionInfo->targetAux[2]) ||
- (pVersionInfo->imageAux[3] != pVersionInfo->targetAux[3]))
+ if ((pVersionInfo->imageMajor != pVersionInfo->targetMajor)
+ || (pVersionInfo->imageMinor != pVersionInfo->targetMinor)
+ || (pVersionInfo->imageAux[0] != pVersionInfo->targetAux[0])
+ || (pVersionInfo->imageAux[1] != pVersionInfo->targetAux[1])
+ || (pVersionInfo->imageAux[2] != pVersionInfo->targetAux[2])
+ || (pVersionInfo->imageAux[3] != pVersionInfo->targetAux[3])) {
return (1);
-
+ }
/* If the image and active target versions are the same and rollback
- * is not supported, then there's nothing to do, skip the upgrade */
- if (!pVersionInfo->rollbackSupported)
+ * is not supported, then there's nothing to do, skip the upgrade
+ */
+ if (!pVersionInfo->rollbackSupported) {
return (0);
-
+ }
/* If the image and rollback target versions are different, then
- * go ahead and upgrade */
- if ((pVersionInfo->imageMajor != pVersionInfo->rollbackMajor) ||
- (pVersionInfo->imageMinor != pVersionInfo->rollbackMinor) ||
- (pVersionInfo->imageAux[0] != pVersionInfo->rollbackAux[0]) ||
- (pVersionInfo->imageAux[1] != pVersionInfo->rollbackAux[1]) ||
- (pVersionInfo->imageAux[2] != pVersionInfo->rollbackAux[2]) ||
- (pVersionInfo->imageAux[3] != pVersionInfo->rollbackAux[3]))
+ * go ahead and upgrade
+ */
+ if ((pVersionInfo->imageMajor != pVersionInfo->rollbackMajor)
+ || (pVersionInfo->imageMinor != pVersionInfo->rollbackMinor)
+ || (pVersionInfo->imageAux[0] != pVersionInfo->rollbackAux[0])
+ || (pVersionInfo->imageAux[1] != pVersionInfo->rollbackAux[1])
+ || (pVersionInfo->imageAux[2] != pVersionInfo->rollbackAux[2])
+ || (pVersionInfo->imageAux[3] != pVersionInfo->rollbackAux[3])) {
return (1);
-
+ }
/* Image and rollback target versions are the same too, skip it */
return (0);
}
-/****************************************************************************
-*
-* Function Name: HpmfwupgPreUpgradeCheck
-*
-* Description: This function the pre Upgrade check, this mainly helps in checking
-* which all version upgrade is skippable because the image version
-* is same as target version.
-*
-*****************************************************************************/
-int HpmfwupgPreUpgradeCheck(struct ipmi_intf *intf,
- struct HpmfwupgUpgradeCtx* pFwupgCtx,
- int componentToUpload, int option)
+/* HpmfwupgValidateActionRecordChecksum - validate checksum of the specified
+ * action record header.
+ */
+int
+HpmfwupgValidateActionRecordChecksum(struct HpmfwupgActionRecord *pActionRecord)
{
- unsigned char* pImagePtr;
- struct HpmfwupgActionRecord *pActionRecord;
- int flagColdReset = FALSE;
- struct HpmfwupgImageHeader *pImageHeader;
-
- pImageHeader = (struct HpmfwupgImageHeader*) pFwupgCtx->pImageData;
-
- /* Put pointer after image header */
- pImagePtr = (unsigned char*)
- (pFwupgCtx->pImageData + sizeof(struct HpmfwupgImageHeader) +
- pImageHeader->oemDataLength + sizeof(unsigned char)/*chksum*/);
-
- if (option & VIEW_MODE) {
- HpmDisplayVersionHeader(TARGET_VER|ROLLBACK_VER|IMAGE_VER);
- }
-
- /* Perform actions defined in the image */
- while (pImagePtr < (pFwupgCtx->pImageData + pFwupgCtx->imageSize -
- HPMFWUPG_MD5_SIGNATURE_LENGTH)) {
- /* Get action record */
- pActionRecord = (struct HpmfwupgActionRecord*)pImagePtr;
-
+ int rc = HPMFWUPG_SUCCESS;
/* Validate action record checksum */
if (HpmfwupgCalculateChecksum((unsigned char*)pActionRecord,
- sizeof(struct HpmfwupgActionRecord)) != 0) {
- lprintf(LOG_NOTICE," Invalid Action record.");
- return HPMFWUPG_ERROR;
+ sizeof(struct HpmfwupgActionRecord)) != 0) {
+ /* Due to ambiguity in the HPM.1 specification, for the case of
+ * the Upload Firmware Image action type, the record header length
+ * might be thought as either the first 3 bytes, or the first 34 bytes
+ * which precede the firmware image data.
+ * For the latter case we re-calculate the Upload Firmware Image
+ * record checksum for the 34 byte header length.
+ */
+ if (pActionRecord->actionType != HPMFWUPG_ACTION_UPLOAD_FIRMWARE
+ || HpmfwupgCalculateChecksum((unsigned char*)pActionRecord,
+ sizeof(struct HpmfwupgActionRecord)
+ + sizeof(struct HpmfwupgFirmwareImage))) {
+ lprintf(LOG_NOTICE, " Invalid Action record.");
+ rc = HPMFWUPG_ERROR;
+ }
}
+ return rc;
+}
- switch( pActionRecord->actionType )
- {
- case HPMFWUPG_ACTION_BACKUP_COMPONENTS:
- {
- pImagePtr += sizeof(struct HpmfwupgActionRecord);
+/* HpmfwupgPreUpgradeCheck - make pre-Upgrade check, this mainly helps in
+ * checking which all version upgrade is skippable because the image version
+ * is same as target version.
+ */
+int
+HpmfwupgPreUpgradeCheck(struct ipmi_intf *intf,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx,
+ int componentMask, int option)
+{
+ unsigned char *pImagePtr;
+ struct HpmfwupgActionRecord *pActionRecord;
+ struct HpmfwupgImageHeader *pImageHeader;
+ int componentId;
+ pImageHeader = (struct HpmfwupgImageHeader*)pFwupgCtx->pImageData;
+ /* Put pointer after image header */
+ pImagePtr = (unsigned char*)(pFwupgCtx->pImageData
+ + sizeof(struct HpmfwupgImageHeader)
+ + pImageHeader->oemDataLength
+ + sizeof(unsigned char)/*chksum*/);
+ if (option & VIEW_MODE) {
+ HpmDisplayVersionHeader(TARGET_VER|ROLLBACK_VER|IMAGE_VER);
}
- break;
-
- case HPMFWUPG_ACTION_PREPARE_COMPONENTS:
- {
- if (componentToUpload != DEFAULT_COMPONENT_UPLOAD) {
- if (!((1 << componentToUpload) &
- pActionRecord->components.ComponentBits.byte)) {
- lprintf(LOG_NOTICE,
- "\nComponent Id given is not supported\n");
- return HPMFWUPG_ERROR;
- }
+ /* Perform actions defined in the image */
+ while (pImagePtr < (pFwupgCtx->pImageData + pFwupgCtx->imageSize
+ - HPMFWUPG_MD5_SIGNATURE_LENGTH)) {
+ /* Get action record */
+ pActionRecord = (struct HpmfwupgActionRecord*)pImagePtr;
+ /* Validate action record checksum */
+ if (HpmfwupgValidateActionRecordChecksum(pActionRecord) != HPMFWUPG_SUCCESS) {
+ return HPMFWUPG_ERROR;
}
- pImagePtr += sizeof(struct HpmfwupgActionRecord);
- }
- break;
-
- case HPMFWUPG_ACTION_UPLOAD_FIRMWARE:
- /* Upload all firmware blocks */
- {
- struct HpmfwupgFirmwareImage *pFwImage;
- unsigned char *pData;
- unsigned int firmwareLength;
- unsigned char mode;
- unsigned char componentId;
- unsigned char componentIdByte;
- unsigned int upgrade_comp;
- VERSIONINFO *pVersionInfo;
- struct HpmfwupgGetComponentPropertiesCtx getCompProp;
-
- /* Save component ID on which the upload is done */
- componentIdByte = pActionRecord->components.ComponentBits.byte;
-
- componentId = 0;
- while ((componentIdByte >>= 1) !=0) {
- componentId++;
+ /* Validate affected components */
+ if (pActionRecord->components.ComponentBits.byte
+ && !pFwupgCtx->targetCap.componentsPresent.ComponentBits.byte) {
+ lprintf(LOG_NOTICE,
+ " Invalid action record. One or more affected components is not supported");
+ return HPMFWUPG_ERROR;
}
- pFwupgCtx->componentId = componentId;
-
- pFwImage = (struct HpmfwupgFirmwareImage*)(pImagePtr +
- sizeof(struct HpmfwupgActionRecord));
-
- pData = ((unsigned char*)pFwImage +
- sizeof(struct HpmfwupgFirmwareImage));
-
- /* Get firmware length */
- firmwareLength = pFwImage->length[0];
- firmwareLength |= (pFwImage->length[1] << 8) & 0xff00;
- firmwareLength |= (pFwImage->length[2] << 16) & 0xff0000;
- firmwareLength |= (pFwImage->length[3] << 24) & 0xff000000;
-
- pVersionInfo = &gVersionInfo[componentId];
-
- pVersionInfo->imageMajor = pFwImage->version[0];
- pVersionInfo->imageMinor = pFwImage->version[1];
- pVersionInfo->imageAux[0] = pFwImage->version[2];
- pVersionInfo->imageAux[1] = pFwImage->version[3];
- pVersionInfo->imageAux[2] = pFwImage->version[4];
- pVersionInfo->imageAux[3] = pFwImage->version[5];
-
- mode = TARGET_VER | IMAGE_VER;
-
- if (pVersionInfo->coldResetRequired)
- flagColdReset = TRUE;
-
- upgrade_comp = 0;
- if (option & FORCE_MODE_ALL) {
- upgrade_comp = 1;
- }
- else if ((option & FORCE_MODE_COMPONENT) &&
- (componentToUpload == componentId)) {
- upgrade_comp = 1;
- }
- else if (image_version_upgradable(pVersionInfo)) {
- upgrade_comp = 1;
- }
-
- if (verbose)
- lprintf(LOG_NOTICE,"%s component %d",
- (upgrade_comp ? "Updating" : "Skipping"),
- componentId);
-
- if (upgrade_comp)
- pFwupgCtx->compUpdateMask.ComponentBits.byte |=
- 1 << componentId;
-
- if (option & VIEW_MODE) {
- if (pVersionInfo->rollbackSupported)
- mode |= ROLLBACK_VER;
- HpmDisplayVersion(mode,pVersionInfo, upgrade_comp);
- printf("\n");
+ switch (pActionRecord->actionType) {
+ case HPMFWUPG_ACTION_BACKUP_COMPONENTS:
+ {
+ /* Make sure every component specified by
+ * this action record
+ * supports the backup operation
+ */
+ for (componentId = HPMFWUPG_COMPONENT_ID_0;
+ componentId < HPMFWUPG_COMPONENT_ID_MAX;
+ componentId++) {
+ if (((1 << componentId) & pActionRecord->components.ComponentBits.byte)
+ && pFwupgCtx->genCompProp[componentId].GeneralCompProperties.bitfield.rollbackBackup == 0) {
+ lprintf(LOG_NOTICE,
+ " Component ID %d does not support backup",
+ componentId);
+ return HPMFWUPG_ERROR;
+ }
+ }
+ pImagePtr += sizeof(struct HpmfwupgActionRecord);
+ }
+ break;
+ case HPMFWUPG_ACTION_PREPARE_COMPONENTS:
+ {
+ /* Make sure every components specified by
+ * this action
+ * supports the prepare operation
+ */
+ for (componentId = HPMFWUPG_COMPONENT_ID_0;
+ componentId < HPMFWUPG_COMPONENT_ID_MAX;
+ componentId++) {
+ if (((1 << componentId) & pActionRecord->components.ComponentBits.byte)
+ && pFwupgCtx->genCompProp[componentId].GeneralCompProperties.bitfield.preparationSupport == 0) {
+ lprintf(LOG_NOTICE,
+ " Component ID %d does not support preparation",
+ componentId);
+ return HPMFWUPG_ERROR;
+ }
+ }
+ pImagePtr += sizeof(struct HpmfwupgActionRecord);
+ }
+ break;
+ case HPMFWUPG_ACTION_UPLOAD_FIRMWARE:
+ /* Upload all firmware blocks */
+ {
+ struct HpmfwupgFirmwareImage *pFwImage;
+ unsigned char *pData;
+ unsigned int firmwareLength;
+ unsigned char mode;
+ unsigned char componentId;
+ unsigned char componentIdByte;
+ unsigned int upgrade_comp;
+ VERSIONINFO *pVersionInfo;
+ /* Save component ID on which the upload is done */
+ componentIdByte = pActionRecord->components.ComponentBits.byte;
+ componentId = 0;
+ while ((componentIdByte >>= 1) != 0) {
+ componentId++;
+ }
+ pFwImage = (struct HpmfwupgFirmwareImage*)(pImagePtr
+ + sizeof(struct HpmfwupgActionRecord));
+ pData = ((unsigned char*)pFwImage
+ + sizeof(struct HpmfwupgFirmwareImage));
+ /* Get firmware length */
+ firmwareLength = pFwImage->length[0];
+ firmwareLength |= (pFwImage->length[1] << 8) & 0xff00;
+ firmwareLength |= (pFwImage->length[2] << 16) & 0xff0000;
+ firmwareLength |= (pFwImage->length[3] << 24) & 0xff000000;
+
+ pVersionInfo = &gVersionInfo[componentId];
+
+ pVersionInfo->imageMajor = pFwImage->version[0];
+ pVersionInfo->imageMinor = pFwImage->version[1];
+ pVersionInfo->imageAux[0] = pFwImage->version[2];
+ pVersionInfo->imageAux[1] = pFwImage->version[3];
+ pVersionInfo->imageAux[2] = pFwImage->version[4];
+ pVersionInfo->imageAux[3] = pFwImage->version[5];
+
+ mode = TARGET_VER | IMAGE_VER;
+ /* check if component is selected for upgrade */
+ upgrade_comp = !componentMask
+ || (componentMask & pActionRecord->components.ComponentBits.byte);
+ /* check if current component version requires upgrade */
+ if (upgrade_comp && !(option & (FORCE_MODE|COMPARE_MODE))) {
+ upgrade_comp = image_version_upgradable(pVersionInfo);
+ }
+ if (verbose) {
+ lprintf(LOG_NOTICE,
+ "%s component %d",
+ (upgrade_comp ? "Updating" : "Skipping"),
+ componentId);
+ }
+ if (upgrade_comp) {
+ pFwupgCtx->compUpdateMask.ComponentBits.byte|= 1 << componentId;
+ }
+ if (option & VIEW_MODE) {
+ if (pVersionInfo->rollbackSupported) {
+ mode|= ROLLBACK_VER;
+ }
+ HpmDisplayVersion(mode,pVersionInfo, upgrade_comp);
+ printf("\n");
+ }
+ pImagePtr = pData + firmwareLength;
+ }
+ break;
+ default:
+ lprintf(LOG_NOTICE,
+ " Invalid Action type. Cannot continue");
+ return HPMFWUPG_ERROR;
+ break;
}
- pImagePtr = pData + firmwareLength;
}
- break;
- default:
+ if (option & VIEW_MODE) {
+ HpmDisplayLine("-",74);
+ fflush(stdout);
lprintf(LOG_NOTICE,
- " Invalid Action type. Cannot continue");
- return HPMFWUPG_ERROR;
- break;
+ "(*) Component requires Payload Cold Reset");
+ lprintf(LOG_NOTICE,
+ "(^) Indicates component would be upgraded");
}
- }
+ return HPMFWUPG_SUCCESS;
+}
- if (option & VIEW_MODE) {
- HpmDisplayLine("-",74);
+/* HpmfwupgUpgradeStage - upgrade stage of a firmware upgrade procedure as
+ * defined in section 3.3 of the IPM Controller Firmware Upgrade Specification
+ * version 1.0
+ */
+int
+HpmfwupgUpgradeStage(struct ipmi_intf *intf,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx, int option)
+{
+ struct HpmfwupgImageHeader *pImageHeader = (struct HpmfwupgImageHeader*)
+ pFwupgCtx->pImageData;
+ struct HpmfwupgActionRecord* pActionRecord;
+ int rc = HPMFWUPG_SUCCESS;
+ unsigned char *pImagePtr;
+ unsigned int actionsSize;
+ int flagColdReset = FALSE;
+ time_t start,end;
+ /* Put pointer after image header */
+ pImagePtr = (unsigned char*)
+ (pFwupgCtx->pImageData + sizeof(struct HpmfwupgImageHeader) +
+ pImageHeader->oemDataLength + sizeof(unsigned char)/*checksum*/);
+ /* Deternime actions size */
+ actionsSize = pFwupgCtx->imageSize - sizeof(struct HpmfwupgImageHeader);
+ if (!(option & VIEW_MODE)) {
+ HpmDisplayUpgradeHeader();
+ }
+ /* Perform actions defined in the image */
+ while (( pImagePtr < (pFwupgCtx->pImageData + pFwupgCtx->imageSize -
+ HPMFWUPG_MD5_SIGNATURE_LENGTH))
+ && (rc == HPMFWUPG_SUCCESS)) {
+ /* Get action record */
+ pActionRecord = (struct HpmfwupgActionRecord*)pImagePtr;
+ /* Validate action record checksum */
+ rc = HpmfwupgValidateActionRecordChecksum(pActionRecord);
+ if (rc != HPMFWUPG_SUCCESS) {
+ continue;
+ }
+ switch(pActionRecord->actionType) {
+ case HPMFWUPG_ACTION_BACKUP_COMPONENTS:
+ {
+ if (!(option & COMPARE_MODE)) {
+ /* Send Upgrade Action command */
+ struct HpmfwupgInitiateUpgradeActionCtx initUpgActionCmd;
+ /* Affect only selected components */
+ initUpgActionCmd.req.componentsMask.ComponentBits.byte =
+ pFwupgCtx->compUpdateMask.ComponentBits.byte &
+ pActionRecord->components.ComponentBits.byte;
+ /* Action is prepare components */
+ if (initUpgActionCmd.req.componentsMask.ComponentBits.byte) {
+ initUpgActionCmd.req.upgradeAction = HPMFWUPG_UPGRADE_ACTION_BACKUP;
+ rc = HpmfwupgInitiateUpgradeAction(intf, &initUpgActionCmd, pFwupgCtx);
+ }
+ }
+ pImagePtr+= sizeof(struct HpmfwupgActionRecord);
+ }
+ break;
+ case HPMFWUPG_ACTION_PREPARE_COMPONENTS:
+ {
+ if (!(option & COMPARE_MODE)) {
+ /* Send prepare components command */
+ struct HpmfwupgInitiateUpgradeActionCtx initUpgActionCmd;
+ /* Affect only selected components */
+ initUpgActionCmd.req.componentsMask.ComponentBits.byte =
+ pFwupgCtx->compUpdateMask.ComponentBits.byte &
+ pActionRecord->components.ComponentBits.byte;
+ if (initUpgActionCmd.req.componentsMask.ComponentBits.byte) {
+ /* Action is prepare components */
+ initUpgActionCmd.req.upgradeAction = HPMFWUPG_UPGRADE_ACTION_PREPARE;
+ rc = HpmfwupgInitiateUpgradeAction(intf, &initUpgActionCmd, pFwupgCtx);
+ }
+ }
+ pImagePtr+= sizeof(struct HpmfwupgActionRecord);
+ }
+ break;
+ case HPMFWUPG_ACTION_UPLOAD_FIRMWARE:
+ /* Upload all firmware blocks */
+ rc = HpmFwupgActionUploadFirmware(pActionRecord->components,
+ pFwupgCtx,
+ &pImagePtr,
+ intf,
+ option,
+ &flagColdReset);
+ break;
+ default:
+ lprintf(LOG_NOTICE, " Invalid Action type. Cannot continue");
+ rc = HPMFWUPG_ERROR;
+ break;
+ }
+ }
+ HpmDisplayLine("-", 79);
fflush(stdout);
- lprintf(LOG_NOTICE,"(*) Component requires Payload Cold Reset");
- lprintf(LOG_NOTICE,"(^) Indicates component would be upgraded");
- }
- return HPMFWUPG_SUCCESS;
+ lprintf(LOG_NOTICE, "(*) Component requires Payload Cold Reset");
+ return rc;
}
-
-/****************************************************************************
-*
-* Function Name: HpmfwupgUpgradeStage
-*
-* Description: This function the upgrade stage of a firmware upgrade
-* procedure as defined in section 3.3 of the IPM Controller
-* Firmware Upgrade Specification version 1.0
-*
-*****************************************************************************/
-int HpmfwupgUpgradeStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx,
- int componentToUpload, int option)
-{
- struct HpmfwupgImageHeader* pImageHeader = (struct HpmfwupgImageHeader*)
- pFwupgCtx->pImageData;
- struct HpmfwupgActionRecord* pActionRecord;
-
- int rc = HPMFWUPG_SUCCESS;
- unsigned char* pImagePtr;
- unsigned int actionsSize;
- int flagColdReset = FALSE;
- time_t start,end;
-
- /* Put pointer after image header */
- pImagePtr = (unsigned char*)
- (pFwupgCtx->pImageData + sizeof(struct HpmfwupgImageHeader) +
- pImageHeader->oemDataLength + sizeof(unsigned char)/*checksum*/);
-
- /* Deternime actions size */
- actionsSize = pFwupgCtx->imageSize - sizeof(struct HpmfwupgImageHeader);
-
- if (option & VERSIONCHECK_MODE || option & FORCE_MODE)
- {
- HpmDisplayUpgradeHeader();
- }
-
- /* Perform actions defined in the image */
- while( ( pImagePtr < (pFwupgCtx->pImageData + pFwupgCtx->imageSize -
- HPMFWUPG_MD5_SIGNATURE_LENGTH)) &&
- ( rc == HPMFWUPG_SUCCESS) )
- {
- /* Get action record */
- pActionRecord = (struct HpmfwupgActionRecord*)pImagePtr;
-
- /* Validate action record checksum */
- if ( HpmfwupgCalculateChecksum((unsigned char*)pActionRecord,
- sizeof(struct HpmfwupgActionRecord)) != 0 )
- {
- lprintf(LOG_NOTICE," Invalid Action record.");
- rc = HPMFWUPG_ERROR;
- }
-
- if ( rc == HPMFWUPG_SUCCESS )
- {
- switch( pActionRecord->actionType )
- {
- case HPMFWUPG_ACTION_BACKUP_COMPONENTS:
- {
- /* Send prepare components command */
- struct HpmfwupgInitiateUpgradeActionCtx initUpgActionCmd;
-
- initUpgActionCmd.req.componentsMask = pFwupgCtx->compUpdateMask;
- /* Action is prepare components */
- initUpgActionCmd.req.upgradeAction = HPMFWUPG_UPGRADE_ACTION_BACKUP;
- rc = HpmfwupgInitiateUpgradeAction(intf, &initUpgActionCmd, pFwupgCtx);
- pImagePtr += sizeof(struct HpmfwupgActionRecord);
-
- }
- break;
- case HPMFWUPG_ACTION_PREPARE_COMPONENTS:
- {
- int componentId;
- /* Make sure every components specified by this action
- supports the prepare components */
-
- /* Component 'filtering' is done in PreUpdateCheck() and pFwupgCtx is set accordiongly */
-
- for ( componentId = HPMFWUPG_COMPONENT_ID_0;
- componentId < HPMFWUPG_COMPONENT_ID_MAX;
- componentId++ )
- {
- if ( (1 << componentId & pFwupgCtx->compUpdateMask.ComponentBits.byte) )
- {
- if ( pFwupgCtx->genCompProp[componentId].GeneralCompProperties.bitfield.preparationSupport == 0 )
- {
- lprintf(LOG_NOTICE," Prepare component not supported by component ID %d", componentId);
- rc = HPMFWUPG_ERROR;
- break;
- }
- }
- }
-
- if ( rc == HPMFWUPG_SUCCESS )
- {
- if ( pFwupgCtx->compUpdateMask.ComponentBits.byte != 0x00 )
- {
- /* Send prepare components command */
- struct HpmfwupgInitiateUpgradeActionCtx initUpgActionCmd;
- initUpgActionCmd.req.componentsMask = pFwupgCtx->compUpdateMask;
- /* Action is prepare components */
- initUpgActionCmd.req.upgradeAction = HPMFWUPG_UPGRADE_ACTION_PREPARE;
- rc = HpmfwupgInitiateUpgradeAction(intf, &initUpgActionCmd, pFwupgCtx);
-
- }
- pImagePtr += sizeof(struct HpmfwupgActionRecord);
- }
- }
- break;
-
- case HPMFWUPG_ACTION_UPLOAD_FIRMWARE:
- /* Upload all firmware blocks */
- rc = HpmFwupgActionUploadFirmware
- (
- pActionRecord->components,
- pFwupgCtx,
- &pImagePtr,
- componentToUpload,
- intf,
- option,
- &flagColdReset
- );
-
- break;
- default:
- lprintf(LOG_NOTICE," Invalid Action type. Cannot continue");
- rc = HPMFWUPG_ERROR;
- break;
- }
- }
- }
-
- HpmDisplayLine("-",79);
-
- fflush(stdout);
- lprintf(LOG_NOTICE,"(*) Component requires Payload Cold Reset");
-
- return rc;
+int
+get_max_rq_data_size(struct ipmi_intf *intf)
+{
+ int bufLength;
+ /* Check if we receive size in parameters */
+ if(intf->channel_buf_size != 0) {
+ /* Plan for overhead */
+ if (intf->target_addr == intf->my_addr) {
+ bufLength = intf->channel_buf_size - 9;
+ } else {
+ bufLength = intf->channel_buf_size - 11;
+ }
+ } else if (strstr(intf->name,"lan") != NULL) {
+ /* Find max buffer length according the connection
+ * parameters
+ */
+ bufLength = HPMFWUPG_SEND_DATA_COUNT_LAN - 2;
+ if (intf->transit_addr != intf->my_addr
+ && intf->transit_addr != 0) {
+ bufLength -= 8;
+ }
+ } else if (strstr(intf->name,"open") != NULL
+ && intf->target_addr == intf->my_addr) {
+ bufLength = HPMFWUPG_SEND_DATA_COUNT_KCS - 2;
+ } else if (intf->target_channel == 7) {
+ bufLength = HPMFWUPG_SEND_DATA_COUNT_IPMBL;
+ } else {
+ bufLength = HPMFWUPG_SEND_DATA_COUNT_IPMB;
+ }
+ return bufLength;
}
-static int HpmFwupgActionUploadFirmware
-(
- struct HpmfwupgComponentBitMask components,
- struct HpmfwupgUpgradeCtx* pFwupgCtx,
- unsigned char** pImagePtr,
- int componentToUpload,
- struct ipmi_intf *intf,
- int option,
- int *pFlagColdReset
-)
-{
- struct HpmfwupgFirmwareImage* pFwImage;
- struct HpmfwupgInitiateUpgradeActionCtx initUpgActionCmd;
- struct HpmfwupgUploadFirmwareBlockCtx uploadCmd;
- struct HpmfwupgFinishFirmwareUploadCtx finishCmd;
- struct HpmfwupgGetComponentPropertiesCtx getCompProp;
- VERSIONINFO *pVersionInfo;
- time_t start,end;
-
- int rc = HPMFWUPG_SUCCESS;
- int skip = TRUE;
- unsigned char* pData, *pDataInitial;
- unsigned char count;
- unsigned int totalSent = 0;
- unsigned char bufLength = 0;
- unsigned int firmwareLength = 0;
-
- unsigned int displayFWLength = 0;
- unsigned char *pDataTemp;
- unsigned int imageOffset = 0x00;
- unsigned int blockLength = 0x00;
- unsigned int lengthOfBlock = 0x00;
- unsigned int numTxPkts = 0;
- unsigned int numRxPkts = 0;
- unsigned char mode = 0;
- unsigned char componentId = 0x00;
- unsigned char componentIdByte = 0x00;
-
- /* Save component ID on which the upload is done */
- componentIdByte = components.ComponentBits.byte;
- while ((componentIdByte>>=1)!=0)
- {
- componentId++;
- }
- pFwupgCtx->componentId = componentId;
-
- pVersionInfo = (VERSIONINFO*) &gVersionInfo[componentId];
-
- pFwImage = (struct HpmfwupgFirmwareImage*)((*pImagePtr) +
- sizeof(struct HpmfwupgActionRecord));
-
- pDataInitial = ((unsigned char*)pFwImage + sizeof(struct HpmfwupgFirmwareImage));
- pData = pDataInitial;
-
- /* Get firmware length */
- firmwareLength = pFwImage->length[0];
- firmwareLength |= (pFwImage->length[1] << 8) & 0xff00;
- firmwareLength |= (pFwImage->length[2] << 16) & 0xff0000;
- firmwareLength |= (pFwImage->length[3] << 24) & 0xff000000;
-
- mode = TARGET_VER | IMAGE_VER;
-
- if (pVersionInfo->rollbackSupported)
- {
- mode |= ROLLBACK_VER;
+int
+HpmFwupgActionUploadFirmware(struct HpmfwupgComponentBitMask components,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx,
+ unsigned char **pImagePtr,
+ struct ipmi_intf *intf,
+ int option,
+ int *pFlagColdReset)
+{
+ struct HpmfwupgFirmwareImage *pFwImage;
+ struct HpmfwupgInitiateUpgradeActionCtx initUpgActionCmd;
+ struct HpmfwupgUploadFirmwareBlockCtx uploadCmd;
+ struct HpmfwupgFinishFirmwareUploadCtx finishCmd;
+ VERSIONINFO *pVersionInfo;
+ time_t start,end;
+
+ int rc = HPMFWUPG_SUCCESS;
+ int skip = TRUE;
+ unsigned char *pData, *pDataInitial;
+ unsigned short count;
+ unsigned int totalSent = 0;
+ unsigned short bufLength = 0;
+ unsigned short bufLengthIsSet = 0;
+ unsigned int firmwareLength = 0;
+
+ unsigned int displayFWLength = 0;
+ unsigned char *pDataTemp;
+ unsigned int imageOffset = 0x00;
+ unsigned int blockLength = 0x00;
+ unsigned int lengthOfBlock = 0x00;
+ unsigned int numTxPkts = 0;
+ unsigned int numRxPkts = 0;
+ unsigned char mode = 0;
+ unsigned char componentId = 0x00;
+ unsigned char componentIdByte = 0x00;
+ /* Save component ID on which the upload is done */
+ componentIdByte = components.ComponentBits.byte;
+ while ((componentIdByte>>= 1) != 0) {
+ componentId++;
}
-
- if ((option & DEBUG_MODE))
- {
- printf("\n\n Comp ID : %d [%-20s]\n",pVersionInfo->componentId,pFwImage->desc);
+ pFwupgCtx->componentId = componentId;
+ pVersionInfo = (VERSIONINFO *)&gVersionInfo[componentId];
+ pFwImage = (struct HpmfwupgFirmwareImage*)((*pImagePtr)
+ + sizeof(struct HpmfwupgActionRecord));
+ pDataInitial = ((unsigned char *)pFwImage
+ + sizeof(struct HpmfwupgFirmwareImage));
+ pData = pDataInitial;
+ /* Find max buffer length according the connection parameters */
+ bufLength = get_max_rq_data_size(intf);
+ /* Get firmware length */
+ firmwareLength = pFwImage->length[0];
+ firmwareLength|= (pFwImage->length[1] << 8) & 0xff00;
+ firmwareLength|= (pFwImage->length[2] << 16) & 0xff0000;
+ firmwareLength|= (pFwImage->length[3] << 24) & 0xff000000;
+ mode = TARGET_VER | IMAGE_VER;
+ if (pVersionInfo->rollbackSupported) {
+ mode |= ROLLBACK_VER;
}
- else
- {
- HpmDisplayVersion(mode,pVersionInfo, 0);
+ if ((option & DEBUG_MODE)) {
+ printf("\n\n Comp ID : %d [%-20s]\n",
+ pVersionInfo->componentId,
+ pFwImage->desc);
+ } else {
+ HpmDisplayVersion(mode, pVersionInfo, 0);
}
-
- if( (1 << componentId) & pFwupgCtx->compUpdateMask.ComponentBits.byte)
- {
- if( verbose ) {
- lprintf(LOG_NOTICE,"Do not skip %d" , componentId);
+ if ((1 << componentId) & pFwupgCtx->compUpdateMask.ComponentBits.byte) {
+ if (verbose) {
+ lprintf(LOG_NOTICE, "Do not skip %d",
+ componentId);
}
skip = FALSE;
}
-
- if(!skip)
- {
- HpmDisplayUpgrade(0,0,1,0);
- /* Initialize parameters */
- uploadCmd.req.blockNumber = 0;
-
- /* Check if we receive size in parameters */
- if(intf->channel_buf_size != 0)
- {
- if (intf->target_addr == intf->my_addr)
- {
- bufLength = intf->channel_buf_size - 9; /* Plan for overhead */
- }
- else
- {
- bufLength = intf->channel_buf_size - 11; /* Plan for overhead */
- }
- }
- else
- {
- /* Find max buffer length according the connection parameters */
- if ( strstr(intf->name,"lan") != NULL )
- {
- bufLength = HPMFWUPG_SEND_DATA_COUNT_LAN - 2;
- if ( intf->transit_addr != intf->my_addr && intf->transit_addr != 0 )
- bufLength -= 8;
- }
- else
- {
- if
- (
- strstr(intf->name,"open") != NULL
- &&
- (
- intf->target_addr == intf->my_addr
- )
- )
- {
- bufLength = HPMFWUPG_SEND_DATA_COUNT_KCS - 2;
- }
- else
- {
- if ( intf->target_channel == 7 )
- {
- bufLength = HPMFWUPG_SEND_DATA_COUNT_IPMBL;
- }
- else
- {
- bufLength = HPMFWUPG_SEND_DATA_COUNT_IPMB;
- }
- }
- }
- }
-
- /* Send Initiate Upgrade Action */
- initUpgActionCmd.req.componentsMask = components;
- /* Action is upgrade */
- initUpgActionCmd.req.upgradeAction = HPMFWUPG_UPGRADE_ACTION_UPGRADE;
- rc = HpmfwupgInitiateUpgradeAction(intf, &initUpgActionCmd, pFwupgCtx);
-
- if (rc != HPMFWUPG_SUCCESS)
- {
- skip = TRUE;
- }
-
- if ( (pVersionInfo->coldResetRequired) && (!skip))
- {
- *pFlagColdReset = TRUE;
- }
- /* pDataInitial is the starting pointer of the image data */
- /* pDataTemp is one which we will move across */
- pData = pDataInitial;
- pDataTemp = pDataInitial;
- lengthOfBlock = firmwareLength;
- totalSent = 0x00;
- displayFWLength= firmwareLength;
- time(&start);
-
-
- while ( (pData < (pDataTemp+lengthOfBlock)) && (rc == HPMFWUPG_SUCCESS) )
- {
- if ( (pData+bufLength) <= (pDataTemp+lengthOfBlock) )
- {
- count = bufLength;
- }
- else
- {
- count = (unsigned char)((pDataTemp+lengthOfBlock) - pData);
- }
- memcpy(&uploadCmd.req.data, pData, bufLength);
-
- imageOffset = 0x00;
- blockLength = 0x00;
- numTxPkts++;
- rc = HpmfwupgUploadFirmwareBlock(intf, &uploadCmd, pFwupgCtx, count,
- &imageOffset,&blockLength);
- numRxPkts++;
-
- if ( rc != HPMFWUPG_SUCCESS)
- {
- if ( rc == HPMFWUPG_UPLOAD_BLOCK_LENGTH )
- {
- /* Retry with a smaller buffer length */
- if ( strstr(intf->name,"lan") != NULL )
- {
- bufLength -= (unsigned char)8;
- lprintf(LOG_INFO,"Trying reduced buffer length: %d", bufLength);
- }
- else
- {
- bufLength -= (unsigned char)1;
- lprintf(LOG_INFO,"Trying reduced buffer length: %d", bufLength);
- }
- rc = HPMFWUPG_SUCCESS;
- }
- else if ( rc == HPMFWUPG_UPLOAD_RETRY )
- {
- rc = HPMFWUPG_SUCCESS;
- }
- else
- {
- fflush(stdout);
- lprintf(LOG_NOTICE,"\n Error in Upload FIRMWARE command [rc=%d]\n",rc);
- lprintf(LOG_NOTICE,"\n TotalSent:0x%x ",totalSent);
- /* Exiting from the function */
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- if (blockLength > firmwareLength)
- {
- /*
- * blockLength is the remaining length of the firmware to upload so
- * if its greater than the firmware length then its kind of error
- */
- lprintf(LOG_NOTICE,"\n Error in Upload FIRMWARE command [rc=%d]\n",rc);
- lprintf(LOG_NOTICE,"\n TotalSent:0x%x Img offset:0x%x Blk length:0x%x Fwlen:0x%x\n",
- totalSent,imageOffset,blockLength,firmwareLength);
- rc = HPMFWUPG_ERROR;
- }
- totalSent += count;
- if (imageOffset != 0x00)
- {
- /* block Length is valid */
- lengthOfBlock = blockLength;
- pDataTemp = pDataInitial + imageOffset;
- pData = pDataTemp;
- if ( displayFWLength == firmwareLength)
- {
- /* This is basically used only to make sure that we display uptil 100% */
- displayFWLength = blockLength + totalSent;
- }
- }
- else
- {
- pData += count;
- }
- time(&end);
- /*
- * Just added debug mode in case we need to see exactly how many bytes have
- * gone through - Its a hidden option used mainly should be used for debugging
- */
- if ( option & DEBUG_MODE)
- {
- fflush(stdout);
- printf(" Blk Num : %02x Bytes : %05x ",
- uploadCmd.req.blockNumber,totalSent);
- if (imageOffset || blockLength)
- {
- printf("\n--> ImgOff : %x BlkLen : %x\n",imageOffset,blockLength);
- }
- if (displayFWLength == totalSent)
- {
- printf("\n Time Taken %02ld:%02ld",(end-start)/60, (end-start)%60);
- printf("\n\n");
- }
- }
- else
- {
- HpmDisplayUpgrade(0,totalSent,displayFWLength,(end-start));
- }
- uploadCmd.req.blockNumber++;
- }
- }
- }
-
- if (skip)
- {
-
- HpmDisplayUpgrade(1,0,0,0);
- *pImagePtr = pDataInitial + firmwareLength;
- }
-
- if
- (
- (rc == HPMFWUPG_SUCCESS)
- &&
- (!skip)
- )
- {
- /* Send finish component */
- /* Set image length */
- finishCmd.req.componentId = componentId;
- /* We need to send the actual data that is sent
- * not the comlete firmware image length
- */
- finishCmd.req.imageLength[0] = totalSent & 0xFF;
- finishCmd.req.imageLength[1] = (totalSent >> 8) & 0xFF;
- finishCmd.req.imageLength[2] = (totalSent >> 16) & 0xFF;
- finishCmd.req.imageLength[3] = (totalSent >> 24) & 0xFF;
- rc = HpmfwupgFinishFirmwareUpload(intf, &finishCmd, pFwupgCtx);
- *pImagePtr = pDataInitial + firmwareLength;
- }
-
- return rc;
+ if (!skip) {
+ HpmDisplayUpgrade(0,0,1,0);
+ /* Initialize parameters */
+ uploadCmd.req = malloc(get_max_rq_data_size(intf)
+ + sizeof(struct HpmfwupgUploadFirmwareBlockReq));
+ if (!uploadCmd.req) {
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
+ return HPMFWUPG_ERROR;
+ }
+ uploadCmd.req->blockNumber = 0;
+ /* Send Initiate Upgrade Action */
+ initUpgActionCmd.req.componentsMask = components;
+ if (option & COMPARE_MODE) {
+ /* Action is compare */
+ initUpgActionCmd.req.upgradeAction = HPMFWUPG_UPGRADE_ACTION_COMPARE;
+ } else {
+ /* Action is upgrade */
+ initUpgActionCmd.req.upgradeAction = HPMFWUPG_UPGRADE_ACTION_UPGRADE;
+ }
+ rc = HpmfwupgInitiateUpgradeAction(intf, &initUpgActionCmd, pFwupgCtx);
+ if (rc != HPMFWUPG_SUCCESS) {
+ skip = TRUE;
+ }
+ if ((pVersionInfo->coldResetRequired) && (!skip)) {
+ *pFlagColdReset = TRUE;
+ }
+ /* pDataInitial is the starting pointer of the image data */
+ /* pDataTemp is one which we will move across */
+ pData = pDataInitial;
+ pDataTemp = pDataInitial;
+ lengthOfBlock = firmwareLength;
+ totalSent = 0x00;
+ displayFWLength= firmwareLength;
+ time(&start);
+ while ((pData < (pDataTemp+lengthOfBlock)) && (rc == HPMFWUPG_SUCCESS)) {
+ if ((pData+bufLength) <= (pDataTemp+lengthOfBlock)) {
+ count = bufLength;
+ } else {
+ count = (unsigned short)((pDataTemp+lengthOfBlock) - pData);
+ }
+ memcpy(&uploadCmd.req->data, pData, bufLength);
+ imageOffset = 0x00;
+ blockLength = 0x00;
+ numTxPkts++;
+ rc = HpmfwupgUploadFirmwareBlock(intf, &uploadCmd,
+ pFwupgCtx, count, &imageOffset,&blockLength);
+ numRxPkts++;
+ if (rc != HPMFWUPG_SUCCESS) {
+ if (rc == HPMFWUPG_UPLOAD_BLOCK_LENGTH && !bufLengthIsSet) {
+ rc = HPMFWUPG_SUCCESS;
+ /* Retry with a smaller buffer length */
+ if (strstr(intf->name,"lan") != NULL && bufLength > 8) {
+ bufLength-= 8;
+ lprintf(LOG_INFO,
+ "Trying reduced buffer length: %d",
+ bufLength);
+ } else if (bufLength) {
+ bufLength-= 1;
+ lprintf(LOG_INFO,
+ "Trying reduced buffer length: %d",
+ bufLength);
+ } else {
+ rc = HPMFWUPG_ERROR;
+ }
+ } else if (rc == HPMFWUPG_UPLOAD_RETRY) {
+ rc = HPMFWUPG_SUCCESS;
+ } else {
+ fflush(stdout);
+ lprintf(LOG_NOTICE,
+ "\n Error in Upload FIRMWARE command [rc=%d]\n",
+ rc);
+ lprintf(LOG_NOTICE,
+ "\n TotalSent:0x%x ",
+ totalSent);
+ /* Exiting from the function */
+ rc = HPMFWUPG_ERROR;
+ }
+ } else {
+ /* success, buf length is valid */
+ bufLengthIsSet = 1;
+ if (blockLength > firmwareLength) {
+ /*
+ * blockLength is the remaining length of the firmware to upload so
+ * if its greater than the firmware length then its kind of error
+ */
+ lprintf(LOG_NOTICE,
+ "\n Error in Upload FIRMWARE command [rc=%d]\n",
+ rc);
+ lprintf(LOG_NOTICE,
+ "\n TotalSent:0x%x Img offset:0x%x Blk length:0x%x Fwlen:0x%x\n",
+ totalSent,imageOffset,blockLength,firmwareLength);
+ rc = HPMFWUPG_ERROR;
+ }
+ totalSent += count;
+ if (imageOffset != 0x00) {
+ /* block Length is valid */
+ lengthOfBlock = blockLength;
+ pDataTemp = pDataInitial + imageOffset;
+ pData = pDataTemp;
+ if (displayFWLength == firmwareLength) {
+ /* This is basically used only to make sure that we display uptil 100% */
+ displayFWLength = blockLength + totalSent;
+ }
+ } else {
+ pData += count;
+ }
+ time(&end);
+ /*
+ * Just added debug mode in case we need to see exactly how many bytes have
+ * gone through - Its a hidden option used mainly should be used for debugging
+ */
+ if (option & DEBUG_MODE) {
+ fflush(stdout);
+ printf(" Blk Num : %02x Bytes : %05x ",
+ uploadCmd.req->blockNumber,totalSent);
+ if (imageOffset || blockLength) {
+ printf("\n--> ImgOff : %x BlkLen : %x\n",
+ imageOffset,blockLength);
+ }
+ if (displayFWLength == totalSent) {
+ printf("\n Time Taken %02ld:%02ld",
+ (end-start)/60, (end-start)%60);
+ printf("\n\n");
+ }
+ } else {
+ HpmDisplayUpgrade(0, totalSent,
+ displayFWLength, (end-start));
+ }
+ uploadCmd.req->blockNumber++;
+ }
+ }
+ /* free buffer */
+ free(uploadCmd.req);
+ uploadCmd.req = NULL;
+ }
+ if (skip) {
+ HpmDisplayUpgrade(1,0,0,0);
+ if ((option & COMPARE_MODE)
+ && !pFwupgCtx->genCompProp[pFwupgCtx->componentId].GeneralCompProperties.bitfield.comparisonSupport) {
+ printf("| |Comparison isn't supported for given compenent. |\n");
+ }
+ *pImagePtr = pDataInitial + firmwareLength;
+ }
+ if (rc == HPMFWUPG_SUCCESS && !skip) {
+ /* Send finish component */
+ /* Set image length */
+ finishCmd.req.componentId = componentId;
+ /* We need to send the actual data that is sent
+ * not the comlete firmware image length
+ */
+ finishCmd.req.imageLength[0] = totalSent & 0xFF;
+ finishCmd.req.imageLength[1] = (totalSent >> 8) & 0xFF;
+ finishCmd.req.imageLength[2] = (totalSent >> 16) & 0xFF;
+ finishCmd.req.imageLength[3] = (totalSent >> 24) & 0xFF;
+ rc = HpmfwupgFinishFirmwareUpload(intf, &finishCmd,
+ pFwupgCtx, option);
+ *pImagePtr = pDataInitial + firmwareLength;
+ }
+ return rc;
}
-/****************************************************************************
-*
-* Function Name: HpmfwupgActivationStage
-*
-* Description: This function the validation stage of a firmware upgrade
-* procedure as defined in section 3.4 of the IPM Controller
-* Firmware Upgrade Specification version 1.0
-*
-*****************************************************************************/
-static int HpmfwupgActivationStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx)
-{
- int rc = HPMFWUPG_SUCCESS;
- struct HpmfwupgActivateFirmwareCtx activateCmd;
- struct HpmfwupgImageHeader* pImageHeader = (struct HpmfwupgImageHeader*)
- pFwupgCtx->pImageData;
-
- /* Print out stuf...*/
- printf(" ");
- fflush(stdout);
- /* Activate new firmware */
- rc = HpmfwupgActivateFirmware(intf, &activateCmd, pFwupgCtx);
-
- if ( rc == HPMFWUPG_SUCCESS )
- {
- /* Query self test result if supported by target and new image */
- if ( (pFwupgCtx->targetCap.GlobalCapabilities.bitField.ipmcSelftestCap == 1) ||
- (pImageHeader->imageCapabilities.bitField.imageSelfTest == 1) )
- {
- struct HpmfwupgQuerySelftestResultCtx selfTestCmd;
- rc = HpmfwupgQuerySelftestResult(intf, &selfTestCmd, pFwupgCtx);
-
- if ( rc == HPMFWUPG_SUCCESS )
- {
- /* Get the self test result */
- if ( selfTestCmd.resp.result1 != 0x55 )
- {
- /* Perform manual rollback if necessary */
- /* BACKUP/ MANUAL ROLLBACK not supported by this UA */
- lprintf(LOG_NOTICE," Self test failed:");
- lprintf(LOG_NOTICE," Result1 = %x", selfTestCmd.resp.result1);
- lprintf(LOG_NOTICE," Result2 = %x", selfTestCmd.resp.result2);
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- /* Perform manual rollback if necessary */
- /* BACKUP / MANUAL ROLLBACK not supported by this UA */
- lprintf(LOG_NOTICE," Self test failed.");
- }
- }
- }
-
- /* If activation / self test failed, query rollback status if automatic rollback supported */
- if ( rc == HPMFWUPG_ERROR )
- {
- if ( (pFwupgCtx->targetCap.GlobalCapabilities.bitField.autRollback == 1) &&
- (pFwupgCtx->genCompProp[pFwupgCtx->componentId].GeneralCompProperties.bitfield.rollbackBackup != 0x00) )
- {
- struct HpmfwupgQueryRollbackStatusCtx rollCmd;
- lprintf(LOG_NOTICE," Getting rollback status...");
- fflush(stdout);
- rc = HpmfwupgQueryRollbackStatus(intf, &rollCmd, pFwupgCtx);
- }
- }
-
- return rc;
+/* HpmfwupgActivationStage - validate stage of a firmware upgrade procedure as
+ * defined in section 3.4 of the IPM Controller Firmware Upgrade Specification
+ * version 1.0
+ */
+int
+HpmfwupgActivationStage(struct ipmi_intf *intf,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx)
+{
+ int rc = HPMFWUPG_SUCCESS;
+ struct HpmfwupgActivateFirmwareCtx activateCmd;
+ struct HpmfwupgImageHeader *pImageHeader = (struct HpmfwupgImageHeader*)
+ pFwupgCtx->pImageData;
+ /* Print out stuf...*/
+ printf(" ");
+ fflush(stdout);
+ /* Activate new firmware */
+ activateCmd.req.rollback_override = 0;
+ rc = HpmfwupgActivateFirmware(intf, &activateCmd, pFwupgCtx);
+ if (rc == HPMFWUPG_SUCCESS) {
+ /* Query self test result if supported by target and new image */
+ if ((pFwupgCtx->targetCap.GlobalCapabilities.bitField.ipmcSelftestCap == 1)
+ || (pImageHeader->imageCapabilities.bitField.imageSelfTest == 1)) {
+ struct HpmfwupgQuerySelftestResultCtx selfTestCmd;
+ rc = HpmfwupgQuerySelftestResult(intf, &selfTestCmd,
+ pFwupgCtx);
+ if (rc == HPMFWUPG_SUCCESS) {
+ /* Get the self test result */
+ if (selfTestCmd.resp.result1 != 0x55) {
+ /* Perform manual rollback if necessary */
+ /* BACKUP/ MANUAL ROLLBACK not supported by this UA */
+ lprintf(LOG_NOTICE, " Self test failed:");
+ lprintf(LOG_NOTICE, " Result1 = %x",
+ selfTestCmd.resp.result1);
+ lprintf(LOG_NOTICE, " Result2 = %x",
+ selfTestCmd.resp.result2);
+ rc = HPMFWUPG_ERROR;
+ }
+ } else {
+ /* Perform manual rollback if necessary */
+ /* BACKUP / MANUAL ROLLBACK not supported by this UA */
+ lprintf(LOG_NOTICE," Self test failed.");
+ }
+ }
+ }
+ /* If activation / self test failed, query rollback
+ * status if automatic rollback supported
+ */
+ if (rc == HPMFWUPG_ERROR) {
+ if ((pFwupgCtx->targetCap.GlobalCapabilities.bitField.autRollback == 1)
+ && (pFwupgCtx->genCompProp[pFwupgCtx->componentId].GeneralCompProperties.bitfield.rollbackBackup != 0x00)) {
+ struct HpmfwupgQueryRollbackStatusCtx rollCmd;
+ lprintf(LOG_NOTICE," Getting rollback status...");
+ fflush(stdout);
+ rc = HpmfwupgQueryRollbackStatus(intf,
+ &rollCmd, pFwupgCtx);
+ }
+ }
+ return rc;
}
-int HpmfwupgGetBufferFromFile(char* imageFilename, struct HpmfwupgUpgradeCtx* pFwupgCtx)
+int
+HpmfwupgGetBufferFromFile(char *imageFilename,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx)
{
- int rc = HPMFWUPG_SUCCESS;
- int ret = 0;
- FILE* pImageFile = fopen(imageFilename, "rb");
-
- if ( pImageFile == NULL )
- {
- lprintf(LOG_NOTICE,"Cannot open image file %s", imageFilename);
- rc = HPMFWUPG_ERROR;
- }
-
- if ( rc == HPMFWUPG_SUCCESS )
- {
- /* Get the raw data in file */
- fseek(pImageFile, 0, SEEK_END);
- pFwupgCtx->imageSize = ftell(pImageFile);
- pFwupgCtx->pImageData = malloc(sizeof(unsigned char)*pFwupgCtx->imageSize);
- pFwupgCtx->compUpdateMask.ComponentBits.byte = 0;
- rewind(pImageFile);
- if ( pFwupgCtx->pImageData != NULL )
- {
- ret = fread(pFwupgCtx->pImageData, sizeof(unsigned char),
- pFwupgCtx->imageSize, pImageFile);
- if (ret != pFwupgCtx->imageSize) {
- lprintf(LOG_ERROR,"Failed to read file %s size %d",
- imageFilename, pFwupgCtx->imageSize);
+ int rc = HPMFWUPG_SUCCESS;
+ int ret = 0;
+ FILE *pImageFile = fopen(imageFilename, "rb");
+ if (pImageFile == NULL) {
+ lprintf(LOG_ERR, "Cannot open image file '%s'",
+ imageFilename);
+ return HPMFWUPG_ERROR;
+ }
+ /* Get the raw data in file */
+ fseek(pImageFile, 0, SEEK_END);
+ pFwupgCtx->imageSize = ftell(pImageFile);
+ pFwupgCtx->pImageData = malloc(sizeof(unsigned char)*pFwupgCtx->imageSize);
+ if (pFwupgCtx->pImageData == NULL) {
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
+ fclose(pImageFile);
+ return HPMFWUPG_ERROR;
+ }
+ rewind(pImageFile);
+ ret = fread(pFwupgCtx->pImageData,
+ sizeof(unsigned char),
+ pFwupgCtx->imageSize,
+ pImageFile);
+ if (ret != pFwupgCtx->imageSize) {
+ lprintf(LOG_ERR,
+ "Failed to read file %s size %d",
+ imageFilename,
+ pFwupgCtx->imageSize);
rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- rc = HPMFWUPG_ERROR;
- }
-
- fclose(pImageFile);
- }
-
- return rc;
+ }
+ fclose(pImageFile);
+ return rc;
}
-int HpmfwupgGetDeviceId(struct ipmi_intf *intf, struct ipm_devid_rsp* pGetDevId)
+int
+HpmfwupgGetDeviceId(struct ipmi_intf *intf, struct ipm_devid_rsp *pGetDevId)
{
- int rc = HPMFWUPG_SUCCESS;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_APP;
- req.msg.cmd = BMC_GET_DEVICE_ID;
- req.msg.data_len = 0;
-
- rsp = HpmfwupgSendCmd(intf, req, NULL);
-
- if ( rsp )
- {
- if ( rsp->ccode == 0x00 )
- {
- memcpy(pGetDevId, rsp->data, sizeof(struct ipm_devid_rsp));
- }
- else
- {
- lprintf(LOG_NOTICE,"Error getting device ID");
- lprintf(LOG_NOTICE,"compcode=0x%x: %s",
- rsp->ccode,
- val2str(rsp->ccode, completion_code_vals));
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"Error getting device ID\n");
- rc = HPMFWUPG_ERROR;
- }
- return rc;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_APP;
+ req.msg.cmd = BMC_GET_DEVICE_ID;
+ req.msg.data_len = 0;
+ rsp = HpmfwupgSendCmd(intf, req, NULL);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Error getting device ID.");
+ return HPMFWUPG_ERROR;
+ }
+ if (rsp->ccode != 0x00) {
+ lprintf(LOG_ERR, "Error getting device ID.");
+ lprintf(LOG_ERR, "compcode=0x%x: %s",
+ rsp->ccode,
+ val2str(rsp->ccode, completion_code_vals));
+ return HPMFWUPG_ERROR;
+ }
+ memcpy(pGetDevId, rsp->data, sizeof(struct ipm_devid_rsp));
+ return HPMFWUPG_SUCCESS;
}
-int HpmfwupgGetTargetUpgCapabilities(struct ipmi_intf *intf,
- struct HpmfwupgGetTargetUpgCapabilitiesCtx* pCtx)
+int
+HpmfwupgGetTargetUpgCapabilities(struct ipmi_intf *intf,
+ struct HpmfwupgGetTargetUpgCapabilitiesCtx *pCtx)
{
- int rc = HPMFWUPG_SUCCESS;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
-
- pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = HPMFWUPG_GET_TARGET_UPG_CAPABILITIES;
- req.msg.data = (unsigned char*)&pCtx->req;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = HPMFWUPG_GET_TARGET_UPG_CAPABILITIES;
+ req.msg.data = (unsigned char*)&pCtx->req;
req.msg.data_len = sizeof(struct HpmfwupgGetTargetUpgCapabilitiesReq);
-
- rsp = HpmfwupgSendCmd(intf, req, NULL);
-
- if ( rsp )
- {
- if ( rsp->ccode == 0x00 )
- {
- memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetTargetUpgCapabilitiesResp));
- if ( verbose )
- {
- lprintf(LOG_NOTICE,"TARGET UPGRADE CAPABILITIES");
- lprintf(LOG_NOTICE,"-------------------------------");
- lprintf(LOG_NOTICE,"HPM.1 version............%d ", pCtx->resp.hpmVersion);
- lprintf(LOG_NOTICE,"Component 0 presence....[%c] ", pCtx->resp.componentsPresent.ComponentBits.
- bitField.component0 ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Component 1 presence....[%c] ", pCtx->resp.componentsPresent.ComponentBits.
- bitField.component1 ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Component 2 presence....[%c] ", pCtx->resp.componentsPresent.ComponentBits.
- bitField.component2 ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Component 3 presence....[%c] ", pCtx->resp.componentsPresent.ComponentBits.
- bitField.component3 ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Component 4 presence....[%c] ", pCtx->resp.componentsPresent.ComponentBits.
- bitField.component4 ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Component 5 presence....[%c] ", pCtx->resp.componentsPresent.ComponentBits.
- bitField.component5 ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Component 6 presence....[%c] ", pCtx->resp.componentsPresent.ComponentBits.
- bitField.component6 ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Component 7 presence....[%c] ", pCtx->resp.componentsPresent.ComponentBits.
- bitField.component7 ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Upgrade undesirable.....[%c] ", pCtx->resp.GlobalCapabilities.
- bitField.fwUpgUndesirable ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Aut rollback override...[%c] ", pCtx->resp.GlobalCapabilities.
- bitField.autRollbackOverride ? 'y' : 'n');
- lprintf(LOG_NOTICE,"IPMC degraded...........[%c] ", pCtx->resp.GlobalCapabilities.
- bitField.ipmcDegradedDurinUpg ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Defered activation......[%c] ", pCtx->resp.GlobalCapabilities.
- bitField.deferActivation ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Service affected........[%c] ", pCtx->resp.GlobalCapabilities.
- bitField.servAffectDuringUpg ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Manual rollback.........[%c] ", pCtx->resp.GlobalCapabilities.
- bitField.manualRollback ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Automatic rollback......[%c] ", pCtx->resp.GlobalCapabilities.
- bitField.autRollback ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Self test...............[%c] ", pCtx->resp.GlobalCapabilities.
- bitField.ipmcSelftestCap ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Upgrade timeout.........[%d sec] ", pCtx->resp.upgradeTimeout*5);
- lprintf(LOG_NOTICE,"Self test timeout.......[%d sec] ", pCtx->resp.selftestTimeout*5);
- lprintf(LOG_NOTICE,"Rollback timeout........[%d sec] ", pCtx->resp.rollbackTimeout*5);
- lprintf(LOG_NOTICE,"Inaccessibility timeout.[%d sec] \n", pCtx->resp.inaccessTimeout*5);
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"Error getting target upgrade capabilities\n", rsp->ccode);
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"Error getting target upgrade capabilities\n");
- rc = HPMFWUPG_ERROR;
- }
-
-
-
- return rc;
+ rsp = HpmfwupgSendCmd(intf, req, NULL);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR,
+ "Error getting target upgrade capabilities.");
+ return HPMFWUPG_ERROR;
+ }
+ if (rsp->ccode != 0x00) {
+ lprintf(LOG_ERR,
+ "Error getting target upgrade capabilities, ccode: 0x%x: %s",
+ rsp->ccode,
+ val2str(rsp->ccode, completion_code_vals));
+ return HPMFWUPG_ERROR;
+ }
+ memcpy(&pCtx->resp, rsp->data,
+ sizeof(struct HpmfwupgGetTargetUpgCapabilitiesResp));
+ if (verbose) {
+ lprintf(LOG_NOTICE, "TARGET UPGRADE CAPABILITIES");
+ lprintf(LOG_NOTICE, "-------------------------------");
+ lprintf(LOG_NOTICE, "HPM.1 version............%d ",
+ pCtx->resp.hpmVersion);
+ lprintf(LOG_NOTICE, "Component 0 presence....[%c] ",
+ pCtx->resp.componentsPresent.ComponentBits.bitField.component0 ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Component 1 presence....[%c] ",
+ pCtx->resp.componentsPresent.ComponentBits.bitField.component1 ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Component 2 presence....[%c] ",
+ pCtx->resp.componentsPresent.ComponentBits.bitField.component2 ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Component 3 presence....[%c] ",
+ pCtx->resp.componentsPresent.ComponentBits.bitField.component3 ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Component 4 presence....[%c] ",
+ pCtx->resp.componentsPresent.ComponentBits.bitField.component4 ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Component 5 presence....[%c] ",
+ pCtx->resp.componentsPresent.ComponentBits.bitField.component5 ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Component 6 presence....[%c] ",
+ pCtx->resp.componentsPresent.ComponentBits.bitField.component6 ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Component 7 presence....[%c] ",
+ pCtx->resp.componentsPresent.ComponentBits.bitField.component7 ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Upgrade undesirable.....[%c] ",
+ pCtx->resp.GlobalCapabilities.bitField.fwUpgUndesirable ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Aut rollback override...[%c] ",
+ pCtx->resp.GlobalCapabilities.bitField.autRollbackOverride ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "IPMC degraded...........[%c] ",
+ pCtx->resp.GlobalCapabilities.bitField.ipmcDegradedDurinUpg ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Defered activation......[%c] ",
+ pCtx->resp.GlobalCapabilities.bitField.deferActivation ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Service affected........[%c] ",
+ pCtx->resp.GlobalCapabilities.bitField.servAffectDuringUpg ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Manual rollback.........[%c] ",
+ pCtx->resp.GlobalCapabilities.bitField.manualRollback ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Automatic rollback......[%c] ",
+ pCtx->resp.GlobalCapabilities.bitField.autRollback ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Self test...............[%c] ",
+ pCtx->resp.GlobalCapabilities.bitField.ipmcSelftestCap ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Upgrade timeout.........[%d sec] ",
+ pCtx->resp.upgradeTimeout*5);
+ lprintf(LOG_NOTICE, "Self test timeout.......[%d sec] ",
+ pCtx->resp.selftestTimeout*5);
+ lprintf(LOG_NOTICE, "Rollback timeout........[%d sec] ",
+ pCtx->resp.rollbackTimeout*5);
+ lprintf(LOG_NOTICE, "Inaccessibility timeout.[%d sec] \n",
+ pCtx->resp.inaccessTimeout*5);
+ }
+ return HPMFWUPG_SUCCESS;
}
-
-int HpmfwupgGetComponentProperties(struct ipmi_intf *intf, struct HpmfwupgGetComponentPropertiesCtx* pCtx)
+int
+HpmfwupgGetComponentProperties(struct ipmi_intf *intf,
+ struct HpmfwupgGetComponentPropertiesCtx *pCtx)
{
- int rc = HPMFWUPG_SUCCESS;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
-
- pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = HPMFWUPG_GET_COMPONENT_PROPERTIES;
- req.msg.data = (unsigned char*)&pCtx->req;
+ int rc = HPMFWUPG_SUCCESS;
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = HPMFWUPG_GET_COMPONENT_PROPERTIES;
+ req.msg.data = (unsigned char*)&pCtx->req;
req.msg.data_len = sizeof(struct HpmfwupgGetComponentPropertiesReq);
-
- rsp = HpmfwupgSendCmd(intf, req, NULL);
-
- if ( rsp )
- {
- if ( rsp->ccode == 0x00 )
- {
- switch ( pCtx->req.selector )
- {
- case HPMFWUPG_COMP_GEN_PROPERTIES:
- memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetGeneralPropResp));
- if ( verbose )
- {
- lprintf(LOG_NOTICE,"GENERAL PROPERTIES");
- lprintf(LOG_NOTICE,"-------------------------------");
- lprintf(LOG_NOTICE,"Payload cold reset req....[%c] ", pCtx->resp.Response.generalPropResp.
- GeneralCompProperties.bitfield.payloadColdReset ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Def. activation supported.[%c] ", pCtx->resp.Response.generalPropResp.
- GeneralCompProperties.bitfield.deferredActivation ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Comparison supported......[%c] ", pCtx->resp.Response.generalPropResp.
- GeneralCompProperties.bitfield.comparisonSupport ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Preparation supported.....[%c] ", pCtx->resp.Response.generalPropResp.
- GeneralCompProperties.bitfield.preparationSupport ? 'y' : 'n');
- lprintf(LOG_NOTICE,"Rollback supported........[%c] \n", pCtx->resp.Response.generalPropResp.
- GeneralCompProperties.bitfield.rollbackBackup ? 'y' : 'n');
- }
- break;
- case HPMFWUPG_COMP_CURRENT_VERSION:
- memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetCurrentVersionResp));
- if ( verbose )
- {
- lprintf(LOG_NOTICE,"Current Version: ");
- lprintf(LOG_NOTICE," Major: %d", pCtx->resp.Response.currentVersionResp.currentVersion[0]);
- lprintf(LOG_NOTICE," Minor: %x", pCtx->resp.Response.currentVersionResp.currentVersion[1]);
- lprintf(LOG_NOTICE," Aux : %03d %03d %03d %03d\n", pCtx->resp.Response.currentVersionResp.currentVersion[2],
- pCtx->resp.Response.currentVersionResp.currentVersion[3],
- pCtx->resp.Response.currentVersionResp.currentVersion[4],
- pCtx->resp.Response.currentVersionResp.currentVersion[5]);
- }
- break;
- case HPMFWUPG_COMP_DESCRIPTION_STRING:
- memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetDescStringResp));
- if ( verbose )
- {
- lprintf(LOG_NOTICE,"Description string: %s\n", pCtx->resp.Response.descStringResp.descString);
- }
- break;
- case HPMFWUPG_COMP_ROLLBACK_FIRMWARE_VERSION:
- memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetRollbackFwVersionResp));
- if ( verbose )
- {
- lprintf(LOG_NOTICE,"Rollback FW Version: ");
- lprintf(LOG_NOTICE," Major: %d", pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[0]);
- lprintf(LOG_NOTICE," Minor: %x", pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[1]);
- lprintf(LOG_NOTICE," Aux : %03d %03d %03d %03d\n", pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[2],
- pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[3],
- pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[4],
- pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[5]);
- }
- break;
- case HPMFWUPG_COMP_DEFERRED_FIRMWARE_VERSION:
- memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetDeferredFwVersionResp));
- if ( verbose )
- {
- lprintf(LOG_NOTICE,"Deferred FW Version: ");
- lprintf(LOG_NOTICE," Major: %d", pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[0]);
- lprintf(LOG_NOTICE," Minor: %x", pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[1]);
- lprintf(LOG_NOTICE," Aux : %03d %03d %03d %03d\n", pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[2],
- pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[3],
- pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[4],
- pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[5]);
- }
- break;
- // OEM Properties command
- case HPMFWUPG_COMP_OEM_PROPERTIES:
- memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetOemProperties));
- if ( verbose )
- {
- unsigned char i = 0;
- lprintf(LOG_NOTICE,"OEM Properties: ");
- for (i=0; i < HPMFWUPG_OEM_LENGTH; i++)
- {
- lprintf(LOG_NOTICE," 0x%x ", pCtx->resp.Response.oemProperties.oemRspData[i]);
- }
- }
- break;
- default:
- lprintf(LOG_NOTICE,"Unsupported component selector");
- rc = HPMFWUPG_ERROR;
- break;
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"Error getting component properties");
- lprintf(LOG_NOTICE,"compcode=0x%x: %s",
- rsp->ccode,
- val2str(rsp->ccode, completion_code_vals));
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"Error getting component properties\n");
- rc = HPMFWUPG_ERROR;
- }
-
-
- return rc;
+ rsp = HpmfwupgSendCmd(intf, req, NULL);
+ if (rsp == NULL) {
+ lprintf(LOG_NOTICE,
+ "Error getting component properties\n");
+ return HPMFWUPG_ERROR;
+ }
+ if (rsp->ccode != 0x00) {
+ lprintf(LOG_NOTICE,
+ "Error getting component properties");
+ lprintf(LOG_NOTICE,
+ "compcode=0x%x: %s",
+ rsp->ccode,
+ val2str(rsp->ccode, completion_code_vals));
+ return HPMFWUPG_ERROR;
+ }
+ switch (pCtx->req.selector) {
+ case HPMFWUPG_COMP_GEN_PROPERTIES:
+ memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetGeneralPropResp));
+ if (verbose) {
+ lprintf(LOG_NOTICE, "GENERAL PROPERTIES");
+ lprintf(LOG_NOTICE, "-------------------------------");
+ lprintf(LOG_NOTICE, "Payload cold reset req....[%c] ",
+ pCtx->resp.Response.generalPropResp.GeneralCompProperties.bitfield.payloadColdReset ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Def. activation supported.[%c] ",
+ pCtx->resp.Response.generalPropResp.GeneralCompProperties.bitfield.deferredActivation ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Comparison supported......[%c] ",
+ pCtx->resp.Response.generalPropResp.GeneralCompProperties.bitfield.comparisonSupport ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Preparation supported.....[%c] ",
+ pCtx->resp.Response.generalPropResp.GeneralCompProperties.bitfield.preparationSupport ? 'y' : 'n');
+ lprintf(LOG_NOTICE, "Rollback supported........[%c] \n",
+ pCtx->resp.Response.generalPropResp.GeneralCompProperties.bitfield.rollbackBackup ? 'y' : 'n');
+ }
+ break;
+ case HPMFWUPG_COMP_CURRENT_VERSION:
+ memcpy(&pCtx->resp, rsp->data,
+ sizeof(struct HpmfwupgGetCurrentVersionResp));
+ if (verbose) {
+ lprintf(LOG_NOTICE, "Current Version: ");
+ lprintf(LOG_NOTICE, " Major: %d",
+ pCtx->resp.Response.currentVersionResp.currentVersion[0]);
+ lprintf(LOG_NOTICE, " Minor: %x",
+ pCtx->resp.Response.currentVersionResp.currentVersion[1]);
+ lprintf(LOG_NOTICE, " Aux : %03d %03d %03d %03d\n",
+ pCtx->resp.Response.currentVersionResp.currentVersion[2],
+ pCtx->resp.Response.currentVersionResp.currentVersion[3],
+ pCtx->resp.Response.currentVersionResp.currentVersion[4],
+ pCtx->resp.Response.currentVersionResp.currentVersion[5]);
+ }
+ break;
+ case HPMFWUPG_COMP_DESCRIPTION_STRING:
+ memcpy(&pCtx->resp, rsp->data,
+ sizeof(struct HpmfwupgGetDescStringResp));
+ if (verbose) {
+ char descString[HPMFWUPG_DESC_STRING_LENGTH + 1];
+ memcpy(descString,
+ pCtx->resp.Response.descStringResp.descString,
+ HPMFWUPG_DESC_STRING_LENGTH);
+ descString[HPMFWUPG_DESC_STRING_LENGTH] = '\0';
+ lprintf(LOG_NOTICE,
+ "Description string: %s\n",
+ descString);
+ }
+ break;
+ case HPMFWUPG_COMP_ROLLBACK_FIRMWARE_VERSION:
+ memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetRollbackFwVersionResp));
+ if (verbose) {
+ lprintf(LOG_NOTICE, "Rollback FW Version: ");
+ lprintf(LOG_NOTICE, " Major: %d",
+ pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[0]);
+ lprintf(LOG_NOTICE, " Minor: %x",
+ pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[1]);
+ lprintf(LOG_NOTICE, " Aux : %03d %03d %03d %03d\n",
+ pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[2],
+ pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[3],
+ pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[4],
+ pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[5]);
+ }
+ break;
+ case HPMFWUPG_COMP_DEFERRED_FIRMWARE_VERSION:
+ memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetDeferredFwVersionResp));
+ if (verbose) {
+ lprintf(LOG_NOTICE, "Deferred FW Version: ");
+ lprintf(LOG_NOTICE, " Major: %d",
+ pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[0]);
+ lprintf(LOG_NOTICE, " Minor: %x",
+ pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[1]);
+ lprintf(LOG_NOTICE, " Aux : %03d %03d %03d %03d\n",
+ pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[2],
+ pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[3],
+ pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[4],
+ pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[5]);
+ }
+ break;
+ case HPMFWUPG_COMP_OEM_PROPERTIES:
+ /* OEM Properties command */
+ memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetOemProperties));
+ if (verbose) {
+ unsigned char i = 0;
+ lprintf(LOG_NOTICE,"OEM Properties: ");
+ for (i=0; i < HPMFWUPG_OEM_LENGTH; i++) {
+ lprintf(LOG_NOTICE, " 0x%x ",
+ pCtx->resp.Response.oemProperties.oemRspData[i]);
+ }
+ }
+ break;
+ default:
+ lprintf(LOG_NOTICE,"Unsupported component selector");
+ rc = HPMFWUPG_ERROR;
+ break;
+ }
+ return rc;
}
-int HpmfwupgAbortUpgrade(struct ipmi_intf *intf, struct HpmfwupgAbortUpgradeCtx* pCtx)
+int
+HpmfwupgAbortUpgrade(struct ipmi_intf *intf,
+ struct HpmfwupgAbortUpgradeCtx *pCtx)
{
- int rc = HPMFWUPG_SUCCESS;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
-
- pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = HPMFWUPG_ABORT_UPGRADE;
- req.msg.data = (unsigned char*)&pCtx->req;
+ int rc = HPMFWUPG_SUCCESS;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = HPMFWUPG_ABORT_UPGRADE;
+ req.msg.data = (unsigned char*)&pCtx->req;
req.msg.data_len = sizeof(struct HpmfwupgAbortUpgradeReq);
-
- rsp = HpmfwupgSendCmd(intf, req, NULL);
-
- if ( rsp )
- {
- if ( rsp->ccode != 0x00 )
- {
- lprintf(LOG_NOTICE,"Error aborting upgrade");
- lprintf(LOG_NOTICE,"compcode=0x%x: %s",
- rsp->ccode,
- val2str(rsp->ccode, completion_code_vals));
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"Error aborting upgrade\n");
- rc = HPMFWUPG_ERROR;
- }
- return rc;
+ rsp = HpmfwupgSendCmd(intf, req, NULL);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Error - aborting upgrade.");
+ return HPMFWUPG_ERROR;
+ }
+ if (rsp->ccode != 0x00) {
+ lprintf(LOG_ERR, "Error aborting upgrade");
+ lprintf(LOG_ERR, "compcode=0x%x: %s",
+ rsp->ccode,
+ val2str(rsp->ccode, completion_code_vals));
+ rc = HPMFWUPG_ERROR;
+ }
+ return rc;
}
-int HpmfwupgInitiateUpgradeAction(struct ipmi_intf *intf, struct HpmfwupgInitiateUpgradeActionCtx* pCtx,
- struct HpmfwupgUpgradeCtx* pFwupgCtx)
+int
+HpmfwupgInitiateUpgradeAction(struct ipmi_intf *intf,
+ struct HpmfwupgInitiateUpgradeActionCtx *pCtx,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx)
{
- int rc = HPMFWUPG_SUCCESS;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
-
- pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = HPMFWUPG_INITIATE_UPGRADE_ACTION;
- req.msg.data = (unsigned char*)&pCtx->req;
+ int rc = HPMFWUPG_SUCCESS;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = HPMFWUPG_INITIATE_UPGRADE_ACTION;
+ req.msg.data = (unsigned char*)&pCtx->req;
req.msg.data_len = sizeof(struct HpmfwupgInitiateUpgradeActionReq);
-
- rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
-
- if ( rsp )
- {
- /* Long duration command handling */
- if ( rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS )
- {
- rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx);
- }
- else if ( rsp->ccode != 0x00 )
- {
- lprintf(LOG_NOTICE,"Error initiating upgrade action");
- lprintf(LOG_NOTICE,"compcode=0x%x: %s",
- rsp->ccode,
- val2str(rsp->ccode, completion_code_vals));
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"Error initiating upgrade action\n");
- rc = HPMFWUPG_ERROR;
- }
-
- return rc;
+ rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Error initiating upgrade action.");
+ return HPMFWUPG_ERROR;
+ }
+ /* Long duration command handling */
+ if (rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) {
+ rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx);
+ } else if (rsp->ccode != 0x00) {
+ lprintf(LOG_NOTICE,"Error initiating upgrade action");
+ lprintf(LOG_NOTICE, "compcode=0x%x: %s",
+ rsp->ccode,
+ val2str(rsp->ccode, completion_code_vals));
+ rc = HPMFWUPG_ERROR;
+ }
+ return rc;
}
-int HpmfwupgUploadFirmwareBlock(struct ipmi_intf *intf, struct HpmfwupgUploadFirmwareBlockCtx* pCtx,
- struct HpmfwupgUpgradeCtx* pFwupgCtx, int count
- ,unsigned int *imageOffset, unsigned int *blockLength )
+int
+HpmfwupgUploadFirmwareBlock(struct ipmi_intf *intf,
+ struct HpmfwupgUploadFirmwareBlockCtx *pCtx,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx, int count,
+ unsigned int *imageOffset, unsigned int *blockLength)
{
- int rc = HPMFWUPG_SUCCESS;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
-
- pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = HPMFWUPG_UPLOAD_FIRMWARE_BLOCK;
- req.msg.data = (unsigned char*)&pCtx->req;
- /* 2 is the size of the upload struct - data */
- req.msg.data_len = 2 + count;
-
- rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
-
- if ( rsp )
- {
- if ( rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS ||
- rsp->ccode == 0x00 )
- {
- /*
- * We need to check if the response also contains the next upload firmware offset
- * and the firmware length in its response - These are optional but very vital
- */
- if ( rsp->data_len > 1 )
- {
- /*
- * If the response data length is greater than 1 it should contain both the
- * the Section offset and section length. Because we cannot just have
- * Section offset without section length so the length should be 9
- */
- if ( rsp->data_len == 9 )
- {
- /* rsp->data[1] - LSB rsp->data[2] - rsp->data[3] = MSB */
- *imageOffset = (rsp->data[4] << 24) + (rsp->data[3] << 16) + (rsp->data[2] << 8) + rsp->data[1];
- *blockLength = (rsp->data[8] << 24) + (rsp->data[7] << 16) + (rsp->data[6] << 8) + rsp->data[5];
- }
- else
- {
- /*
- * The Spec does not say much for this kind of errors where the
- * firmware returned only offset and length so currently returning it
- * as 0x82 - Internal CheckSum Error
- */
- lprintf(LOG_NOTICE,"Error wrong rsp->datalen %d for Upload Firmware block command\n",rsp->data_len);
- rsp->ccode = HPMFWUPG_INT_CHECKSUM_ERROR;
- }
- }
- }
- /* Long duration command handling */
- if ( rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS )
- {
- rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx);
- }
- else if (rsp->ccode != 0x00)
- {
- /*
- * PATCH --> This validation is to handle retryables errors codes on IPMB bus.
- * This will be fixed in the next release of open ipmi and this
- * check will have to be removed. (Buggy version = 39)
- */
- if ( HPMFWUPG_IS_RETRYABLE(rsp->ccode) )
- {
- lprintf(LOG_DEBUG,"HPM: [PATCH]Retryable error detected");
- rc = HPMFWUPG_UPLOAD_RETRY;
- }
- /*
- * If completion code = 0xc7, we will retry with a reduced buffer length.
- * Do not print error.
- */
- else if ( rsp->ccode == IPMI_CC_REQ_DATA_INV_LENGTH )
- {
- rc = HPMFWUPG_UPLOAD_BLOCK_LENGTH;
- }
- else
- {
- lprintf(LOG_NOTICE,"Error uploading firmware block");
- lprintf(LOG_NOTICE,"compcode=0x%x: %s",
- rsp->ccode,
- val2str(rsp->ccode, completion_code_vals));
- rc = HPMFWUPG_ERROR;
- }
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"Error uploading firmware block\n");
- rc = HPMFWUPG_ERROR;
- }
-
- return rc;
+ int rc = HPMFWUPG_SUCCESS;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ pCtx->req->picmgId = HPMFWUPG_PICMG_IDENTIFIER;
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = HPMFWUPG_UPLOAD_FIRMWARE_BLOCK;
+ req.msg.data = (unsigned char *)pCtx->req;
+ /* 2 is the size of the upload struct - data */
+ req.msg.data_len = 2 + count;
+ rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
+ if (rsp == NULL) {
+ lprintf(LOG_NOTICE, "Error uploading firmware block.");
+ return HPMFWUPG_ERROR;
+ }
+ if (rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS
+ || rsp->ccode == 0x00) {
+ /*
+ * We need to check if the response also contains the next upload firmware offset
+ * and the firmware length in its response - These are optional but very vital
+ */
+ if (rsp->data_len > 1) {
+ /*
+ * If the response data length is greater than 1 it should contain both the
+ * the Section offset and section length. Because we cannot just have
+ * Section offset without section length so the length should be 9
+ */
+ if (rsp->data_len == 9) {
+ /* rsp->data[1] - LSB rsp->data[2] - rsp->data[3] = MSB */
+ *imageOffset = (rsp->data[4] << 24) + (rsp->data[3] << 16) + (rsp->data[2] << 8) + rsp->data[1];
+ *blockLength = (rsp->data[8] << 24) + (rsp->data[7] << 16) + (rsp->data[6] << 8) + rsp->data[5];
+ } else {
+ /*
+ * The Spec does not say much for this kind of errors where the
+ * firmware returned only offset and length so currently returning it
+ * as 0x82 - Internal CheckSum Error
+ */
+ lprintf(LOG_NOTICE,
+ "Error wrong rsp->datalen %d for Upload Firmware block command\n",
+ rsp->data_len);
+ rsp->ccode = HPMFWUPG_INT_CHECKSUM_ERROR;
+ }
+ }
+ }
+ /* Long duration command handling */
+ if (rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) {
+ rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx);
+ } else if (rsp->ccode != 0x00) {
+ /* PATCH --> This validation is to handle retryables errors codes on IPMB bus.
+ * This will be fixed in the next release of open ipmi and this
+ * check will have to be removed. (Buggy version = 39)
+ */
+ if (HPMFWUPG_IS_RETRYABLE(rsp->ccode)) {
+ lprintf(LOG_DEBUG, "HPM: [PATCH]Retryable error detected");
+ rc = HPMFWUPG_UPLOAD_RETRY;
+ } else if (rsp->ccode == IPMI_CC_REQ_DATA_INV_LENGTH ||
+ rsp->ccode == IPMI_CC_REQ_DATA_FIELD_EXCEED) {
+ /* If completion code = 0xc7(0xc8), we will retry with a reduced buffer length.
+ * Do not print error.
+ */
+ rc = HPMFWUPG_UPLOAD_BLOCK_LENGTH;
+ } else {
+ lprintf(LOG_ERR, "Error uploading firmware block");
+ lprintf(LOG_ERR, "compcode=0x%x: %s",
+ rsp->ccode,
+ val2str(rsp->ccode,
+ completion_code_vals));
+ rc = HPMFWUPG_ERROR;
+ }
+ }
+ return rc;
}
-int HpmfwupgFinishFirmwareUpload(struct ipmi_intf *intf, struct HpmfwupgFinishFirmwareUploadCtx* pCtx,
- struct HpmfwupgUpgradeCtx* pFwupgCtx)
+int
+HpmfwupgFinishFirmwareUpload(struct ipmi_intf *intf,
+ struct HpmfwupgFinishFirmwareUploadCtx *pCtx,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx, int option)
{
- int rc = HPMFWUPG_SUCCESS;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
-
- pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = HPMFWUPG_FINISH_FIRMWARE_UPLOAD;
- req.msg.data = (unsigned char*)&pCtx->req;
+ int rc = HPMFWUPG_SUCCESS;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = HPMFWUPG_FINISH_FIRMWARE_UPLOAD;
+ req.msg.data = (unsigned char*)&pCtx->req;
req.msg.data_len = sizeof(struct HpmfwupgFinishFirmwareUploadReq);
-
- rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
-
- if ( rsp )
- {
- /* Long duration command handling */
- if ( rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS )
- {
- rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx);
- }
- else if ( rsp->ccode != IPMI_CC_OK )
- {
- lprintf(LOG_NOTICE,"Error finishing firmware upload");
- lprintf(LOG_NOTICE,"compcode=0x%x: %s",
- rsp->ccode,
- val2str(rsp->ccode, completion_code_vals));
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"Error fininshing firmware upload\n");
- rc = HPMFWUPG_ERROR;
- }
-
- return rc;
+ rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Error fininshing firmware upload.");
+ return HPMFWUPG_ERROR;
+ }
+ /* Long duration command handling */
+ if (rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) {
+ rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx);
+ } else if ((option & COMPARE_MODE) && rsp->ccode == 0x83) {
+ printf("| |Component's active copy doesn't match the upgrade image |\n");
+ } else if ((option & COMPARE_MODE) && rsp->ccode == IPMI_CC_OK) {
+ printf("| |Comparison passed |\n");
+ } else if ( rsp->ccode != IPMI_CC_OK ) {
+ lprintf(LOG_ERR, "Error finishing firmware upload");
+ lprintf(LOG_ERR, "compcode=0x%x: %s",
+ rsp->ccode,
+ val2str(rsp->ccode, completion_code_vals));
+ rc = HPMFWUPG_ERROR;
+ }
+ return rc;
}
-int HpmfwupgActivateFirmware(struct ipmi_intf *intf, struct HpmfwupgActivateFirmwareCtx* pCtx,
- struct HpmfwupgUpgradeCtx* pFwupgCtx)
+int
+HpmfwupgActivateFirmware(struct ipmi_intf *intf,
+ struct HpmfwupgActivateFirmwareCtx *pCtx,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx)
{
- int rc = HPMFWUPG_SUCCESS;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
-
- pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = HPMFWUPG_ACTIVATE_FIRMWARE;
- req.msg.data = (unsigned char*)&pCtx->req;
- req.msg.data_len = sizeof(struct HpmfwupgActivateFirmwareReq) -
- (!pCtx->req.rollback_override ? 1 : 0);
-
- rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
-
- if ( rsp )
- {
- /* Long duration command handling */
- if ( rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS )
- {
- printf("Waiting firmware activation...");
- fflush(stdout);
-
- rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx);
-
- if ( rc == HPMFWUPG_SUCCESS )
- {
- lprintf(LOG_NOTICE,"OK");
- }
- else
- {
- lprintf(LOG_NOTICE,"Failed");
- }
- }
- else if ( rsp->ccode != IPMI_CC_OK )
- {
- lprintf(LOG_NOTICE,"Error activating firmware");
- lprintf(LOG_NOTICE,"compcode=0x%x: %s",
- rsp->ccode,
- val2str(rsp->ccode, completion_code_vals));
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"Error activating firmware\n");
- rc = HPMFWUPG_ERROR;
- }
-
- return rc;
+ int rc = HPMFWUPG_SUCCESS;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = HPMFWUPG_ACTIVATE_FIRMWARE;
+ req.msg.data = (unsigned char*)&pCtx->req;
+ req.msg.data_len = sizeof(struct HpmfwupgActivateFirmwareReq)
+ - (!pCtx->req.rollback_override ? 1 : 0);
+ rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Error activating firmware.");
+ return HPMFWUPG_ERROR;
+ }
+ /* Long duration command handling */
+ if (rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) {
+ printf("Waiting firmware activation...");
+ fflush(stdout);
+ rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx);
+ if (rc == HPMFWUPG_SUCCESS) {
+ lprintf(LOG_NOTICE, "OK");
+ } else {
+ lprintf(LOG_NOTICE, "Failed");
+ }
+ } else if (rsp->ccode != IPMI_CC_OK) {
+ lprintf(LOG_ERR, "Error activating firmware");
+ lprintf(LOG_ERR, "compcode=0x%x: %s",
+ rsp->ccode,
+ val2str(rsp->ccode, completion_code_vals));
+ rc = HPMFWUPG_ERROR;
+ }
+ return rc;
}
-int HpmfwupgGetUpgradeStatus(struct ipmi_intf *intf,
- struct HpmfwupgGetUpgradeStatusCtx *pCtx,
- struct HpmfwupgUpgradeCtx *pFwupgCtx,
- int silent)
+int
+HpmfwupgGetUpgradeStatus(struct ipmi_intf *intf,
+ struct HpmfwupgGetUpgradeStatusCtx *pCtx,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx,
+ int silent)
{
- int rc = HPMFWUPG_SUCCESS;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
-
+ int rc = HPMFWUPG_SUCCESS;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
-
memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = HPMFWUPG_GET_UPGRADE_STATUS;
- req.msg.data = (unsigned char*)&pCtx->req;
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = HPMFWUPG_GET_UPGRADE_STATUS;
+ req.msg.data = (unsigned char*)&pCtx->req;
req.msg.data_len = sizeof(struct HpmfwupgGetUpgradeStatusReq);
-
rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
- if (!rsp){
+ if (!rsp) {
lprintf(LOG_NOTICE,
- "Error getting upgrade status. Failed to get response.");
+ "Error getting upgrade status. Failed to get response.");
return HPMFWUPG_ERROR;
}
-
- if ( rsp->ccode == 0x00 ) {
+ if (rsp->ccode == 0x00) {
memcpy(&pCtx->resp, rsp->data,
- sizeof(struct HpmfwupgGetUpgradeStatusResp));
- if (!silent)
- {
- lprintf(LOG_NOTICE,"Upgrade status:");
- lprintf(LOG_NOTICE," Command in progress: %x",
- pCtx->resp.cmdInProcess);
- lprintf(LOG_NOTICE," Last command completion code: %x",
- pCtx->resp.lastCmdCompCode);
- }
- } else if ( HPMFWUPG_IS_RETRYABLE(rsp->ccode) ) {
- /*
- * PATCH --> This validation is to handle retryable errors
+ sizeof(struct HpmfwupgGetUpgradeStatusResp));
+ if (!silent) {
+ lprintf(LOG_NOTICE, "Upgrade status:");
+ lprintf(LOG_NOTICE,
+ " Command in progress: %x",
+ pCtx->resp.cmdInProcess);
+ lprintf(LOG_NOTICE,
+ " Last command completion code: %x",
+ pCtx->resp.lastCmdCompCode);
+ }
+ } else if (HPMFWUPG_IS_RETRYABLE(rsp->ccode)) {
+ /* PATCH --> This validation is to handle retryable errors
* codes on the IPMB bus.
* This will be fixed in the next release of
* open ipmi and this check can be removed.
* (Buggy version = 39)
*/
- if (!silent)
- {
- lprintf(LOG_DEBUG,"HPM: Retryable error detected");
- }
+ if (!silent) {
+ lprintf(LOG_DEBUG, "HPM: Retryable error detected");
+ }
pCtx->resp.lastCmdCompCode = HPMFWUPG_COMMAND_IN_PROGRESS;
} else {
- lprintf(LOG_NOTICE,"Error getting upgrade status");
- lprintf(LOG_NOTICE,"compcode=0x%x: %s",
- rsp->ccode,
- val2str(rsp->ccode, completion_code_vals));
+ lprintf(LOG_NOTICE, "Error getting upgrade status");
+ lprintf(LOG_NOTICE, "compcode=0x%x: %s", rsp->ccode,
+ val2str(rsp->ccode, completion_code_vals));
return HPMFWUPG_ERROR;
}
-
return HPMFWUPG_SUCCESS;
}
-int HpmfwupgManualFirmwareRollback(struct ipmi_intf *intf, struct HpmfwupgManualFirmwareRollbackCtx* pCtx,
- struct HpmfwupgUpgradeCtx* pFwupgCtx)
-{
- int rc = HPMFWUPG_SUCCESS;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
-
- pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = HPMFWUPG_MANUAL_FIRMWARE_ROLLBACK;
- req.msg.data = (unsigned char*)&pCtx->req;
+int
+HpmfwupgManualFirmwareRollback(struct ipmi_intf *intf,
+ struct HpmfwupgManualFirmwareRollbackCtx *pCtx)
+{
+ struct HpmfwupgUpgradeCtx fwupgCtx;
+ struct HpmfwupgGetTargetUpgCapabilitiesCtx targetCapCmd;
+ int rc = HPMFWUPG_SUCCESS;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ /* prepare fake upgrade context */
+ memset(&fwupgCtx, 0, sizeof (fwupgCtx));
+ verbose--;
+ rc = HpmfwupgGetTargetUpgCapabilities(intf, &targetCapCmd);
+ verbose++;
+ if (rc != HPMFWUPG_SUCCESS) {
+ return rc;
+ }
+ memcpy(&fwupgCtx.targetCap, &targetCapCmd.resp, sizeof(targetCapCmd.resp));
+ pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = HPMFWUPG_MANUAL_FIRMWARE_ROLLBACK;
+ req.msg.data = (unsigned char*)&pCtx->req;
req.msg.data_len = sizeof(struct HpmfwupgManualFirmwareRollbackReq);
-
- rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
-
- if ( rsp )
- {
- /* Long duration command handling */
- if ( rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS )
- {
- struct HpmfwupgQueryRollbackStatusCtx resCmd;
- printf("Waiting firmware rollback...");
- fflush(stdout);
- rc = HpmfwupgQueryRollbackStatus(intf, &resCmd, pFwupgCtx);
- }
- else if ( rsp->ccode != 0x00 )
- {
- lprintf(LOG_NOTICE,"Error sending manual rollback");
- lprintf(LOG_NOTICE,"compcode=0x%x: %s",
- rsp->ccode,
- val2str(rsp->ccode, completion_code_vals));
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"Error sending manual rollback\n");
- rc = HPMFWUPG_ERROR;
- }
- return rc;
+ rsp = HpmfwupgSendCmd(intf, req, &fwupgCtx);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Error sending manual rollback.");
+ return HPMFWUPG_ERROR;
+ }
+ /* Long duration command handling */
+ if (rsp->ccode == IPMI_CC_OK
+ || rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) {
+ struct HpmfwupgQueryRollbackStatusCtx resCmd;
+ printf("Waiting firmware rollback...");
+ fflush(stdout);
+ rc = HpmfwupgQueryRollbackStatus(intf, &resCmd, &fwupgCtx);
+ } else if ( rsp->ccode != 0x00 ) {
+ lprintf(LOG_ERR, "Error sending manual rollback");
+ lprintf(LOG_ERR, "compcode=0x%x: %s",
+ rsp->ccode,
+ val2str(rsp->ccode, completion_code_vals));
+ rc = HPMFWUPG_ERROR;
+ }
+ return rc;
}
-int HpmfwupgQueryRollbackStatus(struct ipmi_intf *intf, struct HpmfwupgQueryRollbackStatusCtx* pCtx,
- struct HpmfwupgUpgradeCtx* pFwupgCtx)
+int
+HpmfwupgQueryRollbackStatus(struct ipmi_intf *intf,
+ struct HpmfwupgQueryRollbackStatusCtx *pCtx,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx)
{
- int rc = HPMFWUPG_SUCCESS;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- unsigned int rollbackTimeout = 0;
- unsigned int timeoutSec1, timeoutSec2;
-
- pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = HPMFWUPG_QUERY_ROLLBACK_STATUS;
- req.msg.data = (unsigned char*)&pCtx->req;
+ int rc = HPMFWUPG_SUCCESS;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ unsigned int rollbackTimeout = 0;
+ unsigned int timeoutSec1, timeoutSec2;
+ pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = HPMFWUPG_QUERY_ROLLBACK_STATUS;
+ req.msg.data = (unsigned char*)&pCtx->req;
req.msg.data_len = sizeof(struct HpmfwupgQueryRollbackStatusReq);
-
- /*
- * If we are not in upgrade context, we use default timeout values
- */
- if ( pFwupgCtx != NULL )
- {
- rollbackTimeout = pFwupgCtx->targetCap.rollbackTimeout*5;
- }
- else
- {
- struct HpmfwupgGetTargetUpgCapabilitiesCtx targetCapCmd;
- verbose--;
- rc = HpmfwupgGetTargetUpgCapabilities(intf, &targetCapCmd);
- verbose++;
- if ( rc == HPMFWUPG_SUCCESS )
- {
- rollbackTimeout = targetCapCmd.resp.rollbackTimeout *5;
- }
- else
- {
- rollbackTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT;
- }
- }
-
- /* Poll rollback status until completion or timeout */
- timeoutSec1 = time(NULL);
- timeoutSec2 = time(NULL);
- do
- {
- /* Must wait at least 100 ms between status requests */
- usleep(100000);
- rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
- /*
- * PATCH --> This validation is to handle retryables errors codes on IPMB bus.
- * This will be fixed in the next release of open ipmi and this
- * check will have to be removed. (Buggy version = 39)
- */
- if ( rsp )
- {
- if ( HPMFWUPG_IS_RETRYABLE(rsp->ccode) )
- {
- lprintf(LOG_DEBUG,"HPM: [PATCH]Retryable error detected");
- rsp->ccode = HPMFWUPG_COMMAND_IN_PROGRESS;
- }
- }
- timeoutSec2 = time(NULL);
-
- }while( rsp &&
- ((rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) ||
- (rsp->ccode == IPMI_CC_TIMEOUT)) &&
- (timeoutSec2 - timeoutSec1 < rollbackTimeout ) );
-
- if ( rsp )
- {
- if ( rsp->ccode == 0x00 )
- {
- memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgQueryRollbackStatusResp));
- if ( pCtx->resp.rollbackComp.ComponentBits.byte != 0 )
- {
- /* Rollback occured */
- lprintf(LOG_NOTICE,"Rollback occured on component mask: 0x%02x",
- pCtx->resp.rollbackComp.ComponentBits.byte);
- }
- else
- {
- lprintf(LOG_NOTICE,"No Firmware rollback occured");
- }
- }
- else if ( rsp->ccode == 0x81 )
- {
- lprintf(LOG_NOTICE,"Rollback failed on component mask: 0x%02x",
- pCtx->resp.rollbackComp.ComponentBits.byte);
- rc = HPMFWUPG_ERROR;
- }
- else
- {
- lprintf(LOG_NOTICE,"Error getting rollback status");
- lprintf(LOG_NOTICE,"compcode=0x%x: %s",
- rsp->ccode,
- val2str(rsp->ccode, completion_code_vals));
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"Error getting upgrade status\n");
- rc = HPMFWUPG_ERROR;
- }
-
- return rc;
+ /* If we are not in upgrade context, we use default timeout values */
+ if (pFwupgCtx != NULL) {
+ struct HpmfwupgImageHeader *pImageHeader;
+ if (pFwupgCtx->pImageData) {
+ pImageHeader = (struct HpmfwupgImageHeader*)pFwupgCtx->pImageData;
+ rollbackTimeout = pImageHeader->rollbackTimeout;
+ } else {
+ rollbackTimeout = 0;
+ }
+ /* Use the greater of the two timeouts (header and target caps) */
+ rollbackTimeout = MAX(rollbackTimeout,
+ pFwupgCtx->targetCap.rollbackTimeout) * 5;
+ } else {
+ rollbackTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT;
+ }
+ /* Poll rollback status until completion or timeout */
+ timeoutSec1 = time(NULL);
+ timeoutSec2 = time(NULL);
+ do {
+ /* Must wait at least 100 ms between status requests */
+ usleep(100000);
+ rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
+ /* PATCH --> This validation is to handle retryables errors codes on IPMB bus.
+ * This will be fixed in the next release of open ipmi and this
+ * check will have to be removed. (Buggy version = 39)
+ */
+ if (rsp) {
+ if (HPMFWUPG_IS_RETRYABLE(rsp->ccode)) {
+ lprintf(LOG_DEBUG,"HPM: [PATCH]Retryable error detected");
+ rsp->ccode = HPMFWUPG_COMMAND_IN_PROGRESS;
+ }
+ }
+ timeoutSec2 = time(NULL);
+ } while (rsp
+ && ((rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS)
+ || (rsp->ccode == IPMI_CC_TIMEOUT))
+ && (timeoutSec2 - timeoutSec1 < rollbackTimeout));
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Error getting upgrade status.");
+ return HPMFWUPG_ERROR;
+ }
+ if (rsp->ccode == 0x00) {
+ memcpy(&pCtx->resp, rsp->data,
+ sizeof(struct HpmfwupgQueryRollbackStatusResp));
+ if (pCtx->resp.rollbackComp.ComponentBits.byte != 0) {
+ /* Rollback occured */
+ lprintf(LOG_NOTICE,
+ "Rollback occured on component mask: 0x%02x",
+ pCtx->resp.rollbackComp.ComponentBits.byte);
+ } else {
+ lprintf(LOG_NOTICE,
+ "No Firmware rollback occured");
+ }
+ } else if (rsp->ccode == 0x81) {
+ lprintf(LOG_ERR,
+ "Rollback failed on component mask: 0x%02x",
+ pCtx->resp.rollbackComp.ComponentBits.byte);
+ rc = HPMFWUPG_ERROR;
+ } else {
+ lprintf(LOG_ERR,
+ "Error getting rollback status");
+ lprintf(LOG_ERR,
+ "compcode=0x%x: %s",
+ rsp->ccode,
+ val2str(rsp->ccode, completion_code_vals));
+ rc = HPMFWUPG_ERROR;
+ }
+ return rc;
}
-int HpmfwupgQuerySelftestResult(struct ipmi_intf *intf, struct HpmfwupgQuerySelftestResultCtx* pCtx,
- struct HpmfwupgUpgradeCtx* pFwupgCtx)
+int
+HpmfwupgQuerySelftestResult(struct ipmi_intf *intf, struct HpmfwupgQuerySelftestResultCtx *pCtx,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx)
{
- int rc = HPMFWUPG_SUCCESS;
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- unsigned char selfTestTimeout = 0;
- unsigned int timeoutSec1, timeoutSec2;
-
- pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
-
- /*
- * If we are not in upgrade context, we use default timeout values
- */
- if ( pFwupgCtx != NULL )
- {
- /* Getting selftest timeout from new image */
- struct HpmfwupgImageHeader* pImageHeader = (struct HpmfwupgImageHeader*)
- pFwupgCtx->pImageData;
- selfTestTimeout = pImageHeader->selfTestTimeout;
- }
- else
- {
- selfTestTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT;
- }
-
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = HPMFWUPG_QUERY_SELFTEST_RESULT;
- req.msg.data = (unsigned char*)&pCtx->req;
+ int rc = HPMFWUPG_SUCCESS;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ unsigned char selfTestTimeout = 0;
+ unsigned int timeoutSec1, timeoutSec2;
+ pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER;
+ /* If we are not in upgrade context, we use default timeout values */
+ if (pFwupgCtx != NULL) {
+ /* Getting selftest timeout from new image */
+ struct HpmfwupgImageHeader *pImageHeader = (struct HpmfwupgImageHeader*)
+ pFwupgCtx->pImageData;
+ selfTestTimeout = MAX(pImageHeader->selfTestTimeout,
+ pFwupgCtx->targetCap.selftestTimeout) * 5;
+ } else {
+ selfTestTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT;
+ }
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = HPMFWUPG_QUERY_SELFTEST_RESULT;
+ req.msg.data = (unsigned char*)&pCtx->req;
req.msg.data_len = sizeof(struct HpmfwupgQuerySelftestResultReq);
-
-
- /* Poll rollback status until completion or timeout */
- timeoutSec1 = time(NULL);
- timeoutSec2 = time(NULL);
- do
- {
- /* Must wait at least 100 ms between status requests */
- usleep(100000);
- rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
- /*
- * PATCH --> This validation is to handle retryables errors codes on IPMB bus.
- * This will be fixed in the next release of open ipmi and this
- * check will have to be removed. (Buggy version = 39)
- */
- if ( rsp )
- {
- if ( HPMFWUPG_IS_RETRYABLE(rsp->ccode) )
- {
- lprintf(LOG_DEBUG,"HPM: [PATCH]Retryable error detected");
- rsp->ccode = HPMFWUPG_COMMAND_IN_PROGRESS;
- }
- }
- timeoutSec2 = time(NULL);
-
- }while( rsp &&
- (rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) &&
- (timeoutSec2 - timeoutSec1 < selfTestTimeout ) );
-
- if ( rsp )
- {
- if ( rsp->ccode == 0x00 )
- {
- memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgQuerySelftestResultResp));
- if ( verbose )
- {
- lprintf(LOG_NOTICE,"Self test results:");
- lprintf(LOG_NOTICE,"Result1 = %x", pCtx->resp.result1);
- lprintf(LOG_NOTICE,"Result2 = %x", pCtx->resp.result2);
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"Error getting self test results");
- lprintf(LOG_NOTICE,"compcode=0x%x: %s",
- rsp->ccode,
- val2str(rsp->ccode, completion_code_vals));
- rc = HPMFWUPG_ERROR;
- }
- }
- else
- {
- lprintf(LOG_NOTICE,"Error getting upgrade status\n");
- rc = HPMFWUPG_ERROR;
- }
-
- return rc;
+ /* Poll rollback status until completion or timeout */
+ timeoutSec1 = time(NULL);
+ timeoutSec2 = time(NULL);
+ do {
+ /* Must wait at least 100 ms between status requests */
+ usleep(100000);
+ rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
+ /* PATCH --> This validation is to handle retryables errors codes on IPMB bus.
+ * This will be fixed in the next release of open ipmi and this
+ * check will have to be removed. (Buggy version = 39)
+ */
+ if (rsp) {
+ if (HPMFWUPG_IS_RETRYABLE(rsp->ccode)) {
+ lprintf(LOG_DEBUG,
+ "HPM: [PATCH]Retryable error detected");
+ rsp->ccode = HPMFWUPG_COMMAND_IN_PROGRESS;
+ }
+ }
+ timeoutSec2 = time(NULL);
+ } while (rsp
+ && (rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS)
+ && (timeoutSec2 - timeoutSec1 < selfTestTimeout));
+ if (rsp == NULL) {
+ lprintf(LOG_NOTICE, "Error getting upgrade status\n");
+ return HPMFWUPG_ERROR;
+ }
+ if (rsp->ccode == 0x00) {
+ memcpy(&pCtx->resp, rsp->data,
+ sizeof(struct HpmfwupgQuerySelftestResultResp));
+ if (verbose) {
+ lprintf(LOG_NOTICE, "Self test results:");
+ lprintf(LOG_NOTICE, "Result1 = %x",
+ pCtx->resp.result1);
+ lprintf(LOG_NOTICE, "Result2 = %x",
+ pCtx->resp.result2);
+ }
+ } else {
+ lprintf(LOG_NOTICE, "Error getting self test results");
+ lprintf(LOG_NOTICE, "compcode=0x%x: %s",
+ rsp->ccode,
+ val2str(rsp->ccode, completion_code_vals));
+ rc = HPMFWUPG_ERROR;
+ }
+ return rc;
}
-struct ipmi_rs * HpmfwupgSendCmd(struct ipmi_intf *intf, struct ipmi_rq req,
- struct HpmfwupgUpgradeCtx* pFwupgCtx )
-{
- struct ipmi_rs * rsp;
- unsigned int inaccessTimeout = 0, inaccessTimeoutCounter = 0;
- unsigned int upgradeTimeout = 0, upgradeTimeoutCounter = 0;
- unsigned int timeoutSec1, timeoutSec2;
- unsigned char retry = 0;
-
- /*
- * If we are not in upgrade context, we use default timeout values
- */
- if ( pFwupgCtx != NULL )
- {
- inaccessTimeout = pFwupgCtx->targetCap.inaccessTimeout*5;
- upgradeTimeout = pFwupgCtx->targetCap.upgradeTimeout*5;
- }
- else
- {
- /* keeping the inaccessTimeout to 60 seconds results in almost 2900 retries
- * So if the target is not available it will be retrying the command for 2900
- * times which is not effecient -So reducing the Timout to 5 seconds which is
- * almost 200 retries if it continuously recieves 0xC3 as completion code.
- */
- inaccessTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT;
- upgradeTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT;
- }
-
- timeoutSec1 = time(NULL);
-
- do
- {
- static unsigned char isValidSize = FALSE;
- rsp = intf->sendrecv(intf, &req);
-
- if( ( rsp == NULL ) )
- {
- #define HPM_LAN_PACKET_RESIZE_LIMIT 6
-
- if(strstr(intf->name,"lan")!= NULL) /* also covers lanplus */
- {
- static int errorCount=0;
- static struct ipmi_rs fakeRsp;
-
- lprintf(LOG_DEBUG,"HPM: no response available");
- lprintf(LOG_DEBUG,"HPM: the command may be rejected for " \
- "security reasons");
-
- if
- (
- req.msg.netfn == IPMI_NETFN_PICMG
- &&
- req.msg.cmd == HPMFWUPG_UPLOAD_FIRMWARE_BLOCK
- &&
- errorCount < HPM_LAN_PACKET_RESIZE_LIMIT
- &&
- (!isValidSize)
- )
- {
- lprintf(LOG_DEBUG,"HPM: upload firmware block API called");
- lprintf(LOG_DEBUG,"HPM: returning length error to force resize");
-
- fakeRsp.ccode = IPMI_CC_REQ_DATA_INV_LENGTH;
- rsp = &fakeRsp;
- errorCount++;
- }
- else if
- (
- req.msg.netfn == IPMI_NETFN_PICMG
- &&
- ( req.msg.cmd == HPMFWUPG_ACTIVATE_FIRMWARE ||
- req.msg.cmd == HPMFWUPG_MANUAL_FIRMWARE_ROLLBACK )
- )
- {
- /*
- * rsp == NULL and command activate firmware or manual firmware
- * rollback most likely occurs when we have sent a firmware activation
- * request. Fake a command in progress response.
- */
- lprintf(LOG_DEBUG,"HPM: activate/rollback firmware API called");
- lprintf(LOG_DEBUG,"HPM: returning in progress to handle IOL session lost");
-
- fakeRsp.ccode = HPMFWUPG_COMMAND_IN_PROGRESS;
- rsp = &fakeRsp;
- }
- else if
- (
- req.msg.netfn == IPMI_NETFN_PICMG
- &&
- ( req.msg.cmd == HPMFWUPG_QUERY_ROLLBACK_STATUS ||
- req.msg.cmd == HPMFWUPG_GET_UPGRADE_STATUS )
- )
- {
- /*
- * rsp == NULL and command get upgrade status or query rollback
- * status most likely occurs when we are waiting for firmware
- * activation. Try to re-open the IOL session (re-open will work
- * once the IPMC recovers from firmware activation.
- */
-
- lprintf(LOG_DEBUG,"HPM: upg/rollback status firmware API called");
- lprintf(LOG_DEBUG,"HPM: try to re-open IOL session");
-
- {
- /* force session re-open */
- intf->opened = 0;
- intf->session->authtype = IPMI_SESSION_AUTHTYPE_NONE;
- intf->session->session_id = 0;
- intf->session->in_seq = 0;
- intf->session->out_seq = 0;
- intf->session->active = 0;
- intf->session->retry = 10;
-
- while
- (
- intf->open(intf) == HPMFWUPG_ERROR
- &&
- inaccessTimeoutCounter < inaccessTimeout
- )
- {
- inaccessTimeoutCounter += (time(NULL) - timeoutSec1);
- timeoutSec1 = time(NULL);
- }
- /* Fake timeout to retry command */
- fakeRsp.ccode = 0xc3;
- rsp = &fakeRsp;
- }
- }
- }
- }
-
- /* Handle inaccessibility timeout (rsp = NULL if IOL) */
- if ( rsp == NULL || rsp->ccode == 0xff || rsp->ccode == 0xc3 || rsp->ccode == 0xd3 )
- {
- if ( inaccessTimeoutCounter < inaccessTimeout )
- {
- timeoutSec2 = time(NULL);
- if ( timeoutSec2 > timeoutSec1 )
- {
- inaccessTimeoutCounter += timeoutSec2 - timeoutSec1;
- timeoutSec1 = time(NULL);
- }
- usleep(100000);
- retry = 1;
- }
- else
- {
- retry = 0;
- }
- }
- /* Handle node busy timeout */
- else if ( rsp->ccode == 0xc0 )
- {
- if ( upgradeTimeoutCounter < upgradeTimeout )
- {
- timeoutSec2 = time(NULL);
- if ( timeoutSec2 > timeoutSec1 )
- {
- timeoutSec1 = time(NULL);
- upgradeTimeoutCounter += timeoutSec2 - timeoutSec1;
- }
- usleep(100000);
- retry = 1;
- }
- else
- {
- retry = 0;
- }
- }
- else
- {
- #ifdef ENABLE_OPENIPMI_V39_PATCH
- if( rsp->ccode == IPMI_CC_OK )
- {
- errorCount = 0 ;
- }
- #endif
- retry = 0;
-
- if
- (
- req.msg.netfn == IPMI_NETFN_PICMG
- &&
- req.msg.cmd == HPMFWUPG_UPLOAD_FIRMWARE_BLOCK
- &&
- (!isValidSize)
- )
- {
- lprintf(LOG_INFO,"Buffer length is now considered valid" );
-
- isValidSize = TRUE;
+struct ipmi_rs *
+HpmfwupgSendCmd(struct ipmi_intf *intf, struct ipmi_rq req,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx)
+{
+ struct ipmi_rs *rsp;
+ unsigned int inaccessTimeout = 0, inaccessTimeoutCounter = 0;
+ unsigned int upgradeTimeout = 0, upgradeTimeoutCounter = 0;
+ unsigned int timeoutSec1, timeoutSec2;
+ unsigned char retry = 0;
+ /* If we are not in upgrade context, we use default timeout values */
+ if (pFwupgCtx != NULL) {
+ inaccessTimeout = pFwupgCtx->targetCap.inaccessTimeout*5;
+ upgradeTimeout = pFwupgCtx->targetCap.upgradeTimeout*5;
+ } else {
+ /* keeping the inaccessTimeout to 60 seconds results in almost 2900 retries
+ * So if the target is not available it will be retrying the command for 2900
+ * times which is not effecient -So reducing the Timout to 5 seconds which is
+ * almost 200 retries if it continuously recieves 0xC3 as completion code.
+ */
+ inaccessTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT;
+ upgradeTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT;
}
- }
- }while( retry );
- return rsp;
+ timeoutSec1 = time(NULL);
+ do {
+ static unsigned char isValidSize = FALSE;
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ #define HPM_LAN_PACKET_RESIZE_LIMIT 6
+ /* also covers lanplus */
+ if (strstr(intf->name, "lan") != NULL) {
+ static int errorCount=0;
+ static struct ipmi_rs fakeRsp;
+ lprintf(LOG_DEBUG,
+ "HPM: no response available");
+ lprintf(LOG_DEBUG,
+ "HPM: the command may be rejected for security reasons");
+ if (req.msg.netfn == IPMI_NETFN_PICMG
+ && req.msg.cmd == HPMFWUPG_UPLOAD_FIRMWARE_BLOCK
+ && errorCount < HPM_LAN_PACKET_RESIZE_LIMIT
+ && (!isValidSize)) {
+ lprintf(LOG_DEBUG,
+ "HPM: upload firmware block API called");
+ lprintf(LOG_DEBUG,
+ "HPM: returning length error to force resize");
+ fakeRsp.ccode = IPMI_CC_REQ_DATA_INV_LENGTH;
+ rsp = &fakeRsp;
+ errorCount++;
+ } else if (req.msg.netfn == IPMI_NETFN_PICMG
+ && (req.msg.cmd == HPMFWUPG_ACTIVATE_FIRMWARE
+ || req.msg.cmd == HPMFWUPG_MANUAL_FIRMWARE_ROLLBACK)) {
+ /*
+ * rsp == NULL and command activate firmware or manual firmware
+ * rollback most likely occurs when we have sent a firmware activation
+ * request. Fake a command in progress response.
+ */
+ lprintf(LOG_DEBUG,
+ "HPM: activate/rollback firmware API called");
+ lprintf(LOG_DEBUG,
+ "HPM: returning in progress to handle IOL session lost");
+ fakeRsp.ccode = HPMFWUPG_COMMAND_IN_PROGRESS;
+ rsp = &fakeRsp;
+ } else if (req.msg.netfn == IPMI_NETFN_PICMG
+ && (req.msg.cmd == HPMFWUPG_QUERY_ROLLBACK_STATUS
+ || req.msg.cmd == HPMFWUPG_GET_UPGRADE_STATUS
+ || req.msg.cmd == HPMFWUPG_QUERY_SELFTEST_RESULT)
+ && ( !intf->target_addr || intf->target_addr == intf->my_addr)) {
+ /* reopen session only if target IPMC is directly accessed */
+ /*
+ * rsp == NULL and command get upgrade status or query rollback
+ * status most likely occurs when we are waiting for firmware
+ * activation. Try to re-open the IOL session (re-open will work
+ * once the IPMC recovers from firmware activation.
+ */
+ lprintf(LOG_DEBUG, "HPM: upg/rollback status firmware API called");
+ lprintf(LOG_DEBUG, "HPM: try to re-open IOL session");
+ {
+ /* force session re-open */
+ intf->opened = 0;
+ intf->session->authtype = IPMI_SESSION_AUTHTYPE_NONE;
+ intf->session->session_id = 0;
+ intf->session->in_seq = 0;
+ intf->session->out_seq = 0;
+ intf->session->active = 0;
+ intf->session->retry = 10;
+ while (intf->open(intf) == HPMFWUPG_ERROR
+ && inaccessTimeoutCounter < inaccessTimeout) {
+ inaccessTimeoutCounter += (time(NULL) - timeoutSec1);
+ timeoutSec1 = time(NULL);
+ }
+ /* Fake timeout to retry command */
+ fakeRsp.ccode = 0xc3;
+ rsp = &fakeRsp;
+ }
+ }
+ }
+ }
+ /* Handle inaccessibility timeout (rsp = NULL if IOL) */
+ if (rsp == NULL || rsp->ccode == 0xff || rsp->ccode == 0xc3 || rsp->ccode == 0xd3) {
+ if (inaccessTimeoutCounter < inaccessTimeout) {
+ timeoutSec2 = time(NULL);
+ if (timeoutSec2 > timeoutSec1) {
+ inaccessTimeoutCounter += timeoutSec2 - timeoutSec1;
+ timeoutSec1 = time(NULL);
+ }
+ usleep(100000);
+ retry = 1;
+ } else {
+ retry = 0;
+ }
+ } else if ( rsp->ccode == 0xc0 ) {
+ /* Handle node busy timeout */
+ if (upgradeTimeoutCounter < upgradeTimeout) {
+ timeoutSec2 = time(NULL);
+ if (timeoutSec2 > timeoutSec1) {
+ timeoutSec1 = time(NULL);
+ upgradeTimeoutCounter += timeoutSec2 - timeoutSec1;
+ }
+ usleep(100000);
+ retry = 1;
+ } else {
+ retry = 0;
+ }
+ } else {
+# ifdef ENABLE_OPENIPMI_V39_PATCH
+ if (rsp->ccode == IPMI_CC_OK) {
+ errorCount = 0 ;
+ }
+# endif
+ retry = 0;
+ if (req.msg.netfn == IPMI_NETFN_PICMG
+ && req.msg.cmd == HPMFWUPG_UPLOAD_FIRMWARE_BLOCK
+ && (!isValidSize)) {
+ lprintf(LOG_INFO,
+ "Buffer length is now considered valid");
+ isValidSize = TRUE;
+ }
+ }
+ } while (retry);
+ return rsp;
}
-int HpmfwupgWaitLongDurationCmd(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx)
-{
- int rc = HPMFWUPG_SUCCESS;
- unsigned int upgradeTimeout = 0;
- unsigned int timeoutSec1, timeoutSec2;
- struct HpmfwupgGetUpgradeStatusCtx upgStatusCmd;
-
- /*
- * If we are not in upgrade context, we use default timeout values
- */
- if ( pFwupgCtx != NULL )
- {
- upgradeTimeout = (unsigned int)(pFwupgCtx->targetCap.upgradeTimeout*5);
- if ( verbose )
- printf("Use File Upgrade Capabilities: %i seconds\n", upgradeTimeout);
- }
- else
- {
- /* Try to retreive from Caps */
- struct HpmfwupgGetTargetUpgCapabilitiesCtx targetCapCmd;
-
- if(HpmfwupgGetTargetUpgCapabilities(intf, &targetCapCmd) != HPMFWUPG_SUCCESS)
- {
- upgradeTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT;
-
- if ( verbose )
- printf("Use default timeout: %i seconds\n", upgradeTimeout);
- }
- else
- {
- upgradeTimeout = (unsigned int)(targetCapCmd.resp.upgradeTimeout * 5);
- if ( verbose )
- printf("Use Command Upgrade Capabilities Timeout: %i seconds\n", upgradeTimeout);
- }
- }
-
- if(rc == HPMFWUPG_SUCCESS)
- {
- /* Poll upgrade status until completion or timeout*/
- timeoutSec1 = time(NULL);
- timeoutSec2 = time(NULL);
- rc = HpmfwupgGetUpgradeStatus(intf, &upgStatusCmd, pFwupgCtx, 1);
- }
-
- while(
- //With KCS: Cover the case where we sometime receive d5 (on the first get status) from the ipmi driver.
- (upgStatusCmd.resp.lastCmdCompCode != 0x00 ) &&
- ((timeoutSec2 - timeoutSec1) < upgradeTimeout ) &&
- (rc == HPMFWUPG_SUCCESS)
- )
- {
- /* Must wait at least 1000 ms between status requests */
- usleep(1000000);
- timeoutSec2 = time(NULL);
- rc = HpmfwupgGetUpgradeStatus(intf, &upgStatusCmd, pFwupgCtx, 1);
- //printf("Get Status: %x - %x = %x _ %x [%x]\n", timeoutSec2, timeoutSec1,(timeoutSec2 - timeoutSec1),upgradeTimeout, rc);
- }
-
- if ( upgStatusCmd.resp.lastCmdCompCode != 0x00 )
- {
- if ( verbose )
- {
- lprintf(LOG_NOTICE,"Error waiting for command %x, compcode = %x",
- upgStatusCmd.resp.cmdInProcess,
- upgStatusCmd.resp.lastCmdCompCode);
- }
- rc = HPMFWUPG_ERROR;
- }
-
- return rc;
+int
+HpmfwupgWaitLongDurationCmd(struct ipmi_intf *intf,
+ struct HpmfwupgUpgradeCtx *pFwupgCtx)
+{
+ int rc = HPMFWUPG_SUCCESS;
+ unsigned int upgradeTimeout = 0;
+ unsigned int timeoutSec1, timeoutSec2;
+ struct HpmfwupgGetUpgradeStatusCtx upgStatusCmd;
+ /* If we are not in upgrade context, we use default timeout values */
+ if (pFwupgCtx != NULL) {
+ upgradeTimeout = (unsigned int)(pFwupgCtx->targetCap.upgradeTimeout*5);
+ if (verbose) {
+ printf("Use File Upgrade Capabilities: %i seconds\n",
+ upgradeTimeout);
+ }
+ } else {
+ /* Try to retreive from Caps */
+ struct HpmfwupgGetTargetUpgCapabilitiesCtx targetCapCmd;
+ if(HpmfwupgGetTargetUpgCapabilities(intf, &targetCapCmd) != HPMFWUPG_SUCCESS) {
+ upgradeTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT;
+ if (verbose) {
+ printf("Use default timeout: %i seconds\n",
+ upgradeTimeout);
+ }
+ } else {
+ upgradeTimeout = (unsigned int)(targetCapCmd.resp.upgradeTimeout * 5);
+ if (verbose) {
+ printf("Use Command Upgrade Capabilities Timeout: %i seconds\n",
+ upgradeTimeout);
+ }
+ }
+ }
+ if (rc == HPMFWUPG_SUCCESS) {
+ /* Poll upgrade status until completion or timeout*/
+ timeoutSec1 = time(NULL);
+ timeoutSec2 = time(NULL);
+ rc = HpmfwupgGetUpgradeStatus(intf, &upgStatusCmd,
+ pFwupgCtx, 1);
+ }
+ while (
+ /* With KCS: Cover the case where we sometime
+ * receive d5 (on the first get status) from
+ * the ipmi driver.
+ */
+ (upgStatusCmd.resp.lastCmdCompCode != 0x00 )
+ && ((timeoutSec2 - timeoutSec1) < upgradeTimeout )
+ && (rc == HPMFWUPG_SUCCESS)) {
+ /* Must wait at least 1000 ms between status requests */
+ usleep(1000000);
+ timeoutSec2 = time(NULL);
+ rc = HpmfwupgGetUpgradeStatus(intf, &upgStatusCmd, pFwupgCtx, 1);
+/*
+ * printf("Get Status: %x - %x = %x _ %x [%x]\n",
+ ( timeoutSec2, timeoutSec1,
+ * (timeoutSec2 - timeoutSec1),
+ * upgradeTimeout, rc);
+ */
+ }
+ if (upgStatusCmd.resp.lastCmdCompCode != 0x00) {
+ if (verbose) {
+ lprintf(LOG_NOTICE,
+ "Error waiting for command %x, compcode = %x",
+ upgStatusCmd.resp.cmdInProcess,
+ upgStatusCmd.resp.lastCmdCompCode);
+ }
+ rc = HPMFWUPG_ERROR;
+ }
+ return rc;
}
-unsigned char HpmfwupgCalculateChecksum(unsigned char* pData, unsigned int length)
+unsigned char
+HpmfwupgCalculateChecksum(unsigned char *pData, unsigned int length)
{
- unsigned char checksum = 0;
- int dataIdx = 0;
-
- for ( dataIdx = 0; dataIdx < length; dataIdx++ )
- {
- checksum += pData[dataIdx];
- }
- return checksum;
+ unsigned char checksum = 0;
+ int dataIdx = 0;
+ for (dataIdx = 0; dataIdx < length; dataIdx++) {
+ checksum += pData[dataIdx];
+ }
+ return checksum;
}
-static void HpmfwupgPrintUsage(void)
-{
- lprintf(LOG_NOTICE,"help - This help menu.");
- lprintf(LOG_NOTICE,"");
- lprintf(LOG_NOTICE,"check - Check the target information.");
- lprintf(LOG_NOTICE,"check <file> - If the user is unsure of what update is going to be ");
- lprintf(LOG_NOTICE," This will display the existing target version and");
- lprintf(LOG_NOTICE," image version on the screen");
- lprintf(LOG_NOTICE,"");
- lprintf(LOG_NOTICE,"upgrade <file> - Copies all the components from a valid HPM.1");
- lprintf(LOG_NOTICE," image <file> to the target.");
- lprintf(LOG_NOTICE," This compares the versions from both the target");
- lprintf(LOG_NOTICE," and image and will only perform the copy");
- lprintf(LOG_NOTICE," if the versions differ.");
- lprintf(LOG_NOTICE,"upgrade <file> activate - Copy and activate the firmware using a valid HPM.1");
- lprintf(LOG_NOTICE," image <file>.");
- lprintf(LOG_NOTICE," This compares the versions from both the target");
- lprintf(LOG_NOTICE," and image and will only perform the copy and");
- lprintf(LOG_NOTICE," activation if the versions differ.");
- lprintf(LOG_NOTICE,"upgrade <file> force - Copies all the components present in <file>");
- lprintf(LOG_NOTICE," to the target board without checking the versions.");
- lprintf(LOG_NOTICE," Make sure to check the versions first using the");
- lprintf(LOG_NOTICE," \"check <file>\" command.");
- lprintf(LOG_NOTICE,"upgrade <file> component x - Copy only component <x> from the given <file>");
- lprintf(LOG_NOTICE," without checking if the versions differ.");
- lprintf(LOG_NOTICE," For example:");
- lprintf(LOG_NOTICE," component 0 = Bootloader");
- lprintf(LOG_NOTICE," component 1 = Firmware");
- lprintf(LOG_NOTICE," Make sure to check the versions first using the");
- lprintf(LOG_NOTICE," \"check <file>\" command.");
- lprintf(LOG_NOTICE,"upgstatus - Returns the status of the last long duration command.");
- lprintf(LOG_NOTICE,"");
- lprintf(LOG_NOTICE,"activate - Activate the newly uploaded firmware.");
- lprintf(LOG_NOTICE,"activate norollback - Activate the newly uploaded firmware but inform");
- lprintf(LOG_NOTICE," the target to not automatically rollback if ");
- lprintf(LOG_NOTICE," the upgrade fails.");
- lprintf(LOG_NOTICE,"");
- lprintf(LOG_NOTICE,"targetcap - Get the target upgrade capabilities.");
- lprintf(LOG_NOTICE,"");
- lprintf(LOG_NOTICE,"compprop <id> <prop> - Get specified component properties from the target.");
- lprintf(LOG_NOTICE," Valid component <id>: 0-7 ");
- lprintf(LOG_NOTICE," Properties <prop> can be one of the following: ");
- lprintf(LOG_NOTICE," 0- General properties");
- lprintf(LOG_NOTICE," 1- Current firmware version");
- lprintf(LOG_NOTICE," 2- Description string");
- lprintf(LOG_NOTICE," 3- Rollback firmware version");
- lprintf(LOG_NOTICE," 4- Deferred firmware version");
- lprintf(LOG_NOTICE,"");
- lprintf(LOG_NOTICE,"abort - Abort the on-going firmware upgrade.");
- lprintf(LOG_NOTICE,"");
- lprintf(LOG_NOTICE,"rollback - Performs a manual rollback on the IPM Controller.");
- lprintf(LOG_NOTICE," firmware");
- lprintf(LOG_NOTICE,"rollbackstatus - Query the rollback status.");
- lprintf(LOG_NOTICE,"");
- lprintf(LOG_NOTICE,"selftestresult - Query the self test results.\n");
+void
+HpmfwupgPrintUsage(void)
+{
+ lprintf(LOG_NOTICE,
+"help - This help menu.");
+ lprintf(LOG_NOTICE,
+"");
+ lprintf(LOG_NOTICE,
+"check - Check the target information.");
+ lprintf(LOG_NOTICE,
+"check <file> - If the user is unsure of what update is going to be ");
+ lprintf(LOG_NOTICE,
+" This will display the existing target version and");
+ lprintf(LOG_NOTICE,
+" image version on the screen");
+ lprintf(LOG_NOTICE,
+"");
+ lprintf(LOG_NOTICE,
+"upgrade <file> [component x...] [force] [activate]");
+ lprintf(LOG_NOTICE,
+" - Copies components from a valid HPM.1 image to the target.");
+ lprintf(LOG_NOTICE,
+" If one or more components specified by \"component\",");
+ lprintf(LOG_NOTICE,
+" only the specified components are copied.");
+ lprintf(LOG_NOTICE,
+" Otherwise, all the image components are copied.");
+ lprintf(LOG_NOTICE,
+" Before copy, each image component undergoes a version check");
+ lprintf(LOG_NOTICE,
+" and can be skipped if the target component version");
+ lprintf(LOG_NOTICE,
+" is the same or more recent.");
+ lprintf(LOG_NOTICE,
+" Use \"force\" to bypass the version check results.");
+ lprintf(LOG_NOTICE,
+" Make sure to check the versions first using the");
+ lprintf(LOG_NOTICE,
+" \"check <file>\" command.");
+ lprintf(LOG_NOTICE,
+" If \"activate\" is specified, the newly uploaded firmware");
+ lprintf(LOG_NOTICE,
+" is activated.");
+ lprintf(LOG_NOTICE,
+"upgstatus - Returns the status of the last long duration command.");
+ lprintf(LOG_NOTICE,
+"");
+ lprintf(LOG_NOTICE,
+"compare <file> - Perform \"Comparison of the Active Copy\" action for all the");
+ lprintf(LOG_NOTICE,
+" components present in the file.");
+ lprintf(LOG_NOTICE,
+"compare <file> component x - Compare only component <x> from the given <file>");
+ lprintf(LOG_NOTICE,
+"activate - Activate the newly uploaded firmware.");
+ lprintf(LOG_NOTICE,
+"activate norollback - Activate the newly uploaded firmware but inform");
+ lprintf(LOG_NOTICE,
+" the target to not automatically rollback if ");
+ lprintf(LOG_NOTICE,
+" the upgrade fails.");
+ lprintf(LOG_NOTICE,
+"");
+ lprintf(LOG_NOTICE,
+"targetcap - Get the target upgrade capabilities.");
+ lprintf(LOG_NOTICE,
+"");
+ lprintf(LOG_NOTICE,
+"compprop <id> <prop> - Get specified component properties from the target.");
+ lprintf(LOG_NOTICE,
+" Valid component <id>: 0-7 ");
+ lprintf(LOG_NOTICE,
+" Properties <prop> can be one of the following: ");
+ lprintf(LOG_NOTICE,
+" 0- General properties");
+ lprintf(LOG_NOTICE,
+" 1- Current firmware version");
+ lprintf(LOG_NOTICE,
+" 2- Description string");
+ lprintf(LOG_NOTICE,
+" 3- Rollback firmware version");
+ lprintf(LOG_NOTICE,
+" 4- Deferred firmware version");
+ lprintf(LOG_NOTICE,
+"");
+ lprintf(LOG_NOTICE,
+"abort - Abort the on-going firmware upgrade.");
+ lprintf(LOG_NOTICE,
+"");
+ lprintf(LOG_NOTICE,
+"rollback - Performs a manual rollback on the IPM Controller.");
+ lprintf(LOG_NOTICE,
+" firmware");
+ lprintf(LOG_NOTICE,
+"rollbackstatus - Query the rollback status.");
+ lprintf(LOG_NOTICE,
+"");
+ lprintf(LOG_NOTICE,
+"selftestresult - Query the self test results.\n");
}
-int ipmi_hpmfwupg_main(struct ipmi_intf * intf, int argc, char ** argv)
-{
- int rc = HPMFWUPG_SUCCESS;
- int activateFlag = 0x00;
- int componentId = DEFAULT_COMPONENT_UPLOAD;
- int option = VERSIONCHECK_MODE;
-
- lprintf(LOG_DEBUG,"ipmi_hpmfwupg_main()");
-
-
- lprintf(LOG_NOTICE,"\nPICMG HPM.1 Upgrade Agent %d.%d.%d: \n",
- HPMFWUPG_VERSION_MAJOR, HPMFWUPG_VERSION_MINOR, HPMFWUPG_VERSION_SUBMINOR);
-
- if ( (argc == 0) || (strcmp(argv[0], "help") == 0) )
- {
- HpmfwupgPrintUsage();
- return HPMFWUPG_ERROR;
- }
- if ( (strcmp(argv[0], "check") == 0) )
- {
- /* hpm check */
- if (argv[1] == NULL)
- {
- rc = HpmfwupgTargetCheck(intf,VIEW_MODE);
- }
- else
- {
- /* hpm check <filename> */
- rc = HpmfwupgTargetCheck(intf,0);
- if (rc == HPMFWUPG_SUCCESS)
- {
- rc = HpmfwupgUpgrade(intf, argv[1],0,DEFAULT_COMPONENT_UPLOAD,VIEW_MODE);
- }
- }
- }
-
- else if ( strcmp(argv[0], "upgrade") == 0)
- {
- int i =0;
- for (i=1; i< argc ; i++)
- {
- if (strcmp(argv[i],"activate") == 0)
- {
- activateFlag = 1;
- }
- /* hpm upgrade <filename> force */
- if (strcmp(argv[i],"force") == 0)
- {
- option &= ~(VERSIONCHECK_MODE);
- option &= ~(VIEW_MODE);
- option |= FORCE_MODE_ALL;
- }
- /* hpm upgrade <filename> component <comp Id> */
- if (strcmp(argv[i],"component") == 0)
- {
- if (i+1 < argc)
- {
- if (str2int(argv[i+1], &componentId) != 0 ||
- componentId < 0 || componentId > 7) {
- lprintf(LOG_ERR, "Given Component ID '%s' is invalid.",
- argv[i+1]);
- lprintf(LOG_ERR, "Valid Compoment ID is: <0..7>");
- return (-1);
- }
- option &= ~(VERSIONCHECK_MODE);
- option &= ~(VIEW_MODE);
- option |= FORCE_MODE_COMPONENT;
-
- if( verbose ) {
- lprintf(LOG_NOTICE,"Component Id %d provided",componentId );
- }
-
- /* Error Checking */
- if (componentId >= HPMFWUPG_COMPONENT_ID_MAX)
- {
- lprintf(LOG_NOTICE,"Given component ID %d exceeds Max Comp ID %d\n",
- componentId, HPMFWUPG_COMPONENT_ID_MAX-1);
- return HPMFWUPG_ERROR;
- }
- }
- if (componentId == DEFAULT_COMPONENT_UPLOAD)
- {
- /* That indicates the user has given component on console but not
- * given any ID */
- lprintf(LOG_NOTICE,"No component Id provided\n");
- return HPMFWUPG_ERROR;
- }
- }
- if (strcmp(argv[i],"debug") == 0)
- {
- option |= DEBUG_MODE;
- }
- }
- rc = HpmfwupgTargetCheck(intf,0);
- if (rc == HPMFWUPG_SUCCESS)
- {
- /* Call the Upgrade function to start the upgrade */
- rc = HpmfwupgUpgrade(intf, argv[1],activateFlag,componentId,option);
- }
- }
-
- else if ( (argc >= 1) && (strcmp(argv[0], "activate") == 0) )
- {
- struct HpmfwupgActivateFirmwareCtx cmdCtx;
- if ( (argc == 2) && (strcmp(argv[1], "norollback") == 0) )
- cmdCtx.req.rollback_override = 1;
- else
- cmdCtx.req.rollback_override = 0;
- rc = HpmfwupgActivateFirmware(intf, &cmdCtx, NULL);
- }
- else if ( (argc == 1) && (strcmp(argv[0], "targetcap") == 0) )
- {
- struct HpmfwupgGetTargetUpgCapabilitiesCtx cmdCtx;
- verbose++;
- rc = HpmfwupgGetTargetUpgCapabilities(intf, &cmdCtx);
- }
- else if ( (argc == 3) && (strcmp(argv[0], "compprop") == 0) )
- {
- struct HpmfwupgGetComponentPropertiesCtx cmdCtx;
- if (str2uchar(argv[1], &(cmdCtx.req.componentId)) != 0
- || cmdCtx.req.componentId > 7) {
- lprintf(LOG_ERR, "Given Component ID '%s' is invalid.", argv[1]);
- lprintf(LOG_ERR, "Valid Compoment ID is: <0..7>");
- return (-1);
- }
- if (str2uchar(argv[2], &(cmdCtx.req.selector)) != 0
- || cmdCtx.req.selector > 4) {
- lprintf(LOG_ERR, "Given Properties selector '%s' is invalid.",
- argv[2]);
- lprintf(LOG_ERR, "Valid Properties selector is: <0..4>");
- return (-1);
- }
- verbose++;
- rc = HpmfwupgGetComponentProperties(intf, &cmdCtx);
- }
- else if ( (argc == 1) && (strcmp(argv[0], "abort") == 0) )
- {
- struct HpmfwupgAbortUpgradeCtx cmdCtx;
- verbose++;
- rc = HpmfwupgAbortUpgrade(intf, &cmdCtx);
- }
- else if ( (argc == 1) && (strcmp(argv[0], "upgstatus") == 0) )
- {
- struct HpmfwupgGetUpgradeStatusCtx cmdCtx;
- verbose++;
- rc = HpmfwupgGetUpgradeStatus(intf, &cmdCtx, NULL, 0);
- }
- else if ( (argc == 1) && (strcmp(argv[0], "rollback") == 0) )
- {
- struct HpmfwupgManualFirmwareRollbackCtx cmdCtx;
- verbose++;
- rc = HpmfwupgManualFirmwareRollback(intf, &cmdCtx, NULL);
- }
- else if ( (argc == 1) && (strcmp(argv[0], "rollbackstatus") == 0) )
- {
- struct HpmfwupgQueryRollbackStatusCtx cmdCtx;
- verbose++;
- rc = HpmfwupgQueryRollbackStatus(intf, &cmdCtx, NULL);
- }
- else if ( (argc == 1) && (strcmp(argv[0], "selftestresult") == 0) )
- {
- struct HpmfwupgQuerySelftestResultCtx cmdCtx;
- verbose++;
- rc = HpmfwupgQuerySelftestResult(intf, &cmdCtx, NULL);
- }
- else
- {
- HpmfwupgPrintUsage();
- }
-
- return rc;
+int
+ipmi_hpmfwupg_main(struct ipmi_intf *intf, int argc, char **argv)
+{
+ int rc = HPMFWUPG_SUCCESS;
+ int activateFlag = 0x00;
+ int componentMask = 0;
+ int componentId = 0;
+ int option = 0;
+
+ lprintf(LOG_DEBUG,"ipmi_hpmfwupg_main()");
+ lprintf(LOG_NOTICE, "\nPICMG HPM.1 Upgrade Agent %d.%d.%d: \n",
+ HPMFWUPG_VERSION_MAJOR, HPMFWUPG_VERSION_MINOR,
+ HPMFWUPG_VERSION_SUBMINOR);
+ if (argc < 1) {
+ lprintf(LOG_ERR, "Not enough parameters given.");
+ HpmfwupgPrintUsage();
+ return HPMFWUPG_ERROR;
+ }
+ if (strcmp(argv[0], "help") == 0) {
+ HpmfwupgPrintUsage();
+ return HPMFWUPG_SUCCESS;
+ } else if ((strcmp(argv[0], "check") == 0)) {
+ /* hpm check */
+ if (argv[1] == NULL) {
+ rc = HpmfwupgTargetCheck(intf,VIEW_MODE);
+ } else {
+ /* hpm check <filename> */
+ rc = HpmfwupgTargetCheck(intf,0);
+ if (rc == HPMFWUPG_SUCCESS) {
+ rc = HpmfwupgUpgrade(intf, argv[1], 0,
+ 0, VIEW_MODE);
+ }
+ }
+ } else if (strcmp(argv[0], "upgrade") == 0) {
+ int i =0;
+ for (i=1; i< argc ; i++) {
+ if (strcmp(argv[i],"activate") == 0) {
+ activateFlag = 1;
+ }
+ /* hpm upgrade <filename> force */
+ if (strcmp(argv[i],"force") == 0) {
+ option |= FORCE_MODE;
+ }
+ /* hpm upgrade <filename> component <comp Id> */
+ if (strcmp(argv[i],"component") == 0) {
+ if (i+1 < argc) {
+ /* Error Checking */
+ if (str2int(argv[i+1], &componentId) != 0
+ || componentId < 0
+ || componentId > HPMFWUPG_COMPONENT_ID_MAX) {
+ lprintf(LOG_ERR,
+ "Given Component ID '%s' is invalid.",
+ argv[i+1]);
+ lprintf(LOG_ERR,
+ "Valid Compoment ID is: <0..7>");
+ return HPMFWUPG_ERROR;
+ }
+ if( verbose ) {
+ lprintf(LOG_NOTICE,
+ "Component Id %d provided",
+ componentId );
+ }
+ componentMask |= 1 << componentId;
+ } else {
+ /* That indicates the user has
+ * given component on console but
+ * not given any ID
+ */
+ lprintf(LOG_NOTICE,
+ "No component Id provided\n");
+ return HPMFWUPG_ERROR;
+ }
+ }
+ if (strcmp(argv[i],"debug") == 0) {
+ option |= DEBUG_MODE;
+ }
+ }
+ rc = HpmfwupgTargetCheck(intf, 0);
+ if (rc == HPMFWUPG_SUCCESS) {
+ /* Call the Upgrade function to start the upgrade */
+ rc = HpmfwupgUpgrade(intf, argv[1], activateFlag,
+ componentMask, option);
+ }
+ } else if (strcmp(argv[0], "compare") == 0) {
+ int i = 0;
+ for (i=1; i< argc; i++) {
+ /* hpm compare <file> [component x...] */
+ if (strcmp(argv[i],"component") == 0) {
+ if (i+1 < argc) {
+ /* Error Checking */
+ if (str2int(argv[i+1], &componentId) != 0
+ || componentId < 0
+ || componentId > HPMFWUPG_COMPONENT_ID_MAX) {
+ lprintf(LOG_ERR,
+ "Given Component ID '%s' is invalid.",
+ argv[i+1]);
+ lprintf(LOG_ERR,
+ "Valid Compoment ID is: <0..7>");
+ return HPMFWUPG_ERROR;
+ }
+ if( verbose ) {
+ lprintf(LOG_NOTICE,
+ "Component Id %d provided",
+ componentId);
+ }
+ componentMask|= 1 << componentId;
+ } else {
+ /* That indicates the user
+ * has given component on
+ * console but not
+ * given any ID
+ */
+ lprintf(LOG_NOTICE,
+ "No component Id provided\n");
+ return HPMFWUPG_ERROR;
+ }
+ } else if (strcmp(argv[i],"debug") == 0) {
+ option|= DEBUG_MODE;
+ }
+ }
+ option|= (COMPARE_MODE);
+ rc = HpmfwupgTargetCheck(intf, 0);
+ if (rc == HPMFWUPG_SUCCESS) {
+ rc = HpmfwupgUpgrade(intf, argv[1], 0,
+ componentMask, option);
+ }
+ } else if ((argc >= 1) && (strcmp(argv[0], "activate") == 0)) {
+ struct HpmfwupgActivateFirmwareCtx cmdCtx;
+ if ((argc == 2) && (strcmp(argv[1], "norollback") == 0)) {
+ cmdCtx.req.rollback_override = 1;
+ } else {
+ cmdCtx.req.rollback_override = 0;
+ }
+ rc = HpmfwupgActivateFirmware(intf, &cmdCtx, NULL);
+ } else if ((argc == 1) && (strcmp(argv[0], "targetcap") == 0)) {
+ struct HpmfwupgGetTargetUpgCapabilitiesCtx cmdCtx;
+ verbose++;
+ rc = HpmfwupgGetTargetUpgCapabilities(intf, &cmdCtx);
+ } else if ((argc == 3) && (strcmp(argv[0], "compprop") == 0)) {
+ struct HpmfwupgGetComponentPropertiesCtx cmdCtx;
+ if (str2uchar(argv[1], &(cmdCtx.req.componentId)) != 0
+ || cmdCtx.req.componentId > 7) {
+ lprintf(LOG_ERR,
+ "Given Component ID '%s' is invalid.",
+ argv[1]);
+ lprintf(LOG_ERR,
+ "Valid Compoment ID is: <0..7>");
+ return (-1);
+ }
+ if (str2uchar(argv[2], &(cmdCtx.req.selector)) != 0
+ || cmdCtx.req.selector > 4) {
+ lprintf(LOG_ERR,
+ "Given Properties selector '%s' is invalid.",
+ argv[2]);
+ lprintf(LOG_ERR,
+ "Valid Properties selector is: <0..4>");
+ return (-1);
+ }
+ verbose++;
+ rc = HpmfwupgGetComponentProperties(intf, &cmdCtx);
+ } else if ((argc == 1) && (strcmp(argv[0], "abort") == 0)) {
+ struct HpmfwupgAbortUpgradeCtx cmdCtx;
+ verbose++;
+ rc = HpmfwupgAbortUpgrade(intf, &cmdCtx);
+ } else if ((argc == 1) && (strcmp(argv[0], "upgstatus") == 0)) {
+ struct HpmfwupgGetUpgradeStatusCtx cmdCtx;
+ verbose++;
+ rc = HpmfwupgGetUpgradeStatus(intf, &cmdCtx, NULL, 0);
+ } else if ((argc == 1) && (strcmp(argv[0], "rollback") == 0)) {
+ struct HpmfwupgManualFirmwareRollbackCtx cmdCtx;
+ verbose++;
+ rc = HpmfwupgManualFirmwareRollback(intf, &cmdCtx);
+ } else if ((argc == 1) && (strcmp(argv[0], "rollbackstatus") == 0)) {
+ struct HpmfwupgQueryRollbackStatusCtx cmdCtx;
+ verbose++;
+ rc = HpmfwupgQueryRollbackStatus(intf, &cmdCtx, NULL);
+ } else if ((argc == 1) && (strcmp(argv[0], "selftestresult") == 0)) {
+ struct HpmfwupgQuerySelftestResultCtx cmdCtx;
+ verbose++;
+ rc = HpmfwupgQuerySelftestResult(intf, &cmdCtx, NULL);
+ } else {
+ lprintf(LOG_ERR, "Invalid HPM command: %s", argv[0]);
+ HpmfwupgPrintUsage();
+ rc = HPMFWUPG_ERROR;
+ }
+ return rc;
}
diff --git a/ipmitool/lib/ipmi_kontronoem.c b/ipmitool/lib/ipmi_kontronoem.c
index dac2ced..c154eda 100644
--- a/ipmitool/lib/ipmi_kontronoem.c
+++ b/ipmitool/lib/ipmi_kontronoem.c
@@ -350,6 +350,7 @@ ipmi_kontron_set_serial_number(struct ipmi_intf * intf)
return(-1);
}
+ memset(&fru, 0, sizeof(fru));
fru.size = (rsp->data[1] << 8) | rsp->data[0];
fru.access = rsp->data[2] & 0x1;
@@ -637,6 +638,7 @@ ipmi_kontron_set_mfg_date (struct ipmi_intf * intf)
return(-1);
}
+ memset(&fru, 0, sizeof(fru));
fru.size = (rsp->data[1] << 8) | rsp->data[0];
fru.access = rsp->data[2] & 0x1;
diff --git a/ipmitool/lib/ipmi_main.c b/ipmitool/lib/ipmi_main.c
index 54b80c0..3d0a3b8 100644
--- a/ipmitool/lib/ipmi_main.c
+++ b/ipmitool/lib/ipmi_main.c
@@ -894,9 +894,11 @@ ipmi_main(int argc, char ** argv,
/* Open the interface with the specified or default IPMB address */
ipmi_main_intf->my_addr = arg_addr ? arg_addr : IPMI_BMC_SLAVE_ADDR;
- if (ipmi_main_intf->open != NULL)
- ipmi_main_intf->open(ipmi_main_intf);
-
+ if (ipmi_main_intf->open != NULL) {
+ if (ipmi_main_intf->open(ipmi_main_intf) < 0) {
+ goto out_free;
+ }
+ }
/*
* Attempt picmg discovery of the actual interface address unless
* the users specified an address.
diff --git a/ipmitool/lib/ipmi_sdr.c b/ipmitool/lib/ipmi_sdr.c
index 093d1ec..d44bbbb 100644
--- a/ipmitool/lib/ipmi_sdr.c
+++ b/ipmitool/lib/ipmi_sdr.c
@@ -456,10 +456,12 @@ ipmi_sdr_get_sensor_thresholds(struct ipmi_intf *intf, uint8_t sensor,
{
struct ipmi_rq req;
struct ipmi_rs *rsp;
- uint32_t save_addr = 0;
+ uint8_t bridged_request = 0;
+ uint32_t save_addr;
uint32_t save_channel;
if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ bridged_request = 1;
save_addr = intf->target_addr;
intf->target_addr = target;
save_channel = intf->target_channel;
@@ -474,7 +476,7 @@ ipmi_sdr_get_sensor_thresholds(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = sizeof (sensor);
rsp = intf->sendrecv(intf, &req);
- if ( save_addr ) {
+ if (bridged_request) {
intf->target_addr = save_addr;
intf->target_channel = save_channel;
}
@@ -498,10 +500,12 @@ ipmi_sdr_get_sensor_hysteresis(struct ipmi_intf *intf, uint8_t sensor,
struct ipmi_rq req;
uint8_t rqdata[2];
struct ipmi_rs *rsp;
- uint32_t save_addr = 0;
+ uint8_t bridged_request = 0;
+ uint32_t save_addr;
uint32_t save_channel;
if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ bridged_request = 1;
save_addr = intf->target_addr;
intf->target_addr = target;
save_channel = intf->target_channel;
@@ -519,7 +523,7 @@ ipmi_sdr_get_sensor_hysteresis(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = 2;
rsp = intf->sendrecv(intf, &req);
- if ( save_addr ) {
+ if (bridged_request) {
intf->target_addr = save_addr;
intf->target_channel = save_channel;
}
@@ -564,10 +568,17 @@ ipmi_sdr_get_sensor_reading_ipmb(struct ipmi_intf *intf, uint8_t sensor,
{
struct ipmi_rq req;
struct ipmi_rs *rsp;
- uint32_t save_addr = 0;
+ uint8_t bridged_request = 0;
+ uint32_t save_addr;
uint32_t save_channel;
if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ lprintf(LOG_DEBUG,
+ "Bridge to Sensor "
+ "Intf my/%#x tgt/%#x:%#x Sdr tgt/%#x:%#x\n",
+ intf->my_addr, intf->target_addr, intf->target_channel,
+ target, channel);
+ bridged_request = 1;
save_addr = intf->target_addr;
intf->target_addr = target;
save_channel = intf->target_channel;
@@ -581,7 +592,7 @@ ipmi_sdr_get_sensor_reading_ipmb(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
- if ( save_addr ) {
+ if (bridged_request) {
intf->target_addr = save_addr;
intf->target_channel = save_channel;
}
@@ -604,10 +615,12 @@ ipmi_sdr_get_sensor_event_status(struct ipmi_intf *intf, uint8_t sensor,
{
struct ipmi_rq req;
struct ipmi_rs *rsp;
- uint32_t save_addr = 0;
+ uint8_t bridged_request = 0;
+ uint32_t save_addr;
uint32_t save_channel;
if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ bridged_request = 1;
save_addr = intf->target_addr;
intf->target_addr = target;
save_channel = intf->target_channel;
@@ -621,7 +634,7 @@ ipmi_sdr_get_sensor_event_status(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
- if ( save_addr ) {
+ if (bridged_request) {
intf->target_addr = save_addr;
intf->target_channel = save_channel;
}
@@ -644,10 +657,12 @@ ipmi_sdr_get_sensor_event_enable(struct ipmi_intf *intf, uint8_t sensor,
{
struct ipmi_rq req;
struct ipmi_rs *rsp;
- uint32_t save_addr = 0;
+ uint8_t bridged_request = 0;
+ uint32_t save_addr;
uint32_t save_channel;
if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
+ bridged_request = 1;
save_addr = intf->target_addr;
intf->target_addr = target;
save_channel = intf->target_channel;
@@ -662,7 +677,7 @@ ipmi_sdr_get_sensor_event_enable(struct ipmi_intf *intf, uint8_t sensor,
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
- if ( save_addr ) {
+ if (bridged_request) {
intf->target_addr = save_addr;
intf->target_channel = save_channel;
}
@@ -2407,6 +2422,7 @@ ipmi_sdr_print_sensor_oem_intel(struct ipmi_intf *intf,
("Power Redundancy | PS@%02xh | nr\n",
oem->data[8]);
}
+ break;
case 9: /* SR2300, non-redundant, PSx present */
if (verbose) {
printf("Power Redundancy : Yes\n");
diff --git a/ipmitool/lib/ipmi_sel.c b/ipmitool/lib/ipmi_sel.c
index b06a81a..63ecbcf 100644
--- a/ipmitool/lib/ipmi_sel.c
+++ b/ipmitool/lib/ipmi_sel.c
@@ -322,7 +322,6 @@ ipmi_get_oem(struct ipmi_intf * intf)
return IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id);
}
-
static int
ipmi_sel_add_entry(struct ipmi_intf * intf, struct sel_event_record * rec)
{
@@ -526,6 +525,115 @@ get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
return description;
}
+char *
+get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ char *desc = NULL;
+ char *str;
+ int chipset_type = 1;
+ int data1;
+ int data2;
+ int data3;
+ int length;
+ int sensor_type;
+ uint8_t i = 0;
+ uint16_t oem_id = 0;
+ /* Get the OEM event Bytes of the SEL Records byte 13, 14, 15 to
+ * data1,data2,data3
+ */
+ data1 = rec->sel_type.standard_type.event_data[0];
+ data2 = rec->sel_type.standard_type.event_data[1];
+ data3 = rec->sel_type.standard_type.event_data[2];
+ /* Check for the Standard Event type == 0x6F */
+ if (rec->sel_type.standard_type.event_type != 0x6F) {
+ return NULL;
+ }
+ /* Allocate mem for te Description string */
+ desc = (char *)malloc(SIZE_OF_DESC);
+ if (desc == NULL) {
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
+ return NULL;
+ }
+ memset(desc,0,SIZE_OF_DESC);
+ sensor_type = rec->sel_type.standard_type.sensor_type;
+ switch (sensor_type) {
+ case SENSOR_TYPE_MEMORY:
+ memset(&req, 0, sizeof (req));
+ req.msg.netfn = IPMI_NETFN_APP;
+ req.msg.lun = 0;
+ req.msg.cmd = BMC_GET_DEVICE_ID;
+ req.msg.data = NULL;
+ req.msg.data_len = 0;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, " Error getting system info");
+ if (desc != NULL) {
+ free(desc);
+ desc = NULL;
+ }
+ return NULL;
+ } else if (rsp->ccode > 0) {
+ lprintf(LOG_ERR, " Error getting system info: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ if (desc != NULL) {
+ free(desc);
+ desc = NULL;
+ }
+ return NULL;
+ }
+ /* check the chipset type */
+ oem_id = ipmi_get_oem_id(intf);
+ if (oem_id == 0) {
+ return NULL;
+ }
+ length = sizeof(supermicro_X8);
+ for (i = 0; i < length; i++) {
+ if (oem_id == supermicro_X8[i]) {
+ chipset_type = 0;
+ break;
+ }
+ }
+ length = sizeof(supermicro_x9);
+ for (i = 0; i < length; i++) {
+ if (oem_id == supermicro_x9[i]) {
+ chipset_type = 2;
+ break;
+ }
+ }
+ if (chipset_type == 0) {
+ snprintf(desc, SIZE_OF_DESC, "@DIMM%2X(CPU%x)",
+ data2,
+ (data3 & 0x03) + 1);
+ } else if (chipset_type == 1) {
+ snprintf(desc, SIZE_OF_DESC, "@DIMM%c%c(CPU%x)",
+ (data2 >> 4) + 0x40 + (data3 & 0x3) * 4,
+ (data2 & 0xf) + 0x27, (data3 & 0x03) + 1);
+ } else if (chipset_type == 2) {
+ snprintf(desc, SIZE_OF_DESC, "@DIMM%c%c(CPU%x)",
+ (data2 >> 4) + 0x40 + (data3 & 0x3) * 3,
+ (data2 & 0xf) + 0x27, (data3 & 0x03) + 1);
+ } else {
+ snprintf(desc, SIZE_OF_DESC, "");
+ }
+ break;
+ case SENSOR_TYPE_SUPERMICRO_OEM:
+ if (data1 == 0x80 && data3 == 0xFF) {
+ if (data2 == 0x0) {
+ snprintf(desc, SIZE_OF_DESC, "BMC unexpected reset");
+ } else if (data2 == 0x1) {
+ snprintf(desc, SIZE_OF_DESC, "BMC cold reset");
+ } else if (data2 == 0x2) {
+ snprintf(desc, SIZE_OF_DESC, "BMC warm reset");
+ }
+ }
+ break;
+ }
+ return desc;
+}
+
/*
* Function : Decoding the SEL OEM Bytes for the DELL Platforms.
* Description : The below fucntion will decode the SEL Events OEM Bytes for the Dell specific Sensors only.
@@ -1067,6 +1175,10 @@ ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
case IPMI_OEM_DELL: // Dell Decoding of the OEM Bytes from SEL Record.
desc = get_dell_evt_desc(intf, rec);
break;
+ case IPMI_OEM_SUPERMICRO:
+ case IPMI_OEM_SUPERMICRO_47488:
+ desc = get_supermicro_evt_desc(intf, rec);
+ break;
case IPMI_OEM_UNKNOWN:
default:
break;
@@ -1092,7 +1204,6 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
*desc = ipmi_get_oem_desc(intf, rec);
return;
} else if (rec->sel_type.standard_type.event_type == 0x6f) {
-
if( rec->sel_type.standard_type.sensor_type >= 0xC0 && rec->sel_type.standard_type.sensor_type < 0xF0) {
IPMI_OEM iana = ipmi_get_oem(intf);
@@ -1116,12 +1227,27 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
sfx = ipmi_get_oem_desc(intf, rec);
}
break;
+ case IPMI_OEM_SUPERMICRO:
+ case IPMI_OEM_SUPERMICRO_47488:
+ evt = sensor_specific_types;
+ code = rec->sel_type.standard_type.sensor_type;
+ sfx = ipmi_get_oem_desc(intf, rec);
+ break;
/* add your oem sensor assignation here */
}
if( evt == NULL ){
lprintf(LOG_DEBUG, "oem sensor type %x using standard type supplied description",
rec->sel_type.standard_type.sensor_type );
}
+ } else {
+ switch (ipmi_get_oem(intf)) {
+ case IPMI_OEM_SUPERMICRO:
+ case IPMI_OEM_SUPERMICRO_47488:
+ evt = sensor_specific_types;
+ code = rec->sel_type.standard_type.sensor_type;
+ sfx = ipmi_get_oem_desc(intf, rec);
+ break;
+ }
}
if( evt == NULL ){
evt = sensor_specific_types;
@@ -1210,6 +1336,9 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
if(0x01 == offset)
flag = 0x01;
break;
+ case SENSOR_TYPE_SUPERMICRO_OEM:
+ flag = 0x02;
+ break;
default:
break;
}
@@ -1222,6 +1351,10 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
return;
}
memset(*desc, 0, 48 + SIZE_OF_DESC);
+ if (flag == 0x02) {
+ sprintf(*desc, "%s", sfx);
+ return;
+ }
sprintf(*desc, "(%s)",sfx);
}
free(sfx);
@@ -1776,10 +1909,17 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt)
}
}
else if (evt->sel_type.standard_type.event_type == 0x6f) {
+ int print_sensor = 1;
+ switch (ipmi_get_oem(intf)) {
+ case IPMI_OEM_SUPERMICRO:
+ case IPMI_OEM_SUPERMICRO_47488:
+ print_sensor = 0;
+ break;
+ }
/*
* Sensor-Specific Discrete
*/
- if (evt->sel_type.standard_type.sensor_type == 0xC &&
+ if (print_sensor && evt->sel_type.standard_type.sensor_type == 0xC && /*TODO*/
evt->sel_type.standard_type.sensor_num == 0 &&
(evt->sel_type.standard_type.event_data[0] & 0x30) == 0x20) {
/* break down memory ECC reporting if we can */
diff --git a/ipmitool/lib/ipmi_sensor.c b/ipmitool/lib/ipmi_sensor.c
index 42e8853..4ef5138 100644
--- a/ipmitool/lib/ipmi_sensor.c
+++ b/ipmitool/lib/ipmi_sensor.c
@@ -110,7 +110,8 @@ ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf,
struct ipmi_rq req;
static struct sensor_set_thresh_rq set_thresh_rq;
struct ipmi_rs *rsp;
- uint32_t save_addr = 0;
+ uint8_t bridged_request = 0;
+ uint32_t save_addr;
uint32_t save_channel;
memset(&set_thresh_rq, 0, sizeof (set_thresh_rq));
@@ -132,6 +133,7 @@ ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf,
return NULL;
if (BRIDGE_TO_SENSOR(intf, target, channel)) {
+ bridged_request = 1;
save_addr = intf->target_addr;
intf->target_addr = target;
save_channel = intf->target_channel;
@@ -145,7 +147,7 @@ ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf,
req.msg.data_len = sizeof (set_thresh_rq);
rsp = intf->sendrecv(intf, &req);
- if (save_addr) {
+ if (bridged_request) {
intf->target_addr = save_addr;
intf->target_channel = save_channel;
}
diff --git a/ipmitool/lib/ipmi_sol.c b/ipmitool/lib/ipmi_sol.c
index b17b60e..4b829fc 100644
--- a/ipmitool/lib/ipmi_sol.c
+++ b/ipmitool/lib/ipmi_sol.c
@@ -71,7 +71,7 @@
#define SOL_PARAMETER_SOL_PAYLOAD_CHANNEL 0x07
#define SOL_PARAMETER_SOL_PAYLOAD_PORT 0x08
-#define MAX_SOL_RETRY 6
+#define MAX_SOL_RETRY 6
const struct valstr sol_parameter_vals[] = {
{ SOL_PARAMETER_SET_IN_PROGRESS, "Set In Progress (0)" },
@@ -100,47 +100,45 @@ extern int verbose;
* ipmi_sol_payload_access
*/
int
-ipmi_sol_payload_access(struct ipmi_intf * intf,
- uint8_t channel,
- uint8_t userid,
- int enable)
+ipmi_sol_payload_access(struct ipmi_intf * intf, uint8_t channel,
+ uint8_t userid, int enable)
{
struct ipmi_rq req;
struct ipmi_rs *rsp;
+ int rc = (-1);
uint8_t data[6];
memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_APP;
- req.msg.cmd = IPMI_SET_USER_PAYLOAD_ACCESS;
- req.msg.data = data;
+ req.msg.netfn = IPMI_NETFN_APP;
+ req.msg.cmd = IPMI_SET_USER_PAYLOAD_ACCESS;
+ req.msg.data = data;
req.msg.data_len = 6;
memset(data, 0, 6);
-
- data[0] = channel & 0xf; /* channel */
- data[1] = userid & 0x3f; /* user id */
- if (!enable)
- data[1] |= 0x40; /* disable */
- data[2] = 0x02; /* payload 1 is SOL */
-
+ /* channel */
+ data[0] = channel & 0xf;
+ /* user id */
+ data[1] = userid & 0x3f;
+ if (!enable) {
+ /* disable */
+ data[1] |= 0x40;
+ }
+ /* payload 1 is SOL */
+ data[2] = 0x02;
rsp = intf->sendrecv(intf, &req);
-
- if (NULL != rsp) {
- switch (rsp->ccode) {
- case 0x00:
- return 0;
- default:
- lprintf(LOG_ERR, "Error %sabling SOL payload for user %d on channel %d: %s",
- enable ? "en" : "dis", userid, channel,
- val2str(rsp->ccode, completion_code_vals));
- break;
- }
- } else {
+ if (rsp == NULL) {
lprintf(LOG_ERR, "Error %sabling SOL payload for user %d on channel %d",
- enable ? "en" : "dis", userid, channel);
+ enable ? "en" : "dis", userid, channel);
+ rc = (-1);
+ } else if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Error %sabling SOL payload for user %d on channel %d: %s",
+ enable ? "en" : "dis", userid, channel,
+ val2str(rsp->ccode, completion_code_vals));
+ rc = (-1);
+ } else {
+ rc = 0;
}
-
- return -1;
+ return rc;
}
int
@@ -1931,29 +1929,21 @@ print_sol_set_usage(void)
-/*
- * ipmi_sol_main
- */
+/* ipmi_sol_main */
int
ipmi_sol_main(struct ipmi_intf * intf, int argc, char ** argv)
{
int retval = 0;
-
- /*
- * Help
- */
- if (!argc || !strncmp(argv[0], "help", 4))
+ if (!argc || !strncmp(argv[0], "help", 4)) {
+ /* Help */
print_sol_usage();
-
- /*
- * Info
- */
- else if (!strncmp(argv[0], "info", 4)) {
+ } else if (!strncmp(argv[0], "info", 4)) {
+ /* Info */
uint8_t channel;
-
- if (argc == 1)
- channel = 0x0E; /* Ask about the current channel */
- else if (argc == 2) {
+ if (argc == 1) {
+ /* Ask about the current channel */
+ channel = 0x0E;
+ } else if (argc == 2) {
if (is_ipmi_channel_num(argv[1], &channel) != 0) {
return (-1);
}
@@ -1961,110 +1951,71 @@ ipmi_sol_main(struct ipmi_intf * intf, int argc, char ** argv)
print_sol_usage();
return -1;
}
-
retval = ipmi_print_sol_info(intf, channel);
- }
-
- /*
- * Payload enable or disable
- */
- else if (!strncmp(argv[0], "payload", 7)) {
+ } else if (!strncmp(argv[0], "payload", 7)) {
+ /* Payload enable or disable */
uint8_t channel = 0xe;
uint8_t userid = 1;
int enable = -1;
-
- if (argc == 1 || argc > 4)
- {
+ if (argc == 1 || argc > 4) {
print_sol_usage();
return -1;
}
-
- if (argc == 1 || argc > 4)
- {
+ if (argc == 1 || argc > 4) {
print_sol_usage();
return -1;
}
-
if (argc >= 3) {
if (is_ipmi_channel_num(argv[2], &channel) != 0) {
return (-1);
}
}
- if (argc == 4)
- {
+ if (argc == 4) {
if (is_ipmi_user_id(argv[3], &userid) != 0) {
return (-1);
}
}
-
- if (!strncmp(argv[1], "enable", 6))
- {
+ if (!strncmp(argv[1], "enable", 6)) {
enable = 1;
- }
- else if (!strncmp(argv[1], "disable", 7))
- {
+ } else if (!strncmp(argv[1], "disable", 7)) {
enable = 0;
- }
- else if (!strncmp(argv[1], "status", 6))
- {
+ } else if (!strncmp(argv[1], "status", 6)) {
return ipmi_sol_payload_access_status(intf, channel, userid);
- }
- else
- {
+ } else {
print_sol_usage();
return -1;
}
-
retval = ipmi_sol_payload_access(intf, channel, userid, enable);
- }
-
-
- /*
- * Set a parameter value
- */
- else if (!strncmp(argv[0], "set", 3)) {
+ } else if (!strncmp(argv[0], "set", 3)) {
+ /* Set a parameter value */
uint8_t channel = 0xe;
uint8_t guard = 1;
-
- if (argc == 3)
- {
+ if (argc == 3) {
channel = 0xe;
- }
- else if (argc == 4)
- {
- if (!strncmp(argv[3], "noguard", 7))
+ } else if (argc == 4) {
+ if (!strncmp(argv[3], "noguard", 7)) {
guard = 0;
- else {
+ } else {
if (is_ipmi_channel_num(argv[3], &channel) != 0) {
return (-1);
}
}
- }
- else if (argc == 5)
- {
+ } else if (argc == 5) {
if (is_ipmi_channel_num(argv[3], &channel) != 0) {
return (-1);
}
- if (!strncmp(argv[4], "noguard", 7))
+ if (!strncmp(argv[4], "noguard", 7)) {
guard = 0;
- }
- else
- {
+ }
+ } else {
print_sol_set_usage();
return -1;
}
-
retval = ipmi_sol_set_param(intf, channel, argv[1], argv[2], guard);
- }
-
-
- /*
- * Activate
- */
- else if (!strncmp(argv[0], "activate", 8)) {
+ } else if (!strncmp(argv[0], "activate", 8)) {
+ /* Activate */
int i;
uint8_t instance = 1;
-
for (i = 1; i < argc; i++) {
if (!strncmp(argv[i], "usesolkeepalive", 15)) {
_use_sol_for_keepalive = 1;
@@ -2082,20 +2033,16 @@ ipmi_sol_main(struct ipmi_intf * intf, int argc, char ** argv)
}
}
retval = ipmi_sol_activate(intf, 0, 0, instance);
- }
-
-
- /*
- * Dectivate
- */
- else if (!strncmp(argv[0], "deactivate", 10)) {
+ } else if (!strncmp(argv[0], "deactivate", 10)) {
+ /* Dectivate */
int i;
uint8_t instance = 1;
-
for (i = 1; i < argc; i++) {
if (!strncmp(argv[i], "instance=", 9)) {
if (str2uchar(argv[i] + 9, &instance) != 0) {
- lprintf(LOG_ERR, "Given instance '%s' is invalid.", argv[i] + 9);
+ lprintf(LOG_ERR,
+ "Given instance '%s' is invalid.",
+ argv[i] + 9);
print_sol_usage();
return -1;
}
@@ -2105,66 +2052,58 @@ ipmi_sol_main(struct ipmi_intf * intf, int argc, char ** argv)
}
}
retval = ipmi_sol_deactivate(intf, instance);
- }
-
- /*
- * SOL loop test: Activate and then Dectivate
- */
- else if (!strncmp(argv[0], "looptest", 8))
- {
+ } else if (!strncmp(argv[0], "looptest", 8)) {
+ /* SOL loop test: Activate and then Dectivate */
int cnt = 200;
int interval = 100; /* Unit is: ms */
- uint8_t instance;
-
- if (argc > 4)
- {
+ uint8_t instance = 1;
+ if (argc > 4) {
print_sol_usage();
return -1;
}
- if (argc != 1) /* at least 2 */
- {
+ if (argc != 1) {
+ /* at least 2 */
if (str2int(argv[1], &cnt) != 0) {
lprintf(LOG_ERR, "Given cnt '%s' is invalid.",
argv[1]);
return (-1);
}
- if(cnt <= 0) cnt = 200;
+ if (cnt <= 0) {
+ cnt = 200;
+ }
}
- if (argc >= 3)
- {
+ if (argc >= 3) {
if (str2int(argv[2], &interval) != 0) {
lprintf(LOG_ERR, "Given interval '%s' is invalid.",
argv[2]);
return (-1);
}
- if(interval < 0) interval = 0;
+ if (interval < 0) {
+ interval = 0;
+ }
}
if (argc >= 4) {
if (str2uchar(argv[3], &instance) != 0) {
- lprintf(LOG_ERR, "Given instance '%s' is invalid.", argv[3]);
+ lprintf(LOG_ERR, "Given instance '%s' is invalid.",
+ argv[3]);
print_sol_usage();
return -1;
}
}
- while (cnt > 0)
- {
+ while (cnt > 0) {
printf("remain loop test counter: %d\n", cnt);
retval = ipmi_sol_activate(intf, 1, interval, instance);
- if (retval)
- {
- printf("SOL looptest failed: %d\n", retval);
+ if (retval) {
+ printf("SOL looptest failed: %d\n",
+ retval);
break;
}
cnt -= 1;
}
- }
-
- else
- {
+ } else {
print_sol_usage();
retval = -1;
}
-
return retval;
}
diff --git a/ipmitool/lib/ipmi_tsol.c b/ipmitool/lib/ipmi_tsol.c
index be53236..94ea284 100644
--- a/ipmitool/lib/ipmi_tsol.c
+++ b/ipmitool/lib/ipmi_tsol.c
@@ -381,7 +381,7 @@ int
ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv)
{
struct pollfd fds_wait[3], fds_data_wait[3], *fds;
- struct sockaddr_in sin, myaddr;
+ struct sockaddr_in sin, myaddr, *sa_in;
socklen_t mylen;
char *recvip = NULL;
char out_buff[IPMI_BUF_SIZE * 8], in_buff[IPMI_BUF_SIZE];
@@ -398,8 +398,11 @@ ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv)
}
for (i = 0; i<argc; i++) {
- if (sscanf(argv[i], "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) == 4)
- recvip = strdup(argv[i]);
+ if (sscanf(argv[i], "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) == 4) {
+ /* not free'd ...*/
+ /* recvip = strdup(argv[i]); */
+ recvip = argv[i];
+ }
else if (sscanf(argv[i], "port=%d", &ip1) == 1)
port = ip1;
else if (sscanf(argv[i], "rows=%d", &ip1) == 1)
@@ -427,8 +430,9 @@ ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv)
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
+ sa_in = (struct sockaddr_in *)&intf->session->addr;
result = inet_pton(AF_INET, (const char *)intf->session->hostname,
- &intf->session->addr.sin_addr);
+ &sa_in->sin_addr);
if (result <= 0) {
struct hostent *host = gethostbyname((const char *)intf->session->hostname);
@@ -444,8 +448,8 @@ ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv)
(host->h_addrtype == AF_INET6) ? "IPv6" : "Unknown");
return (-1);
}
- intf->session->addr.sin_family = host->h_addrtype;
- memcpy(&intf->session->addr.sin_addr, host->h_addr, host->h_length);
+ sa_in->sin_family = host->h_addrtype;
+ memcpy(&sa_in->sin_addr, host->h_addr, host->h_length);
}
fd_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
@@ -455,6 +459,7 @@ ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv)
}
if (-1 == bind(fd_socket, (struct sockaddr *)&sin, sizeof(sin))) {
lprintf(LOG_ERR, "Failed to bind socket.");
+ close(fd_socket);
return -1;
}
diff --git a/ipmitool/src/plugins/Makefile.am b/ipmitool/src/plugins/Makefile.am
index 9d5c2c2..19b5f11 100644
--- a/ipmitool/src/plugins/Makefile.am
+++ b/ipmitool/src/plugins/Makefile.am
@@ -32,8 +32,8 @@ MAINTAINERCLEANFILES = Makefile.in
INCLUDES = -I$(top_srcdir)/include
-SUBDIRS = @INTF_LAN@ @INTF_LANPLUS@ @INTF_OPEN@ @INTF_LIPMI@ @INTF_IMB@ @INTF_BMC@ @INTF_FREE@ @INTF_SERIAL@
-DIST_SUBDIRS = lan lanplus open lipmi imb bmc free serial
+SUBDIRS = @INTF_LAN@ @INTF_LANPLUS@ @INTF_OPEN@ @INTF_LIPMI@ @INTF_IMB@ @INTF_BMC@ @INTF_FREE@ @INTF_SERIAL@ @INTF_DUMMY@
+DIST_SUBDIRS = lan lanplus open lipmi imb bmc free serial dummy
noinst_LTLIBRARIES = libintf.la
libintf_la_SOURCES = ipmi_intf.c
diff --git a/ipmitool/src/plugins/dummy/Makefile.am b/ipmitool/src/plugins/dummy/Makefile.am
new file mode 100644
index 0000000..8a53bbe
--- /dev/null
+++ b/ipmitool/src/plugins/dummy/Makefile.am
@@ -0,0 +1,8 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = -I$(top_srcdir)/include
+
+EXTRA_LTLIBRARIES = libintf_dummy.la
+noinst_LTLIBRARIES = @INTF_DUMMY_LIB@
+libintf_dummy_la_LIBADD = $(top_builddir)/lib/libipmitool.la
+libintf_dummy_la_SOURCES = dummy.c
diff --git a/ipmitool/src/plugins/dummy/dummy.c b/ipmitool/src/plugins/dummy/dummy.c
new file mode 100644
index 0000000..eb2d086
--- /dev/null
+++ b/ipmitool/src/plugins/dummy/dummy.c
@@ -0,0 +1,286 @@
+/* Copyright (c) 2013 Zdenek Styblik, All Rights 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 Zdenek Styblik 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.
+ * Zdenek Styblik 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
+ * Zdenek Styblik 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 Zdenek Styblik HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_intf.h>
+#include <ipmitool/helper.h>
+#include <ipmitool/log.h>
+
+#include "dummy.h"
+
+#if defined(HAVE_CONFIG_H)
+# include <config.h>
+#endif
+
+extern int verbose;
+
+/* data_read - read data from socket
+ *
+ * @data_ptr - pointer to memory where to store read data
+ * @data_len - how much to read from socket
+ *
+ * return 0 on success, otherwise (-1)
+ */
+int
+data_read(int fd, void *data_ptr, int data_len)
+{
+ int rc = 0;
+ int data_read = 0;
+ int data_total = 0;
+ int try = 1;
+ int errno_save = 0;
+ if (data_len < 0) {
+ return (-1);
+ }
+ while (data_total < data_len && try < 4) {
+ errno = 0;
+ /* TODO - add poll() */
+ data_read = read(fd, data_ptr, data_len);
+ errno_save = errno;
+ if (data_read > 0) {
+ data_total+= data_read;
+ }
+ if (errno_save != 0) {
+ if (errno_save == EINTR || errno_save == EAGAIN) {
+ try++;
+ sleep(2);
+ continue;
+ } else {
+ errno = errno_save;
+ perror("dummy failed on read(): ");
+ rc = (-1);
+ break;
+ }
+ }
+ }
+ if (try > 3 && data_total != data_len) {
+ rc = (-1);
+ }
+ return rc;
+}
+
+/* data_write - write data to the socket
+ *
+ * @data_ptr - ptr to data to send
+ * @data_len - how long is the data to send
+ *
+ * returns 0 on success, otherwise (-1)
+ */
+int
+data_write(int fd, void *data_ptr, int data_len)
+{
+ int rc = 0;
+ int data_written = 0;
+ int data_total = 0;
+ int try = 1;
+ int errno_save = 0;
+ if (data_len < 0) {
+ return (-1);
+ }
+ while (data_total < data_len && try < 4) {
+ errno = 0;
+ /* TODO - add poll() */
+ data_written = write(fd, data_ptr, data_len);
+ errno_save = errno;
+ if (data_read > 0) {
+ data_total+= data_written;
+ }
+ if (errno_save != 0) {
+ if (errno_save == EINTR || errno_save == EAGAIN) {
+ try++;
+ sleep(2);
+ continue;
+ } else {
+ errno = errno_save;
+ perror("dummy failed on read(): ");
+ rc = (-1);
+ break;
+ }
+ }
+ }
+ if (try > 3 && data_total != data_len) {
+ rc = (-1);
+ }
+ return rc;
+}
+
+/* ipmi_dummyipmi_close - send "BYE" and close socket
+ *
+ * @intf - ptr to initialize ipmi_intf struct
+ *
+ * returns void
+ */
+static void
+ipmi_dummyipmi_close(struct ipmi_intf *intf)
+{
+ struct dummy_rq req;
+ int data_total = 0;
+ int data_written = 0;
+ int try = 0;
+ if (intf->fd < 0) {
+ return;
+ }
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = 0x3f;
+ req.msg.cmd = 0xff;
+ if (data_write(intf->fd, &req, sizeof(req)) != 0) {
+ lprintf(LOG_ERR, "dummy failed to send 'BYE'");
+ }
+ close(intf->fd);
+ intf->fd = (-1);
+ intf->opened = 0;
+}
+
+/* ipmi_dummyipmi_open - open socket and prepare ipmi_intf struct
+ *
+ * @intf - ptr to ipmi_inf struct
+ *
+ * returns 0 on success, (-1) on error
+ */
+static int
+ipmi_dummyipmi_open(struct ipmi_intf *intf)
+{
+ struct sockaddr_un address;
+ int len;
+ int rc;
+
+ if (intf->opened == 1) {
+ return intf->fd;
+ }
+ intf->fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (intf->fd == (-1)) {
+ lprintf(LOG_ERR, "dummy failed on socket()");
+ return (-1);
+ }
+ address.sun_family = AF_UNIX;
+ strcpy(address.sun_path, DUMMY_SOCKET_PATH);
+ len = sizeof(address);
+ rc = connect(intf->fd, (struct sockaddr *)&address, len);
+ if (rc != 0) {
+ perror("dummy failed on connect(): ");
+ return (-1);
+ }
+ intf->opened = 1;
+ return intf->fd;
+}
+
+/* ipmi_dummyipmi_send_cmd - send IPMI payload and await reply
+ *
+ * @intf - ptr to initialized ipmi_intf struct
+ * @req - ptr to ipmi_rq struct to send
+ *
+ * return pointer to struct ipmi_rs OR NULL on error
+ */
+static struct ipmi_rs*
+ipmi_dummyipmi_send_cmd(struct ipmi_intf *intf, struct ipmi_rq *req)
+{
+ static struct ipmi_rs rsp;
+ struct dummy_rq req_dummy;
+ struct dummy_rs rsp_dummy;
+ if (intf == NULL || intf->fd < 0 || intf->opened != 1) {
+ lprintf(LOG_ERR, "dummy failed on intf check.");
+ return NULL;
+ }
+
+ memset(&req_dummy, 0, sizeof(req_dummy));
+ req_dummy.msg.netfn = req->msg.netfn;
+ req_dummy.msg.lun = req->msg.lun;
+ req_dummy.msg.cmd = req->msg.cmd;
+ req_dummy.msg.target_cmd = req->msg.target_cmd;
+ req_dummy.msg.data_len = req->msg.data_len;
+ req_dummy.msg.data = req->msg.data;
+ if (verbose) {
+ lprintf(LOG_NOTICE, ">>> IPMI req");
+ lprintf(LOG_NOTICE, "msg.data_len: %i",
+ req_dummy.msg.data_len);
+ lprintf(LOG_NOTICE, "msg.netfn: %x", req_dummy.msg.netfn);
+ lprintf(LOG_NOTICE, "msg.cmd: %x", req_dummy.msg.cmd);
+ lprintf(LOG_NOTICE, "msg.target_cmd: %x",
+ req_dummy.msg.target_cmd);
+ lprintf(LOG_NOTICE, "msg.lun: %x", req_dummy.msg.lun);
+ lprintf(LOG_NOTICE, ">>>");
+ }
+ if (data_write(intf->fd, &req_dummy,
+ sizeof(struct dummy_rq)) != 0) {
+ return NULL;
+ }
+ if (req->msg.data_len > 0) {
+ if (data_write(intf->fd, (uint8_t *)(req->msg.data),
+ req_dummy.msg.data_len) != 0) {
+ return NULL;
+ }
+ }
+
+ memset(&rsp_dummy, 0, sizeof(rsp_dummy));
+ if (data_read(intf->fd, &rsp_dummy, sizeof(struct dummy_rs)) != 0) {
+ return NULL;
+ }
+ if (rsp_dummy.data_len > 0) {
+ if (data_read(intf->fd, (uint8_t *)&rsp.data,
+ rsp_dummy.data_len) != 0) {
+ return NULL;
+ }
+ }
+ rsp.ccode = rsp_dummy.ccode;
+ rsp.data_len = rsp_dummy.data_len;
+ rsp.msg.netfn = rsp_dummy.msg.netfn;
+ rsp.msg.cmd = rsp_dummy.msg.cmd;
+ rsp.msg.seq = rsp_dummy.msg.seq;
+ rsp.msg.lun = rsp_dummy.msg.lun;
+ if (verbose) {
+ lprintf(LOG_NOTICE, "<<< IPMI rsp");
+ lprintf(LOG_NOTICE, "ccode: %x", rsp.ccode);
+ lprintf(LOG_NOTICE, "data_len: %i", rsp.data_len);
+ lprintf(LOG_NOTICE, "msg.netfn: %x", rsp.msg.netfn);
+ lprintf(LOG_NOTICE, "msg.cmd: %x", rsp.msg.cmd);
+ lprintf(LOG_NOTICE, "msg.seq: %x", rsp.msg.seq);
+ lprintf(LOG_NOTICE, "msg.lun: %x", rsp.msg.lun);
+ lprintf(LOG_NOTICE, "<<<");
+ }
+ return &rsp;
+}
+
+struct ipmi_intf ipmi_dummy_intf = {
+ name: "dummy",
+ desc: "Linux DummyIPMI Interface",
+ open: ipmi_dummyipmi_open,
+ close: ipmi_dummyipmi_close,
+ sendrecv: ipmi_dummyipmi_send_cmd,
+ my_addr: IPMI_BMC_SLAVE_ADDR,
+ target_addr: IPMI_BMC_SLAVE_ADDR,
+};
diff --git a/ipmitool/src/plugins/dummy/dummy.h b/ipmitool/src/plugins/dummy/dummy.h
new file mode 100644
index 0000000..dac9caa
--- /dev/null
+++ b/ipmitool/src/plugins/dummy/dummy.h
@@ -0,0 +1,30 @@
+#ifndef IPMI_DUMMYIPMI_H
+# define IPMI_DUMMYIPMI_H
+
+# define DUMMY_SOCKET_PATH "/tmp/.ipmi_dummy"
+
+struct dummy_rq {
+ struct {
+ uint8_t netfn;
+ uint8_t lun;
+ uint8_t cmd;
+ uint8_t target_cmd;
+ uint16_t data_len;
+ uint8_t *data;
+ } msg;
+};
+
+struct dummy_rs {
+ struct {
+ uint8_t netfn;
+ uint8_t cmd;
+ uint8_t seq;
+ uint8_t lun;
+ } msg;
+
+ uint8_t ccode;
+ int data_len;
+ uint8_t *data;
+};
+
+#endif
diff --git a/ipmitool/src/plugins/ipmi_intf.c b/ipmitool/src/plugins/ipmi_intf.c
index d0c483a..48e2b61 100644
--- a/ipmitool/src/plugins/ipmi_intf.c
+++ b/ipmitool/src/plugins/ipmi_intf.c
@@ -36,6 +36,18 @@
#if defined(HAVE_CONFIG_H)
# include <config.h>
#endif
+
+#if defined(IPMI_INTF_LAN) || defined (IPMI_INTF_LANPLUS)
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <ifaddrs.h>
+#include <unistd.h>
+#include <netdb.h>
+#endif
+
+
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_sdr.h>
@@ -66,6 +78,9 @@ extern struct ipmi_intf ipmi_free_intf;
extern struct ipmi_intf ipmi_serial_term_intf;
extern struct ipmi_intf ipmi_serial_bm_intf;
#endif
+#ifdef IPMI_INTF_DUMMY
+extern struct ipmi_intf ipmi_dummy_intf;
+#endif
struct ipmi_intf * ipmi_intf_table[] = {
#ifdef IPMI_INTF_OPEN
@@ -93,6 +108,9 @@ struct ipmi_intf * ipmi_intf_table[] = {
&ipmi_serial_term_intf,
&ipmi_serial_bm_intf,
#endif
+#ifdef IPMI_INTF_DUMMY
+ &ipmi_dummy_intf,
+#endif
NULL
};
@@ -315,3 +333,167 @@ ipmi_cleanup(struct ipmi_intf * intf)
{
ipmi_sdr_list_empty(intf);
}
+
+#if defined(IPMI_INTF_LAN) || defined (IPMI_INTF_LANPLUS)
+int
+ipmi_intf_socket_connect(struct ipmi_intf * intf)
+{
+ struct ipmi_session *session;
+
+ struct sockaddr_storage addr;
+ struct addrinfo hints;
+ struct addrinfo *rp0 = NULL, *rp;
+ char service[NI_MAXSERV];
+ int rc;
+
+ if (!intf || intf->session == NULL) {
+ return -1;
+ }
+
+ session = intf->session;
+
+ if (session->hostname == NULL || strlen((const char *)session->hostname) == 0) {
+ lprintf(LOG_ERR, "No hostname specified!");
+ return -1;
+ }
+
+ /* open port to BMC */
+ memset(&addr, 0, sizeof(addr));
+
+ sprintf(service, "%d", session->port);
+ /* Obtain address(es) matching host/port */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
+ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
+ hints.ai_flags = 0; /* use AI_NUMERICSERV for no name resolution */
+ hints.ai_protocol = IPPROTO_UDP; /* */
+
+ if (getaddrinfo(session->hostname, service, &hints, &rp0) != 0) {
+ lprintf(LOG_ERR, "Address lookup for %s failed",
+ session->hostname);
+ return -1;
+ }
+
+ /* getaddrinfo() returns a list of address structures.
+ * Try each address until we successfully connect(2).
+ * If socket(2) (or connect(2)) fails, we (close the socket
+ * and) try the next address.
+ */
+
+ session->ai_family = AF_UNSPEC;
+ for (rp = rp0; rp != NULL; rp = rp->ai_next) {
+ /* We are only interested in IPv4 and IPv6 */
+ if ((rp->ai_family != AF_INET6) && (rp->ai_family != AF_INET)) {
+ continue;
+ }
+
+ intf->fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+ if (intf->fd == -1) {
+ continue;
+ }
+
+ if (rp->ai_family == AF_INET) {
+ if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
+ memcpy(&session->addr, rp->ai_addr, rp->ai_addrlen);
+ session->addrlen = rp->ai_addrlen;
+ session->ai_family = rp->ai_family;
+ break; /* Success */
+ }
+ } else if (rp->ai_family == AF_INET6) {
+ struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)rp->ai_addr;
+ char hbuf[NI_MAXHOST];
+ socklen_t len;
+
+ /* The scope was specified on the command line e.g. with -H FE80::219:99FF:FEA0:BD95%eth0 */
+ if (addr6->sin6_scope_id != 0) {
+ len = sizeof(struct sockaddr_in6);
+ if (getnameinfo((struct sockaddr *)addr6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) {
+ lprintf(LOG_DEBUG, "Trying address: %s scope=%d",
+ hbuf,
+ addr6->sin6_scope_id);
+ }
+ if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
+ memcpy(&session->addr, rp->ai_addr, rp->ai_addrlen);
+ session->addrlen = rp->ai_addrlen;
+ session->ai_family = rp->ai_family;
+ break; /* Success */
+ }
+ } else {
+ /* No scope specified, try to get this from the list of interfaces */
+ struct ifaddrs *ifaddrs = NULL;
+ struct ifaddrs *ifa = NULL;
+
+ if (getifaddrs(&ifaddrs) < 0) {
+ lprintf(LOG_ERR, "Interface address lookup for %s failed",
+ session->hostname);
+ break;
+ }
+
+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr == NULL) {
+ continue;
+ }
+
+ if (ifa->ifa_addr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *tmp6 = (struct sockaddr_in6 *)ifa->ifa_addr;
+
+ /* Skip unwanted addresses */
+ if (IN6_IS_ADDR_MULTICAST(&tmp6->sin6_addr)) {
+ continue;
+ }
+ if (IN6_IS_ADDR_LOOPBACK(&tmp6->sin6_addr)) {
+ continue;
+ }
+ len = sizeof(struct sockaddr_in6);
+ if ( getnameinfo((struct sockaddr *)tmp6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) {
+ lprintf(LOG_DEBUG, "Testing %s interface address: %s scope=%d",
+ ifa->ifa_name != NULL ? ifa->ifa_name : "???",
+ hbuf,
+ tmp6->sin6_scope_id);
+ }
+
+ if (tmp6->sin6_scope_id != 0) {
+ addr6->sin6_scope_id = tmp6->sin6_scope_id;
+ } else {
+ /*
+ * No scope information in interface address information
+ * On some OS'es, getifaddrs() is returning out the 'kernel' representation
+ * of scoped addresses which stores the scope in the 3rd and 4th
+ * byte. See also this page:
+ * http://www.freebsd.org/doc/en/books/developers-handbook/ipv6.html
+ */
+ if (IN6_IS_ADDR_LINKLOCAL(&tmp6->sin6_addr)
+ && (tmp6->sin6_addr.s6_addr16[1] != 0)) {
+ addr6->sin6_scope_id = ntohs(tmp6->sin6_addr.s6_addr16[1]);
+ }
+ }
+
+ /* OK, now try to connect with the scope id from this interface address */
+ if (addr6->sin6_scope_id != 0) {
+ if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
+ memcpy(&session->addr, rp->ai_addr, rp->ai_addrlen);
+ session->addrlen = rp->ai_addrlen;
+ session->ai_family = rp->ai_family;
+ lprintf(LOG_DEBUG, "Successful connected on %s interface with scope id %d", ifa->ifa_name, tmp6->sin6_scope_id);
+ break; /* Success */
+ }
+ }
+ }
+ }
+ freeifaddrs(ifaddrs);
+ }
+ }
+ if (session->ai_family != AF_UNSPEC) {
+ break;
+ }
+ close(intf->fd);
+ intf->fd = -1;
+ }
+
+ /* No longer needed */
+ freeaddrinfo(rp0);
+
+ return ((intf->fd != -1) ? 0 : -1);
+}
+#endif
+
diff --git a/ipmitool/src/plugins/lan/lan.c b/ipmitool/src/plugins/lan/lan.c
index e088479..fc90000 100644
--- a/ipmitool/src/plugins/lan/lan.c
+++ b/ipmitool/src/plugins/lan/lan.c
@@ -2032,44 +2032,14 @@ ipmi_lan_open(struct ipmi_intf * intf)
intf->session->sol_data.sequence_number = 1;
- /* open port to BMC */
- memset(&s->addr, 0, sizeof(struct sockaddr_in));
- s->addr.sin_family = AF_INET;
- s->addr.sin_port = htons(s->port);
-
- rc = inet_pton(AF_INET, (const char *)s->hostname, &s->addr.sin_addr);
- if (rc <= 0) {
- struct hostent *host = gethostbyname((const char *)s->hostname);
- if (host == NULL) {
- lprintf(LOG_ERR, "Address lookup for %s failed",
- s->hostname);
- return -1;
- }
- if (host->h_addrtype != AF_INET) {
- lprintf(LOG_ERR,
- "Address lookup for %s failed. Got %s, expected IPv4 address.",
- s->hostname,
- (host->h_addrtype == AF_INET6) ? "IPv6" : "Unknown");
- return (-1);
- }
- s->addr.sin_family = host->h_addrtype;
- memcpy(&s->addr.sin_addr, host->h_addr, host->h_length);
- }
-
- lprintf(LOG_DEBUG, "IPMI LAN host %s port %d",
- s->hostname, ntohs(s->addr.sin_port));
-
- intf->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (intf->fd < 0) {
- lperror(LOG_ERR, "Socket failed");
+ if (ipmi_intf_socket_connect (intf) == -1) {
+ lprintf(LOG_ERR, "Could not open socket!");
return -1;
}
- /* connect to UDP socket so we get async errors */
- rc = connect(intf->fd, (struct sockaddr *)&s->addr,
- sizeof(struct sockaddr_in));
- if (rc < 0) {
- lperror(LOG_ERR, "Connect failed");
+ if (intf->fd < 0) {
+ lperror(LOG_ERR, "Connect to %s failed",
+ s->hostname);
intf->close(intf);
return -1;
}
diff --git a/ipmitool/src/plugins/lanplus/lanplus.c b/ipmitool/src/plugins/lanplus/lanplus.c
index acf2410..17d42a4 100644
--- a/ipmitool/src/plugins/lanplus/lanplus.c
+++ b/ipmitool/src/plugins/lanplus/lanplus.c
@@ -84,14 +84,14 @@ static struct ipmi_rs * ipmi_lanplus_send_ipmi_cmd(struct ipmi_intf * intf, stru
static struct ipmi_rs * ipmi_lanplus_send_payload(struct ipmi_intf * intf,
struct ipmi_v2_payload * payload);
static void getIpmiPayloadWireRep(
- struct ipmi_intf * intf,
- struct ipmi_v2_payload * payload, /* in */
+ struct ipmi_intf * intf,
+ struct ipmi_v2_payload * payload, /* in */
uint8_t * out,
struct ipmi_rq * req,
uint8_t rq_seq,
- uint8_t curr_seq);
+ uint8_t curr_seq);
static void getSolPayloadWireRep(
- struct ipmi_intf * intf,
+ struct ipmi_intf * intf,
uint8_t * msg,
struct ipmi_v2_payload * payload);
static void read_open_session_response(struct ipmi_rs * rsp, int offset);
@@ -113,7 +113,7 @@ static void ack_sol_packet(
struct ipmi_intf * intf,
struct ipmi_rs * rsp);
-static uint8_t bridgePossible = 0;
+static uint8_t bridgePossible = 0;
struct ipmi_intf ipmi_lanplus_intf = {
name: "lanplus",
@@ -2174,7 +2174,8 @@ ipmi_lanplus_send_payload(
else if (payload->payload_type == IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST)
{
lprintf(LOG_DEBUG, ">> SENDING AN OPEN SESSION REQUEST\n");
- assert(session->v2_data.session_state == LANPLUS_STATE_PRESESSION);
+ assert(session->v2_data.session_state == LANPLUS_STATE_PRESESSION
+ || session->v2_data.session_state == LANPLUS_STATE_OPEN_SESSION_SENT);
ipmi_lanplus_build_v2x_msg(intf, /* in */
payload, /* in */
@@ -2858,7 +2859,10 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
free(msg);
msg = NULL;
-
+ if (!rsp) {
+ lprintf(LOG_WARNING, "Error sending open session message.");
+ return -1;
+ }
if (verbose)
lanplus_dump_open_session_response(rsp);
@@ -3334,7 +3338,6 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
{
int rc;
struct get_channel_auth_cap_rsp auth_cap;
- struct sockaddr_in addr;
struct ipmi_session *session;
if (!intf || !intf->session)
@@ -3373,46 +3376,14 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
/* Kg is set in ipmi_intf */
//memset(session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE);
-
- /* open port to BMC */
- memset(&addr, 0, sizeof(struct sockaddr_in));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(session->port);
-
- rc = inet_pton(AF_INET, (const char *)session->hostname, &addr.sin_addr);
- if (rc <= 0) {
- struct hostent *host = gethostbyname((const char *)session->hostname);
- if (host == NULL) {
- lprintf(LOG_ERR, "Address lookup for %s failed",
- session->hostname);
- return -1;
- }
- if (host->h_addrtype != AF_INET) {
- lprintf(LOG_ERR,
- "Address lookup for %s failed. Got %s, expected IPv4 address.",
- session->hostname,
- (host->h_addrtype == AF_INET6) ? "IPv6" : "Unknown");
- return (-1);
- }
- addr.sin_family = host->h_addrtype;
- memcpy(&addr.sin_addr, host->h_addr, host->h_length);
- }
-
- lprintf(LOG_DEBUG, "IPMI LAN host %s port %d",
- session->hostname, ntohs(addr.sin_port));
-
- intf->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (intf->fd < 0) {
- lperror(LOG_ERR, "Socket failed");
+ if (ipmi_intf_socket_connect (intf) == -1) {
+ lprintf(LOG_ERR, "Could not open socket!");
return -1;
}
-
- /* connect to UDP socket so we get async errors */
- rc = connect(intf->fd,
- (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
- if (rc < 0) {
- lperror(LOG_ERR, "Connect failed");
+ if (intf->fd < 0) {
+ lperror(LOG_ERR, "Connect to %s failed",
+ session->hostname);
intf->close(intf);
return -1;
}
diff --git a/ipmitool/src/plugins/open/open.c b/ipmitool/src/plugins/open/open.c
index 5567992..0fd8c9e 100644
--- a/ipmitool/src/plugins/open/open.c
+++ b/ipmitool/src/plugins/open/open.c
@@ -187,8 +187,9 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
/* use IPMB address if needed */
ipmb_addr.slave_addr = intf->target_addr;
ipmb_addr.lun = req->msg.lun;
- lprintf(LOG_DEBUG, "Sending request to "
+ lprintf(LOG_DEBUG, "Sending request 0x%x to "
"IPMB target @ 0x%x:0x%x (from 0x%x)",
+ req->msg.cmd,
intf->target_addr,intf->target_channel, intf->my_addr);
if(intf->transit_addr != 0 && intf->transit_addr != intf->my_addr) {
@@ -257,8 +258,8 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
_req.addr_len = sizeof(ipmb_addr);
} else {
/* otherwise use system interface */
- lprintf(LOG_DEBUG+2, "Sending request to "
- "System Interface");
+ lprintf(LOG_DEBUG+2, "Sending request 0x%x to "
+ "System Interface", req->msg.cmd);
bmc_addr.lun = req->msg.lun;
_req.addr = (unsigned char *) &bmc_addr;
_req.addr_len = sizeof(bmc_addr);
diff --git a/ipmitool/src/plugins/serial/serial_basic.c b/ipmitool/src/plugins/serial/serial_basic.c
index 55681ab..23c98b7 100644
--- a/ipmitool/src/plugins/serial/serial_basic.c
+++ b/ipmitool/src/plugins/serial/serial_basic.c
@@ -266,8 +266,14 @@ serial_bm_open(struct ipmi_intf * intf)
/* no flow control */
ti.c_cflag &= ~CRTSCTS;
- ti.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IUCLC | INPCK | ISTRIP
+ ti.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | INPCK | ISTRIP
| IXON | IXOFF | IXANY);
+#ifdef IUCLC
+ /* Only disable uppercase-to-lowercase mapping on input for
+ platforms supporting the flag. */
+ ti.c_iflag &= ~(IUCLC);
+#endif
+
ti.c_oflag &= ~(OPOST);
ti.c_lflag &= ~(ICANON | ISIG | ECHO | ECHONL | NOFLSH);
@@ -323,7 +329,13 @@ serial_bm_alloc_seq(void)
static int
serial_bm_flush(struct ipmi_intf * intf)
{
- return ioctl(intf->fd, TCFLSH, TCIOFLUSH);
+#if defined(TCFLSH)
+ return ioctl(intf->fd, TCFLSH, TCIOFLUSH);
+#elif defined(TIOCFLUSH)
+ return ioctl(intf->fd, TIOCFLUSH);
+#else
+# error "unsupported platform, missing flush support (TCFLSH/TIOCFLUSH)"
+#endif
}
/*
diff --git a/ipmitool/src/plugins/serial/serial_terminal.c b/ipmitool/src/plugins/serial/serial_terminal.c
index 10ed942..c82073e 100644
--- a/ipmitool/src/plugins/serial/serial_terminal.c
+++ b/ipmitool/src/plugins/serial/serial_terminal.c
@@ -211,8 +211,13 @@ ipmi_serial_term_open(struct ipmi_intf * intf)
/* no flow control */
ti.c_cflag &= ~CRTSCTS;
- ti.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IUCLC | INPCK | ISTRIP
+ ti.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | INPCK | ISTRIP
| IXON | IXOFF | IXANY);
+#ifdef IUCLC
+ /* Only disable uppercase-to-lowercase mapping on input for
+ platforms supporting the flag. */
+ ti.c_iflag &= ~(IUCLC);
+#endif
ti.c_oflag &= ~(OPOST);
ti.c_lflag &= ~(ICANON | ISIG | ECHO | ECHONL | NOFLSH);
@@ -337,7 +342,14 @@ serial_write_line(struct ipmi_intf * intf, const char *str)
static int
serial_flush(struct ipmi_intf * intf)
{
+#if defined(TCFLSH)
return ioctl(intf->fd, TCFLSH, TCIOFLUSH);
+#elif defined(TIOCFLUSH)
+ return ioctl(intf->fd, TIOCFLUSH);
+#else
+# error "unsupported platform, missing flush support (TCFLSH/TIOCFLUSH)"
+#endif
+
}
/*