xref: /netbsd-src/sys/arch/x86/pci/pci_machdep.c (revision 4e6df137e8e14049b5a701d249962c480449c141)
1 /*	$NetBSD: pci_machdep.c,v 1.40 2010/02/25 20:51:10 dyoung Exp $	*/
2 
3 /*-
4  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9  * NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
35  * Copyright (c) 1994 Charles M. Hannum.  All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. All advertising materials mentioning features or use of this software
46  *    must display the following acknowledgement:
47  *	This product includes software developed by Charles M. Hannum.
48  * 4. The name of the author may not be used to endorse or promote products
49  *    derived from this software without specific prior written permission.
50  *
51  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
52  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
53  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
54  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
55  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
60  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61  */
62 
63 /*
64  * Machine-specific functions for PCI autoconfiguration.
65  *
66  * On PCs, there are two methods of generating PCI configuration cycles.
67  * We try to detect the appropriate mechanism for this machine and set
68  * up a few function pointers to access the correct method directly.
69  *
70  * The configuration method can be hard-coded in the config file by
71  * using `options PCI_CONF_MODE=N', where `N' is the configuration mode
72  * as defined section 3.6.4.1, `Generating Configuration Cycles'.
73  */
74 
75 #include <sys/cdefs.h>
76 __KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.40 2010/02/25 20:51:10 dyoung Exp $");
77 
78 #include <sys/types.h>
79 #include <sys/param.h>
80 #include <sys/time.h>
81 #include <sys/systm.h>
82 #include <sys/errno.h>
83 #include <sys/device.h>
84 #include <sys/bus.h>
85 
86 #include <uvm/uvm_extern.h>
87 
88 #include <machine/bus_private.h>
89 
90 #include <machine/pio.h>
91 #include <machine/lock.h>
92 
93 #include <dev/isa/isareg.h>
94 #include <dev/isa/isavar.h>
95 #include <dev/pci/pcivar.h>
96 #include <dev/pci/pcireg.h>
97 #include <dev/pci/pcidevs.h>
98 
99 #include "acpica.h"
100 #include "opt_mpbios.h"
101 #include "opt_acpi.h"
102 
103 #ifdef MPBIOS
104 #include <machine/mpbiosvar.h>
105 #endif
106 
107 #if NACPICA > 0
108 #include <machine/mpacpi.h>
109 #endif
110 
111 #include <machine/mpconfig.h>
112 
113 #include "opt_pci_conf_mode.h"
114 
115 #ifdef __i386__
116 #include "opt_xbox.h"
117 #ifdef XBOX
118 #include <machine/xbox.h>
119 #endif
120 #endif
121 
122 #ifdef PCI_CONF_MODE
123 #if (PCI_CONF_MODE == 1) || (PCI_CONF_MODE == 2)
124 static int pci_mode = PCI_CONF_MODE;
125 #else
126 #error Invalid PCI configuration mode.
127 #endif
128 #else
129 static int pci_mode = -1;
130 #endif
131 
132 static void pci_bridge_hook(pci_chipset_tag_t, pcitag_t, void *);
133 struct pci_bridge_hook_arg {
134 	void (*func)(pci_chipset_tag_t, pcitag_t, void *);
135 	void *arg;
136 };
137 
138 __cpu_simple_lock_t pci_conf_lock = __SIMPLELOCK_UNLOCKED;
139 
140 #define	PCI_CONF_LOCK(s)						\
141 do {									\
142 	(s) = splhigh();						\
143 	__cpu_simple_lock(&pci_conf_lock);				\
144 } while (0)
145 
146 #define	PCI_CONF_UNLOCK(s)						\
147 do {									\
148 	__cpu_simple_unlock(&pci_conf_lock);				\
149 	splx((s));							\
150 } while (0)
151 
152 #define	PCI_MODE1_ENABLE	0x80000000UL
153 #define	PCI_MODE1_ADDRESS_REG	0x0cf8
154 #define	PCI_MODE1_DATA_REG	0x0cfc
155 
156 #define	PCI_MODE2_ENABLE_REG	0x0cf8
157 #define	PCI_MODE2_FORWARD_REG	0x0cfa
158 
159 #define _m1tag(b, d, f) \
160 	(PCI_MODE1_ENABLE | ((b) << 16) | ((d) << 11) | ((f) << 8))
161 #define _qe(bus, dev, fcn, vend, prod) \
162 	{_m1tag(bus, dev, fcn), PCI_ID_CODE(vend, prod)}
163 struct {
164 	uint32_t tag;
165 	pcireg_t id;
166 } pcim1_quirk_tbl[] = {
167 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX1),
168 	/* XXX Triflex2 not tested */
169 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX2),
170 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX4),
171 	/* Triton needed for Connectix Virtual PC */
172 	_qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82437FX),
173 	/* Connectix Virtual PC 5 has a 440BX */
174 	_qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443BX_NOAGP),
175 	/* Parallels Desktop for Mac */
176 	_qe(0, 2, 0, PCI_VENDOR_PARALLELS, PCI_PRODUCT_PARALLELS_VIDEO),
177 	_qe(0, 3, 0, PCI_VENDOR_PARALLELS, PCI_PRODUCT_PARALLELS_TOOLS),
178 	/* SIS 740 */
179 	_qe(0, 0, 0, PCI_VENDOR_SIS, PCI_PRODUCT_SIS_740),
180 	/* SIS 741 */
181 	_qe(0, 0, 0, PCI_VENDOR_SIS, PCI_PRODUCT_SIS_741),
182 	{0, 0xffffffff} /* patchable */
183 };
184 #undef _m1tag
185 #undef _id
186 #undef _qe
187 
188 /*
189  * PCI doesn't have any special needs; just use the generic versions
190  * of these functions.
191  */
192 struct x86_bus_dma_tag pci_bus_dma_tag = {
193 	0,				/* tag_needs_free */
194 #if defined(_LP64) || defined(PAE)
195 	PCI32_DMA_BOUNCE_THRESHOLD,	/* bounce_thresh */
196 	ISA_DMA_BOUNCE_THRESHOLD,	/* bounce_alloclo */
197 	PCI32_DMA_BOUNCE_THRESHOLD,	/* bounce_allochi */
198 #else
199 	0,
200 	0,
201 	0,
202 #endif
203 	NULL,			/* _may_bounce */
204 	_bus_dmamap_create,
205 	_bus_dmamap_destroy,
206 	_bus_dmamap_load,
207 	_bus_dmamap_load_mbuf,
208 	_bus_dmamap_load_uio,
209 	_bus_dmamap_load_raw,
210 	_bus_dmamap_unload,
211 	_bus_dmamap_sync,
212 	_bus_dmamem_alloc,
213 	_bus_dmamem_free,
214 	_bus_dmamem_map,
215 	_bus_dmamem_unmap,
216 	_bus_dmamem_mmap,
217 	_bus_dmatag_subregion,
218 	_bus_dmatag_destroy,
219 };
220 
221 #ifdef _LP64
222 struct x86_bus_dma_tag pci_bus_dma64_tag = {
223 	0,				/* tag_needs_free */
224 	0,
225 	0,
226 	0,
227 	NULL,			/* _may_bounce */
228 	_bus_dmamap_create,
229 	_bus_dmamap_destroy,
230 	_bus_dmamap_load,
231 	_bus_dmamap_load_mbuf,
232 	_bus_dmamap_load_uio,
233 	_bus_dmamap_load_raw,
234 	_bus_dmamap_unload,
235 	NULL,
236 	_bus_dmamem_alloc,
237 	_bus_dmamem_free,
238 	_bus_dmamem_map,
239 	_bus_dmamem_unmap,
240 	_bus_dmamem_mmap,
241 	_bus_dmatag_subregion,
242 	_bus_dmatag_destroy,
243 };
244 #endif
245 
246 static uint32_t
247 pci_conf_selector(pcitag_t tag, int reg)
248 {
249 	static const pcitag_t mode2_mask = {
250 		.mode2 = {
251 			  .enable = 0xff
252 			, .forward = 0xff
253 		}
254 	};
255 
256 	switch (pci_mode) {
257 	case 1:
258 		return tag.mode1 | reg;
259 	case 2:
260 		return tag.mode1 & mode2_mask.mode1;
261 	default:
262 		panic("%s: mode not configured", __func__);
263 	}
264 }
265 
266 static unsigned int
267 pci_conf_port(pcitag_t tag, int reg)
268 {
269 	switch (pci_mode) {
270 	case 1:
271 		return PCI_MODE1_DATA_REG;
272 	case 2:
273 		return tag.mode2.port | reg;
274 	default:
275 		panic("%s: mode not configured", __func__);
276 	}
277 }
278 
279 static void
280 pci_conf_select(uint32_t addr)
281 {
282 	pcitag_t tag;
283 
284 	switch (pci_mode) {
285 	case 1:
286 		outl(PCI_MODE1_ADDRESS_REG, addr);
287 		return;
288 	case 2:
289 		tag.mode1 = addr;
290 		outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable);
291 		if (tag.mode2.enable != 0)
292 			outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward);
293 		return;
294 	default:
295 		panic("%s: mode not configured", __func__);
296 	}
297 }
298 
299 void
300 pci_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba)
301 {
302 
303 	if (pba->pba_bus == 0)
304 		aprint_normal(": configuration mode %d", pci_mode);
305 #ifdef MPBIOS
306 	mpbios_pci_attach_hook(parent, self, pba);
307 #endif
308 #if NACPICA > 0
309 	mpacpi_pci_attach_hook(parent, self, pba);
310 #endif
311 }
312 
313 int
314 pci_bus_maxdevs(pci_chipset_tag_t pc, int busno)
315 {
316 
317 #if defined(__i386__) && defined(XBOX)
318 	/*
319 	 * Scanning above the first device is fatal on the Microsoft Xbox.
320 	 * If busno=1, only allow for one device.
321 	 */
322 	if (arch_i386_is_xbox) {
323 		if (busno == 1)
324 			return 1;
325 		else if (busno > 1)
326 			return 0;
327 	}
328 #endif
329 
330 	/*
331 	 * Bus number is irrelevant.  If Configuration Mechanism 2 is in
332 	 * use, can only have devices 0-15 on any bus.  If Configuration
333 	 * Mechanism 1 is in use, can have devices 0-32 (i.e. the `normal'
334 	 * range).
335 	 */
336 	if (pci_mode == 2)
337 		return (16);
338 	else
339 		return (32);
340 }
341 
342 pcitag_t
343 pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function)
344 {
345 	pcitag_t tag;
346 
347 	if (pc != NULL && pc->pc_make_tag != NULL)
348 		return (*pc->pc_make_tag)(pc, bus, device, function);
349 
350 	switch (pci_mode) {
351 	case 1:
352 		if (bus >= 256 || device >= 32 || function >= 8)
353 			panic("%s: bad request", __func__);
354 
355 		tag.mode1 = PCI_MODE1_ENABLE |
356 			    (bus << 16) | (device << 11) | (function << 8);
357 		return tag;
358 	case 2:
359 		if (bus >= 256 || device >= 16 || function >= 8)
360 			panic("%s: bad request", __func__);
361 
362 		tag.mode2.port = 0xc000 | (device << 8);
363 		tag.mode2.enable = 0xf0 | (function << 1);
364 		tag.mode2.forward = bus;
365 		return tag;
366 	default:
367 		panic("%s: mode not configured", __func__);
368 	}
369 }
370 
371 void
372 pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag,
373     int *bp, int *dp, int *fp)
374 {
375 
376 	if (pc != NULL && pc->pc_decompose_tag != NULL) {
377 		(*pc->pc_decompose_tag)(pc, tag, bp, dp, fp);
378 		return;
379 	}
380 
381 	switch (pci_mode) {
382 	case 1:
383 		if (bp != NULL)
384 			*bp = (tag.mode1 >> 16) & 0xff;
385 		if (dp != NULL)
386 			*dp = (tag.mode1 >> 11) & 0x1f;
387 		if (fp != NULL)
388 			*fp = (tag.mode1 >> 8) & 0x7;
389 		return;
390 	case 2:
391 		if (bp != NULL)
392 			*bp = tag.mode2.forward & 0xff;
393 		if (dp != NULL)
394 			*dp = (tag.mode2.port >> 8) & 0xf;
395 		if (fp != NULL)
396 			*fp = (tag.mode2.enable >> 1) & 0x7;
397 		return;
398 	default:
399 		panic("%s: mode not configured", __func__);
400 	}
401 }
402 
403 pcireg_t
404 pci_conf_read( pci_chipset_tag_t pc, pcitag_t tag,
405     int reg)
406 {
407 	pcireg_t data;
408 	int s;
409 
410 	KASSERT((reg & 0x3) == 0);
411 
412 	if (pc != NULL && pc->pc_conf_read != NULL)
413 		return (*pc->pc_conf_read)(pc, tag, reg);
414 
415 #if defined(__i386__) && defined(XBOX)
416 	if (arch_i386_is_xbox) {
417 		int bus, dev, fn;
418 		pci_decompose_tag(pc, tag, &bus, &dev, &fn);
419 		if (bus == 0 && dev == 0 && (fn == 1 || fn == 2))
420 			return (pcireg_t)-1;
421 	}
422 #endif
423 
424 	PCI_CONF_LOCK(s);
425 	pci_conf_select(pci_conf_selector(tag, reg));
426 	data = inl(pci_conf_port(tag, reg));
427 	pci_conf_select(0);
428 	PCI_CONF_UNLOCK(s);
429 	return data;
430 }
431 
432 void
433 pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg,
434     pcireg_t data)
435 {
436 	int s;
437 
438 	KASSERT((reg & 0x3) == 0);
439 
440 	if (pc != NULL && pc->pc_conf_write != NULL) {
441 		(*pc->pc_conf_write)(pc, tag, reg, data);
442 		return;
443 	}
444 
445 #if defined(__i386__) && defined(XBOX)
446 	if (arch_i386_is_xbox) {
447 		int bus, dev, fn;
448 		pci_decompose_tag(pc, tag, &bus, &dev, &fn);
449 		if (bus == 0 && dev == 0 && (fn == 1 || fn == 2))
450 			return;
451 	}
452 #endif
453 
454 	PCI_CONF_LOCK(s);
455 	pci_conf_select(pci_conf_selector(tag, reg));
456 	outl(pci_conf_port(tag, reg), data);
457 	pci_conf_select(0);
458 	PCI_CONF_UNLOCK(s);
459 }
460 
461 void
462 pci_mode_set(int mode)
463 {
464 	KASSERT(pci_mode == -1 || pci_mode == mode);
465 
466 	pci_mode = mode;
467 }
468 
469 int
470 pci_mode_detect(void)
471 {
472 	uint32_t sav, val;
473 	int i;
474 	pcireg_t idreg;
475 
476 	if (pci_mode != -1)
477 		return pci_mode;
478 
479 	/*
480 	 * We try to divine which configuration mode the host bridge wants.
481 	 */
482 
483 	sav = inl(PCI_MODE1_ADDRESS_REG);
484 
485 	pci_mode = 1; /* assume this for now */
486 	/*
487 	 * catch some known buggy implementations of mode 1
488 	 */
489 	for (i = 0; i < __arraycount(pcim1_quirk_tbl); i++) {
490 		pcitag_t t;
491 
492 		if (!pcim1_quirk_tbl[i].tag)
493 			break;
494 		t.mode1 = pcim1_quirk_tbl[i].tag;
495 		idreg = pci_conf_read(0, t, PCI_ID_REG); /* needs "pci_mode" */
496 		if (idreg == pcim1_quirk_tbl[i].id) {
497 #ifdef DEBUG
498 			printf("known mode 1 PCI chipset (%08x)\n",
499 			       idreg);
500 #endif
501 			return (pci_mode);
502 		}
503 	}
504 
505 	/*
506 	 * Strong check for standard compliant mode 1:
507 	 * 1. bit 31 ("enable") can be set
508 	 * 2. byte/word access does not affect register
509 	 */
510 	outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE);
511 	outb(PCI_MODE1_ADDRESS_REG + 3, 0);
512 	outw(PCI_MODE1_ADDRESS_REG + 2, 0);
513 	val = inl(PCI_MODE1_ADDRESS_REG);
514 	if ((val & 0x80fffffc) != PCI_MODE1_ENABLE) {
515 #ifdef DEBUG
516 		printf("pci_mode_detect: mode 1 enable failed (%x)\n",
517 		       val);
518 #endif
519 		goto not1;
520 	}
521 	outl(PCI_MODE1_ADDRESS_REG, 0);
522 	val = inl(PCI_MODE1_ADDRESS_REG);
523 	if ((val & 0x80fffffc) != 0)
524 		goto not1;
525 	return (pci_mode);
526 not1:
527 	outl(PCI_MODE1_ADDRESS_REG, sav);
528 
529 	/*
530 	 * This mode 2 check is quite weak (and known to give false
531 	 * positives on some Compaq machines).
532 	 * However, this doesn't matter, because this is the
533 	 * last test, and simply no PCI devices will be found if
534 	 * this happens.
535 	 */
536 	outb(PCI_MODE2_ENABLE_REG, 0);
537 	outb(PCI_MODE2_FORWARD_REG, 0);
538 	if (inb(PCI_MODE2_ENABLE_REG) != 0 ||
539 	    inb(PCI_MODE2_FORWARD_REG) != 0)
540 		goto not2;
541 	return (pci_mode = 2);
542 not2:
543 
544 	return (pci_mode = 0);
545 }
546 
547 /*
548  * Determine which flags should be passed to the primary PCI bus's
549  * autoconfiguration node.  We use this to detect broken chipsets
550  * which cannot safely use memory-mapped device access.
551  */
552 int
553 pci_bus_flags(void)
554 {
555 	int rval = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED |
556 	    PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;
557 	int device, maxndevs;
558 	pcitag_t tag;
559 	pcireg_t id;
560 
561 	maxndevs = pci_bus_maxdevs(NULL, 0);
562 
563 	for (device = 0; device < maxndevs; device++) {
564 		tag = pci_make_tag(NULL, 0, device, 0);
565 		id = pci_conf_read(NULL, tag, PCI_ID_REG);
566 
567 		/* Invalid vendor ID value? */
568 		if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
569 			continue;
570 		/* XXX Not invalid, but we've done this ~forever. */
571 		if (PCI_VENDOR(id) == 0)
572 			continue;
573 
574 		switch (PCI_VENDOR(id)) {
575 		case PCI_VENDOR_SIS:
576 			switch (PCI_PRODUCT(id)) {
577 			case PCI_PRODUCT_SIS_85C496:
578 				goto disable_mem;
579 			}
580 			break;
581 		}
582 	}
583 
584 	return (rval);
585 
586  disable_mem:
587 	printf("Warning: broken PCI-Host bridge detected; "
588 	    "disabling memory-mapped access\n");
589 	rval &= ~(PCI_FLAGS_MEM_ENABLED|PCI_FLAGS_MRL_OKAY|PCI_FLAGS_MRM_OKAY|
590 	    PCI_FLAGS_MWI_OKAY);
591 	return (rval);
592 }
593 
594 void
595 pci_device_foreach(pci_chipset_tag_t pc, int maxbus,
596 	void (*func)(pci_chipset_tag_t, pcitag_t, void *), void *context)
597 {
598 	pci_device_foreach_min(pc, 0, maxbus, func, context);
599 }
600 
601 void
602 pci_device_foreach_min(pci_chipset_tag_t pc, int minbus, int maxbus,
603 	void (*func)(pci_chipset_tag_t, pcitag_t, void *), void *context)
604 {
605 	const struct pci_quirkdata *qd;
606 	int bus, device, function, maxdevs, nfuncs;
607 	pcireg_t id, bhlcr;
608 	pcitag_t tag;
609 
610 	for (bus = minbus; bus <= maxbus; bus++) {
611 		maxdevs = pci_bus_maxdevs(pc, bus);
612 		for (device = 0; device < maxdevs; device++) {
613 			tag = pci_make_tag(pc, bus, device, 0);
614 			id = pci_conf_read(pc, tag, PCI_ID_REG);
615 
616 			/* Invalid vendor ID value? */
617 			if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
618 				continue;
619 			/* XXX Not invalid, but we've done this ~forever. */
620 			if (PCI_VENDOR(id) == 0)
621 				continue;
622 
623 			qd = pci_lookup_quirkdata(PCI_VENDOR(id),
624 				PCI_PRODUCT(id));
625 
626 			bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG);
627 			if (PCI_HDRTYPE_MULTIFN(bhlcr) ||
628 			     (qd != NULL &&
629 		  	     (qd->quirks & PCI_QUIRK_MULTIFUNCTION) != 0))
630 				nfuncs = 8;
631 			else
632 				nfuncs = 1;
633 
634 			for (function = 0; function < nfuncs; function++) {
635 				tag = pci_make_tag(pc, bus, device, function);
636 				id = pci_conf_read(pc, tag, PCI_ID_REG);
637 
638 				/* Invalid vendor ID value? */
639 				if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
640 					continue;
641 				/*
642 				 * XXX Not invalid, but we've done this
643 				 * ~forever.
644 				 */
645 				if (PCI_VENDOR(id) == 0)
646 					continue;
647 				(*func)(pc, tag, context);
648 			}
649 		}
650 	}
651 }
652 
653 void
654 pci_bridge_foreach(pci_chipset_tag_t pc, int minbus, int maxbus,
655 	void (*func)(pci_chipset_tag_t, pcitag_t, void *), void *ctx)
656 {
657 	struct pci_bridge_hook_arg bridge_hook;
658 
659 	bridge_hook.func = func;
660 	bridge_hook.arg = ctx;
661 
662 	pci_device_foreach_min(pc, minbus, maxbus, pci_bridge_hook,
663 		&bridge_hook);
664 }
665 
666 static void
667 pci_bridge_hook(pci_chipset_tag_t pc, pcitag_t tag, void *ctx)
668 {
669 	struct pci_bridge_hook_arg *bridge_hook = (void *)ctx;
670 	pcireg_t reg;
671 
672 	reg = pci_conf_read(pc, tag, PCI_CLASS_REG);
673 	if (PCI_CLASS(reg) == PCI_CLASS_BRIDGE &&
674  	     (PCI_SUBCLASS(reg) == PCI_SUBCLASS_BRIDGE_PCI ||
675 		PCI_SUBCLASS(reg) == PCI_SUBCLASS_BRIDGE_CARDBUS)) {
676 		(*bridge_hook->func)(pc, tag, bridge_hook->arg);
677 	}
678 }
679