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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <alloca.h>
29 #include <errno.h>
30 #include <libintl.h>
31 #include <sys/utsname.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/openpromio.h>
35 #include <sys/ddi.h>
36 #include <syslog.h>
37 #include <fcntl.h>
38 #include <dirent.h>
39 #include <unistd.h>
40 #include <locale.h>
41 #include <picl.h>
42 #include "pdevinfo.h"
43 #include "display.h"
44 #include "display_sun4u.h"
45 #include "picldefs.h"
46 #include "libprtdiag.h"
47
48 #if !defined(TEXT_DOMAIN)
49 #define TEXT_DOMAIN "SYS_TEST"
50 #endif
51
52 #define EM_INIT_FAIL dgettext(TEXT_DOMAIN,\
53 "picl_initialize failed: %s\n")
54 #define EM_GET_ROOT_FAIL dgettext(TEXT_DOMAIN,\
55 "Getting root node failed: %s\n")
56 #define EM_PRTDIAG_FAIL dgettext(TEXT_DOMAIN, "Prtdiag failed!\n")
57
58 #define SIGN_ON_MSG dgettext(TEXT_DOMAIN,\
59 "System Configuration: Oracle Corporation ")
60 #define SYSCLK_FREQ_MSG dgettext(TEXT_DOMAIN,\
61 "System clock frequency: %d MHZ\n")
62 #define MEM_SIZE_MSG dgettext(TEXT_DOMAIN, "Memory size: ")
63
64 #define DEFAULT_BOARD_NUM 0
65 #define DEFAULT_PORTID 0
66 #define CLK_FREQ_66MHZ 66
67 #define USB -1
68 #define HUB -2
69
70 /* bus id */
71 #define PCI_TYPE 1
72
73 /*
74 * PICL classes
75 */
76 #define PICL_CLASS_OPTIONS "options"
77
78 /*
79 * Property names
80 */
81
82 #define OBP_PROP_REG "reg"
83 #define OBP_PROP_CLOCK_FREQ "clock-frequency"
84 #define OBP_PROP_BOARD_NUM "board#"
85 #define OBP_PROP_REVISION_ID "revision-id"
86 #define OBP_PROP_VERSION_NUM "version#"
87 #define OBP_PROP_BOARD_TYPE "board_type"
88 #define OBP_PROP_ECACHE_SIZE "ecache-size"
89 #define OBP_PROP_IMPLEMENTATION "implementation#"
90 #define OBP_PROP_MASK "mask#"
91 #define OBP_PROP_COMPATIBLE "compatible"
92 #define OBP_PROP_BANNER_NAME "banner-name"
93 #define OBP_PROP_MODEL "model"
94 #define OBP_PROP_66MHZ_CAPABLE "66mhz-capable"
95 #define OBP_PROP_FBC_REG_ID "fbc_reg_id"
96 #define OBP_PROP_VERSION "version"
97
98 #define PROP_POWERFAIL_TIME "powerfail-time"
99 #define PICL_PROP_LOW_WARNING_THRESHOLD "LowWarningThreshold"
100
101 #define DEFAULT_LINE_WIDTH 78
102 #define HEADING_SYMBOL "="
103
104 #define SIZE_FIELD 11
105 #define MAX_IWAYS 32
106
107 typedef struct bank_list {
108 picl_nodehdl_t nodeh;
109 uint32_t iway_count;
110 uint32_t iway[MAX_IWAYS];
111 struct bank_list *next;
112 } bank_list_t;
113
114 typedef struct {
115 uint64_t base;
116 uint64_t size;
117 int ifactor;
118 int bank_count;
119 } seg_info_t;
120
121 static struct io_card *io_card_list = NULL; /* The head of the IO card list */
122 static bank_list_t *mem_banks = NULL;
123 static int mem_xfersize;
124 static int no_xfer_size = 0;
125
126 static const char *io_device_table[] = {
127 "block",
128 "disk",
129 "cdrom",
130 "floppy",
131 "tape",
132 "network",
133 "display",
134 "serial",
135 "parallel",
136 "scsi",
137 "scsi-2",
138 "scsi-3",
139 "ide",
140 "fcal",
141 "keyboard",
142 "mouse",
143 "dma"
144 };
145
146 #define NIODEVICE (sizeof (io_device_table) / sizeof (io_device_table[0]))
147
148 static const char *bus_table[] = {
149 "ebus",
150 "isa",
151 "pmu"
152 };
153
154 #define NBUS (sizeof (bus_table) / sizeof (bus_table[0]))
155
156 /*
157 * check if it is an IO deice
158 * return 1 if this is a io device; return 0 for else.
159 */
160 static int
is_io_device(char * device_class)161 is_io_device(char *device_class)
162 {
163 int i;
164
165 for (i = 0; i < NIODEVICE; i++) {
166 if (strcmp(device_class, io_device_table[i]) == 0)
167 return (1);
168 }
169
170 return (0);
171 }
172
173 /*
174 * check if it is a bus
175 * return 1 if this is a bus; return 0 for else.
176 */
177 static int
is_bus(char * device_class)178 is_bus(char *device_class)
179 {
180 int i;
181
182 for (i = 0; i < NBUS; i++) {
183 if (strcmp(device_class, bus_table[i]) == 0)
184 return (1);
185 }
186
187 return (0);
188 }
189
190 /*
191 * search children to get the node by the nodename
192 * return node handler in picl_nodehdl_t *nodeh
193 */
194 static int
picldiag_get_node_by_name(picl_nodehdl_t rooth,char * name,picl_nodehdl_t * nodeh)195 picldiag_get_node_by_name(picl_nodehdl_t rooth, char *name,
196 picl_nodehdl_t *nodeh)
197 {
198 picl_nodehdl_t childh;
199 int err;
200 char *nodename;
201
202 nodename = alloca(strlen(name) + 1);
203 if (nodename == NULL)
204 return (PICL_FAILURE);
205
206 err = picl_get_propval_by_name(rooth, PICL_PROP_CHILD, &childh,
207 sizeof (picl_nodehdl_t));
208
209 while (err == PICL_SUCCESS) {
210 err = picl_get_propval_by_name(childh, PICL_PROP_NAME,
211 nodename, (strlen(name) + 1));
212 if (err != PICL_SUCCESS) {
213 err = picl_get_propval_by_name(childh, PICL_PROP_PEER,
214 &childh, sizeof (picl_nodehdl_t));
215 continue;
216 }
217
218 if (strcmp(nodename, name) == 0) {
219 *nodeh = childh;
220 return (PICL_SUCCESS);
221 }
222
223 err = picl_get_propval_by_name(childh, PICL_PROP_PEER,
224 &childh, sizeof (picl_nodehdl_t));
225 }
226
227 return (err);
228 }
229
230 /*
231 * get the value by the property name of the string prop
232 * the value will be in outbuf
233 * Caller must free the outbuf
234 */
235 static int
picldiag_get_string_propval(picl_nodehdl_t modh,char * prop_name,char ** outbuf)236 picldiag_get_string_propval(picl_nodehdl_t modh, char *prop_name, char **outbuf)
237 {
238 int err;
239 picl_prophdl_t proph;
240 picl_propinfo_t pinfo;
241 char *prop_value;
242
243 err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
244 if (err != PICL_SUCCESS)
245 return (err);
246
247 /*
248 * If it is not a string prop, return NULL
249 */
250 if (pinfo.type != PICL_PTYPE_CHARSTRING)
251 return (PICL_FAILURE);
252
253 prop_value = malloc(pinfo.size);
254 if (prop_value == NULL)
255 return (PICL_FAILURE);
256
257 err = picl_get_propval(proph, prop_value, pinfo.size);
258 if (err != PICL_SUCCESS) {
259 free(prop_value);
260 return (err);
261 }
262
263 *outbuf = prop_value;
264 return (PICL_SUCCESS);
265 }
266
267
268 /*
269 * return the value as a signed integer
270 */
271
272 static int64_t
picldiag_get_int_propval(picl_nodehdl_t modh,char * prop_name,int * ret)273 picldiag_get_int_propval(picl_nodehdl_t modh, char *prop_name, int *ret)
274 {
275 int err;
276 picl_prophdl_t proph;
277 picl_propinfo_t pinfo;
278 int8_t int8v;
279 int16_t int16v;
280 int32_t int32v;
281 int64_t int64v;
282
283 err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
284 if (err != PICL_SUCCESS) {
285 *ret = err;
286 return (0);
287 }
288
289 /*
290 * If it is not an int, uint or byte array prop, return failure
291 */
292 if ((pinfo.type != PICL_PTYPE_INT) &&
293 (pinfo.type != PICL_PTYPE_UNSIGNED_INT) &&
294 (pinfo.type != PICL_PTYPE_BYTEARRAY)) {
295 *ret = PICL_FAILURE;
296 return (0);
297 }
298
299 switch (pinfo.size) {
300 case sizeof (int8_t):
301 err = picl_get_propval(proph, &int8v, sizeof (int8v));
302 *ret = err;
303 return (int8v);
304 case sizeof (int16_t):
305 err = picl_get_propval(proph, &int16v, sizeof (int16v));
306 *ret = err;
307 return (int16v);
308 case sizeof (int32_t):
309 err = picl_get_propval(proph, &int32v, sizeof (int32v));
310 *ret = err;
311 return (int32v);
312 case sizeof (int64_t):
313 err = picl_get_propval(proph, &int64v, sizeof (int64v));
314 *ret = err;
315 return (int64v);
316 default: /* not supported size */
317 *ret = PICL_FAILURE;
318 return (0);
319 }
320 }
321
322 /*
323 * return the value of the uint prop
324 */
325 static uint64_t
picldiag_get_uint_propval(picl_nodehdl_t modh,char * prop_name,int * ret)326 picldiag_get_uint_propval(picl_nodehdl_t modh, char *prop_name, int *ret)
327 {
328 int err;
329 picl_prophdl_t proph;
330 picl_propinfo_t pinfo;
331 uint8_t uint8v;
332 uint16_t uint16v;
333 uint32_t uint32v;
334 uint64_t uint64v;
335
336 err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
337 if (err != PICL_SUCCESS) {
338 *ret = err;
339 return (0);
340 }
341
342 /*
343 * If it is not an int or uint prop, return failure
344 */
345 if ((pinfo.type != PICL_PTYPE_INT) &&
346 (pinfo.type != PICL_PTYPE_UNSIGNED_INT)) {
347 *ret = PICL_FAILURE;
348 return (0);
349 }
350
351 /* uint prop */
352
353 switch (pinfo.size) {
354 case sizeof (uint8_t):
355 err = picl_get_propval(proph, &uint8v, sizeof (uint8v));
356 *ret = err;
357 return (uint8v);
358 case sizeof (uint16_t):
359 err = picl_get_propval(proph, &uint16v, sizeof (uint16v));
360 *ret = err;
361 return (uint16v);
362 case sizeof (uint32_t):
363 err = picl_get_propval(proph, &uint32v, sizeof (uint32v));
364 *ret = err;
365 return (uint32v);
366 case sizeof (uint64_t):
367 err = picl_get_propval(proph, &uint64v, sizeof (uint64v));
368 *ret = err;
369 return (uint64v);
370 default: /* not supported size */
371 *ret = PICL_FAILURE;
372 return (0);
373 }
374 }
375
376 /*
377 * return the value of the float prop
378 */
379 static float
picldiag_get_float_propval(picl_nodehdl_t modh,char * prop_name,int * ret)380 picldiag_get_float_propval(picl_nodehdl_t modh, char *prop_name, int *ret)
381 {
382 int err;
383 picl_prophdl_t proph;
384 picl_propinfo_t pinfo;
385 float floatv;
386
387 err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
388 if (err != PICL_SUCCESS) {
389 *ret = err;
390 return ((float)0);
391 }
392
393 /*
394 * If it is not a float prop, return failure
395 */
396 if (pinfo.type != PICL_PTYPE_FLOAT) {
397 *ret = PICL_FAILURE;
398 return ((float)0);
399 }
400
401 *ret = picl_get_propval(proph, &floatv, sizeof (floatv));
402 return (floatv);
403 }
404
405 /*
406 * get the clock frequency
407 */
408 static int
picldiag_get_clock_freq(picl_nodehdl_t modh,uint32_t * freq)409 picldiag_get_clock_freq(picl_nodehdl_t modh, uint32_t *freq)
410 {
411 #define ROUND_TO_MHZ(x) (((x) + 500000)/ 1000000)
412 int err;
413 uint64_t clk_freq;
414
415 clk_freq = picldiag_get_uint_propval(modh, OBP_PROP_CLOCK_FREQ, &err);
416 if (err != PICL_SUCCESS)
417 return (err);
418
419 *freq = ROUND_TO_MHZ(clk_freq);
420
421 return (PICL_SUCCESS);
422 }
423
424 /*
425 * get the clock frequency from parent
426 */
427 static int
picldiag_get_clock_from_parent(picl_nodehdl_t nodeh,uint32_t * clk)428 picldiag_get_clock_from_parent(picl_nodehdl_t nodeh, uint32_t *clk)
429 {
430 picl_nodehdl_t parenth;
431 int err;
432
433
434 err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT,
435 &parenth, sizeof (parenth));
436
437 while (err == PICL_SUCCESS) {
438 err = picldiag_get_clock_freq(parenth, clk);
439 if (err != PICL_PROPNOTFOUND)
440 return (err);
441
442 err = picl_get_propval_by_name(parenth, PICL_PROP_PARENT,
443 &parenth, sizeof (parenth));
444 }
445
446 return (err);
447 }
448
449 /*
450 * get _fru_parent prop
451 * If not found, then travese superiors (parent nodes) until
452 * a _fru_parent property is found.
453 * If not found, no fru parent
454 */
455 static int
picldiag_get_fru_parent(picl_nodehdl_t nodeh,picl_nodehdl_t * fruparenth)456 picldiag_get_fru_parent(picl_nodehdl_t nodeh, picl_nodehdl_t *fruparenth)
457 {
458 picl_nodehdl_t fruh;
459 int err;
460
461 /* find fru parent */
462 err = picl_get_propval_by_name(nodeh, PICL_REFPROP_FRU_PARENT,
463 &fruh, sizeof (fruh));
464
465 if (err != PICL_SUCCESS)
466 err = picl_get_propval_by_name(nodeh, PICL_REFPROP_LOC_PARENT,
467 &fruh, sizeof (fruh));
468
469 while (err == PICL_PROPNOTFOUND) {
470 err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT,
471 &nodeh, sizeof (nodeh));
472 if (err != PICL_SUCCESS)
473 return (err);
474
475 err = picl_get_propval_by_name(nodeh, PICL_REFPROP_FRU_PARENT,
476 &fruh, sizeof (fruh));
477 if (err != PICL_SUCCESS)
478 err = picl_get_propval_by_name(nodeh,
479 PICL_REFPROP_LOC_PARENT, &fruh, sizeof (fruh));
480 }
481
482 if (err == PICL_SUCCESS)
483 *fruparenth = fruh;
484
485 return (err);
486 }
487
488 /*
489 * get label
490 *
491 * To get the label, use the following algorithm:
492 * Lookup "Label" property in the fru node itself. If no
493 * Label found, then traverse superiors (parent nodes) until
494 * a Label property is found.
495 * if not found, then no label
496 */
497 static int
picldiag_get_label(picl_nodehdl_t nodeh,char ** label)498 picldiag_get_label(picl_nodehdl_t nodeh, char **label)
499 {
500 int err;
501
502 err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL, label);
503
504 while (err == PICL_PROPNOTFOUND) {
505 err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT,
506 &nodeh, sizeof (nodeh));
507 if (err != PICL_SUCCESS)
508 return (err);
509
510 err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL,
511 label);
512 }
513
514 return (err);
515 }
516
517 /*
518 * get combined label
519 *
520 * like picldiag_get_label, except concatenates the labels of parent locations
521 * eg SB0/P3 for processor P3 on system board SB0
522 *
523 * if caller specifies non-zero label length, label will be cut to specified
524 * length.
525 * negative length is left justified, non-negative length is right justified
526 */
527 static int
picldiag_get_combined_label(picl_nodehdl_t nodeh,char ** label,int lablen)528 picldiag_get_combined_label(picl_nodehdl_t nodeh, char **label, int lablen)
529 {
530 int err;
531 char *ptr;
532 char *ptr1 = NULL;
533 char *ptr2;
534 int len;
535
536 err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL, &ptr1);
537 if (err != PICL_PROPNOTFOUND && err != PICL_SUCCESS)
538 return (err);
539
540 for (;;) {
541 err = picl_get_propval_by_name(nodeh, PICL_PROP_PARENT,
542 &nodeh, sizeof (nodeh));
543 if (err == PICL_PROPNOTFOUND)
544 break;
545 if (err != PICL_SUCCESS)
546 return (err);
547
548 err = picldiag_get_string_propval(nodeh, PICL_PROP_LABEL, &ptr);
549 if (err == PICL_SUCCESS) {
550 if (ptr1 == NULL) {
551 ptr1 = ptr;
552 } else {
553 ptr2 = malloc(strlen(ptr1) + strlen(ptr) + 2);
554 if (ptr2 == NULL)
555 return (PICL_FAILURE);
556 (void) strlcpy(ptr2, ptr, strlen(ptr)-1);
557 (void) strlcat(ptr2, "/", 1);
558 (void) strlcat(ptr2, ptr1, strlen(ptr1)-1);
559 (void) strlcat(ptr2, "\0", 1);
560
561 (void) free(ptr);
562 (void) free(ptr1);
563 ptr1 = ptr2;
564 }
565 } else if (err != PICL_PROPNOTFOUND) {
566 return (err);
567 }
568 }
569
570 if (ptr1 == NULL)
571 return (PICL_PROPNOTFOUND);
572
573 len = strlen(ptr1);
574 /* if no string truncation is desired or required */
575 if ((lablen == 0) || (len <= abs(lablen))) {
576 *label = ptr1;
577 return (PICL_SUCCESS);
578 }
579
580 /* string truncation is required; alloc space for (lablen + \0) */
581 ptr = malloc(abs(lablen) + 1);
582 if (ptr == 0)
583 return (PICL_FAILURE);
584 if (lablen > 0) {
585 /* right justification; label = "+<string>\0" */
586 strlcpy(ptr, "+", 1);
587 strlcat(ptr, ptr1 + len - lablen + 1, lablen + 1);
588 } else {
589 /* left justification; label = "<string>+\0" */
590 strlcpy(ptr, ptr1, abs(lablen) - 1);
591 strcat(ptr, "+");
592 }
593
594 *label = ptr;
595 return (PICL_SUCCESS);
596 }
597
598 /*
599 * return the first compatible value
600 */
601 static int
picldiag_get_first_compatible_value(picl_nodehdl_t nodeh,char ** outbuf)602 picldiag_get_first_compatible_value(picl_nodehdl_t nodeh, char **outbuf)
603 {
604 int err;
605 picl_prophdl_t proph;
606 picl_propinfo_t pinfo;
607 picl_prophdl_t tblh;
608 picl_prophdl_t rowproph;
609 char *pval;
610
611 err = picl_get_propinfo_by_name(nodeh, OBP_PROP_COMPATIBLE,
612 &pinfo, &proph);
613 if (err != PICL_SUCCESS)
614 return (err);
615
616 if (pinfo.type == PICL_PTYPE_CHARSTRING) {
617 pval = malloc(pinfo.size);
618 if (pval == NULL)
619 return (PICL_FAILURE);
620 err = picl_get_propval(proph, pval, pinfo.size);
621 if (err != PICL_SUCCESS) {
622 free(pval);
623 return (err);
624 }
625 *outbuf = pval;
626 return (PICL_SUCCESS);
627 }
628
629 if (pinfo.type != PICL_PTYPE_TABLE)
630 return (PICL_FAILURE);
631
632 /* get first string from table */
633 err = picl_get_propval(proph, &tblh, pinfo.size);
634 if (err != PICL_SUCCESS)
635 return (err);
636
637 err = picl_get_next_by_row(tblh, &rowproph);
638 if (err != PICL_SUCCESS)
639 return (err);
640
641 err = picl_get_propinfo(rowproph, &pinfo);
642 if (err != PICL_SUCCESS)
643 return (err);
644
645 pval = malloc(pinfo.size);
646 if (pval == NULL)
647 return (PICL_FAILURE);
648
649 err = picl_get_propval(rowproph, pval, pinfo.size);
650 if (err != PICL_SUCCESS) {
651 free(pval);
652 return (err);
653 }
654
655 *outbuf = pval;
656 return (PICL_SUCCESS);
657 }
658
659 /*
660 * print the header in the center
661 */
662 static void
logprintf_header(char * header,size_t line_width)663 logprintf_header(char *header, size_t line_width)
664 {
665 size_t start_pos;
666 size_t i;
667
668 log_printf("\n");
669 start_pos = (line_width - strlen(header) - 2) / 2;
670
671 for (i = 0; i < start_pos; i++)
672 log_printf("%s", HEADING_SYMBOL);
673
674 log_printf(" %s ", header);
675
676 for (i = 0; i < start_pos; i++)
677 log_printf("%s", HEADING_SYMBOL);
678
679 log_printf("\n");
680 }
681
682 /*
683 * print the size
684 */
685 static void
logprintf_size(uint64_t size)686 logprintf_size(uint64_t size)
687 {
688
689 uint64_t kbyte = 1024;
690 uint64_t mbyte = 1024 * 1024;
691 uint64_t gbyte = 1024 * 1024 * 1024;
692 uint64_t residue;
693 char buf[SIZE_FIELD];
694
695 if (size >= gbyte) {
696 residue = size % gbyte;
697 if (residue == 0)
698 snprintf(buf, sizeof (buf), "%dGB",
699 (int)(size / gbyte));
700 else
701 snprintf(buf, sizeof (buf), "%.2fGB",
702 (float)size / gbyte);
703 } else if (size >= mbyte) {
704 residue = size % mbyte;
705 if (residue == 0)
706 snprintf(buf, sizeof (buf), "%dMB",
707 (int)(size / mbyte));
708 else
709 snprintf(buf, sizeof (buf), "%.2fMB",
710 (float)size / mbyte);
711 } else {
712 residue = size % kbyte;
713 if (residue == 0)
714 snprintf(buf, sizeof (buf), "%dKB",
715 (int)(size / kbyte));
716 else
717 snprintf(buf, sizeof (buf), "%.2fKB",
718 (float)size / kbyte);
719 }
720
721 log_printf("%-10s ", buf);
722 }
723
724 /*
725 * display platform banner
726 */
727 static int
display_platform_banner(picl_nodehdl_t plafh)728 display_platform_banner(picl_nodehdl_t plafh)
729 {
730 char *platform;
731 char *banner_name;
732 int err;
733
734 /*
735 * get PICL_PROP_MACHINE and PICL_PROP_BANNER_NAME
736 */
737 log_printf(SIGN_ON_MSG);
738 err = picldiag_get_string_propval(plafh, PICL_PROP_MACHINE,
739 &platform);
740 if (err != PICL_SUCCESS)
741 return (err);
742 log_printf(" %s", platform);
743 free(platform);
744
745 err = picldiag_get_string_propval(plafh, OBP_PROP_BANNER_NAME,
746 &banner_name);
747 if (err != PICL_SUCCESS)
748 return (err);
749 log_printf(" %s", banner_name);
750 free(banner_name);
751
752 log_printf("\n");
753 return (PICL_SUCCESS);
754 }
755
756 /*
757 * display the clock frequency
758 */
759 static int
display_system_clock(picl_nodehdl_t plafh)760 display_system_clock(picl_nodehdl_t plafh)
761 {
762 uint32_t system_clk;
763 int err;
764
765 err = picldiag_get_clock_freq(plafh, &system_clk);
766 if (err != PICL_SUCCESS)
767 return (err);
768
769 log_printf(SYSCLK_FREQ_MSG, system_clk);
770
771 return (PICL_SUCCESS);
772 }
773
774 /*
775 * callback function to display the memory size
776 */
777 /*ARGSUSED*/
778 static int
memory_callback(picl_nodehdl_t memh,void * args)779 memory_callback(picl_nodehdl_t memh, void *args)
780 {
781 uint64_t mem_size;
782 int err;
783
784 log_printf(MEM_SIZE_MSG);
785 mem_size = picldiag_get_uint_propval(memh, PICL_PROP_SIZE, &err);
786 if (err == PICL_SUCCESS)
787 logprintf_size(mem_size);
788 log_printf("\n");
789 no_xfer_size = 0;
790 mem_xfersize = picldiag_get_uint_propval(memh, PICL_PROP_TRANSFER_SIZE,
791 &err);
792 if (err == PICL_PROPNOTFOUND)
793 no_xfer_size = 1;
794 return (PICL_WALK_TERMINATE);
795 }
796
797 /*
798 * callback function to print cpu information
799 */
800 /*ARGSUSED*/
801 static int
cpu_callback(picl_nodehdl_t nodeh,void * args)802 cpu_callback(picl_nodehdl_t nodeh, void *args)
803 {
804 int err;
805 int id;
806 uint64_t uintval;
807 uint32_t freq;
808 char *impl_name;
809 char *status;
810 picl_prophdl_t parenth;
811 char *label;
812
813 /*
814 * If no ID is found, return
815 */
816 id = picldiag_get_uint_propval(nodeh, PICL_PROP_ID, &err);
817 if (err == PICL_PROPNOTFOUND)
818 return (PICL_WALK_CONTINUE);
819 else if (err != PICL_SUCCESS)
820 return (err);
821 log_printf(" %2d ", id);
822
823 /*
824 * If no freq is found, return
825 */
826 err = picldiag_get_clock_freq(nodeh, &freq);
827 if (err == PICL_PROPNOTFOUND)
828 return (PICL_WALK_CONTINUE);
829 else if (err != PICL_SUCCESS)
830 return (err);
831 log_printf(dgettext(TEXT_DOMAIN, "%4d MHz "), freq);
832
833 /* Ecache size */
834 uintval = picldiag_get_uint_propval(nodeh, OBP_PROP_ECACHE_SIZE, &err);
835 if (err == PICL_PROPNOTFOUND)
836 log_printf(" - ");
837 else if (err == PICL_SUCCESS)
838 logprintf_size(uintval);
839 else
840 return (err);
841
842 /* Implementation */
843 impl_name = NULL;
844 err = picldiag_get_string_propval(nodeh, PICL_PROP_NAME, &impl_name);
845 if (err != PICL_SUCCESS)
846 log_printf(dgettext(TEXT_DOMAIN, " <unknown> "));
847 else
848 log_printf(" %-22s ", impl_name);
849
850 /* CPU Mask */
851 uintval = picldiag_get_uint_propval(nodeh, OBP_PROP_MASK, &err);
852 if (err == PICL_PROPNOTFOUND)
853 log_printf(" - ");
854 else if (err == PICL_SUCCESS)
855 log_printf("%2lld.%-2lld ", (uintval >> 4) & 0xf,
856 uintval & 0xf);
857 else
858 return (err);
859
860 /*
861 * Status - if the node has a status property then display that
862 * otherwise display the State property
863 */
864 err = picldiag_get_string_propval(nodeh, PICL_PROP_STATUS, &status);
865 if (err == PICL_SUCCESS) {
866 log_printf("%-12s", status);
867 free(status);
868 } else if (err != PICL_PROPNOTFOUND && err !=
869 PICL_PROPVALUNAVAILABLE && err != PICL_ENDOFLIST) {
870 return (err);
871 } else {
872 err = picldiag_get_string_propval(nodeh,
873 PICL_PROP_STATE, &status);
874 if (err == PICL_SUCCESS) {
875 log_printf("%-12s", status);
876 free(status);
877 } else if (err != PICL_PROPNOTFOUND && err !=
878 PICL_PROPVALUNAVAILABLE && err !=
879 PICL_ENDOFLIST) {
880 return (err);
881 } else {
882 log_printf(dgettext(TEXT_DOMAIN, "unknown "));
883 }
884 }
885
886 /*
887 * Location: use label of fru parent
888 */
889 err = picldiag_get_fru_parent(nodeh, &parenth);
890 if (err == PICL_PROPNOTFOUND) {
891 log_printf(" - ");
892 } else if (err == PICL_SUCCESS) {
893 err = picldiag_get_combined_label(parenth, &label, 12);
894 if (err == PICL_PROPNOTFOUND)
895 log_printf(" - ");
896 else if (err == PICL_SUCCESS) {
897 log_printf("%s", label);
898 free(label);
899 } else
900 return (err);
901 } else
902 return (err);
903
904 log_printf("\n");
905 return (PICL_WALK_CONTINUE);
906 }
907
908 /*
909 * display cpu information
910 */
911 static int
display_cpu_info(picl_nodehdl_t plafh)912 display_cpu_info(picl_nodehdl_t plafh)
913 {
914 int err;
915
916 /*
917 * Display the table header for CPUs . Then display the CPU
918 * frequency, cache size, and processor revision on all the boards.
919 */
920 logprintf_header(dgettext(TEXT_DOMAIN, "CPUs"), DEFAULT_LINE_WIDTH);
921 log_printf(dgettext(TEXT_DOMAIN, " E$ CPU"
922 " CPU\n"));
923 log_printf(dgettext(TEXT_DOMAIN,
924 "CPU Freq Size Implementation"
925 " Mask Status Location\n"));
926 log_printf("--- -------- ---------- --------------------- "
927 "----- ------ --------\n");
928
929 err = picl_walk_tree_by_class(plafh, PICL_CLASS_CPU, PICL_CLASS_CPU,
930 cpu_callback);
931 return (err);
932 }
933
934 /*
935 * Inserts an io_card structure into the list.
936 */
937 static void
add_io_card(uint32_t board,uint32_t bus_id,uint32_t slot,char * label,uint32_t freq,char * name,char * model,char * status,char * devfs_path)938 add_io_card(uint32_t board, uint32_t bus_id, uint32_t slot, char *label,
939 uint32_t freq, char *name, char *model, char *status, char *devfs_path)
940 {
941 struct io_card card;
942
943 card.display = 1;
944 card.board = board;
945 switch (bus_id) {
946 case PCI_TYPE:
947 strlcpy(card.bus_type, PCI_NAME, MAXSTRLEN);
948 break;
949 default: /* won't reach here */
950 strlcpy(card.bus_type, "", MAXSTRLEN);
951 break;
952 }
953 if (label == NULL)
954 card.slot = slot;
955 else {
956 card.slot = PCI_SLOT_IS_STRING;
957 (void) strlcpy(card.slot_str, label, MAXSTRLEN);
958 }
959 card.freq = freq;
960 card.status[0] = '\0';
961 card.name[0] = '\0';
962 card.model[0] = '\0';
963 card.notes[0] = '\0';
964 if (status != NULL)
965 strlcpy(card.status, status, MAXSTRLEN);
966 if (name != NULL)
967 strlcpy(card.name, name, MAXSTRLEN);
968 if (model != NULL)
969 strlcpy(card.model, model, MAXSTRLEN);
970 if (status != NULL)
971 strlcpy(card.status, status, MAXSTRLEN);
972 if (devfs_path != NULL)
973 strlcpy(card.notes, devfs_path, MAXSTRLEN);
974
975 io_card_list = insert_io_card(io_card_list, &card);
976 }
977
978 static void
append_to_bank_list(bank_list_t * newptr)979 append_to_bank_list(bank_list_t *newptr)
980 {
981 bank_list_t *ptr;
982
983 if (mem_banks == NULL) {
984 mem_banks = newptr;
985 return;
986 }
987 ptr = mem_banks;
988 while (ptr->next != NULL)
989 ptr = ptr->next;
990
991 ptr->next = newptr;
992 }
993
994 static void
free_bank_list(void)995 free_bank_list(void)
996 {
997 bank_list_t *ptr;
998 bank_list_t *tmp;
999
1000 for (ptr = mem_banks; ptr != NULL; ptr = tmp) {
1001 tmp = ptr->next;
1002 free(ptr);
1003 }
1004 mem_banks = NULL;
1005 }
1006
1007
1008 /*
1009 * print label for memory module
1010 */
1011 static int
logprintf_memory_module_label(picl_nodehdl_t moduleh)1012 logprintf_memory_module_label(picl_nodehdl_t moduleh)
1013 {
1014 picl_nodehdl_t fruparenth;
1015 int err;
1016 char *label;
1017
1018 err = picldiag_get_fru_parent(moduleh, &fruparenth);
1019 if (err == PICL_PROPNOTFOUND) {
1020 log_printf("-");
1021 return (PICL_SUCCESS);
1022 } else if (err != PICL_SUCCESS)
1023 return (err);
1024
1025 err = picldiag_get_combined_label(fruparenth, &label, 30);
1026 if (err == PICL_PROPNOTFOUND)
1027 log_printf("-");
1028 else if (err == PICL_SUCCESS) {
1029 log_printf("%-15s", label);
1030 free(label);
1031 } else
1032 return (err);
1033
1034 return (PICL_SUCCESS);
1035 }
1036
1037 /*
1038 * print the bank id and add the bank handle in the bank list
1039 * return the head of the bank list
1040 */
1041 static int
membank_callback(picl_nodehdl_t bankh,void * args)1042 membank_callback(picl_nodehdl_t bankh, void *args)
1043 {
1044 int err;
1045 int64_t id;
1046 uint64_t match;
1047 uint64_t mask;
1048 int i;
1049 bank_list_t *newptr;
1050 seg_info_t *segp = args;
1051
1052 /*
1053 * print the bank id in the segment table contains column
1054 */
1055 id = picldiag_get_uint_propval(bankh, PICL_PROP_ID, &err);
1056 if (segp->bank_count > 0)
1057 log_printf(",");
1058 if (err == PICL_PROPNOTFOUND)
1059 log_printf("-");
1060 else if (err == PICL_SUCCESS)
1061 log_printf("%-lld", id);
1062 else
1063 return (err);
1064 segp->bank_count++;
1065
1066 /*
1067 * Save the bank information for later (print_bank_table)
1068 */
1069 newptr = malloc(sizeof (*newptr));
1070 if (newptr == NULL)
1071 return (PICL_FAILURE);
1072
1073 newptr->nodeh = bankh;
1074 newptr->iway_count = 0;
1075 newptr->next = NULL;
1076 append_to_bank_list(newptr);
1077
1078 /*
1079 * Compute the way numbers for the bank
1080 */
1081 if (no_xfer_size)
1082 return (PICL_WALK_CONTINUE);
1083
1084 match = picldiag_get_uint_propval(bankh, PICL_PROP_ADDRESSMATCH, &err);
1085 if (err == PICL_PROPNOTFOUND)
1086 return (PICL_WALK_CONTINUE);
1087 else if (err != PICL_SUCCESS)
1088 return (err);
1089
1090 mask = picldiag_get_uint_propval(bankh, PICL_PROP_ADDRESSMASK, &err);
1091 if (err == PICL_PROPNOTFOUND)
1092 return (PICL_WALK_CONTINUE);
1093 else if (err != PICL_SUCCESS)
1094 return (err);
1095
1096 i = 0;
1097 while ((i < segp->ifactor) && (newptr->iway_count < MAX_IWAYS)) {
1098 if (((segp->base + i * mem_xfersize) & mask) == match)
1099 newptr->iway[newptr->iway_count++] = i;
1100 ++i;
1101 }
1102 return (PICL_WALK_CONTINUE);
1103 }
1104
1105
1106 /*
1107 * find the memory bank and add the bank handle in the bank list
1108 * return the head of the bank list
1109 */
1110 static int
logprintf_bankinfo(picl_nodehdl_t segh,seg_info_t * segp)1111 logprintf_bankinfo(picl_nodehdl_t segh, seg_info_t *segp)
1112 {
1113 int err;
1114
1115 log_printf(dgettext(TEXT_DOMAIN, "BankIDs "));
1116 /*
1117 * find memory-bank
1118 */
1119 segp->bank_count = 0;
1120 err = picl_walk_tree_by_class(segh, PICL_CLASS_MEMORY_BANK, segp,
1121 membank_callback);
1122 log_printf("\n");
1123 return (err);
1124 }
1125
1126 /*
1127 * print the label of memory module or the memory module bank ids
1128 */
1129 static int
logprintf_seg_contains_col(picl_nodehdl_t nodeh,seg_info_t * segp)1130 logprintf_seg_contains_col(picl_nodehdl_t nodeh, seg_info_t *segp)
1131 {
1132 picl_nodehdl_t moduleh;
1133 int err;
1134
1135 /*
1136 * find memory-module if referenced directly from the memory-segment
1137 * (ie no memory banks)
1138 */
1139 err = picl_get_propval_by_name(nodeh, PICL_REFPROP_MEMORY_MODULE,
1140 &moduleh, sizeof (moduleh));
1141 if ((err != PICL_SUCCESS) && (err != PICL_PROPNOTFOUND))
1142 return (err);
1143 if (err == PICL_SUCCESS) {
1144 err = logprintf_memory_module_label(moduleh);
1145 log_printf("\n");
1146 return (err);
1147 }
1148
1149 /*
1150 * memory-module not referenced directly from the memory segment
1151 * so list memory banks instead
1152 */
1153 err = logprintf_bankinfo(nodeh, segp);
1154 return (err);
1155 }
1156
1157 /*
1158 * find all memory modules under the given memory module group
1159 * and print its label
1160 */
1161 static int
logprintf_memory_module_group_info(picl_nodehdl_t memgrph,uint64_t mcid)1162 logprintf_memory_module_group_info(picl_nodehdl_t memgrph, uint64_t mcid)
1163 {
1164 int err;
1165 int64_t id;
1166 boolean_t got_status;
1167 picl_nodehdl_t moduleh;
1168 char piclclass[PICL_CLASSNAMELEN_MAX];
1169 picl_nodehdl_t fruparenth;
1170 char *status;
1171
1172 id = picldiag_get_uint_propval(memgrph, PICL_PROP_ID, &err);
1173 if (err == PICL_PROPNOTFOUND)
1174 id = -1;
1175 else if (err != PICL_SUCCESS)
1176 return (err);
1177
1178 err = picl_get_propval_by_name(memgrph, PICL_PROP_CHILD, &moduleh,
1179 sizeof (picl_nodehdl_t));
1180
1181 while (err == PICL_SUCCESS) {
1182 /* controller id */
1183 log_printf("%-8lld ", mcid);
1184
1185 /* group id */
1186 if (id == -1) {
1187 log_printf("- ");
1188 } else {
1189 log_printf("%-8lld ", id);
1190 }
1191
1192 err = picl_get_propval_by_name(moduleh, PICL_PROP_CLASSNAME,
1193 piclclass, sizeof (piclclass));
1194 if (err != PICL_SUCCESS)
1195 return (err);
1196
1197 if (strcmp(piclclass, PICL_CLASS_MEMORY_MODULE) == 0) {
1198 err = logprintf_memory_module_label(moduleh);
1199 if (err != PICL_SUCCESS)
1200 return (err);
1201 }
1202
1203 got_status = B_FALSE;
1204 err = picldiag_get_fru_parent(moduleh, &fruparenth);
1205 if (err == PICL_SUCCESS) {
1206 err = picldiag_get_string_propval(fruparenth,
1207 PICL_PROP_OPERATIONAL_STATUS, &status);
1208 if (err == PICL_SUCCESS) {
1209 got_status = B_TRUE;
1210 } else if (err != PICL_PROPNOTFOUND)
1211 return (err);
1212 } else if (err != PICL_PROPNOTFOUND)
1213 return (err);
1214
1215 if (!got_status) {
1216 err = picldiag_get_string_propval(moduleh,
1217 PICL_PROP_STATUS, &status);
1218 if (err == PICL_SUCCESS)
1219 got_status = B_TRUE;
1220 else if (err != PICL_PROPNOTFOUND)
1221 return (err);
1222 }
1223 if (got_status) {
1224 log_printf("%s", status);
1225 free(status);
1226 }
1227 err = picl_get_propval_by_name(moduleh, PICL_PROP_PEER,
1228 &moduleh, sizeof (picl_nodehdl_t));
1229
1230 log_printf("\n");
1231 }
1232 if (err == PICL_PROPNOTFOUND)
1233 return (PICL_SUCCESS);
1234 return (err);
1235 }
1236
1237 /*
1238 * search children to find memory module group under memory-controller
1239 */
1240 static int
find_memory_module_group(picl_nodehdl_t mch,int * print_header)1241 find_memory_module_group(picl_nodehdl_t mch, int *print_header)
1242 {
1243 picl_nodehdl_t memgrph;
1244 uint64_t mcid;
1245 int err;
1246 char piclclass[PICL_CLASSNAMELEN_MAX];
1247
1248 mcid = picldiag_get_uint_propval(mch, OBP_PROP_PORTID, &err);
1249 if (err == PICL_PROPNOTFOUND)
1250 mcid = DEFAULT_PORTID;
1251 else if (err != PICL_SUCCESS)
1252 return (err);
1253
1254 err = picl_get_propval_by_name(mch, PICL_PROP_CHILD,
1255 &memgrph, sizeof (picl_nodehdl_t));
1256 while (err == PICL_SUCCESS) {
1257 err = picl_get_propval_by_name(memgrph,
1258 PICL_PROP_CLASSNAME, piclclass, sizeof (piclclass));
1259 if (err != PICL_SUCCESS)
1260 return (err);
1261
1262 if (strcmp(piclclass, PICL_CLASS_MEMORY_MODULE_GROUP) == 0) {
1263 if (*print_header == 1) {
1264 log_printf(
1265 dgettext(TEXT_DOMAIN,
1266 "\nMemory Module Groups:\n"));
1267 log_printf("--------------------------");
1268 log_printf("------\n");
1269 log_printf(dgettext(TEXT_DOMAIN,
1270 "ControllerID GroupID Labels\n"));
1271 log_printf("--------------------------");
1272 log_printf("------\n");
1273 *print_header = 0;
1274 }
1275 err = logprintf_memory_module_group_info(memgrph, mcid);
1276 if (err != PICL_SUCCESS)
1277 return (err);
1278 }
1279
1280 err = picl_get_propval_by_name(memgrph, PICL_PROP_PEER,
1281 &memgrph, sizeof (picl_nodehdl_t));
1282 }
1283 if (err == PICL_PROPNOTFOUND)
1284 return (PICL_SUCCESS);
1285 return (err);
1286 }
1287
1288 /*
1289 * print memory module group table per memory-controller
1290 */
1291 static int
print_memory_module_group_table(picl_nodehdl_t plafh)1292 print_memory_module_group_table(picl_nodehdl_t plafh)
1293 {
1294 picl_nodehdl_t mch;
1295 int err;
1296 char piclclass[PICL_CLASSNAMELEN_MAX];
1297 int print_header;
1298
1299 print_header = 1;
1300
1301 /*
1302 * find memory-controller
1303 */
1304 err = picl_get_propval_by_name(plafh, PICL_PROP_CHILD, &mch,
1305 sizeof (picl_nodehdl_t));
1306 while (err == PICL_SUCCESS) {
1307 err = picl_get_propval_by_name(mch, PICL_PROP_CLASSNAME,
1308 piclclass, sizeof (piclclass));
1309 if (err != PICL_SUCCESS)
1310 return (err);
1311
1312 if (strcmp(piclclass, PICL_CLASS_MEMORY_CONTROLLER) != 0) {
1313 err = print_memory_module_group_table(mch);
1314 if (err != PICL_SUCCESS)
1315 return (err);
1316 err = picl_get_propval_by_name(mch, PICL_PROP_PEER,
1317 &mch, sizeof (picl_nodehdl_t));
1318 continue;
1319 }
1320
1321 err = find_memory_module_group(mch, &print_header);
1322 if (err != PICL_SUCCESS)
1323 return (err);
1324
1325 err = picl_get_propval_by_name(mch, PICL_PROP_PEER,
1326 &mch, sizeof (picl_nodehdl_t));
1327 }
1328 if (err == PICL_PROPNOTFOUND)
1329 return (PICL_SUCCESS);
1330
1331 return (err);
1332 }
1333
1334 /*
1335 * print bank table
1336 */
1337 static int
print_bank_table(void)1338 print_bank_table(void)
1339 {
1340 bank_list_t *ptr;
1341 picl_nodehdl_t bankh;
1342 picl_nodehdl_t memgrph;
1343 picl_nodehdl_t mch;
1344 int err;
1345 int32_t i;
1346 uint64_t size;
1347 int id;
1348
1349 log_printf(dgettext(TEXT_DOMAIN, "\nBank Table:\n"));
1350 log_printf("---------------------------------------");
1351 log_printf("--------------------\n");
1352 log_printf(dgettext(TEXT_DOMAIN, " Physical Location\n"));
1353 log_printf(dgettext(TEXT_DOMAIN, "ID ControllerID GroupID "));
1354 log_printf(dgettext(TEXT_DOMAIN, "Size Interleave Way\n"));
1355 log_printf("---------------------------------------");
1356 log_printf("--------------------\n");
1357
1358 for (ptr = mem_banks; ptr != NULL; ptr = ptr->next) {
1359 bankh = ptr->nodeh;
1360 id = picldiag_get_uint_propval(bankh, PICL_PROP_ID, &err);
1361 if (err != PICL_SUCCESS)
1362 log_printf("%-8s ", "-");
1363 else
1364 log_printf("%-8d ", id);
1365
1366 /* find memory-module-group */
1367 err = picl_get_propval_by_name(bankh,
1368 PICL_REFPROP_MEMORY_MODULE_GROUP, &memgrph,
1369 sizeof (memgrph));
1370 if (err == PICL_PROPNOTFOUND) {
1371 log_printf("%-8s ", "-");
1372 log_printf("%-8s ", "-");
1373 } else if (err != PICL_SUCCESS)
1374 return (err);
1375 else {
1376 /*
1377 * get controller id
1378 */
1379 err = picl_get_propval_by_name(memgrph,
1380 PICL_PROP_PARENT, &mch, sizeof (picl_nodehdl_t));
1381 if (err != PICL_SUCCESS)
1382 return (err);
1383
1384 id = picldiag_get_uint_propval(mch, OBP_PROP_PORTID,
1385 &err);
1386 if (err == PICL_PROPNOTFOUND)
1387 id = DEFAULT_PORTID; /* use default */
1388 else if (err != PICL_SUCCESS)
1389 return (err);
1390
1391 log_printf("%-8d ", id);
1392
1393 /* get group id */
1394 id = picldiag_get_uint_propval(memgrph, PICL_PROP_ID,
1395 &err);
1396 if (err == PICL_PROPNOTFOUND)
1397 log_printf("- ");
1398 else if (err == PICL_SUCCESS)
1399 log_printf("%-8d ", id);
1400 else
1401 return (err);
1402 }
1403
1404 size = picldiag_get_uint_propval(bankh, PICL_PROP_SIZE, &err);
1405 if (err == PICL_PROPNOTFOUND)
1406 log_printf("- ");
1407 else if (err == PICL_SUCCESS)
1408 logprintf_size(size);
1409 else
1410 return (err);
1411
1412 log_printf(" ");
1413 for (i = 0; i < ptr->iway_count; i++) {
1414 if (i != 0)
1415 log_printf(",");
1416 log_printf("%d", ptr->iway[i]);
1417 }
1418
1419 log_printf("\n");
1420 }
1421 return (PICL_SUCCESS);
1422 }
1423
1424 /*
1425 * callback function to print segment, add the bank in the list and
1426 * return the bank list
1427 */
1428 /* ARGSUSED */
1429 static int
memseg_callback(picl_nodehdl_t segh,void * args)1430 memseg_callback(picl_nodehdl_t segh, void *args)
1431 {
1432 seg_info_t seginfo;
1433 int err;
1434
1435 /* get base address */
1436 seginfo.base = picldiag_get_uint_propval(segh, PICL_PROP_BASEADDRESS,
1437 &err);
1438 if (err == PICL_PROPNOTFOUND) {
1439 log_printf("-\n");
1440 return (PICL_WALK_CONTINUE);
1441 } else if (err == PICL_SUCCESS)
1442 log_printf("0x%-16llx ", seginfo.base);
1443 else
1444 return (err);
1445
1446 /* get size */
1447 seginfo.size = picldiag_get_uint_propval(segh, PICL_PROP_SIZE, &err);
1448 if (err == PICL_PROPNOTFOUND) {
1449 log_printf("-\n");
1450 return (PICL_WALK_CONTINUE);
1451 } else if (err == PICL_SUCCESS)
1452 logprintf_size(seginfo.size);
1453 else
1454 return (err);
1455
1456 /* get interleave factor */
1457 seginfo.ifactor = picldiag_get_uint_propval(segh,
1458 PICL_PROP_INTERLEAVE_FACTOR, &err);
1459
1460 if (err == PICL_PROPNOTFOUND) {
1461 log_printf(" -\n");
1462 return (PICL_WALK_CONTINUE);
1463 } else if (err == PICL_SUCCESS)
1464 log_printf(" %-2d ", seginfo.ifactor);
1465 else
1466 return (err);
1467
1468 seginfo.bank_count = 0;
1469 err = logprintf_seg_contains_col(segh, &seginfo);
1470 if (err != PICL_SUCCESS)
1471 return (err);
1472 return (PICL_WALK_CONTINUE);
1473 }
1474
1475 /*
1476 * search children to find memory-segment and set up the bank list
1477 */
1478 static int
find_segments(picl_nodehdl_t plafh)1479 find_segments(picl_nodehdl_t plafh)
1480 {
1481 int err;
1482
1483 log_printf(dgettext(TEXT_DOMAIN, "Segment Table:\n"));
1484 log_printf("------------------------------");
1485 log_printf("-----------------------------------------\n");
1486 log_printf(dgettext(TEXT_DOMAIN, "Base Address Size "));
1487 log_printf(dgettext(TEXT_DOMAIN, "Interleave Factor Contains\n"));
1488 log_printf("------------------------------");
1489 log_printf("-----------------------------------------\n");
1490
1491 err = picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY_SEGMENT,
1492 NULL, memseg_callback);
1493 return (err);
1494 }
1495
1496 /*
1497 * display memory configuration
1498 */
1499 static int
display_memory_config(picl_nodehdl_t plafh)1500 display_memory_config(picl_nodehdl_t plafh)
1501 {
1502 int err;
1503
1504 logprintf_header(dgettext(TEXT_DOMAIN, "Memory Configuration"),
1505 DEFAULT_LINE_WIDTH);
1506
1507 mem_banks = NULL;
1508 err = find_segments(plafh);
1509
1510 if ((err == PICL_SUCCESS) && (mem_banks != NULL))
1511 print_bank_table();
1512
1513 free_bank_list();
1514
1515 return (print_memory_module_group_table(plafh));
1516 }
1517
1518 /*
1519 * print the hub device
1520 */
1521 static int
logprintf_hub_devices(picl_nodehdl_t hubh)1522 logprintf_hub_devices(picl_nodehdl_t hubh)
1523 {
1524 char *name;
1525 int portnum;
1526 char *labelp;
1527 picl_nodehdl_t parenth;
1528 int err;
1529
1530 err = picldiag_get_string_propval(hubh, PICL_PROP_NAME, &name);
1531 if (err != PICL_SUCCESS)
1532 return (err);
1533 log_printf("%-12.12s ", name);
1534 free(name);
1535
1536 err = picl_get_propval_by_name(hubh, PICL_REFPROP_LOC_PARENT, &parenth,
1537 sizeof (picl_nodehdl_t));
1538
1539 if (err == PICL_SUCCESS) {
1540 /* Read the Label */
1541 err = picldiag_get_label(parenth, &labelp);
1542 if (err == PICL_SUCCESS) {
1543 log_printf("%s\n", labelp);
1544 free(labelp);
1545 return (PICL_SUCCESS);
1546 } else if (err != PICL_PROPNOTFOUND) {
1547 log_printf("\n");
1548 return (err);
1549 }
1550 } else if (err != PICL_PROPNOTFOUND) {
1551 log_printf("\n");
1552 return (err);
1553 }
1554
1555 /* No Label, try the reg */
1556 err = picl_get_propval_by_name(hubh, OBP_PROP_REG, &portnum,
1557 sizeof (portnum));
1558 if (err == PICL_PROPNOTFOUND)
1559 log_printf(" -\n");
1560 else if (err != PICL_SUCCESS) {
1561 log_printf("\n");
1562 return (err);
1563 } else
1564 log_printf("%3d\n", portnum);
1565
1566 return (PICL_SUCCESS);
1567 }
1568
1569 /*
1570 * callback functions to display hub devices
1571 */
1572 /* ARGSUSED */
1573 static int
print_usb_devices(picl_nodehdl_t hubh,void * arg)1574 print_usb_devices(picl_nodehdl_t hubh, void *arg)
1575 {
1576 picl_nodehdl_t chdh;
1577 char *rootname;
1578 int type = *(int *)arg;
1579 int hubnum;
1580 int err;
1581
1582 err = picl_get_propval_by_name(hubh, PICL_PROP_CHILD, &chdh,
1583 sizeof (picl_nodehdl_t));
1584
1585 /* print header */
1586 if (err == PICL_SUCCESS) {
1587 err = picldiag_get_string_propval(hubh, PICL_PROP_NAME,
1588 &rootname);
1589 if (err != PICL_SUCCESS)
1590 return (err);
1591
1592 if (type == USB) {
1593 log_printf("\n===============================");
1594 log_printf(dgettext(TEXT_DOMAIN,
1595 " %s Devices "), rootname);
1596 } else {
1597 /* Get its hub number */
1598 err = picl_get_propval_by_name(hubh,
1599 OBP_PROP_REG, &hubnum, sizeof (hubnum));
1600 if ((err != PICL_SUCCESS) &&
1601 (err != PICL_PROPNOTFOUND)) {
1602 free(rootname);
1603 return (err);
1604 }
1605
1606 log_printf("\n===============================");
1607 if (err == PICL_SUCCESS)
1608 log_printf(dgettext(TEXT_DOMAIN,
1609 " %s#%d Devices "),
1610 rootname, hubnum);
1611 else
1612 log_printf(dgettext(TEXT_DOMAIN,
1613 " %s Devices "), rootname);
1614 }
1615
1616 log_printf("===============================\n\n");
1617 log_printf(dgettext(TEXT_DOMAIN, "Name Port#\n"));
1618 log_printf("------------ -----\n");
1619 free(rootname);
1620
1621 do {
1622 logprintf_hub_devices(chdh);
1623
1624 err = picl_get_propval_by_name(chdh, PICL_PROP_PEER,
1625 &chdh, sizeof (picl_nodehdl_t));
1626 } while (err == PICL_SUCCESS);
1627 }
1628
1629
1630 if (err == PICL_PROPNOTFOUND)
1631 return (PICL_WALK_CONTINUE);
1632 return (err);
1633 }
1634
1635 /*
1636 * callback functions to display usb devices
1637 */
1638 /* ARGSUSED */
1639 static int
usb_callback(picl_nodehdl_t usbh,void * args)1640 usb_callback(picl_nodehdl_t usbh, void *args)
1641 {
1642 int err;
1643 int type;
1644
1645 type = USB;
1646 err = print_usb_devices(usbh, &type);
1647 if (err != PICL_WALK_CONTINUE)
1648 return (err);
1649 type = HUB;
1650 err = picl_walk_tree_by_class(usbh, NULL, &type, print_usb_devices);
1651 if (err == PICL_SUCCESS)
1652 err = PICL_WALK_CONTINUE;
1653 return (err);
1654 }
1655
1656
1657 /*
1658 * find usb devices and print its information
1659 */
1660 static int
display_usb_devices(picl_nodehdl_t plafh)1661 display_usb_devices(picl_nodehdl_t plafh)
1662 {
1663 int err;
1664
1665 /*
1666 * get the usb node
1667 */
1668 err = picl_walk_tree_by_class(plafh, PICL_CLASS_USB, NULL,
1669 usb_callback);
1670 return (err);
1671 }
1672
1673
1674
1675 /*
1676 * If nodeh is the io device, add it into the io list and return
1677 * If it is not an io device and it has the subtree, traverse the subtree
1678 * and add all leaf io devices
1679 */
1680 static int
add_io_leaves(picl_nodehdl_t nodeh,char * parentname,uint32_t board,uint32_t bus_id,uint64_t slot,uint32_t freq,char * model,char * status)1681 add_io_leaves(picl_nodehdl_t nodeh, char *parentname, uint32_t board,
1682 uint32_t bus_id, uint64_t slot, uint32_t freq, char *model, char *status)
1683 {
1684 picl_nodehdl_t childh;
1685 picl_prophdl_t proph;
1686 picl_propinfo_t pinfo;
1687 int err;
1688 char *nameval;
1689 char piclclass[PICL_CLASSNAMELEN_MAX];
1690 char nodename[MAXSTRLEN];
1691 char name[MAXSTRLEN];
1692 char *devfs_path;
1693 char *compatible;
1694 picl_nodehdl_t fruparenth;
1695 char *label;
1696 char binding_name[MAXSTRLEN];
1697
1698 err = picl_get_propinfo_by_name(nodeh, PICL_PROP_NAME, &pinfo,
1699 &proph);
1700 if (err != PICL_SUCCESS)
1701 return (err);
1702
1703 nameval = alloca(pinfo.size);
1704 if (nameval == NULL)
1705 return (PICL_FAILURE);
1706
1707 err = picl_get_propval(proph, nameval, pinfo.size);
1708 if (err != PICL_SUCCESS)
1709 return (err);
1710
1711 (void) strlcpy(nodename, nameval, MAXSTRLEN);
1712
1713 err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
1714 piclclass, sizeof (piclclass));
1715 if (err != PICL_SUCCESS)
1716 return (err);
1717
1718 /* if binding_name is found, name will be <nodename>-<binding_name> */
1719 err = picl_get_propval_by_name(nodeh, PICL_PROP_BINDING_NAME,
1720 binding_name, sizeof (binding_name));
1721 if (err == PICL_PROPNOTFOUND) {
1722 /*
1723 * if compatible prop is found, name will be
1724 * <nodename>-<compatible>
1725 */
1726 err = picldiag_get_first_compatible_value(nodeh, &compatible);
1727 if (err == PICL_SUCCESS) {
1728 strlcat(nodename, "-", MAXSTRLEN);
1729 strlcat(nodename, compatible, MAXSTRLEN);
1730 free(compatible);
1731 } else if (err != PICL_PROPNOTFOUND) {
1732 return (err);
1733 }
1734 } else if (err != PICL_SUCCESS) {
1735 return (err);
1736 } else if (strcmp(nodename, binding_name) != 0) {
1737 if (strcmp(nodename, piclclass) == 0) {
1738 /*
1739 * nodename same as binding name -
1740 * no need to display twice
1741 */
1742 strlcpy(nodename, binding_name, MAXSTRLEN);
1743 } else {
1744 strlcat(nodename, "-", MAXSTRLEN);
1745 strlcat(nodename, binding_name, MAXSTRLEN);
1746 }
1747 }
1748
1749 /*
1750 * If it is an immediate child under pci and not
1751 * a bus node, add it to the io list.
1752 * If it is a child under sub-bus and it is in an io
1753 * device, add it to the io list.
1754 */
1755 if (((parentname == NULL) && (!is_bus(piclclass))) ||
1756 ((parentname != NULL) && (is_io_device(piclclass)))) {
1757 if (parentname == NULL)
1758 (void) snprintf(name, MAXSTRLEN, "%s", nodename);
1759 else
1760 (void) snprintf(name, MAXSTRLEN, "%s/%s", parentname,
1761 nodename);
1762
1763 /*
1764 * append the class if its class is not a generic
1765 * obp-device class
1766 */
1767 if (strcmp(piclclass, PICL_CLASS_OBP_DEVICE))
1768 (void) snprintf(name, MAXSTRLEN, "%s (%s)", name,
1769 piclclass);
1770
1771 err = picldiag_get_fru_parent(nodeh, &fruparenth);
1772 if (err == PICL_PROPNOTFOUND) {
1773 label = NULL;
1774 } else if (err != PICL_SUCCESS) {
1775 return (err);
1776 } else {
1777 err = picldiag_get_combined_label(fruparenth, &label,
1778 15);
1779 if (err == PICL_PROPNOTFOUND)
1780 label = NULL;
1781 else if (err != PICL_SUCCESS)
1782 return (err);
1783 }
1784 /* devfs-path */
1785 err = picldiag_get_string_propval(nodeh, PICL_PROP_DEVFS_PATH,
1786 &devfs_path);
1787 if (err == PICL_PROPNOTFOUND)
1788 devfs_path = NULL;
1789 else if (err != PICL_SUCCESS)
1790 return (err);
1791
1792 add_io_card(board, bus_id, slot, label, freq, name,
1793 model, status, devfs_path);
1794 if (label != NULL)
1795 free(label);
1796 if (devfs_path != NULL)
1797 free(devfs_path);
1798 return (PICL_SUCCESS);
1799 }
1800
1801 /*
1802 * If there is any child, Go through each child.
1803 */
1804
1805 err = picl_get_propval_by_name(nodeh, PICL_PROP_CHILD,
1806 &childh, sizeof (picl_nodehdl_t));
1807
1808 /* there is a child */
1809 while (err == PICL_SUCCESS) {
1810 if (parentname == NULL)
1811 (void) strlcpy(name, nodename, MAXSTRLEN);
1812 else
1813 (void) snprintf(name, MAXSTRLEN, "%s/%s", parentname,
1814 nodename);
1815
1816 err = add_io_leaves(childh, name, board, bus_id, slot, freq,
1817 model, status);
1818 if (err != PICL_SUCCESS)
1819 return (err);
1820 /*
1821 * get next child
1822 */
1823 err = picl_get_propval_by_name(childh, PICL_PROP_PEER,
1824 &childh, sizeof (picl_nodehdl_t));
1825 }
1826
1827 if (err == PICL_PROPNOTFOUND)
1828 return (PICL_SUCCESS);
1829 return (err);
1830 }
1831
1832
1833 /*
1834 * add all io devices under pci in io list
1835 */
1836 /* ARGSUSED */
1837 static int
pci_callback(picl_nodehdl_t pcih,void * args)1838 pci_callback(picl_nodehdl_t pcih, void *args)
1839 {
1840 picl_nodehdl_t nodeh;
1841 int err;
1842 char piclclass[PICL_CLASSNAMELEN_MAX];
1843 uint32_t boardnum;
1844 uint32_t bus_id;
1845 uint32_t slot;
1846 uint32_t freq;
1847 char *model;
1848 char *status;
1849
1850 /* Fill in common infomation */
1851 bus_id = PCI_TYPE;
1852
1853 /*
1854 * Check if it has the freq, if not,
1855 * If not, use its parent's freq
1856 * if its parent's freq is not found, return
1857 */
1858 err = picldiag_get_clock_freq(pcih, &freq);
1859 if (err == PICL_PROPNOTFOUND) {
1860 err = picldiag_get_clock_from_parent(pcih, &freq);
1861 if (err == PICL_PROPNOTFOUND)
1862 return (PICL_WALK_CONTINUE);
1863 else if (err != PICL_SUCCESS)
1864 return (err);
1865 } else if (err != PICL_SUCCESS)
1866 return (err);
1867
1868 /*
1869 * If no board# is found, set boardnum to 0
1870 */
1871 boardnum = picldiag_get_uint_propval(pcih, OBP_PROP_BOARD_NUM, &err);
1872 if (err == PICL_PROPNOTFOUND)
1873 boardnum = DEFAULT_BOARD_NUM;
1874 else if (err != PICL_SUCCESS)
1875 return (err);
1876
1877 /* Walk through the children */
1878
1879 err = picl_get_propval_by_name(pcih, PICL_PROP_CHILD, &nodeh,
1880 sizeof (picl_nodehdl_t));
1881 while (err == PICL_SUCCESS) {
1882 err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
1883 piclclass, sizeof (piclclass));
1884 if (err != PICL_SUCCESS)
1885 return (err);
1886
1887 /*
1888 * Skip PCI bridge and USB devices because they will be
1889 * processed later
1890 */
1891 if ((strcmp(piclclass, PICL_CLASS_PCI) == 0) ||
1892 (strcmp(piclclass, PICL_CLASS_USB) == 0)) {
1893 err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER,
1894 &nodeh, sizeof (picl_nodehdl_t));
1895 continue;
1896 }
1897
1898 /* Get the device id for pci card */
1899 slot = picldiag_get_uint_propval(nodeh,
1900 PICL_PROP_DEVICE_ID, &err);
1901 if (err == PICL_PROPNOTFOUND) {
1902 err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER,
1903 &nodeh, sizeof (picl_nodehdl_t));
1904 continue;
1905 } else if (err != PICL_SUCCESS)
1906 return (err);
1907
1908 /* Get the model of this card */
1909 err = picldiag_get_string_propval(nodeh, OBP_PROP_MODEL,
1910 &model);
1911 if (err == PICL_PROPNOTFOUND)
1912 model = NULL;
1913 else if (err != PICL_SUCCESS)
1914 return (err);
1915
1916 err = picldiag_get_string_propval(nodeh, PICL_PROP_STATUS,
1917 &status);
1918 if (err == PICL_PROPNOTFOUND) {
1919 status = malloc(5);
1920 if (status == NULL)
1921 return (PICL_FAILURE);
1922 strlcpy(status, "okay", 5);
1923 } else if (err != PICL_SUCCESS)
1924 return (err);
1925
1926 err = add_io_leaves(nodeh, NULL, boardnum, bus_id, slot,
1927 freq, model, status);
1928
1929 if (model != NULL)
1930 free(model);
1931
1932 if (status != NULL)
1933 free(status);
1934
1935 if (err != PICL_SUCCESS)
1936 return (err);
1937
1938 err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh,
1939 sizeof (picl_nodehdl_t));
1940
1941 }
1942
1943 if (err == PICL_PROPNOTFOUND)
1944 return (PICL_WALK_CONTINUE);
1945
1946 return (err);
1947 }
1948
1949
1950 /*
1951 * loop through all children and add io devices in io list
1952 */
1953 static int
process_io_leaves(picl_nodehdl_t rooth)1954 process_io_leaves(picl_nodehdl_t rooth)
1955 {
1956 picl_nodehdl_t nodeh;
1957 char classval[PICL_CLASSNAMELEN_MAX];
1958 int err;
1959
1960 err = picl_get_propval_by_name(rooth, PICL_PROP_CHILD, &nodeh,
1961 sizeof (picl_nodehdl_t));
1962 while (err == PICL_SUCCESS) {
1963 err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
1964 classval, sizeof (classval));
1965 if (err != PICL_SUCCESS)
1966 return (err);
1967
1968 if (err != PICL_SUCCESS)
1969 return (err);
1970
1971 err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh,
1972 sizeof (picl_nodehdl_t));
1973 }
1974
1975 if (err == PICL_PROPNOTFOUND)
1976 return (PICL_SUCCESS);
1977
1978 return (err);
1979 }
1980
1981
1982 /*
1983 * find all io devices and add them in the io list
1984 */
1985 static int
gather_io_cards(picl_nodehdl_t plafh)1986 gather_io_cards(picl_nodehdl_t plafh)
1987 {
1988 int err;
1989
1990 /*
1991 * look for io devices under the immediate children of platform
1992 */
1993 err = process_io_leaves(plafh);
1994
1995 if (err != PICL_SUCCESS)
1996 return (err);
1997
1998 if (err != PICL_SUCCESS)
1999 return (err);
2000 err = picl_walk_tree_by_class(plafh, PICL_CLASS_PCI,
2001 PICL_CLASS_PCI, pci_callback);
2002 if (err != PICL_SUCCESS)
2003 return (err);
2004 return (err);
2005 }
2006
2007 static void
picldiag_display_io_cards(struct io_card * list)2008 picldiag_display_io_cards(struct io_card *list)
2009 {
2010 static int banner = 0; /* Have we printed the column headings? */
2011 struct io_card *p;
2012
2013 if (list == NULL)
2014 return;
2015
2016 if (banner == 0) {
2017 log_printf(dgettext(TEXT_DOMAIN,
2018 "Bus Freq Slot + Name +\n"), 0);
2019 log_printf(dgettext(TEXT_DOMAIN, "Type MHz Status "
2020 "Path "
2021 "Model"), 0);
2022 log_printf("\n", 0);
2023 log_printf("---- ---- ---------- "
2024 "---------------------------- "
2025 "--------------------", 0);
2026 log_printf("\n", 0);
2027 banner = 1;
2028 }
2029
2030 for (p = list; p != NULL; p = p -> next) {
2031 log_printf("%-4s ", p->bus_type, 0);
2032 log_printf("%3d ", p->freq, 0);
2033 /*
2034 * We check to see if it's an int or
2035 * a char string to display for slot.
2036 */
2037 if (p->slot == PCI_SLOT_IS_STRING)
2038 log_printf("%10s ", p->slot_str, 0);
2039 else
2040 log_printf("%10d ", p->slot, 0);
2041
2042 log_printf("%-28.28s", p->name, 0);
2043 if (strlen(p->name) > 28)
2044 log_printf("+ ", 0);
2045 else
2046 log_printf(" ", 0);
2047 log_printf("%-19.19s", p->model, 0);
2048 if (strlen(p->model) > 19)
2049 log_printf("+", 0);
2050 log_printf("\n", 0);
2051 log_printf(" %10s ", p->status, 0);
2052 if (strlen(p->notes) > 0)
2053 log_printf("%s", p->notes, 0);
2054 log_printf("\n\n", 0);
2055 }
2056 }
2057
2058 /*
2059 * display all io devices
2060 */
2061 static int
display_io_device_info(picl_nodehdl_t plafh)2062 display_io_device_info(picl_nodehdl_t plafh)
2063 {
2064 int err;
2065
2066 err = gather_io_cards(plafh);
2067 if (err != PICL_SUCCESS)
2068 return (err);
2069
2070 logprintf_header(dgettext(TEXT_DOMAIN, "IO Devices"),
2071 DEFAULT_LINE_WIDTH);
2072
2073 picldiag_display_io_cards(io_card_list);
2074
2075 free_io_cards(io_card_list);
2076
2077 return (PICL_SUCCESS);
2078 }
2079
2080 /*
2081 * print fan device information
2082 */
2083 static int
logprintf_fan_info(picl_nodehdl_t fanh)2084 logprintf_fan_info(picl_nodehdl_t fanh)
2085 {
2086 int err;
2087 char *label;
2088 char *unit;
2089 int64_t speed;
2090 int64_t min_speed;
2091 picl_nodehdl_t fruph;
2092
2093 err = picldiag_get_fru_parent(fanh, &fruph);
2094 if (err != PICL_SUCCESS)
2095 return (err);
2096
2097 err = picldiag_get_combined_label(fruph, &label, 14);
2098 if (err != PICL_SUCCESS)
2099 return (err);
2100
2101 log_printf("%-14s ", label);
2102 free(label);
2103
2104 err = picldiag_get_label(fanh, &label);
2105 if (err == PICL_SUCCESS) {
2106 log_printf("%-14s ", label);
2107 free(label);
2108 } else if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) {
2109 log_printf(" - ");
2110 } else
2111 return (err);
2112
2113 speed = picldiag_get_uint_propval(fanh, PICL_PROP_FAN_SPEED, &err);
2114 if (err == PICL_SUCCESS) {
2115 min_speed = picldiag_get_uint_propval(fanh,
2116 PICL_PROP_LOW_WARNING_THRESHOLD, &err);
2117 if (err != PICL_SUCCESS)
2118 min_speed = 0;
2119 if (speed < min_speed) {
2120 log_printf(dgettext(TEXT_DOMAIN,
2121 "failed (%lld"), speed);
2122 err = picldiag_get_string_propval(fanh,
2123 PICL_PROP_FAN_SPEED_UNIT, &unit);
2124 if (err == PICL_SUCCESS) {
2125 log_printf("%s", unit);
2126 free(unit);
2127 }
2128 log_printf(")");
2129 } else {
2130 log_printf(dgettext(TEXT_DOMAIN, "okay"));
2131 }
2132 } else {
2133 err = picldiag_get_string_propval(fanh,
2134 PICL_PROP_FAN_SPEED_UNIT, &unit);
2135 if (err == PICL_SUCCESS) {
2136 log_printf("%-12s ", unit);
2137 free(unit);
2138 }
2139 }
2140
2141 log_printf("\n");
2142 return (PICL_SUCCESS);
2143 }
2144
2145 static int
fan_callback(picl_nodehdl_t fanh,void * arg)2146 fan_callback(picl_nodehdl_t fanh, void *arg)
2147 {
2148 int *countp = arg;
2149 int err;
2150
2151 if (*countp == 0) {
2152 log_printf(dgettext(TEXT_DOMAIN, "Fan Status:\n"));
2153 log_printf("---------------------------------------\n");
2154 log_printf(dgettext(TEXT_DOMAIN,
2155 "Location Sensor Status \n"));
2156 log_printf("---------------------------------------\n");
2157 }
2158 *countp += 1;
2159 err = logprintf_fan_info(fanh);
2160 if (err == PICL_SUCCESS)
2161 return (PICL_WALK_CONTINUE);
2162 return (err);
2163 }
2164
2165 /*
2166 * callback function search children to find fan device and print its speed
2167 */
2168 static int
display_fan_speed(picl_nodehdl_t plafh)2169 display_fan_speed(picl_nodehdl_t plafh)
2170 {
2171 int err;
2172 int print_header;
2173
2174 print_header = 0;
2175 err = picl_walk_tree_by_class(plafh, PICL_CLASS_FAN,
2176 &print_header, fan_callback);
2177 return (err);
2178 }
2179
2180 /*
2181 * print temperature sensor information
2182 */
2183 static int
logprintf_temp_info(picl_nodehdl_t temph)2184 logprintf_temp_info(picl_nodehdl_t temph)
2185 {
2186 int err;
2187 char *label;
2188 int64_t temperature;
2189 int64_t threshold;
2190 picl_nodehdl_t fruph;
2191 char *status = "unknown";
2192 int got_temp = 0;
2193
2194 err = picldiag_get_fru_parent(temph, &fruph);
2195 if (err != PICL_SUCCESS)
2196 return (err);
2197
2198 err = picldiag_get_combined_label(fruph, &label, 14);
2199 if (err != PICL_SUCCESS)
2200 return (err);
2201
2202 log_printf("%-14s ", label);
2203 free(label);
2204
2205 err = picldiag_get_label(temph, &label);
2206 if (err != PICL_SUCCESS)
2207 return (err);
2208 log_printf("%-14s ", label);
2209 free(label);
2210
2211 temperature = picldiag_get_int_propval(temph, PICL_PROP_TEMPERATURE,
2212 &err);
2213 if (err == PICL_SUCCESS) {
2214 got_temp = 1;
2215 status = "okay";
2216 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2217 return (err);
2218 }
2219
2220 threshold = picldiag_get_int_propval(temph, PICL_PROP_LOW_WARNING,
2221 &err);
2222 if (err == PICL_SUCCESS) {
2223 if (got_temp && temperature < threshold)
2224 status = "warning";
2225 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2226 return (err);
2227 }
2228
2229 threshold = picldiag_get_int_propval(temph, PICL_PROP_LOW_SHUTDOWN,
2230 &err);
2231 if (err == PICL_SUCCESS) {
2232 if (got_temp && temperature < threshold)
2233 status = "failed";
2234 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2235 return (err);
2236 }
2237
2238 threshold = picldiag_get_int_propval(temph, PICL_PROP_HIGH_WARNING,
2239 &err);
2240 if (err == PICL_SUCCESS) {
2241 if (got_temp && temperature > threshold)
2242 status = "warning";
2243 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2244 return (err);
2245 }
2246
2247 threshold = picldiag_get_int_propval(temph, PICL_PROP_HIGH_SHUTDOWN,
2248 &err);
2249 if (err == PICL_SUCCESS) {
2250 if (got_temp && temperature > threshold)
2251 status = "failed";
2252 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2253 return (err);
2254 }
2255
2256 err = picldiag_get_string_propval(temph, PICL_PROP_CONDITION, &status);
2257 if (err == PICL_SUCCESS) {
2258 log_printf("%s", status);
2259 free(status);
2260 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2261 return (err);
2262 } else {
2263 log_printf("%s ", status);
2264 if (strcmp(status, "failed") == 0 ||
2265 strcmp(status, "warning") == 0)
2266 log_printf("(%.2lldC)", temperature);
2267 }
2268
2269 log_printf("\n");
2270 return (PICL_SUCCESS);
2271 }
2272
2273 static int
temp_callback(picl_nodehdl_t temph,void * arg)2274 temp_callback(picl_nodehdl_t temph, void *arg)
2275 {
2276 int err;
2277 int *countp = arg;
2278
2279 if (*countp == 0) {
2280 log_printf("\n");
2281 log_printf("---------------------------------------\n");
2282 log_printf(dgettext(TEXT_DOMAIN, "Temperature sensors:\n"));
2283 log_printf("------------------------------------\n");
2284 log_printf(dgettext(TEXT_DOMAIN,
2285 "Location Sensor Status\n"));
2286 log_printf("------------------------------------\n");
2287 }
2288 *countp += 1;
2289 err = logprintf_temp_info(temph);
2290 if (err == PICL_SUCCESS)
2291 return (PICL_WALK_CONTINUE);
2292 return (err);
2293 }
2294
2295 /*
2296 * callback function search children to find temp sensors and print the temp
2297 */
2298 /* ARGSUSED */
2299 static int
display_temp(picl_nodehdl_t plafh)2300 display_temp(picl_nodehdl_t plafh)
2301 {
2302 int err;
2303 int print_header;
2304
2305 print_header = 0;
2306 err = picl_walk_tree_by_class(plafh, PICL_CLASS_TEMPERATURE_SENSOR,
2307 &print_header, temp_callback);
2308 if (err != PICL_SUCCESS)
2309 return (err);
2310 err = picl_walk_tree_by_class(plafh, PICL_CLASS_TEMPERATURE_INDICATOR,
2311 &print_header, temp_callback);
2312 return (err);
2313 }
2314
2315 /*
2316 * print current sensor information
2317 */
2318 static int
logprintf_current_info(picl_nodehdl_t currenth)2319 logprintf_current_info(picl_nodehdl_t currenth)
2320 {
2321 int err;
2322 char *label;
2323 float current;
2324 float threshold;
2325 picl_nodehdl_t fruph;
2326 char *status = "unknown";
2327 int got_current = 0;
2328
2329 err = picldiag_get_fru_parent(currenth, &fruph);
2330 if (err != PICL_SUCCESS)
2331 return (err);
2332
2333 err = picldiag_get_combined_label(fruph, &label, 10);
2334 if (err != PICL_SUCCESS)
2335 return (err);
2336
2337 log_printf("%-10s ", label);
2338 free(label);
2339
2340 err = picldiag_get_label(currenth, &label);
2341 if (err != PICL_SUCCESS)
2342 return (err);
2343 log_printf("%-10s ", label);
2344 free(label);
2345
2346 current = picldiag_get_float_propval(currenth, PICL_PROP_CURRENT, &err);
2347 if (err == PICL_SUCCESS) {
2348 status = "okay";
2349 got_current = 1;
2350 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2351 return (err);
2352 }
2353
2354 threshold = picldiag_get_float_propval(currenth, PICL_PROP_LOW_WARNING,
2355 &err);
2356 if (err == PICL_SUCCESS) {
2357 if (got_current && current < threshold)
2358 status = "warning";
2359 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2360 return (err);
2361 }
2362
2363 threshold = picldiag_get_float_propval(currenth, PICL_PROP_LOW_SHUTDOWN,
2364 &err);
2365 if (err == PICL_SUCCESS) {
2366 if (got_current && current < threshold)
2367 status = "failed";
2368 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2369 return (err);
2370 }
2371
2372 threshold = picldiag_get_float_propval(currenth, PICL_PROP_HIGH_WARNING,
2373 &err);
2374 if (err == PICL_SUCCESS) {
2375 if (got_current && current > threshold)
2376 status = "warning";
2377 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2378 return (err);
2379 }
2380
2381 threshold = picldiag_get_float_propval(currenth,
2382 PICL_PROP_HIGH_SHUTDOWN, &err);
2383 if (err == PICL_SUCCESS) {
2384 if (got_current && current > threshold)
2385 status = "failed";
2386 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2387 return (err);
2388 }
2389
2390 err = picldiag_get_string_propval(currenth,
2391 PICL_PROP_CONDITION, &status);
2392 if (err == PICL_SUCCESS) {
2393 log_printf(" %s", status);
2394 free(status);
2395 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2396 return (err);
2397 } else {
2398 log_printf("%s ", status);
2399 if (strcmp(status, "failed") == 0 ||
2400 strcmp(status, "warning") == 0)
2401 log_printf("(%.2fA)", current);
2402 }
2403
2404 log_printf("\n");
2405 return (PICL_SUCCESS);
2406 }
2407
2408 static int
current_callback(picl_nodehdl_t currh,void * arg)2409 current_callback(picl_nodehdl_t currh, void *arg)
2410 {
2411 int err;
2412 int *countp = arg;
2413
2414 if (*countp == 0) {
2415 log_printf("------------------------------------\n");
2416 log_printf(dgettext(TEXT_DOMAIN, "Current sensors:\n"));
2417 log_printf("------------------------------\n");
2418 log_printf(dgettext(TEXT_DOMAIN,
2419 "Location Sensor Status\n"));
2420 log_printf("------------------------------\n");
2421 }
2422 *countp += 1;
2423 err = logprintf_current_info(currh);
2424 if (err == PICL_SUCCESS)
2425 return (PICL_WALK_CONTINUE);
2426 return (err);
2427 }
2428
2429 /*
2430 * callback function search children to find curr sensors and print the curr
2431 */
2432 /* ARGSUSED */
2433 static int
display_current(picl_nodehdl_t plafh)2434 display_current(picl_nodehdl_t plafh)
2435 {
2436 int err;
2437 int print_header;
2438
2439 print_header = 0;
2440 err = picl_walk_tree_by_class(plafh, PICL_CLASS_CURRENT_SENSOR,
2441 &print_header, current_callback);
2442 if (err != PICL_SUCCESS)
2443 return (err);
2444 err = picl_walk_tree_by_class(plafh, PICL_CLASS_CURRENT_INDICATOR,
2445 &print_header, current_callback);
2446 return (err);
2447 }
2448
2449 /*
2450 * print voltage sensor information
2451 */
2452 static int
logprintf_voltage_info(picl_nodehdl_t voltageh)2453 logprintf_voltage_info(picl_nodehdl_t voltageh)
2454 {
2455 int err;
2456 char *label;
2457 float voltage;
2458 float threshold;
2459 picl_nodehdl_t fruph;
2460 char *status = "unknown";
2461 int got_voltage = 0;
2462
2463 err = picldiag_get_fru_parent(voltageh, &fruph);
2464 if (err != PICL_SUCCESS)
2465 return (err);
2466
2467 err = picldiag_get_combined_label(fruph, &label, 10);
2468 if (err != PICL_SUCCESS)
2469 return (err);
2470
2471 log_printf("%-10s ", label);
2472 free(label);
2473
2474 err = picldiag_get_label(voltageh, &label);
2475 if (err != PICL_SUCCESS)
2476 return (err);
2477 log_printf("%-12s ", label);
2478 free(label);
2479
2480 voltage = picldiag_get_float_propval(voltageh, PICL_PROP_VOLTAGE, &err);
2481 if (err == PICL_SUCCESS) {
2482 status = "okay";
2483 got_voltage = 1;
2484 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2485 return (err);
2486 }
2487
2488 threshold = picldiag_get_float_propval(voltageh, PICL_PROP_LOW_WARNING,
2489 &err);
2490 if (err == PICL_SUCCESS) {
2491 if (got_voltage && voltage < threshold)
2492 status = "warning";
2493 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2494 return (err);
2495 }
2496
2497 threshold = picldiag_get_float_propval(voltageh, PICL_PROP_LOW_SHUTDOWN,
2498 &err);
2499 if (err == PICL_SUCCESS) {
2500 if (got_voltage && voltage < threshold)
2501 status = "failed";
2502 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2503 return (err);
2504 }
2505
2506 threshold = picldiag_get_float_propval(voltageh, PICL_PROP_HIGH_WARNING,
2507 &err);
2508 if (err == PICL_SUCCESS) {
2509 if (got_voltage && voltage > threshold)
2510 status = "warning";
2511 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2512 return (err);
2513 }
2514
2515 threshold = picldiag_get_float_propval(voltageh,
2516 PICL_PROP_HIGH_SHUTDOWN, &err);
2517 if (err == PICL_SUCCESS) {
2518 if (got_voltage && voltage > threshold)
2519 status = "failed";
2520 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2521 return (err);
2522 }
2523
2524 err = picldiag_get_string_propval(voltageh,
2525 PICL_PROP_CONDITION, &status);
2526 if (err == PICL_SUCCESS) {
2527 log_printf("%s", status);
2528 free(status);
2529 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2530 return (err);
2531 } else {
2532 log_printf("%s ", status);
2533 if (strcmp(status, "warning") == 0 ||
2534 strcmp(status, "failed") == 0)
2535 log_printf("(%.2fV)", voltage);
2536 }
2537
2538 log_printf("\n");
2539 return (PICL_SUCCESS);
2540 }
2541
2542 static int
voltage_callback(picl_nodehdl_t voltageh,void * arg)2543 voltage_callback(picl_nodehdl_t voltageh, void *arg)
2544 {
2545 int *countp = arg;
2546 int err;
2547
2548 if (*countp == 0) {
2549 log_printf("--------------------------------\n");
2550 log_printf(dgettext(TEXT_DOMAIN, "Voltage sensors:\n"));
2551 log_printf("-------------------------------\n");
2552 log_printf(dgettext(TEXT_DOMAIN,
2553 "Location Sensor Status\n"));
2554 log_printf("-------------------------------\n");
2555 }
2556 *countp += 1;
2557 err = logprintf_voltage_info(voltageh);
2558 if (err == PICL_SUCCESS)
2559 return (PICL_WALK_CONTINUE);
2560 return (err);
2561 }
2562
2563 /*
2564 * callback function search children to find voltage sensors and print voltage
2565 */
2566 /* ARGSUSED */
2567 static int
display_voltage(picl_nodehdl_t plafh)2568 display_voltage(picl_nodehdl_t plafh)
2569 {
2570 int err;
2571 int print_header;
2572
2573 print_header = 0;
2574 err = picl_walk_tree_by_class(plafh, PICL_CLASS_VOLTAGE_SENSOR,
2575 &print_header, voltage_callback);
2576 if (err != PICL_SUCCESS)
2577 return (err);
2578 err = picl_walk_tree_by_class(plafh, PICL_CLASS_VOLTAGE_INDICATOR,
2579 &print_header, voltage_callback);
2580 return (err);
2581 }
2582
2583 /*
2584 * print led device information
2585 */
2586 static int
logprintf_led_info(picl_nodehdl_t ledh)2587 logprintf_led_info(picl_nodehdl_t ledh)
2588 {
2589 int err;
2590 char *label;
2591 char *state;
2592 char *color;
2593 picl_nodehdl_t fruph;
2594
2595 err = picldiag_get_fru_parent(ledh, &fruph);
2596 if (err != PICL_SUCCESS)
2597 return (err);
2598
2599 err = picldiag_get_combined_label(fruph, &label, 10);
2600 if (err != PICL_SUCCESS) {
2601 log_printf(" - ", label);
2602 } else {
2603 log_printf("%-10s ", label);
2604 free(label);
2605 }
2606
2607 err = picldiag_get_label(ledh, &label);
2608 if (err != PICL_SUCCESS)
2609 return (err);
2610 log_printf("%-20s ", label);
2611 free(label);
2612
2613 err = picldiag_get_string_propval(ledh, PICL_PROP_STATE, &state);
2614 if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) {
2615 log_printf(" - ");
2616 } else if (err != PICL_SUCCESS) {
2617 return (err);
2618 } else {
2619 log_printf("%-10s ", state);
2620 free(state);
2621 }
2622
2623 err = picldiag_get_string_propval(ledh, PICL_PROP_COLOR, &color);
2624 if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) {
2625 log_printf("\n");
2626 } else if (err != PICL_SUCCESS) {
2627 return (err);
2628 } else {
2629 log_printf("%-16s\n", color);
2630 free(color);
2631 }
2632
2633 return (PICL_SUCCESS);
2634 }
2635
2636 static int
led_callback(picl_nodehdl_t ledh,void * arg)2637 led_callback(picl_nodehdl_t ledh, void *arg)
2638 {
2639 int *countp = arg;
2640 int err;
2641
2642 if (*countp == 0) {
2643
2644 log_printf("--------------------------------------"
2645 "------------\n");
2646 log_printf(dgettext(TEXT_DOMAIN, "Led State:\n"));
2647 log_printf("--------------------------------------"
2648 "------------\n");
2649 log_printf(dgettext(TEXT_DOMAIN,
2650 "Location Led State"
2651 " Color\n"));
2652 log_printf("--------------------------------------"
2653 "------------\n");
2654 }
2655 *countp += 1;
2656 err = logprintf_led_info(ledh);
2657 if (err == PICL_SUCCESS)
2658 return (PICL_WALK_CONTINUE);
2659 return (err);
2660 }
2661
2662 /*
2663 * callback function search children to find led devices and print status
2664 */
2665 /* ARGSUSED */
2666 static int
display_led_status(picl_nodehdl_t plafh)2667 display_led_status(picl_nodehdl_t plafh)
2668 {
2669 int print_header;
2670
2671 print_header = 0;
2672 picl_walk_tree_by_class(plafh, PICL_CLASS_LED,
2673 &print_header, led_callback);
2674 return (PICL_SUCCESS);
2675 }
2676
2677 /*
2678 * print keyswitch device information
2679 */
2680 static int
logprintf_keyswitch_info(picl_nodehdl_t keyswitchh,picl_nodehdl_t fruph)2681 logprintf_keyswitch_info(picl_nodehdl_t keyswitchh, picl_nodehdl_t fruph)
2682 {
2683 int err;
2684 char *label;
2685 char *state;
2686
2687 err = picldiag_get_combined_label(fruph, &label, 10);
2688 if (err != PICL_SUCCESS) {
2689 log_printf("%-14s", " -");
2690 } else {
2691 log_printf("%-14s ", label);
2692 free(label);
2693 }
2694
2695 err = picldiag_get_label(keyswitchh, &label);
2696 if (err != PICL_SUCCESS)
2697 return (err);
2698 log_printf("%-11s ", label);
2699 free(label);
2700
2701 err = picldiag_get_string_propval(keyswitchh, PICL_PROP_STATE, &state);
2702 if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE) {
2703 log_printf(" -\n");
2704 } else if (err != PICL_SUCCESS) {
2705 return (err);
2706 } else {
2707 log_printf("%s\n", state);
2708 free(state);
2709 }
2710
2711 return (PICL_SUCCESS);
2712 }
2713
2714 static int
keyswitch_callback(picl_nodehdl_t keyswitchh,void * arg)2715 keyswitch_callback(picl_nodehdl_t keyswitchh, void *arg)
2716 {
2717 int *countp = arg;
2718 int err;
2719 picl_nodehdl_t fruph;
2720
2721 /*
2722 * Tamale simulates a key-switch on ENxS. So the presence of a
2723 * node of class keyswitch is not sufficient. If it has a fru parent
2724 * or location parent, then believe it.
2725 */
2726 err = picl_get_propval_by_name(keyswitchh, PICL_REFPROP_FRU_PARENT,
2727 &fruph, sizeof (fruph));
2728 if (err == PICL_PROPNOTFOUND) {
2729 err = picl_get_propval_by_name(keyswitchh,
2730 PICL_REFPROP_LOC_PARENT, &fruph, sizeof (fruph));
2731 }
2732 if (err == PICL_PROPNOTFOUND || err == PICL_PROPVALUNAVAILABLE)
2733 return (PICL_WALK_CONTINUE);
2734 if (err != PICL_SUCCESS)
2735 return (err);
2736
2737 if (*countp == 0) {
2738 log_printf("-----------------------------------------\n");
2739 log_printf(dgettext(TEXT_DOMAIN, "Keyswitch:\n"));
2740 log_printf("-----------------------------------------\n");
2741 log_printf(dgettext(TEXT_DOMAIN,
2742 "Location Keyswitch State\n"));
2743 log_printf("-----------------------------------------\n");
2744 }
2745 *countp += 1;
2746 err = logprintf_keyswitch_info(keyswitchh, fruph);
2747 if (err == PICL_SUCCESS)
2748 return (PICL_WALK_CONTINUE);
2749 return (err);
2750 }
2751
2752 /*
2753 * search children to find keyswitch device(s) and print status
2754 */
2755 /* ARGSUSED */
2756 static int
display_keyswitch(picl_nodehdl_t plafh)2757 display_keyswitch(picl_nodehdl_t plafh)
2758 {
2759 int print_header = 0;
2760
2761 picl_walk_tree_by_class(plafh, PICL_CLASS_KEYSWITCH,
2762 &print_header, keyswitch_callback);
2763 return (PICL_SUCCESS);
2764 }
2765
2766 /*
2767 * display environment status
2768 */
2769 static int
display_envctrl_status(picl_nodehdl_t plafh)2770 display_envctrl_status(picl_nodehdl_t plafh)
2771 {
2772 logprintf_header(dgettext(TEXT_DOMAIN, "Environmental Status"),
2773 DEFAULT_LINE_WIDTH);
2774
2775 display_fan_speed(plafh);
2776 display_temp(plafh);
2777 display_current(plafh);
2778 display_voltage(plafh);
2779 display_keyswitch(plafh);
2780 display_led_status(plafh);
2781
2782 return (PICL_SUCCESS);
2783 }
2784
2785 /*
2786 * print fru operational status
2787 */
2788 static int
logprintf_fru_oper_status(picl_nodehdl_t fruh,int * countp)2789 logprintf_fru_oper_status(picl_nodehdl_t fruh, int *countp)
2790 {
2791 int err;
2792 char *label;
2793 char *status;
2794
2795 err = picldiag_get_combined_label(fruh, &label, 15);
2796 if (err != PICL_SUCCESS)
2797 return (PICL_WALK_CONTINUE);
2798
2799 err = picldiag_get_string_propval(fruh,
2800 PICL_PROP_OPERATIONAL_STATUS, &status);
2801 if (err == PICL_SUCCESS) {
2802 if (*countp == 0) {
2803 logprintf_header(dgettext(TEXT_DOMAIN,
2804 "FRU Operational Status"),
2805 DEFAULT_LINE_WIDTH);
2806 log_printf("-------------------------\n");
2807 log_printf(dgettext(TEXT_DOMAIN,
2808 "Fru Operational Status:\n"));
2809 log_printf("-------------------------\n");
2810 log_printf(dgettext(TEXT_DOMAIN,
2811 "Location Status \n"));
2812 log_printf("-------------------------\n");
2813 }
2814 *countp += 1;
2815 log_printf("%-15s ", label);
2816 free(label);
2817 log_printf("%s\n", status);
2818 free(status);
2819 } else if (err != PICL_PROPNOTFOUND && err != PICL_PROPVALUNAVAILABLE) {
2820 free(label);
2821 return (err);
2822 } else {
2823 free(label);
2824 }
2825 return (PICL_WALK_CONTINUE);
2826 }
2827
2828 static int
fru_oper_status_callback(picl_nodehdl_t fruh,void * arg)2829 fru_oper_status_callback(picl_nodehdl_t fruh, void *arg)
2830 {
2831 int err;
2832
2833 err = logprintf_fru_oper_status(fruh, (int *)arg);
2834 return (err);
2835 }
2836
2837 /*
2838 * display fru operational status
2839 */
2840 static int
display_fru_oper_status(picl_nodehdl_t frutreeh)2841 display_fru_oper_status(picl_nodehdl_t frutreeh)
2842 {
2843 int print_header;
2844
2845 print_header = 0;
2846 picl_walk_tree_by_class(frutreeh, PICL_CLASS_FRU,
2847 &print_header, fru_oper_status_callback);
2848 return (PICL_SUCCESS);
2849 }
2850
2851 /*
2852 * check if the node having the version prop
2853 * If yes, print its nodename and version
2854 */
2855 /* ARGSUSED */
2856 static int
asicrev_callback(picl_nodehdl_t nodeh,void * arg)2857 asicrev_callback(picl_nodehdl_t nodeh, void *arg)
2858 {
2859 uint32_t version;
2860 char *name;
2861 char *model;
2862 char *status;
2863 int err;
2864
2865 version = picldiag_get_uint_propval(nodeh, OBP_PROP_VERSION_NUM,
2866 &err);
2867 if (err == PICL_PROPNOTFOUND)
2868 return (PICL_WALK_CONTINUE);
2869 else if (err != PICL_SUCCESS)
2870 return (err);
2871
2872 /* devfs-path */
2873 err = picldiag_get_string_propval(nodeh, PICL_PROP_DEVFS_PATH, &name);
2874 if (err == PICL_PROPNOTFOUND)
2875 name = NULL;
2876 else if (err != PICL_SUCCESS)
2877 return (err);
2878
2879 /* model */
2880 err = picldiag_get_string_propval(nodeh, PICL_PROP_BINDING_NAME,
2881 &model);
2882 if (err == PICL_PROPNOTFOUND)
2883 model = NULL;
2884 else if (err != PICL_SUCCESS)
2885 return (err);
2886
2887 /* status */
2888 err = picldiag_get_string_propval(nodeh, PICL_PROP_STATUS, &status);
2889 if (err == PICL_PROPNOTFOUND)
2890 status = NULL;
2891 else if (err != PICL_SUCCESS)
2892 return (err);
2893
2894 /*
2895 * Display the data
2896 */
2897
2898 /* name */
2899 if (name != NULL) {
2900 log_printf("%-22s ", name);
2901 free(name);
2902 } else
2903 log_printf("%-22s ", "unknown");
2904 /* model */
2905 if (model != NULL) {
2906 log_printf("%-15s ", model);
2907 free(model);
2908 } else
2909 log_printf("%-15s ", "unknown");
2910 /* status */
2911 if (status == NULL)
2912 log_printf("%-15s ", "okay");
2913 else {
2914 log_printf("%-15s ", status);
2915 free(status);
2916 }
2917 /* revision */
2918 log_printf(" %-4d\n", version);
2919
2920 return (PICL_WALK_CONTINUE);
2921 }
2922
2923 /*
2924 * traverse the tree to display asic revision id for ebus
2925 */
2926 /* ARGSUSED */
2927 static int
ebus_callback(picl_nodehdl_t ebush,void * arg)2928 ebus_callback(picl_nodehdl_t ebush, void *arg)
2929 {
2930 uint32_t id;
2931 char *name;
2932 int err;
2933 char *model;
2934 char *status;
2935
2936 id = picldiag_get_uint_propval(ebush, OBP_PROP_REVISION_ID, &err);
2937 if (err == PICL_PROPNOTFOUND)
2938 return (PICL_WALK_CONTINUE);
2939 else if (err != PICL_SUCCESS)
2940 return (err);
2941
2942 /* devfs-path */
2943 err = picldiag_get_string_propval(ebush, PICL_PROP_DEVFS_PATH, &name);
2944 if (err == PICL_PROPNOTFOUND)
2945 name = NULL;
2946 else if (err != PICL_SUCCESS)
2947 return (err);
2948
2949 /* model */
2950 err = picldiag_get_string_propval(ebush, PICL_PROP_BINDING_NAME,
2951 &model);
2952 if (err == PICL_PROPNOTFOUND)
2953 model = NULL;
2954 else if (err != PICL_SUCCESS)
2955 return (err);
2956
2957 /* status */
2958 err = picldiag_get_string_propval(ebush, PICL_PROP_STATUS, &status);
2959 if (err == PICL_PROPNOTFOUND)
2960 status = NULL;
2961 else if (err != PICL_SUCCESS)
2962 return (err);
2963
2964 /*
2965 * Display the data
2966 */
2967
2968 /* name */
2969 if (name != NULL) {
2970 log_printf("%-22s ", name);
2971 free(name);
2972 } else
2973 log_printf("%-22s ", "unknown");
2974 /* model */
2975 if (model != NULL) {
2976 log_printf("%-15s ", model);
2977 free(model);
2978 } else
2979 log_printf("%-15s ", "unknown");
2980 /* status */
2981 if (status == NULL)
2982 log_printf("%-15s ", "okay");
2983 else {
2984 log_printf("%-15s ", status);
2985 free(status);
2986 }
2987 /* revision */
2988 log_printf(" %-4d\n", id);
2989
2990 return (PICL_WALK_CONTINUE);
2991 }
2992
2993 /*
2994 * display asic revision id
2995 */
2996 static int
display_hw_revisions(picl_nodehdl_t plafh)2997 display_hw_revisions(picl_nodehdl_t plafh)
2998 {
2999 int err;
3000
3001 /* Print the header */
3002 logprintf_header(dgettext(TEXT_DOMAIN, "HW Revisions"),
3003 DEFAULT_LINE_WIDTH);
3004
3005 log_printf(dgettext(TEXT_DOMAIN, "ASIC Revisions:\n"));
3006 log_printf("-----------------------------");
3007 log_printf("--------------------------------------\n");
3008 log_printf(dgettext(TEXT_DOMAIN, "Path Device"));
3009 log_printf(dgettext(TEXT_DOMAIN,
3010 " Status Revision\n"));
3011 log_printf("-----------------------------");
3012 log_printf("--------------------------------------\n");
3013
3014 err = picl_walk_tree_by_class(plafh, NULL, NULL, asicrev_callback);
3015 if (err != PICL_SUCCESS)
3016 return (err);
3017
3018 err = picl_walk_tree_by_class(plafh, PICL_CLASS_EBUS,
3019 NULL, ebus_callback);
3020 if (err != PICL_SUCCESS)
3021 return (err);
3022
3023 log_printf("\n");
3024
3025 return (err);
3026 }
3027
3028 /*
3029 * find the options node and its powerfail_time prop
3030 * If found, display the list of latest powerfail.
3031 */
3032 /* ARGSUSED */
3033 static int
options_callback(picl_nodehdl_t nodeh,void * arg)3034 options_callback(picl_nodehdl_t nodeh, void *arg)
3035 {
3036 time_t value;
3037 char *failtime;
3038 int err;
3039
3040 err = picldiag_get_string_propval(nodeh, PROP_POWERFAIL_TIME,
3041 &failtime);
3042 if (err == PICL_PROPNOTFOUND)
3043 return (PICL_WALK_TERMINATE);
3044 else if (err != PICL_SUCCESS)
3045 return (err);
3046
3047 value = (time_t)atoi(failtime);
3048 free(failtime);
3049 if (value == 0)
3050 return (PICL_WALK_TERMINATE);
3051
3052 log_printf(dgettext(TEXT_DOMAIN, "Most recent AC Power Failure:\n"));
3053 log_printf("=============================\n");
3054 log_printf("%s", ctime(&value));
3055 log_printf("\n");
3056 return (PICL_WALK_TERMINATE);
3057 }
3058
3059 /*
3060 * display the OBP and POST prom revisions
3061 */
3062 /* ARGSUSED */
3063 static int
flashprom_callback(picl_nodehdl_t flashpromh,void * arg)3064 flashprom_callback(picl_nodehdl_t flashpromh, void *arg)
3065 {
3066 picl_prophdl_t proph;
3067 picl_prophdl_t tblh;
3068 picl_prophdl_t rowproph;
3069 picl_propinfo_t pinfo;
3070 char *prom_version = NULL;
3071 char *obp_version = NULL;
3072 int err;
3073
3074 err = picl_get_propinfo_by_name(flashpromh, OBP_PROP_VERSION,
3075 &pinfo, &proph);
3076 if (err == PICL_PROPNOTFOUND)
3077 return (PICL_WALK_TERMINATE);
3078 else if (err != PICL_SUCCESS)
3079 return (err);
3080
3081 log_printf(dgettext(TEXT_DOMAIN, "System PROM revisions:\n"));
3082 log_printf("----------------------\n");
3083
3084 /*
3085 * If it's a table prop, the first element is OBP revision
3086 * The second one is POST revision.
3087 * If it's a charstring prop, the value will be only OBP revision
3088 */
3089 if (pinfo.type == PICL_PTYPE_CHARSTRING) {
3090 prom_version = alloca(pinfo.size);
3091 if (prom_version == NULL)
3092 return (PICL_FAILURE);
3093 err = picl_get_propval(proph, prom_version, pinfo.size);
3094 if (err != PICL_SUCCESS)
3095 return (err);
3096 log_printf("%s\n", prom_version);
3097 }
3098
3099 if (pinfo.type != PICL_PTYPE_TABLE) /* not supported type */
3100 return (PICL_WALK_TERMINATE);
3101
3102 err = picl_get_propval(proph, &tblh, pinfo.size);
3103 if (err != PICL_SUCCESS)
3104 return (err);
3105
3106 err = picl_get_next_by_row(tblh, &rowproph);
3107 if (err == PICL_SUCCESS) {
3108 /* get first row */
3109 err = picl_get_propinfo(rowproph, &pinfo);
3110 if (err != PICL_SUCCESS)
3111 return (err);
3112
3113 prom_version = alloca(pinfo.size);
3114 if (prom_version == NULL)
3115 return (PICL_FAILURE);
3116
3117 err = picl_get_propval(rowproph, prom_version, pinfo.size);
3118 if (err != PICL_SUCCESS)
3119 return (err);
3120 log_printf("%s\n", prom_version);
3121
3122 /* get second row */
3123 err = picl_get_next_by_col(rowproph, &rowproph);
3124 if (err == PICL_SUCCESS) {
3125 err = picl_get_propinfo(rowproph, &pinfo);
3126 if (err != PICL_SUCCESS)
3127 return (err);
3128
3129 obp_version = alloca(pinfo.size);
3130 if (obp_version == NULL)
3131 return (PICL_FAILURE);
3132 err = picl_get_propval(rowproph, obp_version,
3133 pinfo.size);
3134 if (err != PICL_SUCCESS)
3135 return (err);
3136 log_printf("%s\n", obp_version);
3137 }
3138 }
3139
3140 return (PICL_WALK_TERMINATE);
3141 }
3142
3143 static int
display_system_info(int serrlog,int log_flag,picl_nodehdl_t rooth)3144 display_system_info(int serrlog, int log_flag, picl_nodehdl_t rooth)
3145 {
3146 int err;
3147 picl_nodehdl_t plafh;
3148 picl_nodehdl_t frutreeh;
3149
3150 err = picldiag_get_node_by_name(rooth, PICL_NODE_PLATFORM, &plafh);
3151 if (err != PICL_SUCCESS)
3152 return (err);
3153
3154 if (!log_flag) {
3155 err = display_platform_banner(plafh);
3156 if (err != PICL_SUCCESS)
3157 return (err);
3158
3159 err = display_system_clock(plafh);
3160 if (err != PICL_SUCCESS)
3161 return (err);
3162
3163 err = picl_walk_tree_by_class(plafh, PICL_CLASS_MEMORY,
3164 PICL_CLASS_MEMORY, memory_callback);
3165 if (err != PICL_SUCCESS)
3166 return (err);
3167
3168 err = display_cpu_info(plafh);
3169 if (err != PICL_SUCCESS)
3170 return (err);
3171
3172 err = display_io_device_info(plafh);
3173 if (err != PICL_SUCCESS)
3174 return (err);
3175
3176 err = display_memory_config(plafh);
3177 if (err != PICL_SUCCESS)
3178 return (err);
3179
3180 err = display_usb_devices(plafh);
3181 if (err != PICL_SUCCESS)
3182 return (err);
3183 }
3184
3185 if (serrlog) {
3186 err = picl_walk_tree_by_class(rooth, PICL_CLASS_OPTIONS,
3187 NULL, options_callback);
3188 if (err != PICL_SUCCESS)
3189 return (err);
3190
3191 err = picldiag_get_node_by_name(rooth, PICL_NODE_FRUTREE,
3192 &frutreeh);
3193
3194 /* return ok if no frutree in picl on schumacher */
3195 if (err != PICL_SUCCESS)
3196 return (PICL_SUCCESS);
3197
3198 err = display_fru_oper_status(frutreeh);
3199 if (err != PICL_SUCCESS)
3200 return (err);
3201
3202 err = display_hw_revisions(plafh);
3203 if (err != PICL_SUCCESS)
3204 return (err);
3205
3206 err = picl_walk_tree_by_class(plafh, PICL_CLASS_FLASHPROM,
3207 NULL, flashprom_callback);
3208 if (err != PICL_SUCCESS)
3209 return (err);
3210 }
3211
3212 return (PICL_SUCCESS);
3213 }
3214
3215 /* ARGSUSED */
3216 int
do_prominfo(int serrlog,char * pgname,int log_flag,int prt_flag)3217 do_prominfo(int serrlog, char *pgname, int log_flag, int prt_flag)
3218 {
3219 int err;
3220 char *errstr;
3221 int done;
3222 picl_nodehdl_t rooth;
3223
3224 err = picl_initialize();
3225 if (err != PICL_SUCCESS) {
3226 fprintf(stderr, EM_INIT_FAIL, picl_strerror(err));
3227 exit(1);
3228 }
3229
3230 do {
3231 done = 1;
3232 err = picl_get_root(&rooth);
3233 if (err != PICL_SUCCESS) {
3234 fprintf(stderr, EM_GET_ROOT_FAIL, picl_strerror(err));
3235 exit(1);
3236 }
3237
3238 err = display_system_info(serrlog, log_flag, rooth);
3239
3240 if ((err == PICL_STALEHANDLE) || (err == PICL_INVALIDHANDLE))
3241 done = 0;
3242 } while (!done);
3243
3244 if (err != PICL_SUCCESS) {
3245 errstr = picl_strerror(err);
3246 fprintf(stderr, EM_PRTDIAG_FAIL);
3247 fprintf(stderr, "%s\n", errstr? errstr : " ");
3248 }
3249
3250 (void) picl_shutdown();
3251
3252 return (0);
3253 }
3254