/*
* 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
*/
/*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <alloca.h>
#include <errno.h>
#include <libintl.h>
#include <sys/openpromio.h>
#include <syslog.h>
#include <fcntl.h>
#include <dirent.h>
#include <unistd.h>
#include <locale.h>
#include <picl.h>
#include "pdevinfo.h"
#include "display.h"
#include "display_sun4u.h"
#include "picldefs.h"
#include "libprtdiag.h"
#if !defined(TEXT_DOMAIN)
#endif
"picl_initialize failed: %s\n")
"Getting root node failed: %s\n")
"System Configuration: Oracle Corporation ")
"System clock frequency: %d MHZ\n")
#define DEFAULT_BOARD_NUM 0
#define DEFAULT_PORTID 0
/* bus id */
#define SBUS_TYPE 0
/*
* PICL classes
*/
/*
* Property names
*/
typedef struct bank_list {
} bank_list_t;
typedef struct {
int ifactor;
int bank_count;
} seg_info_t;
static int mem_xfersize;
static int no_xfer_size = 0;
static char *io_device_table[] = {
"block",
"disk",
"cdrom",
"floppy",
"tape",
"network",
"display",
"serial",
"parallel",
"scsi",
"scsi-2",
"scsi-3",
"ide",
"fcal",
"keyboard",
"mouse",
"dma"
};
static char *bus_table[] = {
"ebus",
"isa",
"pmu"
};
/* prtdiag exit codes */
#define PD_SUCCESS 0
/*
* Use of global assumes do_prominfo only called from main in prtdiag and
* access does not need to be multi-thread safe.
*/
/*
* This function is called from every location where a status value is output.
* It checks the status arg and sets exit_code if an error is detected.
* The status is typically returned from a PICL query. A case-insensitive
* string comparison is done to check for any status that starts with "fail"
* or "fault".
*/
static void
{
return;
}
/*
* check if it is an IO deice
*/
static int
{
int i;
for (i = 0; i < NIODEVICE; i++) {
return (1);
}
return (0);
}
/*
* check if it is a bus
*/
static int
{
int i;
for (i = 0; i < NBUS; i++) {
return (1);
}
return (0);
}
/*
* 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);
}
/*
* 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);
}
/*
* return the value as a signed integer
*/
static int64_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);
}
case sizeof (int8_t):
return (int8v);
case sizeof (int16_t):
return (int16v);
case sizeof (int32_t):
return (int32v);
case sizeof (int64_t):
return (int64v);
default: /* not supported size */
*ret = PICL_FAILURE;
return (0);
}
}
/*
* 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);
}
}
/*
* return the value of the float prop
*/
static float
{
int err;
float floatv;
if (err != PICL_SUCCESS) {
return ((float)0);
}
/*
* If it is not a float prop, return failure
*/
*ret = PICL_FAILURE;
return ((float)0);
}
return (floatv);
}
/*
* get the clock frequency
*/
static int
{
int err;
if (err != PICL_SUCCESS)
return (err);
return (PICL_SUCCESS);
}
/*
* get the clock frequency from parent
*/
static int
{
int err;
while (err == PICL_SUCCESS) {
if (err != PICL_PROPNOTFOUND)
return (err);
}
return (err);
}
/*
* get _fru_parent prop
* If not found, then travese superiors (parent nodes) until
* a _fru_parent property is found.
* If not found, no fru parent
*/
static int
{
int err;
/* find fru parent */
if (err != PICL_SUCCESS)
while (err == PICL_PROPNOTFOUND) {
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
}
if (err == PICL_SUCCESS)
*fruparenth = fruh;
return (err);
}
/*
* get label
*
* To get the label, use the following algorithm:
* Lookup "Label" property in the fru node itself. If no
* Label found, then traverse superiors (parent nodes) until
* a Label property is found.
* if not found, then no label
*/
static int
{
int err;
while (err == PICL_PROPNOTFOUND) {
if (err != PICL_SUCCESS)
return (err);
label);
}
return (err);
}
/*
* get combined label
*
* like picldiag_get_label, except concatenates the labels of parent locations
*
* if caller specifies non-zero label length, label will be cut to specified
* length.
* negative length is left justified, non-negative length is right justified
*/
static int
{
int err;
char *ptr;
char *ptr2;
int len;
return (err);
for (;;) {
if (err == PICL_PROPNOTFOUND)
break;
if (err != PICL_SUCCESS)
return (err);
if (err == PICL_SUCCESS) {
} else {
return (PICL_FAILURE);
}
} else if (err != PICL_PROPNOTFOUND) {
return (err);
}
}
return (PICL_PROPNOTFOUND);
/* if no string truncation is desired or required */
return (PICL_SUCCESS);
}
/* string truncation is required; alloc space for (lablen + \0) */
if (ptr == 0)
return (PICL_FAILURE);
if (lablen > 0) {
/* right justification; label = "+<string>\0" */
} else {
/* left justification; label = "<string>+\0" */
}
return (PICL_SUCCESS);
}
/*
* return the first compatible value
*/
static int
{
int err;
char *pval;
if (err != PICL_SUCCESS)
return (err);
return (PICL_FAILURE);
if (err != PICL_SUCCESS) {
return (err);
}
return (PICL_SUCCESS);
}
return (PICL_FAILURE);
/* get first string from table */
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
return (PICL_FAILURE);
if (err != PICL_SUCCESS) {
return (err);
}
return (PICL_SUCCESS);
}
/*
* print the header in the center
*/
static void
{
size_t i;
log_printf("\n");
for (i = 0; i < start_pos; i++)
for (i = 0; i < start_pos; i++)
log_printf("\n");
}
/*
* print the size
*/
static void
{
if (residue == 0)
else
if (residue == 0)
else
} else {
if (residue == 0)
else
}
}
/*
* display platform banner
*/
static int
{
char *platform;
char *banner_name;
int err;
/*
* get PICL_PROP_MACHINE and PICL_PROP_BANNER_NAME
*/
&platform);
if (err != PICL_SUCCESS)
return (err);
&banner_name);
if (err != PICL_SUCCESS)
return (err);
log_printf("\n");
return (PICL_SUCCESS);
}
/*
* display the clock frequency
*/
static int
{
int err;
if (err != PICL_SUCCESS)
return (err);
return (PICL_SUCCESS);
}
/*
* callback function to display the memory size
*/
/*ARGSUSED*/
static int
{
int err;
if (err == PICL_SUCCESS)
log_printf("\n");
no_xfer_size = 0;
&err);
if (err == PICL_PROPNOTFOUND)
no_xfer_size = 1;
return (PICL_WALK_TERMINATE);
}
/*
* callback function to print cpu information
*/
/*ARGSUSED*/
static int
{
int err;
char *impl_name;
char *status;
char *label;
int is_cmp = 0;
int is_cheetah = 0;
/*
* first check the implementation. If it's a CMP
* we need to combine info from both cores.
*/
if (err == PICL_SUCCESS) {
if (CPU_IMPL_IS_CMP(uintval)) {
is_cmp = 1;
&impl_name);
if (err != PICL_SUCCESS)
is_cheetah = 1;
&impl_name);
if (err != PICL_SUCCESS)
}
} else {
if (err != PICL_SUCCESS)
}
/*
* In the CMP case, combine info from both cores. If we
* are being called with the first core handle, we display
* info on the sibling core handle too. If we are being
* called with the second core hanlde as an argument, simply
* return.
*/
if (is_cmp) {
&peerh, sizeof (picl_nodehdl_t));
if (err != PICL_SUCCESS)
return (PICL_WALK_CONTINUE);
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_CONTINUE);
else if (err != PICL_SUCCESS)
return (err);
}
/*
* If no ID is found, return
*/
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_CONTINUE);
else if (err != PICL_SUCCESS)
return (err);
if (is_cmp) {
} else {
}
/*
* If no freq is found, return
*/
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_CONTINUE);
else if (err != PICL_SUCCESS)
return (err);
/* Ecache size */
if (is_cmp) {
if (err == PICL_SUCCESS) {
/*
* Panther L3 is logically shared, so the total E$
* size is equal to the core size.
*/
} else {
if (err == PICL_SUCCESS) {
/*
* Jaguar has a split E$, so the total size
* is the sum of both cores.
*/
} else
log_printf(" - ");
}
} else {
if (err == PICL_SUCCESS)
else
log_printf(" - ");
}
/* Implementation */
else
log_printf(" <unknown> ");
/* CPU Mask */
if (err == PICL_PROPNOTFOUND)
log_printf(" - ");
else if (err == PICL_SUCCESS) {
if (is_cheetah) {
} else {
}
decoded_mask & 0xf);
} else
return (err);
/*
* Status - if the node has a status property then display that
* otherwise display the State property
*/
if (err == PICL_SUCCESS) {
return (err);
} else {
if (err == PICL_SUCCESS) {
PICL_PROPVALUNAVAILABLE && err !=
return (err);
} else {
log_printf("unknown ");
}
}
/*
* Location: use label of fru parent
*/
if (err == PICL_PROPNOTFOUND) {
log_printf(" - ");
} else if (err == PICL_SUCCESS) {
if (err == PICL_PROPNOTFOUND)
log_printf(" - ");
else if (err == PICL_SUCCESS) {
} else
return (err);
} else
return (err);
log_printf("\n");
return (PICL_WALK_CONTINUE);
}
/*
* display cpu information
*/
static int
{
int err;
/*
* Display the table header for CPUs . Then display the CPU
* frequency, cache size, and processor revision on all the boards.
*/
log_printf(" E$ CPU "
"CPU\n");
log_printf("CPU Freq Size Implementation "
"Mask Status Location\n");
log_printf("------- -------- ---------- ------------------- "
"----- ------ --------\n");
return (err);
}
/*
* Inserts an io_card structure into the list.
*/
static void
{
switch (bus_id) {
case SBUS_TYPE:
break;
case PCI_TYPE:
break;
case UPA_TYPE:
break;
default: /* won't reach here */
break;
}
else {
}
if (devfs_path != NULL)
}
static void
{
return;
}
}
static void
free_bank_list(void)
{
}
}
/*
* print label for memory module
*/
static int
{
int err;
char *label;
if (err == PICL_PROPNOTFOUND) {
log_printf("-");
return (PICL_SUCCESS);
} else if (err != PICL_SUCCESS)
return (err);
if (err == PICL_PROPNOTFOUND)
log_printf("-");
else if (err == PICL_SUCCESS) {
} else
return (err);
return (PICL_SUCCESS);
}
/*
* print the bank id and add the bank handle in the bank list
* return the head of the bank list
*/
static int
{
int err;
int i;
/*
* print the bank id in the segment table contains column
*/
if (segp->bank_count > 0)
log_printf(",");
if (err == PICL_PROPNOTFOUND)
log_printf("-");
else if (err == PICL_SUCCESS)
else
return (err);
segp->bank_count++;
/*
* Save the bank information for later (print_bank_table)
*/
return (PICL_FAILURE);
newptr->iway_count = 0;
/*
* Compute the way numbers for the bank
*/
if (no_xfer_size)
return (PICL_WALK_CONTINUE);
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_CONTINUE);
else if (err != PICL_SUCCESS)
return (err);
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_CONTINUE);
else if (err != PICL_SUCCESS)
return (err);
i = 0;
++i;
}
return (PICL_WALK_CONTINUE);
}
/*
* find the memory bank and add the bank handle in the bank list
* return the head of the bank list
*/
static int
{
int err;
log_printf("BankIDs ");
/*
* find memory-bank
*/
segp->bank_count = 0;
log_printf("\n");
return (err);
}
/*
* print the label of memory module or the memory module bank ids
*/
static int
{
int err;
/*
* find memory-module if referenced directly from the memory-segment
* (ie no memory banks)
*/
return (err);
if (err == PICL_SUCCESS) {
log_printf("\n");
return (err);
}
/*
* memory-module not referenced directly from the memory segment
* so list memory banks instead
*/
return (err);
}
/*
* find all memory modules under the given memory module group
* and print its label
*/
static int
{
int err;
char *status;
if (err == PICL_PROPNOTFOUND)
id = -1;
else if (err != PICL_SUCCESS)
return (err);
sizeof (picl_nodehdl_t));
while (err == PICL_SUCCESS) {
/* controller id */
/* group id */
if (id == -1) {
log_printf("- ");
} else {
}
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
}
if (err == PICL_SUCCESS) {
if (err == PICL_SUCCESS) {
} else if (err != PICL_PROPNOTFOUND)
return (err);
} else if (err != PICL_PROPNOTFOUND)
return (err);
&moduleh, sizeof (picl_nodehdl_t));
log_printf("\n");
}
if (err == PICL_PROPNOTFOUND)
return (PICL_SUCCESS);
return (err);
}
/*
* search children to find memory module group under memory-controller
*/
static int
{
int err;
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
&memgrph, sizeof (picl_nodehdl_t));
while (err == PICL_SUCCESS) {
if (err != PICL_SUCCESS)
return (err);
if (*print_header == 1) {
"\nMemory Module Groups:\n"));
log_printf("--------------------------");
log_printf("------------------------\n");
log_printf("ControllerID GroupID Labels");
log_printf(" Status\n");
log_printf("--------------------------");
log_printf("------------------------\n");
*print_header = 0;
}
if (err != PICL_SUCCESS)
return (err);
}
&memgrph, sizeof (picl_nodehdl_t));
}
if (err == PICL_PROPNOTFOUND)
return (PICL_SUCCESS);
return (err);
}
/*
* print memory module group table per memory-controller
*/
static int
{
int err;
int print_header;
print_header = 1;
/*
* find memory-controller
*/
sizeof (picl_nodehdl_t));
while (err == PICL_SUCCESS) {
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
&mch, sizeof (picl_nodehdl_t));
continue;
}
if (err != PICL_SUCCESS)
return (err);
&mch, sizeof (picl_nodehdl_t));
}
if (err == PICL_PROPNOTFOUND)
return (PICL_SUCCESS);
return (err);
}
/*
* print bank table
*/
static int
print_bank_table(void)
{
int err;
int32_t i;
int id;
log_printf("---------------------------------------");
log_printf("--------------------\n");
log_printf("---------------------------------------");
log_printf("--------------------\n");
if (err != PICL_SUCCESS)
else
/* find memory-module-group */
sizeof (memgrph));
if (err == PICL_PROPNOTFOUND) {
} else if (err != PICL_SUCCESS)
return (err);
else {
/*
* get controller id
*/
if (err != PICL_SUCCESS)
return (err);
&err);
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
/* get group id */
&err);
if (err == PICL_PROPNOTFOUND)
log_printf("- ");
else if (err == PICL_SUCCESS)
else
return (err);
}
if (err == PICL_PROPNOTFOUND)
log_printf("- ");
else if (err == PICL_SUCCESS)
else
return (err);
log_printf(" ");
for (i = 0; i < ptr->iway_count; i++) {
if (i != 0)
log_printf(",");
}
log_printf("\n");
}
return (PICL_SUCCESS);
}
/*
* callback function to print segment, add the bank in the list and
* return the bank list
*/
/* ARGSUSED */
static int
{
int err;
/* get base address */
&err);
if (err == PICL_PROPNOTFOUND) {
log_printf("-\n");
return (PICL_WALK_CONTINUE);
} else if (err == PICL_SUCCESS)
else
return (err);
/* get size */
if (err == PICL_PROPNOTFOUND) {
log_printf("-\n");
return (PICL_WALK_CONTINUE);
} else if (err == PICL_SUCCESS)
else
return (err);
/* get interleave factor */
if (err == PICL_PROPNOTFOUND) {
log_printf(" -\n");
return (PICL_WALK_CONTINUE);
} else if (err == PICL_SUCCESS)
else
return (err);
seginfo.bank_count = 0;
if (err != PICL_SUCCESS)
return (err);
return (PICL_WALK_CONTINUE);
}
/*
* search children to find memory-segment and set up the bank list
*/
static int
{
int err;
log_printf("------------------------------");
log_printf("-----------------------------------------\n");
log_printf("------------------------------");
log_printf("-----------------------------------------\n");
return (err);
}
/*
* display memory configuration
*/
static int
{
int err;
return (print_memory_module_group_table(plafh));
}
/*
* print the hub device
*/
static int
{
char *name;
int portnum;
int err;
if (err != PICL_SUCCESS)
return (err);
if (err == PICL_PROPNOTFOUND)
log_printf("-\n");
else if (err == PICL_SUCCESS)
else
return (err);
return (PICL_SUCCESS);
}
/*
* callback functions to display hub devices
*/
/* ARGSUSED */
static int
{
char *rootname;
int hubnum;
int err;
sizeof (picl_nodehdl_t));
/* print header */
if (err == PICL_SUCCESS) {
&rootname);
if (err != PICL_SUCCESS)
return (err);
log_printf("\n===============================");
" %s Devices "), rootname);
} else {
/* Get its hub number */
if ((err != PICL_SUCCESS) &&
(err != PICL_PROPNOTFOUND)) {
return (err);
}
log_printf("\n===============================");
if (err == PICL_SUCCESS)
" %s#%d Devices "),
else
" %s Devices "), rootname);
}
log_printf("===============================\n\n");
log_printf("Name Port#\n");
log_printf("------------ -----\n");
do {
&chdh, sizeof (picl_nodehdl_t));
} while (err == PICL_SUCCESS);
}
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_CONTINUE);
return (err);
}
/*
* callback functions to display usb devices
*/
/* ARGSUSED */
static int
{
int err;
int type;
if (err != PICL_WALK_CONTINUE)
return (err);
if (err == PICL_SUCCESS)
return (err);
}
/*
* find usb devices and print its information
*/
static int
{
int err;
/*
* get the usb node
*/
return (err);
}
/*
* If nodeh is the io device, add it into the io list and return
* If it is not an io device and it has the subtree, traverse the subtree
* and add all leaf io devices
*/
static int
{
int err;
char *nameval;
char *devfs_path;
char *compatible;
char *label;
&proph);
if (err != PICL_SUCCESS)
return (err);
return (PICL_FAILURE);
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
/* if binding_name is found, name will be <nodename>-<binding_name> */
binding_name, sizeof (binding_name));
if (err == PICL_PROPNOTFOUND) {
/*
* if compatible prop is found, name will be
* <nodename>-<compatible>
*/
if (err == PICL_SUCCESS) {
} else if (err != PICL_PROPNOTFOUND) {
return (err);
}
} else if (err != PICL_SUCCESS) {
return (err);
/*
* nodename same as binding name -
* no need to display twice
*/
} else {
}
}
/*
* a bus node, add it to the io list.
* If it is a child under sub-bus and it is in an io
* device, add it to the io list.
*/
if (parentname == NULL)
else
nodename);
/*
* append the class if its class is not a generic
* obp-device class
*/
if (err == PICL_PROPNOTFOUND) {
} else if (err != PICL_SUCCESS) {
return (err);
} else {
15);
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
}
/* devfs-path */
&devfs_path);
if (err == PICL_PROPNOTFOUND)
devfs_path = NULL;
else if (err != PICL_SUCCESS)
return (err);
if (devfs_path != NULL)
return (PICL_SUCCESS);
}
/*
* If there is any child, Go through each child.
*/
&childh, sizeof (picl_nodehdl_t));
/* there is a child */
while (err == PICL_SUCCESS) {
if (parentname == NULL)
else
nodename);
if (err != PICL_SUCCESS)
return (err);
/*
* get next child
*/
&childh, sizeof (picl_nodehdl_t));
}
if (err == PICL_PROPNOTFOUND)
return (PICL_SUCCESS);
return (err);
}
/*
* callback function to add all io devices under sbus in io list
*/
/*ARGSUSED*/
static int
{
int err;
char *model;
char *status;
/* Fill in common infomation */
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_CONTINUE);
else if (err != PICL_SUCCESS)
return (err);
/*
* If no board# is found, set boardnum to 0
*/
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
sizeof (picl_nodehdl_t));
while (err == PICL_SUCCESS) {
PICL_PROP_SLOT, &err);
if (err == PICL_PROPNOTFOUND) {
&nodeh, sizeof (picl_nodehdl_t));
continue;
} else if (err != PICL_SUCCESS)
return (err);
&model);
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
&status);
if (err == PICL_PROPNOTFOUND) {
} else if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
sizeof (picl_nodehdl_t));
}
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_CONTINUE);
return (err);
}
/*
* add all io devices under pci in io list
*/
/* ARGSUSED */
static int
{
int err;
char *model;
char *status;
/* Fill in common infomation */
/*
* Check if it has the freq, if not,
* If not, use its parent's freq
* if its parent's freq is not found, return
*/
if (err == PICL_PROPNOTFOUND) {
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_CONTINUE);
else if (err != PICL_SUCCESS)
return (err);
} else if (err != PICL_SUCCESS)
return (err);
/*
* If no board# is found, set boardnum to 0
*/
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
/* Walk through the children */
sizeof (picl_nodehdl_t));
while (err == PICL_SUCCESS) {
if (err != PICL_SUCCESS)
return (err);
/*
* Skip PCI bridge and USB devices because they will be
* processed later
*/
&nodeh, sizeof (picl_nodehdl_t));
continue;
}
/* Get the device id for pci card */
if (err == PICL_PROPNOTFOUND) {
&nodeh, sizeof (picl_nodehdl_t));
continue;
} else if (err != PICL_SUCCESS)
return (err);
/* Get the model of this card */
&model);
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
&status);
if (err == PICL_PROPNOTFOUND) {
} else if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
sizeof (picl_nodehdl_t));
}
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_CONTINUE);
return (err);
}
/*
* add io devices in io list
* Its slot number is drived from upa-portid
*/
static int
{
int err;
char *devfs_path;
char *nameval;
char *model;
char *status;
char *label;
/*
* If clock frequency can't be found from its parent, don't add
*/
if (err == PICL_PROPNOTFOUND)
return (PICL_SUCCESS);
else if (err != PICL_SUCCESS)
return (err);
/*
* If no board# is found, set boardnum to 0
*/
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
/*
* get upa portid as slot number
* If upa portid is not found, don't add the card.
*/
&err);
if (err == PICL_PROPNOTFOUND)
return (PICL_SUCCESS);
else if (err != PICL_SUCCESS)
return (err);
/* Get the model of this card */
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
/*
* check if it is a ffb device
* If it's a ffb device, append its board type to name
* otherwise, use its nodename
*/
if (err == PICL_PROPNOTFOUND) {
if (err != PICL_SUCCESS)
return (err);
return (PICL_FAILURE);
if (err != PICL_SUCCESS)
return (err);
} else if (err == PICL_SUCCESS) {
/* Find out if it's single or double buffered */
if (err == PICL_PROPNOTFOUND)
if (err == PICL_SUCCESS) {
if (board_type & FFB_B_BUFF)
sizeof (name));
else
sizeof (name));
} else
return (err);
} else
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err == PICL_PROPNOTFOUND) {
} else if (err != PICL_SUCCESS)
return (err);
if (err == PICL_PROPNOTFOUND) {
} else if (err != PICL_SUCCESS) {
return (err);
} else {
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
}
/* devfs-path */
&devfs_path);
if (err == PICL_PROPNOTFOUND)
devfs_path = NULL;
else if (err != PICL_SUCCESS)
return (err);
if (devfs_path != NULL)
return (PICL_SUCCESS);
}
/*
* loop through all children and add io devices in io list
*/
static int
{
int err;
sizeof (picl_nodehdl_t));
while (err == PICL_SUCCESS) {
if (err != PICL_SUCCESS)
return (err);
if (is_io_device(classval))
if (err != PICL_SUCCESS)
return (err);
sizeof (picl_nodehdl_t));
}
if (err == PICL_PROPNOTFOUND)
return (PICL_SUCCESS);
return (err);
}
/*
* callback function to add all io devices under upa in io list
*/
/*ARGSUSED*/
static int
{
int err;
if (err == PICL_SUCCESS)
return (PICL_WALK_CONTINUE);
return (err);
}
/*
* display ffb hardware configuration
*/
/* ARGSUSED */
static int
{
int err;
char *dac_ver;
char *fbram_ver;
/*
* If it has PICL_PROP_FFB_BOARD_REV, it is a ffb device
* Otherwise, return.
*/
&err);
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_CONTINUE);
else if (err != PICL_SUCCESS)
return (err);
log_printf("FFB Hardware Configuration:\n");
log_printf("-----------------------------------\n");
&err);
if (err == PICL_SUCCESS)
else if (err != PICL_PROPNOTFOUND)
return (err);
&dac_ver);
if (err == PICL_SUCCESS) {
} else if (err != PICL_PROPNOTFOUND)
return (err);
&fbram_ver);
if (err == PICL_SUCCESS) {
} else if (err != PICL_PROPNOTFOUND)
return (err);
log_printf("\n");
return (PICL_WALK_CONTINUE);
}
/*
* find all io devices and add them in the io list
*/
static int
{
int err;
/*
* look for io devices under the immediate children of platform
*/
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
return (err);
}
static void
{
struct io_card *p;
return;
if (banner == 0) {
log_printf("Bus Freq Slot + Name +\n", 0);
log_printf("Type MHz Status "
"Path "
"Model", 0);
log_printf("\n", 0);
log_printf("---- ---- ---------- "
"---------------------------- "
"--------------------", 0);
log_printf("\n", 0);
banner = 1;
}
/*
* We check to see if it's an int or
* a char string to display for slot.
*/
if (p->slot == PCI_SLOT_IS_STRING)
else
log_printf("+ ", 0);
else
log_printf(" ", 0);
log_printf("+", 0);
log_printf("\n", 0);
set_exit_code(p->status);
log_printf("\n\n", 0);
}
}
/*
* display all io devices
*/
static int
{
int err;
if (err != PICL_SUCCESS)
return (err);
return (PICL_SUCCESS);
}
/*
* print fan device information
*/
static int
{
int err;
char *label;
char *unit;
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err == PICL_SUCCESS) {
log_printf(" - ");
} else
return (err);
if (err == PICL_SUCCESS) {
if (err != PICL_SUCCESS)
min_speed = 1;
if (err == PICL_SUCCESS) {
}
log_printf(")");
} else {
log_printf("okay");
}
} else {
if (err == PICL_SUCCESS) {
}
}
log_printf("\n");
return (PICL_SUCCESS);
}
static int
{
int err;
if (*countp == 0) {
log_printf("---------------------------------------\n");
log_printf("Location Sensor Status \n");
log_printf("---------------------------------------\n");
}
*countp += 1;
if (err == PICL_SUCCESS)
return (PICL_WALK_CONTINUE);
return (err);
}
/*
* callback function search children to find fan device and print its speed
*/
static int
{
int err;
int print_header;
print_header = 0;
return (err);
}
/*
* print temperature sensor information
*/
static int
{
int err;
char *label;
int got_temp = 0;
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
&err);
if (err == PICL_SUCCESS) {
got_temp = 1;
status = "okay";
return (err);
}
&err);
if (err == PICL_SUCCESS) {
status = "warning";
return (err);
}
&err);
if (err == PICL_SUCCESS) {
status = "failed";
return (err);
}
&err);
if (err == PICL_SUCCESS) {
status = "warning";
return (err);
}
&err);
if (err == PICL_SUCCESS) {
status = "failed";
return (err);
}
if (err == PICL_SUCCESS) {
return (err);
} else {
}
log_printf("\n");
return (PICL_SUCCESS);
}
static int
{
int err;
if (*countp == 0) {
log_printf("\n");
log_printf("---------------------------------------\n");
log_printf("------------------------------------\n");
log_printf("Location Sensor Status\n");
log_printf("------------------------------------\n");
}
*countp += 1;
if (err == PICL_SUCCESS)
return (PICL_WALK_CONTINUE);
return (err);
}
/*
* callback function search children to find temp sensors and print the temp
*/
/* ARGSUSED */
static int
{
int err;
int print_header;
print_header = 0;
if (err != PICL_SUCCESS)
return (err);
return (err);
}
/*
* print current sensor information
*/
static int
{
int err;
char *label;
float current;
float threshold;
int got_current = 0;
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err == PICL_SUCCESS) {
status = "okay";
got_current = 1;
return (err);
}
&err);
if (err == PICL_SUCCESS) {
status = "warning";
return (err);
}
&err);
if (err == PICL_SUCCESS) {
status = "failed";
return (err);
}
&err);
if (err == PICL_SUCCESS) {
status = "warning";
return (err);
}
if (err == PICL_SUCCESS) {
status = "failed";
return (err);
}
if (err == PICL_SUCCESS) {
return (err);
} else {
}
log_printf("\n");
return (PICL_SUCCESS);
}
static int
{
int err;
if (*countp == 0) {
log_printf("------------------------------------\n");
log_printf("------------------------------\n");
log_printf("Location Sensor Status\n");
log_printf("------------------------------\n");
}
*countp += 1;
if (err == PICL_SUCCESS)
return (PICL_WALK_CONTINUE);
return (err);
}
/*
* callback function search children to find curr sensors and print the curr
*/
/* ARGSUSED */
static int
{
int err;
int print_header;
print_header = 0;
if (err != PICL_SUCCESS)
return (err);
return (err);
}
/*
* print voltage sensor information
*/
static int
{
int err;
char *label;
float voltage;
float threshold;
int got_voltage = 0;
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err == PICL_SUCCESS) {
status = "okay";
got_voltage = 1;
return (err);
}
&err);
if (err == PICL_SUCCESS) {
status = "warning";
return (err);
}
&err);
if (err == PICL_SUCCESS) {
status = "failed";
return (err);
}
&err);
if (err == PICL_SUCCESS) {
status = "warning";
return (err);
}
if (err == PICL_SUCCESS) {
status = "failed";
return (err);
}
if (err == PICL_SUCCESS) {
return (err);
} else {
}
log_printf("\n");
return (PICL_SUCCESS);
}
static int
{
int err;
if (*countp == 0) {
log_printf("--------------------------------\n");
log_printf("-------------------------------\n");
log_printf("Location Sensor Status\n");
log_printf("-------------------------------\n");
}
*countp += 1;
if (err == PICL_SUCCESS)
return (PICL_WALK_CONTINUE);
return (err);
}
/*
* callback function search children to find voltage sensors and print voltage
*/
/* ARGSUSED */
static int
{
int err;
int print_header;
print_header = 0;
if (err != PICL_SUCCESS)
return (err);
return (err);
}
/*
* print led device information
*/
static int
{
int err;
char *label;
char *state;
char *color;
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS) {
} else {
}
if (err != PICL_SUCCESS)
return (err);
log_printf(" - ");
} else if (err != PICL_SUCCESS) {
return (err);
} else {
}
log_printf("\n");
} else if (err != PICL_SUCCESS) {
return (err);
} else {
}
return (PICL_SUCCESS);
}
static int
{
int err;
if (*countp == 0) {
log_printf("--------------------------------------"
"------------\n");
log_printf("--------------------------------------"
"------------\n");
log_printf("Location Led State"
" Color\n");
log_printf("--------------------------------------"
"------------\n");
}
*countp += 1;
if (err == PICL_SUCCESS)
return (PICL_WALK_CONTINUE);
return (err);
}
/*
* callback function search children to find led devices and print status
*/
/* ARGSUSED */
static int
{
int print_header;
print_header = 0;
return (PICL_SUCCESS);
}
/*
* print keyswitch device information
*/
static int
{
int err;
char *label;
char *state;
if (err != PICL_SUCCESS) {
} else {
}
if (err != PICL_SUCCESS)
return (err);
log_printf(" -\n");
} else if (err != PICL_SUCCESS) {
return (err);
} else {
}
return (PICL_SUCCESS);
}
static int
{
int err;
/*
* Tamale simulates a key-switch on ENxS. So the presence of a
* node of class keyswitch is not sufficient. If it has a fru parent
* or location parent, then believe it.
*/
if (err == PICL_PROPNOTFOUND) {
}
return (PICL_WALK_CONTINUE);
if (err != PICL_SUCCESS)
return (err);
if (*countp == 0) {
log_printf("-----------------------------------------\n");
log_printf("-----------------------------------------\n");
"Location Keyswitch State\n"));
log_printf("-----------------------------------------\n");
}
*countp += 1;
if (err == PICL_SUCCESS)
return (PICL_WALK_CONTINUE);
return (err);
}
/*
* search children to find keyswitch device(s) and print status
*/
/* ARGSUSED */
static int
{
int print_header = 0;
return (PICL_SUCCESS);
}
/*
* display environment status
*/
static int
{
return (PICL_SUCCESS);
}
/*
* print fru operational status
*/
static int
{
int err;
char *label;
char *status;
if (err != PICL_SUCCESS)
return (PICL_WALK_CONTINUE);
if (err == PICL_SUCCESS) {
if (*countp == 0) {
"FRU Operational Status"),
log_printf("-------------------------\n");
"Fru Operational Status:\n"));
log_printf("-------------------------\n");
log_printf("Location Status \n");
log_printf("-------------------------\n");
}
*countp += 1;
return (err);
} else {
}
return (PICL_WALK_CONTINUE);
}
static int
{
int err;
return (err);
}
/*
* display fru operational status
*/
static int
{
int print_header;
print_header = 0;
return (PICL_SUCCESS);
}
/*
* check if the node having the version prop
* If yes, print its nodename and version
*/
/* ARGSUSED */
static int
{
char *name;
char *model;
char *status;
int err;
&err);
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_CONTINUE);
else if (err != PICL_SUCCESS)
return (err);
/* devfs-path */
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
/* model */
&model);
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
/* status */
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
/*
* Display the data
*/
/* name */
} else
/* model */
} else
/* status */
else {
}
/* revision */
return (PICL_WALK_CONTINUE);
}
/*
* traverse the tree to display asic revision id for ebus
*/
/* ARGSUSED */
static int
{
char *name;
int err;
char *model;
char *status;
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_CONTINUE);
else if (err != PICL_SUCCESS)
return (err);
/* devfs-path */
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
/* model */
&model);
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
/* status */
if (err == PICL_PROPNOTFOUND)
else if (err != PICL_SUCCESS)
return (err);
/*
* Display the data
*/
/* name */
} else
/* model */
} else
/* status */
else {
}
/* revision */
return (PICL_WALK_CONTINUE);
}
/*
* display asic revision id
*/
static int
{
int err;
/* Print the header */
log_printf("ASIC Revisions:\n");
log_printf("-----------------------------");
log_printf("--------------------------------------\n");
log_printf("Path Device");
log_printf(" Status Revision\n");
log_printf("-----------------------------");
log_printf("--------------------------------------\n");
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
log_printf("\n");
return (err);
}
/*
* find the options node and its powerfail_time prop
* If found, display the list of latest powerfail.
*/
/* ARGSUSED */
static int
{
char *failtime;
int err;
&failtime);
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_TERMINATE);
else if (err != PICL_SUCCESS)
return (err);
if (value == 0)
return (PICL_WALK_TERMINATE);
log_printf("=============================\n");
log_printf("\n");
return (PICL_WALK_TERMINATE);
}
/*
* display the OBP and POST prom revisions
*/
/* ARGSUSED */
static int
{
int err;
if (err == PICL_PROPNOTFOUND)
return (PICL_WALK_TERMINATE);
else if (err != PICL_SUCCESS)
return (err);
log_printf("----------------------\n");
/*
* If it's a table prop, the first element is OBP revision
* The second one is POST revision.
* If it's a charstring prop, the value will be only OBP revision
*/
if (prom_version == NULL)
return (PICL_FAILURE);
if (err != PICL_SUCCESS)
return (err);
}
return (PICL_WALK_TERMINATE);
if (err != PICL_SUCCESS)
return (err);
if (err == PICL_SUCCESS) {
/* get first row */
if (err != PICL_SUCCESS)
return (err);
if (prom_version == NULL)
return (PICL_FAILURE);
if (err != PICL_SUCCESS)
return (err);
/* get second row */
if (err == PICL_SUCCESS) {
if (err != PICL_SUCCESS)
return (err);
if (obp_version == NULL)
return (PICL_FAILURE);
if (err != PICL_SUCCESS)
return (err);
}
}
return (PICL_WALK_TERMINATE);
}
static int
{
int err;
if (err != PICL_SUCCESS)
return (err);
if (!log_flag) {
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
}
if (serrlog) {
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
&frutreeh);
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
if (err != PICL_SUCCESS)
return (err);
}
return (PICL_SUCCESS);
}
/*
* do_prominfo is called from main in prtdiag. It returns PD_SYSTEM_FAILURE if
* any system failure is detected, PD_INTERNAL_FAILURE for internal errors and
* PD_SUCCESS otherwise. main uses the return value as the exit code.
*/
/* ARGSUSED */
int
{
int err;
char *errstr;
int done;
err = picl_initialize();
if (err != PICL_SUCCESS) {
return (PD_INTERNAL_FAILURE);
}
do {
done = 1;
if (err != PICL_SUCCESS) {
return (PD_INTERNAL_FAILURE);
}
done = 0;
} while (!done);
if (err != PICL_SUCCESS) {
}
(void) picl_shutdown();
return (exit_code);
}