diff -u --recursive --new-file v2.3.99-pre4/linux/Makefile linux/Makefile
--- v2.3.99-pre4/linux/Makefile	Tue Apr 11 15:09:11 2000
+++ linux/Makefile	Tue Apr 11 17:25:19 2000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 3
 SUBLEVEL = 99
-EXTRAVERSION = -pre4
+EXTRAVERSION = -pre5
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -u --recursive --new-file v2.3.99-pre4/linux/arch/i386/kernel/Makefile linux/arch/i386/kernel/Makefile
--- v2.3.99-pre4/linux/arch/i386/kernel/Makefile	Tue Apr 11 15:09:12 2000
+++ linux/arch/i386/kernel/Makefile	Tue Apr 11 16:10:32 2000
@@ -24,7 +24,7 @@
 ifdef CONFIG_VISWS
 O_OBJS += pci-visws.o
 else
-O_OBJS += pci-pc.o
+O_OBJS += pci-pc.o pci-irq.o
 endif
 endif
 
diff -u --recursive --new-file v2.3.99-pre4/linux/arch/i386/kernel/pci-i386.h linux/arch/i386/kernel/pci-i386.h
--- v2.3.99-pre4/linux/arch/i386/kernel/pci-i386.h	Fri Oct 22 13:21:45 1999
+++ linux/arch/i386/kernel/pci-i386.h	Tue Apr 11 16:10:32 2000
@@ -18,7 +18,6 @@
 #define PCI_NO_SORT 0x100
 #define PCI_BIOS_SORT 0x200
 #define PCI_NO_CHECKS 0x400
-#define PCI_PEER_FIXUP 0x800
 #define PCI_ASSIGN_ROMS 0x1000
 #define PCI_BIOS_IRQ_SCAN 0x2000
 
@@ -28,3 +27,42 @@
 
 void pcibios_resource_survey(void);
 int pcibios_enable_resources(struct pci_dev *);
