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 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 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 * 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 * 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 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 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 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 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 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 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 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 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 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 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 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