#define DEBUG_CONFIG 1
#if DEBUG_CONFIG
-# define DBGC(args) printk args
+#define DBG(x...) printk(x)
#else
-# define DBGC(args)
+#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 (4096)
-#define CARDBUS_MEM_SIZE (32*1024*1024)
+#define CARDBUS_IO_SIZE (256)
+#define CARDBUS_MEM_SIZE (64*1024*1024)
static void __devinit
pbus_assign_resources_sorted(struct pci_bus *bus)
struct resource_list head, *list, *tmp;
int idx;
- bus->bridge_ctl &= ~PCI_BRIDGE_CTL_VGA;
-
head.next = NULL;
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;
- if (class == PCI_CLASS_DISPLAY_VGA ||
- class == PCI_CLASS_NOT_DEFINED_VGA)
- bus->bridge_ctl |= PCI_BRIDGE_CTL_VGA;
+ /* 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);
}
for (list = head.next; list;) {
res = list->res;
idx = res - &list->dev->resource[0];
- pci_assign_resource(list->dev, idx);
+ if (pci_assign_resource(list->dev, idx)) {
+ res->start = 0;
+ res->end = 0;
+ res->flags = 0;
+ }
tmp = list;
list = list->next;
kfree(tmp);
}
}
-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;
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)
struct pci_bus_region region;
u32 l, io_upper16;
- DBGC((KERN_INFO "PCI: Bus %d, bridge: %s\n",
- bus->number, pci_name(bridge)));
+ DBG(KERN_INFO "PCI: Bridge: %s\n", pci_name(bridge));
/* Set up the top and bottom of the PCI I/O segment for this bus. */
pcibios_resource_to_bus(bridge, ®ion, bus->resource[0]);
l |= region.end & 0xf000;
/* Set up upper 16 bits of I/O base/limit. */
io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
- DBGC((KERN_INFO " IO window: %04lx-%04lx\n",
- region.start, region.end));
+ DBG(KERN_INFO " IO window: %04lx-%04lx\n",
+ region.start, region.end);
}
else {
/* Clear upper 16 bits of I/O base/limit. */
io_upper16 = 0;
l = 0x00f0;
- DBGC((KERN_INFO " IO window: disabled.\n"));
+ DBG(KERN_INFO " IO window: disabled.\n");
}
/* Temporarily disable the I/O range before updating PCI_IO_BASE. */
pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff);
if (bus->resource[1]->flags & IORESOURCE_MEM) {
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
- DBGC((KERN_INFO " MEM window: %08lx-%08lx\n",
- region.start, region.end));
+ DBG(KERN_INFO " MEM window: %08lx-%08lx\n",
+ region.start, region.end);
}
else {
l = 0x0000fff0;
- DBGC((KERN_INFO " MEM window: disabled.\n"));
+ DBG(KERN_INFO " MEM window: disabled.\n");
}
pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
- DBGC((KERN_INFO " PREFETCH window: %08lx-%08lx\n",
- region.start, region.end));
+ DBG(KERN_INFO " PREFETCH window: %08lx-%08lx\n",
+ region.start, region.end);
}
else {
l = 0x0000fff0;
- DBGC((KERN_INFO " PREFETCH window: disabled.\n"));
+ DBG(KERN_INFO " PREFETCH window: disabled.\n");
}
pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
r = bus->resource[i];
+ if (r == &ioport_resource || r == &iomem_resource)
+ continue;
if (r && (r->flags & type_mask) == type && !r->parent)
return r;
}
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;
}
pbus_assign_resources_sorted(bus);
- if (bus->bridge_ctl & PCI_BRIDGE_CTL_VGA) {
- /* Propagate presence of the VGA to upstream bridges */
- for (b = bus; b->parent; b = b->parent) {
- b->bridge_ctl |= PCI_BRIDGE_CTL_VGA;
- }
- }
list_for_each_entry(dev, &bus->devices, bus_list) {
b = dev->subordinate;
if (!b)