@@ -123,6 +123,54 @@ int pci_dev_resource_idx(struct pci_dev *dev, struct resource *res)
return -1;
}
+static void __init_res_idx_mask(unsigned long *mask, int flag)
+{
+ bitmap_zero(mask, PCI_NUM_RESOURCES);
+ if (flag & PCI_STD_RES)
+ bitmap_set(mask, PCI_STD_RESOURCES,
+ PCI_STD_RESOURCE_END - PCI_STD_RESOURCES + 1);
+ if (flag & PCI_ROM_RES)
+ bitmap_set(mask, PCI_ROM_RESOURCE, 1);
+#ifdef CONFIG_PCI_IOV
+ if (flag & PCI_IOV_RES)
+ bitmap_set(mask, PCI_IOV_RESOURCES,
+ PCI_IOV_RESOURCE_END - PCI_IOV_RESOURCES + 1);
+#endif
+ if (flag & PCI_BRIDGE_RES)
+ bitmap_set(mask, PCI_BRIDGE_RESOURCES,
+ PCI_BRIDGE_RESOURCE_END - PCI_BRIDGE_RESOURCES + 1);
+}
+
+static DECLARE_BITMAP(res_idx_mask[1 << PCI_RES_BLOCK_NUM], PCI_NUM_RESOURCES);
+static int __init pci_res_idx_mask_init(void)
+{
+ int i;
+
+ for (i = 0; i < (1 << PCI_RES_BLOCK_NUM); i++)
+ __init_res_idx_mask(res_idx_mask[i], i);
+
+ return 0;
+}
+postcore_initcall(pci_res_idx_mask_init);
+
+static inline unsigned long *get_res_idx_mask(int flag)
+{
+ return res_idx_mask[flag & ((1 << PCI_RES_BLOCK_NUM) - 1)];
+}
+
+int pci_next_resource_idx(int i, int flag)
+{
+ i++;
+ if (i < PCI_NUM_RESOURCES)
+ i = find_next_bit(get_res_idx_mask(flag), PCI_NUM_RESOURCES, i);
+
+ if (i < PCI_NUM_RESOURCES)
+ return i;
+
+ return -1;
+}
+EXPORT_SYMBOL(pci_next_resource_idx);
+
static u64 pci_size(u64 base, u64 maxbase, u64 mask)
{
u64 size = mask & maxbase; /* Find the significant bits */
@@ -379,6 +379,30 @@ struct pci_dev {
struct resource *pci_dev_resource_n(struct pci_dev *dev, int n);
int pci_dev_resource_idx(struct pci_dev *dev, struct resource *res);
+#define PCI_STD_RES (1<<0)
+#define PCI_ROM_RES (1<<1)
+#define PCI_IOV_RES (1<<2)
+#define PCI_BRIDGE_RES (1<<3)
+#define PCI_RES_BLOCK_NUM 4
+
+#define PCI_ALL_RES (PCI_STD_RES | PCI_ROM_RES | PCI_BRIDGE_RES | PCI_IOV_RES)
+#define PCI_ROM_IOV_BRIDGE_RES (PCI_ROM_RES | PCI_BRIDGE_RES | PCI_IOV_RES)
+#define PCI_STD_ROM_BRIDGE_RES (PCI_STD_RES | PCI_ROM_RES | PCI_BRIDGE_RES)
+#define PCI_STD_IOV_BRIDGE_RES (PCI_STD_RES | PCI_IOV_RES | PCI_BRIDGE_RES)
+#define PCI_STD_ROM_IOV_RES (PCI_STD_RES | PCI_ROM_RES | PCI_IOV_RES)
+#define PCI_STD_ROM_RES (PCI_STD_RES | PCI_ROM_RES)
+#define PCI_STD_IOV_RES (PCI_STD_RES | PCI_IOV_RES)
+#define PCI_STD_ROM_IOV_RES (PCI_STD_RES | PCI_ROM_RES | PCI_IOV_RES)
+
+int pci_next_resource_idx(int i, int flag);
+
+#define for_each_pci_resource(dev, res, i, flag) \
+ for (i = pci_next_resource_idx(-1, flag), \
+ res = pci_dev_resource_n(dev, i); \
+ res; \
+ i = pci_next_resource_idx(i, flag), \
+ res = pci_dev_resource_n(dev, i))
+
static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
{
#ifdef CONFIG_PCI_IOV