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
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]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * PICL Cherrystone platform plug-in to remove environment tree nodes
31 * if corresponding physical device is not present. For creating
32 * the picltree nodes, see:
33 * usr/src/cmd/picl/plugins/sun4u/psvc/psvcplugin/psvcplugin.c
35 #define _POSIX_PRIORITY_SCHEDULING 1
49 #include <semaphore.h>
52 #include <sys/types.h>
53 #include <sys/systeminfo.h>
54 #include <psvc_objects.h>
56 static psvc_opaque_t hdlp
;
58 #define PSVC_PLUGIN_VERSION PICLD_PLUGIN_VERSION_1
60 #pragma init(psvc_psr_plugin_register) /* place in .init section */
67 extern struct handle
{
73 void psvc_psr_plugin_init(void);
74 void psvc_psr_plugin_fini(void);
76 picld_plugin_reg_t psvc_psr_reg
= {
78 PICLD_PLUGIN_CRITICAL
,
84 #define PSVC_INIT_ERR gettext("%s: Error in psvc_init(): %s\n")
85 #define PTREE_DELETE_NODE_ERR gettext("%s: ptree_delete_node() failed: %s\n")
86 #define PTREE_GET_NODE_ERR \
87 gettext("%s: ptree_get_node_by_path() failed: %s\n")
89 extern int ptree_get_node_by_path(const char *, picl_nodehdl_t
*);
91 /* ======================================== */
96 /* Search for memory */
97 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_A0_0",
98 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a0:fru"},
99 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_A2_0",
100 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a2:fru"},
101 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_A4_0",
102 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a4:fru"},
103 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_A6_0",
104 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a6:fru"},
105 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_A8_0",
106 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@0,a8:fru"},
107 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_AA_0",
108 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@0,aa:fru"},
109 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_AC_0",
110 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@0,ac:fru"},
111 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_AE_0",
112 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@0,ae:fru"},
113 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_A0_1",
114 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a0:fru"},
115 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_A2_1",
116 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a2:fru"},
117 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_A4_1",
118 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a4:fru"},
119 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_A6_1",
120 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a6:fru"},
121 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_A8_1",
122 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@1,a8:fru"},
123 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_AA_1",
124 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@1,aa:fru"},
125 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_AC_1",
126 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@1,ac:fru"},
127 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_AE_1",
128 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@1,ae:fru"},
129 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_A0_2",
130 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a0:fru"},
131 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_A2_2",
132 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a2:fru"},
133 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_A4_2",
134 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a4:fru"},
135 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_A6_2",
136 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a6:fru"},
137 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_A8_2",
138 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@2,a8:fru"},
139 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_AA_2",
140 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@2,aa:fru"},
141 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_AC_2",
142 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@2,ac:fru"},
143 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C02_AE_2",
144 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@2,ae:fru"},
145 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_A0_3",
146 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a0:fru"},
147 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_A2_3",
148 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a2:fru"},
149 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_A4_3",
150 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a4:fru"},
151 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_A6_3",
152 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a6:fru"},
153 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_A8_3",
154 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@3,a8:fru"},
155 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_AA_3",
156 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@3,aa:fru"},
157 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_AC_3",
158 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@3,ac:fru"},
159 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C02_AE_3",
160 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@3,ae:fru"},
161 /* Search for 64Kbit SPD */
162 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD/24C64_A0_4",
163 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@4,a0:fru"},
164 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD/24C64_A2_4",
165 "/devices/pci@9,700000/ebus@1/i2c@1,2e/fru@4,a2:fru"},
168 * Search for CPU Module cards. We check one cpu's die temperature
169 * sensor If not present, then we remove the entire node since module
170 * cards come with two cpus in them, each cpu having a die temperature
174 {"/SYSTEM/MOTHERBOARD/CPU_0_2_MOD_SLOT/CPU_0_2_MOD_CARD",
175 "/devices/pci@9,700000/ebus@1/i2c@1,30/temperature@0,30:die_temp"},
176 {"/SYSTEM/MOTHERBOARD/CPU_1_3_MOD_SLOT/CPU_1_3_MOD_CARD",
177 "/devices/pci@9,700000/ebus@1/i2c@1,30/temperature@0,52:die_temp"},
178 {"/SYSTEM/SIB_BOARD",
179 "/devices/pci@9,700000/ebus@1/i2c@1,30/temperature@0,98:die_temp"},
181 * Check to see if RSC Card FRU is present. If it is not present,
182 * then RSC Card is not present, and so we remove those nodes from
185 {"/SYSTEM/RSC_SLOT/RSC_CARD/24C64_A6_5",
186 "/devices/pci@9,700000/ebus@1/i2c@1,30/fru@0,a6:fru"},
187 {"/SYSTEM/RSC_SLOT/RSC_CARD",
188 "/devices/pci@9,700000/ebus@1/i2c@1,30/fru@0,a6:fru"}
191 #define DEV_PR_COUNT (sizeof (dev_pr_info) / sizeof (struct node_file))
193 static void init_err(char *fmt
, char *arg1
, char *arg2
)
197 sprintf(msg
, fmt
, arg1
, arg2
);
198 syslog(LOG_ERR
, msg
);
202 psvc_psr_plugin_init(void)
204 char *funcname
= "psvc_plugin_psr_init";
209 * So the volatile read/write routines can retrieve data from
212 err
= psvc_init(&hdlp
);
214 init_err(PSVC_INIT_ERR
, funcname
, strerror(errno
));
219 * Remove nodes whose devices aren't present from the picl tree.
221 for (i
= 0; i
< psvc_hdl
.obj_count
; ++i
) {
224 objp
= &psvc_hdl
.objects
[i
];
226 err
= psvc_get_attr(hdlp
, objp
->name
, PSVC_PRESENCE_ATTR
,
228 if (err
!= PSVC_SUCCESS
)
230 err
= psvc_get_attr(hdlp
, objp
->name
, PSVC_FEATURES_ATTR
,
232 if (err
!= PSVC_SUCCESS
)
234 if ((features
& (PSVC_DEV_HOTPLUG
| PSVC_DEV_OPTION
)) &&
235 (present
== PSVC_ABSENT
)) {
236 err
= ptree_delete_node(objp
->node
);
238 init_err(PTREE_DELETE_NODE_ERR
, funcname
,
246 * Remove PICL device nodes if their /devices file isn't present or
247 * if the device file is present but the open returns ENXIO
248 * which indicates that the node file doesn't represent a device
249 * tree node and is probably a relic from some previous boot config
251 for (i
= 0; i
< DEV_PR_COUNT
; ++i
) {
252 picl_nodehdl_t dev_pr_node
;
254 fd
= open(dev_pr_info
[i
].file
, O_RDONLY
);
259 if ((errno
!= ENOENT
) && (errno
!= ENXIO
))
262 err
= ptree_get_node_by_path(dev_pr_info
[i
].path
, &dev_pr_node
);
264 syslog(LOG_ERR
, "Bad path: %s", dev_pr_info
[i
].path
);
265 init_err(PTREE_GET_NODE_ERR
, funcname
,
270 err
= ptree_delete_node(dev_pr_node
);
272 init_err(PTREE_DELETE_NODE_ERR
, funcname
,
277 free(psvc_hdl
.objects
);
281 psvc_psr_plugin_fini(void)
288 psvc_psr_plugin_register(void)
290 picld_plugin_register(&psvc_psr_reg
);