]> err.no Git - linux-2.6/blobdiff - drivers/pci/probe.c
[PATCH] PCI: Reduce nr of ptr derefs in drivers/pci/hotplug/rpaphp_pci.c
[linux-2.6] / drivers / pci / probe.c
index 79be37a533973153729b0974691b79559f496a0c..adfad4fd6a13d66297546c917c8833f65b13a256 100644 (file)
@@ -264,8 +264,10 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
 
        if (base <= limit) {
                res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
-               res->start = base;
-               res->end = limit + 0xfff;
+               if (!res->start)
+                       res->start = base;
+               if (!res->end)
+                       res->end = limit + 0xfff;
        }
 
        res = child->resource[1];
@@ -431,7 +433,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
 {
        struct pci_bus *child;
        int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
-       u32 buses, i;
+       u32 buses, i, j = 0;
        u16 bctl;
 
        pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
@@ -541,10 +543,29 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
                         * as cards with a PCI-to-PCI bridge can be
                         * inserted later.
                         */
-                       for (i=0; i<CARDBUS_RESERVE_BUSNR; i++)
+                       for (i=0; i<CARDBUS_RESERVE_BUSNR; i++) {
+                               struct pci_bus *parent = bus;
                                if (pci_find_bus(pci_domain_nr(bus),
                                                        max+i+1))
                                        break;
+                               while (parent->parent) {
+                                       if ((!pcibios_assign_all_busses()) &&
+                                           (parent->subordinate > max) &&
+                                           (parent->subordinate <= max+i)) {
+                                               j = 1;
+                                       }
+                                       parent = parent->parent;
+                               }
+                               if (j) {
+                                       /*
+                                        * Often, there are two cardbus bridges
+                                        * -- try to leave one valid bus number
+                                        * for each one.
+                                        */
+                                       i /= 2;
+                                       break;
+                               }
+                       }
                        max += i;
                        pci_fixup_parent_subordinate_busnr(child, max);
                }
@@ -559,6 +580,22 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
 
        sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number);
 
+       while (bus->parent) {
+               if ((child->subordinate > bus->subordinate) ||
+                   (child->number > bus->subordinate) ||
+                   (child->number < bus->number) ||
+                   (child->subordinate < bus->number)) {
+                       printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) may be "
+                              "hidden behind%s bridge #%02x (-#%02x)%s\n",
+                              child->number, child->subordinate,
+                              bus->self->transparent ? " transparent" : " ",
+                              bus->number, bus->subordinate,
+                              pcibios_assign_all_busses() ? " " :
+                              " (try 'pci=assign-busses')");
+               }
+               bus = bus->parent;
+       }
+
        return max;
 }
 
@@ -680,7 +717,7 @@ static void pci_release_dev(struct device *dev)
  * reading the dword at 0x100 which must either be 0 or a valid extended
  * capability header.
  */
-static int pci_cfg_space_size(struct pci_dev *dev)
+int pci_cfg_space_size(struct pci_dev *dev)
 {
        int pos;
        u32 status;