xref: /onnv-gate/usr/src/cmd/picl/plugins/sun4u/chicago/envd/piclenvsetup.c (revision 707:ebdb0ba40911)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate  * This file contains code for setting up environmental related nodes
310Sstevel@tonic-gate  * and properties in the PICL tree.
320Sstevel@tonic-gate  *
330Sstevel@tonic-gate  */
340Sstevel@tonic-gate 
350Sstevel@tonic-gate #include <stdio.h>
360Sstevel@tonic-gate #include <fcntl.h>
370Sstevel@tonic-gate #include <unistd.h>
380Sstevel@tonic-gate #include <syslog.h>
390Sstevel@tonic-gate #include <stdlib.h>
400Sstevel@tonic-gate #include <limits.h>
410Sstevel@tonic-gate #include <errno.h>
420Sstevel@tonic-gate #include <sys/open.h>
430Sstevel@tonic-gate #include <ctype.h>
440Sstevel@tonic-gate #include <string.h>
450Sstevel@tonic-gate #include <alloca.h>
460Sstevel@tonic-gate #include <libintl.h>
470Sstevel@tonic-gate #include <sys/systeminfo.h>
480Sstevel@tonic-gate #include <picl.h>
490Sstevel@tonic-gate #include <picltree.h>
500Sstevel@tonic-gate #include <picld_pluginutil.h>
510Sstevel@tonic-gate #include <pthread.h>
520Sstevel@tonic-gate #include <sys/utsname.h>
530Sstevel@tonic-gate #include <sys/systeminfo.h>
540Sstevel@tonic-gate #include "picldefs.h"
550Sstevel@tonic-gate #include "envd.h"
560Sstevel@tonic-gate 
570Sstevel@tonic-gate /*
580Sstevel@tonic-gate  * Volatile property read/write function typedef
590Sstevel@tonic-gate  */
600Sstevel@tonic-gate typedef int ptree_vol_rdfunc_t(ptree_rarg_t *parg, void *buf);
610Sstevel@tonic-gate typedef int ptree_vol_wrfunc_t(ptree_warg_t *parg, const void *buf);
620Sstevel@tonic-gate 
63138Svenki extern int disk_temp_monitor;
640Sstevel@tonic-gate extern env_tuneable_t	tuneables[];
650Sstevel@tonic-gate extern	int errno;
660Sstevel@tonic-gate extern	int	ntuneables;
670Sstevel@tonic-gate #define	PROP_FAN_SPEED_UNIT_VALUE	"rpm"
680Sstevel@tonic-gate 
690Sstevel@tonic-gate /*
700Sstevel@tonic-gate  * Sensor node data structure
710Sstevel@tonic-gate  */
720Sstevel@tonic-gate typedef struct {
730Sstevel@tonic-gate 	char		*parent_path;	/* parent path */
740Sstevel@tonic-gate 	char		*sensor_name;	/* sensor name */
750Sstevel@tonic-gate 	env_sensor_t	*sensorp;	/* sensor info */
760Sstevel@tonic-gate 	picl_nodehdl_t	nodeh;		/* sensor node handle */
770Sstevel@tonic-gate 	picl_prophdl_t	proph;		/* "Temperature" property handle */
780Sstevel@tonic-gate 	picl_prophdl_t	target_proph;	/* "TargetTemp" property handle */
790Sstevel@tonic-gate } sensor_node_t;
800Sstevel@tonic-gate 
810Sstevel@tonic-gate /*
820Sstevel@tonic-gate  * Sensor nodes array
830Sstevel@tonic-gate  */
840Sstevel@tonic-gate static sensor_node_t sensor_nodes[] = {
850Sstevel@tonic-gate 	{"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_CPU0,
860Sstevel@tonic-gate 	NULL, NULL, NULL, NULL},
870Sstevel@tonic-gate 	{"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_CPU1,
880Sstevel@tonic-gate 	NULL, NULL, NULL, NULL},
890Sstevel@tonic-gate 	{"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_MB,
900Sstevel@tonic-gate 	NULL, NULL, NULL, NULL},
910Sstevel@tonic-gate 	{"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_ADT7462,
920Sstevel@tonic-gate 	NULL, NULL, NULL, NULL},
930Sstevel@tonic-gate 	{"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_LM95221,
940Sstevel@tonic-gate 	NULL, NULL, NULL, NULL},
950Sstevel@tonic-gate 	{"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_FIRE,
960Sstevel@tonic-gate 	NULL, NULL, NULL, NULL},
970Sstevel@tonic-gate 	{"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_LSI1064,
980Sstevel@tonic-gate 	NULL, NULL, NULL, NULL},
990Sstevel@tonic-gate 	{"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_FRONT_PANEL,
100*707Svenki 	NULL, NULL, NULL, NULL},
101*707Svenki 	{"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_PSU,
1020Sstevel@tonic-gate 	NULL, NULL, NULL, NULL}
1030Sstevel@tonic-gate };
1040Sstevel@tonic-gate #define	N_SENSOR_NODES	(sizeof (sensor_nodes)/sizeof (sensor_nodes[0]))
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate /*
1070Sstevel@tonic-gate  * Fan node data structure
1080Sstevel@tonic-gate  */
1090Sstevel@tonic-gate typedef struct {
1100Sstevel@tonic-gate 	char		*parent_path;	/* parent node path */
1110Sstevel@tonic-gate 	char		*fan_name;	/* fan name */
1120Sstevel@tonic-gate 	env_fan_t 	*fanp;		/* fan information */
1130Sstevel@tonic-gate 	char		*speed_unit;	/* speed unit string */
1140Sstevel@tonic-gate 	picl_nodehdl_t	nodeh;		/* "fan" node handle */
1150Sstevel@tonic-gate 	picl_prophdl_t	proph;		/* "Speed" property handle */
1160Sstevel@tonic-gate } fan_node_t;
1170Sstevel@tonic-gate 
1180Sstevel@tonic-gate /*
1190Sstevel@tonic-gate  * Fan node array
1200Sstevel@tonic-gate  */
1210Sstevel@tonic-gate static fan_node_t fan_nodes[] =  {
1220Sstevel@tonic-gate 	{"/platform/ebus@1f,464000/env-monitor@3,0", ENV_SYSTEM_FAN0,
1230Sstevel@tonic-gate 	NULL, PROP_FAN_SPEED_UNIT_VALUE, NULL, NULL},
1240Sstevel@tonic-gate 	{"/platform/ebus@1f,464000/env-monitor@3,0", ENV_SYSTEM_FAN1,
1250Sstevel@tonic-gate 	NULL, PROP_FAN_SPEED_UNIT_VALUE, NULL, NULL},
1260Sstevel@tonic-gate 	{"/platform/ebus@1f,464000/env-monitor@3,0", ENV_SYSTEM_FAN2,
1270Sstevel@tonic-gate 	NULL, PROP_FAN_SPEED_UNIT_VALUE, NULL, NULL},
1280Sstevel@tonic-gate 	{"/platform/ebus@1f,464000/env-monitor@3,0", ENV_SYSTEM_FAN3,
1290Sstevel@tonic-gate 	NULL, PROP_FAN_SPEED_UNIT_VALUE, NULL, NULL},
1300Sstevel@tonic-gate 	{"/platform/ebus@1f,464000/env-monitor@3,0", ENV_SYSTEM_FAN4,
1310Sstevel@tonic-gate 	NULL, PROP_FAN_SPEED_UNIT_VALUE, NULL, NULL}
1320Sstevel@tonic-gate };
1330Sstevel@tonic-gate #define	N_FAN_NODES	(sizeof (fan_nodes)/sizeof (fan_nodes[0]))
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate /*
1360Sstevel@tonic-gate  * Disk node data structure
1370Sstevel@tonic-gate  */
1380Sstevel@tonic-gate typedef struct {
1390Sstevel@tonic-gate 	char		*parent_path;	/* parent node path */
1400Sstevel@tonic-gate 	char		*disk_name;	/* disk name */
1410Sstevel@tonic-gate 	env_disk_t 	*diskp;		/* disk information */
1420Sstevel@tonic-gate 	picl_nodehdl_t	nodeh;		/* "disk" node handle */
1430Sstevel@tonic-gate 	picl_prophdl_t	proph;		/* "Temperature" property handle */
1440Sstevel@tonic-gate } disk_node_t;
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate /*
1470Sstevel@tonic-gate  * Disk node array
1480Sstevel@tonic-gate  */
1490Sstevel@tonic-gate static disk_node_t disk_nodes[] =  {
1500Sstevel@tonic-gate 	{DISK0_NODE_PATH, ENV_DISK0, NULL, NULL, NULL},
1510Sstevel@tonic-gate 	{DISK1_NODE_PATH, ENV_DISK1, NULL, NULL, NULL},
1520Sstevel@tonic-gate 	{DISK2_NODE_PATH, ENV_DISK2, NULL, NULL, NULL},
1530Sstevel@tonic-gate 	{DISK3_NODE_PATH, ENV_DISK3, NULL, NULL, NULL}
1540Sstevel@tonic-gate };
1550Sstevel@tonic-gate #define	N_DISK_NODES	(sizeof (disk_nodes)/sizeof (disk_nodes[0]))
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate /*
1580Sstevel@tonic-gate  * Miscellaneous declarations
1590Sstevel@tonic-gate  */
1600Sstevel@tonic-gate static void delete_sensor_nodes_and_props(void);
1610Sstevel@tonic-gate static void delete_disk_nodes_and_props(void);
1620Sstevel@tonic-gate static void delete_fan_nodes_and_props(void);
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate /*
1660Sstevel@tonic-gate  * Read function for volatile "Temperature" property
1670Sstevel@tonic-gate  */
1680Sstevel@tonic-gate static int
get_current_temp(ptree_rarg_t * parg,void * buf)1690Sstevel@tonic-gate get_current_temp(ptree_rarg_t *parg, void *buf)
1700Sstevel@tonic-gate {
1710Sstevel@tonic-gate 	tempr_t 	temp;
1720Sstevel@tonic-gate 	picl_prophdl_t	proph;
1730Sstevel@tonic-gate 	sensor_node_t	*snodep;
1740Sstevel@tonic-gate 	int		i;
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate 	/*
1770Sstevel@tonic-gate 	 * Locate the sensor in our sensor_nodes table by matching the
1780Sstevel@tonic-gate 	 * property handle and get its temperature.
1790Sstevel@tonic-gate 	 */
1800Sstevel@tonic-gate 	proph = parg->proph;
1810Sstevel@tonic-gate 	for (i = 0; i < N_SENSOR_NODES; i++) {
1820Sstevel@tonic-gate 		snodep = &sensor_nodes[i];
1830Sstevel@tonic-gate 		if (snodep->proph != proph)
1840Sstevel@tonic-gate 			continue;
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 		if (get_temperature(snodep->sensorp, &temp) < 0)
1870Sstevel@tonic-gate 			break;
1880Sstevel@tonic-gate 		(void) memcpy(buf, (caddr_t)&temp, sizeof (tempr_t));
1890Sstevel@tonic-gate 		return (PICL_SUCCESS);
1900Sstevel@tonic-gate 	}
1910Sstevel@tonic-gate 	return (PICL_FAILURE);
1920Sstevel@tonic-gate }
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate /*
1950Sstevel@tonic-gate  * Read function for volatile "Temperature" property
1960Sstevel@tonic-gate  */
1970Sstevel@tonic-gate static int
get_disk_temp(ptree_rarg_t * parg,void * buf)1980Sstevel@tonic-gate get_disk_temp(ptree_rarg_t *parg, void *buf)
1990Sstevel@tonic-gate {
2000Sstevel@tonic-gate 	tempr_t 	temp;
2010Sstevel@tonic-gate 	picl_prophdl_t	proph;
2020Sstevel@tonic-gate 	disk_node_t	*dnodep;
2030Sstevel@tonic-gate 	int		i;
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate 	/*
2060Sstevel@tonic-gate 	 * Locate the sensor in our sensor_nodes table by matching the
2070Sstevel@tonic-gate 	 * property handle and get its temperature.
2080Sstevel@tonic-gate 	 */
2090Sstevel@tonic-gate 	proph = parg->proph;
2100Sstevel@tonic-gate 	for (i = 0; i < N_DISK_NODES; i++) {
2110Sstevel@tonic-gate 		dnodep = &disk_nodes[i];
2120Sstevel@tonic-gate 		if (dnodep->proph != proph)
2130Sstevel@tonic-gate 			continue;
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate 		if (disk_temperature(dnodep->diskp, &temp) < 0)
2160Sstevel@tonic-gate 			break;
2170Sstevel@tonic-gate 		(void) memcpy(buf, (caddr_t)&temp, sizeof (tempr_t));
2180Sstevel@tonic-gate 		return (PICL_SUCCESS);
2190Sstevel@tonic-gate 	}
2200Sstevel@tonic-gate 	return (PICL_FAILURE);
2210Sstevel@tonic-gate }
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate /*
2240Sstevel@tonic-gate  * Read function for volatile "Speed" property on "fan" class node
2250Sstevel@tonic-gate  */
2260Sstevel@tonic-gate static int
set_current_speed(ptree_warg_t * parg,const void * buf)2270Sstevel@tonic-gate set_current_speed(ptree_warg_t *parg, const void *buf)
2280Sstevel@tonic-gate {
2290Sstevel@tonic-gate 	fanspeed_t	speed;
2300Sstevel@tonic-gate 	picl_prophdl_t	proph;
2310Sstevel@tonic-gate 	fan_node_t	*fnodep;
2320Sstevel@tonic-gate 	int		i, ret;
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate 	/*
2350Sstevel@tonic-gate 	 * Locate the fan in our fan_nodes table by matching the
2360Sstevel@tonic-gate 	 * property handle and get fan speed.
2370Sstevel@tonic-gate 	 */
2380Sstevel@tonic-gate 	proph = parg->proph;
2390Sstevel@tonic-gate 	for (i = 0; i < N_FAN_NODES; i++) {
2400Sstevel@tonic-gate 		fnodep = &fan_nodes[i];
2410Sstevel@tonic-gate 		if (fnodep->proph != proph)
2420Sstevel@tonic-gate 			continue;
2430Sstevel@tonic-gate 		if (fnodep->fanp->fd == -1)
2440Sstevel@tonic-gate 			continue;
2450Sstevel@tonic-gate 
2460Sstevel@tonic-gate 		(void) memcpy((caddr_t)&speed, buf, sizeof (speed));
2470Sstevel@tonic-gate 
2480Sstevel@tonic-gate 		ret = set_fan_speed(fnodep->fanp, speed);
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate 		if (ret < 0) {
2510Sstevel@tonic-gate 			if (ret == -1 && errno == EBUSY)
2520Sstevel@tonic-gate 				return (PICL_NOTWRITABLE);
2530Sstevel@tonic-gate 			if (ret == -2)
2540Sstevel@tonic-gate 				return (PICL_INVALIDARG);
2550Sstevel@tonic-gate 			break;
2560Sstevel@tonic-gate 		}
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate 
2590Sstevel@tonic-gate 		return (PICL_SUCCESS);
2600Sstevel@tonic-gate 	}
2610Sstevel@tonic-gate 	return (PICL_FAILURE);
2620Sstevel@tonic-gate }
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate /*
2660Sstevel@tonic-gate  * Read function for volatile "Speed" property on "fan" class node
2670Sstevel@tonic-gate  */
2680Sstevel@tonic-gate static int
get_current_speed(ptree_rarg_t * parg,void * buf)2690Sstevel@tonic-gate get_current_speed(ptree_rarg_t *parg, void *buf)
2700Sstevel@tonic-gate {
2710Sstevel@tonic-gate 	fanspeed_t	speed;
2720Sstevel@tonic-gate 	picl_prophdl_t	proph;
2730Sstevel@tonic-gate 	fan_node_t	*fnodep;
2740Sstevel@tonic-gate 	int		i;
2750Sstevel@tonic-gate 
2760Sstevel@tonic-gate 	/*
2770Sstevel@tonic-gate 	 * Locate the fan in our fan_nodes table by matching the
2780Sstevel@tonic-gate 	 * property handle and get fan speed.
2790Sstevel@tonic-gate 	 */
2800Sstevel@tonic-gate 	proph = parg->proph;
2810Sstevel@tonic-gate 	for (i = 0; i < N_FAN_NODES; i++) {
2820Sstevel@tonic-gate 		fnodep = &fan_nodes[i];
2830Sstevel@tonic-gate 		if (fnodep->proph != proph)
2840Sstevel@tonic-gate 			continue;
2850Sstevel@tonic-gate 		if (fnodep->fanp->fd == -1)
2860Sstevel@tonic-gate 			continue;
2870Sstevel@tonic-gate 		if (get_fan_speed(fnodep->fanp, &speed) < 0)
2880Sstevel@tonic-gate 			break;
2890Sstevel@tonic-gate 
2900Sstevel@tonic-gate 		(void) memcpy(buf, (caddr_t)&speed, sizeof (speed));
2910Sstevel@tonic-gate 		return (PICL_SUCCESS);
2920Sstevel@tonic-gate 	}
2930Sstevel@tonic-gate 	return (PICL_FAILURE);
2940Sstevel@tonic-gate }
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate /*
2970Sstevel@tonic-gate  * Create and add the specified regular property
2980Sstevel@tonic-gate  */
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate static int
add_regular_prop(picl_nodehdl_t nodeh,char * name,int type,int access,int size,void * valbuf,picl_prophdl_t * prophp)3010Sstevel@tonic-gate add_regular_prop(picl_nodehdl_t nodeh, char *name, int type, int access,
3020Sstevel@tonic-gate     int size, void *valbuf, picl_prophdl_t *prophp)
3030Sstevel@tonic-gate {
3040Sstevel@tonic-gate 	int			err;
3050Sstevel@tonic-gate 	ptree_propinfo_t	propinfo;
3060Sstevel@tonic-gate 	picl_prophdl_t		proph;
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate 	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
3090Sstevel@tonic-gate 	    type, access, size, name, NULL, NULL);
3100Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
3110Sstevel@tonic-gate 		return (err);
3120Sstevel@tonic-gate 
3130Sstevel@tonic-gate 	err = ptree_create_and_add_prop(nodeh, &propinfo, valbuf, &proph);
3140Sstevel@tonic-gate 	if (err == PICL_SUCCESS && prophp)
3150Sstevel@tonic-gate 		*prophp = proph;
3160Sstevel@tonic-gate 	return (err);
3170Sstevel@tonic-gate }
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate /*
3210Sstevel@tonic-gate  * Create and add the specified volatile property
3220Sstevel@tonic-gate  */
3230Sstevel@tonic-gate 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)3240Sstevel@tonic-gate add_volatile_prop(picl_nodehdl_t nodeh, char *name, int type, int access,
3250Sstevel@tonic-gate     int size, ptree_vol_rdfunc_t *rdfunc, ptree_vol_wrfunc_t *wrfunc,
3260Sstevel@tonic-gate     picl_prophdl_t *prophp)
3270Sstevel@tonic-gate {
3280Sstevel@tonic-gate 	int			err;
3290Sstevel@tonic-gate 	ptree_propinfo_t	propinfo;
3300Sstevel@tonic-gate 	picl_prophdl_t		proph;
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate 	err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
3330Sstevel@tonic-gate 	    type, (access|PICL_VOLATILE), size, name, rdfunc, wrfunc);
3340Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
3350Sstevel@tonic-gate 		return (err);
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate 	err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, &proph);
3380Sstevel@tonic-gate 	if (err == PICL_SUCCESS && prophp)
3390Sstevel@tonic-gate 		*prophp = proph;
3400Sstevel@tonic-gate 	return (err);
3410Sstevel@tonic-gate }
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate /*
3440Sstevel@tonic-gate  * Add temperature threshold properties
3450Sstevel@tonic-gate  */
3460Sstevel@tonic-gate static void
add_sensor_thresh_props(picl_nodehdl_t nodeh,es_sensor_blk_t * sensor_blkp)347323Svenki add_sensor_thresh_props(picl_nodehdl_t nodeh, es_sensor_blk_t *sensor_blkp)
3480Sstevel@tonic-gate {
3490Sstevel@tonic-gate 	picl_prophdl_t	proph;
3500Sstevel@tonic-gate 
3510Sstevel@tonic-gate 	(void) add_regular_prop(nodeh, PICL_PROP_LOW_POWER_OFF,
3520Sstevel@tonic-gate 	    PICL_PTYPE_INT, PICL_READ,
353323Svenki 	    sizeof (sensor_blkp->esb_low_power_off),
354323Svenki 	    &sensor_blkp->esb_low_power_off, &proph);
3550Sstevel@tonic-gate 
3560Sstevel@tonic-gate 	(void) add_regular_prop(nodeh, PICL_PROP_LOW_SHUTDOWN,
3570Sstevel@tonic-gate 	    PICL_PTYPE_INT, PICL_READ,
358323Svenki 	    sizeof (sensor_blkp->esb_low_shutdown),
359323Svenki 	    &sensor_blkp->esb_low_shutdown, &proph);
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate 	(void) add_regular_prop(nodeh, PICL_PROP_LOW_WARNING,
3620Sstevel@tonic-gate 	    PICL_PTYPE_INT, PICL_READ,
363323Svenki 	    sizeof (sensor_blkp->esb_low_warning),
364323Svenki 	    &sensor_blkp->esb_low_warning, &proph);
3650Sstevel@tonic-gate 
3660Sstevel@tonic-gate 	(void) add_regular_prop(nodeh, PICL_PROP_HIGH_WARNING,
3670Sstevel@tonic-gate 	    PICL_PTYPE_INT, PICL_READ,
368323Svenki 	    sizeof (sensor_blkp->esb_high_warning),
369323Svenki 	    &sensor_blkp->esb_high_warning, &proph);
3700Sstevel@tonic-gate 
3710Sstevel@tonic-gate 	(void) add_regular_prop(nodeh, PICL_PROP_HIGH_SHUTDOWN,
3720Sstevel@tonic-gate 	    PICL_PTYPE_INT, PICL_READ,
373323Svenki 	    sizeof (sensor_blkp->esb_high_shutdown),
374323Svenki 	    &sensor_blkp->esb_high_shutdown, &proph);
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate 	(void) add_regular_prop(nodeh, PICL_PROP_HIGH_POWER_OFF,
3770Sstevel@tonic-gate 	    PICL_PTYPE_INT, PICL_READ,
378323Svenki 	    sizeof (sensor_blkp->esb_high_power_off),
379323Svenki 	    &sensor_blkp->esb_high_power_off, &proph);
3800Sstevel@tonic-gate }
3810Sstevel@tonic-gate 
3820Sstevel@tonic-gate 
3830Sstevel@tonic-gate /*
3840Sstevel@tonic-gate  * Go through the sensor_nodes array and create those nodes
3850Sstevel@tonic-gate  * and the Temperature property to report the temperature.
3860Sstevel@tonic-gate  */
3870Sstevel@tonic-gate static int
add_sensor_nodes_and_props()3880Sstevel@tonic-gate add_sensor_nodes_and_props()
3890Sstevel@tonic-gate {
3900Sstevel@tonic-gate 	int		err;
3910Sstevel@tonic-gate 	char		*pname, *nodename, *devfs_path;
3920Sstevel@tonic-gate 	sensor_node_t	*snodep;
3930Sstevel@tonic-gate 	picl_nodehdl_t	nodeh, cnodeh;
3940Sstevel@tonic-gate 	picl_prophdl_t	proph;
3950Sstevel@tonic-gate 	env_sensor_t	*sensorp;
396323Svenki 	es_sensor_blk_t	*sensor_blkp;
3970Sstevel@tonic-gate 	int		i;
3980Sstevel@tonic-gate 
3990Sstevel@tonic-gate 	for (i = 0; i < N_SENSOR_NODES; i++) {
4000Sstevel@tonic-gate 		snodep = &sensor_nodes[i];
4010Sstevel@tonic-gate 		/*
4020Sstevel@tonic-gate 		 * Get the parent nodeh
4030Sstevel@tonic-gate 		 */
4040Sstevel@tonic-gate 		err = ptree_get_node_by_path(snodep->parent_path, &nodeh);
4050Sstevel@tonic-gate 		if (err != PICL_SUCCESS) {
4060Sstevel@tonic-gate 		if (env_debug)
4070Sstevel@tonic-gate 			envd_log(LOG_ERR, "failed to get_node_by_path %s\n",
4080Sstevel@tonic-gate 			    snodep->parent_path);
4090Sstevel@tonic-gate 			continue;
4100Sstevel@tonic-gate 		}
4110Sstevel@tonic-gate 		sensorp = snodep->sensorp;
4120Sstevel@tonic-gate 		if (sensorp == NULL)
4130Sstevel@tonic-gate 			continue;
4140Sstevel@tonic-gate 		if (sensorp->present == B_FALSE)
4150Sstevel@tonic-gate 			continue;
4160Sstevel@tonic-gate 		/*
4170Sstevel@tonic-gate 		 * Create temperature-sensor node
4180Sstevel@tonic-gate 		 */
4190Sstevel@tonic-gate 		nodename = snodep->sensor_name;
4200Sstevel@tonic-gate 		err = ptree_create_and_add_node(nodeh, nodename,
4210Sstevel@tonic-gate 		    PICL_CLASS_TEMPERATURE_SENSOR, &cnodeh);
4220Sstevel@tonic-gate 		if (env_debug)
4230Sstevel@tonic-gate 			envd_log(LOG_ERR,
4240Sstevel@tonic-gate 			    "Creating PICL sensor node '%s' err:%d\n",
4250Sstevel@tonic-gate 			    nodename, err);
4260Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4270Sstevel@tonic-gate 			break;
4280Sstevel@tonic-gate 
4290Sstevel@tonic-gate 		/* save node handle */
4300Sstevel@tonic-gate 		snodep->nodeh = cnodeh;
4310Sstevel@tonic-gate 
4320Sstevel@tonic-gate 		/*
4330Sstevel@tonic-gate 		 * Add "devfs_path" property in child node
4340Sstevel@tonic-gate 		 */
4350Sstevel@tonic-gate 		devfs_path = sensorp->devfs_path;
4360Sstevel@tonic-gate 		pname = PICL_PROP_DEVFS_PATH;
4370Sstevel@tonic-gate 		err = add_regular_prop(cnodeh, pname,
4380Sstevel@tonic-gate 		    PICL_PTYPE_CHARSTRING, PICL_READ,
4390Sstevel@tonic-gate 		    strlen(devfs_path)+1, (void *)devfs_path, &proph);
4400Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4410Sstevel@tonic-gate 			break;
4420Sstevel@tonic-gate 
4430Sstevel@tonic-gate 		/*
4440Sstevel@tonic-gate 		 * Now add volatile "temperature" volatile property
4450Sstevel@tonic-gate 		 * in this "temperature-sensor" class node.
4460Sstevel@tonic-gate 		 */
4470Sstevel@tonic-gate 		pname = PICL_PROP_TEMPERATURE;
4480Sstevel@tonic-gate 		err = add_volatile_prop(cnodeh, pname,
4490Sstevel@tonic-gate 		    PICL_PTYPE_INT, PICL_READ, sizeof (tempr_t),
4500Sstevel@tonic-gate 		    get_current_temp, NULL, &proph);
4510Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
4520Sstevel@tonic-gate 			break;
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate 		/* Save prop handle */
4550Sstevel@tonic-gate 		snodep->proph = proph;
4560Sstevel@tonic-gate 
4570Sstevel@tonic-gate 		/*
4580Sstevel@tonic-gate 		 * Add threshold related properties
4590Sstevel@tonic-gate 		 */
460323Svenki 		sensor_blkp = sensorp->es;
461323Svenki 		if (sensor_blkp != NULL)
462323Svenki 			add_sensor_thresh_props(cnodeh, sensor_blkp);
463323Svenki 	}
4640Sstevel@tonic-gate 
4650Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
4660Sstevel@tonic-gate 		delete_sensor_nodes_and_props();
4670Sstevel@tonic-gate 		if (env_debug)
4680Sstevel@tonic-gate 			envd_log(LOG_INFO,
4690Sstevel@tonic-gate 			    "Can't create prop/node for sensor '%s'\n",
4700Sstevel@tonic-gate 			    nodename);
4710Sstevel@tonic-gate 		return (err);
4720Sstevel@tonic-gate 	}
4730Sstevel@tonic-gate 	return (PICL_SUCCESS);
4740Sstevel@tonic-gate }
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate /*
4770Sstevel@tonic-gate  * Delete all sensor nodes and related properties created by the
4780Sstevel@tonic-gate  * add_sensor_prop() for each sensor node in the PICL tree.
4790Sstevel@tonic-gate  */
4800Sstevel@tonic-gate static void
delete_sensor_nodes_and_props(void)4810Sstevel@tonic-gate delete_sensor_nodes_and_props(void)
4820Sstevel@tonic-gate {
4830Sstevel@tonic-gate 	sensor_node_t	*snodep;
4840Sstevel@tonic-gate 	int		i;
4850Sstevel@tonic-gate 
4860Sstevel@tonic-gate 	/*
4870Sstevel@tonic-gate 	 * Delete/destroy any property created in the sensed device
4880Sstevel@tonic-gate 	 * as well as the sensor node and all properties under it.
4890Sstevel@tonic-gate 	 * Note that deleiing/destroying a node deletes/destroys
4900Sstevel@tonic-gate 	 * all properties within that node.
4910Sstevel@tonic-gate 	 */
4920Sstevel@tonic-gate 
4930Sstevel@tonic-gate 	for (i = 0; i < N_SENSOR_NODES; i++) {
4940Sstevel@tonic-gate 		snodep = &sensor_nodes[i];
4950Sstevel@tonic-gate 		if (snodep->nodeh != NULL) {
4960Sstevel@tonic-gate 			/* delete node and all properties under it */
4970Sstevel@tonic-gate 			(void) ptree_delete_node(snodep->nodeh);
4980Sstevel@tonic-gate 			(void) ptree_destroy_node(snodep->nodeh);
4990Sstevel@tonic-gate 			snodep->nodeh = NULL;
5000Sstevel@tonic-gate 			snodep->proph = NULL;
5010Sstevel@tonic-gate 		}
5020Sstevel@tonic-gate 	}
5030Sstevel@tonic-gate }
5040Sstevel@tonic-gate 
5050Sstevel@tonic-gate /*
5060Sstevel@tonic-gate  * Go through the disk_nodes array and create those nodes
5070Sstevel@tonic-gate  * and the Temperature property to report the temperature.
5080Sstevel@tonic-gate  */
5090Sstevel@tonic-gate static int
add_disk_nodes_and_props()5100Sstevel@tonic-gate add_disk_nodes_and_props()
5110Sstevel@tonic-gate {
5120Sstevel@tonic-gate 	int		err;
5130Sstevel@tonic-gate 	char		*pname, *nodename, *devfs_path;
5140Sstevel@tonic-gate 	disk_node_t	*dnodep;
5150Sstevel@tonic-gate 	picl_nodehdl_t	nodeh, cnodeh;
5160Sstevel@tonic-gate 	picl_prophdl_t	proph;
5170Sstevel@tonic-gate 	env_disk_t	*diskp;
5180Sstevel@tonic-gate 	int		i;
5190Sstevel@tonic-gate 
5200Sstevel@tonic-gate 	for (i = 0; i < N_DISK_NODES; i++) {
5210Sstevel@tonic-gate 		if (env_debug)
5220Sstevel@tonic-gate 			envd_log(LOG_ERR, "adding disk nodes...\n");
5230Sstevel@tonic-gate 		dnodep = &disk_nodes[i];
5240Sstevel@tonic-gate 		/*
5250Sstevel@tonic-gate 		 * Get the parent nodeh
5260Sstevel@tonic-gate 		 */
5270Sstevel@tonic-gate 		err = ptree_get_node_by_path(dnodep->parent_path, &nodeh);
5280Sstevel@tonic-gate 		if (err != PICL_SUCCESS) {
5290Sstevel@tonic-gate 			if (env_debug)
5300Sstevel@tonic-gate 				envd_log(LOG_ERR,
5310Sstevel@tonic-gate 				    "failed to get node for path %s\n",
5320Sstevel@tonic-gate 				    dnodep->parent_path);
5330Sstevel@tonic-gate 
5340Sstevel@tonic-gate 			err = PICL_SUCCESS;
5350Sstevel@tonic-gate 			continue;
5360Sstevel@tonic-gate 		}
5370Sstevel@tonic-gate 		diskp = dnodep->diskp;
5380Sstevel@tonic-gate 		if (diskp == NULL)
5390Sstevel@tonic-gate 			continue;
5400Sstevel@tonic-gate 		if (diskp->present == B_FALSE)
5410Sstevel@tonic-gate 			continue;
5420Sstevel@tonic-gate 		/*
5430Sstevel@tonic-gate 		 * Create temperature-sensor node
5440Sstevel@tonic-gate 		 */
5450Sstevel@tonic-gate 		nodename = dnodep->disk_name;
5460Sstevel@tonic-gate 		err = ptree_create_and_add_node(nodeh, nodename,
5470Sstevel@tonic-gate 		    PICL_CLASS_TEMPERATURE_SENSOR, &cnodeh);
5480Sstevel@tonic-gate 		if (env_debug)
5490Sstevel@tonic-gate 			envd_log(LOG_ERR,
5500Sstevel@tonic-gate 			    "Creating PICL disk node '%s' err:%d\n",
5510Sstevel@tonic-gate 			    nodename, err);
5520Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
5530Sstevel@tonic-gate 			break;
5540Sstevel@tonic-gate 
5550Sstevel@tonic-gate 		/* save node handle */
5560Sstevel@tonic-gate 		dnodep->nodeh = cnodeh;
5570Sstevel@tonic-gate 
5580Sstevel@tonic-gate 		/*
5590Sstevel@tonic-gate 		 * Add "devfs_path" property in child node
5600Sstevel@tonic-gate 		 */
5610Sstevel@tonic-gate 		devfs_path = diskp->devfs_path;
5620Sstevel@tonic-gate 		pname = PICL_PROP_DEVFS_PATH;
5630Sstevel@tonic-gate 		err = add_regular_prop(cnodeh, pname,
5640Sstevel@tonic-gate 		    PICL_PTYPE_CHARSTRING, PICL_READ,
5650Sstevel@tonic-gate 		    strlen(devfs_path)+1, (void *)devfs_path, &proph);
5660Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
5670Sstevel@tonic-gate 			break;
5680Sstevel@tonic-gate 
5690Sstevel@tonic-gate 		/*
5700Sstevel@tonic-gate 		 * Now add volatile "temperature" volatile property
5710Sstevel@tonic-gate 		 * in this "temperature-sensor" class node.
5720Sstevel@tonic-gate 		 */
5730Sstevel@tonic-gate 		pname = PICL_PROP_TEMPERATURE;
5740Sstevel@tonic-gate 		err = add_volatile_prop(cnodeh, pname,
5750Sstevel@tonic-gate 		    PICL_PTYPE_INT, PICL_READ, sizeof (tempr_t),
5760Sstevel@tonic-gate 		    get_disk_temp, NULL, &proph);
5770Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
5780Sstevel@tonic-gate 			break;
5790Sstevel@tonic-gate 
5800Sstevel@tonic-gate 		/* Save prop handle */
5810Sstevel@tonic-gate 		dnodep->proph = proph;
5820Sstevel@tonic-gate 
5830Sstevel@tonic-gate 		/*
5840Sstevel@tonic-gate 		 * Add threshold related properties
5850Sstevel@tonic-gate 		 */
5860Sstevel@tonic-gate 
5870Sstevel@tonic-gate 		(void) add_regular_prop(cnodeh, PICL_PROP_LOW_SHUTDOWN,
5880Sstevel@tonic-gate 		    PICL_PTYPE_INT, PICL_READ,
5890Sstevel@tonic-gate 		    sizeof (diskp->low_shutdown),
5900Sstevel@tonic-gate 		    (void *)&(diskp->low_shutdown), &proph);
5910Sstevel@tonic-gate 
5920Sstevel@tonic-gate 		(void) add_regular_prop(cnodeh, PICL_PROP_LOW_WARNING,
5930Sstevel@tonic-gate 		    PICL_PTYPE_INT, PICL_READ,
5940Sstevel@tonic-gate 		    sizeof (diskp->low_warning),
5950Sstevel@tonic-gate 		    (void *)&(diskp->low_warning), &proph);
5960Sstevel@tonic-gate 
5970Sstevel@tonic-gate 		(void) add_regular_prop(cnodeh, PICL_PROP_HIGH_WARNING,
5980Sstevel@tonic-gate 		    PICL_PTYPE_INT, PICL_READ,
5990Sstevel@tonic-gate 		    sizeof (diskp->high_warning),
6000Sstevel@tonic-gate 		    (void *)&(diskp->high_warning), &proph);
6010Sstevel@tonic-gate 
6020Sstevel@tonic-gate 		(void) add_regular_prop(cnodeh, PICL_PROP_HIGH_SHUTDOWN,
6030Sstevel@tonic-gate 		    PICL_PTYPE_INT, PICL_READ,
6040Sstevel@tonic-gate 		    sizeof (diskp->high_shutdown),
6050Sstevel@tonic-gate 		    (void *)&(diskp->high_shutdown), &proph);
6060Sstevel@tonic-gate 
6070Sstevel@tonic-gate 	}
6080Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
6090Sstevel@tonic-gate 		delete_disk_nodes_and_props();
6100Sstevel@tonic-gate 		if (env_debug)
6110Sstevel@tonic-gate 			envd_log(LOG_INFO,
6120Sstevel@tonic-gate 			    "Can't create prop/node for disk '%s'\n",
6130Sstevel@tonic-gate 			    nodename);
6140Sstevel@tonic-gate 		return (err);
6150Sstevel@tonic-gate 	}
6160Sstevel@tonic-gate 	return (PICL_SUCCESS);
6170Sstevel@tonic-gate }
6180Sstevel@tonic-gate 
6190Sstevel@tonic-gate /*
6200Sstevel@tonic-gate  * Delete all disk nodes and related properties created by the
6210Sstevel@tonic-gate  * add_disk_props() for each disk node in the PICL tree.
6220Sstevel@tonic-gate  */
6230Sstevel@tonic-gate static void
delete_disk_nodes_and_props(void)6240Sstevel@tonic-gate delete_disk_nodes_and_props(void)
6250Sstevel@tonic-gate {
6260Sstevel@tonic-gate 	disk_node_t	*dnodep;
6270Sstevel@tonic-gate 	int		i;
6280Sstevel@tonic-gate 
6290Sstevel@tonic-gate 	/*
6300Sstevel@tonic-gate 	 * Delete/destroy disk node and all properties under it.
6310Sstevel@tonic-gate 	 * Note that deleting/destroying a node deletes/destroys
6320Sstevel@tonic-gate 	 * all properties within that node.
6330Sstevel@tonic-gate 	 */
6340Sstevel@tonic-gate 
6350Sstevel@tonic-gate 	for (i = 0; i < N_DISK_NODES; i++) {
6360Sstevel@tonic-gate 		dnodep = &disk_nodes[i];
6370Sstevel@tonic-gate 		if (dnodep->nodeh != NULL) {
6380Sstevel@tonic-gate 			(void) ptree_delete_node(dnodep->nodeh);
6390Sstevel@tonic-gate 			(void) ptree_destroy_node(dnodep->nodeh);
6400Sstevel@tonic-gate 			dnodep->nodeh = NULL;
6410Sstevel@tonic-gate 			dnodep->proph = NULL;
6420Sstevel@tonic-gate 		}
6430Sstevel@tonic-gate 	}
6440Sstevel@tonic-gate }
6450Sstevel@tonic-gate 
6460Sstevel@tonic-gate /*
6470Sstevel@tonic-gate  * For each entry in fan_nodes[] array, do the following:
6480Sstevel@tonic-gate  *	- Create specified "fan" class node.
6490Sstevel@tonic-gate  *	- Create "Speed" volatile propery under "fan" class node.
6500Sstevel@tonic-gate  *	- Create "SpeedUnit" property under "fan" class node.
6510Sstevel@tonic-gate  */
6520Sstevel@tonic-gate static int
add_fan_nodes_and_props()6530Sstevel@tonic-gate add_fan_nodes_and_props()
6540Sstevel@tonic-gate {
6550Sstevel@tonic-gate 	int		err = PICL_FAILURE;
6560Sstevel@tonic-gate 	char		*pname, *nodename, *devfs_path;
6570Sstevel@tonic-gate 	env_fan_t	*fanp;
6580Sstevel@tonic-gate 	fan_node_t	*fnodep;
6590Sstevel@tonic-gate 	picl_nodehdl_t	nodeh, cnodeh;
6600Sstevel@tonic-gate 	picl_prophdl_t	proph;
6610Sstevel@tonic-gate 	int		i;
6620Sstevel@tonic-gate 
6630Sstevel@tonic-gate 	for (i = 0; i < N_FAN_NODES; i++) {
6640Sstevel@tonic-gate 		/*
6650Sstevel@tonic-gate 		 * Add various fan nodes and properties
6660Sstevel@tonic-gate 		 */
6670Sstevel@tonic-gate 		fnodep = &fan_nodes[i];
6680Sstevel@tonic-gate 		if (fnodep == NULL)
6690Sstevel@tonic-gate 			continue;
6700Sstevel@tonic-gate 		if (fnodep->fanp == NULL)
6710Sstevel@tonic-gate 			continue;
6720Sstevel@tonic-gate 		if (fnodep->fanp->present == B_FALSE)
6730Sstevel@tonic-gate 			continue;
6740Sstevel@tonic-gate 		/*
6750Sstevel@tonic-gate 		 * get parent nodeh
6760Sstevel@tonic-gate 		 */
6770Sstevel@tonic-gate 		err = ptree_get_node_by_path(fnodep->parent_path, &nodeh);
6780Sstevel@tonic-gate 		if (err != PICL_SUCCESS) {
6790Sstevel@tonic-gate 			if (env_debug)
6800Sstevel@tonic-gate 				envd_log(LOG_ERR,
6810Sstevel@tonic-gate 		"node for %s NOT FOUND.\n", fnodep->parent_path);
6820Sstevel@tonic-gate 			err = PICL_SUCCESS;
6830Sstevel@tonic-gate 			continue;
6840Sstevel@tonic-gate 		}
6850Sstevel@tonic-gate 		/*
6860Sstevel@tonic-gate 		 * Create "fan" class node and save node handle
6870Sstevel@tonic-gate 		 */
6880Sstevel@tonic-gate 		nodename = fnodep->fan_name;
6890Sstevel@tonic-gate 		err = ptree_create_and_add_node(nodeh, nodename,
6900Sstevel@tonic-gate 		    PICL_CLASS_FAN, &cnodeh);
6910Sstevel@tonic-gate 		if (env_debug)
6920Sstevel@tonic-gate 			envd_log(LOG_ERR,
6930Sstevel@tonic-gate 			    "Creating PICL fan node '%s' err:%d\n",
6940Sstevel@tonic-gate 			    nodename, err);
6950Sstevel@tonic-gate 
6960Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
6970Sstevel@tonic-gate 			break;
6980Sstevel@tonic-gate 		fnodep->nodeh = cnodeh;
6990Sstevel@tonic-gate 
7000Sstevel@tonic-gate 		/*
7010Sstevel@tonic-gate 		 * Add "devfs_path" property in child node
7020Sstevel@tonic-gate 		 */
7030Sstevel@tonic-gate 		fanp = fnodep->fanp;
7040Sstevel@tonic-gate 		devfs_path  = fanp->devfs_path;
7050Sstevel@tonic-gate 		pname = PICL_PROP_DEVFS_PATH;
7060Sstevel@tonic-gate 		err = add_regular_prop(cnodeh, pname,
7070Sstevel@tonic-gate 		    PICL_PTYPE_CHARSTRING, PICL_READ,
7080Sstevel@tonic-gate 		    strlen(devfs_path)+1, (void *)devfs_path, &proph);
7090Sstevel@tonic-gate 
7100Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
7110Sstevel@tonic-gate 
7120Sstevel@tonic-gate 			break;
7130Sstevel@tonic-gate 
7140Sstevel@tonic-gate 		/*
7150Sstevel@tonic-gate 		 * Add "Speed" volatile property in this "fan"
7160Sstevel@tonic-gate 		 * class node and save prop handle.
7170Sstevel@tonic-gate 		 */
7180Sstevel@tonic-gate 		pname = PICL_PROP_FAN_SPEED;
7190Sstevel@tonic-gate 
7200Sstevel@tonic-gate 		err = add_volatile_prop(cnodeh, pname, PICL_PTYPE_INT,
7210Sstevel@tonic-gate 		    PICL_READ|PICL_WRITE, sizeof (fanspeed_t),
7220Sstevel@tonic-gate 		    get_current_speed, set_current_speed, &proph);
7230Sstevel@tonic-gate 
7240Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
7250Sstevel@tonic-gate 			break;
7260Sstevel@tonic-gate 		fnodep->proph = proph;
7270Sstevel@tonic-gate 
7280Sstevel@tonic-gate 		/*
7290Sstevel@tonic-gate 		 * Add other "fan" class properties
7300Sstevel@tonic-gate 		 */
7310Sstevel@tonic-gate 		pname = PICL_PROP_FAN_SPEED_UNIT;
7320Sstevel@tonic-gate 		err = add_regular_prop(cnodeh, pname,
7330Sstevel@tonic-gate 		    PICL_PTYPE_CHARSTRING, PICL_READ,
7340Sstevel@tonic-gate 		    strlen(fnodep->speed_unit)+1,
7350Sstevel@tonic-gate 		    (void *)fnodep->speed_unit, &proph);
7360Sstevel@tonic-gate 
7370Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
7380Sstevel@tonic-gate 			break;
7390Sstevel@tonic-gate 
7400Sstevel@tonic-gate 		pname = PICL_PROP_LOW_WARNING;
7410Sstevel@tonic-gate 		err = add_regular_prop(cnodeh, pname,
7420Sstevel@tonic-gate 		    PICL_PTYPE_INT, PICL_READ,
7430Sstevel@tonic-gate 		    sizeof (fanspeed_t),
7440Sstevel@tonic-gate 		    &(fnodep->fanp->speed_min), &proph);
7450Sstevel@tonic-gate 
7460Sstevel@tonic-gate 		if (err != PICL_SUCCESS)
7470Sstevel@tonic-gate 			break;
7480Sstevel@tonic-gate 	}
7490Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
7500Sstevel@tonic-gate 		delete_fan_nodes_and_props();
7510Sstevel@tonic-gate 		return (err);
7520Sstevel@tonic-gate 	}
7530Sstevel@tonic-gate 	return (PICL_SUCCESS);
7540Sstevel@tonic-gate }
7550Sstevel@tonic-gate 
7560Sstevel@tonic-gate 
7570Sstevel@tonic-gate /*
7580Sstevel@tonic-gate  * Delete all fan nodes and related properties created by the
7590Sstevel@tonic-gate  * add_fan_props() for each fan node in the PICL tree.
7600Sstevel@tonic-gate  */
7610Sstevel@tonic-gate static void
delete_fan_nodes_and_props(void)7620Sstevel@tonic-gate delete_fan_nodes_and_props(void)
7630Sstevel@tonic-gate {
7640Sstevel@tonic-gate 	fan_node_t	*fnodep;
7650Sstevel@tonic-gate 	int		i;
7660Sstevel@tonic-gate 
7670Sstevel@tonic-gate 	/*
7680Sstevel@tonic-gate 	 * Delete/destroy fan node and all properties under it.
7690Sstevel@tonic-gate 	 * Note that deleting/destroying a node deletes/destroys
7700Sstevel@tonic-gate 	 * all properties within that node.
7710Sstevel@tonic-gate 	 */
7720Sstevel@tonic-gate 
7730Sstevel@tonic-gate 	for (i = 0; i < N_FAN_NODES; i++) {
7740Sstevel@tonic-gate 		fnodep = &fan_nodes[i];
7750Sstevel@tonic-gate 		if (fnodep->nodeh != NULL) {
7760Sstevel@tonic-gate 			(void) ptree_delete_node(fnodep->nodeh);
7770Sstevel@tonic-gate 			(void) ptree_destroy_node(fnodep->nodeh);
7780Sstevel@tonic-gate 			fnodep->nodeh = NULL;
7790Sstevel@tonic-gate 		}
7800Sstevel@tonic-gate 	}
7810Sstevel@tonic-gate }
7820Sstevel@tonic-gate /*
7830Sstevel@tonic-gate  * Tuneables publishing functions
7840Sstevel@tonic-gate  */
7850Sstevel@tonic-gate static int
copy_persistent_tuneable(env_tuneable_t * tune,char * buf)7860Sstevel@tonic-gate copy_persistent_tuneable(env_tuneable_t *tune, char *buf)
7870Sstevel@tonic-gate {
7880Sstevel@tonic-gate 
7890Sstevel@tonic-gate 	switch (tune->type) {
7900Sstevel@tonic-gate 	case PICL_PTYPE_INT : {
7910Sstevel@tonic-gate 		(void) memcpy((int *)tune->value,
7920Sstevel@tonic-gate 		    buf, tune->nbytes);
7930Sstevel@tonic-gate 		break;
7940Sstevel@tonic-gate 	}
7950Sstevel@tonic-gate 	case PICL_PTYPE_CHARSTRING : {
7960Sstevel@tonic-gate 		(void) memcpy((caddr_t)tune->value,
7970Sstevel@tonic-gate 		    buf, tune->nbytes);
7980Sstevel@tonic-gate 		break;
7990Sstevel@tonic-gate 	}
8000Sstevel@tonic-gate 	default	: {
8010Sstevel@tonic-gate 		return (PICL_FAILURE);
8020Sstevel@tonic-gate 	}
8030Sstevel@tonic-gate 	}
8040Sstevel@tonic-gate 	return (PICL_SUCCESS);
8050Sstevel@tonic-gate }
8060Sstevel@tonic-gate 
8070Sstevel@tonic-gate static void
env_parse_tunables(picl_nodehdl_t rooth)8080Sstevel@tonic-gate env_parse_tunables(picl_nodehdl_t rooth)
8090Sstevel@tonic-gate {
8100Sstevel@tonic-gate 	char	nmbuf[SYS_NMLN];
8110Sstevel@tonic-gate 	char    pname[PATH_MAX];
8120Sstevel@tonic-gate 
8130Sstevel@tonic-gate 	if (sysinfo(SI_PLATFORM, nmbuf, sizeof (nmbuf)) != -1) {
8140Sstevel@tonic-gate 		(void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
8150Sstevel@tonic-gate 		(void) strlcat(pname, TUNABLE_CONF_FILE, PATH_MAX);
8160Sstevel@tonic-gate 		if (access(pname, R_OK) == 0) {
8170Sstevel@tonic-gate 			(void) picld_pluginutil_parse_config_file(rooth, pname);
8180Sstevel@tonic-gate 			return;
8190Sstevel@tonic-gate 		}
8200Sstevel@tonic-gate 	}
8210Sstevel@tonic-gate }
8220Sstevel@tonic-gate 
8230Sstevel@tonic-gate int
env_picl_setup_tuneables(void)8240Sstevel@tonic-gate env_picl_setup_tuneables(void)
8250Sstevel@tonic-gate {
8260Sstevel@tonic-gate 	int		err;
8270Sstevel@tonic-gate 	int		i;
8280Sstevel@tonic-gate 	picl_nodehdl_t	nodeh;
8290Sstevel@tonic-gate 	picl_nodehdl_t	rooth;
8300Sstevel@tonic-gate 	picl_prophdl_t	proph;
8310Sstevel@tonic-gate 	env_tuneable_t	*tuneablep;
8320Sstevel@tonic-gate 	char		read_buf[BUFSIZ];
8330Sstevel@tonic-gate 
8340Sstevel@tonic-gate 	if (ptree_get_root(&rooth) != PICL_SUCCESS) {
8350Sstevel@tonic-gate 		return (PICL_FAILURE);
8360Sstevel@tonic-gate 	}
8370Sstevel@tonic-gate 	err = ptree_create_and_add_node(rooth, PICL_PLUGINS_NODE,
8380Sstevel@tonic-gate 	    PICL_CLASS_PICL, &nodeh);
8390Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
8400Sstevel@tonic-gate 		return (PICL_FAILURE);
8410Sstevel@tonic-gate 	err = ptree_create_and_add_node(nodeh, PICL_ENVIRONMENTAL_NODE,
8420Sstevel@tonic-gate 	    PICL_CLASS_PICL, &nodeh);
8430Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
8440Sstevel@tonic-gate 		return (PICL_FAILURE);
8450Sstevel@tonic-gate 	}
8460Sstevel@tonic-gate 
8470Sstevel@tonic-gate 	/*
8480Sstevel@tonic-gate 	 * Parse the conf file
8490Sstevel@tonic-gate 	 */
8500Sstevel@tonic-gate 	if (env_debug)
8510Sstevel@tonic-gate 		envd_log(LOG_ERR, "parsing tuneables...\n");
8520Sstevel@tonic-gate 	env_parse_tunables(rooth);
8530Sstevel@tonic-gate 	for (i = 0; i < ntuneables; i++) {
8540Sstevel@tonic-gate 		if (env_debug)
8550Sstevel@tonic-gate 			envd_log(LOG_ERR, "tuneable %d being added\n", i);
8560Sstevel@tonic-gate 		tuneablep = &tuneables[i];
8570Sstevel@tonic-gate 		err = ptree_get_propval_by_name(nodeh, tuneablep->name,
8580Sstevel@tonic-gate 		    read_buf, tuneablep->nbytes);
8590Sstevel@tonic-gate 
8600Sstevel@tonic-gate 		if (err != PICL_SUCCESS) {
8610Sstevel@tonic-gate 			/*
8620Sstevel@tonic-gate 			 * Add volitle functions to environmental node
8630Sstevel@tonic-gate 			 */
8640Sstevel@tonic-gate 			err = add_volatile_prop(nodeh, tuneablep->name,
8650Sstevel@tonic-gate 			    tuneablep->type,
8660Sstevel@tonic-gate 			    PICL_READ|PICL_WRITE, tuneablep->nbytes,
8670Sstevel@tonic-gate 			    tuneablep->rfunc,
8680Sstevel@tonic-gate 			    tuneablep->wfunc, &proph);
8690Sstevel@tonic-gate 
8700Sstevel@tonic-gate 			tuneablep->proph = proph;
8710Sstevel@tonic-gate 		} else {
8720Sstevel@tonic-gate 			/*
8730Sstevel@tonic-gate 			 * property is persistent
8740Sstevel@tonic-gate 			 */
8750Sstevel@tonic-gate 			(void) copy_persistent_tuneable(tuneablep,
8760Sstevel@tonic-gate 			    read_buf);
8770Sstevel@tonic-gate 		}
8780Sstevel@tonic-gate 	}
8790Sstevel@tonic-gate 
8800Sstevel@tonic-gate 	return	(PICL_SUCCESS);
8810Sstevel@tonic-gate }
8820Sstevel@tonic-gate 
8830Sstevel@tonic-gate /*
8840Sstevel@tonic-gate  * Find the ENVMODEL_CONF_FILE file.
8850Sstevel@tonic-gate  */
8860Sstevel@tonic-gate static int
get_envmodel_conf_file(char * outfilename)8870Sstevel@tonic-gate get_envmodel_conf_file(char *outfilename)
8880Sstevel@tonic-gate {
8890Sstevel@tonic-gate 	char	nmbuf[SYS_NMLN];
8900Sstevel@tonic-gate 	char    pname[PATH_MAX];
8910Sstevel@tonic-gate 
8920Sstevel@tonic-gate 	if (sysinfo(SI_PLATFORM, nmbuf, sizeof (nmbuf)) != -1) {
8930Sstevel@tonic-gate 		(void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
8940Sstevel@tonic-gate 		(void) strlcat(pname, ENV_CONF_FILE, PATH_MAX);
8950Sstevel@tonic-gate 		if (access(pname, R_OK) == 0) {
8960Sstevel@tonic-gate 			(void) strlcpy(outfilename, pname, PATH_MAX);
8970Sstevel@tonic-gate 			return (0);
8980Sstevel@tonic-gate 		}
8990Sstevel@tonic-gate 	}
9000Sstevel@tonic-gate 
9010Sstevel@tonic-gate 	if (sysinfo(SI_MACHINE, nmbuf, sizeof (nmbuf)) != -1) {
9020Sstevel@tonic-gate 		(void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
9030Sstevel@tonic-gate 		(void) strlcat(pname, ENV_CONF_FILE, PATH_MAX);
9040Sstevel@tonic-gate 		if (access(pname, R_OK) == 0) {
9050Sstevel@tonic-gate 			(void) strlcpy(outfilename, pname, PATH_MAX);
9060Sstevel@tonic-gate 			return (0);
9070Sstevel@tonic-gate 		}
9080Sstevel@tonic-gate 	}
9090Sstevel@tonic-gate 
9100Sstevel@tonic-gate 	(void) snprintf(pname, PATH_MAX, "%s/%s", PICLD_COMMON_PLUGIN_DIR,
9110Sstevel@tonic-gate 	    ENV_CONF_FILE);
9120Sstevel@tonic-gate 
9130Sstevel@tonic-gate 	if (access(pname, R_OK) == 0) {
9140Sstevel@tonic-gate 		(void) strlcpy(outfilename, pname, PATH_MAX);
9150Sstevel@tonic-gate 		return (0);
9160Sstevel@tonic-gate 	}
9170Sstevel@tonic-gate 
9180Sstevel@tonic-gate 	return (-1);
9190Sstevel@tonic-gate }
9200Sstevel@tonic-gate 
9210Sstevel@tonic-gate /* Delete all sensor/fan nodes and any properties created by this plugin */
9220Sstevel@tonic-gate void
env_picl_destroy(void)9230Sstevel@tonic-gate env_picl_destroy(void)
9240Sstevel@tonic-gate {
9250Sstevel@tonic-gate 	delete_fan_nodes_and_props();
9260Sstevel@tonic-gate 	delete_sensor_nodes_and_props();
9270Sstevel@tonic-gate 	delete_disk_nodes_and_props();
9280Sstevel@tonic-gate }
9290Sstevel@tonic-gate 
9300Sstevel@tonic-gate void
env_picl_setup(void)9310Sstevel@tonic-gate env_picl_setup(void)
9320Sstevel@tonic-gate {
9330Sstevel@tonic-gate 	int		err, sensor_err, fan_err, disk_err;
9340Sstevel@tonic-gate 	sensor_node_t	*snodep;
9350Sstevel@tonic-gate 	fan_node_t	*fnodep;
9360Sstevel@tonic-gate 	disk_node_t	*dnodep;
9370Sstevel@tonic-gate 	picl_nodehdl_t	plath;
9380Sstevel@tonic-gate 	char		fullfilename[PATH_MAX];
9390Sstevel@tonic-gate 	picl_nodehdl_t  rooth;
9400Sstevel@tonic-gate 	int		i;
9410Sstevel@tonic-gate 
9420Sstevel@tonic-gate 
9430Sstevel@tonic-gate 	/*
9440Sstevel@tonic-gate 	 * Initialize sensorp and other fields in the sensor_nodes[] array
9450Sstevel@tonic-gate 	 */
9460Sstevel@tonic-gate 
9470Sstevel@tonic-gate 	for (i = 0; i < N_SENSOR_NODES; i++) {
9480Sstevel@tonic-gate 		snodep = &sensor_nodes[i];
9490Sstevel@tonic-gate 		snodep->sensorp = sensor_lookup(snodep->sensor_name);
9500Sstevel@tonic-gate 		snodep->nodeh = NULL;
9510Sstevel@tonic-gate 		snodep->proph = NULL;
9520Sstevel@tonic-gate 		snodep->target_proph = NULL;
9530Sstevel@tonic-gate 	}
9540Sstevel@tonic-gate 
9550Sstevel@tonic-gate 	/*
9560Sstevel@tonic-gate 	 * Initialize fanp and other fields in the fan_nodes[] array
9570Sstevel@tonic-gate 	 */
9580Sstevel@tonic-gate 	for (i = 0; i < N_FAN_NODES; i++) {
9590Sstevel@tonic-gate 		fnodep = &fan_nodes[i];
9600Sstevel@tonic-gate 		fnodep->fanp = fan_lookup(fnodep->fan_name);
9610Sstevel@tonic-gate 		fnodep->nodeh = NULL;
9620Sstevel@tonic-gate 		fnodep->proph = NULL;
9630Sstevel@tonic-gate 	}
9640Sstevel@tonic-gate 
9650Sstevel@tonic-gate 	/*
9660Sstevel@tonic-gate 	 * Initialize diskp and other fields in the disk_nodes[] array
9670Sstevel@tonic-gate 	 */
9680Sstevel@tonic-gate 	for (i = 0; i < N_DISK_NODES; i++) {
9690Sstevel@tonic-gate 		dnodep = &disk_nodes[i];
9700Sstevel@tonic-gate 		dnodep->diskp = disk_lookup(dnodep->disk_name);
9710Sstevel@tonic-gate 		dnodep->nodeh = NULL;
9720Sstevel@tonic-gate 		dnodep->proph = NULL;
9730Sstevel@tonic-gate 	}
9740Sstevel@tonic-gate 
9750Sstevel@tonic-gate 	/*
9760Sstevel@tonic-gate 	 * Get platform handle and populate PICL tree with environmental
9770Sstevel@tonic-gate 	 * nodes and properties
9780Sstevel@tonic-gate 	 */
9790Sstevel@tonic-gate 	err = ptree_get_node_by_path("/platform", &plath);
9800Sstevel@tonic-gate 
9810Sstevel@tonic-gate 	if (err == PICL_SUCCESS) {
9820Sstevel@tonic-gate 		sensor_err = add_sensor_nodes_and_props();
9830Sstevel@tonic-gate 		fan_err = add_fan_nodes_and_props();
984138Svenki 		if (disk_temp_monitor)
9850Sstevel@tonic-gate 			disk_err = add_disk_nodes_and_props();
9860Sstevel@tonic-gate 	}
9870Sstevel@tonic-gate 
9880Sstevel@tonic-gate 	/*
9890Sstevel@tonic-gate 	 * We can safely call delete_xxx_nodes_and_props even
9900Sstevel@tonic-gate 	 * if nodes were not added.
9910Sstevel@tonic-gate 	 */
9920Sstevel@tonic-gate 
9930Sstevel@tonic-gate 	if (err != PICL_SUCCESS) {
9940Sstevel@tonic-gate 		if (fan_err != PICL_SUCCESS)
9950Sstevel@tonic-gate 			delete_fan_nodes_and_props();
9960Sstevel@tonic-gate 		if (disk_err != PICL_SUCCESS)
9970Sstevel@tonic-gate 			delete_disk_nodes_and_props();
9980Sstevel@tonic-gate 		if (sensor_err != PICL_SUCCESS)
9990Sstevel@tonic-gate 			delete_sensor_nodes_and_props();
10000Sstevel@tonic-gate 
10010Sstevel@tonic-gate 	envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
10020Sstevel@tonic-gate 		return;
10030Sstevel@tonic-gate 	}
10040Sstevel@tonic-gate 	if (env_debug)
10050Sstevel@tonic-gate 		envd_log(LOG_ERR, "parsing the envmodel.conf file...\n");
10060Sstevel@tonic-gate 
10070Sstevel@tonic-gate 	/*
10080Sstevel@tonic-gate 	 * Parse the envmodel.conf file and populate the PICL tree
10090Sstevel@tonic-gate 	 */
10100Sstevel@tonic-gate 	if (get_envmodel_conf_file(fullfilename) < 0)
10110Sstevel@tonic-gate 		envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
10120Sstevel@tonic-gate 	if (ptree_get_root(&rooth) != PICL_SUCCESS)
10130Sstevel@tonic-gate 		envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
10140Sstevel@tonic-gate 	err = picld_pluginutil_parse_config_file(rooth, fullfilename);
10150Sstevel@tonic-gate 
10160Sstevel@tonic-gate 	if (err != PICL_SUCCESS)
10170Sstevel@tonic-gate 		envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
10180Sstevel@tonic-gate }
1019