17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate  * PICL plug-in that creates the FRU Hierarchy for the
297c478bd9Sstevel@tonic-gate  * SUNW,Sun-Fire-880 (Daktari) platform
307c478bd9Sstevel@tonic-gate  */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <stdio.h>
337c478bd9Sstevel@tonic-gate #include <string.h>
347c478bd9Sstevel@tonic-gate #include <libintl.h>
357c478bd9Sstevel@tonic-gate #include <libnvpair.h>
367c478bd9Sstevel@tonic-gate #include <syslog.h>
377c478bd9Sstevel@tonic-gate #include <picl.h>
387c478bd9Sstevel@tonic-gate #include <picltree.h>
397c478bd9Sstevel@tonic-gate #include <picldefs.h>
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * Plugin registration entry points
437c478bd9Sstevel@tonic-gate  */
447c478bd9Sstevel@tonic-gate static void	picl_frutree_register(void);
457c478bd9Sstevel@tonic-gate static void	picl_frutree_init(void);
467c478bd9Sstevel@tonic-gate static void	picl_frutree_fini(void);
477c478bd9Sstevel@tonic-gate static void	picl_frutree_evhandler(const char *ename, const void *earg,
487c478bd9Sstevel@tonic-gate 		    size_t size, void *cookie);
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate #pragma	init(picl_frutree_register)
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate /*
537c478bd9Sstevel@tonic-gate  * Log message texts
547c478bd9Sstevel@tonic-gate  */
557c478bd9Sstevel@tonic-gate #define	CREATE_FRUTREE_FAIL	gettext("Failed to create frutree node\n")
567c478bd9Sstevel@tonic-gate #define	CREATE_CHASSIS_FAIL	gettext("Failed to create chassis node\n")
577c478bd9Sstevel@tonic-gate #define	IOBRD_INIT_FAIL		gettext("do_ioboard_init() failed\n")
587c478bd9Sstevel@tonic-gate #define	RSCBRD_INIT_FAIL	gettext("do_rscboard_init() failed\n")
597c478bd9Sstevel@tonic-gate #define	FCAL_INIT_FAIL		gettext("do_fcal_init() failed\n")
607c478bd9Sstevel@tonic-gate #define	PS_INIT_FAIL		gettext("do_power_supplies_init() failed\n")
617c478bd9Sstevel@tonic-gate #define	SYSBOARD_INIT_FAIL	gettext("do_motherboard_init() failed\n")
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate /*
647c478bd9Sstevel@tonic-gate  * Viewpoints property field used by SunMC
657c478bd9Sstevel@tonic-gate  */
667c478bd9Sstevel@tonic-gate #define	CHASSIS_VIEWPOINTS	gettext("front left right rear")
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate /*
697c478bd9Sstevel@tonic-gate  * Ref prop values
707c478bd9Sstevel@tonic-gate  */
717c478bd9Sstevel@tonic-gate #define	SEEPROM_SOURCE		"_seeprom_source"
727c478bd9Sstevel@tonic-gate #define	FRU_PARENT		"_fru_parent"
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate /*
757c478bd9Sstevel@tonic-gate  * List of all the FRU locations in the platform_frupath[] array, and
767c478bd9Sstevel@tonic-gate  * location_label[] array
777c478bd9Sstevel@tonic-gate  */
787c478bd9Sstevel@tonic-gate #define	IOBRD		0
797c478bd9Sstevel@tonic-gate #define	RSC		1
807c478bd9Sstevel@tonic-gate #define	FCAL0		2
817c478bd9Sstevel@tonic-gate #define	FCAL1		3
827c478bd9Sstevel@tonic-gate #define	FCALGBIC	4
837c478bd9Sstevel@tonic-gate #define	PDB		5
847c478bd9Sstevel@tonic-gate #define	PS0		6
857c478bd9Sstevel@tonic-gate #define	PS1		7
867c478bd9Sstevel@tonic-gate #define	PS2		8
877c478bd9Sstevel@tonic-gate #define	SYSBRD		9
887c478bd9Sstevel@tonic-gate #define	CPUMOD0		10
897c478bd9Sstevel@tonic-gate #define	CPUMOD1		11
907c478bd9Sstevel@tonic-gate #define	CPUMOD2		12
917c478bd9Sstevel@tonic-gate #define	CPUMOD3		13
927c478bd9Sstevel@tonic-gate #define	CPU0_DIMM0	14
937c478bd9Sstevel@tonic-gate #define	DIMMS_PER_MOD	8
947c478bd9Sstevel@tonic-gate #define	DIMMS_PER_SLOT	16
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate /*
987c478bd9Sstevel@tonic-gate  * Local variables
997c478bd9Sstevel@tonic-gate  */
1007c478bd9Sstevel@tonic-gate static picld_plugin_reg_t  my_reg_info = {
1017c478bd9Sstevel@tonic-gate 	PICLD_PLUGIN_VERSION_1,
1027c478bd9Sstevel@tonic-gate 	PICLD_PLUGIN_NON_CRITICAL,
1037c478bd9Sstevel@tonic-gate 	"SUNW_Sun-Fire-880_frutree",
1047c478bd9Sstevel@tonic-gate 	picl_frutree_init,
1057c478bd9Sstevel@tonic-gate 	picl_frutree_fini
1067c478bd9Sstevel@tonic-gate };
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate /*
1097c478bd9Sstevel@tonic-gate  * List of all the FRUs in the /platform tree with SEEPROMs
1107c478bd9Sstevel@tonic-gate  */
1117c478bd9Sstevel@tonic-gate static char *platform_frupath[] = {
1127c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@4,aa", /* IO */
1137c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,a6", /* RSC */
1147c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,a8", /* FCAL 0 */
1157c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,ac", /* FCAL 1 */
1167c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,aa", /* FCAL-GBIC */
1177c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,ae", /* PDB */
1187c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,a0", /* PS 0 */
1197c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,a2", /* PS 1 */
1207c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,a4", /* PS 2 */
1217c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@4,a8", /* SYS BRD */
1227c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@4,a0", /* CPU MOD 0 */
1237c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@4,a2", /* CPU MOD 1 */
1247c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@4,a4", /* CPU MOD 2 */
1257c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@4,a6", /* CPU MOD 3 */
1267c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a0", /* CPU0 DIMM0 */
1277c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a2", /* CPU0 DIMM1 */
1287c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a4", /* CPU0 DIMM2 */
1297c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a6", /* CPU0 DIMM3 */
1307c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a8", /* CPU0 DIMM4 */
1317c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,aa", /* CPU0 DIMM5 */
1327c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,ac", /* CPU0 DIMM6 */
1337c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,ae", /* CPU0 DIMM7 */
1347c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a0", /* CPU2 DIMM0 */
1357c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a2", /* CPU2 DIMM1 */
1367c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a4", /* CPU2 DIMM2 */
1377c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a6", /* CPU2 DIMM3 */
1387c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a8", /* CPU2 DIMM4 */
1397c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,aa", /* CPU2 DIMM5 */
1407c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,ac", /* CPU2 DIMM6 */
1417c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,ae", /* CPU2 DIMM7 */
1427c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a0", /* CPU1 DIMM0 */
1437c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a2", /* CPU1 DIMM1 */
1447c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a4", /* CPU1 DIMM2 */
1457c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a6", /* CPU1 DIMM3 */
1467c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a8", /* CPU1 DIMM4 */
1477c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,aa", /* CPU1 DIMM5 */
1487c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,ac", /* CPU1 DIMM6 */
1497c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,ae", /* CPU1 DIMM7 */
1507c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a0", /* CPU3 DIMM0 */
1517c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a2", /* CPU3 DIMM1 */
1527c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a4", /* CPU3 DIMM2 */
1537c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a6", /* CPU3 DIMM3 */
1547c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a8", /* CPU3 DIMM4 */
1557c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,aa", /* CPU3 DIMM5 */
1567c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,ac", /* CPU3 DIMM6 */
1577c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,ae", /* CPU3 DIMM7 */
1587c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,a0", /* CPU4 DIMM0 */
1597c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,a2", /* CPU4 DIMM1 */
1607c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,a4", /* CPU4 DIMM2 */
1617c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,a6", /* CPU4 DIMM3 */
1627c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,a8", /* CPU4 DIMM4 */
1637c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,aa", /* CPU4 DIMM5 */
1647c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,ac", /* CPU4 DIMM6 */
1657c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,ae", /* CPU4 DIMM7 */
1667c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,a0", /* CPU6 DIMM0 */
1677c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,a2", /* CPU6 DIMM1 */
1687c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,a4", /* CPU6 DIMM2 */
1697c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,a6", /* CPU6 DIMM3 */
1707c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,a8", /* CPU6 DIMM4 */
1717c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,aa", /* CPU6 DIMM5 */
1727c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,ac", /* CPU6 DIMM6 */
1737c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,ae", /* CPU6 DIMM7 */
1747c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,a0", /* CPU5 DIMM0 */
1757c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,a2", /* CPU5 DIMM1 */
1767c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,a4", /* CPU5 DIMM2 */
1777c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,a6", /* CPU5 DIMM3 */
1787c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,a8", /* CPU5 DIMM4 */
1797c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,aa", /* CPU5 DIMM5 */
1807c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,ac", /* CPU5 DIMM6 */
1817c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,ae", /* CPU5 DIMM7 */
1827c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,a0", /* CPU7 DIMM0 */
1837c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,a2", /* CPU7 DIMM1 */
1847c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,a4", /* CPU7 DIMM2 */
1857c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,a6", /* CPU7 DIMM3 */
1867c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,a8", /* CPU7 DIMM4 */
1877c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,aa", /* CPU7 DIMM5 */
1887c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,ac", /* CPU7 DIMM6 */
1897c478bd9Sstevel@tonic-gate 	"/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,ae", /* CPU7 DIMM7 */
1907c478bd9Sstevel@tonic-gate 	NULL};
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate /*
1937c478bd9Sstevel@tonic-gate  * List of Labels for FRU locations (uses the #define's from above)
1947c478bd9Sstevel@tonic-gate  */
1957c478bd9Sstevel@tonic-gate static char *location_label[] = {
1967c478bd9Sstevel@tonic-gate 	NULL,			/* IOBRD */
1977c478bd9Sstevel@tonic-gate 	NULL,			/* RSC */
1987c478bd9Sstevel@tonic-gate 	"0",			/* FCAL0 */
1997c478bd9Sstevel@tonic-gate 	"1",			/* FCAL1 */
2007c478bd9Sstevel@tonic-gate 	NULL,			/* FCALGBIC */
2017c478bd9Sstevel@tonic-gate 	NULL,			/* PDB */
2027c478bd9Sstevel@tonic-gate 	"0",			/* PS0 */
2037c478bd9Sstevel@tonic-gate 	"1",			/* PS1 */
2047c478bd9Sstevel@tonic-gate 	"2",			/* PS2 */
2057c478bd9Sstevel@tonic-gate 	NULL,			/* SYSBRD */
2067c478bd9Sstevel@tonic-gate 	"A",			/* CPUMOD0 */
2077c478bd9Sstevel@tonic-gate 	"B",			/* CPUMOD1 */
2087c478bd9Sstevel@tonic-gate 	"C",			/* CPUMOD2 */
2097c478bd9Sstevel@tonic-gate 	"D",			/* CPUMOD3 */
2107c478bd9Sstevel@tonic-gate 	"J2900",		/* CPU0 DIMM0 */
2117c478bd9Sstevel@tonic-gate 	"J3100",		/* CPU0 DIMM1 */
2127c478bd9Sstevel@tonic-gate 	"J2901",		/* CPU0 DIMM2 */
2137c478bd9Sstevel@tonic-gate 	"J3101",		/* CPU0 DIMM3 */
2147c478bd9Sstevel@tonic-gate 	"J3000",		/* CPU0 DIMM4 */
2157c478bd9Sstevel@tonic-gate 	"J3200",		/* CPU0 DIMM5 */
2167c478bd9Sstevel@tonic-gate 	"J3001",		/* CPU0 DIMM6 */
2177c478bd9Sstevel@tonic-gate 	"J3201",		/* CPU0 DIMM7 */
2187c478bd9Sstevel@tonic-gate 	"J7900",		/* CPU1 DIMM0 */
2197c478bd9Sstevel@tonic-gate 	"J8100",		/* CPU1 DIMM1 */
2207c478bd9Sstevel@tonic-gate 	"J7901",		/* CPU1 DIMM2 */
2217c478bd9Sstevel@tonic-gate 	"J8101",		/* CPU1 DIMM3 */
2227c478bd9Sstevel@tonic-gate 	"J8000",		/* CPU1 DIMM4 */
2237c478bd9Sstevel@tonic-gate 	"J8200",		/* CPU1 DIMM5 */
2247c478bd9Sstevel@tonic-gate 	"J8001",		/* CPU1 DIMM6 */
2257c478bd9Sstevel@tonic-gate 	"J8201",		/* CPU1 DIMM7 */
2267c478bd9Sstevel@tonic-gate 	"0",			/* CPU0 label */
2277c478bd9Sstevel@tonic-gate 	"1",			/* CPU1 label */
2287c478bd9Sstevel@tonic-gate 	NULL};
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate /*
2317c478bd9Sstevel@tonic-gate  * List of all the FRU slots for power supplies (hotpluggable)
2327c478bd9Sstevel@tonic-gate  */
2337c478bd9Sstevel@tonic-gate static char *frutree_power_supply[] = {
2347c478bd9Sstevel@tonic-gate 	"/frutree/chassis/power-dist-board/power-supply-slot?Slot=0",
2357c478bd9Sstevel@tonic-gate 	"/frutree/chassis/power-dist-board/power-supply-slot?Slot=1",
2367c478bd9Sstevel@tonic-gate 	"/frutree/chassis/power-dist-board/power-supply-slot?Slot=2",
2377c478bd9Sstevel@tonic-gate 	NULL};
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate /*
2407c478bd9Sstevel@tonic-gate  * List of all the FRU slots for CPU Memory modules (hotpluggable)
2417c478bd9Sstevel@tonic-gate  */
2427c478bd9Sstevel@tonic-gate static char *frutree_cpu_module[] = {
2437c478bd9Sstevel@tonic-gate 	"/frutree/chassis/system-board/cpu-mem-slot?Slot=0",
2447c478bd9Sstevel@tonic-gate 	"/frutree/chassis/system-board/cpu-mem-slot?Slot=1",
2457c478bd9Sstevel@tonic-gate 	"/frutree/chassis/system-board/cpu-mem-slot?Slot=2",
2467c478bd9Sstevel@tonic-gate 	"/frutree/chassis/system-board/cpu-mem-slot?Slot=3",
2477c478bd9Sstevel@tonic-gate 	NULL};
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate /* PICL handle for the root node of the "frutree" */
2507c478bd9Sstevel@tonic-gate static picl_nodehdl_t	frutreeh;
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate static int	do_ioboard_init(picl_nodehdl_t);
2537c478bd9Sstevel@tonic-gate static int	do_rscboard_init(picl_nodehdl_t);
2547c478bd9Sstevel@tonic-gate static int	do_fcal_init(picl_nodehdl_t);
2557c478bd9Sstevel@tonic-gate static int	do_power_supplies_init(picl_nodehdl_t);
2567c478bd9Sstevel@tonic-gate static int	do_motherboard_init(picl_nodehdl_t);
2577c478bd9Sstevel@tonic-gate static int	do_cpu_module_init(picl_nodehdl_t, int);
2587c478bd9Sstevel@tonic-gate static int	do_dimms_init(picl_nodehdl_t, int, int);
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate static int	add_ref_prop(picl_nodehdl_t, picl_nodehdl_t, char *);
2617c478bd9Sstevel@tonic-gate static int	add_slot_prop(picl_nodehdl_t, int);
2627c478bd9Sstevel@tonic-gate static int	add_label_prop(picl_nodehdl_t, char *);
2637c478bd9Sstevel@tonic-gate static int	add_void_fda_prop(picl_nodehdl_t);
2647c478bd9Sstevel@tonic-gate static int	add_viewpoints_prop(picl_nodehdl_t, char *);
2657c478bd9Sstevel@tonic-gate static int	add_all_nodes();
2667c478bd9Sstevel@tonic-gate static int	remove_all_nodes(picl_nodehdl_t);
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate static int	add_hotplug_fru_device(void);
2697c478bd9Sstevel@tonic-gate static int	rem_hotplug_fru_device(void);
2707c478bd9Sstevel@tonic-gate static int	is_added_device(char *, char *);
2717c478bd9Sstevel@tonic-gate static int	is_removed_device(char *, char *);
2727c478bd9Sstevel@tonic-gate static int	add_power_supply(int);
2737c478bd9Sstevel@tonic-gate static int	remove_power_supply(int);
2747c478bd9Sstevel@tonic-gate static int	add_cpu_module(int);
2757c478bd9Sstevel@tonic-gate static int	remove_cpu_module(int);
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate /*
2787c478bd9Sstevel@tonic-gate  * This function is executed as part of .init when the plugin is
2797c478bd9Sstevel@tonic-gate  * dlopen()ed
2807c478bd9Sstevel@tonic-gate  */
2817c478bd9Sstevel@tonic-gate static void
picl_frutree_register()2827c478bd9Sstevel@tonic-gate picl_frutree_register()
2837c478bd9Sstevel@tonic-gate {
2847c478bd9Sstevel@tonic-gate 	(void) picld_plugin_register(&my_reg_info);
2857c478bd9Sstevel@tonic-gate }
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate /*
2887c478bd9Sstevel@tonic-gate  * This function is the init entry point of the plugin.
2897c478bd9Sstevel@tonic-gate  * It initializes the /frutree tree
2907c478bd9Sstevel@tonic-gate  */
2917c478bd9Sstevel@tonic-gate static void
picl_frutree_init()2927c478bd9Sstevel@tonic-gate picl_frutree_init()
2937c478bd9Sstevel@tonic-gate {
2947c478bd9Sstevel@tonic-gate 	int		err;
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	err = add_all_nodes();
2977c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
2987c478bd9Sstevel@tonic-gate 		(void) remove_all_nodes(frutreeh);
2997c478bd9Sstevel@tonic-gate 		return;
3007c478bd9Sstevel@tonic-gate 	}
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 	/* Register the event handler routine */
3037c478bd9Sstevel@tonic-gate 	(void) ptree_register_handler(PICLEVENT_SYSEVENT_DEVICE_ADDED,
3047c478bd9Sstevel@tonic-gate 	    picl_frutree_evhandler, NULL);
3057c478bd9Sstevel@tonic-gate 	(void) ptree_register_handler(PICLEVENT_SYSEVENT_DEVICE_REMOVED,
3067c478bd9Sstevel@tonic-gate 	    picl_frutree_evhandler, NULL);
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate /*
3107c478bd9Sstevel@tonic-gate  * This function is the fini entry point of the plugin
3117c478bd9Sstevel@tonic-gate  */
3127c478bd9Sstevel@tonic-gate static void
picl_frutree_fini(void)3137c478bd9Sstevel@tonic-gate picl_frutree_fini(void)
3147c478bd9Sstevel@tonic-gate {
3157c478bd9Sstevel@tonic-gate 	/* Unregister the event handler routine */
3167c478bd9Sstevel@tonic-gate 	(void) ptree_unregister_handler(PICLEVENT_SYSEVENT_DEVICE_ADDED,
3177c478bd9Sstevel@tonic-gate 	    picl_frutree_evhandler, NULL);
3187c478bd9Sstevel@tonic-gate 	(void) ptree_unregister_handler(PICLEVENT_SYSEVENT_DEVICE_REMOVED,
3197c478bd9Sstevel@tonic-gate 	    picl_frutree_evhandler, NULL);
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 	(void) remove_all_nodes(frutreeh);
3227c478bd9Sstevel@tonic-gate }
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate /*
3257c478bd9Sstevel@tonic-gate  * This function is the event handler of this plug-in.
3267c478bd9Sstevel@tonic-gate  *
3277c478bd9Sstevel@tonic-gate  * It processes the following events:
3287c478bd9Sstevel@tonic-gate  *
329*ada2da53SToomas Soome  *	PICLEVENT_SYSEVENT_DEVICE_ADDED
330*ada2da53SToomas Soome  *	PICLEVENT_SYSEVENT_DEVICE_REMOVED
3317c478bd9Sstevel@tonic-gate  */
3327c478bd9Sstevel@tonic-gate /* ARGSUSED */
3337c478bd9Sstevel@tonic-gate static void
picl_frutree_evhandler(const char * ename,const void * earg,size_t size,void * cookie)3347c478bd9Sstevel@tonic-gate picl_frutree_evhandler(const char *ename, const void *earg, size_t size,
3357c478bd9Sstevel@tonic-gate     void *cookie)
3367c478bd9Sstevel@tonic-gate {
3377c478bd9Sstevel@tonic-gate 	if (strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_ADDED) == 0) {
3387c478bd9Sstevel@tonic-gate 		/* Check for and add any hotplugged device(s) */
3397c478bd9Sstevel@tonic-gate 		(void) add_hotplug_fru_device();
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 	} else if (strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_REMOVED) == 0) {
3427c478bd9Sstevel@tonic-gate 		/* Check for and remove any hotplugged device(s) */
3437c478bd9Sstevel@tonic-gate 		(void) rem_hotplug_fru_device();
3447c478bd9Sstevel@tonic-gate 	}
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate /* Initializes the FRU nodes for the IO board */
3487c478bd9Sstevel@tonic-gate static int
do_ioboard_init(picl_nodehdl_t rooth)3497c478bd9Sstevel@tonic-gate do_ioboard_init(picl_nodehdl_t rooth)
3507c478bd9Sstevel@tonic-gate {
3517c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		iobrdh;
3527c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
3537c478bd9Sstevel@tonic-gate 	int			err;
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 	/* Create the node for the IO board (if it exists) */
3567c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(platform_frupath[IOBRD], &tmph) ==
3577c478bd9Sstevel@tonic-gate 	    PICL_SUCCESS) {
3587c478bd9Sstevel@tonic-gate 		err = ptree_create_node("io-board", "fru", &iobrdh);
3597c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
3607c478bd9Sstevel@tonic-gate 			return (err);
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 		err = add_ref_prop(iobrdh, tmph, SEEPROM_SOURCE);
3637c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
3647c478bd9Sstevel@tonic-gate 			return (err);
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate 		err = add_void_fda_prop(iobrdh);
3677c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
3687c478bd9Sstevel@tonic-gate 			return (err);
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate 		err = ptree_add_node(rooth, iobrdh);
3717c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
3727c478bd9Sstevel@tonic-gate 			return (err);
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate 		err = add_ref_prop(tmph, iobrdh, FRU_PARENT);
3757c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
3767c478bd9Sstevel@tonic-gate 			return (err);
3777c478bd9Sstevel@tonic-gate 	}
3787c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
3797c478bd9Sstevel@tonic-gate }
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate /* Initializes the FRU node for the RSC card */
3827c478bd9Sstevel@tonic-gate static int
do_rscboard_init(picl_nodehdl_t rooth)3837c478bd9Sstevel@tonic-gate do_rscboard_init(picl_nodehdl_t rooth)
3847c478bd9Sstevel@tonic-gate {
3857c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		rscbrdh;
3867c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
3877c478bd9Sstevel@tonic-gate 	int			err;
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate 	/* Create the node for the RSC board (if it exists) */
3907c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(platform_frupath[RSC], &tmph) ==
3917c478bd9Sstevel@tonic-gate 	    PICL_SUCCESS) {
3927c478bd9Sstevel@tonic-gate 		err = ptree_create_node("rsc-board", "fru", &rscbrdh);
3937c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
3947c478bd9Sstevel@tonic-gate 			return (err);
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate 		err = add_ref_prop(rscbrdh, tmph, SEEPROM_SOURCE);
3977c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
3987c478bd9Sstevel@tonic-gate 			return (err);
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 		err = add_void_fda_prop(rscbrdh);
4017c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4027c478bd9Sstevel@tonic-gate 			return (err);
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate 		err = ptree_add_node(rooth, rscbrdh);
4057c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4067c478bd9Sstevel@tonic-gate 			return (err);
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate 		err = add_ref_prop(tmph, rscbrdh, FRU_PARENT);
4097c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4107c478bd9Sstevel@tonic-gate 			return (err);
4117c478bd9Sstevel@tonic-gate 	}
4127c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
4137c478bd9Sstevel@tonic-gate }
4147c478bd9Sstevel@tonic-gate 
4157c478bd9Sstevel@tonic-gate /* Initializes the FRU nodes for the FCAL backplanes and GBIC card */
4167c478bd9Sstevel@tonic-gate static int
do_fcal_init(picl_nodehdl_t rooth)4177c478bd9Sstevel@tonic-gate do_fcal_init(picl_nodehdl_t rooth)
4187c478bd9Sstevel@tonic-gate {
4197c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		fcalsloth;
4207c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		fcalmodh;
4217c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		fcalgbich;
4227c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
4237c478bd9Sstevel@tonic-gate 	int			i, err, slotnum;
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate 	for (i = FCAL0; i <= FCAL1; i++) {
4267c478bd9Sstevel@tonic-gate 		/* Create the node for the FCAL backplane slot */
4277c478bd9Sstevel@tonic-gate 		err = ptree_create_node("fcal-backplane-slot",
4287c478bd9Sstevel@tonic-gate 		    "location", &fcalsloth);
4297c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4307c478bd9Sstevel@tonic-gate 			return (err);
4317c478bd9Sstevel@tonic-gate 
4327c478bd9Sstevel@tonic-gate 		slotnum = i - FCAL0;
4337c478bd9Sstevel@tonic-gate 		err = add_slot_prop(fcalsloth, slotnum);
4347c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4357c478bd9Sstevel@tonic-gate 			return (err);
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate 		err = add_label_prop(fcalsloth, location_label[i]);
4387c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4397c478bd9Sstevel@tonic-gate 			return (err);
4407c478bd9Sstevel@tonic-gate 
4417c478bd9Sstevel@tonic-gate 		err = ptree_add_node(rooth, fcalsloth);
4427c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4437c478bd9Sstevel@tonic-gate 			return (err);
4447c478bd9Sstevel@tonic-gate 
4457c478bd9Sstevel@tonic-gate 		/* If the FCAL backplane exists, create a node for it */
4467c478bd9Sstevel@tonic-gate 		if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
4477c478bd9Sstevel@tonic-gate 		    PICL_SUCCESS) {
4487c478bd9Sstevel@tonic-gate 			err = ptree_create_node("fcal-backplane", "fru",
4497c478bd9Sstevel@tonic-gate 			    &fcalmodh);
4507c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
4517c478bd9Sstevel@tonic-gate 				return (err);
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate 			err = add_ref_prop(fcalmodh, tmph, SEEPROM_SOURCE);
4547c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
4557c478bd9Sstevel@tonic-gate 				return (err);
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate 			err = add_void_fda_prop(fcalmodh);
4587c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
4597c478bd9Sstevel@tonic-gate 				return (err);
4607c478bd9Sstevel@tonic-gate 
4617c478bd9Sstevel@tonic-gate 			err = ptree_add_node(fcalsloth, fcalmodh);
4627c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
4637c478bd9Sstevel@tonic-gate 				return (err);
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 			err = add_ref_prop(tmph, fcalmodh, FRU_PARENT);
4667c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
4677c478bd9Sstevel@tonic-gate 				return (err);
4687c478bd9Sstevel@tonic-gate 		}
4697c478bd9Sstevel@tonic-gate 	}
4707c478bd9Sstevel@tonic-gate 
4717c478bd9Sstevel@tonic-gate 	/* If the FCAL GBIC board exists, create a node for it */
4727c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(platform_frupath[FCALGBIC], &tmph) ==
4737c478bd9Sstevel@tonic-gate 	    PICL_SUCCESS) {
4747c478bd9Sstevel@tonic-gate 		err = ptree_create_node("fcal-gbic-board", "fru",
4757c478bd9Sstevel@tonic-gate 		    &fcalgbich);
4767c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4777c478bd9Sstevel@tonic-gate 			return (err);
4787c478bd9Sstevel@tonic-gate 
4797c478bd9Sstevel@tonic-gate 		err = add_ref_prop(fcalgbich, tmph, SEEPROM_SOURCE);
4807c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4817c478bd9Sstevel@tonic-gate 			return (err);
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate 		err = add_void_fda_prop(fcalgbich);
4847c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4857c478bd9Sstevel@tonic-gate 			return (err);
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate 		err = ptree_add_node(rooth, fcalgbich);
4887c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4897c478bd9Sstevel@tonic-gate 			return (err);
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate 		err = add_ref_prop(tmph, fcalgbich, FRU_PARENT);
4927c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4937c478bd9Sstevel@tonic-gate 			return (err);
4947c478bd9Sstevel@tonic-gate 	}
4957c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
4967c478bd9Sstevel@tonic-gate }
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate /* Initializes the FRU nodes for the PDB and the power supplies */
4997c478bd9Sstevel@tonic-gate static int
do_power_supplies_init(picl_nodehdl_t rooth)5007c478bd9Sstevel@tonic-gate do_power_supplies_init(picl_nodehdl_t rooth)
5017c478bd9Sstevel@tonic-gate {
5027c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		powerbrdh;
5037c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		powersloth;
5047c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		powermodh;
5057c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
5067c478bd9Sstevel@tonic-gate 	int			i, err, slotnum;
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 	/* Create the node for the PDB (if it exists) */
5097c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(platform_frupath[PDB], &tmph) ==
5107c478bd9Sstevel@tonic-gate 	    PICL_SUCCESS) {
5117c478bd9Sstevel@tonic-gate 		err = ptree_create_node("power-dist-board", "fru", &powerbrdh);
5127c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
5137c478bd9Sstevel@tonic-gate 			return (err);
5147c478bd9Sstevel@tonic-gate 
5157c478bd9Sstevel@tonic-gate 		err = add_ref_prop(powerbrdh, tmph, SEEPROM_SOURCE);
5167c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
5177c478bd9Sstevel@tonic-gate 			return (err);
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate 		err = add_void_fda_prop(powerbrdh);
5207c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
5217c478bd9Sstevel@tonic-gate 			return (err);
5227c478bd9Sstevel@tonic-gate 
5237c478bd9Sstevel@tonic-gate 		err = ptree_add_node(rooth, powerbrdh);
5247c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
5257c478bd9Sstevel@tonic-gate 			return (err);
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate 		err = add_ref_prop(tmph, powerbrdh, FRU_PARENT);
5287c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
5297c478bd9Sstevel@tonic-gate 			return (err);
5307c478bd9Sstevel@tonic-gate 
5317c478bd9Sstevel@tonic-gate 		for (i = PS0; i <= PS2; i++) {
5327c478bd9Sstevel@tonic-gate 			/* Create the node for the power supply slot */
5337c478bd9Sstevel@tonic-gate 			err = ptree_create_node("power-supply-slot",
5347c478bd9Sstevel@tonic-gate 			    "location", &powersloth);
5357c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
5367c478bd9Sstevel@tonic-gate 				return (err);
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate 			slotnum = i - PS0;
5397c478bd9Sstevel@tonic-gate 			err = add_slot_prop(powersloth, slotnum);
5407c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
5417c478bd9Sstevel@tonic-gate 				return (err);
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate 			err = add_label_prop(powersloth, location_label[i]);
5447c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
5457c478bd9Sstevel@tonic-gate 				return (err);
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate 			err = ptree_add_node(powerbrdh, powersloth);
5487c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
5497c478bd9Sstevel@tonic-gate 				return (err);
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate 			/* If the PS exists, create a node for it */
5527c478bd9Sstevel@tonic-gate 			if (ptree_get_node_by_path(platform_frupath[i],
5537c478bd9Sstevel@tonic-gate 			    &tmph) == PICL_SUCCESS) {
5547c478bd9Sstevel@tonic-gate 				err = ptree_create_node("power-supply",
5557c478bd9Sstevel@tonic-gate 				    "fru", &powermodh);
5567c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
5577c478bd9Sstevel@tonic-gate 					return (err);
5587c478bd9Sstevel@tonic-gate 
5597c478bd9Sstevel@tonic-gate 				err = add_ref_prop(powermodh, tmph,
5607c478bd9Sstevel@tonic-gate 				    SEEPROM_SOURCE);
5617c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
5627c478bd9Sstevel@tonic-gate 					return (err);
5637c478bd9Sstevel@tonic-gate 
5647c478bd9Sstevel@tonic-gate 				err = add_void_fda_prop(powermodh);
5657c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
5667c478bd9Sstevel@tonic-gate 					return (err);
5677c478bd9Sstevel@tonic-gate 
5687c478bd9Sstevel@tonic-gate 				err = ptree_add_node(powersloth, powermodh);
5697c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
5707c478bd9Sstevel@tonic-gate 					return (err);
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate 				err = add_ref_prop(tmph, powermodh, FRU_PARENT);
5737c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
5747c478bd9Sstevel@tonic-gate 					return (err);
5757c478bd9Sstevel@tonic-gate 			}
5767c478bd9Sstevel@tonic-gate 		}
5777c478bd9Sstevel@tonic-gate 	}
5787c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
5797c478bd9Sstevel@tonic-gate }
5807c478bd9Sstevel@tonic-gate 
5817c478bd9Sstevel@tonic-gate /* Initializes the FRU nodes for the motherboard and CPU Memory modules */
5827c478bd9Sstevel@tonic-gate static int
do_motherboard_init(picl_nodehdl_t rooth)5837c478bd9Sstevel@tonic-gate do_motherboard_init(picl_nodehdl_t rooth)
5847c478bd9Sstevel@tonic-gate {
5857c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		sysboardh;
5867c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		cpumemsloth;
5877c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		cpumemmodh;
5887c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
5897c478bd9Sstevel@tonic-gate 	int			i, err, slotnum;
5907c478bd9Sstevel@tonic-gate 
5917c478bd9Sstevel@tonic-gate 	/* Create the node for the system board (if it exists) */
5927c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(platform_frupath[SYSBRD], &tmph) ==
5937c478bd9Sstevel@tonic-gate 	    PICL_SUCCESS) {
5947c478bd9Sstevel@tonic-gate 		err = ptree_create_node("system-board", "fru",
5957c478bd9Sstevel@tonic-gate 		    &sysboardh);
5967c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
5977c478bd9Sstevel@tonic-gate 			return (err);
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate 		err = add_ref_prop(sysboardh, tmph, SEEPROM_SOURCE);
6007c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
6017c478bd9Sstevel@tonic-gate 			return (err);
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate 		err = add_void_fda_prop(sysboardh);
6047c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
6057c478bd9Sstevel@tonic-gate 			return (err);
6067c478bd9Sstevel@tonic-gate 
6077c478bd9Sstevel@tonic-gate 		err = ptree_add_node(rooth, sysboardh);
6087c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
6097c478bd9Sstevel@tonic-gate 			return (err);
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 		err = add_ref_prop(tmph, sysboardh, FRU_PARENT);
6127c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
6137c478bd9Sstevel@tonic-gate 			return (err);
6147c478bd9Sstevel@tonic-gate 
6157c478bd9Sstevel@tonic-gate 		for (i = CPUMOD0; i <= CPUMOD3; i++) {
6167c478bd9Sstevel@tonic-gate 			/* Create the node for the CPU Memory slot */
6177c478bd9Sstevel@tonic-gate 			err = ptree_create_node("cpu-mem-slot", "location",
6187c478bd9Sstevel@tonic-gate 			    &cpumemsloth);
6197c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
6207c478bd9Sstevel@tonic-gate 				return (err);
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate 			slotnum = i - CPUMOD0;
6237c478bd9Sstevel@tonic-gate 			err = add_slot_prop(cpumemsloth, slotnum);
6247c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
6257c478bd9Sstevel@tonic-gate 				return (err);
6267c478bd9Sstevel@tonic-gate 
6277c478bd9Sstevel@tonic-gate 			err = add_label_prop(cpumemsloth, location_label[i]);
6287c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
6297c478bd9Sstevel@tonic-gate 				return (err);
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate 			err = ptree_add_node(sysboardh, cpumemsloth);
6327c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
6337c478bd9Sstevel@tonic-gate 				return (err);
6347c478bd9Sstevel@tonic-gate 
6357c478bd9Sstevel@tonic-gate 			/* If CPU Mem module exists, create a node for it */
6367c478bd9Sstevel@tonic-gate 			if (ptree_get_node_by_path(platform_frupath[i],
6377c478bd9Sstevel@tonic-gate 			    &tmph) == PICL_SUCCESS) {
6387c478bd9Sstevel@tonic-gate 				err = ptree_create_node("cpu-mem-module",
6397c478bd9Sstevel@tonic-gate 				    "fru", &cpumemmodh);
6407c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
6417c478bd9Sstevel@tonic-gate 					return (err);
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate 				err = add_ref_prop(cpumemmodh, tmph,
6447c478bd9Sstevel@tonic-gate 				    SEEPROM_SOURCE);
6457c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
6467c478bd9Sstevel@tonic-gate 					return (err);
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate 				err = add_void_fda_prop(cpumemmodh);
6497c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
6507c478bd9Sstevel@tonic-gate 					return (err);
6517c478bd9Sstevel@tonic-gate 
6527c478bd9Sstevel@tonic-gate 				err = ptree_add_node(cpumemsloth, cpumemmodh);
6537c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
6547c478bd9Sstevel@tonic-gate 					return (err);
6557c478bd9Sstevel@tonic-gate 
6567c478bd9Sstevel@tonic-gate 				err = add_ref_prop(tmph, cpumemmodh,
6577c478bd9Sstevel@tonic-gate 				    FRU_PARENT);
6587c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
6597c478bd9Sstevel@tonic-gate 					return (err);
6607c478bd9Sstevel@tonic-gate 
6617c478bd9Sstevel@tonic-gate 				err = do_cpu_module_init(cpumemmodh, slotnum);
6627c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
6637c478bd9Sstevel@tonic-gate 					return (err);
6647c478bd9Sstevel@tonic-gate 			}
6657c478bd9Sstevel@tonic-gate 		}
6667c478bd9Sstevel@tonic-gate 	}
6677c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
6687c478bd9Sstevel@tonic-gate }
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate /* Creates the FRU nodes for the CPU Module and associated DIMMs */
6717c478bd9Sstevel@tonic-gate static int
do_cpu_module_init(picl_nodehdl_t rooth,int slot)6727c478bd9Sstevel@tonic-gate do_cpu_module_init(picl_nodehdl_t rooth, int slot)
6737c478bd9Sstevel@tonic-gate {
6747c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		cpumodh;
6757c478bd9Sstevel@tonic-gate 	int			i, c, err;
6767c478bd9Sstevel@tonic-gate 
6777c478bd9Sstevel@tonic-gate 	for (i = 0; i <= 1; i++) {
6787c478bd9Sstevel@tonic-gate 		err = ptree_create_node("cpu-module", "location",
6797c478bd9Sstevel@tonic-gate 		    &cpumodh);
6807c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
6817c478bd9Sstevel@tonic-gate 			return (err);
6827c478bd9Sstevel@tonic-gate 
6837c478bd9Sstevel@tonic-gate 		err = add_slot_prop(cpumodh, i);
6847c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
6857c478bd9Sstevel@tonic-gate 			return (err);
6867c478bd9Sstevel@tonic-gate 
6877c478bd9Sstevel@tonic-gate 		c = CPU0_DIMM0 + DIMMS_PER_SLOT + i;
6887c478bd9Sstevel@tonic-gate 
6897c478bd9Sstevel@tonic-gate 		err = add_label_prop(cpumodh, location_label[c]);
6907c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
6917c478bd9Sstevel@tonic-gate 			return (err);
6927c478bd9Sstevel@tonic-gate 
6937c478bd9Sstevel@tonic-gate 		err = ptree_add_node(rooth, cpumodh);
6947c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
6957c478bd9Sstevel@tonic-gate 			return (err);
6967c478bd9Sstevel@tonic-gate 
6977c478bd9Sstevel@tonic-gate 		/* Create the nodes for the memory (if they exist) */
6987c478bd9Sstevel@tonic-gate 		err = do_dimms_init(cpumodh, slot, i);
6997c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
7007c478bd9Sstevel@tonic-gate 			return (err);
7017c478bd9Sstevel@tonic-gate 	}
7027c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
7037c478bd9Sstevel@tonic-gate }
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate /* Creates the FRU nodes for the DIMMs on a particular CPU Module */
7067c478bd9Sstevel@tonic-gate static int
do_dimms_init(picl_nodehdl_t rooth,int slot,int module)7077c478bd9Sstevel@tonic-gate do_dimms_init(picl_nodehdl_t rooth, int slot, int module)
7087c478bd9Sstevel@tonic-gate {
7097c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		dimmsloth;
7107c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		dimmmodh;
7117c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
7127c478bd9Sstevel@tonic-gate 	int			i, c, l, err;
7137c478bd9Sstevel@tonic-gate 
7147c478bd9Sstevel@tonic-gate 	for (i = 0; i < DIMMS_PER_MOD; i++) {
7157c478bd9Sstevel@tonic-gate 		/* Create the node for the memory slot */
7167c478bd9Sstevel@tonic-gate 		err = ptree_create_node("dimm-slot", "location",
7177c478bd9Sstevel@tonic-gate 		    &dimmsloth);
7187c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
7197c478bd9Sstevel@tonic-gate 			return (err);
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate 		err = add_slot_prop(dimmsloth, i);
7227c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
7237c478bd9Sstevel@tonic-gate 			return (err);
7247c478bd9Sstevel@tonic-gate 
7257c478bd9Sstevel@tonic-gate 		c = ((slot * DIMMS_PER_SLOT) +
7267c478bd9Sstevel@tonic-gate 		    (module * DIMMS_PER_MOD) + i) + CPU0_DIMM0;
7277c478bd9Sstevel@tonic-gate 
7287c478bd9Sstevel@tonic-gate 		l = c - (DIMMS_PER_SLOT * slot);
7297c478bd9Sstevel@tonic-gate 
7307c478bd9Sstevel@tonic-gate 		err = add_label_prop(dimmsloth, location_label[l]);
7317c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
7327c478bd9Sstevel@tonic-gate 			return (err);
7337c478bd9Sstevel@tonic-gate 
7347c478bd9Sstevel@tonic-gate 		err = ptree_add_node(rooth, dimmsloth);
7357c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
7367c478bd9Sstevel@tonic-gate 			return (err);
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate 		/* If the memory module exists, create a node for it */
7397c478bd9Sstevel@tonic-gate 		if (ptree_get_node_by_path(platform_frupath[c], &tmph) ==
7407c478bd9Sstevel@tonic-gate 		    PICL_SUCCESS) {
7417c478bd9Sstevel@tonic-gate 			err = ptree_create_node("dimm-module", "fru",
7427c478bd9Sstevel@tonic-gate 			    &dimmmodh);
7437c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
7447c478bd9Sstevel@tonic-gate 				return (err);
7457c478bd9Sstevel@tonic-gate 
7467c478bd9Sstevel@tonic-gate 			err = add_ref_prop(dimmmodh, tmph, SEEPROM_SOURCE);
7477c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
7487c478bd9Sstevel@tonic-gate 				return (err);
7497c478bd9Sstevel@tonic-gate 
7507c478bd9Sstevel@tonic-gate 			err = add_void_fda_prop(dimmmodh);
7517c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
7527c478bd9Sstevel@tonic-gate 				return (err);
7537c478bd9Sstevel@tonic-gate 
7547c478bd9Sstevel@tonic-gate 			err = ptree_add_node(dimmsloth, dimmmodh);
7557c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
7567c478bd9Sstevel@tonic-gate 				return (err);
7577c478bd9Sstevel@tonic-gate 
7587c478bd9Sstevel@tonic-gate 			err = add_ref_prop(tmph, dimmmodh, FRU_PARENT);
7597c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
7607c478bd9Sstevel@tonic-gate 				return (err);
7617c478bd9Sstevel@tonic-gate 		}
7627c478bd9Sstevel@tonic-gate 	}
7637c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
7647c478bd9Sstevel@tonic-gate }
7657c478bd9Sstevel@tonic-gate 
7667c478bd9Sstevel@tonic-gate /* Creates a "reference" property between two PICL nodes */
7677c478bd9Sstevel@tonic-gate static int
add_ref_prop(picl_nodehdl_t nodeh,picl_nodehdl_t tmph,char * str)7687c478bd9Sstevel@tonic-gate add_ref_prop(picl_nodehdl_t nodeh, picl_nodehdl_t tmph, char *str)
7697c478bd9Sstevel@tonic-gate {
7707c478bd9Sstevel@tonic-gate 	picl_prophdl_t		proph;
7717c478bd9Sstevel@tonic-gate 	ptree_propinfo_t	propinfo;
7727c478bd9Sstevel@tonic-gate 	int			err;
7737c478bd9Sstevel@tonic-gate 
7747c478bd9Sstevel@tonic-gate 	if (str == NULL)
7757c478bd9Sstevel@tonic-gate 		return (PICL_FAILURE);
7767c478bd9Sstevel@tonic-gate 
7777c478bd9Sstevel@tonic-gate 	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
7787c478bd9Sstevel@tonic-gate 	    PICL_PTYPE_REFERENCE, PICL_READ, sizeof (picl_nodehdl_t),
7797c478bd9Sstevel@tonic-gate 	    str, NULL, NULL);
7807c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
7817c478bd9Sstevel@tonic-gate 		return (err);
7827c478bd9Sstevel@tonic-gate 
7837c478bd9Sstevel@tonic-gate 	err = ptree_create_and_add_prop(nodeh, &propinfo, &tmph, &proph);
7847c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
7857c478bd9Sstevel@tonic-gate 		return (err);
7867c478bd9Sstevel@tonic-gate 
7877c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
7887c478bd9Sstevel@tonic-gate }
7897c478bd9Sstevel@tonic-gate 
7907c478bd9Sstevel@tonic-gate /* Creates a "slot" property for a given PICL node */
7917c478bd9Sstevel@tonic-gate static int
add_slot_prop(picl_nodehdl_t nodeh,int slotnum)7927c478bd9Sstevel@tonic-gate add_slot_prop(picl_nodehdl_t nodeh, int slotnum)
7937c478bd9Sstevel@tonic-gate {
7947c478bd9Sstevel@tonic-gate 	picl_prophdl_t		proph;
7957c478bd9Sstevel@tonic-gate 	ptree_propinfo_t	propinfo;
7967c478bd9Sstevel@tonic-gate 	int			err;
7977c478bd9Sstevel@tonic-gate 
7987c478bd9Sstevel@tonic-gate 	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
7997c478bd9Sstevel@tonic-gate 	    PICL_PTYPE_INT, PICL_READ, 4, "Slot", NULL, NULL);
8007c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
8017c478bd9Sstevel@tonic-gate 		return (err);
8027c478bd9Sstevel@tonic-gate 
8037c478bd9Sstevel@tonic-gate 	err = ptree_create_and_add_prop(nodeh, &propinfo, &slotnum, &proph);
8047c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
8057c478bd9Sstevel@tonic-gate 		return (err);
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
8087c478bd9Sstevel@tonic-gate }
8097c478bd9Sstevel@tonic-gate 
8107c478bd9Sstevel@tonic-gate /* Creates a "Label" property for a given PICL node */
8117c478bd9Sstevel@tonic-gate static int
add_label_prop(picl_nodehdl_t nodeh,char * label)8127c478bd9Sstevel@tonic-gate add_label_prop(picl_nodehdl_t nodeh, char *label)
8137c478bd9Sstevel@tonic-gate {
8147c478bd9Sstevel@tonic-gate 	picl_prophdl_t		proph;
8157c478bd9Sstevel@tonic-gate 	ptree_propinfo_t	propinfo;
8167c478bd9Sstevel@tonic-gate 	int			err;
8177c478bd9Sstevel@tonic-gate 
8187c478bd9Sstevel@tonic-gate 	if (label == NULL)
8197c478bd9Sstevel@tonic-gate 		return (PICL_FAILURE);
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate 	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
8227c478bd9Sstevel@tonic-gate 	    PICL_PTYPE_CHARSTRING, PICL_READ, strlen(label)+1, "Label",
8237c478bd9Sstevel@tonic-gate 	    NULL, NULL);
8247c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
8257c478bd9Sstevel@tonic-gate 		return (err);
8267c478bd9Sstevel@tonic-gate 
8277c478bd9Sstevel@tonic-gate 	err = ptree_create_and_add_prop(nodeh, &propinfo, label, &proph);
8287c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
8297c478bd9Sstevel@tonic-gate 		return (err);
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
8327c478bd9Sstevel@tonic-gate }
8337c478bd9Sstevel@tonic-gate 
8347c478bd9Sstevel@tonic-gate /* Creates a "FRUDataAvailable" void property for the given PICL node */
8357c478bd9Sstevel@tonic-gate static int
add_void_fda_prop(picl_nodehdl_t nodeh)8367c478bd9Sstevel@tonic-gate add_void_fda_prop(picl_nodehdl_t nodeh)
8377c478bd9Sstevel@tonic-gate {
8387c478bd9Sstevel@tonic-gate 	picl_prophdl_t		proph;
8397c478bd9Sstevel@tonic-gate 	ptree_propinfo_t	propinfo;
8407c478bd9Sstevel@tonic-gate 	int			err;
8417c478bd9Sstevel@tonic-gate 
8427c478bd9Sstevel@tonic-gate 	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
8437c478bd9Sstevel@tonic-gate 	    PICL_PTYPE_VOID, PICL_READ, 0, "FRUDataAvailable", NULL, NULL);
8447c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
8457c478bd9Sstevel@tonic-gate 		return (err);
8467c478bd9Sstevel@tonic-gate 
8477c478bd9Sstevel@tonic-gate 	err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, &proph);
8487c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
8497c478bd9Sstevel@tonic-gate 		return (err);
8507c478bd9Sstevel@tonic-gate 
8517c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
8527c478bd9Sstevel@tonic-gate }
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate /* Creates a "ViewPoints" property -- used for chassis */
8557c478bd9Sstevel@tonic-gate static int
add_viewpoints_prop(picl_nodehdl_t nodeh,char * string)8567c478bd9Sstevel@tonic-gate add_viewpoints_prop(picl_nodehdl_t nodeh, char *string)
8577c478bd9Sstevel@tonic-gate {
8587c478bd9Sstevel@tonic-gate 	picl_prophdl_t		proph;
8597c478bd9Sstevel@tonic-gate 	ptree_propinfo_t	propinfo;
8607c478bd9Sstevel@tonic-gate 	int			err;
8617c478bd9Sstevel@tonic-gate 
8627c478bd9Sstevel@tonic-gate 	if (string == NULL)
8637c478bd9Sstevel@tonic-gate 		return (PICL_FAILURE);
8647c478bd9Sstevel@tonic-gate 
8657c478bd9Sstevel@tonic-gate 	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
8667c478bd9Sstevel@tonic-gate 	    PICL_PTYPE_CHARSTRING, PICL_READ, strlen(string)+1, "ViewPoints",
8677c478bd9Sstevel@tonic-gate 	    NULL, NULL);
8687c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
8697c478bd9Sstevel@tonic-gate 		return (err);
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate 	err = ptree_create_and_add_prop(nodeh, &propinfo, string, &proph);
8727c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
8737c478bd9Sstevel@tonic-gate 		return (err);
8747c478bd9Sstevel@tonic-gate 
8757c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
8767c478bd9Sstevel@tonic-gate }
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate /* Creates and adds all of the frutree nodes */
8797c478bd9Sstevel@tonic-gate static int
add_all_nodes()8807c478bd9Sstevel@tonic-gate add_all_nodes()
8817c478bd9Sstevel@tonic-gate {
8827c478bd9Sstevel@tonic-gate 	picl_nodehdl_t	rooth;
8837c478bd9Sstevel@tonic-gate 	picl_nodehdl_t	chassish;
8847c478bd9Sstevel@tonic-gate 	int		err;
8857c478bd9Sstevel@tonic-gate 
8867c478bd9Sstevel@tonic-gate 	/* Get the root node of the PICL tree */
8877c478bd9Sstevel@tonic-gate 	err = ptree_get_root(&rooth);
8887c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
8897c478bd9Sstevel@tonic-gate 		return (err);
8907c478bd9Sstevel@tonic-gate 	}
8917c478bd9Sstevel@tonic-gate 
8927c478bd9Sstevel@tonic-gate 	/* Create and add the root node of the FRU subtree */
8937c478bd9Sstevel@tonic-gate 	err = ptree_create_and_add_node(rooth, "frutree", "picl", &frutreeh);
8947c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
8957c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, CREATE_FRUTREE_FAIL);
8967c478bd9Sstevel@tonic-gate 		return (err);
8977c478bd9Sstevel@tonic-gate 	}
8987c478bd9Sstevel@tonic-gate 
8997c478bd9Sstevel@tonic-gate 	/* Create and add the chassis node */
9007c478bd9Sstevel@tonic-gate 	err = ptree_create_and_add_node(frutreeh, "chassis", "fru", &chassish);
9017c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
9027c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, CREATE_CHASSIS_FAIL);
9037c478bd9Sstevel@tonic-gate 		return (err);
9047c478bd9Sstevel@tonic-gate 	}
9057c478bd9Sstevel@tonic-gate 
9067c478bd9Sstevel@tonic-gate 	/* Add ViewPoints prop to chassis node */
9077c478bd9Sstevel@tonic-gate 	err = add_viewpoints_prop(chassish, CHASSIS_VIEWPOINTS);
9087c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
9097c478bd9Sstevel@tonic-gate 		return (err);
9107c478bd9Sstevel@tonic-gate 
9117c478bd9Sstevel@tonic-gate 	/* Initialize the FRU nodes for the IO board */
9127c478bd9Sstevel@tonic-gate 	err = do_ioboard_init(chassish);
9137c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
9147c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, IOBRD_INIT_FAIL);
9157c478bd9Sstevel@tonic-gate 		return (err);
9167c478bd9Sstevel@tonic-gate 	}
9177c478bd9Sstevel@tonic-gate 
9187c478bd9Sstevel@tonic-gate 	/* Initialize the FRU node for the RSC card */
9197c478bd9Sstevel@tonic-gate 	err = do_rscboard_init(chassish);
9207c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
9217c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, RSCBRD_INIT_FAIL);
9227c478bd9Sstevel@tonic-gate 		return (err);
9237c478bd9Sstevel@tonic-gate 	}
9247c478bd9Sstevel@tonic-gate 
9257c478bd9Sstevel@tonic-gate 	/* Initialize the FRU nodes for the FCAL backplanes and GBIC board */
9267c478bd9Sstevel@tonic-gate 	err = do_fcal_init(chassish);
9277c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
9287c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, FCAL_INIT_FAIL);
9297c478bd9Sstevel@tonic-gate 		return (err);
9307c478bd9Sstevel@tonic-gate 	}
9317c478bd9Sstevel@tonic-gate 
9327c478bd9Sstevel@tonic-gate 	/* Initialize the FRU nodes for the PDB and the power supplies */
9337c478bd9Sstevel@tonic-gate 	err = do_power_supplies_init(chassish);
9347c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
9357c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, PS_INIT_FAIL);
9367c478bd9Sstevel@tonic-gate 		return (err);
9377c478bd9Sstevel@tonic-gate 	}
9387c478bd9Sstevel@tonic-gate 
9397c478bd9Sstevel@tonic-gate 	/* Initialize the FRU nodes for the CPU Memory modules */
9407c478bd9Sstevel@tonic-gate 	err = do_motherboard_init(chassish);
9417c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
9427c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, SYSBOARD_INIT_FAIL);
9437c478bd9Sstevel@tonic-gate 		return (err);
9447c478bd9Sstevel@tonic-gate 	}
9457c478bd9Sstevel@tonic-gate 
9467c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
9477c478bd9Sstevel@tonic-gate }
9487c478bd9Sstevel@tonic-gate 
9497c478bd9Sstevel@tonic-gate /* Deletes and destroys all PICL nodes for which rooth is a ancestor */
9507c478bd9Sstevel@tonic-gate static int
remove_all_nodes(picl_nodehdl_t rooth)9517c478bd9Sstevel@tonic-gate remove_all_nodes(picl_nodehdl_t rooth)
9527c478bd9Sstevel@tonic-gate {
9537c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		chdh;
9547c478bd9Sstevel@tonic-gate 	int			err, done = 0;
9557c478bd9Sstevel@tonic-gate 
9567c478bd9Sstevel@tonic-gate 	while (!done) {
9577c478bd9Sstevel@tonic-gate 		err = ptree_get_propval_by_name(rooth, PICL_PROP_CHILD, &chdh,
9587c478bd9Sstevel@tonic-gate 		    sizeof (picl_nodehdl_t));
9597c478bd9Sstevel@tonic-gate 		if (err != PICL_PROPNOTFOUND) {
9607c478bd9Sstevel@tonic-gate 			(void) remove_all_nodes(chdh);
9617c478bd9Sstevel@tonic-gate 		} else {
9627c478bd9Sstevel@tonic-gate 			err = ptree_delete_node(rooth);
9637c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS) {
9647c478bd9Sstevel@tonic-gate 				return (err);
9657c478bd9Sstevel@tonic-gate 			} else {
9667c478bd9Sstevel@tonic-gate 				(void) ptree_destroy_node(rooth);
9677c478bd9Sstevel@tonic-gate 			}
9687c478bd9Sstevel@tonic-gate 			done = 1;
9697c478bd9Sstevel@tonic-gate 		}
9707c478bd9Sstevel@tonic-gate 	}
9717c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
9727c478bd9Sstevel@tonic-gate }
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate /* Searches the list of hotpluggable FRUs, adds the appropriate node(s) */
9757c478bd9Sstevel@tonic-gate static int
add_hotplug_fru_device()9767c478bd9Sstevel@tonic-gate add_hotplug_fru_device()
9777c478bd9Sstevel@tonic-gate {
9787c478bd9Sstevel@tonic-gate 	int		i, err, slotnum;
9797c478bd9Sstevel@tonic-gate 
9807c478bd9Sstevel@tonic-gate 	/* Check for hotplugged power supplies */
9817c478bd9Sstevel@tonic-gate 	for (i = PS0; i <= PS2; i++) {
9827c478bd9Sstevel@tonic-gate 		/* Compare the /platform tree to the frutree */
9837c478bd9Sstevel@tonic-gate 		slotnum = i - PS0;
9847c478bd9Sstevel@tonic-gate 		err = is_added_device(platform_frupath[i],
9857c478bd9Sstevel@tonic-gate 		    frutree_power_supply[slotnum]);
9867c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
9877c478bd9Sstevel@tonic-gate 			continue;
9887c478bd9Sstevel@tonic-gate 
9897c478bd9Sstevel@tonic-gate 		/* If they are different, then add a power supply */
9907c478bd9Sstevel@tonic-gate 		err = add_power_supply(slotnum);
9917c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
9927c478bd9Sstevel@tonic-gate 			continue;
9937c478bd9Sstevel@tonic-gate 	}
9947c478bd9Sstevel@tonic-gate 
9957c478bd9Sstevel@tonic-gate 	/* Check for hotplugged CPU Memory modules */
9967c478bd9Sstevel@tonic-gate 	for (i = CPUMOD0; i <= CPUMOD3; i++) {
9977c478bd9Sstevel@tonic-gate 		/* Compare the /platform tree to the frutree */
9987c478bd9Sstevel@tonic-gate 		slotnum = i - CPUMOD0;
9997c478bd9Sstevel@tonic-gate 		err = is_added_device(platform_frupath[i],
10007c478bd9Sstevel@tonic-gate 		    frutree_cpu_module[slotnum]);
10017c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
10027c478bd9Sstevel@tonic-gate 			continue;
10037c478bd9Sstevel@tonic-gate 
10047c478bd9Sstevel@tonic-gate 		/* If they are different, then add a CPU Mem module */
10057c478bd9Sstevel@tonic-gate 		err = add_cpu_module(slotnum);
10067c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
10077c478bd9Sstevel@tonic-gate 			continue;
10087c478bd9Sstevel@tonic-gate 	}
10097c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
10107c478bd9Sstevel@tonic-gate }
10117c478bd9Sstevel@tonic-gate 
10127c478bd9Sstevel@tonic-gate /* Searches the list of hotpluggable FRUs, removes the appropriate node(s) */
10137c478bd9Sstevel@tonic-gate static int
rem_hotplug_fru_device()10147c478bd9Sstevel@tonic-gate rem_hotplug_fru_device()
10157c478bd9Sstevel@tonic-gate {
10167c478bd9Sstevel@tonic-gate 	int		i, err, slotnum;
10177c478bd9Sstevel@tonic-gate 
10187c478bd9Sstevel@tonic-gate 	/* Check for hotplugged power supplies */
10197c478bd9Sstevel@tonic-gate 	for (i = PS0; i <= PS2; i++) {
10207c478bd9Sstevel@tonic-gate 		/* Compare the /platform tree to the frutree */
10217c478bd9Sstevel@tonic-gate 		slotnum = i - PS0;
10227c478bd9Sstevel@tonic-gate 		err = is_removed_device(platform_frupath[i],
10237c478bd9Sstevel@tonic-gate 		    frutree_power_supply[slotnum]);
10247c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
10257c478bd9Sstevel@tonic-gate 			continue;
10267c478bd9Sstevel@tonic-gate 
10277c478bd9Sstevel@tonic-gate 		/* If they are different, then remove a power supply */
10287c478bd9Sstevel@tonic-gate 		err = remove_power_supply(slotnum);
10297c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
10307c478bd9Sstevel@tonic-gate 			continue;
10317c478bd9Sstevel@tonic-gate 	}
10327c478bd9Sstevel@tonic-gate 
10337c478bd9Sstevel@tonic-gate 	/* Check for hotplugged CPU Memory modules */
10347c478bd9Sstevel@tonic-gate 	for (i = CPUMOD0; i <= CPUMOD3; i++) {
10357c478bd9Sstevel@tonic-gate 		/* Compare the /platform tree to the frutree */
10367c478bd9Sstevel@tonic-gate 		slotnum = i - CPUMOD0;
10377c478bd9Sstevel@tonic-gate 		err = is_removed_device(platform_frupath[i],
10387c478bd9Sstevel@tonic-gate 		    frutree_cpu_module[slotnum]);
10397c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
10407c478bd9Sstevel@tonic-gate 			continue;
10417c478bd9Sstevel@tonic-gate 
10427c478bd9Sstevel@tonic-gate 		/* If they are different, then remove a CPU Mem module */
10437c478bd9Sstevel@tonic-gate 		err = remove_cpu_module(slotnum);
10447c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
10457c478bd9Sstevel@tonic-gate 			continue;
10467c478bd9Sstevel@tonic-gate 	}
10477c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
10487c478bd9Sstevel@tonic-gate }
10497c478bd9Sstevel@tonic-gate 
10507c478bd9Sstevel@tonic-gate /*
10517c478bd9Sstevel@tonic-gate  * Compare the /platform tree to the /frutree to determine if a
10527c478bd9Sstevel@tonic-gate  * new device has been added
10537c478bd9Sstevel@tonic-gate  */
10547c478bd9Sstevel@tonic-gate static int
is_added_device(char * plat,char * fru)10557c478bd9Sstevel@tonic-gate is_added_device(char *plat, char *fru)
10567c478bd9Sstevel@tonic-gate {
10577c478bd9Sstevel@tonic-gate 	int		err;
10587c478bd9Sstevel@tonic-gate 	picl_nodehdl_t	plath, frusloth, frumodh;
10597c478bd9Sstevel@tonic-gate 
10607c478bd9Sstevel@tonic-gate 	/* Check for node in the /platform tree */
10617c478bd9Sstevel@tonic-gate 	err = ptree_get_node_by_path(plat, &plath);
10627c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
10637c478bd9Sstevel@tonic-gate 		return (err);
10647c478bd9Sstevel@tonic-gate 
10657c478bd9Sstevel@tonic-gate 	/*
10667c478bd9Sstevel@tonic-gate 	 * The node is in /platform, so find the corresponding slot in
10677c478bd9Sstevel@tonic-gate 	 * the frutree
10687c478bd9Sstevel@tonic-gate 	 */
10697c478bd9Sstevel@tonic-gate 	err = ptree_get_node_by_path(fru, &frusloth);
10707c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
10717c478bd9Sstevel@tonic-gate 		return (err);
10727c478bd9Sstevel@tonic-gate 
10737c478bd9Sstevel@tonic-gate 	/*
10747c478bd9Sstevel@tonic-gate 	 * If the slot in the frutree has a child, then return
10757c478bd9Sstevel@tonic-gate 	 * PICL_FAILURE.  This means that the /platform tree and
10767c478bd9Sstevel@tonic-gate 	 * the frutree are consistent and no action is necessary.
10777c478bd9Sstevel@tonic-gate 	 * Otherwise return PICL_SUCCESS to indicate that a node needs
10787c478bd9Sstevel@tonic-gate 	 * to be added to the frutree
10797c478bd9Sstevel@tonic-gate 	 */
10807c478bd9Sstevel@tonic-gate 	err = ptree_get_propval_by_name(frusloth, PICL_PROP_CHILD,
10817c478bd9Sstevel@tonic-gate 	    &frumodh, sizeof (picl_nodehdl_t));
10827c478bd9Sstevel@tonic-gate 	if (err == PICL_SUCCESS)
10837c478bd9Sstevel@tonic-gate 		return (PICL_FAILURE);
10847c478bd9Sstevel@tonic-gate 
10857c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
10867c478bd9Sstevel@tonic-gate }
10877c478bd9Sstevel@tonic-gate 
10887c478bd9Sstevel@tonic-gate /*
10897c478bd9Sstevel@tonic-gate  * Compare the /platform tree to the /frutree to determine if a
10907c478bd9Sstevel@tonic-gate  * device has been removed
10917c478bd9Sstevel@tonic-gate  */
10927c478bd9Sstevel@tonic-gate static int
is_removed_device(char * plat,char * fru)10937c478bd9Sstevel@tonic-gate is_removed_device(char *plat, char *fru)
10947c478bd9Sstevel@tonic-gate {
10957c478bd9Sstevel@tonic-gate 	int		err;
10967c478bd9Sstevel@tonic-gate 	picl_nodehdl_t	plath, frusloth, frumodh;
10977c478bd9Sstevel@tonic-gate 
10987c478bd9Sstevel@tonic-gate 
10997c478bd9Sstevel@tonic-gate 	/* Check for node in /platform tree */
11007c478bd9Sstevel@tonic-gate 	err = ptree_get_node_by_path(plat, &plath);
11017c478bd9Sstevel@tonic-gate 	if (err == PICL_SUCCESS)
11027c478bd9Sstevel@tonic-gate 		return (PICL_FAILURE);
11037c478bd9Sstevel@tonic-gate 
11047c478bd9Sstevel@tonic-gate 	/*
11057c478bd9Sstevel@tonic-gate 	 * The node is not in /platform, so find the corresponding slot in
11067c478bd9Sstevel@tonic-gate 	 * the frutree
11077c478bd9Sstevel@tonic-gate 	 */
11087c478bd9Sstevel@tonic-gate 	err = ptree_get_node_by_path(fru, &frusloth);
11097c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
11107c478bd9Sstevel@tonic-gate 		return (err);
11117c478bd9Sstevel@tonic-gate 
11127c478bd9Sstevel@tonic-gate 	/*
11137c478bd9Sstevel@tonic-gate 	 * If the slot in the frutree does not have a child, then return
11147c478bd9Sstevel@tonic-gate 	 * PICL_FAILURE.  This means that the /platform tree and
11157c478bd9Sstevel@tonic-gate 	 * the frutree are consistent and no action is necessary.
11167c478bd9Sstevel@tonic-gate 	 * Otherwise return PICL_SUCCESS to indicate that the needs
11177c478bd9Sstevel@tonic-gate 	 * to be removed from the frutree
11187c478bd9Sstevel@tonic-gate 	 */
11197c478bd9Sstevel@tonic-gate 	err = ptree_get_propval_by_name(frusloth, PICL_PROP_CHILD,
11207c478bd9Sstevel@tonic-gate 	    &frumodh, sizeof (picl_nodehdl_t));
11217c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
11227c478bd9Sstevel@tonic-gate 		return (err);
11237c478bd9Sstevel@tonic-gate 
11247c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
11257c478bd9Sstevel@tonic-gate }
11267c478bd9Sstevel@tonic-gate 
11277c478bd9Sstevel@tonic-gate static int
remove_picl_node(picl_nodehdl_t nodeh)11287c478bd9Sstevel@tonic-gate remove_picl_node(picl_nodehdl_t nodeh)
11297c478bd9Sstevel@tonic-gate {
11307c478bd9Sstevel@tonic-gate 	int err;
11317c478bd9Sstevel@tonic-gate 	err = ptree_delete_node(nodeh);
11327c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
11337c478bd9Sstevel@tonic-gate 		return (err);
11347c478bd9Sstevel@tonic-gate 	(void) ptree_destroy_node(nodeh);
11357c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
11367c478bd9Sstevel@tonic-gate }
11377c478bd9Sstevel@tonic-gate 
11387c478bd9Sstevel@tonic-gate /* event completion handler for PICL_FRU_ADDED/PICL_FRU_REMOVED events */
11397c478bd9Sstevel@tonic-gate /*ARGSUSED2*/
11407c478bd9Sstevel@tonic-gate static void
frudr_completion_handler(char * ename,void * earg,size_t size)11417c478bd9Sstevel@tonic-gate frudr_completion_handler(char *ename, void *earg, size_t size)
11427c478bd9Sstevel@tonic-gate {
11437c478bd9Sstevel@tonic-gate 	picl_nodehdl_t	fruh;
11447c478bd9Sstevel@tonic-gate 
11457c478bd9Sstevel@tonic-gate 	if (strcmp(ename, PICL_FRU_REMOVED) == 0) {
11467c478bd9Sstevel@tonic-gate 		/*
11477c478bd9Sstevel@tonic-gate 		 * now frudata has been notified that the node is to be
11487c478bd9Sstevel@tonic-gate 		 * removed, we can actually remove it
11497c478bd9Sstevel@tonic-gate 		 */
1150*ada2da53SToomas Soome 		fruh = 0;
11517c478bd9Sstevel@tonic-gate 		(void) nvlist_lookup_uint64(earg,
11527c478bd9Sstevel@tonic-gate 		    PICLEVENTARG_FRUHANDLE, &fruh);
1153*ada2da53SToomas Soome 		if (fruh != 0) {
11547c478bd9Sstevel@tonic-gate 			(void) remove_picl_node(fruh);
11557c478bd9Sstevel@tonic-gate 		}
11567c478bd9Sstevel@tonic-gate 	}
11577c478bd9Sstevel@tonic-gate 	nvlist_free(earg);
11587c478bd9Sstevel@tonic-gate 	free(earg);
11597c478bd9Sstevel@tonic-gate 	free(ename);
11607c478bd9Sstevel@tonic-gate }
11617c478bd9Sstevel@tonic-gate 
11627c478bd9Sstevel@tonic-gate /*
11637c478bd9Sstevel@tonic-gate  * Post the PICL_FRU_ADDED/PICL_FRU_REMOVED event
11647c478bd9Sstevel@tonic-gate  */
11657c478bd9Sstevel@tonic-gate static void
post_frudr_event(char * ename,picl_nodehdl_t parenth,picl_nodehdl_t fruh)11667c478bd9Sstevel@tonic-gate post_frudr_event(char *ename, picl_nodehdl_t parenth, picl_nodehdl_t fruh)
11677c478bd9Sstevel@tonic-gate {
11687c478bd9Sstevel@tonic-gate 	nvlist_t	*nvl;
11697c478bd9Sstevel@tonic-gate 	char		*ev_name;
11707c478bd9Sstevel@tonic-gate 
11717c478bd9Sstevel@tonic-gate 	ev_name = strdup(ename);
11727c478bd9Sstevel@tonic-gate 	if (ev_name == NULL)
11737c478bd9Sstevel@tonic-gate 		return;
1174*ada2da53SToomas Soome 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME_TYPE, 0)) {
11757c478bd9Sstevel@tonic-gate 		free(ev_name);
11767c478bd9Sstevel@tonic-gate 		return;
11777c478bd9Sstevel@tonic-gate 	}
11787c478bd9Sstevel@tonic-gate 	if (parenth != 0L &&
11797c478bd9Sstevel@tonic-gate 	    nvlist_add_uint64(nvl, PICLEVENTARG_PARENTHANDLE, parenth)) {
11807c478bd9Sstevel@tonic-gate 		free(ev_name);
11817c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
11827c478bd9Sstevel@tonic-gate 		return;
11837c478bd9Sstevel@tonic-gate 	}
11847c478bd9Sstevel@tonic-gate 	if (fruh != 0L &&
11857c478bd9Sstevel@tonic-gate 	    nvlist_add_uint64(nvl, PICLEVENTARG_FRUHANDLE, fruh)) {
11867c478bd9Sstevel@tonic-gate 		free(ev_name);
11877c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
11887c478bd9Sstevel@tonic-gate 		return;
11897c478bd9Sstevel@tonic-gate 	}
11907c478bd9Sstevel@tonic-gate 	if (ptree_post_event(ev_name, nvl, sizeof (nvl),
11917c478bd9Sstevel@tonic-gate 	    frudr_completion_handler) != 0) {
11927c478bd9Sstevel@tonic-gate 		free(ev_name);
11937c478bd9Sstevel@tonic-gate 		nvlist_free(nvl);
11947c478bd9Sstevel@tonic-gate 	}
11957c478bd9Sstevel@tonic-gate }
11967c478bd9Sstevel@tonic-gate 
11977c478bd9Sstevel@tonic-gate /* Hotplug routine used to add a new power supply */
11987c478bd9Sstevel@tonic-gate static int
add_power_supply(int slotnum)11997c478bd9Sstevel@tonic-gate add_power_supply(int slotnum)
12007c478bd9Sstevel@tonic-gate {
12017c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		powersloth;
12027c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		powermodh;
12037c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
12047c478bd9Sstevel@tonic-gate 	int			i, err;
12057c478bd9Sstevel@tonic-gate 
12067c478bd9Sstevel@tonic-gate 	/* Find the node for the given power supply slot */
12077c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(frutree_power_supply[slotnum],
12087c478bd9Sstevel@tonic-gate 	    &powersloth) == PICL_SUCCESS) {
12097c478bd9Sstevel@tonic-gate 
12107c478bd9Sstevel@tonic-gate 		i = slotnum + PS0;
12117c478bd9Sstevel@tonic-gate 
12127c478bd9Sstevel@tonic-gate 		/* Make sure it's in /platform and create the frutree node */
12137c478bd9Sstevel@tonic-gate 		if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
12147c478bd9Sstevel@tonic-gate 		    PICL_SUCCESS) {
12157c478bd9Sstevel@tonic-gate 			err = ptree_create_node("power-supply", "fru",
12167c478bd9Sstevel@tonic-gate 			    &powermodh);
12177c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
12187c478bd9Sstevel@tonic-gate 				return (err);
12197c478bd9Sstevel@tonic-gate 
12207c478bd9Sstevel@tonic-gate 			err = add_ref_prop(powermodh, tmph, SEEPROM_SOURCE);
12217c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
12227c478bd9Sstevel@tonic-gate 				return (err);
12237c478bd9Sstevel@tonic-gate 
12247c478bd9Sstevel@tonic-gate 			err = add_void_fda_prop(powermodh);
12257c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
12267c478bd9Sstevel@tonic-gate 				return (err);
12277c478bd9Sstevel@tonic-gate 
12287c478bd9Sstevel@tonic-gate 			err = ptree_add_node(powersloth, powermodh);
12297c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
12307c478bd9Sstevel@tonic-gate 				return (err);
12317c478bd9Sstevel@tonic-gate 
12327c478bd9Sstevel@tonic-gate 			err = add_ref_prop(tmph, powermodh, FRU_PARENT);
12337c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
12347c478bd9Sstevel@tonic-gate 				return (err);
12357c478bd9Sstevel@tonic-gate 
12367c478bd9Sstevel@tonic-gate 			/* Post picl-fru-added event */
1237*ada2da53SToomas Soome 			post_frudr_event(PICL_FRU_ADDED, 0, powermodh);
12387c478bd9Sstevel@tonic-gate 		}
12397c478bd9Sstevel@tonic-gate 	}
12407c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
12417c478bd9Sstevel@tonic-gate }
12427c478bd9Sstevel@tonic-gate 
12437c478bd9Sstevel@tonic-gate /* Hotplug routine used to remove an existing power supply */
12447c478bd9Sstevel@tonic-gate static int
remove_power_supply(int slotnum)12457c478bd9Sstevel@tonic-gate remove_power_supply(int slotnum)
12467c478bd9Sstevel@tonic-gate {
12477c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		powersloth;
12487c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		powermodh;
12497c478bd9Sstevel@tonic-gate 	int			err;
12507c478bd9Sstevel@tonic-gate 
12517c478bd9Sstevel@tonic-gate 	/* Find the node for the given power supply slot */
12527c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(frutree_power_supply[slotnum],
12537c478bd9Sstevel@tonic-gate 	    &powersloth) == PICL_SUCCESS) {
12547c478bd9Sstevel@tonic-gate 		/* Make sure it's got a child, then delete it */
12557c478bd9Sstevel@tonic-gate 		err = ptree_get_propval_by_name(powersloth, PICL_PROP_CHILD,
12567c478bd9Sstevel@tonic-gate 		    &powermodh, sizeof (picl_nodehdl_t));
12577c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS) {
12587c478bd9Sstevel@tonic-gate 			return (err);
12597c478bd9Sstevel@tonic-gate 		}
12607c478bd9Sstevel@tonic-gate 
12617c478bd9Sstevel@tonic-gate 		err = ptree_delete_node(powermodh);
12627c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS) {
12637c478bd9Sstevel@tonic-gate 			return (err);
12647c478bd9Sstevel@tonic-gate 		} else {
12657c478bd9Sstevel@tonic-gate 			(void) ptree_destroy_node(powermodh);
12667c478bd9Sstevel@tonic-gate 		}
12677c478bd9Sstevel@tonic-gate 
12687c478bd9Sstevel@tonic-gate 		/* Post picl-fru-removed event */
1269*ada2da53SToomas Soome 		post_frudr_event(PICL_FRU_REMOVED, 0, powermodh);
12707c478bd9Sstevel@tonic-gate 
12717c478bd9Sstevel@tonic-gate 	}
12727c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
12737c478bd9Sstevel@tonic-gate }
12747c478bd9Sstevel@tonic-gate 
12757c478bd9Sstevel@tonic-gate /* Hotplug routine used to add a new CPU Mem Module (with associated DIMMs) */
12767c478bd9Sstevel@tonic-gate static int
add_cpu_module(int slotnum)12777c478bd9Sstevel@tonic-gate add_cpu_module(int slotnum)
12787c478bd9Sstevel@tonic-gate {
12797c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		cpumemsloth;
12807c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		cpumemmodh;
12817c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
12827c478bd9Sstevel@tonic-gate 	int			i, err;
12837c478bd9Sstevel@tonic-gate 
12847c478bd9Sstevel@tonic-gate 	/* Find the node for the given CPU Memory module slot */
12857c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(frutree_cpu_module[slotnum],
12867c478bd9Sstevel@tonic-gate 	    &cpumemsloth) == PICL_SUCCESS) {
12877c478bd9Sstevel@tonic-gate 
12887c478bd9Sstevel@tonic-gate 		i = slotnum + CPUMOD0;
12897c478bd9Sstevel@tonic-gate 
12907c478bd9Sstevel@tonic-gate 		/* Make sure it's in /platform and create the frutree nodes */
12917c478bd9Sstevel@tonic-gate 		if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
12927c478bd9Sstevel@tonic-gate 		    PICL_SUCCESS) {
12937c478bd9Sstevel@tonic-gate 			err = ptree_create_node("cpu-mem-module", "fru",
12947c478bd9Sstevel@tonic-gate 			    &cpumemmodh);
12957c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
12967c478bd9Sstevel@tonic-gate 				return (err);
12977c478bd9Sstevel@tonic-gate 
12987c478bd9Sstevel@tonic-gate 			err = add_ref_prop(cpumemmodh, tmph, SEEPROM_SOURCE);
12997c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
13007c478bd9Sstevel@tonic-gate 				return (err);
13017c478bd9Sstevel@tonic-gate 
13027c478bd9Sstevel@tonic-gate 			err = add_void_fda_prop(cpumemmodh);
13037c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
13047c478bd9Sstevel@tonic-gate 				return (err);
13057c478bd9Sstevel@tonic-gate 
13067c478bd9Sstevel@tonic-gate 			err = ptree_add_node(cpumemsloth, cpumemmodh);
13077c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
13087c478bd9Sstevel@tonic-gate 				return (err);
13097c478bd9Sstevel@tonic-gate 
13107c478bd9Sstevel@tonic-gate 			err = add_ref_prop(tmph, cpumemmodh, FRU_PARENT);
13117c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
13127c478bd9Sstevel@tonic-gate 				return (err);
13137c478bd9Sstevel@tonic-gate 		}
13147c478bd9Sstevel@tonic-gate 
13157c478bd9Sstevel@tonic-gate 		err = do_cpu_module_init(cpumemmodh, slotnum);
13167c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
13177c478bd9Sstevel@tonic-gate 			return (err);
13187c478bd9Sstevel@tonic-gate 	}
13197c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
13207c478bd9Sstevel@tonic-gate }
13217c478bd9Sstevel@tonic-gate 
13227c478bd9Sstevel@tonic-gate /* Hotplug routine used to remove an existing CPU Mem Module */
13237c478bd9Sstevel@tonic-gate static int
remove_cpu_module(int slotnum)13247c478bd9Sstevel@tonic-gate remove_cpu_module(int slotnum)
13257c478bd9Sstevel@tonic-gate {
13267c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		cpumemsloth;
13277c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		cpumemmodh;
13287c478bd9Sstevel@tonic-gate 	int			err;
13297c478bd9Sstevel@tonic-gate 
13307c478bd9Sstevel@tonic-gate 	/* Find the node for the given CPU Memory module slot */
13317c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(frutree_cpu_module[slotnum],
13327c478bd9Sstevel@tonic-gate 	    &cpumemsloth) == PICL_SUCCESS) {
13337c478bd9Sstevel@tonic-gate 		/* Make sure it's got a child, then delete it */
13347c478bd9Sstevel@tonic-gate 		err = ptree_get_propval_by_name(cpumemsloth, PICL_PROP_CHILD,
13357c478bd9Sstevel@tonic-gate 		    &cpumemmodh, sizeof (picl_nodehdl_t));
13367c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS) {
13377c478bd9Sstevel@tonic-gate 			return (err);
13387c478bd9Sstevel@tonic-gate 		}
13397c478bd9Sstevel@tonic-gate 
13407c478bd9Sstevel@tonic-gate 		err = remove_all_nodes(cpumemmodh);
13417c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS) {
13427c478bd9Sstevel@tonic-gate 			return (err);
13437c478bd9Sstevel@tonic-gate 		}
13447c478bd9Sstevel@tonic-gate 	}
13457c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
13467c478bd9Sstevel@tonic-gate }
1347