103831d35Sstevel /*
203831d35Sstevel  * CDDL HEADER START
303831d35Sstevel  *
403831d35Sstevel  * The contents of this file are subject to the terms of the
5e79c98e6Szk  * Common Development and Distribution License (the "License").
6e79c98e6Szk  * 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 /*
22e79c98e6Szk  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
2303831d35Sstevel  * Use is subject to license terms.
24*2bcbf80cSPeter Tribble  * Copyright 2020 Peter Tribble.
2503831d35Sstevel  */
2603831d35Sstevel 
2703831d35Sstevel /*
2803831d35Sstevel  * Daktari Platform specific functions.
2903831d35Sstevel  *
30*2bcbf80cSPeter Tribble  *	called when :
3103831d35Sstevel  *      machine_type ==  MTYPE_DAKTARI
3203831d35Sstevel  *
3303831d35Sstevel  */
3403831d35Sstevel 
3503831d35Sstevel #include <stdio.h>
3603831d35Sstevel #include <stdlib.h>
3703831d35Sstevel #include <unistd.h>
3803831d35Sstevel #include <kstat.h>
3903831d35Sstevel #include <string.h>
4003831d35Sstevel #include <assert.h>
4103831d35Sstevel #include <libintl.h>
4203831d35Sstevel #include <note.h>
4303831d35Sstevel 
4403831d35Sstevel #include <sys/openpromio.h>
4503831d35Sstevel #include <sys/sysmacros.h>
4603831d35Sstevel #include <sys/daktari.h>
4703831d35Sstevel 
4803831d35Sstevel #include <pdevinfo.h>
4903831d35Sstevel #include <display.h>
5003831d35Sstevel #include <pdevinfo_sun4u.h>
5103831d35Sstevel #include <display_sun4u.h>
5203831d35Sstevel #include <libprtdiag.h>
5303831d35Sstevel 
5403831d35Sstevel #include <picl.h>
5503831d35Sstevel #include "workfile.c"
5603831d35Sstevel 
5703831d35Sstevel #if !defined(TEXT_DOMAIN)
5803831d35Sstevel #define	TEXT_DOMAIN	"SYS_TEST"
5903831d35Sstevel #endif
6003831d35Sstevel 
6103831d35Sstevel #define	DAK_MAX_SLOTS_PER_IO_BD		9
6203831d35Sstevel #define	DAK_MAX_DISKS			12
6303831d35Sstevel #define	DAK_MAX_FSP_LEDS		2
6403831d35Sstevel #define	DAK_MAX_PS			3
6503831d35Sstevel #define	DAK_MAX_PS_VOLTAGE_SENSORS	4
6603831d35Sstevel #define	DAK_MAX_PS_FAULT_SENSORS	3
6703831d35Sstevel #define	DAK_MAX_FANS			10
6803831d35Sstevel #ifndef SCHIZO_COMPAT_PROP
6903831d35Sstevel #define	SCHIZO_COMPAT_PROP		"pci108e,8001"
7003831d35Sstevel #endif
7103831d35Sstevel 
7203831d35Sstevel #define	MULTIPLE_BITS_SET(x)		((x)&((x)-1))
7303831d35Sstevel 
7403831d35Sstevel extern	int	print_flag;
7503831d35Sstevel 
7603831d35Sstevel /*
7703831d35Sstevel  * these functions will overlay the symbol table of libprtdiag
7803831d35Sstevel  * at runtime (workgroup server systems only)
7903831d35Sstevel  */
8003831d35Sstevel void	display_cpu_devices(Sys_tree *tree);
8103831d35Sstevel void	display_cpus(Board_node *board);
8203831d35Sstevel void	display_pci(Board_node *board);
8303831d35Sstevel void	display_io_cards(struct io_card *list);
8403831d35Sstevel void	display_diaginfo(int flag, Prom_node *root, Sys_tree *tree,
8503831d35Sstevel 				struct system_kstat_data *kstats);
8603831d35Sstevel void	display_ffb(Board_node *board, int table);
87*2bcbf80cSPeter Tribble void	display_memoryconf(Sys_tree *tree);
8803831d35Sstevel 
8903831d35Sstevel /* local functions */
9003831d35Sstevel static	int disp_envc_status(void);
9103831d35Sstevel static	int dak_env_print_temps(picl_nodehdl_t);
9203831d35Sstevel static	int dak_env_print_keyswitch(picl_nodehdl_t);
9303831d35Sstevel static	int dak_env_print_FSP_LEDS(picl_nodehdl_t);
9403831d35Sstevel static	int dak_env_print_disk(picl_nodehdl_t);
9503831d35Sstevel static	int dak_env_print_fans(picl_nodehdl_t);
9603831d35Sstevel static	int dak_env_print_ps(picl_nodehdl_t);
9703831d35Sstevel 
9803831d35Sstevel static void dak_display_hw_revisions(Prom_node *root,
9903831d35Sstevel 					Board_node *bnode);
10003831d35Sstevel static void display_schizo_revisions(Board_node *bdlist);
10103831d35Sstevel 
10203831d35Sstevel 
10303831d35Sstevel /*
10403831d35Sstevel  * Defining the error_check function in order to return the
10503831d35Sstevel  * appropriate error code.
10603831d35Sstevel  */
10703831d35Sstevel /*ARGSUSED0*/
10803831d35Sstevel int
error_check(Sys_tree * tree,struct system_kstat_data * kstats)10903831d35Sstevel error_check(Sys_tree *tree, struct system_kstat_data *kstats)
11003831d35Sstevel {
11103831d35Sstevel 	int exit_code = 0;	/* init to all OK */
11203831d35Sstevel 	/*
11303831d35Sstevel 	 * silently check for any types of machine errors
11403831d35Sstevel 	 */
11503831d35Sstevel 	print_flag = 0;
11603831d35Sstevel 	if (disp_fail_parts(tree)) {
11703831d35Sstevel 		/* set exit_code to show failures */
11803831d35Sstevel 		exit_code = 1;
11903831d35Sstevel 	}
12003831d35Sstevel 	print_flag = 1;
12103831d35Sstevel 
12203831d35Sstevel 	return (exit_code);
12303831d35Sstevel }
12403831d35Sstevel 
12503831d35Sstevel /*
12603831d35Sstevel  * disp_fail_parts
12703831d35Sstevel  *
12803831d35Sstevel  * Display the failed parts in the system. This function looks for
12903831d35Sstevel  * the status property in all PROM nodes. On systems where
13003831d35Sstevel  * the PROM does not support passing diagnostic information
13103831d35Sstevel  * through the device tree, this routine will be silent.
13203831d35Sstevel  */
13303831d35Sstevel int
disp_fail_parts(Sys_tree * tree)13403831d35Sstevel disp_fail_parts(Sys_tree *tree)
13503831d35Sstevel {
13603831d35Sstevel 	int exit_code = 0;
13703831d35Sstevel 	int system_failed = 0;
13803831d35Sstevel 	Board_node *bnode = tree->bd_list;
13903831d35Sstevel 	Prom_node *pnode;
14003831d35Sstevel 
14103831d35Sstevel 	/* go through all of the boards looking for failed units. */
14203831d35Sstevel 	while (bnode != NULL) {
14303831d35Sstevel 		/* find failed chips */
14403831d35Sstevel 		pnode = find_failed_node(bnode->nodes);
14503831d35Sstevel 		if ((pnode != NULL) && !system_failed) {
14603831d35Sstevel 			system_failed = 1;
14703831d35Sstevel 			exit_code = 1;
14803831d35Sstevel 			if (print_flag == 0) {
14903831d35Sstevel 				return (exit_code);
15003831d35Sstevel 			}
15103831d35Sstevel 			log_printf("\n");
15203831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "Failed Field "
153e79c98e6Szk 			    "Replaceable Units (FRU) in System:\n"));
15403831d35Sstevel 			log_printf("=========================="
155e79c98e6Szk 			    "====================\n");
15603831d35Sstevel 		}
15703831d35Sstevel 		while (pnode != NULL) {
15803831d35Sstevel 			void *value;
15903831d35Sstevel 			char *name;		/* node name string */
16003831d35Sstevel 			char *type;		/* node type string */
16103831d35Sstevel 			char *board_type = NULL;
16203831d35Sstevel 
16303831d35Sstevel 			value = get_prop_val(find_prop(pnode, "status"));
16403831d35Sstevel 			name = get_node_name(pnode);
16503831d35Sstevel 
16603831d35Sstevel 			/* sanity check of data retrieved from PROM */
16703831d35Sstevel 			if ((value == NULL) || (name == NULL)) {
16803831d35Sstevel 				pnode = next_failed_node(pnode);
16903831d35Sstevel 				continue;
17003831d35Sstevel 			}
17103831d35Sstevel 
17203831d35Sstevel 			/* Find the board type of this board */
17303831d35Sstevel 			if (bnode->board_type == CPU_BOARD) {
17403831d35Sstevel 				board_type = "CPU";
17503831d35Sstevel 			} else {
17603831d35Sstevel 				board_type = "IO";
17703831d35Sstevel 			}
17803831d35Sstevel 
17903831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "%s unavailable "
180e79c98e6Szk 			    "on %s Board #%d\n"), name, board_type,
181e79c98e6Szk 			    bnode->board_num);
18203831d35Sstevel 
18303831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
184e79c98e6Szk 			    "\tPROM fault string: %s\n"), value);
18503831d35Sstevel 
18603831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
187e79c98e6Szk 			    "\tFailed Field Replaceable Unit is "));
18803831d35Sstevel 
18903831d35Sstevel 			/*
19003831d35Sstevel 			 * Determine whether FRU is CPU module, system
19103831d35Sstevel 			 * board, or SBus card.
19203831d35Sstevel 			 */
19303831d35Sstevel 			if ((name != NULL) && (strstr(name, "sbus"))) {
19403831d35Sstevel 
19503831d35Sstevel 				log_printf(dgettext(TEXT_DOMAIN,
196e79c98e6Szk 				    "SBus Card %d\n"),
197e79c98e6Szk 				    get_sbus_slot(pnode));
19803831d35Sstevel 
19903831d35Sstevel 			} else if (((name = get_node_name(pnode->parent)) !=
20003831d35Sstevel 			    NULL) && (strstr(name, "pci"))) {
20103831d35Sstevel 
20203831d35Sstevel 				log_printf(dgettext(TEXT_DOMAIN,
203e79c98e6Szk 				    "PCI Card %d"),
204e79c98e6Szk 				    get_pci_device(pnode));
20503831d35Sstevel 
20603831d35Sstevel 			} else if (((type = get_node_type(pnode)) != NULL) &&
20703831d35Sstevel 			    (strstr(type, "cpu"))) {
20803831d35Sstevel 
20903831d35Sstevel 				log_printf(dgettext(TEXT_DOMAIN, "UltraSPARC "
210e79c98e6Szk 				    "module Board %d Module %d\n"), 0,
211e79c98e6Szk 				    get_id(pnode));
21203831d35Sstevel 
21303831d35Sstevel 			} else {
21403831d35Sstevel 				log_printf(dgettext(TEXT_DOMAIN,
215e79c98e6Szk 				    "%s board %d\n"), board_type,
216e79c98e6Szk 				    bnode->board_num);
21703831d35Sstevel 			}
21803831d35Sstevel 			pnode = next_failed_node(pnode);
21903831d35Sstevel 		}
22003831d35Sstevel 		bnode = bnode->next;
22103831d35Sstevel 	}
22203831d35Sstevel 
22303831d35Sstevel 	if (!system_failed) {
22403831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
225e79c98e6Szk 		    "No failures found in System\n"));
22603831d35Sstevel 		log_printf("===========================\n\n");
22703831d35Sstevel 	}
22803831d35Sstevel 
22903831d35Sstevel 	if (system_failed)
23003831d35Sstevel 		return (1);
23103831d35Sstevel 	else
23203831d35Sstevel 		return (0);
23303831d35Sstevel }
23403831d35Sstevel 
23503831d35Sstevel /*ARGSUSED*/
23603831d35Sstevel void
display_hp_fail_fault(Sys_tree * tree,struct system_kstat_data * kstats)23703831d35Sstevel display_hp_fail_fault(Sys_tree *tree, struct system_kstat_data *kstats)
23803831d35Sstevel {
23903831d35Sstevel 	/* Display failed units */
24003831d35Sstevel 	(void) disp_fail_parts(tree);
24103831d35Sstevel }
24203831d35Sstevel 
24303831d35Sstevel void
display_memoryconf(Sys_tree * tree)244*2bcbf80cSPeter Tribble display_memoryconf(Sys_tree *tree)
24503831d35Sstevel {
24603831d35Sstevel 	Board_node	*bnode = tree->bd_list;
24703831d35Sstevel 
24803831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
249e79c98e6Szk 	    "========================= Memory Configuration"
250e79c98e6Szk 	    " ===============================\n"
251e79c98e6Szk 	    "\n           Logical  Logical"
252e79c98e6Szk 	    "  Logical "
253e79c98e6Szk 	    "\n      MC   Bank     Bank     Bank"
254e79c98e6Szk 	    "         DIMM    Interleave  Interleaved"
255e79c98e6Szk 	    "\n Brd  ID   num      size     "
256e79c98e6Szk 	    "Status       Size    "
257e79c98e6Szk 	    "Factor      with"
258e79c98e6Szk 	    "\n----  ---  ----     ------   "
259e79c98e6Szk 	    "-----------  ------  "
260e79c98e6Szk 	    "----------  -----------"));
26103831d35Sstevel 
26203831d35Sstevel 	while (bnode != NULL) {
26303831d35Sstevel 		if (get_us3_mem_regs(bnode)) {
26403831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
265e79c98e6Szk 			    "\nFailed to get memory information.\n"));
26603831d35Sstevel 			return;
26703831d35Sstevel 		}
26803831d35Sstevel 		bnode = bnode->next;
26903831d35Sstevel 	}
27003831d35Sstevel 
27103831d35Sstevel 	/* Display what we have found */
27203831d35Sstevel 	display_us3_banks();
27303831d35Sstevel }
27403831d35Sstevel 
27503831d35Sstevel void
display_cpu_devices(Sys_tree * tree)27603831d35Sstevel display_cpu_devices(Sys_tree *tree)
27703831d35Sstevel {
27803831d35Sstevel 	Board_node *bnode;
27903831d35Sstevel 
28003831d35Sstevel 	/*
28103831d35Sstevel 	 * Display the table header for CPUs . Then display the CPU
28203831d35Sstevel 	 * frequency, cache size, and processor revision of all cpus.
28303831d35Sstevel 	 */
28403831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
285e79c98e6Szk 	    "\n"
286e79c98e6Szk 	    "========================="
287e79c98e6Szk 	    " CPUs "
288e79c98e6Szk 	    "==============================================="
289e79c98e6Szk 	    "\n"
290e79c98e6Szk 	    "\n"
291e79c98e6Szk 	    "           Run   E$  CPU    CPU  \n"
292e79c98e6Szk 	    "Brd  CPU   MHz   MB Impl.   Mask \n"
293e79c98e6Szk 	    "--- ----- ---- ---- ------- ---- \n"));
29403831d35Sstevel 
29503831d35Sstevel 	/* Now display all of the cpus on each board */
29603831d35Sstevel 	bnode = tree->bd_list;
29703831d35Sstevel 	if (bnode == NULL) {
29803831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
299e79c98e6Szk 		    "CPU Board list was NULL\n"));
30003831d35Sstevel 	}
30103831d35Sstevel 	while (bnode != NULL) {
30203831d35Sstevel 		display_cpus(bnode);
30303831d35Sstevel 		bnode = bnode->next;
30403831d35Sstevel 	}
30503831d35Sstevel 
30603831d35Sstevel 	log_printf("\n");
30703831d35Sstevel }
30803831d35Sstevel 
30903831d35Sstevel /*
31003831d35Sstevel  * Display the CPUs present on this board.
31103831d35Sstevel  */
31203831d35Sstevel void
display_cpus(Board_node * board)31303831d35Sstevel display_cpus(Board_node *board)
31403831d35Sstevel {
31503831d35Sstevel 	Prom_node 	*cpu;
316e79c98e6Szk 	uint_t freq;	 /* CPU clock frequency */
31703831d35Sstevel 	int ecache_size; /* External cache size */
31803831d35Sstevel 	int *l3_shares;
31903831d35Sstevel 	int *mid;
32003831d35Sstevel 	int *impl;
32103831d35Sstevel 	int *mask;
32203831d35Sstevel 	int *coreid;
32303831d35Sstevel 	char fru_prev = 'X'; /* Valid frus are 'A','B','C','D' */
32403831d35Sstevel 	int mid_prev;
32503831d35Sstevel 	int ecache_size_prev = 0;
32603831d35Sstevel 	char fru_name;
32703831d35Sstevel 
32803831d35Sstevel 	/*
32903831d35Sstevel 	 * display the CPUs' operating frequency, cache size, impl. field
33003831d35Sstevel 	 * and mask revision.
33103831d35Sstevel 	 */
33203831d35Sstevel 	for (cpu = dev_find_type(board->nodes, "cpu"); cpu != NULL;
33303831d35Sstevel 	    cpu = dev_next_type(cpu, "cpu")) {
33403831d35Sstevel 
33503831d35Sstevel 		mid = (int *)get_prop_val(find_prop(cpu, "portid"));
33603831d35Sstevel 		if (mid == NULL)
33703831d35Sstevel 			mid = (int *)get_prop_val(find_prop(cpu, "cpuid"));
33803831d35Sstevel 		freq = DAK_CLK_FREQ_TO_MHZ(get_cpu_freq(cpu));
33903831d35Sstevel 		ecache_size = get_ecache_size(cpu);
34003831d35Sstevel 		impl = (int *)get_prop_val(find_prop(cpu, "implementation#"));
34103831d35Sstevel 		mask = (int *)get_prop_val(find_prop(cpu, "mask#"));
342e79c98e6Szk 		l3_shares = (int *)get_prop_val(find_prop(cpu,
343e79c98e6Szk 		    "l3-cache-sharing"));
34403831d35Sstevel 
34503831d35Sstevel 		/* Do not display a failed CPU node */
34603831d35Sstevel 		if ((impl == NULL) || (freq == 0) || (node_failed(cpu)))
34703831d35Sstevel 			continue;
34803831d35Sstevel 
34903831d35Sstevel 		/* Board number */
35003831d35Sstevel 		fru_name = (char)('A' + DAK_GETSLOT(*mid));
35103831d35Sstevel 
35203831d35Sstevel 		if (CPU_IMPL_IS_CMP(*impl)) {
35303831d35Sstevel 			coreid = (int *)get_prop_val(find_prop(cpu, "reg"));
35403831d35Sstevel 			if (coreid == NULL) {
35503831d35Sstevel 				continue;
35603831d35Sstevel 			}
35703831d35Sstevel 			if ((fru_prev == 'X') ||
358e79c98e6Szk 			    ((fru_prev != 'X') &&
359e79c98e6Szk 			    (fru_name != fru_prev))) {
36003831d35Sstevel 				fru_prev = fru_name;
36103831d35Sstevel 				mid_prev = *mid;
36203831d35Sstevel 				ecache_size_prev = ecache_size;
36303831d35Sstevel 				continue;
36403831d35Sstevel 			} else {
36503831d35Sstevel 				/*
36603831d35Sstevel 				 * Some CMP chips have a split E$,
36703831d35Sstevel 				 * so the size for both cores is added
36803831d35Sstevel 				 * together to get the total size for
36903831d35Sstevel 				 * the chip.
37003831d35Sstevel 				 *
37103831d35Sstevel 				 * Still, other CMP chips have E$ (L3)
37203831d35Sstevel 				 * which is logically shared, so the
37303831d35Sstevel 				 * total size is equal to the core size.
37403831d35Sstevel 				 */
37503831d35Sstevel 				if ((l3_shares == NULL) ||
376e79c98e6Szk 				    ((l3_shares != NULL) &&
377e79c98e6Szk 				    MULTIPLE_BITS_SET(*l3_shares))) {
37803831d35Sstevel 					ecache_size += ecache_size_prev;
37903831d35Sstevel 				}
38003831d35Sstevel 				ecache_size_prev = 0;
38103831d35Sstevel 				fru_prev = 'X';
38203831d35Sstevel 			}
38303831d35Sstevel 		}
38403831d35Sstevel 
38503831d35Sstevel 		log_printf("%2c", fru_name);
38603831d35Sstevel 
38703831d35Sstevel 		/* CPU Module ID */
38803831d35Sstevel 		if (CPU_IMPL_IS_CMP(*impl)) {
38903831d35Sstevel 			log_printf("%3d,%3d", mid_prev, *mid, 0);
39003831d35Sstevel 		} else
39103831d35Sstevel 			log_printf("    %d  ", *mid);
39203831d35Sstevel 
39303831d35Sstevel 		/* Running frequency */
394e79c98e6Szk 		log_printf(" %4u ", freq);
39503831d35Sstevel 
39603831d35Sstevel 		/* Ecache size */
39703831d35Sstevel 		if (ecache_size == 0)
39803831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "%3s  "),
39903831d35Sstevel 			    "N/A");
40003831d35Sstevel 		else
40103831d35Sstevel 			log_printf("%4.1f ",
402e79c98e6Szk 			    (float)ecache_size / (float)(1<<20));
40303831d35Sstevel 
40403831d35Sstevel 		/* Implementation */
40503831d35Sstevel 		if (impl == NULL) {
40603831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "%s    "),
40703831d35Sstevel 			"N/A");
40803831d35Sstevel 		} else {
40903831d35Sstevel 			if (IS_CHEETAH(*impl))
41003831d35Sstevel 				log_printf("%7s", "US-III ", 0);
41103831d35Sstevel 			else if (IS_CHEETAH_PLUS(*impl))
41203831d35Sstevel 				log_printf("%7s", "US-III+", 0);
41303831d35Sstevel 			else if (IS_JAGUAR(*impl))
41403831d35Sstevel 				log_printf("%7s", "US-IV  ", 0);
41503831d35Sstevel 			else if (IS_PANTHER(*impl))
41603831d35Sstevel 				log_printf("%7s", "US-IV+ ", 0);
41703831d35Sstevel 			else
41803831d35Sstevel 				log_printf("%-7x", *impl, 0);
41903831d35Sstevel 		}
42003831d35Sstevel 
42103831d35Sstevel 		/* CPU Mask */
42203831d35Sstevel 		if (mask == NULL) {
42303831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, " %3s   "),
42403831d35Sstevel 			"N/A");
42503831d35Sstevel 		} else {
42603831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, " %2d.%d"),
42703831d35Sstevel 			    (*mask >> 4) & 0xf, *mask & 0xf);
42803831d35Sstevel 		}
42903831d35Sstevel 
43003831d35Sstevel 		log_printf("\n");
43103831d35Sstevel 	}
43203831d35Sstevel }
43303831d35Sstevel 
43403831d35Sstevel /*
43503831d35Sstevel  * display_pci
43603831d35Sstevel  * Display all the PCI IO cards on this board.
43703831d35Sstevel  */
43803831d35Sstevel void
display_pci(Board_node * board)43903831d35Sstevel display_pci(Board_node *board)
44003831d35Sstevel {
44103831d35Sstevel 	struct io_card	*card_list = NULL;
44203831d35Sstevel 	struct io_card	card;
44303831d35Sstevel 	void		*value;
44403831d35Sstevel 	Prom_node	*pci;
44503831d35Sstevel 	Prom_node	*card_node;
44603831d35Sstevel 	char		*slot_name_arr[DAK_MAX_SLOTS_PER_IO_BD] = {NULL};
44703831d35Sstevel 	int		i;
44803831d35Sstevel #ifdef DEBUG
44903831d35Sstevel 	int		slot_name_bits;
45003831d35Sstevel #endif
45103831d35Sstevel 
45203831d35Sstevel 	if (board == NULL)
45303831d35Sstevel 		return;
45403831d35Sstevel 
45503831d35Sstevel 	memset(&card, 0, sizeof (struct io_card));
45603831d35Sstevel 	/* Initialize all the common information */
45703831d35Sstevel 	card.display = TRUE;
45803831d35Sstevel 	card.board = board->board_num;
45903831d35Sstevel 
46003831d35Sstevel 	/*
46103831d35Sstevel 	 * Search for each pci instance, then find/display all nodes under
46203831d35Sstevel 	 * each instance node found.
46303831d35Sstevel 	 */
46403831d35Sstevel 	for (pci = dev_find_node_by_compat(board->nodes, SCHIZO_COMPAT_PROP);
465e79c98e6Szk 	    pci != NULL;
466e79c98e6Szk 	    pci = dev_next_node_by_compat(pci, SCHIZO_COMPAT_PROP)) {
46703831d35Sstevel 		(void) snprintf(card.bus_type, MAXSTRLEN,
468e79c98e6Szk 		    dgettext(TEXT_DOMAIN, "PCI"));
46903831d35Sstevel 		/*
47003831d35Sstevel 		 * Get slot-name properties from parent node and
47103831d35Sstevel 		 * store them in an array.
47203831d35Sstevel 		 */
47303831d35Sstevel 		value = (char *)get_prop_val(
474e79c98e6Szk 		    find_prop(pci, "slot-names"));
47503831d35Sstevel 
47603831d35Sstevel 		if (value != NULL) {
47703831d35Sstevel #ifdef DEBUG
47803831d35Sstevel 			/* save the 4 byte bitmask */
47903831d35Sstevel 			slot_name_bits = *(int *)value;
48003831d35Sstevel #endif
48103831d35Sstevel 
48203831d35Sstevel 			/* array starts after first int */
48303831d35Sstevel 			slot_name_arr[0] = (char *)value + sizeof (int);
48403831d35Sstevel 			for (i = 1; i < DAK_MAX_SLOTS_PER_IO_BD; i++) {
48503831d35Sstevel 				slot_name_arr[i] = (char *)slot_name_arr[i - 1]
486e79c98e6Szk 				    + strlen(slot_name_arr[i - 1]) +1;
48703831d35Sstevel 			}
48803831d35Sstevel 		}
48903831d35Sstevel 		/*
49003831d35Sstevel 		 * Search for Children of this node ie. Cards.
49103831d35Sstevel 		 * Note: any of these cards can be a pci-bridge
49203831d35Sstevel 		 *	that itself has children. If we find a
49303831d35Sstevel 		 *	pci-bridge we need to handle it specially.
49403831d35Sstevel 		 */
49503831d35Sstevel 		card_node = pci->child;
49603831d35Sstevel 		/* Generate the list of pci cards on pci instance: pci */
49703831d35Sstevel 		fill_pci_card_list(pci, card_node, &card, &card_list,
498e79c98e6Szk 		    slot_name_arr);
49903831d35Sstevel 	} /* end-for */
50003831d35Sstevel 
50103831d35Sstevel 	display_io_cards(card_list);
50203831d35Sstevel 	free_io_cards(card_list);
50303831d35Sstevel 	log_printf("\n");
50403831d35Sstevel }
50503831d35Sstevel 
50603831d35Sstevel /*
50703831d35Sstevel  * Print out all the io cards in the list.  Also print the column
50803831d35Sstevel  * headers if told to do so.
50903831d35Sstevel  */
51003831d35Sstevel void
display_io_cards(struct io_card * list)51103831d35Sstevel display_io_cards(struct io_card *list)
51203831d35Sstevel {
51303831d35Sstevel 	static int banner = 0; /* Have we printed the column headings? */
51403831d35Sstevel 	struct io_card *p;
51503831d35Sstevel 
51603831d35Sstevel 	if (list == NULL)
51703831d35Sstevel 		return;
51803831d35Sstevel 
51903831d35Sstevel 	if (banner == FALSE) {
52003831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
521e79c98e6Szk 		    "                         Bus  Max\n"
522e79c98e6Szk 		    "     IO   Port Bus       Freq Bus  Dev,"
523e79c98e6Szk 		    "\n"
524e79c98e6Szk 		    "Brd  Type  ID  Side Slot MHz  Freq "
525e79c98e6Szk 		    "Func State Name                              "
526e79c98e6Szk 		    "Model\n"
52703831d35Sstevel 		/* ---------Brd  IO   Port Bus  Slot Bus  Max  Dev  Stat */
528e79c98e6Szk 		    "---- ---- ---- ---- ---- ---- ---- ----"
529e79c98e6Szk 		    " ----- "
530e79c98e6Szk 		    "--------------------------------  "
531e79c98e6Szk 		    "----------------------\n"));
53203831d35Sstevel 		banner = TRUE;
53303831d35Sstevel 	}
53403831d35Sstevel 
53503831d35Sstevel 	for (p = list; p != NULL; p = p -> next) {
53603831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN, "I/O  "));
53703831d35Sstevel 		log_printf("%-4s  ", p->bus_type);
53803831d35Sstevel 		log_printf("%-3d  ", p->schizo_portid);
53903831d35Sstevel 		log_printf("%c    ", p->pci_bus);
54003831d35Sstevel 		log_printf("%-1s    ", p->slot_str);
54103831d35Sstevel 		log_printf("%-3d ", p->freq);
54203831d35Sstevel 		switch (p->pci_bus) {
54303831d35Sstevel 		case 'A':
54403831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, " 66  "));
54503831d35Sstevel 			break;
54603831d35Sstevel 		case 'B':
54703831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, " 33  "));
54803831d35Sstevel 			break;
54903831d35Sstevel 		default:
55003831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "  -  "));
55103831d35Sstevel 			break;
55203831d35Sstevel 		}
55303831d35Sstevel 
55403831d35Sstevel 		log_printf("%-1d,%-1d  ", p->dev_no, p->func_no);
55503831d35Sstevel 		log_printf("%-5s ", p->status);
55603831d35Sstevel 		log_printf("%-32.32s", p->name);
55703831d35Sstevel 		if (strlen(p->name) > 32)
55803831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "+ "));
55903831d35Sstevel 		else
56003831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "  "));
56103831d35Sstevel 		log_printf("%-22.22s", p->model);
56203831d35Sstevel 		if (strlen(p->model) > 22)
56303831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "+"));
56403831d35Sstevel 
56503831d35Sstevel #ifdef DEBUG
56603831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN, "%s  "), p->notes);
56703831d35Sstevel #endif
56803831d35Sstevel 		log_printf("\n");
56903831d35Sstevel 	}
57003831d35Sstevel }
57103831d35Sstevel 
57203831d35Sstevel /*
57303831d35Sstevel  * display_ffb
57403831d35Sstevel  *
57503831d35Sstevel  * There are no FFB's on a Daktari, however in the generic library,
57603831d35Sstevel  * the display_ffb() function is implemented so we have to define an
57703831d35Sstevel  * empty function here.
57803831d35Sstevel  */
57903831d35Sstevel /* ARGSUSED */
58003831d35Sstevel void
display_ffb(Board_node * board,int table)58103831d35Sstevel display_ffb(Board_node *board, int table)
58203831d35Sstevel {}
58303831d35Sstevel 
58403831d35Sstevel 
58503831d35Sstevel /*
58603831d35Sstevel  * ----------------------------------------------------------------------------
58703831d35Sstevel  */
58803831d35Sstevel 
58903831d35Sstevel /* ARGSUSED */
59003831d35Sstevel void
display_diaginfo(int flag,Prom_node * root,Sys_tree * tree,struct system_kstat_data * kstats)59103831d35Sstevel display_diaginfo(int flag, Prom_node *root, Sys_tree *tree,
59203831d35Sstevel 	struct system_kstat_data *kstats)
59303831d35Sstevel {
59403831d35Sstevel 	/* NOTE(ARGUNUSED(kstats)) */
59503831d35Sstevel 	/*
59603831d35Sstevel 	 * Now display the last powerfail time and the fatal hardware
59703831d35Sstevel 	 * reset information. We do this under a couple of conditions.
59803831d35Sstevel 	 * First if the user asks for it. The second is if the user
59903831d35Sstevel 	 * told us to do logging, and we found a system failure.
60003831d35Sstevel 	 */
60103831d35Sstevel 	if (flag) {
60203831d35Sstevel 		/*
60303831d35Sstevel 		 * display time of latest powerfail. Not all systems
60403831d35Sstevel 		 * have this capability. For those that do not, this
60503831d35Sstevel 		 * is just a no-op.
60603831d35Sstevel 		 */
60703831d35Sstevel 		disp_powerfail(root);
60803831d35Sstevel 
60903831d35Sstevel 		(void) disp_envc_status();
61003831d35Sstevel 
61103831d35Sstevel 		/* platform_disp_prom_version(tree); */
61203831d35Sstevel 		dak_display_hw_revisions(root, tree->bd_list);
61303831d35Sstevel 	}
61403831d35Sstevel }
61503831d35Sstevel 
61603831d35Sstevel /*
61703831d35Sstevel  * local functions
61803831d35Sstevel  */
61903831d35Sstevel 
62003831d35Sstevel /*
62103831d35Sstevel  * disp_envc_status
62203831d35Sstevel  *
62303831d35Sstevel  * This routine displays the environmental status passed up from
62403831d35Sstevel  * device drivers via the envlibobj.so library.
62503831d35Sstevel  * This is a Daktari specific environmental information display routine.
62603831d35Sstevel  */
62703831d35Sstevel int
disp_envc_status()62803831d35Sstevel disp_envc_status()
62903831d35Sstevel {
63003831d35Sstevel 	int err;
63103831d35Sstevel 	char *system = "SYSTEM";
63203831d35Sstevel 	picl_nodehdl_t system_node, root;
63303831d35Sstevel 
63403831d35Sstevel 	err = picl_initialize();
63503831d35Sstevel 	if (err != PICL_SUCCESS) {
63603831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
637e79c98e6Szk 		    "picl_initialize failed\n"
638e79c98e6Szk 		    "%s\nCannot display environmental status\n"),
639e79c98e6Szk 		    picl_strerror(err));
64003831d35Sstevel 		return (err);
64103831d35Sstevel 	}
64203831d35Sstevel 	err = picl_get_root(&root);
64303831d35Sstevel 	err = find_child_device(root, system, &system_node);
64403831d35Sstevel 	if (err != PICL_SUCCESS) {
64503831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
646e79c98e6Szk 		    "picl_get_node_by_path for the SYSTEM node "
647e79c98e6Szk 		    "failed\n"
648e79c98e6Szk 		    "%s\nCannot display environmental status\n"),
649e79c98e6Szk 		    picl_strerror(err));
65003831d35Sstevel 		return (err);
65103831d35Sstevel 	}
65203831d35Sstevel 
65303831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
654e79c98e6Szk 	    "\n"
655e79c98e6Szk 	    "========================= "
656e79c98e6Szk 	    "Environmental Status "
657e79c98e6Szk 	    "========================="
658e79c98e6Szk 	    "\n"
659e79c98e6Szk 	    "\n"));
66003831d35Sstevel 
66103831d35Sstevel 	dak_env_print_temps(system_node);
66203831d35Sstevel 	dak_env_print_keyswitch(system_node);
66303831d35Sstevel 	dak_env_print_FSP_LEDS(system_node);
66403831d35Sstevel 	dak_env_print_disk(system_node);
66503831d35Sstevel 	dak_env_print_fans(system_node);
66603831d35Sstevel 	dak_env_print_ps(system_node);
66703831d35Sstevel 
66803831d35Sstevel 	(void) picl_shutdown();
66903831d35Sstevel 	return (0);
67003831d35Sstevel }
67103831d35Sstevel 
67203831d35Sstevel int
dak_env_print_ps(picl_nodehdl_t system_node)67303831d35Sstevel dak_env_print_ps(picl_nodehdl_t system_node)
67403831d35Sstevel {
67503831d35Sstevel 	int		i, r, fail, err = 0;
6768a88157cSvb 	int		low_warn_flag = 0;
67703831d35Sstevel 	int32_t		number;
67803831d35Sstevel 	char		name[PICL_PROPNAMELEN_MAX];
67903831d35Sstevel 	picl_nodehdl_t	*ps;
68003831d35Sstevel 	picl_nodehdl_t	*ps_fail[DAK_MAX_PS_FAULT_SENSORS];
68103831d35Sstevel 	picl_nodehdl_t	*ps_I_sensor[DAK_MAX_PS_VOLTAGE_SENSORS];
68203831d35Sstevel 	int32_t		volts[DAK_MAX_PS_VOLTAGE_SENSORS];
6838a88157cSvb 	int32_t		lo_warn[DAK_MAX_PS_VOLTAGE_SENSORS];
68403831d35Sstevel 	char		fault_state
685e79c98e6Szk 	    [DAK_MAX_PS_FAULT_SENSORS][PICL_PROPNAMELEN_MAX];
68603831d35Sstevel 	char		ps_state[PICL_PROPNAMELEN_MAX];
68703831d35Sstevel 	/* Printing out the Power Supply Heading information */
68803831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
689e79c98e6Szk 	    "Power Supplies:\n"
690e79c98e6Szk 	    "---------------\n"
691e79c98e6Szk 	    "                                                    "
692e79c98e6Szk 	    "Current Drain:\n"
693e79c98e6Szk 	    "Supply     Status     Fan Fail  Temp Fail  CS Fail  "
694e79c98e6Szk 	    "3.3V   5V   12V   48V\n"
695e79c98e6Szk 	    "------  ------------  --------  ---------  "
696e79c98e6Szk 	    "-------  ----   --   ---   ---\n"));
69703831d35Sstevel 
69803831d35Sstevel 	err = fill_device_array_from_id(system_node, "PSVC_PS", &number,
69903831d35Sstevel 	    &ps);
70003831d35Sstevel 	if (err != PICL_SUCCESS) {
70103831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
702e79c98e6Szk 		    "failed in fill_device_array_from_id for PS\n"
703e79c98e6Szk 		    "%s\n"), picl_strerror(err));
70403831d35Sstevel 		return (err);
70503831d35Sstevel 	}
70603831d35Sstevel 	/* Printing out the Power Supply Status information */
70703831d35Sstevel 	for (i = 0; i < DAK_MAX_PS; i++) {
70803831d35Sstevel 		/*
70903831d35Sstevel 		 * Re initialize the fail variable so that if
71003831d35Sstevel 		 * one power supply fails, they don't all do also.
71103831d35Sstevel 		 */
71203831d35Sstevel 		fail = 0;
71303831d35Sstevel 
71403831d35Sstevel 		err = picl_get_propval_by_name(ps[i], PICL_PROP_NAME, name,
71503831d35Sstevel 		    PICL_PROPNAMELEN_MAX);
71603831d35Sstevel 		if (err != PICL_SUCCESS) {
71703831d35Sstevel 			continue;
71803831d35Sstevel 		}
71903831d35Sstevel 		err = picl_get_propval_by_name(ps[i], "State", ps_state,
720e79c98e6Szk 		    PICL_PROPNAMELEN_MAX);
72103831d35Sstevel 		if (err != PICL_SUCCESS) {
72203831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
723e79c98e6Szk 			    "Error getting ps[%d]'s state: %s"),
724e79c98e6Szk 			    i, picl_strerror(err));
72503831d35Sstevel 		}
72603831d35Sstevel 
72703831d35Sstevel 		err = fill_device_array_from_id(ps[i], "PSVC_DEV_FAULT_SENSOR",
728e79c98e6Szk 		    &number, &ps_fail[i]);
72903831d35Sstevel 
73003831d35Sstevel 		if (err != PICL_SUCCESS) {
73103831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
732e79c98e6Szk 			    "failed to get present PS fault sensors\n"
733e79c98e6Szk 			    "%s\n"), picl_strerror(err));
73403831d35Sstevel 			return (err);
73503831d35Sstevel 		}
73603831d35Sstevel 
73703831d35Sstevel 		err = fill_device_array_from_id(ps[i], "PSVC_PS_I_SENSOR",
73803831d35Sstevel 		    &number, &ps_I_sensor[i]);
73903831d35Sstevel 
74003831d35Sstevel 		if ((err != PICL_SUCCESS) && (err != PICL_INVALIDHANDLE)) {
74103831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
742e79c98e6Szk 			    "failed to get present PS I sensors\n"
743e79c98e6Szk 			    "%s\n"), picl_strerror(err));
74403831d35Sstevel 		}
74503831d35Sstevel 
74603831d35Sstevel 		log_printf("%s", name);
74703831d35Sstevel 
74803831d35Sstevel 		/*
74903831d35Sstevel 		 * If the AC cord is unplugged, then the power supply
75003831d35Sstevel 		 * sensors will have unreliable values.  In this case,
75103831d35Sstevel 		 * skip to the next power supply.
75203831d35Sstevel 		 */
75303831d35Sstevel 		if (strcmp(ps_state, "HOTPLUGGED") == 0) {
75403831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
75503831d35Sstevel 			    "      UNPLUGGED\n"));
75603831d35Sstevel 			continue;
75703831d35Sstevel 		}
75803831d35Sstevel 
75903831d35Sstevel 		for (r = 0; r < DAK_MAX_PS_FAULT_SENSORS; r++) {
76003831d35Sstevel 			err = picl_get_propval_by_name(ps_fail[i][r], "State",
761e79c98e6Szk 			    fault_state[r], PICL_PROPNAMELEN_MAX);
76203831d35Sstevel 			if (err == PICL_SUCCESS) {
76303831d35Sstevel 				fail =
76403831d35Sstevel 				    strcmp(fault_state[r], "OFF")
76503831d35Sstevel 				    + fail;
76603831d35Sstevel 			} else {
76703831d35Sstevel 				log_printf(dgettext(TEXT_DOMAIN,
768e79c98e6Szk 				    "picl_get_propval_by_name for ps "
769e79c98e6Szk 				    "fault state failed\n"
770e79c98e6Szk 				    "%s\n"), picl_strerror(err));
77103831d35Sstevel 				return (err);
77203831d35Sstevel 			}
77303831d35Sstevel 		}
77403831d35Sstevel 		for (r = 0; r < DAK_MAX_PS_VOLTAGE_SENSORS; r++) {
77503831d35Sstevel 			err = picl_get_propval_by_name(ps_I_sensor[i][r],
776e79c98e6Szk 			    "AtoDSensorValue", &volts[r],
777e79c98e6Szk 			    sizeof (int32_t));
7788a88157cSvb 			if (err != PICL_SUCCESS) {
7798a88157cSvb 				log_printf(dgettext(TEXT_DOMAIN,
7808a88157cSvb 				    "failed to get A to D sensor "
7818a88157cSvb 				    "value\n%s\n"), picl_strerror(err));
7828a88157cSvb 				return (err);
7838a88157cSvb 			}
7848a88157cSvb 			err = picl_get_propval_by_name(ps_I_sensor[i][r],
7858a88157cSvb 			    "LowWarningThreshold", &lo_warn[r],
7868a88157cSvb 			    sizeof (int32_t));
7878a88157cSvb 			if (err != PICL_SUCCESS) {
7888a88157cSvb 				log_printf(dgettext(TEXT_DOMAIN,
7898a88157cSvb 				    "failed to get low warning threshold "
7908a88157cSvb 				    "value\n%s\n"), picl_strerror(err));
7918a88157cSvb 				return (err);
7928a88157cSvb 			}
7938a88157cSvb 			if (volts[r] <= lo_warn[r])
7948a88157cSvb 				low_warn_flag++;
79503831d35Sstevel 		}
79603831d35Sstevel 
7978a88157cSvb 		if (fail != 0 || low_warn_flag != 0) {
79803831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
79903831d35Sstevel 			    "      FAIL      "));
8008a88157cSvb 		} else {
8018a88157cSvb 			log_printf(dgettext(TEXT_DOMAIN, "      GOOD      "));
8028a88157cSvb 		}
8038a88157cSvb 
8048a88157cSvb 		if (fail != 0) {
80503831d35Sstevel 			for (r = 0; r < DAK_MAX_PS_FAULT_SENSORS; r++) {
80603831d35Sstevel 				log_printf(dgettext(TEXT_DOMAIN, "      %-4s"),
807e79c98e6Szk 				    fault_state[r]);
80803831d35Sstevel 			}
80903831d35Sstevel 		} else {
81003831d35Sstevel 			for (r = 0; r < DAK_MAX_PS_FAULT_SENSORS; r++) {
81103831d35Sstevel 				log_printf(dgettext(TEXT_DOMAIN, "          "));
81203831d35Sstevel 			}
81303831d35Sstevel 		}
81403831d35Sstevel 		for (r = 0; r < DAK_MAX_PS_VOLTAGE_SENSORS; r++) {
81503831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "    %2d"), volts[r]);
81603831d35Sstevel 		}
81703831d35Sstevel 		log_printf("\n");
81803831d35Sstevel 	}
81903831d35Sstevel 	log_printf("\n");
82003831d35Sstevel 	return (err);
82103831d35Sstevel }
82203831d35Sstevel 
82303831d35Sstevel int
dak_env_print_fans(picl_nodehdl_t system_node)82403831d35Sstevel dak_env_print_fans(picl_nodehdl_t system_node)
82503831d35Sstevel {
82603831d35Sstevel 	int		i, err = 0;
82703831d35Sstevel 	int32_t		number, fan_speed;
82803831d35Sstevel 	picl_nodehdl_t	*fans;
82903831d35Sstevel 	char		name[PICL_PROPNAMELEN_MAX];
83003831d35Sstevel 	char		enabled[PICL_PROPNAMELEN_MAX];
83103831d35Sstevel 
83203831d35Sstevel 	err = fill_device_array_from_id(system_node, "PSVC_FAN", &number,
83303831d35Sstevel 	    &fans);
83403831d35Sstevel 	if (err != PICL_SUCCESS) {
83503831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
836e79c98e6Szk 		    "failed in fill_device_array_from_id "
837e79c98e6Szk 		    "for FAN\n"
838e79c98e6Szk 		    "%s\n"), picl_strerror(err));
83903831d35Sstevel 		return (err);
84003831d35Sstevel 	}
84103831d35Sstevel 
84203831d35Sstevel 	log_printf("\n");
84303831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
844e79c98e6Szk 	    "=================================\n"));
84503831d35Sstevel 	log_printf("\n");
84603831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN, "Fan Bank :\n"));
84703831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN, "----------\n"));
84803831d35Sstevel 	log_printf("\n");
84903831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN, "Bank                        Speed "
850e79c98e6Szk 	    "        Status        Fan State\n"));
85103831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN, "                           ( RPMS )"
852e79c98e6Szk 	    "	\n"));
85303831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN, "----                       --------"
854e79c98e6Szk 	    "      ---------      ---------\n"));
85503831d35Sstevel 
85603831d35Sstevel 
85703831d35Sstevel 	for (i = 0; i < DAK_MAX_FANS; i++) {
85803831d35Sstevel 		char fan_state[PICL_PROPNAMELEN_MAX];
85903831d35Sstevel 		fan_speed = 0;
86003831d35Sstevel 		err = picl_get_propval_by_name(fans[i], PICL_PROP_NAME, name,
86103831d35Sstevel 		    PICL_PROPNAMELEN_MAX);
86203831d35Sstevel 		if (err == PICL_SUCCESS) {
86303831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "%16-s"), name);
86403831d35Sstevel 		} else {
86503831d35Sstevel 			continue;
86603831d35Sstevel 		}
86703831d35Sstevel 
86803831d35Sstevel 		err = picl_get_propval_by_name(fans[i], "Fan-speed",
869e79c98e6Szk 		    &fan_speed, sizeof (int32_t));
87003831d35Sstevel 		if ((err != PICL_SUCCESS) && (err != PICL_INVALIDHANDLE)) {
87103831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
872e79c98e6Szk 			    "failed in picl_get_propval_by_name for "
873e79c98e6Szk 			    "fan speed\n"
874e79c98e6Szk 			    "%s\n"), picl_strerror(err));
87503831d35Sstevel 			return (err);
87603831d35Sstevel 		}
87703831d35Sstevel 
87803831d35Sstevel 		if ((strcmp(name, "CPU0_PRIM_FAN") != 0) &&
879e79c98e6Szk 		    (strcmp(name, "CPU1_PRIM_FAN") != 0)) {
88003831d35Sstevel 			err = picl_get_propval_by_name(fans[i], "Fan-switch",
881e79c98e6Szk 			    enabled, PICL_PROPNAMELEN_MAX);
88203831d35Sstevel 			if ((err != PICL_SUCCESS) &&
88303831d35Sstevel 			    (err != PICL_INVALIDHANDLE)) {
88403831d35Sstevel 				log_printf(dgettext(TEXT_DOMAIN,
885e79c98e6Szk 				    "failed in picl_get_propval_by_name for"
886e79c98e6Szk 				    " fan enabled/disabled\n"
887e79c98e6Szk 				    "%s\n"), picl_strerror(err));
88803831d35Sstevel 				return (err);
88903831d35Sstevel 			}
89003831d35Sstevel 			/*
89103831d35Sstevel 			 * Display the fan's speed and whether or not
89203831d35Sstevel 			 * it's enabled.
89303831d35Sstevel 			 */
89403831d35Sstevel 			if (strcmp(enabled, "ON") == 0) {
89503831d35Sstevel 				log_printf(dgettext(TEXT_DOMAIN,
896e79c98e6Szk 				    "\t     %4d        [ENABLED]"),
897e79c98e6Szk 				    fan_speed);
89803831d35Sstevel 			} else {
89903831d35Sstevel 				log_printf(dgettext(TEXT_DOMAIN,
900e79c98e6Szk 				    "\t        0        [DISABLED]"));
90103831d35Sstevel 			}
90203831d35Sstevel 
90303831d35Sstevel 		} else {
90403831d35Sstevel 			/* Display the fan's speed */
90503831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "\t     %4d"),
906e79c98e6Szk 			    fan_speed);
90703831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
908e79c98e6Szk 			    "        [ENABLED]"));
90903831d35Sstevel 		}
91003831d35Sstevel 
91103831d35Sstevel 		err = picl_get_propval_by_name(fans[i], "State", fan_state,
912e79c98e6Szk 		    PICL_PROPNAMELEN_MAX);
91303831d35Sstevel 		if (err != PICL_SUCCESS) {
91403831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
915e79c98e6Szk 			    "picl_get_propval_by_name failed: %s"),
916e79c98e6Szk 			    picl_strerror(err));
91703831d35Sstevel 			return (err);
91803831d35Sstevel 		}
91903831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN, "\t    %s\n"), fan_state);
92003831d35Sstevel 	}
92103831d35Sstevel 	log_printf("\n");
92203831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
923e79c98e6Szk 	    "=================================\n"));
92403831d35Sstevel 	log_printf("\n");
92503831d35Sstevel 
92603831d35Sstevel 	return (err);
92703831d35Sstevel }
92803831d35Sstevel 
92903831d35Sstevel int
dak_env_print_disk(picl_nodehdl_t system_node)93003831d35Sstevel dak_env_print_disk(picl_nodehdl_t system_node)
93103831d35Sstevel {
93203831d35Sstevel 	int		i, err;
93303831d35Sstevel 	int32_t		number;
93403831d35Sstevel 	picl_nodehdl_t	*disks;
93503831d35Sstevel 	picl_nodehdl_t	disk_slots[DAK_MAX_DISKS];
93603831d35Sstevel 	picl_nodehdl_t	disk_fault_leds[DAK_MAX_DISKS];
93703831d35Sstevel 	picl_nodehdl_t	disk_remove_leds[DAK_MAX_DISKS];
93803831d35Sstevel 	char		led_state[PICL_PROPNAMELEN_MAX];
93903831d35Sstevel 	char		name[PICL_PROPNAMELEN_MAX];
94003831d35Sstevel 
94103831d35Sstevel 	err = fill_device_array_from_id(system_node, "PSVC_DISK", &number,
942e79c98e6Szk 	    &disks);
94303831d35Sstevel 	if (err != PICL_SUCCESS) {
94403831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
945e79c98e6Szk 		    "failed in fill_device_array_from_id for "
946e79c98e6Szk 		    "DISK\n"
947e79c98e6Szk 		    "%s\n"), picl_strerror(err));
94803831d35Sstevel 		return (err);
94903831d35Sstevel 	}
95003831d35Sstevel 
95103831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
952e79c98e6Szk 	    "Disk Status:\n"
953e79c98e6Szk 	    "	  Presence	Fault LED	Remove LED\n"));
95403831d35Sstevel 
95503831d35Sstevel 	for (i = 0; i < DAK_MAX_DISKS; i++) {
95603831d35Sstevel 		err = picl_get_propval_by_name(disks[i], PICL_PROP_NAME, name,
95703831d35Sstevel 		    PICL_PROPNAMELEN_MAX);
95803831d35Sstevel 		switch (err) {
95903831d35Sstevel 		case PICL_SUCCESS:
96003831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "DISK  %2d: [%7s]"),
961e79c98e6Szk 			    i, "PRESENT");
96203831d35Sstevel 			break;
96303831d35Sstevel 		case PICL_INVALIDHANDLE:
96403831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "DISK  %2d: [%7s]"),
965e79c98e6Szk 			    i, "EMPTY");
96603831d35Sstevel 			log_printf("\n");
96703831d35Sstevel 			continue;
96803831d35Sstevel 		default:
96903831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
970e79c98e6Szk 			    "Failed picl_get_propval_by_name for "
971e79c98e6Szk 			    "disk %d with %s\n"), i, picl_strerror(err));
97203831d35Sstevel 			return (err);
97303831d35Sstevel 		}
97403831d35Sstevel 
97503831d35Sstevel 		err = fill_device_from_id(disks[i], "PSVC_PARENT",
976e79c98e6Szk 		    &(disk_slots[i]));
97703831d35Sstevel 		switch (err) {
97803831d35Sstevel 		case PICL_SUCCESS:
97903831d35Sstevel 			break;
98003831d35Sstevel 		case PICL_INVALIDHANDLE:
98103831d35Sstevel 			continue;
98203831d35Sstevel 		default:
98303831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
984e79c98e6Szk 			    "failed in fill_device_from_id for disk "
985e79c98e6Szk 			    "slot\n"
986e79c98e6Szk 			    "%s\n"), picl_strerror(err));
98703831d35Sstevel 			return (err);
98803831d35Sstevel 		}
98903831d35Sstevel 
99003831d35Sstevel 		err = fill_device_from_id(disk_slots[i], "PSVC_SLOT_FAULT_LED",
99103831d35Sstevel 		    &disk_fault_leds[i]);
99203831d35Sstevel 		if (err != PICL_SUCCESS) {
99303831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
994e79c98e6Szk 			    "failed in fill_device_from_id for disk slot "
995e79c98e6Szk 			    "fault led\n"
996e79c98e6Szk 			    "%s\n"), picl_strerror(err));
99703831d35Sstevel 			return (err);
99803831d35Sstevel 		}
99903831d35Sstevel 		err = picl_get_propval_by_name(disk_fault_leds[i],
1000e79c98e6Szk 		    "State", led_state, PICL_PROPNAMELEN_MAX);
100103831d35Sstevel 		if (err == PICL_SUCCESS) {
100203831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "	   [%3s]"),
1003e79c98e6Szk 			    led_state);
100403831d35Sstevel 		} else {
100503831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
1006e79c98e6Szk 			    "picl_get_propval_by_name for fault led_state"
1007e79c98e6Szk 			    " failed\n"
1008e79c98e6Szk 			    "%s\n"), picl_strerror(err));
100903831d35Sstevel 			return (err);
101003831d35Sstevel 		}
101103831d35Sstevel 		err = fill_device_from_id(disk_slots[i], "PSVC_SLOT_REMOVE_LED",
101203831d35Sstevel 		    &disk_remove_leds[i]);
101303831d35Sstevel 		if (err != PICL_SUCCESS) {
101403831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
1015e79c98e6Szk 			    "failed in fill_device_from_id for disk slot "
1016e79c98e6Szk 			    "remove led\n"
1017e79c98e6Szk 			    "%s\n"), picl_strerror(err));
101803831d35Sstevel 			return (err);
101903831d35Sstevel 		}
102003831d35Sstevel 
102103831d35Sstevel 		err = picl_get_propval_by_name(disk_remove_leds[i],
1022e79c98e6Szk 		    "State", led_state, PICL_PROPNAMELEN_MAX);
102303831d35Sstevel 		if (err == PICL_SUCCESS) {
102403831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
1025e79c98e6Szk 			    "	   [%3s]"), led_state);
102603831d35Sstevel 		} else {
102703831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
1028e79c98e6Szk 			    "picl_get_propval_by_name for remove"
1029e79c98e6Szk 			    " led_state failed\n"
1030e79c98e6Szk 			    "%s\n"), picl_strerror(err));
103103831d35Sstevel 			return (err);
103203831d35Sstevel 		}
103303831d35Sstevel 		log_printf("\n");
103403831d35Sstevel 	}
103503831d35Sstevel 	return (err);
103603831d35Sstevel }
103703831d35Sstevel 
103803831d35Sstevel int
dak_env_print_FSP_LEDS(picl_nodehdl_t system_node)103903831d35Sstevel dak_env_print_FSP_LEDS(picl_nodehdl_t system_node)
104003831d35Sstevel {
104103831d35Sstevel 	int		i, err = 0;
104203831d35Sstevel 	int32_t		number;
104303831d35Sstevel 	picl_nodehdl_t	*fsp_leds;
104403831d35Sstevel 	char		led_state[PICL_PROPNAMELEN_MAX];
104503831d35Sstevel 
104603831d35Sstevel 	err = fill_device_array_from_id(system_node, "PSVC_FSP_LED", &number,
104703831d35Sstevel 	    &fsp_leds);
104803831d35Sstevel 	if (err != PICL_SUCCESS) {
104903831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
1050e79c98e6Szk 		    "failed in fill_device_array_from_id for "
1051e79c98e6Szk 		    "FSP_LED\n"
1052e79c98e6Szk 		    "%s\n"), picl_strerror(err));
105303831d35Sstevel 		return (err);
105403831d35Sstevel 	}
105503831d35Sstevel 
105603831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
1057e79c98e6Szk 	    "System LED Status:\n"
1058e79c98e6Szk 	    "                   GEN FAULT                REMOVE\n"));
105903831d35Sstevel 	for (i = 0; i < DAK_MAX_FSP_LEDS; i++) {
106003831d35Sstevel 		err = picl_get_propval_by_name(fsp_leds[i], "State",
1061e79c98e6Szk 		    led_state, PICL_PROPNAMELEN_MAX);
106203831d35Sstevel 		if (err != PICL_SUCCESS) {
106303831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
1064e79c98e6Szk 			    "picl_get_propval_by_name for led_state"
1065e79c98e6Szk 			    " failed\n"
1066e79c98e6Szk 			    "%s\n"), picl_strerror(err));
106703831d35Sstevel 			return (err);
106803831d35Sstevel 		}
106903831d35Sstevel 
107003831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
1071e79c98e6Szk 		    "                    [%3s]"), led_state);
107203831d35Sstevel 	}
107303831d35Sstevel 	log_printf("\n\n");
107403831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
1075e79c98e6Szk 	    "                   DISK FAULT               "));
107603831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN, "POWER FAULT\n"));
107703831d35Sstevel 	for (i = 2; i < 4; i++) {
107803831d35Sstevel 		err = picl_get_propval_by_name(fsp_leds[i], "State",
1079e79c98e6Szk 		    led_state, PICL_PROPNAMELEN_MAX);
108003831d35Sstevel 		if (err != PICL_SUCCESS) {
108103831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
1082e79c98e6Szk 			    "picl_get_propval_by_name for led_state"
1083e79c98e6Szk 			    " failed\n"
1084e79c98e6Szk 			    "%s\n"), picl_strerror(err));
108503831d35Sstevel 			return (err);
108603831d35Sstevel 		}
108703831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN, "                    [%3s]"),
108803831d35Sstevel 		    led_state);
108903831d35Sstevel 	}
109003831d35Sstevel 	log_printf("\n\n");
109103831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
1092e79c98e6Szk 	    "                   LEFT THERMAL FAULT       "
1093e79c98e6Szk 	    "RIGHT THERMAL FAULT\n"));
109403831d35Sstevel 	for (i = 4; i < 6; i++) {
109503831d35Sstevel 		err = picl_get_propval_by_name(fsp_leds[i], "State",
109603831d35Sstevel 		    led_state, PICL_PROPNAMELEN_MAX);
109703831d35Sstevel 		if (err != PICL_SUCCESS) {
109803831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
1099e79c98e6Szk 			    "picl_get_propval_by_name for led_state "
1100e79c98e6Szk 			    "failed\n"
1101e79c98e6Szk 			    "%s\n"), picl_strerror(err));
110203831d35Sstevel 			return (err);
110303831d35Sstevel 		}
110403831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN, "                    [%3s]"),
1105e79c98e6Szk 		    led_state);
110603831d35Sstevel 	}
110703831d35Sstevel 	log_printf("\n\n");
110803831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
1109e79c98e6Szk 	    "                   LEFT DOOR                "
1110e79c98e6Szk 	    "RIGHT DOOR\n"));
111103831d35Sstevel 	for (i = 6; i < 8; i++) {
111203831d35Sstevel 		err = picl_get_propval_by_name(fsp_leds[i], "State",
111303831d35Sstevel 		    led_state, PICL_PROPNAMELEN_MAX);
111403831d35Sstevel 		if (err != PICL_SUCCESS) {
111503831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN,
1116e79c98e6Szk 			    "picl_get_propval_by_name for led_state"
1117e79c98e6Szk 			    " failed\n"
1118e79c98e6Szk 			    "%s\n"), picl_strerror(err));
111903831d35Sstevel 			return (err);
112003831d35Sstevel 		}
112103831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN, "                    [%3s]"),
1122e79c98e6Szk 		    led_state);
112303831d35Sstevel 	}
112403831d35Sstevel 	log_printf("\n\n");
112503831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
1126e79c98e6Szk 	    "=================================\n"));
112703831d35Sstevel 	log_printf("\n");
112803831d35Sstevel 
112903831d35Sstevel 	return (err);
113003831d35Sstevel }
113103831d35Sstevel 
113203831d35Sstevel int
dak_env_print_keyswitch(picl_nodehdl_t system_node)113303831d35Sstevel dak_env_print_keyswitch(picl_nodehdl_t system_node)
113403831d35Sstevel {
113503831d35Sstevel 	int 		err = 0;
113603831d35Sstevel 	picl_nodehdl_t *keyswitch;
113703831d35Sstevel 	int32_t		number;
113803831d35Sstevel 	char		ks_pos[PICL_PROPNAMELEN_MAX];
113903831d35Sstevel 
114003831d35Sstevel 	err = fill_device_array_from_id(system_node, "PSVC_KEYSWITCH", &number,
114103831d35Sstevel 	    &keyswitch);
114203831d35Sstevel 	if (err != PICL_SUCCESS) {
114303831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
1144e79c98e6Szk 		    "failed in fill_device_array_from_id for "
1145e79c98e6Szk 		    "	PSVC_KEYSWITCH\n"
1146e79c98e6Szk 		    "%s\n"), picl_strerror(err));
114703831d35Sstevel 		return (err);
114803831d35Sstevel 	}
114903831d35Sstevel 
115003831d35Sstevel 	err = picl_get_propval_by_name(keyswitch[0], "State", ks_pos,
1151e79c98e6Szk 	    PICL_PROPNAMELEN_MAX);
115203831d35Sstevel 	if (err != PICL_SUCCESS) {
115303831d35Sstevel 		log_printf(dgettext(TEXT_DOMAIN,
1154e79c98e6Szk 		    "picl_get_propval_by_name for keyswitch state "
1155e79c98e6Szk 		    "failed\n"
1156e79c98e6Szk 		    "%s\n"), picl_strerror(err));
115703831d35Sstevel 		return (err);
115803831d35Sstevel 	}
115903831d35Sstevel 
116003831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
1161e79c98e6Szk 	    "Front Status Panel:\n"
1162e79c98e6Szk 	    "-------------------\n"
1163e79c98e6Szk 	    "Keyswitch position: "
1164e79c98e6Szk 	    "%s\n"), ks_pos);
116503831d35Sstevel 	log_printf("\n");
116603831d35Sstevel 
116703831d35Sstevel 	return (err);
116803831d35Sstevel }
116903831d35Sstevel 
117003831d35Sstevel int
dak_env_print_temps(picl_nodehdl_t system_node)117103831d35Sstevel dak_env_print_temps(picl_nodehdl_t system_node)
117203831d35Sstevel {
117303831d35Sstevel 	int		i;
117403831d35Sstevel 	int		err;
117503831d35Sstevel 	picl_nodehdl_t	*system_ts_nodes;
117603831d35Sstevel 	int32_t		temp;
117703831d35Sstevel 	int32_t		number;
117803831d35Sstevel 	char		label[PICL_PROPNAMELEN_MAX];
117903831d35Sstevel 	char		state[PICL_PROPNAMELEN_MAX];
118003831d35Sstevel 	char		*p;
118103831d35Sstevel 
118203831d35Sstevel 	err = fill_device_array_from_id(system_node, "PSVC_TS", &number,
118303831d35Sstevel 	    &system_ts_nodes);
118403831d35Sstevel 	if (err != PICL_SUCCESS) {
118503831d35Sstevel 		return (err);
118603831d35Sstevel 	}
118703831d35Sstevel 
118803831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
1189e79c98e6Szk 	    "System Temperatures (Celsius):\n"
1190e79c98e6Szk 	    "-------------------------------\n"
1191e79c98e6Szk 	    "Device\t\tTemperature\tStatus\n"
1192e79c98e6Szk 	    "---------------------------------------\n"));
119303831d35Sstevel 
119403831d35Sstevel 	for (i = 0; i < number; i++) {
119503831d35Sstevel 		err = picl_get_propval_by_name(system_ts_nodes[i],
119603831d35Sstevel 		    "State", state, sizeof (state));
119703831d35Sstevel 		if (err != PICL_SUCCESS) {
119803831d35Sstevel 			if (err == PICL_INVALIDHANDLE) {
119903831d35Sstevel 				strcpy(state, "n/a");
120003831d35Sstevel 			} else {
120103831d35Sstevel 				log_printf("%s\n", picl_strerror(err));
120203831d35Sstevel 				return (err);
120303831d35Sstevel 			}
120403831d35Sstevel 		}
120503831d35Sstevel 		err = picl_get_propval_by_name(system_ts_nodes[i],
120603831d35Sstevel 		    PICL_PROP_NAME, label, PICL_PROPNAMELEN_MAX);
120703831d35Sstevel 		if (err != PICL_SUCCESS) {
120803831d35Sstevel 			if (err == PICL_INVALIDHANDLE)
120903831d35Sstevel 				/* This FRU isn't present. Skip it. */
121003831d35Sstevel 				continue;
121103831d35Sstevel 			log_printf("%s\n", picl_strerror(err));
121203831d35Sstevel 			return (err);
121303831d35Sstevel 		}
121403831d35Sstevel 
121503831d35Sstevel 		/*
121603831d35Sstevel 		 * The names in the tree are like "CPU0_DIE_TEMPERATURE_SENSOR".
121703831d35Sstevel 		 * All we want to print is up to the first underscore.
121803831d35Sstevel 		 */
121903831d35Sstevel 		p = strchr(label, '_');
122003831d35Sstevel 		if (p != NULL)
122103831d35Sstevel 			*p = '\0';
122203831d35Sstevel 
122303831d35Sstevel 		err = picl_get_propval_by_name(system_ts_nodes[i],
1224e79c98e6Szk 		    "Temperature", &temp, sizeof (temp));
122503831d35Sstevel 		if (err != PICL_SUCCESS) {
122603831d35Sstevel 			log_printf("%s\n", picl_strerror(err));
122703831d35Sstevel 			return (err);
122803831d35Sstevel 		}
122903831d35Sstevel 		log_printf("%s\t\t%3d\t\t%s\n", label, temp, state);
123003831d35Sstevel 	}
123103831d35Sstevel 
123203831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
1233e79c98e6Szk 	    "\n=================================\n\n"));
123403831d35Sstevel 
123503831d35Sstevel 	return (PICL_SUCCESS);
123603831d35Sstevel }
123703831d35Sstevel 
123803831d35Sstevel static void
dak_display_hw_revisions(Prom_node * root,Board_node * bdlist)123903831d35Sstevel dak_display_hw_revisions(Prom_node *root, Board_node *bdlist)
124003831d35Sstevel {
124103831d35Sstevel 	Prom_node	*pnode;
124203831d35Sstevel 	char		*value;
124303831d35Sstevel 
124403831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN, "\n"
1245e79c98e6Szk 	    "========================= HW Revisions "
1246e79c98e6Szk 	    "=======================================\n\n"));
124703831d35Sstevel 
124803831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN,
1249e79c98e6Szk 	    "System PROM revisions:\n"
1250e79c98e6Szk 	    "----------------------\n"));
125103831d35Sstevel 
125203831d35Sstevel 	pnode = dev_find_node(root, "openprom");
125303831d35Sstevel 	if (pnode != NULL) {
1254e79c98e6Szk 		value = (char *)get_prop_val(find_prop(pnode, "version"));
1255e79c98e6Szk 		log_printf(value);
125603831d35Sstevel 	}
125703831d35Sstevel 
125803831d35Sstevel 	log_printf(dgettext(TEXT_DOMAIN, "\n\n"
1259e79c98e6Szk 	    "IO ASIC revisions:\n"
1260e79c98e6Szk 	    "------------------\n"
1261e79c98e6Szk 	    "         Port\n"
1262e79c98e6Szk 	    "Model     ID  Status Version\n"
1263e79c98e6Szk 	    "-------- ---- ------ -------\n"));
126403831d35Sstevel 
126503831d35Sstevel 	display_schizo_revisions(bdlist);
126603831d35Sstevel }
126703831d35Sstevel 
126803831d35Sstevel static void
display_schizo_revisions(Board_node * bdlist)126903831d35Sstevel display_schizo_revisions(Board_node *bdlist)
127003831d35Sstevel {
127103831d35Sstevel 	Prom_node	*pnode;
127203831d35Sstevel 	int		*int_val;
127303831d35Sstevel 	int		portid;
127403831d35Sstevel 	int		prev_portid = -1;
127503831d35Sstevel 	char		*status_a = NULL;
127603831d35Sstevel 	char		*status_b = NULL;
127703831d35Sstevel 	int		revision;
127803831d35Sstevel #ifdef DEBUG
127903831d35Sstevel 	uint32_t	a_notes, b_notes;
128003831d35Sstevel #endif
128103831d35Sstevel 	int		pci_bus;
128203831d35Sstevel 	Board_node	*bnode;
128303831d35Sstevel 	bnode = bdlist;
128403831d35Sstevel 
128503831d35Sstevel 	while (bnode != NULL) {
128603831d35Sstevel 		/*
128703831d35Sstevel 		 * search this board node for all Schizos
128803831d35Sstevel 		 */
128903831d35Sstevel 		for (pnode = dev_find_node_by_compat(bnode->nodes,
1290e79c98e6Szk 		    SCHIZO_COMPAT_PROP); pnode != NULL;
1291e79c98e6Szk 		    pnode = dev_next_node_by_compat(pnode,
1292e79c98e6Szk 		    SCHIZO_COMPAT_PROP)) {
129303831d35Sstevel 
129403831d35Sstevel 			/*
129503831d35Sstevel 			 * get the reg property to determine
129603831d35Sstevel 			 * whether we are looking at side A or B
129703831d35Sstevel 			 */
129803831d35Sstevel 			int_val = (int *)get_prop_val
1299e79c98e6Szk 			    (find_prop(pnode, "reg"));
130003831d35Sstevel 			if (int_val != NULL) {
130103831d35Sstevel 				int_val ++; /* second integer in array */
130203831d35Sstevel 				pci_bus = ((*int_val) & 0x7f0000);
130303831d35Sstevel 			}
130403831d35Sstevel 
130503831d35Sstevel 			/* get portid */
130603831d35Sstevel 			int_val = (int *)get_prop_val
1307e79c98e6Szk 			    (find_prop(pnode, "portid"));
130803831d35Sstevel 			if (int_val == NULL)
130903831d35Sstevel 				continue;
131003831d35Sstevel 
131103831d35Sstevel 			portid = *int_val;
131203831d35Sstevel 
131303831d35Sstevel 			/*
131403831d35Sstevel 			 * If this is a new portid and it is PCI bus B,
131503831d35Sstevel 			 * we skip onto the PCI bus A.
131603831d35Sstevel 			 */
131703831d35Sstevel 			if ((portid != prev_portid) && (pci_bus == 0x700000)) {
131803831d35Sstevel 				prev_portid = portid;
131903831d35Sstevel 				/* status */
132003831d35Sstevel 				status_b = (char *)get_prop_val
132103831d35Sstevel 				    (find_prop(pnode, "status"));
132203831d35Sstevel #ifdef DEBUG
132303831d35Sstevel 				b_notes = pci_bus;
132403831d35Sstevel #endif
132503831d35Sstevel 				continue; /* skip to the next schizo */
132603831d35Sstevel 			}
132703831d35Sstevel 
132803831d35Sstevel 			/*
132903831d35Sstevel 			 * This must be side A of the same Schizo.
133003831d35Sstevel 			 * Gather all its props and display them.
133103831d35Sstevel 			 */
133203831d35Sstevel #ifdef DEBUG
133303831d35Sstevel 			a_notes = pci_bus;
133403831d35Sstevel #endif
133503831d35Sstevel 
133603831d35Sstevel 			prev_portid = portid;
133703831d35Sstevel 
133803831d35Sstevel 			int_val = (int *)get_prop_val
1339e79c98e6Szk 			    (find_prop(pnode, "version#"));
134003831d35Sstevel 			if (int_val != NULL)
134103831d35Sstevel 				revision = *int_val;
134203831d35Sstevel 			else
134303831d35Sstevel 				revision = -1;
134403831d35Sstevel 
134503831d35Sstevel 			status_a = (char *)get_prop_val(find_prop
1346e79c98e6Szk 			    (pnode, "status"));
134703831d35Sstevel 
134803831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "Schizo    "));
134903831d35Sstevel 
135003831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, "%-3d "), portid, 0);
135103831d35Sstevel 
135203831d35Sstevel 
135303831d35Sstevel 			log_printf((status_a == NULL && status_b == NULL) ?
1354e79c98e6Szk 			    dgettext(TEXT_DOMAIN, "  ok  ") :
1355e79c98e6Szk 			    dgettext(TEXT_DOMAIN, " fail "));
135603831d35Sstevel 
135703831d35Sstevel 			log_printf(dgettext(TEXT_DOMAIN, " %4d   "),
135803831d35Sstevel 			    revision);
135903831d35Sstevel #ifdef DEBUG
136003831d35Sstevel 			log_printf(" 0x%x 0x%x", a_notes, b_notes);
136103831d35Sstevel #endif
136203831d35Sstevel 			log_printf("\n");
136303831d35Sstevel 		}
136403831d35Sstevel 		bnode = bnode->next;
136503831d35Sstevel 	}
136603831d35Sstevel }
1367