changeset 11015:0a0751599d31

6865474 need a mechanism for parsing FRUPROM records from memory buffer
author Sundeep Panicker <Sundeep.Panicker@Sun.COM>
date Mon, 09 Nov 2009 16:53:15 -0800
parents 00a6bf03a774
children efcd833e2d40
files exception_lists/check_rtime usr/src/lib/Makefile usr/src/lib/libfru/Makefile usr/src/lib/libfru/amd64/Makefile usr/src/lib/libfru/conf/Makefile usr/src/lib/libfru/conf/fru_container.conf usr/src/lib/libfru/i386/Makefile usr/src/lib/libfru/include/libfru.h usr/src/lib/libfru/libfruraw/Makefile usr/src/lib/libfru/libfruraw/Makefile.com usr/src/lib/libfru/libfruraw/amd64/Makefile usr/src/lib/libfru/libfruraw/crcmodel.c usr/src/lib/libfru/libfruraw/crcmodel.h usr/src/lib/libfru/libfruraw/crcutils.c usr/src/lib/libfru/libfruraw/fru_access.h usr/src/lib/libfru/libfruraw/fru_access_impl.h usr/src/lib/libfru/libfruraw/fruraw.c usr/src/lib/libfru/libfruraw/fruraw.h usr/src/lib/libfru/libfruraw/i386/Makefile usr/src/lib/libfru/libfruraw/raw_access.c usr/src/lib/libfru/libfruraw/sparc/Makefile usr/src/lib/libfru/libfruraw/sparcv9/Makefile usr/src/lib/libfru/libfrureg/amd64/Makefile usr/src/lib/libfru/libfrureg/i386/Makefile usr/src/lib/libfru/libnvfru/Makefile usr/src/lib/libfru/libnvfru/Makefile.com usr/src/lib/libfru/libnvfru/amd64/Makefile usr/src/lib/libfru/libnvfru/i386/Makefile usr/src/lib/libfru/libnvfru/nvfru.c usr/src/lib/libfru/libnvfru/nvfru.h usr/src/lib/libfru/libnvfru/sparc/Makefile usr/src/lib/libfru/libnvfru/sparcv9/Makefile usr/src/lib/libfruutils/amd64/Makefile usr/src/lib/libfruutils/fru_tag.c usr/src/lib/libfruutils/fru_tag.h usr/src/lib/libfruutils/i386/Makefile usr/src/pkgdefs/Makefile usr/src/pkgdefs/SUNWfruid/prototype_com usr/src/pkgdefs/SUNWfruid/prototype_i386 usr/src/pkgdefs/SUNWfruid/prototype_sparc usr/src/pkgdefs/SUNWfruip.i/Makefile usr/src/pkgdefs/SUNWfruip.i/depend usr/src/pkgdefs/SUNWfruip.i/pkginfo.tmpl usr/src/pkgdefs/SUNWfruip.i/prototype_i386
diffstat 44 files changed, 4932 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/exception_lists/check_rtime	Mon Nov 09 16:25:35 2009 -0800
+++ b/exception_lists/check_rtime	Mon Nov 09 16:53:15 2009 -0800
@@ -196,6 +196,7 @@
 NOSYMSORT	lib/libsun_fc\.so\.1				# C++
 NOSYMSORT	lib/amd64/libsun_fc\.so\.1			# C++
 NOSYMSORT	lib/sparcv9/libsun_fc\.so\.1 			# C++
+NOSYMSORT	usr/lib/amd64/libfru\.so\.1			# C++
 
 
 # The libprtdiag_psr.so.1 objects built under usr/src/lib/libprtdiag_psr
--- a/usr/src/lib/Makefile	Mon Nov 09 16:25:35 2009 -0800
+++ b/usr/src/lib/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -264,6 +264,8 @@
 	librstp		\
 	libreparse	\
 	libhotplug	\
+	libfruutils	.WAIT	\
+	libfru		\
 	$($(MACH)_SUBDIRS)
 
 i386_SUBDIRS=		\
@@ -280,8 +282,6 @@
 	libprtdiag_psr	\
 	libpri		\
 	librsc		\
-	libfruutils	.WAIT	\
-	libfru		\
 	storage		\
 	libpcp		\
 	libtsalarm
--- a/usr/src/lib/libfru/Makefile	Mon Nov 09 16:25:35 2009 -0800
+++ b/usr/src/lib/libfru/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -2,9 +2,8 @@
 # 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.
+# Common Development and Distribution License (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.
@@ -20,19 +19,24 @@
 # CDDL HEADER END
 #
 #
-# Copyright (c) 2000-2001 by Sun Microsystems, Inc.
-# All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
 #
 # 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
+SUBDIRS_i386 = libfrureg $(MACH)
+$(BUILD64)SUBDIRS_i386 += $(MACH64)
+SUBDIRS_sparc = libfrureg $(MACH)
+$(BUILD64)SUBDIRS_sparc += $(MACH64)
+SUBDIRS_i386 += .WAIT libnvfru libfruraw conf
+SUBDIRS_sparc += .WAIT libfrupicl libfrupicltree libnvfru libfruraw
+
+SUBDIRS = $(SUBDIRS_$(MACH))
+
+
 
 # conditional assignments
 all :=      	TARGET= all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/amd64/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,40 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+# include common Makefiles
+include ../Makefile.obj
+include ../../Makefile.lib.64
+include ../Makefile.flag
+LDLIBS += -lc -m64
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/conf/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+# include library definitions
+include $(SRC)/Makefile.psm
+include $(SRC)/lib/Makefile.lib
+
+CONF		= fru_container.conf
+ROOT_PICL_DIR	= $(ROOT)/usr/lib/picl
+ROOT_PLUGIN_DIR	= $(ROOT_PICL_DIR)/plugins
+ROOTCONF	= $(CONF:%=$(ROOT_PLUGIN_DIR)/%)
+
+$(ROOT_PICL_DIR) := DIRMODE = 0755
+$(ROOT_PLUGIN_DIR) := DIRMODE = 0755
+$(ROOTCONF)	:= FILEMODE = 0644
+
+.KEEP_STATE:
+
+all: $(CONF)
+
+install: all $(ROOTCONF)
+
+$(ROOT_PICL_DIR):
+	$(INS.dir)
+
+$(ROOT_PLUGIN_DIR): $(ROOT_PICL_DIR)
+	$(INS.dir)
+
+$(ROOT_PLUGIN_DIR)/%: % $(ROOT_PLUGIN_DIR)
+	$(INS.file)
+
+# include library targets
+include $(SRC)/lib/Makefile.targ
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/conf/fru_container.conf	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,52 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+# Cut-off read-only section
+6krw1792ro|8k_6krw1792ro_SEEPROM:1:0,0,6144:1,6144,1792
+
+# Standard SEEPROM
+i2c-at24c64|6krw2kro|8k_6krw2kro_SEEPROM:1:0,0,6144:1,6144,2048
+
+# 2KB read-only device (e.g., subset of PCI VPD)
+2kro:1:1,0,2048
+
+# 256 bytes read/write section.
+i2c-at34cps|256rw:1:0,0,256
+
+# Available section of device used in commodity FRUs
+i2c-at34c02|128rwDDR1:1:2,0,146,SPD:0,128,128
+
+i2c-at34c02|128rw128ro:1:0,0,128:1,128,128
+
+# 2155x bridge based product using 93LC66 serial prom VPD.
+93LC66|392rw:1:0,0,392
+
+# Implement Sun SPD JEDEC DIMM Spec.
+# DDR2 DIMM
+128rwDDR2:1:2,0,128,SPD:3,128,128
+
+#ipmi image
+ipmi:0:0,0,512
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/i386/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,41 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+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
+
--- a/usr/src/lib/libfru/include/libfru.h	Mon Nov 09 16:25:35 2009 -0800
+++ b/usr/src/lib/libfru/include/libfru.h	Mon Nov 09 16:53:15 2009 -0800
@@ -2,9 +2,8 @@
  * 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.
+ * Common Development and Distribution License (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.
@@ -19,16 +18,15 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 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
@@ -107,6 +105,26 @@
 	char **strs;
 } fru_strlist_t;
 
+#if defined(_LITTLE_ENDIAN)
+typedef union
+{
+	uint32_t raw_data;
+	struct
+	{
+		unsigned repair_perm : 3;
+		unsigned engineering_perm : 3;
+		unsigned operations_perm : 3;
+		unsigned domain_perm : 3;
+		unsigned field_perm : 3;
+		unsigned unused : 13;
+		unsigned fixed : 1;
+		unsigned opaque : 1;
+		unsigned ignore_checksum : 1;
+		unsigned encrypted : 1;
+
+	} field;
+} fru_segdesc_t;
+#else
 typedef union
 {
 	uint32_t raw_data;
@@ -124,6 +142,7 @@
 		unsigned repair_perm : 3;
 	} field;
 } fru_segdesc_t;
+#endif
 
 #define	FRU_SEGDESC_PERM_DELETE_MASK (1<<0)
 #define	FRU_SEGDESC_PERM_WRITE_MASK (1<<1)
@@ -145,6 +164,21 @@
 #define	SEGMENT_WRITE	2
 #define	SEGMENT_DELETE	1
 
+#if defined(_LITTLE_ENDIAN)
+typedef union
+{
+	uint32_t all_bits;
+	struct
+	{
+		unsigned : 8;
+		unsigned : 8;
+		unsigned : 8;
+		unsigned : 7;
+		uint32_t read_only : 1;
+
+	} field;
+} fru_seg_hwdesc_t;
+#else
 typedef union
 {
 	uint32_t all_bits;
@@ -157,6 +191,7 @@
 		unsigned : 8;
 	} field;
 } fru_seg_hwdesc_t;