+
+/* pci-pc.c */
+
+extern int pcibios_last_bus;
+extern struct pci_bus *pci_root_bus;
+extern struct pci_ops *pci_root_ops;
+
+struct irq_routing_table *pcibios_get_irq_routing_table(void);
+int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
+
+/* pci-irq.c */
+
+struct irq_info {
+	u8 bus, devfn;			/* Bus, device and function */
+	struct {
+		u8 link;		/* IRQ line ID, chipset dependent, 0=not routed */
+		u16 bitmap;		/* Available IRQs */
+	} __attribute__((packed)) irq[4];
+	u8 slot;			/* Slot number, 0=onboard */
+	u8 rfu;
+} __attribute__((packed));
+
+struct irq_routing_table {
+	u32 signature;			/* PIRQ_SIGNATURE should be here */
+	u16 version;			/* PIRQ_VERSION */
+	u16 size;			/* Table size in bytes */
+	u8 rtr_bus, rtr_devfn;		/* Where the interrupt router lies */
+	u16 exclusive_irqs;		/* IRQs devoted exclusively to PCI usage */
+	u16 rtr_vendor, rtr_device;	/* Vendor and device ID of interrupt router */
+	u32 miniport_data;		/* Crap */
+	u8 rfu[11];
+	u8 checksum;			/* Modulo 256 checksum must give zero */
+	struct irq_info slots[0];
+} __attribute__((packed));
+
+extern unsigned int pcibios_irq_mask;
+
+void pcibios_fixup_irqs(void);
+int pcibios_lookup_irq(struct pci_dev *dev, int assign);
diff -u --recursive --new-file v2.3.99-pre4/linux/arch/i386/kernel/pci-irq.c linux/arch/i386/kernel/pci-irq.c
--- v2.3.99-pre4/linux/arch/i386/kernel/pci-irq.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/i386/kernel/pci-irq.c	Tue Apr 11 16:10:32 2000
@@ -0,0 +1,431 @@
+/*
+ *	Low-Level PCI Support for PC -- Routing of Interrupts
+ *
+ *	(c) 1999--2000 Martin Mares <mj@suse.cz>
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/malloc.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+
+#include "pci-i386.h"
+
+extern int skip_ioapic_setup;
+
+#define PIRQ_SIGNATURE	(('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
+#define PIRQ_VERSION 0x0100
+
+static struct irq_routing_table *pirq_table;
+
+/*
+ * Never use: 0, 1, 2 (timer, keyboard, and cascade)
+ * Avoid using: 13, 14 and 15 (FP error and IDE).
+ * Penalize: 3, 4, 7, 12 (known ISA uses: serial, parallel and mouse)
+ */
+unsigned int pcibios_irq_mask = ~0;
+
+static unsigned pirq_penalty[16] = {
+	10000, 10000, 10000, 100, 100, 0, 0, 100,
+	0, 0, 0, 0, 100, 1000, 1000, 1000
+};
+
+struct irq_router {
+	char *name;
+	u16 vendor, device;
+	int (*get)(struct pci_dev *router, struct pci_dev *dev, int pirq);
+	int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq, int new);
+};
+
+/*
+ *  Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
+ */
+
+static struct irq_routing_table * __init pirq_find_routing_table(void)
+{
+	u8 *addr;
+	struct irq_routing_table *rt;
+	int i;
+	u8 sum;
+
+	for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
+		rt = (struct irq_routing_table *) addr;
+		if (rt->signature != PIRQ_SIGNATURE ||
+		    rt->version != PIRQ_VERSION ||
+		    rt->size % 16 ||
+		    rt->size < sizeof(struct irq_routing_table))
+			continue;
+		sum = 0;
+		for(i=0; i<rt->size; i++)
+			sum += addr[i];
+		if (!sum) {
+			DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+			return rt;
+		}
+	}
+	return NULL;
+}
+
+/*
+ *  If we have a IRQ routing table, use it to search for peer host
+ *  bridges.  It's a gross hack, but since there are no other known
+ *  ways how to get a list of buses, we have to go this way.
+ */
+
+static void __init pirq_peer_trick(void)
+{
+	struct irq_routing_table *rt = pirq_table;
+	u8 busmap[256];
+	int i;
+	struct irq_info *e;
+
+	memset(busmap, 0, sizeof(busmap));
+	for(i=0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) {
+		e = &rt->slots[i];
+#ifdef DEBUG
+		{
+			int j;
+			DBG("%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot);
+			for(j=0; j<4; j++)
+				DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap);
+			DBG("\n");
+		}
+#endif
+		busmap[e->bus] = 1;
+	}
+	for(i=1; i<256; i++)
+		/*
+		 *  It might be a secondary bus, but in this case its parent is already
+		 *  known (ascending bus order) and therefore pci_scan_bus returns immediately.
+		 */
+		if (busmap[i] && pci_scan_bus(i, pci_root_bus->ops, NULL))
+			printk("PCI: Discovered primary peer bus %02x [IRQ]\n", i);
+	pcibios_last_bus = -1;
+}
+
+/*
+ *  Code for querying and setting of IRQ routes on various interrupt routers.
+ */
+
+static void eisa_set_level_irq(unsigned int irq)
+{
+	unsigned char mask = 1 << (irq & 7);
+	unsigned int port = 0x4d0 + (irq >> 3);
+	unsigned char val = inb(port);
+
+	if (!(val & mask)) {
+		DBG(" -> edge");
+		outb(val | mask, port);
+	}
+}
+
+static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	static unsigned char irqmap[16] = {
+		0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15
+	};
+	unsigned int val = irqmap[irq];
+	pirq--;
+	if (val && pirq < 8) {
+		u8 x;
+		unsigned reg = 0x48 + (pirq >> 1);
+		pci_read_config_byte(router, reg, &x);
+		x = (pirq & 1) ? ((x & 0x0f) | (val << 4)) : ((x & 0xf0) | val);
+		pci_write_config_byte(router, reg, x);
+		eisa_set_level_irq(irq);
+		return 1;
+	}
+	return 0;
+}
+
+static int pirq_piix_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+	u8 x;
+	pci_read_config_byte(router, pirq, &x);
+	return (x < 16) ? x : 0;
+}
+
+static int pirq_piix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	pci_write_config_byte(router, pirq, irq);
+	return 1;
+}
+
+static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+	u8 x;
+	int reg = 0x55 + (pirq >> 1);
+	pci_read_config_byte(router, reg, &x);
+	return (pirq & 1) ? (x >> 4) : (x & 0x0f);
+}
+
+static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	u8 x;
+	int reg = 0x55 + (pirq >> 1);
+	pci_read_config_byte(router, reg, &x);
+	x = (pirq & 1) ? ((x & 0x0f) | (irq << 4)) : ((x & 0xf0) | irq);
+	pci_write_config_byte(router, reg, x);
+	return 1;
+}
+
+static int pirq_opti_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+	u8 x;
+	int reg = 0xb8 + (pirq >> 5);
+	pci_read_config_byte(router, reg, &x);
+	return (pirq & 0x10) ? (x >> 4) : (x & 0x0f);
+}
+
+static int pirq_opti_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	u8 x;
+	int reg = 0xb8 + (pirq >> 5);
+	pci_read_config_byte(router, reg, &x);
+	x = (pirq & 0x10) ? ((x & 0x0f) | (irq << 4)) : ((x & 0xf0) | irq);
+	pci_write_config_byte(router, reg, x);
+	return 1;
+}
+
+#ifdef CONFIG_PCI_BIOS
+
+static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	struct pci_dev *bridge;
+	int pin = pci_get_interrupt_pin(dev, &bridge);
+	return pcibios_set_irq_routing(bridge, pin, irq);
+}
+
+static struct irq_router pirq_bios_router =
+	{ "BIOS", 0, 0, NULL, pirq_bios_set };
+
+#endif
+
+static struct irq_router pirq_routers[] = {
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, pirq_piix_get, pirq_piix_set },
+	{ "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL, pirq_ali_set },
+	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, pirq_via_get, pirq_via_set },
+	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, pirq_via_get, pirq_via_set },
+	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, pirq_via_get, pirq_via_set },
+	{ "OPTI", PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C700, pirq_opti_get, pirq_opti_set },
+	{ "default", 0, 0, NULL, NULL }
+};
+
+static struct irq_router *pirq_router;
+static struct pci_dev *pirq_router_dev;
+
+static void __init pirq_find_router(void)
+{
+	struct irq_routing_table *rt = pirq_table;
+	u16 rvendor, rdevice;
+	struct irq_router *r;
+
+#ifdef CONFIG_PCI_BIOS
+	if (!rt->signature) {
+		printk("PCI: Using BIOS for IRQ routing\n");
+		pirq_router = &pirq_bios_router;
+		return;
+	}
+#endif
+	if (!(pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn))) {
+		DBG("PCI: Interrupt router not found\n");
+		return;
+	}
+	if (rt->rtr_vendor) {
+		rvendor = rt->rtr_vendor;
+		rdevice = rt->rtr_device;
+	} else {
+		/*
+		 * Several BIOSes forget to set the router type. In such cases, we
+		 * use chip vendor/device. This doesn't guarantee us semantics of
+		 * PIRQ values, but was found to work in practice and it's still
+		 * better than not trying.
+		 */
+		DBG("PCI: Guessed interrupt router ID from %s\n", pirq_router_dev->slot_name);
+		rvendor = pirq_router_dev->vendor;
+		rdevice = pirq_router_dev->device;
+	}
+	for(r=pirq_routers; r->vendor; r++)
+		if (r->vendor == rvendor && r->device == rdevice)
+			break;
+	pirq_router = r;
+	printk("PCI: Using IRQ router %s [%04x/%04x] at %s\n", r->name,
+	       rvendor, rdevice, pirq_router_dev->slot_name);
+}
+
+static struct irq_info *pirq_get_info(struct pci_dev *dev, int pin)
+{
+	struct irq_routing_table *rt = pirq_table;
+	int entries = (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
+	struct irq_info *info;
+
+	for (info = rt->slots; entries--; info++)
+		if (info->bus == dev->bus->number && PCI_SLOT(info->devfn) == PCI_SLOT(dev->devfn))
+			return info;
+	return NULL;
+}
+
+int pcibios_lookup_irq(struct pci_dev *dev, int assign)
+{
+	struct irq_info *info;
+	int i, pirq, pin, newirq;
+	int irq = 0;
+	u32 mask;
+	struct irq_router *r = pirq_router;
+	struct pci_dev *dev2, *d;
+	char *msg = NULL;
+
+	if (!pirq_table)
+		return 0;
+
+	/* Find IRQ routing entry */
+	pin = pci_get_interrupt_pin(dev, &d);
+	if (pin < 0) {
+		DBG(" -> no interrupt pin\n");
+		return 0;
+	}
+	DBG("IRQ for %s(%d) via %s", dev->slot_name, pin, d->slot_name);
+	info = pirq_get_info(d, pin);
+	if (!info) {
+		DBG(" -> not found in routing table\n");
+		return 0;
+	}
+	pirq = info->irq[pin].link;
+	mask = info->irq[pin].bitmap;
+	if (!pirq) {
+		DBG(" -> not routed\n");
+		return 0;
+	}
+	DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs);
+	if (pcibios_irq_mask != ~0)
+		mask &= pcibios_irq_mask;
+	else
+		mask &= pirq_table->exclusive_irqs;
+
+	/* Find the best IRQ to assign */
+	newirq = 0;
+	for (i = 0; i < 16; i++) {
+		if (!(mask & (1 << i)))
+			continue;
+		if (pirq_penalty[i] < pirq_penalty[newirq])
+			newirq = i;
+	}
+	DBG(" -> newirq=%d", newirq);
+
+	/* Try to get current IRQ */
+	if (r->get && (irq = r->get(pirq_router_dev, d, pirq))) {
+		DBG(" -> got IRQ %d\n", irq);
+		msg = "Found";
+	} else if (assign && newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
+		DBG(" -> assigning IRQ %d", newirq);
+		if (r->set(pirq_router_dev, d, pirq, newirq)) {
+			DBG(" ... OK\n");
+			msg = "Assigned";
+			irq = newirq;
+		}
+	}
+
+	if (!irq) {
+		DBG(" ... failed\n");
+		if (newirq && mask == (1 << newirq)) {
+			msg = "Guessed";
+			irq = newirq;
+		} else
+			return 0;
+	}
+	printk("PCI: %s IRQ %d for device %s\n", msg, irq, dev->slot_name);
+
+	/* Update IRQ for all devices with the same pirq value */
+	pci_for_each_dev(dev2) {
+		if ((pin = pci_get_interrupt_pin(dev2, &d)) >= 0 &&
+		    (info = pirq_get_info(d, pin)) &&
+		    info->irq[pin].link == pirq) {
+			dev2->irq = irq;
+			pirq_penalty[irq]++;
+			if (dev != dev2)
+				printk("PCI: The same IRQ used for device %s\n", dev2->slot_name);
+		}
+	}
+	return 1;
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+	struct pci_dev *dev;
+	u8 pin;
+
+	DBG("PCI: IRQ fixup\n");
+	pirq_table = pirq_find_routing_table();
+#ifdef CONFIG_PCI_BIOS
+	if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN))
+		pirq_table = pcibios_get_irq_routing_table();
+#endif
+	if (pirq_table) {
+		pirq_peer_trick();
+		pirq_find_router();
+	}
+
+	pci_for_each_dev(dev) {
+		/*
+		 * If the BIOS has set an out of range IRQ number, just ignore it.
+		 * Also keep track of which IRQ's are already in use.
+		 */
+		if (dev->irq >= 16) {
+			DBG("%s: ignoring bogus IRQ %d\n", dev->slot_name, dev->irq);
+			dev->irq = 0;
+		}
+		pirq_penalty[dev->irq]++;
+	}
+
+	pci_for_each_dev(dev) {
+		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+#if defined(CONFIG_X86_IO_APIC)
+		/*
+		 * Recalculate IRQ numbers if we use the I/O APIC.
+		 */
+		if (!skip_ioapic_setup)
+		{
+			int irq;
+
+			if (pin) {
+				pin--;		/* interrupt pins are numbered starting from 1 */
+				irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
+/*
+ * Will be removed completely if things work out well with fuzzy parsing
+ */
+#if 0
+				if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
+					struct pci_dev * bridge = dev->bus->self;
+
+					pin = (pin + PCI_SLOT(dev->devfn)) % 4;
+					irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 
+							PCI_SLOT(bridge->devfn), pin);
+					if (irq >= 0)
+						printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", 
+							bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
+				}
+#endif
+				if (irq >= 0) {
+					printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
+						dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
+					dev->irq = irq;
+				}
+			}
+			pirq_table = NULL;	/* Avoid automatic IRQ assignment */
+		}
+#endif
+		/*
+		 * Still no IRQ? Try to lookup one...
+		 */
+		if (pin && !dev->irq)
+			pcibios_lookup_irq(dev, 0);
+	}
+}
diff -u --recursive --new-file v2.3.99-pre4/linux/arch/i386/kernel/pci-pc.c linux/arch/i386/kernel/pci-pc.c
--- v2.3.99-pre4/linux/arch/i386/kernel/pci-pc.c	Tue Apr 11 15:09:12 2000
+++ linux/arch/i386/kernel/pci-pc.c	Tue Apr 11 16:10:32 2000
@@ -10,9 +10,6 @@
 #include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/init.h>
