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 <hsela...@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 _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"