+#endif
 
 #define	FRU_SEGNAMELEN 2
 typedef struct {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfruraw/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,66 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+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:
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfruraw/Makefile.com	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,84 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+LIBRARY=	libfruraw.a
+VERS=		.1
+
+OBJECTS=	fruraw.o raw_access.o crcmodel.o crcutils.o
+
+# include library definitions
+include $(SRC)/lib/Makefile.lib
+
+CLOBBERFILES += $(LIBLINKS)
+
+LIBS =		$(DYNLIB)
+
+MAPFILES =
+
+LINTFLAGS =	-uxn
+LINTFLAGS64 =	$(LINTFLAGS) -m64
+LINTOUT=	lint.out
+LINTSRC =       $(LINTLIB:%.ln=%)
+ROOTLINTDIR =   $(ROOTLIBDIR)
+ROOTLINT =      $(LINTSRC:%=$(ROOTLINTDIR)/%)
+
+CLEANFILES=	$(LINTOUT)
+
+CPPFLAGS +=	-I.. \
+		-I$(SRC)/lib/libfru/include \
+		-I$(SRC)/lib/libfruutils
+CPPFLAGS += 	-D_REENTRANT
+CFLAGS +=	$(CCVERBOSE)
+
+$(LINTLIB) :=	LINTFLAGS = -nvx -I..
+$(LINTLIB) :=	LINTFLAGS64 = -nvx -m64 -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)
+
+# include library targets
+include $(SRC)/lib/Makefile.targ
+
+pics/%.o:	../%.c
+	$(COMPILE.c) -o $@ $<
+	$(POST_PROCESS_O)
+
+$(ROOTLINTDIR)/%: ../%
+	$(INS.file)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfruraw/amd64/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+LDLIBS +=	-L$(SRC)/lib/libfruutils/$(MACH64)
+LDLIBS +=	-L$(SRC)/lib/libfru/$(MACH64)
+LDLIBS +=	-lc -lfru -lfruutils
+
+.KEEP_STATE:
+
+all: $(ROOTLIBDIR64) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS):    FRC
+	$(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR64):
+	$(INS.dir)
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64)
+
+FRC:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfruraw/crcmodel.c	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,170 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ *
+ *                             Start of crcmodel.c
+ *
+ *
+ * Author : Ross Williams (ross@guest.adelaide.edu.au.).
+ * Date   : 3 June 1993.
+ * Status : Public domain.
+ *
+ * Description : This is the implementation (.c) file for the reference
+ * implementation of the Rocksoft^tm Model CRC Algorithm. For more
+ * information on the Rocksoft^tm Model CRC Algorithm, see the document
+ * titled "A Painless Guide to CRC Error Detection Algorithms" by Ross
+ * Williams (ross@guest.adelaide.edu.au.). This document is likely to be in
+ * "ftp.adelaide.edu.au/pub/rocksoft".
+ *
+ * Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia.
+ *
+ *
+ *
+ * Implementation Notes
+ * --------------------
+ * To avoid inconsistencies, the specification of each function is not echoed
+ * here. See the header file for a description of these functions.
+ * This package is light on checking because I want to keep it short and
+ * simple and portable (i.e. it would be too messy to distribute my entire
+ * C culture (e.g. assertions package) with this package.
+ *
+ *
+ */
+
+#include "crcmodel.h"
+
+/* The following definitions make the code more readable. */
+
+#define	BITMASK(X) (1L << (X))
+#define	MASK32 0xFFFFFFFFL
+#define	LOCAL static
+
+LOCAL uint32_t reflect P_((uint32_t v, int b));
+LOCAL uint32_t
+reflect(v, b)
+/* Returns the value v with the bottom b [0,32] bits reflected. */
+/* Example: reflect(0x3e23L,3) == 0x3e26 */
+uint32_t v;
+int   b;
+{
+	int i;
+	uint32_t t = v;
+	for (i = 0; i < b; i++) {
+		if (t & 1L)
+			v |=  BITMASK((b-1)-i);
+		else
+			v &= ~BITMASK((b-1)-i);
+		t >>= 1;
+	}
+	return (v);
+}
+
+LOCAL uint32_t widmask P_((p_cm_t));
+LOCAL uint32_t
+widmask(p_cm)
+/* Returns a longword whose value is (2^p_cm->cm_width)-1. */
+/* The trick is to do this portably (e.g. without doing <<32). */
+p_cm_t p_cm;
+{
+	return ((((1L<<(p_cm->cm_width-1))-1L)<<1)|1L);
+}
+
+void
+cm_ini(p_cm)
+p_cm_t p_cm;
+{
+	p_cm->cm_reg = p_cm->cm_init;
+}
+
+void
+cm_nxt(p_cm, ch)
+p_cm_t p_cm;
+int    ch;
+{
+	int i;
+	uint32_t uch = (uint32_t)ch;
+	uint32_t topbit = BITMASK(p_cm->cm_width-1);
+
+	if (p_cm->cm_refin)
+		uch = reflect(uch, 8);
+
+	p_cm->cm_reg ^= (uch << (p_cm->cm_width-8));
+	for (i = 0; i < 8; i++) {
+		if (p_cm->cm_reg & topbit)
+			p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly;
+		else
+			p_cm->cm_reg <<= 1;
+
+		p_cm->cm_reg &= widmask(p_cm);
+	}
+}
+
+void
+cm_blk(p_cm, blk_adr, blk_len)
+p_cm_t   p_cm;
+p_ubyte_ blk_adr;
+uint32_t    blk_len;
+{
+	while (blk_len--)
+		cm_nxt(p_cm, *blk_adr++);
+}
+
+uint32_t
+cm_crc(p_cm)
+p_cm_t p_cm;
+{
+	if (p_cm->cm_refot)
+		return (p_cm->cm_xorot ^ reflect(p_cm->cm_reg, p_cm->cm_width));
+	else
+		return (p_cm->cm_xorot ^ p_cm->cm_reg);
+}
+
+uint32_t
+cm_tab(p_cm, index)
+p_cm_t p_cm;
+int    index;
+{
+	int   i;
+	uint32_t r;
+	uint32_t topbit = BITMASK(p_cm->cm_width-1);
+	uint32_t inbyte = (uint32_t)index;
+
+	if (p_cm->cm_refin)
+		inbyte = reflect(inbyte, 8);
+
+	r = inbyte << (p_cm->cm_width-8);
+	for (i = 0; i < 8; i++)
+		if (r & topbit)
+			r = (r << 1) ^ p_cm->cm_poly;
+		else
+			r <<= 1;
+
+	if (p_cm->cm_refin)
+		r = reflect(r, p_cm->cm_width);
+
+	return (r & widmask(p_cm));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfruraw/crcmodel.h	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,181 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_CRCMODEL_H
+#define	_CRCMODEL_H
+
+#ifdef SOLARIS_UNIX
+#include <sys/types.h>
+#else
+typedef long uint32_t;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *
+ *                             Start of crcmodel.h
+ *
+ *
+ * Author : Ross Williams (ross@guest.adelaide.edu.au.).
+ * Date   : 3 June 1993.
+ * Status : Public domain.
+ *
+ * Description : This is the header (.h) file for the reference
+ * implementation of the Rocksoft^tm Model CRC Algorithm. For more
+ * information on the Rocksoft^tm Model CRC Algorithm, see the document
+ * titled "A Painless Guide to CRC Error Detection Algorithms" by Ross
+ * Williams (ross@guest.adelaide.edu.au.). This document is likely to be in
+ * "ftp.adelaide.edu.au/pub/rocksoft".
+ *
+ * Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia.
+ *
+ *
+ *
+ * How to Use This Package
+ * -----------------------
+ * Step 1: Declare a variable of type cm_t. Declare another variable
+ *         (p_cm say) of type p_cm_t and initialize it to point to the first
+ *         variable (e.g. p_cm_t p_cm = &cm_t).
+ *
+ * Step 2: Assign values to the parameter fields of the structure.
+ *         If you don't know what to assign, see the document cited earlier.
+ *         For example:
+ *            p_cm->cm_width = 16;
+ *            p_cm->cm_poly  = 0x8005L;
+ *            p_cm->cm_init  = 0L;
+ *            p_cm->cm_refin = TRUE;
+ *            p_cm->cm_refot = TRUE;
+ *            p_cm->cm_xorot = 0L;
+ *         Note: Poly is specified without its top bit (18005 becomes 8005).
+ *         Note: Width is one bit less than the raw poly width.
+ *
+ * Step 3: Initialize the instance with a call cm_ini(p_cm);
+ *
+ * Step 4: Process zero or more message bytes by placing zero or more
+ *         successive calls to cm_nxt. Example: cm_nxt(p_cm,ch);
+ *
+ * Step 5: Extract the CRC value at any time by calling crc = cm_crc(p_cm);
+ *         If the CRC is a 16-bit value, it will be in the bottom 16 bits.
+ *
+ *
+ *
+ * Design Notes
+ * ------------
+ * PORTABILITY: This package has been coded very conservatively so that
+ * it will run on as many machines as possible. For example, all external
+ * identifiers have been restricted to 6 characters and all internal ones to
+ * 8 characters. The prefix cm (for Crc Model) is used as an attempt to avoid
+ * namespace collisions. This package is endian independent.
+ *
+ * EFFICIENCY: This package (and its interface) is not designed for
+ * speed. The purpose of this package is to act as a well-defined reference
+ * model for the specification of CRC algorithms. If you want speed, cook up
+ * a specific table-driven implementation as described in the document cited
+ * above. This package is designed for validation only; if you have found or
+ * implemented a CRC algorithm and wish to describe it as a set of parameters
+ * to the Rocksoft^tm Model CRC Algorithm, your CRC algorithm implementation
+ * should behave identically to this package under those parameters.
+ *
+ */
+
+
+/* The following definitions are extracted from my style header file which */
+/* would be cumbersome to distribute with this package. The DONE_STYLE is the */
+/* idempotence symbol used in my style header file. */
+
+#ifndef DONE_STYLE
+
+typedef unsigned bool;
+typedef unsigned char *p_ubyte_;
+
+#ifndef TRUE
+#define	FALSE 0
+#define	TRUE  1
+#endif
+
+/* Change to the second definition if you don't have prototypes. */
+#define	P_(A) A
+/* #define P_(A) () */
+
+/* Uncomment this definition if you don't have void. */
+/* typedef int void; */
+
+#endif
+
+/* CRC Model Abstract Type */
+/* ----------------------- */
+/* The following type stores the context of an executing instance of the */
+/* model algorithm. Most of the fields are model parameters which must be */
+/* set before the first initializing call to cm_ini. */
+typedef struct
+{
+	int cm_width; /* Parameter: Width in bits [8,32]. */
+	uint32_t cm_poly; /* Parameter: The algorithm's polynomial. */
+	uint32_t cm_init; /* Parameter: Initial register value. */
+	bool cm_refin; /* Parameter: Reflect input bytes? */
+	bool cm_refot; /* Parameter: Reflect output CRC? */
+	uint32_t cm_xorot; /* Parameter: XOR this to output CRC. */
+
+	uint32_t cm_reg; /* Context: Context during execution. */
+} cm_t;
+typedef cm_t *p_cm_t;
+
+/* Functions That Implement The Model */
+/* ---------------------------------- */
+/* The following functions animate the cm_t abstraction. */
+
+void cm_ini P_((p_cm_t p_cm));
+/* Initializes the argument CRC model instance. */
+/* All parameter fields must be set before calling this. */
+
+void cm_nxt P_((p_cm_t p_cm, int ch));
+/* Processes a single message byte [0,255]. */
+
+void cm_blk P_((p_cm_t p_cm, p_ubyte_ blk_adr, uint32_t blk_len));
+/* Processes a block of message bytes. */
+
+uint32_t cm_crc P_((p_cm_t p_cm));
+/* Returns the CRC value for the message bytes processed so far. */
+
+/* Functions For Table Calculation */
+/* ------------------------------- */
+/* The following function can be used to calculate a CRC lookup table. */
+/* It can also be used at run-time to create or check static tables. */
+
+uint32_t cm_tab P_((p_cm_t p_cm, int index));
+/* Returns the i'th entry for the lookup table for the specified algorithm. */
+/* The function examines the fields cm_width, cm_poly, cm_refin, and the */
+/* argument table index in the range [0,255] and returns the table entry in */
+/* the bottom cm_width bytes of the return value. */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CRCMODEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfruraw/crcutils.c	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,157 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <string.h>
+#include <limits.h>
+
+#include "crcmodel.h"
+
+#if defined(_LITTLE_ENDIAN)
+
+/* Little-endian architectures need byte-swapping. */
+
+#define	sws(x) (((x >> 8) & 0x00ff) | ((x << 8) & 0xff00))
+#define	swl(x) (sws(x >> 16) | (sws(x) << 16))
+
+#define	swap_short(x) (x = sws(x))
+#define	swap_long(x) (x = swl(x))
+
+#else   /* if !_LITTLE_ENDIAN */
+
+/* Big-endian anchictectures don't need byte-swapping. */
+
+#define	sws(x) (x)
+#define	swl(x) (x)
+
+#define	swap_short(x) (x = sws(x))
+#define	swap_long(x) (x = swl(x))
+
+#endif  /* _LITTLE_ENDIAN */
+
+unsigned char
+compute_crc8(unsigned char *bytes, int length)
+{
+	cm_t crc_mdl;
+	p_cm_t p_crc;
+	int i;
+	unsigned char aCRC;
+
+	p_crc = &crc_mdl;
+
+	p_crc->cm_width = 8;
+	p_crc->cm_poly = 0x107; /* = X^8 + x^2 + x + 1 */
+	p_crc->cm_init = 0;
+	p_crc->cm_refin = TRUE;
+	p_crc->cm_refot = TRUE;
+	p_crc->cm_xorot = 0;
+
+	cm_ini(p_crc);
+
+	for (i = 0; i < length; i++) {
+		cm_nxt(p_crc, bytes[i]);
+	}
+
+	aCRC = (unsigned char)cm_crc(p_crc);
+
+	return (aCRC);
+}
+
+uint32_t
+compute_crc32(unsigned char *bytes, int length)
+{
+	cm_t crc_mdl;
+	p_cm_t p_crc;
+	int i;
+	uint32_t aCRC;
+
+	p_crc = &crc_mdl;
+
+	p_crc->cm_width = 32;
+	p_crc->cm_poly = 0x04c11db7;
+	p_crc->cm_init = 0xffffffff;
+	p_crc->cm_refin = TRUE;
+	p_crc->cm_refot = TRUE;
+	p_crc->cm_xorot = 0xffffffff;
+
+	cm_ini(p_crc);
+
+	for (i = 0; i < length; i++) {
+		cm_nxt(p_crc, bytes[i]);
+	}
+
+	aCRC = (uint32_t)cm_crc(p_crc);
+
+	return (aCRC);
+}
+
+/*
+ * This is the max value an uint32_t value can hold...
+ * Define this for Windows compilers which don't have "limits.h" or equivalant
+ */
+#define	UINT32_T_MAX 0xFFFFFFFF
+
+uint32_t
+compute_checksum32(unsigned char *bytes, int length)
+{
+	uint32_t regval = 0;
+	int i, j, k;
+	uint32_t next4bytes;
+	unsigned char tailbytes[4] = { 0x00, 0x00, 0x00, 0x00 };
+
+	/* Grab bytes in 4-byte chunks */
+	for (i = 0; i < length-4; i += 4) {
+		/* Grab chunk as an int */
+		(void) memcpy(&next4bytes, &(bytes[i]), 4);
+		swap_long(next4bytes);
+
+		if (next4bytes > UINT32_T_MAX - regval) {
+			next4bytes -= UINT32_T_MAX - regval;
+			regval = 0;
+		}
+
+		/* Add intval to regval */
+		regval += next4bytes;
+	}
+
+	/* Grab any remaining bytes at the end */
+	for (j = length-1, k = 3; j >= i; j--, k--) {
+		tailbytes[k] = bytes[j];
+	}
+
+/*
+ * Treat any remaining bytes put into tailbytes as if they were
+ * a left-zero-padded unsigned int (uint32_t == 4 bytes!)
+ */
+	(void) memcpy(&next4bytes, tailbytes, 4);
+	swap_long(next4bytes);
+	if (next4bytes > UINT32_T_MAX - regval) {
+		next4bytes -= UINT32_T_MAX - regval;
+		regval = 0;
+	}
+	regval += next4bytes;
+
+	return ((uint32_t)regval);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfruraw/fru_access.h	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,114 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _FRU_ACCESS_H
+#define	_FRU_ACCESS_H
+
+#include <sys/types.h>
+#include <picl.h>
+#include <door.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+
+#define	SEG_NAME_LEN	2
+
+
+typedef uint64_t  fru_hdl_t;
+
+typedef fru_hdl_t  container_hdl_t;
+typedef fru_hdl_t  section_hdl_t;
+typedef fru_hdl_t  segment_hdl_t;
+typedef fru_hdl_t  packet_hdl_t;
+
+typedef struct
+{
+	section_hdl_t	handle;	/*  for use in operations on section  */
+	uint32_t	offset;	/*  bytes from container beginning  */
+	uint32_t	length;	/*  length of section in bytes  */
+	uint32_t	protection; /* non-zero if section is write-protected */
+	int32_t		version;	/*  version of section header, or -1 */
+}
+section_t;
+
+typedef struct
+{
+	segment_hdl_t	handle;	/*  for operations on segment  */
+	char	name[SEG_NAME_LEN];	/*  from container section header  */
+	uint32_t	descriptor;	/*  ditto  */
+	uint32_t	offset;		/*  ditto  */
+	uint32_t	length;		/*  ditto  */
+}
+segment_t;
+
+typedef uint64_t  tag_t;
+
+typedef struct
+{
+	packet_hdl_t	handle;	/*  for use in operations on packet  */
+	tag_t		tag;
+}
+packet_t;
+
+
+container_hdl_t fru_open_container(picl_nodehdl_t fru);
+
+int fru_close_container(container_hdl_t container);
+int fru_get_num_sections(container_hdl_t container, door_cred_t *cred);
+int fru_get_sections(container_hdl_t container, section_t *section,
+				int max_sections, door_cred_t *cred);
+int fru_get_num_segments(section_hdl_t section, door_cred_t *rarg);
+int fru_get_segments(section_hdl_t section, segment_t *segment,
+				int max_segments, door_cred_t *rarg);
+int fru_add_segment(section_hdl_t section, segment_t *segment,
+			section_hdl_t *newsection, door_cred_t *cred);
+int fru_delete_segment(segment_hdl_t segment, section_hdl_t *newsection,
+							door_cred_t *cred);
+ssize_t fru_read_segment(segment_hdl_t segment, void *buffer, size_t nbytes,
+							door_cred_t *cred);
+int fru_write_segment(segment_hdl_t segment, const void *data, size_t nbytes,
+				segment_hdl_t *newsegment, door_cred_t *cred);
+int fru_get_num_packets(segment_hdl_t segment, door_cred_t *cred);
+int fru_get_packets(segment_hdl_t segment, packet_t *packet,
+			int max_packets, door_cred_t *cred);
+ssize_t fru_get_payload(packet_hdl_t packet, void *buffer,
+			size_t nbytes, door_cred_t *cred);
+int fru_update_payload(packet_hdl_t packet, const void *data, size_t nbytes,
+			packet_hdl_t *newpacket, door_cred_t *cred);
+int fru_append_packet(segment_hdl_t segment, packet_t *packet,
+	const void *payload, size_t nbytes, segment_hdl_t *newsegment,
+						door_cred_t *cred);
+int fru_delete_packet(packet_hdl_t packet, segment_hdl_t *newsegment,
+						door_cred_t *cred);
+int fru_is_data_available(picl_nodehdl_t fru);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _FRU_ACCESS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfruraw/fru_access_impl.h	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,205 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_FRU_ACCESS_IMPL_H
+#define	_FRU_ACCESS_IMPL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dial.h>
+#include <strings.h>
+#include <libdevinfo.h>
+#include <sys/systeminfo.h>
+#include <sys/byteorder.h>
+#include <syslog.h>
+#include <errno.h>
+#include <libfru.h>
+#include <limits.h>
+#include <fru_tag.h>
+#include <fru_access.h>
+
+
+/* object types */
+typedef	enum {CONTAINER_TYPE, SECTION_TYPE, SEGMENT_TYPE, PACKET_TYPE} object_t;
+
+#define	TABLE_SIZE		64	/* hash table size */
+
+
+/* section header */
+#define	SECTION_HDR_TAG		0x08
+#define	SECTION_HDR_VER		0x0001
+#define	SECTION_HDR_LENGTH	0x06
+#define	SECTION_HDR_CRC8	0x00
+#define	SECTION_HDR_VER_BIT0	0x00
+#define	SECTION_HDR_VER_BIT1	0x01
+
+#define	READ_ONLY_SECTION	1	/* section is read-only */
+
+#define	GET_SEGMENT_DESCRIPTOR	\
+		(BE_16(seg_layout->descriptor[1])| \
+		BE_16(seg_layout->descriptor[0] << 16))
+
+#define	GET_SECTION_HDR_VERSION	\
+		(sec_hdr.headerversion[1]|sec_hdr.headerversion[0] << 8)
+
+/* Segment Trailer Tag */
+#define	SEG_TRAILER_TAG 0x0C
+
+/* defines fixed segment */
+#define	SEGMENT_FIXED		1
+
+typedef union {
+	uint32_t all_bits;
+	struct {
+		unsigned read_only : 1;
+		unsigned unused : 8;
+		unsigned : 8;
+		unsigned : 8;
+		unsigned : 7;
+	} field;
+} sectdescbit_t;
+
+typedef enum {
+	ENC_STANDARD = 0,	/* proper fruid data */
+	ENC_SPD			/* serial presence detect data */
+} sectencoding_t;
+
+typedef struct {
+	sectdescbit_t	description;
+	uint32_t	address; /* for SEEPROMS this is the offset */
+	uint32_t	size;
+	sectencoding_t	encoding;
+} sectioninfo_t;
+
+typedef uint16_t headerrev_t;
+
+#define	MAX_NUMOF_SECTION	2
+
+typedef struct {
+	headerrev_t header_ver;
+	int num_sections;
+	sectioninfo_t section_info[MAX_NUMOF_SECTION];
+} container_info_t;
+
+
+/* section header layout */
+typedef struct {
+	uint8_t	headertag; /* section header tag */
+	uint8_t	headerversion[2]; /* header version (msb) */
+	uint8_t	headerlength; /* header length */
+	uint8_t	headercrc8; /* crc8 */
+	uint8_t	segmentcount; /* total number of segment */
+} section_layout_t;
+
+/* segment header layout */
+typedef struct  {
+	uint16_t	name; 	/* segment name */
+	uint16_t	descriptor[2]; /* descriptor (msb) */
+	uint16_t	offset; /* segment data offset */
+	uint16_t	length; /* segment length */
+} segment_layout_t;
+
+/* segment information used in finding new offset for a new segment */
+typedef struct {
+	int segnum;	/* segment number */
+	int offset;	/* segment offset */
+	int length;	/* segment length */
+	int fixed;	/* fixed or non-fixed segment */
+} seg_info_t;
+
+typedef	uint64_t	handle_t;
+
+struct	hash_obj;
+
+/* packet hash object */
+typedef	struct {
+	handle_t	segment_hdl;	/* segment handle */
+	fru_tag_t	tag;
+	int		tag_size;
+	uint8_t		*payload;
+	uint32_t	paylen;
+	uint32_t	payload_offset;
+	struct hash_obj *next;
+} packet_obj_t;
+
+/* segment hash object */
+typedef struct {
+	handle_t	section_hdl;	/* section handle */
+	int		num_of_packets;	/* in a segment */
+	int		trailer_offset;
+	segment_t	segment;
+	struct hash_obj	*pkt_obj_list;	/* packet object list */
+	struct hash_obj	*next;
+} segment_obj_t;
+
+/* section hash object */
+typedef	struct {
+	handle_t	cont_hdl;	/* container handle */
+	section_t	section;
+	sectencoding_t	encoding;	/* standard or needing interpretation */
+	int	num_of_segment;		/* in a section */
+	struct hash_obj	*seg_obj_list;	/* points to segment objects list */
+	struct hash_obj	*next;
+} section_obj_t;
+
+/* container hash object */
+typedef	struct {
+	char	device_pathname[PATH_MAX]; /* device name */
+	int	num_of_section;	/* num of section in container */
+	struct hash_obj	*sec_obj_list; /* points to section objects list */
+} container_obj_t;
+
+/* hash object */
+typedef	struct hash_obj {
+	int	object_type;
+	handle_t obj_hdl;
+	union {
+		container_obj_t		*cont_obj;
+		section_obj_t		*sec_obj;
+		segment_obj_t		*seg_obj;
+		packet_obj_t		*pkt_obj;
+	} u;
+	struct hash_obj 	*next;
+	struct hash_obj 	*prev;
+} hash_obj_t;
+
+unsigned char compute_crc8(unsigned char *bytes, int length);
+long compute_crc32(unsigned char *bytes, int length);
+long compute_checksum32(unsigned char *bytes, int length);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _FRU_ACCESS_IMPL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfruraw/fruraw.c	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,737 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include "fru_access_impl.h"
+
+#include "libfruds.h"
+#include "libfrup.h"
+#include "fru_access.h"
+#include "fruraw.h"
+
+
+raw_list_t *g_raw = NULL;
+
+
+/* ARGSUSED */
+static raw_list_t *
+treehdl_to_rawlist(fru_treehdl_t handle)
+{
+	return (g_raw);
+}
+
+
+static container_hdl_t
+treehdl_to_conthdl(fru_treehdl_t handle)
+{
+	raw_list_t *ptr;
+
+	ptr = treehdl_to_rawlist(handle);
+	if (ptr == NULL) {
+		return (-1);
+	}
+
+	return (ptr->cont);
+}
+
+
+static fru_errno_t
+map_errno(int err)
+{
+	switch (err) {
+	case ENFILE:
+	case EEXIST:
+		return (FRU_DUPSEG);
+	case EAGAIN:
+		return (FRU_NOSPACE);
+	case EPERM:
+		return (FRU_INVALPERM);
+	default :
+		return (FRU_IOERROR);
+	}
+}
+
+
+static raw_list_t *
+make_raw(uint8_t *buffer, size_t size, char *cont_type)
+{
+	raw_list_t *node;
+
+	node = (raw_list_t *)malloc(sizeof (raw_list_t));
+	if (node == NULL) {
+		return (NULL);
+	}
+
+	node->hdl = 0;
+	node->raw = buffer;
+	node->size = size;
+	node->cont_type = strdup(cont_type);
+	if (node->cont_type == NULL) {
+		free(node);
+		return (NULL);
+	}
+	node->segs = NULL;
+
+	return (node);
+}
+
+
+/*
+ * Arguments :
+ * 0 - pointer to byte buffer (in)
+ * 1 - size of buffer (in)
+ * 2 - container type, string (in)
+ */
+static fru_errno_t
+frt_initialize(int num, char **args)
+{
+
+
+	if (num != 3) {
+		return (FRU_FAILURE);
+	}
+
+	g_raw = make_raw((uint8_t *)args[0], (size_t)args[1], args[2]);
+	if (g_raw == NULL) {
+		return (FRU_FAILURE);
+	}
+
+	g_raw->cont = open_raw_data(g_raw);
+	if (g_raw->cont == NULL) {
+		return (FRU_FAILURE);
+	}
+
+	return (FRU_SUCCESS);
+}
+
+
+static fru_errno_t
+frt_shutdown(void)
+{
+	segment_list_t *lptr, *lptr2;
+
+	(void) fru_close_container(g_raw->cont);
+	free(g_raw->cont_type);
+	lptr = g_raw->segs;
+	while (lptr) {
+		lptr2 = lptr;
+		lptr = lptr->next;
+		free(lptr2);
+	}
+	g_raw = NULL;
+
+	return (FRU_SUCCESS);
+}
+
+
+static fru_errno_t
+frt_get_root(fru_treehdl_t *node)
+{
+	*node = g_raw->hdl;
+
+	return (FRU_SUCCESS);
+}
+
+/* ARGSUSED */
+static fru_errno_t
+frt_get_peer(fru_treehdl_t sibling, fru_treehdl_t *peer)
+{
+	return (FRU_NODENOTFOUND);
+}
+/* ARGSUSED */
+static fru_errno_t
+frt_get_child(fru_treehdl_t handle, fru_treehdl_t *child)
+{
+	return (FRU_NODENOTFOUND);
+}
+
+/* ARGSUSED */
+static fru_errno_t
+frt_get_parent(fru_treehdl_t handle, fru_treehdl_t *parent)
+{
+	return (FRU_NODENOTFOUND);
+}
+
+/* ARGSUSED */
+static fru_errno_t
+frt_get_name_from_hdl(fru_treehdl_t handle, char **name)
+{
+	*name = strdup("unknown");
+	return (FRU_SUCCESS);
+}
+
+/* ARGSUSED */
+static fru_errno_t
+frt_get_node_type(fru_treehdl_t node, fru_node_t *type)
+{
+	*type = FRU_NODE_CONTAINER;
+	return (FRU_SUCCESS);
+}
+
+
+
+static fru_errno_t
+add_segs_for_section(section_t *section, fru_strlist_t *list)
+{
+	int i = 0;
+	segment_t *segs = NULL;
+	int acc_err = 0;
+
+	int num_segment = fru_get_num_segments(section->handle, NULL);
+	if (num_segment == -1) {
+		return (map_errno(errno));
+	} else if (num_segment == 0) {
+		return (FRU_SUCCESS);
+	}
+
+	segs = malloc(sizeof (*segs) * (num_segment));
+	if (segs == NULL) {
+		return (FRU_FAILURE);
+	}
+
+	acc_err = fru_get_segments(section->handle, segs, num_segment, NULL);
+	if (acc_err == -1) {
+		free(segs);
+		return (map_errno(errno));
+	}
+
+	list->strs = realloc(list->strs, sizeof (char *)
+	    * (list->num + num_segment));
+
+	for (i = 0; i < num_segment; i++) {
+		/* ensure NULL terminated. */
+		char *tmp = malloc(sizeof (*tmp) * (sizeof (segs[i].name)+1));
+		if (tmp == NULL) {
+			free(segs);
+			return (FRU_FAILURE);
+		}
+		(void) memcpy(tmp, segs[i].name, sizeof (segs[i].name));
+		tmp[sizeof (segs[i].name)] = '\0';
+
+		list->strs[(list->num)++] = tmp;
+	}
+
+	free(segs);
+
+	return (FRU_SUCCESS);
+}
+
+
+
+static fru_errno_t
+frt_get_seg_list(fru_treehdl_t handle, fru_strlist_t *list)
+{
+	fru_strlist_t rc_list;
+	fru_errno_t err = FRU_SUCCESS;
+	int acc_err = 0;
+	int i = 0;
+	int num_section = 0;
+	section_t *sects = NULL;
+	container_hdl_t cont;
+
+	cont = treehdl_to_conthdl(handle);
+
+	num_section = fru_get_num_sections(cont, NULL);
+	if (num_section == -1) {
+		return (map_errno(errno));
+	}
+
+	sects = malloc(sizeof (*sects) * (num_section));
+	if (sects == NULL) {
+		return (FRU_FAILURE);
+	}
+
+	acc_err = fru_get_sections(cont, sects, num_section, NULL);
+	if (acc_err == -1) {
+		free(sects);
+		return (map_errno(errno));
+	}
+
+	rc_list.num = 0;
+	rc_list.strs = NULL;
+	for (i = 0; i < num_section; i++) {
+		if ((err = add_segs_for_section(&(sects[i]), &rc_list))
+		    != FRU_SUCCESS) {
+			fru_destroy_strlist(&rc_list);
+			free(sects);
+			return (err);
+		}
+	}
+
+	list->strs = rc_list.strs;
+	list->num = rc_list.num;
+
+	return (FRU_SUCCESS);
+}
+
+
+static fru_errno_t
+find_seg_in_sect(section_t *sect, const char *seg_name, int *prot_flg,
+    segment_t *segment)
+{
+	int j = 0;
+	int acc_err = 0;
+	segment_t *segs = NULL;
+
+	int num_seg = fru_get_num_segments(sect->handle, NULL);
+	if (num_seg == -1) {
+		return (FRU_FAILURE);
+	}
+
+	segs = malloc(sizeof (*segs) * (num_seg));
+	if (segs == NULL) {
+		return (FRU_FAILURE);
+	}
+
+	acc_err = fru_get_segments(sect->handle, segs, num_seg, NULL);
+	if (acc_err == -1) {
+		free(segs);
+		return (map_errno(errno));
+	}
+
+	for (j = 0; j < num_seg; j++) {
+		/* NULL terminate */
+		char tmp[SEG_NAME_LEN+1];
+		(void) memcpy(tmp, segs[j].name, SEG_NAME_LEN);
+		tmp[SEG_NAME_LEN] = '\0';
+		if (strcmp(tmp, seg_name) == 0) {
+			*segment = segs[j];
+			*prot_flg = (sect->protection ? 1 : 0);
+			free(segs);
+			return (FRU_SUCCESS);
+		}
+	}
+
+	free(segs);
+	return (FRU_INVALSEG);
+}
+
+
+static fru_errno_t
+find_segment(fru_treehdl_t handle, const char *seg_name, int *prot_flg,
+    segment_t *segment)
+{
+	int i = 0;
+	int acc_err = 0;
+	section_t *sect = NULL;
+	container_hdl_t cont;
+	int num_sect;
+
+	cont = treehdl_to_conthdl(handle);
+
+	num_sect = fru_get_num_sections(cont, NULL);
+	if (num_sect == -1) {
+		return (map_errno(errno));
+	}
+
+	sect = malloc(sizeof (*sect) * (num_sect));
+	if (sect == NULL) {
+		return (FRU_FAILURE);
+	}
+
+	acc_err = fru_get_sections(cont, sect, num_sect, NULL);
+	if (acc_err == -1) {
+		free(sect);
+		return (map_errno(errno));
+	}
+
+	for (i = 0; i < num_sect; i++) {
+		if (find_seg_in_sect(&(sect[i]), seg_name, prot_flg, segment)
+		    == FRU_SUCCESS) {
+			free(sect);
+			return (FRU_SUCCESS);
+		}
+	}
+
+	free(sect);
+	return (FRU_INVALSEG);
+}
+
+
+static fru_errno_t
+frt_get_seg_def(fru_treehdl_t handle, const char *seg_name, fru_segdef_t *def)
+{
+	fru_errno_t err = FRU_SUCCESS;
+	int prot_flg = 0;
+	segment_t segment;
+
+	if ((err = find_segment(handle, seg_name, &prot_flg, &segment))
+	    != FRU_SUCCESS) {
+		return (err);
+	}
+
+	(void) memcpy(def->name, segment.name, SEG_NAME_LEN);
+	def->name[SEG_NAME_LEN] = '\0';
+	def->desc.raw_data = segment.descriptor;
+	def->size = segment.length;
+	def->address = segment.offset;
+
+	if (prot_flg == 0)
+		def->hw_desc.field.read_only = 0;
+	else
+		def->hw_desc.field.read_only = 1;
+
+	return (FRU_SUCCESS);
+
+}
+
+/* ARGSUSED */
+static fru_errno_t
+frt_add_seg(fru_treehdl_t handle, fru_segdef_t *def)
+{
+	/* NOT SUPPORTED */
+	return (FRU_NOTSUP);
+}
+
+/* ARGSUSED */
+static fru_errno_t
+frt_delete_seg(fru_treehdl_t handle, const char *seg_name)
+{
+	/* NOT SUPPORTED */
+	return (FRU_NOTSUP);
+}
+
+/* ARGSUSED */
+static fru_errno_t
+frt_for_each_segment(fru_nodehdl_t node,
+    int (*function)(fru_seghdl_t hdl, void *args), void *args)
+{
+	int num_segment;
+	int cnt;
+	int num_sect;
+	int each_seg;
+	section_t *sects;
+	segment_t *segs;
+	segment_list_t *tmp_list;
+	int acc_err;
+	int status;
+	container_hdl_t cont;
+
+	cont = g_raw->cont;
+
+	num_sect = fru_get_num_sections(cont, NULL);
+	if (num_sect == -1) {
+		return (map_errno(errno));
+	}
+
+	sects = malloc((num_sect + 1) * sizeof (section_t));
+	if (sects == NULL) {
+		return (FRU_FAILURE);
+	}
+	num_sect = fru_get_sections(cont, sects, num_sect, NULL);
+	if (num_sect == -1) {
+		free(sects);
+		return (map_errno(errno));
+	}
+	for (cnt = 0; cnt < num_sect; cnt++) {
+		num_segment = fru_get_num_segments(sects[cnt].handle, NULL);
+		if (num_segment == -1) {
+			return (map_errno(errno));
+		} else if (num_segment == 0) {
+			continue;
+		}
+		segs = malloc((num_segment + 1) * sizeof (segment_t));
+		if (segs == NULL) {
+			free(sects);
+			return (FRU_FAILURE);
+		}
+		acc_err = fru_get_segments(sects[cnt].handle, segs,
+		    num_segment, NULL);
+		if (acc_err == -1) {
+			free(sects);
+			free(segs);
+			return (map_errno(errno));
+		}
+		for (each_seg = 0; each_seg < num_segment; each_seg++) {
+			tmp_list = malloc(sizeof (segment_list_t));
+			tmp_list->segment = &segs[each_seg];
+			tmp_list->next = NULL;
+			if (g_raw->segs == NULL) {
+				g_raw->segs = tmp_list;
+			} else {
+				tmp_list->next = g_raw->segs;
+				g_raw->segs = tmp_list;
+			}
+
+			if ((status = function(segs[each_seg].handle, args))
+			    != FRU_SUCCESS) {
+				free(segs);
+				free(sects);
+				return (status);
+			}
+		}
+		free(segs);
+		free(sects);
+
+	}
+	return (FRU_SUCCESS);
+}
+
+
+static fru_errno_t
+frt_get_segment_name(fru_seghdl_t node, char **name)
+{
+	int num_sect;
+	int acc_err;
+	int cnt;
+	int num_segment;
+	section_t *sects;
+	segment_t *segs;
+	int each_seg;
+	container_hdl_t cont;
+
+	cont = treehdl_to_conthdl(node);
+
+	num_sect = fru_get_num_sections(cont, NULL);
+	if (num_sect == -1) {
+		return (map_errno(errno));
+	}
+
+	sects = malloc(sizeof (*sects) * (num_sect));
+	if (sects == NULL) {
+		return (FRU_FAILURE);
+	}
+	acc_err = fru_get_sections(cont, sects, num_sect, NULL);
+	if (acc_err == -1) {
+		free(sects);
+		return (map_errno(errno));
+	}
+
+	for (cnt = 0; cnt < num_sect; cnt++) {
+		num_segment = fru_get_num_segments(sects[cnt].handle, NULL);
+		if (num_segment == -1) {
+			free(sects);
+			return (map_errno(errno));
+		} else if (num_segment == 0) {
+			continue;
+		}
+
+		segs = malloc(sizeof (*segs) * (num_segment));
+		if (segs == NULL) {
+			free(sects);
+			return (FRU_FAILURE);
+		}
+
+		acc_err = fru_get_segments(sects[cnt].handle, segs,
+		    num_segment, NULL);
+		if (acc_err == -1) {
+			free(sects);
+			free(segs);
+			return (map_errno(errno));
+		}
+
+		for (each_seg = 0; each_seg < num_segment; each_seg++) {
+			if (segs[each_seg].handle == node) {
+				segs[each_seg].name[FRU_SEGNAMELEN] = '\0';
+				*name = segs[each_seg].name;
+				free(sects);
+				return (FRU_SUCCESS);
+			}
+		}
+		free(segs);
+	}
+
+	return (FRU_FAILURE);
+}
+
+
+/* ARGSUSED */
+static fru_errno_t
+frt_add_tag_to_seg(fru_treehdl_t handle, const char *seg_name,
+    fru_tag_t tag, uint8_t *data, size_t data_len)
+{
+	/* NOT SUPPORTED */
+	return (FRU_NOTSUP);
+}
+
+
+/* ARGSUSED */
+static fru_errno_t
+frt_get_tag_list(fru_treehdl_t handle, const char *seg_name,
+		fru_tag_t **tags, int *number)
+{
+	/* NOT SUPPORTED */
+	return (FRU_NOTSUP);
+}
+
+
+/* ARGSUSED */
+static fru_errno_t
+frt_get_tag_data(fru_treehdl_t handle, const char *seg_name,
+		fru_tag_t tag, int instance,
+		uint8_t **data, size_t *data_len)
+{
+	/* NOT SUPPORTED */
+	return (FRU_NOTSUP);
+}
+
+
+/* ARGSUSED */
+static fru_errno_t
+frt_set_tag_data(fru_treehdl_t handle, const char *seg_name,
+		fru_tag_t tag, int instance,
+		uint8_t *data, size_t data_len)
+{
+	/* NOT SUPPORTED */
+	return (FRU_NOTSUP);
+}
+
+
+/* ARGSUSED */
+static fru_errno_t
+frt_delete_tag(fru_treehdl_t handle, const char *seg_name, fru_tag_t tag,
+    int instance)
+{
+	/* NOT SUPPORTED */
+	return (FRU_NOTSUP);
+}
+
+
+static fru_errno_t
+frt_for_each_packet(fru_seghdl_t node,
+    int (*function)(fru_tag_t *tag, uint8_t *payload, size_t length,
+	void *args), void *args)
+{
+	int rc_num;
+	int status;
+	char *rc_tags;
+	char *rc_data;
+	int i;
+	packet_t *packets = NULL;
+	segment_list_t *tmp_list;
+	fru_segdesc_t *descriptor;
+
+	tmp_list = g_raw->segs;
+
+	/* num of packet */
+	rc_num = fru_get_num_packets(node, NULL);
+	if (rc_num == -1) {
+		return (map_errno(errno));
+	} else if (rc_num == 0) {
+		return (FRU_SUCCESS);
+	}
+	while (tmp_list) {
+		if (node == tmp_list->segment->handle) {
+			break;
+		}
+		tmp_list = tmp_list->next;
+	}
+	if (tmp_list) {
+		descriptor = (fru_segdesc_t *)&tmp_list->segment->descriptor;
+		if (descriptor->field.opaque) {
+			return (FRU_SUCCESS);
+		}
+
+		if (descriptor->field.encrypted && (encrypt_func == NULL)) {
+			return (FRU_SUCCESS);
+		}
+	}
+
+	packets = malloc(sizeof (*packets) * (rc_num));
+	if (packets == NULL) {
+		return (FRU_FAILURE);
+	}
+	/* get all packets */
+	if (fru_get_packets(node, packets, rc_num, NULL) == -1) {
+		free(packets);
+		return (map_errno(errno));
+	}
+
+	rc_tags = malloc(sizeof (*rc_tags) * (rc_num));
+	if (rc_tags == NULL) {
+		free(packets);
+		return (FRU_FAILURE);
+	}
+
+	/* number of tags */
+	for (i = 0; i < rc_num; i++) {
+		size_t rc_len =
+		    get_payload_length((fru_tag_t *)&packets[i].tag);
+
+		rc_data = malloc(sizeof (*rc_data) * (rc_len));
+		if (rc_data == NULL) {
+			free(packets);
+			return (FRU_FAILURE);
+		}
+		/* get the payload data */
+		(void) fru_get_payload(packets[i].handle, (void *)rc_data,
+		    rc_len, NULL);
+
+		if (tmp_list) {
+			descriptor =
+			    (fru_segdesc_t *)&tmp_list->segment->descriptor;
+
+			if ((descriptor->field.encrypted) &&
+			    ((status = encrypt_func(FRU_DECRYPT,
+			    (void *)rc_data, rc_len))
+			    != FRU_SUCCESS)) {
+				return (status);
+			}
+		}
+		/* print packet */
+		if ((status = function((fru_tag_t *)&packets[i].tag,
+		    (uint8_t *)rc_data, rc_len, args)) != FRU_SUCCESS) {
+			free(rc_data);
+			free(packets);
+			return (status);
+		}
+		free(rc_data);
+	}
+	return (FRU_SUCCESS);
+
+}
+
+
+/* object for libfru to link to */
+fru_datasource_t data_source =
+{
+	LIBFRU_DS_VER,
+	frt_initialize,
+	frt_shutdown,
+	frt_get_root,
+	frt_get_child,
+	frt_get_peer,
+	frt_get_parent,
+	frt_get_name_from_hdl,
+	frt_get_node_type,
+	frt_get_seg_list,
+	frt_get_seg_def,
+	frt_add_seg,
+	frt_delete_seg,
+	frt_for_each_segment,
+	frt_get_segment_name,
+	frt_add_tag_to_seg,
+	frt_get_tag_list,
+	frt_get_tag_data,
+	frt_set_tag_data,
+	frt_delete_tag,
+	frt_for_each_packet
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfruraw/fruraw.h	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _FRURAW_H
+#define	_FRURAW_H
+
+#include <stdint.h>
+#include <fru_access.h>
+#include <libfruds.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	FRU_CONT_CONF_SPARC	"/usr/platform/sun4u/lib/fru_container.conf"
+#define	FRU_CONT_CONF_X86	"/usr/lib/picl/plugins/fru_container.conf"
+#define	FRU_CONT_CONF_ENV_VAR   "FRU_CONTAINER_CONF"
+#define	IGNORE_CHECK		"IGNORE_CHECKSUM"
+
+typedef struct segment_list {
+	segment_t *segment;
+	struct segment_list *next;
+} segment_list_t;
+
+
+typedef struct raw_list {
+	uint8_t *raw;
+	size_t size;
+	char *cont_type;
+
+	container_hdl_t cont;
+	segment_list_t *segs;
+
+	fru_treehdl_t hdl;
+} raw_list_t;
+
+
+/* raw_access.c */
+container_hdl_t open_raw_data(raw_list_t *);
+int fru_close_container(container_hdl_t);
+raw_list_t *seghdl_to_rawlist(segment_hdl_t node);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FRURAW_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfruraw/i386/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+include ../Makefile.com
+
+LDLIBS +=	-L$(SRC)/lib/libfruutils/$(MACH)
+LDLIBS +=	-L$(SRC)/lib/libfru/$(MACH)
+LDLIBS +=	-lc -lfru -lfruutils
+
+.KEEP_STATE:
+
+all: $(ROOTLIBDIR) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS):    FRC
+	$(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR):
+	$(INS.dir)
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
+
+FRC:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfruraw/raw_access.c	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,1227 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <alloca.h>
+#include <sys/byteorder.h>
+#include "fru_access_impl.h"
+#include "fruraw.h"
+
+#pragma init(initialize_raw_access)
+
+static hash_obj_t	*hash_table[TABLE_SIZE];
+extern raw_list_t 	*g_raw;
+
+static void
+initialize_raw_access(void)
+{
+	int	count;
+
+	for (count = 0; count < TABLE_SIZE; count++) {
+		hash_table[count] = NULL;
+	}
+}
+
+
+static hash_obj_t *
+lookup_handle_object(handle_t	handle, int object_type)
+{
+	handle_t index_to_hash;
+	hash_obj_t *first_hash_obj;
+	hash_obj_t *next_hash_obj;
+
+	index_to_hash = (handle % TABLE_SIZE);
+
+	first_hash_obj = hash_table[index_to_hash];
+	for (next_hash_obj = first_hash_obj; next_hash_obj != NULL;
+	    next_hash_obj = next_hash_obj->next) {
+		if ((handle == next_hash_obj->obj_hdl) &&
+		    (object_type == next_hash_obj->object_type)) {
+			return (next_hash_obj);
+		}
+	}
+	return (NULL);
+}
+
+
+static void
+add_hashobject_to_hashtable(hash_obj_t *hash_obj)
+{
+	handle_t index_to_hash;
+	static	uint64_t handle_count = 0;
+
+	hash_obj->obj_hdl = ++handle_count;	/* store the handle */
+
+	/* where to add ? */
+	index_to_hash = ((hash_obj->obj_hdl) % TABLE_SIZE);
+
+	hash_obj->next = hash_table[index_to_hash];
+	hash_table[index_to_hash] = hash_obj;	/* hash obj. added */
+
+	if (hash_obj->next != NULL) {
+		hash_obj->next->prev = hash_obj;
+	}
+}
+
+
+static hash_obj_t *
+create_container_hash_object(void)
+{
+	hash_obj_t *hash_obj;
+	container_obj_t *cont_obj;
+
+	cont_obj = malloc(sizeof (container_obj_t));
+	if (cont_obj == NULL) {
+		return (NULL);
+	}
+
+	hash_obj = malloc(sizeof (hash_obj_t));
+	if (hash_obj == NULL) {
+		free(cont_obj);
+		return (NULL);
+	}
+
+	cont_obj->sec_obj_list = NULL;
+
+	hash_obj->object_type = CONTAINER_TYPE;
+	hash_obj->u.cont_obj = cont_obj;
+	hash_obj->next = NULL;
+	hash_obj->prev = NULL;
+
+	return (hash_obj);
+}
+
+
+static hash_obj_t *
+create_section_hash_object(void)
+{
+	hash_obj_t *hash_obj;
+	section_obj_t *sec_obj;
+
+	sec_obj	= malloc(sizeof (section_obj_t));
+	if (sec_obj == NULL) {
+		return (NULL);
+	}
+
+	hash_obj = malloc(sizeof (hash_obj_t));
+	if (hash_obj == NULL) {
+		free(sec_obj);
+		return (NULL);
+	}
+
+	sec_obj->next = NULL;
+	sec_obj->seg_obj_list = NULL;
+
+	hash_obj->u.sec_obj = sec_obj;
+	hash_obj->object_type = SECTION_TYPE;
+	hash_obj->next = NULL;
+	hash_obj->prev = NULL;
+
+	return (hash_obj);
+}
+
+
+static hash_obj_t *
+create_segment_hash_object(void)
+{
+	hash_obj_t *hash_obj;
+	segment_obj_t *seg_obj;
+
+	seg_obj	= malloc(sizeof (segment_obj_t));
+	if (seg_obj == NULL) {
+		return (NULL);
+	}
+
+	hash_obj = malloc(sizeof (hash_obj_t));
+	if (hash_obj == NULL) {
+		free(seg_obj);
+		return (NULL);
+	}
+
+	seg_obj->next = NULL;
+	seg_obj->pkt_obj_list = NULL;
+
+	hash_obj->object_type = SEGMENT_TYPE;
+	hash_obj->u.seg_obj = seg_obj;
+	hash_obj->next = NULL;
+	hash_obj->prev = NULL;
+
+	return (hash_obj);
+}
+
+
+static hash_obj_t *
+create_packet_hash_object(void)
+{
+	hash_obj_t *hash_obj;
+	packet_obj_t *pkt_obj;
+
+	pkt_obj	= malloc(sizeof (packet_obj_t));
+	if (pkt_obj == NULL) {
+		return (NULL);
+	}
+
+	hash_obj = malloc(sizeof (hash_obj_t));
+	if (hash_obj == NULL) {
+		free(pkt_obj);
+		return (NULL);
+	}
+
+	pkt_obj->next = NULL;
+
+	hash_obj->object_type = PACKET_TYPE;
+	hash_obj->u.pkt_obj = pkt_obj;
+	hash_obj->next = NULL;
+	hash_obj->prev = NULL;
+
+	return (hash_obj);
+}
+
+
+
+static hash_obj_t *
+get_container_hash_object(int	object_type, handle_t	handle)
+{
+	hash_obj_t	*hash_obj;
+
+	switch (object_type) {
+	case CONTAINER_TYPE:
+		break;
+	case SECTION_TYPE:
+		hash_obj = lookup_handle_object(handle, CONTAINER_TYPE);
+		if (hash_obj == NULL) {
+			return (NULL);
+		}
+		break;
+	case SEGMENT_TYPE:
+		hash_obj = lookup_handle_object(handle, SECTION_TYPE);
+		if (hash_obj == NULL) {
+			return (NULL);
+		}
+		hash_obj = lookup_handle_object(hash_obj->u.sec_obj->cont_hdl,
+		    CONTAINER_TYPE);
+		break;
+	case PACKET_TYPE:
+		break;
+	default:
+		return (NULL);
+	}
+
+	return (hash_obj);
+}
+
+
+static void
+add_to_pkt_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj)
+{
+	hash_obj_t *next_hash;
+
+	/* add the packet object in the end of list */
+	child_obj->u.pkt_obj->segment_hdl = parent_obj->obj_hdl;
+
+	if (parent_obj->u.seg_obj->pkt_obj_list == NULL) {
+		parent_obj->u.seg_obj->pkt_obj_list = child_obj;
+		return;
+	}
+
+	for (next_hash = parent_obj->u.seg_obj->pkt_obj_list;
+	    next_hash->u.pkt_obj->next != NULL;
+	    next_hash = next_hash->u.pkt_obj->next) {
+		;
+	}
+
+	next_hash->u.pkt_obj->next = child_obj;
+}
+
+
+static void
+free_pkt_object_list(hash_obj_t	*hash_obj)
+{
+	hash_obj_t *next_obj;
+	hash_obj_t *free_obj;
+
+	next_obj = hash_obj->u.seg_obj->pkt_obj_list;
+	while (next_obj != NULL) {
+		free_obj = next_obj;
+		next_obj = next_obj->u.pkt_obj->next;
+		/* if prev is NULL it's the first object in the list */
+		if (free_obj->prev == NULL) {
+			hash_table[(free_obj->obj_hdl % TABLE_SIZE)] =
+			    free_obj->next;
+			if (free_obj->next != NULL) {
+				free_obj->next->prev = free_obj->prev;
+			}
+		} else {
+			free_obj->prev->next = free_obj->next;
+			if (free_obj->next != NULL) {
+				free_obj->next->prev = free_obj->prev;
+			}
+		}
+
+		free(free_obj->u.pkt_obj->payload);
+		free(free_obj->u.pkt_obj);
+		free(free_obj);
+	}
+
+	hash_obj->u.seg_obj->pkt_obj_list = NULL;
+}
+
+
+static void
+free_segment_hash(handle_t handle, hash_obj_t *sec_hash)
+{
+	hash_obj_t *seg_hash;
+	hash_obj_t *next_hash;
+
+	seg_hash = sec_hash->u.sec_obj->seg_obj_list;
+	if (seg_hash == NULL) {
+		return;
+	}
+
+	if (seg_hash->obj_hdl == handle) {
+		sec_hash->u.sec_obj->seg_obj_list = seg_hash->u.seg_obj->next;
+	} else {
+		while (seg_hash->obj_hdl != handle) {
+			next_hash = seg_hash;
+			seg_hash = seg_hash->u.seg_obj->next;
+			if (seg_hash == NULL) {
+				return;
+			}
+		}
+		next_hash->u.seg_obj->next = seg_hash->u.seg_obj->next;
+	}
+
+	if (seg_hash->prev == NULL) {
+		hash_table[(seg_hash->obj_hdl % TABLE_SIZE)] = seg_hash->next;
+		if (seg_hash->next != NULL) {
+			seg_hash->next->prev = NULL;
+		}
+	} else {
+		seg_hash->prev->next = seg_hash->next;
+		if (seg_hash->next != NULL) {
+			seg_hash->next->prev = seg_hash->prev;
+		}
+	}
+
+	free_pkt_object_list(seg_hash);
+	free(seg_hash->u.seg_obj);
+	free(seg_hash);
+}
+
+
+
+static void
+add_to_sec_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj)
+{
+	hash_obj_t *next_hash;
+
+	child_obj->u.sec_obj->cont_hdl = parent_obj->obj_hdl;
+	if (parent_obj->u.cont_obj->sec_obj_list == NULL) {
+		parent_obj->u.cont_obj->sec_obj_list = child_obj;
+		return;
+	}
+
+	for (next_hash = parent_obj->u.cont_obj->sec_obj_list;
+	    next_hash->u.sec_obj->next != NULL;
+	    next_hash = next_hash->u.sec_obj->next) {
+		;
+	}
+
+	next_hash->u.sec_obj->next = child_obj;
+}
+
+
+static void
+add_to_seg_object_list(hash_obj_t *parent_obj, hash_obj_t *child_obj)
+{
+	hash_obj_t *next_hash;
+
+	child_obj->u.seg_obj->section_hdl = parent_obj->obj_hdl;
+	if (parent_obj->u.sec_obj->seg_obj_list == NULL) {
+		parent_obj->u.sec_obj->seg_obj_list = child_obj;
+		return;
+	}
+
+	for (next_hash = parent_obj->u.sec_obj->seg_obj_list;
+	    next_hash->u.seg_obj->next != NULL;
+	    next_hash = next_hash->u.seg_obj->next) {
+		;
+	}
+
+	next_hash->u.seg_obj->next = child_obj;
+}
+
+
+static char *
+tokenizer(char *buf, char *separator, char **nextBuf, char *matched)
+{
+	int i = 0;
+	int j = 0;
+
+	for (i = 0; buf[i] != '\0'; i++) {
+		for (j = 0; j < strlen(separator); j++) {
+			if (buf[i] == separator[j]) {
+				buf[i] = '\0';
+				*nextBuf = &(buf[i+1]);
+				*matched = separator[j];
+				return (buf);
+			}
+		}
+	}
+
+	*nextBuf = buf;
+	*matched = '\0';
+	return (NULL);
+}
+
+
+static void
+copy_segment_layout(segment_t *seghdr, void *layout)
+{
+	segment_layout_t *seg_layout;
+
+	seg_layout = (segment_layout_t *)layout;
+	(void) memcpy(seghdr->name, &seg_layout->name, SEG_NAME_LEN);
+	seghdr->descriptor = GET_SEGMENT_DESCRIPTOR;
+	seghdr->offset = BE_16(seg_layout->offset);
+	seghdr->length = BE_16(seg_layout->length);
+}
+
+
+static int
+get_container_info(const char *def_file, const char *cont_desc_str,
+    container_info_t *cont_info)
+{
+	char *item;
+	char *token;
+	char *field;
+	char matched;
+	char buf[1024];
+	int foundIt = 0;
+	FILE *file = fopen(def_file, "r");
+
+	if (file == NULL)
+		return (-1);
+
+	cont_info->num_sections = 0;
+
+	while (fgets(buf, sizeof (buf), file) != NULL) {
+		/* ignore all comments */
+		token = tokenizer(buf, "#", &field, &matched);
+		/* find the names */
+		token = tokenizer(buf, ":", &field, &matched);
+		if (token != 0x00) {
+			token = tokenizer(token, "|", &item, &matched);
+			while (token != 0x00) {
+				if (strcmp(token, cont_desc_str) == 0) {
+					foundIt = 1;
+					goto found;
+				}
+				token = tokenizer(item, "|", &item, &matched);
+			}
+			/* check the last remaining item */
+			if ((item != 0x00) &&
+			    (strcmp(item, cont_desc_str) == 0)) {
+				foundIt = 1;
+				goto found;
+			}
+		}
+	}
+
+found :
+	if (foundIt == 1) {
+		token = tokenizer(field, ":", &field, &matched);
+		if (token == 0x00) {
+			(void) fclose(file);
+			return (-1);
+		}
+		cont_info->header_ver = (headerrev_t)atoi(token);
+
+		token = tokenizer(field, ":\n", &field, &matched);
+		while (token != 0x00) {
+			token = tokenizer(token, ",", &item, &matched);
+			if (token == 0x00) {
+				(void) fclose(file);
+				return (-1);
+			}
+			if (atoi(token) == 1) {
+				cont_info->section_info[cont_info->
+				    num_sections].description.field.read_only
+				    = 1;
+			} else if (atoi(token) == 0) {
+				cont_info->section_info[cont_info->
+				    num_sections].description.field.read_only
+				    = 0;
+			} else {
+				(void) fclose(file);
+				return (-1);
+			}
+
+			token = tokenizer(item, ",", &item, &matched);
+			if (token == 0x00) {
+				(void) fclose(file);
+				return (-1);
+			}
+
+			cont_info->section_info[cont_info->
+			    num_sections].address = atoi(token);
+			if (item == '\0') {
+				(void) fclose(file);
+				return (-1);
+			}
+			cont_info->section_info[cont_info->num_sections].size =
+			    atoi(item);
+			(cont_info->num_sections)++;
+
+			token = tokenizer(field, ":\n ", &field, &matched);
+		}
+	}
+	(void) fclose(file);
+
+	return (0);
+}
+
+
+/* ARGSUSED */
+int
+fru_get_segments(section_hdl_t section, segment_t *segment, int maxseg,
+    door_cred_t *cred)
+{
+	int count;
+	hash_obj_t *sec_object;
+	hash_obj_t *seg_object;
+	section_obj_t *sec_obj;
+
+	sec_object = lookup_handle_object(section, SECTION_TYPE);
+	if (sec_object == NULL) {
+		return (-1);
+	}
+
+	sec_obj	= sec_object->u.sec_obj;
+	if (sec_obj == NULL) {
+		return (-1);
+	}
+
+	if (sec_obj->num_of_segment > maxseg) {
+		return (-1);
+	}
+
+	seg_object = sec_object->u.sec_obj->seg_obj_list;
+	if (seg_object == NULL) {
+		return (-1);
+	}
+
+	for (count = 0; count < sec_obj->num_of_segment; count++) {
+
+		/* populate segment_t */
+		segment->handle = seg_object->obj_hdl;
+		(void) memcpy(segment->name,
+		    seg_object->u.seg_obj->segment.name, SEG_NAME_LEN);
+		segment->descriptor = seg_object->u.seg_obj->segment.descriptor;
+
+		segment->offset	= seg_object->u.seg_obj->segment.offset;
+		segment->length	= seg_object->u.seg_obj->segment.length;
+		seg_object = seg_object->u.seg_obj->next;
+		segment++;
+	}
+	return (0);
+}
+
+
+static int
+raw_memcpy(void *buffer, raw_list_t *rawlist, int offset, int size)
+{
+	if (offset + size > rawlist->size) {
+		size = rawlist->size - offset;
+	}
+
+	(void) memcpy(buffer, &rawlist->raw[offset], size);
+
+	return (size);
+}
+
+
+static int
+verify_header_crc8(headerrev_t head_ver, unsigned char *bytes, int length)
+{
+	int crc_offset = 0;
+	unsigned char orig_crc8 = 0;
+	unsigned char calc_crc8 = 0;
+
+	switch (head_ver) {
+		case SECTION_HDR_VER:
+			crc_offset = 4;
+			break;
+		default:
+			errno = EINVAL;
+			return (0);
+	}
+
+	orig_crc8 = bytes[crc_offset];
+	bytes[crc_offset] = 0x00; /* clear for calc */
+	calc_crc8 = compute_crc8(bytes, length);
+	bytes[crc_offset] = orig_crc8; /* restore */
+
+	return (orig_crc8 == calc_crc8);
+}
+
+
+static int
+get_section(raw_list_t *rawlist, hash_obj_t *sec_hash, section_t *section)
+{
+	int retval;
+	int size;
+	int count;
+	uint16_t hdrver;
+	hash_obj_t *seg_hash;
+	unsigned char *buffer;
+	section_obj_t *sec_obj;
+	section_layout_t sec_hdr;
+	segment_layout_t *seg_hdr;
+	segment_layout_t *seg_buf;
+
+	sec_obj	= sec_hash->u.sec_obj;
+	if (sec_obj == NULL) {
+		return (-1);
+	}
+
+	/* populate section_t */
+	section->handle = sec_hash->obj_hdl;
+	section->offset = sec_obj->section.offset;
+	section->length = sec_obj->section.length;
+	section->protection = sec_obj->section.protection;
+	section->version = sec_obj->section.version;
+
+	/* read section header layout */
+	retval = raw_memcpy(&sec_hdr, rawlist, sec_obj->section.offset,
+	    sizeof (sec_hdr));
+
+	if (retval != sizeof (sec_hdr)) {
+		return (-1);
+	}
+
+
+	hdrver = GET_SECTION_HDR_VERSION;
+
+	if ((sec_hdr.headertag != SECTION_HDR_TAG) &&
+	    (hdrver != section->version)) {
+		return (-1);
+	}
+
+	/* size = section layout + total sizeof segment header */
+	size = sizeof (sec_hdr) + ((sec_hdr.segmentcount)
+	    * sizeof (segment_layout_t));
+
+	buffer = alloca(size);
+	if (buffer == NULL) {
+		return (-1);
+	}
+
+	/* segment header buffer */
+	seg_buf = alloca(size - sizeof (sec_hdr));
+	if (seg_buf == NULL) {
+		return (-1);
+	}
+
+	/* read segment header */
+	retval = raw_memcpy(seg_buf, rawlist,
+	    sec_obj->section.offset + sizeof (sec_hdr),
+	    size - sizeof (sec_hdr));
+
+	if (retval != (size - sizeof (sec_hdr))) {
+		return (-1);
+	}
+
+	/* copy section header layout */
+	(void) memcpy(buffer, &sec_hdr, sizeof (sec_hdr));
+
+	/* copy segment header layout */
+	(void) memcpy(buffer + sizeof (sec_hdr), seg_buf, size -
+	    sizeof (sec_hdr));
+
+	/* verify crc8 */
+	retval = verify_header_crc8(hdrver, buffer, size);
+	if (retval != TRUE) {
+		return (-1);
+	}
+
+	section->version = hdrver;
+	sec_obj->section.version = hdrver;
+
+	seg_hdr	= (segment_layout_t *)seg_buf;
+
+	/* bug fix for frutool */
+	if (sec_hash->u.sec_obj->seg_obj_list != NULL) {
+		return (0);
+	} else {
+		sec_obj->num_of_segment = 0;
+	}
+	for (count = 0; count < sec_hdr.segmentcount; count++, seg_hdr++) {
+
+		seg_hash = create_segment_hash_object();
+		if (seg_hash == NULL) {
+			return (-1);
+		}
+		add_hashobject_to_hashtable(seg_hash);
+		copy_segment_layout(&seg_hash->u.seg_obj->segment, seg_hdr);
+		add_to_seg_object_list(sec_hash, seg_hash);
+		sec_obj->num_of_segment++;
+	}
+	return (0);
+}
+
+/* ARGSUSED */
+int
+fru_get_sections(container_hdl_t container, section_t *section, int maxsec,
+    door_cred_t *cred)
+{
+	int count;
+	int num_sec = 0;
+	hash_obj_t *cont_object;
+	hash_obj_t *sec_hash;
+
+	cont_object = lookup_handle_object(container, CONTAINER_TYPE);
+	if (cont_object == NULL) {
+		return (-1);
+	}
+
+	if (cont_object->u.cont_obj->num_of_section > maxsec) {
+		return (-1);
+	}
+
+	sec_hash = cont_object->u.cont_obj->sec_obj_list;
+	if (sec_hash == NULL) {
+		return (-1);
+	}
+
+	for (count = 0; count < cont_object->u.cont_obj->num_of_section;
+	    count++) {
+		section->version = -1;
+		/* populate section_t */
+		if (get_section(g_raw, sec_hash, section) == 0) {
+			section++;
+			num_sec++;
+		}
+		sec_hash = sec_hash->u.sec_obj->next;
+	}
+	return (num_sec);
+}
+
+
+static uint32_t
+get_checksum_crc(hash_obj_t *seg_hash, int data_size)
+{
+	int protection;
+	int offset = 0;
+	uint32_t crc;
+	hash_obj_t *sec_hash;
+	hash_obj_t *pkt_hash;
+	unsigned char *buffer;
+
+	sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl,
+	    SECTION_TYPE);
+	if (sec_hash == NULL) {
+		return ((uint32_t)-1);
+	}
+
+	buffer = alloca(data_size);
+	if (buffer == NULL) {
+		return ((uint32_t)-1);
+	}
+
+	/* traverse the packet object list for all the tags and payload */
+	for (pkt_hash = seg_hash->u.seg_obj->pkt_obj_list; pkt_hash != NULL;
+	    pkt_hash = pkt_hash->u.pkt_obj->next) {
+		(void) memcpy(buffer + offset, &pkt_hash->u.pkt_obj->tag,
+		    pkt_hash->u.pkt_obj->tag_size);
+		offset += pkt_hash->u.pkt_obj->tag_size;
+		(void) memcpy(buffer + offset, pkt_hash->u.pkt_obj->payload,
+		    pkt_hash->u.pkt_obj->paylen);
+		offset += pkt_hash->u.pkt_obj->paylen;
+	}
+
+	protection = sec_hash->u.sec_obj->section.protection;
+
+	if (protection == READ_ONLY_SECTION) { /* read-only section */
+		crc = compute_crc32(buffer, data_size);
+	} else {		/* read/write section */
+		crc = compute_checksum32(buffer, data_size);
+	}
+	return (crc);	/* computed crc */
+}
+
+
+static int
+get_packet(raw_list_t *rawlist, void *buffer, int size, int offset)
+{
+	int retval;
+
+	retval = raw_memcpy(buffer, rawlist, offset, size);
+
+	if (retval != -1) {
+		return (0);
+	}
+	return (-1);
+}
+
+
+static int
+get_packets(hash_obj_t *seg_hash, raw_list_t *rawlist, int offset, int length)
+{
+	int tag_size;
+	int paylen;
+	int retval;
+	int seg_limit = 0;
+	int pktcnt = 0;
+	char *data;
+	uint32_t crc;
+	uint32_t origcrc;
+	fru_tag_t tag;
+	hash_obj_t *pkt_hash_obj;
+	hash_obj_t *sec_hash;
+	fru_segdesc_t *segdesc;
+	fru_tagtype_t tagtype;
+	char *ignore_flag;
+
+	retval = get_packet(rawlist, &tag, sizeof (fru_tag_t), offset);
+	if (retval == -1) {
+		return (-1);
+	}
+
+	/* section hash object */
+	sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl,
+	    SECTION_TYPE);
+
+	if (sec_hash == NULL) {
+		return (-1);
+	}
+
+	seg_hash->u.seg_obj->trailer_offset = offset;
+
+	data = (char *)&tag;
+	while (data[0] != SEG_TRAILER_TAG) {
+		tagtype	= get_tag_type(&tag); /* verify tag type */
+		if (tagtype == -1) {
+			return (-1);
+		}
+
+		tag_size = get_tag_size(tagtype);
+		if (tag_size == -1) {
+			return (-1);
+		}
+
+		seg_limit += tag_size;
+		if (seg_limit > length) {
+			return (-1);
+		}
+
+		paylen = get_payload_length((void *)&tag);
+		if (paylen == -1) {
+			return (-1);
+		}
+
+		seg_limit += paylen;
+		if (seg_limit > length) {
+			return (-1);
+		}
+		if ((offset + tag_size + paylen) >
+		    (sec_hash->u.sec_obj->section.offset +
+		    sec_hash->u.sec_obj->section.length)) {
+			return (-1);
+		}
+
+		pkt_hash_obj = create_packet_hash_object();
+		if (pkt_hash_obj == NULL) {
+			return (-1);
+		}
+
+		pkt_hash_obj->u.pkt_obj->payload = malloc(paylen);
+		if (pkt_hash_obj->u.pkt_obj->payload == NULL) {
+			free(pkt_hash_obj);
+			return (-1);
+		}
+
+		offset += tag_size;
+
+		retval = raw_memcpy(pkt_hash_obj->u.pkt_obj->payload, rawlist,
+		    offset, paylen);
+
+		if (retval != paylen) {
+			free(pkt_hash_obj->u.pkt_obj->payload);
+			free(pkt_hash_obj);
+			return (-1);
+		}
+
+		/* don't change this */
+		pkt_hash_obj->u.pkt_obj->tag.raw_data = 0;
+		(void) memcpy(&pkt_hash_obj->u.pkt_obj->tag, &tag, tag_size);
+		pkt_hash_obj->u.pkt_obj->paylen = paylen;
+		pkt_hash_obj->u.pkt_obj->tag_size = tag_size;
+		pkt_hash_obj->u.pkt_obj->payload_offset = offset;
+
+		offset += paylen;
+
+		add_hashobject_to_hashtable(pkt_hash_obj);
+		add_to_pkt_object_list(seg_hash, pkt_hash_obj);
+
+		pktcnt++;
+
+		retval = get_packet(rawlist, &tag, sizeof (fru_tag_t),
+		    offset);
+		if (retval == -1) {
+			return (retval);
+		}
+
+		data = (char *)&tag;
+	}
+
+	segdesc	= (fru_segdesc_t *)&seg_hash->u.seg_obj->segment.descriptor;
+
+	seg_hash->u.seg_obj->trailer_offset = offset;
+
+	if (!segdesc->field.ignore_checksum)  {
+		crc = get_checksum_crc(seg_hash, seg_limit);
+		offset = seg_hash->u.seg_obj->segment.offset;
+
+		retval = raw_memcpy(&origcrc, rawlist, offset + seg_limit + 1,
+		    sizeof (origcrc));
+
+		ignore_flag = getenv(IGNORE_CHECK);
+		if (ignore_flag != NULL) {
+			return (pktcnt);
+		}
+
+		if (retval != sizeof (origcrc)) {
+			return (-1);
+		}
+
+		origcrc = BE_32(origcrc);
+		if (origcrc != crc) {
+			seg_hash->u.seg_obj->trailer_offset = offset;
+			return (-1);
+		}
+	}
+
+	return (pktcnt);
+}
+
+/* ARGSUSED */
+int
+fru_get_num_sections(container_hdl_t container, door_cred_t *cred)
+{
+	hash_obj_t *hash_object;
+
+	hash_object = lookup_handle_object(container, CONTAINER_TYPE);
+	if (hash_object == NULL) {
+		return (-1);
+	}
+
+	return (hash_object->u.cont_obj->num_of_section);
+}
+
+/* ARGSUSED */
+int
+fru_get_num_segments(section_hdl_t section, door_cred_t *cred)
+{
+	hash_obj_t *sec_object;
+	section_obj_t *sec_obj;
+
+	sec_object = lookup_handle_object(section, SECTION_TYPE);
+	if (sec_object == NULL) {
+		return (-1);
+	}
+
+	sec_obj	= sec_object->u.sec_obj;
+	if (sec_obj == NULL) {
+		return (-1);
+	}
+
+	return (sec_obj->num_of_segment);
+}
+
+/* ARGSUSED */
+int
+fru_get_num_packets(segment_hdl_t segment, door_cred_t *cred)
+{
+	int pktcnt;
+	int length;
+	uint16_t offset;
+	hash_obj_t *cont_hash_obj;
+	hash_obj_t *seg_hash;
+	hash_obj_t *sec_hash;
+	fru_segdesc_t *segdesc;
+	segment_obj_t *segment_object;
+
+	seg_hash = lookup_handle_object(segment, SEGMENT_TYPE);
+	if (seg_hash == NULL) {
+		return (-1);
+	}
+
+	segment_object = seg_hash->u.seg_obj;
+	if (segment_object == NULL) {
+		return (-1);
+	}
+
+	segdesc = (fru_segdesc_t *)&segment_object->segment.descriptor;
+	if (segdesc->field.opaque) {
+		return (0);
+	}
+
+	offset = segment_object->segment.offset;
+	length = segment_object->segment.length;
+
+	cont_hash_obj = get_container_hash_object(SEGMENT_TYPE,
+	    segment_object->section_hdl);
+
+	if (cont_hash_obj == NULL) {
+		return (-1);
+	}
+
+	if (seg_hash->u.seg_obj->pkt_obj_list != NULL) {
+		return (segment_object->num_of_packets);
+	}
+	/* section hash object */
+	sec_hash = lookup_handle_object(seg_hash->u.seg_obj->section_hdl,
+	    SECTION_TYPE);
+	if (sec_hash == NULL) {
+		return (-1);
+	}
+
+	/* valid segment header b'cos crc8 already validated */
+	if (offset < sec_hash->u.sec_obj->section.offset) {
+		return (-1);
+	}
+
+	segment_object->num_of_packets = 0;
+
+	pktcnt = get_packets(seg_hash, g_raw, offset, length);
+	if (pktcnt == -1) {
+		free_pkt_object_list(seg_hash);
+		seg_hash->u.seg_obj->pkt_obj_list = NULL;
+	}
+
+	segment_object->num_of_packets = pktcnt;
+
+	return (segment_object->num_of_packets);
+}
+
+/* ARGSUSED */
+int
+fru_get_packets(segment_hdl_t segment, packet_t *packet, int maxpackets,
+    door_cred_t *cred)
+{
+	int count;
+	hash_obj_t *seg_hash_obj;
+	hash_obj_t *pkt_hash_obj;
+
+	/* segment hash object */
+	seg_hash_obj = lookup_handle_object(segment, SEGMENT_TYPE);
+	if (seg_hash_obj == NULL) {
+		return (-1);
+	}
+
+	if (seg_hash_obj->u.seg_obj->num_of_packets != maxpackets) {
+		return (-1);
+	}
+
+	pkt_hash_obj = seg_hash_obj->u.seg_obj->pkt_obj_list;
+	if (pkt_hash_obj == NULL) {
+		return (-1);
+	}
+
+	for (count = 0; count < maxpackets; count++, packet++) {
+		packet->handle	= pkt_hash_obj->obj_hdl;
+		packet->tag = 0;
+		(void) memcpy(&packet->tag, &pkt_hash_obj->u.pkt_obj->tag,
+		    pkt_hash_obj->u.pkt_obj->tag_size);
+		pkt_hash_obj = pkt_hash_obj->u.pkt_obj->next;
+	}
+
+	return (0);
+}
+
+/* ARGSUSED */
+ssize_t
+fru_get_payload(packet_hdl_t packet, void *buffer, size_t nbytes,
+    door_cred_t *cred)
+{
+	hash_obj_t *packet_hash_obj;
+
+	/* packet hash object */
+	packet_hash_obj	= lookup_handle_object(packet, PACKET_TYPE);
+	if (packet_hash_obj == NULL) {
+		return (-1);
+	}
+
+	/* verify payload length */
+	if (nbytes != packet_hash_obj->u.pkt_obj->paylen) {
+		return (-1);
+	}
+
+	(void) memcpy(buffer, packet_hash_obj->u.pkt_obj->payload, nbytes);
+	return (nbytes);
+}
+
+
+container_hdl_t
+open_raw_data(raw_list_t *node)
+{
+	char *cont_conf_file = NULL;
+	hash_obj_t *cont_hash_obj;
+	hash_obj_t *sec_hash_obj;
+	container_info_t cont_info;
+	int retval;
+	int count;
+
+	cont_hash_obj = create_container_hash_object();
+	if (cont_hash_obj == NULL) {
+		return (NULL);
+	}
+
+	add_hashobject_to_hashtable(cont_hash_obj);
+
+	(void) strncpy(cont_hash_obj->u.cont_obj->device_pathname, "unknown",
+	    sizeof (cont_hash_obj->u.cont_obj->device_pathname));
+
+	cont_conf_file = getenv(FRU_CONT_CONF_ENV_VAR);
+	if (cont_conf_file == NULL) {
+		cont_conf_file = FRU_CONT_CONF_SPARC;
+		retval = get_container_info(cont_conf_file, node->cont_type,
+		    &cont_info);
+		if (retval < 0) {
+			cont_conf_file = FRU_CONT_CONF_X86;
+			retval = get_container_info(cont_conf_file,
+			    node->cont_type, &cont_info);
+		}
+	} else {
+		retval = get_container_info(cont_conf_file, node->cont_type,
+		    &cont_info);
+	}
+
+	if (retval < 0) {
+		return (NULL);
+	}
+
+	cont_hash_obj->u.cont_obj->num_of_section = cont_info.num_sections;
+	cont_hash_obj->u.cont_obj->sec_obj_list = NULL;
+
+	for (count = 0; count < cont_info.num_sections; count++) {
+		sec_hash_obj = create_section_hash_object();
+		if (sec_hash_obj == NULL) {
+			return (NULL);
+		}
+
+		add_hashobject_to_hashtable(sec_hash_obj);
+
+		sec_hash_obj->u.sec_obj->section.offset =
+		    cont_info.section_info[count].address;
+
+		sec_hash_obj->u.sec_obj->section.protection =
+		    cont_info.section_info[count].description.field.read_only;
+
+		sec_hash_obj->u.sec_obj->section.length =
+		    cont_info.section_info[count].size;
+		sec_hash_obj->u.sec_obj->section.version =
+		    cont_info.header_ver;
+
+		add_to_sec_object_list(cont_hash_obj, sec_hash_obj);
+	}
+
+	return (cont_hash_obj->obj_hdl);
+}
+
+
+int
+fru_close_container(container_hdl_t container)
+{
+	hash_obj_t *hash_obj;
+	hash_obj_t *prev_hash;
+	hash_obj_t *sec_hash_obj;
+	handle_t obj_hdl;
+
+	/* lookup for container hash object */
+	hash_obj = lookup_handle_object(container, CONTAINER_TYPE);
+	if (hash_obj == NULL) {
+		return (0);
+	}
+
+	/* points to section object list */
+	sec_hash_obj = hash_obj->u.cont_obj->sec_obj_list;
+
+	/* traverse section object list */
+	while (sec_hash_obj != NULL) {
+
+		/* traverse segment hash object in the section */
+		while (sec_hash_obj->u.sec_obj->seg_obj_list != NULL) {
+			/* object handle of the segment hash object */
+			obj_hdl	=
+			    sec_hash_obj->u.sec_obj->seg_obj_list->obj_hdl;
+			free_segment_hash(obj_hdl, sec_hash_obj);
+		}
+
+		/* going to free section hash object, relink the hash object */
+		if (sec_hash_obj->prev == NULL) {
+			hash_table[(sec_hash_obj->obj_hdl % TABLE_SIZE)] =
+			    sec_hash_obj->next;
+			if (sec_hash_obj->next != NULL) {
+				sec_hash_obj->next->prev = NULL;
+			}
+		} else {
+			sec_hash_obj->prev->next = sec_hash_obj->next;
+			if (sec_hash_obj->next != NULL) {
+				sec_hash_obj->next->prev = sec_hash_obj->prev;
+			}
+		}
+
+		free(sec_hash_obj->u.sec_obj); /* free section hash object */
+
+		prev_hash = sec_hash_obj;
+
+		sec_hash_obj = sec_hash_obj->u.sec_obj->next;
+
+		free(prev_hash); /* free section hash */
+	}
+
+	/* free container hash object */
+	if (hash_obj->prev == NULL) {
+		hash_table[(hash_obj->obj_hdl % TABLE_SIZE)] =
+		    hash_obj->next;
+		if (hash_obj->next != NULL) {
+			hash_obj->next->prev = NULL;
+		}
+	} else {
+		hash_obj->prev->next = hash_obj->next;
+		if (hash_obj->next != NULL) {
+			hash_obj->next->prev = hash_obj->prev;
+		}
+	}
+
+	free(hash_obj->u.cont_obj);
+	free(hash_obj);
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfruraw/sparc/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+include ../Makefile.com
+
+LDLIBS +=	-L$(SRC)/lib/libfruutils/$(MACH)
+LDLIBS +=	-L$(SRC)/lib/libfru/$(MACH)
+LDLIBS +=	-lc -lfru -lfruutils
+
+.KEEP_STATE:
+
+all: $(ROOTLIBDIR) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS):    FRC
+	$(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR):
+	$(INS.dir)
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
+
+FRC:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfruraw/sparcv9/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+LDLIBS +=	-L$(SRC)/lib/libfruutils/$(MACH64)
+LDLIBS +=	-L$(SRC)/lib/libfru/$(MACH64)
+LDLIBS +=	-lc -lfru -lfruutils
+
+.KEEP_STATE:
+
+all: $(ROOTLIBDIR64) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS):    FRC
+	$(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR64):
+	$(INS.dir)
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64)
+
+FRC:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfrureg/amd64/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+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:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libfrureg/i386/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+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:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libnvfru/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,67 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+include	$(SRC)/lib/Makefile.lib
+
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(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:
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libnvfru/Makefile.com	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,74 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+LIBRARY=	libnvfru.a
+VERS=		.1
+
+OBJECTS=	nvfru.o
+
+# include library definitions
+include $(SRC)/lib/Makefile.lib
+
+CLOBBERFILES += $(LIBLINKS)
+
+LIBS =		$(DYNLIB)
+
+MAPFILES =
+
+LINTFLAGS =	-uxn
+LINTFLAGS64 =	$(LINTFLAGS) -m64
+LINTOUT=	lint.out
+LINTSRC =       $(LINTLIB:%.ln=%)
+ROOTLINTDIR =   $(ROOTLIBDIR)
+ROOTLINT =      $(LINTSRC:%=$(ROOTLINTDIR)/%)
+
+CLEANFILES=	$(LINTOUT)
+
+CPPFLAGS +=	-I.. \
+		-I$(SRC)/lib/libfru/include \
+		-I$(SRC)/lib/libfruutils
+CPPFLAGS += 	-D_REENTRANT
+CFLAGS +=	$(CCVERBOSE)
+
+$(LINTLIB) :=	LINTFLAGS = -nvx -I..
+$(LINTLIB) :=	LINTFLAGS64 = -nvx -m64 -I..
+
+XGETFLAGS += -a
+
+.KEEP_STATE:
+
+all : $(LIBS)
+
+lint :	lintcheck
+
+# include library targets
+include $(SRC)/lib/Makefile.targ
+
+pics/%.o:	../%.c
+	$(COMPILE.c) -o $@ $<
+	$(POST_PROCESS_O)
+
+$(ROOTLINTDIR)/%: ../%
+	$(INS.file)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libnvfru/amd64/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,47 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+LDLIBS +=	-L$(SRC)/lib/libfruutils/$(MACH64)
+LDLIBS +=	-L$(SRC)/lib/libfru/libfrureg/$(MACH64)
+LDLIBS +=	-L$(SRC)/lib/libfru/$(MACH64)
+LDLIBS +=	-lc -lfru -lfruutils -lfrureg -lnvpair
+
+.KEEP_STATE:
+
+all: $(ROOTLIBDIR64) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS):    FRC
+	$(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR64):
+	$(INS.dir)
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64)
+
+FRC:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libnvfru/i386/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+include ../Makefile.com
+
+LDLIBS +=	-L$(SRC)/lib/libfruutils/$(MACH)
+LDLIBS +=	-L$(SRC)/lib/libfru/libfrureg/$(MACH)
+LDLIBS +=	-L$(SRC)/lib/libfru/$(MACH)
+LDLIBS +=	-lc -lfru -lfruutils -lfrureg -lnvpair
+
+.KEEP_STATE:
+
+all: $(ROOTLIBDIR) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS):    FRC
+	$(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR):
+	$(INS.dir)
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
+
+FRC:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libnvfru/nvfru.c	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,409 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <strings.h>
+#include <assert.h>
+#include <pthread.h>
+#include <sys/byteorder.h>
+#include <sys/types.h>
+#include <sys/nvpair.h>
+
+#include "libfru.h"
+#include "libfrup.h"
+#include "fru_tag.h"
+#include "libfrureg.h"
+
+
+#define	NUM_ITER_BYTES	4
+#define	HEAD_ITER 	0
+#define	TAIL_ITER	1
+#define	NUM_ITER	2
+#define	MAX_ITER	3
+#define	TIMESTRINGLEN	128
+
+#define	PARSE_TIME	1
+
+static pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER;
+
+
+
+static void
+convert_field(const uint8_t *field, const fru_regdef_t *def, const char *path,
+    nvlist_t *nv)
+{
+	char timestring[TIMESTRINGLEN];
+	int i;
+	uint64_t value;
+	time_t timefield;
+
+	switch (def->dataType) {
+	case FDTYPE_Binary:
+		assert(def->payloadLen <= sizeof (value));
+		switch (def->dispType) {
+#if PARSE_TIME == 1
+		case FDISP_Time:
+			if (def->payloadLen > sizeof (timefield)) {
+				/* too big for formatting */
+				return;
+			}
+			(void) memcpy(&timefield, field, sizeof (timefield));
+			timefield = BE_32(timefield);
+			if (strftime(timestring, sizeof (timestring), "%C",
+			    localtime(&timefield)) == 0) {
+				/* buffer too small */
+				return;
+			}
+			(void) nvlist_add_string(nv, path, timestring);
+			return;
+#endif
+
+		case FDISP_Binary:
+		case FDISP_Octal:
+		case FDISP_Decimal:
+		case FDISP_Hex:
+		default:
+			value = 0;
+			(void) memcpy((((uint8_t *)&value) +
+			    sizeof (value) - def->payloadLen),
+			    field, def->payloadLen);
+			value = BE_64(value);
+			switch (def->payloadLen) {
+			case 1:
+				(void) nvlist_add_uint8(nv, path,
+				    (uint8_t)value);
+				break;
+			case 2:
+				(void) nvlist_add_uint16(nv, path,
+				    (uint16_t)value);
+				break;
+			case 4:
+				(void) nvlist_add_uint32(nv, path,
+				    (uint32_t)value);
+				break;
+			default:
+				(void) nvlist_add_uint64(nv, path, value);
+			}
+			return;
+		}
+
+	case FDTYPE_ASCII:
+		(void) nvlist_add_string(nv, path, (char *)field);
+		return;
+
+	case FDTYPE_Enumeration:
+		value = 0;
+		(void) memcpy((((uint8_t *)&value) + sizeof (value) -
+		    def->payloadLen), field, def->payloadLen);
+		value = BE_64(value);
+		for (i = 0; i < def->enumCount; i++) {
+			if (def->enumTable[i].value == value) {
+				(void) nvlist_add_string(nv, path,
+				    def->enumTable[i].text);
+				return;
+			}
+		}
+	}
+
+	/* nothing matched above, use byte array */
+	(void) nvlist_add_byte_array(nv, path, (uchar_t *)field,
+	    def->payloadLen);
+}
+
+
+
+static void
+convert_element(const uint8_t *data, const fru_regdef_t *def, char *ppath,
+    nvlist_t *nv, boolean_t from_iter)
+{
+	int i;
+	char *path;
+
+	/* construct path */
+	if ((def->iterationCount == 0) &&
+	    (def->iterationType != FRU_NOT_ITERATED)) {
+		path = ppath;
+	} else {
+		path = (char *)def->name;
+	}
+
+	/* iteration, record and field */
+	if (def->iterationCount) {
+		int iterlen, n;
+		uint8_t head, num;
+		fru_regdef_t newdef;
+		nvlist_t **nv_elems;
+		char num_str[32];
+
+		iterlen = (def->payloadLen - NUM_ITER_BYTES) /
+		    def->iterationCount;
+
+		/*
+		 * make a new element definition to describe the components of
+		 * the iteration.
+		 */
+		(void) memcpy(&newdef, def, sizeof (newdef));
+		newdef.iterationCount = 0;
+		newdef.payloadLen = iterlen;
+
+		/* validate the content of the iteration control bytes */
+		if ((data[HEAD_ITER] >= def->iterationCount) ||
+		    (data[NUM_ITER] > def->iterationCount) ||
+		    (data[MAX_ITER] != def->iterationCount)) {
+			/* invalid. show all iterations */
+			head = 0;
+			num = def->iterationCount;
+		} else {
+			head = data[HEAD_ITER];
+			num = data[NUM_ITER];
+		}
+
+		nv_elems = (nvlist_t **)malloc(num * sizeof (nvlist_t *));
+		if (!nv_elems)
+			return;
+		for (i = head, n = 0, data += sizeof (uint32_t); n < num;
+		    i = ((i + 1) % def->iterationCount), n++) {
+			if (nvlist_alloc(&nv_elems[n], 0, 0) != 0)
+				return;
+			(void) snprintf(num_str, sizeof (num_str), "%d", n);
+			convert_element((data + i*iterlen), &newdef, num_str,
+			    nv_elems[n], B_TRUE);
+		}
+		(void) nvlist_add_nvlist_array(nv, path, nv_elems, num);
+
+	} else if (def->dataType == FDTYPE_Record) {
+		const fru_regdef_t *component;
+		nvlist_t *nv_record;
+
+		if (!from_iter) {
+			if (nvlist_alloc(&nv_record, 0, 0) != 0) {
+				return;
+			}
+		} else {
+			nv_record = nv;
+		}
+
+		for (i = 0; i < def->enumCount; i++,
+		    data += component->payloadLen) {
+			component = fru_reg_lookup_def_by_name(
+			    def->enumTable[i].text);
+			convert_element(data, component, "", nv_record,
+			    B_FALSE);
+		}
+
+		(void) nvlist_add_nvlist(nv, path, nv_record);
+
+	} else {
+		convert_field(data, def, path, nv);
+	}
+}
+
+
+static fru_regdef_t *
+alloc_unknown_fru_regdef(void)
+{
+	fru_regdef_t *p;
+
+	p = malloc(sizeof (fru_regdef_t));
+	if (!p) {
+		return (NULL);
+	}
+	p->version = REGDEF_VERSION;
+	p->name = NULL;
+	p->tagType = -1;
+	p->tagDense = -1;
+	p->payloadLen = -1;
+	p->dataLength = -1;
+	p->dataType = FDTYPE_ByteArray;
+	p->dispType = FDISP_Hex;
+	p->purgeable = FRU_WHICH_UNDEFINED;
+	p->relocatable = FRU_WHICH_UNDEFINED;
+	p->enumCount = 0;
+	p-> enumTable = NULL;
+	p->iterationCount = 0;
+	p->iterationType = FRU_NOT_ITERATED;
+	p->exampleString = NULL;
+
+	return (p);
+}
+
+static int
+convert_packet(fru_tag_t *tag, uint8_t *payload, size_t length, void *args)
+{
+	int tag_type;
+	size_t payload_length;
+	const fru_regdef_t *def;
+	nvlist_t *nv = (nvlist_t *)args;
+	char tagname[sizeof ("?_0123456789_0123456789")];
+	tag_type = get_tag_type(tag);
+	payload_length = 0;
+
+	/* check for unrecognized tag */
+	if ((tag_type == -1) ||
+	    ((payload_length = get_payload_length(tag)) != length)) {
+		fru_regdef_t *unknown;
+
+		unknown = alloc_unknown_fru_regdef();
+		unknown->payloadLen = length;
+		unknown->dataLength = unknown->payloadLen;
+
+		if (tag_type == -1) {
+			(void) snprintf(tagname, sizeof (tagname),
+			    "INVALID");
+		} else {
+			(void) snprintf(tagname, sizeof (tagname),
+			    "%s_%u_%u_%u", get_tagtype_str(tag_type),
+			    get_tag_dense(tag), payload_length, length);
+		}
+		unknown->name = tagname;
+		convert_element(payload, unknown, "", nv, B_FALSE);
+		free(unknown);
+
+	} else if ((def = fru_reg_lookup_def_by_tag(*tag)) == NULL) {
+		fru_regdef_t *unknown;
+
+		unknown = alloc_unknown_fru_regdef();
+		unknown->payloadLen = length;
+		unknown->dataLength = unknown->payloadLen;
+
+		(void) snprintf(tagname, sizeof (tagname), "%s_%u_%u",
+		    get_tagtype_str(tag_type),
+		    unknown->tagDense, payload_length);
+
+		unknown->name = tagname;
+		convert_element(payload, unknown, "", nv, B_FALSE);
+		free(unknown);
+
+	} else {
+
+		convert_element(payload, def, "", nv, B_FALSE);
+
+	}
+
+	return (FRU_SUCCESS);
+}
+
+
+static int
+convert_packets_in_segment(fru_seghdl_t segment, void *args)
+{
+	char *name;
+	int ret;
+	nvlist_t *nv = (nvlist_t *)args;
+	nvlist_t *nv_segment;
+
+	ret = fru_get_segment_name(segment, &name);
+	if (ret != FRU_SUCCESS) {
+		return (ret);
+	}
+
+	/* create a new nvlist for each segment */
+	ret = nvlist_alloc(&nv_segment, 0, 0);
+	if (ret) {
+		free(name);
+		return (FRU_FAILURE);
+	}
+
+	/* convert the segment to an nvlist */
+	ret = fru_for_each_packet(segment, convert_packet, nv_segment);
+	if (ret != FRU_SUCCESS) {
+		nvlist_free(nv_segment);
+		free(name);
+		return (ret);
+	}
+
+	/* add the nvlist for this segment */
+	(void) nvlist_add_nvlist(nv, name, nv_segment);
+
+	free(name);
+
+	return (FRU_SUCCESS);
+}
+
+
+static int
+convert_fru(fru_nodehdl_t hdl, nvlist_t **nvlist)
+{
+	int err;
+	nvlist_t *nv;
+	fru_node_t fru_type;
+
+	if (fru_get_node_type(hdl, &fru_type) != FRU_SUCCESS) {
+		return (-1);
+	}
+
+	if (fru_type != FRU_NODE_CONTAINER) {
+		return (-1);
+	}
+
+	err = nvlist_alloc(&nv, 0, 0);
+	if (err) {
+		return (err);
+	}
+
+	if (fru_for_each_segment(hdl, convert_packets_in_segment, nv) !=
+	    FRU_SUCCESS) {
+		nvlist_free(nv);
+		return (-1);
+	}
+
+	*nvlist = nv;
+
+	return (0);
+}
+
+
+int
+rawfru_to_nvlist(uint8_t *buffer, size_t bufsize, char *cont_type,
+    nvlist_t **nvlist)
+{
+	fru_errno_t fru_err;
+	fru_nodehdl_t hdl;
+	int err;
+
+	(void) pthread_mutex_lock(&gLock);
+	fru_err = fru_open_data_source("raw", buffer, bufsize, cont_type,
+	    NULL);
+	if (fru_err != FRU_SUCCESS) {
+		(void) pthread_mutex_unlock(&gLock);
+		return (-1);
+	}
+	fru_err = fru_get_root(&hdl);
+	if (fru_err != FRU_SUCCESS) {
+		(void) pthread_mutex_unlock(&gLock);
+		return (-1);
+	}
+
+	err = convert_fru(hdl, nvlist);
+
+	fru_close_data_source();
+
+	(void) pthread_mutex_unlock(&gLock);
+
+	return (err);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libnvfru/nvfru.h	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,43 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _NVFRU_H
+#define	_NVFRU_H
+
+#include <sys/types.h>
+#include <libnvpair.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+int rawfru_to_nvlist(uint8_t *, size_t, char *, nvlist_t **);
+
+#ifdef  __cplusplus
+	}
+#endif
+
+#endif /* _NVFRU_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libnvfru/sparc/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+include ../Makefile.com
+
+LDLIBS +=	-L$(SRC)/lib/libfruutils/$(MACH)
+LDLIBS +=	-L$(SRC)/lib/libfru/libfrureg/$(MACH)
+LDLIBS +=	-L$(SRC)/lib/libfru/$(MACH)
+LDLIBS +=	-lc -lfru -lfruutils -lfrureg -lnvpair
+
+.KEEP_STATE:
+
+all: $(ROOTLIBDIR) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS):    FRC
+	$(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR):
+	$(INS.dir)
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
+
+FRC:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfru/libnvfru/sparcv9/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,47 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+LDLIBS +=	-L$(SRC)/lib/libfruutils/$(MACH64)
+LDLIBS +=	-L$(SRC)/lib/libfru/libfrureg/$(MACH64)
+LDLIBS +=	-L$(SRC)/lib/libfru/$(MACH64)
+LDLIBS +=	-lc -lfru -lfruutils -lfrureg -lnvpair
+
+.KEEP_STATE:
+
+all: $(ROOTLIBDIR64) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS):    FRC
+	$(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR64):
+	$(INS.dir)
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64)
+
+FRC:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfruutils/amd64/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,42 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+
+include ../Makefile.com
+include $(SRC)/lib/Makefile.lib.64
+
+.KEEP_STATE:
+
+LDLIBS += -lc
+
+all:  $(ROOTLIBDIR64) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS):    FRC
+	$(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR64):
+	$(INS.dir)
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64)
+
+FRC:
--- a/usr/src/lib/libfruutils/fru_tag.c	Mon Nov 09 16:25:35 2009 -0800
+++ b/usr/src/lib/libfruutils/fru_tag.c	Mon Nov 09 16:53:15 2009 -0800
@@ -2,9 +2,8 @@
  * 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.
+ * Common Development and Distribution License (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.
@@ -19,13 +18,12 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <errno.h>
 
 #include "fru_tag.h"
@@ -156,6 +154,50 @@
 	return (get_tag_size(type));
 }
 
+#if defined(_LITTLE_ENDIAN)
+fru_tagtype_t
+get_tag_type(fru_tag_t *tag)
+{
+	uint64_t tmp64;
+	uint32_t tmp32;
+	fru_tag_t tmp;
+
+	if (tag->a.type == FRU_A_ID)
+		return (FRU_A);
+
+	tmp.raw_data = (tag->byte[0] << 8) | tag->byte[1];
+	if (tmp.b.type == FRU_B_ID)
+		return (FRU_B);
+	if (tmp.c.type == FRU_C_ID)
+		return (FRU_C);
+
+	tmp32 = (tag->byte[0] << 16) | (tag->byte[1] << 8) | tag->byte[2];
+	tmp.raw_data = tmp32;
+	if (tmp.d.type == FRU_D_ID)
+		return (FRU_D);
+	if (tmp.e.type == FRU_E_ID)
+		return (FRU_E);
+
+	tmp32 = (tag->byte[0] << 24) | (tag->byte[1] << 16) |
+	    (tag->byte[2] << 8) | tag->byte[3];
+	tmp.raw_data = tmp32;
+	if (tmp.f.type == FRU_F_ID)
+		return (FRU_F);
+
+	tmp64 = ((uint64_t)tag->byte[0] << 40) |
+	    ((uint64_t)tag->byte[1] << 32) |
+	    ((uint64_t)tag->byte[2] << 24) |
+	    ((uint64_t)tag->byte[3] << 16) |
+	    ((uint64_t)tag->byte[4] << 8) |
+	    (uint64_t)tag->byte[5];
+	tmp.raw_data = tmp64;
+	if (tmp.g.type == FRU_G_ID)
+		return (FRU_G);
+
+	errno = EINVAL;
+	return (-1);
+}
+#else
 fru_tagtype_t
 get_tag_type(fru_tag_t *tag)
 {
@@ -177,7 +219,56 @@
 		errno = EINVAL;
 		return (-1);
 }