-#include <linux/malloc.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
 
 #include <asm/segment.h>
 #include <asm/io.h>
@@ -22,35 +19,9 @@
 
 unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2;
 
-static struct pci_bus *pci_root_bus;
-static struct pci_ops *pci_root_ops;
-
-/*
- * IRQ routing table provided by the BIOS
- */
-
-struct irq_info {
-	u8 bus, devfn;			/* Bus, device and function */
-	struct {
-		u8 link;		/* IRQ line ID, chipset dependent, 0=not routed */
-		u16 bitmap;		/* Available IRQs */
-	} __attribute__((packed)) irq[4];
-	u8 slot;			/* Slot number, 0=onboard */
-	u8 rfu;
-} __attribute__((packed));
-
-struct irq_routing_table {
-	u32 signature;			/* PIRQ_SIGNATURE should be here */
-	u16 version;			/* PIRQ_VERSION */
-	u16 size;			/* Table size in bytes */
-	u8 rtr_bus, rtr_devfn;		/* Where the interrupt router lies */
-	u16 exclusive_irqs;		/* IRQs devoted exclusively to PCI usage */
-	u16 rtr_vendor, rtr_device;	/* Vendor and device ID of interrupt router */
-	u32 miniport_data;		/* Crap */
-	u8 rfu[11];
-	u8 checksum;			/* Modulo 256 checksum must give zero */
-	struct irq_info slots[0];
-} __attribute__((packed));
+int pcibios_last_bus = -1;
+struct pci_bus *pci_root_bus;
+struct pci_ops *pci_root_ops;
 
 /*
  * Direct access to PCI hardware...
@@ -378,7 +349,7 @@
 static int __init check_pcibios(void)
 {
 	u32 signature, eax, ebx, ecx;
-	u8 status, major_ver, minor_ver, hw_mech, last_bus;
+	u8 status, major_ver, minor_ver, hw_mech;
 	unsigned long flags, pcibios_entry;
 
 	if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
@@ -403,16 +374,17 @@
 		hw_mech = eax & 0xff;
 		major_ver = (ebx >> 8) & 0xff;
 		minor_ver = ebx & 0xff;
-		last_bus = ecx & 0xff;
+		if (pcibios_last_bus < 0)
+			pcibios_last_bus = ecx & 0xff;
 		DBG("PCI: BIOS probe returned s=%02x hw=%02x ver=%02x.%02x l=%02x\n",
-			status, hw_mech, major_ver, minor_ver, last_bus);
+			status, hw_mech, major_ver, minor_ver, pcibios_last_bus);
 		if (status || signature != PCI_SIGNATURE) {
 			printk (KERN_ERR "PCI: BIOS BUG #%x[%08x] found, report to <mj@suse.cz>\n",
 				status, signature);
 			return 0;
 		}
-		printk("PCI: PCI BIOS revision %x.%02x entry at 0x%lx\n",
-			major_ver, minor_ver, pcibios_entry);
+		printk("PCI: PCI BIOS revision %x.%02x entry at 0x%lx, last bus=%d\n",
+			major_ver, minor_ver, pcibios_entry, pcibios_last_bus);
 #ifdef CONFIG_PCI_DIRECT
 		if (!(hw_mech & PCIBIOS_HW_TYPE1))
 			pci_probe &= ~PCI_PROBE_CONF1;
@@ -670,7 +642,7 @@
 }
 
 /*
- *  Ask BIOS for IRQ Routing Table
+ *  BIOS Functions for IRQ Routing
  */
 
 struct irq_routing_options {
@@ -679,28 +651,20 @@
 	u16 segment;
 } __attribute__((packed));
 
