From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Jones Subject: [PATCH kvm-unit-tests 3/5] lib/pci: generalize pci_cap_walk Date: Mon, 16 Jan 2017 16:32:13 +0100 Message-ID: <20170116153215.6033-4-drjones@redhat.com> References: <20170116153215.6033-1-drjones@redhat.com> Cc: pbonzini@redhat.com, rkrcmar@redhat.com, peterx@redhat.com To: kvm@vger.kernel.org Return-path: Received: from mx1.redhat.com ([209.132.183.28]:54306 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751007AbdAPPcY (ORCPT ); Mon, 16 Jan 2017 10:32:24 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AB0D88553F for ; Mon, 16 Jan 2017 15:32:23 +0000 (UTC) In-Reply-To: <20170116153215.6033-1-drjones@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: 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 --- 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