1 /*- 2 * Copyright (c) 2015, 2020 Ruslan Bukin <br@bsdpad.com> 3 * Copyright (c) 2014 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * This software was developed by Semihalf under 7 * the sponsorship of the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 /* Generic ECAM PCIe driver */ 32 33 #include <sys/cdefs.h> 34 #include "opt_platform.h" 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/malloc.h> 39 #include <sys/kernel.h> 40 #include <sys/rman.h> 41 #include <sys/module.h> 42 #include <sys/bus.h> 43 #include <sys/endian.h> 44 45 #include <dev/pci/pcivar.h> 46 #include <dev/pci/pcireg.h> 47 #include <dev/pci/pcib_private.h> 48 #include <dev/pci/pci_host_generic.h> 49 50 #include <machine/bus.h> 51 #include <machine/intr.h> 52 53 #include "pcib_if.h" 54 55 #if defined(VM_MEMATTR_DEVICE_NP) 56 #define PCI_UNMAPPED 57 #define PCI_RF_FLAGS RF_UNMAPPED 58 #else 59 #define PCI_RF_FLAGS 0 60 #endif 61 62 /* 63 * We allocate "ranges" specified mappings higher up in the rid space to avoid 64 * conflicts with various definitions in the wild that may have other registers 65 * attributed to the controller besides just the config space. 66 */ 67 #define RANGE_RID(idx) ((idx) + 100) 68 69 /* Forward prototypes */ 70 71 static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot, 72 u_int func, u_int reg, int bytes); 73 static void generic_pcie_write_config(device_t dev, u_int bus, u_int slot, 74 u_int func, u_int reg, uint32_t val, int bytes); 75 static int generic_pcie_maxslots(device_t dev); 76 static int generic_pcie_write_ivar(device_t dev, device_t child, int index, 77 uintptr_t value); 78 79 int 80 pci_host_generic_core_attach(device_t dev) 81 { 82 #ifdef PCI_UNMAPPED 83 struct resource_map_request req; 84 struct resource_map map; 85 #endif 86 struct generic_pcie_core_softc *sc; 87 struct rman *rm; 88 uint64_t phys_base; 89 uint64_t pci_base; 90 uint64_t size; 91 const char *range_descr; 92 char buf[64]; 93 int domain, error; 94 int flags, rid, tuple; 95 96 sc = device_get_softc(dev); 97 sc->dev = dev; 98 99 /* Create the parent DMA tag to pass down the coherent flag */ 100 error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 101 1, 0, /* alignment, bounds */ 102 BUS_SPACE_MAXADDR, /* lowaddr */ 103 BUS_SPACE_MAXADDR, /* highaddr */ 104 NULL, NULL, /* filter, filterarg */ 105 BUS_SPACE_MAXSIZE, /* maxsize */ 106 BUS_SPACE_UNRESTRICTED, /* nsegments */ 107 BUS_SPACE_MAXSIZE, /* maxsegsize */ 108 sc->coherent ? BUS_DMA_COHERENT : 0, /* flags */ 109 NULL, NULL, /* lockfunc, lockarg */ 110 &sc->dmat); 111 if (error != 0) 112 return (error); 113 114 /* 115 * Attempt to set the domain. If it's missing, or we are unable to 116 * set it then memory allocations may be placed in the wrong domain. 117 */ 118 if (bus_get_domain(dev, &domain) == 0) 119 (void)bus_dma_tag_set_domain(sc->dmat, domain); 120 121 if ((sc->quirks & PCIE_CUSTOM_CONFIG_SPACE_QUIRK) == 0) { 122 rid = 0; 123 sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 124 PCI_RF_FLAGS | RF_ACTIVE); 125 if (sc->res == NULL) { 126 device_printf(dev, "could not allocate memory.\n"); 127 error = ENXIO; 128 goto err_resource; 129 } 130 #ifdef PCI_UNMAPPED 131 resource_init_map_request(&req); 132 req.memattr = VM_MEMATTR_DEVICE_NP; 133 error = bus_map_resource(dev, SYS_RES_MEMORY, sc->res, &req, 134 &map); 135 if (error != 0) { 136 device_printf(dev, "could not map memory.\n"); 137 return (error); 138 } 139 rman_set_mapping(sc->res, &map); 140 #endif 141 } 142 143 sc->has_pmem = false; 144 sc->pmem_rman.rm_type = RMAN_ARRAY; 145 snprintf(buf, sizeof(buf), "%s prefetch window", 146 device_get_nameunit(dev)); 147 sc->pmem_rman.rm_descr = strdup(buf, M_DEVBUF); 148 149 sc->mem_rman.rm_type = RMAN_ARRAY; 150 snprintf(buf, sizeof(buf), "%s memory window", 151 device_get_nameunit(dev)); 152 sc->mem_rman.rm_descr = strdup(buf, M_DEVBUF); 153 154 sc->io_rman.rm_type = RMAN_ARRAY; 155 snprintf(buf, sizeof(buf), "%s I/O port window", 156 device_get_nameunit(dev)); 157 sc->io_rman.rm_descr = strdup(buf, M_DEVBUF); 158 159 /* Initialize rman and allocate memory regions */ 160 error = rman_init(&sc->pmem_rman); 161 if (error) { 162 device_printf(dev, "rman_init() failed. error = %d\n", error); 163 goto err_pmem_rman; 164 } 165 166 error = rman_init(&sc->mem_rman); 167 if (error) { 168 device_printf(dev, "rman_init() failed. error = %d\n", error); 169 goto err_mem_rman; 170 } 171 172 error = rman_init(&sc->io_rman); 173 if (error) { 174 device_printf(dev, "rman_init() failed. error = %d\n", error); 175 goto err_io_rman; 176 } 177 178 for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) { 179 phys_base = sc->ranges[tuple].phys_base; 180 pci_base = sc->ranges[tuple].pci_base; 181 size = sc->ranges[tuple].size; 182 rid = RANGE_RID(tuple); 183 if (size == 0) 184 continue; /* empty range element */ 185 switch (FLAG_TYPE(sc->ranges[tuple].flags)) { 186 case FLAG_TYPE_PMEM: 187 sc->has_pmem = true; 188 range_descr = "prefetch"; 189 flags = RF_PREFETCHABLE; 190 rm = &sc->pmem_rman; 191 break; 192 case FLAG_TYPE_MEM: 193 range_descr = "memory"; 194 flags = 0; 195 rm = &sc->mem_rman; 196 break; 197 case FLAG_TYPE_IO: 198 range_descr = "I/O port"; 199 flags = 0; 200 rm = &sc->io_rman; 201 break; 202 default: 203 continue; 204 } 205 if (bootverbose) 206 device_printf(dev, 207 "PCI addr: 0x%jx, CPU addr: 0x%jx, Size: 0x%jx, Type: %s\n", 208 pci_base, phys_base, size, range_descr); 209 error = bus_set_resource(dev, SYS_RES_MEMORY, rid, phys_base, 210 size); 211 if (error != 0) { 212 device_printf(dev, 213 "failed to set resource for range %d: %d\n", tuple, 214 error); 215 continue; 216 } 217 sc->ranges[tuple].rid = rid; 218 sc->ranges[tuple].res = bus_alloc_resource_any(dev, 219 SYS_RES_MEMORY, &rid, RF_ACTIVE | RF_UNMAPPED | flags); 220 if (sc->ranges[tuple].res == NULL) { 221 device_printf(dev, 222 "failed to allocate resource for range %d\n", tuple); 223 continue; 224 } 225 error = rman_manage_region(rm, pci_base, pci_base + size - 1); 226 if (error) { 227 device_printf(dev, "rman_manage_region() failed." 228 "error = %d\n", error); 229 continue; 230 } 231 } 232 233 return (0); 234 235 err_io_rman: 236 rman_fini(&sc->mem_rman); 237 err_mem_rman: 238 rman_fini(&sc->pmem_rman); 239 err_pmem_rman: 240 free(__DECONST(char *, sc->io_rman.rm_descr), M_DEVBUF); 241 free(__DECONST(char *, sc->mem_rman.rm_descr), M_DEVBUF); 242 free(__DECONST(char *, sc->pmem_rman.rm_descr), M_DEVBUF); 243 if (sc->res != NULL) 244 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->res); 245 err_resource: 246 bus_dma_tag_destroy(sc->dmat); 247 return (error); 248 } 249 250 int 251 pci_host_generic_core_detach(device_t dev) 252 { 253 int error; 254 255 error = bus_generic_detach(dev); 256 if (error != 0) 257 return (error); 258 259 return (pci_host_generic_core_free(dev)); 260 } 261 262 int 263 pci_host_generic_core_free(device_t dev) 264 { 265 struct generic_pcie_core_softc *sc; 266 int rid, tuple; 267 268 sc = device_get_softc(dev); 269 for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) { 270 rid = sc->ranges[tuple].rid; 271 if (sc->ranges[tuple].size == 0) { 272 MPASS(sc->ranges[tuple].res == NULL); 273 continue; /* empty range element */ 274 } 275 276 MPASS(rid != -1); 277 switch (FLAG_TYPE(sc->ranges[tuple].flags)) { 278 case FLAG_TYPE_PMEM: 279 case FLAG_TYPE_MEM: 280 case FLAG_TYPE_IO: 281 break; 282 default: 283 continue; 284 } 285 if (sc->ranges[tuple].res != NULL) 286 bus_release_resource(dev, SYS_RES_MEMORY, rid, 287 sc->ranges[tuple].res); 288 bus_delete_resource(dev, SYS_RES_MEMORY, rid); 289 } 290 rman_fini(&sc->io_rman); 291 rman_fini(&sc->mem_rman); 292 rman_fini(&sc->pmem_rman); 293 free(__DECONST(char *, sc->io_rman.rm_descr), M_DEVBUF); 294 free(__DECONST(char *, sc->mem_rman.rm_descr), M_DEVBUF); 295 free(__DECONST(char *, sc->pmem_rman.rm_descr), M_DEVBUF); 296 if (sc->res != NULL) 297 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->res); 298 bus_dma_tag_destroy(sc->dmat); 299 300 return (0); 301 } 302 303 static uint32_t 304 generic_pcie_read_config(device_t dev, u_int bus, u_int slot, 305 u_int func, u_int reg, int bytes) 306 { 307 struct generic_pcie_core_softc *sc; 308 uint64_t offset; 309 uint32_t data; 310 311 sc = device_get_softc(dev); 312 if ((bus < sc->bus_start) || (bus > sc->bus_end)) 313 return (~0U); 314 if ((slot > PCI_SLOTMAX) || (func > PCI_FUNCMAX) || 315 (reg > PCIE_REGMAX)) 316 return (~0U); 317 if ((sc->quirks & PCIE_ECAM_DESIGNWARE_QUIRK) && bus == 0 && slot > 0) 318 return (~0U); 319 320 offset = PCIE_ADDR_OFFSET(bus - sc->bus_start, slot, func, reg); 321 322 switch (bytes) { 323 case 1: 324 data = bus_read_1(sc->res, offset); 325 break; 326 case 2: 327 data = le16toh(bus_read_2(sc->res, offset)); 328 break; 329 case 4: 330 data = le32toh(bus_read_4(sc->res, offset)); 331 break; 332 default: 333 return (~0U); 334 } 335 336 return (data); 337 } 338 339 static void 340 generic_pcie_write_config(device_t dev, u_int bus, u_int slot, 341 u_int func, u_int reg, uint32_t val, int bytes) 342 { 343 struct generic_pcie_core_softc *sc; 344 uint64_t offset; 345 346 sc = device_get_softc(dev); 347 if ((bus < sc->bus_start) || (bus > sc->bus_end)) 348 return; 349 if ((slot > PCI_SLOTMAX) || (func > PCI_FUNCMAX) || 350 (reg > PCIE_REGMAX)) 351 return; 352 353 offset = PCIE_ADDR_OFFSET(bus - sc->bus_start, slot, func, reg); 354 355 switch (bytes) { 356 case 1: 357 bus_write_1(sc->res, offset, val); 358 break; 359 case 2: 360 bus_write_2(sc->res, offset, htole16(val)); 361 break; 362 case 4: 363 bus_write_4(sc->res, offset, htole32(val)); 364 break; 365 default: 366 return; 367 } 368 } 369 370 static int 371 generic_pcie_maxslots(device_t dev) 372 { 373 374 return (31); /* max slots per bus acc. to standard */ 375 } 376 377 int 378 generic_pcie_read_ivar(device_t dev, device_t child, int index, 379 uintptr_t *result) 380 { 381 struct generic_pcie_core_softc *sc; 382 383 sc = device_get_softc(dev); 384 switch (index) { 385 case PCIB_IVAR_BUS: 386 *result = sc->bus_start; 387 return (0); 388 case PCIB_IVAR_DOMAIN: 389 *result = sc->ecam; 390 return (0); 391 } 392 393 if (bootverbose) 394 device_printf(dev, "ERROR: Unknown index %d.\n", index); 395 return (ENOENT); 396 } 397 398 static int 399 generic_pcie_write_ivar(device_t dev, device_t child, int index, 400 uintptr_t value) 401 { 402 403 return (ENOENT); 404 } 405 406 static struct rman * 407 generic_pcie_get_rman(device_t dev, int type, u_int flags) 408 { 409 struct generic_pcie_core_softc *sc = device_get_softc(dev); 410 411 switch (type) { 412 case SYS_RES_IOPORT: 413 return (&sc->io_rman); 414 case SYS_RES_MEMORY: 415 if (sc->has_pmem && (flags & RF_PREFETCHABLE) != 0) 416 return (&sc->pmem_rman); 417 return (&sc->mem_rman); 418 default: 419 break; 420 } 421 422 return (NULL); 423 } 424 425 int 426 pci_host_generic_core_release_resource(device_t dev, device_t child, 427 struct resource *res) 428 { 429 struct generic_pcie_core_softc *sc; 430 431 sc = device_get_softc(dev); 432 switch (rman_get_type(res)) { 433 case PCI_RES_BUS: 434 return (pci_domain_release_bus(sc->ecam, child, res)); 435 case SYS_RES_IOPORT: 436 case SYS_RES_MEMORY: 437 return (bus_generic_rman_release_resource(dev, child, res)); 438 default: 439 return (bus_generic_release_resource(dev, child, res)); 440 } 441 } 442 443 static struct pcie_range * 444 generic_pcie_containing_range(device_t dev, int type, rman_res_t start, 445 rman_res_t end) 446 { 447 struct generic_pcie_core_softc *sc = device_get_softc(dev); 448 uint64_t pci_base; 449 uint64_t size; 450 int i, space; 451 452 switch (type) { 453 case SYS_RES_IOPORT: 454 case SYS_RES_MEMORY: 455 break; 456 default: 457 return (NULL); 458 } 459 460 for (i = 0; i < MAX_RANGES_TUPLES; i++) { 461 pci_base = sc->ranges[i].pci_base; 462 size = sc->ranges[i].size; 463 if (size == 0) 464 continue; /* empty range element */ 465 466 if (start < pci_base || end >= pci_base + size) 467 continue; 468 469 switch (FLAG_TYPE(sc->ranges[i].flags)) { 470 case FLAG_TYPE_MEM: 471 case FLAG_TYPE_PMEM: 472 space = SYS_RES_MEMORY; 473 break; 474 case FLAG_TYPE_IO: 475 space = SYS_RES_IOPORT; 476 break; 477 default: 478 continue; 479 } 480 481 if (type == space) 482 return (&sc->ranges[i]); 483 } 484 return (NULL); 485 } 486 487 static int 488 generic_pcie_translate_resource(device_t dev, int type, rman_res_t start, 489 rman_res_t *new_start) 490 { 491 struct pcie_range *range; 492 493 /* Translate the address from a PCI address to a physical address */ 494 switch (type) { 495 case SYS_RES_IOPORT: 496 case SYS_RES_MEMORY: 497 range = generic_pcie_containing_range(dev, type, start, start); 498 if (range == NULL) 499 return (ENOENT); 500 *new_start = start - range->pci_base + range->phys_base; 501 break; 502 default: 503 /* No translation for non-memory types */ 504 *new_start = start; 505 break; 506 } 507 508 return (0); 509 } 510 511 struct resource * 512 pci_host_generic_core_alloc_resource(device_t dev, device_t child, int type, 513 int rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 514 { 515 struct generic_pcie_core_softc *sc; 516 struct resource *res; 517 518 sc = device_get_softc(dev); 519 520 switch (type) { 521 case PCI_RES_BUS: 522 res = pci_domain_alloc_bus(sc->ecam, child, rid, start, end, 523 count, flags); 524 break; 525 case SYS_RES_IOPORT: 526 case SYS_RES_MEMORY: 527 res = bus_generic_rman_alloc_resource(dev, child, type, rid, 528 start, end, count, flags); 529 break; 530 default: 531 res = bus_generic_alloc_resource(dev, child, type, rid, start, 532 end, count, flags); 533 break; 534 } 535 if (res == NULL) { 536 device_printf(dev, "%s FAIL: type=%d, rid=%d, " 537 "start=%016jx, end=%016jx, count=%016jx, flags=%x\n", 538 __func__, type, rid, start, end, count, flags); 539 } 540 return (res); 541 } 542 543 static int 544 generic_pcie_activate_resource(device_t dev, device_t child, struct resource *r) 545 { 546 struct generic_pcie_core_softc *sc; 547 548 sc = device_get_softc(dev); 549 switch (rman_get_type(r)) { 550 case PCI_RES_BUS: 551 return (pci_domain_activate_bus(sc->ecam, child, r)); 552 case SYS_RES_IOPORT: 553 case SYS_RES_MEMORY: 554 return (bus_generic_rman_activate_resource(dev, child, r)); 555 default: 556 return (bus_generic_activate_resource(dev, child, r)); 557 } 558 } 559 560 static int 561 generic_pcie_deactivate_resource(device_t dev, device_t child, 562 struct resource *r) 563 { 564 struct generic_pcie_core_softc *sc; 565 566 sc = device_get_softc(dev); 567 switch (rman_get_type(r)) { 568 case PCI_RES_BUS: 569 return (pci_domain_deactivate_bus(sc->ecam, child, r)); 570 case SYS_RES_IOPORT: 571 case SYS_RES_MEMORY: 572 return (bus_generic_rman_deactivate_resource(dev, child, r)); 573 default: 574 return (bus_generic_deactivate_resource(dev, child, r)); 575 } 576 } 577 578 static int 579 generic_pcie_adjust_resource(device_t dev, device_t child, 580 struct resource *res, rman_res_t start, rman_res_t end) 581 { 582 struct generic_pcie_core_softc *sc; 583 584 sc = device_get_softc(dev); 585 switch (rman_get_type(res)) { 586 case PCI_RES_BUS: 587 return (pci_domain_adjust_bus(sc->ecam, child, res, start, 588 end)); 589 case SYS_RES_IOPORT: 590 case SYS_RES_MEMORY: 591 return (bus_generic_rman_adjust_resource(dev, child, res, 592 start, end)); 593 default: 594 return (bus_generic_adjust_resource(dev, child, res, start, 595 end)); 596 } 597 } 598 599 static int 600 generic_pcie_map_resource(device_t dev, device_t child, struct resource *r, 601 struct resource_map_request *argsp, struct resource_map *map) 602 { 603 struct resource_map_request args; 604 struct pcie_range *range; 605 rman_res_t length, start; 606 int error, type; 607 608 type = rman_get_type(r); 609 switch (type) { 610 case PCI_RES_BUS: 611 return (EINVAL); 612 case SYS_RES_IOPORT: 613 case SYS_RES_MEMORY: 614 break; 615 default: 616 return (bus_generic_map_resource(dev, child, r, argsp, map)); 617 } 618 619 /* Resources must be active to be mapped. */ 620 if (!(rman_get_flags(r) & RF_ACTIVE)) 621 return (ENXIO); 622 623 resource_init_map_request(&args); 624 error = resource_validate_map_request(r, argsp, &args, &start, &length); 625 if (error) 626 return (error); 627 628 range = generic_pcie_containing_range(dev, type, rman_get_start(r), 629 rman_get_end(r)); 630 if (range == NULL || range->res == NULL) 631 return (ENOENT); 632 633 args.offset = start - range->pci_base; 634 args.length = length; 635 return (bus_map_resource(dev, range->res, &args, map)); 636 } 637 638 static int 639 generic_pcie_unmap_resource(device_t dev, device_t child, struct resource *r, 640 struct resource_map *map) 641 { 642 struct pcie_range *range; 643 int type; 644 645 type = rman_get_type(r); 646 switch (type) { 647 case PCI_RES_BUS: 648 return (EINVAL); 649 case SYS_RES_IOPORT: 650 case SYS_RES_MEMORY: 651 break; 652 default: 653 return (bus_generic_unmap_resource(dev, child, r, map)); 654 } 655 656 range = generic_pcie_containing_range(dev, type, rman_get_start(r), 657 rman_get_end(r)); 658 if (range == NULL || range->res == NULL) 659 return (ENOENT); 660 return (bus_unmap_resource(dev, range->res, map)); 661 } 662 663 static bus_dma_tag_t 664 generic_pcie_get_dma_tag(device_t dev, device_t child) 665 { 666 struct generic_pcie_core_softc *sc; 667 668 sc = device_get_softc(dev); 669 return (sc->dmat); 670 } 671 672 static device_method_t generic_pcie_methods[] = { 673 DEVMETHOD(device_attach, pci_host_generic_core_attach), 674 DEVMETHOD(device_detach, pci_host_generic_core_detach), 675 676 DEVMETHOD(bus_get_rman, generic_pcie_get_rman), 677 DEVMETHOD(bus_read_ivar, generic_pcie_read_ivar), 678 DEVMETHOD(bus_write_ivar, generic_pcie_write_ivar), 679 DEVMETHOD(bus_alloc_resource, pci_host_generic_core_alloc_resource), 680 DEVMETHOD(bus_adjust_resource, generic_pcie_adjust_resource), 681 DEVMETHOD(bus_activate_resource, generic_pcie_activate_resource), 682 DEVMETHOD(bus_deactivate_resource, generic_pcie_deactivate_resource), 683 DEVMETHOD(bus_release_resource, pci_host_generic_core_release_resource), 684 DEVMETHOD(bus_translate_resource, generic_pcie_translate_resource), 685 DEVMETHOD(bus_map_resource, generic_pcie_map_resource), 686 DEVMETHOD(bus_unmap_resource, generic_pcie_unmap_resource), 687 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 688 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 689 690 DEVMETHOD(bus_get_dma_tag, generic_pcie_get_dma_tag), 691 692 /* pcib interface */ 693 DEVMETHOD(pcib_maxslots, generic_pcie_maxslots), 694 DEVMETHOD(pcib_read_config, generic_pcie_read_config), 695 DEVMETHOD(pcib_write_config, generic_pcie_write_config), 696 697 DEVMETHOD_END 698 }; 699 700 DEFINE_CLASS_0(pcib, generic_pcie_core_driver, 701 generic_pcie_methods, sizeof(struct generic_pcie_core_softc)); 702