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 #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 <limits.h> 41 #include <errno.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 extern int disk_temp_monitor; 64 extern env_tuneable_t tuneables[]; 65 extern int errno; 66 extern int ntuneables; 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 * Sensor nodes array 83 */ 84 static sensor_node_t sensor_nodes[] = { 85 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_CPU0, 86 NULL, NULL, NULL, NULL}, 87 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_CPU1, 88 NULL, NULL, NULL, NULL}, 89 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_MB, 90 NULL, NULL, NULL, NULL}, 91 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_ADT7462, 92 NULL, NULL, NULL, NULL}, 93 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_LM95221, 94 NULL, NULL, NULL, NULL}, 95 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_FIRE, 96 NULL, NULL, NULL, NULL}, 97 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_LSI1064, 98 NULL, NULL, NULL, NULL}, 99 {"/platform/ebus@1f,464000/env-monitor@3,0", SENSOR_FRONT_PANEL, 100 NULL, NULL, NULL, NULL} 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, NULL, NULL}, 122 {"/platform/ebus@1f,464000/env-monitor@3,0", ENV_SYSTEM_FAN1, 123 NULL, PROP_FAN_SPEED_UNIT_VALUE, NULL, NULL}, 124 {"/platform/ebus@1f,464000/env-monitor@3,0", ENV_SYSTEM_FAN2, 125 NULL, PROP_FAN_SPEED_UNIT_VALUE, NULL, NULL}, 126 {"/platform/ebus@1f,464000/env-monitor@3,0", ENV_SYSTEM_FAN3, 127 NULL, PROP_FAN_SPEED_UNIT_VALUE, NULL, NULL}, 128 {"/platform/ebus@1f,464000/env-monitor@3,0", ENV_SYSTEM_FAN4, 129 NULL, PROP_FAN_SPEED_UNIT_VALUE, NULL, NULL} 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, NULL, NULL}, 149 {DISK1_NODE_PATH, ENV_DISK1, NULL, NULL, NULL}, 150 {DISK2_NODE_PATH, ENV_DISK2, NULL, NULL, NULL}, 151 {DISK3_NODE_PATH, ENV_DISK3, NULL, NULL, NULL} 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, "failed to get_node_by_path %s\n", 406 snodep->parent_path); 407 continue; 408 } 409 sensorp = snodep->sensorp; 410 if (sensorp == NULL) 411 continue; 412 if (sensorp->present == B_FALSE) 413 continue; 414 /* 415 * Create temperature-sensor node 416 */ 417 nodename = snodep->sensor_name; 418 err = ptree_create_and_add_node(nodeh, nodename, 419 PICL_CLASS_TEMPERATURE_SENSOR, &cnodeh); 420 if (env_debug) 421 envd_log(LOG_ERR, 422 "Creating PICL sensor node '%s' err:%d\n", 423 nodename, err); 424 if (err != PICL_SUCCESS) 425 break; 426 427 /* save node handle */ 428 snodep->nodeh = cnodeh; 429 430 /* 431 * Add "devfs_path" property in child node 432 */ 433 devfs_path = sensorp->devfs_path; 434 pname = PICL_PROP_DEVFS_PATH; 435 err = add_regular_prop(cnodeh, pname, 436 PICL_PTYPE_CHARSTRING, PICL_READ, 437 strlen(devfs_path)+1, (void *)devfs_path, &proph); 438 if (err != PICL_SUCCESS) 439 break; 440 441 /* 442 * Now add volatile "temperature" volatile property 443 * in this "temperature-sensor" class node. 444 */ 445 pname = PICL_PROP_TEMPERATURE; 446 err = add_volatile_prop(cnodeh, pname, 447 PICL_PTYPE_INT, PICL_READ, sizeof (tempr_t), 448 get_current_temp, NULL, &proph); 449 if (err != PICL_SUCCESS) 450 break; 451 452 /* Save prop handle */ 453 snodep->proph = proph; 454 455 /* 456 * Add threshold related properties 457 */ 458 sensor_blkp = sensorp->es; 459 if (sensor_blkp != NULL) 460 add_sensor_thresh_props(cnodeh, sensor_blkp); 461 } 462 463 if (err != PICL_SUCCESS) { 464 delete_sensor_nodes_and_props(); 465 if (env_debug) 466 envd_log(LOG_INFO, 467 "Can't create prop/node for sensor '%s'\n", 468 nodename); 469 return (err); 470 } 471 return (PICL_SUCCESS); 472 } 473 474 /* 475 * Delete all sensor nodes and related properties created by the 476 * add_sensor_prop() for each sensor node in the PICL tree. 477 */ 478 static void 479 delete_sensor_nodes_and_props(void) 480 { 481 sensor_node_t *snodep; 482 int i; 483 484 /* 485 * Delete/destroy any property created in the sensed device 486 * as well as the sensor node and all properties under it. 487 * Note that deleiing/destroying a node deletes/destroys 488 * all properties within that node. 489 */ 490 491 for (i = 0; i < N_SENSOR_NODES; i++) { 492 snodep = &sensor_nodes[i]; 493 if (snodep->nodeh != NULL) { 494 /* delete node and all properties under it */ 495 (void) ptree_delete_node(snodep->nodeh); 496 (void) ptree_destroy_node(snodep->nodeh); 497 snodep->nodeh = NULL; 498 snodep->proph = NULL; 499 } 500 } 501 } 502 503 /* 504 * Go through the disk_nodes array and create those nodes 505 * and the Temperature property to report the temperature. 506 */ 507 static int 508 add_disk_nodes_and_props() 509 { 510 int err; 511 char *pname, *nodename, *devfs_path; 512 disk_node_t *dnodep; 513 picl_nodehdl_t nodeh, cnodeh; 514 picl_prophdl_t proph; 515 env_disk_t *diskp; 516 int i; 517 518 for (i = 0; i < N_DISK_NODES; i++) { 519 if (env_debug) 520 envd_log(LOG_ERR, "adding disk nodes...\n"); 521 dnodep = &disk_nodes[i]; 522 /* 523 * Get the parent nodeh 524 */ 525 err = ptree_get_node_by_path(dnodep->parent_path, &nodeh); 526 if (err != PICL_SUCCESS) { 527 if (env_debug) 528 envd_log(LOG_ERR, 529 "failed to get node for path %s\n", 530 dnodep->parent_path); 531 532 err = PICL_SUCCESS; 533 continue; 534 } 535 diskp = dnodep->diskp; 536 if (diskp == NULL) 537 continue; 538 if (diskp->present == B_FALSE) 539 continue; 540 /* 541 * Create temperature-sensor node 542 */ 543 nodename = dnodep->disk_name; 544 err = ptree_create_and_add_node(nodeh, nodename, 545 PICL_CLASS_TEMPERATURE_SENSOR, &cnodeh); 546 if (env_debug) 547 envd_log(LOG_ERR, 548 "Creating PICL disk node '%s' err:%d\n", 549 nodename, err); 550 if (err != PICL_SUCCESS) 551 break; 552 553 /* save node handle */ 554 dnodep->nodeh = cnodeh; 555 556 /* 557 * Add "devfs_path" property in child node 558 */ 559 devfs_path = diskp->devfs_path; 560 pname = PICL_PROP_DEVFS_PATH; 561 err = add_regular_prop(cnodeh, pname, 562 PICL_PTYPE_CHARSTRING, PICL_READ, 563 strlen(devfs_path)+1, (void *)devfs_path, &proph); 564 if (err != PICL_SUCCESS) 565 break; 566 567 /* 568 * Now add volatile "temperature" volatile property 569 * in this "temperature-sensor" class node. 570 */ 571 pname = PICL_PROP_TEMPERATURE; 572 err = add_volatile_prop(cnodeh, pname, 573 PICL_PTYPE_INT, PICL_READ, sizeof (tempr_t), 574 get_disk_temp, NULL, &proph); 575 if (err != PICL_SUCCESS) 576 break; 577 578 /* Save prop handle */ 579 dnodep->proph = proph; 580 581 /* 582 * Add threshold related properties 583 */ 584 585 (void) add_regular_prop(cnodeh, PICL_PROP_LOW_SHUTDOWN, 586 PICL_PTYPE_INT, PICL_READ, 587 sizeof (diskp->low_shutdown), 588 (void *)&(diskp->low_shutdown), &proph); 589 590 (void) add_regular_prop(cnodeh, PICL_PROP_LOW_WARNING, 591 PICL_PTYPE_INT, PICL_READ, 592 sizeof (diskp->low_warning), 593 (void *)&(diskp->low_warning), &proph); 594 595 (void) add_regular_prop(cnodeh, PICL_PROP_HIGH_WARNING, 596 PICL_PTYPE_INT, PICL_READ, 597 sizeof (diskp->high_warning), 598 (void *)&(diskp->high_warning), &proph); 599 600 (void) add_regular_prop(cnodeh, PICL_PROP_HIGH_SHUTDOWN, 601 PICL_PTYPE_INT, PICL_READ, 602 sizeof (diskp->high_shutdown), 603 (void *)&(diskp->high_shutdown), &proph); 604 605 } 606 if (err != PICL_SUCCESS) { 607 delete_disk_nodes_and_props(); 608 if (env_debug) 609 envd_log(LOG_INFO, 610 "Can't create prop/node for disk '%s'\n", 611 nodename); 612 return (err); 613 } 614 return (PICL_SUCCESS); 615 } 616 617 /* 618 * Delete all disk nodes and related properties created by the 619 * add_disk_props() for each disk node in the PICL tree. 620 */ 621 static void 622 delete_disk_nodes_and_props(void) 623 { 624 disk_node_t *dnodep; 625 int i; 626 627 /* 628 * Delete/destroy disk node and all properties under it. 629 * Note that deleting/destroying a node deletes/destroys 630 * all properties within that node. 631 */ 632 633 for (i = 0; i < N_DISK_NODES; i++) { 634 dnodep = &disk_nodes[i]; 635 if (dnodep->nodeh != NULL) { 636 (void) ptree_delete_node(dnodep->nodeh); 637 (void) ptree_destroy_node(dnodep->nodeh); 638 dnodep->nodeh = NULL; 639 dnodep->proph = NULL; 640 } 641 } 642 } 643 644 /* 645 * For each entry in fan_nodes[] array, do the following: 646 * - Create specified "fan" class node. 647 * - Create "Speed" volatile propery under "fan" class node. 648 * - Create "SpeedUnit" property under "fan" class node. 649 */ 650 static int 651 add_fan_nodes_and_props() 652 { 653 int err = PICL_FAILURE; 654 char *pname, *nodename, *devfs_path; 655 env_fan_t *fanp; 656 fan_node_t *fnodep; 657 picl_nodehdl_t nodeh, cnodeh; 658 picl_prophdl_t proph; 659 int i; 660 661 for (i = 0; i < N_FAN_NODES; i++) { 662 /* 663 * Add various fan nodes and properties 664 */ 665 fnodep = &fan_nodes[i]; 666 if (fnodep == NULL) 667 continue; 668 if (fnodep->fanp == NULL) 669 continue; 670 if (fnodep->fanp->present == B_FALSE) 671 continue; 672 /* 673 * get parent nodeh 674 */ 675 err = ptree_get_node_by_path(fnodep->parent_path, &nodeh); 676 if (err != PICL_SUCCESS) { 677 if (env_debug) 678 envd_log(LOG_ERR, 679 "node for %s NOT FOUND.\n", fnodep->parent_path); 680 err = PICL_SUCCESS; 681 continue; 682 } 683 /* 684 * Create "fan" class node and save node handle 685 */ 686 nodename = fnodep->fan_name; 687 err = ptree_create_and_add_node(nodeh, nodename, 688 PICL_CLASS_FAN, &cnodeh); 689 if (env_debug) 690 envd_log(LOG_ERR, 691 "Creating PICL fan node '%s' err:%d\n", 692 nodename, err); 693 694 if (err != PICL_SUCCESS) 695 break; 696 fnodep->nodeh = cnodeh; 697 698 /* 699 * Add "devfs_path" property in child node 700 */ 701 fanp = fnodep->fanp; 702 devfs_path = fanp->devfs_path; 703 pname = PICL_PROP_DEVFS_PATH; 704 err = add_regular_prop(cnodeh, pname, 705 PICL_PTYPE_CHARSTRING, PICL_READ, 706 strlen(devfs_path)+1, (void *)devfs_path, &proph); 707 708 if (err != PICL_SUCCESS) 709 710 break; 711 712 /* 713 * Add "Speed" volatile property in this "fan" 714 * class node and save prop handle. 715 */ 716 pname = PICL_PROP_FAN_SPEED; 717 718 err = add_volatile_prop(cnodeh, pname, PICL_PTYPE_INT, 719 PICL_READ|PICL_WRITE, sizeof (fanspeed_t), 720 get_current_speed, set_current_speed, &proph); 721 722 if (err != PICL_SUCCESS) 723 break; 724 fnodep->proph = proph; 725 726 /* 727 * Add other "fan" class properties 728 */ 729 pname = PICL_PROP_FAN_SPEED_UNIT; 730 err = add_regular_prop(cnodeh, pname, 731 PICL_PTYPE_CHARSTRING, PICL_READ, 732 strlen(fnodep->speed_unit)+1, 733 (void *)fnodep->speed_unit, &proph); 734 735 if (err != PICL_SUCCESS) 736 break; 737 738 pname = PICL_PROP_LOW_WARNING; 739 err = add_regular_prop(cnodeh, pname, 740 PICL_PTYPE_INT, PICL_READ, 741 sizeof (fanspeed_t), 742 &(fnodep->fanp->speed_min), &proph); 743 744 if (err != PICL_SUCCESS) 745 break; 746 } 747 if (err != PICL_SUCCESS) { 748 delete_fan_nodes_and_props(); 749 return (err); 750 } 751 return (PICL_SUCCESS); 752 } 753 754 755 /* 756 * Delete all fan nodes and related properties created by the 757 * add_fan_props() for each fan node in the PICL tree. 758 */ 759 static void 760 delete_fan_nodes_and_props(void) 761 { 762 fan_node_t *fnodep; 763 int i; 764 765 /* 766 * Delete/destroy fan node and all properties under it. 767 * Note that deleting/destroying a node deletes/destroys 768 * all properties within that node. 769 */ 770 771 for (i = 0; i < N_FAN_NODES; i++) { 772 fnodep = &fan_nodes[i]; 773 if (fnodep->nodeh != NULL) { 774 (void) ptree_delete_node(fnodep->nodeh); 775 (void) ptree_destroy_node(fnodep->nodeh); 776 fnodep->nodeh = NULL; 777 } 778 } 779 } 780 /* 781 * Tuneables publishing functions 782 */ 783 static int 784 copy_persistent_tuneable(env_tuneable_t *tune, char *buf) 785 { 786 787 switch (tune->type) { 788 case PICL_PTYPE_INT : { 789 (void) memcpy((int *)tune->value, 790 buf, tune->nbytes); 791 break; 792 } 793 case PICL_PTYPE_CHARSTRING : { 794 (void) memcpy((caddr_t)tune->value, 795 buf, tune->nbytes); 796 break; 797 } 798 default : { 799 return (PICL_FAILURE); 800 } 801 } 802 return (PICL_SUCCESS); 803 } 804 805 static void 806 env_parse_tunables(picl_nodehdl_t rooth) 807 { 808 char nmbuf[SYS_NMLN]; 809 char pname[PATH_MAX]; 810 811 if (sysinfo(SI_PLATFORM, nmbuf, sizeof (nmbuf)) != -1) { 812 (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf); 813 (void) strlcat(pname, TUNABLE_CONF_FILE, PATH_MAX); 814 if (access(pname, R_OK) == 0) { 815 (void) picld_pluginutil_parse_config_file(rooth, pname); 816 return; 817 } 818 } 819 } 820 821 int 822 env_picl_setup_tuneables(void) 823 { 824 int err; 825 int i; 826 picl_nodehdl_t nodeh; 827 picl_nodehdl_t rooth; 828 picl_prophdl_t proph; 829 env_tuneable_t *tuneablep; 830 char read_buf[BUFSIZ]; 831 832 if (ptree_get_root(&rooth) != PICL_SUCCESS) { 833 return (PICL_FAILURE); 834 } 835 err = ptree_create_and_add_node(rooth, PICL_PLUGINS_NODE, 836 PICL_CLASS_PICL, &nodeh); 837 if (err != PICL_SUCCESS) 838 return (PICL_FAILURE); 839 err = ptree_create_and_add_node(nodeh, PICL_ENVIRONMENTAL_NODE, 840 PICL_CLASS_PICL, &nodeh); 841 if (err != PICL_SUCCESS) { 842 return (PICL_FAILURE); 843 } 844 845 /* 846 * Parse the conf file 847 */ 848 if (env_debug) 849 envd_log(LOG_ERR, "parsing tuneables...\n"); 850 env_parse_tunables(rooth); 851 for (i = 0; i < ntuneables; i++) { 852 if (env_debug) 853 envd_log(LOG_ERR, "tuneable %d being added\n", i); 854 tuneablep = &tuneables[i]; 855 err = ptree_get_propval_by_name(nodeh, tuneablep->name, 856 read_buf, tuneablep->nbytes); 857 858 if (err != PICL_SUCCESS) { 859 /* 860 * Add volitle functions to environmental node 861 */ 862 err = add_volatile_prop(nodeh, tuneablep->name, 863 tuneablep->type, 864 PICL_READ|PICL_WRITE, tuneablep->nbytes, 865 tuneablep->rfunc, 866 tuneablep->wfunc, &proph); 867 868 tuneablep->proph = proph; 869 } else { 870 /* 871 * property is persistent 872 */ 873 (void) copy_persistent_tuneable(tuneablep, 874 read_buf); 875 } 876 } 877 878 return (PICL_SUCCESS); 879 } 880 881 /* 882 * Find the ENVMODEL_CONF_FILE file. 883 */ 884 static int 885 get_envmodel_conf_file(char *outfilename) 886 { 887 char nmbuf[SYS_NMLN]; 888 char pname[PATH_MAX]; 889 890 if (sysinfo(SI_PLATFORM, nmbuf, sizeof (nmbuf)) != -1) { 891 (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf); 892 (void) strlcat(pname, ENV_CONF_FILE, PATH_MAX); 893 if (access(pname, R_OK) == 0) { 894 (void) strlcpy(outfilename, pname, PATH_MAX); 895 return (0); 896 } 897 } 898 899 if (sysinfo(SI_MACHINE, nmbuf, sizeof (nmbuf)) != -1) { 900 (void) snprintf(pname, PATH_MAX, PICLD_PLAT_PLUGIN_DIRF, nmbuf); 901 (void) strlcat(pname, ENV_CONF_FILE, PATH_MAX); 902 if (access(pname, R_OK) == 0) { 903 (void) strlcpy(outfilename, pname, PATH_MAX); 904 return (0); 905 } 906 } 907 908 (void) snprintf(pname, PATH_MAX, "%s/%s", PICLD_COMMON_PLUGIN_DIR, 909 ENV_CONF_FILE); 910 911 if (access(pname, R_OK) == 0) { 912 (void) strlcpy(outfilename, pname, PATH_MAX); 913 return (0); 914 } 915 916 return (-1); 917 } 918 919 /* Delete all sensor/fan nodes and any properties created by this plugin */ 920 void 921 env_picl_destroy(void) 922 { 923 delete_fan_nodes_and_props(); 924 delete_sensor_nodes_and_props(); 925 delete_disk_nodes_and_props(); 926 } 927 928 void 929 env_picl_setup(void) 930 { 931 int err, sensor_err, fan_err, disk_err; 932 sensor_node_t *snodep; 933 fan_node_t *fnodep; 934 disk_node_t *dnodep; 935 picl_nodehdl_t plath; 936 char fullfilename[PATH_MAX]; 937 picl_nodehdl_t rooth; 938 int i; 939 940 941 /* 942 * Initialize sensorp and other fields in the sensor_nodes[] array 943 */ 944 945 for (i = 0; i < N_SENSOR_NODES; i++) { 946 snodep = &sensor_nodes[i]; 947 snodep->sensorp = sensor_lookup(snodep->sensor_name); 948 snodep->nodeh = NULL; 949 snodep->proph = NULL; 950 snodep->target_proph = NULL; 951 } 952 953 /* 954 * Initialize fanp and other fields in the fan_nodes[] array 955 */ 956 for (i = 0; i < N_FAN_NODES; i++) { 957 fnodep = &fan_nodes[i]; 958 fnodep->fanp = fan_lookup(fnodep->fan_name); 959 fnodep->nodeh = NULL; 960 fnodep->proph = NULL; 961 } 962 963 /* 964 * Initialize diskp and other fields in the disk_nodes[] array 965 */ 966 for (i = 0; i < N_DISK_NODES; i++) { 967 dnodep = &disk_nodes[i]; 968 dnodep->diskp = disk_lookup(dnodep->disk_name); 969 dnodep->nodeh = NULL; 970 dnodep->proph = NULL; 971 } 972 973 /* 974 * Get platform handle and populate PICL tree with environmental 975 * nodes and properties 976 */ 977 err = ptree_get_node_by_path("/platform", &plath); 978 979 if (err == PICL_SUCCESS) { 980 sensor_err = add_sensor_nodes_and_props(); 981 fan_err = add_fan_nodes_and_props(); 982 if (disk_temp_monitor) 983 disk_err = add_disk_nodes_and_props(); 984 } 985 986 /* 987 * We can safely call delete_xxx_nodes_and_props even 988 * if nodes were not added. 989 */ 990 991 if (err != PICL_SUCCESS) { 992 if (fan_err != PICL_SUCCESS) 993 delete_fan_nodes_and_props(); 994 if (disk_err != PICL_SUCCESS) 995 delete_disk_nodes_and_props(); 996 if (sensor_err != PICL_SUCCESS) 997 delete_sensor_nodes_and_props(); 998 999 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED); 1000 return; 1001 } 1002 if (env_debug) 1003 envd_log(LOG_ERR, "parsing the envmodel.conf file...\n"); 1004 1005 /* 1006 * Parse the envmodel.conf file and populate the PICL tree 1007 */ 1008 if (get_envmodel_conf_file(fullfilename) < 0) 1009 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED); 1010 if (ptree_get_root(&rooth) != PICL_SUCCESS) 1011 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED); 1012 err = picld_pluginutil_parse_config_file(rooth, fullfilename); 1013 1014 if (err != PICL_SUCCESS) 1015 envd_log(LOG_CRIT, ENVD_PICL_SETUP_FAILED); 1016 } 1017