cmd: remove sparc-only virtinfo
[unleashed.git] / usr / src / cmd / picl / plugins / sun4u / littleneck / frutree / piclfrutree.c
blob0475b1aa7561e8ea47ebb13ffe5c9ca9719fe585
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * PICL plug-in that creates the FRU Hierarchy for the
31 * SUNW,Sun-Fire-280R (Littleneck) platform
34 #include <stdio.h>
35 #include <string.h>
36 #include <libintl.h>
37 #include <syslog.h>
38 #include <picl.h>
39 #include <picltree.h>
40 #include <picldefs.h>
43 * Plugin registration entry points
45 static void picl_frutree_register(void);
46 static void picl_frutree_init(void);
47 static void picl_frutree_fini(void);
48 static void picl_frutree_evhandler(const char *ename, const void *earg,
49 size_t size, void *cookie);
51 #pragma init(picl_frutree_register)
54 * Log message texts
56 #define CREATE_FRUTREE_FAIL gettext("Failed to create frutree node\n")
57 #define CREATE_CHASSIS_FAIL gettext("Failed to create chassis node\n")
58 #define SYSBRD_INIT_FAIL gettext("do_sysboard_init() failed\n")
59 #define CPUS_INIT_FAIL gettext("do_cpus_init() failed\n")
60 #define DIMMS_INIT_FAIL gettext("do_mem_init() failed\n")
61 #define PS_INIT_FAIL gettext("do_power_supplies_init() failed\n")
62 #define FCAL_INIT_FAIL gettext("do_fcal_init() failed\n")
63 #define RSC_INIT_FAIL gettext("do_rscboard_init() failed\n")
66 * ViewPoints property field used by SunMC
68 #define CHASSIS_VIEWPOINTS gettext("front top rear")
71 * Ref prop values
73 #define SEEPROM_SOURCE "_seeprom_source"
74 #define FRU_PARENT "_fru_parent"
77 * List of all the FRU locations in the platform_frupath[] array, and
78 * location_label[] array
80 #define CPU0 0
81 #define CPU1 1
82 #define DIMM0 2
83 #define DIMM1 3
84 #define DIMM2 4
85 #define DIMM3 5
86 #define DIMM4 6
87 #define DIMM5 7
88 #define DIMM6 8
89 #define DIMM7 9
90 #define PDB 10
91 #define PS0 11
92 #define PS1 12
93 #define FCAL 13
94 #define RSC 14
95 #define SYSBRD 15
98 * Local variables
100 static picld_plugin_reg_t my_reg_info = {
101 PICLD_PLUGIN_VERSION_1,
102 PICLD_PLUGIN_NON_CRITICAL,
103 "SUNW_Sun-Fire-280R_frutree",
104 picl_frutree_init,
105 picl_frutree_fini,
109 * List of all the FRUs in the /platform tree with SEEPROMs
111 static char *platform_frupath[] = {
112 "/platform/pci@8,700000/ebus@5/i2c@1,30/cpu-fru@0,a0",
113 "/platform/pci@8,700000/ebus@5/i2c@1,30/cpu-fru@0,a2",
114 "/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,a0",
115 "/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,a2",
116 "/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,a4",
117 "/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,a6",
118 "/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,a8",
119 "/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,aa",
120 "/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,ac",
121 "/platform/pci@8,700000/ebus@5/i2c@1,2e/dimm-fru@1,ae",
122 "/platform/pci@8,700000/ebus@5/i2c@1,30/power-distribution-board@0,aa",
123 "/platform/pci@8,700000/ebus@5/i2c@1,30/power-supply@0,ac",
124 "/platform/pci@8,700000/ebus@5/i2c@1,30/power-supply@0,ae",
125 "/platform/pci@8,700000/ebus@5/i2c@1,30/fcal-backplane@0,a4",
126 "/platform/pci@8,700000/ebus@5/i2c@1,30/remote-system-console@0,a6",
127 "/platform/pci@8,700000/ebus@5/i2c@1,30/motherboard-fru@0,a8",
128 NULL};
131 * List of all the FRU slots in the frutree that can be hotplugged
133 static char *frutree_power_supply[] = {
134 "/frutree/chassis/power-dist-board/power-supply-slot?Slot=0",
135 "/frutree/chassis/power-dist-board/power-supply-slot?Slot=1",
136 NULL};
139 * List of Labels for FRU locations (uses the #define's from above)
141 static char *location_label[] = {
142 "0",
143 "1",
144 "J0100",
145 "J0101",
146 "J0202",
147 "J0203",
148 "J0304",
149 "J0305",
150 "J0406",
151 "J0407",
152 NULL, /* power distribution board placeholder */
153 "0",
154 "1",
155 NULL};
157 /* PICL handle for the root node of the "frutree" */
158 static picl_nodehdl_t frutreeh;
160 static int do_sysboard_init(picl_nodehdl_t, picl_nodehdl_t *);
161 static int do_cpus_init(picl_nodehdl_t);
162 static int do_mem_init(picl_nodehdl_t);
163 static int do_power_supplies_init(picl_nodehdl_t);
164 static int do_fcal_init(picl_nodehdl_t);
165 static int do_rscboard_init(picl_nodehdl_t);
167 static int add_ref_prop(picl_nodehdl_t, picl_nodehdl_t, char *);
168 static int add_slot_prop(picl_nodehdl_t, int);
169 static int add_label_prop(picl_nodehdl_t, char *);
170 static int add_void_fda_prop(picl_nodehdl_t);
171 static int add_viewpoints_prop(picl_nodehdl_t, char *);
172 static int add_all_nodes();
173 static int remove_all_nodes(picl_nodehdl_t);
175 static int add_hotplug_fru_device(void);
176 static int rem_hotplug_fru_device(void);
177 static int is_added_device(char *, char *);
178 static int is_removed_device(char *, char *);
179 static int add_power_supply(int);
180 static int remove_power_supply(int);
183 * This function is executed as part of .init when the plugin is
184 * dlopen()ed
186 void
187 picl_frutree_register()
189 (void) picld_plugin_register(&my_reg_info);
193 * This function is the init entry point of the plugin.
194 * It initializes the /frutree tree
196 void
197 picl_frutree_init()
199 int err;
201 err = add_all_nodes();
202 if (err != PICL_SUCCESS) {
203 (void) remove_all_nodes(frutreeh);
204 return;
207 /* Register the event handler routine */
208 (void) ptree_register_handler(PICLEVENT_SYSEVENT_DEVICE_ADDED,
209 picl_frutree_evhandler, NULL);
210 (void) ptree_register_handler(PICLEVENT_SYSEVENT_DEVICE_REMOVED,
211 picl_frutree_evhandler, NULL);
215 * This function is the fini entry point of the plugin
217 void
218 picl_frutree_fini(void)
220 /* Unregister the event handler routine */
221 (void) ptree_unregister_handler(PICLEVENT_SYSEVENT_DEVICE_ADDED,
222 picl_frutree_evhandler, NULL);
223 (void) ptree_unregister_handler(PICLEVENT_SYSEVENT_DEVICE_REMOVED,
224 picl_frutree_evhandler, NULL);
226 (void) remove_all_nodes(frutreeh);
230 * This function is the event handler of this plug-in.
232 * It processes the following events:
234 * PICLEVENT_SYSEVENT_DEVICE_ADDED
235 * PICLEVENT_SYSEVENT_DEVICE_REMOVED
237 /* ARGSUSED */
238 static void
239 picl_frutree_evhandler(const char *ename, const void *earg, size_t size,
240 void *cookie)
242 if (strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_ADDED) == 0) {
243 /* Check for and add any hotplugged device(s) */
244 (void) add_hotplug_fru_device();
246 } else if (strcmp(ename, PICLEVENT_SYSEVENT_DEVICE_REMOVED) == 0) {
247 /* Check for and remove any hotplugged device(s) */
248 (void) rem_hotplug_fru_device();
252 /* Initialize the FRU node for the system board */
253 static int
254 do_sysboard_init(picl_nodehdl_t rooth, picl_nodehdl_t *childh)
256 picl_nodehdl_t tmph;
257 int err;
259 /* Create the node for the system board */
260 if (ptree_get_node_by_path(platform_frupath[SYSBRD], &tmph) ==
261 PICL_SUCCESS) {
262 err = ptree_create_node("system-board", "fru", childh);
263 if (err != PICL_SUCCESS)
264 return (err);
266 err = add_ref_prop(*childh, tmph, SEEPROM_SOURCE);
267 if (err != PICL_SUCCESS)
268 return (err);
270 err = add_void_fda_prop(*childh);
271 if (err != PICL_SUCCESS)
272 return (err);
274 err = ptree_add_node(rooth, *childh);
275 if (err != PICL_SUCCESS)
276 return (err);
278 err = add_ref_prop(tmph, *childh, FRU_PARENT);
279 if (err != PICL_SUCCESS)
280 return (err);
283 return (PICL_SUCCESS);
286 /* Initializes the FRU nodes for the CPU modules */
287 static int
288 do_cpus_init(picl_nodehdl_t rooth)
290 picl_nodehdl_t cpusloth;
291 picl_nodehdl_t cpumodh;
292 picl_nodehdl_t tmph;
293 int i, err;
295 for (i = CPU0; i <= CPU1; i++) {
296 /* Create the node for the CPU slot */
297 err = ptree_create_node("cpu-slot", "location", &cpusloth);
298 if (err != PICL_SUCCESS)
299 return (err);
301 err = add_slot_prop(cpusloth, i);
302 if (err != PICL_SUCCESS)
303 return (err);
305 err = add_label_prop(cpusloth, location_label[i]);
306 if (err != PICL_SUCCESS)
307 return (err);
309 err = ptree_add_node(rooth, cpusloth);
310 if (err != PICL_SUCCESS)
311 return (err);
313 /* If the CPU module exists, create a node for it */
314 if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
315 PICL_SUCCESS) {
316 err = ptree_create_node("cpu-module", "fru", &cpumodh);
317 if (err != PICL_SUCCESS)
318 return (err);
320 err = add_ref_prop(cpumodh, tmph, SEEPROM_SOURCE);
321 if (err != PICL_SUCCESS)
322 return (err);
324 err = add_void_fda_prop(cpumodh);
325 if (err != PICL_SUCCESS)
326 return (err);
328 err = ptree_add_node(cpusloth, cpumodh);
329 if (err != PICL_SUCCESS)
330 return (err);
332 err = add_ref_prop(tmph, cpumodh, FRU_PARENT);
333 if (err != PICL_SUCCESS)
334 return (err);
337 return (PICL_SUCCESS);
340 /* Initializes the FRU nodes for the memory modules */
341 static int
342 do_mem_init(picl_nodehdl_t rooth)
344 picl_nodehdl_t memsloth;
345 picl_nodehdl_t memmodh;
346 picl_nodehdl_t tmph;
347 int i, err, slotnum;
349 for (i = DIMM0; i <= DIMM7; i++) {
350 /* Create the node for the memory slot */
351 err = ptree_create_node("mem-slot", "location", &memsloth);
352 if (err != PICL_SUCCESS)
353 return (err);
355 slotnum = i - DIMM0;
356 err = add_slot_prop(memsloth, slotnum);
357 if (err != PICL_SUCCESS)
358 return (err);
360 err = add_label_prop(memsloth, location_label[i]);
361 if (err != PICL_SUCCESS)
362 return (err);
364 err = ptree_add_node(rooth, memsloth);
365 if (err != PICL_SUCCESS)
366 return (err);
368 /* If the memory exists, create a node for it */
369 if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
370 PICL_SUCCESS) {
371 err = ptree_create_node("mem-module", "fru", &memmodh);
372 if (err != PICL_SUCCESS)
373 return (err);
375 err = add_ref_prop(memmodh, tmph, SEEPROM_SOURCE);
376 if (err != PICL_SUCCESS)
377 return (err);
379 err = add_void_fda_prop(memmodh);
380 if (err != PICL_SUCCESS)
381 return (err);
383 err = ptree_add_node(memsloth, memmodh);
384 if (err != PICL_SUCCESS)
385 return (err);
387 err = add_ref_prop(tmph, memmodh, FRU_PARENT);
388 if (err != PICL_SUCCESS)
389 return (err);
392 return (PICL_SUCCESS);
395 /* Initializes the FRU nodes for the PDB and the power supplies */
396 static int
397 do_power_supplies_init(picl_nodehdl_t rooth)
399 picl_nodehdl_t powerbrdh;
400 picl_nodehdl_t powersloth;
401 picl_nodehdl_t powermodh;
402 picl_nodehdl_t tmph;
403 int i, err, slotnum;
405 /* Create the node for the PDB (if it exists) */
406 if (ptree_get_node_by_path(platform_frupath[PDB], &tmph) ==
407 PICL_SUCCESS) {
408 err = ptree_create_node("power-dist-board", "fru", &powerbrdh);
409 if (err != PICL_SUCCESS)
410 return (err);
412 err = add_ref_prop(powerbrdh, tmph, SEEPROM_SOURCE);
413 if (err != PICL_SUCCESS)
414 return (err);
416 err = add_void_fda_prop(powerbrdh);
417 if (err != PICL_SUCCESS)
418 return (err);
420 err = ptree_add_node(rooth, powerbrdh);
421 if (err != PICL_SUCCESS)
422 return (err);
424 err = add_ref_prop(tmph, powerbrdh, FRU_PARENT);
425 if (err != PICL_SUCCESS)
426 return (err);
428 for (i = PS0; i <= PS1; i++) {
429 /* Create the node for the power supply slot */
430 err = ptree_create_node("power-supply-slot",
431 "location", &powersloth);
432 if (err != PICL_SUCCESS)
433 return (err);
435 slotnum = i - PS0;
436 err = add_slot_prop(powersloth, slotnum);
437 if (err != PICL_SUCCESS)
438 return (err);
440 err = add_label_prop(powersloth, location_label[i]);
441 if (err != PICL_SUCCESS)
442 return (err);
444 err = ptree_add_node(powerbrdh, powersloth);
445 if (err != PICL_SUCCESS)
446 return (err);
448 /* If the PS exists, create a node for it */
449 if (ptree_get_node_by_path(platform_frupath[i],
450 &tmph) == PICL_SUCCESS) {
451 err = ptree_create_node("power-supply",
452 "fru", &powermodh);
453 if (err != PICL_SUCCESS)
454 return (err);
456 err = add_ref_prop(powermodh, tmph,
457 SEEPROM_SOURCE);
458 if (err != PICL_SUCCESS)
459 return (err);
461 err = add_void_fda_prop(powermodh);
462 if (err != PICL_SUCCESS)
463 return (err);
465 err = ptree_add_node(powersloth, powermodh);
466 if (err != PICL_SUCCESS)
467 return (err);
469 err = add_ref_prop(tmph, powermodh, FRU_PARENT);
470 if (err != PICL_SUCCESS)
471 return (err);
475 return (PICL_SUCCESS);
478 /* Initializes the FRU nodes for the FCAL backplane */
479 static int
480 do_fcal_init(picl_nodehdl_t rooth)
482 picl_nodehdl_t fcalbrdh;
483 picl_nodehdl_t tmph;
484 int err;
486 /* Create the node for the FCAL backplane (if it exists) */
487 if (ptree_get_node_by_path(platform_frupath[FCAL], &tmph) ==
488 PICL_SUCCESS) {
489 err = ptree_create_node("fcal-backplane", "fru", &fcalbrdh);
490 if (err != PICL_SUCCESS)
491 return (err);
493 err = add_ref_prop(fcalbrdh, tmph, SEEPROM_SOURCE);
494 if (err != PICL_SUCCESS)
495 return (err);
497 err = add_void_fda_prop(fcalbrdh);
498 if (err != PICL_SUCCESS)
499 return (err);
501 err = ptree_add_node(rooth, fcalbrdh);
502 if (err != PICL_SUCCESS)
503 return (err);
505 err = add_ref_prop(tmph, fcalbrdh, FRU_PARENT);
506 if (err != PICL_SUCCESS)
507 return (err);
509 return (PICL_SUCCESS);
512 /* Initializes the FRU node for the RSC card */
513 static int
514 do_rscboard_init(picl_nodehdl_t rooth)
516 picl_nodehdl_t rscbrdh;
517 picl_nodehdl_t tmph;
518 int err;
520 /* Create the node for the RSC board (if it exists) */
521 if (ptree_get_node_by_path(platform_frupath[RSC], &tmph) ==
522 PICL_SUCCESS) {
523 err = ptree_create_node("rsc-board", "fru", &rscbrdh);
524 if (err != PICL_SUCCESS)
525 return (err);
527 err = add_ref_prop(rscbrdh, tmph, SEEPROM_SOURCE);
528 if (err != PICL_SUCCESS)
529 return (err);
531 err = add_void_fda_prop(rscbrdh);
532 if (err != PICL_SUCCESS)
533 return (err);
535 err = ptree_add_node(rooth, rscbrdh);
536 if (err != PICL_SUCCESS)
537 return (err);
539 err = add_ref_prop(tmph, rscbrdh, FRU_PARENT);
540 if (err != PICL_SUCCESS)
541 return (err);
543 return (PICL_SUCCESS);
546 /* Creates a "reference" property between two PICL nodes */
547 static int
548 add_ref_prop(picl_nodehdl_t nodeh, picl_nodehdl_t tmph, char *str)
550 picl_prophdl_t proph;
551 ptree_propinfo_t propinfo;
552 int err;
554 if (str == NULL)
555 return (PICL_FAILURE);
557 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
558 PICL_PTYPE_REFERENCE, PICL_READ, sizeof (picl_nodehdl_t),
559 str, NULL, NULL);
560 if (err != PICL_SUCCESS)
561 return (err);
563 err = ptree_create_and_add_prop(nodeh, &propinfo, &tmph, &proph);
564 if (err != PICL_SUCCESS)
565 return (err);
567 return (PICL_SUCCESS);
570 /* Creates a "Slot" property for a given PICL node */
571 static int
572 add_slot_prop(picl_nodehdl_t nodeh, int slotnum)
574 picl_prophdl_t proph;
575 ptree_propinfo_t propinfo;
576 int err;
578 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
579 PICL_PTYPE_INT, PICL_READ, 4, "Slot", NULL, NULL);
580 if (err != PICL_SUCCESS)
581 return (err);
583 err = ptree_create_and_add_prop(nodeh, &propinfo, &slotnum, &proph);
584 if (err != PICL_SUCCESS)
585 return (err);
587 return (PICL_SUCCESS);
590 /* Creates a "Label" property for a given PICL node */
591 static int
592 add_label_prop(picl_nodehdl_t nodeh, char *label)
594 picl_prophdl_t proph;
595 ptree_propinfo_t propinfo;
596 int err;
598 if (label == NULL)
599 return (PICL_FAILURE);
601 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
602 PICL_PTYPE_CHARSTRING, PICL_READ, strlen(label)+1, "Label",
603 NULL, NULL);
604 if (err != PICL_SUCCESS)
605 return (err);
607 err = ptree_create_and_add_prop(nodeh, &propinfo, label, &proph);
608 if (err != PICL_SUCCESS)
609 return (err);
611 return (PICL_SUCCESS);
614 /* Creates a "FRUDataAvailable" void property for the given PICL node */
615 static int
616 add_void_fda_prop(picl_nodehdl_t nodeh)
618 picl_prophdl_t proph;
619 ptree_propinfo_t propinfo;
620 int err;
622 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
623 PICL_PTYPE_VOID, PICL_READ, 0, "FRUDataAvailable", NULL, NULL);
624 if (err != PICL_SUCCESS)
625 return (err);
627 err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, &proph);
628 if (err != PICL_SUCCESS)
629 return (err);
631 return (PICL_SUCCESS);
634 /* Creates a "ViewPoints" property -- used for chassis */
635 static int
636 add_viewpoints_prop(picl_nodehdl_t nodeh, char *string)
638 picl_prophdl_t proph;
639 ptree_propinfo_t propinfo;
640 int err;
642 if (string == NULL)
643 return (PICL_FAILURE);
645 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
646 PICL_PTYPE_CHARSTRING, PICL_READ, strlen(string)+1, "ViewPoints",
647 NULL, NULL);
648 if (err != PICL_SUCCESS)
649 return (err);
651 err = ptree_create_and_add_prop(nodeh, &propinfo, string, &proph);
652 if (err != PICL_SUCCESS)
653 return (err);
655 return (PICL_SUCCESS);
658 /* Creates and adds all of the frutree nodes */
659 static int
660 add_all_nodes()
662 picl_nodehdl_t rooth;
663 picl_nodehdl_t chassish;
664 picl_nodehdl_t sysboardh;
665 int err;
667 /* Get the root node of the PICL tree */
668 err = ptree_get_root(&rooth);
669 if (err != PICL_SUCCESS) {
670 return (err);
673 /* Create and add the root node of the FRU subtree */
674 err = ptree_create_and_add_node(rooth, "frutree", "picl", &frutreeh);
675 if (err != PICL_SUCCESS) {
676 syslog(LOG_ERR, CREATE_FRUTREE_FAIL);
677 return (err);
680 /* Create and add the chassis node */
681 err = ptree_create_and_add_node(frutreeh, "chassis", "fru", &chassish);
682 if (err != PICL_SUCCESS) {
683 syslog(LOG_ERR, CREATE_CHASSIS_FAIL);
684 return (err);
687 /* Add ViewPoints prop to chassis node */
688 err = add_viewpoints_prop(chassish, CHASSIS_VIEWPOINTS);
689 if (err != PICL_SUCCESS)
690 return (err);
692 /* Initialize the FRU node for the system board */
693 err = do_sysboard_init(chassish, &sysboardh);
694 if (err != PICL_SUCCESS) {
695 syslog(LOG_ERR, SYSBRD_INIT_FAIL);
696 return (err);
699 /* Initialize the FRU nodes for the CPU modules */
700 err = do_cpus_init(sysboardh);
701 if (err != PICL_SUCCESS) {
702 syslog(LOG_ERR, CPUS_INIT_FAIL);
703 return (err);
706 /* Initialize the FRU nodes for the memory modules */
707 err = do_mem_init(sysboardh);
708 if (err != PICL_SUCCESS) {
709 syslog(LOG_ERR, DIMMS_INIT_FAIL);
710 return (err);
713 /* Initialize the FRU nodes for the PDB and the power supplies */
714 err = do_power_supplies_init(chassish);
715 if (err != PICL_SUCCESS) {
716 syslog(LOG_ERR, PS_INIT_FAIL);
717 return (err);
720 /* Initialize the FRU nodes for the FCAL backplane */
721 err = do_fcal_init(chassish);
722 if (err != PICL_SUCCESS) {
723 syslog(LOG_ERR, FCAL_INIT_FAIL);
724 return (err);
727 /* Initialize the FRU node for the RSC card */
728 err = do_rscboard_init(chassish);
729 if (err != PICL_SUCCESS) {
730 syslog(LOG_ERR, RSC_INIT_FAIL);
731 return (err);
734 return (PICL_SUCCESS);
737 /* Deletes and destroys all PICL nodes for which rooth is a ancestor */
738 static int
739 remove_all_nodes(picl_nodehdl_t rooth)
741 picl_nodehdl_t chdh;
742 int err, done = 0;
744 while (!done) {
745 err = ptree_get_propval_by_name(rooth, PICL_PROP_CHILD, &chdh,
746 sizeof (picl_nodehdl_t));
747 if (err != PICL_PROPNOTFOUND) {
748 (void) remove_all_nodes(chdh);
749 } else {
750 err = ptree_delete_node(rooth);
751 if (err != PICL_SUCCESS) {
752 return (err);
753 } else {
754 (void) ptree_destroy_node(rooth);
756 done = 1;
759 return (PICL_SUCCESS);
763 * Searches the list of hotpluggable FRUs for this platform and adds the
764 * appropriate node(s) to the frutree
766 static int
767 add_hotplug_fru_device()
769 int i, err, slotnum;
771 /* Check for hotplugged power supplies */
772 for (i = PS0; i <= PS1; i++) {
773 /* Compare the /platform tree to the frutree */
774 slotnum = i - PS0;
775 err = is_added_device(platform_frupath[i],
776 frutree_power_supply[slotnum]);
777 if (err != PICL_SUCCESS)
778 continue;
780 /* If they are different, then add a power supply */
781 err = add_power_supply(slotnum);
782 if (err != PICL_SUCCESS)
783 continue;
785 return (PICL_SUCCESS);
789 * Searches the list of hotpluggable FRUs for this platform and removes the
790 * appropriate node(s) from the frutree
792 static int
793 rem_hotplug_fru_device()
795 int i, err, slotnum;
797 /* Check for hotplugged power supplies */
798 for (i = PS0; i <= PS1; i++) {
799 /* Compare the /platform tree to the frutree */
800 slotnum = i - PS0;
801 err = is_removed_device(platform_frupath[i],
802 frutree_power_supply[slotnum]);
803 if (err != PICL_SUCCESS)
804 continue;
806 /* If they are different, then remove a power supply */
807 err = remove_power_supply(slotnum);
808 if (err != PICL_SUCCESS)
809 continue;
811 return (PICL_SUCCESS);
815 * Compare the /platform tree to the /frutree to determine if a
816 * new device has been added
818 static int
819 is_added_device(char *plat, char *fru)
821 int err;
822 picl_nodehdl_t plath, frusloth, frumodh;
824 /* Check for node in the /platform tree */
825 err = ptree_get_node_by_path(plat, &plath);
826 if (err != PICL_SUCCESS)
827 return (err);
830 * The node is in /platform, so find the corresponding slot in
831 * the frutree
833 err = ptree_get_node_by_path(fru, &frusloth);
834 if (err != PICL_SUCCESS)
835 return (err);
838 * If the slot in the frutree has a child, then return
839 * PICL_FAILURE. This means that the /platform tree and
840 * the frutree are consistent and no action is necessary.
841 * Otherwise return PICL_SUCCESS to indicate that a node needs
842 * to be added to the frutree
844 err = ptree_get_propval_by_name(frusloth, PICL_PROP_CHILD,
845 &frumodh, sizeof (picl_nodehdl_t));
846 if (err == PICL_SUCCESS)
847 return (PICL_FAILURE);
849 return (PICL_SUCCESS);
853 * Compare the /platform tree to the /frutree to determine if a
854 * device has been removed
856 static int
857 is_removed_device(char *plat, char *fru)
859 int err;
860 picl_nodehdl_t plath, frusloth, frumodh;
863 /* Check for node in /platform tree */
864 err = ptree_get_node_by_path(plat, &plath);
865 if (err == PICL_SUCCESS)
866 return (PICL_FAILURE);
869 * The node is not in /platform, so find the corresponding slot in
870 * the frutree
872 err = ptree_get_node_by_path(fru, &frusloth);
873 if (err != PICL_SUCCESS)
874 return (err);
877 * If the slot in the frutree does not have a child, then return
878 * PICL_FAILURE. This means that the /platform tree and
879 * the frutree are consistent and no action is necessary.
880 * Otherwise return PICL_SUCCESS to indicate that the needs
881 * to be removed from the frutree
883 err = ptree_get_propval_by_name(frusloth, PICL_PROP_CHILD,
884 &frumodh, sizeof (picl_nodehdl_t));
885 if (err != PICL_SUCCESS)
886 return (PICL_FAILURE);
888 return (PICL_SUCCESS);
891 /* Hotplug routine used to add a new power supply */
892 static int
893 add_power_supply(int slotnum)
895 picl_nodehdl_t powersloth;
896 picl_nodehdl_t powermodh;
897 picl_nodehdl_t tmph;
898 int i, err;
900 /* Find the node for the given power supply slot */
901 if (ptree_get_node_by_path(frutree_power_supply[slotnum],
902 &powersloth) == PICL_SUCCESS) {
904 i = slotnum + PS0;
906 /* Make sure it's in /platform and create the frutree node */
907 if (ptree_get_node_by_path(platform_frupath[i], &tmph) ==
908 PICL_SUCCESS) {
909 err = ptree_create_node("power-supply", "fru",
910 &powermodh);
911 if (err != PICL_SUCCESS)
912 return (err);
914 err = add_ref_prop(powermodh, tmph, SEEPROM_SOURCE);
915 if (err != PICL_SUCCESS)
916 return (err);
918 err = add_void_fda_prop(powermodh);
919 if (err != PICL_SUCCESS)
920 return (err);
922 err = ptree_add_node(powersloth, powermodh);
923 if (err != PICL_SUCCESS)
924 return (err);
926 err = add_ref_prop(tmph, powermodh, FRU_PARENT);
927 if (err != PICL_SUCCESS)
928 return (err);
931 return (PICL_SUCCESS);
934 /* Hotplug routine used to remove an existing power supply */
935 static int
936 remove_power_supply(int slotnum)
938 picl_nodehdl_t powersloth;
939 picl_nodehdl_t powermodh;
940 int err;
942 /* Find the node for the given power supply slot */
943 if (ptree_get_node_by_path(frutree_power_supply[slotnum],
944 &powersloth) == PICL_SUCCESS) {
945 /* Make sure it's got a child, then delete it */
946 err = ptree_get_propval_by_name(powersloth, PICL_PROP_CHILD,
947 &powermodh, sizeof (picl_nodehdl_t));
948 if (err != PICL_SUCCESS) {
949 return (err);
952 err = ptree_delete_node(powermodh);
953 if (err != PICL_SUCCESS) {
954 return (err);
955 } else {
956 (void) ptree_destroy_node(powermodh);
959 return (PICL_SUCCESS);