aboutsummaryrefslogtreecommitdiff
path: root/core/pci.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2017-06-06 08:59:17 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-06-06 20:49:05 +1000
commitacd94a9c7c589e36db013c026b5910d24af26bab (patch)
tree86fcd295abaa087d58746ecb00e79226672a5780 /core/pci.c
parent25897895a076471dc4566671fda5cf7d2a2c3379 (diff)
downloadskiboot-acd94a9c7c589e36db013c026b5910d24af26bab.zip
skiboot-acd94a9c7c589e36db013c026b5910d24af26bab.tar.gz
skiboot-acd94a9c7c589e36db013c026b5910d24af26bab.tar.bz2
pci: Add bitmap to know if a pci device has cfg reg filters
This avoids doing a search through the list of all devices on every config space access to every device under a PHB. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/pci.c')
-rw-r--r--core/pci.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/core/pci.c b/core/pci.c
index 0adc6d2..5671b69 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -247,6 +247,7 @@ static struct pci_device *pci_scan_one(struct phb *phb, struct pci_device *paren
PCIERR(phb, bdfn,"Failed to allocate structure pci_device !\n");
goto fail;
}
+ pd->phb = phb;
pd->bdfn = bdfn;
pd->vdid = vdid;
pci_cfg_read32(phb, bdfn, PCI_CFG_SUBSYS_VENDOR_ID, &pd->sub_vdid);
@@ -951,6 +952,9 @@ int64_t pci_register_phb(struct phb *phb, int opal_id)
init_lock(&phb->lock);
list_head_init(&phb->devices);
+ phb->filter_map = zalloc(BITMAP_BYTES(0x10000));
+ assert(phb->filter_map);
+
return OPAL_SUCCESS;
}
@@ -1764,6 +1768,11 @@ struct pci_cfg_reg_filter *pci_find_cfg_reg_filter(struct pci_device *pd,
return NULL;
}
+bool pci_device_has_cfg_reg_filters(struct phb *phb, uint16_t bdfn)
+{
+ return bitmap_tst_bit(*phb->filter_map, bdfn);
+}
+
struct pci_cfg_reg_filter *pci_add_cfg_reg_filter(struct pci_device *pd,
uint32_t start, uint32_t len,
uint32_t flags,
@@ -1793,6 +1802,7 @@ struct pci_cfg_reg_filter *pci_add_cfg_reg_filter(struct pci_device *pd,
if (pd->pcrf_end < (start + len))
pd->pcrf_end = start + len;
list_add_tail(&pd->pcrf, &pcrf->link);
+ bitmap_set_bit(*pd->phb->filter_map, pd->bdfn);
return pcrf;
}