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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <alloca.h> 29 #include <errno.h> 30 #include <libintl.h> 31 #include <sys/utsname.h> 32 #include <sys/types.h> 33 #include <sys/stat.h> 34 #include <sys/openpromio.h> 35 #include <sys/ddi.h> 36 #include <syslog.h> 37 #include <fcntl.h> 38 #include <dirent.h> 39 #include <unistd.h> 40 #include <locale.h> 41 #include <picl.h> 42 #include "pdevinfo.h" 43 #include "display.h" 44 #include "display_sun4u.h" 45 #include "picldefs.h" 46 #include "libprtdiag.h" 47 48 #if !defined(TEXT_DOMAIN) 49 #define TEXT_DOMAIN "SYS_TEST" 50 #endif 51 52 #define EM_INIT_FAIL dgettext(TEXT_DOMAIN,\ 53 "picl_initialize failed: %s\n") 54 #define EM_GET_ROOT_FAIL dgettext(TEXT_DOMAIN,\ 55 "Getting root node failed: %s\n") 56 #define EM_PRTDIAG_FAIL dgettext(TEXT_DOMAIN, "Prtdiag failed!\n") 57 58 #define SIGN_ON_MSG dgettext(TEXT_DOMAIN,\ 59 "System Configuration: Oracle Corporation ") 60 #define SYSCLK_FREQ_MSG dgettext(TEXT_DOMAIN,\ 61 "System clock frequency: %d MHZ\n") 62 #define MEM_SIZE_MSG dgettext(TEXT_DOMAIN, "Memory size: ") 63 64 #define DEFAULT_BOARD_NUM 0 65 #define DEFAULT_PORTID 0 66 #define CLK_FREQ_66MHZ 66 67 #define USB -1 68 #define HUB -2 69 70 /* bus id */ 71 #define PCI_TYPE 1 72 73 /* 74 * PICL classes 75 */ 76 #define PICL_CLASS_OPTIONS "options" 77 78 /* 79 * Property names 80 */ 81 82 #define OBP_PROP_REG "reg" 83 #define OBP_PROP_CLOCK_FREQ "clock-frequency" 84 #define OBP_PROP_BOARD_NUM "board#" 85 #define OBP_PROP_REVISION_ID "revision-id" 86 #define OBP_PROP_VERSION_NUM "version#" 87 #define OBP_PROP_BOARD_TYPE "board_type" 88 #define OBP_PROP_ECACHE_SIZE "ecache-size" 89 #define OBP_PROP_IMPLEMENTATION "implementation#" 90 #define OBP_PROP_MASK "mask#" 91 #define OBP_PROP_COMPATIBLE "compatible" 92 #define OBP_PROP_BANNER_NAME "banner-name" 93 #define OBP_PROP_MODEL "model" 94 #define OBP_PROP_66MHZ_CAPABLE "66mhz-capable" 95 #define OBP_PROP_FBC_REG_ID "fbc_reg_id" 96 #define OBP_PROP_VERSION "version" 97 98 #define PROP_POWERFAIL_TIME "powerfail-time" 99 #define PICL_PROP_LOW_WARNING_THRESHOLD "LowWarningThreshold" 100 101 #define DEFAULT_LINE_WIDTH 78 102 #define HEADING_SYMBOL "=" 103 104 #define SIZE_FIELD 11 105 #define MAX_IWAYS 32 106 107 typedef struct bank_list { 108 picl_nodehdl_t nodeh; 109 uint32_t iway_count; 110 uint32_t iway[MAX_IWAYS]; 111 struct bank_list *next; 112 } bank_list_t; 113 114 typedef struct { 115 uint64_t base; 116 uint64_t size; 117 int ifactor; 118 int bank_count; 119 } seg_info_t; 120 121 static struct io_card *io_card_list = NULL; /* The head of the IO card list */ 122 static bank_list_t *mem_banks = NULL; 123 static int mem_xfersize; 124 static int no_xfer_size = 0; 125 126 static const char *io_device_table[] = { 127 "block", 128 "disk", 129 "cdrom", 130 "floppy", 131 "tape", 132 "network", 133 "display", 134 "serial", 135 "parallel", 136 "scsi", 137 "scsi-2", 138 "scsi-3", 139 "ide", 140 "fcal", 141 "keyboard", 142 "mouse", 143 "dma" 144 }; 145 146 #define NIODEVICE (sizeof (io_device_table) / sizeof (io_device_table[0])) 147 148 static const char *bus_table[] = { 149 "ebus", 150 "isa", 151 "pmu" 152 }; 153 154 #define NBUS (sizeof (bus_table) / sizeof (bus_table[0])) 155 156 /* 157 * check if it is an IO deice 158 * return 1 if this is a io device; return 0 for else. 159 */ 160 static int 161 is_io_device(char *device_class) 162 { 163 int i; 164 165 for (i = 0; i < NIODEVICE; i++) { 166 if (strcmp(device_class, io_device_table[i]) == 0) 167 return (1); 168 } 169 170 return (0); 171 } 172 173 /* 174 * check if it is a bus 175 * return 1 if this is a bus; return 0 for else. 176 */ 177 static int 178 is_bus(char *device_class) 179 { 180 int i; 181 182 for (i = 0; i < NBUS; i++) { 183 if (strcmp(device_class, bus_table[i]) == 0) 184 return (1); 185 } 186 187 return (0); 188 } 189 190 /* 191 * search children to get the node by the nodename 192 * return node handler in picl_nodehdl_t *nodeh 193 */ 194 static int 195 picldiag_get_node_by_name(picl_nodehdl_t rooth, char *name, 196 picl_nodehdl_t *nodeh) 197 { 198 picl_nodehdl_t childh; 199 int err; 200 char *nodename; 201 202 nodename = alloca(strlen(name) + 1); 203 if (nodename == NULL) 204 return (PICL_FAILURE); 205 206 err = picl_get_propval_by_name(rooth, PICL_PROP_CHILD, &childh, 207 sizeof (picl_nodehdl_t)); 208 209 while (err == PICL_SUCCESS) { 210 err = picl_get_propval_by_name(childh, PICL_PROP_NAME, 211 nodename, (strlen(name) + 1)); 212 if (err != PICL_SUCCESS) { 213 err = picl_get_propval_by_name(childh, PICL_PROP_PEER, 214 &childh, sizeof (picl_nodehdl_t)); 215 continue; 216 } 217 218 if (strcmp(nodename, name) == 0) { 219 *nodeh = childh; 220 return (PICL_SUCCESS); 221 } 222 223 err = picl_get_propval_by_name(childh, PICL_PROP_PEER, 224 &childh, sizeof (picl_nodehdl_t)); 225 } 226 227 return (err); 228 } 229 230 /* 231 * get the value by the property name of the string prop 232 * the value will be in outbuf 233 * Caller must free the outbuf 234 */ 235 static int 236 picldiag_get_string_propval(picl_nodehdl_t modh, char *prop_name, char **outbuf) 237 { 238 int err; 239 picl_prophdl_t proph; 240 picl_propinfo_t pinfo; 241 char *prop_value; 242 243 err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph); 244 if (err != PICL_SUCCESS) 245 return (err); 246 247 /* 248 * If it is not a string prop, return NULL 249 */ 250 if (pinfo.type != PICL_PTYPE_CHARSTRING) 251 return (PICL_FAILURE); 252 253 prop_value = malloc(pinfo.size); 254 if (prop_value == NULL) 255 return (PICL_FAILURE); 256 257 err = picl_get_propval(proph, prop_value, pinfo.size); 258 if (err != PICL_SUCCESS) { 259 free(prop_value); 260 return (err); 261 } 262 263 *outbuf = prop_value; 264 return (PICL_SUCCESS); 265 } 266 267 268 /* 269 * return the value as a signed integer 270 */ 271 272 static int64_t 273 picldiag_get_int_propval(picl_nodehdl_t modh, char *prop_name, int *ret) 274 { 275 int err; 276 picl_prophdl_t proph; 277 picl_propinfo_t pinfo; 278 int8_t int8v; 279 int16_t int16v; 280 int32_t int32v; 281 int64_t int64v; 282 283 err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph); 284 if (err != PICL_SUCCESS) { 285 *ret = err; 286 return (0); 287 } 288 289 /* 290 * If it is not an int, uint or byte array prop, return failure 291 */ 292 if ((pinfo.type != PICL_PTYPE_INT) && 293 (pinfo.type != PICL_PTYPE_UNSIGNED_INT) && 294 (pinfo.type != PICL_PTYPE_BYTEARRAY)) { 295 *ret = PICL_FAILURE; 296 return (0); 297 } 298 299 switch (pinfo.size) { 300 case sizeof (int8_t): 301 err = picl_get_propval(proph, &int8v, sizeof (int8v)); 302 *ret = err; 303 return (int8v); 304 case sizeof (int16_t): 305 err = picl_get_propval(proph, &int16v, sizeof (int16v)); 306 *ret = err; 307 return (int16v); 308 case sizeof (int32_t): 309 err = picl_get_propval(proph, &int32v, sizeof (int32v)); 310 *ret = err; 311 return (int32v); 312 case sizeof (int64_t): 313 err = picl_get_propval(proph, &int64v, sizeof (int64v)); 314 *ret = err; 315 return (int64v); 316 default: /* not supported size */ 317 *ret = PICL_FAILURE; 318 return (0); 319 } 320 } 321 322 /* 323 * return the value of the uint prop 324 */ 325 static uint64_t 326 picldiag_get_uint_propval(picl_nodehdl_t modh, char *prop_name, int *ret) 327 { 328 int err; 329 picl_prophdl_t proph; 330 picl_propinfo_t pinfo; 331 uint8_t uint8v; 332 uint16_t uint16v; 333 uint32_t uint32v; 334 uint64_t uint64v; 335 336 err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph); 337 if (err != PICL_SUCCESS) { 338 *ret = err; 339 return (0); 340 } 341 342 /* 343 * If it is not an int or uint prop, return failure 344 */ 345 if ((pinfo.type != PICL_PTYPE_INT) && 346 (pinfo.type != PICL_PTYPE_UNSIGNED_INT)) { 347 *ret = PICL_FAILURE; 348 return (0); 349 } 350 351 /* uint prop */ 352 353 switch (pinfo.size) { 354 case sizeof (uint8_t): 355 err = picl_get_propval(proph, &uint8v, sizeof (uint8v)); 356 *ret = err; 357 return (uint8v); 358 case sizeof (uint16_t): 359 err = picl_get_propval(proph, &uint16v, sizeof (uint16v)); 360 *ret = err; 361 return (uint16v); 362 case sizeof (uint32_t): 363 err = picl_get_propval(proph, &uint32v, sizeof (uint32v)); 364 *ret = err; 365 return (uint32v); 366 case sizeof (uint64_t): 367 err = picl_get_propval(proph, &uint64v, sizeof (uint64v)); 368 *ret = err; 369 return (uint64v); 370 default: /* not supported size */ 371 *ret = PICL_FAILURE; 372 return (0); 373 } 374 } 375 376 /* 377 * return the value of the float prop 378 */ 379 static float 380 picldiag_get_float_propval(picl_nodehdl_t modh, char *prop_name, int *ret) 381 { 382 int err; 383 picl_prophdl_t proph; 384 picl_propinfo_t pinfo; 385 float floatv; 386 387 err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph); 388 if (err != PICL_SUCCESS) { 389 *ret = err; 390 return ((float)0); 391 } 392 393 /* 394 * If it is not a float prop, return failure 395 */ 396 if (pinfo.type != PICL_PTYPE_FLOAT) { 397 *ret = PICL_FAILURE; 398 return ((float)0); 399 } 400 401 *ret = picl_get_propval(proph, &floatv, sizeof (floatv)); 402 return (floatv); 403 } 404 405 /* 406 * get the clock frequency 407 */ 408 static int 409 picldiag_get_clock_freq(picl_nodehdl_t modh, uint32_t *freq) 410 { 411 #define ROUND_TO_MHZ(x) (((x) + 500000)/ 1000000) 412 int err; 413 uint64_t clk_freq; 414 415 clk_freq = picldiag_get_uint_propval(modh, OBP_PROP_CLOCK_FREQ, &err); 416 if (err != PICL_SUCCESS) 417 return (err); 418 419 *freq = ROUND_TO_MHZ(clk_freq); 420 421 return (PICL_SUCCESS); 422 } 423 424 /* 425 * get the clock frequency from parent 426 */ 427 static int 428 picldiag_get_clock_from_parent(picl_nodehdl_t nodeh, uint32_t *clk) 429 { 430 picl_nodehdl_t parenth; 431 int err; 432 433 434 err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, 435 &parenth, sizeof (parenth)); 436 437 while (err == PICL_SUCCESS) { 438 err = picldiag_get_clock_freq(parenth, clk); 439 if (err != PICL_PROPNOTFOUND) 440 return (err); 441 442 err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT, 443 &parenth, sizeof (parenth)); 444 } 445 446 return (err); 447 } 448 449 /* 450 * get _fru_parent prop 451 * If not found, then travese superiors (parent nodes) until 452 * a _fru_parent property is found. 453 * If not found, no fru parent 454 */ 455 static int 456 picldiag_get_fru_parent(picl_nodehdl_t nodeh, picl_nodehdl_t *fruparenth) 457 { 458 picl_nodehdl_t fruh; 459 int err; 460 461 /* find fru parent */ 462 err = picl_get_propval_by_name(nodeh, PICL_REFPROP_FRU_PARENT, 463 &fruh, sizeof (fruh)); 464 465 if (err != PICL_SUCCESS) 466 err = picl_get_propval_by_name(nodeh, PICL_REFPROP_LOC_PARENT, 467 &fruh, sizeof (fruh)); 468 469 while (err == PICL_PROPNOTFOUND) { 470 err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, 471 &nodeh, sizeof (nodeh)); 472 if (err != PICL_SUCCESS) 473 return (err); 474 475 err = picl_get_propval_by_name(nodeh, PICL_REFPROP_FRU_PARENT, 476 &fruh, sizeof (fruh)); 477 if (err != PICL_SUCCESS) 478 err = picl_get_propval_by_name(nodeh, 479 PICL_REFPROP_LOC_PARENT, &fruh, sizeof (fruh)); 480 } 481 482 if (err == PICL_SUCCESS) 483 *fruparenth = fruh; 484 485 return (err); 486 } 487 488 /* 489 * get label 490 * 491 * To get the label, use the following algorithm: 492 * Lookup "Label" property in the fru node itself. If no 493 * Label found, then traverse superiors (parent nodes) until 494 * a Label property is found. 495 * if not found, then no label 496 */ 497 static int 498 picldiag_get_label(picl_nodehdl_t nodeh, char **label) 499 { 500 int err; 501 502 err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL, label); 503 504 while (err == PICL_PROPNOTFOUND) { 505 err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, 506 &nodeh, sizeof (nodeh)); 507 if (err != PICL_SUCCESS) 508 return (err); 509 510 err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL, 511 label); 512 } 513 514 return (err); 515 } 516 517 /* 518 * get combined label 519 * 520 * like picldiag_get_label, except concatenates the labels of parent locations 521 * eg SB0/P3 for processor P3 on system board SB0 522 * 523 * if caller specifies non-zero label length, label will be cut to specified 524 * length. 525 * negative length is left justified, non-negative length is right justified 526 */ 527 static int 528 picldiag_get_combined_label(picl_nodehdl_t nodeh, char **label, int lablen) 529 { 530 int err; 531 char *ptr; 532 char *ptr1 = NULL; 533 char *ptr2; 534 int len; 535 536 err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL, &ptr1); 537 if (err != PICL_PROPNOTFOUND && err != PICL_SUCCESS) 538 return (err); 539 540 for (;;) { 541 err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, 542 &nodeh, sizeof (nodeh)); 543 if (err == PICL_PROPNOTFOUND) 544 break; 545 if (err != PICL_SUCCESS) 546 return (err); 547 548 err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL, &ptr); 549 if (err == PICL_SUCCESS) { 550 if (ptr1 == NULL) { 551 ptr1 = ptr; 552 } else { 553 ptr2 = malloc(strlen(ptr1) + strlen(ptr) + 2); 554 if (ptr2 == NULL) 555 return (PICL_FAILURE); 556 (void) strlcpy(ptr2, ptr, strlen(ptr)-1); 557 (void) strlcat(ptr2, "/", 1); 558 (void) strlcat(ptr2, ptr1, strlen(ptr1)-1); 559 (void) strlcat(ptr2, "\0", 1); 560 561 (void) free(ptr); 562 (void) free(ptr1); 563 ptr1 = ptr2; 564 } 565 } else if (err != PICL_PROPNOTFOUND) { 566 return (err); 567 } 568 } 569 570 if (ptr1 == NULL) 571 return (PICL_PROPNOTFOUND); 572 573 len = strlen(ptr1); 574 /* if no string truncation is desired or required */ 575 if ((lablen == 0) || (len <= abs(lablen))) { 576 *label = ptr1; 577 return (PICL_SUCCESS); 578 } 579 580 /* string truncation is required; alloc space for (lablen + \0) */ 581 ptr = malloc(abs(lablen) + 1); 582 if (ptr == 0) 583 return (PICL_FAILURE); 584 if (lablen > 0) { 585 /* right justification; label = "+<string>\0" */ 586 strlcpy(ptr, "+", 1); 587 strlcat(ptr, ptr1 + len - lablen + 1, lablen + 1); 588 } else { 589 /* left justification; label = "<string>+\0" */ 590 strlcpy(ptr, ptr1, abs(lablen) - 1); 591 strcat(ptr, "+"); 592 } 593 594 *label = ptr; 595 return (PICL_SUCCESS); 596 } 597 598 /* 599 * return the first compatible value 600 */ 601 static int 602 picldiag_get_first_compatible_value(picl_nodehdl_t nodeh, char **outbuf) 603 { 604 int err; 605 picl_prophdl_t proph; 606 picl_propinfo_t pinfo; 607 picl_prophdl_t tblh; 608 picl_prophdl_t rowproph; 609 char *pval; 610 611 err = picl_get_propinfo_by_name(nodeh, OBP_PROP_COMPATIBLE, 612 &pinfo, &proph); 613 if (err != PICL_SUCCESS) 614 return (err); 615 616 if (pinfo.type == PICL_PTYPE_CHARSTRING) { 617 pval = malloc(pinfo.size); 618 if (pval == NULL) 619 return (PICL_FAILURE); 620 err = picl_get_propval(proph, pval, pinfo.size); 621 if (err != PICL_SUCCESS) { 622 free(pval); 623 return (err); 624 } 625 *outbuf = pval; 626 return (PICL_SUCCESS); 627 } 628 629 if (pinfo.type != PICL_PTYPE_TABLE) 630 return (PICL_FAILURE); 631 632 /* get first string from table */ 633 err = picl_get_propval(proph, &tblh, pinfo.size); 634 if (err != PICL_SUCCESS) 635 return (err); 636 637 err = picl_get_next_by_row(tblh, &rowproph); 638 if (err != PICL_SUCCESS) 639 return (err); 640 641 err = picl_get_propinfo(rowproph, &pinfo); 642 if (err != PICL_SUCCESS) 643 return (err); 644 645 pval = malloc(pinfo.size); 646 if (pval == NULL) 647 return (PICL_FAILURE); 648 649 err = picl_get_propval(rowproph, pval, pinfo.size); 650 if (err != PICL_SUCCESS) { 651 free(pval); 652 return (err); 653 } 654 655 *outbuf = pval; 656 return (PICL_SUCCESS); 657 } 658 659 /* 660 * print the header in the center 661 */ 662 static void 663 logprintf_header(char *header, size_t line_width) 664 { 665 size_t start_pos; 666 size_t i; 667 668 log_printf("\n"); 669 start_pos = (line_width - strlen(header) - 2) / 2; 670 671 for (i = 0; i < start_pos; i++) 672 log_printf("%s", HEADING_SYMBOL); 673 674 log_printf(" %s ", header); 675 676 for (i = 0; i < start_pos; i++) 677 log_printf("%s", HEADING_SYMBOL); 678 679 log_printf("\n"); 680 } 681 682 /* 683 * print the size 684 */ 685 static void 686 logprintf_size(uint64_t size) 687 { 688 689 uint64_t kbyte = 1024; 690 uint64_t mbyte = 1024 * 1024; 691 uint64_t gbyte = 1024 * 1024 * 1024; 692 uint64_t residue; 693 char buf[SIZE_FIELD]; 694 695 if (size >= gbyte) { 696 residue = size % gbyte; 697 if (residue == 0) 698 snprintf(buf, sizeof (buf), "%dGB", 699 (int)(size / gbyte)); 700 else 701 snprintf(buf, sizeof (buf), "%.2fGB", 702 (float)size / gbyte); 703 } else if (size >= mbyte) { 704 residue = size % mbyte; 705 if (residue == 0) 706 snprintf(buf, sizeof (buf), "%dMB", 707 (int)(size / mbyte)); 708 else 709 snprintf(buf, sizeof (buf), "%.2fMB", 710 (float)size / mbyte); 711 } else { 712 residue = size % kbyte; 713 if (residue == 0) 714 snprintf(buf, sizeof (buf), "%dKB", 715 (int)(size / kbyte)); 716 else 717 snprintf(buf, sizeof (buf), "%.2fKB", 718 (float)size / kbyte); 719 } 720 721 log_printf("%-10s ", buf); 722 } 723 724 /* 725 * display platform banner 726 */ 727 static int 728 display_platform_banner(picl_nodehdl_t plafh) 729 { 730 char *platform; 731 char *banner_name; 732 int err; 733 734 /* 735 * get PICL_PROP_MACHINE and PICL_PROP_BANNER_NAME 736 */ 737 log_printf(SIGN_ON_MSG); 738 err = picldiag_get_string_propval(plafh, PICL_PROP_MACHINE, 739 &platform); 740 if (err != PICL_SUCCESS) 741 return (err); 742 log_printf(" %s", platform); 743 free(platform); 744 745 err = picldiag_get_string_propval(plafh, OBP_PROP_BANNER_NAME, 746 &banner_name); 747 if (err != PICL_SUCCESS) 748 return (err); 749 log_printf(" %s", banner_name); 750 free(banner_name); 751 752 log_printf("\n"); 753 return (PICL_SUCCESS); 754 } 755 756 /* 757 * display the clock frequency 758 */ 759 static int 760 display_system_clock(picl_nodehdl_t plafh) 761 { 762 uint32_t system_clk; 763 int err; 764 765 err = picldiag_get_clock_freq(plafh, &system_clk); 766 if (err != PICL_SUCCESS) 767 return (err); 768 769 log_printf(SYSCLK_FREQ_MSG, system_clk); 770 771 return (PICL_SUCCESS); 772 } 773 774 /* 775 * callback function to display the memory size 776 */ 777 /*ARGSUSED*/ 778 static int 779 memory_callback(picl_nodehdl_t memh, void *args) 780 { 781 uint64_t mem_size; 782 int err; 783 784 log_printf(MEM_SIZE_MSG); 785 mem_size = picldiag_get_uint_propval(memh, PICL_PROP_SIZE, &err); 786 if (err == PICL_SUCCESS) 787 logprintf_size(mem_size); 788 log_printf("\n"); 789 no_xfer_size = 0; 790 mem_xfersize = picldiag_get_uint_propval(memh, PICL_PROP_TRANSFER_SIZE, 791 &err); 792 if (err == PICL_PROPNOTFOUND) 793 no_xfer_size = 1; 794 return (PICL_WALK_TERMINATE); 795 } 796 797 /* 798 * callback function to print cpu information 799 */ 800 /*ARGSUSED*/ 801 static int 802 cpu_callback(picl_nodehdl_t nodeh, void *args) 803 { 804 int err; 805 int id; 806 uint64_t uintval; 807 uint32_t freq; 808 char *impl_name; 809 char *status; 810 picl_prophdl_t parenth; 811 char *label; 812 813 /* 814 * If no ID is found, return 815 */ 816 id = picldiag_get_uint_propval(nodeh, PICL_PROP_ID, &err); 817 if (err == PICL_PROPNOTFOUND) 818 return (PICL_WALK_CONTINUE); 819 else if (err != PICL_SUCCESS) 820 return (err); 821 log_printf(" %2d ", id); 822 823 /* 824 * If no freq is found, return 825 */ 826 err = picldiag_get_clock_freq(nodeh, &freq); 827 if (err == PICL_PROPNOTFOUND) 828 return (PICL_WALK_CONTINUE); 829 else if (err != PICL_SUCCESS) 830 return (err); 831 log_printf(dgettext(TEXT_DOMAIN, "%4d MHz "), freq); 832 833 /* Ecache size */ 834 uintval = picldiag_get_uint_propval(nodeh, OBP_PROP_ECACHE_SIZE, &err); 835 if (err == PICL_PROPNOTFOUND) 836 log_printf(" - "); 837 else if (err == PICL_SUCCESS) 838 logprintf_size(uintval); 839 else 840 return (err); 841 842 /* Implementation */ 843 impl_name = NULL; 844 err = picldiag_get_string_propval(nodeh, PICL_PROP_NAME, &impl_name); 845 if (err != PICL_SUCCESS) 846 log_printf(dgettext(TEXT_DOMAIN, " <unknown> ")); 847 else 848 log_printf(" %-22s ", impl_name); 849 850 /* CPU Mask */ 851 uintval = picldiag_get_uint_propval(nodeh, OBP_PROP_MASK, &err); 852 if (err == PICL_PROPNOTFOUND) 853 log_printf(" - "); 854 else if (err == PICL_SUCCESS) 855 log_printf("%2lld.%-2lld ", (uintval >> 4) & 0xf, 856 uintval & 0xf); 857 else 858 return (err); 859 860 /* 861 * Status - if the node has a status property then display that 862 * otherwise display the State property 863 */ 864 err = picldiag_get_string_propval(nodeh, PICL_PROP_STATUS, &status); 865 if (err == PICL_SUCCESS) { 866 log_printf("%-12s", status); 867 free(status); 868 } else if (err != PICL_PROPNOTFOUND && err != 869 PICL_PROPVALUNAVAILABLE && err != PICL_ENDOFLIST) { 870 return (err); 871 } else { 872 err = picldiag_get_string_propval(nodeh, 873 PICL_PROP_STATE, &status); 874 if (err == PICL_SUCCESS) { 875 log_printf("%-12s", status); 876 free(status); 877 } else if (err != PICL_PROPNOTFOUND && err != 878 PICL_PROPVALUNAVAILABLE && err != 879 PICL_ENDOFLIST) { 880 return (err); 881 } else { 882 log_printf(dgettext(TEXT_DOMAIN, "unknown ")); 883 } 884 } 885 886 /* 887 * Location: use label of fru parent 888 */ 889 err = picldiag_get_fru_parent(nodeh, &parenth); 890 if (err == PICL_PROPNOTFOUND) { 891 log_printf(" - "); 892 } else if (err == PICL_SUCCESS) { 893 err = picldiag_get_combined_label(parenth, &label, 12); 894 if (err == PICL_PROPNOTFOUND) 895 log_printf(" - "); 896 else if (err == PICL_SUCCESS) { 897 log_printf("%s", label); 898 free(label); 899 } else 900 return (err); 901 } else 902 return (err); 903 904 log_printf("\n"); 905 return (PICL_WALK_CONTINUE); 906 } 907 908 /* 909 * display cpu information 910 */ 911 static int 912 display_cpu_info(picl_nodehdl_t plafh) 913 { 914 int err; 915 916 /* 917 * Display the table header for CPUs . Then display the CPU 918 * frequency, cache size, and processor revision on all the boards. 919 */ 920 logprintf_header(dgettext(TEXT_DOMAIN, "CPUs"), DEFAULT_LINE_WIDTH); 921 log_printf(dgettext(TEXT_DOMAIN, " E$ CPU" 922 " CPU\n")); 923 log_printf(dgettext(TEXT_DOMAIN, 924 "CPU Freq Size Implementation" 925 " Mask Status Location\n")); 926 log_printf("--- -------- ---------- --------------------- " 927 "----- ------ --------\n"); 928 929 err = picl_walk_tree_by_class(plafh, PICL_CLASS_CPU, PICL_CLASS_CPU, 930 cpu_callback); 931 return (err); 932 } 933 934 /* 935 * Inserts an io_card structure into the list. 936 */ 937 static void 938 add_io_card(uint32_t board, uint32_t bus_id, uint32_t slot, char *label, 939 uint32_t freq, char *name, char *model, char *status, char *devfs_path) 940 { 941 struct io_card card; 942 943 card.display = 1; 944 card.board = board; 945 switch (bus_id) { 946 case PCI_TYPE: 947 strlcpy(card.bus_type, PCI_NAME, MAXSTRLEN); 948 break; 949 default: /* won't reach here */ 950 strlcpy(card.bus_type, "", MAXSTRLEN); 951 break; 952 } 953 if (label == NULL) 954 card.slot = slot; 955 else { 956 card.slot = PCI_SLOT_IS_STRING; 957 (void) strlcpy(card.slot_str, label, MAXSTRLEN); 958 } 959 card.freq = freq; 960 card.status[0] = '\0'; 961 card.name[0] = '\0'; 962 card.model[0] = '\0'; 963 card.notes[0] = '\0'; 964 if (status != NULL) 965 strlcpy(card.status, status, MAXSTRLEN); 966 if (name != NULL) 967 strlcpy(card.name, name, MAXSTRLEN); 968 if (model != NULL) 969 strlcpy(card.model, model, MAXSTRLEN); 970 if (status != NULL) 971 strlcpy(card.status, status, MAXSTRLEN); 972 if (devfs_path != NULL) 973 strlcpy(card.notes, devfs_path, MAXSTRLEN); 974 975 io_card_list = insert_io_card(io_card_list, &card); 976 } 977 978 static void 979 append_to_bank_list(bank_list_t *newptr) 980 { 981 bank_list_t *ptr; 982 983 if (mem_banks == NULL) { 984 mem_banks = newptr; 985 return; 986 } 987 ptr = mem_banks; 988 while (ptr->next != NULL) 989 ptr = ptr->next; 990 991 ptr->next = newptr; 992 } 993 994 static void 995 free_bank_list(void) 996 { 997 bank_list_t *ptr; 998 bank_list_t *tmp; 999 1000 for (ptr = mem_banks; ptr != NULL; ptr = tmp) { 1001 tmp = ptr->next; 1002 free(ptr); 1003 } 1004 mem_banks = NULL; 1005 } 1006 1007 1008 /* 1009 * print label for memory module 1010 */ 1011 static int 1012 logprintf_memory_module_label(picl_nodehdl_t moduleh) 1013 { 1014 picl_nodehdl_t fruparenth; 1015 int err; 1016 char *label; 1017 1018 err = picldiag_get_fru_parent(moduleh, &fruparenth); 1019 if (err == PICL_PROPNOTFOUND) { 1020 log_printf("-"); 1021 return (PICL_SUCCESS); 1022 } else if (err != PICL_SUCCESS) 1023 return (err); 1024 1025 err = picldiag_get_combined_label(fruparenth, &label, 30); 1026 if (err == PICL_PROPNOTFOUND) 1027 log_printf("-"); 1028 else if (err == PICL_SUCCESS) { 1029 log_printf("%-15s", label); 1030 free(label); 1031 } else 1032 return (err); 1033 1034 return (PICL_SUCCESS); 1035 } 1036 1037 /* 1038 * print the bank id and add the bank handle in the bank list 1039 * return the head of the bank list 1040 */ 1041 static int 1042 membank_callback(picl_nodehdl_t bankh, void *args) 1043 { 1044 int err; 1045 int64_t id; 1046 uint64_t match; 1047 uint64_t mask; 1048 int i; 1049 bank_list_t *newptr; 1050 seg_info_t *segp = args; 1051 1052 /* 1053 * print the bank id in the segment table contains column 1054 */ 1055 id = picldiag_get_uint_propval(bankh, PICL_PROP_ID, &err); 1056 if (segp->bank_count > 0) 1057 log_printf(","); 1058 if (err == PICL_PROPNOTFOUND) 1059 log_printf("-"); 1060 else if (err == PICL_SUCCESS) 1061 log_printf("%-lld", id); 1062 else 1063 return (err); 1064 segp->bank_count++; 1065 1066 /* 1067 * Save the bank information for later (print_bank_table) 1068 */ 1069 newptr = malloc(sizeof (*newptr)); 1070 if (newptr == NULL) 1071 return (PICL_FAILURE); 1072 1073 newptr->nodeh = bankh; 1074 newptr->iway_count = 0; 1075 newptr->next = NULL; 1076 append_to_bank_list(newptr); 1077 1078 /* 1079 * Compute the way numbers for the bank 1080 */ 1081 if (no_xfer_size) 1082 return (PICL_WALK_CONTINUE); 1083 1084 match = picldiag_get_uint_propval(bankh, PICL_PROP_ADDRESSMATCH, &err); 1085 if (err == PICL_PROPNOTFOUND) 1086 return (PICL_WALK_CONTINUE); 1087 else if (err != PICL_SUCCESS) 1088 return (err); 1089 1090 mask = picldiag_get_uint_propval(bankh, PICL_PROP_ADDRESSMASK, &err); 1091 if (err == PICL_PROPNOTFOUND) 1092 return (PICL_WALK_CONTINUE); 1093 else if (err != PICL_SUCCESS) 1094 return (err); 1095 1096 i = 0; 1097 while ((i < segp->ifactor) && (newptr->iway_count < MAX_IWAYS)) { 1098 if (((segp->base + i * mem_xfersize) & mask) == match) 1099 newptr->iway[newptr->iway_count++] = i; 1100 ++i; 1101 } 1102 return (PICL_WALK_CONTINUE); 1103 } 1104 1105 1106 /* 1107 * find the memory bank and add the bank handle in the bank list 1108 * return the head of the bank list 1109 */ 1110 static int 1111 logprintf_bankinfo(picl_nodehdl_t segh, seg_info_t *segp) 1112 { 1113 int err; 1114 1115 log_printf(dgettext(TEXT_DOMAIN, "BankIDs ")); 1116 /* 1117 * find memory-bank 1118 */ 1119 segp->bank_count = 0; 1120 err = picl_walk_tree_by_class(segh, PICL_CLASS_MEMORY_BANK, segp, 1121 membank_callback); 1122 log_printf("\n"); 1123 return (err); 1124 } 1125 1126 /* 1127 * print the label of memory module or the memory module bank ids 1128 */ 1129 static int 1130 logprintf_seg_contains_col(picl_nodehdl_t nodeh, seg_info_t *segp) 1131 { 1132 picl_nodehdl_t moduleh; 1133 int err; 1134 1135 /* 1136 * find memory-module if referenced directly from the memory-segment 1137 * (ie no memory banks) 1138 */ 1139 err = picl_get_propval_by_name(nodeh, PICL_REFPROP_MEMORY_MODULE, 1140 &moduleh, sizeof (moduleh)); 1141 if ((err != PICL_SUCCESS) && (err != PICL_PROPNOTFOUND)) 1142 return (err); 1143 if (err == PICL_SUCCESS) { 1144 err = logprintf_memory_module_label(moduleh); 1145 log_printf("\n"); 1146 return (err); 1147 } 1148 1149 /* 1150 * memory-module not referenced directly from the memory segment 1151 * so list memory banks instead 1152 */ 1153 err = logprintf_bankinfo(nodeh, segp); 1154 return (err); 1155 } 1156 1157 /* 1158 * find all memory modules under the given memory module group 1159 * and print its label 1160 */ 1161 static int 1162 logprintf_memory_module_group_info(picl_nodehdl_t memgrph, uint64_t mcid) 1163 { 1164 int err; 1165 int64_t id; 1166 boolean_t got_status; 1167 picl_nodehdl_t moduleh; 1168 char piclclass[PICL_CLASSNAMELEN_MAX]; 1169 picl_nodehdl_t fruparenth; 1170 char *status; 1171 1172 id = picldiag_get_uint_propval(memgrph, PICL_PROP_ID, &err); 1173 if (err == PICL_PROPNOTFOUND) 1174 id = -1; 1175 else if (err != PICL_SUCCESS) 1176 return (err); 1177 1178 err = picl_get_propval_by_name(memgrph, PICL_PROP_CHILD, &moduleh, 1179 sizeof (picl_nodehdl_t)); 1180 1181 while (err == PICL_SUCCESS) { 1182 /* controller id */ 1183 log_printf("%-8lld ", mcid); 1184 1185 /* group id */ 1186 if (id == -1) { 1187 log_printf("- "); 1188 } else { 1189 log_printf("%-8lld ", id); 1190 } 1191 1192 err = picl_get_propval_by_name(moduleh, PICL_PROP_CLASSNAME, 1193 piclclass, sizeof (piclclass)); 1194 if (err != PICL_SUCCESS) 1195 return (err); 1196 1197 if (strcmp(piclclass, PICL_CLASS_MEMORY_MODULE) == 0) { 1198 err = logprintf_memory_module_label(moduleh); 1199 if (err != PICL_SUCCESS) 1200 return (err); 1201 } 1202 1203 got_status = B_FALSE; 1204 err = picldiag_get_fru_parent(moduleh, &fruparenth); 1205 if (err == PICL_SUCCESS) { 1206 err = picldiag_get_string_propval(fruparenth, 1207 PICL_PROP_OPERATIONAL_STATUS, &status); 1208 if (err == PICL_SUCCESS) { 1209 got_status = B_TRUE; 1210 } else if (err != PICL_PROPNOTFOUND) 1211 return (err); 1212 } else if (err != PICL_PROPNOTFOUND) 1213 return (err); 1214 1215 if (!got_status) { 1216 err = picldiag_get_string_propval(moduleh, 1217 PICL_PROP_STATUS, &status); 1218 if (err == PICL_SUCCESS) 1219 got_status = B_TRUE; 1220 else if (err != PICL_PROPNOTFOUND) 1221 return (err); 1222 } 1223 if (got_status) { 1224 log_printf("%s", status); 1225 free(status); 1226 } 1227 err = picl_get_propval_by_name(moduleh, PICL_PROP_PEER, 1228 &moduleh, sizeof (picl_nodehdl_t)); 1229 1230 log_printf("\n"); 1231 } 1232 if (err == PICL_PROPNOTFOUND) 1233 return (PICL_SUCCESS); 1234 return (err); 1235 } 1236 1237 /* 1238 * search children to find memory module group under memory-controller 1239 */ 1240 static int 1241 find_memory_module_group(picl_nodehdl_t mch, int *print_header) 1242 { 1243 picl_nodehdl_t memgrph; 1244 uint64_t mcid; 1245 int err; 1246 char piclclass[PICL_CLASSNAMELEN_MAX]; 1247 1248 mcid = picldiag_get_uint_propval(mch, OBP_PROP_PORTID, &err); 1249 if (err == PICL_PROPNOTFOUND) 1250 mcid = DEFAULT_PORTID; 1251 else if (err != PICL_SUCCESS) 1252 return (err); 1253 1254 err = picl_get_propval_by_name(mch, PICL_PROP_CHILD, 1255 &memgrph, sizeof (picl_nodehdl_t)); 1256 while (err == PICL_SUCCESS) { 1257 err = picl_get_propval_by_name(memgrph, 1258 PICL_PROP_CLASSNAME, piclclass, sizeof (piclclass)); 1259 if (err != PICL_SUCCESS) 1260 return (err); 1261 1262 if (strcmp(piclclass, PICL_CLASS_MEMORY_MODULE_GROUP) == 0) { 1263 if (*print_header == 1) { 1264 log_printf( 1265 dgettext(TEXT_DOMAIN, 1266 "\nMemory Module Groups:\n")); 1267 log_printf("--------------------------"); 1268 log_printf("------\n"); 1269 log_printf(dgettext(TEXT_DOMAIN, 1270 "ControllerID GroupID Labels\n")); 1271 log_printf("--------------------------"); 1272 log_printf("------\n"); 1273 *print_header = 0; 1274 } 1275 err = logprintf_memory_module_group_info(memgrph, mcid); 1276 if (err != PICL_SUCCESS) 1277 return (err); 1278 } 1279 1280 err = picl_get_propval_by_name(memgrph, PICL_PROP_PEER, 1281 &memgrph, sizeof (picl_nodehdl_t)); 1282 } 1283 if (err == PICL_PROPNOTFOUND) 1284 return (PICL_SUCCESS); 1285 return (err); 1286 } 1287 1288 /* 1289 * print memory module group table per memory-controller 1290 */ 1291 static int 1292 print_memory_module_group_table(picl_nodehdl_t plafh) 1293 { 1294 picl_nodehdl_t mch; 1295 int err; 1296 char piclclass[PICL_CLASSNAMELEN_MAX]; 1297 int print_header; 1298 1299 print_header = 1; 1300 1301 /* 1302 * find memory-controller 1303 */ 1304 err = picl_get_propval_by_name(plafh, PICL_PROP_CHILD, &mch, 1305 sizeof (picl_nodehdl_t)); 1306 while (err == PICL_SUCCESS) { 1307 err = picl_get_propval_by_name(mch, PICL_PROP_CLASSNAME, 1308 piclclass, sizeof (piclclass)); 1309 if (err != PICL_SUCCESS) 1310 return (err); 1311 1312 if (strcmp(piclclass, PICL_CLASS_MEMORY_CONTROLLER) != 0) { 1313 err = print_memory_module_group_table(mch); 1314 if (err != PICL_SUCCESS) 1315 return (err); 1316 err = picl_get_propval_by_name(mch, PICL_PROP_PEER, 1317 &mch, sizeof (picl_nodehdl_t)); 1318 continue; 1319 } 1320 1321 err = find_memory_module_group(mch, &print_header); 1322 if (err != PICL_SUCCESS) 1323 return (err); 1324 1325 err = picl_get_propval_by_name(mch, PICL_PROP_PEER, 1326 &mch, sizeof (picl_nodehdl_t)); 1327 } 1328 if (err == PICL_PROPNOTFOUND) 1329 return (PICL_SUCCESS); 1330 1331 return (err); 1332 } 1333 1334 /* 1335 * print bank table 1336 */ 1337 static int 1338 print_bank_table(void) 1339 { 1340 bank_list_t *ptr; 1341 picl_nodehdl_t bankh; 1342 picl_nodehdl_t memgrph; 1343 picl_nodehdl_t mch; 1344 int err; 1345 int32_t i; 1346 uint64_t size; 1347 int id; 1348 1349 log_printf(dgettext(TEXT_DOMAIN, "\nBank Table:\n")); 1350 log_printf("---------------------------------------"); 1351 log_printf("--------------------\n"); 1352 log_printf(dgettext(TEXT_DOMAIN, " Physical Location\n")); 1353 log_printf(dgettext(TEXT_DOMAIN, "ID ControllerID GroupID ")); 1354 log_printf(dgettext(TEXT_DOMAIN, "Size Interleave Way\n")); 1355 log_printf("---------------------------------------"); 1356 log_printf("--------------------\n"); 1357 1358 for (ptr = mem_banks; ptr != NULL; ptr = ptr->next) { 1359 bankh = ptr->nodeh; 1360 id = picldiag_get_uint_propval(bankh, PICL_PROP_ID, &err); 1361 if (err != PICL_SUCCESS) 1362 log_printf("%-8s ", "-"); 1363 else 1364 log_printf("%-8d ", id); 1365 1366 /* find memory-module-group */ 1367 err = picl_get_propval_by_name(bankh, 1368 PICL_REFPROP_MEMORY_MODULE_GROUP, &memgrph, 1369 sizeof (memgrph)); 1370 if (err == PICL_PROPNOTFOUND) { 1371 log_printf("%-8s ", "-"); 1372 log_printf("%-8s ", "-"); 1373 } else if (err != PICL_SUCCESS) 1374 return (err); 1375 else { 1376 /* 1377 * get controller id 1378 */ 1379 err = picl_get_propval_by_name(memgrph, 1380 PICL_PROP_PARENT, &mch, sizeof (picl_nodehdl_t)); 1381 if (err != PICL_SUCCESS) 1382 return (err); 1383 1384 id = picldiag_get_uint_propval(mch, OBP_PROP_PORTID, 1385 &err); 1386 if (err == PICL_PROPNOTFOUND) 1387 id = DEFAULT_PORTID; /* use default */ 1388 else if (err != PICL_SUCCESS) 1389 return (err); 1390 1391 log_printf("%-8d ", id); 1392 1393 /* get group id */ 1394 id = picldiag_get_uint_propval(memgrph, PICL_PROP_ID, 1395 &err); 1396 if (err == PICL_PROPNOTFOUND) 1397 log_printf("- "); 1398 else if (err == PICL_SUCCESS) 1399 log_printf("%-8d ", id); 1400 else 1401 return (err); 1402 } 1403 1404 size = picldiag_get_uint_propval(bankh, PICL_PROP_SIZE, &err); 1405 if (err == PICL_PROPNOTFOUND) 1406 log_printf("- "); 1407 else if (err == PICL_SUCCESS) 1408 logprintf_size(size); 1409 else 1410 return (err); 1411 1412 log_printf(" "); 1413 for (i = 0; i < ptr->iway_count; i++) { 1414 if (i != 0) 1415 log_printf(","); 1416 log_printf("%d", ptr->iway[i]); 1417 } 1418 1419 log_printf("\n"); 1420 } 1421 return (PICL_SUCCESS); 1422 } 1423 1424 /* 1425 * callback function to print segment, add the bank in the list and 1426 * return the bank list 1427 */ 1428 /* ARGSUSED */ 1429 static int 1430 memseg_callback(picl_nodehdl_t segh, void *args) 1431 { 1432 seg_info_t seginfo; 1433 int err; 1434 1435 /* get base address */ 1436 seginfo.base = picldiag_get_uint_propval(segh, PICL_PROP_BASEADDRESS, 1437 &err); 1438 if (err == PICL_PROPNOTFOUND) { 1439 log_printf("-\n"); 1440 return (PICL_WALK_CONTINUE); 1441 } else if (err == PICL_SUCCESS) 1442 log_printf("0x%-16llx ", seginfo.base); 1443 else 1444 return (err); 1445 1446 /* get size */ 1447 seginfo.size = picldiag_get_uint_propval(segh, PICL_PROP_SIZE, &err); 1448 if (err == PICL_PROPNOTFOUND) { 1449 log_printf("-\n"); 1450 return (PICL_WALK_CONTINUE); 1451 } else if (err == PICL_SUCCESS) 1452 logprintf_size(seginfo.size); 1453 else 1454 return (err); 1455 1456 /* get interleave factor */ 1457 seginfo.ifactor = picldiag_get_uint_propval(segh, 1458 PICL_PROP_INTERLEAVE_FACTOR, &err); 1459 1460 if (err == PICL_PROPNOTFOUND) { 1461 log_printf(" -\n"); 1462 return (PICL_WALK_CONTINUE); 1463 } else if (err == PICL_SUCCESS) 1464 log_printf(" %-2d ", seginfo.ifactor); 1465 else 1466 return (err); 1467 1468 seginfo.bank_count = 0; 1469 err = logprintf_seg_contains_col(segh, &seginfo); 1470 if (err != PICL_SUCCESS) 1471 return (err); 1472 return (PICL_WALK_CONTINUE); 1473 } 1474 1475 /* 1476 * search children to find memory-segment and set up the bank list 1477 */ 1478 static int 1479 find_segments(picl_nodehdl_t plafh) 1480 { 1481 int err; 1482 1483 log_printf(dgettext(TEXT_DOMAIN, "Segment Table:\n")); 1484 log_printf("------------------------------"); 1485 log_printf("-----------------------------------------\n"); 1486 log_printf(dgettext(TEXT_DOMAIN, "Base Address Size ")); 1487 log_printf(dgettext(TEXT_DOMAIN, "Interleave Factor Contains\n")); 1488 log_printf("------------------------------"); 1489 log_printf("-----------------------------------------\n"); 1490 1491 err = picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY_SEGMENT, 1492 NULL, memseg_callback); 1493 return (err); 1494 } 1495 1496 /* 1497 * display memory configuration 1498 */ 1499 static int 1500 display_memory_config(picl_nodehdl_t plafh) 1501 { 1502 int err; 1503 1504 logprintf_header(dgettext(TEXT_DOMAIN, "Memory Configuration"), 1505 DEFAULT_LINE_WIDTH); 1506 1507 mem_banks = NULL; 1508 err = find_segments(plafh); 1509 1510 if ((err == PICL_SUCCESS) && (mem_banks != NULL)) 1511 print_bank_table(); 1512 1513 free_bank_list(); 1514 1515 return (print_memory_module_group_table(plafh)); 1516 } 1517 1518 /* 1519 * print the hub device 1520 */ 1521 static int 1522 logprintf_hub_devices(picl_nodehdl_t hubh) 1523 { 1524 char *name; 1525 int portnum; 1526 char *labelp; 1527 picl_nodehdl_t parenth; 1528 int err; 1529 1530 err = picldiag_get_string_propval(hubh, PICL_PROP_NAME, &name); 1531 if (err != PICL_SUCCESS) 1532 return (err); 1533 log_printf("%-12.12s ", name); 1534 free(name); 1535 1536 err = picl_get_propval_by_name(hubh, PICL_REFPROP_LOC_PARENT, &parenth, 1537 sizeof (picl_nodehdl_t)); 1538 1539 if (err == PICL_SUCCESS) { 1540 /* Read the Label */ 1541 err = picldiag_get_label(parenth, &labelp); 1542 if (err == PICL_SUCCESS) { 1543 log_printf("%s\n", labelp); 1544 free(labelp); 1545 return (PICL_SUCCESS); 1546 } else if (err != PICL_PROPNOTFOUND) { 1547 log_printf("\n"); 1548 return (err); 1549 } 1550 } else if (err != PICL_PROPNOTFOUND) { 1551 log_printf("\n"); 1552 return (err); 1553 } 1554 1555 /* No Label, try the reg */ 1556 err = picl_get_propval_by_name(hubh, OBP_PROP_REG, &portnum, 1557 sizeof (portnum)); 1558 if (err == PICL_PROPNOTFOUND) 1559 log_printf(" -\n"); 1560 else if (err != PICL_SUCCESS) { 1561 log_printf("\n"); 1562 return (err); 1563 } else 1564 log_printf("%3d\n", portnum); 1565 1566 return (PICL_SUCCESS); 1567 } 1568 1569 /* 1570 * callback functions to display hub devices 1571 */ 1572 /* ARGSUSED */ 1573 static int 1574 print_usb_devices(picl_nodehdl_t hubh, void *arg) 1575 { 1576 picl_nodehdl_t chdh; 1577 char *rootname; 1578 int type = *(int *)arg; 1579 int hubnum; 1580 int err; 1581 1582 err = picl_get_propval_by_name(hubh, PICL_PROP_CHILD, &chdh, 1583 sizeof (picl_nodehdl_t)); 1584 1585 /* print header */ 1586 if (err == PICL_SUCCESS) { 1587 err = picldiag_get_string_propval(hubh, PICL_PROP_NAME, 1588 &rootname); 1589 if (err != PICL_SUCCESS) 1590 return (err); 1591 1592 if (type == USB) { 1593 log_printf("\n==============================="); 1594 log_printf(dgettext(TEXT_DOMAIN, 1595 " %s Devices "), rootname); 1596 } else { 1597 /* Get its hub number */ 1598 err = picl_get_propval_by_name(hubh, 1599 OBP_PROP_REG, &hubnum, sizeof (hubnum)); 1600 if ((err != PICL_SUCCESS) && 1601 (err != PICL_PROPNOTFOUND)) { 1602 free(rootname); 1603 return (err); 1604 } 1605 1606 log_printf("\n==============================="); 1607 if (err == PICL_SUCCESS) 1608 log_printf(dgettext(TEXT_DOMAIN, 1609 " %s#%d Devices "), 1610 rootname, hubnum); 1611 else 1612 log_printf(dgettext(TEXT_DOMAIN, 1613 " %s Devices "), rootname); 1614 } 1615 1616 log_printf("===============================\n\n"); 1617 log_printf(dgettext(TEXT_DOMAIN, "Name Port#\n")); 1618 log_printf("------------ -----\n"); 1619 free(rootname); 1620 1621 do { 1622 logprintf_hub_devices(chdh); 1623 1624 err = picl_get_propval_by_name(chdh, PICL_PROP_PEER, 1625 &chdh, sizeof (picl_nodehdl_t)); 1626 } while (err == PICL_SUCCESS); 1627 } 1628 1629 1630 if (err == PICL_PROPNOTFOUND) 1631 return (PICL_WALK_CONTINUE); 1632 return (err); 1633 } 1634 1635 /* 1636 * callback functions to display usb devices 1637 */ 1638 /* ARGSUSED */ 1639 static int 1640 usb_callback(picl_nodehdl_t usbh, void *args) 1641 { 1642 int err; 1643 int type; 1644 1645 type = USB; 1646 err = print_usb_devices(usbh, &type); 1647 if (err != PICL_WALK_CONTINUE) 1648 return (err); 1649 type = HUB; 1650 err = picl_walk_tree_by_class(usbh, NULL, &type, print_usb_devices); 1651 if (err == PICL_SUCCESS) 1652 err = PICL_WALK_CONTINUE; 1653 return (err); 1654 } 1655 1656 1657 /* 1658 * find usb devices and print its information 1659 */ 1660 static int 1661 display_usb_devices(picl_nodehdl_t plafh) 1662 { 1663 int err; 1664 1665 /* 1666 * get the usb node 1667 */ 1668 err = picl_walk_tree_by_class(plafh, PICL_CLASS_USB, NULL, 1669 usb_callback); 1670 return (err); 1671 } 1672 1673 1674 1675 /* 1676 * If nodeh is the io device, add it into the io list and return 1677 * If it is not an io device and it has the subtree, traverse the subtree 1678 * and add all leaf io devices 1679 */ 1680 static int 1681 add_io_leaves(picl_nodehdl_t nodeh, char *parentname, uint32_t board, 1682 uint32_t bus_id, uint64_t slot, uint32_t freq, char *model, char *status) 1683 { 1684 picl_nodehdl_t childh; 1685 picl_prophdl_t proph; 1686 picl_propinfo_t pinfo; 1687 int err; 1688 char *nameval; 1689 char piclclass[PICL_CLASSNAMELEN_MAX]; 1690 char nodename[MAXSTRLEN]; 1691 char name[MAXSTRLEN]; 1692 char *devfs_path; 1693 char *compatible; 1694 picl_nodehdl_t fruparenth; 1695 char *label; 1696 char binding_name[MAXSTRLEN]; 1697 1698 err = picl_get_propinfo_by_name(nodeh, PICL_PROP_NAME, &pinfo, 1699 &proph); 1700 if (err != PICL_SUCCESS) 1701 return (err); 1702 1703 nameval = alloca(pinfo.size); 1704 if (nameval == NULL) 1705 return (PICL_FAILURE); 1706 1707 err = picl_get_propval(proph, nameval, pinfo.size); 1708 if (err != PICL_SUCCESS) 1709 return (err); 1710 1711 (void) strlcpy(nodename, nameval, MAXSTRLEN); 1712 1713 err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME, 1714 piclclass, sizeof (piclclass)); 1715 if (err != PICL_SUCCESS) 1716 return (err); 1717 1718 /* if binding_name is found, name will be <nodename>-<binding_name> */ 1719 err = picl_get_propval_by_name(nodeh, PICL_PROP_BINDING_NAME, 1720 binding_name, sizeof (binding_name)); 1721 if (err == PICL_PROPNOTFOUND) { 1722 /* 1723 * if compatible prop is found, name will be 1724 * <nodename>-<compatible> 1725 */ 1726 err = picldiag_get_first_compatible_value(nodeh, &compatible); 1727 if (err == PICL_SUCCESS) { 1728 strlcat(nodename, "-", MAXSTRLEN); 1729 strlcat(nodename, compatible, MAXSTRLEN); 1730 free(compatible); 1731 } else if (err != PICL_PROPNOTFOUND) { 1732 return (err); 1733 } 1734 } else if (err != PICL_SUCCESS) { 1735 return (err); 1736 } else if (strcmp(nodename, binding_name) != 0) { 1737 if (strcmp(nodename, piclclass) == 0) { 1738 /* 1739 * nodename same as binding name - 1740 * no need to display twice 1741 */ 1742 strlcpy(nodename, binding_name, MAXSTRLEN); 1743 } else { 1744 strlcat(nodename, "-", MAXSTRLEN); 1745 strlcat(nodename, binding_name, MAXSTRLEN); 1746 } 1747 } 1748 1749 /* 1750 * If it is an immediate child under pci and not 1751 * a bus node, add it to the io list. 1752 * If it is a child under sub-bus and it is in an io 1753 * device, add it to the io list. 1754 */ 1755 if (((parentname == NULL) && (!is_bus(piclclass))) || 1756 ((parentname != NULL) && (is_io_device(piclclass)))) { 1757 if (parentname == NULL) 1758 (void) snprintf(name, MAXSTRLEN, "%s", nodename); 1759 else 1760 (void) snprintf(name, MAXSTRLEN, "%s/%s", parentname, 1761 nodename); 1762 1763 /* 1764 * append the class if its class is not a generic 1765 * obp-device class 1766 */ 1767 if (strcmp(piclclass, PICL_CLASS_OBP_DEVICE)) 1768 (void) snprintf(name, MAXSTRLEN, "%s (%s)", name, 1769 piclclass); 1770 1771 err = picldiag_get_fru_parent(nodeh, &fruparenth); 1772 if (err == PICL_PROPNOTFOUND) { 1773 label = NULL; 1774 } else if (err != PICL_SUCCESS) { 1775 return (err); 1776 } else { 1777 err = picldiag_get_combined_label(fruparenth, &label, 1778 15); 1779 if (err == PICL_PROPNOTFOUND) 1780 label = NULL; 1781 else if (err != PICL_SUCCESS) 1782 return (err); 1783 } 1784 /* devfs-path */ 1785 err = picldiag_get_string_propval(nodeh, PICL_PROP_DEVFS_PATH, 1786 &devfs_path); 1787 if (err == PICL_PROPNOTFOUND) 1788 devfs_path = NULL; 1789 else if (err != PICL_SUCCESS) 1790 return (err); 1791 1792 add_io_card(board, bus_id, slot, label, freq, name, 1793 model, status, devfs_path); 1794 if (label != NULL) 1795 free(label); 1796 if (devfs_path != NULL) 1797 free(devfs_path); 1798 return (PICL_SUCCESS); 1799 } 1800 1801 /* 1802 * If there is any child, Go through each child. 1803 */ 1804 1805 err = picl_get_propval_by_name(nodeh, PICL_PROP_CHILD, 1806 &childh, sizeof (picl_nodehdl_t)); 1807 1808 /* there is a child */ 1809 while (err == PICL_SUCCESS) { 1810 if (parentname == NULL) 1811 (void) strlcpy(name, nodename, MAXSTRLEN); 1812 else 1813 (void) snprintf(name, MAXSTRLEN, "%s/%s", parentname, 1814 nodename); 1815 1816 err = add_io_leaves(childh, name, board, bus_id, slot, freq, 1817 model, status); 1818 if (err != PICL_SUCCESS) 1819 return (err); 1820 /* 1821 * get next child 1822 */ 1823 err = picl_get_propval_by_name(childh, PICL_PROP_PEER, 1824 &childh, sizeof (picl_nodehdl_t)); 1825 } 1826 1827 if (err == PICL_PROPNOTFOUND) 1828 return (PICL_SUCCESS); 1829 return (err); 1830 } 1831 1832 1833 /* 1834 * add all io devices under pci in io list 1835 */ 1836 /* ARGSUSED */ 1837 static int 1838 pci_callback(picl_nodehdl_t pcih, void *args) 1839 { 1840 picl_nodehdl_t nodeh; 1841 int err; 1842 char piclclass[PICL_CLASSNAMELEN_MAX]; 1843 uint32_t boardnum; 1844 uint32_t bus_id; 1845 uint32_t slot; 1846 uint32_t freq; 1847 char *model; 1848 char *status; 1849 1850 /* Fill in common infomation */ 1851 bus_id = PCI_TYPE; 1852 1853 /* 1854 * Check if it has the freq, if not, 1855 * If not, use its parent's freq 1856 * if its parent's freq is not found, return 1857 */ 1858 err = picldiag_get_clock_freq(pcih, &freq); 1859 if (err == PICL_PROPNOTFOUND) { 1860 err = picldiag_get_clock_from_parent(pcih, &freq); 1861 if (err == PICL_PROPNOTFOUND) 1862 return (PICL_WALK_CONTINUE); 1863 else if (err != PICL_SUCCESS) 1864 return (err); 1865 } else if (err != PICL_SUCCESS) 1866 return (err); 1867 1868 /* 1869 * If no board# is found, set boardnum to 0 1870 */ 1871 boardnum = picldiag_get_uint_propval(pcih, OBP_PROP_BOARD_NUM, &err); 1872 if (err == PICL_PROPNOTFOUND) 1873 boardnum = DEFAULT_BOARD_NUM; 1874 else if (err != PICL_SUCCESS) 1875 return (err); 1876 1877 /* Walk through the children */ 1878 1879 err = picl_get_propval_by_name(pcih, PICL_PROP_CHILD, &nodeh, 1880 sizeof (picl_nodehdl_t)); 1881 while (err == PICL_SUCCESS) { 1882 err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME, 1883 piclclass, sizeof (piclclass)); 1884 if (err != PICL_SUCCESS) 1885 return (err); 1886 1887 /* 1888 * Skip PCI bridge and USB devices because they will be 1889 * processed later 1890 */ 1891 if ((strcmp(piclclass, PICL_CLASS_PCI) == 0) || 1892 (strcmp(piclclass, PICL_CLASS_USB) == 0)) { 1893 err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, 1894 &nodeh, sizeof (picl_nodehdl_t)); 1895 continue; 1896 } 1897 1898 /* Get the device id for pci card */ 1899 slot = picldiag_get_uint_propval(nodeh, 1900 PICL_PROP_DEVICE_ID, &err); 1901 if (err == PICL_PROPNOTFOUND) { 1902 err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, 1903 &nodeh, sizeof (picl_nodehdl_t)); 1904 continue; 1905 } else if (err != PICL_SUCCESS) 1906 return (err); 1907 1908 /* Get the model of this card */ 1909 err = picldiag_get_string_propval(nodeh, OBP_PROP_MODEL, 1910 &model); 1911 if (err == PICL_PROPNOTFOUND) 1912 model = NULL; 1913 else if (err != PICL_SUCCESS) 1914 return (err); 1915 1916 err = picldiag_get_string_propval(nodeh, PICL_PROP_STATUS, 1917 &status); 1918 if (err == PICL_PROPNOTFOUND) { 1919 status = malloc(5); 1920 if (status == NULL) 1921 return (PICL_FAILURE); 1922 strlcpy(status, "okay", 5); 1923 } else if (err != PICL_SUCCESS) 1924 return (err); 1925 1926 err = add_io_leaves(nodeh, NULL, boardnum, bus_id, slot, 1927 freq, model, status); 1928 1929 if (model != NULL) 1930 free(model); 1931 1932 if (status != NULL) 1933 free(status); 1934 1935 if (err != PICL_SUCCESS) 1936 return (err); 1937 1938 err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh, 1939 sizeof (picl_nodehdl_t)); 1940 1941 } 1942 1943 if (err == PICL_PROPNOTFOUND) 1944 return (PICL_WALK_CONTINUE); 1945 1946 return (err); 1947 } 1948 1949 1950 /* 1951 * loop through all children and add io devices in io list 1952 */ 1953 static int 1954 process_io_leaves(picl_nodehdl_t rooth) 1955 { 1956 picl_nodehdl_t nodeh; 1957 char classval[PICL_CLASSNAMELEN_MAX]; 1958 int err; 1959 1960 err = picl_get_propval_by_name(rooth, PICL_PROP_CHILD, &nodeh, 1961 sizeof (picl_nodehdl_t)); 1962 while (err == PICL_SUCCESS) { 1963 err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME, 1964 classval, sizeof (classval)); 1965 if (err != PICL_SUCCESS) 1966 return (err); 1967 1968 if (err != PICL_SUCCESS) 1969 return (err); 1970 1971 err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh, 1972 sizeof (picl_nodehdl_t)); 1973 } 1974 1975 if (err == PICL_PROPNOTFOUND) 1976 return (PICL_SUCCESS); 1977 1978 return (err); 1979 } 1980 1981 1982 /* 1983 * find all io devices and add them in the io list 1984 */ 1985 static int 1986 gather_io_cards(picl_nodehdl_t plafh) 1987 { 1988 int err; 1989 1990 /* 1991 * look for io devices under the immediate children of platform 1992 */ 1993 err = process_io_leaves(plafh); 1994 1995 if (err != PICL_SUCCESS) 1996 return (err); 1997 1998 if (err != PICL_SUCCESS) 1999 return (err); 2000 err = picl_walk_tree_by_class(plafh, PICL_CLASS_PCI, 2001 PICL_CLASS_PCI, pci_callback); 2002 if (err != PICL_SUCCESS) 2003 return (err); 2004 return (err); 2005 } 2006 2007 static void 2008 picldiag_display_io_cards(struct io_card *list) 2009 { 2010 static int banner = 0; /* Have we printed the column headings? */ 2011 struct io_card *p; 2012 2013 if (list == NULL) 2014 return; 2015 2016 if (banner == 0) { 2017 log_printf(dgettext(TEXT_DOMAIN, 2018 "Bus Freq Slot + Name +\n"), 0); 2019 log_printf(dgettext(TEXT_DOMAIN, "Type MHz Status " 2020 "Path " 2021 "Model"), 0); 2022 log_printf("\n", 0); 2023 log_printf("---- ---- ---------- " 2024 "---------------------------- " 2025 "--------------------", 0); 2026 log_printf("\n", 0); 2027 banner = 1; 2028 } 2029 2030 for (p = list; p != NULL; p = p -> next) { 2031 log_printf("%-4s ", p->bus_type, 0); 2032 log_printf("%3d ", p->freq, 0); 2033 /* 2034 * We check to see if it's an int or 2035 * a char string to display for slot. 2036 */ 2037 if (p->slot == PCI_SLOT_IS_STRING) 2038 log_printf("%10s ", p->slot_str, 0); 2039 else 2040 log_printf("%10d ", p->slot, 0); 2041 2042 log_printf("%-28.28s", p->name, 0); 2043 if (strlen(p->name) > 28) 2044 log_printf("+ ", 0); 2045 else 2046 log_printf(" ", 0); 2047 log_printf("%-19.19s", p->model, 0); 2048 if (strlen(p->model) > 19) 2049 log_printf("+", 0); 2050 log_printf("\n", 0); 2051 log_printf(" %10s ", p->status, 0); 2052 if (strlen(p->notes) > 0) 2053 log_printf("%s", p->notes, 0); 2054 log_printf("\n\n", 0); 2055 } 2056 } 2057 2058 /* 2059 * display all io devices 2060 */ 2061 static int 2062 display_io_device_info(picl_nodehdl_t plafh) 2063 { 2064 int err; 2065 2066 err = gather_io_cards(plafh); 2067 if (err != PICL_SUCCESS) 2068 return (err); 2069 2070 logprintf_header(dgettext(TEXT_DOMAIN, "IO Devices"), 2071 DEFAULT_LINE_WIDTH); 2072 2073 picldiag_display_io_cards(io_card_list); 2074 2075 free_io_cards(io_card_list); 2076 2077 return (PICL_SUCCESS); 2078 } 2079 2080 /* 2081 * print fan device information 2082 */ 2083 static int 2084 logprintf_fan_info(picl_nodehdl_t fanh) 2085 { 2086 int err; 2087 char *label; 2088 char *unit; 2089 int64_t speed; 2090 int64_t min_speed; 2091 picl_nodehdl_t fruph; 2092 2093 err = picldiag_get_fru_parent(fanh, &fruph); 2094 if (err != PICL_SUCCESS) 2095 return (err); 2096 2097 err = picldiag_get_combined_label(fruph, &label, 14); 2098 if (err != PICL_SUCCESS) 2099 return (err); 2100 2101 log_printf("%-14s ", label); 2102 free(label); 2103 2104 err = picldiag_get_label(fanh, &label); 2105 if (err == PICL_SUCCESS) { 2106 log_printf("%-14s ", label); 2107 free(label); 2108 } else if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) { 2109 log_printf(" - "); 2110 } else 2111 return (err); 2112 2113 speed = picldiag_get_uint_propval(fanh, PICL_PROP_FAN_SPEED, &err); 2114 if (err == PICL_SUCCESS) { 2115 min_speed = picldiag_get_uint_propval(fanh, 2116 PICL_PROP_LOW_WARNING_THRESHOLD, &err); 2117 if (err != PICL_SUCCESS) 2118 min_speed = 0; 2119 if (speed < min_speed) { 2120 log_printf(dgettext(TEXT_DOMAIN, 2121 "failed (%lld"), speed); 2122 err = picldiag_get_string_propval(fanh, 2123 PICL_PROP_FAN_SPEED_UNIT, &unit); 2124 if (err == PICL_SUCCESS) { 2125 log_printf("%s", unit); 2126 free(unit); 2127 } 2128 log_printf(")"); 2129 } else { 2130 log_printf(dgettext(TEXT_DOMAIN, "okay")); 2131 } 2132 } else { 2133 err = picldiag_get_string_propval(fanh, 2134 PICL_PROP_FAN_SPEED_UNIT, &unit); 2135 if (err == PICL_SUCCESS) { 2136 log_printf("%-12s ", unit); 2137 free(unit); 2138 } 2139 } 2140 2141 log_printf("\n"); 2142 return (PICL_SUCCESS); 2143 } 2144 2145 static int 2146 fan_callback(picl_nodehdl_t fanh, void *arg) 2147 { 2148 int *countp = arg; 2149 int err; 2150 2151 if (*countp == 0) { 2152 log_printf(dgettext(TEXT_DOMAIN, "Fan Status:\n")); 2153 log_printf("---------------------------------------\n"); 2154 log_printf(dgettext(TEXT_DOMAIN, 2155 "Location Sensor Status \n")); 2156 log_printf("---------------------------------------\n"); 2157 } 2158 *countp += 1; 2159 err = logprintf_fan_info(fanh); 2160 if (err == PICL_SUCCESS) 2161 return (PICL_WALK_CONTINUE); 2162 return (err); 2163 } 2164 2165 /* 2166 * callback function search children to find fan device and print its speed 2167 */ 2168 static int 2169 display_fan_speed(picl_nodehdl_t plafh) 2170 { 2171 int err; 2172 int print_header; 2173 2174 print_header = 0; 2175 err = picl_walk_tree_by_class(plafh, PICL_CLASS_FAN, 2176 &print_header, fan_callback); 2177 return (err); 2178 } 2179 2180 /* 2181 * print temperature sensor information 2182 */ 2183 static int 2184 logprintf_temp_info(picl_nodehdl_t temph) 2185 { 2186 int err; 2187 char *label; 2188 int64_t temperature; 2189 int64_t threshold; 2190 picl_nodehdl_t fruph; 2191 char *status = "unknown"; 2192 int got_temp = 0; 2193 2194 err = picldiag_get_fru_parent(temph, &fruph); 2195 if (err != PICL_SUCCESS) 2196 return (err); 2197 2198 err = picldiag_get_combined_label(fruph, &label, 14); 2199 if (err != PICL_SUCCESS) 2200 return (err); 2201 2202 log_printf("%-14s ", label); 2203 free(label); 2204 2205 err = picldiag_get_label(temph, &label); 2206 if (err != PICL_SUCCESS) 2207 return (err); 2208 log_printf("%-14s ", label); 2209 free(label); 2210 2211 temperature = picldiag_get_int_propval(temph, PICL_PROP_TEMPERATURE, 2212 &err); 2213 if (err == PICL_SUCCESS) { 2214 got_temp = 1; 2215 status = "okay"; 2216 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2217 return (err); 2218 } 2219 2220 threshold = picldiag_get_int_propval(temph, PICL_PROP_LOW_WARNING, 2221 &err); 2222 if (err == PICL_SUCCESS) { 2223 if (got_temp && temperature < threshold) 2224 status = "warning"; 2225 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2226 return (err); 2227 } 2228 2229 threshold = picldiag_get_int_propval(temph, PICL_PROP_LOW_SHUTDOWN, 2230 &err); 2231 if (err == PICL_SUCCESS) { 2232 if (got_temp && temperature < threshold) 2233 status = "failed"; 2234 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2235 return (err); 2236 } 2237 2238 threshold = picldiag_get_int_propval(temph, PICL_PROP_HIGH_WARNING, 2239 &err); 2240 if (err == PICL_SUCCESS) { 2241 if (got_temp && temperature > threshold) 2242 status = "warning"; 2243 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2244 return (err); 2245 } 2246 2247 threshold = picldiag_get_int_propval(temph, PICL_PROP_HIGH_SHUTDOWN, 2248 &err); 2249 if (err == PICL_SUCCESS) { 2250 if (got_temp && temperature > threshold) 2251 status = "failed"; 2252 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2253 return (err); 2254 } 2255 2256 err = picldiag_get_string_propval(temph, PICL_PROP_CONDITION, &status); 2257 if (err == PICL_SUCCESS) { 2258 log_printf("%s", status); 2259 free(status); 2260 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2261 return (err); 2262 } else { 2263 log_printf("%s ", status); 2264 if (strcmp(status, "failed") == 0 || 2265 strcmp(status, "warning") == 0) 2266 log_printf("(%.2lldC)", temperature); 2267 } 2268 2269 log_printf("\n"); 2270 return (PICL_SUCCESS); 2271 } 2272 2273 static int 2274 temp_callback(picl_nodehdl_t temph, void *arg) 2275 { 2276 int err; 2277 int *countp = arg; 2278 2279 if (*countp == 0) { 2280 log_printf("\n"); 2281 log_printf("---------------------------------------\n"); 2282 log_printf(dgettext(TEXT_DOMAIN, "Temperature sensors:\n")); 2283 log_printf("------------------------------------\n"); 2284 log_printf(dgettext(TEXT_DOMAIN, 2285 "Location Sensor Status\n")); 2286 log_printf("------------------------------------\n"); 2287 } 2288 *countp += 1; 2289 err = logprintf_temp_info(temph); 2290 if (err == PICL_SUCCESS) 2291 return (PICL_WALK_CONTINUE); 2292 return (err); 2293 } 2294 2295 /* 2296 * callback function search children to find temp sensors and print the temp 2297 */ 2298 /* ARGSUSED */ 2299 static int 2300 display_temp(picl_nodehdl_t plafh) 2301 { 2302 int err; 2303 int print_header; 2304 2305 print_header = 0; 2306 err = picl_walk_tree_by_class(plafh, PICL_CLASS_TEMPERATURE_SENSOR, 2307 &print_header, temp_callback); 2308 if (err != PICL_SUCCESS) 2309 return (err); 2310 err = picl_walk_tree_by_class(plafh, PICL_CLASS_TEMPERATURE_INDICATOR, 2311 &print_header, temp_callback); 2312 return (err); 2313 } 2314 2315 /* 2316 * print current sensor information 2317 */ 2318 static int 2319 logprintf_current_info(picl_nodehdl_t currenth) 2320 { 2321 int err; 2322 char *label; 2323 float current; 2324 float threshold; 2325 picl_nodehdl_t fruph; 2326 char *status = "unknown"; 2327 int got_current = 0; 2328 2329 err = picldiag_get_fru_parent(currenth, &fruph); 2330 if (err != PICL_SUCCESS) 2331 return (err); 2332 2333 err = picldiag_get_combined_label(fruph, &label, 10); 2334 if (err != PICL_SUCCESS) 2335 return (err); 2336 2337 log_printf("%-10s ", label); 2338 free(label); 2339 2340 err = picldiag_get_label(currenth, &label); 2341 if (err != PICL_SUCCESS) 2342 return (err); 2343 log_printf("%-10s ", label); 2344 free(label); 2345 2346 current = picldiag_get_float_propval(currenth, PICL_PROP_CURRENT, &err); 2347 if (err == PICL_SUCCESS) { 2348 status = "okay"; 2349 got_current = 1; 2350 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2351 return (err); 2352 } 2353 2354 threshold = picldiag_get_float_propval(currenth, PICL_PROP_LOW_WARNING, 2355 &err); 2356 if (err == PICL_SUCCESS) { 2357 if (got_current && current < threshold) 2358 status = "warning"; 2359 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2360 return (err); 2361 } 2362 2363 threshold = picldiag_get_float_propval(currenth, PICL_PROP_LOW_SHUTDOWN, 2364 &err); 2365 if (err == PICL_SUCCESS) { 2366 if (got_current && current < threshold) 2367 status = "failed"; 2368 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2369 return (err); 2370 } 2371 2372 threshold = picldiag_get_float_propval(currenth, PICL_PROP_HIGH_WARNING, 2373 &err); 2374 if (err == PICL_SUCCESS) { 2375 if (got_current && current > threshold) 2376 status = "warning"; 2377 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2378 return (err); 2379 } 2380 2381 threshold = picldiag_get_float_propval(currenth, 2382 PICL_PROP_HIGH_SHUTDOWN, &err); 2383 if (err == PICL_SUCCESS) { 2384 if (got_current && current > threshold) 2385 status = "failed"; 2386 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2387 return (err); 2388 } 2389 2390 err = picldiag_get_string_propval(currenth, 2391 PICL_PROP_CONDITION, &status); 2392 if (err == PICL_SUCCESS) { 2393 log_printf(" %s", status); 2394 free(status); 2395 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2396 return (err); 2397 } else { 2398 log_printf("%s ", status); 2399 if (strcmp(status, "failed") == 0 || 2400 strcmp(status, "warning") == 0) 2401 log_printf("(%.2fA)", current); 2402 } 2403 2404 log_printf("\n"); 2405 return (PICL_SUCCESS); 2406 } 2407 2408 static int 2409 current_callback(picl_nodehdl_t currh, void *arg) 2410 { 2411 int err; 2412 int *countp = arg; 2413 2414 if (*countp == 0) { 2415 log_printf("------------------------------------\n"); 2416 log_printf(dgettext(TEXT_DOMAIN, "Current sensors:\n")); 2417 log_printf("------------------------------\n"); 2418 log_printf(dgettext(TEXT_DOMAIN, 2419 "Location Sensor Status\n")); 2420 log_printf("------------------------------\n"); 2421 } 2422 *countp += 1; 2423 err = logprintf_current_info(currh); 2424 if (err == PICL_SUCCESS) 2425 return (PICL_WALK_CONTINUE); 2426 return (err); 2427 } 2428 2429 /* 2430 * callback function search children to find curr sensors and print the curr 2431 */ 2432 /* ARGSUSED */ 2433 static int 2434 display_current(picl_nodehdl_t plafh) 2435 { 2436 int err; 2437 int print_header; 2438 2439 print_header = 0; 2440 err = picl_walk_tree_by_class(plafh, PICL_CLASS_CURRENT_SENSOR, 2441 &print_header, current_callback); 2442 if (err != PICL_SUCCESS) 2443 return (err); 2444 err = picl_walk_tree_by_class(plafh, PICL_CLASS_CURRENT_INDICATOR, 2445 &print_header, current_callback); 2446 return (err); 2447 } 2448 2449 /* 2450 * print voltage sensor information 2451 */ 2452 static int 2453 logprintf_voltage_info(picl_nodehdl_t voltageh) 2454 { 2455 int err; 2456 char *label; 2457 float voltage; 2458 float threshold; 2459 picl_nodehdl_t fruph; 2460 char *status = "unknown"; 2461 int got_voltage = 0; 2462 2463 err = picldiag_get_fru_parent(voltageh, &fruph); 2464 if (err != PICL_SUCCESS) 2465 return (err); 2466 2467 err = picldiag_get_combined_label(fruph, &label, 10); 2468 if (err != PICL_SUCCESS) 2469 return (err); 2470 2471 log_printf("%-10s ", label); 2472 free(label); 2473 2474 err = picldiag_get_label(voltageh, &label); 2475 if (err != PICL_SUCCESS) 2476 return (err); 2477 log_printf("%-12s ", label); 2478 free(label); 2479 2480 voltage = picldiag_get_float_propval(voltageh, PICL_PROP_VOLTAGE, &err); 2481 if (err == PICL_SUCCESS) { 2482 status = "okay"; 2483 got_voltage = 1; 2484 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2485 return (err); 2486 } 2487 2488 threshold = picldiag_get_float_propval(voltageh, PICL_PROP_LOW_WARNING, 2489 &err); 2490 if (err == PICL_SUCCESS) { 2491 if (got_voltage && voltage < threshold) 2492 status = "warning"; 2493 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2494 return (err); 2495 } 2496 2497 threshold = picldiag_get_float_propval(voltageh, PICL_PROP_LOW_SHUTDOWN, 2498 &err); 2499 if (err == PICL_SUCCESS) { 2500 if (got_voltage && voltage < threshold) 2501 status = "failed"; 2502 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2503 return (err); 2504 } 2505 2506 threshold = picldiag_get_float_propval(voltageh, PICL_PROP_HIGH_WARNING, 2507 &err); 2508 if (err == PICL_SUCCESS) { 2509 if (got_voltage && voltage > threshold) 2510 status = "warning"; 2511 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2512 return (err); 2513 } 2514 2515 threshold = picldiag_get_float_propval(voltageh, 2516 PICL_PROP_HIGH_SHUTDOWN, &err); 2517 if (err == PICL_SUCCESS) { 2518 if (got_voltage && voltage > threshold) 2519 status = "failed"; 2520 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2521 return (err); 2522 } 2523 2524 err = picldiag_get_string_propval(voltageh, 2525 PICL_PROP_CONDITION, &status); 2526 if (err == PICL_SUCCESS) { 2527 log_printf("%s", status); 2528 free(status); 2529 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2530 return (err); 2531 } else { 2532 log_printf("%s ", status); 2533 if (strcmp(status, "warning") == 0 || 2534 strcmp(status, "failed") == 0) 2535 log_printf("(%.2fV)", voltage); 2536 } 2537 2538 log_printf("\n"); 2539 return (PICL_SUCCESS); 2540 } 2541 2542 static int 2543 voltage_callback(picl_nodehdl_t voltageh, void *arg) 2544 { 2545 int *countp = arg; 2546 int err; 2547 2548 if (*countp == 0) { 2549 log_printf("--------------------------------\n"); 2550 log_printf(dgettext(TEXT_DOMAIN, "Voltage sensors:\n")); 2551 log_printf("-------------------------------\n"); 2552 log_printf(dgettext(TEXT_DOMAIN, 2553 "Location Sensor Status\n")); 2554 log_printf("-------------------------------\n"); 2555 } 2556 *countp += 1; 2557 err = logprintf_voltage_info(voltageh); 2558 if (err == PICL_SUCCESS) 2559 return (PICL_WALK_CONTINUE); 2560 return (err); 2561 } 2562 2563 /* 2564 * callback function search children to find voltage sensors and print voltage 2565 */ 2566 /* ARGSUSED */ 2567 static int 2568 display_voltage(picl_nodehdl_t plafh) 2569 { 2570 int err; 2571 int print_header; 2572 2573 print_header = 0; 2574 err = picl_walk_tree_by_class(plafh, PICL_CLASS_VOLTAGE_SENSOR, 2575 &print_header, voltage_callback); 2576 if (err != PICL_SUCCESS) 2577 return (err); 2578 err = picl_walk_tree_by_class(plafh, PICL_CLASS_VOLTAGE_INDICATOR, 2579 &print_header, voltage_callback); 2580 return (err); 2581 } 2582 2583 /* 2584 * print led device information 2585 */ 2586 static int 2587 logprintf_led_info(picl_nodehdl_t ledh) 2588 { 2589 int err; 2590 char *label; 2591 char *state; 2592 char *color; 2593 picl_nodehdl_t fruph; 2594 2595 err = picldiag_get_fru_parent(ledh, &fruph); 2596 if (err != PICL_SUCCESS) 2597 return (err); 2598 2599 err = picldiag_get_combined_label(fruph, &label, 10); 2600 if (err != PICL_SUCCESS) { 2601 log_printf(" - ", label); 2602 } else { 2603 log_printf("%-10s ", label); 2604 free(label); 2605 } 2606 2607 err = picldiag_get_label(ledh, &label); 2608 if (err != PICL_SUCCESS) 2609 return (err); 2610 log_printf("%-20s ", label); 2611 free(label); 2612 2613 err = picldiag_get_string_propval(ledh, PICL_PROP_STATE, &state); 2614 if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) { 2615 log_printf(" - "); 2616 } else if (err != PICL_SUCCESS) { 2617 return (err); 2618 } else { 2619 log_printf("%-10s ", state); 2620 free(state); 2621 } 2622 2623 err = picldiag_get_string_propval(ledh, PICL_PROP_COLOR, &color); 2624 if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) { 2625 log_printf("\n"); 2626 } else if (err != PICL_SUCCESS) { 2627 return (err); 2628 } else { 2629 log_printf("%-16s\n", color); 2630 free(color); 2631 } 2632 2633 return (PICL_SUCCESS); 2634 } 2635 2636 static int 2637 led_callback(picl_nodehdl_t ledh, void *arg) 2638 { 2639 int *countp = arg; 2640 int err; 2641 2642 if (*countp == 0) { 2643 2644 log_printf("--------------------------------------" 2645 "------------\n"); 2646 log_printf(dgettext(TEXT_DOMAIN, "Led State:\n")); 2647 log_printf("--------------------------------------" 2648 "------------\n"); 2649 log_printf(dgettext(TEXT_DOMAIN, 2650 "Location Led State" 2651 " Color\n")); 2652 log_printf("--------------------------------------" 2653 "------------\n"); 2654 } 2655 *countp += 1; 2656 err = logprintf_led_info(ledh); 2657 if (err == PICL_SUCCESS) 2658 return (PICL_WALK_CONTINUE); 2659 return (err); 2660 } 2661 2662 /* 2663 * callback function search children to find led devices and print status 2664 */ 2665 /* ARGSUSED */ 2666 static int 2667 display_led_status(picl_nodehdl_t plafh) 2668 { 2669 int print_header; 2670 2671 print_header = 0; 2672 picl_walk_tree_by_class(plafh, PICL_CLASS_LED, 2673 &print_header, led_callback); 2674 return (PICL_SUCCESS); 2675 } 2676 2677 /* 2678 * print keyswitch device information 2679 */ 2680 static int 2681 logprintf_keyswitch_info(picl_nodehdl_t keyswitchh, picl_nodehdl_t fruph) 2682 { 2683 int err; 2684 char *label; 2685 char *state; 2686 2687 err = picldiag_get_combined_label(fruph, &label, 10); 2688 if (err != PICL_SUCCESS) { 2689 log_printf("%-14s", " -"); 2690 } else { 2691 log_printf("%-14s ", label); 2692 free(label); 2693 } 2694 2695 err = picldiag_get_label(keyswitchh, &label); 2696 if (err != PICL_SUCCESS) 2697 return (err); 2698 log_printf("%-11s ", label); 2699 free(label); 2700 2701 err = picldiag_get_string_propval(keyswitchh, PICL_PROP_STATE, &state); 2702 if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) { 2703 log_printf(" -\n"); 2704 } else if (err != PICL_SUCCESS) { 2705 return (err); 2706 } else { 2707 log_printf("%s\n", state); 2708 free(state); 2709 } 2710 2711 return (PICL_SUCCESS); 2712 } 2713 2714 static int 2715 keyswitch_callback(picl_nodehdl_t keyswitchh, void *arg) 2716 { 2717 int *countp = arg; 2718 int err; 2719 picl_nodehdl_t fruph; 2720 2721 /* 2722 * Tamale simulates a key-switch on ENxS. So the presence of a 2723 * node of class keyswitch is not sufficient. If it has a fru parent 2724 * or location parent, then believe it. 2725 */ 2726 err = picl_get_propval_by_name(keyswitchh, PICL_REFPROP_FRU_PARENT, 2727 &fruph, sizeof (fruph)); 2728 if (err == PICL_PROPNOTFOUND) { 2729 err = picl_get_propval_by_name(keyswitchh, 2730 PICL_REFPROP_LOC_PARENT, &fruph, sizeof (fruph)); 2731 } 2732 if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) 2733 return (PICL_WALK_CONTINUE); 2734 if (err != PICL_SUCCESS) 2735 return (err); 2736 2737 if (*countp == 0) { 2738 log_printf("-----------------------------------------\n"); 2739 log_printf(dgettext(TEXT_DOMAIN, "Keyswitch:\n")); 2740 log_printf("-----------------------------------------\n"); 2741 log_printf(dgettext(TEXT_DOMAIN, 2742 "Location Keyswitch State\n")); 2743 log_printf("-----------------------------------------\n"); 2744 } 2745 *countp += 1; 2746 err = logprintf_keyswitch_info(keyswitchh, fruph); 2747 if (err == PICL_SUCCESS) 2748 return (PICL_WALK_CONTINUE); 2749 return (err); 2750 } 2751 2752 /* 2753 * search children to find keyswitch device(s) and print status 2754 */ 2755 /* ARGSUSED */ 2756 static int 2757 display_keyswitch(picl_nodehdl_t plafh) 2758 { 2759 int print_header = 0; 2760 2761 picl_walk_tree_by_class(plafh, PICL_CLASS_KEYSWITCH, 2762 &print_header, keyswitch_callback); 2763 return (PICL_SUCCESS); 2764 } 2765 2766 /* 2767 * display environment status 2768 */ 2769 static int 2770 display_envctrl_status(picl_nodehdl_t plafh) 2771 { 2772 logprintf_header(dgettext(TEXT_DOMAIN, "Environmental Status"), 2773 DEFAULT_LINE_WIDTH); 2774 2775 display_fan_speed(plafh); 2776 display_temp(plafh); 2777 display_current(plafh); 2778 display_voltage(plafh); 2779 display_keyswitch(plafh); 2780 display_led_status(plafh); 2781 2782 return (PICL_SUCCESS); 2783 } 2784 2785 /* 2786 * print fru operational status 2787 */ 2788 static int 2789 logprintf_fru_oper_status(picl_nodehdl_t fruh, int *countp) 2790 { 2791 int err; 2792 char *label; 2793 char *status; 2794 2795 err = picldiag_get_combined_label(fruh, &label, 15); 2796 if (err != PICL_SUCCESS) 2797 return (PICL_WALK_CONTINUE); 2798 2799 err = picldiag_get_string_propval(fruh, 2800 PICL_PROP_OPERATIONAL_STATUS, &status); 2801 if (err == PICL_SUCCESS) { 2802 if (*countp == 0) { 2803 logprintf_header(dgettext(TEXT_DOMAIN, 2804 "FRU Operational Status"), 2805 DEFAULT_LINE_WIDTH); 2806 log_printf("-------------------------\n"); 2807 log_printf(dgettext(TEXT_DOMAIN, 2808 "Fru Operational Status:\n")); 2809 log_printf("-------------------------\n"); 2810 log_printf(dgettext(TEXT_DOMAIN, 2811 "Location Status \n")); 2812 log_printf("-------------------------\n"); 2813 } 2814 *countp += 1; 2815 log_printf("%-15s ", label); 2816 free(label); 2817 log_printf("%s\n", status); 2818 free(status); 2819 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) { 2820 free(label); 2821 return (err); 2822 } else { 2823 free(label); 2824 } 2825 return (PICL_WALK_CONTINUE); 2826 } 2827 2828 static int 2829 fru_oper_status_callback(picl_nodehdl_t fruh, void *arg) 2830 { 2831 int err; 2832 2833 err = logprintf_fru_oper_status(fruh, (int *)arg); 2834 return (err); 2835 } 2836 2837 /* 2838 * display fru operational status 2839 */ 2840 static int 2841 display_fru_oper_status(picl_nodehdl_t frutreeh) 2842 { 2843 int print_header; 2844 2845 print_header = 0; 2846 picl_walk_tree_by_class(frutreeh, PICL_CLASS_FRU, 2847 &print_header, fru_oper_status_callback); 2848 return (PICL_SUCCESS); 2849 } 2850 2851 /* 2852 * check if the node having the version prop 2853 * If yes, print its nodename and version 2854 */ 2855 /* ARGSUSED */ 2856 static int 2857 asicrev_callback(picl_nodehdl_t nodeh, void *arg) 2858 { 2859 uint32_t version; 2860 char *name; 2861 char *model; 2862 char *status; 2863 int err; 2864 2865 version = picldiag_get_uint_propval(nodeh, OBP_PROP_VERSION_NUM, 2866 &err); 2867 if (err == PICL_PROPNOTFOUND) 2868 return (PICL_WALK_CONTINUE); 2869 else if (err != PICL_SUCCESS) 2870 return (err); 2871 2872 /* devfs-path */ 2873 err = picldiag_get_string_propval(nodeh, PICL_PROP_DEVFS_PATH, &name); 2874 if (err == PICL_PROPNOTFOUND) 2875 name = NULL; 2876 else if (err != PICL_SUCCESS) 2877 return (err); 2878 2879 /* model */ 2880 err = picldiag_get_string_propval(nodeh, PICL_PROP_BINDING_NAME, 2881 &model); 2882 if (err == PICL_PROPNOTFOUND) 2883 model = NULL; 2884 else if (err != PICL_SUCCESS) 2885 return (err); 2886 2887 /* status */ 2888 err = picldiag_get_string_propval(nodeh, PICL_PROP_STATUS, &status); 2889 if (err == PICL_PROPNOTFOUND) 2890 status = NULL; 2891 else if (err != PICL_SUCCESS) 2892 return (err); 2893 2894 /* 2895 * Display the data 2896 */ 2897 2898 /* name */ 2899 if (name != NULL) { 2900 log_printf("%-22s ", name); 2901 free(name); 2902 } else 2903 log_printf("%-22s ", "unknown"); 2904 /* model */ 2905 if (model != NULL) { 2906 log_printf("%-15s ", model); 2907 free(model); 2908 } else 2909 log_printf("%-15s ", "unknown"); 2910 /* status */ 2911 if (status == NULL) 2912 log_printf("%-15s ", "okay"); 2913 else { 2914 log_printf("%-15s ", status); 2915 free(status); 2916 } 2917 /* revision */ 2918 log_printf(" %-4d\n", version); 2919 2920 return (PICL_WALK_CONTINUE); 2921 } 2922 2923 /* 2924 * traverse the tree to display asic revision id for ebus 2925 */ 2926 /* ARGSUSED */ 2927 static int 2928 ebus_callback(picl_nodehdl_t ebush, void *arg) 2929 { 2930 uint32_t id; 2931 char *name; 2932 int err; 2933 char *model; 2934 char *status; 2935 2936 id = picldiag_get_uint_propval(ebush, OBP_PROP_REVISION_ID, &err); 2937 if (err == PICL_PROPNOTFOUND) 2938 return (PICL_WALK_CONTINUE); 2939 else if (err != PICL_SUCCESS) 2940 return (err); 2941 2942 /* devfs-path */ 2943 err = picldiag_get_string_propval(ebush, PICL_PROP_DEVFS_PATH, &name); 2944 if (err == PICL_PROPNOTFOUND) 2945 name = NULL; 2946 else if (err != PICL_SUCCESS) 2947 return (err); 2948 2949 /* model */ 2950 err = picldiag_get_string_propval(ebush, PICL_PROP_BINDING_NAME, 2951 &model); 2952 if (err == PICL_PROPNOTFOUND) 2953 model = NULL; 2954 else if (err != PICL_SUCCESS) 2955 return (err); 2956 2957 /* status */ 2958 err = picldiag_get_string_propval(ebush, PICL_PROP_STATUS, &status); 2959 if (err == PICL_PROPNOTFOUND) 2960 status = NULL; 2961 else if (err != PICL_SUCCESS) 2962 return (err); 2963 2964 /* 2965 * Display the data 2966 */ 2967 2968 /* name */ 2969 if (name != NULL) { 2970 log_printf("%-22s ", name); 2971 free(name); 2972 } else 2973 log_printf("%-22s ", "unknown"); 2974 /* model */ 2975 if (model != NULL) { 2976 log_printf("%-15s ", model); 2977 free(model); 2978 } else 2979 log_printf("%-15s ", "unknown"); 2980 /* status */ 2981 if (status == NULL) 2982 log_printf("%-15s ", "okay"); 2983 else { 2984 log_printf("%-15s ", status); 2985 free(status); 2986 } 2987 /* revision */ 2988 log_printf(" %-4d\n", id); 2989 2990 return (PICL_WALK_CONTINUE); 2991 } 2992 2993 /* 2994 * display asic revision id 2995 */ 2996 static int 2997 display_hw_revisions(picl_nodehdl_t plafh) 2998 { 2999 int err; 3000 3001 /* Print the header */ 3002 logprintf_header(dgettext(TEXT_DOMAIN, "HW Revisions"), 3003 DEFAULT_LINE_WIDTH); 3004 3005 log_printf(dgettext(TEXT_DOMAIN, "ASIC Revisions:\n")); 3006 log_printf("-----------------------------"); 3007 log_printf("--------------------------------------\n"); 3008 log_printf(dgettext(TEXT_DOMAIN, "Path Device")); 3009 log_printf(dgettext(TEXT_DOMAIN, 3010 " Status Revision\n")); 3011 log_printf("-----------------------------"); 3012 log_printf("--------------------------------------\n"); 3013 3014 err = picl_walk_tree_by_class(plafh, NULL, NULL, asicrev_callback); 3015 if (err != PICL_SUCCESS) 3016 return (err); 3017 3018 err = picl_walk_tree_by_class(plafh, PICL_CLASS_EBUS, 3019 NULL, ebus_callback); 3020 if (err != PICL_SUCCESS) 3021 return (err); 3022 3023 log_printf("\n"); 3024 3025 return (err); 3026 } 3027 3028 /* 3029 * find the options node and its powerfail_time prop 3030 * If found, display the list of latest powerfail. 3031 */ 3032 /* ARGSUSED */ 3033 static int 3034 options_callback(picl_nodehdl_t nodeh, void *arg) 3035 { 3036 time_t value; 3037 char *failtime; 3038 int err; 3039 3040 err = picldiag_get_string_propval(nodeh, PROP_POWERFAIL_TIME, 3041 &failtime); 3042 if (err == PICL_PROPNOTFOUND) 3043 return (PICL_WALK_TERMINATE); 3044 else if (err != PICL_SUCCESS) 3045 return (err); 3046 3047 value = (time_t)atoi(failtime); 3048 free(failtime); 3049 if (value == 0) 3050 return (PICL_WALK_TERMINATE); 3051 3052 log_printf(dgettext(TEXT_DOMAIN, "Most recent AC Power Failure:\n")); 3053 log_printf("=============================\n"); 3054 log_printf("%s", ctime(&value)); 3055 log_printf("\n"); 3056 return (PICL_WALK_TERMINATE); 3057 } 3058 3059 /* 3060 * display the OBP and POST prom revisions 3061 */ 3062 /* ARGSUSED */ 3063 static int 3064 flashprom_callback(picl_nodehdl_t flashpromh, void *arg) 3065 { 3066 picl_prophdl_t proph; 3067 picl_prophdl_t tblh; 3068 picl_prophdl_t rowproph; 3069 picl_propinfo_t pinfo; 3070 char *prom_version = NULL; 3071 char *obp_version = NULL; 3072 int err; 3073 3074 err = picl_get_propinfo_by_name(flashpromh, OBP_PROP_VERSION, 3075 &pinfo, &proph); 3076 if (err == PICL_PROPNOTFOUND) 3077 return (PICL_WALK_TERMINATE); 3078 else if (err != PICL_SUCCESS) 3079 return (err); 3080 3081 log_printf(dgettext(TEXT_DOMAIN, "System PROM revisions:\n")); 3082 log_printf("----------------------\n"); 3083 3084 /* 3085 * If it's a table prop, the first element is OBP revision 3086 * The second one is POST revision. 3087 * If it's a charstring prop, the value will be only OBP revision 3088 */ 3089 if (pinfo.type == PICL_PTYPE_CHARSTRING) { 3090 prom_version = alloca(pinfo.size); 3091 if (prom_version == NULL) 3092 return (PICL_FAILURE); 3093 err = picl_get_propval(proph, prom_version, pinfo.size); 3094 if (err != PICL_SUCCESS) 3095 return (err); 3096 log_printf("%s\n", prom_version); 3097 } 3098 3099 if (pinfo.type != PICL_PTYPE_TABLE) /* not supported type */ 3100 return (PICL_WALK_TERMINATE); 3101 3102 err = picl_get_propval(proph, &tblh, pinfo.size); 3103 if (err != PICL_SUCCESS) 3104 return (err); 3105 3106 err = picl_get_next_by_row(tblh, &rowproph); 3107 if (err == PICL_SUCCESS) { 3108 /* get first row */ 3109 err = picl_get_propinfo(rowproph, &pinfo); 3110 if (err != PICL_SUCCESS) 3111 return (err); 3112 3113 prom_version = alloca(pinfo.size); 3114 if (prom_version == NULL) 3115 return (PICL_FAILURE); 3116 3117 err = picl_get_propval(rowproph, prom_version, pinfo.size); 3118 if (err != PICL_SUCCESS) 3119 return (err); 3120 log_printf("%s\n", prom_version); 3121 3122 /* get second row */ 3123 err = picl_get_next_by_col(rowproph, &rowproph); 3124 if (err == PICL_SUCCESS) { 3125 err = picl_get_propinfo(rowproph, &pinfo); 3126 if (err != PICL_SUCCESS) 3127 return (err); 3128 3129 obp_version = alloca(pinfo.size); 3130 if (obp_version == NULL) 3131 return (PICL_FAILURE); 3132 err = picl_get_propval(rowproph, obp_version, 3133 pinfo.size); 3134 if (err != PICL_SUCCESS) 3135 return (err); 3136 log_printf("%s\n", obp_version); 3137 } 3138 } 3139 3140 return (PICL_WALK_TERMINATE); 3141 } 3142 3143 static int 3144 display_system_info(int serrlog, int log_flag, picl_nodehdl_t rooth) 3145 { 3146 int err; 3147 picl_nodehdl_t plafh; 3148 picl_nodehdl_t frutreeh; 3149 3150 err = picldiag_get_node_by_name(rooth, PICL_NODE_PLATFORM, &plafh); 3151 if (err != PICL_SUCCESS) 3152 return (err); 3153 3154 if (!log_flag) { 3155 err = display_platform_banner(plafh); 3156 if (err != PICL_SUCCESS) 3157 return (err); 3158 3159 err = display_system_clock(plafh); 3160 if (err != PICL_SUCCESS) 3161 return (err); 3162 3163 err = picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY, 3164 PICL_CLASS_MEMORY, memory_callback); 3165 if (err != PICL_SUCCESS) 3166 return (err); 3167 3168 err = display_cpu_info(plafh); 3169 if (err != PICL_SUCCESS) 3170 return (err); 3171 3172 err = display_io_device_info(plafh); 3173 if (err != PICL_SUCCESS) 3174 return (err); 3175 3176 err = display_memory_config(plafh); 3177 if (err != PICL_SUCCESS) 3178 return (err); 3179 3180 err = display_usb_devices(plafh); 3181 if (err != PICL_SUCCESS) 3182 return (err); 3183 } 3184 3185 if (serrlog) { 3186 err = picl_walk_tree_by_class(rooth, PICL_CLASS_OPTIONS, 3187 NULL, options_callback); 3188 if (err != PICL_SUCCESS) 3189 return (err); 3190 3191 err = picldiag_get_node_by_name(rooth, PICL_NODE_FRUTREE, 3192 &frutreeh); 3193 3194 /* return ok if no frutree in picl on schumacher */ 3195 if (err != PICL_SUCCESS) 3196 return (PICL_SUCCESS); 3197 3198 err = display_fru_oper_status(frutreeh); 3199 if (err != PICL_SUCCESS) 3200 return (err); 3201 3202 err = display_hw_revisions(plafh); 3203 if (err != PICL_SUCCESS) 3204 return (err); 3205 3206 err = picl_walk_tree_by_class(plafh, PICL_CLASS_FLASHPROM, 3207 NULL, flashprom_callback); 3208 if (err != PICL_SUCCESS) 3209 return (err); 3210 } 3211 3212 return (PICL_SUCCESS); 3213 } 3214 3215 /* ARGSUSED */ 3216 int 3217 do_prominfo(int serrlog, char *pgname, int log_flag, int prt_flag) 3218 { 3219 int err; 3220 char *errstr; 3221 int done; 3222 picl_nodehdl_t rooth; 3223 3224 err = picl_initialize(); 3225 if (err != PICL_SUCCESS) { 3226 fprintf(stderr, EM_INIT_FAIL, picl_strerror(err)); 3227 exit(1); 3228 } 3229 3230 do { 3231 done = 1; 3232 err = picl_get_root(&rooth); 3233 if (err != PICL_SUCCESS) { 3234 fprintf(stderr, EM_GET_ROOT_FAIL, picl_strerror(err)); 3235 exit(1); 3236 } 3237 3238 err = display_system_info(serrlog, log_flag, rooth); 3239 3240 if ((err == PICL_STALEHANDLE) || (err == PICL_INVALIDHANDLE)) 3241 done = 0; 3242 } while (!done); 3243 3244 if (err != PICL_SUCCESS) { 3245 errstr = picl_strerror(err); 3246 fprintf(stderr, EM_PRTDIAG_FAIL); 3247 fprintf(stderr, "%s\n", errstr? errstr : " "); 3248 } 3249 3250 (void) picl_shutdown(); 3251 3252 return (0); 3253 } 3254