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