103831d35Sstevel /*
203831d35Sstevel * CDDL HEADER START
303831d35Sstevel *
403831d35Sstevel * The contents of this file are subject to the terms of the
50d63ce2bSvenki * Common Development and Distribution License (the "License").
60d63ce2bSvenki * 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 /*
227ae8c7a8SMichael Bergknoff * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2303831d35Sstevel */
2403831d35Sstevel
2503831d35Sstevel #include <stdio.h>
2603831d35Sstevel #include <stdlib.h>
27dc6ca969Sfw157321 #include <alloca.h>
2803831d35Sstevel #include <unistd.h>
2903831d35Sstevel #include <ctype.h>
3003831d35Sstevel #include <string.h>
3103831d35Sstevel #include <kvm.h>
3203831d35Sstevel #include <varargs.h>
3303831d35Sstevel #include <time.h>
3403831d35Sstevel #include <dirent.h>
3503831d35Sstevel #include <fcntl.h>
3603831d35Sstevel #include <sys/param.h>
3703831d35Sstevel #include <sys/stat.h>
3803831d35Sstevel #include <sys/types.h>
3903831d35Sstevel #include <sys/utsname.h>
4003831d35Sstevel #include <sys/openpromio.h>
4103831d35Sstevel #include <libintl.h>
4203831d35Sstevel #include <syslog.h>
4303831d35Sstevel #include <sys/dkio.h>
440d63ce2bSvenki #include <sys/systeminfo.h>
450d63ce2bSvenki #include <picldefs.h>
46aaba19e2Sfw157321 #include <math.h>
47aaba19e2Sfw157321 #include <errno.h>
4803831d35Sstevel #include "pdevinfo.h"
4903831d35Sstevel #include "display.h"
5003831d35Sstevel #include "display_sun4v.h"
5103831d35Sstevel #include "libprtdiag.h"
5203831d35Sstevel
5303831d35Sstevel #if !defined(TEXT_DOMAIN)
5403831d35Sstevel #define TEXT_DOMAIN "SYS_TEST"
5503831d35Sstevel #endif
5603831d35Sstevel
57a90d965dSfw157321 #define MOTHERBOARD "MB"
580d63ce2bSvenki #define NETWORK "network"
590d63ce2bSvenki #define SUN4V_MACHINE "sun4v"
600d63ce2bSvenki #define PARENT_NAMES 10
610d63ce2bSvenki
620d63ce2bSvenki /*
630d63ce2bSvenki * Additional OBP properties
640d63ce2bSvenki */
650d63ce2bSvenki #define OBP_PROP_COMPATIBLE "compatible"
660d63ce2bSvenki #define OBP_PROP_MODEL "model"
670d63ce2bSvenki #define OBP_PROP_SLOT_NAMES "slot-names"
68dc6ca969Sfw157321 #define OBP_PROP_VERSION "version"
690d63ce2bSvenki
700d63ce2bSvenki #define PICL_NODE_PHYSICAL_PLATFORM "physical-platform"
710d63ce2bSvenki #define PICL_NODE_CHASSIS "chassis"
720d63ce2bSvenki #define MEMORY_SIZE_FIELD 11
730d63ce2bSvenki #define INVALID_THRESHOLD 1000000
740d63ce2bSvenki
750d63ce2bSvenki /*
760d63ce2bSvenki * Additional picl classes
770d63ce2bSvenki */
780d63ce2bSvenki #ifndef PICL_CLASS_SUN4V
790d63ce2bSvenki #define PICL_CLASS_SUN4V "sun4v"
800d63ce2bSvenki #endif
810d63ce2bSvenki
820d63ce2bSvenki #ifndef PICL_PROP_NAC
830d63ce2bSvenki #define PICL_PROP_NAC "nac"
840d63ce2bSvenki #endif
850d63ce2bSvenki
8603831d35Sstevel extern int sys_clk;
870d63ce2bSvenki extern picl_errno_t sun4v_get_node_by_name(picl_nodehdl_t, char *,
880d63ce2bSvenki picl_nodehdl_t *);
890d63ce2bSvenki
900d63ce2bSvenki static picl_nodehdl_t rooth = 0, phyplatformh = 0;
910d63ce2bSvenki static picl_nodehdl_t chassish = 0;
920d63ce2bSvenki static int class_node_found;
930d63ce2bSvenki static int syserrlog;
940d63ce2bSvenki static int all_status_ok;
950d63ce2bSvenki
960d63ce2bSvenki /* local functions */
970d63ce2bSvenki static int sun4v_get_first_compatible_value(picl_nodehdl_t, char **);
980d63ce2bSvenki static void sun4v_display_memory_conf(picl_nodehdl_t);
99d776656fSmb158278 static int sun4v_disp_env_status();
1000d63ce2bSvenki static void sun4v_env_print_fan_sensors();
1010d63ce2bSvenki static void sun4v_env_print_fan_indicators();
1020d63ce2bSvenki static void sun4v_env_print_temp_sensors();
1030d63ce2bSvenki static void sun4v_env_print_temp_indicators();
1040d63ce2bSvenki static void sun4v_env_print_current_sensors();
1050d63ce2bSvenki static void sun4v_env_print_current_indicators();
1060d63ce2bSvenki static void sun4v_env_print_voltage_sensors();
1070d63ce2bSvenki static void sun4v_env_print_voltage_indicators();
1080d63ce2bSvenki static void sun4v_env_print_LEDs();
1090d63ce2bSvenki static void sun4v_print_fru_status();
1108a31bd2bSBirva Shah static int is_fru_absent(picl_nodehdl_t);
1110d63ce2bSvenki static void sun4v_print_fw_rev();
1120d63ce2bSvenki static void sun4v_print_chassis_serial_no();
113dc6ca969Sfw157321 static int openprom_callback(picl_nodehdl_t openpromh, void *arg);
114dc6ca969Sfw157321 static void sun4v_print_openprom_rev();
11503831d35Sstevel
11603831d35Sstevel int
sun4v_display(Sys_tree * tree,Prom_node * root,int log,picl_nodehdl_t plafh)1170d63ce2bSvenki sun4v_display(Sys_tree *tree, Prom_node *root, int log,
11803831d35Sstevel picl_nodehdl_t plafh)
11903831d35Sstevel {
12003831d35Sstevel void *value; /* used for opaque PROM data */
12103831d35Sstevel struct mem_total memory_total; /* Total memory in system */
12203831d35Sstevel struct grp_info grps; /* Info on all groups in system */
1230d63ce2bSvenki char machine[MAXSTRLEN];
124d776656fSmb158278 int exit_code = 0;
1250d63ce2bSvenki
1260d63ce2bSvenki if (sysinfo(SI_MACHINE, machine, sizeof (machine)) == -1)
1270d63ce2bSvenki return (1);
1280d63ce2bSvenki if (strncmp(machine, SUN4V_MACHINE, strlen(SUN4V_MACHINE)) != 0)
1290d63ce2bSvenki return (1);
13003831d35Sstevel
13103831d35Sstevel sys_clk = -1; /* System clock freq. (in MHz) */
13203831d35Sstevel
13303831d35Sstevel /*
13403831d35Sstevel * Now display the machine's configuration. We do this if we
13503831d35Sstevel * are not logging.
13603831d35Sstevel */
13703831d35Sstevel if (!logging) {
13803831d35Sstevel struct utsname uts_buf;
13903831d35Sstevel
14003831d35Sstevel /*
14103831d35Sstevel * Display system banner
14203831d35Sstevel */
14303831d35Sstevel (void) uname(&uts_buf);
14403831d35Sstevel
1450d63ce2bSvenki log_printf(dgettext(TEXT_DOMAIN, "System Configuration: "
146*2983dda7SMichael Bergknoff "Oracle Corporation %s %s\n"), uts_buf.machine,
1470d63ce2bSvenki get_prop_val(find_prop(root, "banner-name")), 0);
14803831d35Sstevel
14903831d35Sstevel /* display system clock frequency */
15003831d35Sstevel value = get_prop_val(find_prop(root, "clock-frequency"));
15103831d35Sstevel if (value != NULL) {
15203831d35Sstevel sys_clk = ((*((int *)value)) + 500000) / 1000000;
15303831d35Sstevel log_printf(dgettext(TEXT_DOMAIN, "System clock "
15403831d35Sstevel "frequency: %d MHz\n"), sys_clk, 0);
15503831d35Sstevel }
15603831d35Sstevel
15703831d35Sstevel /* Display the Memory Size */
15803831d35Sstevel display_memorysize(tree, NULL, &grps, &memory_total);
15903831d35Sstevel
16003831d35Sstevel /* Display the CPU devices */
16103831d35Sstevel sun4v_display_cpu_devices(plafh);
16203831d35Sstevel
16303831d35Sstevel /* Display the Memory configuration */
1640d63ce2bSvenki class_node_found = 0;
1650d63ce2bSvenki sun4v_display_memory_conf(plafh);
16603831d35Sstevel
16703831d35Sstevel /* Display all the IO cards. */
16803831d35Sstevel (void) sun4v_display_pci(plafh);
1690d63ce2bSvenki sun4v_display_diaginfo((log || (logging)), root, plafh);
17003831d35Sstevel
1710d63ce2bSvenki if (picl_get_root(&rooth) != PICL_SUCCESS)
1720d63ce2bSvenki return (1);
173d776656fSmb158278
174d776656fSmb158278 /*
175d776656fSmb158278 * The physical-platform node may be missing on systems with
176d776656fSmb158278 * older firmware so don't consider that an error.
177d776656fSmb158278 */
1780d63ce2bSvenki if (sun4v_get_node_by_name(rooth, PICL_NODE_PHYSICAL_PLATFORM,
1790d63ce2bSvenki &phyplatformh) != PICL_SUCCESS)
180d776656fSmb158278 return (0);
1810d63ce2bSvenki
1820d63ce2bSvenki if (picl_find_node(phyplatformh, PICL_PROP_CLASSNAME,
1830d63ce2bSvenki PICL_PTYPE_CHARSTRING, (void *)PICL_CLASS_CHASSIS,
1840d63ce2bSvenki strlen(PICL_CLASS_CHASSIS), &chassish) != PICL_SUCCESS)
1850d63ce2bSvenki return (1);
1860d63ce2bSvenki
1870d63ce2bSvenki syserrlog = log;
188d776656fSmb158278 exit_code = sun4v_disp_env_status();
1890d63ce2bSvenki }
190d776656fSmb158278 return (exit_code);
19103831d35Sstevel }
19203831d35Sstevel
193db8f0877Sfw157321 /*
194db8f0877Sfw157321 * The binding-name property encodes the bus type.
195db8f0877Sfw157321 */
1960d63ce2bSvenki static void
get_bus_type(picl_nodehdl_t nodeh,struct io_card * card)1970d63ce2bSvenki get_bus_type(picl_nodehdl_t nodeh, struct io_card *card)
1980d63ce2bSvenki {
199db8f0877Sfw157321 char val[PICL_PROPNAMELEN_MAX], *p, *q;
2000d63ce2bSvenki
201db8f0877Sfw157321 card->bus_type[0] = '\0';
202db8f0877Sfw157321
203db8f0877Sfw157321 if (picl_get_propval_by_name(nodeh, PICL_PROP_BINDING_NAME, val,
204db8f0877Sfw157321 sizeof (val)) == PICL_SUCCESS) {
205db8f0877Sfw157321 if (strstr(val, PICL_CLASS_PCIEX))
2064c5e0fdeSvivek (void) strlcpy(card->bus_type, "PCIE",
2074c5e0fdeSvivek sizeof (card->bus_type));
208db8f0877Sfw157321 else if (strstr(val, PICL_CLASS_PCI))
209db8f0877Sfw157321 (void) strlcpy(card->bus_type, "PCIX",
210db8f0877Sfw157321 sizeof (card->bus_type));
211db8f0877Sfw157321 else {
212db8f0877Sfw157321 /*
213db8f0877Sfw157321 * Not perfect: process the binding-name until
214db8f0877Sfw157321 * we encounter something that we don't think would
215db8f0877Sfw157321 * be part of a bus type. This may get confused a bit
216db8f0877Sfw157321 * if a device or vendor id is encoded right after
217db8f0877Sfw157321 * the bus class since there's no delimiter. If the
218db8f0877Sfw157321 * id number begins with a hex digit [abcdef] then
219db8f0877Sfw157321 * this will become part of the bus type string
220db8f0877Sfw157321 * reported by prtdiag. This is all an effort to
221db8f0877Sfw157321 * print something potentially useful for bus types
222db8f0877Sfw157321 * other than PCI/PCIe.
223db8f0877Sfw157321 *
224db8f0877Sfw157321 * We do this because this code will get called for
225db8f0877Sfw157321 * non-PCI class devices like the xaui (class sun4v.)
226db8f0877Sfw157321 */
227db8f0877Sfw157321 if (strstr(val, "SUNW,") != NULL)
228db8f0877Sfw157321 p = strchr(val, ',') + 1;
229db8f0877Sfw157321 else
230db8f0877Sfw157321 p = val;
231db8f0877Sfw157321 q = p;
232db8f0877Sfw157321 while (*p != '\0') {
233db8f0877Sfw157321 if (isdigit((char)*p) || ispunct((char)*p)) {
234db8f0877Sfw157321 *p = '\0';
235db8f0877Sfw157321 break;
236db8f0877Sfw157321 }
237db8f0877Sfw157321 *p = (char)_toupper((int)*p);
238db8f0877Sfw157321 ++p;
239db8f0877Sfw157321 }
240db8f0877Sfw157321 (void) strlcpy(card->bus_type, q,
241db8f0877Sfw157321 sizeof (card->bus_type));
242db8f0877Sfw157321 }
2430d63ce2bSvenki }
2440d63ce2bSvenki }
2450d63ce2bSvenki
246db8f0877Sfw157321 /*
247db8f0877Sfw157321 * Fetch the Label property for this device. If none is found then
248db8f0877Sfw157321 * search all the siblings with the same device ID for a
249db8f0877Sfw157321 * Label and return that Label. The plug-in can only match the canonical
250db8f0877Sfw157321 * path from the PRI with a specific devfs path. So we take care of
251db8f0877Sfw157321 * devices with multiple functions here. A leaf device downstream of
252db8f0877Sfw157321 * a bridge should fall out of here with PICL_PROPNOTFOUND, and the
253db8f0877Sfw157321 * caller can walk back up the tree in search of the slot's Label.
254db8f0877Sfw157321 */
2550d63ce2bSvenki static picl_errno_t
get_slot_label(picl_nodehdl_t nodeh,struct io_card * card)2560d63ce2bSvenki get_slot_label(picl_nodehdl_t nodeh, struct io_card *card)
2570d63ce2bSvenki {
2580d63ce2bSvenki char val[PICL_PROPNAMELEN_MAX];
2590d63ce2bSvenki picl_errno_t err;
260dc6ca969Sfw157321 picl_nodehdl_t pnodeh;
261db8f0877Sfw157321 uint32_t devid, sib_devid;
262db8f0877Sfw157321 int32_t instance;
2630d63ce2bSvenki
264dc6ca969Sfw157321 /*
265db8f0877Sfw157321 * If there's a Label at this node then return it - we're
266db8f0877Sfw157321 * done.
267dc6ca969Sfw157321 */
2680d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, val,
2690d63ce2bSvenki sizeof (val));
270db8f0877Sfw157321 if (err == PICL_SUCCESS) {
2714c5e0fdeSvivek (void) strlcpy(card->slot_str, val, sizeof (card->slot_str));
272db8f0877Sfw157321 return (err);
273db8f0877Sfw157321 } else if (err != PICL_PROPNOTFOUND)
274db8f0877Sfw157321 return (err);
275dc6ca969Sfw157321
276db8f0877Sfw157321 /*
277db8f0877Sfw157321 * At this point we're starting to extrapolate what the Label
278db8f0877Sfw157321 * should be since there is none at this specific node.
279db8f0877Sfw157321 * Note that until the value of "err" is overwritten in the
280db8f0877Sfw157321 * loop below, its value should be PICL_PROPNOTFOUND.
281db8f0877Sfw157321 */
282db8f0877Sfw157321
283db8f0877Sfw157321 /*
284db8f0877Sfw157321 * The device must be attached, and we can figure that out if
285db8f0877Sfw157321 * the instance number is present and is not equal to -1.
286db8f0877Sfw157321 * This will prevent is from returning a Label for a sibling
287db8f0877Sfw157321 * node when the node passed in would have a unique Label if the
288db8f0877Sfw157321 * device were attached. But if the device is downstream of a
289db8f0877Sfw157321 * node with a Label then pci_callback() will still find that
290db8f0877Sfw157321 * and use it.
291db8f0877Sfw157321 */
292db8f0877Sfw157321 if (picl_get_propval_by_name(nodeh, PICL_PROP_INSTANCE, &instance,
293db8f0877Sfw157321 sizeof (instance)) != PICL_SUCCESS)
294db8f0877Sfw157321 return (err);
295db8f0877Sfw157321 if (instance == -1)
296db8f0877Sfw157321 return (err);
297db8f0877Sfw157321
298db8f0877Sfw157321 /*
299db8f0877Sfw157321 * Narrow the search to just the one device ID.
300db8f0877Sfw157321 */
301db8f0877Sfw157321 if (picl_get_propval_by_name(nodeh, PICL_PROP_DEVICE_ID, &devid,
302db8f0877Sfw157321 sizeof (devid)) != PICL_SUCCESS)
303db8f0877Sfw157321 return (err);
304db8f0877Sfw157321
305db8f0877Sfw157321 /*
306db8f0877Sfw157321 * Go find the first child of the parent so we can search
307db8f0877Sfw157321 * all of the siblings.
308db8f0877Sfw157321 */
309db8f0877Sfw157321 if (picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &pnodeh,
310db8f0877Sfw157321 sizeof (pnodeh)) != PICL_SUCCESS)
311db8f0877Sfw157321 return (err);
312db8f0877Sfw157321 if (picl_get_propval_by_name(pnodeh, PICL_PROP_CHILD, &pnodeh,
313db8f0877Sfw157321 sizeof (pnodeh)) != PICL_SUCCESS)
314db8f0877Sfw157321 return (err);
315db8f0877Sfw157321
316db8f0877Sfw157321 /*
317db8f0877Sfw157321 * If the child's device ID matches, then fetch the Label and
318db8f0877Sfw157321 * return it. The first child/device ID should have a Label
319db8f0877Sfw157321 * associated with it.
320db8f0877Sfw157321 */
321db8f0877Sfw157321 do {
322db8f0877Sfw157321 if (picl_get_propval_by_name(pnodeh, PICL_PROP_DEVICE_ID,
323db8f0877Sfw157321 &sib_devid, sizeof (sib_devid)) == PICL_SUCCESS) {
324db8f0877Sfw157321 if (sib_devid == devid) {
325db8f0877Sfw157321 if ((err = picl_get_propval_by_name(pnodeh,
326db8f0877Sfw157321 PICL_PROP_LABEL, val, sizeof (val))) ==
327db8f0877Sfw157321 PICL_SUCCESS) {
328db8f0877Sfw157321 (void) strlcpy(card->slot_str, val,
329db8f0877Sfw157321 sizeof (card->slot_str));
330db8f0877Sfw157321 break;
331db8f0877Sfw157321 }
332db8f0877Sfw157321 }
333db8f0877Sfw157321 }
334db8f0877Sfw157321 } while (picl_get_propval_by_name(pnodeh, PICL_PROP_PEER, &pnodeh,
335db8f0877Sfw157321 sizeof (pnodeh)) == PICL_SUCCESS);
336db8f0877Sfw157321
337dc6ca969Sfw157321 return (err);
3380d63ce2bSvenki }
3390d63ce2bSvenki
3400d63ce2bSvenki static void
get_slot_number(picl_nodehdl_t nodeh,struct io_card * card)3410d63ce2bSvenki get_slot_number(picl_nodehdl_t nodeh, struct io_card *card)
3420d63ce2bSvenki {
3430d63ce2bSvenki picl_errno_t err;
3440d63ce2bSvenki picl_prophdl_t proph;
3450d63ce2bSvenki picl_propinfo_t pinfo;
3460d63ce2bSvenki picl_nodehdl_t pnodeh;
3470d63ce2bSvenki uint8_t *pval;
3480d63ce2bSvenki uint32_t dev_mask;
3490d63ce2bSvenki char uaddr[MAXSTRLEN];
3500d63ce2bSvenki int i;
3510d63ce2bSvenki
3520d63ce2bSvenki err = PICL_SUCCESS;
3530d63ce2bSvenki while (err == PICL_SUCCESS) {
3540d63ce2bSvenki if (picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &pnodeh,
3550d63ce2bSvenki sizeof (pnodeh)) != PICL_SUCCESS) {
356a90d965dSfw157321 (void) strlcpy(card->slot_str, MOTHERBOARD,
3574c5e0fdeSvivek sizeof (card->slot_str));
3580d63ce2bSvenki card->slot = -1;
3590d63ce2bSvenki return;
3600d63ce2bSvenki }
3610d63ce2bSvenki if (picl_get_propinfo_by_name(pnodeh, OBP_PROP_SLOT_NAMES,
3620d63ce2bSvenki &pinfo, &proph) == PICL_SUCCESS) {
3630d63ce2bSvenki break;
3640d63ce2bSvenki }
3650d63ce2bSvenki nodeh = pnodeh;
3660d63ce2bSvenki }
3670d63ce2bSvenki if (picl_get_propval_by_name(nodeh, PICL_PROP_UNIT_ADDRESS, uaddr,
3680d63ce2bSvenki sizeof (uaddr)) != PICL_SUCCESS) {
369a90d965dSfw157321 (void) strlcpy(card->slot_str, MOTHERBOARD,
3704c5e0fdeSvivek sizeof (card->slot_str));
3710d63ce2bSvenki card->slot = -1;
3720d63ce2bSvenki return;
3730d63ce2bSvenki }
3740d63ce2bSvenki pval = (uint8_t *)malloc(pinfo.size);
3750d63ce2bSvenki if (!pval) {
376a90d965dSfw157321 (void) strlcpy(card->slot_str, MOTHERBOARD,
3774c5e0fdeSvivek sizeof (card->slot_str));
3780d63ce2bSvenki card->slot = -1;
3790d63ce2bSvenki return;
3800d63ce2bSvenki }
3810d63ce2bSvenki if (picl_get_propval(proph, pval, pinfo.size) != PICL_SUCCESS) {
382a90d965dSfw157321 (void) strlcpy(card->slot_str, MOTHERBOARD,
3834c5e0fdeSvivek sizeof (card->slot_str));
3840d63ce2bSvenki card->slot = -1;
3850d63ce2bSvenki free(pval);
3860d63ce2bSvenki return;
3870d63ce2bSvenki }
3880d63ce2bSvenki
3890d63ce2bSvenki dev_mask = 0;
3900d63ce2bSvenki for (i = 0; i < sizeof (dev_mask); i++)
3910d63ce2bSvenki dev_mask |= (*(pval+i) << 8*(sizeof (dev_mask)-1-i));
3920d63ce2bSvenki for (i = 0; i < sizeof (uaddr) && uaddr[i] != '\0'; i++) {
3930d63ce2bSvenki if (uaddr[i] == ',') {
3940d63ce2bSvenki uaddr[i] = '\0';
3950d63ce2bSvenki break;
3960d63ce2bSvenki }
3970d63ce2bSvenki }
3980d63ce2bSvenki card->slot = atol(uaddr);
3990d63ce2bSvenki if (((1 << card->slot) & dev_mask) == 0) {
400a90d965dSfw157321 (void) strlcpy(card->slot_str, MOTHERBOARD,
4014c5e0fdeSvivek sizeof (card->slot_str));
4020d63ce2bSvenki card->slot = -1;
4030d63ce2bSvenki } else {
4040d63ce2bSvenki char *p = (char *)(pval+sizeof (dev_mask));
4050d63ce2bSvenki int shift = sizeof (uint32_t)*8-1-card->slot;
4060d63ce2bSvenki uint32_t x = (dev_mask << shift) >> shift;
4070d63ce2bSvenki int count = 0; /* count # of 1's in x */
4080d63ce2bSvenki int i = 0;
4090d63ce2bSvenki while (x != 0) {
4100d63ce2bSvenki count++;
4110d63ce2bSvenki x &= x-1;
4120d63ce2bSvenki }
4130d63ce2bSvenki while (count > 1) {
414a90d965dSfw157321 while (p[i++] != '\0')
415a90d965dSfw157321 ;
4160d63ce2bSvenki count--;
4170d63ce2bSvenki }
4184c5e0fdeSvivek (void) strlcpy(card->slot_str, (char *)(p+i),
4194c5e0fdeSvivek sizeof (card->slot_str));
4200d63ce2bSvenki }
4210d63ce2bSvenki free(pval);
4220d63ce2bSvenki }
4230d63ce2bSvenki
4240d63ce2bSvenki /*
4250d63ce2bSvenki * add all io devices under pci in io list
4260d63ce2bSvenki */
4270d63ce2bSvenki /* ARGSUSED */
4280d63ce2bSvenki static int
sun4v_pci_callback(picl_nodehdl_t pcih,void * args)4290d63ce2bSvenki sun4v_pci_callback(picl_nodehdl_t pcih, void *args)
4300d63ce2bSvenki {
4310d63ce2bSvenki char path[PICL_PROPNAMELEN_MAX];
4320d63ce2bSvenki char class[PICL_CLASSNAMELEN_MAX];
4330d63ce2bSvenki char name[PICL_PROPNAMELEN_MAX];
4340d63ce2bSvenki char model[PICL_PROPNAMELEN_MAX];
4350d63ce2bSvenki char binding_name[PICL_PROPNAMELEN_MAX];
4360d63ce2bSvenki char val[PICL_PROPNAMELEN_MAX];
4370d63ce2bSvenki char *compatible;
4380d63ce2bSvenki picl_errno_t err;
439db8f0877Sfw157321 picl_nodehdl_t nodeh, pnodeh;
4400d63ce2bSvenki struct io_card pci_card;
4410d63ce2bSvenki
4420d63ce2bSvenki /* Walk through the children */
4430d63ce2bSvenki
4440d63ce2bSvenki err = picl_get_propval_by_name(pcih, PICL_PROP_CHILD, &nodeh,
4450d63ce2bSvenki sizeof (picl_nodehdl_t));
4460d63ce2bSvenki
4470d63ce2bSvenki while (err == PICL_SUCCESS) {
4480d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
4490d63ce2bSvenki class, sizeof (class));
4500d63ce2bSvenki if (err != PICL_SUCCESS)
4510d63ce2bSvenki return (err);
4520d63ce2bSvenki
4530d63ce2bSvenki if (args) {
4540d63ce2bSvenki char *val = args;
4550d63ce2bSvenki if (strcmp(class, val) == 0) {
4560d63ce2bSvenki err = picl_get_propval_by_name(nodeh,
4570d63ce2bSvenki PICL_PROP_PEER, &nodeh,
4580d63ce2bSvenki sizeof (picl_nodehdl_t));
4590d63ce2bSvenki continue;
4600d63ce2bSvenki } else if (strcmp(val, PICL_CLASS_PCIEX) == 0 &&
4610d63ce2bSvenki strcmp(class, PICL_CLASS_PCI) == 0) {
4620d63ce2bSvenki err = picl_get_propval_by_name(nodeh,
4630d63ce2bSvenki PICL_PROP_PEER, &nodeh,
4640d63ce2bSvenki sizeof (picl_nodehdl_t));
4650d63ce2bSvenki continue;
4660d63ce2bSvenki } else if (strcmp(val, PICL_CLASS_PCI) == 0 &&
4670d63ce2bSvenki strcmp(class, PICL_CLASS_PCIEX) == 0) {
4680d63ce2bSvenki err = picl_get_propval_by_name(nodeh,
4690d63ce2bSvenki PICL_PROP_PEER, &nodeh,
4700d63ce2bSvenki sizeof (picl_nodehdl_t));
4710d63ce2bSvenki continue;
4720d63ce2bSvenki }
4730d63ce2bSvenki }
4740d63ce2bSvenki
4750d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_DEVFS_PATH,
4760d63ce2bSvenki path, sizeof (path));
4770d63ce2bSvenki if (err != PICL_SUCCESS)
4780d63ce2bSvenki return (err);
4790d63ce2bSvenki
4800d63ce2bSvenki (void) strlcpy(pci_card.notes, path, sizeof (pci_card.notes));
4810d63ce2bSvenki
482db8f0877Sfw157321 pnodeh = nodeh;
483db8f0877Sfw157321 err = get_slot_label(nodeh, &pci_card);
484db8f0877Sfw157321
485db8f0877Sfw157321 /*
486db8f0877Sfw157321 * No Label at this node, maybe we're looking at a device
487db8f0877Sfw157321 * downstream of a bridge. Walk back up and find a Label and
488db8f0877Sfw157321 * record that node in "pnodeh".
489db8f0877Sfw157321 */
490db8f0877Sfw157321 while (err != PICL_SUCCESS) {
491db8f0877Sfw157321 if (err != PICL_PROPNOTFOUND)
492db8f0877Sfw157321 break;
493db8f0877Sfw157321 else if (picl_get_propval_by_name(pnodeh,
494db8f0877Sfw157321 PICL_PROP_PARENT, &pnodeh, sizeof (pnodeh)) ==
495db8f0877Sfw157321 PICL_SUCCESS)
496db8f0877Sfw157321 err = get_slot_label(pnodeh, &pci_card);
497db8f0877Sfw157321 else
498db8f0877Sfw157321 break;
499db8f0877Sfw157321 }
500db8f0877Sfw157321
501db8f0877Sfw157321 /*
502db8f0877Sfw157321 * Can't find a Label for this device in the PCI heirarchy.
503db8f0877Sfw157321 * Try to synthesize a slot name from atoms. This depends
504db8f0877Sfw157321 * on the OBP slot_names property being implemented, and this
505db8f0877Sfw157321 * so far doesn't seem to be on sun4v. But just in case that
506db8f0877Sfw157321 * is resurrected, the code is here.
507db8f0877Sfw157321 */
508db8f0877Sfw157321 if (err != PICL_SUCCESS) {
509db8f0877Sfw157321 pnodeh = nodeh;
5100d63ce2bSvenki get_slot_number(nodeh, &pci_card);
511db8f0877Sfw157321 }
512db8f0877Sfw157321
513db8f0877Sfw157321 /*
514db8f0877Sfw157321 * Passing in pnodeh instead of nodeh will cause prtdiag
515db8f0877Sfw157321 * to display the type of IO slot for the leaf node. For
516db8f0877Sfw157321 * built-in devices and a lot of IO cards these will be
517db8f0877Sfw157321 * the same thing. But for IO cards with bridge chips or
518db8f0877Sfw157321 * for things like expansion chassis, prtdiag will report
519db8f0877Sfw157321 * the bus type of the IO slot and not the leaf, which
520db8f0877Sfw157321 * could be different things.
521db8f0877Sfw157321 */
522db8f0877Sfw157321 get_bus_type(pnodeh, &pci_card);
5230d63ce2bSvenki
5240d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_NAME, name,
5250d63ce2bSvenki sizeof (name));
5260d63ce2bSvenki if (err == PICL_PROPNOTFOUND)
5274c5e0fdeSvivek (void) strlcpy(name, "", sizeof (name));
5280d63ce2bSvenki else if (err != PICL_SUCCESS)
5290d63ce2bSvenki return (err);
5300d63ce2bSvenki
5310d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_STATUS, val,
5320d63ce2bSvenki sizeof (val));
5330d63ce2bSvenki if (err == PICL_PROPNOTFOUND)
5344c5e0fdeSvivek (void) strlcpy(val, "", sizeof (val));
5350d63ce2bSvenki else if (err != PICL_SUCCESS)
5360d63ce2bSvenki return (err);
5370d63ce2bSvenki
538dc6ca969Sfw157321 (void) snprintf(pci_card.status, sizeof (pci_card.status),
5390d63ce2bSvenki "%s", pci_card.slot_str);
5400d63ce2bSvenki
5410d63ce2bSvenki /*
5420d63ce2bSvenki * Get the name of this card. If binding_name is found,
5430d63ce2bSvenki * name will be <nodename>-<binding_name>.
5440d63ce2bSvenki */
5450d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_BINDING_NAME,
5460d63ce2bSvenki binding_name, sizeof (binding_name));
5470d63ce2bSvenki if (err == PICL_SUCCESS) {
5480d63ce2bSvenki if (strcmp(name, binding_name) != 0) {
5490d63ce2bSvenki (void) strlcat(name, "-", sizeof (name));
5500d63ce2bSvenki (void) strlcat(name, binding_name,
5510d63ce2bSvenki sizeof (name));
5520d63ce2bSvenki }
5530d63ce2bSvenki } else if (err == PICL_PROPNOTFOUND) {
5540d63ce2bSvenki /*
5550d63ce2bSvenki * if compatible prop is not found, name will be
5560d63ce2bSvenki * <nodename>-<compatible>
5570d63ce2bSvenki */
5580d63ce2bSvenki err = sun4v_get_first_compatible_value(nodeh,
5590d63ce2bSvenki &compatible);
5600d63ce2bSvenki if (err == PICL_SUCCESS) {
5610d63ce2bSvenki (void) strlcat(name, "-", sizeof (name));
5624c5e0fdeSvivek (void) strlcat(name, compatible,
5634c5e0fdeSvivek sizeof (name));
5640d63ce2bSvenki free(compatible);
5650d63ce2bSvenki }
5660d63ce2bSvenki } else
5670d63ce2bSvenki return (err);
5680d63ce2bSvenki
5690d63ce2bSvenki (void) strlcpy(pci_card.name, name, sizeof (pci_card.name));
5700d63ce2bSvenki
5710d63ce2bSvenki /* Get the model of this card */
5720d63ce2bSvenki
5730d63ce2bSvenki err = picl_get_propval_by_name(nodeh, OBP_PROP_MODEL,
5740d63ce2bSvenki model, sizeof (model));
5750d63ce2bSvenki if (err == PICL_PROPNOTFOUND)
5764c5e0fdeSvivek (void) strlcpy(model, "", sizeof (model));
5770d63ce2bSvenki else if (err != PICL_SUCCESS)
5780d63ce2bSvenki return (err);
5790d63ce2bSvenki (void) strlcpy(pci_card.model, model, sizeof (pci_card.model));
5800d63ce2bSvenki
5810d63ce2bSvenki /* Print NAC name */
582aaba19e2Sfw157321 log_printf("%-18s", pci_card.status);
5830d63ce2bSvenki /* Print IO Type */
5840d63ce2bSvenki log_printf("%-6s", pci_card.bus_type);
5850d63ce2bSvenki /* Printf Card Name */
5867ae4bfcbSfw157321 log_printf("%-34s", pci_card.name);
5870d63ce2bSvenki /* Print Card Model */
5880d63ce2bSvenki log_printf("%-8s", pci_card.model);
5890d63ce2bSvenki log_printf("\n");
5900d63ce2bSvenki /* Print Status */
591aaba19e2Sfw157321 log_printf("%-18s", val);
5920d63ce2bSvenki /* Print IO Type */
5930d63ce2bSvenki log_printf("%-6s", "");
5940d63ce2bSvenki /* Print Parent Path */
595aaba19e2Sfw157321 log_printf("%-44s", pci_card.notes);
5960d63ce2bSvenki log_printf("\n");
5970d63ce2bSvenki
5980d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh,
5990d63ce2bSvenki sizeof (picl_nodehdl_t));
6000d63ce2bSvenki }
6010d63ce2bSvenki return (PICL_WALK_CONTINUE);
60203831d35Sstevel }
60303831d35Sstevel
60403831d35Sstevel /*
60503831d35Sstevel * display_pci
60603831d35Sstevel * Display all the PCI IO cards on this board.
60703831d35Sstevel */
60803831d35Sstevel void
sun4v_display_pci(picl_nodehdl_t plafh)60903831d35Sstevel sun4v_display_pci(picl_nodehdl_t plafh)
61003831d35Sstevel {
6117ae4bfcbSfw157321 char *fmt = "%-17s %-5s %-33s %-8s";
6120d63ce2bSvenki /* Have we printed the column headings? */
6130d63ce2bSvenki static int banner = FALSE;
6140d63ce2bSvenki
6150d63ce2bSvenki if (banner == FALSE) {
6160d63ce2bSvenki log_printf("\n");
617aaba19e2Sfw157321 log_printf("================================");
6180d63ce2bSvenki log_printf(" IO Devices ");
619aaba19e2Sfw157321 log_printf("================================");
6200d63ce2bSvenki log_printf("\n");
6210d63ce2bSvenki log_printf(fmt, "Slot +", "Bus", "Name +", "Model", 0);
6220d63ce2bSvenki log_printf("\n");
6230d63ce2bSvenki log_printf(fmt, "Status", "Type", "Path", "", 0);
6240d63ce2bSvenki log_printf("\n");
6250d63ce2bSvenki log_printf("---------------------------------"
626aaba19e2Sfw157321 "-------------------------------------------\n");
6270d63ce2bSvenki banner = TRUE;
62803831d35Sstevel }
62903831d35Sstevel
6300d63ce2bSvenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_PCIEX,
6310d63ce2bSvenki PICL_CLASS_PCIEX, sun4v_pci_callback);
6320d63ce2bSvenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_PCI,
6330d63ce2bSvenki PICL_CLASS_PCI, sun4v_pci_callback);
6340d63ce2bSvenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_SUN4V,
6350d63ce2bSvenki PICL_CLASS_SUN4V, sun4v_pci_callback);
6360d63ce2bSvenki }
6370d63ce2bSvenki
63803831d35Sstevel /*
6390d63ce2bSvenki * return the first compatible value
64003831d35Sstevel */
6410d63ce2bSvenki static int
sun4v_get_first_compatible_value(picl_nodehdl_t nodeh,char ** outbuf)6420d63ce2bSvenki sun4v_get_first_compatible_value(picl_nodehdl_t nodeh, char **outbuf)
6430d63ce2bSvenki {
6440d63ce2bSvenki picl_errno_t err;
6450d63ce2bSvenki picl_prophdl_t proph;
6460d63ce2bSvenki picl_propinfo_t pinfo;
6470d63ce2bSvenki picl_prophdl_t tblh;
6480d63ce2bSvenki picl_prophdl_t rowproph;
6490d63ce2bSvenki char *pval;
6500d63ce2bSvenki
6510d63ce2bSvenki err = picl_get_propinfo_by_name(nodeh, OBP_PROP_COMPATIBLE,
6520d63ce2bSvenki &pinfo, &proph);
6530d63ce2bSvenki if (err != PICL_SUCCESS)
6540d63ce2bSvenki return (err);
6550d63ce2bSvenki
6560d63ce2bSvenki if (pinfo.type == PICL_PTYPE_CHARSTRING) {
6570d63ce2bSvenki pval = malloc(pinfo.size);
6580d63ce2bSvenki if (pval == NULL)
6590d63ce2bSvenki return (PICL_FAILURE);
6600d63ce2bSvenki err = picl_get_propval(proph, pval, pinfo.size);
6610d63ce2bSvenki if (err != PICL_SUCCESS) {
6620d63ce2bSvenki free(pval);
6630d63ce2bSvenki return (err);
6640d63ce2bSvenki }
6650d63ce2bSvenki *outbuf = pval;
6660d63ce2bSvenki return (PICL_SUCCESS);
6670d63ce2bSvenki }
6680d63ce2bSvenki
6690d63ce2bSvenki if (pinfo.type != PICL_PTYPE_TABLE)
6700d63ce2bSvenki return (PICL_FAILURE);
6710d63ce2bSvenki
6720d63ce2bSvenki /* get first string from table */
6730d63ce2bSvenki err = picl_get_propval(proph, &tblh, pinfo.size);
6740d63ce2bSvenki if (err != PICL_SUCCESS)
6750d63ce2bSvenki return (err);
6760d63ce2bSvenki
6770d63ce2bSvenki err = picl_get_next_by_row(tblh, &rowproph);
6780d63ce2bSvenki if (err != PICL_SUCCESS)
6790d63ce2bSvenki return (err);
6800d63ce2bSvenki
6810d63ce2bSvenki err = picl_get_propinfo(rowproph, &pinfo);
6820d63ce2bSvenki if (err != PICL_SUCCESS)
6830d63ce2bSvenki return (err);
6840d63ce2bSvenki
6850d63ce2bSvenki pval = malloc(pinfo.size);
6860d63ce2bSvenki if (pval == NULL)
6870d63ce2bSvenki return (PICL_FAILURE);
6880d63ce2bSvenki
6890d63ce2bSvenki err = picl_get_propval(rowproph, pval, pinfo.size);
6900d63ce2bSvenki if (err != PICL_SUCCESS) {
6910d63ce2bSvenki free(pval);
6920d63ce2bSvenki return (err);
6930d63ce2bSvenki }
6940d63ce2bSvenki
6950d63ce2bSvenki *outbuf = pval;
6960d63ce2bSvenki return (PICL_SUCCESS);
6970d63ce2bSvenki }
6980d63ce2bSvenki
6990d63ce2bSvenki /*
7000d63ce2bSvenki * print size of a memory segment
7010d63ce2bSvenki */
7020d63ce2bSvenki static void
print_memory_segment_size(uint64_t size)7030d63ce2bSvenki print_memory_segment_size(uint64_t size)
7040d63ce2bSvenki {
7050d63ce2bSvenki uint64_t kbyte = 1024;
7060d63ce2bSvenki uint64_t mbyte = kbyte * kbyte;
7070d63ce2bSvenki uint64_t gbyte = kbyte * mbyte;
7087ae4bfcbSfw157321 uint64_t tbyte = kbyte * gbyte;
7090d63ce2bSvenki char buf[MEMORY_SIZE_FIELD];
7100d63ce2bSvenki
7117ae4bfcbSfw157321 if (size >= tbyte) {
7127ae4bfcbSfw157321 if (size % tbyte == 0)
7137ae4bfcbSfw157321 (void) snprintf(buf, sizeof (buf), "%d TB",
7147ae4bfcbSfw157321 (int)(size / tbyte));
7157ae4bfcbSfw157321 else
7167ae4bfcbSfw157321 (void) snprintf(buf, sizeof (buf), "%.2f TB",
7177ae4bfcbSfw157321 (float)size / tbyte);
7187ae4bfcbSfw157321 } else if (size >= gbyte) {
7190d63ce2bSvenki if (size % gbyte == 0)
7200d63ce2bSvenki (void) snprintf(buf, sizeof (buf), "%d GB",
7210d63ce2bSvenki (int)(size / gbyte));
7220d63ce2bSvenki else
7230d63ce2bSvenki (void) snprintf(buf, sizeof (buf), "%.2f GB",
7240d63ce2bSvenki (float)size / gbyte);
7250d63ce2bSvenki } else if (size >= mbyte) {
7260d63ce2bSvenki if (size % mbyte == 0)
7270d63ce2bSvenki (void) snprintf(buf, sizeof (buf), "%d MB",
7280d63ce2bSvenki (int)(size / mbyte));
7290d63ce2bSvenki else
7300d63ce2bSvenki (void) snprintf(buf, sizeof (buf), "%.2f MB",
7310d63ce2bSvenki (float)size / mbyte);
7320d63ce2bSvenki } else {
7330d63ce2bSvenki if (size % kbyte == 0)
7340d63ce2bSvenki (void) snprintf(buf, sizeof (buf), "%d KB",
7350d63ce2bSvenki (int)(size / kbyte));
7360d63ce2bSvenki else
7370d63ce2bSvenki (void) snprintf(buf, sizeof (buf), "%.2f KB",
7380d63ce2bSvenki (float)size / kbyte);
7390d63ce2bSvenki }
7407ae4bfcbSfw157321 log_printf("%-9s", buf);
7410d63ce2bSvenki }
7420d63ce2bSvenki
7430d63ce2bSvenki /*
744a90d965dSfw157321 * Enumerate banks and dimms within a memory segment. We're handed
745a90d965dSfw157321 * the first bank within the segment - we assume there are dimms
746a90d965dSfw157321 * (memory-module) nodes underneath.
7470d63ce2bSvenki */
7480d63ce2bSvenki static void
print_memory_segment_contain(picl_nodehdl_t bank_nodeh)749a90d965dSfw157321 print_memory_segment_contain(picl_nodehdl_t bank_nodeh)
7500d63ce2bSvenki {
7510d63ce2bSvenki char val[PICL_PROPNAMELEN_MAX];
752a90d965dSfw157321 picl_nodehdl_t module_nodeh;
753a90d965dSfw157321 int flag = 0;
7547ae4bfcbSfw157321 uint64_t size;
755a90d965dSfw157321
756a90d965dSfw157321 do {
757a90d965dSfw157321 if (picl_get_propval_by_name(bank_nodeh, PICL_PROP_CHILD,
758a90d965dSfw157321 &module_nodeh, sizeof (picl_nodehdl_t)) != PICL_SUCCESS)
759a90d965dSfw157321 continue;
7607ae4bfcbSfw157321 if (picl_get_propval_by_name(bank_nodeh, PICL_PROP_SIZE,
7617ae4bfcbSfw157321 &size, sizeof (size)) == PICL_SUCCESS) {
7627ae4bfcbSfw157321 if (!flag) {
7637ae4bfcbSfw157321 print_memory_segment_size(size);
7647ae4bfcbSfw157321 } else {
7657ae4bfcbSfw157321 log_printf(" "
7667ae4bfcbSfw157321 " ");
7677ae4bfcbSfw157321 print_memory_segment_size(size);
7687ae4bfcbSfw157321 flag = 0;
7697ae4bfcbSfw157321 }
7707ae4bfcbSfw157321 }
771a90d965dSfw157321 do {
772a90d965dSfw157321 if (picl_get_propval_by_name(module_nodeh,
773a90d965dSfw157321 PICL_PROP_NAC, val, sizeof (val)) !=
774a90d965dSfw157321 PICL_SUCCESS)
775a90d965dSfw157321 continue;
776a90d965dSfw157321 else {
777a90d965dSfw157321 if (!flag) {
7787ae4bfcbSfw157321 log_printf("%s\n", val);
779a90d965dSfw157321 flag = 1;
7807ae4bfcbSfw157321 } else {
7817ae4bfcbSfw157321 log_printf("%s%s\n",
7827ae4bfcbSfw157321 " "
7837ae4bfcbSfw157321 " ",
7847ae4bfcbSfw157321 val);
7857ae4bfcbSfw157321 }
7860d63ce2bSvenki }
787a90d965dSfw157321 } while (picl_get_propval_by_name(module_nodeh, PICL_PROP_PEER,
788a90d965dSfw157321 &module_nodeh, sizeof (picl_nodehdl_t)) ==
789a90d965dSfw157321 PICL_SUCCESS);
790a90d965dSfw157321 } while (picl_get_propval_by_name(bank_nodeh, PICL_PROP_PEER,
791a90d965dSfw157321 &bank_nodeh, sizeof (picl_nodehdl_t)) == PICL_SUCCESS);
7920d63ce2bSvenki }
7930d63ce2bSvenki
7940d63ce2bSvenki /*
7950d63ce2bSvenki * Search node where _class=="memory-segment"
7960d63ce2bSvenki * print "Base Address", "Size", etc
7970d63ce2bSvenki */
7980d63ce2bSvenki /*ARGSUSED*/
7990d63ce2bSvenki static int
sun4v_memory_conf_callback(picl_nodehdl_t nodeh,void * args)8000d63ce2bSvenki sun4v_memory_conf_callback(picl_nodehdl_t nodeh, void *args)
8010d63ce2bSvenki {
8020d63ce2bSvenki uint64_t base;
8030d63ce2bSvenki uint64_t size;
8040d63ce2bSvenki uint64_t ifactor;
8050d63ce2bSvenki picl_errno_t err = PICL_SUCCESS;
8060d63ce2bSvenki
8070d63ce2bSvenki if (class_node_found == 0) {
8080d63ce2bSvenki class_node_found = 1;
8090d63ce2bSvenki return (PICL_WALK_TERMINATE);
8100d63ce2bSvenki }
8110d63ce2bSvenki while (err == PICL_SUCCESS) {
8120d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_BASEADDRESS,
8130d63ce2bSvenki &base, sizeof (base));
8140d63ce2bSvenki if (err != PICL_SUCCESS)
8150d63ce2bSvenki break;
8160d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_SIZE,
8170d63ce2bSvenki &size, sizeof (size));
8180d63ce2bSvenki if (err != PICL_SUCCESS)
8190d63ce2bSvenki break;
8200d63ce2bSvenki err = picl_get_propval_by_name(nodeh,
8210d63ce2bSvenki PICL_PROP_INTERLEAVE_FACTOR, &ifactor,
8220d63ce2bSvenki sizeof (ifactor));
8230d63ce2bSvenki if (err != PICL_SUCCESS)
8240d63ce2bSvenki break;
8257ae4bfcbSfw157321 log_printf("0x%-13llx", base);
8260d63ce2bSvenki print_memory_segment_size(size);
8277ae4bfcbSfw157321 log_printf("%-12lld", ifactor);
828a90d965dSfw157321 err = picl_get_propval_by_name(nodeh, PICL_PROP_CHILD,
829a90d965dSfw157321 &nodeh, sizeof (nodeh));
830a90d965dSfw157321 if (err == PICL_SUCCESS)
8310d63ce2bSvenki print_memory_segment_contain(nodeh);
8320d63ce2bSvenki log_printf("\n");
8330d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh,
8340d63ce2bSvenki sizeof (picl_nodehdl_t));
8350d63ce2bSvenki }
8360d63ce2bSvenki
8370d63ce2bSvenki return (PICL_WALK_CONTINUE);
8380d63ce2bSvenki }
8390d63ce2bSvenki
8400d63ce2bSvenki /*ARGSUSED*/
8410d63ce2bSvenki void
sun4v_display_memory_conf(picl_nodehdl_t plafh)8420d63ce2bSvenki sun4v_display_memory_conf(picl_nodehdl_t plafh)
8430d63ce2bSvenki {
8447ae4bfcbSfw157321 char *fmt = "%-14s %-8s %-11s %-8s %-s";
8450d63ce2bSvenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY_SEGMENT,
8460d63ce2bSvenki NULL, sun4v_memory_conf_callback);
8470d63ce2bSvenki if (class_node_found == 0)
8480d63ce2bSvenki return;
8490d63ce2bSvenki log_printf("\n");
8507ae4bfcbSfw157321 log_printf("=======================");
8517ae4bfcbSfw157321 log_printf(" Physical Memory Configuration ");
8527ae4bfcbSfw157321 log_printf("========================");
8530d63ce2bSvenki log_printf("\n");
8540d63ce2bSvenki log_printf("Segment Table:\n");
855a90d965dSfw157321 log_printf(
8567ae4bfcbSfw157321 "--------------------------------------------------------------\n");
8577ae4bfcbSfw157321 log_printf(fmt, "Base", "Segment", "Interleave", "Bank", "Contains", 0);
8587ae4bfcbSfw157321 log_printf("\n");
8597ae4bfcbSfw157321 log_printf(fmt, "Address", "Size", "Factor", "Size", "Modules", 0);
8600d63ce2bSvenki log_printf("\n");
861a90d965dSfw157321 log_printf(
8627ae4bfcbSfw157321 "--------------------------------------------------------------\n");
8630d63ce2bSvenki (void) picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY_SEGMENT,
8640d63ce2bSvenki NULL, sun4v_memory_conf_callback);
86503831d35Sstevel }
86603831d35Sstevel
86703831d35Sstevel void
sun4v_display_cpu_devices(picl_nodehdl_t plafh)86803831d35Sstevel sun4v_display_cpu_devices(picl_nodehdl_t plafh)
86903831d35Sstevel {
8707ae4bfcbSfw157321 char *fmt = "%-6s %-9s %-22s %-6s";
87103831d35Sstevel
87203831d35Sstevel /*
87303831d35Sstevel * Display the table header for CPUs . Then display the CPU
87403831d35Sstevel * frequency, cache size, and processor revision of all cpus.
87503831d35Sstevel */
87603831d35Sstevel log_printf(dgettext(TEXT_DOMAIN,
87703831d35Sstevel "\n"
8787ae4bfcbSfw157321 "================================"
8797ae4bfcbSfw157321 " Virtual CPUs "
8807ae4bfcbSfw157321 "================================"
88103831d35Sstevel "\n"
88203831d35Sstevel "\n"));
88303831d35Sstevel log_printf("\n");
8847ae4bfcbSfw157321 log_printf(fmt, "CPU ID", "Frequency", "Implementation",
8857ae4bfcbSfw157321 "Status", 0);
88603831d35Sstevel log_printf("\n");
8877ae4bfcbSfw157321 log_printf(fmt, "------", "---------",
8887ae4bfcbSfw157321 "----------------------", "-------", 0);
88903831d35Sstevel log_printf("\n");
89003831d35Sstevel
8917ae4bfcbSfw157321 (void) picl_walk_tree_by_class(plafh, PICL_CLASS_CPU, PICL_CLASS_CPU,
8927ae4bfcbSfw157321 sun4v_display_cpus);
89303831d35Sstevel }
89403831d35Sstevel
89503831d35Sstevel /*
89603831d35Sstevel * Display the CPUs present on this board.
89703831d35Sstevel */
89803831d35Sstevel /*ARGSUSED*/
89903831d35Sstevel int
sun4v_display_cpus(picl_nodehdl_t cpuh,void * args)90003831d35Sstevel sun4v_display_cpus(picl_nodehdl_t cpuh, void* args)
90103831d35Sstevel {
90203831d35Sstevel int status;
90303831d35Sstevel picl_prophdl_t proph;
90403831d35Sstevel picl_prophdl_t tblh;
90503831d35Sstevel picl_prophdl_t rowproph;
90603831d35Sstevel picl_propinfo_t propinfo;
90703831d35Sstevel int *int_value;
9085e3e415aSfw157321 int cpuid;
90903831d35Sstevel char *comp_value;
91003831d35Sstevel char *no_prop_value = " ";
91103831d35Sstevel char freq_str[MAXSTRLEN];
9125e3e415aSfw157321 char state[MAXSTRLEN];
91303831d35Sstevel
91403831d35Sstevel /*
91503831d35Sstevel * Get cpuid property and print it and the NAC name
91603831d35Sstevel */
9177ae4bfcbSfw157321 status = picl_get_propinfo_by_name(cpuh, OBP_PROP_CPUID, &propinfo,
9187ae4bfcbSfw157321 &proph);
91903831d35Sstevel if (status == PICL_SUCCESS) {
92003831d35Sstevel status = picl_get_propval(proph, &cpuid, sizeof (cpuid));
92103831d35Sstevel if (status != PICL_SUCCESS) {
9227ae4bfcbSfw157321 log_printf("%-7s", no_prop_value);
92303831d35Sstevel } else {
9247ae4bfcbSfw157321 log_printf("%-7d", cpuid);
92503831d35Sstevel }
92603831d35Sstevel } else {
9277ae4bfcbSfw157321 log_printf("%-7s", no_prop_value);
92803831d35Sstevel }
92903831d35Sstevel
93003831d35Sstevel clock_freq:
93103831d35Sstevel status = picl_get_propinfo_by_name(cpuh, "clock-frequency", &propinfo,
93203831d35Sstevel &proph);
93303831d35Sstevel if (status == PICL_SUCCESS) {
93403831d35Sstevel int_value = malloc(propinfo.size);
93503831d35Sstevel if (int_value == NULL) {
9367ae4bfcbSfw157321 log_printf("%-10s", no_prop_value);
93703831d35Sstevel goto compatible;
93803831d35Sstevel }
93903831d35Sstevel status = picl_get_propval(proph, int_value, propinfo.size);
94003831d35Sstevel if (status != PICL_SUCCESS) {
9417ae4bfcbSfw157321 log_printf("%-10s", no_prop_value);
94203831d35Sstevel } else {
94303831d35Sstevel /* Running frequency */
94403831d35Sstevel (void) snprintf(freq_str, sizeof (freq_str), "%d MHz",
94503831d35Sstevel CLK_FREQ_TO_MHZ(*int_value));
9467ae4bfcbSfw157321 log_printf("%-10s", freq_str);
94703831d35Sstevel }
94803831d35Sstevel free(int_value);
94903831d35Sstevel } else
9507ae4bfcbSfw157321 log_printf("%-10s", no_prop_value);
95103831d35Sstevel
95203831d35Sstevel compatible:
95303831d35Sstevel status = picl_get_propinfo_by_name(cpuh, "compatible", &propinfo,
95403831d35Sstevel &proph);
95503831d35Sstevel if (status == PICL_SUCCESS) {
95603831d35Sstevel if (propinfo.type == PICL_PTYPE_CHARSTRING) {
95703831d35Sstevel /*
95803831d35Sstevel * Compatible Property only has 1 value
95903831d35Sstevel */
96003831d35Sstevel comp_value = malloc(propinfo.size);
96103831d35Sstevel if (comp_value == NULL) {
9627ae4bfcbSfw157321 log_printf("%-23s", no_prop_value, 0);
9635e3e415aSfw157321 goto state;
96403831d35Sstevel }
96503831d35Sstevel status = picl_get_propval(proph, comp_value,
96603831d35Sstevel propinfo.size);
9670d63ce2bSvenki if (status != PICL_SUCCESS)
9687ae4bfcbSfw157321 log_printf("%-23s", no_prop_value, 0);
9690d63ce2bSvenki else
9707ae4bfcbSfw157321 log_printf("%-23s", comp_value, 0);
97103831d35Sstevel free(comp_value);
97203831d35Sstevel } else if (propinfo.type == PICL_PTYPE_TABLE) {
97303831d35Sstevel /*
97403831d35Sstevel * Compatible Property has multiple values
97503831d35Sstevel */
97603831d35Sstevel status = picl_get_propval(proph, &tblh, propinfo.size);
97703831d35Sstevel if (status != PICL_SUCCESS) {
9787ae4bfcbSfw157321 log_printf("%-23s", no_prop_value, 0);
9795e3e415aSfw157321 goto state;
98003831d35Sstevel }
98103831d35Sstevel status = picl_get_next_by_row(tblh, &rowproph);
98203831d35Sstevel if (status != PICL_SUCCESS) {
9837ae4bfcbSfw157321 log_printf("%-23s", no_prop_value, 0);
9845e3e415aSfw157321 goto state;
98503831d35Sstevel }
98603831d35Sstevel
98703831d35Sstevel status = picl_get_propinfo(rowproph, &propinfo);
98803831d35Sstevel if (status != PICL_SUCCESS) {
9897ae4bfcbSfw157321 log_printf("%-23s", no_prop_value, 0);
9905e3e415aSfw157321 goto state;
99103831d35Sstevel }
99203831d35Sstevel
99303831d35Sstevel comp_value = malloc(propinfo.size);
99403831d35Sstevel if (comp_value == NULL) {
9957ae4bfcbSfw157321 log_printf("%-23s", no_prop_value, 0);
9965e3e415aSfw157321 goto state;
99703831d35Sstevel }
99803831d35Sstevel status = picl_get_propval(rowproph, comp_value,
99903831d35Sstevel propinfo.size);
10000d63ce2bSvenki if (status != PICL_SUCCESS)
10017ae4bfcbSfw157321 log_printf("%-23s", no_prop_value, 0);
10020d63ce2bSvenki else
10037ae4bfcbSfw157321 log_printf("%-23s", comp_value, 0);
100403831d35Sstevel free(comp_value);
100503831d35Sstevel }
100603831d35Sstevel } else
10077ae4bfcbSfw157321 log_printf("%-23s", no_prop_value, 0);
100803831d35Sstevel
10095e3e415aSfw157321 state:
10105e3e415aSfw157321 status = picl_get_propinfo_by_name(cpuh, PICL_PROP_STATE,
10115e3e415aSfw157321 &propinfo, &proph);
101203831d35Sstevel if (status == PICL_SUCCESS) {
10135e3e415aSfw157321 status = picl_get_propval(proph, state, sizeof (state));
101403831d35Sstevel if (status != PICL_SUCCESS) {
10150d63ce2bSvenki log_printf("%-9s", no_prop_value);
101603831d35Sstevel } else {
10175e3e415aSfw157321 log_printf("%-9s", state);
101803831d35Sstevel }
101903831d35Sstevel } else
10200d63ce2bSvenki log_printf("%-9s", no_prop_value);
102103831d35Sstevel
102203831d35Sstevel done:
102303831d35Sstevel log_printf("\n");
102403831d35Sstevel return (PICL_WALK_CONTINUE);
102503831d35Sstevel }
102603831d35Sstevel
102703831d35Sstevel void
sun4v_display_diaginfo(int flag,Prom_node * root,picl_nodehdl_t plafh)102803831d35Sstevel sun4v_display_diaginfo(int flag, Prom_node *root, picl_nodehdl_t plafh)
102903831d35Sstevel {
103003831d35Sstevel #ifdef lint
103103831d35Sstevel flag = flag;
103203831d35Sstevel root = root;
103303831d35Sstevel plafh = plafh;
103403831d35Sstevel #endif
103503831d35Sstevel /*
103603831d35Sstevel * This function is intentionally empty
103703831d35Sstevel */
103803831d35Sstevel }
103903831d35Sstevel
104003831d35Sstevel void
display_boardnum(int num)104103831d35Sstevel display_boardnum(int num)
104203831d35Sstevel {
104303831d35Sstevel log_printf("%2d ", num, 0);
104403831d35Sstevel }
10450d63ce2bSvenki
1046d776656fSmb158278 static int
sun4v_disp_env_status()10470d63ce2bSvenki sun4v_disp_env_status()
10480d63ce2bSvenki {
1049d776656fSmb158278 int exit_code = 0;
1050d776656fSmb158278
10510d63ce2bSvenki if (phyplatformh == 0)
1052d776656fSmb158278 return (0);
10530d63ce2bSvenki log_printf("\n");
10540d63ce2bSvenki log_printf("============================");
10550d63ce2bSvenki log_printf(" Environmental Status ");
10560d63ce2bSvenki log_printf("============================");
10570d63ce2bSvenki log_printf("\n");
10580d63ce2bSvenki
10590d63ce2bSvenki class_node_found = 0;
10600d63ce2bSvenki all_status_ok = 1;
10610d63ce2bSvenki sun4v_env_print_fan_sensors();
1062d776656fSmb158278 exit_code |= (!all_status_ok);
10630d63ce2bSvenki
10640d63ce2bSvenki class_node_found = 0;
10650d63ce2bSvenki all_status_ok = 1;
10660d63ce2bSvenki sun4v_env_print_fan_indicators();
1067d776656fSmb158278 exit_code |= (!all_status_ok);
10680d63ce2bSvenki
10690d63ce2bSvenki class_node_found = 0;
10700d63ce2bSvenki all_status_ok = 1;
10710d63ce2bSvenki sun4v_env_print_temp_sensors();
1072d776656fSmb158278 exit_code |= (!all_status_ok);
10730d63ce2bSvenki
10740d63ce2bSvenki class_node_found = 0;
10750d63ce2bSvenki all_status_ok = 1;
10760d63ce2bSvenki sun4v_env_print_temp_indicators();
1077d776656fSmb158278 exit_code |= (!all_status_ok);
10780d63ce2bSvenki
10790d63ce2bSvenki class_node_found = 0;
10800d63ce2bSvenki all_status_ok = 1;
10810d63ce2bSvenki sun4v_env_print_current_sensors();
1082d776656fSmb158278 exit_code |= (!all_status_ok);
10830d63ce2bSvenki
10840d63ce2bSvenki class_node_found = 0;
10850d63ce2bSvenki all_status_ok = 1;
10860d63ce2bSvenki sun4v_env_print_current_indicators();
1087d776656fSmb158278 exit_code |= (!all_status_ok);
10880d63ce2bSvenki
10890d63ce2bSvenki class_node_found = 0;
10900d63ce2bSvenki all_status_ok = 1;
10910d63ce2bSvenki sun4v_env_print_voltage_sensors();
1092d776656fSmb158278 exit_code |= (!all_status_ok);
10930d63ce2bSvenki
10940d63ce2bSvenki class_node_found = 0;
10950d63ce2bSvenki all_status_ok = 1;
10960d63ce2bSvenki sun4v_env_print_voltage_indicators();
1097d776656fSmb158278 exit_code |= (!all_status_ok);
10980d63ce2bSvenki
10990d63ce2bSvenki class_node_found = 0;
1100d776656fSmb158278 all_status_ok = 1;
11010d63ce2bSvenki sun4v_env_print_LEDs();
1102d776656fSmb158278 exit_code |= (!all_status_ok);
11030d63ce2bSvenki
11040d63ce2bSvenki class_node_found = 0;
11050d63ce2bSvenki all_status_ok = 1;
11060d63ce2bSvenki sun4v_print_fru_status();
1107d776656fSmb158278 exit_code |= (!all_status_ok);
11080d63ce2bSvenki
11090d63ce2bSvenki class_node_found = 0;
11100d63ce2bSvenki sun4v_print_fw_rev();
11110d63ce2bSvenki
1112dc6ca969Sfw157321 class_node_found = 0;
1113dc6ca969Sfw157321 sun4v_print_openprom_rev();
1114dc6ca969Sfw157321
11150d63ce2bSvenki sun4v_print_chassis_serial_no();
1116d776656fSmb158278
1117d776656fSmb158278 return (exit_code);
11180d63ce2bSvenki }
11190d63ce2bSvenki
11200d63ce2bSvenki /*ARGSUSED*/
11210d63ce2bSvenki static int
sun4v_env_print_sensor_callback(picl_nodehdl_t nodeh,void * args)11220d63ce2bSvenki sun4v_env_print_sensor_callback(picl_nodehdl_t nodeh, void *args)
11230d63ce2bSvenki {
11240d63ce2bSvenki char val[PICL_PROPNAMELEN_MAX];
11250d63ce2bSvenki picl_nodehdl_t parenth;
11260d63ce2bSvenki char *names[PARENT_NAMES];
1127aaba19e2Sfw157321 char *base_units[PICL_PROPNAMELEN_MAX];
11280d63ce2bSvenki char *loc;
11290d63ce2bSvenki int i;
11300d63ce2bSvenki char *prop;
11310d63ce2bSvenki picl_errno_t err;
1132dc6ca969Sfw157321 int32_t lo_warning, lo_shutdown, lo_poweroff;
1133dc6ca969Sfw157321 int32_t hi_warning, hi_shutdown, hi_poweroff;
11340d63ce2bSvenki int32_t current_val;
1135aaba19e2Sfw157321 int32_t exponent;
1136aaba19e2Sfw157321 double display_val;
1137a42ff480Sfw157321 typedef enum {SENSOR_OK, SENSOR_WARN, SENSOR_FAILED,
1138a42ff480Sfw157321 SENSOR_DISABLED, SENSOR_UNKNOWN} sensor_status_t;
1139a42ff480Sfw157321 sensor_status_t sensor_status = SENSOR_OK;
11400d63ce2bSvenki
11410d63ce2bSvenki if (class_node_found == 0) {
11420d63ce2bSvenki class_node_found = 1;
11430d63ce2bSvenki return (PICL_WALK_TERMINATE);
11440d63ce2bSvenki }
11450d63ce2bSvenki
1146a42ff480Sfw157321 prop = (char *)args;
1147a42ff480Sfw157321 if (!prop) {
1148a42ff480Sfw157321 sensor_status = SENSOR_UNKNOWN;
1149a42ff480Sfw157321 all_status_ok = 0;
1150a42ff480Sfw157321 } else {
11510d63ce2bSvenki err = picl_get_propval_by_name(nodeh,
11520d63ce2bSvenki PICL_PROP_OPERATIONAL_STATUS, val,
11530d63ce2bSvenki sizeof (val));
11540d63ce2bSvenki if (err == PICL_SUCCESS) {
11550d63ce2bSvenki if (strcmp(val, "disabled") == 0) {
1156a42ff480Sfw157321 sensor_status = SENSOR_DISABLED;
11570d63ce2bSvenki }
11580d63ce2bSvenki }
11590d63ce2bSvenki }
11604c5e0fdeSvivek
1161a42ff480Sfw157321 if (sensor_status != SENSOR_DISABLED &&
1162a42ff480Sfw157321 sensor_status != SENSOR_UNKNOWN) {
11630d63ce2bSvenki if (picl_get_propval_by_name(nodeh, prop, ¤t_val,
11640d63ce2bSvenki sizeof (current_val)) != PICL_SUCCESS) {
1165a42ff480Sfw157321 sensor_status = SENSOR_UNKNOWN;
1166dc6ca969Sfw157321 } else {
1167dc6ca969Sfw157321 if (picl_get_propval_by_name(nodeh,
1168dc6ca969Sfw157321 PICL_PROP_LOW_WARNING,
11690d63ce2bSvenki &lo_warning, sizeof (lo_warning)) != PICL_SUCCESS)
11700d63ce2bSvenki lo_warning = INVALID_THRESHOLD;
1171dc6ca969Sfw157321 if (picl_get_propval_by_name(nodeh,
1172dc6ca969Sfw157321 PICL_PROP_LOW_SHUTDOWN,
11730d63ce2bSvenki &lo_shutdown, sizeof (lo_shutdown)) != PICL_SUCCESS)
11740d63ce2bSvenki lo_shutdown = INVALID_THRESHOLD;
1175dc6ca969Sfw157321 if (picl_get_propval_by_name(nodeh,
1176dc6ca969Sfw157321 PICL_PROP_LOW_POWER_OFF,
1177dc6ca969Sfw157321 &lo_poweroff, sizeof (lo_poweroff)) != PICL_SUCCESS)
1178dc6ca969Sfw157321 lo_poweroff = INVALID_THRESHOLD;
1179dc6ca969Sfw157321 if (picl_get_propval_by_name(nodeh,
1180dc6ca969Sfw157321 PICL_PROP_HIGH_WARNING,
11810d63ce2bSvenki &hi_warning, sizeof (hi_warning)) != PICL_SUCCESS)
11820d63ce2bSvenki hi_warning = INVALID_THRESHOLD;
1183dc6ca969Sfw157321 if (picl_get_propval_by_name(nodeh,
1184dc6ca969Sfw157321 PICL_PROP_HIGH_SHUTDOWN,
11850d63ce2bSvenki &hi_shutdown, sizeof (hi_shutdown)) != PICL_SUCCESS)
11860d63ce2bSvenki hi_shutdown = INVALID_THRESHOLD;
1187dc6ca969Sfw157321 if (picl_get_propval_by_name(nodeh,
1188dc6ca969Sfw157321 PICL_PROP_HIGH_POWER_OFF,
1189dc6ca969Sfw157321 &hi_poweroff, sizeof (hi_poweroff)) != PICL_SUCCESS)
1190dc6ca969Sfw157321 hi_poweroff = INVALID_THRESHOLD;
11910d63ce2bSvenki
1192dc6ca969Sfw157321 if ((lo_poweroff != INVALID_THRESHOLD &&
1193dc6ca969Sfw157321 current_val <= lo_poweroff) ||
1194dc6ca969Sfw157321 (hi_poweroff != INVALID_THRESHOLD &&
1195dc6ca969Sfw157321 current_val >= hi_poweroff)) {
1196dc6ca969Sfw157321 sensor_status = SENSOR_FAILED;
1197dc6ca969Sfw157321 } else if ((lo_shutdown != INVALID_THRESHOLD &&
11980d63ce2bSvenki current_val <= lo_shutdown) ||
11990d63ce2bSvenki (hi_shutdown != INVALID_THRESHOLD &&
12000d63ce2bSvenki current_val >= hi_shutdown)) {
1201a42ff480Sfw157321 sensor_status = SENSOR_FAILED;
12020d63ce2bSvenki } else if ((lo_warning != INVALID_THRESHOLD &&
12030d63ce2bSvenki current_val <= lo_warning) ||
12040d63ce2bSvenki (hi_warning != INVALID_THRESHOLD &&
12050d63ce2bSvenki current_val >= hi_warning)) {
1206a42ff480Sfw157321 sensor_status = SENSOR_WARN;
12070d63ce2bSvenki } else {
1208a42ff480Sfw157321 sensor_status = SENSOR_OK;
1209a42ff480Sfw157321 }
1210a42ff480Sfw157321 }
1211dc6ca969Sfw157321 }
1212a42ff480Sfw157321
1213a42ff480Sfw157321 if (syserrlog == 0) {
1214a42ff480Sfw157321 if (sensor_status != SENSOR_OK && all_status_ok == 1) {
12150d63ce2bSvenki all_status_ok = 0;
12160d63ce2bSvenki return (PICL_WALK_TERMINATE);
12170d63ce2bSvenki }
1218a42ff480Sfw157321 if (sensor_status == SENSOR_OK) {
1219a42ff480Sfw157321 return (PICL_WALK_CONTINUE);
12200d63ce2bSvenki }
12217ae8c7a8SMichael Bergknoff } else {
12227ae8c7a8SMichael Bergknoff if (sensor_status != SENSOR_OK && all_status_ok == 1) {
12237ae8c7a8SMichael Bergknoff all_status_ok = 0;
12247ae8c7a8SMichael Bergknoff }
1225a42ff480Sfw157321 }
1226a42ff480Sfw157321
1227a42ff480Sfw157321 /*
1228a42ff480Sfw157321 * If we're here then prtdiag was invoked with "-v" or we have
1229a42ff480Sfw157321 * a sensor that is beyond a threshold, so give them a book to
1230a42ff480Sfw157321 * read instead of the Cliff Notes.
1231a42ff480Sfw157321 */
12320d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth,
12330d63ce2bSvenki sizeof (parenth));
12340d63ce2bSvenki if (err != PICL_SUCCESS) {
12350d63ce2bSvenki log_printf("\n");
12360d63ce2bSvenki return (PICL_WALK_CONTINUE);
12370d63ce2bSvenki }
1238a42ff480Sfw157321
1239a42ff480Sfw157321 /* gather up the path name for the sensor */
1240a42ff480Sfw157321 if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) != NULL) {
1241a42ff480Sfw157321 for (i = 0; i < PARENT_NAMES; i++) {
1242a42ff480Sfw157321 if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) ==
1243a42ff480Sfw157321 NULL) {
12440d63ce2bSvenki while (--i > -1)
12450d63ce2bSvenki free(names[i]);
12460d63ce2bSvenki free(loc);
1247a42ff480Sfw157321 loc = NULL;
1248a42ff480Sfw157321 }
1249a42ff480Sfw157321 }
12500d63ce2bSvenki }
12510d63ce2bSvenki i = 0;
1252a42ff480Sfw157321 if (loc != 0) {
12530d63ce2bSvenki while (err == PICL_SUCCESS) {
1254aaba19e2Sfw157321 if (parenth == phyplatformh)
12550d63ce2bSvenki break;
12560d63ce2bSvenki err = picl_get_propval_by_name(parenth, PICL_PROP_NAME,
12570d63ce2bSvenki names[i++], PICL_PROPNAMELEN_MAX);
12580d63ce2bSvenki if (err != PICL_SUCCESS) {
12590d63ce2bSvenki i--;
12600d63ce2bSvenki break;
12610d63ce2bSvenki }
12620d63ce2bSvenki if (i == PARENT_NAMES)
12630d63ce2bSvenki break;
1264a42ff480Sfw157321 err = picl_get_propval_by_name(parenth,
1265a42ff480Sfw157321 PICL_PROP_PARENT, &parenth, sizeof (parenth));
12660d63ce2bSvenki }
12670d63ce2bSvenki loc[0] = '\0';
12684c5e0fdeSvivek if (--i > -1) {
12694c5e0fdeSvivek (void) strlcat(loc, names[i],
12704c5e0fdeSvivek PICL_PROPNAMELEN_MAX * PARENT_NAMES);
12714c5e0fdeSvivek }
12720d63ce2bSvenki while (--i > -1) {
1273a42ff480Sfw157321 (void) strlcat(loc, "/", PICL_PROPNAMELEN_MAX *
1274a42ff480Sfw157321 PARENT_NAMES);
12754c5e0fdeSvivek (void) strlcat(loc, names[i],
12764c5e0fdeSvivek PICL_PROPNAMELEN_MAX * PARENT_NAMES);
12770d63ce2bSvenki }
12785e3e415aSfw157321 log_printf("%-35s", loc);
12790d63ce2bSvenki for (i = 0; i < PARENT_NAMES; i++)
12800d63ce2bSvenki free(names[i]);
12810d63ce2bSvenki free(loc);
1282a42ff480Sfw157321 } else {
12835e3e415aSfw157321 log_printf("%-35s", " ");
1284a42ff480Sfw157321 }
12850d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, val,
12860d63ce2bSvenki sizeof (val));
12870d63ce2bSvenki if (err == PICL_SUCCESS)
1288bbda49b5SSree Vemuri log_printf("%-19s", val);
1289a42ff480Sfw157321
1290a42ff480Sfw157321 /*
1291a42ff480Sfw157321 * Get the exponent if present, and do a little math so that
1292a42ff480Sfw157321 * if we need to we can print a normalized value for the
1293a42ff480Sfw157321 * sensor reading.
1294a42ff480Sfw157321 */
1295a42ff480Sfw157321 if (picl_get_propval_by_name(nodeh, PICL_PROP_EXPONENT,
1296a42ff480Sfw157321 &exponent, sizeof (exponent)) != PICL_SUCCESS)
1297a42ff480Sfw157321 exponent = 0;
1298a42ff480Sfw157321 if (exponent == 0)
1299a42ff480Sfw157321 display_val = (double)current_val;
1300dc6ca969Sfw157321 else {
1301a42ff480Sfw157321 display_val = (double)current_val *
1302a42ff480Sfw157321 pow((double)10, (double)exponent);
1303dc6ca969Sfw157321
1304dc6ca969Sfw157321 /*
1305dc6ca969Sfw157321 * Sometimes ILOM will scale a sensor reading but
1306dc6ca969Sfw157321 * there will be nothing to the right of the decimal
1307dc6ca969Sfw157321 * once that value is normalized. Setting the
1308dc6ca969Sfw157321 * exponent to zero will prevent the printf below
1309dc6ca969Sfw157321 * from printing extraneous zeros. Otherwise a
1310dc6ca969Sfw157321 * negative exponent is used to set the precision
1311dc6ca969Sfw157321 * for the printf.
1312dc6ca969Sfw157321 */
1313dc6ca969Sfw157321 if ((int)display_val == display_val || exponent > 0)
1314dc6ca969Sfw157321 exponent = 0;
1315dc6ca969Sfw157321 }
1316dc6ca969Sfw157321
1317a42ff480Sfw157321 err = picl_get_propval_by_name(nodeh, PICL_PROP_BASE_UNITS,
1318a42ff480Sfw157321 base_units, sizeof (base_units));
1319a42ff480Sfw157321 if (err != PICL_SUCCESS)
1320a42ff480Sfw157321 base_units[0] = '\0';
1321a42ff480Sfw157321
1322a42ff480Sfw157321 switch (sensor_status) {
1323a42ff480Sfw157321 case SENSOR_FAILED:
1324a42ff480Sfw157321 log_printf("%-s", "failed (");
1325a42ff480Sfw157321 log_printf("%-.*f", abs(exponent), display_val);
1326a42ff480Sfw157321 log_printf("%-s %s", base_units, ")");
1327a42ff480Sfw157321 break;
1328a42ff480Sfw157321 case SENSOR_WARN:
1329a42ff480Sfw157321 log_printf("%-s", "warning (");
1330a42ff480Sfw157321 log_printf("%-.*f", abs(exponent), display_val);
1331a42ff480Sfw157321 log_printf("%-s %s", base_units, ")");
1332a42ff480Sfw157321 break;
1333a42ff480Sfw157321 case SENSOR_DISABLED:
1334a42ff480Sfw157321 log_printf("%-s", "disabled");
1335a42ff480Sfw157321 break;
1336a42ff480Sfw157321 case SENSOR_OK:
1337a42ff480Sfw157321 log_printf("%-s", "ok");
1338a42ff480Sfw157321 break;
1339a42ff480Sfw157321 default:
1340a42ff480Sfw157321 log_printf("%-s", "unknown");
1341a42ff480Sfw157321 break;
1342a42ff480Sfw157321 }
1343a42ff480Sfw157321
1344a42ff480Sfw157321 log_printf("\n");
13450d63ce2bSvenki return (PICL_WALK_CONTINUE);
13460d63ce2bSvenki }
1347a42ff480Sfw157321
1348a42ff480Sfw157321 /*ARGSUSED*/
1349a42ff480Sfw157321 static int
sun4v_env_print_indicator_callback(picl_nodehdl_t nodeh,void * args)1350a42ff480Sfw157321 sun4v_env_print_indicator_callback(picl_nodehdl_t nodeh, void *args)
1351a42ff480Sfw157321 {
1352a42ff480Sfw157321 char current_val[PICL_PROPNAMELEN_MAX];
1353a42ff480Sfw157321 char expected_val[PICL_PROPNAMELEN_MAX];
1354a42ff480Sfw157321 char label[PICL_PROPNAMELEN_MAX];
1355a42ff480Sfw157321 picl_nodehdl_t parenth;
1356a42ff480Sfw157321 char *names[PARENT_NAMES];
1357a42ff480Sfw157321 char *loc;
1358a42ff480Sfw157321 int i = 0;
1359a42ff480Sfw157321 char *prop = (char *)args;
1360a42ff480Sfw157321 picl_errno_t err = PICL_SUCCESS;
1361a42ff480Sfw157321 typedef enum {SENSOR_OK, SENSOR_WARN, SENSOR_FAILED,
1362a42ff480Sfw157321 SENSOR_DISABLED, SENSOR_UNKNOWN} sensor_status_t;
1363a42ff480Sfw157321 sensor_status_t sensor_status = SENSOR_OK;
1364a42ff480Sfw157321
1365a42ff480Sfw157321 if (class_node_found == 0) {
1366a42ff480Sfw157321 class_node_found = 1;
1367a42ff480Sfw157321 return (PICL_WALK_TERMINATE);
1368a42ff480Sfw157321 }
1369a42ff480Sfw157321
1370a42ff480Sfw157321 prop = (char *)args;
1371a42ff480Sfw157321 if (!prop) {
1372a42ff480Sfw157321 sensor_status = SENSOR_UNKNOWN;
1373a42ff480Sfw157321 all_status_ok = 0;
1374a42ff480Sfw157321 } else {
1375a42ff480Sfw157321 err = picl_get_propval_by_name(nodeh,
1376a42ff480Sfw157321 PICL_PROP_OPERATIONAL_STATUS, current_val,
1377a42ff480Sfw157321 sizeof (current_val));
1378a42ff480Sfw157321 if (err == PICL_SUCCESS) {
1379a42ff480Sfw157321 if (strcmp(current_val, "disabled") == 0) {
1380a42ff480Sfw157321 sensor_status = SENSOR_DISABLED;
1381a42ff480Sfw157321 }
1382a42ff480Sfw157321 }
1383a42ff480Sfw157321 }
1384a42ff480Sfw157321
1385a42ff480Sfw157321 if (sensor_status != SENSOR_DISABLED &&
1386a42ff480Sfw157321 sensor_status != SENSOR_UNKNOWN) {
1387a42ff480Sfw157321 if (picl_get_propval_by_name(nodeh, prop, ¤t_val,
1388a42ff480Sfw157321 sizeof (current_val)) != PICL_SUCCESS) {
1389a42ff480Sfw157321 (void) strlcpy(current_val, "unknown",
1390a42ff480Sfw157321 sizeof (current_val));
1391a42ff480Sfw157321 sensor_status = SENSOR_UNKNOWN;
1392a42ff480Sfw157321 } else {
1393a42ff480Sfw157321 if (picl_get_propval_by_name(nodeh, PICL_PROP_EXPECTED,
13947ae8c7a8SMichael Bergknoff &expected_val, sizeof (expected_val)) ==
1395a42ff480Sfw157321 PICL_SUCCESS) {
1396a42ff480Sfw157321 if (strncmp(current_val, expected_val,
1397a42ff480Sfw157321 sizeof (current_val)) == 0) {
1398a42ff480Sfw157321 sensor_status = SENSOR_OK;
1399a42ff480Sfw157321 } else {
1400a42ff480Sfw157321 sensor_status = SENSOR_FAILED;
1401a42ff480Sfw157321 }
1402a42ff480Sfw157321 }
1403a42ff480Sfw157321 }
1404a42ff480Sfw157321 }
1405a42ff480Sfw157321
1406a42ff480Sfw157321 if (syserrlog == 0) {
1407a42ff480Sfw157321 if (sensor_status != SENSOR_OK && all_status_ok == 1) {
1408a42ff480Sfw157321 all_status_ok = 0;
1409a42ff480Sfw157321 return (PICL_WALK_TERMINATE);
1410a42ff480Sfw157321 }
1411a42ff480Sfw157321 if (sensor_status == SENSOR_OK) {
1412a42ff480Sfw157321 return (PICL_WALK_CONTINUE);
1413a42ff480Sfw157321 }
14147ae8c7a8SMichael Bergknoff } else {
14157ae8c7a8SMichael Bergknoff if (sensor_status != SENSOR_OK && all_status_ok == 1) {
14167ae8c7a8SMichael Bergknoff all_status_ok = 0;
14177ae8c7a8SMichael Bergknoff }
1418a42ff480Sfw157321 }
1419a42ff480Sfw157321
1420a42ff480Sfw157321 /*
1421a42ff480Sfw157321 * If we're here then prtdiag was invoked with "-v" or we have
1422a42ff480Sfw157321 * a sensor that is beyond a threshold, so give them a book to
1423a42ff480Sfw157321 * read instead of the Cliff Notes.
1424a42ff480Sfw157321 */
1425a42ff480Sfw157321 err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth,
1426a42ff480Sfw157321 sizeof (parenth));
1427a42ff480Sfw157321 if (err != PICL_SUCCESS) {
1428a42ff480Sfw157321 log_printf("\n");
1429a42ff480Sfw157321 return (PICL_WALK_CONTINUE);
1430a42ff480Sfw157321 }
1431a42ff480Sfw157321 if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) != NULL) {
1432a42ff480Sfw157321 for (i = 0; i < PARENT_NAMES; i++) {
1433a42ff480Sfw157321 if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) ==
1434a42ff480Sfw157321 NULL) {
1435a42ff480Sfw157321 while (--i > -1)
1436a42ff480Sfw157321 free(names[i]);
1437a42ff480Sfw157321 free(loc);
1438a42ff480Sfw157321 loc = NULL;
1439a42ff480Sfw157321 }
1440a42ff480Sfw157321 }
1441a42ff480Sfw157321 }
1442a42ff480Sfw157321 i = 0;
1443a42ff480Sfw157321 if (loc) {
1444a42ff480Sfw157321 while (err == PICL_SUCCESS) {
1445a42ff480Sfw157321 if (parenth == phyplatformh)
1446a42ff480Sfw157321 break;
1447a42ff480Sfw157321 err = picl_get_propval_by_name(parenth, PICL_PROP_NAME,
1448a42ff480Sfw157321 names[i++], PICL_PROPNAMELEN_MAX);
1449a42ff480Sfw157321 if (err != PICL_SUCCESS) {
1450a42ff480Sfw157321 i--;
1451a42ff480Sfw157321 break;
1452a42ff480Sfw157321 }
1453a42ff480Sfw157321 if (i == PARENT_NAMES)
1454a42ff480Sfw157321 break;
1455a42ff480Sfw157321 err = picl_get_propval_by_name(parenth,
1456a42ff480Sfw157321 PICL_PROP_PARENT, &parenth, sizeof (parenth));
1457a42ff480Sfw157321 }
1458a42ff480Sfw157321 loc[0] = '\0';
1459a42ff480Sfw157321 if (--i > -1) {
1460a42ff480Sfw157321 (void) strlcat(loc, names[i],
1461a42ff480Sfw157321 PICL_PROPNAMELEN_MAX * PARENT_NAMES);
1462a42ff480Sfw157321 }
1463a42ff480Sfw157321 while (--i > -1) {
1464a42ff480Sfw157321 (void) strlcat(loc, "/", PICL_PROPNAMELEN_MAX *
1465a42ff480Sfw157321 PARENT_NAMES);
1466a42ff480Sfw157321 (void) strlcat(loc, names[i],
1467a42ff480Sfw157321 PICL_PROPNAMELEN_MAX * PARENT_NAMES);
1468a42ff480Sfw157321 }
14695e3e415aSfw157321 log_printf("%-35s", loc);
1470a42ff480Sfw157321 for (i = 0; i < PARENT_NAMES; i++)
1471a42ff480Sfw157321 free(names[i]);
1472a42ff480Sfw157321 free(loc);
1473a42ff480Sfw157321 } else {
14745e3e415aSfw157321 log_printf("%-35s", "");
1475a42ff480Sfw157321 }
1476a42ff480Sfw157321
1477a42ff480Sfw157321 err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, label,
1478a42ff480Sfw157321 sizeof (label));
1479a42ff480Sfw157321 if (err != PICL_SUCCESS)
1480a42ff480Sfw157321 (void) strlcpy(label, "", sizeof (label));
1481bbda49b5SSree Vemuri log_printf("%-19s", label);
1482a42ff480Sfw157321
1483a42ff480Sfw157321 log_printf("%-8s", current_val);
1484a42ff480Sfw157321
14850d63ce2bSvenki log_printf("\n");
14860d63ce2bSvenki return (PICL_WALK_CONTINUE);
14870d63ce2bSvenki }
14880d63ce2bSvenki
14890d63ce2bSvenki static void
sun4v_env_print_fan_sensors()14900d63ce2bSvenki sun4v_env_print_fan_sensors()
14910d63ce2bSvenki {
1492bbda49b5SSree Vemuri char *fmt = "%-34s %-18s %-10s\n";
14930d63ce2bSvenki /*
14940d63ce2bSvenki * If there isn't any fan sensor node, return now.
14950d63ce2bSvenki */
14960d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
1497a42ff480Sfw157321 PICL_CLASS_RPM_SENSOR, (void *)PICL_PROP_SPEED,
14980d63ce2bSvenki sun4v_env_print_sensor_callback);
14990d63ce2bSvenki if (!class_node_found)
15000d63ce2bSvenki return;
15010d63ce2bSvenki log_printf("Fan sensors:\n");
15020d63ce2bSvenki if (syserrlog == 0) {
15030d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
15040d63ce2bSvenki PICL_CLASS_RPM_SENSOR,
1505a42ff480Sfw157321 PICL_PROP_SPEED, sun4v_env_print_sensor_callback);
15060d63ce2bSvenki if (all_status_ok) {
15070d63ce2bSvenki log_printf("All fan sensors are OK.\n");
15080d63ce2bSvenki return;
15090d63ce2bSvenki }
15100d63ce2bSvenki }
15115e3e415aSfw157321 log_printf("-------------------------------------------------"
1512bbda49b5SSree Vemuri "---------------\n");
15130d63ce2bSvenki log_printf(fmt, "Location", "Sensor", "Status", 0);
15145e3e415aSfw157321 log_printf("-------------------------------------------------"
1515bbda49b5SSree Vemuri "---------------\n");
15160d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_RPM_SENSOR,
15170d63ce2bSvenki PICL_PROP_SPEED, sun4v_env_print_sensor_callback);
15180d63ce2bSvenki }
15190d63ce2bSvenki
15200d63ce2bSvenki static void
sun4v_env_print_fan_indicators()15210d63ce2bSvenki sun4v_env_print_fan_indicators()
15220d63ce2bSvenki {
1523bbda49b5SSree Vemuri char *fmt = "%-34s %-18s %-10s\n";
15240d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
1525a42ff480Sfw157321 PICL_CLASS_RPM_INDICATOR, (void *)PICL_PROP_CONDITION,
15260d63ce2bSvenki sun4v_env_print_indicator_callback);
15270d63ce2bSvenki if (!class_node_found)
15280d63ce2bSvenki return;
15290d63ce2bSvenki log_printf("\nFan indicators:\n");
15300d63ce2bSvenki if (syserrlog == 0) {
15310d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
15320d63ce2bSvenki PICL_CLASS_RPM_INDICATOR,
1533a42ff480Sfw157321 (void *)PICL_PROP_CONDITION,
1534a42ff480Sfw157321 sun4v_env_print_indicator_callback);
15350d63ce2bSvenki if (all_status_ok) {
15360d63ce2bSvenki log_printf("All fan indicators are OK.\n");
15370d63ce2bSvenki return;
15380d63ce2bSvenki }
15390d63ce2bSvenki }
15405e3e415aSfw157321 log_printf("-------------------------------------------------"
1541bbda49b5SSree Vemuri "---------------\n");
15420d63ce2bSvenki log_printf(fmt, "Location", "Sensor", "Condition", 0);
15435e3e415aSfw157321 log_printf("-------------------------------------------------"
1544bbda49b5SSree Vemuri "---------------\n");
15450d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_RPM_INDICATOR,
1546aaba19e2Sfw157321 (void *)PICL_PROP_CONDITION, sun4v_env_print_indicator_callback);
15470d63ce2bSvenki }
15480d63ce2bSvenki
15490d63ce2bSvenki static void
sun4v_env_print_temp_sensors()15500d63ce2bSvenki sun4v_env_print_temp_sensors()
15510d63ce2bSvenki {
1552bbda49b5SSree Vemuri char *fmt = "%-34s %-18s %-10s\n";
15530d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
15540d63ce2bSvenki PICL_CLASS_TEMPERATURE_SENSOR,
15550d63ce2bSvenki (void *)PICL_PROP_TEMPERATURE,
15560d63ce2bSvenki sun4v_env_print_sensor_callback);
15570d63ce2bSvenki if (!class_node_found)
15580d63ce2bSvenki return;
15590d63ce2bSvenki
15600d63ce2bSvenki log_printf("\nTemperature sensors:\n");
15610d63ce2bSvenki if (syserrlog == 0) {
15620d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
15630d63ce2bSvenki PICL_CLASS_TEMPERATURE_SENSOR,
1564a42ff480Sfw157321 PICL_PROP_TEMPERATURE, sun4v_env_print_sensor_callback);
15650d63ce2bSvenki if (all_status_ok) {
15660d63ce2bSvenki log_printf("All temperature sensors are OK.\n");
15670d63ce2bSvenki return;
15680d63ce2bSvenki }
15690d63ce2bSvenki }
15705e3e415aSfw157321 log_printf("-------------------------------------------------"
1571bbda49b5SSree Vemuri "---------------\n");
15720d63ce2bSvenki log_printf(fmt, "Location", "Sensor", "Status", 0);
15735e3e415aSfw157321 log_printf("-------------------------------------------------"
1574bbda49b5SSree Vemuri "---------------\n");
15750d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
15760d63ce2bSvenki PICL_CLASS_TEMPERATURE_SENSOR,
15770d63ce2bSvenki (void *)PICL_PROP_TEMPERATURE, sun4v_env_print_sensor_callback);
15780d63ce2bSvenki }
15790d63ce2bSvenki
15800d63ce2bSvenki static void
sun4v_env_print_temp_indicators()15810d63ce2bSvenki sun4v_env_print_temp_indicators()
15820d63ce2bSvenki {
1583bbda49b5SSree Vemuri char *fmt = "%-34s %-18s %-8s\n";
15840d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
15850d63ce2bSvenki PICL_CLASS_TEMPERATURE_INDICATOR, (void *)PICL_PROP_CONDITION,
15860d63ce2bSvenki sun4v_env_print_indicator_callback);
15870d63ce2bSvenki if (!class_node_found)
15880d63ce2bSvenki return;
15890d63ce2bSvenki log_printf("\nTemperature indicators:\n");
15900d63ce2bSvenki if (syserrlog == 0) {
15910d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
1592a42ff480Sfw157321 PICL_CLASS_TEMPERATURE_INDICATOR,
1593a42ff480Sfw157321 (void *)PICL_PROP_CONDITION,
15940d63ce2bSvenki sun4v_env_print_indicator_callback);
15950d63ce2bSvenki if (all_status_ok) {
15960d63ce2bSvenki log_printf("All temperature indicators are OK.\n");
15970d63ce2bSvenki return;
15980d63ce2bSvenki }
15990d63ce2bSvenki }
16005e3e415aSfw157321 log_printf("-------------------------------------------------"
1601bbda49b5SSree Vemuri "---------------\n");
16020d63ce2bSvenki log_printf(fmt, "Location", "Indicator", "Condition", 0);
16035e3e415aSfw157321 log_printf("-------------------------------------------------"
1604bbda49b5SSree Vemuri "---------------\n");
16050d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
16060d63ce2bSvenki PICL_CLASS_TEMPERATURE_INDICATOR,
16070d63ce2bSvenki (void *)PICL_PROP_CONDITION,
16080d63ce2bSvenki sun4v_env_print_indicator_callback);
16090d63ce2bSvenki }
16100d63ce2bSvenki
16110d63ce2bSvenki static void
sun4v_env_print_current_sensors()16120d63ce2bSvenki sun4v_env_print_current_sensors()
16130d63ce2bSvenki {
1614bbda49b5SSree Vemuri char *fmt = "%-34s %-18s %-10s\n";
16150d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_CURRENT_SENSOR,
16160d63ce2bSvenki (void *)PICL_PROP_CURRENT, sun4v_env_print_sensor_callback);
16170d63ce2bSvenki if (!class_node_found)
16180d63ce2bSvenki return;
16190d63ce2bSvenki log_printf("\nCurrent sensors:\n");
16200d63ce2bSvenki if (syserrlog == 0) {
16210d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
16220d63ce2bSvenki PICL_CLASS_CURRENT_SENSOR,
1623a42ff480Sfw157321 PICL_PROP_CURRENT, sun4v_env_print_sensor_callback);
16240d63ce2bSvenki if (all_status_ok) {
16250d63ce2bSvenki log_printf("All current sensors are OK.\n");
16260d63ce2bSvenki return;
16270d63ce2bSvenki }
16280d63ce2bSvenki }
16295e3e415aSfw157321 log_printf("-------------------------------------------------"
1630bbda49b5SSree Vemuri "---------------\n");
16310d63ce2bSvenki log_printf(fmt, "Location", "Sensor", "Status", 0);
16325e3e415aSfw157321 log_printf("-------------------------------------------------"
1633bbda49b5SSree Vemuri "---------------\n");
16340d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
16350d63ce2bSvenki PICL_CLASS_CURRENT_SENSOR, (void *)PICL_PROP_CURRENT,
16360d63ce2bSvenki sun4v_env_print_sensor_callback);
16370d63ce2bSvenki }
16380d63ce2bSvenki
16390d63ce2bSvenki static void
sun4v_env_print_current_indicators()16400d63ce2bSvenki sun4v_env_print_current_indicators()
16410d63ce2bSvenki {
1642bbda49b5SSree Vemuri char *fmt = "%-34s %-18s %-8s\n";
16430d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
16440d63ce2bSvenki PICL_CLASS_CURRENT_INDICATOR,
16450d63ce2bSvenki (void *)PICL_PROP_CONDITION,
16460d63ce2bSvenki sun4v_env_print_indicator_callback);
16470d63ce2bSvenki if (!class_node_found)
16480d63ce2bSvenki return;
16490d63ce2bSvenki log_printf("\nCurrent indicators:\n");
16500d63ce2bSvenki if (syserrlog == 0) {
16510d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
1652a42ff480Sfw157321 PICL_CLASS_CURRENT_INDICATOR, (void *)PICL_PROP_CONDITION,
16530d63ce2bSvenki sun4v_env_print_indicator_callback);
16540d63ce2bSvenki if (all_status_ok) {
16550d63ce2bSvenki log_printf("All current indicators are OK.\n");
16560d63ce2bSvenki return;
16570d63ce2bSvenki }
16580d63ce2bSvenki }
16595e3e415aSfw157321 log_printf("-------------------------------------------------"
1660bbda49b5SSree Vemuri "---------------\n");
16610d63ce2bSvenki log_printf(fmt, "Location", "Indicator", "Condition", 0);
16625e3e415aSfw157321 log_printf("-------------------------------------------------"
1663bbda49b5SSree Vemuri "---------------\n");
16640d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
16650d63ce2bSvenki PICL_CLASS_CURRENT_INDICATOR,
16660d63ce2bSvenki (void *)PICL_PROP_CONDITION,
16670d63ce2bSvenki sun4v_env_print_indicator_callback);
16680d63ce2bSvenki }
16690d63ce2bSvenki
16700d63ce2bSvenki static void
sun4v_env_print_voltage_sensors()16710d63ce2bSvenki sun4v_env_print_voltage_sensors()
16720d63ce2bSvenki {
1673bbda49b5SSree Vemuri char *fmt = "%-34s %-18s %-10s\n";
16740d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
16750d63ce2bSvenki PICL_CLASS_VOLTAGE_SENSOR,
16760d63ce2bSvenki PICL_PROP_VOLTAGE,
16770d63ce2bSvenki sun4v_env_print_sensor_callback);
16780d63ce2bSvenki if (!class_node_found)
16790d63ce2bSvenki return;
16800d63ce2bSvenki log_printf("\nVoltage sensors:\n");
16810d63ce2bSvenki if (syserrlog == 0) {
16820d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
16830d63ce2bSvenki PICL_CLASS_VOLTAGE_SENSOR,
1684a42ff480Sfw157321 PICL_PROP_VOLTAGE, sun4v_env_print_sensor_callback);
16850d63ce2bSvenki if (all_status_ok) {
16860d63ce2bSvenki log_printf("All voltage sensors are OK.\n");
16870d63ce2bSvenki return;
16880d63ce2bSvenki }
16890d63ce2bSvenki }
16905e3e415aSfw157321 log_printf("-------------------------------------------------"
1691bbda49b5SSree Vemuri "---------------\n");
16920d63ce2bSvenki log_printf(fmt, "Location", "Sensor", "Status", 0);
16935e3e415aSfw157321 log_printf("-------------------------------------------------"
1694bbda49b5SSree Vemuri "---------------\n");
16950d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
16960d63ce2bSvenki PICL_CLASS_VOLTAGE_SENSOR,
16970d63ce2bSvenki (void *)PICL_PROP_VOLTAGE,
16980d63ce2bSvenki sun4v_env_print_sensor_callback);
16990d63ce2bSvenki }
17000d63ce2bSvenki
17010d63ce2bSvenki static void
sun4v_env_print_voltage_indicators()17020d63ce2bSvenki sun4v_env_print_voltage_indicators()
17030d63ce2bSvenki {
1704bbda49b5SSree Vemuri char *fmt = "%-34s %-18s %-8s\n";
17050d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
17060d63ce2bSvenki PICL_CLASS_VOLTAGE_INDICATOR,
17070d63ce2bSvenki (void *)PICL_PROP_CONDITION,
17080d63ce2bSvenki sun4v_env_print_indicator_callback);
17090d63ce2bSvenki if (!class_node_found)
17100d63ce2bSvenki return;
17110d63ce2bSvenki log_printf("\nVoltage indicators:\n");
17120d63ce2bSvenki if (syserrlog == 0) {
17130d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
1714a42ff480Sfw157321 PICL_CLASS_VOLTAGE_INDICATOR, (void *)PICL_PROP_CONDITION,
17150d63ce2bSvenki sun4v_env_print_indicator_callback);
17160d63ce2bSvenki if (all_status_ok) {
17170d63ce2bSvenki log_printf("All voltage indicators are OK.\n");
17180d63ce2bSvenki return;
17190d63ce2bSvenki }
17200d63ce2bSvenki }
17215e3e415aSfw157321 log_printf("-------------------------------------------------"
1722bbda49b5SSree Vemuri "---------------\n");
17230d63ce2bSvenki log_printf(fmt, "Location", "Indicator", "Condition", 0);
17245e3e415aSfw157321 log_printf("-------------------------------------------------"
1725bbda49b5SSree Vemuri "---------------\n");
17260d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
17270d63ce2bSvenki PICL_CLASS_VOLTAGE_INDICATOR,
17280d63ce2bSvenki (void *)PICL_PROP_CONDITION,
17290d63ce2bSvenki sun4v_env_print_indicator_callback);
17300d63ce2bSvenki }
17310d63ce2bSvenki
17320d63ce2bSvenki static void
sun4v_env_print_LEDs()17330d63ce2bSvenki sun4v_env_print_LEDs()
17340d63ce2bSvenki {
1735bbda49b5SSree Vemuri char *fmt = "%-34s %-18s %-8s\n";
17360d63ce2bSvenki if (syserrlog == 0)
17370d63ce2bSvenki return;
17380d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_LED,
17390d63ce2bSvenki (void *)PICL_PROP_STATE, sun4v_env_print_indicator_callback);
17400d63ce2bSvenki if (!class_node_found)
17410d63ce2bSvenki return;
17420d63ce2bSvenki log_printf("\nLEDs:\n");
17435e3e415aSfw157321 log_printf("-------------------------------------------------"
1744bbda49b5SSree Vemuri "---------------\n");
17450d63ce2bSvenki log_printf(fmt, "Location", "LED", "State", 0);
17465e3e415aSfw157321 log_printf("-------------------------------------------------"
1747bbda49b5SSree Vemuri "---------------\n");
17480d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh, PICL_CLASS_LED,
17490d63ce2bSvenki (void *)PICL_PROP_STATE, sun4v_env_print_indicator_callback);
17500d63ce2bSvenki }
17510d63ce2bSvenki
17520d63ce2bSvenki /*ARGSUSED*/
17530d63ce2bSvenki static int
sun4v_print_fru_status_callback(picl_nodehdl_t nodeh,void * args)17540d63ce2bSvenki sun4v_print_fru_status_callback(picl_nodehdl_t nodeh, void *args)
17550d63ce2bSvenki {
17560d63ce2bSvenki char label[PICL_PROPNAMELEN_MAX];
17570d63ce2bSvenki char status[PICL_PROPNAMELEN_MAX];
17580d63ce2bSvenki picl_errno_t err;
17590d63ce2bSvenki picl_prophdl_t proph;
17600d63ce2bSvenki picl_nodehdl_t parenth;
17610d63ce2bSvenki char *names[PARENT_NAMES];
17620d63ce2bSvenki char *loc;
17630d63ce2bSvenki int i;
17640d63ce2bSvenki
17650d63ce2bSvenki if (!class_node_found) {
17660d63ce2bSvenki class_node_found = 1;
17670d63ce2bSvenki return (PICL_WALK_TERMINATE);
17680d63ce2bSvenki }
17690d63ce2bSvenki err = picl_get_prop_by_name(nodeh, PICL_PROP_IS_FRU, &proph);
17700d63ce2bSvenki if (err != PICL_SUCCESS)
17710d63ce2bSvenki return (PICL_WALK_CONTINUE);
17720d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_LABEL, label,
17730d63ce2bSvenki sizeof (label));
17740d63ce2bSvenki if (err != PICL_SUCCESS)
17750d63ce2bSvenki return (PICL_WALK_CONTINUE);
17760d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_OPERATIONAL_STATUS,
17770d63ce2bSvenki status, sizeof (status));
17780d63ce2bSvenki if (err != PICL_SUCCESS)
17790d63ce2bSvenki return (PICL_WALK_CONTINUE);
17800d63ce2bSvenki if (syserrlog == 0) {
17810d63ce2bSvenki if (strcmp(status, "disabled") == 0) {
17820d63ce2bSvenki if (all_status_ok) {
17830d63ce2bSvenki all_status_ok = 0;
17840d63ce2bSvenki return (PICL_WALK_TERMINATE);
17850d63ce2bSvenki }
17860d63ce2bSvenki } else
17870d63ce2bSvenki return (PICL_WALK_CONTINUE);
17887ae8c7a8SMichael Bergknoff } else {
17897ae8c7a8SMichael Bergknoff if (all_status_ok && (strcmp(status, "disabled") == 0)) {
17907ae8c7a8SMichael Bergknoff all_status_ok = 0;
17917ae8c7a8SMichael Bergknoff }
17920d63ce2bSvenki }
17938a31bd2bSBirva Shah
17948a31bd2bSBirva Shah if (is_fru_absent(nodeh))
17958a31bd2bSBirva Shah strcpy(status, "Not present");
17968a31bd2bSBirva Shah
17970d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT, &parenth,
17980d63ce2bSvenki sizeof (parenth));
17990d63ce2bSvenki if (err != PICL_SUCCESS) {
18000d63ce2bSvenki log_printf("\n");
18010d63ce2bSvenki return (PICL_WALK_CONTINUE);
18020d63ce2bSvenki }
18030d63ce2bSvenki if ((loc = (char *)malloc(PICL_PROPNAMELEN_MAX*PARENT_NAMES)) == NULL)
18040d63ce2bSvenki return (PICL_WALK_TERMINATE);
18050d63ce2bSvenki for (i = 0; i < PARENT_NAMES; i++)
18060d63ce2bSvenki if ((names[i] = (char *)malloc(PICL_PROPNAMELEN_MAX)) == NULL) {
18070d63ce2bSvenki while (--i > -1)
18080d63ce2bSvenki free(names[i]);
18090d63ce2bSvenki free(loc);
18100d63ce2bSvenki return (PICL_WALK_TERMINATE);
18110d63ce2bSvenki }
18120d63ce2bSvenki i = 0;
18130d63ce2bSvenki while (err == PICL_SUCCESS) {
1814aaba19e2Sfw157321 if (parenth == phyplatformh)
18150d63ce2bSvenki break;
18160d63ce2bSvenki err = picl_get_propval_by_name(parenth, PICL_PROP_NAME,
18170d63ce2bSvenki names[i++], PICL_PROPNAMELEN_MAX);
18180d63ce2bSvenki if (err != PICL_SUCCESS) {
18190d63ce2bSvenki i--;
18200d63ce2bSvenki break;
18210d63ce2bSvenki }
18220d63ce2bSvenki if (i == PARENT_NAMES)
18230d63ce2bSvenki break;
18240d63ce2bSvenki err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT,
18250d63ce2bSvenki &parenth, sizeof (parenth));
18260d63ce2bSvenki }
18270d63ce2bSvenki loc[0] = '\0';
18284c5e0fdeSvivek if (--i > -1) {
18294c5e0fdeSvivek (void) strlcat(loc, names[i],
18304c5e0fdeSvivek PICL_PROPNAMELEN_MAX * PARENT_NAMES);
18314c5e0fdeSvivek }
18320d63ce2bSvenki while (--i > -1) {
18334c5e0fdeSvivek (void) strlcat(loc, "/", PICL_PROPNAMELEN_MAX * PARENT_NAMES);
18344c5e0fdeSvivek (void) strlcat(loc, names[i],
18354c5e0fdeSvivek PICL_PROPNAMELEN_MAX * PARENT_NAMES);
18360d63ce2bSvenki }
18375e3e415aSfw157321 log_printf("%-35s", loc);
18380d63ce2bSvenki for (i = 0; i < PARENT_NAMES; i++)
18390d63ce2bSvenki free(names[i]);
18400d63ce2bSvenki free(loc);
18410d63ce2bSvenki log_printf("%-10s", label);
18420d63ce2bSvenki log_printf("%-9s", status);
18430d63ce2bSvenki log_printf("\n");
18440d63ce2bSvenki return (PICL_WALK_CONTINUE);
18450d63ce2bSvenki }
18460d63ce2bSvenki
18470d63ce2bSvenki static void
sun4v_print_fru_status()18480d63ce2bSvenki sun4v_print_fru_status()
18490d63ce2bSvenki {
18505e3e415aSfw157321 char *fmt = "%-34s %-9s %-8s\n";
1851dc6ca969Sfw157321
18520d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh, NULL, NULL,
18530d63ce2bSvenki sun4v_print_fru_status_callback);
18540d63ce2bSvenki if (!class_node_found)
18550d63ce2bSvenki return;
1856dc6ca969Sfw157321
18570d63ce2bSvenki log_printf("\n");
18580d63ce2bSvenki log_printf("============================");
18590d63ce2bSvenki log_printf(" FRU Status ");
18600d63ce2bSvenki log_printf("============================");
18610d63ce2bSvenki log_printf("\n");
18620d63ce2bSvenki
18630d63ce2bSvenki if (syserrlog == 0) {
18640d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh,
1865aaba19e2Sfw157321 NULL, NULL,
18660d63ce2bSvenki sun4v_print_fru_status_callback);
18670d63ce2bSvenki if (all_status_ok) {
18680d63ce2bSvenki log_printf("All FRUs are enabled.\n");
18690d63ce2bSvenki return;
18700d63ce2bSvenki }
18710d63ce2bSvenki }
18720d63ce2bSvenki log_printf(fmt, "Location", "Name", "Status", 0);
18735e3e415aSfw157321 log_printf("------------------------------------------------------\n");
1874aaba19e2Sfw157321 (void) picl_walk_tree_by_class(phyplatformh, NULL, NULL,
18750d63ce2bSvenki sun4v_print_fru_status_callback);
18760d63ce2bSvenki }
18770d63ce2bSvenki
18788a31bd2bSBirva Shah /* Check the children of the FRU node for a presence indicator */
18798a31bd2bSBirva Shah static int
is_fru_absent(picl_nodehdl_t fruh)18808a31bd2bSBirva Shah is_fru_absent(picl_nodehdl_t fruh)
18818a31bd2bSBirva Shah {
18828a31bd2bSBirva Shah char class [PICL_CLASSNAMELEN_MAX];
18838a31bd2bSBirva Shah char condition [PICL_PROPNAMELEN_MAX];
18848a31bd2bSBirva Shah picl_errno_t err;
18858a31bd2bSBirva Shah picl_nodehdl_t nodeh;
18868a31bd2bSBirva Shah
18878a31bd2bSBirva Shah err = picl_get_propval_by_name(fruh, PICL_PROP_CHILD, &nodeh,
18888a31bd2bSBirva Shah sizeof (picl_nodehdl_t));
18898a31bd2bSBirva Shah while (err == PICL_SUCCESS) {
18908a31bd2bSBirva Shah err = picl_get_propval_by_name(nodeh,
18918a31bd2bSBirva Shah PICL_PROP_CLASSNAME, class, sizeof (class));
18928a31bd2bSBirva Shah if (err == PICL_SUCCESS &&
18938a31bd2bSBirva Shah strcmp(class, "presence-indicator") == 0) {
18948a31bd2bSBirva Shah err = picl_get_propval_by_name(nodeh,
18958a31bd2bSBirva Shah PICL_PROP_CONDITION, condition,
18968a31bd2bSBirva Shah sizeof (condition));
18978a31bd2bSBirva Shah if (err == PICL_SUCCESS) {
18988a31bd2bSBirva Shah if (strcmp(condition, "Absent") == 0) {
18998a31bd2bSBirva Shah return (1);
19008a31bd2bSBirva Shah } else {
19018a31bd2bSBirva Shah return (0);
19028a31bd2bSBirva Shah }
19038a31bd2bSBirva Shah }
19048a31bd2bSBirva Shah }
19058a31bd2bSBirva Shah err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER,
19068a31bd2bSBirva Shah &nodeh, sizeof (picl_nodehdl_t));
19078a31bd2bSBirva Shah }
19088a31bd2bSBirva Shah return (0);
19098a31bd2bSBirva Shah }
19108a31bd2bSBirva Shah
19110d63ce2bSvenki /*ARGSUSED*/
19120d63ce2bSvenki static int
sun4v_print_fw_rev_callback(picl_nodehdl_t nodeh,void * args)19130d63ce2bSvenki sun4v_print_fw_rev_callback(picl_nodehdl_t nodeh, void *args)
19140d63ce2bSvenki {
19150d63ce2bSvenki char rev[PICL_PROPNAMELEN_MAX];
19160d63ce2bSvenki picl_errno_t err;
19170d63ce2bSvenki
19180d63ce2bSvenki if (!class_node_found) {
19190d63ce2bSvenki class_node_found = 1;
19200d63ce2bSvenki return (PICL_WALK_TERMINATE);
19210d63ce2bSvenki }
1922dc6ca969Sfw157321
19230d63ce2bSvenki err = picl_get_propval_by_name(nodeh, PICL_PROP_FW_REVISION, rev,
19240d63ce2bSvenki sizeof (rev));
19250d63ce2bSvenki if (err != PICL_SUCCESS)
19260d63ce2bSvenki return (PICL_WALK_CONTINUE);
19270d63ce2bSvenki if (strlen(rev) == 0)
19280d63ce2bSvenki return (PICL_WALK_CONTINUE);
1929dc6ca969Sfw157321 log_printf("%s", rev);
19300d63ce2bSvenki log_printf("\n");
19310d63ce2bSvenki return (PICL_WALK_CONTINUE);
19320d63ce2bSvenki }
19330d63ce2bSvenki
19340d63ce2bSvenki static void
sun4v_print_fw_rev()19350d63ce2bSvenki sun4v_print_fw_rev()
19360d63ce2bSvenki {
19370d63ce2bSvenki if (syserrlog == 0)
19380d63ce2bSvenki return;
1939dc6ca969Sfw157321
19400d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh, NULL, NULL,
19410d63ce2bSvenki sun4v_print_fw_rev_callback);
19420d63ce2bSvenki if (!class_node_found)
19430d63ce2bSvenki return;
1944dc6ca969Sfw157321
19450d63ce2bSvenki log_printf("\n");
19460d63ce2bSvenki log_printf("============================");
19470d63ce2bSvenki log_printf(" FW Version ");
19480d63ce2bSvenki log_printf("============================");
19490d63ce2bSvenki log_printf("\n");
1950dc6ca969Sfw157321 log_printf("Version\n");
19515e3e415aSfw157321 log_printf("-------------------------------------------------"
19525e3e415aSfw157321 "-----------\n");
19530d63ce2bSvenki (void) picl_walk_tree_by_class(phyplatformh, NULL, NULL,
19540d63ce2bSvenki sun4v_print_fw_rev_callback);
19550d63ce2bSvenki }
19560d63ce2bSvenki
19570d63ce2bSvenki static void
sun4v_print_openprom_rev()1958dc6ca969Sfw157321 sun4v_print_openprom_rev()
1959dc6ca969Sfw157321 {
1960dc6ca969Sfw157321 if (syserrlog == 0)
1961dc6ca969Sfw157321 return;
1962dc6ca969Sfw157321
1963dc6ca969Sfw157321 (void) picl_walk_tree_by_class(rooth, "openprom", NULL,
1964dc6ca969Sfw157321 openprom_callback);
1965dc6ca969Sfw157321 if (!class_node_found)
1966dc6ca969Sfw157321 return;
1967dc6ca969Sfw157321
1968dc6ca969Sfw157321 log_printf("\n");
1969dc6ca969Sfw157321 log_printf("======================");
1970dc6ca969Sfw157321 log_printf(" System PROM revisions ");
1971dc6ca969Sfw157321 log_printf("=======================");
1972dc6ca969Sfw157321 log_printf("\n");
1973dc6ca969Sfw157321 log_printf("Version\n");
1974dc6ca969Sfw157321 log_printf("-------------------------------------------------"
1975dc6ca969Sfw157321 "-----------\n");
1976dc6ca969Sfw157321 (void) picl_walk_tree_by_class(rooth, "openprom", NULL,
1977dc6ca969Sfw157321 openprom_callback);
1978dc6ca969Sfw157321 }
1979dc6ca969Sfw157321
1980dc6ca969Sfw157321 /*
1981dc6ca969Sfw157321 * display the OBP and POST prom revisions (if present)
1982dc6ca969Sfw157321 */
1983dc6ca969Sfw157321 /* ARGSUSED */
1984dc6ca969Sfw157321 static int
openprom_callback(picl_nodehdl_t openpromh,void * arg)1985dc6ca969Sfw157321 openprom_callback(picl_nodehdl_t openpromh, void *arg)
1986dc6ca969Sfw157321 {
1987dc6ca969Sfw157321 picl_prophdl_t proph;
1988dc6ca969Sfw157321 picl_prophdl_t tblh;
1989dc6ca969Sfw157321 picl_prophdl_t rowproph;
1990dc6ca969Sfw157321 picl_propinfo_t pinfo;
1991dc6ca969Sfw157321 char *prom_version = NULL;
1992dc6ca969Sfw157321 char *obp_version = NULL;
1993dc6ca969Sfw157321 int err;
1994dc6ca969Sfw157321
1995dc6ca969Sfw157321 if (!class_node_found) {
1996dc6ca969Sfw157321 class_node_found = 1;
1997dc6ca969Sfw157321 return (PICL_WALK_TERMINATE);
1998dc6ca969Sfw157321 }
1999dc6ca969Sfw157321
2000dc6ca969Sfw157321 err = picl_get_propinfo_by_name(openpromh, OBP_PROP_VERSION,
2001dc6ca969Sfw157321 &pinfo, &proph);
2002dc6ca969Sfw157321 if (err == PICL_PROPNOTFOUND)
2003dc6ca969Sfw157321 return (PICL_WALK_TERMINATE);
2004dc6ca969Sfw157321 else if (err != PICL_SUCCESS)
2005dc6ca969Sfw157321 return (err);
2006dc6ca969Sfw157321
2007dc6ca969Sfw157321 /*
2008dc6ca969Sfw157321 * If it's a table prop, the first element is OBP revision
2009dc6ca969Sfw157321 * The second one is POST revision.
2010dc6ca969Sfw157321 * If it's a charstring prop, the value will be only OBP revision
2011dc6ca969Sfw157321 */
2012dc6ca969Sfw157321 if (pinfo.type == PICL_PTYPE_CHARSTRING) {
2013dc6ca969Sfw157321 prom_version = (char *)alloca(pinfo.size);
2014dc6ca969Sfw157321 if (prom_version == NULL)
2015dc6ca969Sfw157321 return (PICL_FAILURE);
2016dc6ca969Sfw157321 err = picl_get_propval(proph, prom_version, pinfo.size);
2017dc6ca969Sfw157321 if (err != PICL_SUCCESS)
2018dc6ca969Sfw157321 return (err);
2019dc6ca969Sfw157321 log_printf("%s\n", prom_version);
2020dc6ca969Sfw157321 }
2021dc6ca969Sfw157321
2022dc6ca969Sfw157321 if (pinfo.type != PICL_PTYPE_TABLE) /* not supported type */
2023dc6ca969Sfw157321 return (PICL_WALK_TERMINATE);
2024dc6ca969Sfw157321
2025dc6ca969Sfw157321 err = picl_get_propval(proph, &tblh, pinfo.size);
2026dc6ca969Sfw157321 if (err != PICL_SUCCESS)
2027dc6ca969Sfw157321 return (err);
2028dc6ca969Sfw157321
2029dc6ca969Sfw157321 err = picl_get_next_by_row(tblh, &rowproph);
2030dc6ca969Sfw157321 if (err == PICL_SUCCESS) {
2031dc6ca969Sfw157321 /* get first row */
2032dc6ca969Sfw157321 err = picl_get_propinfo(rowproph, &pinfo);
2033dc6ca969Sfw157321 if (err != PICL_SUCCESS)
2034dc6ca969Sfw157321 return (err);
2035dc6ca969Sfw157321
2036dc6ca969Sfw157321 prom_version = (char *)alloca(pinfo.size);
2037dc6ca969Sfw157321 if (prom_version == NULL)
2038dc6ca969Sfw157321 return (PICL_FAILURE);
2039dc6ca969Sfw157321
2040dc6ca969Sfw157321 err = picl_get_propval(rowproph, prom_version, pinfo.size);
2041dc6ca969Sfw157321 if (err != PICL_SUCCESS)
2042dc6ca969Sfw157321 return (err);
2043dc6ca969Sfw157321 log_printf("%s\n", prom_version);
2044dc6ca969Sfw157321
2045dc6ca969Sfw157321 /* get second row */
2046dc6ca969Sfw157321 err = picl_get_next_by_col(rowproph, &rowproph);
2047dc6ca969Sfw157321 if (err == PICL_SUCCESS) {
2048dc6ca969Sfw157321 err = picl_get_propinfo(rowproph, &pinfo);
2049dc6ca969Sfw157321 if (err != PICL_SUCCESS)
2050dc6ca969Sfw157321 return (err);
2051dc6ca969Sfw157321
2052dc6ca969Sfw157321 obp_version = (char *)alloca(pinfo.size);
2053dc6ca969Sfw157321 if (obp_version == NULL)
2054dc6ca969Sfw157321 return (PICL_FAILURE);
2055dc6ca969Sfw157321 err = picl_get_propval(rowproph, obp_version,
2056dc6ca969Sfw157321 pinfo.size);
2057dc6ca969Sfw157321 if (err != PICL_SUCCESS)
2058dc6ca969Sfw157321 return (err);
2059dc6ca969Sfw157321 log_printf("%s\n", obp_version);
2060dc6ca969Sfw157321 }
2061dc6ca969Sfw157321 }
2062dc6ca969Sfw157321
2063dc6ca969Sfw157321 return (PICL_WALK_TERMINATE);
2064dc6ca969Sfw157321 }
2065dc6ca969Sfw157321
2066dc6ca969Sfw157321 static void
sun4v_print_chassis_serial_no()20670d63ce2bSvenki sun4v_print_chassis_serial_no()
20680d63ce2bSvenki {
20690d63ce2bSvenki char val[PICL_PROPNAMELEN_MAX];
20700d63ce2bSvenki picl_errno_t err;
20710d63ce2bSvenki if (syserrlog == 0 || chassish == 0)
20720d63ce2bSvenki return;
20730d63ce2bSvenki
20740d63ce2bSvenki log_printf("\n");
20751cf6ec7eSsuha log_printf("Chassis Serial Number");
20760d63ce2bSvenki log_printf("\n");
20770d63ce2bSvenki log_printf("---------------------\n");
20780d63ce2bSvenki err = picl_get_propval_by_name(chassish, PICL_PROP_SERIAL_NUMBER,
20790d63ce2bSvenki val, sizeof (val));
20800d63ce2bSvenki if (err == PICL_SUCCESS)
20810d63ce2bSvenki log_printf("%s", val);
20820d63ce2bSvenki log_printf("\n");
20830d63ce2bSvenki }
2084