1 /* $NetBSD: pci_machdep.c,v 1.34 2008/04/28 20:23:40 martin 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.34 2008/04/28 20:23:40 martin 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 "acpi.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 NACPI > 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 int pci_mode = -1; 123 124 static void pci_bridge_hook(pci_chipset_tag_t, pcitag_t, void *); 125 struct pci_bridge_hook_arg { 126 void (*func)(pci_chipset_tag_t, pcitag_t, void *); 127 void *arg; 128 }; 129 130 131 __cpu_simple_lock_t pci_conf_lock = __SIMPLELOCK_UNLOCKED; 132 133 #define PCI_CONF_LOCK(s) \ 134 do { \ 135 (s) = splhigh(); \ 136 __cpu_simple_lock(&pci_conf_lock); \ 137 } while (0) 138 139 #define PCI_CONF_UNLOCK(s) \ 140 do { \ 141 __cpu_simple_unlock(&pci_conf_lock); \ 142 splx((s)); \ 143 } while (0) 144 145 #define PCI_MODE1_ENABLE 0x80000000UL 146 #define PCI_MODE1_ADDRESS_REG 0x0cf8 147 #define PCI_MODE1_DATA_REG 0x0cfc 148 149 #define PCI_MODE2_ENABLE_REG 0x0cf8 150 #define PCI_MODE2_FORWARD_REG 0x0cfa 151 152 #define _m1tag(b, d, f) \ 153 (PCI_MODE1_ENABLE | ((b) << 16) | ((d) << 11) | ((f) << 8)) 154 #define _qe(bus, dev, fcn, vend, prod) \ 155 {_m1tag(bus, dev, fcn), PCI_ID_CODE(vend, prod)} 156 struct { 157 uint32_t tag; 158 pcireg_t id; 159 } pcim1_quirk_tbl[] = { 160 _qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX1), 161 /* XXX Triflex2 not tested */ 162 _qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX2), 163 _qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX4), 164 /* Triton needed for Connectix Virtual PC */ 165 _qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82437FX), 166 /* Connectix Virtual PC 5 has a 440BX */ 167 _qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443BX_NOAGP), 168 /* Parallels Desktop for Mac */ 169 _qe(0, 2, 0, PCI_VENDOR_PARALLELS, PCI_PRODUCT_PARALLELS_VIDEO), 170 _qe(0, 3, 0, PCI_VENDOR_PARALLELS, PCI_PRODUCT_PARALLELS_TOOLS), 171 /* SIS 741 */ 172 _qe(0, 0, 0, PCI_VENDOR_SIS, PCI_PRODUCT_SIS_741), 173 {0, 0xffffffff} /* patchable */ 174 }; 175 #undef _m1tag 176 #undef _id 177 #undef _qe 178 179 /* 180 * PCI doesn't have any special needs; just use the generic versions 181 * of these functions. 182 */ 183 struct x86_bus_dma_tag pci_bus_dma_tag = { 184 0, /* tag_needs_free */ 185 #if defined(_LP64) || defined(PAE) 186 PCI32_DMA_BOUNCE_THRESHOLD, /* bounce_thresh */ 187 ISA_DMA_BOUNCE_THRESHOLD, /* bounce_alloclo */ 188 PCI32_DMA_BOUNCE_THRESHOLD, /* bounce_allochi */ 189 #else 190 0, 191 0, 192 0, 193 #endif 194 NULL, /* _may_bounce */ 195 _bus_dmamap_create, 196 _bus_dmamap_destroy, 197 _bus_dmamap_load, 198 _bus_dmamap_load_mbuf, 199 _bus_dmamap_load_uio, 200 _bus_dmamap_load_raw, 201 _bus_dmamap_unload, 202 _bus_dmamap_sync, 203 _bus_dmamem_alloc, 204 _bus_dmamem_free, 205 _bus_dmamem_map, 206 _bus_dmamem_unmap, 207 _bus_dmamem_mmap, 208 _bus_dmatag_subregion, 209 _bus_dmatag_destroy, 210 }; 211 212 #ifdef _LP64 213 struct x86_bus_dma_tag pci_bus_dma64_tag = { 214 0, /* tag_needs_free */ 215 0, 216 0, 217 0, 218 NULL, /* _may_bounce */ 219 _bus_dmamap_create, 220 _bus_dmamap_destroy, 221 _bus_dmamap_load, 222 _bus_dmamap_load_mbuf, 223 _bus_dmamap_load_uio, 224 _bus_dmamap_load_raw, 225 _bus_dmamap_unload, 226 NULL, 227 _bus_dmamem_alloc, 228 _bus_dmamem_free, 229 _bus_dmamem_map, 230 _bus_dmamem_unmap, 231 _bus_dmamem_mmap, 232 _bus_dmatag_subregion, 233 _bus_dmatag_destroy, 234 }; 235 #endif 236 237 void 238 pci_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba) 239 { 240 241 if (pba->pba_bus == 0) 242 aprint_normal(": configuration mode %d", pci_mode); 243 #ifdef MPBIOS 244 mpbios_pci_attach_hook(parent, self, pba); 245 #endif 246 #if NACPI > 0 247 mpacpi_pci_attach_hook(parent, self, pba); 248 #endif 249 } 250 251 int 252 pci_bus_maxdevs(pci_chipset_tag_t pc, int busno) 253 { 254 255 #if defined(__i386__) && defined(XBOX) 256 /* 257 * Scanning above the first device is fatal on the Microsoft Xbox. 258 * If busno=1, only allow for one device. 259 */ 260 if (arch_i386_is_xbox) { 261 if (busno == 1) 262 return 1; 263 else if (busno > 1) 264 return 0; 265 } 266 #endif 267 268 /* 269 * Bus number is irrelevant. If Configuration Mechanism 2 is in 270 * use, can only have devices 0-15 on any bus. If Configuration 271 * Mechanism 1 is in use, can have devices 0-32 (i.e. the `normal' 272 * range). 273 */ 274 if (pci_mode == 2) 275 return (16); 276 else 277 return (32); 278 } 279 280 pcitag_t 281 pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function) 282 { 283 pcitag_t tag; 284 285 #ifndef PCI_CONF_MODE 286 switch (pci_mode) { 287 case 1: 288 goto mode1; 289 case 2: 290 goto mode2; 291 default: 292 panic("pci_make_tag: mode not configured"); 293 } 294 #endif 295 296 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 1) 297 #ifndef PCI_CONF_MODE 298 mode1: 299 #endif 300 if (bus >= 256 || device >= 32 || function >= 8) 301 panic("pci_make_tag: bad request"); 302 303 tag.mode1 = PCI_MODE1_ENABLE | 304 (bus << 16) | (device << 11) | (function << 8); 305 return tag; 306 #endif 307 308 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 2) 309 #ifndef PCI_CONF_MODE 310 mode2: 311 #endif 312 if (bus >= 256 || device >= 16 || function >= 8) 313 panic("pci_make_tag: bad request"); 314 315 tag.mode2.port = 0xc000 | (device << 8); 316 tag.mode2.enable = 0xf0 | (function << 1); 317 tag.mode2.forward = bus; 318 return tag; 319 #endif 320 } 321 322 void 323 pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, 324 int *bp, int *dp, int *fp) 325 { 326 327 #ifndef PCI_CONF_MODE 328 switch (pci_mode) { 329 case 1: 330 goto mode1; 331 case 2: 332 goto mode2; 333 default: 334 panic("pci_decompose_tag: mode not configured"); 335 } 336 #endif 337 338 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 1) 339 #ifndef PCI_CONF_MODE 340 mode1: 341 #endif 342 if (bp != NULL) 343 *bp = (tag.mode1 >> 16) & 0xff; 344 if (dp != NULL) 345 *dp = (tag.mode1 >> 11) & 0x1f; 346 if (fp != NULL) 347 *fp = (tag.mode1 >> 8) & 0x7; 348 return; 349 #endif 350 351 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 2) 352 #ifndef PCI_CONF_MODE 353 mode2: 354 #endif 355 if (bp != NULL) 356 *bp = tag.mode2.forward & 0xff; 357 if (dp != NULL) 358 *dp = (tag.mode2.port >> 8) & 0xf; 359 if (fp != NULL) 360 *fp = (tag.mode2.enable >> 1) & 0x7; 361 #endif 362 } 363 364 pcireg_t 365 pci_conf_read( pci_chipset_tag_t pc, pcitag_t tag, 366 int reg) 367 { 368 pcireg_t data; 369 int s; 370 371 KASSERT((reg & 0x3) == 0); 372 #if defined(__i386__) && defined(XBOX) 373 if (arch_i386_is_xbox) { 374 int bus, dev, fn; 375 pci_decompose_tag(pc, tag, &bus, &dev, &fn); 376 if (bus == 0 && dev == 0 && (fn == 1 || fn == 2)) 377 return (pcireg_t)-1; 378 } 379 #endif 380 381 #ifndef PCI_CONF_MODE 382 switch (pci_mode) { 383 case 1: 384 goto mode1; 385 case 2: 386 goto mode2; 387 default: 388 panic("pci_conf_read: mode not configured"); 389 } 390 #endif 391 392 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 1) 393 #ifndef PCI_CONF_MODE 394 mode1: 395 #endif 396 PCI_CONF_LOCK(s); 397 outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg); 398 data = inl(PCI_MODE1_DATA_REG); 399 outl(PCI_MODE1_ADDRESS_REG, 0); 400 PCI_CONF_UNLOCK(s); 401 return data; 402 #endif 403 404 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 2) 405 #ifndef PCI_CONF_MODE 406 mode2: 407 #endif 408 PCI_CONF_LOCK(s); 409 outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable); 410 outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward); 411 data = inl(tag.mode2.port | reg); 412 outb(PCI_MODE2_ENABLE_REG, 0); 413 PCI_CONF_UNLOCK(s); 414 return data; 415 #endif 416 } 417 418 void 419 pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, 420 pcireg_t data) 421 { 422 int s; 423 424 KASSERT((reg & 0x3) == 0); 425 #if defined(__i386__) && defined(XBOX) 426 if (arch_i386_is_xbox) { 427 int bus, dev, fn; 428 pci_decompose_tag(pc, tag, &bus, &dev, &fn); 429 if (bus == 0 && dev == 0 && (fn == 1 || fn == 2)) 430 return; 431 } 432 #endif 433 434 #ifndef PCI_CONF_MODE 435 switch (pci_mode) { 436 case 1: 437 goto mode1; 438 case 2: 439 goto mode2; 440 default: 441 panic("pci_conf_write: mode not configured"); 442 } 443 #endif 444 445 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 1) 446 #ifndef PCI_CONF_MODE 447 mode1: 448 #endif 449 PCI_CONF_LOCK(s); 450 outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg); 451 outl(PCI_MODE1_DATA_REG, data); 452 outl(PCI_MODE1_ADDRESS_REG, 0); 453 PCI_CONF_UNLOCK(s); 454 return; 455 #endif 456 457 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 2) 458 #ifndef PCI_CONF_MODE 459 mode2: 460 #endif 461 PCI_CONF_LOCK(s); 462 outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable); 463 outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward); 464 outl(tag.mode2.port | reg, data); 465 outb(PCI_MODE2_ENABLE_REG, 0); 466 PCI_CONF_UNLOCK(s); 467 #endif 468 } 469 470 int 471 pci_mode_detect(void) 472 { 473 474 #ifdef PCI_CONF_MODE 475 #if (PCI_CONF_MODE == 1) || (PCI_CONF_MODE == 2) 476 return (pci_mode = PCI_CONF_MODE); 477 #else 478 #error Invalid PCI configuration mode. 479 #endif 480 #else 481 uint32_t sav, val; 482 int i; 483 pcireg_t idreg; 484 485 if (pci_mode != -1) 486 return pci_mode; 487 488 /* 489 * We try to divine which configuration mode the host bridge wants. 490 */ 491 492 sav = inl(PCI_MODE1_ADDRESS_REG); 493 494 pci_mode = 1; /* assume this for now */ 495 /* 496 * catch some known buggy implementations of mode 1 497 */ 498 for (i = 0; i < __arraycount(pcim1_quirk_tbl); i++) { 499 pcitag_t t; 500 501 if (!pcim1_quirk_tbl[i].tag) 502 break; 503 t.mode1 = pcim1_quirk_tbl[i].tag; 504 idreg = pci_conf_read(0, t, PCI_ID_REG); /* needs "pci_mode" */ 505 if (idreg == pcim1_quirk_tbl[i].id) { 506 #ifdef DEBUG 507 printf("known mode 1 PCI chipset (%08x)\n", 508 idreg); 509 #endif 510 return (pci_mode); 511 } 512 } 513 514 /* 515 * Strong check for standard compliant mode 1: 516 * 1. bit 31 ("enable") can be set 517 * 2. byte/word access does not affect register 518 */ 519 outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE); 520 outb(PCI_MODE1_ADDRESS_REG + 3, 0); 521 outw(PCI_MODE1_ADDRESS_REG + 2, 0); 522 val = inl(PCI_MODE1_ADDRESS_REG); 523 if ((val & 0x80fffffc) != PCI_MODE1_ENABLE) { 524 #ifdef DEBUG 525 printf("pci_mode_detect: mode 1 enable failed (%x)\n", 526 val); 527 #endif 528 goto not1; 529 } 530 outl(PCI_MODE1_ADDRESS_REG, 0); 531 val = inl(PCI_MODE1_ADDRESS_REG); 532 if ((val & 0x80fffffc) != 0) 533 goto not1; 534 return (pci_mode); 535 not1: 536 outl(PCI_MODE1_ADDRESS_REG, sav); 537 538 /* 539 * This mode 2 check is quite weak (and known to give false 540 * positives on some Compaq machines). 541 * However, this doesn't matter, because this is the 542 * last test, and simply no PCI devices will be found if 543 * this happens. 544 */ 545 outb(PCI_MODE2_ENABLE_REG, 0); 546 outb(PCI_MODE2_FORWARD_REG, 0); 547 if (inb(PCI_MODE2_ENABLE_REG) != 0 || 548 inb(PCI_MODE2_FORWARD_REG) != 0) 549 goto not2; 550 return (pci_mode = 2); 551 not2: 552 553 return (pci_mode = 0); 554 #endif 555 } 556 557 /* 558 * Determine which flags should be passed to the primary PCI bus's 559 * autoconfiguration node. We use this to detect broken chipsets 560 * which cannot safely use memory-mapped device access. 561 */ 562 int 563 pci_bus_flags() 564 { 565 int rval = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED | 566 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; 567 int device, maxndevs; 568 pcitag_t tag; 569 pcireg_t id; 570 571 maxndevs = pci_bus_maxdevs(NULL, 0); 572 573 for (device = 0; device < maxndevs; device++) { 574 tag = pci_make_tag(NULL, 0, device, 0); 575 id = pci_conf_read(NULL, tag, PCI_ID_REG); 576 577 /* Invalid vendor ID value? */ 578 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID) 579 continue; 580 /* XXX Not invalid, but we've done this ~forever. */ 581 if (PCI_VENDOR(id) == 0) 582 continue; 583 584 switch (PCI_VENDOR(id)) { 585 case PCI_VENDOR_SIS: 586 switch (PCI_PRODUCT(id)) { 587 case PCI_PRODUCT_SIS_85C496: 588 goto disable_mem; 589 } 590 break; 591 } 592 } 593 594 return (rval); 595 596 disable_mem: 597 printf("Warning: broken PCI-Host bridge detected; " 598 "disabling memory-mapped access\n"); 599 rval &= ~(PCI_FLAGS_MEM_ENABLED|PCI_FLAGS_MRL_OKAY|PCI_FLAGS_MRM_OKAY| 600 PCI_FLAGS_MWI_OKAY); 601 return (rval); 602 } 603 604 void 605 pci_device_foreach(pci_chipset_tag_t pc, int maxbus, 606 void (*func)(pci_chipset_tag_t, pcitag_t, void *), void *context) 607 { 608 pci_device_foreach_min(pc, 0, maxbus, func, context); 609 } 610 611 void 612 pci_device_foreach_min(pci_chipset_tag_t pc, int minbus, int maxbus, 613 void (*func)(pci_chipset_tag_t, pcitag_t, void *), void *context) 614 { 615 const struct pci_quirkdata *qd; 616 int bus, device, function, maxdevs, nfuncs; 617 pcireg_t id, bhlcr; 618 pcitag_t tag; 619 620 for (bus = minbus; bus <= maxbus; bus++) { 621 maxdevs = pci_bus_maxdevs(pc, bus); 622 for (device = 0; device < maxdevs; device++) { 623 tag = pci_make_tag(pc, bus, device, 0); 624 id = pci_conf_read(pc, tag, PCI_ID_REG); 625 626 /* Invalid vendor ID value? */ 627 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID) 628 continue; 629 /* XXX Not invalid, but we've done this ~forever. */ 630 if (PCI_VENDOR(id) == 0) 631 continue; 632 633 qd = pci_lookup_quirkdata(PCI_VENDOR(id), 634 PCI_PRODUCT(id)); 635 636 bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG); 637 if (PCI_HDRTYPE_MULTIFN(bhlcr) || 638 (qd != NULL && 639 (qd->quirks & PCI_QUIRK_MULTIFUNCTION) != 0)) 640 nfuncs = 8; 641 else 642 nfuncs = 1; 643 644 for (function = 0; function < nfuncs; function++) { 645 tag = pci_make_tag(pc, bus, device, function); 646 id = pci_conf_read(pc, tag, PCI_ID_REG); 647 648 /* Invalid vendor ID value? */ 649 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID) 650 continue; 651 /* 652 * XXX Not invalid, but we've done this 653 * ~forever. 654 */ 655 if (PCI_VENDOR(id) == 0) 656 continue; 657 (*func)(pc, tag, context); 658 } 659 } 660 } 661 } 662 663 void 664 pci_bridge_foreach(pci_chipset_tag_t pc, int minbus, int maxbus, 665 void (*func)(pci_chipset_tag_t, pcitag_t, void *), void *ctx) 666 { 667 struct pci_bridge_hook_arg bridge_hook; 668 669 bridge_hook.func = func; 670 bridge_hook.arg = ctx; 671 672 pci_device_foreach_min(pc, minbus, maxbus, pci_bridge_hook, 673 &bridge_hook); 674 } 675 676 static void 677 pci_bridge_hook(pci_chipset_tag_t pc, pcitag_t tag, void *ctx) 678 { 679 struct pci_bridge_hook_arg *bridge_hook = (void *)ctx; 680 pcireg_t reg; 681 682 reg = pci_conf_read(pc, tag, PCI_CLASS_REG); 683 if (PCI_CLASS(reg) == PCI_CLASS_BRIDGE && 684 (PCI_SUBCLASS(reg) == PCI_SUBCLASS_BRIDGE_PCI || 685 PCI_SUBCLASS(reg) == PCI_SUBCLASS_BRIDGE_CARDBUS)) { 686 (*bridge_hook->func)(pc, tag, bridge_hook->arg); 687 } 688 } 689