From 61e83cdde15f8850087d6c57c8576e25b671db59 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 22 Jul 2013 14:37:12 -0700 Subject: PCI: Drop temporary variable in pci_assign_unassigned_resources() Drop the "bus" temporary variable. No functional change, but simplifies later patch slightly. [bhelgaas: changelog, make same change in pci_assign_unassigned_bridge_resources() to keep it parallel with pci_assign_unassigned_resources()] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/setup-bus.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers/pci/setup-bus.c') diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index d254e2379533..cb6bcbb26226 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1458,12 +1458,11 @@ again: * Try to release leaf bridge's resources that doesn't fit resource of * child device under that bridge */ - list_for_each_entry(fail_res, &fail_head, list) { - bus = fail_res->dev->bus; - pci_bus_release_bridge_resources(bus, + list_for_each_entry(fail_res, &fail_head, list) + pci_bus_release_bridge_resources(fail_res->dev->bus, fail_res->flags & type_mask, rel_type); - } + /* restore size and flags */ list_for_each_entry(fail_res, &fail_head, list) { struct resource *res = fail_res->res; @@ -1522,13 +1521,11 @@ again: * Try to release leaf bridge's resources that doesn't fit resource of * child device under that bridge */ - list_for_each_entry(fail_res, &fail_head, list) { - struct pci_bus *bus = fail_res->dev->bus; - unsigned long flags = fail_res->flags; - - pci_bus_release_bridge_resources(bus, flags & type_mask, + list_for_each_entry(fail_res, &fail_head, list) + pci_bus_release_bridge_resources(fail_res->dev->bus, + fail_res->flags & type_mask, whole_subtree); - } + /* restore size and flags */ list_for_each_entry(fail_res, &fail_head, list) { struct resource *res = fail_res->res; -- cgit v1.2.3 From 223d96fc3249b0ffdc30bf77fd90c93f857e9a6e Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 22 Jul 2013 14:37:13 -0700 Subject: PCI: Look for unassigned resources on per-bus basis When CONFIG_PCI_REALLOC_ENABLE_AUTO=y, pci_realloc_detect() looks at PCI devices to see if any have SR-IOV resources that need to be assigned. If it finds any, it turns on automatic resource reallocation. This patch changes pci_realloc_detect() so it uses pci_walk_bus() on each root bus instead of using for_each_pci_dev(). This is a step toward doing reallocation on a per-bus basis, so we can do it for a hot-added host bridge. [bhelgaas: changelog, rename callback to iov_resources_unassigned(), use boolean for "unassigned"] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/setup-bus.c | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) (limited to 'drivers/pci/setup-bus.c') diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index cb6bcbb26226..20c09bd652db 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1359,30 +1359,44 @@ static bool __init pci_realloc_enabled(void) return pci_realloc_enable >= user_enabled; } -static void __init pci_realloc_detect(void) -{ #if defined(CONFIG_PCI_IOV) && defined(CONFIG_PCI_REALLOC_ENABLE_AUTO) - struct pci_dev *dev = NULL; +static int __init iov_resources_unassigned(struct pci_dev *dev, void *data) +{ + int i; + bool *unassigned = data; - if (pci_realloc_enable != undefined) - return; + for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++) { + struct resource *r = &dev->resource[i]; - for_each_pci_dev(dev) { - int i; + /* Not assigned or rejected by kernel? */ + if (r->flags && !r->start) { + *unassigned = true; + return 1; /* return early from pci_walk_bus() */ + } + } - for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++) { - struct resource *r = &dev->resource[i]; + return 0; +} - /* Not assigned, or rejected by kernel ? */ - if (r->flags && !r->start) { - pci_realloc_enable = auto_enabled; +static void __init pci_realloc_detect(void) +{ + bool unassigned = false; + struct pci_bus *bus; - return; - } + if (pci_realloc_enable != undefined) + return; + + list_for_each_entry(bus, &pci_root_buses, node) { + pci_walk_bus(bus, iov_resources_unassigned, &unassigned); + if (unassigned) { + pci_realloc_enable = auto_enabled; + return; } } -#endif } +#else +static void __init pci_realloc_detect(void) { } +#endif /* * first try will not touch pci bridge res -- cgit v1.2.3 From fa216bf4dbe35e15044b90e7b51509768bab3d9a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 22 Jul 2013 14:37:14 -0700 Subject: PCI: Turn on reallocation for unassigned resources with host bridge offset Previously we did not turn on automatic PCI resource reallocation for unassigned IOV resources behind a host bridge with address offset. This patch fixes that bug. The intent was that "!r->start" would check for a BAR containing zero. But that check is incorrect for host bridges that apply an offset, because in that case the resource address is not the same as the bus address. This patch fixes that by converting the resource address back to a bus address before checking for zero. [bhelgaas: changelog] Suggested-by: Benjamin Herrenschmidt Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/setup-bus.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/pci/setup-bus.c') diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 20c09bd652db..ed1bd0cdf521 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1367,9 +1367,14 @@ static int __init iov_resources_unassigned(struct pci_dev *dev, void *data) for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++) { struct resource *r = &dev->resource[i]; + struct pci_bus_region region; /* Not assigned or rejected by kernel? */ - if (r->flags && !r->start) { + if (!r->flags) + continue; + + pcibios_resource_to_bus(dev, ®ion, r); + if (!region.start) { *unassigned = true; return 1; /* return early from pci_walk_bus() */ } -- cgit v1.2.3 From 967260cdb13f9c0de3cf56e305b34eb363e41d5b Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 22 Jul 2013 14:37:15 -0700 Subject: PCI: Enable unassigned resource reallocation on per-bus basis pci_realloc_detect() turns on automatic resource allocation when it finds unassigned SR-IOV resources. Previously it did this on a global basis, so we enabled reallocation if any PCI device anywhere had an unassigned SR-IOV resource. This patch changes pci_realloc_detect() so it looks at a single bus, so we can do this when a host bridge is hot-added. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/setup-bus.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'drivers/pci/setup-bus.c') diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index ed1bd0cdf521..4aaa8d57443f 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1354,9 +1354,9 @@ void __init pci_realloc_get_opt(char *str) else if (!strncmp(str, "on", 2)) pci_realloc_enable = user_enabled; } -static bool __init pci_realloc_enabled(void) +static bool __init pci_realloc_enabled(enum enable_type enable) { - return pci_realloc_enable >= user_enabled; + return enable >= user_enabled; } #if defined(CONFIG_PCI_IOV) && defined(CONFIG_PCI_REALLOC_ENABLE_AUTO) @@ -1383,24 +1383,26 @@ static int __init iov_resources_unassigned(struct pci_dev *dev, void *data) return 0; } -static void __init pci_realloc_detect(void) +static enum enable_type __init pci_realloc_detect(struct pci_bus *bus, + enum enable_type enable_local) { bool unassigned = false; - struct pci_bus *bus; - if (pci_realloc_enable != undefined) - return; + if (enable_local != undefined) + return enable_local; - list_for_each_entry(bus, &pci_root_buses, node) { - pci_walk_bus(bus, iov_resources_unassigned, &unassigned); - if (unassigned) { - pci_realloc_enable = auto_enabled; - return; - } - } + pci_walk_bus(bus, iov_resources_unassigned, &unassigned); + if (unassigned) + return auto_enabled; + + return enable_local; } #else -static void __init pci_realloc_detect(void) { } +static enum enable_type __init pci_realloc_detect(struct pci_bus *bus, + enum enable_type enable_local) +{ + return enable_local; +} #endif /* @@ -1422,10 +1424,12 @@ pci_assign_unassigned_resources(void) unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH; int pci_try_num = 1; + enum enable_type enable_local = pci_realloc_enable; + + list_for_each_entry(bus, &pci_root_buses, node) + enable_local = pci_realloc_detect(bus, enable_local); - /* don't realloc if asked to do so */ - pci_realloc_detect(); - if (pci_realloc_enabled()) { + if (pci_realloc_enabled(enable_local)) { int max_depth = pci_get_max_depth(); pci_try_num = max_depth + 1; @@ -1457,9 +1461,9 @@ again: goto enable_and_dump; if (tried_times >= pci_try_num) { - if (pci_realloc_enable == undefined) + if (enable_local == undefined) printk(KERN_INFO "Some PCI device resources are unassigned, try booting with pci=realloc\n"); - else if (pci_realloc_enable == auto_enabled) + else if (enable_local == auto_enabled) printk(KERN_INFO "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n"); free_list(&fail_head); -- cgit v1.2.3 From 55ed83a615730c2578da155bc99b68f4417ffe20 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 22 Jul 2013 14:37:16 -0700 Subject: PCI: Assign resources on a per-bus basis Previously, we did resource assignment globally. This patch splits up pci_assign_unassigned_resources() so assignment is done for each root bus in turn. We check each root bus individually to see whether it needs any reassignment, and if it does, we assign resources for just that bus. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/setup-bus.c | 62 ++++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 37 deletions(-) (limited to 'drivers/pci/setup-bus.c') diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 4aaa8d57443f..4d9ebb4ce015 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1315,21 +1315,6 @@ static int __init pci_bus_get_depth(struct pci_bus *bus) return depth; } -static int __init pci_get_max_depth(void) -{ - int depth = 0; - struct pci_bus *bus; - - list_for_each_entry(bus, &pci_root_buses, node) { - int ret; - - ret = pci_bus_get_depth(bus); - if (ret > depth) - depth = ret; - } - - return depth; -} /* * -1: undefined, will auto detect later @@ -1410,10 +1395,9 @@ static enum enable_type __init pci_realloc_detect(struct pci_bus *bus, * second and later try will clear small leaf bridge res * will stop till to the max deepth if can not find good one */ -void __init -pci_assign_unassigned_resources(void) +static void __init +pci_assign_unassigned_root_bus_resources(struct pci_bus *bus) { - struct pci_bus *bus; LIST_HEAD(realloc_head); /* list of resources that want additional resources */ struct list_head *add_list = NULL; @@ -1424,17 +1408,17 @@ pci_assign_unassigned_resources(void) unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH; int pci_try_num = 1; - enum enable_type enable_local = pci_realloc_enable; - - list_for_each_entry(bus, &pci_root_buses, node) - enable_local = pci_realloc_detect(bus, enable_local); + enum enable_type enable_local; + /* don't realloc if asked to do so */ + enable_local = pci_realloc_detect(bus, pci_realloc_enable); if (pci_realloc_enabled(enable_local)) { - int max_depth = pci_get_max_depth(); + int max_depth = pci_bus_get_depth(bus); pci_try_num = max_depth + 1; - printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n", - max_depth, pci_try_num); + dev_printk(KERN_DEBUG, &bus->dev, + "max bus depth: %d pci_try_num: %d\n", + max_depth, pci_try_num); } again: @@ -1446,12 +1430,10 @@ again: add_list = &realloc_head; /* Depth first, calculate sizes and alignments of all subordinate buses. */ - list_for_each_entry(bus, &pci_root_buses, node) - __pci_bus_size_bridges(bus, add_list); + __pci_bus_size_bridges(bus, add_list); /* Depth last, allocate resources and update the hardware. */ - list_for_each_entry(bus, &pci_root_buses, node) - __pci_bus_assign_resources(bus, add_list, &fail_head); + __pci_bus_assign_resources(bus, add_list, &fail_head); if (add_list) BUG_ON(!list_empty(add_list)); tried_times++; @@ -1462,16 +1444,16 @@ again: if (tried_times >= pci_try_num) { if (enable_local == undefined) - printk(KERN_INFO "Some PCI device resources are unassigned, try booting with pci=realloc\n"); + dev_info(&bus->dev, "Some PCI device resources are unassigned, try booting with pci=realloc\n"); else if (enable_local == auto_enabled) - printk(KERN_INFO "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n"); + dev_info(&bus->dev, "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n"); free_list(&fail_head); goto enable_and_dump; } - printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n", - tried_times + 1); + dev_printk(KERN_DEBUG, &bus->dev, + "No. %d try to assign unassigned res\n", tried_times + 1); /* third times and later will not check if it is leaf */ if ((tried_times + 1) > 2) @@ -1502,12 +1484,18 @@ again: enable_and_dump: /* Depth last, update the hardware. */ - list_for_each_entry(bus, &pci_root_buses, node) - pci_enable_bridges(bus); + pci_enable_bridges(bus); /* dump the resource on buses */ - list_for_each_entry(bus, &pci_root_buses, node) - pci_bus_dump_resources(bus); + pci_bus_dump_resources(bus); +} + +void __init pci_assign_unassigned_resources(void) +{ + struct pci_bus *root_bus; + + list_for_each_entry(root_bus, &pci_root_buses, node) + pci_assign_unassigned_root_bus_resources(root_bus); } void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) -- cgit v1.2.3 From 928bea964827d7824b548c1f8e06eccbbc4d0d7d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 22 Jul 2013 14:37:17 -0700 Subject: PCI: Delay enabling bridges until they're needed We currently enable PCI bridges after scanning a bus and assigning resources. This is often done in arch code. This patch changes this so we don't enable a bridge until necessary, i.e., until we enable a PCI device behind the bridge. We do this in the generic pci_enable_device() path, so this also removes the arch-specific code to enable bridges. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/setup-bus.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/pci/setup-bus.c') diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 4d9ebb4ce015..8f86be13678f 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1440,7 +1440,7 @@ again: /* any device complain? */ if (list_empty(&fail_head)) - goto enable_and_dump; + goto dump; if (tried_times >= pci_try_num) { if (enable_local == undefined) @@ -1449,7 +1449,7 @@ again: dev_info(&bus->dev, "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n"); free_list(&fail_head); - goto enable_and_dump; + goto dump; } dev_printk(KERN_DEBUG, &bus->dev, @@ -1482,10 +1482,7 @@ again: goto again; -enable_and_dump: - /* Depth last, update the hardware. */ - pci_enable_bridges(bus); - +dump: /* dump the resource on buses */ pci_bus_dump_resources(bus); } @@ -1556,7 +1553,6 @@ enable_all: if (retval) dev_err(&bridge->dev, "Error reenabling bridge (%d)\n", retval); pci_set_master(bridge); - pci_enable_bridges(parent); } EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources); -- cgit v1.2.3 From ff35147cf15814e13c62831f6910f8663e4dc91e Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 24 Jul 2013 15:37:13 -0600 Subject: PCI: Move resource reallocation code to non-__init Resource reallocation is currently done only at boot-time, but will soon be done when host bridge is hot-added. This patch removes the __init annotations so the code will still be present after boot. [bhelgaas: split __init changes out] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/setup-bus.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/pci/setup-bus.c') diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 8f86be13678f..8d1e654256a8 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1297,7 +1297,7 @@ static void pci_bus_dump_resources(struct pci_bus *bus) } } -static int __init pci_bus_get_depth(struct pci_bus *bus) +static int pci_bus_get_depth(struct pci_bus *bus) { int depth = 0; struct pci_dev *dev; @@ -1331,7 +1331,7 @@ enum enable_type { auto_enabled, }; -static enum enable_type pci_realloc_enable __initdata = undefined; +static enum enable_type pci_realloc_enable = undefined; void __init pci_realloc_get_opt(char *str) { if (!strncmp(str, "off", 3)) @@ -1339,13 +1339,13 @@ void __init pci_realloc_get_opt(char *str) else if (!strncmp(str, "on", 2)) pci_realloc_enable = user_enabled; } -static bool __init pci_realloc_enabled(enum enable_type enable) +static bool pci_realloc_enabled(enum enable_type enable) { return enable >= user_enabled; } #if defined(CONFIG_PCI_IOV) && defined(CONFIG_PCI_REALLOC_ENABLE_AUTO) -static int __init iov_resources_unassigned(struct pci_dev *dev, void *data) +static int iov_resources_unassigned(struct pci_dev *dev, void *data) { int i; bool *unassigned = data; @@ -1368,7 +1368,7 @@ static int __init iov_resources_unassigned(struct pci_dev *dev, void *data) return 0; } -static enum enable_type __init pci_realloc_detect(struct pci_bus *bus, +static enum enable_type pci_realloc_detect(struct pci_bus *bus, enum enable_type enable_local) { bool unassigned = false; @@ -1383,7 +1383,7 @@ static enum enable_type __init pci_realloc_detect(struct pci_bus *bus, return enable_local; } #else -static enum enable_type __init pci_realloc_detect(struct pci_bus *bus, +static enum enable_type pci_realloc_detect(struct pci_bus *bus, enum enable_type enable_local) { return enable_local; @@ -1395,8 +1395,7 @@ static enum enable_type __init pci_realloc_detect(struct pci_bus *bus, * second and later try will clear small leaf bridge res * will stop till to the max deepth if can not find good one */ -static void __init -pci_assign_unassigned_root_bus_resources(struct pci_bus *bus) +static void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus) { LIST_HEAD(realloc_head); /* list of resources that want additional resources */ -- cgit v1.2.3 From 39772038ea93e85ea4f1307ec9c1f48a063d89a0 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 22 Jul 2013 14:37:18 -0700 Subject: PCI: Assign resources for hot-added host bridge more aggressively When hot-adding an ACPI host bridge, use pci_assign_unassigned_root_bus_resources() instead of pci_assign_unassigned_bus_resources(). The former is more aggressive and will release and reassign existing resources if necessary. This is safe at hot-add time because no drivers are bound to devices below the new host bridge yet. [bhelgaas: changelog, split __init changes out for reviewability] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/setup-bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/pci/setup-bus.c') diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 8d1e654256a8..94b777d108bb 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1395,7 +1395,7 @@ static enum enable_type pci_realloc_detect(struct pci_bus *bus, * second and later try will clear small leaf bridge res * will stop till to the max deepth if can not find good one */ -static void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus) +void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus) { LIST_HEAD(realloc_head); /* list of resources that want additional resources */ -- cgit v1.2.3 From f2a230bd4e1ac4b54ec59dc0b2a246bfe3e89ffe Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Fri, 2 Aug 2013 17:31:03 +0800 Subject: 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(-) (limited to 'drivers/pci/setup-bus.c') 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; } -- cgit v1.2.3 From 496f70cf6507be96397d319b1b7d3946d51d9932 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Fri, 2 Aug 2013 17:31:04 +0800 Subject: 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(+) (limited to 'drivers/pci/setup-bus.c') 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 -- cgit v1.2.3 From 11251a869e84b2a3224955fe149dd33a16805cbf Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Fri, 2 Aug 2013 17:31:05 +0800 Subject: 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(-) (limited to 'drivers/pci/setup-bus.c') 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); } } -- cgit v1.2.3 From 2d1d66780ecd12c9518835303f5302fc5262d49b Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Mon, 5 Aug 2013 16:15:10 -0600 Subject: 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(-) (limited to 'drivers/pci/setup-bus.c') 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) -- cgit v1.2.3