diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2015-06-25 10:49:10 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2015-06-30 08:19:25 +0200 |
commit | e38be2d12c4aa6f3552ff189928e323703dd2476 (patch) | |
tree | 916dfaef9ab219c49792285ac856970a980e341e | |
parent | f24eb2f853d4aa28814761e0bbc7df78149f8029 (diff) | |
download | seabios-e38be2d12c4aa6f3552ff189928e323703dd2476.tar.gz |
pci: allow to loop over capabilities
Add a parameter to pci_find_capability, to specify the start point.
This allows to find multiple capabilities of the same type, by calling
pci_find_capability again with the offset of the last capability found.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r-- | src/fw/pciinit.c | 4 | ||||
-rw-r--r-- | src/hw/pci.c | 11 | ||||
-rw-r--r-- | src/hw/pci.h | 2 |
3 files changed, 11 insertions, 6 deletions
diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index ac39d237..45870f20 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -642,7 +642,7 @@ pci_region_create_entry(struct pci_bus *bus, struct pci_device *dev, static int pci_bus_hotplug_support(struct pci_bus *bus) { - u8 pcie_cap = pci_find_capability(bus->bus_dev, PCI_CAP_ID_EXP); + u8 pcie_cap = pci_find_capability(bus->bus_dev, PCI_CAP_ID_EXP, 0); u8 shpc_cap; if (pcie_cap) { @@ -666,7 +666,7 @@ static int pci_bus_hotplug_support(struct pci_bus *bus) return downstream_port && slot_implemented; } - shpc_cap = pci_find_capability(bus->bus_dev, PCI_CAP_ID_SHPC); + shpc_cap = pci_find_capability(bus->bus_dev, PCI_CAP_ID_SHPC, 0); return !!shpc_cap; } diff --git a/src/hw/pci.c b/src/hw/pci.c index 0379b558..a241d067 100644 --- a/src/hw/pci.c +++ b/src/hw/pci.c @@ -221,16 +221,21 @@ pci_find_init_device(const struct pci_device_id *ids, void *arg) return NULL; } -u8 pci_find_capability(struct pci_device *pci, u8 cap_id) +u8 pci_find_capability(struct pci_device *pci, u8 cap_id, u8 cap) { int i; - u8 cap; u16 status = pci_config_readw(pci->bdf, PCI_STATUS); if (!(status & PCI_STATUS_CAP_LIST)) return 0; - cap = pci_config_readb(pci->bdf, PCI_CAPABILITY_LIST); + if (cap == 0) { + /* find first */ + cap = pci_config_readb(pci->bdf, PCI_CAPABILITY_LIST); + } else { + /* find next */ + cap = pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_NEXT); + } for (i = 0; cap && i <= 0xff; i++) { if (pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_ID) == cap_id) return cap; diff --git a/src/hw/pci.h b/src/hw/pci.h index 0aaa84c1..fc5e7b9b 100644 --- a/src/hw/pci.h +++ b/src/hw/pci.h @@ -123,7 +123,7 @@ int pci_init_device(const struct pci_device_id *ids , struct pci_device *pci, void *arg); struct pci_device *pci_find_init_device(const struct pci_device_id *ids , void *arg); -u8 pci_find_capability(struct pci_device *pci, u8 cap_id); +u8 pci_find_capability(struct pci_device *pci, u8 cap_id, u8 cap); int pci_bridge_has_region(struct pci_device *pci, enum pci_region_type region_type); void pci_reboot(void); |