changeset 3895:811da2ad2260

6529553 FRU FMRI incorrect in topo output on x86
author zx143588
date Mon, 26 Mar 2007 10:13:33 -0700
parents 7c0146a89509
children 1d5fb739bf40
files usr/src/lib/fm/topo/modules/Makefile.plugin usr/src/lib/fm/topo/modules/common/pcibus/did.c usr/src/lib/fm/topo/modules/common/pcibus/did.h usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h usr/src/lib/fm/topo/modules/common/pcibus/did_props.c usr/src/lib/fm/topo/modules/common/pcibus/did_props.h usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.c usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.h usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.c usr/src/lib/fm/topo/modules/sun4/pcibus/Makefile.pci usr/src/lib/fm/topo/modules/sun4/pcibus/pci_sun4.c usr/src/lib/fm/topo/modules/sun4/pcibus/pci_sun4.h usr/src/lib/fm/topo/modules/sun4u/pcibus/Makefile usr/src/lib/fm/topo/modules/sun4u/pcibus/pci_sun4u.c usr/src/lib/fm/topo/modules/sun4v/pcibus/Makefile usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.c
diffstat 17 files changed, 348 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/fm/topo/modules/Makefile.plugin	Mon Mar 26 05:47:53 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/Makefile.plugin	Mon Mar 26 10:13:33 2007 -0700
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -64,7 +64,7 @@
 CFLAGS += $(CTF_FLAGS) $(CCVERBOSE) $(XSTRCONST) $(CC_PICFLAGS)
 CFLAGS += -G $(XREGSFLAG)
 
-CPPFLAGS += -I. -I../../../libtopo/common
+CPPFLAGS += -I.
 CPPFLAGS += -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT
 LDFLAGS += $(ZIGNORE) -M$(APIMAP)
 LDLIBS += -L$(ROOTLIBDIR)/fm -R/usr/lib/fm -ltopo -lnvpair -lc
--- a/usr/src/lib/fm/topo/modules/common/pcibus/did.c	Mon Mar 26 05:47:53 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/did.c	Mon Mar 26 10:13:33 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -231,6 +231,7 @@
 	np->dp_mod = mp;
 	np->dp_src = src;
 	np->dp_hash = (did_hash_t *)topo_mod_getspecific(mp);
+	np->dp_tnode = NULL;
 
 	/*
 	 * We must have a reg prop and from it we extract the bus #,
@@ -544,3 +545,16 @@
 	hbdid = (did_t *)data;
 	topo_mod_setspecific(mp, hbdid->dp_hash);
 }
+
+void
+did_settnode(did_t *pd, tnode_t *tn)
+{
+	assert(tn != NULL);
+	pd->dp_tnode = tn;
+}
+
+tnode_t *
+did_gettnode(did_t *pd)
+{
+	return (pd->dp_tnode);
+}
--- a/usr/src/lib/fm/topo/modules/common/pcibus/did.h	Mon Mar 26 05:47:53 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/did.h	Mon Mar 26 10:13:33 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -69,7 +69,8 @@
 extern void did_did_link_set(did_t *, did_t *);
 extern void did_did_chain_set(did_t *, did_t *);
 extern void did_rele(did_t *);
-
+extern void did_settnode(did_t *, tnode_t *);
+extern tnode_t *did_gettnode(did_t *);
 
 #ifdef __cplusplus
 }
--- a/usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h	Mon Mar 26 05:47:53 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h	Mon Mar 26 10:13:33 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -89,6 +89,7 @@
 	 */
 	int dp_nslots;		/* number of slots actually described */
 	slotnm_t *dp_slotnames; /* the slot names as labels */