-static unsigned long pcibios_irq_page __initdata = 0;
-
-static inline void __init pcibios_free_irq_routing_table(void)
-{
-	if (pcibios_irq_page)
-		free_page(pcibios_irq_page);
-}
-
-static struct irq_routing_table * __init pcibios_get_irq_routing_table(void)
+struct irq_routing_table * __init pcibios_get_irq_routing_table(void)
 {
 	struct irq_routing_options opt;
-	struct irq_routing_table *rt;
+	struct irq_routing_table *rt = NULL;
 	int ret, map;
+	unsigned long page;
 
-	if (!(pci_probe & PCI_BIOS_IRQ_SCAN))
+	if (!pci_bios_present)
+		return NULL;
+	page = __get_free_page(GFP_KERNEL);
+	if (!page)
 		return NULL;
-	pcibios_irq_page = __get_free_page(GFP_KERNEL);
-	if (!pcibios_irq_page)
-		return 0;
-	rt = (void *) pcibios_irq_page;
-	opt.table = rt->slots;
-	opt.size = PAGE_SIZE - sizeof(struct irq_routing_table);
+	opt.table = (struct irq_info *) page;
+	opt.size = PAGE_SIZE;
 	opt.segment = __KERNEL_DS;
 
 	DBG("PCI: Fetching IRQ routing table... ");
@@ -719,17 +683,39 @@
 		  "D" ((long) &opt),
 		  "S" (&pci_indirect));
 	DBG("OK  ret=%d, size=%d, map=%x\n", ret, opt.size, map);
-	if (ret & 0xff00) {
+	if (ret & 0xff00)
 		printk(KERN_ERR "PCI: Error %02x when fetching IRQ routing table.\n", (ret >> 8) & 0xff);
-		return 0;
+	else if (opt.size) {
+		rt = kmalloc(sizeof(struct irq_routing_table) + opt.size, GFP_KERNEL);
+		if (rt) {
+			memset(rt, 0, sizeof(struct irq_routing_table));
+			rt->size = opt.size + sizeof(struct irq_routing_table);
+			rt->exclusive_irqs = map;
+			memcpy(rt->slots, (void *) page, opt.size);
+			printk("PCI: Using BIOS Interrupt Routing Table\n");
+		}
 	}
-
-	memset(rt, 0, sizeof(struct irq_routing_table));
-	rt->size = opt.size + sizeof(struct irq_routing_table);
-	printk("PCI: Using BIOS Interrupt Routing Table\n");
+	free_page(page);
 	return rt;
 }
 
