summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/lib/Makefile4
-rw-r--r--usr/src/lib/libfru/Makefile24
-rw-r--r--usr/src/lib/libfru/amd64/Makefile40
-rw-r--r--usr/src/lib/libfru/conf/Makefile56
-rw-r--r--usr/src/lib/libfru/conf/fru_container.conf52
-rw-r--r--usr/src/lib/libfru/i386/Makefile41
-rw-r--r--usr/src/lib/libfru/include/libfru.h47
-rw-r--r--usr/src/lib/libfru/libfruraw/Makefile66
-rw-r--r--usr/src/lib/libfru/libfruraw/Makefile.com84
-rw-r--r--usr/src/lib/libfru/libfruraw/amd64/Makefile46
-rw-r--r--usr/src/lib/libfru/libfruraw/crcmodel.c170
-rw-r--r--usr/src/lib/libfru/libfruraw/crcmodel.h181
-rw-r--r--usr/src/lib/libfru/libfruraw/crcutils.c157
-rw-r--r--usr/src/lib/libfru/libfruraw/fru_access.h114
-rw-r--r--usr/src/lib/libfru/libfruraw/fru_access_impl.h205
-rw-r--r--usr/src/lib/libfru/libfruraw/fruraw.c737
-rw-r--r--usr/src/lib/libfru/libfruraw/fruraw.h70
-rw-r--r--usr/src/lib/libfru/libfruraw/i386/Makefile45
-rw-r--r--usr/src/lib/libfru/libfruraw/raw_access.c1227
-rw-r--r--usr/src/lib/libfru/libfruraw/sparc/Makefile45
-rw-r--r--usr/src/lib/libfru/libfruraw/sparcv9/Makefile46
-rw-r--r--usr/src/lib/libfru/libfrureg/amd64/Makefile46
-rw-r--r--usr/src/lib/libfru/libfrureg/i386/Makefile45
-rw-r--r--usr/src/lib/libfru/libnvfru/Makefile67
-rw-r--r--usr/src/lib/libfru/libnvfru/Makefile.com74
-rw-r--r--usr/src/lib/libfru/libnvfru/amd64/Makefile47
-rw-r--r--usr/src/lib/libfru/libnvfru/i386/Makefile46
-rw-r--r--usr/src/lib/libfru/libnvfru/nvfru.c409
-rw-r--r--usr/src/lib/libfru/libnvfru/nvfru.h43
-rw-r--r--usr/src/lib/libfru/libnvfru/sparc/Makefile46
-rw-r--r--usr/src/lib/libfru/libnvfru/sparcv9/Makefile47
-rw-r--r--usr/src/lib/libfruutils/amd64/Makefile42
-rw-r--r--usr/src/lib/libfruutils/fru_tag.c157
-rw-r--r--usr/src/lib/libfruutils/fru_tag.h59
-rw-r--r--usr/src/lib/libfruutils/i386/Makefile43
-rw-r--r--usr/src/pkgdefs/Makefile3
-rw-r--r--usr/src/pkgdefs/SUNWfruid/prototype_com61
-rw-r--r--usr/src/pkgdefs/SUNWfruid/prototype_i38659
-rw-r--r--usr/src/pkgdefs/SUNWfruid/prototype_sparc39
-rw-r--r--usr/src/pkgdefs/SUNWfruip.i/Makefile35
-rw-r--r--usr/src/pkgdefs/SUNWfruip.i/depend53
-rw-r--r--usr/src/pkgdefs/SUNWfruip.i/pkginfo.tmpl57
-rw-r--r--usr/src/pkgdefs/SUNWfruip.i/prototype_i38653
43 files changed, 4931 insertions, 57 deletions
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile
index 850b3cc570..12860d0ff9 100644
--- a/usr/src/lib/Makefile
+++ b/usr/src/lib/Makefile
@@ -264,6 +264,8 @@ SUBDIRS += \
librstp \
libreparse \
libhotplug \
+ libfruutils .WAIT \
+ libfru \
$($(MACH)_SUBDIRS)
i386_SUBDIRS= \
@@ -280,8 +282,6 @@ sparc_SUBDIRS= .WAIT \
libprtdiag_psr \
libpri \
librsc \
- libfruutils .WAIT \
- libfru \
storage \
libpcp \
libtsalarm
diff --git a/usr/src/lib/libfru/Makefile b/usr/src/lib/libfru/Makefile
index 01995e26bd..74d551e9be 100644
--- a/usr/src/lib/libfru/Makefile
+++ b/usr/src/lib/libfru/Makefile
@@ -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
diff --git a/usr/src/lib/libfru/amd64/Makefile b/usr/src/lib/libfru/amd64/Makefile
new file mode 100644
index 0000000000..230c18efea
--- /dev/null
+++ b/usr/src/lib/libfru/amd64/Makefile
@@ -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
diff --git a/usr/src/lib/libfru/conf/Makefile b/usr/src/lib/libfru/conf/Makefile
new file mode 100644
index 0000000000..82eea308d8
--- /dev/null
+++ b/usr/src/lib/libfru/conf/Makefile
@@ -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
+
diff --git a/usr/src/lib/libfru/conf/fru_container.conf b/usr/src/lib/libfru/conf/fru_container.conf
new file mode 100644
index 0000000000..33fb26a819
--- /dev/null
+++ b/usr/src/lib/libfru/conf/fru_container.conf
@@ -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
+
diff --git a/usr/src/lib/libfru/i386/Makefile b/usr/src/lib/libfru/i386/Makefile
new file mode 100644
index 0000000000..e04d11b309
--- /dev/null
+++ b/usr/src/lib/libfru/i386/Makefile
@@ -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
+
diff --git a/usr/src/lib/libfru/include/libfru.h b/usr/src/lib/libfru/include/libfru.h
index 756e22dfbc..207fdcdfa3 100644
--- a/usr/src/lib/libfru/include/libfru.h
+++ b/usr/src/lib/libfru/include/libfru.h
@@ -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 @@ typedef struct {
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 @@ typedef union
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 @@ typedef union
#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 @@ typedef union
unsigned : 8;
} field;
} fru_seg_hwdesc_t;
+#endif
#define FRU_SEGNAMELEN 2
typedef struct {
diff --git a/usr/src/lib/libfru/libfruraw/Makefile b/usr/src/lib/libfru/libfruraw/Makefile
new file mode 100644
index 0000000000..3d39b02828
--- /dev/null
+++ b/usr/src/lib/libfru/libfruraw/Makefile
@@ -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:
+
diff --git a/usr/src/lib/libfru/libfruraw/Makefile.com b/usr/src/lib/libfru/libfruraw/Makefile.com
new file mode 100644
index 0000000000..1302bceca9
--- /dev/null
+++ b/usr/src/lib/libfru/libfruraw/Makefile.com
@@ -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)
diff --git a/usr/src/lib/libfru/libfruraw/amd64/Makefile b/usr/src/lib/libfru/libfruraw/amd64/Makefile
new file mode 100644
index 0000000000..cb5b955305
--- /dev/null
+++ b/usr/src/lib/libfru/libfruraw/amd64/Makefile
@@ -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:
diff --git a/usr/src/lib/libfru/libfruraw/crcmodel.c b/usr/src/lib/libfru/libfruraw/crcmodel.c
new file mode 100644
index 0000000000..2d7c46d8b6
--- /dev/null
+++ b/usr/src/lib/libfru/libfruraw/crcmodel.c
@@ -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));
+}
diff --git a/usr/src/lib/libfru/libfruraw/crcmodel.h b/usr/src/lib/libfru/libfruraw/crcmodel.h
new file mode 100644
index 0000000000..9c30c19061
--- /dev/null
+++ b/usr/src/lib/libfru/libfruraw/crcmodel.h
@@ -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 */
diff --git a/usr/src/lib/libfru/libfruraw/crcutils.c b/usr/src/lib/libfru/libfruraw/crcutils.c
new file mode 100644
index 0000000000..a3815e700d
--- /dev/null
+++ b/usr/src/lib/libfru/libfruraw/crcutils.c
@@ -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);
+}
diff --git a/usr/src/lib/libfru/libfruraw/fru_access.h b/usr/src/lib/libfru/libfruraw/fru_access.h
new file mode 100644
index 0000000000..7c78b9bc8e
--- /dev/null
+++ b/usr/src/lib/libfru/libfruraw/fru_access.h
@@ -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 */
diff --git a/usr/src/lib/libfru/libfruraw/fru_access_impl.h b/usr/src/lib/libfru/libfruraw/fru_access_impl.h
new file mode 100644
index 0000000000..f2a33d01e1
--- /dev/null
+++ b/usr/src/lib/libfru/libfruraw/fru_access_impl.h
@@ -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 */
diff --git a/usr/src/lib/libfru/libfruraw/fruraw.c b/usr/src/lib/libfru/libfruraw/fruraw.c
new file mode 100644
index 0000000000..872d3c203e
--- /dev/null
+++ b/usr/src/lib/libfru/libfruraw/fruraw.c
@@ -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
+};
diff --git a/usr/src/lib/libfru/libfruraw/fruraw.h b/usr/src/lib/libfru/libfruraw/fruraw.h
new file mode 100644
index 0000000000..0e40f0be2a
--- /dev/null
+++ b/usr/src/lib/libfru/libfruraw/fruraw.h
@@ -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 */
diff --git a/usr/src/lib/libfru/libfruraw/i386/Makefile b/usr/src/lib/libfru/libfruraw/i386/Makefile
new file mode 100644
index 0000000000..e2817aeee5
--- /dev/null
+++ b/usr/src/lib/libfru/libfruraw/i386/Makefile
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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:
diff --git a/usr/src/lib/libfru/libfruraw/raw_access.c b/usr/src/lib/libfru/libfruraw/raw_access.c
new file mode 100644
index 0000000000..6fe602d7b2
--- /dev/null
+++ b/usr/src/lib/libfru/libfruraw/raw_access.c
@@ -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);
+}
diff --git a/usr/src/lib/libfru/libfruraw/sparc/Makefile b/usr/src/lib/libfru/libfruraw/sparc/Makefile
new file mode 100644
index 0000000000..e2817aeee5
--- /dev/null
+++ b/usr/src/lib/libfru/libfruraw/sparc/Makefile
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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:
diff --git a/usr/src/lib/libfru/libfruraw/sparcv9/Makefile b/usr/src/lib/libfru/libfruraw/sparcv9/Makefile
new file mode 100644
index 0000000000..cb5b955305
--- /dev/null
+++ b/usr/src/lib/libfru/libfruraw/sparcv9/Makefile
@@ -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:
diff --git a/usr/src/lib/libfru/libfrureg/amd64/Makefile b/usr/src/lib/libfru/libfrureg/amd64/Makefile
new file mode 100644
index 0000000000..6cde243bbb
--- /dev/null
+++ b/usr/src/lib/libfru/libfrureg/amd64/Makefile
@@ -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:
diff --git a/usr/src/lib/libfru/libfrureg/i386/Makefile b/usr/src/lib/libfru/libfrureg/i386/Makefile
new file mode 100644
index 0000000000..221026a4f8
--- /dev/null
+++ b/usr/src/lib/libfru/libfrureg/i386/Makefile
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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:
diff --git a/usr/src/lib/libfru/libnvfru/Makefile b/usr/src/lib/libfru/libnvfru/Makefile
new file mode 100644
index 0000000000..642ecbd02a
--- /dev/null
+++ b/usr/src/lib/libfru/libnvfru/Makefile
@@ -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:
+
diff --git a/usr/src/lib/libfru/libnvfru/Makefile.com b/usr/src/lib/libfru/libnvfru/Makefile.com
new file mode 100644
index 0000000000..79f9b20089
--- /dev/null
+++ b/usr/src/lib/libfru/libnvfru/Makefile.com
@@ -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)
diff --git a/usr/src/lib/libfru/libnvfru/amd64/Makefile b/usr/src/lib/libfru/libnvfru/amd64/Makefile
new file mode 100644
index 0000000000..1953fb437d
--- /dev/null
+++ b/usr/src/lib/libfru/libnvfru/amd64/Makefile
@@ -0,0 +1,47 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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:
diff --git a/usr/src/lib/libfru/libnvfru/i386/Makefile b/usr/src/lib/libfru/libnvfru/i386/Makefile
new file mode 100644
index 0000000000..b16c6b1214
--- /dev/null
+++ b/usr/src/lib/libfru/libnvfru/i386/Makefile
@@ -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:
diff --git a/usr/src/lib/libfru/libnvfru/nvfru.c b/usr/src/lib/libfru/libnvfru/nvfru.c
new file mode 100644
index 0000000000..aa47eed931
--- /dev/null
+++ b/usr/src/lib/libfru/libnvfru/nvfru.c
@@ -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);
+}
diff --git a/usr/src/lib/libfru/libnvfru/nvfru.h b/usr/src/lib/libfru/libnvfru/nvfru.h
new file mode 100644
index 0000000000..f06110adc6
--- /dev/null
+++ b/usr/src/lib/libfru/libnvfru/nvfru.h
@@ -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 */
diff --git a/usr/src/lib/libfru/libnvfru/sparc/Makefile b/usr/src/lib/libfru/libnvfru/sparc/Makefile
new file mode 100644
index 0000000000..b16c6b1214
--- /dev/null
+++ b/usr/src/lib/libfru/libnvfru/sparc/Makefile
@@ -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:
diff --git a/usr/src/lib/libfru/libnvfru/sparcv9/Makefile b/usr/src/lib/libfru/libnvfru/sparcv9/Makefile
new file mode 100644
index 0000000000..1953fb437d
--- /dev/null
+++ b/usr/src/lib/libfru/libnvfru/sparcv9/Makefile
@@ -0,0 +1,47 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (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:
diff --git a/usr/src/lib/libfruutils/amd64/Makefile b/usr/src/lib/libfruutils/amd64/Makefile
new file mode 100644
index 0000000000..80cb65114a
--- /dev/null
+++ b/usr/src/lib/libfruutils/amd64/Makefile
@@ -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:
diff --git a/usr/src/lib/libfruutils/fru_tag.c b/usr/src/lib/libfruutils/fru_tag.c
index 1e5032971e..b14646dd45 100644
--- a/usr/src/lib/libfruutils/fru_tag.c
+++ b/usr/src/lib/libfruutils/fru_tag.c
@@ -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 @@ mk_tag(fru_tagtype_t type, uint32_t dense, size_t pl_len,
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 @@ get_tag_type(fru_tag_t *tag)
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 @@ get_tag_dense(fru_tag_t *tag)
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 @@ get_payload_length(fru_tag_t *tag)
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)));
}
diff --git a/usr/src/lib/libfruutils/fru_tag.h b/usr/src/lib/libfruutils/fru_tag.h
index 391864b02c..3c5d6c1f65 100644
--- a/usr/src/lib/libfruutils/fru_tag.h
+++ b/usr/src/lib/libfruutils/fru_tag.h
@@ -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 @@ typedef union {
} g;
} fru_tag_t;
+#endif /* LITTLE_ENDIAN */
+
#define FRU_ID_MASK 0xFF
#define FRU_A_ID 0x00
#define FRU_B_ID 0x02
diff --git a/usr/src/lib/libfruutils/i386/Makefile b/usr/src/lib/libfruutils/i386/Makefile
new file mode 100644
index 0000000000..ed61d03439
--- /dev/null
+++ b/usr/src/lib/libfruutils/i386/Makefile
@@ -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:
+
diff --git a/usr/src/pkgdefs/Makefile b/usr/src/pkgdefs/Makefile
index a61a50bcd0..31182015ce 100644
--- a/usr/src/pkgdefs/Makefile
+++ b/usr/src/pkgdefs/Makefile
@@ -52,7 +52,6 @@ sparc_SUBDIRS= \
SUNWefc.u \
SUNWefck \
SUNWerid \
- SUNWfruid \
SUNWfruip.u \
SUNWfsr \
SUNWfsu \
@@ -128,6 +127,7 @@ i386_SUBDIRS= \
SUNWgrubS \
SUNWdcopy \
SUNWfipe \
+ SUNWfruip.i \
SUNWipw \
SUNWiwh \
SUNWiwi \
@@ -265,6 +265,7 @@ COMMON_SUBDIRS= \
SUNWfilebench \
SUNWfmd \
SUNWfmdr \
+ SUNWfruid \
SUNWfss \
SUNWftdur \
SUNWftduu \
diff --git a/usr/src/pkgdefs/SUNWfruid/prototype_com b/usr/src/pkgdefs/SUNWfruid/prototype_com
new file mode 100644
index 0000000000..60f6715c98
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWfruid/prototype_com
@@ -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
+
diff --git a/usr/src/pkgdefs/SUNWfruid/prototype_i386 b/usr/src/pkgdefs/SUNWfruid/prototype_i386
new file mode 100644
index 0000000000..1a889a2a0c
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWfruid/prototype_i386
@@ -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
diff --git a/usr/src/pkgdefs/SUNWfruid/prototype_sparc b/usr/src/pkgdefs/SUNWfruid/prototype_sparc
index f70f98dfe1..7c7a480380 100644
--- a/usr/src/pkgdefs/SUNWfruid/prototype_sparc
+++ b/usr/src/pkgdefs/SUNWfruid/prototype_sparc
@@ -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 @@ i depend
#
# 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 @@ f none usr/lib/sparcv9/libfrureg.so.1 755 root bin
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
diff --git a/usr/src/pkgdefs/SUNWfruip.i/Makefile b/usr/src/pkgdefs/SUNWfruip.i/Makefile
new file mode 100644
index 0000000000..0d285de132
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWfruip.i/Makefile
@@ -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
diff --git a/usr/src/pkgdefs/SUNWfruip.i/depend b/usr/src/pkgdefs/SUNWfruip.i/depend
new file mode 100644
index 0000000000..81e04b4ff8
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWfruip.i/depend
@@ -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)
diff --git a/usr/src/pkgdefs/SUNWfruip.i/pkginfo.tmpl b/usr/src/pkgdefs/SUNWfruip.i/pkginfo.tmpl
new file mode 100644
index 0000000000..c0cea59db9
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWfruip.i/pkginfo.tmpl
@@ -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>"
diff --git a/usr/src/pkgdefs/SUNWfruip.i/prototype_i386 b/usr/src/pkgdefs/SUNWfruip.i/prototype_i386
new file mode 100644
index 0000000000..cd48b5b50f
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWfruip.i/prototype_i386
@@ -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