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);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to