diff options
author | Jörg Frings-Fürst <debian@jff.email> | 2025-03-16 13:34:00 +0100 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff.email> | 2025-03-16 13:34:00 +0100 |
commit | 0bbe5815fd94129767ec0072d1d7e5e7eff1a6e7 (patch) | |
tree | 1b44e7d6fd8446f8c3e2fc8f1ef3af281d590fab /util | |
parent | 9641459c047738b492ab6002a9d38d286e237721 (diff) | |
parent | 5ad8be875662e799ca8739e267b4879bb281a048 (diff) |
Merge branch 'feature/upstream' into develop
Diffstat (limited to 'util')
-rw-r--r-- | util/Makefile.in | 522 | ||||
-rw-r--r-- | util/idiscover.c | 50 | ||||
-rw-r--r-- | util/idiscover.c-319 | 1061 | ||||
-rw-r--r-- | util/ievents.c | 8 | ||||
-rw-r--r-- | util/ifru.c | 7 | ||||
-rw-r--r-- | util/ilan.c | 2 | ||||
-rw-r--r-- | util/imb_api.h | 3 | ||||
-rw-r--r-- | util/imbapi.c | 2 | ||||
-rw-r--r-- | util/ipmicmd.h | 1 | ||||
-rw-r--r-- | util/ipmidir.c | 4 | ||||
-rw-r--r-- | util/ipmiutil.c | 2 | ||||
-rw-r--r-- | util/isensor.c | 7 | ||||
-rw-r--r-- | util/isensor.c-old | 3907 | ||||
-rw-r--r-- | util/isensor.h | 2 | ||||
-rw-r--r-- | util/isol.c | 2 | ||||
-rw-r--r-- | util/itsol.c | 8 | ||||
-rw-r--r-- | util/itsol.h | 4 | ||||
-rw-r--r-- | util/mem_if.c | 2 | ||||
-rw-r--r-- | util/ocm_dell.c-319 | 6121 | ||||
-rw-r--r-- | util/oem_dell.c | 15 |
20 files changed, 7389 insertions, 4341 deletions
diff --git a/util/Makefile.in b/util/Makefile.in index 50f821c..28cff49 100644 --- a/util/Makefile.in +++ b/util/Makefile.in @@ -1,8 +1,9 @@ -# Makefile.in generated by automake 1.16.2 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2020 Free Software Foundation, Inc. - +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,61 +16,6 @@ @SET_MAKE@ VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -92,11 +38,11 @@ bin_PROGRAMS = ipmiutil$(EXEEXT) ievents$(EXEEXT) idiscover$(EXEEXT) sbin_PROGRAMS = ipmi_port$(EXEEXT) iseltime$(EXEEXT) EXTRA_PROGRAMS = ipmi_sample$(EXEEXT) ipmi_sample_evt$(EXEEXT) subdir = util +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -108,10 +54,6 @@ idiscover_OBJECTS = $(am_idiscover_OBJECTS) idiscover_LDADD = $(LDADD) am__DEPENDENCIES_1 = idiscover_DEPENDENCIES = $(am__DEPENDENCIES_1) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = am_ievents_OBJECTS = ievents.$(OBJEXT) ievents_OBJECTS = $(am_ievents_OBJECTS) ievents_LDADD = $(LDADD) @@ -155,100 +97,29 @@ iseltime_SOURCES = iseltime.c iseltime_OBJECTS = iseltime.$(OBJEXT) iseltime_LDADD = $(LDADD) iseltime_DEPENDENCIES = $(am__DEPENDENCIES_1) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/ialarms.Po ./$(DEPDIR)/icmd.Po \ - ./$(DEPDIR)/iconfig.Po ./$(DEPDIR)/idcmi.Po \ - ./$(DEPDIR)/idiscover.Po ./$(DEPDIR)/iekanalyzer.Po \ - ./$(DEPDIR)/ievents.Po ./$(DEPDIR)/ifirewall.Po \ - ./$(DEPDIR)/ifru.Po ./$(DEPDIR)/ifru_picmg.Po \ - ./$(DEPDIR)/ifwum.Po ./$(DEPDIR)/igetevent.Po \ - ./$(DEPDIR)/ihealth.Po ./$(DEPDIR)/ihpm.Po ./$(DEPDIR)/ilan.Po \ - ./$(DEPDIR)/imbapi.Po ./$(DEPDIR)/ipicmg.Po \ - ./$(DEPDIR)/ipmi_port.Po ./$(DEPDIR)/ipmi_sample.Po \ - ./$(DEPDIR)/ipmi_sample_evt.Po ./$(DEPDIR)/ipmibmc.Po \ - ./$(DEPDIR)/ipmicmd.Po ./$(DEPDIR)/ipmidir.Po \ - ./$(DEPDIR)/ipmilan.Po ./$(DEPDIR)/ipmilanplus.Po \ - ./$(DEPDIR)/ipmild.Po ./$(DEPDIR)/ipmilipmi.Po \ - ./$(DEPDIR)/ipmimv.Po ./$(DEPDIR)/ipmiutil.Po \ - ./$(DEPDIR)/ireset.Po ./$(DEPDIR)/isel.Po \ - ./$(DEPDIR)/iseltime.Po ./$(DEPDIR)/isensor.Po \ - ./$(DEPDIR)/iserial.Po ./$(DEPDIR)/isol.Po \ - ./$(DEPDIR)/itsol.Po ./$(DEPDIR)/iuser.Po ./$(DEPDIR)/iwdt.Po \ - ./$(DEPDIR)/md2.Po ./$(DEPDIR)/md5.Po ./$(DEPDIR)/mem_if.Po \ - ./$(DEPDIR)/oem_asus.Po ./$(DEPDIR)/oem_dell.Po \ - ./$(DEPDIR)/oem_fujitsu.Po ./$(DEPDIR)/oem_hp.Po \ - ./$(DEPDIR)/oem_intel.Po ./$(DEPDIR)/oem_kontron.Po \ - ./$(DEPDIR)/oem_lenovo.Po ./$(DEPDIR)/oem_newisys.Po \ - ./$(DEPDIR)/oem_quanta.Po ./$(DEPDIR)/oem_sun.Po \ - ./$(DEPDIR)/oem_supermicro.Po ./$(DEPDIR)/subs.Po +am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ SOURCES = $(idiscover_SOURCES) $(ievents_SOURCES) $(ipmi_port_SOURCES) \ ipmi_sample.c ipmi_sample_evt.c $(ipmiutil_SOURCES) iseltime.c DIST_SOURCES = $(idiscover_SOURCES) $(ievents_SOURCES) \ $(ipmi_port_SOURCES) ipmi_sample.c ipmi_sample_evt.c \ $(ipmiutil_SOURCES) iseltime.c -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ - $(top_srcdir)/mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -264,7 +135,6 @@ CROSS_LFLAGS = @CROSS_LFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -301,9 +171,7 @@ LIB_DIR = @LIB_DIR@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ @@ -319,7 +187,6 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_DIR = @PKG_DIR@ @@ -337,7 +204,6 @@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ @@ -370,6 +236,7 @@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = $(datadir)/locale localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ @@ -378,7 +245,6 @@ pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -468,13 +334,14 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign util/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign util/Makefile +.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -487,19 +354,14 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p \ - || test -f $$p1 \ - ; then echo "$$p"; echo "$$p"; else :; fi; \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ done | \ - sed -e 'p;s,.*/,,;n;h' \ - -e 's|.*|.|' \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ @@ -520,8 +382,7 @@ uninstall-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' \ - `; \ + -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files @@ -536,19 +397,14 @@ clean-binPROGRAMS: rm -f $$list install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) + test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ - fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p \ - || test -f $$p1 \ - ; then echo "$$p"; echo "$$p"; else :; fi; \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ done | \ - sed -e 'p;s,.*/,,;n;h' \ - -e 's|.*|.|' \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ @@ -569,8 +425,7 @@ uninstall-sbinPROGRAMS: @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' \ - `; \ + -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sbindir)" && rm -f $$files @@ -590,86 +445,80 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ialarms.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icmd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iconfig.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idcmi.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idiscover.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iekanalyzer.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ievents.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifirewall.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifru.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifru_picmg.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifwum.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/igetevent.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ihealth.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ihpm.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ilan.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imbapi.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipicmg.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_port.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_sample.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_sample_evt.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmibmc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmicmd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmidir.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmilan.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmilanplus.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmild.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmilipmi.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmimv.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmiutil.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ireset.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isel.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iseltime.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isensor.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iserial.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isol.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/itsol.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iuser.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iwdt.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem_if.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_asus.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_dell.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_fujitsu.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_hp.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_intel.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_kontron.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_lenovo.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_newisys.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_quanta.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_sun.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_supermicro.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subs.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ialarms.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icmd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iconfig.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idcmi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idiscover.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iekanalyzer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ievents.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifirewall.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifru.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifru_picmg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifwum.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/igetevent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ihealth.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ihpm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ilan.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imbapi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipicmg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_port.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_sample.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_sample_evt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmibmc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmicmd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmidir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmilan.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmilanplus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmild.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmilipmi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmimv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmiutil.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ireset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iseltime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isensor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iserial.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isol.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/itsol.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iuser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iwdt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem_if.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_asus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_dell.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_fujitsu.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_hp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_intel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_kontron.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_lenovo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_newisys.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_quanta.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_sun.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oem_supermicro.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subs.Po@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo @@ -677,15 +526,26 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ - $(am__define_uniq_tagged_files); \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -697,11 +557,15 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $$unique; \ fi; \ fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -710,29 +574,11 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -779,15 +625,10 @@ install-am: all-am installcheck: installcheck-am install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: distclean-generic: @@ -803,59 +644,7 @@ clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/ialarms.Po - -rm -f ./$(DEPDIR)/icmd.Po - -rm -f ./$(DEPDIR)/iconfig.Po - -rm -f ./$(DEPDIR)/idcmi.Po - -rm -f ./$(DEPDIR)/idiscover.Po - -rm -f ./$(DEPDIR)/iekanalyzer.Po - -rm -f ./$(DEPDIR)/ievents.Po - -rm -f ./$(DEPDIR)/ifirewall.Po - -rm -f ./$(DEPDIR)/ifru.Po - -rm -f ./$(DEPDIR)/ifru_picmg.Po - -rm -f ./$(DEPDIR)/ifwum.Po - -rm -f ./$(DEPDIR)/igetevent.Po - -rm -f ./$(DEPDIR)/ihealth.Po - -rm -f ./$(DEPDIR)/ihpm.Po - -rm -f ./$(DEPDIR)/ilan.Po - -rm -f ./$(DEPDIR)/imbapi.Po - -rm -f ./$(DEPDIR)/ipicmg.Po - -rm -f ./$(DEPDIR)/ipmi_port.Po - -rm -f ./$(DEPDIR)/ipmi_sample.Po - -rm -f ./$(DEPDIR)/ipmi_sample_evt.Po - -rm -f ./$(DEPDIR)/ipmibmc.Po - -rm -f ./$(DEPDIR)/ipmicmd.Po - -rm -f ./$(DEPDIR)/ipmidir.Po - -rm -f ./$(DEPDIR)/ipmilan.Po - -rm -f ./$(DEPDIR)/ipmilanplus.Po - -rm -f ./$(DEPDIR)/ipmild.Po - -rm -f ./$(DEPDIR)/ipmilipmi.Po - -rm -f ./$(DEPDIR)/ipmimv.Po - -rm -f ./$(DEPDIR)/ipmiutil.Po - -rm -f ./$(DEPDIR)/ireset.Po - -rm -f ./$(DEPDIR)/isel.Po - -rm -f ./$(DEPDIR)/iseltime.Po - -rm -f ./$(DEPDIR)/isensor.Po - -rm -f ./$(DEPDIR)/iserial.Po - -rm -f ./$(DEPDIR)/isol.Po - -rm -f ./$(DEPDIR)/itsol.Po - -rm -f ./$(DEPDIR)/iuser.Po - -rm -f ./$(DEPDIR)/iwdt.Po - -rm -f ./$(DEPDIR)/md2.Po - -rm -f ./$(DEPDIR)/md5.Po - -rm -f ./$(DEPDIR)/mem_if.Po - -rm -f ./$(DEPDIR)/oem_asus.Po - -rm -f ./$(DEPDIR)/oem_dell.Po - -rm -f ./$(DEPDIR)/oem_fujitsu.Po - -rm -f ./$(DEPDIR)/oem_hp.Po - -rm -f ./$(DEPDIR)/oem_intel.Po - -rm -f ./$(DEPDIR)/oem_kontron.Po - -rm -f ./$(DEPDIR)/oem_lenovo.Po - -rm -f ./$(DEPDIR)/oem_newisys.Po - -rm -f ./$(DEPDIR)/oem_quanta.Po - -rm -f ./$(DEPDIR)/oem_sun.Po - -rm -f ./$(DEPDIR)/oem_supermicro.Po - -rm -f ./$(DEPDIR)/subs.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -899,59 +688,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/ialarms.Po - -rm -f ./$(DEPDIR)/icmd.Po - -rm -f ./$(DEPDIR)/iconfig.Po - -rm -f ./$(DEPDIR)/idcmi.Po - -rm -f ./$(DEPDIR)/idiscover.Po - -rm -f ./$(DEPDIR)/iekanalyzer.Po - -rm -f ./$(DEPDIR)/ievents.Po - -rm -f ./$(DEPDIR)/ifirewall.Po - -rm -f ./$(DEPDIR)/ifru.Po - -rm -f ./$(DEPDIR)/ifru_picmg.Po - -rm -f ./$(DEPDIR)/ifwum.Po - -rm -f ./$(DEPDIR)/igetevent.Po - -rm -f ./$(DEPDIR)/ihealth.Po - -rm -f ./$(DEPDIR)/ihpm.Po - -rm -f ./$(DEPDIR)/ilan.Po - -rm -f ./$(DEPDIR)/imbapi.Po - -rm -f ./$(DEPDIR)/ipicmg.Po - -rm -f ./$(DEPDIR)/ipmi_port.Po - -rm -f ./$(DEPDIR)/ipmi_sample.Po - -rm -f ./$(DEPDIR)/ipmi_sample_evt.Po - -rm -f ./$(DEPDIR)/ipmibmc.Po - -rm -f ./$(DEPDIR)/ipmicmd.Po - -rm -f ./$(DEPDIR)/ipmidir.Po - -rm -f ./$(DEPDIR)/ipmilan.Po - -rm -f ./$(DEPDIR)/ipmilanplus.Po - -rm -f ./$(DEPDIR)/ipmild.Po - -rm -f ./$(DEPDIR)/ipmilipmi.Po - -rm -f ./$(DEPDIR)/ipmimv.Po - -rm -f ./$(DEPDIR)/ipmiutil.Po - -rm -f ./$(DEPDIR)/ireset.Po - -rm -f ./$(DEPDIR)/isel.Po - -rm -f ./$(DEPDIR)/iseltime.Po - -rm -f ./$(DEPDIR)/isensor.Po - -rm -f ./$(DEPDIR)/iserial.Po - -rm -f ./$(DEPDIR)/isol.Po - -rm -f ./$(DEPDIR)/itsol.Po - -rm -f ./$(DEPDIR)/iuser.Po - -rm -f ./$(DEPDIR)/iwdt.Po - -rm -f ./$(DEPDIR)/md2.Po - -rm -f ./$(DEPDIR)/md5.Po - -rm -f ./$(DEPDIR)/mem_if.Po - -rm -f ./$(DEPDIR)/oem_asus.Po - -rm -f ./$(DEPDIR)/oem_dell.Po - -rm -f ./$(DEPDIR)/oem_fujitsu.Po - -rm -f ./$(DEPDIR)/oem_hp.Po - -rm -f ./$(DEPDIR)/oem_intel.Po - -rm -f ./$(DEPDIR)/oem_kontron.Po - -rm -f ./$(DEPDIR)/oem_lenovo.Po - -rm -f ./$(DEPDIR)/oem_newisys.Po - -rm -f ./$(DEPDIR)/oem_quanta.Po - -rm -f ./$(DEPDIR)/oem_sun.Po - -rm -f ./$(DEPDIR)/oem_supermicro.Po - -rm -f ./$(DEPDIR)/subs.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -972,9 +709,8 @@ uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-binPROGRAMS clean-generic clean-libtool \ - clean-sbinPROGRAMS cscopelist-am ctags ctags-am distclean \ +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool clean-sbinPROGRAMS ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ @@ -985,11 +721,9 @@ uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ + tags uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-sbinPROGRAMS -.PRECIOUS: Makefile - # To build an imb api library (libimbapi.a): libimbapi.a: imbapi.c diff --git a/util/idiscover.c b/util/idiscover.c index 567cf05..34ea125 100644 --- a/util/idiscover.c +++ b/util/idiscover.c @@ -18,6 +18,7 @@ * 07/15/08 Andy Cress - added -r for ping repeats * 11/21/08 Andy Cress - detect eth intf and broadcast ip addr * 01/04/16 Andy Cress - v1.11, allow 0 if fBroadcastOk (-a) + * 11/30/24 Andy Cress - v1.12, detect if IP address */ /*M* Copyright (c) 2006, Intel Corporation @@ -158,7 +159,7 @@ int GetFirstIP(uchar *ipaddr, uchar *macadr, char *ipname, char fdb); /*ilan.c*/ /* * Global variables */ -static char * progver = "1.11"; +static char * progver = "1.12"; static char * progname = "idiscover"; static char fdebug = 0; static char fping = 1; @@ -283,17 +284,19 @@ static void cleanup(void) void show_usage(void) { - printf("Usage: %s [-abegix] \n",progname); - printf(" -a all nodes, enables broadcast ping\n"); - printf(" -b <ip> beginning IP address (x.x.x.x), required\n"); - printf(" -e <ip> ending IP address (x.x.x.x), default is begin IP\n"); - printf(" -g use GetChanAuthCap instead of RMCP ping\n"); - printf(" -i interface name, default is eth0\n"); - printf(" -m get MAC addresses with a raw broadcast ping\n"); - printf(" -p N specific Port (IPMI LAN port=623)\n"); - printf(" -r N number of Repeat pings to each node (default=1)\n"); - // printf(" -s specific subnet\n"); - printf(" -x show eXtra debug messages\n"); + printf("Usage: %s [-abeghimprx] \n",progname); + printf(" -a all nodes, enables broadcast ping\n"); + printf(" -b <ip> beginning IP address (x.x.x.x), required\n"); + printf(" -e <ip> ending IP address (x.x.x.x), default is begin IP\n"); + printf(" -g use GetChanAuthCap instead of RMCP ping\n"); + printf(" -h print this help text\n"); + printf(" -i <name|ip> interface to use: name, IP address or 0.0.0.0\n"); + printf(" defaults to first network interface (e.g. eth0)\n"); + printf(" -m get MAC addresses with a raw broadcast ping\n"); + printf(" -p <N> specific port (IPMI LAN port=623)\n"); + printf(" -r <N> number of repeat pings to each node (default=1)\n"); +// printf(" -s specific subnet\n"); + printf(" -x show extra debug messages\n"); } static int os_sleep(unsigned int s, unsigned int u) @@ -527,6 +530,22 @@ int sock_init( char *_interface, char *_startIP, char *_endIP) if (n < 0) rv = LAN_ERR_OTHER; /*-13*/ } else { /* valid _interface string */ if (strchr(_interface, '.') != NULL) + { /* assume it is an IP address*/ + rv = inet_pton(AF_INET, _interface, &_srcaddr.sin_addr); + if (rv < 0) + { + printerr("inet_pton: %s\n", showlasterr()); + return(-1); + } + if (rv == 0) + { + printerr("invalid interface address\n"); + return(-1); + } + } + else + { /* assume interface name, like eth0 */ + if (strchr(_interface, '.') != NULL) { /* assume it is an IP address*/ if ((rv = inet_pton(AF_INET, _interface, &_srcaddr.sin_addr)) < 0) printerr("inet_pton: %s\n", showlasterr()); @@ -534,7 +553,7 @@ int sock_init( char *_interface, char *_startIP, char *_endIP) printerr("invalid interface address\n"); return(rv); } - else + else { /* assume interface name, like eth0 */ strncpy(ifr.ifr_name, _interface, IFNAMSIZ); ifr.ifr_addr.sa_family = AF_INET; @@ -554,6 +573,7 @@ int sock_init( char *_interface, char *_startIP, char *_endIP) strcpy(g_endDest,temp_start); } } + } } } #endif @@ -963,7 +983,7 @@ main(int argc, char **argv) #endif printf("%s ver %s\n", progname,progver); - while ( (c = getopt( argc, argv,"ab:ce:gi:l:mp:r:s:x?")) != EOF ) + while ( (c = getopt( argc, argv,"ab:ce:ghi:l:mp:r:s:x?")) != EOF ) switch(c) { case 'a': fBroadcastOk = 1; fping = 1; break; /*all (broadcast ping)*/ @@ -996,7 +1016,7 @@ main(int argc, char **argv) * begin/end range. */ break; case 'x': fdebug = 1; break; /* debug messages */ - default: + case 'h': default: if (fdebug) printerr("getopt(%c) default\n",c); show_usage(); rv = ERR_USAGE; diff --git a/util/idiscover.c-319 b/util/idiscover.c-319 new file mode 100644 index 0000000..567cf05 --- /dev/null +++ b/util/idiscover.c-319 @@ -0,0 +1,1061 @@ +/* + * idiscover.c + * Discover all IPMI-LAN-enabled nodes on this network or subnet. + * This program is not completely reliable yet, not all IPMI-LAN-enabled + * nodes respond. + * Currently this utility is compiled with NO_THREADS, but threads can + * be enabled by commenting out this flag. + * + * Author: Andy Cress arcress at users.sourceforge.net + * Copyright (c) 2006 Intel Corporation. + * Copyright (c) 2009 Kontron America, Inc. + * + * 10/27/06 Andy Cress - created + * 05/01/07 Andy Cress - added -g for GetChannelAuthCap method, + * added -a logic for broadcast ping, + * updated WIN32 logic + * 09/20/07 Andy Cress - fixed send/receive thread order + * 07/15/08 Andy Cress - added -r for ping repeats + * 11/21/08 Andy Cress - detect eth intf and broadcast ip addr + * 01/04/16 Andy Cress - v1.11, allow 0 if fBroadcastOk (-a) + */ +/*M* +Copyright (c) 2006, Intel Corporation +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + a.. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + b.. Redistributions 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. + c.. Neither the name of Intel Corporation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *M*/ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#ifdef WIN32 +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#include <winsock.h> +#include <io.h> +#include <time.h> +#include "getopt.h" +#define NO_THREADS 1 +typedef unsigned int socklen_t; +WSADATA lan_ws; /*global for WSA*/ + +#elif defined(DOS) +#include <dos.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "getopt.h" +#define NO_THREADS 1 + +#else +/* Linux, BSD, Solaris */ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/select.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <net/if.h> +#include <netdb.h> +#include <fcntl.h> +#include <errno.h> +#include <pthread.h> +#if defined(HPUX) +/* getopt is defined in stdio.h */ +#elif defined(MACOS) +/* getopt is defined in unistd.h */ +#include <unistd.h> +#include <sys/sockio.h> +#ifndef HAVE_CONFIG_H +typedef unsigned int socklen_t; +#endif +#else +#include <getopt.h> +#endif + +/* comment out NO_THREADS to use this utility in Linux with threads */ +#define NO_THREADS 1 +#endif +#ifndef ETH_P_IP +#define ETH_P_IP 0x0800 /* Internet Protocol packet, see linux/if_ether.h */ +#endif + +/* TODO: fix RAW for -m in Solaris, FreeBSD, Windows (works in Linux) */ +#ifdef SOLARIS +#include <sys/sockio.h> +#define RAW_DOMAIN AF_INET +#define RAW_PROTO IPPROTO_RAW +static char frawok = 0; /*raw not working in Solaris*/ +#elif BSD +#define RAW_DOMAIN AF_INET +#define RAW_PROTO IPPROTO_RAW +static char frawok = 0; /*raw not working in FreeBSD*/ +#elif HPUX +#define RAW_DOMAIN AF_INET +#define RAW_PROTO IPPROTO_RAW +static char frawok = 0; /*raw not working in HPUX*/ +#elif MACOS +#define RAW_DOMAIN AF_INET +#define RAW_PROTO IPPROTO_RAW +static char frawok = 0; /*raw not working in MacOS*/ +#elif WIN32 +#define RAW_DOMAIN AF_INET +#define RAW_PROTO IPPROTO_ICMP +static char frawok = 0; /*raw not working in Windows*/ +#else +#define RAW_DOMAIN AF_PACKET +#define RAW_PROTO htons(ETH_P_IP) +static char frawok = 1; /*raw works in Linux*/ +#endif + +#include <string.h> +#include "ipmicmd.h" + +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +#define RMCP_PRI_RMCP_PORT 0x26F +#define SZ_PING 12 +#define IPMI_PING_MAX_LEN 50 /* usu 28 */ +#define CMD_GET_CHAN_AUTH_CAP 0x38 + +#ifdef WIN32 +int GetFirstIP(uchar *ipaddr, uchar *macadr, char *ipname, char fdb); /*ilan.c*/ +#endif + +/* + * Global variables + */ +static char * progver = "1.11"; +static char * progname = "idiscover"; +static char fdebug = 0; +static char fping = 1; +static char fraw = 0; +static char fBroadcastOk = 0; +static char fcanonical = 0; +static int broadcast_pings = 1; +//static uchar ipmi_maj = 0; +//static uchar ipmi_min = 0; +//static uchar netfn; +static ushort g_port = RMCP_PRI_RMCP_PORT; +static SockType g_sockfd = 0; +static SockType g_sockraw = 0; +static int g_limit = 30; /* after this many 'other' packets, stop. */ +static struct sockaddr_in _srcaddr; +// static struct sockaddr_in _destaddrlist[255]; +static struct in_addr _startAddr, _endAddr; +static char g_startDest[MAXHOSTNAMELEN+1] = {'\0'}; +static char g_endDest[MAXHOSTNAMELEN+1] = {'\0'}; +static char g_interface[INET_ADDRSTRLEN+1] = {""}; /*e.g. "eth0"*/ +static int g_num_packets = 0; +static int g_npings = 0; +static int g_npongs = 0; +static int g_recv_status = 0; +static int g_wait = 1; /* num sec to wait */ +static int g_delay = 0; /* num usec between sends */ +static int g_repeat = 1; /* number of times to repeat ping to each node */ +static char bdelim = BDELIM; /* '|' */ + +#ifdef METACOMMAND +extern FILE *fpdbg; /*from ipmicmd.c*/ +extern char *strlasterr(int rv); /*from ipmilan.c*/ +#else +void dump_buf(char *tag, uchar *pbuf, int sz, char fshowascii) +{ + uchar line[17]; + uchar a; + int i, j; + FILE *fpdbg; + + fpdbg = stdout; + line[0] = 0; line[16] = 0; + j = 0; + fprintf(fpdbg,"%s (len=%d): ", tag,sz); + for (i = 0; i < sz; i++) { + if (i % 16 == 0) { j = 0; fprintf(fpdbg,"%s\n %04x: ",line,i); } + if (fshowascii) { + a = pbuf[i]; + if (a < 0x20 || a > 0x7f) a = '.'; + line[j++] = a; + } + fprintf(fpdbg,"%02x ",pbuf[i]); + } + if (j < 16) { + line[j] = 0; + for (i = 0; i < (16-j); i++) fprintf(fpdbg," "); + } + fprintf(fpdbg,"%s\n",line); + return; +} +#endif + +void printerr( const char *pattn, ...) +{ + va_list arglist; + FILE *fderr; + + // fderr = fopen("/tmp/idiscover.log","a+"); + // if (fderr == NULL) return; + fderr = stderr; + + va_start(arglist, pattn); + vfprintf(fderr, pattn, arglist); + va_end(arglist); + + // fclose(fderr); +} + +static char *showlasterr(void) +{ + char *str; +#ifdef WIN32 + static char strbuf[80]; + int rv; + char *desc; + rv = WSAGetLastError(); +#ifdef METACOMMAND + /* get descriptions from strlasterr in ipmilan.c */ + desc = strlasterr(rv); +#else + if (rv == WSAECONNRESET) desc = "Connection reset"; /*10054*/ + else if (rv == WSAECONNREFUSED) desc = "Connection refused"; /*10061*/ + else if (rv == WSAEHOSTUNREACH) desc = "No route to host"; /*10065*/ + else desc = ""; +#endif + sprintf(strbuf,"LastError = %d %s",rv,desc); + str = strbuf; +#else + str = strerror(errno); +#endif + return(str); +} + +static void cleanup(void) +{ + SockType *pfd; + int i; + for (i = 0; i < 2; i++) { + if (i == 0) pfd = &g_sockfd; + else pfd = &g_sockraw; + if (*pfd > 0) { +#ifdef WIN32 + closesocket(*pfd); + WSACleanup(); +#else + close(*pfd); +#endif + } + *pfd = 0; + } +} + +void show_usage(void) +{ + printf("Usage: %s [-abegix] \n",progname); + printf(" -a all nodes, enables broadcast ping\n"); + printf(" -b <ip> beginning IP address (x.x.x.x), required\n"); + printf(" -e <ip> ending IP address (x.x.x.x), default is begin IP\n"); + printf(" -g use GetChanAuthCap instead of RMCP ping\n"); + printf(" -i interface name, default is eth0\n"); + printf(" -m get MAC addresses with a raw broadcast ping\n"); + printf(" -p N specific Port (IPMI LAN port=623)\n"); + printf(" -r N number of Repeat pings to each node (default=1)\n"); + // printf(" -s specific subnet\n"); + printf(" -x show eXtra debug messages\n"); +} + +static int os_sleep(unsigned int s, unsigned int u) +{ +#ifdef WIN32 + if (s == 0) { + if (u >= 1000) Sleep(u/1000); + } else { + Sleep(s * 1000); + } +#else +/*Linux*/ +#ifdef SELECT_TIMER + struct timeval tv; + tv.tv_sec = s; + tv.tv_usec = u; + if (select(1, NULL, NULL, NULL, &tv) < 0) + printerr("select: %s\n", showlasterr()); +#else + if (s == 0) { + usleep(u); + } else { + sleep(s); + } +#endif +#endif + return 0; +} + +void split_ip(uint addr, uchar *ip) +{ + ip[3] = (addr & 0x000000ff); + ip[2] = (addr & 0x0000ff00) >> 8; + ip[1] = (addr & 0x00ff0000) >> 16; + ip[0] = (addr & 0xff000000) >> 24; +} + +int ntoi(int addr) +{ + return(addr); +} + +void show_ip(int saddr) +{ + uchar ip[4]; + split_ip(saddr,ip); + printerr("%d.%d.%d.%d\n",ip[0],ip[1],ip[2],ip[3]); +} + +static int ipmilan_sendto(SockType s, const void *msg, size_t len, int flags, + const struct sockaddr *to, socklen_t tolen) +{ + int n; +#ifdef NEED_PAD + int fusepad = 0; + /* Never need a pad byte for ping/pong packets */ + if (len == 56 || len == 84 || len == 112 || len == 128 || len == 156) { + fusepad = 1; + len += 1; + } +#endif + n = (int)sendto(s,msg,len,flags,to,tolen); + // if (fusepad && (n > 0)) n--; + return(n); +} + +static int ipmilan_recvfrom(SockType s, void *buf, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen) +{ + int rv; + rv = (int)recvfrom(s,buf,len,flags,from,fromlen); + /* Sometimes the OS sends an ECONNREFUSED error, but + * retrying will catch the BMC's reply packet. */ +#ifdef WIN32 + if (rv < 0) { + int err; + err = WSAGetLastError(); + if (err == WSAECONNREFUSED) /*10061*/ + rv = (int)recvfrom(s,buf,len,flags,from,fromlen); + } +#else + if ((rv < 0) && (errno == ECONNREFUSED)) + rv = (int)recvfrom(s,buf,len,flags,from,fromlen); +#endif + return(rv); +} + +#if defined(WIN32) +int inet_aton(const char *cp, struct in_addr *inp) +{ + int rv; + int adr; + inp->s_addr = inet_addr(cp); + adr = (int)inp->s_addr; + if (adr == INADDR_NONE) rv = 0; + else rv = 1; /*success*/ + return(rv); +} +#elif defined(SOLARIS) || defined(HPUX) +int find_ifname(char *ifname) +{ return(-1); } +#else +#include <ifaddrs.h> +int find_ifname(char *ifname) +{ + struct ifaddrs *ifaddr, *ifa; + int rv = -1; + if (getifaddrs(&ifaddr) == -1) return(rv); + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) continue; + if ((ifa->ifa_addr->sa_family != AF_INET) && + (ifa->ifa_addr->sa_family != AF_INET6)) continue; + if (strcmp(ifa->ifa_name,"lo") == 0) continue; + /* if here, we have a valid ifname */ + strcpy(ifname,ifa->ifa_name); + if (fdebug) printf("find_ifname: found %s\n",ifname); + rv = 0; + break; + } + freeifaddrs(ifaddr); + return(rv); +} +#endif + +int sock_init( char *_interface, char *_startIP, char *_endIP) +{ + int rv; + uchar *pb; + uchar val; + +#ifdef WIN32 + DWORD rvl; + rvl = WSAStartup(0x0101,&lan_ws); + if (rvl != 0) { + printerr("init: WSAStartup(1.1) error %ld\n", rvl); + return((int)rvl); + } +#else + char findif; +#endif + + if ((g_sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SockInvalid) { + printerr("socket: %s\n", showlasterr()); + return(-1); + } + + memset(&_srcaddr, 0, sizeof(_srcaddr)); + _srcaddr.sin_family = AF_INET; + _srcaddr.sin_port = htons(0); + _srcaddr.sin_addr.s_addr = htonl(INADDR_ANY); + +#ifdef WIN32 + { + int ret; + uchar osip[4]; + uchar osmac[6]; + uchar osname[64]; + char ipstr[20]; + char *temp_start; + if (fBroadcastOk && (g_startDest[0] == 0)) { + ret = GetFirstIP(osip,osmac,osname,fdebug); /*ilan.c*/ + if (ret == 0) { + // osip[3] = 0xFF; /*255 for broadcast*/ + sprintf(ipstr,"%d.%d.%d.255",osip[0],osip[1],osip[2]); + temp_start = ipstr; + strcpy(g_startDest,temp_start); + strcpy(g_endDest,temp_start); + } else { /*use some defaults*/ + strcpy(g_startDest,"255.255.255.255"); + strcpy(g_endDest,"255.255.255.255"); + } + } + } +#elif defined(HPUX) + { /*find the OS eth interface to use*/ + char devname[INET_ADDRSTRLEN+1]; + int i, n; + n = 0; + sprintf(devname,"lan%d",n); + } +#else + { /*find the OS eth interface to use*/ + struct sockaddr_in temp_sockaddr; + char *temp_start; + struct ifreq ifr; + char devname[INET_ADDRSTRLEN+1]; + int i, n; + if (_interface == NULL) findif = 1; + else if (_interface[0] == 0) findif = 1; + else findif = 0; + if (findif) { + n = find_ifname(devname); + if (n >= 0) { + _interface = devname; + findif = 0; /*found, do not find again below */ + } + } + if (findif) + { /* try again to find the first active ethN interface */ + n = -1; + for (i = 0; (i < 16) && (n == -1); i++) { +#ifdef SOLARIS + sprintf(devname,"e1000g%d",i); +#elif BSD + sprintf(devname,"em%d",i); +#else + sprintf(devname,"eth%d",i); +#endif + strcpy(ifr.ifr_name, devname); + ifr.ifr_addr.sa_family = AF_INET; + if (ioctl(g_sockfd, SIOCGIFADDR, &ifr) >= 0) { + /* valid IP address, so active interface, use it */ + temp_sockaddr = *((struct sockaddr_in *)&ifr.ifr_addr); + memcpy(&_srcaddr.sin_addr.s_addr, &temp_sockaddr.sin_addr.s_addr, + sizeof(_srcaddr.sin_addr.s_addr)); + strcpy(g_interface, devname); + temp_start = inet_ntoa(temp_sockaddr.sin_addr); + if (temp_start == NULL) temp_start = ""; + else if (fBroadcastOk && (g_startDest[0] == 0)) { + pb = (uchar *)&temp_sockaddr.sin_addr.s_addr; + pb[3] = 0xFF; /*255 for broadcast*/ + temp_start = inet_ntoa(temp_sockaddr.sin_addr); + strcpy(g_startDest,temp_start); + strcpy(g_endDest,temp_start); + } + printf("sock_init: found %s with %s\n",devname,temp_start); + n = i; + break; + } + } + if (n < 0) rv = LAN_ERR_OTHER; /*-13*/ + } else { /* valid _interface string */ + if (strchr(_interface, '.') != NULL) + { /* assume it is an IP address*/ + if ((rv = inet_pton(AF_INET, _interface, &_srcaddr.sin_addr)) < 0) + printerr("inet_pton: %s\n", showlasterr()); + if (rv == 0) + printerr("invalid interface address\n"); + return(rv); + } + else + { /* assume interface name, like eth0 */ + strncpy(ifr.ifr_name, _interface, IFNAMSIZ); + ifr.ifr_addr.sa_family = AF_INET; + if (ioctl(g_sockfd, SIOCGIFADDR, &ifr) < 0) { + printerr("ioctl(%s): %s\n", _interface, showlasterr()); + return(-1); + } + + temp_sockaddr = *((struct sockaddr_in *)&ifr.ifr_addr); + memcpy(&_srcaddr.sin_addr.s_addr, &temp_sockaddr.sin_addr.s_addr, + sizeof(_srcaddr.sin_addr.s_addr)); + if (fBroadcastOk && (g_startDest[0] == 0)) { + pb = (uchar *)&temp_sockaddr.sin_addr.s_addr; + pb[3] = 0xFF; /*255 for broadcast*/ + temp_start = inet_ntoa(temp_sockaddr.sin_addr); + strcpy(g_startDest,temp_start); + strcpy(g_endDest,temp_start); + } + } + } + } +#endif + + if (fBroadcastOk) { + rv = setsockopt(g_sockfd, SOL_SOCKET, SO_BROADCAST, + (char *)&broadcast_pings, sizeof(broadcast_pings)); + if (rv) { + printerr("setsockopt: %s\n", showlasterr()); + return(-1); + } + } + + if (bind(g_sockfd, (struct sockaddr *)&_srcaddr, sizeof(_srcaddr)) < 0) { + printerr("bind: %s\n", showlasterr()); + return(-1); + } + + rv = inet_aton(_startIP, &_startAddr); + if (rv ) { + _startAddr.s_addr = ntohl(_startAddr.s_addr); + if (fdebug) show_ip(_startAddr.s_addr); + pb = (unsigned char*)&_startAddr.s_addr; + if (!fBroadcastOk && (pb[0] < 1) ) + printerr("Malformed begin IP: %s\n", _startIP); + else if (!fBroadcastOk && (pb[0] >254) ) + printerr("Malformed begin IP: %s\n", _startIP); + else if (fBroadcastOk) { + val = pb[0] & 0x0f; + if (val == 0x0f) rv = 0; + else if (val == 0x00) rv = 0; + else printerr("Malformed begin broadcast IP: %s\n", _startIP); + } else rv = 0; + } else { + printerr("Invalid begin IP: %s\n", _startIP); + } + if (rv) return(rv); + + rv = inet_aton(_endIP, &_endAddr); + if (rv ) { + _endAddr.s_addr = ntohl(_endAddr.s_addr); + if (fdebug) show_ip(_endAddr.s_addr); + pb = (unsigned char*)&_endAddr.s_addr; + if (!fBroadcastOk && (pb[0] < 1) ) + printerr("Malformed end IP: %s\n", _endIP); + else if (!fBroadcastOk && (pb[0] >254) ) + printerr("Malformed end IP: %s\n", _endIP); + else rv = 0; + } else { + printerr("Invalid end IP: %s\n", _endIP); + } + + /* calculate g_num_packets */ + g_num_packets = ntoi(_endAddr.s_addr) - ntoi(_startAddr.s_addr) + 1; + if (fdebug) printerr("g_num_packets = %d\n",g_num_packets); + if (g_num_packets < 1) g_num_packets = 0; + + return(rv); +} /*end sock_init*/ + +void *receiveThread(void *p) +{ + uchar buffer[IPMI_PING_MAX_LEN]; + struct timeval tv; + fd_set rset; + int rv, len; + static int needlf = 0; + char host[200]; + SockType sockrecv; + int nothers = 0; + int addr_type = AF_INET; /*or AF_INET6*/ +#ifndef WIN32 + struct hostent *h_ent = NULL; + char serv[200]; + int r; +#endif + + sockrecv = g_sockfd; + if (fraw) { /* opening SOCK_RAW requires admin/root privilege. */ + if ((g_sockraw = socket(RAW_DOMAIN, SOCK_RAW,RAW_PROTO)) == SockInvalid) + { + printerr("raw socket: %s\n", showlasterr()); + fraw = 0; + } else { + sockrecv = g_sockraw; + if (fdebug) printf("g_sockraw = %d\n",g_sockraw); + } + } + + /* receive while loop */ + do + { + tv.tv_sec = g_wait; + tv.tv_usec = 0; + FD_ZERO(&rset); + FD_SET(sockrecv, &rset); + g_recv_status = 0; + + if (fdebug) printerr("waiting for ping %d response\n",g_npings); + if ((rv = select((int)(sockrecv+1), &rset, NULL, NULL, &tv)) < 0) { + printerr("select: %s\n", showlasterr()); + cleanup(); + exit(rv); // error, exit idiscover recv thread + } + + if (fdebug) printerr("select rv = %d\n",rv); + if (rv > 0) + { + struct sockaddr_in from; + socklen_t fromlen; + char rstr[40]; + char macstr[20]; + struct in_addr from_ip; + char estr[40]; + + if (needlf) { printf("\n"); needlf = 0; } + g_recv_status = 1; + fromlen = sizeof(from); + len = ipmilan_recvfrom(sockrecv, buffer, IPMI_PING_MAX_LEN, 0, + (struct sockaddr *)&from, &fromlen); + if (fdebug) printerr("recvfrom rv = %d\n",rv); + if (len < 0) { + printerr("ipmilan_recvfrom: %s\n", showlasterr()); + continue; + } + if (fdebug) { + /* can we get the MAC addr of the responder also? */ + // dump_buf("from_addr",(uchar *)&from,fromlen,0); + dump_buf("recvfrom",buffer,len,0); + } + g_recv_status = 2; + g_npongs++; + macstr[0] = 0; + if (fraw) { /* Raw packet, include MAC address string */ + /* + * Sample raw packet for UDP ping response + * dst_mac src_mac eth_p iphdr + * 0000: 00 07 e9 06 15 31 00 0e 0c 2b b5 81 08 00 45 00 + * udp src_ip dst_ip + * 0010: 00 38 00 00 40 00 40 11 b6 01 c0 a8 01 c2 c0 a8 + * rmcp + * 0020: 01 a1 02 6f 80 1e 00 24 0e d1 06 00 ff 06 00 00 + * 0030: 11 be + */ + if ((buffer[23] != 0x11) || (buffer[42] != 0x06)) { + /* [23]: 0x11==UDP, 0x06==TCP ; [42]: 0x06 ==RMCP */ + if (nothers > g_limit) { + if (fdebug) + printf("got %d other packets, stop.\n",nothers); + break; + } + nothers++; + continue; + } + if (buffer[6] == 0xFF || buffer[26] == 0xFF) /*broadcast*/ + continue; + sprintf(macstr,"%02x:%02x:%02x:%02x:%02x:%02x %c", + buffer[6], buffer[7], buffer[8], /*06=src_mac*/ + buffer[9], buffer[10], buffer[11], bdelim); + memcpy(&from_ip,&buffer[26],4); /*26=src_ip*/ + } else { + memcpy(&from_ip,&from.sin_addr,4); + } + host[0] = 0; +#ifndef WIN32 +/* Linux, BSD, Solaris, MacOS */ +#if !defined(CROSS_COMPILE) + h_ent = gethostbyaddr((void *)&from_ip,4,addr_type); + if (h_ent != NULL) { + strncpy(host,h_ent->h_name,sizeof(host)); + } else if (!fraw) +#endif + { + r = getnameinfo((struct sockaddr *)&from, fromlen, + host, sizeof(host), serv, sizeof(serv), 0); + if (r) host[0] = 0; + else if (host[0] >= '0' && host[0] <= '9') host[0] = 0; + } +#endif + // parse the received pong + rstr[0] = 0; + if (fping == 0 && len > 0) { /* -g and got rsp data */ + /* parse GetChanAuthcap response into rstr */ + /* 4 bytes RMCP, 10 bytes IPMI session, then msg */ + /* 6 bytes msg hdr, then rsp data */ + /* 20 = ccode, 21 = chan, 22 = auth type support */ + if (buffer[20] != 0) /*ccode error*/ + sprintf(rstr,"%c (ccode=0x%02x)",bdelim,buffer[20]); + else /*ccode is ok*/ + sprintf(rstr,"%c (channel %d)",bdelim,buffer[21]); + } + if (fcanonical) { + estr[0] = 0; + rstr[0] = 0; + } else { + sprintf(estr,"response from %c ",bdelim); + } + /* &buffer[0] = source MAC, &buffer[6] = destination MAC */ + printf("%.2d%c %s%s %s \t%c %s %s\n", + g_npongs,bdelim,estr,macstr,inet_ntoa(from_ip), + bdelim,host,rstr); + } + else { /*ping, no answer*/ + if (!fBroadcastOk) { + printf("."); fflush(stdout); /*show progress*/ + needlf = 1; + } + } + } +#ifdef NO_THREADS + while(fBroadcastOk && rv > 0); +#else + while(1); +#endif + return(p); +} + +/* + * send_ping_pkt: + * RMCP Ping buffer, sent as a UDP packet to port 0x026f. + * rmcp.ver = 0x06 // RMCP Version 1.0 + * rmcp.resvd = 0x00 // RESERVED + * rmcp.seq = 0xff // no RMCP ACK + * rmcp.class = 0x06 // RMCP_CLASS_ASF + * asf.iana = 0x000011BE // ASF_RMCP_IANA (hi-lo) + * asf.type = 0x80 // ASF_TYPE_PING + * asf.tag = 0x00 // ASF sequence number + * asf.resvd = 0x00 // RESERVED + * asf.len = 0x00 + */ +int send_ping_pkt(struct sockaddr_in *_daddr, uchar seq) +{ + uchar pingbuf[SZ_PING] = {06,0,0xFF,06,0x00,0x00,0x11,0xBE,0x80,0,0,0 }; + int rv, len; + + pingbuf[9] = seq; + len = sizeof(pingbuf); + if (fdebug) dump_buf("send_ping",pingbuf,len,0); + rv = ipmilan_sendto(g_sockfd, pingbuf, len, 0, + (struct sockaddr *)_daddr, sizeof(struct sockaddr_in)); + return(rv); +} + +static int send_poke1(struct sockaddr_in *_daddr) +{ + int rv; + uchar asfpkt[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x20, 0x18, 0xc8, 0xc2, 0x01, 0x01, 0x3c }; + if (fdebug) dump_buf("send_poke1",asfpkt,16,0); + rv = ipmilan_sendto(g_sockfd, asfpkt, 16, 0, + (struct sockaddr *)_daddr, sizeof(struct sockaddr_in)); + return rv; +} + +static uchar cksum(const uchar *buf, register int len) +{ + register uchar csum; + register int i; + + /* 8-bit 2s compliment checksum */ + csum = 0; + for (i = 0; i < len; i++) + csum = (csum + buf[i]) % 256; + csum = -csum; + return(csum); +} + +static int send_getauth(struct sockaddr_in *_daddr, uchar seq) +{ + int rv, len; + // static uchar swseq = 0; + uchar getauthpkt[23] = { 0x06, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x20, 0x18, + 0xc8, 0x81, 0x04, 0x38, 0x0e, 0x04, 0x31 }; + /* + * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + * 06 00 ff 07 00 00 00 00 00 00 00 00 00 09 20 18 c8 81 04 38 0e 04 31 + * [RMCP hdr ] [IPMI session hdr (len)] [IPMI msg ] [data] + */ + // getauthpkt[8] = 0x00; /* seq always 00 for GetChanAuthCap */ + getauthpkt[21] = 0x02; /*requested priv_level: 2=user, 4=admin*/ + getauthpkt[22] = cksum(&getauthpkt[17],5); + len = sizeof(getauthpkt); + if (fdebug) dump_buf("send_getauth",getauthpkt,len,0); + rv = ipmilan_sendto(g_sockfd, getauthpkt, len, 0, + (struct sockaddr *)_daddr, sizeof(struct sockaddr_in)); + if (fdebug) + printf("send_getauth: rv = %d\n",rv); + return rv; +} + +int send_probe(struct sockaddr_in *_daddr, uchar seq) +{ + int rv; + + if (fBroadcastOk) { + rv = setsockopt(g_sockfd, SOL_SOCKET, SO_BROADCAST, + (char *)&broadcast_pings, sizeof(broadcast_pings)); + if (fdebug) { + char *estr; + if (rv) estr = showlasterr(); + else estr = ""; + printerr("setsockopt(broadcast): rv=%d %s\n", rv,estr); + } + } + if (fping) + rv = send_ping_pkt( _daddr, seq); + else + rv = send_getauth( _daddr, seq); + return(rv); +} + +void *sendThread(void *p) +{ + int i, j, n; + // char _dest[MAXHOSTNAMELEN+1]; + char _dest_ip[INET_ADDRSTRLEN+1]; + struct sockaddr_in _destaddr; + uchar o[4]; + uint ip; + uchar _seq; + int rv; + + n = g_num_packets; /*num*/ + ip = _startAddr.s_addr; + + for (i = 0; i < n; i++) + { + split_ip(ip,o); + if (o[3] == 0) continue; + if (!fBroadcastOk && (o[3] == 255)) continue; + sprintf(_dest_ip,"%d.%d.%d.%d",o[0],o[1],o[2],o[3]); + + /* set _destaddr */ + _destaddr.sin_family = AF_INET; + _destaddr.sin_port = htons(g_port); + if ( !inet_aton( _dest_ip, &_destaddr.sin_addr)) { + printerr("inet_aton error %s\n",_dest_ip); + continue; + } + + for (j=0; j<g_repeat; j++) + { + /* send ping buffer */ + _seq = 0; + rv = send_probe(&_destaddr,_seq); + g_npings++; + if (fdebug) printerr("sendto[%d,%d] %s rv = %d\n", + g_npings,_seq,_dest_ip,rv); + if (rv < 0) { /*try to send again*/ + rv = send_probe(&_destaddr,++_seq); + if (rv < 0) { + printerr("sendto[%d,%d] %s error %s\n", + g_npings,_seq,_dest_ip,showlasterr()); + continue; + } + } + +#ifdef NO_THREADS + receiveThread(NULL); + if (g_recv_status == 0 && !fBroadcastOk) { + /* nothing returned, try again */ + if (fping) { + rv = send_poke1(&_destaddr); + if (fdebug) printerr("sendto[%d,%d] %s poke rv = %d\n", + g_npings,_seq,_dest_ip,rv); + } + rv = send_probe(&_destaddr,++_seq); + if (fdebug) printerr("sendto[%d,%d] %s rv = %d\n", + g_npings,_seq,_dest_ip,rv); + if (rv >= 0) { + receiveThread(NULL); + } + } +#endif + + /* sleep an interval (g_delay usec) */ + if (g_delay > 0) os_sleep(0,g_delay); + } /*end-for g_repeat*/ + + ip++; /* increment to next IP */ + } + return(p); +} + +#ifdef METACOMMAND +int i_discover(int argc, char **argv) +#else +#ifdef WIN32 +int __cdecl +#else +int +#endif +main(int argc, char **argv) +#endif +{ + int rv = 0; + int c; +#ifndef NO_THREADS + char message[32]; + pthread_t thread[2]; + int iret[2]; +#endif + +#ifdef METACOMMAND + fpdbg = stdout; +#endif + printf("%s ver %s\n", progname,progver); + + while ( (c = getopt( argc, argv,"ab:ce:gi:l:mp:r:s:x?")) != EOF ) + switch(c) { + case 'a': fBroadcastOk = 1; fping = 1; + break; /*all (broadcast ping)*/ + case 'c': /*canonical, CSV*/ + fcanonical = 1; + bdelim = BCOMMA; + break; + case 'm': /* show MAC address, use raw, requires root priv */ + fBroadcastOk = 1; fping = 1; fraw = 1; + break; /*all (broadcast ping)*/ + case 'l': g_limit = atoi(optarg); break; + case 'g': fping = 0; break; /*use get chan auth cap method */ + case 'b': /*begin*/ + strncpy(g_startDest,optarg,MAXHOSTNAMELEN); + break; + case 'e': /*end*/ + strncpy(g_endDest,optarg,MAXHOSTNAMELEN); + break; + case 'i': /*interface*/ + strncpy(g_interface,optarg,sizeof(g_interface)); + break; + case 'p': /*port/socket*/ + g_port = (ushort)atoi(optarg); + break; + case 'r': /*repeat N times*/ + g_repeat = atoi(optarg); + break; + case 's': /*subnet*/ + /* copy optarg from 10.243.42.0 or similar, to + * begin/end range. */ + break; + case 'x': fdebug = 1; break; /* debug messages */ + default: + if (fdebug) printerr("getopt(%c) default\n",c); + show_usage(); + rv = ERR_USAGE; + goto do_exit; + } +#ifdef WIN32 + /* Winsock inet_aton() does not like 255.255.255.255 */ + if (!fBroadcastOk && (g_startDest[0] == 0) ) { + show_usage(); + printerr("A beginning IP is required, using -b\n"); + goto do_exit; + } +#else + if (g_startDest[0] == 0) { + strcpy(g_startDest,"255.255.255.255"); /* INADDR_BROADCAST */ + fBroadcastOk = 1; + } +#endif + if (fraw == 1) { + if (frawok == 0) { + printf("Warning: SOCK_RAW not yet implemented on this OS\n"); + } +#ifdef LINUX + else { + c = geteuid(); + if (c > 1) printf("Must be root/superuser to use SOCK_RAW\n"); + } +#endif + } + if (g_endDest[0] == 0 || fBroadcastOk) + strcpy(g_endDest,g_startDest); /*only one IP address*/ + if (fdebug) + printerr("intf=%s begin=%s end=%s port=%d\n", + g_interface,g_startDest,g_endDest,g_port); + + rv = sock_init(g_interface, g_startDest, g_endDest); + if (fdebug) printerr("sock_init rv = %d, sockfd = %d\n",rv,g_sockfd); + if (rv != 0) { + show_usage(); + printerr("sock_init error %d\n",rv); + goto do_exit; + } + + printf("Discovering IPMI Devices:\n"); +#ifdef NO_THREADS + sendThread(NULL); +#else + iret[1] = pthread_create( &thread[1], NULL, receiveThread, (void*) message); + iret[0] = pthread_create( &thread[0], NULL, sendThread, (void*) message); + pthread_join( thread[0], NULL); + pthread_join( thread[1], NULL); +#endif + + // if (fdebug) + printf("\n%s: %d pings sent, %d responses\n",progname,g_npings,g_npongs); + +do_exit: + cleanup(); + return(rv); +} /* end main()*/ + +/* end idiscover.c */ diff --git a/util/ievents.c b/util/ievents.c index 17b41a4..d9e9054 100644 --- a/util/ievents.c +++ b/util/ievents.c @@ -80,7 +80,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. extern char *progver; /*from ipmiutil.c*/ static char * progname = "ipmiutil events"; #else -static char *progver = "3.19"; +static char *progver = "3.21"; static char *progname = "ievents"; #endif static char fsensdesc = 0; /* 1= get extended sensor descriptions*/ @@ -626,7 +626,7 @@ extern int GetSDR(int recid, int *recnext, uchar *sdr, int szsdr, int *slen); extern double RawToFloat(uchar raw, uchar *psdr); extern char *get_unit_type(uchar iunit, uchar ibase, uchar imod, int flg); extern int find_sdr_by_snum(uchar *psdr,uchar *pcache, uchar snum, uchar sa); -extern int GetSensorType(int snum, uchar *stype, uchar *rtype); +extern int GetSensorType(uchar snum, uchar *stype, uchar *rtype); extern char * get_mfg_str(uchar *rgmfg, int *pmfg); /*from ihealth.c*/ extern int decode_post_intel(int prod, ushort code, char *outbuf,int szbuf); extern int decode_sel_kontron(uchar *evt, char *obuf,int sz,char fdesc,char fdbg); /*oem_kontron.c*/ @@ -678,7 +678,7 @@ extern int GetSDR(int recid, int *recnext, uchar *sdr, int szsdr, int *slen); extern double RawToFloat(uchar raw, uchar *psdr); extern char *get_unit_type(uchar iunit, uchar ibase, uchar imod, int flg); extern int find_sdr_by_snum(uchar *psdr,uchar *pcache, uchar snum, uchar sa); -extern int GetSensorType(int snum, uchar *stype, uchar *rtype); +extern int GetSensorType(uchar snum, uchar *stype, uchar *rtype); #else static int GetSDR(int recid, int *recnext, uchar *sdr, int szsdr, int *slen) { return(-1); } @@ -688,7 +688,7 @@ static char *get_unit_type(uchar iunit, uchar ibase, uchar imod, int flg) { return(""); }; static int find_sdr_by_snum(uchar *psdr,uchar *pcache, uchar snum, uchar sa) { return(-1); } -static int GetSensorType(int snum, uchar *stype, uchar *rtype) +static int GetSensorType(uchar snum, uchar *stype, uchar *rtype) { return(-1); } #endif #endif diff --git a/util/ifru.c b/util/ifru.c index 9b51aad..c6815ec 100644 --- a/util/ifru.c +++ b/util/ifru.c @@ -2032,6 +2032,13 @@ int i_fru(int argc, char **argv) } if (fdump && ret == 0) { + ret = load_fru(sa,g_fruid,g_frutype,&pfru); + if (ret != 0) { + show_loadfru_error(sa,g_fruid,ret); + free_fru(pfru); + pfru = NULL; + goto do_exit; + } /* Dump FRU to a binary file */ #ifdef WIN32 fp = fopen(binfile,"wb"); diff --git a/util/ilan.c b/util/ilan.c index 161e40e..b8216fb 100644 --- a/util/ilan.c +++ b/util/ilan.c @@ -1001,7 +1001,7 @@ GetUserInfo (uchar unum, uchar chan, uchar * enab, uchar * priv, char *uname, max_users = responseData[0] & 0x3f; enabled_users = responseData[1] & 0x3f; } - upriv = responseData[3]; + upriv = responseData[3] & 0x0F; if ((responseData[1] & 0x80) != 0) *enab = 0; else *enab = 1; inputData[0] = unum; /* usually = 1 for BMC LAN */ diff --git a/util/imb_api.h b/util/imb_api.h index cca3c5f..fc2df3e 100644 --- a/util/imb_api.h +++ b/util/imb_api.h @@ -65,10 +65,11 @@ typedef long wchar_t; #ifndef CONST #define CONST const #endif +#define uchar unsigned char +#define BYTE unsigned char typedef unsigned int UINT32; typedef unsigned long DWORD; typedef int BOOL; -typedef unsigned char BYTE; typedef unsigned short WORD; typedef float FLOAT; typedef FLOAT *PFLOAT; diff --git a/util/imbapi.c b/util/imbapi.c index 3859e0d..07d16ff 100644 --- a/util/imbapi.c +++ b/util/imbapi.c @@ -861,7 +861,7 @@ int ipmi_close_ia(void) int ipmi_cmdraw_ia(BYTE cmd, BYTE netfn, BYTE lun, BYTE sa, BYTE bus, - BYTE *pdata, BYTE sdata, BYTE *presp, int *sresp, + BYTE *pdata, int sdata, BYTE *presp, int *sresp, BYTE *pcc, char fdebugcmd) { IMBPREQUESTDATA requestData; diff --git a/util/ipmicmd.h b/util/ipmicmd.h index 17deca2..8d45c4c 100644 --- a/util/ipmicmd.h +++ b/util/ipmicmd.h @@ -42,6 +42,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define uchar unsigned char #define uint32 unsigned int #define uint64 unsigned long +#define BYTE unsigned char // #ifdef __USE_MISC /* Can use compatibility names for C types. (from sys/types.h) */ // typedef unsigned long int ulong; diff --git a/util/ipmidir.c b/util/ipmidir.c index 0378d46..3d40a4c 100644 --- a/util/ipmidir.c +++ b/util/ipmidir.c @@ -53,7 +53,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* May stub out direct io. For instance, PPC does not support <sys/io.h> */ #define UCHAR unsigned char #define UINT16 unsigned short -int ipmi_open_direct(int fdebugcmd) +int ipmi_open_direct(char fdebugcmd) { return(-1); } int ipmi_close_direct(void) { return(-1); } @@ -389,7 +389,7 @@ static int check_lock_dir(void) return(rv); } -int ipmi_open_direct(int fdebugcmd) +int ipmi_open_direct(char fdebugcmd) { int status = 0; //char *dmsg = ""; diff --git a/util/ipmiutil.c b/util/ipmiutil.c index 409cb9f..09a7fc8 100644 --- a/util/ipmiutil.c +++ b/util/ipmiutil.c @@ -57,7 +57,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ipmiutil.h" static char *progname = "ipmiutil"; -char *progver = "3.19"; +char *progver = "3.21"; // static char fdebug = 0; /*int ipmiutil(int argc, char **argv); */ diff --git a/util/isensor.c b/util/isensor.c index a3fc650..b6432e3 100644 --- a/util/isensor.c +++ b/util/isensor.c @@ -625,7 +625,7 @@ int get_idx_range(char *str) return(0); } -char *get_unit_type(int iunits, int ibase, int imod, int fshort) +char *get_unit_type(uchar iunits, uchar ibase, uchar imod, int fshort) { char *pstr = NULL; char **punittypes; @@ -1332,13 +1332,14 @@ int GetSDR(int r_id, int *r_next, uchar *recdata, int srecdata, int *rlen) if (sresp < (thislen+2)) { /* There are some SDRs that may report the wrong length, and * return less bytes than they reported, so just truncate. */ + fprintf(stderr,"SDR record %x is malformed, length %d is less than minimum %d\n",r_id,sresp,thislen+2); if (fdebug) printf("sdr[%x] off=%d, expected %d, got %d\n", r_id,off,thislen+2,sresp); if (sresp >= 2) thislen = sresp - 2; else thislen = 0; reclen = off + thislen; /* truncate, stop reading */ - fprintf(stderr,"SDR record %x is malformed, length %d is less than minimum %d\n",r_id,sresp,thislen+2); - rc = ERR_SDR_MALFORMED; + /* auto-corrected, so not a fatal error */ + // rc = ERR_SDR_MALFORMED; } /* successful */ memcpy(&resp[off],&respchunk[2],thislen); diff --git a/util/isensor.c-old b/util/isensor.c-old deleted file mode 100644 index eded150..0000000 --- a/util/isensor.c-old +++ /dev/null @@ -1,3907 +0,0 @@ -/* - * isensor.c - * - * This tool reads the SDR records to return sensor information. - * It can use either the Intel /dev/imb driver or VALinux /dev/ipmikcs. - * - * Author: arcress at users.sourceforge.net - * Copyright (c) 2002-2006 Intel Corporation. - * Copyright (c) 2009 Kontron America, Inc. - * - * 07/25/02 Andy Cress created - * 10/09/02 Andy Cress v1.1 added decodeValue(RawToFloat) routine - * 10/11/02 Andy Cress v1.2 added expon routine - * 10/30/02 Andy Cress v1.3 added SDR types 08 & 14 - * 12/04/02 Andy Cress v1.4 changed dstatus descriptions - * 01/29/03 Andy Cress v1.5 added MV OpenIPMI driver support - * Hannes Schulz <schulz@schwaar.com> - * 1) correct raw readings to floatval - * 2) allow extra SDR bytes returned from HP netserver 1000r - * Guo Min <guo.min@intel.com> - * add -l option for simpler list display - * 02/25/03 Andy Cress v1.6 misc cleanup - * 05/02/03 Andy Cress v1.7 add PowerOnHours - * 07/28/03 Andy Cress v1.8 added -t option for threshold values, - * added sample Discovery routine (unfinished), - * added ipmi_getdeviceid for completeness. - * 09/05/03 Andy Cress v1.9 show SDR OEM subtypes, - * fix GetSDR multi-part get for OEM SDRs - * stop if SDR Repository is empty - * 09/23/03 Andy Cress v1.10 Add options to set thresholds - * 10/14/03 Andy Cress v1.11 Fixed sdr offset for ShowThreshold values - * 01/15/04 Andy Cress v1.12 Fixed SetThreshold to set hysteresis, - * Fixed sens_cap testing in ShowThresh(Full) - * 01/30/04 Andy Cress v1.13 Changed field display order, added header, - * check for sdr sz below min, added WIN32. - * 02/19/04 Andy Cress v1.14 Added SDR type 3 parsing for mBMC - * 02/27/04 Andy Cress v1.15 Added check for superuser, more mBMC logic - * 03/11/04 Andy Cress v1.16 Added & removed private mBMC code for set - * thresholds due to licensing issues - * 04/13/04 Andy Cress v1.17 Added -r to show raw SDRs also - * 05/05/04 Andy Cress v1.18 call ipmi_close before exit, - * fix sresp in GetSDR for WIN32. - * 07/07/04 Andy Cress v1.19 Added -a to reArm sensor, - * show debug raw reading values only in hex - * 08/18/04 Andy Cress v1.20 Added decoding for DIMM status - * 11/01/04 Andy Cress v1.21 add -N / -R for remote nodes, - * added -U for remote username - * 11/19/04 Andy Cress v1.22 added more decoding for compact reading types, - * added -w option to wrap thresholds - * 11/24/04 ARCress v1.23 added sens_type to display output - * 12/10/04 ARCress v1.24 added support for device sdrs also, - * fixed sens_cap byte, - * 01/10/05 ARCress v1.25 change ShowThresh order, highest to lowest, - * change signed exponent type in RawToFloat - * 01/13/05 ARCress v1.26 added time display if fwrap - * 01/28/05 ARCress v1.27 mod for Power Redundancy SDR status - * 02/15/05 ARCress v1.28 added FloatToRaw for -h/-l threshold set funcs, - * always take -n sensor_num as hex (like displayed) - * 03/07/05 ARCress v1.29 added "LAN Leash Lost" decoding in decode_comp_ - * added -v to show max/min & hysteresis. - * 03/22/05 ARCress v1.30 added OEM subtype 0x60 for BMC TAM - * 03/26/05 ARCress v1.31 added battery type to decode_comp_reading - * 04/21/05 ARCress v1.32 added error message if -n sensor_num not found, - * added more decoding for Power Redund sensor - * 06/20/05 ARCress v1.33 if GetSDRRepository cc=0xc1 switch fdevsdrs mode, - * also detect fdevsdrs better for ATCA. - * 07/28/05 ARCress v1.34 check for Reading init state, - * add extra byte to decode_comp_reading() - * 09/12/05 ARCress v1.35 don't check superuser for fipmi_lan - * 01/26/06 ARCress v1.36 added -i option to only show one sensor index - * 03/14/06 ARCress v1.37 added -p option to save persistent thresholds - * 04/06/06 ARCress v1.38 show auto/manual rearm - * 07/17/06 ARCress v1.39 add -V, add -L, handle RepInfo rc=0xc1 - * 11/28/06 ARCress v1.46 added -c -m for ATCA child MCs - * 08/15/07 ARCress v1.58 filter display if -n sensor_num - * 08/29/07 ARCress v1.59 fixed Battery sensor interpretation - * 10/31/07 ARCress v2.3 retry GetSDR if cc=0xC5 (lost reservationID) - * 01/14/08 ARCress v2.6 add -u param for setting unique thresholds, - * always show float when setting thresholds, - * fixup in decoding Proc,PS Comp readings - * 01/25/08 ARCress v2.7 allow float input with -u thresholds, - * add -p persist logic for -u thresholds. - * 09/20/19 ARCress v3.15 workaround for Pigeon Point bad sa in SDR - */ -/*M* -Copyright (c) 2002-2006 Intel Corporation. -Copyright (c) 2009 Kontron America, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - a.. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - b.. Redistributions 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. - c.. Neither the name of Intel nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *M*/ -#include <stdio.h> -#include <stdlib.h> -#include <math.h> // for: double pow(double x, double y); -#include <string.h> -#include <time.h> -#ifdef WIN32 -#include <windows.h> -#include "getopt.h" -#elif defined(DOS) -#include <dos.h> -#include "getopt.h" -#else -#include <sys/stat.h> -#if defined(HPUX) -/* getopt is defined in stdio.h */ -#elif defined(MACOS) -/* getopt is defined in unistd.h */ -#include <unistd.h> -#else -#include <getopt.h> -#endif -#endif -#if defined(LINUX) -#include <unistd.h> -#include <sys/types.h> -#endif -#include "ipmicmd.h" -#include "isensor.h" - -#define PICMG_CHILD 1 /* show child MCs if -b */ -#define MIN_SDR_SZ 8 -#define SZCHUNK 16 /* SDR chunksize was 8, now 16 */ -#define INIT_SNUM 0xff -#define N_SGRP 16 -#define THR_EMPTY 999 - -/* prototypes */ -int get_LastError( void ); /* ipmilan.c */ -extern int use_devsdrs(int picmg); /* ipmicmd.c */ -extern int get_MemDesc(int array, int dimm, char *desc, int *psz); /*mem_if.c*/ -extern char *get_sensor_type_desc(uchar stype); /*ievents.c*/ -#ifdef METACOMMAND -#include "oem_intel.h" -/* void show_oemsdr_intel(uchar *sdr); in oem_intel.h */ -/* int decode_sensor_intel(); in oem_intel.h */ -/* int is_romley(int vend, int prod); in oem_intel.h */ -extern int decode_sensor_kontron(uchar *sdr,uchar *reading,char *pstring, - int slen); /*see oem_kontron.c*/ -extern int decode_sensor_fujitsu(uchar *sdr,uchar *reading,char *pstring, - int slen); /*see oem_fujitsu.c*/ -extern int decode_sensor_sun(uchar *sdr,uchar *reading,char *pstring, - int slen); /*see oem_sun.c*/ -extern int decode_sensor_supermicro(uchar *sdr,uchar *reading,char *pstring, - int slen, int fsimple, char fdbg); /*see oem_supermicro.c*/ -extern int decode_sensor_quanta(uchar *sdr,uchar *reading,char *pstring, - int slen); /*see oem_quanta.c*/ -extern int decode_sensor_dell(uchar *sdr,uchar *reading,char *pstring, - int slen); /*see oem_dell.c*/ -extern int decode_sensor_lenovo(uchar *sdr,uchar *reading,char *pstring, - int slen); /*see oem_lenovo.c*/ -extern int decode_sensor_asus(uchar *sdr,uchar *reading,char *pstring,int slen); -extern int decode_sensor_hp(uchar *sdr,uchar *reading,char *pstring, - int slen); /*see oem_hp.c*/ -extern void show_oemsdr_hp(uchar *sdr); -#else -int is_romley(int vend, int prod) { - if ((vend == VENDOR_INTEL) && ((prod >= 0x0048) && (prod <= 0x005e))) - return(1); - return(0); -} -int is_grantley(int vend, int prod) { - if ((vend == VENDOR_INTEL) && (prod == 0x0071)) - return(1); - return(0); -} -int is_thurley(int vend, int prod) { - if ((vend == VENDOR_INTEL) && ((prod >= 0x003A) && (prod <= 0x0040))) - return(1); - return(0); -} -#endif -#ifdef ALONE -#define NENTID 53 -static char *entity_id_str[NENTID] = { -/* 00 */ "unspecified", -/* 01 */ "other", -/* 02 */ "unknown", -/* 03 */ "processor", -/* 04 */ "disk", -/* 05 */ "peripheral bay", -/* 06 */ "management module", -/* 07 */ "system board", -/* 08 */ "memory module", -/* 09 */ "processor module", -/* 10 */ "power supply", -/* 11 */ "add-in card", -/* 12 */ "front panel bd", -/* 13 */ "back panel board", -/* 14 */ "power system bd", -/* 15 */ "drive backplane", -/* 16 */ "expansion board", -/* 17 */ "Other system board", -/* 18 */ "processor board", -/* 19 */ "power unit", -/* 20 */ "power module", -/* 21 */ "power distr board", -/* 22 */ "chassis back panel bd", -/* 23 */ "system chassis", -/* 24 */ "sub-chassis", -/* 25 */ "Other chassis board", -/* 26 */ "Disk Drive Bay", -/* 27 */ "Peripheral Bay", -/* 28 */ "Device Bay", -/* 29 */ "fan", -/* 30 */ "cooling unit", -/* 31 */ "cable/interconnect", -/* 32 */ "memory device ", -/* 33 */ "System Mgt Software", -/* 34 */ "BIOS", -/* 35 */ "Operating System", -/* 36 */ "system bus", -/* 37 */ "Group", -/* 38 */ "Remote Mgt Comm Device", -/* 39 */ "External Environment", -/* 40 */ "battery", -/* 41 */ "Processing blade", -/* 43 */ "Processor/memory module", -/* 44 */ "I/O module", -/* 45 */ "Processor/IO module", -/* 46 */ "Mgt Controller Firmware", -/* 47 */ "IPMI Channel", -/* 48 */ "PCI Bus", -/* 49 */ "PCI Express Bus", -/* 50 */ "SCSI Bus", -/* 51 */ "SATA/SAS bus", -/* 52 */ "Processor FSB" -}; -char *decode_entity_id(int id) { - if (id < NENTID) return (""); - else return(entity_id_str[id]); } -#else -/* char *decode_entity_id(int id); *isensor.h, from ievents.c*/ -#endif -/************************ - * Global Data - ************************/ -#ifdef METACOMMAND -extern char * progver; /*from ipmiutil.c*/ -static char * progname = "ipmiutil sensor"; -#else -static char * progver = "3.15"; -static char * progname = "isensor"; -#endif -#ifdef WIN32 -static char savefile[] = "%ipmiutildir%\\thresholds.cmd"; -#else -static char savefile[] = "/var/lib/ipmiutil/thresholds.sh"; -// static char savefile[] = "/usr/share/ipmiutil/thresholds.sh"; -#endif -extern char fdebug; /*from ipmicmd.c*/ -int sens_verbose = 0; /* =1 show max/min & hysteresis also */ -static int fdevsdrs = 0; -static int fReserveOK = 1; -static int fDoReserve = 1; -static int fsimple = 0; /*=1 simple, canonical output*/ -static int fshowthr = 0; /* =1 show thresholds, =2 show thr in ::: fmt */ -static int fwrap = 0; -static int frawsdr = 0; -static int frearm = 0; -static int fshowidx = 0; /* only show a specific SDR index/range */ -static int fshowgrp = 0; /* =1 show group of sensors by sensor type */ -static int fdoloop = 0; /* =1 if user specified number of loops */ -static int fpicmg = 0; -static int fchild = 0; /* =1 show child SDRs */ -static int fset_mc = 0; /* =1 -m to set_mc */ -static int fbadsdr = 0; /* =1 to ignore bad SDR mc */ -static int fdump = 0; -static int frestore = 0; -static int fjumpstart = 0; -static int fgetmem = 0; -static int fprivset = 0; -static char fremote = 0; -static int nloops = 1; /* num times to show repeated sensor readings */ -static int loopsec = 1; /* wait N sec between loops, default 1 */ -static char bdelim = BDELIM; /* delimiter for canonical output */ -static char tmpstr[20]; /* temp string */ -static char *binfile = NULL; -static int fsetthresh = 0; -static int fsavethresh = 0; -static uchar sensor_grps[N_SGRP] = {0, 0}; /*sensor type groups*/ -static ushort sensor_idx1 = 0xffff; -static ushort sensor_idxN = 0xffff; -static uchar sensor_num = INIT_SNUM; -static uchar sensor_hi = 0xff; -static uchar sensor_lo = 0xff; -static uchar sensor_thr[6] = {0,0,0,0,0,0}; -static double sensor_thrf[6] = {0,0,0,0,0,0}; -static double sensor_hi_f = 0; -static double sensor_lo_f = 0; -static int fmBMC = 0; -static int fRomley = 0; -static int fGrantley = 0; -static char chEol = '\n'; /* newline by default, space if option -w */ -static uchar resid[2] = {0,0}; -static uchar g_bus = PUBLIC_BUS; -static uchar g_sa = 0; -static uchar g_lun = BMC_LUN; -static uchar g_addrtype = ADDR_SMI; -static int vend_id = 0; -static int prod_id; - -/* sensor_dstatus - * This is used to decode the sensor reading types and meanings. - * Use IPMI Table 36-1 and 36-2 for this. - */ -#define N_DSTATUS 101 -#define STR_CUSTOM 58 -#define STR_OEM 71 -#define STR_AC_LOST 76 -#define STR_PS_FAIL 77 -#define STR_PS_CONFIG 78 -#define STR_HSC_OFF 79 -#define STR_REBUILDING 80 -#define STR_OTHER 81 -static char oem_string[50] = "OEM"; -static char *sensor_dstatus[N_DSTATUS] = { -/* 0 00h */ "OK ", -/* Threshold event states */ -/* 1 01h */ "Warn-lo", // "Warning-lo", -/* 2 02h */ "Crit-lo", // "Critical-lo", -/* 3 04h */ "BelowCrit", // "BelowCrit-lo", -/* 4 08h */ "Warn-hi", // "Warning-hi", -/* 5 10h */ "Crit-hi", // "Critical-hi", -/* 6 20h */ "AboveCrit", // "AboveCrit-hi", -/* 7 40h */ "Init ", /*in init state, no reading*/ -/* 8 80h */ "OK* ", -/* Hotswap Controller event states, also Availability */ -/* 9 HSC */ "Present", /*present,inserted*/ -/*10 HSC */ "Absent", /*absent,removed,empty,missing*/ -/*11 HSC */ "Ready", -/*12 HSC */ "Faulty", -/* Digital/Discrete event states */ -/*13 D-D */ "Asserted", -/*14 D-D */ "Deassert", -/*15 D-D */ "Predict ", -/* Availability event states */ -/*16 Avl */ "Disabled", -/*17 Avl */ "Enabled ", -/*18 Avl */ "Redundant", -/*19 Avl */ "RedunLost", -/*20 Avl */ "RedunDegr", -/* ACPI Device Power States */ -/*21 ACPI*/ "Off ", /*D3*/ -/*22 ACPI*/ "Working", /*D1*/ -/*23 ACPI*/ "Sleeping", /*D2/S2*/ -/*24 ACPI*/ "On", /*D0*/ -/* Critical Interrupt event states */ -/*25 CrI */ "FP_NMI ", -/*26 CrI */ "Bus_TimOut", -/*27 CrI */ "IOch_NMI", -/*28 CrI */ "SW_NMI ", -/*29 CrI */ "PCI_PERR", -/*30 CrI */ "PCI_SERR", -/*31 CrI */ "EISA_TimOut", -/*32 CrI */ "Bus_Warn ", /*Correctable*/ -/*33 CrI */ "Bus_Error", /*Uncorrectable*/ -/*34 CrI */ "Fatal_NMI", -/*35 CrI */ "Bus_Fatal", /*0x0A*/ -/*36 CrI */ "Bus_Degraded", /*0x0B*/ -/* Physical Security event states */ -/*37 Phys*/ "LanLeashLost", -/*38 Phys*/ "ChassisIntrus", -/* Memory states */ -/*39 Mem */ "ECCerror", -/*40 Mem */ "ParityErr", -/* Discrete sensor invalid readings (error or init state) */ -/*41 D-D */ "Unknown", -/*42 D-D */ "NotAvailable", -/* Discrete sensor OEM reading states */ -/*43 OEM */ "Enabled ", -/*44 OEM */ "Disabled", -/* Session Audit states */ -/*45 OEM */ "Activated ", -/*46 OEM */ "Deactivated", -/*47 HSC */ "Unused ", -/* Processor event states */ -/*48 Proc*/ "IERR", -/*49 Proc*/ "ThermalTrip", -/*50 Proc*/ "FRB1Failure", -/*51 Proc*/ "FRB2Failure", -/*52 Proc*/ "FRB3Failure", -/*53 Proc*/ "ConfigError", -/*54 Proc*/ "SMBIOSError", -/*55 Proc*/ "ProcPresent", -/*56 Proc*/ "ProcDisabled", -/*57 Proc*/ "TermPresent", -/* Custom data string, 15 bytes */ -/*58 Custom*/ "CustomData12345", -/* Event Log */ -/*59 EvLog*/ "MemLogDisab", -/*60 EvLog*/ "TypLogDisab", -/*61 EvLog*/ "LogCleared", -/*62 EvLog*/ "AllLogDisab", -/*63 EvLog*/ "SelFull", -/*64 EvLog*/ "SelNearFull", -/* more Digital Discrete */ -/*65 D-D */ "Exceeded", -/*66 Alert*/ "AlertPage", -/*67 Alert*/ "AlertLAN", -/*68 Alert*/ "AlertPET", -/*69 Alert*/ "AlertSNMP", -/*70 Alert*/ "None", -/*71 OEM str*/ &oem_string[0], -/* Version Change */ -/*72 Change*/ "HW Changed", -/*73 Change*/ "SW Changed", -/*74 Change*/ "HW incompatibility", -/*75 Change*/ "Change Error", -/* Power Supply event states */ -/*76 PS */ "AC_Lost ", -/*77 PS */ "PS_Failed", -/* Power Supply event states */ -/*78 PS */ "Config_Err", -/*79 HSC */ "Offline", -/*80 HSC */ "Rebuilding", -/*81 other*/ " _ ", -/*82 Avl */ "NonRedund_Sufficient", -/*83 Avl */ "NonRedund_Insufficient", -/*84 Usage */ "Idle", -/*85 Usage */ "Active", -/*86 Usage */ "Busy", -/*87 Trans */ "Non-Critical", -/*88 Trans */ "Critical", -/*89 Trans */ "Non-Recoverable", -/*90 Trans */ "Monitor", -/*91 Trans */ "Informational", -/*92 State */ "Running", -/*93 State */ "In_Test", -/*94 State */ "Power_Off", -/*95 State */ "Online", -/*96 State */ "Offline", -/*97 State */ "Off_Duty", -/*98 State */ "Degraded", -/*99 State */ "PowerSave", -/*100 State */ "InstallError" -}; - -static char *raid_states[9] = { /*for sensor type 0x0d drive status */ - "Faulty", - "Rebuilding", - "InFailedArray", - "InCriticalArray", - "ParityCheck", - "PredictedFault", - "Un-configured", - "HotSpare", - "NoRaid" }; - -#define NSENSTYPES 0x2a -#ifdef OLD -/* see ievents.c */ -static const char *sensor_types[NSENSTYPES] = { /*IPMI 2.0 Table 42-3*/ -/* 00h */ "reserved", -/* 01h */ "Temperature", -/* 02h */ "Voltage", -/* 03h */ "Current", -/* 04h */ "Fan", -/* 05h */ "Platform Chassis Intrusion", -/* 06h */ "Platform Security Violation", -/* 07h */ "Processor", -/* 08h */ "Power Supply", -/* 09h */ "Power Unit", -/* 0Ah */ "Cooling Device", -/* 0Bh */ "FRU Sensor", -/* 0Ch */ "Memory", -/* 0Dh */ "Drive Slot", -/* 0Eh */ "POST Memory Resize", -/* 0Fh */ "System Firmware", -/* 10h */ "SEL Disabled", -/* 11h */ "Watchdog 1", -/* 12h */ "System Event", /* offset 0,1,2 */ -/* 13h */ "Critical Interrupt", /* offset 0,1,2 */ -/* 14h */ "Button", /* offset 0,1,2 */ -/* 15h */ "Board", -/* 16h */ "Microcontroller", -/* 17h */ "Add-in Card", -/* 18h */ "Chassis", -/* 19h */ "Chip Set", -/* 1Ah */ "Other FRU", -/* 1Bh */ "Cable / Interconnect", -/* 1Ch */ "Terminator", -/* 1Dh */ "System Boot Initiated", -/* 1Eh */ "Boot Error", -/* 1Fh */ "OS Boot", -/* 20h */ "OS Critical Stop", -/* 21h */ "Slot / Connector", -/* 22h */ "ACPI Power State", -/* 23h */ "Watchdog 2", -/* 24h */ "Platform Alert", -/* 25h */ "Entity Presence", -/* 26h */ "Monitor ASIC", -/* 27h */ "LAN", -/* 28h */ "Management Subsystem Health", -/* 29h */ "Battery", -}; -#endif - -#define NUNITS 30 -static char *unit_types[] = { -/* 00 */ "unspecified", -/* 01 */ "degrees C", -/* 02 */ "degrees F", -/* 03 */ "degrees K", -/* 04 */ "Volts", -/* 05 */ "Amps", -/* 06 */ "Watts", -/* 07 */ "Joules", -/* 08 */ "Coulombs", -/* 09 */ "VA", -/* 10 */ "Nits", -/* 11 */ "lumen", -/* 12 */ "lux", -/* 13 */ "Candela", -/* 14 */ "kPa", -/* 15 */ "PSI", -/* 16 */ "Newton", -/* 17 */ "CFM", -/* 18 */ "RPM", -/* 19 */ "Hz", -/* 20 */ "microseconds", -/* 21 */ "milliseconds", -/* 22 */ "seconds", -/* 23 */ "minutes", -/* 24 */ "hours", -/* 25 */ "days", -/* 26 */ "weeks", -/* 27 */ "mil", -/* 28 */ "inches", -/* 29 */ "feet", -/* 42 */ "cycles" -}; -/* 68 * "megabit", */ -/* 72 * "megabyte", */ -/* 90 * "uncorrectable error" (last defined)*/ -static char *unit_types_short[] = { -/* 00 */ "?", /*unknown, not specified*/ -/* 01 */ "C", -/* 02 */ "F", -/* 03 */ "K", -/* 04 */ "V", -/* 05 */ "A", -/* 06 */ "W", -/* 07 */ "J", -/* 08 */ "Coul", -/* 09 */ "VA", -/* 10 */ "Nits", -/* 11 */ "lumen", -/* 12 */ "lux", -/* 13 */ "Cand", -/* 14 */ "kPa", -/* 15 */ "PSI", -/* 16 */ "Newton", -/* 17 */ "CFM", -/* 18 */ "RPM", -/* 19 */ "Hz", -/* 20 */ "usec", -/* 21 */ "msec", -/* 22 */ "sec", -/* 23 */ "min", -/* 24 */ "hrs", -/* 25 */ "days", -/* 26 */ "wks", -/* 27 */ "mil", -/* 28 */ "in", -/* 29 */ "ft", -/* 42 */ "cyc" -}; - -ushort parse_idx(char *str) -{ - int i, n; - char istr[5]; - if (strncmp(str,"0x",2) == 0) str += 2; - n = strlen_(str); - if (n == 4) { - i = (htoi(str) << 8) + htoi(&str[2]); - } else if (n == 3) { - istr[0] = '0'; - memcpy(&istr[1],str,3); - i = (htoi(istr) << 8) + htoi(&istr[2]); - } else i = htoi(str); /*was atoi()*/ - printf("idx = 0x%x\n",i); - return((ushort)i); -} - -int get_idx_range(char *str) -{ - // int i = 0; - char *p; - p = strchr(str,'-'); - if (p == NULL) p = strchr(str,','); - if (p != NULL) { - *p = 0; - p++; - sensor_idx1 = parse_idx(str); - sensor_idxN = parse_idx(p); - } else { - sensor_idx1 = parse_idx(str); - sensor_idxN = sensor_idx1; - } - return(0); -} - -char *get_unit_type(int iunits, int ibase, int imod, int fshort) -{ - char *pstr = NULL; - char **punittypes; - static char unitstr[32]; - int jbase, jmod; - uchar umod; - - punittypes = unit_types; - if (fshort) punittypes = unit_types_short; - if (fdebug) printf("get_unit_type(%x,%d,%d,%d)\n",iunits,ibase,imod,fshort); - umod = (iunits & 0x06) >> 1; - if (ibase < NUNITS) jbase = ibase; - else { - if (fdebug) printf("units base %02x > %d\n",ibase,NUNITS); - if (ibase == 42) jbase = NUNITS; /*"cycles"*/ - else jbase = 0; - } - if (imod < NUNITS) jmod = imod; - else { - if (fdebug) printf("units mod %02x > %d\n",imod,NUNITS); - jmod = 0; - } - switch (umod) { - case 2: - snprintf(unitstr,sizeof(unitstr),"%s * %s", - punittypes[jbase],punittypes[jmod]); - pstr = unitstr; - break; - case 1: - snprintf(unitstr,sizeof(unitstr),"%s/%s", - punittypes[jbase],punittypes[jmod]); - pstr = unitstr; - break; - case 0: - default: - pstr = punittypes[jbase]; - break; - } - if ((umod == 0) && (iunits > 0)) { - /* special cases for other SensorUnits1 bits */ - if ((iunits & 0x01) != 0) { /*percentage*/ - if (fshort) pstr = "%"; - else pstr = "percent"; - } else if (iunits == 0xC0) { /*no analog reading*/ - pstr = "na"; - } else if (iunits == 0x18) { - /* For Tyan fans: base=42, units=24.(0x18) -> cycles/hour */ - snprintf(unitstr,sizeof(unitstr),"%s/hour",punittypes[jbase]); - pstr = unitstr; - } - } - return(pstr); -} - -char *decode_capab(uchar c) -{ - static char cstr[50]; - char *arm; - char *thr; - char *evt; - // char *hys; - uchar b; - /* decode sens_capab bits */ - if ((c & 0x40) == 0) arm = "man"; /*manual rearm*/ - else arm = "auto"; /*automatic rearm*/ - /* skip hysteresis bits (0x30) */ - b = ((c & 0x0c) >> 2); - switch(b) { - case 0x00: thr = "none"; break; /*no thresholds*/ - case 0x01: thr = "read"; break; - case 0x02: thr = "write"; break; /*read & write*/ - case 0x03: - default: thr = "fixed"; break; - } - b = (c & 0x03) ; - switch(b) { - case 0x00: evt = "state"; break; /*threshold or discrete state*/ - case 0x01: evt = "entire"; break; /*entire sensor only*/ - case 0x02: evt = "disab"; break; /*global disable only*/ - case 0x03: - default: evt = "none"; break; /*no events*/ - } - sprintf(cstr,"arm=%s thr=%s evts=%s",arm,thr,evt); - return(cstr); -} - - -int get_group_id(char *pstr) -{ - int i, j, n, sz, len; - char *p; - int rv = -1; - - sz = strlen_(pstr); - p = &pstr[0]; - n = 0; - for (i = 0; i <= sz; i++) { - if (n >= N_SGRP) break; - switch(pstr[i]) { - case ',': /*delimiter*/ - case '\n': - case '\0': - pstr[i] = 0; /*stringify this word*/ - len = strlen_(p); - for (j = 0; j < NSENSTYPES; j++) { - if (strncasecmp(get_sensor_type_desc(j),p,len) == 0) { - sensor_grps[n++] = (uchar)j; - rv = 0; - break; - } - } /*endfor(j)*/ - if (i+1 < sz) p = &pstr[i+1]; /*set p for next word*/ - if (j >= NSENSTYPES) { /* sensor type not found */ - rv = -1; - i = sz; /*exit loop*/ - } - break; - default: - break; - } /*end switch*/ - } /*end for(i)*/ - if (rv == 0) rv = n; - else rv = -1; - return(rv); -} - -static int validate_thresholds(void *pthrs, char flag, uchar *sdr) -{ - double *thrf; - uchar *thr; - int rv = 0; - uchar bits; - - if (sdr == NULL) bits = 0xff; /*assume all are used*/ - else bits = sdr[18]; /*18=indicates which are readable/used */ - - if (bits == 0) { - printf("No threshold values can be set for this sensor.\n"); - return(3); - } - if (flag == 1) { /*float*/ - thrf = (double *)pthrs; - if (fdebug) - printf("validate_thresh: bits=%02x, values: %f>=%f>=%f, %f<=%f<=%f\n", - bits, thrf[0],thrf[1],thrf[2], thrf[3],thrf[4],thrf[5]); - if ((bits & 0x02) != 0) { /*thrf[1] lo-crit is valid*/ - if ((thrf[1] > thrf[0]) && ((bits & 0x01) != 0)) rv = 1; - if ((thrf[2] > thrf[1]) && ((bits & 0x04) != 0)) rv = 1; /*lo is wrong*/ - } - if ((bits & 0x10) != 0) { /*thrf[4] hi-crit is valid*/ - if ((thrf[4] < thrf[3]) && ((bits & 0x08) != 0)) rv = 2; - if ((thrf[5] < thrf[4]) && ((bits & 0x20) != 0)) rv = 2; /*hi is wrong*/ - } - if (rv != 0) { - printf("Threshold values: %f>=%f>=%f, %f<=%f<=%f\n", - thrf[0], thrf[1], thrf[2], thrf[3], thrf[4], thrf[5]); - printf("Invalid threshold order in %s range.\n", - ((rv == 1)? "lo": "hi")); - } - } else { - thr = (uchar *)pthrs; - if ((bits & 0x02) != 0) { /*thr[1] lo-crit is valid*/ - if ((thr[1] > thr[0]) && ((bits & 0x01) != 0)) rv = 1; - if ((thr[2] > thr[1]) && ((bits & 0x04) != 0)) rv = 1; /*lo is wrong*/ - } - if ((bits & 0x10) != 0) { /*thr[4] hi-crit is valid*/ - if ((thr[4] < thr[3]) && ((bits & 0x08) != 0)) rv = 2; - if ((thr[5] < thr[4]) && ((bits & 0x20) != 0)) rv = 2; /*hi is wrong*/ - } - if (rv != 0) { - printf("Threshold values: %02x>=%02x>=%02x %02x<=%02x<=%02x\n", - thr[0], thr[1], thr[2], thr[3], thr[4], thr[5]); - printf("Invalid threshold order within -u (%s)\n", - ((rv == 1)? "lo": "hi")); - } - } - return(rv); -} - -int -GetSDRRepositoryInfo(int *nret, int *fdev) -{ - uchar resp[MAX_BUFFER_SIZE]; - int sresp = MAX_BUFFER_SIZE; - int rc; - int nSDR; - int freespace; - ushort cmd; - uchar cc = 0; - int i; - - memset(resp,0,6); /* init first part of buffer */ - if (nret != NULL) *nret = 0; - if (fdev != NULL) fdevsdrs = *fdev; - if (fdevsdrs) cmd = GET_DEVSDR_INFO; - else cmd = GET_SDR_REPINFO; - rc = ipmi_cmd_mc(cmd, NULL, 0, resp,&sresp, &cc, fdebug); - if (fdebug) printf("ipmi_cmd[%04x] repinf(%d) status=%d cc=%x\n", - cmd, fdevsdrs,rc,cc); - /* some drivers return cc in rc */ - if ((rc == 0xc1) || (rc == 0xd4)) cc = rc; - else if (rc != 0) return(rc); - if (cc != 0) { - if ((cc == 0xc1) || /*0xC1 (193.) means unsupported command */ - (cc == 0xd4)) /*0xD4 means insufficient privilege (Sun/HP)*/ - { - /* Must be reporting wrong bit for fdevsdrs, - * so switch & retry */ - if (fdevsdrs) { - fdevsdrs = 0; - cmd = GET_SDR_REPINFO; - } else { - fdevsdrs = 1; - cmd = GET_DEVSDR_INFO; - } - sresp = MAX_BUFFER_SIZE; - rc = ipmi_cmd_mc(cmd, NULL, 0, resp,&sresp, &cc, fdebug); - if (fdebug) - printf("ipmi_cmd[%04x] repinf status=%d cc=%x\n",cmd,rc,cc); - if (rc != ACCESS_OK) return(rc); - if (cc != 0) return(cc); - } else return(cc); - } - - if (fdevsdrs) { - nSDR = resp[0]; - freespace = 1; - fReserveOK = 1; - } else { - nSDR = resp[1] + (resp[2] << 8); - freespace = resp[3] + (resp[4] << 8); - if ((resp[13] & 0x02) == 0) fReserveOK = 0; - else fReserveOK = 1; - } - if (nret != NULL) *nret = nSDR; - if (fdev != NULL) *fdev = fdevsdrs; - if (fdebug) { - //successful, show data - printf("SDR Repository (len=%d): ",sresp); - for (i = 0; i < sresp; i++) printf("%02x ",resp[i]); - printf("\n"); - printf("SDR Info: fdevsdrs=%d nSDRs=%d free space = %x ReserveOK=%d\n", - fdevsdrs,nSDR,freespace,fReserveOK); - } - - return(0); -} /*end GetSDRRepositoryInfo()*/ - - -int -GetSensorThresholds(uchar sens_num, uchar *thr_data) -{ - uchar resp[MAX_BUFFER_SIZE]; - int sresp = MAX_BUFFER_SIZE; - uchar inputData[6]; - int rc; - uchar cc = 0; - - inputData[0] = sens_num; - rc = ipmi_cmd_mc(GET_SENSOR_THRESHOLD, inputData,1, resp,&sresp, &cc,fdebug); - if (fdebug) - printf("GetSensorThreshold[%02x] rc = %d, resp(%d) %02x %02x %02x %02x %02x %02x %02x\n", - sens_num,rc, sresp,resp[0],resp[1],resp[2],resp[3], - resp[4],resp[5],resp[6]); - if (rc != ACCESS_OK) return(rc); - if (cc != 0) return(cc); - if (sresp == 0) return(-2); - memcpy(thr_data,resp,sresp); - return(0); -} - -int -RearmSensor(uchar sens_num) -{ - uchar resp[MAX_BUFFER_SIZE]; - int sresp = MAX_BUFFER_SIZE; - uchar inputData[8]; - int rc; - uchar cc = 0; - - memset(inputData,0,6); - memset(resp,0,6); - inputData[0] = sens_num; - rc = ipmi_cmd_mc(GET_SEVT_ENABLE, inputData, 1, resp,&sresp, &cc, fdebug); - if (rc == 0 && cc != 0) rc = cc; - if (rc != 0 || fdebug) - printf("GetSensorEventEnable(%02x) rc = %d, cc = %x %02x %02x %02x\n", - sens_num,rc,cc,resp[0],resp[1],resp[3]); - if (rc == 0 && resp[0] != 0xc0) { - printf("EventEnable(%02x) = %02x, is not 0xc0\n", - sens_num,resp[0]); - memset(inputData,0,6); - inputData[0] = sens_num; - inputData[1] = resp[0] | 0xc0; - inputData[2] = resp[1]; - inputData[3] = resp[2]; - inputData[4] = resp[3]; - inputData[5] = resp[4]; - rc = ipmi_cmd_mc(SET_SEVT_ENABLE, inputData, 6, resp,&sresp, - &cc, fdebug); - if (rc == 0 && cc != 0) rc = cc; - if (rc != 0 || fdebug) - printf("SetSensorEventEnable(%02x) rc = %d, cc = %x\n", - sens_num,rc,cc); - } - - memset(inputData,0,6); - inputData[0] = sens_num; - inputData[1] = 0; /* rearm all events for this sensor */ - rc = ipmi_cmd_mc(REARM_SENSOR, inputData, 6, resp,&sresp, &cc, fdebug); - if (fdebug) - printf("RearmSensor(%02x) rc = %d, cc = %x %02x %02x\n", - sens_num,rc,cc,resp[0],resp[1]); - if (rc == 0 && cc != 0) rc = cc; - - /* Could also do a global rearm via SetEventReceiver. */ - - return(rc); -} /*end RearmSensor*/ - -int -SetSensorThresholds(uchar sens_num, uchar hi, uchar lo, - uchar *thr_data, uchar *thr_set) -{ - uchar resp[MAX_BUFFER_SIZE]; - int sresp = MAX_BUFFER_SIZE; - uchar inputData[8]; - int rc; - uchar cc = 0; - uchar sets = 0; - int i; - - /* - * Set the sensor Hysteresis before setting the threshold. - */ - memset(inputData,0,8); - inputData[0] = sens_num; - inputData[1] = 0xff; - rc = ipmi_cmd_mc(GET_SENSOR_HYSTERESIS,inputData,2, resp,&sresp, &cc,fdebug); - if (fdebug) - printf("GetSensorHysteresis(%02x) rc = %d, cc = %x %02x %02x\n", - sens_num,rc,cc,resp[0],resp[1]); - if (rc != ACCESS_OK) return(rc); - inputData[0] = sens_num; - inputData[1] = 0xff; - inputData[2] = resp[0]; - inputData[3] = resp[1]; - rc = ipmi_cmd_mc(SET_SENSOR_HYSTERESIS,inputData,4, resp,&sresp, &cc,fdebug); - if (fdebug) - printf("SetSensorHysteresis(%02x) rc = %d, cc = %x\n", - sens_num,rc,cc); - if (rc != ACCESS_OK) return(rc); - - /* - * The application should validate that values are ordered, - * e.g. upper critical should be greater than upper - * non-critical. - * Due to the limited command line parameter interface, - * use the hi & lo values to set each of the thresholds. - * For a full implemenation, these thresholds should be set - * individually. - */ - memset(inputData,0,8); - inputData[0] = sens_num; - sets = thr_data[0]; - if (thr_set != NULL) { /* use specific thr_set values */ - memcpy(&inputData[2],thr_set,6); - } else { /*default, use hi/lo params */ - if (lo == 0xff) sets &= 0x38; /* don't set lowers */ - else { - inputData[2] = lo; /* lower non-crit (& 0x01) */ - inputData[3] = lo - 1; /* lower critical (& 0x02) */ - inputData[4] = lo - 2; /* lower non-recov (& 0x04) */ - } - if (hi == 0xff) sets &= 0x07; /* don't set uppers */ - else { - inputData[5] = hi; /* upper non-crit (& 0x08) */ - inputData[6] = hi + 1; /* upper critical (& 0x10) */ - inputData[7] = hi + 2; /* upper non-recov (& 0x20) */ - } - } - inputData[1] = sets; /* which ones to set */ - { /* show from/to changes */ - printf("GetThreshold[%02x]: %02x ",sens_num,sens_num); - for (i = 0; i < 7; i++) printf("%02x ",thr_data[i]); - printf("\n"); - printf("SetThreshold[%02x]: ",sens_num); - for (i = 0; i < 8; i++) printf("%02x ",inputData[i]); - printf("\n"); - } - rc = ipmi_cmd_mc(SET_SENSOR_THRESHOLD, inputData, 8, resp,&sresp, &cc, fdebug); - if (fdebug) - printf("SetSensorThreshold(%02x) rc = %d, cc = %x\n", - sens_num,rc,cc); - if (rc == 0 && cc != 0) rc = cc; - /* mBMC gets cc = 0xD5 (213.) here, setting thresholds disabled. */ - return(rc); -} - -int -GetSensorReading(uchar sens_num, void *psdr, uchar *sens_data) -{ - uchar resp[MAX_BUFFER_SIZE]; - int sresp = MAX_BUFFER_SIZE; - uchar inputData[6]; - SDR02REC *sdr = NULL; - int mc; - int rc; - uchar cc = 0; - uchar lun = 0; - uchar chan = 0; - - if (psdr != NULL && fbadsdr == 0) { - sdr = (SDR02REC *)psdr; - mc = sdr->sens_ownid; - if (mc != BMC_SA) { /* not BMC, e.g. HSC or ME sensor */ - uchar a = ADDR_IPMB; - if (mc == HSC_SA) a = ADDR_SMI; - chan = (sdr->sens_ownlun & 0xf0) >> 4; - lun = (sdr->sens_ownlun & 0x03); - ipmi_set_mc(chan,(uchar)mc, lun,a); - } - } else mc = BMC_SA; - inputData[0] = sens_num; - rc = ipmi_cmd_mc(GET_SENSOR_READING,inputData,1, resp,&sresp,&cc,fdebug); - if (fdebug) - printf("GetSensorReading mc=%x,%x,%x status=%d cc=%x sz=%d resp: %02x %02x %02x %02x\n", - chan,mc,lun,rc,cc,sresp,resp[0],resp[1],resp[2],resp[3]); - if (mc != BMC_SA) ipmi_restore_mc(); - if ((rc == 0) && (cc != 0)) { - if (fdebug) printf("GetSensorReading error %x %s\n",cc, - decode_cc((ushort)0,(uchar)cc)); - rc = cc; - } - if (rc != 0) return(rc); - - if (resp[1] & 0x20) { /* init state, reading invalid */ - if (fdebug) - printf("sensor[%x] in init state, no reading\n", sens_num); - sens_data[1] = resp[1]; - sens_data[2] = 0x40; /*set bit num for init state*/ - } else { /*valid reading, copy it*/ - /* only returns 4 bytes, no matter what type */ - memcpy(sens_data,resp,4); - } - return(0); -} /*end GetSensorReading()*/ - -int -GetSensorReadingFactors(uchar snum, uchar raw, int *m, int *b, int * b_exp, - int *r, int *a) -{ - uchar resp[MAX_BUFFER_SIZE]; - int sresp = MAX_BUFFER_SIZE; - uchar inputData[6]; - int rc; - uchar cc = 0; - int toler, a_exp; - - inputData[0] = snum; - inputData[1] = raw; - rc = ipmi_cmd_mc(GET_SENSOR_READING_FACTORS, inputData, 2, - resp,&sresp, &cc, fdebug); - if (fdebug) printf("GetSensorReadingFactors status = %d\n",rc); - if (rc != ACCESS_OK) return(rc); - if (cc != 0) return(cc); - - /* successful, copy values */ - *m = resp[1] + ((resp[2] & 0xc0) << 2); - toler = resp[2] & 0x3f; - *b = resp[3] + ((resp[4] & 0xc0) << 2); - *a = (resp[4] & 0x3f) + ((resp[5] & 0xf0) << 4); - a_exp = (resp[5] & 0xc0) >> 2; - *r = (resp[6] &0xf0) >> 4; - *b_exp = resp[6] & 0x0f; - if (fdebug) { - printf("factors: next=%x m=%d b=%d b_exp=%d a=%d a_exp=%d r=%d\n", - resp[0],*m,*b,*b_exp,*a,a_exp,*r); - } - return(0); -} - -int GetSensorType(uchar snum, uchar *stype, uchar *rtype) -{ - uchar resp[MAX_BUFFER_SIZE]; - int sresp = MAX_BUFFER_SIZE; - uchar inputData[6]; - int rc; - uchar cc = 0; - - inputData[0] = snum; - rc = ipmi_cmd_mc(GET_SENSOR_TYPE, inputData, 1, - resp,&sresp, &cc, fdebug); - if (fdebug) printf("GetSensorType: ipmi_cmd rv = %d, cc = %x\n",rc,cc); - if (rc != ACCESS_OK) return(rc); - if (cc != 0) return(cc); - /* successful, copy values */ - if (stype != NULL) *stype = resp[0]; - if (rtype != NULL) *rtype = resp[1] & 0x7f; - return(rc); -} - -void set_reserve(int val) -{ - fDoReserve = val; -} - -int sdr_get_reservation(uchar *res_id, int fdev) -{ - int sresp; - uchar resp[MAX_BUFFER_SIZE]; - uchar cc = 0; - ushort cmd; - int rc = -1; - - if (fDoReserve == 1) { - fDoReserve = 0; /* only reserve SDR the first time */ - sresp = sizeof(resp);; - if (fdev) cmd = RESERVE_DEVSDR_REP; - else cmd = RESERVE_SDR_REP; - rc = ipmi_cmd_mc(cmd, NULL, 0, resp, &sresp, &cc, fdebug); - if (rc == 0 && cc != 0) rc = cc; - if (rc == 0) { /* ok, so set the reservation id */ - resid[0] = resp[0]; - resid[1] = resp[1]; - } - /* A reservation is cancelled by the next reserve request. */ - if (fdebug) - printf("ipmi_cmd RESERVE status=%d cc=%x id=%02x%02x\n", - rc,cc,resid[0],resid[1]); - } else rc = 0; - /* if not first time, or if error, return existing resid. */ - res_id[0] = resid[0]; - res_id[1] = resid[1]; - return(rc); -} /*end sdr_get_reservation*/ - -int sdr_clear_repo(int fdev) -{ - int sresp; - uchar resp[MAX_BUFFER_SIZE]; - uchar inputData[6]; - uchar cc = 0; - int rc = -1; - ushort cmd; - uchar resv[2] = {0,0}; - - if (fReserveOK) - rc = sdr_get_reservation(resv,fdev); - - cmd = 0x27 + (NETFN_STOR << 8); /*Clear SDR Repository*/ - inputData[0] = resv[0]; /*res id LSB*/ - inputData[1] = resv[1]; /*res id MSB*/ - inputData[2] = 'C'; - inputData[3] = 'L'; - inputData[4] = 'R'; - inputData[5] = 0xAA; - sresp = sizeof(resp);; - rc = ipmi_cmd_mc(cmd, inputData, 6, resp, &sresp,&cc, fdebug); - if (fdebug) printf("sdr_clear_repo: rc = %d, cc = %x, sz=%d\n",rc,cc,sresp); - if (rc == 0 && cc != 0) rc = cc; - - if (rc == 0 && (resp[0] & 1) != 1) { - if (fdebug) printf("Wait for sdr_clear_repo to complete\n"); - os_usleep(1,0); - } - return(rc); -} - -int sdr_add_record(uchar *sdr, int fdev) -{ - int sresp; - uchar resp[MAX_BUFFER_SIZE]; - uchar inputData[6+SZCHUNK]; - uchar cc = 0; - int rc = -1; - ushort cmd; - uchar resv[2] = {0,0}; - int reclen, len, i; - int recid, chunksz; - uchar prog; - - reclen = sdr[4] + 5; - recid = sdr[0] + (sdr[1] << 8); - /* OEM SDRs can be min 8 bytes, less is an error. */ - if (reclen < 8) return(LAN_ERR_BADLENGTH); - if (fReserveOK) - rc = sdr_get_reservation(resv,fdev); - if (fdebug) printf("sdr_add_record[%x]: reclen = %d, reserve rc = %d\n", - recid,reclen,rc); - - cmd = 0x25 + (NETFN_STOR << 8); /*PartialAddSdr*/ - recid = 0; /*first chunk must be added as 0000*/ - chunksz = SZCHUNK; - for (i = 0; i < reclen; ) - { - prog = 0; - len = chunksz; - if ((i+chunksz) >= reclen) { /*last record*/ - len = reclen - i; - prog = 1; - } - inputData[0] = resv[0]; /*res id LSB*/ - inputData[1] = resv[1]; /*res id MSB*/ - inputData[2] = recid & 0x00ff; /*record id LSB*/ - inputData[3] = (recid >> 8) & 0x00ff; /*record id MSB*/ - inputData[4] = (uchar)i; /*offset */ - inputData[5] = prog; /*progress: 1=last record*/ - memcpy(&inputData[6],&sdr[i],len); - sresp = sizeof(resp); - rc = ipmi_cmd_mc(cmd, inputData, 6+len, resp, &sresp,&cc, fdebug); - if (fdebug) - printf("sdr_add_record[%x,%x]: rc = %d, cc = %x, sz=%d\n", - recid,i,rc,cc,sresp); - if (rc == 0 && cc != 0) rc = cc; - if (rc != 0) break; - if (recid == 0 && rc == 0) /*first time, so set recid*/ - recid = resp[0] + (resp[1] << 8); - i += len; - } - return(rc); -} - -int GetSDR(int r_id, int *r_next, uchar *recdata, int srecdata, int *rlen) -{ - int sresp; - uchar resp[MAX_BUFFER_SIZE+SZCHUNK]; - uchar respchunk[SZCHUNK+10]; - uchar inputData[6]; - uchar cc = 0; - int rc = -1; - int i, chunksz, thislen, off; - int reclen; - ushort cmd; - uchar resv[2] = {0,0}; - - chunksz = SZCHUNK; - reclen = srecdata; /*max size of SDR record*/ - off = 0; - *rlen = 0; - *r_next = 0xffff; /*default*/ - if (fReserveOK) - rc = sdr_get_reservation(resv,fdevsdrs); - if (fdevsdrs) cmd = GET_DEVICE_SDR; - else cmd = GET_SDR; - if (reclen == 0xFFFF) { /* get it all in one call */ - inputData[0] = resv[0]; /*res id LSB*/ - inputData[1] = resv[1]; /*res id MSB*/ - inputData[2] = r_id & 0x00ff; /*record id LSB*/ - inputData[3] = (r_id & 0xff00) >> 8; /*record id MSB*/ - inputData[4] = 0; /*offset */ - inputData[5] = 0xFF; /*bytes to read, ff=all*/ - sresp = sizeof(resp);; - if (fdebug) printf("ipmi_cmd SDR id=%d read_all, len=%d\n", - r_id,sresp); - rc = ipmi_cmd_mc(cmd, inputData, 6, recdata, &sresp,&cc, fdebug); - /* This will usually return cc = 0xCA (invalid length). */ - if (fdebug) printf("ipmi_cmd SDR data status = %d, cc = %x, sz=%d\n", - rc,cc,sresp); - reclen = sresp; - *r_next = recdata[0] + (recdata[1] << 8); - } else /* if (reclen > chunksz) do multi-part chunks */ - for (off = 0; off < reclen; ) - { - thislen = chunksz; - if ((off+chunksz) > reclen) thislen = reclen - off; - inputData[0] = resv[0]; /*res id LSB*/ - inputData[1] = resv[1]; /*res id MSB*/ - inputData[2] = r_id & 0x00ff; /*record id LSB*/ - inputData[3] = (r_id & 0xff00) >> 8; /*record id MSB*/ - inputData[4] = (uchar)off; /*offset */ - inputData[5] = (uchar)thislen; /*bytes to read, ff=all*/ - sresp = sizeof(respchunk); - rc = ipmi_cmd_mc(cmd, inputData, 6, respchunk, &sresp,&cc, fdebug); - if (fdebug) - printf("ipmi_cmd SDR[%x] off=%d ilen=%d status=%d cc=%x sz=%d\n", - r_id,off,thislen,rc,cc,sresp); - if (off == 0 && cc == 0xCA && thislen == SZCHUNK) { - /* maybe shorter than SZCHUNK, try again */ - chunksz = 0x06; - if (fdebug) printf("sdr[%x] try again with chunksz=%d\n", - r_id,chunksz); - continue; - } - if (off > chunksz) { - /* already have first part of the SDR, ok to truncate */ - if (rc == -3) { /* if LAN_ERR_RECV_FAIL */ - if (fdebug) printf("sdr[%x] error rc=%d len=%d truncated\n", - r_id,rc,sresp); - sresp = 0; - rc = 0; - } - if (cc == 0xC8 || cc == 0xCA) { /* length errors */ - /* handle certain MCs that report wrong length, - * at least use what we already have (sresp==0) */ - if (fdebug) printf("sdr[%x] error cc=%02x len=%d truncated\n", - r_id,cc,sresp); - cc = 0; - } - } - if (rc != ACCESS_OK) return(rc); - if (cc != 0) return(cc); - /* if here, successful, chunk was read */ - if (sresp < (thislen+2)) { - /* There are some SDRs that may report the wrong length, and - * return less bytes than they reported, so just truncate. */ - if (fdebug) printf("sdr[%x] off=%d, expected %d, got %d\n", - r_id,off,thislen+2,sresp); - if (sresp >= 2) thislen = sresp - 2; - else thislen = 0; - reclen = off + thislen; /* truncate, stop reading */ - fprintf(stderr,"SDR record %x is malformed, length %d is less than minimum %d\n",r_id,sresp,thislen+2); - rc = ERR_SDR_MALFORMED; - } - /* successful */ - memcpy(&resp[off],&respchunk[2],thislen); - if (off == 0 && sresp >= 5) { - *r_next = respchunk[0] + (respchunk[1] << 8); - reclen = respchunk[6] + 5; /*get actual record size*/ - if (reclen > srecdata) { - if (fdebug) printf("sdr[%x] chunk0, reclen=%d srecdata=%d\n", - r_id, reclen, srecdata); - reclen = srecdata; /*truncate*/ - } - } - off += thislen; - *rlen = off; - } - if (fdebug) { - printf("GetSDR[%04x] next=%x (len=%d): ",r_id,*r_next,reclen); - for (i = 0; i < reclen; i++) printf("%02x ",resp[i]); - printf("\n"); - } - memcpy(recdata,&resp[0],reclen); - *rlen = reclen; - return(rc); -} /*end GetSDR*/ - -static int nsdrs = 0; /*number of sdrs*/ -static int sz_sdrs = 0; /*actual size used with sdrs*/ -static uchar *psdrcache = NULL; - -void free_sdr_cache(uchar *ptr) -{ - if (ptr != NULL) free(ptr); - if ((ptr != psdrcache) && (psdrcache != NULL)) - free(psdrcache); - psdrcache = NULL; -} - -int get_sdr_file(char *sdrfile, uchar **sdrlist) -{ - int rv = -1; - FILE *fp = NULL; - int i, n, num, nsdr, isdr, len; - uchar *sdrbuf; - char buff[255]; - uchar hbuf[85]; - char fvalid; - - fp = fopen(sdrfile,"r"); - if (fp == NULL) { - printf("Cannot open file %s\n",sdrfile); - return(ERR_FILE_OPEN); - } - /* determine number of SDRs by number of lines in the file */ - num = 0; - while (fgets(buff, 255, fp)) { num++; } - if (fdebug) { - printf("Reading %d SDRs from file %s\n",num,sdrfile); - if ((psdrcache != NULL) && (nsdrs > 0)) { /*already have sdrcache*/ - printf("get_sdr_file: Already have cache\n"); /*fdebug*/ - free_sdr_cache(psdrcache); /*free previous sdrcache*/ - } - } - sdrbuf = malloc(num * SDR_SZ); - if (sdrbuf == NULL) { - fclose(fp); - return(rv); - } - fseek(fp, 0L, SEEK_SET); - *sdrlist = sdrbuf; - psdrcache = sdrbuf; - nsdrs = num; - isdr = 0; - nsdr = 0; - while (fgets(buff, 255, fp)) { - len = strlen_(buff); - fvalid = 0; - if (buff[0] >= '0' && (buff[0] <= '9')) fvalid = 1; - else if (buff[0] >= 'a' && (buff[0] <= 'f')) fvalid = 1; - else if (buff[0] >= 'A' && (buff[0] <= 'F')) fvalid = 1; - if (fvalid == 0) continue; - i = 0; - for (n = 0; n < len; ) { - if (buff[n] < 0x20) break; /* '\n', etc. */ - hbuf[i++] = htoi(&buff[n]); - n += 3; - } - memcpy(&sdrbuf[isdr],hbuf,i); - isdr += i; - nsdr++; - } /*end while*/ - if (fdebug) printf("Read %d SDRs, %d bytes\n",nsdr,isdr); - fclose(fp); - rv = 0; - return(rv); -} - -int get_sdr_cache(uchar **pret) -{ - int rv = -1; - int i, n, sz, len, asz; - int recid, recnext; - uchar *pcache; - uchar *psdr; - - if (pret == NULL) return(rv); - fdevsdrs = use_devsdrs(fpicmg); - - if ((psdrcache != NULL) && (nsdrs > 0)) { /*already have sdrcache*/ - *pret = psdrcache; - if (fdebug) printf("get_sdr_cache: already have cache (%p)\n",*pret); - return(0); - } - else if (fdebug) printf("get_sdr_cache: Allocating cache\n"); - - rv = GetSDRRepositoryInfo(&n,&fdevsdrs); - if (rv != 0) return(rv); - if (n == 0) { - /* this is an error, probably because fdevsdrs is wrong.*/ - if (fdebug) printf("get_sdr_cache: nsdrs=0, retrying\n"); - fdevsdrs = (fdevsdrs ^ 1); - n = 150; /*try some default num SDRs*/ - } - - sz = n * SDR_SZ; /*estimate max size for n sdrs*/ - pcache = malloc(sz); - if (pcache == NULL) return(rv); - psdrcache = pcache; - *pret = pcache; - memset(pcache,0,sz); - recid = 0; - asz = 0; - for (i = 0; i <= n; i++) - { - if (recid == 0xffff) break; - // psdr = &pcache[i * SDR_SZ]; - psdr = &pcache[asz]; - rv = GetSDR(recid,&recnext,psdr,SDR_SZ,&len); - if (fdebug) - printf("GetSDR[%x] rv = %d len=%d next=%x\n",recid,rv,len,recnext); - if (rv != 0) { - if (rv == 0xC5) { set_reserve(1); i--; } /*retry*/ - else break; - } else { /*success*/ - /* if sdrlen!=len, adjust */ - if ((len > 5) && (len != (psdr[4] + 5)) ) { - if (fdebug) printf("SDR[%x] adjust len from %d to %d\n", - recid,psdr[4]+5,len); - psdr[4] = len - 5; - } - asz += len; - if (recnext == recid) recid = 0xffff; - else recid = recnext; - } - } - nsdrs = n; - sz_sdrs = asz; /* save the size for later*/ - if (fdebug) { - printf("get_sdr_cache, n=%d sz=%d asz=%d\n",n,sz,asz); - if (i < n) printf("get_sdr_cache error, i=%d < n=%d, rv=%d\n",i,n,rv); - } - return(rv); -} - -int find_nsdrs(uchar *pcache) -{ - int num = 0; - ulong asz = 0; - int i, len; - uchar *sdr; - ushort recid = 0; - - if (pcache == NULL) return(num); - for (i = 0; (int)asz < sz_sdrs; i++) - { - sdr = &pcache[asz]; - if (sdr[2] != 0x51) { /* Dell SDR length error */ - printf("SDR[%x] length error at %ld\n",recid,asz); - sdr = &pcache[++asz]; /*try it if off-by-one*/ - } - len = sdr[4] + 5; - recid = sdr[0] + (sdr[1] << 8); - if (fdebug) printf("SDR[%x] len=%d i=%d offset=%lx\n",recid,len,i,asz); - asz += len; - } - num = i; - return(num); -} - -int find_sdr_by_snum(uchar *psdr, uchar *pcache, uchar snum, uchar sa) -{ - int rv = -1; - uchar *sdr; - int i, k, len; - int asz = 0; - if (psdr == NULL) return(rv); - if (pcache == NULL) return(rv); - for (i = 0; i <= nsdrs; i++) - { - // sdr = &pcache[i * SDR_SZ]; - sdr = &pcache[asz]; - len = sdr[4] + 5; - asz += len; - switch(sdr[3]) { - case 0x01: k = 7; break; /*full sensor*/ - case 0x02: k = 7; break; /*compact sensor*/ - case 0x03: k = 7; break;/*compact sensor*/ - default: k = 0; break; - } - if (k == 0) continue; - else { - if ((sdr[5] == sa) && (sdr[k] == snum)) { - memcpy(psdr,sdr,len); - return(0); - } - } - } - return(rv); -} - -int find_sdr_by_tag(uchar *psdr, uchar *pcache, char *tag, uchar dbg) -{ - int rv = -1; - uchar *sdr; - int i, k, n, len; - int asz = 0; - if (psdr == NULL) return(rv); - if (pcache == NULL) return(rv); - if (tag == NULL) return(rv); - if (dbg) fdebug = 1; - n = strlen_(tag); - if (fdebug) printf("find_sdr_by_tag(%s) nsdrs=%d\n",tag,nsdrs); - for (i = 0; i <= nsdrs; i++) - { - // sdr = &pcache[i * SDR_SZ]; - sdr = &pcache[asz]; - len = sdr[4] + 5; - asz += len; - switch(sdr[3]) { /* set tag offset by SDR type */ - case 0x01: k = 48; break; /*full SDR*/ - case 0x02: k = 32; break; /*compact SDR*/ - case 0x03: k = 17; break; /*event-only SDR*/ - case 0x10: k = 16; break; /*device locator SDR*/ - case 0x11: k = 16; break; /*FRU device locator SDR*/ - case 0x12: k = 16; break; /*IPMB device locator SDR*/ - default: k = 0; break; /*else do not have an ID string/tag*/ - } - if (k == 0) { - if (fdebug) printf("sdr[%d] idx=%02x%02x num=%x type=%x skip\n", - i,sdr[1],sdr[0],sdr[7],sdr[3]); - continue; - } else { - if (len > SDR_SZ) len = SDR_SZ; - if (fdebug) { - char tmp[17]; - memset(tmp,0,sizeof(tmp)); - memcpy(tmp,&sdr[k],(len - k)); - tmp[16] = 0; /*force stringify*/ - printf("sdr[%d] idx=%02x%02x num=%x tag: %s\n",i,sdr[1],sdr[0], - sdr[7],tmp); - } - if (strncmp(tag,(char *)&sdr[k],n) == 0) { - memcpy(psdr,sdr,len); - return(0); - } - } - } - return(rv); -} - - -int find_sdr_next(uchar *psdr, uchar *pcache, ushort id) -{ - int rv = -1; - uchar *sdr; - int i, imatch, len; - ushort recid; - int asz = 0; - if (psdr == NULL) return(rv); - if (pcache == NULL) return(rv); - imatch = nsdrs; - for (i = 0; i < nsdrs; i++) - { - // sdr = &pcache[i * SDR_SZ]; - sdr = &pcache[asz]; - if (sdr[2] != 0x51) /* Dell SDR off-by-one error */ - sdr = &pcache[++asz]; - len = sdr[4] + 5; - recid = sdr[0] + (sdr[1] << 8); - asz += len; - // if (fdebug) printf("SDR[%x] len=%d id=%x i=%d imatch=%d\n", - // recid,len,id,i,imatch); - if (recid == id) imatch = i + 1; /*matches prev, return next one*/ - else if (id == 0) { rv = 0; break; } /* 0000 = first one */ - if (i == imatch) { rv = 0; break; } - } - if (rv == 0) memcpy(psdr,sdr,len); - return(rv); -} - -int find_sdr_by_id(uchar *psdr, uchar *pcache, ushort id) -{ - int rv = -1; - uchar *sdr; - int i, imatch, len; - ushort recid; - int asz = 0; - if (psdr == NULL) return(rv); - if (pcache == NULL) return(rv); - imatch = nsdrs; - for (i = 0; i < nsdrs; i++) - { - sdr = &pcache[asz]; - len = sdr[4] + 5; - recid = sdr[0] + (sdr[1] << 8); - asz += len; - if (recid == id) { rv = 0; break; } - else if (id == 0) { rv = 0; break; } /* 0000 = first one */ - } - if (rv == 0) memcpy(psdr,sdr,len); - return(rv); -} - -uchar -bitnum(ushort value) -{ - uchar ret = 0; - int i; - /* returns the highest bit number number set in this word. */ - /* Bit numbers are 1-based in this routine, 0 means no bits set. */ - /* scan 15 bits (0x7FFF). */ - for (i = 0; i < 15; i++) { - if (value & 0x01) ret = i+1; /*was ret++;*/ - value = (value >> 1); - } - return(ret); -} - -static double -expon(int x, int y) -{ - double res; - int i; - /* compute exponent: x to the power y */ - res = 1; - if (y > 0) { - for (i = 0; i < y; i++) res = res * x; - } else if (y < 0) { - for (i = 0; i > y; i--) res = res / x; - } /* else if if (y == 0) do nothing, res=1 */ - return(res); -} - -double -RawToFloat(uchar raw, uchar *psdr) -{ - double floatval; - int m, b, a; - uchar ax; - int rx, b_exp; - SDR01REC *sdr; - int signval; - - sdr = (SDR01REC *)psdr; - floatval = (double)raw; /*default*/ - - // if (raw == 0xff) floatval = 0; else - if (sdr->rectype == 0x01) { /* SDR rectype == full */ - if (fdebug) - printf("units=%x base=%d mod=%d (raw=%x, nom_rd=%x)\n", - sdr->sens_units,sdr->sens_base,sdr->sens_mod, - raw, sdr->nom_reading); - m = sdr->m + ((sdr->m_t & 0xc0) << 2); - b = sdr->b + ((sdr->b_a & 0xc0) << 2); - if (b & 0x0200) b = (b - 0x0400); /*negative*/ - if (m & 0x0200) m = (m - 0x0400); /*negative*/ - rx = (sdr->rx_bx & 0xf0) >> 4; - if (rx & 0x08) rx = (rx - 0x10); /*negative, fix sign w ARM compilers*/ - a = (sdr->b_a & 0x3f) + ((sdr->a_ax & 0xf0) << 2); - ax = (sdr->a_ax & 0x0c) >> 2; - b_exp = (sdr->rx_bx & 0x0f); - if (b_exp & 0x08) b_exp = (b_exp - 0x10); /*negative*/ - //b_exp |= 0xf0; /* negative 8-bit */ - if ((sdr->sens_units & 0xc0) == 0) { /*unsigned*/ - floatval = (double)raw; - } else { /*signed*/ - if (raw & 0x80) signval = (raw - 0x100); - else signval = raw; - floatval = (double)signval; - } - floatval *= (double) m; -#ifdef MATH_OK - floatval += (b * pow (10,b_exp)); - floatval *= pow (10,rx); -#else - floatval += (b * expon (10,b_exp)); - floatval *= expon (10,rx); -#endif - if (fdebug) - printf("decode1: m=%d b=%d b_exp=%x rx=%d, a=%d ax=%d l=%x, floatval=%f\n", - m,b,b_exp,rx,a,ax,sdr->linear,floatval); - switch(sdr->linear) { - case 0: /*linear*/ - break; - case 7: /*invert 1/x*/ - /* skip if zero to avoid dividing by zero */ - if (raw != 0) floatval = 1 / floatval; - break; - case 1: /*ln*/ - case 2: /*log10, log2, e, exp10, exp2, */ - case 3: /*log2*/ - case 4: /*e*/ - case 5: /*exp10*/ - case 6: /*exp2*/ - case 8: /*sqr(x)*/ - case 9: /*cube(x)*/ - case 10: /*sqrt(x)*/ - case 11: /*cube-1(x)*/ - default: - if (fdebug) printf("linear mode %x not implemented\n",sdr->linear); - break; - } /*end-switch linear*/ - } - -#ifdef NOT_LINEAR - /* else if (sdr->linear != 7) */ - { - double be, re; - rc = GetSensorType(sdr->sens_num,&stype,&rtype); - if (fdebug) - printf("decode: rc=%x, stype=%x, rtype=%x\n",rc,stype,rtype); - if (rc != 0) return(floatval); - - /* GetSensorReadingFactors */ - rc = GetSensorReadingFactors(sdr->sens_num,raw,&m,&b,&b_exp,&r,&a); - if (rc == 0) { - // floatval = ((m * raw) + (b * be)) * re; - } - if (fdebug) printf("decode: rc=%x, floatval=%f\n",rc,floatval); - } -#endif - - return(floatval); -} - -#define IpmiAnalogDataFormatUnsigned 0 -#define IpmiAnalogDataFormat1Compl 1 -#define IpmiAnalogDataFormat2Compl 2 - -uchar -FloatToRaw(double val, uchar *psdr, int rounding) -{ - double cval; - int lowraw, highraw, raw, maxraw, minraw, next_raw; - int analog_dfmt; - - analog_dfmt = (psdr[20] >> 6) & 0x03; - switch( analog_dfmt ) - { - case IpmiAnalogDataFormat1Compl: - lowraw = -127; - highraw = 127; - minraw = -127; - maxraw = 127; - next_raw = 0; - break; - case IpmiAnalogDataFormat2Compl: - lowraw = -128; - highraw = 127; - minraw = -128; - maxraw = 127; - next_raw = 0; - break; - case IpmiAnalogDataFormatUnsigned: - default: - lowraw = 0; - highraw = 255; - minraw = 0; - maxraw = 255; - next_raw = 128; - break; - } - - /* do a binary search for the right nth root value */ - do { - raw = next_raw; - cval = RawToFloat( (uchar)raw, psdr ); - if ( cval < val ) { - next_raw = ((highraw - raw) / 2) + raw; - lowraw = raw; - } else { - next_raw = ((raw - lowraw) / 2) + lowraw; - highraw = raw; - } - } while ( raw != next_raw ); - - /* Do rounding to get the final value */ - switch( rounding ) { - case 0: /* Round Normal = Round to nearest value */ - if ( val > cval ) { - if ( raw < maxraw ) { - double nval; - nval = RawToFloat((uchar)(raw+1),psdr); - nval = cval + ((nval - cval) / 2.0); - if ( val >= nval ) raw++; - } - } else { - if ( raw > minraw ) { - double pval; - pval = RawToFloat((uchar)(raw-1),psdr); - pval = pval + ((cval - pval) / 2.0); - if ( val < pval ) raw--; - } - } - break; - case 1: /*Round Down*/ - if ((val < cval) && (raw > minraw )) raw--; - break; - case 2: /*Round Up*/ - if ((val > cval) && (raw < maxraw)) raw++; - break; - } - if ( analog_dfmt == IpmiAnalogDataFormat1Compl ) - if ( raw < 0 ) raw -= 1; - return((uchar)raw); -} /*end FloatToRaw()*/ - -static int fill_thresholds(double *thrf, uchar *sdr) -{ - int rv = 0; - uchar *vals; - uchar bits; - - // snum = sdr[7]; - bits = sdr[19]; /*which are settable*/ - vals = &sdr[36]; - if (fdebug) - printf("fill_thresholds: bits=%02x, values: %f>=%f>=%f, %f<=%f<=%f\n", - bits, thrf[0],thrf[1],thrf[2], thrf[3],thrf[4],thrf[5]); - if (thrf[0] == THR_EMPTY) { - if ((bits & 0x01) != 0) { /*lo-noncrit*/ - thrf[0] = RawToFloat(vals[5],sdr); - rv++; - } else thrf[0] = 0; - } - if (thrf[1] == THR_EMPTY) { - if ((bits & 0x02) != 0) { /*lo-crit*/ - thrf[1] = RawToFloat(vals[4],sdr); - rv++; - } else thrf[1] = 0; - } - if (thrf[2] == THR_EMPTY) { - if ((bits & 0x04) != 0) { /*lo-unrec*/ - thrf[2] = RawToFloat(vals[3],sdr); - rv++; - } else thrf[2] = 0; - } - if (thrf[3] == THR_EMPTY) { - if ((bits & 0x08) != 0) { /*hi-noncrit*/ - thrf[3] = RawToFloat(vals[2],sdr); - rv++; - } else thrf[3] = 0; - } - if (thrf[4] == THR_EMPTY) { - if ((bits & 0x10) != 0) { /*hi-crit*/ - thrf[4] = RawToFloat(vals[1],sdr); - rv++; - } else thrf[4] = 0; - } - if (thrf[5] == THR_EMPTY) { - if ((bits & 0x20) != 0) { /*hi-unrec*/ - thrf[5] = RawToFloat(vals[0],sdr); - rv++; - } else thrf[5] = 0; - } - if (fdebug) - printf("fill_thresholds: after rv=%d values: %f>=%f>=%f, %f<=%f<=%f\n", - rv,thrf[0],thrf[1],thrf[2], thrf[3],thrf[4],thrf[5]); - return(rv); -} - -char * -decode_itype(uchar itype) -{ - char *retstr; - int i; - /* Decode the Interrupt Type from Entity Assoc records */ - - retstr = tmpstr; - if (itype <= 0x0f) sprintf(retstr,"IRQ_%d",itype); - else if (itype <= 0x13) { - strcpy(retstr,"PCI-A"); - for (i=0x10;i<itype;i++) retstr[4]++; - } - else if (itype == 0x14) strcpy(retstr,"SMI"); - else if (itype == 0x15) strcpy(retstr,"SCI"); - else if (itype >= 0x20 && itype <= 0x5f) - sprintf(retstr,"SysInt_%d",itype-0x20); - else if (itype == 0x60) strcpy(retstr,"ACPI/PnP"); - else if (itype == 0xFF) strcpy(retstr,"NoInt"); - else strcpy(retstr,"Invalid"); - return(retstr); -} - -int decode_oem_sensor(uchar *sdr,uchar *reading,char *pstring,int slen) -{ - int rv = -1; -#ifdef METACOMMAND - switch(vend_id) { - case VENDOR_INTEL: - rv = decode_sensor_intel(sdr, reading, pstring, slen); - break; - case VENDOR_KONTRON: - rv = decode_sensor_kontron(sdr, reading, pstring, slen); - break; - case VENDOR_FUJITSU: - rv = decode_sensor_fujitsu(sdr,reading,pstring,slen); - break; - case VENDOR_SUN: - rv = decode_sensor_sun(sdr, reading, pstring, slen); - break; - case VENDOR_MAGNUM: - case VENDOR_SUPERMICRO: - case VENDOR_SUPERMICROX: - rv = decode_sensor_supermicro(sdr,reading,pstring,slen,fsimple,fdebug); - break; - case VENDOR_QUANTA: - rv = decode_sensor_quanta(sdr, reading, pstring, slen); - break; - case VENDOR_HP: - rv = decode_sensor_hp(sdr, reading, pstring, slen); - break; - case VENDOR_DELL: - rv = decode_sensor_dell(sdr, reading, pstring, slen); - break; - case VENDOR_IBM: - case VENDOR_LENOVO: - case VENDOR_LENOVO2: - rv = decode_sensor_lenovo(sdr, reading, pstring, slen); - break; - case VENDOR_ASUS: - rv = decode_sensor_asus(sdr, reading, pstring, slen); - break; - default: - break; - } /*end-switch vend_id*/ - if (fdebug) // && rv == 0) - printf("decode_oem_sensor rv=%d vend=%x string=%s\n",rv,vend_id,pstring); -#endif - return (rv); -} - -int show_oemsdr(int vend, uchar *sdr) -{ - int rv = -1; - int i, len; - -#ifdef METACOMMAND - if (vend == VENDOR_INTEL) { - show_oemsdr_intel(sdr); /*show subtypes for Intel BMC_TAM*/ - rv = 0; - } else if (vend == 4156) { /*special HP/NewAccess OEM SDR*/ - show_oemsdr_hp(sdr); - rv = 0; - } else if (vend == VENDOR_QUANTA) { - printf("Quanta: "); - show_oemsdr_nm(sdr); - rv = 0; - } -#endif - if (rv != 0) { - len = sdr[4] + 5; - if (vend == VENDOR_FUJITSU) printf("Fujitsu: "); - else if (vend == VENDOR_INTEL) printf("Intel: "); - else printf("manuf=%d: ",vend); - for (i = 8; i < len; i++) printf("%02x ",sdr[i]); - printf("\n"); - } - return(rv); -} - -void -ShowThresh(int flg, uchar bits, uchar *vals, uchar *sdr) -{ - char str[128] = ""; - char part[24]; /* ~15 bytes used */ - double ival; - char sep[4]; - char *tag; - tag = ""; - if (fsimple) { - sprintf(sep,"%c ",bdelim); - tag = "Thresholds"; - } else sep[0] = 0; /*null string*/ - if (fshowthr == 2) { - double i0, i1, i2, i3, i4, i5; - i0 = RawToFloat(vals[0],sdr); - i1 = RawToFloat(vals[1],sdr); - i2 = RawToFloat(vals[2],sdr); - i3 = RawToFloat(vals[3],sdr); - i4 = RawToFloat(vals[4],sdr); - i5 = RawToFloat(vals[5],sdr); - sprintf(str,"%.2f:%.2f:%.2f:%.2f:%.2f:%.2f",i0,i1,i2,i3,i4,i5); - printf("\t%s%s%s%c",sep,"Thresh ",str,chEol); - } else if (flg != 0) { /* Compact, did GetThresholds, reverse order */ - if (bits & 0x20) { - ival = RawToFloat(vals[5],sdr); - sprintf(part,"%shi-unrec %.2f ",sep,ival); - strcat(str,part); - } - if (bits & 0x10) { - ival = RawToFloat(vals[4],sdr); - sprintf(part,"%shi-crit %.2f ", sep,ival); - strcat(str,part); - } - if (bits & 0x08) { - ival = RawToFloat(vals[3],sdr); - sprintf(part,"%shi-noncr %.2f ",sep,ival); - strcat(str,part); - } - if (bits & 0x01) { - ival = RawToFloat(vals[0],sdr); - sprintf(part,"%slo-noncr %.2f ",sep,ival); - strcat(str,part); - } - if (bits & 0x02) { - ival = RawToFloat(vals[1],sdr); - sprintf(part,"%slo-crit %.2f ", sep,ival); - strcat(str,part); - } - if (bits & 0x04) { - ival = RawToFloat(vals[2],sdr); - sprintf(part,"%slo-unrec %.2f ",sep,ival); - strcat(str,part); - } - if (flg == 2) { - if (sens_verbose) tag = "Volatile "; - printf("\t%s%s%s%c",sep,tag,str,chEol); - } else - printf("\t%s%s%s%c",sep,tag,str,chEol); - } else { /*Full SDR*/ - if (fdebug) printf("ShowThresh[%x]: bits=%02x, sdr18=%02x %02x\n", - sdr[7],bits,sdr[18],sdr[19]); - if (bits & 0x20) { - ival = RawToFloat(vals[0],sdr); - sprintf(part,"%shi-unrec %.2f ",sep,ival); - strcat(str,part); - } - if (bits & 0x10) { - ival = RawToFloat(vals[1],sdr); - sprintf(part,"%shi-crit %.2f ",sep,ival); - strcat(str,part); - } - if (bits & 0x08) { - ival = RawToFloat(vals[2],sdr); - sprintf(part,"%shi-noncr %.2f ",sep,ival); - strcat(str,part); - } - if (bits & 0x01) { - ival = RawToFloat(vals[5],sdr); - sprintf(part,"%slo-noncr %.2f ",sep,ival); - strcat(str,part); - } - if (bits & 0x02) { - ival = RawToFloat(vals[4],sdr); - sprintf(part,"%slo-crit %.2f ",sep,ival); - strcat(str,part); - } - if (bits & 0x04) { - ival = RawToFloat(vals[3],sdr); - sprintf(part,"%slo-unrec %.2f ",sep,ival); - strcat(str,part); - } - if (sens_verbose) tag = "SdrThres "; - printf("\t%s%s%s%c",sep,tag,str,chEol); - if (sens_verbose) - { /* show max/min & hysteresis from full sdr */ - str[0] = 0; - ival = RawToFloat(sdr[31],sdr); - sprintf(part,"%snom %.2f ",sep,ival); - strcat(str,part); - ival = RawToFloat(sdr[32],sdr); - sprintf(part,"%snmax %.2f ",sep,ival); - strcat(str,part); - ival = RawToFloat(sdr[33],sdr); - sprintf(part,"%snmin %.2f ",sep,ival); - strcat(str,part); - - ival = RawToFloat(sdr[34],sdr); - sprintf(part,"%ssmax %.2f ",sep,ival); - strcat(str,part); - - ival = RawToFloat(sdr[35],sdr); - sprintf(part,"%ssmin %.2f ",sep,ival); - strcat(str,part); - -#ifdef OLD - ival = RawToFloat(sdr[42],sdr); - sprintf(part,"%s+hyst %.2f ",sep,ival); - strcat(str,part); - - ival = RawToFloat(sdr[43],sdr); - sprintf(part,"%s-hyst %.2f ",sep,ival); - strcat(str,part); -#endif - - printf("\t%s%c",str,chEol); - } - } /*endif full sdr*/ -} - -int decode_comp_generic(uchar type, uchar evtype, uchar num, ushort reading) -{ - int istr = 0; - uchar b; - /* decode via evtype */ - switch(evtype) - { - case 0x02: - if (reading & 0x01) istr = 85; /* Active */ - if (reading & 0x02) istr = 86; /* Busy */ - else istr = 84; /* Idle (OK)) */ - case 0x03: - if (reading & 0x01) istr = 13; /* Asserted */ - else istr = 0; /* "OK" Deasserted */ - break; - case 0x04: - if (reading & 0x01) istr = 15; /* Predictive Failure */ - else istr = 0; /* "OK" Deasserted */ - break; - case 0x05: - if (reading & 0x01) istr = 65; /* Limit Exceeded*/ - else istr = 0; /* "OK" LimitNotExceeded*/ - break; - case 0x07: /* transition */ - b = bitnum(reading); - switch(b) { - case 0: istr = 0; break; /*no bits set, OK*/ - case 1: istr = 87; break; /*transition up to Non-Critical*/ - case 2: istr = 88; break; /*transition up to Critical */ - case 3: istr = 89; break; /*transition up to Non-recoverable */ - case 4: istr = 87; break; /*transition down to Non-Critical */ - case 5: istr = 88; break; /*transition down to Critical */ - case 6: istr = 89; break; /*transition to Non-recoverable */ - case 7: istr = 90; break; /*Monitor*/ - case 8: istr = 91; break; /*Informational*/ - default: istr = 8; break; /*'OK*'*/ - } - break; - case 0x08: - if (reading & 0x01) istr = 9; /* Present */ - else istr = 10; /*Absent*/ - break; - case 0x09: /* Availability event states */ - if (reading & 0x01) istr = 17; /* Enabled */ - else istr = 16; /*Disabled*/ - break; - case 0x0A: /* */ - b = (reading & 0x7f); - switch(b) { - case 0x00: istr = 8; break; /* 00 'OK*'*/ - case 0x01: istr = 92; break; /* transition to Running */ - case 0x02: istr = 93; break; /* transition to In Test */ - case 0x04: istr = 94; break; /* transition to Power Off */ - case 0x08: istr = 95; break; /* transition to On Line */ - case 0x10: istr = 96; break; /* transition to Off Line */ - case 0x20: istr = 97; break; /* transition to Off Duty */ - case 0x40: istr = 98; break; /* transition to Degraded */ - case 0x80: istr = 99; break; /* transition to Power Save */ - default: istr = 100; break; /* Install Error */ - } - break; - case 0x0B: /* Redundancy */ - b = (reading & 0x7f); - switch(b) { - case 0x00: istr = 8; break; /* 00 'OK*'*/ - case 0x01: istr = 18; break; /* 01 Fully Redundant */ - case 0x02: istr = 19; break; /* 02 Redundancy Lost */ - case 0x04: istr = 20; break; /* 04 Redundancy Degraded */ - case 0x08: istr = 82; break; /* 08 Non-Redundant/Sufficient down */ - case 0x10: istr = 82; break; /* 10 Non-Redundant/Sufficient up*/ - case 0x20: istr = 83; break; /* 20 Non-Redundant/Insufficient */ - case 0x40: istr = 20; break; /* 40 Redundancy Degraded down */ - default: istr = 20; break; /* Redundancy Degraded up */ - } - break; - case 0x0C: /* ACPI Power States */ - if (reading & 0x04) istr = 21; /* D3, Off */ - else if (reading & 0x02) istr = 23; /* D2, Sleeping */ - else if (reading & 0x01) istr = 22; /* D1, Working */ - else istr = 24; /*D0, On*/ - break; - default: - if (fdebug) - printf("sensor[%x] et %02x type %02x not decoded, reading = %04x\n", - num,evtype,type,reading); - istr = STR_OTHER; /* other " - " */ - break; - } - return(istr); -} - -/* - * decode_comp_reading - * - * Decodes the readings from compact SDR sensors. - * Use sensor_dstatus array for sensor reading types and meaning strings. - * Refer to IPMI Table 36-1 and 36-2 for this. - * - * Note that decoding should be based on sensor type and ev_type only, - * except for end cases. - * - * Note reading1 = sens_reading[2], reading2 = sens_reading[3] - */ -int -decode_comp_reading(uchar type, uchar evtype, uchar num, - uchar reading1, uchar reading2) -{ - int istr = 0; /*string index into sensor_dstatus[] */ - uchar b; - ushort reading; - static char customstr[35]; - - /* usually reading2 has h.o. bit set (0x80). */ - reading = reading1 | ((reading2 & 0x7f) << 8); - - switch(type) - { - case 0x01: /*Discrete Thermal, Temperature*/ - if (fdebug) - printf("Discrete Thermal snum %x evtype=%x reading=%x\n", - num,evtype,reading); - if (evtype == 0x07) { - b = bitnum(reading); - if (b == 0) istr = 8; /*no bits set, "OK*"*/ - else if (b < 3) istr = 0; /*bits 1,2 "OK"*/ - else istr = 65; /*transition to error, Limit Exceeded*/ - } else if (evtype == 0x05) { - /* see CPU1 VRD Temp on S5000, snum 0xc0 thru 0xcf */ - if (reading & 0x01) istr = 65; /* Limit Exceeded*/ - else istr = 0; /* "OK" LimitNotExceeded*/ - } else if (evtype == 0x03) { - if (reading & 0x01) istr = 13; /* Asserted */ - else istr = 0; /* "OK" Deasserted */ - } else { /* evtype == other 0x05 */ - if (reading & 0x01) istr = 0; /* 8="OK*", 0="OK" */ - else istr = 5; /*state asserted, Crit-hi */ - } - break; - case 0x02: /*Discrete Voltage*/ - { /* evtype == 0x05 for VBat, 0x03 for VR Watchdog */ - if (reading & 0x01) istr = 65; /*LimitExceeded, was Crit-hi*/ - else istr = 0; /* "OK" LimitNotExceeded*/ - } - break; - case 0x04: /*Fan*/ - if (evtype == 0x0b) { /*redundancy*/ - b = reading & 0x3f; - if (b == 0x00) istr = 16; /*sensor disabled*/ - else if (b == 0x01) istr = 18; /*fully redundant*/ - else if (b == 0x02) istr = 19; /*redundancy lost*/ - else if (b == 0x0b) istr = STR_AC_LOST; /*ac lost*/ - else istr = 20; /*redundancy degraded*/ - } else if (evtype == 0x08) { /*presence*/ - if (reading & 0x02) istr = 9; /*Present/Inserted*/ - else if (reading & 0x01) istr = 10; /*Absent/Removed*/ - else /*reading==00*/ istr = 47; /*Unused*/ - } else if (evtype == 0x03) { /*PS Fan Fail*/ - if (reading == 0) istr = 0; /*OK*/ - else istr = 12; /*faulty*/ - } else { /*other evtype*/ - b = reading & 0x0f; - if (b == 0) istr = 12; /*faulty*/ - else if (b & 0x01) istr = 11; /*ready*/ - else istr = 41; /*Unknown*/ - } - break; - case 0x05: /*Physical Security, Chassis */ - if (reading == 0) istr = 0; /*OK*/ - else if (reading & 0x01) istr = 38; /*chassis intrusion*/ - /* 0x02 Drive bay intrusion */ - /* 0x04 IO area intrusion */ - /* 0x08 Processor area intrusion */ - else if (reading & 0x10) istr = 37; /*lan leash lost*/ - /* 0x20 Dock/Undock */ - /* 0x40 Fan area intrusion */ - else istr = 41; /* Unknown, was bitnum(reading); */ - break; - case 0x07: /*Processor Status - 0x80 is OK/Present */ - b = bitnum(reading); - if (evtype == 0x03) { - if (b <= 1) istr = 0; /*bit1 Deasserted, OK* */ - else istr = 13; /*bit2 Asserted*/ - } else { /*usu 0x6f*/ - if (b > 10) istr = 41; /*Unknown*/ - else if (b == 0) istr = 0; /*OK*/ - else istr = 47 + b; /*Proc strings 48 thru 57*/ - } - break; - case 0x08: /*Power Supply*/ - b = reading & 0x7f; - if (b == 0) istr = 10; /*absent*/ - else if (b & 0x40) istr = STR_PS_CONFIG; /*Config Err*/ - else if (b & 0x08) istr = STR_AC_LOST; /*AC Lost*/ - else if (b & 0x04) istr = 15; /*Predictive Fail*/ - else if (b & 0x02) istr = STR_PS_FAIL; /*PS Fail*/ - else if (b & 0x01) istr = 9; /*present*/ - break; - case 0x09: /*Power Unit*/ - b = reading & 0x3f; - if (evtype == 0x0b) { /*Power Redundancy*/ - if (b == 0x00) istr = 16; /*sensor disabled*/ - else if (b == 0x01) istr = 18; /*fully redundant*/ - else if (b == 0x02) istr = 19; /*redundancy lost*/ - else if (b == 0x0b) istr = STR_AC_LOST; /*ac lost*/ - else istr = 20; /*redundancy degraded*/ - } else { /* Power Unit (evtype==0x6f or 0xef) */ - if (b == 0) istr = 17; /*enabled*/ - else if ((b & 0x01) == 1) istr = 16; /*disabled*/ - } - break; - case 0x0C: /* Memory */ - b = reading & 0x3f; - if (b == 0) istr = 0; /*OK*/ - else if (b & 0x01) istr = 8; /*Correctable ECC (OK*)*/ - else if ((b & 0x02) || (b & 0x20)) istr = 39; /*ECC Error*/ - else if (b & 0x04) istr = 40; /*Parity Error*/ - else istr = bitnum(b); /* ECC or other error */ - break; - case 0x0D: /* drive slot - usually HSC sens_ownid == 0xc0 */ - if (fRomley || fGrantley) { /* evtype==0x6f, has both status and presence */ - if (reading & 0x02) istr = 12; /*Faulty*/ - else if (reading & 0x80) istr = STR_REBUILDING; /*Rebuilding*/ - else if (reading & 0x01) istr = 9; /*Present (OK)*/ - else istr = 10; /*Absent*/ - } else { - if (evtype == 8) { /* HSC slot presence sensors (num > 8)*/ - if (reading1 & 0x02) istr = 9; /*Present/Inserted*/ - else if (reading1 & 0x01) istr = 10; /*Absent/Removed*/ - else /*reading1==00*/ istr = 47; /*Unused*/ - } else { /* HSC slot status sensors (evtype==0x6f)*/ - /* usually reading2 == 0x82 or 0x8E if healthy */ - if (reading2 & 0x01) istr = 12; /*state8=Rebuild stopped*/ - else if (reading2 & 0x02) istr = 11; /*state9=Inserted/Ready */ - else if (reading2 & 0x04) istr = 11; /*state10=Safe_to_Remove*/ - else if (reading2 & 0x08) istr = 11; /*state11=Ready */ - else if (reading2 == 0x80) istr = 47; /*no states, Unused*/ - else istr = 12; /*faulty*/ - b = 8; /*if no bits set, no raid state */ - if (reading1 & 0x01) { b = 0; } /*state0=Faulty*/ - else if (reading1 & 0x02) b = 1; /*state1=Rebuilding*/ - else if (reading1 & 0x04) b = 2; /*state2=InFailedArray*/ - else if (reading1 & 0x08) b = 3; /*state3=InCriticalArray*/ - else if (reading1 & 0x10) b = 4; /*state4=ParityCheck*/ - else if (reading1 & 0x20) b = 5; /*state5=PredictedFault*/ - else if (reading1 & 0x40) b = 6; /*state6=Un-configured*/ - else if (reading1 & 0x80) b = 7; /*state7=HotSpare*/ - if (b < 8) { - /* also include a raid_state, via custom string */ - sprintf(customstr,"%s %s", - sensor_dstatus[istr], raid_states[b]); - istr = STR_CUSTOM; - sensor_dstatus[istr] = customstr; - if (fdebug) printf("dstatus=%s\n",sensor_dstatus[istr]); - } - } /*end-else-if HSC slot status (0x6f)*/ - } - break; - case 0x10: /*Event Logging*/ - /* usu evtype==0x6f*/ - b = bitnum(reading & 0x3f); - switch (b) { - case 0x00: istr = 0; break; /*OK*/ - case 0x01: istr = 59; break; /*MemLogDisabled*/ - case 0x02: istr = 60; break; /*TypLogDisabled*/ - case 0x03: istr = 61; break; /*LogCleared*/ - case 0x04: istr = 62; break; /*AllLogDisabled*/ - case 0x05: istr = 63; break; /*SelFull*/ - case 0x06: istr = 64; break; /*SelNearFull*/ - default: istr = 41; break; /*Unknown*/ - } - break; - case 0x12: /*System Event*/ - if (reading == 0) istr = 0; - else istr = 13; /*Asserted*/ - break; - case 0x13: /*Critical Interrupt*/ - /* valid bits: 0x03FF */ - if (reading == 0) istr = 0; /*OK*/ - else { - b = bitnum(reading); /* ECC or other error */ - if (b > 10) b = 10; - istr = 24 + b; - } - break; - case 0x14: /*Button*/ - if (reading == 0) istr = 0; /*OK*/ - else istr = 13; /*Asserted*/ - break; - case 0x15: /*Module/ Board */ - if (evtype == 0x08) { /*presence*/ - if (reading & 0x02) istr = 9; /*Present/Inserted*/ - else if (reading & 0x01) istr = 10; /*Absent/Removed*/ - else /*reading==00*/ istr = 47; /*Unused*/ - } - break; - case 0x16: /* HSBP Status (esp. Romley) */ - if (reading & 0x010) istr = STR_HSC_OFF; /*Offline*/ - else istr = 0; /*OK*/ - break; - case 0x17: /* ATCA CDM, Air Filter, Filter Tray */ - if (reading == 0) istr = 0; /*OK*/ - else if (reading & 0x01) istr = 10; /*Absent*/ - else istr = bitnum(reading); /* other error, TODO: fix this */ - break; - case 0x1C: /*Terminator (usu SCSI)*/ - if (reading & 0x01) istr = 9; /*present*/ - else istr = 10; /*missing,absent*/ - break; - case 0x21: /*DIMM memory slot*/ - if ((reading & 0x04) != 0) istr = 9; /*present*/ - else istr = 10; /*absent*/ - sprintf(customstr,"%s", sensor_dstatus[istr]); - if ((reading & 0x01) != 0) strcat(customstr,",Fault"); - if ((reading & 0x0100) != 0) strcat(customstr,",Disabled"); - istr = 58; /*use a custom string*/ - sensor_dstatus[istr] = customstr; - if (fdebug) printf("dstatus=%s\n",sensor_dstatus[istr]); - break; - case 0x22: /*ACPI Power State*/ - b = bitnum(reading); - switch(b) { - case 0: istr = 0; break; /*OK*/ - case 1: istr = 22; break; /*Working*/ - case 2: - case 3: - case 4: - case 5: - case 9: - case 10: istr = 23; break; /*Sleeping*/ - case 6: - case 7: - case 8: - case 11: - case 12: istr = 24; break; /*On*/ - case 13: istr = 21; break; /*Off*/ - default: istr = 41; /*unknown*/ - } - break; - case 0x23: /*Watchdog*/ - if (reading == 0) istr = 0; - else istr = 13; /*Asserted*/ - break; - case 0x24: /*Platform Alert*/ - b = bitnum(reading); - switch(b) { - case 0: istr = 0; break; /*OK, no bits set*/ - case 1: istr = 66; break; /*Page, bit 0 set*/ - case 2: istr = 67; break; /*LAN, bit 1 set*/ - case 3: istr = 68; break; /*PET*/ - case 4: istr = 69; break; /*SNMP OEM*/ - default: istr = 70; /*None*/ - } - break; - case 0x25: /* Entity Presence */ - if (reading & 0x01) istr = 8; /*Present*/ - else if (reading & 0x02) istr = 9; /*Absent*/ - else if (reading & 0x04) istr = 16; /*Disabled*/ - else istr = 42; /* NotAvailable */ - break; - case 0x28: /* BMC FW Health */ - if (evtype == 0x6F) { /*Sensor-specific*/ - if (reading == 0) istr = 0; /*OK*/ - else istr = 12; /*Faulty*/ - } else { /*use event/reading type*/ - istr = decode_comp_generic(type, evtype, num, reading); - } - break; - case 0x29: /* Battery */ - switch(reading & 0x7f) { - case 0x00: istr = 0; break; /*OK*/ - case 0x01: istr = 15; break; /*Predict Fail*/ - case 0x04: istr = 9; break; /*Present*/ - case 0x02: - default: istr = 12; break; /*Failed/Faulty*/ - } - break; - case 0x2A: /* Session Audit (IPMI 2.0) */ - if (reading == 0x00) istr = 45; /*Activated*/ - else istr = 46; /*Deactivated*/ - break; - case 0x2B: /* Version Change */ - b = bitnum(reading1); - switch(b) { - case 0: istr = 0; break; /*OK, no bits set*/ - case 1: istr = 72; break; /*HW Changed, bit 0 set*/ - case 2: istr = 73; break; /*SW Changed, bit 1 set*/ - case 3: istr = 74; break; /*HW incompatibility*/ - default: istr = 75; break; /*Change error*/ - } - break; - - /* sensor types 0xC0 - 0xFF are OEM RESERVED */ - case 0xF1: /* ATCA IPMB-0 Sensor */ - if ((reading & 0x7fff) == 0x0008) istr = 0; /*OK*/ - else istr = bitnum(reading1); /* other error, TODO: refine this */ - break; - case 0xC0: /* SMI State, NMI State */ - case 0xD8: /* BIST */ - case 0xF0: /* ATCA FRU HotSwap, TODO: refine this */ - case 0xF2: /* ATCA Module HotSwap, TODO: refine this */ - case 0xF3: /* SMI Timeout, etc. */ - if (reading & 0x01) istr = 13; /* Asserted */ - else istr = 0; /* "OK", Deasserted */ - break; - - case 0x60: /* SCSI 1 Term Flt */ - case 0x61: /* SCSI 2 Term Flt */ - default: - istr = decode_comp_generic(type, evtype, num, reading); - break; - } - return(istr); -} /* end decode_comp_reading */ - -#define STYPSZ 15 -static char *get_stype_str(uchar stype) -{ /*return sensor type string, with fixed length */ - static char stype_str[STYPSZ+1]; - char *tmpstr; - int i, n; - tmpstr = get_sensor_type_desc(stype); - n = strlen_(tmpstr); - if (n > STYPSZ) n = STYPSZ; - strncpy(stype_str,tmpstr,n); - for (i = n; i < STYPSZ; i++) stype_str[i] = ' '; - stype_str[i] = 0; - tmpstr = stype_str; - return(tmpstr); -} - -void -ShowSDR(char *tag, uchar *sdr) -{ - SDR01REC *sdr01; - SDR02REC *sdr02; - SDR08REC *sdr08; - SDR11REC *sdr11; - SDR12REC *sdr12; - SDR14REC *sdr14; - SDRc0REC *sdrc0; - char idstr[32]; - char *typestr = NULL; - int vend; - int len, ilen, i, j; - int ioff; - uchar sens[4]; - uchar sens_cap; - uchar shar_cnt; - int rc; - double val; - char brearm; - uchar sep[4]; - char rdgstr[50]; - - len = sdr[4] + 5; - sens_cap = 0x80; /*ignore*/ - if (fdebug) printf("ShowSDR: len=%d, type=%x\n",len,sdr[3]); - memset(sens,0,4); - if (frawsdr || fdebug) { - /* raw is different than dump_buf */ - printf("raw SDR: "); - for (i = 0; i < len; i++) - printf("%02x ",sdr[i]); - printf("\n"); - } - strcpy(idstr,"INIT"); /*always set idstr to some initial string*/ - switch(sdr[3]) - { - case 0x01: /* Full sensor record */ - sdr01 = (SDR01REC *)sdr; - ioff = 48; - if (ioff > len) { - if (fdebug) printf("bad length: type=%x, len=%d, ioff=%d\n", - sdr[3],len,ioff); - fprintf(stderr,"Bad SDR Length %d, please apply the correct FRU/SDR diskette\n",len); - return; - } - sens_cap = sdr[11]; /*sdr01->sens_capab*/ - // ilen = (sdr[ioff] & 0x1f); /*sdr01->id_typelen*/ - ilen = len - ioff; - if (fdebug) printf("SDR[%x] Full ioff=%d idTypLen=0x%02x ilen=%d\n", - sdr01->recid, ioff,sdr[ioff] ,ilen); - if (ilen >= sizeof(idstr)) ilen = sizeof(idstr) - 1; - if (ilen <= 0) { /*bug if true*/ - fprintf(stderr,"Bad SDR Length %d, omits ID string\n",len); - ilen = 16; /*less than sizeof(idstr)*/ - } - memcpy(idstr,&sdr[ioff],ilen); - for (i=ilen; i<16; i++) { idstr[i] = ' '; ilen++; } - idstr[ilen] = 0; /* stringify */ - if ((sdr01->sens_capab & 0x40) == 0) brearm = 'm'; /*manual rearm*/ - else brearm = 'a'; /*automatic rearm*/ - if (fdebug) printf("entity %d.%d, idlen=%d sizeof=%lu idstr0=%c s0=%x\n", - sdr01->entity_id, sdr01->entity_inst, - ilen,sizeof(SDR01REC),idstr[0],sdr[ioff]); - rc = GetSensorReading(sdr01->sens_num,sdr01,sens); - if (rc != 0) { /* if rc != 0, leave sens values zero */ - i = 41; /* Unknown */ - val = 0; - if (rc == 0xCB) { /*sensor not present*/ - i = 10; /* Absent */ - typestr = "na"; - } else typestr = decode_rv(rc); - } else { - j = (sens[2] & 0x3f); /*sensor reading state*/ - i = bitnum((ushort)j); /*sensor_dstatus index*/ - if (fdebug) - printf("bitnum(%02x)=%d raw=%02x init=%x base/units=%x/%x\n", - sens[2],i,sens[0],sens[1],sdr01->sens_base, - sdr01->sens_units); - if ((sens[1] & 0x20) != 0) { i = 7; val = 0; } /* Init state */ - else if (sdr01->sens_units == 0xC0) i = 42; /*reading NotAvailable*/ - else if (sens[2] == 0xc7) { i = 10; val = 0; /* Absent (Intel) */ - if (fdebug) printf("sensor[%x] is absent (c7), no reading\n", - sdr01->sens_num); - } - else val = RawToFloat(sens[0],sdr); - typestr = get_unit_type(sdr01->sens_units, sdr01->sens_base, - sdr01->sens_mod, fsimple); -#ifdef WRONG - if (is_romley(vend_id,prod_id) && - (sdr01->sens_type == 0x0C) && (sdr01->sens_units & 0x01)) - { /* Intel Memory Thermal Throttling %, raw 0x01 == 0.5 % */ - val = (val / 2); /* handle MTT SDR errata */ - } /*correct solution is to fix the SDR m-value instead */ -#endif - } - rc = decode_oem_sensor(sdr,sens,oem_string,sizeof(oem_string)); - if (rc == 0) { - if (fsimple) strncpy(rdgstr,oem_string,sizeof(rdgstr)); - else snprintf(rdgstr,sizeof(rdgstr),"%02x %s",sens[0],oem_string); - } else { - if (fsimple) - snprintf(rdgstr,sizeof(rdgstr),"%s %c %.2f %s", - sensor_dstatus[i],bdelim,val,typestr); - else - snprintf(rdgstr,sizeof(rdgstr),"%02x %s %.2f %s", - sens[0], sensor_dstatus[i],val,typestr); - } - sep[0] = 0; /*null string*/ - printf("%s", tag); - if (fsimple) { - sprintf(sep,"%c ",bdelim); - printf("%04x %c Full %c %s %c %02x %c %s %c %s%c", - sdr01->recid, bdelim, bdelim, - get_stype_str(sdr01->sens_type), - bdelim, sdr01->sens_num,bdelim, idstr, - bdelim,rdgstr,chEol); - } else - printf("%04x SDR Full %02x %02x %02x %c %02x snum %02x %s = %s%c", - sdr01->recid, sdr01->rectype, sdr01->ev_type, - sdr01->sens_ownid, brearm, sdr01->sens_type, sdr01->sens_num, - idstr, rdgstr, chEol); - if (fdebug && fshowthr) - printf("cap=%02x settable=%02x, readable=%02x\n", - sens_cap,sdr[19],sdr[18]); - if (sens_verbose) /* if -v, also show Entity ID */ - printf("\t%sEntity ID %d.%d (%s), Capab: %s%c", - sep, sdr01->entity_id, sdr01->entity_inst, - decode_entity_id(sdr01->entity_id), // sens_cap, - decode_capab(sens_cap),chEol); - if (fshowthr && (sens_cap & 0x0f) != 0x03) { - uchar thresh[7]; - /* Thresholds, so show them */ - /* Use settable bits to show thresholds, since the - * readable values will be off for Full SDRs. - * If cant set any thresholds, only show SDR thresholds */ - if (sdr[19] == 0) rc = 1; - else { - /* Show volatile thresholds. */ - rc = GetSensorThresholds(sdr01->sens_num,&thresh[0]); - if (rc == 0) ShowThresh(2,thresh[0],&thresh[1],sdr); - } - /* Show SDR non-volatile thresholds. */ - if (sens_verbose || rc !=0) ShowThresh(0,sdr[18],&sdr[36],sdr); - // ShowThresh(0,0x3f,&sdr[36],sdr); /* to show all %%%% */ - } - if (fwrap) { /* (chEol != '\n') include time */ - time_t ltime; - time(<ime); - if (fsimple) - printf("%c %s",bdelim,ctime(<ime)); /*ctime has '\n' */ - else - printf("at %s",ctime(<ime)); /*ctime has '\n' */ - } - break; - case 0x02: /* Compact sensor record */ - sdr02 = (SDR02REC *)sdr; - ioff = 32; - if (ioff > len) { - if (fdebug) printf("bad length: type=%x, len=%d, ioff=%d\n", - sdr[3],len,ioff); - fprintf(stderr,"Bad SDR Length, please apply the correct FRU/SDR diskette\n"); - return; - } - sens_cap = sdr[11]; /*sdr02->sens_capab*/ - shar_cnt = sdr02->shar_cnt & 0x0f; /*sdr[23]*/ - ilen = len - ioff; - if ((ilen+1) >= sizeof(idstr)) ilen = sizeof(idstr) - 2; - memcpy(idstr,&sdr[ioff],ilen); - if ((shar_cnt > 1) && (sdr02->shar_off & 0x80) != 0) { /*do shared SDR*/ - j = (sdr02->shar_off & 0x7f); /*sdr[24] = modifier offset*/ - if (fdebug) printf("share count = %d, mod_offset = %d\n",shar_cnt,j); - if ((sdr02->shar_cnt & 0x10) != 0) { /*alpha*/ - idstr[ilen++] = 0x40 + j; /* j=1 -> 'A' */ - idstr[ilen] = 0; /* stringify */ - } else { /*numeric*/ - sprintf(&idstr[ilen],"%d",j); - ilen = strlen_(idstr); - } - } /* else normal idstr */ - for (i=ilen; i<16; i++) { idstr[i] = ' '; ilen++; } - idstr[ilen] = 0; /* stringify */ - if ((sdr02->sens_capab & 0x40) == 0) brearm = 'm'; /*manual rearm*/ - else brearm = 'a'; /*automatic rearm*/ - if (fdebug) printf("ilen=%d, istr0=%c, sizeof=%zu, s0=%x\n", - ilen,idstr[0],sizeof(SDR02REC),sdr[ioff]); - memset(sens,0,sizeof(sens)); - rc = GetSensorReading(sdr02->sens_num,sdr02,sens); - if (rc != 0) { /* if rc != 0, leave sens values zero */ - i = 41; /* Unknown */ - val = 0; - if (rc == 0xCB) { /*sensor not present*/ - i = 10; /* Absent */ - typestr = "na"; - } else typestr = decode_rv(rc); - } else { - if ((sens[1] & 0x20) != 0) i = 42; /*init state, NotAvailable*/ - else { - rc = decode_oem_sensor(sdr,sens,oem_string,sizeof(oem_string)); - if (rc == 0) i = STR_OEM; - else i = decode_comp_reading(sdr02->sens_type,sdr02->ev_type, - sdr02->sens_num,sens[2],sens[3]); - } - } - if (fdebug) - printf("snum %x type %x evt %x reading %02x%02x i=%d rc=%d %s\n", - sdr02->sens_num,sdr02->sens_type,sdr02->ev_type, - sens[3],sens[2],i,rc, decode_rv(rc)); - j = sens[2] | ((sens[3] & 0x7f) << 8); /*full reading, less h.o. bit*/ - sep[0] = 0; /*null string*/ - printf("%s", tag); - if (fsimple) { - sprintf(sep,"%c ",bdelim); - printf("%04x %c Compact %c %s %c %02x %c %s %c %s %c%c", - sdr02->recid, bdelim, bdelim, - get_stype_str(sdr02->sens_type), - bdelim, sdr02->sens_num, bdelim, idstr, - bdelim, sensor_dstatus[i],bdelim,chEol); - } else if (i == STR_OEM) { - // idstr[ilen] = 0; /*cut out padding in idstr*/ - printf("%04x SDR Comp %02x %02x %02x %c %02x snum %02x %s = %04x %s%c", - sdr02->recid, sdr02->rectype, sdr02->ev_type, - sdr02->sens_ownid, brearm, sdr02->sens_type, sdr02->sens_num, - idstr, j, sensor_dstatus[i],chEol); - // sensor_dstatus[i] == oem_string - } else { - printf("%04x SDR Comp %02x %02x %02x %c %02x snum %02x %s = %04x %s%c", - sdr02->recid, sdr02->rectype, sdr02->ev_type, - sdr02->sens_ownid, brearm, sdr02->sens_type, sdr02->sens_num, - idstr, j, sensor_dstatus[i],chEol); - /* idstr, sens[0], sens[1], sens[2], sens[3], */ - } - if (fdebug && fshowthr) - printf("cap=%02x settable=%02x, readable=%02x\n", - sens_cap,sdr[19],sdr[18]); - if (fshowthr) /*also show Entity ID */ - printf("\t%sEntity ID %d.%d (%s), Capab: %s%c", - sep, sdr02->entity_id, sdr02->entity_inst, - decode_entity_id(sdr02->entity_id), // sens_cap, - decode_capab(sens_cap),chEol); - if (fshowthr && - ((sens_cap & 0x80) == 0) && (sens_cap & 0x0C) != 0) { - uchar thresh[7]; - /* Thresholds, show them */ - /* Use readable bits to get & show thresholds */ - if (sdr[20] != 0) { - rc = GetSensorThresholds(sdr02->sens_num,&thresh[0]); - if (rc == 0) ShowThresh(1,thresh[0],&thresh[1],sdr); - } - } - if (fwrap) { /*include time and \n */ - time_t ltime; - time(<ime); - if (fsimple) - printf("%c %s",bdelim,ctime(<ime)); /*ctime has '\n' */ - else - printf("at %s",ctime(<ime)); /*ctime has '\n' */ - } - break; - case 0x03: /* Event-only sensor record, treat like Compact SDR */ - sdr02 = (SDR02REC *)sdr; - ioff = 17; - if (ioff > len) { - fprintf(stderr,"Bad SDR %x Length %d. Please apply the correct FRU/SDR diskette\n", - sdr02->recid, len); - return; - } - if (!fsimple) - { - ilen = len - ioff; - if (ilen >= sizeof(idstr)) ilen = sizeof(idstr) - 1; - memcpy(idstr,&sdr[ioff],ilen); - for (i=ilen; i<16; i++) { idstr[i] = ' '; ilen++; } - idstr[ilen] = 0; /* stringify */ - sens_cap = sdr[11]; - memset(sens,0,sizeof(sens)); - if ((sdr02->sens_capab & 0x40) == 0) brearm = 'm'; /*manual rearm*/ - else brearm = 'a'; /*automatic rearm*/ - // rc = GetSensorReading(sdr02->sens_num,sdr02,sens); - /* EvtOnly SDRs do not support readings. - * GetSensorReading would return ccode=0xCB (not present), - * but this skips error msg */ - rc = 0xCB; - i = bitnum((ushort)sens[2]); - j = sens[2] | ((sens[3] & 0x7f) << 8); - printf("%s",tag); - printf("%04x SDR EvtO %02x %02x %02x %c %02x snum %02x %s = %04x %s\n", - sdr02->recid, sdr02->rectype, sdr02->reclen, - sdr02->sens_ownid, 'a', sdr[10], sdr02->sens_num, - idstr, j, sensor_dstatus[i]); - // sens[0], sens[1], sens[2], sens[3], sensor_dstatus[i] - } - break; - case 0x08: /* Entity Association record */ - sdr08 = (SDR08REC *)sdr; - if (!fsimple) - { - printf("%s",tag); - printf("%04x SDR EntA %02x %02x %02x %02x %02x: ", - sdr08->recid, sdr08->rectype, sdr08->reclen, - sdr08->contid, sdr08->continst, sdr08->flags); - for (i = 0; i < 8; i++) printf("%02x ",sdr08->edata[i]); - printf("\n"); - } - break; - case 0x09: /* Device-relative Entity Association record */ - sdr08 = (SDR08REC *)sdr; /*but SDR09 is 26 bytes*/ - if (!fsimple) - { - printf("%s",tag); - printf("%04x SDR DEnt %02x %02x %02x %02x %02x %02x %02x: ", - sdr08->recid, sdr08->rectype, sdr08->reclen, - sdr08->contid, sdr08->continst, sdr08->flags, - sdr08->edata[0], sdr08->edata[1]); - /*display 2 of 4 contained entity devices edata[2-10] */ - for (i = 2; i < 8; i++) printf("%02x ",sdr08->edata[i]); - printf("\n"); - } - break; - case 0x10: /* Generic Device Locator record */ - sdr11 = (SDR11REC *)sdr; - ioff = 16; - if (ioff > len) { - if (fdebug) printf("SDR %x bad length: type=%x, len=%d, ioff=%d\n", - sdr11->recid, sdr[3],len,ioff); - return; - } - if (!fsimple) - { - ilen = len - ioff; - if (ilen >= sizeof(idstr)) ilen = sizeof(idstr) - 1; - memcpy(idstr,&sdr[ioff],ilen); - idstr[ilen] = 0; /* stringify */ - printf("%s", tag); - if (fsimple) - printf("DevLocator record[%x]%c device %02x %c %s\n", - sdr11->recid, bdelim,sdr11->dev_slave_adr,bdelim,idstr); - else - printf("%04x SDR DLoc %02x %02x dev: %02x %02x %02x %02x %02x %02x %s\n", - sdr11->recid, sdr11->rectype, sdr11->reclen, - sdr11->dev_access_adr, sdr11->dev_slave_adr, - sdr11->access_lun, sdr[8], sdr[10], sdr[11], - idstr); - } - break; - case 0x11: /* FRU record */ - sdr11 = (SDR11REC *)sdr; - ioff = 16; - if (ioff > len) { - if (fdebug) printf("SDR %x bad length: type=%x len=%d ioff=%d\n", - sdr11->recid, sdr[3],len,ioff); - printf("Please apply the correct FRU/SDR diskette\n"); - return; - } - if (!fsimple) - { - ilen = len - ioff; - if (ilen >= sizeof(idstr)) ilen = sizeof(idstr) - 1; - memcpy(idstr,&sdr[ioff],ilen); - idstr[ilen] = 0; /* stringify */ - if (fdebug) printf("ilen=%d, istr0=%c, sizeof=%zu, s0=%x\n", - ilen,idstr[0],sizeof(SDR11REC),sdr[ioff]); - printf("%s", tag); - if (fsimple) - printf("FRU record[%x]: device %02x : %s\n", - sdr11->recid, sdr11->dev_slave_adr,idstr); - else - printf("%04x SDR FRU %02x %02x dev: %02x %02x %02x %02x %02x %02x %s\n", - sdr11->recid, sdr11->rectype, sdr11->reclen, - sdr11->dev_access_adr, sdr11->dev_slave_adr /*fru_id*/, - sdr11->access_lun, sdr11->chan_num, - sdr11->entity_id, sdr11->entity_inst, - idstr); - } - break; - case 0x12: /* IPMB record */ - sdr12 = (SDR12REC *)sdr; - ioff = 16; - if (ioff > len) { - if (fdebug) printf("bad length: type=%x, len=%d, ioff=%d\n", - sdr[3],len,ioff); - printf("Please apply the correct FRU/SDR diskette\n"); - return; - } - if (!fsimple) - { - ilen = len - ioff; - if (ilen >= sizeof(idstr)) ilen = sizeof(idstr) - 1; - memcpy(idstr,&sdr[ioff],ilen); - idstr[ilen] = 0; /* stringify */ - if (fdebug) printf("ilen=%d, istr0=%c, sizeof=%zu, s0=%x\n", - ilen,idstr[0],sizeof(SDR12REC),sdr[ioff]); - printf("%s", tag); - if (fsimple) - printf("IPMB record[%x]%c addr %02x %02x %c %s\n", - sdr12->recid, bdelim,sdr12->dev_slave_adr, - sdr12->chan_num,bdelim,idstr); - else - printf("%04x SDR IPMB %02x %02x dev: %02x %02x %02x %02x %02x %s\n", - sdr12->recid, sdr12->rectype, sdr12->reclen, - sdr12->dev_slave_adr, sdr12->chan_num, sdr12->dev_capab, - sdr12->entity_id, sdr12->entity_inst, - idstr); - } - break; - case 0x14: /* BMC Message Channel Info record */ - sdr14 = (SDR14REC *)sdr; - if(!fsimple){ - printf("%s", tag); - printf("%04x SDR BMsg %02x %02x: ", - sdr14->recid, sdr14->rectype, sdr14->reclen ); - for (i = 0; i < 8; i++) printf("%02x ",sdr14->mdata[i]); - printf("%s %s %02x\n",decode_itype(sdr14->mint), - decode_itype(sdr14->eint), sdr14->rsvd); - } - break; - case 0xc0: /* OEM SDR record (manuf_id 343. = Intel) */ - sdrc0 = (SDRc0REC *)sdr; - if(!fsimple) - { - vend = sdrc0->manuf_id[0] + (sdrc0->manuf_id[1] << 8) - + (sdrc0->manuf_id[2] << 16); - printf("%s",tag); - printf("%04x SDR OEM %02x %02x ", - sdrc0->recid, sdrc0->rectype, sdrc0->reclen); - show_oemsdr(vend,sdr); - } - break; - default: - sdrc0 = (SDRc0REC *)sdr; - /* also saw type = 0x08 & 0x14 on STL2s */ - if (!fsimple){ - printf("%s", tag); - printf("%04x SDR type=%02x ", sdrc0->recid, sdr[3]); - for (i = 0; i < len; i++) printf("%02x ",sdr[i]); - printf("\n"); - } - } - return; -} - -static int -ShowPowerOnHours(void) -{ - uchar resp[MAX_BUFFER_SIZE]; - int sresp = MAX_BUFFER_SIZE; - uchar cc; - int rc = -1; - int i; - unsigned int hrs; - - if (fmBMC) return(0); - if (fsimple) return(0); - sresp = MAX_BUFFER_SIZE; - memset(resp,0,6); /* default response size is 5 */ - rc = ipmi_cmd_mc(GET_POWERON_HOURS, NULL, 0, resp, &sresp, &cc, fdebug); - if (rc == 0 && cc == 0) { - /* show the hours (32-bits) */ - hrs = resp[1] | (resp[2] << 8) | (resp[3] << 16) | (resp[4] << 24); - /*60=normal, more is OOB, so avoid div-by-zero*/ - if ((resp[0] <= 0) || (resp[0] >= 60)) i = 1; - else { - i = 60 / resp[0]; - hrs = hrs / i; - } - printf(" SDR IPMI sensor: Power On Hours \t = %d hours\n", - hrs); - } - if (fdebug) { - printf("PowerOnHours (rc=%d cc=%x len=%d): ",rc,cc,sresp); - if (rc == 0) - for (i = 0; i < sresp; i++) printf("%02x ",resp[i]); - printf("\n"); - } - return(rc); -} - -int SaveThreshold(int id, int sensor_num, int sensor_lo, int sensor_hi, - uchar *thr_set) -{ - int rv = 0; - char lostr[20]; - char histr[20]; - FILE *fd; - - /* persist the thresholds by re-applying with ipmiutil sensor commands.*/ - if (thr_set != NULL) { - sprintf(lostr,"-u 0x%02x%02x%02x%02x%02x%02x", - sensor_thr[0], sensor_thr[1], sensor_thr[2], - sensor_thr[3], sensor_thr[4], sensor_thr[5]); - histr[0] = 0; /*empty string*/ - } else { - if (sensor_lo != 0xff) { - sprintf(lostr,"-l 0x%02x",sensor_lo); - } else lostr[0] = 0; - if (sensor_hi != 0xff) { - sprintf(histr,"-h 0x%02x",sensor_hi); - } else histr[0] = 0; - } - fd = fopen(savefile,"a+"); - if (fd == NULL) return(-1); - fprintf(fd, "ipmiutil sensor -i 0x%04x -n 0x%02x %s %s\n", id, sensor_num, - lostr,histr); - fclose(fd); - return(rv); -} - -#ifdef NOT_USED -#define PICMG_GET_ADDR_INFO 0x01 -static int get_picmg_addrinfo(uchar a1, uchar a2, uchar *addrdata) -{ - uchar idata[5]; - uchar rdata[16]; - int rlen; - ushort icmd; - uchar ilen, cc; - int rv; - - idata[0] = 0x00; - idata[1] = 0x00; - idata[2] = 0x03; - idata[3] = a1; /* 01 thru 0f */ - idata[4] = a2; /* 00, 01 thru 09 */ - ilen = 5; - rlen = sizeof(rdata); - icmd = PICMG_GET_ADDR_INFO | (NETFN_PICMG << 8); - rv = ipmi_cmd_mc(icmd, idata, ilen, rdata, &rlen, &cc, fdebug); - if (rv == 0 && cc != 0) rv = cc; - if (rv == 0) { - if (fdebug) { - printf("picmg_addr(%02x,%02x)",a1,a2); - dump_buf("picmg_addr",rdata,rlen,0); - } - memcpy(addrdata,rdata,rlen); - } - return(rv); -} -#endif - -#ifdef WIN32 -static int get_filesize(char *fileName, ulong *psize) -{ - int rv; - WIN32_FILE_ATTRIBUTE_DATA fileInfo; - - if (fileName == NULL) return -1; - if (psize == NULL) return -1; - rv = GetFileAttributesEx(fileName, GetFileExInfoStandard, (void*)&fileInfo); - if (!rv) return -1; - *psize = (long)fileInfo.nFileSizeLow; - return 0; -} -#endif - -int write_sdr_binfile(char *binfile) -{ - uchar *pbuf = NULL; - FILE *fp; - int len, ret; - ret = get_sdr_cache(&pbuf); /* sets nsdrs, sz_sdrs */ - if (ret == 0) { - fp = fopen(binfile,"wb"); - if (fp == NULL) { - ret = get_LastError(); - printf("Cannot open file %s for writing, error %d\n",binfile,ret); - } else { - printf("Writing SDR size %d to %s ...\n",sz_sdrs,binfile); - len = (int)fwrite(pbuf, 1, sz_sdrs, fp); - fclose(fp); - if (len <= 0) { - ret = get_LastError(); - printf("Error %d writing file %s\n",ret,binfile); - } else ret = 0; - } - free_sdr_cache(pbuf); - } - return(ret); -} - -int read_sdr_binfile(char *binfile, uchar **pbufret, int *buflen) -{ - uchar *pbuf = NULL; - FILE *fp; - int len; - int ret; -#ifdef WIN32 - { - ulong flen; - ret = get_filesize(binfile, &flen); - if (ret == 0) len = flen; - else { - ret = get_LastError(); - printf("Cannot get file size for %s, error %d\n",binfile,ret); - return(ret); - } - } -#endif - fp = fopen(binfile,"rb"); - if (fp == NULL) { - ret = get_LastError(); - printf("Cannot open file %s, error %d\n",binfile,ret); - return(ret); - } - fseek(fp, 0L, SEEK_SET); -#ifndef WIN32 - { /*not windows but Linux, etc.*/ - struct stat st; - /* use fstat to get file size and allocate buffer */ - ret = fstat(fileno(fp), &st); - len = st.st_size; /*file size in bytes*/ - if (ret != 0) { - ret = get_LastError(); - printf("Cannot stat file %s, error %d\n",binfile,ret); - return(ret); - } - } -#endif - /* Could estimate size for nsdrs*SDR_SZ, but we don't yet know nsdrs. - * It is better to use the real file size detected above. */ - sz_sdrs = len; - pbuf = malloc(len); - if (fdebug) printf("sdr_binfile: malloc(%d) pbuf=%p\n",len,pbuf); - if (pbuf == NULL) { - ret = -2; - fclose(fp); - return(ret); - } - psdrcache = pbuf; - /*ok, so proceed with restore*/ - ret = 0; - len = (int)fread(pbuf, 1, sz_sdrs, fp); - if (len <= 0) { - ret = get_LastError(); - printf("Error %d reading file %s\n",ret,binfile); - sz_sdrs = 0; /*for safety*/ - } else if (len < sz_sdrs) { - /* Show error if this happens in Windows */ - ret = get_LastError(); - printf("truncated fread(%s): attempted %d, got %d, error %d\n", - binfile,sz_sdrs,len,ret); - ret = 0; /*try to keep going*/ - } - fclose(fp); - if (fdebug) { - printf("SDR buffer from file (len=%d,sz=%d)\n",len,sz_sdrs); - dump_buf("SDR buffer",pbuf,len,1); - } - *pbufret = pbuf; - *buflen = len; - return(ret); -} - -#ifdef ALONE -#ifdef WIN32 -int __cdecl -#else -int -#endif -main(int argc, char **argv) -#else -/* METACOMMAND or libipmiutil */ -int i_sensor(int argc, char **argv) -#endif -{ - int ret, rv; - int c; - int recid, recnext; - uchar sdrdata[MAX_BUFFER_SIZE]; - uchar devrec[16]; - int sz, i, j; - int fsetfound = 0; - int iloop, irec; - int ipass, npass; - uchar *pset; - char *p; - char *s1; - - printf("%s version %s\n",progname,progver); - - while ( (c = getopt( argc, argv,"a:bcd:ef:g:h:i:j:k:l:m:n:opqrstu:vwxT:V:J:L:EYF:P:N:R:U:Z:?")) != EOF ) - switch(c) { - case 'a': /* reArm sensor number N */ - if (strncmp(optarg,"0x",2) == 0) frearm = htoi(&optarg[2]); - else frearm = htoi(optarg); /*was atoi()*/ - break; - case 'c': fsimple = 1; break; /* Canonical/simple output*/ - case 'd': fdump = 1; /* Dump SDRs to a file*/ - binfile = optarg; break; - case 'b': fchild = 1; break; /* Bladed, so get child SDRs */ - case 'e': fchild = 1; break; /* Extra bladed child SDRs */ - case 'f': frestore = 1; /* Restore SDRs from a file*/ - binfile = optarg; break; - case 's': fsimple = 1; break; /* Simple/canonical output */ - /*fcanonical==fsimple*/ - case 'g': - rv = get_group_id(optarg); - if (rv < 0) { - printf("Unrecognized sensor type group (%s)\n",optarg); - ret = ERR_BAD_PARAM; - goto do_exit; - } else fshowgrp = rv; - if (fdebug) printf("num sensor type groups = %d\n",fshowgrp); - break; - case 'i': - fshowidx = 1; - get_idx_range(optarg); - break; - case 'j': fjumpstart = 1; /* Load SDR cache from a file*/ - binfile = optarg; break; - case 'k': loopsec = atoi(optarg); break; /*N sec between loops*/ - case 'm': /* specific MC, 3-byte address, e.g. "409600" */ - g_bus = htoi(&optarg[0]); /*bus/channel*/ - g_sa = htoi(&optarg[2]); /*device slave address*/ - g_lun = htoi(&optarg[4]); /*LUN*/ - if (optarg[6] == 's') { - g_addrtype = ADDR_SMI; s1 = "SMI"; - } else { g_addrtype = ADDR_IPMB; s1 = "IPMB"; } - fset_mc = 1; - printf("set MC at %s bus=%x sa=%x lun=%x\n", - s1,g_bus,g_sa,g_lun); - break; - case 'o': - fgetmem = 1; - break; - case 'n': - if (strncmp(optarg,"0x",2) == 0) i = htoi(&optarg[2]); - else i = htoi(optarg); /*was atoi()*/ - sensor_num = (uchar)i; - printf("sensor_num = 0x%x\n",sensor_num); - break; - case 'h': /* highest threshold */ - if (strncmp(optarg,"0x",2) == 0) { - i = htoi(&optarg[2]); - sensor_hi = (uchar)i; - fsetthresh = 1; - } else { - sensor_hi_f = atof(optarg); - fsetthresh = 2; /*indicates float conversion*/ - } - break; - case 'l': /* lowest threshold */ - if (strncmp(optarg,"0x",2) == 0) { - i = htoi(&optarg[2]); - sensor_lo = (uchar)i; - fsetthresh = 1; - } else { - sensor_lo_f = atof(optarg); - fsetthresh = 2; /*indicates float conversion*/ - } - break; - case 'p': fsavethresh = 1; break; - case 'q': fshowthr = 2; fwrap = 1; break; - case 'r': frawsdr = 1; break; - case 't': fshowthr = 1; break; - case 'v': fshowthr = 1; sens_verbose = 1; break; - case 'u': /* specify unique thresholds in hex or float */ - /* raw hex format: 0xLNLCLUHNHCHU, all 6 required */ - if (strncmp(optarg,"0x",2) == 0) { /*raw hex thresholds*/ - sensor_thr[0] = htoi(&optarg[2]); /*lo noncrit*/ - sensor_thr[1] = htoi(&optarg[4]); /*lo crit*/ - sensor_thr[2] = htoi(&optarg[6]); /*lo unrec*/ - sensor_thr[3] = htoi(&optarg[8]); /*hi noncrit*/ - sensor_thr[4] = htoi(&optarg[10]); /*hi crit*/ - sensor_thr[5] = htoi(&optarg[12]); /*hi unrec*/ - /* validate sensor threshold ordering */ - rv = validate_thresholds(&sensor_thr[0],0,NULL); - if (rv == 0) { - sensor_lo = sensor_thr[0]; - sensor_hi = sensor_thr[3]; - fsetthresh = 3; /*indicates unique raw thresholds */ - } else { - ret = ERR_BAD_PARAM; - goto do_exit; - } - } else { - /* assume float input thresholds, with ':' separator*/ - /* format LN:LC:LU:HN:HC:HU */ - sz = strlen_(optarg); - p = &optarg[0]; - for (i = 0; i < 6; i++) sensor_thrf[i] = THR_EMPTY; - j = 0; - for (i = 0; i <= sz; i++) { - if (j >= 6) break; - switch(optarg[i]) { - case ':': - case '\n': - case '\0': - optarg[i] = 0; - if (p[0] == 0) sensor_thrf[j] = THR_EMPTY; - else sensor_thrf[j] = atof(p); - if (i+1 < sz) p = &optarg[i+1]; - j++; - break; - default: - break; - } - } - /* validate sensor threshold ordering later */ - // rv = validate_thresholds(&sensor_thrf[0],1,NULL); - // if (rv == 0) { - sensor_lo_f = sensor_thrf[0]; - sensor_hi_f = sensor_thrf[3]; - fsetthresh = 4; /*indicates unique float thresholds */ - // } else { - // ret = ERR_BAD_PARAM; - // goto do_exit; - // } - } /*end-else -u float thresholds*/ - break; - case 'w': fwrap = 1; break; - case 'x': fdebug = 1; break; - case 'L': /* Loop */ - nloops = atoi(optarg); - fdoloop = 1; - break; - case 'V': /* priv level */ - fprivset = 1; - case 'N': /* nodename */ - case 'U': /* remote username */ - case 'P': /* remote password */ - case 'R': /* remote password */ - case 'E': /* get password from IPMI_PASSWORD environment var */ - case 'F': /* force driver type */ - case 'T': /* auth type */ - case 'J': /* cipher suite */ - case 'Y': /* prompt for remote password */ - case 'Z': /* set local MC address */ - parse_lan_options(c,optarg,fdebug); - break; - default: /*usage*/ - printf("Usage: %s [-abcdefghijlmnprstuvwxL -NUPREFTVYZ]\n",progname); - printf("where -x shows eXtra debug messages\n"); - printf(" -a snum reArms the sensor (snum) for events\n"); - printf(" -b show Bladed child MCs for PICMG (same as -e)\n"); - printf(" -c displays a simpler, Canonical output fmt\n"); - printf(" -d file Dump SDRs to a binary file\n"); - printf(" -e show Every bladed child MC for PICMG\n"); - // printf(" -f file Restore SDRs from a binary dump file\n"); - printf(" -g fan show only this sensor type group\n"); - printf(" -h tval specifies the Highest threshold to set\n"); - printf(" -i id only show these sensor id numbers\n"); - printf(" -j file Jump-start SDR cache from a binary file\n"); - printf(" -k K If -L, wait K sec between loops (default=1)\n"); - printf(" -l tval specifies the Lowest threshold to set\n"); - printf(" -m002000 specific MC (bus 00,sa 20,lun 00)\n"); - printf(" -n snum specifies the sensor Number to set hi/lo\n"); - printf(" -o output memory DIMM information\n"); - printf(" -p persist the threshold being set\n"); - printf(" -q shows threshold values in d:d:d format\n"); - printf(" -r show Raw SDR bytes\n"); - printf(" -s displays a Simpler output format\n"); - printf(" -t shows Threshold values in text format\n"); - printf(" -u thr set Unique threshold values (e.g. 3:2:1:48:49:50)\n"); - printf(" -v Verbose: thresholds, max/min, hysteresis\n"); - printf(" -w Wrap thresholds on sensor line\n"); - printf(" -L n Loop n times every k seconds (default k=1)\n"); - print_lan_opt_usage(0); - ret = ERR_USAGE; - goto do_exit; - } - if (fjumpstart && fchild) { - printf("Cannot use -j jumpstart cache with -c child SDRs\n"); - ret = ERR_BAD_PARAM; - goto do_exit; - } - fremote = is_remote(); -#ifndef WIN32 - if (fremote == 0) { - /* only run this as superuser for accessing IPMI devices. */ - i = geteuid(); - if (i > 1) { - printf("Not superuser (%d)\n", i); - /* Show warning, but could be ok if /dev/ipmi0 is accessible */ - //ret = ERR_NOT_ALLOWED; - //goto do_exit; - } - } -#endif - if (fremote) { - if (!fprivset) { - /* on many systems, getting the SDR Reservation ID requires admin */ - /* if ((fsetthresh != 0) || (frearm != 0)) also require admin */ - parse_lan_options('V',"4",0); - } - } - - ret = ipmi_getdeviceid(devrec,sizeof(devrec),fdebug); - if (ret == 0) { - uchar ipmi_maj; - uchar ipmi_min; - char *pstr; - ipmi_maj = devrec[4] & 0x0f; - ipmi_min = devrec[4] >> 4; - if ((devrec[1] & 0x80) == 0x80) fdevsdrs = 1; - vend_id = devrec[6] + (devrec[7] << 8) + (devrec[8] << 16); - prod_id = devrec[9] + (devrec[10] << 8); - if (vend_id == VENDOR_NSC) { /*NSC mBMC*/ - pstr = "mBMC"; - fmBMC = 1; - fdevsdrs = 0; - } else if (vend_id == VENDOR_INTEL) { /*Intel BMC*/ - /*Intel Sahalee BMC */ - pstr = "BMC"; - fmBMC = 0; - if (is_romley(vend_id,prod_id)) fRomley = 1; - if (is_grantley(vend_id,prod_id)) fGrantley = 1; - if (prod_id == 0x003E || fRomley || fGrantley) /*Urbanna,CG2100*/ - set_max_kcs_loops(URNLOOPS); /*longer KCS timeout*/ - } else if ((vend_id == VENDOR_SUPERMICRO) - || (vend_id == VENDOR_SUPERMICROX)) { - set_max_kcs_loops(URNLOOPS); /*longer KCS timeout*/ - } else if (vend_id == 16394) { /*Pigeon Point*/ - fbadsdr = 1; /* SDR has bad sa/mc value, so ignore it */ - } else { /* Other products */ - pstr = "BMC"; - fmBMC = 0; - if (vend_id == VENDOR_NEC) fdevsdrs = 0; - } - show_devid( devrec[2], devrec[3], ipmi_maj, ipmi_min); - // "-- %s version %x.%x, IPMI version %d.%d \n", pstr, - } else { - goto do_exit; - } - - ret = ipmi_getpicmg( devrec, sizeof(devrec),fdebug); - if (ret == 0) fpicmg = 1; - /*if not PICMG, some vendors override to SDR Rep*/ - fdevsdrs = use_devsdrs(fpicmg); - if (fdevsdrs) printf("supports device sdrs\n"); - npass = 1; - if (g_sa != 0) { - /* target a specific MC via IPMB (usu a picmg blade) */ - ipmi_set_mc(g_bus,g_sa,g_lun,g_addrtype); - fchild = 0; /* no children, only the specified address */ - } else { -#ifdef PICMG_CHILD - /* fchild set above if -b is specified to get Blade child SDRs */ - /* npass = 2 will get both SdrRep & DevSdr passes on CMM */ - if (fpicmg && fdevsdrs) { - npass = 2; - g_addrtype = ADDR_IPMB; - } -#endif - g_sa = BMC_SA; - } - - if (fgetmem) { - if (fremote) printf("Cannot get memory DIMM information remotely.\n"); - else { - int msz; - char desc[80]; - char szstr[25]; - ret = -1; - for (j = 0; j < 1; j++) { - for (i = 0; i < 16; i++) { - rv = get_MemDesc(j, i, desc,&msz); - if (rv == 0) { - if (msz == 0) strcpy(szstr,"not present"); - else if (msz & 0x8000) - sprintf(szstr,"size=%dKB",(msz & 0x7FFF)); - else sprintf(szstr,"size=%dMB",msz); - printf("Memory Device (%d,%d): %s : %s\n", - j,i,desc,szstr); - ret = 0; - } - } - } - } /*end-else*/ - goto do_exit; - } - - if (fdump) { - ret = write_sdr_binfile(binfile); - goto do_exit; - } /*endif fdump*/ - - if (frestore) { - uchar sdr[MAX_BUFFER_SIZE]; - ushort id; - int slen; - uchar *pbuf = NULL; - - ret = read_sdr_binfile(binfile,&pbuf,&slen); - if (ret == 0) { /*successful, so write SDRs */ - nsdrs = find_nsdrs(pbuf); - printf("Ready to restore %d SDRs\n",nsdrs); - set_reserve(1); - ret = sdr_clear_repo(fdevsdrs); - if (ret != 0) { - printf("SDR Clear Repository error %d\n",ret); - goto do_exit; - } - id = 0; - while(find_sdr_next(sdr,pbuf,id) == 0) { - id = sdr[0] + (sdr[1] << 8); - if (fdebug) printf("adding SDR[%x]\n",id); - set_reserve(1); - ret = sdr_add_record(sdr,fdevsdrs); - if (ret != 0) { - printf("SDR[%x] add error %d\n",id,ret); - break; - } - } /*end while sdr*/ - } - if (ret == 0) printf("Restored %d SDRs successfully.\n",nsdrs); - free_sdr_cache(pbuf); /* does nothing if (pbuf == NULL) */ - goto do_exit; - } /*endif frestore*/ - - if (fjumpstart) { - uchar *pbuf = NULL; - int slen; - ret = read_sdr_binfile(binfile,&pbuf,&slen); - if (ret != 0) { - /* Try to dump sdrs to this file if not there */ - ret = write_sdr_binfile(binfile); - if (ret == 0) - ret = read_sdr_binfile(binfile,&pbuf,&slen); - if (ret != 0) { - fjumpstart = 0; /*cannot do jumpstart*/ - } - } else { /* set this as the SDR cache */ - psdrcache = pbuf; - sz_sdrs = slen; - nsdrs = find_nsdrs(pbuf); - if (fdebug) printf("jumpstart cache: nsdrs=%d size=%d\n",nsdrs,slen); - } - } /*endif fjumpstart*/ - - for (ipass = 0; ipass < npass; ipass++) - { - if (fjumpstart) ; /*already got this above*/ - else { - ret = GetSDRRepositoryInfo(&j,&fdevsdrs); - if (fdebug) printf("GetSDRRepositoryInfo: ret=%x nSDRs=%d\n",ret,j); - if (ret == 0 && j == 0) { - printf("SDR Repository is empty\n"); - goto do_exit; - } - nsdrs = j; - } - - /* show header for SDR records */ - if (fsimple) - printf(" ID | SDRType | Type |SNum| Name |Status| Reading\n"); - else - printf("_ID_ SDR_Type_xx ET Own Typ S_Num Sens_Description Hex & Interp Reading\n"); - - if (fwrap) chEol = ' '; - if (!fdoloop) nloops = 1; - for (iloop = 0; iloop < nloops; iloop++) - { - if (fshowidx) recid = sensor_idx1; - else recid = 0; - irec = 0; /*first sdr record*/ - while (recid != 0xffff) - { - if (fjumpstart) { - if (irec == 0) /*need sdr_by_id if fshowid recid>0*/ - ret = find_sdr_by_id(sdrdata,psdrcache,recid); - else ret = find_sdr_next(sdrdata,psdrcache,recid); - if (ret != 0) { /*end of sdrs*/ - if (fdebug) printf("find_sdr_next(%04x): ret = %d\n", recid,ret); - ret = 0; break; - } - recnext = sdrdata[0] + (sdrdata[1] << 8); /*same as recid*/ - if (fdebug) printf("find_sdr_next(%04x): ret = %d, next=%04x\n", - recid,ret,recnext); - if (recid > 0 && recnext == 0) { - if (fdebug) printf("Error recid=%04x recnext=%04x\n",recid,recnext); - ret = 0; break; - } - sz = sdrdata[4] + 5; - } else { - int try; - for (try = 0; try < 10; try++) { - ret = GetSDR(recid,&recnext,sdrdata,sizeof(sdrdata),&sz); - if (fdebug) - printf("GetSDR[%04x]: ret = %x, next=%x\n",recid,ret,recnext); - if (ret != 0) { - if (ret == 0xC5) { /* lost Reservation ID, retry */ - /*fprintf(stderr,"%04x lost reservation retrying to get, try: %d, %d, rlen = %d\n", recid,try,ret,sz);*/ - os_usleep((rand() & 3000),0); - fDoReserve = 1; - } - else { - fprintf(stderr,"%04x GetSDR error %d, rlen = %d\n", recid,ret,sz); - break; - } - } - else { - break; - } - if (try==9){ - sz=0; - fprintf(stderr,"%04x GetSDR error %d, rlen = %d\n", recid,ret,sz); - } - } - if (sz < MIN_SDR_SZ) { /* don't have recnext, so abort */ - break; - } /* else fall through & continue */ - } /*end-else*/ - if (ret == 0) { /* (ret == 0) OK, got full SDR */ - if (fdebug) { - dump_buf("got SDR",sdrdata,sz,0); - } - if (sz < MIN_SDR_SZ) goto NextSdr; - /* if recid == 0, get real record id */ - if (recid == 0) recid = sdrdata[0] + (sdrdata[1] << 8); - if (fshowgrp > 0) { - for (i = 0; i < fshowgrp; i++) { - uchar styp; - if (sdrdata[3] == 0x03) styp = sdrdata[10]; /*EvtOnly*/ - else styp = sdrdata[12]; - if (fdebug) printf("sdrt=%02x styp=%02x sgrp[%d]=%02x\n", - sdrdata[3],styp,i,sensor_grps[i]); - if (sdrdata[3] == 0xc0) continue; /*skip OEM SDRs*/ - if (styp == sensor_grps[i]) break; - } - if (i >= fshowgrp) goto NextSdr; - } - - if ((sensor_num == INIT_SNUM) || (sdrdata[7] == sensor_num) - || fsetthresh) { - /* if -n not set or if -n matches, parse and show the SDR */ - ShowSDR("",sdrdata); - } /* else filter SDRs if not matching -n sensor_num */ - -#ifdef PICMG_CHILD - /* - * Special logic for blade child MCs in PICMG ATCA systems - * if fchild, try all child MCs within the chassis. - * SDR type 12 capabilities bits (sdrdata[8]): - * 80 = Chassis Device - * 40 = Bridge - * 20 = IPMB Event Generator - * 10 = IPMB Event Receiver - * 08 = FRU Device - * 04 = SEL Device - * 02 = SDR Repository Device - * 01 = Sensor Device - * But all child MCs use Device SDRs anyway. - */ - if (fpicmg && fchild && (sdrdata[3] == 0x12)) { /* PICMG MC DLR */ - int _recid, _recnext, _sz; - uchar _sdrdata[MAX_SDR_SIZE]; - int devsdrs_save; - uchar cc; - - /* save the BMC globals, use IPMB MC */ - devsdrs_save = fdevsdrs; - fdevsdrs = 1; /* use Device SDRs for the children*/ - if (fdebug) - printf(" --- IPMB MC (sa=%02x cap=%02x id=%02x devsdrs=%d):\n", - sdrdata[5],sdrdata[8],sdrdata[12],fdevsdrs); - fDoReserve = 1; /* get a new SDR Reservation ID */ - ipmi_set_mc(PICMG_SLAVE_BUS,sdrdata[5],sdrdata[6],g_addrtype); - - _sz = 16; - ret = ipmi_cmd_mc(GET_DEVICE_ID,NULL,0,_sdrdata,&_sz,&cc,fdebug); - if (ret == 0 && cc == 0) { - /* Get the SDRs from the IPMB MC */ - _recid = 0; - while (_recid != 0xffff) - { - ret = GetSDR(_recid,&_recnext,_sdrdata,sizeof(_sdrdata),&_sz); - if (ret != 0) { - fprintf(stderr,"%04x GetSDR error %d, rlen = %d\n",_recid,ret,_sz); - break; - } - else if (_sz >= MIN_SDR_SZ) - ShowSDR(" ",_sdrdata); - - if (_recnext == _recid) _recid = 0xffff; - else _recid = _recnext; - } /*end while*/ - } /*endif ret==0*/ - - /* restore BMC globals */ - fdevsdrs = devsdrs_save; - ipmi_restore_mc(); - fDoReserve = 1; /* get a new SDR Reservation ID */ - } /*endif fpicmg && fchild*/ -#endif - - if (fdebug) printf("fsetthresh=%d snum=%02x(%02x) sa=%02x(%02x)\n", - fsetthresh,sdrdata[7],sensor_num,sdrdata[5],g_sa); - if (fsetthresh && (sdrdata[7] == sensor_num) - && (sdrdata[5] == g_sa)) /*g_sa usu is BMC_SA*/ - { - /* setting threshold, compute threshold raw values */ - if (fsetthresh == 2) { /*set from float*/ - if (fdebug) - printf("lof=%.2f hif=%.2f\n", sensor_lo_f,sensor_hi_f); - if (sensor_lo_f != 0) - sensor_lo = FloatToRaw(sensor_lo_f,sdrdata,0); - if (sensor_hi_f != 0) - sensor_hi = FloatToRaw(sensor_hi_f,sdrdata,0); - } else if (fsetthresh == 1) { /*raw thresholds*/ - if (sensor_hi != 0xff) - sensor_hi_f = RawToFloat(sensor_hi,sdrdata); - if (sensor_lo != 0xff) - sensor_lo_f = RawToFloat(sensor_lo,sdrdata); - } else if (fsetthresh == 3) { /*unique raw thresholds*/ - if (sensor_hi != 0xff) - sensor_hi_f = RawToFloat(sensor_hi,sdrdata); - if (sensor_lo != 0xff) - sensor_lo_f = RawToFloat(sensor_lo,sdrdata); - } else if (fsetthresh == 4) { /*set unique from float*/ - i = fill_thresholds(&sensor_thrf[0], sdrdata); - /* if (i > 0) ; * filled in some thresholds */ - { /* always set lo/hi if any are non-zero */ - for (j = 0; j < 3; j++) { - if (sensor_thrf[j] != 0) { - sensor_lo_f = sensor_thrf[j]; break; } - } - for (j = 3; j < 6; j++) { - if (sensor_thrf[j] != 0) { - sensor_hi_f = sensor_thrf[j]; break; } - } - } - if (fdebug) - printf("lof=%.2f hif=%.2f\n", sensor_lo_f,sensor_hi_f); - /* convert thrf (float) to thr (raw) */ - if (sensor_lo_f != 0) { - sensor_lo = FloatToRaw(sensor_lo_f,sdrdata,0); - sensor_thr[0] = FloatToRaw(sensor_thrf[0],sdrdata,0); - sensor_thr[1] = FloatToRaw(sensor_thrf[1],sdrdata,0); - sensor_thr[2] = FloatToRaw(sensor_thrf[2],sdrdata,0); - } - if (sensor_hi_f != 0) { - sensor_hi = FloatToRaw(sensor_hi_f,sdrdata,0); - sensor_thr[3] = FloatToRaw(sensor_thrf[3],sdrdata,0); - sensor_thr[4] = FloatToRaw(sensor_thrf[4],sdrdata,0); - sensor_thr[5] = FloatToRaw(sensor_thrf[5],sdrdata,0); - } - /* validate threshold ordering */ - if (validate_thresholds(sensor_thrf,1,sdrdata) != 0) { - ret = ERR_BAD_PARAM; - goto do_exit; - } - } - { - printf("\tSetting SDR %04x sensor %02x to lo=%02x hi=%02x\n", - recid,sensor_num,sensor_lo,sensor_hi); - if (recid == 0) fsetfound = 1; - else fsetfound = recid; - } - } /*endif fsetthresh */ - } /*endif ok, got full SDR */ - -NextSdr: - if (ret == ERR_SDR_MALFORMED) break; - if (fjumpstart) recid = recnext; - else { - if (recnext == recid) recid = 0xffff; /*break;*/ - else recid = recnext; - } - if (fshowidx) { - /* if we have already read the last in the range, done. */ - if (recid >= sensor_idxN) break; // recnext = 0xffff; // break; - } - irec++; - } /*end while recid*/ - if (fdoloop && (nloops > 1)) { - printf("\n"); /* output an empty separator line */ - os_usleep(loopsec,0); /*delay 1 sec between loops*/ - } - } /*end for nloops*/ - - if (npass > 1) { /* npass==2 for PICMG */ - /* Switch fdevsdrs from Device to Repository */ - if (fdevsdrs == 0) fdevsdrs = 1; - else fdevsdrs = 0; - fDoReserve = 1; /* get a new SDR Reservation ID */ - } - } /*end for npass*/ - - if ((fshowidx == 0) && (fshowgrp == 0)) { - /* use local rv, errors are ignored for POH */ - rv = ShowPowerOnHours(); - } - - if (frearm != 0) { - ret = RearmSensor((uchar)frearm); - printf("RearmSensor(0x%02x) ret = %d\n",frearm,ret); - } - - if (fsetthresh != 0) { - uchar tdata[7]; - if (fsetfound == 0) { - printf("Did not find sensor number %02x.\nPlease enter the sensor number parameter in hex, as it is displayed above.\n",sensor_num); - } - ret = GetSensorThresholds(sensor_num,tdata); - if (ret != 0) goto do_exit; -#ifdef TEST - printf("thresh(%02x): %02x %02x %02x %02x %02x %02x %02x %02x\n", - sensor_num, sensor_num, tdata[0], tdata[1], tdata[2], - tdata[3], tdata[4], tdata[5], tdata[6]); - printf(" set(%02x): %02x %02x \n", - sensor_num,sensor_lo,sensor_hi); -#endif - if (fsetthresh == 3 || fsetthresh == 4) { - /* apply unique sensor thresholds */ - pset = &sensor_thr[0]; - } else pset = NULL; /* use just hi/lo */ - ret = SetSensorThresholds(sensor_num,sensor_hi,sensor_lo,tdata,pset); - printf("SetSensorThreshold[%02x] to lo=%02x(%4.3f) hi=%02x(%4.3f), ret = %d\n", - sensor_num,sensor_lo,sensor_lo_f,sensor_hi,sensor_hi_f,ret); - if (fsavethresh && ret == 0) { - recid = fsetfound; - rv = SaveThreshold(recid,sensor_num,sensor_lo,sensor_hi,pset); - if (rv == 0) - printf("Saved thresholds for sensor %02x\n",sensor_num); - } - fsetthresh = 0; /*only set threshold once*/ - } - -do_exit: - // if (fjumpstart) - free_sdr_cache(psdrcache); /* does nothing if ==NULL*/ - /* show_outcome(progname,ret); *handled in ipmiutil.c*/ - ipmi_close_(); - return(ret); -} - -/* end isensor.c */ diff --git a/util/isensor.h b/util/isensor.h index d08a0a8..d56a5c9 100644 --- a/util/isensor.h +++ b/util/isensor.h @@ -159,7 +159,7 @@ int GetSensorReadingFactors(uchar snum, uchar raw, int *m, int *b, int * b_exp, int *r, int *a); double RawToFloat(uchar raw, uchar *psdr); char *decode_entity_id(int id); -char *get_unit_type(int iunits, int ibase, int imod, int fshort); +char *get_unit_type(uchar iunits, uchar ibase, uchar imod, int fshort); /* * decode_comp_reading diff --git a/util/isol.c b/util/isol.c index 6b72b14..447945b 100644 --- a/util/isol.c +++ b/util/isol.c @@ -142,7 +142,7 @@ extern void tty_setnormal(int mode); /*from ipmicmd.c*/ extern SockType lan_get_fd(void); /*from ipmilan.c*/ extern int lan_send_sol( uchar *payload, int len, SOL_RSP_PKT *rsp); extern int lan_recv_sol( SOL_RSP_PKT *rsp ); -extern int lan_keepalive(int type); +extern int lan_keepalive(uchar type); extern void lan_get_sol_data(uchar fEnc, uchar iseed, uint32 *seed); extern void lan_set_sol_data(uchar fEnc, uchar auth, uchar iseed, int insize, int outsize); diff --git a/util/itsol.c b/util/itsol.c index e84bd5a..12071ec 100644 --- a/util/itsol.c +++ b/util/itsol.c @@ -118,9 +118,9 @@ static SOCKADDR_T haddr; static int haddrlen = 0; static int hauth, hpriv, hcipher; #ifdef WIN32 -#define NI_MAXHOST 80 -#define NI_MAXSERV 80 -struct pollfd { int fd; short events; short revents; }; +// #define NI_MAXHOST 80 +// #define NI_MAXSERV 80 +// struct pollfd { int fd; short events; short revents; }; struct winsize { int x; int y; }; #else static struct termios _saved_tio; @@ -499,7 +499,7 @@ ipmi_tsol_main(void * intf, int argc, char ** argv) } get_lan_options(hostname,NULL,NULL,&hauth, &hpriv, &hcipher,NULL,NULL); - result = open_sockfd(hostname, &sockfd, &haddr, &haddrlen, 1); + result = open_sockfd(hostname, port, &sockfd, &haddr, &haddrlen, 1); if (result) { lperror(LOG_ERR, "Connect to %s failed",hostname); return result; diff --git a/util/itsol.h b/util/itsol.h index ec28d3f..9e70b9f 100644 --- a/util/itsol.h +++ b/util/itsol.h @@ -54,11 +54,11 @@ int get_LastError( void ); /* ipmilan.c */ void show_LastError(char *tag, int err); void lprintf(int level, const char * format, ...); /*subs.c*/ -int lan_keepalive(int type); /*ipmilan.c*/ +int lan_keepalive(uchar type); /*ipmilan.c*/ void set_loglevel(int level); void lperror(int level, const char * format, ...); int ipmi_open(char fdebugcmd); -int open_sockfd(char *node, SockType *sfd, SOCKADDR_T *daddr, +int open_sockfd(char *node, int port, SockType *sfd, SOCKADDR_T *daddr, int *daddr_len, int foutput); int ipmi_tsol_main(void *, int, char **); diff --git a/util/mem_if.c b/util/mem_if.c index c7ca677..1f5f9c1 100644 --- a/util/mem_if.c +++ b/util/mem_if.c @@ -614,7 +614,7 @@ int get_IpmiStruct(UCHAR *iftype, UCHAR *ver, UCHAR *sa, int *base, UCHAR *inc) // Returns: 0 for success, or -1 if not found. // if success, the desc string will have valid data ////////////////////////////////////////////////////////////////////////////// -int get_MemDesc(UCHAR array, UCHAR dimm, char *desc, int *psize) +int get_MemDesc(int array, int dimm, char *desc, int *psize) { UCHAR *VirtualAddress; ULONG SMBiosLen = 0; diff --git a/util/ocm_dell.c-319 b/util/ocm_dell.c-319 new file mode 100644 index 0000000..b474ee3 --- /dev/null +++ b/util/ocm_dell.c-319 @@ -0,0 +1,6121 @@ +/* + * oem_dell.c + * Handle Dell OEM command functions + * + * Change history: + * 08/17/2011 ARCress - included in ipmiutil source tree + * + */ +/****************************************************************** +Copyright (c) 2008, Dell Inc +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +- Redistributions 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 Dell Inc nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + +******************************************************************/ +/* +* Thursday Oct 7 17:30:12 2009 +* <deepaganesh_paulraj@dell.com> +* +* This code implements a dell OEM proprietary commands. +* This Code is edited and Implemented the License feature for Delloem +* Author Harsha S <Harsha_S1@dell.com> +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef WIN32 +#include <windows.h> +#define int8_t char +#define uint8_t unsigned char +#define uint16_t unsigned short +#define uint32_t unsigned int +#define uint64_t unsigned long +#include "getopt.h" +#else +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <errno.h> +#include <unistd.h> +#include <signal.h> +#include <ctype.h> +#include <limits.h> +#if defined(HPUX) +/* getopt is defined in stdio.h */ +#elif defined(MACOS) +/* getopt is defined in unistd.h */ +#include <unistd.h> +#include <stdint.h> +#else +#include <getopt.h> +#endif +#endif + +#include <time.h> +#include "ipmicmd.h" +#include "isensor.h" +#include "ievents.h" +#include "oem_dell.h" + +// #ifdef METACOMMAND is assumed +extern int i_sol(int argc, char **argv); /*isol.c*/ +extern void lprintf(int level, const char * format, ...); /*ipmilanplus.c*/ +extern void set_loglevel(int level); +extern void printbuf(const uint8_t * buf, int len, const char * desc); + +#define IPMI_DELL_OEM_NETFN (uint8_t)(0x30) +#define GET_CHASSIS_LED_STATE (uint8_t)(0x32) +#define GET_IDRAC_VIRTUAL_MAC (uint8_t)(0xC9) +// 11g Support Macros +#define INVALID -1 +#define SHARED 0 +#define SHARED_WITH_FAILOVER_LOM2 1 +#define DEDICATED 2 +#define SHARED_WITH_FAILOVER_ALL_LOMS 3 +char ActiveLOM_String[6][10] = {"None","LOM1","LOM2","LOM3","LOM4","dedicated"}; +#define INVAILD_FAILOVER_MODE -2 +#define INVAILD_FAILOVER_MODE_SETTINGS -3 +#define INVAILD_SHARED_MODE -4 + +#define INVAILD_FAILOVER_MODE_STRING "ERROR: Cannot set shared with failover lom same as current shared lom.\n" +#define INVAILD_FAILOVER_MODE_SET "ERROR: Cannot set shared with failover loms when NIC is set to dedicated Mode.\n" +#define INVAILD_SHARED_MODE_SET_STRING "ERROR: Cannot set shared Mode for Blades.\n" + +// 11g Support Strings for nic selection +char NIC_Selection_Mode_String [4] [50] = { "shared", + "shared with failover lom2", + "dedicated", + "shared with Failover all loms" + }; + +// 11g Support Macros (dups) +//#define SHARED 0 +//#define SHARED_WITH_FAILOVER_LOM2 1 +//#define DEDICATED 2 +//#define SHARED_WITH_FAILOVER_ALL_LOMS 3 + +// 12g Support Strings for nic selection +char NIC_Selection_Mode_String_12g[] [50] = { + "dedicated", + "shared with lom1", + "shared with lom2", + "shared with lom3", + "shared with lom4", + "shared with failover lom1", + "shared with failover lom2", + "shared with failover lom3", + "shared with failover lom4", + "shared with failover all loms" + }; + +#ifdef METACOMMAND +extern char * progver; /*from ipmiutil.c*/ +static char * progname = "ipmiutil delloem"; +#else +static char * progver = "3.08"; +static char * progname = "idelloem"; +#endif +static int verbose = 0; +static char fdebug = 0; +static uchar g_bus = PUBLIC_BUS; +static uchar g_sa = BMC_SA; +static uchar g_lun = BMC_LUN; +static uchar g_addrtype = ADDR_SMI; +static uchar *sdrcache = NULL; +static char *sdrfile = NULL; +static int argc_sav; +static char **argv_sav; +static int current_arg =0; +uint8_t iDRAC_FLAG=0; +LCD_MODE lcd_mode; +static uint8_t LcdSupported=0; +static uint8_t SetLEDSupported=0; + +volatile uint8_t IMC_Type = IMC_IDRAC_10G; + + +const struct vFlashstr vFlash_completion_code_vals[] = { + {0x00, "SUCCESS"}, + {0x01, "NO_SD_CARD"}, + {0x63, "UNKNOWN_ERROR"}, + {0x00, NULL} +}; + + +POWER_HEADROOM powerheadroom; + +uint8_t PowercapSetable_flag=0; +uint8_t PowercapstatusFlag=0; + +static void usage(void); + +/* LCD Function prototypes */ +static int ipmi_delloem_lcd_main (void * intf, int argc, char ** argv); +static int ipmi_lcd_get_platform_model_name (void * intf,char* lcdstring, + uint8_t max_length,uint8_t field_type); +static int ipmi_idracvalidator_command (void * intf); +static int ipmi_lcd_get_configure_command_wh (void * intf); +static int ipmi_lcd_get_configure_command (void * intf,uint8_t *command); +static int ipmi_lcd_set_configure_command (void * intf, int command); +static int ipmi_lcd_set_configure_command_wh (void * intf, uint32_t mode, + uint16_t lcdqualifier,uint8_t errordisp); +static int ipmi_lcd_get_single_line_text (void * intf, char* lcdstring, uint8_t max_length); +static int ipmi_lcd_get_info_wh(void * intf); +static int ipmi_lcd_get_info(void * intf); +static int ipmi_lcd_get_status_val(void * intf, LCD_STATUS* lcdstatus); +static int IsLCDSupported (); +static void CheckLCDSupport(void * intf); +static void ipmi_lcd_status_print( LCD_STATUS lcdstatus); +static int ipmi_lcd_get_status(void * intf ); +static int ipmi_lcd_set_kvm(void * intf, char status); +static int ipmi_lcd_set_lock(void * intf, char lock); +static int ipmi_lcd_set_single_line_text (void * intf, char * text); +static int ipmi_lcd_set_text(void * intf, char * text, int line_number); +static int ipmi_lcd_configure_wh (void * intf, uint32_t mode , + uint16_t lcdqualifier, uint8_t errordisp, + int8_t line_number, char * text); +static int ipmi_lcd_configure (void * intf, int command, + int8_t line_number, char * text); +static void ipmi_lcd_usage(void); + +/* MAC Function prototypes */ +static int ipmi_delloem_mac_main (void * intf, int argc, char ** argv); +static int make_int(const char *str, int *value); +static void InitEmbeddedNICMacAddressValues (); +static int ipmi_macinfo_drac_idrac_virtual_mac(void* intf,uint8_t NicNum); +static int ipmi_macinfo_drac_idrac_mac(void* intf,uint8_t NicNum); +static int ipmi_macinfo_10g (void* intf, uint8_t NicNum); +static int ipmi_macinfo_11g (void* intf, uint8_t NicNum); +static int ipmi_macinfo (void* intf, uint8_t NicNum); +static void ipmi_mac_usage(void); + +/* LAN Function prototypes */ +static int ipmi_delloem_lan_main (void * intf, int argc, char ** argv); +static int IsLANSupported (); +static int get_nic_selection_mode (int current_arg, char ** argv); +static int ipmi_lan_set_nic_selection (void* intf, uint8_t nic_selection); +static int ipmi_lan_get_nic_selection (void* intf); +static int get_nic_selection_mode_12g (void* intf,int iarg, char **argv, char *nic_set); +static int ipmi_lan_get_active_nic (void* intf); +static void ipmi_lan_usage(void); +static int ipmi_lan_set_nic_selection_12g (void* intf, uint8_t* nic_selection); + +/* POwer monitor Function prototypes */ +static int ipmi_delloem_powermonitor_main (void * intf, int argc, char **argv); +static void ipmi_time_to_str(time_t rawTime, char* strTime); +static int ipmi_get_power_capstatus_command (void * intf); +static int ipmi_set_power_capstatus_command (void * intf,uint8_t val); +static int ipmi_powermgmt(void* intf); +static int ipmi_powermgmt_clear(void* intf,uint8_t clearValue); +static uint64_t watt_to_btuphr_conversion(uint32_t powerinwatt); +static uint32_t btuphr_to_watt_conversion(uint64_t powerinbtuphr); +static int ipmi_get_power_headroom_command (void * intf,uint8_t unit); +static int ipmi_get_power_consumption_data(void* intf,uint8_t unit); +static int ipmi_get_instan_power_consmpt_data(void* intf, + IPMI_INST_POWER_CONSUMPTION_DATA* instpowerconsumptiondata); +static void ipmi_print_get_instan_power_Amps_data(IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata); +static int ipmi_print_get_power_consmpt_data(void* intf,uint8_t unit); +static int ipmi_get_avgpower_consmpt_history(void* intf,IPMI_AVGPOWER_CONSUMP_HISTORY* pavgpower ); +static int ipmi_get_peakpower_consmpt_history(void* intf,IPMI_POWER_CONSUMP_HISTORY * pstPeakpower); +static int ipmi_get_minpower_consmpt_history(void* intf,IPMI_POWER_CONSUMP_HISTORY * pstMinpower); +static int ipmi_print_power_consmpt_history(void* intf,int unit ); +static int ipmi_get_power_cap(void* intf,IPMI_POWER_CAP* ipmipowercap ); +static int ipmi_print_power_cap(void* intf,uint8_t unit ); +static int ipmi_set_power_cap(void* intf,int unit,int val ); +static void ipmi_powermonitor_usage(void); + +/* vFlash Function prototypes */ +static int ipmi_delloem_vFlash_main(void * intf, int argc, char ** argv); +const char * get_vFlash_compcode_str(uint8_t vflashcompcode, const struct vFlashstr *vs); +static int ipmi_get_sd_card_info(void* intf); +static int ipmi_delloem_vFlash_process(void* intf, int current_arg, char ** argv); +static void ipmi_vFlash_usage(void); + + +/* windbg Function prototypes */ +volatile uint8_t windbgsession = 0; +static int ipmi_delloem_windbg_main (void * intf, int argc, char ** argv); +static int ipmi_windbg_start (void * intf); +static int ipmi_windbg_end (void * intf); +static void ipmi_windbg_usage (void); + + + +/* LED Function prototypes */ + +static int ipmi_getsesmask(int, char **); +static int CheckSetLEDSupport(void * intf); +static int IsSetLEDSupported(void); +static void ipmi_setled_usage(void); +static int ipmi_delloem_setled_main(void *intf, int argc, char ** argv); +static int ipmi_delloem_getled_main(void *intf, int argc, char ** argv); +static int ipmi_setled_state (void * intf, int bayId, int slotId, int state); +static int ipmi_getdrivemap (void * intf, int b, int d, int f, int *bayId, int *slotId); +//extern int optind; /*from getopt*/ + +static int ipmi_sol_activate(void *intf, int j, int k) +{ + char **args; + int rv, i, n; + int x = 0; + n = argc_sav; + args = argv_sav; + /* use the user-specified args, but switch to sol */ + for (i = 0; i < n; i++) { + if (strcmp(args[i],"ipmiutil") == 0) { x = 1; } + else if (strcmp(args[i],"delloem") == 0) args[i] = "sol"; + else if (strcmp(args[i],"windbg") == 0) args[i] = "-a"; + else if (strcmp(args[i],"start") == 0) args[i] = "-a"; + } + ipmi_close_(); + if (x == 1) { args++; n--; } + optind = 0; + rv = i_sol(n, args); + return rv; +} + +static int ipmi_sol_deactivate(void *intf) +{ + char **args; + int rv, i, n; + int x = 0; + n = argc_sav; + args = argv_sav; + /* use the user-specified args, but switch to sol */ + for (i = 0; i < n; i++) { + if (strcmp(args[i],"ipmiutil") == 0) { x = 1; } + else if (strcmp(args[i],"delloem") == 0) args[i] = "sol"; + else if (strcmp(args[i],"windbg") == 0) args[i] = "-d"; + else if (strcmp(args[i],"end") == 0) args[i] = "-d"; + } + ipmi_close_(); + if (x == 1) { args++; n--; } + optind = 0; + rv = i_sol(n, args); + return rv; +} + +static int sysinfo_param(const char *str) { + // SysInfo Parameters + // 1 = system firmware version + // 2 = system hostname + // 3 = primary operating system name (non-volatile) + // 4 = operating system name (volatile) + // 0xe3 = dell: os version + // 0xde = dell: url + if (!strcmp(str, "system_name")) return 0x02; + if (!strcmp(str, "primary_os_name")) return 0x03; + if (!strcmp(str, "os_name")) return 0x04; + if (!strcmp(str, "dell_os_version")) return 0xe4; + if (!strcmp(str, "dell_url")) return 0xde; + return strtoul(str, 0, 16); +} + +static void ipmi_sysinfo_usage() +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " getsysinfo (os_name|primary_os_name|dell_os_version|dell_url)"); + lprintf(LOG_NOTICE, " Retrieves system info from bmc for given argument"); + lprintf(LOG_NOTICE, " setsysinfo (os_name|primary_os_name|dell_os_version|dell_url)"); + lprintf(LOG_NOTICE, " Stores system Info for given argument to bmc"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " primary_os_name = primary operating system name"); + lprintf(LOG_NOTICE, " os_name = secondary operating system name"); + lprintf(LOG_NOTICE, " system_name = system hostname of server"); + lprintf(LOG_NOTICE, " dell_os_version = running version of operating system (Dell)"); + lprintf(LOG_NOTICE, " dell_url = url of bmc webserver (Dell)"); + + lprintf(LOG_NOTICE, ""); +} + +static int +ipmi_delloem_sysinfo_main(void * intf, int argc, char ** argv) +{ + int param, isset; + char *str; + unsigned char infostr[256], *pos; + int j, ret; + + /* Is this a setsysinfo or getsysinfo */ + isset = !strncmp(argv[current_arg], "setsysinfo\0",10); + + current_arg++; + if (argc < current_arg) { + usage(); + return -1; + } + if (argc == 1 || strcmp(argv[current_arg], "help") == 0 || + argc < (isset ? current_arg+2 : current_arg+1)) { + ipmi_sysinfo_usage(); + return 0; + } + memset(infostr, 0, sizeof(infostr)); + + param = sysinfo_param(argv[current_arg++]); + + if (isset) { + str = argv[current_arg]; + j = strlen_(str); + ret = set_system_info(param,str,j); + } else { + pos = infostr; + j = sizeof(infostr); + ret = get_system_info(param,infostr,&j); + printf("%s\n", infostr); + } + return ret; +} + +static void ipmi_password_policy_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " passwordpolicy <on | off>"); + lprintf(LOG_NOTICE, " Set the OEM Password Policy Check on or off"); + lprintf(LOG_NOTICE, " This parameter is write-only"); + lprintf(LOG_NOTICE, ""); +} + +static int +ipmi_delloem_password_policy(void * intf, int argc, char ** argv) +{ + int rv = 0; + int rsp_len; + struct ipmi_rq req; + uint8_t data[4]; + uint8_t rsp[IPMI_RSPBUF_SIZE]; + uint8_t bval; + + + current_arg++; + if (argc < current_arg) { + usage(); + return -1; + } + + if (strcmp(argv[current_arg], "on") == 0) { + bval = 0x01; + } else if (strcmp(argv[current_arg], "off") == 0) { + bval = 0x00; + } else { /* other or "help" */ + ipmi_password_policy_usage(); + return 0; + } + + printf("Setting OEM Password Policy Check to %s ...\n", argv[current_arg]); + req.msg.netfn = 0x30; /*Dell OEM netfn*/ + req.msg.lun = 0; + req.msg.cmd = 0x51; + req.msg.data_len = 1; + req.msg.data = data; + data[0] = bval; + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error setting OEM password policy: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + } + if (rv == 0) printf("successful\n"); + /* This works for DELL C6220 with firmware >= 1.23 */ + + return(rv); +} + +/***************************************************************** +* Function Name: ipmi_delloem_main +* +* Description: This function processes the delloem command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ + +int +ipmi_delloem_main(void * intf, int argc, char ** argv) +{ + int rc = 0; + + // ipmi_idracvalidator_command(intf); + // CheckLCDSupport (intf); + // CheckSetLEDSupport (intf); + + if (argc == 0 || strncmp(argv[0], "help\0", 5) == 0) + { + usage(); + return 0; + } + + if (0 ==strncmp(argv[current_arg], "lcd\0", 4) ) + { + rc = ipmi_delloem_lcd_main (intf,argc,argv); + } + /* mac address*/ + else if (strncmp(argv[current_arg], "mac\0", 4) == 0) + { + rc = ipmi_delloem_mac_main (intf,argc,argv); + } + /* lan address*/ + else if (strncmp(argv[current_arg], "lan\0", 4) == 0) + { + rc = ipmi_delloem_lan_main (intf,argc,argv); + } + /* SetLED support */ + else if (strncmp(argv[current_arg], "setled\0", 7) == 0) + { + rc = ipmi_delloem_setled_main (intf,argc,argv); + } + else if (strncmp(argv[current_arg], "getled\0", 13) == 0) + { + rc = ipmi_delloem_getled_main (intf,argc,argv); + } + else if (strncmp(argv[current_arg], "passwordpolicy\0", 14) == 0) + { + rc = ipmi_delloem_password_policy (intf,argc,argv); + } + /*Powermanagement report processing*/ + else if (strncmp(argv[current_arg], "powermonitor\0", 13) == 0) + { + rc = ipmi_delloem_powermonitor_main (intf,argc,argv); + } + /* vFlash Support */ + else if (strncmp(argv[current_arg], "vFlash\0", 7) == 0) + { + rc = ipmi_delloem_vFlash_main (intf,argc,argv); + } + else if (strncmp(argv[current_arg], "windbg\0", 7) == 0) + { + rc = ipmi_delloem_windbg_main (intf,argc,argv); + } + else if ((strncmp(argv[current_arg], "getsysinfo\0", 10) == 0) || + (strncmp(argv[current_arg], "setsysinfo\0", 10) == 0)) + { + rc = ipmi_delloem_sysinfo_main (intf,argc,argv); + } + else + { + usage(); + return ERR_USAGE; + } + return rc; +} + +/***************************************************************** +* Function Name: usage +* +* Description: This function prints help message for delloem command +* Input: +* Output: +* +* Return: +* +******************************************************************/ + +static void usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "usage: delloem <command> [option...]"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "commands:"); + lprintf(LOG_NOTICE, " lcd"); + lprintf(LOG_NOTICE, " mac"); + lprintf(LOG_NOTICE, " lan"); + lprintf(LOG_NOTICE, " setled"); + lprintf(LOG_NOTICE, " getled"); + lprintf(LOG_NOTICE, " powermonitor"); + lprintf(LOG_NOTICE, " windbg"); + lprintf(LOG_NOTICE, " vFlash"); + lprintf(LOG_NOTICE, " getsysinfo"); + lprintf(LOG_NOTICE, " setsysinfo"); + lprintf(LOG_NOTICE, " passwordpolicy"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "For help on individual commands type:"); + lprintf(LOG_NOTICE, "delloem <command> help"); + +} + +/***************************************************************** +* Function Name: ipmi_delloem_lcd_main +* +* Description: This function processes the delloem lcd command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ + +static int ipmi_delloem_lcd_main (void * intf, int argc, char ** argv) +{ + int rc = 0; + + current_arg++; + if (argc < current_arg) + { + usage(); + return -1; + } + + + /* ipmitool delloem lcd info*/ + if (argc == 1 || strcmp(argv[current_arg], "help") == 0) + { + ipmi_lcd_usage(); + return 0; + } + CheckLCDSupport (intf); + ipmi_idracvalidator_command(intf); + if (!IsLCDSupported()) { + printf("lcd is not supported on this system.\n"); + return -1; + } + else if (strncmp(argv[current_arg], "info\0", 5) == 0) + { + if((iDRAC_FLAG==IDRAC_11G) || (iDRAC_FLAG==IDRAC_12G) ) + rc = ipmi_lcd_get_info_wh(intf); + else + rc = ipmi_lcd_get_info(intf); + } + else if (strncmp(argv[current_arg], "status\0", 7) == 0) + { + rc = ipmi_lcd_get_status(intf); + } + /* ipmitool delloem lcd set*/ + else if (strncmp(argv[current_arg], "set\0", 4) == 0) + { + uint8_t line_number = 0; + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage(); + return -1; + } + if (strncmp(argv[current_arg], "line\0", 5) == 0) + { + current_arg++; + if (argc <= current_arg) {usage();return -1;} + line_number = (uint8_t)strtoul(argv[current_arg], NULL, 0); + current_arg++; + if (argc <= current_arg) {usage();return -1;} + } + + + if ((strncmp(argv[current_arg], "mode\0", 5) == 0)&&((iDRAC_FLAG==IDRAC_11G) || (iDRAC_FLAG==IDRAC_12G) )) + { + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage(); + return -1; + } + if (argv[current_arg] == NULL) + { + ipmi_lcd_usage(); + return -1; + } + if (strncmp(argv[current_arg], "none\0", 5) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_CONFIG_NONE,0xFF,0XFF, 0, NULL); + } + else if (strncmp(argv[current_arg], "modelname\0", 10) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_CONFIG_DEFAULT,0xFF,0XFF, 0, NULL); + } + else if (strncmp(argv[current_arg], "userdefined\0", 12) == 0) + { + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage();return -1; + } + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_CONFIG_USER_DEFINED,0xFF,0XFF, line_number, argv[current_arg]); + } + else if (strncmp(argv[current_arg], "ipv4address\0", 12) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_iDRAC_IPV4ADRESS ,0xFF,0XFF, 0, NULL); + } + else if (strncmp(argv[current_arg], "macaddress\0", 11) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_IDRAC_MAC_ADDRESS,0xFF,0XFF, 0, NULL); + } + else if (strncmp(argv[current_arg], "systemname\0", 11) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_OS_SYSTEM_NAME,0xFF,0XFF, 0, NULL); + } + else if (strncmp(argv[current_arg], "servicetag\0", 11) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_SERVICE_TAG, 0xFF,0XFF,0, NULL); + } + else if (strncmp(argv[current_arg], "ipv6address\0", 12) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_iDRAC_IPV6ADRESS ,0xFF,0XFF, 0, NULL); + } + else if (strncmp(argv[current_arg], "ambienttemp\0", 12) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_AMBEINT_TEMP, 0xFF,0XFF,0, NULL); + + } + else if (strncmp(argv[current_arg], "systemwatt\0", 11) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_SYSTEM_WATTS , 0xFF,0XFF,0, NULL); + + } + else if (strncmp(argv[current_arg], "assettag\0", 9) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_ASSET_TAG , 0xFF,0XFF,0, NULL); + + } + else if (strncmp(argv[current_arg], "help\0", 5) == 0) + { + ipmi_lcd_usage(); + } + else + { + ipmi_lcd_usage(); + } + } + else if ((strncmp(argv[current_arg], "lcdqualifier\0", 13)== 0) &&((iDRAC_FLAG==IDRAC_11G) || (iDRAC_FLAG==IDRAC_12G) ) ) + { + + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage(); + return -1; + } + if (argv[current_arg] == NULL) + { + ipmi_lcd_usage(); + return -1; + } + + if (strncmp(argv[current_arg], "watt\0", 5) == 0) { + + + rc = ipmi_lcd_configure_wh (intf, 0xFF,0x00,0XFF, 0, NULL); + } + else if (strncmp(argv[current_arg], "btuphr\0",7) == 0) { + rc = ipmi_lcd_configure_wh (intf, 0xFF,0x01,0XFF, 0, NULL); + + } else if (strncmp(argv[current_arg], "celsius\0", 8) == 0) { + rc = ipmi_lcd_configure_wh (intf, 0xFF,0x02,0xFF, 0, NULL); + } else if (strncmp(argv[current_arg], "fahrenheit", 11) == 0) { + rc = ipmi_lcd_configure_wh (intf, 0xFF,0x03,0xFF, 0, NULL); + + }else if (strncmp(argv[current_arg], "help\0", 5) == 0) { + ipmi_lcd_usage(); + } + else { + ipmi_lcd_usage(); + } + } + else if( (strncmp(argv[current_arg], "errordisplay\0", 13) == 0)&&((iDRAC_FLAG==IDRAC_11G) || (iDRAC_FLAG==IDRAC_12G) )) + { + + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage(); + return -1; + } + if (argv[current_arg] == NULL) + { + ipmi_lcd_usage(); + return -1; + } + + if (strncmp(argv[current_arg], "sel\0", 4) == 0) + { + rc = ipmi_lcd_configure_wh (intf, 0xFF,0xFF,IPMI_DELL_LCD_ERROR_DISP_SEL , 0, NULL); + } + else if (strncmp(argv[current_arg], "simple\0", 7) == 0) + { + rc = ipmi_lcd_configure_wh (intf, 0xFF,0xFF,IPMI_DELL_LCD_ERROR_DISP_VERBOSE , 0, NULL); + + } + else if (strncmp(argv[current_arg], "help\0", 5) == 0) + { + ipmi_lcd_usage(); + } + else + { + ipmi_lcd_usage(); + } + } + + else if ((strncmp(argv[current_arg], "none\0", 5) == 0)&&(iDRAC_FLAG==0)) + { + rc = ipmi_lcd_configure (intf, IPMI_DELL_LCD_CONFIG_NONE, 0, NULL); + } + else if ((strncmp(argv[current_arg], "default\0", 8) == 0)&&(iDRAC_FLAG==0)) + { + rc = ipmi_lcd_configure (intf, IPMI_DELL_LCD_CONFIG_DEFAULT, 0, NULL); + + } + else if ((strncmp(argv[current_arg], "custom\0", 7) == 0)&&(iDRAC_FLAG==0)) + { + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage(); + return -1; + } + rc = ipmi_lcd_configure (intf, IPMI_DELL_LCD_CONFIG_USER_DEFINED, line_number, argv[current_arg]); + } + + else if (strncmp(argv[current_arg], "vkvm\0", 5) == 0) + { + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage(); + return -1; + } + + if (strncmp(argv[current_arg], "active\0", 7) == 0) + { + rc = ipmi_lcd_set_kvm (intf, 1); + } + else if (strncmp(argv[current_arg], "inactive\0", 9)==0) + { + rc = ipmi_lcd_set_kvm (intf, 0); + + } + else if (strncmp(argv[current_arg], "help\0", 5) == 0) + { + ipmi_lcd_usage(); + } + else + { + ipmi_lcd_usage(); + } + + } + else if (strncmp(argv[current_arg], "frontpanelaccess\0", 17) == 0) + { + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage(); + return -1; + } + if (strncmp(argv[current_arg], "viewandmodify\0", 14) == 0) + { + rc = ipmi_lcd_set_lock (intf, 0); + } + else if (strncmp(argv[current_arg], "viewonly\0", 9)==0) + { + rc = ipmi_lcd_set_lock (intf, 1); + + } + else if (strncmp(argv[current_arg], "disabled\0", 9)==0) + { + rc = ipmi_lcd_set_lock (intf, 2); + + } + else if (strncmp(argv[current_arg], "help\0", 5) == 0) + { + ipmi_lcd_usage(); + } + else + { + ipmi_lcd_usage(); + } + + } + else if( (strncmp(argv[current_arg], "help\0", 5) == 0)&&(iDRAC_FLAG==0)) + { + ipmi_lcd_usage(); + } + else + { + ipmi_lcd_usage(); + return -1; + } + } + else + { + ipmi_lcd_usage(); + return -1; + } + return(rc); +} + + + +/***************************************************************** +* Function Name: ipmi_lcd_get_platform_model_name +* +* Description: This function retrieves the platform model name, or any other parameter +* which stores data in the same format +* Input: intf - pointer to interface +* max_length - length of the platform model string +* field_type - either hostname / platform model +* Output: lcdstring - hostname / platform model string +* +* Return: +* +******************************************************************/ +static int +ipmi_lcd_get_platform_model_name (void * intf, + char* lcdstring, + uint8_t max_length, + uint8_t field_type) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[4]; + IPMI_DELL_LCD_STRING * lcdstringblock; + int lcdstring_len = 0; + int bytes_copied = 0; + + int ii; + + for (ii = 0; ii < 4; ii++) + { + int bytes_to_copy; + memset (&req,0,sizeof(req)); + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter*/ + data[1] = field_type; + data[2] = ii; + data[3] = 0; + + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting platform model name: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + lcdstringblock = (IPMI_DELL_LCD_STRING *) (void *) rsp; + + /* first block is different - 14 bytes*/ + if (0 == ii) { + lcdstring_len = lcdstringblock->lcd_string.selector_0_string.length; + + lcdstring_len = MIN (lcdstring_len,max_length); + + bytes_to_copy = MIN(lcdstring_len, IPMI_DELL_LCD_STRING1_SIZE); + memcpy (lcdstring, lcdstringblock->lcd_string.selector_0_string.data, bytes_to_copy); + } else { + int string_offset; + + bytes_to_copy = MIN(lcdstring_len - bytes_copied, IPMI_DELL_LCD_STRINGN_SIZE); + if (bytes_to_copy < 1) + break; + string_offset = IPMI_DELL_LCD_STRING1_SIZE + IPMI_DELL_LCD_STRINGN_SIZE * (ii-1); + memcpy (lcdstring+string_offset, lcdstringblock->lcd_string.selector_n_data, bytes_to_copy); + } + + + bytes_copied += bytes_to_copy; + + if (bytes_copied >= lcdstring_len) + + break; + } + return rv; +} + +/***************************************************************** +* Function Name: ipmi_idracvalidator_command +* +* Description: This function returns the iDRAC6 type +* Input: intf - ipmi interface +* Output: +* +* Return: iDRAC6 type 1 - whoville +* 0 - others +* +******************************************************************/ + +static int +ipmi_idracvalidator_command (void * intf) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[4]; + + memset (&req,0,sizeof(req)); + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; + data[1] = IPMI_DELL_IDRAC_VALIDATOR; + data[2] = 2; + data[3] = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv && fdebug) { + printf(" Error getting IMC type"); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + IMC_Type = rsp[10]; + if( (IMC_Type == IMC_IDRAC_11G_MONOLITHIC) || (IMC_Type == IMC_IDRAC_11G_MODULAR) ) + { + iDRAC_FLAG=IDRAC_11G; + } + else if( (IMC_Type == IMC_IDRAC_12G_MONOLITHIC) || (IMC_Type == IMC_IDRAC_12G_MODULAR) ) + { + iDRAC_FLAG=IDRAC_12G; + } + else + { + iDRAC_FLAG=0; + } + + return 0; +} + +/***************************************************************** +* Function Name: ipmi_lcd_get_configure_command_wh +* +* Description: This function returns current lcd configuration for Dell OEM LCD command +* Input: intf - ipmi interface +* Global: lcd_mode - lcd mode setting +* Output: +* +* Return: returns the current lcd configuration +* 0 = User defined +* 1 = Default +* 2 = None +* +******************************************************************/ +static int +ipmi_lcd_get_configure_command_wh (void * intf) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[4]; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; + data[1] = IPMI_DELL_LCD_CONFIG_SELECTOR; + data[2] = 0; + data[3] = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting LCD configuration: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + lcd_mode= *((LCD_MODE*)(&rsp[0])); + return 0; +} + + +/***************************************************************** +* Function Name: ipmi_lcd_get_configure_command +* +* Description: This function returns current lcd configuration for Dell OEM LCD command +* Input: intf - ipmi interface +* Output: command - user defined / default / none / ipv4 / mac address / + system name / service tag / ipv6 / temp / system watt / asset tag +* +* Return: +* +******************************************************************/ + +static int +ipmi_lcd_get_configure_command (void * intf, + uint8_t *command) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[4]; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; + data[1] = IPMI_DELL_LCD_CONFIG_SELECTOR; + data[2] = 0; + data[3] = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting LCD configuration: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + /* rsp->data[0] is the rev */ + *command = rsp[1]; + + return 0; +} + +/***************************************************************** +* Function Name: ipmi_lcd_set_configure_command +* +* Description: This function updates current lcd configuration +* Input: intf - ipmi interface +* command - user defined / default / none / ipv4 / mac address / +* system name / service tag / ipv6 / temp / system watt / asset tag +* Output: +* Return: +* +******************************************************************/ + +static int +ipmi_lcd_set_configure_command (void * intf, int command) +{ +#define LSCC_DATA_LEN 2 + + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[2]; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = 2; + req.msg.data = data; + data[0] = IPMI_DELL_LCD_CONFIG_SELECTOR; + data[1] = command; /* command - custom, default, none */ + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error setting LCD configuration: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + return 0; +} + + +/***************************************************************** +* Function Name: ipmi_lcd_set_configure_command +* +* Description: This function updates current lcd configuration +* Input: intf - ipmi interface +* mode - user defined / default / none +* lcdqualifier - lcd quallifier id +* errordisp - error number +* Output: +* Return: +* +******************************************************************/ +static int +ipmi_lcd_set_configure_command_wh (void * intf, + uint32_t mode, + uint16_t lcdqualifier, + uint8_t errordisp) +{ +#define LSCC_DATA_LEN 2 + + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[13]; + + ipmi_lcd_get_configure_command_wh(intf); + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = 13; + req.msg.data = data; + data[0] = IPMI_DELL_LCD_CONFIG_SELECTOR; + + if(mode!=0xFF) + { + + data[1] = mode&0xFF; /* command - custom, default, none*/ + data[2]=(mode&0xFF00)>>8; + data[3]=(mode&0xFF0000)>>16; + data[4]=(mode&0xFF000000)>>24; + } + else + { + data[1] = (lcd_mode.lcdmode)&0xFF; /* command - custom, default, none*/ + data[2]=((lcd_mode.lcdmode)&0xFF00)>>8; + data[3]=((lcd_mode.lcdmode)&0xFF0000)>>16; + data[4]=((lcd_mode.lcdmode)&0xFF000000)>>24; + } + + if(lcdqualifier!=0xFF) + { + if(lcdqualifier==0x01) + { + data[5] =(lcd_mode.lcdqualifier)|0x01; /* command - custom, default, none*/ + + } + else if(lcdqualifier==0x00) + { + data[5] =(lcd_mode.lcdqualifier)&0xFE; /* command - custom, default, none*/ + } + else if (lcdqualifier==0x03) + { + data[5] =(lcd_mode.lcdqualifier)|0x02; /* command - custom, default, none*/ + } + else if (lcdqualifier==0x02) + { + data[5] =(lcd_mode.lcdqualifier)&0xFD; + } + } + else + { + data[5]=(uchar)lcd_mode.lcdqualifier; + } + if(errordisp!=0xFF) + { + data[11]=errordisp; + } + else + { + data[11]=lcd_mode.error_display; + } + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error setting LCD configuration: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + return 0; +} + + + +/***************************************************************** +* Function Name: ipmi_lcd_get_single_line_text +* +* Description: This function updates current lcd configuration +* Input: intf - ipmi interface +* lcdstring - new string to be updated +* max_length - length of the string +* Output: +* Return: +* +******************************************************************/ + +static int +ipmi_lcd_get_single_line_text (void * intf, char* lcdstring, uint8_t max_length) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[4]; + IPMI_DELL_LCD_STRING * lcdstringblock; + int lcdstring_len = 0; + int bytes_copied = 0; + int ii; + + for (ii = 0; ii < 4; ii++) { + int bytes_to_copy; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter*/ + data[1] = IPMI_DELL_LCD_STRING_SELECTOR; + data[2] = ii; /* block selector*/ + data[3] = 0; /* set selector (n/a)*/ + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting text data: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + lcdstringblock = (IPMI_DELL_LCD_STRING *) (void *) rsp; + + /* first block is different - 14 bytes*/ + if (0 == ii) + { + lcdstring_len = lcdstringblock->lcd_string.selector_0_string.length; + + if (lcdstring_len < 1 || lcdstring_len > max_length) + break; + + bytes_to_copy = MIN(lcdstring_len, IPMI_DELL_LCD_STRING1_SIZE); + memcpy (lcdstring, lcdstringblock->lcd_string.selector_0_string.data, bytes_to_copy); + } + else + { + int string_offset; + + bytes_to_copy = MIN(lcdstring_len - bytes_copied, IPMI_DELL_LCD_STRINGN_SIZE); + if (bytes_to_copy < 1) + break; + string_offset = IPMI_DELL_LCD_STRING1_SIZE + IPMI_DELL_LCD_STRINGN_SIZE * (ii-1); + memcpy (lcdstring+string_offset, lcdstringblock->lcd_string.selector_n_data, bytes_to_copy); + } + + bytes_copied += bytes_to_copy; + if (bytes_copied >= lcdstring_len) + break; + } + return 0; +} + +/***************************************************************** +* Function Name: ipmi_lcd_get_info_wh +* +* Description: This function prints current lcd configuration for whoville platform +* Input: intf - ipmi interface +* Output: +* Return: +* +******************************************************************/ + +static int +ipmi_lcd_get_info_wh(void * intf) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[4]; + IPMI_DELL_LCD_CAPS* lcd_caps; + char lcdstring[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; + + printf("LCD info\n"); + + if (ipmi_lcd_get_configure_command_wh (intf) != 0) + { + return -1; + } + else + { + if (lcd_mode.lcdmode== IPMI_DELL_LCD_CONFIG_DEFAULT) + { + char text[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; + + ipmi_lcd_get_platform_model_name(intf, text, + IPMI_DELL_LCD_STRING_LENGTH_MAX, + IPMI_DELL_PLATFORM_MODEL_NAME_SELECTOR); + + if (text == NULL) + return -1; + printf(" Setting:Model name\n"); + printf(" Line 1: %s\n", text); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_CONFIG_NONE) + { + printf(" Setting: none\n"); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_CONFIG_USER_DEFINED) + { + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter*/ + data[1] = IPMI_DELL_LCD_GET_CAPS_SELECTOR; + data[2] = 0; /* set selector (n/a)*/ + data[3] = 0; /* block selector (n/a)*/ + + printf(" Setting: User defined\n"); + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting LCD capabilities: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + lcd_caps = (IPMI_DELL_LCD_CAPS *)rsp; + if (lcd_caps->number_lines > 0) + { + memset(lcdstring, 0, IPMI_DELL_LCD_STRING_LENGTH_MAX+1); + + rv = ipmi_lcd_get_single_line_text (intf, lcdstring, lcd_caps->max_chars[0]); + printf(" Text: %s\n", lcdstring); + } + else + { + printf(" No lines to show\n"); + } + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_iDRAC_IPV4ADRESS) + { + printf(" Setting: IPV4 Address\n"); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_IDRAC_MAC_ADDRESS) + { + printf(" Setting: MAC Address\n"); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_OS_SYSTEM_NAME) + { + printf(" Setting: OS System Name\n"); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_SERVICE_TAG) + { + printf(" Setting: System Tag\n"); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_iDRAC_IPV6ADRESS) + { + printf(" Setting: IPV6 Address\n"); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_AMBEINT_TEMP) + { + printf(" Setting: Ambient Temp\n"); + if(lcd_mode.lcdqualifier&0x02) + printf(" Unit: F\n"); + else + printf(" Unit: C\n"); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_SYSTEM_WATTS) + { + printf(" Setting: System Watts\n"); + + if(lcd_mode.lcdqualifier&0x01) + printf(" Unit: BTU/hr\n"); + else + printf(" Unit: Watt\n"); + + } + if(lcd_mode.error_display==IPMI_DELL_LCD_ERROR_DISP_SEL) + printf(" Error Display: SEL\n"); + else if(lcd_mode.error_display==IPMI_DELL_LCD_ERROR_DISP_VERBOSE) + printf(" Error Display: Simple\n"); + } + + return 0; +} + +/***************************************************************** +* Function Name: ipmi_lcd_get_info +* +* Description: This function prints current lcd configuration for platform other than whoville +* Input: intf - ipmi interface +* Output: +* Return: +* +******************************************************************/ +static int ipmi_lcd_get_info(void * intf) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[4]; + IPMI_DELL_LCD_CAPS * lcd_caps; + uint8_t command = 0; + char lcdstring[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; + + printf("LCD info\n"); + + if (ipmi_lcd_get_configure_command (intf, &command) != 0) + { + return -1; + } + else + { + if (command == IPMI_DELL_LCD_CONFIG_DEFAULT) + { + memset (lcdstring,0,IPMI_DELL_LCD_STRING_LENGTH_MAX+1); + + ipmi_lcd_get_platform_model_name(intf, lcdstring, IPMI_DELL_LCD_STRING_LENGTH_MAX, + IPMI_DELL_PLATFORM_MODEL_NAME_SELECTOR); + + printf(" Setting: default\n"); + printf(" Line 1: %s\n", lcdstring); + } + else if (command == IPMI_DELL_LCD_CONFIG_NONE) + { + printf(" Setting: none\n"); + } + else if (command == IPMI_DELL_LCD_CONFIG_USER_DEFINED) + { + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter */ + data[1] = IPMI_DELL_LCD_GET_CAPS_SELECTOR; + data[2] = 0; /* set selector (n/a) */ + data[3] = 0; /* block selector (n/a) */ + + printf(" Setting: custom\n"); + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting LCD capabilities: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + lcd_caps = (IPMI_DELL_LCD_CAPS *)(void *)rsp; + if (lcd_caps->number_lines > 0) + { + memset (lcdstring,0,IPMI_DELL_LCD_STRING_LENGTH_MAX+1); + rv = ipmi_lcd_get_single_line_text (intf, lcdstring, lcd_caps->max_chars[0]); + printf(" Text: %s\n", lcdstring); + } + else + { + printf(" No lines to show\n"); + } + } + } + + return 0; +} + +/***************************************************************** +* Function Name: ipmi_lcd_get_status_val +* +* Description: This function gets current lcd configuration +* Input: intf - ipmi interface +* Output: lcdstatus - KVM Status & Lock Status +* Return: +* +******************************************************************/ + +static int +ipmi_lcd_get_status_val(void * intf, LCD_STATUS* lcdstatus) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[4]; + + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter */ + data[1] = IPMI_DELL_LCD_STATUS_SELECTOR; + data[2] = 0; /* block selector */ + data[3] = 0; + /* set selector (n/a) */ + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting LCD status: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + /*lcdstatus= (LCD_STATUS* ) rsp->data; */ + + lcdstatus->vKVM_status=rsp[1]; + lcdstatus->lock_status=rsp[2]; + + return 0; +} + + +/***************************************************************** +* Function Name: IsLCDSupported +* +* Description: This function returns whether lcd supported or not +* Input: +* Output: +* Return: +* +******************************************************************/ +static int IsLCDSupported () +{ + return LcdSupported; +} + +/***************************************************************** +* Function Name: CheckLCDSupport +* +* Description: This function checks whether lcd supported or not +* Input: intf - ipmi interface +* Output: +* Return: +* +******************************************************************/ +static void CheckLCDSupport(void * intf) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[4]; + + LcdSupported = 0; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter */ + data[1] = IPMI_DELL_LCD_STATUS_SELECTOR; + data[2] = 0; /* block selector */ + data[3] = 0; + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { return; } + LcdSupported = 1; + +} + +/***************************************************************** +* Function Name: ipmi_lcd_status_print +* +* Description: This function prints current lcd configuration KVM Status & Lock Status +* Input: lcdstatus - KVM Status & Lock Status +* Output: +* Return: +* +******************************************************************/ + +static void ipmi_lcd_status_print( LCD_STATUS lcdstatus) +{ + switch (lcdstatus.vKVM_status) + { + case 0x00: + printf("LCD KVM Status :Inactive\n"); + break; + case 0x01: + printf("LCD KVM Status :Active\n"); + break; + default: + printf("LCD KVM Status :Invalid Status\n"); + + break; + } + + switch (lcdstatus.lock_status) + { + case 0x00: + printf("LCD lock Status :View and modify\n"); + break; + case 0x01: + printf("LCD lock Status :View only\n"); + break; + case 0x02: + printf("LCD lock Status :disabled\n"); + break; + default: + printf("LCD lock Status :Invalid\n"); + break; + } + +} + +/***************************************************************** +* Function Name: ipmi_lcd_get_status +* +* Description: This function gets current lcd KVM active status & lcd access mode +* Input: intf - ipmi interface +* Output: +* Return: -1 on error +* 0 if successful +* +******************************************************************/ +static int +ipmi_lcd_get_status(void * intf ) +{ + int rc=0; + LCD_STATUS lcdstatus; + + rc =ipmi_lcd_get_status_val( intf, &lcdstatus); + if (rc <0) + return -1; + ipmi_lcd_status_print(lcdstatus); + + return rc; + +} + +/***************************************************************** +* Function Name: ipmi_lcd_set_kvm +* +* Description: This function sets lcd KVM active status +* Input: intf - ipmi interface +* status - Inactive / Active +* Output: +* Return: -1 on error +* 0 if successful +* +******************************************************************/ +static int +ipmi_lcd_set_kvm(void * intf, char status) +{ +#define LSCC_DATA_LEN 2 + LCD_STATUS lcdstatus; + int rc=0; + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[5]; + rc=ipmi_lcd_get_status_val(intf,&lcdstatus); + if (rc < 0) + return -1; + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = 5; + req.msg.data = data; + data[0] = IPMI_DELL_LCD_STATUS_SELECTOR; + data[1] = status; /* active- incative*/ + data[2] = lcdstatus.lock_status; /* full-veiw-locked */ + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error setting LCD status: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + return rc; +} + +/***************************************************************** +* Function Name: ipmi_lcd_set_lock +* +* Description: This function sets lcd access mode +* Input: intf - ipmi interface +* lock - View and modify / View only / Diabled +* Output: +* Return: -1 on error +* 0 if successful +* +******************************************************************/ +static int +ipmi_lcd_set_lock(void * intf, char lock) +{ +#define LSCC_DATA_LEN 2 + LCD_STATUS lcdstatus; + int rc =0; + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[5]; + rc=ipmi_lcd_get_status_val(intf,&lcdstatus); + if (rc < 0) + return -1; + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = 5; + req.msg.data = data; + data[0] = IPMI_DELL_LCD_STATUS_SELECTOR; + data[1] = lcdstatus.vKVM_status; /* active- incative */ + data[2] = lock; /* full- veiw-locked */ + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error setting LCD status: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + return rc; +} + +/***************************************************************** +* Function Name: ipmi_lcd_set_single_line_text +* +* Description: This function sets lcd line text +* Input: intf - ipmi interface +* text - lcd string +* Output: +* Return: -1 on error +* 0 if successful +* +******************************************************************/ + +static int +ipmi_lcd_set_single_line_text (void * intf, char * text) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[18]; + int bytes_to_store = strlen_(text); + int bytes_stored = 0; + int ii; + int rc = 0; + if (bytes_to_store>IPMI_DELL_LCD_STRING_LENGTH_MAX) + { + lprintf(LOG_ERR, " Out of range Max limit is 62 characters"); + return 1; + + } + else + { + bytes_to_store = MIN(bytes_to_store, IPMI_DELL_LCD_STRING_LENGTH_MAX); + for (ii = 0; ii < 4; ii++) { + /*first block, 2 bytes parms and 14 bytes data*/ + if (0 == ii) { + int size_of_copy = + MIN((bytes_to_store - bytes_stored), IPMI_DELL_LCD_STRING1_SIZE); + if (size_of_copy < 0) /* allow 0 string length*/ + break; + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = size_of_copy + 4; /* chars, selectors and sizes*/ + req.msg.data = data; + data[0] = IPMI_DELL_LCD_STRING_SELECTOR; + data[1] = ii; /* block number to use (0)*/ + data[2] = 0; /*string encoding*/ + data[3] = bytes_to_store; /* total string length*/ + memcpy (data+4, text+bytes_stored, size_of_copy); + bytes_stored += size_of_copy; + } else { + int size_of_copy = + MIN((bytes_to_store - bytes_stored), IPMI_DELL_LCD_STRINGN_SIZE); + if (size_of_copy <= 0) + break; + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = size_of_copy + 2; + req.msg.data = data; + data[0] = IPMI_DELL_LCD_STRING_SELECTOR; + data[1] = ii; /* block number to use (1,2,3)*/ + memcpy (data+2, text+bytes_stored, size_of_copy); + bytes_stored += size_of_copy; + } + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error setting text data: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + } + } + return rc; +} + +/***************************************************************** +* Function Name: ipmi_lcd_set_text +* +* Description: This function sets lcd line text +* Input: intf - ipmi interface +* text - lcd string +* line_number- line number + +* Output: +* Return: -1 on error +* 0 if successful +* +******************************************************************/ + +static int +ipmi_lcd_set_text(void * intf, char * text, int line_number) +{ + int rc = 0; + + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[4]; + IPMI_DELL_LCD_CAPS * lcd_caps; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter*/ + data[1] = IPMI_DELL_LCD_GET_CAPS_SELECTOR; + data[2] = 0; /* set selector (n/a)*/ + data[3] = 0; /* block selector (n/a)*/ + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting LCD capabilities: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + lcd_caps = (IPMI_DELL_LCD_CAPS *)(void *)rsp; + + if (lcd_caps->number_lines > 0) { + rc = ipmi_lcd_set_single_line_text (intf, text); + } else { + lprintf(LOG_ERR, "LCD does not have any lines that can be set"); + rc = -1; + } + + + return rc; +} + +/***************************************************************** +* Function Name: ipmi_lcd_configure_wh +* +* Description: This function updates the current lcd configuration +* Input: intf - ipmi interface +* lcdqualifier- lcd quallifier +* errordisp - error number +* line_number-line number +* text - lcd string +* Output: +* Return: -1 on error +* 0 if successful +* +******************************************************************/ + +static int +ipmi_lcd_configure_wh (void * intf, uint32_t mode , + uint16_t lcdqualifier, uint8_t errordisp, + int8_t line_number, char * text) +{ + int rc = 0; + + + if (IPMI_DELL_LCD_CONFIG_USER_DEFINED == mode) + /* Any error was reported earlier. */ + rc = ipmi_lcd_set_text(intf, text, line_number); + + + if (rc == 0) + + rc = ipmi_lcd_set_configure_command_wh (intf, mode ,lcdqualifier,errordisp); + + return rc; +} + + +/***************************************************************** +* Function Name: ipmi_lcd_configure +* +* Description: This function updates the current lcd configuration +* Input: intf - ipmi interface +* command- lcd command +* line_number-line number +* text - lcd string +* Output: +* Return: -1 on error +* 0 if successful +* +******************************************************************/ + +static int +ipmi_lcd_configure (void * intf, int command, + int8_t line_number, char * text) +{ + int rc = 0; + + if (IPMI_DELL_LCD_CONFIG_USER_DEFINED == command) + rc = ipmi_lcd_set_text(intf, text, line_number); + + if (rc == 0) + rc = ipmi_lcd_set_configure_command (intf, command); + + return rc; +} + + +/***************************************************************** +* Function Name: ipmi_lcd_usage +* +* Description: This function prints help message for lcd command +* Input: +* Output: +* +* Return: +* +******************************************************************/ + +static void +ipmi_lcd_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "Generic DELL HW:"); + lprintf(LOG_NOTICE, " lcd set {none}|{default}|{custom <text>}"); + lprintf(LOG_NOTICE, " Set LCD text displayed during non-fault conditions"); + + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "iDRAC 11g or iDRAC 12g:"); + lprintf(LOG_NOTICE, " lcd set {mode}|{lcdqualifier}|{errordisplay}"); + lprintf(LOG_NOTICE, " Allows you to set the LCD mode and user-definedstring."); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd set mode {none}|{modelname}|{ipv4address}|{macaddress}|"); + lprintf(LOG_NOTICE, " {systemname}|{servicetag}|{ipv6address}|{ambienttemp}"); + lprintf(LOG_NOTICE, " {systemwatt }|{assettag}|{userdefined}<text>"); + lprintf(LOG_NOTICE, " Allows you to set the LCD display mode to any of the preceding parameters"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd set lcdqualifier {watt}|{btuphr}|{celsius}|{fahrenheit}"); + lprintf(LOG_NOTICE, " Allows you to set the unit for the system ambient temperature mode."); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd set errordisplay {sel}|{simple}"); + lprintf(LOG_NOTICE, " Allows you to set the error display."); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd info"); + lprintf(LOG_NOTICE, " Show LCD text that is displayed during non-fault conditions"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd set vkvm{active}|{inactive}"); + lprintf(LOG_NOTICE, " Set vKVM active and inactive, message will be displayed on lcd"); + lprintf(LOG_NOTICE, " when vKVM is active and vKVM session is in progress"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd set frontpanelaccess {viewandmodify}|{viewonly}|{disabled}"); + lprintf(LOG_NOTICE, " Set LCD mode to view and modify, view only or disabled "); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd status"); + lprintf(LOG_NOTICE, " Show LCD Status for vKVM display<active|inactive>"); + lprintf(LOG_NOTICE, " and Front Panel access mode {viewandmodify}|{viewonly}|{disabled} "); + lprintf(LOG_NOTICE, ""); +} + +/***************************************************************** +* Function Name: ipmi_delloem_mac_main +* +* Description: This function processes the delloem mac command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ + + +static int ipmi_delloem_mac_main (void * intf, int argc, char ** argv) +{ + int rc = 0; + + current_arg++; + if (argc > 1 && strcmp(argv[current_arg], "help") == 0) + { + ipmi_mac_usage(); + return 0; + } + ipmi_idracvalidator_command(intf); + if (argc == 1) /*( || (strncmp(argv[current_arg], "list\0", 5) == 0) )*/ + { + rc = ipmi_macinfo(intf, 0xff); + } + else if (strncmp(argv[current_arg], "get\0", 4) == 0) + { + int currIdInt; + current_arg++; + if (argv[current_arg] == NULL) + { + ipmi_mac_usage(); + return -1; + } + if(make_int(argv[current_arg],&currIdInt) < 0) { + lprintf(LOG_ERR, "Invalid NIC number. The NIC number should be between 0-8\n"); + return -1; + } + if( (currIdInt > 8) || (currIdInt < 0) ) + { + lprintf(LOG_ERR, "Invalid NIC number. The NIC number should be between 0-8\n"); + return -1; + } + rc = ipmi_macinfo(intf, currIdInt); + } + else + { + ipmi_mac_usage(); + } + return(rc); +} + + +/***************************************************************** +* Function Name: make_int +* +* Description: This function convert string into integer +* Input: str - decimal number string +* Output: value - integer value +* Return: +* +******************************************************************/ +static int make_int(const char *str, int *value) +{ + char *tmp=NULL; + *value = (int)strtol(str,&tmp,0); + if ( tmp-str != strlen(str) ) + { + return -1; + } + return 0; +} + + + + + +EmbeddedNICMacAddressType EmbeddedNICMacAddress; + +EmbeddedNICMacAddressType_10G EmbeddedNICMacAddress_10G; + +static void InitEmbeddedNICMacAddressValues () +{ + uint8_t i; + uint8_t j; + + + for (i=0;i<MAX_LOM;i++) + { +#ifdef LOM_OLD + EmbeddedNICMacAddress.LOMMacAddress[i].BladSlotNumber = 0; + EmbeddedNICMacAddress.LOMMacAddress[i].MacType = LOM_MACTYPE_RESERVED; + EmbeddedNICMacAddress.LOMMacAddress[i].EthernetStatus = LOM_ETHERNET_RESERVED; + EmbeddedNICMacAddress.LOMMacAddress[i].NICNumber = 0; + EmbeddedNICMacAddress.LOMMacAddress[i].Reserved = 0; +#else + EmbeddedNICMacAddress.LOMMacAddress[i].b0 = 0xF0; + EmbeddedNICMacAddress.LOMMacAddress[i].b1 = 0x00; +#endif + for (j=0;j<MACADDRESSLENGH;j++) + { + EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte[j] = 0; + EmbeddedNICMacAddress_10G.MacAddress[i].MacAddressByte[j] = 0; + } + } +} + +uint8_t UseVirtualMacAddress = 0; +#define VIRTUAL_MAC_OFFSET (2) +static int ipmi_macinfo_drac_idrac_virtual_mac(void* intf,uint8_t NicNum) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t VirtualMacAddress [MACADDRESSLENGH]; + uint8_t input_length=0; + uint8_t j; + //uint8_t length; + uint8_t i; + + + if (0xff==NicNum || IDRAC_NIC_NUMBER==NicNum ) + { + UseVirtualMacAddress = 0; + + input_length = 0; + msg_data[input_length++] = 1; /*Get*/ + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_IDRAC_VIRTUAL_MAC; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { return rv; } + + if( (IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_12G_MONOLITHIC== IMC_Type) ) { + // Get the Chasiss Assigned MAC Addresss for 12g Only + memcpy(VirtualMacAddress,&rsp[1],MACADDRESSLENGH); + + for (i=0;i<MACADDRESSLENGH;i++) + { + if (0 != VirtualMacAddress [i]) + { + UseVirtualMacAddress = 1; + } + } + // Get the Server Assigned MAC Addresss for 12g Only + if(!UseVirtualMacAddress) { + memcpy(VirtualMacAddress,&rsp[1+MACADDRESSLENGH],MACADDRESSLENGH); + + for (i=0;i<MACADDRESSLENGH;i++) + { + if (0 != VirtualMacAddress [i]) + { + UseVirtualMacAddress = 1; + } + } + } + } else { + memcpy(VirtualMacAddress,&rsp[VIRTUAL_MAC_OFFSET],MACADDRESSLENGH); + + for (i=0;i<MACADDRESSLENGH;i++) + { + if (0 != VirtualMacAddress [i]) + { + UseVirtualMacAddress = 1; + } + } + } + if (0 == UseVirtualMacAddress) + return -1; + if (IMC_IDRAC_10G == IMC_Type) + printf ("\nDRAC MAC Address "); + else if ( (IMC_IDRAC_11G_MODULAR == IMC_Type) || (IMC_IDRAC_11G_MONOLITHIC== IMC_Type) ) + printf ("\niDRAC6 MAC Address "); + else if ( (IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_12G_MONOLITHIC== IMC_Type) ) + printf ("\niDRAC7 MAC Address "); + + for (j=0;j<5;j++) + printf("%02x:",VirtualMacAddress[j]); + printf("%02x",VirtualMacAddress[j]); /*5*/ + + printf ("\n\r"); + + } + return 0; +} + + +/***************************************************************** +* Function Name: ipmi_macinfo_drac_idrac_mac +* +* Description: This function retrieves the mac address of DRAC or iDRAC +* Input: NicNum +* Output: +* Return: +* +******************************************************************/ + +static int ipmi_macinfo_drac_idrac_mac(void* intf,uint8_t NicNum) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t input_length=0; + uint8_t iDRAC6MacAddressByte[MACADDRESSLENGH]; + uint8_t j; + + ipmi_macinfo_drac_idrac_virtual_mac (intf,NicNum); + + + if ((0xff==NicNum || IDRAC_NIC_NUMBER==NicNum) && 0 == UseVirtualMacAddress) + { + + input_length = 0; + + msg_data[input_length++] = LAN_CHANNEL_NUMBER; + msg_data[input_length++] = MAC_ADDR_PARAM; + msg_data[input_length++] = 0x00; + msg_data[input_length++] = 0x00; + + req.msg.netfn = TRANSPORT_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_LAN_PARAM_CMD; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting MAC Address: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + memcpy(iDRAC6MacAddressByte,&rsp[PARAM_REV_OFFSET],MACADDRESSLENGH); + + if (IMC_IDRAC_10G == IMC_Type) + printf ("\n\rDRAC MAC Address "); + else if ((IMC_IDRAC_11G_MODULAR == IMC_Type) || (IMC_IDRAC_11G_MONOLITHIC== IMC_Type)) + printf ("\n\riDRAC6 MAC Address "); + else if ((IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_12G_MONOLITHIC== IMC_Type)) + printf ("\n\riDRAC7 MAC Address "); + else + printf ("\n\riDRAC6 MAC Address "); + + for (j=0;j<5;j++) + printf("%02x:",iDRAC6MacAddressByte[j]); + printf("%02x",iDRAC6MacAddressByte[j]); + + printf ("\n\r"); + } + return 0; +} + + +/***************************************************************** +* Function Name: ipmi_macinfo_10g +* +* Description: This function retrieves the mac address of LOMs +* Input: intf - ipmi interface + NicNum - NIC number +* Output: +* Return: +* +******************************************************************/ + +static int ipmi_macinfo_10g (void* intf, uint8_t NicNum) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t input_length=0; + + uint8_t j; + uint8_t i; + + uint8_t Total_No_NICs = 0; + + + InitEmbeddedNICMacAddressValues (); + + memset(msg_data, 0, sizeof(msg_data)); + input_length = 0; + msg_data[input_length++] = 0x00; /* Get Parameter Command */ + msg_data[input_length++] = EMB_NIC_MAC_ADDRESS_9G_10G; /* OEM Param */ + + msg_data[input_length++] = 0x00; + msg_data[input_length++] = 0x00; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = APP_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_SYSTEM_INFO_CMD; + req.msg.data = msg_data; + + + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting MAC Address: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + if (fdebug) dump_buf("GetMacResp_10G",rsp,rsp_len,0); + + Total_No_NICs = (uint8_t) rsp[PARAM_REV_OFFSET]; /* Byte 1: Total Number of Embedded NICs */ + + if (IDRAC_NIC_NUMBER != NicNum) + { + if (0xff == NicNum) + { + printf ("\n\rSystem LOMs"); + } + printf("\n\rNIC Number\tMAC Address\n\r"); + + memcpy(&EmbeddedNICMacAddress_10G,&rsp[PARAM_REV_OFFSET+TOTAL_N0_NICS_INDEX],Total_No_NICs* MACADDRESSLENGH); + + + /*Read the LOM type and Mac Addresses */ + + for (i=0;i<Total_No_NICs;i++) + { + if ((0xff==NicNum) || (i == NicNum) ) + { + printf ("\n\r%d",i); + printf ("\t\t"); + for (j=0;j<5;j++) + { + printf("%02x:",EmbeddedNICMacAddress_10G.MacAddress[i].MacAddressByte[j]); + } + printf("%02x",EmbeddedNICMacAddress_10G.MacAddress[i].MacAddressByte[j]); + } + } + printf ("\n\r"); + + } + + ipmi_macinfo_drac_idrac_mac(intf,NicNum); + + + return 0; +} + + +/***************************************************************** +* Function Name: ipmi_macinfo_11g +* +* Description: This function retrieves the mac address of LOMs +* Input: intf - ipmi interface +* Output: +* Return: +* +******************************************************************/ + +static int ipmi_macinfo_11g (void* intf, uint8_t NicNum) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t msg_data[30]; + uint8_t input_length=0; + uint8_t len; + uint8_t j; + uint8_t offset; + uint8_t maxlen; + uint8_t loop_count; + uint8_t i; + uint8_t lom_mactype; + uint8_t lom_nicnum; + uint8_t lom_ethstat; + uint8_t *lom_mac; + // uint8_t LOMStatus = 0; + // uint8_t PlayingDead = 0; + + offset = 0; + len = 8; /*eigher 8 or 16 */ + maxlen = 64; + loop_count = maxlen / len; + + InitEmbeddedNICMacAddressValues (); + + memset(msg_data, 0, sizeof(msg_data)); + input_length = 0; + msg_data[input_length++] = 0x00; /* Get Parameter Command */ + msg_data[input_length++] = EMB_NIC_MAC_ADDRESS_11G; /* OEM Param */ + + msg_data[input_length++] = 0x00; + msg_data[input_length++] = 0x00; + msg_data[input_length++] = 0x00; + msg_data[input_length++] = 0x00; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = APP_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_SYSTEM_INFO_CMD; + req.msg.data = msg_data; + + + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting MAC Address: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + len = 8; /*eigher 8 or 16 */ + maxlen = (uint8_t) rsp[0+PARAM_REV_OFFSET]; + loop_count = maxlen / len; + + if (IDRAC_NIC_NUMBER != NicNum) + { + if (0xff == NicNum) + { + printf ("\n\rSystem LOMs"); + } + printf("\n\rNIC Number\tMAC Address\t\tStatus\n\r"); + + + /*Read the LOM type and Mac Addresses */ + offset=0; + for (i=0;i<loop_count;i++,offset=offset+len) + { + input_length = 4; + msg_data[input_length++] = offset; + msg_data[input_length++] = len; + + req.msg.netfn = APP_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_SYSTEM_INFO_CMD; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting MAC Address: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + if (fdebug) { + printf("ipmi_macinfo_11g(%d) i=%d offset=%d\n",NicNum,i,offset); + dump_buf("GetMacResp",rsp,rsp_len,0); + } + + memcpy(&(EmbeddedNICMacAddress.LOMMacAddress[i]),&rsp[PARAM_REV_OFFSET],len); + +#ifdef LOM_OLD + lom_ethstat = EmbeddedNICMacAddress.LOMMacAddress[i].EthernetStatus; + lom_mactype = EmbeddedNICMacAddress.LOMMacAddress[i].MacType; + lom_nicnum = EmbeddedNICMacAddress.LOMMacAddress[i].NICNumber; + lom_mac = &EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte[0]; +#else + lom_ethstat = ((EmbeddedNICMacAddress.LOMMacAddress[i].b0 & 0xc0) >> 6); + lom_mactype = ((EmbeddedNICMacAddress.LOMMacAddress[i].b0 & 0x30) >> 4); + /* lom_bladslot = (b0 & 0x0f); */ + lom_nicnum = (EmbeddedNICMacAddress.LOMMacAddress[i].b1 & 0x1f); + lom_mac = &EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte[0]; + if (fdebug) { + printf("\n\rlom_ethstat=%x lom_mactype=%x lom_nicnum=%x\n", + lom_ethstat,lom_mactype,lom_nicnum); + printf("MacAdrB=%02x:%02x:%02x:%02x:%02x:%02x\n", + lom_mac[0], lom_mac[1], lom_mac[2], + lom_mac[3], lom_mac[4], lom_mac[5]); + printf("\n\rrsp_mac=%02x:%02x:%02x:%02x:%02x:%02x\n", + rsp[3], rsp[4], rsp[5], rsp[6], rsp[7], rsp[8]); + } + lom_mac = &rsp[3]; +#endif + + if (LOM_MACTYPE_ETHERNET == lom_mactype) + { + + if ( (0xff==NicNum) || (NicNum == lom_nicnum) ) + { + printf ("\n\r%d",lom_nicnum); + printf ("\t\t"); + for (j=0;j<5;j++) + printf("%02x:",lom_mac[j]); + printf("%02x",lom_mac[j]); + + if (LOM_ETHERNET_ENABLED == lom_ethstat) + printf ("\tEnabled"); + else + printf ("\tDisabled"); + } + } + + } + printf ("\n\r"); + + } + + ipmi_macinfo_drac_idrac_mac(intf,NicNum); + + return 0; + +} + + + +/***************************************************************** +* Function Name: ipmi_macinfo +* +* Description: This function retrieves the mac address of LOMs +* Input: intf - ipmi interface +* Output: +* Return: +* +******************************************************************/ + +static int ipmi_macinfo (void* intf, uint8_t NicNum) +{ + if (IMC_IDRAC_10G == IMC_Type) + { + return ipmi_macinfo_10g (intf,NicNum); + } + else if ((IMC_IDRAC_11G_MODULAR == IMC_Type || IMC_IDRAC_11G_MONOLITHIC== IMC_Type ) || + (IMC_IDRAC_12G_MODULAR == IMC_Type || IMC_IDRAC_12G_MONOLITHIC== IMC_Type ) ) + { + return ipmi_macinfo_11g (intf,NicNum); + } + else + { + lprintf(LOG_ERR, " Error in getting MAC Address : Not supported platform"); + return 0; + } +} + + +/***************************************************************** +* Function Name: ipmi_mac_usage +* +* Description: This function prints help message for mac command +* Input: +* Output: +* +* Return: +* +******************************************************************/ + +static void +ipmi_mac_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " mac list"); + lprintf(LOG_NOTICE, " Lists the MAC address of LOMs"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " mac get <NIC number>"); + lprintf(LOG_NOTICE, " Shows the MAC address of specified LOM. 0-7 System LOM, 8- DRAC/iDRAC."); + lprintf(LOG_NOTICE, ""); +} + +/***************************************************************** +* Function Name: ipmi_delloem_lan_main +* +* Description: This function processes the delloem lan command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ + +static int ipmi_delloem_lan_main (void * intf, int argc, char ** argv) +{ + int rc = 0; + + int nic_selection = 0; + char nic_set[2] = {0}; + current_arg++; + if (argv[current_arg] == NULL || strcmp(argv[current_arg], "help") == 0) + { + ipmi_lan_usage(); + return 0; + } + ipmi_idracvalidator_command(intf); + if (!IsLANSupported()) + { + printf("lan is not supported on this system.\n"); + return -1; + } + else if (strncmp(argv[current_arg], "set\0", 4) == 0) + { + current_arg++; + if (argv[current_arg] == NULL) + { + ipmi_lan_usage(); + return -1; + } + if(iDRAC_FLAG == IDRAC_12G) { + nic_selection = get_nic_selection_mode_12g(intf,current_arg,argv,nic_set); + if (INVALID == nic_selection) + { + ipmi_lan_usage(); + return -1; + } else if(INVAILD_FAILOVER_MODE == nic_selection) { + printf(INVAILD_FAILOVER_MODE_STRING); + return 0; + } else if(INVAILD_FAILOVER_MODE_SETTINGS == nic_selection){ + printf(INVAILD_FAILOVER_MODE_SET); + return 0; + } else if(INVAILD_SHARED_MODE == nic_selection){ + printf(INVAILD_SHARED_MODE_SET_STRING); + return 0; + } + + rc = ipmi_lan_set_nic_selection_12g(intf,nic_set); + } + else + { + nic_selection = get_nic_selection_mode(current_arg,argv); + + if (INVALID == nic_selection) + { + ipmi_lan_usage(); + return -1; + } + if(IMC_IDRAC_11G_MODULAR == IMC_Type) { + printf(INVAILD_SHARED_MODE_SET_STRING); + return 0; + } + rc = ipmi_lan_set_nic_selection(intf,nic_selection); + } + return 0; + } + else if (strncmp(argv[current_arg], "get\0", 4) == 0) + { + current_arg++; + if (argv[current_arg] == NULL) + { + rc = ipmi_lan_get_nic_selection(intf); + return rc; + } + else if (strncmp(argv[current_arg], "active\0", 7) == 0) + { + rc = ipmi_lan_get_active_nic(intf); + return rc; + } + else + { + ipmi_lan_usage(); + } + + } + else + { + ipmi_lan_usage(); + return -1; + } + return(rc); +} + + +static int IsLANSupported () +{ + if (IMC_IDRAC_11G_MODULAR == IMC_Type) + return 0; + return 1; +} + + +int get_nic_selection_mode_12g (void* intf,int current_arg, char ** argv, char *nic_set) +{ + int failover = 0; + + // First get the current settings. + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t input_length=0; + + input_length = 0; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + + req.msg.cmd = GET_NIC_SELECTION_12G_CMD; + + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting NIC selection: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", + rv,decode_cc(0,rv)); + return rv; + } + + nic_set[0] = rsp[0]; + nic_set[1] = rsp[1]; + + + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "dedicated\0", 10)) + { + nic_set[0] = 1; + nic_set[1] = 0; + return 0; + } + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "shared\0", 7)) + { + + } + else + return INVALID; + + current_arg++; + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "with\0", 5)) + { + } + else + return INVALID; + + current_arg++; + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "failover\0", 9)) + { + failover = 1; + } + if(failover) + current_arg++; + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "lom1\0", 5)) + { + if(IMC_IDRAC_12G_MODULAR == IMC_Type) + { + return INVAILD_SHARED_MODE; + } + if(failover) { + if(nic_set[0] == 2) + { + return INVAILD_FAILOVER_MODE; + } else if(nic_set[0] == 1) { + return INVAILD_FAILOVER_MODE_SETTINGS; + } + nic_set[1] = 2; + } + else { + nic_set[0] = 2; + if(nic_set[1] == 2) + nic_set[1] = 0; + } + return 0; + } + else if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "lom2\0", 5)) + { + if(IMC_IDRAC_12G_MODULAR == IMC_Type) + { + return INVAILD_SHARED_MODE; + } + if(failover) { + if(nic_set[0] == 3) + { + return INVAILD_FAILOVER_MODE; + } else if(nic_set[0] == 1) { + return INVAILD_FAILOVER_MODE_SETTINGS; + } + nic_set[1] = 3; + } + else { + nic_set[0] = 3; + if(nic_set[1] == 3) + nic_set[1] = 0; + + } + return 0; + } + else if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "lom3\0", 5)) + { + if(IMC_IDRAC_12G_MODULAR == IMC_Type) + { + return INVAILD_SHARED_MODE; + } + if(failover) { + if(nic_set[0] == 4) + { + return INVAILD_FAILOVER_MODE; + } else if(nic_set[0] == 1) { + return INVAILD_FAILOVER_MODE_SETTINGS; + } + nic_set[1] = 4; + } + else { + nic_set[0] = 4; + if(nic_set[1] == 4) + nic_set[1] = 0; + } + return 0; + } + else if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "lom4\0", 5)) + { + if(IMC_IDRAC_12G_MODULAR == IMC_Type) + { + return INVAILD_SHARED_MODE; + } + if(failover) { + if(nic_set[0] == 5) + { + return INVAILD_FAILOVER_MODE; + } else if(nic_set[0] == 1) { + return INVAILD_FAILOVER_MODE_SETTINGS; + } + nic_set[1] = 5; + } + else { + nic_set[0] = 5; + if(nic_set[1] == 5) + nic_set[1] = 0; + } + return 0; + } + else if (failover && NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "none\0", 5)) + { + if(IMC_IDRAC_12G_MODULAR == IMC_Type) + { + return INVAILD_SHARED_MODE; + } + if(failover) { + if(nic_set[0] == 1) { + return INVAILD_FAILOVER_MODE_SETTINGS; + } + nic_set[1] = 0; + } + return 0; + } + else if (failover && NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "all\0", 4)) + { + } + else + return INVALID; + + current_arg++; + if (failover && NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "loms\0", 5)) + { + if(IMC_IDRAC_12G_MODULAR == IMC_Type) + { + return INVAILD_SHARED_MODE; + } + if(nic_set[0] == 1) { + return INVAILD_FAILOVER_MODE_SETTINGS; + } + nic_set[1] = 6; + return 0; + } + + return INVALID; + +} + + +static int get_nic_selection_mode (int current_arg, char ** argv) +{ + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "dedicated\0", 10)) + { + return DEDICATED; + } + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "shared\0", 7)) + { + if (NULL == argv[current_arg+1] ) + return SHARED; + } + current_arg++; + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "with\0", 5)) + { + } + else + return INVALID; + + current_arg++; + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "failover\0", 9)) + { + } + else + return INVALID; + + current_arg++; + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "lom2\0", 5)) + { + return SHARED_WITH_FAILOVER_LOM2; + } + else if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "all\0", 4)) + { + } + else + return INVALID; + + current_arg++; + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "loms\0", 5)) + { + return SHARED_WITH_FAILOVER_ALL_LOMS; + } + + return INVALID; + +} + + +static int ipmi_lan_set_nic_selection_12g (void* intf, uint8_t* nic_selection) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t input_length=0; + + input_length = 0; + + msg_data[input_length++] = nic_selection[0]; + msg_data[input_length++] = nic_selection[1]; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = SET_NIC_SELECTION_12G_CMD; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in setting NIC selection: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", + rv,decode_cc(0,rv)); + return rv; + } + printf("configured successfully"); + + return 0; +} + + +static int ipmi_lan_set_nic_selection (void* intf, uint8_t nic_selection) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t input_length=0; + //uint8_t j; + + input_length = 0; + + msg_data[input_length++] = nic_selection; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = SET_NIC_SELECTION_CMD; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in setting NIC selection: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", + rv,decode_cc(0,rv)); + return rv; + } + printf("configured successfully"); + + return 0; +} + +static int ipmi_lan_get_nic_selection (void* intf) +{ + uint8_t nic_selection=-1; + uint8_t nic_selection_failover = 0; + + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t input_length=0; + //uint8_t j; + + input_length = 0; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + if(iDRAC_FLAG == IDRAC_12G) + req.msg.cmd = GET_NIC_SELECTION_12G_CMD; + else + req.msg.cmd = GET_NIC_SELECTION_CMD; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting NIC selection: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", + rv,decode_cc(0,rv)); + return rv; + } + nic_selection = rsp[0]; + + if(iDRAC_FLAG == IDRAC_12G) + { + + nic_selection_failover = rsp[1]; + if ((nic_selection < 6) && (nic_selection > 0) && (nic_selection_failover < 7)) + { + if(nic_selection == 1) { + printf ("%s\n",NIC_Selection_Mode_String_12g[nic_selection-1]); + } else if(nic_selection) { + printf ("Shared LOM : %s\n",NIC_Selection_Mode_String_12g[nic_selection-1]); + if(nic_selection_failover == 0) + printf ("Failover LOM : None\n"); + else if(nic_selection_failover >= 2 && nic_selection_failover <= 6) + printf ("Failover LOM : %s\n",NIC_Selection_Mode_String_12g[nic_selection_failover + 3]); + } + + } + else + { + lprintf(LOG_ERR, " Error Outof bond Value received (%d) (%d) \n",nic_selection,nic_selection_failover); + return -1; + } + } + else + { + printf ("%s\n",NIC_Selection_Mode_String[nic_selection]); + } + + return 0; +} + +static int ipmi_lan_get_active_nic (void* intf) +{ + uint8_t active_nic=0; + uint8_t current_lom =0; + + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t input_length=0; + + input_length = 0; + + msg_data[input_length++] = 0; /*Get current LOM*/ + msg_data[input_length++] = 0; /*Reserved*/ + msg_data[input_length++] = 0; /*Reserved*/ + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_ACTIVE_NIC_CMD; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting Current LOM: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", + rv,decode_cc(0,rv)); + return rv; + } + current_lom = rsp[0]; + + input_length = 0; + + msg_data[input_length++] = 1; //Get Link status + msg_data[input_length++] = 0; //Reserved + msg_data[input_length++] = 0; //Reserved + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_ACTIVE_NIC_CMD; + req.msg.data = msg_data; + req.msg.data_len = input_length; + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting Active LOM Status: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", + rv,decode_cc(0,rv)); + return rv; + } + + active_nic = rsp[1]; + if (current_lom < 5 && active_nic) + printf ("\n%s\n",ActiveLOM_String[current_lom]); + else + printf ("\n%s\n",ActiveLOM_String[5]); + + return 0; +} + + +static void +ipmi_lan_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lan set <Mode> "); + lprintf(LOG_NOTICE, " sets the NIC Selection Mode :"); + lprintf(LOG_NOTICE, " on iDRAC12g :"); + + lprintf(LOG_NOTICE, " dedicated, shared with lom1, shared with lom2,shared with lom3,shared "); + lprintf(LOG_NOTICE, " with lom4,shared with failover lom1,shared with failover lom2,shared "); + lprintf(LOG_NOTICE, " with failover lom3,shared with failoverlom4,shared with Failover all "); + lprintf(LOG_NOTICE, " loms, shared with Failover None)."); + lprintf(LOG_NOTICE, " on other systems :"); + lprintf(LOG_NOTICE, " dedicated, shared, shared with failoverlom2,"); + lprintf(LOG_NOTICE, " shared with Failover all loms."); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lan get "); + lprintf(LOG_NOTICE, " on iDRAC12g :"); + lprintf(LOG_NOTICE, " returns the current NIC Selection Mode (dedicated, shared with lom1, shared "); + lprintf(LOG_NOTICE, " with lom2, shared with lom3, shared with lom4,shared with failover lom1,"); + lprintf(LOG_NOTICE, " shared with failover lom2,shared with failover lom3,shared with failover "); + lprintf(LOG_NOTICE, " lom4,shared with Failover all loms,shared with Failover None)."); + lprintf(LOG_NOTICE, " on other systems :"); + lprintf(LOG_NOTICE, " dedicated, shared, shared with failover,"); + lprintf(LOG_NOTICE, " lom2, shared with Failover all loms."); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lan get active"); + lprintf(LOG_NOTICE, " Get the current active LOMs (LOM1, LOM2, LOM3, LOM4, NONE)."); + lprintf(LOG_NOTICE, ""); + +} + +/***************************************************************** +* Function Name: ipmi_delloem_powermonitor_main +* +* Description: This function processes the delloem powermonitor command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ + +static int ipmi_delloem_powermonitor_main (void * intf, int argc, char ** argv) +{ + int rc = 0; + + current_arg++; + if (argc > 1 && strcmp(argv[current_arg], "help") == 0) + { + ipmi_powermonitor_usage(); + return 0; + } + ipmi_idracvalidator_command(intf); + if (argc == 1) + { + rc = ipmi_powermgmt(intf); + } + else if (strncmp(argv[current_arg], "status\0", 7) == 0) + { + rc = ipmi_powermgmt(intf); + } + + else if (strncmp(argv[current_arg], "clear\0", 6) == 0) + { + current_arg++; + if (argv[current_arg] == NULL) + { + ipmi_powermonitor_usage(); + return -1; + } + else if (strncmp(argv[current_arg], "peakpower\0", 10) == 0) + { + rc = ipmi_powermgmt_clear(intf, 1); + } + else if (strncmp(argv[current_arg], "cumulativepower\0", 16) == 0) + { + rc = ipmi_powermgmt_clear(intf, 0); + } + else + { + ipmi_powermonitor_usage(); + return -1; + } + + } + + + else if (strncmp(argv[current_arg], "powerconsumption\0", 17) == 0) + { + current_arg++; + + if (argv[current_arg] == NULL) + { + + rc=ipmi_print_get_power_consmpt_data(intf,watt); + + } + else if (strncmp(argv[current_arg], "watt\0", 5) == 0) + { + + rc = ipmi_print_get_power_consmpt_data(intf, watt); + } + else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) + { + rc = ipmi_print_get_power_consmpt_data(intf, btuphr); + } + else + { + ipmi_powermonitor_usage(); + return -1; + } + } + else if (strncmp(argv[current_arg], "powerconsumptionhistory\0", 23) == 0) + { + current_arg++; + if (argv[current_arg] == NULL) + { + rc=ipmi_print_power_consmpt_history(intf,watt); + + } + else if (strncmp(argv[current_arg], "watt\0", 5) == 0) + { + rc = ipmi_print_power_consmpt_history(intf, watt); + } + else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) + { + rc = ipmi_print_power_consmpt_history(intf, btuphr); + } + else + { + ipmi_powermonitor_usage(); + return -1; + } + + } + + else if (strncmp(argv[current_arg], "getpowerbudget\0", 15) == 0) + { + current_arg++; + if (argv[current_arg] == NULL) + { + rc=ipmi_print_power_cap(intf,watt); + + } + else if (strncmp(argv[current_arg], "watt\0", 5) == 0) + { + rc = ipmi_print_power_cap(intf, watt); + } + else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) + { + rc = ipmi_print_power_cap(intf, btuphr); + } + else + { + ipmi_powermonitor_usage(); + return -1; + } + + } + + else if (strncmp(argv[current_arg], "setpowerbudget\0", 15) == 0) + { + int val; + current_arg++; + if (argv[current_arg] == NULL) + { + ipmi_powermonitor_usage(); + return -1; + } + if (strchr(argv[current_arg], '.')) + { + lprintf(LOG_ERR, " Cap value in Watts, Btu/hr or percent should be whole number"); + return -1; + } + make_int(argv[current_arg],&val); + current_arg++; + if (argv[current_arg] == NULL) + { + ipmi_powermonitor_usage(); + } + else if (strncmp(argv[current_arg], "watt\0", 5) == 0) + { + rc=ipmi_set_power_cap(intf,watt,val); + } + else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) + { + rc=ipmi_set_power_cap(intf, btuphr,val); + } + else if (strncmp(argv[current_arg], "percent\0", 8) == 0) + { + rc=ipmi_set_power_cap(intf,percent,val); + } + else + { + ipmi_powermonitor_usage(); + return -1; + } + + } + + else if (strncmp(argv[current_arg], "enablepowercap\0", 15) == 0) + { + rc = ipmi_set_power_capstatus_command(intf,1); + } + + else if (strncmp(argv[current_arg], "disablepowercap\0", 16) == 0) + { + rc = ipmi_set_power_capstatus_command(intf,0); + } + else + { + ipmi_powermonitor_usage(); + return -1; + } + if (sdrcache != NULL) free_sdr_cache(sdrcache); + return(rc); +} + + +/***************************************************************** +* Function Name: ipmi_time_to_str +* +* Description: This function converts ipmi time format into gmtime format +* Input: rawTime - ipmi time format +* Output: strTime - gmtime format +* +* Return: +* +******************************************************************/ + +static void +ipmi_time_to_str(time_t rawTime, char* strTime) +{ + struct tm * tm; + char *temp; + tm = gmtime(&rawTime); + + temp = asctime(tm); + + strcpy(strTime,temp); +} + +#ifdef NOT_USED +static int ipmi_get_sensor_reading(void *intf , + unsigned char sensorNumber, + SensorReadingType* pSensorReadingData); +/***************************************************************** +* Function Name: ipmi_get_sensor_reading +* +* Description: This function retrieves a raw sensor reading +* Input: sensorOwner - sensor owner id +* sensorNumber - sensor id +* intf - ipmi interface +* Output: sensorReadingData - ipmi response structure +* Return: 1 on error +* 0 if successful +* +******************************************************************/ +static int +ipmi_get_sensor_reading(void *intf , + unsigned char sensorNumber, + SensorReadingType* pSensorReadingData) +{ + struct ipmi_rq req; + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len; + int rc = 0; + // uint8_t save_addr; + + memset(&req, 0, sizeof (req)); + req.msg.netfn = IPMI_NETFN_SE; + req.msg.lun = 0; + req.msg.cmd = (uint8_t)(GET_SENSOR_READING | 0x0ff); + req.msg.data = &sensorNumber; + req.msg.data_len = 1; + + if (NULL == pSensorReadingData) + return -1; + memset(pSensorReadingData,0, sizeof(SensorReadingType)); + + rc = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rc) return 1; + + memcpy(pSensorReadingData, rsp, sizeof(SensorReadingType)); + + /* if sensor messages are disabled, return error*/ + if ((!(rsp[1]& 0xC0)) || ((rsp[1] & 0x20))) { + rc =1; + } + return rc; +} +#endif + + +/***************************************************************** +* Function Name: ipmi_get_power_capstatus_command +* +* Description: This function gets the power cap status +* Input: intf - ipmi interface +* Global: PowercapSetable_flag - power cap status +* Output: +* +* Return: +* +******************************************************************/ +static int +ipmi_get_power_capstatus_command (void * intf) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[2]; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = IPMI_DELL_POWER_CAP_STATUS; + req.msg.data_len = 2; + req.msg.data = data; + data[0] = 01; + data[1] = 0xFF; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting powercap status: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", + rv,decode_cc(0,rv)); + return rv; + } + if (rsp[0]&0x02) + PowercapSetable_flag=1; + if(rsp[0]&0x01) + PowercapstatusFlag=1; + return 0; +} + +/***************************************************************** +* Function Name: ipmi_set_power_capstatus_command +* +* Description: This function sets the power cap status +* Input: intf - ipmi interface +* val - power cap status +* Output: +* +* Return: +* +******************************************************************/ + +static int +ipmi_set_power_capstatus_command (void * intf,uint8_t val) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[2]; + if(ipmi_get_power_capstatus_command(intf) < 0) + return -1; + + if (PowercapSetable_flag!=1) + { + lprintf(LOG_ERR, " Can not set powercap on this system"); + return -1; + } + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = IPMI_DELL_POWER_CAP_STATUS; + req.msg.data_len = 2; + req.msg.data = data; + + data[0] = 00; + data[1] = val; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error setting powercap status: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; //return unlicensed Error code + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + return 0; +} + + + +/***************************************************************** +* Function Name: ipmi_powermgmt +* +* Description: This function print the powermonitor details +* Input: intf - ipmi interface +* Output: +* +* Return: +* +******************************************************************/ +static int ipmi_powermgmt(void* intf) +{ + time_t now; + struct tm* tm; + char* dte; + + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t msg_data[2]; + uint32_t cumStartTimeConv; + uint32_t cumReadingConv; + uint32_t maxPeakStartTimeConv; + uint32_t ampPeakTimeConv; + uint16_t ampReadingConv; + uint32_t wattPeakTimeConv; + uint32_t wattReadingConv; + uint32_t bmctimeconv; + uint32_t * bmctimeconvval; + + IPMI_POWER_MONITOR* pwrMonitorInfo; + + + char cumStartTime[26]; + char maxPeakStartTime[26]; + char ampPeakTime[26]; + char wattPeakTime[26]; + char bmctime[26]; + + // float cumReading; + int ampReading; + int wattReading; + int ampReadingRemainder; + // int round; + // int round2; + int remainder; + + now = time(0); + tm = gmtime(&now); + dte = asctime(tm); + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.lun = 0; + req.msg.cmd = IPMI_CMD_GET_SEL_TIME; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting BMC time info "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + bmctimeconvval=(uint32_t*)rsp; +#if WORDS_BIGENDIAN + bmctimeconv=BSWAP_32(*bmctimeconvval); +#else + bmctimeconv=*bmctimeconvval; +#endif + + /* get powermanagement info*/ + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0x0; + req.msg.cmd = GET_PWRMGMT_INFO_CMD; + req.msg.data = msg_data; + req.msg.data_len = 2; + + memset(msg_data, 0, 2); + msg_data[0] = 0x07; + msg_data[1] = 0x01; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting power management info "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + pwrMonitorInfo = (IPMI_POWER_MONITOR*)rsp; + +#if WORDS_BIGENDIAN + cumStartTimeConv = BSWAP_32(pwrMonitorInfo->cumStartTime); + cumReadingConv = BSWAP_32(pwrMonitorInfo->cumReading); + maxPeakStartTimeConv = BSWAP_32(pwrMonitorInfo->maxPeakStartTime); + ampPeakTimeConv = BSWAP_32(pwrMonitorInfo->ampPeakTime); + ampReadingConv = BSWAP_16(pwrMonitorInfo->ampReading); + wattPeakTimeConv = BSWAP_32(pwrMonitorInfo->wattPeakTime); + wattReadingConv = BSWAP_16(pwrMonitorInfo->wattReading); +#else + cumStartTimeConv = pwrMonitorInfo->cumStartTime; + cumReadingConv = pwrMonitorInfo->cumReading; + maxPeakStartTimeConv = pwrMonitorInfo->maxPeakStartTime; + ampPeakTimeConv = pwrMonitorInfo->ampPeakTime; + ampReadingConv = pwrMonitorInfo->ampReading; + wattPeakTimeConv = pwrMonitorInfo->wattPeakTime; + wattReadingConv = pwrMonitorInfo->wattReading; +#endif + + ipmi_time_to_str(cumStartTimeConv, cumStartTime); + + ipmi_time_to_str(maxPeakStartTimeConv, maxPeakStartTime); + ipmi_time_to_str(ampPeakTimeConv, ampPeakTime); + ipmi_time_to_str(wattPeakTimeConv, wattPeakTime); + ipmi_time_to_str(bmctimeconv, bmctime); + + now = time(0); + + + remainder = (cumReadingConv % 1000); + cumReadingConv = cumReadingConv / 1000; + remainder = (remainder + 50) / 100; + + ampReading = ampReadingConv; + ampReadingRemainder = ampReading%10; + ampReading = ampReading/10; + + wattReading = wattReadingConv; + + printf("Power Tracking Statistics\n"); + printf("Statistic : Cumulative Energy Consumption\n"); + printf("Start Time : %s", cumStartTime); + printf("Finish Time : %s", bmctime); + printf("Reading : %d.%d kWh\n\n", cumReadingConv, remainder); + + printf("Statistic : System Peak Power\n"); + printf("Start Time : %s", maxPeakStartTime); + printf("Peak Time : %s", wattPeakTime); + printf("Peak Reading : %d W\n\n", wattReading); + + printf("Statistic : System Peak Amperage\n"); + printf("Start Time : %s", maxPeakStartTime); + printf("Peak Time : %s", ampPeakTime); + printf("Peak Reading : %d.%d A\n", ampReading, ampReadingRemainder); + + + return 0; + +} +/***************************************************************** +* Function Name: ipmi_powermgmt_clear +* +* Description: This function clears peakpower / cumulativepower value +* Input: intf - ipmi interface +* clearValue - peakpower / cumulativepower +* Output: +* +* Return: +* +******************************************************************/ +static int +ipmi_powermgmt_clear(void* intf,uint8_t clearValue) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t clearType; + uint8_t msg_data[3]; + + if (clearValue) { + clearType = 2; + } else { + clearType = 1; + } + + /* clear powermanagement info*/ + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = CLEAR_PWRMGMT_INFO_CMD; + req.msg.data = msg_data; + req.msg.data_len = 3; + + + memset(msg_data, 0, 3); + msg_data[0] = 0x07; + msg_data[1] = 0x01; + msg_data[2] = clearType; + + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error clearing power values: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + return 0; + +} + +/***************************************************************** +* Function Name: watt_to_btuphr_conversion +* +* Description: This function converts the power value in watt to btuphr +* Input: powerinwatt - power in watt +* +* Output: power in btuphr +* +* Return: +* +******************************************************************/ +static uint64_t watt_to_btuphr_conversion(uint32_t powerinwatt) +{ + uint64_t powerinbtuphr; + powerinbtuphr=(uint64_t)(3.413*powerinwatt); + + return(powerinbtuphr); +} + +/***************************************************************** +* Function Name: btuphr_to_watt_conversion +* +* Description: This function converts the power value in btuphr to watt +* Input: powerinbtuphr - power in btuphr +* +* Output: power in watt +* +* Return: +* +******************************************************************/ +static uint32_t btuphr_to_watt_conversion(uint64_t powerinbtuphr) +{ + uint32_t powerinwatt; + /*returning the floor value*/ + powerinwatt= (uint32_t)(powerinbtuphr/3.413); + return (powerinwatt); +} + +/***************************************************************** +* Function Name: ipmi_get_power_headroom_command +* +* Description: This function prints the Power consumption information +* Input: intf - ipmi interface +* unit - watt / btuphr +* Output: +* +* Return: +* +******************************************************************/ +static int ipmi_get_power_headroom_command (void * intf,uint8_t unit) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint64_t peakpowerheadroombtuphr; + uint64_t instantpowerhearoom; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_PWR_HEADROOM_CMD; + req.msg.data_len = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting power headroom status: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + if(verbose>1) + printf("power headroom Data : %x %x %x %x ", + /*need to look into */ rsp[0], rsp[1], rsp[2], rsp[3]); + powerheadroom= *(( POWER_HEADROOM *)rsp); +#if WORDS_BIGENDIAN + powerheadroom.instheadroom = BSWAP_16(powerheadroom.instheadroom); + powerheadroom.peakheadroom = BSWAP_16(powerheadroom.peakheadroom); +#endif + + printf ("Headroom\n\r"); + printf ("Statistic Reading\n\r"); + + if(unit == btuphr) + { + peakpowerheadroombtuphr=watt_to_btuphr_conversion(powerheadroom.peakheadroom); + instantpowerhearoom= watt_to_btuphr_conversion(powerheadroom.instheadroom); + + printf ("System Instantaneous Headroom : %ld BTU/hr\n",instantpowerhearoom); + printf ("System Peak Headroom : %ld BTU/hr\n",peakpowerheadroombtuphr); + } + else + { + printf ("System Instantaneous Headroom : %d W\n",powerheadroom.instheadroom); + printf ("System Peak Headroom : %d W\n",powerheadroom.peakheadroom); + } + + return 0; +} + +/***************************************************************** +* Function Name: ipmi_get_power_consumption_data +* +* Description: This function updates the instant Power consumption information +* Input: intf - ipmi interface +* Output: power consumption current reading +* Assumption value will be in Watt. +* +* Return: +* +******************************************************************/ +static int ipmi_get_power_consumption_data(void* intf,uint8_t unit) +{ + int rc = 0; + SensorReadingType sensorReadingData; + uint8_t rsp[IPMI_RSPBUF_SIZE]; + struct sdr_record_list *sdr = NULL; + uchar sdrbuf[SDR_SZ]; + double readingf, warningf, failuref; + int readingbtuphr=0; + int warning_threshbtuphr=0; + int failure_thresbtuphr=0; + int status=0; + int sensor_number = 0; + + if (sdrfile != NULL) { + rc = get_sdr_file(sdrfile,&sdrcache); + if (rc) printf ("Error 0x%02x: Cannot get SDRs from %s\n",rc,sdrfile); + } else if (sdrcache == NULL) { + rc = get_sdr_cache(&sdrcache); + if (rc) printf ("Error 0x%02x: Cannot get SDRs\n",rc); + } + + rc = find_sdr_by_tag(sdrbuf, sdrcache, "System Level", fdebug); + if (rc != 0) + { + printf ("Error %d: Cannot access the System Level sensor data\n",rc); + return rc; + } + sdr = (struct sdr_record_list *)sdrbuf; + + sensor_number = sdrbuf[7]; // sdr->record.full->keys.sensor_num; + if (fdebug) printf("calling GetSensorReading(%x)\n",sensor_number); + rc = GetSensorReading(sensor_number, sdrbuf, + (uchar *)&sensorReadingData.sensorReading); + if (rc != 0) + printf("Error %d getting sensor %x reading\n",rc,sensor_number); + + rc = GetSensorThresholds( sensor_number, rsp); + if (fdebug) printf("GetSensorThresholds(%x) rc = %d\n",sensor_number,rc); + if (rc == 0) + { + readingf = RawToFloat(sensorReadingData.sensorReading,sdrbuf); + warningf = RawToFloat(rsp[4], sdrbuf); + failuref = RawToFloat(rsp[5], sdrbuf); + readingbtuphr = (int)readingf; + warning_threshbtuphr = (int)warningf; + failure_thresbtuphr = (int)failuref; + + if (fdebug) { + printf("Reading 0x%02x = %.2f, Warning 0x%02x = %.2f, Failure 0x%02x = %.2f\n", + sensorReadingData.sensorReading, readingf, + rsp[4], warningf, rsp[5], failuref); + } + + printf ("System Board System Level\n\r"); + if (unit==btuphr) + { + readingbtuphr= watt_to_btuphr_conversion(readingbtuphr); + warning_threshbtuphr= watt_to_btuphr_conversion(warning_threshbtuphr); + failure_thresbtuphr= watt_to_btuphr_conversion( failure_thresbtuphr); + + printf ("Reading : %d BTU/hr\n",readingbtuphr); + printf ("Warning threshold : %d BTU/hr\n",warning_threshbtuphr); + printf ("Failure threshold : %d BTU/hr\n",failure_thresbtuphr); + } + else + { + printf ("Reading : %d W \n",readingbtuphr); + printf ("Warning threshold : %d W \n",(warning_threshbtuphr)); + printf ("Failure threshold : %d W \n",(failure_thresbtuphr)); + } + } + else + { + printf ("Error %d: Cannot access the System Level threshold data\n",rc); + return -1; + } + return status; +} + + + + +/***************************************************************** +* Function Name: ipmi_get_instan_power_consmpt_data +* +* Description: This function updates the instant Power consumption information +* Input: intf - ipmi interface +* Output: instpowerconsumptiondata - instant Power consumption information +* +* Return: +* +******************************************************************/ + +static int ipmi_get_instan_power_consmpt_data(void* intf, + IPMI_INST_POWER_CONSUMPTION_DATA* instpowerconsumptiondata) +{ + + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[2]; + + + /*get instantaneous power consumption command*/ + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_PWR_CONSUMPTION_CMD; + + req.msg.data = msg_data; + req.msg.data_len = 2; + + + + memset(msg_data, 0, 2); + + msg_data[0] = 0x0A; + msg_data[1] = 0x00; + + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting power consumption data: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + * instpowerconsumptiondata = * ( (IPMI_INST_POWER_CONSUMPTION_DATA*) (rsp)); +#if WORDS_BIGENDIAN + instpowerconsumptiondata->instanpowerconsumption = BSWAP_16(instpowerconsumptiondata->instanpowerconsumption); + instpowerconsumptiondata->instanApms = BSWAP_16(instpowerconsumptiondata->instanApms); + instpowerconsumptiondata->resv1 = BSWAP_16(instpowerconsumptiondata->resv1); +#endif + + return 0; + + +} + + +/***************************************************************** +* Function Name: ipmi_print_get_instan_power_Amps_data +* +* Description: This function prints the instant Power consumption information +* Input: instpowerconsumptiondata - instant Power consumption information +* Output: +* +* Return: +* +******************************************************************/ +static void ipmi_print_get_instan_power_Amps_data(IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata) +{ + uint16_t intampsval=0; + uint16_t decimalampsval=0; + + + if (instpowerconsumptiondata.instanApms>0) + { + decimalampsval=(instpowerconsumptiondata.instanApms%10); + intampsval=instpowerconsumptiondata.instanApms/10; + } + printf("\nAmperage value: %d.%d A \n",intampsval,decimalampsval); +} +/***************************************************************** +* Function Name: ipmi_print_get_power_consmpt_data +* +* Description: This function prints the Power consumption information +* Input: intf - ipmi interface +* unit - watt / btuphr +* Output: +* +* Return: +* +******************************************************************/ +static int ipmi_print_get_power_consmpt_data(void* intf,uint8_t unit) +{ + + int rc = 0; + IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata = {0,0,0,0}; + // int i; + //uint16_t inputwattageL=0; + //int sensorIndex = 0; + //uint32_t readingbtuphr; + //uint32_t warning_threshbtuphr; + //uint32_t failure_thresbtuphr; + + printf ("\nPower consumption information\n"); + + + rc=ipmi_get_power_consumption_data(intf,unit); + if (-1 == rc) + return rc; + + rc=ipmi_get_instan_power_consmpt_data(intf,&instpowerconsumptiondata); + if (-1 == rc) + return rc; + + ipmi_print_get_instan_power_Amps_data(instpowerconsumptiondata); + + + rc=ipmi_get_power_headroom_command(intf,unit); + + if (-1 == rc) + return rc; + + return rc; + + +} + + +/***************************************************************** +* Function Name: ipmi_get_avgpower_consmpt_history +* +* Description: This function updates the average power consumption information +* Input: intf - ipmi interface +* Output: pavgpower- average power consumption information +* +* Return: +* +******************************************************************/ +static int ipmi_get_avgpower_consmpt_history(void* intf,IPMI_AVGPOWER_CONSUMP_HISTORY* pavgpower ) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[4]; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; + data[1] = 0xeb; + data[2] = 0; + data[3] = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting average power consumption data: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + if (verbose > 1) + { + printf("Average power consumption history Data :%x %x %x %x %x %x %x %x\n\n", + rsp[0], rsp[1], rsp[2], rsp[3], + rsp[4], rsp[5], rsp[6], rsp[7]); + + } + + *pavgpower = *( (IPMI_AVGPOWER_CONSUMP_HISTORY*) rsp); +#if WORDS_BIGENDIAN + pavgpower->lastminutepower = BSWAP_16(pavgpower->lastminutepower); + pavgpower->lasthourpower = BSWAP_16(pavgpower->lasthourpower); + pavgpower->lastdaypower = BSWAP_16(pavgpower->lastdaypower); + pavgpower->lastweakpower = BSWAP_16(pavgpower->lastweakpower); +#endif + + return 0; +} + +/***************************************************************** +* Function Name: ipmi_get_peakpower_consmpt_history +* +* Description: This function updates the peak power consumption information +* Input: intf - ipmi interface +* Output: pavgpower- peak power consumption information +* +* Return: +* +******************************************************************/ +static int ipmi_get_peakpower_consmpt_history(void* intf,IPMI_POWER_CONSUMP_HISTORY * pstPeakpower) +{ + + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[4]; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; + data[1] = 0xec; + data[2] = 0; + data[3] = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting peak power consumption history: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + if (verbose > 1) + { + 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 %x\n\n", + rsp[0], rsp[1], rsp[2], rsp[3], + rsp[4], rsp[5], rsp[6], rsp[7], + rsp[8], rsp[9], rsp[10], rsp[11], + rsp[12], rsp[13], rsp[14], rsp[15], + rsp[16], rsp[17], rsp[18], rsp[19], + rsp[20], rsp[21], rsp[22], rsp[23] + ); + + } + *pstPeakpower =* ((IPMI_POWER_CONSUMP_HISTORY*)rsp); +#if WORDS_BIGENDIAN + pstPeakpower->lastminutepower = BSWAP_16(pstPeakpower->lastminutepower); + pstPeakpower->lasthourpower = BSWAP_16(pstPeakpower->lasthourpower); + pstPeakpower->lastdaypower = BSWAP_16(pstPeakpower->lastdaypower); + pstPeakpower->lastweakpower = BSWAP_16(pstPeakpower->lastweakpower); + pstPeakpower->lastminutepowertime = BSWAP_32(pstPeakpower->lastminutepowertime); + pstPeakpower->lasthourpowertime = BSWAP_32(pstPeakpower->lasthourpowertime); + pstPeakpower->lastdaypowertime = BSWAP_32(pstPeakpower->lastdaypowertime); + pstPeakpower->lastweekpowertime = BSWAP_32(pstPeakpower->lastweekpowertime); +#endif + return 0; +} + + +/***************************************************************** +* Function Name: ipmi_get_minpower_consmpt_history +* +* Description: This function updates the peak power consumption information +* Input: intf - ipmi interface +* Output: pavgpower- peak power consumption information +* +* Return: +* +******************************************************************/ +static int ipmi_get_minpower_consmpt_history(void* intf,IPMI_POWER_CONSUMP_HISTORY * pstMinpower) +{ + + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[4]; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; + data[1] = 0xed; + data[2] = 0; + data[3] = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting min power consumption history: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + if (verbose > 1) + { + 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 %x\n\n", + rsp[0], rsp[1], rsp[2], rsp[3], + rsp[4], rsp[5], rsp[6], rsp[7], + rsp[8], rsp[9], rsp[10], rsp[11], + rsp[12], rsp[13], rsp[14], rsp[15], + rsp[16], rsp[17], rsp[18], rsp[19], + rsp[20], rsp[21], rsp[22], rsp[23] + ); + + } + *pstMinpower =* ((IPMI_POWER_CONSUMP_HISTORY*)rsp); +#if WORDS_BIGENDIAN + pstMinpower->lastminutepower = BSWAP_16(pstMinpower->lastminutepower); + pstMinpower->lasthourpower = BSWAP_16(pstMinpower->lasthourpower); + pstMinpower->lastdaypower = BSWAP_16(pstMinpower->lastdaypower); + pstMinpower->lastweakpower = BSWAP_16(pstMinpower->lastweakpower); + pstMinpower->lastminutepowertime = BSWAP_32(pstMinpower->lastminutepowertime); + pstMinpower->lasthourpowertime = BSWAP_32(pstMinpower->lasthourpowertime); + pstMinpower->lastdaypowertime = BSWAP_32(pstMinpower->lastdaypowertime); + pstMinpower->lastweekpowertime = BSWAP_32(pstMinpower->lastweekpowertime); +#endif + return 0; +} + + + +/***************************************************************** +* Function Name: ipmi_print_power_consmpt_history +* +* Description: This function print the average and peak power consumption information +* Input: intf - ipmi interface +* unit - watt / btuphr +* Output: +* +* Return: +* +******************************************************************/ +static int ipmi_print_power_consmpt_history(void* intf,int unit ) +{ + + char timestr[30]; + + uint32_t lastminutepeakpower; + uint32_t lasthourpeakpower; + uint32_t lastdaypeakpower; + uint32_t lastweekpeakpower; + + IPMI_AVGPOWER_CONSUMP_HISTORY avgpower; + IPMI_POWER_CONSUMP_HISTORY stMinpower; + IPMI_POWER_CONSUMP_HISTORY stPeakpower; + int rc=0; + + uint64_t tempbtuphrconv; + //uint16_t temp; + + + rc= ipmi_get_avgpower_consmpt_history(intf,&avgpower); + if (-1 == rc) + return rc; + + rc= ipmi_get_peakpower_consmpt_history(intf,&stPeakpower); + if (-1 == rc) + return rc; + + rc= ipmi_get_minpower_consmpt_history(intf,&stMinpower); + if (-1 == rc) + return rc; + + + if(rc==0) + { + printf ("Power Consumption History\n\r\n\r"); + /* The fields are alligned manually changing the spaces will alter the alignment*/ + printf ("Statistic Last Minute Last Hour Last Day Last Week\n\r\n\r"); + + if (unit ==btuphr) + { + printf ("Average Power Consumption "); + tempbtuphrconv=watt_to_btuphr_conversion(avgpower.lastminutepower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(avgpower.lasthourpower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(avgpower.lastdaypower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(avgpower.lastweakpower); + printf ("%4d BTU/hr\n\r",tempbtuphrconv); + + printf ("Max Power Consumption "); + tempbtuphrconv=watt_to_btuphr_conversion(stPeakpower.lastminutepower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(stPeakpower.lasthourpower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(stPeakpower.lastdaypower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(stPeakpower.lastweakpower); + printf ("%4d BTU/hr\n\r",tempbtuphrconv); + + printf ("Min Power Consumption "); + tempbtuphrconv=watt_to_btuphr_conversion(stMinpower.lastminutepower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(stMinpower.lasthourpower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(stMinpower.lastdaypower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(stMinpower.lastweakpower); + printf ("%4d BTU/hr\n\r\n\r",tempbtuphrconv); + + } + else + { + + printf ("Average Power Consumption "); + tempbtuphrconv=(avgpower.lastminutepower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(avgpower.lasthourpower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(avgpower.lastdaypower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(avgpower.lastweakpower); + printf ("%4ld W \n\r",tempbtuphrconv); + + printf ("Max Power Consumption "); + tempbtuphrconv=(stPeakpower.lastminutepower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(stPeakpower.lasthourpower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(stPeakpower.lastdaypower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(stPeakpower.lastweakpower); + printf ("%4ld W \n\r",tempbtuphrconv); + + printf ("Min Power Consumption "); + tempbtuphrconv=(stMinpower.lastminutepower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(stMinpower.lasthourpower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(stMinpower.lastdaypower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(stMinpower.lastweakpower); + printf ("%4ld W \n\r\n\r",tempbtuphrconv); + } + + lastminutepeakpower=stPeakpower.lastminutepowertime; + lasthourpeakpower=stPeakpower.lasthourpowertime; + lastdaypeakpower=stPeakpower.lastdaypowertime; + lastweekpeakpower=stPeakpower.lastweekpowertime; + + printf ("Max Power Time\n\r"); + ipmi_time_to_str(lastminutepeakpower, timestr); + printf ("Last Minute : %s",timestr); + ipmi_time_to_str(lasthourpeakpower, timestr); + printf ("Last Hour : %s",timestr); + ipmi_time_to_str(lastdaypeakpower, timestr); + printf ("Last Day : %s",timestr); + ipmi_time_to_str(lastweekpeakpower, timestr); + printf ("Last Week : %s",timestr); + + + lastminutepeakpower=stMinpower.lastminutepowertime; + lasthourpeakpower=stMinpower.lasthourpowertime; + lastdaypeakpower=stMinpower.lastdaypowertime; + lastweekpeakpower=stMinpower.lastweekpowertime; + + printf ("Min Power Time\n\r"); + ipmi_time_to_str(lastminutepeakpower, timestr); + printf ("Last Minute : %s",timestr); + ipmi_time_to_str(lasthourpeakpower, timestr); + printf ("Last Hour : %s",timestr); + ipmi_time_to_str(lastdaypeakpower, timestr); + printf ("Last Day : %s",timestr); + ipmi_time_to_str(lastweekpeakpower, timestr); + printf ("Last Week : %s",timestr); + + } + return rc; + +} + + + +/***************************************************************** +* Function Name: ipmi_get_power_cap +* +* Description: This function updates the power cap information +* Input: intf - ipmi interface +* Output: ipmipowercap - power cap information +* +* Return: +* +******************************************************************/ + +static int ipmi_get_power_cap(void* intf,IPMI_POWER_CAP* ipmipowercap ) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + //uint64_t tempbtuphrconv; + uint8_t data[4]; + + /* power supply rating command*/ + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + + data[0] = 0; + data[1] = IPMI_DELL_POWER_CAP; + data[2] = 0; + data[3] = 0; + + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting power cap: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + if (verbose > 1){ + printf("power cap Data :%x %x %x %x %x %x %x %x %x %x %x", + rsp[1], rsp[2], rsp[3], + rsp[4], rsp[5], rsp[6], rsp[7], + rsp[8], rsp[9], rsp[10],rsp[11]); + + } + + * ipmipowercap = *((IPMI_POWER_CAP*)(rsp)); +#if WORDS_BIGENDIAN + ipmipowercap->PowerCap = BSWAP_16(ipmipowercap->PowerCap); + ipmipowercap->MaximumPowerConsmp = BSWAP_16(ipmipowercap->MaximumPowerConsmp); + ipmipowercap->MinimumPowerConsmp = BSWAP_16(ipmipowercap->MinimumPowerConsmp); + ipmipowercap->totalnumpowersupp = BSWAP_16(ipmipowercap->totalnumpowersupp); + ipmipowercap->AvailablePower = BSWAP_16(ipmipowercap->AvailablePower); + ipmipowercap->SystemThrottling = BSWAP_16(ipmipowercap->SystemThrottling); + ipmipowercap->Resv = BSWAP_16(ipmipowercap->Resv); +#endif + + return 0; +} + +/***************************************************************** +* Function Name: ipmi_print_power_cap +* +* Description: This function print the power cap information +* Input: intf - ipmi interface +* unit - watt / btuphr +* Output: +* Return: +* +******************************************************************/ +static int ipmi_print_power_cap(void* intf,uint8_t unit ) +{ + uint64_t tempbtuphrconv; + int rc; + IPMI_POWER_CAP ipmipowercap; + + memset(&ipmipowercap,0,sizeof(ipmipowercap)); + rc=ipmi_get_power_cap(intf,&ipmipowercap); + + + if (rc==0) + { + if (unit ==btuphr){ + tempbtuphrconv=watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp); + printf ("Maximum power: %ld BTU/hr\n",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(ipmipowercap.MinimumPowerConsmp); + printf ("Minimum power: %ld BTU/hr\n",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(ipmipowercap.PowerCap); + printf ("Power cap : %ld BTU/hr\n",tempbtuphrconv); + }else{ + printf ("Maximum power: %d Watt\n",ipmipowercap.MaximumPowerConsmp); + printf ("Minimum power: %d Watt\n",ipmipowercap.MinimumPowerConsmp); + printf ("Power cap : %d Watt\n",ipmipowercap.PowerCap); + } + } + return rc; + +} + +/***************************************************************** +* Function Name: ipmi_set_power_cap +* +* Description: This function updates the power cap information +* Input: intf - ipmi interface +* unit - watt / btuphr +* val - new power cap value +* Output: +* Return: +* +******************************************************************/ +static int ipmi_set_power_cap(void* intf,int unit,int val ) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[13]; + uint16_t powercapval; + uint64_t maxpowerbtuphr; + uint64_t maxpowerbtuphr1; + uint64_t minpowerbtuphr; + IPMI_POWER_CAP ipmipowercap; + + if(ipmi_get_power_capstatus_command(intf) < 0) + return -1; // Adding the failed condition check + + if (PowercapSetable_flag!=1) + { + lprintf(LOG_ERR, " Can not set powercap on this system"); + return -1; + } + else if(PowercapstatusFlag!=1) + { + lprintf(LOG_ERR, " Power cap set feature is not enabled"); + return -1; + } + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + memset(data, 0, 4); + req.msg.data = data; + + data[0] = 0; + data[1] = IPMI_DELL_POWER_CAP; + data[2] = 0; + data[3] = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting power cap: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + if (verbose > 1) + { + printf("power cap Data :%x %x %x %x %x %x %x %x %x %x %x", + rsp[1], rsp[2], rsp[3], + rsp[4], rsp[5], rsp[6], rsp[7], + rsp[8], rsp[9], rsp[10],rsp[11]); + + } + + ipmipowercap.PowerCap=((rsp[1]<<8)+rsp[2]); + ipmipowercap.unit=rsp[3]; + ipmipowercap.MaximumPowerConsmp=((rsp[4]<<8)+rsp[5]); + ipmipowercap.MinimumPowerConsmp=((rsp[6]<<8)+rsp[7]); + /* ARC: need Dell to verify these 3 values */ + ipmipowercap.totalnumpowersupp = rsp[8]; + ipmipowercap.AvailablePower = ((rsp[9]<<8)+rsp[10]); + ipmipowercap.SystemThrottling = rsp[11]; + + memset(data, 0, 13); + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = 13; + req.msg.data = data; + data[0] = IPMI_DELL_POWER_CAP; + powercapval=val; + + + data[1] = (powercapval&0XFF); + data[2] = ((powercapval&0XFF00)>>8); + data[3] = unit; + + data[4]=((ipmipowercap.MaximumPowerConsmp&0xFF)); + data[5]=((ipmipowercap.MaximumPowerConsmp&0xFF00)>>8); + data[6]=((ipmipowercap.MinimumPowerConsmp&0xFF)); + data[7]=((ipmipowercap.MinimumPowerConsmp&0xFF00)>>8); + data[8]=(uint8_t)(ipmipowercap.totalnumpowersupp); + data[9]=((ipmipowercap.AvailablePower&0xFF)); + data[10]=((ipmipowercap.AvailablePower&0xFF00)>>8); + data[11]=(uint8_t)(ipmipowercap.SystemThrottling); + data[12]=0x00; + + ipmipowercap.MaximumPowerConsmp = BSWAP_16(ipmipowercap.MaximumPowerConsmp); + ipmipowercap.MinimumPowerConsmp = BSWAP_16(ipmipowercap.MinimumPowerConsmp); + ipmipowercap.PowerCap = BSWAP_16(ipmipowercap.PowerCap); + if(unit==btuphr) + { + val = btuphr_to_watt_conversion(val); + + } + else if(unit ==percent) + { + if((val <0)||(val>100)) + { + lprintf(LOG_ERR, " Cap value is out of boundary conditon it should be between 0 - 100"); + return -1; + } + val =( (val*(ipmipowercap.MaximumPowerConsmp -ipmipowercap.MinimumPowerConsmp))/100)+ipmipowercap.MinimumPowerConsmp; + lprintf(LOG_ERR, " Cap value in percentage is %d ",val); + data[1] = (val&0XFF); + data[2] = ((val&0XFF00)>>8); + data[3] = watt; + } + if(((val<ipmipowercap.MinimumPowerConsmp)||(val>ipmipowercap.MaximumPowerConsmp))&&(unit==watt)) + { + lprintf(LOG_ERR, " Cap value is out of boundary conditon it should be between %d - %d", + ipmipowercap.MinimumPowerConsmp,ipmipowercap.MaximumPowerConsmp); + return -1; + } + else if(((val<ipmipowercap.MinimumPowerConsmp)||(val>ipmipowercap.MaximumPowerConsmp))&&(unit==btuphr)) + { + minpowerbtuphr= watt_to_btuphr_conversion(ipmipowercap.MinimumPowerConsmp); + maxpowerbtuphr=watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp); + maxpowerbtuphr1= watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp); + lprintf(LOG_ERR, " Cap value is out of boundary conditon it should be between %d", + minpowerbtuphr); + lprintf(LOG_ERR, " -%d", + maxpowerbtuphr1); + + return -1; + } + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error setting power cap: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + if (verbose > 1) + { + printf("CC for setpowercap :%d ",rv); + } + return 0; +} + +#ifdef NOT_USED +static int getpowersupplyfruinfo(void *intf, uint8_t id, + struct fru_header header, struct fru_info fru); +/***************************************************************** +* Function Name: getpowersupplyfruinfo +* +* Description: This function retrieves the FRU header +* Input: intf - ipmi interface +* header - watt / btuphr +* fru - FRU information +* Output: header - FRU header +* Return: +* +******************************************************************/ +static int getpowersupplyfruinfo(void *intf, uint8_t id, + struct fru_header header, struct fru_info fru) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[4]; + + memset(&fru, 0, sizeof(struct fru_info)); + memset(&header, 0, sizeof(struct fru_header)); + + /* + * get info about this FRU + */ + memset(msg_data, 0, 4); + msg_data[0] = id; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.lun = 0; + req.msg.cmd = GET_FRU_INFO; + req.msg.data = msg_data; + req.msg.data_len = 1; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Device not present, "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + fru.size = (rsp[1] << 8) | rsp[0]; + fru.access = rsp[2] & 0x1; + + lprintf(LOG_DEBUG, "fru.size = %d bytes (accessed by %s)", + fru.size, fru.access ? "words" : "bytes"); + + if (fru.size < 1) { + printf(" Invalid FRU size %d", fru.size); + return -1; + } + + /* + * retrieve the FRU header + */ + msg_data[0] = id; + msg_data[1] = 0; + msg_data[2] = 0; + msg_data[3] = 8; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.lun = 0; + req.msg.cmd = GET_FRU_DATA; + req.msg.data = msg_data; + req.msg.data_len = 4; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Device not present, "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + if (verbose > 1) + printbuf(rsp, rsp_len, "FRU DATA"); + + memcpy(&header, &rsp[1], 8); + + return 0; + + +} +#endif + +/***************************************************************** +* Function Name: ipmi_powermonitor_usage +* +* Description: This function prints help message for powermonitor command +* Input: +* Output: +* +* Return: +* +******************************************************************/ +static void +ipmi_powermonitor_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor"); + lprintf(LOG_NOTICE, " Shows power tracking statistics "); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor clear cumulativepower"); + lprintf(LOG_NOTICE, " Reset cumulative power reading"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor clear peakpower"); + lprintf(LOG_NOTICE, " Reset peak power reading"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor powerconsumption"); + lprintf(LOG_NOTICE, " Displays power consumption in <watt|btuphr>"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor powerconsumptionhistory <watt|btuphr>"); + lprintf(LOG_NOTICE, " Displays power consumption history "); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor getpowerbudget"); + lprintf(LOG_NOTICE, " Displays power cap in <watt|btuphr>"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor setpowerbudget <val><watt|btuphr|percent>"); + lprintf(LOG_NOTICE, " Allows user to set the power cap in <watt|BTU/hr|percentage>"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor enablepowercap "); + lprintf(LOG_NOTICE, " To enable set power cap"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor disablepowercap "); + lprintf(LOG_NOTICE, " To disable set power cap"); + lprintf(LOG_NOTICE, ""); + +} +/***************************************************************** +* Function Name: ipmi_delloem_vFlash_main +* +* Description: This function processes the delloem vFlash command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ + +static int ipmi_delloem_vFlash_main (void * intf, int argc, char ** argv) +{ + int rc = 0; + + current_arg++; + rc = ipmi_delloem_vFlash_process(intf, current_arg, argv); + return(rc); +} + + + +/***************************************************************** +* Function Name: get_vFlash_compcode_str +* +* Description: This function maps the vFlash completion code +* to a string +* Input : vFlash completion code and static array of codes vs strings +* Output: - +* Return: returns the mapped string +* +******************************************************************/ +const char * +get_vFlash_compcode_str(uint8_t vflashcompcode, const struct vFlashstr *vs) +{ + static char un_str[32]; + int i; + + for (i = 0; vs[i].str != NULL; i++) { + if (vs[i].val == vflashcompcode) + return vs[i].str; + } + + memset(un_str, 0, 32); + snprintf(un_str, 32, "Unknown (0x%02X)", vflashcompcode); + + return un_str; +} + +/***************************************************************** +* Function Name: ipmi_get_sd_card_info +* +* Description: This function prints the vFlash Extended SD card info +* Input : ipmi interface +* Output: prints the sd card extended info +* Return: 0 - success -1 - failure +* +******************************************************************/ +static int +ipmi_get_sd_card_info(void* intf) { + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[2]; + uint8_t input_length=0; + uint8_t cardstatus=0x00; + + IPMI_DELL_SDCARD_INFO * sdcardinfoblock; + + input_length = 2; + msg_data[0] = msg_data[1] = 0x00; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_EXT_SD_CARD_INFO; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting SD Card Extended info, "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + sdcardinfoblock = (IPMI_DELL_SDCARD_INFO *) (void *) rsp; + + if( (iDRAC_FLAG == IDRAC_12G) && (sdcardinfoblock->vflashcompcode == VFL_NOT_LICENSED)) + { + printf("FM001 : A required license is missing or expired\n"); + return -1; + } + else if (sdcardinfoblock->vflashcompcode != 0x00) + { + lprintf(LOG_ERR, " Error in getting SD Card Extended Information (%s) \n", get_vFlash_compcode_str(sdcardinfoblock->vflashcompcode, + vFlash_completion_code_vals)); + return -1; + } + + if (!(sdcardinfoblock->sdcardstatus & 0x04)) + { + lprintf(LOG_ERR, " vFlash SD card is unavailable, please insert the card\n of size 256MB or greater\n"); + return 0; + } + + printf("vFlash SD Card Properties\n"); + printf("SD Card size : %8dMB\n",sdcardinfoblock->sdcardsize); + printf("Available size : %8dMB\n",sdcardinfoblock->sdcardavailsize); + printf("Initialized : %10s\n", (sdcardinfoblock->sdcardstatus & 0x80) ? + "Yes" : "No"); + printf("Licensed : %10s\n", (sdcardinfoblock->sdcardstatus & 0x40) ? + "Yes" : "No"); + printf("Attached : %10s\n", (sdcardinfoblock->sdcardstatus & 0x20) ? + "Yes" : "No"); + printf("Enabled : %10s\n", (sdcardinfoblock->sdcardstatus & 0x10) ? + "Yes" : "No"); + printf("Write Protected : %10s\n", (sdcardinfoblock->sdcardstatus & 0x08) ? + "Yes" : "No"); + cardstatus = sdcardinfoblock->sdcardstatus & 0x03; + printf("Health : %10s\n", ((0x00 == cardstatus + ) ? "OK" : ((cardstatus == 0x03) ? + "Undefined" : ((cardstatus == 0x02) ? + "Critical" : "Warning")))); + printf("Bootable partition : %10d\n",sdcardinfoblock->bootpartion); + return 0; +} + +/***************************************************************** +* Function Name: ipmi_delloem_vFlash_process +* +* Description: This function processes the args for vFlash subcmd +* Input : intf - ipmi interface, arg index, argv array +* Output: prints help or error with help +* Return: 0 - Success -1 - failure +* +******************************************************************/ +static int +ipmi_delloem_vFlash_process(void* intf, int current_arg, char ** argv) +{ + int rc = 0; + int drv; + + drv = get_driver_type(); + if (drv != DRV_MV) /* MV open driver */ + { + lprintf(LOG_ERR, " vFlash support is enabled only for wmi and open interface.\n Its not enabled for lan and lanplus interface."); + return -1; + } + + if (argv[current_arg] == NULL || strcmp(argv[current_arg], "help") == 0) + { + ipmi_vFlash_usage(); + return 0; + } + ipmi_idracvalidator_command(intf); + if (!strncmp(argv[current_arg], "info\0", 5)) + { + current_arg++; + if (argv[current_arg] == NULL) + { + ipmi_vFlash_usage(); + return -1; + } + else if (strncmp(argv[current_arg], "Card\0", 5) == 0) + { + current_arg++; + if (argv[current_arg] != NULL) + { + ipmi_vFlash_usage(); + return -1; + } + rc = ipmi_get_sd_card_info(intf); + return rc; + } + else /* TBD: many sub commands are present */ + { + ipmi_vFlash_usage(); + return -1; + } + } + /* TBD other vFlash subcommands */ + else + { + ipmi_vFlash_usage(); + return -1; + } + return(rc); +} + +/***************************************************************** +* Function Name: ipmi_vFlash_usage +* +* Description: This function displays the usage for using vFlash +* Input : void +* Output: prints help +* Return: void +* +******************************************************************/ +static void +ipmi_vFlash_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " vFlash info Card"); + lprintf(LOG_NOTICE, " Shows Extended SD Card information"); + lprintf(LOG_NOTICE, ""); +} +/***************************************************************** +* Function Name: ipmi_delloem_windbg_main +* +* Description: This function processes the delloem windbg command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ + +static int ipmi_delloem_windbg_main (void * intf, int argc, char ** argv) +{ + int rc = 0; + + current_arg++; + if (argv[current_arg] == NULL) + { + ipmi_windbg_usage(); + return -1; + } + if (strncmp(argv[current_arg], "start\0", 6) == 0) + { + rc = ipmi_windbg_start(intf); + } + else if (strncmp(argv[current_arg], "end\0", 4) == 0) + { + rc = ipmi_windbg_end(intf); + } + else + { + ipmi_windbg_usage(); + } + return(rc); +} + +/***************************************************************** +* Function Name: ipmi_windbg_start +* +* Description: This function Starts the windbg +* Input : void +* Output: Start the debug +* Return: void +* +******************************************************************/ +static int +ipmi_windbg_start (void * intf) +{ + int rc; + lprintf(LOG_NOTICE, "Issuing sol activate"); + lprintf(LOG_NOTICE, ""); + + rc = ipmi_sol_activate(intf,0,0); + if (rc) lprintf(LOG_NOTICE, "Can not issue sol activate"); + else windbgsession = 1; + return(rc); +} + +/***************************************************************** +* Function Name: ipmi_windbg_end +* +* Description: This function ends the windbg +* Input : void +* Output: End the debug +* Return: void +* +******************************************************************/ + +static int +ipmi_windbg_end(void * intf) +{ + int rc; + lprintf(LOG_NOTICE, "Issuing sol deactivate"); + lprintf(LOG_NOTICE, ""); + rc = ipmi_sol_deactivate(intf); + if (rc) lprintf(LOG_NOTICE, "Can not issue sol deactivate"); + else windbgsession = 0; + return(rc); +} + + +/***************************************************************** +* Function Name: ipmi_windbg_usage +* +* Description: This function displays the usage for using windbg +* Input : void +* Output: prints help +* Return: void +* +******************************************************************/ + +static void +ipmi_windbg_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " windbg start"); + lprintf(LOG_NOTICE, " Starts the windbg session (Cold Reset & SOL Activation)"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " windbg end"); + lprintf(LOG_NOTICE, " Ends the windbg session (SOL Deactivation"); + lprintf(LOG_NOTICE, ""); +} + + + +/********************************************************************** +* Function Name: ipmi_setled_usage +* +* Description: This function prints help message for setled command +* Input: +* Output: +* +* Return: +* +***********************************************************************/ +static void +ipmi_setled_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " setled <b:d.f> <state..>"); + lprintf(LOG_NOTICE, " Set backplane LED state"); + lprintf(LOG_NOTICE, " b:d.f = PCI Bus:Device.Function of drive (lspci format)"); + lprintf(LOG_NOTICE, " state = present|online|hotspare|identify|rebuilding|"); + lprintf(LOG_NOTICE, " fault|predict|critical|failed"); + lprintf(LOG_NOTICE, ""); +} + +static void +ipmi_delloem_getled_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " getled "); + lprintf(LOG_NOTICE, " Get Chassis ID LED state"); + lprintf(LOG_NOTICE, ""); +} + +static int +IsSetLEDSupported(void) +{ + return SetLEDSupported; +} + +static int +CheckSetLEDSupport(void * intf) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[10]; + + SetLEDSupported = 0; + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = 0xD5; /* Storage */ + req.msg.data_len = sizeof(data); /*10*/ + req.msg.data = data; + + memset(data, 0, sizeof(data)); + data[0] = 0x01; // get + data[1] = 0x00; // subcmd:get firmware version + data[2] = 0x08; // length lsb + data[3] = 0x00; // length msb + data[4] = 0x00; // offset lsb + data[5] = 0x00; // offset msb + data[6] = 0x00; // bay id + data[7] = 0x00; + data[8] = 0x00; + data[9] = 0x00; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv == 0) SetLEDSupported = 1; + return(rv); +} + +/***************************************************************** +* Function Name: ipmi_getdrivemap +* +* Description: This function returns mapping of BDF to Bay:Slot +* Input: intf - ipmi interface +* bdf - PCI Address of drive +* *bay - Returns bay ID + *slot - Returns slot ID +* Output: +* +* Return: +* +******************************************************************/ +static int +ipmi_getdrivemap(void * intf, int b, int d, int f, int *bay, int *slot) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[8]; + + /* Get mapping of BDF to bay:slot */ + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = 0xD5; + req.msg.data_len = 8; + req.msg.data = data; + + memset(data, 0, sizeof(data)); + data[0] = 0x01; // get + data[1] = 0x07; // storage map + data[2] = 0x06; // length lsb + data[3] = 0x00; // length msb + data[4] = 0x00; // offset lsb + data[5] = 0x00; // offset msb + data[6] = b; // bus + data[7] = (d << 3) + f; // devfn + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error issuing getdrivemap command, "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", rv, decode_cc(0,rv)); + return rv; + } + + *bay = rsp[7]; + *slot = rsp[8]; + if (*bay == 0xFF || *slot == 0xFF) + { + lprintf(LOG_ERR, "Error could not get drive bay:slot mapping"); + return -1; + } + return 0; +} + +/***************************************************************** +* Function Name: ipmi_setled_state +* +* Description: This function updates the LED on the backplane +* Input: intf - ipmi interface +* bdf - PCI Address of drive +* state - SES Flags state of drive +* Output: +* +* Return: +* +******************************************************************/ +static int +ipmi_setled_state (void * intf, int bayId, int slotId, int state) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[20]; + + /* Issue Drive Status Update to bay:slot */ + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = 0xD5; + req.msg.data_len = 20; + req.msg.data = data; + + memset(data, 0, sizeof(data)); + data[0] = 0x00; // set + data[1] = 0x04; // set drive status + data[2] = 0x0e; // length lsb + data[3] = 0x00; // length msb + data[4] = 0x00; // offset lsb + data[5] = 0x00; // offset msb + data[6] = 0x0e; // length lsb + data[7] = 0x00; // length msb + data[8] = bayId; // bayid + data[9] = slotId; // slotid + data[10] = state & 0xff; // state LSB + data[11] = state >> 8; // state MSB; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error issuing setled command, "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", rv, decode_cc(0,rv)); + return rv; + } + + return 0; +} + +int ipmi_delloem_getled_state (void * intf, uint8_t *state) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t data[2]; + uint8_t led_state = 0; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_CHASSIS_LED_STATE; + req.msg.data_len = 0; + req.msg.data = data; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error issuing getled command, "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", rv, decode_cc(0,rv)); + } else { + led_state = rsp[0]; + } + *state = led_state; + return rv; +} + +/***************************************************************** +* Function Name: ipmi_getsesmask +* +* Description: This function calculates bits in SES drive update +* Return: Mask set with bits for SES backplane update +* +******************************************************************/ +static int ipmi_getsesmask(int argc, char **argv) +{ + int mask = 0; + //int idx; + + while (current_arg < argc) { + if (!strcmp(argv[current_arg], "present")) + mask |= (1L << 0); + if (!strcmp(argv[current_arg], "online")) + mask |= (1L << 1); + if (!strcmp(argv[current_arg], "hotspare")) + mask |= (1L << 2); + if (!strcmp(argv[current_arg], "identify")) + mask |= (1L << 3); + if (!strcmp(argv[current_arg], "rebuilding")) + mask |= (1L << 4); + if (!strcmp(argv[current_arg], "fault")) + mask |= (1L << 5); + if (!strcmp(argv[current_arg], "predict")) + mask |= (1L << 6); + if (!strcmp(argv[current_arg], "critical")) + mask |= (1L << 9); + if (!strcmp(argv[current_arg], "failed")) + mask |= (1L << 10); + current_arg++; + } + return mask; +} + +/***************************************************************** +* Function Name: ipmi_delloem_setled_main +* +* Description: This function processes the delloem setled command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ +static int +ipmi_delloem_setled_main(void * intf, int argc, char ** argv) +{ + int rc = -1; + int b,d,f, mask; + int bayId, slotId; + + bayId = 0xFF; + slotId = 0xFF; + + current_arg++; + if (argc < current_arg) + { + usage(); + return rc; + } + + /* ipmitool delloem setled info*/ + if (argc == 1 || strcmp(argv[current_arg], "help") == 0) + { + ipmi_setled_usage(); + return 0; + } + CheckSetLEDSupport (intf); + if (!IsSetLEDSupported()) + { + printf("'setled' is not supported on this system.\n"); + return rc; + } + else if (sscanf(argv[current_arg], "%*x:%x:%x.%x", &b,&d,&f) == 3) { + /* We have bus/dev/function of drive */ + current_arg++; + ipmi_getdrivemap (intf, b, d, f, &bayId, &slotId); + } + else if (sscanf(argv[current_arg], "%x:%x.%x", &b,&d,&f) == 3) { + /* We have bus/dev/function of drive */ + current_arg++; + } + else { + ipmi_setled_usage(); + return -1; + } + /* Get mask of SES flags */ + mask = ipmi_getsesmask(argc, argv); + + /* Get drive mapping */ + if (ipmi_getdrivemap (intf, b, d, f, &bayId, &slotId)) + return -1; + + /* Set drive LEDs */ + return ipmi_setled_state (intf, bayId, slotId, mask); +} + +static int +ipmi_delloem_getled_main(void * intf, int argc, char ** argv) +{ + int rc = 0; + uint8_t state; + + if (argc == 1 || strncmp(argv[0], "help\0", 5) == 0) + { + ipmi_delloem_getled_usage(); + return(0); + } else { + rc = ipmi_delloem_getled_state (intf, &state); + if (rc != 0) printf("getled_state error %d\n",rc); + else { + if (state == 0x01) + printf("Chassis ID LED Status = ON\n"); + else printf("Chassis ID LED Status = off\n"); + } + } + return (rc); +} + +/* + * decode_sensor_dell + * inputs: + * sdr = the SDR buffer + * reading = the 3 or 4 bytes of data from GetSensorReading + * pstring = points to the output string buffer + * slen = size of the output buffer + * outputs: + * rv = 0 if this sensor was successfully interpreted here, + * non-zero otherwise, to use default interpretations. + * pstring = contains the sensor reading interpretation string (if rv==0) + */ +int decode_sensor_dell(uchar *sdr,uchar *reading,char *pstring, int slen) +{ + int rv = -1; + uchar stype, evtype; + + if (sdr == NULL || reading == NULL) return(rv); + if (pstring == NULL || slen == 0) return(rv); + /* sdr[3] is SDR type: 1=full, 2=compact, 0xC0=oem */ + if (sdr[3] != 0x02) return(rv); /*return if not compact SDR */ + stype = sdr[12]; /*sensor type*/ + evtype = sdr[13]; /*event type */ + if (stype == 0x02) { /* Discrete Voltage */ + /* Dell Discrete Voltage is opposite from normal */ + if (evtype == 0x03) { /*oem interpretation */ + if (reading[2] & 0x01) strncpy(pstring,"OK",slen); + else strncpy(pstring,"Exceeded",slen); /*LimitExceeded*/ + rv = 0; + } + } + return(rv); +} + +#define BIT(x) (1 << x) +#define SIZE_OF_DESC 128 + +char * get_dell_evt_desc(uchar *sel_rec, int *psev) +{ + struct sel_event_record * rec = (struct sel_event_record *)sel_rec; + int data1, data2, data3; + int code; + char *desc = NULL; + + unsigned char count; + unsigned char node; + //unsigned char num; + unsigned char dimmNum; + unsigned char dimmsPerNode; + char dimmStr[32]; + //char cardStr[32]; + //char numStr[32]; + char tmpdesc[SIZE_OF_DESC]; + static char rgdesc[SIZE_OF_DESC]; + char* str; + unsigned char incr = 0; + unsigned char i = 0; + //unsigned char postCode; + // struct ipmi_rs *rsp; + // struct ipmi_rq req; + char tmpData; + int version; + // uint8_t devid[20]; /*usually 16 bytes*/ + uint8_t iver; + // int rv; + + 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]; + if ( (rec->sel_type.standard_type.event_type == 0x0B) || + (rec->sel_type.standard_type.event_type == 0x6F) || + (rec->sel_type.standard_type.event_type == 0x07)) + { + code = rec->sel_type.standard_type.sensor_type; + /* BDF or Slot */ + desc = rgdesc; + memset(desc,0,SIZE_OF_DESC); + switch (code) { + case 0x07: + if( ((data1 & DATA_BYTE2_SPECIFIED_MASK) == 0x80)) + { + *psev = SEV_CRIT; + if((data1 & 0x0f) == 0x00) + snprintf(desc,SIZE_OF_DESC,"CPU Internal Err | "); + if((data1 & 0x0f) == 0x06) + { + snprintf(desc,SIZE_OF_DESC,"CPU Protocol Err | "); + } + /* change bit location to a number */ + for (count= 0; count < 8; count++) + { + if (BIT(count)& data2) + { + count++; + if( ((data1 & 0x0f) == 0x06) && (rec->sel_type.standard_type.sensor_num == 0x0A)) + snprintf(desc,SIZE_OF_DESC,"FSB %d ",count); + else + snprintf(desc,SIZE_OF_DESC,"CPU %d | APIC ID %d ",count,data3); + break; + } + } + } + break; + case 0x0C: + if ( (rec->sel_type.standard_type.event_type == 0x0B) && + !(data1 & 0x03) ) + { + *psev = SEV_INFO; + if(data2 & 0x04) + strcpy(desc,"Memory is in Spare Mode"); + else if(data2 & 0x02) + strcpy(desc,"Memory is in Raid Mode "); + else if(data2 & 0x01) + strcpy(desc,"Memory is in Mirror Mode "); + break; + } + case 0x10: + get_devid_ver(NULL,NULL,&iver); + // rv = ipmi_getdeviceid(devid,sizeof(devid),fdbg); + // if (rv != 0) return NULL; + version = iver; + /* Memory DIMMS */ + *psev = SEV_MAJ; /*default severity for DIMM events*/ + if( (data1 & 0x80) || (data1 & 0x20 ) ) + { + if( (code == 0x0c) && (rec->sel_type.standard_type.event_type == 0x0B) ) + { + if((data1 & 0x0f) == 0x00) + { + snprintf(desc,SIZE_OF_DESC," Redundancy Regained | "); + *psev = SEV_INFO; + } + else if((data1 & 0x0f) == 0x01) + { + snprintf(desc,SIZE_OF_DESC,"Redundancy Lost | "); + *psev = SEV_MAJ; + } + } + else if(code == 0x0c) + { + if((data1 & 0x0f) == 0x00) + { + if(rec->sel_type.standard_type.sensor_num == 0x1C) + { + if((data1 & 0x80) && (data1 & 0x20 )) + { + count = 0; + snprintf(desc,SIZE_OF_DESC,"CRC Error on:"); + for(i=0;i<4;i++) + { + if((BIT(i))&(data2)) + { + if(count) + { + str = desc+strlen(desc); + *str++ = ','; + str = '\0'; + count = 0; + } + switch(i) + { + case 0: snprintf(tmpdesc,SIZE_OF_DESC,"South Bound Memory"); + strcat(desc,tmpdesc); + count++; + break; + case 1: snprintf(tmpdesc,SIZE_OF_DESC,"South Bound Config"); + strcat(desc,tmpdesc); + count++; + break; + case 2: snprintf(tmpdesc,SIZE_OF_DESC,"North Bound memory"); + strcat(desc,tmpdesc); + count++; + break; + case 3: snprintf(tmpdesc,SIZE_OF_DESC,"North Bound memory-corr"); + strcat(desc,tmpdesc); + count++; + break; + default: + break; + } + } + } + if(data3>=0x00 && data3<0xFF) + { + snprintf(tmpdesc,SIZE_OF_DESC,"|Failing_Channel:%d",data3); + strcat(desc,tmpdesc); + } + } + break; + } + snprintf(desc,SIZE_OF_DESC,"Correctable ECC | "); + *psev = SEV_MAJ; + } + else if((data1 & 0x0f) == 0x01) + { + snprintf(desc,SIZE_OF_DESC,"UnCorrectable ECC | "); + *psev = SEV_CRIT; + } + } + else if(code == 0x10) + { + if((data1 & 0x0f) == 0x00) { + snprintf(desc,SIZE_OF_DESC,"Corr Memory Log Disabled | "); + *psev = SEV_INFO; + } + } + } + else + { + if(code == 0x12) + { + if((data1 & 0x0f) == 0x02) { + snprintf(desc,SIZE_OF_DESC,"Unknown System Hardware Failure "); + *psev = SEV_MAJ; + } + } + if(code == 0x10) + { + if((data1 & 0x0f) == 0x03) { + snprintf(desc,SIZE_OF_DESC,"All Even Logging Dissabled"); + *psev = SEV_INFO; + } + } + } + if(data1 & 0x80 ) + { + if(((data2 >> 4) != 0x0f) && ((data2 >> 4) < 0x08)) + { + tmpData = ('A'+ (data2 >> 4)); + if( (code == 0x0c) && (rec->sel_type.standard_type.event_type == 0x0B) ) + { + snprintf(tmpdesc, SIZE_OF_DESC, "Bad Card %c", tmpData); + } + else + { + snprintf(tmpdesc, SIZE_OF_DESC, "Card %c", tmpData); + } + strcat(desc, tmpdesc); + } + if (0x0F != (data2 & 0x0f)) + { + if(0x51 == version) + { + snprintf(tmpdesc, SIZE_OF_DESC, "Bank %d", ((data2 & 0x0f)+1)); + strcat(desc, tmpdesc); + } + else + { + incr = (data2 & 0x0f) << 3; + } + } + + } + if(data1 & 0x20 ) + { + strcat(desc, "ECC Error,"); + if(0x51 == version) + { + snprintf(tmpdesc, SIZE_OF_DESC, "DIMM %c", (char)('A'+ data3)); + strcat(desc, tmpdesc); + } + else if( ((data2 >> 4) > 0x07) && ((data2 >> 4) != 0x0F)) + { + strcpy(dimmStr, " DIMM_"); + str = desc+strlen(desc); + dimmsPerNode = 4; + if( (data2 >> 4) == 0x09) dimmsPerNode = 6; + else if( (data2 >> 4) == 0x0A) dimmsPerNode = 8; + else if( (data2 >> 4) == 0x0B) dimmsPerNode = 9; + else if( (data2 >> 4) == 0x0C) dimmsPerNode = 12; + else if( (data2 >> 4) == 0x0D) dimmsPerNode = 24; + else if( (data2 >> 4) == 0x0E) dimmsPerNode = 3; + count = 0; + for (i = 0; i < 8; i++) + { + if (BIT(i) & data3) + { + if (count) + { + *str++ = ','; + count = 0; + } + node = (incr + i)/dimmsPerNode; + dimmNum = ((incr + i)%dimmsPerNode)+1; + dimmStr[6] = node + 'A'; + sprintf(tmpdesc,"%d",dimmNum); + dimmStr[7] = tmpdesc[0]; + dimmStr[8] = '\0'; + strcat(str,dimmStr); + count++; + } + } + } + else + { + strcpy(dimmStr, " DIMM"); + str = desc+strlen(desc); + count = 0; + for (i = 0; i < 8; i++) + { + if (BIT(i) & data3) + { + // check if more than one DIMM, if so add a comma to the string. + if (count) + { + *str++ = ','; + count = 0; + } + sprintf(tmpdesc,"%d",(i + incr + 1)); + dimmStr[5] = tmpdesc[0]; + dimmStr[6] = '\0'; + strcat(str, dimmStr); + count++; + } + } + } + } + break; + case 0x20: + if(((data1 & 0x0f)== 0x00)&&((data1 & 0x80) && (data1 & 0x20))) + { + *psev = SEV_MAJ; + if((data2 > 0x00)&&(data2<0xFF)) + { + //Add the code to display 194 entries.This sensor present only in ORCA + + } + switch(data3) + { + case 0x01: + snprintf(desc,SIZE_OF_DESC,"BIOS TXT Error"); + break; + case 0x02: + snprintf(desc,SIZE_OF_DESC,"Processor/FIT TXT"); + break; + case 0x03: + snprintf(desc,SIZE_OF_DESC,"BIOS ACM TXT Error"); + break; + case 0x04: + snprintf(desc,SIZE_OF_DESC,"SINIT ACM TXT Error"); + break; + case 0xff: + snprintf(desc,SIZE_OF_DESC,"Unrecognized TT Error12"); + break; + default: + break; + } + } + break; + case 0x23: + + if(data1 == 0xC1) + { + if(data2 == 0x04) + { + *psev = SEV_CRIT; + snprintf(desc,SIZE_OF_DESC,"Hard Reset|Interrupt type None,SMS/OS Timer used at expiration"); + } + } + + break; + case 0x2B: + if(((data1 & 0x0f)== 0x02)&&((data1 & 0x80) && (data1 & 0x20))) + { + if(data2 == 0x02) + { + *psev = SEV_MAJ; + if(data3 == 0x00) + { + snprintf(desc, SIZE_OF_DESC, "between BMC/iDRAC Firmware and other hardware"); + } + else if(data3 == 0x01) + { + snprintf(desc, SIZE_OF_DESC, "between BMC/iDRAC Firmware and CPU"); + } + } + } + break; + + case 0xC1: + if(rec->sel_type.standard_type.sensor_num == 0x25) + { + *psev = SEV_MAJ; + if((data1 & 0x0f) == 0x01) + { + snprintf(desc, SIZE_OF_DESC, "Failed to program Virtual Mac Address"); + if((data1 & 0x80)&&(data1 & 0x20)) + { + snprintf(tmpdesc, SIZE_OF_DESC, "PCI %.2x:%.2x.%x", + data3 &0x7f, (data2 >> 3) & 0x1F, + data2 & 0x7); + } + } + else if((data1 & 0x0f) == 0x02) + { + snprintf(desc, SIZE_OF_DESC, "Device option ROM failed to support link tuning or flex address"); + if((data1 & 0x80)&&(data1 & 0x20)) + { + //Add Mezzanine code here.DELLOEM SEL displayed unknown event + } + } + else if((data1 & 0x0f) == 0x03) + { + snprintf(desc, SIZE_OF_DESC, "Failed to get link tuning or flex address data from BMC/iDRAC"); + } + strcat(desc,tmpdesc); + } + break; + case 0x13: + case 0xC2: + case 0xC3: + if(rec->sel_type.standard_type.sensor_num == 0x29) + { + *psev = SEV_MAJ; + if(((data1 & 0x0f)== 0x02)&&((data1 & 0x80) && (data1 & 0x20))) + { + #if 1 /*This sensor is not implemented in iDRAC code*/ + snprintf(tmpdesc, SIZE_OF_DESC, "Partner-(LinkId:%d,AgentId:%d)|",(data2 & 0xC0),(data2 & 0x30)); + strcat(desc,tmpdesc); + snprintf(tmpdesc, SIZE_OF_DESC, "ReportingAgent(LinkId:%d,AgentId:%d)|",(data2 & 0x0C),(data2 & 0x03)); + strcat(desc,tmpdesc); + if((data3 & 0xFC) == 0x00) + { + snprintf(tmpdesc, SIZE_OF_DESC, "LinkWidthDegraded|"); + strcat(desc,tmpdesc); + } + if(BIT(1)& data3) + { + snprintf(tmpdesc,SIZE_OF_DESC,"PA_Type:IOH|"); + } + else + { + snprintf(tmpdesc,SIZE_OF_DESC,"PA-Type:CPU|"); + } + strcat(desc,tmpdesc); + if(BIT(0)& data3) + { + snprintf(tmpdesc,SIZE_OF_DESC,"RA-Type:IOH"); + } + else + { + snprintf(tmpdesc,SIZE_OF_DESC,"RA-Type:CPU"); + } + strcat(desc,tmpdesc); + #endif + *psev = SEV_MAJ; + } + } + else + { + *psev = SEV_MAJ; + if((data1 & 0x0f) == 0x02) + { + sprintf(desc,"%s","IO channel Check NMI"); + } + else + { + if((data1 & 0x0f) == 0x00) + { + snprintf(desc, SIZE_OF_DESC, "%s","PCIe Error |"); + } + else if((data1 & 0x0f) == 0x01) + { + snprintf(desc, SIZE_OF_DESC, "%s","I/O Error |"); + } + else if((data1 & 0x0f) == 0x04) + { + snprintf(desc, SIZE_OF_DESC, "%s","PCI PERR |"); + } + else if((data1 & 0x0f) == 0x05) + { + snprintf(desc, SIZE_OF_DESC, "%s","PCI SERR |"); + } + else + { + snprintf(desc, SIZE_OF_DESC, "%s"," "); + } + if (data3 & 0x80) + snprintf(tmpdesc, SIZE_OF_DESC, "Slot %d", data3 & 0x7f); + else + snprintf(tmpdesc, SIZE_OF_DESC, "PCI %.2x:%.2x.%x", + data3 &0x7f, (data2 >> 3) & 0x1F, + data2 & 0x7); + strcat(desc,tmpdesc); + } + *psev = SEV_CRIT; + } + break; + case 0x0F: + if(((data1 & 0x0f)== 0x0F)&&(data1 & 0x80)) + { + *psev = SEV_CRIT; + switch(data2) + { + case 0x80: + snprintf(desc, SIZE_OF_DESC, "No memory is detected.");break; + case 0x81: + snprintf(desc,SIZE_OF_DESC, "Memory is detected but is not configurable.");break; + case 0x82: + snprintf(desc, SIZE_OF_DESC, "Memory is configured but not usable.");break; + case 0x83: + snprintf(desc, SIZE_OF_DESC, "System BIOS shadow failed.");break; + case 0x84: + snprintf(desc, SIZE_OF_DESC, "CMOS failed.");break; + case 0x85: + snprintf(desc, SIZE_OF_DESC, "DMA controller failed.");break; + case 0x86: + snprintf(desc, SIZE_OF_DESC, "Interrupt controller failed.");break; + case 0x87: + snprintf(desc, SIZE_OF_DESC, "Timer refresh failed.");break; + case 0x88: + snprintf(desc, SIZE_OF_DESC, "Programmable interval timer error.");break; + case 0x89: + snprintf(desc, SIZE_OF_DESC, "Parity error.");break; + case 0x8A: + snprintf(desc, SIZE_OF_DESC, "SIO failed.");break; + case 0x8B: + snprintf(desc, SIZE_OF_DESC, "Keyboard controller failed.");break; + case 0x8C: + snprintf(desc, SIZE_OF_DESC, "System management interrupt initialization failed.");break; + case 0x8D: + snprintf(desc, SIZE_OF_DESC, "TXT-SX Error.");break; + case 0xC0: + snprintf(desc, SIZE_OF_DESC, "Shutdown test failed.");break; + case 0xC1: + snprintf(desc, SIZE_OF_DESC, "BIOS POST memory test failed.");break; + case 0xC2: + snprintf(desc, SIZE_OF_DESC, "RAC configuration failed.");break; + case 0xC3: + snprintf(desc, SIZE_OF_DESC, "CPU configuration failed.");break; + case 0xC4: + snprintf(desc, SIZE_OF_DESC, "Incorrect memory configuration.");break; + case 0xFE: + snprintf(desc, SIZE_OF_DESC, "General failure after video."); + break; + } + } + break; + + default: + break; + } + if (desc[0] == 0) { /* if no description specified above */ + /* snprintf(desc,SIZE_OF_DESC,"%02x [%02x %02x %02x]", + code,data1,date2,data3); // show raw data */ + desc = NULL; /*if empty, handle with default logic*/ + } + } + else + { + code = rec->sel_type.standard_type.event_type; + } + return desc; +} + +/* + * decode_sel_dell + * inputs: + * evt = the 16-byte IPMI SEL event + * outbuf = points to the output string buffer + * outsz = size of the output buffer + * outputs: + * rv = 0 if this event was successfully interpreted here, + * non-zero otherwise, to use default interpretations. + * outbuf = will contain the interpreted event text string (if rv==0) + */ +int decode_sel_dell(uint8_t *evt, char *outbuf, int outsz, char fdesc, + char fdbg) +{ + int rv = -1; + uint16_t id, genid; + uint8_t rectype; + uint32_t timestamp; + char *type_str = NULL; + char *gstr = NULL; + char *pstr = NULL; + int sevid; + uchar stype, snum; + + fdebug = fdbg; + sevid = SEV_INFO; + id = evt[0] + (evt[1] << 8); + rectype = evt[2]; + timestamp = evt[3] + (evt[4] << 8) + (evt[5] << 16) + (evt[6] << 24); + genid = evt[7] | (evt[8] << 8); + stype = evt[10]; + snum = evt[11]; + gstr = "BMC "; + if (genid == 0x0033) gstr = "Bios"; + +#ifdef OTHER + /* evt[13] is data1/offset*/ + if ( ((evt[13] & DATA_BYTE2_SPECIFIED_MASK) == 0x80) || + ((evt[13] & DATA_BYTE3_SPECIFIED_MASK) == 0x20) ) { + // if (evt[13] & DATA_BYTE2_SPECIFIED_MASK) + // evt->data = rec->sel_type.standard_type.event_data[1]; + pstr = get_dell_evt_desc(evt,&sevid); + } else if (evt[13] == 0xC1) { + if (snum == 0x23) { + // evt->data = rec->sel_type.standard_type.event_data[1]; + pstr = get_dell_evt_desc(evt,&sevid); + } + } +#endif + pstr = get_dell_evt_desc(evt,&sevid); + if (pstr != NULL) rv = 0; + + if (rv == 0) { + type_str = ""; + if (rectype == 0x02) type_str = get_sensor_type_desc(stype); + format_event(id,timestamp, sevid, genid, type_str, + snum,NULL,pstr,NULL,outbuf,outsz); + } + return rv; +} + +#ifdef METACOMMAND +int i_delloem(int argc, char **argv) +#else +#ifdef WIN32 +int __cdecl +#else +int +#endif +main(int argc, char **argv) +#endif +{ + int rv = 0; + uchar devrec[16]; + int c, i; + char *s1; + + printf("%s ver %s\n", progname,progver); + set_loglevel(LOG_NOTICE); + argc_sav = argc; + argv_sav = argv; + parse_lan_options('V',"4",0); /*default to admin priv*/ + + while ( (c = getopt( argc, argv,"m:s:xzEF:J:N:P:R:T:U:V:YZ:?")) != EOF ) + switch(c) { + case 'm': /* specific IPMB MC, 3-byte address, e.g. "409600" */ + g_bus = htoi(&optarg[0]); /*bus/channel*/ + g_sa = htoi(&optarg[2]); /*device slave address*/ + g_lun = htoi(&optarg[4]); /*LUN*/ + g_addrtype = ADDR_IPMB; + if (optarg[6] == 's') { + g_addrtype = ADDR_SMI; s1 = "SMI"; + } else { g_addrtype = ADDR_IPMB; s1 = "IPMB"; } + ipmi_set_mc(g_bus,g_sa,g_lun,g_addrtype); + printf("Use MC at %s bus=%x sa=%x lun=%x\n", + s1,g_bus,g_sa,g_lun); + break; + case 's': sdrfile = optarg; break; + case 'x': fdebug = 2; /* normal (dbglog if isol) */ + verbose = 1; + break; + case 'z': fdebug = 3; /*full debug (for isol)*/ + verbose = 1; + break; + case 'N': /* nodename */ + case 'U': /* remote username */ + case 'P': /* remote password */ + case 'R': /* remote password */ + case 'E': /* get password from IPMI_PASSWORD environment var */ + case 'F': /* force driver type */ + case 'T': /* auth type */ + case 'J': /* cipher suite */ + case 'V': /* priv level */ + case 'Y': /* prompt for remote password */ + case 'Z': /* set local MC address */ + parse_lan_options(c,optarg,fdebug); + break; + default: + usage(); + rv = ERR_USAGE; + goto do_exit; + break; + } + rv = ipmi_getdeviceid(devrec,16,fdebug); + if (rv == 0) { + char ipmi_maj, ipmi_min; + ipmi_maj = devrec[4] & 0x0f; + ipmi_min = devrec[4] >> 4; + // vend_id = devrec[6] + (devrec[7] << 8) + (devrec[8] << 16); + // prod_id = devrec[9] + (devrec[10] << 8); + show_devid( devrec[2], devrec[3], ipmi_maj, ipmi_min); + } + for (i = 0; i < optind; i++) { argv++; argc--; } + + rv = ipmi_delloem_main(NULL, argc, argv); + +do_exit: + ipmi_close_(); + return(rv); +} +/* end oem_dell.c */ diff --git a/util/oem_dell.c b/util/oem_dell.c index b474ee3..ae7a3d1 100644 --- a/util/oem_dell.c +++ b/util/oem_dell.c @@ -4,6 +4,7 @@ * * Change history: * 08/17/2011 ARCress - included in ipmiutil source tree + * 09/18/2024 ARCress - fix macos compile error with vFlashstr typedef * */ /****************************************************************** @@ -157,8 +158,14 @@ static uint8_t SetLEDSupported=0; volatile uint8_t IMC_Type = IMC_IDRAC_10G; +typedef struct +{ + int val; + char *str; +} vFlashstr; -const struct vFlashstr vFlash_completion_code_vals[] = { +// const struct vFlashstr vFlash_completion_code_vals[] = { +const vFlashstr vFlash_completion_code_vals[] = { {0x00, "SUCCESS"}, {0x01, "NO_SD_CARD"}, {0x63, "UNKNOWN_ERROR"}, @@ -250,7 +257,8 @@ static void ipmi_powermonitor_usage(void); /* vFlash Function prototypes */ static int ipmi_delloem_vFlash_main(void * intf, int argc, char ** argv); -const char * get_vFlash_compcode_str(uint8_t vflashcompcode, const struct vFlashstr *vs); +// const char * get_vFlash_compcode_str(uint8_t vflashcompcode, const struct vFlashstr *vs); +const char * get_vFlash_compcode_str(uint8_t vflashcompcode, const vFlashstr *vs); static int ipmi_get_sd_card_info(void* intf); static int ipmi_delloem_vFlash_process(void* intf, int current_arg, char ** argv); static void ipmi_vFlash_usage(void); @@ -4818,7 +4826,8 @@ static int ipmi_delloem_vFlash_main (void * intf, int argc, char ** argv) * ******************************************************************/ const char * -get_vFlash_compcode_str(uint8_t vflashcompcode, const struct vFlashstr *vs) +// get_vFlash_compcode_str(uint8_t vflashcompcode, const struct vFlashstr *vs) +get_vFlash_compcode_str(uint8_t vflashcompcode, const vFlashstr *vs) { static char un_str[32]; int i; |