diff -urp 2.4.0t10/arch/alpha/kernel/pci.c linux/arch/alpha/kernel/pci.c --- 2.4.0t10/arch/alpha/kernel/pci.c Tue Aug 1 18:55:34 2000 +++ linux/arch/alpha/kernel/pci.c Mon Nov 6 14:21:13 2000 @@ -8,6 +8,11 @@ /* 2.3.x PCI/resources, 1999 Andrea Arcangeli */ +/* + * Nov 2000, Ivan Kokshaysky + * PCI-PCI bridges cleanup + */ + #include #include #include @@ -71,6 +76,26 @@ quirk_ali_ide_ports(struct pci_dev *dev) dev->resource[3].end = dev->resource[3].start + 7; } +/* + * Notorious Cy82C693 chip. One of its numerous bugs: although + * Cypress IDE controller doesn't support native mode, it has + * programmable addresses of IDE command/control registers. + * This violates PCI specifications, confuses IDE subsystem + * and causes resource conflict between primary HD_CMD register + * and floppy controller. Ugh. + * Fix that. + */ +static void __init +quirk_cypress_ide_ports(struct pci_dev *dev) +{ + if (dev->class >> 8 != PCI_CLASS_STORAGE_IDE) + return; + dev->resource[1].start |= 2; + dev->resource[1].end = dev->resource[1].start; + pci_claim_resource(dev, 0); + pci_claim_resource(dev, 1); +} + static void __init quirk_vga_enable_rom(struct pci_dev *dev) { @@ -78,7 +103,6 @@ quirk_vga_enable_rom(struct pci_dev *dev But if its a Cirrus 543x/544x DISABLE it, since enabling ROM disables the memory... */ if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA && - /* But if its a Cirrus 543x/544x DISABLE it */ (dev->vendor != PCI_VENDOR_ID_CIRRUS || (dev->device < 0x00a0) || (dev->device > 0x00ac))) { @@ -98,6 +122,8 @@ struct pci_fixup pcibios_fixups[] __init quirk_isa_bridge }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, quirk_ali_ide_ports }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, + quirk_cypress_ide_ports }, { PCI_FIXUP_FINAL, PCI_ANY_ID, PCI_ANY_ID, quirk_vga_enable_rom }, { 0 } }; @@ -122,18 +148,12 @@ pcibios_align_resource(void *data, struc start = PCIBIOS_MIN_IO + hose->io_space->start; /* - * Aligning to 0x800 rather than the minimum base of - * 0x400 is an attempt to avoid having devices in - * any 0x?C?? range, which is where the de4x5 driver - * probes for EISA cards. - * - * Adaptecs, especially, resent such intrusions. - * - * The de4x5 driver has the eisa probe conditionalized - * out for Alpha, so lower the minimum base back to 0x400. + * Put everything into 0x00-0xff region modulo 0x400 */ - alignto = MAX(0x400, size); - start = ALIGN(start, alignto); + if (start & 0x300) { + start = (start + 0x3ff) & ~0x3ff; + res->start = start; + } } else if (res->flags & IORESOURCE_MEM) { /* Make sure we start at our min on all hoses */ @@ -181,44 +201,6 @@ pcibios_align_resource(void *data, struc #undef MB #undef GB -/* - * Pre-layout host-independant device initialization. - */ - -static void __init -pcibios_assign_special(struct pci_dev * dev) -{ - int i; - - /* The first three resources of an IDE controler are often magic, - so leave them unchanged. This is true, for instance, of the - Contaq 82C693 as seen on SX164 and DP264. */ - - if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE) { - /* Resource 1 of IDE controller is the address of HD_CMD - register which actually occupies a single byte (0x3f6 - for ide0) in reported 0x3f4-3f7 range. We have to fix - that to avoid resource conflict with AT-style floppy - controller. */ - dev->resource[1].start += 2; - dev->resource[1].end = dev->resource[1].start; - for (i = 0; i < PCI_NUM_RESOURCES; i++) - if (dev->resource[i].flags && dev->resource[i].start) - pci_claim_resource(dev, i); - } - /* - * We don't have code that will init the CYPRESS bridge correctly - * so we do the next best thing, and depend on the previous - * console code to do the right thing, and ignore it here... :-\ - */ - else if (dev->vendor == PCI_VENDOR_ID_CONTAQ && - dev->device == PCI_DEVICE_ID_CONTAQ_82C693) - for (i = 0; i < PCI_NUM_RESOURCES; i++) - if (dev->resource[i].flags && dev->resource[i].start) - pci_claim_resource(dev, i); -} - - void __init pcibios_init(void) { @@ -257,7 +239,6 @@ pcibios_fixup_device_resources(struct pc pcibios_fixup_resource(&dev->resource[i], hose->mem_space); } - pcibios_assign_special(dev); } void __init @@ -265,17 +246,33 @@ pcibios_fixup_bus(struct pci_bus *bus) { /* Propogate hose info into the subordinate devices. */ - struct pci_controler *hose = (struct pci_controler *) bus->sysdata; + struct pci_controler *hose = bus->sysdata; struct list_head *ln; + struct pci_dev *dev = bus->self; + + if (!dev) { + /* Root bus */ + bus->resource[0] = hose->io_space; + bus->resource[1] = hose->mem_space; + } else { + /* This is a bridge. Do not care how it's initialized, + just link its resources to the bus ones */ + int i; - /* ???? */ - bus->resource[0] = hose->io_space; - bus->resource[1] = hose->mem_space; - - /* If this is a bridge, get the current bases */ - if (bus->self) { - pci_read_bridge_bases(bus); - pcibios_fixup_device_resources(bus->self, bus->parent); + for(i=0; i<3; i++) { + bus->resource[i] = + &dev->resource[PCI_BRIDGE_RESOURCES+i]; + bus->resource[i]->name = bus->name; + } + bus->resource[0]->flags |= IORESOURCE_IO; + bus->resource[1]->flags |= IORESOURCE_MEM; + /* For now, propogate hose limits to the bus; + we'll adjust them later. */ + bus->resource[0]->end = hose->io_space->end; + bus->resource[1]->end = hose->mem_space->end; + /* Turn off downstream PF memory address range by default */ + bus->resource[2]->start = 1024*1024; + bus->resource[2]->end = bus->resource[2]->start - 1; } for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { @@ -385,99 +382,6 @@ pcibios_set_master(struct pci_dev *dev) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); } -#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) - -static void __init -pcibios_size_bridge(struct pci_bus *bus, struct pbus_set_ranges_data *outer) -{ - struct pbus_set_ranges_data inner; - struct pci_dev *dev; - struct pci_dev *bridge = bus->self; - struct pci_controler *hose = bus->sysdata; - struct list_head *ln; - - if (!bridge) - return; /* host bridge, nothing to do */ - - /* set reasonable default locations for pcibios_align_resource */ - inner.io_start = hose->io_space->start + PCIBIOS_MIN_IO; - inner.mem_start = hose->mem_space->start + PCIBIOS_MIN_MEM; - inner.io_end = inner.io_start; - inner.mem_end = inner.mem_start; - - /* Collect information about how our direct children are layed out. */ - for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) { - int i; - dev = pci_dev_b(ln); - - /* Skip bridges for now */ - if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI) - continue; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource res; - unsigned long size; - - memcpy(&res, &dev->resource[i], sizeof(res)); - size = res.end - res.start + 1; - - if (res.flags & IORESOURCE_IO) { - res.start = inner.io_end; - pcibios_align_resource(dev, &res, size); - inner.io_end = res.start + size; - } else if (res.flags & IORESOURCE_MEM) { - res.start = inner.mem_end; - pcibios_align_resource(dev, &res, size); - inner.mem_end = res.start + size; - } - } - } - - /* And for all of the subordinate busses. */ - for (ln=bus->children.next; ln != &bus->children; ln=ln->next) - pcibios_size_bridge(pci_bus_b(ln), &inner); - - /* turn the ending locations into sizes (subtract start) */ - inner.io_end -= inner.io_start; - inner.mem_end -= inner.mem_start; - - /* Align the sizes up by bridge rules */ - inner.io_end = ROUND_UP(inner.io_end, 4*1024) - 1; - inner.mem_end = ROUND_UP(inner.mem_end, 1*1024*1024) - 1; - - /* Adjust the bridge's allocation requirements */ - bridge->resource[0].end = bridge->resource[0].start + inner.io_end; - bridge->resource[1].end = bridge->resource[1].start + inner.mem_end; - - bridge->resource[PCI_BRIDGE_RESOURCES].end = - bridge->resource[PCI_BRIDGE_RESOURCES].start + inner.io_end; - bridge->resource[PCI_BRIDGE_RESOURCES+1].end = - bridge->resource[PCI_BRIDGE_RESOURCES+1].start + inner.mem_end; - - /* adjust parent's resource requirements */ - if (outer) { - outer->io_end = ROUND_UP(outer->io_end, 4*1024); - outer->io_end += inner.io_end; - - outer->mem_end = ROUND_UP(outer->mem_end, 1*1024*1024); - outer->mem_end += inner.mem_end; - } -} - -#undef ROUND_UP - -static void __init -pcibios_size_bridges(void) -{ - struct list_head *ln1, *ln2; - - for(ln1=pci_root_buses.next; ln1 != &pci_root_buses; ln1=ln1->next) - for(ln2 = pci_bus_b(ln1)->children.next; - ln2 != &pci_bus_b(ln1)->children; - ln2 = ln2->next) - pcibios_size_bridge(pci_bus_b(ln2), NULL); -} - void __init common_init_pci(void) { @@ -495,10 +399,8 @@ common_init_pci(void) next_busno += 1; } - pcibios_size_bridges(); pci_assign_unassigned_resources(); pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq); - pci_set_bus_ranges(); } diff -urp 2.4.0t10/arch/arm/kernel/bios32.c linux/arch/arm/kernel/bios32.c --- 2.4.0t10/arch/arm/kernel/bios32.c Wed Oct 4 02:42:19 2000 +++ linux/arch/arm/kernel/bios32.c Mon Nov 6 14:20:53 2000 @@ -451,7 +451,6 @@ void __init pcibios_init(void) */ pci_assign_unassigned_resources(); pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq); - pci_set_bus_ranges(); } char * __init pcibios_setup(char *str) diff -urp 2.4.0t10/arch/mips/ddb5074/pci.c linux/arch/mips/ddb5074/pci.c --- 2.4.0t10/arch/mips/ddb5074/pci.c Tue Jul 11 16:41:48 2000 +++ linux/arch/mips/ddb5074/pci.c Mon Nov 6 14:21:03 2000 @@ -286,7 +286,6 @@ void __init pcibios_init(void) pci_scan_bus(0, &nile4_pci_ops, NULL); ddb5074_pci_fixup(); pci_assign_unassigned_resources(); - pci_set_bus_ranges(); pcibios_fixup_irqs(); } diff -urp 2.4.0t10/drivers/pci/setup-bus.c linux/drivers/pci/setup-bus.c --- 2.4.0t10/drivers/pci/setup-bus.c Wed Jan 12 01:22:31 2000 +++ linux/drivers/pci/setup-bus.c Mon Nov 6 15:48:57 2000 @@ -9,148 +9,201 @@ * Support routines for initializing a PCI subsystem. */ +/* + * Nov 2000, Ivan Kokshaysky + * PCI-PCI bridges cleanup, sorted resource allocation + */ + #include #include #include #include #include #include +#include -#define DEBUG_CONFIG 0 +#define DEBUG_CONFIG 1 #if DEBUG_CONFIG # define DBGC(args) printk args #else # define DBGC(args) #endif - #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) -#define ROUND_DOWN(x, a) ((x) & ~((a) - 1)) +static int __init +pbus_assign_resources_sorted(struct pci_bus *bus, + struct pbus_set_ranges_data *ranges) +{ + struct list_head *ln; + struct resource *res; + struct resource_list head_io, head_mem, *list, *tmp; + unsigned long io_reserved = 0, mem_reserved = 0; + int idx, found_vga = 0; + + head_io.next = head_mem.next = NULL; + for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) { + struct pci_dev *dev = pci_dev_b(ln); + + /* Skip PCI-PCI bridges */ + if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI) + continue; + + /* ??? Reserve some resources for CardBus */ + if (dev->class >> 8 == PCI_CLASS_BRIDGE_CARDBUS) { + io_reserved += 8*1024; + mem_reserved += 32*1024*1024; + continue; + } + pdev_sort_resources(dev, &head_io, IORESOURCE_IO); + pdev_sort_resources(dev, &head_mem, IORESOURCE_MEM); + } + for (list = head_io.next; list;) { + res = list->res; + idx = res - &list->dev->resource[0]; + if (pci_assign_resource(list->dev, idx) == 0) + ranges->io_end = res->end; + tmp = list; + list = list->next; + vfree(tmp); + } + for (list = head_mem.next; list;) { + res = list->res; + idx = res - &list->dev->resource[0]; + if (pci_assign_resource(list->dev, idx) == 0) + ranges->mem_end = res->end; + tmp = list; + list = list->next; + vfree(tmp); + } + ranges->io_end += io_reserved; + ranges->mem_end += mem_reserved; + ranges->io_end = ROUND_UP(ranges->io_end, 4*1024); + ranges->mem_end = ROUND_UP(ranges->mem_end, 1024*1024); + return found_vga; +} + +/* Initialize bridges with base/limit values we have collected */ static void __init -pbus_set_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *outer) +pci_setup_bridge(struct pci_bus *bus) +{ + struct pbus_set_ranges_data ranges; + struct pci_dev *bridge = bus->self; + u32 l; + + if (!bridge || (bridge->class >> 8) != PCI_CLASS_BRIDGE_PCI) + return; + ranges.io_start = bus->resource[0]->start; + ranges.io_end = bus->resource[0]->end; + ranges.mem_start = bus->resource[1]->start; + ranges.mem_end = bus->resource[1]->end; + pcibios_fixup_pbus_ranges(bus, &ranges); + + DBGC(("PCI: Bus %d, bridge: %s\n", bus->number, bridge->name)); + DBGC((" IO window: %04lx-%04lx\n", ranges.io_start, ranges.io_end)); + DBGC((" MEM window: %08lx-%08lx\n", ranges.mem_start, ranges.mem_end)); + + /* Set the cache line correctly. */ + pci_write_config_byte(bridge, PCI_CACHE_LINE_SIZE, + (L1_CACHE_BYTES / sizeof(u32))); + + /* Set up the top and bottom of the PCI I/O segment for this bus. */ + pci_read_config_dword(bridge, PCI_IO_BASE, &l); + l &= 0xffff0000; + l |= (ranges.io_start >> 8) & 0x00f0; + l |= ranges.io_end & 0xf000; + pci_write_config_dword(bridge, PCI_IO_BASE, l); + +#if 0 + /* Set up upper 16 bits of I/O base/limit. */ + l = (ranges.io_start >> 16) & 0xffff; + l |= ranges.io_end & 0xffff0000; + pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l); +#else + pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0); +#endif + /* Clear out the upper 32 bits of PREF base/limit. */ + pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0); + pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); + + /* Set up the top and bottom of the PCI Memory segment + for this bus. */ + l = (ranges.mem_start >> 16) & 0xfff0; + l |= ranges.mem_end & 0xfff00000; + pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); + + /* Set up PREF base/limit. */ + l = (bus->resource[2]->start >> 16) & 0xfff0; + l |= bus->resource[2]->end & 0xfff00000; + pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); + + /* Check if we have VGA behind the bridge. + Enable ISA in either case. */ + l = (bus->resource[0]->flags & IORESOURCE_BUS_HAS_VGA) ? 0x0c : 0x04; + pci_write_config_byte(bridge, PCI_BRIDGE_CONTROL, l); + + /* + * Clear status bits, + * turn on I/O enable (for downstream I/O), + * turn on memory enable (for downstream memory), + * turn on master enable (for upstream memory and I/O). + */ + pci_write_config_dword(bridge, PCI_COMMAND, 0xffff0007); +} + +static void __init +pbus_assign_resources(struct pci_bus *bus, struct pbus_set_ranges_data *ranges) { - struct pbus_set_ranges_data inner; - struct pci_dev *dev; struct list_head *ln; + int found_vga = pbus_assign_resources_sorted(bus, ranges); - inner.found_vga = 0; - inner.mem_start = inner.io_start = ~0UL; - inner.mem_end = inner.io_end = 0; + if (!ranges->found_vga && found_vga) { + struct pci_bus *b; - /* Collect information about how our direct children are layed out. */ - for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) { - int i; - dev = pci_dev_b(ln); - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *res = &dev->resource[i]; - if (res->flags & IORESOURCE_IO) { - if (res->start < inner.io_start) - inner.io_start = res->start; - if (res->end > inner.io_end) - inner.io_end = res->end; - } else if (res->flags & IORESOURCE_MEM) { - if (res->start < inner.mem_start) - inner.mem_start = res->start; - if (res->end > inner.mem_end) - inner.mem_end = res->end; - } + ranges->found_vga = 1; + /* Propogate presence of the VGA to upstream bridges */ + for (b = bus; b->parent; b = b->parent) { +#if 0 + /* ? Do we actually need to enable PF memory? */ + b->resource[2]->start = 0; +#endif + b->resource[0]->flags |= IORESOURCE_BUS_HAS_VGA; } - if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) - inner.found_vga = 1; } + for (ln=bus->children.next; ln != &bus->children; ln=ln->next) { + struct pci_bus *b = pci_bus_b(ln); - /* And for all of the sub-busses. */ - for (ln=bus->children.next; ln != &bus->children; ln=ln->next) - pbus_set_ranges(pci_bus_b(ln), &inner); - - /* Align the values. */ - inner.io_start = ROUND_DOWN(inner.io_start, 4*1024); - inner.io_end = ROUND_UP(inner.io_end, 4*1024); - - inner.mem_start = ROUND_DOWN(inner.mem_start, 1*1024*1024); - inner.mem_end = ROUND_UP(inner.mem_end, 1*1024*1024); - - pcibios_fixup_pbus_ranges(bus, &inner); - - /* Configure the bridge, if possible. */ - if (bus->self) { - struct pci_dev *bridge = bus->self; - u32 l; - - /* Set up the top and bottom of the PCI I/O segment - for this bus. */ - pci_read_config_dword(bridge, PCI_IO_BASE, &l); - l &= 0xffff0000; - l |= (inner.io_start >> 8) & 0x00f0; - l |= (inner.io_end - 1) & 0xf000; - pci_write_config_dword(bridge, PCI_IO_BASE, l); - - /* - * Clear out the upper 16 bits of IO base/limit. - * Clear out the upper 32 bits of PREF base/limit. - */ - pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0); - pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0); - pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); - - /* Set up the top and bottom of the PCI Memory segment - for this bus. */ - l = (inner.mem_start & 0xfff00000) >> 16; - l |= (inner.mem_end - 1) & 0xfff00000; - pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); - - /* - * Turn off downstream PF memory address range, unless - * there is a VGA behind this bridge, in which case, we - * enable the PREFETCH range to include BIOS ROM at C0000. - * - * NOTE: this is a bit of a hack, done with PREFETCH for - * simplicity, rather than having to add it into the above - * non-PREFETCH range, which could then be bigger than we want. - * We might assume that we could relocate the BIOS ROM, but - * that would depend on having it found by those who need it - * (the DEC BIOS emulator would find it, but I do not know - * about the Xservers). So, we do it this way for now... ;-) - */ - l = (inner.found_vga) ? 0 : 0x0000ffff; - pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); - - /* - * Tell bridge that there is an ISA bus in the system, - * and (possibly) a VGA as well. - */ - l = (inner.found_vga) ? 0x0c : 0x04; - pci_write_config_byte(bridge, PCI_BRIDGE_CONTROL, l); - - /* - * Clear status bits, - * turn on I/O enable (for downstream I/O), - * turn on memory enable (for downstream memory), - * turn on master enable (for upstream memory and I/O). - */ - pci_write_config_dword(bridge, PCI_COMMAND, 0xffff0007); - } - - if (outer) { - outer->found_vga |= inner.found_vga; - if (inner.io_start < outer->io_start) - outer->io_start = inner.io_start; - if (inner.io_end > outer->io_end) - outer->io_end = inner.io_end; - if (inner.mem_start < outer->mem_start) - outer->mem_start = inner.mem_start; - if (inner.mem_end > outer->mem_end) - outer->mem_end = inner.mem_end; + b->resource[0]->start = ranges->io_start = ranges->io_end; + b->resource[1]->start = ranges->mem_start = ranges->mem_end; + + pbus_assign_resources(b, ranges); + + b->resource[0]->end = ranges->io_end - 1; + b->resource[1]->end = ranges->mem_end - 1; + + pci_setup_bridge(b); } } -void __init -pci_set_bus_ranges(void) +void __init +pci_assign_unassigned_resources(void) { + struct pbus_set_ranges_data ranges; struct list_head *ln; + struct pci_dev *dev; - for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next) - pbus_set_ranges(pci_bus_b(ln), NULL); + for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next) { + struct pci_bus *b = pci_bus_b(ln); + + ranges.io_start = b->resource[0]->start; + ranges.mem_start = b->resource[1]->start; + ranges.io_end = ranges.io_start; + ranges.mem_end = ranges.mem_start; + ranges.found_vga = 0; + pbus_assign_resources(b, &ranges); + } + pci_for_each_dev(dev) { + pdev_enable_device(dev); + } } diff -urp 2.4.0t10/drivers/pci/setup-res.c linux/drivers/pci/setup-res.c --- 2.4.0t10/drivers/pci/setup-res.c Thu Aug 24 19:03:54 2000 +++ linux/drivers/pci/setup-res.c Mon Nov 6 14:38:02 2000 @@ -11,12 +11,18 @@ /* fixed for multiple pci buses, 1999 Andrea Arcangeli */ +/* + * Nov 2000, Ivan Kokshaysky + * Resource sorting + */ + #include #include #include #include #include #include +#include #define DEBUG_CONFIG 0 @@ -119,14 +125,46 @@ pci_assign_resource(struct pci_dev *dev, return 0; } -void -pdev_assign_unassigned_resources(struct pci_dev *dev) +/* Sort resources of a given type by alignment */ +void __init +pdev_sort_resources(struct pci_dev *dev, + struct resource_list *head, u32 type_mask) +{ + int i; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + struct resource *r; + struct resource_list *list, *tmp; + + r = &dev->resource[i]; + if (!(r->flags & type_mask) || r->parent) + continue; + for (list = head; ; list = list->next) { + unsigned long size = 0; + struct resource_list *ln = list->next; + + if (ln) + size = ln->res->end - ln->res->start; + if (r->end - r->start > size) { + tmp = vmalloc(sizeof(*tmp)); + tmp->next = ln; + tmp->res = r; + tmp->dev = dev; + list->next = tmp; + break; + } + } + } +} + +void __init +pdev_enable_device(struct pci_dev *dev) { u32 reg; u16 cmd; int i; - DBGC(("PCI assign unassigned: (%s)\n", dev->name)); + DBGC(("PCI enable device: (%s)\n", dev->name)); pci_read_config_word(dev, PCI_COMMAND, &cmd); @@ -137,13 +175,6 @@ pdev_assign_unassigned_resources(struct cmd |= PCI_COMMAND_IO; else if (res->flags & IORESOURCE_MEM) cmd |= PCI_COMMAND_MEMORY; - - /* If it is already assigned or the resource does - not exist, there is nothing to do. */ - if (res->parent != NULL || res->flags == 0) - continue; - - pci_assign_resource(dev, i); } /* Special case, disable the ROM. Several devices act funny @@ -175,20 +206,4 @@ pdev_assign_unassigned_resources(struct pci_write_config_word(dev, PCI_COMMAND, cmd); DBGC((" cmd reg 0x%x\n", cmd)); - - /* If this is a PCI bridge, set the cache line correctly. */ - if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, - (L1_CACHE_BYTES / sizeof(u32))); - } -} - -void __init -pci_assign_unassigned_resources(void) -{ - struct pci_dev *dev; - - pci_for_each_dev(dev) { - pdev_assign_unassigned_resources(dev); - } } diff -urp 2.4.0t10/include/asm-alpha/param.h linux/include/asm-alpha/param.h --- 2.4.0t10/include/asm-alpha/param.h Tue Jul 13 13:29:35 1999 +++ linux/include/asm-alpha/param.h Sun Nov 5 18:31:47 2000 @@ -27,4 +27,8 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ +#ifdef __KERNEL__ +# define CLOCKS_PER_SEC HZ /* frequency at which times() counts */ +#endif + #endif /* _ASM_ALPHA_PARAM_H */ diff -urp 2.4.0t10/include/linux/ioport.h linux/include/linux/ioport.h --- 2.4.0t10/include/linux/ioport.h Wed Mar 1 02:28:46 2000 +++ linux/include/linux/ioport.h Sun Nov 5 19:40:20 2000 @@ -19,6 +19,12 @@ struct resource { struct resource *parent, *sibling, *child; }; +struct resource_list { + struct resource_list *next; + struct resource *res; + struct pci_dev *dev; +}; + /* * IO resources have these defined flags. */ @@ -34,6 +40,7 @@ struct resource { #define IORESOURCE_CACHEABLE 0x00004000 #define IORESOURCE_RANGELENGTH 0x00008000 #define IORESOURCE_SHADOWABLE 0x00010000 +#define IORESOURCE_BUS_HAS_VGA 0x00080000 #define IORESOURCE_UNSET 0x20000000 #define IORESOURCE_AUTO 0x40000000 diff -urp 2.4.0t10/include/linux/pci.h linux/include/linux/pci.h --- 2.4.0t10/include/linux/pci.h Wed Oct 4 02:42:56 2000 +++ linux/include/linux/pci.h Mon Nov 6 15:32:47 2000 @@ -530,12 +530,12 @@ void pci_set_master(struct pci_dev *dev) int pci_set_power_state(struct pci_dev *dev, int state); int pci_assign_resource(struct pci_dev *dev, int i); -/* Helper functions for low-level code (drivers/pci/setup.c) */ +/* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ int pci_claim_resource(struct pci_dev *, int); void pci_assign_unassigned_resources(void); -void pdev_assign_unassigned_resources(struct pci_dev *dev); -void pci_set_bus_ranges(void); +void pdev_enable_device(struct pci_dev *); +void pdev_sort_resources(struct pci_dev *, struct resource_list *, u32); void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *), int (*)(struct pci_dev *, u8, u8));