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