svn commit: r336066 - in head/sys: compat/linsysfs dev/pci

Warner Losh imp at FreeBSD.org
Sat Jul 7 15:25:14 UTC 2018


Author: imp
Date: Sat Jul  7 15:25:11 2018
New Revision: 336066
URL: https://svnweb.freebsd.org/changeset/base/336066

Log:
  Create PCI_MATCH and pci_match_device
  
  Create a covenience function to match PCI device IDs. It's about 15
  years overdue.
  
  Differential Revision: https://reviews.freebsd.org/D15999

Modified:
  head/sys/compat/linsysfs/linsysfs.c
  head/sys/dev/pci/pci.c
  head/sys/dev/pci/pcivar.h

Modified: head/sys/compat/linsysfs/linsysfs.c
==============================================================================
--- head/sys/compat/linsysfs/linsysfs.c	Sat Jul  7 15:25:06 2018	(r336065)
+++ head/sys/compat/linsysfs/linsysfs.c	Sat Jul  7 15:25:11 2018	(r336066)
@@ -273,6 +273,7 @@ linsysfs_fill_vgapci(PFS_FILL_ARGS)
 	return (0);
 }
 
+#undef PCI_DEV
 #define PCI_DEV "pci"
 #define DRMN_DEV "drmn"
 static int

Modified: head/sys/dev/pci/pci.c
==============================================================================
--- head/sys/dev/pci/pci.c	Sat Jul  7 15:25:06 2018	(r336065)
+++ head/sys/dev/pci/pci.c	Sat Jul  7 15:25:11 2018	(r336066)
@@ -6244,3 +6244,39 @@ pcie_flr(device_t dev, u_int max_delay, bool force)
 		pci_printf(&dinfo->cfg, "Transactions pending after FLR!\n");
 	return (true);
 }
+
+const struct pci_device_table *
+pci_match_device(device_t child, const struct pci_device_table *id, size_t nelt)
+{
+	bool match;
+	uint16_t vendor, device, subvendor, subdevice, class, subclass, revid;
+
+	vendor = pci_get_vendor(child);
+	device = pci_get_device(child);
+	subvendor = pci_get_subvendor(child);
+	subdevice = pci_get_subdevice(child);
+	class = pci_get_class(child);
+	subclass = pci_get_subclass(child);
+	revid = pci_get_revid(child);
+	while (nelt-- > 0) {
+		match = true;
+		if (id->match_flag_vendor)
+			match &= vendor == id->vendor;
+		if (id->match_flag_device)
+			match &= device == id->device;
+		if (id->match_flag_subvendor)
+			match &= subvendor == id->subvendor;
+		if (id->match_flag_subdevice)
+			match &= subdevice == id->subdevice;
+		if (id->match_flag_class)
+			match &= class == id->class_id;
+		if (id->match_flag_subclass)
+			match &= subclass == id->subclass;
+		if (id->match_flag_revid)
+			match &= revid == id->revid;
+		if (match)
+			return (id);
+		id++;
+	}
+	return (NULL);
+}

Modified: head/sys/dev/pci/pcivar.h
==============================================================================
--- head/sys/dev/pci/pcivar.h	Sat Jul  7 15:25:06 2018	(r336065)
+++ head/sys/dev/pci/pcivar.h	Sat Jul  7 15:25:11 2018	(r336066)
@@ -259,6 +259,66 @@ typedef struct {
 
 extern uint32_t pci_numdevs;
 
+struct pci_device_table {
+#if BYTE_ORDER == LITTLE_ENDIAN
+	uint16_t
+		match_flag_vendor:1,
+		match_flag_device:1,
+		match_flag_subvendor:1,
+		match_flag_subdevice:1,
+		match_flag_class:1,
+		match_flag_subclass:1,
+		match_flag_revid:1,
+		match_flag_unused:9;
+#else
+	uint16_t
+		match_flag_unused:9,
+		match_flag_revid:1,
+		match_flag_subclass:1,
+		match_flag_class:1,
+		match_flag_subdevice:1,
+		match_flag_subvendor:1,
+		match_flag_device:1,
+		match_flag_vendor:1;
+#endif
+	uint16_t	vendor;
+	uint16_t	device;
+	uint16_t	subvendor;
+	uint16_t	subdevice;
+	uint16_t	class_id;
+	uint16_t	subclass;
+	uint16_t	revid;
+	uint16_t	unused;
+	uintptr_t	driver_data;
+	char		*descr;
+};
+
+#define	PCI_DEV(v, d)							\
+	.match_flag_vendor = 1, .vendor = (v),				\
+	.match_flag_device = 1, .device = (d)
+#define	PCI_SUBDEV(sv, sd)						\
+	.match_flag_subvendor = 1, .subvendor = (sv),			\
+	.match_flag_subdevice = 1, .subdevice = (sd)
+#define	PCI_CLASS(x)							\
+	.match_flag_class = 1, .class_id = (x)
+#define	PCI_SUBCLASS(x)							\
+	.match_flag_subclass = 1, .subclass = (x)
+#define	PCI_REVID(x)							\
+	.match_flag_revid = 1, .revid = (x)
+#define	PCI_DESCR(x)							\
+	.descr = (x)
+#define PCI_PNP_STR							\
+	"M16:mask;U16:vendor;U16:device;U16:subvendor;U16:subdevice;"	\
+	"U16:class;U16:subclass;U16:revid;"
+#define PCI_PNP_INFO(table)						\
+	MODULE_PNP_INFO(PCI_PNP_STR, pci, table, table, sizeof(table[0]), \
+	    sizeof(table) / sizeof(table[0]))
+
+const struct pci_device_table *pci_match_device(device_t child,
+    const struct pci_device_table *id, size_t nelt);
+#define PCI_MATCH(child, table) \
+	pci_match_device(child, (table), nitems(table));
+
 /* Only if the prerequisites are present */
 #if defined(_SYS_BUS_H_) && defined(_SYS_PCIIO_H_)
 struct pci_devinfo {
@@ -416,7 +476,7 @@ pci_get_vpd_readonly(device_t dev, const char *kw, con
 static __inline int
 pci_is_vga_ioport_range(rman_res_t start, rman_res_t end)
 {
- 
+
 	return (((start >= 0x3b0 && end <= 0x3bb) ||
 	    (start >= 0x3c0 && end <= 0x3df)) ? 1 : 0);
 }


More information about the svn-src-head mailing list