/*
* 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
*/
/*
*/
#include <alloca.h>
#include <assert.h>
#include <fm/topo_mod.h>
#include <libnvpair.h>
#include <string.h>
#include <did.h>
#include <pcibus.h>
#include <pcibus_labels.h>
extern slotnm_rewrite_t *Slot_Rewrites;
extern physlot_names_t *Physlot_Names;
extern missing_names_t *Missing_Names;
/*
* Do a platform specific label lookup based on physical slot number.
*/
static const char *
{
int n, p, i;
return (NULL);
__func__, n);
for (p = 0; p < Physlot_Names->psn_nplats; p++) {
platform) != 0)
continue;
"platform\n", __func__);
break;
}
}
break;
}
}
return (rlabel);
}
/*
* Do a platform specific label lookup based on slot name.
*/
static const char *
{
int s, i, ret;
return (rlabel);
for (s = 0; s < Slot_Rewrites->srw_nplats; s++) {
platform) != 0)
continue;
"platform\n", __func__);
for (i = 0;
i++) {
"old_label=%s, new_label=%s\n",
/*
* If a test function is specified then call
* it to do an additional check.
*/
"%s: calling test function=%p\n",
"%s: test function return=%d\n",
} else {
}
break;
}
}
break;
}
return (rlabel);
}
/*
* Do a platform specific label lookup based on bus, dev, etc.
*/
static const char *
{
int p, i, ret;
return (NULL);
"board=%d, bridge=%d, rc=%d, bus=%d, dev=%d\n",
for (p = 0; p < Missing_Names->mn_nplats; p++) {
platform) != 0)
continue;
"platform\n", __func__);
devlab_t m;
/*
* If a test function is specified then call
* it to do an additional test.
*/
"%s: calling test function=%p\n",
"%s: test function return=%d\n",
if (ret)
break;
} else {
break;
}
}
}
break;
}
}
return (rlabel);
}
/*
* Do an overall slot label lookup for the device node.
*/
char *
{
"node_inst=%d, dp=%p, dp_bdf=%d/%d/%d, pdp=%p\n",
/*
* The slot label is determined in the following order:
* - Platform specific lookup based on physical slot #.
* - Platform specific lookup based on default label string.
* - Platform specific lookup based on device number (Note that this
* can override the default label by pci_label_slotname_lookup
* returning null, and the pci_label_missing_lookup setting a new
* value).
* - Default label.
* If no platform known, then just use default label.
*/
/*
* Trim SUNW, from the platform name
*/
else
++pp;
!= NULL) {
label_override = 1;
} else {
if ((new_l = (char *)pci_label_slotname_lookup(
label_override = 1;
l = new_l;
}
}
if (l == NULL) {
if ((l = (char *)pci_label_missing_lookup(mod,
label_override = 1;
}
}
} else {
l = (char *)did_physlot_name(pdp, d);
}
if (l == NULL) {
return (NULL);
}
/*
* If we haven't overridden the label, then we may need to
* concatenate with that of an ancestor node. Check ancestors for a
* slot label until we either find one or hit a non-pci device.
* If an ancestor has a slot label, then this node's label
* is generated by concatenating the default label onto the
* ancestor's label.
*
* We grab pairs of ancestors (parent and child) as we go up
* the tree because the parent is checked for the presence
* of a slot while the child contains the label.
*/
if (!label_override) {
l);
/*
* Check ancestors for a slot label until we
* either find one or hit a non-pci device.
*/
while (!done) {
/*
* Get next ancestor node and data pointers.
*/
else
} else {
}
"two ancestors: anode=%p, adp=%p "
"apnode=%p, apdp=%p\n",
"anode_name=%s[%d], anode_bdf=%d/%d/%d\n",
topo_node_instance(anode), b, d, f);
}
"apnode_name=%s[%d], "
"apnode_bdf=%d/%d/%d\n",
topo_node_instance(apnode), b, d, f);
}
/*
* If the ancestors do not exist or are not pci
* devices then we're done searching.
*
* Otherwise, if the ancestor has a physical slot,
* and it is a different slot than the one we
* started with then lookup the ancestor label,
* and we're done.
*/
done++;
} else if (did_physlot_exists(apdp) &&
&err) != 0) {
"%s: node=%p: topo_node_label() "
return (NULL);
}
done++;
"ancestor with a slot, label=%s ",
}
}
/*
* If we found an ancestor with a slot label, and this node has
* a physical slot number label then concatenate the two to form
* this node's label. Otherwise, do a full slot label lookup.
*/
if (ancestor_l) {
"ancestor_l=%s and l=%s\n",
l = new_l;
} else {
}
}
/*
* If we calculated a slot label, then save it in the
* node's data structure so we can free it later.
*/
l = topo_mod_strdup(mod, l);
did_slot_label_set(dp, l);
return (l);
}
int
{
char *l;
char *nm;
int err;
/*
* If it's not a device or a PCI-express bus (which could potentially
* represent a slot, and therefore we might need to capture its slot
* name information), just inherit any label from our parent
*/
if (err != ETOPO_PROP_NOENT)
return (0);
}
"%s: label method argument not found.\n", __func__);
return (-1);
}
/*
* Is there a slot label associated with the device?
*/
return (0);
} else {
if (err != ETOPO_PROP_NOENT)
return (0);
}
}
int
{
int err = 0;
char *nm;
return (0);
"%s: label method argument not found.\n", __func__);
return (-1);
}
/*
* Is there a slot label associated with the device?
*/
}
}
return (0);
}