+
+int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
+{
+	int ret;
+
+	__asm__("lcall (%%esi); cld\n\t"
+		"jc 1f\n\t"
+		"xor %%ah, %%ah\n"
+		"1:"
+		: "=a" (ret)
+		: "0" (PCIBIOS_SET_PCI_HW_INT),
+		  "b" ((dev->bus->number << 8) | dev->devfn),
+		  "c" ((irq << 8) | (pin + 10)),
+		  "S" (&pci_indirect));
+	return !(ret & 0xff00);
+}
+
 #endif
 
 /*
@@ -786,75 +772,33 @@
 }
 
 /*
- * In case there are peer host bridges, scan bus behind each of them.
- * Although several sources claim that the host bridges should have
- * header type 1 and be assigned a bus number as for PCI2PCI bridges,
- * the reality doesn't pass this test and the bus number is usually
- * set by BIOS to the first free value.
+ * Discover remaining PCI buses in case there are peer host bridges.
+ * We use the number of last PCI bus provided by the PCI BIOS.
  */
 static void __init pcibios_fixup_peer_bridges(void)
 {
-	struct list_head *ln;
-	struct pci_bus *b = pci_root_bus;
-	int n, cnt=-1;
-	struct pci_ops *ops = pci_root_bus->ops;
+	int n;
+	struct pci_bus bus;
+	struct pci_dev dev;
+	u16 l;
 
-#ifdef CONFIG_PCI_DIRECT
-	/*
-	 * Don't search for peer host bridges if we use config type 2
-	 * since it reads bogus values for non-existent buses and
-	 * chipsets supporting multiple primary buses use conf1 anyway.
-	 */
-	if (ops == &pci_direct_conf2)
+	if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
 		return;
-#endif
-
 	DBG("PCI: Peer bridge fixup\n");
-
-	for(ln=b->devices.next; ln != &b->devices; ln=ln->next)
-		if ((pci_dev_b(ln)->class >> 8) == PCI_CLASS_BRIDGE_HOST)
-			cnt++;
-	n = b->subordinate + 1;
-	while (n <= 0xff) {
-		int found = 0;
-		u16 l;
-		struct pci_bus bus;
-		struct pci_dev dev;
+	for (n=0; n <= pcibios_last_bus; n++) {
+		if (pci_bus_exists(&pci_root_buses, n))
+			continue;
 		bus.number = n;
-		bus.ops = ops;
+		bus.ops = pci_root_ops;
 		dev.bus = &bus;
 		for(dev.devfn=0; dev.devfn<256; dev.devfn += 8)
 			if (!pci_read_config_word(&dev, PCI_VENDOR_ID, &l) &&
 			    l != 0x0000 && l != 0xffff) {
-#ifdef CONFIG_PCI_BIOS
-				if (pci_bios_present) {
-					int err, idx = 0;
-					u8 bios_bus, bios_dfn;
-					u16 d;
-					pci_read_config_word(&dev, PCI_DEVICE_ID, &d);
-					DBG("BIOS test for %02x:%02x (%04x:%04x)\n", n, dev.devfn, l, d);
-					while (!(err = pci_bios_find_device(l, d, idx, &bios_bus, &bios_dfn)) &&
-					       (bios_bus != n || bios_dfn != dev.devfn))
-						idx++;
-					if (err)
-						break;
-				}
-#endif
-				DBG("Found device at %02x:%02x\n", n, dev.devfn);
-				found++;
-				if (!pci_read_config_word(&dev, PCI_CLASS_DEVICE, &l) &&
-				    l == PCI_CLASS_BRIDGE_HOST)
-					cnt++;
+				DBG("Found device at %02x:%02x [%04x]\n", n, dev.devfn, l);
+				printk("PCI: Discovered peer bus %02x\n", n);
+				pci_scan_bus(n, pci_root_ops, NULL);
+				break;
 			}
-		if (cnt-- <= 0)
-			break;
-		if (found) {
-			printk("PCI: Discovered primary peer bus %02x\n", n);
-			b = pci_scan_bus(n, ops, NULL);
-			if (b)
-				n = b->subordinate;
-		}
-		n++;
 	}
 }
 
@@ -881,6 +825,7 @@
 		if (suba < subb)
 			pci_scan_bus(suba+1, pci_root_ops, NULL);	/* Bus B */
 	}
+	pcibios_last_bus = -1;
 }
 
 static void __init pci_fixup_i450gx(struct pci_dev *d)
@@ -893,6 +838,7 @@
 	pci_read_config_byte(d, 0x4a, &busno);
 	printk("PCI: i440KX/GX host bridge %s: secondary bus %02x\n", d->slot_name, busno);
 	pci_scan_bus(busno, pci_root_ops, NULL);
+	pcibios_last_bus = -1;
 }
 
 static void __init pci_fixup_rcc(struct pci_dev *d)
@@ -905,6 +851,7 @@
 	pci_read_config_byte(d, 0x44, &busno);
 	printk("PCI: RCC host bridge: secondary bus %02x\n", busno);
 	pci_scan_bus(busno, pci_root_ops, NULL);
+	pcibios_last_bus = -1;
 }
 
 static void __init pci_fixup_compaq(struct pci_dev *d)
@@ -917,6 +864,7 @@
 	pci_read_config_byte(d, 0xc8, &busno);
 	printk("PCI: Compaq host bridge: secondary bus %02x\n", busno);
 	pci_scan_bus(busno, pci_root_ops, NULL);
+	pcibios_last_bus = -1;
 }
 
 static void __init pci_fixup_umc_ide(struct pci_dev *d)
@@ -977,333 +925,6 @@
 };
 
 /*
- *  Fix up IRQs of all PCI devices.
- */
-
-extern int skip_ioapic_setup;
-
-#define PIRQ_SIGNATURE	(('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
-#define PIRQ_VERSION 0x0100
-
-static struct irq_routing_table *pirq_table;
-
-/*
- *  Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
- */
-
-static struct irq_routing_table * __init pcibios_find_irq_routing_table(void)
-{
-	u8 *addr;
-	struct irq_routing_table *rt;
-	int i;
-	u8 sum;
-
-	for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
-		rt = (struct irq_routing_table *) addr;
-		if (rt->signature != PIRQ_SIGNATURE ||
-		    rt->version != PIRQ_VERSION ||
-		    rt->size % 16 ||
-		    rt->size < sizeof(struct irq_routing_table))
-			continue;
-		sum = 0;
-		for(i=0; i<rt->size; i++)
-			sum += addr[i];
-		if (!sum) {
-			printk("PCI: Interrupt Routing Table found at 0x%p [router type %04x/%04x]\n",
-			       rt, rt->rtr_vendor, rt->rtr_device);
-			return rt;
-		}
-	}
-	return NULL;
-}
-
-/*
- *  If we have a IRQ routing table, use it to search for peer host
- *  bridges.  It's a gross hack, but since there are no other known
- *  ways how to get a list of buses, we have to go this way.
- */
-
-static void __init pcibios_irq_peer_trick(struct irq_routing_table *rt)
-{
-	u8 busmap[256];
-	int i;
-	struct irq_info *e;
-
-	memset(busmap, 0, sizeof(busmap));
-	for(i=0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) {
-		e = &rt->slots[i];
-		DBG("b=%02x d=%02x s=%02x\n", e->bus, e->devfn, e->slot);
-		busmap[e->bus] = 1;
-	}
-	for(i=1; i<256; i++)
-		/*
-		 *  It might be a secondary bus, but in this case its parent is already
-		 *  known (ascending bus order) and therefore pci_scan_bus returns immediately.
-		 */
-		if (busmap[i] && pci_scan_bus(i, pci_root_bus->ops, NULL))
-			printk("PCI: Discovered primary peer bus %02x [IRQ]\n", i);
-}
-
-static void ali_set_level_irq(unsigned irq)
-{
-	unsigned char mask = 1 << (irq & 7);
-	unsigned int port = 0x4d0 + (irq >> 3);
-	unsigned char val = inb(port);
-
-	if (val & mask) {
-		DBG("PCI irq %d was level\n", irq);
-		return;
-	}
-	DBG("PCI irq %d was edge, turning into level-triggered\n", irq);
-	outb(val | mask, port);
-}
-
-static int ali_set_irq(struct pci_dev *router, unsigned pirq, unsigned irq)
-{
-	if (irq < 15) {
-		static unsigned char irqmap[16] = {
-			0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15
-		};
-		unsigned char val = irqmap[irq];
-		if (val && pirq < 8) {
-			u8 byte;
-			unsigned offset = 0x48 + (pirq >> 1);
-			unsigned shift = (pirq & 1) << 2;
-			pci_read_config_byte(router, offset, &byte);
-			DBG("ALI: old %04x=%02x\n", offset, byte);
-			byte &= ~(0xf << shift);
-			byte |= val << shift;
-			DBG("ALI: new %04x=%02x\n", offset, byte);
-			pci_write_config_byte(router, offset, byte);
-			ali_set_level_irq(irq);
-			return irq;
-		}
-	}
-	return 0;
-}
-
-/*
- *  In case BIOS forgets to tell us about IRQ, we try to look it up in the routing
- *  table, but unfortunately we have to know the interrupt router chip.
- */
-
-/*
- * Never use: 0, 1, 2 (timer, keyboard, and cascade)
- * Avoid using: 13, 14 and 15 (FP error and IDE).
- * Penalize: 3, 4, 7, 12 (known ISA uses: serial, parallel and mouse)
- */
-static unsigned int pcibios_irq_mask = 0xfff8;
-
-static unsigned pcibios_irq_penalty[16] = {
-	10000, 10000, 10000, 100, 100, 0, 0, 100,
-	0, 0, 0, 0, 100, 1000, 1000, 1000
-};
-
-static char *pcibios_lookup_irq(struct pci_dev *dev, struct irq_routing_table *rt, int pin, int assign)
-{
-	struct irq_info *q;
-	struct pci_dev *router;
-	int i, pirq, newirq, reg;
-	u32 rtrid, mask;
-	u8 x, y;
-	char *msg = NULL;
-
-	pin--;
-	DBG("IRQ for %s(%d)", dev->slot_name, pin);
-	while (dev->bus->self) {
-		pin = (pin + PCI_SLOT(dev->devfn)) % 4;
-		dev = dev->bus->self;
-		DBG(" -> %s(%d)", dev->slot_name, pin);
-	}
-	for(q = rt->slots, i = rt->size - sizeof(struct irq_routing_table);
-	    i && (q->bus != dev->bus->number || PCI_SLOT(q->devfn) != PCI_SLOT(dev->devfn));
-	    i -= sizeof(struct irq_info), q++)
-		;
-	if (!i) {
-		DBG(" -> not found in routing table\n");
-		return NULL;
-	}
-	pirq = q->irq[pin].link;
-	mask = q->irq[pin].bitmap;
-	if (!pirq) {
-		DBG(" -> not routed\n");
-		return NULL;
-	}
-	DBG(" -> PIRQ %02x, mask %04x", pirq, mask);
-	newirq = 0;
-	if (assign && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
-		for (i = 0; i < 16; i++) {
-			if (!(mask & pcibios_irq_mask & (1 << i)))
-				continue;
-			if (pcibios_irq_penalty[i] < pcibios_irq_penalty[newirq])
-				newirq = i;
-		}
-	}
-	if (!(router = pci_find_slot(rt->rtr_bus, rt->rtr_devfn))) {
-		DBG(" -> router not found\n");
-		return NULL;
-	}
-#define ID(x,y) ((x << 16) | y)
-	rtrid = ID(rt->rtr_vendor, rt->rtr_device);
-	if (!rtrid) {
-		/*
-		 * Several BIOSes forget to set the router type. In such cases, we
-		 * use chip vendor/device. This doesn't guarantee us semantics of
-		 * PIRQ values, but was found to work in practice and it's still
-		 * better than not trying.
-		 */
-		DBG(" [%s]", router->slot_name);
-		rtrid = ID(router->vendor, router->device);
-	}
-	switch (rtrid) {
-	case ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0):
-	case ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0):
-	case ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0):
-		/* Intel PIIX: PIRQ holds configuration register address */
-		pci_read_config_byte(router, pirq, &x);
-		if (x < 16) {
-			DBG(" -> [PIIX] %02x\n", x);
-			newirq = x;
-			msg = "PIIX";
-		} else if (newirq) {
-			DBG(" -> [PIIX] set to %02x\n", newirq);
-			pci_write_config_byte(router, pirq, newirq);
-			msg = "PIIX-NEW";
-		} else DBG(" -> [PIIX] sink\n");
-		break;
-	case ID(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533):
-		newirq = ali_set_irq(router, pirq-1, newirq);
-		if (newirq)
-			msg = "ALI";
-		break;
-	case ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596):
-	case ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686):
-		reg = 0x55 + (pirq >> 1);
-		pci_read_config_byte(router, reg, &x);
-		y = (pirq & 1) ? (x >> 4) : (x & 0x0f);
-		if (y) {
-			DBG(" -> [VIA] %02x\n", y);
-			newirq = y;
-			msg = "VIA";
-		} else if (newirq) {
-			DBG(" -> [VIA] set to %02x\n", newirq);
-			x = (pirq & 1) ? ((x & 0x0f) | (newirq << 4)) : ((x & 0xf0) | newirq);
-			pci_write_config_byte(router, reg, x);
-			msg = "VIA-NEW";
-		} else DBG(" -> [VIA] sink\n");
-		break;
-	case ID(PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C700):
-		reg = 0xb8 + (pirq >> 5);
-		pci_read_config_byte(router, reg, &x);
-		y = (pirq & 0x10) ? (x >> 4) : (x & 0x0f);
-		if (y) {
-			DBG(" -> [OPTI] %02x\n", y);
-			newirq = y;
-			msg = "OPTI";
-		} else if (newirq) {
-			DBG(" -> [OPTI] set to %02x\n", newirq);
-			x = (pirq & 0x10) ? ((x & 0x0f) | (newirq << 4)) : ((x & 0xf0) | newirq);
-			pci_write_config_byte(router, reg, y);
-			msg = "OPTI-NEW";
-		} else DBG(" -> [OPTI] sink\n");
-		break;
-	default:
-		DBG(" -> unknown router %04x/%04x\n", rt->rtr_vendor, rt->rtr_device);
-		if (newirq && mask == (1 << newirq)) {
-			/* Only one IRQ available -> use it */
-			msg = "guess";
-		}
-	}
-#undef ID
-
-	if (msg) {
-		dev->irq = newirq;
-		pcibios_irq_penalty[newirq]++;
-	}
-	return msg;
-}
-
-static void __init pcibios_fixup_irqs(void)
-{
-	struct irq_routing_table *rtable;
-	struct pci_dev *dev;
-	u8 pin;
-
-	DBG("PCI: IRQ fixup\n");
-	rtable = pirq_table = pcibios_find_irq_routing_table();
-#ifdef CONFIG_PCI_BIOS
-	if (!rtable && pci_bios_present)
-		rtable = pcibios_get_irq_routing_table();
-#endif
-
-	if (rtable)
-		pcibios_irq_peer_trick(rtable);
-
-	pci_for_each_dev(dev) {
-		/*
-		 * If the BIOS has set an out of range IRQ number, just ignore it.
-		 * Also keep track of which IRQ's are already in use.
-		 */
-		if (dev->irq >= 16) {
-			DBG("%s: ignoring bogus IRQ %d\n", dev->slot_name, dev->irq);
-			dev->irq = 0;
-		}
-		pcibios_irq_penalty[dev->irq]++;
-	}
-
-	pci_for_each_dev(dev) {
-		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-#if defined(CONFIG_X86_IO_APIC)
-		/*
-		 * Recalculate IRQ numbers if we use the I/O APIC.
-		 */
-		if(!skip_ioapic_setup)
-		{
-			int irq;
-
-			if (pin) {
-				pin--;		/* interrupt pins are numbered starting from 1 */
-				irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
-/*
- * Will be removed completely if things work out well with fuzzy parsing
- */
-#if 0
-				if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
-					struct pci_dev * bridge = dev->bus->self;
-
-					pin = (pin + PCI_SLOT(dev->devfn)) % 4;
-					irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 
-							PCI_SLOT(bridge->devfn), pin);
-					if (irq >= 0)
-						printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", 
-							bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
-				}
-#endif
-				if (irq >= 0) {
-					printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
-						dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
-					dev->irq = irq;
-				}
-			}
-			pirq_table = NULL;	/* Avoid automatic IRQ assignment */
-		}
-#endif
-		/*
-		 * Still no IRQ? Try to assign one...
-		 */
-		if (pin && !dev->irq && pirq_table) {
-			char *msg = pcibios_lookup_irq(dev, pirq_table, pin, 0);
-			if (msg)
-				printk("PCI: Found IRQ %d for device %s [%s]\n", dev->irq, dev->slot_name, msg);
-		}
-	}
-
-#ifdef CONFIG_PCI_BIOS
-	pcibios_free_irq_routing_table();
-#endif
-}
-
-/*
  *  Called after each bus is probed, but before its children
  *  are examined.
  */
