summaryrefslogtreecommitdiff
path: root/usr/src/lib/libfru
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/lib/libfru
downloadillumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/lib/libfru')
-rw-r--r--usr/src/lib/libfru/Makefile74
-rw-r--r--usr/src/lib/libfru/Makefile.flag63
-rw-r--r--usr/src/lib/libfru/Makefile.obj68
-rw-r--r--usr/src/lib/libfru/Makefile.targ60
-rw-r--r--usr/src/lib/libfru/include/Str.h87
-rw-r--r--usr/src/lib/libfru/include/libfru.h266
-rw-r--r--usr/src/lib/libfru/include/libfruds.h102
-rw-r--r--usr/src/lib/libfru/include/libfrup.h86
-rw-r--r--usr/src/lib/libfru/include/libfrureg.h66
-rw-r--r--usr/src/lib/libfru/libfru/Ancestor.cc263
-rw-r--r--usr/src/lib/libfru/libfru/Ancestor.h105
-rw-r--r--usr/src/lib/libfru/libfru/Parser.cc104
-rw-r--r--usr/src/lib/libfru/libfru/Parser.h71
-rw-r--r--usr/src/lib/libfru/libfru/PayloadReader.cc557
-rw-r--r--usr/src/lib/libfru/libfru/PayloadReader.h102
-rw-r--r--usr/src/lib/libfru/libfru/libfru.cc2231
-rw-r--r--usr/src/lib/libfru/libfru/nameSyntaxLex.l64
-rw-r--r--usr/src/lib/libfru/libfru/nameSyntaxYacc.y184
-rw-r--r--usr/src/lib/libfru/libfru/yy-lsed63
-rw-r--r--usr/src/lib/libfru/libfru/yy-sed53
-rw-r--r--usr/src/lib/libfru/libfrupicl/Makefile68
-rw-r--r--usr/src/lib/libfru/libfrupicl/Makefile.com94
-rw-r--r--usr/src/lib/libfru/libfrupicl/frupicl.c1180
-rw-r--r--usr/src/lib/libfru/libfrupicl/sparc/Makefile47
-rw-r--r--usr/src/lib/libfru/libfrupicl/sparcv9/Makefile48
-rw-r--r--usr/src/lib/libfru/libfrupicltree/Makefile69
-rw-r--r--usr/src/lib/libfru/libfrupicltree/Makefile.com92
-rw-r--r--usr/src/lib/libfru/libfrupicltree/frupicltree.c1187
-rw-r--r--usr/src/lib/libfru/libfrupicltree/sparc/Makefile49
-rw-r--r--usr/src/lib/libfru/libfrureg/Makefile68
-rw-r--r--usr/src/lib/libfru/libfrureg/Makefile.com96
-rw-r--r--usr/src/lib/libfru/libfrureg/frudefs.c10563
-rw-r--r--usr/src/lib/libfru/libfrureg/frureg.c88
-rw-r--r--usr/src/lib/libfru/libfrureg/sparc/Makefile49
-rw-r--r--usr/src/lib/libfru/libfrureg/sparcv9/Makefile50
-rw-r--r--usr/src/lib/libfru/libgenutil/Str.cc198
-rw-r--r--usr/src/lib/libfru/sparc/Makefile45
-rw-r--r--usr/src/lib/libfru/sparcv9/Makefile44
38 files changed, 18704 insertions, 0 deletions
diff --git a/usr/src/lib/libfru/Makefile b/usr/src/lib/libfru/Makefile
new file mode 100644
index 0000000000..01995e26bd
--- /dev/null
+++ b/usr/src/lib/libfru/Makefile
@@ -0,0 +1,74 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+# lib/libfru/Makefile
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+
+include $(SRC)/lib/Makefile.lib
+
+SUBDIRS = libfrureg $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+SUBDIRS += .WAIT libfrupicl libfrupicltree
+
+# conditional assignments
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+lint := TARGET= lint
+_msg := TARGET= _msg
+
+POFILE= libfru.po
+
+.KEEP_STATE:
+
+all install clean clobber lint: $(SUBDIRS)
+
+_msg: $(MSGDOMAIN) $(POFILE)
+ $(RM) $(MSGDOMAIN)/$(POFILE)
+ $(CP) $(POFILE) $(MSGDOMAIN)
+
+$(POFILE):
+ $(RM) $@ messages.po
+ $(XGETTEXT) $(XGETFLAGS) *.[ch]* */*.[ch]*
+ $(SED) -e '/^# msg/d' -e '/^domain/d' messages.po > $@
+ $(RM) messages.po
+
+$(MSGDOMAIN):
+ $(INS.dir)
+
+clobber: po_clean
+
+po_clean:
+ $(RM) $(POFILE)
+
+check: $(CHECKHDRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
diff --git a/usr/src/lib/libfru/Makefile.flag b/usr/src/lib/libfru/Makefile.flag
new file mode 100644
index 0000000000..4354aaa059
--- /dev/null
+++ b/usr/src/lib/libfru/Makefile.flag
@@ -0,0 +1,63 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libfru/Makefile.flag
+#
+
+LINTFLAGS = -uxn
+LINTFLAGS64 = $(LINTFLAGS) -Xarch=$(MACH64:sparcv9=v9)
+LINTOUT= lint.out
+LINTSRC = $(LINTLIB:%.ln=%)
+ROOTLINTDIR = $(ROOTLIBDIR)
+ROOTLINT = $(LINTSRC:%=$(ROOTLINTDIR)/%)
+
+CPPFLAGS += -I../include -I$(SRC)/lib/libpicl
+CPPFLAGS += -I$(SRC)/lib/libfruutils
+CPPFLAGS += -I$(SRC)/cmd/picl/plugins/inc
+CPPFLAGS += -D_REENTRANT
+CFLAGS += $(CCVERBOSE)
+CCFLAGS64 += -mt
+CCFLAGS += -mt
+LDLIBS += -lc
+
+CLEANFILES += pics/lex.fru.cc pics/y.tab.cc pics/y.tab.h
+
+$(LINTLIB) := SRCS = ../llib-lfru
+$(LINTLIB) := LINTFLAGS = -nvx -I../include
+$(LINTLIB) := LINTFLAGS64 = -nvx -Xarch=$(MACH64:sparcv9=v9) -I../include
+
+CLOBBERFILES += $(DYNLIBCCC) libfru.so
+
+.KEEP_STATE:
+
+all : pics .WAIT $(DYNLIBCCC)
+ $(RM) libfru.so
+ $(LN) $(DYNLIBCCC) libfru.so
+ $(CHMOD) 755 libfru.so
+
+lint :
+ @ $(ECHO) "No C code here, only C++ code: skipping"
diff --git a/usr/src/lib/libfru/Makefile.obj b/usr/src/lib/libfru/Makefile.obj
new file mode 100644
index 0000000000..0eac420b35
--- /dev/null
+++ b/usr/src/lib/libfru/Makefile.obj
@@ -0,0 +1,68 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libfru/Makefile.obj
+#
+
+#
+# define all the common stuff here for all the different platforms we are
+# building on.
+#
+
+LIBRARYCCC= libfru.a
+VERS= .1
+
+SED= sed
+
+MAINOBJS= Parser.o \
+ PayloadReader.o \
+ libfru.o \
+ Ancestor.o
+
+YACCOBJS= nameSyntaxYacc.o
+LEXOBJS= nameSyntaxLex.o
+
+GENUTOBJS= Str.o
+
+OBJECTS= $(MAINOBJS) \
+ $(YACCOBJS) \
+ $(LEXOBJS) \
+ $(GENUTOBJS)
+
+MAINSRCS= $(MAINOBJS:%.o=./libfru/%.cc)
+YACCSRCS= $(YACCOBJS:%.o=./libfru/%.y)
+LEXSRCS= $(LEXOBJS:%.o=./libfru/%.l)
+GENUTSRCS= $(GENUTOBJS:%.o=./libgenutil/%.cc)
+
+SRCS= $(MAINSRCS) \
+ $(YACCSRCS) \
+ $(LEXSRCS) \
+ $(GENUTSRCS)
+
+# include common Makefiles
+include ../../Makefile.lib
+
diff --git a/usr/src/lib/libfru/Makefile.targ b/usr/src/lib/libfru/Makefile.targ
new file mode 100644
index 0000000000..709e1a8159
--- /dev/null
+++ b/usr/src/lib/libfru/Makefile.targ
@@ -0,0 +1,60 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2000 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libfru/Makefile.targ
+#
+
+include ../../Makefile.targ
+
+# build rules for pics. (access sub directories)
+pics/%.o objs/%.o: ../libfru/%.cc
+ $(COMPILE.cc) -o $@ $<
+ $(POST_PROCESS_O)
+
+pics/%.o objs/%.o: ../libfrureg/%.cc
+ $(COMPILE.cc) -o $@ $<
+ $(POST_PROCESS_O)
+
+pics/%.o objs/%.o: ../libgenutil/%.cc
+ $(COMPILE.cc) -o $@ $<
+ $(POST_PROCESS_O)
+
+# some special rules for the yacc and lex parser. (with sub directories)
+pics/y.tab.cc pics/y.tab.h: ../libfru/nameSyntaxYacc.y
+ $(YACC.y) -d ../libfru/nameSyntaxYacc.y
+ $(SED) -f ../libfru/yy-sed y.tab.c > pics/y.tab.cc
+ $(SED) -f ../libfru/yy-sed y.tab.h > pics/y.tab.h
+ $(RM) y.tab.c y.tab.h
+
+pics/nameSyntaxYacc.o: pics/y.tab.cc
+ $(COMPILE.cc) -I../libfru -Ipics -o $@ pics/y.tab.cc
+
+pics/nameSyntaxLex.o: ../libfru/nameSyntaxLex.l pics/y.tab.h
+ $(LEX.l) ../libfru/nameSyntaxLex.l | \
+ $(SED) -f ../libfru/yy-lsed > pics/lex.fru.cc
+ $(COMPILE.cc) -I../libfru -Ipics -o $@ pics/lex.fru.cc
+
diff --git a/usr/src/lib/libfru/include/Str.h b/usr/src/lib/libfru/include/Str.h
new file mode 100644
index 0000000000..acf1cfaa23
--- /dev/null
+++ b/usr/src/lib/libfru/include/Str.h
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2000 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _STR_H
+#define _STR_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+struct Str
+{
+ Str();
+ Str(const char *str);
+ Str(const char *str, int len);
+ Str(const Str& rhs);
+ virtual ~Str();
+
+ void operator=(const Str& rhs);
+ void operator=(const char *str);
+
+ int operator != (const Str& rhs) const;
+ int operator == (const Str& rhs) const;
+
+ char& operator[](int index) const;
+ Str& operator<<(Str rhs);
+ Str& operator<<(long long i);
+ Str& operator<<(long i);
+ Str& operator<<(int i);
+ Str& operator<<(char c);
+
+ // normal "C" strcmp
+ int compare(const Str& rhs) const;
+
+ int length(void) const;
+
+ // returns character found or 0x00 if nothing found.
+ char tokenize(Str& token, const Str& separators, Str& remainder);
+ void resetToken(void);
+
+ const char *peak(void) const;
+
+ void replaceAll(char c, char newc);
+
+private:
+ char *str_;
+ char *nextTok_;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STR_H */
diff --git a/usr/src/lib/libfru/include/libfru.h b/usr/src/lib/libfru/include/libfru.h
new file mode 100644
index 0000000000..bba6640b9f
--- /dev/null
+++ b/usr/src/lib/libfru/include/libfru.h
@@ -0,0 +1,266 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBFRU_H
+#define _LIBFRU_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+
+#define LIBFRU_VERSION 1
+
+/* fru errno return types */
+typedef enum
+{
+ FRU_SUCCESS = 0,
+ FRU_NODENOTFOUND,
+ FRU_IOERROR,
+ FRU_NOREGDEF,
+ FRU_NOTCONTAINER,
+ FRU_INVALHANDLE,
+ FRU_INVALSEG,
+ FRU_INVALPATH,
+ FRU_INVALELEMENT,
+ FRU_INVALDATASIZE,
+ FRU_DUPSEG,
+ FRU_NOTFIELD,
+ FRU_NOSPACE,
+ FRU_DATANOTFOUND,
+ FRU_ITERFULL,
+ FRU_INVALPERM,
+ FRU_NOTSUP,
+ FRU_ELEMNOTTAGGED,
+ FRU_CONTFAILED,
+ FRU_SEGCORRUPT,
+ FRU_DATACORRUPT,
+ FRU_FAILURE,
+ FRU_WALK_TERMINATE
+
+} fru_errno_t;
+
+/*
+ * Structures for libfru.c
+ */
+
+/* Fru Display Types */
+typedef enum { FDISP_Binary = 0, FDISP_Octal, FDISP_Hex, FDISP_Decimal,
+ FDISP_String, FDISP_Time, FDISP_UNDEFINED
+} fru_displaytype_t;
+
+/* Fru Data Types */
+typedef enum { FDTYPE_Binary = 0, FDTYPE_ByteArray, FDTYPE_ASCII,
+ FDTYPE_Unicode, FDTYPE_Record, FDTYPE_Enumeration,
+ FDTYPE_UNDEFINED
+} fru_datatype_t;
+
+/* Fru Which Type */
+typedef enum { FRU_No = 0, FRU_Yes, FRU_WHICH_UNDEFINED } fru_which_t;
+
+/* Fru Iteration Types */
+typedef enum { FRU_FIFO = 0, FRU_Circular,
+ FRU_Linear, FRU_LIFO, FRU_NOT_ITERATED } fru_itertype_t;
+
+/* Fru Handle Type */
+typedef uint64_t fru_nodehdl_t;
+
+/* Node Types */
+typedef enum
+{
+ FRU_NODE_UNKNOWN,
+ FRU_NODE_LOCATION,
+ FRU_NODE_FRU,
+ FRU_NODE_CONTAINER
+} fru_node_t;
+
+/* Sting list */
+typedef struct {
+ unsigned int num;
+ char **strs;
+} fru_strlist_t;
+
+typedef union
+{
+ uint32_t raw_data;
+ struct
+ {
+ unsigned encrypted : 1;
+ unsigned ignore_checksum : 1;
+ unsigned opaque : 1;
+ unsigned fixed : 1;
+ unsigned unused : 13;
+ unsigned field_perm : 3;
+ unsigned domain_perm : 3;
+ unsigned operations_perm : 3;
+ unsigned engineering_perm : 3;
+ unsigned repair_perm : 3;
+ } field;
+} fru_segdesc_t;
+
+#define FRU_SEGDESC_PERM_DELETE_MASK (1<<0)
+#define FRU_SEGDESC_PERM_WRITE_MASK (1<<1)
+#define FRU_SEGDESC_PERM_READ_MASK (1<<2)
+#define FRU_SEGDESC_PERM_RW_MASK ((1<<2) | (1<<1))
+#define FRU_SEGDESC_PERM_RD_MASK ((1<<2) | (1<<0))
+#define FRU_SEGDESC_PERM_WD_MASK ((1<<1) | (1<<0))
+#define FRU_SEGDESC_PERM_RWD_MASK ((1<<0) | (1<<1) | (1<<2))
+
+#define FRU_SEGDESC_ALL_RO_MASK 0x000036db
+
+#define FRU_SEGDESC_FIXED_MASK (1<<28)
+#define FRU_SEGDESC_OPAQUE_MASK (1<<29)
+#define FRU_SEGDESC_IGNORECHECKSUM_MASK (1<<30)
+#define FRU_SEGDESC_ENCRYPTED_MASK (1<<31)
+
+/* segment descriptor field perm. */
+#define SEGMENT_READ 4
+#define SEGMENT_WRITE 2
+#define SEGMENT_DELETE 1
+
+typedef union
+{
+ uint32_t all_bits;
+ struct
+ {
+ uint32_t read_only : 1;
+ unsigned : 7;
+ unsigned : 8;
+ unsigned : 8;
+ unsigned : 8;
+ } field;
+} fru_seg_hwdesc_t;
+
+#define FRU_SEGNAMELEN 2
+typedef struct {
+ uint32_t version;
+ char name[FRU_SEGNAMELEN + 1]; /* +1 to include '\0' byte. */
+ fru_segdesc_t desc;
+ uint32_t size;
+ uint32_t address; /* used for fixed segments (0 otherwise) */
+ fru_seg_hwdesc_t hw_desc;
+} fru_segdef_t;
+
+/* Fru enumerations */
+typedef struct {
+ uint64_t value;
+ char *text;
+} fru_enum_t;
+
+/* Element/Field level operations */
+#define FRU_ELEMDEF_REV 1
+typedef struct {
+ uint32_t version;
+ fru_datatype_t data_type;
+ fru_which_t tagged;
+ size_t data_length; /* in Bytes or Bits depending on data_type */
+ fru_displaytype_t disp_type;
+ fru_which_t purgeable;
+ fru_which_t relocatable;
+ unsigned int enum_count; /* number of enum values in table */
+ fru_enum_t *enum_table; /* enum strings or sub-elements depending on */
+ /* the data_type */
+ unsigned int iteration_count;
+ fru_itertype_t iteration_type;
+ char *example_string;
+} fru_elemdef_t;
+
+/* Data Source operations */
+fru_errno_t fru_open_data_source(const char *name, ...);
+fru_errno_t fru_close_data_source(void);
+
+/* Tree operations */
+fru_errno_t fru_get_root(fru_nodehdl_t *handle);
+fru_errno_t fru_get_child(fru_nodehdl_t handle, fru_nodehdl_t *child);
+fru_errno_t fru_get_peer(fru_nodehdl_t handle, fru_nodehdl_t *peer);
+fru_errno_t fru_get_parent(fru_nodehdl_t handle, fru_nodehdl_t *parent);
+
+/* Node information functions */
+fru_errno_t fru_get_name_from_hdl(fru_nodehdl_t handle, char **name);
+fru_errno_t fru_get_node_type(fru_nodehdl_t handle, fru_node_t *type);
+
+/* Segment Operations */
+fru_errno_t fru_list_segments(fru_nodehdl_t container, fru_strlist_t *list);
+fru_errno_t fru_create_segment(fru_nodehdl_t container, fru_segdef_t *def);
+fru_errno_t fru_remove_segment(fru_nodehdl_t container, const char *seg_name);
+fru_errno_t fru_get_segment_def(fru_nodehdl_t container, const char *seg_name,
+ fru_segdef_t *definition);
+fru_errno_t fru_list_elems_in(fru_nodehdl_t container, const char *seg_name,
+ fru_strlist_t *list);
+
+/* Data operations */
+fru_errno_t fru_read_field(fru_nodehdl_t container,
+ char **seg_name, /* IN/OUT */
+ unsigned int instance,
+ const char *field_path,
+ void **data,
+ size_t *data_len,
+ char **found_path);
+fru_errno_t fru_update_field(fru_nodehdl_t container,
+ char *seg_name,
+ unsigned int instance,
+ const char *field_path,
+ void *data,
+ size_t length);
+fru_errno_t fru_get_num_iterations(fru_nodehdl_t container,
+ char **seg_name, /* IN/OUT */
+ unsigned int instance,
+ const char *iter_path,
+ int *num_there,
+ char **found_path);
+
+/* Tagged Element operations */
+fru_errno_t fru_add_element(fru_nodehdl_t container, const char *seg_name,
+ const char *element);
+fru_errno_t fru_delete_element(fru_nodehdl_t container, const char *seg_name,
+ unsigned int instance, const char *element);
+
+/* General library support */
+fru_errno_t fru_get_definition(const char *element_name,
+ fru_elemdef_t *definition);
+fru_errno_t fru_get_registry(fru_strlist_t *list);
+fru_errno_t fru_get_tagged_parents(const char *elem_name,
+ fru_strlist_t *parents);
+
+/* Structure destroy functions */
+fru_errno_t fru_destroy_strlist(fru_strlist_t *list);
+fru_errno_t fru_destroy_elemdef(fru_elemdef_t *def);
+
+/* Enum to String Conversions */
+const char *fru_strerror(fru_errno_t errnum);
+const char *get_displaytype_str(fru_displaytype_t e);
+const char *get_datatype_str(fru_datatype_t e);
+const char *get_which_str(fru_which_t e);
+const char *get_itertype_str(fru_itertype_t e);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBFRU_H */
diff --git a/usr/src/lib/libfru/include/libfruds.h b/usr/src/lib/libfru/include/libfruds.h
new file mode 100644
index 0000000000..40cf1087fa
--- /dev/null
+++ b/usr/src/lib/libfru/include/libfruds.h
@@ -0,0 +1,102 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBFRUDS_H
+#define _LIBFRUDS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdarg.h>
+
+#include "libfru.h"
+#include "fru_tag.h"
+
+#define LIBFRU_DS_VER 1
+
+/* Tree handle specific to the datasource */
+typedef uint64_t fru_treehdl_t;
+typedef uint64_t fru_treeseghdl_t;
+
+typedef struct
+{
+ int version;
+
+/* init */
+fru_errno_t (*initialize)(int argc, char **argv);
+fru_errno_t (*shutdown)(void);
+
+/* Tree ops */
+fru_errno_t (*get_root)(fru_treehdl_t *root);
+fru_errno_t (*get_child)(fru_treehdl_t parent, fru_treehdl_t *child);
+fru_errno_t (*get_peer)(fru_treehdl_t sibling, fru_treehdl_t *peer);
+fru_errno_t (*get_parent)(fru_treehdl_t child, fru_treehdl_t *parent);
+
+/* Node ops */
+fru_errno_t (*get_name_from_hdl)(fru_treehdl_t node, char **name);
+fru_errno_t (*get_node_type)(fru_treehdl_t node, fru_node_t *type);
+
+/* Segment ops */
+fru_errno_t (*get_seg_list)(fru_treehdl_t container, fru_strlist_t *list);
+fru_errno_t (*get_seg_def)(fru_treehdl_t container, const char *seg_name,
+ fru_segdef_t *def);
+fru_errno_t (*add_seg)(fru_treehdl_t container, fru_segdef_t *def);
+fru_errno_t (*delete_seg)(fru_treehdl_t container, const char *seg_name);
+fru_errno_t (*for_each_segment)(fru_treehdl_t node,
+ int (*function)(fru_treeseghdl_t segment,
+ void *args),
+ void *args);
+fru_errno_t (*get_segment_name)(fru_treeseghdl_t segment, char **name);
+
+/* Tag ops */
+fru_errno_t (*add_tag_to_seg)(fru_treehdl_t container, const char *seg_name,
+ fru_tag_t tag, uint8_t *data, size_t data_len);
+fru_errno_t (*get_tag_list)(fru_treehdl_t container, const char *seg_name,
+ fru_tag_t **tags, int *number);
+fru_errno_t (*get_tag_data)(fru_treehdl_t container, const char *seg_name,
+ fru_tag_t tag, int instance,
+ uint8_t **data, size_t *data_len);
+fru_errno_t (*set_tag_data)(fru_treehdl_t container, const char *seg_name,
+ fru_tag_t tag, int instance,
+ uint8_t *data, size_t data_len);
+fru_errno_t (*delete_tag)(fru_treehdl_t container, const char *seg_name,
+ fru_tag_t tag, int instance);
+fru_errno_t (*for_each_packet)(fru_treeseghdl_t segment,
+ int (*function)(fru_tag_t *tag,
+ uint8_t *payload,
+ size_t length, void *args),
+ void *args);
+
+} fru_datasource_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBFRUDS_H */
diff --git a/usr/src/lib/libfru/include/libfrup.h b/usr/src/lib/libfru/include/libfrup.h
new file mode 100644
index 0000000000..a7634f86eb
--- /dev/null
+++ b/usr/src/lib/libfru/include/libfrup.h
@@ -0,0 +1,86 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBFRUP_H
+#define _LIBFRUP_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdarg.h>
+
+#include "libfru.h"
+#include "../../libfruutils/fru_tag.h"
+
+typedef uint64_t fru_seghdl_t;
+typedef enum {FRU_ENCRYPT, FRU_DECRYPT} fru_encrypt_t;
+typedef fru_errno_t
+(*fru_encrypt_func_t)(fru_encrypt_t en_dec, unsigned char *buf, size_t buf_len);
+
+/*
+ * Type for pointers to functions for terminating the processing of a node
+ * (after its children have been processed)
+ */
+typedef void (*end_node_fp_t)(fru_nodehdl_t node, const char *path,
+ const char *name, void *args);
+
+/*
+ * Project-private exported symbols
+ */
+fru_encrypt_func_t encrypt_func;
+
+fru_errno_t fru_encryption_supported(void);
+
+fru_errno_t
+fru_walk_tree(fru_nodehdl_t node, const char *prior_path,
+ fru_errno_t (*process_node)(fru_nodehdl_t node,
+ const char *path,
+ const char *name, void *args,
+ end_node_fp_t *end_node,
+ void **end_args),
+ void *args);
+
+int fru_pathmatch(const char *path, const char *searchpath);
+
+fru_errno_t fru_for_each_segment(fru_nodehdl_t node,
+ int (*function)(fru_seghdl_t segment,
+ void *args),
+ void *args);
+fru_errno_t fru_get_segment_name(fru_seghdl_t segment, char **name);
+fru_errno_t fru_for_each_packet(fru_seghdl_t segment,
+ int (*function)(fru_tag_t *tag,
+ uint8_t *payload,
+ size_t length, void *args),
+ void *args);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBFRUP_H */
diff --git a/usr/src/lib/libfru/include/libfrureg.h b/usr/src/lib/libfru/include/libfrureg.h
new file mode 100644
index 0000000000..91e0844891
--- /dev/null
+++ b/usr/src/lib/libfru/include/libfrureg.h
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _LIBFRUREG_H
+#define _LIBFRUREG_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "libfru.h"
+#include "fru_tag.h"
+
+#define REGDEF_VERSION 1
+typedef struct {
+ int version;
+ const char *name;
+ fru_tagtype_t tagType;
+ int tagDense;
+ int payloadLen;
+ int dataLength;
+ fru_datatype_t dataType;
+ fru_displaytype_t dispType;
+ fru_which_t purgeable;
+ fru_which_t relocatable;
+ int enumCount;
+ fru_enum_t *enumTable;
+ int iterationCount;
+ fru_itertype_t iterationType;
+ const char *exampleString;
+} fru_regdef_t;
+
+extern const fru_regdef_t *fru_reg_lookup_def_by_name(const char *elem_name);
+extern const fru_regdef_t *fru_reg_lookup_def_by_tag(fru_tag_t tag);
+extern char **fru_reg_list_entries(unsigned int *num);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBFRUREG_H */
diff --git a/usr/src/lib/libfru/libfru/Ancestor.cc b/usr/src/lib/libfru/libfru/Ancestor.cc
new file mode 100644
index 0000000000..25032bb14d
--- /dev/null
+++ b/usr/src/lib/libfru/libfru/Ancestor.cc
@@ -0,0 +1,263 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "Ancestor.h"
+
+/* ========================================================================= */
+/* Ancestor object definitions. */
+
+Ancestor::Ancestor(Str field, fru_tag_t t, const fru_regdef_t *d)
+ : field_name(field),
+ tag(t),
+ def(d),
+ numInstances(0),
+ numBufs(1),
+ next(NULL)
+{
+ offsets = (uint32_t *)malloc(sizeof (uint32_t)
+ * ANCESTOR_INST_BUF_SIZE);
+ paths = (char **)malloc(sizeof (char *)
+ * ANCESTOR_INST_BUF_SIZE);
+}
+
+Ancestor::~Ancestor()
+{
+ free(offsets);
+ if (paths != NULL) {
+ for (int i = 0; i < numInstances; i++) {
+ free(paths[i]);
+ }
+ }
+ free(paths);
+ delete next;
+}
+
+/*
+void
+Ancestor::print(void)
+{
+ fprintf(stderr, "Ancestor Information\n");
+ fprintf(stderr, "Tag Name: %s\n", def->name);
+ fprintf(stderr, "Tag Type: %s\n",
+ get_tagtype_str(get_tag_type(&tag)));
+ fprintf(stderr, "Num instances: %d\n", numInstances);
+ fprintf(stderr, " offsets:\n");
+ for (int i = 0; i < numInstances; i++) {
+ fprintf(stderr, " %d\n", offsets[i]);
+ }
+
+ if (next != NULL) {
+ next->print();
+ }
+}
+*/
+
+void
+Ancestor::addInstance(const char *path, uint32_t offset)
+{
+ if (numInstances >= ANCESTOR_INST_BUF_SIZE) {
+ numBufs++;
+ offsets = (uint32_t *)realloc(offsets,
+ (sizeof (uint32_t) *
+ (ANCESTOR_INST_BUF_SIZE * numBufs)));
+ paths = (char **)realloc(offsets,
+ (sizeof (char *) *
+ (ANCESTOR_INST_BUF_SIZE * numBufs)));
+ }
+ offsets[numInstances] = offset;
+ paths[numInstances++] = strdup(path);
+}
+
+Str
+Ancestor::getFieldName(void)
+{
+ return (field_name);
+}
+
+fru_tag_t
+Ancestor::getTag(void)
+{
+ return (tag);
+}
+
+const fru_regdef_t *
+Ancestor::getDef(void)
+{
+ return (def);
+}
+
+int
+Ancestor::getNumInstances(void)
+{
+ return (numInstances);
+}
+
+uint32_t
+Ancestor::getInstOffset(int num)
+{
+ if (num < numInstances)
+ return (offsets[num]);
+ else
+ return (offsets[numInstances]);
+}
+
+const char *
+Ancestor::getPath(int num)
+{
+ if (num < numInstances)
+ return (paths[num]);
+ else
+ return (paths[numInstances]);
+}
+
+
+Ancestor *
+Ancestor::listTaggedAncestors(char *element)
+{
+ Ancestor *rc = NULL;
+ fru_regdef_t *def = NULL;
+ int i = 0;
+
+ unsigned int number = 0;
+ char **data_elems = fru_reg_list_entries(&number);
+
+ if (data_elems == NULL) {
+ return (NULL);
+ }
+
+ // look through all the elements.
+ for (i = 0; i < number; i++) {
+ def = (fru_regdef_t *)
+ fru_reg_lookup_def_by_name(data_elems[i]);
+ Ancestor *ant = createTaggedAncestor(def, element);
+ if (ant != NULL) {
+ if (rc == NULL) {
+ rc = ant;
+ } else {
+ Ancestor *tmp = rc;
+ while (tmp->next != NULL) {
+ tmp = tmp->next;
+ }
+ tmp->next = ant;
+ }
+ }
+ }
+
+ for (i = 0; i < number; i++) {
+ free(data_elems[i]);
+ }
+ free(data_elems);
+
+ return (rc);
+}
+
+Ancestor *
+Ancestor::createTaggedAncestor(const fru_regdef_t *def, Str element)
+{
+ // ancestors have to be tagged.
+ if (def->tagType == FRU_X)
+ return (NULL);
+
+ fru_tag_t tag;
+ mk_tag(def->tagType, def->tagDense, def->payloadLen, &tag);
+ Ancestor *rc = new Ancestor(element, tag, def);
+
+ if (element.compare(def->name) == 0) {
+ rc->addInstance("", 0);
+ return (rc);
+ }
+
+ int found = 0;
+ if (def->dataType == FDTYPE_Record) {
+ uint32_t offset = 0;
+ for (int i = 0; i < def->enumCount; i++) {
+ const fru_regdef_t *tmp
+ = fru_reg_lookup_def_by_name
+ ((char *)def->enumTable[i].text);
+ Str path = "/";
+ path << def->name;
+ int f = definitionContains(tmp, def, element,
+ offset, rc, path);
+ if (f == 1) found = 1; // found needs to latch at one.
+ offset += tmp->payloadLen;
+ }
+ }
+
+ if (!found) {
+ delete rc;
+ return (NULL);
+ }
+
+ return (rc);
+}
+
+int
+Ancestor::definitionContains(const fru_regdef_t *def,
+ const fru_regdef_t *parent_def,
+ Str element,
+ uint32_t offset,
+ Ancestor *ant,
+ Str path)
+{
+ if (element.compare(def->name) == 0) {
+ if (parent_def->iterationType != FRU_NOT_ITERATED) {
+ offset += 4;
+ for (int i = 0; i < parent_def->iterationCount; i++) {
+ Str tmp = path;
+ tmp << "[" << i << "]/";
+ ant->addInstance(tmp.peak(), offset);
+ offset += (parent_def->payloadLen - 4) /
+ parent_def->iterationCount;
+ }
+ } else {
+ path << "/";
+ ant->addInstance(path.peak(), offset);
+ }
+ return (1);
+ }
+
+ int found = 0;
+ if (def->dataType == FDTYPE_Record) {
+ for (int i = 0; i < def->enumCount; i++) {
+ const fru_regdef_t *tmp
+ = fru_reg_lookup_def_by_name
+ ((char *)def->enumTable[i].text);
+ Str newPath = path;
+ newPath << "/" << def->name;
+ int f = definitionContains(tmp, def, element,
+ offset, ant, newPath);
+ if (f == 1) found = 1; // found needs to latch at one.
+ offset += tmp->payloadLen;
+ }
+ }
+
+ return (found);
+}
diff --git a/usr/src/lib/libfru/libfru/Ancestor.h b/usr/src/lib/libfru/libfru/Ancestor.h
new file mode 100644
index 0000000000..9029eb0229
--- /dev/null
+++ b/usr/src/lib/libfru/libfru/Ancestor.h
@@ -0,0 +1,105 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _ANCESTOR_H
+#define _ANCESTOR_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "libfru.h"
+#include "libfrureg.h"
+#include "fru_tag.h"
+#include "Str.h"
+
+// the object used to determine the ancestory of a particular element.
+struct Ancestor
+{
+ Ancestor(Str field, fru_tag_t t, const fru_regdef_t *d);
+ ~Ancestor();
+
+ void addInstance(const char *path, uint32_t offset);
+
+ Str getFieldName(void);
+ fru_tag_t getTag(void);
+
+ const fru_regdef_t *getDef(void);
+
+ int getNumInstances(void);
+ uint32_t getInstOffset(int num);
+ const char *getPath(int num);
+/*
+ * void print(void);
+ */
+
+ // returns a NULL terminated list of Ancestor objects which contain
+ // information about all the Ancestors of element.
+ static Ancestor *listTaggedAncestors(char *element);
+
+public:
+ Ancestor *next;
+
+private:
+ Str field_name;
+ fru_tag_t tag;
+ const fru_regdef_t *def;
+ int numInstances;
+#define ANCESTOR_INST_BUF_SIZE 256
+ int numBufs;
+ uint32_t *offsets;
+ char **paths;
+
+ // internal calls
+ static Ancestor * createTaggedAncestor(const fru_regdef_t *def,
+ Str element);
+ static int definitionContains(const fru_regdef_t *def,
+ const fru_regdef_t *parent_def,
+ Str element,
+ uint32_t offset,
+ Ancestor *ant,
+ Str path);
+
+private:
+ Ancestor(const Ancestor&);
+ void operator=(const Ancestor&);
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ANCESTOR_H */
diff --git a/usr/src/lib/libfru/libfru/Parser.cc b/usr/src/lib/libfru/libfru/Parser.cc
new file mode 100644
index 0000000000..7a01db2a39
--- /dev/null
+++ b/usr/src/lib/libfru/libfru/Parser.cc
@@ -0,0 +1,104 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2000 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <pthread.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "Parser.h"
+
+// yacc symbols
+int fruparse(void);
+extern int frudebug;
+
+// global data to/from the lexer
+pthread_mutex_t gParserLock;
+fru_errno_t gParserErrno = FRU_SUCCESS;
+char *gParserString = NULL;
+Ancestor *gParserAnts = NULL;
+PathDef *gParserHead = NULL;
+int *gParserAbs = NULL;
+
+// returns a NULL terminated list of PathDef objects.
+// and a NULL terminated list of ancestor objects this path exists in
+// NOTE: ancestors may be NULL if no tags contain a valid path.
+fru_errno_t
+fru_field_parser(const char *path, Ancestor **ancestors,
+ int *absolute, PathDef **pathDef)
+{
+ // lock up the globals for the parser...
+ pthread_mutex_lock(&gParserLock);
+
+ // get out a string for the parser to play with.
+ gParserString = strdup(path);
+ if (gParserString == NULL) {
+ pthread_mutex_unlock(&gParserLock);
+ return (FRU_FAILURE);
+ }
+ // save the head pointer for delete.
+ char *delPtr = gParserString;
+
+ // frudebug = 1;
+
+ // set up for return data from lexer.
+ gParserHead = NULL;
+ gParserAnts = NULL;
+ gParserErrno = FRU_SUCCESS;
+ gParserAbs = absolute;
+ *gParserAbs = 0;
+
+ int rc = fruparse();
+
+ // clean up the string we used for yacc.
+ free(delPtr);
+ gParserString = NULL;
+
+ // frudebug = 0;
+ if (rc != 0) {
+ delete gParserHead;
+ delete gParserAnts;
+ fru_errno_t err = gParserErrno;
+ pthread_mutex_unlock(&gParserLock);
+ return (err);
+ }
+
+ /* if ((gParserHead == NULL) || (gParserAnts == NULL)) { */
+ /* allow ancestors to be NULL */
+ /* some elements don't have tagged ancestors */
+ if (gParserHead == NULL) {
+ delete gParserAnts;
+ pthread_mutex_unlock(&gParserLock);
+ return (FRU_FAILURE);
+ }
+
+ *pathDef = gParserHead;
+ *ancestors = gParserAnts;
+
+ pthread_mutex_unlock(&gParserLock);
+ return (FRU_SUCCESS);
+}
diff --git a/usr/src/lib/libfru/libfru/Parser.h b/usr/src/lib/libfru/libfru/Parser.h
new file mode 100644
index 0000000000..0e683b3032
--- /dev/null
+++ b/usr/src/lib/libfru/libfru/Parser.h
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _PARSER_H
+#define _PARSER_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "fru_tag.h"
+#include "libfrureg.h"
+#include "Ancestor.h"
+
+struct PathDef
+{
+ fru_regdef_t *def;
+ static const int lastIteration = -1;
+ static const int addIteration = -2;
+ int iterIndex; // index of the iteration. (or special)
+ // -1 if '$' specified.
+ // -2 if '+' specified.
+ PathDef *next;
+
+ ~PathDef() { delete next; }
+};
+
+// returns the top PathData object.
+// and a NULL terminated list of Ancestor objects.
+// USER MUST delete the PathDef and Ancestor returned.
+fru_errno_t fru_field_parser(const char *path, Ancestor **ancestors,
+ int *absolute, PathDef **pathDef);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PARSER_H */
diff --git a/usr/src/lib/libfru/libfru/PayloadReader.cc b/usr/src/lib/libfru/libfru/PayloadReader.cc
new file mode 100644
index 0000000000..2eb7d736a0
--- /dev/null
+++ b/usr/src/lib/libfru/libfru/PayloadReader.cc
@@ -0,0 +1,557 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "PayloadReader.h"
+
+#define ITER_CONT_BYTE_LEN 4
+#define IS_ITERATED(pathDef) \
+(pathDef->def->iterationType != FRU_NOT_ITERATED)
+
+// functions to place bit data properly.
+static fru_errno_t
+writeBits(uint64_t bitData, size_t bitLength,
+ uint8_t *data, size_t dataLength, size_t bitOffset)
+{
+ if ((bitLength > 64) &&
+ (bitOffset > 64) &&
+ (dataLength > 8) &&
+ (bitOffset > (dataLength * 8)))
+ return (FRU_FAILURE);
+ // move the bit data into place
+ bitData = (bitData << (64-bitLength));
+ bitData = (bitData >> bitOffset);
+
+ // create a mask to clear the old data.
+ uint64_t mask = 0;
+ for (size_t i = 0; i < bitLength; i++) {
+ mask = ((mask << 1) + 1);
+ }
+ mask = (mask << (64-bitLength));
+ mask = (mask >> bitOffset);
+ mask = (mask ^ 0xFFFFFFFFFFFFFFFF);
+
+ // get the data out of the byte array.
+ uint64_t rd = 0;
+ memcpy((void *)&rd, (void *)data, dataLength);
+
+ // clear the old data
+ rd = (rd & mask);
+ // put in the new data.
+ rd = (rd | bitData);
+
+ // write the data back to the buffer.
+ memcpy((void *)data, (void *)&rd, dataLength);
+ return (FRU_SUCCESS);
+}
+
+static fru_errno_t
+readBits(size_t bitLength, uint8_t *data,
+ size_t dataLength, int bitOffset, uint64_t *ret)
+{
+ if ((bitLength > 64) ||
+ (bitLength < 0) ||
+ (bitOffset > 64) ||
+ (dataLength > 8) ||
+ (bitOffset > (dataLength * 8)))
+ return (FRU_FAILURE);
+ // get the data out of the byte array.
+ uint64_t rc = 0;
+ memcpy((void *)&rc, (void *)data, dataLength);
+
+ rc = (rc << bitOffset);
+ rc = (rc >> (64 - bitLength));
+ *ret = rc;
+ return (FRU_SUCCESS);
+}
+
+// ===========================================================================
+// caller is to be sure elemDef is contained by recDef.
+int
+PayloadReader::getOffsetIntoRecord(fru_regdef_t *recDef,
+ fru_regdef_t *elemDef)
+{
+ int rc = 0;
+ for (int i = 0; i < recDef->enumCount; i++) {
+ if (strcmp(recDef->enumTable[i].text, elemDef->name) == 0)
+ return (rc);
+ const fru_regdef_t *tmpDef = fru_reg_lookup_def_by_name(
+ (char *)recDef->enumTable[i].text);
+ rc += tmpDef->payloadLen;
+ }
+
+}
+
+// ===========================================================================
+// return -1 on error.
+int
+PayloadReader::calcOffset(int iterType,
+ uint8_t head, uint8_t tail,
+ uint8_t iterThere, uint8_t iterPoss,
+ size_t length, int index,
+ fru_errno_t *err)
+{
+ *err = FRU_SUCCESS;
+ switch (iterType) {
+ case FRU_FIFO:
+ case FRU_Linear:
+ {
+ if (index == PathDef::lastIteration)
+ return (length * tail);
+ return (length * index);
+ break;
+ }
+ case FRU_Circular:
+ case FRU_LIFO:
+ {
+ if (index == PathDef::lastIteration) {
+ if (iterType == FRU_LIFO)
+ return (length * head);
+ return (length * tail);
+ }
+
+ // For reading they are oposite.
+ if (iterType == FRU_Circular) {
+ return (length * ((head + index) % iterPoss));
+ } else {
+ int abs = tail - index;
+ if (abs < 0)
+ // abs is negative here
+ abs = iterPoss + abs;
+ return (length * abs);
+ }
+ break;
+ }
+ }
+ *err = FRU_FAILURE;
+ return (-1);
+}
+
+// ===========================================================================
+// return -1 on error.
+int
+PayloadReader::getIterationOffset(uint8_t *iter, int iterLen,
+ PathDef *path, int *rcIterThere,
+ fru_errno_t *err,
+ int onlyFindingIterThereFlag)
+{
+ int rc = 0;
+
+ // read the iteration control bytes first because we may ONLY need
+ // them.
+ uint8_t head = iter[0];
+ uint8_t tail = iter[1];
+ uint8_t iterThere = iter[2];
+ uint8_t iterPoss = iter[3];
+
+ // the '+' symbol on anything is an error here
+ if (path->iterIndex == PathDef::addIteration) {
+ *err = FRU_INVALPATH;
+ return (-1);
+ }
+
+ // check assumptions for next calls.
+ if (iterPoss != path->def->iterationCount) {
+ *err = FRU_DATACORRUPT;
+ return (-1);
+ }
+
+ if (onlyFindingIterThereFlag == ITER_THERE_ONLY) {
+ if (rcIterThere != NULL) {
+ *rcIterThere = iterThere;
+ }
+ *err = FRU_SUCCESS;
+ return (ITER_CONT_BYTE_LEN);
+ }
+
+ if ((path->iterIndex != PathDef::addIteration) &&
+ (path->iterIndex != PathDef::lastIteration) &&
+ (path->iterIndex >= iterThere)) {
+ *err = FRU_DATANOTFOUND;
+ return (-1);
+ }
+
+ // don't forget to skip the iteration control bytes!!!
+ int length = ((path->def->payloadLen - ITER_CONT_BYTE_LEN)
+ /path->def->iterationCount);
+
+ rc = calcOffset(path->def->iterationType,
+ head, tail, iterThere, iterPoss,
+ length, path->iterIndex, err);
+ if (rc == -1) {
+ // error set by calcOffset
+ return (-1);
+ }
+
+ *err = FRU_SUCCESS;
+ return (ITER_CONT_BYTE_LEN + rc);
+}
+
+// ===========================================================================
+// Iff onlyFindingIterThereFlag is set data is ignored and dataLen will be set
+// to the number of iterations which are actually in the seeprom.
+fru_errno_t
+PayloadReader::readRecurse(PathDef *path,
+ uint8_t *cur, size_t curLen,
+ void **data, size_t *dataLen,
+ int onlyFindingIterThereFlag)
+{
+ fru_errno_t rc = FRU_SUCCESS;
+ size_t calc_data_len = 0;
+
+ if (path->next == NULL) {
+
+ // alway go ahead and do the iterated thing. If we are not a
+ // field then the onlyFindingIterThereFlag should be set.
+ // Check this afterward.
+ int offset = 0;
+ int iterThere = 0;
+ // zzz altering the length things again...
+ if (IS_ITERATED(path)) {
+ // we are iterated.
+ calc_data_len = (path->def->payloadLen
+ -ITER_CONT_BYTE_LEN)/
+ path->def->iterationCount;
+// zzz still have to figure out the bit offsets for bit iterations...
+ offset = getIterationOffset(cur, curLen, path,
+ &iterThere, &rc,
+ onlyFindingIterThereFlag);
+ if (offset == -1)
+ return (rc);
+
+ // done
+ if (onlyFindingIterThereFlag) {
+ *dataLen = iterThere;
+ return (FRU_SUCCESS);
+ }
+ } else {
+ // done but this thing was not an iteration!!!
+ if (onlyFindingIterThereFlag) {
+ return (FRU_INVALPATH);
+ }
+
+ calc_data_len = path->def->payloadLen;
+ offset = 0;
+ }
+ // end zzz
+
+ // now make sure we have a field.
+ if (path->def->dataType == FDTYPE_Record) {
+ return (FRU_NOTFIELD);
+ }
+
+ // allocate and copy.
+ if (path->def->dataType == FDTYPE_Binary) {
+ uint64_t *eData = (uint64_t *)malloc(sizeof (*eData));
+ if (eData == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ int bitLength = path->def->dataLength;
+ // iterated bit field adjust acordingly.
+ if (IS_ITERATED(path)) {
+ bitLength = (bitLength-(ITER_CONT_BYTE_LEN*8))/
+ path->def->iterationCount;
+ }
+
+ rc = readBits(bitLength, &(cur[offset]),
+ calc_data_len, 0, eData);
+ if (rc != FRU_SUCCESS) {
+ free(eData);
+ return (rc);
+ }
+ *data = (void *)eData;
+ *dataLen = sizeof (*eData);
+ } else if (path->def->dataType == FDTYPE_Enumeration) {
+ unsigned char *eData
+ = (unsigned char *)malloc(sizeof (uint64_t));
+ if (eData == NULL) {
+ return (FRU_FAILURE);
+ }
+ /* copy the correct number of bytes to eData */
+ memset(eData, 0x00, sizeof (uint64_t));
+ memcpy(&(eData[(sizeof (uint64_t) - (calc_data_len))]),
+ &(cur[offset]),
+ (calc_data_len));
+ *data = (void*)eData;
+ *dataLen = sizeof (uint64_t);
+ } else {
+ void *rc_data = malloc(calc_data_len);
+ if (rc_data == NULL) {
+ return (FRU_FAILURE);
+ }
+ memcpy(rc_data, &(cur[offset]), calc_data_len);
+ *data = rc_data;
+ *dataLen = calc_data_len;
+ }
+
+ return (FRU_SUCCESS);
+ }
+
+ // At this point we know the entry is some sort of record.
+
+ int newOffset = 0, newLength = 0;
+ if (IS_ITERATED(path)) {
+
+// zzz still have to figure out the bit offsets for bit iterations...
+ newOffset = getIterationOffset(cur, curLen,
+ path, NULL, &rc, NORMAL_READ);
+ if (newOffset == -1)
+ return (rc);
+ }
+
+ newOffset += getOffsetIntoRecord(path->def, path->next->def);
+ newLength = path->next->def->payloadLen;
+
+ return (readRecurse(path->next, &(cur[newOffset]), newLength,
+ data, dataLen, onlyFindingIterThereFlag));
+}
+
+// ===========================================================================
+// will send the data back in (data,dataLen)
+fru_errno_t
+PayloadReader::readData(PathDef *path, Ancestor *curDef,
+ int instWICur,
+ uint8_t *payload, size_t payloadLen,
+ void **data, size_t *dataLen)
+{
+ int offset = curDef->getInstOffset(instWICur);
+ return (readRecurse(path, &(payload[offset]), payloadLen-offset,
+ data, dataLen, NORMAL_READ));
+}
+
+// ===========================================================================
+fru_errno_t
+PayloadReader::findIterThere(PathDef *path, Ancestor *curDef,
+ int instWICur,
+ uint8_t *payload, size_t payloadLen,
+ int *numThere)
+{
+ int offset = curDef->getInstOffset(instWICur);
+ size_t tmp_num = 0;
+ fru_errno_t err = readRecurse(path, &(payload[offset]),
+ payloadLen-offset, NULL, &tmp_num, ITER_THERE_ONLY);
+
+ if (err == FRU_SUCCESS) {
+ int tmp_num_there = (int)tmp_num;
+ if (tmp_num_there != tmp_num) {
+ return (FRU_FAILURE);
+ }
+ *numThere = tmp_num_there;
+ }
+ return (err);
+}
+
+static fru_errno_t
+update_iter_cont_bytes(PathDef *path, uint8_t *cur, size_t curLen)
+{
+ // update the iteration control information
+ uint8_t *head = &(cur[0]);
+ uint8_t *tail = &(cur[1]);
+ uint8_t *numThere = &(cur[2]);
+ // This never changes.
+ uint8_t numPoss = cur[3];
+
+ if (numPoss != path->def->iterationCount) {
+ return (FRU_DATACORRUPT);
+ }
+
+ // Remember that when the iteration is added the head and the tail both
+ // equal 0 (ie point to 0). So if we are empty when we are updating
+ // then we don't have to alter the head or tail values. We simply add
+ // one to the numThere.
+ if (*numThere != 0) {
+ switch (path->def->iterationType) {
+ case FRU_Linear:
+ // this will flag an error when Linear can't
+ // hold anymore.
+ if ((*tail + 1) == numPoss)
+ return (FRU_ITERFULL);
+ /* Fall through */
+ case FRU_FIFO:
+ // if we are not at the end move the tail.
+ if (*tail != (numPoss-1))
+ *tail = *tail+1;
+ break;
+
+ case FRU_Circular:
+ case FRU_LIFO:
+ // this is the same except LIFO is read
+ // BACKWARDS
+
+ // move the tail.
+ *tail = *tail + 1;
+ // if the tail hits the end wrap around.
+ if (*tail == numPoss)
+ *tail = 0;
+ // if tail catches head move the head.
+ if (*tail == *head) {
+ // if head hits the end wrap around.
+ if (++(*head) == numPoss)
+ *head = 0;
+ }
+ break;
+ }
+ }
+ if ((*numThere) < numPoss) {
+ // add one IFF we are not full
+ *numThere = *numThere + 1;
+ }
+
+ return (FRU_SUCCESS);
+}
+
+// ===========================================================================
+fru_errno_t
+PayloadReader::updateRecurse(PathDef *path,
+ uint8_t *cur, size_t curLen,
+ void *data, size_t dataLen)
+{
+ fru_errno_t rc = FRU_SUCCESS;
+
+ if (path->next == NULL) {
+
+ // Delay checking for Records until after this which will
+ // allow for [+] notation for Iterated Records.
+ // if this is updating an iteration AND we are adding one...
+ if (IS_ITERATED(path) &&
+ (path->iterIndex == PathDef::addIteration)) {
+ return (update_iter_cont_bytes(path, cur, curLen));
+ }
+
+ if (path->def->dataType == FDTYPE_Record) {
+ return (FRU_NOTFIELD);
+ }
+
+ int offset = 0;
+ int calcLen = 0;
+ int dummy = 0;
+ // zzz altering the length things again...
+ if (IS_ITERATED(path)) {
+ // we are iterated.
+ calcLen = (path->def->payloadLen-ITER_CONT_BYTE_LEN)/
+ path->def->iterationCount;
+// zzz still have to figure out the bit offsets
+ offset = getIterationOffset(cur, curLen,
+ path, &dummy, &rc, NORMAL_READ);
+ if (offset == -1)
+ return (rc);
+ } else {
+ calcLen = path->def->payloadLen;
+ offset = 0;
+ }
+ // end zzz
+
+ // once again convert enums for the user again.
+ if (path->def->dataType == FDTYPE_Binary) {
+ int bitLength = path->def->dataLength;
+ // iterated bit field adjust acordingly.
+ if (path->def->iterationType != FRU_NOT_ITERATED) {
+ bitLength = (bitLength - 32)/
+ path->def->iterationCount;
+ }
+
+ rc = writeBits (*(uint64_t *)data, bitLength,
+ &(cur[offset]), calcLen, 0);
+ if (rc != FRU_SUCCESS)
+ return (rc);
+ } else if (path->def->dataType == FDTYPE_Enumeration) {
+ unsigned char *tmp = (unsigned char *)data;
+ memcpy(&(cur[offset]),
+ &(tmp[(sizeof (uint64_t) - (calcLen))]),
+ calcLen);
+ } else {
+ // copy into and return.
+ memcpy(&(cur[offset]), data, dataLen);
+ }
+
+ return (FRU_SUCCESS);
+ }
+
+ int newOffset = 0, newLength = 0;
+ int dummy = 0;
+ if (path->def->iterationType != FRU_NOT_ITERATED) {
+
+// zzz still have to figure out the bit offsets
+ newOffset = getIterationOffset(cur, curLen, path,
+ &dummy, &rc, NORMAL_READ);
+ if (newOffset == -1)
+ return (rc);
+ }
+ newOffset += getOffsetIntoRecord(path->def, path->next->def);
+ newLength = path->next->def->payloadLen;
+
+ return (updateRecurse(path->next, &(cur[newOffset]), newLength,
+ data, dataLen));
+}
+
+// ===========================================================================
+// will update the data in payload which can then be written back.
+fru_errno_t
+PayloadReader::updateData(PathDef *path, Ancestor *ancestorDef,
+ int instWICur,
+ uint8_t *payload, size_t payloadLen,
+ void *data, size_t dataLen)
+{
+ // verify the user data first before doing any major work.
+ int calcLen = 0;
+ PathDef *prev = path;
+ PathDef *cur = path;
+ while (cur != NULL) {
+ prev = cur;
+ cur = cur->next;
+ }
+
+ // unless we are updateing with [+] symbol
+ // (which means we don't have any data length at all.)
+ if (prev->iterIndex != PathDef::addIteration) {
+ if (IS_ITERATED(prev)) {
+ calcLen = (prev->def->payloadLen-ITER_CONT_BYTE_LEN)/
+ prev->def->iterationCount;
+ } else {
+ calcLen = prev->def->payloadLen;
+ }
+ // the sizeof the data for Binary or Enumeration MUST
+ // be uint64_t
+ if ((prev->def->dataType == FDTYPE_Enumeration) ||
+ (prev->def->dataType == FDTYPE_Binary)) {
+ if (dataLen != sizeof (uint64_t))
+ return (FRU_INVALDATASIZE);
+ // all others must be shorter than the space available.
+ } else {
+ if (dataLen > calcLen)
+ return (FRU_INVALDATASIZE);
+ }
+ }
+
+ int offset = ancestorDef->getInstOffset(instWICur);
+ return (updateRecurse(path, &(payload[offset]), payloadLen-offset,
+ data, dataLen));
+}
diff --git a/usr/src/lib/libfru/libfru/PayloadReader.h b/usr/src/lib/libfru/libfru/PayloadReader.h
new file mode 100644
index 0000000000..510cf25d2f
--- /dev/null
+++ b/usr/src/lib/libfru/libfru/PayloadReader.h
@@ -0,0 +1,102 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _PAYLOADREADER_H
+#define _PAYLOADREADER_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "Parser.h"
+
+#define NORMAL_READ 0
+#define ITER_THERE_ONLY 1
+
+struct PayloadReader
+{
+ // will send the data back in (data,dataLen)
+ static fru_errno_t readData(PathDef *path, Ancestor *curDef,
+ int instWICur,
+ uint8_t *payload, size_t payloadLen,
+ void **data, size_t *dataLen);
+
+ // will update the data in payload which can then be written back.
+ static fru_errno_t updateData(PathDef *path, Ancestor *curDef,
+ int instWICur,
+ uint8_t *payload, size_t payloadLen,
+ void *data, size_t dataLen);
+
+ // will return the nuber of iterations actually there.
+ static fru_errno_t findIterThere(PathDef *path, Ancestor *curDef,
+ int instWICur,
+ uint8_t *payload, size_t payloadLen,
+ int *numThere);
+
+private:
+ static int getIterationOffset(uint8_t *iter, int iterLen,
+ PathDef *path, int *rcIterThere,
+ fru_errno_t *err,
+ int onlyFindingIterThereFlag);
+ static int calcOffset(int iterType,
+ uint8_t head, uint8_t tail,
+ uint8_t iterThere, uint8_t iterPoss,
+ size_t length, int index,
+ fru_errno_t *err);
+
+ static fru_errno_t readRecurse(PathDef *path,
+ uint8_t *cur, size_t curLen,
+ void **data, size_t *dataLen,
+ int onlyFindingIterThereFlag);
+
+ static fru_errno_t updateRecurse(PathDef *path,
+ uint8_t *cur, size_t curLen,
+ void *data, size_t dataLen);
+
+ static int getOffsetIntoRecord(fru_regdef_t *recDef,
+ fru_regdef_t *elemDef);
+
+ PayloadReader();
+ ~PayloadReader();
+ PayloadReader(const PayloadReader&);
+ void operator=(const PayloadReader&);
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PAYLOADREADER_H */
diff --git a/usr/src/lib/libfru/libfru/libfru.cc b/usr/src/lib/libfru/libfru/libfru.cc
new file mode 100644
index 0000000000..94bd09cc68
--- /dev/null
+++ b/usr/src/lib/libfru/libfru/libfru.cc
@@ -0,0 +1,2231 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * libfru is divided into the following modules:
+ * 1) This file. Support for the API and ties together all the sub-modules.
+ * 2) The parser which parses the field_paths supplied by the user.
+ * 3) The data_source sub-libraries which provide payloads(tags) and the tree
+ * structure of frus and locations.
+ * 4) The PayloadReader which given a payload and a path definition can extract
+ * the exact field the user is looking for.
+ * 5) The Registry which provides the definitions for all the Data Elements
+ * supported.
+ *
+ * The basic algorithim for reading/updating fields is this:
+ * 1) Parse the field_path given by the user.
+ * 2) Using the registry determine which payloads this data MAY appear in.
+ * 3) Figure out which tags of this type are in the container.
+ * 4) Find the specific tag which contains the instance of this data the user
+ * requested.
+ * 5) Get this tag from the data source and read it with the PayloadReader to
+ * read/write data.
+ * 6) For UPDATES write this tag back to the data source.
+ *
+ * This algorithim is altered only when dealing with "UNKNOWN" payloads where
+ * it simplifies slightly.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <libintl.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <dlfcn.h>
+#include <alloca.h>
+#include <limits.h>
+
+#include "libfru.h"
+#include "libfrup.h"
+#include "libfruds.h"
+#include "Ancestor.h"
+#include "libfrureg.h"
+#include "Parser.h"
+#include "PayloadReader.h"
+
+#define DATA_SOURCE_OBJ_NAME "data_source"
+
+#define ENCRYPTION_LIB_NAME "libfrucrypt.so.1"
+#define FRU_ENCRYPT_FUNC_NAME "fru_encrypt_func"
+
+#define UNKNOWN_PATH "UNKNOWN"
+#define IS_UNKNOWN_PATH(path) \
+((strcmp(path, "/UNKNOWN") == 0) || (strcmp(path, "UNKNOWN") == 0))
+
+#define NODEHDL_TO_TREEHDL(nodehdl) (fru_treehdl_t)nodehdl
+#define TREEHDL_TO_NODEHDL(treehdl) (fru_nodehdl_t)treehdl
+
+/* ========================================================================= */
+/*
+ * Define a hash of rwlocks for each container.
+ */
+struct cont_lock
+{
+ fru_nodehdl_t handle;
+ pthread_rwlock_t lock;
+ struct cont_lock *next;
+};
+typedef struct cont_lock cont_lock_t;
+
+#define CONT_LOCK_HASH_NUM 128
+cont_lock_t *cont_lock_hash[CONT_LOCK_HASH_NUM];
+pthread_mutex_t cont_lock_hash_lock;
+
+typedef enum { WRITE_LOCK, READ_LOCK } lock_mode_t;
+
+/*
+ * These control the Data sources available.
+ */
+static pthread_mutex_t ds_lock;
+static fru_datasource_t *data_source = NULL;
+static void *ds_lib = NULL;
+static int ds_lib_ref_cnt = 0;
+static char *ds_lib_name = NULL;
+
+/* ========================================================================= */
+static const char *fru_errmsg[] =
+{
+ "Success",
+ "Node not found",
+ "IO error",
+ "No registry definition for this element",
+ "Not container",
+ "Invalid handle",
+ "Invalid Segment",
+ "Invalid Path",
+ "Invalid Element",
+ "Invalid Data size (does not match registry definition)",
+ "Duplicate Segment",
+ "Not Field",
+ "No space available",
+ "Data could not be found",
+ "Iteration full",
+ "Invalid Permisions",
+ "Feature not Supported",
+ "Element is not Tagged",
+ "Failed to read container device",
+ "Segment Corrupt",
+ "Data Corrupt",
+ "General LIBFRU FAILURE",
+ "Walk terminated",
+ "Unknown error"
+};
+
+fru_errno_t
+fru_encryption_supported(void)
+{
+ if (encrypt_func == NULL)
+ return (FRU_NOTSUP);
+ else
+ return (FRU_SUCCESS);
+}
+
+extern "C" {
+void
+init_libfru(void)
+{
+ // attempt to find the encryption library.
+ void *crypt_lib = NULL;
+ encrypt_func = NULL;
+ crypt_lib = dlopen(ENCRYPTION_LIB_NAME, RTLD_LAZY);
+ if (crypt_lib != NULL) {
+ encrypt_func = (fru_encrypt_func_t)dlsym(crypt_lib,
+ FRU_ENCRYPT_FUNC_NAME);
+ }
+}
+#pragma init(init_libfru)
+}
+
+/* ========================================================================= */
+static void
+add_cont_lock(cont_lock_t *lock)
+{
+ cont_lock_t *prev = NULL;
+ int hash_bucket = lock->handle % CONT_LOCK_HASH_NUM;
+
+ /* insert at tail */
+ if (cont_lock_hash[hash_bucket] == NULL) {
+ cont_lock_hash[hash_bucket] = lock;
+ } else {
+ cont_lock_t *prev = cont_lock_hash[hash_bucket];
+ while (prev->next != NULL) {
+ prev = prev->next;
+ }
+ prev->next = lock;
+ }
+}
+
+/* ========================================================================= */
+static cont_lock_t *
+find_cont_lock(fru_nodehdl_t handle)
+{
+ int hash_bucket = handle % CONT_LOCK_HASH_NUM;
+ cont_lock_t *which = cont_lock_hash[hash_bucket];
+
+ while (which != NULL) {
+ if (which->handle == handle) {
+ break;
+ }
+ which = which->next;
+ }
+ return (which);
+}
+
+/* ========================================================================= */
+static cont_lock_t *
+alloc_cont_lock(fru_nodehdl_t handle)
+{
+ cont_lock_t *lock = (cont_lock_t *)malloc(sizeof (cont_lock_t));
+ if (lock == NULL) {
+ return (NULL);
+ }
+ lock->handle = handle;
+ if (pthread_rwlock_init(&(lock->lock), NULL) != 0) {
+ free(lock);
+ return (NULL);
+ }
+ lock->next = NULL;
+ return (lock);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+lock_container(lock_mode_t mode, fru_nodehdl_t handle)
+{
+ cont_lock_t *which = NULL;
+ int hash_bucket = 0;
+ int lock_rc;
+
+ pthread_mutex_lock(&cont_lock_hash_lock);
+
+ which = find_cont_lock(handle);
+
+ /* if not found add to hash */
+ if (which == NULL) {
+ if ((which = alloc_cont_lock(handle)) == NULL) {
+ pthread_mutex_unlock(&cont_lock_hash_lock);
+ return (FRU_FAILURE);
+ }
+ add_cont_lock(which);
+ }
+
+ /* execute lock */
+ lock_rc = 0;
+ switch (mode) {
+ case READ_LOCK:
+ lock_rc = pthread_rwlock_rdlock(&(which->lock));
+ break;
+ case WRITE_LOCK:
+ lock_rc = pthread_rwlock_wrlock(&(which->lock));
+ break;
+ }
+
+ pthread_mutex_unlock(&cont_lock_hash_lock);
+ if (lock_rc != 0) {
+ return (FRU_FAILURE);
+ }
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+/*
+ * Macro to make checking unlock_conatiner error code easier
+ */
+#define CHK_UNLOCK_CONTAINER(handle) \
+ if (unlock_container(handle) != FRU_SUCCESS) { \
+ return (FRU_FAILURE); \
+ }
+static fru_errno_t
+unlock_container(fru_nodehdl_t handle)
+{
+ cont_lock_t *which = NULL;
+ pthread_mutex_lock(&cont_lock_hash_lock);
+
+ which = find_cont_lock(handle);
+ if (which == NULL) {
+ pthread_mutex_unlock(&cont_lock_hash_lock);
+ return (FRU_NODENOTFOUND);
+ }
+
+ if (pthread_rwlock_unlock(&(which->lock)) != 0) {
+ pthread_mutex_unlock(&cont_lock_hash_lock);
+ return (FRU_FAILURE);
+ }
+
+ pthread_mutex_unlock(&cont_lock_hash_lock);
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+clear_cont_locks(void)
+{
+ pthread_mutex_lock(&cont_lock_hash_lock);
+
+ // for each bucket
+ for (int i = 0; i < CONT_LOCK_HASH_NUM; i++) {
+ // free all the locks
+ cont_lock_t *cur = cont_lock_hash[i];
+ while (cur != NULL) {
+ cont_lock_t *tmp = cur;
+ cur = cur->next;
+ pthread_rwlock_destroy(&(tmp->lock));
+ free(tmp);
+ }
+ cont_lock_hash[i] = NULL;
+ }
+
+ pthread_mutex_unlock(&cont_lock_hash_lock);
+ return (FRU_SUCCESS);
+}
+
+
+/* ========================================================================= */
+/* VARARGS */
+fru_errno_t
+fru_open_data_source(const char *name, ...)
+{
+ fru_errno_t err = FRU_SUCCESS;
+
+ va_list args;
+ int num_args = 0;
+ char **init_args = NULL;
+ char *tmp;
+ int i = 0;
+
+ char ds_name[PATH_MAX];
+ fru_datasource_t *ds = NULL;
+ void *tmp_lib = NULL;
+
+ pthread_mutex_lock(&ds_lock);
+
+ if ((ds_lib_name != NULL) && (data_source != NULL)) {
+ // we already have a DS assigned.
+ if ((strcmp(ds_lib_name, name) == 0)) {
+ // user wants to open the same one... ok.
+ ds_lib_ref_cnt++;
+ pthread_mutex_unlock(&ds_lock);
+ return (FRU_SUCCESS);
+ } else {
+ pthread_mutex_unlock(&ds_lock);
+ return (FRU_FAILURE);
+ }
+ }
+
+ snprintf(ds_name, sizeof (ds_name), "libfru%s.so.%d",
+ name, LIBFRU_DS_VER);
+ tmp_lib = dlopen(ds_name, RTLD_LAZY);
+ if (tmp_lib == NULL) {
+ pthread_mutex_unlock(&ds_lock);
+ return (FRU_NOTSUP);
+ }
+ ds = (fru_datasource_t *)dlsym(tmp_lib,
+ DATA_SOURCE_OBJ_NAME);
+ if (ds == NULL) {
+ pthread_mutex_unlock(&ds_lock);
+ return (FRU_FAILURE);
+ }
+
+ va_start(args, name);
+ tmp = va_arg(args, char *);
+ while (tmp != NULL) {
+ num_args++;
+ tmp = va_arg(args, char *);
+ }
+ va_end(args);
+
+ init_args = (char **)malloc(sizeof (char *) * num_args);
+ if (init_args == NULL) {
+ pthread_mutex_unlock(&ds_lock);
+ return (FRU_FAILURE);
+ }
+
+ va_start(args, name);
+ for (tmp = va_arg(args, char *), i = 0;
+ (tmp != NULL) && (i < num_args);
+ tmp = va_arg(args, char *), i++) {
+ init_args[i] = tmp;
+ }
+ va_end(args);
+
+ if ((err = ds->initialize(num_args, init_args)) == FRU_SUCCESS) {
+ // don't switch unless the source connects ok.
+ ds_lib = tmp_lib;
+ data_source = ds;
+ ds_lib_name = strdup(name);
+ ds_lib_ref_cnt++;
+ }
+
+ free(init_args);
+ pthread_mutex_unlock(&ds_lock);
+ return (err);
+}
+
+
+/* ========================================================================= */
+fru_errno_t
+fru_close_data_source(void)
+{
+ fru_errno_t err = FRU_SUCCESS;
+
+ if (ds_lib_ref_cnt == 0) {
+ return (FRU_FAILURE);
+ }
+
+ pthread_mutex_lock(&ds_lock);
+ if ((--ds_lib_ref_cnt) == 0) {
+ /* don't check err code here */
+ err = data_source->shutdown();
+ /* continue to clean up libfru and return the err at the end */
+ clear_cont_locks();
+ dlclose(ds_lib);
+ ds_lib = NULL;
+ free(ds_lib_name);
+ ds_lib_name = NULL;
+ data_source = NULL;
+ }
+
+ pthread_mutex_unlock(&ds_lock);
+ return (err);
+}
+
+/* ========================================================================= */
+int
+segment_is_encrypted(fru_nodehdl_t container, const char *seg_name)
+{
+ fru_errno_t tmp;
+ fru_segdef_t segdef;
+
+ if (data_source == NULL) {
+ return (0);
+ }
+ if (data_source->get_seg_def(NODEHDL_TO_TREEHDL(container),
+ seg_name, &segdef) != FRU_SUCCESS) {
+ return (0);
+ }
+
+ return (segdef.desc.field.encrypted == 1);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+get_seg_list_from_ds(fru_nodehdl_t node, fru_strlist_t *list)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ fru_strlist_t raw_list;
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ /* get a list of all segments */
+ if ((err = data_source->get_seg_list(NODEHDL_TO_TREEHDL(node),
+ &raw_list)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ /* leave out the encrypted segments if necessary */
+ list->num = 0;
+ list->strs = (char **)malloc(sizeof (*(list->strs)) * raw_list.num);
+ if (list->strs == NULL) {
+ fru_destroy_strlist(&raw_list);
+ return (err);
+ }
+ for (int i = 0; i < raw_list.num; i++) {
+ if (segment_is_encrypted(node, raw_list.strs[i])) {
+ if (fru_encryption_supported() == FRU_SUCCESS) {
+ list->strs[list->num]
+ = strdup(raw_list.strs[i]);
+ list->num++;
+ } // else leave it out.
+ } else {
+ list->strs[list->num] = strdup(raw_list.strs[i]);
+ list->num++;
+ }
+ }
+
+ fru_destroy_strlist(&raw_list);
+ return (FRU_SUCCESS);
+}
+
+
+/* ========================================================================= */
+const char *
+fru_strerror(fru_errno_t errnum)
+{
+ if ((errnum < (sizeof (fru_errmsg)/sizeof (*fru_errmsg))) &&
+ (errnum >= 0)) {
+ return (gettext(fru_errmsg[errnum]));
+ }
+ return (gettext
+ (fru_errmsg[(sizeof (fru_errmsg)/sizeof (*fru_errmsg))]));
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_get_root(fru_nodehdl_t *handle)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ fru_treehdl_t tr_root;
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ err = data_source->get_root(&tr_root);
+ if (err == FRU_SUCCESS) {
+ *handle = TREEHDL_TO_NODEHDL(tr_root);
+ }
+ return (err);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_get_child(fru_nodehdl_t handle, fru_nodehdl_t *child)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ fru_treehdl_t tr_child;
+ fru_node_t type;
+
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+ if ((err = data_source->get_child(NODEHDL_TO_TREEHDL(handle),
+ &tr_child)) != FRU_SUCCESS) {
+ return (err);
+ }
+ if ((err = data_source->get_node_type(tr_child, &type))
+ != FRU_SUCCESS) {
+ return (err);
+ }
+ if ((type == FRU_NODE_LOCATION) ||
+ (type == FRU_NODE_FRU) ||
+ (type == FRU_NODE_CONTAINER)) {
+ *child = TREEHDL_TO_NODEHDL(tr_child);
+ return (FRU_SUCCESS);
+ }
+
+/*
+ * if the child is not valid try and find a peer of the child which is
+ * valid
+ */
+ do {
+ if ((err = data_source->get_peer(tr_child,
+ &tr_child)) != FRU_SUCCESS) {
+ return (err);
+ }
+ if ((err = data_source->get_node_type(tr_child, &type))
+ != FRU_SUCCESS) {
+ return (err);
+ }
+ if ((type == FRU_NODE_LOCATION) ||
+ (type == FRU_NODE_FRU) ||
+ (type == FRU_NODE_CONTAINER)) {
+ *child = TREEHDL_TO_NODEHDL(tr_child);
+ return (FRU_SUCCESS);
+ }
+ } while (1);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_get_peer(fru_nodehdl_t handle, fru_nodehdl_t *peer)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ fru_treehdl_t tr_peer = NODEHDL_TO_TREEHDL(handle);
+ fru_node_t type;
+
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ do {
+ if ((err = data_source->get_peer(tr_peer, &tr_peer))
+ != FRU_SUCCESS) {
+ return (err);
+ }
+ if ((err = data_source->get_node_type(tr_peer, &type))
+ != FRU_SUCCESS) {
+ return (err);
+ }
+ if ((type == FRU_NODE_LOCATION) ||
+ (type == FRU_NODE_FRU) ||
+ (type == FRU_NODE_CONTAINER)) {
+ *peer = TREEHDL_TO_NODEHDL(tr_peer);
+ return (FRU_SUCCESS);
+ }
+ } while (1);
+}
+/* ========================================================================= */
+fru_errno_t
+fru_get_parent(fru_nodehdl_t handle, fru_nodehdl_t *parent)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ fru_treehdl_t tr_parent;
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+ err = data_source->get_parent(NODEHDL_TO_TREEHDL(handle), &tr_parent);
+ if (err == FRU_SUCCESS) {
+ *parent = TREEHDL_TO_NODEHDL(tr_parent);
+ }
+ return (err);
+}
+
+
+/* ========================================================================= */
+fru_errno_t
+fru_get_name_from_hdl(fru_nodehdl_t handle, char **name)
+{
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+ return (data_source->get_name_from_hdl(NODEHDL_TO_TREEHDL(handle),
+ name));
+}
+
+/* ========================================================================= */
+/*
+ * Project-private interface
+ *
+ * Apply process_node() to each node in the tree rooted at "node".
+ *
+ * process_node() has available the handle, path (in the subtree from the root
+ * "node" passed to fru_walk_tree()), and name of the node to which it is
+ * applied, as well as any arguments provided via the generic pointer "args".
+ * process_node() also takes a pointer to an end_node() function pointer
+ * argument and a pointer to a generic pointer "end_args" argument. If
+ * non-null, end_node() is called after the node and its children have been
+ * processed, but before the node's siblings are visited.
+ */
+extern "C" fru_errno_t
+fru_walk_tree(fru_nodehdl_t node, const char *prior_path,
+ fru_errno_t (*process_node)(fru_nodehdl_t node,
+ const char *path,
+ const char *name, void *args,
+ end_node_fp_t *end_node,
+ void **end_args),
+ void *args)
+{
+ void *end_args = NULL;
+
+ char *name = NULL, *path;
+
+ int prior_length;
+
+ fru_errno_t status;
+
+ fru_nodehdl_t next;
+
+ end_node_fp_t end_node = NULL;
+
+
+ /* Build node's path */
+ if ((status = fru_get_name_from_hdl(node, &name)) != FRU_SUCCESS)
+ return (status);
+ else if (name == NULL)
+ return (FRU_FAILURE);
+
+ prior_length = strlen(prior_path);
+ path = (char *)alloca(prior_length + sizeof ("/") + strlen(name));
+ (void) sprintf(path, "%s/%s", prior_path, name);
+ free(name);
+ name = path + prior_length + 1;
+
+
+ /* Process node */
+ assert(process_node != NULL);
+ if ((status = process_node(node, path, name, args,
+ &end_node, &end_args))
+ != FRU_SUCCESS) {
+ if (end_node) end_node(node, path, name, end_args);
+ return (status);
+ }
+
+
+ /* Process children */
+ if ((status = fru_get_child(node, &next)) == FRU_SUCCESS)
+ status = fru_walk_tree(next, path, process_node, args);
+ else if (status == FRU_NODENOTFOUND)
+ status = FRU_SUCCESS;
+
+ /* "Close" node */
+ if (end_node) end_node(node, path, name, end_args);
+ if (status != FRU_SUCCESS)
+ return (status);
+
+ /* Process siblings */
+ if ((status = fru_get_peer(node, &next)) == FRU_SUCCESS)
+ status = fru_walk_tree(next, prior_path, process_node, args);
+ else if (status == FRU_NODENOTFOUND)
+ status = FRU_SUCCESS;
+
+ return (status);
+}
+
+/* ========================================================================= */
+/*
+ * Project-private interface
+ *
+ * Return true if "searchpath" equals "path" or is a tail of "path" and
+ * begins at a component name within "path"
+ */
+int
+fru_pathmatch(const char *path, const char *searchpath)
+{
+ const char *match;
+
+ if (((match = strstr(path, searchpath)) != NULL) &&
+ ((match + strlen(searchpath)) == (path + strlen(path))) &&
+ ((match == path) || (*(match - 1) == '/')))
+ return (1);
+
+ return (0);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_get_node_type(fru_nodehdl_t handle, fru_node_t *type)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ fru_node_t tmp;
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+ if ((err = data_source->get_node_type(NODEHDL_TO_TREEHDL(handle),
+ &tmp)) != FRU_SUCCESS) {
+ return (err);
+ }
+ *type = tmp;
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+is_container(fru_nodehdl_t handle)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ fru_node_t type;
+ if ((err = fru_get_node_type(handle, &type)) != FRU_SUCCESS) {
+ return (err);
+ }
+ if (type == FRU_NODE_CONTAINER) {
+ return (FRU_SUCCESS);
+ }
+ return (FRU_NOTCONTAINER);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_destroy_enum(fru_enum_t *e)
+{
+ if (e == NULL) {
+ return (FRU_SUCCESS);
+ }
+ if (e->text != NULL)
+ free(e->text);
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+/*
+ * NOTE: does not free list. This is allocated by the user and should be
+ * deallocated by the user.
+ */
+fru_errno_t
+fru_destroy_strlist(fru_strlist_t *list)
+{
+ if (list == NULL) {
+ return (FRU_SUCCESS);
+ }
+ if (list->strs != NULL) {
+ for (int i = 0; i < list->num; i++) {
+ if (list->strs[i] != NULL)
+ free(list->strs[i]);
+ }
+ free(list->strs);
+ }
+
+ list->num = 0;
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_destroy_elemdef(fru_elemdef_t *def)
+{
+ if (def == NULL) {
+ return (FRU_SUCCESS);
+ }
+ if (def->enum_table != NULL) {
+ for (int i = 0; i < def->enum_count; i++)
+ fru_destroy_enum(&(def->enum_table[i]));
+ free(def->enum_table);
+ }
+ def->enum_count = 0;
+
+ if (def->example_string != NULL)
+ free(def->example_string);
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_list_segments(fru_nodehdl_t container, fru_strlist_t *list)
+{
+ fru_errno_t err = FRU_SUCCESS;
+
+ if ((err = is_container(container)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if (lock_container(READ_LOCK, container) != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+
+ err = get_seg_list_from_ds(container, list);
+
+ CHK_UNLOCK_CONTAINER(container);
+ return (err);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_create_segment(fru_nodehdl_t container, fru_segdef_t *def)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ int i = 0;
+
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ if ((def->desc.field.encrypted == 1) &&
+ (fru_encryption_supported() == FRU_NOTSUP)) {
+ return (FRU_NOTSUP);
+ }
+
+ if ((err = is_container(container)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if (lock_container(WRITE_LOCK, container) != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+ fru_strlist_t seg_list;
+
+ /* get a list of all segments */
+ /* here we do not want to leave out the encrypted segments. */
+ if ((err = data_source->get_seg_list(NODEHDL_TO_TREEHDL(container),
+ &seg_list)) != FRU_SUCCESS) {
+ CHK_UNLOCK_CONTAINER(container);
+ return (err);
+ }
+
+ for (i = 0; i < seg_list.num; i++) {
+ if (strncmp(seg_list.strs[i], def->name, FRU_SEGNAMELEN)
+ == 0) {
+ fru_destroy_strlist(&seg_list);
+ CHK_UNLOCK_CONTAINER(container);
+ return (FRU_DUPSEG);
+ }
+ }
+ fru_destroy_strlist(&seg_list);
+
+ err = data_source->add_seg(NODEHDL_TO_TREEHDL(container), def);
+ CHK_UNLOCK_CONTAINER(container);
+ return (err);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_remove_segment(fru_nodehdl_t container, const char *seg_name)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ if ((seg_name == NULL) || (strlen(seg_name) > FRU_SEGNAMELEN)) {
+ return (FRU_INVALSEG);
+ }
+
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ if ((err = is_container(container)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if (lock_container(WRITE_LOCK, container) != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+
+ /* do not allow encrypted segments to be removed */
+ /* unless encryption is supported */
+ if ((segment_is_encrypted(container, seg_name)) &&
+ (fru_encryption_supported() == FRU_NOTSUP)) {
+ err = FRU_INVALSEG;
+ } else {
+ err = data_source->delete_seg(NODEHDL_TO_TREEHDL(container),
+ seg_name);
+ }
+
+ CHK_UNLOCK_CONTAINER(container);
+ return (err);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_get_segment_def(fru_nodehdl_t container, const char *seg_name,
+ fru_segdef_t *definition)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ if ((seg_name == NULL) || (strlen(seg_name) > 2)) {
+ return (FRU_INVALSEG);
+ }
+
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ if ((err = is_container(container)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if (lock_container(READ_LOCK, container) != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+
+ // NOTE: not passing "definition" to this function such that I may
+ // check for encryption before allowing the user to get the data.
+ fru_segdef_t segdef;
+ if ((err = data_source->get_seg_def(NODEHDL_TO_TREEHDL(container),
+ seg_name, &segdef)) != FRU_SUCCESS) {
+ CHK_UNLOCK_CONTAINER(container);
+ return (err);
+ }
+
+ if ((segdef.desc.field.encrypted == 1) &&
+ (fru_encryption_supported() == FRU_NOTSUP)) {
+ CHK_UNLOCK_CONTAINER(container);
+ return (FRU_INVALSEG);
+ }
+
+ // After encryption check, copy from my def to users.
+ definition->version = segdef.version;
+ strlcpy(definition->name, segdef.name, FRU_SEGNAMELEN+1);
+ definition->desc = segdef.desc;
+ definition->size = segdef.size;
+ definition->address = segdef.address;
+ definition->hw_desc = segdef.hw_desc;
+
+ CHK_UNLOCK_CONTAINER(container);
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_list_elems_in(fru_nodehdl_t container, const char *seg_name,
+ fru_strlist_t *list)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ fru_tag_t *tags = NULL;
+ int i = 0;
+ int num_tags = 0;
+ fru_strlist_t rc_list;
+
+ if ((seg_name == NULL) || (strlen(seg_name) > 2)) {
+ return (FRU_INVALSEG);
+ }
+
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ if ((err = is_container(container)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if (lock_container(READ_LOCK, container) != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+
+ if ((segment_is_encrypted(container, seg_name)) &&
+ (fru_encryption_supported() == FRU_NOTSUP)) {
+ CHK_UNLOCK_CONTAINER(container);
+ return (FRU_INVALSEG);
+ }
+
+ if ((err = data_source->get_tag_list(NODEHDL_TO_TREEHDL(container),
+ seg_name, &tags, &num_tags))
+ != FRU_SUCCESS) {
+ CHK_UNLOCK_CONTAINER(container);
+ return (err);
+ }
+ if (num_tags == 0) {
+ CHK_UNLOCK_CONTAINER(container);
+ list->num = 0;
+ list->strs = NULL;
+ return (FRU_SUCCESS);
+ }
+
+ // allocate the memory for the names.
+ rc_list.num = 0;
+ rc_list.strs = (char **)malloc(num_tags * sizeof (char *));
+ if (rc_list.strs == NULL) {
+ CHK_UNLOCK_CONTAINER(container);
+ free(tags);
+ return (FRU_FAILURE);
+ }
+
+ // for each tag fill in it's name.
+ for (i = 0; i < num_tags; i++) {
+ const fru_regdef_t *def = fru_reg_lookup_def_by_tag(tags[i]);
+ if (def != NULL) {
+ rc_list.strs[i] = strdup(def->name);
+ if (rc_list.strs[i] == NULL) {
+ CHK_UNLOCK_CONTAINER(container);
+ fru_destroy_strlist(&rc_list);
+ free(tags);
+ return (FRU_FAILURE);
+ }
+ } else {
+ // instead of failing return "UNKNOWN"
+ rc_list.strs[i] = strdup(UNKNOWN_PATH);
+ if (rc_list.strs[i] == NULL) {
+ CHK_UNLOCK_CONTAINER(container);
+ fru_destroy_strlist(&rc_list);
+ free(tags);
+ return (FRU_FAILURE);
+ }
+ }
+ rc_list.num++;
+ }
+
+ CHK_UNLOCK_CONTAINER(container);
+ list->num = rc_list.num;
+ list->strs = rc_list.strs;
+ free(tags);
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+/* Project-private interface */
+extern "C" fru_errno_t
+fru_for_each_segment(fru_nodehdl_t container,
+ int (*function)(fru_seghdl_t segment, void *args),
+ void *args)
+{
+ fru_errno_t status;
+
+
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ if (lock_container(READ_LOCK, container) != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+
+ status = data_source->for_each_segment(NODEHDL_TO_TREEHDL(container),
+ function, args);
+
+ CHK_UNLOCK_CONTAINER(container);
+ return (status);
+}
+
+/* ========================================================================= */
+/*
+ * Project-private interface
+ *
+ * This routine is only safe when called from within fru_for_each_segment()
+ * (which is currently the only way to get a segment handle) so that the
+ * segment's container will be locked
+ */
+fru_errno_t
+fru_get_segment_name(fru_seghdl_t segment, char **name)
+{
+ assert(data_source != NULL);
+ return (data_source->get_segment_name(NODEHDL_TO_TREEHDL(segment),
+ name));
+}
+
+/* ========================================================================= */
+/*
+ * Project-private interface
+ *
+ * This routine is only safe when called from within fru_for_each_segment()
+ * (which is currently the only way to get a segment handle) so that the
+ * segment's container will be locked
+ */
+extern "C" fru_errno_t
+fru_for_each_packet(fru_seghdl_t segment,
+ int (*function)(fru_tag_t *tag, uint8_t *payload,
+ size_t length, void *args),
+ void *args)
+{
+ assert(data_source != NULL);
+ return (data_source->for_each_packet(NODEHDL_TO_TREEHDL(segment),
+ function, args));
+}
+
+
+/* ========================================================================= */
+// To keep track of the number of instances for each type of tag which
+// might occur.
+struct TagInstPair
+{
+ int inst;
+ fru_tag_t tag;
+};
+
+struct tag_inst_hist_t
+{
+ TagInstPair *pairs;
+ unsigned size;
+ unsigned numStored;
+};
+
+static fru_errno_t
+update_tag_inst_hist(tag_inst_hist_t *hist, fru_tag_t tag)
+{
+ // find if this tag has occured before.
+ int found = 0;
+ for (int s = 0; s < (hist->numStored); s++) {
+ if (tags_equal((hist->pairs)[s].tag, tag)) {
+ // if so just add to the instance.
+ hist->pairs[s].inst++;
+ found = 1;
+ break;
+ }
+ }
+ // if not add to the end of the array of instance 0.
+ if (!found) {
+ if (hist->numStored > hist->size) {
+ return (FRU_FAILURE);
+ }
+ (hist->pairs)[(hist->numStored)].tag.raw_data = tag.raw_data;
+ (hist->pairs)[(hist->numStored)].inst = 0;
+ (hist->numStored)++;
+ }
+ return (FRU_SUCCESS);
+}
+
+static fru_errno_t
+get_tag_inst_from_hist(tag_inst_hist_t *hist, fru_tag_t tag, int *instance)
+{
+ int j = 0;
+ for (j = 0; j < hist->numStored; j++) {
+ if (tags_equal((hist->pairs)[j].tag, tag)) {
+ *instance = (hist->pairs)[j].inst;
+ return (FRU_SUCCESS);
+ }
+ }
+ return (FRU_FAILURE);
+}
+
+/* ========================================================================= */
+// Input:
+// a list of tags and number of them
+// and an instance of the unknown payload you are looking for.
+// Returns:
+// on FRU_SUCCESS
+// instance == the instance of the tag "tag" to read from the list
+// else
+// instance == the number of instances remaining.
+//
+static fru_errno_t
+find_unknown_element(fru_tag_t *tags, int num_tags,
+ int *instance, fru_tag_t *tag)
+{
+ fru_errno_t err = FRU_SUCCESS;
+
+ tag_inst_hist_t hist;
+ hist.pairs = (TagInstPair *)alloca(sizeof (TagInstPair) * num_tags);
+ if (hist.pairs == NULL) {
+ return (FRU_FAILURE);
+ }
+ hist.numStored = 0;
+ hist.size = num_tags;
+
+ // search all the tags untill they are exhausted or we find
+ // the instance we want.
+ int found = 0;
+ int instFound = 0;
+ // NOTE: instancesFound is a running total of the instances in the tags
+ // WE SKIPED!
+ // (ie instances left over == instance - instancesFound)
+
+ int i = 0;
+ for (i = 0; i < num_tags; i++) {
+
+ const fru_regdef_t *def = fru_reg_lookup_def_by_tag(tags[i]);
+ // unknown tag encountered.
+ if (def == NULL) {
+ if (update_tag_inst_hist(&hist, tags[i])
+ != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+ // do this check because everything is 0 based.
+ // if we do the add before the check we will go
+ // to far.
+ if ((instFound + 1) > (*instance)) {
+ found = 1;
+ break;
+ } else {
+ instFound++;
+ }
+ }
+ }
+
+ *instance -= instFound;
+ if (!found) {
+ return (FRU_DATANOTFOUND);
+ }
+
+ (*tag).raw_data = tags[i].raw_data;
+ if (get_tag_inst_from_hist(&hist, tags[i], instance) != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+
+ return (FRU_SUCCESS);
+}
+
+// Input:
+// a list of tags and number of them
+// a list of Ancestors
+// the instance we are looking for
+// Returns:
+// on FRU_SUCCESS
+// instance == the instance of the field within the payload to read.
+// correct == pointer into ants which is correct.
+// tagInstance == instance of the tag
+// else
+// instance == the number of instances remaining.
+// correct == NULL
+// tagInstance == UNDEFINED
+//
+static fru_errno_t
+find_known_element(fru_tag_t *tags, int num_tags, Ancestor *ants,
+ int *instance, Ancestor **correct,
+ int *tagInstance)
+{
+ int j = 0;
+ Ancestor *cur = ants;
+ int num_posible = 0;
+ while (cur != NULL) {
+ num_posible++;
+ cur = cur->next;
+ }
+
+ tag_inst_hist_t hist;
+ hist.pairs = (TagInstPair *)alloca(sizeof (TagInstPair) * num_posible);
+ hist.size = num_posible;
+ if (hist.pairs == NULL) {
+ return (FRU_FAILURE);
+ }
+ hist.numStored = 0;
+
+ *correct = NULL;
+ int i = 0;
+ int found = 0;
+ int instancesFound = 0;
+ // NOTE: instancesFound is a running total of the instances in the tags
+ // WE SKIPED!
+ // (ie instances left over == instance - instancesFound)
+ for (i = 0; i < num_tags; i++) {
+ cur = ants;
+ while (cur != NULL) {
+ if (tags_equal(cur->getTag(), tags[i])) {
+ if (update_tag_inst_hist(&hist, tags[i])
+ != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+
+ // do this check because everything is 0 based.
+ // if we do the add before the check we will go
+ // to far.
+ if ((instancesFound + cur->getNumInstances())
+ > (*instance)) {
+ *correct = cur;
+ found = 1;
+ break; /* while loop */
+ }
+ instancesFound += cur->getNumInstances();
+ }
+ cur = cur->next;
+ }
+ /* when found break out of both "for" and "while" loops */
+ if (found == 1) {
+ break; /* for loop */
+ }
+ }
+
+ *instance -= instancesFound;
+ if (!found) {
+ return (FRU_DATANOTFOUND);
+ }
+
+ if (get_tag_inst_from_hist(&hist, tags[i], tagInstance)
+ != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+
+ return (FRU_SUCCESS);
+}
+
+/*
+ * Same as find_known_element but ONLY searches for absolute paths
+ * (ie PathDef->head == tag)
+ */
+static fru_errno_t
+find_known_element_abs(fru_tag_t *tags, int num_tags, int *instance,
+ PathDef *head, Ancestor *ants, Ancestor **correct,
+ int *tagInstance)
+{
+ *correct = NULL;
+ // find the exact ancestor we want.
+ Ancestor *cur = ants;
+ while (cur != NULL) {
+ if (strcmp(cur->getDef()->name, head->def->name) == 0) {
+ *correct = cur;
+ break;
+ }
+ cur = cur->next;
+ }
+ if (cur == NULL) {
+ // serious parser bug might cause this, double check.
+ return (FRU_FAILURE);
+ }
+
+ int found = 0;
+ (*tagInstance) = 0;
+ for (int i = 0; i < num_tags; i++) {
+ if (tags_equal(cur->getTag(), tags[i])) {
+ // do this check because everything is 0 based.
+ // if we do the add before the check we will go
+ // to far.
+ if (((*tagInstance) +1) > (*instance)) {
+ *correct = cur;
+ found = 1;
+ break;
+ }
+ (*tagInstance)++;
+ }
+ }
+
+ *instance -= (*tagInstance);
+ if (!found) {
+ return (FRU_DATANOTFOUND);
+ }
+
+ return (FRU_SUCCESS);
+}
+
+
+/* ========================================================================= */
+// From the container, seg_name, instance, and field_path get me...
+// pathDef: A linked list of Path Def objects which represent the
+// field_path
+// ancestors: A linked list of Tagged Ancestors which represent the
+// possible payloads this data MAY reside in.
+// correct: A pointer into the above list which indicates the Ancestor
+// in which this instance actually resides.
+// tagInstance: The instance of this ancestor in the segment. (ie Tag
+// instance)
+// instWICur: The instance of this element within the tag itself.
+// Or in other words "the instances left"
+// payload: The payload data
+//
+// For an "UNKNOWN" payload this will return NULL for the pathDef, ancestors,
+// cur pointers. This will indicate to read that this payload should be
+// returned with a special definition for it (UNKNOWN)... What a HACK I
+// know...
+#define READ_MODE 0
+#define UPDATE_MODE 1
+static fru_errno_t get_payload(fru_nodehdl_t container,
+ const char *seg_name,
+ int instance,
+ const char *field_path,
+ // returns the following...
+ PathDef **pathDef,
+ Ancestor **ancestors,
+ Ancestor **correct,
+ int *tagInstance, // instance of the tag within the seg
+ int *instLeft, // within this payload
+ uint8_t **payload,
+ size_t *payloadLen,
+ int mode)
+{
+ int abs_path_flg = 0;
+ fru_errno_t err = FRU_SUCCESS;
+ int num_tags = 0;
+ fru_tag_t *tags = NULL;
+
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+ if ((err = data_source->get_tag_list(NODEHDL_TO_TREEHDL(container),
+ seg_name, &tags, &num_tags))
+ != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if (num_tags == 0) {
+ *instLeft = instance;
+ return (FRU_DATANOTFOUND);
+ }
+
+ if (IS_UNKNOWN_PATH(field_path)) {
+ fru_tag_t tagToRead;
+
+ *pathDef = NULL;
+ *correct = *ancestors = NULL;
+ *tagInstance = 0;
+
+ int unknown_inst = instance;
+ if ((err = find_unknown_element(tags, num_tags, &unknown_inst,
+ &tagToRead)) != FRU_SUCCESS) {
+ *instLeft = unknown_inst;
+ free(tags);
+ return (err);
+ }
+
+ err = data_source->get_tag_data(NODEHDL_TO_TREEHDL(container),
+ seg_name, tagToRead, unknown_inst,
+ payload, payloadLen);
+ free(tags);
+ return (err);
+ }
+
+ err = fru_field_parser(field_path, ancestors,
+ &abs_path_flg, pathDef);
+
+ if (err != FRU_SUCCESS) {
+ free(tags);
+ return (err);
+ } else if (ancestors == NULL) {
+ /* without valid ancestors we can't find payloads for this */
+ free(tags);
+ delete pathDef;
+ return (FRU_INVALELEMENT);
+ }
+
+ if ((mode == UPDATE_MODE) && (abs_path_flg != 1)) {
+ free(tags);
+ delete *ancestors; // linked list
+ delete *pathDef;
+ return (FRU_INVALPATH);
+ }
+
+ if (abs_path_flg == 1) {
+ if ((err = find_known_element_abs(tags, num_tags, &instance,
+ *pathDef, *ancestors, correct, tagInstance))
+ != FRU_SUCCESS) {
+ // set up to search next segment for instances left
+ // over
+ *instLeft = instance;
+ free(tags);
+ delete *ancestors; // linked list
+ delete *pathDef;
+ return (err);
+ }
+ } else {
+ if ((err = find_known_element(tags, num_tags, *ancestors,
+ &instance, correct, tagInstance))
+ != FRU_SUCCESS) {
+ // set up to search next segment for instances left
+ // over
+ *instLeft = instance;
+ free(tags);
+ delete *ancestors; // linked list
+ delete *pathDef;
+ return (err);
+ }
+ }
+
+ // if we get here this means the instance number within the payload.
+ *instLeft = instance;
+
+ if ((err = data_source->get_tag_data(NODEHDL_TO_TREEHDL(container),
+ seg_name, (*correct)->getTag(),
+ (*tagInstance),
+ payload, payloadLen))
+ != FRU_SUCCESS) {
+ free(tags);
+ delete *ancestors; // linked list
+ delete *pathDef;
+ return (err);
+ }
+
+ free(tags);
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+/*
+ * Handle decryption if necessary
+ */
+static fru_errno_t
+do_decryption(fru_nodehdl_t container, const char *seg_name,
+ uint8_t *payload, size_t payloadLen)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ if (segment_is_encrypted(container, seg_name)) {
+ if (fru_encryption_supported() == FRU_SUCCESS) {
+ if ((err = encrypt_func(FRU_DECRYPT,
+ payload, payloadLen)) != FRU_SUCCESS) {
+ return (err);
+ }
+ } else {
+ return (FRU_FAILURE);
+ }
+ }
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+// Same as get_payload except if seg_name is NULL and it will find the one
+// used and return it.
+//
+static fru_errno_t
+get_seg_and_payload(fru_nodehdl_t container,
+ char **seg_name,
+ int instance,
+ const char *field_path,
+ // returns the following...
+ PathDef **pathDef,
+ Ancestor **ancestors,
+ Ancestor **correct,
+ int *tagInstance, // within the segment.
+ int *instLeft, // within this payload
+ uint8_t **payload,
+ size_t *payloadLen)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ if ((err = is_container(container)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if (field_path == NULL)
+ return (FRU_INVALPATH);
+
+ if ((*seg_name) != NULL) {
+
+ // always check for valid segment names.
+ if (strlen((const char *)(*seg_name)) > FRU_SEGNAMELEN) {
+ return (FRU_INVALSEG);
+ }
+
+ if ((err = get_payload(container, (const char *)(*seg_name),
+ instance, field_path, pathDef, ancestors, correct,
+ tagInstance, instLeft, payload, payloadLen, READ_MODE))
+ != FRU_SUCCESS) {
+ return (err);
+ }
+ return (do_decryption(container, (const char *)(*seg_name),
+ *payload, *payloadLen));
+
+ } else {
+ fru_strlist_t seg_list;
+
+ if ((err = get_seg_list_from_ds(container, &seg_list))
+ != FRU_SUCCESS) {
+ return (err);
+ }
+
+ int found = 0;
+ for (int i = 0; i < seg_list.num; i++) {
+ err = get_payload(container,
+ seg_list.strs[i],
+ instance, field_path,
+ pathDef, ancestors, correct,
+ tagInstance, instLeft,
+ payload, payloadLen, READ_MODE);
+ if (err == FRU_SUCCESS) {
+ (*seg_name) = strdup(seg_list.strs[i]);
+ fru_destroy_strlist(&seg_list);
+ return (do_decryption(container,
+ (const char *)(*seg_name),
+ *payload, *payloadLen));
+ } else if (err == FRU_DATANOTFOUND) {
+ // we may have found some instances or none at
+ // all but not enough all together. search
+ // again with the # of instances left.
+ instance = *instLeft;
+ } else {
+ fru_destroy_strlist(&seg_list);
+ return (err);
+ }
+ }
+ fru_destroy_strlist(&seg_list);
+ return (FRU_DATANOTFOUND);
+ }
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_read_field(fru_nodehdl_t container,
+ char **seg_name, unsigned int instance,
+ const char *field_path,
+ void **data, size_t *data_len,
+ char **found_path)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ // just init this value for the user
+ *data = NULL;
+ *data_len = 0;
+
+ if (lock_container(READ_LOCK, container) != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+ PathDef *pathDef;
+ Ancestor *ancestors;
+ Ancestor *correctAnt;
+ int tagInstance = 0;
+ int instWIPayload = 0;
+ uint8_t *payload;
+ size_t payloadLen = 0;
+ err = get_seg_and_payload(container, seg_name, instance, field_path,
+ &pathDef, &ancestors, &correctAnt, &tagInstance,
+ &instWIPayload, &payload, &payloadLen);
+
+ CHK_UNLOCK_CONTAINER(container);
+
+ if (err != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if (pathDef == NULL) { // SPECIAL CASE of UNKNOW payload.
+ delete ancestors;
+ delete pathDef;
+ free(payload);
+
+ *data = (void *)malloc(payloadLen);
+ if ((*data) == NULL) {
+ return (FRU_FAILURE);
+ }
+ memcpy(*data, payload, payloadLen);
+ *data_len = payloadLen;
+ if (found_path != NULL) {
+ *found_path = strdup(UNKNOWN_PATH);
+ }
+ return (FRU_SUCCESS);
+ }
+
+ // get the specific data
+ err = PayloadReader::readData(pathDef, correctAnt,
+ instWIPayload,
+ payload, payloadLen,
+ data, data_len);
+ delete pathDef;
+ free(payload);
+
+ if (err == FRU_SUCCESS) {
+ if (found_path != NULL) {
+ *found_path = (char *)malloc(
+ strlen(correctAnt->getPath(instWIPayload))
+ + strlen(field_path) + 2);
+ if ((*found_path) == NULL) {
+ delete ancestors;
+ return (FRU_FAILURE);
+ }
+ sprintf(*found_path, "%s%s",
+ correctAnt->getPath(instWIPayload),
+ field_path);
+ }
+ }
+
+ delete ancestors;
+ return (err);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_update_field(fru_nodehdl_t container,
+ char *seg_name, unsigned int instance,
+ const char *field_path,
+ void *data, size_t length)
+{
+ fru_errno_t err = FRU_SUCCESS;
+
+ if ((field_path == NULL) || IS_UNKNOWN_PATH(field_path)) {
+ return (FRU_INVALPATH);
+ } else if (seg_name == NULL) {
+ return (FRU_INVALSEG);
+ }
+
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ if (lock_container(WRITE_LOCK, container) != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+ PathDef *pathDef;
+ Ancestor *ancestors;
+ Ancestor *correctAnt;
+ int tagInstance = 0;
+ int instWIPayload = 0;
+ uint8_t *payload;
+ size_t payloadLen = 0;
+ err = get_payload(container, seg_name, instance, field_path,
+ &pathDef, &ancestors, &correctAnt, &tagInstance,
+ &instWIPayload, &payload, &payloadLen, UPDATE_MODE);
+
+ if (err != FRU_SUCCESS) {
+ CHK_UNLOCK_CONTAINER(container);
+ return (err);
+ }
+
+ if ((err = do_decryption(container, (const char *)seg_name,
+ payload, payloadLen)) != FRU_SUCCESS) {
+ free(payload);
+ return (err);
+ }
+
+ // fill in the new data in the payload
+ err = PayloadReader::updateData(pathDef, correctAnt, instWIPayload,
+ payload, payloadLen,
+ data, length);
+
+ if (err != FRU_SUCCESS) {
+ CHK_UNLOCK_CONTAINER(container);
+ delete ancestors; // linked list.
+ delete pathDef;
+ free(payload);
+ return (err);
+ }
+
+ if ((segment_is_encrypted(container, seg_name)) &&
+ (fru_encryption_supported() == FRU_SUCCESS)) {
+ if ((err = encrypt_func(FRU_ENCRYPT, payload, payloadLen))
+ != FRU_SUCCESS) {
+ CHK_UNLOCK_CONTAINER(container);
+ delete ancestors; // linked list.
+ delete pathDef;
+ free(payload);
+ return (err);
+ }
+ }
+
+ err = data_source->set_tag_data(NODEHDL_TO_TREEHDL(container),
+ seg_name,
+ correctAnt->getTag(), tagInstance,
+ payload, payloadLen);
+
+ CHK_UNLOCK_CONTAINER(container);
+ delete ancestors; // linked list.
+ free(payload);
+ delete pathDef;
+ return (err);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_get_num_iterations(fru_nodehdl_t container,
+ char **seg_name,
+ unsigned int instance,
+ const char *iter_path,
+ int *num_there,
+ char **found_path)
+{
+ // this ensures a more descriptive error message.
+ fru_errno_t err = FRU_SUCCESS;
+
+ if (lock_container(READ_LOCK, container) != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+ PathDef *pathDef;
+ Ancestor *ancestors;
+ Ancestor *correctAnt;
+ int tagInstance = 0;
+ int instWIPayload = 0;
+ uint8_t *payload;
+ size_t payloadLen = 0;
+ err = get_seg_and_payload(container, seg_name, instance, iter_path,
+ &pathDef, &ancestors, &correctAnt, &tagInstance,
+ &instWIPayload, &payload, &payloadLen);
+
+ CHK_UNLOCK_CONTAINER(container);
+
+ if (err != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if (pathDef == NULL) { // SPECIAL CASE of UNKNOW payload.
+ // clean up memory from called functions.
+ err = FRU_INVALPATH;
+ } else {
+ // get the specific data
+ err = PayloadReader::findIterThere(pathDef, correctAnt,
+ instWIPayload,
+ payload, payloadLen,
+ num_there);
+ }
+
+ delete pathDef;
+ free(payload);
+
+ if (err == FRU_SUCCESS) {
+ if (found_path != NULL) {
+ *found_path = (char *)malloc(
+ strlen(correctAnt->getPath(instWIPayload))
+ + strlen(iter_path) + 2);
+ if ((*found_path) == NULL) {
+ delete ancestors;
+ return (FRU_FAILURE);
+ }
+ sprintf(*found_path, "%s%s",
+ correctAnt->getPath(instWIPayload),
+ iter_path);
+ }
+ }
+
+ delete ancestors;
+ return (err);
+}
+
+/* ========================================================================= */
+// When adding a new payload with 0 data the iteration control bytes must be
+// filled in with the number possible.
+fru_errno_t
+fill_in_iteration_control_bytes(uint8_t *data,
+ const fru_regdef_t *def,
+ int inIteration)
+{
+ fru_errno_t rc = FRU_SUCCESS;
+
+ if ((def->iterationType == FRU_NOT_ITERATED) ||
+ (inIteration)) {
+
+ if (def->dataType == FDTYPE_Record) {
+
+ int offset = 0;
+ for (int i = 0; i < def->enumCount; i++) {
+ const fru_regdef_t *newDef
+ = fru_reg_lookup_def_by_name((char *)def->enumTable[i].text);
+ fru_errno_t rc2
+ = fill_in_iteration_control_bytes(&(data[offset]), newDef, 0);
+ if (rc2 != FRU_SUCCESS)
+ return (rc2);
+ offset += newDef->payloadLen;
+ }
+
+ } // else field, no sub elements; do nothing... ;-)
+
+ } else {
+ data[3] = (char)def->iterationCount;
+
+ int offset = 3;
+ for (int i = 0; i < def->iterationCount; i++) {
+ fru_errno_t rc3
+ = fill_in_iteration_control_bytes(&(data[offset]), def, 1);
+ if (rc3 != FRU_SUCCESS)
+ return (rc3);
+ offset += ((def->payloadLen - 4)/(def->iterationCount));
+ }
+ }
+
+ return (rc);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_add_element(fru_nodehdl_t container,
+ const char *seg_name,
+ const char *element)
+{
+ fru_errno_t err = FRU_SUCCESS;
+
+ if ((seg_name == NULL) || (strlen(seg_name) > FRU_SEGNAMELEN)) {
+ return (FRU_INVALSEG);
+ }
+
+ const fru_regdef_t *def
+ = fru_reg_lookup_def_by_name((char *)element);
+ if (def == NULL) {
+ return (FRU_NOREGDEF);
+ }
+ if (def->tagType == FRU_X) {
+ return (FRU_ELEMNOTTAGGED);
+ }
+
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ if ((err = is_container(container)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if (lock_container(WRITE_LOCK, container) != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+
+ fru_tag_t tag;
+ mk_tag(def->tagType, def->tagDense, def->payloadLen, &tag);
+ uint8_t *data = new uint8_t[def->payloadLen];
+ memset(data, 0x00, def->payloadLen);
+
+ err = fill_in_iteration_control_bytes(data, def, 0);
+ if (err != FRU_SUCCESS) {
+ CHK_UNLOCK_CONTAINER(container);
+ delete[] data;
+ return (err);
+ }
+
+ if (segment_is_encrypted(container, seg_name)) {
+ if (fru_encryption_supported() == FRU_NOTSUP) {
+ CHK_UNLOCK_CONTAINER(container);
+ delete[] data;
+ return (FRU_INVALSEG);
+ }
+ if ((err = encrypt_func(FRU_ENCRYPT, data,
+ def->payloadLen)) != FRU_SUCCESS) {
+ CHK_UNLOCK_CONTAINER(container);
+ delete[] data;
+ return (err);
+ }
+ }
+
+ err = data_source->add_tag_to_seg(NODEHDL_TO_TREEHDL(container),
+ seg_name, tag,
+ data, def->payloadLen);
+
+ CHK_UNLOCK_CONTAINER(container);
+ delete[] data;
+ return (err);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_delete_element(fru_nodehdl_t container,
+ const char *seg_name,
+ unsigned int instance,
+ const char *element)
+{
+ fru_errno_t err = FRU_SUCCESS;
+
+ if ((seg_name == NULL) || (strlen(seg_name) > FRU_SEGNAMELEN)) {
+ return (FRU_INVALSEG);
+ }
+
+ if (data_source == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ if ((err = is_container(container)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if (lock_container(WRITE_LOCK, container) != FRU_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+ if ((segment_is_encrypted(container, seg_name)) &&
+ (fru_encryption_supported() == FRU_NOTSUP)) {
+ CHK_UNLOCK_CONTAINER(container);
+ return (FRU_INVALSEG);
+ }
+
+ fru_tag_t tag;
+ int localInst = instance;
+ // again the special case of UNKNOWN. This allows us to delete these
+ // elements if they are somehow not wanted.
+ // NOTE: "/UNKNOWN" is not supported just as "/ManR" would not be valid
+ // either. Both of these will result in returning FRU_NOREGDEF
+ if (strcmp(element, "UNKNOWN") == 0) {
+ fru_tag_t *tags = NULL;
+ int num_tags = 0;
+
+ if ((err = data_source->get_tag_list(
+ NODEHDL_TO_TREEHDL(container),
+ seg_name, &tags, &num_tags))
+ != FRU_SUCCESS) {
+ CHK_UNLOCK_CONTAINER(container);
+ return (err);
+ }
+ if ((err = find_unknown_element(tags, num_tags,
+ &localInst, &tag)) != FRU_SUCCESS) {
+ free(tags);
+ CHK_UNLOCK_CONTAINER(container);
+ return (err);
+ }
+ free(tags);
+ } else {
+ const fru_regdef_t *def
+ = fru_reg_lookup_def_by_name((char *)element);
+ if (def == NULL) {
+ CHK_UNLOCK_CONTAINER(container);
+ return (FRU_NOREGDEF);
+ }
+ if (def->tagType == FRU_X) {
+ CHK_UNLOCK_CONTAINER(container);
+ return (FRU_ELEMNOTTAGGED);
+ }
+ mk_tag(def->tagType, def->tagDense, def->payloadLen, &tag);
+ }
+
+ err = data_source->delete_tag(NODEHDL_TO_TREEHDL(container), seg_name,
+ tag, instance);
+ CHK_UNLOCK_CONTAINER(container);
+ return (err);
+}
+
+/* General library support */
+/* ========================================================================= */
+static fru_errno_t
+make_definition(const fru_regdef_t *def, fru_elemdef_t *definition)
+{
+ definition->version = FRU_ELEMDEF_REV;
+ definition->data_type = def->dataType;
+ if (def->tagType != FRU_X)
+ definition->tagged = FRU_Yes;
+ else
+ definition->tagged = FRU_No;
+
+ // zzz
+ // This should be the following statement.
+ // (*definition)->data_length = def->dataLength;
+ // instead of.
+ if (def->iterationType != FRU_NOT_ITERATED) {
+ int elemLen = ((def->dataLength-4)/def->iterationCount);
+ definition->data_length = elemLen;
+ } else {
+ definition->data_length = def->dataLength;
+ }
+ // END zzz
+
+ definition->disp_type = def->dispType;
+ definition->purgeable = def->purgeable;
+ definition->relocatable = def->relocatable;
+
+ definition->enum_count = 0;
+ definition->enum_table = NULL;
+
+ unsigned int count = def->enumCount;
+ if (count != 0) {
+ definition->enum_table = (fru_enum_t *)malloc(
+ (sizeof (fru_enum_t)) * count);
+ if ((definition->enum_table) == NULL) {
+ return (FRU_FAILURE);
+ }
+ memset(definition->enum_table, 0x00,
+ ((sizeof (fru_enum_t)) * count));
+ }
+
+ for (int i = 0; i < count; i++) {
+ definition->enum_table[i].value = def->enumTable[i].value;
+ definition->enum_table[i].text = strdup(def->enumTable[i].text);
+ if ((definition->enum_table[i].text) == NULL) {
+ fru_destroy_elemdef(definition);
+ return (FRU_FAILURE);
+ }
+ (definition->enum_count)++;
+ }
+
+ definition->iteration_count = def->iterationCount;
+ definition->iteration_type = def->iterationType;
+
+ definition->example_string = strdup(def->exampleString);
+ if ((definition->example_string) == NULL) {
+ fru_destroy_elemdef(definition);
+ return (FRU_FAILURE);
+ }
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_get_definition(const char *element_name,
+ fru_elemdef_t *definition)
+{
+ // find the last one in the string...
+ int abs_path_flg = 0;
+ Ancestor *ancestors = NULL;
+ PathDef *pathDef = NULL;
+ fru_errno_t err = FRU_SUCCESS;
+
+ err = fru_field_parser(element_name, &ancestors,
+ &abs_path_flg, &pathDef);
+ if (err != FRU_SUCCESS) {
+ return (err);
+ }
+
+ PathDef *last = pathDef;
+ while (last->next != NULL)
+ last = last->next;
+
+ err = make_definition(last->def, definition);
+
+ delete ancestors;
+ delete pathDef;
+ return (err);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_get_registry(fru_strlist_t *list)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ unsigned int number = 0;
+ char **entries = fru_reg_list_entries(&number);
+ if (entries == NULL) {
+ return (FRU_FAILURE);
+ }
+ list->strs = entries;
+ list->num = number;
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+fru_errno_t
+fru_get_tagged_parents(const char *element, fru_strlist_t *parents)
+{
+ Ancestor *ancestors
+ = Ancestor::listTaggedAncestors((char *)element);
+
+ Ancestor *cur = ancestors;
+ /* count them */
+ int number = 0;
+ while (cur != NULL) {
+ number++;
+ cur = cur->next;
+ }
+
+ parents->num = 0;
+ parents->strs = NULL;
+ if (number == 0) {
+ return (FRU_SUCCESS);
+ }
+ parents->strs = (char **)malloc(number * sizeof (char *));
+ if (parents->strs == NULL) {
+ return (FRU_FAILURE);
+ }
+ memset(parents->strs, 0x00, (number * sizeof (char *)));
+
+ cur = ancestors;
+ for (int i = 0; i < number; i++) {
+ if (cur == NULL) {
+ fru_destroy_strlist(parents);
+ return (FRU_FAILURE);
+ }
+ parents->strs[i] = strdup(cur->getDef()->name);
+ if (parents->strs[i] == NULL) {
+ fru_destroy_strlist(parents);
+ return (FRU_FAILURE);
+ }
+ parents->num++;
+ cur = cur->next;
+ }
+
+ return (FRU_SUCCESS);
+}
+
+/*
+ * Enum string converters.
+ */
+/* ========================================================================= */
+const char *
+get_displaytype_str(fru_displaytype_t e)
+{
+ switch (e) {
+ case FDISP_Binary:
+ return (gettext("Binary"));
+ case FDISP_Hex:
+ return (gettext("Hex"));
+ case FDISP_Decimal:
+ return (gettext("Decimal"));
+ case FDISP_Octal:
+ return (gettext("Octal"));
+ case FDISP_String:
+ return (gettext("String"));
+ case FDISP_Time:
+ return (gettext("Time"));
+ case FDISP_UNDEFINED:
+ return (gettext("UNDEFINED"));
+ }
+ return (gettext("UNDEFINED"));
+}
+
+/* ========================================================================= */
+const char *
+get_datatype_str(fru_datatype_t e)
+{
+ switch (e) {
+ case FDTYPE_Binary:
+ return (gettext("Binary"));
+ case FDTYPE_ByteArray:
+ return (gettext("Byte Array"));
+ case FDTYPE_ASCII:
+ return (gettext("ASCII"));
+ case FDTYPE_Unicode:
+ return (gettext("Unicode"));
+ case FDTYPE_Record:
+ return (gettext("Record"));
+ case FDTYPE_Enumeration:
+ return (gettext("Enumeration"));
+ case FDTYPE_UNDEFINED:
+ return (gettext("UNDEFINED"));
+ }
+ return (gettext("UNDEFINED"));
+}
+/* ========================================================================= */
+const char *
+get_which_str(fru_which_t e)
+{
+ switch (e) {
+ case FRU_No:
+ return (gettext("No"));
+ case FRU_Yes:
+ return (gettext("Yes"));
+ case FRU_WHICH_UNDEFINED:
+ return (gettext("WHICH UNDEFINED"));
+ }
+ return (gettext("WHICH UNDEFINED"));
+}
+/* ========================================================================= */
+const char *
+get_itertype_str(fru_itertype_t e)
+{
+ switch (e) {
+ case FRU_FIFO:
+ return (gettext("FIFO"));
+ case FRU_Circular:
+ return (gettext("Circular"));
+ case FRU_Linear:
+ return (gettext("Linear"));
+ case FRU_LIFO:
+ return (gettext("LIFO"));
+ case FRU_NOT_ITERATED:
+ return (gettext("NOT ITERATED"));
+ }
+ return (gettext("NOT ITERATED"));
+}
diff --git a/usr/src/lib/libfru/libfru/nameSyntaxLex.l b/usr/src/lib/libfru/libfru/nameSyntaxLex.l
new file mode 100644
index 0000000000..dbb21a8e18
--- /dev/null
+++ b/usr/src/lib/libfru/libfru/nameSyntaxLex.l
@@ -0,0 +1,64 @@
+%{
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright (c) 2000 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <string.h>
+
+/* this is the lexer for the libfru NamingSyntax */
+/* parser.h MUST occur before nameSyntax.tab.h */
+#include "Parser.h"
+
+extern char *gParserString;
+
+#undef input
+#undef unput
+#define input()(*gParserString++)
+#define unput(c)(*--gParserString=c)
+
+#undef lex_input
+#define lex_input()(*gParserString++)
+
+#include "y.tab.h"
+
+/* Keep the separator symbols here because the lexer is the only one who knows
+ * about the string being parsed. */
+
+%}
+
+%%
+
+"$" { return LAST; }
+"+" { return ADD; }
+"/" { return SEPIDENT; }
+"[" { return ITERBEGIN; }
+"]" { return ITEREND; }
+
+[0-9]+ { yylval.num = atoi (yytext); return NUMBER; }
+[_a-zA-Z0-9]+ { yylval.name = strdup(yytext); return NAME; }
+
+%%
+
diff --git a/usr/src/lib/libfru/libfru/nameSyntaxYacc.y b/usr/src/lib/libfru/libfru/nameSyntaxYacc.y
new file mode 100644
index 0000000000..34c5aa7ae0
--- /dev/null
+++ b/usr/src/lib/libfru/libfru/nameSyntaxYacc.y
@@ -0,0 +1,184 @@
+%{
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/* This is the yacc grammar for the libfru NamingSyntax */
+#include <assert.h>
+#include <stdio.h>
+
+#include "Parser.h"
+
+//#define YYDEBUG 1
+
+// Parser Globals.
+extern fru_errno_t gParserErrno;
+extern char *gParserString;
+extern Ancestor *gParserAnts;
+extern PathDef *gParserHead;
+extern int *gParserAbs;
+
+extern void yyerror (const char *msg);
+extern int yylex (void);
+
+%}
+
+%union {
+ int num;
+ char *name;
+ PathDef *pathDef;
+}
+
+%token SEPIDENT ITERBEGIN ITEREND
+%token LAST ADD
+%token <num> NUMBER
+%token <name> NAME
+
+%type <pathDef> recordpath element
+%type <num> itercount
+
+%left SEPIDENT
+
+%%
+fullpath : recordpath
+ {
+ gParserHead = $1;
+ gParserAnts
+ = Ancestor::listTaggedAncestors((char *)$1->def->name);
+ }
+ ;
+
+recordpath : element
+ {
+ $$ = $1;
+ }
+ | element SEPIDENT recordpath
+ {
+ if ($1->def->dataType != FDTYPE_Record)
+ {
+ yyerror (NULL);
+ YYABORT;
+ }
+ int found = 0;
+ for ( int i=0;i<$1->def->enumCount;i++)
+ {
+ if ( strcmp ($3->def->name, $1->def->enumTable[i].text) == 0 )
+ found = 1;
+ }
+ if ( !found )
+ {
+ yyerror (NULL);
+ YYABORT;
+ }
+ // insert it in the list.
+ $1->next = $3;
+ // return the head of the list.
+ $$ = $1;
+ }
+ | SEPIDENT recordpath
+ {
+ // absolute path definitions MUST start with tagged elements.
+ if ( $2->def->tagType == FRU_X )
+ {
+ yyerror ("First Element of absolute path MUST be tagged");
+ YYABORT;
+ }
+ *gParserAbs = 1;
+ $$ = $2;
+ }
+ ;
+
+element : NAME
+ {
+ const fru_regdef_t *def = fru_reg_lookup_def_by_name($1);
+ if ( def == NULL )
+ {
+ yyerror (NULL);
+ gParserErrno = FRU_NOREGDEF;
+ free ($1); // the lexer allocates this memory.
+ YYABORT;
+ }
+ PathDef *pathDef = new PathDef;
+ pathDef->def = (fru_regdef_t *)def;
+ pathDef->iterIndex = 0;
+ pathDef->next = NULL;
+ free ($1); // the lexer allocates this memory.
+ $$ = pathDef;
+ }
+ | NAME ITERBEGIN itercount ITEREND
+ {
+ const fru_regdef_t *def = fru_reg_lookup_def_by_name($1);
+ if ( def == NULL )
+ {
+ yyerror (NULL);
+ gParserErrno = FRU_NOREGDEF;
+ free ($1); // the lexer allocates this memory.
+ YYABORT;
+ }
+ if ( def->iterationType == FRU_NOT_ITERATED )
+ {
+ yyerror (NULL);
+ free ($1); // the lexer allocates this memory.
+ YYABORT;
+ }
+ if ( ($3 != PathDef::lastIteration) &&
+ ($3 != PathDef::addIteration) )
+ {
+ if ( ($3 >= def->iterationCount) || ($3 < 0) )
+ {
+ yyerror (NULL);
+ free ($1); // the lexer allocates this memory.
+ YYABORT;
+ }
+ }
+ PathDef *pathDef = new PathDef;
+ pathDef->def = (fru_regdef_t *)def;
+ pathDef->iterIndex = $3;
+ pathDef->next = NULL;
+ free ($1); // the lexer allocates this memory.
+ $$ = pathDef;
+ }
+ ;
+
+itercount : NUMBER
+ { $$ = $1; }
+ | LAST
+ { $$ = PathDef::lastIteration; }
+ | ADD
+ { $$ = PathDef::addIteration; }
+ ;
+
+%%
+
+void
+yyerror (const char *msg)
+{
+ gParserErrno = FRU_INVALPATH;
+}
+
+// just to override what the library should have done.
+int yywrap (void) { return 1; }
+
diff --git a/usr/src/lib/libfru/libfru/yy-lsed b/usr/src/lib/libfru/libfru/yy-lsed
new file mode 100644
index 0000000000..98f9e67a82
--- /dev/null
+++ b/usr/src/lib/libfru/libfru/yy-lsed
@@ -0,0 +1,63 @@
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+
+s/yyback/fruback/g
+s/yybgin/frubgin/g
+s/yycrank/frucrank/g
+s/yyerror/fruerror/g
+s/yyestate/fruestate/g
+s/yyextra/fruextra/g
+s/yyfnd/frufnd/g
+s/yyin/fruin/g
+s/yyinput/fruinput/g
+s/yyleng/fruleng/g
+s/yylex/frulex/g
+s/yylineno/frulineno/g
+s/yylook/frulook/g
+s/yylsp/frulsp/g
+s/yylstate/frulstate/g
+s/yytext/frutext/g
+s/yylval/frulval/g
+s/yymatch/frumatch/g
+s/yymorfg/frumorfg/g
+s/yyolsp/fruolsp/g
+s/yyout/fruout/g
+s/yyoutput/fruoutput/g
+s/yyprevious/fruprevious/g
+s/yysbuf/frusbuf/g
+s/yysptr/frusptr/g
+s/yysvec/frusvec/g
+s/yytchar/frutchar/g
+s/yytop/frutop/g
+s/yyunput/fruunput/g
+s/yyvstop/fruvstop/g
+s/yywrap/fruwrap/g
+s/yyracc/fruracc/g
+s/yyreject/frureject/g
+s/yywoutput/fruwoutput/g
+s/yywinput/fruwinput/g
+s/yyless/fruless/g
diff --git a/usr/src/lib/libfru/libfru/yy-sed b/usr/src/lib/libfru/libfru/yy-sed
new file mode 100644
index 0000000000..0aafe96f41
--- /dev/null
+++ b/usr/src/lib/libfru/libfru/yy-sed
@@ -0,0 +1,53 @@
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+
+s/yyact/fruact/g
+s/yychar/fruchar/g
+s/yychk/fruchk/g
+s/yydebug/frudebug/g
+s/yydef/frudef/g
+s/yyerrflag/fruerrflag/g
+s/yyerror/fruerror/g
+s/yyexca/fruexca/g
+s/yylex/frulex/g
+s/yylval/frulval/g
+s/yynerrs/frunerrs/g
+s/yypact/frupact/g
+s/yyparse/fruparse/g
+s/yypgo/frupgo/g
+s/yyps/frups/g
+s/yypv/frupv/g
+s/yyr1/frur1/g
+s/yyr2/frur2/g
+s/yyreds/frureds/g
+s/yys/frus/g
+s/yystate/frustate/g
+s/yytmp/frutmp/g
+s/yytoks/frutoks/g
+s/yyv/fruv/g
+s/yyval/fruval/g
+s/yywrap/fruwrap/g
diff --git a/usr/src/lib/libfru/libfrupicl/Makefile b/usr/src/lib/libfru/libfrupicl/Makefile
new file mode 100644
index 0000000000..cd361c6ba3
--- /dev/null
+++ b/usr/src/lib/libfru/libfrupicl/Makefile
@@ -0,0 +1,68 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2000 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+
+include $(SRC)/lib/Makefile.lib
+
+SUBDIRS = .WAIT $(MACH) $(BUILD64) $(MACH64)
+
+# conditional assignments
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+lint := TARGET= lint
+_msg := TARGET= _msg
+
+sparc_HDRS=
+sparcv9_HDRS=
+i386_HDRS=
+HDRS= $($(MACH)_HDRS)
+ROOTHDRDIR= $(ROOT)/usr/include
+ROOTHDRS= $(HDRS:%=$(ROOTHDRDIR)/%)
+CHECKHDRS= $(HDRS:%.h=%.check)
+
+.KEEP_STATE:
+
+all install clean clobber lint: $(SUBDIRS)
+
+_msg: $(MACH) $(MACH64)
+
+
+$(ROOTHDRDIR)/%: %
+ $(INS.file)
+
+$(ROOTHDRDIR):
+ $(INS.dir)
+
+check: $(CHECKHDRS)
+
+$(MACH) $(MACH64): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
diff --git a/usr/src/lib/libfru/libfrupicl/Makefile.com b/usr/src/lib/libfru/libfrupicl/Makefile.com
new file mode 100644
index 0000000000..c3aecd6eaf
--- /dev/null
+++ b/usr/src/lib/libfru/libfrupicl/Makefile.com
@@ -0,0 +1,94 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY= libfrupicl.a
+VERS= .1
+
+OBJECTS= frupicl.o
+
+# include library definitions
+include $(SRC)/lib/Makefile.lib
+
+SRCS= $(OBJECTS:%.o=../%.c)
+CLOBBERFILES += $(LIBLINKS)
+
+LIBS = $(DYNLIB)
+
+LINTFLAGS = -mnux
+LINTFLAGS64 = $(LINTFLAGS) -Xarch=$(MACH64:sparcv9=v9)
+LINTOUT= lint.out
+LINTSRC = $(LINTLIB:%.ln=%)
+ROOTLINTDIR = $(ROOTLIBDIR)
+ROOTLINT = $(LINTSRC:%=$(ROOTLINTDIR)/%)
+
+CLEANFILES= $(LINTOUT)
+
+CPPFLAGS += -I.. \
+ -I$(SRC)/lib/libfru/include \
+ -I$(SRC)/cmd/picl/plugins/sun4u/frudata \
+ -I$(SRC)/lib/libpicl \
+ -I$(SRC)/lib/libfruutils \
+ -I$(SRC)/cmd/picl/plugins/inc
+CPPFLAGS += -D_REENTRANT
+CFLAGS += $(CCVERBOSE)
+
+$(LINTLIB) := LINTFLAGS = -nvx -I..
+$(LINTLIB) := LINTFLAGS64 = -nvx -Xarch=$(MACH64:sparcv9=v9) -I..
+
+XGETFLAGS += -a
+POFILE= picl.po
+
+.KEEP_STATE:
+
+all : $(LIBS)
+ chmod 755 $(DYNLIB)
+
+lint : lintcheck
+
+%.po: ../%.c
+ $(CP) $< $<.i
+ $(BUILD.po)
+
+_msg: $(MSGDOMAIN) $(POFILE)
+ $(RM) $(MSGDOMAIN)/$(POFILE)
+ $(CP) $(POFILE) $(MSGDOMAIN)
+
+$(DYNLIB): $(MAPFILE)
+
+$(MAPFILE):
+ @cd $(MAPDIR); $(MAKE) mapfile
+
+# include library targets
+include $(SRC)/lib/Makefile.targ
+
+pics/%.o: ../%.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
+
+$(ROOTLINTDIR)/%: ../%
+ $(INS.file)
diff --git a/usr/src/lib/libfru/libfrupicl/frupicl.c b/usr/src/lib/libfru/libfrupicl/frupicl.c
new file mode 100644
index 0000000000..1814a35eb0
--- /dev/null
+++ b/usr/src/lib/libfru/libfrupicl/frupicl.c
@@ -0,0 +1,1180 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <alloca.h>
+#include <picl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include "picldefs.h"
+#include "fru_data.h"
+
+#include "libfruds.h"
+#include "libfrup.h"
+
+/* ========================================================================= */
+#define TREEHDL_TO_PICLHDL(treehdl) ((picl_nodehdl_t)treehdl)
+#define PICLHDL_TO_TREEHDL(piclhdl) ((fru_treehdl_t)piclhdl)
+
+#define TREESEGHDL_TO_PICLHDL(treeseghdl) ((picl_nodehdl_t)treeseghdl)
+#define PICLHDL_TO_TREESEGHDL(piclhdl) ((fru_treeseghdl_t)piclhdl)
+
+/* Cache of the root node for quick checks */
+static picl_nodehdl_t picl_root_node;
+
+
+/* ========================================================================= */
+/*
+ * Map the PICL errors the plugin would give me to FRU errors
+ */
+static fru_errno_t
+map_plugin_err(int picl_err)
+{
+ switch (picl_err) {
+ case PICL_SUCCESS:
+ return (FRU_SUCCESS);
+ case PICL_PERMDENIED:
+ return (FRU_INVALPERM);
+ case PICL_PROPEXISTS:
+ return (FRU_DUPSEG);
+ case PICL_NOSPACE:
+ return (FRU_NOSPACE);
+ }
+ return (FRU_IOERROR);
+}
+
+/* ========================================================================= */
+/*
+ * cause a refresh of the sub-nodes by writing anything to the container
+ * property of the node.
+ */
+static fru_errno_t
+update_data_nodes(picl_nodehdl_t handle)
+{
+ uint32_t container = FRUDATA_DELETE_TAG_KEY;
+ int picl_err = PICL_SUCCESS;
+
+ if ((picl_err = picl_set_propval_by_name(handle,
+ PICL_PROP_CONTAINER, (void *)&container,
+ sizeof (container))) != PICL_SUCCESS) {
+ return (map_plugin_err(picl_err));
+ }
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+/*
+ * picl like function which gets a string property with the proper length
+ * NOTE: returns picl errno values NOT fru_errno_t
+ */
+static int
+get_strprop_by_name(picl_nodehdl_t handle, char *prop_name, char **string)
+{
+ int picl_err = PICL_SUCCESS;
+ picl_prophdl_t proph;
+ picl_propinfo_t prop_info;
+ char *tmp_buf = NULL;
+
+ if ((picl_err = picl_get_propinfo_by_name(handle, prop_name,
+ &prop_info, &proph)) != PICL_SUCCESS) {
+ return (picl_err);
+ }
+
+ tmp_buf = malloc((sizeof (*tmp_buf) * prop_info.size));
+ if (tmp_buf == NULL) {
+ return (PICL_FAILURE);
+ }
+
+ if ((picl_err = picl_get_propval(proph, tmp_buf, prop_info.size))
+ != PICL_SUCCESS) {
+ free(tmp_buf);
+ return (picl_err);
+ }
+
+ *string = tmp_buf;
+ return (PICL_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_name_from_hdl(fru_treehdl_t node, char **name)
+{
+ int picl_err = PICL_SUCCESS;
+ char *tmp_name = NULL;
+ char *label = NULL;
+ picl_nodehdl_t handle = TREEHDL_TO_PICLHDL(node);
+
+ /* get the name */
+ if ((picl_err = get_strprop_by_name(handle, PICL_PROP_NAME,
+ &tmp_name)) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ /* get the label, if any */
+ if ((picl_err = get_strprop_by_name(handle, PICL_PROP_LABEL,
+ &label)) != PICL_SUCCESS) {
+ if (picl_err != PICL_PROPNOTFOUND) {
+ free(tmp_name);
+ return (FRU_IOERROR);
+ }
+ /* else PICL_PROPNOTFOUND is OK because not all nodes */
+ /* will have a label. */
+ }
+
+ /* construct the name as nessecary */
+ if (label == NULL) {
+ *name = strdup(tmp_name);
+ } else {
+#define FRU_LABEL_PADDING 10
+ size_t buf_size = strlen(tmp_name) + strlen(label) +
+ FRU_LABEL_PADDING;
+ char *tmp = malloc(buf_size);
+ if (tmp == NULL) {
+ free(tmp_name);
+ free(label);
+ return (FRU_FAILURE);
+ }
+ snprintf(tmp, buf_size, "%s?%s=%s", tmp_name,
+ PICL_PROP_LABEL, label);
+ *name = tmp;
+ }
+
+ free(tmp_name);
+ free(label);
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+/* compare the node name to the name passed */
+static fru_errno_t
+cmp_node_name(picl_nodehdl_t node, const char *name)
+{
+ char *node_name = NULL;
+
+ if (get_strprop_by_name(node, PICL_PROP_NAME, &node_name)
+ != PICL_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+
+ if (strcmp(node_name, name) == 0) {
+ free(node_name);
+ return (FRU_SUCCESS);
+ }
+
+ free(node_name);
+ return (FRU_FAILURE);
+}
+
+/* ========================================================================= */
+/* compare the node class name to the name passed */
+static fru_errno_t
+cmp_class_name(picl_nodehdl_t node, const char *name)
+{
+ char *class_name = NULL;
+
+ if (get_strprop_by_name(node, PICL_PROP_CLASSNAME, &class_name)
+ != PICL_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+
+ if (strcmp(class_name, name) == 0) {
+ free(class_name);
+ return (FRU_SUCCESS);
+ }
+
+ free(class_name);
+ return (FRU_FAILURE);
+}
+
+
+/* ========================================================================= */
+/* get the "frutree" root node */
+static fru_errno_t
+fpt_get_root(fru_treehdl_t *node)
+{
+ picl_nodehdl_t picl_node;
+ int picl_err = PICL_SUCCESS;
+
+ picl_err = picl_get_root(&picl_node);
+ if ((picl_err = picl_get_propval_by_name(picl_node, PICL_PROP_CHILD,
+ (void *)&picl_node, sizeof (picl_node)))
+ != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ while (cmp_node_name(picl_node, PICL_NODE_FRUTREE)
+ != FRU_SUCCESS) {
+
+ if ((picl_err = picl_get_propval_by_name(picl_node,
+ PICL_PROP_PEER, (void *)&picl_node,
+ sizeof (picl_node))) == PICL_PROPNOTFOUND) {
+ return (FRU_NODENOTFOUND);
+ } else if (picl_err != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+ }
+
+ picl_root_node = picl_node;
+ *node = PICLHDL_TO_TREEHDL(picl_node);
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_peer(fru_treehdl_t sibling, fru_treehdl_t *peer)
+{
+ int rc = PICL_SUCCESS;
+ picl_nodehdl_t handle = TREEHDL_TO_PICLHDL(sibling);
+ picl_nodehdl_t picl_peer;
+
+ rc = picl_get_propval_by_name(handle, PICL_PROP_PEER,
+ (void *)&picl_peer, sizeof (picl_peer));
+ if (rc != PICL_SUCCESS) {
+ if (rc == PICL_PROPNOTFOUND)
+ return (FRU_NODENOTFOUND);
+ else
+ return (FRU_IOERROR);
+ }
+
+ *peer = PICLHDL_TO_TREEHDL(picl_peer);
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_child(fru_treehdl_t handle, fru_treehdl_t *child)
+{
+ picl_nodehdl_t p_child;
+ int rc = picl_get_propval_by_name(TREEHDL_TO_PICLHDL(handle),
+ PICL_PROP_CHILD, (void *)&p_child, sizeof (p_child));
+ if (rc != PICL_SUCCESS) {
+ if (rc == PICL_PROPNOTFOUND)
+ return (FRU_NODENOTFOUND);
+ else
+ return (FRU_IOERROR);
+ }
+
+ *child = PICLHDL_TO_TREEHDL(p_child);
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_parent(fru_treehdl_t handle, fru_treehdl_t *parent)
+{
+ int rc = PICL_SUCCESS;
+ picl_nodehdl_t p_parent;
+
+ /* do not allow the libfru users to see the parent of the root */
+ if (TREEHDL_TO_PICLHDL(handle) == picl_root_node) {
+ return (FRU_NODENOTFOUND);
+ }
+
+ rc = picl_get_propval_by_name(TREEHDL_TO_PICLHDL(handle),
+ PICL_PROP_PARENT, (void *)&p_parent, sizeof (p_parent));
+ if (rc != PICL_SUCCESS) {
+ if (rc == PICL_PROPNOTFOUND)
+ return (FRU_NODENOTFOUND);
+ else
+ return (FRU_IOERROR);
+ }
+
+ *parent = PICLHDL_TO_TREEHDL(p_parent);
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_node_type(fru_treehdl_t node, fru_node_t *type)
+{
+ char picl_class[PICL_PROPNAMELEN_MAX];
+ picl_nodehdl_t handle = TREEHDL_TO_PICLHDL(node);
+
+ if (picl_get_propval_by_name(handle, PICL_PROP_CLASSNAME,
+ picl_class, sizeof (picl_class)) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ if (strcmp(picl_class, PICL_CLASS_LOCATION) == 0) {
+ *type = FRU_NODE_LOCATION;
+ return (FRU_SUCCESS);
+ } else if (strcmp(picl_class, PICL_CLASS_FRU) == 0) {
+ picl_prophdl_t proph;
+
+ /* check for the CONTAINER_PROP property which indicates */
+ /* there is data for this node. (ie fru is a container) */
+ if (picl_get_prop_by_name(handle,
+ PICL_PROP_CONTAINER, &proph) == PICL_SUCCESS) {
+ *type = FRU_NODE_CONTAINER;
+ return (FRU_SUCCESS);
+ }
+ *type = FRU_NODE_FRU;
+ return (FRU_SUCCESS);
+ }
+
+ *type = FRU_NODE_UNKNOWN;
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+/* find the next section or return NODENOTFOUND */
+static fru_errno_t
+find_next_section(picl_nodehdl_t current, picl_nodehdl_t *next)
+{
+ picl_nodehdl_t rc_next;
+
+ if (picl_get_propval_by_name(current, PICL_PROP_PEER,
+ (void *)&rc_next, sizeof (rc_next)) != PICL_SUCCESS) {
+ return (FRU_NODENOTFOUND);
+ }
+
+ /* Make sure this is a "Section" node */
+ if (cmp_class_name(rc_next, PICL_CLASS_SECTION)
+ == FRU_SUCCESS) {
+ *next = rc_next;
+ return (FRU_SUCCESS);
+ }
+
+ /* and if this is not good keep trying to find a peer which */
+ /* is a section */
+ return (find_next_section(rc_next, next));
+}
+
+/* ========================================================================= */
+/* find the first section or return NODENOTFOUND */
+static fru_errno_t
+find_first_section(picl_nodehdl_t parent, picl_nodehdl_t *section)
+{
+ picl_nodehdl_t rc_section;
+
+ if (picl_get_propval_by_name(parent, PICL_PROP_CHILD,
+ (void *)&rc_section, sizeof (rc_section)) != PICL_SUCCESS) {
+ return (FRU_NODENOTFOUND);
+ }
+
+ /* Make sure this is a "Section" node */
+ if (cmp_class_name(rc_section, PICL_CLASS_SECTION)
+ == FRU_SUCCESS) {
+ *section = rc_section;
+ return (FRU_SUCCESS);
+ }
+
+ /* and if this is not good keep trying to find a peer which */
+ /* is a section */
+ return (find_next_section(rc_section, section));
+}
+
+/* ========================================================================= */
+/*
+ * Find the handle of the segment node "segment".
+ * also returns the hardware description of this segment. (read from the
+ * section this was found in.)
+ * If the ign_cor_flg is set this will still succeed even if the segment is
+ * corrupt, otherwise it will return FRU_SEGCORRUPT for corrupt segments
+ */
+#define IGN_CORRUPT_YES 1
+#define IGN_CORRUPT_NO 0
+static fru_errno_t
+get_segment_node(picl_nodehdl_t handle, const char *segment,
+ picl_nodehdl_t *seg_hdl, fru_seg_hwdesc_t *hw_desc, int ign_cor_flg)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ picl_nodehdl_t sect_node;
+
+ if ((err = update_data_nodes(handle)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if ((err = find_first_section(handle, &sect_node)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ /* while there are sections. */
+ while (err == FRU_SUCCESS) {
+ uint32_t num_segs = 0;
+ int rc = PICL_SUCCESS;
+ picl_nodehdl_t seg_node;
+
+ /* do this just in case the Segments have not been built. */
+ if ((rc = picl_get_propval_by_name(sect_node,
+ PICL_PROP_NUM_SEGMENTS,
+ (void *)&num_segs,
+ sizeof (num_segs))) != PICL_SUCCESS) {
+ return (map_plugin_err(rc));
+ }
+
+ /* while there are segments. */
+ rc = picl_get_propval_by_name(sect_node, PICL_PROP_CHILD,
+ (void *)&seg_node, sizeof (seg_node));
+ while (rc == PICL_SUCCESS) {
+ char name[PICL_PROPNAMELEN_MAX];
+ picl_get_propval_by_name(seg_node, PICL_PROP_NAME,
+ name, sizeof (name));
+ if (strcmp(segment, name) == 0) {
+ int dummy = 0;
+ int protection = 0;
+ /* NUM_TAGS prop exists iff segment is OK */
+ if ((ign_cor_flg == IGN_CORRUPT_NO) &&
+ (picl_get_propval_by_name(seg_node,
+ PICL_PROP_NUM_TAGS,
+ (void *)&dummy,
+ sizeof (dummy)) != PICL_SUCCESS)) {
+ return (FRU_SEGCORRUPT);
+ }
+ /* get the HW protections of this section. */
+ if (picl_get_propval_by_name(sect_node,
+ PICL_PROP_PROTECTED,
+ (void *)&protection,
+ sizeof (protection)) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+ hw_desc->all_bits = 0;
+ hw_desc->field.read_only = protection;
+
+ *seg_hdl = seg_node;
+ return (FRU_SUCCESS);
+ }
+ rc = picl_get_propval_by_name(seg_node, PICL_PROP_PEER,
+ (void *)&seg_node, sizeof (seg_node));
+ }
+
+ /* Peer property not found is ok */
+ if (rc != PICL_PROPNOTFOUND) {
+ return (FRU_IOERROR);
+ }
+
+ err = find_next_section(sect_node, &sect_node);
+ }
+
+ return (FRU_INVALSEG);
+}
+
+/* ========================================================================= */
+/*
+ * For the section handle passed add to list all the segment names found.
+ * Also incriments total by the number found.
+ */
+static fru_errno_t
+add_segs_for_section(picl_nodehdl_t section, fru_strlist_t *list)
+{
+ uint32_t num_segments = 0;
+ int rc = PICL_SUCCESS;
+
+ if ((rc = picl_get_propval_by_name(section,
+ PICL_PROP_NUM_SEGMENTS,
+ (void *)&num_segments,
+ sizeof (num_segments))) != PICL_SUCCESS) {
+ fru_destroy_strlist(list);
+ return (map_plugin_err(rc));
+ }
+
+ if (num_segments != 0) {
+ picl_nodehdl_t seg_node;
+ int total_space = list->num + num_segments;
+
+ list->strs = realloc(list->strs,
+ (sizeof (*(list->strs)) * (total_space)));
+ if (list->strs == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ /* get the first segment */
+ rc = picl_get_propval_by_name(section,
+ PICL_PROP_CHILD, (void *)&seg_node,
+ sizeof (seg_node));
+
+ /* while there are more segments. */
+ while (rc == PICL_SUCCESS) {
+ char name[FRU_SEGNAMELEN +1];
+
+ if ((rc = picl_get_propval_by_name(seg_node,
+ PICL_PROP_NAME, name,
+ sizeof (name))) != PICL_SUCCESS) {
+ break;
+ }
+
+ /* check array bounds */
+ if (list->num >= total_space) {
+ /* PICL reported incorrect number of segs */
+ return (FRU_IOERROR);
+ }
+ list->strs[(list->num)++] = strdup(name);
+
+ rc = picl_get_propval_by_name(seg_node,
+ PICL_PROP_PEER, (void *)&seg_node,
+ sizeof (seg_node));
+ }
+
+ /* Peer property not found is ok */
+ if (rc != PICL_PROPNOTFOUND) {
+ return (FRU_IOERROR);
+ }
+
+ }
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_seg_list(fru_treehdl_t handle, fru_strlist_t *list)
+{
+ fru_errno_t err;
+ picl_nodehdl_t sect_node;
+ fru_strlist_t rc_list;
+ rc_list.num = 0;
+ rc_list.strs = NULL;
+
+ if ((err = update_data_nodes(TREEHDL_TO_PICLHDL(handle)))
+ != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if ((err = find_first_section(TREEHDL_TO_PICLHDL(handle), &sect_node))
+ != FRU_SUCCESS) {
+ return (err);
+ }
+
+ /* while there are sections. */
+ while (err == FRU_SUCCESS) {
+ if ((err = add_segs_for_section(sect_node, &rc_list))
+ != FRU_SUCCESS) {
+ fru_destroy_strlist(&rc_list);
+ return (err);
+ }
+ err = find_next_section(sect_node, &sect_node);
+ }
+
+ list->num = rc_list.num;
+ list->strs = rc_list.strs;
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_seg_def(fru_treehdl_t handle, const char *seg_name, fru_segdef_t *def)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ picl_nodehdl_t seg_node;
+ fru_seg_hwdesc_t hw_desc;
+
+ fru_segdesc_t desc;
+ uint32_t size;
+ uint32_t address;
+ /* LINTED */
+ int picl_err = PICL_SUCCESS;
+
+ if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name,
+ &seg_node, &hw_desc, IGN_CORRUPT_YES)) != FRU_SUCCESS)
+ return (err);
+
+ if ((picl_err = picl_get_propval_by_name(seg_node,
+ PICL_PROP_DESCRIPTOR,
+ &desc, sizeof (desc))) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ if ((picl_err = picl_get_propval_by_name(seg_node,
+ PICL_PROP_LENGTH,
+ &size, sizeof (size))) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ if ((picl_err = picl_get_propval_by_name(seg_node,
+ PICL_PROP_OFFSET,
+ &address, sizeof (address))) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ def->version = LIBFRU_VERSION;
+ strlcpy(def->name, seg_name, FRU_SEGNAMELEN+1);
+ def->desc = desc;
+ def->size = size;
+ def->address = address;
+ def->hw_desc = hw_desc;
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_add_seg(fru_treehdl_t handle, fru_segdef_t *def)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ int picl_err = PICL_SUCCESS;
+ picl_nodehdl_t section;
+
+/*
+ * for every section which has a ADD_SEGMENT_PROP try and add the segment
+ */
+ if ((err = find_first_section(TREEHDL_TO_PICLHDL(handle), &section))
+ != FRU_SUCCESS) {
+ return (err);
+ }
+ do {
+ fru_segdef_t dummy;
+ if ((picl_err = picl_get_propval_by_name(section,
+ PICL_PROP_ADD_SEGMENT, &dummy, sizeof (dummy)))
+ == PICL_SUCCESS) {
+
+ picl_err = picl_set_propval_by_name(section,
+ PICL_PROP_ADD_SEGMENT, def, sizeof (*def));
+
+ return (map_plugin_err(picl_err));
+ }
+ } while (find_next_section(section, &section) == FRU_SUCCESS);
+
+ return (map_plugin_err(picl_err));
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_delete_seg(fru_treehdl_t handle, const char *seg_name)
+{
+ picl_nodehdl_t seg_hdl;
+ fru_seg_hwdesc_t hw_desc;
+ fru_errno_t err;
+
+ int dead_flag = FRUDATA_DELETE_TAG_KEY;
+ int rc = PICL_SUCCESS;
+
+ if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name,
+ &seg_hdl, &hw_desc, IGN_CORRUPT_YES)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ rc = picl_set_propval_by_name(seg_hdl, PICL_PROP_DELETE_SEGMENT,
+ &dead_flag, sizeof (dead_flag));
+ return (map_plugin_err(rc));
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_add_tag_to_seg(fru_treehdl_t handle, const char *seg_name,
+ fru_tag_t tag, uint8_t *data, size_t data_len)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ picl_nodehdl_t segHdl;
+ fru_seg_hwdesc_t hw_desc;
+ int picl_err = PICL_SUCCESS;
+ size_t buf_size = 0;
+ uint8_t *buffer = NULL;
+ picl_prophdl_t add_prop;
+ picl_propinfo_t add_prop_info;
+
+ if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name,
+ &segHdl, &hw_desc, IGN_CORRUPT_NO)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ /* get the length of the buffer required. */
+ if ((picl_err = picl_get_prop_by_name(segHdl,
+ PICL_PROP_ADD_PACKET,
+ &add_prop)) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+ if ((picl_err = picl_get_propinfo(add_prop, &add_prop_info))
+ != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ buf_size = add_prop_info.size;
+ if (data_len >= (buf_size - get_tag_size(get_tag_type(&tag)))) {
+ return (FRU_NOSPACE);
+ }
+
+ buffer = malloc(buf_size);
+ if (buffer == NULL) {
+ return (FRU_FAILURE);
+ }
+ /* write the tag and data into the buffer */
+ memcpy(buffer, &tag, get_tag_size(get_tag_type(&tag)));
+ memcpy((void *)(buffer+get_tag_size(get_tag_type(&tag))),
+ data, data_len);
+
+ picl_err = picl_set_propval(add_prop, buffer, buf_size);
+ free(buffer);
+ return (map_plugin_err(picl_err));
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_tag_list(fru_treehdl_t handle, const char *seg_name,
+ fru_tag_t **tags, int *number)
+{
+ picl_nodehdl_t seg_node;
+ fru_seg_hwdesc_t hw_desc;
+ fru_errno_t err = FRU_SUCCESS;
+ picl_prophdl_t tagTable;
+ int picl_err = PICL_SUCCESS;
+ unsigned int total_tags = 0;
+
+ /* return variables */
+ fru_tag_t *rc_tags = NULL;
+ unsigned int rc_num = 0;
+
+ if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name,
+ &seg_node, &hw_desc, IGN_CORRUPT_NO)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ /* get the number of tags and allocate array for them */
+ if ((picl_err = picl_get_propval_by_name(seg_node,
+ PICL_PROP_NUM_TAGS,
+ (void *)&total_tags,
+ sizeof (total_tags))) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ if (total_tags == 0) {
+ *tags = rc_tags;
+ *number = rc_num;
+ return (FRU_SUCCESS);
+ }
+
+ rc_tags = malloc((sizeof (*rc_tags) * total_tags));
+ if (rc_tags == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ /* go through the tagTable and fill in the array */
+ if ((picl_err = picl_get_propval_by_name(seg_node,
+ PICL_PROP_PACKET_TABLE,
+ &tagTable, sizeof (tagTable))) != PICL_SUCCESS) {
+ free(rc_tags);
+ return (FRU_IOERROR);
+ }
+ picl_err = picl_get_next_by_col(tagTable, &tagTable);
+ while (picl_err == PICL_SUCCESS) {
+ /* check array bounds */
+ if (rc_num >= total_tags) {
+ free(rc_tags);
+ return (FRU_FAILURE);
+ }
+ /* fill in the array */
+ if ((picl_err = picl_get_propval(tagTable,
+ (void *)&(rc_tags[rc_num++]),
+ sizeof (fru_tag_t))) != PICL_SUCCESS) {
+ free(rc_tags);
+ return (FRU_IOERROR);
+ }
+ /* get the next tag */
+ picl_err = picl_get_next_by_col(tagTable, &tagTable);
+ }
+
+ if (picl_err == PICL_ENDOFLIST) {
+ *tags = rc_tags;
+ *number = rc_num;
+ return (FRU_SUCCESS);
+ }
+ return (FRU_IOERROR);
+}
+
+/* ========================================================================= */
+/*
+ * From the handle, segment name, tag, and instance of the tag get me:
+ * segHdl: The segment handle for this segment.
+ * tagHdl: tag property handle in the tag table for this instance "tag"
+ */
+static fru_errno_t
+get_tag_handle(picl_nodehdl_t handle, const char *segment,
+ fru_tag_t tag, int instance,
+ picl_nodehdl_t *segHdl,
+ picl_prophdl_t *tagHdl)
+{
+ fru_seg_hwdesc_t hw_desc;
+ fru_errno_t err;
+ picl_prophdl_t tagTable = 0;
+ int picl_err = PICL_SUCCESS;
+ picl_nodehdl_t tmp_seg;
+
+ fru_tag_t foundTag;
+
+ if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), segment,
+ &tmp_seg, &hw_desc, IGN_CORRUPT_NO)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ foundTag.raw_data = 0;
+ if ((picl_err = picl_get_propval_by_name(tmp_seg,
+ PICL_PROP_PACKET_TABLE,
+ &tagTable, sizeof (tagTable))) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ picl_err = picl_get_next_by_col(tagTable, &tagTable);
+ while ((picl_err != PICL_ENDOFLIST) &&
+ (picl_err == PICL_SUCCESS)) {
+ if ((picl_err = picl_get_propval(tagTable, (void *)&foundTag,
+ sizeof (foundTag))) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+ if ((tags_equal(tag, foundTag) == 1) && (instance-- == 0)) {
+ *segHdl = tmp_seg;
+ *tagHdl = tagTable;
+ return (FRU_SUCCESS);
+ }
+ picl_err = picl_get_next_by_col(tagTable, &tagTable);
+ }
+
+ if (picl_err == PICL_ENDOFLIST)
+ return (FRU_DATANOTFOUND);
+
+ return (FRU_IOERROR);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_tag_data(fru_treehdl_t handle, const char *seg_name,
+ fru_tag_t tag, int instance,
+ uint8_t **data, size_t *data_len)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ int picl_err = PICL_SUCCESS;
+ uint8_t *buffer;
+ int buf_len = 0;
+
+ picl_nodehdl_t seg;
+ picl_prophdl_t tagHdl;
+
+ if ((err = get_tag_handle(TREEHDL_TO_PICLHDL(handle), seg_name,
+ tag, instance, &seg, &tagHdl)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if ((picl_err = picl_get_next_by_row(tagHdl, &tagHdl))
+ != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ buf_len = get_payload_length(&tag);
+ buffer = malloc(buf_len);
+ if (buffer == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ if ((picl_err = picl_get_propval(tagHdl, buffer, buf_len))
+ != PICL_SUCCESS) {
+ free(buffer);
+ return (map_plugin_err(picl_err));
+ }
+
+ *data = buffer;
+ *data_len = buf_len;
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_set_tag_data(fru_treehdl_t handle, const char *seg_name,
+ fru_tag_t tag, int instance,
+ uint8_t *data, size_t data_len)
+{
+ fru_errno_t rc = FRU_SUCCESS;
+ int picl_err = PICL_SUCCESS;
+
+ picl_nodehdl_t seg;
+ picl_prophdl_t tagHdl;
+
+ if ((rc = get_tag_handle(TREEHDL_TO_PICLHDL(handle), seg_name,
+ tag, instance, &seg, &tagHdl)) != FRU_SUCCESS) {
+ return (rc);
+ }
+
+ if ((picl_err = picl_get_next_by_row(tagHdl, &tagHdl))
+ != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ if ((picl_err = picl_set_propval(tagHdl, data, data_len))
+ != PICL_SUCCESS) {
+ return (map_plugin_err(picl_err));
+ }
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_delete_tag(fru_treehdl_t handle, const char *seg_name, fru_tag_t tag,
+ int instance)
+{
+ fru_errno_t rc = FRU_SUCCESS;
+ int picl_err = PICL_SUCCESS;
+
+ picl_nodehdl_t segHdl;
+ picl_prophdl_t tagHdl;
+
+ /* get tag handle */
+ if ((rc = get_tag_handle(TREEHDL_TO_PICLHDL(handle), seg_name,
+ tag, instance, &segHdl, &tagHdl)) != FRU_SUCCESS) {
+ return (rc);
+ }
+
+ /* set up key */
+ tag.raw_data &= FRUDATA_DELETE_TAG_MASK;
+ tag.raw_data |= FRUDATA_DELETE_TAG_KEY;
+
+ /* Write back */
+ picl_err = picl_set_propval(tagHdl, (void *)&(tag.raw_data),
+ sizeof (tag.raw_data));
+ return (map_plugin_err(picl_err));
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_for_each_segment(fru_treehdl_t treenode,
+ int (*function)(fru_treeseghdl_t segment, void *args),
+ void *args)
+{
+ int num_segments = 0, status;
+
+ fru_errno_t saved_status = FRU_SUCCESS;
+
+ picl_nodehdl_t container = TREEHDL_TO_PICLHDL(treenode),
+ section, segment;
+
+
+ if ((status = update_data_nodes(container)) != FRU_SUCCESS)
+ return (status);
+
+ /* process each section */
+ for (status = picl_get_propval_by_name(container, PICL_PROP_CHILD,
+ &section, sizeof (section));
+ status == PICL_SUCCESS;
+ status = picl_get_propval_by_name(section, PICL_PROP_PEER,
+ &section,
+ sizeof (section))) {
+
+ if (cmp_class_name(section, PICL_CLASS_SECTION) != FRU_SUCCESS)
+ continue;
+
+ if ((status = picl_get_propval_by_name(section,
+ PICL_PROP_NUM_SEGMENTS,
+ &num_segments,
+ sizeof (num_segments)))
+ == PICL_PROPNOTFOUND) {
+ continue;
+ } else if (status != PICL_SUCCESS) {
+ saved_status = map_plugin_err(status);
+ continue;
+ } else if (num_segments == 0) {
+ continue;
+ }
+
+ /* process each segment */
+ for (status = picl_get_propval_by_name(section,
+ PICL_PROP_CHILD,
+ &segment,
+ sizeof (segment));
+ status == PICL_SUCCESS;
+ status = picl_get_propval_by_name(segment,
+ PICL_PROP_PEER,
+ &segment,
+ sizeof (segment))) {
+
+ if (cmp_class_name(segment, PICL_CLASS_SEGMENT)
+ != FRU_SUCCESS) continue;
+
+ if ((status = function(PICLHDL_TO_TREESEGHDL(segment),
+ args))
+ != FRU_SUCCESS) return (status);
+ }
+
+ if (status != PICL_PROPNOTFOUND)
+ saved_status = map_plugin_err(status);
+ }
+
+ if (status != PICL_PROPNOTFOUND)
+ saved_status = map_plugin_err(status);
+
+ return (saved_status);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_segment_name(fru_treeseghdl_t segment, char **name)
+{
+ char *propval;
+
+ int status;
+
+ picl_prophdl_t proph = 0;
+
+ picl_propinfo_t propinfo;
+
+
+ if (picl_get_propinfo_by_name(TREESEGHDL_TO_PICLHDL(segment),
+ PICL_PROP_NAME, &propinfo, &proph)
+ != PICL_SUCCESS)
+ return (FRU_IOERROR);
+
+ if (propinfo.size == 0)
+ return (FRU_INVALDATASIZE);
+
+ if ((propval = malloc(propinfo.size)) == NULL)
+ return (FRU_NOSPACE);
+
+ if ((status = picl_get_propval(proph, propval, propinfo.size))
+ != PICL_SUCCESS) {
+ free(propval);
+ return (map_plugin_err(status));
+ }
+
+ *name = propval;
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_for_each_packet(fru_treeseghdl_t treesegment,
+ int (*function)(fru_tag_t *tag, uint8_t *payload,
+ size_t length,
+ void *args),
+ void *args)
+{
+ int status;
+
+ uint8_t *payload;
+
+ picl_nodehdl_t segment = TREESEGHDL_TO_PICLHDL(treesegment);
+
+ picl_prophdl_t packet, payloadh = 0;
+
+ picl_propinfo_t propinfo;
+
+ fru_segdesc_t descriptor;
+
+ fru_tag_t tag;
+
+
+ if ((status = picl_get_propval_by_name(segment, PICL_PROP_DESCRIPTOR,
+ &descriptor,
+ sizeof (descriptor)))
+ != PICL_SUCCESS) return (map_plugin_err(status));
+
+ if (descriptor.field.opaque)
+ return (FRU_SUCCESS);
+
+ if (descriptor.field.encrypted && (encrypt_func == NULL))
+ return (FRU_SUCCESS);
+
+ if ((status = picl_get_propval_by_name(segment, PICL_PROP_PACKET_TABLE,
+ &packet, sizeof (packet)))
+ == PICL_PROPNOTFOUND)
+ return (FRU_SUCCESS);
+ else if (status != PICL_SUCCESS)
+ return (map_plugin_err(status));
+
+ while ((status = picl_get_next_by_col(packet, &packet))
+ == PICL_SUCCESS) {
+ if (((status = picl_get_propval(packet, &tag, sizeof (tag)))
+ != PICL_SUCCESS) ||
+ ((status = picl_get_next_by_row(packet, &payloadh))
+ != PICL_SUCCESS) ||
+ ((status = picl_get_propinfo(payloadh, &propinfo))
+ != PICL_SUCCESS))
+ return (map_plugin_err(status));
+
+ if (propinfo.size > 0) {
+ payload = alloca(propinfo.size);
+ if ((status = picl_get_propval(payloadh, payload,
+ propinfo.size))
+ != PICL_SUCCESS) return (map_plugin_err(status));
+ } else {
+ payload = NULL;
+ }
+
+ if ((descriptor.field.encrypted) &&
+ ((status = encrypt_func(FRU_DECRYPT, payload,
+ propinfo.size))
+ != FRU_SUCCESS)) return status;
+
+ if ((status = function(&tag, payload, propinfo.size, args))
+ != FRU_SUCCESS) return (status);
+ }
+
+ if (status == PICL_ENDOFLIST)
+ return (FRU_SUCCESS);
+ else
+ return (map_plugin_err(status));
+}
+
+/* ========================================================================= */
+/* ARGSUSED0 */
+static fru_errno_t
+initialize(int argc, char **argv)
+{
+ /* LINTED */
+ int rc = PICL_SUCCESS;
+ if ((rc = picl_initialize()) != PICL_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+shutdown(void)
+{
+ if (picl_shutdown() != PICL_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+/* object for libfru to link to */
+fru_datasource_t data_source =
+{
+ LIBFRU_DS_VER,
+ initialize,
+ shutdown,
+ fpt_get_root,
+ fpt_get_child,
+ fpt_get_peer,
+ fpt_get_parent,
+ fpt_get_name_from_hdl,
+ fpt_get_node_type,
+ fpt_get_seg_list,
+ fpt_get_seg_def,
+ fpt_add_seg,
+ fpt_delete_seg,
+ fpt_for_each_segment,
+ fpt_get_segment_name,
+ fpt_add_tag_to_seg,
+ fpt_get_tag_list,
+ fpt_get_tag_data,
+ fpt_set_tag_data,
+ fpt_delete_tag,
+ fpt_for_each_packet
+};
diff --git a/usr/src/lib/libfru/libfrupicl/sparc/Makefile b/usr/src/lib/libfru/libfrupicl/sparc/Makefile
new file mode 100644
index 0000000000..aff02f315c
--- /dev/null
+++ b/usr/src/lib/libfru/libfrupicl/sparc/Makefile
@@ -0,0 +1,47 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+LDLIBS += -L$(SRC)/lib/libfruutils/$(MACH) -lfruutils
+LDLIBS += -L$(SRC)/lib/libfru/$(MACH) -lfru
+LDLIBS += -lc -lpicl
+
+.KEEP_STATE:
+
+all: $(ROOTLIBDIR) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS): FRC
+ $(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR):
+ $(INS.dir)
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
+
+FRC:
diff --git a/usr/src/lib/libfru/libfrupicl/sparcv9/Makefile b/usr/src/lib/libfru/libfrupicl/sparcv9/Makefile
new file mode 100644
index 0000000000..fdd3f280fc
--- /dev/null
+++ b/usr/src/lib/libfru/libfrupicl/sparcv9/Makefile
@@ -0,0 +1,48 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+LDLIBS += -L$(SRC)/lib/libfruutils/$(MACH64) -lfruutils
+LDLIBS += -L$(SRC)/lib/libfru/$(MACH64) -lfru
+LDLIBS += -lc -lpicl
+
+.KEEP_STATE:
+
+all: $(ROOTLIBDIR64) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS): FRC
+ $(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR64):
+ $(INS.dir)
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64)
+
+FRC:
diff --git a/usr/src/lib/libfru/libfrupicltree/Makefile b/usr/src/lib/libfru/libfrupicltree/Makefile
new file mode 100644
index 0000000000..0bdf6ea08f
--- /dev/null
+++ b/usr/src/lib/libfru/libfrupicltree/Makefile
@@ -0,0 +1,69 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+# lib/libfru/libfrupicltree/Makefile
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+
+include $(SRC)/lib/Makefile.lib
+
+SUBDIRS = .WAIT $(MACH)
+
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+lint := TARGET= lint
+_msg := TARGET= _msg
+
+sparc_HDRS=
+sparcv9_HDRS=
+i386_HDRS=
+HDRS= $($(MACH)_HDRS)
+ROOTHDRDIR= $(ROOT)/usr/include
+ROOTHDRS= $(HDRS:%=$(ROOTHDRDIR)/%)
+CHECKHDRS= $(HDRS:%.h=%.check)
+
+.KEEP_STATE:
+
+all install clean clobber lint: $(SUBDIRS)
+
+_msg: $(MACH) $(MACH64)
+
+
+$(ROOTHDRDIR)/%: %
+ $(INS.file)
+
+$(ROOTHDRDIR):
+ $(INS.dir)
+
+check: $(CHECKHDRS)
+
+$(MACH) $(MACH64): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
diff --git a/usr/src/lib/libfru/libfrupicltree/Makefile.com b/usr/src/lib/libfru/libfrupicltree/Makefile.com
new file mode 100644
index 0000000000..5e3f905a7b
--- /dev/null
+++ b/usr/src/lib/libfru/libfrupicltree/Makefile.com
@@ -0,0 +1,92 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY= libfrupicltree.a
+VERS= .1
+
+OBJECTS= frupicltree.o
+
+include $(SRC)/lib/Makefile.lib
+
+SRCS= $(OBJECTS:%.o=../%.c)
+CLOBBERFILES += $(LIBLINKS)
+
+LIBS = $(DYNLIB)
+
+LINTFLAGS = -mnux
+LINTFLAGS64 = $(LINTFLAGS) -Xarch=$(MACH64:sparcv9=v9)
+LINTOUT= lint.out
+LINTSRC = $(LINTLIB:%.ln=%)
+ROOTLINTDIR = $(ROOTLIBDIR)
+ROOTLINT = $(LINTSRC:%=$(ROOTLINTDIR)/%)
+
+CLEANFILES= $(LINTOUT)
+
+CPPFLAGS += -I.. \
+ -I$(SRC)/lib/libfru/include \
+ -I$(SRC)/cmd/picl/plugins/sun4u/frudata \
+ -I$(SRC)/lib/libpicl \
+ -I$(SRC)/lib/libfruutils \
+ -I$(SRC)/cmd/picl/plugins/inc
+CPPFLAGS += -D_REENTRANT
+CFLAGS += $(CCVERBOSE)
+
+$(LINTLIB) := LINTFLAGS = -nvx -I..
+$(LINTLIB) := LINTFLAGS64 = -nvx -Xarch=$(MACH64:sparcv9=v9) -I..
+
+XGETFLAGS += -a
+POFILE= picl.po
+
+.KEEP_STATE:
+
+all : $(LIBS)
+ chmod 755 $(DYNLIB)
+
+lint : lintcheck
+
+%.po: ../%.c
+ $(CP) $< $<.i
+ $(BUILD.po)
+
+_msg: $(MSGDOMAIN) $(POFILE)
+ $(RM) $(MSGDOMAIN)/$(POFILE)
+ $(CP) $(POFILE) $(MSGDOMAIN)
+
+$(DYNLIB): $(MAPFILE)
+
+$(MAPFILE):
+ @cd $(MAPDIR); $(MAKE) mapfile
+
+include $(SRC)/lib/Makefile.targ
+
+pics/%.o: ../%.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
+
+$(ROOTLINTDIR)/%: ../%
+ $(INS.file)
diff --git a/usr/src/lib/libfru/libfrupicltree/frupicltree.c b/usr/src/lib/libfru/libfrupicltree/frupicltree.c
new file mode 100644
index 0000000000..2a21e4b8a4
--- /dev/null
+++ b/usr/src/lib/libfru/libfrupicltree/frupicltree.c
@@ -0,0 +1,1187 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <alloca.h>
+#include <picl.h>
+#include <picltree.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "picldefs.h"
+#include "fru_data.h"
+
+#include "libfruds.h"
+#include "libfrup.h"
+
+#define FRU_LABEL_PADDING 10
+
+/* ========================================================================= */
+#define TREEHDL_TO_PICLHDL(treehdl) ((picl_nodehdl_t)treehdl)
+#define PICLHDL_TO_TREEHDL(piclhdl) ((fru_treehdl_t)piclhdl)
+
+#define TREESEGHDL_TO_PICLHDL(treeseghdl) ((picl_nodehdl_t)treeseghdl)
+#define PICLHDL_TO_TREESEGHDL(piclhdl) ((fru_treeseghdl_t)piclhdl)
+
+/* Cache of the root node for quick checks */
+static picl_nodehdl_t picl_root_node;
+
+/* ========================================================================= */
+/*
+ * Map the PICL errors the plugin would give me to FRU errors
+ */
+static fru_errno_t
+map_plugin_err(int picl_err)
+{
+ switch (picl_err) {
+ case PICL_SUCCESS:
+ return (FRU_SUCCESS);
+ case PICL_PERMDENIED:
+ return (FRU_INVALPERM);
+ case PICL_PROPEXISTS:
+ return (FRU_DUPSEG);
+ case PICL_NOSPACE:
+ return (FRU_NOSPACE);
+ }
+ return (FRU_IOERROR);
+}
+
+/* ========================================================================= */
+/*
+ * cause a refresh of the sub-nodes by writing anything to the container
+ * property of the node.
+ */
+static fru_errno_t
+update_data_nodes(picl_nodehdl_t handle)
+{
+ uint32_t container = FRUDATA_DELETE_TAG_KEY;
+ int picl_err = PICL_SUCCESS;
+
+ if ((picl_err = ptree_update_propval_by_name(handle,
+ PICL_PROP_CONTAINER, (void *)&container,
+ sizeof (container))) != PICL_SUCCESS) {
+ return (map_plugin_err(picl_err));
+ }
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+/*
+ * picl like function which gets a string property with the proper length
+ * NOTE: returns picl errno values NOT fru_errno_t
+ */
+static int
+get_strprop_by_name(picl_nodehdl_t handle, char *prop_name, char **string)
+{
+ int picl_err = PICL_SUCCESS;
+ picl_prophdl_t proph;
+
+ size_t buf_size = 0;
+ char *tmp_buf = NULL;
+
+ ptree_propinfo_t prop_info;
+
+ if ((picl_err = ptree_get_prop_by_name(handle, prop_name, &proph))
+ != PICL_SUCCESS) {
+ return (picl_err);
+ }
+ if ((picl_err = ptree_get_propinfo(proph, &prop_info))
+ != PICL_SUCCESS) {
+ return (picl_err);
+ }
+ buf_size = prop_info.piclinfo.size;
+
+ tmp_buf = malloc((sizeof (*tmp_buf) * buf_size));
+ if (tmp_buf == NULL) {
+ return (PICL_FAILURE);
+ }
+
+ if ((picl_err = ptree_get_propval(proph, tmp_buf, buf_size))
+ != PICL_SUCCESS) {
+ free(tmp_buf);
+ return (picl_err);
+ }
+
+ *string = tmp_buf;
+ return (PICL_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_name_from_hdl(fru_treehdl_t node, char **name)
+{
+ int picl_err = PICL_SUCCESS;
+ char *tmp_name = NULL;
+ char *label = NULL;
+ picl_nodehdl_t handle = TREEHDL_TO_PICLHDL(node);
+
+ /* get the name */
+ if ((picl_err = get_strprop_by_name(handle, PICL_PROP_NAME,
+ &tmp_name)) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ /* get the label, if any */
+ if ((picl_err = get_strprop_by_name(handle, PICL_PROP_LABEL,
+ &label)) != PICL_SUCCESS) {
+ if (picl_err != PICL_PROPNOTFOUND) {
+ free(tmp_name);
+ return (FRU_IOERROR);
+ }
+ /* else PICL_PROPNOTFOUND is OK because not all nodes */
+ /* will have a label. */
+ }
+
+ /* construct the name as nessecary */
+ if (label == NULL) {
+ *name = strdup(tmp_name);
+ } else {
+ size_t buf_size = strlen(tmp_name) + strlen(label) +
+ FRU_LABEL_PADDING;
+ char *tmp = malloc(buf_size);
+ if (tmp == NULL) {
+ free(tmp_name);
+ free(label);
+ return (FRU_FAILURE);
+ }
+ snprintf(tmp, buf_size, "%s?%s=%s", tmp_name,
+ PICL_PROP_LABEL, label);
+ *name = tmp;
+ }
+
+ free(tmp_name);
+ free(label);
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+/* compare the node name to the name passed */
+static fru_errno_t
+cmp_node_name(picl_nodehdl_t node, const char *name)
+{
+ char *node_name = NULL;
+
+ if (get_strprop_by_name(node, PICL_PROP_NAME, &node_name)
+ != PICL_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+
+ if (strcmp(node_name, name) == 0) {
+ free(node_name);
+ return (FRU_SUCCESS);
+ }
+
+ free(node_name);
+ return (FRU_FAILURE);
+}
+
+/* ========================================================================= */
+/* compare the node class name to the name passed */
+static fru_errno_t
+cmp_class_name(picl_nodehdl_t node, const char *name)
+{
+ char *class_name = NULL;
+
+ if (get_strprop_by_name(node, PICL_PROP_CLASSNAME, &class_name)
+ != PICL_SUCCESS) {
+ return (FRU_FAILURE);
+ }
+
+ if (strcmp(class_name, name) == 0) {
+ free(class_name);
+ return (FRU_SUCCESS);
+ }
+
+ free(class_name);
+ return (FRU_FAILURE);
+}
+
+
+/* ========================================================================= */
+/* get the "frutree" root node */
+static fru_errno_t
+fpt_get_root(fru_treehdl_t *node)
+{
+ picl_nodehdl_t picl_node;
+ int picl_err = PICL_SUCCESS;
+
+ picl_err = ptree_get_root(&picl_node);
+ if ((picl_err = ptree_get_propval_by_name(picl_node, PICL_PROP_CHILD,
+ (void *)&picl_node, sizeof (picl_node)))
+ != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ while (cmp_node_name(picl_node, PICL_NODE_FRUTREE)
+ != FRU_SUCCESS) {
+
+ if ((picl_err = ptree_get_propval_by_name(picl_node,
+ PICL_PROP_PEER, (void *)&picl_node,
+ sizeof (picl_node))) == PICL_PROPNOTFOUND) {
+ return (FRU_NODENOTFOUND);
+ } else if (picl_err != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+ }
+
+ picl_root_node = picl_node;
+ *node = PICLHDL_TO_TREEHDL(picl_node);
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_peer(fru_treehdl_t sibling, fru_treehdl_t *peer)
+{
+ int rc = PICL_SUCCESS;
+ picl_nodehdl_t handle = TREEHDL_TO_PICLHDL(sibling);
+ picl_nodehdl_t picl_peer;
+
+ rc = ptree_get_propval_by_name(handle, PICL_PROP_PEER,
+ (void *)&picl_peer, sizeof (picl_peer));
+ if (rc != PICL_SUCCESS) {
+ if (rc == PICL_PROPNOTFOUND)
+ return (FRU_NODENOTFOUND);
+ else
+ return (FRU_IOERROR);
+ }
+
+ *peer = PICLHDL_TO_TREEHDL(picl_peer);
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_child(fru_treehdl_t handle, fru_treehdl_t *child)
+{
+ picl_nodehdl_t p_child;
+ int rc = ptree_get_propval_by_name(TREEHDL_TO_PICLHDL(handle),
+ PICL_PROP_CHILD, (void *)&p_child, sizeof (p_child));
+ if (rc != PICL_SUCCESS) {
+ if (rc == PICL_PROPNOTFOUND)
+ return (FRU_NODENOTFOUND);
+ else
+ return (FRU_IOERROR);
+ }
+
+ *child = PICLHDL_TO_TREEHDL(p_child);
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_parent(fru_treehdl_t handle, fru_treehdl_t *parent)
+{
+ int rc = PICL_SUCCESS;
+ picl_nodehdl_t p_parent;
+
+ /* do not allow the libfru users to see the parent of the root */
+ if (TREEHDL_TO_PICLHDL(handle) == picl_root_node) {
+ return (FRU_NODENOTFOUND);
+ }
+
+ rc = ptree_get_propval_by_name(TREEHDL_TO_PICLHDL(handle),
+ PICL_PROP_PARENT, (void *)&p_parent, sizeof (p_parent));
+ if (rc != PICL_SUCCESS) {
+ if (rc == PICL_PROPNOTFOUND)
+ return (FRU_NODENOTFOUND);
+ else
+ return (FRU_IOERROR);
+ }
+
+ *parent = PICLHDL_TO_TREEHDL(p_parent);
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_node_type(fru_treehdl_t node, fru_node_t *type)
+{
+ char picl_class[PICL_PROPNAMELEN_MAX];
+ picl_nodehdl_t handle = TREEHDL_TO_PICLHDL(node);
+
+ if (ptree_get_propval_by_name(handle, PICL_PROP_CLASSNAME,
+ picl_class, sizeof (picl_class)) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ if (strcmp(picl_class, PICL_CLASS_LOCATION) == 0) {
+ *type = FRU_NODE_LOCATION;
+ return (FRU_SUCCESS);
+ } else if (strcmp(picl_class, PICL_CLASS_FRU) == 0) {
+ picl_prophdl_t proph;
+
+ /* check for the CONTAINER_PROP property which indicates */
+ /* there is data for this node. (ie fru is a container) */
+ if (ptree_get_prop_by_name(handle,
+ PICL_PROP_CONTAINER, &proph) == PICL_SUCCESS) {
+ *type = FRU_NODE_CONTAINER;
+ return (FRU_SUCCESS);
+ }
+ *type = FRU_NODE_FRU;
+ return (FRU_SUCCESS);
+ }
+
+ *type = FRU_NODE_UNKNOWN;
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+/* find the next section or return NODENOTFOUND */
+static fru_errno_t
+find_next_section(picl_nodehdl_t current, picl_nodehdl_t *next)
+{
+ picl_nodehdl_t rc_next;
+
+ if (ptree_get_propval_by_name(current, PICL_PROP_PEER,
+ (void *)&rc_next, sizeof (rc_next)) != PICL_SUCCESS) {
+ return (FRU_NODENOTFOUND);
+ }
+
+ /* Make sure this is a "Section" node */
+ if (cmp_class_name(rc_next, PICL_CLASS_SECTION)
+ == FRU_SUCCESS) {
+ *next = rc_next;
+ return (FRU_SUCCESS);
+ }
+
+ /* and if this is not good keep trying to find a peer which */
+ /* is a section */
+ return (find_next_section(rc_next, next));
+}
+
+/* ========================================================================= */
+/* find the first section or return NODENOTFOUND */
+static fru_errno_t
+find_first_section(picl_nodehdl_t parent, picl_nodehdl_t *section)
+{
+ picl_nodehdl_t rc_section;
+
+ if (ptree_get_propval_by_name(parent, PICL_PROP_CHILD,
+ (void *)&rc_section, sizeof (rc_section)) != PICL_SUCCESS) {
+ return (FRU_NODENOTFOUND);
+ }
+
+ /* Make sure this is a "Section" node */
+ if (cmp_class_name(rc_section, PICL_CLASS_SECTION)
+ == FRU_SUCCESS) {
+ *section = rc_section;
+ return (FRU_SUCCESS);
+ }
+
+ /* and if this is not good keep trying to find a peer which */
+ /* is a section */
+ return (find_next_section(rc_section, section));
+}
+
+/* ========================================================================= */
+/*
+ * Find the handle of the segment node "segment".
+ * also returns the hardware description of this segment. (read from the
+ * section this was found in.)
+ * If the ign_cor_flg is set this will still succeed even if the segment is
+ * corrupt, otherwise it will return FRU_SEGCORRUPT for corrupt segments
+ */
+#define IGN_CORRUPT_YES 1
+#define IGN_CORRUPT_NO 0
+static fru_errno_t
+get_segment_node(picl_nodehdl_t handle, const char *segment,
+ picl_nodehdl_t *seg_hdl, fru_seg_hwdesc_t *hw_desc, int ign_cor_flg)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ picl_nodehdl_t sect_node;
+
+ if ((err = update_data_nodes(handle)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if ((err = find_first_section(handle, &sect_node)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ /* while there are sections. */
+ while (err == FRU_SUCCESS) {
+ uint32_t num_segs = 0;
+ int rc = PICL_SUCCESS;
+ picl_nodehdl_t seg_node;
+
+ /* do this just in case the Segments have not been built. */
+ if ((rc = ptree_get_propval_by_name(sect_node,
+ PICL_PROP_NUM_SEGMENTS,
+ (void *)&num_segs,
+ sizeof (num_segs))) != PICL_SUCCESS) {
+ return (map_plugin_err(rc));
+ }
+
+ /* while there are segments. */
+ rc = ptree_get_propval_by_name(sect_node, PICL_PROP_CHILD,
+ (void *)&seg_node, sizeof (seg_node));
+ while (rc == PICL_SUCCESS) {
+ char name[PICL_PROPNAMELEN_MAX];
+ ptree_get_propval_by_name(seg_node, PICL_PROP_NAME,
+ name, sizeof (name));
+ if (strcmp(segment, name) == 0) {
+ int dummy = 0;
+ int protection = 0;
+ /* NUM_TAGS prop exists iff segment is OK */
+ if ((ign_cor_flg == IGN_CORRUPT_NO) &&
+ (ptree_get_propval_by_name(seg_node,
+ PICL_PROP_NUM_TAGS,
+ (void *)&dummy,
+ sizeof (dummy)) != PICL_SUCCESS)) {
+ return (FRU_SEGCORRUPT);
+ }
+ /* get the HW protections of this section. */
+ if (ptree_get_propval_by_name(sect_node,
+ PICL_PROP_PROTECTED,
+ (void *)&protection,
+ sizeof (protection)) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+ hw_desc->all_bits = 0;
+ hw_desc->field.read_only = protection;
+
+ *seg_hdl = seg_node;
+ return (FRU_SUCCESS);
+ }
+ rc = ptree_get_propval_by_name(seg_node, PICL_PROP_PEER,
+ (void *)&seg_node, sizeof (seg_node));
+ }
+
+ /* Peer property not found is ok */
+ if (rc != PICL_PROPNOTFOUND) {
+ return (FRU_IOERROR);
+ }
+
+ err = find_next_section(sect_node, &sect_node);
+ }
+
+ return (FRU_INVALSEG);
+}
+
+/* ========================================================================= */
+/*
+ * For the section handle passed add to list all the segment names found.
+ * Also incriments total by the number found.
+ */
+static fru_errno_t
+add_segs_for_section(picl_nodehdl_t section, fru_strlist_t *list)
+{
+ int num_segments = 0;
+ int rc = PICL_SUCCESS;
+
+ if ((rc = ptree_get_propval_by_name(section,
+ PICL_PROP_NUM_SEGMENTS,
+ (void *)&num_segments,
+ sizeof (num_segments))) != PICL_SUCCESS) {
+ fru_destroy_strlist(list);
+ return (map_plugin_err(rc));
+ }
+
+ if (num_segments != 0) {
+ picl_nodehdl_t seg_node;
+ int total_space = list->num + num_segments;
+
+ list->strs = realloc(list->strs,
+ (sizeof (*(list->strs)) * (total_space)));
+ if (list->strs == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ /* get the first segment */
+ rc = ptree_get_propval_by_name(section,
+ PICL_PROP_CHILD, (void *)&seg_node,
+ sizeof (seg_node));
+
+ /* while there are more segments. */
+ while (rc == PICL_SUCCESS) {
+ char name[FRU_SEGNAMELEN +1];
+
+ if ((rc = ptree_get_propval_by_name(seg_node,
+ PICL_PROP_NAME, name,
+ sizeof (name))) != PICL_SUCCESS) {
+ break;
+ }
+
+ /* check array bounds */
+ if (list->num >= total_space) {
+ /* PICL reported incorrect number of segs */
+ return (FRU_IOERROR);
+ }
+ list->strs[(list->num)++] = strdup(name);
+
+ rc = ptree_get_propval_by_name(seg_node,
+ PICL_PROP_PEER, (void *)&seg_node,
+ sizeof (seg_node));
+ }
+
+ /* Peer property not found is ok */
+ if (rc != PICL_PROPNOTFOUND) {
+ return (FRU_IOERROR);
+ }
+
+ }
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_seg_list(fru_treehdl_t handle, fru_strlist_t *list)
+{
+ fru_errno_t err;
+ picl_nodehdl_t sect_node;
+ fru_strlist_t rc_list;
+ rc_list.num = 0;
+ rc_list.strs = NULL;
+
+ if ((err = update_data_nodes(TREEHDL_TO_PICLHDL(handle)))
+ != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if ((err = find_first_section(TREEHDL_TO_PICLHDL(handle), &sect_node))
+ != FRU_SUCCESS) {
+ return (err);
+ }
+
+ /* while there are sections. */
+ while (err == FRU_SUCCESS) {
+ if ((err = add_segs_for_section(sect_node, &rc_list))
+ != FRU_SUCCESS) {
+ fru_destroy_strlist(&rc_list);
+ return (err);
+ }
+ err = find_next_section(sect_node, &sect_node);
+ }
+
+ list->num = rc_list.num;
+ list->strs = rc_list.strs;
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_seg_def(fru_treehdl_t handle, const char *seg_name, fru_segdef_t *def)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ picl_nodehdl_t seg_node;
+ fru_seg_hwdesc_t hw_desc;
+
+ fru_segdesc_t desc;
+ uint32_t size;
+ uint32_t address;
+ /* LINTED */
+ int picl_err = PICL_SUCCESS;
+
+ if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name,
+ &seg_node, &hw_desc, IGN_CORRUPT_YES)) != FRU_SUCCESS)
+ return (err);
+
+ if ((picl_err = ptree_get_propval_by_name(seg_node,
+ PICL_PROP_DESCRIPTOR,
+ &desc, sizeof (desc))) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ if ((picl_err = ptree_get_propval_by_name(seg_node,
+ PICL_PROP_LENGTH,
+ &size, sizeof (size))) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ if ((picl_err = ptree_get_propval_by_name(seg_node,
+ PICL_PROP_OFFSET,
+ &address, sizeof (address))) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ def->version = LIBFRU_VERSION;
+ strlcpy(def->name, seg_name, FRU_SEGNAMELEN+1);
+ def->desc = desc;
+ def->size = size;
+ def->address = address;
+ def->hw_desc = hw_desc;
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_add_seg(fru_treehdl_t handle, fru_segdef_t *def)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ int picl_err = PICL_SUCCESS;
+ picl_nodehdl_t section;
+
+/*
+ * for every section which has a ADD_SEGMENT_PROP try and add the segment
+ */
+ if ((err = find_first_section(TREEHDL_TO_PICLHDL(handle), &section))
+ != FRU_SUCCESS) {
+ return (err);
+ }
+ do {
+ fru_segdef_t dummy;
+ if ((picl_err = ptree_get_propval_by_name(section,
+ PICL_PROP_ADD_SEGMENT, &dummy, sizeof (dummy)))
+ == PICL_SUCCESS) {
+
+ picl_err = ptree_update_propval_by_name(section,
+ PICL_PROP_ADD_SEGMENT, def, sizeof (*def));
+
+ return (map_plugin_err(picl_err));
+ }
+ } while (find_next_section(section, &section) == FRU_SUCCESS);
+
+ return (map_plugin_err(picl_err));
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_delete_seg(fru_treehdl_t handle, const char *seg_name)
+{
+ picl_nodehdl_t seg_hdl;
+ fru_seg_hwdesc_t hw_desc;
+ fru_errno_t err;
+
+ int dead_flag = FRUDATA_DELETE_TAG_KEY;
+ int rc = PICL_SUCCESS;
+
+ if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name,
+ &seg_hdl, &hw_desc, IGN_CORRUPT_YES)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ rc = ptree_update_propval_by_name(seg_hdl, PICL_PROP_DELETE_SEGMENT,
+ &dead_flag, sizeof (dead_flag));
+ return (map_plugin_err(rc));
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_add_tag_to_seg(fru_treehdl_t handle, const char *seg_name,
+ fru_tag_t tag, uint8_t *data, size_t data_len)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ picl_nodehdl_t segHdl;
+ fru_seg_hwdesc_t hw_desc;
+ int picl_err = PICL_SUCCESS;
+ size_t buf_size = 0;
+ uint8_t *buffer = NULL;
+ picl_prophdl_t add_prop;
+ ptree_propinfo_t add_prop_info;
+
+ if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name,
+ &segHdl, &hw_desc, IGN_CORRUPT_NO)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ /* get the length of the buffer required. */
+ if ((picl_err = ptree_get_prop_by_name(segHdl,
+ PICL_PROP_ADD_PACKET,
+ &add_prop)) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ if ((picl_err = ptree_get_propinfo(add_prop, &add_prop_info))
+ != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+ buf_size = add_prop_info.piclinfo.size;
+
+ if (data_len >= (buf_size - get_tag_size(get_tag_type(&tag)))) {
+ return (FRU_NOSPACE);
+ }
+
+ buffer = malloc(buf_size);
+ if (buffer == NULL) {
+ return (FRU_FAILURE);
+ }
+ /* write the tag and data into the buffer */
+ memcpy(buffer, &tag, get_tag_size(get_tag_type(&tag)));
+ memcpy((void *)(buffer+get_tag_size(get_tag_type(&tag))),
+ data, data_len);
+
+ picl_err = ptree_update_propval(add_prop, buffer, buf_size);
+ free(buffer);
+ return (map_plugin_err(picl_err));
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_tag_list(fru_treehdl_t handle, const char *seg_name,
+ fru_tag_t **tags, int *number)
+{
+ picl_nodehdl_t seg_node;
+ fru_seg_hwdesc_t hw_desc;
+ fru_errno_t err = FRU_SUCCESS;
+ picl_prophdl_t tagTable;
+ int picl_err = PICL_SUCCESS;
+ unsigned int total_tags = 0;
+
+ /* return variables */
+ fru_tag_t *rc_tags = NULL;
+ unsigned int rc_num = 0;
+
+ if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), seg_name,
+ &seg_node, &hw_desc, IGN_CORRUPT_NO)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ /* get the number of tags and allocate array for them */
+ if ((picl_err = ptree_get_propval_by_name(seg_node,
+ PICL_PROP_NUM_TAGS,
+ (void *)&total_tags,
+ sizeof (total_tags))) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ if (total_tags == 0) {
+ *tags = rc_tags;
+ *number = rc_num;
+ return (FRU_SUCCESS);
+ }
+
+ rc_tags = malloc((sizeof (*rc_tags) * total_tags));
+ if (rc_tags == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ /* go through the tagTable and fill in the array */
+ if ((picl_err = ptree_get_propval_by_name(seg_node,
+ PICL_PROP_PACKET_TABLE,
+ &tagTable, sizeof (tagTable))) != PICL_SUCCESS) {
+ free(rc_tags);
+ return (FRU_IOERROR);
+ }
+ picl_err = ptree_get_next_by_col(tagTable, &tagTable);
+ while (picl_err == PICL_SUCCESS) {
+ /* check array bounds */
+ if (rc_num >= total_tags) {
+ free(rc_tags);
+ return (FRU_FAILURE);
+ }
+ /* fill in the array */
+ if ((picl_err = ptree_get_propval(tagTable,
+ (void *)&(rc_tags[rc_num++]),
+ sizeof (fru_tag_t))) != PICL_SUCCESS) {
+ free(rc_tags);
+ return (FRU_IOERROR);
+ }
+ /* get the next tag */
+ picl_err = ptree_get_next_by_col(tagTable, &tagTable);
+ }
+
+ if (picl_err == PICL_ENDOFLIST) {
+ *tags = rc_tags;
+ *number = rc_num;
+ return (FRU_SUCCESS);
+ }
+ return (FRU_IOERROR);
+}
+
+/* ========================================================================= */
+/*
+ * From the handle, segment name, tag, and instance of the tag get me:
+ * segHdl: The segment handle for this segment.
+ * tagHdl: tag property handle in the tag table for this instance "tag"
+ */
+static fru_errno_t
+get_tag_handle(picl_nodehdl_t handle, const char *segment,
+ fru_tag_t tag, int instance,
+ picl_nodehdl_t *segHdl,
+ picl_prophdl_t *tagHdl)
+{
+ fru_seg_hwdesc_t hw_desc;
+ fru_errno_t err;
+ picl_prophdl_t tagTable = 0;
+ int picl_err = PICL_SUCCESS;
+ picl_nodehdl_t tmp_seg;
+
+ fru_tag_t foundTag;
+
+ if ((err = get_segment_node(TREEHDL_TO_PICLHDL(handle), segment,
+ &tmp_seg, &hw_desc, IGN_CORRUPT_NO)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ foundTag.raw_data = 0;
+ if ((picl_err = ptree_get_propval_by_name(tmp_seg,
+ PICL_PROP_PACKET_TABLE,
+ &tagTable, sizeof (tagTable))) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ picl_err = ptree_get_next_by_col(tagTable, &tagTable);
+ while ((picl_err != PICL_ENDOFLIST) &&
+ (picl_err == PICL_SUCCESS)) {
+ if ((picl_err = ptree_get_propval(tagTable, (void *)&foundTag,
+ sizeof (foundTag))) != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+ if ((tags_equal(tag, foundTag) == 1) && (instance-- == 0)) {
+ *segHdl = tmp_seg;
+ *tagHdl = tagTable;
+ return (FRU_SUCCESS);
+ }
+ picl_err = ptree_get_next_by_col(tagTable, &tagTable);
+ }
+
+ if (picl_err == PICL_ENDOFLIST)
+ return (FRU_DATANOTFOUND);
+
+ return (FRU_IOERROR);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_tag_data(fru_treehdl_t handle, const char *seg_name,
+ fru_tag_t tag, int instance,
+ uint8_t **data, size_t *data_len)
+{
+ fru_errno_t err = FRU_SUCCESS;
+ int picl_err = PICL_SUCCESS;
+ uint8_t *buffer;
+ int buf_len = 0;
+
+ picl_nodehdl_t seg;
+ picl_prophdl_t tagHdl;
+
+ if ((err = get_tag_handle(TREEHDL_TO_PICLHDL(handle), seg_name,
+ tag, instance, &seg, &tagHdl)) != FRU_SUCCESS) {
+ return (err);
+ }
+
+ if ((picl_err = ptree_get_next_by_row(tagHdl, &tagHdl))
+ != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ buf_len = get_payload_length(&tag);
+ buffer = malloc(buf_len);
+ if (buffer == NULL) {
+ return (FRU_FAILURE);
+ }
+
+ if ((picl_err = ptree_get_propval(tagHdl, buffer, buf_len))
+ != PICL_SUCCESS) {
+ free(buffer);
+ return (map_plugin_err(picl_err));
+ }
+
+ *data = buffer;
+ *data_len = buf_len;
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_set_tag_data(fru_treehdl_t handle, const char *seg_name,
+ fru_tag_t tag, int instance,
+ uint8_t *data, size_t data_len)
+{
+ fru_errno_t rc = FRU_SUCCESS;
+ int picl_err = PICL_SUCCESS;
+
+ picl_nodehdl_t seg;
+ picl_prophdl_t tagHdl;
+
+ if ((rc = get_tag_handle(TREEHDL_TO_PICLHDL(handle), seg_name,
+ tag, instance, &seg, &tagHdl)) != FRU_SUCCESS) {
+ return (rc);
+ }
+
+ if ((picl_err = ptree_get_next_by_row(tagHdl, &tagHdl))
+ != PICL_SUCCESS) {
+ return (FRU_IOERROR);
+ }
+
+ if ((picl_err = ptree_update_propval(tagHdl, data, data_len))
+ != PICL_SUCCESS) {
+ return (map_plugin_err(picl_err));
+ }
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_delete_tag(fru_treehdl_t handle, const char *seg_name, fru_tag_t tag,
+ int instance)
+{
+ fru_errno_t rc = FRU_SUCCESS;
+ int picl_err = PICL_SUCCESS;
+
+ picl_nodehdl_t segHdl;
+ picl_prophdl_t tagHdl;
+
+ /* get tag handle */
+ if ((rc = get_tag_handle(TREEHDL_TO_PICLHDL(handle), seg_name,
+ tag, instance, &segHdl, &tagHdl)) != FRU_SUCCESS) {
+ return (rc);
+ }
+
+ /* set up key */
+ tag.raw_data &= FRUDATA_DELETE_TAG_MASK;
+ tag.raw_data |= FRUDATA_DELETE_TAG_KEY;
+
+ /* Write back */
+ picl_err = ptree_update_propval(tagHdl, (void *)&(tag.raw_data),
+ sizeof (tag.raw_data));
+ return (map_plugin_err(picl_err));
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_for_each_segment(fru_treehdl_t treenode,
+ int (*function)(fru_treeseghdl_t segment, void *args),
+ void *args)
+{
+ int num_segments = 0, status;
+
+ fru_errno_t saved_status = FRU_SUCCESS;
+
+ picl_nodehdl_t container = TREEHDL_TO_PICLHDL(treenode),
+ section, segment;
+
+
+ if ((status = update_data_nodes(container)) != FRU_SUCCESS)
+ return (status);
+
+ /* process each section */
+ for (status = ptree_get_propval_by_name(container, PICL_PROP_CHILD,
+ &section, sizeof (section));
+ status == PICL_SUCCESS;
+ status = ptree_get_propval_by_name(section, PICL_PROP_PEER,
+ &section,
+ sizeof (section))) {
+
+ if (cmp_class_name(section, PICL_CLASS_SECTION) != FRU_SUCCESS)
+ continue;
+
+ if ((status = ptree_get_propval_by_name(section,
+ PICL_PROP_NUM_SEGMENTS,
+ &num_segments,
+ sizeof (num_segments)))
+ == PICL_PROPNOTFOUND) {
+ continue;
+ } else if (status != PICL_SUCCESS) {
+ saved_status = map_plugin_err(status);
+ continue;
+ } else if (num_segments == 0) {
+ continue;
+ }
+
+ /* process each segment */
+ for (status = ptree_get_propval_by_name(section,
+ PICL_PROP_CHILD,
+ &segment,
+ sizeof (segment));
+ status == PICL_SUCCESS;
+ status = ptree_get_propval_by_name(segment,
+ PICL_PROP_PEER,
+ &segment,
+ sizeof (segment))) {
+
+ if (cmp_class_name(segment, PICL_CLASS_SEGMENT)
+ != FRU_SUCCESS) continue;
+
+ if ((status = function(PICLHDL_TO_TREESEGHDL(segment),
+ args))
+ != FRU_SUCCESS) return (status);
+ }
+
+ if (status != PICL_PROPNOTFOUND)
+ saved_status = map_plugin_err(status);
+ }
+
+ if (status != PICL_PROPNOTFOUND)
+ saved_status = map_plugin_err(status);
+
+ return (saved_status);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_get_segment_name(fru_treeseghdl_t segment, char **name)
+{
+ char *propval;
+
+ int status;
+
+ picl_prophdl_t proph = 0;
+
+ ptree_propinfo_t propinfo;
+
+
+ if (ptree_get_prop_by_name(TREESEGHDL_TO_PICLHDL(segment),
+ PICL_PROP_NAME, &proph)
+ != PICL_SUCCESS)
+ return (FRU_IOERROR);
+
+ if (ptree_get_propinfo(proph, &propinfo) != PICL_SUCCESS)
+ return (FRU_IOERROR);
+
+ if (propinfo.piclinfo.size == 0)
+ return (FRU_INVALDATASIZE);
+
+ if ((propval = malloc(propinfo.piclinfo.size)) == NULL)
+ return (FRU_NOSPACE);
+
+ if ((status = ptree_get_propval(proph, propval, propinfo.piclinfo.size))
+ != PICL_SUCCESS) {
+ free(propval);
+ return (map_plugin_err(status));
+ }
+
+ *name = propval;
+
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+fpt_for_each_packet(fru_treeseghdl_t treesegment,
+ int (*function)(fru_tag_t *tag, uint8_t *payload,
+ size_t length,
+ void *args),
+ void *args)
+{
+ int status;
+
+ uint8_t *payload;
+
+ picl_nodehdl_t segment = TREESEGHDL_TO_PICLHDL(treesegment);
+
+ picl_prophdl_t packet, payloadh = 0;
+
+ ptree_propinfo_t propinfo;
+
+ fru_segdesc_t descriptor;
+
+ fru_tag_t tag;
+
+
+ if ((status = ptree_get_propval_by_name(segment, PICL_PROP_DESCRIPTOR,
+ &descriptor,
+ sizeof (descriptor)))
+ != PICL_SUCCESS) return (map_plugin_err(status));
+
+ if (descriptor.field.opaque)
+ return (FRU_SUCCESS);
+
+ if (descriptor.field.encrypted && (encrypt_func == NULL))
+ return (FRU_SUCCESS);
+
+ if ((status = ptree_get_propval_by_name(segment, PICL_PROP_PACKET_TABLE,
+ &packet, sizeof (packet)))
+ == PICL_PROPNOTFOUND)
+ return (FRU_SUCCESS);
+ else if (status != PICL_SUCCESS)
+ return (map_plugin_err(status));
+
+ while ((status = ptree_get_next_by_col(packet, &packet))
+ == PICL_SUCCESS) {
+ if (((status = ptree_get_propval(packet, &tag, sizeof (tag)))
+ != PICL_SUCCESS) ||
+ ((status = ptree_get_next_by_row(packet, &payloadh))
+ != PICL_SUCCESS) ||
+ ((status = ptree_get_propinfo(payloadh, &propinfo))
+ != PICL_SUCCESS))
+ return (map_plugin_err(status));
+
+ if (propinfo.piclinfo.size > 0) {
+ payload = alloca(propinfo.piclinfo.size);
+ if ((status = ptree_get_propval(payloadh, payload,
+ propinfo.piclinfo.size))
+ != PICL_SUCCESS) return (map_plugin_err(status));
+ } else {
+ payload = NULL;
+ }
+
+ if ((descriptor.field.encrypted) &&
+ ((status = encrypt_func(FRU_DECRYPT, payload,
+ propinfo.piclinfo.size))
+ != FRU_SUCCESS)) return status;
+
+ if ((status = function(&tag, payload, propinfo.piclinfo.size,
+ args))
+ != FRU_SUCCESS) return (status);
+ }
+
+ if (status == PICL_ENDOFLIST)
+ return (FRU_SUCCESS);
+ else
+ return (map_plugin_err(status));
+}
+
+/* ========================================================================= */
+/* ARGSUSED0 */
+static fru_errno_t
+initialize(int argc, char **argv)
+{
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+static fru_errno_t
+shutdown(void)
+{
+ return (FRU_SUCCESS);
+}
+
+/* ========================================================================= */
+/* object for libfru to link to */
+fru_datasource_t data_source =
+{
+ LIBFRU_DS_VER,
+ initialize,
+ shutdown,
+ fpt_get_root,
+ fpt_get_child,
+ fpt_get_peer,
+ fpt_get_parent,
+ fpt_get_name_from_hdl,
+ fpt_get_node_type,
+ fpt_get_seg_list,
+ fpt_get_seg_def,
+ fpt_add_seg,
+ fpt_delete_seg,
+ fpt_for_each_segment,
+ fpt_get_segment_name,
+ fpt_add_tag_to_seg,
+ fpt_get_tag_list,
+ fpt_get_tag_data,
+ fpt_set_tag_data,
+ fpt_delete_tag,
+ fpt_for_each_packet
+};
diff --git a/usr/src/lib/libfru/libfrupicltree/sparc/Makefile b/usr/src/lib/libfru/libfrupicltree/sparc/Makefile
new file mode 100644
index 0000000000..a5f8e16aaf
--- /dev/null
+++ b/usr/src/lib/libfru/libfrupicltree/sparc/Makefile
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libfru/libfrupicl/sparc/Makefile
+#
+
+include ../Makefile.com
+
+LDLIBS += -L$(SRC)/lib/libfruutils/$(MACH)
+LDLIBS += -L$(SRC)/lib/libfru/$(MACH)
+LDLIBS += -lc -lfruutils -lfru -lpicltree
+
+.KEEP_STATE:
+
+all: $(ROOTLIBDIR) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS): FRC
+ $(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR):
+ $(INS.dir)
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
+
+FRC:
diff --git a/usr/src/lib/libfru/libfrureg/Makefile b/usr/src/lib/libfru/libfrureg/Makefile
new file mode 100644
index 0000000000..9543bc389f
--- /dev/null
+++ b/usr/src/lib/libfru/libfrureg/Makefile
@@ -0,0 +1,68 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+
+include $(SRC)/lib/Makefile.lib
+
+SUBDIRS = .WAIT $(MACH) $(BUILD64) $(MACH64)
+
+# conditional assignments
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+lint := TARGET= lint
+_msg := TARGET= _msg
+
+sparc_HDRS=
+sparcv9_HDRS=
+i386_HDRS=
+HDRS= $($(MACH)_HDRS)
+ROOTHDRDIR= $(ROOT)/usr/include
+ROOTHDRS= $(HDRS:%=$(ROOTHDRDIR)/%)
+CHECKHDRS= $(HDRS:%.h=%.check)
+
+.KEEP_STATE:
+
+all install clean clobber lint: $(SUBDIRS)
+
+_msg: $(MACH) $(MACH64)
+
+
+$(ROOTHDRDIR)/%: %
+ $(INS.file)
+
+$(ROOTHDRDIR):
+ $(INS.dir)
+
+check: $(CHECKHDRS)
+
+$(MACH) $(MACH64): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
diff --git a/usr/src/lib/libfru/libfrureg/Makefile.com b/usr/src/lib/libfru/libfrureg/Makefile.com
new file mode 100644
index 0000000000..1d370fe047
--- /dev/null
+++ b/usr/src/lib/libfru/libfrureg/Makefile.com
@@ -0,0 +1,96 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY= libfrureg.a
+VERS= .1
+
+OBJECTS= frureg.o
+
+# include library definitions
+include $(SRC)/lib/Makefile.lib
+
+SRCS= $(OBJECTS:%.o=../%.c)
+#MAPFILE= $(MAPDIR)/mapfile
+#CLOBBERFILES += $(MAPFILE)
+CLOBBERFILES += $(LIBLINKS)
+
+LIBS = $(DYNLIB)
+
+LINTFLAGS = -uxn
+LINTFLAGS64 = $(LINTFLAGS) -Xarch=$(MACH64:sparcv9=v9)
+LINTOUT= lint.out
+LINTSRC = $(LINTLIB:%.ln=%)
+ROOTLINTDIR = $(ROOTLIBDIR)
+ROOTLINT = $(LINTSRC:%=$(ROOTLINTDIR)/%)
+
+CLEANFILES= $(LINTOUT)
+
+CPPFLAGS += -I.. \
+ -I$(SRC)/lib/libfru/include \
+ -I$(SRC)/cmd/picl/plugins/sun4u/frudata \
+ -I$(SRC)/lib/libpicl \
+ -I$(SRC)/lib/libfruutils \
+ -I$(SRC)/cmd/picl/plugins/inc
+CPPFLAGS += -D_REENTRANT
+CFLAGS += $(CCVERBOSE)
+
+$(LINTLIB) := LINTFLAGS = -nvx -I..
+$(LINTLIB) := LINTFLAGS64 = -nvx -Xarch=$(MACH64:sparcv9=v9) -I..
+
+XGETFLAGS += -a
+POFILE= picl.po
+
+.KEEP_STATE:
+
+all : $(LIBS)
+ chmod 755 $(DYNLIB)
+
+lint : lintcheck
+
+%.po: ../%.c
+ $(CP) $< $<.i
+ $(BUILD.po)
+
+_msg: $(MSGDOMAIN) $(POFILE)
+ $(RM) $(MSGDOMAIN)/$(POFILE)
+ $(CP) $(POFILE) $(MSGDOMAIN)
+
+$(DYNLIB): $(MAPFILE)
+
+$(MAPFILE):
+ @cd $(MAPDIR); $(MAKE) mapfile
+
+# include library targets
+include $(SRC)/lib/Makefile.targ
+
+pics/%.o: ../%.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
+
+$(ROOTLINTDIR)/%: ../%
+ $(INS.file)
diff --git a/usr/src/lib/libfru/libfrureg/frudefs.c b/usr/src/lib/libfru/libfrureg/frudefs.c
new file mode 100644
index 0000000000..8deec07c27
--- /dev/null
+++ b/usr/src/lib/libfru/libfrureg/frudefs.c
@@ -0,0 +1,10563 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * FRUID Tag Registry
+ * This file is AUTO-generated DO NOT EDIT
+ *
+ * Generated on Thu Mar 25 16:40:06 PST 2004 by kmohan.
+ * From input file data.frureg
+ *
+ */
+
+
+static const char *registry_version
+ = "%Z%%M% %I% %E% SMI";
+
+fru_enum_t Vendor[] = {
+ { 0x0, "NO JEDEC CODE FOR THIS VENDOR" },
+ { 0x1, "AMD" },
+ { 0x2, "AMI" },
+ { 0x4, "Fujitsu" },
+ { 0x7, "Hitachi" },
+ { 0x8, "Inmos" },
+ { 0xb, "Intersil" },
+ { 0xd, "Mostek" },
+ { 0xe, "Motorola" },
+ { 0x10, "NEC" },
+ { 0x13, "Rockwell" },
+ { 0x15, "Philips Semi. (Signetics)" },
+ { 0x16, "Synertek" },
+ { 0x19, "Xicor" },
+ { 0x1a, "Zilog" },
+ { 0x1c, "Mitsubishi" },
+ { 0x1f, "Atmel" },
+ { 0x20, "SGS/Thomson" },
+ { 0x23, "Wafer Scale Integration" },
+ { 0x25, "Tristar" },
+ { 0x26, "Visic" },
+ { 0x29, "MicrochipTechnology" },
+ { 0x2a, "Ricoh Ltd." },
+ { 0x2c, "Micron Technology" },
+ { 0x2f, "ACTEL" },
+ { 0x31, "Catalyst" },
+ { 0x32, "Panasonic" },
+ { 0x34, "Cypress" },
+ { 0x37, "Plessey" },
+ { 0x38, "UTMC" },
+ { 0x3b, "Integrated CMOS(Vertex)" },
+ { 0x3d, "Tektronix" },
+ { 0x3e, "Sun Microsystems" },
+ { 0x40, "MOSEL" },
+ { 0x43, "Xerox" },
+ { 0x45, "SunDisk" },
+ { 0x46, "Elan Circuit Tech." },
+ { 0x4a, "Compaq" },
+ { 0x4c, "SCI" },
+ { 0x4f, "I3 Design System" },
+ { 0x51, "Crosspoint Solutions" },
+ { 0x52, "Alliance Semiconductor" },
+ { 0x54, "Hewlett-Packard" },
+ { 0x57, "New Media" },
+ { 0x58, "MHS Electronic" },
+ { 0x5b, "Kawasaki Steel" },
+ { 0x5d, "TECMAR" },
+ { 0x5e, "Exar" },
+ { 0x61, "Northern Telecom" },
+ { 0x62, "Sanyo" },
+ { 0x64, "Crystal Semiconductor" },
+ { 0x67, "Asparix" },
+ { 0x68, "Convex Computer" },
+ { 0x6b, "Transwitch" },
+ { 0x6d, "Cannon" },
+ { 0x6e, "Altera" },
+ { 0x70, "QUALCOMM" },
+ { 0x73, "AMS(Austria Micro)" },
+ { 0x75, "Aster Electronics" },
+ { 0x76, "Bay Networks(Synoptic)" },
+ { 0x79, "Thesys" },
+ { 0x7a, "Solbourne Computer" },
+ { 0x7c, "Dialog" },
+ { 0x83, "Fairchild" },
+ { 0x85, "GTE" },
+ { 0x86, "Harris" },
+ { 0x89, "Intel" },
+ { 0x8a, "I.T.T." },
+ { 0x8c, "Monolithic Memories" },
+ { 0x8f, "National" },
+ { 0x91, "RCA" },
+ { 0x92, "Raytheon" },
+ { 0x94, "Seeq" },
+ { 0x97, "Texas Instruments" },
+ { 0x98, "Toshiba" },
+ { 0x9b, "Eurotechnique" },
+ { 0x9d, "Lucent (AT&T)" },
+ { 0x9e, "Exel" },
+ { 0xa1, "Lattice Semi." },
+ { 0xa2, "NCR" },
+ { 0xa4, "IBM" },
+ { 0xa7, "Intl. CMOS Technology" },
+ { 0xa8, "SSSI" },
+ { 0xab, "VLSI" },
+ { 0xad, "Hyundai Electronics" },
+ { 0xae, "OKI Semiconductor" },
+ { 0xb0, "Sharp" },
+ { 0xb3, "IDT" },
+ { 0xb5, "DEC" },
+ { 0xb6, "LSI Logic" },
+ { 0xb9, "Thinking Machine" },
+ { 0xba, "Thomson CSF" },
+ { 0xbc, "Honeywell" },
+ { 0xbf, "SST" },
+ { 0xc1, "Infineon (formerly Siemens)" },
+ { 0xc2, "Macronix" },
+ { 0xc4, "Plus Logic" },
+ { 0xc7, "European Silicon Str." },
+ { 0xc8, "Apple Computer" },
+ { 0xc9, "Xilinx" },
+ { 0xcb, "Protocol Engines" },
+ { 0xcd, "Seiko Instruments" },
+ { 0xce, "Samsung" },
+ { 0xd0, "Klic" },
+ { 0xd3, "Tandem" },
+ { 0xd5, "Intg. Silicon Solutions" },
+ { 0xd6, "Brooktree" },
+ { 0xd9, "Performance Semi." },
+ { 0xda, "Winbond Electronic" },
+ { 0xdc, "Bright Micro" },
+ { 0xdf, "PCMCIA" },
+ { 0xe0, "Goldstar" },
+ { 0xe3, "Array Microsystems" },
+ { 0xe5, "Analog Devices" },
+ { 0xe6, "PMC-Sierra" },
+ { 0xe9, "Quality Semiconductor" },
+ { 0xea, "Nimbus Technology" },
+ { 0xec, "ITT Intermetall" },
+ { 0xef, "NEXCOM" },
+ { 0xf1, "Sony" },
+ { 0xf2, "Cray Research" },
+ { 0xf4, "Vitesse" },
+ { 0xf7, "Zentrum Mikroeleckt." },
+ { 0xf8, "TRW" },
+ { 0xfb, "Allied-Signal" },
+ { 0xfd, "Media Vision" },
+ { 0xfe, "Level One Communication" },
+ { 0x101, "Cirrus Logic" },
+ { 0x102, "National Instruments" },
+ { 0x104, "Alcatel Mietec" },
+ { 0x107, "JTAG Technologies" },
+ { 0x108, "Loral" },
+ { 0x10b, "Bestlink Systems" },
+ { 0x10d, "GENNUM" },
+ { 0x10e, "VideoLogic" },
+ { 0x110, "Chip Express" },
+ { 0x113, "TCSI" },
+ { 0x115, "Hughes Aircraft" },
+ { 0x116, "Lanstar Semiconductor" },
+ { 0x119, "Music Semi" },
+ { 0x11a, "Ericsson Components" },
+ { 0x11c, "Eon Silicon Devices" },
+ { 0x11f, "Integ. Memories Tech." },
+ { 0x120, "Corollary Inc." },
+ { 0x123, "EIV(Switzerland)" },
+ { 0x125, "Mitel" },
+ { 0x126, "Clearpoint" },
+ { 0x129, "Vanguard" },
+ { 0x12a, "Hagiwara Sys-Com" },
+ { 0x12c, "Celestica" },
+ { 0x12f, "Rohm Company Ltd." },
+ { 0x131, "Libit Signal Processing" },
+ { 0x132, "Enhanced Memories Inc." },
+ { 0x134, "Adaptec Inc." },
+ { 0x137, "AMIC Technology" },
+ { 0x138, "Adobe Systems" },
+ { 0x13b, "Newport Digital" },
+ { 0x13d, "T Square" },
+ { 0x13e, "Seiko Epson" },
+ { 0x140, "Viking Components" },
+ { 0x143, "Suwa Electronics" },
+ { 0x145, "Micron CMS" },
+ { 0x146, "American Computer & Digital Components Inc" },
+ { 0x149, "CPU Design" },
+ { 0x14a, "Price Point" },
+ { 0x14c, "Tellabs" },
+ { 0x14f, "Transcend Information" },
+ { 0x151, "CKD Corporation Ltd." },
+ { 0x152, "Capital Instruments, Inc." },
+ { 0x154, "Linvex Technology" },
+ { 0x157, "Dynamem, Inc." },
+ { 0x158, "NERA ASA" },
+ { 0x15b, "Acorn Computers" },
+ { 0x15d, "Oak Technology, Inc." },
+ { 0x15e, "Itec Memory" },
+ { 0x161, "Wintec Industries" },
+ { 0x162, "Super PC Memory" },
+ { 0x164, "Galvantech" },
+ { 0x167, "GateField" },
+ { 0x168, "Integrated Memory System" },
+ { 0x16b, "Goldenram" },
+ { 0x16d, "Cimaron Communications" },
+ { 0x16e, "Nippon Steel Semi. Corp." },
+ { 0x170, "AMCC" },
+ { 0x173, "Digital Microwave" },
+ { 0x175, "MIMOS Semiconductor" },
+ { 0x176, "Advanced Fibre" },
+ { 0x179, "Acbel Polytech Inc." },
+ { 0x17a, "Apacer Technology" },
+ { 0x17c, "FOXCONN" },
+ { 0x183, "ILC Data Device" },
+ { 0x185, "Micro Linear" },
+ { 0x186, "Univ. of NC" },
+ { 0x189, "Nchip" },
+ { 0x18a, "Galileo Tech" },
+ { 0x18c, "Graychip" },
+ { 0x18f, "Robert Bosch" },
+ { 0x191, "DATARAM" },
+ { 0x192, "United Microelec Corp." },
+ { 0x194, "Smart Modular" },
+ { 0x197, "Qlogic" },
+ { 0x198, "Kingston" },
+ { 0x19b, "SpaSE" },
+ { 0x19d, "Programmable Micro Corp" },
+ { 0x19e, "DoD" },
+ { 0x1a1, "Dallas Semiconductor" },
+ { 0x1a2, "Omnivision" },
+ { 0x1a4, "Novatel Wireless" },
+ { 0x1a7, "Cabletron" },
+ { 0x1a8, "Simple Technology" },
+ { 0x1ab, "Vantis" },
+ { 0x1ad, "Century" },
+ { 0x1ae, "Hal Computers" },
+ { 0x1b0, "Juniper Networks" },
+ { 0x1b3, "Tundra Semiconductor" },
+ { 0x1b5, "LightSpeed Semi." },
+ { 0x1b6, "ZSP Corp." },
+ { 0x1b9, "Dynachip" },
+ { 0x1ba, "PNY Electronics" },
+ { 0x1bc, "MMC Networks" },
+ { 0x1bf, "Broadcom" },
+ { 0x1c1, "V3 Semiconductor" },
+ { 0x1c2, "Flextronics Semiconductor" },
+ { 0x1c4, "Transmeta" },
+ { 0x1c7, "Enhance 3000 Inc" },
+ { 0x1c8, "Tower Semiconductor" },
+ { 0x1cb, "Maxim Integrated Product" },
+ { 0x1cd, "Centaur Technology" },
+ { 0x1ce, "Unigen Corporation" },
+ { 0x1d0, "Memory Card Technology" },
+ { 0x1d3, "Aica Kogyo, Ltd." },
+ { 0x1d5, "MSC Vertriebs GmbH" },
+ { 0x1d6, "AKM Company, Ltd." },
+ { 0x1d9, "GSI Technology" },
+ { 0x1da, "Dane-Elec" },
+ { 0x1dc, "Lara Technology" },
+ { 0x1df, "Tanisys Technology" },
+ { 0x1e0, "Truevision" },
+ { 0x1e3, "MGV Memory" },
+ { 0x1e5, "Gadzoox Networks" },
+ { 0x1e6, "Multi Dimensional Cons." },
+ { 0x1e9, "Triscend" },
+ { 0x1ea, "XaQti" },
+ { 0x1ec, "Clear Logic" },
+ { 0x1ef, "Advantage Memory" },
+ { 0x1f1, "LeCroy" },
+ { 0x1f2, "Yamaha Corporation" },
+ { 0x1f4, "NetLogic Microsystems" },
+ { 0x1f7, "BF Goodrich Data." },
+ { 0x1f8, "Epigram" },
+ { 0x1fb, "Admor Memory" },
+ { 0x1fd, "Quadratics Superconductor" },
+ { 0x1fe, "3COM" },
+ { 0x201, "Camintonn Corporation" },
+ { 0x202, "ISOA Incorporated" },
+ { 0x204, "ADMtek Incorporated" },
+ { 0x207, "MOSAID Technologies" },
+ { 0x208, "Ardent Technologies" },
+ { 0x20b, "Allayer Technologies" },
+ { 0x20d, "Oasis Semiconductor" },
+ { 0x20e, "Novanet Semiconductor" },
+ { 0x210, "Power General" },
+ { 0x213, "Telocity" },
+ { 0x215, "Symagery Microsystems" },
+ { 0x216, "C-Port Corporation" },
+ { 0x219, "Malleable Technologies" },
+ { 0x21a, "Kendin Communications" },
+ { 0x21c, "Sanmina Corporation" },
+ { 0x21f, "Actrans System Inc." },
+ { 0x220, "ALPHA Technologies" },
+ { 0x223, "Align Manufacturing" },
+ { 0x225, "Chameleon Systems" },
+ { 0x226, "Aplus Flash Technology" },
+ { 0x229, "ADTEC Corporation" },
+ { 0x22a, "Kentron Technologies" },
+ { 0x22c, "ASIC Designs Inc" },
+ { 0x22f, "Siemens AG" },
+ { 0x231, "Itautec Philco SA" },
+ { 0x232, "Radiata Inc." },
+ { 0x234, "Legend" },
+ { 0x237, "Enikia Incorporated" },
+ { 0x238, "SwitchOn Networks" },
+ { 0x23b, "ESS Technology" },
+ { 0x23d, "Excess Bandwidth" },
+ { 0x23e, "West bay Semiconductor" },
+ { 0x240, "Newport Communications" },
+ { 0x243, "Intellitech Corporation" },
+ { 0x245, "Ishoni Networks" },
+ { 0x246, "Silicon Spice" },
+ { 0x249, "Centillium Communications" },
+ { 0x24a, "W.L. Gore" },
+ { 0x24c, "GlobeSpan" },
+ { 0x24f, "Saifun Semiconductors" },
+ { 0x251, "MetaLink Technologies" },
+ { 0x252, "Feiya Technology" },
+ { 0x254, "Shikatronics" },
+ { 0x257, "Com-Tier" },
+ { 0x258, "Malaysia Micro Solutions" },
+ { 0x25b, "Anadyne Microelectronics" },
+ { 0x25d, "Mellanox Technologies" },
+ { 0x25e, "Tenx Technologies" },
+ { 0x261, "Skyup Technology" },
+ { 0x262, "HiNT Corporation" },
+ { 0x264, "MCI Computer GMBH" },
+ { 0x267, "AVED Memory" },
+ { 0x268, "Legerity" },
+ { 0x26b, "nCUBE" },
+ { 0x26d, "FDK Corporation" },
+ { 0x26e, "High Bandwidth Access" },
+ { 0x270, "BRECIS" },
+ { 0x273, "Chicory Systems" },
+ { 0x275, "Fast-Chip" },
+ { 0x276, "Zucotto Wireless" },
+ { 0x279, "eSilicon" },
+ { 0x27a, "Morphics Technology" },
+ { 0x27c, "Silicon Wave" },
+ { 0x283, "Agate Semiconductor" },
+ { 0x285, "HYPERTEC" },
+ { 0x286, "Adhoc Technologies" },
+ { 0x289, "Switchcore" },
+ { 0x28a, "Cisco Systems, Inc." },
+ { 0x28c, "Wichmann WorkX AG" },
+ { 0x28f, "E-M Solutions" },
+ { 0x291, "Advanced Hardware Arch." },
+ { 0x292, "Inova Semiconductors GmbH" },
+ { 0x294, "Delkin Devices" },
+ { 0x297, "SiberCore Technologies" },
+ { 0x298, "Southland Microsystems" },
+ { 0x29b, "Great Technology Microcomputer" },
+ { 0x29d, "HADCO Corporation" },
+ { 0x29e, "Corsair" },
+ { 0x2a1, "Cygnal Integrated Products Incorporated" },
+ { 0x2a2, "Artesyn Technologies" },
+ { 0x2a4, "Peregrine Semiconductor" },
+ { 0x2a7, "MIPS Technologies" },
+ { 0x2a8, "Chrysalis ITS" },
+ { 0x2ab, "Win Technologies" },
+ { 0x2ad, "Extreme Packet Devices" },
+ { 0x2ae, "RF Micro Devices" },
+ { 0x2b0, "Sarnoff Corporation" },
+ { 0x2b3, "Benchmark Electronics" },
+ { 0x2b5, "SpecTek Incorporated" },
+ { 0x2b6, "Hi/fn" },
+ { 0x2b9, "AANetcom Incorporated" },
+ { 0x2ba, "Micro Memory Bank" },
+ { 0x2bc, "Virata Corporation" },
+ { 0x2bf, "DSP Group" },
+ { 0x2c1, "Chip2Chip Incorporated" },
+ { 0x2c2, "Phobos Corporation" },
+ { 0x2c4, "Nordic VLSI ASA" },
+ { 0x2c7, "Alchemy Semiconductor" },
+ { 0x2c8, "Agilent Technologies" },
+ { 0x2cb, "HanBit Electronics" },
+ { 0x2cd, "Element 14" },
+ { 0x2ce, "Pycon" },
+ { 0x2d0, "Sibyte, Incorporated" },
+ { 0x2d3, "I & C Technology" },
+ { 0x2d5, "Elektrobit" },
+ { 0x2d6, "Megic" },
+ { 0x2d9, "Hyperchip" },
+ { 0x2da, "Gemstone Communications" },
+ { 0x2dc, "3ParData" },
+ { 0x2df, "Helix AG" },
+ { 0x2e0, "Domosys" },
+ { 0x2e3, "Chiaro" },
+ { 0x2e5, "Exbit Technology" },
+ { 0x2e6, "Integrated Technology Express" },
+ { 0x2e9, "Jasmine Networks" },
+ { 0x2ea, "Caspian Networks" },
+ { 0x2ec, "Silicon Access Networks" },
+ { 0x2ef, "MultiLink Technology" },
+ { 0x2f1, "World Wide Packets" },
+ { 0x2f2, "APW Silicon Valley Division" },
+ { 0x2f4, "Xstream Logic" },
+ { 0x2f7, "Realchip" },
+ { 0x2f8, "Galaxy Power" },
+ { 0x2fb, "Accelerant Networks" },
+ { 0x2fd, "SandCraft" },
+ { 0x2fe, "Elpida" },
+ { 0x301, "Solectron" },
+ { 0x302, "Optosys Technologies" },
+ { 0x304, "TriMedia Technologies" },
+ { 0x307, "Optillion" },
+ { 0x308, "Terago Communications" },
+ { 0x30b, "Nanya Technology" },
+ { 0x30d, "Mysticon" },
+ { 0x30e, "LightSand Communications" },
+ { 0x310, "Agere Systems" },
+ { 0x313, "Golden Empire" },
+ { 0x315, "Tioga Technologies" },
+ { 0x316, "Netlist" },
+ { 0x319, "Centon Electronics" },
+ { 0x31a, "Tyco Electronics" },
+ { 0x31c, "Zettacom" },
+ { 0x31f, "Aspex Technology" },
+ { 0x320, "F5 Networks" },
+ { 0x323, "Acorn Networks" },
+ { 0x325, "Kingmax Semiconductor" },
+ { 0x326, "BOPS" },
+ { 0x329, "eMemory Technology" },
+ { 0x32a, "Procket Networks" },
+ { 0x32c, "Trebia Networks" },
+ { 0x32f, "Ample Communications" },
+ { 0x331, "Astute Networks" },
+ { 0x332, "Azanda Network Devices" },
+ { 0x334, "Tekmos" },
+ { 0x337, "Firecron Ltd" },
+ { 0x338, "Resonext Communications" },
+ { 0x33b, "Concept Computer" },
+ { 0x33d, "3Dlabs" },
+ { 0x33e, "ct Magazine" },
+ { 0x340, "Silicon Packets" },
+ { 0x343, "Semicon Devices Singapore" },
+ { 0x345, "Improv Systems" },
+ { 0x346, "INDUSYS GmbH" },
+ { 0x349, "Ritek Corp" },
+ { 0x34a, "empowerTel Networks" },
+ { 0x34c, "Cavium Networks" },
+ { 0x34f, "Intrinsity" },
+ { 0x351, "Terawave Communications" },
+ { 0x352, "IceFyre Semiconductor" },
+ { 0x354, "Picochip Designs Ltd" },
+ { 0x357, "Pijnenburg Securealink" },
+ { 0x358, "MemorySolutionN" },
+ { 0x35b, "Nazomi Communications" },
+ { 0x35d, "Rockwell Collins" },
+ { 0x35e, "PAION" },
+ { 0x361, "SiCon Video" },
+ { 0x362, "NanoAmp Solutions" },
+ { 0x364, "PrairieComm" },
+ { 0x367, "Atsana Semiconductor" },
+ { 0x368, "Allegro Networks" },
+ { 0x36b, "NVIDIA" },
+ { 0x36d, "Peak Electronics" },
+ { 0x370, "Teradiant Networks" },
+ { 0x373, "RAM Components" },
+ { 0x375, "ClearSpeed" },
+ { 0x376, "Matsushita Battery de Baja" },
+ { 0x379, "Utron Technology" },
+ { 0x37a, "Astec Intl" },
+ { 0x37c, "Redux Communications" },
+ { 0x383, "Melco" },
+ { 0x385, "Cyan Technologies" },
+ { 0x386, "Global Locate" },
+ { 0x389, "Ikanos Communications" },
+ { 0x38a, "Princeton Technology" },
+ { 0x38c, "Elite Flash Storage" },
+ { 0x38f, "ATI Technologies" },
+ { 0x391, "NeoMagic" },
+ { 0x392, "AuroraNectics" },
+ { 0x394, "Muskin" },
+ { 0x397, "TeraLogic" },
+ { 0x398, "Cicada Semiconductor" },
+ { 0x39b, "Magis Works" },
+ { 0x39d, "Cogency Semiconductor" },
+ { 0x39e, "Chipcon AS" },
+ { 0x3a1, "Programmable Silicon Soluctions" },
+ { 0x3a2, "ChipWrights" },
+ { 0x3a4, "Quicklogic" },
+ { 0x3a7, "Flasys" },
+ { 0x3a8, "BitBlitz Communications" },
+ { 0x3ab, "Purple Ray" },
+ { 0x3ad, "Delta Electronics" },
+ { 0x3ae, "Onex Communications" },
+ { 0x3b0, "Memory Experts Intl" },
+ { 0x3b3, "Dibcom" },
+ { 0x3b5, "API NetWorks" },
+ { 0x3b6, "Bay Microsystems" },
+ { 0x3b9, "Tachys Technologies" },
+ { 0x3ba, "Equator Technology" },
+ { 0x3bc, "SILCOM" },
+ { 0x3bf, "Sanera Systems" },
+ { 0x3c1, "Viasystems Group" },
+ { 0x3c2, "Simtek" },
+ { 0x3c4, "Satron Handelsges" },
+ { 0x3c7, "Corrent" },
+ { 0x3c8, "Infrant Technologies" },
+ { 0x3cb, "Hypertec" },
+ { 0x3cd, "PLX Technology" },
+ { 0x3ce, "Massana Design" },
+ { 0x3d0, "Valence Semiconductor" },
+ { 0x3d3, "Primarion" },
+ { 0x3d5, "Silverback Systems" },
+ { 0x3d6, "Jade Star Technologies" },
+ { 0x3d9, "Cambridge Silicon Radio" },
+ { 0x3da, "Swissbit" },
+ { 0x3dc, "eWave System" },
+ { 0x3df, "Alphamosaic Ltd" },
+ { 0x3e0, "Sandburst" },
+ { 0x3e3, "Ericsson Technology" },
+ { 0x3e5, "Mitac International" },
+ { 0x3e6, "Layer N Networks" },
+ { 0x3e9, "Marvell Semiconductor" },
+ { 0x3ea, "Netergy Microelectronic" },
+ { 0x3ec, "Internet Machines" },
+ { 0x3ef, "Accton Technology Corporation" },
+ { 0x3f2, "Cortina Systems" },
+ { 0x3f4, "Raqia Network" },
+ { 0x3f7, "Xelerated" },
+ { 0x3f8, "SimpleTech" },
+ { 0x3fb, "AVM gmbH" },
+ { 0x3fd, "Dot Hill Systems Corp." },
+ { 0x3fe, "TeraChip" },
+ { 0x401, "T-RAM Incorporated" },
+ { 0x402, "Innovics Wireless" },
+ { 0x404, "KeyEye Communications" },
+ { 0x407, "Dotcast" },
+ { 0x408, "Silicon Mountain Memory" },
+ { 0x40b, "Galazar Networks" },
+ { 0x40d, "Patriot Scientific" },
+ { 0x40e, "Neoaxiom Corporation" },
+ { 0x410, "Europe Technologies" },
+ { 0x413, "Digital Communications Technology Incorporated" },
+ { 0x415, "Fulcrum Microsystems" },
+ { 0x416, "Positivo Informatica Ltd" },
+ { 0x419, "Zhiying Software" },
+ { 0x41a, "Direct2Data" },
+ { 0x41c, "Skyworks Solutions" },
+ { 0x41f, "Zensys A/S" },
+ { 0x420, "Legend Silicon Corp" },
+ { 0x423, "Renesas Technology" },
+ { 0x425, "Phyworks" },
+ { 0x426, "MediaTek" },
+ { 0x429, "Wintegra Ltd" },
+ { 0x42a, "Mathstar" },
+ { 0x42c, "Oplus Technologies" },
+ { 0x42f, "Radia Communications" },
+ { 0x43e, "Endicott Interconnect Tech" },
+ { 0x483, "Teknovus" },
+ { 0x485, "Runcom Technologies" },
+ { 0x486, "RedSwitch" },
+ { 0x489, "Signia Technologies" },
+ { 0x48a, "Pixim" },
+ { 0x48c, "White Electronics Designs" },
+ { 0x48f, "3Y Power Technology" },
+ { 0x491, "Potentia Power Systems" },
+ { 0x492, "C-guys Incorporated" },
+ { 0x494, "Silicon-Based Technology" },
+ { 0x497, "XIOtech Corporation" },
+ { 0x498, "PortalPlayer" },
+ { 0x49b, "Phonex Broadband" },
+ { 0x49d, "Entropic Communications" },
+ { 0x49e, "Pacific Force Technology" },
+ { 0x4a1, "sci-worx GmbH" },
+ { 0x4a2, "Oasis Silicon Systems" },
+ { 0x4a4, "Raza Microelectronics" },
+ { 0x4a7, "Non-cents Productions" },
+ { 0x4a8, "US Modular" },
+ { 0x4ab, "StarCore" },
+ { 0x4ad, "Mindspeed" },
+ { 0x4ae, "Just Young Computer" },
+ { 0x4b0, "OCZ" }
+};
+
+fru_enum_t FRU_Type[] = {
+ { 0x0, "Unknown FRU" },
+ { 0x101, "System Controller" },
+ { 0x102, "SP System Controller" },
+ { 0x201, "CPU Board" },
+ { 0x202, "WCI CPU Board CPU WIB" },
+ { 0x203, "Zulu CPU Board" },
+ { 0x204, "CPU Board V2" },
+ { 0x205, "CPU Board V3" },
+ { 0x206, "LW8_CPU_Board" },
+ { 0x207, "LW8 CPU Board V3" },
+ { 0x301, "L2 Board" },
+ { 0x302, "Logic Analyzer Board" },
+ { 0x303, "SP L2 Board" },
+ { 0x401, "DC IO Fan Tray" },
+ { 0x402, "DC CPU Fan Tray" },
+ { 0x403, "Rack Fan Tray" },
+ { 0x404, "ME Fan Tray" },
+ { 0x405, "MD IO Fan Tray" },
+ { 0x406, "MD CPU Fan Tray" },
+ { 0x407, "MD Top Fan Tray" },
+ { 0x408, "SP Fan Tray" },
+ { 0x409, "MD Bottom IO Fan Tray" },
+ { 0x40a, "LW8_Fan_Tray" },
+ { 0x40b, "MD Top IO High Volume Fan Tray" },
+ { 0x40c, "MD Bottom Left IO High Volume Fan Tray" },
+ { 0x40d, "MD Bottom Right IO High Volume Fan Tray" },
+ { 0x501, "PCI IO Board" },
+ { 0x502, "CPCI IO Board" },
+ { 0x503, "SP CPCI IO Board" },
+ { 0x504, "WCI CPCI IO Board NonSP IO WIB" },
+ { 0x505, "WCI SP CPCI IO Board SPonly IO WIB" },
+ { 0x506, "LW8_PCI_Board" },
+ { 0x507, "PCIX IO Board" },
+ { 0x601, "A123 Power Supply" },
+ { 0x602, "A138 Power Supply" },
+ { 0x603, "A145 Power Supply" },
+ { 0x604, "A152 Power Supply" },
+ { 0x605, "A153 Power Supply" },
+ { 0x606, "A145E Power Supply" },
+ { 0x607, "A166_Module" },
+ { 0x608, "D142_Module" },
+ { 0x609, "A184 Power Supply" },
+ { 0x60a, "A185 Power Supply" },
+ { 0x701, "SP Centerplane" },
+ { 0x702, "DC Centerplane w/ID Board" },
+ { 0x703, "ME Centerplane w/ID Board" },
+ { 0x704, "MD Centerplane w/ID Board" },
+ { 0x705, "SP Replacement Centerplane" },
+ { 0x706, "DS Replacement Centerplane" },
+ { 0x707, "ME Replacement Centerplane" },
+ { 0x708, "MD Replacement Centerplane" },
+ { 0x709, "Generic Replacement ID Board" },
+ { 0x70a, "LW8_SCC" },
+ { 0x70b, "LW8_AC_Chassis" },
+ { 0x70c, "LW8_DC_Chassis" },
+ { 0x70d, "4900 Centerplane w/ID Board" },
+ { 0x70e, "6900 Centerplance w/ID Board" },
+ { 0x70f, "4900 Replacement Centerplane" },
+ { 0x710, "6900 Replacement Centerplane" },
+ { 0x801, "Top Cap Asm Frame Manager" },
+ { 0x901, "RTS Seq" },
+ { 0xa01, "2MB Ecache" },
+ { 0xa02, "4MB Ecache" },
+ { 0xa03, "8MB Ecache" },
+ { 0xa04, "16MB Ecache" },
+ { 0xb00, "64 MB DIMM" },
+ { 0xb01, "128 MB DIMM" },
+ { 0xb02, "256 MB DIMM" },
+ { 0xb03, "512 MB DIMM" },
+ { 0xb04, "1024 MB DIMM" },
+ { 0xb05, "2048 MB DIMM" },
+ { 0xc01, "COU WIB Paroli Opt Mod" },
+ { 0xc02, "CPCI FF Paroli Single Link Mod" },
+ { 0xc03, "CPCI FF Paroli Double Link Mod" },
+ { 0xc04, "New_EnumCodee" },
+ { 0xc05, "New_EnumCode" },
+ { 0xc06, "New_EnumCodeeo" },
+ { 0xd01, "2MB_WC_DIMM" },
+ { 0xd02, "10MB_WC_DIMM" },
+ { 0xd03, "20MB_WC_DIMM" },
+ { 0xd04, "40MB_WC_DIMM" },
+ { 0xd05, "Cluster_WC_DIMM" },
+ { 0xd06, "20MB_WC_ECC_DIMM" },
+ { 0xd07, "40MB_WC_ECC_DIMM" },
+ { 0xd08, "Cluster_WC_ECC_DIMM" },
+ { 0xe01, "LW8_PDB" },
+ { 0xe02, "LW8_Baseplane" },
+ { 0xe03, "LW8_Indicator_BD" },
+ { 0xe04, "LW8_Media_Bay" },
+ { 0xe05, "2900_Indicator_BD" }
+};
+
+fru_enum_t CPU_Type[] = {
+ { 0x0, "Cheetah" },
+ { 0x1, "Jubatus" }
+};
+
+fru_enum_t Cause_Code[] = {
+ { 0x1f4, "ENGINEERING REVIEW NTF" },
+ { 0x1f5, "SHOTGUN" },
+ { 0x1f6, "DEFECTIVE COMPONENT REPLACED" },
+ { 0x1f7, "POWER SUPPLY REPLACE/REPAIR" },
+ { 0x1f8, "VIDEO PCB REPLACE/REPAIR" },
+ { 0x1f9, "DEFLECTION PCB REPLACE/REPAIR" },
+ { 0x1fa, "I/O PCB REPLACE/REPAIR" },
+ { 0x1fb, "SCRAP" },
+ { 0x1fc, "REPLACE BEZEL" },
+ { 0x1fd, "REPLACE BACKCOVER" },
+ { 0x1fe, "REPLACE BASE" },
+ { 0x1ff, "REPLACE CRT" },
+ { 0x200, "REPLACE SUBASSEMBLY (OTHER)" },
+ { 0x201, "HIGH VOLTAGE (Flyback) REPLACED" },
+ { 0x202, "B & W OUT OF ADJUSTMENT" },
+ { 0x203, "WHITE BALANCE OUT OF ADJUSTMENT" },
+ { 0x204, "CONVERGENCE OUT OF ADJUSTMENT" },
+ { 0x205, "REJUVENATION" },
+ { 0x206, "RESTORE CRT" },
+ { 0x207, "YOKE ASSEMBLY REPLACEMENT" },
+ { 0x208, "RFB1-P4 DA-CAPS" },
+ { 0x209, "BAD / DIRTY CONNECTION" },
+ { 0x20a, "THERMAL INTERMITTENT DEVICE" },
+ { 0x20b, "VOLTAGE MARGIN FAILURE" },
+ { 0x20c, "FREQUENCY MARGIN FAILURE" },
+ { 0x20d, "BAD DATE CODE" },
+ { 0x20e, "SHORTED TRACE" },
+ { 0x20f, "OPEN TRACE" },
+ { 0x210, "DEVICE DEAD/NO OUTPUT" },
+ { 0x211, "INTERMITTENT DEVICE" },
+ { 0x212, "REPLACE / FLASH PROM" },
+ { 0x213, "RECONFIGURE JUMPER / SWITCH" },
+ { 0x214, "REPLACE CONNECTOR" },
+ { 0x215, "BENT PIN" },
+ { 0x216, "MISSING COMPONENT(S)/HARDWARE" },
+ { 0x217, "WRONG COMPONENT(S)/HARDWARE" },
+ { 0x218, "COMPONENT INCORRECTLY INSTALLED" },
+ { 0x219, "COLD SOLDER" },
+ { 0x21a, "SOLDER BRIDGE" },
+ { 0x21b, "UNSOLDERED" },
+ { 0x21c, "CANNOT DUPLICATE ERROR" },
+ { 0x21d, "INADEQUATE DIAGNOSTICS" },
+ { 0x21e, "ECO INCORRECTLY INSTALLED" },
+ { 0x21f, "ADJUST TO SPEC" },
+ { 0x220, "ECO UPGRADE" },
+ { 0x221, "REPLACED FAN" },
+ { 0x222, "BURNT" },
+ { 0x223, "CLEAN & TEST" },
+ { 0x224, "DAMAGED FAB" },
+ { 0x225, "AUTO SCRAP" },
+ { 0x226, "REPLACED BLOWN FUSE" },
+ { 0x227, "REPLACED COMPONENT" },
+ { 0x228, "REPAIRED COMPONENT" },
+ { 0x229, "HIGH IMPEDANCE ETCH" },
+ { 0x22a, "SEATING PROBLEM" },
+ { 0x22b, "SOFTWARE PROBLEM" },
+ { 0x22c, "CONFIGURATION ERROR" },
+ { 0x22d, "OTHER" },
+ { 0x22e, "HEAD" },
+ { 0x22f, "SENSOR(S)" },
+ { 0x230, "MOTOR-REEL" },
+ { 0x231, "MOTOR-CAPSTAN" },
+ { 0x232, "MOTOR-STEPPER" },
+ { 0x233, "MOTOR-EJECT" },
+ { 0x234, "Code Not Used" },
+ { 0x235, "PCB-INTERFACE" },
+ { 0x236, "PCB-READ/WRITE" },
+ { 0x237, "PCB-SERVO" },
+ { 0x238, "PINCH ROLLER" },
+ { 0x239, "LEADER" },
+ { 0x23a, "REPLACED/REPAIRED DA/MAIN BOARD" },
+ { 0x23b, "REPLACED/REPAIRED AC ADAPTER" },
+ { 0x23c, "REPLACED/REPAIRED INVERTER PCB" },
+ { 0x23d, "REPLACED/REPAIRED USER CONTROL PCB" },
+ { 0x23e, "REPLACED FLAT PANEL" },
+ { 0x23f, "REPLACED/REPAIRED TMDS CABLE" },
+ { 0x240, "REPLACED/REPAIRED USER CONTROL CABLE" },
+ { 0x241, "REPLACED/REPAIRED BACKLIGHTS" },
+ { 0x242, "BLACK LEVEL ADJUST" },
+ { 0x243, "REPLACED/REPAIRED VIDEO INPUT CONNECTOR" },
+ { 0x244, "BATTERY REPLACEMENT" },
+ { 0x245, "RECHARGE BATTERY" },
+ { 0x246, "RETURN TO CUSTOMER" },
+ { 0x248, "NTF-MISSPULL" },
+ { 0x249, "NTF-MASS SWAP" },
+ { 0x24a, "NTF-SEATING ISSUE/BAD CONNECTION" },
+ { 0x24b, "NTF-CUSTOMER REQUEST REPLACEMENT" },
+ { 0x24c, "NTF-ECO UPGRADE PRIOR TO TEST" },
+ { 0x24d, "NTF-CANNOT DUPLICATE FAILURE" },
+ { 0x24e, "ROBOTICS MECHANICAL FAILURE-" }
+};
+
+fru_enum_t Error_Type[] = {
+ { 0x1, "UE" },
+ { 0x2, "CE" }
+};
+
+fru_enum_t Error_Platform[] = {
+ { 0x1, "Serengeti" },
+ { 0x2, "Excalibur" },
+ { 0x3, "Daktari" },
+ { 0x4, "Starcat" },
+ { 0x5, "Wildcat" }
+};
+
+fru_enum_t AFT_Struct[] = {
+ { 0x0, "None" },
+ { 0x1, "CPU" },
+ { 0x2, "IO PCI" },
+ { 0x3, "IO CPCI" },
+ { 0x4, "IO SP CPCI" },
+ { 0x5, "WCI CPU" },
+ { 0x6, "WCI IO CPCI" },
+ { 0x7, "WCI IO SP CPCI" }
+};
+
+fru_enum_t Device_Type[] = {
+ { 0x0, "Unknown Device" },
+ { 0x66, "Excalibur Motherboard" },
+ { 0xca, "Excalibur CPU 1MB Module" },
+ { 0xcb, "Excalibur CPU 4MB Module" },
+ { 0xcc, "Excalibur CPU 8MB Module" },
+ { 0xfb, "Graphics_Board" },
+ { 0x100, "Motherboard" },
+ { 0x101, "Daktari Motherboard" },
+ { 0x102, "Littleneck Motherboard" },
+ { 0x103, "Cherrystone Centerplane" },
+ { 0x104, "A42 Motherboard" },
+ { 0x200, "CPU Module" },
+ { 0x201, "Daktari CPU Module" },
+ { 0x202, "A42 1.064 GHZ CPU Memory Module" },
+ { 0x203, "A42 1.280 GHZ CPU Memory Module" },
+ { 0x204, "SeSi CMP Module" },
+ { 0x300, "IO Board" },
+ { 0x301, "Daktari IO Board" },
+ { 0x303, "Cherrystone Riser" },
+ { 0x400, "RSC Card" },
+ { 0x401, "Daktari RSC Card" },
+ { 0x402, "ALOM Card" },
+ { 0x403, "ALOM Plus Card" },
+ { 0x500, "Disk Backplane" },
+ { 0x501, "Daktari Disk Backplane" },
+ { 0x502, "Littleneck Disk Backplane" },
+ { 0x503, "Cherrystone Disk Backplane" },
+ { 0x504, "A42 SCSI Disk Backplane" },
+ { 0x505, "N42 SCSI Disk Backplane" },
+ { 0x600, "PDB Board" },
+ { 0x601, "Daktari PDB Board" },
+ { 0x602, "Littleneck PDB Board" },
+ { 0x603, "Cherrystone PDB Board" },
+ { 0x604, "N42 PDB Board" },
+ { 0x700, "Power Supply" },
+ { 0x701, "Daktari Power Supply" },
+ { 0x702, "Littleneck Power Supply" },
+ { 0x703, "Cherrystone Power Supply" },
+ { 0x704, "A42 AC Power Supply" },
+ { 0x800, "GBIC Board" },
+ { 0x801, "Daktari GBIC Board" },
+ { 0x900, "LoopB Card" },
+ { 0x901, "Daktari LoopB Card" }
+};
+
+fru_enum_t Ecache_Mode[] = {
+ { 0x0, "Late_Write" },
+ { 0x1, "Late_Select" }
+};
+
+fru_enum_t Repair_Sympton_Code[] = {
+ { 0x1, "NTF" },
+ { 0x2, "ECO UPDATE" },
+ { 0x3, "FIRST PASS NTF" },
+ { 0x4, "POOR / MISSING ESD PROTECTION" },
+ { 0x5, "NO FAILURE INFORMATION" },
+ { 0x6, "RETEST ONLY" },
+ { 0x7, "DOWN REV" },
+ { 0x8, "DAMAGED - COSMETIC" },
+ { 0x9, "BURNT." },
+ { 0xa, "DAMAGED CONNECTIONS" },
+ { 0xb, "MECHANICAL / PHYSICAL DAMAGE" },
+ { 0xc, "NO POWER" },
+ { 0xd, "RECEIVED DAMAGED" },
+ { 0xe, "WILL NOT BOOT SCSI" },
+ { 0xf, "NOISY - AUDIBLE" },
+ { 0x10, "NOISE - ELECTRICAL" },
+ { 0x11, "SELF TEST FAILURE" },
+ { 0x12, "MECHANICAL FAILURE" },
+ { 0x13, "NONFUNCTIONAL/NO RESPONSE" },
+ { 0x14, "VTS/SUNDIAG ERROR" },
+ { 0x15, "WILL NOT BOOT UNIX" },
+ { 0x16, "MISSING COMPONENT(S)" },
+ { 0x17, "ETHERNET PROBLEM" },
+ { 0x18, "LOST POWER (INTERMITTENT)" },
+ { 0x19, "DIAGNOSTIC FAILURE (OTHER)" },
+ { 0x1a, "POST TEST FAILURE" },
+ { 0x1b, "WORKMANSHIP" },
+ { 0x1c, "DAMAGED CABLE" },
+ { 0x1d, "MISSING HARDWARE" },
+ { 0x1e, "ENVIRONMENTAL FAILURE" },
+ { 0x1f, "DEFECTIVE SCSI PORT" },
+ { 0x20, "DIRTY" },
+ { 0x21, "BAD FAN" },
+ { 0x22, "MODIFIED / ABUSED UNIT" },
+ { 0x23, "UNRELEASED PRODUCT" },
+ { 0x24, "NON-SUN UNIT" },
+ { 0x64, "DISTORTED VIDEO" },
+ { 0x65, "UNSTABLE VIDEO" },
+ { 0x66, "NO VIDEO" },
+ { 0x67, "DIM VIDEO" },
+ { 0x68, "POOR FOCUS" },
+ { 0x69, "IMAGE QUALITY" },
+ { 0x6a, "DAMAGED CRT" },
+ { 0x6b, "GEOMETRY OUT OF SPEC" },
+ { 0x6c, "IMAGE SIZING PROBLEM" },
+ { 0x6d, "PHOSPHOR AGED/DEFECTS" },
+ { 0x6e, "MISSING/POOR COLORS" },
+ { 0x6f, "BAD CONVERGENCE" },
+ { 0x70, "BLANKING VIDEO" },
+ { 0x71, "FLASHING VIDEO" },
+ { 0x72, "SHADOWING" },
+ { 0x73, "NO SYNC" },
+ { 0x74, "SPOT KILL" },
+ { 0x75, "RIGHTNESS UNIFORMITY" },
+ { 0x76, "DAMAGED FLAT PANEL" },
+ { 0x77, "DEFECTIVE FLAT PANEL" },
+ { 0x78, "DEFECTIVE ON-SCREEN DISPLAY" },
+ { 0x79, "DEFECTIVE AC/DC ADAPTER" },
+ { 0x7a, "DEFECTIVE/DIM BACKLIGHT" },
+ { 0x7b, "PANEL CONTAMINATION" },
+ { 0x7c, "PIXEL CONTAMINATION" },
+ { 0xc8, "BAD CPU/SRAM" },
+ { 0xc9, "SRAM PURGE FAIL" },
+ { 0xca, "E10K R-CORE FAILURE" },
+ { 0xcb, "PLASTIC CPU" },
+ { 0xcc, "MOUSE FAILURE" },
+ { 0xcd, "SYSTEM PANIC/TRAP ERROR" },
+ { 0xce, "FAILS A.T.E." },
+ { 0xcf, "TOD FAILURE" },
+ { 0xd0, "MEMORY FAILURE/ERROR" },
+ { 0xd1, "KEYBOARD FAILURE" },
+ { 0xd2, "DEFECTIVE SERIAL PORT" },
+ { 0xd3, "WATCHDOG RESET/TIMEOUT" },
+ { 0xd4, "WILL NOT SEE OTHER BOARDS" },
+ { 0xd5, "E-CACHE PARITY ERROR" },
+ { 0xd6, "PARITY ERROR (MEMORY)" },
+ { 0xd7, "DEFECTIVE PARALLEL PORT" },
+ { 0xd8, "ARB-STOP" },
+ { 0xd9, "GRANT PARITY ERROR" },
+ { 0xda, "HANGS (LOCK-UP)" },
+ { 0xdb, "POWER-ON SEQUENCE FAILURE" },
+ { 0xdc, "PARITY ERROR-PSI BUS" },
+ { 0xdd, "POWER STAT" },
+ { 0xde, "GRANT TIME-OUT" },
+ { 0xdf, "PARITY ERROR R-BUS" },
+ { 0xe0, "RECORD STOP" },
+ { 0xe1, "PLL ERROR" },
+ { 0xe2, "DTAG PARITY ERROR" },
+ { 0xe3, "INTERCONNECT TEST FAILURE" },
+ { 0xe4, "DATA BUS INTEGRITY ERROR" },
+ { 0x12c, "WILL NOT FORMAT" },
+ { 0x12d, "MISSING DEFECT LIST" },
+ { 0x12e, "EXCESSIVE DEFECTS" },
+ { 0x12f, "DRIVE FAULTS" },
+ { 0x130, "SEEK ERRORS" },
+ { 0x131, "READ/WRITE ERRORS" },
+ { 0x132, "WILL NOT SPIN UP" },
+ { 0x133, "EXCESSIVE SOFT ERRORS" },
+ { 0x134, "HARD-UNRECOVERABLE ECC-ERR" },
+ { 0x135, "WILL NOT COME READY" },
+ { 0x136, "MISSING (SOFT) LABEL" },
+ { 0x137, "DEFECTIVE BLOCKS" },
+ { 0x138, "PRINTER JAMS" },
+ { 0x139, "POOR PRINT QUALITY" },
+ { 0x13a, "WILL NOT EJECT MEDIA" },
+ { 0x13b, "WILL NOT LOAD MEDIA" },
+ { 0x13c, "ROBOTICS MECHANICAL FAILURE" },
+ { 0x190, "BATTERY VOLTAGE" },
+ { 0x191, "CONTROL VOLTAGE PROBLEM" },
+ { 0x192, "ENERGY OUTPUT PROBLEM" },
+ { 0x193, "FAILS CURRENT SHARE" },
+ { 0x194, "HIPOT/GND CONTINUITY PROBLEM" },
+ { 0x195, "REGULATION PROBLEM" },
+ { 0x196, "OUTPUT VOLTAGE PROBLEM" },
+ { 0x197, "IN_OUT VOLTAGE PROBLEM" }
+};
+
+fru_enum_t Initiator_30[] = {
+ { 0x65, "Depot" },
+ { 0x66, "Field_Eng" },
+ { 0x67, "CTE" },
+ { 0x68, "Customer" },
+ { 0xc9, "SMS" },
+ { 0xca, "SCAPP" },
+ { 0xcb, "POST" },
+ { 0xcc, "OBP" },
+ { 0xcd, "OBDIAG" },
+ { 0xce, "Kernel" },
+ { 0xcf, "Driver" },
+ { 0xd0, "SUNVTS" },
+ { 0xd1, "AFR" },
+ { 0xd2, "COD" },
+ { 0xd3, "Fault Management" },
+ { 0xd4, "ES SP Software" }
+};
+
+fru_enum_t Power_Events_50[] = {
+ { 0x1, "power_on" },
+ { 0x2, "still_on" },
+ { 0x3, "power_off" }
+};
+
+fru_enum_t Error_Code[] = {
+ { 0x0, "UNKNOWN_SoftError" },
+ { 0x1, "Correctable ECC Errors" },
+ { 0x2, "Uncorrectable ECC Errors" },
+ { 0x3, "Correctable ECC error from E$" },
+ { 0x4, "Uncorrectable ECC error from E$" },
+ { 0x5, "Correctable ECC error from E$ for Write-back" },
+ { 0x6, "Uncorrectable ECC error from E$ for Write-back" },
+ { 0x7, "Copy-Out correctable ECC Error" },
+ { 0x8, "Copy-Out uncorrectble ECC Error" },
+ { 0x9, "Software Handled Correctable E$ Error" },
+ { 0xa, "Software Handled Uncorrectable E$ Error" },
+ { 0xb, "Correctable MTAG ECC Error" },
+ { 0xc, "Uncorrectable MTAG ECC Error" }
+};
+
+fru_enum_t Status_Event_Code_71[] = {
+ { 0x0, "UNKNOWN" },
+ { 0xffff0001, "Excess" },
+ { 0xffff0002, "Obsolete" },
+ { 0xffff0003, "Not Repairable" },
+ { 0xffff0004, "Reliability" },
+ { 0xffff0005, "Economics" }
+};
+
+fru_enum_t Boolean_90[] = {
+ { 0x0, "False" },
+ { 0x1, "True" }
+};
+
+fru_enum_t SPD_Module_Bank_Density_110[] = {
+ { 0x10, "64MB" },
+ { 0x20, "128MB" },
+ { 0x40, "256MB" },
+ { 0x80, "512MB" },
+ { 0xff, "1GB" }
+};
+
+fru_enum_t SPD_Sun_Mod_Power_Parm_111[] = {
+ { 0x18, "2.4W" },
+ { 0x30, "4.8W" },
+ { 0x60, "9.6W" }
+};
+
+fru_enum_t SPD_Memory_Type[] = {
+ { 0x1, "Standard FPM DRAM" },
+ { 0x2, "EDO" },
+ { 0x3, "Pipelined Nibble" },
+ { 0x4, "Sync Dram (SDRAM)" },
+ { 0x5, "Multiplexed ROM" },
+ { 0x6, "SGRAM DDR" },
+ { 0x7, "SDRAM DDR" },
+ { 0x8, "DDR II SDRAM" }
+};
+
+fru_enum_t SPD_Err_Detect[] = {
+ { 0x0, "Non-parity" },
+ { 0x1, "Parity" },
+ { 0x2, "ECC" }
+};
+
+
+fru_enum_t ManR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Fru_Description" },
+ { 2, "Manufacture_Loc" },
+ { 3, "Sun_Part_No" },
+ { 4, "Sun_Serial_No" },
+ { 5, "Vendor_Name" },
+ { 6, "Initial_HW_Dash_Level" },
+ { 7, "Initial_HW_Rev_Level" },
+ { 8, "Fru_Shortname" }
+};
+
+fru_enum_t UsageR[] = {
+ { 0, "Number_of_Updates" },
+ { 1, "Last_Power_On" },
+ { 2, "Total_Errors" },
+ { 3, "Total_Inserts" },
+ { 4, "Total_Power_Ons_old" },
+ { 5, "Total_Time_On" }
+};
+
+fru_enum_t HW_Data_R[] = {
+ { 0, "HW_Dash_Level" },
+ { 1, "Hardware_Revision" }
+};
+
+fru_enum_t SG_CenterplaneR[] = {
+ { 0, "Board_Speed" },
+ { 1, "DomainAEthernetAddr" },
+ { 2, "DomainBEthernetAddr" },
+ { 3, "DomainCEthernetAddr" },
+ { 4, "DomainDEthernetAddr" },
+ { 5, "MasterSCEthernetAddr" },
+ { 6, "SlaveSCEthernetAddr" }
+};
+
+fru_enum_t SG_BoardParameterR[] = {
+ { 0, "Board_Speed" },
+ { 1, "SG_Bootbus_Timing" }
+};
+
+fru_enum_t L2_BoardR[] = {
+ { 0, "Board_Speed" }
+};
+
+fru_enum_t SP_FanTrayR[] = {
+ { 0, "Fan_Pair_Mask" },
+ { 1, "Fan_Startup_Delay" },
+ { 2, "Fan_Present_Mask" }
+};
+
+fru_enum_t ExcalCPUR[] = {
+ { 0, "Cache_Size" },
+ { 1, "CPU_Max_Safari_Speed" },
+ { 2, "CPU_Speed" },
+ { 3, "CPU_Type" },
+ { 4, "Ecache_Module_IDR" },
+ { 5, "SRAM_Manufacturer" },
+ { 6, "SRAM_Speed" }
+};
+
+fru_enum_t ExcalUsageR[] = {
+ { 0, "HoursAtHalfSpeed" },
+ { 1, "HoursAtOne32ndSpeed" },
+ { 2, "HoursAtFullSpeed" }
+};
+
+fru_enum_t Dak_MotherboardR[] = {
+ { 0, "PROM_Format_Version" },
+ { 1, "Device_Type" },
+ { 2, "Min_Bus_Speed" },
+ { 3, "Max_Bus_Speed" },
+ { 4, "Num_CPU_Module_Slots" },
+ { 5, "Ambient_Temp_Array" },
+ { 6, "Bootbus_Timing" },
+ { 7, "JTAG_Info_Pointer" },
+ { 8, "Min_Power_Rating" },
+ { 9, "Max_Power_Rating" },
+ { 10, "StickClock" },
+ { 11, "Junction_Temp_Array" },
+ { 12, "Reserved_24" }
+};
+
+fru_enum_t Dak_DualCPUModuleR[] = {
+ { 0, "PROM_Format_Version" },
+ { 1, "Device_Type" },
+ { 2, "Num_CPUs_in_Module" },
+ { 3, "Ambient_Temp_Array" },
+ { 4, "Junction_Temp_Array" },
+ { 5, "Cache_Size" },
+ { 6, "Cache_Timing" },
+ { 7, "Ecache_Features" },
+ { 8, "CPU_Speed" },
+ { 9, "Min_Bus_Speed" },
+ { 10, "Max_Bus_Speed" },
+ { 11, "JTAG_Info_Pointer" },
+ { 12, "Min_Power_Rating" },
+ { 13, "Max_Power_Rating" },
+ { 14, "CPU0_Features" },
+ { 15, "CPU1_Features" },
+ { 16, "CPU0_DIMMBank0_Map" },
+ { 17, "CPU0_DIMMBank1_Map" },
+ { 18, "CPU1_DIMMBank0_Map" },
+ { 19, "CPU1_DIMMBank1_Map" },
+ { 20, "Reserved" }
+};
+
+fru_enum_t Dak_RSCR[] = {
+ { 0, "PROM_Format_Version" },
+ { 1, "Device_Type" },
+ { 2, "Ethernet_Addr" },
+ { 3, "Ambient_Temp_Array" },
+ { 4, "Memory_Size" },
+ { 5, "Min_Power_Rating" },
+ { 6, "Max_Power_Rating" }
+};
+
+fru_enum_t Dak_IOBoardR[] = {
+ { 0, "PROM_Format_Version" },
+ { 1, "Device_Type" },
+ { 2, "Ambient_Temp_Array" },
+ { 3, "Min_Power_Rating" },
+ { 4, "Max_Power_Rating" }
+};
+
+fru_enum_t Dak_DBPR[] = {
+ { 0, "PROM_Format_Version" },
+ { 1, "Device_Type" },
+ { 2, "Ambient_Temp_Array" },
+ { 3, "WWN" },
+ { 4, "Min_Power_Rating" },
+ { 5, "Max_Power_Rating" },
+ { 6, "Max_Power_Distribution" }
+};
+
+fru_enum_t Dak_PDBR[] = {
+ { 0, "PROM_Format_Version" },
+ { 1, "Device_Type" },
+ { 2, "Ambient_Temp_Array" },
+ { 3, "Voltage_Rails" },
+ { 4, "Min_Power_Rating" },
+ { 5, "Max_Power_Rating" },
+ { 6, "Max_Power_Distribution" }
+};
+
+fru_enum_t Dak_PowersupplyR[] = {
+ { 0, "PROM_Format_Version" },
+ { 1, "Device_Type" },
+ { 2, "Max_Power_Distribution" }
+};
+
+fru_enum_t Dak_FCAL_GBICR[] = {
+ { 0, "PROM_Format_Version" },
+ { 1, "Device_Type" }
+};
+
+fru_enum_t Ecache_Module_IDR[] = {
+ { 0, "Lot_Code" },
+ { 1, "Date_Code" }
+};
+
+fru_enum_t EcacheR[] = {
+ { 0, "SRAM_Speed" },
+ { 1, "SRAM_Size" }
+};
+
+fru_enum_t DIMM_R[] = {
+ { 0, "DIMM_Speed" },
+ { 1, "DIMM_Size" }
+};
+
+fru_enum_t CPUBoardSpeedR[] = {
+ { 0, "CPU0_Speed" },
+ { 1, "CPU1_Speed" },
+ { 2, "CPU2_Speed" },
+ { 3, "CPU3_Speed" }
+};
+
+fru_enum_t SG_CPUSpeedR[] = {
+ { 0, "CPU0_SerialNum" },
+ { 1, "CPU0_Speed" },
+ { 2, "CPU1_SerialNum" },
+ { 3, "CPU1_Speed" },
+ { 4, "CPU2_SerialNum" },
+ { 5, "CPU2_Speed" },
+ { 6, "CPU3_SerialNum" },
+ { 7, "CPU3_Speed" }
+};
+
+fru_enum_t ExcalMotherboardR[] = {
+ { 0, "Ethernet_Addr" }
+};
+
+fru_enum_t Repair_DetailR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Repair_Vendor" },
+ { 2, "Repair_Location" },
+ { 3, "Case_Number" },
+ { 4, "Fault_Detail" },
+ { 5, "Dash_Number_In" },
+ { 6, "Dash_Number_Out" },
+ { 7, "Symptom_Code" },
+ { 8, "Cause_Code" },
+ { 9, "Components_Replaced" }
+};
+
+fru_enum_t Repair_Update[] = {
+ { 0, "HW_Dash_Level" },
+ { 1, "Hardware_Revision" },
+ { 2, "Firmware_Revision" },
+ { 3, "Total_Returns" },
+ { 4, "Total_Repairs" }
+};
+
+fru_enum_t Lit_DBPR[] = {
+ { 0, "PROM_Format_Version" },
+ { 1, "Device_Type" },
+ { 2, "Ambient_Temp_Array" },
+ { 3, "WWN" },
+ { 4, "Min_Power_Rating" },
+ { 5, "Max_Power_Rating" }
+};
+
+fru_enum_t DIMM_Conf_R[] = {
+ { 0, "SPD_Version" },
+ { 1, "Fru_Type" }
+};
+
+fru_enum_t InstallationR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Fru_Path" },
+ { 2, "Parent_Part_Number" },
+ { 3, "Parent_Serial_Number" },
+ { 4, "Parent_Dash_Level" },
+ { 5, "System_Id" },
+ { 6, "System_Tz" },
+ { 7, "Geo_North" },
+ { 8, "Geo_East" },
+ { 9, "Geo_Alt" },
+ { 10, "Geo_Location" }
+};
+
+fru_enum_t Power_EventsR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Event" }
+};
+
+fru_enum_t Power_SummaryR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Total_Time_On" },
+ { 2, "Total_Power_Ons" },
+ { 3, "Total_Power_Offs" }
+};
+
+fru_enum_t Temperature_HistoryR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Sensor" },
+ { 2, "Lowest" },
+ { 3, "Highest" },
+ { 4, "Latest" },
+ { 5, "Histogram" }
+};
+
+fru_enum_t Status_CurrentR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Status" }
+};
+
+fru_enum_t Status_EventsR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Old_Status" },
+ { 2, "New_Status" },
+ { 3, "Initiator" },
+ { 4, "Component" },
+ { 5, "Event_Code" },
+ { 6, "Message" }
+};
+
+fru_enum_t Soft_ErrorsR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Component" },
+ { 2, "Softerror_Code" },
+ { 3, "Syndrome" }
+};
+
+fru_enum_t ECO_CurrentR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Firmware_Revision" },
+ { 2, "Hardware_Revision" },
+ { 3, "HW_Dash_Level" }
+};
+
+fru_enum_t Customer_DataR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Cust_Data" }
+};
+
+fru_enum_t MD_Bottom_IO_FanTrayR[] = {
+ { 0, "Fan_Pair_Mask" },
+ { 1, "Fan_Startup_Delay" },
+ { 2, "Fan_Present_Mask" }
+};
+
+fru_enum_t MD_CPU_Three_FanTrayR[] = {
+ { 0, "Fan_Pair_Mask" },
+ { 1, "Fan_Startup_Delay" },
+ { 2, "Fan_Present_Mask" }
+};
+
+fru_enum_t ME_Three_FanTrayR[] = {
+ { 0, "Fan_Pair_Mask" },
+ { 1, "Fan_Startup_Delay" },
+ { 2, "Fan_Present_Mask" }
+};
+
+fru_enum_t DS_CPU_Six_FanTrayR[] = {
+ { 0, "Fan_Pair_Mask" },
+ { 1, "Fan_Startup_Delay" },
+ { 2, "Fan_Present_Mask" }
+};
+
+fru_enum_t DS_IO_Four_FanTrayR[] = {
+ { 0, "Fan_Pair_Mask" },
+ { 1, "Fan_Startup_Delay" },
+ { 2, "Fan_Present_Mask" }
+};
+
+fru_enum_t MD_Top_FanTrayR[] = {
+ { 0, "Fan_Pair_Mask" },
+ { 1, "Fan_Startup_Delay" },
+ { 2, "Fan_Present_Mask" }
+};
+
+fru_enum_t Repair_SummaryR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Total_Returns" },
+ { 2, "Total_Repairs" }
+};
+
+fru_enum_t Dak_DBPNameR[] = {
+ { 0, "Loop_A_Name" },
+ { 1, "Loop_B_Name" }
+};
+
+fru_enum_t Sheffield_RCP_FirmwareR[] = {
+ { 0, "Sun_Part_No" },
+ { 1, "HW_Dash_Level" }
+};
+
+fru_enum_t PROM_FirmwareR[] = {
+ { 0, "Sun_Part_No" },
+ { 1, "HW_Dash_Level" }
+};
+
+fru_enum_t Sheffield_Bridge_FirmwareR[] = {
+ { 0, "Sun_Part_No" },
+ { 1, "HW_Dash_Level" }
+};
+
+fru_enum_t Temperature_LimitsR[] = {
+ { 0, "Lowest_Temp_Limit" },
+ { 1, "Highest_Temp_Limit" }
+};
+
+fru_enum_t Error_SummaryR[] = {
+ { 0, "Hard_Errors" },
+ { 1, "Soft_Errors" }
+};
+
+fru_enum_t Temperature_ExcessR[] = {
+ { 0, "Time_Below" },
+ { 1, "Time_Above" }
+};
+
+fru_enum_t CPUR[] = {
+ { 0, "Num_CPUs_in_Module" },
+ { 1, "CPU_Speed" },
+ { 2, "Cache_Size" },
+ { 3, "RAM" }
+};
+
+fru_enum_t SG_FanTrayR[] = {
+ { 0, "Fan_Present_Mask" },
+ { 1, "Fan_Pair_Mask" },
+ { 2, "Fan_Startup_Delay" }
+};
+
+fru_enum_t SG_PowerSupplyR[] = {
+ { 0, "AMB_Warning_Level" },
+ { 1, "AMB_Shutdown_Level" },
+ { 2, "V1_CUR_Warning_Low_Line" },
+ { 3, "V1_CUR_Warning_High_Line" },
+ { 4, "V1_CUR_Shutdown_Low_Line" },
+ { 5, "V1_CUR_Shutdown_High_Line" },
+ { 6, "V1_VLT_Under_Warning" },
+ { 7, "V1_VLT_Under_Shutdown" },
+ { 8, "V1_VLT_Over_Warning" },
+ { 9, "V1_VLT_Over_Shutdown" },
+ { 10, "V1_Power_Rating_Low_Line" },
+ { 11, "V1_Power_Rating_High_Line" }
+};
+
+fru_enum_t Sheffield_Split_ModeR[] = {
+ { 0, "Sheffield_Split_Mode_Flags" },
+ { 1, "HostID0" },
+ { 2, "HostID1" },
+ { 3, "Sheffield_Fixed_Hardware" },
+ { 4, "Sheffield_SideA_Hardware" },
+ { 5, "Sheffield_SideB_Hardware" }
+};
+
+fru_enum_t SG_HostIdR[] = {
+ { 0, "SG_HostId_A" },
+ { 1, "SG_HostId_B" },
+ { 2, "SG_HostId_C" },
+ { 3, "SG_HostId_D" },
+ { 4, "SG_HostId_SC0" },
+ { 5, "SG_HostId_SC1" }
+};
+
+fru_enum_t WCI_CalibrationR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "WCI_A_Rcalibrated" },
+ { 2, "WCI_B_Rcalibrated" },
+ { 3, "WCI_Tcalibrated" }
+};
+
+fru_enum_t Wildcat_IO_DIMM_Lot[] = {
+ { 0, "Lot_Code" }
+};
+
+fru_enum_t Cum_Power_SummaryR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Total_Time_On" },
+ { 2, "Total_Power_Ons" },
+ { 3, "Total_Power_Offs" }
+};
+
+fru_enum_t Cum_Temperature_HistoryR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Sensor" },
+ { 2, "Lowest" },
+ { 3, "Highest" },
+ { 4, "Latest" },
+ { 5, "Histogram" }
+};
+
+fru_enum_t Configured_LevelR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Sun_Part_No" },
+ { 2, "Configured_Serial_No" },
+ { 3, "HW_Dash_Level" }
+};
+
+fru_enum_t SPD_ParametersR[] = {
+ { 0, "SPD_Bytes_Written_SPDMemory" },
+ { 1, "SPD_TotBytes_SPDMemory" },
+ { 2, "SPD_Fund_Memory_Type" },
+ { 3, "SPD_Row_Address_Bits" },
+ { 4, "SPD_Column_Address_Bits" },
+ { 5, "SPD_No_Banks_Assembly" },
+ { 6, "SPD_Data_Width_Module" },
+ { 7, "SPD_Mod_Data_Width" },
+ { 8, "SPD_Mod_Voltage_Interface" },
+ { 9, "SPD_Cycle_Time" },
+ { 10, "SPD_Access_Time" },
+ { 11, "SPD_Module_Config_Type" },
+ { 12, "SPD_Refresh_RateType" },
+ { 13, "SPD_Primary_SDRAM_Width" },
+ { 14, "SPD_Error_Check_SDRAM_Width" },
+ { 15, "SPD_Min_Clock_Delay" },
+ { 16, "SPD_Burst_Length_Support" },
+ { 17, "SPD_No_Banks_SDRAM_Device" },
+ { 18, "SPD_Device_Attrib_CAS" },
+ { 19, "SPD_Device_Attrib_CS" },
+ { 20, "SPD_Device_Attrib_Write" },
+ { 21, "SPD_Module_Attrib" },
+ { 22, "SPD_Device_Attrib_Gen" },
+ { 23, "SPD_Min_Cycle_Time_CL2tCC2" },
+ { 24, "SPD_Max_Access_Time_CL2tSAC2" },
+ { 25, "SPD_Min_Cycle_Time_CL1tCC1" },
+ { 26, "SPD_Max_Access_Time_CL1tSAC1" },
+ { 27, "SPD_Min_Row_Precharge_Time" },
+ { 28, "SPD_Min_Row_Delay" },
+ { 29, "SPD_Min_RAS_To_CAS_Delay" },
+ { 30, "SPD_Min_Ras_Pulse_Width" },
+ { 31, "SPD_Module_Bank_Density" },
+ { 32, "SPD_Sig_Input_Setup_Time" },
+ { 33, "SPD_Sig_Input_Hold_Time" },
+ { 34, "SPD_Data_Sig_Input_Setup_Time" },
+ { 35, "SPD_Data_Sig_Input_Hold_Time" },
+ { 36, "SPD_Sun_Copyright" },
+ { 37, "Spare_7bytes" },
+ { 38, "SPD_Data_Edition_Code" },
+ { 39, "SPD_TSHZ_Max_Nbrs_CAS_Lat" },
+ { 40, "SPD_TSLZ_CLK_To_Output" },
+ { 41, "SPD_Data_Revision_Code" },
+ { 42, "Checksum_8" },
+ { 43, "SPD_Old_Man_Code" },
+ { 44, "SPD_Old_Man_Loc" },
+ { 45, "SPD_Manufacturer_Part_No" },
+ { 46, "SPD_Man_Rev_Code_Pcb" },
+ { 47, "SPD_Man_Rev_Code_Comp" },
+ { 48, "SPD_Manufacture_Date_Week" },
+ { 49, "SPD_Manufacture_Date_Year" },
+ { 50, "SPD_Old_Assembly_Serial_No" },
+ { 51, "SPD_Old_Sun_Part_No" },
+ { 52, "SPD_Sun_Module_Power_Parm" },
+ { 53, "SPD_Sun_Mod_Power_Parm_2" },
+ { 54, "SPD_Sun_Mod_Cycle_Time" },
+ { 55, "SPD_Sun_Mod_Cycle_Time_TOH" },
+ { 56, "SPD_Old_Sun_Module_Label_Info" },
+ { 57, "SPD_Mode_Register_Data_1" },
+ { 58, "SPD_Mode_Register_Data_2" },
+ { 59, "Spare_8bytes" },
+ { 60, "SPD_Module_Freq" },
+ { 61, "SPD_CAS_Latencies" },
+ { 62, "SPD_Edge_Connect_Sig_Dq0" },
+ { 63, "SPD_Edge_Connect_Sig_Dq1" },
+ { 64, "SPD_Edge_Connect_Sig_Dq2" },
+ { 65, "SPD_Edge_Connect_Sig_Dq3" },
+ { 66, "SPD_Edge_Connect_Sig_Dq4" },
+ { 67, "SPD_Edge_Connect_Sig_Dq5" },
+ { 68, "SPD_Edge_Connect_Sig_Dq6" },
+ { 69, "SPD_Edge_Connect_Sig_Dq7" },
+ { 70, "SPD_Edge_Connect_Sig_Dq8" },
+ { 71, "SPD_Edge_Connect_Sig_Dq9" },
+ { 72, "SPD_Edge_Connect_Sig_Dq10" },
+ { 73, "SPD_Edge_Connect_Sig_Dq11" },
+ { 74, "SPD_Edge_Connect_Sig_Dq12" },
+ { 75, "SPD_Edge_Connect_Sig_Dq13" },
+ { 76, "SPD_Edge_Connect_Sig_Dq14" },
+ { 77, "SPD_Edge_Connect_Sig_Dq15" },
+ { 78, "SPD_Edge_Connect_Sig_Dq16" },
+ { 79, "SPD_Edge_Connect_Sig_Dq17" },
+ { 80, "SPD_Edge_Connect_Sig_Dq18" },
+ { 81, "SPD_Edge_Connect_Sig_Dq19" },
+ { 82, "SPD_Edge_Connect_Sig_Dq20" },
+ { 83, "SPD_Edge_Connect_Sig_Dq21" },
+ { 84, "SPD_Edge_Connect_Sig_Dq22" },
+ { 85, "SPD_Edge_Connect_Sig_Dq23" },
+ { 86, "SPD_Edge_Connect_Sig_Dq24" },
+ { 87, "SPD_Edge_Connect_Sig_Dq25" },
+ { 88, "SPD_Edge_Connect_Sig_Dq26" },
+ { 89, "SPD_Edge_Connect_Sig_Dq27" },
+ { 90, "SPD_Edge_Connect_Sig_Dq28" },
+ { 91, "SPD_Edge_Connect_Sig_Dq29" },
+ { 92, "SPD_Edge_Connect_Sig_Dq30" },
+ { 93, "SPD_Edge_Connect_Sig_Dq31" },
+ { 94, "SPD_Edge_Connect_Sig_Dq32" },
+ { 95, "SPD_Edge_Connect_Sig_Dq33" },
+ { 96, "SPD_Edge_Connect_Sig_Dq34" },
+ { 97, "SPD_Edge_Connect_Sig_Dq35" },
+ { 98, "SPD_Edge_Connect_Sig_Dq36" },
+ { 99, "SPD_Edge_Connect_Sig_Dq37" },
+ { 100, "SPD_Edge_Connect_Sig_Dq38" },
+ { 101, "SPD_Edge_Connect_Sig_Dq39" },
+ { 102, "SPD_Edge_Connect_Sig_Dq40" },
+ { 103, "SPD_Edge_Connect_Sig_Dq41" },
+ { 104, "SPD_Edge_Connect_Sig_Dq42" },
+ { 105, "SPD_Edge_Connect_Sig_Dq43" },
+ { 106, "SPD_Edge_Connect_Sig_Dq44" },
+ { 107, "SPD_Edge_Connect_Sig_Dq45" },
+ { 108, "SPD_Edge_Connect_Sig_Dq46" },
+ { 109, "SPD_Edge_Connect_Sig_Dq47" },
+ { 110, "SPD_Edge_Connect_Sig_Dq48" },
+ { 111, "SPD_Edge_Connect_Sig_Dq49" },
+ { 112, "SPD_Edge_Connect_Sig_Dq50" },
+ { 113, "SPD_Edge_Connect_Sig_Dq51" },
+ { 114, "SPD_Edge_Connect_Sig_Dq52" },
+ { 115, "SPD_Edge_Connect_Sig_Dq53" },
+ { 116, "SPD_Edge_Connect_Sig_Dq54" },
+ { 117, "SPD_Edge_Connect_Sig_Dq55" },
+ { 118, "SPD_Edge_Connect_Sig_Dq56" },
+ { 119, "SPD_Edge_Connect_Sig_Dq57" },
+ { 120, "SPD_Edge_Connect_Sig_Dq58" },
+ { 121, "SPD_Edge_Connect_Sig_Dq59" },
+ { 122, "SPD_Edge_Connect_Sig_Dq60" },
+ { 123, "SPD_Edge_Connect_Sig_Dq61" },
+ { 124, "SPD_Edge_Connect_Sig_Dq62" },
+ { 125, "SPD_Edge_Connect_Sig_Dq63" },
+ { 126, "SPD_Edge_Connect_Sig_Dq64" },
+ { 127, "SPD_Edge_Connect_Sig_Dq65" },
+ { 128, "SPD_Edge_Connect_Sig_Dq66" },
+ { 129, "SPD_Edge_Connect_Sig_Dq67" },
+ { 130, "SPD_Edge_Connect_Sig_Dq68" },
+ { 131, "SPD_Edge_Connect_Sig_Dq69" },
+ { 132, "SPD_Edge_Connect_Sig_Dq70" },
+ { 133, "SPD_Edge_Connect_Sig_Dq71" },
+ { 134, "SPD_Edge_Connect_Sig_Dq72" },
+ { 135, "SPD_Edge_Connect_Sig_Dq73" },
+ { 136, "SPD_Edge_Connect_Sig_Dq74" },
+ { 137, "SPD_Edge_Connect_Sig_Dq75" },
+ { 138, "SPD_Edge_Connect_Sig_Dq76" },
+ { 139, "SPD_Edge_Connect_Sig_Dq77" },
+ { 140, "SPD_Edge_Connect_Sig_Dq78" },
+ { 141, "SPD_Edge_Connect_Sig_Dq79" },
+ { 142, "SPD_Edge_Connect_Sig_Dq80" },
+ { 143, "SPD_Edge_Connect_Sig_Dq81" },
+ { 144, "SPD_Edge_Connect_Sig_Dq82" },
+ { 145, "SPD_Edge_Connect_Sig_Dq83" },
+ { 146, "SPD_Edge_Connect_Sig_Dq84" },
+ { 147, "SPD_Edge_Connect_Sig_Dq85" },
+ { 148, "SPD_Edge_Connect_Sig_Dq86" },
+ { 149, "SPD_Edge_Connect_Sig_Dq87" },
+ { 150, "SPD_Edge_Connect_Sig_Dq88" },
+ { 151, "SPD_Edge_Connect_Sig_Dq89" },
+ { 152, "SPD_Edge_Connect_Sig_Dq90" },
+ { 153, "SPD_Edge_Connect_Sig_Dq91" },
+ { 154, "SPD_Edge_Connect_Sig_Dq92" },
+ { 155, "SPD_Edge_Connect_Sig_Dq93" },
+ { 156, "SPD_Edge_Connect_Sig_Dq94" },
+ { 157, "SPD_Edge_Connect_Sig_Dq95" },
+ { 158, "SPD_Edge_Connect_Sig_Dq96" },
+ { 159, "SPD_Edge_Connect_Sig_Dq97" },
+ { 160, "SPD_Edge_Connect_Sig_Dq98" },
+ { 161, "SPD_Edge_Connect_Sig_Dq99" },
+ { 162, "SPD_Edge_Connect_Sig_Dq100" },
+ { 163, "SPD_Edge_Connect_Sig_Dq101" },
+ { 164, "SPD_Edge_Connect_Sig_Dq102" },
+ { 165, "SPD_Edge_Connect_Sig_Dq103" },
+ { 166, "SPD_Edge_Connect_Sig_Dq104" },
+ { 167, "SPD_Edge_Connect_Sig_Dq105" },
+ { 168, "SPD_Edge_Connect_Sig_Dq106" },
+ { 169, "SPD_Edge_Connect_Sig_Dq107" },
+ { 170, "SPD_Edge_Connect_Sig_Dq108" },
+ { 171, "SPD_Edge_Connect_Sig_Dq109" },
+ { 172, "SPD_Edge_Connect_Sig_Dq110" },
+ { 173, "SPD_Edge_Connect_Sig_Dq111" },
+ { 174, "SPD_Edge_Connect_Sig_Dq112" },
+ { 175, "SPD_Edge_Connect_Sig_Dq113" },
+ { 176, "SPD_Edge_Connect_Sig_Dq114" },
+ { 177, "SPD_Edge_Connect_Sig_Dq115" },
+ { 178, "SPD_Edge_Connect_Sig_Dq116" },
+ { 179, "SPD_Edge_Connect_Sig_Dq117" },
+ { 180, "SPD_Edge_Connect_Sig_Dq118" },
+ { 181, "SPD_Edge_Connect_Sig_Dq119" },
+ { 182, "SPD_Edge_Connect_Sig_Dq120" },
+ { 183, "SPD_Edge_Connect_Sig_Dq121" },
+ { 184, "SPD_Edge_Connect_Sig_Dq122" },
+ { 185, "SPD_Edge_Connect_Sig_Dq123" },
+ { 186, "SPD_Edge_Connect_Sig_Dq124" },
+ { 187, "SPD_Edge_Connect_Sig_Dq125" },
+ { 188, "SPD_Edge_Connect_Sig_Dq126" },
+ { 189, "SPD_Edge_Connect_Sig_Dq127" },
+ { 190, "SPD_Edge_Connect_Sig_Dq128" },
+ { 191, "SPD_Edge_Connect_Sig_Dq129" },
+ { 192, "SPD_Edge_Connect_Sig_Dq130" },
+ { 193, "SPD_Edge_Connect_Sig_Dq131" },
+ { 194, "SPD_Edge_Connect_Sig_Dq132" },
+ { 195, "SPD_Edge_Connect_Sig_Dq133" },
+ { 196, "SPD_Edge_Connect_Sig_Dq134" },
+ { 197, "SPD_Edge_Connect_Sig_Dq135" },
+ { 198, "SPD_Edge_Connect_Sig_Dq136" },
+ { 199, "SPD_Edge_Connect_Sig_Dq137" },
+ { 200, "SPD_Edge_Connect_Sig_Dq138" },
+ { 201, "SPD_Edge_Connect_Sig_Dq139" },
+ { 202, "SPD_Edge_Connect_Sig_Dq140" },
+ { 203, "SPD_Edge_Connect_Sig_Dq141" },
+ { 204, "SPD_Edge_Connect_Sig_Dq142" },
+ { 205, "SPD_Edge_Connect_Sig_Dq143" },
+ { 206, "SPD_Sun_Mod_Label_Info" },
+ { 207, "Spare_49bytes" }
+};
+
+fru_enum_t Laser_Power_EventsR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Event" }
+};
+
+fru_enum_t Laser_Power_SummaryR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Total_Time_On" },
+ { 2, "Total_Power_Ons" },
+ { 3, "Total_Power_Offs" }
+};
+
+fru_enum_t Laser_Cum_Power_SummaryR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Total_Time_On" },
+ { 2, "Total_Power_Ons" },
+ { 3, "Total_Power_Offs" }
+};
+
+fru_enum_t COD_CPUSpeedR[] = {
+ { 0, "CPU0_SerialNum" },
+ { 1, "CPU0_Speed" },
+ { 2, "CPU1_SerialNum" },
+ { 3, "CPU1_Speed" },
+ { 4, "CPU2_SerialNum" },
+ { 5, "CPU2_Speed" },
+ { 6, "CPU3_SerialNum" },
+ { 7, "CPU3_Speed" }
+};
+
+fru_enum_t EthernetMACAddr2R[] = {
+ { 0, "Ethernet_Addr" },
+ { 1, "Ethernet_Addr2" }
+};
+
+fru_enum_t Status_Proxy1R[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Version" },
+ { 2, "StatusMap31" }
+};
+
+fru_enum_t Status_Proxy2R[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Version" },
+ { 2, "StatusMap127" }
+};
+
+fru_enum_t Sun_Part_Number_DataR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Sun_Part_No" },
+ { 2, "Sun_Serial_No" },
+ { 3, "Vendor_Name" },
+ { 4, "Initial_HW_Dash_Level" }
+};
+
+fru_enum_t Fault_DataR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Error_Code" },
+ { 2, "Fault_Code" }
+};
+
+fru_enum_t BatteryWarrantyR[] = {
+ { 0, "WarrantyDuration" },
+ { 1, "RefreshCycle" },
+ { 2, "ShelfLife" }
+};
+
+fru_enum_t EthernetMACAddrRangeR[] = {
+ { 0, "Ethernet_Addr" },
+ { 1, "Ethernet_Addr_Range" }
+};
+
+fru_enum_t Drawer_DescriptionR[] = {
+ { 0, "Drawer_Type" },
+ { 1, "Access_Model" },
+ { 2, "Disk_Presence" },
+ { 3, "Power_Type" },
+ { 4, "Sun_Part_No" },
+ { 5, "Sun_Serial_No" },
+ { 6, "Diskslot1_Label" },
+ { 7, "Diskslot2_Label" },
+ { 8, "Fanslot1_Label" },
+ { 9, "Fanslot2_Label" },
+ { 10, "Psuslot1_Label" },
+ { 11, "Psuslot2_Label" },
+ { 12, "Scbslot_Label" },
+ { 13, "Rmmslot_Label" },
+ { 14, "Pdu1_Label" },
+ { 15, "Pdu2_Label" }
+};
+
+fru_enum_t Drawer_ConfigR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Drawer_Cfg" },
+ { 2, "Power_Supply_Cfg" },
+ { 3, "Location" },
+ { 4, "User_Label" }
+};
+
+fru_enum_t Drawer_InfoR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Drawer_Id" },
+ { 2, "Drawer_Type" },
+ { 3, "Access_Model" },
+ { 4, "Slot_Mode" },
+ { 5, "Reserved_Data" }
+};
+
+fru_enum_t CPUFirmwareR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "CPU_FW_Part_No" },
+ { 2, "CPU_FW_Dash_Level" }
+};
+
+fru_enum_t Netra_ACFirmwareR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "BCFW_Part_No" },
+ { 2, "BCFW_Dash_Level" },
+ { 3, "CMSW_Part_No" },
+ { 4, "CMSW_Dash_Level" },
+ { 5, "BMCFW_Part_No" },
+ { 6, "BMCFW_Dash_Level" }
+};
+
+fru_enum_t Fru_DescriptionR[] = {
+ { 0, "Fru_Type" },
+ { 1, "External_Label" },
+ { 2, "Min_Power_Rating" },
+ { 3, "Max_Power_Rating" },
+ { 4, "Fru_Description_StringG" },
+ { 5, "Fru_Description_StringL" }
+};
+
+fru_enum_t CPCI_Slot_DataR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Acceptable_Fru_Types" },
+ { 2, "Slot_Mode" },
+ { 3, "Boot_Devices" }
+};
+
+fru_enum_t MCNet_ConfigR[] = {
+ { 0, "MCNetIPSubnet" },
+ { 1, "MCNetIPSubnetMask" },
+ { 2, "MCNetOpaque" }
+};
+
+fru_enum_t Battery_StatusR[] = {
+ { 0, "WarrantyStartDate" },
+ { 1, "LastRechargeDate" },
+ { 2, "LastHealthCheckDate" },
+ { 3, "BatteryStatus" }
+};
+
+fru_enum_t Battery_WarrantyR[] = {
+ { 0, "WarrantyDuration" },
+ { 1, "RefreshCycle" },
+ { 2, "ShelfLife" }
+};
+
+fru_enum_t Config_LevelR[] = {
+ { 0, "Configured_Serial_No" },
+ { 1, "Fru_Description" },
+ { 2, "FRU_Part_And_Dash_No" }
+};
+
+fru_enum_t Chassis_InfoR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Chassis_Id" },
+ { 2, "Chassis_Type" },
+ { 3, "Access_Model" },
+ { 4, "Reserved_Data" }
+};
+
+fru_enum_t Netra_DMCFirmwareR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "BCFW_Part_No" },
+ { 2, "BCFW_Dash_Level" },
+ { 3, "CMSW_Part_No" },
+ { 4, "CMSW_Dash_Level" },
+ { 5, "BMCFW_Part_No" },
+ { 6, "BMCFW_Dash_Level" }
+};
+
+fru_enum_t Chassis_DataR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Chassis_Id" },
+ { 2, "Chassis_Type" },
+ { 3, "Access_Model" },
+ { 4, "Reserved_Data" }
+};
+
+fru_enum_t DMCFirmwareR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "BCFW_Part_No" },
+ { 2, "BCFW_Dash_Level" },
+ { 3, "CMSW_Part_No" },
+ { 4, "CMSW_Dash_Level" },
+ { 5, "BMCFW_Part_No" },
+ { 6, "BMCFW_Dash_Level" }
+};
+
+fru_enum_t MaintenanceR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "New_Description" },
+ { 2, "New_Sun_Part_No" }
+};
+
+fru_enum_t SPD_R[] = {
+ { 0, "SPD_Bytes_Written_SPDMemory" },
+ { 1, "SPD_TotBytes_SPDMemory" },
+ { 2, "SPD_Fundamental_Memory_Type" },
+ { 3, "SPD_Row_Address_Bits" },
+ { 4, "SPD_Column_Address_Bits" },
+ { 5, "SPD_No_Banks_Assembly" },
+ { 6, "SPD_Module_Data_Width" },
+ { 7, "SPD_Mod_Voltage_Interface" },
+ { 8, "SPD_Cycle_Time" },
+ { 9, "SPD_Access_Time" },
+ { 10, "SPD_DIMM_Config_Type" },
+ { 11, "SPD_Type_Specific" },
+ { 12, "SPD_Data_Revision_Code" },
+ { 13, "Checksum_8" },
+ { 14, "Vendor_Name" },
+ { 15, "SPD_Man_Loc" },
+ { 16, "SPD_Manufacturer_Part_No" },
+ { 17, "SPD_Module_Rev_Code" },
+ { 18, "SPD_Manufacture_Year" },
+ { 19, "SPD_Manufacture_Week" },
+ { 20, "SPD_Assembly_Serial_No" },
+ { 21, "SPD_Man_Specific" }
+};
+
+fru_enum_t PlatformR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "Platform_Name" }
+};
+
+fru_enum_t PartNumber_ChangedR[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "From_Part_No" },
+ { 2, "From_Serial_No" },
+ { 3, "From_Dash_No" },
+ { 4, "To_Part_No" },
+ { 5, "To_Serial_No" },
+ { 6, "To_Dash_No" }
+};
+
+fru_enum_t FRU_Props_PrivateR[] = {
+ { 0, "SpecPartNo" },
+ { 1, "Properties" }
+};
+
+fru_enum_t Fan_Speeds[] = {
+ { 0, "Fan_Revs_Per_Sec" },
+ { 1, "Tacho_Pulses_Per_Rev" }
+};
+
+fru_enum_t FRU_Props_Private2R[] = {
+ { 0, "UNIX_Timestamp32" },
+ { 1, "SpecPartNo" },
+ { 2, "Properties" }
+};
+
+
+fru_regdef_t Element_Defs[] = {
+ {FRU_REVNO,
+ "AFT_Structure",
+ FRU_C,
+ 1,
+ 1,
+ 1,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 8,
+ AFT_Struct,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "AMB_Shutdown_Level",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "AMB_Warning_Level",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Acceptable_Fru_Types",
+ FRU_X,
+ 0,
+ 96,
+ 96,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Access_Model",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Ambient_Temp_Array",
+ FRU_X,
+ 0,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "BCFW_Dash_Level",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "BCFW_Part_No",
+ FRU_X,
+ 0,
+ 7,
+ 7,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "BMCFW_Dash_Level",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "BMCFW_Part_No",
+ FRU_X,
+ 0,
+ 7,
+ 7,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "BatteryStatus",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "BatteryWarrantyR",
+ FRU_G,
+ 1,
+ 16,
+ 16,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 3,
+ BatteryWarrantyR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Battery_StatusR",
+ FRU_C,
+ 2,
+ 13,
+ 13,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 4,
+ Battery_StatusR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Battery_WarrantyR",
+ FRU_C,
+ 2,
+ 12,
+ 12,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 3,
+ Battery_WarrantyR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Board_Speed",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Boot_Devices",
+ FRU_X,
+ 0,
+ 25,
+ 25,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Bootbus_Timing",
+ FRU_X,
+ 0,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CMSW_Dash_Level",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CMSW_Part_No",
+ FRU_X,
+ 0,
+ 7,
+ 7,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "COD_CPUSpeedR",
+ FRU_E,
+ 1,
+ 40,
+ 40,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 8,
+ COD_CPUSpeedR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CODenabled",
+ FRU_B,
+ 1,
+ 1,
+ 1,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 2,
+ Boolean_90,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPCI_Slot_DataR",
+ FRU_F,
+ 1,
+ 886,
+ 886,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 4,
+ CPCI_Slot_DataR,
+ 7,
+ FRU_Linear,
+ ""},
+ {FRU_REVNO,
+ "CPU0_DIMMBank0_Map",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU0_DIMMBank1_Map",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU0_Features",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU0_SerialNum",
+ FRU_X,
+ 0,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Binary,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU0_Speed",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU1_DIMMBank0_Map",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU1_DIMMBank1_Map",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU1_Features",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU1_SerialNum",
+ FRU_X,
+ 0,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Binary,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU1_Speed",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU2_SerialNum",
+ FRU_X,
+ 0,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Binary,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU2_Speed",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU3_SerialNum",
+ FRU_X,
+ 0,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Binary,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU3_Speed",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPUBoardSpeedR",
+ FRU_C,
+ 2,
+ 8,
+ 8,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 4,
+ CPUBoardSpeedR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPUFirmwareR",
+ FRU_C,
+ 1,
+ 13,
+ 13,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 3,
+ CPUFirmwareR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPUR",
+ FRU_C,
+ 4,
+ 8,
+ 8,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 4,
+ CPUR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU_FW_Dash_Level",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU_FW_Part_No",
+ FRU_X,
+ 0,
+ 7,
+ 7,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU_Max_Safari_Speed",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU_Speed",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "CPU_Type",
+ FRU_X,
+ 0,
+ 1,
+ 1,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 2,
+ CPU_Type,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Cache_Size",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Cache_Timing",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Case_Number",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Case_Number_old",
+ FRU_X,
+ 0,
+ 5,
+ 40,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Cause_Code",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 90,
+ Cause_Code,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Chassis_DataR",
+ FRU_E,
+ 1,
+ 76,
+ 76,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 5,
+ Chassis_DataR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Chassis_Id",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Chassis_InfoR",
+ FRU_G,
+ 1,
+ 76,
+ 76,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 5,
+ Chassis_InfoR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Chassis_Type",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Checksum_8",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Component",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Components_Replaced",
+ FRU_X,
+ 0,
+ 40,
+ 40,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Config_LevelR",
+ FRU_E,
+ 1,
+ 109,
+ 109,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 3,
+ Config_LevelR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Configured_LevelR",
+ FRU_E,
+ 1,
+ 33,
+ 33,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 4,
+ Configured_LevelR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Configured_Serial_No",
+ FRU_X,
+ 0,
+ 20,
+ 20,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Container_Header",
+ FRU_A,
+ 1,
+ 0,
+ 0,
+ FDTYPE_UNDEFINED,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Cum_Power_SummaryR",
+ FRU_C,
+ 4,
+ 16,
+ 16,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 4,
+ Cum_Power_SummaryR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Cum_Temperature_HistoryR",
+ FRU_E,
+ 2,
+ 32,
+ 32,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 6,
+ Cum_Temperature_HistoryR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Cust_Data",
+ FRU_X,
+ 0,
+ 80,
+ 80,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Customer_DataR",
+ FRU_E,
+ 3,
+ 84,
+ 84,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 2,
+ Customer_DataR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Customer_Private",
+ FRU_F,
+ 1,
+ 256,
+ 256,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DIMM_Capacity",
+ FRU_C,
+ 8,
+ 8,
+ 8,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DIMM_Conf_R",
+ FRU_B,
+ 1,
+ 4,
+ 4,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 2,
+ DIMM_Conf_R,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DIMM_Private74",
+ FRU_E,
+ 1,
+ 74,
+ 74,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DIMM_Private768",
+ FRU_F,
+ 1,
+ 768,
+ 768,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DIMM_Private768_2",
+ FRU_F,
+ 2,
+ 768,
+ 768,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DIMM_R",
+ FRU_E,
+ 2,
+ 4,
+ 4,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 2,
+ DIMM_R,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DIMM_Size",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DIMM_Speed",
+ FRU_E,
+ 1,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DMCFirmwareR",
+ FRU_C,
+ 2,
+ 31,
+ 31,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 7,
+ DMCFirmwareR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DS_CPU_Six_FanTrayR",
+ FRU_B,
+ 5,
+ 4,
+ 4,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 3,
+ DS_CPU_Six_FanTrayR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DS_IO_Four_FanTrayR",
+ FRU_B,
+ 6,
+ 4,
+ 4,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 3,
+ DS_IO_Four_FanTrayR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Dak_DBPNameR",
+ FRU_E,
+ 1,
+ 64,
+ 64,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 2,
+ Dak_DBPNameR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Dak_DBPR",
+ FRU_E,
+ 10,
+ 80,
+ 80,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 7,
+ Dak_DBPR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Dak_DualCPUModuleR",
+ FRU_F,
+ 1,
+ 121,
+ 121,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 21,
+ Dak_DualCPUModuleR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Dak_FCAL_GBICR",
+ FRU_B,
+ 11,
+ 4,
+ 4,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 2,
+ Dak_FCAL_GBICR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Dak_IOBoardR",
+ FRU_F,
+ 1,
+ 52,
+ 52,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 5,
+ Dak_IOBoardR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Dak_MotherboardR",
+ FRU_F,
+ 1,
+ 103,
+ 103,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 13,
+ Dak_MotherboardR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Dak_PDBR",
+ FRU_E,
+ 2,
+ 84,
+ 84,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 7,
+ Dak_PDBR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Dak_PowersupplyR",
+ FRU_C,
+ 11,
+ 24,
+ 24,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 3,
+ Dak_PowersupplyR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Dak_RSCR",
+ FRU_E,
+ 9,
+ 59,
+ 59,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 7,
+ Dak_RSCR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Dash_Number_In",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Dash_Number_Out",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Date_Code",
+ FRU_X,
+ 0,
+ 8,
+ 8,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Date_Of_Repair",
+ FRU_X,
+ 0,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Time,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Device_Type",
+ FRU_C,
+ 1,
+ 2,
+ 2,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 43,
+ Device_Type,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Devices",
+ FRU_B,
+ 3,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Binary,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Disk_Presence",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Diskslot1_Label",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Diskslot2_Label",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DomainAEthernetAddr",
+ FRU_X,
+ 0,
+ 6,
+ 48,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DomainBEthernetAddr",
+ FRU_X,
+ 0,
+ 6,
+ 48,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DomainCEthernetAddr",
+ FRU_X,
+ 0,
+ 6,
+ 48,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "DomainDEthernetAddr",
+ FRU_X,
+ 0,
+ 6,
+ 48,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Drawer_Cfg",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Drawer_ConfigR",
+ FRU_E,
+ 1,
+ 96,
+ 96,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 5,
+ Drawer_ConfigR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Drawer_DescriptionR",
+ FRU_E,
+ 1,
+ 77,
+ 77,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 16,
+ Drawer_DescriptionR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Drawer_Id",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Drawer_InfoR",
+ FRU_E,
+ 2,
+ 77,
+ 77,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 6,
+ Drawer_InfoR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Drawer_Type",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "ECO_CurrentR",
+ FRU_C,
+ 1,
+ 16,
+ 16,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 4,
+ ECO_CurrentR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "EcacheR",
+ FRU_E,
+ 1,
+ 3,
+ 3,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 2,
+ EcacheR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Ecache_Features",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Ecache_Mode",
+ FRU_A,
+ 1,
+ 1,
+ 1,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 2,
+ Ecache_Mode,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Ecache_Module_IDR",
+ FRU_E,
+ 1,
+ 84,
+ 84,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 2,
+ Ecache_Module_IDR,
+ 4,
+ FRU_Linear,
+ ""},
+ {FRU_REVNO,
+ "Error_Code",
+ FRU_X,
+ 0,
+ 1,
+ 1,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 13,
+ Error_Code,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Error_SummaryR",
+ FRU_B,
+ 10,
+ 4,
+ 4,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 2,
+ Error_SummaryR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "EthernetMACAddr2R",
+ FRU_C,
+ 1,
+ 12,
+ 12,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 2,
+ EthernetMACAddr2R,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "EthernetMACAddrRangeR",
+ FRU_C,
+ 7,
+ 8,
+ 8,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 2,
+ EthernetMACAddrRangeR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Ethernet_Addr",
+ FRU_A,
+ 1,
+ 6,
+ 48,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Ethernet_Addr2",
+ FRU_X,
+ 0,
+ 6,
+ 48,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Ethernet_Addr_Range",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Event",
+ FRU_X,
+ 0,
+ 1,
+ 1,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 3,
+ Power_Events_50,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Event_Code",
+ FRU_X,
+ 0,
+ 4,
+ 4,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 6,
+ Status_Event_Code_71,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "ExcalCPUR",
+ FRU_E,
+ 1,
+ 94,
+ 94,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 7,
+ ExcalCPUR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "ExcalMotherboardR",
+ FRU_A,
+ 2,
+ 6,
+ 6,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 1,
+ ExcalMotherboardR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "ExcalUsageR",
+ FRU_C,
+ 1,
+ 9,
+ 9,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 3,
+ ExcalUsageR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Experimental",
+ FRU_F,
+ 1,
+ 128,
+ 128,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "External_Label",
+ FRU_X,
+ 0,
+ 20,
+ 20,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "FRU_Part_And_Dash_No",
+ FRU_X,
+ 0,
+ 9,
+ 9,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "FRU_Props_Private2R",
+ FRU_E,
+ 1,
+ 63,
+ 63,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 3,
+ FRU_Props_Private2R,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "FRU_Props_PrivateR",
+ FRU_E,
+ 2,
+ 59,
+ 59,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 2,
+ FRU_Props_PrivateR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fan_Pair_Mask",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fan_Present_Mask",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fan_Revs_Per_Sec",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fan_Speeds",
+ FRU_C,
+ 1,
+ 28,
+ 28,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 2,
+ Fan_Speeds,
+ 8,
+ FRU_Linear,
+ ""},
+ {FRU_REVNO,
+ "Fan_Startup_Delay",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fanslot1_Label",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fanslot2_Label",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fault_Code",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fault_DataR",
+ FRU_A,
+ 1,
+ 7,
+ 7,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 3,
+ Fault_DataR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fault_Detail",
+ FRU_X,
+ 0,
+ 80,
+ 80,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Firmware_Revision",
+ FRU_X,
+ 0,
+ 8,
+ 8,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "From_Dash_No",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "From_Part_No",
+ FRU_X,
+ 0,
+ 7,
+ 7,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "From_Serial_No",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fru_Description",
+ FRU_X,
+ 0,
+ 80,
+ 80,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fru_DescriptionR",
+ FRU_F,
+ 1,
+ 382,
+ 382,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 6,
+ Fru_DescriptionR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fru_Description_StringG",
+ FRU_X,
+ 0,
+ 64,
+ 64,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fru_Description_StringL",
+ FRU_X,
+ 0,
+ 256,
+ 256,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fru_Path",
+ FRU_X,
+ 0,
+ 128,
+ 128,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fru_Shortname",
+ FRU_X,
+ 0,
+ 16,
+ 16,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Fru_Type",
+ FRU_A,
+ 2,
+ 2,
+ 2,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 90,
+ FRU_Type,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Geo_Alt",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Geo_East",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Geo_Location",
+ FRU_X,
+ 0,
+ 40,
+ 40,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Geo_North",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "HW_Dash_Level",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "HW_Data_R",
+ FRU_A,
+ 2,
+ 4,
+ 4,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 2,
+ HW_Data_R,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Hard_Errors",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Hardware_Revision",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Highest",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Highest_Temp_Limit",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Histogram",
+ FRU_X,
+ 0,
+ 24,
+ 192,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 10,
+ FRU_Linear,
+ ""},
+ {FRU_REVNO,
+ "HostID0",
+ FRU_B,
+ 12,
+ 4,
+ 4,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "HostID1",
+ FRU_B,
+ 13,
+ 4,
+ 4,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "HoursAtFullSpeed",
+ FRU_X,
+ 0,
+ 3,
+ 24,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "HoursAtHalfSpeed",
+ FRU_X,
+ 0,
+ 3,
+ 24,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "HoursAtOne32ndSpeed",
+ FRU_X,
+ 0,
+ 3,
+ 24,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Initial_HW_Dash_Level",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Initial_HW_Rev_Level",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Initiator",
+ FRU_X,
+ 0,
+ 1,
+ 1,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 16,
+ Initiator_30,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "InstallationR",
+ FRU_F,
+ 1,
+ 1099,
+ 1099,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 11,
+ InstallationR,
+ 5,
+ FRU_Circular,
+ ""},
+ {FRU_REVNO,
+ "JTAG_Info_Pointer",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Junction_Temp_Array",
+ FRU_X,
+ 0,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "L2_BoardR",
+ FRU_B,
+ 1,
+ 2,
+ 2,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 1,
+ L2_BoardR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Laser_Cum_Power_SummaryR",
+ FRU_C,
+ 6,
+ 16,
+ 16,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 4,
+ Laser_Cum_Power_SummaryR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Laser_Power_EventsR",
+ FRU_F,
+ 2,
+ 254,
+ 254,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 2,
+ Laser_Power_EventsR,
+ 50,
+ FRU_Circular,
+ ""},
+ {FRU_REVNO,
+ "Laser_Power_SummaryR",
+ FRU_C,
+ 5,
+ 16,
+ 16,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 4,
+ Laser_Power_SummaryR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "LastHealthCheckDate",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Time,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "LastRechargeDate",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Time,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Last_Power_On",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Time,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Latest",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Lit_DBPR",
+ FRU_E,
+ 1,
+ 60,
+ 60,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 6,
+ Lit_DBPR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Location",
+ FRU_X,
+ 0,
+ 80,
+ 80,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Loop_A_Name",
+ FRU_X,
+ 0,
+ 32,
+ 32,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Loop_B_Name",
+ FRU_X,
+ 0,
+ 32,
+ 32,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Lot_Code",
+ FRU_X,
+ 0,
+ 12,
+ 12,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Lowest",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Lowest_Temp_Limit",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "MCNetIPSubnet",
+ FRU_X,
+ 0,
+ 3,
+ 24,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "MCNetIPSubnetMask",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "MCNetOpaque",
+ FRU_X,
+ 0,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "MCNet_ConfigR",
+ FRU_C,
+ 1,
+ 15,
+ 15,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 3,
+ MCNet_ConfigR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "MD_Bottom_IO_FanTrayR",
+ FRU_B,
+ 2,
+ 4,
+ 4,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 3,
+ MD_Bottom_IO_FanTrayR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "MD_CPU_Three_FanTrayR",
+ FRU_B,
+ 3,
+ 4,
+ 4,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 3,
+ MD_CPU_Three_FanTrayR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "MD_Top_FanTrayR",
+ FRU_B,
+ 8,
+ 4,
+ 4,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 3,
+ MD_Top_FanTrayR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "ME_Three_FanTrayR",
+ FRU_B,
+ 4,
+ 4,
+ 4,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 3,
+ ME_Three_FanTrayR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "MaintenanceR",
+ FRU_F,
+ 1,
+ 264,
+ 264,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 3,
+ MaintenanceR,
+ 5,
+ FRU_Circular,
+ ""},
+ {FRU_REVNO,
+ "ManR",
+ FRU_F,
+ 1,
+ 183,
+ 183,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 9,
+ ManR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Manufacture_Loc",
+ FRU_X,
+ 0,
+ 64,
+ 64,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Marker",
+ FRU_C,
+ 1,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "MasterSCEthernetAddr",
+ FRU_X,
+ 0,
+ 6,
+ 48,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Max_Ambient_Temp",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Max_Bus_Speed",
+ FRU_A,
+ 1,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Max_Power_Distribution",
+ FRU_X,
+ 0,
+ 20,
+ 160,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 4,
+ FRU_Linear,
+ ""},
+ {FRU_REVNO,
+ "Max_Power_Rating",
+ FRU_X,
+ 0,
+ 20,
+ 160,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 4,
+ FRU_Linear,
+ ""},
+ {FRU_REVNO,
+ "Memory_Size",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Message",
+ FRU_X,
+ 0,
+ 128,
+ 128,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Microcode_Version",
+ FRU_C,
+ 3,
+ 16,
+ 16,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Min_Bus_Speed",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Min_Power_Rating",
+ FRU_X,
+ 0,
+ 20,
+ 160,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 4,
+ FRU_Linear,
+ ""},
+ {FRU_REVNO,
+ "Netra_ACFirmwareR",
+ FRU_C,
+ 1,
+ 31,
+ 31,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 7,
+ Netra_ACFirmwareR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Netra_DMCFirmwareR",
+ FRU_G,
+ 1,
+ 31,
+ 31,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 7,
+ Netra_DMCFirmwareR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "New_Description",
+ FRU_X,
+ 0,
+ 32,
+ 32,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "New_Status",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "New_Sun_Part_No",
+ FRU_X,
+ 0,
+ 16,
+ 16,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Num_CPU_Module_Slots",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Num_CPUs_in_Module",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Number_of_Updates",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Old_Status",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "PROM_FirmwareR",
+ FRU_C,
+ 4,
+ 9,
+ 9,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 2,
+ PROM_FirmwareR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "PROM_Format_Version",
+ FRU_E,
+ 2,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Parent_Dash_Level",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Parent_Part_Number",
+ FRU_X,
+ 0,
+ 7,
+ 7,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Parent_Serial_Number",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "PartNumber_ChangedR",
+ FRU_E,
+ 1,
+ 34,
+ 34,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 7,
+ PartNumber_ChangedR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Pdu1_Label",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Pdu2_Label",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "PlatformR",
+ FRU_C,
+ 2,
+ 24,
+ 24,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 2,
+ PlatformR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Platform_Name",
+ FRU_C,
+ 3,
+ 20,
+ 20,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Power_EventsR",
+ FRU_F,
+ 1,
+ 254,
+ 254,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 2,
+ Power_EventsR,
+ 50,
+ FRU_Circular,
+ ""},
+ {FRU_REVNO,
+ "Power_SummaryR",
+ FRU_C,
+ 2,
+ 16,
+ 16,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 4,
+ Power_SummaryR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Power_Supply_Cfg",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Power_Type",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Properties",
+ FRU_X,
+ 0,
+ 48,
+ 48,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Psuslot1_Label",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Psuslot2_Label",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "RAM",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "RefreshCycle",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Binary,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Repair_DetailR",
+ FRU_F,
+ 1,
+ 884,
+ 884,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 10,
+ Repair_DetailR,
+ 5,
+ FRU_Circular,
+ ""},
+ {FRU_REVNO,
+ "Repair_Location",
+ FRU_X,
+ 0,
+ 24,
+ 24,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Repair_SummaryR",
+ FRU_B,
+ 1,
+ 6,
+ 6,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 3,
+ Repair_SummaryR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Repair_Update",
+ FRU_E,
+ 1,
+ 14,
+ 14,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 5,
+ Repair_Update,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Repair_Vendor",
+ FRU_X,
+ 0,
+ 16,
+ 16,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Repair_Vendor_old",
+ FRU_X,
+ 0,
+ 15,
+ 15,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Reserved",
+ FRU_X,
+ 0,
+ 32,
+ 32,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Reserved_24",
+ FRU_X,
+ 0,
+ 24,
+ 24,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Reserved_Data",
+ FRU_X,
+ 0,
+ 64,
+ 64,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Rmmslot_Label",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SG_BoardParameterR",
+ FRU_E,
+ 4,
+ 30,
+ 30,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 2,
+ SG_BoardParameterR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SG_Bootbus_Timing",
+ FRU_X,
+ 0,
+ 28,
+ 224,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 6,
+ FRU_Linear,
+ ""},
+ {FRU_REVNO,
+ "SG_CPUSpeedR",
+ FRU_E,
+ 0,
+ 40,
+ 40,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 8,
+ SG_CPUSpeedR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SG_CenterplaneR",
+ FRU_E,
+ 4,
+ 38,
+ 38,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 7,
+ SG_CenterplaneR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SG_Cpu_Sparc_Freq",
+ FRU_B,
+ 2,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SG_FanTrayR",
+ FRU_B,
+ 9,
+ 4,
+ 4,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 3,
+ SG_FanTrayR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SG_HostIdR",
+ FRU_E,
+ 1,
+ 24,
+ 24,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 6,
+ SG_HostIdR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SG_HostId_A",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SG_HostId_B",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SG_HostId_C",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SG_HostId_D",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SG_HostId_SC0",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SG_HostId_SC1",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SG_PowerSupplyR",
+ FRU_C,
+ 1,
+ 14,
+ 14,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 12,
+ SG_PowerSupplyR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Access_Time",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Assembly_Serial_No",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Burst_Length_Support",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Bytes_Written_SPDMemory",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_CAS_Latencies",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Column_Address_Bits",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Cycle_Time",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_DIMM_Config_Type",
+ FRU_X,
+ 0,
+ 1,
+ 1,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 3,
+ SPD_Err_Detect,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Data_Edition_Code",
+ FRU_X,
+ 0,
+ 1,
+ 1,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Data_Revision_Code",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Data_Sig_Input_Hold_Time",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Data_Sig_Input_Setup_Time",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Data_Width_Module",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Device_Attrib_CAS",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Device_Attrib_CS",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Device_Attrib_Gen",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Device_Attrib_Write",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq0",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq1",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq10",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq100",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq101",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq102",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq103",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq104",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq105",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq106",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq107",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq108",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq109",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq11",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq110",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq111",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq112",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq113",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq114",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq115",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq116",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq117",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq118",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq119",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq12",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq120",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq121",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq122",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq123",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq124",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq125",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq126",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq127",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq128",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq129",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq13",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq130",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq131",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq132",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq133",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq134",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq135",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq136",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq137",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq138",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq139",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq14",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq140",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq141",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq142",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq143",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq15",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq16",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq17",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq18",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq19",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq2",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq20",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq20Dq142",
+ FRU_X,
+ 0,
+ 492,
+ 3936,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq21",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq22",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq23",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq24",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq25",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq26",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq27",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq28",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq29",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq3",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq30",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq31",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq32",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq33",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq34",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq35",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq36",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq37",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq38",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq39",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq4",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq40",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq41",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq42",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq43",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq44",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq45",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq46",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq47",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq48",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq49",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq5",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq50",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq51",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq52",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq53",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq54",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq55",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq56",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq57",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq58",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq59",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq6",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq60",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq61",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq62",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq63",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq64",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq65",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq66",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq67",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq68",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq69",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq7",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq70",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq71",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq72",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq73",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq74",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq75",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq76",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq77",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq78",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq79",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq8",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq80",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq81",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq82",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq83",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq84",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq85",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq86",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq87",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq88",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq89",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq9",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq90",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq91",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq92",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq93",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq94",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq95",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq96",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq97",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq98",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Edge_Connect_Sig_Dq99",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Error_Check_SDRAM_Width",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Fund_Memory_Type",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Fundamental_Memory_Type",
+ FRU_X,
+ 0,
+ 1,
+ 1,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 8,
+ SPD_Memory_Type,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Man_Loc",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Man_Rev_Code_Comp",
+ FRU_X,
+ 0,
+ 1,
+ 1,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Man_Rev_Code_Pcb",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Man_Specific",
+ FRU_X,
+ 0,
+ 29,
+ 29,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Manufacture_Date_Week",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Manufacture_Date_Year",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Manufacture_Week",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Manufacture_Year",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Manufacturer_Part_No",
+ FRU_X,
+ 0,
+ 18,
+ 18,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Max_Access_Time_CL1tSAC1",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Max_Access_Time_CL2tSAC2",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Min_Clock_Delay",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Min_Cycle_Time_CL1tCC1",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Min_Cycle_Time_CL2tCC2",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Min_RAS_To_CAS_Delay",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Min_Ras_Pulse_Width",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Min_Row_Delay",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Min_Row_Precharge_Time",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Mod_Data_Width",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Mod_Voltage_Interface",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Mode_Register_Data_1",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Mode_Register_Data_2",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Module_Attrib",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Module_Bank_Density",
+ FRU_X,
+ 0,
+ 1,
+ 1,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 5,
+ SPD_Module_Bank_Density_110,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Module_Config_Type",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Module_Data_Width",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Module_Freq",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Module_Rev_Code",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_No_Banks_Assembly",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_No_Banks_SDRAM_Device",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Old_Assembly_Serial_No",
+ FRU_X,
+ 0,
+ 3,
+ 24,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Old_Man_Code",
+ FRU_X,
+ 0,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Old_Man_Loc",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Old_Sun_Module_Label_Info",
+ FRU_X,
+ 0,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Old_Sun_Part_No",
+ FRU_X,
+ 0,
+ 5,
+ 40,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_ParametersR",
+ FRU_X,
+ 0,
+ 768,
+ 768,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 208,
+ SPD_ParametersR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Primary_SDRAM_Width",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_R",
+ FRU_E,
+ 1,
+ 123,
+ 123,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 22,
+ SPD_R,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Refresh_RateType",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Row_Address_Bits",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Sig_Input_Hold_Time",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Sig_Input_Setup_Time",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Sun_Copyright",
+ FRU_X,
+ 0,
+ 16,
+ 16,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Sun_Mod_Cycle_Time",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Sun_Mod_Cycle_Time_TOH",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Sun_Mod_Label_Info",
+ FRU_X,
+ 0,
+ 15,
+ 15,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Sun_Mod_Power_Parm_2",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Sun_Module_Power_Parm",
+ FRU_X,
+ 0,
+ 1,
+ 1,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 3,
+ SPD_Sun_Mod_Power_Parm_111,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_TSHZ_Max_Nbrs_CAS_Lat",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_TSLZ_CLK_To_Output",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_TotBytes_SPDMemory",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Type_Specific",
+ FRU_X,
+ 0,
+ 50,
+ 50,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SPD_Version",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SP_FanTrayR",
+ FRU_B,
+ 7,
+ 4,
+ 4,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 3,
+ SP_FanTrayR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SRAM_Manufacturer",
+ FRU_B,
+ 5,
+ 2,
+ 2,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 552,
+ Vendor,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SRAM_Size",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SRAM_Speed",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Safari_DIMM_Mapping_Pointer",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Scbslot_Label",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Segment_Trailer",
+ FRU_A,
+ 1,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Sensor",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Sheffield_Bridge_FirmwareR",
+ FRU_C,
+ 3,
+ 9,
+ 9,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 2,
+ Sheffield_Bridge_FirmwareR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Sheffield_Fixed_Hardware",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Sheffield_RCP_FirmwareR",
+ FRU_C,
+ 2,
+ 9,
+ 9,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 2,
+ Sheffield_RCP_FirmwareR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Sheffield_SideA_Hardware",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Sheffield_SideB_Hardware",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Sheffield_Split_ModeR",
+ FRU_C,
+ 1,
+ 27,
+ 27,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 6,
+ Sheffield_Split_ModeR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Sheffield_Split_Mode_Flags",
+ FRU_X,
+ 0,
+ 1,
+ 1,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "ShelfLife",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Binary,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Shutdown_Temperature",
+ FRU_B,
+ 2,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SlaveSCEthernetAddr",
+ FRU_X,
+ 0,
+ 6,
+ 48,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Slot_Mode",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Soft_Errors",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Soft_ErrorsR",
+ FRU_F,
+ 1,
+ 324,
+ 324,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 4,
+ Soft_ErrorsR,
+ 20,
+ FRU_Circular,
+ ""},
+ {FRU_REVNO,
+ "Softerror_Code",
+ FRU_X,
+ 0,
+ 1,
+ 1,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 13,
+ Error_Code,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Spare_49bytes",
+ FRU_X,
+ 0,
+ 49,
+ 49,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Spare_64bytes",
+ FRU_X,
+ 0,
+ 64,
+ 64,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Spare_7bytes",
+ FRU_X,
+ 0,
+ 7,
+ 56,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Spare_8bytes",
+ FRU_X,
+ 0,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SpecPartNo",
+ FRU_C,
+ 1,
+ 11,
+ 11,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Status",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "StatusMap127",
+ FRU_X,
+ 0,
+ 127,
+ 127,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "StatusMap31",
+ FRU_X,
+ 0,
+ 31,
+ 31,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Status_CurrentR",
+ FRU_B,
+ 1,
+ 5,
+ 5,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 2,
+ Status_CurrentR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Status_EventsR",
+ FRU_F,
+ 1,
+ 1404,
+ 1404,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 7,
+ Status_EventsR,
+ 10,
+ FRU_Circular,
+ ""},
+ {FRU_REVNO,
+ "Status_Proxy1R",
+ FRU_E,
+ 1,
+ 36,
+ 36,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 3,
+ Status_Proxy1R,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Status_Proxy2R",
+ FRU_F,
+ 1,
+ 132,
+ 132,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 3,
+ Status_Proxy2R,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "StickClock",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Sun_Part_No",
+ FRU_X,
+ 0,
+ 7,
+ 7,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Sun_Part_Number_DataR",
+ FRU_C,
+ 1,
+ 21,
+ 21,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 5,
+ Sun_Part_Number_DataR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Sun_Serial_No",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Symptom_Code",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 115,
+ Repair_Sympton_Code,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Syndrome",
+ FRU_X,
+ 0,
+ 10,
+ 10,
+ FDTYPE_ByteArray,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "SystemLocation",
+ FRU_E,
+ 2,
+ 80,
+ 80,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "System_Id",
+ FRU_X,
+ 0,
+ 20,
+ 20,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "System_Serial",
+ FRU_C,
+ 2,
+ 20,
+ 20,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "System_Tz",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Tacho_Pulses_Per_Rev",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Temperature_ExcessR",
+ FRU_C,
+ 5,
+ 8,
+ 8,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 2,
+ Temperature_ExcessR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Temperature_HistoryR",
+ FRU_E,
+ 1,
+ 32,
+ 32,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 6,
+ Temperature_HistoryR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Temperature_LimitsR",
+ FRU_B,
+ 4,
+ 2,
+ 2,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 2,
+ Temperature_LimitsR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Test_Cycles",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Test_Failures",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Test_Max_Temp",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Test_Tester_Id",
+ FRU_X,
+ 0,
+ 1,
+ 1,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Test_Version",
+ FRU_X,
+ 0,
+ 8,
+ 8,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Time_Above",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Time_Below",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "To_Dash_No",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "To_Part_No",
+ FRU_X,
+ 0,
+ 7,
+ 7,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "To_Serial_No",
+ FRU_X,
+ 0,
+ 6,
+ 6,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "ToeTagMessage",
+ FRU_E,
+ 1,
+ 80,
+ 80,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Total_Errors",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Total_Inserts",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Total_Power_Offs",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Total_Power_Ons",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Total_Power_Ons_old",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Total_Repairs",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Total_Returns",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Total_Time_On",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "UNIX_Timestamp32",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Time,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "UNIX_Timestamp64",
+ FRU_X,
+ 0,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Time,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "UNKNOWN",
+ FRU_X,
+ 0,
+ 0,
+ 0,
+ FDTYPE_UNDEFINED,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "UsageR",
+ FRU_E,
+ 1,
+ 20,
+ 20,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_No,
+ 6,
+ UsageR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "User_Label",
+ FRU_X,
+ 0,
+ 10,
+ 10,
+ FDTYPE_ASCII,
+ FDISP_String,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "V1_CUR_Shutdown_High_Line",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "V1_CUR_Shutdown_Low_Line",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "V1_CUR_Warning_High_Line",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "V1_CUR_Warning_Low_Line",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "V1_Power_Rating_High_Line",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "V1_Power_Rating_Low_Line",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "V1_VLT_Over_Shutdown",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "V1_VLT_Over_Warning",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "V1_VLT_Under_Shutdown",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "V1_VLT_Under_Warning",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Vendor_Name",
+ FRU_X,
+ 0,
+ 2,
+ 2,
+ FDTYPE_Enumeration,
+ FDISP_String,
+ FRU_No,
+ FRU_No,
+ 552,
+ Vendor,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Version",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Voltage_Rails",
+ FRU_X,
+ 0,
+ 12,
+ 96,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 4,
+ FRU_Linear,
+ ""},
+ {FRU_REVNO,
+ "WCI_A_Rcalibrated",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "WCI_B_Rcalibrated",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "WCI_CalibrationR",
+ FRU_C,
+ 6,
+ 8,
+ 8,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_No,
+ FRU_Yes,
+ 4,
+ WCI_CalibrationR,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "WCI_Tcalibrated",
+ FRU_X,
+ 0,
+ 2,
+ 16,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "WC_Max_WCI_Temp",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "WC_Min_WCI_Temp",
+ FRU_X,
+ 0,
+ 1,
+ 8,
+ FDTYPE_Binary,
+ FDISP_Decimal,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "WWN",
+ FRU_C,
+ 3,
+ 8,
+ 64,
+ FDTYPE_Binary,
+ FDISP_Hex,
+ FRU_No,
+ FRU_No,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "WarrantyDuration",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Binary,
+ FRU_No,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "WarrantyStartDate",
+ FRU_X,
+ 0,
+ 4,
+ 32,
+ FDTYPE_Binary,
+ FDISP_Time,
+ FRU_Yes,
+ FRU_Yes,
+ 0,
+ NULL,
+ 0,
+ FRU_NOT_ITERATED,
+ ""},
+ {FRU_REVNO,
+ "Wildcat_IO_DIMM_Lot",
+ FRU_E,
+ 1,
+ 124,
+ 124,
+ FDTYPE_Record,
+ FDISP_UNDEFINED,
+ FRU_Yes,
+ FRU_Yes,
+ 1,
+ Wildcat_IO_DIMM_Lot,
+ 10,
+ FRU_Linear,
+ ""}
+};
diff --git a/usr/src/lib/libfru/libfrureg/frureg.c b/usr/src/lib/libfru/libfrureg/frureg.c
new file mode 100644
index 0000000000..d0bdd00cb8
--- /dev/null
+++ b/usr/src/lib/libfru/libfrureg/frureg.c
@@ -0,0 +1,88 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "libfrureg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define FRU_REVNO 1
+#include "frudefs.c"
+
+const int max_data_element_count = sizeof (Element_Defs) /
+ sizeof (fru_regdef_t);
+
+const fru_regdef_t *
+fru_reg_lookup_def_by_name(const char *elem_name)
+{
+ fru_regdef_t *ret_def = NULL;
+ int i = 0;
+ for (i = 0; i < max_data_element_count; i++) {
+ ret_def = &(Element_Defs[i]);
+ if (strcmp(ret_def->name, elem_name) == 0) {
+ return (ret_def);
+ }
+ }
+ return (NULL);
+}
+
+const fru_regdef_t *
+fru_reg_lookup_def_by_tag(fru_tag_t tag)
+{
+ fru_regdef_t *ret_def = NULL;
+ int i = 0;
+ for (i = 0; i < max_data_element_count; i++) {
+ ret_def = &(Element_Defs[i]);
+ if (ret_def->tagType == get_tag_type(&tag) &&
+ ret_def->tagDense == get_tag_dense(&tag) &&
+ ret_def->payloadLen == get_payload_length(&tag)) {
+ return (ret_def);
+ }
+ }
+ return (NULL);
+}
+
+char **
+fru_reg_list_entries(unsigned int *num)
+{
+ char **rc = NULL;
+ int number = 0;
+ fru_regdef_t *def = NULL;
+ int i = 0;
+
+ for (i = 0; i < max_data_element_count; i++) {
+ def = &(Element_Defs[i]);
+ rc = realloc(rc, sizeof (char *) * (number + 1));
+ rc[number] = strdup(def->name);
+ number++;
+ }
+
+ *num = number;
+ return (rc);
+}
diff --git a/usr/src/lib/libfru/libfrureg/sparc/Makefile b/usr/src/lib/libfru/libfrureg/sparc/Makefile
new file mode 100644
index 0000000000..5a6815bd20
--- /dev/null
+++ b/usr/src/lib/libfru/libfrureg/sparc/Makefile
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libfru/libfrureg/sparc/Makefile
+#
+
+include ../Makefile.com
+
+LDLIBS += -L$(SRC)/lib/libfruutils/$(MACH)
+LDLIBS += -L$(SRC)/lib/libfru/$(MACH)
+LDLIBS += -lc -lfruutils
+
+.KEEP_STATE:
+
+all: $(ROOTLIBDIR) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS): FRC
+ $(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR):
+ $(INS.dir)
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
+
+FRC:
diff --git a/usr/src/lib/libfru/libfrureg/sparcv9/Makefile b/usr/src/lib/libfru/libfrureg/sparcv9/Makefile
new file mode 100644
index 0000000000..8cfa533e04
--- /dev/null
+++ b/usr/src/lib/libfru/libfrureg/sparcv9/Makefile
@@ -0,0 +1,50 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libfru/libfrureg/sparcv9/Makefile
+#
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+LDLIBS += -L$(SRC)/lib/libfruutils/$(MACH64)
+LDLIBS += -L$(SRC)/lib/libfru/$(MACH64)
+LDLIBS += -lc -lfruutils
+
+.KEEP_STATE:
+
+all: $(ROOTLIBDIR64) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS): FRC
+ $(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR64):
+ $(INS.dir)
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64)
+
+FRC:
diff --git a/usr/src/lib/libfru/libgenutil/Str.cc b/usr/src/lib/libfru/libgenutil/Str.cc
new file mode 100644
index 0000000000..f78e4ee93c
--- /dev/null
+++ b/usr/src/lib/libfru/libgenutil/Str.cc
@@ -0,0 +1,198 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2000 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <string.h>
+#include <stdio.h>
+
+#include "Str.h"
+
+Str::Str()
+ : str_(strcpy(new char[strlen("")+1], "")),
+ nextTok_(str_)
+{}
+
+Str::Str(const char *str)
+ : str_(strcpy(new char[strlen(str)+1], str)),
+ nextTok_(str_)
+{}
+
+Str::Str(const char *str, int len)
+ : str_(new char[len+1]),
+ nextTok_(str_)
+{
+ strlcpy(str_, str, len+1);
+}
+
+Str::Str(const Str& rhs)
+ : str_(strcpy(new char[strlen(rhs.str_)+1], rhs.str_)),
+ nextTok_(str_)
+{}
+
+Str::~Str()
+{
+ delete[] str_;
+}
+
+void
+Str::operator = (const Str& rhs)
+{
+ delete[] str_;
+ str_ = strcpy(new char[strlen(rhs.str_)+1], rhs.str_);
+ // pointer arithmetic very BAD I know...
+ nextTok_ = str_ + (rhs.nextTok_ - rhs.str_);
+}
+
+void
+Str::operator = (const char *str)
+{
+ delete[] str_;
+ str_ = strcpy(new char[strlen(str)+1], str);
+ nextTok_ = str_;
+}
+
+int
+Str::operator == (const Str& rhs) const
+{
+ return (strcmp(str_, rhs.str_) == 0);
+}
+
+int
+Str::operator != (const Str& rhs) const
+{
+ return (strcmp(str_, rhs.str_) != 0);
+}
+
+char&
+Str::operator[](int index) const
+{
+ return (str_[index]);
+}
+
+Str&
+Str::operator<<(Str rhs)
+{
+ char *tmp = new char[strlen(str_)+strlen(rhs.peak())+1];
+ strcpy(tmp, str_);
+ delete[] str_;
+ str_ = tmp;
+ strcat(str_, rhs.peak());
+ return (*this);
+}
+
+Str&
+Str::operator<<(long long i)
+{
+ char msg[256];
+ sprintf(msg, "%lld", i);
+ return (*this << msg);
+}
+
+Str&
+Str::operator<<(long i)
+{
+ char msg[256];
+ sprintf(msg, "%ld", i);
+ return (*this << msg);
+}
+
+Str&
+Str::operator<<(int i)
+{
+ char msg[256];
+ sprintf(msg, "%d", i);
+ return (*this << msg);
+}
+
+Str&
+Str::operator<<(char c)
+{
+ char msg[256];
+ sprintf(msg, "%c", c);
+ return (*this << msg);
+}
+
+// normal "C" strcmp
+int
+Str::compare(const Str& rhs) const
+{
+ return (strcmp(str_, rhs.str_));
+}
+
+int
+Str::length(void) const
+{
+ return (strlen(str_));
+}
+
+char
+Str::tokenize(Str& token, const Str& separators, Str& remainder)
+{
+ int i = 0;
+ int j = 0;
+ for (i = 0; nextTok_[i] != '\0'; i++) {
+ for (j = 0; j < separators.length(); j++) {
+ if (nextTok_[i] == separators[j]) {
+ Str rc(nextTok_, i);
+ token = rc;
+ nextTok_ = &(nextTok_[i+1]);
+ // Str remain(nextTok_);
+ remainder = nextTok_;
+ return (separators[j]);
+ }
+ }
+ }
+
+ token = "";
+ remainder = nextTok_;
+ // remainder = *this;
+ // did not find it!
+ return (NULL);
+}
+
+void
+Str::resetToken(void)
+{
+ nextTok_ = str_;
+}
+
+const char *
+Str::peak(void) const
+{
+ return (str_);
+}
+
+void
+Str::replaceAll(char c, char newc)
+{
+ for (int i = 0; i < strlen(str_); i++) {
+ if (str_[i] == c) {
+ str_[i] = newc;
+ }
+ }
+}
+// oh look an extra line!!!
diff --git a/usr/src/lib/libfru/sparc/Makefile b/usr/src/lib/libfru/sparc/Makefile
new file mode 100644
index 0000000000..72c01007d7
--- /dev/null
+++ b/usr/src/lib/libfru/sparc/Makefile
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libfru/sparc/Makefile
+#
+
+include ../Makefile.obj
+include ../Makefile.flag
+LDLIBS += -L$(SRC)/lib/libfruutils/$(MACH) -lfruutils
+LDLIBS += -L$(SRC)/lib/libfru/libfrureg/$(MACH) -lfrureg
+
+# Redefine this such that libC is found.
+BUILDCCC.SO= $(LINK.cc) $(DYNFLAGS) -o $@ -G $(PICS) $(LDLIBS)
+
+install: all $(ROOTLIBDIR) $(ROOTLINKSCCC)
+
+$(ROOTLIBDIR):
+ $(INS.dir)
+
+include ../Makefile.targ
+
diff --git a/usr/src/lib/libfru/sparcv9/Makefile b/usr/src/lib/libfru/sparcv9/Makefile
new file mode 100644
index 0000000000..3f3bc05bff
--- /dev/null
+++ b/usr/src/lib/libfru/sparcv9/Makefile
@@ -0,0 +1,44 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2000-2001 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libfru/sparcv9/Makefile
+#
+
+# include common Makefiles
+include ../Makefile.obj
+include ../../Makefile.lib.64
+include ../Makefile.flag
+LDLIBS += -lc -xarch=v9
+LDLIBS += -L$(SRC)/lib/libfruutils/$(MACH64) -lfruutils
+LDLIBS += -L$(SRC)/lib/libfru/libfrureg/$(MACH64) -lfrureg
+
+install: all $(ROOTLIBDIR64) $(ROOTLINKSCCC64)
+
+$(ROOTLIBDIR64):
+ $(INS.dir)
+
+include ../Makefile.targ