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 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <unistd.h> 31 #include <ctype.h> 32 #include <string.h> 33 #include <kvm.h> 34 #include <varargs.h> 35 #include <time.h> 36 #include <dirent.h> 37 #include <fcntl.h> 38 #include <sys/param.h> 39 #include <sys/stat.h> 40 #include <sys/types.h> 41 #include <sys/utsname.h> 42 #include <sys/openpromio.h> 43 #include <libintl.h> 44 #include <syslog.h> 45 #include <sys/dkio.h> 46 #include <sys/systeminfo.h> 47 #include <picldefs.h> 48 #include "pdevinfo.h" 49 #include "display.h" 50 #include "display_sun4v.h" 51 #include "libprtdiag.h" 52 53 #if !defined(TEXT_DOMAIN) 54 #define TEXT_DOMAIN "SYS_TEST" 55 #endif 56 57 #define MOTHERBOARD "MB" 58 #define NETWORK "network" 59 #define PCIE_COMPATIBLE_STR "pciex" 60 #define PCIX_COMPATIBLE_STR "pci" 61 #define SUN4V_MACHINE "sun4v" 62 #define PARENT_NAMES 10 63 64 /* 65 * Additional OBP properties 66 */ 67 #define OBP_PROP_COMPATIBLE "compatible" 68 #define OBP_PROP_MODEL "model" 69 #define OBP_PROP_SLOT_NAMES "slot-names" 70 71 #define PICL_NODE_PHYSICAL_PLATFORM "physical-platform" 72 #define PICL_NODE_CHASSIS "chassis" 73 #define MEMORY_SIZE_FIELD 11 74 #define INVALID_THRESHOLD 1000000 75 76 /* 77 * Additional picl classes 78 */ 79 #ifndef PICL_CLASS_SUN4V 80 #define PICL_CLASS_SUN4V "sun4v" 81 #endif 82 83 #ifndef PICL_PROP_NAC 84 #define PICL_PROP_NAC "nac" 85 #endif 86 87 extern int sys_clk; 88 extern picl_errno_t sun4v_get_node_by_name(picl_nodehdl_t, char *, 89 picl_nodehdl_t *); 90 91 static picl_nodehdl_t rooth = 0, phyplatformh = 0; 92 static picl_nodehdl_t chassish = 0; 93 static int class_node_found; 94 static int syserrlog; 95 static int all_status_ok; 96 97 /* local functions */ 98 static int sun4v_get_first_compatible_value(picl_nodehdl_t, char **); 99 static void sun4v_display_memory_conf(picl_nodehdl_t); 100 static void sun4v_disp_env_status(); 101 static void sun4v_env_print_fan_sensors(); 102 static void sun4v_env_print_fan_indicators(); 103 static void sun4v_env_print_temp_sensors(); 104 static void sun4v_env_print_temp_indicators(); 105 static void sun4v_env_print_current_sensors(); 106 static void sun4v_env_print_current_indicators(); 107 static void sun4v_env_print_voltage_sensors(); 108 static void sun4v_env_print_voltage_indicators(); 109 static void sun4v_env_print_LEDs(); 110 static void sun4v_print_fru_status(); 111 static void sun4v_print_fw_rev(); 112 static void sun4v_print_chassis_serial_no(); 113 114 int 115 sun4v_display(Sys_tree *tree, Prom_node *root, int log, 116 picl_nodehdl_t plafh) 117 { 118 void *value; /* used for opaque PROM data */ 119 struct mem_total memory_total; /* Total memory in system */ 120 struct grp_info grps; /* Info on all groups in system */ 121 char machine[MAXSTRLEN]; 122 123 if (sysinfo(SI_MACHINE, machine, sizeof (machine)) == -1) 124 return (1); 125 if (strncmp(machine, SUN4V_MACHINE, strlen(SUN4V_MACHINE)) != 0) 126 return (1); 127 128 sys_clk = -1; /* System clock freq. (in MHz) */ 129 130 /* 131 * Now display the machine's configuration. We do this if we 132 * are not logging. 133 */ 134 if (!logging) { 135 struct utsname uts_buf; 136 137 /* 138 * Display system banner 139 */ 140 (void) uname(&uts_buf); 141 142 log_printf(dgettext(TEXT_DOMAIN, "System Configuration: " 143 "Sun Microsystems %s %s\n"), uts_buf.machine, 144 get_prop_val(find_prop(root, "banner-name")), 0); 145 146 /* display system clock frequency */ 147 value = get_prop_val(find_prop(root, "clock-frequency")); 148 if (value != NULL) { 149 sys_clk = ((*((int *)value)) + 500000) / 1000000; 150 log_printf(dgettext(TEXT_DOMAIN, "System clock " 151 "frequency: %d MHz\n"), sys_clk, 0); 152 } 153 154 /* Display the Memory Size */ 155 display_memorysize(tree, NULL, &grps, &memory_total); 156 157 /* Display the CPU devices */ 158 sun4v_display_cpu_devices(plafh); 159 160 /* Display the Memory configuration */ 161 class_node_found = 0; 162 sun4v_display_memory_conf(plafh); 163 164 /* Display all the IO cards. */ 165 (void) sun4v_display_pci(plafh); 166 sun4v_display_diaginfo((log || (logging)), root, plafh); 167 168 if (picl_get_root(&rooth) != PICL_SUCCESS) 169 return (1); 170 if (sun4v_get_node_by_name(rooth, PICL_NODE_PHYSICAL_PLATFORM, 171 &phyplatformh) != PICL_SUCCESS) 172 return (1); 173 174 if (picl_find_node(phyplatformh, PICL_PROP_CLASSNAME, 175 PICL_PTYPE_CHARSTRING, (void *)PICL_CLASS_CHASSIS, 176 strlen(PICL_CLASS_CHASSIS), &chassish) != PICL_SUCCESS) 177 return (1); 178 179 syserrlog = log; 180 sun4v_disp_env_status(); 181 } 182 return (0); 183 } 184 185 static void 186 get_bus_type(picl_nodehdl_t nodeh, struct io_card *card) 187 { 188 char *compatible; 189 190 (void) strlcpy(card->bus_type, "PCIX", sizeof (card->bus_type)); 191 if (sun4v_get_first_compatible_value(nodeh, &compatible) 192 == PICL_SUCCESS) { 193 if (strncmp(compatible, PCIE_COMPATIBLE_STR, 194 strlen(PCIE_COMPATIBLE_STR)) == 0) 195 (void) strlcpy(card->bus_type, "PCIE", 196 sizeof (card->bus_type)); 197 free(compatible); 198 } 199 } 200 201 static picl_errno_t 202 get_slot_label(picl_nodehdl_t nodeh, struct io_card *card) 203 { 204 char val[PICL_PROPNAMELEN_MAX]; 205 picl_errno_t err; 206 207 err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, val, 208 sizeof (val)); 209 if (err != PICL_SUCCESS) 210 return (err); 211 212 (void) strlcpy(card->slot_str, val, sizeof (card->slot_str)); 213 card->slot = -1; 214 return (PICL_SUCCESS); 215 } 216 217 static void 218 get_slot_number(picl_nodehdl_t nodeh, struct io_card *card) 219 { 220 picl_errno_t err; 221 picl_prophdl_t proph; 222 picl_propinfo_t pinfo; 223 picl_nodehdl_t pnodeh; 224 uint8_t *pval; 225 uint32_t dev_mask; 226 char uaddr[MAXSTRLEN]; 227 int i; 228 229 if (get_slot_label(nodeh, card) == PICL_SUCCESS) 230 return; 231 err = PICL_SUCCESS; 232 while (err == PICL_SUCCESS) { 233 if (picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &pnodeh, 234 sizeof (pnodeh)) != PICL_SUCCESS) { 235 (void) strlcpy(card->slot_str, MOTHERBOARD, 236 sizeof (card->slot_str)); 237 card->slot = -1; 238 return; 239 } 240 if (picl_get_propinfo_by_name(pnodeh, OBP_PROP_SLOT_NAMES, 241 &pinfo, &proph) == PICL_SUCCESS) { 242 break; 243 } 244 nodeh = pnodeh; 245 } 246 if (picl_get_propval_by_name(nodeh, PICL_PROP_UNIT_ADDRESS, uaddr, 247 sizeof (uaddr)) != PICL_SUCCESS) { 248 (void) strlcpy(card->slot_str, MOTHERBOARD, 249 sizeof (card->slot_str)); 250 card->slot = -1; 251 return; 252 } 253 pval = (uint8_t *)malloc(pinfo.size); 254 if (!pval) { 255 (void) strlcpy(card->slot_str, MOTHERBOARD, 256 sizeof (card->slot_str)); 257 card->slot = -1; 258 return; 259 } 260 if (picl_get_propval(proph, pval, pinfo.size) != PICL_SUCCESS) { 261 (void) strlcpy(card->slot_str, MOTHERBOARD, 262 sizeof (card->slot_str)); 263 card->slot = -1; 264 free(pval); 265 return; 266 } 267 268 dev_mask = 0; 269 for (i = 0; i < sizeof (dev_mask); i++) 270 dev_mask |= (*(pval+i) << 8*(sizeof (dev_mask)-1-i)); 271 for (i = 0; i < sizeof (uaddr) && uaddr[i] != '\0'; i++) { 272 if (uaddr[i] == ',') { 273 uaddr[i] = '\0'; 274 break; 275 } 276 } 277 card->slot = atol(uaddr); 278 if (((1 << card->slot) & dev_mask) == 0) { 279 (void) strlcpy(card->slot_str, MOTHERBOARD, 280 sizeof (card->slot_str)); 281 card->slot = -1; 282 } else { 283 char *p = (char *)(pval+sizeof (dev_mask)); 284 int shift = sizeof (uint32_t)*8-1-card->slot; 285 uint32_t x = (dev_mask << shift) >> shift; 286 int count = 0; /* count # of 1's in x */ 287 int i = 0; 288 while (x != 0) { 289 count++; 290 x &= x-1; 291 } 292 while (count > 1) { 293 while (p[i++] != '\0') 294 ; 295 count--; 296 } 297 (void) strlcpy(card->slot_str, (char *)(p+i), 298 sizeof (card->slot_str)); 299 } 300 free(pval); 301 } 302 303 /* 304 * add all io devices under pci in io list 305 */ 306 /* ARGSUSED */ 307 static int 308 sun4v_pci_callback(picl_nodehdl_t pcih, void *args) 309 { 310 char path[PICL_PROPNAMELEN_MAX]; 311 char class[PICL_CLASSNAMELEN_MAX]; 312 char name[PICL_PROPNAMELEN_MAX]; 313 char model[PICL_PROPNAMELEN_MAX]; 314 char binding_name[PICL_PROPNAMELEN_MAX]; 315 char val[PICL_PROPNAMELEN_MAX]; 316 char *compatible; 317 picl_errno_t err; 318 picl_nodehdl_t nodeh; 319 struct io_card pci_card; 320 321 /* Walk through the children */ 322 323 err = picl_get_propval_by_name(pcih, PICL_PROP_CHILD, &nodeh, 324 sizeof (picl_nodehdl_t)); 325 326 while (err == PICL_SUCCESS) { 327 err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME, 328 class, sizeof (class)); 329 if (err != PICL_SUCCESS) 330 return (err); 331 332 if (args) { 333 char *val = args; 334 if (strcmp(class, val) == 0) { 335 err = picl_get_propval_by_name(nodeh, 336 PICL_PROP_PEER, &nodeh, 337 sizeof (picl_nodehdl_t)); 338 continue; 339 } else if (strcmp(val, PICL_CLASS_PCIEX) == 0 && 340 strcmp(class, PICL_CLASS_PCI) == 0) { 341 err = picl_get_propval_by_name(nodeh, 342 PICL_PROP_PEER, &nodeh, 343 sizeof (picl_nodehdl_t)); 344 continue; 345 } else if (strcmp(val, PICL_CLASS_PCI) == 0 && 346 strcmp(class, PICL_CLASS_PCIEX) == 0) { 347 err = picl_get_propval_by_name(nodeh, 348 PICL_PROP_PEER, &nodeh, 349 sizeof (picl_nodehdl_t)); 350 continue; 351 } 352 } 353 354 err = picl_get_propval_by_name(nodeh, PICL_PROP_DEVFS_PATH, 355 path, sizeof (path)); 356 if (err != PICL_SUCCESS) 357 return (err); 358 359 (void) strlcpy(pci_card.notes, path, sizeof (pci_card.notes)); 360 361 get_bus_type(nodeh, &pci_card); 362 get_slot_number(nodeh, &pci_card); 363 364 err = picl_get_propval_by_name(nodeh, PICL_PROP_NAME, name, 365 sizeof (name)); 366 if (err == PICL_PROPNOTFOUND) 367 (void) strlcpy(name, "", sizeof (name)); 368 else if (err != PICL_SUCCESS) 369 return (err); 370 371 err = picl_get_propval_by_name(nodeh, PICL_PROP_STATUS, val, 372 sizeof (val)); 373 if (err == PICL_PROPNOTFOUND) 374 (void) strlcpy(val, "", sizeof (val)); 375 else if (err != PICL_SUCCESS) 376 return (err); 377 378 /* Figure NAC name */ 379 if (pci_card.slot != -1) 380 (void) snprintf(pci_card.status, 381 sizeof (pci_card.status), 382 "%s%d", pci_card.slot_str, 383 pci_card.slot); 384 else 385 (void) snprintf(pci_card.status, 386 sizeof (pci_card.status), 387 "%s", pci_card.slot_str); 388 389 /* 390 * Get the name of this card. If binding_name is found, 391 * name will be <nodename>-<binding_name>. 392 */ 393 err = picl_get_propval_by_name(nodeh, PICL_PROP_BINDING_NAME, 394 binding_name, sizeof (binding_name)); 395 if (err == PICL_SUCCESS) { 396 if (strcmp(name, binding_name) != 0) { 397 (void) strlcat(name, "-", sizeof (name)); 398 (void) strlcat(name, binding_name, 399 sizeof (name)); 400 } 401 } else if (err == PICL_PROPNOTFOUND) { 402 /* 403 * if compatible prop is not found, name will be 404 * <nodename>-<compatible> 405 */ 406 err = sun4v_get_first_compatible_value(nodeh, 407 &compatible); 408 if (err == PICL_SUCCESS) { 409 (void) strlcat(name, "-", sizeof (name)); 410 (void) strlcat(name, compatible, 411 sizeof (name)); 412 free(compatible); 413 } 414 } else 415 return (err); 416 417 (void) strlcpy(pci_card.name, name, sizeof (pci_card.name)); 418 419 /* Get the model of this card */ 420 421 err = picl_get_propval_by_name(nodeh, OBP_PROP_MODEL, 422 model, sizeof (model)); 423 if (err == PICL_PROPNOTFOUND) 424 (void) strlcpy(model, "", sizeof (model)); 425 else if (err != PICL_SUCCESS) 426 return (err); 427 (void) strlcpy(pci_card.model, model, sizeof (pci_card.model)); 428 429 /* Print NAC name */ 430 log_printf("%-12s", pci_card.status); 431 /* Print IO Type */ 432 log_printf("%-6s", pci_card.bus_type); 433 /* Printf Card Name */ 434 log_printf("%-46s", pci_card.name); 435 /* Print Card Model */ 436 log_printf("%-8s", pci_card.model); 437 log_printf("\n"); 438 /* Print Status */ 439 log_printf("%-12s", val); 440 /* Print IO Type */ 441 log_printf("%-6s", ""); 442 /* Print Parent Path */ 443 log_printf("%-46s", pci_card.notes); 444 log_printf("\n"); 445 446 err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh, 447 sizeof (picl_nodehdl_t)); 448 } 449 return (PICL_WALK_CONTINUE); 450 } 451 452 /* 453 * display_pci 454 * Display all the PCI IO cards on this board. 455 */ 456 void 457 sun4v_display_pci(picl_nodehdl_t plafh) 458 { 459 char *fmt = "%-11s %-5s %-45s %-8s"; 460 /* Have we printed the column headings? */ 461 static int banner = FALSE; 462 463 if (banner == FALSE) { 464 log_printf("\n"); 465 log_printf("============================"); 466 log_printf(" IO Devices "); 467 log_printf("============================"); 468 log_printf("\n"); 469 log_printf(fmt, "Slot +", "Bus", "Name +", "Model", 0); 470 log_printf("\n"); 471 log_printf(fmt, "Status", "Type", "Path", "", 0); 472 log_printf("\n"); 473 log_printf("---------------------------------" 474 "------------------------------------\n"); 475 banner = TRUE; 476 } 477 478 (void) picl_walk_tree_by_class(plafh, PICL_CLASS_PCIEX, 479 PICL_CLASS_PCIEX, sun4v_pci_callback); 480 (void) picl_walk_tree_by_class(plafh, PICL_CLASS_PCI, 481 PICL_CLASS_PCI, sun4v_pci_callback); 482 (void) picl_walk_tree_by_class(plafh, PICL_CLASS_SUN4V, 483 PICL_CLASS_SUN4V, sun4v_pci_callback); 484 } 485 486 /* 487 * return the first compatible value 488 */ 489 static int 490 sun4v_get_first_compatible_value(picl_nodehdl_t nodeh, char **outbuf) 491 { 492 picl_errno_t err; 493 picl_prophdl_t proph; 494 picl_propinfo_t pinfo; 495 picl_prophdl_t tblh; 496 picl_prophdl_t rowproph; 497 char *pval; 498 499 err = picl_get_propinfo_by_name(nodeh, OBP_PROP_COMPATIBLE, 500 &pinfo, &proph); 501 if (err != PICL_SUCCESS) 502 return (err); 503 504 if (pinfo.type == PICL_PTYPE_CHARSTRING) { 505 pval = malloc(pinfo.size); 506 if (pval == NULL) 507 return (PICL_FAILURE); 508 err = picl_get_propval(proph, pval, pinfo.size); 509 if (err != PICL_SUCCESS) { 510 free(pval); 511 return (err); 512 } 513 *outbuf = pval; 514 return (PICL_SUCCESS); 515 } 516 517 if (pinfo.type != PICL_PTYPE_TABLE) 518 return (PICL_FAILURE); 519 520 /* get first string from table */ 521 err = picl_get_propval(proph, &tblh, pinfo.size); 522 if (err != PICL_SUCCESS) 523 return (err); 524 525 err = picl_get_next_by_row(tblh, &rowproph); 526 if (err != PICL_SUCCESS) 527 return (err); 528 529 err = picl_get_propinfo(rowproph, &pinfo); 530 if (err != PICL_SUCCESS) 531 return (err); 532 533 pval = malloc(pinfo.size); 534 if (pval == NULL) 535 return (PICL_FAILURE); 536 537 err = picl_get_propval(rowproph, pval, pinfo.size); 538 if (err != PICL_SUCCESS) { 539 free(pval); 540 return (err); 541 } 542 543 *outbuf = pval; 544 return (PICL_SUCCESS); 545 } 546 547 /* 548 * print size of a memory segment 549 */ 550 static void 551 print_memory_segment_size(uint64_t size) 552 { 553 uint64_t kbyte = 1024; 554 uint64_t mbyte = kbyte * kbyte; 555 uint64_t gbyte = kbyte * mbyte; 556 char buf[MEMORY_SIZE_FIELD]; 557 558 if (size >= gbyte) { 559 if (size % gbyte == 0) 560 (void) snprintf(buf, sizeof (buf), "%d GB", 561 (int)(size / gbyte)); 562 else 563 (void) snprintf(buf, sizeof (buf), "%.2f GB", 564 (float)size / gbyte); 565 } else if (size >= mbyte) { 566 if (size % mbyte == 0) 567 (void) snprintf(buf, sizeof (buf), "%d MB", 568 (int)(size / mbyte)); 569 else 570 (void) snprintf(buf, sizeof (buf), "%.2f MB", 571 (float)size / mbyte); 572 } else { 573 if (size % kbyte == 0) 574 (void) snprintf(buf, sizeof (buf), "%d KB", 575 (int)(size / kbyte)); 576 else 577 (void) snprintf(buf, sizeof (buf), "%.2f KB", 578 (float)size / kbyte); 579 } 580 log_printf("%-7s ", buf); 581 } 582 583 /* 584 * Enumerate banks and dimms within a memory segment. We're handed 585 * the first bank within the segment - we assume there are dimms 586 * (memory-module) nodes underneath. 587 */ 588 static void 589 print_memory_segment_contain(picl_nodehdl_t bank_nodeh) 590 { 591 char val[PICL_PROPNAMELEN_MAX]; 592 picl_nodehdl_t module_nodeh; 593 int flag = 0; 594 595 do { 596 if (picl_get_propval_by_name(bank_nodeh, PICL_PROP_CHILD, 597 &module_nodeh, sizeof (picl_nodehdl_t)) != PICL_SUCCESS) 598 continue; 599 do { 600 if (picl_get_propval_by_name(module_nodeh, 601 PICL_PROP_NAC, val, sizeof (val)) != 602 PICL_SUCCESS) 603 continue; 604 else { 605 if (!flag) { 606 log_printf("%-30s\n", val); 607 flag = 1; 608 } else 609 log_printf("%57s\n", val); 610 } 611 } while (picl_get_propval_by_name(module_nodeh, PICL_PROP_PEER, 612 &module_nodeh, sizeof (picl_nodehdl_t)) == 613 PICL_SUCCESS); 614 } while (picl_get_propval_by_name(bank_nodeh, PICL_PROP_PEER, 615 &bank_nodeh, sizeof (picl_nodehdl_t)) == PICL_SUCCESS); 616 } 617 618 /* 619 * Search node where _class=="memory-segment" 620 * print "Base Address", "Size", etc 621 */ 622 /*ARGSUSED*/ 623 static int 624 sun4v_memory_conf_callback(picl_nodehdl_t nodeh, void *args) 625 { 626 uint64_t base; 627 uint64_t size; 628 uint64_t ifactor; 629 picl_errno_t err = PICL_SUCCESS; 630 631 if (class_node_found == 0) { 632 class_node_found = 1; 633 return (PICL_WALK_TERMINATE); 634 } 635 while (err == PICL_SUCCESS) { 636 err = picl_get_propval_by_name(nodeh, PICL_PROP_BASEADDRESS, 637 &base, sizeof (base)); 638 if (err != PICL_SUCCESS) 639 break; 640 err = picl_get_propval_by_name(nodeh, PICL_PROP_SIZE, 641 &size, sizeof (size)); 642 if (err != PICL_SUCCESS) 643 break; 644 err = picl_get_propval_by_name(nodeh, 645 PICL_PROP_INTERLEAVE_FACTOR, &ifactor, 646 sizeof (ifactor)); 647 if (err != PICL_SUCCESS) 648 break; 649 log_printf("%-13llx", base); 650 print_memory_segment_size(size); 651 log_printf("%-18lld", ifactor); 652 err = picl_get_propval_by_name(nodeh, PICL_PROP_CHILD, 653 &nodeh, sizeof (nodeh)); 654 if (err == PICL_SUCCESS) 655 print_memory_segment_contain(nodeh); 656 log_printf("\n"); 657 err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh, 658 sizeof (picl_nodehdl_t)); 659 } 660 661 return (PICL_WALK_CONTINUE); 662 } 663 664 /*ARGSUSED*/ 665 void 666 sun4v_display_memory_conf(picl_nodehdl_t plafh) 667 { 668 char *fmt = "%-12s %-7s %-9s %-20s"; 669 (void) picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY_SEGMENT, 670 NULL, sun4v_memory_conf_callback); 671 if (class_node_found == 0) 672 return; 673 log_printf("\n"); 674 log_printf("============================"); 675 log_printf(" Memory Configuration "); 676 log_printf("============================"); 677 log_printf("\n"); 678 log_printf("Segment Table:\n"); 679 log_printf( 680 "---------------------------------------------------------\n"); 681 log_printf(fmt, "Base Address", "Size", "Interleave Factor", 682 "Contains", 0); 683 log_printf("\n"); 684 log_printf( 685 "---------------------------------------------------------\n"); 686 (void) picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY_SEGMENT, 687 NULL, sun4v_memory_conf_callback); 688 } 689 690 void 691 sun4v_display_cpu_devices(picl_nodehdl_t plafh) 692 { 693 char *fmt = "%-12s %-5s %-8s %-19s %-5s"; 694 695 /* 696 * Display the table header for CPUs . Then display the CPU 697 * frequency, cache size, and processor revision of all cpus. 698 */ 699 log_printf(dgettext(TEXT_DOMAIN, 700 "\n" 701 "=========================" 702 " CPUs " 703 "===============================================" 704 "\n" 705 "\n")); 706 log_printf(fmt, "", "", "", "CPU", "CPU", 0); 707 log_printf("\n"); 708 log_printf(fmt, "Location", "CPU", "Freq", 709 "Implementation", "Mask", 0); 710 log_printf("\n"); 711 log_printf(fmt, "------------", "-----", "--------", 712 "-------------------", "-----", 0); 713 log_printf("\n"); 714 715 (void) picl_walk_tree_by_class(plafh, "cpu", "cpu", sun4v_display_cpus); 716 } 717 718 /* 719 * Display the CPUs present on this board. 720 */ 721 /*ARGSUSED*/ 722 int 723 sun4v_display_cpus(picl_nodehdl_t cpuh, void* args) 724 { 725 int status; 726 picl_prophdl_t proph; 727 picl_prophdl_t tblh; 728 picl_prophdl_t rowproph; 729 picl_propinfo_t propinfo; 730 int *int_value; 731 uint64_t cpuid, mask_no; 732 char *comp_value; 733 char *no_prop_value = " "; 734 char freq_str[MAXSTRLEN]; 735 char fru_name[MAXSTRLEN]; 736 737 /* 738 * Get cpuid property and print it and the NAC name 739 */ 740 status = picl_get_propinfo_by_name(cpuh, "cpuid", &propinfo, &proph); 741 if (status == PICL_SUCCESS) { 742 status = picl_get_propval(proph, &cpuid, sizeof (cpuid)); 743 if (status != PICL_SUCCESS) { 744 log_printf("%-13s", no_prop_value); 745 log_printf("%-6s", no_prop_value); 746 } else { 747 (void) snprintf(fru_name, sizeof (fru_name), "%s%d", 748 CPU_STRAND_NAC, (int)cpuid); 749 log_printf("%-13s", fru_name); 750 log_printf("%-6d", (int)cpuid); 751 } 752 } else { 753 log_printf("%-13s", no_prop_value); 754 log_printf("%-6s", no_prop_value); 755 } 756 757 clock_freq: 758 status = picl_get_propinfo_by_name(cpuh, "clock-frequency", &propinfo, 759 &proph); 760 if (status == PICL_SUCCESS) { 761 int_value = malloc(propinfo.size); 762 if (int_value == NULL) { 763 log_printf("%-9s", no_prop_value); 764 goto compatible; 765 } 766 status = picl_get_propval(proph, int_value, propinfo.size); 767 if (status != PICL_SUCCESS) { 768 log_printf("%-9s", no_prop_value); 769 } else { 770 /* Running frequency */ 771 (void) snprintf(freq_str, sizeof (freq_str), "%d MHz", 772 CLK_FREQ_TO_MHZ(*int_value)); 773 log_printf("%-9s", freq_str); 774 } 775 free(int_value); 776 } else 777 log_printf("%-9s", no_prop_value); 778 779 compatible: 780 status = picl_get_propinfo_by_name(cpuh, "compatible", &propinfo, 781 &proph); 782 if (status == PICL_SUCCESS) { 783 if (propinfo.type == PICL_PTYPE_CHARSTRING) { 784 /* 785 * Compatible Property only has 1 value 786 */ 787 comp_value = malloc(propinfo.size); 788 if (comp_value == NULL) { 789 log_printf("%-20s", no_prop_value, 0); 790 goto mask; 791 } 792 status = picl_get_propval(proph, comp_value, 793 propinfo.size); 794 if (status != PICL_SUCCESS) 795 log_printf("%-20s", no_prop_value, 0); 796 else 797 log_printf("%-20s", comp_value, 0); 798 free(comp_value); 799 } else if (propinfo.type == PICL_PTYPE_TABLE) { 800 /* 801 * Compatible Property has multiple values 802 */ 803 status = picl_get_propval(proph, &tblh, propinfo.size); 804 if (status != PICL_SUCCESS) { 805 log_printf("%-20s", no_prop_value, 0); 806 goto mask; 807 } 808 status = picl_get_next_by_row(tblh, &rowproph); 809 if (status != PICL_SUCCESS) { 810 log_printf("%-20s", no_prop_value, 0); 811 goto mask; 812 } 813 814 status = picl_get_propinfo(rowproph, &propinfo); 815 if (status != PICL_SUCCESS) { 816 log_printf("%-20s", no_prop_value, 0); 817 goto mask; 818 } 819 820 comp_value = malloc(propinfo.size); 821 if (comp_value == NULL) { 822 log_printf("%-20s", no_prop_value, 0); 823 goto mask; 824 } 825 status = picl_get_propval(rowproph, comp_value, 826 propinfo.size); 827 if (status != PICL_SUCCESS) 828 log_printf("%-20s", no_prop_value, 0); 829 else 830 log_printf("%-20s", comp_value, 0); 831 free(comp_value); 832 } 833 } else 834 log_printf("%-20s", no_prop_value, 0); 835 836 mask: 837 status = picl_get_propinfo_by_name(cpuh, "mask#", &propinfo, &proph); 838 if (status == PICL_SUCCESS) { 839 status = picl_get_propval(proph, &mask_no, sizeof (mask_no)); 840 if (status != PICL_SUCCESS) { 841 log_printf("%-9s", no_prop_value); 842 } else { 843 log_printf(dgettext(TEXT_DOMAIN, " %2d.%d"), 844 (mask_no>> 4) & 0xf, mask_no & 0xf); 845 } 846 } else 847 log_printf("%-9s", no_prop_value); 848 849 done: 850 log_printf("\n"); 851 return (PICL_WALK_CONTINUE); 852 } 853 854 void 855 sun4v_display_diaginfo(int flag, Prom_node *root, picl_nodehdl_t plafh) 856 { 857 #ifdef lint 858 flag = flag; 859 root = root; 860 plafh = plafh; 861 #endif 862 /* 863 * This function is intentionally empty 864 */ 865 } 866 867 void 868 display_boardnum(int num) 869 { 870 log_printf("%2d ", num, 0); 871 } 872 873 static void 874 sun4v_disp_env_status() 875 { 876 if (phyplatformh == 0) 877 return; 878 log_printf("\n"); 879 log_printf("============================"); 880 log_printf(" Environmental Status "); 881 log_printf("============================"); 882 log_printf("\n"); 883 884 class_node_found = 0; 885 all_status_ok = 1; 886 sun4v_env_print_fan_sensors(); 887 888 class_node_found = 0; 889 all_status_ok = 1; 890 sun4v_env_print_fan_indicators(); 891 892 class_node_found = 0; 893 all_status_ok = 1; 894 sun4v_env_print_temp_sensors(); 895 896 class_node_found = 0; 897 all_status_ok = 1; 898 sun4v_env_print_temp_indicators(); 899 900 class_node_found = 0; 901 all_status_ok = 1; 902 sun4v_env_print_current_sensors(); 903 904 class_node_found = 0; 905 all_status_ok = 1; 906 sun4v_env_print_current_indicators(); 907 908 class_node_found = 0; 909 all_status_ok = 1; 910 sun4v_env_print_voltage_sensors(); 911 912 class_node_found = 0; 913 all_status_ok = 1; 914 sun4v_env_print_voltage_indicators(); 915 916 class_node_found = 0; 917 sun4v_env_print_LEDs(); 918 919 class_node_found = 0; 920 all_status_ok = 1; 921 sun4v_print_fru_status(); 922 923 class_node_found = 0; 924 sun4v_print_fw_rev(); 925 926 sun4v_print_chassis_serial_no(); 927 } 928 929 /*ARGSUSED*/ 930 static int 931 sun4v_env_print_sensor_callback(picl_nodehdl_t nodeh, void *args) 932 { 933 char val[PICL_PROPNAMELEN_MAX]; 934 picl_nodehdl_t parenth; 935 char *names[PARENT_NAMES]; 936 char *loc; 937 int i; 938 char *prop; 939 picl_errno_t err; 940 int32_t lo_warning, lo_shutdown; 941 int32_t hi_warning, hi_shutdown; 942 int32_t current_val; 943 944 if (class_node_found == 0) { 945 class_node_found = 1; 946 return (PICL_WALK_TERMINATE); 947 } 948 949 if (syserrlog == 0) { 950 err = picl_get_propval_by_name(nodeh, 951 PICL_PROP_OPERATIONAL_STATUS, val, 952 sizeof (val)); 953 if (err == PICL_SUCCESS) { 954 if (strcmp(val, "disabled") == 0) { 955 if (all_status_ok) { 956 all_status_ok = 0; 957 return (PICL_WALK_TERMINATE); 958 } 959 } else 960 return (PICL_WALK_CONTINUE); 961 } else { 962 all_status_ok = 0; 963 return (PICL_WALK_TERMINATE); 964 } 965 } 966 err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth, 967 sizeof (parenth)); 968 if (err != PICL_SUCCESS) { 969 log_printf("\n"); 970 return (PICL_WALK_CONTINUE); 971 } 972 973 if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) == NULL) 974 return (PICL_WALK_TERMINATE); 975 for (i = 0; i < PARENT_NAMES; i++) 976 if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) == NULL) { 977 while (--i > -1) 978 free(names[i]); 979 free(loc); 980 return (PICL_WALK_TERMINATE); 981 } 982 i = 0; 983 while (err == PICL_SUCCESS) { 984 if (parenth == chassish || parenth == phyplatformh) 985 break; 986 err = picl_get_propval_by_name(parenth, PICL_PROP_NAME, 987 names[i++], PICL_PROPNAMELEN_MAX); 988 if (err != PICL_SUCCESS) { 989 i--; 990 break; 991 } 992 if (i == PARENT_NAMES) 993 break; 994 err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT, 995 &parenth, sizeof (parenth)); 996 } 997 loc[0] = '\0'; 998 if (--i > -1) { 999 (void) strlcat(loc, names[i], 1000 PICL_PROPNAMELEN_MAX * PARENT_NAMES); 1001 } 1002 while (--i > -1) { 1003 (void) strlcat(loc, "/", PICL_PROPNAMELEN_MAX*PARENT_NAMES); 1004 (void) strlcat(loc, names[i], 1005 PICL_PROPNAMELEN_MAX * PARENT_NAMES); 1006 } 1007 log_printf("%-21s", loc); 1008 for (i = 0; i < PARENT_NAMES; i++) 1009 free(names[i]); 1010 free(loc); 1011 err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, val, 1012 sizeof (val)); 1013 if (err == PICL_SUCCESS) 1014 log_printf("%-15s", val); 1015 1016 prop = (char *)args; 1017 if (!prop) { 1018 log_printf("\n"); 1019 return (PICL_WALK_CONTINUE); 1020 } 1021 if (picl_get_propval_by_name(nodeh, prop, ¤t_val, 1022 sizeof (current_val)) != PICL_SUCCESS) { 1023 log_printf("\n"); 1024 return (PICL_WALK_CONTINUE); 1025 } 1026 if (picl_get_propval_by_name(nodeh, PICL_PROP_LOW_WARNING, 1027 &lo_warning, sizeof (lo_warning)) != PICL_SUCCESS) 1028 lo_warning = INVALID_THRESHOLD; 1029 if (picl_get_propval_by_name(nodeh, PICL_PROP_LOW_SHUTDOWN, 1030 &lo_shutdown, sizeof (lo_shutdown)) != PICL_SUCCESS) 1031 lo_shutdown = INVALID_THRESHOLD; 1032 if (picl_get_propval_by_name(nodeh, PICL_PROP_HIGH_WARNING, 1033 &hi_warning, sizeof (hi_warning)) != PICL_SUCCESS) 1034 hi_warning = INVALID_THRESHOLD; 1035 if (picl_get_propval_by_name(nodeh, PICL_PROP_HIGH_SHUTDOWN, 1036 &hi_shutdown, sizeof (hi_shutdown)) != PICL_SUCCESS) 1037 hi_shutdown = INVALID_THRESHOLD; 1038 1039 if ((lo_shutdown != INVALID_THRESHOLD && 1040 current_val <= lo_shutdown) || 1041 (hi_shutdown != INVALID_THRESHOLD && 1042 current_val >= hi_shutdown)) { 1043 log_printf("%-s", "failed ("); 1044 log_printf("%-d", current_val); 1045 log_printf("%-s", ")"); 1046 } else if ((lo_warning != INVALID_THRESHOLD && 1047 current_val <= lo_warning) || 1048 (hi_warning != INVALID_THRESHOLD && 1049 current_val >= hi_warning)) { 1050 log_printf("%-s", "warning ("); 1051 log_printf("%-d", current_val); 1052 log_printf("%-s", ")"); 1053 } else 1054 log_printf("%-s", "ok"); 1055 1056 log_printf("\n"); 1057 return (PICL_WALK_CONTINUE); 1058 } 1059 1060 /*ARGSUSED*/ 1061 static int 1062 sun4v_env_print_indicator_callback(picl_nodehdl_t nodeh, void *args) 1063 { 1064 char val[PICL_PROPNAMELEN_MAX]; 1065 char status[PICL_PROPNAMELEN_MAX]; 1066 picl_nodehdl_t parenth; 1067 char *names[PARENT_NAMES]; 1068 char *loc; 1069 int i = 0; 1070 char *prop = (char *)args; 1071 picl_errno_t err = PICL_SUCCESS; 1072 1073 if (class_node_found == 0) { 1074 class_node_found = 1; 1075 return (PICL_WALK_TERMINATE); 1076 } 1077 if (syserrlog == 0) { 1078 err = picl_get_propval_by_name(nodeh, 1079 PICL_PROP_OPERATIONAL_STATUS, status, 1080 sizeof (status)); 1081 if (err == PICL_SUCCESS) { 1082 if (strcmp(status, "disabled") == 0) { 1083 if (all_status_ok) { 1084 all_status_ok = 0; 1085 return (PICL_WALK_TERMINATE); 1086 } 1087 } else 1088 return (PICL_WALK_CONTINUE); 1089 } else { 1090 all_status_ok = 0; 1091 return (PICL_WALK_TERMINATE); 1092 } 1093 } 1094 err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth, 1095 sizeof (parenth)); 1096 if (err != PICL_SUCCESS) { 1097 log_printf("\n"); 1098 return (PICL_WALK_CONTINUE); 1099 } 1100 if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) == NULL) 1101 return (PICL_WALK_TERMINATE); 1102 for (i = 0; i < PARENT_NAMES; i++) 1103 if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) == NULL) { 1104 while (--i > -1) 1105 free(names[i]); 1106 free(loc); 1107 return (PICL_WALK_TERMINATE); 1108 } 1109 i = 0; 1110 while (err == PICL_SUCCESS) { 1111 if (parenth == chassish || parenth == phyplatformh) 1112 break; 1113 err = picl_get_propval_by_name(parenth, PICL_PROP_NAME, 1114 names[i++], PICL_PROPNAMELEN_MAX); 1115 if (err != PICL_SUCCESS) { 1116 i--; 1117 break; 1118 } 1119 if (i == PARENT_NAMES) 1120 break; 1121 err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT, 1122 &parenth, sizeof (parenth)); 1123 } 1124 loc[0] = '\0'; 1125 if (--i > -1) { 1126 (void) strlcat(loc, names[i], 1127 PICL_PROPNAMELEN_MAX * PARENT_NAMES); 1128 } 1129 while (--i > -1) { 1130 (void) strlcat(loc, "/", PICL_PROPNAMELEN_MAX * PARENT_NAMES); 1131 (void) strlcat(loc, names[i], 1132 PICL_PROPNAMELEN_MAX * PARENT_NAMES); 1133 } 1134 log_printf("%-21s", loc); 1135 for (i = 0; i < PARENT_NAMES; i++) 1136 free(names[i]); 1137 free(loc); 1138 err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, val, 1139 sizeof (val)); 1140 if (err == PICL_SUCCESS) 1141 log_printf("%-15s", val); 1142 if (syserrlog == 0) { 1143 log_printf("%-8s", status); 1144 return (PICL_WALK_CONTINUE); 1145 } 1146 err = picl_get_propval_by_name(nodeh, prop, val, sizeof (val)); 1147 if (err == PICL_SUCCESS) 1148 log_printf("%-8s", val); 1149 log_printf("\n"); 1150 return (PICL_WALK_CONTINUE); 1151 } 1152 1153 static void 1154 sun4v_env_print_fan_sensors() 1155 { 1156 char *fmt = "%-20s %-14s %-10s\n"; 1157 /* 1158 * If there isn't any fan sensor node, return now. 1159 */ 1160 (void) picl_walk_tree_by_class(phyplatformh, 1161 PICL_CLASS_RPM_SENSOR, (void *)PICL_CLASS_RPM_SENSOR, 1162 sun4v_env_print_sensor_callback); 1163 if (!class_node_found) 1164 return; 1165 log_printf("Fan sensors:\n"); 1166 if (syserrlog == 0) { 1167 (void) picl_walk_tree_by_class(phyplatformh, 1168 PICL_CLASS_RPM_SENSOR, 1169 NULL, sun4v_env_print_sensor_callback); 1170 if (all_status_ok) { 1171 log_printf("All fan sensors are OK.\n"); 1172 return; 1173 } 1174 } 1175 log_printf("------------------------------------------\n"); 1176 log_printf(fmt, "Location", "Sensor", "Status", 0); 1177 log_printf("------------------------------------------\n"); 1178 (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_RPM_SENSOR, 1179 PICL_PROP_SPEED, sun4v_env_print_sensor_callback); 1180 } 1181 1182 static void 1183 sun4v_env_print_fan_indicators() 1184 { 1185 char *fmt = "%-20s %-14s %-10s\n"; 1186 (void) picl_walk_tree_by_class(phyplatformh, 1187 PICL_CLASS_RPM_INDICATOR, (void *)PICL_CLASS_RPM_INDICATOR, 1188 sun4v_env_print_indicator_callback); 1189 if (!class_node_found) 1190 return; 1191 log_printf("\nFan indicators:\n"); 1192 if (syserrlog == 0) { 1193 (void) picl_walk_tree_by_class(phyplatformh, 1194 PICL_CLASS_RPM_INDICATOR, 1195 NULL, sun4v_env_print_indicator_callback); 1196 if (all_status_ok) { 1197 log_printf("All fan indicators are OK.\n"); 1198 return; 1199 } 1200 } 1201 log_printf("---------------------------------------------\n"); 1202 log_printf(fmt, "Location", "Sensor", "Condition", 0); 1203 log_printf("---------------------------------------------\n"); 1204 (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_RPM_INDICATOR, 1205 PICL_CLASS_RPM_INDICATOR, sun4v_env_print_indicator_callback); 1206 } 1207 1208 static void 1209 sun4v_env_print_temp_sensors() 1210 { 1211 char *fmt = "%-20s %-14s %-10s\n"; 1212 (void) picl_walk_tree_by_class(phyplatformh, 1213 PICL_CLASS_TEMPERATURE_SENSOR, 1214 (void *)PICL_PROP_TEMPERATURE, 1215 sun4v_env_print_sensor_callback); 1216 if (!class_node_found) 1217 return; 1218 1219 log_printf("\nTemperature sensors:\n"); 1220 if (syserrlog == 0) { 1221 (void) picl_walk_tree_by_class(phyplatformh, 1222 PICL_CLASS_TEMPERATURE_SENSOR, 1223 NULL, sun4v_env_print_sensor_callback); 1224 if (all_status_ok) { 1225 log_printf("All temperature sensors are OK.\n"); 1226 return; 1227 } 1228 } 1229 log_printf("------------------------------------------\n"); 1230 log_printf(fmt, "Location", "Sensor", "Status", 0); 1231 log_printf("------------------------------------------\n"); 1232 (void) picl_walk_tree_by_class(phyplatformh, 1233 PICL_CLASS_TEMPERATURE_SENSOR, 1234 (void *)PICL_PROP_TEMPERATURE, sun4v_env_print_sensor_callback); 1235 } 1236 1237 static void 1238 sun4v_env_print_temp_indicators() 1239 { 1240 char *fmt = "%-20s %-14s %-8s\n"; 1241 (void) picl_walk_tree_by_class(phyplatformh, 1242 PICL_CLASS_TEMPERATURE_INDICATOR, (void *)PICL_PROP_CONDITION, 1243 sun4v_env_print_indicator_callback); 1244 if (!class_node_found) 1245 return; 1246 log_printf("\nTemperature indicators:\n"); 1247 if (syserrlog == 0) { 1248 (void) picl_walk_tree_by_class(phyplatformh, 1249 PICL_CLASS_TEMPERATURE_INDICATOR, NULL, 1250 sun4v_env_print_indicator_callback); 1251 if (all_status_ok) { 1252 log_printf("All temperature indicators are OK.\n"); 1253 return; 1254 } 1255 } 1256 log_printf("---------------------------------------\n"); 1257 log_printf(fmt, "Location", "Indicator", "Condition", 0); 1258 log_printf("---------------------------------------\n"); 1259 (void) picl_walk_tree_by_class(phyplatformh, 1260 PICL_CLASS_TEMPERATURE_INDICATOR, 1261 (void *)PICL_PROP_CONDITION, 1262 sun4v_env_print_indicator_callback); 1263 } 1264 1265 static void 1266 sun4v_env_print_current_sensors() 1267 { 1268 char *fmt = "%-20s %-14s %-10s\n"; 1269 (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_CURRENT_SENSOR, 1270 (void *)PICL_PROP_CURRENT, sun4v_env_print_sensor_callback); 1271 if (!class_node_found) 1272 return; 1273 log_printf("\nCurrent sensors:\n"); 1274 if (syserrlog == 0) { 1275 (void) picl_walk_tree_by_class(phyplatformh, 1276 PICL_CLASS_CURRENT_SENSOR, 1277 NULL, sun4v_env_print_sensor_callback); 1278 if (all_status_ok) { 1279 log_printf("All current sensors are OK.\n"); 1280 return; 1281 } 1282 } 1283 log_printf("------------------------------------------\n"); 1284 log_printf(fmt, "Location", "Sensor", "Status", 0); 1285 log_printf("------------------------------------------\n"); 1286 (void) picl_walk_tree_by_class(phyplatformh, 1287 PICL_CLASS_CURRENT_SENSOR, (void *)PICL_PROP_CURRENT, 1288 sun4v_env_print_sensor_callback); 1289 } 1290 1291 static void 1292 sun4v_env_print_current_indicators() 1293 { 1294 char *fmt = "%-20s %-14s %-8s\n"; 1295 (void) picl_walk_tree_by_class(phyplatformh, 1296 PICL_CLASS_CURRENT_INDICATOR, 1297 (void *)PICL_PROP_CONDITION, 1298 sun4v_env_print_indicator_callback); 1299 if (!class_node_found) 1300 return; 1301 log_printf("\nCurrent indicators:\n"); 1302 if (syserrlog == 0) { 1303 (void) picl_walk_tree_by_class(phyplatformh, 1304 PICL_CLASS_CURRENT_INDICATOR, NULL, 1305 sun4v_env_print_indicator_callback); 1306 if (all_status_ok) { 1307 log_printf("All current indicators are OK.\n"); 1308 return; 1309 } 1310 } 1311 log_printf("---------------------------------------------\n"); 1312 log_printf(fmt, "Location", "Indicator", "Condition", 0); 1313 log_printf("---------------------------------------------\n"); 1314 (void) picl_walk_tree_by_class(phyplatformh, 1315 PICL_CLASS_CURRENT_INDICATOR, 1316 (void *)PICL_PROP_CONDITION, 1317 sun4v_env_print_indicator_callback); 1318 } 1319 1320 static void 1321 sun4v_env_print_voltage_sensors() 1322 { 1323 char *fmt = "%-20s %-14s %-10s\n"; 1324 (void) picl_walk_tree_by_class(phyplatformh, 1325 PICL_CLASS_VOLTAGE_SENSOR, 1326 PICL_PROP_VOLTAGE, 1327 sun4v_env_print_sensor_callback); 1328 if (!class_node_found) 1329 return; 1330 log_printf("\nVoltage sensors:\n"); 1331 if (syserrlog == 0) { 1332 (void) picl_walk_tree_by_class(phyplatformh, 1333 PICL_CLASS_VOLTAGE_SENSOR, 1334 NULL, sun4v_env_print_sensor_callback); 1335 if (all_status_ok) { 1336 log_printf("All voltage sensors are OK.\n"); 1337 return; 1338 } 1339 } 1340 log_printf("------------------------------------------\n"); 1341 log_printf(fmt, "Location", "Sensor", "Status", 0); 1342 log_printf("------------------------------------------\n"); 1343 (void) picl_walk_tree_by_class(phyplatformh, 1344 PICL_CLASS_VOLTAGE_SENSOR, 1345 (void *)PICL_PROP_VOLTAGE, 1346 sun4v_env_print_sensor_callback); 1347 } 1348 1349 static void 1350 sun4v_env_print_voltage_indicators() 1351 { 1352 char *fmt = "%-20s %-14s %-8s\n"; 1353 (void) picl_walk_tree_by_class(phyplatformh, 1354 PICL_CLASS_VOLTAGE_INDICATOR, 1355 (void *)PICL_PROP_CONDITION, 1356 sun4v_env_print_indicator_callback); 1357 if (!class_node_found) 1358 return; 1359 log_printf("\nVoltage indicators:\n"); 1360 if (syserrlog == 0) { 1361 (void) picl_walk_tree_by_class(phyplatformh, 1362 PICL_CLASS_VOLTAGE_INDICATOR, NULL, 1363 sun4v_env_print_indicator_callback); 1364 if (all_status_ok) { 1365 log_printf("All voltage indicators are OK.\n"); 1366 return; 1367 } 1368 } 1369 log_printf("---------------------------------------------\n"); 1370 log_printf(fmt, "Location", "Indicator", "Condition", 0); 1371 log_printf("---------------------------------------------\n"); 1372 (void) picl_walk_tree_by_class(phyplatformh, 1373 PICL_CLASS_VOLTAGE_INDICATOR, 1374 (void *)PICL_PROP_CONDITION, 1375 sun4v_env_print_indicator_callback); 1376 } 1377 1378 static void 1379 sun4v_env_print_LEDs() 1380 { 1381 char *fmt = "%-20s %-14s %-8s\n"; 1382 if (syserrlog == 0) 1383 return; 1384 (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_LED, 1385 (void *)PICL_PROP_STATE, sun4v_env_print_indicator_callback); 1386 if (!class_node_found) 1387 return; 1388 log_printf("\nLEDs:\n"); 1389 log_printf("-----------------------------------------\n"); 1390 log_printf(fmt, "Location", "LED", "State", 0); 1391 log_printf("-----------------------------------------\n"); 1392 (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_LED, 1393 (void *)PICL_PROP_STATE, sun4v_env_print_indicator_callback); 1394 } 1395 1396 /*ARGSUSED*/ 1397 static int 1398 sun4v_print_fru_status_callback(picl_nodehdl_t nodeh, void *args) 1399 { 1400 char label[PICL_PROPNAMELEN_MAX]; 1401 char status[PICL_PROPNAMELEN_MAX]; 1402 picl_errno_t err; 1403 picl_prophdl_t proph; 1404 picl_nodehdl_t parenth; 1405 char *names[PARENT_NAMES]; 1406 char *loc; 1407 int i; 1408 1409 if (!class_node_found) { 1410 class_node_found = 1; 1411 return (PICL_WALK_TERMINATE); 1412 } 1413 err = picl_get_prop_by_name(nodeh, PICL_PROP_IS_FRU, &proph); 1414 if (err != PICL_SUCCESS) 1415 return (PICL_WALK_CONTINUE); 1416 err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, label, 1417 sizeof (label)); 1418 if (err != PICL_SUCCESS) 1419 return (PICL_WALK_CONTINUE); 1420 err = picl_get_propval_by_name(nodeh, PICL_PROP_OPERATIONAL_STATUS, 1421 status, sizeof (status)); 1422 if (err != PICL_SUCCESS) 1423 return (PICL_WALK_CONTINUE); 1424 if (syserrlog == 0) { 1425 if (strcmp(status, "disabled") == 0) { 1426 if (all_status_ok) { 1427 all_status_ok = 0; 1428 return (PICL_WALK_TERMINATE); 1429 } 1430 } else 1431 return (PICL_WALK_CONTINUE); 1432 } 1433 err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth, 1434 sizeof (parenth)); 1435 if (err != PICL_SUCCESS) { 1436 log_printf("\n"); 1437 return (PICL_WALK_CONTINUE); 1438 } 1439 if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) == NULL) 1440 return (PICL_WALK_TERMINATE); 1441 for (i = 0; i < PARENT_NAMES; i++) 1442 if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) == NULL) { 1443 while (--i > -1) 1444 free(names[i]); 1445 free(loc); 1446 return (PICL_WALK_TERMINATE); 1447 } 1448 i = 0; 1449 while (err == PICL_SUCCESS) { 1450 if (parenth == chassish || parenth == phyplatformh) 1451 break; 1452 err = picl_get_propval_by_name(parenth, PICL_PROP_NAME, 1453 names[i++], PICL_PROPNAMELEN_MAX); 1454 if (err != PICL_SUCCESS) { 1455 i--; 1456 break; 1457 } 1458 if (i == PARENT_NAMES) 1459 break; 1460 err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT, 1461 &parenth, sizeof (parenth)); 1462 } 1463 loc[0] = '\0'; 1464 if (--i > -1) { 1465 (void) strlcat(loc, names[i], 1466 PICL_PROPNAMELEN_MAX * PARENT_NAMES); 1467 } 1468 while (--i > -1) { 1469 (void) strlcat(loc, "/", PICL_PROPNAMELEN_MAX * PARENT_NAMES); 1470 (void) strlcat(loc, names[i], 1471 PICL_PROPNAMELEN_MAX * PARENT_NAMES); 1472 } 1473 log_printf("%-21s", loc); 1474 for (i = 0; i < PARENT_NAMES; i++) 1475 free(names[i]); 1476 free(loc); 1477 log_printf("%-10s", label); 1478 log_printf("%-9s", status); 1479 log_printf("\n"); 1480 return (PICL_WALK_CONTINUE); 1481 } 1482 1483 static void 1484 sun4v_print_fru_status() 1485 { 1486 char *fmt = "%-20s %-9s %-8s\n"; 1487 (void) picl_walk_tree_by_class(phyplatformh, NULL, NULL, 1488 sun4v_print_fru_status_callback); 1489 if (!class_node_found) 1490 return; 1491 log_printf("\n"); 1492 log_printf("============================"); 1493 log_printf(" FRU Status "); 1494 log_printf("============================"); 1495 log_printf("\n"); 1496 1497 if (syserrlog == 0) { 1498 (void) picl_walk_tree_by_class(phyplatformh, 1499 PICL_CLASS_MODULE, NULL, 1500 sun4v_print_fru_status_callback); 1501 if (all_status_ok) { 1502 log_printf("All FRUs are enabled.\n"); 1503 return; 1504 } 1505 } 1506 log_printf(fmt, "Location", "Name", "Status", 0); 1507 log_printf("----------------------------------------\n"); 1508 (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_MODULE, NULL, 1509 sun4v_print_fru_status_callback); 1510 } 1511 1512 /*ARGSUSED*/ 1513 static int 1514 sun4v_print_fw_rev_callback(picl_nodehdl_t nodeh, void *args) 1515 { 1516 char label[PICL_PROPNAMELEN_MAX]; 1517 char rev[PICL_PROPNAMELEN_MAX]; 1518 picl_errno_t err; 1519 1520 if (!class_node_found) { 1521 class_node_found = 1; 1522 return (PICL_WALK_TERMINATE); 1523 } 1524 err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, label, 1525 sizeof (label)); 1526 if (err != PICL_SUCCESS) 1527 return (PICL_WALK_CONTINUE); 1528 err = picl_get_propval_by_name(nodeh, PICL_PROP_FW_REVISION, rev, 1529 sizeof (rev)); 1530 if (err != PICL_SUCCESS) 1531 return (PICL_WALK_CONTINUE); 1532 if (strlen(rev) == 0) 1533 return (PICL_WALK_CONTINUE); 1534 log_printf("%-21s", label); 1535 log_printf("%-40s", rev); 1536 log_printf("\n"); 1537 return (PICL_WALK_CONTINUE); 1538 } 1539 1540 static void 1541 sun4v_print_fw_rev() 1542 { 1543 char *fmt = "%-20s %-10s\n"; 1544 if (syserrlog == 0) 1545 return; 1546 (void) picl_walk_tree_by_class(phyplatformh, NULL, NULL, 1547 sun4v_print_fw_rev_callback); 1548 if (!class_node_found) 1549 return; 1550 log_printf("\n"); 1551 log_printf("============================"); 1552 log_printf(" FW Version "); 1553 log_printf("============================"); 1554 log_printf("\n"); 1555 log_printf(fmt, "Name", "Version", 0); 1556 log_printf("----------------------------\n"); 1557 (void) picl_walk_tree_by_class(phyplatformh, NULL, NULL, 1558 sun4v_print_fw_rev_callback); 1559 } 1560 1561 static void 1562 sun4v_print_chassis_serial_no() 1563 { 1564 char val[PICL_PROPNAMELEN_MAX]; 1565 picl_errno_t err; 1566 if (syserrlog == 0 || chassish == 0) 1567 return; 1568 1569 log_printf("\n"); 1570 log_printf("Chassis Serial Number"); 1571 log_printf("\n"); 1572 log_printf("---------------------\n"); 1573 err = picl_get_propval_by_name(chassish, PICL_PROP_SERIAL_NUMBER, 1574 val, sizeof (val)); 1575 if (err == PICL_SUCCESS) 1576 log_printf("%s", val); 1577 log_printf("\n"); 1578 } 1579