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