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 (c) 1999-2001 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27 /*
28 * This file contains code for setting up environmental related nodes
29 * and properties in the PICL tree.
30 *
31 * For each temperature-device class node, it does the following:
32 * - Create cpu and cpu-ambient temperautre-sensor class nodes.
33 * - Create "devfs-path" property under each temperature-sensor class node
34 * - Create "Temperature" volatile property under these nodes.
35 * - Create various temperature threshold properties under each node.
36 * - Create "Temperature" and "AmbientTemperature" volatile properties
37 * under corresponding "cpu" class node.
38 *
39 * For the "fan-control" node, it does the following:
40 * - Create system-fan node
41 * - Create "devfs-path" property under "fan" class node
42 * - Create "Speed" volatile propery under each node.
43 * - Create "SpeedUnit" property under each node.
44 */
45
46 #include <stdio.h>
47 #include <fcntl.h>
48 #include <unistd.h>
49 #include <syslog.h>
50 #include <stdlib.h>
51 #include <limits.h>
52 #include <sys/open.h>
53 #include <ctype.h>
54 #include <string.h>
55 #include <alloca.h>
56 #include <libintl.h>
57 #include <sys/systeminfo.h>
58 #include <picl.h>
59 #include <picltree.h>
60 #include <picld_pluginutil.h>
61 #include <pthread.h>
62 #include <sys/utsname.h>
63 #include <sys/systeminfo.h>
64 #include "envd.h"
65
66
67 /*
68 * Volatile property read/write function typedef
69 */
70 typedef int ptree_vol_rdfunc_t(ptree_rarg_t *parg, void *buf);
71 typedef int ptree_vol_wrfunc_t(ptree_warg_t *parg, const void *buf);
72
73 /*
74 * PICL Classes and standard property names
75 */
76 #define PICL_CLASS_CPU "cpu"
77 #define PICL_CLASS_FAN "fan"
78 #define PICL_CLASS_FAN_CONTROL "fan-control"
79 #define PICL_CLASS_TEMP_DEVICE "temperature-device"
80 #define PICL_CLASS_TEMP_SENSOR "temperature-sensor"
81
82 #define PICL_PROP_REG "reg"
83 #define PICL_PROP_DEVFS_PATH "devfs-path"
84 #define PICL_PROP_UNIT_ADDRESS "UnitAddress"
85 #define UNITADDR_LEN_MAX 256 /* max length for UnitAddress */
86
87 /*
88 * temperature properties
89 */
90 #define PROP_TEMPERATURE "Temperature"
91 #define PROP_CPU_AMB_TEMP "AmbientTemperature"
92 #define PROP_CPU_DIE_TEMP "Temperature"
93
94 /*
95 * Various temperature threshold property names
96 */
97 #define PROP_LOW_POWER_OFF "LowPowerOffThreshold"
98 #define PROP_LOW_SHUTDOWN "LowShutdownThreshold"
99 #define PROP_LOW_WARNING "LowWarningThreshold"
100 #define PROP_HIGH_POWER_OFF "HighPowerOffThreshold"
101 #define PROP_HIGH_SHUTDOWN "HighShutdownThreshold"
102 #define PROP_HIGH_WARNING "HighWarningThreshold"
103
104 /*
105 * fan properties
106 */
107 #define PROP_FAN_SPEED "Speed"
108 #define PROP_FAN_SPEED_UNIT "SpeedUnit"
109 #define PROP_FAN_SPEED_UNIT_VALUE "%"
110
111 /*
112 * PICL class path for CPU nodes
113 */
114 #define CPU_PLAT_PATH "_class:/upa/cpu?ID=0"
115
116 /*
117 * "UnitAddress" propval for various temperature devices (platform dependent)
118 */
119 #define CPU_TEMPDEV_UNITADDR "0,30"
120
121 /*
122 * Sensor node data structure
123 */
124 typedef struct {
125 char *sensor_name; /* sensor name */
126 env_sensor_t *sensorp; /* sensor info */
127 char *unitaddr; /* parent's UnitAddress propval */
128 char *sdev_node; /* sensed device node name */
129 char *sdev_pname; /* sensed device "temp" prop name */
130 picl_nodehdl_t nodeh; /* sensor node handle */
131 picl_prophdl_t proph; /* "Temperature" property handle */
132 picl_prophdl_t sdev_proph; /* property handle for sensed dev */
133 } sensor_node_t;
134
135
136 /*
137 * Sensor nodes array
138 */
139 static sensor_node_t sensor_nodes[] = {
140 {SENSOR_CPU_DIE, NULL, CPU_TEMPDEV_UNITADDR,
141 CPU_PLAT_PATH, PROP_CPU_DIE_TEMP},
142
143 {SENSOR_CPU_AMB, NULL, CPU_TEMPDEV_UNITADDR,
144 CPU_PLAT_PATH, PROP_CPU_AMB_TEMP},
145
146 {NULL, NULL, NULL, NULL, NULL}
147 };
148
149
150 /*
151 * Fan node data structure
152 */
153 typedef struct {
154 char *fan_name; /* fan name */
155 env_fan_t *fanp; /* fan information */
156 char *speed_unit; /* speed unit string */
157 picl_nodehdl_t nodeh; /* "fan" node handle */
158 picl_prophdl_t proph; /* "Speed" property handle */
159 } fan_node_t;
160
161
162 /*
163 * Fan node array
164 */
165 static fan_node_t fan_nodes[] = {
166 {ENV_SYSTEM_FAN, NULL, PROP_FAN_SPEED_UNIT_VALUE},
167 {NULL, NULL, NULL}
168 };
169
170 /*
171 * Miscellaneous declarations
172 */
173 typedef struct node_list {
174 picl_nodehdl_t nodeh;
175 struct node_list *next;
176 } node_list_t;
177
178 static void delete_sensor_nodes_and_props(void);
179 static void delete_fan_nodes_and_props(void);
180
181
182
183 /*
184 * Read function for volatile "Temperature" property
185 */
186 static int
get_current_temp(ptree_rarg_t * parg,void * buf)187 get_current_temp(ptree_rarg_t *parg, void *buf)
188 {
189 tempr_t temp;
190 picl_prophdl_t proph;
191 sensor_node_t *snodep;
192
193 /*
194 * Locate the sensor in our sensor_nodes table by matching the
195 * property handle and get its temperature.
196 */
197 proph = parg->proph;
198 for (snodep = &sensor_nodes[0]; snodep->sensor_name != NULL; snodep++) {
199 if (snodep->proph != proph &&
200 snodep->sdev_proph != proph)
201 continue;
202
203 if (get_temperature(snodep->sensorp, &temp) < 0)
204 return (PICL_FAILURE);
205 (void) memcpy(buf, (caddr_t)&temp, sizeof (tempr_t));
206 return (PICL_SUCCESS);
207 }
208 return (PICL_FAILURE);
209 }
210
211
212 /*
213 * Read function for volatile "Speed" property on "fan" class node
214 */
215 static int
get_current_speed(ptree_rarg_t * parg,void * buf)216 get_current_speed(ptree_rarg_t *parg, void *buf)
217 {
218 fanspeed_t speed;
219 picl_prophdl_t proph;
220 fan_node_t *fnodep;
221
222 /*
223 * Locate the fan in our fan_nodes table by matching the
224 * property handle and get fan speed.
225 */
226 proph = parg->proph;
227 for (fnodep = &fan_nodes[0]; fnodep->fan_name != NULL; fnodep++) {
228 if (fnodep->proph != proph)
229 continue;
230 if (get_fan_speed(fnodep->fanp, &speed) < 0)
231 return (PICL_FAILURE);
232
233 (void) memcpy(buf, (caddr_t)&speed, sizeof (speed));
234 return (PICL_SUCCESS);
235 }
236 return (PICL_FAILURE);
237 }
238
239
240 static node_list_t *
add_node_to_list(picl_nodehdl_t nodeh,node_list_t * listp)241 add_node_to_list(picl_nodehdl_t nodeh, node_list_t *listp)
242 {
243 node_list_t *el;
244 node_list_t *tmp;
245
246 el = malloc(sizeof (node_list_t));
247 if (el == NULL)
248 return (listp);
249 el->nodeh = nodeh;
250 el->next = NULL;
251 if (listp == NULL) {
252 listp = el;
253 return (listp);
254 }
255
256 /*
257 * append to the end to preserve the order found
258 */
259 tmp = listp;
260 while (tmp->next != NULL)
261 tmp = tmp->next;
262
263 tmp->next = el;
264 return (listp);
265 }
266
267
268
269 /*
270 * Get a list of nodes of the specified classname under nodeh
271 * Once a node of the specified class is found, it's children are not
272 * searched.
273 */
274 static node_list_t *
get_node_list_by_class(picl_nodehdl_t nodeh,const char * classname,node_list_t * listp)275 get_node_list_by_class(picl_nodehdl_t nodeh, const char *classname,
276 node_list_t *listp)
277 {
278 int err;
279 char clname[PICL_CLASSNAMELEN_MAX+1];
280 picl_nodehdl_t chdh;
281
282 /*
283 * go through the children
284 */
285 err = ptree_get_propval_by_name(nodeh, PICL_PROP_CHILD, &chdh,
286 sizeof (picl_nodehdl_t));
287
288 while (err == PICL_SUCCESS) {
289 err = ptree_get_propval_by_name(chdh, PICL_PROP_CLASSNAME,
290 clname, strlen(classname) + 1);
291
292 if ((err == PICL_SUCCESS) && (strcmp(clname, classname) == 0))
293 listp = add_node_to_list(chdh, listp);
294 else
295 listp = get_node_list_by_class(chdh, classname, listp);
296
297 err = ptree_get_propval_by_name(chdh, PICL_PROP_PEER, &chdh,
298 sizeof (picl_nodehdl_t));
299 }
300 return (listp);
301 }
302
303
304 /*
305 * Free memory allocated to build the specified node list.
306 */
307 static void
free_node_list(node_list_t * listp)308 free_node_list(node_list_t *listp)
309 {
310 node_list_t *next;
311
312 for (; listp != NULL; listp = next) {
313 next = listp->next;
314 free(listp);
315 }
316 }
317
318 /*
319 * Get PICL_PTYPE_CHARSTRING "UnitAddress" property
320 */
321 static int
get_unit_address_prop(picl_nodehdl_t nodeh,void * buf,size_t len)322 get_unit_address_prop(picl_nodehdl_t nodeh, void *buf, size_t len)
323 {
324 int err;
325 picl_prophdl_t proph;
326 ptree_propinfo_t pinfo;
327
328 err = ptree_get_prop_by_name(nodeh, PICL_PROP_UNIT_ADDRESS, &proph);
329 if (err == PICL_SUCCESS)
330 err = ptree_get_propinfo(proph, &pinfo);
331
332 if (err != PICL_SUCCESS)
333 return (err);
334
335 if (pinfo.piclinfo.type != PICL_PTYPE_CHARSTRING ||
336 pinfo.piclinfo.size > len)
337 return (PICL_FAILURE);
338
339 err = ptree_get_propval(proph, buf, pinfo.piclinfo.size);
340 return (err);
341 }
342
343
344 /*
345 * Create and add the specified regular property
346 */
347
348 static int
add_regular_prop(picl_nodehdl_t nodeh,char * name,int type,int access,int size,void * valbuf,picl_prophdl_t * prophp)349 add_regular_prop(picl_nodehdl_t nodeh, char *name, int type, int access,
350 int size, void *valbuf, picl_prophdl_t *prophp)
351 {
352 int err;
353 ptree_propinfo_t propinfo;
354 picl_prophdl_t proph;
355
356 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
357 type, access, size, name, NULL, NULL);
358 if (err != PICL_SUCCESS)
359 return (err);
360
361 err = ptree_create_and_add_prop(nodeh, &propinfo, valbuf, &proph);
362 if (err == PICL_SUCCESS && prophp)
363 *prophp = proph;
364 return (err);
365 }
366
367
368 /*
369 * Create and add the specified volatile property
370 */
371 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)372 add_volatile_prop(picl_nodehdl_t nodeh, char *name, int type, int access,
373 int size, ptree_vol_rdfunc_t *rdfunc, ptree_vol_wrfunc_t *wrfunc,
374 picl_prophdl_t *prophp)
375 {
376 int err;
377 ptree_propinfo_t propinfo;
378 picl_prophdl_t proph;
379
380 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
381 type, (access|PICL_VOLATILE), size, name, rdfunc, wrfunc);
382 if (err != PICL_SUCCESS)
383 return (err);
384
385 err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, &proph);
386 if (err == PICL_SUCCESS && prophp)
387 *prophp = proph;
388 return (err);
389 }
390
391 /*
392 * Add temperature threshold properties
393 */
394 static void
add_sensor_thresh_props(picl_nodehdl_t nodeh,sensor_thresh_t * threshp)395 add_sensor_thresh_props(picl_nodehdl_t nodeh, sensor_thresh_t *threshp)
396 {
397 picl_prophdl_t proph;
398
399 (void) add_regular_prop(nodeh, PROP_LOW_POWER_OFF,
400 PICL_PTYPE_INT, PICL_READ,
401 sizeof (threshp->low_power_off),
402 (void *)&(threshp->low_power_off), &proph);
403
404 (void) add_regular_prop(nodeh, PROP_LOW_SHUTDOWN,
405 PICL_PTYPE_INT, PICL_READ,
406 sizeof (threshp->low_shutdown),
407 (void *)&(threshp->low_shutdown), &proph);
408
409 (void) add_regular_prop(nodeh, PROP_LOW_WARNING,
410 PICL_PTYPE_INT, PICL_READ,
411 sizeof (threshp->low_warning),
412 (void *)&(threshp->low_warning), &proph);
413
414 (void) add_regular_prop(nodeh, PROP_HIGH_WARNING,
415 PICL_PTYPE_INT, PICL_READ,
416 sizeof (threshp->high_warning),
417 (void *)&(threshp->high_warning), &proph);
418
419 (void) add_regular_prop(nodeh, PROP_HIGH_SHUTDOWN,
420 PICL_PTYPE_INT, PICL_READ,
421 sizeof (threshp->high_shutdown),
422 (void *)&(threshp->high_shutdown), &proph);
423
424 (void) add_regular_prop(nodeh, PROP_HIGH_POWER_OFF,
425 PICL_PTYPE_INT, PICL_READ,
426 sizeof (threshp->high_power_off),
427 (void *)&(threshp->high_power_off), &proph);
428 }
429
430
431 /*
432 * Lookup "temperature-device" class nodes and create "temperature-sensor"
433 * class nodes and relevant properties under those nodes.
434 *
435 * For each entry in sensor_nodes[] array, do the following:
436 * - Create specified (cpu-die or cpu-ambient) "temperautre-sensor" class
437 * node.
438 * - Create "devfs-path" property under this node.
439 * - Create "Temperature" volatile property under this node.
440 * - Create various temperature threshold properties under this node.
441 * - Create specified ("Temperature" or "AmbientTemperature") volatile
442 * temperature property under specified sdev_node node.
443 */
444
445 static int
add_sensor_nodes_and_props(picl_nodehdl_t plath)446 add_sensor_nodes_and_props(picl_nodehdl_t plath)
447 {
448 int err;
449 char *pname, *nodename, *refnode, *devfs_path;
450 node_list_t *node_list, *listp;
451 sensor_node_t *snodep;
452 sensor_thresh_t *threshp;
453 picl_nodehdl_t nodeh, refnodeh, cnodeh;
454 picl_prophdl_t proph;
455 char unitaddr[UNITADDR_LEN_MAX];
456 env_sensor_t *sensorp;
457
458 node_list =
459 get_node_list_by_class(plath, PICL_CLASS_TEMP_DEVICE, NULL);
460
461 if (node_list == NULL)
462 return (PICL_FAILURE);
463
464 for (listp = node_list; listp != NULL; listp = listp->next) {
465 /*
466 * Get "reg" property. Skip if no "reg" property found.
467 */
468 nodeh = listp->nodeh;
469 err = get_unit_address_prop(nodeh, (void *)unitaddr,
470 sizeof (unitaddr));
471 if (err != PICL_SUCCESS)
472 continue;
473
474 for (snodep = sensor_nodes; snodep->sensor_name != NULL;
475 snodep++) {
476
477 /* Match "UnitAddress" property */
478 if (strcasecmp(unitaddr, snodep->unitaddr) != 0)
479 continue;
480
481 /*
482 * Skip if already initialized or no sensor info
483 */
484 sensorp = snodep->sensorp;
485 if (snodep->nodeh != 0 || sensorp == NULL)
486 continue;
487
488 /*
489 * Create temperature-sensor node
490 */
491 nodename = snodep->sensor_name;
492 err = ptree_create_and_add_node(nodeh, nodename,
493 PICL_CLASS_TEMP_SENSOR, &cnodeh);
494 if (env_debug)
495 envd_log(LOG_INFO,
496 "Creating PICL sensor node '%s' err:%d\n",
497 nodename, err);
498 if (err != PICL_SUCCESS)
499 break;
500
501 /* save node handle */
502 snodep->nodeh = cnodeh;
503
504 /*
505 * Add "devfs_path" property in child node
506 */
507 devfs_path = sensorp->devfs_path;
508 pname = PICL_PROP_DEVFS_PATH;
509 err = add_regular_prop(cnodeh, pname,
510 PICL_PTYPE_CHARSTRING, PICL_READ,
511 strlen(devfs_path)+1, (void *)devfs_path, &proph);
512 if (err != PICL_SUCCESS)
513 break;
514
515 /*
516 * Now add volatile "temperature" volatile property
517 * in this "temperature-sensor" class node.
518 */
519 pname = PROP_TEMPERATURE;
520 err = add_volatile_prop(cnodeh, pname,
521 PICL_PTYPE_INT, PICL_READ, sizeof (tempr_t),
522 get_current_temp, NULL, &proph);
523 if (err != PICL_SUCCESS)
524 break;
525
526 /* Save prop handle */
527 snodep->proph = proph;
528
529 /*
530 * Add threshold related properties
531 */
532 threshp = sensorp->temp_thresh;
533 if (threshp != NULL)
534 add_sensor_thresh_props(cnodeh, threshp);
535
536 /*
537 * Finally create property in the sensed device
538 * (if one specified)
539 */
540 refnode = snodep->sdev_node;
541 pname = snodep->sdev_pname;
542 if (refnode == NULL || pname == NULL)
543 continue;
544
545 err = ptree_get_node_by_path(refnode, &refnodeh);
546 if (err == PICL_SUCCESS) {
547 err = add_volatile_prop(refnodeh, pname,
548 PICL_PTYPE_INT, PICL_READ,
549 sizeof (tempr_t), get_current_temp,
550 NULL, &proph);
551 }
552
553 if (err != PICL_SUCCESS)
554 break;
555
556 /* Save prop handle */
557 snodep->sdev_proph = proph;
558 }
559 if (err != PICL_SUCCESS) {
560 delete_sensor_nodes_and_props();
561 free_node_list(node_list);
562 if (env_debug)
563 envd_log(LOG_INFO,
564 "Can't create prop/node for sensor '%s'\n",
565 nodename);
566 return (err);
567 }
568 }
569
570 free_node_list(node_list);
571 return (PICL_SUCCESS);
572 }
573
574 /*
575 * Delete all sensor nodes and related properties created by the
576 * add_sensor_prop() for each sensor node in the PICL tree.
577 */
578 static void
delete_sensor_nodes_and_props(void)579 delete_sensor_nodes_and_props(void)
580 {
581 sensor_node_t *snodep;
582
583 /*
584 * Delete/destroy any property created in the sensed device
585 * as well as the sensor node and all properties under it.
586 * Note that deleiing/destroying a node deletes/destroys
587 * all properties within that node.
588 */
589
590 for (snodep = sensor_nodes; snodep->sensor_name != NULL; snodep++) {
591 if (snodep->sdev_proph != 0) {
592 (void) ptree_delete_prop(snodep->sdev_proph);
593 (void) ptree_destroy_prop(snodep->sdev_proph);
594 snodep->sdev_proph = 0;
595 }
596
597 if (snodep->nodeh != 0) {
598 /* delete node and all properties under it */
599 (void) ptree_delete_node(snodep->nodeh);
600 (void) ptree_destroy_node(snodep->nodeh);
601 snodep->nodeh = 0;
602 snodep->proph = 0;
603 }
604 }
605 }
606
607
608 /*
609 * Lookup "fan-control" class node and create "fan" class nodes and
610 * relevant properties under those nodes.
611 *
612 * For each entry in fan_nodes[] array, do the following:
613 * - Create specified "fan" class node.
614 * - Create "devfs-path" property under "fan" class node
615 * - Create "Speed" volatile propery under "fan" class node.
616 * - Create "SpeedUnit" property under "fan" class node.
617 */
618
619 static int
add_fan_nodes_and_props(picl_nodehdl_t plath)620 add_fan_nodes_and_props(picl_nodehdl_t plath)
621 {
622 int err;
623 char *pname, *nodename, *devfs_path;
624 env_fan_t *fanp;
625 fan_node_t *fnodep;
626 picl_nodehdl_t nodeh, cnodeh;
627 picl_prophdl_t proph;
628 node_list_t *node_list, *listp;
629
630 node_list =
631 get_node_list_by_class(plath, PICL_CLASS_FAN_CONTROL, NULL);
632
633 if (node_list == NULL)
634 return (PICL_FAILURE);
635
636 for (listp = node_list; listp != NULL; listp = listp->next) {
637 /*
638 * Add various fan nodes and properties
639 */
640 nodeh = listp->nodeh;
641 err = PICL_SUCCESS;
642 for (fnodep = fan_nodes; fnodep->fan_name != NULL; fnodep++) {
643
644 /* Skip if already initialized or no fan info */
645 if (fnodep->nodeh != 0 || fnodep->fanp == NULL)
646 continue;
647
648 /*
649 * Create "fan" class node and save node handle
650 */
651 nodename = fnodep->fan_name;
652 err = ptree_create_and_add_node(nodeh, nodename,
653 PICL_CLASS_FAN, &cnodeh);
654 if (env_debug)
655 envd_log(LOG_INFO,
656 "Creating PICL fan node '%s' err:%d\n",
657 nodename, err);
658
659 if (err != PICL_SUCCESS)
660 break;
661 fnodep->nodeh = cnodeh;
662
663 /*
664 * Add "devfs_path" property in child node
665 */
666 fanp = fnodep->fanp;
667 devfs_path = fanp->devfs_path;
668 pname = PICL_PROP_DEVFS_PATH;
669 err = add_regular_prop(cnodeh, pname,
670 PICL_PTYPE_CHARSTRING, PICL_READ,
671 strlen(devfs_path)+1, (void *)devfs_path, &proph);
672
673 if (err != PICL_SUCCESS)
674 break;
675
676 /*
677 * Add "Speed" volatile property in this "fan"
678 * class node and save prop handle.
679 */
680 pname = PROP_FAN_SPEED;
681 err = add_volatile_prop(cnodeh, pname, PICL_PTYPE_INT,
682 PICL_READ, sizeof (fanspeed_t), get_current_speed,
683 NULL, &proph);
684
685 if (err != PICL_SUCCESS)
686 break;
687 fnodep->proph = proph;
688
689 /*
690 * Add other "fan" class properties
691 */
692 pname = PROP_FAN_SPEED_UNIT;
693 err = add_regular_prop(cnodeh, pname,
694 PICL_PTYPE_CHARSTRING, PICL_READ,
695 strlen(fnodep->speed_unit)+1,
696 (void *)fnodep->speed_unit, &proph);
697
698 if (err != PICL_SUCCESS)
699 break;
700 }
701 if (err != PICL_SUCCESS) {
702 delete_fan_nodes_and_props();
703 free_node_list(node_list);
704 if (env_debug)
705 envd_log(LOG_WARNING,
706 "Can't create prop/node for fan '%s'\n",
707 nodename);
708 return (err);
709 }
710 }
711
712 free_node_list(node_list);
713 return (PICL_SUCCESS);
714 }
715
716
717 /*
718 * Delete all fan nodes and related properties created by the
719 * add_fan_props() for each fan node in the PICL tree.
720 */
721 static void
delete_fan_nodes_and_props(void)722 delete_fan_nodes_and_props(void)
723 {
724 fan_node_t *fnodep;
725
726 /*
727 * Delete/destroy fan node and all properties under it.
728 * Note that deleiing/destroying a node deletes/destroys
729 * all properties within that node.
730 */
731
732 for (fnodep = fan_nodes; fnodep->fan_name != NULL; fnodep++) {
733 if (fnodep->nodeh != 0) {
734 (void) ptree_delete_node(fnodep->nodeh);
735 (void) ptree_destroy_node(fnodep->nodeh);
736 fnodep->nodeh = 0;
737 }
738 }
739 }
740
741 /*
742 * Find the ENVMODEL_CONF_FILE file.
743 */
744 static int
get_envmodel_conf_file(char * outfilename)745 get_envmodel_conf_file(char *outfilename)
746 {
747 char nmbuf[SYS_NMLN];
748 char pname[PATH_MAX];
749
750 if (sysinfo(SI_PLATFORM, nmbuf, sizeof (nmbuf)) != -1) {
751 (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
752 (void) strlcat(pname, ENVMODEL_CONF_FILE, PATH_MAX);
753 if (access(pname, R_OK) == 0) {
754 (void) strlcpy(outfilename, pname, PATH_MAX);
755 return (0);
756 }
757 }
758
759 if (sysinfo(SI_MACHINE, nmbuf, sizeof (nmbuf)) != -1) {
760 (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
761 (void) strlcat(pname, ENVMODEL_CONF_FILE, PATH_MAX);
762 if (access(pname, R_OK) == 0) {
763 (void) strlcpy(outfilename, pname, PATH_MAX);
764 return (0);
765 }
766 }
767
768 (void) snprintf(pname, PATH_MAX, "%s/%s", PICLD_COMMON_PLUGIN_DIR,
769 ENVMODEL_CONF_FILE);
770
771 if (access(pname, R_OK) == 0) {
772 (void) strlcpy(outfilename, pname, PATH_MAX);
773 return (0);
774 }
775
776 return (-1);
777 }
778
779 void
env_picl_setup(void)780 env_picl_setup(void)
781 {
782 int err;
783 sensor_node_t *snodep;
784 fan_node_t *fnodep;
785 picl_nodehdl_t plath;
786 char fullfilename[PATH_MAX];
787 picl_nodehdl_t rooth;
788
789 /*
790 * Initialize sensorp and other fields in the sensor_nodes[] array
791 */
792 for (snodep = sensor_nodes; snodep->sensor_name != NULL; snodep++) {
793 snodep->sensorp = sensor_lookup(snodep->sensor_name);
794 snodep->nodeh = 0;
795 snodep->proph = 0;
796 snodep->sdev_proph = 0;
797 }
798
799 /*
800 * Initialize fanp and other fields in the fan_nodes[] array
801 */
802 for (fnodep = fan_nodes; fnodep->fan_name != NULL; fnodep++) {
803 fnodep->fanp = fan_lookup(fnodep->fan_name);
804 fnodep->nodeh = 0;
805 fnodep->proph = 0;
806 }
807
808 /*
809 * Get platform handle and populate PICL tree with environmental
810 * nodes and properties
811 */
812 err = ptree_get_node_by_path("/platform", &plath);
813
814 if (err == PICL_SUCCESS) {
815 err = add_sensor_nodes_and_props(plath);
816 if (err == PICL_SUCCESS)
817 err = add_fan_nodes_and_props(plath);
818 }
819
820 if (err != PICL_SUCCESS) {
821 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
822 return;
823 }
824
825 /*
826 * Parse the envmodel.conf file and populate the PICL tree
827 */
828 if (get_envmodel_conf_file(fullfilename) < 0)
829 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
830 if (ptree_get_root(&rooth) != PICL_SUCCESS)
831 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
832 err = picld_pluginutil_parse_config_file(rooth, fullfilename);
833
834 if (err != PICL_SUCCESS)
835 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
836 }
837