@@ -1349,8 +970,7 @@
 	pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
 
 	pcibios_fixup_irqs();
-	if (pci_probe & PCI_PEER_FIXUP)
-		pcibios_fixup_peer_bridges();
+	pcibios_fixup_peer_bridges();
 	pcibios_resource_survey();
 
 #ifdef CONFIG_PCI_BIOS
@@ -1390,15 +1010,15 @@
 		return NULL;
 	}
 #endif
-	else if (!strcmp(str, "peer")) {
-		pci_probe |= PCI_PEER_FIXUP;
-		return NULL;
-	} else if (!strcmp(str, "rom")) {
+	else if (!strcmp(str, "rom")) {
 		pci_probe |= PCI_ASSIGN_ROMS;
 		return NULL;
 	} else if (!strncmp(str, "irqmask=", 8)) {
 		pcibios_irq_mask = simple_strtol(str+8, NULL, 0);
 		return NULL;
+	} else if (!strncmp(str, "lastbus=", 8)) {
+		pcibios_last_bus = simple_strtol(str+8, NULL, 0);
+		return NULL;
 	}
 	return str;
 }
@@ -1412,15 +1032,10 @@
 	if (!dev->irq) {
 		u8 pin;
 		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-		if (pin) {
-			char *msg;
-			if (pirq_table && ((msg = pcibios_lookup_irq(dev, pirq_table, pin, 1))))
-				printk("PCI: Assigned IRQ %d to device %s [%s]\n", dev->irq, dev->slot_name, msg);
-			else
-				printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
-				       'A' + pin - 1, dev->slot_name,
-				       (pci_probe & PCI_BIOS_IRQ_SCAN) ? "" : " Please try using pci=biosirq.");
-		}
+		if (pin && !pcibios_lookup_irq(dev, 1))
+			printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
+			       'A' + pin - 1, dev->slot_name,
+			       (pci_probe & PCI_BIOS_IRQ_SCAN) ? "" : " Please try using pci=biosirq.");
 	}
 	return 0;
 }
diff -u --recursive --new-file v2.3.99-pre4/linux/drivers/net/Space.c linux/drivers/net/Space.c
--- v2.3.99-pre4/linux/drivers/net/Space.c	Tue Apr 11 15:09:17 2000
+++ linux/drivers/net/Space.c	Tue Apr 11 15:11:54 2000
@@ -186,7 +186,7 @@
 	{ne3210_probe, 0},
 #endif
 #ifdef CONFIG_DEFXX
