103831d35Sstevel /*
203831d35Sstevel * CDDL HEADER START
303831d35Sstevel *
403831d35Sstevel * The contents of this file are subject to the terms of the
5*2983dda7SMichael Bergknoff * Common Development and Distribution License (the "License").
6*2983dda7SMichael Bergknoff * You may not use this file except in compliance with the License.
703831d35Sstevel *
803831d35Sstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
903831d35Sstevel * or http://www.opensolaris.org/os/licensing.
1003831d35Sstevel * See the License for the specific language governing permissions
1103831d35Sstevel * and limitations under the License.
1203831d35Sstevel *
1303831d35Sstevel * When distributing Covered Code, include this CDDL HEADER in each
1403831d35Sstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1503831d35Sstevel * If applicable, add the following below this CDDL HEADER, with the
1603831d35Sstevel * fields enclosed by brackets "[]" replaced with your own identifying
1703831d35Sstevel * information: Portions Copyright [yyyy] [name of copyright owner]
1803831d35Sstevel *
1903831d35Sstevel * CDDL HEADER END
2003831d35Sstevel */
2103831d35Sstevel /*
22*2983dda7SMichael Bergknoff * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2303831d35Sstevel */
2403831d35Sstevel
2503831d35Sstevel #include <stdio.h>
2603831d35Sstevel #include <stdlib.h>
2703831d35Sstevel #include <string.h>
2803831d35Sstevel #include <alloca.h>
2903831d35Sstevel #include <errno.h>
3003831d35Sstevel #include <libintl.h>
3103831d35Sstevel #include <sys/utsname.h>
3203831d35Sstevel #include <sys/types.h>
3303831d35Sstevel #include <sys/stat.h>
3403831d35Sstevel #include <sys/openpromio.h>
3503831d35Sstevel #include <sys/ddi.h>
3603831d35Sstevel #include <syslog.h>
3703831d35Sstevel #include <fcntl.h>
3803831d35Sstevel #include <dirent.h>
3903831d35Sstevel #include <unistd.h>
4003831d35Sstevel #include <locale.h>
4103831d35Sstevel #include <picl.h>
4203831d35Sstevel #include "pdevinfo.h"
4303831d35Sstevel #include "display.h"
4403831d35Sstevel #include "display_sun4u.h"
4503831d35Sstevel #include "picldefs.h"
4603831d35Sstevel #include "libprtdiag.h"
4703831d35Sstevel
4803831d35Sstevel #if !defined(TEXT_DOMAIN)
4903831d35Sstevel #define TEXT_DOMAIN "SYS_TEST"
5003831d35Sstevel #endif
5103831d35Sstevel
5203831d35Sstevel #define EM_INIT_FAIL dgettext(TEXT_DOMAIN,\
5303831d35Sstevel "picl_initialize failed: %s\n")
5403831d35Sstevel #define EM_GET_ROOT_FAIL dgettext(TEXT_DOMAIN,\
5503831d35Sstevel "Getting root node failed: %s\n")
5603831d35Sstevel #define EM_PRTDIAG_FAIL dgettext(TEXT_DOMAIN, "Prtdiag failed!\n")
5703831d35Sstevel
5803831d35Sstevel #define SIGN_ON_MSG dgettext(TEXT_DOMAIN,\
59*2983dda7SMichael Bergknoff "System Configuration: Oracle Corporation ")
6003831d35Sstevel #define SYSCLK_FREQ_MSG dgettext(TEXT_DOMAIN,\
6103831d35Sstevel "System clock frequency: %d MHZ\n")
6203831d35Sstevel #define MEM_SIZE_MSG dgettext(TEXT_DOMAIN, "Memory size: ")
6303831d35Sstevel
6403831d35Sstevel #define DEFAULT_BOARD_NUM 0
6503831d35Sstevel #define DEFAULT_PORTID 0
6603831d35Sstevel #define CLK_FREQ_66MHZ 66
6703831d35Sstevel #define USB -1
6803831d35Sstevel #define HUB -2
6903831d35Sstevel
7003831d35Sstevel /* bus id */
7103831d35Sstevel #define PCI_TYPE 1
7203831d35Sstevel
7303831d35Sstevel /*
7403831d35Sstevel * PICL classes
7503831d35Sstevel */
7603831d35Sstevel #define PICL_CLASS_OPTIONS "options"
7703831d35Sstevel
7803831d35Sstevel /*
7903831d35Sstevel * Property names
8003831d35Sstevel */
8103831d35Sstevel
8203831d35Sstevel #define OBP_PROP_REG "reg"
8303831d35Sstevel #define OBP_PROP_CLOCK_FREQ "clock-frequency"
8403831d35Sstevel #define OBP_PROP_BOARD_NUM "board#"
8503831d35Sstevel #define OBP_PROP_REVISION_ID "revision-id"
8603831d35Sstevel #define OBP_PROP_VERSION_NUM "version#"
8703831d35Sstevel #define OBP_PROP_BOARD_TYPE "board_type"
8803831d35Sstevel #define OBP_PROP_ECACHE_SIZE "ecache-size"
8903831d35Sstevel #define OBP_PROP_IMPLEMENTATION "implementation#"
9003831d35Sstevel #define OBP_PROP_MASK "mask#"
9103831d35Sstevel #define OBP_PROP_COMPATIBLE "compatible"
9203831d35Sstevel #define OBP_PROP_BANNER_NAME "banner-name"
9303831d35Sstevel #define OBP_PROP_MODEL "model"
9403831d35Sstevel #define OBP_PROP_66MHZ_CAPABLE "66mhz-capable"
9503831d35Sstevel #define OBP_PROP_FBC_REG_ID "fbc_reg_id"
9603831d35Sstevel #define OBP_PROP_VERSION "version"
9703831d35Sstevel
9803831d35Sstevel #define PROP_POWERFAIL_TIME "powerfail-time"
9903831d35Sstevel #define PICL_PROP_LOW_WARNING_THRESHOLD "LowWarningThreshold"
10003831d35Sstevel
10103831d35Sstevel #define DEFAULT_LINE_WIDTH 78
10203831d35Sstevel #define HEADING_SYMBOL "="
10303831d35Sstevel
10403831d35Sstevel #define SIZE_FIELD 11
10503831d35Sstevel #define MAX_IWAYS 32
10603831d35Sstevel
10703831d35Sstevel typedef struct bank_list {
10803831d35Sstevel picl_nodehdl_t nodeh;
10903831d35Sstevel uint32_t iway_count;
11003831d35Sstevel uint32_t iway[MAX_IWAYS];
11103831d35Sstevel struct bank_list *next;
11203831d35Sstevel } bank_list_t;
11303831d35Sstevel
11403831d35Sstevel typedef struct {
11503831d35Sstevel uint64_t base;
11603831d35Sstevel uint64_t size;
11703831d35Sstevel int ifactor;
11803831d35Sstevel int bank_count;
11903831d35Sstevel } seg_info_t;
12003831d35Sstevel
12103831d35Sstevel static struct io_card *io_card_list = NULL; /* The head of the IO card list */
12203831d35Sstevel static bank_list_t *mem_banks = NULL;
12303831d35Sstevel static int mem_xfersize;
12403831d35Sstevel static int no_xfer_size = 0;
12503831d35Sstevel
12603831d35Sstevel static const char *io_device_table[] = {
12703831d35Sstevel "block",
12803831d35Sstevel "disk",
12903831d35Sstevel "cdrom",
13003831d35Sstevel "floppy",
13103831d35Sstevel "tape",
13203831d35Sstevel "network",
13303831d35Sstevel "display",
13403831d35Sstevel "serial",
13503831d35Sstevel "parallel",
13603831d35Sstevel "scsi",
13703831d35Sstevel "scsi-2",
13803831d35Sstevel "scsi-3",
13903831d35Sstevel "ide",
14003831d35Sstevel "fcal",
14103831d35Sstevel "keyboard",
14203831d35Sstevel "mouse",
14303831d35Sstevel "dma"
14403831d35Sstevel };
14503831d35Sstevel
14603831d35Sstevel #define NIODEVICE (sizeof (io_device_table) / sizeof (io_device_table[0]))
14703831d35Sstevel
14803831d35Sstevel static const char *bus_table[] = {
14903831d35Sstevel "ebus",
15003831d35Sstevel "isa",
15103831d35Sstevel "pmu"
15203831d35Sstevel };
15303831d35Sstevel
15403831d35Sstevel #define NBUS (sizeof (bus_table) / sizeof (bus_table[0]))
15503831d35Sstevel
15603831d35Sstevel /*
15703831d35Sstevel * check if it is an IO deice
15803831d35Sstevel * return 1 if this is a io device; return 0 for else.
15903831d35Sstevel */
16003831d35Sstevel static int
is_io_device(char * device_class)16103831d35Sstevel is_io_device(char *device_class)
16203831d35Sstevel {
16303831d35Sstevel int i;
16403831d35Sstevel
16503831d35Sstevel for (i = 0; i < NIODEVICE; i++) {
166*2983dda7SMichael Bergknoff if (strcmp(device_class, io_device_table[i]) == 0)
167*2983dda7SMichael Bergknoff return (1);
16803831d35Sstevel }
16903831d35Sstevel
17003831d35Sstevel return (0);
17103831d35Sstevel }
17203831d35Sstevel
17303831d35Sstevel /*
17403831d35Sstevel * check if it is a bus
17503831d35Sstevel * return 1 if this is a bus; return 0 for else.
17603831d35Sstevel */
17703831d35Sstevel static int
is_bus(char * device_class)17803831d35Sstevel is_bus(char *device_class)
17903831d35Sstevel {
18003831d35Sstevel int i;
18103831d35Sstevel
18203831d35Sstevel for (i = 0; i < NBUS; i++) {
183*2983dda7SMichael Bergknoff if (strcmp(device_class, bus_table[i]) == 0)
184*2983dda7SMichael Bergknoff return (1);
18503831d35Sstevel }
18603831d35Sstevel
18703831d35Sstevel return (0);
18803831d35Sstevel }
18903831d35Sstevel
19003831d35Sstevel /*
19103831d35Sstevel * search children to get the node by the nodename
19203831d35Sstevel * return node handler in picl_nodehdl_t *nodeh
19303831d35Sstevel */
19403831d35Sstevel static int
picldiag_get_node_by_name(picl_nodehdl_t rooth,char * name,picl_nodehdl_t * nodeh)19503831d35Sstevel picldiag_get_node_by_name(picl_nodehdl_t rooth, char *name,
19603831d35Sstevel picl_nodehdl_t *nodeh)
19703831d35Sstevel {
19803831d35Sstevel picl_nodehdl_t childh;
19903831d35Sstevel int err;
20003831d35Sstevel char *nodename;
20103831d35Sstevel
20203831d35Sstevel nodename = alloca(strlen(name) + 1);
20303831d35Sstevel if (nodename == NULL)
20403831d35Sstevel return (PICL_FAILURE);
20503831d35Sstevel
20603831d35Sstevel err = picl_get_propval_by_name(rooth, PICL_PROP_CHILD, &childh,
20703831d35Sstevel sizeof (picl_nodehdl_t));
20803831d35Sstevel
20903831d35Sstevel while (err == PICL_SUCCESS) {
21003831d35Sstevel err = picl_get_propval_by_name(childh, PICL_PROP_NAME,
21103831d35Sstevel nodename, (strlen(name) + 1));
21203831d35Sstevel if (err != PICL_SUCCESS) {
21303831d35Sstevel err = picl_get_propval_by_name(childh, PICL_PROP_PEER,
214*2983dda7SMichael Bergknoff &childh, sizeof (picl_nodehdl_t));
21503831d35Sstevel continue;
21603831d35Sstevel }
21703831d35Sstevel
21803831d35Sstevel if (strcmp(nodename, name) == 0) {
21903831d35Sstevel *nodeh = childh;
22003831d35Sstevel return (PICL_SUCCESS);
22103831d35Sstevel }
22203831d35Sstevel
22303831d35Sstevel err = picl_get_propval_by_name(childh, PICL_PROP_PEER,
22403831d35Sstevel &childh, sizeof (picl_nodehdl_t));
22503831d35Sstevel }
22603831d35Sstevel
22703831d35Sstevel return (err);
22803831d35Sstevel }
22903831d35Sstevel
23003831d35Sstevel /*
23103831d35Sstevel * get the value by the property name of the string prop
23203831d35Sstevel * the value will be in outbuf
23303831d35Sstevel * Caller must free the outbuf
23403831d35Sstevel */
23503831d35Sstevel static int
picldiag_get_string_propval(picl_nodehdl_t modh,char * prop_name,char ** outbuf)23603831d35Sstevel picldiag_get_string_propval(picl_nodehdl_t modh, char *prop_name, char **outbuf)
23703831d35Sstevel {
23803831d35Sstevel int err;
23903831d35Sstevel picl_prophdl_t proph;
24003831d35Sstevel picl_propinfo_t pinfo;
24103831d35Sstevel char *prop_value;
24203831d35Sstevel
24303831d35Sstevel err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
24403831d35Sstevel if (err != PICL_SUCCESS)
24503831d35Sstevel return (err);
24603831d35Sstevel
24703831d35Sstevel /*
24803831d35Sstevel * If it is not a string prop, return NULL
24903831d35Sstevel */
25003831d35Sstevel if (pinfo.type != PICL_PTYPE_CHARSTRING)
251*2983dda7SMichael Bergknoff return (PICL_FAILURE);
25203831d35Sstevel
25303831d35Sstevel prop_value = malloc(pinfo.size);
25403831d35Sstevel if (prop_value == NULL)
25503831d35Sstevel return (PICL_FAILURE);
25603831d35Sstevel
25703831d35Sstevel err = picl_get_propval(proph, prop_value, pinfo.size);
25803831d35Sstevel if (err != PICL_SUCCESS) {
25903831d35Sstevel free(prop_value);
26003831d35Sstevel return (err);
26103831d35Sstevel }
26203831d35Sstevel
26303831d35Sstevel *outbuf = prop_value;
26403831d35Sstevel return (PICL_SUCCESS);
26503831d35Sstevel }
26603831d35Sstevel
26703831d35Sstevel
26803831d35Sstevel /*
26903831d35Sstevel * return the value as a signed integer
27003831d35Sstevel */
27103831d35Sstevel
27203831d35Sstevel static int64_t
picldiag_get_int_propval(picl_nodehdl_t modh,char * prop_name,int * ret)27303831d35Sstevel picldiag_get_int_propval(picl_nodehdl_t modh, char *prop_name, int *ret)
27403831d35Sstevel {
27503831d35Sstevel int err;
27603831d35Sstevel picl_prophdl_t proph;
27703831d35Sstevel picl_propinfo_t pinfo;
27803831d35Sstevel int8_t int8v;
27903831d35Sstevel int16_t int16v;
28003831d35Sstevel int32_t int32v;
28103831d35Sstevel int64_t int64v;
28203831d35Sstevel
28303831d35Sstevel err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
28403831d35Sstevel if (err != PICL_SUCCESS) {
28503831d35Sstevel *ret = err;
28603831d35Sstevel return (0);
28703831d35Sstevel }
28803831d35Sstevel
28903831d35Sstevel /*
29003831d35Sstevel * If it is not an int, uint or byte array prop, return failure
29103831d35Sstevel */
29203831d35Sstevel if ((pinfo.type != PICL_PTYPE_INT) &&
293*2983dda7SMichael Bergknoff (pinfo.type != PICL_PTYPE_UNSIGNED_INT) &&
294*2983dda7SMichael Bergknoff (pinfo.type != PICL_PTYPE_BYTEARRAY)) {
29503831d35Sstevel *ret = PICL_FAILURE;
29603831d35Sstevel return (0);
29703831d35Sstevel }
29803831d35Sstevel
29903831d35Sstevel switch (pinfo.size) {
30003831d35Sstevel case sizeof (int8_t):
30103831d35Sstevel err = picl_get_propval(proph, &int8v, sizeof (int8v));
30203831d35Sstevel *ret = err;
30303831d35Sstevel return (int8v);
30403831d35Sstevel case sizeof (int16_t):
30503831d35Sstevel err = picl_get_propval(proph, &int16v, sizeof (int16v));
30603831d35Sstevel *ret = err;
30703831d35Sstevel return (int16v);
30803831d35Sstevel case sizeof (int32_t):
30903831d35Sstevel err = picl_get_propval(proph, &int32v, sizeof (int32v));
31003831d35Sstevel *ret = err;
31103831d35Sstevel return (int32v);
31203831d35Sstevel case sizeof (int64_t):
31303831d35Sstevel err = picl_get_propval(proph, &int64v, sizeof (int64v));
31403831d35Sstevel *ret = err;
31503831d35Sstevel return (int64v);
31603831d35Sstevel default: /* not supported size */
31703831d35Sstevel *ret = PICL_FAILURE;
31803831d35Sstevel return (0);
31903831d35Sstevel }
32003831d35Sstevel }
32103831d35Sstevel
32203831d35Sstevel /*
32303831d35Sstevel * return the value of the uint prop
32403831d35Sstevel */
32503831d35Sstevel static uint64_t
picldiag_get_uint_propval(picl_nodehdl_t modh,char * prop_name,int * ret)32603831d35Sstevel picldiag_get_uint_propval(picl_nodehdl_t modh, char *prop_name, int *ret)
32703831d35Sstevel {
32803831d35Sstevel int err;
32903831d35Sstevel picl_prophdl_t proph;
33003831d35Sstevel picl_propinfo_t pinfo;
33103831d35Sstevel uint8_t uint8v;
33203831d35Sstevel uint16_t uint16v;
33303831d35Sstevel uint32_t uint32v;
33403831d35Sstevel uint64_t uint64v;
33503831d35Sstevel
33603831d35Sstevel err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
33703831d35Sstevel if (err != PICL_SUCCESS) {
33803831d35Sstevel *ret = err;
33903831d35Sstevel return (0);
34003831d35Sstevel }
34103831d35Sstevel
34203831d35Sstevel /*
34303831d35Sstevel * If it is not an int or uint prop, return failure
34403831d35Sstevel */
34503831d35Sstevel if ((pinfo.type != PICL_PTYPE_INT) &&
346*2983dda7SMichael Bergknoff (pinfo.type != PICL_PTYPE_UNSIGNED_INT)) {
34703831d35Sstevel *ret = PICL_FAILURE;
34803831d35Sstevel return (0);
34903831d35Sstevel }
35003831d35Sstevel
35103831d35Sstevel /* uint prop */
35203831d35Sstevel
35303831d35Sstevel switch (pinfo.size) {
35403831d35Sstevel case sizeof (uint8_t):
35503831d35Sstevel err = picl_get_propval(proph, &uint8v, sizeof (uint8v));
35603831d35Sstevel *ret = err;
35703831d35Sstevel return (uint8v);
35803831d35Sstevel case sizeof (uint16_t):
35903831d35Sstevel err = picl_get_propval(proph, &uint16v, sizeof (uint16v));
36003831d35Sstevel *ret = err;
36103831d35Sstevel return (uint16v);
36203831d35Sstevel case sizeof (uint32_t):
36303831d35Sstevel err = picl_get_propval(proph, &uint32v, sizeof (uint32v));
36403831d35Sstevel *ret = err;
36503831d35Sstevel return (uint32v);
36603831d35Sstevel case sizeof (uint64_t):
36703831d35Sstevel err = picl_get_propval(proph, &uint64v, sizeof (uint64v));
36803831d35Sstevel *ret = err;
36903831d35Sstevel return (uint64v);
37003831d35Sstevel default: /* not supported size */
37103831d35Sstevel *ret = PICL_FAILURE;
37203831d35Sstevel return (0);
37303831d35Sstevel }
37403831d35Sstevel }
37503831d35Sstevel
37603831d35Sstevel /*
37703831d35Sstevel * return the value of the float prop
37803831d35Sstevel */
37903831d35Sstevel static float
picldiag_get_float_propval(picl_nodehdl_t modh,char * prop_name,int * ret)38003831d35Sstevel picldiag_get_float_propval(picl_nodehdl_t modh, char *prop_name, int *ret)
38103831d35Sstevel {
38203831d35Sstevel int err;
38303831d35Sstevel picl_prophdl_t proph;
38403831d35Sstevel picl_propinfo_t pinfo;
38503831d35Sstevel float floatv;
38603831d35Sstevel
38703831d35Sstevel err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
38803831d35Sstevel if (err != PICL_SUCCESS) {
38903831d35Sstevel *ret = err;
39003831d35Sstevel return ((float)0);
39103831d35Sstevel }
39203831d35Sstevel
39303831d35Sstevel /*
39403831d35Sstevel * If it is not a float prop, return failure
39503831d35Sstevel */
39603831d35Sstevel if (pinfo.type != PICL_PTYPE_FLOAT) {
39703831d35Sstevel *ret = PICL_FAILURE;
39803831d35Sstevel return ((float)0);
39903831d35Sstevel }
40003831d35Sstevel
40103831d35Sstevel *ret = picl_get_propval(proph, &floatv, sizeof (floatv));
40203831d35Sstevel return (floatv);
40303831d35Sstevel }
40403831d35Sstevel
40503831d35Sstevel /*
40603831d35Sstevel * get the clock frequency
40703831d35Sstevel */
40803831d35Sstevel static int
picldiag_get_clock_freq(picl_nodehdl_t modh,uint32_t * freq)40903831d35Sstevel picldiag_get_clock_freq(picl_nodehdl_t modh, uint32_t *freq)
41003831d35Sstevel {
41103831d35Sstevel #define ROUND_TO_MHZ(x) (((x) + 500000)/ 1000000)
41203831d35Sstevel int err;
41303831d35Sstevel uint64_t clk_freq;
41403831d35Sstevel
41503831d35Sstevel clk_freq = picldiag_get_uint_propval(modh, OBP_PROP_CLOCK_FREQ, &err);
41603831d35Sstevel if (err != PICL_SUCCESS)
41703831d35Sstevel return (err);
41803831d35Sstevel
41903831d35Sstevel *freq = ROUND_TO_MHZ(clk_freq);
42003831d35Sstevel
42103831d35Sstevel return (PICL_SUCCESS);
42203831d35Sstevel }
42303831d35Sstevel
42403831d35Sstevel /*
42503831d35Sstevel * get the clock frequency from parent
42603831d35Sstevel */
42703831d35Sstevel static int
picldiag_get_clock_from_parent(picl_nodehdl_t nodeh,uint32_t * clk)42803831d35Sstevel picldiag_get_clock_from_parent(picl_nodehdl_t nodeh, uint32_t *clk)
42903831d35Sstevel {
43003831d35Sstevel picl_nodehdl_t parenth;
43103831d35Sstevel int err;
43203831d35Sstevel
43303831d35Sstevel
43403831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT,
43503831d35Sstevel &parenth, sizeof (parenth));
43603831d35Sstevel
43703831d35Sstevel while (err == PICL_SUCCESS) {
43803831d35Sstevel err = picldiag_get_clock_freq(parenth, clk);
43903831d35Sstevel if (err != PICL_PROPNOTFOUND)
44003831d35Sstevel return (err);
44103831d35Sstevel
44203831d35Sstevel err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT,
44303831d35Sstevel &parenth, sizeof (parenth));
44403831d35Sstevel }
44503831d35Sstevel
44603831d35Sstevel return (err);
44703831d35Sstevel }
44803831d35Sstevel
44903831d35Sstevel /*
45003831d35Sstevel * get _fru_parent prop
45103831d35Sstevel * If not found, then travese superiors (parent nodes) until
45203831d35Sstevel * a _fru_parent property is found.
45303831d35Sstevel * If not found, no fru parent
45403831d35Sstevel */
45503831d35Sstevel static int
picldiag_get_fru_parent(picl_nodehdl_t nodeh,picl_nodehdl_t * fruparenth)45603831d35Sstevel picldiag_get_fru_parent(picl_nodehdl_t nodeh, picl_nodehdl_t *fruparenth)
45703831d35Sstevel {
45803831d35Sstevel picl_nodehdl_t fruh;
45903831d35Sstevel int err;
46003831d35Sstevel
46103831d35Sstevel /* find fru parent */
46203831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_REFPROP_FRU_PARENT,
46303831d35Sstevel &fruh, sizeof (fruh));
46403831d35Sstevel
46503831d35Sstevel if (err != PICL_SUCCESS)
46603831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_REFPROP_LOC_PARENT,
46703831d35Sstevel &fruh, sizeof (fruh));
46803831d35Sstevel
46903831d35Sstevel while (err == PICL_PROPNOTFOUND) {
47003831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT,
47103831d35Sstevel &nodeh, sizeof (nodeh));
47203831d35Sstevel if (err != PICL_SUCCESS)
47303831d35Sstevel return (err);
47403831d35Sstevel
47503831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_REFPROP_FRU_PARENT,
47603831d35Sstevel &fruh, sizeof (fruh));
47703831d35Sstevel if (err != PICL_SUCCESS)
47803831d35Sstevel err = picl_get_propval_by_name(nodeh,
47903831d35Sstevel PICL_REFPROP_LOC_PARENT, &fruh, sizeof (fruh));
48003831d35Sstevel }
48103831d35Sstevel
48203831d35Sstevel if (err == PICL_SUCCESS)
48303831d35Sstevel *fruparenth = fruh;
48403831d35Sstevel
48503831d35Sstevel return (err);
48603831d35Sstevel }
48703831d35Sstevel
48803831d35Sstevel /*
48903831d35Sstevel * get label
49003831d35Sstevel *
49103831d35Sstevel * To get the label, use the following algorithm:
49203831d35Sstevel * Lookup "Label" property in the fru node itself. If no
49303831d35Sstevel * Label found, then traverse superiors (parent nodes) until
49403831d35Sstevel * a Label property is found.
49503831d35Sstevel * if not found, then no label
49603831d35Sstevel */
49703831d35Sstevel static int
picldiag_get_label(picl_nodehdl_t nodeh,char ** label)49803831d35Sstevel picldiag_get_label(picl_nodehdl_t nodeh, char **label)
49903831d35Sstevel {
50003831d35Sstevel int err;
50103831d35Sstevel
50203831d35Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL, label);
50303831d35Sstevel
50403831d35Sstevel while (err == PICL_PROPNOTFOUND) {
50503831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT,
50603831d35Sstevel &nodeh, sizeof (nodeh));
50703831d35Sstevel if (err != PICL_SUCCESS)
50803831d35Sstevel return (err);
50903831d35Sstevel
51003831d35Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL,
51103831d35Sstevel label);
51203831d35Sstevel }
51303831d35Sstevel
51403831d35Sstevel return (err);
51503831d35Sstevel }
51603831d35Sstevel
51703831d35Sstevel /*
51803831d35Sstevel * get combined label
51903831d35Sstevel *
52003831d35Sstevel * like picldiag_get_label, except concatenates the labels of parent locations
52103831d35Sstevel * eg SB0/P3 for processor P3 on system board SB0
52203831d35Sstevel *
52303831d35Sstevel * if caller specifies non-zero label length, label will be cut to specified
52403831d35Sstevel * length.
52503831d35Sstevel * negative length is left justified, non-negative length is right justified
52603831d35Sstevel */
52703831d35Sstevel static int
picldiag_get_combined_label(picl_nodehdl_t nodeh,char ** label,int lablen)52803831d35Sstevel picldiag_get_combined_label(picl_nodehdl_t nodeh, char **label, int lablen)
52903831d35Sstevel {
53003831d35Sstevel int err;
53103831d35Sstevel char *ptr;
53203831d35Sstevel char *ptr1 = NULL;
53303831d35Sstevel char *ptr2;
53403831d35Sstevel int len;
53503831d35Sstevel
53603831d35Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL, &ptr1);
53703831d35Sstevel if (err != PICL_PROPNOTFOUND && err != PICL_SUCCESS)
53803831d35Sstevel return (err);
53903831d35Sstevel
54003831d35Sstevel for (;;) {
54103831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT,
54203831d35Sstevel &nodeh, sizeof (nodeh));
54303831d35Sstevel if (err == PICL_PROPNOTFOUND)
54403831d35Sstevel break;
54503831d35Sstevel if (err != PICL_SUCCESS)
54603831d35Sstevel return (err);
54703831d35Sstevel
54803831d35Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL, &ptr);
54903831d35Sstevel if (err == PICL_SUCCESS) {
55003831d35Sstevel if (ptr1 == NULL) {
55103831d35Sstevel ptr1 = ptr;
55203831d35Sstevel } else {
55303831d35Sstevel ptr2 = malloc(strlen(ptr1) + strlen(ptr) + 2);
55403831d35Sstevel if (ptr2 == NULL)
55503831d35Sstevel return (PICL_FAILURE);
55603831d35Sstevel (void) strlcpy(ptr2, ptr, strlen(ptr)-1);
55703831d35Sstevel (void) strlcat(ptr2, "/", 1);
55803831d35Sstevel (void) strlcat(ptr2, ptr1, strlen(ptr1)-1);
55903831d35Sstevel (void) strlcat(ptr2, "\0", 1);
56003831d35Sstevel
56103831d35Sstevel (void) free(ptr);
56203831d35Sstevel (void) free(ptr1);
56303831d35Sstevel ptr1 = ptr2;
56403831d35Sstevel }
56503831d35Sstevel } else if (err != PICL_PROPNOTFOUND) {
56603831d35Sstevel return (err);
56703831d35Sstevel }
56803831d35Sstevel }
56903831d35Sstevel
57003831d35Sstevel if (ptr1 == NULL)
57103831d35Sstevel return (PICL_PROPNOTFOUND);
57203831d35Sstevel
57303831d35Sstevel len = strlen(ptr1);
57403831d35Sstevel /* if no string truncation is desired or required */
57503831d35Sstevel if ((lablen == 0) || (len <= abs(lablen))) {
57603831d35Sstevel *label = ptr1;
57703831d35Sstevel return (PICL_SUCCESS);
57803831d35Sstevel }
57903831d35Sstevel
58003831d35Sstevel /* string truncation is required; alloc space for (lablen + \0) */
58103831d35Sstevel ptr = malloc(abs(lablen) + 1);
58203831d35Sstevel if (ptr == 0)
58303831d35Sstevel return (PICL_FAILURE);
58403831d35Sstevel if (lablen > 0) {
58503831d35Sstevel /* right justification; label = "+<string>\0" */
58603831d35Sstevel strlcpy(ptr, "+", 1);
58703831d35Sstevel strlcat(ptr, ptr1 + len - lablen + 1, lablen + 1);
58803831d35Sstevel } else {
58903831d35Sstevel /* left justification; label = "<string>+\0" */
59003831d35Sstevel strlcpy(ptr, ptr1, abs(lablen) - 1);
59103831d35Sstevel strcat(ptr, "+");
59203831d35Sstevel }
59303831d35Sstevel
59403831d35Sstevel *label = ptr;
59503831d35Sstevel return (PICL_SUCCESS);
59603831d35Sstevel }
59703831d35Sstevel
59803831d35Sstevel /*
59903831d35Sstevel * return the first compatible value
60003831d35Sstevel */
60103831d35Sstevel static int
picldiag_get_first_compatible_value(picl_nodehdl_t nodeh,char ** outbuf)60203831d35Sstevel picldiag_get_first_compatible_value(picl_nodehdl_t nodeh, char **outbuf)
60303831d35Sstevel {
60403831d35Sstevel int err;
60503831d35Sstevel picl_prophdl_t proph;
60603831d35Sstevel picl_propinfo_t pinfo;
60703831d35Sstevel picl_prophdl_t tblh;
60803831d35Sstevel picl_prophdl_t rowproph;
60903831d35Sstevel char *pval;
61003831d35Sstevel
61103831d35Sstevel err = picl_get_propinfo_by_name(nodeh, OBP_PROP_COMPATIBLE,
61203831d35Sstevel &pinfo, &proph);
61303831d35Sstevel if (err != PICL_SUCCESS)
614*2983dda7SMichael Bergknoff return (err);
61503831d35Sstevel
61603831d35Sstevel if (pinfo.type == PICL_PTYPE_CHARSTRING) {
61703831d35Sstevel pval = malloc(pinfo.size);
61803831d35Sstevel if (pval == NULL)
61903831d35Sstevel return (PICL_FAILURE);
62003831d35Sstevel err = picl_get_propval(proph, pval, pinfo.size);
62103831d35Sstevel if (err != PICL_SUCCESS) {
62203831d35Sstevel free(pval);
62303831d35Sstevel return (err);
62403831d35Sstevel }
62503831d35Sstevel *outbuf = pval;
62603831d35Sstevel return (PICL_SUCCESS);
62703831d35Sstevel }
62803831d35Sstevel
62903831d35Sstevel if (pinfo.type != PICL_PTYPE_TABLE)
63003831d35Sstevel return (PICL_FAILURE);
63103831d35Sstevel
63203831d35Sstevel /* get first string from table */
63303831d35Sstevel err = picl_get_propval(proph, &tblh, pinfo.size);
63403831d35Sstevel if (err != PICL_SUCCESS)
63503831d35Sstevel return (err);
63603831d35Sstevel
63703831d35Sstevel err = picl_get_next_by_row(tblh, &rowproph);
63803831d35Sstevel if (err != PICL_SUCCESS)
63903831d35Sstevel return (err);
64003831d35Sstevel
64103831d35Sstevel err = picl_get_propinfo(rowproph, &pinfo);
64203831d35Sstevel if (err != PICL_SUCCESS)
643*2983dda7SMichael Bergknoff return (err);
64403831d35Sstevel
64503831d35Sstevel pval = malloc(pinfo.size);
64603831d35Sstevel if (pval == NULL)
64703831d35Sstevel return (PICL_FAILURE);
64803831d35Sstevel
64903831d35Sstevel err = picl_get_propval(rowproph, pval, pinfo.size);
65003831d35Sstevel if (err != PICL_SUCCESS) {
65103831d35Sstevel free(pval);
65203831d35Sstevel return (err);
65303831d35Sstevel }
65403831d35Sstevel
65503831d35Sstevel *outbuf = pval;
65603831d35Sstevel return (PICL_SUCCESS);
65703831d35Sstevel }
65803831d35Sstevel
65903831d35Sstevel /*
66003831d35Sstevel * print the header in the center
66103831d35Sstevel */
66203831d35Sstevel static void
logprintf_header(char * header,size_t line_width)66303831d35Sstevel logprintf_header(char *header, size_t line_width)
66403831d35Sstevel {
66503831d35Sstevel size_t start_pos;
66603831d35Sstevel size_t i;
66703831d35Sstevel
66803831d35Sstevel log_printf("\n");
66903831d35Sstevel start_pos = (line_width - strlen(header) - 2) / 2;
67003831d35Sstevel
67103831d35Sstevel for (i = 0; i < start_pos; i++)
67203831d35Sstevel log_printf("%s", HEADING_SYMBOL);
67303831d35Sstevel
67403831d35Sstevel log_printf(" %s ", header);
67503831d35Sstevel
67603831d35Sstevel for (i = 0; i < start_pos; i++)
67703831d35Sstevel log_printf("%s", HEADING_SYMBOL);
67803831d35Sstevel
67903831d35Sstevel log_printf("\n");
68003831d35Sstevel }
68103831d35Sstevel
68203831d35Sstevel /*
68303831d35Sstevel * print the size
68403831d35Sstevel */
68503831d35Sstevel static void
logprintf_size(uint64_t size)68603831d35Sstevel logprintf_size(uint64_t size)
68703831d35Sstevel {
68803831d35Sstevel
68903831d35Sstevel uint64_t kbyte = 1024;
69003831d35Sstevel uint64_t mbyte = 1024 * 1024;
69103831d35Sstevel uint64_t gbyte = 1024 * 1024 * 1024;
69203831d35Sstevel uint64_t residue;
69303831d35Sstevel char buf[SIZE_FIELD];
69403831d35Sstevel
69503831d35Sstevel if (size >= gbyte) {
69603831d35Sstevel residue = size % gbyte;
69703831d35Sstevel if (residue == 0)
69803831d35Sstevel snprintf(buf, sizeof (buf), "%dGB",
69903831d35Sstevel (int)(size / gbyte));
70003831d35Sstevel else
70103831d35Sstevel snprintf(buf, sizeof (buf), "%.2fGB",
70203831d35Sstevel (float)size / gbyte);
70303831d35Sstevel } else if (size >= mbyte) {
70403831d35Sstevel residue = size % mbyte;
70503831d35Sstevel if (residue == 0)
70603831d35Sstevel snprintf(buf, sizeof (buf), "%dMB",
70703831d35Sstevel (int)(size / mbyte));
70803831d35Sstevel else
70903831d35Sstevel snprintf(buf, sizeof (buf), "%.2fMB",
71003831d35Sstevel (float)size / mbyte);
71103831d35Sstevel } else {
71203831d35Sstevel residue = size % kbyte;
71303831d35Sstevel if (residue == 0)
71403831d35Sstevel snprintf(buf, sizeof (buf), "%dKB",
71503831d35Sstevel (int)(size / kbyte));
71603831d35Sstevel else
71703831d35Sstevel snprintf(buf, sizeof (buf), "%.2fKB",
71803831d35Sstevel (float)size / kbyte);
71903831d35Sstevel }
72003831d35Sstevel
72103831d35Sstevel log_printf("%-10s ", buf);
72203831d35Sstevel }
72303831d35Sstevel
72403831d35Sstevel /*
72503831d35Sstevel * display platform banner
72603831d35Sstevel */
72703831d35Sstevel static int
display_platform_banner(picl_nodehdl_t plafh)72803831d35Sstevel display_platform_banner(picl_nodehdl_t plafh)
72903831d35Sstevel {
73003831d35Sstevel char *platform;
73103831d35Sstevel char *banner_name;
73203831d35Sstevel int err;
73303831d35Sstevel
73403831d35Sstevel /*
73503831d35Sstevel * get PICL_PROP_MACHINE and PICL_PROP_BANNER_NAME
73603831d35Sstevel */
73703831d35Sstevel log_printf(SIGN_ON_MSG);
73803831d35Sstevel err = picldiag_get_string_propval(plafh, PICL_PROP_MACHINE,
73903831d35Sstevel &platform);
74003831d35Sstevel if (err != PICL_SUCCESS)
74103831d35Sstevel return (err);
74203831d35Sstevel log_printf(" %s", platform);
74303831d35Sstevel free(platform);
74403831d35Sstevel
74503831d35Sstevel err = picldiag_get_string_propval(plafh, OBP_PROP_BANNER_NAME,
74603831d35Sstevel &banner_name);
74703831d35Sstevel if (err != PICL_SUCCESS)
74803831d35Sstevel return (err);
74903831d35Sstevel log_printf(" %s", banner_name);
75003831d35Sstevel free(banner_name);
75103831d35Sstevel
75203831d35Sstevel log_printf("\n");
75303831d35Sstevel return (PICL_SUCCESS);
75403831d35Sstevel }
75503831d35Sstevel
75603831d35Sstevel /*
75703831d35Sstevel * display the clock frequency
75803831d35Sstevel */
75903831d35Sstevel static int
display_system_clock(picl_nodehdl_t plafh)76003831d35Sstevel display_system_clock(picl_nodehdl_t plafh)
76103831d35Sstevel {
76203831d35Sstevel uint32_t system_clk;
76303831d35Sstevel int err;
76403831d35Sstevel
76503831d35Sstevel err = picldiag_get_clock_freq(plafh, &system_clk);
76603831d35Sstevel if (err != PICL_SUCCESS)
76703831d35Sstevel return (err);
76803831d35Sstevel
76903831d35Sstevel log_printf(SYSCLK_FREQ_MSG, system_clk);
77003831d35Sstevel
77103831d35Sstevel return (PICL_SUCCESS);
77203831d35Sstevel }
77303831d35Sstevel
77403831d35Sstevel /*
77503831d35Sstevel * callback function to display the memory size
77603831d35Sstevel */
77703831d35Sstevel /*ARGSUSED*/
77803831d35Sstevel static int
memory_callback(picl_nodehdl_t memh,void * args)77903831d35Sstevel memory_callback(picl_nodehdl_t memh, void *args)
78003831d35Sstevel {
78103831d35Sstevel uint64_t mem_size;
78203831d35Sstevel int err;
78303831d35Sstevel
78403831d35Sstevel log_printf(MEM_SIZE_MSG);
78503831d35Sstevel mem_size = picldiag_get_uint_propval(memh, PICL_PROP_SIZE, &err);
78603831d35Sstevel if (err == PICL_SUCCESS)
78703831d35Sstevel logprintf_size(mem_size);
78803831d35Sstevel log_printf("\n");
78903831d35Sstevel no_xfer_size = 0;
79003831d35Sstevel mem_xfersize = picldiag_get_uint_propval(memh, PICL_PROP_TRANSFER_SIZE,
79103831d35Sstevel &err);
79203831d35Sstevel if (err == PICL_PROPNOTFOUND)
79303831d35Sstevel no_xfer_size = 1;
79403831d35Sstevel return (PICL_WALK_TERMINATE);
79503831d35Sstevel }
79603831d35Sstevel
79703831d35Sstevel /*
79803831d35Sstevel * callback function to print cpu information
79903831d35Sstevel */
80003831d35Sstevel /*ARGSUSED*/
80103831d35Sstevel static int
cpu_callback(picl_nodehdl_t nodeh,void * args)80203831d35Sstevel cpu_callback(picl_nodehdl_t nodeh, void *args)
80303831d35Sstevel {
80403831d35Sstevel int err;
80503831d35Sstevel int id;
80603831d35Sstevel uint64_t uintval;
80703831d35Sstevel uint32_t freq;
80803831d35Sstevel char *impl_name;
80903831d35Sstevel char *status;
81003831d35Sstevel picl_prophdl_t parenth;
81103831d35Sstevel char *label;
81203831d35Sstevel
81303831d35Sstevel /*
81403831d35Sstevel * If no ID is found, return
81503831d35Sstevel */
81603831d35Sstevel id = picldiag_get_uint_propval(nodeh, PICL_PROP_ID, &err);
81703831d35Sstevel if (err == PICL_PROPNOTFOUND)
81803831d35Sstevel return (PICL_WALK_CONTINUE);
81903831d35Sstevel else if (err != PICL_SUCCESS)
82003831d35Sstevel return (err);
82103831d35Sstevel log_printf(" %2d ", id);
82203831d35Sstevel
82303831d35Sstevel /*
82403831d35Sstevel * If no freq is found, return
82503831d35Sstevel */
82603831d35Sstevel err = picldiag_get_clock_freq(nodeh, &freq);
82703831d35Sstevel if (err == PICL_PROPNOTFOUND)
82803831d35Sstevel return (PICL_WALK_CONTINUE);
82903831d35Sstevel else if (err != PICL_SUCCESS)
83003831d35Sstevel return (err);
83103831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "%4d MHz "), freq);
83203831d35Sstevel
83303831d35Sstevel /* Ecache size */
83403831d35Sstevel uintval = picldiag_get_uint_propval(nodeh, OBP_PROP_ECACHE_SIZE, &err);
83503831d35Sstevel if (err == PICL_PROPNOTFOUND)
83603831d35Sstevel log_printf(" - ");
83703831d35Sstevel else if (err == PICL_SUCCESS)
83803831d35Sstevel logprintf_size(uintval);
83903831d35Sstevel else
84003831d35Sstevel return (err);
84103831d35Sstevel
84203831d35Sstevel /* Implementation */
84303831d35Sstevel impl_name = NULL;
84403831d35Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_NAME, &impl_name);
84503831d35Sstevel if (err != PICL_SUCCESS)
84603831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, " <unknown> "));
84703831d35Sstevel else
84803831d35Sstevel log_printf(" %-22s ", impl_name);
84903831d35Sstevel
85003831d35Sstevel /* CPU Mask */
85103831d35Sstevel uintval = picldiag_get_uint_propval(nodeh, OBP_PROP_MASK, &err);
85203831d35Sstevel if (err == PICL_PROPNOTFOUND)
85303831d35Sstevel log_printf(" - ");
85403831d35Sstevel else if (err == PICL_SUCCESS)
85503831d35Sstevel log_printf("%2lld.%-2lld ", (uintval >> 4) & 0xf,
85603831d35Sstevel uintval & 0xf);
85703831d35Sstevel else
85803831d35Sstevel return (err);
85903831d35Sstevel
86003831d35Sstevel /*
86103831d35Sstevel * Status - if the node has a status property then display that
86203831d35Sstevel * otherwise display the State property
86303831d35Sstevel */
86403831d35Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_STATUS, &status);
86503831d35Sstevel if (err == PICL_SUCCESS) {
86603831d35Sstevel log_printf("%-12s", status);
86703831d35Sstevel free(status);
86803831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err !=
86903831d35Sstevel PICL_PROPVALUNAVAILABLE && err != PICL_ENDOFLIST) {
87003831d35Sstevel return (err);
87103831d35Sstevel } else {
87203831d35Sstevel err = picldiag_get_string_propval(nodeh,
87303831d35Sstevel PICL_PROP_STATE, &status);
87403831d35Sstevel if (err == PICL_SUCCESS) {
87503831d35Sstevel log_printf("%-12s", status);
87603831d35Sstevel free(status);
87703831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err !=
87803831d35Sstevel PICL_PROPVALUNAVAILABLE && err !=
87903831d35Sstevel PICL_ENDOFLIST) {
88003831d35Sstevel return (err);
88103831d35Sstevel } else {
88203831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "unknown "));
88303831d35Sstevel }
88403831d35Sstevel }
88503831d35Sstevel
88603831d35Sstevel /*
88703831d35Sstevel * Location: use label of fru parent
88803831d35Sstevel */
88903831d35Sstevel err = picldiag_get_fru_parent(nodeh, &parenth);
89003831d35Sstevel if (err == PICL_PROPNOTFOUND) {
89103831d35Sstevel log_printf(" - ");
89203831d35Sstevel } else if (err == PICL_SUCCESS) {
89303831d35Sstevel err = picldiag_get_combined_label(parenth, &label, 12);
89403831d35Sstevel if (err == PICL_PROPNOTFOUND)
89503831d35Sstevel log_printf(" - ");
89603831d35Sstevel else if (err == PICL_SUCCESS) {
89703831d35Sstevel log_printf("%s", label);
89803831d35Sstevel free(label);
89903831d35Sstevel } else
90003831d35Sstevel return (err);
90103831d35Sstevel } else
90203831d35Sstevel return (err);
90303831d35Sstevel
90403831d35Sstevel log_printf("\n");
90503831d35Sstevel return (PICL_WALK_CONTINUE);
90603831d35Sstevel }
90703831d35Sstevel
90803831d35Sstevel /*
90903831d35Sstevel * display cpu information
91003831d35Sstevel */
91103831d35Sstevel static int
display_cpu_info(picl_nodehdl_t plafh)91203831d35Sstevel display_cpu_info(picl_nodehdl_t plafh)
91303831d35Sstevel {
91403831d35Sstevel int err;
91503831d35Sstevel
91603831d35Sstevel /*
91703831d35Sstevel * Display the table header for CPUs . Then display the CPU
91803831d35Sstevel * frequency, cache size, and processor revision on all the boards.
91903831d35Sstevel */
92003831d35Sstevel logprintf_header(dgettext(TEXT_DOMAIN, "CPUs"), DEFAULT_LINE_WIDTH);
92103831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, " E$ CPU"
922*2983dda7SMichael Bergknoff " CPU\n"));
92303831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
92403831d35Sstevel "CPU Freq Size Implementation"
925*2983dda7SMichael Bergknoff " Mask Status Location\n"));
92603831d35Sstevel log_printf("--- -------- ---------- --------------------- "
927*2983dda7SMichael Bergknoff "----- ------ --------\n");
92803831d35Sstevel
92903831d35Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_CPU, PICL_CLASS_CPU,
93003831d35Sstevel cpu_callback);
93103831d35Sstevel return (err);
93203831d35Sstevel }
93303831d35Sstevel
93403831d35Sstevel /*
93503831d35Sstevel * Inserts an io_card structure into the list.
93603831d35Sstevel */
93703831d35Sstevel 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)93803831d35Sstevel add_io_card(uint32_t board, uint32_t bus_id, uint32_t slot, char *label,
93903831d35Sstevel uint32_t freq, char *name, char *model, char *status, char *devfs_path)
94003831d35Sstevel {
94103831d35Sstevel struct io_card card;
94203831d35Sstevel
94303831d35Sstevel card.display = 1;
94403831d35Sstevel card.board = board;
94503831d35Sstevel switch (bus_id) {
94603831d35Sstevel case PCI_TYPE:
94703831d35Sstevel strlcpy(card.bus_type, PCI_NAME, MAXSTRLEN);
94803831d35Sstevel break;
94903831d35Sstevel default: /* won't reach here */
95003831d35Sstevel strlcpy(card.bus_type, "", MAXSTRLEN);
95103831d35Sstevel break;
95203831d35Sstevel }
95303831d35Sstevel if (label == NULL)
95403831d35Sstevel card.slot = slot;
95503831d35Sstevel else {
95603831d35Sstevel card.slot = PCI_SLOT_IS_STRING;
95703831d35Sstevel (void) strlcpy(card.slot_str, label, MAXSTRLEN);
95803831d35Sstevel }
95903831d35Sstevel card.freq = freq;
96003831d35Sstevel card.status[0] = '\0';
96103831d35Sstevel card.name[0] = '\0';
96203831d35Sstevel card.model[0] = '\0';
96303831d35Sstevel card.notes[0] = '\0';
96403831d35Sstevel if (status != NULL)
96503831d35Sstevel strlcpy(card.status, status, MAXSTRLEN);
96603831d35Sstevel if (name != NULL)
96703831d35Sstevel strlcpy(card.name, name, MAXSTRLEN);
96803831d35Sstevel if (model != NULL)
96903831d35Sstevel strlcpy(card.model, model, MAXSTRLEN);
97003831d35Sstevel if (status != NULL)
97103831d35Sstevel strlcpy(card.status, status, MAXSTRLEN);
97203831d35Sstevel if (devfs_path != NULL)
97303831d35Sstevel strlcpy(card.notes, devfs_path, MAXSTRLEN);
97403831d35Sstevel
97503831d35Sstevel io_card_list = insert_io_card(io_card_list, &card);
97603831d35Sstevel }
97703831d35Sstevel
97803831d35Sstevel static void
append_to_bank_list(bank_list_t * newptr)97903831d35Sstevel append_to_bank_list(bank_list_t *newptr)
98003831d35Sstevel {
98103831d35Sstevel bank_list_t *ptr;
98203831d35Sstevel
98303831d35Sstevel if (mem_banks == NULL) {
98403831d35Sstevel mem_banks = newptr;
98503831d35Sstevel return;
98603831d35Sstevel }
98703831d35Sstevel ptr = mem_banks;
98803831d35Sstevel while (ptr->next != NULL)
98903831d35Sstevel ptr = ptr->next;
99003831d35Sstevel
99103831d35Sstevel ptr->next = newptr;
99203831d35Sstevel }
99303831d35Sstevel
99403831d35Sstevel static void
free_bank_list(void)99503831d35Sstevel free_bank_list(void)
99603831d35Sstevel {
99703831d35Sstevel bank_list_t *ptr;
99803831d35Sstevel bank_list_t *tmp;
99903831d35Sstevel
100003831d35Sstevel for (ptr = mem_banks; ptr != NULL; ptr = tmp) {
100103831d35Sstevel tmp = ptr->next;
100203831d35Sstevel free(ptr);
100303831d35Sstevel }
100403831d35Sstevel mem_banks = NULL;
100503831d35Sstevel }
100603831d35Sstevel
100703831d35Sstevel
100803831d35Sstevel /*
100903831d35Sstevel * print label for memory module
101003831d35Sstevel */
101103831d35Sstevel static int
logprintf_memory_module_label(picl_nodehdl_t moduleh)101203831d35Sstevel logprintf_memory_module_label(picl_nodehdl_t moduleh)
101303831d35Sstevel {
101403831d35Sstevel picl_nodehdl_t fruparenth;
101503831d35Sstevel int err;
101603831d35Sstevel char *label;
101703831d35Sstevel
101803831d35Sstevel err = picldiag_get_fru_parent(moduleh, &fruparenth);
101903831d35Sstevel if (err == PICL_PROPNOTFOUND) {
102003831d35Sstevel log_printf("-");
102103831d35Sstevel return (PICL_SUCCESS);
102203831d35Sstevel } else if (err != PICL_SUCCESS)
102303831d35Sstevel return (err);
102403831d35Sstevel
102503831d35Sstevel err = picldiag_get_combined_label(fruparenth, &label, 30);
102603831d35Sstevel if (err == PICL_PROPNOTFOUND)
102703831d35Sstevel log_printf("-");
102803831d35Sstevel else if (err == PICL_SUCCESS) {
102903831d35Sstevel log_printf("%-15s", label);
103003831d35Sstevel free(label);
103103831d35Sstevel } else
103203831d35Sstevel return (err);
103303831d35Sstevel
103403831d35Sstevel return (PICL_SUCCESS);
103503831d35Sstevel }
103603831d35Sstevel
103703831d35Sstevel /*
103803831d35Sstevel * print the bank id and add the bank handle in the bank list
103903831d35Sstevel * return the head of the bank list
104003831d35Sstevel */
104103831d35Sstevel static int
membank_callback(picl_nodehdl_t bankh,void * args)104203831d35Sstevel membank_callback(picl_nodehdl_t bankh, void *args)
104303831d35Sstevel {
104403831d35Sstevel int err;
104503831d35Sstevel int64_t id;
104603831d35Sstevel uint64_t match;
104703831d35Sstevel uint64_t mask;
104803831d35Sstevel int i;
104903831d35Sstevel bank_list_t *newptr;
105003831d35Sstevel seg_info_t *segp = args;
105103831d35Sstevel
105203831d35Sstevel /*
105303831d35Sstevel * print the bank id in the segment table contains column
105403831d35Sstevel */
105503831d35Sstevel id = picldiag_get_uint_propval(bankh, PICL_PROP_ID, &err);
105603831d35Sstevel if (segp->bank_count > 0)
105703831d35Sstevel log_printf(",");
105803831d35Sstevel if (err == PICL_PROPNOTFOUND)
105903831d35Sstevel log_printf("-");
106003831d35Sstevel else if (err == PICL_SUCCESS)
106103831d35Sstevel log_printf("%-lld", id);
106203831d35Sstevel else
106303831d35Sstevel return (err);
106403831d35Sstevel segp->bank_count++;
106503831d35Sstevel
106603831d35Sstevel /*
106703831d35Sstevel * Save the bank information for later (print_bank_table)
106803831d35Sstevel */
106903831d35Sstevel newptr = malloc(sizeof (*newptr));
107003831d35Sstevel if (newptr == NULL)
107103831d35Sstevel return (PICL_FAILURE);
107203831d35Sstevel
107303831d35Sstevel newptr->nodeh = bankh;
107403831d35Sstevel newptr->iway_count = 0;
107503831d35Sstevel newptr->next = NULL;
107603831d35Sstevel append_to_bank_list(newptr);
107703831d35Sstevel
107803831d35Sstevel /*
107903831d35Sstevel * Compute the way numbers for the bank
108003831d35Sstevel */
108103831d35Sstevel if (no_xfer_size)
108203831d35Sstevel return (PICL_WALK_CONTINUE);
108303831d35Sstevel
108403831d35Sstevel match = picldiag_get_uint_propval(bankh, PICL_PROP_ADDRESSMATCH, &err);
108503831d35Sstevel if (err == PICL_PROPNOTFOUND)
108603831d35Sstevel return (PICL_WALK_CONTINUE);
108703831d35Sstevel else if (err != PICL_SUCCESS)
108803831d35Sstevel return (err);
108903831d35Sstevel
109003831d35Sstevel mask = picldiag_get_uint_propval(bankh, PICL_PROP_ADDRESSMASK, &err);
109103831d35Sstevel if (err == PICL_PROPNOTFOUND)
109203831d35Sstevel return (PICL_WALK_CONTINUE);
109303831d35Sstevel else if (err != PICL_SUCCESS)
109403831d35Sstevel return (err);
109503831d35Sstevel
109603831d35Sstevel i = 0;
109703831d35Sstevel while ((i < segp->ifactor) && (newptr->iway_count < MAX_IWAYS)) {
109803831d35Sstevel if (((segp->base + i * mem_xfersize) & mask) == match)
109903831d35Sstevel newptr->iway[newptr->iway_count++] = i;
110003831d35Sstevel ++i;
110103831d35Sstevel }
110203831d35Sstevel return (PICL_WALK_CONTINUE);
110303831d35Sstevel }
110403831d35Sstevel
110503831d35Sstevel
110603831d35Sstevel /*
110703831d35Sstevel * find the memory bank and add the bank handle in the bank list
110803831d35Sstevel * return the head of the bank list
110903831d35Sstevel */
111003831d35Sstevel static int
logprintf_bankinfo(picl_nodehdl_t segh,seg_info_t * segp)111103831d35Sstevel logprintf_bankinfo(picl_nodehdl_t segh, seg_info_t *segp)
111203831d35Sstevel {
111303831d35Sstevel int err;
111403831d35Sstevel
111503831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "BankIDs "));
111603831d35Sstevel /*
111703831d35Sstevel * find memory-bank
111803831d35Sstevel */
111903831d35Sstevel segp->bank_count = 0;
112003831d35Sstevel err = picl_walk_tree_by_class(segh, PICL_CLASS_MEMORY_BANK, segp,
112103831d35Sstevel membank_callback);
112203831d35Sstevel log_printf("\n");
112303831d35Sstevel return (err);
112403831d35Sstevel }
112503831d35Sstevel
112603831d35Sstevel /*
112703831d35Sstevel * print the label of memory module or the memory module bank ids
112803831d35Sstevel */
112903831d35Sstevel static int
logprintf_seg_contains_col(picl_nodehdl_t nodeh,seg_info_t * segp)113003831d35Sstevel logprintf_seg_contains_col(picl_nodehdl_t nodeh, seg_info_t *segp)
113103831d35Sstevel {
113203831d35Sstevel picl_nodehdl_t moduleh;
113303831d35Sstevel int err;
113403831d35Sstevel
113503831d35Sstevel /*
113603831d35Sstevel * find memory-module if referenced directly from the memory-segment
113703831d35Sstevel * (ie no memory banks)
113803831d35Sstevel */
113903831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_REFPROP_MEMORY_MODULE,
114003831d35Sstevel &moduleh, sizeof (moduleh));
114103831d35Sstevel if ((err != PICL_SUCCESS) && (err != PICL_PROPNOTFOUND))
114203831d35Sstevel return (err);
114303831d35Sstevel if (err == PICL_SUCCESS) {
114403831d35Sstevel err = logprintf_memory_module_label(moduleh);
114503831d35Sstevel log_printf("\n");
114603831d35Sstevel return (err);
114703831d35Sstevel }
114803831d35Sstevel
114903831d35Sstevel /*
115003831d35Sstevel * memory-module not referenced directly from the memory segment
115103831d35Sstevel * so list memory banks instead
115203831d35Sstevel */
115303831d35Sstevel err = logprintf_bankinfo(nodeh, segp);
115403831d35Sstevel return (err);
115503831d35Sstevel }
115603831d35Sstevel
115703831d35Sstevel /*
115803831d35Sstevel * find all memory modules under the given memory module group
115903831d35Sstevel * and print its label
116003831d35Sstevel */
116103831d35Sstevel static int
logprintf_memory_module_group_info(picl_nodehdl_t memgrph,uint64_t mcid)116203831d35Sstevel logprintf_memory_module_group_info(picl_nodehdl_t memgrph, uint64_t mcid)
116303831d35Sstevel {
116403831d35Sstevel int err;
116503831d35Sstevel int64_t id;
116603831d35Sstevel boolean_t got_status;
116703831d35Sstevel picl_nodehdl_t moduleh;
116803831d35Sstevel char piclclass[PICL_CLASSNAMELEN_MAX];
116903831d35Sstevel picl_nodehdl_t fruparenth;
117003831d35Sstevel char *status;
117103831d35Sstevel
117203831d35Sstevel id = picldiag_get_uint_propval(memgrph, PICL_PROP_ID, &err);
117303831d35Sstevel if (err == PICL_PROPNOTFOUND)
117403831d35Sstevel id = -1;
117503831d35Sstevel else if (err != PICL_SUCCESS)
117603831d35Sstevel return (err);
117703831d35Sstevel
117803831d35Sstevel err = picl_get_propval_by_name(memgrph, PICL_PROP_CHILD, &moduleh,
117903831d35Sstevel sizeof (picl_nodehdl_t));
118003831d35Sstevel
118103831d35Sstevel while (err == PICL_SUCCESS) {
118203831d35Sstevel /* controller id */
118303831d35Sstevel log_printf("%-8lld ", mcid);
118403831d35Sstevel
118503831d35Sstevel /* group id */
118603831d35Sstevel if (id == -1) {
118703831d35Sstevel log_printf("- ");
118803831d35Sstevel } else {
118903831d35Sstevel log_printf("%-8lld ", id);
119003831d35Sstevel }
119103831d35Sstevel
119203831d35Sstevel err = picl_get_propval_by_name(moduleh, PICL_PROP_CLASSNAME,
119303831d35Sstevel piclclass, sizeof (piclclass));
119403831d35Sstevel if (err != PICL_SUCCESS)
119503831d35Sstevel return (err);
119603831d35Sstevel
119703831d35Sstevel if (strcmp(piclclass, PICL_CLASS_MEMORY_MODULE) == 0) {
119803831d35Sstevel err = logprintf_memory_module_label(moduleh);
119903831d35Sstevel if (err != PICL_SUCCESS)
120003831d35Sstevel return (err);
120103831d35Sstevel }
120203831d35Sstevel
120303831d35Sstevel got_status = B_FALSE;
120403831d35Sstevel err = picldiag_get_fru_parent(moduleh, &fruparenth);
120503831d35Sstevel if (err == PICL_SUCCESS) {
120603831d35Sstevel err = picldiag_get_string_propval(fruparenth,
120703831d35Sstevel PICL_PROP_OPERATIONAL_STATUS, &status);
120803831d35Sstevel if (err == PICL_SUCCESS) {
120903831d35Sstevel got_status = B_TRUE;
121003831d35Sstevel } else if (err != PICL_PROPNOTFOUND)
121103831d35Sstevel return (err);
121203831d35Sstevel } else if (err != PICL_PROPNOTFOUND)
121303831d35Sstevel return (err);
121403831d35Sstevel
121503831d35Sstevel if (!got_status) {
121603831d35Sstevel err = picldiag_get_string_propval(moduleh,
121703831d35Sstevel PICL_PROP_STATUS, &status);
121803831d35Sstevel if (err == PICL_SUCCESS)
121903831d35Sstevel got_status = B_TRUE;
122003831d35Sstevel else if (err != PICL_PROPNOTFOUND)
122103831d35Sstevel return (err);
122203831d35Sstevel }
122303831d35Sstevel if (got_status) {
122403831d35Sstevel log_printf("%s", status);
122503831d35Sstevel free(status);
122603831d35Sstevel }
122703831d35Sstevel err = picl_get_propval_by_name(moduleh, PICL_PROP_PEER,
122803831d35Sstevel &moduleh, sizeof (picl_nodehdl_t));
122903831d35Sstevel
123003831d35Sstevel log_printf("\n");
123103831d35Sstevel }
123203831d35Sstevel if (err == PICL_PROPNOTFOUND)
123303831d35Sstevel return (PICL_SUCCESS);
123403831d35Sstevel return (err);
123503831d35Sstevel }
123603831d35Sstevel
123703831d35Sstevel /*
123803831d35Sstevel * search children to find memory module group under memory-controller
123903831d35Sstevel */
124003831d35Sstevel static int
find_memory_module_group(picl_nodehdl_t mch,int * print_header)124103831d35Sstevel find_memory_module_group(picl_nodehdl_t mch, int *print_header)
124203831d35Sstevel {
124303831d35Sstevel picl_nodehdl_t memgrph;
124403831d35Sstevel uint64_t mcid;
124503831d35Sstevel int err;
124603831d35Sstevel char piclclass[PICL_CLASSNAMELEN_MAX];
124703831d35Sstevel
124803831d35Sstevel mcid = picldiag_get_uint_propval(mch, OBP_PROP_PORTID, &err);
124903831d35Sstevel if (err == PICL_PROPNOTFOUND)
125003831d35Sstevel mcid = DEFAULT_PORTID;
125103831d35Sstevel else if (err != PICL_SUCCESS)
125203831d35Sstevel return (err);
125303831d35Sstevel
125403831d35Sstevel err = picl_get_propval_by_name(mch, PICL_PROP_CHILD,
125503831d35Sstevel &memgrph, sizeof (picl_nodehdl_t));
125603831d35Sstevel while (err == PICL_SUCCESS) {
125703831d35Sstevel err = picl_get_propval_by_name(memgrph,
125803831d35Sstevel PICL_PROP_CLASSNAME, piclclass, sizeof (piclclass));
125903831d35Sstevel if (err != PICL_SUCCESS)
126003831d35Sstevel return (err);
126103831d35Sstevel
126203831d35Sstevel if (strcmp(piclclass, PICL_CLASS_MEMORY_MODULE_GROUP) == 0) {
126303831d35Sstevel if (*print_header == 1) {
126403831d35Sstevel log_printf(
126503831d35Sstevel dgettext(TEXT_DOMAIN,
1266*2983dda7SMichael Bergknoff "\nMemory Module Groups:\n"));
126703831d35Sstevel log_printf("--------------------------");
126803831d35Sstevel log_printf("------\n");
126903831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
127003831d35Sstevel "ControllerID GroupID Labels\n"));
127103831d35Sstevel log_printf("--------------------------");
127203831d35Sstevel log_printf("------\n");
127303831d35Sstevel *print_header = 0;
127403831d35Sstevel }
127503831d35Sstevel err = logprintf_memory_module_group_info(memgrph, mcid);
127603831d35Sstevel if (err != PICL_SUCCESS)
127703831d35Sstevel return (err);
127803831d35Sstevel }
127903831d35Sstevel
128003831d35Sstevel err = picl_get_propval_by_name(memgrph, PICL_PROP_PEER,
128103831d35Sstevel &memgrph, sizeof (picl_nodehdl_t));
128203831d35Sstevel }
128303831d35Sstevel if (err == PICL_PROPNOTFOUND)
128403831d35Sstevel return (PICL_SUCCESS);
128503831d35Sstevel return (err);
128603831d35Sstevel }
128703831d35Sstevel
128803831d35Sstevel /*
128903831d35Sstevel * print memory module group table per memory-controller
129003831d35Sstevel */
129103831d35Sstevel static int
print_memory_module_group_table(picl_nodehdl_t plafh)129203831d35Sstevel print_memory_module_group_table(picl_nodehdl_t plafh)
129303831d35Sstevel {
129403831d35Sstevel picl_nodehdl_t mch;
129503831d35Sstevel int err;
129603831d35Sstevel char piclclass[PICL_CLASSNAMELEN_MAX];
129703831d35Sstevel int print_header;
129803831d35Sstevel
129903831d35Sstevel print_header = 1;
130003831d35Sstevel
130103831d35Sstevel /*
130203831d35Sstevel * find memory-controller
130303831d35Sstevel */
130403831d35Sstevel err = picl_get_propval_by_name(plafh, PICL_PROP_CHILD, &mch,
130503831d35Sstevel sizeof (picl_nodehdl_t));
130603831d35Sstevel while (err == PICL_SUCCESS) {
130703831d35Sstevel err = picl_get_propval_by_name(mch, PICL_PROP_CLASSNAME,
130803831d35Sstevel piclclass, sizeof (piclclass));
130903831d35Sstevel if (err != PICL_SUCCESS)
131003831d35Sstevel return (err);
131103831d35Sstevel
131203831d35Sstevel if (strcmp(piclclass, PICL_CLASS_MEMORY_CONTROLLER) != 0) {
131303831d35Sstevel err = print_memory_module_group_table(mch);
131403831d35Sstevel if (err != PICL_SUCCESS)
131503831d35Sstevel return (err);
131603831d35Sstevel err = picl_get_propval_by_name(mch, PICL_PROP_PEER,
131703831d35Sstevel &mch, sizeof (picl_nodehdl_t));
131803831d35Sstevel continue;
131903831d35Sstevel }
132003831d35Sstevel
132103831d35Sstevel err = find_memory_module_group(mch, &print_header);
132203831d35Sstevel if (err != PICL_SUCCESS)
132303831d35Sstevel return (err);
132403831d35Sstevel
132503831d35Sstevel err = picl_get_propval_by_name(mch, PICL_PROP_PEER,
132603831d35Sstevel &mch, sizeof (picl_nodehdl_t));
132703831d35Sstevel }
132803831d35Sstevel if (err == PICL_PROPNOTFOUND)
132903831d35Sstevel return (PICL_SUCCESS);
133003831d35Sstevel
133103831d35Sstevel return (err);
133203831d35Sstevel }
133303831d35Sstevel
133403831d35Sstevel /*
133503831d35Sstevel * print bank table
133603831d35Sstevel */
133703831d35Sstevel static int
print_bank_table(void)133803831d35Sstevel print_bank_table(void)
133903831d35Sstevel {
134003831d35Sstevel bank_list_t *ptr;
134103831d35Sstevel picl_nodehdl_t bankh;
134203831d35Sstevel picl_nodehdl_t memgrph;
134303831d35Sstevel picl_nodehdl_t mch;
134403831d35Sstevel int err;
134503831d35Sstevel int32_t i;
134603831d35Sstevel uint64_t size;
134703831d35Sstevel int id;
134803831d35Sstevel
134903831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "\nBank Table:\n"));
135003831d35Sstevel log_printf("---------------------------------------");
135103831d35Sstevel log_printf("--------------------\n");
135203831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, " Physical Location\n"));
135303831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "ID ControllerID GroupID "));
135403831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "Size Interleave Way\n"));
135503831d35Sstevel log_printf("---------------------------------------");
135603831d35Sstevel log_printf("--------------------\n");
135703831d35Sstevel
135803831d35Sstevel for (ptr = mem_banks; ptr != NULL; ptr = ptr->next) {
135903831d35Sstevel bankh = ptr->nodeh;
136003831d35Sstevel id = picldiag_get_uint_propval(bankh, PICL_PROP_ID, &err);
136103831d35Sstevel if (err != PICL_SUCCESS)
136203831d35Sstevel log_printf("%-8s ", "-");
136303831d35Sstevel else
136403831d35Sstevel log_printf("%-8d ", id);
136503831d35Sstevel
136603831d35Sstevel /* find memory-module-group */
136703831d35Sstevel err = picl_get_propval_by_name(bankh,
136803831d35Sstevel PICL_REFPROP_MEMORY_MODULE_GROUP, &memgrph,
136903831d35Sstevel sizeof (memgrph));
137003831d35Sstevel if (err == PICL_PROPNOTFOUND) {
137103831d35Sstevel log_printf("%-8s ", "-");
137203831d35Sstevel log_printf("%-8s ", "-");
137303831d35Sstevel } else if (err != PICL_SUCCESS)
137403831d35Sstevel return (err);
137503831d35Sstevel else {
137603831d35Sstevel /*
137703831d35Sstevel * get controller id
137803831d35Sstevel */
137903831d35Sstevel err = picl_get_propval_by_name(memgrph,
138003831d35Sstevel PICL_PROP_PARENT, &mch, sizeof (picl_nodehdl_t));
138103831d35Sstevel if (err != PICL_SUCCESS)
138203831d35Sstevel return (err);
138303831d35Sstevel
138403831d35Sstevel id = picldiag_get_uint_propval(mch, OBP_PROP_PORTID,
138503831d35Sstevel &err);
138603831d35Sstevel if (err == PICL_PROPNOTFOUND)
138703831d35Sstevel id = DEFAULT_PORTID; /* use default */
138803831d35Sstevel else if (err != PICL_SUCCESS)
138903831d35Sstevel return (err);
139003831d35Sstevel
139103831d35Sstevel log_printf("%-8d ", id);
139203831d35Sstevel
139303831d35Sstevel /* get group id */
139403831d35Sstevel id = picldiag_get_uint_propval(memgrph, PICL_PROP_ID,
139503831d35Sstevel &err);
139603831d35Sstevel if (err == PICL_PROPNOTFOUND)
139703831d35Sstevel log_printf("- ");
139803831d35Sstevel else if (err == PICL_SUCCESS)
139903831d35Sstevel log_printf("%-8d ", id);
140003831d35Sstevel else
140103831d35Sstevel return (err);
140203831d35Sstevel }
140303831d35Sstevel
140403831d35Sstevel size = picldiag_get_uint_propval(bankh, PICL_PROP_SIZE, &err);
140503831d35Sstevel if (err == PICL_PROPNOTFOUND)
140603831d35Sstevel log_printf("- ");
140703831d35Sstevel else if (err == PICL_SUCCESS)
140803831d35Sstevel logprintf_size(size);
140903831d35Sstevel else
141003831d35Sstevel return (err);
141103831d35Sstevel
141203831d35Sstevel log_printf(" ");
141303831d35Sstevel for (i = 0; i < ptr->iway_count; i++) {
141403831d35Sstevel if (i != 0)
141503831d35Sstevel log_printf(",");
141603831d35Sstevel log_printf("%d", ptr->iway[i]);
141703831d35Sstevel }
141803831d35Sstevel
141903831d35Sstevel log_printf("\n");
142003831d35Sstevel }
142103831d35Sstevel return (PICL_SUCCESS);
142203831d35Sstevel }
142303831d35Sstevel
142403831d35Sstevel /*
142503831d35Sstevel * callback function to print segment, add the bank in the list and
142603831d35Sstevel * return the bank list
142703831d35Sstevel */
142803831d35Sstevel /* ARGSUSED */
142903831d35Sstevel static int
memseg_callback(picl_nodehdl_t segh,void * args)143003831d35Sstevel memseg_callback(picl_nodehdl_t segh, void *args)
143103831d35Sstevel {
143203831d35Sstevel seg_info_t seginfo;
143303831d35Sstevel int err;
143403831d35Sstevel
143503831d35Sstevel /* get base address */
143603831d35Sstevel seginfo.base = picldiag_get_uint_propval(segh, PICL_PROP_BASEADDRESS,
143703831d35Sstevel &err);
143803831d35Sstevel if (err == PICL_PROPNOTFOUND) {
143903831d35Sstevel log_printf("-\n");
144003831d35Sstevel return (PICL_WALK_CONTINUE);
144103831d35Sstevel } else if (err == PICL_SUCCESS)
144203831d35Sstevel log_printf("0x%-16llx ", seginfo.base);
144303831d35Sstevel else
144403831d35Sstevel return (err);
144503831d35Sstevel
144603831d35Sstevel /* get size */
144703831d35Sstevel seginfo.size = picldiag_get_uint_propval(segh, PICL_PROP_SIZE, &err);
144803831d35Sstevel if (err == PICL_PROPNOTFOUND) {
144903831d35Sstevel log_printf("-\n");
145003831d35Sstevel return (PICL_WALK_CONTINUE);
145103831d35Sstevel } else if (err == PICL_SUCCESS)
145203831d35Sstevel logprintf_size(seginfo.size);
145303831d35Sstevel else
145403831d35Sstevel return (err);
145503831d35Sstevel
145603831d35Sstevel /* get interleave factor */
145703831d35Sstevel seginfo.ifactor = picldiag_get_uint_propval(segh,
145803831d35Sstevel PICL_PROP_INTERLEAVE_FACTOR, &err);
145903831d35Sstevel
146003831d35Sstevel if (err == PICL_PROPNOTFOUND) {
146103831d35Sstevel log_printf(" -\n");
146203831d35Sstevel return (PICL_WALK_CONTINUE);
146303831d35Sstevel } else if (err == PICL_SUCCESS)
146403831d35Sstevel log_printf(" %-2d ", seginfo.ifactor);
146503831d35Sstevel else
146603831d35Sstevel return (err);
146703831d35Sstevel
146803831d35Sstevel seginfo.bank_count = 0;
146903831d35Sstevel err = logprintf_seg_contains_col(segh, &seginfo);
147003831d35Sstevel if (err != PICL_SUCCESS)
147103831d35Sstevel return (err);
147203831d35Sstevel return (PICL_WALK_CONTINUE);
147303831d35Sstevel }
147403831d35Sstevel
147503831d35Sstevel /*
147603831d35Sstevel * search children to find memory-segment and set up the bank list
147703831d35Sstevel */
147803831d35Sstevel static int
find_segments(picl_nodehdl_t plafh)147903831d35Sstevel find_segments(picl_nodehdl_t plafh)
148003831d35Sstevel {
148103831d35Sstevel int err;
148203831d35Sstevel
148303831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "Segment Table:\n"));
148403831d35Sstevel log_printf("------------------------------");
148503831d35Sstevel log_printf("-----------------------------------------\n");
148603831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "Base Address Size "));
148703831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "Interleave Factor Contains\n"));
148803831d35Sstevel log_printf("------------------------------");
148903831d35Sstevel log_printf("-----------------------------------------\n");
149003831d35Sstevel
149103831d35Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY_SEGMENT,
149203831d35Sstevel NULL, memseg_callback);
149303831d35Sstevel return (err);
149403831d35Sstevel }
149503831d35Sstevel
149603831d35Sstevel /*
149703831d35Sstevel * display memory configuration
149803831d35Sstevel */
149903831d35Sstevel static int
display_memory_config(picl_nodehdl_t plafh)150003831d35Sstevel display_memory_config(picl_nodehdl_t plafh)
150103831d35Sstevel {
150203831d35Sstevel int err;
150303831d35Sstevel
150403831d35Sstevel logprintf_header(dgettext(TEXT_DOMAIN, "Memory Configuration"),
150503831d35Sstevel DEFAULT_LINE_WIDTH);
150603831d35Sstevel
150703831d35Sstevel mem_banks = NULL;
150803831d35Sstevel err = find_segments(plafh);
150903831d35Sstevel
151003831d35Sstevel if ((err == PICL_SUCCESS) && (mem_banks != NULL))
151103831d35Sstevel print_bank_table();
151203831d35Sstevel
151303831d35Sstevel free_bank_list();
151403831d35Sstevel
151503831d35Sstevel return (print_memory_module_group_table(plafh));
151603831d35Sstevel }
151703831d35Sstevel
151803831d35Sstevel /*
151903831d35Sstevel * print the hub device
152003831d35Sstevel */
152103831d35Sstevel static int
logprintf_hub_devices(picl_nodehdl_t hubh)152203831d35Sstevel logprintf_hub_devices(picl_nodehdl_t hubh)
152303831d35Sstevel {
152403831d35Sstevel char *name;
152503831d35Sstevel int portnum;
152603831d35Sstevel char *labelp;
152703831d35Sstevel picl_nodehdl_t parenth;
152803831d35Sstevel int err;
152903831d35Sstevel
153003831d35Sstevel err = picldiag_get_string_propval(hubh, PICL_PROP_NAME, &name);
153103831d35Sstevel if (err != PICL_SUCCESS)
153203831d35Sstevel return (err);
153303831d35Sstevel log_printf("%-12.12s ", name);
153403831d35Sstevel free(name);
153503831d35Sstevel
153603831d35Sstevel err = picl_get_propval_by_name(hubh, PICL_REFPROP_LOC_PARENT, &parenth,
153703831d35Sstevel sizeof (picl_nodehdl_t));
153803831d35Sstevel
153903831d35Sstevel if (err == PICL_SUCCESS) {
154003831d35Sstevel /* Read the Label */
154103831d35Sstevel err = picldiag_get_label(parenth, &labelp);
154203831d35Sstevel if (err == PICL_SUCCESS) {
154303831d35Sstevel log_printf("%s\n", labelp);
154403831d35Sstevel free(labelp);
154503831d35Sstevel return (PICL_SUCCESS);
154603831d35Sstevel } else if (err != PICL_PROPNOTFOUND) {
154703831d35Sstevel log_printf("\n");
154803831d35Sstevel return (err);
154903831d35Sstevel }
155003831d35Sstevel } else if (err != PICL_PROPNOTFOUND) {
155103831d35Sstevel log_printf("\n");
155203831d35Sstevel return (err);
155303831d35Sstevel }
155403831d35Sstevel
155503831d35Sstevel /* No Label, try the reg */
155603831d35Sstevel err = picl_get_propval_by_name(hubh, OBP_PROP_REG, &portnum,
155703831d35Sstevel sizeof (portnum));
155803831d35Sstevel if (err == PICL_PROPNOTFOUND)
155903831d35Sstevel log_printf(" -\n");
156003831d35Sstevel else if (err != PICL_SUCCESS) {
156103831d35Sstevel log_printf("\n");
156203831d35Sstevel return (err);
156303831d35Sstevel } else
156403831d35Sstevel log_printf("%3d\n", portnum);
156503831d35Sstevel
156603831d35Sstevel return (PICL_SUCCESS);
156703831d35Sstevel }
156803831d35Sstevel
156903831d35Sstevel /*
157003831d35Sstevel * callback functions to display hub devices
157103831d35Sstevel */
157203831d35Sstevel /* ARGSUSED */
157303831d35Sstevel static int
print_usb_devices(picl_nodehdl_t hubh,void * arg)157403831d35Sstevel print_usb_devices(picl_nodehdl_t hubh, void *arg)
157503831d35Sstevel {
157603831d35Sstevel picl_nodehdl_t chdh;
157703831d35Sstevel char *rootname;
157803831d35Sstevel int type = *(int *)arg;
157903831d35Sstevel int hubnum;
158003831d35Sstevel int err;
158103831d35Sstevel
158203831d35Sstevel err = picl_get_propval_by_name(hubh, PICL_PROP_CHILD, &chdh,
158303831d35Sstevel sizeof (picl_nodehdl_t));
158403831d35Sstevel
158503831d35Sstevel /* print header */
158603831d35Sstevel if (err == PICL_SUCCESS) {
158703831d35Sstevel err = picldiag_get_string_propval(hubh, PICL_PROP_NAME,
158803831d35Sstevel &rootname);
158903831d35Sstevel if (err != PICL_SUCCESS)
159003831d35Sstevel return (err);
159103831d35Sstevel
159203831d35Sstevel if (type == USB) {
159303831d35Sstevel log_printf("\n===============================");
159403831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
159503831d35Sstevel " %s Devices "), rootname);
159603831d35Sstevel } else {
159703831d35Sstevel /* Get its hub number */
159803831d35Sstevel err = picl_get_propval_by_name(hubh,
159903831d35Sstevel OBP_PROP_REG, &hubnum, sizeof (hubnum));
160003831d35Sstevel if ((err != PICL_SUCCESS) &&
160103831d35Sstevel (err != PICL_PROPNOTFOUND)) {
160203831d35Sstevel free(rootname);
160303831d35Sstevel return (err);
160403831d35Sstevel }
160503831d35Sstevel
160603831d35Sstevel log_printf("\n===============================");
160703831d35Sstevel if (err == PICL_SUCCESS)
160803831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
160903831d35Sstevel " %s#%d Devices "),
161003831d35Sstevel rootname, hubnum);
161103831d35Sstevel else
161203831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
161303831d35Sstevel " %s Devices "), rootname);
161403831d35Sstevel }
161503831d35Sstevel
161603831d35Sstevel log_printf("===============================\n\n");
161703831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "Name Port#\n"));
161803831d35Sstevel log_printf("------------ -----\n");
161903831d35Sstevel free(rootname);
162003831d35Sstevel
162103831d35Sstevel do {
162203831d35Sstevel logprintf_hub_devices(chdh);
162303831d35Sstevel
162403831d35Sstevel err = picl_get_propval_by_name(chdh, PICL_PROP_PEER,
162503831d35Sstevel &chdh, sizeof (picl_nodehdl_t));
162603831d35Sstevel } while (err == PICL_SUCCESS);
162703831d35Sstevel }
162803831d35Sstevel
162903831d35Sstevel
163003831d35Sstevel if (err == PICL_PROPNOTFOUND)
163103831d35Sstevel return (PICL_WALK_CONTINUE);
163203831d35Sstevel return (err);
163303831d35Sstevel }
163403831d35Sstevel
163503831d35Sstevel /*
163603831d35Sstevel * callback functions to display usb devices
163703831d35Sstevel */
163803831d35Sstevel /* ARGSUSED */
163903831d35Sstevel static int
usb_callback(picl_nodehdl_t usbh,void * args)164003831d35Sstevel usb_callback(picl_nodehdl_t usbh, void *args)
164103831d35Sstevel {
164203831d35Sstevel int err;
164303831d35Sstevel int type;
164403831d35Sstevel
164503831d35Sstevel type = USB;
164603831d35Sstevel err = print_usb_devices(usbh, &type);
164703831d35Sstevel if (err != PICL_WALK_CONTINUE)
164803831d35Sstevel return (err);
164903831d35Sstevel type = HUB;
165003831d35Sstevel err = picl_walk_tree_by_class(usbh, NULL, &type, print_usb_devices);
165103831d35Sstevel if (err == PICL_SUCCESS)
165203831d35Sstevel err = PICL_WALK_CONTINUE;
165303831d35Sstevel return (err);
165403831d35Sstevel }
165503831d35Sstevel
165603831d35Sstevel
165703831d35Sstevel /*
165803831d35Sstevel * find usb devices and print its information
165903831d35Sstevel */
166003831d35Sstevel static int
display_usb_devices(picl_nodehdl_t plafh)166103831d35Sstevel display_usb_devices(picl_nodehdl_t plafh)
166203831d35Sstevel {
166303831d35Sstevel int err;
166403831d35Sstevel
166503831d35Sstevel /*
166603831d35Sstevel * get the usb node
166703831d35Sstevel */
166803831d35Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_USB, NULL,
166903831d35Sstevel usb_callback);
167003831d35Sstevel return (err);
167103831d35Sstevel }
167203831d35Sstevel
167303831d35Sstevel
167403831d35Sstevel
167503831d35Sstevel /*
167603831d35Sstevel * If nodeh is the io device, add it into the io list and return
167703831d35Sstevel * If it is not an io device and it has the subtree, traverse the subtree
167803831d35Sstevel * and add all leaf io devices
167903831d35Sstevel */
168003831d35Sstevel 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)168103831d35Sstevel add_io_leaves(picl_nodehdl_t nodeh, char *parentname, uint32_t board,
168203831d35Sstevel uint32_t bus_id, uint64_t slot, uint32_t freq, char *model, char *status)
168303831d35Sstevel {
168403831d35Sstevel picl_nodehdl_t childh;
168503831d35Sstevel picl_prophdl_t proph;
168603831d35Sstevel picl_propinfo_t pinfo;
168703831d35Sstevel int err;
168803831d35Sstevel char *nameval;
168903831d35Sstevel char piclclass[PICL_CLASSNAMELEN_MAX];
169003831d35Sstevel char nodename[MAXSTRLEN];
169103831d35Sstevel char name[MAXSTRLEN];
169203831d35Sstevel char *devfs_path;
169303831d35Sstevel char *compatible;
169403831d35Sstevel picl_nodehdl_t fruparenth;
169503831d35Sstevel char *label;
169603831d35Sstevel char binding_name[MAXSTRLEN];
169703831d35Sstevel
169803831d35Sstevel err = picl_get_propinfo_by_name(nodeh, PICL_PROP_NAME, &pinfo,
169903831d35Sstevel &proph);
170003831d35Sstevel if (err != PICL_SUCCESS)
170103831d35Sstevel return (err);
170203831d35Sstevel
170303831d35Sstevel nameval = alloca(pinfo.size);
170403831d35Sstevel if (nameval == NULL)
170503831d35Sstevel return (PICL_FAILURE);
170603831d35Sstevel
170703831d35Sstevel err = picl_get_propval(proph, nameval, pinfo.size);
170803831d35Sstevel if (err != PICL_SUCCESS)
170903831d35Sstevel return (err);
171003831d35Sstevel
171103831d35Sstevel (void) strlcpy(nodename, nameval, MAXSTRLEN);
171203831d35Sstevel
171303831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
171403831d35Sstevel piclclass, sizeof (piclclass));
171503831d35Sstevel if (err != PICL_SUCCESS)
171603831d35Sstevel return (err);
171703831d35Sstevel
171803831d35Sstevel /* if binding_name is found, name will be <nodename>-<binding_name> */
171903831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_BINDING_NAME,
172003831d35Sstevel binding_name, sizeof (binding_name));
172103831d35Sstevel if (err == PICL_PROPNOTFOUND) {
172203831d35Sstevel /*
172303831d35Sstevel * if compatible prop is found, name will be
172403831d35Sstevel * <nodename>-<compatible>
172503831d35Sstevel */
172603831d35Sstevel err = picldiag_get_first_compatible_value(nodeh, &compatible);
172703831d35Sstevel if (err == PICL_SUCCESS) {
172803831d35Sstevel strlcat(nodename, "-", MAXSTRLEN);
172903831d35Sstevel strlcat(nodename, compatible, MAXSTRLEN);
173003831d35Sstevel free(compatible);
173103831d35Sstevel } else if (err != PICL_PROPNOTFOUND) {
173203831d35Sstevel return (err);
173303831d35Sstevel }
173403831d35Sstevel } else if (err != PICL_SUCCESS) {
173503831d35Sstevel return (err);
173603831d35Sstevel } else if (strcmp(nodename, binding_name) != 0) {
173703831d35Sstevel if (strcmp(nodename, piclclass) == 0) {
173803831d35Sstevel /*
173903831d35Sstevel * nodename same as binding name -
174003831d35Sstevel * no need to display twice
174103831d35Sstevel */
174203831d35Sstevel strlcpy(nodename, binding_name, MAXSTRLEN);
174303831d35Sstevel } else {
174403831d35Sstevel strlcat(nodename, "-", MAXSTRLEN);
174503831d35Sstevel strlcat(nodename, binding_name, MAXSTRLEN);
174603831d35Sstevel }
174703831d35Sstevel }
174803831d35Sstevel
174903831d35Sstevel /*
175003831d35Sstevel * If it is an immediate child under pci and not
175103831d35Sstevel * a bus node, add it to the io list.
175203831d35Sstevel * If it is a child under sub-bus and it is in an io
175303831d35Sstevel * device, add it to the io list.
175403831d35Sstevel */
175503831d35Sstevel if (((parentname == NULL) && (!is_bus(piclclass))) ||
175603831d35Sstevel ((parentname != NULL) && (is_io_device(piclclass)))) {
175703831d35Sstevel if (parentname == NULL)
175803831d35Sstevel (void) snprintf(name, MAXSTRLEN, "%s", nodename);
175903831d35Sstevel else
176003831d35Sstevel (void) snprintf(name, MAXSTRLEN, "%s/%s", parentname,
176103831d35Sstevel nodename);
176203831d35Sstevel
176303831d35Sstevel /*
176403831d35Sstevel * append the class if its class is not a generic
176503831d35Sstevel * obp-device class
176603831d35Sstevel */
176703831d35Sstevel if (strcmp(piclclass, PICL_CLASS_OBP_DEVICE))
176803831d35Sstevel (void) snprintf(name, MAXSTRLEN, "%s (%s)", name,
176903831d35Sstevel piclclass);
177003831d35Sstevel
177103831d35Sstevel err = picldiag_get_fru_parent(nodeh, &fruparenth);
177203831d35Sstevel if (err == PICL_PROPNOTFOUND) {
177303831d35Sstevel label = NULL;
177403831d35Sstevel } else if (err != PICL_SUCCESS) {
177503831d35Sstevel return (err);
177603831d35Sstevel } else {
177703831d35Sstevel err = picldiag_get_combined_label(fruparenth, &label,
177803831d35Sstevel 15);
177903831d35Sstevel if (err == PICL_PROPNOTFOUND)
178003831d35Sstevel label = NULL;
178103831d35Sstevel else if (err != PICL_SUCCESS)
178203831d35Sstevel return (err);
178303831d35Sstevel }
178403831d35Sstevel /* devfs-path */
178503831d35Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_DEVFS_PATH,
178603831d35Sstevel &devfs_path);
178703831d35Sstevel if (err == PICL_PROPNOTFOUND)
178803831d35Sstevel devfs_path = NULL;
178903831d35Sstevel else if (err != PICL_SUCCESS)
179003831d35Sstevel return (err);
179103831d35Sstevel
179203831d35Sstevel add_io_card(board, bus_id, slot, label, freq, name,
179303831d35Sstevel model, status, devfs_path);
179403831d35Sstevel if (label != NULL)
179503831d35Sstevel free(label);
179603831d35Sstevel if (devfs_path != NULL)
179703831d35Sstevel free(devfs_path);
179803831d35Sstevel return (PICL_SUCCESS);
179903831d35Sstevel }
180003831d35Sstevel
180103831d35Sstevel /*
180203831d35Sstevel * If there is any child, Go through each child.
180303831d35Sstevel */
180403831d35Sstevel
180503831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_CHILD,
180603831d35Sstevel &childh, sizeof (picl_nodehdl_t));
180703831d35Sstevel
180803831d35Sstevel /* there is a child */
180903831d35Sstevel while (err == PICL_SUCCESS) {
181003831d35Sstevel if (parentname == NULL)
181103831d35Sstevel (void) strlcpy(name, nodename, MAXSTRLEN);
181203831d35Sstevel else
181303831d35Sstevel (void) snprintf(name, MAXSTRLEN, "%s/%s", parentname,
181403831d35Sstevel nodename);
181503831d35Sstevel
181603831d35Sstevel err = add_io_leaves(childh, name, board, bus_id, slot, freq,
181703831d35Sstevel model, status);
181803831d35Sstevel if (err != PICL_SUCCESS)
181903831d35Sstevel return (err);
182003831d35Sstevel /*
182103831d35Sstevel * get next child
182203831d35Sstevel */
182303831d35Sstevel err = picl_get_propval_by_name(childh, PICL_PROP_PEER,
182403831d35Sstevel &childh, sizeof (picl_nodehdl_t));
182503831d35Sstevel }
182603831d35Sstevel
182703831d35Sstevel if (err == PICL_PROPNOTFOUND)
182803831d35Sstevel return (PICL_SUCCESS);
182903831d35Sstevel return (err);
183003831d35Sstevel }
183103831d35Sstevel
183203831d35Sstevel
183303831d35Sstevel /*
183403831d35Sstevel * add all io devices under pci in io list
183503831d35Sstevel */
183603831d35Sstevel /* ARGSUSED */
183703831d35Sstevel static int
pci_callback(picl_nodehdl_t pcih,void * args)183803831d35Sstevel pci_callback(picl_nodehdl_t pcih, void *args)
183903831d35Sstevel {
184003831d35Sstevel picl_nodehdl_t nodeh;
184103831d35Sstevel int err;
184203831d35Sstevel char piclclass[PICL_CLASSNAMELEN_MAX];
184303831d35Sstevel uint32_t boardnum;
184403831d35Sstevel uint32_t bus_id;
184503831d35Sstevel uint32_t slot;
184603831d35Sstevel uint32_t freq;
184703831d35Sstevel char *model;
184803831d35Sstevel char *status;
184903831d35Sstevel
185003831d35Sstevel /* Fill in common infomation */
185103831d35Sstevel bus_id = PCI_TYPE;
185203831d35Sstevel
185303831d35Sstevel /*
185403831d35Sstevel * Check if it has the freq, if not,
185503831d35Sstevel * If not, use its parent's freq
185603831d35Sstevel * if its parent's freq is not found, return
185703831d35Sstevel */
185803831d35Sstevel err = picldiag_get_clock_freq(pcih, &freq);
185903831d35Sstevel if (err == PICL_PROPNOTFOUND) {
186003831d35Sstevel err = picldiag_get_clock_from_parent(pcih, &freq);
186103831d35Sstevel if (err == PICL_PROPNOTFOUND)
186203831d35Sstevel return (PICL_WALK_CONTINUE);
186303831d35Sstevel else if (err != PICL_SUCCESS)
186403831d35Sstevel return (err);
186503831d35Sstevel } else if (err != PICL_SUCCESS)
186603831d35Sstevel return (err);
186703831d35Sstevel
186803831d35Sstevel /*
186903831d35Sstevel * If no board# is found, set boardnum to 0
187003831d35Sstevel */
187103831d35Sstevel boardnum = picldiag_get_uint_propval(pcih, OBP_PROP_BOARD_NUM, &err);
187203831d35Sstevel if (err == PICL_PROPNOTFOUND)
187303831d35Sstevel boardnum = DEFAULT_BOARD_NUM;
187403831d35Sstevel else if (err != PICL_SUCCESS)
187503831d35Sstevel return (err);
187603831d35Sstevel
187703831d35Sstevel /* Walk through the children */
187803831d35Sstevel
187903831d35Sstevel err = picl_get_propval_by_name(pcih, PICL_PROP_CHILD, &nodeh,
188003831d35Sstevel sizeof (picl_nodehdl_t));
188103831d35Sstevel while (err == PICL_SUCCESS) {
188203831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
188303831d35Sstevel piclclass, sizeof (piclclass));
188403831d35Sstevel if (err != PICL_SUCCESS)
188503831d35Sstevel return (err);
188603831d35Sstevel
188703831d35Sstevel /*
188803831d35Sstevel * Skip PCI bridge and USB devices because they will be
188903831d35Sstevel * processed later
189003831d35Sstevel */
189103831d35Sstevel if ((strcmp(piclclass, PICL_CLASS_PCI) == 0) ||
189203831d35Sstevel (strcmp(piclclass, PICL_CLASS_USB) == 0)) {
189303831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER,
189403831d35Sstevel &nodeh, sizeof (picl_nodehdl_t));
189503831d35Sstevel continue;
189603831d35Sstevel }
189703831d35Sstevel
189803831d35Sstevel /* Get the device id for pci card */
189903831d35Sstevel slot = picldiag_get_uint_propval(nodeh,
190003831d35Sstevel PICL_PROP_DEVICE_ID, &err);
190103831d35Sstevel if (err == PICL_PROPNOTFOUND) {
190203831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER,
190303831d35Sstevel &nodeh, sizeof (picl_nodehdl_t));
190403831d35Sstevel continue;
190503831d35Sstevel } else if (err != PICL_SUCCESS)
190603831d35Sstevel return (err);
190703831d35Sstevel
190803831d35Sstevel /* Get the model of this card */
190903831d35Sstevel err = picldiag_get_string_propval(nodeh, OBP_PROP_MODEL,
191003831d35Sstevel &model);
191103831d35Sstevel if (err == PICL_PROPNOTFOUND)
191203831d35Sstevel model = NULL;
191303831d35Sstevel else if (err != PICL_SUCCESS)
191403831d35Sstevel return (err);
191503831d35Sstevel
191603831d35Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_STATUS,
191703831d35Sstevel &status);
191803831d35Sstevel if (err == PICL_PROPNOTFOUND) {
191903831d35Sstevel status = malloc(5);
192003831d35Sstevel if (status == NULL)
192103831d35Sstevel return (PICL_FAILURE);
192203831d35Sstevel strlcpy(status, "okay", 5);
192303831d35Sstevel } else if (err != PICL_SUCCESS)
192403831d35Sstevel return (err);
192503831d35Sstevel
192603831d35Sstevel err = add_io_leaves(nodeh, NULL, boardnum, bus_id, slot,
192703831d35Sstevel freq, model, status);
192803831d35Sstevel
192903831d35Sstevel if (model != NULL)
193003831d35Sstevel free(model);
193103831d35Sstevel
193203831d35Sstevel if (status != NULL)
193303831d35Sstevel free(status);
193403831d35Sstevel
193503831d35Sstevel if (err != PICL_SUCCESS)
193603831d35Sstevel return (err);
193703831d35Sstevel
193803831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh,
193903831d35Sstevel sizeof (picl_nodehdl_t));
194003831d35Sstevel
194103831d35Sstevel }
194203831d35Sstevel
194303831d35Sstevel if (err == PICL_PROPNOTFOUND)
194403831d35Sstevel return (PICL_WALK_CONTINUE);
194503831d35Sstevel
194603831d35Sstevel return (err);
194703831d35Sstevel }
194803831d35Sstevel
194903831d35Sstevel
195003831d35Sstevel /*
195103831d35Sstevel * loop through all children and add io devices in io list
195203831d35Sstevel */
195303831d35Sstevel static int
process_io_leaves(picl_nodehdl_t rooth)195403831d35Sstevel process_io_leaves(picl_nodehdl_t rooth)
195503831d35Sstevel {
195603831d35Sstevel picl_nodehdl_t nodeh;
195703831d35Sstevel char classval[PICL_CLASSNAMELEN_MAX];
195803831d35Sstevel int err;
195903831d35Sstevel
196003831d35Sstevel err = picl_get_propval_by_name(rooth, PICL_PROP_CHILD, &nodeh,
196103831d35Sstevel sizeof (picl_nodehdl_t));
196203831d35Sstevel while (err == PICL_SUCCESS) {
196303831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
196403831d35Sstevel classval, sizeof (classval));
196503831d35Sstevel if (err != PICL_SUCCESS)
196603831d35Sstevel return (err);
196703831d35Sstevel
196803831d35Sstevel if (err != PICL_SUCCESS)
196903831d35Sstevel return (err);
197003831d35Sstevel
197103831d35Sstevel err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh,
197203831d35Sstevel sizeof (picl_nodehdl_t));
197303831d35Sstevel }
197403831d35Sstevel
197503831d35Sstevel if (err == PICL_PROPNOTFOUND)
197603831d35Sstevel return (PICL_SUCCESS);
197703831d35Sstevel
197803831d35Sstevel return (err);
197903831d35Sstevel }
198003831d35Sstevel
198103831d35Sstevel
198203831d35Sstevel /*
198303831d35Sstevel * find all io devices and add them in the io list
198403831d35Sstevel */
198503831d35Sstevel static int
gather_io_cards(picl_nodehdl_t plafh)198603831d35Sstevel gather_io_cards(picl_nodehdl_t plafh)
198703831d35Sstevel {
198803831d35Sstevel int err;
198903831d35Sstevel
199003831d35Sstevel /*
199103831d35Sstevel * look for io devices under the immediate children of platform
199203831d35Sstevel */
199303831d35Sstevel err = process_io_leaves(plafh);
199403831d35Sstevel
199503831d35Sstevel if (err != PICL_SUCCESS)
199603831d35Sstevel return (err);
199703831d35Sstevel
199803831d35Sstevel if (err != PICL_SUCCESS)
199903831d35Sstevel return (err);
200003831d35Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_PCI,
200103831d35Sstevel PICL_CLASS_PCI, pci_callback);
200203831d35Sstevel if (err != PICL_SUCCESS)
200303831d35Sstevel return (err);
200403831d35Sstevel return (err);
200503831d35Sstevel }
200603831d35Sstevel
200703831d35Sstevel static void
picldiag_display_io_cards(struct io_card * list)200803831d35Sstevel picldiag_display_io_cards(struct io_card *list)
200903831d35Sstevel {
201003831d35Sstevel static int banner = 0; /* Have we printed the column headings? */
201103831d35Sstevel struct io_card *p;
201203831d35Sstevel
201303831d35Sstevel if (list == NULL)
201403831d35Sstevel return;
201503831d35Sstevel
201603831d35Sstevel if (banner == 0) {
201703831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
201803831d35Sstevel "Bus Freq Slot + Name +\n"), 0);
201903831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "Type MHz Status "
2020*2983dda7SMichael Bergknoff "Path "
2021*2983dda7SMichael Bergknoff "Model"), 0);
202203831d35Sstevel log_printf("\n", 0);
202303831d35Sstevel log_printf("---- ---- ---------- "
2024*2983dda7SMichael Bergknoff "---------------------------- "
2025*2983dda7SMichael Bergknoff "--------------------", 0);
202603831d35Sstevel log_printf("\n", 0);
202703831d35Sstevel banner = 1;
202803831d35Sstevel }
202903831d35Sstevel
203003831d35Sstevel for (p = list; p != NULL; p = p -> next) {
203103831d35Sstevel log_printf("%-4s ", p->bus_type, 0);
203203831d35Sstevel log_printf("%3d ", p->freq, 0);
203303831d35Sstevel /*
203403831d35Sstevel * We check to see if it's an int or
203503831d35Sstevel * a char string to display for slot.
203603831d35Sstevel */
203703831d35Sstevel if (p->slot == PCI_SLOT_IS_STRING)
203803831d35Sstevel log_printf("%10s ", p->slot_str, 0);
203903831d35Sstevel else
204003831d35Sstevel log_printf("%10d ", p->slot, 0);
204103831d35Sstevel
204203831d35Sstevel log_printf("%-28.28s", p->name, 0);
204303831d35Sstevel if (strlen(p->name) > 28)
204403831d35Sstevel log_printf("+ ", 0);
204503831d35Sstevel else
204603831d35Sstevel log_printf(" ", 0);
204703831d35Sstevel log_printf("%-19.19s", p->model, 0);
204803831d35Sstevel if (strlen(p->model) > 19)
204903831d35Sstevel log_printf("+", 0);
205003831d35Sstevel log_printf("\n", 0);
205103831d35Sstevel log_printf(" %10s ", p->status, 0);
205203831d35Sstevel if (strlen(p->notes) > 0)
205303831d35Sstevel log_printf("%s", p->notes, 0);
205403831d35Sstevel log_printf("\n\n", 0);
205503831d35Sstevel }
205603831d35Sstevel }
205703831d35Sstevel
205803831d35Sstevel /*
205903831d35Sstevel * display all io devices
206003831d35Sstevel */
206103831d35Sstevel static int
display_io_device_info(picl_nodehdl_t plafh)206203831d35Sstevel display_io_device_info(picl_nodehdl_t plafh)
206303831d35Sstevel {
206403831d35Sstevel int err;
206503831d35Sstevel
206603831d35Sstevel err = gather_io_cards(plafh);
206703831d35Sstevel if (err != PICL_SUCCESS)
206803831d35Sstevel return (err);
206903831d35Sstevel
207003831d35Sstevel logprintf_header(dgettext(TEXT_DOMAIN, "IO Devices"),
207103831d35Sstevel DEFAULT_LINE_WIDTH);
207203831d35Sstevel
207303831d35Sstevel picldiag_display_io_cards(io_card_list);
207403831d35Sstevel
207503831d35Sstevel free_io_cards(io_card_list);
207603831d35Sstevel
207703831d35Sstevel return (PICL_SUCCESS);
207803831d35Sstevel }
207903831d35Sstevel
208003831d35Sstevel /*
208103831d35Sstevel * print fan device information
208203831d35Sstevel */
208303831d35Sstevel static int
logprintf_fan_info(picl_nodehdl_t fanh)208403831d35Sstevel logprintf_fan_info(picl_nodehdl_t fanh)
208503831d35Sstevel {
208603831d35Sstevel int err;
208703831d35Sstevel char *label;
208803831d35Sstevel char *unit;
208903831d35Sstevel int64_t speed;
209003831d35Sstevel int64_t min_speed;
209103831d35Sstevel picl_nodehdl_t fruph;
209203831d35Sstevel
209303831d35Sstevel err = picldiag_get_fru_parent(fanh, &fruph);
209403831d35Sstevel if (err != PICL_SUCCESS)
209503831d35Sstevel return (err);
209603831d35Sstevel
209703831d35Sstevel err = picldiag_get_combined_label(fruph, &label, 14);
209803831d35Sstevel if (err != PICL_SUCCESS)
209903831d35Sstevel return (err);
210003831d35Sstevel
210103831d35Sstevel log_printf("%-14s ", label);
210203831d35Sstevel free(label);
210303831d35Sstevel
210403831d35Sstevel err = picldiag_get_label(fanh, &label);
210503831d35Sstevel if (err == PICL_SUCCESS) {
210603831d35Sstevel log_printf("%-14s ", label);
210703831d35Sstevel free(label);
210803831d35Sstevel } else if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) {
210903831d35Sstevel log_printf(" - ");
211003831d35Sstevel } else
211103831d35Sstevel return (err);
211203831d35Sstevel
211303831d35Sstevel speed = picldiag_get_uint_propval(fanh, PICL_PROP_FAN_SPEED, &err);
211403831d35Sstevel if (err == PICL_SUCCESS) {
211503831d35Sstevel min_speed = picldiag_get_uint_propval(fanh,
211603831d35Sstevel PICL_PROP_LOW_WARNING_THRESHOLD, &err);
211703831d35Sstevel if (err != PICL_SUCCESS)
211803831d35Sstevel min_speed = 0;
211903831d35Sstevel if (speed < min_speed) {
212003831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
212103831d35Sstevel "failed (%lld"), speed);
212203831d35Sstevel err = picldiag_get_string_propval(fanh,
212303831d35Sstevel PICL_PROP_FAN_SPEED_UNIT, &unit);
212403831d35Sstevel if (err == PICL_SUCCESS) {
212503831d35Sstevel log_printf("%s", unit);
212603831d35Sstevel free(unit);
212703831d35Sstevel }
212803831d35Sstevel log_printf(")");
212903831d35Sstevel } else {
213003831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "okay"));
213103831d35Sstevel }
213203831d35Sstevel } else {
213303831d35Sstevel err = picldiag_get_string_propval(fanh,
213403831d35Sstevel PICL_PROP_FAN_SPEED_UNIT, &unit);
213503831d35Sstevel if (err == PICL_SUCCESS) {
213603831d35Sstevel log_printf("%-12s ", unit);
213703831d35Sstevel free(unit);
213803831d35Sstevel }
213903831d35Sstevel }
214003831d35Sstevel
214103831d35Sstevel log_printf("\n");
214203831d35Sstevel return (PICL_SUCCESS);
214303831d35Sstevel }
214403831d35Sstevel
214503831d35Sstevel static int
fan_callback(picl_nodehdl_t fanh,void * arg)214603831d35Sstevel fan_callback(picl_nodehdl_t fanh, void *arg)
214703831d35Sstevel {
214803831d35Sstevel int *countp = arg;
214903831d35Sstevel int err;
215003831d35Sstevel
215103831d35Sstevel if (*countp == 0) {
215203831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "Fan Status:\n"));
215303831d35Sstevel log_printf("---------------------------------------\n");
215403831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
215503831d35Sstevel "Location Sensor Status \n"));
215603831d35Sstevel log_printf("---------------------------------------\n");
215703831d35Sstevel }
215803831d35Sstevel *countp += 1;
215903831d35Sstevel err = logprintf_fan_info(fanh);
216003831d35Sstevel if (err == PICL_SUCCESS)
216103831d35Sstevel return (PICL_WALK_CONTINUE);
216203831d35Sstevel return (err);
216303831d35Sstevel }
216403831d35Sstevel
216503831d35Sstevel /*
216603831d35Sstevel * callback function search children to find fan device and print its speed
216703831d35Sstevel */
216803831d35Sstevel static int
display_fan_speed(picl_nodehdl_t plafh)216903831d35Sstevel display_fan_speed(picl_nodehdl_t plafh)
217003831d35Sstevel {
217103831d35Sstevel int err;
217203831d35Sstevel int print_header;
217303831d35Sstevel
217403831d35Sstevel print_header = 0;
217503831d35Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_FAN,
217603831d35Sstevel &print_header, fan_callback);
217703831d35Sstevel return (err);
217803831d35Sstevel }
217903831d35Sstevel
218003831d35Sstevel /*
218103831d35Sstevel * print temperature sensor information
218203831d35Sstevel */
218303831d35Sstevel static int
logprintf_temp_info(picl_nodehdl_t temph)218403831d35Sstevel logprintf_temp_info(picl_nodehdl_t temph)
218503831d35Sstevel {
218603831d35Sstevel int err;
218703831d35Sstevel char *label;
218803831d35Sstevel int64_t temperature;
218903831d35Sstevel int64_t threshold;
219003831d35Sstevel picl_nodehdl_t fruph;
219103831d35Sstevel char *status = "unknown";
219203831d35Sstevel int got_temp = 0;
219303831d35Sstevel
219403831d35Sstevel err = picldiag_get_fru_parent(temph, &fruph);
219503831d35Sstevel if (err != PICL_SUCCESS)
219603831d35Sstevel return (err);
219703831d35Sstevel
219803831d35Sstevel err = picldiag_get_combined_label(fruph, &label, 14);
219903831d35Sstevel if (err != PICL_SUCCESS)
220003831d35Sstevel return (err);
220103831d35Sstevel
220203831d35Sstevel log_printf("%-14s ", label);
220303831d35Sstevel free(label);
220403831d35Sstevel
220503831d35Sstevel err = picldiag_get_label(temph, &label);
220603831d35Sstevel if (err != PICL_SUCCESS)
220703831d35Sstevel return (err);
220803831d35Sstevel log_printf("%-14s ", label);
220903831d35Sstevel free(label);
221003831d35Sstevel
221103831d35Sstevel temperature = picldiag_get_int_propval(temph, PICL_PROP_TEMPERATURE,
221203831d35Sstevel &err);
221303831d35Sstevel if (err == PICL_SUCCESS) {
221403831d35Sstevel got_temp = 1;
221503831d35Sstevel status = "okay";
221603831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
221703831d35Sstevel return (err);
221803831d35Sstevel }
221903831d35Sstevel
222003831d35Sstevel threshold = picldiag_get_int_propval(temph, PICL_PROP_LOW_WARNING,
222103831d35Sstevel &err);
222203831d35Sstevel if (err == PICL_SUCCESS) {
222303831d35Sstevel if (got_temp && temperature < threshold)
222403831d35Sstevel status = "warning";
222503831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
222603831d35Sstevel return (err);
222703831d35Sstevel }
222803831d35Sstevel
222903831d35Sstevel threshold = picldiag_get_int_propval(temph, PICL_PROP_LOW_SHUTDOWN,
223003831d35Sstevel &err);
223103831d35Sstevel if (err == PICL_SUCCESS) {
223203831d35Sstevel if (got_temp && temperature < threshold)
223303831d35Sstevel status = "failed";
223403831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
223503831d35Sstevel return (err);
223603831d35Sstevel }
223703831d35Sstevel
223803831d35Sstevel threshold = picldiag_get_int_propval(temph, PICL_PROP_HIGH_WARNING,
223903831d35Sstevel &err);
224003831d35Sstevel if (err == PICL_SUCCESS) {
224103831d35Sstevel if (got_temp && temperature > threshold)
224203831d35Sstevel status = "warning";
224303831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
224403831d35Sstevel return (err);
224503831d35Sstevel }
224603831d35Sstevel
224703831d35Sstevel threshold = picldiag_get_int_propval(temph, PICL_PROP_HIGH_SHUTDOWN,
224803831d35Sstevel &err);
224903831d35Sstevel if (err == PICL_SUCCESS) {
225003831d35Sstevel if (got_temp && temperature > threshold)
225103831d35Sstevel status = "failed";
225203831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
225303831d35Sstevel return (err);
225403831d35Sstevel }
225503831d35Sstevel
225603831d35Sstevel err = picldiag_get_string_propval(temph, PICL_PROP_CONDITION, &status);
225703831d35Sstevel if (err == PICL_SUCCESS) {
225803831d35Sstevel log_printf("%s", status);
225903831d35Sstevel free(status);
226003831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
226103831d35Sstevel return (err);
226203831d35Sstevel } else {
226303831d35Sstevel log_printf("%s ", status);
226403831d35Sstevel if (strcmp(status, "failed") == 0 ||
226503831d35Sstevel strcmp(status, "warning") == 0)
226603831d35Sstevel log_printf("(%.2lldC)", temperature);
226703831d35Sstevel }
226803831d35Sstevel
226903831d35Sstevel log_printf("\n");
227003831d35Sstevel return (PICL_SUCCESS);
227103831d35Sstevel }
227203831d35Sstevel
227303831d35Sstevel static int
temp_callback(picl_nodehdl_t temph,void * arg)227403831d35Sstevel temp_callback(picl_nodehdl_t temph, void *arg)
227503831d35Sstevel {
227603831d35Sstevel int err;
227703831d35Sstevel int *countp = arg;
227803831d35Sstevel
227903831d35Sstevel if (*countp == 0) {
228003831d35Sstevel log_printf("\n");
228103831d35Sstevel log_printf("---------------------------------------\n");
228203831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "Temperature sensors:\n"));
228303831d35Sstevel log_printf("------------------------------------\n");
228403831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
228503831d35Sstevel "Location Sensor Status\n"));
228603831d35Sstevel log_printf("------------------------------------\n");
228703831d35Sstevel }
228803831d35Sstevel *countp += 1;
228903831d35Sstevel err = logprintf_temp_info(temph);
229003831d35Sstevel if (err == PICL_SUCCESS)
229103831d35Sstevel return (PICL_WALK_CONTINUE);
229203831d35Sstevel return (err);
229303831d35Sstevel }
229403831d35Sstevel
229503831d35Sstevel /*
229603831d35Sstevel * callback function search children to find temp sensors and print the temp
229703831d35Sstevel */
229803831d35Sstevel /* ARGSUSED */
229903831d35Sstevel static int
display_temp(picl_nodehdl_t plafh)230003831d35Sstevel display_temp(picl_nodehdl_t plafh)
230103831d35Sstevel {
230203831d35Sstevel int err;
230303831d35Sstevel int print_header;
230403831d35Sstevel
230503831d35Sstevel print_header = 0;
230603831d35Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_TEMPERATURE_SENSOR,
230703831d35Sstevel &print_header, temp_callback);
230803831d35Sstevel if (err != PICL_SUCCESS)
230903831d35Sstevel return (err);
231003831d35Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_TEMPERATURE_INDICATOR,
231103831d35Sstevel &print_header, temp_callback);
231203831d35Sstevel return (err);
231303831d35Sstevel }
231403831d35Sstevel
231503831d35Sstevel /*
231603831d35Sstevel * print current sensor information
231703831d35Sstevel */
231803831d35Sstevel static int
logprintf_current_info(picl_nodehdl_t currenth)231903831d35Sstevel logprintf_current_info(picl_nodehdl_t currenth)
232003831d35Sstevel {
232103831d35Sstevel int err;
232203831d35Sstevel char *label;
232303831d35Sstevel float current;
232403831d35Sstevel float threshold;
232503831d35Sstevel picl_nodehdl_t fruph;
232603831d35Sstevel char *status = "unknown";
232703831d35Sstevel int got_current = 0;
232803831d35Sstevel
232903831d35Sstevel err = picldiag_get_fru_parent(currenth, &fruph);
233003831d35Sstevel if (err != PICL_SUCCESS)
233103831d35Sstevel return (err);
233203831d35Sstevel
233303831d35Sstevel err = picldiag_get_combined_label(fruph, &label, 10);
233403831d35Sstevel if (err != PICL_SUCCESS)
233503831d35Sstevel return (err);
233603831d35Sstevel
233703831d35Sstevel log_printf("%-10s ", label);
233803831d35Sstevel free(label);
233903831d35Sstevel
234003831d35Sstevel err = picldiag_get_label(currenth, &label);
234103831d35Sstevel if (err != PICL_SUCCESS)
234203831d35Sstevel return (err);
234303831d35Sstevel log_printf("%-10s ", label);
234403831d35Sstevel free(label);
234503831d35Sstevel
234603831d35Sstevel current = picldiag_get_float_propval(currenth, PICL_PROP_CURRENT, &err);
234703831d35Sstevel if (err == PICL_SUCCESS) {
234803831d35Sstevel status = "okay";
234903831d35Sstevel got_current = 1;
235003831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
235103831d35Sstevel return (err);
235203831d35Sstevel }
235303831d35Sstevel
235403831d35Sstevel threshold = picldiag_get_float_propval(currenth, PICL_PROP_LOW_WARNING,
235503831d35Sstevel &err);
235603831d35Sstevel if (err == PICL_SUCCESS) {
235703831d35Sstevel if (got_current && current < threshold)
235803831d35Sstevel status = "warning";
235903831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
236003831d35Sstevel return (err);
236103831d35Sstevel }
236203831d35Sstevel
236303831d35Sstevel threshold = picldiag_get_float_propval(currenth, PICL_PROP_LOW_SHUTDOWN,
236403831d35Sstevel &err);
236503831d35Sstevel if (err == PICL_SUCCESS) {
236603831d35Sstevel if (got_current && current < threshold)
236703831d35Sstevel status = "failed";
236803831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
236903831d35Sstevel return (err);
237003831d35Sstevel }
237103831d35Sstevel
237203831d35Sstevel threshold = picldiag_get_float_propval(currenth, PICL_PROP_HIGH_WARNING,
237303831d35Sstevel &err);
237403831d35Sstevel if (err == PICL_SUCCESS) {
237503831d35Sstevel if (got_current && current > threshold)
237603831d35Sstevel status = "warning";
237703831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
237803831d35Sstevel return (err);
237903831d35Sstevel }
238003831d35Sstevel
238103831d35Sstevel threshold = picldiag_get_float_propval(currenth,
238203831d35Sstevel PICL_PROP_HIGH_SHUTDOWN, &err);
238303831d35Sstevel if (err == PICL_SUCCESS) {
238403831d35Sstevel if (got_current && current > threshold)
238503831d35Sstevel status = "failed";
238603831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
238703831d35Sstevel return (err);
238803831d35Sstevel }
238903831d35Sstevel
239003831d35Sstevel err = picldiag_get_string_propval(currenth,
239103831d35Sstevel PICL_PROP_CONDITION, &status);
239203831d35Sstevel if (err == PICL_SUCCESS) {
239303831d35Sstevel log_printf(" %s", status);
239403831d35Sstevel free(status);
239503831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
239603831d35Sstevel return (err);
239703831d35Sstevel } else {
239803831d35Sstevel log_printf("%s ", status);
239903831d35Sstevel if (strcmp(status, "failed") == 0 ||
240003831d35Sstevel strcmp(status, "warning") == 0)
240103831d35Sstevel log_printf("(%.2fA)", current);
240203831d35Sstevel }
240303831d35Sstevel
240403831d35Sstevel log_printf("\n");
240503831d35Sstevel return (PICL_SUCCESS);
240603831d35Sstevel }
240703831d35Sstevel
240803831d35Sstevel static int
current_callback(picl_nodehdl_t currh,void * arg)240903831d35Sstevel current_callback(picl_nodehdl_t currh, void *arg)
241003831d35Sstevel {
241103831d35Sstevel int err;
241203831d35Sstevel int *countp = arg;
241303831d35Sstevel
241403831d35Sstevel if (*countp == 0) {
241503831d35Sstevel log_printf("------------------------------------\n");
241603831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "Current sensors:\n"));
241703831d35Sstevel log_printf("------------------------------\n");
241803831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
241903831d35Sstevel "Location Sensor Status\n"));
242003831d35Sstevel log_printf("------------------------------\n");
242103831d35Sstevel }
242203831d35Sstevel *countp += 1;
242303831d35Sstevel err = logprintf_current_info(currh);
242403831d35Sstevel if (err == PICL_SUCCESS)
242503831d35Sstevel return (PICL_WALK_CONTINUE);
242603831d35Sstevel return (err);
242703831d35Sstevel }
242803831d35Sstevel
242903831d35Sstevel /*
243003831d35Sstevel * callback function search children to find curr sensors and print the curr
243103831d35Sstevel */
243203831d35Sstevel /* ARGSUSED */
243303831d35Sstevel static int
display_current(picl_nodehdl_t plafh)243403831d35Sstevel display_current(picl_nodehdl_t plafh)
243503831d35Sstevel {
243603831d35Sstevel int err;
243703831d35Sstevel int print_header;
243803831d35Sstevel
243903831d35Sstevel print_header = 0;
244003831d35Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_CURRENT_SENSOR,
244103831d35Sstevel &print_header, current_callback);
244203831d35Sstevel if (err != PICL_SUCCESS)
244303831d35Sstevel return (err);
244403831d35Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_CURRENT_INDICATOR,
244503831d35Sstevel &print_header, current_callback);
244603831d35Sstevel return (err);
244703831d35Sstevel }
244803831d35Sstevel
244903831d35Sstevel /*
245003831d35Sstevel * print voltage sensor information
245103831d35Sstevel */
245203831d35Sstevel static int
logprintf_voltage_info(picl_nodehdl_t voltageh)245303831d35Sstevel logprintf_voltage_info(picl_nodehdl_t voltageh)
245403831d35Sstevel {
245503831d35Sstevel int err;
245603831d35Sstevel char *label;
245703831d35Sstevel float voltage;
245803831d35Sstevel float threshold;
245903831d35Sstevel picl_nodehdl_t fruph;
246003831d35Sstevel char *status = "unknown";
246103831d35Sstevel int got_voltage = 0;
246203831d35Sstevel
246303831d35Sstevel err = picldiag_get_fru_parent(voltageh, &fruph);
246403831d35Sstevel if (err != PICL_SUCCESS)
246503831d35Sstevel return (err);
246603831d35Sstevel
246703831d35Sstevel err = picldiag_get_combined_label(fruph, &label, 10);
246803831d35Sstevel if (err != PICL_SUCCESS)
246903831d35Sstevel return (err);
247003831d35Sstevel
247103831d35Sstevel log_printf("%-10s ", label);
247203831d35Sstevel free(label);
247303831d35Sstevel
247403831d35Sstevel err = picldiag_get_label(voltageh, &label);
247503831d35Sstevel if (err != PICL_SUCCESS)
247603831d35Sstevel return (err);
247703831d35Sstevel log_printf("%-12s ", label);
247803831d35Sstevel free(label);
247903831d35Sstevel
248003831d35Sstevel voltage = picldiag_get_float_propval(voltageh, PICL_PROP_VOLTAGE, &err);
248103831d35Sstevel if (err == PICL_SUCCESS) {
248203831d35Sstevel status = "okay";
248303831d35Sstevel got_voltage = 1;
248403831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
248503831d35Sstevel return (err);
248603831d35Sstevel }
248703831d35Sstevel
248803831d35Sstevel threshold = picldiag_get_float_propval(voltageh, PICL_PROP_LOW_WARNING,
248903831d35Sstevel &err);
249003831d35Sstevel if (err == PICL_SUCCESS) {
249103831d35Sstevel if (got_voltage && voltage < threshold)
249203831d35Sstevel status = "warning";
249303831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
249403831d35Sstevel return (err);
249503831d35Sstevel }
249603831d35Sstevel
249703831d35Sstevel threshold = picldiag_get_float_propval(voltageh, PICL_PROP_LOW_SHUTDOWN,
249803831d35Sstevel &err);
249903831d35Sstevel if (err == PICL_SUCCESS) {
250003831d35Sstevel if (got_voltage && voltage < threshold)
250103831d35Sstevel status = "failed";
250203831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
250303831d35Sstevel return (err);
250403831d35Sstevel }
250503831d35Sstevel
250603831d35Sstevel threshold = picldiag_get_float_propval(voltageh, PICL_PROP_HIGH_WARNING,
250703831d35Sstevel &err);
250803831d35Sstevel if (err == PICL_SUCCESS) {
250903831d35Sstevel if (got_voltage && voltage > threshold)
251003831d35Sstevel status = "warning";
251103831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
251203831d35Sstevel return (err);
251303831d35Sstevel }
251403831d35Sstevel
251503831d35Sstevel threshold = picldiag_get_float_propval(voltageh,
251603831d35Sstevel PICL_PROP_HIGH_SHUTDOWN, &err);
251703831d35Sstevel if (err == PICL_SUCCESS) {
251803831d35Sstevel if (got_voltage && voltage > threshold)
251903831d35Sstevel status = "failed";
252003831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
252103831d35Sstevel return (err);
252203831d35Sstevel }
252303831d35Sstevel
252403831d35Sstevel err = picldiag_get_string_propval(voltageh,
252503831d35Sstevel PICL_PROP_CONDITION, &status);
252603831d35Sstevel if (err == PICL_SUCCESS) {
252703831d35Sstevel log_printf("%s", status);
252803831d35Sstevel free(status);
252903831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
253003831d35Sstevel return (err);
253103831d35Sstevel } else {
253203831d35Sstevel log_printf("%s ", status);
253303831d35Sstevel if (strcmp(status, "warning") == 0 ||
253403831d35Sstevel strcmp(status, "failed") == 0)
253503831d35Sstevel log_printf("(%.2fV)", voltage);
253603831d35Sstevel }
253703831d35Sstevel
253803831d35Sstevel log_printf("\n");
253903831d35Sstevel return (PICL_SUCCESS);
254003831d35Sstevel }
254103831d35Sstevel
254203831d35Sstevel static int
voltage_callback(picl_nodehdl_t voltageh,void * arg)254303831d35Sstevel voltage_callback(picl_nodehdl_t voltageh, void *arg)
254403831d35Sstevel {
254503831d35Sstevel int *countp = arg;
254603831d35Sstevel int err;
254703831d35Sstevel
254803831d35Sstevel if (*countp == 0) {
254903831d35Sstevel log_printf("--------------------------------\n");
255003831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "Voltage sensors:\n"));
255103831d35Sstevel log_printf("-------------------------------\n");
255203831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
255303831d35Sstevel "Location Sensor Status\n"));
255403831d35Sstevel log_printf("-------------------------------\n");
255503831d35Sstevel }
255603831d35Sstevel *countp += 1;
255703831d35Sstevel err = logprintf_voltage_info(voltageh);
255803831d35Sstevel if (err == PICL_SUCCESS)
255903831d35Sstevel return (PICL_WALK_CONTINUE);
256003831d35Sstevel return (err);
256103831d35Sstevel }
256203831d35Sstevel
256303831d35Sstevel /*
256403831d35Sstevel * callback function search children to find voltage sensors and print voltage
256503831d35Sstevel */
256603831d35Sstevel /* ARGSUSED */
256703831d35Sstevel static int
display_voltage(picl_nodehdl_t plafh)256803831d35Sstevel display_voltage(picl_nodehdl_t plafh)
256903831d35Sstevel {
257003831d35Sstevel int err;
257103831d35Sstevel int print_header;
257203831d35Sstevel
257303831d35Sstevel print_header = 0;
257403831d35Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_VOLTAGE_SENSOR,
257503831d35Sstevel &print_header, voltage_callback);
257603831d35Sstevel if (err != PICL_SUCCESS)
257703831d35Sstevel return (err);
257803831d35Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_VOLTAGE_INDICATOR,
257903831d35Sstevel &print_header, voltage_callback);
258003831d35Sstevel return (err);
258103831d35Sstevel }
258203831d35Sstevel
258303831d35Sstevel /*
258403831d35Sstevel * print led device information
258503831d35Sstevel */
258603831d35Sstevel static int
logprintf_led_info(picl_nodehdl_t ledh)258703831d35Sstevel logprintf_led_info(picl_nodehdl_t ledh)
258803831d35Sstevel {
258903831d35Sstevel int err;
259003831d35Sstevel char *label;
259103831d35Sstevel char *state;
259203831d35Sstevel char *color;
259303831d35Sstevel picl_nodehdl_t fruph;
259403831d35Sstevel
259503831d35Sstevel err = picldiag_get_fru_parent(ledh, &fruph);
259603831d35Sstevel if (err != PICL_SUCCESS)
259703831d35Sstevel return (err);
259803831d35Sstevel
259903831d35Sstevel err = picldiag_get_combined_label(fruph, &label, 10);
260003831d35Sstevel if (err != PICL_SUCCESS) {
260103831d35Sstevel log_printf(" - ", label);
260203831d35Sstevel } else {
260303831d35Sstevel log_printf("%-10s ", label);
260403831d35Sstevel free(label);
260503831d35Sstevel }
260603831d35Sstevel
260703831d35Sstevel err = picldiag_get_label(ledh, &label);
260803831d35Sstevel if (err != PICL_SUCCESS)
260903831d35Sstevel return (err);
261003831d35Sstevel log_printf("%-20s ", label);
261103831d35Sstevel free(label);
261203831d35Sstevel
261303831d35Sstevel err = picldiag_get_string_propval(ledh, PICL_PROP_STATE, &state);
261403831d35Sstevel if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) {
261503831d35Sstevel log_printf(" - ");
261603831d35Sstevel } else if (err != PICL_SUCCESS) {
261703831d35Sstevel return (err);
261803831d35Sstevel } else {
261903831d35Sstevel log_printf("%-10s ", state);
262003831d35Sstevel free(state);
262103831d35Sstevel }
262203831d35Sstevel
262303831d35Sstevel err = picldiag_get_string_propval(ledh, PICL_PROP_COLOR, &color);
262403831d35Sstevel if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) {
262503831d35Sstevel log_printf("\n");
262603831d35Sstevel } else if (err != PICL_SUCCESS) {
262703831d35Sstevel return (err);
262803831d35Sstevel } else {
262903831d35Sstevel log_printf("%-16s\n", color);
263003831d35Sstevel free(color);
263103831d35Sstevel }
263203831d35Sstevel
263303831d35Sstevel return (PICL_SUCCESS);
263403831d35Sstevel }
263503831d35Sstevel
263603831d35Sstevel static int
led_callback(picl_nodehdl_t ledh,void * arg)263703831d35Sstevel led_callback(picl_nodehdl_t ledh, void *arg)
263803831d35Sstevel {
263903831d35Sstevel int *countp = arg;
264003831d35Sstevel int err;
264103831d35Sstevel
264203831d35Sstevel if (*countp == 0) {
264303831d35Sstevel
264403831d35Sstevel log_printf("--------------------------------------"
264503831d35Sstevel "------------\n");
264603831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "Led State:\n"));
264703831d35Sstevel log_printf("--------------------------------------"
264803831d35Sstevel "------------\n");
264903831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
265003831d35Sstevel "Location Led State"
265103831d35Sstevel " Color\n"));
265203831d35Sstevel log_printf("--------------------------------------"
265303831d35Sstevel "------------\n");
265403831d35Sstevel }
265503831d35Sstevel *countp += 1;
265603831d35Sstevel err = logprintf_led_info(ledh);
265703831d35Sstevel if (err == PICL_SUCCESS)
265803831d35Sstevel return (PICL_WALK_CONTINUE);
265903831d35Sstevel return (err);
266003831d35Sstevel }
266103831d35Sstevel
266203831d35Sstevel /*
266303831d35Sstevel * callback function search children to find led devices and print status
266403831d35Sstevel */
266503831d35Sstevel /* ARGSUSED */
266603831d35Sstevel static int
display_led_status(picl_nodehdl_t plafh)266703831d35Sstevel display_led_status(picl_nodehdl_t plafh)
266803831d35Sstevel {
266903831d35Sstevel int print_header;
267003831d35Sstevel
267103831d35Sstevel print_header = 0;
267203831d35Sstevel picl_walk_tree_by_class(plafh, PICL_CLASS_LED,
267303831d35Sstevel &print_header, led_callback);
267403831d35Sstevel return (PICL_SUCCESS);
267503831d35Sstevel }
267603831d35Sstevel
267703831d35Sstevel /*
267803831d35Sstevel * print keyswitch device information
267903831d35Sstevel */
268003831d35Sstevel static int
logprintf_keyswitch_info(picl_nodehdl_t keyswitchh,picl_nodehdl_t fruph)268103831d35Sstevel logprintf_keyswitch_info(picl_nodehdl_t keyswitchh, picl_nodehdl_t fruph)
268203831d35Sstevel {
268303831d35Sstevel int err;
268403831d35Sstevel char *label;
268503831d35Sstevel char *state;
268603831d35Sstevel
268703831d35Sstevel err = picldiag_get_combined_label(fruph, &label, 10);
268803831d35Sstevel if (err != PICL_SUCCESS) {
268903831d35Sstevel log_printf("%-14s", " -");
269003831d35Sstevel } else {
269103831d35Sstevel log_printf("%-14s ", label);
269203831d35Sstevel free(label);
269303831d35Sstevel }
269403831d35Sstevel
269503831d35Sstevel err = picldiag_get_label(keyswitchh, &label);
269603831d35Sstevel if (err != PICL_SUCCESS)
269703831d35Sstevel return (err);
269803831d35Sstevel log_printf("%-11s ", label);
269903831d35Sstevel free(label);
270003831d35Sstevel
270103831d35Sstevel err = picldiag_get_string_propval(keyswitchh, PICL_PROP_STATE, &state);
270203831d35Sstevel if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) {
270303831d35Sstevel log_printf(" -\n");
270403831d35Sstevel } else if (err != PICL_SUCCESS) {
270503831d35Sstevel return (err);
270603831d35Sstevel } else {
270703831d35Sstevel log_printf("%s\n", state);
270803831d35Sstevel free(state);
270903831d35Sstevel }
271003831d35Sstevel
271103831d35Sstevel return (PICL_SUCCESS);
271203831d35Sstevel }
271303831d35Sstevel
271403831d35Sstevel static int
keyswitch_callback(picl_nodehdl_t keyswitchh,void * arg)271503831d35Sstevel keyswitch_callback(picl_nodehdl_t keyswitchh, void *arg)
271603831d35Sstevel {
271703831d35Sstevel int *countp = arg;
271803831d35Sstevel int err;
271903831d35Sstevel picl_nodehdl_t fruph;
272003831d35Sstevel
272103831d35Sstevel /*
272203831d35Sstevel * Tamale simulates a key-switch on ENxS. So the presence of a
272303831d35Sstevel * node of class keyswitch is not sufficient. If it has a fru parent
272403831d35Sstevel * or location parent, then believe it.
272503831d35Sstevel */
272603831d35Sstevel err = picl_get_propval_by_name(keyswitchh, PICL_REFPROP_FRU_PARENT,
272703831d35Sstevel &fruph, sizeof (fruph));
272803831d35Sstevel if (err == PICL_PROPNOTFOUND) {
272903831d35Sstevel err = picl_get_propval_by_name(keyswitchh,
273003831d35Sstevel PICL_REFPROP_LOC_PARENT, &fruph, sizeof (fruph));
273103831d35Sstevel }
273203831d35Sstevel if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE)
273303831d35Sstevel return (PICL_WALK_CONTINUE);
273403831d35Sstevel if (err != PICL_SUCCESS)
273503831d35Sstevel return (err);
273603831d35Sstevel
273703831d35Sstevel if (*countp == 0) {
273803831d35Sstevel log_printf("-----------------------------------------\n");
273903831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "Keyswitch:\n"));
274003831d35Sstevel log_printf("-----------------------------------------\n");
274103831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
274203831d35Sstevel "Location Keyswitch State\n"));
274303831d35Sstevel log_printf("-----------------------------------------\n");
274403831d35Sstevel }
274503831d35Sstevel *countp += 1;
274603831d35Sstevel err = logprintf_keyswitch_info(keyswitchh, fruph);
274703831d35Sstevel if (err == PICL_SUCCESS)
274803831d35Sstevel return (PICL_WALK_CONTINUE);
274903831d35Sstevel return (err);
275003831d35Sstevel }
275103831d35Sstevel
275203831d35Sstevel /*
275303831d35Sstevel * search children to find keyswitch device(s) and print status
275403831d35Sstevel */
275503831d35Sstevel /* ARGSUSED */
275603831d35Sstevel static int
display_keyswitch(picl_nodehdl_t plafh)275703831d35Sstevel display_keyswitch(picl_nodehdl_t plafh)
275803831d35Sstevel {
275903831d35Sstevel int print_header = 0;
276003831d35Sstevel
276103831d35Sstevel picl_walk_tree_by_class(plafh, PICL_CLASS_KEYSWITCH,
276203831d35Sstevel &print_header, keyswitch_callback);
276303831d35Sstevel return (PICL_SUCCESS);
276403831d35Sstevel }
276503831d35Sstevel
276603831d35Sstevel /*
276703831d35Sstevel * display environment status
276803831d35Sstevel */
276903831d35Sstevel static int
display_envctrl_status(picl_nodehdl_t plafh)277003831d35Sstevel display_envctrl_status(picl_nodehdl_t plafh)
277103831d35Sstevel {
277203831d35Sstevel logprintf_header(dgettext(TEXT_DOMAIN, "Environmental Status"),
277303831d35Sstevel DEFAULT_LINE_WIDTH);
277403831d35Sstevel
277503831d35Sstevel display_fan_speed(plafh);
277603831d35Sstevel display_temp(plafh);
277703831d35Sstevel display_current(plafh);
277803831d35Sstevel display_voltage(plafh);
277903831d35Sstevel display_keyswitch(plafh);
278003831d35Sstevel display_led_status(plafh);
278103831d35Sstevel
278203831d35Sstevel return (PICL_SUCCESS);
278303831d35Sstevel }
278403831d35Sstevel
278503831d35Sstevel /*
278603831d35Sstevel * print fru operational status
278703831d35Sstevel */
278803831d35Sstevel static int
logprintf_fru_oper_status(picl_nodehdl_t fruh,int * countp)278903831d35Sstevel logprintf_fru_oper_status(picl_nodehdl_t fruh, int *countp)
279003831d35Sstevel {
279103831d35Sstevel int err;
279203831d35Sstevel char *label;
279303831d35Sstevel char *status;
279403831d35Sstevel
279503831d35Sstevel err = picldiag_get_combined_label(fruh, &label, 15);
279603831d35Sstevel if (err != PICL_SUCCESS)
279703831d35Sstevel return (PICL_WALK_CONTINUE);
279803831d35Sstevel
279903831d35Sstevel err = picldiag_get_string_propval(fruh,
280003831d35Sstevel PICL_PROP_OPERATIONAL_STATUS, &status);
280103831d35Sstevel if (err == PICL_SUCCESS) {
280203831d35Sstevel if (*countp == 0) {
280303831d35Sstevel logprintf_header(dgettext(TEXT_DOMAIN,
280403831d35Sstevel "FRU Operational Status"),
280503831d35Sstevel DEFAULT_LINE_WIDTH);
280603831d35Sstevel log_printf("-------------------------\n");
280703831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
280803831d35Sstevel "Fru Operational Status:\n"));
280903831d35Sstevel log_printf("-------------------------\n");
281003831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
281103831d35Sstevel "Location Status \n"));
281203831d35Sstevel log_printf("-------------------------\n");
281303831d35Sstevel }
281403831d35Sstevel *countp += 1;
281503831d35Sstevel log_printf("%-15s ", label);
281603831d35Sstevel free(label);
281703831d35Sstevel log_printf("%s\n", status);
281803831d35Sstevel free(status);
281903831d35Sstevel } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
282003831d35Sstevel free(label);
282103831d35Sstevel return (err);
282203831d35Sstevel } else {
282303831d35Sstevel free(label);
282403831d35Sstevel }
282503831d35Sstevel return (PICL_WALK_CONTINUE);
282603831d35Sstevel }
282703831d35Sstevel
282803831d35Sstevel static int
fru_oper_status_callback(picl_nodehdl_t fruh,void * arg)282903831d35Sstevel fru_oper_status_callback(picl_nodehdl_t fruh, void *arg)
283003831d35Sstevel {
283103831d35Sstevel int err;
283203831d35Sstevel
283303831d35Sstevel err = logprintf_fru_oper_status(fruh, (int *)arg);
283403831d35Sstevel return (err);
283503831d35Sstevel }
283603831d35Sstevel
283703831d35Sstevel /*
283803831d35Sstevel * display fru operational status
283903831d35Sstevel */
284003831d35Sstevel static int
display_fru_oper_status(picl_nodehdl_t frutreeh)284103831d35Sstevel display_fru_oper_status(picl_nodehdl_t frutreeh)
284203831d35Sstevel {
284303831d35Sstevel int print_header;
284403831d35Sstevel
284503831d35Sstevel print_header = 0;
284603831d35Sstevel picl_walk_tree_by_class(frutreeh, PICL_CLASS_FRU,
284703831d35Sstevel &print_header, fru_oper_status_callback);
284803831d35Sstevel return (PICL_SUCCESS);
284903831d35Sstevel }
285003831d35Sstevel
285103831d35Sstevel /*
285203831d35Sstevel * check if the node having the version prop
285303831d35Sstevel * If yes, print its nodename and version
285403831d35Sstevel */
285503831d35Sstevel /* ARGSUSED */
285603831d35Sstevel static int
asicrev_callback(picl_nodehdl_t nodeh,void * arg)285703831d35Sstevel asicrev_callback(picl_nodehdl_t nodeh, void *arg)
285803831d35Sstevel {
285903831d35Sstevel uint32_t version;
286003831d35Sstevel char *name;
286103831d35Sstevel char *model;
286203831d35Sstevel char *status;
286303831d35Sstevel int err;
286403831d35Sstevel
286503831d35Sstevel version = picldiag_get_uint_propval(nodeh, OBP_PROP_VERSION_NUM,
286603831d35Sstevel &err);
286703831d35Sstevel if (err == PICL_PROPNOTFOUND)
286803831d35Sstevel return (PICL_WALK_CONTINUE);
286903831d35Sstevel else if (err != PICL_SUCCESS)
287003831d35Sstevel return (err);
287103831d35Sstevel
287203831d35Sstevel /* devfs-path */
287303831d35Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_DEVFS_PATH, &name);
287403831d35Sstevel if (err == PICL_PROPNOTFOUND)
287503831d35Sstevel name = NULL;
287603831d35Sstevel else if (err != PICL_SUCCESS)
287703831d35Sstevel return (err);
287803831d35Sstevel
287903831d35Sstevel /* model */
288003831d35Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_BINDING_NAME,
288103831d35Sstevel &model);
288203831d35Sstevel if (err == PICL_PROPNOTFOUND)
288303831d35Sstevel model = NULL;
288403831d35Sstevel else if (err != PICL_SUCCESS)
288503831d35Sstevel return (err);
288603831d35Sstevel
288703831d35Sstevel /* status */
288803831d35Sstevel err = picldiag_get_string_propval(nodeh, PICL_PROP_STATUS, &status);
288903831d35Sstevel if (err == PICL_PROPNOTFOUND)
289003831d35Sstevel status = NULL;
289103831d35Sstevel else if (err != PICL_SUCCESS)
289203831d35Sstevel return (err);
289303831d35Sstevel
289403831d35Sstevel /*
289503831d35Sstevel * Display the data
289603831d35Sstevel */
289703831d35Sstevel
289803831d35Sstevel /* name */
289903831d35Sstevel if (name != NULL) {
290003831d35Sstevel log_printf("%-22s ", name);
290103831d35Sstevel free(name);
290203831d35Sstevel } else
290303831d35Sstevel log_printf("%-22s ", "unknown");
290403831d35Sstevel /* model */
290503831d35Sstevel if (model != NULL) {
290603831d35Sstevel log_printf("%-15s ", model);
290703831d35Sstevel free(model);
290803831d35Sstevel } else
290903831d35Sstevel log_printf("%-15s ", "unknown");
291003831d35Sstevel /* status */
291103831d35Sstevel if (status == NULL)
291203831d35Sstevel log_printf("%-15s ", "okay");
291303831d35Sstevel else {
291403831d35Sstevel log_printf("%-15s ", status);
291503831d35Sstevel free(status);
291603831d35Sstevel }
291703831d35Sstevel /* revision */
291803831d35Sstevel log_printf(" %-4d\n", version);
291903831d35Sstevel
292003831d35Sstevel return (PICL_WALK_CONTINUE);
292103831d35Sstevel }
292203831d35Sstevel
292303831d35Sstevel /*
292403831d35Sstevel * traverse the tree to display asic revision id for ebus
292503831d35Sstevel */
292603831d35Sstevel /* ARGSUSED */
292703831d35Sstevel static int
ebus_callback(picl_nodehdl_t ebush,void * arg)292803831d35Sstevel ebus_callback(picl_nodehdl_t ebush, void *arg)
292903831d35Sstevel {
293003831d35Sstevel uint32_t id;
293103831d35Sstevel char *name;
293203831d35Sstevel int err;
293303831d35Sstevel char *model;
293403831d35Sstevel char *status;
293503831d35Sstevel
293603831d35Sstevel id = picldiag_get_uint_propval(ebush, OBP_PROP_REVISION_ID, &err);
293703831d35Sstevel if (err == PICL_PROPNOTFOUND)
293803831d35Sstevel return (PICL_WALK_CONTINUE);
293903831d35Sstevel else if (err != PICL_SUCCESS)
294003831d35Sstevel return (err);
294103831d35Sstevel
294203831d35Sstevel /* devfs-path */
294303831d35Sstevel err = picldiag_get_string_propval(ebush, PICL_PROP_DEVFS_PATH, &name);
294403831d35Sstevel if (err == PICL_PROPNOTFOUND)
294503831d35Sstevel name = NULL;
294603831d35Sstevel else if (err != PICL_SUCCESS)
294703831d35Sstevel return (err);
294803831d35Sstevel
294903831d35Sstevel /* model */
295003831d35Sstevel err = picldiag_get_string_propval(ebush, PICL_PROP_BINDING_NAME,
295103831d35Sstevel &model);
295203831d35Sstevel if (err == PICL_PROPNOTFOUND)
295303831d35Sstevel model = NULL;
295403831d35Sstevel else if (err != PICL_SUCCESS)
295503831d35Sstevel return (err);
295603831d35Sstevel
295703831d35Sstevel /* status */
295803831d35Sstevel err = picldiag_get_string_propval(ebush, PICL_PROP_STATUS, &status);
295903831d35Sstevel if (err == PICL_PROPNOTFOUND)
296003831d35Sstevel status = NULL;
296103831d35Sstevel else if (err != PICL_SUCCESS)
296203831d35Sstevel return (err);
296303831d35Sstevel
296403831d35Sstevel /*
296503831d35Sstevel * Display the data
296603831d35Sstevel */
296703831d35Sstevel
296803831d35Sstevel /* name */
296903831d35Sstevel if (name != NULL) {
297003831d35Sstevel log_printf("%-22s ", name);
297103831d35Sstevel free(name);
297203831d35Sstevel } else
297303831d35Sstevel log_printf("%-22s ", "unknown");
297403831d35Sstevel /* model */
297503831d35Sstevel if (model != NULL) {
297603831d35Sstevel log_printf("%-15s ", model);
297703831d35Sstevel free(model);
297803831d35Sstevel } else
297903831d35Sstevel log_printf("%-15s ", "unknown");
298003831d35Sstevel /* status */
298103831d35Sstevel if (status == NULL)
298203831d35Sstevel log_printf("%-15s ", "okay");
298303831d35Sstevel else {
298403831d35Sstevel log_printf("%-15s ", status);
298503831d35Sstevel free(status);
298603831d35Sstevel }
298703831d35Sstevel /* revision */
298803831d35Sstevel log_printf(" %-4d\n", id);
298903831d35Sstevel
299003831d35Sstevel return (PICL_WALK_CONTINUE);
299103831d35Sstevel }
299203831d35Sstevel
299303831d35Sstevel /*
299403831d35Sstevel * display asic revision id
299503831d35Sstevel */
299603831d35Sstevel static int
display_hw_revisions(picl_nodehdl_t plafh)299703831d35Sstevel display_hw_revisions(picl_nodehdl_t plafh)
299803831d35Sstevel {
299903831d35Sstevel int err;
300003831d35Sstevel
300103831d35Sstevel /* Print the header */
300203831d35Sstevel logprintf_header(dgettext(TEXT_DOMAIN, "HW Revisions"),
300303831d35Sstevel DEFAULT_LINE_WIDTH);
300403831d35Sstevel
300503831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "ASIC Revisions:\n"));
300603831d35Sstevel log_printf("-----------------------------");
300703831d35Sstevel log_printf("--------------------------------------\n");
300803831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "Path Device"));
300903831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
301003831d35Sstevel " Status Revision\n"));
301103831d35Sstevel log_printf("-----------------------------");
301203831d35Sstevel log_printf("--------------------------------------\n");
301303831d35Sstevel
301403831d35Sstevel err = picl_walk_tree_by_class(plafh, NULL, NULL, asicrev_callback);
301503831d35Sstevel if (err != PICL_SUCCESS)
301603831d35Sstevel return (err);
301703831d35Sstevel
301803831d35Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_EBUS,
301903831d35Sstevel NULL, ebus_callback);
302003831d35Sstevel if (err != PICL_SUCCESS)
302103831d35Sstevel return (err);
302203831d35Sstevel
302303831d35Sstevel log_printf("\n");
302403831d35Sstevel
302503831d35Sstevel return (err);
302603831d35Sstevel }
302703831d35Sstevel
302803831d35Sstevel /*
302903831d35Sstevel * find the options node and its powerfail_time prop
303003831d35Sstevel * If found, display the list of latest powerfail.
303103831d35Sstevel */
303203831d35Sstevel /* ARGSUSED */
303303831d35Sstevel static int
options_callback(picl_nodehdl_t nodeh,void * arg)303403831d35Sstevel options_callback(picl_nodehdl_t nodeh, void *arg)
303503831d35Sstevel {
303603831d35Sstevel time_t value;
303703831d35Sstevel char *failtime;
303803831d35Sstevel int err;
303903831d35Sstevel
304003831d35Sstevel err = picldiag_get_string_propval(nodeh, PROP_POWERFAIL_TIME,
304103831d35Sstevel &failtime);
304203831d35Sstevel if (err == PICL_PROPNOTFOUND)
304303831d35Sstevel return (PICL_WALK_TERMINATE);
304403831d35Sstevel else if (err != PICL_SUCCESS)
304503831d35Sstevel return (err);
304603831d35Sstevel
304703831d35Sstevel value = (time_t)atoi(failtime);
304803831d35Sstevel free(failtime);
304903831d35Sstevel if (value == 0)
305003831d35Sstevel return (PICL_WALK_TERMINATE);
305103831d35Sstevel
305203831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "Most recent AC Power Failure:\n"));
305303831d35Sstevel log_printf("=============================\n");
305403831d35Sstevel log_printf("%s", ctime(&value));
305503831d35Sstevel log_printf("\n");
305603831d35Sstevel return (PICL_WALK_TERMINATE);
305703831d35Sstevel }
305803831d35Sstevel
305903831d35Sstevel /*
306003831d35Sstevel * display the OBP and POST prom revisions
306103831d35Sstevel */
306203831d35Sstevel /* ARGSUSED */
306303831d35Sstevel static int
flashprom_callback(picl_nodehdl_t flashpromh,void * arg)306403831d35Sstevel flashprom_callback(picl_nodehdl_t flashpromh, void *arg)
306503831d35Sstevel {
306603831d35Sstevel picl_prophdl_t proph;
306703831d35Sstevel picl_prophdl_t tblh;
306803831d35Sstevel picl_prophdl_t rowproph;
306903831d35Sstevel picl_propinfo_t pinfo;
307003831d35Sstevel char *prom_version = NULL;
307103831d35Sstevel char *obp_version = NULL;
307203831d35Sstevel int err;
307303831d35Sstevel
307403831d35Sstevel err = picl_get_propinfo_by_name(flashpromh, OBP_PROP_VERSION,
307503831d35Sstevel &pinfo, &proph);
307603831d35Sstevel if (err == PICL_PROPNOTFOUND)
307703831d35Sstevel return (PICL_WALK_TERMINATE);
307803831d35Sstevel else if (err != PICL_SUCCESS)
307903831d35Sstevel return (err);
308003831d35Sstevel
308103831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "System PROM revisions:\n"));
308203831d35Sstevel log_printf("----------------------\n");
308303831d35Sstevel
308403831d35Sstevel /*
308503831d35Sstevel * If it's a table prop, the first element is OBP revision
308603831d35Sstevel * The second one is POST revision.
308703831d35Sstevel * If it's a charstring prop, the value will be only OBP revision
308803831d35Sstevel */
308903831d35Sstevel if (pinfo.type == PICL_PTYPE_CHARSTRING) {
309003831d35Sstevel prom_version = alloca(pinfo.size);
309103831d35Sstevel if (prom_version == NULL)
309203831d35Sstevel return (PICL_FAILURE);
309303831d35Sstevel err = picl_get_propval(proph, prom_version, pinfo.size);
309403831d35Sstevel if (err != PICL_SUCCESS)
309503831d35Sstevel return (err);
309603831d35Sstevel log_printf("%s\n", prom_version);
309703831d35Sstevel }
309803831d35Sstevel
309903831d35Sstevel if (pinfo.type != PICL_PTYPE_TABLE) /* not supported type */
310003831d35Sstevel return (PICL_WALK_TERMINATE);
310103831d35Sstevel
310203831d35Sstevel err = picl_get_propval(proph, &tblh, pinfo.size);
310303831d35Sstevel if (err != PICL_SUCCESS)
310403831d35Sstevel return (err);
310503831d35Sstevel
310603831d35Sstevel err = picl_get_next_by_row(tblh, &rowproph);
310703831d35Sstevel if (err == PICL_SUCCESS) {
310803831d35Sstevel /* get first row */
310903831d35Sstevel err = picl_get_propinfo(rowproph, &pinfo);
311003831d35Sstevel if (err != PICL_SUCCESS)
3111*2983dda7SMichael Bergknoff return (err);
311203831d35Sstevel
311303831d35Sstevel prom_version = alloca(pinfo.size);
311403831d35Sstevel if (prom_version == NULL)
311503831d35Sstevel return (PICL_FAILURE);
311603831d35Sstevel
311703831d35Sstevel err = picl_get_propval(rowproph, prom_version, pinfo.size);
311803831d35Sstevel if (err != PICL_SUCCESS)
311903831d35Sstevel return (err);
312003831d35Sstevel log_printf("%s\n", prom_version);
312103831d35Sstevel
312203831d35Sstevel /* get second row */
312303831d35Sstevel err = picl_get_next_by_col(rowproph, &rowproph);
312403831d35Sstevel if (err == PICL_SUCCESS) {
312503831d35Sstevel err = picl_get_propinfo(rowproph, &pinfo);
312603831d35Sstevel if (err != PICL_SUCCESS)
312703831d35Sstevel return (err);
312803831d35Sstevel
312903831d35Sstevel obp_version = alloca(pinfo.size);
313003831d35Sstevel if (obp_version == NULL)
313103831d35Sstevel return (PICL_FAILURE);
313203831d35Sstevel err = picl_get_propval(rowproph, obp_version,
313303831d35Sstevel pinfo.size);
313403831d35Sstevel if (err != PICL_SUCCESS)
313503831d35Sstevel return (err);
313603831d35Sstevel log_printf("%s\n", obp_version);
313703831d35Sstevel }
313803831d35Sstevel }
313903831d35Sstevel
314003831d35Sstevel return (PICL_WALK_TERMINATE);
314103831d35Sstevel }
314203831d35Sstevel
314303831d35Sstevel static int
display_system_info(int serrlog,int log_flag,picl_nodehdl_t rooth)314403831d35Sstevel display_system_info(int serrlog, int log_flag, picl_nodehdl_t rooth)
314503831d35Sstevel {
314603831d35Sstevel int err;
314703831d35Sstevel picl_nodehdl_t plafh;
314803831d35Sstevel picl_nodehdl_t frutreeh;
314903831d35Sstevel
315003831d35Sstevel err = picldiag_get_node_by_name(rooth, PICL_NODE_PLATFORM, &plafh);
315103831d35Sstevel if (err != PICL_SUCCESS)
315203831d35Sstevel return (err);
315303831d35Sstevel
315403831d35Sstevel if (!log_flag) {
315503831d35Sstevel err = display_platform_banner(plafh);
315603831d35Sstevel if (err != PICL_SUCCESS)
315703831d35Sstevel return (err);
315803831d35Sstevel
315903831d35Sstevel err = display_system_clock(plafh);
316003831d35Sstevel if (err != PICL_SUCCESS)
316103831d35Sstevel return (err);
316203831d35Sstevel
316303831d35Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY,
316403831d35Sstevel PICL_CLASS_MEMORY, memory_callback);
316503831d35Sstevel if (err != PICL_SUCCESS)
316603831d35Sstevel return (err);
316703831d35Sstevel
316803831d35Sstevel err = display_cpu_info(plafh);
316903831d35Sstevel if (err != PICL_SUCCESS)
317003831d35Sstevel return (err);
317103831d35Sstevel
317203831d35Sstevel err = display_io_device_info(plafh);
317303831d35Sstevel if (err != PICL_SUCCESS)
317403831d35Sstevel return (err);
317503831d35Sstevel
317603831d35Sstevel err = display_memory_config(plafh);
317703831d35Sstevel if (err != PICL_SUCCESS)
317803831d35Sstevel return (err);
317903831d35Sstevel
318003831d35Sstevel err = display_usb_devices(plafh);
318103831d35Sstevel if (err != PICL_SUCCESS)
318203831d35Sstevel return (err);
318303831d35Sstevel }
318403831d35Sstevel
318503831d35Sstevel if (serrlog) {
318603831d35Sstevel err = picl_walk_tree_by_class(rooth, PICL_CLASS_OPTIONS,
318703831d35Sstevel NULL, options_callback);
318803831d35Sstevel if (err != PICL_SUCCESS)
318903831d35Sstevel return (err);
319003831d35Sstevel
319103831d35Sstevel err = picldiag_get_node_by_name(rooth, PICL_NODE_FRUTREE,
319203831d35Sstevel &frutreeh);
319303831d35Sstevel
319403831d35Sstevel /* return ok if no frutree in picl on schumacher */
319503831d35Sstevel if (err != PICL_SUCCESS)
319603831d35Sstevel return (PICL_SUCCESS);
319703831d35Sstevel
319803831d35Sstevel err = display_fru_oper_status(frutreeh);
319903831d35Sstevel if (err != PICL_SUCCESS)
320003831d35Sstevel return (err);
320103831d35Sstevel
320203831d35Sstevel err = display_hw_revisions(plafh);
320303831d35Sstevel if (err != PICL_SUCCESS)
320403831d35Sstevel return (err);
320503831d35Sstevel
320603831d35Sstevel err = picl_walk_tree_by_class(plafh, PICL_CLASS_FLASHPROM,
320703831d35Sstevel NULL, flashprom_callback);
320803831d35Sstevel if (err != PICL_SUCCESS)
320903831d35Sstevel return (err);
321003831d35Sstevel }
321103831d35Sstevel
321203831d35Sstevel return (PICL_SUCCESS);
321303831d35Sstevel }
321403831d35Sstevel
321503831d35Sstevel /* ARGSUSED */
321603831d35Sstevel int
do_prominfo(int serrlog,char * pgname,int log_flag,int prt_flag)321703831d35Sstevel do_prominfo(int serrlog, char *pgname, int log_flag, int prt_flag)
321803831d35Sstevel {
321903831d35Sstevel int err;
322003831d35Sstevel char *errstr;
322103831d35Sstevel int done;
322203831d35Sstevel picl_nodehdl_t rooth;
322303831d35Sstevel
322403831d35Sstevel err = picl_initialize();
322503831d35Sstevel if (err != PICL_SUCCESS) {
322603831d35Sstevel fprintf(stderr, EM_INIT_FAIL, picl_strerror(err));
322703831d35Sstevel exit(1);
322803831d35Sstevel }
322903831d35Sstevel
323003831d35Sstevel do {
323103831d35Sstevel done = 1;
323203831d35Sstevel err = picl_get_root(&rooth);
323303831d35Sstevel if (err != PICL_SUCCESS) {
323403831d35Sstevel fprintf(stderr, EM_GET_ROOT_FAIL, picl_strerror(err));
323503831d35Sstevel exit(1);
323603831d35Sstevel }
323703831d35Sstevel
323803831d35Sstevel err = display_system_info(serrlog, log_flag, rooth);
323903831d35Sstevel
324003831d35Sstevel if ((err == PICL_STALEHANDLE) || (err == PICL_INVALIDHANDLE))
324103831d35Sstevel done = 0;
324203831d35Sstevel } while (!done);
324303831d35Sstevel
324403831d35Sstevel if (err != PICL_SUCCESS) {
324503831d35Sstevel errstr = picl_strerror(err);
324603831d35Sstevel fprintf(stderr, EM_PRTDIAG_FAIL);
324703831d35Sstevel fprintf(stderr, "%s\n", errstr? errstr : " ");
324803831d35Sstevel }
324903831d35Sstevel
325003831d35Sstevel (void) picl_shutdown();
325103831d35Sstevel
325203831d35Sstevel return (0);
325303831d35Sstevel }
3254