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