+#endif  /* _LITTLE_ENDIAN */
 
+#if defined(_LITTLE_ENDIAN)
+uint32_t
+get_tag_dense(fru_tag_t *tag)
+{
+	uint64_t tmp64;
+	uint32_t tmp32;
+	fru_tag_t tmp;
+
+	tmp = *tag;
+	switch (get_tag_type(tag)) {
+		case FRU_A:
+			return (tag->a.dense);
+		case FRU_B:
+			tmp.raw_data = (tag->byte[0] << 8) | tag->byte[1];
+			return (tmp.b.dense);
+		case FRU_C:
+			tmp.raw_data = (tag->byte[0] << 8) | tag->byte[1];
+			return (tmp.c.dense);
+		case FRU_D:
+			tmp32 = (tag->byte[0] << 16) | (tag->byte[1] << 8) |
+			    tag->byte[2];
+			tmp.raw_data = tmp32;
+			return (tmp.d.dense);
+		case FRU_E:
+			tmp32 = (tag->byte[0] << 16) | (tag->byte[1] << 8) |
+			    tag->byte[2];
+			tmp.raw_data = tmp32;
+			return (tmp.e.dense);
+		case FRU_F:
+			tmp32 = (tag->byte[0] << 24) | (tag->byte[1] << 16) |
+			    (tag->byte[2] << 8) | tag->byte[3];
+			tmp.raw_data = tmp32;
+			return (tmp.f.dense);
+		case FRU_G:
+			tmp64 = ((uint64_t)tag->byte[0] << 40) |
+			    ((uint64_t)tag->byte[1] << 32) |
+			    ((uint64_t)tag->byte[2] << 24) |
+			    ((uint64_t)tag->byte[3] << 16) |
+			    ((uint64_t)tag->byte[4] << 8) |
+			    (uint64_t)tag->byte[5];
+			tmp.raw_data = tmp64;
+			return (tmp.g.dense);
+		default:
+			errno = EINVAL;
+			return ((uint32_t)-1);
+	}
+}
+#else
 uint32_t
 get_tag_dense(fru_tag_t *tag)
 {
@@ -201,7 +292,56 @@
 			return ((uint32_t)-1);
 	}
 }
