PCI: methods to access resources of struct pci_dev 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. Signed-off-by: Ram Pai <linuxram@xxxxxxxxxx> diff --git a/include/linux/pci.h b/include/linux/pci.h index e444f5b..475b10d 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1350,6 +1350,58 @@ static inline int pci_domain_nr(struct pci_bus *bus) \ (pci_resource_end((dev), (bar)) - \ pci_resource_start((dev), (bar)) + 1)) +#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) + +/* code that assume the current resource layout will continue to operate */ +static inline struct resource *pci_get_resource(struct pci_dev *pdev, int bar) +{ + if (bar >= 0 && bar < PCI_ROM_RESOURCE) + return pci_get_std_resource(pdev, bar); + else if (bar == PCI_ROM_RESOURCE) + return pci_get_rom_resource(pdev); + else if (bar <= PCI_IOV_RESOURCE_END) + return pci_get_sriov_resource(pdev, bar-PCI_IOV_RESOURCES); + else if (bar <= PCI_BRIDGE_RESOURCE_END) + return pci_get_bridge_resource(pdev, bar-PCI_BRIDGE_RESOURCES); + else + return NULL; +} + +#define for_each_resource(dev, res, i) \ + for (i = 0; \ + (res = pci_get_resource(dev, i)) || i < PCI_NUM_RESOURCES; \ + i++) + +#define for_each_std_resource(dev, res, i) \ + for (i = 0; \ + (res = pci_get_std_resource(dev, i)) || i <= PCI_STD_RESOURCE_END; \ + i++) + +#define for_each_std_and_rom_resource(dev, res, i) \ + for (i = 0; \ + (res = (i==PCI_ROM_RESOURCE)? pci_get_rom_resource(dev) : \ + pci_get_std_resource(dev, i)) || \ + i <= PCI_ROM_RESOURCE; \ + i++) + +#define for_each_sriov_resource(dev, res, i) \ + for (i = 0; \ + (res = pci_get_sriov_resource(dev, i)) || i < PCI_SRIOV_NUM_BARS; \ + i++) + +#define for_each_bridge_resource(dev, res, i) \ + for (i = 0; \ + (res = pci_get_bridge_resource(dev, i)) || i < PCI_BRIDGE_RESOURCE_NUM; \ + i++) + +#define pci_get_res_attr(dev, bar) (((dev)->res_attr)[bar]) +#define pci_get_res_attrwc(dev, bar) (((dev)->res_attr_wc)[bar]) +#define pci_set_res_attr(dev, bar, value) (((dev)->res_attr)[bar] = value) +#define pci_set_res_attrwc(dev, bar, value) (((dev)->res_attr_wc)[bar] = value) /* Similar to the helpers above, these manipulate per-pci_dev * driver-specific data. They are really just a wrapper around -- 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