From f2a230bd4e1ac4b54ec59dc0b2a246bfe3e89ffe Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Fri, 2 Aug 2013 17:31:03 +0800 Subject: [PATCH 1/4] PCI: Enumerate subordinate buses, not devices, in pci_bus_get_depth() Normally, on one PCI bus there would be more devices than bridges. When calculating the depth of a PCI bus, it would be more time efficient to enumerating through the child buses instead of the child devices. Also by doing so, the code seems more self explaining. Previously, it went through the devices and checked whether a bridge introduced a child bus or not, which needs more background knowledge to understand it. This patch calculates the depth by enumerating the bus hierarchy. Signed-off-by: Wei Yang Signed-off-by: Bjorn Helgaas --- drivers/pci/setup-bus.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index d254e2379533..6dbe5629c8b4 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1300,15 +1300,12 @@ static void pci_bus_dump_resources(struct pci_bus *bus) static int __init pci_bus_get_depth(struct pci_bus *bus) { int depth = 0; - struct pci_dev *dev; + struct pci_bus *child_bus; - list_for_each_entry(dev, &bus->devices, bus_list) { + list_for_each_entry(child_bus, &bus->children, node){ int ret; - struct pci_bus *b = dev->subordinate; - if (!b) - continue; - ret = pci_bus_get_depth(b); + ret = pci_bus_get_depth(child_bus); if (ret + 1 > depth) depth = ret + 1; } From 496f70cf6507be96397d319b1b7d3946d51d9932 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Fri, 2 Aug 2013 17:31:04 +0800 Subject: [PATCH 2/4] PCI: Add comments for pbus_size_mem() parameters This patch fills in the missing description for two parameters of pbus_size_mem(). Signed-off-by: Wei Yang Signed-off-by: Bjorn Helgaas --- drivers/pci/setup-bus.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 6dbe5629c8b4..939ca1b9af92 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -838,6 +838,8 @@ static inline resource_size_t calculate_mem_align(resource_size_t *aligns, * pbus_size_mem() - size the memory window of a given bus * * @bus : the bus + * @mask: mask the resource flag, then compare it with type + * @type: the type of free resource from bridge * @min_size : the minimum memory window that must to be allocated * @add_size : additional optional memory window * @realloc_head : track the additional memory window on this list From 11251a869e84b2a3224955fe149dd33a16805cbf Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Fri, 2 Aug 2013 17:31:05 +0800 Subject: [PATCH 3/4] PCI: Fix types in pbus_size_io() This patch changes the type of "size" to resource_size_t and makes the corresponding dev_printk() change. [bhelgaas: changelog] Signed-off-by: Wei Yang Signed-off-by: Bjorn Helgaas --- drivers/pci/setup-bus.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 939ca1b9af92..d4f1ad956fad 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -747,7 +747,7 @@ 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); - unsigned long size = 0, size0 = 0, size1 = 0; + resource_size_t size = 0, size0 = 0, size1 = 0; resource_size_t children_add_size = 0; resource_size_t min_align, io_align, align; @@ -807,8 +807,9 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align); dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window " - "%pR to %pR add_size %lx\n", b_res, - &bus->busn_res, size1-size0); + "%pR to %pR add_size %llx\n", b_res, + &bus->busn_res, + (unsigned long long)size1-size0); } } From 2d1d66780ecd12c9518835303f5302fc5262d49b Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Mon, 5 Aug 2013 16:15:10 -0600 Subject: [PATCH 4/4] PCI: Align bridge I/O windows as required by downstream devices & bridges An upstream bridge's I/O window must be at least as aligned as any downstream device or bridge requires. In particular, if the upstream bridge supports 1K alignment but a downstream bridge requires 4K alignment, the upstream window must also be 4K aligned. Therefore, do not reduce the required alignment ("min_align") based on the upstream bridge's capabilities. Reported-by: Wei Yang Suggested-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/setup-bus.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index d4f1ad956fad..8333c92c2027 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -749,12 +749,12 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); resource_size_t size = 0, size0 = 0, size1 = 0; resource_size_t children_add_size = 0; - resource_size_t min_align, io_align, align; + resource_size_t min_align, align; if (!b_res) return; - io_align = min_align = window_alignment(bus, IORESOURCE_IO); + min_align = window_alignment(bus, IORESOURCE_IO); list_for_each_entry(dev, &bus->devices, bus_list) { int i; @@ -781,9 +781,6 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, } } - if (min_align > io_align) - min_align = io_align; - size0 = calculate_iosize(size, min_size, size1, resource_size(b_res), min_align); if (children_add_size > add_size)