/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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
*/
/*
* Copyright 2000, 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Littleneck Platform specific functions.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <libprtdiag.h>
void print_us3_memory_line(int portid,
int bank_id,
char *bank_status,
int seg_id);
int do_prominfo(int syserrlog,
char *pgname,
int log_flag,
int prt_flag);
struct io_card **pci_card_list,
char **pci_slot_name_arr);
/* This is stuff to get the HW Revisions stuff to work */
/*
* LNECK_PORTID_TO_SAFARI_ID
*
* Calculates the Safari Agent ID from the portid.
*/
/*
* LNECK_PORTID_IS_CPU_TYPE
*
* If the portid associated with a CPU board is passed in, TRUE is returned,
* otherwise FALSE.
*/
/*
* LNECK_PORTID_TO_NODEID
*
* Calculates the SSM NodeID from the portid
*/
/*
* LNECK_CPU_BD_PORTID_TO_BD_NUM
*
* If the portid associated with a CPU board is passed in, the board number
* associated with this portid is returned, otherwise -1.
*/
((LNECK_PORTID_IS_CPU_TYPE(portid)) ? \
/*
* LNECK_PORTID_IS_IO_TYPE
*
* If the portid associated with an IO board is passed in, TRUE is returned,
* otherwise FALSE.
*/
/*
* LNECK_IO_BD_PORTID_TO_BD_NUM
*
* If the portid associated with an IO board is passed in, the board number
* associated with this portid is returned, otherwise -1.
*/
/*
* LNECK_PORTID_TO_BOARD_NUM
*
* If a valid portid is passed in, this macro returns the board number
* associated with it, otherwise it returns -1.
*/
((LNECK_PORTID_IS_CPU_TYPE(portid)) ? \
((LNECK_PORTID_IS_IO_TYPE(portid)) ? \
/*
* Start from the current node and return the next node besides
* the current one which has the requested model property.
*/
static Prom_node *
{
return (NULL);
/* look at your children first */
return (node);
/* now look at your siblings */
return (node);
return (NULL); /* not found */
}
/*
* Do a depth-first walk of a device tree and
* return the first node with the matching model.
*/
static Prom_node *
{
char *compatible;
char *name;
return (NULL);
return (NULL);
name = "";
if (compatible == NULL)
return (NULL);
return (root); /* found a match */
}
/* look at your children first */
return (node);
/* now look at your siblings */
return (node);
return (NULL); /* not found */
}
{
sizeof (picl_nodehdl_t));
switch (err) {
case PICL_SUCCESS:
break;
case PICL_PROPNOTFOUND:
return (err);
default:
#ifdef WORKFILE_DEBUG
"Failed picl_get_propval_by_name with %s\n"),
picl_strerror(err));
#endif
return (err);
}
#ifdef WORKFILE_DEBUG
if (err != PICL_SUCCESS) {
"failed the get name for root\n"));
}
#endif
return (err);
while (err != PICL_PROPNOTFOUND) {
#ifdef WORKFILE_DEBUG
#endif
&(*child), sizeof (picl_nodehdl_t));
switch (err) {
case PICL_SUCCESS:
return (err);
break;
case PICL_PROPNOTFOUND:
break;
default:
#ifdef WORKFILE_DEBUG
"Failed picl_get_propval_by_name with %s\n"),
picl_strerror(err));
#endif
return (err);
}
}
return (err);
}
{
sizeof (picl_prophdl_t));
if (err != PICL_SUCCESS) {
#ifdef WORKFILE_DEBUG
if (err != PICL_INVALIDHANDLE) {
"fill_device_from_id failure in "
"picl_get_propval_by_name err is %s\n"),
picl_strerror(err));
}
#endif
return (err);
}
if (err != PICL_SUCCESS) {
#ifdef WORKFILE_DEBUG
"fill_device_from_id failure in picl_get_next_by_row"
#endif
return (err);
}
/* get node associated with reference property */
sizeof (picl_nodehdl_t));
#ifdef WORKFILE_DEBUG
if (err != 0) {
"fill_device_from_id failure in picl_get_propval"
}
#endif
return (err);
}
{
int i;
int devs = 0;
sizeof (picl_prophdl_t));
#ifdef WORKFILE_DEBUG
"fill_device_array_from_id failure in "
#endif
return (err);
}
++devs;
if (*device_array == NULL) {
#ifdef WORFILE_DEBUG
"fill_device_array_from_id failure getting memory"
" for array\n"));
#endif
return (PICL_FAILURE);
}
for (i = 0; i < devs; i++) {
if (err != 0) {
#ifdef WORKFILE_DEBUG
"fill_device_array_from_id failure in "
"picl_get_next_by_row err is %s\n"),
picl_strerror(err));
#endif
return (err);
}
/* get node associated with reference property */
sizeof (picl_nodehdl_t));
if (err != 0) {
#ifdef WORKFILE_DEBUG
"fill_device_array_from_id failure in "
#endif
return (err);
}
}
return (err);
}
/*
* Add a board to the system list in order (sorted by board#).
* Initialize all pointer fields to NULL.
*/
static Board_node *
{
perror("malloc");
exit(1);
}
} else {
}
return (bnode);
}
/*
* Find the requested board struct in the system device tree.
*
* This function overrides the functionality of the generic find_board()
* function in libprtdiag, but since we need to pass another parameter,
* we cannot simply overlay the symbol table.
*/
static Board_node *
{
}
return (bnode);
}
/*
* add_node
*
* This function adds a board node to the board structure where that
* that node's physical component lives.
*/
void
{
/* Get the board number of this board from the portid prop */
}
/* find the board node with the same board number */
}
/* now attach this prom node to the board list */
/* Insert this node at the end of the list */
else {
p = p->sibling;
}
}
/*
* This function provides formatting of the memory config
* information that get_us3_mem_regs() and display_us3_banks() code has
* gathered. It overrides the generic print_us3_memory_line() code
* which prints an error message.
*/
void
{
int mcid;
"\n C%-1c %2d %2d %4lldMB %11-s %4lldMB "
" %2d-way %d"),
}
/*
* We call do_devinfo() in order to use the libdevinfo device tree
* instead of OBP's device tree.
*/
int
{
}
/*
* return the property value for the Prop
* passed in. (When using libdevinfo)
*/
void *
{
return (NULL);
}
/*
* Search a Prom node and retrieve the property with the correct
* name. (When using libdevinfo)
*/
Prop *
{
return (NULL);
return (NULL);
return (NULL);
return (NULL);
}
return (prop);
}
/*
* This function searches through the properties of the node passed in
* and returns a pointer to the value of the name property.
* (When using libdevinfo)
*/
char *
{
return (NULL);
}
}
return (NULL);
}
/*
* This function searches through the properties of the node passed in
* and returns a pointer to the value of the device_type property.
* (When using libdevinfo)
*/
char *
{
return (NULL);
}
}
return (NULL);
}
/*
* Fills in the i/o card list to be displayed later in display_pci();
*/
void
{
int *int_val;
int portid;
int pci_bus;
char *child_name;
char *name;
char *type;
void *value;
while (pci_card_node != NULL) {
/* If it doesn't have a name, skip it */
name = (char *)get_prop_val(
continue;
}
/*
* Get the portid of the schizo that this card
* lives under.
*/
portid = -1;
}
/*
* Find out whether this is PCI bus A or B
* using the 'reg' property.
*/
int_val++; /* skip over first integer */
if (pci_bus == 0x600000)
else if (pci_bus == 0x700000)
else
} else {
}
/*
* get dev# and func# for this card from the
* 'reg' property.
*/
int_val = (int *)get_prop_val(
} else {
}
/* We only have one slot on bus A */
!pci_bridge) {
continue;
}
continue;
}
type = (char *)get_prop_val(
/*
* If this is a pci-bridge, then store its dev#
* as its children nodes need this to get their slot#.
* We set the pci_bridge flag so that we know we are
* looking at a pci-bridge node. This flag gets reset
* every time we enter this while loop.
*/
/*
* Check for a PCI-PCI Bridge for PCI and cPCI
* IO Boards using the name and type properties.
*/
if (!pci_bridge) {
pci_bridge = TRUE;
}
}
/*
* Get slot-names property from slot_names_arr.
* If we are the child of a pci_bridge we use the
* dev# of the pci_bridge as an index to get
* the slot number. We know that we are a child of
* a pci-bridge if our parent is the same as the last
* pci_bridge node found above.
*/
/*
* We compare this cards parent node with the
* pci_bridge_node to see if it's a child.
*/
pci_bridge) {
/* use dev_no of pci_bridge */
} else {
}
/* Slot num is last char in string */
} else {
"-");
}
} else {
"%c", '-');
}
/*
* Check for failed status.
*/
if (node_failed(pci_card_node))
else
/* Get the model of this pci_card */
else {
(char *)value);
/* Skip sgsbbc nodes, they are not cards */
continue;
}
}
/*
* The card may have a "clock-frequency" but we
* are not interested in that. Instead we get the
* "clock-frequency" of the PCI Bus that the card
* resides on. PCI-A can operate at 33Mhz or 66Mhz
* depending on what card is plugged into the Bus.
* PCI-B always operates at 33Mhz.
*/
"clock-frequency"));
} else {
}
/*
* Figure out how we want to display the name
*/
"compatible"));
/* use 'name'-'compatible' */
(char *)value);
} else {
/* just use 'name' */
}
/*
* If this node has children, add the device_type
* of the child to the name value of this pci_card->
*/
(child_name != NULL)) {
"device_type"));
/* add device_type of child to name */
"%s/%s (%s)",
(char *)value);
} else {
/* just add childs name */
"%s/%s", name,
}
} else {
"%s", (char *)name);
}
/*
* If this is a pci-bridge, then add the word
* 'pci-bridge' to its model. If we can't find
* a model, then we just describe what the device
* is based on some properties.
*/
if (pci_bridge) {
"%s", "device on pci-bridge");
else if (pci_card_node->parent
"%s", "pci-bridge/pci-bridge");
else
"%s", "PCI-BRIDGE");
}
else
}
/* insert this pci_card in the list to be displayed later */
/*
* If we are dealing with a pci-bridge, we need to move
* down to the children of this bridge if there are any.
*
* If we are not, we are either dealing with a regular
* card (in which case we move onto the sibling of this
* card) or we are dealing with a child of a pci-bridge
* (in which case we move onto the child's siblings or
* if there are no more siblings for this child, we
* move onto the parents siblings).
*/
} /* end-while */
}
/*
* Helper function for fill_pci_card_list(). Indicates which
* card node to go to next.
* Parameters:
* -----------
* Prom_node * curr_card: pointer to the current card node
*
* int * is_bridge: indicates whether or not the card (is | is on)
* a pci bridge
*
* int is_pcidev: indicates whether or not the current card
* is a pci bridge
*
* Prom_node * curr_bridge: pointer to the current pci bridge. Eg:
* curr_card->parent.
*
* Prom_node * parent_bridge: pointer to the first pci bridge encountered.
* we could have nested pci bridges, this would
* be the first one.
*
* Prom_node * pci: pointer to the pci instance that we are attached to.
* This would be parent_bridge->parent, or
* curr_node->parent, if curr_node is not on a pci bridge.
*/
static Prom_node *
{
if (*is_bridge) {
/*
* is_pcidev is used to prevent us from following the
* children of something like a scsi device.
*/
} else {
curr_bridge != parent_bridge &&
curr_bridge != NULL) {
break;
}
if (curr_bridge == NULL ||
curr_bridge == parent_bridge ||
curr_node == parent_bridge) {
}
}
}
} else {
}
return (curr_node);
}