[RFC PATCH v2 ]pci: pci resource iterator

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



PCI: pci resource iterator
    
Currently pci_dev structure holds an array of 17 PCI resources; six base
BARs, one ROM BAR, four BRIDGE BARs, six sriov BARs.  This is wasteful.
A bridge device just needs the 4 bridge resources. A non-bridge device
just needs the six base resources and one ROM resource. The sriov
resources are needed only if the device has SRIOV capability.
    
The pci_dev structure needs to be re-organized to avoid unnecessary
bloating.  However too much code outside the pci-bus driver, assumes the
internal details of the pci_dev structure, thus making it hard to
re-organize the datastructure.
    
As a first step this patch provides generic methods to access the
resource structure of the pci_dev.
    
Once this patch is accepted, I have another 40+ patches that modify all
the files that directly access the resource structure, to use the new
methods provided in the first step.
    
Finally we can re-organize the resource structure in the pci_dev
structure and correspondingly update the methods.

This patch is compile tested only.

Changelog: 
	Consolidated iterator interface as per Bjorn's suggestion.
    
Signed-off-by: Ram Pai <linuxram@xxxxxxxxxx>

diff --git a/include/linux/pci.h b/include/linux/pci.h
index e444f5b..ab897fd 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1351,6 +1351,49 @@ static inline int pci_domain_nr(struct pci_bus *bus)
 	 (pci_resource_end((dev), (bar)) -		\
 	  pci_resource_start((dev), (bar)) + 1))
 
+#define PCI_STD_RES 		0x01
+#define PCI_ROM_RES 		0x02
+#define PCI_BRIDGE_RES		0x04
+#define PCI_IOV_RES 		0x08
+#define PCI_ALL_RES 		PCI_STD_RES|PCI_ROM_RES|PCI_BRIDGE_RES|PCI_IOV_RES
+#define PCI_NOSTD_RES 		PCI_ALL_RES&(^PCI_STD_RES)
+#define PCI_NOIOV_RES 		PCI_ALL_RES&(^PCI_IOV_RES)
+#define PCI_NOROM_RES 		PCI_ALL_RES&(^PCI_ROM_RES)
+#define PCI_NOBRIDGE_RES 	PCI_ALL_RES&(^PCI_BRIDGE_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
+
+#define pci_get_std_resource(dev, bar)     (((dev)->resource)+bar)
+#define pci_get_sriov_resource(dev, bar)     (((dev)->resource)+bar+PCI_IOV_RESOURCES)
+#define pci_get_bridge_resource(dev, bar)    (((dev)->resource)+bar+PCI_BRIDGE_RESOURCES)
+#define pci_get_rom_resource(dev)    	     (((dev)->resource)+PCI_ROM_RESOURCE)
+#define pci_resource_number(dev, res)	     (res - (dev)->resource)
+
+
+static inline struct resource *pci_next_resource(struct pci_dev *pdev,
+			struct resource *res, int flag)
+{
+	int i = res? pci_resource_number(pdev, res) : -1;
+
+	while (++i < PCI_NUM_RESOURCES) {
+		if ((i >= 0 && i < PCI_ROM_RESOURCE) && (flag & PCI_STD_RES))
+			return pci_get_std_resource(pdev, i);
+		else if ((i == PCI_ROM_RESOURCE) && (flag & PCI_ROM_RES))
+			return pci_get_rom_resource(pdev);
+		else if ((i <= PCI_IOV_RESOURCE_END) && (flag & PCI_IOV_RES))
+			return pci_get_sriov_resource(pdev, i-PCI_IOV_RESOURCES);
+		else if ((i <= PCI_BRIDGE_RESOURCE_END) && (flag & PCI_BRIDGE_RES))
+			return pci_get_bridge_resource(pdev, i-PCI_BRIDGE_RESOURCES);
+	}
+	return NULL;
+}
+
+
+#define for_each_pci_resource(dev, res, flag) \
+	for (res = pci_next_resource(dev, NULL, flag); res; \
+			res = pci_next_resource(dev, res, flag))
+
 /* Similar to the helpers above, these manipulate per-pci_dev
  * driver-specific data.  They are really just a wrapper around
  * the generic device structure functions of these calls.

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux