1 /*
2  * CDDL HEADER START
3  *
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.
8  *
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.
13  *
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]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * This file contains code for setting up environmental related nodes
29  * and properties in the PICL tree.
30  *
31  */
32 
33 #include <stdio.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include <syslog.h>
37 #include <stdlib.h>
38 #include <errno.h>
39 #include <limits.h>
40 #include <sys/open.h>
41 #include <ctype.h>
42 #include <string.h>
43 #include <alloca.h>
44 #include <libintl.h>
45 #include <sys/systeminfo.h>
46 #include <picl.h>
47 #include <picltree.h>
48 #include <picld_pluginutil.h>
49 #include <pthread.h>
50 #include <sys/utsname.h>
51 #include <sys/systeminfo.h>
52 #include "picldefs.h"
53 #include "envd.h"
54 
55 /*
56  * Volatile property read/write function typedef
57  */
58 typedef int ptree_vol_rdfunc_t(ptree_rarg_t *parg, void *buf);
59 typedef int ptree_vol_wrfunc_t(ptree_warg_t *parg, const void *buf);
60 
61 
62 extern sensor_ctrl_blk_t sensor_ctrl[];
63 extern fan_ctrl_blk_t fan_ctrl[];
64 extern env_tuneable_t	tuneables[];
65 extern int ntuneables;
66 
67 #define	PROP_FAN_SPEED_UNIT_VALUE	"rpm"
68 
69 /*
70  * Sensor node data structure
71  */
72 typedef struct {
73 	char		*parent_path;	/* parent path */
74 	char		*sensor_name;	/* sensor name */
75 	env_sensor_t	*sensorp;	/* sensor info */
76 	picl_nodehdl_t	nodeh;		/* sensor node handle */
77 	picl_prophdl_t	proph;		/* "Temperature" property handle */
78 	picl_prophdl_t	target_proph;	/* "TargetTemp" property handle */
79 } sensor_node_t;
80 
81 
82 /*
83  * Sensor nodes array
84  */
85 static sensor_node_t sensor_nodes[] = {
86 	{"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c",
87 	SENSOR_CPU_DIE, NULL,
88 	0, 0, 0},
89 
90 	{"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c",
91 	SENSOR_INT_AMB, NULL,
92 	0, 0, 0},
93 
94 	{"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c",
95 	SENSOR_SYS_IN, NULL,
96 	0, 0, 0}
97 };
98 #define	NSENSORS	(sizeof (sensor_nodes)/sizeof (sensor_nodes[0]))
99 
100 
101 /*
102  * Fan node data structure
103  */
104 typedef struct {
105 	char		*parent_path;	/* parent node path */
106 	char		*fan_name;	/* fan name */
107 	env_fan_t	*fanp;		/* fan information */
108 	char		*speed_unit;	/* speed unit string */
109 	picl_nodehdl_t	nodeh;		/* "fan" node handle */
110 	picl_prophdl_t	proph;		/* "Speed" property handle */
111 } fan_node_t;
112 
113 
114 /*
115  * Fan node array
116  */
117 static fan_node_t fan_nodes[] =  {
118 	{"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c",
119 	ENV_CPU_FAN, NULL, PROP_FAN_SPEED_UNIT_VALUE, 0, 0},
120 
121 	{"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c",
122 	ENV_SYSTEM_INTAKE_FAN, NULL, PROP_FAN_SPEED_UNIT_VALUE, 0, 0},
123 
124 	{"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c",
125 	ENV_SYSTEM_OUT_FAN, NULL, PROP_FAN_SPEED_UNIT_VALUE, 0, 0}
126 };
127 #define	NFANS	(sizeof (fan_nodes)/sizeof (fan_nodes[0]))
128 
129 /*
130  * Miscellaneous declarations
131  */
132 static void delete_sensor_nodes_and_props(void);
133 static void delete_fan_nodes_and_props(void);
134 
135 
136 /*
137  * Read function for volatile "Temperature" property
138  */
139 static int
get_current_temp(ptree_rarg_t * parg,void * buf)140 get_current_temp(ptree_rarg_t *parg, void *buf)
141 {
142 	tempr_t		temp;
143 	picl_prophdl_t	proph;
144 	sensor_node_t	*snodep;
145 	int		i;
146 
147 	/*
148 	 * Locate the sensor in our sensor_nodes table by matching the
149 	 * property handle and get its temperature.
150 	 */
151 	proph = parg->proph;
152 	for (i = 0; i < NSENSORS; ++i) {
153 		snodep = &sensor_nodes[i];
154 		if (snodep->proph != proph)
155 			continue;
156 
157 		if (get_temperature(snodep->sensorp, &temp) < 0)
158 			break;
159 		(void) memcpy(buf, (caddr_t)&temp, sizeof (tempr_t));
160 		return (PICL_SUCCESS);
161 	}
162 	return (PICL_FAILURE);
163 }
164 /*
165  * Read function for volatile "Speed" property on "fan" class node
166  */
167 static int
set_current_speed(ptree_warg_t * parg,const void * buf)168 set_current_speed(ptree_warg_t *parg, const void *buf)
169 {
170 	fanspeed_t	speed;
171 	picl_prophdl_t	proph;
172 	fan_node_t	*fnodep;
173 	int		i, ret;
174 
175 	/*
176 	 * Locate the fan in our fan_nodes table by matching the
177 	 * property handle and get fan speed.
178 	 */
179 	proph = parg->proph;
180 	for (i = 0; i < NFANS; ++i) {
181 		fnodep = &fan_nodes[i];
182 		if (fnodep->proph != proph)
183 			continue;
184 		if (fnodep->fanp->fd == -1)
185 			continue;
186 
187 		(void) memcpy((caddr_t)&speed, buf, sizeof (speed));
188 
189 		ret = set_fan_speed(fnodep->fanp, speed);
190 
191 		if (ret < 0) {
192 			if (ret == -1 && errno == EBUSY)
193 				return (PICL_NOTWRITABLE);
194 			if (ret == -2)
195 				return (PICL_INVALIDARG);
196 			break;
197 		}
198 
199 		return (PICL_SUCCESS);
200 	}
201 	return (PICL_FAILURE);
202 }
203 
204 
205 /*
206  * Read function for volatile "Speed" property on "fan" class node
207  */
208 static int
get_current_speed(ptree_rarg_t * parg,void * buf)209 get_current_speed(ptree_rarg_t *parg, void *buf)
210 {
211 	fanspeed_t	speed;
212 	picl_prophdl_t	proph;
213 	fan_node_t	*fnodep;
214 	int		i;
215 
216 	/*
217 	 * Locate the fan in our fan_nodes table by matching the
218 	 * property handle and get fan speed.
219 	 */
220 	proph = parg->proph;
221 	for (i = 0; i < NFANS; ++i) {
222 		fnodep = &fan_nodes[i];
223 		if (fnodep->proph != proph)
224 			continue;
225 		if (fnodep->fanp->fd == -1)
226 			continue;
227 		if (get_fan_speed(fnodep->fanp, &speed) < 0)
228 			break;
229 
230 		(void) memcpy(buf, (caddr_t)&speed, sizeof (speed));
231 		return (PICL_SUCCESS);
232 	}
233 	return (PICL_FAILURE);
234 }
235 
236 /*
237  * Create and add the specified regular property
238  */
239 
240 static int
add_regular_prop(picl_nodehdl_t nodeh,char * name,int type,int access,int size,void * valbuf,picl_prophdl_t * prophp)241 add_regular_prop(picl_nodehdl_t nodeh, char *name, int type, int access,
242     int size, void *valbuf, picl_prophdl_t *prophp)
243 {
244 	int			err;
245 	ptree_propinfo_t	propinfo;
246 	picl_prophdl_t		proph;
247 
248 	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
249 	    type, access, size, name, NULL, NULL);
250 	if (err != PICL_SUCCESS)
251 		return (err);
252 
253 	err = ptree_create_and_add_prop(nodeh, &propinfo, valbuf, &proph);
254 	if (err == PICL_SUCCESS && prophp)
255 		*prophp = proph;
256 	return (err);
257 }
258 
259 
260 /*
261  * Create and add the specified volatile property
262  */
263 static int
add_volatile_prop(picl_nodehdl_t nodeh,char * name,int type,int access,int size,ptree_vol_rdfunc_t * rdfunc,ptree_vol_wrfunc_t * wrfunc,picl_prophdl_t * prophp)264 add_volatile_prop(picl_nodehdl_t nodeh, char *name, int type, int access,
265     int size, ptree_vol_rdfunc_t *rdfunc, ptree_vol_wrfunc_t *wrfunc,
266     picl_prophdl_t *prophp)
267 {
268 	int			err;
269 	ptree_propinfo_t	propinfo;
270 	picl_prophdl_t		proph;
271 
272 	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
273 	    type, (access|PICL_VOLATILE), size, name, rdfunc, wrfunc);
274 	if (err != PICL_SUCCESS)
275 		return (err);
276 
277 	err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, &proph);
278 	if (err == PICL_SUCCESS && prophp)
279 		*prophp = proph;
280 	return (err);
281 }
282 
283 /*
284  * Add temperature threshold properties
285  */
286 static void
add_sensor_thresh_props(picl_nodehdl_t nodeh,sensor_ctrl_blk_t * threshp)287 add_sensor_thresh_props(picl_nodehdl_t nodeh, sensor_ctrl_blk_t *threshp)
288 {
289 	picl_prophdl_t	proph;
290 
291 	(void) add_regular_prop(nodeh, PICL_PROP_LOW_POWER_OFF,
292 	    PICL_PTYPE_INT, PICL_READ,
293 	    sizeof (threshp->low_power_off),
294 	    (void *)&(threshp->low_power_off), &proph);
295 
296 	(void) add_regular_prop(nodeh, PICL_PROP_LOW_SHUTDOWN,
297 	    PICL_PTYPE_INT, PICL_READ,
298 	    sizeof (threshp->low_shutdown),
299 	    (void *)&(threshp->low_shutdown), &proph);
300 
301 	(void) add_regular_prop(nodeh, PICL_PROP_LOW_WARNING,
302 	    PICL_PTYPE_INT, PICL_READ,
303 	    sizeof (threshp->low_warning),
304 	    (void *)&(threshp->low_warning), &proph);
305 
306 	(void) add_regular_prop(nodeh, PICL_PROP_HIGH_WARNING,
307 	    PICL_PTYPE_INT, PICL_READ,
308 	    sizeof (threshp->high_warning),
309 	    (void *)&(threshp->high_warning), &proph);
310 
311 	(void) add_regular_prop(nodeh, PICL_PROP_HIGH_SHUTDOWN,
312 	    PICL_PTYPE_INT, PICL_READ,
313 	    sizeof (threshp->high_shutdown),
314 	    (void *)&(threshp->high_shutdown), &proph);
315 
316 	(void) add_regular_prop(nodeh, PICL_PROP_HIGH_POWER_OFF,
317 	    PICL_PTYPE_INT, PICL_READ,
318 	    sizeof (threshp->high_power_off),
319 	    (void *)&(threshp->high_power_off), &proph);
320 }
321 
322 /*
323  * Go through the sensor_nodes array and create those nodes
324  * and the Temperature property to report the temperature.
325  */
326 static int
add_sensor_nodes_and_props(void)327 add_sensor_nodes_and_props(void)
328 {
329 	int		err;
330 	char		*pname, *nodename, *devfs_path;
331 	sensor_node_t	*snodep;
332 	sensor_ctrl_blk_t *threshp;
333 	picl_nodehdl_t	nodeh, cnodeh;
334 	picl_prophdl_t	proph;
335 	env_sensor_t	*sensorp;
336 	int		i;
337 
338 	for (i = 0; i < NSENSORS; ++i) {
339 		snodep = &sensor_nodes[i];
340 		/*
341 		 * Get the parent nodeh
342 		 */
343 		err = ptree_get_node_by_path(snodep->parent_path, &nodeh);
344 		if (err != PICL_SUCCESS)
345 			continue;
346 		sensorp = snodep->sensorp;
347 
348 		/*
349 		 * Create temperature-sensor node
350 		 */
351 		nodename = snodep->sensor_name;
352 		err = ptree_create_and_add_node(nodeh, nodename,
353 		    PICL_CLASS_TEMPERATURE_SENSOR, &cnodeh);
354 		if (env_debug)
355 			envd_log(LOG_INFO,
356 			    "Creating PICL sensor node '%s' err:%d\n",
357 			    nodename, err);
358 		if (err != PICL_SUCCESS)
359 			break;
360 
361 		/* save node handle */
362 		snodep->nodeh = cnodeh;
363 
364 		/*
365 		 * Add "devfs_path" property in child node
366 		 */
367 		devfs_path = sensorp->devfs_path;
368 		pname = PICL_PROP_DEVFS_PATH;
369 		err = add_regular_prop(cnodeh, pname,
370 		    PICL_PTYPE_CHARSTRING, PICL_READ,
371 		    strlen(devfs_path)+1, (void *)devfs_path, &proph);
372 		if (err != PICL_SUCCESS)
373 			break;
374 
375 		/*
376 		 * Now add volatile "temperature" volatile property
377 		 * in this "temperature-sensor" class node.
378 		 */
379 		pname = PICL_PROP_TEMPERATURE;
380 		err = add_volatile_prop(cnodeh, pname,
381 		    PICL_PTYPE_INT, PICL_READ, sizeof (tempr_t),
382 		    get_current_temp, NULL, &proph);
383 		if (err != PICL_SUCCESS)
384 			break;
385 
386 		/* Save prop handle */
387 		snodep->proph = proph;
388 
389 		/*
390 		 * Add threshold related properties
391 		 */
392 		threshp = sensorp->es_ptr;
393 
394 		if (threshp != NULL)
395 			add_sensor_thresh_props(cnodeh, threshp);
396 
397 	}
398 	if (err != PICL_SUCCESS) {
399 		delete_sensor_nodes_and_props();
400 		if (env_debug)
401 			envd_log(LOG_INFO,
402 			    "Can't create prop/node for sensor '%s'\n",
403 			    nodename);
404 		return (err);
405 	}
406 	return (PICL_SUCCESS);
407 }
408 
409 /*
410  * Delete all sensor nodes and related properties created by the
411  * add_sensor_prop() for each sensor node in the PICL tree.
412  */
413 static void
delete_sensor_nodes_and_props(void)414 delete_sensor_nodes_and_props(void)
415 {
416 	sensor_node_t	*snodep;
417 	int		i;
418 
419 	/*
420 	 * Delete/destroy any property created in the sensed device
421 	 * as well as the sensor node and all properties under it.
422 	 * Note that deleiing/destroying a node deletes/destroys
423 	 * all properties within that node.
424 	 */
425 
426 	for (i = 0; i < NSENSORS; ++i) {
427 		snodep = &sensor_nodes[i];
428 		if (snodep->nodeh != 0) {
429 			/* delete node and all properties under it */
430 			(void) ptree_delete_node(snodep->nodeh);
431 			(void) ptree_destroy_node(snodep->nodeh);
432 			snodep->nodeh = 0;
433 			snodep->proph = 0;
434 		}
435 	}
436 }
437 
438 
439 /*
440  * For each entry in fan_nodes[] array, do the following:
441  *	- Create specified "fan" class node.
442  *	- Create "Speed" volatile propery under "fan" class node.
443  *	- Create "SpeedUnit" property under "fan" class node.
444  */
445 static int
add_fan_nodes_and_props()446 add_fan_nodes_and_props()
447 {
448 	int		err;
449 	char		*pname, *nodename, *devfs_path;
450 	env_fan_t	*fanp;
451 	fan_node_t	*fnodep;
452 	picl_nodehdl_t	nodeh, cnodeh;
453 	picl_prophdl_t	proph;
454 	int		i;
455 
456 
457 	for (i = 0; i < NFANS; ++i) {
458 		/*
459 		 * Add various fan nodes and properties
460 		 */
461 		fnodep = &fan_nodes[i];
462 		/*
463 		 * get parent nodeh
464 		 */
465 		err = ptree_get_node_by_path(fnodep->parent_path, &nodeh);
466 		if (err != PICL_SUCCESS)
467 			continue;
468 
469 		/*
470 		 * Create "fan" class node and save node handle
471 		 */
472 		nodename = fnodep->fan_name;
473 		err = ptree_create_and_add_node(nodeh, nodename,
474 		    PICL_CLASS_FAN, &cnodeh);
475 		if (env_debug)
476 			envd_log(LOG_INFO,
477 			    "Creating PICL fan node '%s' err:%d\n",
478 			    nodename, err);
479 
480 		if (err != PICL_SUCCESS)
481 			break;
482 		fnodep->nodeh = cnodeh;
483 
484 		/*
485 		 * Add "devfs_path" property in child node
486 		 */
487 		fanp = fnodep->fanp;
488 		devfs_path  = fanp->devfs_path;
489 		pname = PICL_PROP_DEVFS_PATH;
490 		err = add_regular_prop(cnodeh, pname,
491 		    PICL_PTYPE_CHARSTRING, PICL_READ,
492 		    strlen(devfs_path)+1, (void *)devfs_path, &proph);
493 
494 		if (err != PICL_SUCCESS)
495 
496 			break;
497 
498 		/*
499 		 * Add "Speed" volatile property in this "fan"
500 		 * class node and save prop handle.
501 		 */
502 		pname = PICL_PROP_FAN_SPEED;
503 		err = add_volatile_prop(cnodeh, pname, PICL_PTYPE_INT,
504 		    PICL_READ|PICL_WRITE, sizeof (fanspeed_t),
505 		    get_current_speed,
506 		    set_current_speed, &proph);
507 
508 		if (err != PICL_SUCCESS)
509 			break;
510 		fnodep->proph = proph;
511 
512 		/*
513 		 * Add other "fan" class properties
514 		 */
515 		pname = PICL_PROP_FAN_SPEED_UNIT;
516 		err = add_regular_prop(cnodeh, pname,
517 		    PICL_PTYPE_CHARSTRING, PICL_READ,
518 		    strlen(fnodep->speed_unit)+1,
519 		    (void *)fnodep->speed_unit, &proph);
520 
521 		if (err != PICL_SUCCESS)
522 			break;
523 	}
524 	if (err != PICL_SUCCESS) {
525 		delete_fan_nodes_and_props();
526 		if (env_debug)
527 			envd_log(LOG_WARNING,
528 			    "Can't create prop/node for fan '%s'\n",
529 			    nodename);
530 		return (err);
531 	}
532 	return (PICL_SUCCESS);
533 }
534 
535 
536 /*
537  * Delete all fan nodes and related properties created by the
538  * add_fan_props() for each fan node in the PICL tree.
539  */
540 static void
delete_fan_nodes_and_props(void)541 delete_fan_nodes_and_props(void)
542 {
543 	fan_node_t	*fnodep;
544 	int		i;
545 
546 	/*
547 	 * Delete/destroy fan node and all properties under it.
548 	 * Note that deleiing/destroying a node deletes/destroys
549 	 * all properties within that node.
550 	 */
551 
552 	for (i = 0; i < NFANS; ++i) {
553 		fnodep = &fan_nodes[i];
554 		if (fnodep->nodeh != 0) {
555 			(void) ptree_delete_node(fnodep->nodeh);
556 			(void) ptree_destroy_node(fnodep->nodeh);
557 			fnodep->nodeh = 0;
558 		}
559 	}
560 }
561 
562 /*
563  * Tuneables publishing functions
564  */
565 static int
copy_persistent_tuneable(env_tuneable_t * tune,char * buf)566 copy_persistent_tuneable(env_tuneable_t *tune, char *buf)
567 {
568 
569 	switch (tune->type) {
570 
571 	case PICL_PTYPE_INT : {
572 		(void) memcpy((int *)tune->value,
573 		    buf, tune->nbytes);
574 		break;
575 	}
576 	case PICL_PTYPE_CHARSTRING : {
577 		(void) memcpy((caddr_t)tune->value,
578 		    buf, tune->nbytes);
579 		break;
580 	}
581 	default	: {
582 		return (PICL_FAILURE);
583 	}
584 	}
585 	return (PICL_SUCCESS);
586 }
587 
588 static void
env_parse_tunables(picl_nodehdl_t rooth)589 env_parse_tunables(picl_nodehdl_t rooth)
590 {
591 	char	nmbuf[SYS_NMLN];
592 	char    pname[PATH_MAX];
593 
594 	if (sysinfo(SI_PLATFORM, nmbuf, sizeof (nmbuf)) != -1) {
595 		(void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
596 		(void) strlcat(pname, TUNABLE_CONF_FILE, PATH_MAX);
597 		if (access(pname, R_OK) == 0) {
598 			(void) picld_pluginutil_parse_config_file(rooth, pname);
599 			return;
600 		}
601 	}
602 }
603 
604 int
env_picl_setup_tuneables(void)605 env_picl_setup_tuneables(void)
606 {
607 	int		err;
608 	int		i;
609 	picl_nodehdl_t	nodeh;
610 	picl_nodehdl_t	rooth;
611 	picl_prophdl_t	proph;
612 	env_tuneable_t	*tuneablep;
613 	char		read_buf[BUFSIZ];
614 
615 	if (ptree_get_root(&rooth) != PICL_SUCCESS) {
616 		return (PICL_FAILURE);
617 	}
618 	err = ptree_create_and_add_node(rooth, PICL_PLUGINS_NODE,
619 	    PICL_CLASS_PICL, &nodeh);
620 	if (err != PICL_SUCCESS)
621 		return (PICL_FAILURE);
622 	err = ptree_create_and_add_node(nodeh, PICL_ENVIRONMENTAL_NODE,
623 	    PICL_CLASS_PICL, &nodeh);
624 	if (err != PICL_SUCCESS) {
625 		return (PICL_FAILURE);
626 	}
627 
628 	/*
629 	 * Parse the conf file
630 	 */
631 	env_parse_tunables(rooth);
632 	for (i = 0; i < ntuneables; i++) {
633 		tuneablep = &tuneables[i];
634 		err = ptree_get_propval_by_name(nodeh, tuneablep->name,
635 		    read_buf, tuneablep->nbytes);
636 
637 		if (err != PICL_SUCCESS) {
638 			/*
639 			 * Add volitle functions to environmental node
640 			 */
641 			err = add_volatile_prop(nodeh, tuneablep->name,
642 			    tuneablep->type,
643 			    PICL_READ|PICL_WRITE, tuneablep->nbytes,
644 			    tuneablep->rfunc,
645 			    tuneablep->wfunc, &proph);
646 
647 			tuneablep->proph = proph;
648 		} else {
649 			/*
650 			 * property is persistent
651 			 */
652 			(void) copy_persistent_tuneable(tuneablep,
653 			    read_buf);
654 		}
655 	}
656 
657 	return	(PICL_SUCCESS);
658 }
659 
660 /*
661  * Find the ENVMODEL_CONF_FILE file.
662  */
663 static int
get_envmodel_conf_file(char * outfilename)664 get_envmodel_conf_file(char *outfilename)
665 {
666 	char	nmbuf[SYS_NMLN];
667 	char    pname[PATH_MAX];
668 
669 	if (sysinfo(SI_PLATFORM, nmbuf, sizeof (nmbuf)) != -1) {
670 		(void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
671 		(void) strlcat(pname, ENV_CONF_FILE, PATH_MAX);
672 		if (access(pname, R_OK) == 0) {
673 			(void) strlcpy(outfilename, pname, PATH_MAX);
674 			return (0);
675 		}
676 	}
677 
678 	if (sysinfo(SI_MACHINE, nmbuf, sizeof (nmbuf)) != -1) {
679 		(void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
680 		(void) strlcat(pname, ENV_CONF_FILE, PATH_MAX);
681 		if (access(pname, R_OK) == 0) {
682 			(void) strlcpy(outfilename, pname, PATH_MAX);
683 			return (0);
684 		}
685 	}
686 
687 	(void) snprintf(pname, PATH_MAX, "%s/%s", PICLD_COMMON_PLUGIN_DIR,
688 	    ENV_CONF_FILE);
689 
690 	if (access(pname, R_OK) == 0) {
691 		(void) strlcpy(outfilename, pname, PATH_MAX);
692 		return (0);
693 	}
694 
695 	return (-1);
696 }
697 
698 /* Delete all sensor/fan nodes and any properties created by this plugin */
699 void
env_picl_destroy(void)700 env_picl_destroy(void)
701 {
702 	delete_fan_nodes_and_props();
703 	delete_sensor_nodes_and_props();
704 }
705 
706 void
env_picl_setup(void)707 env_picl_setup(void)
708 {
709 	int		err;
710 	sensor_node_t	*snodep;
711 	fan_node_t	*fnodep;
712 	char		fullfilename[PATH_MAX];
713 	picl_nodehdl_t  rooth;
714 	int		i;
715 
716 
717 	/*
718 	 * Initialize sensorp and other fields in the sensor_nodes[] array
719 	 */
720 
721 	for (i = 0; i < NSENSORS; ++i) {
722 		snodep = &sensor_nodes[i];
723 		snodep->sensorp = sensor_lookup(snodep->sensor_name);
724 		snodep->nodeh = 0;
725 		snodep->proph = 0;
726 		snodep->target_proph = 0;
727 	}
728 
729 	/*
730 	 * Initialize fanp and other fields in the fan_nodes[] array
731 	 */
732 	for (i = 0; i < NFANS; ++i) {
733 		fnodep = &fan_nodes[i];
734 		fnodep->fanp = fan_lookup(fnodep->fan_name);
735 		fnodep->nodeh = 0;
736 		fnodep->proph = 0;
737 	}
738 
739 	/*
740 	 * Get platform handle and populate PICL tree with environmental
741 	 * nodes and properties
742 	 */
743 
744 	err = add_sensor_nodes_and_props();
745 
746 	if (err == PICL_SUCCESS)
747 		err = add_fan_nodes_and_props();
748 
749 
750 	if (err != PICL_SUCCESS) {
751 		delete_sensor_nodes_and_props();
752 		envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
753 		return;
754 	}
755 
756 	/*
757 	 * Parse the envmodel.conf file and populate the PICL tree
758 	 */
759 	if (get_envmodel_conf_file(fullfilename) < 0)
760 		envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
761 	if (ptree_get_root(&rooth) != PICL_SUCCESS)
762 		envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
763 	err = picld_pluginutil_parse_config_file(rooth, fullfilename);
764 
765 	if (err != PICL_SUCCESS)
766 		envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
767 }
768