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