xref: /src/sys/dev/thunderbolt/tb_pcib.c (revision 067ad8b31bf68b6dcf1ad571746349ed88d63d00)
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 		/* 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
tb_pcib_get_tunables(struct tb_pcib_softc * sc)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
tb_pcib_setup_sysctl(struct tb_pcib_softc * sc)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
tb_pcib_probe_common(device_t dev,char * desc)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
tb_pcib_probe(device_t dev)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
tb_pcib_attach_common(device_t dev)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
tb_pcib_attach(device_t dev)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
tb_pcib_detach(device_t dev)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
tb_pcib_lc_mailbox(device_t dev,struct tb_lcmbox_cmd * cmd)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
tb_pcib_pcie2cio_wait(device_t dev,u_int timeout)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
tb_pcib_pcie2cio_read(device_t dev,u_int space,u_int port,u_int offset,uint32_t * val)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
tb_pcib_pcie2cio_write(device_t dev,u_int space,u_int port,u_int offset,uint32_t val)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
tb_pcib_find_ufp(device_t dev,device_t * ufp)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
tb_pcib_get_debug(device_t dev,u_int * debug)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
tb_pci_probe(device_t dev)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
tb_pci_attach(device_t dev)600 tb_pci_attach(device_t dev)
601 {
602 
603 	return (pci_attach(dev));
604 }
605 
606 static int
tb_pci_detach(device_t dev)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