Loading drivers/pci/iov.c +23 −0 Original line number Diff line number Diff line Loading @@ -597,6 +597,29 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno, 4 * (resno - PCI_IOV_RESOURCES); } /** * pci_sriov_resource_alignment - get resource alignment for VF BAR * @dev: the PCI device * @resno: the resource number * * Returns the alignment of the VF BAR found in the SR-IOV capability. * This is not the same as the resource size which is defined as * the VF BAR size multiplied by the number of VFs. The alignment * is just the VF BAR size. */ int pci_sriov_resource_alignment(struct pci_dev *dev, int resno) { struct resource tmp; enum pci_bar_type type; int reg = pci_iov_resource_bar(dev, resno, &type); if (!reg) return 0; __pci_read_base(dev, type, &tmp, reg); return resource_alignment(&tmp); } /** * pci_restore_iov_state - restore the state of the IOV capability * @dev: the PCI device Loading drivers/pci/pci.h +13 −0 Original line number Diff line number Diff line Loading @@ -243,6 +243,7 @@ extern int pci_iov_init(struct pci_dev *dev); extern void pci_iov_release(struct pci_dev *dev); extern int pci_iov_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); extern int pci_sriov_resource_alignment(struct pci_dev *dev, int resno); extern void pci_restore_iov_state(struct pci_dev *dev); extern int pci_iov_bus_range(struct pci_bus *bus); Loading Loading @@ -298,4 +299,16 @@ static inline int pci_ats_enabled(struct pci_dev *dev) } #endif /* CONFIG_PCI_IOV */ static inline int pci_resource_alignment(struct pci_dev *dev, struct resource *res) { #ifdef CONFIG_PCI_IOV int resno = res - dev->resource; if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END) return pci_sriov_resource_alignment(dev, resno); #endif return resource_alignment(res); } #endif /* DRIVERS_PCI_H */ drivers/pci/setup-bus.c +2 −2 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ #include <linux/ioport.h> #include <linux/cache.h> #include <linux/slab.h> #include "pci.h" static void pbus_assign_resources_sorted(const struct pci_bus *bus) { Loading Loading @@ -384,7 +384,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long continue; r_size = resource_size(r); /* For bridges size != alignment */ align = resource_alignment(r); align = pci_resource_alignment(dev, r); order = __ffs(align) - 20; if (order > 11) { dev_warn(&dev->dev, "BAR %d bad alignment %llx: " Loading drivers/pci/setup-res.c +4 −4 Original line number Diff line number Diff line Loading @@ -144,7 +144,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, size = resource_size(res); min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; align = resource_alignment(res); align = pci_resource_alignment(dev, res); /* First, try exact prefetching match.. */ ret = pci_bus_alloc_resource(bus, res, size, align, min, Loading Loading @@ -178,7 +178,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) struct pci_bus *bus; int ret; align = resource_alignment(res); align = pci_resource_alignment(dev, res); if (!align) { dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus " "alignment) %pR flags %#lx\n", Loading Loading @@ -259,7 +259,7 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) if (!(r->flags) || r->parent) continue; r_align = resource_alignment(r); r_align = pci_resource_alignment(dev, r); if (!r_align) { dev_warn(&dev->dev, "BAR %d: bogus alignment " "%pR flags %#lx\n", Loading @@ -271,7 +271,7 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) struct resource_list *ln = list->next; if (ln) align = resource_alignment(ln->res); align = pci_resource_alignment(ln->dev, ln->res); if (r_align > align) { tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); Loading Loading
drivers/pci/iov.c +23 −0 Original line number Diff line number Diff line Loading @@ -597,6 +597,29 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno, 4 * (resno - PCI_IOV_RESOURCES); } /** * pci_sriov_resource_alignment - get resource alignment for VF BAR * @dev: the PCI device * @resno: the resource number * * Returns the alignment of the VF BAR found in the SR-IOV capability. * This is not the same as the resource size which is defined as * the VF BAR size multiplied by the number of VFs. The alignment * is just the VF BAR size. */ int pci_sriov_resource_alignment(struct pci_dev *dev, int resno) { struct resource tmp; enum pci_bar_type type; int reg = pci_iov_resource_bar(dev, resno, &type); if (!reg) return 0; __pci_read_base(dev, type, &tmp, reg); return resource_alignment(&tmp); } /** * pci_restore_iov_state - restore the state of the IOV capability * @dev: the PCI device Loading
drivers/pci/pci.h +13 −0 Original line number Diff line number Diff line Loading @@ -243,6 +243,7 @@ extern int pci_iov_init(struct pci_dev *dev); extern void pci_iov_release(struct pci_dev *dev); extern int pci_iov_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); extern int pci_sriov_resource_alignment(struct pci_dev *dev, int resno); extern void pci_restore_iov_state(struct pci_dev *dev); extern int pci_iov_bus_range(struct pci_bus *bus); Loading Loading @@ -298,4 +299,16 @@ static inline int pci_ats_enabled(struct pci_dev *dev) } #endif /* CONFIG_PCI_IOV */ static inline int pci_resource_alignment(struct pci_dev *dev, struct resource *res) { #ifdef CONFIG_PCI_IOV int resno = res - dev->resource; if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END) return pci_sriov_resource_alignment(dev, resno); #endif return resource_alignment(res); } #endif /* DRIVERS_PCI_H */
drivers/pci/setup-bus.c +2 −2 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ #include <linux/ioport.h> #include <linux/cache.h> #include <linux/slab.h> #include "pci.h" static void pbus_assign_resources_sorted(const struct pci_bus *bus) { Loading Loading @@ -384,7 +384,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long continue; r_size = resource_size(r); /* For bridges size != alignment */ align = resource_alignment(r); align = pci_resource_alignment(dev, r); order = __ffs(align) - 20; if (order > 11) { dev_warn(&dev->dev, "BAR %d bad alignment %llx: " Loading
drivers/pci/setup-res.c +4 −4 Original line number Diff line number Diff line Loading @@ -144,7 +144,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, size = resource_size(res); min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; align = resource_alignment(res); align = pci_resource_alignment(dev, res); /* First, try exact prefetching match.. */ ret = pci_bus_alloc_resource(bus, res, size, align, min, Loading Loading @@ -178,7 +178,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) struct pci_bus *bus; int ret; align = resource_alignment(res); align = pci_resource_alignment(dev, res); if (!align) { dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus " "alignment) %pR flags %#lx\n", Loading Loading @@ -259,7 +259,7 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) if (!(r->flags) || r->parent) continue; r_align = resource_alignment(r); r_align = pci_resource_alignment(dev, r); if (!r_align) { dev_warn(&dev->dev, "BAR %d: bogus alignment " "%pR flags %#lx\n", Loading @@ -271,7 +271,7 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) struct resource_list *ln = list->next; if (ln) align = resource_alignment(ln->res); align = pci_resource_alignment(ln->dev, ln->res); if (r_align > align) { tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); Loading