1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2022 Scott Long 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 "opt_acpi.h" 30 #include "opt_thunderbolt.h" 31 32 /* PCIe bridge for Thunderbolt */ 33 #include <sys/types.h> 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/module.h> 38 #include <sys/bus.h> 39 #include <sys/conf.h> 40 #include <sys/malloc.h> 41 #include <sys/sysctl.h> 42 #include <sys/lock.h> 43 #include <sys/param.h> 44 #include <sys/endian.h> 45 46 #include <machine/bus.h> 47 #include <machine/resource.h> 48 #include <machine/stdarg.h> 49 #include <sys/rman.h> 50 51 #include <machine/pci_cfgreg.h> 52 #include <dev/pci/pcireg.h> 53 #include <dev/pci/pcivar.h> 54 #include <dev/pci/pcib_private.h> 55 #include <dev/pci/pci_private.h> 56 57 #include <contrib/dev/acpica/include/acpi.h> 58 #include <contrib/dev/acpica/include/accommon.h> 59 #include <dev/acpica/acpivar.h> 60 #include <dev/acpica/acpi_pcibvar.h> 61 #include <machine/md_var.h> 62 63 #include <dev/thunderbolt/tb_reg.h> 64 #include <dev/thunderbolt/tb_pcib.h> 65 #include <dev/thunderbolt/nhi_var.h> 66 #include <dev/thunderbolt/nhi_reg.h> 67 #include <dev/thunderbolt/tbcfg_reg.h> 68 #include <dev/thunderbolt/tb_debug.h> 69 #include "tb_if.h" 70 71 static int tb_pcib_probe(device_t); 72 static int tb_pcib_attach(device_t); 73 static int tb_pcib_detach(device_t); 74 static int tb_pcib_lc_mailbox(device_t, struct tb_lcmbox_cmd *); 75 static int tb_pcib_pcie2cio_read(device_t, u_int, u_int, u_int, 76 uint32_t *); 77 static int tb_pcib_pcie2cio_write(device_t, u_int, u_int, u_int, uint32_t); 78 static int tb_pcib_find_ufp(device_t, device_t *); 79 static int tb_pcib_get_debug(device_t, u_int *); 80 81 static int tb_pci_probe(device_t); 82 static int tb_pci_attach(device_t); 83 static int tb_pci_detach(device_t); 84 85 struct tb_pcib_ident { 86 uint16_t vendor; 87 uint16_t device; 88 uint16_t subvendor; 89 uint16_t subdevice; 90 uint32_t flags; /* This follows the tb_softc flags */ 91 const char *desc; 92 } tb_pcib_identifiers[] = { 93 { VENDOR_INTEL, TB_DEV_AR_2C, 0xffff, 0xffff, TB_GEN_TB3|TB_HWIF_AR, 94 "Thunderbolt 3 PCI-PCI Bridge (Alpine Ridge 2C)" }, 95 { VENDOR_INTEL, TB_DEV_AR_LP, 0xffff, 0xffff, TB_GEN_TB3|TB_HWIF_AR, 96 "Thunderbolt 3 PCI-PCI Bridge (Alpine Ridge LP)" }, 97 { VENDOR_INTEL, TB_DEV_AR_C_4C, 0xffff, 0xffff, TB_GEN_TB3|TB_HWIF_AR, 98 "Thunderbolt 3 PCI-PCI Bridge (Alpine Ridge C 4C)" }, 99 { VENDOR_INTEL, TB_DEV_AR_C_2C, 0xffff, 0xffff, TB_GEN_TB3|TB_HWIF_AR, 100 "Thunderbolt 3 PCI-PCI Bridge C (Alpine Ridge C 2C)" }, 101 { VENDOR_INTEL, TB_DEV_ICL_0, 0xffff, 0xffff, TB_GEN_TB3|TB_HWIF_ICL, 102 "Thunderbolt 3 PCI-PCI Bridge (IceLake)" }, 103 { VENDOR_INTEL, TB_DEV_ICL_1, 0xffff, 0xffff, TB_GEN_TB3|TB_HWIF_ICL, 104 "Thunderbolt 3 PCI-PCI Bridge (IceLake)" }, 105 { 0, 0, 0, 0, 0, NULL } 106 }; 107 108 static struct tb_pcib_ident * 109 tb_pcib_find_ident(device_t dev) 110 { 111 struct tb_pcib_ident *n; 112 uint16_t v, d, sv, sd; 113 114 v = pci_get_vendor(dev); 115 d = pci_get_device(dev); 116 sv = pci_get_subvendor(dev); 117 sd = pci_get_subdevice(dev); 118 119 for (n = tb_pcib_identifiers; n->vendor != 0; n++) { 120 if ((n->vendor != v) || (n->device != d)) 121 continue; 122 /* Only match actual PCI-PCI bridges to avoid conflict with NHI */ 123 if (pci_get_class(dev) != PCIC_BRIDGE || 124 pci_get_subclass(dev) != PCIS_BRIDGE_PCI) 125 continue; 126 if (((n->subvendor != 0xffff) && (n->subvendor != sv)) || 127 ((n->subdevice != 0xffff) && (n->subdevice != sd))) 128 continue; 129 return (n); 130 } 131 132 return (NULL); 133 } 134 135 static void 136 tb_pcib_get_tunables(struct tb_pcib_softc *sc) 137 { 138 char tmpstr[80], oid[80]; 139 140 /* Set the default */ 141 sc->debug = 0; 142 143 /* Grab global variables */ 144 bzero(oid, 80); 145 if (TUNABLE_STR_FETCH("hw.tbolt.debug_level", oid, 80) != 0) 146 tb_parse_debug(&sc->debug, oid); 147 148 /* Grab instance variables */ 149 bzero(oid, 80); 150 snprintf(tmpstr, sizeof(tmpstr), "dev.tbolt.%d.debug_level", 151 device_get_unit(sc->dev)); 152 if (TUNABLE_STR_FETCH(tmpstr, oid, 80) != 0) 153 tb_parse_debug(&sc->debug, oid); 154 155 return; 156 } 157 158 static int 159 tb_pcib_setup_sysctl(struct tb_pcib_softc *sc) 160 { 161 struct sysctl_ctx_list *ctx = NULL; 162 struct sysctl_oid *tree = NULL; 163 164 ctx = device_get_sysctl_ctx(sc->dev); 165 if (ctx != NULL) 166 tree = device_get_sysctl_tree(sc->dev); 167 168 if (tree == NULL) { 169 tb_printf(sc, "Error: cannot create sysctl nodes\n"); 170 return (EINVAL); 171 } 172 sc->sysctl_tree = tree; 173 sc->sysctl_ctx = ctx; 174 175 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), 176 OID_AUTO, "debug_level", CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_MPSAFE, 177 &sc->debug, 0, tb_debug_sysctl, "A", "Thunderbolt debug level"); 178 179 return (0); 180 } 181 182 /* 183 * This is used for both the PCI and ACPI attachments. It shouldn't return 184 * 0, doing so will force the ACPI attachment to fail. 185 */ 186 int 187 tb_pcib_probe_common(device_t dev, char *desc) 188 { 189 device_t ufp; 190 struct tb_pcib_ident *n; 191 char *suffix; 192 193 if ((n = tb_pcib_find_ident(dev)) != NULL) { 194 ufp = NULL; 195 if ((TB_FIND_UFP(dev, &ufp) == 0) && (ufp == dev)) 196 suffix = "(Upstream port)"; 197 else 198 suffix = "(Downstream port)"; 199 snprintf(desc, TB_DESC_MAX, "%s %s", n->desc, suffix); 200 return (BUS_PROBE_VENDOR); 201 } 202 return (ENXIO); 203 } 204 205 static int 206 tb_pcib_probe(device_t dev) 207 { 208 char desc[TB_DESC_MAX]; 209 int val; 210 211 if ((val = tb_pcib_probe_common(dev, desc)) <= 0) 212 device_set_desc_copy(dev, desc); 213 214 return (val); 215 } 216 217 int 218 tb_pcib_attach_common(device_t dev) 219 { 220 device_t ufp; 221 struct tb_pcib_ident *n; 222 struct tb_pcib_softc *sc; 223 uint32_t val; 224 int error; 225 226 sc = device_get_softc(dev); 227 sc->dev = dev; 228 sc->vsec = -1; 229 230 n = tb_pcib_find_ident(dev); 231 KASSERT(n != NULL, ("Cannot find TB ident")); 232 sc->flags = n->flags; 233 234 tb_pcib_get_tunables(sc); 235 tb_pcib_setup_sysctl(sc); 236 237 /* XXX Is this necessary for ACPI attachments? */ 238 tb_debug(sc, DBG_BRIDGE, "busmaster status was %s\n", 239 (pci_read_config(dev, PCIR_COMMAND, 2) & PCIM_CMD_BUSMASTEREN) 240 ? "enabled" : "disabled"); 241 pci_enable_busmaster(dev); 242 243 /* 244 * Determine if this is an upstream or downstream facing device, and 245 * whether it's the root of the Thunderbolt topology. It's too bad 246 * that there aren't unique PCI ID's to help with this. 247 */ 248 ufp = NULL; 249 if ((TB_FIND_UFP(dev, &ufp) == 0) && (ufp != NULL)) { 250 if (ufp == dev) { 251 sc->flags |= TB_FLAGS_ISUFP; 252 if (TB_FIND_UFP(device_get_parent(dev), NULL) == 253 EOPNOTSUPP) { 254 sc->flags |= TB_FLAGS_ISROOT; 255 } 256 } 257 } 258 259 /* 260 * Find the PCI Vendor Specific Extended Capability. It's the magic 261 * wand to configuring the Thunderbolt root bridges. 262 */ 263 if (TB_IS_AR(sc) || TB_IS_TR(sc)) { 264 error = pci_find_extcap(dev, PCIZ_VENDOR, &sc->vsec); 265 if (error) { 266 tb_printf(sc, "Cannot find VSEC capability: %d\n", 267 error); 268 return (ENXIO); 269 } 270 } 271 272 /* 273 * Take the AR bridge out of low-power mode. 274 * XXX AR only? 275 */ 276 if ((1 || TB_IS_AR(sc)) && TB_IS_ROOT(sc)) { 277 struct tb_lcmbox_cmd cmd; 278 279 cmd.cmd = LC_MBOXOUT_CMD_SXEXIT_TBT; 280 cmd.data_in = 0; 281 282 error = TB_LC_MAILBOX(dev, &cmd); 283 tb_debug(sc, DBG_BRIDGE, "SXEXIT returned error= %d resp= 0x%x " 284 "data= 0x%x\n", error, cmd.cmd_resp, cmd.data_out); 285 } 286 287 /* The downstream facing port on AR needs some help */ 288 if (TB_IS_AR(sc) && TB_IS_DFP(sc)) { 289 tb_debug(sc, DBG_BRIDGE, "Doing AR L1 fixup\n"); 290 val = pci_read_config(dev, sc->vsec + AR_VSCAP_1C, 4); 291 tb_debug(sc, DBG_BRIDGE|DBG_FULL, "VSEC+0x1c= 0x%08x\n", val); 292 val |= (1 << 8); 293 pci_write_config(dev, sc->vsec + AR_VSCAP_1C, val, 4); 294 295 val = pci_read_config(dev, sc->vsec + AR_VSCAP_B0, 4); 296 tb_debug(sc, DBG_BRIDGE|DBG_FULL, "VSEC+0xb0= 0x%08x\n", val); 297 val |= (1 << 12); 298 pci_write_config(dev, sc->vsec + AR_VSCAP_B0, val, 4); 299 } 300 301 return (0); 302 } 303 304 static int 305 tb_pcib_attach(device_t dev) 306 { 307 int error; 308 309 error = tb_pcib_attach_common(dev); 310 if (error) 311 return (error); 312 return (pcib_attach(dev)); 313 } 314 315 static int 316 tb_pcib_detach(device_t dev) 317 { 318 struct tb_pcib_softc *sc; 319 int error; 320 321 sc = device_get_softc(dev); 322 323 tb_debug(sc, DBG_BRIDGE|DBG_ROUTER|DBG_EXTRA, "tb_pcib_detach\n"); 324 325 /* Put the AR bridge back to sleep */ 326 /* XXX disable this until power control for downstream switches works */ 327 if (0 && TB_IS_ROOT(sc)) { 328 struct tb_lcmbox_cmd cmd; 329 330 cmd.cmd = LC_MBOXOUT_CMD_GO2SX; 331 cmd.data_in = 0; 332 333 error = TB_LC_MAILBOX(dev, &cmd); 334 tb_debug(sc, DBG_BRIDGE, "SXEXIT returned error= %d resp= 0x%x " 335 "data= 0x%x\n", error, cmd.cmd_resp, cmd.data_out); 336 } 337 338 return (pcib_detach(dev)); 339 } 340 341 /* Read/write the Link Controller registers in CFG space */ 342 static int 343 tb_pcib_lc_mailbox(device_t dev, struct tb_lcmbox_cmd *cmd) 344 { 345 struct tb_pcib_softc *sc; 346 uint32_t regcmd, result; 347 uint16_t m_in, m_out; 348 int vsec, i; 349 350 sc = device_get_softc(dev); 351 vsec = TB_PCIB_VSEC(dev); 352 if (vsec == -1) 353 return (EOPNOTSUPP); 354 355 if (TB_IS_AR(sc)) { 356 m_in = AR_LC_MBOX_IN; 357 m_out = AR_LC_MBOX_OUT; 358 } else if (TB_IS_ICL(sc)) { 359 m_in = ICL_LC_MBOX_IN; 360 m_out = ICL_LC_MBOX_OUT; 361 } else 362 return (EOPNOTSUPP); 363 364 /* Set the valid bit to signal we're sending a command */ 365 regcmd = LC_MBOXOUT_VALID | (cmd->cmd & LC_MBOXOUT_CMD_MASK); 366 regcmd |= (cmd->data_in << LC_MBOXOUT_DATA_SHIFT); 367 tb_debug(sc, DBG_BRIDGE|DBG_FULL, "Writing LC cmd 0x%x\n", regcmd); 368 pci_write_config(dev, vsec + m_out, regcmd, 4); 369 370 for (i = 0; i < 10; i++) { 371 pause("nhi", 1 * hz); 372 result = pci_read_config(dev, vsec + m_in, 4); 373 tb_debug(sc, DBG_BRIDGE|DBG_FULL, "LC Mailbox= 0x%08x\n", 374 result); 375 if ((result & LC_MBOXIN_DONE) != 0) 376 break; 377 } 378 379 /* Clear the valid bit to signal we're done sending the command */ 380 pci_write_config(dev, vsec + m_out, 0, 4); 381 382 cmd->cmd_resp = result & LC_MBOXIN_CMD_MASK; 383 cmd->data_out = result >> LC_MBOXIN_CMD_SHIFT; 384 385 if ((result & LC_MBOXIN_DONE) == 0) 386 return (ETIMEDOUT); 387 388 return (0); 389 } 390 391 static int 392 tb_pcib_pcie2cio_wait(device_t dev, u_int timeout) 393 { 394 #if 0 395 uint32_t val; 396 int vsec; 397 398 vsec = TB_PCIB_VSEC(dev); 399 do { 400 pci_read_config(dev, vsec + PCIE2CIO_CMD, &val); 401 if ((val & PCIE2CIO_CMD_START) == 0) { 402 if (val & PCIE2CIO_CMD_TIMEOUT) 403 break; 404 return 0; 405 } 406 407 msleep(50); 408 } while (time_before(jiffies, end)); 409 410 #endif 411 return ETIMEDOUT; 412 } 413 414 static int 415 tb_pcib_pcie2cio_read(device_t dev, u_int space, u_int port, u_int offset, 416 uint32_t *val) 417 { 418 #if 0 419 uint32_t cmd; 420 int ret, vsec; 421 422 vsec = TB_PCIB_VSEC(dev); 423 if (vsec == -1) 424 return (EOPNOTSUPP); 425 426 cmd = index; 427 cmd |= (port << PCIE2CIO_CMD_PORT_SHIFT) & PCIE2CIO_CMD_PORT_MASK; 428 cmd |= (space << PCIE2CIO_CMD_CS_SHIFT) & PCIE2CIO_CMD_CS_MASK; 429 cmd |= PCIE2CIO_CMD_START; 430 pci_write_config(dev, vsec + PCIE2CIO_CMD, cmd, 4); 431 432 if ((ret = pci2cio_wait_completion(dev, 5000)) != 0) 433 return (ret); 434 435 *val = pci_read_config(dev, vsec + PCIE2CIO_RDDATA, 4); 436 #endif 437 return (0); 438 } 439 440 static int 441 tb_pcib_pcie2cio_write(device_t dev, u_int space, u_int port, u_int offset, 442 uint32_t val) 443 { 444 #if 0 445 uint32_t cmd; 446 int ret, vsec; 447 448 vsec = TB_PCIB_VSEC(dev); 449 if (vsec == -1) 450 return (EOPNOTSUPP); 451 452 pci_write_config(dev, vsec + PCIE2CIO_WRDATA, val, 4); 453 454 cmd = index; 455 cmd |= (port << PCIE2CIO_CMD_PORT_SHIFT) & PCIE2CIO_CMD_PORT_MASK; 456 cmd |= (space << PCIE2CIO_CMD_CS_SHIFT) & PCIE2CIO_CMD_CS_MASK; 457 cmd |= PCIE2CIO_CMD_WRITE | PCIE2CIO_CMD_START; 458 pci_write_config(dev, vsec + PCIE2CIO_CMD, cmd); 459 460 #endif 461 return (tb_pcib_pcie2cio_wait(dev, 5000)); 462 } 463 464 /* 465 * The Upstream Facing Port (UFP) in a switch is special, it's the function 466 * that responds to some of the special programming mailboxes. It can't be 467 * differentiated by PCI ID, so a heuristic approach to identifying it is 468 * required. 469 */ 470 static int 471 tb_pcib_find_ufp(device_t dev, device_t *ufp) 472 { 473 device_t upstream; 474 struct tb_pcib_softc *sc; 475 uint32_t vsec, val; 476 int error; 477 478 upstream = NULL; 479 sc = device_get_softc(dev); 480 if (sc == NULL) 481 return (EOPNOTSUPP); 482 483 if (TB_IS_UFP(sc)) { 484 upstream = dev; 485 error = 0; 486 goto out; 487 } 488 489 /* 490 * This register is supposed to be filled in on the upstream port 491 * and tells how many downstream ports there are. It doesn't seem 492 * to get filled in on AR host controllers, but is on various 493 * peripherals. 494 */ 495 error = pci_find_extcap(dev, PCIZ_VENDOR, &vsec); 496 if (error == 0) { 497 val = pci_read_config(dev, vsec + 0x18, 4); 498 if ((val & 0x1f) > 0) { 499 upstream = dev; 500 goto out; 501 } 502 } 503 504 /* 505 * Since we can't trust that the VSEC register is filled in, the only 506 * other option is to see if we're at the top of the topology, which 507 * implies that we're at the upstream port of the host controller. 508 */ 509 error = TB_FIND_UFP(device_get_parent(dev), ufp); 510 if (error == EOPNOTSUPP) { 511 upstream = dev; 512 error = 0; 513 goto out; 514 } else 515 return (error); 516 517 out: 518 if (ufp != NULL) 519 *ufp = upstream; 520 521 return (error); 522 } 523 524 static int 525 tb_pcib_get_debug(device_t dev, u_int *debug) 526 { 527 struct tb_pcib_softc *sc; 528 529 sc = device_get_softc(dev); 530 if ((sc == NULL) || (debug == NULL)) 531 return (EOPNOTSUPP); 532 533 *debug = sc->debug; 534 return (0); 535 } 536 537 static device_method_t tb_pcib_methods[] = { 538 DEVMETHOD(device_probe, tb_pcib_probe), 539 DEVMETHOD(device_attach, tb_pcib_attach), 540 DEVMETHOD(device_detach, tb_pcib_detach), 541 542 DEVMETHOD(tb_lc_mailbox, tb_pcib_lc_mailbox), 543 DEVMETHOD(tb_pcie2cio_read, tb_pcib_pcie2cio_read), 544 DEVMETHOD(tb_pcie2cio_write, tb_pcib_pcie2cio_write), 545 546 DEVMETHOD(tb_find_ufp, tb_pcib_find_ufp), 547 DEVMETHOD(tb_get_debug, tb_pcib_get_debug), 548 549 DEVMETHOD_END 550 }; 551 552 DEFINE_CLASS_1(tbolt, tb_pcib_driver, tb_pcib_methods, 553 sizeof(struct tb_pcib_softc), pcib_driver); 554 DRIVER_MODULE_ORDERED(tb_pcib, pci, tb_pcib_driver, 555 NULL, NULL, SI_ORDER_MIDDLE); 556 MODULE_DEPEND(tb_pcib, pci, 1, 1, 1); 557 558 static int 559 tb_pci_probe(device_t dev) 560 { 561 struct tb_pcib_ident *n; 562 device_t parent; 563 devclass_t dc; 564 565 /* 566 * This driver is only valid if the parent device is a PCI-PCI 567 * bridge. To determine that, check if the grandparent is a 568 * PCI bus. 569 */ 570 parent = device_get_parent(dev); 571 dc = device_get_devclass(device_get_parent(parent)); 572 if (strcmp(devclass_get_name(dc), "pci") != 0) 573 return (ENXIO); 574 575 if ((n = tb_pcib_find_ident(parent)) != NULL) { 576 switch (n->flags & TB_GEN_MASK) { 577 case TB_GEN_TB1: 578 device_set_desc(dev, "Thunderbolt 1 Link"); 579 break; 580 case TB_GEN_TB2: 581 device_set_desc(dev, "Thunderbolt 2 Link"); 582 break; 583 case TB_GEN_TB3: 584 device_set_desc(dev, "Thunderbolt 3 Link"); 585 break; 586 case TB_GEN_USB4: 587 device_set_desc(dev, "USB4 Link"); 588 break; 589 case TB_GEN_UNK: 590 /* Fallthrough */ 591 default: 592 device_set_desc(dev, "Thunderbolt Link"); 593 } 594 return (BUS_PROBE_VENDOR); 595 } 596 return (ENXIO); 597 } 598 599 static int 600 tb_pci_attach(device_t dev) 601 { 602 603 return (pci_attach(dev)); 604 } 605 606 static int 607 tb_pci_detach(device_t dev) 608 { 609 610 return (pci_detach(dev)); 611 } 612 613 static device_method_t tb_pci_methods[] = { 614 DEVMETHOD(device_probe, tb_pci_probe), 615 DEVMETHOD(device_attach, tb_pci_attach), 616 DEVMETHOD(device_detach, tb_pci_detach), 617 618 DEVMETHOD(tb_find_ufp, tb_generic_find_ufp), 619 DEVMETHOD(tb_get_debug, tb_generic_get_debug), 620 621 DEVMETHOD_END 622 }; 623 624 DEFINE_CLASS_1(pci, tb_pci_driver, tb_pci_methods, sizeof(struct pci_softc), 625 pci_driver); 626 DRIVER_MODULE(tb_pci, pcib, tb_pci_driver, NULL, NULL); 627 MODULE_DEPEND(tb_pci, pci, 1, 1, 1); 628 MODULE_VERSION(tb_pci, 1); 629