xref: /illumos-gate/usr/src/lib/libprtdiag_psr/sparc/daktari/common/daktari.c (revision f998c95e3b7029fe5f7542e115f7474ddb8024d7)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * Daktari Platform specific functions.
28  *
29  * 	called when :
30  *      machine_type ==  MTYPE_DAKTARI
31  *
32  */
33 
34 #pragma ident	"%Z%%M%	%I%	%E% SMI"
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39 #include <kstat.h>
40 #include <string.h>
41 #include <assert.h>
42 #include <libintl.h>
43 #include <note.h>
44 
45 #include <sys/openpromio.h>
46 #include <sys/sysmacros.h>
47 #include <sys/daktari.h>
48 
49 #include <pdevinfo.h>
50 #include <display.h>
51 #include <pdevinfo_sun4u.h>
52 #include <display_sun4u.h>
53 #include <libprtdiag.h>
54 
55 #include <picl.h>
56 #include "workfile.c"
57 
58 #if !defined(TEXT_DOMAIN)
59 #define	TEXT_DOMAIN	"SYS_TEST"
60 #endif
61 
62 #define	DAK_MAX_SLOTS_PER_IO_BD		9
63 #define	DAK_MAX_DISKS			12
64 #define	DAK_MAX_FSP_LEDS		2
65 #define	DAK_MAX_PS			3
66 #define	DAK_MAX_PS_VOLTAGE_SENSORS	4
67 #define	DAK_MAX_PS_FAULT_SENSORS	3
68 #define	DAK_MAX_FANS			10
69 #ifndef SCHIZO_COMPAT_PROP
70 #define	SCHIZO_COMPAT_PROP		"pci108e,8001"
71 #endif
72 
73 #define	MULTIPLE_BITS_SET(x)		((x)&((x)-1))
74 
75 extern	int	print_flag;
76 
77 /*
78  * these functions will overlay the symbol table of libprtdiag
79  * at runtime (workgroup server systems only)
80  */
81 void	display_cpu_devices(Sys_tree *tree);
82 void	display_cpus(Board_node *board);
83 void	display_pci(Board_node *board);
84 void	display_io_cards(struct io_card *list);
85 void	display_diaginfo(int flag, Prom_node *root, Sys_tree *tree,
86 				struct system_kstat_data *kstats);
87 void	display_ffb(Board_node *board, int table);
88 void	display_memoryconf(Sys_tree *tree, struct grp_info *grps);
89 
90 /* local functions */
91 static	int disp_envc_status(void);
92 static	int dak_env_print_temps(picl_nodehdl_t);
93 static	int dak_env_print_keyswitch(picl_nodehdl_t);
94 static	int dak_env_print_FSP_LEDS(picl_nodehdl_t);
95 static	int dak_env_print_disk(picl_nodehdl_t);
96 static	int dak_env_print_fans(picl_nodehdl_t);
97 static	int dak_env_print_ps(picl_nodehdl_t);
98 
99 static void dak_display_hw_revisions(Prom_node *root,
100 					Board_node *bnode);
101 static void display_schizo_revisions(Board_node *bdlist);
102 
103 
104 /*
105  * Defining the error_check function in order to return the
106  * appropriate error code.
107  */
108 /*ARGSUSED0*/
109 int
110 error_check(Sys_tree *tree, struct system_kstat_data *kstats)
111 {
112 	int exit_code = 0;	/* init to all OK */
113 	/*
114 	 * silently check for any types of machine errors
115 	 */
116 	print_flag = 0;
117 	if (disp_fail_parts(tree)) {
118 		/* set exit_code to show failures */
119 		exit_code = 1;
120 	}
121 	print_flag = 1;
122 
123 	return (exit_code);
124 }
125 
126 /*
127  * disp_fail_parts
128  *
129  * Display the failed parts in the system. This function looks for
130  * the status property in all PROM nodes. On systems where
131  * the PROM does not support passing diagnostic information
132  * through the device tree, this routine will be silent.
133  */
134 int
135 disp_fail_parts(Sys_tree *tree)
136 {
137 	int exit_code = 0;
138 	int system_failed = 0;
139 	Board_node *bnode = tree->bd_list;
140 	Prom_node *pnode;
141 
142 	/* go through all of the boards looking for failed units. */
143 	while (bnode != NULL) {
144 		/* find failed chips */
145 		pnode = find_failed_node(bnode->nodes);
146 		if ((pnode != NULL) && !system_failed) {
147 			system_failed = 1;
148 			exit_code = 1;
149 			if (print_flag == 0) {
150 				return (exit_code);
151 			}
152 			log_printf("\n");
153 			log_printf(dgettext(TEXT_DOMAIN, "Failed Field "
154 			    "Replaceable Units (FRU) in System:\n"));
155 			log_printf("=========================="
156 			    "====================\n");
157 		}
158 		while (pnode != NULL) {
159 			void *value;
160 			char *name;		/* node name string */
161 			char *type;		/* node type string */
162 			char *board_type = NULL;
163 
164 			value = get_prop_val(find_prop(pnode, "status"));
165 			name = get_node_name(pnode);
166 
167 			/* sanity check of data retrieved from PROM */
168 			if ((value == NULL) || (name == NULL)) {
169 				pnode = next_failed_node(pnode);
170 				continue;
171 			}
172 
173 			/* Find the board type of this board */
174 			if (bnode->board_type == CPU_BOARD) {
175 				board_type = "CPU";
176 			} else {
177 				board_type = "IO";
178 			}
179 
180 			log_printf(dgettext(TEXT_DOMAIN, "%s unavailable "
181 			    "on %s Board #%d\n"), name, board_type,
182 			    bnode->board_num);
183 
184 			log_printf(dgettext(TEXT_DOMAIN,
185 			    "\tPROM fault string: %s\n"), value);
186 
187 			log_printf(dgettext(TEXT_DOMAIN,
188 			    "\tFailed Field Replaceable Unit is "));
189 
190 			/*
191 			 * Determine whether FRU is CPU module, system
192 			 * board, or SBus card.
193 			 */
194 			if ((name != NULL) && (strstr(name, "sbus"))) {
195 
196 				log_printf(dgettext(TEXT_DOMAIN,
197 				    "SBus Card %d\n"),
198 				    get_sbus_slot(pnode));
199 
200 			} else if (((name = get_node_name(pnode->parent)) !=
201 			    NULL) && (strstr(name, "pci"))) {
202 
203 				log_printf(dgettext(TEXT_DOMAIN,
204 				    "PCI Card %d"),
205 				    get_pci_device(pnode));
206 
207 			} else if (((type = get_node_type(pnode)) != NULL) &&
208 			    (strstr(type, "cpu"))) {
209 
210 				log_printf(dgettext(TEXT_DOMAIN, "UltraSPARC "
211 				    "module Board %d Module %d\n"), 0,
212 				    get_id(pnode));
213 
214 			} else {
215 				log_printf(dgettext(TEXT_DOMAIN,
216 				    "%s board %d\n"), board_type,
217 				    bnode->board_num);
218 			}
219 			pnode = next_failed_node(pnode);
220 		}
221 		bnode = bnode->next;
222 	}
223 
224 	if (!system_failed) {
225 		log_printf(dgettext(TEXT_DOMAIN,
226 		    "No failures found in System\n"));
227 		log_printf("===========================\n\n");
228 	}
229 
230 	if (system_failed)
231 		return (1);
232 	else
233 		return (0);
234 }
235 
236 /*ARGSUSED*/
237 void
238 display_hp_fail_fault(Sys_tree *tree, struct system_kstat_data *kstats)
239 {
240 	/* Display failed units */
241 	(void) disp_fail_parts(tree);
242 }
243 
244 /*ARGSUSED*/
245 void
246 display_memoryconf(Sys_tree *tree, struct grp_info *grps)
247 {
248 	Board_node	*bnode = tree->bd_list;
249 
250 	log_printf(dgettext(TEXT_DOMAIN,
251 	    "========================= Memory Configuration"
252 	    " ===============================\n"
253 	    "\n           Logical  Logical"
254 	    "  Logical "
255 	    "\n      MC   Bank     Bank     Bank"
256 	    "         DIMM    Interleave  Interleaved"
257 	    "\n Brd  ID   num      size     "
258 	    "Status       Size    "
259 	    "Factor      with"
260 	    "\n----  ---  ----     ------   "
261 	    "-----------  ------  "
262 	    "----------  -----------"));
263 
264 	while (bnode != NULL) {
265 		if (get_us3_mem_regs(bnode)) {
266 			log_printf(dgettext(TEXT_DOMAIN,
267 			    "\nFailed to get memory information.\n"));
268 			return;
269 		}
270 		bnode = bnode->next;
271 	}
272 
273 	/* Display what we have found */
274 	display_us3_banks();
275 }
276 
277 void
278 display_cpu_devices(Sys_tree *tree)
279 {
280 	Board_node *bnode;
281 
282 	/*
283 	 * Display the table header for CPUs . Then display the CPU
284 	 * frequency, cache size, and processor revision of all cpus.
285 	 */
286 	log_printf(dgettext(TEXT_DOMAIN,
287 	    "\n"
288 	    "========================="
289 	    " CPUs "
290 	    "==============================================="
291 	    "\n"
292 	    "\n"
293 	    "           Run   E$  CPU    CPU  \n"
294 	    "Brd  CPU   MHz   MB Impl.   Mask \n"
295 	    "--- ----- ---- ---- ------- ---- \n"));
296 
297 	/* Now display all of the cpus on each board */
298 	bnode = tree->bd_list;
299 	if (bnode == NULL) {
300 		log_printf(dgettext(TEXT_DOMAIN,
301 		    "CPU Board list was NULL\n"));
302 	}
303 	while (bnode != NULL) {
304 		display_cpus(bnode);
305 		bnode = bnode->next;
306 	}
307 
308 	log_printf("\n");
309 }
310 
311 /*
312  * Display the CPUs present on this board.
313  */
314 void
315 display_cpus(Board_node *board)
316 {
317 	Prom_node 	*cpu;
318 	uint_t freq;	 /* CPU clock frequency */
319 	int ecache_size; /* External cache size */
320 	int *l3_shares;
321 	int *mid;
322 	int *impl;
323 	int *mask;
324 	int *coreid;
325 	char fru_prev = 'X'; /* Valid frus are 'A','B','C','D' */
326 	int mid_prev;
327 	int ecache_size_prev = 0;
328 	char fru_name;
329 
330 	/*
331 	 * display the CPUs' operating frequency, cache size, impl. field
332 	 * and mask revision.
333 	 */
334 	for (cpu = dev_find_type(board->nodes, "cpu"); cpu != NULL;
335 	    cpu = dev_next_type(cpu, "cpu")) {
336 
337 		mid = (int *)get_prop_val(find_prop(cpu, "portid"));
338 		if (mid == NULL)
339 			mid = (int *)get_prop_val(find_prop(cpu, "cpuid"));
340 		freq = DAK_CLK_FREQ_TO_MHZ(get_cpu_freq(cpu));
341 		ecache_size = get_ecache_size(cpu);
342 		impl = (int *)get_prop_val(find_prop(cpu, "implementation#"));
343 		mask = (int *)get_prop_val(find_prop(cpu, "mask#"));
344 		l3_shares = (int *)get_prop_val(find_prop(cpu,
345 		    "l3-cache-sharing"));
346 
347 		/* Do not display a failed CPU node */
348 		if ((impl == NULL) || (freq == 0) || (node_failed(cpu)))
349 			continue;
350 
351 		/* Board number */
352 		fru_name = (char)('A' + DAK_GETSLOT(*mid));
353 
354 		if (CPU_IMPL_IS_CMP(*impl)) {
355 			coreid = (int *)get_prop_val(find_prop(cpu, "reg"));
356 			if (coreid == NULL) {
357 				continue;
358 			}
359 			if ((fru_prev == 'X') ||
360 			    ((fru_prev != 'X') &&
361 			    (fru_name != fru_prev))) {
362 				fru_prev = fru_name;
363 				mid_prev = *mid;
364 				ecache_size_prev = ecache_size;
365 				continue;
366 			} else {
367 				/*
368 				 * Some CMP chips have a split E$,
369 				 * so the size for both cores is added
370 				 * together to get the total size for
371 				 * the chip.
372 				 *
373 				 * Still, other CMP chips have E$ (L3)
374 				 * which is logically shared, so the
375 				 * total size is equal to the core size.
376 				 */
377 				if ((l3_shares == NULL) ||
378 				    ((l3_shares != NULL) &&
379 				    MULTIPLE_BITS_SET(*l3_shares))) {
380 					ecache_size += ecache_size_prev;
381 				}
382 				ecache_size_prev = 0;
383 				fru_prev = 'X';
384 			}
385 		}
386 
387 		log_printf("%2c", fru_name);
388 
389 		/* CPU Module ID */
390 		if (CPU_IMPL_IS_CMP(*impl)) {
391 			log_printf("%3d,%3d", mid_prev, *mid, 0);
392 		} else
393 			log_printf("    %d  ", *mid);
394 
395 		/* Running frequency */
396 		log_printf(" %4u ", freq);
397 
398 		/* Ecache size */
399 		if (ecache_size == 0)
400 			log_printf(dgettext(TEXT_DOMAIN, "%3s  "),
401 			    "N/A");
402 		else
403 			log_printf("%4.1f ",
404 			    (float)ecache_size / (float)(1<<20));
405 
406 		/* Implementation */
407 		if (impl == NULL) {
408 			log_printf(dgettext(TEXT_DOMAIN, "%s    "),
409 			"N/A");
410 		} else {
411 			if (IS_CHEETAH(*impl))
412 				log_printf("%7s", "US-III ", 0);
413 			else if (IS_CHEETAH_PLUS(*impl))
414 				log_printf("%7s", "US-III+", 0);
415 			else if (IS_JAGUAR(*impl))
416 				log_printf("%7s", "US-IV  ", 0);
417 			else if (IS_PANTHER(*impl))
418 				log_printf("%7s", "US-IV+ ", 0);
419 			else
420 				log_printf("%-7x", *impl, 0);
421 		}
422 
423 		/* CPU Mask */
424 		if (mask == NULL) {
425 			log_printf(dgettext(TEXT_DOMAIN, " %3s   "),
426 			"N/A");
427 		} else {
428 			log_printf(dgettext(TEXT_DOMAIN, " %2d.%d"),
429 			    (*mask >> 4) & 0xf, *mask & 0xf);
430 		}
431 
432 		log_printf("\n");
433 	}
434 }
435 
436 /*
437  * display_pci
438  * Display all the PCI IO cards on this board.
439  */
440 void
441 display_pci(Board_node *board)
442 {
443 	struct io_card	*card_list = NULL;
444 	struct io_card	card;
445 	void		*value;
446 	Prom_node	*pci;
447 	Prom_node	*card_node;
448 	char		*slot_name_arr[DAK_MAX_SLOTS_PER_IO_BD] = {NULL};
449 	int		i;
450 #ifdef DEBUG
451 	int		slot_name_bits;
452 #endif
453 
454 	if (board == NULL)
455 		return;
456 
457 	memset(&card, 0, sizeof (struct io_card));
458 	/* Initialize all the common information */
459 	card.display = TRUE;
460 	card.board = board->board_num;
461 
462 	/*
463 	 * Search for each pci instance, then find/display all nodes under
464 	 * each instance node found.
465 	 */
466 	for (pci = dev_find_node_by_compat(board->nodes, SCHIZO_COMPAT_PROP);
467 	    pci != NULL;
468 	    pci = dev_next_node_by_compat(pci, SCHIZO_COMPAT_PROP)) {
469 		(void) snprintf(card.bus_type, MAXSTRLEN,
470 		    dgettext(TEXT_DOMAIN, "PCI"));
471 		/*
472 		 * Get slot-name properties from parent node and
473 		 * store them in an array.
474 		 */
475 		value = (char *)get_prop_val(
476 		    find_prop(pci, "slot-names"));
477 
478 		if (value != NULL) {
479 #ifdef DEBUG
480 			/* save the 4 byte bitmask */
481 			slot_name_bits = *(int *)value;
482 #endif
483 
484 			/* array starts after first int */
485 			slot_name_arr[0] = (char *)value + sizeof (int);
486 			for (i = 1; i < DAK_MAX_SLOTS_PER_IO_BD; i++) {
487 				slot_name_arr[i] = (char *)slot_name_arr[i - 1]
488 				    + strlen(slot_name_arr[i - 1]) +1;
489 			}
490 		}
491 		/*
492 		 * Search for Children of this node ie. Cards.
493 		 * Note: any of these cards can be a pci-bridge
494 		 *	that itself has children. If we find a
495 		 *	pci-bridge we need to handle it specially.
496 		 */
497 		card_node = pci->child;
498 		/* Generate the list of pci cards on pci instance: pci */
499 		fill_pci_card_list(pci, card_node, &card, &card_list,
500 		    slot_name_arr);
501 	} /* end-for */
502 
503 	display_io_cards(card_list);
504 	free_io_cards(card_list);
505 	log_printf("\n");
506 }
507 
508 /*
509  * Print out all the io cards in the list.  Also print the column
510  * headers if told to do so.
511  */
512 void
513 display_io_cards(struct io_card *list)
514 {
515 	static int banner = 0; /* Have we printed the column headings? */
516 	struct io_card *p;
517 
518 	if (list == NULL)
519 		return;
520 
521 	if (banner == FALSE) {
522 		log_printf(dgettext(TEXT_DOMAIN,
523 		    "                         Bus  Max\n"
524 		    "     IO   Port Bus       Freq Bus  Dev,"
525 		    "\n"
526 		    "Brd  Type  ID  Side Slot MHz  Freq "
527 		    "Func State Name                              "
528 		    "Model\n"
529 		/* ---------Brd  IO   Port Bus  Slot Bus  Max  Dev  Stat */
530 		    "---- ---- ---- ---- ---- ---- ---- ----"
531 		    " ----- "
532 		    "--------------------------------  "
533 		    "----------------------\n"));
534 		banner = TRUE;
535 	}
536 
537 	for (p = list; p != NULL; p = p -> next) {
538 		log_printf(dgettext(TEXT_DOMAIN, "I/O  "));
539 		log_printf("%-4s  ", p->bus_type);
540 		log_printf("%-3d  ", p->schizo_portid);
541 		log_printf("%c    ", p->pci_bus);
542 		log_printf("%-1s    ", p->slot_str);
543 		log_printf("%-3d ", p->freq);
544 		switch (p->pci_bus) {
545 		case 'A':
546 			log_printf(dgettext(TEXT_DOMAIN, " 66  "));
547 			break;
548 		case 'B':
549 			log_printf(dgettext(TEXT_DOMAIN, " 33  "));
550 			break;
551 		default:
552 			log_printf(dgettext(TEXT_DOMAIN, "  -  "));
553 			break;
554 		}
555 
556 		log_printf("%-1d,%-1d  ", p->dev_no, p->func_no);
557 		log_printf("%-5s ", p->status);
558 		log_printf("%-32.32s", p->name);
559 		if (strlen(p->name) > 32)
560 			log_printf(dgettext(TEXT_DOMAIN, "+ "));
561 		else
562 			log_printf(dgettext(TEXT_DOMAIN, "  "));
563 		log_printf("%-22.22s", p->model);
564 		if (strlen(p->model) > 22)
565 			log_printf(dgettext(TEXT_DOMAIN, "+"));
566 
567 #ifdef DEBUG
568 		log_printf(dgettext(TEXT_DOMAIN, "%s  "), p->notes);
569 #endif
570 		log_printf("\n");
571 	}
572 }
573 
574 /*
575  * display_ffb
576  *
577  * There are no FFB's on a Daktari, however in the generic library,
578  * the display_ffb() function is implemented so we have to define an
579  * empty function here.
580  */
581 /* ARGSUSED */
582 void
583 display_ffb(Board_node *board, int table)
584 {}
585 
586 
587 /*
588  * ----------------------------------------------------------------------------
589  */
590 
591 /* ARGSUSED */
592 void
593 display_diaginfo(int flag, Prom_node *root, Sys_tree *tree,
594 	struct system_kstat_data *kstats)
595 {
596 	/* NOTE(ARGUNUSED(kstats)) */
597 	/*
598 	 * Now display the last powerfail time and the fatal hardware
599 	 * reset information. We do this under a couple of conditions.
600 	 * First if the user asks for it. The second is if the user
601 	 * told us to do logging, and we found a system failure.
602 	 */
603 	if (flag) {
604 		/*
605 		 * display time of latest powerfail. Not all systems
606 		 * have this capability. For those that do not, this
607 		 * is just a no-op.
608 		 */
609 		disp_powerfail(root);
610 
611 		(void) disp_envc_status();
612 
613 		/* platform_disp_prom_version(tree); */
614 		dak_display_hw_revisions(root, tree->bd_list);
615 	}
616 }
617 
618 /*
619  * local functions
620  */
621 
622 /*
623  * disp_envc_status
624  *
625  * This routine displays the environmental status passed up from
626  * device drivers via the envlibobj.so library.
627  * This is a Daktari specific environmental information display routine.
628  */
629 int
630 disp_envc_status()
631 {
632 	int err;
633 	char *system = "SYSTEM";
634 	picl_nodehdl_t system_node, root;
635 
636 	err = picl_initialize();
637 	if (err != PICL_SUCCESS) {
638 		log_printf(dgettext(TEXT_DOMAIN,
639 		    "picl_initialize failed\n"
640 		    "%s\nCannot display environmental status\n"),
641 		    picl_strerror(err));
642 		return (err);
643 	}
644 	err = picl_get_root(&root);
645 	err = find_child_device(root, system, &system_node);
646 	if (err != PICL_SUCCESS) {
647 		log_printf(dgettext(TEXT_DOMAIN,
648 		    "picl_get_node_by_path for the SYSTEM node "
649 		    "failed\n"
650 		    "%s\nCannot display environmental status\n"),
651 		    picl_strerror(err));
652 		return (err);
653 	}
654 
655 	log_printf(dgettext(TEXT_DOMAIN,
656 	    "\n"
657 	    "========================= "
658 	    "Environmental Status "
659 	    "========================="
660 	    "\n"
661 	    "\n"));
662 
663 	dak_env_print_temps(system_node);
664 	dak_env_print_keyswitch(system_node);
665 	dak_env_print_FSP_LEDS(system_node);
666 	dak_env_print_disk(system_node);
667 	dak_env_print_fans(system_node);
668 	dak_env_print_ps(system_node);
669 
670 	(void) picl_shutdown();
671 	return (0);
672 }
673 
674 int
675 dak_env_print_ps(picl_nodehdl_t system_node)
676 {
677 	int		i, r, fail, err = 0;
678 	int32_t		number;
679 	char		name[PICL_PROPNAMELEN_MAX];
680 	picl_nodehdl_t	*ps;
681 	picl_nodehdl_t	*ps_fail[DAK_MAX_PS_FAULT_SENSORS];
682 	picl_nodehdl_t	*ps_I_sensor[DAK_MAX_PS_VOLTAGE_SENSORS];
683 	int32_t		volts[DAK_MAX_PS_VOLTAGE_SENSORS];
684 	char		fault_state
685 	    [DAK_MAX_PS_FAULT_SENSORS][PICL_PROPNAMELEN_MAX];
686 	char		ps_state[PICL_PROPNAMELEN_MAX];
687 	/* Printing out the Power Supply Heading information */
688 	log_printf(dgettext(TEXT_DOMAIN,
689 	    "Power Supplies:\n"
690 	    "---------------\n"
691 	    "                                                    "
692 	    "Current Drain:\n"
693 	    "Supply     Status     Fan Fail  Temp Fail  CS Fail  "
694 	    "3.3V   5V   12V   48V\n"
695 	    "------  ------------  --------  ---------  "
696 	    "-------  ----   --   ---   ---\n"));
697 
698 	err = fill_device_array_from_id(system_node, "PSVC_PS", &number,
699 	    &ps);
700 	if (err != PICL_SUCCESS) {
701 		log_printf(dgettext(TEXT_DOMAIN,
702 		    "failed in fill_device_array_from_id for PS\n"
703 		    "%s\n"), picl_strerror(err));
704 		return (err);
705 	}
706 	/* Printing out the Power Supply Status information */
707 	for (i = 0; i < DAK_MAX_PS; i++) {
708 		/*
709 		 * Re initialize the fail variable so that if
710 		 * one power supply fails, they don't all do also.
711 		 */
712 		fail = 0;
713 
714 		err = picl_get_propval_by_name(ps[i], PICL_PROP_NAME, name,
715 		    PICL_PROPNAMELEN_MAX);
716 		if (err != PICL_SUCCESS) {
717 			continue;
718 		}
719 		err = picl_get_propval_by_name(ps[i], "State", ps_state,
720 		    PICL_PROPNAMELEN_MAX);
721 		if (err != PICL_SUCCESS) {
722 			log_printf(dgettext(TEXT_DOMAIN,
723 			    "Error getting ps[%d]'s state: %s"),
724 			    i, picl_strerror(err));
725 		}
726 
727 		err = fill_device_array_from_id(ps[i], "PSVC_DEV_FAULT_SENSOR",
728 		    &number, &ps_fail[i]);
729 
730 		if (err != PICL_SUCCESS) {
731 			log_printf(dgettext(TEXT_DOMAIN,
732 			    "failed to get present PS fault sensors\n"
733 			    "%s\n"), picl_strerror(err));
734 			return (err);
735 		}
736 
737 		err = fill_device_array_from_id(ps[i], "PSVC_PS_I_SENSOR",
738 		    &number, &ps_I_sensor[i]);
739 
740 		if ((err != PICL_SUCCESS) && (err != PICL_INVALIDHANDLE)) {
741 			log_printf(dgettext(TEXT_DOMAIN,
742 			    "failed to get present PS I sensors\n"
743 			    "%s\n"), picl_strerror(err));
744 		}
745 
746 		log_printf("%s", name);
747 
748 		/*
749 		 * If the AC cord is unplugged, then the power supply
750 		 * sensors will have unreliable values.  In this case,
751 		 * skip to the next power supply.
752 		 */
753 		if (strcmp(ps_state, "HOTPLUGGED") == 0) {
754 			log_printf(dgettext(TEXT_DOMAIN,
755 			    "      UNPLUGGED\n"));
756 			continue;
757 		}
758 
759 		for (r = 0; r < DAK_MAX_PS_FAULT_SENSORS; r++) {
760 			err = picl_get_propval_by_name(ps_fail[i][r], "State",
761 			    fault_state[r], PICL_PROPNAMELEN_MAX);
762 			if (err == PICL_SUCCESS) {
763 				fail =
764 				    strcmp(fault_state[r], "OFF")
765 				    + fail;
766 			} else {
767 				log_printf(dgettext(TEXT_DOMAIN,
768 				    "picl_get_propval_by_name for ps "
769 				    "fault state failed\n"
770 				    "%s\n"), picl_strerror(err));
771 				return (err);
772 			}
773 		}
774 		for (r = 0; r < DAK_MAX_PS_VOLTAGE_SENSORS; r++) {
775 			err = picl_get_propval_by_name(ps_I_sensor[i][r],
776 			    "AtoDSensorValue", &volts[r],
777 			    sizeof (int32_t));
778 		}
779 
780 		if (fail != 0) {
781 			log_printf(dgettext(TEXT_DOMAIN,
782 			    "      FAIL      "));
783 			for (r = 0; r < DAK_MAX_PS_FAULT_SENSORS; r++) {
784 				log_printf(dgettext(TEXT_DOMAIN, "      %-4s"),
785 				    fault_state[r]);
786 			}
787 		} else {
788 			log_printf(dgettext(TEXT_DOMAIN, "      GOOD      "));
789 			for (r = 0; r < DAK_MAX_PS_FAULT_SENSORS; r++) {
790 				log_printf(dgettext(TEXT_DOMAIN, "          "));
791 			}
792 		}
793 		for (r = 0; r < DAK_MAX_PS_VOLTAGE_SENSORS; r++) {
794 			log_printf(dgettext(TEXT_DOMAIN, "    %2d"), volts[r]);
795 		}
796 		log_printf("\n");
797 	}
798 	log_printf("\n");
799 	return (err);
800 }
801 
802 int
803 dak_env_print_fans(picl_nodehdl_t system_node)
804 {
805 	int		i, err = 0;
806 	int32_t		number, fan_speed;
807 	picl_nodehdl_t	*fans;
808 	char		name[PICL_PROPNAMELEN_MAX];
809 	char		enabled[PICL_PROPNAMELEN_MAX];
810 
811 	err = fill_device_array_from_id(system_node, "PSVC_FAN", &number,
812 	    &fans);
813 	if (err != PICL_SUCCESS) {
814 		log_printf(dgettext(TEXT_DOMAIN,
815 		    "failed in fill_device_array_from_id "
816 		    "for FAN\n"
817 		    "%s\n"), picl_strerror(err));
818 		return (err);
819 	}
820 
821 	log_printf("\n");
822 	log_printf(dgettext(TEXT_DOMAIN,
823 	    "=================================\n"));
824 	log_printf("\n");
825 	log_printf(dgettext(TEXT_DOMAIN, "Fan Bank :\n"));
826 	log_printf(dgettext(TEXT_DOMAIN, "----------\n"));
827 	log_printf("\n");
828 	log_printf(dgettext(TEXT_DOMAIN, "Bank                        Speed "
829 	    "        Status        Fan State\n"));
830 	log_printf(dgettext(TEXT_DOMAIN, "                           ( RPMS )"
831 	    "	\n"));
832 	log_printf(dgettext(TEXT_DOMAIN, "----                       --------"
833 	    "      ---------      ---------\n"));
834 
835 
836 	for (i = 0; i < DAK_MAX_FANS; i++) {
837 		char fan_state[PICL_PROPNAMELEN_MAX];
838 		fan_speed = 0;
839 		err = picl_get_propval_by_name(fans[i], PICL_PROP_NAME, name,
840 		    PICL_PROPNAMELEN_MAX);
841 		if (err == PICL_SUCCESS) {
842 			log_printf(dgettext(TEXT_DOMAIN, "%16-s"), name);
843 		} else {
844 			continue;
845 		}
846 
847 		err = picl_get_propval_by_name(fans[i], "Fan-speed",
848 		    &fan_speed, sizeof (int32_t));
849 		if ((err != PICL_SUCCESS) && (err != PICL_INVALIDHANDLE)) {
850 			log_printf(dgettext(TEXT_DOMAIN,
851 			    "failed in picl_get_propval_by_name for "
852 			    "fan speed\n"
853 			    "%s\n"), picl_strerror(err));
854 			return (err);
855 		}
856 
857 		if ((strcmp(name, "CPU0_PRIM_FAN") != 0) &&
858 		    (strcmp(name, "CPU1_PRIM_FAN") != 0)) {
859 			err = picl_get_propval_by_name(fans[i], "Fan-switch",
860 			    enabled, PICL_PROPNAMELEN_MAX);
861 			if ((err != PICL_SUCCESS) &&
862 			    (err != PICL_INVALIDHANDLE)) {
863 				log_printf(dgettext(TEXT_DOMAIN,
864 				    "failed in picl_get_propval_by_name for"
865 				    " fan enabled/disabled\n"
866 				    "%s\n"), picl_strerror(err));
867 				return (err);
868 			}
869 			/*
870 			 * Display the fan's speed and whether or not
871 			 * it's enabled.
872 			 */
873 			if (strcmp(enabled, "ON") == 0) {
874 				log_printf(dgettext(TEXT_DOMAIN,
875 				    "\t     %4d        [ENABLED]"),
876 				    fan_speed);
877 			} else {
878 				log_printf(dgettext(TEXT_DOMAIN,
879 				    "\t        0        [DISABLED]"));
880 			}
881 
882 		} else {
883 			/* Display the fan's speed */
884 			log_printf(dgettext(TEXT_DOMAIN, "\t     %4d"),
885 			    fan_speed);
886 			log_printf(dgettext(TEXT_DOMAIN,
887 			    "        [ENABLED]"));
888 		}
889 
890 		err = picl_get_propval_by_name(fans[i], "State", fan_state,
891 		    PICL_PROPNAMELEN_MAX);
892 		if (err != PICL_SUCCESS) {
893 			log_printf(dgettext(TEXT_DOMAIN,
894 			    "picl_get_propval_by_name failed: %s"),
895 			    picl_strerror(err));
896 			return (err);
897 		}
898 		log_printf(dgettext(TEXT_DOMAIN, "\t    %s\n"), fan_state);
899 	}
900 	log_printf("\n");
901 	log_printf(dgettext(TEXT_DOMAIN,
902 	    "=================================\n"));
903 	log_printf("\n");
904 
905 	return (err);
906 }
907 
908 int
909 dak_env_print_disk(picl_nodehdl_t system_node)
910 {
911 	int		i, err;
912 	int32_t		number;
913 	picl_nodehdl_t	*disks;
914 	picl_nodehdl_t	disk_slots[DAK_MAX_DISKS];
915 	picl_nodehdl_t	disk_fault_leds[DAK_MAX_DISKS];
916 	picl_nodehdl_t	disk_remove_leds[DAK_MAX_DISKS];
917 	char		led_state[PICL_PROPNAMELEN_MAX];
918 	char		name[PICL_PROPNAMELEN_MAX];
919 
920 	err = fill_device_array_from_id(system_node, "PSVC_DISK", &number,
921 	    &disks);
922 	if (err != PICL_SUCCESS) {
923 		log_printf(dgettext(TEXT_DOMAIN,
924 		    "failed in fill_device_array_from_id for "
925 		    "DISK\n"
926 		    "%s\n"), picl_strerror(err));
927 		return (err);
928 	}
929 
930 	log_printf(dgettext(TEXT_DOMAIN,
931 	    "Disk Status:\n"
932 	    "	  Presence	Fault LED	Remove LED\n"));
933 
934 	for (i = 0; i < DAK_MAX_DISKS; i++) {
935 		err = picl_get_propval_by_name(disks[i], PICL_PROP_NAME, name,
936 		    PICL_PROPNAMELEN_MAX);
937 		switch (err) {
938 		case PICL_SUCCESS:
939 			log_printf(dgettext(TEXT_DOMAIN, "DISK  %2d: [%7s]"),
940 			    i, "PRESENT");
941 			break;
942 		case PICL_INVALIDHANDLE:
943 			log_printf(dgettext(TEXT_DOMAIN, "DISK  %2d: [%7s]"),
944 			    i, "EMPTY");
945 			log_printf("\n");
946 			continue;
947 		default:
948 			log_printf(dgettext(TEXT_DOMAIN,
949 			    "Failed picl_get_propval_by_name for "
950 			    "disk %d with %s\n"), i, picl_strerror(err));
951 			return (err);
952 		}
953 
954 		err = fill_device_from_id(disks[i], "PSVC_PARENT",
955 		    &(disk_slots[i]));
956 		switch (err) {
957 		case PICL_SUCCESS:
958 			break;
959 		case PICL_INVALIDHANDLE:
960 			continue;
961 		default:
962 			log_printf(dgettext(TEXT_DOMAIN,
963 			    "failed in fill_device_from_id for disk "
964 			    "slot\n"
965 			    "%s\n"), picl_strerror(err));
966 			return (err);
967 		}
968 
969 		err = fill_device_from_id(disk_slots[i], "PSVC_SLOT_FAULT_LED",
970 		    &disk_fault_leds[i]);
971 		if (err != PICL_SUCCESS) {
972 			log_printf(dgettext(TEXT_DOMAIN,
973 			    "failed in fill_device_from_id for disk slot "
974 			    "fault led\n"
975 			    "%s\n"), picl_strerror(err));
976 			return (err);
977 		}
978 		err = picl_get_propval_by_name(disk_fault_leds[i],
979 		    "State", led_state, PICL_PROPNAMELEN_MAX);
980 		if (err == PICL_SUCCESS) {
981 			log_printf(dgettext(TEXT_DOMAIN, "	   [%3s]"),
982 			    led_state);
983 		} else {
984 			log_printf(dgettext(TEXT_DOMAIN,
985 			    "picl_get_propval_by_name for fault led_state"
986 			    " failed\n"
987 			    "%s\n"), picl_strerror(err));
988 			return (err);
989 		}
990 		err = fill_device_from_id(disk_slots[i], "PSVC_SLOT_REMOVE_LED",
991 		    &disk_remove_leds[i]);
992 		if (err != PICL_SUCCESS) {
993 			log_printf(dgettext(TEXT_DOMAIN,
994 			    "failed in fill_device_from_id for disk slot "
995 			    "remove led\n"
996 			    "%s\n"), picl_strerror(err));
997 			return (err);
998 		}
999 
1000 		err = picl_get_propval_by_name(disk_remove_leds[i],
1001 		    "State", led_state, PICL_PROPNAMELEN_MAX);
1002 		if (err == PICL_SUCCESS) {
1003 			log_printf(dgettext(TEXT_DOMAIN,
1004 			    "	   [%3s]"), led_state);
1005 		} else {
1006 			log_printf(dgettext(TEXT_DOMAIN,
1007 			    "picl_get_propval_by_name for remove"
1008 			    " led_state failed\n"
1009 			    "%s\n"), picl_strerror(err));
1010 			return (err);
1011 		}
1012 		log_printf("\n");
1013 	}
1014 	return (err);
1015 }
1016 
1017 int
1018 dak_env_print_FSP_LEDS(picl_nodehdl_t system_node)
1019 {
1020 	int		i, err = 0;
1021 	int32_t		number;
1022 	picl_nodehdl_t	*fsp_leds;
1023 	char		led_state[PICL_PROPNAMELEN_MAX];
1024 
1025 	err = fill_device_array_from_id(system_node, "PSVC_FSP_LED", &number,
1026 	    &fsp_leds);
1027 	if (err != PICL_SUCCESS) {
1028 		log_printf(dgettext(TEXT_DOMAIN,
1029 		    "failed in fill_device_array_from_id for "
1030 		    "FSP_LED\n"
1031 		    "%s\n"), picl_strerror(err));
1032 		return (err);
1033 	}
1034 
1035 	log_printf(dgettext(TEXT_DOMAIN,
1036 	    "System LED Status:\n"
1037 	    "                   GEN FAULT                REMOVE\n"));
1038 	for (i = 0; i < DAK_MAX_FSP_LEDS; i++) {
1039 		err = picl_get_propval_by_name(fsp_leds[i], "State",
1040 		    led_state, PICL_PROPNAMELEN_MAX);
1041 		if (err != PICL_SUCCESS) {
1042 			log_printf(dgettext(TEXT_DOMAIN,
1043 			    "picl_get_propval_by_name for led_state"
1044 			    " failed\n"
1045 			    "%s\n"), picl_strerror(err));
1046 			return (err);
1047 		}
1048 
1049 		log_printf(dgettext(TEXT_DOMAIN,
1050 		    "                    [%3s]"), led_state);
1051 	}
1052 	log_printf("\n\n");
1053 	log_printf(dgettext(TEXT_DOMAIN,
1054 	    "                   DISK FAULT               "));
1055 	log_printf(dgettext(TEXT_DOMAIN, "POWER FAULT\n"));
1056 	for (i = 2; i < 4; i++) {
1057 		err = picl_get_propval_by_name(fsp_leds[i], "State",
1058 		    led_state, PICL_PROPNAMELEN_MAX);
1059 		if (err != PICL_SUCCESS) {
1060 			log_printf(dgettext(TEXT_DOMAIN,
1061 			    "picl_get_propval_by_name for led_state"
1062 			    " failed\n"
1063 			    "%s\n"), picl_strerror(err));
1064 			return (err);
1065 		}
1066 		log_printf(dgettext(TEXT_DOMAIN, "                    [%3s]"),
1067 		    led_state);
1068 	}
1069 	log_printf("\n\n");
1070 	log_printf(dgettext(TEXT_DOMAIN,
1071 	    "                   LEFT THERMAL FAULT       "
1072 	    "RIGHT THERMAL FAULT\n"));
1073 	for (i = 4; i < 6; i++) {
1074 		err = picl_get_propval_by_name(fsp_leds[i], "State",
1075 		    led_state, PICL_PROPNAMELEN_MAX);
1076 		if (err != PICL_SUCCESS) {
1077 			log_printf(dgettext(TEXT_DOMAIN,
1078 			    "picl_get_propval_by_name for led_state "
1079 			    "failed\n"
1080 			    "%s\n"), picl_strerror(err));
1081 			return (err);
1082 		}
1083 		log_printf(dgettext(TEXT_DOMAIN, "                    [%3s]"),
1084 		    led_state);
1085 	}
1086 	log_printf("\n\n");
1087 	log_printf(dgettext(TEXT_DOMAIN,
1088 	    "                   LEFT DOOR                "
1089 	    "RIGHT DOOR\n"));
1090 	for (i = 6; i < 8; i++) {
1091 		err = picl_get_propval_by_name(fsp_leds[i], "State",
1092 		    led_state, PICL_PROPNAMELEN_MAX);
1093 		if (err != PICL_SUCCESS) {
1094 			log_printf(dgettext(TEXT_DOMAIN,
1095 			    "picl_get_propval_by_name for led_state"
1096 			    " failed\n"
1097 			    "%s\n"), picl_strerror(err));
1098 			return (err);
1099 		}
1100 		log_printf(dgettext(TEXT_DOMAIN, "                    [%3s]"),
1101 		    led_state);
1102 	}
1103 	log_printf("\n\n");
1104 	log_printf(dgettext(TEXT_DOMAIN,
1105 	    "=================================\n"));
1106 	log_printf("\n");
1107 
1108 	return (err);
1109 }
1110 
1111 int
1112 dak_env_print_keyswitch(picl_nodehdl_t system_node)
1113 {
1114 	int 		err = 0;
1115 	picl_nodehdl_t *keyswitch;
1116 	int32_t		number;
1117 	char		ks_pos[PICL_PROPNAMELEN_MAX];
1118 
1119 	err = fill_device_array_from_id(system_node, "PSVC_KEYSWITCH", &number,
1120 	    &keyswitch);
1121 	if (err != PICL_SUCCESS) {
1122 		log_printf(dgettext(TEXT_DOMAIN,
1123 		    "failed in fill_device_array_from_id for "
1124 		    "	PSVC_KEYSWITCH\n"
1125 		    "%s\n"), picl_strerror(err));
1126 		return (err);
1127 	}
1128 
1129 	err = picl_get_propval_by_name(keyswitch[0], "State", ks_pos,
1130 	    PICL_PROPNAMELEN_MAX);
1131 	if (err != PICL_SUCCESS) {
1132 		log_printf(dgettext(TEXT_DOMAIN,
1133 		    "picl_get_propval_by_name for keyswitch state "
1134 		    "failed\n"
1135 		    "%s\n"), picl_strerror(err));
1136 		return (err);
1137 	}
1138 
1139 	log_printf(dgettext(TEXT_DOMAIN,
1140 	    "Front Status Panel:\n"
1141 	    "-------------------\n"
1142 	    "Keyswitch position: "
1143 	    "%s\n"), ks_pos);
1144 	log_printf("\n");
1145 
1146 	return (err);
1147 }
1148 
1149 int
1150 dak_env_print_temps(picl_nodehdl_t system_node)
1151 {
1152 	int		i;
1153 	int		err;
1154 	picl_nodehdl_t	*system_ts_nodes;
1155 	int32_t		temp;
1156 	int32_t		number;
1157 	char		label[PICL_PROPNAMELEN_MAX];
1158 	char		state[PICL_PROPNAMELEN_MAX];
1159 	char		*p;
1160 
1161 	err = fill_device_array_from_id(system_node, "PSVC_TS", &number,
1162 	    &system_ts_nodes);
1163 	if (err != PICL_SUCCESS) {
1164 		return (err);
1165 	}
1166 
1167 	log_printf(dgettext(TEXT_DOMAIN,
1168 	    "System Temperatures (Celsius):\n"
1169 	    "-------------------------------\n"
1170 	    "Device\t\tTemperature\tStatus\n"
1171 	    "---------------------------------------\n"));
1172 
1173 	for (i = 0; i < number; i++) {
1174 		err = picl_get_propval_by_name(system_ts_nodes[i],
1175 		    "State", state, sizeof (state));
1176 		if (err != PICL_SUCCESS) {
1177 			if (err == PICL_INVALIDHANDLE) {
1178 				strcpy(state, "n/a");
1179 			} else {
1180 				log_printf("%s\n", picl_strerror(err));
1181 				return (err);
1182 			}
1183 		}
1184 		err = picl_get_propval_by_name(system_ts_nodes[i],
1185 		    PICL_PROP_NAME, label, PICL_PROPNAMELEN_MAX);
1186 		if (err != PICL_SUCCESS) {
1187 			if (err == PICL_INVALIDHANDLE)
1188 				/* This FRU isn't present. Skip it. */
1189 				continue;
1190 			log_printf("%s\n", picl_strerror(err));
1191 			return (err);
1192 		}
1193 
1194 		/*
1195 		 * The names in the tree are like "CPU0_DIE_TEMPERATURE_SENSOR".
1196 		 * All we want to print is up to the first underscore.
1197 		 */
1198 		p = strchr(label, '_');
1199 		if (p != NULL)
1200 			*p = '\0';
1201 
1202 		err = picl_get_propval_by_name(system_ts_nodes[i],
1203 		    "Temperature", &temp, sizeof (temp));
1204 		if (err != PICL_SUCCESS) {
1205 			log_printf("%s\n", picl_strerror(err));
1206 			return (err);
1207 		}
1208 		log_printf("%s\t\t%3d\t\t%s\n", label, temp, state);
1209 	}
1210 
1211 	log_printf(dgettext(TEXT_DOMAIN,
1212 	    "\n=================================\n\n"));
1213 
1214 	return (PICL_SUCCESS);
1215 }
1216 
1217 static void
1218 dak_display_hw_revisions(Prom_node *root, Board_node *bdlist)
1219 {
1220 	Prom_node	*pnode;
1221 	char		*value;
1222 
1223 	log_printf(dgettext(TEXT_DOMAIN, "\n"
1224 	    "========================= HW Revisions "
1225 	    "=======================================\n\n"));
1226 
1227 	log_printf(dgettext(TEXT_DOMAIN,
1228 	    "System PROM revisions:\n"
1229 	    "----------------------\n"));
1230 
1231 	pnode = dev_find_node(root, "openprom");
1232 	if (pnode != NULL) {
1233 		value = (char *)get_prop_val(find_prop(pnode, "version"));
1234 		log_printf(value);
1235 	}
1236 
1237 	log_printf(dgettext(TEXT_DOMAIN, "\n\n"
1238 	    "IO ASIC revisions:\n"
1239 	    "------------------\n"
1240 	    "         Port\n"
1241 	    "Model     ID  Status Version\n"
1242 	    "-------- ---- ------ -------\n"));
1243 
1244 	display_schizo_revisions(bdlist);
1245 }
1246 
1247 static void
1248 display_schizo_revisions(Board_node *bdlist)
1249 {
1250 	Prom_node	*pnode;
1251 	int		*int_val;
1252 	int		portid;
1253 	int		prev_portid = -1;
1254 	char		*status_a = NULL;
1255 	char		*status_b = NULL;
1256 	int		revision;
1257 #ifdef DEBUG
1258 	uint32_t	a_notes, b_notes;
1259 #endif
1260 	int		pci_bus;
1261 	Board_node	*bnode;
1262 	bnode = bdlist;
1263 
1264 	while (bnode != NULL) {
1265 		/*
1266 		 * search this board node for all Schizos
1267 		 */
1268 		for (pnode = dev_find_node_by_compat(bnode->nodes,
1269 		    SCHIZO_COMPAT_PROP); pnode != NULL;
1270 		    pnode = dev_next_node_by_compat(pnode,
1271 		    SCHIZO_COMPAT_PROP)) {
1272 
1273 			/*
1274 			 * get the reg property to determine
1275 			 * whether we are looking at side A or B
1276 			 */
1277 			int_val = (int *)get_prop_val
1278 			    (find_prop(pnode, "reg"));
1279 			if (int_val != NULL) {
1280 				int_val ++; /* second integer in array */
1281 				pci_bus = ((*int_val) & 0x7f0000);
1282 			}
1283 
1284 			/* get portid */
1285 			int_val = (int *)get_prop_val
1286 			    (find_prop(pnode, "portid"));
1287 			if (int_val == NULL)
1288 				continue;
1289 
1290 			portid = *int_val;
1291 
1292 			/*
1293 			 * If this is a new portid and it is PCI bus B,
1294 			 * we skip onto the PCI bus A.
1295 			 */
1296 			if ((portid != prev_portid) && (pci_bus == 0x700000)) {
1297 				prev_portid = portid;
1298 				/* status */
1299 				status_b = (char *)get_prop_val
1300 				    (find_prop(pnode, "status"));
1301 #ifdef DEBUG
1302 				b_notes = pci_bus;
1303 #endif
1304 				continue; /* skip to the next schizo */
1305 			}
1306 
1307 			/*
1308 			 * This must be side A of the same Schizo.
1309 			 * Gather all its props and display them.
1310 			 */
1311 #ifdef DEBUG
1312 			a_notes = pci_bus;
1313 #endif
1314 
1315 			prev_portid = portid;
1316 
1317 			int_val = (int *)get_prop_val
1318 			    (find_prop(pnode, "version#"));
1319 			if (int_val != NULL)
1320 				revision = *int_val;
1321 			else
1322 				revision = -1;
1323 
1324 			status_a = (char *)get_prop_val(find_prop
1325 			    (pnode, "status"));
1326 
1327 			log_printf(dgettext(TEXT_DOMAIN, "Schizo    "));
1328 
1329 			log_printf(dgettext(TEXT_DOMAIN, "%-3d "), portid, 0);
1330 
1331 
1332 			log_printf((status_a == NULL && status_b == NULL) ?
1333 			    dgettext(TEXT_DOMAIN, "  ok  ") :
1334 			    dgettext(TEXT_DOMAIN, " fail "));
1335 
1336 			log_printf(dgettext(TEXT_DOMAIN, " %4d   "),
1337 			    revision);
1338 #ifdef DEBUG
1339 			log_printf(" 0x%x 0x%x", a_notes, b_notes);
1340 #endif
1341 			log_printf("\n");
1342 		}
1343 		bnode = bnode->next;
1344 	}
1345 }
1346