svn commit: r345103 - head/sys/compat/linuxkpi/common/include/linux
Conrad Meyer
cem at freebsd.org
Wed Mar 13 20:37:03 UTC 2019
Hi,
A lot of the information about PCIe devices is read by PCI probe and
cached on the (BSD) device. You could access it out of
device_get_ivars(bsddev)->cfg.pcie and avoid the MMIO latency.
On Wed, Mar 13, 2019 at 12:15 PM Hans Petter Selasky
<hselasky at freebsd.org> wrote:
> +static inline enum pci_bus_speed
> +pcie_get_speed_cap(struct pci_dev *dev)
> +{
> + device_t root;
> + uint32_t lnkcap, lnkcap2;
> + int error, pos;
> +
> + root = device_get_parent(dev->dev.bsddev);
> + if (root == NULL)
> + return (PCI_SPEED_UNKNOWN);
> + root = device_get_parent(root);
> + if (root == NULL)
> + return (PCI_SPEED_UNKNOWN);
> + root = device_get_parent(root);
> + if (root == NULL)
> + return (PCI_SPEED_UNKNOWN);
What is this mechanism trying to accomplish? It seems incredibly
fragile. Looking for pci0? pcib0?
> + if ((error = pci_find_cap(root, PCIY_EXPRESS, &pos)) != 0)
> + return (PCI_SPEED_UNKNOWN);
Cached as non-zero cfg.pcie.pcie_location value in ivars.
> + lnkcap2 = pci_read_config(root, pos + PCIER_LINK_CAP2, 4);
This one we don't cache, unfortunately, but could. Ditto LINK_CAP
below. Usually "pos + PCIEfoo" is spelled "pcie_read_config(...,
PCIEfoo...)."
> +
> + if (lnkcap2) { /* PCIe r3.0-compliant */
> + if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_2_5GB)
> + return (PCIE_SPEED_2_5GT);
Seems like these definitions would be better suited as native
PCIEM_LINK_CAP2_foo definitions in pcireg.h
> + if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB)
> + return (PCIE_SPEED_5_0GT);
> + if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB)
> + return (PCIE_SPEED_8_0GT);
> + if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_16_0GB)
> + return (PCIE_SPEED_16_0GT);
> + } else { /* pre-r3.0 */
> + lnkcap = pci_read_config(root, pos + PCIER_LINK_CAP, 4);
> + if (lnkcap & PCI_EXP_LNKCAP_SLS_2_5GB)
> + return (PCIE_SPEED_2_5GT);
> + if (lnkcap & PCI_EXP_LNKCAP_SLS_5_0GB)
> + return (PCIE_SPEED_5_0GT);
> + if (lnkcap & PCI_EXP_LNKCAP_SLS_8_0GB)
> + return (PCIE_SPEED_8_0GT);
> + if (lnkcap & PCI_EXP_LNKCAP_SLS_16_0GB)
> + return (PCIE_SPEED_16_0GT);
> + }
> + return (PCI_SPEED_UNKNOWN);
> +}
> +
> +static inline enum pcie_link_width
> +pcie_get_width_cap(struct pci_dev *dev)
> +{
> + uint32_t lnkcap;
> +
> + pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap);
Better spelled as PCIER_LINK_CAP.
> + if (lnkcap)
> + return ((lnkcap & PCI_EXP_LNKCAP_MLW) >> 4);
And PCIEM_LINK_CAP_MAX_WIDTH.
> +
> + return (PCIE_LNK_WIDTH_UNKNOWN);
> }
>
> #endif /* _LINUX_PCI_H_ */
>
Best,
Conrad
More information about the svn-src-all
mailing list