fuse: add support for mandatory locking
[safe/jmp/linux-2.6] / drivers / pci / setup-bus.c
index 6b0e646..401e03c 100644 (file)
 #define DBG(x...)
 #endif
 
-#define ROUND_UP(x, a)         (((x) + (a) - 1) & ~((a) - 1))
-
-/*
- * FIXME: IO should be max 256 bytes.  However, since we may
- * have a P2P bridge below a cardbus bridge, we need 4K.
- */
-#define CARDBUS_IO_SIZE                (4*1024)
-#define CARDBUS_MEM_SIZE       (32*1024*1024)
-
-static void __devinit
-pbus_assign_resources_sorted(struct pci_bus *bus)
+static void pbus_assign_resources_sorted(struct pci_bus *bus)
 {
        struct pci_dev *dev;
        struct resource *res;
@@ -55,11 +45,19 @@ pbus_assign_resources_sorted(struct pci_bus *bus)
        list_for_each_entry(dev, &bus->devices, bus_list) {
                u16 class = dev->class >> 8;
 
-               /* Don't touch classless devices and host bridges.  */
+               /* Don't touch classless devices or host bridges or ioapics.  */
                if (class == PCI_CLASS_NOT_DEFINED ||
                    class == PCI_CLASS_BRIDGE_HOST)
                        continue;
 
+               /* Don't touch ioapic devices already enabled by firmware */
+               if (class == PCI_CLASS_SYSTEM_PIC) {
+                       u16 command;
+                       pci_read_config_word(dev, PCI_COMMAND, &command);
+                       if (command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))
+                               continue;
+               }
+
                pdev_sort_resources(dev, &head);
        }
 
@@ -77,8 +75,7 @@ pbus_assign_resources_sorted(struct pci_bus *bus)
        }
 }
 
-static void __devinit
-pci_setup_cardbus(struct pci_bus *bus)
+void pci_setup_cardbus(struct pci_bus *bus)
 {
        struct pci_dev *bridge = bus->self;
        struct pci_bus_region region;
@@ -130,6 +127,7 @@ pci_setup_cardbus(struct pci_bus *bus)
                                        region.end);
        }
 }
+EXPORT_SYMBOL(pci_setup_cardbus);
 
 /* Initialize bridges with base/limit values we have collected.
    PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998)
@@ -219,8 +217,7 @@ pci_setup_bridge(struct pci_bus *bus)
 /* Check whether the bridge supports optional I/O and
    prefetchable memory ranges. If not, the respective
    base/limit registers must be read-only and read as 0. */
