Increase the utility of pci_cap_walk by allowing the caller to supply the table of cap handlers via a single handler, which implements all the cases of interest. Signed-off-by: Andrew Jones <drjones@xxxxxxxxxx> --- lib/pci.h | 3 ++- lib/pci.c | 31 ++++++++++++++----------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/lib/pci.h b/lib/pci.h index 08157544296f..703c1fb689bf 100644 --- a/lib/pci.h +++ b/lib/pci.h @@ -30,7 +30,8 @@ struct pci_dev { extern void pci_dev_init(struct pci_dev *dev, pcidevaddr_t bdf); extern void pci_scan_bars(struct pci_dev *dev); extern void pci_cmd_set_clr(struct pci_dev *dev, uint16_t set, uint16_t clr); -extern void pci_cap_walk(struct pci_dev *dev); +typedef void (*pci_cap_handler_t)(struct pci_dev *dev, int cap_offset, int cap_id); +extern void pci_cap_walk(struct pci_dev *dev, pci_cap_handler_t handler); extern void pci_enable_defaults(struct pci_dev *dev); extern bool pci_setup_msi(struct pci_dev *dev, uint64_t msi_addr, uint32_t msi_data); diff --git a/lib/pci.c b/lib/pci.c index 6ef07df0fd97..99dd830e82ec 100644 --- a/lib/pci.c +++ b/lib/pci.c @@ -7,20 +7,7 @@ #include "pci.h" #include "asm/pci.h" -typedef void (*pci_cap_handler)(struct pci_dev *dev, int cap_offset); - -static void pci_cap_msi_handler(struct pci_dev *dev, int cap_offset) -{ - printf("Detected MSI for device 0x%x offset 0x%x\n", - dev->bdf, cap_offset); - dev->msi_offset = cap_offset; -} - -static pci_cap_handler cap_handlers[PCI_CAP_ID_MAX + 1] = { - [PCI_CAP_ID_MSI] = pci_cap_msi_handler, -}; - -void pci_cap_walk(struct pci_dev *dev) +void pci_cap_walk(struct pci_dev *dev, pci_cap_handler_t handler) { uint8_t cap_offset; uint8_t cap_id; @@ -31,8 +18,7 @@ void pci_cap_walk(struct pci_dev *dev) cap_id = pci_config_readb(dev->bdf, cap_offset); printf("PCI detected cap 0x%x\n", cap_id); assert(cap_id < PCI_CAP_ID_MAX + 1); - if (cap_handlers[cap_id]) - cap_handlers[cap_id](dev, cap_offset); + handler(dev, cap_offset, cap_id); cap_offset = pci_config_readb(dev->bdf, cap_offset + 1); /* Avoid dead loop during cap walk */ assert(++count <= 255); @@ -347,10 +333,21 @@ uint8_t pci_intx_line(struct pci_dev *dev) return pci_config_readb(dev->bdf, PCI_INTERRUPT_LINE); } +static void pci_cap_setup(struct pci_dev *dev, int cap_offset, int cap_id) +{ + switch (cap_id) { + case PCI_CAP_ID_MSI: + printf("Detected MSI for device 0x%x offset 0x%x\n", + dev->bdf, cap_offset); + dev->msi_offset = cap_offset; + break; + } +} + void pci_enable_defaults(struct pci_dev *dev) { pci_scan_bars(dev); /* Enable device DMA operations */ pci_cmd_set_clr(dev, PCI_COMMAND_MASTER, 0); - pci_cap_walk(dev); + pci_cap_walk(dev, pci_cap_setup); } -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html