/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/*
* This program prints the diagnostics of Sanibel system. It
* also prints other miscellaneous information about watchdog, temperature
* of CPU sensor, firmware versions of SMC and, micro controller role
* etc. The basic sources of output is PICL, and SMC.
*/
/* includes */
#include <stdio.h>
#include <strings.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <dirent.h>
#include <picl.h>
#include <libintl.h>
#include <sys/systeminfo.h>
#include <sys/openpromio.h>
#include <fcntl.h>
#include <smc_if.h>
#include <stropts.h>
#include <alloca.h>
#include <errno.h>
#include <poll.h>
#include <stdlib.h>
#include <unistd.h>
#include <kstat.h>
#include <stddef.h>
#include <pdevinfo.h>
#include <display_sun4u.h>
#include <libprtdiag.h>
#include <smclib.h>
#include <smc_commands.h>
#include <picldefs.h>
/* #defines for the PICL library API usage and local static variables */
#define PD_DISABLED 0
/* #defines for the SMC and IPMI commands */
/* SMC driver */
/* Constants */
/* #defines for local usage */
#define PD_SUCCESS 0
/* static global variables */
static int pd_print_option;
static int pd_smc_fd = 0;
/* function declarations used in this program */
static uint32_t pd_check_for_snowbird();
static uint32_t pd_prt_snowbird_diag();
static uint32_t pd_check_cpu_health();
static uint32_t pd_check_tty_debug_mode();
static uint32_t pd_query_SMC_firmware_version();
static uint32_t pd_check_slots();
static uint32_t pd_query_watchdog_state();
int pd_check_wd_state(picl_nodehdl_t, void *);
static uint32_t pd_print_fruinfo_hdr();
static uint32_t pd_print_device_info(int);
static uint32_t pd_get_role_information();
static uint32_t pd_get_message_flags();
static uint32_t pd_get_reset_mode();
static uint32_t pd_get_sensor_reading();
static uint32_t pd_get_sensor_threshold();
static uint64_t
/*
* return the value of the uint prop
*/
static uint64_t
{
int err;
if (err != PICL_SUCCESS) {
return (0);
}
/*
* If it is not an int or uint prop, return failure
*/
*ret = PICL_FAILURE;
return (0);
}
/* uint prop */
case sizeof (uint8_t):
return (uint8v);
case sizeof (uint16_t):
return (uint16v);
case sizeof (uint32_t):
return (uint32v);
case sizeof (uint64_t):
return (uint64v);
default: /* not supported size */
*ret = PICL_FAILURE;
return (0);
}
}
/*
* get the clock frequency
*/
static int
{
int err;
if (err != PICL_SUCCESS)
return (err);
return (PICL_SUCCESS);
}
/*
* display the clock frequency
*/
static int
{
int err;
if (err != PICL_SUCCESS)
return (err);
"System clock frequency: %d MHZ\n"), system_clk);
return (PICL_SUCCESS);
}
/*
* get the value by the property name of the string prop
* Caller must free the outbuf
*/
static int
{
int err;
char *prop_value;
if (err != PICL_SUCCESS)
return (err);
/*
* If it is not a string prop, return NULL
*/
return (PICL_FAILURE);
if (prop_value == NULL)
return (PICL_FAILURE);
if (err != PICL_SUCCESS) {
return (err);
}
*outbuf = prop_value;
return (PICL_SUCCESS);
}
/*
* display platform banner
*/
static int
{
char *platform;
char *banner_name;
int err;
/*
* get PICL_PROP_MACHINE and PICL_PROP_BANNER_NAME
*/
"System Configuration: Oracle Corporation "), 0);
&platform);
if (err != PICL_SUCCESS)
return (err);
&banner_name);
if (err != PICL_SUCCESS)
return (err);
log_printf("\n", 0);
return (PICL_SUCCESS);
}
/*
* search children to get the node by the nodename
*/
static int
{
int err;
char *nodename;
return (PICL_FAILURE);
sizeof (picl_nodehdl_t));
while (err == PICL_SUCCESS) {
if (err != PICL_SUCCESS) {
&childh, sizeof (picl_nodehdl_t));
continue;
}
return (PICL_SUCCESS);
}
&childh, sizeof (picl_nodehdl_t));
}
return (err);
}
/*
* This routine is invoked when prtdiag starts execution. It prints
* system configuration, memory size, initializes PICL and acts as
* a driver routine for prtdiag output for Snowbird.
*/
/* ARGSUSED */
int
{
sys_clk = -1;
log_printf("prtdiag: failed to initialize the PICL\n", 0);
exit(1);
}
log_printf("prtdiag: failed\n", 0);
exit(1);
}
if (status != PICL_SUCCESS)
return (status);
if (!log_flag) {
if (status != PICL_SUCCESS)
return (status);
if (status != PICL_SUCCESS)
return (status);
/* display the memory Size */
}
return (PD_FAILURE);
return (status);
return (status);
if (picl_shutdown() != PICL_SUCCESS)
return (PD_INTERNAL_FAILURE);
return (PD_SUCCESS);
}
/*
* This routine prints out the platform name.
*/
static uint32_t
{
return (PD_FAILURE);
}
/* is it a Snowbird? */
return (PD_FAILURE);
return (PD_SUCCESS);
}
/*
* Driver routine for satellite specific output. This is also used by
* host driver routine as all satellite information is printed by host.
* It also prints some host specific information for formatting purposes
*/
static uint32_t
{
return (status);
}
if (pd_print_option) {
"\n %11s Other Miscellaneous Information \n",
PD_BLANK, 0);
"%12s ------------------------------- \n",
PD_BLANK, 0);
return (status);
}
"IPMI Response Notification\t\tEnabled\n", 0);
} else {
"IPMI Response Notification\t\tDisabled\n", 0);
}
return (status);
}
return (status);
}
return (status);
}
return (status);
}
return (status);
}
return (status);
}
return (status);
}
}
return (status);
}
/*
* This routine prints the mode in which SMC is running. It uses the
* response from SMC global enables to determine the mode
*/
static uint32_t
{
log_printf("SMC verbose mode\t\t\tON\n", 0);
} else {
log_printf("SMC verbose mode\t\t\tOFF\n", 0);
}
return (PD_SUCCESS);
}
/* This routine prints SMC f/w version */
static uint32_t
{
DEFAULT_SEQN, 0);
return (PD_SUCCESS);
}
/*
* This routine checks CPU's health by using SMC self test results command
* It acts as driver routine for printing cPCI slot information
*/
static uint32_t
{
#ifdef DEBUG
#endif
DEFAULT_SEQN, 0);
#ifdef DEBUG
}
#endif
}
return (pd_check_slots());
}
/*
* This routine decodes error message for CPU failures and prints details
* of the failure
*/
static uint32_t
{
switch (dev_id) {
case 1:
log_printf("Mux Philip 9540\n", 0);
break;
case 2:
log_printf("cpu temp max1617\n", 0);
break;
case 3:
log_printf("pmc temp max 1617\n", 0);
break;
case 4:
log_printf("MB HS temp max 1617\n", 0);
break;
case 5:
log_printf("MB mem temp max1617\n", 0);
break;
case 6:
log_printf("MB gpio Philip8574\n", 0);
break;
case 7:
log_printf("MB Fru ID ID i2c eep\n", 0);
break;
case 8:
log_printf("MB enet ID ID i2d eep\n", 0);
break;
case 9:
log_printf("MB gpio Philip8574A\n", 0);
break;
case 10:
log_printf("SDRAM mod1 temp max1617\n", 0);
break;
case 11:
log_printf("SDRAM mod ID ID i2c eep\n", 0);
break;
case 12:
log_printf("SDRAM mod2 temp max1617\n", 0);
break;
case 13:
log_printf("SDRAM mod ID ID i2c eep\n", 0);
break;
case 14:
log_printf("Power mod temp ds1721\n", 0);
break;
case 15:
log_printf("Power mod gpio Philip 8574\n", 0);
break;
case 16:
log_printf("Power mod ID eep ST M24C01\n", 0);
break;
case 17:
log_printf("SMC ID i2c eep\n", 0);
break;
default:
log_printf("device id unknown\n", 0);
break;
}
return (PD_SUCCESS);
}
/*
* This routine walks PICL tree by "Location" class and calls prt_slot_info
* routine to print the slot information
*/
/*ARGSUSED*/
static uint32_t
{
return (PD_INTERNAL_FAILURE);
return (PD_INTERNAL_FAILURE);
}
return (PD_SUCCESS);
}
/*ARGSUSED*/
{
char *valbuf;
/* if not immediate child of "chassis" node, ignore it */
return (PD_INTERNAL_FAILURE);
/* get the label on the location */
&proph) != PICL_SUCCESS)
return (PD_INTERNAL_FAILURE);
return (PD_INTERNAL_FAILURE);
return (PD_INTERNAL_FAILURE);
!= PICL_SUCCESS) {
return (PD_INTERNAL_FAILURE);
}
++ctr;
}
}
/* get the slot type for the location */
&proph) != PICL_SUCCESS)
return (PD_INTERNAL_FAILURE);
return (PD_INTERNAL_FAILURE);
return (PD_INTERNAL_FAILURE);
return (PD_INTERNAL_FAILURE);
}
(void) pd_print_fruinfo_hdr();
/* For Snowbird no unit number is present on the label */
unit_no = 1;
}
/* For Snowbird auto configuration is always enabled */
}
return (PD_SUCCESS);
}
static uint32_t
{
"\n %19s FRU Information \n",
PD_BLANK, 0);
"%11s ------------------------------------------------\n",
PD_BLANK, 0);
"FRU FRU FRU Miscellaneous\n"), 0);
"Type Unit# Present Information\n"), 0);
log_printf("---- ----- -------", 0);
log_printf(" --------------------------------\n", 0);
return (PD_SUCCESS);
}
static uint32_t
{
char *prop_name;
return (PD_FAILURE);
}
return (PD_FAILURE);
}
PICL_PROPNAMELEN_MAX) != PICL_SUCCESS) {
return (PD_FAILURE);
}
return (PD_SUCCESS);
} else {
return (PD_FAILURE);
}
}
/*ARGSUSED*/
static uint32_t
{
return (PD_INTERNAL_FAILURE);
}
return (PD_INTERNAL_FAILURE);
return (PD_SUCCESS);
}
/*ARGSUSED*/
int
{
return (PICL_WALK_TERMINATE);
}
return (PICL_WALK_TERMINATE);
}
&proph)) != PICL_SUCCESS) {
return (PICL_WALK_TERMINATE);
}
return (PICL_WALK_TERMINATE);
}
return (PICL_WALK_TERMINATE);
}
return (PICL_WALK_TERMINATE);
}
if (pd_hdr_prt) {
log_printf("\n Watch Dog Status \n", 0);
log_printf(" ---------------- \n", 0);
log_printf("Node Status\n", 0);
log_printf("---- ------\n", 0);
}
return (PICL_WALK_CONTINUE);
}
static uint32_t
{
DEFAULT_SEQN, 0);
"UltraSPARC Host Role\t\t\t"), 0);
if (usparc_role & 0x80) {
"System Board Computer (SBC)\n"), 0);
}
if (usparc_role & 0x40) {
"Standby System Board Computer (Standby SBC)\n"), 0);
}
if (usparc_role & 0x20) {
"Alternate System Board Computer (Alternate SBC)\n"), 0);
}
if (usparc_role & 0x10) {
"Satellite Board Computer (SAT)\n"), 0);
}
return (PD_SUCCESS);
}
static uint32_t
{
DEFAULT_SEQN, 0);
log_printf("Messages Available in queue Recieving\n", 0);
} else {
log_printf("No messages in queue for Recieving\n", 0);
}
return (PD_SUCCESS);
}
static uint32_t
{
DEFAULT_SEQN, 0);
return (PD_SUCCESS);
}
static uint32_t
{
DEFAULT_SEQN, 1);
return (PD_SUCCESS);
}
static uint32_t
{
DEFAULT_SEQN, 1);
log_printf("Critical Threshold Information\n", 0);
log_printf("------------------------------\n", 0);
if (thres_mask & 0x20) {
log_printf("-%d\n",
} else {
}
}
if (thres_mask & 0x10) {
log_printf("-%d\n",
} else {
}
}
if (thres_mask & 0x08) {
log_printf("-%d\n",
} else {
}
}
if (thres_mask & 0x04) {
log_printf("-%d\n",
} else {
}
}
if (thres_mask & 0x02) {
log_printf("-%d\n",
} else {
}
}
if (thres_mask & 0x01) {
log_printf("-%d\n",
} else {
}
}
return (PD_SUCCESS);
}
static uint32_t
{
char *valbuf;
&proph) != PICL_SUCCESS) {
return (PD_FAILURE);
}
return (PD_FAILURE);
}
return (PD_FAILURE);
}
return (PD_FAILURE);
}
return (PD_SUCCESS);
}