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