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 2005 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 <limits.h>
39 #include <errno.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 extern int disk_temp_monitor;
62 extern env_tuneable_t tuneables[];
63 extern int errno;
64 extern int ntuneables;
65 #define PROP_FAN_SPEED_UNIT_VALUE "rpm"
66
67 /*
68 * Sensor node data structure
69 */
70 typedef struct {
71 char *parent_path; /* parent path */
72 char *sensor_name; /* sensor name */
73 env_sensor_t *sensorp; /* sensor info */
74 picl_nodehdl_t nodeh; /* sensor node handle */
75 picl_prophdl_t proph; /* "Temperature" property handle */
76 picl_prophdl_t target_proph; /* "TargetTemp" property handle */
77 } sensor_node_t;
78
79 /*
80 * Sensor nodes array
81 */
82 static sensor_node_t sensor_nodes[] = {
83 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_CPU0,
84 NULL, 0, 0, 0},
85 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_CPU1,
86 NULL, 0, 0, 0},
87 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_MB,
88 NULL, 0, 0, 0},
89 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_ADT7462,
90 NULL, 0, 0, 0},
91 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_LM95221,
92 NULL, 0, 0, 0},
93 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_FIRE,
94 NULL, 0, 0, 0},
95 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_LSI1064,
96 NULL, 0, 0, 0},
97 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_FRONT_PANEL,
98 NULL, 0, 0, 0},
99 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_PSU,
100 NULL, 0, 0, 0}
101 };
102 #define N_SENSOR_NODES (sizeof (sensor_nodes)/sizeof (sensor_nodes[0]))
103
104 /*
105 * Fan node data structure
106 */
107 typedef struct {
108 char *parent_path; /* parent node path */
109 char *fan_name; /* fan name */
110 env_fan_t *fanp; /* fan information */
111 char *speed_unit; /* speed unit string */
112 picl_nodehdl_t nodeh; /* "fan" node handle */
113 picl_prophdl_t proph; /* "Speed" property handle */
114 } fan_node_t;
115
116 /*
117 * Fan node array
118 */
119 static fan_node_t fan_nodes[] = {
120 {"/platform/ebus@1f,464000/env-monitor@3,0", ENV_SYSTEM_FAN0,
121 NULL, PROP_FAN_SPEED_UNIT_VALUE, 0, 0},
122 {"/platform/ebus@1f,464000/env-monitor@3,0", ENV_SYSTEM_FAN1,
123 NULL, PROP_FAN_SPEED_UNIT_VALUE, 0, 0},
124 {"/platform/ebus@1f,464000/env-monitor@3,0", ENV_SYSTEM_FAN2,
125 NULL, PROP_FAN_SPEED_UNIT_VALUE, 0, 0},
126 {"/platform/ebus@1f,464000/env-monitor@3,0", ENV_SYSTEM_FAN3,
127 NULL, PROP_FAN_SPEED_UNIT_VALUE, 0, 0},
128 {"/platform/ebus@1f,464000/env-monitor@3,0", ENV_SYSTEM_FAN4,
129 NULL, PROP_FAN_SPEED_UNIT_VALUE, 0, 0}
130 };
131 #define N_FAN_NODES (sizeof (fan_nodes)/sizeof (fan_nodes[0]))
132
133 /*
134 * Disk node data structure
135 */
136 typedef struct {
137 char *parent_path; /* parent node path */
138 char *disk_name; /* disk name */
139 env_disk_t *diskp; /* disk information */
140 picl_nodehdl_t nodeh; /* "disk" node handle */
141 picl_prophdl_t proph; /* "Temperature" property handle */
142 } disk_node_t;
143
144 /*
145 * Disk node array
146 */
147 static disk_node_t disk_nodes[] = {
148 {DISK0_NODE_PATH, ENV_DISK0, NULL, 0, 0},
149 {DISK1_NODE_PATH, ENV_DISK1, NULL, 0, 0},
150 {DISK2_NODE_PATH, ENV_DISK2, NULL, 0, 0},
151 {DISK3_NODE_PATH, ENV_DISK3, NULL, 0, 0}
152 };
153 #define N_DISK_NODES (sizeof (disk_nodes)/sizeof (disk_nodes[0]))
154
155 /*
156 * Miscellaneous declarations
157 */
158 static void delete_sensor_nodes_and_props(void);
159 static void delete_disk_nodes_and_props(void);
160 static void delete_fan_nodes_and_props(void);
161
162
163 /*
164 * Read function for volatile "Temperature" property
165 */
166 static int
get_current_temp(ptree_rarg_t * parg,void * buf)167 get_current_temp(ptree_rarg_t *parg, void *buf)
168 {
169 tempr_t temp;
170 picl_prophdl_t proph;
171 sensor_node_t *snodep;
172 int i;
173
174 /*
175 * Locate the sensor in our sensor_nodes table by matching the
176 * property handle and get its temperature.
177 */
178 proph = parg->proph;
179 for (i = 0; i < N_SENSOR_NODES; i++) {
180 snodep = &sensor_nodes[i];
181 if (snodep->proph != proph)
182 continue;
183
184 if (get_temperature(snodep->sensorp, &temp) < 0)
185 break;
186 (void) memcpy(buf, (caddr_t)&temp, sizeof (tempr_t));
187 return (PICL_SUCCESS);
188 }
189 return (PICL_FAILURE);
190 }
191
192 /*
193 * Read function for volatile "Temperature" property
194 */
195 static int
get_disk_temp(ptree_rarg_t * parg,void * buf)196 get_disk_temp(ptree_rarg_t *parg, void *buf)
197 {
198 tempr_t temp;
199 picl_prophdl_t proph;
200 disk_node_t *dnodep;
201 int i;
202
203 /*
204 * Locate the sensor in our sensor_nodes table by matching the
205 * property handle and get its temperature.
206 */
207 proph = parg->proph;
208 for (i = 0; i < N_DISK_NODES; i++) {
209 dnodep = &disk_nodes[i];
210 if (dnodep->proph != proph)
211 continue;
212
213 if (disk_temperature(dnodep->diskp, &temp) < 0)
214 break;
215 (void) memcpy(buf, (caddr_t)&temp, sizeof (tempr_t));
216 return (PICL_SUCCESS);
217 }
218 return (PICL_FAILURE);
219 }
220
221 /*
222 * Read function for volatile "Speed" property on "fan" class node
223 */
224 static int
set_current_speed(ptree_warg_t * parg,const void * buf)225 set_current_speed(ptree_warg_t *parg, const void *buf)
226 {
227 fanspeed_t speed;
228 picl_prophdl_t proph;
229 fan_node_t *fnodep;
230 int i, ret;
231
232 /*
233 * Locate the fan in our fan_nodes table by matching the
234 * property handle and get fan speed.
235 */
236 proph = parg->proph;
237 for (i = 0; i < N_FAN_NODES; i++) {
238 fnodep = &fan_nodes[i];
239 if (fnodep->proph != proph)
240 continue;
241 if (fnodep->fanp->fd == -1)
242 continue;
243
244 (void) memcpy((caddr_t)&speed, buf, sizeof (speed));
245
246 ret = set_fan_speed(fnodep->fanp, speed);
247
248 if (ret < 0) {
249 if (ret == -1 && errno == EBUSY)
250 return (PICL_NOTWRITABLE);
251 if (ret == -2)
252 return (PICL_INVALIDARG);
253 break;
254 }
255
256
257 return (PICL_SUCCESS);
258 }
259 return (PICL_FAILURE);
260 }
261
262
263 /*
264 * Read function for volatile "Speed" property on "fan" class node
265 */
266 static int
get_current_speed(ptree_rarg_t * parg,void * buf)267 get_current_speed(ptree_rarg_t *parg, void *buf)
268 {
269 fanspeed_t speed;
270 picl_prophdl_t proph;
271 fan_node_t *fnodep;
272 int i;
273
274 /*
275 * Locate the fan in our fan_nodes table by matching the
276 * property handle and get fan speed.
277 */
278 proph = parg->proph;
279 for (i = 0; i < N_FAN_NODES; i++) {
280 fnodep = &fan_nodes[i];
281 if (fnodep->proph != proph)
282 continue;
283 if (fnodep->fanp->fd == -1)
284 continue;
285 if (get_fan_speed(fnodep->fanp, &speed) < 0)
286 break;
287
288 (void) memcpy(buf, (caddr_t)&speed, sizeof (speed));
289 return (PICL_SUCCESS);
290 }
291 return (PICL_FAILURE);
292 }
293
294 /*
295 * Create and add the specified regular property
296 */
297
298 static int
add_regular_prop(picl_nodehdl_t nodeh,char * name,int type,int access,int size,void * valbuf,picl_prophdl_t * prophp)299 add_regular_prop(picl_nodehdl_t nodeh, char *name, int type, int access,
300 int size, void *valbuf, picl_prophdl_t *prophp)
301 {
302 int err;
303 ptree_propinfo_t propinfo;
304 picl_prophdl_t proph;
305
306 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
307 type, access, size, name, NULL, NULL);
308 if (err != PICL_SUCCESS)
309 return (err);
310
311 err = ptree_create_and_add_prop(nodeh, &propinfo, valbuf, &proph);
312 if (err == PICL_SUCCESS && prophp)
313 *prophp = proph;
314 return (err);
315 }
316
317
318 /*
319 * Create and add the specified volatile property
320 */
321 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)322 add_volatile_prop(picl_nodehdl_t nodeh, char *name, int type, int access,
323 int size, ptree_vol_rdfunc_t *rdfunc, ptree_vol_wrfunc_t *wrfunc,
324 picl_prophdl_t *prophp)
325 {
326 int err;
327 ptree_propinfo_t propinfo;
328 picl_prophdl_t proph;
329
330 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION,
331 type, (access|PICL_VOLATILE), size, name, rdfunc, wrfunc);
332 if (err != PICL_SUCCESS)
333 return (err);
334
335 err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, &proph);
336 if (err == PICL_SUCCESS && prophp)
337 *prophp = proph;
338 return (err);
339 }
340
341 /*
342 * Add temperature threshold properties
343 */
344 static void
add_sensor_thresh_props(picl_nodehdl_t nodeh,es_sensor_blk_t * sensor_blkp)345 add_sensor_thresh_props(picl_nodehdl_t nodeh, es_sensor_blk_t *sensor_blkp)
346 {
347 picl_prophdl_t proph;
348
349 (void) add_regular_prop(nodeh, PICL_PROP_LOW_POWER_OFF,
350 PICL_PTYPE_INT, PICL_READ,
351 sizeof (sensor_blkp->esb_low_power_off),
352 &sensor_blkp->esb_low_power_off, &proph);
353
354 (void) add_regular_prop(nodeh, PICL_PROP_LOW_SHUTDOWN,
355 PICL_PTYPE_INT, PICL_READ,
356 sizeof (sensor_blkp->esb_low_shutdown),
357 &sensor_blkp->esb_low_shutdown, &proph);
358
359 (void) add_regular_prop(nodeh, PICL_PROP_LOW_WARNING,
360 PICL_PTYPE_INT, PICL_READ,
361 sizeof (sensor_blkp->esb_low_warning),
362 &sensor_blkp->esb_low_warning, &proph);
363
364 (void) add_regular_prop(nodeh, PICL_PROP_HIGH_WARNING,
365 PICL_PTYPE_INT, PICL_READ,
366 sizeof (sensor_blkp->esb_high_warning),
367 &sensor_blkp->esb_high_warning, &proph);
368
369 (void) add_regular_prop(nodeh, PICL_PROP_HIGH_SHUTDOWN,
370 PICL_PTYPE_INT, PICL_READ,
371 sizeof (sensor_blkp->esb_high_shutdown),
372 &sensor_blkp->esb_high_shutdown, &proph);
373
374 (void) add_regular_prop(nodeh, PICL_PROP_HIGH_POWER_OFF,
375 PICL_PTYPE_INT, PICL_READ,
376 sizeof (sensor_blkp->esb_high_power_off),
377 &sensor_blkp->esb_high_power_off, &proph);
378 }
379
380
381 /*
382 * Go through the sensor_nodes array and create those nodes
383 * and the Temperature property to report the temperature.
384 */
385 static int
add_sensor_nodes_and_props()386 add_sensor_nodes_and_props()
387 {
388 int err;
389 char *pname, *nodename, *devfs_path;
390 sensor_node_t *snodep;
391 picl_nodehdl_t nodeh, cnodeh;
392 picl_prophdl_t proph;
393 env_sensor_t *sensorp;
394 es_sensor_blk_t *sensor_blkp;
395 int i;
396
397 for (i = 0; i < N_SENSOR_NODES; i++) {
398 snodep = &sensor_nodes[i];
399 /*
400 * Get the parent nodeh
401 */
402 err = ptree_get_node_by_path(snodep->parent_path, &nodeh);
403 if (err != PICL_SUCCESS) {
404 if (env_debug) {
405 envd_log(LOG_ERR,
406 "failed to get_node_by_path %s\n",
407 snodep->parent_path);
408 }
409 continue;
410 }
411 sensorp = snodep->sensorp;
412 if (sensorp == NULL)
413 continue;
414 if (sensorp->present == B_FALSE)
415 continue;
416 /*
417 * Create temperature-sensor node
418 */
419 nodename = snodep->sensor_name;
420 err = ptree_create_and_add_node(nodeh, nodename,
421 PICL_CLASS_TEMPERATURE_SENSOR, &cnodeh);
422 if (env_debug)
423 envd_log(LOG_ERR,
424 "Creating PICL sensor node '%s' err:%d\n",
425 nodename, err);
426 if (err != PICL_SUCCESS)
427 break;
428
429 /* save node handle */
430 snodep->nodeh = cnodeh;
431
432 /*
433 * Add "devfs_path" property in child node
434 */
435 devfs_path = sensorp->devfs_path;
436 pname = PICL_PROP_DEVFS_PATH;
437 err = add_regular_prop(cnodeh, pname,
438 PICL_PTYPE_CHARSTRING, PICL_READ,
439 strlen(devfs_path)+1, (void *)devfs_path, &proph);
440 if (err != PICL_SUCCESS)
441 break;
442
443 /*
444 * Now add volatile "temperature" volatile property
445 * in this "temperature-sensor" class node.
446 */
447 pname = PICL_PROP_TEMPERATURE;
448 err = add_volatile_prop(cnodeh, pname,
449 PICL_PTYPE_INT, PICL_READ, sizeof (tempr_t),
450 get_current_temp, NULL, &proph);
451 if (err != PICL_SUCCESS)
452 break;
453
454 /* Save prop handle */
455 snodep->proph = proph;
456
457 /*
458 * Add threshold related properties
459 */
460 sensor_blkp = sensorp->es;
461 if (sensor_blkp != NULL)
462 add_sensor_thresh_props(cnodeh, sensor_blkp);
463 }
464
465 if (err != PICL_SUCCESS) {
466 delete_sensor_nodes_and_props();
467 if (env_debug)
468 envd_log(LOG_INFO,
469 "Can't create prop/node for sensor '%s'\n",
470 nodename);
471 return (err);
472 }
473 return (PICL_SUCCESS);
474 }
475
476 /*
477 * Delete all sensor nodes and related properties created by the
478 * add_sensor_prop() for each sensor node in the PICL tree.
479 */
480 static void
delete_sensor_nodes_and_props(void)481 delete_sensor_nodes_and_props(void)
482 {
483 sensor_node_t *snodep;
484 int i;
485
486 /*
487 * Delete/destroy any property created in the sensed device
488 * as well as the sensor node and all properties under it.
489 * Note that deleiing/destroying a node deletes/destroys
490 * all properties within that node.
491 */
492
493 for (i = 0; i < N_SENSOR_NODES; i++) {
494 snodep = &sensor_nodes[i];
495 if (snodep->nodeh != 0) {
496 /* delete node and all properties under it */
497 (void) ptree_delete_node(snodep->nodeh);
498 (void) ptree_destroy_node(snodep->nodeh);
499 snodep->nodeh = 0;
500 snodep->proph = 0;
501 }
502 }
503 }
504
505 /*
506 * Go through the disk_nodes array and create those nodes
507 * and the Temperature property to report the temperature.
508 */
509 static int
add_disk_nodes_and_props()510 add_disk_nodes_and_props()
511 {
512 int err;
513 char *pname, *nodename, *devfs_path;
514 disk_node_t *dnodep;
515 picl_nodehdl_t nodeh, cnodeh;
516 picl_prophdl_t proph;
517 env_disk_t *diskp;
518 int i;
519
520 for (i = 0; i < N_DISK_NODES; i++) {
521 if (env_debug)
522 envd_log(LOG_ERR, "adding disk nodes...\n");
523 dnodep = &disk_nodes[i];
524 /*
525 * Get the parent nodeh
526 */
527 err = ptree_get_node_by_path(dnodep->parent_path, &nodeh);
528 if (err != PICL_SUCCESS) {
529 if (env_debug)
530 envd_log(LOG_ERR,
531 "failed to get node for path %s\n",
532 dnodep->parent_path);
533
534 err = PICL_SUCCESS;
535 continue;
536 }
537 diskp = dnodep->diskp;
538 if (diskp == NULL)
539 continue;
540 if (diskp->present == B_FALSE)
541 continue;
542 /*
543 * Create temperature-sensor node
544 */
545 nodename = dnodep->disk_name;
546 err = ptree_create_and_add_node(nodeh, nodename,
547 PICL_CLASS_TEMPERATURE_SENSOR, &cnodeh);
548 if (env_debug)
549 envd_log(LOG_ERR,
550 "Creating PICL disk node '%s' err:%d\n",
551 nodename, err);
552 if (err != PICL_SUCCESS)
553 break;
554
555 /* save node handle */
556 dnodep->nodeh = cnodeh;
557
558 /*
559 * Add "devfs_path" property in child node
560 */
561 devfs_path = diskp->devfs_path;
562 pname = PICL_PROP_DEVFS_PATH;
563 err = add_regular_prop(cnodeh, pname,
564 PICL_PTYPE_CHARSTRING, PICL_READ,
565 strlen(devfs_path)+1, (void *)devfs_path, &proph);
566 if (err != PICL_SUCCESS)
567 break;
568
569 /*
570 * Now add volatile "temperature" volatile property
571 * in this "temperature-sensor" class node.
572 */
573 pname = PICL_PROP_TEMPERATURE;
574 err = add_volatile_prop(cnodeh, pname,
575 PICL_PTYPE_INT, PICL_READ, sizeof (tempr_t),
576 get_disk_temp, NULL, &proph);
577 if (err != PICL_SUCCESS)
578 break;
579
580 /* Save prop handle */
581 dnodep->proph = proph;
582
583 /*
584 * Add threshold related properties
585 */
586
587 (void) add_regular_prop(cnodeh, PICL_PROP_LOW_SHUTDOWN,
588 PICL_PTYPE_INT, PICL_READ,
589 sizeof (diskp->low_shutdown),
590 (void *)&(diskp->low_shutdown), &proph);
591
592 (void) add_regular_prop(cnodeh, PICL_PROP_LOW_WARNING,
593 PICL_PTYPE_INT, PICL_READ,
594 sizeof (diskp->low_warning),
595 (void *)&(diskp->low_warning), &proph);
596
597 (void) add_regular_prop(cnodeh, PICL_PROP_HIGH_WARNING,
598 PICL_PTYPE_INT, PICL_READ,
599 sizeof (diskp->high_warning),
600 (void *)&(diskp->high_warning), &proph);
601
602 (void) add_regular_prop(cnodeh, PICL_PROP_HIGH_SHUTDOWN,
603 PICL_PTYPE_INT, PICL_READ,
604 sizeof (diskp->high_shutdown),
605 (void *)&(diskp->high_shutdown), &proph);
606
607 }
608 if (err != PICL_SUCCESS) {
609 delete_disk_nodes_and_props();
610 if (env_debug)
611 envd_log(LOG_INFO,
612 "Can't create prop/node for disk '%s'\n",
613 nodename);
614 return (err);
615 }
616 return (PICL_SUCCESS);
617 }
618
619 /*
620 * Delete all disk nodes and related properties created by the
621 * add_disk_props() for each disk node in the PICL tree.
622 */
623 static void
delete_disk_nodes_and_props(void)624 delete_disk_nodes_and_props(void)
625 {
626 disk_node_t *dnodep;
627 int i;
628
629 /*
630 * Delete/destroy disk node and all properties under it.
631 * Note that deleting/destroying a node deletes/destroys
632 * all properties within that node.
633 */
634
635 for (i = 0; i < N_DISK_NODES; i++) {
636 dnodep = &disk_nodes[i];
637 if (dnodep->nodeh != 0) {
638 (void) ptree_delete_node(dnodep->nodeh);
639 (void) ptree_destroy_node(dnodep->nodeh);
640 dnodep->nodeh = 0;
641 dnodep->proph = 0;
642 }
643 }
644 }
645
646 /*
647 * For each entry in fan_nodes[] array, do the following:
648 * - Create specified "fan" class node.
649 * - Create "Speed" volatile propery under "fan" class node.
650 * - Create "SpeedUnit" property under "fan" class node.
651 */
652 static int
add_fan_nodes_and_props()653 add_fan_nodes_and_props()
654 {
655 int err = PICL_FAILURE;
656 char *pname, *nodename, *devfs_path;
657 env_fan_t *fanp;
658 fan_node_t *fnodep;
659 picl_nodehdl_t nodeh, cnodeh;
660 picl_prophdl_t proph;
661 int i;
662
663 for (i = 0; i < N_FAN_NODES; i++) {
664 /*
665 * Add various fan nodes and properties
666 */
667 fnodep = &fan_nodes[i];
668 if (fnodep == NULL)
669 continue;
670 if (fnodep->fanp == NULL)
671 continue;
672 if (fnodep->fanp->present == B_FALSE)
673 continue;
674 /*
675 * get parent nodeh
676 */
677 err = ptree_get_node_by_path(fnodep->parent_path, &nodeh);
678 if (err != PICL_SUCCESS) {
679 if (env_debug)
680 envd_log(LOG_ERR,
681 "node for %s NOT FOUND.\n", fnodep->parent_path);
682 err = PICL_SUCCESS;
683 continue;
684 }
685 /*
686 * Create "fan" class node and save node handle
687 */
688 nodename = fnodep->fan_name;
689 err = ptree_create_and_add_node(nodeh, nodename,
690 PICL_CLASS_FAN, &cnodeh);
691 if (env_debug)
692 envd_log(LOG_ERR,
693 "Creating PICL fan node '%s' err:%d\n",
694 nodename, err);
695
696 if (err != PICL_SUCCESS)
697 break;
698 fnodep->nodeh = cnodeh;
699
700 /*
701 * Add "devfs_path" property in child node
702 */
703 fanp = fnodep->fanp;
704 devfs_path = fanp->devfs_path;
705 pname = PICL_PROP_DEVFS_PATH;
706 err = add_regular_prop(cnodeh, pname,
707 PICL_PTYPE_CHARSTRING, PICL_READ,
708 strlen(devfs_path)+1, (void *)devfs_path, &proph);
709
710 if (err != PICL_SUCCESS)
711
712 break;
713
714 /*
715 * Add "Speed" volatile property in this "fan"
716 * class node and save prop handle.
717 */
718 pname = PICL_PROP_FAN_SPEED;
719
720 err = add_volatile_prop(cnodeh, pname, PICL_PTYPE_INT,
721 PICL_READ|PICL_WRITE, sizeof (fanspeed_t),
722 get_current_speed, set_current_speed, &proph);
723
724 if (err != PICL_SUCCESS)
725 break;
726 fnodep->proph = proph;
727
728 /*
729 * Add other "fan" class properties
730 */
731 pname = PICL_PROP_FAN_SPEED_UNIT;
732 err = add_regular_prop(cnodeh, pname,
733 PICL_PTYPE_CHARSTRING, PICL_READ,
734 strlen(fnodep->speed_unit)+1,
735 (void *)fnodep->speed_unit, &proph);
736
737 if (err != PICL_SUCCESS)
738 break;
739
740 pname = PICL_PROP_LOW_WARNING;
741 err = add_regular_prop(cnodeh, pname,
742 PICL_PTYPE_INT, PICL_READ,
743 sizeof (fanspeed_t),
744 &(fnodep->fanp->speed_min), &proph);
745
746 if (err != PICL_SUCCESS)
747 break;
748 }
749 if (err != PICL_SUCCESS) {
750 delete_fan_nodes_and_props();
751 return (err);
752 }
753 return (PICL_SUCCESS);
754 }
755
756
757 /*
758 * Delete all fan nodes and related properties created by the
759 * add_fan_props() for each fan node in the PICL tree.
760 */
761 static void
delete_fan_nodes_and_props(void)762 delete_fan_nodes_and_props(void)
763 {
764 fan_node_t *fnodep;
765 int i;
766
767 /*
768 * Delete/destroy fan node and all properties under it.
769 * Note that deleting/destroying a node deletes/destroys
770 * all properties within that node.
771 */
772
773 for (i = 0; i < N_FAN_NODES; i++) {
774 fnodep = &fan_nodes[i];
775 if (fnodep->nodeh != 0) {
776 (void) ptree_delete_node(fnodep->nodeh);
777 (void) ptree_destroy_node(fnodep->nodeh);
778 fnodep->nodeh = 0;
779 }
780 }
781 }
782 /*
783 * Tuneables publishing functions
784 */
785 static int
copy_persistent_tuneable(env_tuneable_t * tune,char * buf)786 copy_persistent_tuneable(env_tuneable_t *tune, char *buf)
787 {
788
789 switch (tune->type) {
790 case PICL_PTYPE_INT : {
791 (void) memcpy((int *)tune->value,
792 buf, tune->nbytes);
793 break;
794 }
795 case PICL_PTYPE_CHARSTRING : {
796 (void) memcpy((caddr_t)tune->value,
797 buf, tune->nbytes);
798 break;
799 }
800 default : {
801 return (PICL_FAILURE);
802 }
803 }
804 return (PICL_SUCCESS);
805 }
806
807 static void
env_parse_tunables(picl_nodehdl_t rooth)808 env_parse_tunables(picl_nodehdl_t rooth)
809 {
810 char nmbuf[SYS_NMLN];
811 char pname[PATH_MAX];
812
813 if (sysinfo(SI_PLATFORM, nmbuf, sizeof (nmbuf)) != -1) {
814 (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
815 (void) strlcat(pname, TUNABLE_CONF_FILE, PATH_MAX);
816 if (access(pname, R_OK) == 0) {
817 (void) picld_pluginutil_parse_config_file(rooth, pname);
818 return;
819 }
820 }
821 }
822
823 int
env_picl_setup_tuneables(void)824 env_picl_setup_tuneables(void)
825 {
826 int err;
827 int i;
828 picl_nodehdl_t nodeh;
829 picl_nodehdl_t rooth;
830 picl_prophdl_t proph;
831 env_tuneable_t *tuneablep;
832 char read_buf[BUFSIZ];
833
834 if (ptree_get_root(&rooth) != PICL_SUCCESS) {
835 return (PICL_FAILURE);
836 }
837 err = ptree_create_and_add_node(rooth, PICL_PLUGINS_NODE,
838 PICL_CLASS_PICL, &nodeh);
839 if (err != PICL_SUCCESS)
840 return (PICL_FAILURE);
841 err = ptree_create_and_add_node(nodeh, PICL_ENVIRONMENTAL_NODE,
842 PICL_CLASS_PICL, &nodeh);
843 if (err != PICL_SUCCESS) {
844 return (PICL_FAILURE);
845 }
846
847 /*
848 * Parse the conf file
849 */
850 if (env_debug)
851 envd_log(LOG_ERR, "parsing tuneables...\n");
852 env_parse_tunables(rooth);
853 for (i = 0; i < ntuneables; i++) {
854 if (env_debug)
855 envd_log(LOG_ERR, "tuneable %d being added\n", i);
856 tuneablep = &tuneables[i];
857 err = ptree_get_propval_by_name(nodeh, tuneablep->name,
858 read_buf, tuneablep->nbytes);
859
860 if (err != PICL_SUCCESS) {
861 /*
862 * Add volitle functions to environmental node
863 */
864 err = add_volatile_prop(nodeh, tuneablep->name,
865 tuneablep->type,
866 PICL_READ|PICL_WRITE, tuneablep->nbytes,
867 tuneablep->rfunc,
868 tuneablep->wfunc, &proph);
869
870 tuneablep->proph = proph;
871 } else {
872 /*
873 * property is persistent
874 */
875 (void) copy_persistent_tuneable(tuneablep,
876 read_buf);
877 }
878 }
879
880 return (PICL_SUCCESS);
881 }
882
883 /*
884 * Find the ENVMODEL_CONF_FILE file.
885 */
886 static int
get_envmodel_conf_file(char * outfilename)887 get_envmodel_conf_file(char *outfilename)
888 {
889 char nmbuf[SYS_NMLN];
890 char pname[PATH_MAX];
891
892 if (sysinfo(SI_PLATFORM, nmbuf, sizeof (nmbuf)) != -1) {
893 (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
894 (void) strlcat(pname, ENV_CONF_FILE, PATH_MAX);
895 if (access(pname, R_OK) == 0) {
896 (void) strlcpy(outfilename, pname, PATH_MAX);
897 return (0);
898 }
899 }
900
901 if (sysinfo(SI_MACHINE, nmbuf, sizeof (nmbuf)) != -1) {
902 (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf);
903 (void) strlcat(pname, ENV_CONF_FILE, PATH_MAX);
904 if (access(pname, R_OK) == 0) {
905 (void) strlcpy(outfilename, pname, PATH_MAX);
906 return (0);
907 }
908 }
909
910 (void) snprintf(pname, PATH_MAX, "%s/%s", PICLD_COMMON_PLUGIN_DIR,
911 ENV_CONF_FILE);
912
913 if (access(pname, R_OK) == 0) {
914 (void) strlcpy(outfilename, pname, PATH_MAX);
915 return (0);
916 }
917
918 return (-1);
919 }
920
921 /* Delete all sensor/fan nodes and any properties created by this plugin */
922 void
env_picl_destroy(void)923 env_picl_destroy(void)
924 {
925 delete_fan_nodes_and_props();
926 delete_sensor_nodes_and_props();
927 delete_disk_nodes_and_props();
928 }
929
930 void
env_picl_setup(void)931 env_picl_setup(void)
932 {
933 int err, sensor_err, fan_err, disk_err;
934 sensor_node_t *snodep;
935 fan_node_t *fnodep;
936 disk_node_t *dnodep;
937 picl_nodehdl_t plath;
938 char fullfilename[PATH_MAX];
939 picl_nodehdl_t rooth;
940 int i;
941
942
943 /*
944 * Initialize sensorp and other fields in the sensor_nodes[] array
945 */
946
947 for (i = 0; i < N_SENSOR_NODES; i++) {
948 snodep = &sensor_nodes[i];
949 snodep->sensorp = sensor_lookup(snodep->sensor_name);
950 snodep->nodeh = 0;
951 snodep->proph = 0;
952 snodep->target_proph = 0;
953 }
954
955 /*
956 * Initialize fanp and other fields in the fan_nodes[] array
957 */
958 for (i = 0; i < N_FAN_NODES; i++) {
959 fnodep = &fan_nodes[i];
960 fnodep->fanp = fan_lookup(fnodep->fan_name);
961 fnodep->nodeh = 0;
962 fnodep->proph = 0;
963 }
964
965 /*
966 * Initialize diskp and other fields in the disk_nodes[] array
967 */
968 for (i = 0; i < N_DISK_NODES; i++) {
969 dnodep = &disk_nodes[i];
970 dnodep->diskp = disk_lookup(dnodep->disk_name);
971 dnodep->nodeh = 0;
972 dnodep->proph = 0;
973 }
974
975 /*
976 * Get platform handle and populate PICL tree with environmental
977 * nodes and properties
978 */
979 err = ptree_get_node_by_path("/platform", &plath);
980
981 if (err == PICL_SUCCESS) {
982 sensor_err = add_sensor_nodes_and_props();
983 fan_err = add_fan_nodes_and_props();
984 if (disk_temp_monitor)
985 disk_err = add_disk_nodes_and_props();
986 }
987
988 /*
989 * We can safely call delete_xxx_nodes_and_props even
990 * if nodes were not added.
991 */
992
993 if (err != PICL_SUCCESS) {
994 if (fan_err != PICL_SUCCESS)
995 delete_fan_nodes_and_props();
996 if (disk_err != PICL_SUCCESS)
997 delete_disk_nodes_and_props();
998 if (sensor_err != PICL_SUCCESS)
999 delete_sensor_nodes_and_props();
1000
1001 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
1002 return;
1003 }
1004 if (env_debug)
1005 envd_log(LOG_ERR, "parsing the envmodel.conf file...\n");
1006
1007 /*
1008 * Parse the envmodel.conf file and populate the PICL tree
1009 */
1010 if (get_envmodel_conf_file(fullfilename) < 0)
1011 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
1012 if (ptree_get_root(&rooth) != PICL_SUCCESS)
1013 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
1014 err = picld_pluginutil_parse_config_file(rooth, fullfilename);
1015
1016 if (err != PICL_SUCCESS)
1017 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED);
1018 }
1019