[RFC PATCH v3 ]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.
    
    Next step, change the code in all the drivers that access the
    resource structure to use the new iterator.
    
    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 v2:
            Consolidated iterator interface as per Bjorn's suggestion.
    
    Changelog v3:
    	ability to get index of the returned resource. Suggested by Yinghai.
    	Incorporates Yinghai's code snippets.
    
<TODO get Yinghai's SOB>
Signed-off-by: Ram Pai <linuxram@xxxxxxxxxx>

diff --git a/include/linux/pci.h b/include/linux/pci.h
index e444f5b..7101da2 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1351,6 +1351,48 @@ 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		(1<<0)
+#define PCI_ROM_RES		(1<<1)
+#define PCI_BRIDGE_RES		(1<<2)
+#define PCI_IOV_RES		(1<<3)
+#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_NOBRIDGE_RES)
+
+static inline struct resource *pci_dev_resource_n(struct pci_dev *dev, int n)
+{
+	if (n >= 0 && n < PCI_NUM_RESOURCES)
+		return &dev->resource[n];
+
+	return NULL;
+}
+
+static inline int pci_next_resource_idx(int i, int flag)
+{
+	while (++i < PCI_NUM_RESOURCES) {
+		if ((i >= 0 && i < PCI_ROM_RESOURCE && (flag & PCI_STD_RES)) ||
+		    (i == PCI_ROM_RESOURCE && (flag & PCI_ROM_RES)) ||
+#ifdef CONFIG_PCI_IOV
+		    (i <= PCI_IOV_RESOURCE_END && (flag & PCI_IOV_RES)) ||
+#endif
+		    (i <= PCI_BRIDGE_RESOURCE_END && (flag & PCI_BRIDGE_RES)))
+			return i;
+	}
+	return -1;
+}
+
+#define for_each_pci_resource(dev, res, 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))
+
 /* 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