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

Reply via email to