===================================================================
@@ -536,6 +536,20 @@ static resource_size_t calculate_memsize
return size;
}
+static resource_size_t get_res_add_size(struct resource_list_x *add_head,
+ struct resource *res)
+{
+ struct resource_list_x *list;
+
+ /* check if it is in add_head list */
+ for (list = add_head->next; list && list->res != res;
+ list = list->next);
+ if (list)
+ return list->add_size;
+
+ return 0;
+}
+
/**
* pbus_size_io() - size the io window of a given bus
*
@@ -555,6 +569,7 @@ static void pbus_size_io(struct pci_bus
struct pci_dev *dev;
struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
unsigned long size = 0, size0 = 0, size1 = 0;
+ resource_size_t children_add_size = 0;
if (!b_res)
return;
@@ -575,10 +590,15 @@ static void pbus_size_io(struct pci_bus
size += r_size;
else
size1 += r_size;
+
+ if (add_head)
+ children_add_size += get_res_add_size(add_head, r);
}
}
size0 = calculate_iosize(size, min_size, size1,
resource_size(b_res), 4096);
+ if (children_add_size > add_size)
+ add_size = children_add_size;
size1 = (!add_head || (add_head && !add_size)) ? size0 :
calculate_iosize(size, min_size+add_size, size1,
resource_size(b_res), 4096);
@@ -620,6 +640,7 @@ static int pbus_size_mem(struct pci_bus
int order, max_order;
struct resource *b_res = find_free_bus_resource(bus, type);
unsigned int mem64_mask = 0;
+ resource_size_t children_add_size = 0;
if (!b_res)
return 0;
@@ -661,6 +682,9 @@ static int pbus_size_mem(struct pci_bus
if (order > max_order)
max_order = order;
mem64_mask &= r->flags & IORESOURCE_MEM_64;
+
+ if (add_head)
+ children_add_size += get_res_add_size(add_head, r);
}
}
align = 0;
@@ -677,6 +701,8 @@ static int pbus_size_mem(struct pci_bus
align += aligns[order];
}
size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align);
+ if (children_add_size > add_size)
+ add_size = children_add_size;
size1 = (!add_head || (add_head && !add_size)) ? size0 :
calculate_memsize(size, min_size+add_size, 0,
resource_size(b_res), min_align);
[PATCH] PCI: Make assign resource to unassigned SRIOV BAR to be optional
make them into add list, so it will make other resource could get resource
allocation at first.
still try to make several try with them by adding them into fail list.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/setup-bus.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
===================================================================
@@ -120,13 +120,16 @@ static inline void reset_resource(struct
* resources
* @head : head of the list tracking requests with allocated
* resources
+ * @fail_head : head of the list tracking requests failed to allocate
+ * resources
*
* Walk through each element of the add_head and try to procure
* additional resources for the element, provided the element
* is in the head list.
*/
static void adjust_resources_sorted(struct resource_list_x *add_head,
- struct resource_list *head)
+ struct resource_list *head,
+ struct resource_list_x *fail_head)
{
struct resource *res;
struct resource_list_x *list, *tmp, *prev;
@@ -153,9 +156,17 @@ static void adjust_resources_sorted(stru
idx = res - &list->dev->resource[0];
add_size=list->add_size;
if (!resource_size(res) && add_size) {
- res->end = res->start + add_size - 1;
- if(pci_assign_resource(list->dev, idx))
+ res->end = res->start + add_size - 1;
+ if(pci_assign_resource(list->dev, idx)) {
+#ifdef CONFIG_PCI_IOV
+ /* add to failed list for next loop */
+ if (fail_head && idx >= PCI_IOV_RESOURCES &&
+ idx <= PCI_IOV_RESOURCE_END)
+ add_to_failed_list(fail_head, list->dev,
+ res);
+#endif
reset_resource(res);
+ }
} else if (add_size) {
adjust_resource(res, res->start,
resource_size(res) + add_size);
@@ -212,7 +223,7 @@ static void __assign_resources_sorted(st
/* Try to satisfy any additional nice-to-have resource
requests */
if (add_head)
- adjust_resources_sorted(add_head, head);
+ adjust_resources_sorted(add_head, head, fail_head);
free_list(resource_list, head);
}
@@ -662,6 +673,15 @@ static int pbus_size_mem(struct pci_bus
if (r->parent || (r->flags & mask) != type)
continue;
r_size = resource_size(r);
+#ifdef CONFIG_PCI_IOV
+ /* put SRIOV requested res to good to have list */
+ if (add_head && i >= PCI_IOV_RESOURCES &&
+ i <= PCI_IOV_RESOURCE_END) {
+ r->end = r->start - 1;
+ add_to_list(add_head, dev, r, r_size);
+ r_size = 0;
+ }
+#endif
/* For bridges size != alignment */
align = pci_resource_alignment(dev, r);
order = __ffs(align) - 20;