+#endif  /* _LITTLE_ENDIAN */
 
+#if defined(_LITTLE_ENDIAN)
+size_t
+get_payload_length(fru_tag_t *tag)
+{
+	uint64_t tmp64;
+	uint32_t tmp32;
+	fru_tag_t tmp;
+
+	tmp = *tag;
+	switch (get_tag_type(tag)) {
+		case FRU_A:
+			return (tag->a.pl_len);
+		case FRU_B:
+			tmp.raw_data = (tag->byte[0] << 8) | tag->byte[1];
+			return (tmp.b.pl_len);
+		case FRU_C:
+			tmp.raw_data = (tag->byte[0] << 8) | tag->byte[1];
+			return (tmp.c.pl_len);
+		case FRU_D:
+			tmp32 = (tag->byte[0] << 16) | (tag->byte[1] << 8) |
+			    tag->byte[2];
+			tmp.raw_data = tmp32;
+			return (tmp.d.pl_len);
+		case FRU_E:
+			tmp32 = (tag->byte[0] << 16) | (tag->byte[1] << 8) |
+			    tag->byte[2];
+			tmp.raw_data = tmp32;
+			return (tmp.e.pl_len);
+		case FRU_F:
+			tmp32 = (tag->byte[0] << 24) | (tag->byte[1] << 16) |
+			    (tag->byte[2] << 8) | tag->byte[3];
+			tmp.raw_data = tmp32;
+			return (tmp.f.pl_len);
+		case FRU_G:
+			tmp64 = ((uint64_t)tag->byte[0] << 40) |
+			    ((uint64_t)tag->byte[1] << 32) |
+			    ((uint64_t)tag->byte[2] << 24) |
+			    ((uint64_t)tag->byte[3] << 16) |
+			    ((uint64_t)tag->byte[4] << 8) |
+			    (uint64_t)tag->byte[5];
+			tmp.raw_data = tmp64;
+			return (tmp.g.pl_len);
+		default:
+			errno = EINVAL;
+			return ((uint32_t)-1);
+	}
+}
+#else
 size_t
 get_payload_length(fru_tag_t *tag)
 {
@@ -225,11 +365,12 @@
 			return ((uint32_t)-1);
 	}
 }
