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