/*
* 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
*/
/*
*/
/*
* did.c
* The acronym did means "Dev-Info-Data". Many properties and
* characteristics of topology nodes are, with a bit of coaxing
* derived from devinfo nodes. These routines do some of the
* derivation and also encapsulate the discoveries in did_t
* structures that get associated with topology nodes as their
* "private" data.
*/
#include <alloca.h>
#include <assert.h>
#include <string.h>
#include <strings.h>
#include <fm/topo_mod.h>
#include <libnvpair.h>
#include <libdevinfo.h>
#include <hostbridge.h>
#include <pcibus.h>
#include <did_props.h>
#include "did_impl.h"
static void slotnm_destroy(slotnm_t *);
static slotnm_t *
{
slotnm_t *p;
return (NULL);
slotnm_destroy(p);
return (NULL);
}
return (p);
}
static void
{
if (p == NULL)
return;
slotnm_destroy(p->snm_next);
}
static int
{
int sz;
/*
* For PCI the device type defined the type of device directly below.
* For PCIe RP and Switches, the device-type should be "pciex". For
* PCIe-PCI and PCI-PCI bridges it should be "pci". NICs = "network",
* Graphics = "display", etc..
*/
} else {
}
return (0);
return (-1);
}
typedef struct smbios_slot_cb {
int cb_slotnum;
const char *cb_label;
static int
{
return (0);
return (1);
}
return (0);
}
static int
{
char *slotbuf;
int sz;
*slotnum = -1;
/*
* For PCI-Express, there is only one downstream device, so check for
* a slot-names property, and if it exists, ignore the slotmask value
* and use the string as the label.
*/
sz > 4) {
/*
* If there is a DI_SLOTPROP of the form SlotX (ie set up from
* the IRQ routing table) then trust that in preference to
* DI_PHYSPROP (which is set up from the PCIe slotcap reg).
*/
}
if (*slotnum == -1)
return (0);
/*
* Order of preference
* 1) take slotnum and look up in SMBIOS table
* 2) use slot-names
* 3) fabricate name based on slotnum
*/
/*
* The PCI spec describes slot number 0 as reserved for
* internal PCI devices. Not all platforms respect
* this, so we have to treat slot 0 as a valid device.
* But other platforms use 0 to identify an internal
* device. We deal with this by letting SMBIOS be the
* final decision maker. If SMBIOS is supported, but
* the given slot number is not represented in the
* SMBIOS tables, then ignore the slot entirely.
*/
return (0);
} else if (got_slotprop == B_TRUE) {
} else {
/*
* Make generic description string "SLOT <num>", allow up to
* 10 digits for number
*/
}
return (-1);
return (0);
}
static int
{
char *slotname;
int andbit;
*nslots = 0;
return (0);
return (0);
if (slotmap == 0)
return (0);
char *s = slotname;
*nslots = 0;
return (-1);
}
else {
}
(*nslots)++;
}
}
return (0);
}
int
{
return (did->dp_physlot);
}
int
{
}
did_t *
{
return (pd);
}
return (NULL);
/*
* We must have a reg prop and from it we extract the bus #,
* device #, and function #.
*/
return (NULL);
}
else
/*
* There *may* be a class code we can capture. If there wasn't
* one, capture that fact by setting the class value to -1.
*/
} else {
}
/*
* There *may* be a device type we can capture.
*/
if (irc >= 0) {
/*
* This is a pciex node.
*/
&np->dp_physlot_name) < 0) {
return (NULL);
}
} else {
/*
* This is a pci node.
*/
&np->dp_slotnames) < 0) {
return (NULL);
}
}
return (np);
}
did_t *
{
}
did_t *
{
}
void
{
}
void
{
}
void
{
}
void
{
/*
* did_destroy() is called only from did_hash_destroy() when
* all references to the did_t have been released. We can
* safely destroy the did_t. If at some later time, more
* fine-grained reference count control is desired, this
* code will need to change
*/
}
void
{
}
void
{
}
{
}
{
}
void
{
}
void
{
}
int
{
}
int
{
}
int
{
}
int
{
}
void
{
}
int
{
}
const char *
{
/*
* For pciex, name will be in dp_physlot_name
*/
return (dp->dp_physlot_name);
/*
* For pci, name will be in dp_slotnames
*/
break;
return (NULL);
}
char *
{
return (did->dp_slot_label);
}
void
{
did->dp_slot_label = l;
}
did_t *
{
}
int
{
return (-1);
return (0);
}
int
{
return (-1);
return (-1);
}
return (0);
}
char *
{
return (NULL);
return (dp->dp_devtype);
}
int
{
return (-1);
}
void
{
}
void
{
}
tnode_t *
{
}