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 * This file contains code for setting up environmental related nodes
31 * and properties in the PICL tree.
47 #include <sys/systeminfo.h>
50 #include <picld_pluginutil.h>
52 #include <sys/utsname.h>
53 #include <sys/systeminfo.h>
58 * Volatile property read/write function typedef
60 typedef int ptree_vol_rdfunc_t(ptree_rarg_t
*parg
, void *buf
);
61 typedef int ptree_vol_wrfunc_t(ptree_warg_t
*parg
, const void *buf
);
64 extern sensor_ctrl_blk_t sensor_ctrl
[];
65 extern fan_ctrl_blk_t fan_ctrl
[];
66 extern env_tuneable_t tuneables
[];
67 extern int ntuneables
;
69 #define PROP_FAN_SPEED_UNIT_VALUE "rpm"
72 * Sensor node data structure
75 char *parent_path
; /* parent path */
76 char *sensor_name
; /* sensor name */
77 env_sensor_t
*sensorp
; /* sensor info */
78 picl_nodehdl_t nodeh
; /* sensor node handle */
79 picl_prophdl_t proph
; /* "Temperature" property handle */
80 picl_prophdl_t target_proph
; /* "TargetTemp" property handle */
87 static sensor_node_t sensor_nodes
[] = {
88 {"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c",
92 {"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c",
96 {"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c",
100 #define NSENSORS (sizeof (sensor_nodes)/sizeof (sensor_nodes[0]))
104 * Fan node data structure
107 char *parent_path
; /* parent node path */
108 char *fan_name
; /* fan name */
109 env_fan_t
*fanp
; /* fan information */
110 char *speed_unit
; /* speed unit string */
111 picl_nodehdl_t nodeh
; /* "fan" node handle */
112 picl_prophdl_t proph
; /* "Speed" property handle */
119 static fan_node_t fan_nodes
[] = {
120 {"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c",
121 ENV_CPU_FAN
, NULL
, PROP_FAN_SPEED_UNIT_VALUE
, NULL
, NULL
},
123 {"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c",
124 ENV_SYSTEM_INTAKE_FAN
, NULL
, PROP_FAN_SPEED_UNIT_VALUE
, NULL
, NULL
},
126 {"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c",
127 ENV_SYSTEM_OUT_FAN
, NULL
, PROP_FAN_SPEED_UNIT_VALUE
, NULL
, NULL
}
129 #define NFANS (sizeof (fan_nodes)/sizeof (fan_nodes[0]))
132 * Miscellaneous declarations
134 static void delete_sensor_nodes_and_props(void);
135 static void delete_fan_nodes_and_props(void);
139 * Read function for volatile "Temperature" property
142 get_current_temp(ptree_rarg_t
*parg
, void *buf
)
145 picl_prophdl_t proph
;
146 sensor_node_t
*snodep
;
150 * Locate the sensor in our sensor_nodes table by matching the
151 * property handle and get its temperature.
154 for (i
= 0; i
< NSENSORS
; ++i
) {
155 snodep
= &sensor_nodes
[i
];
156 if (snodep
->proph
!= proph
)
159 if (get_temperature(snodep
->sensorp
, &temp
) < 0)
161 (void) memcpy(buf
, (caddr_t
)&temp
, sizeof (tempr_t
));
162 return (PICL_SUCCESS
);
164 return (PICL_FAILURE
);
167 * Read function for volatile "Speed" property on "fan" class node
170 set_current_speed(ptree_warg_t
*parg
, const void *buf
)
173 picl_prophdl_t proph
;
178 * Locate the fan in our fan_nodes table by matching the
179 * property handle and get fan speed.
182 for (i
= 0; i
< NFANS
; ++i
) {
183 fnodep
= &fan_nodes
[i
];
184 if (fnodep
->proph
!= proph
)
186 if (fnodep
->fanp
->fd
== -1)
189 (void) memcpy((caddr_t
)&speed
, buf
, sizeof (speed
));
191 ret
= set_fan_speed(fnodep
->fanp
, speed
);
194 if (ret
== -1 && errno
== EBUSY
)
195 return (PICL_NOTWRITABLE
);
197 return (PICL_INVALIDARG
);
201 return (PICL_SUCCESS
);
203 return (PICL_FAILURE
);
208 * Read function for volatile "Speed" property on "fan" class node
211 get_current_speed(ptree_rarg_t
*parg
, void *buf
)
214 picl_prophdl_t proph
;
219 * Locate the fan in our fan_nodes table by matching the
220 * property handle and get fan speed.
223 for (i
= 0; i
< NFANS
; ++i
) {
224 fnodep
= &fan_nodes
[i
];
225 if (fnodep
->proph
!= proph
)
227 if (fnodep
->fanp
->fd
== -1)
229 if (get_fan_speed(fnodep
->fanp
, &speed
) < 0)
232 (void) memcpy(buf
, (caddr_t
)&speed
, sizeof (speed
));
233 return (PICL_SUCCESS
);
235 return (PICL_FAILURE
);
239 * Create and add the specified regular property
243 add_regular_prop(picl_nodehdl_t nodeh
, char *name
, int type
, int access
,
244 int size
, void *valbuf
, picl_prophdl_t
*prophp
)
247 ptree_propinfo_t propinfo
;
248 picl_prophdl_t proph
;
250 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
251 type
, access
, size
, name
, NULL
, NULL
);
252 if (err
!= PICL_SUCCESS
)
255 err
= ptree_create_and_add_prop(nodeh
, &propinfo
, valbuf
, &proph
);
256 if (err
== PICL_SUCCESS
&& prophp
)
263 * Create and add the specified volatile property
266 add_volatile_prop(picl_nodehdl_t nodeh
, char *name
, int type
, int access
,
267 int size
, ptree_vol_rdfunc_t
*rdfunc
, ptree_vol_wrfunc_t
*wrfunc
,
268 picl_prophdl_t
*prophp
)
271 ptree_propinfo_t propinfo
;
272 picl_prophdl_t proph
;
274 err
= ptree_init_propinfo(&propinfo
, PTREE_PROPINFO_VERSION
,
275 type
, (access
|PICL_VOLATILE
), size
, name
, rdfunc
, wrfunc
);
276 if (err
!= PICL_SUCCESS
)
279 err
= ptree_create_and_add_prop(nodeh
, &propinfo
, NULL
, &proph
);
280 if (err
== PICL_SUCCESS
&& prophp
)
286 * Add temperature threshold properties
289 add_sensor_thresh_props(picl_nodehdl_t nodeh
, sensor_ctrl_blk_t
*threshp
)
291 picl_prophdl_t proph
;
293 (void) add_regular_prop(nodeh
, PICL_PROP_LOW_POWER_OFF
,
294 PICL_PTYPE_INT
, PICL_READ
,
295 sizeof (threshp
->low_power_off
),
296 (void *)&(threshp
->low_power_off
), &proph
);
298 (void) add_regular_prop(nodeh
, PICL_PROP_LOW_SHUTDOWN
,
299 PICL_PTYPE_INT
, PICL_READ
,
300 sizeof (threshp
->low_shutdown
),
301 (void *)&(threshp
->low_shutdown
), &proph
);
303 (void) add_regular_prop(nodeh
, PICL_PROP_LOW_WARNING
,
304 PICL_PTYPE_INT
, PICL_READ
,
305 sizeof (threshp
->low_warning
),
306 (void *)&(threshp
->low_warning
), &proph
);
308 (void) add_regular_prop(nodeh
, PICL_PROP_HIGH_WARNING
,
309 PICL_PTYPE_INT
, PICL_READ
,
310 sizeof (threshp
->high_warning
),
311 (void *)&(threshp
->high_warning
), &proph
);
313 (void) add_regular_prop(nodeh
, PICL_PROP_HIGH_SHUTDOWN
,
314 PICL_PTYPE_INT
, PICL_READ
,
315 sizeof (threshp
->high_shutdown
),
316 (void *)&(threshp
->high_shutdown
), &proph
);
318 (void) add_regular_prop(nodeh
, PICL_PROP_HIGH_POWER_OFF
,
319 PICL_PTYPE_INT
, PICL_READ
,
320 sizeof (threshp
->high_power_off
),
321 (void *)&(threshp
->high_power_off
), &proph
);
325 * Go through the sensor_nodes array and create those nodes
326 * and the Temperature property to report the temperature.
329 add_sensor_nodes_and_props(void)
332 char *pname
, *nodename
, *devfs_path
;
333 sensor_node_t
*snodep
;
334 sensor_ctrl_blk_t
*threshp
;
335 picl_nodehdl_t nodeh
, cnodeh
;
336 picl_prophdl_t proph
;
337 env_sensor_t
*sensorp
;
340 for (i
= 0; i
< NSENSORS
; ++i
) {
341 snodep
= &sensor_nodes
[i
];
343 * Get the parent nodeh
345 err
= ptree_get_node_by_path(snodep
->parent_path
, &nodeh
);
346 if (err
!= PICL_SUCCESS
)
348 sensorp
= snodep
->sensorp
;
351 * Create temperature-sensor node
353 nodename
= snodep
->sensor_name
;
354 err
= ptree_create_and_add_node(nodeh
, nodename
,
355 PICL_CLASS_TEMPERATURE_SENSOR
, &cnodeh
);
358 "Creating PICL sensor node '%s' err:%d\n",
360 if (err
!= PICL_SUCCESS
)
363 /* save node handle */
364 snodep
->nodeh
= cnodeh
;
367 * Add "devfs_path" property in child node
369 devfs_path
= sensorp
->devfs_path
;
370 pname
= PICL_PROP_DEVFS_PATH
;
371 err
= add_regular_prop(cnodeh
, pname
,
372 PICL_PTYPE_CHARSTRING
, PICL_READ
,
373 strlen(devfs_path
)+1, (void *)devfs_path
, &proph
);
374 if (err
!= PICL_SUCCESS
)
378 * Now add volatile "temperature" volatile property
379 * in this "temperature-sensor" class node.
381 pname
= PICL_PROP_TEMPERATURE
;
382 err
= add_volatile_prop(cnodeh
, pname
,
383 PICL_PTYPE_INT
, PICL_READ
, sizeof (tempr_t
),
384 get_current_temp
, NULL
, &proph
);
385 if (err
!= PICL_SUCCESS
)
388 /* Save prop handle */
389 snodep
->proph
= proph
;
392 * Add threshold related properties
394 threshp
= sensorp
->es_ptr
;
397 add_sensor_thresh_props(cnodeh
, threshp
);
400 if (err
!= PICL_SUCCESS
) {
401 delete_sensor_nodes_and_props();
404 "Can't create prop/node for sensor '%s'\n",
408 return (PICL_SUCCESS
);
412 * Delete all sensor nodes and related properties created by the
413 * add_sensor_prop() for each sensor node in the PICL tree.
416 delete_sensor_nodes_and_props(void)
418 sensor_node_t
*snodep
;
422 * Delete/destroy any property created in the sensed device
423 * as well as the sensor node and all properties under it.
424 * Note that deleiing/destroying a node deletes/destroys
425 * all properties within that node.
428 for (i
= 0; i
< NSENSORS
; ++i
) {
429 snodep
= &sensor_nodes
[i
];
430 if (snodep
->nodeh
!= NULL
) {
431 /* delete node and all properties under it */
432 (void) ptree_delete_node(snodep
->nodeh
);
433 (void) ptree_destroy_node(snodep
->nodeh
);
434 snodep
->nodeh
= NULL
;
435 snodep
->proph
= NULL
;
442 * For each entry in fan_nodes[] array, do the following:
443 * - Create specified "fan" class node.
444 * - Create "Speed" volatile propery under "fan" class node.
445 * - Create "SpeedUnit" property under "fan" class node.
448 add_fan_nodes_and_props()
451 char *pname
, *nodename
, *devfs_path
;
454 picl_nodehdl_t nodeh
, cnodeh
;
455 picl_prophdl_t proph
;
459 for (i
= 0; i
< NFANS
; ++i
) {
461 * Add various fan nodes and properties
463 fnodep
= &fan_nodes
[i
];
467 err
= ptree_get_node_by_path(fnodep
->parent_path
, &nodeh
);
468 if (err
!= PICL_SUCCESS
)
472 * Create "fan" class node and save node handle
474 nodename
= fnodep
->fan_name
;
475 err
= ptree_create_and_add_node(nodeh
, nodename
,
476 PICL_CLASS_FAN
, &cnodeh
);
479 "Creating PICL fan node '%s' err:%d\n",
482 if (err
!= PICL_SUCCESS
)
484 fnodep
->nodeh
= cnodeh
;
487 * Add "devfs_path" property in child node
490 devfs_path
= fanp
->devfs_path
;
491 pname
= PICL_PROP_DEVFS_PATH
;
492 err
= add_regular_prop(cnodeh
, pname
,
493 PICL_PTYPE_CHARSTRING
, PICL_READ
,
494 strlen(devfs_path
)+1, (void *)devfs_path
, &proph
);
496 if (err
!= PICL_SUCCESS
)
501 * Add "Speed" volatile property in this "fan"
502 * class node and save prop handle.
504 pname
= PICL_PROP_FAN_SPEED
;
505 err
= add_volatile_prop(cnodeh
, pname
, PICL_PTYPE_INT
,
506 PICL_READ
|PICL_WRITE
, sizeof (fanspeed_t
),
508 set_current_speed
, &proph
);
510 if (err
!= PICL_SUCCESS
)
512 fnodep
->proph
= proph
;
515 * Add other "fan" class properties
517 pname
= PICL_PROP_FAN_SPEED_UNIT
;
518 err
= add_regular_prop(cnodeh
, pname
,
519 PICL_PTYPE_CHARSTRING
, PICL_READ
,
520 strlen(fnodep
->speed_unit
)+1,
521 (void *)fnodep
->speed_unit
, &proph
);
523 if (err
!= PICL_SUCCESS
)
526 if (err
!= PICL_SUCCESS
) {
527 delete_fan_nodes_and_props();
529 envd_log(LOG_WARNING
,
530 "Can't create prop/node for fan '%s'\n",
534 return (PICL_SUCCESS
);
539 * Delete all fan nodes and related properties created by the
540 * add_fan_props() for each fan node in the PICL tree.
543 delete_fan_nodes_and_props(void)
549 * Delete/destroy fan node and all properties under it.
550 * Note that deleiing/destroying a node deletes/destroys
551 * all properties within that node.
554 for (i
= 0; i
< NFANS
; ++i
) {
555 fnodep
= &fan_nodes
[i
];
556 if (fnodep
->nodeh
!= NULL
) {
557 (void) ptree_delete_node(fnodep
->nodeh
);
558 (void) ptree_destroy_node(fnodep
->nodeh
);
559 fnodep
->nodeh
= NULL
;
565 * Tuneables publishing functions
568 copy_persistent_tuneable(env_tuneable_t
*tune
, char *buf
)
571 switch (tune
->type
) {
573 case PICL_PTYPE_INT
: {
574 (void) memcpy((int *)tune
->value
,
578 case PICL_PTYPE_CHARSTRING
: {
579 (void) memcpy((caddr_t
)tune
->value
,
584 return (PICL_FAILURE
);
587 return (PICL_SUCCESS
);
591 env_parse_tunables(picl_nodehdl_t rooth
)
593 char nmbuf
[SYS_NMLN
];
594 char pname
[PATH_MAX
];
596 if (sysinfo(SI_PLATFORM
, nmbuf
, sizeof (nmbuf
)) != -1) {
597 (void) snprintf(pname
, PATH_MAX
, PICLD_PLAT_PLUGIN_DIRF
, nmbuf
);
598 (void) strlcat(pname
, TUNABLE_CONF_FILE
, PATH_MAX
);
599 if (access(pname
, R_OK
) == 0) {
600 (void) picld_pluginutil_parse_config_file(rooth
, pname
);
607 env_picl_setup_tuneables(void)
611 picl_nodehdl_t nodeh
;
612 picl_nodehdl_t rooth
;
613 picl_prophdl_t proph
;
614 env_tuneable_t
*tuneablep
;
615 char read_buf
[BUFSIZ
];
617 if (ptree_get_root(&rooth
) != PICL_SUCCESS
) {
618 return (PICL_FAILURE
);
620 err
= ptree_create_and_add_node(rooth
, PICL_PLUGINS_NODE
,
621 PICL_CLASS_PICL
, &nodeh
);
622 if (err
!= PICL_SUCCESS
)
623 return (PICL_FAILURE
);
624 err
= ptree_create_and_add_node(nodeh
, PICL_ENVIRONMENTAL_NODE
,
625 PICL_CLASS_PICL
, &nodeh
);
626 if (err
!= PICL_SUCCESS
) {
627 return (PICL_FAILURE
);
631 * Parse the conf file
633 env_parse_tunables(rooth
);
634 for (i
= 0; i
< ntuneables
; i
++) {
635 tuneablep
= &tuneables
[i
];
636 err
= ptree_get_propval_by_name(nodeh
, tuneablep
->name
,
637 read_buf
, tuneablep
->nbytes
);
639 if (err
!= PICL_SUCCESS
) {
641 * Add volitle functions to environmental node
643 err
= add_volatile_prop(nodeh
, tuneablep
->name
,
645 PICL_READ
|PICL_WRITE
, tuneablep
->nbytes
,
647 tuneablep
->wfunc
, &proph
);
649 tuneablep
->proph
= proph
;
652 * property is persistent
654 (void) copy_persistent_tuneable(tuneablep
,
659 return (PICL_SUCCESS
);
663 * Find the ENVMODEL_CONF_FILE file.
666 get_envmodel_conf_file(char *outfilename
)
668 char nmbuf
[SYS_NMLN
];
669 char pname
[PATH_MAX
];
671 if (sysinfo(SI_PLATFORM
, nmbuf
, sizeof (nmbuf
)) != -1) {
672 (void) snprintf(pname
, PATH_MAX
, PICLD_PLAT_PLUGIN_DIRF
, nmbuf
);
673 (void) strlcat(pname
, ENV_CONF_FILE
, PATH_MAX
);
674 if (access(pname
, R_OK
) == 0) {
675 (void) strlcpy(outfilename
, pname
, PATH_MAX
);
680 if (sysinfo(SI_MACHINE
, nmbuf
, sizeof (nmbuf
)) != -1) {
681 (void) snprintf(pname
, PATH_MAX
, PICLD_PLAT_PLUGIN_DIRF
, nmbuf
);
682 (void) strlcat(pname
, ENV_CONF_FILE
, PATH_MAX
);
683 if (access(pname
, R_OK
) == 0) {
684 (void) strlcpy(outfilename
, pname
, PATH_MAX
);
689 (void) snprintf(pname
, PATH_MAX
, "%s/%s", PICLD_COMMON_PLUGIN_DIR
,
692 if (access(pname
, R_OK
) == 0) {
693 (void) strlcpy(outfilename
, pname
, PATH_MAX
);
700 /* Delete all sensor/fan nodes and any properties created by this plugin */
702 env_picl_destroy(void)
704 delete_fan_nodes_and_props();
705 delete_sensor_nodes_and_props();
712 sensor_node_t
*snodep
;
714 char fullfilename
[PATH_MAX
];
715 picl_nodehdl_t rooth
;
720 * Initialize sensorp and other fields in the sensor_nodes[] array
723 for (i
= 0; i
< NSENSORS
; ++i
) {
724 snodep
= &sensor_nodes
[i
];
725 snodep
->sensorp
= sensor_lookup(snodep
->sensor_name
);
726 snodep
->nodeh
= NULL
;
727 snodep
->proph
= NULL
;
728 snodep
->target_proph
= NULL
;
732 * Initialize fanp and other fields in the fan_nodes[] array
734 for (i
= 0; i
< NFANS
; ++i
) {
735 fnodep
= &fan_nodes
[i
];
736 fnodep
->fanp
= fan_lookup(fnodep
->fan_name
);
737 fnodep
->nodeh
= NULL
;
738 fnodep
->proph
= NULL
;
742 * Get platform handle and populate PICL tree with environmental
743 * nodes and properties
746 err
= add_sensor_nodes_and_props();
748 if (err
== PICL_SUCCESS
)
749 err
= add_fan_nodes_and_props();
752 if (err
!= PICL_SUCCESS
) {
753 delete_sensor_nodes_and_props();
754 envd_log(LOG_CRIT
, ENVD_PICL_SETUP_FAILED
);
759 * Parse the envmodel.conf file and populate the PICL tree
761 if (get_envmodel_conf_file(fullfilename
) < 0)
762 envd_log(LOG_CRIT
, ENVD_PICL_SETUP_FAILED
);
763 if (ptree_get_root(&rooth
) != PICL_SUCCESS
)
764 envd_log(LOG_CRIT
, ENVD_PICL_SETUP_FAILED
);
765 err
= picld_pluginutil_parse_config_file(rooth
, fullfilename
);
767 if (err
!= PICL_SUCCESS
)
768 envd_log(LOG_CRIT
, ENVD_PICL_SETUP_FAILED
);