+#endif  /* _LITTLE_ENDIAN */
 
 int
 tags_equal(fru_tag_t t1, fru_tag_t t2)
 {
 	return ((get_tag_type(&t1) == get_tag_type(&t2)) &&
-		(get_tag_dense(&t1) == get_tag_dense(&t2)) &&
-		(get_payload_length(&t1) == get_payload_length(&t2)));
+	    (get_tag_dense(&t1) == get_tag_dense(&t2)) &&
+	    (get_payload_length(&t1) == get_payload_length(&t2)));
 }
--- a/usr/src/lib/libfruutils/fru_tag.h	Mon Nov 09 16:25:35 2009 -0800
+++ b/usr/src/lib/libfruutils/fru_tag.h	Mon Nov 09 16:53:15 2009 -0800
@@ -2,9 +2,8 @@
  * 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.
+ * Common Development and Distribution License (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.
@@ -19,22 +18,66 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright (c) 2000 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
+
 #ifndef	_FRU_TAG_H
 #define	_FRU_TAG_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/types.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if defined(_LITTLE_ENDIAN)
+
+typedef union {
+	uint64_t raw_data;
+	unsigned char byte[8];
+	struct {
+		unsigned pl_len : 3;
+		unsigned dense : 4;
+		unsigned type : 1;
+	} a;
+	struct {
+		unsigned pl_len : 3;
+		unsigned dense : 11;
+		unsigned type : 2;
+	} b;
+	struct {
+		unsigned pl_len : 5;
+		unsigned dense : 8;
+		unsigned type : 3;
+	} c;
+	struct {
+		unsigned pl_len : 3;
+		unsigned dense : 17;
+		unsigned type : 4;
+	} d;
+	struct {
+		unsigned pl_len : 7;
+		unsigned dense : 12;
+		unsigned type : 5;
+	} e;
+	struct {
+		unsigned pl_len : 12;
+		unsigned dense : 14;
+		unsigned type : 6;
+	} f;
+	struct {
+		unsigned pl_len : 32;
+		unsigned dense : 9;
+		unsigned type : 7;
+	} g;
+} fru_tag_t;
+
+#else
+
 typedef union {
 	uint64_t raw_data;
 	char byte[8];
@@ -75,6 +118,8 @@
 	} g;
 } fru_tag_t;
 