+	tnode_t *dp_tnode;  /* the parent tnode */
 };
 
 struct did_hash {
--- a/usr/src/lib/fm/topo/modules/common/pcibus/did_props.c	Mon Mar 26 05:47:53 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.c	Mon Mar 26 10:13:33 2007 -0700
@@ -42,7 +42,6 @@
 #include <pcibus.h>
 #include <did.h>
 #include <did_props.h>
-#include "topo_tree.h"
 #include <fm/libtopo.h>
 
 static int ASRU_set(tnode_t *, did_t *,
@@ -411,32 +410,20 @@
 }
 
 /*
- * Hopefully this hack routine goes away when fmdump can print the labels.
+ * Set the FRU property to the hc fmri of this tnode
  */
-static int
-FRU_fmri_hack(topo_mod_t *mp, tnode_t *tn, const char *label)
+int
+FRU_fmri_set(topo_mod_t *mp, tnode_t *tn)
 {
 	nvlist_t *fmri;
 	int err, e;
-	tnode_t *pnode, *cnode = tn;
-	char *plabel;
 
-	pnode = tn->tn_parent;
-	while (pnode != NULL) {
-		if (topo_node_label(pnode, &plabel, &err) < 0)
-			break;
-		if (strcmp(plabel, label) != 0) {
-			topo_mod_strfree(mp, plabel);
-			break;
-		}
-		topo_mod_strfree(mp, plabel);
-		cnode = pnode;
-		pnode = pnode->tn_parent;
+	if (topo_node_resource(tn, &fmri, &err) < 0 ||
+	    fmri == NULL) {
+		topo_mod_dprintf(mp, "FRU_fmri_set error: %s\n",
+			topo_strerror(topo_mod_errno(mp)));
+		return (topo_mod_seterrno(mp, err));
 	}
-
-	if (topo_node_resource(cnode, &fmri, &err) < 0 ||
-	    fmri == NULL)
-		return (topo_mod_seterrno(mp, err));
 	e = topo_node_fru_set(tn, fmri, 0, &err);
 	nvlist_free(fmri);
 	if (e < 0)
@@ -450,12 +437,11 @@
     const char *dpnm, const char *tpgrp, const char *tpnm)
 {
 	topo_mod_t *mp;
-	char *label, *nm;
-	int e;
+	char *nm;
+	int e = 0, err = 0;
 
 	nm = topo_node_name(tn);
 	mp = did_mod(pd);
-
 	/*
 	 * If this topology node represents something other than an
 	 * ioboard or a device that implements a slot, inherit the
@@ -463,22 +449,43 @@
 	 * parent's FRU value.  Otherwise, munge up an fmri based on
 	 * the label.
 	 */
-	if (strcmp(nm, "ioboard") != 0 && strcmp(nm, PCI_DEVICE) != 0 &&
+	if (strcmp(nm, IOBOARD) != 0 && strcmp(nm, PCI_DEVICE) != 0 &&
 	    strcmp(nm, PCIEX_DEVICE) != 0) {
 		(void) topo_node_fru_set(tn, NULL, 0, &e);
 		return (0);
 	}
 
-	if (topo_prop_get_string(tn,
-	    TOPO_PGROUP_PROTOCOL, TOPO_PROP_LABEL, &label, &e) < 0) {
-		if (e != ETOPO_PROP_NOENT)
-			return (topo_mod_seterrno(mp, e));
-		(void) topo_node_fru_set(tn, NULL, 0, &e);
-		return (0);
-	}
-	e = FRU_fmri_hack(mp, tn, label);
-	topo_mod_strfree(mp, label);
-	return (e);
+	/*
+	 * If ioboard, set fru fmri to hc fmri
+	 */
+	if (strcmp(nm, IOBOARD) == 0) {
+		e = FRU_fmri_set(mp, tn);
+		return (e);
+	} else if (strcmp(nm, PCI_DEVICE) == 0 ||
+		strcmp(nm, PCIEX_DEVICE) == 0) {
+		nvlist_t *in, *out;
+
+		mp = did_mod(pd);
+		if (topo_mod_nvalloc(mp, &in, NV_UNIQUE_NAME) != 0)
+			return (topo_mod_seterrno(mp, EMOD_FMRI_NVL));
+		if (nvlist_add_uint64(in, "nv1", (uintptr_t)pd) != 0) {
+			nvlist_free(in);
+			return (topo_mod_seterrno(mp, EMOD_NOMEM));
+		}
+		if (topo_method_invoke(tn,
+			TOPO_METH_FRU_COMPUTE, TOPO_METH_FRU_COMPUTE_VERSION,
+			in, &out, &err) != 0) {
+			nvlist_free(in);
+			return (topo_mod_seterrno(mp, err));
+		}
+		nvlist_free(in);
+		(void) topo_node_fru_set(tn, out, 0, &err);
+		if (out != NULL)
+			nvlist_free(out);
+	} else
+		(void) topo_node_fru_set(tn, NULL, 0, &err);
+
+	return (0);
 }
 
 /*ARGSUSED*/
--- a/usr/src/lib/fm/topo/modules/common/pcibus/did_props.h	Mon Mar 26 05:47:53 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.h	Mon Mar 26 10:13:33 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -79,6 +79,7 @@
 extern int di_uintprop_get(topo_mod_t *, di_node_t, const char *, uint_t *);
 extern int di_bytes_get(topo_mod_t *, di_node_t, const char *, int *,
     uchar_t **);
+extern int FRU_fmri_set(topo_mod_t *, tnode_t *);
 
 #ifdef __cplusplus
 }
--- a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c	Mon Mar 26 05:47:53 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c	Mon Mar 26 10:13:33 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -56,12 +56,15 @@
 
 extern int platform_pci_label(topo_mod_t *mod, tnode_t *, nvlist_t *,
     nvlist_t **);
-
+extern int platform_pci_fru(topo_mod_t *mod, tnode_t *, nvlist_t *,
+    nvlist_t **);
 static void pci_release(topo_mod_t *, tnode_t *);
 static int pci_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
     topo_instance_t, void *, void *);
 static int pci_label(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *,
     nvlist_t **);
+static int pci_fru(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *,
+    nvlist_t **);
 
 static const topo_modops_t Pci_ops =
 	{ pci_enum, pci_release };
@@ -71,6 +74,8 @@
 static const topo_method_t Pci_methods[] = {
 	{ TOPO_METH_LABEL, TOPO_METH_LABEL_DESC,
 	    TOPO_METH_LABEL_VERSION, TOPO_STABILITY_INTERNAL, pci_label },
+	{ TOPO_METH_FRU_COMPUTE, TOPO_METH_FRU_COMPUTE_DESC,
+	    TOPO_METH_FRU_COMPUTE_VERSION, TOPO_STABILITY_INTERNAL, pci_fru },
 	{ NULL }
 };
 
@@ -107,7 +112,14 @@
 		return (topo_mod_seterrno(mp, EMOD_VER_NEW));
 	return (platform_pci_label(mp, node, in, out));
 }
