11708Sstevel /* 21708Sstevel * CDDL HEADER START 31708Sstevel * 41708Sstevel * The contents of this file are subject to the terms of the 53941Svenki * Common Development and Distribution License (the "License"). 63941Svenki * 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 /* 223941Svenki * 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> 463941Svenki #include <sys/systeminfo.h> 473941Svenki #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*4669Sfw157321 #define MOTHERBOARD "MB" 583941Svenki #define NETWORK "network" 593941Svenki #define PCIE_COMPATIBLE_STR "pciex" 603941Svenki #define PCIX_COMPATIBLE_STR "pci" 613941Svenki #define SUN4V_MACHINE "sun4v" 623941Svenki #define PARENT_NAMES 10 633941Svenki 643941Svenki /* 653941Svenki * Additional OBP properties 663941Svenki */ 673941Svenki #define OBP_PROP_COMPATIBLE "compatible" 683941Svenki #define OBP_PROP_MODEL "model" 693941Svenki #define OBP_PROP_SLOT_NAMES "slot-names" 703941Svenki 713941Svenki #define PICL_NODE_PHYSICAL_PLATFORM "physical-platform" 723941Svenki #define PICL_NODE_CHASSIS "chassis" 733941Svenki #define MEMORY_SIZE_FIELD 11 743941Svenki #define INVALID_THRESHOLD 1000000 753941Svenki 763941Svenki /* 773941Svenki * Additional picl classes 783941Svenki */ 793941Svenki #ifndef PICL_CLASS_SUN4V 803941Svenki #define PICL_CLASS_SUN4V "sun4v" 813941Svenki #endif 823941Svenki 833941Svenki #ifndef PICL_PROP_NAC 843941Svenki #define PICL_PROP_NAC "nac" 853941Svenki #endif 863941Svenki 873941Svenki extern int sys_clk; 883941Svenki extern picl_errno_t sun4v_get_node_by_name(picl_nodehdl_t, char *, 893941Svenki picl_nodehdl_t *); 903941Svenki 913941Svenki static picl_nodehdl_t rooth = 0, phyplatformh = 0; 923941Svenki static picl_nodehdl_t chassish = 0; 933941Svenki static int class_node_found; 943941Svenki static int syserrlog; 953941Svenki static int all_status_ok; 963941Svenki 973941Svenki /* local functions */ 983941Svenki static int sun4v_get_first_compatible_value(picl_nodehdl_t, char **); 993941Svenki static void sun4v_display_memory_conf(picl_nodehdl_t); 1003941Svenki static void sun4v_disp_env_status(); 1013941Svenki static void sun4v_env_print_fan_sensors(); 1023941Svenki static void sun4v_env_print_fan_indicators(); 1033941Svenki static void sun4v_env_print_temp_sensors(); 1043941Svenki static void sun4v_env_print_temp_indicators(); 1053941Svenki static void sun4v_env_print_current_sensors(); 1063941Svenki static void sun4v_env_print_current_indicators(); 1073941Svenki static void sun4v_env_print_voltage_sensors(); 1083941Svenki static void sun4v_env_print_voltage_indicators(); 1093941Svenki static void sun4v_env_print_LEDs(); 1103941Svenki static void sun4v_print_fru_status(); 1113941Svenki static void sun4v_print_fw_rev(); 1123941Svenki static void sun4v_print_chassis_serial_no(); 1131708Sstevel 1141708Sstevel int 1153941Svenki sun4v_display(Sys_tree *tree, Prom_node *root, int log, 1163941Svenki 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 */ 1213941Svenki char machine[MAXSTRLEN]; 1223941Svenki 1233941Svenki if (sysinfo(SI_MACHINE, machine, sizeof (machine)) == -1) 1243941Svenki return (1); 1253941Svenki if (strncmp(machine, SUN4V_MACHINE, strlen(SUN4V_MACHINE)) != 0) 1263941Svenki 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 1423941Svenki log_printf(dgettext(TEXT_DOMAIN, "System Configuration: " 143*4669Sfw157321 "Sun Microsystems %s %s\n"), uts_buf.machine, 144*4669Sfw157321 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 " 151*4669Sfw157321 "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 */ 1613941Svenki class_node_found = 0; 1623941Svenki sun4v_display_memory_conf(plafh); 1631708Sstevel 1641708Sstevel /* Display all the IO cards. */ 1651708Sstevel (void) sun4v_display_pci(plafh); 1663941Svenki sun4v_display_diaginfo((log || (logging)), root, plafh); 1671708Sstevel 1683941Svenki if (picl_get_root(&rooth) != PICL_SUCCESS) 1693941Svenki return (1); 1703941Svenki if (sun4v_get_node_by_name(rooth, PICL_NODE_PHYSICAL_PLATFORM, 171*4669Sfw157321 &phyplatformh) != PICL_SUCCESS) 1723941Svenki return (1); 1733941Svenki 1743941Svenki if (picl_find_node(phyplatformh, PICL_PROP_CLASSNAME, 175*4669Sfw157321 PICL_PTYPE_CHARSTRING, (void *)PICL_CLASS_CHASSIS, 176*4669Sfw157321 strlen(PICL_CLASS_CHASSIS), &chassish) != PICL_SUCCESS) 1773941Svenki return (1); 1783941Svenki 1793941Svenki syserrlog = log; 1803941Svenki sun4v_disp_env_status(); 1813941Svenki } 1823941Svenki return (0); 1833941Svenki } 1843941Svenki 1853941Svenki static void 1863941Svenki get_bus_type(picl_nodehdl_t nodeh, struct io_card *card) 1873941Svenki { 1883941Svenki char *compatible; 1893941Svenki 1904003Svivek (void) strlcpy(card->bus_type, "PCIX", sizeof (card->bus_type)); 1913941Svenki if (sun4v_get_first_compatible_value(nodeh, &compatible) 192*4669Sfw157321 == PICL_SUCCESS) { 1933941Svenki if (strncmp(compatible, PCIE_COMPATIBLE_STR, 194*4669Sfw157321 strlen(PCIE_COMPATIBLE_STR)) == 0) 1954003Svivek (void) strlcpy(card->bus_type, "PCIE", 196*4669Sfw157321 sizeof (card->bus_type)); 1973941Svenki free(compatible); 1983941Svenki } 1993941Svenki } 2003941Svenki 2013941Svenki static picl_errno_t 2023941Svenki get_slot_label(picl_nodehdl_t nodeh, struct io_card *card) 2033941Svenki { 2043941Svenki char val[PICL_PROPNAMELEN_MAX]; 2053941Svenki picl_errno_t err; 2063941Svenki 2073941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, val, 208*4669Sfw157321 sizeof (val)); 2093941Svenki if (err != PICL_SUCCESS) 2103941Svenki return (err); 2113941Svenki 2124003Svivek (void) strlcpy(card->slot_str, val, sizeof (card->slot_str)); 2133941Svenki card->slot = -1; 2143941Svenki return (PICL_SUCCESS); 2153941Svenki } 2163941Svenki 2173941Svenki static void 2183941Svenki get_slot_number(picl_nodehdl_t nodeh, struct io_card *card) 2193941Svenki { 2203941Svenki picl_errno_t err; 2213941Svenki picl_prophdl_t proph; 2223941Svenki picl_propinfo_t pinfo; 2233941Svenki picl_nodehdl_t pnodeh; 2243941Svenki uint8_t *pval; 2253941Svenki uint32_t dev_mask; 2263941Svenki char uaddr[MAXSTRLEN]; 2273941Svenki int i; 2283941Svenki 2293941Svenki if (get_slot_label(nodeh, card) == PICL_SUCCESS) 2303941Svenki return; 2313941Svenki err = PICL_SUCCESS; 2323941Svenki while (err == PICL_SUCCESS) { 2333941Svenki if (picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &pnodeh, 234*4669Sfw157321 sizeof (pnodeh)) != PICL_SUCCESS) { 235*4669Sfw157321 (void) strlcpy(card->slot_str, MOTHERBOARD, 236*4669Sfw157321 sizeof (card->slot_str)); 2373941Svenki card->slot = -1; 2383941Svenki return; 2393941Svenki } 2403941Svenki if (picl_get_propinfo_by_name(pnodeh, OBP_PROP_SLOT_NAMES, 241*4669Sfw157321 &pinfo, &proph) == PICL_SUCCESS) { 2423941Svenki break; 2433941Svenki } 2443941Svenki nodeh = pnodeh; 2453941Svenki } 2463941Svenki if (picl_get_propval_by_name(nodeh, PICL_PROP_UNIT_ADDRESS, uaddr, 247*4669Sfw157321 sizeof (uaddr)) != PICL_SUCCESS) { 248*4669Sfw157321 (void) strlcpy(card->slot_str, MOTHERBOARD, 249*4669Sfw157321 sizeof (card->slot_str)); 2503941Svenki card->slot = -1; 2513941Svenki return; 2523941Svenki } 2533941Svenki pval = (uint8_t *)malloc(pinfo.size); 2543941Svenki if (!pval) { 255*4669Sfw157321 (void) strlcpy(card->slot_str, MOTHERBOARD, 256*4669Sfw157321 sizeof (card->slot_str)); 2573941Svenki card->slot = -1; 2583941Svenki return; 2593941Svenki } 2603941Svenki if (picl_get_propval(proph, pval, pinfo.size) != PICL_SUCCESS) { 261*4669Sfw157321 (void) strlcpy(card->slot_str, MOTHERBOARD, 262*4669Sfw157321 sizeof (card->slot_str)); 2633941Svenki card->slot = -1; 2643941Svenki free(pval); 2653941Svenki return; 2661708Sstevel } 2671708Sstevel 2683941Svenki dev_mask = 0; 2693941Svenki for (i = 0; i < sizeof (dev_mask); i++) 2703941Svenki dev_mask |= (*(pval+i) << 8*(sizeof (dev_mask)-1-i)); 2713941Svenki for (i = 0; i < sizeof (uaddr) && uaddr[i] != '\0'; i++) { 2723941Svenki if (uaddr[i] == ',') { 2733941Svenki uaddr[i] = '\0'; 2743941Svenki break; 2753941Svenki } 2763941Svenki } 2773941Svenki card->slot = atol(uaddr); 2783941Svenki if (((1 << card->slot) & dev_mask) == 0) { 279*4669Sfw157321 (void) strlcpy(card->slot_str, MOTHERBOARD, 280*4669Sfw157321 sizeof (card->slot_str)); 2813941Svenki card->slot = -1; 2823941Svenki } else { 2833941Svenki char *p = (char *)(pval+sizeof (dev_mask)); 2843941Svenki int shift = sizeof (uint32_t)*8-1-card->slot; 2853941Svenki uint32_t x = (dev_mask << shift) >> shift; 2863941Svenki int count = 0; /* count # of 1's in x */ 2873941Svenki int i = 0; 2883941Svenki while (x != 0) { 2893941Svenki count++; 2903941Svenki x &= x-1; 2913941Svenki } 2923941Svenki while (count > 1) { 293*4669Sfw157321 while (p[i++] != '\0') 294*4669Sfw157321 ; 2953941Svenki count--; 2963941Svenki } 2974003Svivek (void) strlcpy(card->slot_str, (char *)(p+i), 298*4669Sfw157321 sizeof (card->slot_str)); 2993941Svenki } 3003941Svenki free(pval); 3013941Svenki } 3023941Svenki 3033941Svenki /* 3043941Svenki * add all io devices under pci in io list 3053941Svenki */ 3063941Svenki /* ARGSUSED */ 3073941Svenki static int 3083941Svenki sun4v_pci_callback(picl_nodehdl_t pcih, void *args) 3093941Svenki { 3103941Svenki char path[PICL_PROPNAMELEN_MAX]; 3113941Svenki char class[PICL_CLASSNAMELEN_MAX]; 3123941Svenki char name[PICL_PROPNAMELEN_MAX]; 3133941Svenki char model[PICL_PROPNAMELEN_MAX]; 3143941Svenki char binding_name[PICL_PROPNAMELEN_MAX]; 3153941Svenki char val[PICL_PROPNAMELEN_MAX]; 3163941Svenki char *compatible; 3173941Svenki picl_errno_t err; 3183941Svenki picl_nodehdl_t nodeh; 3193941Svenki struct io_card pci_card; 3203941Svenki 3213941Svenki /* Walk through the children */ 3223941Svenki 3233941Svenki err = picl_get_propval_by_name(pcih, PICL_PROP_CHILD, &nodeh, 324*4669Sfw157321 sizeof (picl_nodehdl_t)); 3253941Svenki 3263941Svenki while (err == PICL_SUCCESS) { 3273941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME, 328*4669Sfw157321 class, sizeof (class)); 3293941Svenki if (err != PICL_SUCCESS) 3303941Svenki return (err); 3313941Svenki 3323941Svenki if (args) { 3333941Svenki char *val = args; 3343941Svenki if (strcmp(class, val) == 0) { 3353941Svenki err = picl_get_propval_by_name(nodeh, 336*4669Sfw157321 PICL_PROP_PEER, &nodeh, 337*4669Sfw157321 sizeof (picl_nodehdl_t)); 3383941Svenki continue; 3393941Svenki } else if (strcmp(val, PICL_CLASS_PCIEX) == 0 && 340*4669Sfw157321 strcmp(class, PICL_CLASS_PCI) == 0) { 3413941Svenki err = picl_get_propval_by_name(nodeh, 342*4669Sfw157321 PICL_PROP_PEER, &nodeh, 343*4669Sfw157321 sizeof (picl_nodehdl_t)); 3443941Svenki continue; 3453941Svenki } else if (strcmp(val, PICL_CLASS_PCI) == 0 && 346*4669Sfw157321 strcmp(class, PICL_CLASS_PCIEX) == 0) { 3473941Svenki err = picl_get_propval_by_name(nodeh, 348*4669Sfw157321 PICL_PROP_PEER, &nodeh, 349*4669Sfw157321 sizeof (picl_nodehdl_t)); 3503941Svenki continue; 3513941Svenki } 3523941Svenki } 3533941Svenki 3543941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_DEVFS_PATH, 355*4669Sfw157321 path, sizeof (path)); 3563941Svenki if (err != PICL_SUCCESS) 3573941Svenki return (err); 3583941Svenki 3593941Svenki (void) strlcpy(pci_card.notes, path, sizeof (pci_card.notes)); 3603941Svenki 3613941Svenki get_bus_type(nodeh, &pci_card); 3623941Svenki get_slot_number(nodeh, &pci_card); 3633941Svenki 3643941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_NAME, name, 365*4669Sfw157321 sizeof (name)); 3663941Svenki if (err == PICL_PROPNOTFOUND) 3674003Svivek (void) strlcpy(name, "", sizeof (name)); 3683941Svenki else if (err != PICL_SUCCESS) 3693941Svenki return (err); 3703941Svenki 3713941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_STATUS, val, 372*4669Sfw157321 sizeof (val)); 3733941Svenki if (err == PICL_PROPNOTFOUND) 3744003Svivek (void) strlcpy(val, "", sizeof (val)); 3753941Svenki else if (err != PICL_SUCCESS) 3763941Svenki return (err); 3773941Svenki 3783941Svenki /* Figure NAC name */ 3793941Svenki if (pci_card.slot != -1) 3803941Svenki (void) snprintf(pci_card.status, 381*4669Sfw157321 sizeof (pci_card.status), 382*4669Sfw157321 "%s%d", pci_card.slot_str, 383*4669Sfw157321 pci_card.slot); 3843941Svenki else 3853941Svenki (void) snprintf(pci_card.status, 386*4669Sfw157321 sizeof (pci_card.status), 387*4669Sfw157321 "%s", pci_card.slot_str); 3883941Svenki 3893941Svenki /* 3903941Svenki * Get the name of this card. If binding_name is found, 3913941Svenki * name will be <nodename>-<binding_name>. 3923941Svenki */ 3933941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_BINDING_NAME, 394*4669Sfw157321 binding_name, sizeof (binding_name)); 3953941Svenki if (err == PICL_SUCCESS) { 3963941Svenki if (strcmp(name, binding_name) != 0) { 3973941Svenki (void) strlcat(name, "-", sizeof (name)); 3983941Svenki (void) strlcat(name, binding_name, 399*4669Sfw157321 sizeof (name)); 4003941Svenki } 4013941Svenki } else if (err == PICL_PROPNOTFOUND) { 4023941Svenki /* 4033941Svenki * if compatible prop is not found, name will be 4043941Svenki * <nodename>-<compatible> 4053941Svenki */ 4063941Svenki err = sun4v_get_first_compatible_value(nodeh, 407*4669Sfw157321 &compatible); 4083941Svenki if (err == PICL_SUCCESS) { 4093941Svenki (void) strlcat(name, "-", sizeof (name)); 4104003Svivek (void) strlcat(name, compatible, 411*4669Sfw157321 sizeof (name)); 4123941Svenki free(compatible); 4133941Svenki } 4143941Svenki } else 4153941Svenki return (err); 4163941Svenki 4173941Svenki (void) strlcpy(pci_card.name, name, sizeof (pci_card.name)); 4183941Svenki 4193941Svenki /* Get the model of this card */ 4203941Svenki 4213941Svenki err = picl_get_propval_by_name(nodeh, OBP_PROP_MODEL, 422*4669Sfw157321 model, sizeof (model)); 4233941Svenki if (err == PICL_PROPNOTFOUND) 4244003Svivek (void) strlcpy(model, "", sizeof (model)); 4253941Svenki else if (err != PICL_SUCCESS) 4263941Svenki return (err); 4273941Svenki (void) strlcpy(pci_card.model, model, sizeof (pci_card.model)); 4283941Svenki 4293941Svenki /* Print NAC name */ 4303941Svenki log_printf("%-12s", pci_card.status); 4313941Svenki /* Print IO Type */ 4323941Svenki log_printf("%-6s", pci_card.bus_type); 4333941Svenki /* Printf Card Name */ 4343941Svenki log_printf("%-46s", pci_card.name); 4353941Svenki /* Print Card Model */ 4363941Svenki log_printf("%-8s", pci_card.model); 4373941Svenki log_printf("\n"); 4383941Svenki /* Print Status */ 4393941Svenki log_printf("%-12s", val); 4403941Svenki /* Print IO Type */ 4413941Svenki log_printf("%-6s", ""); 4423941Svenki /* Print Parent Path */ 4433941Svenki log_printf("%-46s", pci_card.notes); 4443941Svenki log_printf("\n"); 4453941Svenki 4463941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh, 447*4669Sfw157321 sizeof (picl_nodehdl_t)); 4483941Svenki } 4493941Svenki return (PICL_WALK_CONTINUE); 4501708Sstevel } 4511708Sstevel 4521708Sstevel /* 4531708Sstevel * display_pci 4541708Sstevel * Display all the PCI IO cards on this board. 4551708Sstevel */ 4561708Sstevel void 4571708Sstevel sun4v_display_pci(picl_nodehdl_t plafh) 4581708Sstevel { 4593941Svenki char *fmt = "%-11s %-5s %-45s %-8s"; 4603941Svenki /* Have we printed the column headings? */ 4613941Svenki static int banner = FALSE; 4623941Svenki 4633941Svenki if (banner == FALSE) { 4643941Svenki log_printf("\n"); 4653941Svenki log_printf("============================"); 4663941Svenki log_printf(" IO Devices "); 4673941Svenki log_printf("============================"); 4683941Svenki log_printf("\n"); 4693941Svenki log_printf(fmt, "Slot +", "Bus", "Name +", "Model", 0); 4703941Svenki log_printf("\n"); 4713941Svenki log_printf(fmt, "Status", "Type", "Path", "", 0); 4723941Svenki log_printf("\n"); 4733941Svenki log_printf("---------------------------------" 474*4669Sfw157321 "------------------------------------\n"); 4753941Svenki banner = TRUE; 4763941Svenki } 4773941Svenki 4783941Svenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_PCIEX, 479*4669Sfw157321 PICL_CLASS_PCIEX, sun4v_pci_callback); 4803941Svenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_PCI, 481*4669Sfw157321 PICL_CLASS_PCI, sun4v_pci_callback); 4823941Svenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_SUN4V, 483*4669Sfw157321 PICL_CLASS_SUN4V, sun4v_pci_callback); 4843941Svenki } 4853941Svenki 4863941Svenki /* 4873941Svenki * return the first compatible value 4883941Svenki */ 4893941Svenki static int 4903941Svenki sun4v_get_first_compatible_value(picl_nodehdl_t nodeh, char **outbuf) 4913941Svenki { 4923941Svenki picl_errno_t err; 4933941Svenki picl_prophdl_t proph; 4943941Svenki picl_propinfo_t pinfo; 4953941Svenki picl_prophdl_t tblh; 4963941Svenki picl_prophdl_t rowproph; 4973941Svenki char *pval; 4983941Svenki 4993941Svenki err = picl_get_propinfo_by_name(nodeh, OBP_PROP_COMPATIBLE, 500*4669Sfw157321 &pinfo, &proph); 5013941Svenki if (err != PICL_SUCCESS) 5023941Svenki return (err); 5033941Svenki 5043941Svenki if (pinfo.type == PICL_PTYPE_CHARSTRING) { 5053941Svenki pval = malloc(pinfo.size); 5063941Svenki if (pval == NULL) 5073941Svenki return (PICL_FAILURE); 5083941Svenki err = picl_get_propval(proph, pval, pinfo.size); 5093941Svenki if (err != PICL_SUCCESS) { 5103941Svenki free(pval); 5113941Svenki return (err); 5123941Svenki } 5133941Svenki *outbuf = pval; 5143941Svenki return (PICL_SUCCESS); 5153941Svenki } 5163941Svenki 5173941Svenki if (pinfo.type != PICL_PTYPE_TABLE) 5183941Svenki return (PICL_FAILURE); 5193941Svenki 5203941Svenki /* get first string from table */ 5213941Svenki err = picl_get_propval(proph, &tblh, pinfo.size); 5223941Svenki if (err != PICL_SUCCESS) 5233941Svenki return (err); 5243941Svenki 5253941Svenki err = picl_get_next_by_row(tblh, &rowproph); 5263941Svenki if (err != PICL_SUCCESS) 5273941Svenki return (err); 5283941Svenki 5293941Svenki err = picl_get_propinfo(rowproph, &pinfo); 5303941Svenki if (err != PICL_SUCCESS) 5313941Svenki return (err); 5323941Svenki 5333941Svenki pval = malloc(pinfo.size); 5343941Svenki if (pval == NULL) 5353941Svenki return (PICL_FAILURE); 5363941Svenki 5373941Svenki err = picl_get_propval(rowproph, pval, pinfo.size); 5383941Svenki if (err != PICL_SUCCESS) { 5393941Svenki free(pval); 5403941Svenki return (err); 5413941Svenki } 5423941Svenki 5433941Svenki *outbuf = pval; 5443941Svenki return (PICL_SUCCESS); 5451708Sstevel } 5461708Sstevel 5473941Svenki /* 5483941Svenki * print size of a memory segment 5493941Svenki */ 5503941Svenki static void 5513941Svenki print_memory_segment_size(uint64_t size) 5523941Svenki { 5533941Svenki uint64_t kbyte = 1024; 5543941Svenki uint64_t mbyte = kbyte * kbyte; 5553941Svenki uint64_t gbyte = kbyte * mbyte; 5563941Svenki char buf[MEMORY_SIZE_FIELD]; 5573941Svenki 5583941Svenki if (size >= gbyte) { 5593941Svenki if (size % gbyte == 0) 5603941Svenki (void) snprintf(buf, sizeof (buf), "%d GB", 561*4669Sfw157321 (int)(size / gbyte)); 5623941Svenki else 5633941Svenki (void) snprintf(buf, sizeof (buf), "%.2f GB", 564*4669Sfw157321 (float)size / gbyte); 5653941Svenki } else if (size >= mbyte) { 5663941Svenki if (size % mbyte == 0) 5673941Svenki (void) snprintf(buf, sizeof (buf), "%d MB", 568*4669Sfw157321 (int)(size / mbyte)); 5693941Svenki else 5703941Svenki (void) snprintf(buf, sizeof (buf), "%.2f MB", 571*4669Sfw157321 (float)size / mbyte); 5723941Svenki } else { 5733941Svenki if (size % kbyte == 0) 5743941Svenki (void) snprintf(buf, sizeof (buf), "%d KB", 575*4669Sfw157321 (int)(size / kbyte)); 5763941Svenki else 5773941Svenki (void) snprintf(buf, sizeof (buf), "%.2f KB", 578*4669Sfw157321 (float)size / kbyte); 5793941Svenki } 5803941Svenki log_printf("%-7s ", buf); 5813941Svenki } 5823941Svenki 5833941Svenki /* 584*4669Sfw157321 * Enumerate banks and dimms within a memory segment. We're handed 585*4669Sfw157321 * the first bank within the segment - we assume there are dimms 586*4669Sfw157321 * (memory-module) nodes underneath. 5873941Svenki */ 5883941Svenki static void 589*4669Sfw157321 print_memory_segment_contain(picl_nodehdl_t bank_nodeh) 5901708Sstevel { 5913941Svenki char val[PICL_PROPNAMELEN_MAX]; 592*4669Sfw157321 picl_nodehdl_t module_nodeh; 593*4669Sfw157321 int flag = 0; 594*4669Sfw157321 595*4669Sfw157321 do { 596*4669Sfw157321 if (picl_get_propval_by_name(bank_nodeh, PICL_PROP_CHILD, 597*4669Sfw157321 &module_nodeh, sizeof (picl_nodehdl_t)) != PICL_SUCCESS) 598*4669Sfw157321 continue; 599*4669Sfw157321 do { 600*4669Sfw157321 if (picl_get_propval_by_name(module_nodeh, 601*4669Sfw157321 PICL_PROP_NAC, val, sizeof (val)) != 602*4669Sfw157321 PICL_SUCCESS) 603*4669Sfw157321 continue; 604*4669Sfw157321 else { 605*4669Sfw157321 if (!flag) { 606*4669Sfw157321 log_printf("%-30s\n", val); 607*4669Sfw157321 flag = 1; 608*4669Sfw157321 } else 609*4669Sfw157321 log_printf("%57s\n", val); 610*4669Sfw157321 } 611*4669Sfw157321 } while (picl_get_propval_by_name(module_nodeh, PICL_PROP_PEER, 612*4669Sfw157321 &module_nodeh, sizeof (picl_nodehdl_t)) == 613*4669Sfw157321 PICL_SUCCESS); 614*4669Sfw157321 } while (picl_get_propval_by_name(bank_nodeh, PICL_PROP_PEER, 615*4669Sfw157321 &bank_nodeh, sizeof (picl_nodehdl_t)) == PICL_SUCCESS); 6163941Svenki } 6173941Svenki 6183941Svenki /* 6193941Svenki * Search node where _class=="memory-segment" 6203941Svenki * print "Base Address", "Size", etc 6213941Svenki */ 6223941Svenki /*ARGSUSED*/ 6233941Svenki static int 6243941Svenki sun4v_memory_conf_callback(picl_nodehdl_t nodeh, void *args) 6253941Svenki { 6263941Svenki uint64_t base; 6273941Svenki uint64_t size; 6283941Svenki uint64_t ifactor; 6293941Svenki picl_errno_t err = PICL_SUCCESS; 6303941Svenki 6313941Svenki if (class_node_found == 0) { 6323941Svenki class_node_found = 1; 6333941Svenki return (PICL_WALK_TERMINATE); 6343941Svenki } 6353941Svenki while (err == PICL_SUCCESS) { 6363941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_BASEADDRESS, 637*4669Sfw157321 &base, sizeof (base)); 6383941Svenki if (err != PICL_SUCCESS) 6393941Svenki break; 6403941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_SIZE, 641*4669Sfw157321 &size, sizeof (size)); 6423941Svenki if (err != PICL_SUCCESS) 6433941Svenki break; 6443941Svenki err = picl_get_propval_by_name(nodeh, 645*4669Sfw157321 PICL_PROP_INTERLEAVE_FACTOR, &ifactor, 646*4669Sfw157321 sizeof (ifactor)); 6473941Svenki if (err != PICL_SUCCESS) 6483941Svenki break; 6493941Svenki log_printf("%-13llx", base); 6503941Svenki print_memory_segment_size(size); 651*4669Sfw157321 log_printf("%-18lld", ifactor); 652*4669Sfw157321 err = picl_get_propval_by_name(nodeh, PICL_PROP_CHILD, 653*4669Sfw157321 &nodeh, sizeof (nodeh)); 654*4669Sfw157321 if (err == PICL_SUCCESS) 655*4669Sfw157321 print_memory_segment_contain(nodeh); 6563941Svenki log_printf("\n"); 6573941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh, 658*4669Sfw157321 sizeof (picl_nodehdl_t)); 6593941Svenki } 6603941Svenki 6613941Svenki return (PICL_WALK_CONTINUE); 6623941Svenki } 6633941Svenki 6643941Svenki /*ARGSUSED*/ 6653941Svenki void 6663941Svenki sun4v_display_memory_conf(picl_nodehdl_t plafh) 6673941Svenki { 6683941Svenki char *fmt = "%-12s %-7s %-9s %-20s"; 6693941Svenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY_SEGMENT, 670*4669Sfw157321 NULL, sun4v_memory_conf_callback); 6713941Svenki if (class_node_found == 0) 6723941Svenki return; 6733941Svenki log_printf("\n"); 6743941Svenki log_printf("============================"); 6753941Svenki log_printf(" Memory Configuration "); 6763941Svenki log_printf("============================"); 6773941Svenki log_printf("\n"); 6783941Svenki log_printf("Segment Table:\n"); 679*4669Sfw157321 log_printf( 680*4669Sfw157321 "---------------------------------------------------------\n"); 6813941Svenki log_printf(fmt, "Base Address", "Size", "Interleave Factor", 682*4669Sfw157321 "Contains", 0); 6833941Svenki log_printf("\n"); 684*4669Sfw157321 log_printf( 685*4669Sfw157321 "---------------------------------------------------------\n"); 6863941Svenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY_SEGMENT, 687*4669Sfw157321 NULL, sun4v_memory_conf_callback); 6881708Sstevel } 6891708Sstevel 6901708Sstevel void 6911708Sstevel sun4v_display_cpu_devices(picl_nodehdl_t plafh) 6921708Sstevel { 6933941Svenki char *fmt = "%-12s %-5s %-8s %-19s %-5s"; 6941708Sstevel 6951708Sstevel /* 6961708Sstevel * Display the table header for CPUs . Then display the CPU 6971708Sstevel * frequency, cache size, and processor revision of all cpus. 6981708Sstevel */ 6991708Sstevel log_printf(dgettext(TEXT_DOMAIN, 700*4669Sfw157321 "\n" 701*4669Sfw157321 "=========================" 702*4669Sfw157321 " CPUs " 703*4669Sfw157321 "===============================================" 704*4669Sfw157321 "\n" 705*4669Sfw157321 "\n")); 7061708Sstevel log_printf(fmt, "", "", "", "CPU", "CPU", 0); 7071708Sstevel log_printf("\n"); 7081708Sstevel log_printf(fmt, "Location", "CPU", "Freq", 709*4669Sfw157321 "Implementation", "Mask", 0); 7101708Sstevel log_printf("\n"); 7111708Sstevel log_printf(fmt, "------------", "-----", "--------", 712*4669Sfw157321 "-------------------", "-----", 0); 7131708Sstevel log_printf("\n"); 7141708Sstevel 7151708Sstevel (void) picl_walk_tree_by_class(plafh, "cpu", "cpu", sun4v_display_cpus); 7161708Sstevel } 7171708Sstevel 7181708Sstevel /* 7191708Sstevel * Display the CPUs present on this board. 7201708Sstevel */ 7211708Sstevel /*ARGSUSED*/ 7221708Sstevel int 7231708Sstevel sun4v_display_cpus(picl_nodehdl_t cpuh, void* args) 7241708Sstevel { 7251708Sstevel int status; 7263941Svenki picl_prophdl_t proph; 7273941Svenki picl_prophdl_t tblh; 7283941Svenki picl_prophdl_t rowproph; 7291708Sstevel picl_propinfo_t propinfo; 7303941Svenki int *int_value; 7313941Svenki uint64_t cpuid, mask_no; 7323941Svenki char *comp_value; 7333941Svenki char *no_prop_value = " "; 7343941Svenki char freq_str[MAXSTRLEN]; 7353941Svenki char fru_name[MAXSTRLEN]; 7361708Sstevel 7371708Sstevel /* 7381708Sstevel * Get cpuid property and print it and the NAC name 7391708Sstevel */ 7401708Sstevel status = picl_get_propinfo_by_name(cpuh, "cpuid", &propinfo, &proph); 7411708Sstevel if (status == PICL_SUCCESS) { 7421708Sstevel status = picl_get_propval(proph, &cpuid, sizeof (cpuid)); 7431708Sstevel if (status != PICL_SUCCESS) { 7443941Svenki log_printf("%-13s", no_prop_value); 7453941Svenki log_printf("%-6s", no_prop_value); 7461708Sstevel } else { 7471708Sstevel (void) snprintf(fru_name, sizeof (fru_name), "%s%d", 7481708Sstevel CPU_STRAND_NAC, (int)cpuid); 7493941Svenki log_printf("%-13s", fru_name); 7503941Svenki log_printf("%-6d", (int)cpuid); 7511708Sstevel } 7521708Sstevel } else { 7533941Svenki log_printf("%-13s", no_prop_value); 7543941Svenki log_printf("%-6s", no_prop_value); 7551708Sstevel } 7561708Sstevel 7571708Sstevel clock_freq: 7581708Sstevel status = picl_get_propinfo_by_name(cpuh, "clock-frequency", &propinfo, 759*4669Sfw157321 &proph); 7601708Sstevel if (status == PICL_SUCCESS) { 7611708Sstevel int_value = malloc(propinfo.size); 7621708Sstevel if (int_value == NULL) { 7633941Svenki log_printf("%-9s", no_prop_value); 7641708Sstevel goto compatible; 7651708Sstevel } 7661708Sstevel status = picl_get_propval(proph, int_value, propinfo.size); 7671708Sstevel if (status != PICL_SUCCESS) { 7683941Svenki log_printf("%-9s", no_prop_value); 7691708Sstevel } else { 7701708Sstevel /* Running frequency */ 7711708Sstevel (void) snprintf(freq_str, sizeof (freq_str), "%d MHz", 7721708Sstevel CLK_FREQ_TO_MHZ(*int_value)); 7733941Svenki log_printf("%-9s", freq_str); 7741708Sstevel } 7751708Sstevel free(int_value); 7761708Sstevel } else 7773941Svenki log_printf("%-9s", no_prop_value); 7781708Sstevel 7791708Sstevel compatible: 7801708Sstevel status = picl_get_propinfo_by_name(cpuh, "compatible", &propinfo, 781*4669Sfw157321 &proph); 7821708Sstevel if (status == PICL_SUCCESS) { 7831708Sstevel if (propinfo.type == PICL_PTYPE_CHARSTRING) { 7841708Sstevel /* 7851708Sstevel * Compatible Property only has 1 value 7861708Sstevel */ 7871708Sstevel comp_value = malloc(propinfo.size); 7881708Sstevel if (comp_value == NULL) { 7893941Svenki log_printf("%-20s", no_prop_value, 0); 7901708Sstevel goto mask; 7911708Sstevel } 7921708Sstevel status = picl_get_propval(proph, comp_value, 793*4669Sfw157321 propinfo.size); 7943941Svenki if (status != PICL_SUCCESS) 7953941Svenki log_printf("%-20s", no_prop_value, 0); 7963941Svenki else 7973941Svenki log_printf("%-20s", comp_value, 0); 7983941Svenki free(comp_value); 7991708Sstevel } else if (propinfo.type == PICL_PTYPE_TABLE) { 8001708Sstevel /* 8011708Sstevel * Compatible Property has multiple values 8021708Sstevel */ 8031708Sstevel status = picl_get_propval(proph, &tblh, propinfo.size); 8041708Sstevel if (status != PICL_SUCCESS) { 8053941Svenki log_printf("%-20s", no_prop_value, 0); 8061708Sstevel goto mask; 8071708Sstevel } 8081708Sstevel status = picl_get_next_by_row(tblh, &rowproph); 8091708Sstevel if (status != PICL_SUCCESS) { 8103941Svenki log_printf("%-20s", no_prop_value, 0); 8111708Sstevel goto mask; 8121708Sstevel } 8131708Sstevel 8141708Sstevel status = picl_get_propinfo(rowproph, &propinfo); 8151708Sstevel if (status != PICL_SUCCESS) { 8163941Svenki log_printf("%-20s", no_prop_value, 0); 8171708Sstevel goto mask; 8181708Sstevel } 8191708Sstevel 8201708Sstevel comp_value = malloc(propinfo.size); 8211708Sstevel if (comp_value == NULL) { 8223941Svenki log_printf("%-20s", no_prop_value, 0); 8231708Sstevel goto mask; 8241708Sstevel } 8251708Sstevel status = picl_get_propval(rowproph, comp_value, 826*4669Sfw157321 propinfo.size); 8273941Svenki if (status != PICL_SUCCESS) 8283941Svenki log_printf("%-20s", no_prop_value, 0); 8293941Svenki else 8303941Svenki log_printf("%-20s", comp_value, 0); 8311708Sstevel free(comp_value); 8321708Sstevel } 8331708Sstevel } else 8343941Svenki log_printf("%-20s", no_prop_value, 0); 8351708Sstevel 8361708Sstevel mask: 8371708Sstevel status = picl_get_propinfo_by_name(cpuh, "mask#", &propinfo, &proph); 8381708Sstevel if (status == PICL_SUCCESS) { 8391708Sstevel status = picl_get_propval(proph, &mask_no, sizeof (mask_no)); 8401708Sstevel if (status != PICL_SUCCESS) { 8413941Svenki log_printf("%-9s", no_prop_value); 8421708Sstevel } else { 8431708Sstevel log_printf(dgettext(TEXT_DOMAIN, " %2d.%d"), 844*4669Sfw157321 (mask_no>> 4) & 0xf, mask_no & 0xf); 8451708Sstevel } 8461708Sstevel } else 8473941Svenki log_printf("%-9s", no_prop_value); 8481708Sstevel 8491708Sstevel done: 8501708Sstevel log_printf("\n"); 8511708Sstevel return (PICL_WALK_CONTINUE); 8521708Sstevel } 8531708Sstevel 8541708Sstevel void 8551708Sstevel sun4v_display_diaginfo(int flag, Prom_node *root, picl_nodehdl_t plafh) 8561708Sstevel { 8571708Sstevel #ifdef lint 8581708Sstevel flag = flag; 8591708Sstevel root = root; 8601708Sstevel plafh = plafh; 8611708Sstevel #endif 8621708Sstevel /* 8631708Sstevel * This function is intentionally empty 8641708Sstevel */ 8651708Sstevel } 8661708Sstevel 8671708Sstevel void 8681708Sstevel display_boardnum(int num) 8691708Sstevel { 8701708Sstevel log_printf("%2d ", num, 0); 8711708Sstevel } 8723941Svenki 8733941Svenki static void 8743941Svenki sun4v_disp_env_status() 8753941Svenki { 8763941Svenki if (phyplatformh == 0) 8773941Svenki return; 8783941Svenki log_printf("\n"); 8793941Svenki log_printf("============================"); 8803941Svenki log_printf(" Environmental Status "); 8813941Svenki log_printf("============================"); 8823941Svenki log_printf("\n"); 8833941Svenki 8843941Svenki class_node_found = 0; 8853941Svenki all_status_ok = 1; 8863941Svenki sun4v_env_print_fan_sensors(); 8873941Svenki 8883941Svenki class_node_found = 0; 8893941Svenki all_status_ok = 1; 8903941Svenki sun4v_env_print_fan_indicators(); 8913941Svenki 8923941Svenki class_node_found = 0; 8933941Svenki all_status_ok = 1; 8943941Svenki sun4v_env_print_temp_sensors(); 8953941Svenki 8963941Svenki class_node_found = 0; 8973941Svenki all_status_ok = 1; 8983941Svenki sun4v_env_print_temp_indicators(); 8993941Svenki 9003941Svenki class_node_found = 0; 9013941Svenki all_status_ok = 1; 9023941Svenki sun4v_env_print_current_sensors(); 9033941Svenki 9043941Svenki class_node_found = 0; 9053941Svenki all_status_ok = 1; 9063941Svenki sun4v_env_print_current_indicators(); 9073941Svenki 9083941Svenki class_node_found = 0; 9093941Svenki all_status_ok = 1; 9103941Svenki sun4v_env_print_voltage_sensors(); 9113941Svenki 9123941Svenki class_node_found = 0; 9133941Svenki all_status_ok = 1; 9143941Svenki sun4v_env_print_voltage_indicators(); 9153941Svenki 9163941Svenki class_node_found = 0; 9173941Svenki sun4v_env_print_LEDs(); 9183941Svenki 9193941Svenki class_node_found = 0; 9203941Svenki all_status_ok = 1; 9213941Svenki sun4v_print_fru_status(); 9223941Svenki 9233941Svenki class_node_found = 0; 9243941Svenki sun4v_print_fw_rev(); 9253941Svenki 9263941Svenki sun4v_print_chassis_serial_no(); 9273941Svenki } 9283941Svenki 9293941Svenki /*ARGSUSED*/ 9303941Svenki static int 9313941Svenki sun4v_env_print_sensor_callback(picl_nodehdl_t nodeh, void *args) 9323941Svenki { 9333941Svenki char val[PICL_PROPNAMELEN_MAX]; 9343941Svenki picl_nodehdl_t parenth; 9353941Svenki char *names[PARENT_NAMES]; 9363941Svenki char *loc; 9373941Svenki int i; 9383941Svenki char *prop; 9393941Svenki picl_errno_t err; 9403941Svenki int32_t lo_warning, lo_shutdown; 9413941Svenki int32_t hi_warning, hi_shutdown; 9423941Svenki int32_t current_val; 9433941Svenki 9443941Svenki if (class_node_found == 0) { 9453941Svenki class_node_found = 1; 9463941Svenki return (PICL_WALK_TERMINATE); 9473941Svenki } 9483941Svenki 9493941Svenki if (syserrlog == 0) { 9503941Svenki err = picl_get_propval_by_name(nodeh, 951*4669Sfw157321 PICL_PROP_OPERATIONAL_STATUS, val, 952*4669Sfw157321 sizeof (val)); 9533941Svenki if (err == PICL_SUCCESS) { 9543941Svenki if (strcmp(val, "disabled") == 0) { 9553941Svenki if (all_status_ok) { 9563941Svenki all_status_ok = 0; 9573941Svenki return (PICL_WALK_TERMINATE); 9583941Svenki } 9593941Svenki } else 9603941Svenki return (PICL_WALK_CONTINUE); 9613941Svenki } else { 9623941Svenki all_status_ok = 0; 9633941Svenki return (PICL_WALK_TERMINATE); 9643941Svenki } 9653941Svenki } 9663941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth, 967*4669Sfw157321 sizeof (parenth)); 9683941Svenki if (err != PICL_SUCCESS) { 9693941Svenki log_printf("\n"); 9703941Svenki return (PICL_WALK_CONTINUE); 9713941Svenki } 9724003Svivek 9733941Svenki if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) == NULL) 9743941Svenki return (PICL_WALK_TERMINATE); 9753941Svenki for (i = 0; i < PARENT_NAMES; i++) 9763941Svenki if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) == NULL) { 9773941Svenki while (--i > -1) 9783941Svenki free(names[i]); 9793941Svenki free(loc); 9803941Svenki return (PICL_WALK_TERMINATE); 9813941Svenki } 9823941Svenki i = 0; 9833941Svenki while (err == PICL_SUCCESS) { 9843941Svenki if (parenth == chassish || parenth == phyplatformh) 9853941Svenki break; 9863941Svenki err = picl_get_propval_by_name(parenth, PICL_PROP_NAME, 987*4669Sfw157321 names[i++], PICL_PROPNAMELEN_MAX); 9883941Svenki if (err != PICL_SUCCESS) { 9893941Svenki i--; 9903941Svenki break; 9913941Svenki } 9923941Svenki if (i == PARENT_NAMES) 9933941Svenki break; 9943941Svenki err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT, 995*4669Sfw157321 &parenth, sizeof (parenth)); 9963941Svenki } 9973941Svenki loc[0] = '\0'; 9984003Svivek if (--i > -1) { 9994003Svivek (void) strlcat(loc, names[i], 1000*4669Sfw157321 PICL_PROPNAMELEN_MAX * PARENT_NAMES); 10014003Svivek } 10023941Svenki while (--i > -1) { 10034003Svivek (void) strlcat(loc, "/", PICL_PROPNAMELEN_MAX*PARENT_NAMES); 10044003Svivek (void) strlcat(loc, names[i], 1005*4669Sfw157321 PICL_PROPNAMELEN_MAX * PARENT_NAMES); 10063941Svenki } 1007*4669Sfw157321 log_printf("%-21s", loc); 10083941Svenki for (i = 0; i < PARENT_NAMES; i++) 10093941Svenki free(names[i]); 10103941Svenki free(loc); 10113941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, val, 1012*4669Sfw157321 sizeof (val)); 10133941Svenki if (err == PICL_SUCCESS) 10143941Svenki log_printf("%-15s", val); 10153941Svenki 10163941Svenki prop = (char *)args; 10173941Svenki if (!prop) { 10183941Svenki log_printf("\n"); 10193941Svenki return (PICL_WALK_CONTINUE); 10203941Svenki } 10213941Svenki if (picl_get_propval_by_name(nodeh, prop, ¤t_val, 1022*4669Sfw157321 sizeof (current_val)) != PICL_SUCCESS) { 10233941Svenki log_printf("\n"); 10243941Svenki return (PICL_WALK_CONTINUE); 10253941Svenki } 10263941Svenki if (picl_get_propval_by_name(nodeh, PICL_PROP_LOW_WARNING, 1027*4669Sfw157321 &lo_warning, sizeof (lo_warning)) != PICL_SUCCESS) 10283941Svenki lo_warning = INVALID_THRESHOLD; 10293941Svenki if (picl_get_propval_by_name(nodeh, PICL_PROP_LOW_SHUTDOWN, 1030*4669Sfw157321 &lo_shutdown, sizeof (lo_shutdown)) != PICL_SUCCESS) 10313941Svenki lo_shutdown = INVALID_THRESHOLD; 10323941Svenki if (picl_get_propval_by_name(nodeh, PICL_PROP_HIGH_WARNING, 1033*4669Sfw157321 &hi_warning, sizeof (hi_warning)) != PICL_SUCCESS) 10343941Svenki hi_warning = INVALID_THRESHOLD; 10353941Svenki if (picl_get_propval_by_name(nodeh, PICL_PROP_HIGH_SHUTDOWN, 1036*4669Sfw157321 &hi_shutdown, sizeof (hi_shutdown)) != PICL_SUCCESS) 10373941Svenki hi_shutdown = INVALID_THRESHOLD; 10383941Svenki 10393941Svenki if ((lo_shutdown != INVALID_THRESHOLD && 1040*4669Sfw157321 current_val <= lo_shutdown) || 1041*4669Sfw157321 (hi_shutdown != INVALID_THRESHOLD && 1042*4669Sfw157321 current_val >= hi_shutdown)) { 10433941Svenki log_printf("%-s", "failed ("); 10443941Svenki log_printf("%-d", current_val); 10453941Svenki log_printf("%-s", ")"); 10463941Svenki } else if ((lo_warning != INVALID_THRESHOLD && 1047*4669Sfw157321 current_val <= lo_warning) || 1048*4669Sfw157321 (hi_warning != INVALID_THRESHOLD && 1049*4669Sfw157321 current_val >= hi_warning)) { 10503941Svenki log_printf("%-s", "warning ("); 10513941Svenki log_printf("%-d", current_val); 10523941Svenki log_printf("%-s", ")"); 10533941Svenki } else 10543941Svenki log_printf("%-s", "ok"); 10553941Svenki 10563941Svenki log_printf("\n"); 10573941Svenki return (PICL_WALK_CONTINUE); 10583941Svenki } 10593941Svenki 10603941Svenki /*ARGSUSED*/ 10613941Svenki static int 10623941Svenki sun4v_env_print_indicator_callback(picl_nodehdl_t nodeh, void *args) 10633941Svenki { 10643941Svenki char val[PICL_PROPNAMELEN_MAX]; 10653941Svenki char status[PICL_PROPNAMELEN_MAX]; 10663941Svenki picl_nodehdl_t parenth; 10673941Svenki char *names[PARENT_NAMES]; 10683941Svenki char *loc; 10693941Svenki int i = 0; 10703941Svenki char *prop = (char *)args; 10713941Svenki picl_errno_t err = PICL_SUCCESS; 10723941Svenki 10733941Svenki if (class_node_found == 0) { 10743941Svenki class_node_found = 1; 10753941Svenki return (PICL_WALK_TERMINATE); 10763941Svenki } 10773941Svenki if (syserrlog == 0) { 10783941Svenki err = picl_get_propval_by_name(nodeh, 1079*4669Sfw157321 PICL_PROP_OPERATIONAL_STATUS, status, 1080*4669Sfw157321 sizeof (status)); 10813941Svenki if (err == PICL_SUCCESS) { 10823941Svenki if (strcmp(status, "disabled") == 0) { 10833941Svenki if (all_status_ok) { 10843941Svenki all_status_ok = 0; 10853941Svenki return (PICL_WALK_TERMINATE); 10863941Svenki } 10873941Svenki } else 10883941Svenki return (PICL_WALK_CONTINUE); 10893941Svenki } else { 10903941Svenki all_status_ok = 0; 10913941Svenki return (PICL_WALK_TERMINATE); 10923941Svenki } 10933941Svenki } 10943941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth, 1095*4669Sfw157321 sizeof (parenth)); 10963941Svenki if (err != PICL_SUCCESS) { 10973941Svenki log_printf("\n"); 10983941Svenki return (PICL_WALK_CONTINUE); 10993941Svenki } 11003941Svenki if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) == NULL) 11013941Svenki return (PICL_WALK_TERMINATE); 11023941Svenki for (i = 0; i < PARENT_NAMES; i++) 11033941Svenki if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) == NULL) { 11043941Svenki while (--i > -1) 11053941Svenki free(names[i]); 11063941Svenki free(loc); 11073941Svenki return (PICL_WALK_TERMINATE); 11083941Svenki } 11093941Svenki i = 0; 11103941Svenki while (err == PICL_SUCCESS) { 11113941Svenki if (parenth == chassish || parenth == phyplatformh) 11123941Svenki break; 11133941Svenki err = picl_get_propval_by_name(parenth, PICL_PROP_NAME, 1114*4669Sfw157321 names[i++], PICL_PROPNAMELEN_MAX); 11153941Svenki if (err != PICL_SUCCESS) { 11163941Svenki i--; 11173941Svenki break; 11183941Svenki } 11193941Svenki if (i == PARENT_NAMES) 11203941Svenki break; 11213941Svenki err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT, 1122*4669Sfw157321 &parenth, sizeof (parenth)); 11233941Svenki } 11243941Svenki loc[0] = '\0'; 11254003Svivek if (--i > -1) { 11264003Svivek (void) strlcat(loc, names[i], 1127*4669Sfw157321 PICL_PROPNAMELEN_MAX * PARENT_NAMES); 11284003Svivek } 11293941Svenki while (--i > -1) { 11304003Svivek (void) strlcat(loc, "/", PICL_PROPNAMELEN_MAX * PARENT_NAMES); 11314003Svivek (void) strlcat(loc, names[i], 1132*4669Sfw157321 PICL_PROPNAMELEN_MAX * PARENT_NAMES); 11333941Svenki } 1134*4669Sfw157321 log_printf("%-21s", loc); 11353941Svenki for (i = 0; i < PARENT_NAMES; i++) 11363941Svenki free(names[i]); 11373941Svenki free(loc); 11383941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, val, 1139*4669Sfw157321 sizeof (val)); 11403941Svenki if (err == PICL_SUCCESS) 11413941Svenki log_printf("%-15s", val); 11423941Svenki if (syserrlog == 0) { 11433941Svenki log_printf("%-8s", status); 11443941Svenki return (PICL_WALK_CONTINUE); 11453941Svenki } 1146*4669Sfw157321 err = picl_get_propval_by_name(nodeh, prop, val, sizeof (val)); 11473941Svenki if (err == PICL_SUCCESS) 11483941Svenki log_printf("%-8s", val); 11493941Svenki log_printf("\n"); 11503941Svenki return (PICL_WALK_CONTINUE); 11513941Svenki } 11523941Svenki 11533941Svenki static void 11543941Svenki sun4v_env_print_fan_sensors() 11553941Svenki { 1156*4669Sfw157321 char *fmt = "%-20s %-14s %-10s\n"; 11573941Svenki /* 11583941Svenki * If there isn't any fan sensor node, return now. 11593941Svenki */ 11603941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1161*4669Sfw157321 PICL_CLASS_RPM_SENSOR, (void *)PICL_CLASS_RPM_SENSOR, 1162*4669Sfw157321 sun4v_env_print_sensor_callback); 11633941Svenki if (!class_node_found) 11643941Svenki return; 11653941Svenki log_printf("Fan sensors:\n"); 11663941Svenki if (syserrlog == 0) { 11673941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1168*4669Sfw157321 PICL_CLASS_RPM_SENSOR, 1169*4669Sfw157321 NULL, sun4v_env_print_sensor_callback); 11703941Svenki if (all_status_ok) { 11713941Svenki log_printf("All fan sensors are OK.\n"); 11723941Svenki return; 11733941Svenki } 11743941Svenki } 1175*4669Sfw157321 log_printf("------------------------------------------\n"); 11763941Svenki log_printf(fmt, "Location", "Sensor", "Status", 0); 1177*4669Sfw157321 log_printf("------------------------------------------\n"); 11783941Svenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_RPM_SENSOR, 1179*4669Sfw157321 PICL_PROP_SPEED, sun4v_env_print_sensor_callback); 11803941Svenki } 11813941Svenki 11823941Svenki static void 11833941Svenki sun4v_env_print_fan_indicators() 11843941Svenki { 1185*4669Sfw157321 char *fmt = "%-20s %-14s %-10s\n"; 11863941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1187*4669Sfw157321 PICL_CLASS_RPM_INDICATOR, (void *)PICL_CLASS_RPM_INDICATOR, 1188*4669Sfw157321 sun4v_env_print_indicator_callback); 11893941Svenki if (!class_node_found) 11903941Svenki return; 11913941Svenki log_printf("\nFan indicators:\n"); 11923941Svenki if (syserrlog == 0) { 11933941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1194*4669Sfw157321 PICL_CLASS_RPM_INDICATOR, 1195*4669Sfw157321 NULL, sun4v_env_print_indicator_callback); 11963941Svenki if (all_status_ok) { 11973941Svenki log_printf("All fan indicators are OK.\n"); 11983941Svenki return; 11993941Svenki } 12003941Svenki } 1201*4669Sfw157321 log_printf("---------------------------------------------\n"); 12023941Svenki log_printf(fmt, "Location", "Sensor", "Condition", 0); 1203*4669Sfw157321 log_printf("---------------------------------------------\n"); 12043941Svenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_RPM_INDICATOR, 1205*4669Sfw157321 PICL_CLASS_RPM_INDICATOR, sun4v_env_print_indicator_callback); 12063941Svenki } 12073941Svenki 12083941Svenki static void 12093941Svenki sun4v_env_print_temp_sensors() 12103941Svenki { 1211*4669Sfw157321 char *fmt = "%-20s %-14s %-10s\n"; 12123941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1213*4669Sfw157321 PICL_CLASS_TEMPERATURE_SENSOR, 1214*4669Sfw157321 (void *)PICL_PROP_TEMPERATURE, 1215*4669Sfw157321 sun4v_env_print_sensor_callback); 12163941Svenki if (!class_node_found) 12173941Svenki return; 12183941Svenki 12193941Svenki log_printf("\nTemperature sensors:\n"); 12203941Svenki if (syserrlog == 0) { 12213941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1222*4669Sfw157321 PICL_CLASS_TEMPERATURE_SENSOR, 1223*4669Sfw157321 NULL, sun4v_env_print_sensor_callback); 12243941Svenki if (all_status_ok) { 12253941Svenki log_printf("All temperature sensors are OK.\n"); 12263941Svenki return; 12273941Svenki } 12283941Svenki } 1229*4669Sfw157321 log_printf("------------------------------------------\n"); 12303941Svenki log_printf(fmt, "Location", "Sensor", "Status", 0); 1231*4669Sfw157321 log_printf("------------------------------------------\n"); 12323941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1233*4669Sfw157321 PICL_CLASS_TEMPERATURE_SENSOR, 1234*4669Sfw157321 (void *)PICL_PROP_TEMPERATURE, sun4v_env_print_sensor_callback); 12353941Svenki } 12363941Svenki 12373941Svenki static void 12383941Svenki sun4v_env_print_temp_indicators() 12393941Svenki { 1240*4669Sfw157321 char *fmt = "%-20s %-14s %-8s\n"; 12413941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1242*4669Sfw157321 PICL_CLASS_TEMPERATURE_INDICATOR, (void *)PICL_PROP_CONDITION, 1243*4669Sfw157321 sun4v_env_print_indicator_callback); 12443941Svenki if (!class_node_found) 12453941Svenki return; 12463941Svenki log_printf("\nTemperature indicators:\n"); 12473941Svenki if (syserrlog == 0) { 12483941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1249*4669Sfw157321 PICL_CLASS_TEMPERATURE_INDICATOR, NULL, 1250*4669Sfw157321 sun4v_env_print_indicator_callback); 12513941Svenki if (all_status_ok) { 12523941Svenki log_printf("All temperature indicators are OK.\n"); 12533941Svenki return; 12543941Svenki } 12553941Svenki } 1256*4669Sfw157321 log_printf("---------------------------------------\n"); 12573941Svenki log_printf(fmt, "Location", "Indicator", "Condition", 0); 1258*4669Sfw157321 log_printf("---------------------------------------\n"); 12593941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1260*4669Sfw157321 PICL_CLASS_TEMPERATURE_INDICATOR, 1261*4669Sfw157321 (void *)PICL_PROP_CONDITION, 1262*4669Sfw157321 sun4v_env_print_indicator_callback); 12633941Svenki } 12643941Svenki 12653941Svenki static void 12663941Svenki sun4v_env_print_current_sensors() 12673941Svenki { 1268*4669Sfw157321 char *fmt = "%-20s %-14s %-10s\n"; 12693941Svenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_CURRENT_SENSOR, 1270*4669Sfw157321 (void *)PICL_PROP_CURRENT, sun4v_env_print_sensor_callback); 12713941Svenki if (!class_node_found) 12723941Svenki return; 12733941Svenki log_printf("\nCurrent sensors:\n"); 12743941Svenki if (syserrlog == 0) { 12753941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1276*4669Sfw157321 PICL_CLASS_CURRENT_SENSOR, 1277*4669Sfw157321 NULL, sun4v_env_print_sensor_callback); 12783941Svenki if (all_status_ok) { 12793941Svenki log_printf("All current sensors are OK.\n"); 12803941Svenki return; 12813941Svenki } 12823941Svenki } 1283*4669Sfw157321 log_printf("------------------------------------------\n"); 12843941Svenki log_printf(fmt, "Location", "Sensor", "Status", 0); 1285*4669Sfw157321 log_printf("------------------------------------------\n"); 12863941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1287*4669Sfw157321 PICL_CLASS_CURRENT_SENSOR, (void *)PICL_PROP_CURRENT, 1288*4669Sfw157321 sun4v_env_print_sensor_callback); 12893941Svenki } 12903941Svenki 12913941Svenki static void 12923941Svenki sun4v_env_print_current_indicators() 12933941Svenki { 1294*4669Sfw157321 char *fmt = "%-20s %-14s %-8s\n"; 12953941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1296*4669Sfw157321 PICL_CLASS_CURRENT_INDICATOR, 1297*4669Sfw157321 (void *)PICL_PROP_CONDITION, 1298*4669Sfw157321 sun4v_env_print_indicator_callback); 12993941Svenki if (!class_node_found) 13003941Svenki return; 13013941Svenki log_printf("\nCurrent indicators:\n"); 13023941Svenki if (syserrlog == 0) { 13033941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1304*4669Sfw157321 PICL_CLASS_CURRENT_INDICATOR, NULL, 1305*4669Sfw157321 sun4v_env_print_indicator_callback); 13063941Svenki if (all_status_ok) { 13073941Svenki log_printf("All current indicators are OK.\n"); 13083941Svenki return; 13093941Svenki } 13103941Svenki } 1311*4669Sfw157321 log_printf("---------------------------------------------\n"); 13123941Svenki log_printf(fmt, "Location", "Indicator", "Condition", 0); 1313*4669Sfw157321 log_printf("---------------------------------------------\n"); 13143941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1315*4669Sfw157321 PICL_CLASS_CURRENT_INDICATOR, 1316*4669Sfw157321 (void *)PICL_PROP_CONDITION, 1317*4669Sfw157321 sun4v_env_print_indicator_callback); 13183941Svenki } 13193941Svenki 13203941Svenki static void 13213941Svenki sun4v_env_print_voltage_sensors() 13223941Svenki { 1323*4669Sfw157321 char *fmt = "%-20s %-14s %-10s\n"; 13243941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1325*4669Sfw157321 PICL_CLASS_VOLTAGE_SENSOR, 1326*4669Sfw157321 PICL_PROP_VOLTAGE, 1327*4669Sfw157321 sun4v_env_print_sensor_callback); 13283941Svenki if (!class_node_found) 13293941Svenki return; 13303941Svenki log_printf("\nVoltage sensors:\n"); 13313941Svenki if (syserrlog == 0) { 13323941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1333*4669Sfw157321 PICL_CLASS_VOLTAGE_SENSOR, 1334*4669Sfw157321 NULL, sun4v_env_print_sensor_callback); 13353941Svenki if (all_status_ok) { 13363941Svenki log_printf("All voltage sensors are OK.\n"); 13373941Svenki return; 13383941Svenki } 13393941Svenki } 1340*4669Sfw157321 log_printf("------------------------------------------\n"); 13413941Svenki log_printf(fmt, "Location", "Sensor", "Status", 0); 1342*4669Sfw157321 log_printf("------------------------------------------\n"); 13433941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1344*4669Sfw157321 PICL_CLASS_VOLTAGE_SENSOR, 1345*4669Sfw157321 (void *)PICL_PROP_VOLTAGE, 1346*4669Sfw157321 sun4v_env_print_sensor_callback); 13473941Svenki } 13483941Svenki 13493941Svenki static void 13503941Svenki sun4v_env_print_voltage_indicators() 13513941Svenki { 1352*4669Sfw157321 char *fmt = "%-20s %-14s %-8s\n"; 13533941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1354*4669Sfw157321 PICL_CLASS_VOLTAGE_INDICATOR, 1355*4669Sfw157321 (void *)PICL_PROP_CONDITION, 1356*4669Sfw157321 sun4v_env_print_indicator_callback); 13573941Svenki if (!class_node_found) 13583941Svenki return; 13593941Svenki log_printf("\nVoltage indicators:\n"); 13603941Svenki if (syserrlog == 0) { 13613941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1362*4669Sfw157321 PICL_CLASS_VOLTAGE_INDICATOR, NULL, 1363*4669Sfw157321 sun4v_env_print_indicator_callback); 13643941Svenki if (all_status_ok) { 13653941Svenki log_printf("All voltage indicators are OK.\n"); 13663941Svenki return; 13673941Svenki } 13683941Svenki } 1369*4669Sfw157321 log_printf("---------------------------------------------\n"); 13703941Svenki log_printf(fmt, "Location", "Indicator", "Condition", 0); 1371*4669Sfw157321 log_printf("---------------------------------------------\n"); 13723941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1373*4669Sfw157321 PICL_CLASS_VOLTAGE_INDICATOR, 1374*4669Sfw157321 (void *)PICL_PROP_CONDITION, 1375*4669Sfw157321 sun4v_env_print_indicator_callback); 13763941Svenki } 13773941Svenki 13783941Svenki static void 13793941Svenki sun4v_env_print_LEDs() 13803941Svenki { 1381*4669Sfw157321 char *fmt = "%-20s %-14s %-8s\n"; 13823941Svenki if (syserrlog == 0) 13833941Svenki return; 13843941Svenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_LED, 1385*4669Sfw157321 (void *)PICL_PROP_STATE, sun4v_env_print_indicator_callback); 13863941Svenki if (!class_node_found) 13873941Svenki return; 13883941Svenki log_printf("\nLEDs:\n"); 1389*4669Sfw157321 log_printf("-----------------------------------------\n"); 13903941Svenki log_printf(fmt, "Location", "LED", "State", 0); 1391*4669Sfw157321 log_printf("-----------------------------------------\n"); 13923941Svenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_LED, 1393*4669Sfw157321 (void *)PICL_PROP_STATE, sun4v_env_print_indicator_callback); 13943941Svenki } 13953941Svenki 13963941Svenki /*ARGSUSED*/ 13973941Svenki static int 13983941Svenki sun4v_print_fru_status_callback(picl_nodehdl_t nodeh, void *args) 13993941Svenki { 14003941Svenki char label[PICL_PROPNAMELEN_MAX]; 14013941Svenki char status[PICL_PROPNAMELEN_MAX]; 14023941Svenki picl_errno_t err; 14033941Svenki picl_prophdl_t proph; 14043941Svenki picl_nodehdl_t parenth; 14053941Svenki char *names[PARENT_NAMES]; 14063941Svenki char *loc; 14073941Svenki int i; 14083941Svenki 14093941Svenki if (!class_node_found) { 14103941Svenki class_node_found = 1; 14113941Svenki return (PICL_WALK_TERMINATE); 14123941Svenki } 14133941Svenki err = picl_get_prop_by_name(nodeh, PICL_PROP_IS_FRU, &proph); 14143941Svenki if (err != PICL_SUCCESS) 14153941Svenki return (PICL_WALK_CONTINUE); 14163941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, label, 1417*4669Sfw157321 sizeof (label)); 14183941Svenki if (err != PICL_SUCCESS) 14193941Svenki return (PICL_WALK_CONTINUE); 14203941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_OPERATIONAL_STATUS, 1421*4669Sfw157321 status, sizeof (status)); 14223941Svenki if (err != PICL_SUCCESS) 14233941Svenki return (PICL_WALK_CONTINUE); 14243941Svenki if (syserrlog == 0) { 14253941Svenki if (strcmp(status, "disabled") == 0) { 14263941Svenki if (all_status_ok) { 14273941Svenki all_status_ok = 0; 14283941Svenki return (PICL_WALK_TERMINATE); 14293941Svenki } 14303941Svenki } else 14313941Svenki return (PICL_WALK_CONTINUE); 14323941Svenki } 14333941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth, 1434*4669Sfw157321 sizeof (parenth)); 14353941Svenki if (err != PICL_SUCCESS) { 14363941Svenki log_printf("\n"); 14373941Svenki return (PICL_WALK_CONTINUE); 14383941Svenki } 14393941Svenki if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) == NULL) 14403941Svenki return (PICL_WALK_TERMINATE); 14413941Svenki for (i = 0; i < PARENT_NAMES; i++) 14423941Svenki if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) == NULL) { 14433941Svenki while (--i > -1) 14443941Svenki free(names[i]); 14453941Svenki free(loc); 14463941Svenki return (PICL_WALK_TERMINATE); 14473941Svenki } 14483941Svenki i = 0; 14493941Svenki while (err == PICL_SUCCESS) { 14503941Svenki if (parenth == chassish || parenth == phyplatformh) 14513941Svenki break; 14523941Svenki err = picl_get_propval_by_name(parenth, PICL_PROP_NAME, 1453*4669Sfw157321 names[i++], PICL_PROPNAMELEN_MAX); 14543941Svenki if (err != PICL_SUCCESS) { 14553941Svenki i--; 14563941Svenki break; 14573941Svenki } 14583941Svenki if (i == PARENT_NAMES) 14593941Svenki break; 14603941Svenki err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT, 1461*4669Sfw157321 &parenth, sizeof (parenth)); 14623941Svenki } 14633941Svenki loc[0] = '\0'; 14644003Svivek if (--i > -1) { 14654003Svivek (void) strlcat(loc, names[i], 1466*4669Sfw157321 PICL_PROPNAMELEN_MAX * PARENT_NAMES); 14674003Svivek } 14683941Svenki while (--i > -1) { 14694003Svivek (void) strlcat(loc, "/", PICL_PROPNAMELEN_MAX * PARENT_NAMES); 14704003Svivek (void) strlcat(loc, names[i], 1471*4669Sfw157321 PICL_PROPNAMELEN_MAX * PARENT_NAMES); 14723941Svenki } 14733941Svenki log_printf("%-21s", loc); 14743941Svenki for (i = 0; i < PARENT_NAMES; i++) 14753941Svenki free(names[i]); 14763941Svenki free(loc); 14773941Svenki log_printf("%-10s", label); 14783941Svenki log_printf("%-9s", status); 14793941Svenki log_printf("\n"); 14803941Svenki return (PICL_WALK_CONTINUE); 14813941Svenki } 14823941Svenki 14833941Svenki static void 14843941Svenki sun4v_print_fru_status() 14853941Svenki { 14863941Svenki char *fmt = "%-20s %-9s %-8s\n"; 14873941Svenki (void) picl_walk_tree_by_class(phyplatformh, NULL, NULL, 1488*4669Sfw157321 sun4v_print_fru_status_callback); 14893941Svenki if (!class_node_found) 14903941Svenki return; 14913941Svenki log_printf("\n"); 14923941Svenki log_printf("============================"); 14933941Svenki log_printf(" FRU Status "); 14943941Svenki log_printf("============================"); 14953941Svenki log_printf("\n"); 14963941Svenki 14973941Svenki if (syserrlog == 0) { 14983941Svenki (void) picl_walk_tree_by_class(phyplatformh, 1499*4669Sfw157321 PICL_CLASS_MODULE, NULL, 1500*4669Sfw157321 sun4v_print_fru_status_callback); 15013941Svenki if (all_status_ok) { 15023941Svenki log_printf("All FRUs are enabled.\n"); 15033941Svenki return; 15043941Svenki } 15053941Svenki } 15063941Svenki log_printf(fmt, "Location", "Name", "Status", 0); 1507*4669Sfw157321 log_printf("----------------------------------------\n"); 15083941Svenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_MODULE, NULL, 1509*4669Sfw157321 sun4v_print_fru_status_callback); 15103941Svenki } 15113941Svenki 15123941Svenki /*ARGSUSED*/ 15133941Svenki static int 15143941Svenki sun4v_print_fw_rev_callback(picl_nodehdl_t nodeh, void *args) 15153941Svenki { 15163941Svenki char label[PICL_PROPNAMELEN_MAX]; 15173941Svenki char rev[PICL_PROPNAMELEN_MAX]; 15183941Svenki picl_errno_t err; 15193941Svenki 15203941Svenki if (!class_node_found) { 15213941Svenki class_node_found = 1; 15223941Svenki return (PICL_WALK_TERMINATE); 15233941Svenki } 15243941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, label, 1525*4669Sfw157321 sizeof (label)); 15263941Svenki if (err != PICL_SUCCESS) 15273941Svenki return (PICL_WALK_CONTINUE); 15283941Svenki err = picl_get_propval_by_name(nodeh, PICL_PROP_FW_REVISION, rev, 1529*4669Sfw157321 sizeof (rev)); 15303941Svenki if (err != PICL_SUCCESS) 15313941Svenki return (PICL_WALK_CONTINUE); 15323941Svenki if (strlen(rev) == 0) 15333941Svenki return (PICL_WALK_CONTINUE); 15343941Svenki log_printf("%-21s", label); 15353941Svenki log_printf("%-40s", rev); 15363941Svenki log_printf("\n"); 15373941Svenki return (PICL_WALK_CONTINUE); 15383941Svenki } 15393941Svenki 15403941Svenki static void 15413941Svenki sun4v_print_fw_rev() 15423941Svenki { 15433941Svenki char *fmt = "%-20s %-10s\n"; 15443941Svenki if (syserrlog == 0) 15453941Svenki return; 15463941Svenki (void) picl_walk_tree_by_class(phyplatformh, NULL, NULL, 1547*4669Sfw157321 sun4v_print_fw_rev_callback); 15483941Svenki if (!class_node_found) 15493941Svenki return; 15503941Svenki log_printf("\n"); 15513941Svenki log_printf("============================"); 15523941Svenki log_printf(" FW Version "); 15533941Svenki log_printf("============================"); 15543941Svenki log_printf("\n"); 15553941Svenki log_printf(fmt, "Name", "Version", 0); 15563941Svenki log_printf("----------------------------\n"); 15573941Svenki (void) picl_walk_tree_by_class(phyplatformh, NULL, NULL, 1558*4669Sfw157321 sun4v_print_fw_rev_callback); 15593941Svenki } 15603941Svenki 15613941Svenki static void 15623941Svenki sun4v_print_chassis_serial_no() 15633941Svenki { 15643941Svenki char val[PICL_PROPNAMELEN_MAX]; 15653941Svenki picl_errno_t err; 15663941Svenki if (syserrlog == 0 || chassish == 0) 15673941Svenki return; 15683941Svenki 15693941Svenki log_printf("\n"); 15703941Svenki log_printf("Chassis Serial Number"); 15713941Svenki log_printf("\n"); 15723941Svenki log_printf("---------------------\n"); 15733941Svenki err = picl_get_propval_by_name(chassish, PICL_PROP_SERIAL_NUMBER, 1574*4669Sfw157321 val, sizeof (val)); 15753941Svenki if (err == PICL_SUCCESS) 15763941Svenki log_printf("%s", val); 15773941Svenki log_printf("\n"); 15783941Svenki } 1579