1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate * PICL plug-in that creates the FRU Hierarchy for the
31*0Sstevel@tonic-gate * SUNW,Sun-Fire-880 (Daktari) platform
32*0Sstevel@tonic-gate */
33*0Sstevel@tonic-gate
34*0Sstevel@tonic-gate #include <stdio.h>
35*0Sstevel@tonic-gate #include <string.h>
36*0Sstevel@tonic-gate #include <libintl.h>
37*0Sstevel@tonic-gate #include <libnvpair.h>
38*0Sstevel@tonic-gate #include <syslog.h>
39*0Sstevel@tonic-gate #include <picl.h>
40*0Sstevel@tonic-gate #include <picltree.h>
41*0Sstevel@tonic-gate #include <picldefs.h>
42*0Sstevel@tonic-gate
43*0Sstevel@tonic-gate /*
44*0Sstevel@tonic-gate * Plugin registration entry points
45*0Sstevel@tonic-gate */
46*0Sstevel@tonic-gate static void picl_frutree_register(void);
47*0Sstevel@tonic-gate static void picl_frutree_init(void);
48*0Sstevel@tonic-gate static void picl_frutree_fini(void);
49*0Sstevel@tonic-gate static void picl_frutree_evhandler(const char *ename, const void *earg,
50*0Sstevel@tonic-gate size_t size, void *cookie);
51*0Sstevel@tonic-gate
52*0Sstevel@tonic-gate #pragma init(picl_frutree_register)
53*0Sstevel@tonic-gate
54*0Sstevel@tonic-gate /*
55*0Sstevel@tonic-gate * Log message texts
56*0Sstevel@tonic-gate */
57*0Sstevel@tonic-gate #define CREATE_FRUTREE_FAIL gettext("Failed to create frutree node\n")
58*0Sstevel@tonic-gate #define CREATE_CHASSIS_FAIL gettext("Failed to create chassis node\n")
59*0Sstevel@tonic-gate #define IOBRD_INIT_FAIL gettext("do_ioboard_init() failed\n")
60*0Sstevel@tonic-gate #define RSCBRD_INIT_FAIL gettext("do_rscboard_init() failed\n")
61*0Sstevel@tonic-gate #define FCAL_INIT_FAIL gettext("do_fcal_init() failed\n")
62*0Sstevel@tonic-gate #define PS_INIT_FAIL gettext("do_power_supplies_init() failed\n")
63*0Sstevel@tonic-gate #define SYSBOARD_INIT_FAIL gettext("do_motherboard_init() failed\n")
64*0Sstevel@tonic-gate
65*0Sstevel@tonic-gate /*
66*0Sstevel@tonic-gate * Viewpoints property field used by SunMC
67*0Sstevel@tonic-gate */
68*0Sstevel@tonic-gate #define CHASSIS_VIEWPOINTS gettext("front left right rear")
69*0Sstevel@tonic-gate
70*0Sstevel@tonic-gate /*
71*0Sstevel@tonic-gate * Ref prop values
72*0Sstevel@tonic-gate */
73*0Sstevel@tonic-gate #define SEEPROM_SOURCE "_seeprom_source"
74*0Sstevel@tonic-gate #define FRU_PARENT "_fru_parent"
75*0Sstevel@tonic-gate
76*0Sstevel@tonic-gate /*
77*0Sstevel@tonic-gate * List of all the FRU locations in the platform_frupath[] array, and
78*0Sstevel@tonic-gate * location_label[] array
79*0Sstevel@tonic-gate */
80*0Sstevel@tonic-gate #define IOBRD 0
81*0Sstevel@tonic-gate #define RSC 1
82*0Sstevel@tonic-gate #define FCAL0 2
83*0Sstevel@tonic-gate #define FCAL1 3
84*0Sstevel@tonic-gate #define FCALGBIC 4
85*0Sstevel@tonic-gate #define PDB 5
86*0Sstevel@tonic-gate #define PS0 6
87*0Sstevel@tonic-gate #define PS1 7
88*0Sstevel@tonic-gate #define PS2 8
89*0Sstevel@tonic-gate #define SYSBRD 9
90*0Sstevel@tonic-gate #define CPUMOD0 10
91*0Sstevel@tonic-gate #define CPUMOD1 11
92*0Sstevel@tonic-gate #define CPUMOD2 12
93*0Sstevel@tonic-gate #define CPUMOD3 13
94*0Sstevel@tonic-gate #define CPU0_DIMM0 14
95*0Sstevel@tonic-gate #define DIMMS_PER_MOD 8
96*0Sstevel@tonic-gate #define DIMMS_PER_SLOT 16
97*0Sstevel@tonic-gate
98*0Sstevel@tonic-gate
99*0Sstevel@tonic-gate /*
100*0Sstevel@tonic-gate * Local variables
101*0Sstevel@tonic-gate */
102*0Sstevel@tonic-gate static picld_plugin_reg_t my_reg_info = {
103*0Sstevel@tonic-gate PICLD_PLUGIN_VERSION_1,
104*0Sstevel@tonic-gate PICLD_PLUGIN_NON_CRITICAL,
105*0Sstevel@tonic-gate "SUNW_Sun-Fire-880_frutree",
106*0Sstevel@tonic-gate picl_frutree_init,
107*0Sstevel@tonic-gate picl_frutree_fini
108*0Sstevel@tonic-gate };
109*0Sstevel@tonic-gate
110*0Sstevel@tonic-gate /*
111*0Sstevel@tonic-gate * List of all the FRUs in the /platform tree with SEEPROMs
112*0Sstevel@tonic-gate */
113*0Sstevel@tonic-gate static char *platform_frupath[] = {
114*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@4,aa", /* IO */
115*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,a6", /* RSC */
116*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,a8", /* FCAL 0 */
117*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,ac", /* FCAL 1 */
118*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,aa", /* FCAL-GBIC */
119*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,ae", /* PDB */
120*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,a0", /* PS 0 */
121*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,a2", /* PS 1 */
122*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,30/fru@0,a4", /* PS 2 */
123*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@4,a8", /* SYS BRD */
124*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@4,a0", /* CPU MOD 0 */
125*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@4,a2", /* CPU MOD 1 */
126*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@4,a4", /* CPU MOD 2 */
127*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@4,a6", /* CPU MOD 3 */
128*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a0", /* CPU0 DIMM0 */
129*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a2", /* CPU0 DIMM1 */
130*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a4", /* CPU0 DIMM2 */
131*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a6", /* CPU0 DIMM3 */
132*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a8", /* CPU0 DIMM4 */
133*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,aa", /* CPU0 DIMM5 */
134*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,ac", /* CPU0 DIMM6 */
135*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@0,ae", /* CPU0 DIMM7 */
136*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a0", /* CPU2 DIMM0 */
137*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a2", /* CPU2 DIMM1 */
138*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a4", /* CPU2 DIMM2 */
139*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a6", /* CPU2 DIMM3 */
140*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a8", /* CPU2 DIMM4 */
141*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,aa", /* CPU2 DIMM5 */
142*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,ac", /* CPU2 DIMM6 */
143*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@2,ae", /* CPU2 DIMM7 */
144*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a0", /* CPU1 DIMM0 */
145*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a2", /* CPU1 DIMM1 */
146*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a4", /* CPU1 DIMM2 */
147*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a6", /* CPU1 DIMM3 */
148*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a8", /* CPU1 DIMM4 */
149*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,aa", /* CPU1 DIMM5 */
150*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,ac", /* CPU1 DIMM6 */
151*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@1,ae", /* CPU1 DIMM7 */
152*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a0", /* CPU3 DIMM0 */
153*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a2", /* CPU3 DIMM1 */
154*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a4", /* CPU3 DIMM2 */
155*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a6", /* CPU3 DIMM3 */
156*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a8", /* CPU3 DIMM4 */
157*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,aa", /* CPU3 DIMM5 */
158*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,ac", /* CPU3 DIMM6 */
159*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,2e/fru@3,ae", /* CPU3 DIMM7 */
160*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,a0", /* CPU4 DIMM0 */
161*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,a2", /* CPU4 DIMM1 */
162*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,a4", /* CPU4 DIMM2 */
163*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,a6", /* CPU4 DIMM3 */
164*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,a8", /* CPU4 DIMM4 */
165*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,aa", /* CPU4 DIMM5 */
166*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,ac", /* CPU4 DIMM6 */
167*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@0,ae", /* CPU4 DIMM7 */
168*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,a0", /* CPU6 DIMM0 */
169*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,a2", /* CPU6 DIMM1 */
170*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,a4", /* CPU6 DIMM2 */
171*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,a6", /* CPU6 DIMM3 */
172*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,a8", /* CPU6 DIMM4 */
173*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,aa", /* CPU6 DIMM5 */
174*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,ac", /* CPU6 DIMM6 */
175*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@2,ae", /* CPU6 DIMM7 */
176*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,a0", /* CPU5 DIMM0 */
177*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,a2", /* CPU5 DIMM1 */
178*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,a4", /* CPU5 DIMM2 */
179*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,a6", /* CPU5 DIMM3 */
180*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,a8", /* CPU5 DIMM4 */
181*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,aa", /* CPU5 DIMM5 */
182*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,ac", /* CPU5 DIMM6 */
183*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@1,ae", /* CPU5 DIMM7 */
184*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,a0", /* CPU7 DIMM0 */
185*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,a2", /* CPU7 DIMM1 */
186*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,a4", /* CPU7 DIMM2 */
187*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,a6", /* CPU7 DIMM3 */
188*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,a8", /* CPU7 DIMM4 */
189*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,aa", /* CPU7 DIMM5 */
190*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,ac", /* CPU7 DIMM6 */
191*0Sstevel@tonic-gate "/platform/pci@9,700000/ebus@1/i2c@1,50002e/fru@3,ae", /* CPU7 DIMM7 */
192*0Sstevel@tonic-gate NULL};
193*0Sstevel@tonic-gate
194*0Sstevel@tonic-gate /*
195*0Sstevel@tonic-gate * List of Labels for FRU locations (uses the #define's from above)
196*0Sstevel@tonic-gate */
197*0Sstevel@tonic-gate static char *location_label[] = {
198*0Sstevel@tonic-gate NULL, /* IOBRD */
199*0Sstevel@tonic-gate NULL, /* RSC */
200*0Sstevel@tonic-gate "0", /* FCAL0 */
201*0Sstevel@tonic-gate "1", /* FCAL1 */
202*0Sstevel@tonic-gate NULL, /* FCALGBIC */
203*0Sstevel@tonic-gate NULL, /* PDB */
204*0Sstevel@tonic-gate "0", /* PS0 */
205*0Sstevel@tonic-gate "1", /* PS1 */
206*0Sstevel@tonic-gate "2", /* PS2 */
207*0Sstevel@tonic-gate NULL, /* SYSBRD */
208*0Sstevel@tonic-gate "A", /* CPUMOD0 */
209*0Sstevel@tonic-gate "B", /* CPUMOD1 */
210*0Sstevel@tonic-gate "C", /* CPUMOD2 */
211*0Sstevel@tonic-gate "D", /* CPUMOD3 */
212*0Sstevel@tonic-gate "J2900", /* CPU0 DIMM0 */
213*0Sstevel@tonic-gate "J3100", /* CPU0 DIMM1 */
214*0Sstevel@tonic-gate "J2901", /* CPU0 DIMM2 */
215*0Sstevel@tonic-gate "J3101", /* CPU0 DIMM3 */
216*0Sstevel@tonic-gate "J3000", /* CPU0 DIMM4 */
217*0Sstevel@tonic-gate "J3200", /* CPU0 DIMM5 */
218*0Sstevel@tonic-gate "J3001", /* CPU0 DIMM6 */
219*0Sstevel@tonic-gate "J3201", /* CPU0 DIMM7 */
220*0Sstevel@tonic-gate "J7900", /* CPU1 DIMM0 */
221*0Sstevel@tonic-gate "J8100", /* CPU1 DIMM1 */
222*0Sstevel@tonic-gate "J7901", /* CPU1 DIMM2 */
223*0Sstevel@tonic-gate "J8101", /* CPU1 DIMM3 */
224*0Sstevel@tonic-gate "J8000", /* CPU1 DIMM4 */
225*0Sstevel@tonic-gate "J8200", /* CPU1 DIMM5 */
226*0Sstevel@tonic-gate "J8001", /* CPU1 DIMM6 */
227*0Sstevel@tonic-gate "J8201", /* CPU1 DIMM7 */
228*0Sstevel@tonic-gate "0", /* CPU0 label */
229*0Sstevel@tonic-gate "1", /* CPU1 label */
230*0Sstevel@tonic-gate NULL};
231*0Sstevel@tonic-gate
232*0Sstevel@tonic-gate /*
233*0Sstevel@tonic-gate * List of all the FRU slots for power supplies (hotpluggable)
234*0Sstevel@tonic-gate */
235*0Sstevel@tonic-gate static char *frutree_power_supply[] = {
236*0Sstevel@tonic-gate "/frutree/chassis/power-dist-board/power-supply-slot?Slot=0",
237*0Sstevel@tonic-gate "/frutree/chassis/power-dist-board/power-supply-slot?Slot=1",
238*0Sstevel@tonic-gate "/frutree/chassis/power-dist-board/power-supply-slot?Slot=2",
239*0Sstevel@tonic-gate NULL};
240*0Sstevel@tonic-gate
241*0Sstevel@tonic-gate /*
242*0Sstevel@tonic-gate * List of all the FRU slots for CPU Memory modules (hotpluggable)
243*0Sstevel@tonic-gate */
244*0Sstevel@tonic-gate static char *frutree_cpu_module[] = {
245*0Sstevel@tonic-gate "/frutree/chassis/system-board/cpu-mem-slot?Slot=0",
246*0Sstevel@tonic-gate "/frutree/chassis/system-board/cpu-mem-slot?Slot=1",
247*0Sstevel@tonic-gate "/frutree/chassis/system-board/cpu-mem-slot?Slot=2",
248*0Sstevel@tonic-gate "/frutree/chassis/system-board/cpu-mem-slot?Slot=3",
249*0Sstevel@tonic-gate NULL};
250*0Sstevel@tonic-gate
251*0Sstevel@tonic-gate /* PICL handle for the root node of the "frutree" */
252*0Sstevel@tonic-gate static picl_nodehdl_t frutreeh;
253*0Sstevel@tonic-gate
254*0Sstevel@tonic-gate static int do_ioboard_init(picl_nodehdl_t);
255*0Sstevel@tonic-gate static int do_rscboard_init(picl_nodehdl_t);
256*0Sstevel@tonic-gate static int do_fcal_init(picl_nodehdl_t);
257*0Sstevel@tonic-gate static int do_power_supplies_init(picl_nodehdl_t);
258*0Sstevel@tonic-gate static int do_motherboard_init(picl_nodehdl_t);
259*0Sstevel@tonic-gate static int do_cpu_module_init(picl_nodehdl_t, int);
260*0Sstevel@tonic-gate static int do_dimms_init(picl_nodehdl_t, int, int);
261*0Sstevel@tonic-gate
262*0Sstevel@tonic-gate static int add_ref_prop(picl_nodehdl_t, picl_nodehdl_t, char *);
263*0Sstevel@tonic-gate static int add_slot_prop(picl_nodehdl_t, int);
264*0Sstevel@tonic-gate static int add_label_prop(picl_nodehdl_t, char *);
265*0Sstevel@tonic-gate static int add_void_fda_prop(picl_nodehdl_t);
266*0Sstevel@tonic-gate static int add_viewpoints_prop(picl_nodehdl_t, char *);
267*0Sstevel@tonic-gate static int add_all_nodes();
268*0Sstevel@tonic-gate static int remove_all_nodes(picl_nodehdl_t);
269*0Sstevel@tonic-gate
270*0Sstevel@tonic-gate static int add_hotplug_fru_device(void);
271*0Sstevel@tonic-gate static int rem_hotplug_fru_device(void);
272*0Sstevel@tonic-gate static int is_added_device(char *, char *);
273*0Sstevel@tonic-gate static int is_removed_device(char *, char *);
274*0Sstevel@tonic-gate static int add_power_supply(int);
275*0Sstevel@tonic-gate static int remove_power_supply(int);
276*0Sstevel@tonic-gate static int add_cpu_module(int);
277*0Sstevel@tonic-gate static int remove_cpu_module(int);
278*0Sstevel@tonic-gate
279*0Sstevel@tonic-gate /*
280*0Sstevel@tonic-gate * This function is executed as part of .init when the plugin is
281*0Sstevel@tonic-gate * dlopen()ed
282*0Sstevel@tonic-gate */
283*0Sstevel@tonic-gate static void
picl_frutree_register()284*0Sstevel@tonic-gate picl_frutree_register()
285*0Sstevel@tonic-gate {
286*0Sstevel@tonic-gate (void) picld_plugin_register(&my_reg_info);
287*0Sstevel@tonic-gate }
288*0Sstevel@tonic-gate
289*0Sstevel@tonic-gate /*
290*0Sstevel@tonic-gate * This function is the init entry point of the plugin.
291*0Sstevel@tonic-gate * It initializes the /frutree tree
292*0Sstevel@tonic-gate */
293*0Sstevel@tonic-gate static void
picl_frutree_init()294*0Sstevel@tonic-gate picl_frutree_init()
295*0Sstevel@tonic-gate {
296*0Sstevel@tonic-gate int err;
297*0Sstevel@tonic-gate
298*0Sstevel@tonic-gate err = add_all_nodes();
299*0Sstevel@tonic-gate if (err != PICL_SUCCESS) {
300*0Sstevel@tonic-gate (void) remove_all_nodes(frutreeh);
301*0Sstevel@tonic-gate return;
302*0Sstevel@tonic-gate }
303*0Sstevel@tonic-gate
304*0Sstevel@tonic-gate /* Register the event handler routine */
305*0Sstevel@tonic-gate (void) ptree_register_handler(PICLEVENT_SYSEVENT_DEVICE_ADDED,
306*0Sstevel@tonic-gate picl_frutree_evhandler, NULL);
307*0Sstevel@tonic-gate (void) ptree_register_handler(PICLEVENT_SYSEVENT_DEVICE_REMOVED,
308*0Sstevel@tonic-gate picl_frutree_evhandler, NULL);
309*0Sstevel@tonic-gate }
310*0Sstevel@tonic-gate
311*0Sstevel@tonic-gate /*
312*0Sstevel@tonic-gate * This function is the fini entry point of the plugin
313*0Sstevel@tonic-gate */
314*0Sstevel@tonic-gate static void
picl_frutree_fini(void)315*0Sstevel@tonic-gate picl_frutree_fini(void)
316*0Sstevel@tonic-gate {
317*0Sstevel@tonic-gate /* Unregister the event handler routine */
318*0Sstevel@tonic-gate (void) ptree_unregister_handler(PICLEVENT_SYSEVENT_DEVICE_ADDED,
319*0Sstevel@tonic-gate picl_frutree_evhandler, NULL);
320*0Sstevel@tonic-gate (void) ptree_unregister_handler(PICLEVENT_SYSEVENT_DEVICE_REMOVED,
321*0Sstevel@tonic-gate picl_frutree_evhandler, NULL);
322*0Sstevel@tonic-gate
323*0Sstevel@tonic-gate (void) remove_all_nodes(frutreeh);
324*0Sstevel@tonic-gate }
325*0Sstevel@tonic-gate
326*0Sstevel@tonic-gate /*
327*0Sstevel@tonic-gate * This function is the event handler of this plug-in.
328*0Sstevel@tonic-gate *
329*0Sstevel@tonic-gate * It processes the following events:
330*0Sstevel@tonic-gate *
331*0Sstevel@tonic-gate * PICLEVENT_SYSEVENT_DEVICE_ADDED
332*0Sstevel@tonic-gate * PICLEVENT_SYSEVENT_DEVICE_REMOVED
333*0Sstevel@tonic-gate */
334*0Sstevel@tonic-gate /* ARGSUSED */
335*0Sstevel@tonic-gate static void
picl_frutree_evhandler(const char * ename,const void * earg,size_t size,void * cookie)336*0Sstevel@tonic-gate picl_frutree_evhandler(const char *ename, const void *earg, size_t size,
337*0Sstevel@tonic-gate void *cookie)
338*0Sstevel@tonic-gate {
339*0Sstevel@tonic-gate if (strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_ADDED) == 0) {
340*0Sstevel@tonic-gate /* Check for and add any hotplugged device(s) */
341*0Sstevel@tonic-gate (void) add_hotplug_fru_device();
342*0Sstevel@tonic-gate
343*0Sstevel@tonic-gate } else if (strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_REMOVED) == 0) {
344*0Sstevel@tonic-gate /* Check for and remove any hotplugged device(s) */
345*0Sstevel@tonic-gate (void) rem_hotplug_fru_device();
346*0Sstevel@tonic-gate }
347*0Sstevel@tonic-gate }
348*0Sstevel@tonic-gate
349*0Sstevel@tonic-gate /* Initializes the FRU nodes for the IO board */
350*0Sstevel@tonic-gate static int
do_ioboard_init(picl_nodehdl_t rooth)351*0Sstevel@tonic-gate do_ioboard_init(picl_nodehdl_t rooth)
352*0Sstevel@tonic-gate {
353*0Sstevel@tonic-gate picl_nodehdl_t iobrdh;
354*0Sstevel@tonic-gate picl_nodehdl_t tmph;
355*0Sstevel@tonic-gate int err;
356*0Sstevel@tonic-gate
357*0Sstevel@tonic-gate /* Create the node for the IO board (if it exists) */
358*0Sstevel@tonic-gate if (ptree_get_node_by_path(platform_frupath[IOBRD], &tmph) ==
359*0Sstevel@tonic-gate PICL_SUCCESS) {
360*0Sstevel@tonic-gate err = ptree_create_node("io-board", "fru", &iobrdh);
361*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
362*0Sstevel@tonic-gate return (err);
363*0Sstevel@tonic-gate
364*0Sstevel@tonic-gate err = add_ref_prop(iobrdh, tmph, SEEPROM_SOURCE);
365*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
366*0Sstevel@tonic-gate return (err);
367*0Sstevel@tonic-gate
368*0Sstevel@tonic-gate err = add_void_fda_prop(iobrdh);
369*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
370*0Sstevel@tonic-gate return (err);
371*0Sstevel@tonic-gate
372*0Sstevel@tonic-gate err = ptree_add_node(rooth, iobrdh);
373*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
374*0Sstevel@tonic-gate return (err);
375*0Sstevel@tonic-gate
376*0Sstevel@tonic-gate err = add_ref_prop(tmph, iobrdh, FRU_PARENT);
377*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
378*0Sstevel@tonic-gate return (err);
379*0Sstevel@tonic-gate }
380*0Sstevel@tonic-gate return (PICL_SUCCESS);
381*0Sstevel@tonic-gate }
382*0Sstevel@tonic-gate
383*0Sstevel@tonic-gate /* Initializes the FRU node for the RSC card */
384*0Sstevel@tonic-gate static int
do_rscboard_init(picl_nodehdl_t rooth)385*0Sstevel@tonic-gate do_rscboard_init(picl_nodehdl_t rooth)
386*0Sstevel@tonic-gate {
387*0Sstevel@tonic-gate picl_nodehdl_t rscbrdh;
388*0Sstevel@tonic-gate picl_nodehdl_t tmph;
389*0Sstevel@tonic-gate int err;
390*0Sstevel@tonic-gate
391*0Sstevel@tonic-gate /* Create the node for the RSC board (if it exists) */
392*0Sstevel@tonic-gate if (ptree_get_node_by_path(platform_frupath[RSC], &tmph) ==
393*0Sstevel@tonic-gate PICL_SUCCESS) {
394*0Sstevel@tonic-gate err = ptree_create_node("rsc-board", "fru", &rscbrdh);
395*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
396*0Sstevel@tonic-gate return (err);
397*0Sstevel@tonic-gate
398*0Sstevel@tonic-gate err = add_ref_prop(rscbrdh, tmph, SEEPROM_SOURCE);
399*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
400*0Sstevel@tonic-gate return (err);
401*0Sstevel@tonic-gate
402*0Sstevel@tonic-gate err = add_void_fda_prop(rscbrdh);
403*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
404*0Sstevel@tonic-gate return (err);
405*0Sstevel@tonic-gate
406*0Sstevel@tonic-gate err = ptree_add_node(rooth, rscbrdh);
407*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
408*0Sstevel@tonic-gate return (err);
409*0Sstevel@tonic-gate
410*0Sstevel@tonic-gate err = add_ref_prop(tmph, rscbrdh, FRU_PARENT);
411*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
412*0Sstevel@tonic-gate return (err);
413*0Sstevel@tonic-gate }
414*0Sstevel@tonic-gate return (PICL_SUCCESS);
415*0Sstevel@tonic-gate }
416*0Sstevel@tonic-gate
417*0Sstevel@tonic-gate /* Initializes the FRU nodes for the FCAL backplanes and GBIC card */
418*0Sstevel@tonic-gate static int
do_fcal_init(picl_nodehdl_t rooth)419*0Sstevel@tonic-gate do_fcal_init(picl_nodehdl_t rooth)
420*0Sstevel@tonic-gate {
421*0Sstevel@tonic-gate picl_nodehdl_t fcalsloth;
422*0Sstevel@tonic-gate picl_nodehdl_t fcalmodh;
423*0Sstevel@tonic-gate picl_nodehdl_t fcalgbich;
424*0Sstevel@tonic-gate picl_nodehdl_t tmph;
425*0Sstevel@tonic-gate int i, err, slotnum;
426*0Sstevel@tonic-gate
427*0Sstevel@tonic-gate for (i = FCAL0; i <= FCAL1; i++) {
428*0Sstevel@tonic-gate /* Create the node for the FCAL backplane slot */
429*0Sstevel@tonic-gate err = ptree_create_node("fcal-backplane-slot",
430*0Sstevel@tonic-gate "location", &fcalsloth);
431*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
432*0Sstevel@tonic-gate return (err);
433*0Sstevel@tonic-gate
434*0Sstevel@tonic-gate slotnum = i - FCAL0;
435*0Sstevel@tonic-gate err = add_slot_prop(fcalsloth, slotnum);
436*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
437*0Sstevel@tonic-gate return (err);
438*0Sstevel@tonic-gate
439*0Sstevel@tonic-gate err = add_label_prop(fcalsloth, location_label[i]);
440*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
441*0Sstevel@tonic-gate return (err);
442*0Sstevel@tonic-gate
443*0Sstevel@tonic-gate err = ptree_add_node(rooth, fcalsloth);
444*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
445*0Sstevel@tonic-gate return (err);
446*0Sstevel@tonic-gate
447*0Sstevel@tonic-gate /* If the FCAL backplane exists, create a node for it */
448*0Sstevel@tonic-gate if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
449*0Sstevel@tonic-gate PICL_SUCCESS) {
450*0Sstevel@tonic-gate err = ptree_create_node("fcal-backplane", "fru",
451*0Sstevel@tonic-gate &fcalmodh);
452*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
453*0Sstevel@tonic-gate return (err);
454*0Sstevel@tonic-gate
455*0Sstevel@tonic-gate err = add_ref_prop(fcalmodh, tmph, SEEPROM_SOURCE);
456*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
457*0Sstevel@tonic-gate return (err);
458*0Sstevel@tonic-gate
459*0Sstevel@tonic-gate err = add_void_fda_prop(fcalmodh);
460*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
461*0Sstevel@tonic-gate return (err);
462*0Sstevel@tonic-gate
463*0Sstevel@tonic-gate err = ptree_add_node(fcalsloth, fcalmodh);
464*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
465*0Sstevel@tonic-gate return (err);
466*0Sstevel@tonic-gate
467*0Sstevel@tonic-gate err = add_ref_prop(tmph, fcalmodh, FRU_PARENT);
468*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
469*0Sstevel@tonic-gate return (err);
470*0Sstevel@tonic-gate }
471*0Sstevel@tonic-gate }
472*0Sstevel@tonic-gate
473*0Sstevel@tonic-gate /* If the FCAL GBIC board exists, create a node for it */
474*0Sstevel@tonic-gate if (ptree_get_node_by_path(platform_frupath[FCALGBIC], &tmph) ==
475*0Sstevel@tonic-gate PICL_SUCCESS) {
476*0Sstevel@tonic-gate err = ptree_create_node("fcal-gbic-board", "fru",
477*0Sstevel@tonic-gate &fcalgbich);
478*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
479*0Sstevel@tonic-gate return (err);
480*0Sstevel@tonic-gate
481*0Sstevel@tonic-gate err = add_ref_prop(fcalgbich, tmph, SEEPROM_SOURCE);
482*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
483*0Sstevel@tonic-gate return (err);
484*0Sstevel@tonic-gate
485*0Sstevel@tonic-gate err = add_void_fda_prop(fcalgbich);
486*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
487*0Sstevel@tonic-gate return (err);
488*0Sstevel@tonic-gate
489*0Sstevel@tonic-gate err = ptree_add_node(rooth, fcalgbich);
490*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
491*0Sstevel@tonic-gate return (err);
492*0Sstevel@tonic-gate
493*0Sstevel@tonic-gate err = add_ref_prop(tmph, fcalgbich, FRU_PARENT);
494*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
495*0Sstevel@tonic-gate return (err);
496*0Sstevel@tonic-gate }
497*0Sstevel@tonic-gate return (PICL_SUCCESS);
498*0Sstevel@tonic-gate }
499*0Sstevel@tonic-gate
500*0Sstevel@tonic-gate /* Initializes the FRU nodes for the PDB and the power supplies */
501*0Sstevel@tonic-gate static int
do_power_supplies_init(picl_nodehdl_t rooth)502*0Sstevel@tonic-gate do_power_supplies_init(picl_nodehdl_t rooth)
503*0Sstevel@tonic-gate {
504*0Sstevel@tonic-gate picl_nodehdl_t powerbrdh;
505*0Sstevel@tonic-gate picl_nodehdl_t powersloth;
506*0Sstevel@tonic-gate picl_nodehdl_t powermodh;
507*0Sstevel@tonic-gate picl_nodehdl_t tmph;
508*0Sstevel@tonic-gate int i, err, slotnum;
509*0Sstevel@tonic-gate
510*0Sstevel@tonic-gate /* Create the node for the PDB (if it exists) */
511*0Sstevel@tonic-gate if (ptree_get_node_by_path(platform_frupath[PDB], &tmph) ==
512*0Sstevel@tonic-gate PICL_SUCCESS) {
513*0Sstevel@tonic-gate err = ptree_create_node("power-dist-board", "fru", &powerbrdh);
514*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
515*0Sstevel@tonic-gate return (err);
516*0Sstevel@tonic-gate
517*0Sstevel@tonic-gate err = add_ref_prop(powerbrdh, tmph, SEEPROM_SOURCE);
518*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
519*0Sstevel@tonic-gate return (err);
520*0Sstevel@tonic-gate
521*0Sstevel@tonic-gate err = add_void_fda_prop(powerbrdh);
522*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
523*0Sstevel@tonic-gate return (err);
524*0Sstevel@tonic-gate
525*0Sstevel@tonic-gate err = ptree_add_node(rooth, powerbrdh);
526*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
527*0Sstevel@tonic-gate return (err);
528*0Sstevel@tonic-gate
529*0Sstevel@tonic-gate err = add_ref_prop(tmph, powerbrdh, FRU_PARENT);
530*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
531*0Sstevel@tonic-gate return (err);
532*0Sstevel@tonic-gate
533*0Sstevel@tonic-gate for (i = PS0; i <= PS2; i++) {
534*0Sstevel@tonic-gate /* Create the node for the power supply slot */
535*0Sstevel@tonic-gate err = ptree_create_node("power-supply-slot",
536*0Sstevel@tonic-gate "location", &powersloth);
537*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
538*0Sstevel@tonic-gate return (err);
539*0Sstevel@tonic-gate
540*0Sstevel@tonic-gate slotnum = i - PS0;
541*0Sstevel@tonic-gate err = add_slot_prop(powersloth, slotnum);
542*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
543*0Sstevel@tonic-gate return (err);
544*0Sstevel@tonic-gate
545*0Sstevel@tonic-gate err = add_label_prop(powersloth, location_label[i]);
546*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
547*0Sstevel@tonic-gate return (err);
548*0Sstevel@tonic-gate
549*0Sstevel@tonic-gate err = ptree_add_node(powerbrdh, powersloth);
550*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
551*0Sstevel@tonic-gate return (err);
552*0Sstevel@tonic-gate
553*0Sstevel@tonic-gate /* If the PS exists, create a node for it */
554*0Sstevel@tonic-gate if (ptree_get_node_by_path(platform_frupath[i],
555*0Sstevel@tonic-gate &tmph) == PICL_SUCCESS) {
556*0Sstevel@tonic-gate err = ptree_create_node("power-supply",
557*0Sstevel@tonic-gate "fru", &powermodh);
558*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
559*0Sstevel@tonic-gate return (err);
560*0Sstevel@tonic-gate
561*0Sstevel@tonic-gate err = add_ref_prop(powermodh, tmph,
562*0Sstevel@tonic-gate SEEPROM_SOURCE);
563*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
564*0Sstevel@tonic-gate return (err);
565*0Sstevel@tonic-gate
566*0Sstevel@tonic-gate err = add_void_fda_prop(powermodh);
567*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
568*0Sstevel@tonic-gate return (err);
569*0Sstevel@tonic-gate
570*0Sstevel@tonic-gate err = ptree_add_node(powersloth, powermodh);
571*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
572*0Sstevel@tonic-gate return (err);
573*0Sstevel@tonic-gate
574*0Sstevel@tonic-gate err = add_ref_prop(tmph, powermodh, FRU_PARENT);
575*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
576*0Sstevel@tonic-gate return (err);
577*0Sstevel@tonic-gate }
578*0Sstevel@tonic-gate }
579*0Sstevel@tonic-gate }
580*0Sstevel@tonic-gate return (PICL_SUCCESS);
581*0Sstevel@tonic-gate }
582*0Sstevel@tonic-gate
583*0Sstevel@tonic-gate /* Initializes the FRU nodes for the motherboard and CPU Memory modules */
584*0Sstevel@tonic-gate static int
do_motherboard_init(picl_nodehdl_t rooth)585*0Sstevel@tonic-gate do_motherboard_init(picl_nodehdl_t rooth)
586*0Sstevel@tonic-gate {
587*0Sstevel@tonic-gate picl_nodehdl_t sysboardh;
588*0Sstevel@tonic-gate picl_nodehdl_t cpumemsloth;
589*0Sstevel@tonic-gate picl_nodehdl_t cpumemmodh;
590*0Sstevel@tonic-gate picl_nodehdl_t tmph;
591*0Sstevel@tonic-gate int i, err, slotnum;
592*0Sstevel@tonic-gate
593*0Sstevel@tonic-gate /* Create the node for the system board (if it exists) */
594*0Sstevel@tonic-gate if (ptree_get_node_by_path(platform_frupath[SYSBRD], &tmph) ==
595*0Sstevel@tonic-gate PICL_SUCCESS) {
596*0Sstevel@tonic-gate err = ptree_create_node("system-board", "fru",
597*0Sstevel@tonic-gate &sysboardh);
598*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
599*0Sstevel@tonic-gate return (err);
600*0Sstevel@tonic-gate
601*0Sstevel@tonic-gate err = add_ref_prop(sysboardh, tmph, SEEPROM_SOURCE);
602*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
603*0Sstevel@tonic-gate return (err);
604*0Sstevel@tonic-gate
605*0Sstevel@tonic-gate err = add_void_fda_prop(sysboardh);
606*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
607*0Sstevel@tonic-gate return (err);
608*0Sstevel@tonic-gate
609*0Sstevel@tonic-gate err = ptree_add_node(rooth, sysboardh);
610*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
611*0Sstevel@tonic-gate return (err);
612*0Sstevel@tonic-gate
613*0Sstevel@tonic-gate err = add_ref_prop(tmph, sysboardh, FRU_PARENT);
614*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
615*0Sstevel@tonic-gate return (err);
616*0Sstevel@tonic-gate
617*0Sstevel@tonic-gate for (i = CPUMOD0; i <= CPUMOD3; i++) {
618*0Sstevel@tonic-gate /* Create the node for the CPU Memory slot */
619*0Sstevel@tonic-gate err = ptree_create_node("cpu-mem-slot", "location",
620*0Sstevel@tonic-gate &cpumemsloth);
621*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
622*0Sstevel@tonic-gate return (err);
623*0Sstevel@tonic-gate
624*0Sstevel@tonic-gate slotnum = i - CPUMOD0;
625*0Sstevel@tonic-gate err = add_slot_prop(cpumemsloth, slotnum);
626*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
627*0Sstevel@tonic-gate return (err);
628*0Sstevel@tonic-gate
629*0Sstevel@tonic-gate err = add_label_prop(cpumemsloth, location_label[i]);
630*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
631*0Sstevel@tonic-gate return (err);
632*0Sstevel@tonic-gate
633*0Sstevel@tonic-gate err = ptree_add_node(sysboardh, cpumemsloth);
634*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
635*0Sstevel@tonic-gate return (err);
636*0Sstevel@tonic-gate
637*0Sstevel@tonic-gate /* If CPU Mem module exists, create a node for it */
638*0Sstevel@tonic-gate if (ptree_get_node_by_path(platform_frupath[i],
639*0Sstevel@tonic-gate &tmph) == PICL_SUCCESS) {
640*0Sstevel@tonic-gate err = ptree_create_node("cpu-mem-module",
641*0Sstevel@tonic-gate "fru", &cpumemmodh);
642*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
643*0Sstevel@tonic-gate return (err);
644*0Sstevel@tonic-gate
645*0Sstevel@tonic-gate err = add_ref_prop(cpumemmodh, tmph,
646*0Sstevel@tonic-gate SEEPROM_SOURCE);
647*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
648*0Sstevel@tonic-gate return (err);
649*0Sstevel@tonic-gate
650*0Sstevel@tonic-gate err = add_void_fda_prop(cpumemmodh);
651*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
652*0Sstevel@tonic-gate return (err);
653*0Sstevel@tonic-gate
654*0Sstevel@tonic-gate err = ptree_add_node(cpumemsloth, cpumemmodh);
655*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
656*0Sstevel@tonic-gate return (err);
657*0Sstevel@tonic-gate
658*0Sstevel@tonic-gate err = add_ref_prop(tmph, cpumemmodh,
659*0Sstevel@tonic-gate FRU_PARENT);
660*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
661*0Sstevel@tonic-gate return (err);
662*0Sstevel@tonic-gate
663*0Sstevel@tonic-gate err = do_cpu_module_init(cpumemmodh, slotnum);
664*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
665*0Sstevel@tonic-gate return (err);
666*0Sstevel@tonic-gate }
667*0Sstevel@tonic-gate }
668*0Sstevel@tonic-gate }
669*0Sstevel@tonic-gate return (PICL_SUCCESS);
670*0Sstevel@tonic-gate }
671*0Sstevel@tonic-gate
672*0Sstevel@tonic-gate /* Creates the FRU nodes for the CPU Module and associated DIMMs */
673*0Sstevel@tonic-gate static int
do_cpu_module_init(picl_nodehdl_t rooth,int slot)674*0Sstevel@tonic-gate do_cpu_module_init(picl_nodehdl_t rooth, int slot)
675*0Sstevel@tonic-gate {
676*0Sstevel@tonic-gate picl_nodehdl_t cpumodh;
677*0Sstevel@tonic-gate int i, c, err;
678*0Sstevel@tonic-gate
679*0Sstevel@tonic-gate for (i = 0; i <= 1; i++) {
680*0Sstevel@tonic-gate err = ptree_create_node("cpu-module", "location",
681*0Sstevel@tonic-gate &cpumodh);
682*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
683*0Sstevel@tonic-gate return (err);
684*0Sstevel@tonic-gate
685*0Sstevel@tonic-gate err = add_slot_prop(cpumodh, i);
686*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
687*0Sstevel@tonic-gate return (err);
688*0Sstevel@tonic-gate
689*0Sstevel@tonic-gate c = CPU0_DIMM0 + DIMMS_PER_SLOT + i;
690*0Sstevel@tonic-gate
691*0Sstevel@tonic-gate err = add_label_prop(cpumodh, location_label[c]);
692*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
693*0Sstevel@tonic-gate return (err);
694*0Sstevel@tonic-gate
695*0Sstevel@tonic-gate err = ptree_add_node(rooth, cpumodh);
696*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
697*0Sstevel@tonic-gate return (err);
698*0Sstevel@tonic-gate
699*0Sstevel@tonic-gate /* Create the nodes for the memory (if they exist) */
700*0Sstevel@tonic-gate err = do_dimms_init(cpumodh, slot, i);
701*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
702*0Sstevel@tonic-gate return (err);
703*0Sstevel@tonic-gate }
704*0Sstevel@tonic-gate return (PICL_SUCCESS);
705*0Sstevel@tonic-gate }
706*0Sstevel@tonic-gate
707*0Sstevel@tonic-gate /* Creates the FRU nodes for the DIMMs on a particular CPU Module */
708*0Sstevel@tonic-gate static int
do_dimms_init(picl_nodehdl_t rooth,int slot,int module)709*0Sstevel@tonic-gate do_dimms_init(picl_nodehdl_t rooth, int slot, int module)
710*0Sstevel@tonic-gate {
711*0Sstevel@tonic-gate picl_nodehdl_t dimmsloth;
712*0Sstevel@tonic-gate picl_nodehdl_t dimmmodh;
713*0Sstevel@tonic-gate picl_nodehdl_t tmph;
714*0Sstevel@tonic-gate int i, c, l, err;
715*0Sstevel@tonic-gate
716*0Sstevel@tonic-gate for (i = 0; i < DIMMS_PER_MOD; i++) {
717*0Sstevel@tonic-gate /* Create the node for the memory slot */
718*0Sstevel@tonic-gate err = ptree_create_node("dimm-slot", "location",
719*0Sstevel@tonic-gate &dimmsloth);
720*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
721*0Sstevel@tonic-gate return (err);
722*0Sstevel@tonic-gate
723*0Sstevel@tonic-gate err = add_slot_prop(dimmsloth, i);
724*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
725*0Sstevel@tonic-gate return (err);
726*0Sstevel@tonic-gate
727*0Sstevel@tonic-gate c = ((slot * DIMMS_PER_SLOT) +
728*0Sstevel@tonic-gate (module * DIMMS_PER_MOD) + i) + CPU0_DIMM0;
729*0Sstevel@tonic-gate
730*0Sstevel@tonic-gate l = c - (DIMMS_PER_SLOT * slot);
731*0Sstevel@tonic-gate
732*0Sstevel@tonic-gate err = add_label_prop(dimmsloth, location_label[l]);
733*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
734*0Sstevel@tonic-gate return (err);
735*0Sstevel@tonic-gate
736*0Sstevel@tonic-gate err = ptree_add_node(rooth, dimmsloth);
737*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
738*0Sstevel@tonic-gate return (err);
739*0Sstevel@tonic-gate
740*0Sstevel@tonic-gate /* If the memory module exists, create a node for it */
741*0Sstevel@tonic-gate if (ptree_get_node_by_path(platform_frupath[c], &tmph) ==
742*0Sstevel@tonic-gate PICL_SUCCESS) {
743*0Sstevel@tonic-gate err = ptree_create_node("dimm-module", "fru",
744*0Sstevel@tonic-gate &dimmmodh);
745*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
746*0Sstevel@tonic-gate return (err);
747*0Sstevel@tonic-gate
748*0Sstevel@tonic-gate err = add_ref_prop(dimmmodh, tmph, SEEPROM_SOURCE);
749*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
750*0Sstevel@tonic-gate return (err);
751*0Sstevel@tonic-gate
752*0Sstevel@tonic-gate err = add_void_fda_prop(dimmmodh);
753*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
754*0Sstevel@tonic-gate return (err);
755*0Sstevel@tonic-gate
756*0Sstevel@tonic-gate err = ptree_add_node(dimmsloth, dimmmodh);
757*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
758*0Sstevel@tonic-gate return (err);
759*0Sstevel@tonic-gate
760*0Sstevel@tonic-gate err = add_ref_prop(tmph, dimmmodh, FRU_PARENT);
761*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
762*0Sstevel@tonic-gate return (err);
763*0Sstevel@tonic-gate }
764*0Sstevel@tonic-gate }
765*0Sstevel@tonic-gate return (PICL_SUCCESS);
766*0Sstevel@tonic-gate }
767*0Sstevel@tonic-gate
768*0Sstevel@tonic-gate /* Creates a "reference" property between two PICL nodes */
769*0Sstevel@tonic-gate static int
add_ref_prop(picl_nodehdl_t nodeh,picl_nodehdl_t tmph,char * str)770*0Sstevel@tonic-gate add_ref_prop(picl_nodehdl_t nodeh, picl_nodehdl_t tmph, char *str)
771*0Sstevel@tonic-gate {
772*0Sstevel@tonic-gate picl_prophdl_t proph;
773*0Sstevel@tonic-gate ptree_propinfo_t propinfo;
774*0Sstevel@tonic-gate int err;
775*0Sstevel@tonic-gate
776*0Sstevel@tonic-gate if (str == NULL)
777*0Sstevel@tonic-gate return (PICL_FAILURE);
778*0Sstevel@tonic-gate
779*0Sstevel@tonic-gate err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
780*0Sstevel@tonic-gate PICL_PTYPE_REFERENCE, PICL_READ, sizeof (picl_nodehdl_t),
781*0Sstevel@tonic-gate str, NULL, NULL);
782*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
783*0Sstevel@tonic-gate return (err);
784*0Sstevel@tonic-gate
785*0Sstevel@tonic-gate err = ptree_create_and_add_prop(nodeh, &propinfo, &tmph, &proph);
786*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
787*0Sstevel@tonic-gate return (err);
788*0Sstevel@tonic-gate
789*0Sstevel@tonic-gate return (PICL_SUCCESS);
790*0Sstevel@tonic-gate }
791*0Sstevel@tonic-gate
792*0Sstevel@tonic-gate /* Creates a "slot" property for a given PICL node */
793*0Sstevel@tonic-gate static int
add_slot_prop(picl_nodehdl_t nodeh,int slotnum)794*0Sstevel@tonic-gate add_slot_prop(picl_nodehdl_t nodeh, int slotnum)
795*0Sstevel@tonic-gate {
796*0Sstevel@tonic-gate picl_prophdl_t proph;
797*0Sstevel@tonic-gate ptree_propinfo_t propinfo;
798*0Sstevel@tonic-gate int err;
799*0Sstevel@tonic-gate
800*0Sstevel@tonic-gate err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
801*0Sstevel@tonic-gate PICL_PTYPE_INT, PICL_READ, 4, "Slot", NULL, NULL);
802*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
803*0Sstevel@tonic-gate return (err);
804*0Sstevel@tonic-gate
805*0Sstevel@tonic-gate err = ptree_create_and_add_prop(nodeh, &propinfo, &slotnum, &proph);
806*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
807*0Sstevel@tonic-gate return (err);
808*0Sstevel@tonic-gate
809*0Sstevel@tonic-gate return (PICL_SUCCESS);
810*0Sstevel@tonic-gate }
811*0Sstevel@tonic-gate
812*0Sstevel@tonic-gate /* Creates a "Label" property for a given PICL node */
813*0Sstevel@tonic-gate static int
add_label_prop(picl_nodehdl_t nodeh,char * label)814*0Sstevel@tonic-gate add_label_prop(picl_nodehdl_t nodeh, char *label)
815*0Sstevel@tonic-gate {
816*0Sstevel@tonic-gate picl_prophdl_t proph;
817*0Sstevel@tonic-gate ptree_propinfo_t propinfo;
818*0Sstevel@tonic-gate int err;
819*0Sstevel@tonic-gate
820*0Sstevel@tonic-gate if (label == NULL)
821*0Sstevel@tonic-gate return (PICL_FAILURE);
822*0Sstevel@tonic-gate
823*0Sstevel@tonic-gate err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
824*0Sstevel@tonic-gate PICL_PTYPE_CHARSTRING, PICL_READ, strlen(label)+1, "Label",
825*0Sstevel@tonic-gate NULL, NULL);
826*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
827*0Sstevel@tonic-gate return (err);
828*0Sstevel@tonic-gate
829*0Sstevel@tonic-gate err = ptree_create_and_add_prop(nodeh, &propinfo, label, &proph);
830*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
831*0Sstevel@tonic-gate return (err);
832*0Sstevel@tonic-gate
833*0Sstevel@tonic-gate return (PICL_SUCCESS);
834*0Sstevel@tonic-gate }
835*0Sstevel@tonic-gate
836*0Sstevel@tonic-gate /* Creates a "FRUDataAvailable" void property for the given PICL node */
837*0Sstevel@tonic-gate static int
add_void_fda_prop(picl_nodehdl_t nodeh)838*0Sstevel@tonic-gate add_void_fda_prop(picl_nodehdl_t nodeh)
839*0Sstevel@tonic-gate {
840*0Sstevel@tonic-gate picl_prophdl_t proph;
841*0Sstevel@tonic-gate ptree_propinfo_t propinfo;
842*0Sstevel@tonic-gate int err;
843*0Sstevel@tonic-gate
844*0Sstevel@tonic-gate err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
845*0Sstevel@tonic-gate PICL_PTYPE_VOID, PICL_READ, 0, "FRUDataAvailable", NULL, NULL);
846*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
847*0Sstevel@tonic-gate return (err);
848*0Sstevel@tonic-gate
849*0Sstevel@tonic-gate err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, &proph);
850*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
851*0Sstevel@tonic-gate return (err);
852*0Sstevel@tonic-gate
853*0Sstevel@tonic-gate return (PICL_SUCCESS);
854*0Sstevel@tonic-gate }
855*0Sstevel@tonic-gate
856*0Sstevel@tonic-gate /* Creates a "ViewPoints" property -- used for chassis */
857*0Sstevel@tonic-gate static int
add_viewpoints_prop(picl_nodehdl_t nodeh,char * string)858*0Sstevel@tonic-gate add_viewpoints_prop(picl_nodehdl_t nodeh, char *string)
859*0Sstevel@tonic-gate {
860*0Sstevel@tonic-gate picl_prophdl_t proph;
861*0Sstevel@tonic-gate ptree_propinfo_t propinfo;
862*0Sstevel@tonic-gate int err;
863*0Sstevel@tonic-gate
864*0Sstevel@tonic-gate if (string == NULL)
865*0Sstevel@tonic-gate return (PICL_FAILURE);
866*0Sstevel@tonic-gate
867*0Sstevel@tonic-gate err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
868*0Sstevel@tonic-gate PICL_PTYPE_CHARSTRING, PICL_READ, strlen(string)+1, "ViewPoints",
869*0Sstevel@tonic-gate NULL, NULL);
870*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
871*0Sstevel@tonic-gate return (err);
872*0Sstevel@tonic-gate
873*0Sstevel@tonic-gate err = ptree_create_and_add_prop(nodeh, &propinfo, string, &proph);
874*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
875*0Sstevel@tonic-gate return (err);
876*0Sstevel@tonic-gate
877*0Sstevel@tonic-gate return (PICL_SUCCESS);
878*0Sstevel@tonic-gate }
879*0Sstevel@tonic-gate
880*0Sstevel@tonic-gate /* Creates and adds all of the frutree nodes */
881*0Sstevel@tonic-gate static int
add_all_nodes()882*0Sstevel@tonic-gate add_all_nodes()
883*0Sstevel@tonic-gate {
884*0Sstevel@tonic-gate picl_nodehdl_t rooth;
885*0Sstevel@tonic-gate picl_nodehdl_t chassish;
886*0Sstevel@tonic-gate int err;
887*0Sstevel@tonic-gate
888*0Sstevel@tonic-gate /* Get the root node of the PICL tree */
889*0Sstevel@tonic-gate err = ptree_get_root(&rooth);
890*0Sstevel@tonic-gate if (err != PICL_SUCCESS) {
891*0Sstevel@tonic-gate return (err);
892*0Sstevel@tonic-gate }
893*0Sstevel@tonic-gate
894*0Sstevel@tonic-gate /* Create and add the root node of the FRU subtree */
895*0Sstevel@tonic-gate err = ptree_create_and_add_node(rooth, "frutree", "picl", &frutreeh);
896*0Sstevel@tonic-gate if (err != PICL_SUCCESS) {
897*0Sstevel@tonic-gate syslog(LOG_ERR, CREATE_FRUTREE_FAIL);
898*0Sstevel@tonic-gate return (err);
899*0Sstevel@tonic-gate }
900*0Sstevel@tonic-gate
901*0Sstevel@tonic-gate /* Create and add the chassis node */
902*0Sstevel@tonic-gate err = ptree_create_and_add_node(frutreeh, "chassis", "fru", &chassish);
903*0Sstevel@tonic-gate if (err != PICL_SUCCESS) {
904*0Sstevel@tonic-gate syslog(LOG_ERR, CREATE_CHASSIS_FAIL);
905*0Sstevel@tonic-gate return (err);
906*0Sstevel@tonic-gate }
907*0Sstevel@tonic-gate
908*0Sstevel@tonic-gate /* Add ViewPoints prop to chassis node */
909*0Sstevel@tonic-gate err = add_viewpoints_prop(chassish, CHASSIS_VIEWPOINTS);
910*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
911*0Sstevel@tonic-gate return (err);
912*0Sstevel@tonic-gate
913*0Sstevel@tonic-gate /* Initialize the FRU nodes for the IO board */
914*0Sstevel@tonic-gate err = do_ioboard_init(chassish);
915*0Sstevel@tonic-gate if (err != PICL_SUCCESS) {
916*0Sstevel@tonic-gate syslog(LOG_ERR, IOBRD_INIT_FAIL);
917*0Sstevel@tonic-gate return (err);
918*0Sstevel@tonic-gate }
919*0Sstevel@tonic-gate
920*0Sstevel@tonic-gate /* Initialize the FRU node for the RSC card */
921*0Sstevel@tonic-gate err = do_rscboard_init(chassish);
922*0Sstevel@tonic-gate if (err != PICL_SUCCESS) {
923*0Sstevel@tonic-gate syslog(LOG_ERR, RSCBRD_INIT_FAIL);
924*0Sstevel@tonic-gate return (err);
925*0Sstevel@tonic-gate }
926*0Sstevel@tonic-gate
927*0Sstevel@tonic-gate /* Initialize the FRU nodes for the FCAL backplanes and GBIC board */
928*0Sstevel@tonic-gate err = do_fcal_init(chassish);
929*0Sstevel@tonic-gate if (err != PICL_SUCCESS) {
930*0Sstevel@tonic-gate syslog(LOG_ERR, FCAL_INIT_FAIL);
931*0Sstevel@tonic-gate return (err);
932*0Sstevel@tonic-gate }
933*0Sstevel@tonic-gate
934*0Sstevel@tonic-gate /* Initialize the FRU nodes for the PDB and the power supplies */
935*0Sstevel@tonic-gate err = do_power_supplies_init(chassish);
936*0Sstevel@tonic-gate if (err != PICL_SUCCESS) {
937*0Sstevel@tonic-gate syslog(LOG_ERR, PS_INIT_FAIL);
938*0Sstevel@tonic-gate return (err);
939*0Sstevel@tonic-gate }
940*0Sstevel@tonic-gate
941*0Sstevel@tonic-gate /* Initialize the FRU nodes for the CPU Memory modules */
942*0Sstevel@tonic-gate err = do_motherboard_init(chassish);
943*0Sstevel@tonic-gate if (err != PICL_SUCCESS) {
944*0Sstevel@tonic-gate syslog(LOG_ERR, SYSBOARD_INIT_FAIL);
945*0Sstevel@tonic-gate return (err);
946*0Sstevel@tonic-gate }
947*0Sstevel@tonic-gate
948*0Sstevel@tonic-gate return (PICL_SUCCESS);
949*0Sstevel@tonic-gate }
950*0Sstevel@tonic-gate
951*0Sstevel@tonic-gate /* Deletes and destroys all PICL nodes for which rooth is a ancestor */
952*0Sstevel@tonic-gate static int
remove_all_nodes(picl_nodehdl_t rooth)953*0Sstevel@tonic-gate remove_all_nodes(picl_nodehdl_t rooth)
954*0Sstevel@tonic-gate {
955*0Sstevel@tonic-gate picl_nodehdl_t chdh;
956*0Sstevel@tonic-gate int err, done = 0;
957*0Sstevel@tonic-gate
958*0Sstevel@tonic-gate while (!done) {
959*0Sstevel@tonic-gate err = ptree_get_propval_by_name(rooth, PICL_PROP_CHILD, &chdh,
960*0Sstevel@tonic-gate sizeof (picl_nodehdl_t));
961*0Sstevel@tonic-gate if (err != PICL_PROPNOTFOUND) {
962*0Sstevel@tonic-gate (void) remove_all_nodes(chdh);
963*0Sstevel@tonic-gate } else {
964*0Sstevel@tonic-gate err = ptree_delete_node(rooth);
965*0Sstevel@tonic-gate if (err != PICL_SUCCESS) {
966*0Sstevel@tonic-gate return (err);
967*0Sstevel@tonic-gate } else {
968*0Sstevel@tonic-gate (void) ptree_destroy_node(rooth);
969*0Sstevel@tonic-gate }
970*0Sstevel@tonic-gate done = 1;
971*0Sstevel@tonic-gate }
972*0Sstevel@tonic-gate }
973*0Sstevel@tonic-gate return (PICL_SUCCESS);
974*0Sstevel@tonic-gate }
975*0Sstevel@tonic-gate
976*0Sstevel@tonic-gate /* Searches the list of hotpluggable FRUs, adds the appropriate node(s) */
977*0Sstevel@tonic-gate static int
add_hotplug_fru_device()978*0Sstevel@tonic-gate add_hotplug_fru_device()
979*0Sstevel@tonic-gate {
980*0Sstevel@tonic-gate int i, err, slotnum;
981*0Sstevel@tonic-gate
982*0Sstevel@tonic-gate /* Check for hotplugged power supplies */
983*0Sstevel@tonic-gate for (i = PS0; i <= PS2; i++) {
984*0Sstevel@tonic-gate /* Compare the /platform tree to the frutree */
985*0Sstevel@tonic-gate slotnum = i - PS0;
986*0Sstevel@tonic-gate err = is_added_device(platform_frupath[i],
987*0Sstevel@tonic-gate frutree_power_supply[slotnum]);
988*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
989*0Sstevel@tonic-gate continue;
990*0Sstevel@tonic-gate
991*0Sstevel@tonic-gate /* If they are different, then add a power supply */
992*0Sstevel@tonic-gate err = add_power_supply(slotnum);
993*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
994*0Sstevel@tonic-gate continue;
995*0Sstevel@tonic-gate }
996*0Sstevel@tonic-gate
997*0Sstevel@tonic-gate /* Check for hotplugged CPU Memory modules */
998*0Sstevel@tonic-gate for (i = CPUMOD0; i <= CPUMOD3; i++) {
999*0Sstevel@tonic-gate /* Compare the /platform tree to the frutree */
1000*0Sstevel@tonic-gate slotnum = i - CPUMOD0;
1001*0Sstevel@tonic-gate err = is_added_device(platform_frupath[i],
1002*0Sstevel@tonic-gate frutree_cpu_module[slotnum]);
1003*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1004*0Sstevel@tonic-gate continue;
1005*0Sstevel@tonic-gate
1006*0Sstevel@tonic-gate /* If they are different, then add a CPU Mem module */
1007*0Sstevel@tonic-gate err = add_cpu_module(slotnum);
1008*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1009*0Sstevel@tonic-gate continue;
1010*0Sstevel@tonic-gate }
1011*0Sstevel@tonic-gate return (PICL_SUCCESS);
1012*0Sstevel@tonic-gate }
1013*0Sstevel@tonic-gate
1014*0Sstevel@tonic-gate /* Searches the list of hotpluggable FRUs, removes the appropriate node(s) */
1015*0Sstevel@tonic-gate static int
rem_hotplug_fru_device()1016*0Sstevel@tonic-gate rem_hotplug_fru_device()
1017*0Sstevel@tonic-gate {
1018*0Sstevel@tonic-gate int i, err, slotnum;
1019*0Sstevel@tonic-gate
1020*0Sstevel@tonic-gate /* Check for hotplugged power supplies */
1021*0Sstevel@tonic-gate for (i = PS0; i <= PS2; i++) {
1022*0Sstevel@tonic-gate /* Compare the /platform tree to the frutree */
1023*0Sstevel@tonic-gate slotnum = i - PS0;
1024*0Sstevel@tonic-gate err = is_removed_device(platform_frupath[i],
1025*0Sstevel@tonic-gate frutree_power_supply[slotnum]);
1026*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1027*0Sstevel@tonic-gate continue;
1028*0Sstevel@tonic-gate
1029*0Sstevel@tonic-gate /* If they are different, then remove a power supply */
1030*0Sstevel@tonic-gate err = remove_power_supply(slotnum);
1031*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1032*0Sstevel@tonic-gate continue;
1033*0Sstevel@tonic-gate }
1034*0Sstevel@tonic-gate
1035*0Sstevel@tonic-gate /* Check for hotplugged CPU Memory modules */
1036*0Sstevel@tonic-gate for (i = CPUMOD0; i <= CPUMOD3; i++) {
1037*0Sstevel@tonic-gate /* Compare the /platform tree to the frutree */
1038*0Sstevel@tonic-gate slotnum = i - CPUMOD0;
1039*0Sstevel@tonic-gate err = is_removed_device(platform_frupath[i],
1040*0Sstevel@tonic-gate frutree_cpu_module[slotnum]);
1041*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1042*0Sstevel@tonic-gate continue;
1043*0Sstevel@tonic-gate
1044*0Sstevel@tonic-gate /* If they are different, then remove a CPU Mem module */
1045*0Sstevel@tonic-gate err = remove_cpu_module(slotnum);
1046*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1047*0Sstevel@tonic-gate continue;
1048*0Sstevel@tonic-gate }
1049*0Sstevel@tonic-gate return (PICL_SUCCESS);
1050*0Sstevel@tonic-gate }
1051*0Sstevel@tonic-gate
1052*0Sstevel@tonic-gate /*
1053*0Sstevel@tonic-gate * Compare the /platform tree to the /frutree to determine if a
1054*0Sstevel@tonic-gate * new device has been added
1055*0Sstevel@tonic-gate */
1056*0Sstevel@tonic-gate static int
is_added_device(char * plat,char * fru)1057*0Sstevel@tonic-gate is_added_device(char *plat, char *fru)
1058*0Sstevel@tonic-gate {
1059*0Sstevel@tonic-gate int err;
1060*0Sstevel@tonic-gate picl_nodehdl_t plath, frusloth, frumodh;
1061*0Sstevel@tonic-gate
1062*0Sstevel@tonic-gate /* Check for node in the /platform tree */
1063*0Sstevel@tonic-gate err = ptree_get_node_by_path(plat, &plath);
1064*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1065*0Sstevel@tonic-gate return (err);
1066*0Sstevel@tonic-gate
1067*0Sstevel@tonic-gate /*
1068*0Sstevel@tonic-gate * The node is in /platform, so find the corresponding slot in
1069*0Sstevel@tonic-gate * the frutree
1070*0Sstevel@tonic-gate */
1071*0Sstevel@tonic-gate err = ptree_get_node_by_path(fru, &frusloth);
1072*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1073*0Sstevel@tonic-gate return (err);
1074*0Sstevel@tonic-gate
1075*0Sstevel@tonic-gate /*
1076*0Sstevel@tonic-gate * If the slot in the frutree has a child, then return
1077*0Sstevel@tonic-gate * PICL_FAILURE. This means that the /platform tree and
1078*0Sstevel@tonic-gate * the frutree are consistent and no action is necessary.
1079*0Sstevel@tonic-gate * Otherwise return PICL_SUCCESS to indicate that a node needs
1080*0Sstevel@tonic-gate * to be added to the frutree
1081*0Sstevel@tonic-gate */
1082*0Sstevel@tonic-gate err = ptree_get_propval_by_name(frusloth, PICL_PROP_CHILD,
1083*0Sstevel@tonic-gate &frumodh, sizeof (picl_nodehdl_t));
1084*0Sstevel@tonic-gate if (err == PICL_SUCCESS)
1085*0Sstevel@tonic-gate return (PICL_FAILURE);
1086*0Sstevel@tonic-gate
1087*0Sstevel@tonic-gate return (PICL_SUCCESS);
1088*0Sstevel@tonic-gate }
1089*0Sstevel@tonic-gate
1090*0Sstevel@tonic-gate /*
1091*0Sstevel@tonic-gate * Compare the /platform tree to the /frutree to determine if a
1092*0Sstevel@tonic-gate * device has been removed
1093*0Sstevel@tonic-gate */
1094*0Sstevel@tonic-gate static int
is_removed_device(char * plat,char * fru)1095*0Sstevel@tonic-gate is_removed_device(char *plat, char *fru)
1096*0Sstevel@tonic-gate {
1097*0Sstevel@tonic-gate int err;
1098*0Sstevel@tonic-gate picl_nodehdl_t plath, frusloth, frumodh;
1099*0Sstevel@tonic-gate
1100*0Sstevel@tonic-gate
1101*0Sstevel@tonic-gate /* Check for node in /platform tree */
1102*0Sstevel@tonic-gate err = ptree_get_node_by_path(plat, &plath);
1103*0Sstevel@tonic-gate if (err == PICL_SUCCESS)
1104*0Sstevel@tonic-gate return (PICL_FAILURE);
1105*0Sstevel@tonic-gate
1106*0Sstevel@tonic-gate /*
1107*0Sstevel@tonic-gate * The node is not in /platform, so find the corresponding slot in
1108*0Sstevel@tonic-gate * the frutree
1109*0Sstevel@tonic-gate */
1110*0Sstevel@tonic-gate err = ptree_get_node_by_path(fru, &frusloth);
1111*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1112*0Sstevel@tonic-gate return (err);
1113*0Sstevel@tonic-gate
1114*0Sstevel@tonic-gate /*
1115*0Sstevel@tonic-gate * If the slot in the frutree does not have a child, then return
1116*0Sstevel@tonic-gate * PICL_FAILURE. This means that the /platform tree and
1117*0Sstevel@tonic-gate * the frutree are consistent and no action is necessary.
1118*0Sstevel@tonic-gate * Otherwise return PICL_SUCCESS to indicate that the needs
1119*0Sstevel@tonic-gate * to be removed from the frutree
1120*0Sstevel@tonic-gate */
1121*0Sstevel@tonic-gate err = ptree_get_propval_by_name(frusloth, PICL_PROP_CHILD,
1122*0Sstevel@tonic-gate &frumodh, sizeof (picl_nodehdl_t));
1123*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1124*0Sstevel@tonic-gate return (err);
1125*0Sstevel@tonic-gate
1126*0Sstevel@tonic-gate return (PICL_SUCCESS);
1127*0Sstevel@tonic-gate }
1128*0Sstevel@tonic-gate
1129*0Sstevel@tonic-gate static int
remove_picl_node(picl_nodehdl_t nodeh)1130*0Sstevel@tonic-gate remove_picl_node(picl_nodehdl_t nodeh)
1131*0Sstevel@tonic-gate {
1132*0Sstevel@tonic-gate int err;
1133*0Sstevel@tonic-gate err = ptree_delete_node(nodeh);
1134*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1135*0Sstevel@tonic-gate return (err);
1136*0Sstevel@tonic-gate (void) ptree_destroy_node(nodeh);
1137*0Sstevel@tonic-gate return (PICL_SUCCESS);
1138*0Sstevel@tonic-gate }
1139*0Sstevel@tonic-gate
1140*0Sstevel@tonic-gate /* event completion handler for PICL_FRU_ADDED/PICL_FRU_REMOVED events */
1141*0Sstevel@tonic-gate /*ARGSUSED2*/
1142*0Sstevel@tonic-gate static void
frudr_completion_handler(char * ename,void * earg,size_t size)1143*0Sstevel@tonic-gate frudr_completion_handler(char *ename, void *earg, size_t size)
1144*0Sstevel@tonic-gate {
1145*0Sstevel@tonic-gate picl_nodehdl_t fruh;
1146*0Sstevel@tonic-gate
1147*0Sstevel@tonic-gate if (strcmp(ename, PICL_FRU_REMOVED) == 0) {
1148*0Sstevel@tonic-gate /*
1149*0Sstevel@tonic-gate * now frudata has been notified that the node is to be
1150*0Sstevel@tonic-gate * removed, we can actually remove it
1151*0Sstevel@tonic-gate */
1152*0Sstevel@tonic-gate fruh = NULL;
1153*0Sstevel@tonic-gate (void) nvlist_lookup_uint64(earg,
1154*0Sstevel@tonic-gate PICLEVENTARG_FRUHANDLE, &fruh);
1155*0Sstevel@tonic-gate if (fruh != NULL) {
1156*0Sstevel@tonic-gate (void) remove_picl_node(fruh);
1157*0Sstevel@tonic-gate }
1158*0Sstevel@tonic-gate }
1159*0Sstevel@tonic-gate nvlist_free(earg);
1160*0Sstevel@tonic-gate free(earg);
1161*0Sstevel@tonic-gate free(ename);
1162*0Sstevel@tonic-gate }
1163*0Sstevel@tonic-gate
1164*0Sstevel@tonic-gate /*
1165*0Sstevel@tonic-gate * Post the PICL_FRU_ADDED/PICL_FRU_REMOVED event
1166*0Sstevel@tonic-gate */
1167*0Sstevel@tonic-gate static void
post_frudr_event(char * ename,picl_nodehdl_t parenth,picl_nodehdl_t fruh)1168*0Sstevel@tonic-gate post_frudr_event(char *ename, picl_nodehdl_t parenth, picl_nodehdl_t fruh)
1169*0Sstevel@tonic-gate {
1170*0Sstevel@tonic-gate nvlist_t *nvl;
1171*0Sstevel@tonic-gate char *ev_name;
1172*0Sstevel@tonic-gate
1173*0Sstevel@tonic-gate ev_name = strdup(ename);
1174*0Sstevel@tonic-gate if (ev_name == NULL)
1175*0Sstevel@tonic-gate return;
1176*0Sstevel@tonic-gate if (nvlist_alloc(&nvl, NV_UNIQUE_NAME_TYPE, NULL)) {
1177*0Sstevel@tonic-gate free(ev_name);
1178*0Sstevel@tonic-gate return;
1179*0Sstevel@tonic-gate }
1180*0Sstevel@tonic-gate if (parenth != 0L &&
1181*0Sstevel@tonic-gate nvlist_add_uint64(nvl, PICLEVENTARG_PARENTHANDLE, parenth)) {
1182*0Sstevel@tonic-gate free(ev_name);
1183*0Sstevel@tonic-gate nvlist_free(nvl);
1184*0Sstevel@tonic-gate return;
1185*0Sstevel@tonic-gate }
1186*0Sstevel@tonic-gate if (fruh != 0L &&
1187*0Sstevel@tonic-gate nvlist_add_uint64(nvl, PICLEVENTARG_FRUHANDLE, fruh)) {
1188*0Sstevel@tonic-gate free(ev_name);
1189*0Sstevel@tonic-gate nvlist_free(nvl);
1190*0Sstevel@tonic-gate return;
1191*0Sstevel@tonic-gate }
1192*0Sstevel@tonic-gate if (ptree_post_event(ev_name, nvl, sizeof (nvl),
1193*0Sstevel@tonic-gate frudr_completion_handler) != 0) {
1194*0Sstevel@tonic-gate free(ev_name);
1195*0Sstevel@tonic-gate nvlist_free(nvl);
1196*0Sstevel@tonic-gate }
1197*0Sstevel@tonic-gate }
1198*0Sstevel@tonic-gate
1199*0Sstevel@tonic-gate /* Hotplug routine used to add a new power supply */
1200*0Sstevel@tonic-gate static int
add_power_supply(int slotnum)1201*0Sstevel@tonic-gate add_power_supply(int slotnum)
1202*0Sstevel@tonic-gate {
1203*0Sstevel@tonic-gate picl_nodehdl_t powersloth;
1204*0Sstevel@tonic-gate picl_nodehdl_t powermodh;
1205*0Sstevel@tonic-gate picl_nodehdl_t tmph;
1206*0Sstevel@tonic-gate int i, err;
1207*0Sstevel@tonic-gate
1208*0Sstevel@tonic-gate /* Find the node for the given power supply slot */
1209*0Sstevel@tonic-gate if (ptree_get_node_by_path(frutree_power_supply[slotnum],
1210*0Sstevel@tonic-gate &powersloth) == PICL_SUCCESS) {
1211*0Sstevel@tonic-gate
1212*0Sstevel@tonic-gate i = slotnum + PS0;
1213*0Sstevel@tonic-gate
1214*0Sstevel@tonic-gate /* Make sure it's in /platform and create the frutree node */
1215*0Sstevel@tonic-gate if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
1216*0Sstevel@tonic-gate PICL_SUCCESS) {
1217*0Sstevel@tonic-gate err = ptree_create_node("power-supply", "fru",
1218*0Sstevel@tonic-gate &powermodh);
1219*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1220*0Sstevel@tonic-gate return (err);
1221*0Sstevel@tonic-gate
1222*0Sstevel@tonic-gate err = add_ref_prop(powermodh, tmph, SEEPROM_SOURCE);
1223*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1224*0Sstevel@tonic-gate return (err);
1225*0Sstevel@tonic-gate
1226*0Sstevel@tonic-gate err = add_void_fda_prop(powermodh);
1227*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1228*0Sstevel@tonic-gate return (err);
1229*0Sstevel@tonic-gate
1230*0Sstevel@tonic-gate err = ptree_add_node(powersloth, powermodh);
1231*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1232*0Sstevel@tonic-gate return (err);
1233*0Sstevel@tonic-gate
1234*0Sstevel@tonic-gate err = add_ref_prop(tmph, powermodh, FRU_PARENT);
1235*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1236*0Sstevel@tonic-gate return (err);
1237*0Sstevel@tonic-gate
1238*0Sstevel@tonic-gate /* Post picl-fru-added event */
1239*0Sstevel@tonic-gate post_frudr_event(PICL_FRU_ADDED, NULL, powermodh);
1240*0Sstevel@tonic-gate }
1241*0Sstevel@tonic-gate }
1242*0Sstevel@tonic-gate return (PICL_SUCCESS);
1243*0Sstevel@tonic-gate }
1244*0Sstevel@tonic-gate
1245*0Sstevel@tonic-gate /* Hotplug routine used to remove an existing power supply */
1246*0Sstevel@tonic-gate static int
remove_power_supply(int slotnum)1247*0Sstevel@tonic-gate remove_power_supply(int slotnum)
1248*0Sstevel@tonic-gate {
1249*0Sstevel@tonic-gate picl_nodehdl_t powersloth;
1250*0Sstevel@tonic-gate picl_nodehdl_t powermodh;
1251*0Sstevel@tonic-gate int err;
1252*0Sstevel@tonic-gate
1253*0Sstevel@tonic-gate /* Find the node for the given power supply slot */
1254*0Sstevel@tonic-gate if (ptree_get_node_by_path(frutree_power_supply[slotnum],
1255*0Sstevel@tonic-gate &powersloth) == PICL_SUCCESS) {
1256*0Sstevel@tonic-gate /* Make sure it's got a child, then delete it */
1257*0Sstevel@tonic-gate err = ptree_get_propval_by_name(powersloth, PICL_PROP_CHILD,
1258*0Sstevel@tonic-gate &powermodh, sizeof (picl_nodehdl_t));
1259*0Sstevel@tonic-gate if (err != PICL_SUCCESS) {
1260*0Sstevel@tonic-gate return (err);
1261*0Sstevel@tonic-gate }
1262*0Sstevel@tonic-gate
1263*0Sstevel@tonic-gate err = ptree_delete_node(powermodh);
1264*0Sstevel@tonic-gate if (err != PICL_SUCCESS) {
1265*0Sstevel@tonic-gate return (err);
1266*0Sstevel@tonic-gate } else {
1267*0Sstevel@tonic-gate (void) ptree_destroy_node(powermodh);
1268*0Sstevel@tonic-gate }
1269*0Sstevel@tonic-gate
1270*0Sstevel@tonic-gate /* Post picl-fru-removed event */
1271*0Sstevel@tonic-gate post_frudr_event(PICL_FRU_REMOVED, NULL, powermodh);
1272*0Sstevel@tonic-gate
1273*0Sstevel@tonic-gate }
1274*0Sstevel@tonic-gate return (PICL_SUCCESS);
1275*0Sstevel@tonic-gate }
1276*0Sstevel@tonic-gate
1277*0Sstevel@tonic-gate /* Hotplug routine used to add a new CPU Mem Module (with associated DIMMs) */
1278*0Sstevel@tonic-gate static int
add_cpu_module(int slotnum)1279*0Sstevel@tonic-gate add_cpu_module(int slotnum)
1280*0Sstevel@tonic-gate {
1281*0Sstevel@tonic-gate picl_nodehdl_t cpumemsloth;
1282*0Sstevel@tonic-gate picl_nodehdl_t cpumemmodh;
1283*0Sstevel@tonic-gate picl_nodehdl_t tmph;
1284*0Sstevel@tonic-gate int i, err;
1285*0Sstevel@tonic-gate
1286*0Sstevel@tonic-gate /* Find the node for the given CPU Memory module slot */
1287*0Sstevel@tonic-gate if (ptree_get_node_by_path(frutree_cpu_module[slotnum],
1288*0Sstevel@tonic-gate &cpumemsloth) == PICL_SUCCESS) {
1289*0Sstevel@tonic-gate
1290*0Sstevel@tonic-gate i = slotnum + CPUMOD0;
1291*0Sstevel@tonic-gate
1292*0Sstevel@tonic-gate /* Make sure it's in /platform and create the frutree nodes */
1293*0Sstevel@tonic-gate if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
1294*0Sstevel@tonic-gate PICL_SUCCESS) {
1295*0Sstevel@tonic-gate err = ptree_create_node("cpu-mem-module", "fru",
1296*0Sstevel@tonic-gate &cpumemmodh);
1297*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1298*0Sstevel@tonic-gate return (err);
1299*0Sstevel@tonic-gate
1300*0Sstevel@tonic-gate err = add_ref_prop(cpumemmodh, tmph, SEEPROM_SOURCE);
1301*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1302*0Sstevel@tonic-gate return (err);
1303*0Sstevel@tonic-gate
1304*0Sstevel@tonic-gate err = add_void_fda_prop(cpumemmodh);
1305*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1306*0Sstevel@tonic-gate return (err);
1307*0Sstevel@tonic-gate
1308*0Sstevel@tonic-gate err = ptree_add_node(cpumemsloth, cpumemmodh);
1309*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1310*0Sstevel@tonic-gate return (err);
1311*0Sstevel@tonic-gate
1312*0Sstevel@tonic-gate err = add_ref_prop(tmph, cpumemmodh, FRU_PARENT);
1313*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1314*0Sstevel@tonic-gate return (err);
1315*0Sstevel@tonic-gate }
1316*0Sstevel@tonic-gate
1317*0Sstevel@tonic-gate err = do_cpu_module_init(cpumemmodh, slotnum);
1318*0Sstevel@tonic-gate if (err != PICL_SUCCESS)
1319*0Sstevel@tonic-gate return (err);
1320*0Sstevel@tonic-gate }
1321*0Sstevel@tonic-gate return (PICL_SUCCESS);
1322*0Sstevel@tonic-gate }
1323*0Sstevel@tonic-gate
1324*0Sstevel@tonic-gate /* Hotplug routine used to remove an existing CPU Mem Module */
1325*0Sstevel@tonic-gate static int
remove_cpu_module(int slotnum)1326*0Sstevel@tonic-gate remove_cpu_module(int slotnum)
1327*0Sstevel@tonic-gate {
1328*0Sstevel@tonic-gate picl_nodehdl_t cpumemsloth;
1329*0Sstevel@tonic-gate picl_nodehdl_t cpumemmodh;
1330*0Sstevel@tonic-gate int err;
1331*0Sstevel@tonic-gate
1332*0Sstevel@tonic-gate /* Find the node for the given CPU Memory module slot */
1333*0Sstevel@tonic-gate if (ptree_get_node_by_path(frutree_cpu_module[slotnum],
1334*0Sstevel@tonic-gate &cpumemsloth) == PICL_SUCCESS) {
1335*0Sstevel@tonic-gate /* Make sure it's got a child, then delete it */
1336*0Sstevel@tonic-gate err = ptree_get_propval_by_name(cpumemsloth, PICL_PROP_CHILD,
1337*0Sstevel@tonic-gate &cpumemmodh, sizeof (picl_nodehdl_t));
1338*0Sstevel@tonic-gate if (err != PICL_SUCCESS) {
1339*0Sstevel@tonic-gate return (err);
1340*0Sstevel@tonic-gate }
1341*0Sstevel@tonic-gate
1342*0Sstevel@tonic-gate err = remove_all_nodes(cpumemmodh);
1343*0Sstevel@tonic-gate if (err != PICL_SUCCESS) {
1344*0Sstevel@tonic-gate return (err);
1345*0Sstevel@tonic-gate }
1346*0Sstevel@tonic-gate }
1347*0Sstevel@tonic-gate return (PICL_SUCCESS);
1348*0Sstevel@tonic-gate }
1349