From f77f3e2455011a24f8bb7797f221a62a3d007145fb533e7de56f6c8711f14643 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Thu, 6 Mar 2014 15:11:33 +0000 Subject: [PATCH 1/3] - Update to latest git head and do not split up version 1.8.13.tar.bz2 tarball and patch to latest git HEAD. Reason is that all files in the repository got moved up one directory level by git commit: c18ec02f3304ce2a889a50e378f07a4168af3884 Date: Wed Feb 5 17:30:32 2014 Move all files one level up in the file hierarchy, to avoid the useless ipmitool directory. We want the latest git head asap, because otherwise additionally needed patches will never patch cleanly in mainline and our repo and would always need adjusting. I asked for a new version tag mainline. As soon this happened, the tarball name should again match with the exact mainline git tag. - Incorporate patch on request from Dell: fate#315996 OBS-URL: https://build.opensuse.org/package/show/systemsmanagement/ipmitool?expand=0&rev=25 --- ...tream-comments-to-289-add-whitespace.patch | 359 ++++++++++++++++++ ipmitool-1.8.13.tar.bz2 | 4 +- ipmitool.changes | 19 + ipmitool.spec | 4 +- 4 files changed, 382 insertions(+), 4 deletions(-) create mode 100644 0001-Incorporate-upstream-comments-to-289-add-whitespace.patch diff --git a/0001-Incorporate-upstream-comments-to-289-add-whitespace.patch b/0001-Incorporate-upstream-comments-to-289-add-whitespace.patch new file mode 100644 index 0000000..47a7211 --- /dev/null +++ b/0001-Incorporate-upstream-comments-to-289-add-whitespace.patch @@ -0,0 +1,359 @@ +From f48ce96e7fd0d2fe198845f0e2bd76f95d221fb3 Mon Sep 17 00:00:00 2001 +From: Charles Rose +Date: Thu, 12 Dec 2013 16:10:11 -0500 +Subject: [PATCH] Incorporate upstream comments to #289, add whitespace, other + cleanup + +--- + contrib/bmc-snmp-proxy | 130 +++++++++++++++++++++++++++++-------------------- + 1 file changed, 76 insertions(+), 54 deletions(-) + +diff --git a/contrib/bmc-snmp-proxy b/contrib/bmc-snmp-proxy +index 1704ef3..98479b9 100644 +--- a/contrib/bmc-snmp-proxy ++++ b/contrib/bmc-snmp-proxy +@@ -3,7 +3,7 @@ + # + # bmc-snmp-proxy: Set SNMP proxy to BMC (Baseboard Management Controller) + # +-# version: 0.6 ++# version: 0.62 + # + # Authors: Charles Rose + # Jordan Hargrave +@@ -20,9 +20,9 @@ + SYSCONF_DIR="/etc/sysconfig" + CONFIG="${SYSCONF_DIR}/bmc-snmp-proxy" + +-SNMPD_LOCAL_CONF_DIR="/etc/snmp/bmc" +-SNMPD_LOCAL_CONF="${SNMPD_LOCAL_CONF_DIR}/snmpd.local.conf" +-TRAPD_LOCAL_CONF="${SNMPD_LOCAL_CONF_DIR}/snmptrapd.local.conf" ++SNMPD_BMC_CONF_DIR="/etc/snmp/bmc" ++SNMPD_BMC_CONF="${SNMPD_BMC_CONF_DIR}/snmpd.local.conf" ++TRAPD_BMC_CONF="${SNMPD_BMC_CONF_DIR}/snmptrapd.local.conf" + + TRAPD_CONF="/etc/snmp/snmptrapd.conf" + +@@ -57,14 +57,16 @@ bmc_info_exists() + else + RETVAL=2 + fi ++ + return $RETVAL + } + + check_snmp() + { +- if [ ! -d /etc/snmp ] && [ ! -x /usr/sbin/snmpd ]; then ++ if [ ! -d /etc/snmp ] || [ ! -x /usr/sbin/snmpd ]; then + RETVAL=12 + fi ++ + return $RETVAL + } + +@@ -77,11 +79,12 @@ write_snmp_conf() + printf "###############################################\n" + printf "# Automatically created by %s #\n" "${SCRIPT_NAME}" + printf "###############################################\n" +- printf "view bmcview included %s 80\n" "${BMC_OID}" +- printf "com2sec -Cn bmc_ctx bmc_sec default bmc_cmty\n" +- printf "group bmc_grp v1 bmc_sec\n" +- printf "access bmc_grp bmc_ctx any noauth exact bmcview none none\n" +- printf "proxy -Cn bmc_ctx -v 1 %s\n" "${PROXY_TOKEN}" ++ printf "#view bmcview included %s 80\n" "${BMC_OID}" ++ printf "#com2sec -Cn bmc_ctx bmc_sec default bmc_cmty\n" ++ printf "#group bmc_grp v1 bmc_sec\n" ++ printf "#access bmc_grp bmc_ctx any noauth exact bmcview none none\n" ++ printf "#proxy -Cn bmc_ctx -v 1 %s\n" "${PROXY_TOKEN}" ++ printf "proxy -v 1 %s\n" "${PROXY_TOKEN}" + printf "###############################################\n" + } + +@@ -92,6 +95,7 @@ valid_ip() + + printf -- "%s" "${1}"| grep -Eq \ + "^${octet}\\.${octet}\\.${octet}\\.${octet}$" ++ + return $? + } + +@@ -112,37 +116,38 @@ set_snmp_proxy() + if check_vars; then + PROXY_TOKEN="-c ${BMC_COMMUNITY} ${BMC_IPv4} ${BMC_OID}" + +- if [ ! -d ${SNMPD_LOCAL_CONF_DIR} ] && \ +- mkdir ${SNMPD_LOCAL_CONF_DIR}; then +- write_snmp_conf > ${SNMPD_LOCAL_CONF} +- [ $? -ne 0 ] && RETVAL=4 ++ if [ -d ${SNMPD_BMC_CONF_DIR} ]; then ++ write_snmp_conf > ${SNMPD_BMC_CONF} || RETVAL=4 + fi + else + RETVAL=3 + fi + } + +- + set_snmpd_conf_path() + { +- for SYSCONF in ${SYSCONF_DIR}/snmp*d; ++ if [ ! -d ${SNMPD_BMC_CONF_DIR} ]; then ++ mkdir ${SNMPD_BMC_CONF_DIR} || RETVAL=7 ++ fi ++ ++ # We need SNMPCONFPATH set for both snmpd and snmptrapd ++ for sysconf in ${SYSCONF_DIR}/snmp*d; + do +- if grep -q "${SNMPD_LOCAL_CONF_DIR}" "${SYSCONF}" > \ +- /dev/null 2>&1; then +- continue +- else +- printf "SNMPCONFPATH=%s\n" "${SNMPD_LOCAL_CONF_DIR}" \ +- >> ${SYSCONF} || RETVAL=7 ++ if ! grep -q "^SNMPCONFPATH.*${SNMPD_BMC_CONF_DIR}" \ ++ "${sysconf}" > /dev/null 2>&1; then ++ printf "SNMPCONFPATH=/etc/snmp:%s\n" \ ++ "${SNMPD_BMC_CONF_DIR}" >> ${sysconf} || \ ++ RETVAL=7 + fi + done ++ + return $RETVAL + } + + disable_snmp_proxy() + { +- if [ -f ${SNMPD_LOCAL_CONF} ]; then +- rm -f ${SNMPD_LOCAL_CONF} +- [ $? -ne 0 ] && RETVAL=5 ++ if [ -f ${SNMPD_BMC_CONF} ]; then ++ rm -f ${SNMPD_BMC_CONF} || RETVAL=5 + fi + } + ############################################################################# +@@ -152,6 +157,7 @@ disable_snmp_proxy() + pick_alert_dest() + { + test_ip="$1" ++ # We have 4 IPv4 and 4 IPv6 alert dest. We will set IPv4 for now. + for ALERT_DEST in `seq 1 4` + do + temp_ip=$(${IPMITOOL} lan alert print ${CHANNEL} ${ALERT_DEST}\ +@@ -165,12 +171,12 @@ pick_alert_dest() + set_alert_dest_ip() + { + ${IPMITOOL} lan alert set ${CHANNEL} ${ALERT_DEST} ipaddr ${1} \ +- retry 4 type pet >/dev/null 2>&1 +- [ $? -ne 0 ] && RETVAL=8 ++ retry 4 type pet >/dev/null 2>&1 || RETVAL=8 + } + +-bmc_alert_dest() ++config_bmc_alert_dest() + { ++ # call with enable|disable + # Pick the first active LAN channel + for CHANNEL in `seq 1 14` + do +@@ -180,12 +186,12 @@ bmc_alert_dest() + + # If TRAPD_IP is already set as an alert dest, + if pick_alert_dest "${TRAPD_IP}"; then +- # reset: reset it if we are called with reset +- [ "${1}" = "reset" ] && \ ++ # disable: reset it if we are called with disable ++ [ "${1}" = "disable" ] && \ + set_alert_dest_ip "0.0.0.0" + # else, find the next free alert dest, + elif pick_alert_dest "0.0.0.0"; then +- [ "${1}" = "reset" ] && \ ++ [ "${1}" = "disable" ] && \ + return $RETVAL + # set: the TRAPD_IP + set_alert_dest_ip "${TRAPD_IP}" +@@ -193,42 +199,54 @@ bmc_alert_dest() + # No free alert destinations + RETVAL=9 + fi ++ + return $RETVAL + } + +-set_ipmi_alert() ++set_ipmi_pef() + { +- ${IPMITOOL} lan set ${CHANNEL} alert "${1}" >/dev/null 2>&1 +- [ $? -ne 0 ] && RETVAL=10 ++ # Needs ipmitool-1.8.13 + patches ++ ${IPMITOOL} pef setpolicy ${ALERT_DEST} "${1}" >/dev/null 2>&1 || \ ++ RETVAL=10 + } + + get_host_ip() + { +- # Get host's IP that the BMC can reach. ++ # Get host's IP that the BMC can reach. This is at best a hack. + IFACE=$(/usr/sbin/ip -o -f inet address |awk '!/: lo/ {print $2}') ++ + for dev in ${IFACE} + do +- ping -c 1 -I ${dev} ${BMC_IPv4} > /dev/null 2>&1 ++ temp_ping=$(ping -c 1 -I ${dev} ${BMC_IPv4}) ++ [ $? -ne 0 ] && continue ++ ++ printf -- "%s" "$temp_ping"| awk 'NR==1{print $5}' && break + done + } + + config_bmc_alert() + { ++ # Do two things ++ # Set/Reset TRAP IP in BMC ++ # Enable/Disable PEF alerting in BMC for TRAP ++ + # Get Host's IP that the BMC can send traps to + TRAPD_IP=$(get_host_ip) + + # Set Host's IP as the alert destination in the BMC +- valid_ip ${TRAPD_IP} && bmc_alert_dest "${ACTION}" ++ valid_ip ${TRAPD_IP} && config_bmc_alert_dest "${ACTION}" ++ ++ # Enable/Disable alerting on the LAN channel ++ [ $RETVAL -eq 0 ] && set_ipmi_pef "${ACTION}" + +- # Enable alerting on the LAN channel +- [ $RETVAL -eq 0 ] && set_ipmi_alert "${ACTION}" ++ return $RETVAL + } + + write_trapd_conf() + { + printf "###############################################\n" + printf "# Automatically created by %s #\n" "${SCRIPT_NAME}" +- printf "forward %s %s\n" "${BMC_OID}*" "${FORWARD_HOST}" ++ printf "forward default %s\n" "${FORWARD_HOST}" + printf "###############################################\n" + } + +@@ -236,10 +254,9 @@ config_trapd() + { + # Proceed only if snmptrapd is available on the system + if [ -f ${TRAPD_CONF} ]; then +- write_trapd_conf > ${TRAPD_LOCAL_CONF} +- [ $? -ne 0 ] && RETVAL=11 ++ write_trapd_conf > ${TRAPD_BMC_CONF} || RETVAL=11 + else +- return 1 ++ RETVAL=11 + fi + } + +@@ -249,6 +266,7 @@ trap_sink_exists() + # multiple + FORWARD_HOST=$(awk '/^trap.*sink/{print $2}; /^informsink/{print $2}' \ + /etc/snmp/snmpd*conf | head -1) ++ + if [ -z "${FORWARD_HOST}" ]; then + # there is no trapsink setup. + return 1 +@@ -261,19 +279,20 @@ trap_sink_exists() + trap_forward() + { + NO_TRAP=0 +- ACTION=${1} # set or reset ++ ACTION=${1} # enable or disable + +- if [ "${ACTION}" = "set" ]; then ++ if [ "${ACTION}" = "enable" ]; then + # Get trapd config, + if trap_sink_exists; then +- config_trapd && config_bmc_alert ++ config_bmc_alert && config_trapd + else + # exit silently if there is no sink + NO_TRAP=1 + fi + else +- if [ -f ${TRAPD_LOCAL_CONF} ]; then +- rm -f ${TRAPD_LOCAL_CONF} >/dev/null 2>&1 ++ if [ -f ${TRAPD_BMC_CONF} ]; then ++ rm -f ${TRAPD_BMC_CONF} >/dev/null 2>&1 ++ config_bmc_alert + else + NO_TRAP=1 + fi +@@ -288,7 +307,6 @@ service_reload() + service $1 reload + [ $? -ne 0 ] && RETVAL=6 + fi +- return + } + + ############################################################################# +@@ -296,11 +314,12 @@ start() + { + if bmc_info_exists && check_snmp; then + touch ${LOCKFILE} ++ + set_snmpd_conf_path && set_snmp_proxy + [ $RETVAL -eq 0 ] && service_reload snmpd + + if [ "${TRAP_FORWARD}" = "yes" ]; then +- trap_forward "set" ++ trap_forward "enable" + [ $RETVAL -eq 0 ] && [ $NO_TRAP -eq 0 ] && \ + service_reload snmptrapd + fi +@@ -316,10 +335,11 @@ stop() + [ $RETVAL -eq 0 ] && service_reload snmpd + + if [ "${TRAP_FORWARD}" = "yes" ]; then +- trap_forward "reset" ++ trap_forward "disable" + [ $RETVAL -eq 0 ] && [ $NO_TRAP -eq 0 ] && \ + service_reload snmptrapd + fi ++ + rm -f ${LOCKFILE} + fi + } +@@ -329,12 +349,13 @@ status() + { + eval_gettext "${SCRIPT_NAME}: snmp proxy to BMC is " + # Checking for lockfile is better. +- #if grep -q "^proxy" "${SNMPD_LOCAL_CONF}" > /dev/null 2>&1 ; then ++ #if grep -q "^proxy" "${SNMPD_BMC_CONF}" > /dev/null 2>&1 ; then + if [ -f ${LOCKFILE} ]; then + eval_gettext "set" + else + eval_gettext "not set" + fi ++ + echo + RETVAL=0 + } +@@ -360,10 +381,10 @@ case "$RETVAL" in + 0|1) ;; + 2) eval_gettext "${SCRIPT_NAME}: failed to read ${BMC_INFO} " 1>&2 ;; + 3) eval_gettext "${SCRIPT_NAME}: failed to get proxy config." 1>&2 ;; +- 4) eval_gettext "${SCRIPT_NAME}: failed to set ${SNMPD_LOCAL_CONF}." 1>&2 ;; ++ 4) eval_gettext "${SCRIPT_NAME}: failed to set ${SNMPD_BMC_CONF}." 1>&2 ;; + 5) eval_gettext "${SCRIPT_NAME}: failed to disable snmp proxy." 1>&2 ;; + 6) eval_gettext "${SCRIPT_NAME}: failed to reload snmpd." 1>&2 ;; +- 7) eval_gettext "${SCRIPT_NAME}: failed to update ${SYSCONF}." 1>&2 ;; ++ 7) eval_gettext "${SCRIPT_NAME}: failed to set snmpd config." 1>&2 ;; + 8) eval_gettext "${SCRIPT_NAME}: failed to set IPMI alert dest." 1>&2 ;; + 9) eval_gettext "${SCRIPT_NAME}: no free IPMI alert dest." 1>&2 ;; + 10) eval_gettext "${SCRIPT_NAME}: failed to set IPMI PEF." 1>&2 ;; +@@ -375,6 +396,7 @@ esac + if [ ${RETVAL} -gt 1 ]; then + eval_gettext " Return code: ${RETVAL}"; echo + fi ++ + exit ${RETVAL} + ############################################################################# + # end of file +-- +1.8.3.1 + diff --git a/ipmitool-1.8.13.tar.bz2 b/ipmitool-1.8.13.tar.bz2 index 1ff7cf9..5433993 100644 --- a/ipmitool-1.8.13.tar.bz2 +++ b/ipmitool-1.8.13.tar.bz2 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e7b1bef1ed66f26217daa0b318d6e576ba45a69b2b9d54931c1646a2d81591a -size 423062 +oid sha256:df2f7f44b6f72db87fb33e99a7df02ae2dec6cf915322b9bab0c0745bf8d5748 +size 426220 diff --git a/ipmitool.changes b/ipmitool.changes index 60cc7fd..db2548e 100644 --- a/ipmitool.changes +++ b/ipmitool.changes @@ -1,3 +1,22 @@ +------------------------------------------------------------------- +Thu Mar 6 11:50:59 UTC 2014 - trenn@suse.de + +- Update to latest git head and do not split up version 1.8.13.tar.bz2 tarball + and patch to latest git HEAD. + Reason is that all files in the repository got moved up one directory level + by git commit: + c18ec02f3304ce2a889a50e378f07a4168af3884 + Date: Wed Feb 5 17:30:32 2014 + Move all files one level up in the file hierarchy, to avoid the useless + ipmitool directory. + + We want the latest git head asap, because otherwise additionally needed + patches will never patch cleanly in mainline and our repo and would always + need adjusting. + I asked for a new version tag mainline. As soon this happened, the + tarball name should again match with the exact mainline git tag. +- Incorporate patch on request from Dell: fate#315996 + ------------------------------------------------------------------- Thu Feb 13 23:27:01 UTC 2014 - trenn@suse.de diff --git a/ipmitool.spec b/ipmitool.spec index 2a1e1e8..8c5f79e 100644 --- a/ipmitool.spec +++ b/ipmitool.spec @@ -32,7 +32,6 @@ Release: 0 Source: http://heanet.dl.sourceforge.net/sourceforge/%{name}/%{name}-%{version}.tar.bz2 Source1: ipmievd.service Source2: ipmievd.sysconf -Patch0: ipmitool_update_to_git_head_31_01_2014_b0aad15d67007c74b.patch Patch1: ipmitool-1.8.10-implicit-fortify-decl.patch Patch3: fwum_enhance_output.patch Patch4: sdradd_close_file_handle.patch @@ -40,6 +39,7 @@ Patch6: fix_file_permissions.patch Patch8: several_more_compile_fixes.patch Patch9: automake-1.13.patch Patch10: ipmitool_adjust_suse.paths +Patch11: 0001-Incorporate-upstream-comments-to-289-add-whitespace.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build # bmc-snmp-proxy needs /usr/sbin/snmpd Requires: net-snmp @@ -66,7 +66,6 @@ and setting LAN configuration, and chassis power control. %prep %setup -q -%patch0 -p2 %patch1 -p0 %patch3 -p1 %patch4 -p1 @@ -74,6 +73,7 @@ and setting LAN configuration, and chassis power control. %patch8 -p1 %patch9 -p1 %patch10 -p1 +%patch11 -p1 %build touch INSTALL NEWS From 01998a8ef322a0da741c1e929b0776387e6a4d48204c293bc1d112925b4c22a7 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Thu, 6 Mar 2014 15:12:31 +0000 Subject: [PATCH 2/3] 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 -+ - } - - /* From 6c4dd6487a9ff34e3b7b971d599eddaa308339fbe67d508656cfe8c0a2d5a195 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Thu, 6 Mar 2014 15:13:11 +0000 Subject: [PATCH 3/3] Remove/Delete: ipmitool_update_to_git_head_31_01_2014_b0aad15d67007c74b.patch Add: 0001-Incorporate-upstream-comments-to-289-add-whitespace.patch OBS-URL: https://build.opensuse.org/package/show/systemsmanagement/ipmitool?expand=0&rev=27 --- ipmitool.changes | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ipmitool.changes b/ipmitool.changes index db2548e..1454aa8 100644 --- a/ipmitool.changes +++ b/ipmitool.changes @@ -15,7 +15,11 @@ Thu Mar 6 11:50:59 UTC 2014 - trenn@suse.de need adjusting. I asked for a new version tag mainline. As soon this happened, the tarball name should again match with the exact mainline git tag. + Remove/Delete: + ipmitool_update_to_git_head_31_01_2014_b0aad15d67007c74b.patch + - Incorporate patch on request from Dell: fate#315996 + Add: 0001-Incorporate-upstream-comments-to-289-add-whitespace.patch ------------------------------------------------------------------- Thu Feb 13 23:27:01 UTC 2014 - trenn@suse.de