11708Sstevel /* 21708Sstevel * CDDL HEADER START 31708Sstevel * 41708Sstevel * The contents of this file are subject to the terms of the 5*3941Svenki * Common Development and Distribution License (the "License"). 6*3941Svenki * You may not use this file except in compliance with the License. 71708Sstevel * 81708Sstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 91708Sstevel * or http://www.opensolaris.org/os/licensing. 101708Sstevel * See the License for the specific language governing permissions 111708Sstevel * and limitations under the License. 121708Sstevel * 131708Sstevel * When distributing Covered Code, include this CDDL HEADER in each 141708Sstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 151708Sstevel * If applicable, add the following below this CDDL HEADER, with the 161708Sstevel * fields enclosed by brackets "[]" replaced with your own identifying 171708Sstevel * information: Portions Copyright [yyyy] [name of copyright owner] 181708Sstevel * 191708Sstevel * CDDL HEADER END 201708Sstevel */ 211708Sstevel /* 22*3941Svenki * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 231708Sstevel * Use is subject to license terms. 241708Sstevel */ 251708Sstevel 261708Sstevel #pragma ident "%Z%%M% %I% %E% SMI" 271708Sstevel 281708Sstevel #include <stdio.h> 291708Sstevel #include <stdlib.h> 301708Sstevel #include <unistd.h> 311708Sstevel #include <ctype.h> 321708Sstevel #include <string.h> 331708Sstevel #include <kvm.h> 341708Sstevel #include <varargs.h> 351708Sstevel #include <time.h> 361708Sstevel #include <dirent.h> 371708Sstevel #include <fcntl.h> 381708Sstevel #include <sys/param.h> 391708Sstevel #include <sys/stat.h> 401708Sstevel #include <sys/types.h> 411708Sstevel #include <sys/utsname.h> 421708Sstevel #include <sys/openpromio.h> 431708Sstevel #include <libintl.h> 441708Sstevel #include <syslog.h> 451708Sstevel #include <sys/dkio.h> 46*3941Svenki #include <sys/systeminfo.h> 47*3941Svenki #include <picldefs.h> 481708Sstevel #include "pdevinfo.h" 491708Sstevel #include "display.h" 501708Sstevel #include "display_sun4v.h" 511708Sstevel #include "libprtdiag.h" 521708Sstevel 531708Sstevel #if !defined(TEXT_DOMAIN) 541708Sstevel #define TEXT_DOMAIN "SYS_TEST" 551708Sstevel #endif 561708Sstevel 57*3941Svenki #define IOBOARD "IOBD" 58*3941Svenki #define NETWORK "network" 59*3941Svenki #define PCIE_COMPATIBLE_STR "pciex" 60*3941Svenki #define PCIX_COMPATIBLE_STR "pci" 61*3941Svenki #define SUN4V_MACHINE "sun4v" 62*3941Svenki #define PARENT_NAMES 10 63*3941Svenki 64*3941Svenki /* 65*3941Svenki * Additional OBP properties 66*3941Svenki */ 67*3941Svenki #define OBP_PROP_COMPATIBLE "compatible" 68*3941Svenki #define OBP_PROP_MODEL "model" 69*3941Svenki #define OBP_PROP_SLOT_NAMES "slot-names" 70*3941Svenki 71*3941Svenki #define PICL_NODE_PHYSICAL_PLATFORM "physical-platform" 72*3941Svenki #define PICL_NODE_CHASSIS "chassis" 73*3941Svenki #define MEMORY_SIZE_FIELD 11 74*3941Svenki #define INVALID_THRESHOLD 1000000 75*3941Svenki 76*3941Svenki /* 77*3941Svenki * Additional picl classes 78*3941Svenki */ 79*3941Svenki #ifndef PICL_CLASS_SUN4V 80*3941Svenki #define PICL_CLASS_SUN4V "sun4v" 81*3941Svenki #endif 82*3941Svenki 83*3941Svenki #ifndef PICL_PROP_NAC 84*3941Svenki #define PICL_PROP_NAC "nac" 85*3941Svenki #endif 86*3941Svenki 87*3941Svenki extern int sys_clk; 88*3941Svenki extern picl_errno_t sun4v_get_node_by_name(picl_nodehdl_t, char *, 89*3941Svenki picl_nodehdl_t *); 90*3941Svenki 91*3941Svenki static picl_nodehdl_t rooth = 0, phyplatformh = 0; 92*3941Svenki static picl_nodehdl_t chassish = 0; 93*3941Svenki static int class_node_found; 94*3941Svenki static int syserrlog; 95*3941Svenki static int all_status_ok; 96*3941Svenki 97*3941Svenki /* local functions */ 98*3941Svenki static int sun4v_get_first_compatible_value(picl_nodehdl_t, char **); 99*3941Svenki static void sun4v_display_memory_conf(picl_nodehdl_t); 100*3941Svenki static void sun4v_disp_env_status(); 101*3941Svenki static void sun4v_env_print_fan_sensors(); 102*3941Svenki static void sun4v_env_print_fan_indicators(); 103*3941Svenki static void sun4v_env_print_temp_sensors(); 104*3941Svenki static void sun4v_env_print_temp_indicators(); 105*3941Svenki static void sun4v_env_print_current_sensors(); 106*3941Svenki static void sun4v_env_print_current_indicators(); 107*3941Svenki static void sun4v_env_print_voltage_sensors(); 108*3941Svenki static void sun4v_env_print_voltage_indicators(); 109*3941Svenki static void sun4v_env_print_LEDs(); 110*3941Svenki static void sun4v_print_fru_status(); 111*3941Svenki static void sun4v_print_fw_rev(); 112*3941Svenki static void sun4v_print_chassis_serial_no(); 1131708Sstevel 1141708Sstevel int 115*3941Svenki sun4v_display(Sys_tree *tree, Prom_node *root, int log, 116*3941Svenki picl_nodehdl_t plafh) 1171708Sstevel { 1181708Sstevel void *value; /* used for opaque PROM data */ 1191708Sstevel struct mem_total memory_total; /* Total memory in system */ 1201708Sstevel struct grp_info grps; /* Info on all groups in system */ 121*3941Svenki char machine[MAXSTRLEN]; 122*3941Svenki 123*3941Svenki if (sysinfo(SI_MACHINE, machine, sizeof (machine)) == -1) 124*3941Svenki return (1); 125*3941Svenki if (strncmp(machine, SUN4V_MACHINE, strlen(SUN4V_MACHINE)) != 0) 126*3941Svenki return (1); 1271708Sstevel 1281708Sstevel sys_clk = -1; /* System clock freq. (in MHz) */ 1291708Sstevel 1301708Sstevel /* 1311708Sstevel * Now display the machine's configuration. We do this if we 1321708Sstevel * are not logging. 1331708Sstevel */ 1341708Sstevel if (!logging) { 1351708Sstevel struct utsname uts_buf; 1361708Sstevel 1371708Sstevel /* 1381708Sstevel * Display system banner 1391708Sstevel */ 1401708Sstevel (void) uname(&uts_buf); 1411708Sstevel 142*3941Svenki log_printf(dgettext(TEXT_DOMAIN, "System Configuration: " 143*3941Svenki "Sun Microsystems %s %s\n"), uts_buf.machine, 144*3941Svenki get_prop_val(find_prop(root, "banner-name")), 0); 1451708Sstevel 1461708Sstevel /* display system clock frequency */ 1471708Sstevel value = get_prop_val(find_prop(root, "clock-frequency")); 1481708Sstevel if (value != NULL) { 1491708Sstevel sys_clk = ((*((int *)value)) + 500000) / 1000000; 1501708Sstevel log_printf(dgettext(TEXT_DOMAIN, "System clock " 1511708Sstevel "frequency: %d MHz\n"), sys_clk, 0); 1521708Sstevel } 1531708Sstevel 1541708Sstevel /* Display the Memory Size */ 1551708Sstevel display_memorysize(tree, NULL, &grps, &memory_total); 1561708Sstevel 1571708Sstevel /* Display the CPU devices */ 1581708Sstevel sun4v_display_cpu_devices(plafh); 1591708Sstevel 1601708Sstevel /* Display the Memory configuration */ 161*3941Svenki class_node_found = 0; 162*3941Svenki sun4v_display_memory_conf(plafh); 1631708Sstevel 1641708Sstevel /* Display all the IO cards. */ 1651708Sstevel (void) sun4v_display_pci(plafh); 166*3941Svenki sun4v_display_diaginfo((log || (logging)), root, plafh); 1671708Sstevel 168*3941Svenki if (picl_get_root(&rooth) != PICL_SUCCESS) 169*3941Svenki return (1); 170*3941Svenki if (sun4v_get_node_by_name(rooth, PICL_NODE_PHYSICAL_PLATFORM, 171*3941Svenki &phyplatformh) != PICL_SUCCESS) 172*3941Svenki return (1); 173*3941Svenki 174*3941Svenki if (picl_find_node(phyplatformh, PICL_PROP_CLASSNAME, 175*3941Svenki PICL_PTYPE_CHARSTRING, (void *)PICL_CLASS_CHASSIS, 176*3941Svenki strlen(PICL_CLASS_CHASSIS), &chassish) != PICL_SUCCESS) 177*3941Svenki return (1); 178*3941Svenki 179*3941Svenki syserrlog = log; 180*3941Svenki sun4v_disp_env_status(); 181*3941Svenki } 182*3941Svenki return (0); 183*3941Svenki } 184*3941Svenki 185*3941Svenki static void 186*3941Svenki get_bus_type(picl_nodehdl_t nodeh, struct io_card *card) 187*3941Svenki { 188*3941Svenki char *compatible; 189*3941Svenki 190*3941Svenki (void) strcpy(card->bus_type, "PCIX"); 191*3941Svenki if (sun4v_get_first_compatible_value(nodeh, &compatible) 192*3941Svenki == PICL_SUCCESS) { 193*3941Svenki if (strncmp(compatible, PCIE_COMPATIBLE_STR, 194*3941Svenki strlen(PCIE_COMPATIBLE_STR)) == 0) 195*3941Svenki (void) strcpy(card->bus_type, "PCIE"); 196*3941Svenki free(compatible); 197*3941Svenki } 198*3941Svenki } 199*3941Svenki 200*3941Svenki static picl_errno_t 201*3941Svenki get_slot_label(picl_nodehdl_t nodeh, struct io_card *card) 202*3941Svenki { 203*3941Svenki char val[PICL_PROPNAMELEN_MAX]; 204*3941Svenki picl_errno_t err; 205*3941Svenki 206*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, val, 207*3941Svenki sizeof (val)); 208*3941Svenki if (err != PICL_SUCCESS) 209*3941Svenki return (err); 210*3941Svenki 211*3941Svenki (void) strcpy(card->slot_str, val); 212*3941Svenki card->slot = -1; 213*3941Svenki return (PICL_SUCCESS); 214*3941Svenki } 215*3941Svenki 216*3941Svenki static void 217*3941Svenki get_slot_number(picl_nodehdl_t nodeh, struct io_card *card) 218*3941Svenki { 219*3941Svenki picl_errno_t err; 220*3941Svenki picl_prophdl_t proph; 221*3941Svenki picl_propinfo_t pinfo; 222*3941Svenki picl_nodehdl_t pnodeh; 223*3941Svenki uint8_t *pval; 224*3941Svenki uint32_t dev_mask; 225*3941Svenki char uaddr[MAXSTRLEN]; 226*3941Svenki int i; 227*3941Svenki 228*3941Svenki if (get_slot_label(nodeh, card) == PICL_SUCCESS) 229*3941Svenki return; 230*3941Svenki err = PICL_SUCCESS; 231*3941Svenki while (err == PICL_SUCCESS) { 232*3941Svenki if (picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &pnodeh, 233*3941Svenki sizeof (pnodeh)) != PICL_SUCCESS) { 234*3941Svenki (void) strcpy(card->slot_str, IOBOARD); 235*3941Svenki card->slot = -1; 236*3941Svenki return; 237*3941Svenki } 238*3941Svenki if (picl_get_propinfo_by_name(pnodeh, OBP_PROP_SLOT_NAMES, 239*3941Svenki &pinfo, &proph) == PICL_SUCCESS) { 240*3941Svenki break; 241*3941Svenki } 242*3941Svenki nodeh = pnodeh; 243*3941Svenki } 244*3941Svenki if (picl_get_propval_by_name(nodeh, PICL_PROP_UNIT_ADDRESS, uaddr, 245*3941Svenki sizeof (uaddr)) != PICL_SUCCESS) { 246*3941Svenki (void) strcpy(card->slot_str, IOBOARD); 247*3941Svenki card->slot = -1; 248*3941Svenki return; 249*3941Svenki } 250*3941Svenki pval = (uint8_t *)malloc(pinfo.size); 251*3941Svenki if (!pval) { 252*3941Svenki (void) strcpy(card->slot_str, IOBOARD); 253*3941Svenki card->slot = -1; 254*3941Svenki return; 255*3941Svenki } 256*3941Svenki if (picl_get_propval(proph, pval, pinfo.size) != PICL_SUCCESS) { 257*3941Svenki (void) strcpy(card->slot_str, IOBOARD); 258*3941Svenki card->slot = -1; 259*3941Svenki free(pval); 260*3941Svenki return; 2611708Sstevel } 2621708Sstevel 263*3941Svenki dev_mask = 0; 264*3941Svenki for (i = 0; i < sizeof (dev_mask); i++) 265*3941Svenki dev_mask |= (*(pval+i) << 8*(sizeof (dev_mask)-1-i)); 266*3941Svenki for (i = 0; i < sizeof (uaddr) && uaddr[i] != '\0'; i++) { 267*3941Svenki if (uaddr[i] == ',') { 268*3941Svenki uaddr[i] = '\0'; 269*3941Svenki break; 270*3941Svenki } 271*3941Svenki } 272*3941Svenki card->slot = atol(uaddr); 273*3941Svenki if (((1 << card->slot) & dev_mask) == 0) { 274*3941Svenki (void) strcpy(card->slot_str, IOBOARD); 275*3941Svenki card->slot = -1; 276*3941Svenki } else { 277*3941Svenki char *p = (char *)(pval+sizeof (dev_mask)); 278*3941Svenki int shift = sizeof (uint32_t)*8-1-card->slot; 279*3941Svenki uint32_t x = (dev_mask << shift) >> shift; 280*3941Svenki int count = 0; /* count # of 1's in x */ 281*3941Svenki int i = 0; 282*3941Svenki while (x != 0) { 283*3941Svenki count++; 284*3941Svenki x &= x-1; 285*3941Svenki } 286*3941Svenki while (count > 1) { 287*3941Svenki while (p[i++] != '\0'); 288*3941Svenki count--; 289*3941Svenki } 290*3941Svenki (void) strcpy(card->slot_str, (char *)(p+i)); 291*3941Svenki } 292*3941Svenki free(pval); 293*3941Svenki } 294*3941Svenki 295*3941Svenki /* 296*3941Svenki * add all io devices under pci in io list 297*3941Svenki */ 298*3941Svenki /* ARGSUSED */ 299*3941Svenki static int 300*3941Svenki sun4v_pci_callback(picl_nodehdl_t pcih, void *args) 301*3941Svenki { 302*3941Svenki char path[PICL_PROPNAMELEN_MAX]; 303*3941Svenki char class[PICL_CLASSNAMELEN_MAX]; 304*3941Svenki char name[PICL_PROPNAMELEN_MAX]; 305*3941Svenki char model[PICL_PROPNAMELEN_MAX]; 306*3941Svenki char binding_name[PICL_PROPNAMELEN_MAX]; 307*3941Svenki char val[PICL_PROPNAMELEN_MAX]; 308*3941Svenki char *compatible; 309*3941Svenki picl_errno_t err; 310*3941Svenki picl_nodehdl_t nodeh; 311*3941Svenki struct io_card pci_card; 312*3941Svenki 313*3941Svenki /* Walk through the children */ 314*3941Svenki 315*3941Svenki err = picl_get_propval_by_name(pcih, PICL_PROP_CHILD, &nodeh, 316*3941Svenki sizeof (picl_nodehdl_t)); 317*3941Svenki 318*3941Svenki while (err == PICL_SUCCESS) { 319*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME, 320*3941Svenki class, sizeof (class)); 321*3941Svenki if (err != PICL_SUCCESS) 322*3941Svenki return (err); 323*3941Svenki 324*3941Svenki if (args) { 325*3941Svenki char *val = args; 326*3941Svenki if (strcmp(class, val) == 0) { 327*3941Svenki err = picl_get_propval_by_name(nodeh, 328*3941Svenki PICL_PROP_PEER, &nodeh, 329*3941Svenki sizeof (picl_nodehdl_t)); 330*3941Svenki continue; 331*3941Svenki } else if (strcmp(val, PICL_CLASS_PCIEX) == 0 && 332*3941Svenki strcmp(class, PICL_CLASS_PCI) == 0) { 333*3941Svenki err = picl_get_propval_by_name(nodeh, 334*3941Svenki PICL_PROP_PEER, &nodeh, 335*3941Svenki sizeof (picl_nodehdl_t)); 336*3941Svenki continue; 337*3941Svenki } else if (strcmp(val, PICL_CLASS_PCI) == 0 && 338*3941Svenki strcmp(class, PICL_CLASS_PCIEX) == 0) { 339*3941Svenki err = picl_get_propval_by_name(nodeh, 340*3941Svenki PICL_PROP_PEER, &nodeh, 341*3941Svenki sizeof (picl_nodehdl_t)); 342*3941Svenki continue; 343*3941Svenki } 344*3941Svenki } 345*3941Svenki 346*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_DEVFS_PATH, 347*3941Svenki path, sizeof (path)); 348*3941Svenki if (err != PICL_SUCCESS) 349*3941Svenki return (err); 350*3941Svenki 351*3941Svenki (void) strlcpy(pci_card.notes, path, sizeof (pci_card.notes)); 352*3941Svenki 353*3941Svenki get_bus_type(nodeh, &pci_card); 354*3941Svenki get_slot_number(nodeh, &pci_card); 355*3941Svenki 356*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_NAME, name, 357*3941Svenki sizeof (name)); 358*3941Svenki if (err == PICL_PROPNOTFOUND) 359*3941Svenki (void) strcpy(name, ""); 360*3941Svenki else if (err != PICL_SUCCESS) 361*3941Svenki return (err); 362*3941Svenki 363*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_STATUS, val, 364*3941Svenki sizeof (val)); 365*3941Svenki if (err == PICL_PROPNOTFOUND) 366*3941Svenki (void) strcpy(val, ""); 367*3941Svenki else if (err != PICL_SUCCESS) 368*3941Svenki return (err); 369*3941Svenki 370*3941Svenki /* Figure NAC name */ 371*3941Svenki if (pci_card.slot != -1) 372*3941Svenki (void) snprintf(pci_card.status, 373*3941Svenki sizeof (pci_card.status), 374*3941Svenki "%s%d", pci_card.slot_str, 375*3941Svenki pci_card.slot); 376*3941Svenki else 377*3941Svenki (void) snprintf(pci_card.status, 378*3941Svenki sizeof (pci_card.status), 379*3941Svenki "%s", pci_card.slot_str); 380*3941Svenki 381*3941Svenki /* 382*3941Svenki * Get the name of this card. If binding_name is found, 383*3941Svenki * name will be <nodename>-<binding_name>. 384*3941Svenki */ 385*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_BINDING_NAME, 386*3941Svenki binding_name, sizeof (binding_name)); 387*3941Svenki if (err == PICL_SUCCESS) { 388*3941Svenki if (strcmp(name, binding_name) != 0) { 389*3941Svenki (void) strlcat(name, "-", sizeof (name)); 390*3941Svenki (void) strlcat(name, binding_name, 391*3941Svenki sizeof (name)); 392*3941Svenki } 393*3941Svenki } else if (err == PICL_PROPNOTFOUND) { 394*3941Svenki /* 395*3941Svenki * if compatible prop is not found, name will be 396*3941Svenki * <nodename>-<compatible> 397*3941Svenki */ 398*3941Svenki err = sun4v_get_first_compatible_value(nodeh, 399*3941Svenki &compatible); 400*3941Svenki if (err == PICL_SUCCESS) { 401*3941Svenki (void) strlcat(name, "-", sizeof (name)); 402*3941Svenki (void) strlcat(name, compatible, sizeof (name)); 403*3941Svenki free(compatible); 404*3941Svenki } 405*3941Svenki } else 406*3941Svenki return (err); 407*3941Svenki 408*3941Svenki (void) strlcpy(pci_card.name, name, sizeof (pci_card.name)); 409*3941Svenki 410*3941Svenki /* Get the model of this card */ 411*3941Svenki 412*3941Svenki err = picl_get_propval_by_name(nodeh, OBP_PROP_MODEL, 413*3941Svenki model, sizeof (model)); 414*3941Svenki if (err == PICL_PROPNOTFOUND) 415*3941Svenki (void) strcpy(model, ""); 416*3941Svenki else if (err != PICL_SUCCESS) 417*3941Svenki return (err); 418*3941Svenki (void) strlcpy(pci_card.model, model, sizeof (pci_card.model)); 419*3941Svenki 420*3941Svenki /* Print NAC name */ 421*3941Svenki log_printf("%-12s", pci_card.status); 422*3941Svenki /* Print IO Type */ 423*3941Svenki log_printf("%-6s", pci_card.bus_type); 424*3941Svenki /* Printf Card Name */ 425*3941Svenki log_printf("%-46s", pci_card.name); 426*3941Svenki /* Print Card Model */ 427*3941Svenki log_printf("%-8s", pci_card.model); 428*3941Svenki log_printf("\n"); 429*3941Svenki /* Print Status */ 430*3941Svenki log_printf("%-12s", val); 431*3941Svenki /* Print IO Type */ 432*3941Svenki log_printf("%-6s", ""); 433*3941Svenki /* Print Parent Path */ 434*3941Svenki log_printf("%-46s", pci_card.notes); 435*3941Svenki log_printf("\n"); 436*3941Svenki 437*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh, 438*3941Svenki sizeof (picl_nodehdl_t)); 439*3941Svenki } 440*3941Svenki return (PICL_WALK_CONTINUE); 4411708Sstevel } 4421708Sstevel 4431708Sstevel /* 4441708Sstevel * display_pci 4451708Sstevel * Display all the PCI IO cards on this board. 4461708Sstevel */ 4471708Sstevel void 4481708Sstevel sun4v_display_pci(picl_nodehdl_t plafh) 4491708Sstevel { 450*3941Svenki char *fmt = "%-11s %-5s %-45s %-8s"; 451*3941Svenki /* Have we printed the column headings? */ 452*3941Svenki static int banner = FALSE; 453*3941Svenki 454*3941Svenki if (banner == FALSE) { 455*3941Svenki log_printf("\n"); 456*3941Svenki log_printf("============================"); 457*3941Svenki log_printf(" IO Devices "); 458*3941Svenki log_printf("============================"); 459*3941Svenki log_printf("\n"); 460*3941Svenki log_printf(fmt, "Slot +", "Bus", "Name +", "Model", 0); 461*3941Svenki log_printf("\n"); 462*3941Svenki log_printf(fmt, "Status", "Type", "Path", "", 0); 463*3941Svenki log_printf("\n"); 464*3941Svenki log_printf("---------------------------------" 465*3941Svenki "------------------------------------\n"); 466*3941Svenki banner = TRUE; 467*3941Svenki } 468*3941Svenki 469*3941Svenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_PCIEX, 470*3941Svenki PICL_CLASS_PCIEX, sun4v_pci_callback); 471*3941Svenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_PCI, 472*3941Svenki PICL_CLASS_PCI, sun4v_pci_callback); 473*3941Svenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_SUN4V, 474*3941Svenki PICL_CLASS_SUN4V, sun4v_pci_callback); 475*3941Svenki } 476*3941Svenki 477*3941Svenki /* 478*3941Svenki * return the first compatible value 479*3941Svenki */ 480*3941Svenki static int 481*3941Svenki sun4v_get_first_compatible_value(picl_nodehdl_t nodeh, char **outbuf) 482*3941Svenki { 483*3941Svenki picl_errno_t err; 484*3941Svenki picl_prophdl_t proph; 485*3941Svenki picl_propinfo_t pinfo; 486*3941Svenki picl_prophdl_t tblh; 487*3941Svenki picl_prophdl_t rowproph; 488*3941Svenki char *pval; 489*3941Svenki 490*3941Svenki err = picl_get_propinfo_by_name(nodeh, OBP_PROP_COMPATIBLE, 491*3941Svenki &pinfo, &proph); 492*3941Svenki if (err != PICL_SUCCESS) 493*3941Svenki return (err); 494*3941Svenki 495*3941Svenki if (pinfo.type == PICL_PTYPE_CHARSTRING) { 496*3941Svenki pval = malloc(pinfo.size); 497*3941Svenki if (pval == NULL) 498*3941Svenki return (PICL_FAILURE); 499*3941Svenki err = picl_get_propval(proph, pval, pinfo.size); 500*3941Svenki if (err != PICL_SUCCESS) { 501*3941Svenki free(pval); 502*3941Svenki return (err); 503*3941Svenki } 504*3941Svenki *outbuf = pval; 505*3941Svenki return (PICL_SUCCESS); 506*3941Svenki } 507*3941Svenki 508*3941Svenki if (pinfo.type != PICL_PTYPE_TABLE) 509*3941Svenki return (PICL_FAILURE); 510*3941Svenki 511*3941Svenki /* get first string from table */ 512*3941Svenki err = picl_get_propval(proph, &tblh, pinfo.size); 513*3941Svenki if (err != PICL_SUCCESS) 514*3941Svenki return (err); 515*3941Svenki 516*3941Svenki err = picl_get_next_by_row(tblh, &rowproph); 517*3941Svenki if (err != PICL_SUCCESS) 518*3941Svenki return (err); 519*3941Svenki 520*3941Svenki err = picl_get_propinfo(rowproph, &pinfo); 521*3941Svenki if (err != PICL_SUCCESS) 522*3941Svenki return (err); 523*3941Svenki 524*3941Svenki pval = malloc(pinfo.size); 525*3941Svenki if (pval == NULL) 526*3941Svenki return (PICL_FAILURE); 527*3941Svenki 528*3941Svenki err = picl_get_propval(rowproph, pval, pinfo.size); 529*3941Svenki if (err != PICL_SUCCESS) { 530*3941Svenki free(pval); 531*3941Svenki return (err); 532*3941Svenki } 533*3941Svenki 534*3941Svenki *outbuf = pval; 535*3941Svenki return (PICL_SUCCESS); 5361708Sstevel } 5371708Sstevel 538*3941Svenki /* 539*3941Svenki * print size of a memory segment 540*3941Svenki */ 541*3941Svenki static void 542*3941Svenki print_memory_segment_size(uint64_t size) 543*3941Svenki { 544*3941Svenki uint64_t kbyte = 1024; 545*3941Svenki uint64_t mbyte = kbyte * kbyte; 546*3941Svenki uint64_t gbyte = kbyte * mbyte; 547*3941Svenki char buf[MEMORY_SIZE_FIELD]; 548*3941Svenki 549*3941Svenki if (size >= gbyte) { 550*3941Svenki if (size % gbyte == 0) 551*3941Svenki (void) snprintf(buf, sizeof (buf), "%d GB", 552*3941Svenki (int)(size / gbyte)); 553*3941Svenki else 554*3941Svenki (void) snprintf(buf, sizeof (buf), "%.2f GB", 555*3941Svenki (float)size / gbyte); 556*3941Svenki } else if (size >= mbyte) { 557*3941Svenki if (size % mbyte == 0) 558*3941Svenki (void) snprintf(buf, sizeof (buf), "%d MB", 559*3941Svenki (int)(size / mbyte)); 560*3941Svenki else 561*3941Svenki (void) snprintf(buf, sizeof (buf), "%.2f MB", 562*3941Svenki (float)size / mbyte); 563*3941Svenki } else { 564*3941Svenki if (size % kbyte == 0) 565*3941Svenki (void) snprintf(buf, sizeof (buf), "%d KB", 566*3941Svenki (int)(size / kbyte)); 567*3941Svenki else 568*3941Svenki (void) snprintf(buf, sizeof (buf), "%.2f KB", 569*3941Svenki (float)size / kbyte); 570*3941Svenki } 571*3941Svenki log_printf("%-7s ", buf); 572*3941Svenki } 573*3941Svenki 574*3941Svenki /* 575*3941Svenki * print bank IDs of a memory segment 576*3941Svenki */ 577*3941Svenki static void 578*3941Svenki print_memory_segment_contain(picl_nodehdl_t nodeh) 5791708Sstevel { 580*3941Svenki char val[PICL_PROPNAMELEN_MAX]; 581*3941Svenki picl_errno_t err = picl_get_propval_by_name(nodeh, 582*3941Svenki PICL_PROP_NAC, val, sizeof (val)); 583*3941Svenki if (err != PICL_SUCCESS) 584*3941Svenki return; 585*3941Svenki log_printf("%-30s", val); 586*3941Svenki while ((err = picl_get_propval_by_name(nodeh, 587*3941Svenki PICL_PROP_PEER, &nodeh, 588*3941Svenki sizeof (nodeh))) == PICL_SUCCESS) { 589*3941Svenki err = picl_get_propval_by_name(nodeh, 590*3941Svenki PICL_PROP_NAC, val, sizeof (val)); 591*3941Svenki if (err == PICL_SUCCESS) { 592*3941Svenki log_printf("\n"); 593*3941Svenki log_printf("%-30s", val); 594*3941Svenki } 595*3941Svenki } 596*3941Svenki } 597*3941Svenki 598*3941Svenki /* 599*3941Svenki * Search node where _class=="memory-segment" 600*3941Svenki * print "Base Address", "Size", etc 601*3941Svenki */ 602*3941Svenki /*ARGSUSED*/ 603*3941Svenki static int 604*3941Svenki sun4v_memory_conf_callback(picl_nodehdl_t nodeh, void *args) 605*3941Svenki { 606*3941Svenki uint64_t base; 607*3941Svenki uint64_t size; 608*3941Svenki uint64_t ifactor; 609*3941Svenki picl_errno_t err = PICL_SUCCESS; 610*3941Svenki 611*3941Svenki if (class_node_found == 0) { 612*3941Svenki class_node_found = 1; 613*3941Svenki return (PICL_WALK_TERMINATE); 614*3941Svenki } 615*3941Svenki while (err == PICL_SUCCESS) { 616*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_BASEADDRESS, 617*3941Svenki &base, sizeof (base)); 618*3941Svenki if (err != PICL_SUCCESS) 619*3941Svenki break; 620*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_SIZE, 621*3941Svenki &size, sizeof (size)); 622*3941Svenki if (err != PICL_SUCCESS) 623*3941Svenki break; 624*3941Svenki err = picl_get_propval_by_name(nodeh, 625*3941Svenki PICL_PROP_INTERLEAVE_FACTOR, &ifactor, 626*3941Svenki sizeof (ifactor)); 627*3941Svenki if (err != PICL_SUCCESS) 628*3941Svenki break; 629*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_CHILD, 630*3941Svenki &nodeh, sizeof (nodeh)); 631*3941Svenki if (err != PICL_SUCCESS) 632*3941Svenki break; 633*3941Svenki log_printf("%-13llx", base); 634*3941Svenki print_memory_segment_size(size); 635*3941Svenki log_printf("%-18d", ifactor); 636*3941Svenki print_memory_segment_contain(nodeh); 637*3941Svenki log_printf("\n"); 638*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh, 639*3941Svenki sizeof (picl_nodehdl_t)); 640*3941Svenki } 641*3941Svenki 642*3941Svenki return (PICL_WALK_CONTINUE); 643*3941Svenki } 644*3941Svenki 645*3941Svenki /*ARGSUSED*/ 646*3941Svenki void 647*3941Svenki sun4v_display_memory_conf(picl_nodehdl_t plafh) 648*3941Svenki { 649*3941Svenki char *fmt = "%-12s %-7s %-9s %-20s"; 650*3941Svenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY_SEGMENT, 651*3941Svenki NULL, sun4v_memory_conf_callback); 652*3941Svenki if (class_node_found == 0) 653*3941Svenki return; 654*3941Svenki log_printf("\n"); 655*3941Svenki log_printf("============================"); 656*3941Svenki log_printf(" Memory Configuration "); 657*3941Svenki log_printf("============================"); 658*3941Svenki log_printf("\n"); 659*3941Svenki log_printf("Segment Table:\n"); 660*3941Svenki log_printf("-----------------------------------------------\n"); 661*3941Svenki log_printf(fmt, "Base Address", "Size", "Interleave Factor", 662*3941Svenki "Contains", 0); 663*3941Svenki log_printf("\n"); 664*3941Svenki log_printf("-----------------------------------------------\n"); 665*3941Svenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY_SEGMENT, 666*3941Svenki NULL, sun4v_memory_conf_callback); 6671708Sstevel } 6681708Sstevel 6691708Sstevel void 6701708Sstevel sun4v_display_cpu_devices(picl_nodehdl_t plafh) 6711708Sstevel { 672*3941Svenki char *fmt = "%-12s %-5s %-8s %-19s %-5s"; 6731708Sstevel 6741708Sstevel /* 6751708Sstevel * Display the table header for CPUs . Then display the CPU 6761708Sstevel * frequency, cache size, and processor revision of all cpus. 6771708Sstevel */ 6781708Sstevel log_printf(dgettext(TEXT_DOMAIN, 6791708Sstevel "\n" 6801708Sstevel "=========================" 6811708Sstevel " CPUs " 6821708Sstevel "===============================================" 6831708Sstevel "\n" 6841708Sstevel "\n")); 6851708Sstevel log_printf(fmt, "", "", "", "CPU", "CPU", 0); 6861708Sstevel log_printf("\n"); 6871708Sstevel log_printf(fmt, "Location", "CPU", "Freq", 688*3941Svenki "Implementation", "Mask", 0); 6891708Sstevel log_printf("\n"); 6901708Sstevel log_printf(fmt, "------------", "-----", "--------", 691*3941Svenki "-------------------", "-----", 0); 6921708Sstevel log_printf("\n"); 6931708Sstevel 6941708Sstevel (void) picl_walk_tree_by_class(plafh, "cpu", "cpu", sun4v_display_cpus); 6951708Sstevel } 6961708Sstevel 6971708Sstevel /* 6981708Sstevel * Display the CPUs present on this board. 6991708Sstevel */ 7001708Sstevel /*ARGSUSED*/ 7011708Sstevel int 7021708Sstevel sun4v_display_cpus(picl_nodehdl_t cpuh, void* args) 7031708Sstevel { 7041708Sstevel int status; 705*3941Svenki picl_prophdl_t proph; 706*3941Svenki picl_prophdl_t tblh; 707*3941Svenki picl_prophdl_t rowproph; 7081708Sstevel picl_propinfo_t propinfo; 709*3941Svenki int *int_value; 710*3941Svenki uint64_t cpuid, mask_no; 711*3941Svenki char *comp_value; 712*3941Svenki char *no_prop_value = " "; 713*3941Svenki char freq_str[MAXSTRLEN]; 714*3941Svenki char fru_name[MAXSTRLEN]; 7151708Sstevel 7161708Sstevel /* 7171708Sstevel * Get cpuid property and print it and the NAC name 7181708Sstevel */ 7191708Sstevel status = picl_get_propinfo_by_name(cpuh, "cpuid", &propinfo, &proph); 7201708Sstevel if (status == PICL_SUCCESS) { 7211708Sstevel status = picl_get_propval(proph, &cpuid, sizeof (cpuid)); 7221708Sstevel if (status != PICL_SUCCESS) { 723*3941Svenki log_printf("%-13s", no_prop_value); 724*3941Svenki log_printf("%-6s", no_prop_value); 7251708Sstevel } else { 7261708Sstevel (void) snprintf(fru_name, sizeof (fru_name), "%s%d", 7271708Sstevel CPU_STRAND_NAC, (int)cpuid); 728*3941Svenki log_printf("%-13s", fru_name); 729*3941Svenki log_printf("%-6d", (int)cpuid); 7301708Sstevel } 7311708Sstevel } else { 732*3941Svenki log_printf("%-13s", no_prop_value); 733*3941Svenki log_printf("%-6s", no_prop_value); 7341708Sstevel } 7351708Sstevel 7361708Sstevel clock_freq: 7371708Sstevel status = picl_get_propinfo_by_name(cpuh, "clock-frequency", &propinfo, 738*3941Svenki &proph); 7391708Sstevel if (status == PICL_SUCCESS) { 7401708Sstevel int_value = malloc(propinfo.size); 7411708Sstevel if (int_value == NULL) { 742*3941Svenki log_printf("%-9s", no_prop_value); 7431708Sstevel goto compatible; 7441708Sstevel } 7451708Sstevel status = picl_get_propval(proph, int_value, propinfo.size); 7461708Sstevel if (status != PICL_SUCCESS) { 747*3941Svenki log_printf("%-9s", no_prop_value); 7481708Sstevel } else { 7491708Sstevel /* Running frequency */ 7501708Sstevel (void) snprintf(freq_str, sizeof (freq_str), "%d MHz", 7511708Sstevel CLK_FREQ_TO_MHZ(*int_value)); 752*3941Svenki log_printf("%-9s", freq_str); 7531708Sstevel } 7541708Sstevel free(int_value); 7551708Sstevel } else 756*3941Svenki log_printf("%-9s", no_prop_value); 7571708Sstevel 7581708Sstevel compatible: 7591708Sstevel status = picl_get_propinfo_by_name(cpuh, "compatible", &propinfo, 760*3941Svenki &proph); 7611708Sstevel if (status == PICL_SUCCESS) { 7621708Sstevel if (propinfo.type == PICL_PTYPE_CHARSTRING) { 7631708Sstevel /* 7641708Sstevel * Compatible Property only has 1 value 7651708Sstevel */ 7661708Sstevel comp_value = malloc(propinfo.size); 7671708Sstevel if (comp_value == NULL) { 768*3941Svenki log_printf("%-20s", no_prop_value, 0); 7691708Sstevel goto mask; 7701708Sstevel } 7711708Sstevel status = picl_get_propval(proph, comp_value, 772*3941Svenki propinfo.size); 773*3941Svenki if (status != PICL_SUCCESS) 774*3941Svenki log_printf("%-20s", no_prop_value, 0); 775*3941Svenki else 776*3941Svenki log_printf("%-20s", comp_value, 0); 777*3941Svenki free(comp_value); 7781708Sstevel } else if (propinfo.type == PICL_PTYPE_TABLE) { 7791708Sstevel /* 7801708Sstevel * Compatible Property has multiple values 7811708Sstevel */ 7821708Sstevel status = picl_get_propval(proph, &tblh, propinfo.size); 7831708Sstevel if (status != PICL_SUCCESS) { 784*3941Svenki log_printf("%-20s", no_prop_value, 0); 7851708Sstevel goto mask; 7861708Sstevel } 7871708Sstevel status = picl_get_next_by_row(tblh, &rowproph); 7881708Sstevel if (status != PICL_SUCCESS) { 789*3941Svenki log_printf("%-20s", no_prop_value, 0); 7901708Sstevel goto mask; 7911708Sstevel } 7921708Sstevel 7931708Sstevel status = picl_get_propinfo(rowproph, &propinfo); 7941708Sstevel if (status != PICL_SUCCESS) { 795*3941Svenki log_printf("%-20s", no_prop_value, 0); 7961708Sstevel goto mask; 7971708Sstevel } 7981708Sstevel 7991708Sstevel comp_value = malloc(propinfo.size); 8001708Sstevel if (comp_value == NULL) { 801*3941Svenki log_printf("%-20s", no_prop_value, 0); 8021708Sstevel goto mask; 8031708Sstevel } 8041708Sstevel status = picl_get_propval(rowproph, comp_value, 805*3941Svenki propinfo.size); 806*3941Svenki if (status != PICL_SUCCESS) 807*3941Svenki log_printf("%-20s", no_prop_value, 0); 808*3941Svenki else 809*3941Svenki log_printf("%-20s", comp_value, 0); 8101708Sstevel free(comp_value); 8111708Sstevel } 8121708Sstevel } else 813*3941Svenki log_printf("%-20s", no_prop_value, 0); 8141708Sstevel 8151708Sstevel mask: 8161708Sstevel status = picl_get_propinfo_by_name(cpuh, "mask#", &propinfo, &proph); 8171708Sstevel if (status == PICL_SUCCESS) { 8181708Sstevel status = picl_get_propval(proph, &mask_no, sizeof (mask_no)); 8191708Sstevel if (status != PICL_SUCCESS) { 820*3941Svenki log_printf("%-9s", no_prop_value); 8211708Sstevel } else { 8221708Sstevel log_printf(dgettext(TEXT_DOMAIN, " %2d.%d"), 823*3941Svenki (mask_no>> 4) & 0xf, mask_no & 0xf); 8241708Sstevel } 8251708Sstevel } else 826*3941Svenki log_printf("%-9s", no_prop_value); 8271708Sstevel 8281708Sstevel done: 8291708Sstevel log_printf("\n"); 8301708Sstevel return (PICL_WALK_CONTINUE); 8311708Sstevel } 8321708Sstevel 8331708Sstevel void 8341708Sstevel sun4v_display_diaginfo(int flag, Prom_node *root, picl_nodehdl_t plafh) 8351708Sstevel { 8361708Sstevel #ifdef lint 8371708Sstevel flag = flag; 8381708Sstevel root = root; 8391708Sstevel plafh = plafh; 8401708Sstevel #endif 8411708Sstevel /* 8421708Sstevel * This function is intentionally empty 8431708Sstevel */ 8441708Sstevel } 8451708Sstevel 8461708Sstevel void 8471708Sstevel display_boardnum(int num) 8481708Sstevel { 8491708Sstevel log_printf("%2d ", num, 0); 8501708Sstevel } 851*3941Svenki 852*3941Svenki static void 853*3941Svenki sun4v_disp_env_status() 854*3941Svenki { 855*3941Svenki if (phyplatformh == 0) 856*3941Svenki return; 857*3941Svenki log_printf("\n"); 858*3941Svenki log_printf("============================"); 859*3941Svenki log_printf(" Environmental Status "); 860*3941Svenki log_printf("============================"); 861*3941Svenki log_printf("\n"); 862*3941Svenki 863*3941Svenki class_node_found = 0; 864*3941Svenki all_status_ok = 1; 865*3941Svenki sun4v_env_print_fan_sensors(); 866*3941Svenki 867*3941Svenki class_node_found = 0; 868*3941Svenki all_status_ok = 1; 869*3941Svenki sun4v_env_print_fan_indicators(); 870*3941Svenki 871*3941Svenki class_node_found = 0; 872*3941Svenki all_status_ok = 1; 873*3941Svenki sun4v_env_print_temp_sensors(); 874*3941Svenki 875*3941Svenki class_node_found = 0; 876*3941Svenki all_status_ok = 1; 877*3941Svenki sun4v_env_print_temp_indicators(); 878*3941Svenki 879*3941Svenki class_node_found = 0; 880*3941Svenki all_status_ok = 1; 881*3941Svenki sun4v_env_print_current_sensors(); 882*3941Svenki 883*3941Svenki class_node_found = 0; 884*3941Svenki all_status_ok = 1; 885*3941Svenki sun4v_env_print_current_indicators(); 886*3941Svenki 887*3941Svenki class_node_found = 0; 888*3941Svenki all_status_ok = 1; 889*3941Svenki sun4v_env_print_voltage_sensors(); 890*3941Svenki 891*3941Svenki class_node_found = 0; 892*3941Svenki all_status_ok = 1; 893*3941Svenki sun4v_env_print_voltage_indicators(); 894*3941Svenki 895*3941Svenki class_node_found = 0; 896*3941Svenki sun4v_env_print_LEDs(); 897*3941Svenki 898*3941Svenki class_node_found = 0; 899*3941Svenki all_status_ok = 1; 900*3941Svenki sun4v_print_fru_status(); 901*3941Svenki 902*3941Svenki class_node_found = 0; 903*3941Svenki sun4v_print_fw_rev(); 904*3941Svenki 905*3941Svenki sun4v_print_chassis_serial_no(); 906*3941Svenki } 907*3941Svenki 908*3941Svenki /*ARGSUSED*/ 909*3941Svenki static int 910*3941Svenki sun4v_env_print_sensor_callback(picl_nodehdl_t nodeh, void *args) 911*3941Svenki { 912*3941Svenki char val[PICL_PROPNAMELEN_MAX]; 913*3941Svenki picl_nodehdl_t parenth; 914*3941Svenki char *names[PARENT_NAMES]; 915*3941Svenki char *loc; 916*3941Svenki int i; 917*3941Svenki char *prop; 918*3941Svenki picl_errno_t err; 919*3941Svenki int32_t lo_warning, lo_shutdown; 920*3941Svenki int32_t hi_warning, hi_shutdown; 921*3941Svenki int32_t current_val; 922*3941Svenki 923*3941Svenki if (class_node_found == 0) { 924*3941Svenki class_node_found = 1; 925*3941Svenki return (PICL_WALK_TERMINATE); 926*3941Svenki } 927*3941Svenki 928*3941Svenki if (syserrlog == 0) { 929*3941Svenki err = picl_get_propval_by_name(nodeh, 930*3941Svenki PICL_PROP_OPERATIONAL_STATUS, val, 931*3941Svenki sizeof (val)); 932*3941Svenki if (err == PICL_SUCCESS) { 933*3941Svenki if (strcmp(val, "disabled") == 0) { 934*3941Svenki if (all_status_ok) { 935*3941Svenki all_status_ok = 0; 936*3941Svenki return (PICL_WALK_TERMINATE); 937*3941Svenki } 938*3941Svenki } else 939*3941Svenki return (PICL_WALK_CONTINUE); 940*3941Svenki } else { 941*3941Svenki all_status_ok = 0; 942*3941Svenki return (PICL_WALK_TERMINATE); 943*3941Svenki } 944*3941Svenki } 945*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth, 946*3941Svenki sizeof (parenth)); 947*3941Svenki if (err != PICL_SUCCESS) { 948*3941Svenki log_printf("\n"); 949*3941Svenki return (PICL_WALK_CONTINUE); 950*3941Svenki } 951*3941Svenki if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) == NULL) 952*3941Svenki return (PICL_WALK_TERMINATE); 953*3941Svenki for (i = 0; i < PARENT_NAMES; i++) 954*3941Svenki if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) == NULL) { 955*3941Svenki while (--i > -1) 956*3941Svenki free(names[i]); 957*3941Svenki free(loc); 958*3941Svenki return (PICL_WALK_TERMINATE); 959*3941Svenki } 960*3941Svenki i = 0; 961*3941Svenki while (err == PICL_SUCCESS) { 962*3941Svenki if (parenth == chassish || parenth == phyplatformh) 963*3941Svenki break; 964*3941Svenki err = picl_get_propval_by_name(parenth, PICL_PROP_NAME, 965*3941Svenki names[i++], PICL_PROPNAMELEN_MAX); 966*3941Svenki if (err != PICL_SUCCESS) { 967*3941Svenki i--; 968*3941Svenki break; 969*3941Svenki } 970*3941Svenki if (i == PARENT_NAMES) 971*3941Svenki break; 972*3941Svenki err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT, 973*3941Svenki &parenth, sizeof (parenth)); 974*3941Svenki } 975*3941Svenki loc[0] = '\0'; 976*3941Svenki if (--i > -1) 977*3941Svenki loc = strncat(loc, names[i], strlen(names[i])); 978*3941Svenki while (--i > -1) { 979*3941Svenki loc = strncat(loc, "/", 1); 980*3941Svenki loc = strncat(loc, names[i], strlen(names[i])); 981*3941Svenki } 982*3941Svenki log_printf("%-12s", loc); 983*3941Svenki for (i = 0; i < PARENT_NAMES; i++) 984*3941Svenki free(names[i]); 985*3941Svenki free(loc); 986*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, val, 987*3941Svenki sizeof (val)); 988*3941Svenki if (err == PICL_SUCCESS) 989*3941Svenki log_printf("%-15s", val); 990*3941Svenki 991*3941Svenki prop = (char *)args; 992*3941Svenki if (!prop) { 993*3941Svenki log_printf("\n"); 994*3941Svenki return (PICL_WALK_CONTINUE); 995*3941Svenki } 996*3941Svenki if (picl_get_propval_by_name(nodeh, prop, ¤t_val, 997*3941Svenki sizeof (current_val)) != PICL_SUCCESS) { 998*3941Svenki log_printf("\n"); 999*3941Svenki return (PICL_WALK_CONTINUE); 1000*3941Svenki } 1001*3941Svenki if (picl_get_propval_by_name(nodeh, PICL_PROP_LOW_WARNING, 1002*3941Svenki &lo_warning, sizeof (lo_warning)) != PICL_SUCCESS) 1003*3941Svenki lo_warning = INVALID_THRESHOLD; 1004*3941Svenki if (picl_get_propval_by_name(nodeh, PICL_PROP_LOW_SHUTDOWN, 1005*3941Svenki &lo_shutdown, sizeof (lo_shutdown)) != PICL_SUCCESS) 1006*3941Svenki lo_shutdown = INVALID_THRESHOLD; 1007*3941Svenki if (picl_get_propval_by_name(nodeh, PICL_PROP_HIGH_WARNING, 1008*3941Svenki &hi_warning, sizeof (hi_warning)) != PICL_SUCCESS) 1009*3941Svenki hi_warning = INVALID_THRESHOLD; 1010*3941Svenki if (picl_get_propval_by_name(nodeh, PICL_PROP_HIGH_SHUTDOWN, 1011*3941Svenki &hi_shutdown, sizeof (hi_shutdown)) != PICL_SUCCESS) 1012*3941Svenki hi_shutdown = INVALID_THRESHOLD; 1013*3941Svenki 1014*3941Svenki if ((lo_shutdown != INVALID_THRESHOLD && 1015*3941Svenki current_val <= lo_shutdown) || 1016*3941Svenki (hi_shutdown != INVALID_THRESHOLD && 1017*3941Svenki current_val >= hi_shutdown)) { 1018*3941Svenki log_printf("%-s", "failed ("); 1019*3941Svenki log_printf("%-d", current_val); 1020*3941Svenki log_printf("%-s", ")"); 1021*3941Svenki } else if ((lo_warning != INVALID_THRESHOLD && 1022*3941Svenki current_val <= lo_warning) || 1023*3941Svenki (hi_warning != INVALID_THRESHOLD && 1024*3941Svenki current_val >= hi_warning)) { 1025*3941Svenki log_printf("%-s", "warning ("); 1026*3941Svenki log_printf("%-d", current_val); 1027*3941Svenki log_printf("%-s", ")"); 1028*3941Svenki } else 1029*3941Svenki log_printf("%-s", "ok"); 1030*3941Svenki 1031*3941Svenki log_printf("\n"); 1032*3941Svenki return (PICL_WALK_CONTINUE); 1033*3941Svenki } 1034*3941Svenki 1035*3941Svenki /*ARGSUSED*/ 1036*3941Svenki static int 1037*3941Svenki sun4v_env_print_indicator_callback(picl_nodehdl_t nodeh, void *args) 1038*3941Svenki { 1039*3941Svenki char val[PICL_PROPNAMELEN_MAX]; 1040*3941Svenki char status[PICL_PROPNAMELEN_MAX]; 1041*3941Svenki picl_nodehdl_t parenth; 1042*3941Svenki char *names[PARENT_NAMES]; 1043*3941Svenki char *loc; 1044*3941Svenki int i = 0; 1045*3941Svenki char *prop = (char *)args; 1046*3941Svenki picl_errno_t err = PICL_SUCCESS; 1047*3941Svenki 1048*3941Svenki if (class_node_found == 0) { 1049*3941Svenki class_node_found = 1; 1050*3941Svenki return (PICL_WALK_TERMINATE); 1051*3941Svenki } 1052*3941Svenki if (syserrlog == 0) { 1053*3941Svenki err = picl_get_propval_by_name(nodeh, 1054*3941Svenki PICL_PROP_OPERATIONAL_STATUS, status, 1055*3941Svenki sizeof (status)); 1056*3941Svenki if (err == PICL_SUCCESS) { 1057*3941Svenki if (strcmp(status, "disabled") == 0) { 1058*3941Svenki if (all_status_ok) { 1059*3941Svenki all_status_ok = 0; 1060*3941Svenki return (PICL_WALK_TERMINATE); 1061*3941Svenki } 1062*3941Svenki } else 1063*3941Svenki return (PICL_WALK_CONTINUE); 1064*3941Svenki } else { 1065*3941Svenki all_status_ok = 0; 1066*3941Svenki return (PICL_WALK_TERMINATE); 1067*3941Svenki } 1068*3941Svenki } 1069*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth, 1070*3941Svenki sizeof (parenth)); 1071*3941Svenki if (err != PICL_SUCCESS) { 1072*3941Svenki log_printf("\n"); 1073*3941Svenki return (PICL_WALK_CONTINUE); 1074*3941Svenki } 1075*3941Svenki if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) == NULL) 1076*3941Svenki return (PICL_WALK_TERMINATE); 1077*3941Svenki for (i = 0; i < PARENT_NAMES; i++) 1078*3941Svenki if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) == NULL) { 1079*3941Svenki while (--i > -1) 1080*3941Svenki free(names[i]); 1081*3941Svenki free(loc); 1082*3941Svenki return (PICL_WALK_TERMINATE); 1083*3941Svenki } 1084*3941Svenki i = 0; 1085*3941Svenki while (err == PICL_SUCCESS) { 1086*3941Svenki if (parenth == chassish || parenth == phyplatformh) 1087*3941Svenki break; 1088*3941Svenki err = picl_get_propval_by_name(parenth, PICL_PROP_NAME, 1089*3941Svenki names[i++], PICL_PROPNAMELEN_MAX); 1090*3941Svenki if (err != PICL_SUCCESS) { 1091*3941Svenki i--; 1092*3941Svenki break; 1093*3941Svenki } 1094*3941Svenki if (i == PARENT_NAMES) 1095*3941Svenki break; 1096*3941Svenki err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT, 1097*3941Svenki &parenth, sizeof (parenth)); 1098*3941Svenki } 1099*3941Svenki loc[0] = '\0'; 1100*3941Svenki if (--i > -1) 1101*3941Svenki loc = strncat(loc, names[i], strlen(names[i])); 1102*3941Svenki while (--i > -1) { 1103*3941Svenki loc = strncat(loc, "/", 1); 1104*3941Svenki loc = strncat(loc, names[i], strlen(names[i])); 1105*3941Svenki } 1106*3941Svenki log_printf("%-12s", loc); 1107*3941Svenki for (i = 0; i < PARENT_NAMES; i++) 1108*3941Svenki free(names[i]); 1109*3941Svenki free(loc); 1110*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, val, 1111*3941Svenki sizeof (val)); 1112*3941Svenki if (err == PICL_SUCCESS) 1113*3941Svenki log_printf("%-15s", val); 1114*3941Svenki if (syserrlog == 0) { 1115*3941Svenki log_printf("%-8s", status); 1116*3941Svenki return (PICL_WALK_CONTINUE); 1117*3941Svenki } 1118*3941Svenki err = picl_get_propval_by_name(nodeh, prop, val, 1119*3941Svenki sizeof (val)); 1120*3941Svenki if (err == PICL_SUCCESS) 1121*3941Svenki log_printf("%-8s", val); 1122*3941Svenki log_printf("\n"); 1123*3941Svenki return (PICL_WALK_CONTINUE); 1124*3941Svenki } 1125*3941Svenki 1126*3941Svenki static void 1127*3941Svenki sun4v_env_print_fan_sensors() 1128*3941Svenki { 1129*3941Svenki char *fmt = "%-11s %-14s %-10s\n"; 1130*3941Svenki /* 1131*3941Svenki * If there isn't any fan sensor node, return now. 1132*3941Svenki */ 1133*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1134*3941Svenki PICL_CLASS_RPM_SENSOR, (void *)PICL_CLASS_RPM_SENSOR, 1135*3941Svenki sun4v_env_print_sensor_callback); 1136*3941Svenki if (!class_node_found) 1137*3941Svenki return; 1138*3941Svenki log_printf("Fan sensors:\n"); 1139*3941Svenki if (syserrlog == 0) { 1140*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1141*3941Svenki PICL_CLASS_RPM_SENSOR, 1142*3941Svenki NULL, sun4v_env_print_sensor_callback); 1143*3941Svenki if (all_status_ok) { 1144*3941Svenki log_printf("All fan sensors are OK.\n"); 1145*3941Svenki return; 1146*3941Svenki } 1147*3941Svenki } 1148*3941Svenki log_printf("---------------------------------\n"); 1149*3941Svenki log_printf(fmt, "Location", "Sensor", "Status", 0); 1150*3941Svenki log_printf("---------------------------------\n"); 1151*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_RPM_SENSOR, 1152*3941Svenki PICL_PROP_SPEED, sun4v_env_print_sensor_callback); 1153*3941Svenki } 1154*3941Svenki 1155*3941Svenki static void 1156*3941Svenki sun4v_env_print_fan_indicators() 1157*3941Svenki { 1158*3941Svenki char *fmt = "%-11s %-14s %-10s\n"; 1159*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1160*3941Svenki PICL_CLASS_RPM_INDICATOR, (void *)PICL_CLASS_RPM_INDICATOR, 1161*3941Svenki sun4v_env_print_indicator_callback); 1162*3941Svenki if (!class_node_found) 1163*3941Svenki return; 1164*3941Svenki log_printf("\nFan indicators:\n"); 1165*3941Svenki if (syserrlog == 0) { 1166*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1167*3941Svenki PICL_CLASS_RPM_INDICATOR, 1168*3941Svenki NULL, sun4v_env_print_indicator_callback); 1169*3941Svenki if (all_status_ok) { 1170*3941Svenki log_printf("All fan indicators are OK.\n"); 1171*3941Svenki return; 1172*3941Svenki } 1173*3941Svenki } 1174*3941Svenki log_printf("------------------------------------\n"); 1175*3941Svenki log_printf(fmt, "Location", "Sensor", "Condition", 0); 1176*3941Svenki log_printf("------------------------------------\n"); 1177*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_RPM_INDICATOR, 1178*3941Svenki PICL_CLASS_RPM_INDICATOR, sun4v_env_print_indicator_callback); 1179*3941Svenki } 1180*3941Svenki 1181*3941Svenki static void 1182*3941Svenki sun4v_env_print_temp_sensors() 1183*3941Svenki { 1184*3941Svenki char *fmt = "%-11s %-14s %-10s\n"; 1185*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1186*3941Svenki PICL_CLASS_TEMPERATURE_SENSOR, 1187*3941Svenki (void *)PICL_PROP_TEMPERATURE, 1188*3941Svenki sun4v_env_print_sensor_callback); 1189*3941Svenki if (!class_node_found) 1190*3941Svenki return; 1191*3941Svenki 1192*3941Svenki log_printf("\nTemperature sensors:\n"); 1193*3941Svenki if (syserrlog == 0) { 1194*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1195*3941Svenki PICL_CLASS_TEMPERATURE_SENSOR, 1196*3941Svenki NULL, sun4v_env_print_sensor_callback); 1197*3941Svenki if (all_status_ok) { 1198*3941Svenki log_printf("All temperature sensors are OK.\n"); 1199*3941Svenki return; 1200*3941Svenki } 1201*3941Svenki } 1202*3941Svenki log_printf("---------------------------------\n"); 1203*3941Svenki log_printf(fmt, "Location", "Sensor", "Status", 0); 1204*3941Svenki log_printf("---------------------------------\n"); 1205*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1206*3941Svenki PICL_CLASS_TEMPERATURE_SENSOR, 1207*3941Svenki (void *)PICL_PROP_TEMPERATURE, sun4v_env_print_sensor_callback); 1208*3941Svenki } 1209*3941Svenki 1210*3941Svenki static void 1211*3941Svenki sun4v_env_print_temp_indicators() 1212*3941Svenki { 1213*3941Svenki char *fmt = "%-11s %-14s %-8s\n"; 1214*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1215*3941Svenki PICL_CLASS_TEMPERATURE_INDICATOR, (void *)PICL_PROP_CONDITION, 1216*3941Svenki sun4v_env_print_indicator_callback); 1217*3941Svenki if (!class_node_found) 1218*3941Svenki return; 1219*3941Svenki log_printf("\nTemperature indicators:\n"); 1220*3941Svenki if (syserrlog == 0) { 1221*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1222*3941Svenki PICL_CLASS_TEMPERATURE_INDICATOR, NULL, 1223*3941Svenki sun4v_env_print_indicator_callback); 1224*3941Svenki if (all_status_ok) { 1225*3941Svenki log_printf("All temperature indicators are OK.\n"); 1226*3941Svenki return; 1227*3941Svenki } 1228*3941Svenki } 1229*3941Svenki log_printf("------------------------------\n"); 1230*3941Svenki log_printf(fmt, "Location", "Indicator", "Condition", 0); 1231*3941Svenki log_printf("------------------------------\n"); 1232*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1233*3941Svenki PICL_CLASS_TEMPERATURE_INDICATOR, 1234*3941Svenki (void *)PICL_PROP_CONDITION, 1235*3941Svenki sun4v_env_print_indicator_callback); 1236*3941Svenki } 1237*3941Svenki 1238*3941Svenki static void 1239*3941Svenki sun4v_env_print_current_sensors() 1240*3941Svenki { 1241*3941Svenki char *fmt = "%-11s %-14s %-10s\n"; 1242*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_CURRENT_SENSOR, 1243*3941Svenki (void *)PICL_PROP_CURRENT, sun4v_env_print_sensor_callback); 1244*3941Svenki if (!class_node_found) 1245*3941Svenki return; 1246*3941Svenki log_printf("\nCurrent sensors:\n"); 1247*3941Svenki if (syserrlog == 0) { 1248*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1249*3941Svenki PICL_CLASS_CURRENT_SENSOR, 1250*3941Svenki NULL, sun4v_env_print_sensor_callback); 1251*3941Svenki if (all_status_ok) { 1252*3941Svenki log_printf("All current sensors are OK.\n"); 1253*3941Svenki return; 1254*3941Svenki } 1255*3941Svenki } 1256*3941Svenki log_printf("---------------------------------\n"); 1257*3941Svenki log_printf(fmt, "Location", "Sensor", "Status", 0); 1258*3941Svenki log_printf("---------------------------------\n"); 1259*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1260*3941Svenki PICL_CLASS_CURRENT_SENSOR, (void *)PICL_PROP_CURRENT, 1261*3941Svenki sun4v_env_print_sensor_callback); 1262*3941Svenki } 1263*3941Svenki 1264*3941Svenki static void 1265*3941Svenki sun4v_env_print_current_indicators() 1266*3941Svenki { 1267*3941Svenki char *fmt = "%-11s %-14s %-8s\n"; 1268*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1269*3941Svenki PICL_CLASS_CURRENT_INDICATOR, 1270*3941Svenki (void *)PICL_PROP_CONDITION, 1271*3941Svenki sun4v_env_print_indicator_callback); 1272*3941Svenki if (!class_node_found) 1273*3941Svenki return; 1274*3941Svenki log_printf("\nCurrent indicators:\n"); 1275*3941Svenki if (syserrlog == 0) { 1276*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1277*3941Svenki PICL_CLASS_CURRENT_INDICATOR, NULL, 1278*3941Svenki sun4v_env_print_indicator_callback); 1279*3941Svenki if (all_status_ok) { 1280*3941Svenki log_printf("All current indicators are OK.\n"); 1281*3941Svenki return; 1282*3941Svenki } 1283*3941Svenki } 1284*3941Svenki log_printf("------------------------------------\n"); 1285*3941Svenki log_printf(fmt, "Location", "Indicator", "Condition", 0); 1286*3941Svenki log_printf("------------------------------------\n"); 1287*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1288*3941Svenki PICL_CLASS_CURRENT_INDICATOR, 1289*3941Svenki (void *)PICL_PROP_CONDITION, 1290*3941Svenki sun4v_env_print_indicator_callback); 1291*3941Svenki } 1292*3941Svenki 1293*3941Svenki static void 1294*3941Svenki sun4v_env_print_voltage_sensors() 1295*3941Svenki { 1296*3941Svenki char *fmt = "%-11s %-14s %-10s\n"; 1297*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1298*3941Svenki PICL_CLASS_VOLTAGE_SENSOR, 1299*3941Svenki PICL_PROP_VOLTAGE, 1300*3941Svenki sun4v_env_print_sensor_callback); 1301*3941Svenki if (!class_node_found) 1302*3941Svenki return; 1303*3941Svenki log_printf("\nVoltage sensors:\n"); 1304*3941Svenki if (syserrlog == 0) { 1305*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1306*3941Svenki PICL_CLASS_VOLTAGE_SENSOR, 1307*3941Svenki NULL, sun4v_env_print_sensor_callback); 1308*3941Svenki if (all_status_ok) { 1309*3941Svenki log_printf("All voltage sensors are OK.\n"); 1310*3941Svenki return; 1311*3941Svenki } 1312*3941Svenki } 1313*3941Svenki log_printf("---------------------------------\n"); 1314*3941Svenki log_printf(fmt, "Location", "Sensor", "Status", 0); 1315*3941Svenki log_printf("---------------------------------\n"); 1316*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1317*3941Svenki PICL_CLASS_VOLTAGE_SENSOR, 1318*3941Svenki (void *)PICL_PROP_VOLTAGE, 1319*3941Svenki sun4v_env_print_sensor_callback); 1320*3941Svenki } 1321*3941Svenki 1322*3941Svenki static void 1323*3941Svenki sun4v_env_print_voltage_indicators() 1324*3941Svenki { 1325*3941Svenki char *fmt = "%-11s %-14s %-8s\n"; 1326*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1327*3941Svenki PICL_CLASS_VOLTAGE_INDICATOR, 1328*3941Svenki (void *)PICL_PROP_CONDITION, 1329*3941Svenki sun4v_env_print_indicator_callback); 1330*3941Svenki if (!class_node_found) 1331*3941Svenki return; 1332*3941Svenki log_printf("\nVoltage indicators:\n"); 1333*3941Svenki if (syserrlog == 0) { 1334*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1335*3941Svenki PICL_CLASS_VOLTAGE_INDICATOR, NULL, 1336*3941Svenki sun4v_env_print_indicator_callback); 1337*3941Svenki if (all_status_ok) { 1338*3941Svenki log_printf("All voltage indicators are OK.\n"); 1339*3941Svenki return; 1340*3941Svenki } 1341*3941Svenki } 1342*3941Svenki log_printf("------------------------------------\n"); 1343*3941Svenki log_printf(fmt, "Location", "Indicator", "Condition", 0); 1344*3941Svenki log_printf("------------------------------------\n"); 1345*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1346*3941Svenki PICL_CLASS_VOLTAGE_INDICATOR, 1347*3941Svenki (void *)PICL_PROP_CONDITION, 1348*3941Svenki sun4v_env_print_indicator_callback); 1349*3941Svenki } 1350*3941Svenki 1351*3941Svenki static void 1352*3941Svenki sun4v_env_print_LEDs() 1353*3941Svenki { 1354*3941Svenki char *fmt = "%-11s %-14s %-8s\n"; 1355*3941Svenki if (syserrlog == 0) 1356*3941Svenki return; 1357*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_LED, 1358*3941Svenki (void *)PICL_PROP_STATE, sun4v_env_print_indicator_callback); 1359*3941Svenki if (!class_node_found) 1360*3941Svenki return; 1361*3941Svenki log_printf("\nLEDs:\n"); 1362*3941Svenki log_printf("--------------------------------\n"); 1363*3941Svenki log_printf(fmt, "Location", "LED", "State", 0); 1364*3941Svenki log_printf("--------------------------------\n"); 1365*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_LED, 1366*3941Svenki (void *)PICL_PROP_STATE, sun4v_env_print_indicator_callback); 1367*3941Svenki } 1368*3941Svenki 1369*3941Svenki /*ARGSUSED*/ 1370*3941Svenki static int 1371*3941Svenki sun4v_print_fru_status_callback(picl_nodehdl_t nodeh, void *args) 1372*3941Svenki { 1373*3941Svenki char label[PICL_PROPNAMELEN_MAX]; 1374*3941Svenki char status[PICL_PROPNAMELEN_MAX]; 1375*3941Svenki picl_errno_t err; 1376*3941Svenki picl_prophdl_t proph; 1377*3941Svenki picl_nodehdl_t parenth; 1378*3941Svenki char *names[PARENT_NAMES]; 1379*3941Svenki char *loc; 1380*3941Svenki int i; 1381*3941Svenki 1382*3941Svenki if (!class_node_found) { 1383*3941Svenki class_node_found = 1; 1384*3941Svenki return (PICL_WALK_TERMINATE); 1385*3941Svenki } 1386*3941Svenki err = picl_get_prop_by_name(nodeh, PICL_PROP_IS_FRU, &proph); 1387*3941Svenki if (err != PICL_SUCCESS) 1388*3941Svenki return (PICL_WALK_CONTINUE); 1389*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, label, 1390*3941Svenki sizeof (label)); 1391*3941Svenki if (err != PICL_SUCCESS) 1392*3941Svenki return (PICL_WALK_CONTINUE); 1393*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_OPERATIONAL_STATUS, 1394*3941Svenki status, sizeof (status)); 1395*3941Svenki if (err != PICL_SUCCESS) 1396*3941Svenki return (PICL_WALK_CONTINUE); 1397*3941Svenki if (syserrlog == 0) { 1398*3941Svenki if (strcmp(status, "disabled") == 0) { 1399*3941Svenki if (all_status_ok) { 1400*3941Svenki all_status_ok = 0; 1401*3941Svenki return (PICL_WALK_TERMINATE); 1402*3941Svenki } 1403*3941Svenki } else 1404*3941Svenki return (PICL_WALK_CONTINUE); 1405*3941Svenki } 1406*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth, 1407*3941Svenki sizeof (parenth)); 1408*3941Svenki if (err != PICL_SUCCESS) { 1409*3941Svenki log_printf("\n"); 1410*3941Svenki return (PICL_WALK_CONTINUE); 1411*3941Svenki } 1412*3941Svenki if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) == NULL) 1413*3941Svenki return (PICL_WALK_TERMINATE); 1414*3941Svenki for (i = 0; i < PARENT_NAMES; i++) 1415*3941Svenki if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) == NULL) { 1416*3941Svenki while (--i > -1) 1417*3941Svenki free(names[i]); 1418*3941Svenki free(loc); 1419*3941Svenki return (PICL_WALK_TERMINATE); 1420*3941Svenki } 1421*3941Svenki i = 0; 1422*3941Svenki while (err == PICL_SUCCESS) { 1423*3941Svenki if (parenth == chassish || parenth == phyplatformh) 1424*3941Svenki break; 1425*3941Svenki err = picl_get_propval_by_name(parenth, PICL_PROP_NAME, 1426*3941Svenki names[i++], PICL_PROPNAMELEN_MAX); 1427*3941Svenki if (err != PICL_SUCCESS) { 1428*3941Svenki i--; 1429*3941Svenki break; 1430*3941Svenki } 1431*3941Svenki if (i == PARENT_NAMES) 1432*3941Svenki break; 1433*3941Svenki err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT, 1434*3941Svenki &parenth, sizeof (parenth)); 1435*3941Svenki } 1436*3941Svenki loc[0] = '\0'; 1437*3941Svenki if (--i > -1) 1438*3941Svenki loc = strncat(loc, names[i], strlen(names[i])); 1439*3941Svenki while (--i > -1) { 1440*3941Svenki loc = strncat(loc, "/", 1); 1441*3941Svenki loc = strncat(loc, names[i], strlen(names[i])); 1442*3941Svenki } 1443*3941Svenki log_printf("%-21s", loc); 1444*3941Svenki for (i = 0; i < PARENT_NAMES; i++) 1445*3941Svenki free(names[i]); 1446*3941Svenki free(loc); 1447*3941Svenki log_printf("%-10s", label); 1448*3941Svenki log_printf("%-9s", status); 1449*3941Svenki log_printf("\n"); 1450*3941Svenki return (PICL_WALK_CONTINUE); 1451*3941Svenki } 1452*3941Svenki 1453*3941Svenki static void 1454*3941Svenki sun4v_print_fru_status() 1455*3941Svenki { 1456*3941Svenki char *fmt = "%-20s %-9s %-8s\n"; 1457*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, NULL, NULL, 1458*3941Svenki sun4v_print_fru_status_callback); 1459*3941Svenki if (!class_node_found) 1460*3941Svenki return; 1461*3941Svenki log_printf("\n"); 1462*3941Svenki log_printf("============================"); 1463*3941Svenki log_printf(" FRU Status "); 1464*3941Svenki log_printf("============================"); 1465*3941Svenki log_printf("\n"); 1466*3941Svenki 1467*3941Svenki if (syserrlog == 0) { 1468*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1469*3941Svenki PICL_CLASS_MODULE, NULL, 1470*3941Svenki sun4v_print_fru_status_callback); 1471*3941Svenki if (all_status_ok) { 1472*3941Svenki log_printf("All FRUs are enabled.\n"); 1473*3941Svenki return; 1474*3941Svenki } 1475*3941Svenki } 1476*3941Svenki log_printf(fmt, "Location", "Name", "Status", 0); 1477*3941Svenki log_printf("-------------------------------------\n"); 1478*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_MODULE, NULL, 1479*3941Svenki sun4v_print_fru_status_callback); 1480*3941Svenki } 1481*3941Svenki 1482*3941Svenki /*ARGSUSED*/ 1483*3941Svenki static int 1484*3941Svenki sun4v_print_fw_rev_callback(picl_nodehdl_t nodeh, void *args) 1485*3941Svenki { 1486*3941Svenki char label[PICL_PROPNAMELEN_MAX]; 1487*3941Svenki char rev[PICL_PROPNAMELEN_MAX]; 1488*3941Svenki picl_errno_t err; 1489*3941Svenki 1490*3941Svenki if (!class_node_found) { 1491*3941Svenki class_node_found = 1; 1492*3941Svenki return (PICL_WALK_TERMINATE); 1493*3941Svenki } 1494*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, label, 1495*3941Svenki sizeof (label)); 1496*3941Svenki if (err != PICL_SUCCESS) 1497*3941Svenki return (PICL_WALK_CONTINUE); 1498*3941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_FW_REVISION, rev, 1499*3941Svenki sizeof (rev)); 1500*3941Svenki if (err != PICL_SUCCESS) 1501*3941Svenki return (PICL_WALK_CONTINUE); 1502*3941Svenki if (strlen(rev) == 0) 1503*3941Svenki return (PICL_WALK_CONTINUE); 1504*3941Svenki log_printf("%-21s", label); 1505*3941Svenki log_printf("%-40s", rev); 1506*3941Svenki log_printf("\n"); 1507*3941Svenki return (PICL_WALK_CONTINUE); 1508*3941Svenki } 1509*3941Svenki 1510*3941Svenki static void 1511*3941Svenki sun4v_print_fw_rev() 1512*3941Svenki { 1513*3941Svenki char *fmt = "%-20s %-10s\n"; 1514*3941Svenki if (syserrlog == 0) 1515*3941Svenki return; 1516*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, NULL, NULL, 1517*3941Svenki sun4v_print_fw_rev_callback); 1518*3941Svenki if (!class_node_found) 1519*3941Svenki return; 1520*3941Svenki log_printf("\n"); 1521*3941Svenki log_printf("============================"); 1522*3941Svenki log_printf(" FW Version "); 1523*3941Svenki log_printf("============================"); 1524*3941Svenki log_printf("\n"); 1525*3941Svenki log_printf(fmt, "Name", "Version", 0); 1526*3941Svenki log_printf("----------------------------\n"); 1527*3941Svenki (void) picl_walk_tree_by_class(phyplatformh, NULL, NULL, 1528*3941Svenki sun4v_print_fw_rev_callback); 1529*3941Svenki } 1530*3941Svenki 1531*3941Svenki static void 1532*3941Svenki sun4v_print_chassis_serial_no() 1533*3941Svenki { 1534*3941Svenki char val[PICL_PROPNAMELEN_MAX]; 1535*3941Svenki picl_errno_t err; 1536*3941Svenki if (syserrlog == 0 || chassish == 0) 1537*3941Svenki return; 1538*3941Svenki 1539*3941Svenki log_printf("\n"); 1540*3941Svenki log_printf("Chassis Serial Number"); 1541*3941Svenki log_printf("\n"); 1542*3941Svenki log_printf("---------------------\n"); 1543*3941Svenki err = picl_get_propval_by_name(chassish, PICL_PROP_SERIAL_NUMBER, 1544*3941Svenki val, sizeof (val)); 1545*3941Svenki if (err == PICL_SUCCESS) 1546*3941Svenki log_printf("%s", val); 1547*3941Svenki log_printf("\n"); 1548*3941Svenki } 1549