/*
* 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
*/
/*
*/
/*
* Interfaces for getting device configuration data from kernel
* through the devinfo driver.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <stropts.h>
#include <fcntl.h>
#include <poll.h>
#include <synch.h>
#include <unistd.h>
#include <sys/autoconf.h>
#include <stdarg.h>
#include <assert.h>
#include "libdevinfo.h"
/*
* Debug message levels
*/
typedef enum {
} di_debug_t;
#pragma init(_libdevinfo_init)
void
{
if (debug_str) {
errno = 0;
}
}
{
}
/*
* We use blocking_open() to guarantee access to the devinfo device, if open()
* is failing with EAGAIN.
*/
static int
{
int fd;
return (fd);
}
/* private interface */
{
int fd;
/*
* Don't allow drv_name to exceed MAXPATHLEN - 1, or 1023,
* which should be sufficient for any sensible programmer.
*/
return (DI_NODE_NIL);
}
/*
* open the devinfo driver
*/
O_RDONLY)) == -1) {
return (DI_NODE_NIL);
}
return (DI_NODE_NIL);
}
/*
* Driver load succeeded, return a snapshot
*/
}
struct di_priv_data *priv)
{
/*
* Make sure there is no minor name in the path
* and the path do not start with /devices....
*/
return (DI_NODE_NIL);
}
else if (*phys_path != '/')
"/%s", phys_path);
else
"%s", phys_path);
/*
* If private data is requested, copy the format specification
*/
if (priv)
sizeof (struct di_priv_data));
else {
return (DI_NODE_NIL);
}
}
/*
* Attempt to open the devinfo driver. Make a second attempt at the
* read-only minor node if we don't have privileges to open the full
* version _and_ if we're not requesting operations that the read-only
* node can't perform. (Setgid processes would fail an access() test,
* of course.)
*/
O_RDONLY)) == -1) {
/*
* We wanted to perform a privileged operation, but the
* privileged node isn't available. Don't modify errno
* on our way out (but display it if we're running with
* di_debug set).
*/
errno));
return (DI_NODE_NIL);
}
O_RDONLY)) == -1) {
errno));
return (DI_NODE_NIL);
}
}
/*
* Verify that there is no major conflict, i.e., we are indeed opening
* the devinfo driver.
*/
"driver ID failed; check for major conflict\n"));
return (DI_NODE_NIL);
}
/*
* create snapshot
*/
"error: %d\n", errno));
return (DI_NODE_NIL);
} else if (map_size == 0) {
return (DI_NODE_NIL);
}
/*
* copy snapshot to userland
*/
return (DI_NODE_NIL);
}
return (DI_NODE_NIL);
}
"(expected=%d, actual=%d)\n",
return (DI_NODE_NIL);
}
return (DI_NODE_NIL);
}
}
void
{
/*
* paranoid checking
*/
if (root == DI_NODE_NIL) {
return;
}
/*
* The root contains its own offset--self.
* Subtracting it from root address, we get the starting addr.
* The map_size is stored at the beginning of snapshot.
* Once we have starting address and size, we can free().
*/
}
{
if (node == DI_NODE_NIL) {
return (DI_NODE_NIL);
}
}
/*
* Deal with error condition:
* If parent doesn't exist and node is not the root,
* set errno to ENOTSUP. Otherwise, set errno to ENXIO.
*/
else
return (DI_NODE_NIL);
}
{
if (node == DI_NODE_NIL) {
return (DI_NODE_NIL);
}
}
/*
* Deal with error condition:
* Sibling doesn't exist, figure out if ioctl command
* has DINFOSUBTREE set. If it doesn't, set errno to
* ENOTSUP.
*/
else
return (DI_NODE_NIL);
}
{
if (node == DI_NODE_NIL) {
return (DI_NODE_NIL);
}
}
/*
* Deal with error condition:
* Child doesn't exist, figure out if DINFOSUBTREE is set.
* If it isn't, set errno to ENOTSUP.
*/
else
return (DI_NODE_NIL);
}
{
if (root == DI_NODE_NIL) {
return (DI_NODE_NIL);
}
/*
* get major number of driver
*/
break;
return (DI_NODE_NIL);
}
return (DI_NODE_NIL);
}
}
{
if (node == DI_NODE_NIL) {
return (DI_NODE_NIL);
}
" current=%s, driver=%s\n",
return (DI_NODE_NIL);
}
return (DI_NODE_NIL);
}
}
/*
* Internal library interfaces:
* node_list etc. for node walking
*/
struct node_list {
};
static void
{
while (*headp) {
}
}
static void
{
return;
}
return;
}
static void
{
return;
return;
}
/*
* returns 1 if node is a descendant of parent, 0 otherwise
*/
static int
{
/*
* DI_NODE_NIL is parent of root, so it is
* the parent of all nodes.
*/
if (parent == DI_NODE_NIL) {
return (1);
}
do {
return (node != DI_NODE_NIL);
}
/*
* Insert list before the first node which is NOT a descendent of parent.
* This is needed to reproduce the exact walking order of link generators.
*/
static void
{
return;
return;
}
return;
}
/*
* Find first node which is not a descendant
*/
}
}
/*
* Get a linked list of handles of all children
*/
static struct node_list *
{
return (NULL);
}
return (NULL);
}
return (NULL);
}
}
return (result);
}
/*
* Internal library interface:
* Delete all siblings of the first node from the node_list, along with
* the first node itself.
*/
static void
{
/*
* get handle to parent of first node
*/
/*
* This must be the root of the snapshot, so can't
* have any siblings.
*
* XXX Put a check here just in case.
*/
return;
}
/*
* To be complete, we should also delete the children
* of siblings that have already been visited.
* This happens for DI_WALK_SIBFIRST when the first node
* is NOT the first in the linked list of siblings.
*
* Hence, we compare parent with BOTH the parent and grandparent
* of nodes, and delete node is a match is found.
*/
while (curr) {
/*
* match parent/grandparent: delete curr
*/
} else
}
/*
* delete the first node
*/
}
/*
* Internal library function:
* Update node list based on action (return code from callback)
* and flag specifying walking behavior.
*/
static void
{
switch (action) {
case DI_WALK_TERMINATE:
/*
* free the node list and be done
*/
break;
case DI_WALK_PRUNESIB:
/*
* Get list of children and prune siblings
*/
break;
case DI_WALK_PRUNECHILD:
/*
* Set children to NULL and pop first node
*/
break;
case DI_WALK_CONTINUE:
default:
/*
* Get list of children and pop first node
*/
break;
}
/*
* insert the list of children
*/
switch (flag) {
case DI_WALK_CLDFIRST:
break;
case DI_WALK_SIBFIRST:
break;
case DI_WALK_LINKGEN:
default:
break;
}
}
/*
* Internal library function:
* Invoke callback on one node and update the list of nodes to be walked
* based on the flag and return code.
*/
static void
{
}
int
int (*node_callback)(di_node_t, void *))
{
return (-1);
}
return (-1);
}
di_node_name(root)));
return (0);
}
/*
* Internal library function:
* Invoke callback for each minor on the minor list of first node
* on node_list headp, and place children of first node on the list.
*
* This is similar to walk_one_node, except we only walk in child
* first mode.
*/
static void
{
int ddm_type;
char *node_type;
continue;
if ((ddm_type == DDM_INTERNAL_PATH) &&
!(flag & DI_CHECK_INTERNAL_PATH))
continue;
!= 0))
continue;
break;
}
}
}
int
{
#ifdef DEBUG
#endif
return (-1);
}
return (-1);
}
di_node_name(root)));
return (0);
}
/*
* generic node parameters
* Calling these routines always succeeds.
*/
char *
{
}
/* returns NULL ptr or a valid ptr to non-NULL string */
char *
{
return (NULL);
}
char *
{
return (NULL);
}
int
{
char *c;
return (0);
}
c = *names;
while (len > 0) {
entries++;
c += size;
}
return (entries);
}
int
{
}
/*
* XXX: emulate the return value of the old implementation
* using info from devi_node_class and devi_node_attributes.
*/
int
{
return (DI_PROM_NODEID);
return (DI_SID_NODEID);
return (DI_PSEUDO_NODEID);
}
{
result |= DI_DEVICE_DOWN;
result |= DI_BUS_DOWN;
return (result);
}
{
}
{
}
{
}
{
return (NULL);
}
int
{
int major;
if (major < 0)
return (-1);
return (major);
}
char *
{
int major;
if (major < 0)
return (NULL);
else
return (NULL);
}
{
int major;
if (major < 0)
return (0);
}
/*
* returns the length of the path, caller must free memory
*/
char *
{
if (node == DI_NODE_NIL) {
return (NULL);
}
/*
* trace back to root, note the node_name & address
*/
depth++;
}
/*
* get the path to the root of snapshot
*/
/*
* allocate buffer and assemble path
*/
return (NULL);
}
len--; /* delete trailing '/' */
while (depth) {
depth--;
}
}
return (buf);
}
char *
{
int full_path_len;
if (minor == DI_MINOR_NIL) {
return (NULL);
}
return (NULL);
/* make the full path to the device minor node */
return (full_path);
}
/*
* Produce a string representation of path to di_path_t (pathinfo node). This
* string is identical to di_devfs_path had the device been enumerated under
* the pHCI: it has a base path to pHCI, then uses node_name of client, and
* device unit-address of pathinfo node.
*/
char *
{
char *full_path;
int full_path_len;
if (path == DI_PATH_NIL) {
return (NULL);
}
/* get name@addr for path */
return (NULL);
/* base path to pHCI devinfo node */
return (NULL);
return (NULL);
/* make the full string representation of path */
return (full_path);
}
char *
{
}
void
{
return;
}
}
/*
* Return 1 if name is a IEEE-1275 generic name. If new generic
* names are defined, they should be added to this table
*/
static int
{
const char **gp;
/* from IEEE-1275 recommended practices section 3 */
static const char *generic_names[] = {
"atm",
"disk",
"display",
"dma-controller",
"ethernet",
"fcs",
"fdc",
"fddi",
"fibre-channel",
"ide",
"interrupt-controller",
"isa",
"keyboard",
"memory",
"mouse",
"nvram",
"pc-card",
"pci",
"printer",
"rtc",
"sbus",
"scanner",
"scsi",
"serial",
"sound",
"ssa",
"tape",
"timer",
"token-ring",
"vme",
0
};
return (1);
}
return (0);
}
/*
* Determine if two paths below /devices refer to the same device, ignoring
* any generic .vs. non-generic 'name' issues in "[[/]name[@addr[:minor]]]*".
* Return 1 if the paths match.
*/
int
{
char nc;
/* progress through both strings */
/* require match until the start of a component */
if (*p1 != '/')
continue;
/* advance p1 and p2 to start of 'name' in component */
continue; /* skip trash */
p1++;
p2++;
/*
* Both p1 and p2 point to beginning of 'name' in component.
* Determine where current component ends: next '/' or '\0'.
*/
/* Determine where name ends based on whether '@' exists */
/*
* At this point p[12] point to beginning of name and
* ec[12] point to character past the end of name. Determine
* if the names are generic.
*/
/*
* one generic and one non-generic
* skip past the names in the match.
*/
} else {
break;
}
}
}
/* minor data access */
{
/*
* paranoid error checking
*/
if (node == DI_NODE_NIL) {
return (DI_MINOR_NIL);
}
/*
* minor is not NIL
*/
if (minor != DI_MINOR_NIL) {
else {
return (DI_MINOR_NIL);
}
}
/*
* minor is NIL-->caller asks for first minor node
*/
}
/*
* no minor data-->check if snapshot includes minor data
* in order to set the correct errno
*/
else
return (DI_MINOR_NIL);
}
/* private interface for dealing with alias minor link generation */
{
if (minor == DI_MINOR_NIL) {
return (DI_NODE_NIL);
}
}
{
}
char *
{
return (NULL);
}
{
}
int
{
}
char *
{
return (NULL);
}
/*
* Single public interface for accessing software properties
*/
{
/*
* paranoid check
*/
if (node == DI_NODE_NIL) {
return (DI_PROP_NIL);
}
/*
* Find which prop list we are at
*/
if (prop != DI_PROP_NIL)
do {
switch (list++) {
case DI_PROP_DRV_LIST:
break;
case DI_PROP_SYS_LIST:
break;
case DI_PROP_GLB_LIST:
break;
case DI_PROP_HW_LIST:
break;
default: /* shouldn't happen */
return (DI_PROP_NIL);
}
return (prop);
}
{
}
char *
{
return (NULL);
}
int
{
if (flags & DDI_PROP_UNDEF_IT)
return (DI_PROP_TYPE_UNDEF_IT);
return (DI_PROP_TYPE_BOOLEAN);
return (DI_PROP_TYPE_UNKNOWN);
if (flags & DDI_PROP_TYPE_INT)
return (DI_PROP_TYPE_INT);
if (flags & DDI_PROP_TYPE_INT64)
return (DI_PROP_TYPE_INT64);
if (flags & DDI_PROP_TYPE_STRING)
return (DI_PROP_TYPE_STRING);
if (flags & DDI_PROP_TYPE_BYTE)
return (DI_PROP_TYPE_BYTE);
/*
* Shouldn't get here. In case we do, return unknown type.
*
* XXX--When DDI_PROP_TYPE_COMPOSITE is implemented, we need
* to add DI_PROP_TYPE_COMPOSITE.
*/
return (DI_PROP_TYPE_UNKNOWN);
}
/*
* Extract type-specific values of an property
*/
int
{
return (0); /* boolean property */
return (-1);
}
return (di_prop_decode_common((void *)prop_data,
}
int
{
return (0); /* boolean property */
return (-1);
}
return (di_prop_decode_common((void *)prop_data,
}
int
{
return (0); /* boolean property */
return (-1);
}
return (di_prop_decode_common((void *)prop_data,
}
int
{
return (0); /* boolean property */
return (-1);
}
return (di_prop_decode_common((void *)prop_data,
}
/*
* returns 1 for match, 0 for no match
*/
static int
{
int prop_type;
#ifdef DEBUG
return (0);
}
#endif /* DEBUG */
return (0);
return (0);
/*
* XXX prop_type is different from DDI_*. See PSARC 1997/127.
*/
return (0);
return (1);
}
static di_prop_t
int type)
{
/*
* The check on match_dev follows ddi_prop_lookup_common().
* Other checks are libdevinfo specific implementation.
*/
return (DI_PROP_NIL);
}
di_prop_type(prop)));
return (prop);
}
return (DI_PROP_NIL);
}
{
(match_dev == DDI_DEV_T_NONE)) {
return (DI_PROP_NIL);
}
di_prop_type(prop)));
(match_dev == DDI_DEV_T_ANY ||
return (prop);
}
return (DI_PROP_NIL);
}
int
int **prop_data)
{
DI_PROP_TYPE_INT)) == DI_PROP_NIL)
return (-1);
}
int
{
return (-1);
}
int
char **prop_data)
{
return (-1);
}
int
{
DI_PROP_TYPE_BYTE)) == DI_PROP_NIL)
return (-1);
}
/*
* Consolidation private property access functions
*/
enum prop_type {
};
static di_prop_t
{
if (prop != DI_PROP_NIL) {
} else {
return (DI_PROP_NIL);
}
}
/*
* prop is NIL, caller asks for first property
*/
switch (prop_type) {
case PROP_TYPE_DRV:
break;
case PROP_TYPE_SYS:
break;
case PROP_TYPE_HW:
break;
case PROP_TYPE_GLOB:
if (prop_off == -1) {
/* no global property */
prop_off = 0;
/* refer to devnames array */
sizeof (struct di_devnm)));
}
break;
}
if (prop_off) {
}
/*
* no prop found. Check the reason for not found
*/
else
return (DI_PROP_NIL);
}
{
}
{
}
{
}
{
}
int
{
#ifdef DEBUG
if (prop == DI_PROP_NIL) {
return (-1);
}
#endif /* DEBUG */
return (0);
}
return (-1);
}
/*
* No memory allocation.
*/
}
/*
* Consolidation private interfaces for accessing I/O multipathing data
*/
{
/*
* path is not NIL
*/
if (path != DI_PATH_NIL) {
else {
return (DI_PATH_NIL);
}
}
/*
* Path is NIL; the caller is asking for the first path info node
*/
}
/*
* No pathing data; check if the snapshot includes path data in order
* to set errno properly.
*/
else
return (DI_PATH_NIL);
}
{
/*
* path is not NIL
*/
if (path != DI_PATH_NIL) {
else {
return (DI_PATH_NIL);
}
}
/*
* Path is NIL; the caller is asking for the first path info node
*/
}
/*
* No pathing data; check if the snapshot includes path data in order
* to set errno properly.
*/
else
return (DI_PATH_NIL);
}
/*
* XXX Remove the private di_path_(addr,next,next_phci,next_client) interfaces
* below after NWS consolidation switches to using di_path_bus_addr,
* di_path_phci_next_path, and di_path_client_next_path per CR6638521.
*/
char *
{
return (buf);
}
{
if (node == DI_NODE_NIL) {
return (DI_PATH_NIL);
}
} else {
/*
* The node had multipathing data but didn't appear to be a
* phci *or* a client; probably a programmer error.
*/
return (DI_PATH_NIL);
}
}
{
}
{
}
{
}
{
}
char *
{
/* pathinfo gets node_name from client */
return (NULL);
return (di_node_name(client_node));
}
char *
{
return (NULL);
}
int
{
}
{
if (path == DI_PATH_NIL) {
return (DI_PATH_NIL);
}
}
/*
* Deal with error condition:
* If parent doesn't exist and node is not the root,
* set errno to ENOTSUP. Otherwise, set errno to ENXIO.
*/
else
return (DI_NODE_NIL);
}
{
if (path == DI_PATH_NIL) {
return (DI_PATH_NIL);
}
}
/*
* Deal with error condition:
* If parent doesn't exist and node is not the root,
* set errno to ENOTSUP. Otherwise, set errno to ENXIO.
*/
else
return (DI_NODE_NIL);
}
{
if (path == DI_PATH_NIL) {
return (DI_PROP_NIL);
}
/*
* prop is not NIL
*/
if (prop != DI_PROP_NIL) {
else {
return (DI_PROP_NIL);
}
}
/*
* prop is NIL-->caller asks for first property
*/
}
/*
* no property data-->check if snapshot includes props
* in order to set the correct errno
*/
else
return (DI_PROP_NIL);
}
char *
{
}
int
{
}
int
{
case DDI_PROP_TYPE_INT:
return (DI_PROP_TYPE_INT);
case DDI_PROP_TYPE_INT64:
return (DI_PROP_TYPE_INT64);
case DDI_PROP_TYPE_BYTE:
return (DI_PROP_TYPE_BYTE);
case DDI_PROP_TYPE_STRING:
return (DI_PROP_TYPE_STRING);
}
return (DI_PROP_TYPE_UNKNOWN);
}
int
{
return (-1);
}
return (di_prop_decode_common((void *)prop_data,
}
int
{
return (0);
return (-1);
}
return (di_prop_decode_common((void *)prop_data,
}
int
{
return (0);
return (-1);
}
return (di_prop_decode_common((void *)prop_data,
}
int
{
return (0);
return (-1);
}
return (di_prop_decode_common((void *)prop_data,
}
static di_path_prop_t
{
/*
* Sanity check arguments
*/
!DI_PROP_TYPE_VALID(type)) {
return (DI_PROP_NIL);
}
continue;
continue;
return (prop);
}
return (DI_PROP_NIL);
}
int
{
DI_PROP_TYPE_BYTE)) == DI_PROP_NIL)
return (-1);
}
int
int **prop_data)
{
DI_PROP_TYPE_INT)) == DI_PROP_NIL)
return (-1);
}
int
{
return (-1);
}
char **prop_data)
{
return (-1);
}
/*
* Consolidation private interfaces for traversing vhci nodes.
*/
{
if (root == DI_NODE_NIL) {
return (DI_NODE_NIL);
}
return (DI_NODE_NIL);
}
}
{
if (node == DI_NODE_NIL) {
return (DI_NODE_NIL);
}
return (DI_NODE_NIL);
}
}
/*
* Consolidation private interfaces for traversing phci nodes.
*/
{
if (vhci_node == DI_NODE_NIL) {
return (DI_NODE_NIL);
}
return (DI_NODE_NIL);
}
}
{
if (node == DI_NODE_NIL) {
return (DI_NODE_NIL);
}
return (DI_NODE_NIL);
}
}
/*
* Consolidation private interfaces for private data
*/
void *
{
return (NULL);
}
/*
* Private data requested, but not obtained due to a memory
* error (e.g. wrong format specified)
*/
return (NULL);
}
else
return (NULL);
}
void *
{
return (NULL);
}
/*
* Private data requested, but not obtained due to a memory
* error (e.g. wrong format specified)
*/
return (NULL);
}
else
return (NULL);
}
/*
* Hotplug information access
*/
typedef struct {
void *arg;
const char *type;
static int
{
char *type_str;
/* Exclude non-matching types if a type filter is specified */
continue;
}
/* Exclude ports if DI_HP_PORT flag not specified */
continue;
/* Exclude connectors if DI_HP_CONNECTOR flag not specified */
continue;
/* Perform callback */
return (DI_WALK_TERMINATE);
}
return (DI_WALK_CONTINUE);
}
int
{
#ifdef DEBUG
#endif
/*
* paranoid error checking
*/
return (-1);
}
/* check if hotplug data is included in snapshot */
return (-1);
}
}
{
/*
* paranoid error checking
*/
if (node == DI_NODE_NIL) {
return (DI_HP_NIL);
}
/*
* hotplug node is not NIL
*/
else {
return (DI_HP_NIL);
}
}
/*
* hotplug node is NIL-->caller asks for first hotplug node
*/
}
/*
* no hotplug data-->check if snapshot includes hotplug data
* in order to set the correct errno
*/
else
return (DI_HP_NIL);
}
char *
{
/*
* paranoid error checking
*/
return (NULL);
}
return (NULL);
}
}
int
{
/*
* paranoid error checking
*/
return (-1);
}
}
int
{
/*
* paranoid error checking
*/
return (-1);
}
}
int
{
/*
* paranoid error checking
*/
return (-1);
}
}
int
{
/*
* paranoid error checking
*/
return (-1);
}
}
char *
{
/*
* paranoid error checking
*/
return (NULL);
}
return (NULL);
}
{
/*
* paranoid error checking
*/
return (DI_NODE_NIL);
}
}
/*
* Deal with error condition:
* Child doesn't exist, figure out if DINFOSUBTREE is set.
* If it isn't, set errno to ENOTSUP.
*/
else
return (DI_NODE_NIL);
}
{
/*
* paranoid error checking
*/
return ((time_t)0);
}
}
/*
* PROM property access
*/
/*
* openprom driver stuff:
* The maximum property length depends on the buffer size. We use
* OPROMMAXPARAM defined in <sys/openpromio.h>
*
* MAXNAMESZ is max property name. obpdefs.h defines it as 32 based on 1275
* MAXVALSZ is maximum value size, which is whatever space left in buf
*/
struct di_prom_prop {
char *name;
int len;
};
union {
} oppbuf;
};
{
struct di_prom_handle *p;
return (DI_PROM_HANDLE_NIL);
free(p);
return (DI_PROM_HANDLE_NIL);
}
return ((di_prom_handle_t)p);
}
static void
{
}
}
}
}
void
{
(void) mutex_destroy(&p->lock);
di_prom_prop_free(p->list);
free(p);
}
/*
* Internal library interface for locating the property
* XXX: ph->lock must be held for the duration of call.
*/
static di_prom_prop_t
{
/*
* Set "current" nodeid in the openprom driver
*/
opp->oprom_size = sizeof (int);
return (DI_PROM_PROP_NIL);
}
if (prom_prop != DI_PROM_PROP_NIL)
return (DI_PROM_PROP_NIL);
/*
* Prom property found. Allocate struct for storing prop
* (reuse variable prop)
*/
return (DI_PROM_PROP_NIL);
/*
* Get a copy of property name
*/
return (DI_PROM_PROP_NIL);
}
/*
* get property value and length
*/
return (DI_PROM_PROP_NIL);
}
/*
* make a copy of the property value
*/
return (DI_PROM_PROP_NIL);
}
/*
* Prepend prop to list in prom handle
*/
return ((di_prom_prop_t)prop);
}
{
node, p));
/*
* paranoid check
*/
return (DI_PROM_PROP_NIL);
}
return (DI_PROM_PROP_NIL);
}
/*
* synchronize access to prom file descriptor
*/
(void) mutex_lock(&p->lock);
/*
* look for next property
*/
(void) mutex_unlock(&p->lock);
return (prom_prop);
}
char *
{
/*
* paranoid check
*/
if (prom_prop == DI_PROM_PROP_NIL) {
return (NULL);
}
}
int
{
/*
* paranoid check
*/
if (prom_prop == DI_PROM_PROP_NIL) {
return (NULL);
}
}
/*
* Internal library interface for locating the property
* Returns length if found, -1 if prop doesn't exist.
*/
static struct di_prom_prop *
const char *prom_prop_name)
{
/*
* paranoid check
*/
return (NULL);
}
return (NULL);
}
(void) mutex_lock(&p->lock);
opp->oprom_size = sizeof (int);
(void) mutex_unlock(&p->lock);
return (NULL);
}
/*
* get property length
*/
/* no such property */
(void) mutex_unlock(&p->lock);
return (NULL);
}
/*
* Prom property found. Allocate struct for storing prop
*/
(void) mutex_unlock(&p->lock);
return (NULL);
}
(void) mutex_unlock(&p->lock);
return (prop);
}
/*
* retrieve the property value
*/
/* error retrieving property value */
(void) mutex_unlock(&p->lock);
return (NULL);
}
/*
* make a copy of the property value, stick in ph->list
*/
(void) mutex_unlock(&p->lock);
return (NULL);
}
(void) mutex_unlock(&p->lock);
return (prop);
}
int
const char *prom_prop_name, int **prom_prop_data)
{
int len;
*prom_prop_data = NULL;
return (-1);
}
*prom_prop_data = NULL;
return (0);
}
DI_PROP_TYPE_INT, 1);
return (len);
}
int
const char *prom_prop_name, char **prom_prop_data)
{
int len;
*prom_prop_data = NULL;
return (-1);
}
*prom_prop_data = NULL;
return (0);
}
/*
* Fix an openprom bug (OBP string not NULL terminated).
* XXX This should really be fixed in promif.
*/
return (-1);
"node=%s, prop=%s, val=%s\n",
}
DI_PROP_TYPE_STRING, 1);
return (len);
}
int
{
int len;
*prom_prop_data = NULL;
return (-1);
}
*prom_prop_data = NULL;
return (0);
}
DI_PROP_TYPE_BYTE, 1);
return (len);
}
/*
* returns an allocated array through <prop_data> only when its count > 0
* and the number of entries (count) as the function return value;
* use di_slot_names_free() to free the array
*/
int
{
goto ERROUT;
goto ERROUT;
goto ERROUT;
return (count);
/*NOTREACHED*/
return (-1);
}
int
{
/*
* change this if and when DI_PROP_TYPE_COMPOSITE is implemented
* and slot-names is properly flagged as such
*/
DI_PROP_NIL) {
return (-1);
}
}
/*
* returns an allocated array through <prop_data> only when its count > 0
* and the number of entries (count) as the function return value;
* use di_slot_names_free() to free the array
*/
int
{
goto ERROUT;
goto ERROUT;
return (count);
/*NOTREACHED*/
return (-1);
}
int
{
return (-1);
}
}
{
if ((link == DI_LINK_NIL) ||
return (DI_LNODE_NIL);
}
if (endpoint == DI_LINK_SRC) {
} else {
}
/* NOTREACHED */
}
char *
{
}
{
}
int
{
return (-1);
}
return (-1);
return (0);
}
int
{
}
void
{
}
void *
{
}
void
{
}
void *
{
}
void
{
}
void *
{
}
void
{
}
void *
{
}
void
{
}
void *
{
}
{
/*
* paranoid error checking
*/
if (node == DI_NODE_NIL) {
return (DI_LNODE_NIL);
}
if (lnode == DI_NODE_NIL) {
} else {
}
else
return (DI_LNODE_NIL);
}
{
/*
* paranoid error checking
*/
if ((node == DI_NODE_NIL) ||
return (DI_LINK_NIL);
}
if (endpoint == DI_LINK_SRC) {
if (link == DI_LINK_NIL) {
} else {
}
} else {
if (link == DI_LINK_NIL) {
} else {
}
}
else
return (DI_LINK_NIL);
}
{
/*
* paranoid error checking
*/
if ((lnode == DI_LNODE_NIL) ||
return (DI_LINK_NIL);
}
if (endpoint == DI_LINK_SRC) {
if (link == DI_LINK_NIL) {
return (DI_LINK_NIL);
} else {
return (DI_LINK_NIL);
}
} else {
if (link == DI_LINK_NIL) {
return (DI_LINK_NIL);
} else {
return (DI_LINK_NIL);
}
}
/* NOTREACHED */
}
/*
* Internal library function:
* Invoke callback for each link data on the link list of first node
* on node_list headp, and place children of first node on the list.
*
* This is similar to walk_one_node, except we only walk in child
* first mode.
*/
static void
{
if (action == DI_WALK_TERMINATE) {
break;
}
}
}
int
{
#ifdef DEBUG
#endif
/*
* paranoid error checking
*/
return (-1);
}
return (-1);
}
di_node_name(root)));
return (0);
}
/*
* Internal library function:
* Invoke callback for each link data on the link list of first node
* on node_list headp, and place children of first node on the list.
*
* This is similar to walk_one_node, except we only walk in child
* first mode.
*/
static void
{
if (action == DI_WALK_TERMINATE) {
break;
}
}
}
int
{
#ifdef DEBUG
#endif
/*
* paranoid error checking
*/
return (-1);
}
return (-1);
}
di_node_name(root)));
return (0);
}
static char *
{
char *curr;
char *cp;
char *alias;
return (NULL);
if (*cp == '\0') {
return (NULL);
} else if (*cp == '/') {
return (curr);
}
}
}
return (NULL);
}
static di_node_t
{
/*
* Path must be absolute and musn't have duplicate slashes
*/
return (DI_NODE_NIL);
}
if (root == DI_NODE_NIL) {
return (DI_NODE_NIL);
}
return (DI_NODE_NIL);
}
return (DI_NODE_NIL);
}
/*
* Handle devfspath = "/" case as well as trailing '/'
*/
break;
/*
* More path-components exist. Deal with the next one
*/
*slash = '\0';
*paddr++ = '\0';
continue;
/*
* Mappings between a "path-address" and bus-addr
*
* paddr baddr
* ---------------------
* NULL NULL
* NULL ""
* "" N/A (invalid paddr)
*/
break;
break;
}
/*
* No nodes in the sibling list or there was no match
*/
if (node == DI_NODE_NIL) {
return (DI_NODE_NIL);
}
}
return (node);
}
{
char *curr;
if (node != DI_NODE_NIL) {
return (node);
}
/* node is already set to DI_NODE_NIL */
/* node may or may node be DI_NODE_NIL */
return (node);
}
return (node);
}
char *
{
char *curr;
return (NULL);
return (di_devfs_path(currnode));
}
return (curr);
}
{
return (DI_NODE_NIL);
}
goto out;
}
/* stop at pHCI and find the node for the phci */
*lastslash = '\0';
goto out;
}
/* set up pname and paddr for last component */
goto out;
}
*paddr++ = '\0';
/* walk paths below phci looking for match */
path != DI_PATH_NIL;
/* get name@addr of path */
continue;
/* break on match */
break;
}
return (path);
}
static char *
{
switch (msglevel) {
case DI_ERR:
return ("ERROR");
case DI_INFO:
return ("Info");
case DI_TRACE:
return ("Trace");
case DI_TRACE1:
return ("Trace1");
case DI_TRACE2:
return ("Trace2");
default:
return ("UNKNOWN");
}
}
void
{
char *estr;
return;
return;
}
/* end of devinfo.c */