From 01998a8ef322a0da741c1e929b0776387e6a4d48204c293bc1d112925b4c22a7 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Thu, 6 Mar 2014 15:12:31 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/systemsmanagement/ipmitool?expand=0&rev=26 --- ...it_head_31_01_2014_b0aad15d67007c74b.patch | 13828 ---------------- 1 file changed, 13828 deletions(-) delete mode 100644 ipmitool_update_to_git_head_31_01_2014_b0aad15d67007c74b.patch diff --git a/ipmitool_update_to_git_head_31_01_2014_b0aad15d67007c74b.patch b/ipmitool_update_to_git_head_31_01_2014_b0aad15d67007c74b.patch deleted file mode 100644 index 887e752..0000000 --- a/ipmitool_update_to_git_head_31_01_2014_b0aad15d67007c74b.patch +++ /dev/null @@ -1,13828 +0,0 @@ -diff --git a/ipmitool/AUTHORS b/ipmitool/AUTHORS -index 80ec56b..9589d87 100644 ---- a/ipmitool/AUTHORS -+++ b/ipmitool/AUTHORS -@@ -2,3 +2,4 @@ Duncan Laurie - Fredrik Öhrn - Jon Cassorla - Jeremy Ellington -+Petter Reinholdtsen -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 -+# Jordan Hargrave -+# -+# 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 - #include - -+/* 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++ - #include - #include -+#include - - #if HAVE_CONFIG_H - # include -@@ -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 - #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 - #include - #include -@@ -46,421 +45,259 @@ - #include - #include - --/****************************************************************************** --* 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, ¬Used); -- -- } -- -- -- 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, ¬Used); -- } -- -- 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, ¬_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, ¬_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 - #include -+#include - - #if HAVE_CONFIG_H -- #include -+# include - #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++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 - 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 - Copies all the components from a valid HPM.1"); -- lprintf(LOG_NOTICE," image 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 activate - Copy and activate the firmware using a valid HPM.1"); -- lprintf(LOG_NOTICE," image ."); -- 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 force - Copies all the components present in "); -- 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 \" command."); -- lprintf(LOG_NOTICE,"upgrade component x - Copy only component from the given "); -- 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 \" 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 - Get specified component properties from the target."); -- lprintf(LOG_NOTICE," Valid component : 0-7 "); -- lprintf(LOG_NOTICE," Properties 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 - 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 [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 \" 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 - Perform \"Comparison of the Active Copy\" action for all the"); -+ lprintf(LOG_NOTICE, -+" components present in the file."); -+ lprintf(LOG_NOTICE, -+"compare component x - Compare only component from the given "); -+ 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 - Get specified component properties from the target."); -+ lprintf(LOG_NOTICE, -+" Valid component : 0-7 "); -+ lprintf(LOG_NOTICE, -+" Properties 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 */ -- 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 force */ -- if (strcmp(argv[i],"force") == 0) -- { -- option &= ~(VERSIONCHECK_MODE); -- option &= ~(VIEW_MODE); -- option |= FORCE_MODE_ALL; -- } -- /* hpm upgrade component */ -- 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 */ -+ 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 force */ -+ if (strcmp(argv[i],"force") == 0) { -+ option |= FORCE_MODE; -+ } -+ /* hpm upgrade component */ -+ 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 [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; isession->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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "dummy.h" -+ -+#if defined(HAVE_CONFIG_H) -+# include -+#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 - #endif -+ -+#if defined(IPMI_INTF_LAN) || defined (IPMI_INTF_LANPLUS) -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#endif -+ -+ - #include - #include - #include -@@ -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 -+ - } - - /*