-	{dfx_probe, 0}.
+	{dfx_probe, 0},
 #endif
 	{NULL, 0},
 };
diff -u --recursive --new-file v2.3.99-pre4/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v2.3.99-pre4/linux/drivers/pci/pci.c	Mon Mar 27 08:08:27 2000
+++ linux/drivers/pci/pci.c	Tue Apr 11 16:10:32 2000
@@ -254,6 +254,23 @@
 	return 0;
 }
 
+int
+pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
+{
+	u8 pin;
+
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	if (!pin)
+		return -1;
+	pin--;
+	while (dev->bus->self) {
+		pin = (pin + PCI_SLOT(dev->devfn)) % 4;
+		dev = dev->bus->self;
+	}
+	*bridge = dev;
+	return pin;
+}
+
 /*
  *  Registration of PCI drivers and handling of hot-pluggable devices.
  */
@@ -961,7 +978,7 @@
 	return max;
 }
 
-static int __init pci_bus_exists(const struct list_head *list, int nr)
+int __init pci_bus_exists(const struct list_head *list, int nr)
 {
 	const struct list_head *l;
 
diff -u --recursive --new-file v2.3.99-pre4/linux/drivers/usb/usb.c linux/drivers/usb/usb.c
--- v2.3.99-pre4/linux/drivers/usb/usb.c	Tue Apr 11 15:09:21 2000
+++ linux/drivers/usb/usb.c	Tue Apr 11 16:56:26 2000
@@ -1720,11 +1720,15 @@
 
 	info("USB new device connect, assigned device number %d", dev->devnum);
  
-	dev->maxpacketsize = 0;		/* Default to 8 byte max packet size */
+	/* USB v1.1 5.5.3 */
+	/* We read the first 8 bytes from the device descriptor to get to */
+	/*  the bMaxPacketSize0 field. Then we set the maximum packet size */
+	/*  for the control pipe, and retrieve the rest */
 	dev->epmaxpacketin [0] = 8;
 	dev->epmaxpacketout[0] = 8;
 
-	/* We still haven't set the Address yet */
+	/* Even though we have assigned an address for the device, we */
+	/*  haven't told it what it's address is yet */
 	addr = dev->devnum;
 	dev->devnum = 0;
 
@@ -1740,12 +1744,6 @@
 	}
 	dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0;
 	dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
-	switch (dev->descriptor.bMaxPacketSize0) {
-		case 8: dev->maxpacketsize = 0; break;
-		case 16: dev->maxpacketsize = 1; break;
-		case 32: dev->maxpacketsize = 2; break;
-		case 64: dev->maxpacketsize = 3; break;
-	}
 
 	dev->devnum = addr;
 
diff -u --recursive --new-file v2.3.99-pre4/linux/fs/namei.c linux/fs/namei.c
--- v2.3.99-pre4/linux/fs/namei.c	Tue Apr 11 15:09:22 2000
+++ linux/fs/namei.c	Tue Apr 11 16:53:43 2000
@@ -522,7 +522,7 @@
 walk_init_root(const char *name, unsigned flags, struct nameidata *nd)
 {
 	if (current->personality != PER_LINUX)
-		if (__emul_lookup_dentry(name,flags,nd));
+		if (__emul_lookup_dentry(name,flags,nd))
 			return 0;
 	nd->mnt = mntget(current->fs->rootmnt);
 	nd->dentry = dget(current->fs->root);
diff -u --recursive --new-file v2.3.99-pre4/linux/fs/nfs/inode.c linux/fs/nfs/inode.c
--- v2.3.99-pre4/linux/fs/nfs/inode.c	Tue Apr 11 15:09:22 2000
+++ linux/fs/nfs/inode.c	Tue Apr 11 17:09:02 2000
@@ -198,7 +198,7 @@
 static inline unsigned long
 nfs_calc_block_size(u64 tsize)
 {
-	loff_t used = (tsize + 511) / 512;
+	loff_t used = (tsize + 511) >> 9;
 	return (used > ULONG_MAX) ? ULONG_MAX : used;
 }
 
diff -u --recursive --new-file v2.3.99-pre4/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.3.99-pre4/linux/include/linux/pci.h	Tue Apr 11 15:09:25 2000
+++ linux/include/linux/pci.h	Tue Apr 11 17:31:28 2000
@@ -465,6 +465,7 @@
 /* Generic PCI functions used internally */
 
 void pci_init(void);
+int pci_bus_exists(const struct list_head *list, int nr);
 struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
 struct pci_bus *pci_alloc_primary_bus(int bus);
 struct pci_dev *pci_scan_slot(struct pci_dev *temp);
@@ -474,7 +475,8 @@
 char *pci_class_name(u32 class);
 void pci_read_bridge_bases(struct pci_bus *child);
 struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res);
-int pci_setup_device(struct pci_dev * dev);
+int pci_setup_device(struct pci_dev *dev);
+int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge);
 
 /* Generic PCI functions exported to card drivers */
 
diff -u --recursive --new-file v2.3.99-pre4/linux/include/linux/usb.h linux/include/linux/usb.h
--- v2.3.99-pre4/linux/include/linux/usb.h	Tue Apr 11 15:09:25 2000
+++ linux/include/linux/usb.h	Tue Apr 11 16:56:26 2000
@@ -539,7 +539,6 @@
 
 	atomic_t refcnt;		/* Reference count */
 
-	int maxpacketsize;		/* Maximum packet size; encoded as 0,1,2,3 = 8,16,32,64 */
 	unsigned int toggle[2];		/* one bit for each endpoint ([0] = IN, [1] = OUT) */
 	unsigned int halted[2];		/* endpoint halts; one bit per endpoint # & direction; */
 					/* [0] = IN, [1] = OUT */
@@ -686,7 +685,7 @@
 
 static inline unsigned int __create_pipe(struct usb_device *dev, unsigned int endpoint)
 {
-	return (dev->devnum << 8) | (endpoint << 15) | (dev->slow << 26) | dev->maxpacketsize;
+	return (dev->devnum << 8) | (endpoint << 15) | (dev->slow << 26);
 }
 
 static inline unsigned int __default_pipe(struct usb_device *dev)
