xref: /openbsd/sys/arch/i386/pci/pcibios.c (revision 274d7c50)
1 /*	$OpenBSD: pcibios.c,v 1.48 2015/09/08 08:33:26 deraadt 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 int pcibios_present;
105 
106 struct pcibios_pir_header pcibios_pir_header;
107 struct pcibios_intr_routing *pcibios_pir_table;
108 int pcibios_pir_table_nentries;
109 int pcibios_flags = 0;
110 
111 struct bios32_entry pcibios_entry;
112 struct bios32_entry_info pcibios_entry_info;
113 
114 struct pcibios_intr_routing *pcibios_pir_init(struct pcibios_softc *);
115 
116 int	pcibios_get_status(struct pcibios_softc *,
117 	    u_int32_t *, u_int32_t *, u_int32_t *,
118 	    u_int32_t *, u_int32_t *, u_int32_t *, u_int32_t *);
119 int	pcibios_get_intr_routing(struct pcibios_softc *,
120 	    struct pcibios_intr_routing *, int *, u_int16_t *);
121 
122 int	pcibios_return_code(struct pcibios_softc *, u_int16_t, const char *);
123 
124 void	pcibios_print_exclirq(struct pcibios_softc *);
125 void	pcibios_print_pir_table(void);
126 
127 #define	PCI_IRQ_TABLE_START	0xf0000
128 #define	PCI_IRQ_TABLE_END	0xfffff
129 
130 struct cfdriver pcibios_cd = {
131 	NULL, "pcibios", DV_DULL
132 };
133 
134 int pcibiosprobe(struct device *, void *, void *);
135 void pcibiosattach(struct device *, struct device *, void *);
136 
137 struct cfattach pcibios_ca = {
138 	sizeof(struct pcibios_softc), pcibiosprobe, pcibiosattach
139 };
140 
141 int
142 pcibiosprobe(struct device *parent, void *match, void *aux)
143 {
144 	struct bios_attach_args *ba = aux;
145 	u_int32_t rev_maj, rev_min, mech1, mech2, scmech1, scmech2, maxbus;
146 	int rv;
147 
148 	if (strcmp(ba->ba_name, "pcibios"))
149 		return 0;
150 
151 	rv = bios32_service(PCIBIOS_SIGNATURE, &pcibios_entry,
152 		&pcibios_entry_info);
153 
154 	PCIBIOS_PRINTV(("pcibiosprobe: 0x%hx:0x%x at 0x%x[0x%x]\n",
155 	    pcibios_entry.segment, pcibios_entry.offset,
156 	    pcibios_entry_info.bei_base, pcibios_entry_info.bei_size));
157 
158 	return rv &&
159 	    pcibios_get_status(NULL, &rev_maj, &rev_min, &mech1, &mech2,
160 	        &scmech1, &scmech2, &maxbus) == PCIBIOS_SUCCESS;
161 }
162 
163 void
164 pcibiosattach(struct device *parent, struct device *self, void *aux)
165 {
166 	struct pcibios_softc *sc = (struct pcibios_softc *)self;
167 	u_int32_t rev_maj, rev_min, mech1, mech2, scmech1, scmech2;
168 
169 	pcibios_flags = sc->sc_dev.dv_cfdata->cf_flags;
170 
171 	pcibios_get_status((struct pcibios_softc *)self, &rev_maj,
172 	    &rev_min, &mech1, &mech2,
173 	    &scmech1, &scmech2, &sc->max_bus);
174 
175 	printf(": rev %d.%d @ 0x%x/0x%x\n",
176 	    rev_maj, rev_min >> 4, pcibios_entry_info.bei_base,
177 	    pcibios_entry_info.bei_size);
178 
179 	PCIBIOS_PRINTV(("%s: config mechanism %s%s, special cycles %s%s, "
180 	    "last bus %d\n", sc->sc_dev.dv_xname,
181 	    mech1 ? "[1]" : "[x]", mech2 ? "[2]" : "[x]",
182 	    scmech1 ? "[1]" : "[x]", scmech2 ? "[2]" : "[x]", sc->max_bus));
183 
184 	/*
185 	 * The PCI BIOS tells us the config mechanism; fill it in now
186 	 * so that pci_mode_detect() doesn't have to look for it.
187 	 */
188 	pci_mode = mech1 ? 1 : 2;
189 
190 	pcibios_present = 1;
191 
192 	/*
193 	 * Find the PCI IRQ Routing table.
194 	 */
195 
196 	if (!(pcibios_flags & PCIBIOS_INTR_FIXUP) &&
197 	    pcibios_pir_init((struct pcibios_softc *)self) != NULL) {
198 		int rv;
199 
200 		/*
201 		 * Fixup interrupt routing.
202 		 */
203 		rv = pci_intr_fixup(sc, NULL, I386_BUS_SPACE_IO);
204 		switch (rv) {
205 		case -1:
206 			/* Non-fatal error. */
207 			printf("%s: Warning, unable to fix up PCI interrupt "
208 			    "routing\n", sc->sc_dev.dv_xname);
209 			break;
210 
211 		case 1:
212 			/* Fatal error. */
213 			printf("%s: interrupt fixup failed\n", sc->sc_dev.dv_xname);
214 			return;
215 		}
216 
217 		/*
218 		 * XXX Clear `pciirq' from the ISA interrupt allocation
219 		 * XXX mask.
220 		 */
221 	}
222 
223 	if (!(pcibios_flags & PCIBIOS_BUS_FIXUP)) {
224 		sc->max_bus = pci_bus_fixup(NULL, 0);
225 		printf("%s: PCI bus #%d is the last bus\n",
226 		    sc->sc_dev.dv_xname, sc->max_bus);
227 	}
228 
229 	if (!(pcibios_flags & PCIBIOS_ADDR_FIXUP))
230 		pci_addr_fixup(sc, NULL, sc->max_bus);
231 
232 	bios32_cleanup();
233 }
234 
235 struct pcibios_intr_routing *
236 pcibios_pir_init(struct pcibios_softc *sc)
237 {
238 	paddr_t pa;
239 
240 	pcibios_pir_table = NULL;
241 	for (pa = PCI_IRQ_TABLE_START; pa < PCI_IRQ_TABLE_END; pa += 16) {
242 		u_int8_t *p, cksum;
243 		struct pcibios_pir_header *pirh;
244 		int i;
245 
246 		p = ISA_HOLE_VADDR(pa);
247 		pirh = (struct pcibios_pir_header *)p;
248 		/*
249 		 * Some laptops (such as the Toshiba Libretto L series)
250 		 * use _PIR instead of the standard $PIR for the signature
251 		 * so we check for that too.
252 		 */
253 		if (pirh->signature != BIOS32_MAKESIG('$', 'P', 'I', 'R') &&
254 		    pirh->signature != BIOS32_MAKESIG('_', 'P', 'I', 'R'))
255 			continue;
256 
257 		if (pirh->tablesize < sizeof(*pirh))
258 			continue;
259 
260 		cksum = 0;
261 		for (i = 0; i < pirh->tablesize; i++)
262 			cksum += p[i];
263 
264 		printf("%s: PCI IRQ Routing Table rev %d.%d @ 0x%lx/%d "
265 		    "(%zd entries)\n", sc->sc_dev.dv_xname,
266 		    pirh->version >> 8, pirh->version & 0xff, pa,
267 		    pirh->tablesize, (pirh->tablesize - sizeof(*pirh)) / 16);
268 
269 		if (cksum != 0) {
270 			printf("%s: bad IRQ table checksum\n",
271 			    sc->sc_dev.dv_xname);
272 			continue;
273 		}
274 
275 		if (pirh->tablesize % 16 != 0) {
276 			printf("%s: bad IRQ table size\n", sc->sc_dev.dv_xname);
277 			continue;
278 		}
279 
280 		if (pirh->version != 0x0100) {
281 			printf("%s: unsupported IRQ table version\n",
282 			    sc->sc_dev.dv_xname);
283 			continue;
284 		}
285 
286 		/*
287 		 * We can handle this table!  Make a copy of it.
288 		 */
289 		pcibios_pir_header = *pirh;
290 		pcibios_pir_table =
291 		    malloc(pirh->tablesize - sizeof(*pirh), M_DEVBUF, M_NOWAIT);
292 		if (pcibios_pir_table == NULL) {
293 			printf("%s: no memory for $PIR\n", sc->sc_dev.dv_xname);
294 			return NULL;
295 		}
296 		bcopy(p + sizeof(*pirh), pcibios_pir_table,
297 		    pirh->tablesize - sizeof(*pirh));
298 		pcibios_pir_table_nentries =
299 		    (pirh->tablesize - sizeof(*pirh)) / 16;
300 
301 	}
302 
303 	/*
304 	 * If there was no PIR table found, try using the PCI BIOS
305 	 * Get Interrupt Routing call.
306 	 *
307 	 * XXX The interface to this call sucks; just allocate enough
308 	 * XXX room for 32 entries.
309 	 */
310 	if (pcibios_pir_table == NULL) {
311 
312 		pcibios_pir_table_nentries = 32;
313 		pcibios_pir_table = mallocarray(pcibios_pir_table_nentries,
314 		    sizeof(*pcibios_pir_table), M_DEVBUF, M_NOWAIT);
315 		if (pcibios_pir_table == NULL) {
316 			printf("%s: no memory for $PIR\n", sc->sc_dev.dv_xname);
317 			return NULL;
318 		}
319 		if (pcibios_get_intr_routing(sc, pcibios_pir_table,
320 		    &pcibios_pir_table_nentries,
321 		    &pcibios_pir_header.exclusive_irq) != PCIBIOS_SUCCESS) {
322 			printf("%s: PCI IRQ Routing information unavailable.\n",
323 			    sc->sc_dev.dv_xname);
324 			free(pcibios_pir_table, M_DEVBUF,
325 			    pcibios_pir_table_nentries *
326 			    sizeof(*pcibios_pir_table));
327 			pcibios_pir_table = NULL;
328 			pcibios_pir_table_nentries = 0;
329 			return NULL;
330 		}
331 		printf("%s: PCI BIOS has %d Interrupt Routing table entries\n",
332 		    sc->sc_dev.dv_xname, pcibios_pir_table_nentries);
333 	}
334 
335 	pcibios_print_exclirq(sc);
336 	if (pcibios_flags & PCIBIOS_INTRDEBUG)
337 		pcibios_print_pir_table();
338 	return pcibios_pir_table;
339 }
340 
341 int
342 pcibios_get_status(struct pcibios_softc *sc, u_int32_t *rev_maj,
343     u_int32_t *rev_min, u_int32_t *mech1, u_int32_t *mech2, u_int32_t *scmech1,
344     u_int32_t *scmech2, u_int32_t *maxbus)
345 {
346 	u_int32_t ax, bx, cx, edx;
347 	int rv;
348 
349 	__asm volatile("pushl	%%es\n\t"
350 			 "pushl	%%ds\n\t"
351 			 "movw	4(%%edi), %%cx\n\t"
352 			 "movl	%%ecx, %%ds\n\t"
353 			 "lcall	*%%cs:(%%edi)\n\t"
354 			 "pop	%%ds\n\t"
355 			 "pop	%%es\n\t"
356 			 "jc	1f\n\t"
357 			 "xor	%%ah, %%ah\n"
358 		    "1:"
359 		: "=a" (ax), "=b" (bx), "=c" (cx), "=d" (edx)
360 		: "0" (0xb101), "D" (&pcibios_entry)
361 		: "cc", "memory");
362 
363 	rv = pcibios_return_code(sc, ax, "pcibios_get_status");
364 	if (rv != PCIBIOS_SUCCESS)
365 		return (rv);
366 
367 	if (edx != BIOS32_MAKESIG('P', 'C', 'I', ' '))
368 		return (PCIBIOS_SERVICE_NOT_PRESENT);	/* XXX */
369 
370 	/*
371 	 * Fill in the various pieces of info we're looking for.
372 	 */
373 	*mech1 = ax & 1;
374 	*mech2 = ax & (1 << 1);
375 	*scmech1 = ax & (1 << 4);
376 	*scmech2 = ax & (1 << 5);
377 	*rev_maj = (bx >> 8) & 0xff;
378 	*rev_min = bx & 0xff;
379 	*maxbus = cx & 0xff;
380 
381 	return (PCIBIOS_SUCCESS);
382 }
383 
384 int
385 pcibios_get_intr_routing(struct pcibios_softc *sc,
386     struct pcibios_intr_routing *table, int *nentries, u_int16_t *exclirq)
387 {
388 	u_int32_t ax, bx;
389 	int rv;
390 	struct {
391 		u_int16_t size;
392 		u_int32_t offset;
393 		u_int16_t segment;
394 	} __packed args;
395 
396 	args.size = *nentries * sizeof(*table);
397 	args.offset = (u_int32_t)table;
398 	args.segment = GSEL(GDATA_SEL, SEL_KPL);
399 
400 	memset(table, 0, args.size);
401 
402 	__asm volatile("pushl	%%es\n\t"
403 			 "pushl	%%ds\n\t"
404 			 "movw	4(%%esi), %%cx\n\t"
405 			 "movl	%%ecx, %%ds\n\t"
406 			 "lcall	*%%cs:(%%esi)\n\t"
407 			 "popl	%%ds\n\t"
408 			 "popl	%%es\n\t"
409 			 "jc	1f\n\t"
410 			 "xor	%%ah, %%ah\n"
411 		    "1:\n"
412 		: "=a" (ax), "=b" (bx)
413 		: "0" (0xb10e), "1" (0), "D" (&args), "S" (&pcibios_entry)
414 		: "%ecx", "%edx", "cc", "memory");
415 
416 	rv = pcibios_return_code(sc, ax, "pcibios_get_intr_routing");
417 	if (rv != PCIBIOS_SUCCESS)
418 		return (rv);
419 
420 	*nentries = args.size / sizeof(*table);
421 	*exclirq |= bx;
422 
423 	return (PCIBIOS_SUCCESS);
424 }
425 
426 int
427 pcibios_return_code(struct pcibios_softc *sc, u_int16_t ax, const char *func)
428 {
429 	const char *errstr;
430 	int rv = ax >> 8;
431 	char *nam;
432 
433 	if (sc)
434 		nam = sc->sc_dev.dv_xname;
435 	else
436 		nam = "pcibios0";
437 
438 	switch (rv) {
439 	case PCIBIOS_SUCCESS:
440 		return (PCIBIOS_SUCCESS);
441 
442 	case PCIBIOS_SERVICE_NOT_PRESENT:
443 		errstr = "service not present";
444 		break;
445 
446 	case PCIBIOS_FUNCTION_NOT_SUPPORTED:
447 		errstr = "function not supported";
448 		break;
449 
450 	case PCIBIOS_BAD_VENDOR_ID:
451 		errstr = "bad vendor ID";
452 		break;
453 
454 	case PCIBIOS_DEVICE_NOT_FOUND:
455 		errstr = "device not found";
456 		break;
457 
458 	case PCIBIOS_BAD_REGISTER_NUMBER:
459 		errstr = "bad register number";
460 		break;
461 
462 	case PCIBIOS_SET_FAILED:
463 		errstr = "set failed";
464 		break;
465 
466 	case PCIBIOS_BUFFER_TOO_SMALL:
467 		errstr = "buffer too small";
468 		break;
469 
470 	default:
471 		printf("%s: %s - unknown return code 0x%x\n",
472 		    nam, func, rv);
473 		return (rv);
474 	}
475 
476 	printf("%s: %s - %s\n", nam, func, errstr);
477 	return (rv);
478 }
479 
480 void
481 pcibios_print_exclirq(struct pcibios_softc *sc)
482 {
483 	int i;
484 
485 	if (pcibios_pir_header.exclusive_irq) {
486 		printf("%s: PCI Exclusive IRQs:", sc->sc_dev.dv_xname);
487 		for (i = 0; i < 16; i++) {
488 			if (pcibios_pir_header.exclusive_irq & (1 << i))
489 				printf(" %d", i);
490 		}
491 		printf("\n");
492 	}
493 }
494 
495 void
496 pcibios_print_pir_table(void)
497 {
498 	int i, j;
499 
500 	for (i = 0; i < pcibios_pir_table_nentries; i++) {
501 		printf("PIR Entry %d:\n", i);
502 		printf("\tBus: %d  Device: %d\n",
503 		    pcibios_pir_table[i].bus,
504 		    PIR_DEVFUNC_DEVICE(pcibios_pir_table[i].device));
505 		for (j = 0; j < 4; j++) {
506 			printf("\t\tINT%c: link 0x%02x bitmap 0x%04x\n",
507 			    'A' + j,
508 			    pcibios_pir_table[i].linkmap[j].link,
509 			    pcibios_pir_table[i].linkmap[j].bitmap);
510 		}
511 	}
512 }
513 
514 void
515 pci_device_foreach(struct pcibios_softc *sc, pci_chipset_tag_t pc, int maxbus,
516     void (*func)(struct pcibios_softc *, pci_chipset_tag_t, pcitag_t))
517 {
518 	const struct pci_quirkdata *qd;
519 	int bus, device, function, maxdevs, nfuncs;
520 	pcireg_t id, bhlcr;
521 	pcitag_t tag;
522 
523 	for (bus = 0; bus <= maxbus; bus++) {
524 		maxdevs = pci_bus_maxdevs(pc, bus);
525 		for (device = 0; device < maxdevs; device++) {
526 			tag = pci_make_tag(pc, bus, device, 0);
527 			id = pci_conf_read(pc, tag, PCI_ID_REG);
528 
529 			/* Invalid vendor ID value? */
530 			if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
531 				continue;
532 			/* XXX Not invalid, but we've done this ~forever. */
533 			if (PCI_VENDOR(id) == 0)
534 				continue;
535 
536 			qd = pci_lookup_quirkdata(PCI_VENDOR(id),
537 			    PCI_PRODUCT(id));
538 
539 			bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG);
540 			if (PCI_HDRTYPE_MULTIFN(bhlcr) ||
541 			    (qd != NULL &&
542 			     (qd->quirks & PCI_QUIRK_MULTIFUNCTION) != 0))
543 				nfuncs = 8;
544 			else
545 				nfuncs = 1;
546 
547 			for (function = 0; function < nfuncs; function++) {
548 				tag = pci_make_tag(pc, bus, device, function);
549 				id = pci_conf_read(pc, tag, PCI_ID_REG);
550 
551 				/* Invalid vendor ID value? */
552 				if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
553 					continue;
554 				/*
555 				 * XXX Not invalid, but we've done this
556 				 * ~forever.
557 				 */
558 				if (PCI_VENDOR(id) == 0)
559 					continue;
560 				(*func)(sc, pc, tag);
561 			}
562 		}
563 	}
564 }
565