xref: /openbsd/sys/arch/i386/pci/pcibios.c (revision fdc132c9)
1 /*	$OpenBSD: pcibios.c,v 1.50 2024/04/29 00:29:48 jsg Exp $	*/
2 /*	$NetBSD: pcibios.c,v 1.5 2000/08/01 05:23:59 uch Exp $	*/
3 
4 /*
5  * Copyright (c) 2000 Michael Shalayeff
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
21  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 /*-
30  * Copyright (c) 1999 The NetBSD Foundation, Inc.
31  * All rights reserved.
32  *
33  * This code is derived from software contributed to The NetBSD Foundation
34  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
35  * NASA Ames Research Center.
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  *
46  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
47  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
48  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
50  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
51  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
52  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
53  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
54  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
56  * POSSIBILITY OF SUCH DAMAGE.
57  */
58 /*
59  * Copyright (c) 1999, by UCHIYAMA Yasushi
60  * All rights reserved.
61  *
62  * Redistribution and use in source and binary forms, with or without
63  * modification, are permitted provided that the following conditions
64  * are met:
65  * 1. Redistributions of source code must retain the above copyright
66  *    notice, this list of conditions and the following disclaimer.
67  * 2. The name of the developer may NOT be used to endorse or promote products
68  *    derived from this software without specific prior written permission.
69  *
70  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
71  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
72  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
73  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
74  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
75  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
76  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
77  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
78  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
79  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
80  * SUCH DAMAGE.
81  */
82 
83 /*
84  * Interface to the PCI BIOS and PCI Interrupt Routing table.
85  */
86 
87 #include <sys/param.h>
88 #include <sys/systm.h>
89 #include <sys/device.h>
90 #include <sys/malloc.h>
91 
92 #include <dev/isa/isareg.h>
93 #include <i386/isa/isa_machdep.h>
94 
95 #include <dev/pci/pcireg.h>
96 #include <dev/pci/pcivar.h>
97 #include <dev/pci/pcidevs.h>
98 
99 #include <i386/pci/pcibiosvar.h>
100 
101 #include <machine/biosvar.h>
102 
103 int pcibios_flags;
104 
105 struct pcibios_pir_header pcibios_pir_header;
106 struct pcibios_intr_routing *pcibios_pir_table;
107 int pcibios_pir_table_nentries;
108 int pcibios_flags = 0;
109 
110 struct bios32_entry pcibios_entry;
111 struct bios32_entry_info pcibios_entry_info;
112 
113 struct pcibios_intr_routing *pcibios_pir_init(struct pcibios_softc *);
114 
115 int	pcibios_get_status(struct pcibios_softc *,
116 	    u_int32_t *, u_int32_t *, u_int32_t *,
117 	    u_int32_t *, u_int32_t *, u_int32_t *, u_int32_t *);
118 int	pcibios_get_intr_routing(struct pcibios_softc *,
119 	    struct pcibios_intr_routing *, int *, u_int16_t *);
120 
121 int	pcibios_return_code(struct pcibios_softc *, u_int16_t, const char *);
122 
123 void	pcibios_print_exclirq(struct pcibios_softc *);
124 void	pcibios_print_pir_table(void);
125 
126 #define	PCI_IRQ_TABLE_START	0xf0000
127 #define	PCI_IRQ_TABLE_END	0xfffff
128 
129 struct cfdriver pcibios_cd = {
130 	NULL, "pcibios", DV_DULL
131 };
132 
133 int pcibiosprobe(struct device *, void *, void *);
134 void pcibiosattach(struct device *, struct device *, void *);
135 
136 const struct cfattach pcibios_ca = {
137 	sizeof(struct pcibios_softc), pcibiosprobe, pcibiosattach
138 };
139 
140 int
pcibiosprobe(struct device * parent,void * match,void * aux)141 pcibiosprobe(struct device *parent, void *match, void *aux)
142 {
143 	struct bios_attach_args *ba = aux;
144 	u_int32_t rev_maj, rev_min, mech1, mech2, scmech1, scmech2, maxbus;
145 	int rv;
146 
147 	if (strcmp(ba->ba_name, "pcibios"))
148 		return 0;
149 
150 	rv = bios32_service(PCIBIOS_SIGNATURE, &pcibios_entry,
151 		&pcibios_entry_info);
152 
153 	PCIBIOS_PRINTV(("pcibiosprobe: 0x%hx:0x%x at 0x%x[0x%x]\n",
154 	    pcibios_entry.segment, pcibios_entry.offset,
155 	    pcibios_entry_info.bei_base, pcibios_entry_info.bei_size));
156 
157 	return rv &&
158 	    pcibios_get_status(NULL, &rev_maj, &rev_min, &mech1, &mech2,
159 	        &scmech1, &scmech2, &maxbus) == PCIBIOS_SUCCESS;
160 }
161 
162 void
pcibiosattach(struct device * parent,struct device * self,void * aux)163 pcibiosattach(struct device *parent, struct device *self, void *aux)
164 {
165 	struct pcibios_softc *sc = (struct pcibios_softc *)self;
166 	u_int32_t rev_maj, rev_min, mech1, mech2, scmech1, scmech2;
167 
168 	pcibios_flags = sc->sc_dev.dv_cfdata->cf_flags;
169 
170 	pcibios_get_status((struct pcibios_softc *)self, &rev_maj,
171 	    &rev_min, &mech1, &mech2,
172 	    &scmech1, &scmech2, &sc->max_bus);
173 
174 	printf(": rev %d.%d @ 0x%x/0x%x\n",
175 	    rev_maj, rev_min >> 4, pcibios_entry_info.bei_base,
176 	    pcibios_entry_info.bei_size);
177 
178 	PCIBIOS_PRINTV(("%s: config mechanism %s%s, special cycles %s%s, "
179 	    "last bus %d\n", sc->sc_dev.dv_xname,
180 	    mech1 ? "[1]" : "[x]", mech2 ? "[2]" : "[x]",
181 	    scmech1 ? "[1]" : "[x]", scmech2 ? "[2]" : "[x]", sc->max_bus));
182 
183 	/*
184 	 * The PCI BIOS tells us the config mechanism; fill it in now
185 	 * so that pci_mode_detect() doesn't have to look for it.
186 	 */
187 	pci_mode = mech1 ? 1 : 2;
188 
189 	/*
190 	 * Find the PCI IRQ Routing table.
191 	 */
192 
193 	if (!(pcibios_flags & PCIBIOS_INTR_FIXUP) &&
194 	    pcibios_pir_init((struct pcibios_softc *)self) != NULL) {
195 		int rv;
196 
197 		/*
198 		 * Fixup interrupt routing.
199 		 */
200 		rv = pci_intr_fixup(sc, NULL, I386_BUS_SPACE_IO);
201 		switch (rv) {
202 		case -1:
203 			/* Non-fatal error. */
204 			printf("%s: Warning, unable to fix up PCI interrupt "
205 			    "routing\n", sc->sc_dev.dv_xname);
206 			break;
207 
208 		case 1:
209 			/* Fatal error. */
210 			printf("%s: interrupt fixup failed\n", sc->sc_dev.dv_xname);
211 			return;
212 		}
213 
214 		/*
215 		 * XXX Clear `pciirq' from the ISA interrupt allocation
216 		 * XXX mask.
217 		 */
218 	}
219 
220 	if (!(pcibios_flags & PCIBIOS_BUS_FIXUP)) {
221 		sc->max_bus = pci_bus_fixup(NULL, 0);
222 		printf("%s: PCI bus #%d is the last bus\n",
223 		    sc->sc_dev.dv_xname, sc->max_bus);
224 	}
225 
226 	if (!(pcibios_flags & PCIBIOS_ADDR_FIXUP))
227 		pci_addr_fixup(sc, NULL, sc->max_bus);
228 
229 	bios32_cleanup();
230 }
231 
232 struct pcibios_intr_routing *
pcibios_pir_init(struct pcibios_softc * sc)233 pcibios_pir_init(struct pcibios_softc *sc)
234 {
235 	paddr_t pa;
236 
237 	pcibios_pir_table = NULL;
238 	for (pa = PCI_IRQ_TABLE_START; pa < PCI_IRQ_TABLE_END; pa += 16) {
239 		u_int8_t *p, cksum;
240 		struct pcibios_pir_header *pirh;
241 		int i;
242 
243 		p = ISA_HOLE_VADDR(pa);
244 		pirh = (struct pcibios_pir_header *)p;
245 		/*
246 		 * Some laptops (such as the Toshiba Libretto L series)
247 		 * use _PIR instead of the standard $PIR for the signature
248 		 * so we check for that too.
249 		 */
250 		if (pirh->signature != BIOS32_MAKESIG('$', 'P', 'I', 'R') &&
251 		    pirh->signature != BIOS32_MAKESIG('_', 'P', 'I', 'R'))
252 			continue;
253 
254 		if (pirh->tablesize < sizeof(*pirh))
255 			continue;
256 
257 		cksum = 0;
258 		for (i = 0; i < pirh->tablesize; i++)
259 			cksum += p[i];
260 
261 		printf("%s: PCI IRQ Routing Table rev %d.%d @ 0x%lx/%d "
262 		    "(%zd entries)\n", sc->sc_dev.dv_xname,
263 		    pirh->version >> 8, pirh->version & 0xff, pa,
264 		    pirh->tablesize, (pirh->tablesize - sizeof(*pirh)) / 16);
265 
266 		if (cksum != 0) {
267 			printf("%s: bad IRQ table checksum\n",
268 			    sc->sc_dev.dv_xname);
269 			continue;
270 		}
271 
272 		if (pirh->tablesize % 16 != 0) {
273 			printf("%s: bad IRQ table size\n", sc->sc_dev.dv_xname);
274 			continue;
275 		}
276 
277 		if (pirh->version != 0x0100) {
278 			printf("%s: unsupported IRQ table version\n",
279 			    sc->sc_dev.dv_xname);
280 			continue;
281 		}
282 
283 		/*
284 		 * We can handle this table!  Make a copy of it.
285 		 */
286 		pcibios_pir_header = *pirh;
287 		pcibios_pir_table =
288 		    malloc(pirh->tablesize - sizeof(*pirh), M_DEVBUF, M_NOWAIT);
289 		if (pcibios_pir_table == NULL) {
290 			printf("%s: no memory for $PIR\n", sc->sc_dev.dv_xname);
291 			return NULL;
292 		}
293 		bcopy(p + sizeof(*pirh), pcibios_pir_table,
294 		    pirh->tablesize - sizeof(*pirh));
295 		pcibios_pir_table_nentries =
296 		    (pirh->tablesize - sizeof(*pirh)) / 16;
297 
298 	}
299 
300 	/*
301 	 * If there was no PIR table found, try using the PCI BIOS
302 	 * Get Interrupt Routing call.
303 	 *
304 	 * XXX The interface to this call sucks; just allocate enough
305 	 * XXX room for 32 entries.
306 	 */
307 	if (pcibios_pir_table == NULL) {
308 
309 		pcibios_pir_table_nentries = 32;
310 		pcibios_pir_table = mallocarray(pcibios_pir_table_nentries,
311 		    sizeof(*pcibios_pir_table), M_DEVBUF, M_NOWAIT);
312 		if (pcibios_pir_table == NULL) {
313 			printf("%s: no memory for $PIR\n", sc->sc_dev.dv_xname);
314 			return NULL;
315 		}
316 		if (pcibios_get_intr_routing(sc, pcibios_pir_table,
317 		    &pcibios_pir_table_nentries,
318 		    &pcibios_pir_header.exclusive_irq) != PCIBIOS_SUCCESS) {
319 			printf("%s: PCI IRQ Routing information unavailable.\n",
320 			    sc->sc_dev.dv_xname);
321 			free(pcibios_pir_table, M_DEVBUF,
322 			    pcibios_pir_table_nentries *
323 			    sizeof(*pcibios_pir_table));
324 			pcibios_pir_table = NULL;
325 			pcibios_pir_table_nentries = 0;
326 			return NULL;
327 		}
328 		printf("%s: PCI BIOS has %d Interrupt Routing table entries\n",
329 		    sc->sc_dev.dv_xname, pcibios_pir_table_nentries);
330 	}
331 
332 	pcibios_print_exclirq(sc);
333 	if (pcibios_flags & PCIBIOS_INTRDEBUG)
334 		pcibios_print_pir_table();
335 	return pcibios_pir_table;
336 }
337 
338 int
pcibios_get_status(struct pcibios_softc * sc,u_int32_t * rev_maj,u_int32_t * rev_min,u_int32_t * mech1,u_int32_t * mech2,u_int32_t * scmech1,u_int32_t * scmech2,u_int32_t * maxbus)339 pcibios_get_status(struct pcibios_softc *sc, u_int32_t *rev_maj,
340     u_int32_t *rev_min, u_int32_t *mech1, u_int32_t *mech2, u_int32_t *scmech1,
341     u_int32_t *scmech2, u_int32_t *maxbus)
342 {
343 	u_int32_t ax, bx, cx, edx;
344 	int rv;
345 
346 	__asm volatile("pushl	%%es\n\t"
347 			 "pushl	%%ds\n\t"
348 			 "movw	4(%%edi), %%cx\n\t"
349 			 "movl	%%ecx, %%ds\n\t"
350 			 "lcall	*%%cs:(%%edi)\n\t"
351 			 "pop	%%ds\n\t"
352 			 "pop	%%es\n\t"
353 			 "jc	1f\n\t"
354 			 "xor	%%ah, %%ah\n"
355 		    "1:"
356 		: "=a" (ax), "=b" (bx), "=c" (cx), "=d" (edx)
357 		: "0" (0xb101), "D" (&pcibios_entry)
358 		: "cc", "memory");
359 
360 	rv = pcibios_return_code(sc, ax, "pcibios_get_status");
361 	if (rv != PCIBIOS_SUCCESS)
362 		return (rv);
363 
364 	if (edx != BIOS32_MAKESIG('P', 'C', 'I', ' '))
365 		return (PCIBIOS_SERVICE_NOT_PRESENT);	/* XXX */
366 
367 	/*
368 	 * Fill in the various pieces of info we're looking for.
369 	 */
370 	*mech1 = ax & 1;
371 	*mech2 = ax & (1 << 1);
372 	*scmech1 = ax & (1 << 4);
373 	*scmech2 = ax & (1 << 5);
374 	*rev_maj = (bx >> 8) & 0xff;
375 	*rev_min = bx & 0xff;
376 	*maxbus = cx & 0xff;
377 
378 	return (PCIBIOS_SUCCESS);
379 }
380 
381 int
pcibios_get_intr_routing(struct pcibios_softc * sc,struct pcibios_intr_routing * table,int * nentries,u_int16_t * exclirq)382 pcibios_get_intr_routing(struct pcibios_softc *sc,
383     struct pcibios_intr_routing *table, int *nentries, u_int16_t *exclirq)
384 {
385 	u_int32_t ax, bx;
386 	int rv;
387 	struct {
388 		u_int16_t size;
389 		u_int32_t offset;
390 		u_int16_t segment;
391 	} __packed args;
392 
393 	args.size = *nentries * sizeof(*table);
394 	args.offset = (u_int32_t)table;
395 	args.segment = GSEL(GDATA_SEL, SEL_KPL);
396 
397 	memset(table, 0, args.size);
398 
399 	__asm volatile("pushl	%%es\n\t"
400 			 "pushl	%%ds\n\t"
401 			 "movw	4(%%esi), %%cx\n\t"
402 			 "movl	%%ecx, %%ds\n\t"
403 			 "lcall	*%%cs:(%%esi)\n\t"
404 			 "popl	%%ds\n\t"
405 			 "popl	%%es\n\t"
406 			 "jc	1f\n\t"
407 			 "xor	%%ah, %%ah\n"
408 		    "1:\n"
409 		: "=a" (ax), "=b" (bx)
410 		: "0" (0xb10e), "1" (0), "D" (&args), "S" (&pcibios_entry)
411 		: "%ecx", "%edx", "cc", "memory");
412 
413 	rv = pcibios_return_code(sc, ax, "pcibios_get_intr_routing");
414 	if (rv != PCIBIOS_SUCCESS)
415 		return (rv);
416 
417 	*nentries = args.size / sizeof(*table);
418 	*exclirq |= bx;
419 
420 	return (PCIBIOS_SUCCESS);
421 }
422 
423 int
pcibios_return_code(struct pcibios_softc * sc,u_int16_t ax,const char * func)424 pcibios_return_code(struct pcibios_softc *sc, u_int16_t ax, const char *func)
425 {
426 	const char *errstr;
427 	int rv = ax >> 8;
428 	char *nam;
429 
430 	if (sc)
431 		nam = sc->sc_dev.dv_xname;
432 	else
433 		nam = "pcibios0";
434 
435 	switch (rv) {
436 	case PCIBIOS_SUCCESS:
437 		return (PCIBIOS_SUCCESS);
438 
439 	case PCIBIOS_SERVICE_NOT_PRESENT:
440 		errstr = "service not present";
441 		break;
442 
443 	case PCIBIOS_FUNCTION_NOT_SUPPORTED:
444 		errstr = "function not supported";
445 		break;
446 
447 	case PCIBIOS_BAD_VENDOR_ID:
448 		errstr = "bad vendor ID";
449 		break;
450 
451 	case PCIBIOS_DEVICE_NOT_FOUND:
452 		errstr = "device not found";
453 		break;
454 
455 	case PCIBIOS_BAD_REGISTER_NUMBER:
456 		errstr = "bad register number";
457 		break;
458 
459 	case PCIBIOS_SET_FAILED:
460 		errstr = "set failed";
461 		break;
462 
463 	case PCIBIOS_BUFFER_TOO_SMALL:
464 		errstr = "buffer too small";
465 		break;
466 
467 	default:
468 		printf("%s: %s - unknown return code 0x%x\n",
469 		    nam, func, rv);
470 		return (rv);
471 	}
472 
473 	printf("%s: %s - %s\n", nam, func, errstr);
474 	return (rv);
475 }
476 
477 void
pcibios_print_exclirq(struct pcibios_softc * sc)478 pcibios_print_exclirq(struct pcibios_softc *sc)
479 {
480 	int i;
481 
482 	if (pcibios_pir_header.exclusive_irq) {
483 		printf("%s: PCI Exclusive IRQs:", sc->sc_dev.dv_xname);
484 		for (i = 0; i < 16; i++) {
485 			if (pcibios_pir_header.exclusive_irq & (1 << i))
486 				printf(" %d", i);
487 		}
488 		printf("\n");
489 	}
490 }
491 
492 void
pcibios_print_pir_table(void)493 pcibios_print_pir_table(void)
494 {
495 	int i, j;
496 
497 	for (i = 0; i < pcibios_pir_table_nentries; i++) {
498 		printf("PIR Entry %d:\n", i);
499 		printf("\tBus: %d  Device: %d\n",
500 		    pcibios_pir_table[i].bus,
501 		    PIR_DEVFUNC_DEVICE(pcibios_pir_table[i].device));
502 		for (j = 0; j < 4; j++) {
503 			printf("\t\tINT%c: link 0x%02x bitmap 0x%04x\n",
504 			    'A' + j,
505 			    pcibios_pir_table[i].linkmap[j].link,
506 			    pcibios_pir_table[i].linkmap[j].bitmap);
507 		}
508 	}
509 }
510 
511 void
pci_device_foreach(struct pcibios_softc * sc,pci_chipset_tag_t pc,int maxbus,void (* func)(struct pcibios_softc *,pci_chipset_tag_t,pcitag_t))512 pci_device_foreach(struct pcibios_softc *sc, pci_chipset_tag_t pc, int maxbus,
513     void (*func)(struct pcibios_softc *, pci_chipset_tag_t, pcitag_t))
514 {
515 	const struct pci_quirkdata *qd;
516 	int bus, device, function, maxdevs, nfuncs;
517 	pcireg_t id, bhlcr;
518 	pcitag_t tag;
519 
520 	for (bus = 0; bus <= maxbus; bus++) {
521 		maxdevs = pci_bus_maxdevs(pc, bus);
522 		for (device = 0; device < maxdevs; device++) {
523 			tag = pci_make_tag(pc, bus, device, 0);
524 			id = pci_conf_read(pc, tag, PCI_ID_REG);
525 
526 			/* Invalid vendor ID value? */
527 			if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
528 				continue;
529 			/* XXX Not invalid, but we've done this ~forever. */
530 			if (PCI_VENDOR(id) == 0)
531 				continue;
532 
533 			qd = pci_lookup_quirkdata(PCI_VENDOR(id),
534 			    PCI_PRODUCT(id));
535 
536 			bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG);
537 			if (PCI_HDRTYPE_MULTIFN(bhlcr) ||
538 			    (qd != NULL &&
539 			     (qd->quirks & PCI_QUIRK_MULTIFUNCTION) != 0))
540 				nfuncs = 8;
541 			else
542 				nfuncs = 1;
543 
544 			for (function = 0; function < nfuncs; function++) {
545 				tag = pci_make_tag(pc, bus, device, function);
546 				id = pci_conf_read(pc, tag, PCI_ID_REG);
547 
548 				/* Invalid vendor ID value? */
549 				if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
550 					continue;
551 				/*
552 				 * XXX Not invalid, but we've done this
553 				 * ~forever.
554 				 */
555 				if (PCI_VENDOR(id) == 0)
556 					continue;
557 				(*func)(sc, pc, tag);
558 			}
559 		}
560 	}
561 }
562