Wed Jan 27 05:00:16 2021 UTC ()
Introduce autoconfiguration helpers based around device_compatible_entry:
- pci_compatible_match(): matches against the PCI ID.
- pci_compatible_match_subsys(): matches against PCI SUBSYS ID.
- pci_compatible_lookup(): look up entry by PCI ID.
- pci_compatible_lookup_subsys(): look up entry by PCI SUBSYS ID.
- pci_compatible_lookup_id(): look up entry by an arbitrary ID using the
  PCI ID code conventions.

- Define PCI_COMPAT_EOL as a compat data array sentinel.


(thorpej)
diff -r1.224 -r1.225 src/sys/dev/pci/pci_subr.c
diff -r1.113 -r1.114 src/sys/dev/pci/pcivar.h

cvs diff -r1.224 -r1.225 src/sys/dev/pci/pci_subr.c (expand / switch to context diff)
--- src/sys/dev/pci/pci_subr.c 2020/05/30 10:43:46 1.224
+++ src/sys/dev/pci/pci_subr.c 2021/01/27 05:00:15 1.225
@@ -1,4 +1,4 @@
-/*	$NetBSD: pci_subr.c,v 1.224 2020/05/30 10:43:46 jdolecek Exp $	*/
+/*	$NetBSD: pci_subr.c,v 1.225 2021/01/27 05:00:15 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1997 Zubin D. Dittia.  All rights reserved.
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.224 2020/05/30 10:43:46 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.225 2021/01/27 05:00:15 thorpej Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pci.h"
@@ -83,6 +83,50 @@
 static int pci_conf_find_extcap(const pcireg_t *, unsigned int, int *);
 static void pci_conf_print_pcie_power(uint8_t, unsigned int);
 #define PCIREG_SHIFTOUT(a, b) ((pcireg_t)__SHIFTOUT((a), (b)))
+
+#ifdef _KERNEL
+/*
+ * Common routines used to match a compatible device by its PCI ID code.
+ */
+
+const struct device_compatible_entry *
+pci_compatible_lookup_id(pcireg_t const id,
+    const struct device_compatible_entry *dce)
+{
+	return device_compatible_lookup_id(id, PCI_COMPAT_EOL_VALUE, dce);
+}
+
+const struct device_compatible_entry *
+pci_compatible_lookup(const struct pci_attach_args * const pa,
+    const struct device_compatible_entry * const dce)
+{
+	return pci_compatible_lookup_id(pa->pa_id, dce);
+}
+
+const struct device_compatible_entry *
+pci_compatible_lookup_subsys(const struct pci_attach_args * const pa,
+    const struct device_compatible_entry * const dce)
+{
+	const pcireg_t subsysid =
+	    pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
+
+	return pci_compatible_lookup_id(subsysid, dce);
+}
+
+int
+pci_compatible_match(const struct pci_attach_args * const pa,
+    const struct device_compatible_entry * const dce)
+{
+	return pci_compatible_lookup(pa, dce) != NULL;
+}
+
+int
+pci_compatible_match_subsys(const struct pci_attach_args * const pa,
+    const struct device_compatible_entry * const dce)
+{
+	return pci_compatible_lookup_subsys(pa, dce) != NULL;
+}
+#endif /* _KERNEL */
 
 /*
  * Descriptions of known PCI classes and subclasses.

cvs diff -r1.113 -r1.114 src/sys/dev/pci/pcivar.h (expand / switch to context diff)
--- src/sys/dev/pci/pcivar.h 2018/12/01 01:23:24 1.113
+++ src/sys/dev/pci/pcivar.h 2021/01/27 05:00:16 1.114
@@ -1,4 +1,4 @@
-/*	$NetBSD: pcivar.h,v 1.113 2018/12/01 01:23:24 msaitoh Exp $	*/
+/*	$NetBSD: pcivar.h,v 1.114 2021/01/27 05:00:16 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
@@ -298,7 +298,6 @@
 	    bus_size_t, bus_size_t, bus_space_tag_t *, bus_space_handle_t *, 
 	    bus_addr_t *, bus_size_t *);
 
-
 int pci_find_rom(const struct pci_attach_args *, bus_space_tag_t,
 	    bus_space_handle_t, bus_size_t,
 	    int, bus_space_handle_t *, bus_size_t *);
@@ -315,6 +314,23 @@
 /*
  * Helper functions for autoconfiguration.
  */
+
+#define	PCI_COMPAT_EOL_VALUE	(0xffffffffU)
+#define	PCI_COMPAT_EOL		{ .id = PCI_COMPAT_EOL_VALUE }
+
+const struct device_compatible_entry *
+	pci_compatible_lookup_id(pcireg_t,
+	    const struct device_compatible_entry *);
+const struct device_compatible_entry *
+	pci_compatible_lookup(const struct pci_attach_args *,
+	    const struct device_compatible_entry *);
+int	pci_compatible_match(const struct pci_attach_args *,
+	    const struct device_compatible_entry *);
+const struct device_compatible_entry *
+	pci_compatible_lookup_subsys(const struct pci_attach_args *,
+	    const struct device_compatible_entry *);
+int	pci_compatible_match_subsys(const struct pci_attach_args *,
+	    const struct device_compatible_entry *);
 #ifndef PCI_MACHDEP_ENUMERATE_BUS
 int	pci_enumerate_bus(struct pci_softc *, const int *,
 	    int (*)(const struct pci_attach_args *), struct pci_attach_args *);