-
+static int
+pci_fru(topo_mod_t *mp, tnode_t *node, topo_version_t version,
+    nvlist_t *in, nvlist_t **out)
+{
+	if (version > TOPO_METH_FRU_COMPUTE_VERSION)
+		return (topo_mod_seterrno(mp, EMOD_VER_NEW));
+	return (platform_pci_fru(mp, node, in, out));
+}
 static tnode_t *
 pci_tnode_create(topo_mod_t *mod, tnode_t *parent,
     const char *name, topo_instance_t i, void *priv)
@@ -181,6 +193,8 @@
 
 	if ((pd = did_find(mod, dn)) == NULL)
 		return (NULL);
+	did_settnode(pd, parent);
+
 	if ((ntn = pci_tnode_create(mod, parent, PCIEX_DEVICE, i, dn)) == NULL)
 		return (NULL);
 	if (did_props_set(ntn, pd, Dev_common_props, Dev_propcnt) < 0) {
@@ -266,6 +280,9 @@
 		return (NULL);
 	if ((pd = did_find(mod, dn)) == NULL)
 		return (NULL);
+	/* remember parent tnode */
+	did_settnode(pd, parent);
+
 	if ((ntn = pci_tnode_create(mod, parent, PCI_DEVICE, i, dn)) == NULL)
 		return (NULL);
 	/*
@@ -273,6 +290,7 @@
 	 * own, we may need/want to inherit the information available
 	 * from our parent node's private data.
 	 */
+
 	did_inherit(ppd, pd);
 	if (did_props_set(ntn, pd, Dev_common_props, Dev_propcnt) < 0) {
 		topo_node_unbind(ntn);
@@ -478,8 +496,9 @@
 		return (0);
 	}
 	did_hash_init(mp);
-	if (did_create(mp, pdn, 0, 0, rc, TRUST_BDF) == NULL)
+	if ((did_create(mp, pdn, 0, 0, rc, TRUST_BDF)) == NULL)
 		return (-1);	/* errno already set */
+
 	retval = pci_children_instantiate(mp, ptn, pdn, 0, 0, rc,
 	    (min == max) ? min : TRUST_BDF, 0);
 	did_hash_fini(mp);
--- a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.c	Mon Mar 26 05:47:53 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.c	Mon Mar 26 10:13:33 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -131,7 +131,7 @@
 	return (rlabel);
 }
 
-static const char *
+const char *
 pci_slotname_lookup(topo_mod_t *mod, tnode_t *node, did_t *dp)
 {
 	const char *l;
--- a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.h	Mon Mar 26 05:47:53 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.h	Mon Mar 26 10:13:33 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -30,6 +30,7 @@
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #include <hostbridge.h>
+#include <did.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -102,6 +103,8 @@
 } missing_names_t;
 
 extern int pci_label_cmn(topo_mod_t *mod, tnode_t *, nvlist_t *, nvlist_t **);
+extern const char *
+pci_slotname_lookup(topo_mod_t *, tnode_t *, did_t *);
 
 #ifdef __cplusplus
 }
--- a/usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.c	Mon Mar 26 05:47:53 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.c	Mon Mar 26 10:13:33 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -30,6 +30,8 @@
 
 #include "pcibus.h"
 #include "pcibus_labels.h"
