diff -ur linux-2.2.19/arch/alpha/kernel/bios32.c linux-2.2.19.dp264/arch/alpha/kernel/bios32.c --- linux-2.2.19/arch/alpha/kernel/bios32.c Sun Mar 25 20:31:46 2001 +++ linux-2.2.19.dp264/arch/alpha/kernel/bios32.c Wed Jun 6 15:35:09 2001 @@ -125,6 +125,9 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) { + if (alpha_mv.pci_fixup_bus) { + alpha_mv.pci_fixup_bus(bus); + } } int diff -ur linux-2.2.19/arch/alpha/kernel/sys_dp264.c linux-2.2.19.dp264/arch/alpha/kernel/sys_dp264.c --- linux-2.2.19/arch/alpha/kernel/sys_dp264.c Sun Mar 25 20:31:46 2001 +++ linux-2.2.19.dp264/arch/alpha/kernel/sys_dp264.c Wed Jun 6 15:35:27 2001 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -388,6 +389,60 @@ } static void __init +dp264_pci_fixup_bus(struct pci_bus *bus) +{ + struct pci_dev *dev, *next; + + unsigned int mask = 0; + for (dev = bus->devices; dev; dev = dev->sibling) { + mask |= 1 << (dev->devfn >> 3); + } + + /* analyze the mask */ + if (mask == 0xffffffff) { /* Oops!!! */ + /* disable everything with except of IdSel 7 */ + /* which is known to be a problematic slot */ + /* with a 64 bit cards such as 3COM 3c985 */ + /* !!! NEVER use bus 0 idsel 7 with such cards!!! */ + printk("dp264_pci_fixup_bus: WARNING: Phantom device occupies entire bus %d - only IdSel 7 enabled.\n", bus->number); + mask &= 0xffffff7f; + } else { + /* disable everyting with except of valid */ + /* IdSels 5 - 10 - some 64bit cards */ + /* detects twice - once with valid IdSel */ + /* and secondly with invalid IdSel */ + mask &= 0xfffff81f; + } + + for (dev = bus->devices; dev; dev = next) { + next = dev->sibling; + if (mask & (1 << (dev->devfn >> 3))) { + unsigned short cmd; + struct pci_dev *fixup; + + printk("dp264_pci_fixup_bus: Disabling \"phantom\" device at %02x:%02x.%02x [%04x/%04x]\n", + dev->bus->number, dev->devfn >> 3, dev->devfn & 7, dev->vendor, dev->device); + + /* disable this device to avoid problems */ + pcibios_read_config_word(dev->bus->number, + dev->devfn, PCI_COMMAND, &cmd); + cmd &= (~PCI_COMMAND_IO & ~PCI_COMMAND_MEMORY & ~PCI_COMMAND_MASTER); + pcibios_write_config_word(dev->bus->number, + dev->devfn, PCI_COMMAND, cmd); + + /* delete from the list of devices */ + /* fixup devices */ + for (fixup = pci_devices; fixup; fixup = fixup->next) { + if (fixup->next == dev) fixup->next = dev->next; + if (fixup->sibling == dev) fixup->sibling = dev->sibling; + } + /* free memory */ + kfree(dev); + } + } +} + +static void __init monet_pci_fixup(void) { layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE); @@ -438,6 +493,7 @@ init_irq: dp264_init_irq, init_pit: generic_init_pit, pci_fixup: dp264_pci_fixup, + pci_fixup_bus: dp264_pci_fixup_bus, kill_arch: generic_kill_arch, }; ALIAS_MV(dp264) diff -ur linux-2.2.19/include/asm-alpha/machvec.h linux-2.2.19.dp264/include/asm-alpha/machvec.h --- linux-2.2.19/include/asm-alpha/machvec.h Sun Mar 25 20:31:06 2001 +++ linux-2.2.19.dp264/include/asm-alpha/machvec.h Wed Jun 6 15:34:11 2001 @@ -88,6 +88,7 @@ void (*init_irq)(void); void (*init_pit)(void); void (*pci_fixup)(void); + void (*pci_fixup_bus)(void *); void (*kill_arch)(int, char *); const char *vector_name;