[PATCH] PCI: Export pci_cfg_space_size
[powerpc.git] / drivers / pci / probe.c
index 35caec1..adfad4f 100644 (file)
@@ -72,11 +72,13 @@ void pci_remove_legacy_files(struct pci_bus *bus) { return; }
 /*
  * PCI Bus Class Devices
  */
-static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev, char *buf)
+static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev,
+                                       char *buf)
 {
-       cpumask_t cpumask = pcibus_to_cpumask(to_pci_bus(class_dev));
        int ret;
+       cpumask_t cpumask;
 
+       cpumask = pcibus_to_cpumask(to_pci_bus(class_dev));
        ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask);
        if (ret < PAGE_SIZE)
                buf[ret++] = '\n';
@@ -163,7 +165,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
                if (l == 0xffffffff)
                        l = 0;
                if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) {
-                       sz = pci_size(l, sz, PCI_BASE_ADDRESS_MEM_MASK);
+                       sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK);
                        if (!sz)
                                continue;
                        res->start = l & PCI_BASE_ADDRESS_MEM_MASK;
@@ -213,7 +215,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
                if (l == 0xffffffff)
                        l = 0;
                if (sz && sz != 0xffffffff) {
-                       sz = pci_size(l, sz, PCI_ROM_ADDRESS_MASK);
+                       sz = pci_size(l, sz, (u32)PCI_ROM_ADDRESS_MASK);
                        if (sz) {
                                res->flags = (l & IORESOURCE_ROM_ENABLE) |
                                  IORESOURCE_MEM | IORESOURCE_PREFETCH |
@@ -262,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];
@@ -400,6 +404,12 @@ static void pci_enable_crs(struct pci_dev *dev)
 static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max)
 {
        struct pci_bus *parent = child->parent;
+
+       /* Attempts to fix that up are really dangerous unless
+          we're going to re-assign all bus numbers. */
+       if (!pcibios_assign_all_busses())
+               return;
+
        while (parent->parent && parent->subordinate < max) {
                parent->subordinate = max;
                pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max);
@@ -423,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);
@@ -476,8 +486,18 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
                 * We need to assign a number to this bus which we always
                 * do in the second pass.
                 */
-               if (!pass)
+               if (!pass) {
+                       if (pcibios_assign_all_busses())
+                               /* Temporarily disable forwarding of the
+                                  configuration cycles on all bridges in
+                                  this bus segment to avoid possible
+                                  conflicts in the second pass between two
+                                  bridges programmed with overlapping
+                                  bus ranges. */
+                               pci_write_config_dword(dev, PCI_PRIMARY_BUS,
+                                                      buses & ~0xffffff);
                        return max;
+               }
 
                /* Clear errors */
                pci_write_config_word(dev, PCI_STATUS, 0xffff);
@@ -523,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);
                }
@@ -541,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;
 }
 
@@ -553,6 +608,7 @@ static void pci_read_irq(struct pci_dev *dev)
        unsigned char irq;
 
        pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq);
+       dev->pin = irq;
        if (irq)
                pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
        dev->irq = irq;
@@ -606,6 +662,7 @@ static int pci_setup_device(struct pci_dev * dev)
                /* The PCI-to-PCI bridge spec requires that subtractive
                   decoding (i.e. transparent) bridge must have programming
                   interface code of 0x01. */ 
+               pci_read_irq(dev);
                dev->transparent = ((dev->class & 0xff) == 1);
                pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
                break;
@@ -651,6 +708,7 @@ static void pci_release_dev(struct device *dev)
 
 /**
  * pci_cfg_space_size - get the configuration space size of the PCI device.
+ * @dev: PCI device
  *
  * Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices
  * have 4096 bytes.  Even if the device is capable, that doesn't mean we can
@@ -659,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;