xref: /freebsd/sys/dev/thunderbolt/tb_pcib.c (revision 2ed9833791f28e14843ac813f90cb030e45948dc)
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 *
tb_pcib_find_ident(device_t dev)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
tb_pcib_get_tunables(struct tb_pcib_softc * sc)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
tb_pcib_setup_sysctl(struct tb_pcib_softc * sc)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
tb_pcib_probe_common(device_t dev,char * desc)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
tb_pcib_probe(device_t dev)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
tb_pcib_attach_common(device_t dev)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
tb_pcib_attach(device_t dev)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
tb_pcib_detach(device_t dev)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
tb_pcib_lc_mailbox(device_t dev,struct tb_lcmbox_cmd * cmd)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
tb_pcib_pcie2cio_wait(device_t dev,u_int timeout)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
tb_pcib_pcie2cio_read(device_t dev,u_int space,u_int port,u_int offset,uint32_t * val)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
tb_pcib_pcie2cio_write(device_t dev,u_int space,u_int port,u_int offset,uint32_t val)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
tb_pcib_find_ufp(device_t dev,device_t * ufp)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
tb_pcib_get_debug(device_t dev,u_int * debug)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
tb_pci_probe(device_t dev)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
tb_pci_attach(device_t dev)586 tb_pci_attach(device_t dev)
587 {
588 
589 	return (pci_attach(dev));
590 }
591 
592 static int
tb_pci_detach(device_t dev)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