]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/pci/setup-bus.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mirror_ubuntu-artful-kernel.git] / drivers / pci / setup-bus.c
index 7c443b4583ab67162dd97718636cb30cfbc93b8f..cb1a027eb552228a08bc53cef27af8e7db34e70e 100644 (file)
@@ -309,7 +309,7 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned lon
    since these windows have 4K granularity and the IO ranges
    of non-bridge PCI devices are limited to 256 bytes.
    We must be careful with the ISA aliasing though. */
-static void pbus_size_io(struct pci_bus *bus)
+static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size)
 {
        struct pci_dev *dev;
        struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
@@ -336,6 +336,8 @@ static void pbus_size_io(struct pci_bus *bus)
                                size1 += r_size;
                }
        }
+       if (size < min_size)
+               size = min_size;
 /* To be fixed in 2.5: we should have sort of HAVE_ISA
    flag in the struct pci_bus. */
 #if defined(CONFIG_ISA) || defined(CONFIG_EISA)
@@ -354,7 +356,8 @@ static void pbus_size_io(struct pci_bus *bus)
 
 /* Calculate the size of the bus and minimal alignment which
    guarantees that all child resources fit in this size. */
-static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
+static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
+                        unsigned long type, resource_size_t min_size)
 {
        struct pci_dev *dev;
        resource_size_t min_align, align, size;
@@ -404,6 +407,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
                        mem64_mask &= r->flags & IORESOURCE_MEM_64;
                }
        }
+       if (size < min_size)
+               size = min_size;
 
        align = 0;
        min_align = 0;
@@ -483,6 +488,7 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
 {
        struct pci_dev *dev;
        unsigned long mask, prefmask;
+       resource_size_t min_mem_size = 0, min_io_size = 0;
 
        list_for_each_entry(dev, &bus->devices, bus_list) {
                struct pci_bus *b = dev->subordinate;
@@ -512,8 +518,12 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
 
        case PCI_CLASS_BRIDGE_PCI:
                pci_bridge_check_ranges(bus);
+               if (bus->self->is_hotplug_bridge) {
+                       min_io_size  = pci_hotplug_io_size;
+                       min_mem_size = pci_hotplug_mem_size;
+               }
        default:
-               pbus_size_io(bus);
+               pbus_size_io(bus, min_io_size);
                /* If the bridge supports prefetchable range, size it
                   separately. If it doesn't, or its prefetchable window
                   has already been allocated by arch code, try
@@ -521,9 +531,11 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
                   resources. */
                mask = IORESOURCE_MEM;
                prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
-               if (pbus_size_mem(bus, prefmask, prefmask))
+               if (pbus_size_mem(bus, prefmask, prefmask, min_mem_size))
                        mask = prefmask; /* Success, size non-prefetch only. */
-               pbus_size_mem(bus, mask, IORESOURCE_MEM);
+               else
+                       min_mem_size += min_mem_size;
+               pbus_size_mem(bus, mask, IORESOURCE_MEM, min_mem_size);
                break;
        }
 }