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