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.diff -r1.224 -r1.225 src/sys/dev/pci/pci_subr.c
(thorpej)
--- 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,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: pci_subr.c,v 1.224 2020/05/30 10:43:46 jdolecek Exp $ */ | 1 | /* $NetBSD: pci_subr.c,v 1.225 2021/01/27 05:00:15 thorpej Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1997 Zubin D. Dittia. All rights reserved. | 4 | * Copyright (c) 1997 Zubin D. Dittia. All rights reserved. | |
5 | * Copyright (c) 1995, 1996, 1998, 2000 | 5 | * Copyright (c) 1995, 1996, 1998, 2000 | |
6 | * Christopher G. Demetriou. All rights reserved. | 6 | * Christopher G. Demetriou. All rights reserved. | |
7 | * Copyright (c) 1994 Charles M. Hannum. All rights reserved. | 7 | * Copyright (c) 1994 Charles M. Hannum. All rights reserved. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
@@ -30,27 +30,27 @@ | @@ -30,27 +30,27 @@ | |||
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
33 | */ | 33 | */ | |
34 | 34 | |||
35 | /* | 35 | /* | |
36 | * PCI autoconfiguration support functions. | 36 | * PCI autoconfiguration support functions. | |
37 | * | 37 | * | |
38 | * Note: This file is also built into a userland library (libpci). | 38 | * Note: This file is also built into a userland library (libpci). | |
39 | * Pay attention to this when you make modifications. | 39 | * Pay attention to this when you make modifications. | |
40 | */ | 40 | */ | |
41 | 41 | |||
42 | #include <sys/cdefs.h> | 42 | #include <sys/cdefs.h> | |
43 | __KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.224 2020/05/30 10:43:46 jdolecek Exp $"); | 43 | __KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.225 2021/01/27 05:00:15 thorpej Exp $"); | |
44 | 44 | |||
45 | #ifdef _KERNEL_OPT | 45 | #ifdef _KERNEL_OPT | |
46 | #include "opt_pci.h" | 46 | #include "opt_pci.h" | |
47 | #endif | 47 | #endif | |
48 | 48 | |||
49 | #include <sys/param.h> | 49 | #include <sys/param.h> | |
50 | 50 | |||
51 | #ifdef _KERNEL | 51 | #ifdef _KERNEL | |
52 | #include <sys/systm.h> | 52 | #include <sys/systm.h> | |
53 | #include <sys/intr.h> | 53 | #include <sys/intr.h> | |
54 | #include <sys/module.h> | 54 | #include <sys/module.h> | |
55 | #include <sys/kmem.h> | 55 | #include <sys/kmem.h> | |
56 | 56 | |||
@@ -74,26 +74,70 @@ __KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v | @@ -74,26 +74,70 @@ __KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v | |||
74 | #ifdef _KERNEL | 74 | #ifdef _KERNEL | |
75 | #include <dev/pci/pcivar.h> | 75 | #include <dev/pci/pcivar.h> | |
76 | #else | 76 | #else | |
77 | #include <dev/pci/pci_verbose.h> | 77 | #include <dev/pci/pci_verbose.h> | |
78 | #include <dev/pci/pcidevs.h> | 78 | #include <dev/pci/pcidevs.h> | |
79 | #include <dev/pci/pcidevs_data.h> | 79 | #include <dev/pci/pcidevs_data.h> | |
80 | #endif | 80 | #endif | |
81 | 81 | |||
82 | static int pci_conf_find_cap(const pcireg_t *, unsigned int, int *); | 82 | static int pci_conf_find_cap(const pcireg_t *, unsigned int, int *); | |
83 | static int pci_conf_find_extcap(const pcireg_t *, unsigned int, int *); | 83 | static int pci_conf_find_extcap(const pcireg_t *, unsigned int, int *); | |
84 | static void pci_conf_print_pcie_power(uint8_t, unsigned int); | 84 | static void pci_conf_print_pcie_power(uint8_t, unsigned int); | |
85 | #define PCIREG_SHIFTOUT(a, b) ((pcireg_t)__SHIFTOUT((a), (b))) | 85 | #define PCIREG_SHIFTOUT(a, b) ((pcireg_t)__SHIFTOUT((a), (b))) | |
86 | 86 | |||
87 | #ifdef _KERNEL | |||
88 | /* | |||
89 | * Common routines used to match a compatible device by its PCI ID code. | |||
90 | */ | |||
91 | ||||
92 | const struct device_compatible_entry * | |||
93 | pci_compatible_lookup_id(pcireg_t const id, | |||
94 | const struct device_compatible_entry *dce) | |||
95 | { | |||
96 | return device_compatible_lookup_id(id, PCI_COMPAT_EOL_VALUE, dce); | |||
97 | } | |||
98 | ||||
99 | const struct device_compatible_entry * | |||
100 | pci_compatible_lookup(const struct pci_attach_args * const pa, | |||
101 | const struct device_compatible_entry * const dce) | |||
102 | { | |||
103 | return pci_compatible_lookup_id(pa->pa_id, dce); | |||
104 | } | |||
105 | ||||
106 | const struct device_compatible_entry * | |||
107 | pci_compatible_lookup_subsys(const struct pci_attach_args * const pa, | |||
108 | const struct device_compatible_entry * const dce) | |||
109 | { | |||
110 | const pcireg_t subsysid = | |||
111 | pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); | |||
112 | ||||
113 | return pci_compatible_lookup_id(subsysid, dce); | |||
114 | } | |||
115 | ||||
116 | int | |||
117 | pci_compatible_match(const struct pci_attach_args * const pa, | |||
118 | const struct device_compatible_entry * const dce) | |||
119 | { | |||
120 | return pci_compatible_lookup(pa, dce) != NULL; | |||
121 | } | |||
122 | ||||
123 | int | |||
124 | pci_compatible_match_subsys(const struct pci_attach_args * const pa, | |||
125 | const struct device_compatible_entry * const dce) | |||
126 | { | |||
127 | return pci_compatible_lookup_subsys(pa, dce) != NULL; | |||
128 | } | |||
129 | #endif /* _KERNEL */ | |||
130 | ||||
87 | /* | 131 | /* | |
88 | * Descriptions of known PCI classes and subclasses. | 132 | * Descriptions of known PCI classes and subclasses. | |
89 | * | 133 | * | |
90 | * Subclasses are described in the same way as classes, but have a | 134 | * Subclasses are described in the same way as classes, but have a | |
91 | * NULL subclass pointer. | 135 | * NULL subclass pointer. | |
92 | */ | 136 | */ | |
93 | struct pci_class { | 137 | struct pci_class { | |
94 | const char *name; | 138 | const char *name; | |
95 | u_int val; /* as wide as pci_{,sub}class_t */ | 139 | u_int val; /* as wide as pci_{,sub}class_t */ | |
96 | const struct pci_class *subclasses; | 140 | const struct pci_class *subclasses; | |
97 | }; | 141 | }; | |
98 | 142 | |||
99 | /* | 143 | /* |
--- 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,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: pcivar.h,v 1.113 2018/12/01 01:23:24 msaitoh Exp $ */ | 1 | /* $NetBSD: pcivar.h,v 1.114 2021/01/27 05:00:16 thorpej Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. | 4 | * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. | |
5 | * Copyright (c) 1994 Charles M. Hannum. All rights reserved. | 5 | * Copyright (c) 1994 Charles M. Hannum. All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -288,43 +288,59 @@ int pcibusprint(void *, const char *); | @@ -288,43 +288,59 @@ int pcibusprint(void *, const char *); | |||
288 | * e.g. make_tag, conf_read, conf_write are declared by pci_machdep.h.) | 288 | * e.g. make_tag, conf_read, conf_write are declared by pci_machdep.h.) | |
289 | */ | 289 | */ | |
290 | int pci_mapreg_probe(pci_chipset_tag_t, pcitag_t, int, pcireg_t *); | 290 | int pci_mapreg_probe(pci_chipset_tag_t, pcitag_t, int, pcireg_t *); | |
291 | pcireg_t pci_mapreg_type(pci_chipset_tag_t, pcitag_t, int); | 291 | pcireg_t pci_mapreg_type(pci_chipset_tag_t, pcitag_t, int); | |
292 | int pci_mapreg_info(pci_chipset_tag_t, pcitag_t, int, pcireg_t, | 292 | int pci_mapreg_info(pci_chipset_tag_t, pcitag_t, int, pcireg_t, | |
293 | bus_addr_t *, bus_size_t *, int *); | 293 | bus_addr_t *, bus_size_t *, int *); | |
294 | int pci_mapreg_map(const struct pci_attach_args *, int, pcireg_t, int, | 294 | int pci_mapreg_map(const struct pci_attach_args *, int, pcireg_t, int, | |
295 | bus_space_tag_t *, bus_space_handle_t *, bus_addr_t *, | 295 | bus_space_tag_t *, bus_space_handle_t *, bus_addr_t *, | |
296 | bus_size_t *); | 296 | bus_size_t *); | |
297 | int pci_mapreg_submap(const struct pci_attach_args *, int, pcireg_t, int, | 297 | int pci_mapreg_submap(const struct pci_attach_args *, int, pcireg_t, int, | |
298 | bus_size_t, bus_size_t, bus_space_tag_t *, bus_space_handle_t *, | 298 | bus_size_t, bus_size_t, bus_space_tag_t *, bus_space_handle_t *, | |
299 | bus_addr_t *, bus_size_t *); | 299 | bus_addr_t *, bus_size_t *); | |
300 | 300 | |||
301 | ||||
302 | int pci_find_rom(const struct pci_attach_args *, bus_space_tag_t, | 301 | int pci_find_rom(const struct pci_attach_args *, bus_space_tag_t, | |
303 | bus_space_handle_t, bus_size_t, | 302 | bus_space_handle_t, bus_size_t, | |
304 | int, bus_space_handle_t *, bus_size_t *); | 303 | int, bus_space_handle_t *, bus_size_t *); | |
305 | 304 | |||
306 | int pci_get_capability(pci_chipset_tag_t, pcitag_t, int, int *, pcireg_t *); | 305 | int pci_get_capability(pci_chipset_tag_t, pcitag_t, int, int *, pcireg_t *); | |
307 | int pci_get_ht_capability(pci_chipset_tag_t, pcitag_t, int, int *, | 306 | int pci_get_ht_capability(pci_chipset_tag_t, pcitag_t, int, int *, | |
308 | pcireg_t *); | 307 | pcireg_t *); | |
309 | int pci_get_ext_capability(pci_chipset_tag_t, pcitag_t, int, int *, | 308 | int pci_get_ext_capability(pci_chipset_tag_t, pcitag_t, int, int *, | |
310 | pcireg_t *); | 309 | pcireg_t *); | |
311 | 310 | |||
312 | int pci_msi_count(pci_chipset_tag_t, pcitag_t); | 311 | int pci_msi_count(pci_chipset_tag_t, pcitag_t); | |
313 | int pci_msix_count(pci_chipset_tag_t, pcitag_t); | 312 | int pci_msix_count(pci_chipset_tag_t, pcitag_t); | |
314 | 313 | |||
315 | /* | 314 | /* | |
316 | * Helper functions for autoconfiguration. | 315 | * Helper functions for autoconfiguration. | |
317 | */ | 316 | */ | |
317 | ||||
318 | #define PCI_COMPAT_EOL_VALUE (0xffffffffU) | |||
319 | #define PCI_COMPAT_EOL { .id = PCI_COMPAT_EOL_VALUE } | |||
320 | ||||
321 | const struct device_compatible_entry * | |||
322 | pci_compatible_lookup_id(pcireg_t, | |||
323 | const struct device_compatible_entry *); | |||
324 | const struct device_compatible_entry * | |||
325 | pci_compatible_lookup(const struct pci_attach_args *, | |||
326 | const struct device_compatible_entry *); | |||
327 | int pci_compatible_match(const struct pci_attach_args *, | |||
328 | const struct device_compatible_entry *); | |||
329 | const struct device_compatible_entry * | |||
330 | pci_compatible_lookup_subsys(const struct pci_attach_args *, | |||
331 | const struct device_compatible_entry *); | |||
332 | int pci_compatible_match_subsys(const struct pci_attach_args *, | |||
333 | const struct device_compatible_entry *); | |||
318 | #ifndef PCI_MACHDEP_ENUMERATE_BUS | 334 | #ifndef PCI_MACHDEP_ENUMERATE_BUS | |
319 | int pci_enumerate_bus(struct pci_softc *, const int *, | 335 | int pci_enumerate_bus(struct pci_softc *, const int *, | |
320 | int (*)(const struct pci_attach_args *), struct pci_attach_args *); | 336 | int (*)(const struct pci_attach_args *), struct pci_attach_args *); | |
321 | #endif | 337 | #endif | |
322 | int pci_probe_device(struct pci_softc *, pcitag_t tag, | 338 | int pci_probe_device(struct pci_softc *, pcitag_t tag, | |
323 | int (*)(const struct pci_attach_args *), | 339 | int (*)(const struct pci_attach_args *), | |
324 | struct pci_attach_args *); | 340 | struct pci_attach_args *); | |
325 | void pci_devinfo(pcireg_t, pcireg_t, int, char *, size_t); | 341 | void pci_devinfo(pcireg_t, pcireg_t, int, char *, size_t); | |
326 | void pci_aprint_devinfo_fancy(const struct pci_attach_args *, | 342 | void pci_aprint_devinfo_fancy(const struct pci_attach_args *, | |
327 | const char *, const char *, int); | 343 | const char *, const char *, int); | |
328 | #define pci_aprint_devinfo(pap, naive) \ | 344 | #define pci_aprint_devinfo(pap, naive) \ | |
329 | pci_aprint_devinfo_fancy(pap, naive, NULL, 0); | 345 | pci_aprint_devinfo_fancy(pap, naive, NULL, 0); | |
330 | void pci_conf_print(pci_chipset_tag_t, pcitag_t, | 346 | void pci_conf_print(pci_chipset_tag_t, pcitag_t, |