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