11708Sstevel /*
21708Sstevel * CDDL HEADER START
31708Sstevel *
41708Sstevel * The contents of this file are subject to the terms of the
51708Sstevel * Common Development and Distribution License (the "License").
61708Sstevel * 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
221708Sstevel /*
23*13019SMichael.Bergknoff@Oracle.COM * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
241708Sstevel */
251708Sstevel
261708Sstevel #include <stdio.h>
271708Sstevel #include <stdlib.h>
281708Sstevel #include <string.h>
291708Sstevel #include <alloca.h>
301708Sstevel #include <errno.h>
311708Sstevel #include <libintl.h>
321708Sstevel #include <sys/utsname.h>
331708Sstevel #include <sys/types.h>
341708Sstevel #include <sys/stat.h>
351708Sstevel #include <sys/openpromio.h>
361708Sstevel #include <sys/ddi.h>
371708Sstevel #include <syslog.h>
381708Sstevel #include <fcntl.h>
391708Sstevel #include <dirent.h>
401708Sstevel #include <unistd.h>
411708Sstevel #include <locale.h>
421708Sstevel #include <picl.h>
431708Sstevel #include "pdevinfo.h"
441708Sstevel #include "display.h"
451708Sstevel #include "display_sun4u.h"
461708Sstevel #include "picldefs.h"
471708Sstevel #include "libprtdiag.h"
481708Sstevel
491708Sstevel #if !defined(TEXT_DOMAIN)
501708Sstevel #define TEXT_DOMAIN "SYS_TEST"
511708Sstevel #endif
521708Sstevel
531708Sstevel #define EM_INIT_FAIL dgettext(TEXT_DOMAIN,\
541708Sstevel "picl_initialize failed: %s\n")
551708Sstevel #define EM_GET_ROOT_FAIL dgettext(TEXT_DOMAIN,\
561708Sstevel "Getting root node failed: %s\n")
571708Sstevel #define EM_PRTDIAG_FAIL dgettext(TEXT_DOMAIN, "Prtdiag failed!\n")
581708Sstevel
591708Sstevel #define SIGN_ON_MSG dgettext(TEXT_DOMAIN,\
60*13019SMichael.Bergknoff@Oracle.COM "System Configuration: Oracle Corporation ")
611708Sstevel #define SYSCLK_FREQ_MSG dgettext(TEXT_DOMAIN,\
621708Sstevel "System clock frequency: %d MHZ\n")
631708Sstevel #define MEM_SIZE_MSG dgettext(TEXT_DOMAIN, "Memory size: ")
641708Sstevel #define FFB_DOUBLE_BUF dgettext(TEXT_DOMAIN, "FFB, Double Buffered")
651708Sstevel #define FFB_SINGLE_BUF dgettext(TEXT_DOMAIN, "FFB, Single Buffered")
661708Sstevel
671708Sstevel #define DEFAULT_BOARD_NUM 0
681708Sstevel #define DEFAULT_PORTID 0
691708Sstevel #define CLK_FREQ_66MHZ 66
701708Sstevel #define USB -1
711708Sstevel #define HUB -2
721708Sstevel
731708Sstevel /* bus id */
741708Sstevel #define SBUS_TYPE 0
751708Sstevel #define PCI_TYPE 1
761708Sstevel #define UPA_TYPE 2
771708Sstevel
781708Sstevel #define UPA_NAME "upa"
791708Sstevel
801708Sstevel /*
811708Sstevel * PICL classes
821708Sstevel */
831708Sstevel #define PICL_CLASS_OPTIONS "options"
841708Sstevel
851708Sstevel /*
861708Sstevel * Property names
871708Sstevel */
881708Sstevel
891708Sstevel #define OBP_PROP_REG "reg"
901708Sstevel #define OBP_PROP_CLOCK_FREQ "clock-frequency"
911708Sstevel #define OBP_PROP_BOARD_NUM "board#"
921708Sstevel #define OBP_PROP_REVISION_ID "revision-id"
931708Sstevel #define OBP_PROP_VERSION_NUM "version#"
941708Sstevel #define OBP_PROP_BOARD_TYPE "board_type"
951708Sstevel #define OBP_PROP_ECACHE_SIZE "ecache-size"
961708Sstevel #define OBP_PROP_L2_CACHE_SIZE "l2-cache-size"
971708Sstevel #define OBP_PROP_L3_CACHE_SIZE "l3-cache-size"
981708Sstevel #define OBP_PROP_IMPLEMENTATION "implementation#"
991708Sstevel #define OBP_PROP_MASK "mask#"
1001708Sstevel #define OBP_PROP_COMPATIBLE "compatible"
1011708Sstevel #define OBP_PROP_STATUS "status"
1021708Sstevel #define OBP_PROP_BANNER_NAME "banner-name"
1031708Sstevel #define OBP_PROP_MODEL "model"
1041708Sstevel #define OBP_PROP_66MHZ_CAPABLE "66mhz-capable"
1051708Sstevel #define OBP_PROP_FBC_REG_ID "fbc_reg_id"
1061708Sstevel #define OBP_PROP_VERSION "version"
1071708Sstevel
1081708Sstevel #define PROP_POWERFAIL_TIME "powerfail-time"
1091708Sstevel #define PICL_PROP_LOW_WARNING_THRESHOLD "LowWarningThreshold"
1101708Sstevel
1111708Sstevel #define DEFAULT_LINE_WIDTH 85
1121708Sstevel #define HEADING_SYMBOL "="
1131708Sstevel
1141708Sstevel #define MAX_IWAYS 32
1151708Sstevel
1161708Sstevel typedef struct bank_list {
1171708Sstevel picl_nodehdl_t nodeh;
1181708Sstevel uint32_t iway_count;
1191708Sstevel uint32_t iway[MAX_IWAYS];
1201708Sstevel struct bank_list *next;
1211708Sstevel } bank_list_t;
1221708Sstevel
1231708Sstevel typedef struct {
1241708Sstevel uint64_t base;
1251708Sstevel uint64_t size;
1261708Sstevel int ifactor;
1271708Sstevel int bank_count;
1281708Sstevel } seg_info_t;
1291708Sstevel
1301708Sstevel static struct io_card *io_card_list = NULL; /* The head of the IO card list */
1311708Sstevel static bank_list_t *mem_banks = NULL;
1321708Sstevel static int mem_xfersize;
1331708Sstevel static int no_xfer_size = 0;
1341708Sstevel
1351708Sstevel static char *io_device_table[] = {
1361708Sstevel "block",
1371708Sstevel "disk",
1381708Sstevel "cdrom",
1391708Sstevel "floppy",
1401708Sstevel "tape",
1411708Sstevel "network",
1421708Sstevel "display",
1431708Sstevel "serial",
1441708Sstevel "parallel",
1451708Sstevel "scsi",
1461708Sstevel "scsi-2",
1471708Sstevel "scsi-3",
1481708Sstevel "ide",
1491708Sstevel "fcal",
1501708Sstevel "keyboard",
1511708Sstevel "mouse",
1521708Sstevel "dma"
1531708Sstevel };
1541708Sstevel
1551708Sstevel #define NIODEVICE sizeof (io_device_table) / sizeof (io_device_table[0])
1561708Sstevel
1571708Sstevel static char *bus_table[] = {
1581708Sstevel "ebus",
1591708Sstevel "isa",
1601708Sstevel "pmu"
1611708Sstevel };
1621708Sstevel
1631708Sstevel #define NBUS sizeof (bus_table) / sizeof (bus_table[0])
1641708Sstevel
1653873Skd93003 /* prtdiag exit codes */
1663873Skd93003 #define PD_SUCCESS 0
1673873Skd93003 #define PD_SYSTEM_FAILURE 1
1683873Skd93003 #define PD_INTERNAL_FAILURE 2
1693873Skd93003
1703873Skd93003 /*
1713873Skd93003 * Use of global assumes do_prominfo only called from main in prtdiag and
1723873Skd93003 * access does not need to be multi-thread safe.
1733873Skd93003 */
1743873Skd93003 static int exit_code = PD_SUCCESS;
1753873Skd93003
1763873Skd93003 /*
1773873Skd93003 * This function is called from every location where a status value is output.
1783873Skd93003 * It checks the status arg and sets exit_code if an error is detected.
1793873Skd93003 * The status is typically returned from a PICL query. A case-insensitive
1803873Skd93003 * string comparison is done to check for any status that starts with "fail"
1813873Skd93003 * or "fault".
1823873Skd93003 */
1833873Skd93003 static void
set_exit_code(char * status)1843873Skd93003 set_exit_code(char *status)
1853873Skd93003 {
1863873Skd93003 if (status == NULL)
1873873Skd93003 return;
1883873Skd93003
1893873Skd93003 if (strncasecmp(status, "fail", 4) == 0 ||
1903873Skd93003 strncasecmp(status, "fault", 5) == 0)
1913873Skd93003 exit_code = PD_SYSTEM_FAILURE;
1923873Skd93003 }
1933873Skd93003
1941708Sstevel /*
1951708Sstevel * check if it is an IO deice
1961708Sstevel */
1971708Sstevel static int
is_io_device(char * device_class)1981708Sstevel is_io_device(char *device_class)
1991708Sstevel {
2001708Sstevel int i;
2011708Sstevel
2021708Sstevel for (i = 0; i < NIODEVICE; i++) {
203*13019SMichael.Bergknoff@Oracle.COM if (strcmp(device_class, io_device_table[i]) == 0)
204*13019SMichael.Bergknoff@Oracle.COM return (1);
2051708Sstevel }
2061708Sstevel
2071708Sstevel return (0);
2081708Sstevel }
2091708Sstevel
2101708Sstevel /*
2111708Sstevel * check if it is a bus
2121708Sstevel */
2131708Sstevel static int
is_bus(char * device_class)2141708Sstevel is_bus(char *device_class)
2151708Sstevel {
2161708Sstevel int i;
2171708Sstevel
2181708Sstevel for (i = 0; i < NBUS; i++) {
219*13019SMichael.Bergknoff@Oracle.COM if (strcmp(device_class, bus_table[i]) == 0)
220*13019SMichael.Bergknoff@Oracle.COM return (1);
2211708Sstevel }
2221708Sstevel
2231708Sstevel return (0);
2241708Sstevel }
2251708Sstevel
2261708Sstevel /*
2271708Sstevel * search children to get the node by the nodename
2281708Sstevel */
2291708Sstevel static int
picldiag_get_node_by_name(picl_nodehdl_t rooth,char * name,picl_nodehdl_t * nodeh)2301708Sstevel picldiag_get_node_by_name(picl_nodehdl_t rooth, char *name,
2311708Sstevel picl_nodehdl_t *nodeh)
2321708Sstevel {
2331708Sstevel picl_nodehdl_t childh;
2341708Sstevel int err;
2351708Sstevel char *nodename;
2361708Sstevel
2371708Sstevel nodename = alloca(strlen(name) + 1);
2381708Sstevel if (nodename == NULL)
2391708Sstevel return (PICL_FAILURE);
2401708Sstevel
2411708Sstevel err = picl_get_propval_by_name(rooth, PICL_PROP_CHILD, &childh,
2421708Sstevel sizeof (picl_nodehdl_t));
2431708Sstevel
2441708Sstevel while (err == PICL_SUCCESS) {
2451708Sstevel err = picl_get_propval_by_name(childh, PICL_PROP_NAME,
2461708Sstevel nodename, (strlen(name) + 1));
2471708Sstevel if (err != PICL_SUCCESS) {
2481708Sstevel err = picl_get_propval_by_name(childh, PICL_PROP_PEER,
249*13019SMichael.Bergknoff@Oracle.COM &childh, sizeof (picl_nodehdl_t));
2501708Sstevel continue;
2511708Sstevel }
2521708Sstevel
2531708Sstevel if (strcmp(nodename, name) == 0) {
2541708Sstevel *nodeh = childh;
2551708Sstevel return (PICL_SUCCESS);
2561708Sstevel }
2571708Sstevel
2581708Sstevel err = picl_get_propval_by_name(childh, PICL_PROP_PEER,
2591708Sstevel &childh, sizeof (picl_nodehdl_t));
2601708Sstevel }
2611708Sstevel
2621708Sstevel return (err);
2631708Sstevel }
2641708Sstevel
2651708Sstevel /*
2661708Sstevel * get the value by the property name of the string prop
2671708Sstevel * Caller must free the outbuf
2681708Sstevel */
2691708Sstevel static int
picldiag_get_string_propval(picl_nodehdl_t modh,char * prop_name,char ** outbuf)2701708Sstevel picldiag_get_string_propval(picl_nodehdl_t modh, char *prop_name, char **outbuf)
2711708Sstevel {
2721708Sstevel int err;
2731708Sstevel picl_prophdl_t proph;
2741708Sstevel picl_propinfo_t pinfo;
2751708Sstevel char *prop_value;
2761708Sstevel
2771708Sstevel err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
2781708Sstevel if (err != PICL_SUCCESS)
2791708Sstevel return (err);
2801708Sstevel
2811708Sstevel /*
2821708Sstevel * If it is not a string prop, return NULL
2831708Sstevel */
2841708Sstevel if (pinfo.type != PICL_PTYPE_CHARSTRING)
285*13019SMichael.Bergknoff@Oracle.COM return (PICL_FAILURE);
2861708Sstevel
2871708Sstevel prop_value = malloc(pinfo.size);
2881708Sstevel if (prop_value == NULL)
2891708Sstevel return (PICL_FAILURE);
2901708Sstevel
2911708Sstevel err = picl_get_propval(proph, prop_value, pinfo.size);
2921708Sstevel if (err != PICL_SUCCESS) {
2931708Sstevel free(prop_value);
2941708Sstevel return (err);
2951708Sstevel }
2961708Sstevel
2971708Sstevel *outbuf = prop_value;
2981708Sstevel return (PICL_SUCCESS);
2991708Sstevel }
3001708Sstevel
3011708Sstevel
3021708Sstevel /*
3031708Sstevel * return the value as a signed integer
3041708Sstevel */
3051708Sstevel
3061708Sstevel static int64_t
picldiag_get_int_propval(picl_nodehdl_t modh,char * prop_name,int * ret)3071708Sstevel picldiag_get_int_propval(picl_nodehdl_t modh, char *prop_name, int *ret)
3081708Sstevel {
3091708Sstevel int err;
3101708Sstevel picl_prophdl_t proph;
3111708Sstevel picl_propinfo_t pinfo;
3121708Sstevel int8_t int8v;
3131708Sstevel int16_t int16v;
3141708Sstevel int32_t int32v;
3151708Sstevel int64_t int64v;
3161708Sstevel
3171708Sstevel err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
3181708Sstevel if (err != PICL_SUCCESS) {
3191708Sstevel *ret = err;
3201708Sstevel return (0);
3211708Sstevel }
3221708Sstevel
3231708Sstevel /*
3241708Sstevel * If it is not an int or uint prop, return failure
3251708Sstevel */
3261708Sstevel if ((pinfo.type != PICL_PTYPE_INT) &&
327*13019SMichael.Bergknoff@Oracle.COM (pinfo.type != PICL_PTYPE_UNSIGNED_INT)) {
3281708Sstevel *ret = PICL_FAILURE;
3291708Sstevel return (0);
3301708Sstevel }
3311708Sstevel
3321708Sstevel switch (pinfo.size) {
3331708Sstevel case sizeof (int8_t):
3341708Sstevel err = picl_get_propval(proph, &int8v, sizeof (int8v));
3351708Sstevel *ret = err;
3361708Sstevel return (int8v);
3371708Sstevel case sizeof (int16_t):
3381708Sstevel err = picl_get_propval(proph, &int16v, sizeof (int16v));
3391708Sstevel *ret = err;
3401708Sstevel return (int16v);
3411708Sstevel case sizeof (int32_t):
3421708Sstevel err = picl_get_propval(proph, &int32v, sizeof (int32v));
3431708Sstevel *ret = err;
3441708Sstevel return (int32v);
3451708Sstevel case sizeof (int64_t):
3461708Sstevel err = picl_get_propval(proph, &int64v, sizeof (int64v));
3471708Sstevel *ret = err;
3481708Sstevel return (int64v);
3491708Sstevel default: /* not supported size */
3501708Sstevel *ret = PICL_FAILURE;
3511708Sstevel return (0);
3521708Sstevel }
3531708Sstevel }
3541708Sstevel
3551708Sstevel /*
3561708Sstevel * return the value of the uint prop
3571708Sstevel */
3581708Sstevel static uint64_t
picldiag_get_uint_propval(picl_nodehdl_t modh,char * prop_name,int * ret)3591708Sstevel picldiag_get_uint_propval(picl_nodehdl_t modh, char *prop_name, int *ret)
3601708Sstevel {
3611708Sstevel int err;
3621708Sstevel picl_prophdl_t proph;
3631708Sstevel picl_propinfo_t pinfo;
3641708Sstevel uint8_t uint8v;
3651708Sstevel uint16_t uint16v;
3661708Sstevel uint32_t uint32v;
3671708Sstevel uint64_t uint64v;
3681708Sstevel
3691708Sstevel err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
3701708Sstevel if (err != PICL_SUCCESS) {
3711708Sstevel *ret = err;
3721708Sstevel return (0);
3731708Sstevel }
3741708Sstevel
3751708Sstevel /*
3761708Sstevel * If it is not an int or uint prop, return failure
3771708Sstevel */
3781708Sstevel if ((pinfo.type != PICL_PTYPE_INT) &&
379*13019SMichael.Bergknoff@Oracle.COM (pinfo.type != PICL_PTYPE_UNSIGNED_INT)) {
3801708Sstevel *ret = PICL_FAILURE;
3811708Sstevel return (0);
3821708Sstevel }
3831708Sstevel
3841708Sstevel /* uint prop */
3851708Sstevel
3861708Sstevel switch (pinfo.size) {
3871708Sstevel case sizeof (uint8_t):
3881708Sstevel err = picl_get_propval(proph, &uint8v, sizeof (uint8v));
3891708Sstevel *ret = err;
3901708Sstevel return (uint8v);
3911708Sstevel case sizeof (uint16_t):
3921708Sstevel err = picl_get_propval(proph, &uint16v, sizeof (uint16v));
3931708Sstevel *ret = err;
3941708Sstevel return (uint16v);
3951708Sstevel case sizeof (uint32_t):
3961708Sstevel err = picl_get_propval(proph, &uint32v, sizeof (uint32v));
3971708Sstevel *ret = err;
3981708Sstevel return (uint32v);
3991708Sstevel case sizeof (uint64_t):
4001708Sstevel err = picl_get_propval(proph, &uint64v, sizeof (uint64v));
4011708Sstevel *ret = err;
4021708Sstevel return (uint64v);
4031708Sstevel default: /* not supported size */
4041708Sstevel *ret = PICL_FAILURE;
4051708Sstevel return (0);
4061708Sstevel }
4071708Sstevel }
4081708Sstevel
4091708Sstevel /*
4101708Sstevel * return the value of the float prop
4111708Sstevel */
4121708Sstevel static float
picldiag_get_float_propval(picl_nodehdl_t modh,char * prop_name,int * ret)4131708Sstevel picldiag_get_float_propval(picl_nodehdl_t modh, char *prop_name, int *ret)
4141708Sstevel {
4151708Sstevel int err;
4161708Sstevel picl_prophdl_t proph;
4171708Sstevel picl_propinfo_t pinfo;
4181708Sstevel float floatv;
4191708Sstevel
4201708Sstevel err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
4211708Sstevel if (err != PICL_SUCCESS) {
4221708Sstevel *ret = err;
4231708Sstevel return ((float)0);
4241708Sstevel }
4251708Sstevel
4261708Sstevel /*
4271708Sstevel * If it is not a float prop, return failure
4281708Sstevel */
4291708Sstevel if (pinfo.type != PICL_PTYPE_FLOAT) {
4301708Sstevel *ret = PICL_FAILURE;
4311708Sstevel return ((float)0);
4321708Sstevel }
4331708Sstevel
4341708Sstevel *ret = picl_get_propval(proph, &floatv, sizeof (floatv));
4351708Sstevel return (floatv);
4361708Sstevel }
4371708Sstevel
4381708Sstevel /*
4391708Sstevel * get the clock frequency
4401708Sstevel */
4411708Sstevel static int
picldiag_get_clock_freq(picl_nodehdl_t modh,uint32_t * freq)4421708Sstevel picldiag_get_clock_freq(picl_nodehdl_t modh, uint32_t *freq)
4431708Sstevel {
4441708Sstevel #define ROUND_TO_MHZ(x) (((x) + 500000)/ 1000000)
4451708Sstevel int err;
4461708Sstevel uint64_t clk_freq;
4471708Sstevel
4481708Sstevel clk_freq = picldiag_get_uint_propval(modh, OBP_PROP_CLOCK_FREQ, &err);
4491708Sstevel if (err != PICL_SUCCESS)
4501708Sstevel return (err);
4511708Sstevel
4521708Sstevel *freq = ROUND_TO_MHZ(clk_freq);
4531708Sstevel
4541708Sstevel return (PICL_SUCCESS);
4551708Sstevel }
4561708Sstevel
4571708Sstevel /*
4581708Sstevel * get the clock frequency from parent
4591708Sstevel */
4601708Sstevel static int
picldiag_get_clock_from_parent(picl_nodehdl_t nodeh,uint32_t * clk)4611708Sstevel picldiag_get_clock_from_parent(picl_nodehdl_t nodeh, uint32_t *clk)
4621708Sstevel {
4631708Sstevel picl_nodehdl_t parenth;
4641708Sstevel int err;
4651708Sstevel
4661708Sstevel
4671708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT,
4681708Sstevel &parenth, sizeof (parenth));
4691708Sstevel
4701708Sstevel while (err == PICL_SUCCESS) {
4711708Sstevel err = picldiag_get_clock_freq(parenth, clk);
4721708Sstevel if (err != PICL_PROPNOTFOUND)
4731708Sstevel return (err);
4741708Sstevel
4751708Sstevel err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT,
4761708Sstevel &parenth, sizeof (parenth));
4771708Sstevel }
4781708Sstevel
4791708Sstevel return (err);
4801708Sstevel }
4811708Sstevel
4821708Sstevel /*
4831708Sstevel * get _fru_parent prop
4841708Sstevel * If not found, then travese superiors (parent nodes) until
4851708Sstevel * a _fru_parent property is found.
4861708Sstevel * If not found, no fru parent
4871708Sstevel */
4881708Sstevel static int
picldiag_get_fru_parent(picl_nodehdl_t nodeh,picl_nodehdl_t * fruparenth)4891708Sstevel picldiag_get_fru_parent(picl_nodehdl_t nodeh, picl_nodehdl_t *fruparenth)
4901708Sstevel {
4911708Sstevel picl_nodehdl_t fruh;
4921708Sstevel int err;
4931708Sstevel
4941708Sstevel /* find fru parent */
4951708Sstevel err = picl_get_propval_by_name(nodeh, PICL_REFPROP_FRU_PARENT,
4961708Sstevel &fruh, sizeof (fruh));
4971708Sstevel
4981708Sstevel if (err != PICL_SUCCESS)
4991708Sstevel err = picl_get_propval_by_name(nodeh, PICL_REFPROP_LOC_PARENT,
5001708Sstevel &fruh, sizeof (fruh));
5011708Sstevel
5021708Sstevel while (err == PICL_PROPNOTFOUND) {
5031708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT,
5041708Sstevel &nodeh, sizeof (nodeh));
5051708Sstevel if (err != PICL_SUCCESS)
5061708Sstevel return (err);
5071708Sstevel
5081708Sstevel err = picl_get_propval_by_name(nodeh, PICL_REFPROP_FRU_PARENT,
5091708Sstevel &fruh, sizeof (fruh));
5101708Sstevel if (err != PICL_SUCCESS)
5111708Sstevel err = picl_get_propval_by_name(nodeh,
5121708Sstevel PICL_REFPROP_LOC_PARENT, &fruh, sizeof (fruh));
5131708Sstevel }
5141708Sstevel
5151708Sstevel if (err == PICL_SUCCESS)
5161708Sstevel *fruparenth = fruh;
5171708Sstevel
5181708Sstevel return (err);
5191708Sstevel }
5201708Sstevel
5211708Sstevel /*
5221708Sstevel * get label
5231708Sstevel *
5241708Sstevel * To get the label, use the following algorithm:
5251708Sstevel * Lookup "Label" property in the fru node itself. If no
5261708Sstevel * Label found, then traverse superiors (parent nodes) until
5271708Sstevel * a Label property is found.
5281708Sstevel * if not found, then no label
5291708Sstevel */
5301708Sstevel static int
picldiag_get_label(picl_nodehdl_t nodeh,char ** label)5311708Sstevel picldiag_get_label(picl_nodehdl_t nodeh, char **label)
5321708Sstevel {
5331708Sstevel int err;
5341708Sstevel
5351708Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL, label);
5361708Sstevel
5371708Sstevel while (err == PICL_PROPNOTFOUND) {
5381708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT,
5391708Sstevel &nodeh, sizeof (nodeh));
5401708Sstevel if (err != PICL_SUCCESS)
5411708Sstevel return (err);
5421708Sstevel
5431708Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL,
5441708Sstevel label);
5451708Sstevel }
5461708Sstevel
5471708Sstevel return (err);
5481708Sstevel }
5491708Sstevel
5501708Sstevel /*
5511708Sstevel * get combined label
5521708Sstevel *
5531708Sstevel * like picldiag_get_label, except concatenates the labels of parent locations
5541708Sstevel * eg SB0/P3 for processor P3 on system board SB0
5551708Sstevel *
5561708Sstevel * if caller specifies non-zero label length, label will be cut to specified
5571708Sstevel * length.
5581708Sstevel * negative length is left justified, non-negative length is right justified
5591708Sstevel */
5601708Sstevel static int
picldiag_get_combined_label(picl_nodehdl_t nodeh,char ** label,int lablen)5611708Sstevel picldiag_get_combined_label(picl_nodehdl_t nodeh, char **label, int lablen)
5621708Sstevel {
5631708Sstevel int err;
5641708Sstevel char *ptr;
5651708Sstevel char *ptr1 = NULL;
5661708Sstevel char *ptr2;
5671708Sstevel int len;
5681708Sstevel
5691708Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL, &ptr1);
5701708Sstevel if (err != PICL_PROPNOTFOUND && err != PICL_SUCCESS)
5711708Sstevel return (err);
5721708Sstevel
5731708Sstevel for (;;) {
5741708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT,
5751708Sstevel &nodeh, sizeof (nodeh));
5761708Sstevel if (err == PICL_PROPNOTFOUND)
5771708Sstevel break;
5781708Sstevel if (err != PICL_SUCCESS)
5791708Sstevel return (err);
5801708Sstevel
5811708Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL, &ptr);
5821708Sstevel if (err == PICL_SUCCESS) {
5831708Sstevel if (ptr1 == NULL) {
5841708Sstevel ptr1 = ptr;
5851708Sstevel } else {
5861708Sstevel ptr2 = malloc(strlen(ptr1) + strlen(ptr) + 2);
5871708Sstevel if (ptr2 == NULL)
5881708Sstevel return (PICL_FAILURE);
5891708Sstevel (void) strcpy(ptr2, ptr);
5901708Sstevel (void) strcat(ptr2, "/");
5911708Sstevel (void) strcat(ptr2, ptr1);
5921708Sstevel (void) free(ptr);
5931708Sstevel (void) free(ptr1);
5941708Sstevel ptr1 = ptr2;
5951708Sstevel }
5961708Sstevel } else if (err != PICL_PROPNOTFOUND) {
5971708Sstevel return (err);
5981708Sstevel }
5991708Sstevel }
6001708Sstevel
6011708Sstevel if (ptr1 == NULL)
6021708Sstevel return (PICL_PROPNOTFOUND);
6031708Sstevel
6041708Sstevel len = strlen(ptr1);
6051708Sstevel /* if no string truncation is desired or required */
6061708Sstevel if ((lablen == 0) || (len <= abs(lablen))) {
6071708Sstevel *label = ptr1;
6081708Sstevel return (PICL_SUCCESS);
6091708Sstevel }
6101708Sstevel
6111708Sstevel /* string truncation is required; alloc space for (lablen + \0) */
6121708Sstevel ptr = malloc(abs(lablen) + 1);
6131708Sstevel if (ptr == 0)
6141708Sstevel return (PICL_FAILURE);
6151708Sstevel if (lablen > 0) {
6161708Sstevel /* right justification; label = "+<string>\0" */
6171708Sstevel strcpy(ptr, "+");
6181708Sstevel strncat(ptr, ptr1 + len - lablen + 1, lablen + 1);
6191708Sstevel } else {
6201708Sstevel /* left justification; label = "<string>+\0" */
6211708Sstevel strncpy(ptr, ptr1, abs(lablen) - 1);
6221708Sstevel strcat(ptr, "+");
6231708Sstevel }
6241708Sstevel
6251708Sstevel *label = ptr;
6261708Sstevel return (PICL_SUCCESS);
6271708Sstevel }
6281708Sstevel
6291708Sstevel /*
6301708Sstevel * return the first compatible value
6311708Sstevel */
6321708Sstevel static int
picldiag_get_first_compatible_value(picl_nodehdl_t nodeh,char ** outbuf)6331708Sstevel picldiag_get_first_compatible_value(picl_nodehdl_t nodeh, char **outbuf)
6341708Sstevel {
6351708Sstevel int err;
6361708Sstevel picl_prophdl_t proph;
6371708Sstevel picl_propinfo_t pinfo;
6381708Sstevel picl_prophdl_t tblh;
6391708Sstevel picl_prophdl_t rowproph;
6401708Sstevel char *pval;
6411708Sstevel
6421708Sstevel err = picl_get_propinfo_by_name(nodeh, OBP_PROP_COMPATIBLE,
6431708Sstevel &pinfo, &proph);
6441708Sstevel if (err != PICL_SUCCESS)
645*13019SMichael.Bergknoff@Oracle.COM return (err);
6461708Sstevel
6471708Sstevel if (pinfo.type == PICL_PTYPE_CHARSTRING) {
6481708Sstevel pval = malloc(pinfo.size);
6491708Sstevel if (pval == NULL)
6501708Sstevel return (PICL_FAILURE);
6511708Sstevel err = picl_get_propval(proph, pval, pinfo.size);
6521708Sstevel if (err != PICL_SUCCESS) {
6531708Sstevel free(pval);
6541708Sstevel return (err);
6551708Sstevel }
6561708Sstevel *outbuf = pval;
6571708Sstevel return (PICL_SUCCESS);
6581708Sstevel }
6591708Sstevel
6601708Sstevel if (pinfo.type != PICL_PTYPE_TABLE)
6611708Sstevel return (PICL_FAILURE);
6621708Sstevel
6631708Sstevel /* get first string from table */
6641708Sstevel err = picl_get_propval(proph, &tblh, pinfo.size);
6651708Sstevel if (err != PICL_SUCCESS)
6661708Sstevel return (err);
6671708Sstevel
6681708Sstevel err = picl_get_next_by_row(tblh, &rowproph);
6691708Sstevel if (err != PICL_SUCCESS)
6701708Sstevel return (err);
6711708Sstevel
6721708Sstevel err = picl_get_propinfo(rowproph, &pinfo);
6731708Sstevel if (err != PICL_SUCCESS)
674*13019SMichael.Bergknoff@Oracle.COM return (err);
6751708Sstevel
6761708Sstevel pval = malloc(pinfo.size);
6771708Sstevel if (pval == NULL)
6781708Sstevel return (PICL_FAILURE);
6791708Sstevel
6801708Sstevel err = picl_get_propval(rowproph, pval, pinfo.size);
6811708Sstevel if (err != PICL_SUCCESS) {
6821708Sstevel free(pval);
6831708Sstevel return (err);
6841708Sstevel }
6851708Sstevel
6861708Sstevel *outbuf = pval;
6871708Sstevel return (PICL_SUCCESS);
6881708Sstevel }
6891708Sstevel
6901708Sstevel /*
6911708Sstevel * print the header in the center
6921708Sstevel */
6931708Sstevel static void
logprintf_header(char * header,size_t line_width)6941708Sstevel logprintf_header(char *header, size_t line_width)
6951708Sstevel {
6961708Sstevel size_t start_pos;
6971708Sstevel size_t i;
6981708Sstevel
6991708Sstevel log_printf("\n");
7001708Sstevel start_pos = (line_width - strlen(header) - 2) / 2;
7011708Sstevel
7021708Sstevel for (i = 0; i < start_pos; i++)
7031708Sstevel log_printf("%s", HEADING_SYMBOL);
7041708Sstevel
7051708Sstevel log_printf(" %s ", header);
7061708Sstevel
7071708Sstevel for (i = 0; i < start_pos; i++)
7081708Sstevel log_printf("%s", HEADING_SYMBOL);
7091708Sstevel
7101708Sstevel log_printf("\n");
7111708Sstevel }
7121708Sstevel
7131708Sstevel /*
7141708Sstevel * print the size
7151708Sstevel */
7161708Sstevel static void
logprintf_size(uint64_t size)7171708Sstevel logprintf_size(uint64_t size)
7181708Sstevel {
7191708Sstevel #define SIZE_FIELD 11
7201708Sstevel
7211708Sstevel uint64_t kbyte = 1024;
7221708Sstevel uint64_t mbyte = 1024 * 1024;
7231708Sstevel uint64_t gbyte = 1024 * 1024 * 1024;
7241708Sstevel uint64_t residue;
7251708Sstevel char buf[SIZE_FIELD];
7261708Sstevel
7271708Sstevel if (size >= gbyte) {
7281708Sstevel residue = size % gbyte;
7291708Sstevel if (residue == 0)
7301708Sstevel snprintf(buf, sizeof (buf), "%dGB",
7311708Sstevel (int)(size / gbyte));
7321708Sstevel else
7331708Sstevel snprintf(buf, sizeof (buf), "%.2fGB",
7341708Sstevel (float)size / gbyte);
7351708Sstevel } else if (size >= mbyte) {
7361708Sstevel residue = size % mbyte;
7371708Sstevel if (residue == 0)
7381708Sstevel snprintf(buf, sizeof (buf), "%dMB",
7391708Sstevel (int)(size / mbyte));
7401708Sstevel else
7411708Sstevel snprintf(buf, sizeof (buf), "%.2fMB",
7421708Sstevel (float)size / mbyte);
7431708Sstevel } else {
7441708Sstevel residue = size % kbyte;
7451708Sstevel if (residue == 0)
7461708Sstevel snprintf(buf, sizeof (buf), "%dKB",
7471708Sstevel (int)(size / kbyte));
7481708Sstevel else
7491708Sstevel snprintf(buf, sizeof (buf), "%.2fKB",
7501708Sstevel (float)size / kbyte);
7511708Sstevel }
7521708Sstevel
7531708Sstevel log_printf("%-10s ", buf);
7541708Sstevel }
7551708Sstevel
7561708Sstevel /*
7571708Sstevel * display platform banner
7581708Sstevel */
7591708Sstevel static int
display_platform_banner(picl_nodehdl_t plafh)7601708Sstevel display_platform_banner(picl_nodehdl_t plafh)
7611708Sstevel {
7621708Sstevel char *platform;
7631708Sstevel char *banner_name;
7641708Sstevel int err;
7651708Sstevel
7661708Sstevel /*
7671708Sstevel * get PICL_PROP_MACHINE and PICL_PROP_BANNER_NAME
7681708Sstevel */
7691708Sstevel log_printf(SIGN_ON_MSG);
7701708Sstevel err = picldiag_get_string_propval(plafh, PICL_PROP_MACHINE,
7711708Sstevel &platform);
7721708Sstevel if (err != PICL_SUCCESS)
7731708Sstevel return (err);
7741708Sstevel log_printf(" %s", platform);
7751708Sstevel free(platform);
7761708Sstevel
7771708Sstevel err = picldiag_get_string_propval(plafh, OBP_PROP_BANNER_NAME,
7781708Sstevel &banner_name);
7791708Sstevel if (err != PICL_SUCCESS)
7801708Sstevel return (err);
7811708Sstevel log_printf(" %s", banner_name);
7821708Sstevel free(banner_name);
7831708Sstevel
7841708Sstevel log_printf("\n");
7851708Sstevel return (PICL_SUCCESS);
7861708Sstevel }
7871708Sstevel
7881708Sstevel /*
7891708Sstevel * display the clock frequency
7901708Sstevel */
7911708Sstevel static int
display_system_clock(picl_nodehdl_t plafh)7921708Sstevel display_system_clock(picl_nodehdl_t plafh)
7931708Sstevel {
7941708Sstevel uint32_t system_clk;
7951708Sstevel int err;
7961708Sstevel
7971708Sstevel err = picldiag_get_clock_freq(plafh, &system_clk);
7981708Sstevel if (err != PICL_SUCCESS)
7991708Sstevel return (err);
8001708Sstevel
8011708Sstevel log_printf(SYSCLK_FREQ_MSG, system_clk);
8021708Sstevel
8031708Sstevel return (PICL_SUCCESS);
8041708Sstevel }
8051708Sstevel
8061708Sstevel /*
8071708Sstevel * callback function to display the memory size
8081708Sstevel */
8091708Sstevel /*ARGSUSED*/
8101708Sstevel static int
memory_callback(picl_nodehdl_t memh,void * args)8111708Sstevel memory_callback(picl_nodehdl_t memh, void *args)
8121708Sstevel {
8131708Sstevel uint64_t mem_size;
8141708Sstevel int err;
8151708Sstevel
8161708Sstevel log_printf(MEM_SIZE_MSG);
8171708Sstevel mem_size = picldiag_get_uint_propval(memh, PICL_PROP_SIZE, &err);
8181708Sstevel if (err == PICL_SUCCESS)
8191708Sstevel logprintf_size(mem_size);
8201708Sstevel log_printf("\n");
8211708Sstevel no_xfer_size = 0;
8221708Sstevel mem_xfersize = picldiag_get_uint_propval(memh, PICL_PROP_TRANSFER_SIZE,
8231708Sstevel &err);
8241708Sstevel if (err == PICL_PROPNOTFOUND)
8251708Sstevel no_xfer_size = 1;
8261708Sstevel return (PICL_WALK_TERMINATE);
8271708Sstevel }
8281708Sstevel
8291708Sstevel /*
8301708Sstevel * callback function to print cpu information
8311708Sstevel */
8321708Sstevel /*ARGSUSED*/
8331708Sstevel static int
cpu_callback(picl_nodehdl_t nodeh,void * args)8341708Sstevel cpu_callback(picl_nodehdl_t nodeh, void *args)
8351708Sstevel {
8361708Sstevel int err;
8371708Sstevel int id0, id1;
8381708Sstevel uint64_t uintval;
8391708Sstevel uint64_t decoded_mask;
8401708Sstevel uint32_t freq;
8411708Sstevel char *impl_name;
8421708Sstevel char *status;
8431708Sstevel picl_prophdl_t parenth;
8441708Sstevel picl_prophdl_t peerh;
8451708Sstevel char *label;
8461708Sstevel int is_cmp = 0;
8471708Sstevel int is_cheetah = 0;
8481708Sstevel
8491708Sstevel /*
8501708Sstevel * first check the implementation. If it's a CMP
8511708Sstevel * we need to combine info from both cores.
8521708Sstevel */
8531708Sstevel
8541708Sstevel impl_name = NULL;
8551708Sstevel uintval = picldiag_get_uint_propval(nodeh,
8561708Sstevel OBP_PROP_IMPLEMENTATION, &err);
8571708Sstevel if (err == PICL_SUCCESS) {
8581708Sstevel if (CPU_IMPL_IS_CMP(uintval)) {
8591708Sstevel is_cmp = 1;
8601708Sstevel err = picldiag_get_first_compatible_value(nodeh,
8611708Sstevel &impl_name);
8621708Sstevel if (err != PICL_SUCCESS)
8631708Sstevel impl_name = NULL;
8641708Sstevel } else if (IS_CHEETAH(uintval) || IS_CHEETAH_PLUS(uintval)) {
8651708Sstevel is_cheetah = 1;
8661708Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_NAME,
8671708Sstevel &impl_name);
8681708Sstevel if (err != PICL_SUCCESS)
8691708Sstevel impl_name = NULL;
8701708Sstevel }
8711708Sstevel } else {
8721708Sstevel err = picldiag_get_string_propval(nodeh,
8731708Sstevel PICL_PROP_NAME, &impl_name);
8741708Sstevel if (err != PICL_SUCCESS)
8751708Sstevel impl_name = NULL;
8761708Sstevel }
8771708Sstevel
8781708Sstevel /*
8791708Sstevel * In the CMP case, combine info from both cores. If we
8801708Sstevel * are being called with the first core handle, we display
8811708Sstevel * info on the sibling core handle too. If we are being
8821708Sstevel * called with the second core hanlde as an argument, simply
8831708Sstevel * return.
8841708Sstevel */
8851708Sstevel
8861708Sstevel if (is_cmp) {
8871708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER,
8881708Sstevel &peerh, sizeof (picl_nodehdl_t));
8891708Sstevel if (err != PICL_SUCCESS)
8901708Sstevel return (PICL_WALK_CONTINUE);
8911708Sstevel id1 = picldiag_get_uint_propval(peerh, PICL_PROP_ID, &err);
8921708Sstevel if (err == PICL_PROPNOTFOUND)
8931708Sstevel return (PICL_WALK_CONTINUE);
8941708Sstevel else if (err != PICL_SUCCESS)
8951708Sstevel return (err);
8961708Sstevel }
8971708Sstevel
8981708Sstevel /*
8991708Sstevel * If no ID is found, return
9001708Sstevel */
9011708Sstevel id0 = picldiag_get_uint_propval(nodeh, PICL_PROP_ID, &err);
9021708Sstevel if (err == PICL_PROPNOTFOUND)
9031708Sstevel return (PICL_WALK_CONTINUE);
9041708Sstevel else if (err != PICL_SUCCESS)
9051708Sstevel return (err);
9061708Sstevel if (is_cmp) {
9071708Sstevel log_printf("%3d,%3d ", id0, id1);
9081708Sstevel } else {
9091708Sstevel log_printf("%7d ", id0);
9101708Sstevel }
9111708Sstevel
9121708Sstevel /*
9131708Sstevel * If no freq is found, return
9141708Sstevel */
9151708Sstevel err = picldiag_get_clock_freq(nodeh, &freq);
9161708Sstevel if (err == PICL_PROPNOTFOUND)
9171708Sstevel return (PICL_WALK_CONTINUE);
9181708Sstevel else if (err != PICL_SUCCESS)
9191708Sstevel return (err);
9201708Sstevel log_printf("%4d MHz ", freq);
9211708Sstevel
9221708Sstevel /* Ecache size */
9231708Sstevel
9241708Sstevel if (is_cmp) {
9251708Sstevel uintval = picldiag_get_uint_propval(nodeh,
9261708Sstevel OBP_PROP_L3_CACHE_SIZE, &err);
9271708Sstevel if (err == PICL_SUCCESS) {
9281708Sstevel /*
9291708Sstevel * Panther L3 is logically shared, so the total E$
9301708Sstevel * size is equal to the core size.
9311708Sstevel */
9321708Sstevel logprintf_size(uintval);
9331708Sstevel } else {
9341708Sstevel uintval = picldiag_get_uint_propval(nodeh,
9351708Sstevel OBP_PROP_L2_CACHE_SIZE, &err);
9361708Sstevel if (err == PICL_SUCCESS) {
9371708Sstevel /*
9381708Sstevel * Jaguar has a split E$, so the total size
9391708Sstevel * is the sum of both cores.
9401708Sstevel */
9411708Sstevel logprintf_size(uintval * 2);
9421708Sstevel } else
9431708Sstevel log_printf(" - ");
9441708Sstevel }
9451708Sstevel } else {
9461708Sstevel uintval = picldiag_get_uint_propval(nodeh,
947*13019SMichael.Bergknoff@Oracle.COM OBP_PROP_ECACHE_SIZE, &err);
9481708Sstevel if (err == PICL_SUCCESS)
9491708Sstevel logprintf_size(uintval);
9501708Sstevel else
9511708Sstevel log_printf(" - ");
9521708Sstevel }
9531708Sstevel
9541708Sstevel /* Implementation */
9551708Sstevel if (impl_name != NULL)
9561708Sstevel log_printf(" %-20s ", impl_name);
9571708Sstevel else
9581708Sstevel log_printf(" <unknown> ");
9591708Sstevel
9601708Sstevel /* CPU Mask */
9611708Sstevel uintval = picldiag_get_uint_propval(nodeh, OBP_PROP_MASK, &err);
9621708Sstevel if (err == PICL_PROPNOTFOUND)
9631708Sstevel log_printf(" - ");
9641708Sstevel else if (err == PICL_SUCCESS) {
9651708Sstevel if (is_cheetah) {
9661708Sstevel decoded_mask = REMAP_CHEETAH_MASK(uintval);
9671708Sstevel } else {
9681708Sstevel decoded_mask = uintval;
9691708Sstevel }
9701708Sstevel log_printf("%2lld.%-2lld ", (decoded_mask >> 4) & 0xf,
9711708Sstevel decoded_mask & 0xf);
9721708Sstevel } else
9731708Sstevel return (err);
9741708Sstevel
9751708Sstevel /*
9761708Sstevel * Status - if the node has a status property then display that
9771708Sstevel * otherwise display the State property
9781708Sstevel */
9791708Sstevel err = picldiag_get_string_propval(nodeh, OBP_PROP_STATUS, &status);
9801708Sstevel if (err == PICL_SUCCESS) {
9811708Sstevel log_printf("%-12s", status);
9823873Skd93003 set_exit_code(status);
9831708Sstevel free(status);
9841708Sstevel } else if (err != PICL_PROPNOTFOUND && err !=
9851708Sstevel PICL_PROPVALUNAVAILABLE && err != PICL_ENDOFLIST) {
9861708Sstevel return (err);
9871708Sstevel } else {
9881708Sstevel err = picldiag_get_string_propval(nodeh,
9891708Sstevel PICL_PROP_STATE, &status);
9901708Sstevel if (err == PICL_SUCCESS) {
9911708Sstevel log_printf("%-12s", status);
9923873Skd93003 set_exit_code(status);
9931708Sstevel free(status);
9941708Sstevel } else if (err != PICL_PROPNOTFOUND && err !=
9951708Sstevel PICL_PROPVALUNAVAILABLE && err !=
9961708Sstevel PICL_ENDOFLIST) {
9971708Sstevel return (err);
9981708Sstevel } else {
9991708Sstevel log_printf("unknown ");
10001708Sstevel }
10011708Sstevel }
10021708Sstevel
10031708Sstevel /*
10041708Sstevel * Location: use label of fru parent
10051708Sstevel */
10061708Sstevel err = picldiag_get_fru_parent(nodeh, &parenth);
10071708Sstevel if (err == PICL_PROPNOTFOUND) {
10081708Sstevel log_printf(" - ");
10091708Sstevel } else if (err == PICL_SUCCESS) {
10101708Sstevel err = picldiag_get_combined_label(parenth, &label, 12);
10111708Sstevel if (err == PICL_PROPNOTFOUND)
10121708Sstevel log_printf(" - ");
10131708Sstevel else if (err == PICL_SUCCESS) {
10141708Sstevel log_printf("%s", label);
10151708Sstevel free(label);
10161708Sstevel } else
10171708Sstevel return (err);
10181708Sstevel } else
10191708Sstevel return (err);
10201708Sstevel
10211708Sstevel log_printf("\n");
10221708Sstevel return (PICL_WALK_CONTINUE);
10231708Sstevel }
10241708Sstevel
10251708Sstevel /*
10261708Sstevel * display cpu information
10271708Sstevel */
10281708Sstevel static int
display_cpu_info(picl_nodehdl_t plafh)10291708Sstevel display_cpu_info(picl_nodehdl_t plafh)
10301708Sstevel {
10311708Sstevel int err;
10321708Sstevel
10331708Sstevel /*
10341708Sstevel * Display the table header for CPUs . Then display the CPU
10351708Sstevel * frequency, cache size, and processor revision on all the boards.
10361708Sstevel */
10371708Sstevel logprintf_header(dgettext(TEXT_DOMAIN, "CPUs"), DEFAULT_LINE_WIDTH);
10381708Sstevel log_printf(" E$ CPU "
1039*13019SMichael.Bergknoff@Oracle.COM "CPU\n");
10401708Sstevel log_printf("CPU Freq Size Implementation "
1041*13019SMichael.Bergknoff@Oracle.COM "Mask Status Location\n");
10421708Sstevel log_printf("------- -------- ---------- ------------------- "
1043*13019SMichael.Bergknoff@Oracle.COM "----- ------ --------\n");
10441708Sstevel
10451708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_CPU, PICL_CLASS_CPU,
10461708Sstevel cpu_callback);
10471708Sstevel return (err);
10481708Sstevel }
10491708Sstevel
10501708Sstevel /*
10511708Sstevel * Inserts an io_card structure into the list.
10521708Sstevel */
10531708Sstevel static void
add_io_card(uint32_t board,uint32_t bus_id,uint32_t slot,char * label,uint32_t freq,char * name,char * model,char * status,char * devfs_path)10541708Sstevel add_io_card(uint32_t board, uint32_t bus_id, uint32_t slot, char *label,
10551708Sstevel uint32_t freq, char *name, char *model, char *status, char *devfs_path)
10561708Sstevel {
10571708Sstevel struct io_card card;
10581708Sstevel
10591708Sstevel card.display = 1;
10601708Sstevel card.board = board;
10611708Sstevel switch (bus_id) {
10621708Sstevel case SBUS_TYPE:
10631708Sstevel strlcpy(card.bus_type, SBUS_NAME, MAXSTRLEN);
10641708Sstevel break;
10651708Sstevel case PCI_TYPE:
10661708Sstevel strlcpy(card.bus_type, PCI_NAME, MAXSTRLEN);
10671708Sstevel break;
10681708Sstevel case UPA_TYPE:
10691708Sstevel strlcpy(card.bus_type, UPA_NAME, MAXSTRLEN);
10701708Sstevel break;
10711708Sstevel default: /* won't reach here */
10721708Sstevel strlcpy(card.bus_type, "", MAXSTRLEN);
10731708Sstevel break;
10741708Sstevel }
10751708Sstevel if (label == NULL)
10761708Sstevel card.slot = slot;
10771708Sstevel else {
10781708Sstevel card.slot = PCI_SLOT_IS_STRING;
10791708Sstevel (void) strlcpy(card.slot_str, label, MAXSTRLEN);
10801708Sstevel }
10811708Sstevel card.freq = freq;
10821708Sstevel card.status[0] = '\0';
10831708Sstevel card.name[0] = '\0';
10841708Sstevel card.model[0] = '\0';
10851708Sstevel card.notes[0] = '\0';
10861708Sstevel if (status != NULL)
10871708Sstevel strlcpy(card.status, status, MAXSTRLEN);
10881708Sstevel if (name != NULL)
10891708Sstevel strlcpy(card.name, name, MAXSTRLEN);
10901708Sstevel if (model != NULL)
10911708Sstevel strlcpy(card.model, model, MAXSTRLEN);
10921708Sstevel if (status != NULL)
10931708Sstevel strlcpy(card.status, status, MAXSTRLEN);
10941708Sstevel if (devfs_path != NULL)
10951708Sstevel strlcpy(card.notes, devfs_path, MAXSTRLEN);
10961708Sstevel
10971708Sstevel io_card_list = insert_io_card(io_card_list, &card);
10981708Sstevel }
10991708Sstevel
11001708Sstevel static void
append_to_bank_list(bank_list_t * newptr)11011708Sstevel append_to_bank_list(bank_list_t *newptr)
11021708Sstevel {
11031708Sstevel bank_list_t *ptr;
11041708Sstevel
11051708Sstevel if (mem_banks == NULL) {
11061708Sstevel mem_banks = newptr;
11071708Sstevel return;
11081708Sstevel }
11091708Sstevel ptr = mem_banks;
11101708Sstevel while (ptr->next != NULL)
11111708Sstevel ptr = ptr->next;
11121708Sstevel
11131708Sstevel ptr->next = newptr;
11141708Sstevel }
11151708Sstevel
11161708Sstevel static void
free_bank_list(void)11171708Sstevel free_bank_list(void)
11181708Sstevel {
11191708Sstevel bank_list_t *ptr;
11201708Sstevel bank_list_t *tmp;
11211708Sstevel
11221708Sstevel for (ptr = mem_banks; ptr != NULL; ptr = tmp) {
11231708Sstevel tmp = ptr->next;
11241708Sstevel free(ptr);
11251708Sstevel }
11261708Sstevel mem_banks = NULL;
11271708Sstevel }
11281708Sstevel
11291708Sstevel
11301708Sstevel /*
11311708Sstevel * print label for memory module
11321708Sstevel */
11331708Sstevel static int
logprintf_memory_module_label(picl_nodehdl_t moduleh)11341708Sstevel logprintf_memory_module_label(picl_nodehdl_t moduleh)
11351708Sstevel {
11361708Sstevel picl_nodehdl_t fruparenth;
11371708Sstevel int err;
11381708Sstevel char *label;
11391708Sstevel
11401708Sstevel err = picldiag_get_fru_parent(moduleh, &fruparenth);
11411708Sstevel if (err == PICL_PROPNOTFOUND) {
11421708Sstevel log_printf("-");
11431708Sstevel return (PICL_SUCCESS);
11441708Sstevel } else if (err != PICL_SUCCESS)
11451708Sstevel return (err);
11461708Sstevel
11471708Sstevel err = picldiag_get_combined_label(fruparenth, &label, 30);
11481708Sstevel if (err == PICL_PROPNOTFOUND)
11491708Sstevel log_printf("-");
11501708Sstevel else if (err == PICL_SUCCESS) {
11511708Sstevel log_printf("%-15s", label);
11521708Sstevel free(label);
11531708Sstevel } else
11541708Sstevel return (err);
11551708Sstevel
11561708Sstevel return (PICL_SUCCESS);
11571708Sstevel }
11581708Sstevel
11591708Sstevel /*
11601708Sstevel * print the bank id and add the bank handle in the bank list
11611708Sstevel * return the head of the bank list
11621708Sstevel */
11631708Sstevel static int
membank_callback(picl_nodehdl_t bankh,void * args)11641708Sstevel membank_callback(picl_nodehdl_t bankh, void *args)
11651708Sstevel {
11661708Sstevel int err;
11671708Sstevel int64_t id;
11681708Sstevel uint64_t match;
11691708Sstevel uint64_t mask;
11701708Sstevel int i;
11711708Sstevel bank_list_t *newptr;
11721708Sstevel seg_info_t *segp = args;
11731708Sstevel
11741708Sstevel /*
11751708Sstevel * print the bank id in the segment table contains column
11761708Sstevel */
11771708Sstevel id = picldiag_get_uint_propval(bankh, PICL_PROP_ID, &err);
11781708Sstevel if (segp->bank_count > 0)
11791708Sstevel log_printf(",");
11801708Sstevel if (err == PICL_PROPNOTFOUND)
11811708Sstevel log_printf("-");
11821708Sstevel else if (err == PICL_SUCCESS)
11831708Sstevel log_printf("%-lld", id);
11841708Sstevel else
11851708Sstevel return (err);
11861708Sstevel segp->bank_count++;
11871708Sstevel
11881708Sstevel /*
11891708Sstevel * Save the bank information for later (print_bank_table)
11901708Sstevel */
11911708Sstevel newptr = malloc(sizeof (*newptr));
11921708Sstevel if (newptr == NULL)
11931708Sstevel return (PICL_FAILURE);
11941708Sstevel
11951708Sstevel newptr->nodeh = bankh;
11961708Sstevel newptr->iway_count = 0;
11971708Sstevel newptr->next = NULL;
11981708Sstevel append_to_bank_list(newptr);
11991708Sstevel
12001708Sstevel /*
12011708Sstevel * Compute the way numbers for the bank
12021708Sstevel */
12031708Sstevel if (no_xfer_size)
12041708Sstevel return (PICL_WALK_CONTINUE);
12051708Sstevel
12061708Sstevel match = picldiag_get_uint_propval(bankh, PICL_PROP_ADDRESSMATCH, &err);
12071708Sstevel if (err == PICL_PROPNOTFOUND)
12081708Sstevel return (PICL_WALK_CONTINUE);
12091708Sstevel else if (err != PICL_SUCCESS)
12101708Sstevel return (err);
12111708Sstevel
12121708Sstevel mask = picldiag_get_uint_propval(bankh, PICL_PROP_ADDRESSMASK, &err);
12131708Sstevel if (err == PICL_PROPNOTFOUND)
12141708Sstevel return (PICL_WALK_CONTINUE);
12151708Sstevel else if (err != PICL_SUCCESS)
12161708Sstevel return (err);
12171708Sstevel
12181708Sstevel i = 0;
12191708Sstevel while ((i < segp->ifactor) && (newptr->iway_count < MAX_IWAYS)) {
12201708Sstevel if (((segp->base + i * mem_xfersize) & mask) == match)
12211708Sstevel newptr->iway[newptr->iway_count++] = i;
12221708Sstevel ++i;
12231708Sstevel }
12241708Sstevel return (PICL_WALK_CONTINUE);
12251708Sstevel }
12261708Sstevel
12271708Sstevel
12281708Sstevel /*
12291708Sstevel * find the memory bank and add the bank handle in the bank list
12301708Sstevel * return the head of the bank list
12311708Sstevel */
12321708Sstevel static int
logprintf_bankinfo(picl_nodehdl_t segh,seg_info_t * segp)12331708Sstevel logprintf_bankinfo(picl_nodehdl_t segh, seg_info_t *segp)
12341708Sstevel {
12351708Sstevel int err;
12361708Sstevel
12371708Sstevel log_printf("BankIDs ");
12381708Sstevel /*
12391708Sstevel * find memory-bank
12401708Sstevel */
12411708Sstevel segp->bank_count = 0;
12421708Sstevel err = picl_walk_tree_by_class(segh, PICL_CLASS_MEMORY_BANK, segp,
12431708Sstevel membank_callback);
12441708Sstevel log_printf("\n");
12451708Sstevel return (err);
12461708Sstevel }
12471708Sstevel
12481708Sstevel /*
12491708Sstevel * print the label of memory module or the memory module bank ids
12501708Sstevel */
12511708Sstevel static int
logprintf_seg_contains_col(picl_nodehdl_t nodeh,seg_info_t * segp)12521708Sstevel logprintf_seg_contains_col(picl_nodehdl_t nodeh, seg_info_t *segp)
12531708Sstevel {
12541708Sstevel picl_nodehdl_t moduleh;
12551708Sstevel int err;
12561708Sstevel
12571708Sstevel /*
12581708Sstevel * find memory-module if referenced directly from the memory-segment
12591708Sstevel * (ie no memory banks)
12601708Sstevel */
12611708Sstevel err = picl_get_propval_by_name(nodeh, PICL_REFPROP_MEMORY_MODULE,
12621708Sstevel &moduleh, sizeof (moduleh));
12631708Sstevel if ((err != PICL_SUCCESS) && (err != PICL_PROPNOTFOUND))
12641708Sstevel return (err);
12651708Sstevel if (err == PICL_SUCCESS) {
12661708Sstevel err = logprintf_memory_module_label(moduleh);
12671708Sstevel log_printf("\n");
12681708Sstevel return (err);
12691708Sstevel }
12701708Sstevel
12711708Sstevel /*
12721708Sstevel * memory-module not referenced directly from the memory segment
12731708Sstevel * so list memory banks instead
12741708Sstevel */
12751708Sstevel err = logprintf_bankinfo(nodeh, segp);
12761708Sstevel return (err);
12771708Sstevel }
12781708Sstevel
12791708Sstevel /*
12801708Sstevel * find all memory modules under the given memory module group
12811708Sstevel * and print its label
12821708Sstevel */
12831708Sstevel static int
logprintf_memory_module_group_info(picl_nodehdl_t memgrph,uint64_t mcid)12841708Sstevel logprintf_memory_module_group_info(picl_nodehdl_t memgrph, uint64_t mcid)
12851708Sstevel {
12861708Sstevel int err;
12871708Sstevel int64_t id;
12881708Sstevel picl_nodehdl_t moduleh;
12891708Sstevel char piclclass[PICL_CLASSNAMELEN_MAX];
12901708Sstevel picl_nodehdl_t fruparenth;
12911708Sstevel char *status;
12921708Sstevel
12931708Sstevel id = picldiag_get_uint_propval(memgrph, PICL_PROP_ID, &err);
12941708Sstevel if (err == PICL_PROPNOTFOUND)
12951708Sstevel id = -1;
12961708Sstevel else if (err != PICL_SUCCESS)
12971708Sstevel return (err);
12981708Sstevel
12991708Sstevel err = picl_get_propval_by_name(memgrph, PICL_PROP_CHILD, &moduleh,
13001708Sstevel sizeof (picl_nodehdl_t));
13011708Sstevel
13021708Sstevel while (err == PICL_SUCCESS) {
13031708Sstevel /* controller id */
13041708Sstevel log_printf("%-8lld ", mcid);
13051708Sstevel
13061708Sstevel /* group id */
13071708Sstevel if (id == -1) {
13081708Sstevel log_printf("- ");
13091708Sstevel } else {
13101708Sstevel log_printf("%-8lld ", id);
13111708Sstevel }
13121708Sstevel
13131708Sstevel err = picl_get_propval_by_name(moduleh, PICL_PROP_CLASSNAME,
13141708Sstevel piclclass, sizeof (piclclass));
13151708Sstevel if (err != PICL_SUCCESS)
13161708Sstevel return (err);
13171708Sstevel
13181708Sstevel if (strcmp(piclclass, PICL_CLASS_MEMORY_MODULE) == 0) {
13191708Sstevel err = logprintf_memory_module_label(moduleh);
13201708Sstevel if (err != PICL_SUCCESS)
13211708Sstevel return (err);
13221708Sstevel }
13231708Sstevel
13241708Sstevel err = picldiag_get_fru_parent(moduleh, &fruparenth);
13251708Sstevel if (err == PICL_SUCCESS) {
13261708Sstevel err = picldiag_get_string_propval(fruparenth,
13271708Sstevel PICL_PROP_OPERATIONAL_STATUS, &status);
13281708Sstevel if (err == PICL_SUCCESS) {
13291708Sstevel log_printf("%s", status);
13303873Skd93003 set_exit_code(status);
13311708Sstevel free(status);
13321708Sstevel } else if (err != PICL_PROPNOTFOUND)
13331708Sstevel return (err);
13341708Sstevel } else if (err != PICL_PROPNOTFOUND)
13351708Sstevel return (err);
13361708Sstevel
13371708Sstevel err = picl_get_propval_by_name(moduleh, PICL_PROP_PEER,
13381708Sstevel &moduleh, sizeof (picl_nodehdl_t));
13391708Sstevel
13401708Sstevel log_printf("\n");
13411708Sstevel }
13421708Sstevel if (err == PICL_PROPNOTFOUND)
13431708Sstevel return (PICL_SUCCESS);
13441708Sstevel return (err);
13451708Sstevel }
13461708Sstevel
13471708Sstevel /*
13481708Sstevel * search children to find memory module group under memory-controller
13491708Sstevel */
13501708Sstevel static int
find_memory_module_group(picl_nodehdl_t mch,int * print_header)13511708Sstevel find_memory_module_group(picl_nodehdl_t mch, int *print_header)
13521708Sstevel {
13531708Sstevel picl_nodehdl_t memgrph;
13541708Sstevel uint64_t mcid;
13551708Sstevel int err;
13561708Sstevel char piclclass[PICL_CLASSNAMELEN_MAX];
13571708Sstevel
13581708Sstevel mcid = picldiag_get_uint_propval(mch, OBP_PROP_PORTID, &err);
13591708Sstevel if (err == PICL_PROPNOTFOUND)
13601708Sstevel mcid = DEFAULT_PORTID;
13611708Sstevel else if (err != PICL_SUCCESS)
13621708Sstevel return (err);
13631708Sstevel
13641708Sstevel err = picl_get_propval_by_name(mch, PICL_PROP_CHILD,
13651708Sstevel &memgrph, sizeof (picl_nodehdl_t));
13661708Sstevel while (err == PICL_SUCCESS) {
13671708Sstevel err = picl_get_propval_by_name(memgrph,
13681708Sstevel PICL_PROP_CLASSNAME, piclclass, sizeof (piclclass));
13691708Sstevel if (err != PICL_SUCCESS)
13701708Sstevel return (err);
13711708Sstevel
13721708Sstevel if (strcmp(piclclass, PICL_CLASS_MEMORY_MODULE_GROUP) == 0) {
13731708Sstevel if (*print_header == 1) {
13741708Sstevel log_printf(
13751708Sstevel dgettext(TEXT_DOMAIN,
1376*13019SMichael.Bergknoff@Oracle.COM "\nMemory Module Groups:\n"));
13771708Sstevel log_printf("--------------------------");
13781708Sstevel log_printf("------------------------\n");
13791708Sstevel log_printf("ControllerID GroupID Labels");
13801708Sstevel log_printf(" Status\n");
13811708Sstevel log_printf("--------------------------");
13821708Sstevel log_printf("------------------------\n");
13831708Sstevel *print_header = 0;
13841708Sstevel }
13851708Sstevel err = logprintf_memory_module_group_info(memgrph, mcid);
13861708Sstevel if (err != PICL_SUCCESS)
13871708Sstevel return (err);
13881708Sstevel }
13891708Sstevel
13901708Sstevel err = picl_get_propval_by_name(memgrph, PICL_PROP_PEER,
13911708Sstevel &memgrph, sizeof (picl_nodehdl_t));
13921708Sstevel }
13931708Sstevel if (err == PICL_PROPNOTFOUND)
13941708Sstevel return (PICL_SUCCESS);
13951708Sstevel return (err);
13961708Sstevel }
13971708Sstevel
13981708Sstevel /*
13991708Sstevel * print memory module group table per memory-controller
14001708Sstevel */
14011708Sstevel static int
print_memory_module_group_table(picl_nodehdl_t plafh)14021708Sstevel print_memory_module_group_table(picl_nodehdl_t plafh)
14031708Sstevel {
14041708Sstevel picl_nodehdl_t mch;
14051708Sstevel int err;
14061708Sstevel char piclclass[PICL_CLASSNAMELEN_MAX];
14071708Sstevel int print_header;
14081708Sstevel
14091708Sstevel print_header = 1;
14101708Sstevel
14111708Sstevel /*
14121708Sstevel * find memory-controller
14131708Sstevel */
14141708Sstevel err = picl_get_propval_by_name(plafh, PICL_PROP_CHILD, &mch,
14151708Sstevel sizeof (picl_nodehdl_t));
14161708Sstevel while (err == PICL_SUCCESS) {
14171708Sstevel err = picl_get_propval_by_name(mch, PICL_PROP_CLASSNAME,
14181708Sstevel piclclass, sizeof (piclclass));
14191708Sstevel if (err != PICL_SUCCESS)
14201708Sstevel return (err);
14211708Sstevel
14221708Sstevel if (strcmp(piclclass, PICL_CLASS_MEMORY_CONTROLLER) != 0) {
14231708Sstevel err = print_memory_module_group_table(mch);
14241708Sstevel if (err != PICL_SUCCESS)
14251708Sstevel return (err);
14261708Sstevel err = picl_get_propval_by_name(mch, PICL_PROP_PEER,
14271708Sstevel &mch, sizeof (picl_nodehdl_t));
14281708Sstevel continue;
14291708Sstevel }
14301708Sstevel
14311708Sstevel err = find_memory_module_group(mch, &print_header);
14321708Sstevel if (err != PICL_SUCCESS)
14331708Sstevel return (err);
14341708Sstevel
14351708Sstevel err = picl_get_propval_by_name(mch, PICL_PROP_PEER,
14361708Sstevel &mch, sizeof (picl_nodehdl_t));
14371708Sstevel }
14381708Sstevel if (err == PICL_PROPNOTFOUND)
14391708Sstevel return (PICL_SUCCESS);
14401708Sstevel
14411708Sstevel return (err);
14421708Sstevel }
14431708Sstevel
14441708Sstevel /*
14451708Sstevel * print bank table
14461708Sstevel */
14471708Sstevel static int
print_bank_table(void)14481708Sstevel print_bank_table(void)
14491708Sstevel {
14501708Sstevel bank_list_t *ptr;
14511708Sstevel picl_nodehdl_t bankh;
14521708Sstevel picl_nodehdl_t memgrph;
14531708Sstevel picl_nodehdl_t mch;
14541708Sstevel int err;
14551708Sstevel int32_t i;
14561708Sstevel uint64_t size;
14571708Sstevel int id;
14581708Sstevel
14591708Sstevel log_printf(dgettext(TEXT_DOMAIN, "\nBank Table:\n"));
14601708Sstevel log_printf("---------------------------------------");
14611708Sstevel log_printf("--------------------\n");
14621708Sstevel log_printf(dgettext(TEXT_DOMAIN, " Physical Location\n"));
14631708Sstevel log_printf(dgettext(TEXT_DOMAIN, "ID ControllerID GroupID "));
14641708Sstevel log_printf(dgettext(TEXT_DOMAIN, "Size Interleave Way\n"));
14651708Sstevel log_printf("---------------------------------------");
14661708Sstevel log_printf("--------------------\n");
14671708Sstevel
14681708Sstevel for (ptr = mem_banks; ptr != NULL; ptr = ptr->next) {
14691708Sstevel bankh = ptr->nodeh;
14701708Sstevel id = picldiag_get_uint_propval(bankh, PICL_PROP_ID, &err);
14711708Sstevel if (err != PICL_SUCCESS)
14721708Sstevel log_printf("%-8s ", "-");
14731708Sstevel else
14741708Sstevel log_printf("%-8d ", id);
14751708Sstevel
14761708Sstevel /* find memory-module-group */
14771708Sstevel err = picl_get_propval_by_name(bankh,
14781708Sstevel PICL_REFPROP_MEMORY_MODULE_GROUP, &memgrph,
14791708Sstevel sizeof (memgrph));
14801708Sstevel if (err == PICL_PROPNOTFOUND) {
14811708Sstevel log_printf("%-8s ", "-");
14821708Sstevel log_printf("%-8s ", "-");
14831708Sstevel } else if (err != PICL_SUCCESS)
14841708Sstevel return (err);
14851708Sstevel else {
14861708Sstevel /*
14871708Sstevel * get controller id
14881708Sstevel */
14891708Sstevel err = picl_get_propval_by_name(memgrph,
14901708Sstevel PICL_PROP_PARENT, &mch, sizeof (picl_nodehdl_t));
14911708Sstevel if (err != PICL_SUCCESS)
14921708Sstevel return (err);
14931708Sstevel
14941708Sstevel id = picldiag_get_uint_propval(mch, OBP_PROP_PORTID,
14951708Sstevel &err);
14961708Sstevel if (err == PICL_PROPNOTFOUND)
14971708Sstevel id = DEFAULT_PORTID; /* use default */
14981708Sstevel else if (err != PICL_SUCCESS)
14991708Sstevel return (err);
15001708Sstevel
15011708Sstevel log_printf("%-8d ", id);
15021708Sstevel
15031708Sstevel /* get group id */
15041708Sstevel id = picldiag_get_uint_propval(memgrph, PICL_PROP_ID,
15051708Sstevel &err);
15061708Sstevel if (err == PICL_PROPNOTFOUND)
15071708Sstevel log_printf("- ");
15081708Sstevel else if (err == PICL_SUCCESS)
15091708Sstevel log_printf("%-8d ", id);
15101708Sstevel else
15111708Sstevel return (err);
15121708Sstevel }
15131708Sstevel
15141708Sstevel size = picldiag_get_uint_propval(bankh, PICL_PROP_SIZE, &err);
15151708Sstevel if (err == PICL_PROPNOTFOUND)
15161708Sstevel log_printf("- ");
15171708Sstevel else if (err == PICL_SUCCESS)
15181708Sstevel logprintf_size(size);
15191708Sstevel else
15201708Sstevel return (err);
15211708Sstevel
15221708Sstevel log_printf(" ");
15231708Sstevel for (i = 0; i < ptr->iway_count; i++) {
15241708Sstevel if (i != 0)
15251708Sstevel log_printf(",");
15261708Sstevel log_printf("%d", ptr->iway[i]);
15271708Sstevel }
15281708Sstevel
15291708Sstevel log_printf("\n");
15301708Sstevel }
15311708Sstevel return (PICL_SUCCESS);
15321708Sstevel }
15331708Sstevel
15341708Sstevel /*
15351708Sstevel * callback function to print segment, add the bank in the list and
15361708Sstevel * return the bank list
15371708Sstevel */
15381708Sstevel /* ARGSUSED */
15391708Sstevel static int
memseg_callback(picl_nodehdl_t segh,void * args)15401708Sstevel memseg_callback(picl_nodehdl_t segh, void *args)
15411708Sstevel {
15421708Sstevel seg_info_t seginfo;
15431708Sstevel int err;
15441708Sstevel
15451708Sstevel /* get base address */
15461708Sstevel seginfo.base = picldiag_get_uint_propval(segh, PICL_PROP_BASEADDRESS,
15471708Sstevel &err);
15481708Sstevel if (err == PICL_PROPNOTFOUND) {
15491708Sstevel log_printf("-\n");
15501708Sstevel return (PICL_WALK_CONTINUE);
15511708Sstevel } else if (err == PICL_SUCCESS)
15521708Sstevel log_printf("0x%-16llx ", seginfo.base);
15531708Sstevel else
15541708Sstevel return (err);
15551708Sstevel
15561708Sstevel /* get size */
15571708Sstevel seginfo.size = picldiag_get_uint_propval(segh, PICL_PROP_SIZE, &err);
15581708Sstevel if (err == PICL_PROPNOTFOUND) {
15591708Sstevel log_printf("-\n");
15601708Sstevel return (PICL_WALK_CONTINUE);
15611708Sstevel } else if (err == PICL_SUCCESS)
15621708Sstevel logprintf_size(seginfo.size);
15631708Sstevel else
15641708Sstevel return (err);
15651708Sstevel
15661708Sstevel /* get interleave factor */
15671708Sstevel seginfo.ifactor = picldiag_get_uint_propval(segh,
15681708Sstevel PICL_PROP_INTERLEAVE_FACTOR, &err);
15691708Sstevel
15701708Sstevel if (err == PICL_PROPNOTFOUND) {
15711708Sstevel log_printf(" -\n");
15721708Sstevel return (PICL_WALK_CONTINUE);
15731708Sstevel } else if (err == PICL_SUCCESS)
15741708Sstevel log_printf(" %-2d ", seginfo.ifactor);
15751708Sstevel else
15761708Sstevel return (err);
15771708Sstevel
15781708Sstevel seginfo.bank_count = 0;
15791708Sstevel err = logprintf_seg_contains_col(segh, &seginfo);
15801708Sstevel if (err != PICL_SUCCESS)
15811708Sstevel return (err);
15821708Sstevel return (PICL_WALK_CONTINUE);
15831708Sstevel }
15841708Sstevel
15851708Sstevel /*
15861708Sstevel * search children to find memory-segment and set up the bank list
15871708Sstevel */
15881708Sstevel static int
find_segments(picl_nodehdl_t plafh)15891708Sstevel find_segments(picl_nodehdl_t plafh)
15901708Sstevel {
15911708Sstevel int err;
15921708Sstevel
15931708Sstevel log_printf(dgettext(TEXT_DOMAIN, "Segment Table:\n"));
15941708Sstevel log_printf("------------------------------");
15951708Sstevel log_printf("-----------------------------------------\n");
15961708Sstevel log_printf(dgettext(TEXT_DOMAIN, "Base Address Size "));
15971708Sstevel log_printf(dgettext(TEXT_DOMAIN, "Interleave Factor Contains\n"));
15981708Sstevel log_printf("------------------------------");
15991708Sstevel log_printf("-----------------------------------------\n");
16001708Sstevel
16011708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY_SEGMENT,
16021708Sstevel NULL, memseg_callback);
16031708Sstevel return (err);
16041708Sstevel }
16051708Sstevel
16061708Sstevel /*
16071708Sstevel * display memory configuration
16081708Sstevel */
16091708Sstevel static int
display_memory_config(picl_nodehdl_t plafh)16101708Sstevel display_memory_config(picl_nodehdl_t plafh)
16111708Sstevel {
16121708Sstevel int err;
16131708Sstevel
16141708Sstevel logprintf_header(dgettext(TEXT_DOMAIN, "Memory Configuration"),
16151708Sstevel DEFAULT_LINE_WIDTH);
16161708Sstevel
16171708Sstevel mem_banks = NULL;
16181708Sstevel err = find_segments(plafh);
16191708Sstevel
16201708Sstevel if ((err == PICL_SUCCESS) && (mem_banks != NULL))
16211708Sstevel print_bank_table();
16221708Sstevel
16231708Sstevel free_bank_list();
16241708Sstevel
16251708Sstevel return (print_memory_module_group_table(plafh));
16261708Sstevel }
16271708Sstevel
16281708Sstevel /*
16291708Sstevel * print the hub device
16301708Sstevel */
16311708Sstevel static int
logprintf_hub_devices(picl_nodehdl_t hubh)16321708Sstevel logprintf_hub_devices(picl_nodehdl_t hubh)
16331708Sstevel {
16341708Sstevel char *name;
16351708Sstevel int portnum;
16361708Sstevel int err;
16371708Sstevel
16381708Sstevel err = picldiag_get_string_propval(hubh, PICL_PROP_NAME, &name);
16391708Sstevel if (err != PICL_SUCCESS)
16401708Sstevel return (err);
16411708Sstevel log_printf("%-12.12s ", name);
16421708Sstevel free(name);
16431708Sstevel
16441708Sstevel err = picl_get_propval_by_name(hubh, OBP_PROP_REG,
16451708Sstevel &portnum, sizeof (portnum));
16461708Sstevel if (err == PICL_PROPNOTFOUND)
16471708Sstevel log_printf("-\n");
16481708Sstevel else if (err == PICL_SUCCESS)
16491708Sstevel log_printf("%3d\n", portnum);
16501708Sstevel else
16511708Sstevel return (err);
16521708Sstevel
16531708Sstevel return (PICL_SUCCESS);
16541708Sstevel }
16551708Sstevel
16561708Sstevel /*
16571708Sstevel * callback functions to display hub devices
16581708Sstevel */
16591708Sstevel /* ARGSUSED */
16601708Sstevel static int
print_usb_devices(picl_nodehdl_t hubh,void * arg)16611708Sstevel print_usb_devices(picl_nodehdl_t hubh, void *arg)
16621708Sstevel {
16631708Sstevel picl_nodehdl_t chdh;
16641708Sstevel char *rootname;
16651708Sstevel int type = *(int *)arg;
16661708Sstevel int hubnum;
16671708Sstevel int err;
16681708Sstevel
16691708Sstevel err = picl_get_propval_by_name(hubh, PICL_PROP_CHILD, &chdh,
16701708Sstevel sizeof (picl_nodehdl_t));
16711708Sstevel
16721708Sstevel /* print header */
16731708Sstevel if (err == PICL_SUCCESS) {
16741708Sstevel err = picldiag_get_string_propval(hubh, PICL_PROP_NAME,
16751708Sstevel &rootname);
16761708Sstevel if (err != PICL_SUCCESS)
16771708Sstevel return (err);
16781708Sstevel
16791708Sstevel if (type == USB) {
16801708Sstevel log_printf("\n===============================");
16811708Sstevel log_printf(dgettext(TEXT_DOMAIN,
16821708Sstevel " %s Devices "), rootname);
16831708Sstevel } else {
16841708Sstevel /* Get its hub number */
16851708Sstevel err = picl_get_propval_by_name(hubh,
16861708Sstevel OBP_PROP_REG, &hubnum, sizeof (hubnum));
16871708Sstevel if ((err != PICL_SUCCESS) &&
16881708Sstevel (err != PICL_PROPNOTFOUND)) {
16891708Sstevel free(rootname);
16901708Sstevel return (err);
16911708Sstevel }
16921708Sstevel
16931708Sstevel log_printf("\n===============================");
16941708Sstevel if (err == PICL_SUCCESS)
16951708Sstevel log_printf(dgettext(TEXT_DOMAIN,
16961708Sstevel " %s#%d Devices "),
16971708Sstevel rootname, hubnum);
16981708Sstevel else
16991708Sstevel log_printf(dgettext(TEXT_DOMAIN,
17001708Sstevel " %s Devices "), rootname);
17011708Sstevel }
17021708Sstevel
17031708Sstevel log_printf("===============================\n\n");
17041708Sstevel log_printf("Name Port#\n");
17051708Sstevel log_printf("------------ -----\n");
17061708Sstevel free(rootname);
17071708Sstevel
17081708Sstevel do {
17091708Sstevel logprintf_hub_devices(chdh);
17101708Sstevel
17111708Sstevel err = picl_get_propval_by_name(chdh, PICL_PROP_PEER,
17121708Sstevel &chdh, sizeof (picl_nodehdl_t));
17131708Sstevel } while (err == PICL_SUCCESS);
17141708Sstevel }
17151708Sstevel
17161708Sstevel
17171708Sstevel if (err == PICL_PROPNOTFOUND)
17181708Sstevel return (PICL_WALK_CONTINUE);
17191708Sstevel return (err);
17201708Sstevel }
17211708Sstevel
17221708Sstevel /*
17231708Sstevel * callback functions to display usb devices
17241708Sstevel */
17251708Sstevel /* ARGSUSED */
17261708Sstevel static int
usb_callback(picl_nodehdl_t usbh,void * args)17271708Sstevel usb_callback(picl_nodehdl_t usbh, void *args)
17281708Sstevel {
17291708Sstevel int err;
17301708Sstevel int type;
17311708Sstevel
17321708Sstevel type = USB;
17331708Sstevel err = print_usb_devices(usbh, &type);
17341708Sstevel if (err != PICL_WALK_CONTINUE)
17351708Sstevel return (err);
17361708Sstevel type = HUB;
17371708Sstevel err = picl_walk_tree_by_class(usbh, NULL, &type, print_usb_devices);
17381708Sstevel if (err == PICL_SUCCESS)
17391708Sstevel err = PICL_WALK_CONTINUE;
17401708Sstevel return (err);
17411708Sstevel }
17421708Sstevel
17431708Sstevel
17441708Sstevel /*
17451708Sstevel * find usb devices and print its information
17461708Sstevel */
17471708Sstevel static int
display_usb_devices(picl_nodehdl_t plafh)17481708Sstevel display_usb_devices(picl_nodehdl_t plafh)
17491708Sstevel {
17501708Sstevel int err;
17511708Sstevel
17521708Sstevel /*
17531708Sstevel * get the usb node
17541708Sstevel */
17551708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_USB, NULL,
17561708Sstevel usb_callback);
17571708Sstevel return (err);
17581708Sstevel }
17591708Sstevel
17601708Sstevel
17611708Sstevel
17621708Sstevel /*
17631708Sstevel * If nodeh is the io device, add it into the io list and return
17641708Sstevel * If it is not an io device and it has the subtree, traverse the subtree
17651708Sstevel * and add all leaf io devices
17661708Sstevel */
17671708Sstevel static int
add_io_leaves(picl_nodehdl_t nodeh,char * parentname,uint32_t board,uint32_t bus_id,uint64_t slot,uint32_t freq,char * model,char * status)17681708Sstevel add_io_leaves(picl_nodehdl_t nodeh, char *parentname, uint32_t board,
17691708Sstevel uint32_t bus_id, uint64_t slot, uint32_t freq, char *model, char *status)
17701708Sstevel {
17711708Sstevel picl_nodehdl_t childh;
17721708Sstevel picl_prophdl_t proph;
17731708Sstevel picl_propinfo_t pinfo;
17741708Sstevel int err;
17751708Sstevel char *nameval;
17761708Sstevel char piclclass[PICL_CLASSNAMELEN_MAX];
17771708Sstevel char nodename[MAXSTRLEN];
17781708Sstevel char name[MAXSTRLEN];
17791708Sstevel char *devfs_path;
17801708Sstevel char *compatible;
17811708Sstevel picl_nodehdl_t fruparenth;
17821708Sstevel char *label;
17831708Sstevel char binding_name[MAXSTRLEN];
17841708Sstevel
17851708Sstevel err = picl_get_propinfo_by_name(nodeh, PICL_PROP_NAME, &pinfo,
17861708Sstevel &proph);
17871708Sstevel if (err != PICL_SUCCESS)
17881708Sstevel return (err);
17891708Sstevel
17901708Sstevel nameval = alloca(pinfo.size);
17911708Sstevel if (nameval == NULL)
17921708Sstevel return (PICL_FAILURE);
17931708Sstevel
17941708Sstevel err = picl_get_propval(proph, nameval, pinfo.size);
17951708Sstevel if (err != PICL_SUCCESS)
17961708Sstevel return (err);
17971708Sstevel
17981708Sstevel (void) strlcpy(nodename, nameval, MAXSTRLEN);
17991708Sstevel
18001708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
18011708Sstevel piclclass, sizeof (piclclass));
18021708Sstevel if (err != PICL_SUCCESS)
18031708Sstevel return (err);
18041708Sstevel
18051708Sstevel /* if binding_name is found, name will be <nodename>-<binding_name> */
18061708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_BINDING_NAME,
18071708Sstevel binding_name, sizeof (binding_name));
18081708Sstevel if (err == PICL_PROPNOTFOUND) {
18091708Sstevel /*
18101708Sstevel * if compatible prop is found, name will be
18111708Sstevel * <nodename>-<compatible>
18121708Sstevel */
18131708Sstevel err = picldiag_get_first_compatible_value(nodeh, &compatible);
18141708Sstevel if (err == PICL_SUCCESS) {
18151708Sstevel strlcat(nodename, "-", MAXSTRLEN);
18161708Sstevel strlcat(nodename, compatible, MAXSTRLEN);
18171708Sstevel free(compatible);
18181708Sstevel } else if (err != PICL_PROPNOTFOUND) {
18191708Sstevel return (err);
18201708Sstevel }
18211708Sstevel } else if (err != PICL_SUCCESS) {
18221708Sstevel return (err);
18231708Sstevel } else if (strcmp(nodename, binding_name) != 0) {
18241708Sstevel if (strcmp(nodename, piclclass) == 0) {
18251708Sstevel /*
18261708Sstevel * nodename same as binding name -
18271708Sstevel * no need to display twice
18281708Sstevel */
18291708Sstevel strlcpy(nodename, binding_name, MAXSTRLEN);
18301708Sstevel } else {
18311708Sstevel strlcat(nodename, "-", MAXSTRLEN);
18321708Sstevel strlcat(nodename, binding_name, MAXSTRLEN);
18331708Sstevel }
18341708Sstevel }
18351708Sstevel
18361708Sstevel /*
18371708Sstevel * If it is an immediate child under pci/sbus/upa and not
18381708Sstevel * a bus node, add it to the io list.
18391708Sstevel * If it is a child under sub-bus and it is in an io
18401708Sstevel * device, add it to the io list.
18411708Sstevel */
18421708Sstevel if (((parentname == NULL) && (!is_bus(piclclass))) ||
18431708Sstevel ((parentname != NULL) && (is_io_device(piclclass)))) {
18441708Sstevel if (parentname == NULL)
18451708Sstevel (void) snprintf(name, MAXSTRLEN, "%s", nodename);
18461708Sstevel else
18471708Sstevel (void) snprintf(name, MAXSTRLEN, "%s/%s", parentname,
18481708Sstevel nodename);
18491708Sstevel
18501708Sstevel /*
18511708Sstevel * append the class if its class is not a generic
18521708Sstevel * obp-device class
18531708Sstevel */
18541708Sstevel if (strcmp(piclclass, PICL_CLASS_OBP_DEVICE))
18551708Sstevel (void) snprintf(name, MAXSTRLEN, "%s (%s)", name,
18561708Sstevel piclclass);
18571708Sstevel
18581708Sstevel err = picldiag_get_fru_parent(nodeh, &fruparenth);
18591708Sstevel if (err == PICL_PROPNOTFOUND) {
18601708Sstevel label = NULL;
18611708Sstevel } else if (err != PICL_SUCCESS) {
18621708Sstevel return (err);
18631708Sstevel } else {
18641708Sstevel err = picldiag_get_combined_label(fruparenth, &label,
18651708Sstevel 15);
18661708Sstevel if (err == PICL_PROPNOTFOUND)
18671708Sstevel label = NULL;
18681708Sstevel else if (err != PICL_SUCCESS)
18691708Sstevel return (err);
18701708Sstevel }
18711708Sstevel /* devfs-path */
18721708Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_DEVFS_PATH,
18731708Sstevel &devfs_path);
18741708Sstevel if (err == PICL_PROPNOTFOUND)
18751708Sstevel devfs_path = NULL;
18761708Sstevel else if (err != PICL_SUCCESS)
18771708Sstevel return (err);
18781708Sstevel
18791708Sstevel add_io_card(board, bus_id, slot, label, freq, name,
18801708Sstevel model, status, devfs_path);
18811708Sstevel if (label != NULL)
18821708Sstevel free(label);
18831708Sstevel if (devfs_path != NULL)
18841708Sstevel free(devfs_path);
18851708Sstevel return (PICL_SUCCESS);
18861708Sstevel }
18871708Sstevel
18881708Sstevel /*
18891708Sstevel * If there is any child, Go through each child.
18901708Sstevel */
18911708Sstevel
18921708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_CHILD,
18931708Sstevel &childh, sizeof (picl_nodehdl_t));
18941708Sstevel
18951708Sstevel /* there is a child */
18961708Sstevel while (err == PICL_SUCCESS) {
18971708Sstevel if (parentname == NULL)
18981708Sstevel (void) strlcpy(name, nodename, MAXSTRLEN);
18991708Sstevel else
19001708Sstevel (void) snprintf(name, MAXSTRLEN, "%s/%s", parentname,
19011708Sstevel nodename);
19021708Sstevel
19031708Sstevel err = add_io_leaves(childh, name, board, bus_id, slot, freq,
19041708Sstevel model, status);
19051708Sstevel if (err != PICL_SUCCESS)
19061708Sstevel return (err);
19071708Sstevel /*
19081708Sstevel * get next child
19091708Sstevel */
19101708Sstevel err = picl_get_propval_by_name(childh, PICL_PROP_PEER,
19111708Sstevel &childh, sizeof (picl_nodehdl_t));
19121708Sstevel }
19131708Sstevel
19141708Sstevel if (err == PICL_PROPNOTFOUND)
19151708Sstevel return (PICL_SUCCESS);
19161708Sstevel return (err);
19171708Sstevel }
19181708Sstevel
19191708Sstevel /*
19201708Sstevel * callback function to add all io devices under sbus in io list
19211708Sstevel */
19221708Sstevel /*ARGSUSED*/
19231708Sstevel static int
sbus_callback(picl_nodehdl_t sbush,void * args)19241708Sstevel sbus_callback(picl_nodehdl_t sbush, void *args)
19251708Sstevel {
19261708Sstevel picl_nodehdl_t nodeh;
19271708Sstevel int err;
19281708Sstevel uint32_t boardnum;
19291708Sstevel uint32_t bus_id;
19301708Sstevel uint32_t slot;
19311708Sstevel uint32_t freq;
19321708Sstevel char *model;
19331708Sstevel char *status;
19341708Sstevel
19351708Sstevel /* Fill in common infomation */
19361708Sstevel bus_id = SBUS_TYPE;
19371708Sstevel
19381708Sstevel err = picldiag_get_clock_freq(sbush, &freq);
19391708Sstevel if (err == PICL_PROPNOTFOUND)
19401708Sstevel return (PICL_WALK_CONTINUE);
19411708Sstevel else if (err != PICL_SUCCESS)
19421708Sstevel return (err);
19431708Sstevel /*
19441708Sstevel * If no board# is found, set boardnum to 0
19451708Sstevel */
19461708Sstevel boardnum = picldiag_get_uint_propval(sbush, OBP_PROP_BOARD_NUM, &err);
19471708Sstevel if (err == PICL_PROPNOTFOUND)
19481708Sstevel boardnum = DEFAULT_BOARD_NUM;
19491708Sstevel else if (err != PICL_SUCCESS)
19501708Sstevel return (err);
19511708Sstevel
19521708Sstevel err = picl_get_propval_by_name(sbush, PICL_PROP_CHILD, &nodeh,
19531708Sstevel sizeof (picl_nodehdl_t));
19541708Sstevel
19551708Sstevel while (err == PICL_SUCCESS) {
19561708Sstevel slot = picldiag_get_uint_propval(nodeh,
19571708Sstevel PICL_PROP_SLOT, &err);
19581708Sstevel if (err == PICL_PROPNOTFOUND) {
19591708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER,
19601708Sstevel &nodeh, sizeof (picl_nodehdl_t));
19611708Sstevel continue;
19621708Sstevel } else if (err != PICL_SUCCESS)
19631708Sstevel return (err);
19641708Sstevel
19651708Sstevel err = picldiag_get_string_propval(nodeh, OBP_PROP_MODEL,
19661708Sstevel &model);
19671708Sstevel if (err == PICL_PROPNOTFOUND)
19681708Sstevel model = NULL;
19691708Sstevel else if (err != PICL_SUCCESS)
19701708Sstevel return (err);
19711708Sstevel
19721708Sstevel err = picldiag_get_string_propval(nodeh, OBP_PROP_STATUS,
19731708Sstevel &status);
19741708Sstevel if (err == PICL_PROPNOTFOUND) {
19751708Sstevel status = malloc(5);
19761708Sstevel strncpy(status, "okay", 5);
19771708Sstevel } else if (err != PICL_SUCCESS)
19781708Sstevel return (err);
19791708Sstevel
19801708Sstevel err = add_io_leaves(nodeh, NULL, boardnum, bus_id, slot, freq,
19811708Sstevel model, status);
19821708Sstevel if (model != NULL)
19831708Sstevel free(model);
19841708Sstevel if (status != NULL)
19851708Sstevel free(status);
19861708Sstevel if (err != PICL_SUCCESS)
19871708Sstevel return (err);
19881708Sstevel
19891708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh,
19901708Sstevel sizeof (picl_nodehdl_t));
19911708Sstevel }
19921708Sstevel if (err == PICL_PROPNOTFOUND)
19931708Sstevel return (PICL_WALK_CONTINUE);
19941708Sstevel return (err);
19951708Sstevel }
19961708Sstevel
19971708Sstevel /*
19981708Sstevel * add all io devices under pci in io list
19991708Sstevel */
20001708Sstevel /* ARGSUSED */
20011708Sstevel static int
pci_callback(picl_nodehdl_t pcih,void * args)20021708Sstevel pci_callback(picl_nodehdl_t pcih, void *args)
20031708Sstevel {
20041708Sstevel picl_nodehdl_t nodeh;
20051708Sstevel int err;
20061708Sstevel char piclclass[PICL_CLASSNAMELEN_MAX];
20071708Sstevel uint32_t boardnum;
20081708Sstevel uint32_t bus_id;
20091708Sstevel uint32_t slot;
20101708Sstevel uint32_t freq;
20111708Sstevel char *model;
20121708Sstevel char *status;
20131708Sstevel
20141708Sstevel /* Fill in common infomation */
20151708Sstevel bus_id = PCI_TYPE;
20161708Sstevel
20171708Sstevel /*
20181708Sstevel * Check if it has the freq, if not,
20191708Sstevel * If not, use its parent's freq
20201708Sstevel * if its parent's freq is not found, return
20211708Sstevel */
20221708Sstevel err = picldiag_get_clock_freq(pcih, &freq);
20231708Sstevel if (err == PICL_PROPNOTFOUND) {
20241708Sstevel err = picldiag_get_clock_from_parent(pcih, &freq);
20251708Sstevel if (err == PICL_PROPNOTFOUND)
20261708Sstevel return (PICL_WALK_CONTINUE);
20271708Sstevel else if (err != PICL_SUCCESS)
20281708Sstevel return (err);
20291708Sstevel } else if (err != PICL_SUCCESS)
20301708Sstevel return (err);
20311708Sstevel
20321708Sstevel /*
20331708Sstevel * If no board# is found, set boardnum to 0
20341708Sstevel */
20351708Sstevel boardnum = picldiag_get_uint_propval(pcih, OBP_PROP_BOARD_NUM, &err);
20361708Sstevel if (err == PICL_PROPNOTFOUND)
20371708Sstevel boardnum = DEFAULT_BOARD_NUM;
20381708Sstevel else if (err != PICL_SUCCESS)
20391708Sstevel return (err);
20401708Sstevel
20411708Sstevel /* Walk through the children */
20421708Sstevel
20431708Sstevel err = picl_get_propval_by_name(pcih, PICL_PROP_CHILD, &nodeh,
20441708Sstevel sizeof (picl_nodehdl_t));
20451708Sstevel while (err == PICL_SUCCESS) {
20461708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
20471708Sstevel piclclass, sizeof (piclclass));
20481708Sstevel if (err != PICL_SUCCESS)
20491708Sstevel return (err);
20501708Sstevel
20511708Sstevel /*
20521708Sstevel * Skip PCI bridge and USB devices because they will be
20531708Sstevel * processed later
20541708Sstevel */
20551708Sstevel if ((strcmp(piclclass, PICL_CLASS_PCI) == 0) ||
20561708Sstevel (strcmp(piclclass, PICL_CLASS_USB) == 0)) {
20571708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER,
20581708Sstevel &nodeh, sizeof (picl_nodehdl_t));
20591708Sstevel continue;
20601708Sstevel }
20611708Sstevel
20621708Sstevel /* Get the device id for pci card */
20631708Sstevel slot = picldiag_get_uint_propval(nodeh,
20641708Sstevel PICL_PROP_DEVICE_ID, &err);
20651708Sstevel if (err == PICL_PROPNOTFOUND) {
20661708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER,
20671708Sstevel &nodeh, sizeof (picl_nodehdl_t));
20681708Sstevel continue;
20691708Sstevel } else if (err != PICL_SUCCESS)
20701708Sstevel return (err);
20711708Sstevel
20721708Sstevel /* Get the model of this card */
20731708Sstevel err = picldiag_get_string_propval(nodeh, OBP_PROP_MODEL,
20741708Sstevel &model);
20751708Sstevel if (err == PICL_PROPNOTFOUND)
20761708Sstevel model = NULL;
20771708Sstevel else if (err != PICL_SUCCESS)
20781708Sstevel return (err);
20791708Sstevel
20801708Sstevel err = picldiag_get_string_propval(nodeh, OBP_PROP_STATUS,
20811708Sstevel &status);
20821708Sstevel if (err == PICL_PROPNOTFOUND) {
20831708Sstevel status = malloc(5);
20841708Sstevel strncpy(status, "okay", 5);
20851708Sstevel } else if (err != PICL_SUCCESS)
20861708Sstevel return (err);
20871708Sstevel
20881708Sstevel err = add_io_leaves(nodeh, NULL, boardnum, bus_id, slot,
20891708Sstevel freq, model, status);
20901708Sstevel
20911708Sstevel if (model != NULL)
20921708Sstevel free(model);
20931708Sstevel
20941708Sstevel if (status != NULL)
20951708Sstevel free(status);
20961708Sstevel
20971708Sstevel if (err != PICL_SUCCESS)
20981708Sstevel return (err);
20991708Sstevel
21001708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh,
21011708Sstevel sizeof (picl_nodehdl_t));
21021708Sstevel
21031708Sstevel }
21041708Sstevel
21051708Sstevel if (err == PICL_PROPNOTFOUND)
21061708Sstevel return (PICL_WALK_CONTINUE);
21071708Sstevel
21081708Sstevel return (err);
21091708Sstevel }
21101708Sstevel
21111708Sstevel /*
21121708Sstevel * add io devices in io list
21131708Sstevel * Its slot number is drived from upa-portid
21141708Sstevel */
21151708Sstevel static int
add_io_devices(picl_nodehdl_t nodeh)21161708Sstevel add_io_devices(picl_nodehdl_t nodeh)
21171708Sstevel {
21181708Sstevel int err;
21191708Sstevel uint64_t board_type;
21201708Sstevel char piclclass[PICL_CLASSNAMELEN_MAX];
21211708Sstevel char name[MAXSTRLEN];
21221708Sstevel char *devfs_path;
21231708Sstevel char *nameval;
21241708Sstevel uint32_t boardnum;
21251708Sstevel uint32_t bus_id;
21261708Sstevel uint32_t slot;
21271708Sstevel uint32_t freq;
21281708Sstevel char *model;
21291708Sstevel char *status;
21301708Sstevel picl_prophdl_t proph;
21311708Sstevel picl_propinfo_t pinfo;
21321708Sstevel picl_nodehdl_t fruparenth;
21331708Sstevel char *label;
21341708Sstevel
21351708Sstevel
21361708Sstevel bus_id = UPA_TYPE;
21371708Sstevel
21381708Sstevel /*
21391708Sstevel * If clock frequency can't be found from its parent, don't add
21401708Sstevel */
21411708Sstevel err = picldiag_get_clock_from_parent(nodeh, &freq);
21421708Sstevel if (err == PICL_PROPNOTFOUND)
21431708Sstevel return (PICL_SUCCESS);
21441708Sstevel else if (err != PICL_SUCCESS)
21451708Sstevel return (err);
21461708Sstevel
21471708Sstevel /*
21481708Sstevel * If no board# is found, set boardnum to 0
21491708Sstevel */
21501708Sstevel boardnum = picldiag_get_uint_propval(nodeh, OBP_PROP_BOARD_NUM, &err);
21511708Sstevel if (err == PICL_PROPNOTFOUND)
21521708Sstevel boardnum = DEFAULT_BOARD_NUM;
21531708Sstevel else if (err != PICL_SUCCESS)
21541708Sstevel return (err);
21551708Sstevel
21561708Sstevel /*
21571708Sstevel * get upa portid as slot number
21581708Sstevel * If upa portid is not found, don't add the card.
21591708Sstevel */
21601708Sstevel slot = picldiag_get_uint_propval(nodeh, OBP_PROP_UPA_PORTID,
21611708Sstevel &err);
21621708Sstevel if (err == PICL_PROPNOTFOUND)
21631708Sstevel return (PICL_SUCCESS);
21641708Sstevel else if (err != PICL_SUCCESS)
21651708Sstevel return (err);
21661708Sstevel
21671708Sstevel /* Get the model of this card */
21681708Sstevel err = picldiag_get_string_propval(nodeh, OBP_PROP_MODEL, &model);
21691708Sstevel if (err == PICL_PROPNOTFOUND)
21701708Sstevel model = NULL;
21711708Sstevel else if (err != PICL_SUCCESS)
21721708Sstevel return (err);
21731708Sstevel
21741708Sstevel /*
21751708Sstevel * check if it is a ffb device
21761708Sstevel * If it's a ffb device, append its board type to name
21771708Sstevel * otherwise, use its nodename
21781708Sstevel */
21791708Sstevel err = picl_get_prop_by_name(nodeh, PICL_PROP_FFB_BOARD_REV, &proph);
21801708Sstevel if (err == PICL_PROPNOTFOUND) {
21811708Sstevel err = picl_get_propinfo_by_name(nodeh, PICL_PROP_NAME,
21821708Sstevel &pinfo, &proph);
21831708Sstevel if (err != PICL_SUCCESS)
21841708Sstevel return (err);
21851708Sstevel
21861708Sstevel nameval = alloca(pinfo.size);
21871708Sstevel if (nameval == NULL)
21881708Sstevel return (PICL_FAILURE);
21891708Sstevel
21901708Sstevel err = picl_get_propval(proph, nameval, pinfo.size);
21911708Sstevel if (err != PICL_SUCCESS)
21921708Sstevel return (err);
21931708Sstevel
21941708Sstevel (void) strlcpy(name, nameval, MAXSTRLEN);
21951708Sstevel } else if (err == PICL_SUCCESS) {
21961708Sstevel /* Find out if it's single or double buffered */
21971708Sstevel board_type = picldiag_get_uint_propval(nodeh,
21981708Sstevel OBP_PROP_BOARD_TYPE, &err);
21991708Sstevel if (err == PICL_PROPNOTFOUND)
22001708Sstevel (void) strlcpy(name, FFB_NAME, sizeof (name));
22011708Sstevel if (err == PICL_SUCCESS) {
22021708Sstevel if (board_type & FFB_B_BUFF)
22031708Sstevel (void) strlcpy(name, FFB_DOUBLE_BUF,
22041708Sstevel sizeof (name));
22051708Sstevel else
22061708Sstevel (void) strlcpy(name, FFB_SINGLE_BUF,
22071708Sstevel sizeof (name));
22081708Sstevel } else
22091708Sstevel return (err);
22101708Sstevel } else
22111708Sstevel return (err);
22121708Sstevel
22131708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
22141708Sstevel piclclass, sizeof (piclclass));
22151708Sstevel if (err != PICL_SUCCESS)
22161708Sstevel return (err);
22171708Sstevel
22181708Sstevel (void) snprintf(name, sizeof (name), "%s (%s)", name, piclclass);
22191708Sstevel
22201708Sstevel err = picldiag_get_string_propval(nodeh, OBP_PROP_STATUS, &status);
22211708Sstevel if (err == PICL_PROPNOTFOUND) {
22221708Sstevel status = malloc(5);
22231708Sstevel strncpy(status, "okay", 5);
22241708Sstevel } else if (err != PICL_SUCCESS)
22251708Sstevel return (err);
22261708Sstevel
22271708Sstevel err = picldiag_get_fru_parent(nodeh, &fruparenth);
22281708Sstevel if (err == PICL_PROPNOTFOUND) {
22291708Sstevel label = NULL;
22301708Sstevel } else if (err != PICL_SUCCESS) {
22311708Sstevel return (err);
22321708Sstevel } else {
22331708Sstevel err = picldiag_get_combined_label(fruparenth, &label, 15);
22341708Sstevel if (err == PICL_PROPNOTFOUND)
22351708Sstevel label = NULL;
22361708Sstevel else if (err != PICL_SUCCESS)
22371708Sstevel return (err);
22381708Sstevel }
22391708Sstevel /* devfs-path */
22401708Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_DEVFS_PATH,
22411708Sstevel &devfs_path);
22421708Sstevel if (err == PICL_PROPNOTFOUND)
22431708Sstevel devfs_path = NULL;
22441708Sstevel else if (err != PICL_SUCCESS)
22451708Sstevel return (err);
22461708Sstevel
22471708Sstevel add_io_card(boardnum, bus_id, slot, label, freq, name, model, status,
22481708Sstevel devfs_path);
22491708Sstevel if (label != NULL)
22501708Sstevel free(label);
22511708Sstevel if (model != NULL)
22521708Sstevel free(model);
22531708Sstevel if (status != NULL)
22541708Sstevel free(status);
22551708Sstevel if (devfs_path != NULL)
22561708Sstevel free(devfs_path);
22571708Sstevel
22581708Sstevel return (PICL_SUCCESS);
22591708Sstevel }
22601708Sstevel
22611708Sstevel /*
22621708Sstevel * loop through all children and add io devices in io list
22631708Sstevel */
22641708Sstevel static int
process_io_leaves(picl_nodehdl_t rooth)22651708Sstevel process_io_leaves(picl_nodehdl_t rooth)
22661708Sstevel {
22671708Sstevel picl_nodehdl_t nodeh;
22681708Sstevel char classval[PICL_CLASSNAMELEN_MAX];
22691708Sstevel int err;
22701708Sstevel
22711708Sstevel err = picl_get_propval_by_name(rooth, PICL_PROP_CHILD, &nodeh,
22721708Sstevel sizeof (picl_nodehdl_t));
22731708Sstevel while (err == PICL_SUCCESS) {
22741708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
22751708Sstevel classval, sizeof (classval));
22761708Sstevel if (err != PICL_SUCCESS)
22771708Sstevel return (err);
22781708Sstevel
22791708Sstevel if (is_io_device(classval))
22801708Sstevel err = add_io_devices(nodeh);
22811708Sstevel
22821708Sstevel if (err != PICL_SUCCESS)
22831708Sstevel return (err);
22841708Sstevel
22851708Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh,
22861708Sstevel sizeof (picl_nodehdl_t));
22871708Sstevel }
22881708Sstevel
22891708Sstevel if (err == PICL_PROPNOTFOUND)
22901708Sstevel return (PICL_SUCCESS);
22911708Sstevel
22921708Sstevel return (err);
22931708Sstevel }
22941708Sstevel
22951708Sstevel /*
22961708Sstevel * callback function to add all io devices under upa in io list
22971708Sstevel */
22981708Sstevel /*ARGSUSED*/
22991708Sstevel static int
upa_callback(picl_nodehdl_t upah,void * args)23001708Sstevel upa_callback(picl_nodehdl_t upah, void *args)
23011708Sstevel {
23021708Sstevel int err;
23031708Sstevel
23041708Sstevel err = process_io_leaves(upah);
23051708Sstevel
23061708Sstevel if (err == PICL_SUCCESS)
23071708Sstevel return (PICL_WALK_CONTINUE);
23081708Sstevel return (err);
23091708Sstevel }
23101708Sstevel
23111708Sstevel /*
23121708Sstevel * display ffb hardware configuration
23131708Sstevel */
23141708Sstevel /* ARGSUSED */
23151708Sstevel static int
ffbconfig_callback(picl_nodehdl_t ffbh,void * arg)23161708Sstevel ffbconfig_callback(picl_nodehdl_t ffbh, void *arg)
23171708Sstevel {
23181708Sstevel int err;
23191708Sstevel uint64_t board_rev;
23201708Sstevel uint64_t fbc_ver;
23211708Sstevel char *dac_ver;
23221708Sstevel char *fbram_ver;
23231708Sstevel
23241708Sstevel /*
23251708Sstevel * If it has PICL_PROP_FFB_BOARD_REV, it is a ffb device
23261708Sstevel * Otherwise, return.
23271708Sstevel */
23281708Sstevel board_rev = picldiag_get_uint_propval(ffbh, PICL_PROP_FFB_BOARD_REV,
23291708Sstevel &err);
23301708Sstevel if (err == PICL_PROPNOTFOUND)
23311708Sstevel return (PICL_WALK_CONTINUE);
23321708Sstevel else if (err != PICL_SUCCESS)
23331708Sstevel return (err);
23341708Sstevel
23351708Sstevel log_printf("FFB Hardware Configuration:\n");
23361708Sstevel log_printf("-----------------------------------\n");
23371708Sstevel log_printf("Board rev: %lld\n", board_rev);
23381708Sstevel
23391708Sstevel fbc_ver = picldiag_get_uint_propval(ffbh, OBP_PROP_FBC_REG_ID,
23401708Sstevel &err);
23411708Sstevel if (err == PICL_SUCCESS)
23421708Sstevel log_printf("FBC version: 0x%llx\n", fbc_ver);
23431708Sstevel else if (err != PICL_PROPNOTFOUND)
23441708Sstevel return (err);
23451708Sstevel
23461708Sstevel err = picldiag_get_string_propval(ffbh, PICL_PROP_FFB_DAC_VER,
23471708Sstevel &dac_ver);
23481708Sstevel if (err == PICL_SUCCESS) {
23491708Sstevel log_printf("DAC: %s\n", dac_ver);
23501708Sstevel free(dac_ver);
23511708Sstevel } else if (err != PICL_PROPNOTFOUND)
23521708Sstevel return (err);
23531708Sstevel
23541708Sstevel err = picldiag_get_string_propval(ffbh, PICL_PROP_FFB_FBRAM_VER,
23551708Sstevel &fbram_ver);
23561708Sstevel if (err == PICL_SUCCESS) {
23571708Sstevel log_printf("3DRAM: %s\n", fbram_ver);
23581708Sstevel free(fbram_ver);
23591708Sstevel } else if (err != PICL_PROPNOTFOUND)
23601708Sstevel return (err);
23611708Sstevel
23621708Sstevel log_printf("\n");
23631708Sstevel return (PICL_WALK_CONTINUE);
23641708Sstevel }
23651708Sstevel
23661708Sstevel /*
23671708Sstevel * find all io devices and add them in the io list
23681708Sstevel */
23691708Sstevel static int
gather_io_cards(picl_nodehdl_t plafh)23701708Sstevel gather_io_cards(picl_nodehdl_t plafh)
23711708Sstevel {
23721708Sstevel int err;
23731708Sstevel
23741708Sstevel /*
23751708Sstevel * look for io devices under the immediate children of platform
23761708Sstevel */
23771708Sstevel err = process_io_leaves(plafh);
23781708Sstevel
23791708Sstevel if (err != PICL_SUCCESS)
23801708Sstevel return (err);
23811708Sstevel
23821708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_SBUS,
23831708Sstevel PICL_CLASS_SBUS, sbus_callback);
23841708Sstevel if (err != PICL_SUCCESS)
23851708Sstevel return (err);
23861708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_PCI,
23871708Sstevel PICL_CLASS_PCI, pci_callback);
23881708Sstevel if (err != PICL_SUCCESS)
23891708Sstevel return (err);
23901708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_UPA,
23911708Sstevel PICL_CLASS_UPA, upa_callback);
23921708Sstevel return (err);
23931708Sstevel }
23941708Sstevel
23951708Sstevel static void
picldiag_display_io_cards(struct io_card * list)23961708Sstevel picldiag_display_io_cards(struct io_card *list)
23971708Sstevel {
23981708Sstevel static int banner = 0; /* Have we printed the column headings? */
23991708Sstevel struct io_card *p;
24001708Sstevel
24011708Sstevel if (list == NULL)
24021708Sstevel return;
24031708Sstevel
24041708Sstevel if (banner == 0) {
24051708Sstevel log_printf("Bus Freq Slot + Name +\n", 0);
24061708Sstevel log_printf("Type MHz Status "
2407*13019SMichael.Bergknoff@Oracle.COM "Path "
2408*13019SMichael.Bergknoff@Oracle.COM "Model", 0);
24091708Sstevel log_printf("\n", 0);
24101708Sstevel log_printf("---- ---- ---------- "
2411*13019SMichael.Bergknoff@Oracle.COM "---------------------------- "
2412*13019SMichael.Bergknoff@Oracle.COM "--------------------", 0);
24131708Sstevel log_printf("\n", 0);
24141708Sstevel banner = 1;
24151708Sstevel }
24161708Sstevel
24171708Sstevel for (p = list; p != NULL; p = p -> next) {
24181708Sstevel log_printf("%-4s ", p->bus_type, 0);
24191708Sstevel log_printf("%3d ", p->freq, 0);
24201708Sstevel /*
24211708Sstevel * We check to see if it's an int or
24221708Sstevel * a char string to display for slot.
24231708Sstevel */
24241708Sstevel if (p->slot == PCI_SLOT_IS_STRING)
24251708Sstevel log_printf("%10s ", p->slot_str, 0);
24261708Sstevel else
24271708Sstevel log_printf("%10d ", p->slot, 0);
24281708Sstevel
24291708Sstevel log_printf("%-28.28s", p->name, 0);
24301708Sstevel if (strlen(p->name) > 28)
24311708Sstevel log_printf("+ ", 0);
24321708Sstevel else
24331708Sstevel log_printf(" ", 0);
24341708Sstevel log_printf("%-19.19s", p->model, 0);
24351708Sstevel if (strlen(p->model) > 19)
24361708Sstevel log_printf("+", 0);
24371708Sstevel log_printf("\n", 0);
24381708Sstevel log_printf(" %10s ", p->status, 0);
24393873Skd93003 set_exit_code(p->status);
24401708Sstevel if (strlen(p->notes) > 0)
24411708Sstevel log_printf("%s", p->notes, 0);
24421708Sstevel log_printf("\n\n", 0);
24431708Sstevel }
24441708Sstevel }
24451708Sstevel
24461708Sstevel /*
24471708Sstevel * display all io devices
24481708Sstevel */
24491708Sstevel static int
display_io_device_info(picl_nodehdl_t plafh)24501708Sstevel display_io_device_info(picl_nodehdl_t plafh)
24511708Sstevel {
24521708Sstevel int err;
24531708Sstevel
24541708Sstevel err = gather_io_cards(plafh);
24551708Sstevel if (err != PICL_SUCCESS)
24561708Sstevel return (err);
24571708Sstevel
24581708Sstevel logprintf_header(dgettext(TEXT_DOMAIN, "IO Devices"),
24591708Sstevel DEFAULT_LINE_WIDTH);
24601708Sstevel
24611708Sstevel picldiag_display_io_cards(io_card_list);
24621708Sstevel
24631708Sstevel free_io_cards(io_card_list);
24641708Sstevel
24651708Sstevel return (PICL_SUCCESS);
24661708Sstevel }
24671708Sstevel
24681708Sstevel /*
24691708Sstevel * print fan device information
24701708Sstevel */
24711708Sstevel static int
logprintf_fan_info(picl_nodehdl_t fanh)24721708Sstevel logprintf_fan_info(picl_nodehdl_t fanh)
24731708Sstevel {
24741708Sstevel int err;
24751708Sstevel char *label;
24761708Sstevel char *unit;
24771708Sstevel int64_t speed;
24781708Sstevel int64_t min_speed;
24791708Sstevel picl_nodehdl_t fruph;
24801708Sstevel
24811708Sstevel err = picldiag_get_fru_parent(fanh, &fruph);
24821708Sstevel if (err != PICL_SUCCESS)
24831708Sstevel return (err);
24841708Sstevel
24851708Sstevel err = picldiag_get_combined_label(fruph, &label, 14);
24861708Sstevel if (err != PICL_SUCCESS)
24871708Sstevel return (err);
24881708Sstevel
24891708Sstevel log_printf("%-14s ", label);
24901708Sstevel free(label);
24911708Sstevel
24921708Sstevel err = picldiag_get_label(fanh, &label);
24931708Sstevel if (err == PICL_SUCCESS) {
24941708Sstevel log_printf("%-14s ", label);
24951708Sstevel free(label);
24961708Sstevel } else if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) {
24971708Sstevel log_printf(" - ");
24981708Sstevel } else
24991708Sstevel return (err);
25001708Sstevel
25011708Sstevel speed = picldiag_get_uint_propval(fanh, PICL_PROP_FAN_SPEED, &err);
25021708Sstevel if (err == PICL_SUCCESS) {
25031708Sstevel min_speed = picldiag_get_uint_propval(fanh,
25041708Sstevel PICL_PROP_LOW_WARNING_THRESHOLD, &err);
25051708Sstevel if (err != PICL_SUCCESS)
25061708Sstevel min_speed = 1;
25071708Sstevel if (speed < min_speed) {
25081708Sstevel log_printf("failed (%lld", speed);
25091708Sstevel err = picldiag_get_string_propval(fanh,
25101708Sstevel PICL_PROP_FAN_SPEED_UNIT, &unit);
25111708Sstevel if (err == PICL_SUCCESS) {
25121708Sstevel log_printf("%s", unit);
25131708Sstevel free(unit);
25141708Sstevel }
25151708Sstevel log_printf(")");
25163873Skd93003 exit_code = PD_SYSTEM_FAILURE;
25171708Sstevel } else {
25181708Sstevel log_printf("okay");
25191708Sstevel }
25201708Sstevel } else {
25211708Sstevel err = picldiag_get_string_propval(fanh,
25221708Sstevel PICL_PROP_FAN_SPEED_UNIT, &unit);
25231708Sstevel if (err == PICL_SUCCESS) {
25241708Sstevel log_printf("%-12s ", unit);
25251708Sstevel free(unit);
25261708Sstevel }
25271708Sstevel }
25281708Sstevel
25291708Sstevel log_printf("\n");
25301708Sstevel return (PICL_SUCCESS);
25311708Sstevel }
25321708Sstevel
25331708Sstevel static int
fan_callback(picl_nodehdl_t fanh,void * arg)25341708Sstevel fan_callback(picl_nodehdl_t fanh, void *arg)
25351708Sstevel {
25361708Sstevel int *countp = arg;
25371708Sstevel int err;
25381708Sstevel
25391708Sstevel if (*countp == 0) {
25401708Sstevel log_printf(dgettext(TEXT_DOMAIN, "Fan Status:\n"));
25411708Sstevel log_printf("---------------------------------------\n");
25421708Sstevel log_printf("Location Sensor Status \n");
25431708Sstevel log_printf("---------------------------------------\n");
25441708Sstevel }
25451708Sstevel *countp += 1;
25461708Sstevel err = logprintf_fan_info(fanh);
25471708Sstevel if (err == PICL_SUCCESS)
25481708Sstevel return (PICL_WALK_CONTINUE);
25491708Sstevel return (err);
25501708Sstevel }
25511708Sstevel
25521708Sstevel /*
25531708Sstevel * callback function search children to find fan device and print its speed
25541708Sstevel */
25551708Sstevel static int
display_fan_speed(picl_nodehdl_t plafh)25561708Sstevel display_fan_speed(picl_nodehdl_t plafh)
25571708Sstevel {
25581708Sstevel int err;
25591708Sstevel int print_header;
25601708Sstevel
25611708Sstevel print_header = 0;
25621708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_FAN,
25631708Sstevel &print_header, fan_callback);
25641708Sstevel return (err);
25651708Sstevel }
25661708Sstevel
25671708Sstevel /*
25681708Sstevel * print temperature sensor information
25691708Sstevel */
25701708Sstevel static int
logprintf_temp_info(picl_nodehdl_t temph)25711708Sstevel logprintf_temp_info(picl_nodehdl_t temph)
25721708Sstevel {
25731708Sstevel int err;
25741708Sstevel char *label;
25751708Sstevel int64_t temperature;
25761708Sstevel int64_t threshold;
25771708Sstevel picl_nodehdl_t fruph;
25781708Sstevel char *status = "unknown";
25791708Sstevel int got_temp = 0;
25801708Sstevel
25811708Sstevel err = picldiag_get_fru_parent(temph, &fruph);
25821708Sstevel if (err != PICL_SUCCESS)
25831708Sstevel return (err);
25841708Sstevel
25851708Sstevel err = picldiag_get_combined_label(fruph, &label, 14);
25861708Sstevel if (err != PICL_SUCCESS)
25871708Sstevel return (err);
25881708Sstevel
25891708Sstevel log_printf("%-14s ", label);
25901708Sstevel free(label);
25911708Sstevel
25921708Sstevel err = picldiag_get_label(temph, &label);
25931708Sstevel if (err != PICL_SUCCESS)
25941708Sstevel return (err);
25951708Sstevel log_printf("%-14s ", label);
25961708Sstevel free(label);
25971708Sstevel
25981708Sstevel temperature = picldiag_get_int_propval(temph, PICL_PROP_TEMPERATURE,
25991708Sstevel &err);
26001708Sstevel if (err == PICL_SUCCESS) {
26011708Sstevel got_temp = 1;
26021708Sstevel status = "okay";
26031708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
26041708Sstevel return (err);
26051708Sstevel }
26061708Sstevel
26071708Sstevel threshold = picldiag_get_int_propval(temph, PICL_PROP_LOW_WARNING,
26081708Sstevel &err);
26091708Sstevel if (err == PICL_SUCCESS) {
26101708Sstevel if (got_temp && temperature < threshold)
26111708Sstevel status = "warning";
26121708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
26131708Sstevel return (err);
26141708Sstevel }
26151708Sstevel
26161708Sstevel threshold = picldiag_get_int_propval(temph, PICL_PROP_LOW_SHUTDOWN,
26171708Sstevel &err);
26181708Sstevel if (err == PICL_SUCCESS) {
26191708Sstevel if (got_temp && temperature < threshold)
26201708Sstevel status = "failed";
26211708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
26221708Sstevel return (err);
26231708Sstevel }
26241708Sstevel
26251708Sstevel threshold = picldiag_get_int_propval(temph, PICL_PROP_HIGH_WARNING,
26261708Sstevel &err);
26271708Sstevel if (err == PICL_SUCCESS) {
26281708Sstevel if (got_temp && temperature > threshold)
26291708Sstevel status = "warning";
26301708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
26311708Sstevel return (err);
26321708Sstevel }
26331708Sstevel
26341708Sstevel threshold = picldiag_get_int_propval(temph, PICL_PROP_HIGH_SHUTDOWN,
26351708Sstevel &err);
26361708Sstevel if (err == PICL_SUCCESS) {
26371708Sstevel if (got_temp && temperature > threshold)
26381708Sstevel status = "failed";
26391708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
26401708Sstevel return (err);
26411708Sstevel }
26421708Sstevel
26431708Sstevel err = picldiag_get_string_propval(temph, PICL_PROP_CONDITION, &status);
26441708Sstevel if (err == PICL_SUCCESS) {
26451708Sstevel log_printf("%s", status);
26463873Skd93003 set_exit_code(status);
26471708Sstevel free(status);
26481708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
26491708Sstevel return (err);
26501708Sstevel } else {
26511708Sstevel log_printf("%s ", status);
26523873Skd93003 set_exit_code(status);
26531708Sstevel if (strcmp(status, "failed") == 0 ||
26541708Sstevel strcmp(status, "warning") == 0)
26551708Sstevel log_printf("(%.2lldC)", temperature);
26561708Sstevel }
26571708Sstevel
26581708Sstevel log_printf("\n");
26591708Sstevel return (PICL_SUCCESS);
26601708Sstevel }
26611708Sstevel
26621708Sstevel static int
temp_callback(picl_nodehdl_t temph,void * arg)26631708Sstevel temp_callback(picl_nodehdl_t temph, void *arg)
26641708Sstevel {
26651708Sstevel int err;
26661708Sstevel int *countp = arg;
26671708Sstevel
26681708Sstevel if (*countp == 0) {
26691708Sstevel log_printf("\n");
26701708Sstevel log_printf("---------------------------------------\n");
26711708Sstevel log_printf(dgettext(TEXT_DOMAIN, "Temperature sensors:\n"));
26721708Sstevel log_printf("------------------------------------\n");
26731708Sstevel log_printf("Location Sensor Status\n");
26741708Sstevel log_printf("------------------------------------\n");
26751708Sstevel }
26761708Sstevel *countp += 1;
26771708Sstevel err = logprintf_temp_info(temph);
26781708Sstevel if (err == PICL_SUCCESS)
26791708Sstevel return (PICL_WALK_CONTINUE);
26801708Sstevel return (err);
26811708Sstevel }
26821708Sstevel
26831708Sstevel /*
26841708Sstevel * callback function search children to find temp sensors and print the temp
26851708Sstevel */
26861708Sstevel /* ARGSUSED */
26871708Sstevel static int
display_temp(picl_nodehdl_t plafh)26881708Sstevel display_temp(picl_nodehdl_t plafh)
26891708Sstevel {
26901708Sstevel int err;
26911708Sstevel int print_header;
26921708Sstevel
26931708Sstevel print_header = 0;
26941708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_TEMPERATURE_SENSOR,
26951708Sstevel &print_header, temp_callback);
26961708Sstevel if (err != PICL_SUCCESS)
26971708Sstevel return (err);
26981708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_TEMPERATURE_INDICATOR,
26991708Sstevel &print_header, temp_callback);
27001708Sstevel return (err);
27011708Sstevel }
27021708Sstevel
27031708Sstevel /*
27041708Sstevel * print current sensor information
27051708Sstevel */
27061708Sstevel static int
logprintf_current_info(picl_nodehdl_t currenth)27071708Sstevel logprintf_current_info(picl_nodehdl_t currenth)
27081708Sstevel {
27091708Sstevel int err;
27101708Sstevel char *label;
27111708Sstevel float current;
27121708Sstevel float threshold;
27131708Sstevel picl_nodehdl_t fruph;
27141708Sstevel char *status = "unknown";
27151708Sstevel int got_current = 0;
27161708Sstevel
27171708Sstevel err = picldiag_get_fru_parent(currenth, &fruph);
27181708Sstevel if (err != PICL_SUCCESS)
27191708Sstevel return (err);
27201708Sstevel
27211708Sstevel err = picldiag_get_combined_label(fruph, &label, 10);
27221708Sstevel if (err != PICL_SUCCESS)
27231708Sstevel return (err);
27241708Sstevel
27251708Sstevel log_printf("%-10s ", label);
27261708Sstevel free(label);
27271708Sstevel
27281708Sstevel err = picldiag_get_label(currenth, &label);
27291708Sstevel if (err != PICL_SUCCESS)
27301708Sstevel return (err);
27311708Sstevel log_printf("%-10s ", label);
27321708Sstevel free(label);
27331708Sstevel
27341708Sstevel current = picldiag_get_float_propval(currenth, PICL_PROP_CURRENT, &err);
27351708Sstevel if (err == PICL_SUCCESS) {
27361708Sstevel status = "okay";
27371708Sstevel got_current = 1;
27381708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
27391708Sstevel return (err);
27401708Sstevel }
27411708Sstevel
27421708Sstevel threshold = picldiag_get_float_propval(currenth, PICL_PROP_LOW_WARNING,
27431708Sstevel &err);
27441708Sstevel if (err == PICL_SUCCESS) {
27451708Sstevel if (got_current && current < threshold)
27461708Sstevel status = "warning";
27471708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
27481708Sstevel return (err);
27491708Sstevel }
27501708Sstevel
27511708Sstevel threshold = picldiag_get_float_propval(currenth, PICL_PROP_LOW_SHUTDOWN,
27521708Sstevel &err);
27531708Sstevel if (err == PICL_SUCCESS) {
27541708Sstevel if (got_current && current < threshold)
27551708Sstevel status = "failed";
27561708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
27571708Sstevel return (err);
27581708Sstevel }
27591708Sstevel
27601708Sstevel threshold = picldiag_get_float_propval(currenth, PICL_PROP_HIGH_WARNING,
27611708Sstevel &err);
27621708Sstevel if (err == PICL_SUCCESS) {
27631708Sstevel if (got_current && current > threshold)
27641708Sstevel status = "warning";
27651708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
27661708Sstevel return (err);
27671708Sstevel }
27681708Sstevel
27691708Sstevel threshold = picldiag_get_float_propval(currenth,
27701708Sstevel PICL_PROP_HIGH_SHUTDOWN, &err);
27711708Sstevel if (err == PICL_SUCCESS) {
27721708Sstevel if (got_current && current > threshold)
27731708Sstevel status = "failed";
27741708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
27751708Sstevel return (err);
27761708Sstevel }
27771708Sstevel
27781708Sstevel err = picldiag_get_string_propval(currenth,
27791708Sstevel PICL_PROP_CONDITION, &status);
27801708Sstevel if (err == PICL_SUCCESS) {
27811708Sstevel log_printf(" %s", status);
27823873Skd93003 set_exit_code(status);
27831708Sstevel free(status);
27841708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
27851708Sstevel return (err);
27861708Sstevel } else {
27871708Sstevel log_printf("%s ", status);
27883873Skd93003 set_exit_code(status);
27891708Sstevel if (strcmp(status, "failed") == 0 ||
27901708Sstevel strcmp(status, "warning") == 0)
27911708Sstevel log_printf("(%.2fA)", current);
27921708Sstevel }
27931708Sstevel
27941708Sstevel log_printf("\n");
27951708Sstevel return (PICL_SUCCESS);
27961708Sstevel }
27971708Sstevel
27981708Sstevel static int
current_callback(picl_nodehdl_t currh,void * arg)27991708Sstevel current_callback(picl_nodehdl_t currh, void *arg)
28001708Sstevel {
28011708Sstevel int err;
28021708Sstevel int *countp = arg;
28031708Sstevel
28041708Sstevel if (*countp == 0) {
28051708Sstevel log_printf("------------------------------------\n");
28061708Sstevel log_printf(dgettext(TEXT_DOMAIN, "Current sensors:\n"));
28071708Sstevel log_printf("------------------------------\n");
28081708Sstevel log_printf("Location Sensor Status\n");
28091708Sstevel log_printf("------------------------------\n");
28101708Sstevel }
28111708Sstevel *countp += 1;
28121708Sstevel err = logprintf_current_info(currh);
28131708Sstevel if (err == PICL_SUCCESS)
28141708Sstevel return (PICL_WALK_CONTINUE);
28151708Sstevel return (err);
28161708Sstevel }
28171708Sstevel
28181708Sstevel /*
28191708Sstevel * callback function search children to find curr sensors and print the curr
28201708Sstevel */
28211708Sstevel /* ARGSUSED */
28221708Sstevel static int
display_current(picl_nodehdl_t plafh)28231708Sstevel display_current(picl_nodehdl_t plafh)
28241708Sstevel {
28251708Sstevel int err;
28261708Sstevel int print_header;
28271708Sstevel
28281708Sstevel print_header = 0;
28291708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_CURRENT_SENSOR,
28301708Sstevel &print_header, current_callback);
28311708Sstevel if (err != PICL_SUCCESS)
28321708Sstevel return (err);
28331708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_CURRENT_INDICATOR,
28341708Sstevel &print_header, current_callback);
28351708Sstevel return (err);
28361708Sstevel }
28371708Sstevel
28381708Sstevel /*
28391708Sstevel * print voltage sensor information
28401708Sstevel */
28411708Sstevel static int
logprintf_voltage_info(picl_nodehdl_t voltageh)28421708Sstevel logprintf_voltage_info(picl_nodehdl_t voltageh)
28431708Sstevel {
28441708Sstevel int err;
28451708Sstevel char *label;
28461708Sstevel float voltage;
28471708Sstevel float threshold;
28481708Sstevel picl_nodehdl_t fruph;
28491708Sstevel char *status = "unknown";
28501708Sstevel int got_voltage = 0;
28511708Sstevel
28521708Sstevel err = picldiag_get_fru_parent(voltageh, &fruph);
28531708Sstevel if (err != PICL_SUCCESS)
28541708Sstevel return (err);
28551708Sstevel
28561708Sstevel err = picldiag_get_combined_label(fruph, &label, 10);
28571708Sstevel if (err != PICL_SUCCESS)
28581708Sstevel return (err);
28591708Sstevel
28601708Sstevel log_printf("%-10s ", label);
28611708Sstevel free(label);
28621708Sstevel
28631708Sstevel err = picldiag_get_label(voltageh, &label);
28641708Sstevel if (err != PICL_SUCCESS)
28651708Sstevel return (err);
28661708Sstevel log_printf("%-12s ", label);
28671708Sstevel free(label);
28681708Sstevel
28691708Sstevel voltage = picldiag_get_float_propval(voltageh, PICL_PROP_VOLTAGE, &err);
28701708Sstevel if (err == PICL_SUCCESS) {
28711708Sstevel status = "okay";
28721708Sstevel got_voltage = 1;
28731708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
28741708Sstevel return (err);
28751708Sstevel }
28761708Sstevel
28771708Sstevel threshold = picldiag_get_float_propval(voltageh, PICL_PROP_LOW_WARNING,
28781708Sstevel &err);
28791708Sstevel if (err == PICL_SUCCESS) {
28801708Sstevel if (got_voltage && voltage < threshold)
28811708Sstevel status = "warning";
28821708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
28831708Sstevel return (err);
28841708Sstevel }
28851708Sstevel
28861708Sstevel threshold = picldiag_get_float_propval(voltageh, PICL_PROP_LOW_SHUTDOWN,
28871708Sstevel &err);
28881708Sstevel if (err == PICL_SUCCESS) {
28891708Sstevel if (got_voltage && voltage < threshold)
28901708Sstevel status = "failed";
28911708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
28921708Sstevel return (err);
28931708Sstevel }
28941708Sstevel
28951708Sstevel threshold = picldiag_get_float_propval(voltageh, PICL_PROP_HIGH_WARNING,
28961708Sstevel &err);
28971708Sstevel if (err == PICL_SUCCESS) {
28981708Sstevel if (got_voltage && voltage > threshold)
28991708Sstevel status = "warning";
29001708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
29011708Sstevel return (err);
29021708Sstevel }
29031708Sstevel
29041708Sstevel threshold = picldiag_get_float_propval(voltageh,
29051708Sstevel PICL_PROP_HIGH_SHUTDOWN, &err);
29061708Sstevel if (err == PICL_SUCCESS) {
29071708Sstevel if (got_voltage && voltage > threshold)
29081708Sstevel status = "failed";
29091708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
29101708Sstevel return (err);
29111708Sstevel }
29121708Sstevel
29131708Sstevel err = picldiag_get_string_propval(voltageh,
29141708Sstevel PICL_PROP_CONDITION, &status);
29151708Sstevel if (err == PICL_SUCCESS) {
29161708Sstevel log_printf("%s", status);
29173873Skd93003 set_exit_code(status);
29181708Sstevel free(status);
29191708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
29201708Sstevel return (err);
29211708Sstevel } else {
29221708Sstevel log_printf("%s ", status);
29233873Skd93003 set_exit_code(status);
29241708Sstevel if (strcmp(status, "warning") == 0 ||
29251708Sstevel strcmp(status, "failed") == 0)
29261708Sstevel log_printf("(%.2fV)", voltage);
29271708Sstevel }
29281708Sstevel
29291708Sstevel log_printf("\n");
29301708Sstevel return (PICL_SUCCESS);
29311708Sstevel }
29321708Sstevel
29331708Sstevel static int
voltage_callback(picl_nodehdl_t voltageh,void * arg)29341708Sstevel voltage_callback(picl_nodehdl_t voltageh, void *arg)
29351708Sstevel {
29361708Sstevel int *countp = arg;
29371708Sstevel int err;
29381708Sstevel
29391708Sstevel if (*countp == 0) {
29401708Sstevel log_printf("--------------------------------\n");
29411708Sstevel log_printf(dgettext(TEXT_DOMAIN, "Voltage sensors:\n"));
29421708Sstevel log_printf("-------------------------------\n");
29431708Sstevel log_printf("Location Sensor Status\n");
29441708Sstevel log_printf("-------------------------------\n");
29451708Sstevel }
29461708Sstevel *countp += 1;
29471708Sstevel err = logprintf_voltage_info(voltageh);
29481708Sstevel if (err == PICL_SUCCESS)
29491708Sstevel return (PICL_WALK_CONTINUE);
29501708Sstevel return (err);
29511708Sstevel }
29521708Sstevel
29531708Sstevel /*
29541708Sstevel * callback function search children to find voltage sensors and print voltage
29551708Sstevel */
29561708Sstevel /* ARGSUSED */
29571708Sstevel static int
display_voltage(picl_nodehdl_t plafh)29581708Sstevel display_voltage(picl_nodehdl_t plafh)
29591708Sstevel {
29601708Sstevel int err;
29611708Sstevel int print_header;
29621708Sstevel
29631708Sstevel print_header = 0;
29641708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_VOLTAGE_SENSOR,
29651708Sstevel &print_header, voltage_callback);
29661708Sstevel if (err != PICL_SUCCESS)
29671708Sstevel return (err);
29681708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_VOLTAGE_INDICATOR,
29691708Sstevel &print_header, voltage_callback);
29701708Sstevel return (err);
29711708Sstevel }
29721708Sstevel
29731708Sstevel /*
29741708Sstevel * print led device information
29751708Sstevel */
29761708Sstevel static int
logprintf_led_info(picl_nodehdl_t ledh)29771708Sstevel logprintf_led_info(picl_nodehdl_t ledh)
29781708Sstevel {
29791708Sstevel int err;
29801708Sstevel char *label;
29811708Sstevel char *state;
29821708Sstevel char *color;
29831708Sstevel picl_nodehdl_t fruph;
29841708Sstevel
29851708Sstevel err = picldiag_get_fru_parent(ledh, &fruph);
29861708Sstevel if (err != PICL_SUCCESS)
29871708Sstevel return (err);
29881708Sstevel
29891708Sstevel err = picldiag_get_combined_label(fruph, &label, 10);
29901708Sstevel if (err != PICL_SUCCESS) {
29911708Sstevel log_printf(" - ", label);
29921708Sstevel } else {
29931708Sstevel log_printf("%-10s ", label);
29941708Sstevel free(label);
29951708Sstevel }
29961708Sstevel
29971708Sstevel err = picldiag_get_label(ledh, &label);
29981708Sstevel if (err != PICL_SUCCESS)
29991708Sstevel return (err);
30001708Sstevel log_printf("%-20s ", label);
30011708Sstevel free(label);
30021708Sstevel
30031708Sstevel err = picldiag_get_string_propval(ledh, PICL_PROP_STATE, &state);
30041708Sstevel if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) {
30051708Sstevel log_printf(" - ");
30061708Sstevel } else if (err != PICL_SUCCESS) {
30071708Sstevel return (err);
30081708Sstevel } else {
30091708Sstevel log_printf("%-10s ", state);
30101708Sstevel free(state);
30111708Sstevel }
30121708Sstevel
30131708Sstevel err = picldiag_get_string_propval(ledh, PICL_PROP_COLOR, &color);
30141708Sstevel if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) {
30151708Sstevel log_printf("\n");
30161708Sstevel } else if (err != PICL_SUCCESS) {
30171708Sstevel return (err);
30181708Sstevel } else {
30191708Sstevel log_printf("%-16s\n", color);
30201708Sstevel free(color);
30211708Sstevel }
30221708Sstevel
30231708Sstevel return (PICL_SUCCESS);
30241708Sstevel }
30251708Sstevel
30261708Sstevel static int
led_callback(picl_nodehdl_t ledh,void * arg)30271708Sstevel led_callback(picl_nodehdl_t ledh, void *arg)
30281708Sstevel {
30291708Sstevel int *countp = arg;
30301708Sstevel int err;
30311708Sstevel
30321708Sstevel if (*countp == 0) {
30331708Sstevel
30341708Sstevel log_printf("--------------------------------------"
30351708Sstevel "------------\n");
30361708Sstevel log_printf(dgettext(TEXT_DOMAIN, "Led State:\n"));
30371708Sstevel log_printf("--------------------------------------"
30381708Sstevel "------------\n");
30391708Sstevel log_printf("Location Led State"
30401708Sstevel " Color\n");
30411708Sstevel log_printf("--------------------------------------"
30421708Sstevel "------------\n");
30431708Sstevel }
30441708Sstevel *countp += 1;
30451708Sstevel err = logprintf_led_info(ledh);
30461708Sstevel if (err == PICL_SUCCESS)
30471708Sstevel return (PICL_WALK_CONTINUE);
30481708Sstevel return (err);
30491708Sstevel }
30501708Sstevel
30511708Sstevel /*
30521708Sstevel * callback function search children to find led devices and print status
30531708Sstevel */
30541708Sstevel /* ARGSUSED */
30551708Sstevel static int
display_led_status(picl_nodehdl_t plafh)30561708Sstevel display_led_status(picl_nodehdl_t plafh)
30571708Sstevel {
30581708Sstevel int print_header;
30591708Sstevel
30601708Sstevel print_header = 0;
30611708Sstevel picl_walk_tree_by_class(plafh, PICL_CLASS_LED,
30621708Sstevel &print_header, led_callback);
30631708Sstevel return (PICL_SUCCESS);
30641708Sstevel }
30651708Sstevel
30661708Sstevel /*
30671708Sstevel * print keyswitch device information
30681708Sstevel */
30691708Sstevel static int
logprintf_keyswitch_info(picl_nodehdl_t keyswitchh,picl_nodehdl_t fruph)30701708Sstevel logprintf_keyswitch_info(picl_nodehdl_t keyswitchh, picl_nodehdl_t fruph)
30711708Sstevel {
30721708Sstevel int err;
30731708Sstevel char *label;
30741708Sstevel char *state;
30751708Sstevel
30761708Sstevel err = picldiag_get_combined_label(fruph, &label, 10);
30771708Sstevel if (err != PICL_SUCCESS) {
30781708Sstevel log_printf("%-14s", " -");
30791708Sstevel } else {
30801708Sstevel log_printf("%-14s ", label);
30811708Sstevel free(label);
30821708Sstevel }
30831708Sstevel
30841708Sstevel err = picldiag_get_label(keyswitchh, &label);
30851708Sstevel if (err != PICL_SUCCESS)
30861708Sstevel return (err);
30871708Sstevel log_printf("%-11s ", label);
30881708Sstevel free(label);
30891708Sstevel
30901708Sstevel err = picldiag_get_string_propval(keyswitchh, PICL_PROP_STATE, &state);
30911708Sstevel if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) {
30921708Sstevel log_printf(" -\n");
30931708Sstevel } else if (err != PICL_SUCCESS) {
30941708Sstevel return (err);
30951708Sstevel } else {
30961708Sstevel log_printf("%s\n", state);
30971708Sstevel free(state);
30981708Sstevel }
30991708Sstevel
31001708Sstevel return (PICL_SUCCESS);
31011708Sstevel }
31021708Sstevel
31031708Sstevel static int
keyswitch_callback(picl_nodehdl_t keyswitchh,void * arg)31041708Sstevel keyswitch_callback(picl_nodehdl_t keyswitchh, void *arg)
31051708Sstevel {
31061708Sstevel int *countp = arg;
31071708Sstevel int err;
31081708Sstevel picl_nodehdl_t fruph;
31091708Sstevel
31101708Sstevel /*
31111708Sstevel * Tamale simulates a key-switch on ENxS. So the presence of a
31121708Sstevel * node of class keyswitch is not sufficient. If it has a fru parent
31131708Sstevel * or location parent, then believe it.
31141708Sstevel */
31151708Sstevel err = picl_get_propval_by_name(keyswitchh, PICL_REFPROP_FRU_PARENT,
31161708Sstevel &fruph, sizeof (fruph));
31171708Sstevel if (err == PICL_PROPNOTFOUND) {
31181708Sstevel err = picl_get_propval_by_name(keyswitchh,
31191708Sstevel PICL_REFPROP_LOC_PARENT, &fruph, sizeof (fruph));
31201708Sstevel }
31211708Sstevel if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE)
31221708Sstevel return (PICL_WALK_CONTINUE);
31231708Sstevel if (err != PICL_SUCCESS)
31241708Sstevel return (err);
31251708Sstevel
31261708Sstevel if (*countp == 0) {
31271708Sstevel log_printf("-----------------------------------------\n");
31281708Sstevel log_printf(dgettext(TEXT_DOMAIN, "Keyswitch:\n"));
31291708Sstevel log_printf("-----------------------------------------\n");
31301708Sstevel log_printf(dgettext(TEXT_DOMAIN,
31311708Sstevel "Location Keyswitch State\n"));
31321708Sstevel log_printf("-----------------------------------------\n");
31331708Sstevel }
31341708Sstevel *countp += 1;
31351708Sstevel err = logprintf_keyswitch_info(keyswitchh, fruph);
31361708Sstevel if (err == PICL_SUCCESS)
31371708Sstevel return (PICL_WALK_CONTINUE);
31381708Sstevel return (err);
31391708Sstevel }
31401708Sstevel
31411708Sstevel /*
31421708Sstevel * search children to find keyswitch device(s) and print status
31431708Sstevel */
31441708Sstevel /* ARGSUSED */
31451708Sstevel static int
display_keyswitch(picl_nodehdl_t plafh)31461708Sstevel display_keyswitch(picl_nodehdl_t plafh)
31471708Sstevel {
31481708Sstevel int print_header = 0;
31491708Sstevel
31501708Sstevel picl_walk_tree_by_class(plafh, PICL_CLASS_KEYSWITCH,
31511708Sstevel &print_header, keyswitch_callback);
31521708Sstevel return (PICL_SUCCESS);
31531708Sstevel }
31541708Sstevel
31551708Sstevel /*
31561708Sstevel * display environment status
31571708Sstevel */
31581708Sstevel static int
display_envctrl_status(picl_nodehdl_t plafh)31591708Sstevel display_envctrl_status(picl_nodehdl_t plafh)
31601708Sstevel {
31611708Sstevel logprintf_header(dgettext(TEXT_DOMAIN, "Environmental Status"),
31621708Sstevel DEFAULT_LINE_WIDTH);
31631708Sstevel
31641708Sstevel display_fan_speed(plafh);
31651708Sstevel display_temp(plafh);
31661708Sstevel display_current(plafh);
31671708Sstevel display_voltage(plafh);
31681708Sstevel display_keyswitch(plafh);
31691708Sstevel display_led_status(plafh);
31701708Sstevel
31711708Sstevel return (PICL_SUCCESS);
31721708Sstevel }
31731708Sstevel
31741708Sstevel /*
31751708Sstevel * print fru operational status
31761708Sstevel */
31771708Sstevel static int
logprintf_fru_oper_status(picl_nodehdl_t fruh,int * countp)31781708Sstevel logprintf_fru_oper_status(picl_nodehdl_t fruh, int *countp)
31791708Sstevel {
31801708Sstevel int err;
31811708Sstevel char *label;
31821708Sstevel char *status;
31831708Sstevel
31841708Sstevel err = picldiag_get_combined_label(fruh, &label, 15);
31851708Sstevel if (err != PICL_SUCCESS)
31861708Sstevel return (PICL_WALK_CONTINUE);
31871708Sstevel
31881708Sstevel err = picldiag_get_string_propval(fruh,
31891708Sstevel PICL_PROP_OPERATIONAL_STATUS, &status);
31901708Sstevel if (err == PICL_SUCCESS) {
31911708Sstevel if (*countp == 0) {
31921708Sstevel logprintf_header(dgettext(TEXT_DOMAIN,
31931708Sstevel "FRU Operational Status"),
31941708Sstevel DEFAULT_LINE_WIDTH);
31951708Sstevel log_printf("-------------------------\n");
31961708Sstevel log_printf(dgettext(TEXT_DOMAIN,
31971708Sstevel "Fru Operational Status:\n"));
31981708Sstevel log_printf("-------------------------\n");
31991708Sstevel log_printf("Location Status \n");
32001708Sstevel log_printf("-------------------------\n");
32011708Sstevel }
32021708Sstevel *countp += 1;
32031708Sstevel log_printf("%-15s ", label);
32041708Sstevel free(label);
32051708Sstevel log_printf("%s\n", status);
32063873Skd93003 set_exit_code(status);
32071708Sstevel free(status);
32081708Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
32091708Sstevel free(label);
32101708Sstevel return (err);
32111708Sstevel } else {
32121708Sstevel free(label);
32131708Sstevel }
32141708Sstevel return (PICL_WALK_CONTINUE);
32151708Sstevel }
32161708Sstevel
32171708Sstevel static int
fru_oper_status_callback(picl_nodehdl_t fruh,void * arg)32181708Sstevel fru_oper_status_callback(picl_nodehdl_t fruh, void *arg)
32191708Sstevel {
32201708Sstevel int err;
32211708Sstevel
32221708Sstevel err = logprintf_fru_oper_status(fruh, (int *)arg);
32231708Sstevel return (err);
32241708Sstevel }
32251708Sstevel
32261708Sstevel /*
32271708Sstevel * display fru operational status
32281708Sstevel */
32291708Sstevel static int
display_fru_oper_status(picl_nodehdl_t frutreeh)32301708Sstevel display_fru_oper_status(picl_nodehdl_t frutreeh)
32311708Sstevel {
32321708Sstevel int print_header;
32331708Sstevel
32341708Sstevel print_header = 0;
32351708Sstevel picl_walk_tree_by_class(frutreeh, PICL_CLASS_FRU,
32361708Sstevel &print_header, fru_oper_status_callback);
32371708Sstevel return (PICL_SUCCESS);
32381708Sstevel }
32391708Sstevel
32401708Sstevel /*
32411708Sstevel * check if the node having the version prop
32421708Sstevel * If yes, print its nodename and version
32431708Sstevel */
32441708Sstevel /* ARGSUSED */
32451708Sstevel static int
asicrev_callback(picl_nodehdl_t nodeh,void * arg)32461708Sstevel asicrev_callback(picl_nodehdl_t nodeh, void *arg)
32471708Sstevel {
32481708Sstevel uint32_t version;
32491708Sstevel char *name;
32501708Sstevel char *model;
32511708Sstevel char *status;
32521708Sstevel int err;
32531708Sstevel
32541708Sstevel version = picldiag_get_uint_propval(nodeh, OBP_PROP_VERSION_NUM,
32551708Sstevel &err);
32561708Sstevel if (err == PICL_PROPNOTFOUND)
32571708Sstevel return (PICL_WALK_CONTINUE);
32581708Sstevel else if (err != PICL_SUCCESS)
32591708Sstevel return (err);
32601708Sstevel
32611708Sstevel /* devfs-path */
32621708Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_DEVFS_PATH, &name);
32631708Sstevel if (err == PICL_PROPNOTFOUND)
32641708Sstevel name = NULL;
32651708Sstevel else if (err != PICL_SUCCESS)
32661708Sstevel return (err);
32671708Sstevel
32681708Sstevel /* model */
32691708Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_BINDING_NAME,
32701708Sstevel &model);
32711708Sstevel if (err == PICL_PROPNOTFOUND)
32721708Sstevel model = NULL;
32731708Sstevel else if (err != PICL_SUCCESS)
32741708Sstevel return (err);
32751708Sstevel
32761708Sstevel /* status */
32771708Sstevel err = picldiag_get_string_propval(nodeh, OBP_PROP_STATUS, &status);
32781708Sstevel if (err == PICL_PROPNOTFOUND)
32791708Sstevel status = NULL;
32801708Sstevel else if (err != PICL_SUCCESS)
32811708Sstevel return (err);
32821708Sstevel
32831708Sstevel /*
32841708Sstevel * Display the data
32851708Sstevel */
32861708Sstevel
32871708Sstevel /* name */
32881708Sstevel if (name != NULL) {
32891708Sstevel log_printf("%-22s ", name);
32901708Sstevel free(name);
32911708Sstevel } else
32921708Sstevel log_printf("%-22s ", "unknown");
32931708Sstevel /* model */
32941708Sstevel if (model != NULL) {
32951708Sstevel log_printf("%-15s ", model);
32961708Sstevel free(model);
32971708Sstevel } else
32981708Sstevel log_printf("%-15s ", "unknown");
32991708Sstevel /* status */
33001708Sstevel if (status == NULL)
33011708Sstevel log_printf("%-15s ", "okay");
33021708Sstevel else {
33031708Sstevel log_printf("%-15s ", status);
33043873Skd93003 set_exit_code(status);
33051708Sstevel free(status);
33061708Sstevel }
33071708Sstevel /* revision */
33081708Sstevel log_printf(" %-4d\n", version);
33091708Sstevel
33101708Sstevel return (PICL_WALK_CONTINUE);
33111708Sstevel }
33121708Sstevel
33131708Sstevel /*
33141708Sstevel * traverse the tree to display asic revision id for ebus
33151708Sstevel */
33161708Sstevel /* ARGSUSED */
33171708Sstevel static int
ebus_callback(picl_nodehdl_t ebush,void * arg)33181708Sstevel ebus_callback(picl_nodehdl_t ebush, void *arg)
33191708Sstevel {
33201708Sstevel uint32_t id;
33211708Sstevel char *name;
33221708Sstevel int err;
33231708Sstevel char *model;
33241708Sstevel char *status;
33251708Sstevel
33261708Sstevel id = picldiag_get_uint_propval(ebush, OBP_PROP_REVISION_ID, &err);
33271708Sstevel if (err == PICL_PROPNOTFOUND)
33281708Sstevel return (PICL_WALK_CONTINUE);
33291708Sstevel else if (err != PICL_SUCCESS)
33301708Sstevel return (err);
33311708Sstevel
33321708Sstevel /* devfs-path */
33331708Sstevel err = picldiag_get_string_propval(ebush, PICL_PROP_DEVFS_PATH, &name);
33341708Sstevel if (err == PICL_PROPNOTFOUND)
33351708Sstevel name = NULL;
33361708Sstevel else if (err != PICL_SUCCESS)
33371708Sstevel return (err);
33381708Sstevel
33391708Sstevel /* model */
33401708Sstevel err = picldiag_get_string_propval(ebush, PICL_PROP_BINDING_NAME,
33411708Sstevel &model);
33421708Sstevel if (err == PICL_PROPNOTFOUND)
33431708Sstevel model = NULL;
33441708Sstevel else if (err != PICL_SUCCESS)
33451708Sstevel return (err);
33461708Sstevel
33471708Sstevel /* status */
33481708Sstevel err = picldiag_get_string_propval(ebush, OBP_PROP_STATUS, &status);
33491708Sstevel if (err == PICL_PROPNOTFOUND)
33501708Sstevel status = NULL;
33511708Sstevel else if (err != PICL_SUCCESS)
33521708Sstevel return (err);
33531708Sstevel
33541708Sstevel /*
33551708Sstevel * Display the data
33561708Sstevel */
33571708Sstevel
33581708Sstevel /* name */
33591708Sstevel if (name != NULL) {
33601708Sstevel log_printf("%-22s ", name);
33611708Sstevel free(name);
33621708Sstevel } else
33631708Sstevel log_printf("%-22s ", "unknown");
33641708Sstevel /* model */
33651708Sstevel if (model != NULL) {
33661708Sstevel log_printf("%-15s ", model);
33671708Sstevel free(model);
33681708Sstevel } else
33691708Sstevel log_printf("%-15s ", "unknown");
33701708Sstevel /* status */
33711708Sstevel if (status == NULL)
33721708Sstevel log_printf("%-15s ", "okay");
33731708Sstevel else {
33741708Sstevel log_printf("%-15s ", status);
33753873Skd93003 set_exit_code(status);
33761708Sstevel free(status);
33771708Sstevel }
33781708Sstevel /* revision */
33791708Sstevel log_printf(" %-4d\n", id);
33801708Sstevel
33811708Sstevel return (PICL_WALK_CONTINUE);
33821708Sstevel }
33831708Sstevel
33841708Sstevel /*
33851708Sstevel * display asic revision id
33861708Sstevel */
33871708Sstevel static int
display_hw_revisions(picl_nodehdl_t plafh)33881708Sstevel display_hw_revisions(picl_nodehdl_t plafh)
33891708Sstevel {
33901708Sstevel int err;
33911708Sstevel
33921708Sstevel /* Print the header */
33931708Sstevel logprintf_header(dgettext(TEXT_DOMAIN, "HW Revisions"),
33941708Sstevel DEFAULT_LINE_WIDTH);
33951708Sstevel
33961708Sstevel log_printf("ASIC Revisions:\n");
33971708Sstevel log_printf("-----------------------------");
33981708Sstevel log_printf("--------------------------------------\n");
33991708Sstevel log_printf("Path Device");
34001708Sstevel log_printf(" Status Revision\n");
34011708Sstevel log_printf("-----------------------------");
34021708Sstevel log_printf("--------------------------------------\n");
34031708Sstevel
34041708Sstevel err = picl_walk_tree_by_class(plafh, NULL, NULL, asicrev_callback);
34051708Sstevel if (err != PICL_SUCCESS)
34061708Sstevel return (err);
34071708Sstevel
34081708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_EBUS,
34091708Sstevel NULL, ebus_callback);
34101708Sstevel if (err != PICL_SUCCESS)
34111708Sstevel return (err);
34121708Sstevel
34131708Sstevel log_printf("\n");
34141708Sstevel
34151708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_DISPLAY,
34161708Sstevel NULL, ffbconfig_callback);
34171708Sstevel return (err);
34181708Sstevel }
34191708Sstevel
34201708Sstevel /*
34211708Sstevel * find the options node and its powerfail_time prop
34221708Sstevel * If found, display the list of latest powerfail.
34231708Sstevel */
34241708Sstevel /* ARGSUSED */
34251708Sstevel static int
options_callback(picl_nodehdl_t nodeh,void * arg)34261708Sstevel options_callback(picl_nodehdl_t nodeh, void *arg)
34271708Sstevel {
34281708Sstevel time_t value;
34291708Sstevel char *failtime;
34301708Sstevel int err;
34311708Sstevel
34321708Sstevel err = picldiag_get_string_propval(nodeh, PROP_POWERFAIL_TIME,
34331708Sstevel &failtime);
34341708Sstevel if (err == PICL_PROPNOTFOUND)
34351708Sstevel return (PICL_WALK_TERMINATE);
34361708Sstevel else if (err != PICL_SUCCESS)
34371708Sstevel return (err);
34381708Sstevel
34391708Sstevel value = (time_t)atoi(failtime);
34401708Sstevel free(failtime);
34411708Sstevel if (value == 0)
34421708Sstevel return (PICL_WALK_TERMINATE);
34431708Sstevel
34441708Sstevel log_printf(dgettext(TEXT_DOMAIN, "Most recent AC Power Failure:\n"));
34451708Sstevel log_printf("=============================\n");
34461708Sstevel log_printf("%s", ctime(&value));
34471708Sstevel log_printf("\n");
34481708Sstevel return (PICL_WALK_TERMINATE);
34491708Sstevel }
34501708Sstevel
34511708Sstevel /*
34521708Sstevel * display the OBP and POST prom revisions
34531708Sstevel */
34541708Sstevel /* ARGSUSED */
34551708Sstevel static int
flashprom_callback(picl_nodehdl_t flashpromh,void * arg)34561708Sstevel flashprom_callback(picl_nodehdl_t flashpromh, void *arg)
34571708Sstevel {
34581708Sstevel picl_prophdl_t proph;
34591708Sstevel picl_prophdl_t tblh;
34601708Sstevel picl_prophdl_t rowproph;
34611708Sstevel picl_propinfo_t pinfo;
34621708Sstevel char *prom_version = NULL;
34631708Sstevel char *obp_version = NULL;
34641708Sstevel int err;
34651708Sstevel
34661708Sstevel err = picl_get_propinfo_by_name(flashpromh, OBP_PROP_VERSION,
34671708Sstevel &pinfo, &proph);
34681708Sstevel if (err == PICL_PROPNOTFOUND)
34691708Sstevel return (PICL_WALK_TERMINATE);
34701708Sstevel else if (err != PICL_SUCCESS)
34711708Sstevel return (err);
34721708Sstevel
34731708Sstevel log_printf(dgettext(TEXT_DOMAIN, "System PROM revisions:\n"));
34741708Sstevel log_printf("----------------------\n");
34751708Sstevel
34761708Sstevel /*
34771708Sstevel * If it's a table prop, the first element is OBP revision
34781708Sstevel * The second one is POST revision.
34791708Sstevel * If it's a charstring prop, the value will be only OBP revision
34801708Sstevel */
34811708Sstevel if (pinfo.type == PICL_PTYPE_CHARSTRING) {
34821708Sstevel prom_version = alloca(pinfo.size);
34831708Sstevel if (prom_version == NULL)
34841708Sstevel return (PICL_FAILURE);
34851708Sstevel err = picl_get_propval(proph, prom_version, pinfo.size);
34861708Sstevel if (err != PICL_SUCCESS)
34871708Sstevel return (err);
34881708Sstevel log_printf("%s\n", prom_version);
34891708Sstevel }
34901708Sstevel
34911708Sstevel if (pinfo.type != PICL_PTYPE_TABLE) /* not supported type */
34921708Sstevel return (PICL_WALK_TERMINATE);
34931708Sstevel
34941708Sstevel err = picl_get_propval(proph, &tblh, pinfo.size);
34951708Sstevel if (err != PICL_SUCCESS)
34961708Sstevel return (err);
34971708Sstevel
34981708Sstevel err = picl_get_next_by_row(tblh, &rowproph);
34991708Sstevel if (err == PICL_SUCCESS) {
35001708Sstevel /* get first row */
35011708Sstevel err = picl_get_propinfo(rowproph, &pinfo);
35021708Sstevel if (err != PICL_SUCCESS)
3503*13019SMichael.Bergknoff@Oracle.COM return (err);
35041708Sstevel
35051708Sstevel prom_version = alloca(pinfo.size);
35061708Sstevel if (prom_version == NULL)
35071708Sstevel return (PICL_FAILURE);
35081708Sstevel
35091708Sstevel err = picl_get_propval(rowproph, prom_version, pinfo.size);
35101708Sstevel if (err != PICL_SUCCESS)
35111708Sstevel return (err);
35121708Sstevel log_printf("%s\n", prom_version);
35131708Sstevel
35141708Sstevel /* get second row */
35151708Sstevel err = picl_get_next_by_col(rowproph, &rowproph);
35161708Sstevel if (err == PICL_SUCCESS) {
35171708Sstevel err = picl_get_propinfo(rowproph, &pinfo);
35181708Sstevel if (err != PICL_SUCCESS)
35191708Sstevel return (err);
35201708Sstevel
35211708Sstevel obp_version = alloca(pinfo.size);
35221708Sstevel if (obp_version == NULL)
35231708Sstevel return (PICL_FAILURE);
35241708Sstevel err = picl_get_propval(rowproph, obp_version,
35251708Sstevel pinfo.size);
35261708Sstevel if (err != PICL_SUCCESS)
35271708Sstevel return (err);
35281708Sstevel log_printf("%s\n", obp_version);
35291708Sstevel }
35301708Sstevel }
35311708Sstevel
35321708Sstevel return (PICL_WALK_TERMINATE);
35331708Sstevel }
35341708Sstevel
35351708Sstevel static int
display_system_info(int serrlog,int log_flag,picl_nodehdl_t rooth)35361708Sstevel display_system_info(int serrlog, int log_flag, picl_nodehdl_t rooth)
35371708Sstevel {
35381708Sstevel int err;
35391708Sstevel picl_nodehdl_t plafh;
35401708Sstevel picl_nodehdl_t frutreeh;
35411708Sstevel
35421708Sstevel err = picldiag_get_node_by_name(rooth, PICL_NODE_PLATFORM, &plafh);
35431708Sstevel if (err != PICL_SUCCESS)
35441708Sstevel return (err);
35451708Sstevel
35461708Sstevel if (!log_flag) {
35471708Sstevel err = display_platform_banner(plafh);
35481708Sstevel if (err != PICL_SUCCESS)
35491708Sstevel return (err);
35501708Sstevel
35511708Sstevel err = display_system_clock(plafh);
35521708Sstevel if (err != PICL_SUCCESS)
35531708Sstevel return (err);
35541708Sstevel
35551708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY,
35561708Sstevel PICL_CLASS_MEMORY, memory_callback);
35571708Sstevel if (err != PICL_SUCCESS)
35581708Sstevel return (err);
35591708Sstevel
35601708Sstevel err = display_cpu_info(plafh);
35611708Sstevel if (err != PICL_SUCCESS)
35621708Sstevel return (err);
35631708Sstevel
35641708Sstevel err = display_io_device_info(plafh);
35651708Sstevel if (err != PICL_SUCCESS)
35661708Sstevel return (err);
35671708Sstevel
35681708Sstevel err = display_memory_config(plafh);
35691708Sstevel if (err != PICL_SUCCESS)
35701708Sstevel return (err);
35711708Sstevel
35721708Sstevel err = display_usb_devices(plafh);
35731708Sstevel if (err != PICL_SUCCESS)
35741708Sstevel return (err);
35751708Sstevel }
35761708Sstevel
35771708Sstevel if (serrlog) {
35781708Sstevel err = picl_walk_tree_by_class(rooth, PICL_CLASS_OPTIONS,
35791708Sstevel NULL, options_callback);
35801708Sstevel if (err != PICL_SUCCESS)
35811708Sstevel return (err);
35821708Sstevel
35831708Sstevel err = display_envctrl_status(plafh);
35841708Sstevel if (err != PICL_SUCCESS)
35851708Sstevel return (err);
35861708Sstevel
35871708Sstevel err = picldiag_get_node_by_name(rooth, PICL_NODE_FRUTREE,
35881708Sstevel &frutreeh);
35891708Sstevel if (err != PICL_SUCCESS)
35901708Sstevel return (err);
35911708Sstevel
35921708Sstevel err = display_fru_oper_status(frutreeh);
35931708Sstevel if (err != PICL_SUCCESS)
35941708Sstevel return (err);
35951708Sstevel
35961708Sstevel err = display_hw_revisions(plafh);
35971708Sstevel if (err != PICL_SUCCESS)
35981708Sstevel return (err);
35991708Sstevel
36001708Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_FLASHPROM,
36011708Sstevel NULL, flashprom_callback);
36021708Sstevel if (err != PICL_SUCCESS)
36031708Sstevel return (err);
36041708Sstevel }
36051708Sstevel
36061708Sstevel return (PICL_SUCCESS);
36071708Sstevel }
36081708Sstevel
36093873Skd93003 /*
36103873Skd93003 * do_prominfo is called from main in prtdiag. It returns PD_SYSTEM_FAILURE if
36113873Skd93003 * any system failure is detected, PD_INTERNAL_FAILURE for internal errors and
36123873Skd93003 * PD_SUCCESS otherwise. main uses the return value as the exit code.
36133873Skd93003 */
36141708Sstevel /* ARGSUSED */
36151708Sstevel int
do_prominfo(int serrlog,char * pgname,int log_flag,int prt_flag)36161708Sstevel do_prominfo(int serrlog, char *pgname, int log_flag, int prt_flag)
36171708Sstevel {
36181708Sstevel int err;
36191708Sstevel char *errstr;
36201708Sstevel int done;
36211708Sstevel picl_nodehdl_t rooth;
36221708Sstevel
36231708Sstevel err = picl_initialize();
36241708Sstevel if (err != PICL_SUCCESS) {
36251708Sstevel fprintf(stderr, EM_INIT_FAIL, picl_strerror(err));
36263873Skd93003 return (PD_INTERNAL_FAILURE);
36271708Sstevel }
36281708Sstevel
36291708Sstevel do {
36301708Sstevel done = 1;
36311708Sstevel err = picl_get_root(&rooth);
36321708Sstevel if (err != PICL_SUCCESS) {
36331708Sstevel fprintf(stderr, EM_GET_ROOT_FAIL, picl_strerror(err));
36343873Skd93003 return (PD_INTERNAL_FAILURE);
36351708Sstevel }
36361708Sstevel
36371708Sstevel err = display_system_info(serrlog, log_flag, rooth);
36381708Sstevel
36391708Sstevel if ((err == PICL_STALEHANDLE) || (err == PICL_INVALIDHANDLE))
36401708Sstevel done = 0;
36411708Sstevel } while (!done);
36421708Sstevel
36431708Sstevel if (err != PICL_SUCCESS) {
36441708Sstevel errstr = picl_strerror(err);
36451708Sstevel fprintf(stderr, EM_PRTDIAG_FAIL);
36461708Sstevel fprintf(stderr, "%s\n", errstr? errstr : " ");
36473873Skd93003 exit_code = PD_INTERNAL_FAILURE;
36481708Sstevel }
36491708Sstevel
36501708Sstevel (void) picl_shutdown();
36511708Sstevel
36523873Skd93003 return (exit_code);
36531708Sstevel }
3654