+#endif  /* LITTLE_ENDIAN */
+
 #define	FRU_ID_MASK 0xFF
 #define	FRU_A_ID 0x00
 #define	FRU_B_ID 0x02
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libfruutils/i386/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,43 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+include ../Makefile.com
+
+LDLIBS += -lc
+
+.KEEP_STATE:
+
+all:  $(ROOTLIBDIR) $(LIBS) $(LIBLINKS)
+
+$(LIBLINKS):    FRC
+	$(RM) $@; $(SYMLINK) $(DYNLIB) $@
+
+$(ROOTLIBDIR):
+	$(INS.dir)
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
+
+FRC:
+
--- a/usr/src/pkgdefs/Makefile	Mon Nov 09 16:25:35 2009 -0800
+++ b/usr/src/pkgdefs/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -52,7 +52,6 @@
 	SUNWefc.u \
 	SUNWefck \
 	SUNWerid \
-	SUNWfruid \
 	SUNWfruip.u \
 	SUNWfsr \
 	SUNWfsu \
@@ -128,6 +127,7 @@
 	SUNWgrubS \
 	SUNWdcopy \
 	SUNWfipe \
+	SUNWfruip.i \
 	SUNWipw \
 	SUNWiwh	\
 	SUNWiwi \
@@ -265,6 +265,7 @@
 	SUNWfilebench \
 	SUNWfmd  \
 	SUNWfmdr  \
