Date: Wed, 13 Mar 2019 13:36:45 -0700 From: Conrad Meyer <cem@freebsd.org> To: Hans Petter Selasky <hselasky@freebsd.org>, Johannes Lundberg <johalun0@gmail.com> Cc: src-committers <src-committers@freebsd.org>, svn-src-all <svn-src-all@freebsd.org>, svn-src-head <svn-src-head@freebsd.org> Subject: Re: svn commit: r345103 - head/sys/compat/linuxkpi/common/include/linux Message-ID: <CAG6CVpU0feif5Z99By7R93cVnNi-MjCsoGh_t9j3xhqhNR%2B%2BQA@mail.gmail.com> In-Reply-To: <201903131915.x2DJFbRk002502@repo.freebsd.org> References: <201903131915.x2DJFbRk002502@repo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
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@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAG6CVpU0feif5Z99By7R93cVnNi-MjCsoGh_t9j3xhqhNR%2B%2BQA>
