8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / picl / plugins / sun4u / cherrystone / psvcplugin / psvcplugin.c
blob431ba0f75e8a502047f8d758438903ff4c782b67
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 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
37 #include <picl.h>
38 #include <picltree.h>
39 #include <stdio.h>
40 #include <time.h>
41 #include <fcntl.h>
42 #include <unistd.h>
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include <libintl.h>
46 #include <limits.h>
47 #include <ctype.h>
48 #include <errno.h>
49 #include <semaphore.h>
50 #include <syslog.h>
51 #include <string.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 */
62 typedef struct {
63 char name[32];
64 picl_nodehdl_t node;
65 } picl_psvc_t;
67 extern struct handle {
68 uint32_t obj_count;
69 picl_psvc_t *objects;
70 FILE *fp;
71 } psvc_hdl;
73 void psvc_psr_plugin_init(void);
74 void psvc_psr_plugin_fini(void);
76 picld_plugin_reg_t psvc_psr_reg = {
77 PSVC_PLUGIN_VERSION,
78 PICLD_PLUGIN_CRITICAL,
79 "PSVC_PSR",
80 psvc_psr_plugin_init,
81 psvc_psr_plugin_fini
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 /* ======================================== */
92 struct node_file {
93 char path[256];
94 char file[256];
95 } dev_pr_info[] = {
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
171 * sensor
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
183 * picl tree as well.
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)
195 char msg[256];
197 sprintf(msg, fmt, arg1, arg2);
198 syslog(LOG_ERR, msg);
201 void
202 psvc_psr_plugin_init(void)
204 char *funcname = "psvc_plugin_psr_init";
205 int32_t i;
206 int err;
207 boolean_t present;
209 * So the volatile read/write routines can retrieve data from
210 * psvc or picl
212 err = psvc_init(&hdlp);
213 if (err != 0) {
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) {
222 picl_psvc_t *objp;
223 uint64_t features;
224 objp = &psvc_hdl.objects[i];
226 err = psvc_get_attr(hdlp, objp->name, PSVC_PRESENCE_ATTR,
227 &present);
228 if (err != PSVC_SUCCESS)
229 continue;
230 err = psvc_get_attr(hdlp, objp->name, PSVC_FEATURES_ATTR,
231 &features);
232 if (err != PSVC_SUCCESS)
233 continue;
234 if ((features & (PSVC_DEV_HOTPLUG | PSVC_DEV_OPTION)) &&
235 (present == PSVC_ABSENT)) {
236 err = ptree_delete_node(objp->node);
237 if (err != 0) {
238 init_err(PTREE_DELETE_NODE_ERR, funcname,
239 picl_strerror(err));
240 return;
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;
253 int fd;
254 fd = open(dev_pr_info[i].file, O_RDONLY);
255 if (fd != -1) {
256 close(fd);
257 continue;
259 if ((errno != ENOENT) && (errno != ENXIO))
260 continue;
262 err = ptree_get_node_by_path(dev_pr_info[i].path, &dev_pr_node);
263 if (err != 0) {
264 syslog(LOG_ERR, "Bad path: %s", dev_pr_info[i].path);
265 init_err(PTREE_GET_NODE_ERR, funcname,
266 picl_strerror(err));
267 return;
270 err = ptree_delete_node(dev_pr_node);
271 if (err != 0) {
272 init_err(PTREE_DELETE_NODE_ERR, funcname,
273 picl_strerror(err));
274 return;
277 free(psvc_hdl.objects);
280 void
281 psvc_psr_plugin_fini(void)
283 psvc_fini(hdlp);
284 hdlp = NULL;
287 void
288 psvc_psr_plugin_register(void)
290 picld_plugin_register(&psvc_psr_reg);