Re: [PATCH v4] PCI: Relabel JHL6540 on Lenovo X1 Carbon 7,8

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hey!
Asking for some help on implementation.
So I implemented most of this, and successfully tested the quirk on 6
different devices with various types of discrete fixed JHL Thunderbolt
chips.

However I want to add an additional check. A device wouldn't need this
quirk if it already has Thunderbolt functionality built in within its
Root Port.

I tried to use "is_thunderbolt" as an identifier for that type of
device--- but when I tested on a device with a thunderbolt root port,
"is_thunderbolt" was false for all the Thunderbolt PCI components
listed below.

~ # lspci -nn | grep Thunderbolt
00:07.0 PCI bridge [0604]: Intel Corporation Tiger Lake-LP Thunderbolt
4 PCI Express Root Port #1 [8086:9a25] (rev 01)
00:07.2 PCI bridge [0604]: Intel Corporation Tiger Lake-LP Thunderbolt
4 PCI Express Root Port #2 [8086:9a27] (rev 01)
00:0d.0 USB controller [0c03]: Intel Corporation Tiger Lake-LP
Thunderbolt 4 USB Controller [8086:9a13] (rev 01)
00:0d.2 USB controller [0c03]: Intel Corporation Tiger Lake-LP
Thunderbolt 4 NHI #0 [8086:9a1b] (rev 01)
00:0d.3 USB controller [0c03]: Intel Corporation Tiger Lake-LP
Thunderbolt 4 NHI #1 [8086:9a1d] (rev 01)

The device I tested was the Lenovo carbon X1 Gen 9. When
set_pcie_thunderbolt is run, the devices listed above return false on
the pci_find_next_ext_capability check.

I have spent some time trying to see if there are any ACPI values or
any alternative indicators to reliably know if a root port has
thunderbolt capabilities. I do see that ADBG is often set to TBT but
that looks like a debugging tool in ACPI.

I also looked through lspci -vvv and compared the output with a device
that has no Thunderbolt built into its CPU, which gave me nothing.

I also tried looking through values in /sys/bus and searching through
the kernel, looking through logs etc. The only option I see now is
figuring out how to get the string value returned by the lspci and
parsing it, but I'm not 100% sure if all Thunderbolt CPUs would have
Root ports specifically labeled as "Thunderbolt Root Port". I'm also
not sure if that value is supposed to be used in that way.

I was hoping that someone may have a suggestion here.


Just for reference, this is the fix I have so far. I don't want to
submit it as a new patch, until I resolve the above question.

+static bool get_pci_exp_upstream_port(struct pci_dev *dev,
+                                   struct pci_dev **upstream_port)
+{
+       struct pci_dev *parent = dev;
+
+       // If the dev is an upstream port, return itself
+       if (pci_pcie_type(dev) == PCI_EXP_TYPE_UPSTREAM) {
+               *upstream_port = dev;
+               return true;
+       }
+
+       // Iterate through the dev's parents to find its upstream port
+       while ((parent = pci_upstream_bridge(parent))) {
+               if (pci_pcie_type(parent) == PCI_EXP_TYPE_UPSTREAM) {
+                       *upstream_port = parent;
+                       return true;
+               }
+       }
+       return false;
+}
+
+static void relabel_internal_thunderbolt_chip(struct pci_dev *dev)
+{
+       struct pci_dev *upstream_port;
+       struct pci_dev *upstream_ports_parent;
+
+       // Get the upstream port closest to the dev
+       if (!(get_pci_exp_upstream_port(dev, &upstream_port)))
+               return;
+
+       // Next, we confirm if the upstream port is directly behind a PCIe root
+       // port.
+       if (!(upstream_ports_parent == pci_upstream_bridge(upstream_port)))
+               return;
+       if (!(pci_pcie_type(upstream_ports_parent) == PCI_EXP_TYPE_ROOT_PORT))
+               return; // quirk does not apply
+
+       // If a device's root port already has thunderbolt capabilities, then
+       // it shouldn't be using this quirk.
+       // TODO: THIS CHECK DOES NOT WORK
+       // I ALSO TRIED USING pci_is_thunderbolt_attached WHICH DIDN'T
WORK EITHER
+       if (!(upstream_ports_parent->is_thunderbolt))
+               return; // thunderbolt functionality is built into root port
+
+       // Apply quirk
+       dev_set_removable(&dev->dev, DEVICE_FIXED);
+
+       // External facing bridges must be marked as such so that devices
+       // below them can correctly be labeled as REMOVABLE
+       if ((pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM)
+            && (dev->devfn == 0x08 | dev->devfn == 0x20))
+               dev->external_facing = true;
+}




[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux