[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1337754877-19759-11-git-send-email-yinghai@kernel.org>
Date: Tue, 22 May 2012 23:34:36 -0700
From: Yinghai Lu <yinghai@...nel.org>
To: Bjorn Helgaas <bhelgaas@...gle.com>
Cc: Andrew Morton <akpm@...ux-foundation.org>,
Linus Torvalds <torvalds@...ux-foundation.org>,
linux-pci@...r.kernel.org, linux-kernel@...r.kernel.org,
Yinghai Lu <yinghai@...nel.org>
Subject: [PATCH 10/11] PCI: Sort unassigned resources with correct alignment
For SIZEALIGN type resource, we need to add back add_size in optional
resource list during __dev_sort_resources(), otherwise those optional
resources will get skipped.
SRIOV BAR is specical one, it will always re-read size for BAR.
Signed-off-by: Yinghai Lu <yinghai@...nel.org>
---
drivers/pci/setup-bus.c | 33 ++++++++++++++++++++++++++-------
1 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 99bc728..ed32864 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -120,8 +120,25 @@ static resource_size_t get_res_add_size(struct list_head *head,
return 0;
}
+static resource_size_t __pci_resource_alignment(
+ struct pci_dev *dev,
+ struct resource *r,
+ struct list_head *realloc_head)
+{
+ resource_size_t r_align, add_size = 0;
+
+ if ((r->flags & IORESOURCE_SIZEALIGN) && realloc_head)
+ add_size = get_res_add_size(realloc_head, r);
+ r->end += add_size;
+ r_align = pci_resource_alignment(dev, r);
+ r->end -= add_size;
+
+ return r_align;
+}
/* Sort resources by alignment */
-static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head)
+static void pdev_sort_resources(struct pci_dev *dev,
+ struct list_head *realloc_head,
+ struct list_head *head)
{
int i;
@@ -139,7 +156,7 @@ static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head)
if (!(r->flags) || r->parent)
continue;
- r_align = pci_resource_alignment(dev, r);
+ r_align = __pci_resource_alignment(dev, r, realloc_head);
if (!r_align) {
dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n",
i, r);
@@ -159,8 +176,9 @@ static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head)
list_for_each_entry(dev_res, head, list) {
resource_size_t align;
- align = pci_resource_alignment(dev_res->dev,
- dev_res->res);
+ align = __pci_resource_alignment(dev_res->dev,
+ dev_res->res,
+ realloc_head);
if (r_align > align ||
(r_align == align &&
@@ -175,6 +193,7 @@ static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head)
}
static void __dev_sort_resources(struct pci_dev *dev,
+ struct list_head *realloc_head,
struct list_head *head)
{
u16 class = dev->class >> 8;
@@ -191,7 +210,7 @@ static void __dev_sort_resources(struct pci_dev *dev,
return;
}
- pdev_sort_resources(dev, head);
+ pdev_sort_resources(dev, realloc_head, head);
}
static inline void reset_resource(struct resource *res)
@@ -387,7 +406,7 @@ static void pdev_assign_resources_sorted(struct pci_dev *dev,
{
LIST_HEAD(head);
- __dev_sort_resources(dev, &head);
+ __dev_sort_resources(dev, add_head, &head);
__assign_resources_sorted(&head, add_head, fail_head);
}
@@ -400,7 +419,7 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus,
LIST_HEAD(head);
list_for_each_entry(dev, &bus->devices, bus_list)
- __dev_sort_resources(dev, &head);
+ __dev_sort_resources(dev, realloc_head, &head);
__assign_resources_sorted(&head, realloc_head, fail_head);
}
--
1.7.7
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists