git: 46d383af0dbd - main - pciconf: Add -C option to filter by class name
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 21 Sep 2026 18:39:35 UTC
The branch main has been updated by bnovkov:
URL: https://cgit.FreeBSD.org/src/commit/?id=46d383af0dbdb3871354f344b9c1ba99da691121
commit 46d383af0dbdb3871354f344b9c1ba99da691121
Author: Federico Angelilli <code@fedang.net>
AuthorDate: 2026-09-21 18:23:10 +0000
Commit: Bojan Novković <bnovkov@FreeBSD.org>
CommitDate: 2026-09-21 18:37:59 +0000
pciconf: Add -C option to filter by class name
Differential Revision: https://reviews.freebsd.org/D59602
MFC after: 3 weeks
PR: 289923
Reviewed by: bnovkov
---
usr.sbin/pciconf/pciconf.8 | 10 ++++++++--
usr.sbin/pciconf/pciconf.c | 40 +++++++++++++++++++++++++++++++++++-----
2 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/usr.sbin/pciconf/pciconf.8 b/usr.sbin/pciconf/pciconf.8
index 1c9be4e817ae..e82db4ed0fc8 100644
--- a/usr.sbin/pciconf/pciconf.8
+++ b/usr.sbin/pciconf/pciconf.8
@@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd September 5, 2026
+.Dd September 21, 2026
.Dt PCICONF 8
.Os
.Sh NAME
@@ -31,7 +31,7 @@
.Nd diagnostic utility for the PCI bus
.Sh SYNOPSIS
.Nm
-.Fl l Oo Fl BbceVv Oc Op Ar device
+.Fl l Oo Fl BbceVv Oc Oo Fl C Ar class Oc Op Ar device
.Nm
.Fl t Oo Fl v Oc
.Nm
@@ -227,6 +227,12 @@ Each capability is enumerated via a line in the following format:
cap 10[40] = PCI-Express 1 root port
.Ed
.Pp
+If the
+.Fl C
+option is supplied,
+.Nm
+will list only the devices whose PCI class name matches the given argument.
+.Pp
The first value after the
.Dq Li cap
prefix is the capability ID in hexadecimal.
diff --git a/usr.sbin/pciconf/pciconf.c b/usr.sbin/pciconf/pciconf.c
index 581a0cb3ff85..7da61da5fa11 100644
--- a/usr.sbin/pciconf/pciconf.c
+++ b/usr.sbin/pciconf/pciconf.c
@@ -79,10 +79,11 @@ static struct pcisel getsel(const char *str);
static void list_bridge(int fd, struct pci_conf *p);
static void list_bars(int fd, struct pci_conf *p);
static void list_devs(const char *name, int verbose, int bars, int bridge,
- int caps, int errors, int vpd, int compact);
+ int caps, int errors, int vpd, int compact, const char *class);
static void show_tree(int verbose);
static void list_verbose(struct pci_conf *p);
static void list_vpd(int fd, struct pci_conf *p);
+static bool validate_class(const char *class);
static const char *guess_class(struct pci_conf *p);
static const char *guess_subclass(struct pci_conf *p);
static int load_vendors(void);
@@ -103,7 +104,7 @@ usage(void)
{
fprintf(stderr, "%s",
- "usage: pciconf -l [-BbcevV] [device]\n"
+ "usage: pciconf -l [-BbcevV] [-C class] [device]\n"
" pciconf -t [-v]\n"
" pciconf -a device\n"
" pciconf -r [-b | -h] device addr[:addr2]\n"
@@ -122,12 +123,14 @@ main(int argc, char **argv)
enum { NONE, LIST, TREE, READ, WRITE, ATTACHED, DUMPBAR, READBAR,
WRITEBAR } mode;
int compact, bars, bridge, caps, errors, verbose, vpd;
+ const char *class;
mode = NONE;
compact = bars = bridge = caps = errors = verbose = vpd = 0;
width = 4;
+ class = NULL;
- while ((c = getopt(argc, argv, "aBbcDehlRrtWwVvx")) != -1) {
+ while ((c = getopt(argc, argv, "aBbcC:DehlRrtWwVvx")) != -1) {
switch(c) {
case 'a':
mode = ATTACHED;
@@ -146,6 +149,10 @@ main(int argc, char **argv)
caps++;
break;
+ case 'C':
+ class = optarg;
+ break;
+
case 'D':
mode = DUMPBAR;
break;
@@ -206,7 +213,7 @@ main(int argc, char **argv)
if (optind >= argc + 1)
usage();
list_devs(optind + 1 == argc ? argv[optind] : NULL, verbose,
- bars, bridge, caps, errors, vpd, compact);
+ bars, bridge, caps, errors, vpd, compact, class);
break;
case TREE:
if (optind != argc)
@@ -314,16 +321,20 @@ fetch_devs(int fd, const char *name, struct pci_conf **confp, size_t *countp)
static void
list_devs(const char *name, int verbose, int bars, int bridge, int caps,
- int errors, int vpd, int compact)
+ int errors, int vpd, int compact, const char *class)
{
int fd;
struct pci_conf *conf, *p;
size_t count;
+ const char *pclass;
int none_count = 0;
if (verbose)
load_vendors();
+ if (class != NULL && !validate_class(class))
+ errx(1, "Invalid class name");
+
fd = open(_PATH_DEVPCI, (bridge || caps || errors) ? O_RDWR : O_RDONLY,
0);
if (fd < 0)
@@ -339,6 +350,12 @@ list_devs(const char *name, int verbose, int bars, int bridge, int caps,
printf("drv\tselector\tclass rev hdr "
"vendor device subven subdev\n");
for (p = conf; p < conf + count; p++) {
+ if (class != NULL) {
+ pclass = guess_class(p);
+ if (pclass == NULL || strcasecmp(pclass, class) != 0)
+ continue;
+ }
+
if (compact)
printf("%s%d@pci%d:%d:%d:%d:"
"\t%06x %02x %02x "
@@ -1081,6 +1098,19 @@ static struct
{0, 0, NULL}
};
+static bool
+validate_class(const char *class)
+{
+ int i;
+
+ for (i = 0; pci_nomatch_tab[i].desc != NULL; i++) {
+ if ((strcasecmp(class, pci_nomatch_tab[i].desc) == 0) &&
+ (pci_nomatch_tab[i].subclass == -1))
+ return (true);
+ }
+ return (false);
+}
+
static const char *
guess_class(struct pci_conf *p)
{