/*
* 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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <sys/openpromio.h>
#include <libintl.h>
#include "pdevinfo.h"
#include "display.h"
#include "pdevinfo_sun4u.h"
/*
* For machines that support the openprom, fetch and print the list
* of devices that the kernel has fetched from the prom or conjured up.
*
*/
static int prom_fd;
extern char *progname;
extern char *promdev;
extern void getppdata();
extern void printppdata();
/*
* Define DPRINT for run-time debugging printf's...
* #define DPRINT 1
*/
#ifdef DPRINT
#endif /* DPRINT */
#if !defined(TEXT_DOMAIN)
#endif
/*VARARGS1*/
int
{
int saved_errno;
extern int errno;
saved_errno = errno;
if (progname)
errno = saved_errno;
perror("");
return (2);
}
int
is_openprom(void)
{
register unsigned int i;
i = (unsigned int)((unsigned char)opp->oprom_array[0]);
return ((i & OPROMCONS_OPENPROM) == OPROMCONS_OPENPROM);
}
/*
* Read all properties and values from nodes.
* Copy the properties read into the prom_node passsed in.
*/
void
{
/* clear out pointers in pnode */
/* get first prop by asking for null string */
/* allocate space for the property */
perror("malloc");
exit(1);
}
while (opp->oprom_size != 0) {
int i;
/*
* get property
*/
if (opp->oprom_size != 0) {
opp->oprom_array);
/* Now copy over temp's data to new. */
perror("malloc");
exit(1);
}
/*
* First copy over temp->name's data. The
* temp->name.opp.opio_u union always contains char[]
* (as opposed to an int or int []).
*/
perror("malloc");
exit(1);
}
/*
* Then copy over temp->value's data.
* temp->value.opp.opio_u could contain char[], int or
* int []. If *(temp->value.opp.oprom_array) is '\0',
* this indicates int or int []. int is the norm, but
* to be safe we assume int [] and copy over
* OPROM_NODE_SIZE int elements.
*/
for (i = 0; i < OPROM_NODE_SIZE; i++)
} else {
== NULL) {
perror("malloc");
exit(1);
}
/*
* temp->value.opp.oprom_array can contain one
* or more embedded NULLs. These trip-up the
* standard string copying functions, so we do
* the copy by hand. temp->value.opp.oprom_array
* will be NULL-terminated. oprom_size includes
* this terminating NULL.
*/
}
/* everything worked so link the property list */
}
}
}
int
{
/*CONSTCOND*/
while (1) {
(void) sleep(5);
continue;
}
return (-1);
promdev));
} else
return (0);
}
/*NOTREACHED*/
}
void
promclose(void)
{
promdev));
}
/*
* Read the value of the property from the PROM device tree
*/
void
{
}
int
{
/* LINTED */
return (_error("OPROMNEXT"));
/* LINTED */
return (*(int *)opp->oprom_array);
}
int
{
/* LINTED */
return (_error("OPROMCHILD"));
/* LINTED */
return (*(int *)opp->oprom_array);
}
/*
* Check if the Prom node passed in contains a property called
* "board#".
*/
int
{
/*
* walk thru all properties in this PROM node and look for
* board# prop
*/
return (1);
}
return (0);
} /* end of has_board_num() */
/*
* Retrieve the value of the board number property from this Prom
* node. It has the type of int.
*/
int
{
/*
* walk thru all properties in this PROM node and look for
* board# prop
*/
}
return (-1);
} /* end of get_board_num() */
/*
* Find the requested board struct in the system device tree.
*/
{
return (bnode);
} /* end of find_board() */
/*
* Add a board to the system list in order. Initialize all pointer
* fields to NULL.
*/
{
perror("malloc");
exit(1);
}
} else {
}
return (bnode);
} /* end of insert_board() */
/*
* This function searches through the properties of the node passed in
* and returns a pointer to the value of the name property.
*/
char *
{
return (NULL);
}
}
return (NULL);
} /* end of get_node_name() */
/*
* This function searches through the properties of the node passed in
* and returns a pointer to the value of the name property.
*/
char *
{
return (NULL);
}
}
return (NULL);
} /* end of get_node_type() */
/*
* Do a depth-first walk of a device tree and
* return the first node with the name matching.
*/
{
return (node);
}
{
return (node);
}
/*
* Search for and return a node of the required type. If no node is found,
* then return NULL.
*/
{
return (node); /* not found */
}
/*
* Start from the current node and return the next node besides the
* current one which has the requested type property.
*/
{
return (node); /* not found */
}
/*
* Search a device tree and return the first failed node that is found.
* (has a 'status' property)
*/
{
return (NULL);
if (node_failed(root)) {
return (root);
}
/* search the child */
return (pnode);
/* search the siblings */
return (pnode);
return (NULL);
} /* end of find_failed_node() */
/*
* Start from the current node and return the next node besides
* the current one which is failed. (has a 'status' property)
*/
{
return (NULL);
/* search the child */
return (pnode);
}
/* search the siblings */
return (pnode);
}
/* backtracking the search up through parents' siblings */
return (pnode);
else
}
return (NULL);
} /* end of find_failed_node() */
/*
* node_failed
*
* This function determines if the current Prom node is failed. This
* is defined by having a status property containing the token 'fail'.
*/
int
{
}
int
{
void *value;
return (0);
/* search the local node */
return (1);
}
return (0);
}
/*
* Get a property's value. Must be void * since the property can
* be any data type. Caller must know the *PROPER* way to use this
* data.
*/
void *
{
return (NULL);
else
} /* end of get_prop_val() */
/*
* Search a Prom node and retrieve the property with the correct
* name.
*/
Prop *
{
return (NULL);
}
"no properties\n"));
return (NULL);
}
return (prop);
}
/*
* This function adds a board node to the board structure where that
* that node's physical component lives.
*/
void
{
int board;
Prom_node *p;
/* add this node to the Board list of the appropriate board */
/* board is 0 if not on Sunfire */
board = 0;
}
/* find the 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;
}
}
/*
* Find the device on the current board with the requested device ID
* and name. If this rountine is passed a NULL pointer, it simply returns
* NULL.
*/
{
int mask;
/* find the first cpu node */
mask = 0x1F;
return (pnode);
}
return (NULL);
}
{
char *type_prop;
return (NULL);
return (root);
}
}
/* look at your children first */
return (node);
/* now look at your siblings */
return (node);
return (NULL); /* not found */
}
{
return (NULL);
/* look at your children first */
return (node);
/* now look at your siblings */
return (node);
/* now look at papa's siblings */
return (node);
return (NULL); /* not found */
}
/*
* Do a depth-first walk of a device tree and
* return the first node with the matching compatible.
*/
{
char *compatible_array;
return (NULL);
/*
* The Prop structure returned by find_prop() is supposed
* to contain an indication of how big the value of the
* compatible property is. Since it is an array of strings
* this is our only means of determining just how many
* strings might be in this property. However, this size
* is often left as zero even though there is at least one
* string present. When this is the case, all we can do
* is examine the first string in the compatible property.
*/
return (root); /* found a match */
}
}
return (node);
/*
* Note the very deliberate use of tail recursion here. A good
* compiler (such as Sun's) will recognize this and generate code
* that does not allocate another stack frame. Instead, it will
* overlay the existing stack frame with the new one, the only change
* having been to replace the original root with its sibling.
* This has the potential to create some confusion for anyone
* trying to debug this code from a core dump, since the stack
* trace will not reveal recursion on siblings, only on children.
*/
}
/*
* Start from the current node and return the next node besides
* the current one which has the requested compatible property.
*/
{
return (NULL);
return (node);
/*
* More tail recursion. Even though it is a different function,
* this will overlay the current stack frame. Caveat exterminator.
*/
return (node);
}