+	SUNWfruid \
 	SUNWfss \
 	SUNWftdur \
 	SUNWftduu \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWfruid/prototype_com	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,61 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>	# where to find pkg objects
+#!include <filename>			# include another 'prototype' file
+#!default <mode> <owner> <group>	# default used if not specified on entry
+#!<param>=<value>			# puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+#
+# List files which are common here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWfruid
+#
+d none usr 755 root sys
+d none usr/lib 755 root bin
+f none usr/lib/libfru.so.1 755 root bin
+s none usr/lib/libfru.so=./libfru.so.1 755 root bin
+f none usr/lib/libfrureg.so.1 755 root bin
+s none usr/lib/libfrureg.so=./libfrureg.so.1 755 root bin
+f none usr/lib/libfruutils.so.1 755 root bin
+s none usr/lib/libfruutils.so=./libfruutils.so.1 755 root bin
+f none usr/lib/libfruraw.so.1 755 root bin
+s none usr/lib/libfruraw.so=./libfruraw.so.1 755 root bin
+f none usr/lib/libnvfru.so.1 755 root bin
+s none usr/lib/libnvfru.so=./libnvfru.so.1 755 root bin
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWfruid/prototype_i386	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>        # where to find pkg objects
+#!include <filename>                    # include another 'prototype' file
+#!default <mode> <owner> <group>        # default used if not specified on entry
+#!<param>=<value>                       # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWfruid
+#
+d none usr/lib/amd64 755 root bin
+f none usr/lib/amd64/libfru.so.1 755 root bin
+s none usr/lib/amd64/libfru.so=./libfru.so.1 755 root bin
+f none usr/lib/amd64/libfrureg.so.1 755 root bin
+s none usr/lib/amd64/libfrureg.so=./libfrureg.so.1 755 root bin
+f none usr/lib/amd64/libfruutils.so.1 755 root bin
+s none usr/lib/amd64/libfruutils.so=./libfruutils.so.1 755 root bin
+f none usr/lib/amd64/libfruraw.so.1 755 root bin
+s none usr/lib/amd64/libfruraw.so=./libfruraw.so.1 755 root bin
+f none usr/lib/amd64/libnvfru.so.1 755 root bin
+s none usr/lib/amd64/libnvfru.so=./libnvfru.so.1 755 root bin
--- a/usr/src/pkgdefs/SUNWfruid/prototype_sparc	Mon Nov 09 16:25:35 2009 -0800
+++ b/usr/src/pkgdefs/SUNWfruid/prototype_sparc	Mon Nov 09 16:53:15 2009 -0800
@@ -2,9 +2,8 @@
 # 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.
+# Common Development and Distribution License (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.
@@ -19,26 +18,24 @@
 #
 # CDDL HEADER END
 #
-#
-# Copyright 1999-2001,2003 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-#
 # This required package information file contains a list of package contents.
 # The 'pkgmk' command uses this file to identify the contents of a package
 # and their location on the development machine when building the package.
 # Can be created via a text editor or through use of the 'pkgproto' command.
 
-#!search <pathname pathname ...>	# where to find pkg objects
-#!include <filename>			# include another 'prototype' file
-#!default <mode> <owner> <group>	# default used if not specified on entry
-#!<param>=<value>			# puts parameter in pkg environment
+#!search <pathname pathname ...>        # where to find pkg objects
+#!include <filename>                    # include another 'prototype' file
+#!default <mode> <owner> <group>        # default used if not specified on entry
+#!<param>=<value>                       # puts parameter in pkg environment
 
-# packaging files
-i pkginfo
-i copyright
-i depend
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
 #
 #
 # List files which are SPARC specific here
@@ -48,20 +45,12 @@
 #
 # SUNWfruid
 #
-d none usr 755 root sys
 d none usr/sbin 755 root bin
 f none usr/sbin/prtfru 755 root bin
-d none usr/lib 755 root bin
-f none usr/lib/libfru.so.1 755 root bin
-s none usr/lib/libfru.so=./libfru.so.1 755 root bin
 f none usr/lib/libfrupicl.so.1 755 root bin
 s none usr/lib/libfrupicl.so=./libfrupicl.so.1 755 root bin
 f none usr/lib/libfrupicltree.so.1 755 root bin
 s none usr/lib/libfrupicltree.so=./libfrupicltree.so.1 755 root bin
-f none usr/lib/libfrureg.so.1 755 root bin
-s none usr/lib/libfrureg.so=./libfrureg.so.1 755 root bin
-f none usr/lib/libfruutils.so.1 755 root bin
-s none usr/lib/libfruutils.so=./libfruutils.so.1 755 root bin
 d none usr/lib/sparcv9 755 root bin
 f none usr/lib/sparcv9/libfru.so.1 755 root bin
 s none usr/lib/sparcv9/libfru.so=./libfru.so.1 755 root bin
@@ -71,3 +60,7 @@
 s none usr/lib/sparcv9/libfrureg.so=./libfrureg.so.1 755 root bin
 f none usr/lib/sparcv9/libfruutils.so.1 755 root bin
 s none usr/lib/sparcv9/libfruutils.so=./libfruutils.so.1 755 root bin
+f none usr/lib/sparcv9/libfruraw.so.1 755 root bin
+s none usr/lib/sparcv9/libfruraw.so=./libfruraw.so.1 755 root bin
+f none usr/lib/sparcv9/libnvfru.so.1 755 root bin
+s none usr/lib/sparcv9/libnvfru.so=./libnvfru.so.1 755 root bin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWfruip.i/Makefile	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+
+include	../Makefile.com
+
+.KEEP_STATE:
+
+all: $(FILES) depend
+install: all pkg
+
+include ../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWfruip.i/depend	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,53 @@
+#
+# Copyright 2009 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 (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
+#
+#
+# This package information file defines software dependencies associated
+# with the pkg.  You can define three types of pkg dependencies with this file:
+#	 P indicates a prerequisite for installation
+#	 I indicates an incompatible package
+#	 R indicates a reverse dependency
+# <pkg.abbr> see pkginfo(4), PKG parameter
+# <name> see pkginfo(4), NAME parameter
+# <version> see pkginfo(4), VERSION parameter
+# <arch> see pkginfo(4), ARCH parameter
+# <type> <pkg.abbr> <name>
+# 	(<arch>)<version>
+# 	(<arch>)<version>
+# 	...
+# <type> <pkg.abbr> <name>
+# ...
+#
+
+P SUNWcar	Core Architecture, (Root)
+P SUNWcakr	Core Solaris Kernel Architecture (Root)
+P SUNWkvm	Core Architecture, (Kvm)
+P SUNWcsr	Core Solaris, (Root)
+P SUNWckr	Core Solaris Kernel (Root)
+P SUNWcnetr	Core Solaris Network Infrastructure (Root)
+P SUNWcsu	Core Solaris, (Usr)
+P SUNWcsd	Core Solaris Devices
+P SUNWcsl	Core Solaris Libraries
+P SUNWcslr	Core Solaris Libraries (Root)
+P SUNWpiclu	PICL Libraries, and Plugin Modules (Usr)
+P SUNWfruid	FRU ID Utility and Library (Usr)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWfruip.i/pkginfo.tmpl	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,57 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWfruip"
+NAME="FRU ID Platform Modules (Usr)"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="kvm"
+MAXINST="1000"
+CATEGORY="system"
+DESC="FRU ID platform data module and access library"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWfruip.i/prototype_i386	Mon Nov 09 16:53:15 2009 -0800
@@ -0,0 +1,53 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>	# where to find pkg objects
+#!include <filename>			# include another 'prototype' file
+#!default <mode> <owner> <group>	# default used if not specified on entry
+#!<param>=<value>			# puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+#
+# List files which are i386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWfruip.i
+#
+d none usr 755 root sys
+d none usr/lib 755 root bin
+d none usr/lib/picl 755 root sys
+d none usr/lib/picl/plugins 755 root sys
+f none usr/lib/picl/plugins/fru_container.conf 644 root sys