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