1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate  * All rights reserved.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*
28*7c478bd9Sstevel@tonic-gate  * PICL plug-in that creates the FRU Hierarchy for the
29*7c478bd9Sstevel@tonic-gate  * SUNW,Sun-Fire-280R (Littleneck) platform
30*7c478bd9Sstevel@tonic-gate  */
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #include <stdio.h>
33*7c478bd9Sstevel@tonic-gate #include <string.h>
34*7c478bd9Sstevel@tonic-gate #include <libintl.h>
35*7c478bd9Sstevel@tonic-gate #include <syslog.h>
36*7c478bd9Sstevel@tonic-gate #include <picl.h>
37*7c478bd9Sstevel@tonic-gate #include <picltree.h>
38*7c478bd9Sstevel@tonic-gate #include <picldefs.h>
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate /*
41*7c478bd9Sstevel@tonic-gate  * Plugin registration entry points
42*7c478bd9Sstevel@tonic-gate  */
43*7c478bd9Sstevel@tonic-gate static void	picl_frutree_register(void);
44*7c478bd9Sstevel@tonic-gate static void	picl_frutree_init(void);
45*7c478bd9Sstevel@tonic-gate static void	picl_frutree_fini(void);
46*7c478bd9Sstevel@tonic-gate static void	picl_frutree_evhandler(const char *ename, const void *earg,
47*7c478bd9Sstevel@tonic-gate 		    size_t size, void *cookie);
48*7c478bd9Sstevel@tonic-gate 
49*7c478bd9Sstevel@tonic-gate #pragma	init(picl_frutree_register)
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate /*
52*7c478bd9Sstevel@tonic-gate  * Log message texts
53*7c478bd9Sstevel@tonic-gate  */
54*7c478bd9Sstevel@tonic-gate #define	CREATE_FRUTREE_FAIL	gettext("Failed to create frutree node\n")
55*7c478bd9Sstevel@tonic-gate #define	CREATE_CHASSIS_FAIL	gettext("Failed to create chassis node\n")
56*7c478bd9Sstevel@tonic-gate #define	SYSBRD_INIT_FAIL	gettext("do_sysboard_init() failed\n")
57*7c478bd9Sstevel@tonic-gate #define	CPUS_INIT_FAIL		gettext("do_cpus_init() failed\n")
58*7c478bd9Sstevel@tonic-gate #define	DIMMS_INIT_FAIL		gettext("do_mem_init() failed\n")
59*7c478bd9Sstevel@tonic-gate #define	PS_INIT_FAIL		gettext("do_power_supplies_init() failed\n")
60*7c478bd9Sstevel@tonic-gate #define	FCAL_INIT_FAIL		gettext("do_fcal_init() failed\n")
61*7c478bd9Sstevel@tonic-gate #define	RSC_INIT_FAIL		gettext("do_rscboard_init() failed\n")
62*7c478bd9Sstevel@tonic-gate 
63*7c478bd9Sstevel@tonic-gate /*
64*7c478bd9Sstevel@tonic-gate  * ViewPoints property field used by SunMC
65*7c478bd9Sstevel@tonic-gate  */
66*7c478bd9Sstevel@tonic-gate #define	CHASSIS_VIEWPOINTS	gettext("front top rear")
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate /*
69*7c478bd9Sstevel@tonic-gate  * Ref prop values
70*7c478bd9Sstevel@tonic-gate  */
71*7c478bd9Sstevel@tonic-gate #define	SEEPROM_SOURCE		"_seeprom_source"
72*7c478bd9Sstevel@tonic-gate #define	FRU_PARENT		"_fru_parent"
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate /*
75*7c478bd9Sstevel@tonic-gate  * List of all the FRU locations in the platform_frupath[] array, and
76*7c478bd9Sstevel@tonic-gate  * location_label[] array
77*7c478bd9Sstevel@tonic-gate  */
78*7c478bd9Sstevel@tonic-gate #define	CPU0	0
79*7c478bd9Sstevel@tonic-gate #define	CPU1	1
80*7c478bd9Sstevel@tonic-gate #define	DIMM0	2
81*7c478bd9Sstevel@tonic-gate #define	DIMM1	3
82*7c478bd9Sstevel@tonic-gate #define	DIMM2	4
83*7c478bd9Sstevel@tonic-gate #define	DIMM3	5
84*7c478bd9Sstevel@tonic-gate #define	DIMM4	6
85*7c478bd9Sstevel@tonic-gate #define	DIMM5	7
86*7c478bd9Sstevel@tonic-gate #define	DIMM6	8
87*7c478bd9Sstevel@tonic-gate #define	DIMM7	9
88*7c478bd9Sstevel@tonic-gate #define	PDB	10
89*7c478bd9Sstevel@tonic-gate #define	PS0	11
90*7c478bd9Sstevel@tonic-gate #define	PS1	12
91*7c478bd9Sstevel@tonic-gate #define	FCAL	13
92*7c478bd9Sstevel@tonic-gate #define	RSC	14
93*7c478bd9Sstevel@tonic-gate #define	SYSBRD	15
94*7c478bd9Sstevel@tonic-gate 
95*7c478bd9Sstevel@tonic-gate /*
96*7c478bd9Sstevel@tonic-gate  * Local variables
97*7c478bd9Sstevel@tonic-gate  */
98*7c478bd9Sstevel@tonic-gate static picld_plugin_reg_t  my_reg_info = {
99*7c478bd9Sstevel@tonic-gate 	PICLD_PLUGIN_VERSION_1,
100*7c478bd9Sstevel@tonic-gate 	PICLD_PLUGIN_NON_CRITICAL,
101*7c478bd9Sstevel@tonic-gate 	"SUNW_Sun-Fire-280R_frutree",
102*7c478bd9Sstevel@tonic-gate 	picl_frutree_init,
103*7c478bd9Sstevel@tonic-gate 	picl_frutree_fini,
104*7c478bd9Sstevel@tonic-gate };
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate /*
107*7c478bd9Sstevel@tonic-gate  * List of all the FRUs in the /platform tree with SEEPROMs
108*7c478bd9Sstevel@tonic-gate  */
109*7c478bd9Sstevel@tonic-gate static char *platform_frupath[] = {
110*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,30/cpu-fru@0,a0",
111*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,30/cpu-fru@0,a2",
112*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,a0",
113*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,a2",
114*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,a4",
115*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,a6",
116*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,a8",
117*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,aa",
118*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,ac",
119*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,ae",
120*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,30/power-distribution-board@0,aa",
121*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,30/power-supply@0,ac",
122*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,30/power-supply@0,ae",
123*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,30/fcal-backplane@0,a4",
124*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,30/remote-system-console@0,a6",
125*7c478bd9Sstevel@tonic-gate 	"/platform/pci@8,700000/ebus@5/i2c@1,30/motherboard-fru@0,a8",
126*7c478bd9Sstevel@tonic-gate 	NULL};
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate /*
129*7c478bd9Sstevel@tonic-gate  * List of all the FRU slots in the frutree that can be hotplugged
130*7c478bd9Sstevel@tonic-gate  */
131*7c478bd9Sstevel@tonic-gate static char *frutree_power_supply[] = {
132*7c478bd9Sstevel@tonic-gate 	"/frutree/chassis/power-dist-board/power-supply-slot?Slot=0",
133*7c478bd9Sstevel@tonic-gate 	"/frutree/chassis/power-dist-board/power-supply-slot?Slot=1",
134*7c478bd9Sstevel@tonic-gate 	NULL};
135*7c478bd9Sstevel@tonic-gate 
136*7c478bd9Sstevel@tonic-gate /*
137*7c478bd9Sstevel@tonic-gate  * List of Labels for FRU locations (uses the #define's from above)
138*7c478bd9Sstevel@tonic-gate  */
139*7c478bd9Sstevel@tonic-gate static char *location_label[] = {
140*7c478bd9Sstevel@tonic-gate 	"0",
141*7c478bd9Sstevel@tonic-gate 	"1",
142*7c478bd9Sstevel@tonic-gate 	"J0100",
143*7c478bd9Sstevel@tonic-gate 	"J0101",
144*7c478bd9Sstevel@tonic-gate 	"J0202",
145*7c478bd9Sstevel@tonic-gate 	"J0203",
146*7c478bd9Sstevel@tonic-gate 	"J0304",
147*7c478bd9Sstevel@tonic-gate 	"J0305",
148*7c478bd9Sstevel@tonic-gate 	"J0406",
149*7c478bd9Sstevel@tonic-gate 	"J0407",
150*7c478bd9Sstevel@tonic-gate 	NULL,			/* power distribution board placeholder */
151*7c478bd9Sstevel@tonic-gate 	"0",
152*7c478bd9Sstevel@tonic-gate 	"1",
153*7c478bd9Sstevel@tonic-gate 	NULL};
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate /* PICL handle for the root node of the "frutree" */
156*7c478bd9Sstevel@tonic-gate static picl_nodehdl_t	frutreeh;
157*7c478bd9Sstevel@tonic-gate 
158*7c478bd9Sstevel@tonic-gate static int	do_sysboard_init(picl_nodehdl_t, picl_nodehdl_t *);
159*7c478bd9Sstevel@tonic-gate static int	do_cpus_init(picl_nodehdl_t);
160*7c478bd9Sstevel@tonic-gate static int	do_mem_init(picl_nodehdl_t);
161*7c478bd9Sstevel@tonic-gate static int	do_power_supplies_init(picl_nodehdl_t);
162*7c478bd9Sstevel@tonic-gate static int	do_fcal_init(picl_nodehdl_t);
163*7c478bd9Sstevel@tonic-gate static int	do_rscboard_init(picl_nodehdl_t);
164*7c478bd9Sstevel@tonic-gate 
165*7c478bd9Sstevel@tonic-gate static int	add_ref_prop(picl_nodehdl_t, picl_nodehdl_t, char *);
166*7c478bd9Sstevel@tonic-gate static int	add_slot_prop(picl_nodehdl_t, int);
167*7c478bd9Sstevel@tonic-gate static int	add_label_prop(picl_nodehdl_t, char *);
168*7c478bd9Sstevel@tonic-gate static int	add_void_fda_prop(picl_nodehdl_t);
169*7c478bd9Sstevel@tonic-gate static int	add_viewpoints_prop(picl_nodehdl_t, char *);
170*7c478bd9Sstevel@tonic-gate static int	add_all_nodes();
171*7c478bd9Sstevel@tonic-gate static int	remove_all_nodes(picl_nodehdl_t);
172*7c478bd9Sstevel@tonic-gate 
173*7c478bd9Sstevel@tonic-gate static int	add_hotplug_fru_device(void);
174*7c478bd9Sstevel@tonic-gate static int	rem_hotplug_fru_device(void);
175*7c478bd9Sstevel@tonic-gate static int	is_added_device(char *, char *);
176*7c478bd9Sstevel@tonic-gate static int	is_removed_device(char *, char *);
177*7c478bd9Sstevel@tonic-gate static int	add_power_supply(int);
178*7c478bd9Sstevel@tonic-gate static int	remove_power_supply(int);
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate /*
181*7c478bd9Sstevel@tonic-gate  * This function is executed as part of .init when the plugin is
182*7c478bd9Sstevel@tonic-gate  * dlopen()ed
183*7c478bd9Sstevel@tonic-gate  */
184*7c478bd9Sstevel@tonic-gate void
picl_frutree_register()185*7c478bd9Sstevel@tonic-gate picl_frutree_register()
186*7c478bd9Sstevel@tonic-gate {
187*7c478bd9Sstevel@tonic-gate 	(void) picld_plugin_register(&my_reg_info);
188*7c478bd9Sstevel@tonic-gate }
189*7c478bd9Sstevel@tonic-gate 
190*7c478bd9Sstevel@tonic-gate /*
191*7c478bd9Sstevel@tonic-gate  * This function is the init entry point of the plugin.
192*7c478bd9Sstevel@tonic-gate  * It initializes the /frutree tree
193*7c478bd9Sstevel@tonic-gate  */
194*7c478bd9Sstevel@tonic-gate void
picl_frutree_init()195*7c478bd9Sstevel@tonic-gate picl_frutree_init()
196*7c478bd9Sstevel@tonic-gate {
197*7c478bd9Sstevel@tonic-gate 	int		err;
198*7c478bd9Sstevel@tonic-gate 
199*7c478bd9Sstevel@tonic-gate 	err = add_all_nodes();
200*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
201*7c478bd9Sstevel@tonic-gate 		(void) remove_all_nodes(frutreeh);
202*7c478bd9Sstevel@tonic-gate 		return;
203*7c478bd9Sstevel@tonic-gate 	}
204*7c478bd9Sstevel@tonic-gate 
205*7c478bd9Sstevel@tonic-gate 	/* Register the event handler routine */
206*7c478bd9Sstevel@tonic-gate 	(void) ptree_register_handler(PICLEVENT_SYSEVENT_DEVICE_ADDED,
207*7c478bd9Sstevel@tonic-gate 	    picl_frutree_evhandler, NULL);
208*7c478bd9Sstevel@tonic-gate 	(void) ptree_register_handler(PICLEVENT_SYSEVENT_DEVICE_REMOVED,
209*7c478bd9Sstevel@tonic-gate 	    picl_frutree_evhandler, NULL);
210*7c478bd9Sstevel@tonic-gate }
211*7c478bd9Sstevel@tonic-gate 
212*7c478bd9Sstevel@tonic-gate /*
213*7c478bd9Sstevel@tonic-gate  * This function is the fini entry point of the plugin
214*7c478bd9Sstevel@tonic-gate  */
215*7c478bd9Sstevel@tonic-gate void
picl_frutree_fini(void)216*7c478bd9Sstevel@tonic-gate picl_frutree_fini(void)
217*7c478bd9Sstevel@tonic-gate {
218*7c478bd9Sstevel@tonic-gate 	/* Unregister the event handler routine */
219*7c478bd9Sstevel@tonic-gate 	(void) ptree_unregister_handler(PICLEVENT_SYSEVENT_DEVICE_ADDED,
220*7c478bd9Sstevel@tonic-gate 	    picl_frutree_evhandler, NULL);
221*7c478bd9Sstevel@tonic-gate 	(void) ptree_unregister_handler(PICLEVENT_SYSEVENT_DEVICE_REMOVED,
222*7c478bd9Sstevel@tonic-gate 	    picl_frutree_evhandler, NULL);
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate 	(void) remove_all_nodes(frutreeh);
225*7c478bd9Sstevel@tonic-gate }
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate /*
228*7c478bd9Sstevel@tonic-gate  * This function is the event handler of this plug-in.
229*7c478bd9Sstevel@tonic-gate  *
230*7c478bd9Sstevel@tonic-gate  * It processes the following events:
231*7c478bd9Sstevel@tonic-gate  *
232*7c478bd9Sstevel@tonic-gate  *	PICLEVENT_SYSEVENT_DEVICE_ADDED
233*7c478bd9Sstevel@tonic-gate  *	PICLEVENT_SYSEVENT_DEVICE_REMOVED
234*7c478bd9Sstevel@tonic-gate  */
235*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
236*7c478bd9Sstevel@tonic-gate static void
picl_frutree_evhandler(const char * ename,const void * earg,size_t size,void * cookie)237*7c478bd9Sstevel@tonic-gate picl_frutree_evhandler(const char *ename, const void *earg, size_t size,
238*7c478bd9Sstevel@tonic-gate     void *cookie)
239*7c478bd9Sstevel@tonic-gate {
240*7c478bd9Sstevel@tonic-gate 	if (strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_ADDED) == 0) {
241*7c478bd9Sstevel@tonic-gate 		/* Check for and add any hotplugged device(s) */
242*7c478bd9Sstevel@tonic-gate 		(void) add_hotplug_fru_device();
243*7c478bd9Sstevel@tonic-gate 
244*7c478bd9Sstevel@tonic-gate 	} else if (strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_REMOVED) == 0) {
245*7c478bd9Sstevel@tonic-gate 		/* Check for and remove any hotplugged device(s) */
246*7c478bd9Sstevel@tonic-gate 		(void) rem_hotplug_fru_device();
247*7c478bd9Sstevel@tonic-gate 	}
248*7c478bd9Sstevel@tonic-gate }
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate /* Initialize the FRU node for the system board */
251*7c478bd9Sstevel@tonic-gate static int
do_sysboard_init(picl_nodehdl_t rooth,picl_nodehdl_t * childh)252*7c478bd9Sstevel@tonic-gate do_sysboard_init(picl_nodehdl_t rooth, picl_nodehdl_t *childh)
253*7c478bd9Sstevel@tonic-gate {
254*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
255*7c478bd9Sstevel@tonic-gate 	int			err;
256*7c478bd9Sstevel@tonic-gate 
257*7c478bd9Sstevel@tonic-gate 	/* Create the node for the system board */
258*7c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(platform_frupath[SYSBRD], &tmph) ==
259*7c478bd9Sstevel@tonic-gate 	    PICL_SUCCESS) {
260*7c478bd9Sstevel@tonic-gate 		err = ptree_create_node("system-board", "fru", childh);
261*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
262*7c478bd9Sstevel@tonic-gate 			return (err);
263*7c478bd9Sstevel@tonic-gate 
264*7c478bd9Sstevel@tonic-gate 		err = add_ref_prop(*childh, tmph, SEEPROM_SOURCE);
265*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
266*7c478bd9Sstevel@tonic-gate 			return (err);
267*7c478bd9Sstevel@tonic-gate 
268*7c478bd9Sstevel@tonic-gate 		err = add_void_fda_prop(*childh);
269*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
270*7c478bd9Sstevel@tonic-gate 			return (err);
271*7c478bd9Sstevel@tonic-gate 
272*7c478bd9Sstevel@tonic-gate 		err = ptree_add_node(rooth, *childh);
273*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
274*7c478bd9Sstevel@tonic-gate 			return (err);
275*7c478bd9Sstevel@tonic-gate 
276*7c478bd9Sstevel@tonic-gate 		err = add_ref_prop(tmph, *childh, FRU_PARENT);
277*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
278*7c478bd9Sstevel@tonic-gate 			return (err);
279*7c478bd9Sstevel@tonic-gate 
280*7c478bd9Sstevel@tonic-gate 	}
281*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
282*7c478bd9Sstevel@tonic-gate }
283*7c478bd9Sstevel@tonic-gate 
284*7c478bd9Sstevel@tonic-gate /* Initializes the FRU nodes for the CPU modules */
285*7c478bd9Sstevel@tonic-gate static int
do_cpus_init(picl_nodehdl_t rooth)286*7c478bd9Sstevel@tonic-gate do_cpus_init(picl_nodehdl_t rooth)
287*7c478bd9Sstevel@tonic-gate {
288*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		cpusloth;
289*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		cpumodh;
290*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
291*7c478bd9Sstevel@tonic-gate 	int			i, err;
292*7c478bd9Sstevel@tonic-gate 
293*7c478bd9Sstevel@tonic-gate 	for (i = CPU0; i <= CPU1; i++) {
294*7c478bd9Sstevel@tonic-gate 		/* Create the node for the CPU slot */
295*7c478bd9Sstevel@tonic-gate 		err = ptree_create_node("cpu-slot", "location", &cpusloth);
296*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
297*7c478bd9Sstevel@tonic-gate 			return (err);
298*7c478bd9Sstevel@tonic-gate 
299*7c478bd9Sstevel@tonic-gate 		err = add_slot_prop(cpusloth, i);
300*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
301*7c478bd9Sstevel@tonic-gate 			return (err);
302*7c478bd9Sstevel@tonic-gate 
303*7c478bd9Sstevel@tonic-gate 		err = add_label_prop(cpusloth, location_label[i]);
304*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
305*7c478bd9Sstevel@tonic-gate 			return (err);
306*7c478bd9Sstevel@tonic-gate 
307*7c478bd9Sstevel@tonic-gate 		err = ptree_add_node(rooth, cpusloth);
308*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
309*7c478bd9Sstevel@tonic-gate 			return (err);
310*7c478bd9Sstevel@tonic-gate 
311*7c478bd9Sstevel@tonic-gate 		/* If the CPU module exists, create a node for it */
312*7c478bd9Sstevel@tonic-gate 		if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
313*7c478bd9Sstevel@tonic-gate 		    PICL_SUCCESS) {
314*7c478bd9Sstevel@tonic-gate 			err = ptree_create_node("cpu-module", "fru", &cpumodh);
315*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
316*7c478bd9Sstevel@tonic-gate 				return (err);
317*7c478bd9Sstevel@tonic-gate 
318*7c478bd9Sstevel@tonic-gate 			err = add_ref_prop(cpumodh, tmph, SEEPROM_SOURCE);
319*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
320*7c478bd9Sstevel@tonic-gate 				return (err);
321*7c478bd9Sstevel@tonic-gate 
322*7c478bd9Sstevel@tonic-gate 			err = add_void_fda_prop(cpumodh);
323*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
324*7c478bd9Sstevel@tonic-gate 				return (err);
325*7c478bd9Sstevel@tonic-gate 
326*7c478bd9Sstevel@tonic-gate 			err = ptree_add_node(cpusloth, cpumodh);
327*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
328*7c478bd9Sstevel@tonic-gate 				return (err);
329*7c478bd9Sstevel@tonic-gate 
330*7c478bd9Sstevel@tonic-gate 			err = add_ref_prop(tmph, cpumodh, FRU_PARENT);
331*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
332*7c478bd9Sstevel@tonic-gate 				return (err);
333*7c478bd9Sstevel@tonic-gate 		}
334*7c478bd9Sstevel@tonic-gate 	}
335*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
336*7c478bd9Sstevel@tonic-gate }
337*7c478bd9Sstevel@tonic-gate 
338*7c478bd9Sstevel@tonic-gate /* Initializes the FRU nodes for the memory modules */
339*7c478bd9Sstevel@tonic-gate static int
do_mem_init(picl_nodehdl_t rooth)340*7c478bd9Sstevel@tonic-gate do_mem_init(picl_nodehdl_t rooth)
341*7c478bd9Sstevel@tonic-gate {
342*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		memsloth;
343*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		memmodh;
344*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
345*7c478bd9Sstevel@tonic-gate 	int			i, err, slotnum;
346*7c478bd9Sstevel@tonic-gate 
347*7c478bd9Sstevel@tonic-gate 	for (i = DIMM0; i <= DIMM7; i++) {
348*7c478bd9Sstevel@tonic-gate 		/* Create the node for the memory slot */
349*7c478bd9Sstevel@tonic-gate 		err = ptree_create_node("mem-slot", "location", &memsloth);
350*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
351*7c478bd9Sstevel@tonic-gate 			return (err);
352*7c478bd9Sstevel@tonic-gate 
353*7c478bd9Sstevel@tonic-gate 		slotnum = i - DIMM0;
354*7c478bd9Sstevel@tonic-gate 		err = add_slot_prop(memsloth, slotnum);
355*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
356*7c478bd9Sstevel@tonic-gate 			return (err);
357*7c478bd9Sstevel@tonic-gate 
358*7c478bd9Sstevel@tonic-gate 		err = add_label_prop(memsloth, location_label[i]);
359*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
360*7c478bd9Sstevel@tonic-gate 			return (err);
361*7c478bd9Sstevel@tonic-gate 
362*7c478bd9Sstevel@tonic-gate 		err = ptree_add_node(rooth, memsloth);
363*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
364*7c478bd9Sstevel@tonic-gate 			return (err);
365*7c478bd9Sstevel@tonic-gate 
366*7c478bd9Sstevel@tonic-gate 		/* If the memory exists, create a node for it */
367*7c478bd9Sstevel@tonic-gate 		if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
368*7c478bd9Sstevel@tonic-gate 		    PICL_SUCCESS) {
369*7c478bd9Sstevel@tonic-gate 			err = ptree_create_node("mem-module", "fru", &memmodh);
370*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
371*7c478bd9Sstevel@tonic-gate 				return (err);
372*7c478bd9Sstevel@tonic-gate 
373*7c478bd9Sstevel@tonic-gate 			err = add_ref_prop(memmodh, tmph, SEEPROM_SOURCE);
374*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
375*7c478bd9Sstevel@tonic-gate 				return (err);
376*7c478bd9Sstevel@tonic-gate 
377*7c478bd9Sstevel@tonic-gate 			err = add_void_fda_prop(memmodh);
378*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
379*7c478bd9Sstevel@tonic-gate 				return (err);
380*7c478bd9Sstevel@tonic-gate 
381*7c478bd9Sstevel@tonic-gate 			err = ptree_add_node(memsloth, memmodh);
382*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
383*7c478bd9Sstevel@tonic-gate 				return (err);
384*7c478bd9Sstevel@tonic-gate 
385*7c478bd9Sstevel@tonic-gate 			err = add_ref_prop(tmph, memmodh, FRU_PARENT);
386*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
387*7c478bd9Sstevel@tonic-gate 				return (err);
388*7c478bd9Sstevel@tonic-gate 		}
389*7c478bd9Sstevel@tonic-gate 	}
390*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
391*7c478bd9Sstevel@tonic-gate }
392*7c478bd9Sstevel@tonic-gate 
393*7c478bd9Sstevel@tonic-gate /* Initializes the FRU nodes for the PDB and the power supplies */
394*7c478bd9Sstevel@tonic-gate static int
do_power_supplies_init(picl_nodehdl_t rooth)395*7c478bd9Sstevel@tonic-gate do_power_supplies_init(picl_nodehdl_t rooth)
396*7c478bd9Sstevel@tonic-gate {
397*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		powerbrdh;
398*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		powersloth;
399*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		powermodh;
400*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
401*7c478bd9Sstevel@tonic-gate 	int			i, err, slotnum;
402*7c478bd9Sstevel@tonic-gate 
403*7c478bd9Sstevel@tonic-gate 	/* Create the node for the PDB (if it exists) */
404*7c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(platform_frupath[PDB], &tmph) ==
405*7c478bd9Sstevel@tonic-gate 	    PICL_SUCCESS) {
406*7c478bd9Sstevel@tonic-gate 		err = ptree_create_node("power-dist-board", "fru", &powerbrdh);
407*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
408*7c478bd9Sstevel@tonic-gate 			return (err);
409*7c478bd9Sstevel@tonic-gate 
410*7c478bd9Sstevel@tonic-gate 		err = add_ref_prop(powerbrdh, tmph, SEEPROM_SOURCE);
411*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
412*7c478bd9Sstevel@tonic-gate 			return (err);
413*7c478bd9Sstevel@tonic-gate 
414*7c478bd9Sstevel@tonic-gate 		err = add_void_fda_prop(powerbrdh);
415*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
416*7c478bd9Sstevel@tonic-gate 			return (err);
417*7c478bd9Sstevel@tonic-gate 
418*7c478bd9Sstevel@tonic-gate 		err = ptree_add_node(rooth, powerbrdh);
419*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
420*7c478bd9Sstevel@tonic-gate 			return (err);
421*7c478bd9Sstevel@tonic-gate 
422*7c478bd9Sstevel@tonic-gate 		err = add_ref_prop(tmph, powerbrdh, FRU_PARENT);
423*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
424*7c478bd9Sstevel@tonic-gate 			return (err);
425*7c478bd9Sstevel@tonic-gate 
426*7c478bd9Sstevel@tonic-gate 		for (i = PS0; i <= PS1; i++) {
427*7c478bd9Sstevel@tonic-gate 			/* Create the node for the power supply slot */
428*7c478bd9Sstevel@tonic-gate 			err = ptree_create_node("power-supply-slot",
429*7c478bd9Sstevel@tonic-gate 			    "location", &powersloth);
430*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
431*7c478bd9Sstevel@tonic-gate 				return (err);
432*7c478bd9Sstevel@tonic-gate 
433*7c478bd9Sstevel@tonic-gate 			slotnum = i - PS0;
434*7c478bd9Sstevel@tonic-gate 			err = add_slot_prop(powersloth, slotnum);
435*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
436*7c478bd9Sstevel@tonic-gate 				return (err);
437*7c478bd9Sstevel@tonic-gate 
438*7c478bd9Sstevel@tonic-gate 			err = add_label_prop(powersloth, location_label[i]);
439*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
440*7c478bd9Sstevel@tonic-gate 				return (err);
441*7c478bd9Sstevel@tonic-gate 
442*7c478bd9Sstevel@tonic-gate 			err = ptree_add_node(powerbrdh, powersloth);
443*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
444*7c478bd9Sstevel@tonic-gate 				return (err);
445*7c478bd9Sstevel@tonic-gate 
446*7c478bd9Sstevel@tonic-gate 			/* If the PS exists, create a node for it */
447*7c478bd9Sstevel@tonic-gate 			if (ptree_get_node_by_path(platform_frupath[i],
448*7c478bd9Sstevel@tonic-gate 			    &tmph) == PICL_SUCCESS) {
449*7c478bd9Sstevel@tonic-gate 				err = ptree_create_node("power-supply",
450*7c478bd9Sstevel@tonic-gate 				    "fru", &powermodh);
451*7c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
452*7c478bd9Sstevel@tonic-gate 					return (err);
453*7c478bd9Sstevel@tonic-gate 
454*7c478bd9Sstevel@tonic-gate 				err = add_ref_prop(powermodh, tmph,
455*7c478bd9Sstevel@tonic-gate 				    SEEPROM_SOURCE);
456*7c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
457*7c478bd9Sstevel@tonic-gate 					return (err);
458*7c478bd9Sstevel@tonic-gate 
459*7c478bd9Sstevel@tonic-gate 				err = add_void_fda_prop(powermodh);
460*7c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
461*7c478bd9Sstevel@tonic-gate 					return (err);
462*7c478bd9Sstevel@tonic-gate 
463*7c478bd9Sstevel@tonic-gate 				err = ptree_add_node(powersloth, powermodh);
464*7c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
465*7c478bd9Sstevel@tonic-gate 					return (err);
466*7c478bd9Sstevel@tonic-gate 
467*7c478bd9Sstevel@tonic-gate 				err = add_ref_prop(tmph, powermodh, FRU_PARENT);
468*7c478bd9Sstevel@tonic-gate 				if (err != PICL_SUCCESS)
469*7c478bd9Sstevel@tonic-gate 					return (err);
470*7c478bd9Sstevel@tonic-gate 			}
471*7c478bd9Sstevel@tonic-gate 		}
472*7c478bd9Sstevel@tonic-gate 	}
473*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
474*7c478bd9Sstevel@tonic-gate }
475*7c478bd9Sstevel@tonic-gate 
476*7c478bd9Sstevel@tonic-gate /* Initializes the FRU nodes for the FCAL backplane */
477*7c478bd9Sstevel@tonic-gate static int
do_fcal_init(picl_nodehdl_t rooth)478*7c478bd9Sstevel@tonic-gate do_fcal_init(picl_nodehdl_t rooth)
479*7c478bd9Sstevel@tonic-gate {
480*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		fcalbrdh;
481*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
482*7c478bd9Sstevel@tonic-gate 	int			err;
483*7c478bd9Sstevel@tonic-gate 
484*7c478bd9Sstevel@tonic-gate 	/* Create the node for the FCAL backplane (if it exists) */
485*7c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(platform_frupath[FCAL], &tmph) ==
486*7c478bd9Sstevel@tonic-gate 	    PICL_SUCCESS) {
487*7c478bd9Sstevel@tonic-gate 		err = ptree_create_node("fcal-backplane", "fru", &fcalbrdh);
488*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
489*7c478bd9Sstevel@tonic-gate 			return (err);
490*7c478bd9Sstevel@tonic-gate 
491*7c478bd9Sstevel@tonic-gate 		err = add_ref_prop(fcalbrdh, tmph, SEEPROM_SOURCE);
492*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
493*7c478bd9Sstevel@tonic-gate 			return (err);
494*7c478bd9Sstevel@tonic-gate 
495*7c478bd9Sstevel@tonic-gate 		err = add_void_fda_prop(fcalbrdh);
496*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
497*7c478bd9Sstevel@tonic-gate 			return (err);
498*7c478bd9Sstevel@tonic-gate 
499*7c478bd9Sstevel@tonic-gate 		err = ptree_add_node(rooth, fcalbrdh);
500*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
501*7c478bd9Sstevel@tonic-gate 			return (err);
502*7c478bd9Sstevel@tonic-gate 
503*7c478bd9Sstevel@tonic-gate 		err = add_ref_prop(tmph, fcalbrdh, FRU_PARENT);
504*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
505*7c478bd9Sstevel@tonic-gate 			return (err);
506*7c478bd9Sstevel@tonic-gate 	}
507*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
508*7c478bd9Sstevel@tonic-gate }
509*7c478bd9Sstevel@tonic-gate 
510*7c478bd9Sstevel@tonic-gate /* Initializes the FRU node for the RSC card */
511*7c478bd9Sstevel@tonic-gate static int
do_rscboard_init(picl_nodehdl_t rooth)512*7c478bd9Sstevel@tonic-gate do_rscboard_init(picl_nodehdl_t rooth)
513*7c478bd9Sstevel@tonic-gate {
514*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		rscbrdh;
515*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
516*7c478bd9Sstevel@tonic-gate 	int			err;
517*7c478bd9Sstevel@tonic-gate 
518*7c478bd9Sstevel@tonic-gate 	/* Create the node for the RSC board (if it exists) */
519*7c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(platform_frupath[RSC], &tmph) ==
520*7c478bd9Sstevel@tonic-gate 	    PICL_SUCCESS) {
521*7c478bd9Sstevel@tonic-gate 		err = ptree_create_node("rsc-board", "fru", &rscbrdh);
522*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
523*7c478bd9Sstevel@tonic-gate 			return (err);
524*7c478bd9Sstevel@tonic-gate 
525*7c478bd9Sstevel@tonic-gate 		err = add_ref_prop(rscbrdh, tmph, SEEPROM_SOURCE);
526*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
527*7c478bd9Sstevel@tonic-gate 			return (err);
528*7c478bd9Sstevel@tonic-gate 
529*7c478bd9Sstevel@tonic-gate 		err = add_void_fda_prop(rscbrdh);
530*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
531*7c478bd9Sstevel@tonic-gate 			return (err);
532*7c478bd9Sstevel@tonic-gate 
533*7c478bd9Sstevel@tonic-gate 		err = ptree_add_node(rooth, rscbrdh);
534*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
535*7c478bd9Sstevel@tonic-gate 			return (err);
536*7c478bd9Sstevel@tonic-gate 
537*7c478bd9Sstevel@tonic-gate 		err = add_ref_prop(tmph, rscbrdh, FRU_PARENT);
538*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
539*7c478bd9Sstevel@tonic-gate 			return (err);
540*7c478bd9Sstevel@tonic-gate 	}
541*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
542*7c478bd9Sstevel@tonic-gate }
543*7c478bd9Sstevel@tonic-gate 
544*7c478bd9Sstevel@tonic-gate /* Creates a "reference" property between two PICL nodes */
545*7c478bd9Sstevel@tonic-gate static int
add_ref_prop(picl_nodehdl_t nodeh,picl_nodehdl_t tmph,char * str)546*7c478bd9Sstevel@tonic-gate add_ref_prop(picl_nodehdl_t nodeh, picl_nodehdl_t tmph, char *str)
547*7c478bd9Sstevel@tonic-gate {
548*7c478bd9Sstevel@tonic-gate 	picl_prophdl_t		proph;
549*7c478bd9Sstevel@tonic-gate 	ptree_propinfo_t	propinfo;
550*7c478bd9Sstevel@tonic-gate 	int			err;
551*7c478bd9Sstevel@tonic-gate 
552*7c478bd9Sstevel@tonic-gate 	if (str == NULL)
553*7c478bd9Sstevel@tonic-gate 		return (PICL_FAILURE);
554*7c478bd9Sstevel@tonic-gate 
555*7c478bd9Sstevel@tonic-gate 	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
556*7c478bd9Sstevel@tonic-gate 	    PICL_PTYPE_REFERENCE, PICL_READ, sizeof (picl_nodehdl_t),
557*7c478bd9Sstevel@tonic-gate 	    str, NULL, NULL);
558*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
559*7c478bd9Sstevel@tonic-gate 		return (err);
560*7c478bd9Sstevel@tonic-gate 
561*7c478bd9Sstevel@tonic-gate 	err = ptree_create_and_add_prop(nodeh, &propinfo, &tmph, &proph);
562*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
563*7c478bd9Sstevel@tonic-gate 		return (err);
564*7c478bd9Sstevel@tonic-gate 
565*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
566*7c478bd9Sstevel@tonic-gate }
567*7c478bd9Sstevel@tonic-gate 
568*7c478bd9Sstevel@tonic-gate /* Creates a "Slot" property for a given PICL node */
569*7c478bd9Sstevel@tonic-gate static int
add_slot_prop(picl_nodehdl_t nodeh,int slotnum)570*7c478bd9Sstevel@tonic-gate add_slot_prop(picl_nodehdl_t nodeh, int slotnum)
571*7c478bd9Sstevel@tonic-gate {
572*7c478bd9Sstevel@tonic-gate 	picl_prophdl_t		proph;
573*7c478bd9Sstevel@tonic-gate 	ptree_propinfo_t	propinfo;
574*7c478bd9Sstevel@tonic-gate 	int			err;
575*7c478bd9Sstevel@tonic-gate 
576*7c478bd9Sstevel@tonic-gate 	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
577*7c478bd9Sstevel@tonic-gate 	    PICL_PTYPE_INT, PICL_READ, 4, "Slot", NULL, NULL);
578*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
579*7c478bd9Sstevel@tonic-gate 		return (err);
580*7c478bd9Sstevel@tonic-gate 
581*7c478bd9Sstevel@tonic-gate 	err = ptree_create_and_add_prop(nodeh, &propinfo, &slotnum, &proph);
582*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
583*7c478bd9Sstevel@tonic-gate 		return (err);
584*7c478bd9Sstevel@tonic-gate 
585*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
586*7c478bd9Sstevel@tonic-gate }
587*7c478bd9Sstevel@tonic-gate 
588*7c478bd9Sstevel@tonic-gate /* Creates a "Label" property for a given PICL node */
589*7c478bd9Sstevel@tonic-gate static int
add_label_prop(picl_nodehdl_t nodeh,char * label)590*7c478bd9Sstevel@tonic-gate add_label_prop(picl_nodehdl_t nodeh, char *label)
591*7c478bd9Sstevel@tonic-gate {
592*7c478bd9Sstevel@tonic-gate 	picl_prophdl_t		proph;
593*7c478bd9Sstevel@tonic-gate 	ptree_propinfo_t	propinfo;
594*7c478bd9Sstevel@tonic-gate 	int			err;
595*7c478bd9Sstevel@tonic-gate 
596*7c478bd9Sstevel@tonic-gate 	if (label == NULL)
597*7c478bd9Sstevel@tonic-gate 		return (PICL_FAILURE);
598*7c478bd9Sstevel@tonic-gate 
599*7c478bd9Sstevel@tonic-gate 	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
600*7c478bd9Sstevel@tonic-gate 	    PICL_PTYPE_CHARSTRING, PICL_READ, strlen(label)+1, "Label",
601*7c478bd9Sstevel@tonic-gate 	    NULL, NULL);
602*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
603*7c478bd9Sstevel@tonic-gate 		return (err);
604*7c478bd9Sstevel@tonic-gate 
605*7c478bd9Sstevel@tonic-gate 	err = ptree_create_and_add_prop(nodeh, &propinfo, label, &proph);
606*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
607*7c478bd9Sstevel@tonic-gate 		return (err);
608*7c478bd9Sstevel@tonic-gate 
609*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
610*7c478bd9Sstevel@tonic-gate }
611*7c478bd9Sstevel@tonic-gate 
612*7c478bd9Sstevel@tonic-gate /* Creates a "FRUDataAvailable" void property for the given PICL node */
613*7c478bd9Sstevel@tonic-gate static int
add_void_fda_prop(picl_nodehdl_t nodeh)614*7c478bd9Sstevel@tonic-gate add_void_fda_prop(picl_nodehdl_t nodeh)
615*7c478bd9Sstevel@tonic-gate {
616*7c478bd9Sstevel@tonic-gate 	picl_prophdl_t		proph;
617*7c478bd9Sstevel@tonic-gate 	ptree_propinfo_t	propinfo;
618*7c478bd9Sstevel@tonic-gate 	int			err;
619*7c478bd9Sstevel@tonic-gate 
620*7c478bd9Sstevel@tonic-gate 	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
621*7c478bd9Sstevel@tonic-gate 	    PICL_PTYPE_VOID, PICL_READ, 0, "FRUDataAvailable", NULL, NULL);
622*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
623*7c478bd9Sstevel@tonic-gate 		return (err);
624*7c478bd9Sstevel@tonic-gate 
625*7c478bd9Sstevel@tonic-gate 	err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, &proph);
626*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
627*7c478bd9Sstevel@tonic-gate 		return (err);
628*7c478bd9Sstevel@tonic-gate 
629*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
630*7c478bd9Sstevel@tonic-gate }
631*7c478bd9Sstevel@tonic-gate 
632*7c478bd9Sstevel@tonic-gate /* Creates a "ViewPoints" property -- used for chassis */
633*7c478bd9Sstevel@tonic-gate static int
add_viewpoints_prop(picl_nodehdl_t nodeh,char * string)634*7c478bd9Sstevel@tonic-gate add_viewpoints_prop(picl_nodehdl_t nodeh, char *string)
635*7c478bd9Sstevel@tonic-gate {
636*7c478bd9Sstevel@tonic-gate 	picl_prophdl_t		proph;
637*7c478bd9Sstevel@tonic-gate 	ptree_propinfo_t	propinfo;
638*7c478bd9Sstevel@tonic-gate 	int			err;
639*7c478bd9Sstevel@tonic-gate 
640*7c478bd9Sstevel@tonic-gate 	if (string == NULL)
641*7c478bd9Sstevel@tonic-gate 		return (PICL_FAILURE);
642*7c478bd9Sstevel@tonic-gate 
643*7c478bd9Sstevel@tonic-gate 	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
644*7c478bd9Sstevel@tonic-gate 	    PICL_PTYPE_CHARSTRING, PICL_READ, strlen(string)+1, "ViewPoints",
645*7c478bd9Sstevel@tonic-gate 	    NULL, NULL);
646*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
647*7c478bd9Sstevel@tonic-gate 		return (err);
648*7c478bd9Sstevel@tonic-gate 
649*7c478bd9Sstevel@tonic-gate 	err = ptree_create_and_add_prop(nodeh, &propinfo, string, &proph);
650*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
651*7c478bd9Sstevel@tonic-gate 		return (err);
652*7c478bd9Sstevel@tonic-gate 
653*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
654*7c478bd9Sstevel@tonic-gate }
655*7c478bd9Sstevel@tonic-gate 
656*7c478bd9Sstevel@tonic-gate /* Creates and adds all of the frutree nodes */
657*7c478bd9Sstevel@tonic-gate static int
add_all_nodes()658*7c478bd9Sstevel@tonic-gate add_all_nodes()
659*7c478bd9Sstevel@tonic-gate {
660*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t	rooth;
661*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t	chassish;
662*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t	sysboardh;
663*7c478bd9Sstevel@tonic-gate 	int		err;
664*7c478bd9Sstevel@tonic-gate 
665*7c478bd9Sstevel@tonic-gate 	/* Get the root node of the PICL tree */
666*7c478bd9Sstevel@tonic-gate 	err = ptree_get_root(&rooth);
667*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
668*7c478bd9Sstevel@tonic-gate 		return (err);
669*7c478bd9Sstevel@tonic-gate 	}
670*7c478bd9Sstevel@tonic-gate 
671*7c478bd9Sstevel@tonic-gate 	/* Create and add the root node of the FRU subtree */
672*7c478bd9Sstevel@tonic-gate 	err = ptree_create_and_add_node(rooth, "frutree", "picl", &frutreeh);
673*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
674*7c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, CREATE_FRUTREE_FAIL);
675*7c478bd9Sstevel@tonic-gate 		return (err);
676*7c478bd9Sstevel@tonic-gate 	}
677*7c478bd9Sstevel@tonic-gate 
678*7c478bd9Sstevel@tonic-gate 	/* Create and add the chassis node */
679*7c478bd9Sstevel@tonic-gate 	err = ptree_create_and_add_node(frutreeh, "chassis", "fru", &chassish);
680*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
681*7c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, CREATE_CHASSIS_FAIL);
682*7c478bd9Sstevel@tonic-gate 		return (err);
683*7c478bd9Sstevel@tonic-gate 	}
684*7c478bd9Sstevel@tonic-gate 
685*7c478bd9Sstevel@tonic-gate 	/* Add ViewPoints prop to chassis node */
686*7c478bd9Sstevel@tonic-gate 	err = add_viewpoints_prop(chassish, CHASSIS_VIEWPOINTS);
687*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
688*7c478bd9Sstevel@tonic-gate 		return (err);
689*7c478bd9Sstevel@tonic-gate 
690*7c478bd9Sstevel@tonic-gate 	/* Initialize the FRU node for the system board */
691*7c478bd9Sstevel@tonic-gate 	err = do_sysboard_init(chassish, &sysboardh);
692*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
693*7c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, SYSBRD_INIT_FAIL);
694*7c478bd9Sstevel@tonic-gate 		return (err);
695*7c478bd9Sstevel@tonic-gate 	}
696*7c478bd9Sstevel@tonic-gate 
697*7c478bd9Sstevel@tonic-gate 	/* Initialize the FRU nodes for the CPU modules */
698*7c478bd9Sstevel@tonic-gate 	err = do_cpus_init(sysboardh);
699*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
700*7c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, CPUS_INIT_FAIL);
701*7c478bd9Sstevel@tonic-gate 		return (err);
702*7c478bd9Sstevel@tonic-gate 	}
703*7c478bd9Sstevel@tonic-gate 
704*7c478bd9Sstevel@tonic-gate 	/* Initialize the FRU nodes for the memory modules */
705*7c478bd9Sstevel@tonic-gate 	err = do_mem_init(sysboardh);
706*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
707*7c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, DIMMS_INIT_FAIL);
708*7c478bd9Sstevel@tonic-gate 		return (err);
709*7c478bd9Sstevel@tonic-gate 	}
710*7c478bd9Sstevel@tonic-gate 
711*7c478bd9Sstevel@tonic-gate 	/* Initialize the FRU nodes for the PDB and the power supplies */
712*7c478bd9Sstevel@tonic-gate 	err = do_power_supplies_init(chassish);
713*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
714*7c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, PS_INIT_FAIL);
715*7c478bd9Sstevel@tonic-gate 		return (err);
716*7c478bd9Sstevel@tonic-gate 	}
717*7c478bd9Sstevel@tonic-gate 
718*7c478bd9Sstevel@tonic-gate 	/* Initialize the FRU nodes for the FCAL backplane */
719*7c478bd9Sstevel@tonic-gate 	err = do_fcal_init(chassish);
720*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
721*7c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, FCAL_INIT_FAIL);
722*7c478bd9Sstevel@tonic-gate 		return (err);
723*7c478bd9Sstevel@tonic-gate 	}
724*7c478bd9Sstevel@tonic-gate 
725*7c478bd9Sstevel@tonic-gate 	/* Initialize the FRU node for the RSC card */
726*7c478bd9Sstevel@tonic-gate 	err = do_rscboard_init(chassish);
727*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
728*7c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, RSC_INIT_FAIL);
729*7c478bd9Sstevel@tonic-gate 		return (err);
730*7c478bd9Sstevel@tonic-gate 	}
731*7c478bd9Sstevel@tonic-gate 
732*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
733*7c478bd9Sstevel@tonic-gate }
734*7c478bd9Sstevel@tonic-gate 
735*7c478bd9Sstevel@tonic-gate /* Deletes and destroys all PICL nodes for which rooth is a ancestor */
736*7c478bd9Sstevel@tonic-gate static int
remove_all_nodes(picl_nodehdl_t rooth)737*7c478bd9Sstevel@tonic-gate remove_all_nodes(picl_nodehdl_t rooth)
738*7c478bd9Sstevel@tonic-gate {
739*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		chdh;
740*7c478bd9Sstevel@tonic-gate 	int			err, done = 0;
741*7c478bd9Sstevel@tonic-gate 
742*7c478bd9Sstevel@tonic-gate 	while (!done) {
743*7c478bd9Sstevel@tonic-gate 		err = ptree_get_propval_by_name(rooth, PICL_PROP_CHILD, &chdh,
744*7c478bd9Sstevel@tonic-gate 		    sizeof (picl_nodehdl_t));
745*7c478bd9Sstevel@tonic-gate 		if (err != PICL_PROPNOTFOUND) {
746*7c478bd9Sstevel@tonic-gate 			(void) remove_all_nodes(chdh);
747*7c478bd9Sstevel@tonic-gate 		} else {
748*7c478bd9Sstevel@tonic-gate 			err = ptree_delete_node(rooth);
749*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS) {
750*7c478bd9Sstevel@tonic-gate 				return (err);
751*7c478bd9Sstevel@tonic-gate 			} else {
752*7c478bd9Sstevel@tonic-gate 				(void) ptree_destroy_node(rooth);
753*7c478bd9Sstevel@tonic-gate 			}
754*7c478bd9Sstevel@tonic-gate 			done = 1;
755*7c478bd9Sstevel@tonic-gate 		}
756*7c478bd9Sstevel@tonic-gate 	}
757*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
758*7c478bd9Sstevel@tonic-gate }
759*7c478bd9Sstevel@tonic-gate 
760*7c478bd9Sstevel@tonic-gate /*
761*7c478bd9Sstevel@tonic-gate  * Searches the list of hotpluggable FRUs for this platform and adds the
762*7c478bd9Sstevel@tonic-gate  * appropriate node(s) to the frutree
763*7c478bd9Sstevel@tonic-gate  */
764*7c478bd9Sstevel@tonic-gate static int
add_hotplug_fru_device()765*7c478bd9Sstevel@tonic-gate add_hotplug_fru_device()
766*7c478bd9Sstevel@tonic-gate {
767*7c478bd9Sstevel@tonic-gate 	int		i, err, slotnum;
768*7c478bd9Sstevel@tonic-gate 
769*7c478bd9Sstevel@tonic-gate 	/* Check for hotplugged power supplies */
770*7c478bd9Sstevel@tonic-gate 	for (i = PS0; i <= PS1; i++) {
771*7c478bd9Sstevel@tonic-gate 		/* Compare the /platform tree to the frutree */
772*7c478bd9Sstevel@tonic-gate 		slotnum = i - PS0;
773*7c478bd9Sstevel@tonic-gate 		err = is_added_device(platform_frupath[i],
774*7c478bd9Sstevel@tonic-gate 		    frutree_power_supply[slotnum]);
775*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
776*7c478bd9Sstevel@tonic-gate 			continue;
777*7c478bd9Sstevel@tonic-gate 
778*7c478bd9Sstevel@tonic-gate 		/* If they are different, then add a power supply */
779*7c478bd9Sstevel@tonic-gate 		err = add_power_supply(slotnum);
780*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
781*7c478bd9Sstevel@tonic-gate 			continue;
782*7c478bd9Sstevel@tonic-gate 	}
783*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
784*7c478bd9Sstevel@tonic-gate }
785*7c478bd9Sstevel@tonic-gate 
786*7c478bd9Sstevel@tonic-gate /*
787*7c478bd9Sstevel@tonic-gate  * Searches the list of hotpluggable FRUs for this platform and removes the
788*7c478bd9Sstevel@tonic-gate  * appropriate node(s) from the frutree
789*7c478bd9Sstevel@tonic-gate  */
790*7c478bd9Sstevel@tonic-gate static int
rem_hotplug_fru_device()791*7c478bd9Sstevel@tonic-gate rem_hotplug_fru_device()
792*7c478bd9Sstevel@tonic-gate {
793*7c478bd9Sstevel@tonic-gate 	int		i, err, slotnum;
794*7c478bd9Sstevel@tonic-gate 
795*7c478bd9Sstevel@tonic-gate 	/* Check for hotplugged power supplies */
796*7c478bd9Sstevel@tonic-gate 	for (i = PS0; i <= PS1; i++) {
797*7c478bd9Sstevel@tonic-gate 		/* Compare the /platform tree to the frutree */
798*7c478bd9Sstevel@tonic-gate 		slotnum = i - PS0;
799*7c478bd9Sstevel@tonic-gate 		err = is_removed_device(platform_frupath[i],
800*7c478bd9Sstevel@tonic-gate 		    frutree_power_supply[slotnum]);
801*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
802*7c478bd9Sstevel@tonic-gate 			continue;
803*7c478bd9Sstevel@tonic-gate 
804*7c478bd9Sstevel@tonic-gate 		/* If they are different, then remove a power supply */
805*7c478bd9Sstevel@tonic-gate 		err = remove_power_supply(slotnum);
806*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
807*7c478bd9Sstevel@tonic-gate 			continue;
808*7c478bd9Sstevel@tonic-gate 	}
809*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
810*7c478bd9Sstevel@tonic-gate }
811*7c478bd9Sstevel@tonic-gate 
812*7c478bd9Sstevel@tonic-gate /*
813*7c478bd9Sstevel@tonic-gate  * Compare the /platform tree to the /frutree to determine if a
814*7c478bd9Sstevel@tonic-gate  * new device has been added
815*7c478bd9Sstevel@tonic-gate  */
816*7c478bd9Sstevel@tonic-gate static int
is_added_device(char * plat,char * fru)817*7c478bd9Sstevel@tonic-gate is_added_device(char *plat, char *fru)
818*7c478bd9Sstevel@tonic-gate {
819*7c478bd9Sstevel@tonic-gate 	int		err;
820*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t	plath, frusloth, frumodh;
821*7c478bd9Sstevel@tonic-gate 
822*7c478bd9Sstevel@tonic-gate 	/* Check for node in the /platform tree */
823*7c478bd9Sstevel@tonic-gate 	err = ptree_get_node_by_path(plat, &plath);
824*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
825*7c478bd9Sstevel@tonic-gate 		return (err);
826*7c478bd9Sstevel@tonic-gate 
827*7c478bd9Sstevel@tonic-gate 	/*
828*7c478bd9Sstevel@tonic-gate 	 * The node is in /platform, so find the corresponding slot in
829*7c478bd9Sstevel@tonic-gate 	 * the frutree
830*7c478bd9Sstevel@tonic-gate 	 */
831*7c478bd9Sstevel@tonic-gate 	err = ptree_get_node_by_path(fru, &frusloth);
832*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
833*7c478bd9Sstevel@tonic-gate 		return (err);
834*7c478bd9Sstevel@tonic-gate 
835*7c478bd9Sstevel@tonic-gate 	/*
836*7c478bd9Sstevel@tonic-gate 	 * If the slot in the frutree has a child, then return
837*7c478bd9Sstevel@tonic-gate 	 * PICL_FAILURE.  This means that the /platform tree and
838*7c478bd9Sstevel@tonic-gate 	 * the frutree are consistent and no action is necessary.
839*7c478bd9Sstevel@tonic-gate 	 * Otherwise return PICL_SUCCESS to indicate that a node needs
840*7c478bd9Sstevel@tonic-gate 	 * to be added to the frutree
841*7c478bd9Sstevel@tonic-gate 	 */
842*7c478bd9Sstevel@tonic-gate 	err = ptree_get_propval_by_name(frusloth, PICL_PROP_CHILD,
843*7c478bd9Sstevel@tonic-gate 	    &frumodh, sizeof (picl_nodehdl_t));
844*7c478bd9Sstevel@tonic-gate 	if (err == PICL_SUCCESS)
845*7c478bd9Sstevel@tonic-gate 		return (PICL_FAILURE);
846*7c478bd9Sstevel@tonic-gate 
847*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
848*7c478bd9Sstevel@tonic-gate }
849*7c478bd9Sstevel@tonic-gate 
850*7c478bd9Sstevel@tonic-gate /*
851*7c478bd9Sstevel@tonic-gate  * Compare the /platform tree to the /frutree to determine if a
852*7c478bd9Sstevel@tonic-gate  * device has been removed
853*7c478bd9Sstevel@tonic-gate  */
854*7c478bd9Sstevel@tonic-gate static int
is_removed_device(char * plat,char * fru)855*7c478bd9Sstevel@tonic-gate is_removed_device(char *plat, char *fru)
856*7c478bd9Sstevel@tonic-gate {
857*7c478bd9Sstevel@tonic-gate 	int		err;
858*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t	plath, frusloth, frumodh;
859*7c478bd9Sstevel@tonic-gate 
860*7c478bd9Sstevel@tonic-gate 
861*7c478bd9Sstevel@tonic-gate 	/* Check for node in /platform tree */
862*7c478bd9Sstevel@tonic-gate 	err = ptree_get_node_by_path(plat, &plath);
863*7c478bd9Sstevel@tonic-gate 	if (err == PICL_SUCCESS)
864*7c478bd9Sstevel@tonic-gate 		return (PICL_FAILURE);
865*7c478bd9Sstevel@tonic-gate 
866*7c478bd9Sstevel@tonic-gate 	/*
867*7c478bd9Sstevel@tonic-gate 	 * The node is not in /platform, so find the corresponding slot in
868*7c478bd9Sstevel@tonic-gate 	 * the frutree
869*7c478bd9Sstevel@tonic-gate 	 */
870*7c478bd9Sstevel@tonic-gate 	err = ptree_get_node_by_path(fru, &frusloth);
871*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
872*7c478bd9Sstevel@tonic-gate 		return (err);
873*7c478bd9Sstevel@tonic-gate 
874*7c478bd9Sstevel@tonic-gate 	/*
875*7c478bd9Sstevel@tonic-gate 	 * If the slot in the frutree does not have a child, then return
876*7c478bd9Sstevel@tonic-gate 	 * PICL_FAILURE.  This means that the /platform tree and
877*7c478bd9Sstevel@tonic-gate 	 * the frutree are consistent and no action is necessary.
878*7c478bd9Sstevel@tonic-gate 	 * Otherwise return PICL_SUCCESS to indicate that the needs
879*7c478bd9Sstevel@tonic-gate 	 * to be removed from the frutree
880*7c478bd9Sstevel@tonic-gate 	 */
881*7c478bd9Sstevel@tonic-gate 	err = ptree_get_propval_by_name(frusloth, PICL_PROP_CHILD,
882*7c478bd9Sstevel@tonic-gate 	    &frumodh, sizeof (picl_nodehdl_t));
883*7c478bd9Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
884*7c478bd9Sstevel@tonic-gate 		return (PICL_FAILURE);
885*7c478bd9Sstevel@tonic-gate 
886*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
887*7c478bd9Sstevel@tonic-gate }
888*7c478bd9Sstevel@tonic-gate 
889*7c478bd9Sstevel@tonic-gate /* Hotplug routine used to add a new power supply */
890*7c478bd9Sstevel@tonic-gate static int
add_power_supply(int slotnum)891*7c478bd9Sstevel@tonic-gate add_power_supply(int slotnum)
892*7c478bd9Sstevel@tonic-gate {
893*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		powersloth;
894*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		powermodh;
895*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		tmph;
896*7c478bd9Sstevel@tonic-gate 	int			i, err;
897*7c478bd9Sstevel@tonic-gate 
898*7c478bd9Sstevel@tonic-gate 	/* Find the node for the given power supply slot */
899*7c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(frutree_power_supply[slotnum],
900*7c478bd9Sstevel@tonic-gate 	    &powersloth) == PICL_SUCCESS) {
901*7c478bd9Sstevel@tonic-gate 
902*7c478bd9Sstevel@tonic-gate 		i = slotnum + PS0;
903*7c478bd9Sstevel@tonic-gate 
904*7c478bd9Sstevel@tonic-gate 		/* Make sure it's in /platform and create the frutree node */
905*7c478bd9Sstevel@tonic-gate 		if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
906*7c478bd9Sstevel@tonic-gate 		    PICL_SUCCESS) {
907*7c478bd9Sstevel@tonic-gate 			err = ptree_create_node("power-supply", "fru",
908*7c478bd9Sstevel@tonic-gate 			    &powermodh);
909*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
910*7c478bd9Sstevel@tonic-gate 				return (err);
911*7c478bd9Sstevel@tonic-gate 
912*7c478bd9Sstevel@tonic-gate 			err = add_ref_prop(powermodh, tmph, SEEPROM_SOURCE);
913*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
914*7c478bd9Sstevel@tonic-gate 				return (err);
915*7c478bd9Sstevel@tonic-gate 
916*7c478bd9Sstevel@tonic-gate 			err = add_void_fda_prop(powermodh);
917*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
918*7c478bd9Sstevel@tonic-gate 				return (err);
919*7c478bd9Sstevel@tonic-gate 
920*7c478bd9Sstevel@tonic-gate 			err = ptree_add_node(powersloth, powermodh);
921*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
922*7c478bd9Sstevel@tonic-gate 				return (err);
923*7c478bd9Sstevel@tonic-gate 
924*7c478bd9Sstevel@tonic-gate 			err = add_ref_prop(tmph, powermodh, FRU_PARENT);
925*7c478bd9Sstevel@tonic-gate 			if (err != PICL_SUCCESS)
926*7c478bd9Sstevel@tonic-gate 				return (err);
927*7c478bd9Sstevel@tonic-gate 		}
928*7c478bd9Sstevel@tonic-gate 	}
929*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
930*7c478bd9Sstevel@tonic-gate }
931*7c478bd9Sstevel@tonic-gate 
932*7c478bd9Sstevel@tonic-gate /* Hotplug routine used to remove an existing power supply */
933*7c478bd9Sstevel@tonic-gate static int
remove_power_supply(int slotnum)934*7c478bd9Sstevel@tonic-gate remove_power_supply(int slotnum)
935*7c478bd9Sstevel@tonic-gate {
936*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		powersloth;
937*7c478bd9Sstevel@tonic-gate 	picl_nodehdl_t		powermodh;
938*7c478bd9Sstevel@tonic-gate 	int			err;
939*7c478bd9Sstevel@tonic-gate 
940*7c478bd9Sstevel@tonic-gate 	/* Find the node for the given power supply slot */
941*7c478bd9Sstevel@tonic-gate 	if (ptree_get_node_by_path(frutree_power_supply[slotnum],
942*7c478bd9Sstevel@tonic-gate 	    &powersloth) == PICL_SUCCESS) {
943*7c478bd9Sstevel@tonic-gate 		/* Make sure it's got a child, then delete it */
944*7c478bd9Sstevel@tonic-gate 		err = ptree_get_propval_by_name(powersloth, PICL_PROP_CHILD,
945*7c478bd9Sstevel@tonic-gate 		    &powermodh, sizeof (picl_nodehdl_t));
946*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS) {
947*7c478bd9Sstevel@tonic-gate 			return (err);
948*7c478bd9Sstevel@tonic-gate 		}
949*7c478bd9Sstevel@tonic-gate 
950*7c478bd9Sstevel@tonic-gate 		err = ptree_delete_node(powermodh);
951*7c478bd9Sstevel@tonic-gate 		if (err != PICL_SUCCESS) {
952*7c478bd9Sstevel@tonic-gate 			return (err);
953*7c478bd9Sstevel@tonic-gate 		} else {
954*7c478bd9Sstevel@tonic-gate 			(void) ptree_destroy_node(powermodh);
955*7c478bd9Sstevel@tonic-gate 		}
956*7c478bd9Sstevel@tonic-gate 	}
957*7c478bd9Sstevel@tonic-gate 	return (PICL_SUCCESS);
958*7c478bd9Sstevel@tonic-gate }
959