This patch adds a common function for scanning PCIE Express Capability list The PCIE Capability list starts at 0x100 in extended PCI configuration space.
--- sys/dev/pci/pci.c | 28 ++++++++++++++++++++++++++++ sys/dev/pci/pcivar.h | 2 ++ 2 files changed, 30 insertions(+) diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index bf75f875e..8f9a5ef7a 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -677,6 +677,34 @@ pci_get_ht_capability(pci_chipset_tag_t pc, pcitag_t tag, int capid, return (0); } +int +pcie_get_capability(pci_chipset_tag_t pc, pcitag_t tag, int capid, + int *offset, pcireg_t *value) +{ + pcireg_t reg; + unsigned int ofs; + + /* Make sure we support PCIExpress device */ + if (pci_get_capability(pc, tag, PCI_CAP_PCIEXPRESS, NULL, NULL) == 0) + return (0); + /* Scan PCIExpress capabilities */ + ofs = PCI_PCIE_ECAP; + while (ofs != 0) { + if ((ofs & 3) || (ofs < PCI_PCIE_ECAP)) + return (0); + reg = pci_conf_read(pc, tag, ofs); + if (PCI_PCIE_ECAP_ID(reg) == capid) { + if (offset) + *offset = ofs; + if (value) + *value = reg; + return (1); + } + ofs = PCI_PCIE_ECAP_NEXT(reg); + } + return (0); +} + uint16_t pci_requester_id(pci_chipset_tag_t pc, pcitag_t tag) { diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index bdfe0404f..0376ba992 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -233,6 +233,8 @@ int pci_io_find(pci_chipset_tag_t, pcitag_t, int, bus_addr_t *, int pci_mem_find(pci_chipset_tag_t, pcitag_t, int, bus_addr_t *, bus_size_t *, int *); +int pcie_get_capability(pci_chipset_tag_t, pcitag_t, int, + int *, pcireg_t *); int pci_get_capability(pci_chipset_tag_t, pcitag_t, int, int *, pcireg_t *); int pci_get_ht_capability(pci_chipset_tag_t, pcitag_t, int, -- 2.26.2