pi_subr.c revision 908f1e1388f616898b4e515d343c0414f2a6472e
/*
* 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
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Subroutines used by various components of the Sun4v PI enumerator
*/
#include <sys/systeminfo.h>
#include <strings.h>
#include <fm/topo_mod.h>
#include <libnvpair.h>
#include "pi_impl.h"
static const topo_pgroup_info_t sys_pgroup = {
1
};
static const topo_pgroup_info_t auth_pgroup = {
1
};
/*
* Search the PRI for MDE nodes using md_scan_dag. Using this routine
* consolodates similar searches used in a few places within the sun4vpi
* enumerator.
*
* The routine returns the number of nodes found, or -1. If the node array
* is non-NULL on return, then it must be freed:
* topo_mod_free(mod, nodes, nsize);
*
*/
int
{
int result;
int total_mdenodes;
/* Prepare to scan the PRI using the start string and given arc */
/* Allocate an array to hold the results of the scan */
/* We have no memory. Set an error code and return failure */
*nsize = 0;
return (-1);
}
if (result <= 0) {
/* No nodes found. Free the node array before returning */
*nsize = 0;
}
return (result);
}
/*
* Determine if this node should be skipped by finding the topo-skip property.
*/
int
{
int result;
/*
* These parameters are required. Tell the caller to skip
* all nodes.
*/
return (1);
}
skip = 0; /* do not skip by default */
if (result != 0) {
/*
* There is no topo-skip property. Assume we are not skipping
* the mde node.
*/
skip = 0;
}
/*
* If skip is present and non-zero we want to skip this node. We
* return 1 to indicate this.
*/
if (skip != 0) {
return (1);
}
return (0);
}
/*
* Get the cfg-handle property value from the given PRI node
*/
int
{
int result;
if (cfg_handle == NULL) {
return (-1);
}
if (result != 0) {
"failed to get property %s from node_0x%llx\n",
}
return (result);
}
/*
* Get the chassis serial number (the ID as far as the topo authority is
* concerned) either from the current node, if it is of type 'chassis', or
* search for a chassis node in the PRI.
*
* The string must be freed with topo_mod_strfree()
*/
char *
{
int result;
int idx;
int num_nodes;
/*
* This is a chassis node. We need only search for the serial
* number property on this node to return the ID.
*/
&id);
return (NULL);
}
}
/*
* Search the PRI for nodes of type MD_STR_COMPONENT and find the
* first element with topo-hc-type of MD_STR_CHASSIS. This node
* will contain the MD_STR_SERIAL_NUMBER property to use as the
* chassis-id.
*/
/* We did not find any chassis nodes */
return (NULL);
}
idx = 0;
/*
* This is a chassis node. Get the serial number
* property from the node.
*/
if (result != 0) {
"failed to read %s from node_0x%llx\n",
}
}
/* Search the next node, if necessary */
idx++;
}
/* Everything is freed up and it's time to return the platform-id */
return (NULL);
}
}
/*
* Determine if the node is a FRU by checking for the existance and non-zero
* value of the 'fru' property on the mde node.
*/
int
{
int result;
return (-1);
}
fru = 0;
*is_fru = 0;
if (result != 0) {
/* The node is not a FRU. */
return (-1);
}
if (fru != 0) {
*is_fru = 1;
}
return (0);
}
/*
* Get the id property value from the given PRI node
*/
int
{
int result;
id = 0;
if (result != 0) {
/*
* There is no id property.
*/
return (-1);
}
return (0);
}
/*
* If the given MDE node is a FRU return the 'nac' property, if it exists,
* to use as the label.
*
* The string must be freed with topo_mod_strfree()
*/
char *
{
int result;
int is_fru;
/* This node is not a FRU. It has no label */
return (NULL);
}
/*
* The node is a FRU. Get the NAC name to use as a label.
*/
/* No NAC label. Return NULL */
return (NULL);
}
/* Return a copy of the label */
}
/*
* Return the complete part number string to the caller. The complete part
* number is made up of the part number attribute concatenated with the dash
* number attribute of the mde node.
*
* The string must be freed with topo_mod_strfree()
*/
char *
{
int result;
if (result != 0) {
}
if (result != 0) {
}
if (bufsize == 1) {
return (NULL);
}
/* Construct the part number from the part and dash values */
}
return (buf);
}
/*
* Get the product ID from the 'platform' node in the PRI
*
* The string must be freed with topo_mod_strfree()
*/
char *
{
int result;
/*
* Search the PRI for nodes of type MD_STR_PLATFORM, which contains
* the product-id in it's MD_STR_NAME property.
*/
/* We did not find any platform nodes */
return (NULL);
}
result);
/*
* There should only be 1 platform node, so we will always
* use the first if we find any at all.
*/
/* Everything is freed up and it's time to return the platform-id */
return (NULL);
}
}
/*
* Return the revision string to the caller.
*
* The string must be freed with topo_mod_strfree()
*/
char *
{
int result;
return (NULL);
}
}
/*
* Return the serial number string to the caller.
*
* The string must be freed with topo_mod_strfree()
*/
char *
{
int result;
char buf[MAXNAMELEN];
/* Is this a uint64_t type serial number? */
&sn);
if (result != 0) {
/* No. We have failed to find a serial number */
return (NULL);
}
/* Convert the acquired value to a string */
if (result < 0) {
return (NULL);
}
}
}
/*
* Get the server hostname (the ID as far as the topo authority is
* concerned) from sysinfo and return a copy to the caller.
*
* The string must be freed with topo_mod_strfree()
*/
char *
{
int result;
char hostname[MAXNAMELEN];
/* Everything is freed up and it's time to return the platform-id */
if (result == -1) {
return (NULL);
}
}
/*
* Get the hc scheme name for the given node
*/
char *
{
int result;
char *hc_name;
/*
* Request the hc name from the node.
*/
"failed to get property %s from node_0x%llx\n",
return (NULL);
}
/* Return a copy of the type string */
}
/*
* Calculate the authority information for a node. Inherit the data if
* possible, but always create an appropriate property group.
*/
int
{
int result;
int err;
return (-1);
}
/*
* We failed to create the property group and it was not
* already defined. Set the err code and return failure.
*/
return (-1);
}
/* Get the authority information already available from the parent */
/*
* Set the authority data, inheriting it if possible, but creating it
* if necessary.
*/
&val);
/*
* No product information in the parent node or auth
* list. Find the product information in the PRI.
*/
"name not found for node_0x%llx\n",
}
} else {
/*
* Dup the string. If we cannot find it in the auth
* nvlist we will need to free it, so this lets us
* have a single code path.
*/
}
/*
* We continue even if the product information is not available
* to enumerate as much as possible.
*/
&err);
if (result != 0) {
/* Preserve the error and continue */
"set property %s (%d) : %s\n",
topo_strerror(err));
}
}
}
&val);
/*
* No product information in the parent node or auth
* list. Find the product information in the PRI.
*/
"name not found for node_0x%llx\n",
}
} else {
/*
* Dup the string. If we cannot find it in the auth
* nvlist we will need to free it, so this lets us
* have a single code path.
*/
}
/*
* We continue even if the product information is not available
* to enumerate as much as possible.
*/
&err);
if (result != 0) {
/* Preserve the error and continue */
"set property %s (%d) : %s\n",
topo_strerror(err));
}
}
}
&val);
/*
* No product information in the parent node or auth
* list. Find the product information in the PRI.
*/
"name not found for node_0x%llx\n",
}
} else {
/*
* Dup the string. If we cannot find it in the auth
* nvlist we will need to free it, so this lets us
* have a single code path.
*/
}
/*
* We continue even if the product information is not available
* to enumerate as much as possible.
*/
&err);
if (result != 0) {
/* Preserve the error and continue */
"set property %s (%d) : %s\n",
topo_strerror(err));
}
}
}
return (0);
}
/*
* Calculate a generic FRU for the given node. If the node is not a FRU,
* then inherit the FRU data from the nodes parent.
*/
int
{
int result;
int err;
int is_fru;
char *part;
char *rev;
char *serial;
return (-1);
}
/*
* Determine if this node is a FRU
*/
/* This node is not a FRU. Inherit from parent and return */
return (0);
}
/*
* This node is a FRU. Create an FMRI.
*/
}
/* Set the FRU, whether NULL or not */
if (result != 0) {
}
return (result);
}
int
{
int result;
int err;
char *label;
return (-1);
}
/*
* Get the label, if any, from the mde node and apply it as the label
* for this topology node. Note that a NULL label will inherit the
* label from topology node's parent.
*/
if (result != 0) {
}
return (result);
}
/*
* Calculate the system information for a node. Inherit the data if
* possible, but always create an appropriate property group.
*/
int
{
int result;
int err;
char isa[MAXNAMELEN];
return (-1);
}
/*
* We failed to create the property group and it was not
* already defined. Set the err code and return failure.
*/
return (-1);
}
&err);
isa[0] = '\0';
if (result == -1) {
/* Preserve the error and continue */
"read SI_ARCHITECTURE: %d\n", errno);
}
if (result != 0) {
/* Preserve the error and continue */
"set property %s (%d) : %s\n",
}
}
}
TOPO_PROP_MACHINE, &err);
if (result == -1) {
/* Preserve the error and continue */
"read uname: %d\n", errno);
}
if (result != 0) {
/* Preserve the error and continue */
"set property %s (%d) : %s\n",
}
}
}
return (0);
}
tnode_t *
{
int result;
"cannot bind for node_0x%llx instance %d type %s\n",
return (NULL);
}
/* Bind this node to the parent */
"failed to bind node_0x%llx instance %d: %s\n",
return (NULL);
}
/*
* We have bound the node. Now decorate it with an appropriate
* FRU and label (which may be inherited from the parent).
*/
t_node);
if (result != 0) {
/*
* Though we have failed to set the FRU FMRI we still continue.
* The module errno is set by the called routine, so we report
* the problem and move on.
*/
"failed to set FRU FMRI for node_0x%llx\n",
}
if (result != 0) {
/*
* Though we have failed to set the label, we still continue.
* The module errno is set by the called routine, so we report
* the problem and move on.
*/
}
if (result != 0) {
/*
* Though we have failed to set the authority, we still
* continue. The module errno is set by the called routine, so
* we report the problem and move on.
*/
}
if (result != 0) {
/*
* Though we have failed to set the system group, we still
* continue. The module errno is set by the called routine, so
* we report the problem and move on.
*/
}
return (t_node);
}