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