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