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