+#include <string.h>
+#include <strings.h>
 
 slotnm_rewrite_t *Slot_Rewrites = NULL;
 physlot_names_t *Physlot_Names = NULL;
@@ -41,3 +43,34 @@
 {
 	return (pci_label_cmn(mod, node, in, out));
 }
+/*ARGSUSED*/
+int
+platform_pci_fru(topo_mod_t *mod, tnode_t *node, nvlist_t *in,
+    nvlist_t **out)
+{
+	char *nm, *label;
+	char buf[PATH_MAX];
+	nvlist_t *fmri;
+	int e;
+
+	*out = NULL;
+	nm = topo_node_name(node);
+	if (strcmp(nm, PCI_DEVICE) != 0 && strcmp(nm, PCIEX_DEVICE) != 0 &&
+	    strcmp(nm, PCIEX_BUS) != 0)
+		return (0);
+
+	if (topo_prop_get_string(node,
+		TOPO_PGROUP_PROTOCOL, TOPO_PROP_LABEL, &label, &e) < 0) {
+		if (e != ETOPO_PROP_NOENT)
+			return (topo_mod_seterrno(mod, e));
+		return (0);
+	}
+
+	(void) snprintf(buf, PATH_MAX, "hc:///component=%s", label);
+	topo_mod_strfree(mod, label);
+	if (topo_mod_str2nvl(mod, buf, &fmri) < 0)
+		return (-1);
+
+	*out = fmri;
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/sun4/pcibus/Makefile.pci	Mon Mar 26 10:13:33 2007 -0700
@@ -0,0 +1,55 @@
+#
+# 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 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+
+MODULE = pcibus
+CLASS = arch
+SUN4DIR = ../../sun4/$(MODULE)
+UTILDIR = ../../common/pcibus
+HBDIR = ../../common/hostbridge
+UTILSRCS = did.c did_hash.c did_props.c util.c
+PCISRCS = pcibus.c pcibus_labels.c pci_sun4.c
+
+MODULESRCS = $(PCISRCS) $(UTILSRCS) pci_$(ARCH).c
+
+include ../../Makefile.plugin
+
+LDLIBS += -ldevinfo
+CPPFLAGS += -I$(SUN4DIR) -I$(UTILDIR) -I$(HBDIR)
+
+%.o: $(SUN4DIR)/%.c
+	$(COMPILE.c) -o $@ $<
+	$(CTFCONVERT_O)
+
+%.o: $(UTILDIR)/%.c
+	$(COMPILE.c) -o $@ $<
+	$(CTFCONVERT_O)
+
+%.ln: $(SUN4DIR)/%.c
+	$(LINT.c) -c $<
+
+%.ln: $(UTILDIR)/%.c
+	$(LINT.c) -c $<
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/sun4/pcibus/pci_sun4.c	Mon Mar 26 10:13:33 2007 -0700
@@ -0,0 +1,94 @@
+/*
+ * 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 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <string.h>
+#include <fm/topo_mod.h>
+#include <libnvpair.h>
+#include <util.h>
+#include <pcibus.h>
+#include <did.h>
+#include <pcibus_labels.h>
+
+int
+pci_fru_compute(topo_mod_t *mod, tnode_t *node, nvlist_t *in, nvlist_t **out)
+{
+	char *nm;
+	uint64_t ptr;
+	did_t *dp;
+	const char *l;
+	char *plabel;
+	tnode_t *pn;
+	int err;
+	nvlist_t *fmri = NULL;
+
+	*out = NULL;
+	nm = topo_node_name(node);
+	if (strcmp(nm, PCI_DEVICE) != 0 && strcmp(nm, PCIEX_DEVICE) != 0 &&
+	    strcmp(nm, PCIEX_BUS) != 0)
+		return (0);
+
+	if (nvlist_lookup_uint64(in, "nv1", &ptr) != 0) {
+		topo_mod_dprintf(mod,
+		    "label method argument not found.\n");
+		return (-1);
+	}
+	dp = (did_t *)(uintptr_t)ptr;
+
+	if (topo_node_resource(node, &fmri, &err) < 0 ||
+	    fmri == NULL) {
+		topo_mod_dprintf(mod, "pci_fru_compute error: %s\n",
+			topo_strerror(topo_mod_errno(mod)));
+		return (topo_mod_seterrno(mod, err));
+	}
+
+	/*
+	 * Is there a slotname associated with the device?
+	 */
+	if ((l = pci_slotname_lookup(mod, node, dp)) != NULL) {
+		/*
+		 * Get parent label. If l is the same as parent label,
+		 * inherit parent's FRU property.
+		 */
+		pn = did_gettnode(dp);
+		if (pn != NULL &&
+		    (topo_prop_get_string(pn,
+			TOPO_PGROUP_PROTOCOL,
+			TOPO_PROP_LABEL, &plabel, &err) == 0)) {
+			if (strcmp(plabel, l) == 0) {
+				topo_mod_strfree(mod, plabel);
+				nvlist_free(fmri);
+				return (0);
+			}
+			topo_mod_strfree(mod, plabel);
+		}
+		*out = fmri;
+	} else
+		nvlist_free(fmri);
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/sun4/pcibus/pci_sun4.h	Mon Mar 26 10:13:33 2007 -0700
@@ -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 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _HB_SUN4_H
+#define	_HB_SUN4_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <fm/topo_mod.h>
+#include <libnvpair.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int
+pci_fru_compute(topo_mod_t *mod, tnode_t *node, nvlist_t *in, nvlist_t **out);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _HB_SUN4_H */
--- a/usr/src/lib/fm/topo/modules/sun4u/pcibus/Makefile	Mon Mar 26 05:47:53 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/sun4u/pcibus/Makefile	Mon Mar 26 10:13:33 2007 -0700
@@ -20,24 +20,11 @@
 #
 
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
 #
+ARCH = sun4u
+include ../../sun4/pcibus/Makefile.pci
 
-MODULE = pcibus
-ARCH = sun4u
-CLASS = arch
-UTILDIR = ../../common/pcibus
-HBDIR = ../../common/hostbridge
-UTILSRCS = did.c did_hash.c did_props.c util.c
-PCISRCS = pcibus.c pcibus_labels.c
-
-MODULESRCS = $(UTILSRCS) $(PCISRCS) pci_sun4u.c
-
-include ../../Makefile.plugin
-
-LDLIBS += -ldevinfo
-
-CPPFLAGS += -I$(UTILDIR) -I$(HBDIR)
--- a/usr/src/lib/fm/topo/modules/sun4u/pcibus/pci_sun4u.c	Mon Mar 26 05:47:53 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/sun4u/pcibus/pci_sun4u.c	Mon Mar 26 10:13:33 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -36,9 +36,17 @@
  */
 #include "pci_sun4u.h"
 
+#include "pci_sun4.h"
+
 int
 platform_pci_label(topo_mod_t *mod, tnode_t *node, nvlist_t *in,
     nvlist_t **out)
 {
 	return (pci_label_cmn(mod, node, in, out));
 }
+int
+platform_pci_fru(topo_mod_t *mod, tnode_t *node, nvlist_t *in,
+    nvlist_t **out)
+{
+	return (pci_fru_compute(mod, node, in, out));
+}
--- a/usr/src/lib/fm/topo/modules/sun4v/pcibus/Makefile	Mon Mar 26 05:47:53 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/sun4v/pcibus/Makefile	Mon Mar 26 10:13:33 2007 -0700
@@ -20,24 +20,12 @@
 #
 
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
 #
 
-MODULE = pcibus
 ARCH = sun4v
-CLASS = arch
-UTILDIR = ../../common/pcibus
-HBDIR = ../../common/hostbridge
-UTILSRCS = did.c did_hash.c did_props.c util.c
-PCISRCS = pcibus.c pcibus_labels.c
+include ../../sun4/pcibus/Makefile.pci
 
-MODULESRCS = $(UTILSRCS) $(PCISRCS) pci_sun4v.c
-
-include ../../Makefile.plugin
-
-LDLIBS += -ldevinfo
-
-CPPFLAGS += -I$(UTILDIR) -I$(HBDIR)
--- a/usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.c	Mon Mar 26 05:47:53 2007 -0700
+++ b/usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.c	Mon Mar 26 10:13:33 2007 -0700
@@ -20,14 +20,13 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #include <fm/topo_mod.h>
-
 /*
  * Including the following file gives us definitions of the three
  * global arrays used to adjust labels, Slot_Rewrites, Physlot_Names,
@@ -36,9 +35,18 @@
  */
 #include "pci_sun4v.h"
 
+#include "pci_sun4.h"
+
 int
 platform_pci_label(topo_mod_t *mod, tnode_t *node, nvlist_t *in,
     nvlist_t **out)
 {
 	return (pci_label_cmn(mod, node, in, out));
 }
+int
+platform_pci_fru(topo_mod_t *mod, tnode_t *node, nvlist_t *in,
+    nvlist_t **out)
+{
+	topo_mod_dprintf(mod, "entering platform_pci_fru\n");
+	return (pci_fru_compute(mod, node, in, out));
+}