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