diff options
author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
---|---|---|
committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/lib/libfru | |
download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz |
OpenSolaris Launch
Diffstat (limited to 'usr/src/lib/libfru')
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, §_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, §_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), §_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, §_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), §ion)) + != 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, §ion) == 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, + §ion, sizeof (section)); + status == PICL_SUCCESS; + status = picl_get_propval_by_name(section, PICL_PROP_PEER, + §ion, + 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, §_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, §_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), §_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, §_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), §ion)) + != 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, §ion) == 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, + §ion, sizeof (section)); + status == PICL_SUCCESS; + status = ptree_get_propval_by_name(section, PICL_PROP_PEER, + §ion, + 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 |