aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/setup-bus.c
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2011-07-25 16:08:38 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2011-08-01 14:49:39 -0400
commitbe768912a49b10b68e96fbd8fa3cab0adfbd3091 (patch)
treed1414e67c840bd66fef1d92177d41a2c22529015 /drivers/pci/setup-bus.c
parentb03e7495a862b028294f59fc87286d6d78ee7fa1 (diff)
PCI: honor child buses add_size in hot plug configuration
git commit c8adf9a3e873eddaaec11ac410a99ef6b9656938 "PCI: pre-allocate additional resources to devices only after successful allocation of essential resources." fails to take into consideration the optional-resources needed by children devices while calculating the optional-resource needed by the bridge. This can be a problem on some setup. For example, if a hotplug bridge has 8 children hotplug bridges, the bridge should have enough resources to accomodate the hotplug requirements for each of its children hotplug bridges. Currently this is not the case. This patch fixes the problem. Signed-off-by: Yinghai Lu <yinghai@kernel.org> Reviewed-by: Ram Pai <linuxram@us.ibm.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/setup-bus.c')
-rw-r--r--drivers/pci/setup-bus.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 8a1d3c7863a8..4409cd0e15fa 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -540,6 +540,20 @@ static resource_size_t calculate_memsize(resource_size_t size,
540 return size; 540 return size;
541} 541}
542 542
543static resource_size_t get_res_add_size(struct resource_list_x *add_head,
544 struct resource *res)
545{
546 struct resource_list_x *list;
547
548 /* check if it is in add_head list */
549 for (list = add_head->next; list && list->res != res;
550 list = list->next);
551 if (list)
552 return list->add_size;
553
554 return 0;
555}
556
543/** 557/**
544 * pbus_size_io() - size the io window of a given bus 558 * pbus_size_io() - size the io window of a given bus
545 * 559 *
@@ -559,6 +573,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
559 struct pci_dev *dev; 573 struct pci_dev *dev;
560 struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); 574 struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
561 unsigned long size = 0, size0 = 0, size1 = 0; 575 unsigned long size = 0, size0 = 0, size1 = 0;
576 resource_size_t children_add_size = 0;
562 577
563 if (!b_res) 578 if (!b_res)
564 return; 579 return;
@@ -579,10 +594,15 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
579 size += r_size; 594 size += r_size;
580 else 595 else
581 size1 += r_size; 596 size1 += r_size;
597
598 if (add_head)
599 children_add_size += get_res_add_size(add_head, r);
582 } 600 }
583 } 601 }
584 size0 = calculate_iosize(size, min_size, size1, 602 size0 = calculate_iosize(size, min_size, size1,
585 resource_size(b_res), 4096); 603 resource_size(b_res), 4096);
604 if (children_add_size > add_size)
605 add_size = children_add_size;
586 size1 = (!add_head || (add_head && !add_size)) ? size0 : 606 size1 = (!add_head || (add_head && !add_size)) ? size0 :
587 calculate_iosize(size, min_size+add_size, size1, 607 calculate_iosize(size, min_size+add_size, size1,
588 resource_size(b_res), 4096); 608 resource_size(b_res), 4096);
@@ -624,6 +644,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
624 int order, max_order; 644 int order, max_order;
625 struct resource *b_res = find_free_bus_resource(bus, type); 645 struct resource *b_res = find_free_bus_resource(bus, type);
626 unsigned int mem64_mask = 0; 646 unsigned int mem64_mask = 0;
647 resource_size_t children_add_size = 0;
627 648
628 if (!b_res) 649 if (!b_res)
629 return 0; 650 return 0;
@@ -665,6 +686,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
665 if (order > max_order) 686 if (order > max_order)
666 max_order = order; 687 max_order = order;
667 mem64_mask &= r->flags & IORESOURCE_MEM_64; 688 mem64_mask &= r->flags & IORESOURCE_MEM_64;
689
690 if (add_head)
691 children_add_size += get_res_add_size(add_head, r);
668 } 692 }
669 } 693 }
670 align = 0; 694 align = 0;
@@ -681,6 +705,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
681 align += aligns[order]; 705 align += aligns[order];
682 } 706 }
683 size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align); 707 size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align);
708 if (children_add_size > add_size)
709 add_size = children_add_size;
684 size1 = (!add_head || (add_head && !add_size)) ? size0 : 710 size1 = (!add_head || (add_head && !add_size)) ? size0 :
685 calculate_memsize(size, min_size+add_size, 0, 711 calculate_memsize(size, min_size+add_size, 0,
686 resource_size(b_res), min_align); 712 resource_size(b_res), min_align);