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) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25
26 /*
27 * This program prints the diagnostics of Sanibel system. It
28 * also prints other miscellaneous information about watchdog, temperature
29 * of CPU sensor, firmware versions of SMC and, micro controller role
30 * etc. The basic sources of output is PICL, and SMC.
31 */
32
33 /* includes */
34
35 #include <stdio.h>
36 #include <strings.h>
37 #include <ctype.h>
38 #include <string.h>
39 #include <time.h>
40 #include <dirent.h>
41 #include <sys/param.h>
42 #include <picl.h>
43 #include <libintl.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <sys/systeminfo.h>
47 #include <sys/openpromio.h>
48 #include <fcntl.h>
49 #include <smc_if.h>
50 #include <stropts.h>
51 #include <alloca.h>
52 #include <errno.h>
53 #include <poll.h>
54 #include <stdlib.h>
55 #include <unistd.h>
56 #include <kstat.h>
57 #include <sys/utsname.h>
58 #include <stddef.h>
59 #include <pdevinfo.h>
60 #include <display_sun4u.h>
61 #include <libprtdiag.h>
62 #include <smclib.h>
63 #include <smc_commands.h>
64 #include <picldefs.h>
65
66 /* #defines for the PICL library API usage and local static variables */
67 #define PD_CPCI_SLOT_TYPE "cpci"
68 #define PD_PCI_SLOT_TYPE "pci"
69 #define PD_PRESENT 1
70 #define PD_BLANK " "
71 #define PD_ENABLED 1
72 #define PD_DISABLED 0
73 #define SNOWBIRD "SUNW,Netra-CP2300"
74 #define CHASSIS_NODE_NAME "chassis"
75
76 /* #defines for the SMC and IPMI commands */
77 #define POLL_TIMEOUT 10000
78 #define DEFAULT_SEQN 0xff
79
80 /* SMC driver */
81 #define PD_SMC_DRV_PATH "/dev/ctsmc"
82
83 /* Constants */
84 #define OBP_PROP_BANNER_NAME "banner-name"
85 #define OBP_PROP_CLOCK_FREQ "clock-frequency"
86
87
88
89 /* #defines for local usage */
90 #define PD_SUCCESS 0
91 #define PD_FAILURE 1
92 #define PD_INTERNAL_FAILURE 2
93 #define PD_ERROR -1
94
95 /* static global variables */
96 static int pd_print_option;
97 static uint8_t pd_smc_glbl_enabl_rsp[2];
98 static boolean_t pd_hdr_prt = B_TRUE;
99 static int pd_smc_fd = 0;
100
101
102 /* function declarations used in this program */
103 static uint32_t pd_check_for_snowbird();
104 static uint32_t pd_prt_snowbird_diag();
105 static uint32_t pd_check_cpu_health();
106 static uint32_t pd_check_tty_debug_mode();
107 static uint32_t pd_query_SMC_firmware_version();
108 static uint32_t pd_check_slots();
109 int32_t pd_prt_slot_info(picl_nodehdl_t, void *);
110 int do_prominfo(int syserrlog, char *pname, int log_flag, int prt_flag);
111 static uint32_t pd_query_watchdog_state();
112 int pd_check_wd_state(picl_nodehdl_t, void *);
113 static uint32_t pd_print_fruinfo_hdr();
114 static uint32_t pd_print_device_info(int);
115 static uint32_t pd_get_role_information();
116 static uint32_t pd_get_message_flags();
117 static uint32_t pd_get_reset_mode();
118 static uint32_t pd_get_sensor_reading();
119 static uint32_t pd_get_sensor_threshold();
120 static uint32_t pd_prt_cpci_condition(picl_nodehdl_t nodeh);
121 static uint32_t pd_check_location_parent(picl_nodehdl_t nodeh);
122 static uint64_t
123 picldiag_get_uint_propval(picl_nodehdl_t modh, char *prop_name, int *ret);
124 static int picldiag_get_clock_freq(picl_nodehdl_t modh, uint32_t *freq);
125 static int display_system_clock(picl_nodehdl_t plafh);
126
127 /*
128 * return the value of the uint prop
129 */
130 static uint64_t
picldiag_get_uint_propval(picl_nodehdl_t modh,char * prop_name,int * ret)131 picldiag_get_uint_propval(picl_nodehdl_t modh, char *prop_name, int *ret)
132 {
133 int err;
134 picl_prophdl_t proph;
135 picl_propinfo_t pinfo;
136 uint8_t uint8v;
137 uint16_t uint16v;
138 uint32_t uint32v;
139 uint64_t uint64v;
140
141 err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
142 if (err != PICL_SUCCESS) {
143 *ret = err;
144 return (0);
145 }
146
147 /*
148 * If it is not an int or uint prop, return failure
149 */
150 if ((pinfo.type != PICL_PTYPE_INT) &&
151 (pinfo.type != PICL_PTYPE_UNSIGNED_INT)) {
152 *ret = PICL_FAILURE;
153 return (0);
154 }
155
156 /* uint prop */
157
158 switch (pinfo.size) {
159 case sizeof (uint8_t):
160 err = picl_get_propval(proph, &uint8v, sizeof (uint8v));
161 *ret = err;
162 return (uint8v);
163 case sizeof (uint16_t):
164 err = picl_get_propval(proph, &uint16v, sizeof (uint16v));
165 *ret = err;
166 return (uint16v);
167 case sizeof (uint32_t):
168 err = picl_get_propval(proph, &uint32v, sizeof (uint32v));
169 *ret = err;
170 return (uint32v);
171 case sizeof (uint64_t):
172 err = picl_get_propval(proph, &uint64v, sizeof (uint64v));
173 *ret = err;
174 return (uint64v);
175 default: /* not supported size */
176 *ret = PICL_FAILURE;
177 return (0);
178 }
179 }
180
181
182
183 /*
184 * get the clock frequency
185 */
186 static int
picldiag_get_clock_freq(picl_nodehdl_t modh,uint32_t * freq)187 picldiag_get_clock_freq(picl_nodehdl_t modh, uint32_t *freq)
188 {
189 #define ROUND_TO_MHZ(x) (((x) + 500000)/ 1000000)
190
191 int err;
192 uint64_t clk_freq;
193
194 clk_freq = picldiag_get_uint_propval(modh, OBP_PROP_CLOCK_FREQ, &err);
195 if (err != PICL_SUCCESS)
196 return (err);
197
198 *freq = ROUND_TO_MHZ(clk_freq);
199
200 return (PICL_SUCCESS);
201 }
202
203
204 /*
205 * display the clock frequency
206 */
207 static int
display_system_clock(picl_nodehdl_t plafh)208 display_system_clock(picl_nodehdl_t plafh)
209 {
210 uint32_t system_clk;
211 int err;
212
213 err = picldiag_get_clock_freq(plafh, &system_clk);
214 if (err != PICL_SUCCESS)
215 return (err);
216
217 log_printf(dgettext(TEXT_DOMAIN,
218 "System clock frequency: %d MHZ\n"), system_clk);
219
220 return (PICL_SUCCESS);
221 }
222
223
224 /*
225 * get the value by the property name of the string prop
226 * Caller must free the outbuf
227 */
228 static int
picldiag_get_string_propval(picl_nodehdl_t modh,char * prop_name,char ** outbuf)229 picldiag_get_string_propval(picl_nodehdl_t modh, char *prop_name, char **outbuf)
230 {
231 int err;
232 picl_prophdl_t proph;
233 picl_propinfo_t pinfo;
234 char *prop_value;
235
236 err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
237 if (err != PICL_SUCCESS)
238 return (err);
239
240 /*
241 * If it is not a string prop, return NULL
242 */
243 if (pinfo.type != PICL_PTYPE_CHARSTRING)
244 return (PICL_FAILURE);
245
246 prop_value = malloc(pinfo.size);
247 if (prop_value == NULL)
248 return (PICL_FAILURE);
249
250 err = picl_get_propval(proph, prop_value, pinfo.size);
251 if (err != PICL_SUCCESS) {
252 free(prop_value);
253 return (err);
254 }
255
256 *outbuf = prop_value;
257 return (PICL_SUCCESS);
258 }
259
260
261
262 /*
263 * display platform banner
264 */
265 static int
display_platform_banner(picl_nodehdl_t plafh)266 display_platform_banner(picl_nodehdl_t plafh)
267 {
268 char *platform;
269 char *banner_name;
270 int err;
271
272 /*
273 * get PICL_PROP_MACHINE and PICL_PROP_BANNER_NAME
274 */
275 log_printf(dgettext(TEXT_DOMAIN,
276 "System Configuration: Oracle Corporation "), 0);
277 err = picldiag_get_string_propval(plafh, PICL_PROP_MACHINE,
278 &platform);
279 if (err != PICL_SUCCESS)
280 return (err);
281 log_printf(" %s", platform, 0);
282 free(platform);
283
284 err = picldiag_get_string_propval(plafh, OBP_PROP_BANNER_NAME,
285 &banner_name);
286 if (err != PICL_SUCCESS)
287 return (err);
288 log_printf(" %s", banner_name, 0);
289 free(banner_name);
290
291 log_printf("\n", 0);
292 return (PICL_SUCCESS);
293 }
294
295 /*
296 * search children to get the node by the nodename
297 */
298 static int
picldiag_get_node_by_name(picl_nodehdl_t rooth,char * name,picl_nodehdl_t * nodeh)299 picldiag_get_node_by_name(picl_nodehdl_t rooth, char *name,
300 picl_nodehdl_t *nodeh)
301 {
302 picl_nodehdl_t childh;
303 int err;
304 char *nodename;
305
306 nodename = alloca(strlen(name) + 1);
307 if (nodename == NULL)
308 return (PICL_FAILURE);
309
310 err = picl_get_propval_by_name(rooth, PICL_PROP_CHILD, &childh,
311 sizeof (picl_nodehdl_t));
312
313 while (err == PICL_SUCCESS) {
314 err = picl_get_propval_by_name(childh, PICL_PROP_NAME,
315 nodename, (strlen(name) + 1));
316 if (err != PICL_SUCCESS) {
317 err = picl_get_propval_by_name(childh, PICL_PROP_PEER,
318 &childh, sizeof (picl_nodehdl_t));
319 continue;
320 }
321
322 if (strcmp(nodename, name) == 0) {
323 *nodeh = childh;
324 return (PICL_SUCCESS);
325 }
326
327 err = picl_get_propval_by_name(childh, PICL_PROP_PEER,
328 &childh, sizeof (picl_nodehdl_t));
329 }
330
331 return (err);
332 }
333
334
335 /*
336 * This routine is invoked when prtdiag starts execution. It prints
337 * system configuration, memory size, initializes PICL and acts as
338 * a driver routine for prtdiag output for Snowbird.
339 */
340 /* ARGSUSED */
341 int
do_prominfo(int syserrlog,char * pname,int log_flag,int prt_flag)342 do_prominfo(int syserrlog, char *pname, int log_flag, int prt_flag)
343 {
344
345 struct mem_total memory_total; /* total memory in system */
346 struct grp_info grps;
347 uint8_t status = PD_SUCCESS;
348 picl_nodehdl_t rooth;
349 picl_nodehdl_t plafh;
350 struct system_kstat_data *kstats = NULL;
351 Sys_tree *tree = NULL;
352
353 sys_clk = -1;
354 pd_print_option = syserrlog;
355
356 if ((status = picl_initialize()) != PICL_SUCCESS) {
357 log_printf("prtdiag: failed to initialize the PICL\n", 0);
358 exit(1);
359 }
360
361 if ((status = picl_get_root(&rooth)) != PICL_SUCCESS) {
362 log_printf("prtdiag: failed\n", 0);
363 exit(1);
364 }
365
366 status = picldiag_get_node_by_name(rooth, PICL_NODE_PLATFORM, &plafh);
367 if (status != PICL_SUCCESS)
368 return (status);
369
370 if (!log_flag) {
371
372 status = display_platform_banner(plafh);
373 if (status != PICL_SUCCESS)
374 return (status);
375
376 status = display_system_clock(plafh);
377 if (status != PICL_SUCCESS)
378 return (status);
379
380 /* display the memory Size */
381 display_memorysize(tree, kstats, &grps, &memory_total);
382 }
383
384 if ((pd_smc_fd = open(PD_SMC_DRV_PATH, O_RDWR)) == -1)
385 return (PD_FAILURE);
386
387 if ((status = pd_check_for_snowbird()) != PD_SUCCESS)
388 return (status);
389
390 if ((status = pd_prt_snowbird_diag()) != PD_SUCCESS)
391 return (status);
392
393 (void) close(pd_smc_fd);
394
395 if (picl_shutdown() != PICL_SUCCESS)
396 return (PD_INTERNAL_FAILURE);
397
398 return (PD_SUCCESS);
399
400 }
401
402 /*
403 * This routine prints out the platform name.
404 */
405
406 static uint32_t
pd_check_for_snowbird()407 pd_check_for_snowbird()
408 {
409
410 char si_platform[30];
411
412 if (sysinfo(SI_PLATFORM, si_platform, sizeof (si_platform)) == -1) {
413 return (PD_FAILURE);
414 }
415 /* is it a Snowbird? */
416 if (strcmp(si_platform, SNOWBIRD) != 0)
417 return (PD_FAILURE);
418
419 log_printf("platform Type : %s\n", si_platform, 0);
420 return (PD_SUCCESS);
421
422 }
423
424
425 /*
426 * Driver routine for satellite specific output. This is also used by
427 * host driver routine as all satellite information is printed by host.
428 * It also prints some host specific information for formatting purposes
429 */
430
431 static uint32_t
pd_prt_snowbird_diag()432 pd_prt_snowbird_diag()
433 {
434 uint8_t status = PD_SUCCESS;
435 if ((status = pd_check_cpu_health()) != PD_SUCCESS) {
436 return (status);
437 }
438 if (pd_print_option) {
439
440 log_printf(
441 "\n %11s Other Miscellaneous Information \n",
442 PD_BLANK, 0);
443 log_printf(
444 "%12s ------------------------------- \n",
445 PD_BLANK, 0);
446
447 if ((status = pd_get_role_information()) != PD_SUCCESS) {
448 return (status);
449 }
450
451 if (pd_smc_glbl_enabl_rsp[1] & 0x10) {
452 log_printf(
453 "IPMI Response Notification\t\tEnabled\n", 0);
454 } else {
455 log_printf(
456 "IPMI Response Notification\t\tDisabled\n", 0);
457 }
458 if ((status = pd_query_SMC_firmware_version()) != PD_SUCCESS) {
459 return (status);
460 }
461
462 if ((status = pd_check_tty_debug_mode()) != PD_SUCCESS) {
463 return (status);
464 }
465
466 if ((status = pd_get_reset_mode()) != PD_SUCCESS) {
467 return (status);
468 }
469
470 if ((status = pd_get_message_flags()) != PD_SUCCESS) {
471 return (status);
472 }
473
474 if ((status = pd_query_watchdog_state()) != PD_SUCCESS) {
475 return (status);
476 }
477
478 if ((status = pd_get_sensor_reading()) != PD_SUCCESS) {
479 return (status);
480 }
481
482 if ((status = pd_get_sensor_threshold()) != PD_SUCCESS) {
483 return (status);
484 }
485
486 }
487 return (status);
488
489 }
490
491 /*
492 * This routine prints the mode in which SMC is running. It uses the
493 * response from SMC global enables to determine the mode
494 */
495 static uint32_t
pd_check_tty_debug_mode()496 pd_check_tty_debug_mode()
497 {
498
499 if (pd_smc_glbl_enabl_rsp[1] & 0x20) {
500 log_printf("SMC verbose mode\t\t\tON\n", 0);
501 } else {
502 log_printf("SMC verbose mode\t\t\tOFF\n", 0);
503 }
504
505 return (PD_SUCCESS);
506 }
507
508 /* This routine prints SMC f/w version */
509 static uint32_t
pd_query_SMC_firmware_version()510 pd_query_SMC_firmware_version()
511 {
512
513 sc_reqmsg_t req_pkt;
514 sc_rspmsg_t rsp_pkt;
515 uint8_t ver, rev, bldrev;
516
517
518 smc_init_smc_msg(&req_pkt, SMC_QUERY_FIRMWARE_VERSION,
519 DEFAULT_SEQN, 0);
520 smc_send_msg(-1, &req_pkt, &rsp_pkt, POLL_TIMEOUT);
521 ver = (rsp_pkt.data[0] & 0xf0) >> 4;
522 rev = rsp_pkt.data[0] & 0x0f;
523 bldrev = rsp_pkt.data[2] & 0x3f;
524
525 log_printf("SMC f/w version is\t\t\t%d.%d.%d\n", ver, rev, bldrev, 0);
526
527 return (PD_SUCCESS);
528
529 }
530
531 /*
532 * This routine checks CPU's health by using SMC self test results command
533 * It acts as driver routine for printing cPCI slot information
534 */
535 static uint32_t
pd_check_cpu_health()536 pd_check_cpu_health()
537 {
538
539 sc_reqmsg_t req_pkt;
540 sc_rspmsg_t rsp_pkt;
541 uint8_t dev_id = 0x1f;
542 #ifdef DEBUG
543 uint8_t i2c_chk = 0x40;
544 #endif
545 uint8_t mem_test = 0x20;
546
547 smc_init_smc_msg(&req_pkt, SMC_GET_SMC_SELF_TEST_RESULT,
548 DEFAULT_SEQN, 0);
549 smc_send_msg(-1, &req_pkt, &rsp_pkt, POLL_TIMEOUT);
550
551 dev_id = rsp_pkt.data[0] & dev_id;
552
553 #ifdef DEBUG
554 if (rsp_pkt.data[0] & i2c_chk) {
555 pd_print_device_info(dev_id);
556 }
557 #endif
558 if (rsp_pkt.data[0] & mem_test) {
559 pd_print_device_info(dev_id);
560 }
561 return (pd_check_slots());
562
563 }
564
565 /*
566 * This routine decodes error message for CPU failures and prints details
567 * of the failure
568 */
569 static uint32_t
pd_print_device_info(int dev_id)570 pd_print_device_info(int dev_id)
571 {
572
573 switch (dev_id) {
574 case 1:
575 log_printf("Mux Philip 9540\n", 0);
576 break;
577 case 2:
578 log_printf("cpu temp max1617\n", 0);
579 break;
580 case 3:
581 log_printf("pmc temp max 1617\n", 0);
582 break;
583 case 4:
584 log_printf("MB HS temp max 1617\n", 0);
585 break;
586 case 5:
587 log_printf("MB mem temp max1617\n", 0);
588 break;
589 case 6:
590 log_printf("MB gpio Philip8574\n", 0);
591 break;
592 case 7:
593 log_printf("MB Fru ID ID i2c eep\n", 0);
594 break;
595 case 8:
596 log_printf("MB enet ID ID i2d eep\n", 0);
597 break;
598 case 9:
599 log_printf("MB gpio Philip8574A\n", 0);
600 break;
601 case 10:
602 log_printf("SDRAM mod1 temp max1617\n", 0);
603 break;
604 case 11:
605 log_printf("SDRAM mod ID ID i2c eep\n", 0);
606 break;
607 case 12:
608 log_printf("SDRAM mod2 temp max1617\n", 0);
609 break;
610 case 13:
611 log_printf("SDRAM mod ID ID i2c eep\n", 0);
612 break;
613 case 14:
614 log_printf("Power mod temp ds1721\n", 0);
615 break;
616 case 15:
617 log_printf("Power mod gpio Philip 8574\n", 0);
618 break;
619 case 16:
620 log_printf("Power mod ID eep ST M24C01\n", 0);
621 break;
622 case 17:
623 log_printf("SMC ID i2c eep\n", 0);
624 break;
625
626 default:
627 log_printf("device id unknown\n", 0);
628 break;
629
630 }
631
632 return (PD_SUCCESS);
633
634 }
635
636 /*
637 * This routine walks PICL tree by "Location" class and calls prt_slot_info
638 * routine to print the slot information
639 */
640
641 /*ARGSUSED*/
642 static uint32_t
pd_check_slots()643 pd_check_slots()
644 {
645
646 picl_nodehdl_t nodeh;
647 char *c_args = NULL;
648
649 if (picl_get_root(&nodeh) != PICL_SUCCESS)
650 return (PD_INTERNAL_FAILURE);
651
652
653 if (picl_walk_tree_by_class(nodeh, PICL_CLASS_LOCATION,
654 (void *)c_args, pd_prt_slot_info) != PICL_SUCCESS) {
655 return (PD_INTERNAL_FAILURE);
656 }
657
658 return (PD_SUCCESS);
659
660 }
661
662
663 /*ARGSUSED*/
664 int32_t
665
pd_prt_slot_info(picl_nodehdl_t nodeh,void * c_args)666 pd_prt_slot_info(picl_nodehdl_t nodeh, void *c_args)
667 {
668
669 char *valbuf;
670 char label_txt[30];
671 int unit_no = -1, ctr = 0;
672 picl_nodehdl_t childh;
673 picl_propinfo_t propinfo;
674 picl_prophdl_t proph;
675
676 /* if not immediate child of "chassis" node, ignore it */
677 if (pd_check_location_parent(nodeh) != PD_SUCCESS)
678 return (PD_INTERNAL_FAILURE);
679
680
681 /* get the label on the location */
682 if (picl_get_prop_by_name(nodeh, PICL_PROP_LABEL,
683 &proph) != PICL_SUCCESS)
684 return (PD_INTERNAL_FAILURE);
685
686 if (picl_get_propinfo(proph, &propinfo) != PICL_SUCCESS)
687 return (PD_INTERNAL_FAILURE);
688
689 valbuf = (char *) malloc(sizeof (char) * (propinfo.size));
690 if (valbuf == NULL)
691 return (PD_INTERNAL_FAILURE);
692
693 if (picl_get_propval(proph, (void *)valbuf, propinfo.size)
694 != PICL_SUCCESS) {
695 free(valbuf);
696 return (PD_INTERNAL_FAILURE);
697 }
698
699 while (valbuf[ctr] != ' ' && valbuf[ctr] != NULL) {
700 label_txt[ctr] = valbuf[ctr];
701 ++ctr;
702 }
703
704 label_txt[ctr++] = '\0';
705
706 if (valbuf[ctr] != NULL) {
707 unit_no = atoi(valbuf+ctr);
708 }
709
710 free(valbuf);
711
712 /* get the slot type for the location */
713 if (picl_get_prop_by_name(nodeh, PICL_PROP_SLOT_TYPE,
714 &proph) != PICL_SUCCESS)
715 return (PD_INTERNAL_FAILURE);
716
717 if (picl_get_propinfo(proph, & propinfo) != PICL_SUCCESS)
718 return (PD_INTERNAL_FAILURE);
719
720 valbuf = (char *) malloc(sizeof (char) * (propinfo.size));
721 if (valbuf == NULL)
722 return (PD_INTERNAL_FAILURE);
723
724 if (picl_get_propval(proph, (void *)valbuf,
725 propinfo.size) != PICL_SUCCESS) {
726 free(valbuf);
727 return (PD_INTERNAL_FAILURE);
728 }
729
730 if ((strcmp(valbuf, PD_CPCI_SLOT_TYPE) == 0) ||
731 (strcmp(valbuf, PD_PCI_SLOT_TYPE) == 0)) {
732 (void) pd_print_fruinfo_hdr();
733 log_printf("\n%s ", label_txt, 0);
734
735 /* For Snowbird no unit number is present on the label */
736 unit_no = 1;
737 log_printf(" %d Yes cPSB IO Slot\n", unit_no, 0);
738
739 if (picl_get_propval_by_name(nodeh, PICL_PROP_CHILD,
740 &childh, sizeof (childh)) == PICL_SUCCESS) {
741 pd_prt_cpci_condition(childh);
742 }
743 /* For Snowbird auto configuration is always enabled */
744 log_printf("%29s Properties:\n", PD_BLANK, 0);
745 log_printf("%31s auto-config = enabled\n", PD_BLANK, 0);
746 }
747
748
749 free(valbuf);
750 return (PD_SUCCESS);
751
752 }
753
754
755
756 static uint32_t
pd_print_fruinfo_hdr()757 pd_print_fruinfo_hdr()
758 {
759
760 log_printf(
761 "\n %19s FRU Information \n",
762 PD_BLANK, 0);
763 log_printf(
764 "%11s ------------------------------------------------\n",
765 PD_BLANK, 0);
766
767 log_printf(dgettext(TEXT_DOMAIN,
768 "FRU FRU FRU Miscellaneous\n"), 0);
769 log_printf(dgettext(TEXT_DOMAIN,
770 "Type Unit# Present Information\n"), 0);
771 log_printf("---- ----- -------", 0);
772 log_printf(" --------------------------------\n", 0);
773 return (PD_SUCCESS);
774
775 }
776
777 static uint32_t
pd_check_location_parent(picl_nodehdl_t nodeh)778 pd_check_location_parent(picl_nodehdl_t nodeh)
779 {
780
781 picl_nodehdl_t parenth;
782 char *prop_name;
783
784 if (picl_get_propval_by_name(nodeh, PICL_PROP_PARENT,
785 &parenth, sizeof (parenth)) != PICL_SUCCESS) {
786 return (PD_FAILURE);
787 }
788
789 prop_name = (char *) malloc(sizeof (char) * PICL_PROPNAMELEN_MAX);
790 if (prop_name == NULL) {
791 return (PD_FAILURE);
792 }
793
794 if (picl_get_propval_by_name(parenth, PICL_PROP_NAME, (void *)prop_name,
795 PICL_PROPNAMELEN_MAX) != PICL_SUCCESS) {
796 free(prop_name);
797 return (PD_FAILURE);
798 }
799
800 if (strcmp(prop_name, CHASSIS_NODE_NAME) == 0) {
801 free(prop_name);
802 return (PD_SUCCESS);
803 } else {
804 free(prop_name);
805 return (PD_FAILURE);
806 }
807
808 }
809
810
811 /*ARGSUSED*/
812 static uint32_t
pd_query_watchdog_state()813 pd_query_watchdog_state()
814 {
815
816 picl_nodehdl_t nodehandle;
817 char *c_args = NULL;
818
819 if (picl_get_root(&nodehandle) != PICL_SUCCESS) {
820 return (PD_INTERNAL_FAILURE);
821 }
822
823 if (picl_walk_tree_by_class(nodehandle, PICL_CLASS_WATCHDOG_TIMER,
824 (void *)c_args, pd_check_wd_state) != PICL_SUCCESS)
825 return (PD_INTERNAL_FAILURE);
826
827 return (PD_SUCCESS);
828
829 }
830
831 /*ARGSUSED*/
832 int
pd_check_wd_state(picl_nodehdl_t nodeh,void * c_args)833 pd_check_wd_state(picl_nodehdl_t nodeh, void *c_args)
834 {
835
836 char *prop_name, *valbuf;
837 picl_propinfo_t propinfo;
838 picl_prophdl_t proph;
839
840 prop_name = (char *) malloc(sizeof (char) * PICL_PROPNAMELEN_MAX);
841 if (prop_name == NULL) {
842 return (PICL_WALK_TERMINATE);
843 }
844
845 if (picl_get_propval_by_name(nodeh, PICL_PROP_NAME,
846 (void *)prop_name, PICL_PROPNAMELEN_MAX) != PICL_SUCCESS) {
847 free(prop_name);
848 return (PICL_WALK_TERMINATE);
849 }
850
851 if ((picl_get_prop_by_name(nodeh, PICL_PROP_STATE,
852 &proph)) != PICL_SUCCESS) {
853 free(prop_name);
854 return (PICL_WALK_TERMINATE);
855 }
856
857 if ((picl_get_propinfo(proph, &propinfo)) != PICL_SUCCESS) {
858 free(prop_name);
859 return (PICL_WALK_TERMINATE);
860 }
861
862 valbuf = (char *) malloc(sizeof (char) * (propinfo.size));
863 if (valbuf == NULL) {
864 free(prop_name);
865 return (PICL_WALK_TERMINATE);
866 }
867
868 if ((picl_get_propval(proph, (void *)valbuf,
869 propinfo.size)) != PICL_SUCCESS) {
870 free(valbuf);
871 free(prop_name);
872 return (PICL_WALK_TERMINATE);
873 }
874
875 if (pd_hdr_prt) {
876 log_printf("\n Watch Dog Status \n", 0);
877 log_printf(" ---------------- \n", 0);
878 log_printf("Node Status\n", 0);
879 log_printf("---- ------\n", 0);
880 pd_hdr_prt = B_FALSE;
881 }
882
883 log_printf("%s ", prop_name, 0);
884 log_printf("%s\n", valbuf, 0);
885
886 free(prop_name);
887 free(valbuf);
888 return (PICL_WALK_CONTINUE);
889
890 }
891
892
893 static uint32_t
pd_get_role_information()894 pd_get_role_information()
895 {
896
897 sc_reqmsg_t req_pkt;
898 sc_rspmsg_t rsp_pkt;
899 uint8_t usparc_role;
900
901 smc_init_smc_msg(&req_pkt, SMC_GET_ROLE_INFO,
902 DEFAULT_SEQN, 0);
903 smc_send_msg(-1, &req_pkt, &rsp_pkt, POLL_TIMEOUT);
904 usparc_role = rsp_pkt.data[1];
905
906 log_printf(dgettext(TEXT_DOMAIN,
907 "UltraSPARC Host Role\t\t\t"), 0);
908 if (usparc_role & 0x80) {
909 log_printf(
910 dgettext(TEXT_DOMAIN,
911 "System Board Computer (SBC)\n"), 0);
912 }
913 if (usparc_role & 0x40) {
914 log_printf(dgettext(TEXT_DOMAIN,
915 "Standby System Board Computer (Standby SBC)\n"), 0);
916 }
917 if (usparc_role & 0x20) {
918 log_printf(dgettext(TEXT_DOMAIN,
919 "Alternate System Board Computer (Alternate SBC)\n"), 0);
920 }
921 if (usparc_role & 0x10) {
922 log_printf(dgettext(TEXT_DOMAIN,
923 "Satellite Board Computer (SAT)\n"), 0);
924 }
925 return (PD_SUCCESS);
926
927 }
928
929
930 static uint32_t
pd_get_message_flags()931 pd_get_message_flags()
932 {
933
934 sc_reqmsg_t req_pkt;
935 sc_rspmsg_t rsp_pkt;
936
937 smc_init_smc_msg(&req_pkt, SMC_GET_MESSAGE_FLAGS,
938 DEFAULT_SEQN, 0);
939 smc_send_msg(-1, &req_pkt, &rsp_pkt, POLL_TIMEOUT);
940
941 if (rsp_pkt.data[0] & 0x01) {
942 log_printf("Messages Available in queue Recieving\n", 0);
943 } else {
944 log_printf("No messages in queue for Recieving\n", 0);
945 }
946
947 return (PD_SUCCESS);
948
949
950 }
951
952
953
954 static uint32_t
pd_get_reset_mode()955 pd_get_reset_mode()
956 {
957
958 sc_reqmsg_t req_pkt;
959 sc_rspmsg_t rsp_pkt;
960
961
962 smc_init_smc_msg(&req_pkt, SMC_GET_CONFIG_BLOCK,
963 DEFAULT_SEQN, 0);
964 smc_send_msg(-1, &req_pkt, &rsp_pkt, POLL_TIMEOUT);
965
966 log_printf("Reset Mode\t\t\t\t%x \n", rsp_pkt.data[2], 0);
967
968 return (PD_SUCCESS);
969
970 }
971
972
973 static uint32_t
pd_get_sensor_reading()974 pd_get_sensor_reading()
975 {
976
977
978 sc_reqmsg_t req_pkt;
979 sc_rspmsg_t rsp_pkt;
980
981 req_pkt.data[0] = 0x0e;
982
983 smc_init_smc_msg(&req_pkt, SMC_SENSOR_READING_GET,
984 DEFAULT_SEQN, 1);
985 smc_send_msg(-1, &req_pkt, &rsp_pkt, POLL_TIMEOUT);
986 log_printf("\nCPU Node Temperature Information\n", PD_BLANK, 0);
987 log_printf("--------------------------------\n", PD_BLANK, 0);
988 log_printf("Temperature Reading: %d\n\n", rsp_pkt.data[0], 0);
989
990 return (PD_SUCCESS);
991
992 }
993
994
995 static uint32_t
pd_get_sensor_threshold()996 pd_get_sensor_threshold()
997 {
998
999
1000 sc_reqmsg_t req_pkt;
1001 sc_rspmsg_t rsp_pkt;
1002 uint8_t thres_mask;
1003 req_pkt.data[0] = 0x0e;
1004
1005 smc_init_smc_msg(&req_pkt, SMC_SENSOR_THRESHOLD_GET,
1006 DEFAULT_SEQN, 1);
1007 smc_send_msg(-1, &req_pkt, &rsp_pkt, POLL_TIMEOUT);
1008 log_printf("Critical Threshold Information\n", 0);
1009 log_printf("------------------------------\n", 0);
1010
1011 thres_mask = rsp_pkt.data[0];
1012
1013 if (thres_mask & 0x20) {
1014 log_printf("High Power-Off Threshold %9s", PD_BLANK, 0);
1015 if (rsp_pkt.data[6] & 0x80) {
1016 log_printf("-%d\n",
1017 (int)((uint8_t)~rsp_pkt.data[6] + 1), 0);
1018 } else {
1019 log_printf(" %d\n", rsp_pkt.data[6], 0);
1020 }
1021 }
1022
1023 if (thres_mask & 0x10) {
1024 log_printf("High Shutdown Threshold %10s", PD_BLANK, 0);
1025 if (rsp_pkt.data[5] & 0x80) {
1026 log_printf("-%d\n",
1027 (int)((uint8_t)~rsp_pkt.data[5] + 1), 0);
1028 } else {
1029 log_printf(" %d\n", rsp_pkt.data[5], 0);
1030 }
1031 }
1032
1033
1034 if (thres_mask & 0x08) {
1035 log_printf("High Warning Threshold %11s", PD_BLANK, 0);
1036 if (rsp_pkt.data[4] & 0x80) {
1037 log_printf("-%d\n",
1038 (int)((uint8_t)~rsp_pkt.data[4] + 1), 0);
1039 } else {
1040 log_printf(" %d\n", rsp_pkt.data[4], 0);
1041 }
1042 }
1043
1044 if (thres_mask & 0x04) {
1045 log_printf("Low Power Off Threshold %10s", PD_BLANK, 0);
1046 if (rsp_pkt.data[3] & 0x80) {
1047 log_printf("-%d\n",
1048 (int)((uint8_t)~rsp_pkt.data[3] + 1), 0);
1049 } else {
1050 log_printf(" %d\n", rsp_pkt.data[3], 0);
1051 }
1052 }
1053
1054 if (thres_mask & 0x02) {
1055 log_printf("Low Shutdown Threshold %11s", PD_BLANK, 0);
1056 if (rsp_pkt.data[2] & 0x80) {
1057 log_printf("-%d\n",
1058 (int)((uint8_t)~rsp_pkt.data[2] + 1), 0);
1059 } else {
1060 log_printf(" %d\n", rsp_pkt.data[2], 0);
1061 }
1062 }
1063
1064 if (thres_mask & 0x01) {
1065 log_printf("Low Warning Threshold %12s", PD_BLANK, 0);
1066 if (rsp_pkt.data[1] & 0x80) {
1067 log_printf("-%d\n",
1068 (int)((uint8_t)~rsp_pkt.data[1] + 1), 0);
1069 } else {
1070 log_printf(" %d\n", rsp_pkt.data[1], 0);
1071 }
1072 }
1073
1074 return (PD_SUCCESS);
1075
1076 }
1077
1078
1079
1080 static uint32_t
pd_prt_cpci_condition(picl_nodehdl_t nodeh)1081 pd_prt_cpci_condition(picl_nodehdl_t nodeh)
1082 {
1083
1084 picl_propinfo_t propinfo;
1085 picl_prophdl_t proph;
1086 char *valbuf;
1087
1088
1089 if (picl_get_prop_by_name(nodeh, PICL_PROP_CONDITION,
1090 &proph) != PICL_SUCCESS) {
1091 return (PD_FAILURE);
1092 }
1093
1094 if (picl_get_propinfo(proph, &propinfo) != PICL_SUCCESS) {
1095 return (PD_FAILURE);
1096 }
1097
1098 valbuf = (char *) malloc(sizeof (char) * (propinfo.size));
1099 if (valbuf == NULL) {
1100 return (PD_FAILURE);
1101 }
1102
1103 if (picl_get_propval(proph, (void *)valbuf,
1104 propinfo.size) != PICL_SUCCESS) {
1105 free(valbuf);
1106 return (PD_FAILURE);
1107 }
1108
1109
1110 log_printf("%29s Condition : %s\n", PD_BLANK, valbuf, 0);
1111
1112 free(valbuf);
1113 return (PD_SUCCESS);
1114
1115
1116 }
1117