1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright 2019 Cisco Systems, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __FBSDID("$FreeBSD$"); 31 32 #include <sys/types.h> 33 #include <sys/param.h> 34 #include <sys/bus.h> 35 #include <sys/conf.h> 36 #include <sys/kernel.h> 37 #include <sys/module.h> 38 #include <sys/systm.h> 39 #include <sys/malloc.h> 40 41 #include <machine/bus.h> 42 #include <machine/resource.h> 43 #include <sys/rman.h> 44 #include <sys/lock.h> 45 #include <sys/mutex.h> 46 #include <sys/taskqueue.h> 47 48 #include <sys/pciio.h> 49 #include <dev/pci/pcivar.h> 50 #include <dev/pci/pcireg.h> 51 #include <dev/pci/pci_private.h> 52 #include <dev/pci/pcib_private.h> 53 54 #define TASK_QUEUE_INTR 1 55 #include <dev/vmd/vmd.h> 56 57 #include "pcib_if.h" 58 #include "pci_if.h" 59 60 struct vmd_type { 61 u_int16_t vmd_vid; 62 u_int16_t vmd_did; 63 char *vmd_name; 64 int flags; 65 #define BUS_RESTRICT 1 66 }; 67 68 #define INTEL_VENDOR_ID 0x8086 69 #define INTEL_DEVICE_ID_201d 0x201d 70 #define INTEL_DEVICE_ID_28c0 0x28c0 71 #define INTEL_DEVICE_ID_467f 0x467f 72 #define INTEL_DEVICE_ID_4c3d 0x4c3d 73 #define INTEL_DEVICE_ID_9a0b 0x9a0b 74 75 #define VMD_CAP 0x40 76 #define VMD_BUS_RESTRICT 0x1 77 78 #define VMD_CONFIG 0x44 79 #define VMD_BUS_START(x) ((x >> 8) & 0x3) 80 81 #define VMD_LOCK 0x70 82 83 static struct vmd_type vmd_devs[] = { 84 { INTEL_VENDOR_ID, INTEL_DEVICE_ID_201d, "Intel Volume Management Device", 0 }, 85 { INTEL_VENDOR_ID, INTEL_DEVICE_ID_28c0, "Intel Volume Management Device", BUS_RESTRICT }, 86 { INTEL_VENDOR_ID, INTEL_DEVICE_ID_467f, "Intel Volume Management Device", BUS_RESTRICT }, 87 { INTEL_VENDOR_ID, INTEL_DEVICE_ID_4c3d, "Intel Volume Management Device", BUS_RESTRICT }, 88 { INTEL_VENDOR_ID, INTEL_DEVICE_ID_9a0b, "Intel Volume Management Device", BUS_RESTRICT }, 89 { 0, 0, NULL, 0 } 90 }; 91 92 static int 93 vmd_probe(device_t dev) 94 { 95 struct vmd_type *t; 96 uint16_t vid, did; 97 98 t = vmd_devs; 99 vid = pci_get_vendor(dev); 100 did = pci_get_device(dev); 101 102 while (t->vmd_name != NULL) { 103 if (vid == t->vmd_vid && 104 did == t->vmd_did) { 105 device_set_desc(dev, t->vmd_name); 106 return (BUS_PROBE_DEFAULT); 107 } 108 t++; 109 } 110 111 return (ENXIO); 112 } 113 114 static void 115 vmd_free(struct vmd_softc *sc) 116 { 117 int i; 118 struct vmd_irq_handler *elm, *tmp; 119 120 if (sc->vmd_bus.rman.rm_end != 0) 121 rman_fini(&sc->vmd_bus.rman); 122 123 #ifdef TASK_QUEUE_INTR 124 if (sc->vmd_irq_tq != NULL) { 125 taskqueue_drain(sc->vmd_irq_tq, &sc->vmd_irq_task); 126 taskqueue_free(sc->vmd_irq_tq); 127 sc->vmd_irq_tq = NULL; 128 } 129 #endif 130 if (sc->vmd_irq != NULL) { 131 for (i = 0; i < sc->vmd_msix_count; i++) { 132 if (sc->vmd_irq[i].vmd_res != NULL) { 133 bus_teardown_intr(sc->vmd_dev, 134 sc->vmd_irq[i].vmd_res, 135 sc->vmd_irq[i].vmd_handle); 136 bus_release_resource(sc->vmd_dev, SYS_RES_IRQ, 137 sc->vmd_irq[i].vmd_rid, 138 sc->vmd_irq[i].vmd_res); 139 } 140 } 141 TAILQ_FOREACH_SAFE(elm, &sc->vmd_irq[0].vmd_list ,vmd_link, 142 tmp) { 143 TAILQ_REMOVE(&sc->vmd_irq[0].vmd_list, elm, vmd_link); 144 free(elm, M_DEVBUF); 145 } 146 } 147 free(sc->vmd_irq, M_DEVBUF); 148 sc->vmd_irq = NULL; 149 pci_release_msi(sc->vmd_dev); 150 for (i = 0; i < VMD_MAX_BAR; i++) { 151 if (sc->vmd_regs_resource[i] != NULL) 152 bus_release_resource(sc->vmd_dev, SYS_RES_MEMORY, 153 sc->vmd_regs_rid[i], 154 sc->vmd_regs_resource[i]); 155 } 156 if (sc->vmd_io_resource) 157 bus_release_resource(device_get_parent(sc->vmd_dev), 158 SYS_RES_IOPORT, sc->vmd_io_rid, sc->vmd_io_resource); 159 160 #ifndef TASK_QUEUE_INTR 161 if (mtx_initialized(&sc->vmd_irq_lock)) { 162 mtx_destroy(&sc->vmd_irq_lock); 163 } 164 #endif 165 } 166 167 /* Hidden PCI Roots are hidden in BAR(0). */ 168 169 static uint32_t 170 vmd_read_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, int width) 171 { 172 173 struct vmd_softc *sc; 174 bus_addr_t offset; 175 176 sc = device_get_softc(dev); 177 if (b < sc->vmd_bus_start) 178 return (0xffffffff); 179 180 offset = ((b - sc->vmd_bus_start) << 20) + (s << 15) + (f << 12) + reg; 181 182 switch(width) { 183 case 4: 184 return (bus_space_read_4(sc->vmd_btag, sc->vmd_bhandle, 185 offset)); 186 case 2: 187 return (bus_space_read_2(sc->vmd_btag, sc->vmd_bhandle, 188 offset)); 189 case 1: 190 return (bus_space_read_1(sc->vmd_btag, sc->vmd_bhandle, 191 offset)); 192 default: 193 KASSERT(1, ("Invalid width requested")); 194 return (0xffffffff); 195 } 196 } 197 198 static void 199 vmd_write_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, 200 uint32_t val, int width) 201 { 202 203 struct vmd_softc *sc; 204 bus_addr_t offset; 205 206 sc = device_get_softc(dev); 207 if (b < sc->vmd_bus_start) 208 return; 209 210 offset = ((b - sc->vmd_bus_start) << 20) + (s << 15) + (f << 12) + reg; 211 212 switch(width) { 213 case 4: 214 return (bus_space_write_4(sc->vmd_btag, sc->vmd_bhandle, 215 offset, val)); 216 case 2: 217 return (bus_space_write_2(sc->vmd_btag, sc->vmd_bhandle, 218 offset, val)); 219 case 1: 220 return (bus_space_write_1(sc->vmd_btag, sc->vmd_bhandle, 221 offset, val)); 222 default: 223 panic("Failed to specific width"); 224 } 225 } 226 227 static uint32_t 228 vmd_pci_read_config(device_t dev, device_t child, int reg, int width) 229 { 230 struct pci_devinfo *dinfo = device_get_ivars(child); 231 pcicfgregs *cfg = &dinfo->cfg; 232 233 return vmd_read_config(dev, cfg->bus, cfg->slot, cfg->func, reg, width); 234 } 235 236 static void 237 vmd_pci_write_config(device_t dev, device_t child, int reg, uint32_t val, 238 int width) 239 { 240 struct pci_devinfo *dinfo = device_get_ivars(child); 241 pcicfgregs *cfg = &dinfo->cfg; 242 243 vmd_write_config(dev, cfg->bus, cfg->slot, cfg->func, reg, val, width); 244 } 245 246 static struct pci_devinfo * 247 vmd_alloc_devinfo(device_t dev) 248 { 249 struct pci_devinfo *dinfo; 250 251 dinfo = malloc(sizeof(*dinfo), M_DEVBUF, M_WAITOK | M_ZERO); 252 return (dinfo); 253 } 254 255 static void 256 vmd_intr(void *arg) 257 { 258 struct vmd_irq *irq; 259 struct vmd_softc *sc; 260 #ifndef TASK_QUEUE_INTR 261 struct vmd_irq_handler *elm, *tmp_elm; 262 #endif 263 264 irq = (struct vmd_irq *)arg; 265 sc = irq->vmd_sc; 266 #ifdef TASK_QUEUE_INTR 267 taskqueue_enqueue(sc->vmd_irq_tq, &sc->vmd_irq_task); 268 #else 269 mtx_lock(&sc->vmd_irq_lock); 270 TAILQ_FOREACH_SAFE(elm, &sc->vmd_irq[0].vmd_list, vmd_link, tmp_elm) { 271 (elm->vmd_intr)(elm->vmd_arg); 272 } 273 mtx_unlock(&sc->vmd_irq_lock); 274 #endif 275 } 276 277 #ifdef TASK_QUEUE_INTR 278 static void 279 vmd_handle_irq(void *context, int pending) 280 { 281 struct vmd_irq_handler *elm, *tmp_elm; 282 struct vmd_softc *sc; 283 284 sc = context; 285 286 TAILQ_FOREACH_SAFE(elm, &sc->vmd_irq[0].vmd_list, vmd_link, tmp_elm) { 287 (elm->vmd_intr)(elm->vmd_arg); 288 } 289 } 290 #endif 291 292 static int 293 vmd_attach(device_t dev) 294 { 295 struct vmd_softc *sc; 296 struct pcib_secbus *bus; 297 struct vmd_type *t; 298 uint16_t vid, did; 299 uint32_t bar; 300 int i, j, error; 301 int rid, sec_reg; 302 static int b; 303 static int s; 304 static int f; 305 int min_count = 1; 306 char buf[64]; 307 308 sc = device_get_softc(dev); 309 bzero(sc, sizeof(*sc)); 310 sc->vmd_dev = dev; 311 b = s = f = 0; 312 313 pci_enable_busmaster(dev); 314 315 #ifdef TASK_QUEUE_INTR 316 sc->vmd_irq_tq = taskqueue_create_fast("vmd_taskq", M_NOWAIT, 317 taskqueue_thread_enqueue, &sc->vmd_irq_tq); 318 taskqueue_start_threads(&sc->vmd_irq_tq, 1, PI_DISK, "%s taskq", 319 device_get_nameunit(sc->vmd_dev)); 320 TASK_INIT(&sc->vmd_irq_task, 0, vmd_handle_irq, sc); 321 #else 322 mtx_init(&sc->vmd_irq_lock, "VMD IRQ lock", NULL, MTX_DEF); 323 #endif 324 for (i = 0, j = 0; i < VMD_MAX_BAR; i++, j++ ) { 325 sc->vmd_regs_rid[i] = PCIR_BAR(j); 326 bar = pci_read_config(dev, PCIR_BAR(0), 4); 327 if (PCI_BAR_MEM(bar) && (bar & PCIM_BAR_MEM_TYPE) == 328 PCIM_BAR_MEM_64) 329 j++; 330 if ((sc->vmd_regs_resource[i] = bus_alloc_resource_any( 331 sc->vmd_dev, SYS_RES_MEMORY, &sc->vmd_regs_rid[i], 332 RF_ACTIVE)) == NULL) { 333 device_printf(dev, "Cannot allocate resources\n"); 334 goto fail; 335 } 336 } 337 338 sc->vmd_io_rid = PCIR_IOBASEL_1; 339 sc->vmd_io_resource = bus_alloc_resource_any( 340 device_get_parent(sc->vmd_dev), SYS_RES_IOPORT, &sc->vmd_io_rid, 341 RF_ACTIVE); 342 if (sc->vmd_io_resource == NULL) { 343 device_printf(dev, "Cannot allocate IO\n"); 344 goto fail; 345 } 346 347 sc->vmd_btag = rman_get_bustag(sc->vmd_regs_resource[0]); 348 sc->vmd_bhandle = rman_get_bushandle(sc->vmd_regs_resource[0]); 349 350 pci_write_config(dev, PCIR_PRIBUS_2, 351 pcib_get_bus(device_get_parent(dev)), 1); 352 353 t = vmd_devs; 354 vid = pci_get_vendor(dev); 355 did = pci_get_device(dev); 356 357 sc->vmd_bus_start = 0; 358 while (t->vmd_name != NULL) { 359 if (vid == t->vmd_vid && 360 did == t->vmd_did) { 361 if (t->flags == BUS_RESTRICT) { 362 if (pci_read_config(dev, VMD_CAP, 2) & 363 VMD_BUS_RESTRICT) 364 switch (VMD_BUS_START(pci_read_config( 365 dev, VMD_CONFIG, 2))) { 366 case 1: 367 sc->vmd_bus_start = 128; 368 break; 369 case 2: 370 sc->vmd_bus_start = 224; 371 break; 372 case 3: 373 device_printf(dev, 374 "Unknown bug offset\n"); 375 goto fail; 376 break; 377 } 378 } 379 } 380 t++; 381 } 382 383 device_printf(dev, "VMD bus starts at %d\n", sc->vmd_bus_start); 384 385 sec_reg = PCIR_SECBUS_1; 386 bus = &sc->vmd_bus; 387 bus->sub_reg = PCIR_SUBBUS_1; 388 bus->sec = vmd_read_config(dev, b, s, f, sec_reg, 1); 389 bus->sub = vmd_read_config(dev, b, s, f, bus->sub_reg, 1); 390 bus->dev = dev; 391 bus->rman.rm_start = sc->vmd_bus_start; 392 bus->rman.rm_end = PCI_BUSMAX; 393 bus->rman.rm_type = RMAN_ARRAY; 394 snprintf(buf, sizeof(buf), "%s bus numbers", device_get_nameunit(dev)); 395 bus->rman.rm_descr = strdup(buf, M_DEVBUF); 396 error = rman_init(&bus->rman); 397 if (error) { 398 device_printf(dev, "Failed to initialize %s bus number rman\n", 399 device_get_nameunit(dev)); 400 bus->rman.rm_end = 0; 401 goto fail; 402 } 403 404 /* 405 * Allocate a bus range. This will return an existing bus range 406 * if one exists, or a new bus range if one does not. 407 */ 408 rid = 0; 409 bus->res = bus_alloc_resource_anywhere(dev, PCI_RES_BUS, &rid, 410 min_count, 0); 411 if (bus->res == NULL) { 412 /* 413 * Fall back to just allocating a range of a single bus 414 * number. 415 */ 416 bus->res = bus_alloc_resource_anywhere(dev, PCI_RES_BUS, &rid, 417 1, 0); 418 } else if (rman_get_size(bus->res) < min_count) { 419 /* 420 * Attempt to grow the existing range to satisfy the 421 * minimum desired count. 422 */ 423 (void)bus_adjust_resource(dev, PCI_RES_BUS, bus->res, 424 rman_get_start(bus->res), rman_get_start(bus->res) + 425 min_count - 1); 426 } 427 428 /* 429 * Add the initial resource to the rman. 430 */ 431 if (bus->res != NULL) { 432 error = rman_manage_region(&bus->rman, rman_get_start(bus->res), 433 rman_get_end(bus->res)); 434 if (error) { 435 device_printf(dev, "Failed to add resource to rman\n"); 436 goto fail; 437 } 438 bus->sec = rman_get_start(bus->res); 439 bus->sub = rman_get_end(bus->res); 440 } 441 442 sc->vmd_msix_count = pci_msix_count(dev); 443 if (pci_alloc_msix(dev, &sc->vmd_msix_count) == 0) { 444 sc->vmd_irq = malloc(sizeof(struct vmd_irq) * 445 sc->vmd_msix_count, 446 M_DEVBUF, M_WAITOK | M_ZERO); 447 448 for (i = 0; i < sc->vmd_msix_count; i++) { 449 sc->vmd_irq[i].vmd_rid = i + 1; 450 sc->vmd_irq[i].vmd_sc = sc; 451 sc->vmd_irq[i].vmd_instance = i; 452 sc->vmd_irq[i].vmd_res = bus_alloc_resource_any(dev, 453 SYS_RES_IRQ, &sc->vmd_irq[i].vmd_rid, 454 RF_ACTIVE); 455 if (sc->vmd_irq[i].vmd_res == NULL) { 456 device_printf(dev,"Failed to alloc irq\n"); 457 goto fail; 458 } 459 460 TAILQ_INIT(&sc->vmd_irq[i].vmd_list); 461 if (bus_setup_intr(dev, sc->vmd_irq[i].vmd_res, 462 INTR_TYPE_MISC | INTR_MPSAFE, NULL, vmd_intr, 463 &sc->vmd_irq[i], &sc->vmd_irq[i].vmd_handle)) { 464 device_printf(sc->vmd_dev, 465 "Cannot set up interrupt\n"); 466 sc->vmd_irq[i].vmd_res = NULL; 467 goto fail; 468 } 469 } 470 } 471 472 sc->vmd_child = device_add_child(dev, NULL, -1); 473 if (sc->vmd_child == NULL) { 474 device_printf(dev, "Failed to attach child\n"); 475 goto fail; 476 } 477 478 error = device_probe_and_attach(sc->vmd_child); 479 if (error) { 480 device_printf(dev, "Failed to add probe child: %d\n", error); 481 (void)device_delete_child(dev, sc->vmd_child); 482 goto fail; 483 } 484 485 return (0); 486 487 fail: 488 vmd_free(sc); 489 return (ENXIO); 490 } 491 492 static int 493 vmd_detach(device_t dev) 494 { 495 struct vmd_softc *sc; 496 int err; 497 498 sc = device_get_softc(dev); 499 if (sc->vmd_child != NULL) { 500 err = bus_generic_detach(sc->vmd_child); 501 if (err) 502 return (err); 503 err = device_delete_child(dev, sc->vmd_child); 504 if (err) 505 return (err); 506 } 507 vmd_free(sc); 508 return (0); 509 } 510 511 /* Pass request to alloc an MSI-X message up to the parent bridge. */ 512 static int 513 vmd_alloc_msix(device_t pcib, device_t dev, int *irq) 514 { 515 struct vmd_softc *sc = device_get_softc(pcib); 516 device_t bus; 517 int ret; 518 519 if (sc->vmd_flags & PCIB_DISABLE_MSIX) 520 return (ENXIO); 521 bus = device_get_parent(pcib); 522 ret = PCIB_ALLOC_MSIX(device_get_parent(bus), dev, irq); 523 return (ret); 524 } 525 526 static struct resource * 527 vmd_alloc_resource(device_t dev, device_t child, int type, int *rid, 528 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 529 { 530 /* Start at max PCI vmd_domain and work down */ 531 if (type == PCI_RES_BUS) { 532 return (pci_domain_alloc_bus(PCI_DOMAINMAX - 533 device_get_unit(dev), child, rid, start, end, 534 count, flags)); 535 } 536 537 return (pcib_alloc_resource(dev, child, type, rid, start, end, 538 count, flags)); 539 } 540 541 static int 542 vmd_adjust_resource(device_t dev, device_t child, int type, 543 struct resource *r, rman_res_t start, rman_res_t end) 544 { 545 struct resource *res = r; 546 547 if (type == PCI_RES_BUS) 548 return (pci_domain_adjust_bus(PCI_DOMAINMAX - 549 device_get_unit(dev), child, res, start, end)); 550 return (pcib_adjust_resource(dev, child, type, res, start, end)); 551 } 552 553 static int 554 vmd_release_resource(device_t dev, device_t child, int type, int rid, 555 struct resource *r) 556 { 557 if (type == PCI_RES_BUS) 558 return (pci_domain_release_bus(PCI_DOMAINMAX - 559 device_get_unit(dev), child, rid, r)); 560 return (pcib_release_resource(dev, child, type, rid, r)); 561 } 562 563 static int 564 vmd_shutdown(device_t dev) 565 { 566 return (0); 567 } 568 569 static int 570 vmd_pcib_route_interrupt(device_t pcib, device_t dev, int pin) 571 { 572 return (pcib_route_interrupt(pcib, dev, pin)); 573 } 574 575 static int 576 vmd_pcib_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, 577 int *irqs) 578 { 579 return (pcib_alloc_msi(pcib, dev, count, maxcount, irqs)); 580 } 581 582 static int 583 vmd_pcib_release_msi(device_t pcib, device_t dev, int count, int *irqs) 584 { 585 586 return (pcib_release_msi(pcib, dev, count, irqs)); 587 } 588 589 static int 590 vmd_pcib_release_msix(device_t pcib, device_t dev, int irq) { 591 return pcib_release_msix(pcib, dev, irq); 592 } 593 594 static int 595 vmd_setup_intr(device_t dev, device_t child, struct resource *irq, 596 int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg, 597 void **cookiep) 598 { 599 struct vmd_irq_handler *elm; 600 struct vmd_softc *sc; 601 int i; 602 603 sc = device_get_softc(dev); 604 605 /* 606 * There appears to be no steering of VMD interrupts from device 607 * to VMD interrupt 608 */ 609 610 i = 0; 611 elm = malloc(sizeof(*elm), M_DEVBUF, M_NOWAIT|M_ZERO); 612 elm->vmd_child = child; 613 elm->vmd_intr = intr; 614 elm->vmd_rid = rman_get_rid(irq); 615 elm->vmd_arg = arg; 616 TAILQ_INSERT_TAIL(&sc->vmd_irq[i].vmd_list, elm, vmd_link); 617 618 return (bus_generic_setup_intr(dev, child, irq, flags, filter, intr, 619 arg, cookiep)); 620 } 621 622 static int 623 vmd_teardown_intr(device_t dev, device_t child, struct resource *irq, 624 void *cookie) 625 { 626 struct vmd_irq_handler *elm, *tmp;; 627 struct vmd_softc *sc; 628 629 sc = device_get_softc(dev); 630 TAILQ_FOREACH_SAFE(elm, &sc->vmd_irq[0].vmd_list, vmd_link, tmp) { 631 if (elm->vmd_child == child && 632 elm->vmd_rid == rman_get_rid(irq)) { 633 TAILQ_REMOVE(&sc->vmd_irq[0].vmd_list, elm, vmd_link); 634 free(elm, M_DEVBUF); 635 } 636 } 637 638 return (bus_generic_teardown_intr(dev, child, irq, cookie)); 639 } 640 641 static device_method_t vmd_pci_methods[] = { 642 /* Device interface */ 643 DEVMETHOD(device_probe, vmd_probe), 644 DEVMETHOD(device_attach, vmd_attach), 645 DEVMETHOD(device_detach, vmd_detach), 646 DEVMETHOD(device_shutdown, vmd_shutdown), 647 648 /* Bus interface */ 649 DEVMETHOD(bus_read_ivar, pcib_read_ivar), 650 DEVMETHOD(bus_write_ivar, pcib_write_ivar), 651 DEVMETHOD(bus_alloc_resource, vmd_alloc_resource), 652 DEVMETHOD(bus_adjust_resource, vmd_adjust_resource), 653 DEVMETHOD(bus_release_resource, vmd_release_resource), 654 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 655 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 656 DEVMETHOD(bus_setup_intr, vmd_setup_intr), 657 DEVMETHOD(bus_teardown_intr, vmd_teardown_intr), 658 659 /* pci interface */ 660 DEVMETHOD(pci_read_config, vmd_pci_read_config), 661 DEVMETHOD(pci_write_config, vmd_pci_write_config), 662 DEVMETHOD(pci_alloc_devinfo, vmd_alloc_devinfo), 663 664 /* pcib interface */ 665 DEVMETHOD(pcib_maxslots, pcib_maxslots), 666 DEVMETHOD(pcib_read_config, vmd_read_config), 667 DEVMETHOD(pcib_write_config, vmd_write_config), 668 DEVMETHOD(pcib_route_interrupt, vmd_pcib_route_interrupt), 669 DEVMETHOD(pcib_alloc_msi, vmd_pcib_alloc_msi), 670 DEVMETHOD(pcib_release_msi, vmd_pcib_release_msi), 671 DEVMETHOD(pcib_alloc_msix, vmd_alloc_msix), 672 DEVMETHOD(pcib_release_msix, vmd_pcib_release_msix), 673 DEVMETHOD(pcib_map_msi, pcib_map_msi), 674 675 DEVMETHOD_END 676 }; 677 678 static devclass_t vmd_devclass; 679 680 DEFINE_CLASS_0(vmd, vmd_pci_driver, vmd_pci_methods, sizeof(struct vmd_softc)); 681 DRIVER_MODULE(vmd, pci, vmd_pci_driver, vmd_devclass, NULL, NULL); 682 MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, vmd, 683 vmd_devs, nitems(vmd_devs) - 1); 684 MODULE_DEPEND(vmd, vmd_bus, 1, 1, 1); 685