-static void __devinit
-pci_bridge_check_ranges(struct pci_bus *bus)
+static void pci_bridge_check_ranges(struct pci_bus *bus)
 {
        u16 io;
        u32 pmem;
@@ -258,8 +255,7 @@ pci_bridge_check_ranges(struct pci_bus *bus)
    bus resource of a given type. Note: we intentionally skip
    the bus resources which have already been assigned (that is,
    have non-NULL parent resource). */
-static struct resource * __devinit
-find_free_bus_resource(struct pci_bus *bus, unsigned long type)
+static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned long type)
 {
        int i;
        struct resource *r;
@@ -280,8 +276,7 @@ find_free_bus_resource(struct pci_bus *bus, unsigned long type)
    since these windows have 4K granularity and the IO ranges
    of non-bridge PCI devices are limited to 256 bytes.
    We must be careful with the ISA aliasing though. */
-static void __devinit
-pbus_size_io(struct pci_bus *bus)
+static void pbus_size_io(struct pci_bus *bus)
 {
        struct pci_dev *dev;
        struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
@@ -313,7 +308,7 @@ pbus_size_io(struct pci_bus *bus)
 #if defined(CONFIG_ISA) || defined(CONFIG_EISA)
        size = (size & 0xff) + ((size & ~0xffUL) << 2);
 #endif
-       size = ROUND_UP(size + size1, 4096);
+       size = ALIGN(size + size1, 4096);
        if (!size) {
                b_res->flags = 0;
                return;
@@ -325,8 +320,7 @@ pbus_size_io(struct pci_bus *bus)
 
 /* Calculate the size of the bus and minimal alignment which
    guarantees that all child resources fit in this size. */
-static int __devinit
-pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
+static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
 {
        struct pci_dev *dev;
        unsigned long min_align, align, size;
@@ -356,8 +350,10 @@ pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
                        order = __ffs(align) - 20;
                        if (order > 11) {
                                printk(KERN_WARNING "PCI: region %s/%d "
-                                      "too large: %lx-%lx\n",
-                                      pci_name(dev), i, r->start, r->end);
+                                      "too large: %llx-%llx\n",
+                                       pci_name(dev), i,
+                                       (unsigned long long)r->start,
+                                       (unsigned long long)r->end);
                                r->flags = 0;
                                continue;
                        }
@@ -380,11 +376,11 @@ pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
 
                if (!align)
                        min_align = align1;
-               else if (ROUND_UP(align + min_align, min_align) < align1)
+               else if (ALIGN(align + min_align, min_align) < align1)
                        min_align = align1 >> 1;
                align += aligns[order];
        }
-       size = ROUND_UP(size, min_align);
+       size = ALIGN(size, min_align);
        if (!size) {
                b_res->flags = 0;
                return 1;
@@ -405,12 +401,12 @@ pci_bus_size_cardbus(struct pci_bus *bus)
         * Reserve some resources for CardBus.  We reserve
         * a fixed amount of bus space for CardBus bridges.
         */
-       b_res[0].start = CARDBUS_IO_SIZE;
-       b_res[0].end = b_res[0].start + CARDBUS_IO_SIZE - 1;
+       b_res[0].start = pci_cardbus_io_size;
+       b_res[0].end = b_res[0].start + pci_cardbus_io_size - 1;
        b_res[0].flags |= IORESOURCE_IO;
 
-       b_res[1].start = CARDBUS_IO_SIZE;
-       b_res[1].end = b_res[1].start + CARDBUS_IO_SIZE - 1;
+       b_res[1].start = pci_cardbus_io_size;
+       b_res[1].end = b_res[1].start + pci_cardbus_io_size - 1;
        b_res[1].flags |= IORESOURCE_IO;
 
        /*
@@ -430,22 +426,21 @@ pci_bus_size_cardbus(struct pci_bus *bus)
         * twice the size.
         */
        if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) {
-               b_res[2].start = CARDBUS_MEM_SIZE;
-               b_res[2].end = b_res[2].start + CARDBUS_MEM_SIZE - 1;
+               b_res[2].start = pci_cardbus_mem_size;
+               b_res[2].end = b_res[2].start + pci_cardbus_mem_size - 1;
                b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
 
-               b_res[3].start = CARDBUS_MEM_SIZE;
-               b_res[3].end = b_res[3].start + CARDBUS_MEM_SIZE - 1;
+               b_res[3].start = pci_cardbus_mem_size;
+               b_res[3].end = b_res[3].start + pci_cardbus_mem_size - 1;
                b_res[3].flags |= IORESOURCE_MEM;
        } else {
-               b_res[3].start = CARDBUS_MEM_SIZE * 2;
-               b_res[3].end = b_res[3].start + CARDBUS_MEM_SIZE * 2 - 1;
+               b_res[3].start = pci_cardbus_mem_size * 2;
+               b_res[3].end = b_res[3].start + pci_cardbus_mem_size * 2 - 1;
                b_res[3].flags |= IORESOURCE_MEM;
        }
 }
 
-void __devinit
-pci_bus_size_bridges(struct pci_bus *bus)
+void pci_bus_size_bridges(struct pci_bus *bus)
 {
        struct pci_dev *dev;
        unsigned long mask, prefmask;
@@ -477,7 +472,12 @@ pci_bus_size_bridges(struct pci_bus *bus)
                break;
 
        case PCI_CLASS_BRIDGE_PCI:
+               /* don't size subtractive decoding (transparent)
+                * PCI-to-PCI bridges */
+               if (bus->self->transparent)
+                       break;
                pci_bridge_check_ranges(bus);
+               /* fall through */
        default:
                pbus_size_io(bus);
                /* If the bridge supports prefetchable range, size it
@@ -495,8 +495,7 @@ pci_bus_size_bridges(struct pci_bus *bus)
 }
 EXPORT_SYMBOL(pci_bus_size_bridges);
 
-void __devinit
-pci_bus_assign_resources(struct pci_bus *bus)
+void pci_bus_assign_resources(struct pci_bus *bus)
 {
        struct pci_bus *b;
        struct pci_dev *dev;