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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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