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 2004 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 <errno.h> 39 #include <limits.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 62 extern sensor_ctrl_blk_t sensor_ctrl[]; 63 extern fan_ctrl_blk_t fan_ctrl[]; 64 extern env_tuneable_t tuneables[]; 65 extern int ntuneables; 66 67 #define PROP_FAN_SPEED_UNIT_VALUE "rpm" 68 69 /* 70 * Sensor node data structure 71 */ 72 typedef struct { 73 char *parent_path; /* parent path */ 74 char *sensor_name; /* sensor name */ 75 env_sensor_t *sensorp; /* sensor info */ 76 picl_nodehdl_t nodeh; /* sensor node handle */ 77 picl_prophdl_t proph; /* "Temperature" property handle */ 78 picl_prophdl_t target_proph; /* "TargetTemp" property handle */ 79 } sensor_node_t; 80 81 82 /* 83 * Sensor nodes array 84 */ 85 static sensor_node_t sensor_nodes[] = { 86 {"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c", 87 SENSOR_CPU_DIE, NULL, 88 0, 0, 0}, 89 90 {"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c", 91 SENSOR_INT_AMB, NULL, 92 0, 0, 0}, 93 94 {"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c", 95 SENSOR_SYS_IN, NULL, 96 0, 0, 0} 97 }; 98 #define NSENSORS (sizeof (sensor_nodes)/sizeof (sensor_nodes[0])) 99 100 101 /* 102 * Fan node data structure 103 */ 104 typedef struct { 105 char *parent_path; /* parent node path */ 106 char *fan_name; /* fan name */ 107 env_fan_t *fanp; /* fan information */ 108 char *speed_unit; /* speed unit string */ 109 picl_nodehdl_t nodeh; /* "fan" node handle */ 110 picl_prophdl_t proph; /* "Speed" property handle */ 111 } fan_node_t; 112 113 114 /* 115 * Fan node array 116 */ 117 static fan_node_t fan_nodes[] = { 118 {"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c", 119 ENV_CPU_FAN, NULL, PROP_FAN_SPEED_UNIT_VALUE, 0, 0}, 120 121 {"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c", 122 ENV_SYSTEM_INTAKE_FAN, NULL, PROP_FAN_SPEED_UNIT_VALUE, 0, 0}, 123 124 {"/platform/pci@1e,600000/isa@7/i2c@0,320/hardware-monitor@0,5c", 125 ENV_SYSTEM_OUT_FAN, NULL, PROP_FAN_SPEED_UNIT_VALUE, 0, 0} 126 }; 127 #define NFANS (sizeof (fan_nodes)/sizeof (fan_nodes[0])) 128 129 /* 130 * Miscellaneous declarations 131 */ 132 static void delete_sensor_nodes_and_props(void); 133 static void delete_fan_nodes_and_props(void); 134 135 136 /* 137 * Read function for volatile "Temperature" property 138 */ 139 static int 140 get_current_temp(ptree_rarg_t *parg, void *buf) 141 { 142 tempr_t temp; 143 picl_prophdl_t proph; 144 sensor_node_t *snodep; 145 int i; 146 147 /* 148 * Locate the sensor in our sensor_nodes table by matching the 149 * property handle and get its temperature. 150 */ 151 proph = parg->proph; 152 for (i = 0; i < NSENSORS; ++i) { 153 snodep = &sensor_nodes[i]; 154 if (snodep->proph != proph) 155 continue; 156 157 if (get_temperature(snodep->sensorp, &temp) < 0) 158 break; 159 (void) memcpy(buf, (caddr_t)&temp, sizeof (tempr_t)); 160 return (PICL_SUCCESS); 161 } 162 return (PICL_FAILURE); 163 } 164 /* 165 * Read function for volatile "Speed" property on "fan" class node 166 */ 167 static int 168 set_current_speed(ptree_warg_t *parg, const void *buf) 169 { 170 fanspeed_t speed; 171 picl_prophdl_t proph; 172 fan_node_t *fnodep; 173 int i, ret; 174 175 /* 176 * Locate the fan in our fan_nodes table by matching the 177 * property handle and get fan speed. 178 */ 179 proph = parg->proph; 180 for (i = 0; i < NFANS; ++i) { 181 fnodep = &fan_nodes[i]; 182 if (fnodep->proph != proph) 183 continue; 184 if (fnodep->fanp->fd == -1) 185 continue; 186 187 (void) memcpy((caddr_t)&speed, buf, sizeof (speed)); 188 189 ret = set_fan_speed(fnodep->fanp, speed); 190 191 if (ret < 0) { 192 if (ret == -1 && errno == EBUSY) 193 return (PICL_NOTWRITABLE); 194 if (ret == -2) 195 return (PICL_INVALIDARG); 196 break; 197 } 198 199 return (PICL_SUCCESS); 200 } 201 return (PICL_FAILURE); 202 } 203 204 205 /* 206 * Read function for volatile "Speed" property on "fan" class node 207 */ 208 static int 209 get_current_speed(ptree_rarg_t *parg, void *buf) 210 { 211 fanspeed_t speed; 212 picl_prophdl_t proph; 213 fan_node_t *fnodep; 214 int i; 215 216 /* 217 * Locate the fan in our fan_nodes table by matching the 218 * property handle and get fan speed. 219 */ 220 proph = parg->proph; 221 for (i = 0; i < NFANS; ++i) { 222 fnodep = &fan_nodes[i]; 223 if (fnodep->proph != proph) 224 continue; 225 if (fnodep->fanp->fd == -1) 226 continue; 227 if (get_fan_speed(fnodep->fanp, &speed) < 0) 228 break; 229 230 (void) memcpy(buf, (caddr_t)&speed, sizeof (speed)); 231 return (PICL_SUCCESS); 232 } 233 return (PICL_FAILURE); 234 } 235 236 /* 237 * Create and add the specified regular property 238 */ 239 240 static int 241 add_regular_prop(picl_nodehdl_t nodeh, char *name, int type, int access, 242 int size, void *valbuf, picl_prophdl_t *prophp) 243 { 244 int err; 245 ptree_propinfo_t propinfo; 246 picl_prophdl_t proph; 247 248 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, 249 type, access, size, name, NULL, NULL); 250 if (err != PICL_SUCCESS) 251 return (err); 252 253 err = ptree_create_and_add_prop(nodeh, &propinfo, valbuf, &proph); 254 if (err == PICL_SUCCESS && prophp) 255 *prophp = proph; 256 return (err); 257 } 258 259 260 /* 261 * Create and add the specified volatile property 262 */ 263 static int 264 add_volatile_prop(picl_nodehdl_t nodeh, char *name, int type, int access, 265 int size, ptree_vol_rdfunc_t *rdfunc, ptree_vol_wrfunc_t *wrfunc, 266 picl_prophdl_t *prophp) 267 { 268 int err; 269 ptree_propinfo_t propinfo; 270 picl_prophdl_t proph; 271 272 err = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, 273 type, (access|PICL_VOLATILE), size, name, rdfunc, wrfunc); 274 if (err != PICL_SUCCESS) 275 return (err); 276 277 err = ptree_create_and_add_prop(nodeh, &propinfo, NULL, &proph); 278 if (err == PICL_SUCCESS && prophp) 279 *prophp = proph; 280 return (err); 281 } 282 283 /* 284 * Add temperature threshold properties 285 */ 286 static void 287 add_sensor_thresh_props(picl_nodehdl_t nodeh, sensor_ctrl_blk_t *threshp) 288 { 289 picl_prophdl_t proph; 290 291 (void) add_regular_prop(nodeh, PICL_PROP_LOW_POWER_OFF, 292 PICL_PTYPE_INT, PICL_READ, 293 sizeof (threshp->low_power_off), 294 (void *)&(threshp->low_power_off), &proph); 295 296 (void) add_regular_prop(nodeh, PICL_PROP_LOW_SHUTDOWN, 297 PICL_PTYPE_INT, PICL_READ, 298 sizeof (threshp->low_shutdown), 299 (void *)&(threshp->low_shutdown), &proph); 300 301 (void) add_regular_prop(nodeh, PICL_PROP_LOW_WARNING, 302 PICL_PTYPE_INT, PICL_READ, 303 sizeof (threshp->low_warning), 304 (void *)&(threshp->low_warning), &proph); 305 306 (void) add_regular_prop(nodeh, PICL_PROP_HIGH_WARNING, 307 PICL_PTYPE_INT, PICL_READ, 308 sizeof (threshp->high_warning), 309 (void *)&(threshp->high_warning), &proph); 310 311 (void) add_regular_prop(nodeh, PICL_PROP_HIGH_SHUTDOWN, 312 PICL_PTYPE_INT, PICL_READ, 313 sizeof (threshp->high_shutdown), 314 (void *)&(threshp->high_shutdown), &proph); 315 316 (void) add_regular_prop(nodeh, PICL_PROP_HIGH_POWER_OFF, 317 PICL_PTYPE_INT, PICL_READ, 318 sizeof (threshp->high_power_off), 319 (void *)&(threshp->high_power_off), &proph); 320 } 321 322 /* 323 * Go through the sensor_nodes array and create those nodes 324 * and the Temperature property to report the temperature. 325 */ 326 static int 327 add_sensor_nodes_and_props(void) 328 { 329 int err; 330 char *pname, *nodename, *devfs_path; 331 sensor_node_t *snodep; 332 sensor_ctrl_blk_t *threshp; 333 picl_nodehdl_t nodeh, cnodeh; 334 picl_prophdl_t proph; 335 env_sensor_t *sensorp; 336 int i; 337 338 for (i = 0; i < NSENSORS; ++i) { 339 snodep = &sensor_nodes[i]; 340 /* 341 * Get the parent nodeh 342 */ 343 err = ptree_get_node_by_path(snodep->parent_path, &nodeh); 344 if (err != PICL_SUCCESS) 345 continue; 346 sensorp = snodep->sensorp; 347 348 /* 349 * Create temperature-sensor node 350 */ 351 nodename = snodep->sensor_name; 352 err = ptree_create_and_add_node(nodeh, nodename, 353 PICL_CLASS_TEMPERATURE_SENSOR, &cnodeh); 354 if (env_debug) 355 envd_log(LOG_INFO, 356 "Creating PICL sensor node '%s' err:%d\n", 357 nodename, err); 358 if (err != PICL_SUCCESS) 359 break; 360 361 /* save node handle */ 362 snodep->nodeh = cnodeh; 363 364 /* 365 * Add "devfs_path" property in child node 366 */ 367 devfs_path = sensorp->devfs_path; 368 pname = PICL_PROP_DEVFS_PATH; 369 err = add_regular_prop(cnodeh, pname, 370 PICL_PTYPE_CHARSTRING, PICL_READ, 371 strlen(devfs_path)+1, (void *)devfs_path, &proph); 372 if (err != PICL_SUCCESS) 373 break; 374 375 /* 376 * Now add volatile "temperature" volatile property 377 * in this "temperature-sensor" class node. 378 */ 379 pname = PICL_PROP_TEMPERATURE; 380 err = add_volatile_prop(cnodeh, pname, 381 PICL_PTYPE_INT, PICL_READ, sizeof (tempr_t), 382 get_current_temp, NULL, &proph); 383 if (err != PICL_SUCCESS) 384 break; 385 386 /* Save prop handle */ 387 snodep->proph = proph; 388 389 /* 390 * Add threshold related properties 391 */ 392 threshp = sensorp->es_ptr; 393 394 if (threshp != NULL) 395 add_sensor_thresh_props(cnodeh, threshp); 396 397 } 398 if (err != PICL_SUCCESS) { 399 delete_sensor_nodes_and_props(); 400 if (env_debug) 401 envd_log(LOG_INFO, 402 "Can't create prop/node for sensor '%s'\n", 403 nodename); 404 return (err); 405 } 406 return (PICL_SUCCESS); 407 } 408 409 /* 410 * Delete all sensor nodes and related properties created by the 411 * add_sensor_prop() for each sensor node in the PICL tree. 412 */ 413 static void 414 delete_sensor_nodes_and_props(void) 415 { 416 sensor_node_t *snodep; 417 int i; 418 419 /* 420 * Delete/destroy any property created in the sensed device 421 * as well as the sensor node and all properties under it. 422 * Note that deleiing/destroying a node deletes/destroys 423 * all properties within that node. 424 */ 425 426 for (i = 0; i < NSENSORS; ++i) { 427 snodep = &sensor_nodes[i]; 428 if (snodep->nodeh != 0) { 429 /* delete node and all properties under it */ 430 (void) ptree_delete_node(snodep->nodeh); 431 (void) ptree_destroy_node(snodep->nodeh); 432 snodep->nodeh = 0; 433 snodep->proph = 0; 434 } 435 } 436 } 437 438 439 /* 440 * For each entry in fan_nodes[] array, do the following: 441 * - Create specified "fan" class node. 442 * - Create "Speed" volatile propery under "fan" class node. 443 * - Create "SpeedUnit" property under "fan" class node. 444 */ 445 static int 446 add_fan_nodes_and_props() 447 { 448 int err; 449 char *pname, *nodename, *devfs_path; 450 env_fan_t *fanp; 451 fan_node_t *fnodep; 452 picl_nodehdl_t nodeh, cnodeh; 453 picl_prophdl_t proph; 454 int i; 455 456 457 for (i = 0; i < NFANS; ++i) { 458 /* 459 * Add various fan nodes and properties 460 */ 461 fnodep = &fan_nodes[i]; 462 /* 463 * get parent nodeh 464 */ 465 err = ptree_get_node_by_path(fnodep->parent_path, &nodeh); 466 if (err != PICL_SUCCESS) 467 continue; 468 469 /* 470 * Create "fan" class node and save node handle 471 */ 472 nodename = fnodep->fan_name; 473 err = ptree_create_and_add_node(nodeh, nodename, 474 PICL_CLASS_FAN, &cnodeh); 475 if (env_debug) 476 envd_log(LOG_INFO, 477 "Creating PICL fan node '%s' err:%d\n", 478 nodename, err); 479 480 if (err != PICL_SUCCESS) 481 break; 482 fnodep->nodeh = cnodeh; 483 484 /* 485 * Add "devfs_path" property in child node 486 */ 487 fanp = fnodep->fanp; 488 devfs_path = fanp->devfs_path; 489 pname = PICL_PROP_DEVFS_PATH; 490 err = add_regular_prop(cnodeh, pname, 491 PICL_PTYPE_CHARSTRING, PICL_READ, 492 strlen(devfs_path)+1, (void *)devfs_path, &proph); 493 494 if (err != PICL_SUCCESS) 495 496 break; 497 498 /* 499 * Add "Speed" volatile property in this "fan" 500 * class node and save prop handle. 501 */ 502 pname = PICL_PROP_FAN_SPEED; 503 err = add_volatile_prop(cnodeh, pname, PICL_PTYPE_INT, 504 PICL_READ|PICL_WRITE, sizeof (fanspeed_t), 505 get_current_speed, 506 set_current_speed, &proph); 507 508 if (err != PICL_SUCCESS) 509 break; 510 fnodep->proph = proph; 511 512 /* 513 * Add other "fan" class properties 514 */ 515 pname = PICL_PROP_FAN_SPEED_UNIT; 516 err = add_regular_prop(cnodeh, pname, 517 PICL_PTYPE_CHARSTRING, PICL_READ, 518 strlen(fnodep->speed_unit)+1, 519 (void *)fnodep->speed_unit, &proph); 520 521 if (err != PICL_SUCCESS) 522 break; 523 } 524 if (err != PICL_SUCCESS) { 525 delete_fan_nodes_and_props(); 526 if (env_debug) 527 envd_log(LOG_WARNING, 528 "Can't create prop/node for fan '%s'\n", 529 nodename); 530 return (err); 531 } 532 return (PICL_SUCCESS); 533 } 534 535 536 /* 537 * Delete all fan nodes and related properties created by the 538 * add_fan_props() for each fan node in the PICL tree. 539 */ 540 static void 541 delete_fan_nodes_and_props(void) 542 { 543 fan_node_t *fnodep; 544 int i; 545 546 /* 547 * Delete/destroy fan node and all properties under it. 548 * Note that deleiing/destroying a node deletes/destroys 549 * all properties within that node. 550 */ 551 552 for (i = 0; i < NFANS; ++i) { 553 fnodep = &fan_nodes[i]; 554 if (fnodep->nodeh != 0) { 555 (void) ptree_delete_node(fnodep->nodeh); 556 (void) ptree_destroy_node(fnodep->nodeh); 557 fnodep->nodeh = 0; 558 } 559 } 560 } 561 562 /* 563 * Tuneables publishing functions 564 */ 565 static int 566 copy_persistent_tuneable(env_tuneable_t *tune, char *buf) 567 { 568 569 switch (tune->type) { 570 571 case PICL_PTYPE_INT : { 572 (void) memcpy((int *)tune->value, 573 buf, tune->nbytes); 574 break; 575 } 576 case PICL_PTYPE_CHARSTRING : { 577 (void) memcpy((caddr_t)tune->value, 578 buf, tune->nbytes); 579 break; 580 } 581 default : { 582 return (PICL_FAILURE); 583 } 584 } 585 return (PICL_SUCCESS); 586 } 587 588 static void 589 env_parse_tunables(picl_nodehdl_t rooth) 590 { 591 char nmbuf[SYS_NMLN]; 592 char pname[PATH_MAX]; 593 594 if (sysinfo(SI_PLATFORM, nmbuf, sizeof (nmbuf)) != -1) { 595 (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf); 596 (void) strlcat(pname, TUNABLE_CONF_FILE, PATH_MAX); 597 if (access(pname, R_OK) == 0) { 598 (void) picld_pluginutil_parse_config_file(rooth, pname); 599 return; 600 } 601 } 602 } 603 604 int 605 env_picl_setup_tuneables(void) 606 { 607 int err; 608 int i; 609 picl_nodehdl_t nodeh; 610 picl_nodehdl_t rooth; 611 picl_prophdl_t proph; 612 env_tuneable_t *tuneablep; 613 char read_buf[BUFSIZ]; 614 615 if (ptree_get_root(&rooth) != PICL_SUCCESS) { 616 return (PICL_FAILURE); 617 } 618 err = ptree_create_and_add_node(rooth, PICL_PLUGINS_NODE, 619 PICL_CLASS_PICL, &nodeh); 620 if (err != PICL_SUCCESS) 621 return (PICL_FAILURE); 622 err = ptree_create_and_add_node(nodeh, PICL_ENVIRONMENTAL_NODE, 623 PICL_CLASS_PICL, &nodeh); 624 if (err != PICL_SUCCESS) { 625 return (PICL_FAILURE); 626 } 627 628 /* 629 * Parse the conf file 630 */ 631 env_parse_tunables(rooth); 632 for (i = 0; i < ntuneables; i++) { 633 tuneablep = &tuneables[i]; 634 err = ptree_get_propval_by_name(nodeh, tuneablep->name, 635 read_buf, tuneablep->nbytes); 636 637 if (err != PICL_SUCCESS) { 638 /* 639 * Add volitle functions to environmental node 640 */ 641 err = add_volatile_prop(nodeh, tuneablep->name, 642 tuneablep->type, 643 PICL_READ|PICL_WRITE, tuneablep->nbytes, 644 tuneablep->rfunc, 645 tuneablep->wfunc, &proph); 646 647 tuneablep->proph = proph; 648 } else { 649 /* 650 * property is persistent 651 */ 652 (void) copy_persistent_tuneable(tuneablep, 653 read_buf); 654 } 655 } 656 657 return (PICL_SUCCESS); 658 } 659 660 /* 661 * Find the ENVMODEL_CONF_FILE file. 662 */ 663 static int 664 get_envmodel_conf_file(char *outfilename) 665 { 666 char nmbuf[SYS_NMLN]; 667 char pname[PATH_MAX]; 668 669 if (sysinfo(SI_PLATFORM, nmbuf, sizeof (nmbuf)) != -1) { 670 (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf); 671 (void) strlcat(pname, ENV_CONF_FILE, PATH_MAX); 672 if (access(pname, R_OK) == 0) { 673 (void) strlcpy(outfilename, pname, PATH_MAX); 674 return (0); 675 } 676 } 677 678 if (sysinfo(SI_MACHINE, nmbuf, sizeof (nmbuf)) != -1) { 679 (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf); 680 (void) strlcat(pname, ENV_CONF_FILE, PATH_MAX); 681 if (access(pname, R_OK) == 0) { 682 (void) strlcpy(outfilename, pname, PATH_MAX); 683 return (0); 684 } 685 } 686 687 (void) snprintf(pname, PATH_MAX, "%s/%s", PICLD_COMMON_PLUGIN_DIR, 688 ENV_CONF_FILE); 689 690 if (access(pname, R_OK) == 0) { 691 (void) strlcpy(outfilename, pname, PATH_MAX); 692 return (0); 693 } 694 695 return (-1); 696 } 697 698 /* Delete all sensor/fan nodes and any properties created by this plugin */ 699 void 700 env_picl_destroy(void) 701 { 702 delete_fan_nodes_and_props(); 703 delete_sensor_nodes_and_props(); 704 } 705 706 void 707 env_picl_setup(void) 708 { 709 int err; 710 sensor_node_t *snodep; 711 fan_node_t *fnodep; 712 char fullfilename[PATH_MAX]; 713 picl_nodehdl_t rooth; 714 int i; 715 716 717 /* 718 * Initialize sensorp and other fields in the sensor_nodes[] array 719 */ 720 721 for (i = 0; i < NSENSORS; ++i) { 722 snodep = &sensor_nodes[i]; 723 snodep->sensorp = sensor_lookup(snodep->sensor_name); 724 snodep->nodeh = 0; 725 snodep->proph = 0; 726 snodep->target_proph = 0; 727 } 728 729 /* 730 * Initialize fanp and other fields in the fan_nodes[] array 731 */ 732 for (i = 0; i < NFANS; ++i) { 733 fnodep = &fan_nodes[i]; 734 fnodep->fanp = fan_lookup(fnodep->fan_name); 735 fnodep->nodeh = 0; 736 fnodep->proph = 0; 737 } 738 739 /* 740 * Get platform handle and populate PICL tree with environmental 741 * nodes and properties 742 */ 743 744 err = add_sensor_nodes_and_props(); 745 746 if (err == PICL_SUCCESS) 747 err = add_fan_nodes_and_props(); 748 749 750 if (err != PICL_SUCCESS) { 751 delete_sensor_nodes_and_props(); 752 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED); 753 return; 754 } 755 756 /* 757 * Parse the envmodel.conf file and populate the PICL tree 758 */ 759 if (get_envmodel_conf_file(fullfilename) < 0) 760 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED); 761 if (ptree_get_root(&rooth) != PICL_SUCCESS) 762 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED); 763 err = picld_pluginutil_parse_config_file(rooth, fullfilename); 764 765 if (err != PICL_SUCCESS) 766 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED); 767 } 768