Did a quick test, looks good on my machine.

Thanks :-)

On Mon, Jan 12, 2015 at 11:23:19AM -0800, Yinghai Lu wrote:
>Some bios put range that is not fully coverred by root bus resources.
>Try to clip them and update them in pci bridge bars.
>
>We'd like to fix other arches instead of just x86.
>
>Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
>Reported-by: Marek Kordik <kordikma...@gmail.com>
>Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 
>64-bit resources")
>Signed-off-by: Yinghai Lu <ying...@kernel.org>
>Cc: Benjamin Herrenschmidt <b...@kernel.crashing.org>
>Cc: Paul Mackerras <pau...@samba.org>
>Cc: Michael Ellerman <m...@ellerman.id.au>
>Cc: Gavin Shan <gws...@linux.vnet.ibm.com>
>Cc: Anton Blanchard <an...@samba.org>
>Cc: Sebastian Ott <seb...@linux.vnet.ibm.com>
>Cc: Wei Yang <weiy...@linux.vnet.ibm.com>
>Cc: Andrew Murray <amur...@embedded-bits.co.uk>
>Cc: linuxppc-...@lists.ozlabs.org
>---
> arch/powerpc/kernel/pci-common.c | 43 +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 42 insertions(+), 1 deletion(-)
>
>diff --git a/arch/powerpc/kernel/pci-common.c 
>b/arch/powerpc/kernel/pci-common.c
>index 37d512d..6909546 100644
>--- a/arch/powerpc/kernel/pci-common.c
>+++ b/arch/powerpc/kernel/pci-common.c
>@@ -1148,6 +1148,7 @@ static void pcibios_allocate_bus_resources(struct 
>pci_bus *bus)
>       struct pci_bus *b;
>       int i;
>       struct resource *res, *pr;
>+      bool changed = false;
>
>       pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
>                pci_domain_nr(bus), bus->number);
>@@ -1184,6 +1185,8 @@ static void pcibios_allocate_bus_resources(struct 
>pci_bus *bus)
>                        pr, (pr && pr->name) ? pr->name : "nil");
>
>               if (pr && !(pr->flags & IORESOURCE_UNSET)) {
>+                      struct pci_dev *dev = bus->self;
>+
>                       if (request_resource(pr, res) == 0)
>                               continue;
>                       /*
>@@ -1193,6 +1196,16 @@ static void pcibios_allocate_bus_resources(struct 
>pci_bus *bus)
>                        */
>                       if (reparent_resources(pr, res) == 0)
>                               continue;
>+
>+                      if (dev && i >= PCI_BRIDGE_RESOURCES &&
>+                          i < PCI_NUM_RESOURCES &&
>+                          (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
>+                          pci_bus_clip_resource(dev, res)) {
>+                              changed = true;
>+                              if (pci_claim_resource(dev, i) >= 0)
>+                                      continue;
>+                      }
>+
>               }
>               pr_warning("PCI: Cannot allocate resource region "
>                          "%d of PCI bridge %d, will remap\n", i, bus->number);
>@@ -1208,6 +1221,9 @@ static void pcibios_allocate_bus_resources(struct 
>pci_bus *bus)
>               res->flags = 0;
>       }
>
>+      if (changed)
>+              pci_setup_bridge(bus);
>+
>       list_for_each_entry(b, &bus->children, node)
>               pcibios_allocate_bus_resources(b);
> }
>@@ -1225,6 +1241,13 @@ static inline void alloc_resource(struct pci_dev *dev, 
>int idx)
>       pr = pci_find_parent_resource(dev, r);
>       if (!pr || (pr->flags & IORESOURCE_UNSET) ||
>           request_resource(pr, r) < 0) {
>+              /* try again with clip */
>+              if (idx != PCI_ROM_RESOURCE && pci_bus_clip_resource(dev, r)) {
>+                      pci_update_resource(dev, idx);
>+                      if (pci_claim_resource(dev, idx) >= 0)
>+                              return;
>+              }
>+
>               printk(KERN_WARNING "PCI: Cannot allocate resource region %d"
>                      " of device %s, will remap\n", idx, pci_name(dev));
>               if (pr)
>@@ -1386,6 +1409,7 @@ void pcibios_claim_one_bus(struct pci_bus *bus)
>       struct pci_bus *child_bus;
>
>       list_for_each_entry(dev, &bus->devices, bus_list) {
>+              bool changed = false;
>               int i;
>
>               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
>@@ -1401,8 +1425,25 @@ void pcibios_claim_one_bus(struct pci_bus *bus)
>                                (unsigned long long)r->end,
>                                (unsigned int)r->flags);
>
>-                      pci_claim_resource(dev, i);
>+                      if (pci_claim_resource(dev, i) >= 0)
>+                              continue;
>+
>+                      if (dev->subordinate &&
>+                          i >= PCI_BRIDGE_RESOURCES &&
>+                          i < PCI_NUM_RESOURCES &&
>+                          (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
>+                          pci_bus_clip_resource(dev, r)) {
>+                              changed = true;
>+                              pci_claim_resource(dev, i);
>+                      } else if (i < PCI_BRIDGE_RESOURCES &&
>+                                 i != PCI_ROM_RESOURCE &&
>+                                 pci_bus_clip_resource(dev, r)) {
>+                                      pci_update_resource(dev, i);
>+                                      pci_claim_resource(dev, i);
>+                      }
>               }
>+              if (changed)
>+                      pci_setup_bridge(dev->subordinate);
>       }
>
>       list_for_each_entry(child_bus, &bus->children, node)
>-- 
>1.8.4.5

-- 
Richard Yang
Help you, Help me

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to