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