devinfo: Support PCI DBSF and ACPI handles for -p
When matching on a name of a device, match on ACPI handles and PCI selectors in addition to device names. This can be useful for matching on devices without an attached driver. For example: devinfo -p pci0:0:31:0 Reviewed by: imp Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D55673
This commit is contained in:
@@ -26,7 +26,7 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd August 28, 2025
|
||||
.Dd March 6, 2026
|
||||
.Dt DEVINFO 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -53,6 +53,26 @@ The following options are accepted:
|
||||
Display the path of
|
||||
.Ar dev
|
||||
back to the root of the device tree.
|
||||
.Ar dev
|
||||
can either be a device name,
|
||||
the absolute path of an ACPI handle
|
||||
.Po must begin with a
|
||||
.Dq \e
|
||||
.Pc ,
|
||||
or a PCI selector
|
||||
.Po
|
||||
either
|
||||
.Sy pci Ns Fa domain Ns : Ns Fa bus Ns : Ns Fa slot Ns : Ns Fa function
|
||||
or
|
||||
.Sy pci Ns Fa bus Ns : Ns Fa slot Ns : Ns Fa function
|
||||
.Pc .
|
||||
.Pp
|
||||
If
|
||||
.Fl v
|
||||
is specified,
|
||||
each device is output on a separate line including the device name and
|
||||
additional verbose information;
|
||||
otherwise, a space-separated list of device names is output.
|
||||
.It Fl r
|
||||
Causes hardware resource information
|
||||
.Pq such as IRQ, I/O ports, I/O memory addresses
|
||||
|
||||
@@ -275,13 +275,69 @@ print_device_path_entry(struct devinfo_dev *dev)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* This assumes the string to be compared in *cp is either space or
|
||||
* nul terminated.
|
||||
*/
|
||||
static bool
|
||||
match_value(const char *cp, const char *name)
|
||||
{
|
||||
const char *end;
|
||||
size_t len;
|
||||
|
||||
end = strchr(cp, ' ');
|
||||
if (end == NULL)
|
||||
return (strcmp(cp, name) == 0);
|
||||
|
||||
if (end == cp)
|
||||
return (false);
|
||||
|
||||
/* NB: strncmp(3) would return zero if name matches a prefix. */
|
||||
len = end - cp;
|
||||
return (strlen(name) == len && memcmp(name, cp, len) == 0);
|
||||
}
|
||||
|
||||
static bool
|
||||
device_matches_name(struct devinfo_dev *dev, const char *name)
|
||||
{
|
||||
const char *cp, *val;
|
||||
|
||||
if (strcmp(dev->dd_name, name) == 0)
|
||||
return (true);
|
||||
|
||||
if (*dev->dd_location) {
|
||||
/* Permit matches on the ACPI handle stored in location. */
|
||||
if (name[0] == '\\' && (cp = strstr(dev->dd_location,
|
||||
"handle=\\")) != NULL) {
|
||||
if (match_value(cp + strlen("handle="), name))
|
||||
return (true);
|
||||
}
|
||||
|
||||
/* Permit matches on the PCI dbsf stored in location. */
|
||||
if (strncmp(name, "pci", strlen("pci")) == 0 &&
|
||||
(cp = strstr(dev->dd_location, "dbsf=pci")) != NULL) {
|
||||
cp += strlen("dbsf=pci");
|
||||
val = name + strlen("pci");
|
||||
if (match_value(cp, val))
|
||||
return (true);
|
||||
|
||||
/* Also match on pci<b>:<s>:<f> for domain 0. */
|
||||
if (strncmp(cp, "0:", strlen("0:")) == 0 &&
|
||||
match_value(cp + strlen("0:"), val))
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
static int
|
||||
print_device_path(struct devinfo_dev *dev, void *xname)
|
||||
{
|
||||
const char *name = xname;
|
||||
int rv;
|
||||
|
||||
if (strcmp(dev->dd_name, name) == 0) {
|
||||
if (device_matches_name(dev, name)) {
|
||||
print_device_path_entry(dev);
|
||||
return (1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user