diff -u --recursive --new-file v2.1.94/linux/Makefile linux/Makefile
--- v2.1.94/linux/Makefile	Wed Apr  8 19:36:24 1998
+++ linux/Makefile	Wed Apr  8 19:36:06 1998
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 94
+SUBLEVEL = 95
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/)
 
diff -u --recursive --new-file v2.1.94/linux/arch/alpha/kernel/apecs.c linux/arch/alpha/kernel/apecs.c
--- v2.1.94/linux/arch/alpha/kernel/apecs.c	Wed Apr  1 20:11:47 1998
+++ linux/arch/alpha/kernel/apecs.c	Thu Apr  9 13:16:18 1998
@@ -10,7 +10,6 @@
 #include <linux/kernel.h>
 #include <linux/config.h>
 #include <linux/types.h>
-#include <linux/bios32.h>
 #include <linux/pci.h>
 
 #include <asm/system.h>
diff -u --recursive --new-file v2.1.94/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c
--- v2.1.94/linux/arch/alpha/kernel/bios32.c	Wed Apr  8 19:36:24 1998
+++ linux/arch/alpha/kernel/bios32.c	Thu Apr  9 13:16:18 1998
@@ -250,7 +250,7 @@
 {
 	struct pci_bus *bus;
 	unsigned short cmd;
-	unsigned int base, mask, size, off;
+	unsigned int base, mask, size, off, idx;
 	unsigned int alignto;
 	unsigned long handle;
 
@@ -278,7 +278,8 @@
 	bus = dev->bus;
 	pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
 
-	for (off = PCI_BASE_ADDRESS_0; off <= PCI_BASE_ADDRESS_5; off += 4) {
+	for (idx = 0; idx <= 5; idx++) {
+		off = PCI_BASE_ADDRESS_0 + 4*idx;
 		/*
 		 * Figure out how much space and of what type this
 		 * device wants.
@@ -288,7 +289,7 @@
 		pcibios_read_config_dword(bus->number, dev->devfn, off, &base);
 		if (!base) {
 			/* this base-address register is unused */
-			dev->base_address[PCI_BASE_INDEX(off)] = 0;
+			dev->base_address[idx] = 0;
 			continue;
 		}
 
@@ -324,7 +325,7 @@
 						   off, base | 0x1);
 
 			handle = HANDLE(bus->number) | base | 1;
-			dev->base_address[PCI_BASE_INDEX(off)] = handle;
+			dev->base_address[idx] = handle;
 
 			DBG_DEVS(("layout_dev: dev 0x%x IO @ 0x%lx (0x%x)\n",
 				  dev->device, handle, size));
@@ -348,7 +349,7 @@
 				       "slot %d, function %d: \n",
 				       PCI_SLOT(dev->devfn),
 				       PCI_FUNC(dev->devfn));
-				off += 4;	/* skip extra 4 bytes */
+				idx++;	/* skip extra 4 bytes */
 				continue;
 
 			case PCI_BASE_ADDRESS_MEM_TYPE_1M:
diff -u --recursive --new-file v2.1.94/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c
--- v2.1.94/linux/arch/i386/kernel/bios32.c	Wed Apr  8 19:36:24 1998
+++ linux/arch/i386/kernel/bios32.c	Thu Apr  9 13:16:18 1998
@@ -834,44 +834,52 @@
 __initfunc(void pcibios_fixup(void))
 {
 	struct pci_dev *dev;
-	int i, has_io;
+	int i, has_io, has_mem;
+	unsigned short cmd;
+	unsigned char pin;
 
 	for(dev = pci_devices; dev; dev=dev->next) {
 		/*
-		 * There are probably some buggy BIOSes that forget to assign I/O port
-		 * addresses to several devices. We probably should assign new addresses
-		 * to such devices, but we need to gather some information first. [mj]
+		 * There are buggy BIOSes that forget to enable I/O and memory
+		 * access to PCI devices. We try to fix this, but we need to
+		 * be sure that the BIOS didn't forget to assign an address
+		 * to the device. [mj]
 		 */
-		has_io = 0;
+		has_io = has_mem = 0;
 		for(i=0; i<6; i++) {
 			unsigned long a = dev->base_address[i];
 			if (a & PCI_BASE_ADDRESS_SPACE_IO) {
-				has_io = 1;
+				has_io |= 1;
 				a &= PCI_BASE_ADDRESS_IO_MASK;
-				if (!a || a == PCI_BASE_ADDRESS_IO_MASK)
+				if (!a || a == PCI_BASE_ADDRESS_IO_MASK) {
 					printk(KERN_WARNING "PCI: BIOS forgot to assign address #%d to device %02x:%02x,"
 						" please report to <mj@ucw.cz>\n", i, dev->bus->number, dev->devfn);
-			}
+					has_io |= 2;
+				}
+			} else if (a & PCI_BASE_ADDRESS_MEM_MASK)
+				has_mem = 1;
 		}
-		/*
-		 * Check if the I/O space access is allowed. If not, moan loudly. [mj]
-		 */
-		if (has_io) {
-			unsigned short cmd;
-			pci_read_config_word(dev, PCI_COMMAND, &cmd);
-			if (!(cmd & PCI_COMMAND_IO))
-				printk(KERN_WARNING "PCI: BIOS forgot to enable I/O for device %02x:%02x,"
-					" please report to <mj@ucw.cz>\n", dev->bus->number, dev->devfn);
+		pci_read_config_word(dev, PCI_COMMAND, &cmd);
+		if (has_io == 1 && !(cmd & PCI_COMMAND_IO)) {
+			printk("PCI: Enabling I/O for device %02x:%02x\n",
+				dev->bus->number, dev->devfn);
+			cmd |= PCI_COMMAND_IO;
+			pci_write_config_word(dev, PCI_COMMAND, cmd);
 		}
+		if (has_mem && !(cmd & PCI_COMMAND_MEMORY)) {
+			printk("PCI: Enabling memory for device %02x:%02x\n",
+				dev->bus->number, dev->devfn);
+			cmd |= PCI_COMMAND_MEMORY;
+			pci_write_config_word(dev, PCI_COMMAND, cmd);
+		}
+		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 #ifdef __SMP__
 		/*
 		 * Recalculate IRQ numbers if we use the I/O APIC
 		 */
 		{
-		unsigned char pin;
 		int irq;
 
-		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 		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);
@@ -884,10 +892,13 @@
 		}
 #endif
 		/*
-		 * Fix out-of-range IRQ numbers.
+		 * Fix out-of-range IRQ numbers and report bogus IRQ.
 		 */
 		if (dev->irq >= NR_IRQS)
 			dev->irq = 0;
+		if (pin && !dev->irq)
+			printk(KERN_WARNING "PCI: Bogus IRQ for device %02x:%02x [pin=%x], please report to <mj@ucw.cz>\n",
+				dev->bus->number, dev->devfn, pin);
 	}
 }
 
@@ -919,25 +930,25 @@
 {
 	if (!strncmp(str, "off", 3)) {
 		pci_probe = 0;
-		return str+3;
+		return NULL;
 	}
 #ifdef CONFIG_PCI_BIOS
 	else if (!strncmp(str, "bios", 4)) {
 		pci_probe = PCI_PROBE_BIOS;
-		return str+4;
+		return NULL;
 	} else if (!strncmp(str, "nobios", 6)) {
 		pci_probe &= ~PCI_PROBE_BIOS;
-		return str+6;
+		return NULL;
 	}
 #endif
 #ifdef CONFIG_PCI_DIRECT
 	else if (!strncmp(str, "conf1", 5)) {
 		pci_probe = PCI_PROBE_CONF1;
-		return str+5;
+		return NULL;
 	}
 	else if (!strncmp(str, "conf2", 5)) {
 		pci_probe = PCI_PROBE_CONF2;
-		return str+5;
+		return NULL;
 	}
 #endif
 	return str;
diff -u --recursive --new-file v2.1.94/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.1.94/linux/arch/i386/kernel/irq.c	Wed Apr  8 19:36:25 1998
+++ linux/arch/i386/kernel/irq.c	Thu Apr  9 22:10:59 1998
@@ -537,20 +537,31 @@
 	global_irq_holder = cpu;
 }
 
+#define EFLAGS_IF_SHIFT 9
+
 /*
  * A global "cli()" while in an interrupt context
  * turns into just a local cli(). Interrupts
  * should use spinlocks for the (very unlikely)
  * case that they ever want to protect against
  * each other.
+ *
+ * If we already have local interrupts disabled,
+ * this will not turn a local disable into a
+ * global one (problems with spinlocks: this makes
+ * save_flags+cli+sti usable inside a spinlock).
  */
 void __global_cli(void)
 {
-	int cpu = smp_processor_id();
+	unsigned int flags;
 
-	__cli();
-	if (!local_irq_count[cpu])
-		get_irqlock(cpu);
+	__save_flags(flags);
+	if (flags & (1 << EFLAGS_IF_SHIFT)) {
+		int cpu = smp_processor_id();
+		__cli();
+		if (!local_irq_count[cpu])
+			get_irqlock(cpu);
+	}
 }
 
 void __global_sti(void)
@@ -562,33 +573,53 @@
 	__sti();
 }
 
+/*
+ * SMP flags value to restore to:
+ * 0 - global cli
+ * 1 - global sti
+ * 2 - local cli
+ * 3 - local sti
+ */
 unsigned long __global_save_flags(void)
 {
-	if (!local_irq_count[smp_processor_id()])
-		return global_irq_holder == (unsigned char) smp_processor_id();
-	else {
-		unsigned long x;
-		__save_flags(x);
-		return x;
+	int retval;
+	int local_enabled;
+	unsigned long flags;
+
+	__save_flags(flags);
+	local_enabled = (flags >> EFLAGS_IF_SHIFT) & 1;
+	/* default to local */
+	retval = 2 + local_enabled;
+
+	/* check for global flags if we're not in an interrupt */
+	if (!local_irq_count[smp_processor_id()]) {
+		if (local_enabled)
+			retval = 1;
+		if (global_irq_holder == (unsigned char) smp_processor_id())
+			retval = 0;
 	}
+	return retval;
 }
 
 void __global_restore_flags(unsigned long flags)
 {
-	if (!local_irq_count[smp_processor_id()]) {
-		switch (flags) {
-		case 0:
-			__global_sti();
-			break;
-		case 1:
-			__global_cli();
-			break;
-		default:
-			printk("global_restore_flags: %08lx (%08lx)\n",
-				flags, (&flags)[-1]);
-		}
-	} else
-		__restore_flags(flags);
+	switch (flags) {
+	case 0:
+		__global_cli();
+		break;
+	case 1:
+		__global_sti();
+		break;
+	case 2:
+		__cli();
+		break;
+	case 3:
+		__sti();
+		break;
+	default:
+		printk("global_restore_flags: %08lx (%08lx)\n",
+			flags, (&flags)[-1]);
+	}
 }
 
 #endif
@@ -1073,7 +1104,6 @@
 	outb_p(LATCH & 0xff , 0x40);	/* LSB */
 	outb(LATCH >> 8 , 0x40);	/* MSB */
 
-	printk("INIT IRQ\n");
 	for (i=0; i<NR_IRQS; i++) {
 		irq_events[i] = 0;
 		disabled_irq[i] = 0;
diff -u --recursive --new-file v2.1.94/linux/drivers/block/ide-disk.c linux/drivers/block/ide-disk.c
--- v2.1.94/linux/drivers/block/ide-disk.c	Wed Apr  1 20:11:48 1998
+++ linux/drivers/block/ide-disk.c	Thu Apr  9 13:43:52 1998
@@ -120,7 +120,6 @@
 	}
 	msect = drive->mult_count;
 	
-	spin_lock_irqsave(&io_request_lock,flags);
 read_next:
 	rq = HWGROUP(drive)->rq;
 	if (msect) {
@@ -152,7 +151,6 @@
 			goto read_next;
 		ide_set_handler (drive, &read_intr, WAIT_CMD);
 	}
-	spin_unlock_irqrestore(&io_request_lock,flags);
 }
 
 /*
@@ -167,7 +165,6 @@
 	unsigned long flags;
 	int error = 0;
 
-	spin_lock_irqsave(&io_request_lock,flags);
 	if (OK_STAT(stat=GET_STAT(),DRIVE_READY,drive->bad_wstat)) {
 #ifdef DEBUG
 		printk("%s: write: sector %ld, buffer=0x%08lx, remaining=%ld\n",
@@ -192,7 +189,6 @@
 		error = 1;
 
 out:
-	spin_unlock_irqrestore(&io_request_lock,flags);
 
 	if (error)
 		ide_error(drive, "write_intr", stat);
@@ -246,7 +242,6 @@
 	unsigned long flags;
 	int error = 0;
 
-	spin_lock_irqsave(&io_request_lock,flags);
 	if (OK_STAT(stat=GET_STAT(),DRIVE_READY,drive->bad_wstat)) {
 		if (stat & DRQ_STAT) {
 			if (rq->nr_sectors) {
@@ -268,7 +263,6 @@
 		error = 1;
 
 out:
-	spin_unlock_irqrestore(&io_request_lock,flags);
 
 	if (error)
 		ide_error(drive, "multwrite_intr", stat);
diff -u --recursive --new-file v2.1.94/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v2.1.94/linux/drivers/block/ide.c	Mon Apr  6 17:40:59 1998
+++ linux/drivers/block/ide.c	Thu Apr  9 15:42:07 1998
@@ -1265,10 +1265,7 @@
 #define IDE_IRQ_EQUAL(irq1, irq2)	((irq1) == (irq2))
 #endif
 
-/*
- * entry point for all interrupts, caller does __cli() for us
- */
-void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
+static void do_ide_intr (int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned long flags;
 	ide_hwgroup_t *hwgroup = dev_id;
@@ -1303,13 +1300,11 @@
 			ide_sti(); HACK */
 		handler(drive);
 		/* this is necessary, as next rq may be different irq */
-		spin_lock_irqsave(&io_request_lock,flags);
 		if (hwgroup->handler == NULL) {
 			set_recovery_timer(HWIF(drive));
 			drive->service_time = jiffies - drive->service_start;
 			ide_do_request(hwgroup);
 		}
-		spin_unlock_irqrestore(&io_request_lock,flags);
 	} else {
 		unexpected_intr(irq, hwgroup);
 	}
@@ -1319,6 +1314,18 @@
 		if (!IDE_IRQ_EQUAL(hwif->irq, irq))
 			enable_irq(hwif->irq);
 	} while ((hwif = hwif->next) != hwgroup->hwif);
+}
+
+/*
+ * entry point for all interrupts, caller does __cli() for us
+ */
+void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	do_ide_intr(irq, dev_id, regs);
+	spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
 /*
diff -u --recursive --new-file v2.1.94/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- v2.1.94/linux/drivers/block/ll_rw_blk.c	Mon Apr  6 17:40:59 1998
+++ linux/drivers/block/ll_rw_blk.c	Thu Apr  9 13:44:53 1998
@@ -148,8 +148,6 @@
 			queue_new_request = 1;
 		}
 	}
-	spin_unlock_irqrestore(&io_request_lock,flags);
-
 	if (queue_new_request)
 		/*
 		 * request functions are smart enough to notice a change
@@ -157,6 +155,8 @@
 		 * is OK, i think. <-- FIXME: [is this true? --mingo]
 		 */
 		(dev->request_fn)();
+
+	spin_unlock_irqrestore(&io_request_lock,flags);
 }
 
 /*
@@ -348,14 +348,13 @@
 	if (scsi_blk_major(MAJOR(req->rq_dev)))
 		queue_new_request = 1;
 out:
-	spin_unlock_irqrestore(&io_request_lock,flags);
-
 	/*
 	 * request_fn() is usually a quite complex and slow function,
 	 * we want to call it with no spinlocks held
 	 */
 	if (queue_new_request)
 		(dev->request_fn)();
+	spin_unlock_irqrestore(&io_request_lock,flags);
 }
 
 /*
diff -u --recursive --new-file v2.1.94/linux/drivers/char/tga.c linux/drivers/char/tga.c
--- v2.1.94/linux/drivers/char/tga.c	Mon Apr  6 17:40:59 1998
+++ linux/drivers/char/tga.c	Thu Apr  9 13:10:15 1998
@@ -472,12 +472,11 @@
 tga_console_init(void))
 {
 	struct pci_dev *dev;
-	int status;
 	
 	/*
 	 * first, find the TGA among the PCI devices...
 	 */
-	if (! (dev = pci_find_device(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA, NULL)))
+	if (! (dev = pci_find_device(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA, NULL))) {
 		/* PANIC!!! */
 		printk("tga_console_init: TGA not found!!! :-(\n");
 		return;
diff -u --recursive --new-file v2.1.94/linux/drivers/misc/parport_pc.c linux/drivers/misc/parport_pc.c
--- v2.1.94/linux/drivers/misc/parport_pc.c	Mon Apr  6 17:41:00 1998
+++ linux/drivers/misc/parport_pc.c	Fri Apr 10 10:10:31 1998
@@ -641,58 +641,6 @@
 
 /* --- IRQ detection -------------------------------------- */
 
-/* This code is for detecting ECP interrupts (due to problems with the
- * monolithic interrupt probing routines).
- *
- * In short this is a voting system where the interrupt with the most
- * "votes" is the elected interrupt (it SHOULD work...)
- *
- * This is horribly x86-specific at the moment.  I'm not convinced it
- * belongs at all.
- */
-
-static int intr_vote[16];
-
-static void parport_vote_intr_func(int irq, void *dev_id, struct pt_regs *regs)
-{
-	intr_vote[irq]++;
-	return;
-}
-
-static long open_intr_election(void)
-{
-	long tmp = 0;
-	int i;
-
-	/* We ignore the timer - irq 0 */
-	for (i = 1; i < 16; i++) {
-		intr_vote[i] = 0;
-		if (request_irq(i, parport_vote_intr_func,
-		       SA_INTERRUPT, "probe", intr_vote) == 0)
-			tmp |= 1 << i;
-	}
-	return tmp;
-}
-
-static int close_intr_election(long tmp)
-{
-	int irq = PARPORT_IRQ_NONE;
-	int i;
-
-	/* We ignore the timer - irq 0 */
-	for (i = 1; i < 16; i++)
-		if (tmp & (1 << i)) {
-			if (intr_vote[i]) {
-				if (irq != PARPORT_IRQ_NONE)
-					/* More than one interrupt */
-					return PARPORT_IRQ_NONE;
-				irq = i;
-			}
-			free_irq(i, intr_vote);
-		}
-	return irq;
-}
-
 /* Only if supports ECP mode */
 static int programmable_irq_support(struct parport *pb)
 {
@@ -714,20 +662,23 @@
 static int irq_probe_ECP(struct parport *pb)
 {
 	int irqs, i;
-	unsigned char oecr = parport_pc_read_econtrol(pb);
 		
-	probe_irq_off(probe_irq_on());	/* Clear any interrupts */
-	irqs = open_intr_election();
+	sti();
+	irqs = probe_irq_on();
 		
-	parport_pc_write_econtrol(pb, 0x00);	    /* Reset FIFO */
-	parport_pc_write_econtrol(pb, 0xd0);	    /* TEST FIFO + nErrIntrEn */
+	parport_pc_write_econtrol(pb, 0x00);    /* Reset FIFO */
+	parport_pc_write_econtrol(pb, 0xd0);    /* TEST FIFO + nErrIntrEn */
 
 	/* If Full FIFO sure that WriteIntrThresold is generated */
 	for (i=0; i < 1024 && !(parport_pc_read_econtrol(pb) & 0x02) ; i++) 
 		parport_pc_write_fifo(pb, 0xaa);
 		
-	pb->irq = close_intr_election(irqs);
-	parport_pc_write_econtrol(pb, oecr);
+	pb->irq = probe_irq_off(irqs);
+	parport_pc_write_econtrol(pb, 0x00);
+
+	if (pb->irq <= 0)
+		pb->irq = PARPORT_IRQ_NONE;
+
 	return pb->irq;
 }
 
@@ -745,26 +696,30 @@
 	return PARPORT_IRQ_NONE;
 #endif
 	
-	probe_irq_off(probe_irq_on());	/* Clear any interrupts */
-	irqs = open_intr_election();
+	sti();
+	irqs = probe_irq_on();
 
 	if (pb->modes & PARPORT_MODE_PCECR)
-		parport_pc_write_econtrol(pb, parport_pc_read_econtrol(pb) | 0x10);
+		parport_pc_frob_econtrol (pb, 0x10, 0x10);
 	
 	epp_clear_timeout(pb);
-	parport_pc_write_control(pb, parport_pc_read_control(pb) | 0x20);
-	parport_pc_write_control(pb, parport_pc_read_control(pb) | 0x10);
+	parport_pc_frob_control (pb, 0x20, 0x20);
+	parport_pc_frob_control (pb, 0x10, 0x10);
 	epp_clear_timeout(pb);
 
-	/*  Device isn't expecting an EPP read
+	/* Device isn't expecting an EPP read
 	 * and generates an IRQ.
 	 */
 	parport_pc_read_epp(pb);
 	udelay(20);
 
-	pb->irq = close_intr_election(irqs);
+	pb->irq = probe_irq_off (irqs);
 	parport_pc_write_econtrol(pb, oecr);
 	parport_pc_write_control(pb, octr);
+
+	if (pb->irq <= 0)
+		pb->irq = PARPORT_IRQ_NONE;
+
 	return pb->irq;
 }
 
@@ -815,16 +770,19 @@
  */
 static int parport_irq_probe(struct parport *pb)
 {
-	if (pb->modes & PARPORT_MODE_PCECR)
+	unsigned char oecr = parport_pc_read_econtrol (pb);
+
+	if (pb->modes & PARPORT_MODE_PCECR) {
 		pb->irq = programmable_irq_support(pb);
+		if (pb->irq != PARPORT_IRQ_NONE)
+			goto out;
+	}
 
 	if (pb->modes & PARPORT_MODE_PCECP)
 		pb->irq = irq_probe_ECP(pb);
-			
+
 	if (pb->irq == PARPORT_IRQ_NONE && 
 	    (pb->modes & PARPORT_MODE_PCECPEPP)) {
-		unsigned char oecr = parport_pc_read_econtrol(pb);
-		parport_pc_write_econtrol(pb, 0x80);
 		pb->irq = irq_probe_EPP(pb);
 		parport_pc_write_econtrol(pb, oecr);
 	}
@@ -839,6 +797,8 @@
 	if (pb->irq == PARPORT_IRQ_NONE)
 		pb->irq = irq_probe_SPP(pb);
 
+out:
+	parport_pc_write_econtrol (pb, oecr);
 	return pb->irq;
 }
 
diff -u --recursive --new-file v2.1.94/linux/drivers/net/ne.c linux/drivers/net/ne.c
--- v2.1.94/linux/drivers/net/ne.c	Mon Apr  6 17:41:00 1998
+++ linux/drivers/net/ne.c	Thu Apr  9 16:20:29 1998
@@ -215,7 +215,7 @@
 			if (check_region(pci_ioaddr, NE_IO_EXTENT))
 				continue;
 			pci_irq_line = pdev->irq;
-			if (pci_irq_line == 0) continue;	/* Try next PCI ID */
+			if (pci_irq_line) break;	/* Found it */
 		}
 		if (!pdev)
 			continue;
diff -u --recursive --new-file v2.1.94/linux/drivers/pci/oldproc.c linux/drivers/pci/oldproc.c
--- v2.1.94/linux/drivers/pci/oldproc.c	Mon Apr  6 17:41:00 1998
+++ linux/drivers/pci/oldproc.c	Thu Apr  9 13:16:18 1998
@@ -13,6 +13,8 @@
 #include <linux/pci.h>
 #include <linux/string.h>
 #include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
 #include <asm/page.h>
 
 #ifdef CONFIG_PROC_FS
@@ -910,6 +912,17 @@
 		len += nprinted;
 	}
 	return len;
+}
+
+static struct proc_dir_entry proc_old_pci = {
+	PROC_PCI, 3, "pci",
+	S_IFREG | S_IRUGO, 1, 0, 0,
+	0, &proc_array_inode_operations
+};
+
+__initfunc(void proc_old_pci_init(void))
+{
+	proc_register(&proc_root, &proc_old_pci);
 }
 
 #endif /* CONFIG_PROC_FS */
diff -u --recursive --new-file v2.1.94/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v2.1.94/linux/drivers/pci/pci.c	Mon Apr  6 17:41:00 1998
+++ linux/drivers/pci/pci.c	Thu Apr  9 13:16:18 1998
@@ -20,6 +20,7 @@
 struct pci_bus pci_root;
 struct pci_dev *pci_devices = NULL;
 static struct pci_dev **pci_last_dev_p = &pci_devices;
+static int pci_reverse __initdata = 0;
 
 #undef DEBUG
 
@@ -193,8 +194,13 @@
 		 * Put it into the global PCI device chain. It's used to
 		 * find devices once everything is set up.
 		 */
-		*pci_last_dev_p = dev;
-		pci_last_dev_p = &dev->next;
+		if (!pci_reverse) {
+			*pci_last_dev_p = dev;
+			pci_last_dev_p = &dev->next;
+		} else {
+			dev->next = pci_devices;
+			pci_devices = dev;
+		}
 
 		/*
 		 * Now insert it into the list of devices held
@@ -204,6 +210,17 @@
 		bus->devices = dev;
 
 		/*
+		 * In case the latency timer value is less than 32,
+		 * which makes everything very sllooowww, set it to
+		 * 32. Pciutils should be used to fine-tune it later.
+		 * Note that we don't check if the device is a bus-master:
+		 * if it isn't, write to the latency timer should be ignored.
+		 */
+		pcibios_read_config_byte(bus->number, dev->devfn, PCI_LATENCY_TIMER, &tmp);
+		if (tmp < 32)
+			pcibios_write_config_byte(bus->number, dev->devfn, PCI_LATENCY_TIMER, 32);
+
+		/*
 		 * If it's a bridge, scan the bus behind it.
 		 */
 		if (class >> 8 == PCI_CLASS_BRIDGE_PCI) {
@@ -299,6 +316,7 @@
 
 	if (!pci_present()) {
 		printk("PCI: No PCI bus detected\n");
+		return;
 	}
 
 	printk("PCI: Probing PCI hardware.\n");
@@ -312,12 +330,30 @@
 #ifdef CONFIG_PCI_OPTIMIZE
 	pci_quirks_init();
 #endif
+
+#ifdef CONFIG_PROC_FS
+	proc_bus_pci_init();
+#ifdef CONFIG_PCI_OLD_PROC
+	proc_old_pci_init();
+#endif
+#endif
 }
 
 
 __initfunc(void pci_setup (char *str, int *ints))
 {
 	str = pcibios_setup(str);
-	if (*str)
-		printk(KERN_ERR "PCI: Unknown option `%s'\n", str);
+	while (str) {
+		char *k = strchr(str, ',');
+		if (k)
+			*k++ = 0;
+		if (*str) {
+			if (!(str = pcibios_setup(str)) || !*str)
+				continue;
+			if (!strcmp(str, "reverse"))
+				pci_reverse = 1;
+			else printk(KERN_ERR "PCI: Unknown option `%s'\n", str);
+		}
+		str = k;
+	}
 }
diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c
--- v2.1.94/linux/drivers/scsi/BusLogic.c	Wed Apr  1 20:11:52 1998
+++ linux/drivers/scsi/BusLogic.c	Thu Apr  9 13:53:13 1998
@@ -42,6 +42,9 @@
 #include <linux/stat.h>
 #include <linux/pci.h>
 #include <linux/bios32.h>
+
+#include <linux/blk.h>
+
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -3267,8 +3270,7 @@
   BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
   Adapters.
 */
-
-static void BusLogic_InterruptHandler(int IRQ_Channel,
+static void do_BusLogic_InterruptHandler(int IRQ_Channel,
 				      void *DeviceIdentifier,
 				      Registers_T *InterruptRegisters)
 {
@@ -3375,6 +3377,22 @@
 	}
 }
 
+/*
+ * This is the low-level interrupt handler:
+ * we get the io request lock here to guarantee
+ * that all of this is atomic wrt the setup
+ * functions.
+ */
+static void BusLogic_InterruptHandler(int IRQ_Channel,
+				      void *DeviceIdentifier,
+				      Registers_T *InterruptRegisters)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	do_BusLogic_InterruptHandler(IRQ_Channel, DeviceIdentifier, InterruptRegisters);
+	spin_unlock_irqrestore(&io_request_lock, flags);
+}
 
 /*
   BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/aha1740.c linux/drivers/scsi/aha1740.c
--- v2.1.94/linux/drivers/scsi/aha1740.c	Thu Mar 27 14:40:05 1997
+++ linux/drivers/scsi/aha1740.c	Thu Apr  9 13:47:16 1998
@@ -228,6 +228,9 @@
     struct ecb *ecbptr;
     Scsi_Cmnd *SCtmp;
     unsigned int base;
+    unsigned long flags;
+
+    spin_lock_irqsave(&io_request_lock, flags);
 
     if (!aha_host[irq - 9])
 	panic("aha1740.c: Irq from unknown host!\n");
@@ -304,6 +307,8 @@
 	}
 	number_serviced++;
     }
+
+    spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
 int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c
--- v2.1.94/linux/drivers/scsi/eata.c	Mon Apr  6 17:41:00 1998
+++ linux/drivers/scsi/eata.c	Fri Apr 10 10:13:58 1998
@@ -1,6 +1,14 @@
 /*
  *      eata.c - Low-level driver for EATA/DMA SCSI host adapters.
  *   
+ *      10 Apr 1998 rev. 4.04 for linux 2.0.33 and 2.1.95
+ *          Improved SMP support (if linux version >= 2.1.95).
+ *
+ *       9 Apr 1998 rev. 4.03 for linux 2.0.33 and 2.1.94
+ *          Added support for new PCI code and IO-APIC remapping of irqs.
+ *          Performance improvement: when sequential i/o is detected,
+ *          always use direct sort instead of reverse sort.
+ *   
  *       4 Apr 1998 rev. 4.02 for linux 2.0.33 and 2.1.92
  *          io_port is now unsigned long.
  *
@@ -280,11 +288,14 @@
  *  the driver sets host->wish_block = TRUE for all ISA boards.
  */
 
+#include <linux/version.h>
+
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
 #define MAX_INT_PARAM 10
+
 #if defined(MODULE)
 #include <linux/module.h>
-#include <linux/version.h>
+
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,26)
 MODULE_PARM(io_port, "1-" __MODULE_STRING(MAX_INT_PARAM) "i");
 MODULE_PARM(linked_comm, "i");
@@ -294,6 +305,7 @@
 MODULE_PARM(tag_mode, "i");
 MODULE_AUTHOR("Dario Ballabio");
 #endif
+
 #endif
 
 #include <linux/string.h>
@@ -314,9 +326,12 @@
 #include "eata.h"
 #include <linux/stat.h>
 #include <linux/config.h>
-#include <linux/bios32.h>
 #include <linux/pci.h>
 
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,1,93)
+#include <linux/bios32.h>
+#endif
+
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,36)
 #include <linux/init.h>
 #else
@@ -338,6 +353,7 @@
 
 #undef  DEBUG_LINKED_COMMANDS
 #undef  DEBUG_DETECT
+#undef  DEBUG_PCI_DETECT
 #undef  DEBUG_INTERRUPT
 #undef  DEBUG_RESET
 
@@ -583,7 +599,7 @@
 #define V2DEV(addr) ((addr) ? H2DEV(virt_to_bus((void *)addr)) : 0)
 #define DEV2V(addr) ((addr) ? DEV2H(bus_to_virt((unsigned long)addr)) : 0)
 
-static void eata2x_interrupt_handler(int, void *, struct pt_regs *);
+static void interrupt_handler(int, void *, struct pt_regs *);
 static void flush_dev(Scsi_Device *, unsigned long, unsigned int, unsigned int);
 static int do_trace = FALSE;
 static int setup_done = FALSE;
@@ -715,10 +731,48 @@
    return FALSE;
 }
 
+__initfunc (static inline int
+            get_pci_irq(unsigned long port_base, unsigned char *apic_irq)) {
+
+#if defined(CONFIG_PCI)
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,93)
+
+   unsigned int addr;
+   struct pci_dev *dev = NULL;
+
+   if (!pci_present()) return FALSE;
+
+   while((dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
+
+      if (pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &addr)) continue;
+
+#if defined(DEBUG_PCI_DETECT)
+      printk("%s: get_pci_irq, bus %d, devfn 0x%x, addr 0x%x, apic_irq %u.\n",
+             driver_name, dev->bus->number, dev->devfn, addr, dev->irq);
+#endif
+
+      if ((addr & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO)
+             continue;
+
+      if ((addr & PCI_BASE_ADDRESS_IO_MASK) + PCI_BASE_ADDRESS_0 == port_base) {
+         *apic_irq = dev->irq;
+         return TRUE;
+         }
+
+      }
+
+#endif /* end new style PCI code */
+
+#endif /* end CONFIG_PCI */
+
+   return FALSE;
+}
+
 __initfunc (static inline int port_detect \
       (unsigned long port_base, unsigned int j, Scsi_Host_Template *tpnt)) {
    unsigned char irq, dma_channel, subversion, i;
-   unsigned char protocol_rev;
+   unsigned char protocol_rev, apic_irq;
    struct eata_info info;
    char *bus_type, dma_name[16], tag_type;
 
@@ -812,8 +866,13 @@
       printk("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",
              name, irq);
 
+   if (get_pci_irq(port_base, &apic_irq) && (irq != apic_irq)) {
+      printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq, apic_irq);
+      irq = apic_irq;
+      }
+
    /* Board detected, allocate its IRQ */
-   if (request_irq(irq, eata2x_interrupt_handler,
+   if (request_irq(irq, interrupt_handler,
              SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0),
              driver_name, (void *) &sha[j])) {
       printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
@@ -1016,21 +1075,49 @@
 
 #if defined(CONFIG_PCI)
 
-   unsigned short i = 0;
-   unsigned char bus, devfn;
    unsigned int addr, k;
 
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,93)
+
+   struct pci_dev *dev = NULL;
+
    if (!pci_present()) return;
 
    for (k = 0; k < MAX_PCI; k++) {
 
+      if (!(dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break;
+
+      if (pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &addr)) continue;
+
+#if defined(DEBUG_PCI_DETECT)
+      printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n",
+             driver_name, k, dev->bus->number, dev->devfn, addr);
+#endif
+
+      if ((addr & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO)
+             continue;
+
+      /* Reverse the returned address order */
+      io_port[MAX_INT_PARAM + MAX_PCI - k] = 
+             (addr & PCI_BASE_ADDRESS_IO_MASK) + PCI_BASE_ADDRESS_0;
+      }
+
+#else  /* else old style PCI code */
+
+   unsigned short i = 0;
+   unsigned char bus, devfn;
+
+   if (!pcibios_present()) return;
+
+   for (k = 0; k < MAX_PCI; k++) {
+
       if (pcibios_find_class(PCI_CLASS_STORAGE_SCSI << 8, i++, &bus, &devfn)
              != PCIBIOS_SUCCESSFUL) break;
 
       if (pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &addr)
              != PCIBIOS_SUCCESSFUL) continue;
 
-#if defined(DEBUG_DETECT)
+#if defined(DEBUG_PCI_DETECT)
       printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n",
              driver_name, k, bus, devfn, addr);
 #endif
@@ -1042,7 +1129,10 @@
       io_port[MAX_INT_PARAM + MAX_PCI - k] = 
              (addr & PCI_BASE_ADDRESS_IO_MASK) + PCI_BASE_ADDRESS_0;
       }
-#endif
+
+#endif /* end old style PCI code */
+
+#endif /* end CONFIG_PCI */
 
    return;
 }
@@ -1523,6 +1613,7 @@
    unsigned int input_only = TRUE, overlap = FALSE;
    unsigned long sl[n_ready], pl[n_ready], ll[n_ready];
    unsigned long maxsec = 0, minsec = ULONG_MAX, seek = 0, iseek = 0;
+   unsigned long ioseek = 0;
 
    static unsigned int flushcount = 0, batchcount = 0, sortcount = 0;
    static unsigned int readycount = 0, ovlcount = 0, inputcount = 0;
@@ -1547,6 +1638,7 @@
       if (SCpnt->request.sector > maxsec) maxsec = SCpnt->request.sector;
 
       sl[n] = SCpnt->request.sector;
+      ioseek += SCpnt->request.nr_sectors;
 
       if (!n) continue;
 
@@ -1568,6 +1660,8 @@
 
    if (cursec > ((maxsec + minsec) / 2)) rev = TRUE;
 
+   if (ioseek > ((maxsec - minsec) / 2)) rev = FALSE;
+
    if (!((rev && r) || (!rev && s))) sort(sl, il, n_ready, rev);
 
    if (!input_only) for (n = 0; n < n_ready; n++) {
@@ -1644,8 +1738,7 @@
 
 }
 
-static void eata2x_interrupt_handler(int irq, void *shap,
-                                     struct pt_regs *regs) {
+static inline void ihdlr(int irq, void *shap, struct pt_regs *regs) {
    Scsi_Cmnd *SCpnt;
    unsigned int i, j, k, c, status, tstatus, reg;
    unsigned int n, n_ready, il[MAX_MAILBOXES];
@@ -1703,7 +1796,8 @@
       else if (HD(j)->cp_stat[i] == IN_RESET)
          printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
       else if (HD(j)->cp_stat[i] != IN_USE) 
-         panic("%s: ihdlr, mbox %d, invalid cp_stat.\n", BN(j), i);
+         panic("%s: ihdlr, mbox %d, invalid cp_stat: %d.\n", 
+               BN(j), i, HD(j)->cp_stat[i]);
 
       HD(j)->cp_stat[i] = FREE;
       cpp = &HD(j)->cp[i];
@@ -1839,6 +1933,22 @@
                         HD(j)->iocount);
 
    return;
+}
+
+static void interrupt_handler(int irq, void *shap, struct pt_regs *regs) {
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,95)
+
+   unsigned long flags;
+   spin_lock_irqsave(&io_request_lock, flags);
+   ihdlr(irq, shap, regs);
+   spin_unlock_irqrestore(&io_request_lock, flags);
+
+#else
+
+   ihdlr(irq, shap, regs);
+
+#endif
 }
 
 int eata2x_release(struct Scsi_Host *shpnt) {
diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/eata.h linux/drivers/scsi/eata.h
--- v2.1.94/linux/drivers/scsi/eata.h	Mon Apr  6 17:41:00 1998
+++ linux/drivers/scsi/eata.h	Fri Apr 10 10:47:30 1998
@@ -5,6 +5,7 @@
 #define _EATA_H
 
 #include <scsi/scsicam.h>
+#include <linux/version.h>
 
 int eata2x_detect(Scsi_Host_Template *);
 int eata2x_release(struct Scsi_Host *);
@@ -12,7 +13,7 @@
 int eata2x_abort(Scsi_Cmnd *);
 int eata2x_reset(Scsi_Cmnd *, unsigned int);
 
-#define EATA_VERSION "4.02.00"
+#define EATA_VERSION "4.04.00"
 
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
 
diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
--- v2.1.94/linux/drivers/scsi/ncr53c8xx.c	Mon Apr  6 17:41:00 1998
+++ linux/drivers/scsi/ncr53c8xx.c	Thu Apr  9 22:11:00 1998
@@ -9787,12 +9787,16 @@
 #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,70)
 static void ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs)
 {
+     unsigned long flags;
+
 #ifdef DEBUG_NCR53C8XX
      printk("ncr53c8xx : interrupt received\n");
 #endif
 
      if (DEBUG_FLAGS & DEBUG_TINY) printf ("[");
+     spin_lock_irqsave(&io_request_lock, flags);
      ncr_exception((ncb_p) dev_id);
+     spin_unlock_irqrestore(&io_request_lock, flags);
      if (DEBUG_FLAGS & DEBUG_TINY) printf ("]\n");
 }
 
diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v2.1.94/linux/drivers/scsi/scsi.c	Mon Apr  6 17:41:00 1998
+++ linux/drivers/scsi/scsi.c	Thu Apr  9 22:11:00 1998
@@ -354,7 +354,6 @@
      */
 
    
-    spin_lock_irqsave(&io_request_lock, flags);
     host_active = NULL;
 
     for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next) {
@@ -386,7 +385,6 @@
 	       sh[index]->host_no);
     }
 
-    spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
 static void scan_scsis_done (Scsi_Cmnd * SCpnt)
@@ -653,9 +651,11 @@
     struct semaphore sem = MUTEX_LOCKED;
     SCpnt->request.sem = &sem;
     SCpnt->request.rq_status = RQ_SCSI_BUSY;
+    spin_lock_irq(&io_request_lock);
     scsi_do_cmd (SCpnt, (void *) scsi_cmd,
                  (void *) scsi_result,
                  256, scan_scsis_done, SCSI_TIMEOUT + 4 * HZ, 5);
+    spin_unlock_irq(&io_request_lock);
     down (&sem);
     SCpnt->request.sem = NULL;
   }
@@ -694,9 +694,11 @@
     struct semaphore sem = MUTEX_LOCKED;
     SCpnt->request.sem = &sem;
     SCpnt->request.rq_status = RQ_SCSI_BUSY;
+    spin_lock_irq(&io_request_lock);
     scsi_do_cmd (SCpnt, (void *) scsi_cmd,
                  (void *) scsi_result,
                  256, scan_scsis_done, SCSI_TIMEOUT, 3);
+    spin_unlock_irq(&io_request_lock);
     down (&sem);
     SCpnt->request.sem = NULL;
   }
@@ -836,9 +838,11 @@
       struct semaphore sem = MUTEX_LOCKED;
       SCpnt->request.rq_status = RQ_SCSI_BUSY;
       SCpnt->request.sem = &sem;
+      spin_lock_irq(&io_request_lock);
       scsi_do_cmd (SCpnt, (void *) scsi_cmd,
                    (void *) scsi_result, 0x2a,
                    scan_scsis_done, SCSI_TIMEOUT, 3);
+      spin_unlock_irq(&io_request_lock);
       down (&sem);
       SCpnt->request.sem = NULL;
     }
@@ -1133,21 +1137,18 @@
 	    SCpnt = found;
 	}
 
-        __save_flags(flags);
-	__cli();
 	/* See if this request has already been queued by an interrupt routine
 	 */
 	if (req && (req->rq_status == RQ_INACTIVE || req->rq_dev != dev)) {
-	   __restore_flags(flags);
 	    return NULL;
 	}
 	if (!SCpnt || SCpnt->request.rq_status != RQ_INACTIVE)	/* Might have changed */
 	{
 		if (wait && SCwait && SCwait->request.rq_status != RQ_INACTIVE){
+			spin_unlock(&io_request_lock);		/* FIXME!!!! */
  			sleep_on(&device->device_wait);
-			__restore_flags(flags);
+ 			spin_lock_irq(&io_request_lock);	/* FIXME!!!! */
 	 	} else {
-			__restore_flags(flags);
 	 		if (!wait) return NULL;
  			if (!SCwait) {
 	 			printk("Attempt to allocate device channel %d,"
@@ -1197,7 +1198,6 @@
 					      * to complete */
 	    }
             atomic_inc(&SCpnt->host->host_active); 
-	    __restore_flags(flags);
             SCSI_LOG_MLQUEUE(5, printk("Activating command for device %d (%d)\n", 
                                        SCpnt->target,
                                        atomic_read(&SCpnt->host->host_active)));
@@ -1294,7 +1294,6 @@
 
     host = SCpnt->host;
 
-    spin_lock_irqsave(&io_request_lock, flags);
     /* Assign a unique nonzero serial_number. */
     if (++serial_number == 0) serial_number = 1;
     SCpnt->serial_number = serial_number;
@@ -1304,7 +1303,6 @@
      * we can avoid the drive not being ready.
      */
     timeout = host->last_reset + MIN_RESET_DELAY;
-    spin_unlock(&io_request_lock);
 
     if (jiffies < timeout) {
 	int ticks_remaining = timeout - jiffies;
@@ -1317,11 +1315,11 @@
 	 * interrupt handler (assuming there is one irq-level per
 	 * host).
 	 */
-	__sti();
+	spin_unlock_irq(&io_request_lock);
 	while (--ticks_remaining >= 0) udelay(1000000/HZ);
 	host->last_reset = jiffies - MIN_RESET_DELAY;
+	spin_lock_irq(&io_request_lock);
     }
-    __restore_flags(flags); /* this possibly puts us back into __cli() */
 
     if( host->hostt->use_new_eh_code )
       {
@@ -1348,18 +1346,6 @@
     {
 	SCSI_LOG_MLQUEUE(3,printk("queuecommand : routine at %p\n",
                                   host->hostt->queuecommand));
-	/* This locking tries to prevent all sorts of races between
-	 * queuecommand and the interrupt code.  In effect,
-	 * we are only allowed to be in queuecommand once at
-	 * any given time, and we can only be in the interrupt
-	 * handler and the queuecommand function at the same time
-	 * when queuecommand is called while servicing the
-	 * interrupt.
-	 */
-
-	if(!in_interrupt() && SCpnt->host->irq)
-	    disable_irq(SCpnt->host->irq);
-
         /*
          * Use the old error handling code if we haven't converted the driver
          * to use the new one yet.  Note - only the new queuecommand variant
@@ -1377,9 +1363,6 @@
           {
             host->hostt->queuecommand (SCpnt, scsi_old_done);
           }
-
-	if(!in_interrupt() && SCpnt->host->irq)
-	    enable_irq(SCpnt->host->irq);
     }
     else
     {
@@ -1452,20 +1435,18 @@
      * ourselves.
      */
 
-    spin_lock_irqsave(&io_request_lock, flags);
     SCpnt->pid = scsi_pid++;
 
     while (SCSI_BLOCK((Scsi_Device *) NULL, host)) {
-	spin_unlock_irqrestore(&io_request_lock, flags);
+    	spin_unlock(&io_request_lock);	/* FIXME!!! */
 	SCSI_SLEEP(&host->host_wait, SCSI_BLOCK((Scsi_Device *) NULL, host));
-	spin_lock_irqsave(&io_request_lock, flags);
+    	spin_lock_irq(&io_request_lock);	/* FIXME!!! */
     }
 
     if (host->block) host_active = host;
 
     host->host_busy++;
     device->device_busy++;
-    spin_unlock_irqrestore(&io_request_lock, flags);
 
     /*
      * Our own function scsi_done (which marks the host as not busy, disables
@@ -1819,7 +1800,6 @@
     if(len % SECTOR_SIZE != 0 || len > PAGE_SIZE)
 	return NULL;
 
-    spin_lock_irqsave(&io_request_lock, flags);
     nbits = len >> 9;
     mask = (1 << nbits) - 1;
 
@@ -1827,7 +1807,6 @@
 	for(j=0; j<=SECTORS_PER_PAGE - nbits; j++){
 	    if ((dma_malloc_freelist[i] & (mask << j)) == 0){
 		dma_malloc_freelist[i] |= (mask << j);
-		spin_unlock_irqrestore(&io_request_lock, flags);
 		scsi_dma_free_sectors -= nbits;
 #ifdef DEBUG
                 SCSI_LOG_MLQUEUE(3,printk("SMalloc: %d %p [From:%p]\n",len, dma_malloc_pages[i] + (j << 9)));
@@ -1836,7 +1815,6 @@
 		return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9));
 	    }
 	}
-    spin_unlock_irqrestore(&io_request_lock, flags);
     return NULL;  /* Nope.  No more */
 }
 
@@ -1870,20 +1848,16 @@
             if ((mask << sector) >= (1 << SECTORS_PER_PAGE))
                 panic ("scsi_free:Bad memory alignment");
 
-	    spin_lock_irqsave(&io_request_lock, flags);
             if((dma_malloc_freelist[page] &
                 (mask << sector)) != (mask<<sector)){
-		spin_unlock_irqrestore(&io_request_lock, flags);
 #ifdef DEBUG
 		printk("scsi_free(obj=%p, len=%d) called from %08lx\n",
                        obj, len, ret);
 #endif
                 panic("scsi_free:Trying to free unused memory");
-		spin_lock_irqsave(&io_request_lock, flags);
             }
             scsi_dma_free_sectors += nbits;
             dma_malloc_freelist[page] &= ~(mask << sector);
-	    spin_unlock_irqrestore(&io_request_lock, flags);
             return 0;
 	}
     }
@@ -2547,7 +2521,6 @@
     /* When we dick with the actual DMA list, we need to
      * protect things
      */
-    spin_lock_irqsave(&io_request_lock, flags);
     if (dma_malloc_freelist)
     {
         size = (dma_sectors / SECTORS_PER_PAGE)*sizeof(FreeSectorBitmap);
@@ -2567,7 +2540,6 @@
     dma_malloc_pages = new_dma_malloc_pages;
     dma_sectors = new_dma_sectors;
     scsi_need_isa_buffer = new_need_isa_buffer;
-    spin_unlock_irqrestore(&io_request_lock, flags);
 
 #ifdef DEBUG_INIT
     printk("resize_dma_pool: dma free sectors   = %d\n", scsi_dma_free_sectors);
@@ -2806,10 +2778,8 @@
 	    {
                 online_status = SDpnt->online;
                 SDpnt->online = FALSE;
-		spin_lock_irqsave(&io_request_lock, flags);
 	        if(SCpnt->request.rq_status != RQ_INACTIVE) 
                 {
-		    spin_unlock_irqrestore(&io_request_lock, flags);
                     printk("SCSI device not inactive - state=%d, id=%d\n",
                            SCpnt->request.rq_status, SCpnt->target);
                     for(SDpnt1 = shpnt->host_queue; SDpnt1; 
@@ -2830,7 +2800,6 @@
                  */
                 SCpnt->state = SCSI_STATE_DISCONNECTING;
 	        SCpnt->request.rq_status = RQ_SCSI_DISCONNECTING;  /* Mark as busy */
-		spin_unlock_irqrestore(&io_request_lock, flags);
 	    }
         }
     }
diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v2.1.94/linux/drivers/scsi/scsi.h	Thu Mar 26 15:57:03 1998
+++ linux/drivers/scsi/scsi.h	Fri Apr 10 10:47:30 1998
@@ -686,7 +686,6 @@
 #define INIT_SCSI_REQUEST       \
     if (!CURRENT) {             \
 	CLEAR_INTR;             \
-	spin_unlock_irqrestore(&io_request_lock,flags);	\
 	return;                 \
     }                           \
     if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)           \
diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.1.94/linux/drivers/scsi/sd.c	Tue Mar 17 22:18:14 1998
+++ linux/drivers/scsi/sd.c	Thu Apr  9 22:19:46 1998
@@ -36,6 +36,9 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 
+#include <linux/smp.h>
+#include <asm/smp_lock.h>
+
 #include <asm/system.h>
 #include <asm/io.h>
 
@@ -513,14 +516,10 @@
     Scsi_Cmnd * SCpnt = NULL;
     Scsi_Device * SDev;
     struct request * req = NULL;
-    unsigned long flags;
     int flag = 0;
 
     while (1==1){
-	spin_lock_irqsave(&io_request_lock, flags);
-
 	if (CURRENT != NULL && CURRENT->rq_status == RQ_INACTIVE) {
-            spin_unlock_irqrestore(&io_request_lock, flags);
 	    return;
 	}
 
@@ -535,7 +534,6 @@
          */
         if( SDev->host->in_recovery )
           {
-            spin_unlock_irqrestore(&io_request_lock, flags);
             return;
           }
 
@@ -555,10 +553,11 @@
 	     */
 	    if( SDev->removable && !in_interrupt() )
 	    {
-                spin_unlock_irqrestore(&io_request_lock, flags);
+                spin_unlock_irq(&io_request_lock);	/* FIXME!!!! */
                 scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0);
 		/* scsi_ioctl may allow CURRENT to change, so start over. */
 		SDev->was_reset = 0;
+                spin_lock_irq(&io_request_lock);	/* FIXME!!!! */
 		continue;
 	    }
 	    SDev->was_reset = 0;
@@ -587,7 +586,6 @@
 	 * Using a "sti()" gets rid of the latency problems but causes
 	 * race conditions and crashes.
 	 */
-        spin_unlock_irqrestore(&io_request_lock, flags);
 
 	/* This is a performance enhancement. We dig down into the request
 	 * list and try to find a queueable request (i.e. device not busy,
@@ -605,7 +603,6 @@
 	if (!SCpnt && sd_template.nr_dev > 1){
 	    struct request *req1;
 	    req1 = NULL;
-	    spin_lock_irqsave(&io_request_lock, flags);
 	    req = CURRENT;
 	    while(req){
 		SCpnt = scsi_request_queueable(req,
@@ -620,7 +617,6 @@
 		else
 		    req1->next = req->next;
 	    }
-            spin_unlock_irqrestore(&io_request_lock, flags);
 	}
 
 	if (!SCpnt) return; /* Could not find anything to do */
@@ -1125,6 +1121,8 @@
         return i;
     }
 
+    spin_lock_irq(&io_request_lock);
+
     /* We need to retry the READ_CAPACITY because a UNIT_ATTENTION is
      * considered a fatal error, and many devices report such an error
      * just after a scsi bus reset.
@@ -1157,7 +1155,9 @@
 				 (void *) cmd, (void *) buffer,
 				 512, sd_init_done,  SD_TIMEOUT,
 				 MAX_RETRIES);
+		    spin_unlock_irq(&io_request_lock);
 		    down(&sem);
+		    spin_lock_irq(&io_request_lock);
                     SCpnt->request.sem = NULL;
 		}
 
@@ -1193,7 +1193,9 @@
 				     (void *) cmd, (void *) buffer,
 				     512, sd_init_done,  SD_TIMEOUT,
 				     MAX_RETRIES);
+			spin_unlock_irq(&io_request_lock);
 			down(&sem);
+			spin_lock_irq(&io_request_lock);
                         SCpnt->request.sem = NULL;
 		    }
 
@@ -1201,8 +1203,10 @@
 		}
 
 		time1 = jiffies + HZ;
+		spin_unlock_irq(&io_request_lock);
 		while(jiffies < time1); /* Wait 1 second for next try */
 		printk( "." );
+		spin_lock_irq(&io_request_lock);
 	    }
 	} while(the_result && spintime && spintime+100*HZ > jiffies);
 	if (spintime) {
@@ -1231,7 +1235,9 @@
 			 (void *) cmd, (void *) buffer,
 			 8, sd_init_done,  SD_TIMEOUT,
 			 MAX_RETRIES);
+	    spin_unlock_irq(&io_request_lock);
 	    down(&sem);	/* sleep until it is ready */
+	    spin_lock_irq(&io_request_lock);
             SCpnt->request.sem = NULL;
 	}
 
@@ -1406,7 +1412,9 @@
 			 (void *) cmd, (void *) buffer,
 			 512, sd_init_done,  SD_TIMEOUT,
 			 MAX_RETRIES);
+	    spin_unlock_irq(&io_request_lock);
 	    down(&sem);
+	    spin_lock_irq(&io_request_lock);
             SCpnt->request.sem = NULL;
 	}
 
@@ -1431,6 +1439,7 @@
     rscsi_disks[i].ten = 1;
     rscsi_disks[i].remap = 1;
     scsi_free(buffer, 512);
+    spin_unlock_irq(&io_request_lock);
     return i;
 }
 
@@ -1590,7 +1599,6 @@
 int revalidate_scsidisk(kdev_t dev, int maxusage){
     int target;
     struct gendisk * gdev;
-    unsigned long flags;
     int max_p;
     int start;
     int i;
@@ -1598,14 +1606,11 @@
     target =  DEVICE_NR(dev);
     gdev = &GENDISK_STRUCT;
 
-    spin_lock_irqsave(&io_request_lock, flags);
     if (DEVICE_BUSY || USAGE > maxusage) {
-	spin_unlock_irqrestore(&io_request_lock, flags);
 	printk("Device busy for revalidation (usage=%d)\n", USAGE);
 	return -EBUSY;
     }
     DEVICE_BUSY = 1;
-    spin_unlock_irqrestore(&io_request_lock, flags);
 
     max_p = gdev->max_p;
     start = target << gdev->minor_shift;
diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- v2.1.94/linux/drivers/scsi/sg.c	Wed Apr  1 20:11:53 1998
+++ linux/drivers/scsi/sg.c	Thu Apr  9 22:11:00 1998
@@ -250,23 +250,22 @@
     /*
      * Wait until the command is actually done.
      */
-    save_flags(flags);
-    cli();
+    spin_lock_irqsave(&io_request_lock, flags);
     while(!device->pending || !device->complete)
     {
 	if (filp->f_flags & O_NONBLOCK)
 	{
-	    restore_flags(flags);
+	    spin_unlock_irqrestore(&io_request_lock, flags);
 	    return -EAGAIN;
 	}
 	interruptible_sleep_on(&device->read_wait);
 	if (signal_pending(current))
 	{
-	    restore_flags(flags);
+	    spin_unlock_irqrestore(&io_request_lock, flags);
 	    return -ERESTARTSYS;
 	}
     }
-    restore_flags(flags);
+    spin_unlock_irqrestore(&io_request_lock, flags);
 
     /*
      * Now copy the result back to the user buffer.
diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- v2.1.94/linux/drivers/scsi/sr.c	Tue Mar 10 10:03:33 1998
+++ linux/drivers/scsi/sr.c	Thu Apr  9 13:43:52 1998
@@ -431,10 +431,7 @@
     int flag = 0;
 
     while (1==1){
-    	spin_lock_irqsave(&io_request_lock, flags);
-
 	if (CURRENT != NULL && CURRENT->rq_status == RQ_INACTIVE) {
-	    spin_unlock_irqrestore(&io_request_lock, flags);
 	    return;
 	};
 
@@ -450,7 +447,6 @@
          */
         if( SDev->host->in_recovery )
           {
-	    spin_unlock_irqrestore(&io_request_lock, flags);
             return;
           }
 
@@ -469,8 +465,9 @@
  	     */
  	    if( SDev->removable && !in_interrupt() )
  	    {
-		spin_unlock_irqrestore(&io_request_lock, flags);
+		spin_unlock_irq(&io_request_lock);		/* FIXME!!!! */
 		scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0);
+		spin_lock_irq(&io_request_lock);		/* FIXME!!!! */
 		/* scsi_ioctl may allow CURRENT to change, so start over. */
 		SDev->was_reset = 0;
 		continue;
@@ -493,7 +490,6 @@
 	    SCpnt = scsi_allocate_device(&CURRENT,
 				    scsi_CDs[DEVICE_NR(CURRENT->rq_dev)].device, 0);
 	else SCpnt = NULL;
-	spin_unlock_irqrestore(&io_request_lock, flags);
 
 	/* This is a performance enhancement.  We dig down into the request list and
 	 * try to find a queueable request (i.e. device not busy, and host able to
@@ -505,7 +501,6 @@
 	if (!SCpnt && sr_template.nr_dev > 1){
 	    struct request *req1;
 	    req1 = NULL;
-	    spin_lock_irqsave(&io_request_lock, flags);
 	    req = CURRENT;
 	    while(req){
 		SCpnt = scsi_request_queueable(req,
@@ -520,7 +515,6 @@
 		else
 		    req1->next = req->next;
 	    }
-	    spin_unlock_irqrestore(&io_request_lock, flags);
 	}
 
 	if (!SCpnt)
diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c
--- v2.1.94/linux/drivers/scsi/u14-34f.c	Mon Apr  6 17:41:00 1998
+++ linux/drivers/scsi/u14-34f.c	Fri Apr 10 10:13:58 1998
@@ -1,6 +1,13 @@
 /*
  *      u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
  *
+ *      10 Apr 1998 rev. 4.04 for linux 2.0.33 and 2.1.95
+ *          Improved SMP support (if linux version >= 2.1.95).
+ *
+ *       9 Apr 1998 rev. 4.03 for linux 2.0.33 and 2.1.94
+ *          Performance improvement: when sequential i/o is detected,
+ *          always use direct sort instead of reverse sort.
+ *   
  *       4 Apr 1998 rev. 4.02 for linux 2.0.33 and 2.1.92
  *          io_port is now unsigned long.
  *
@@ -266,11 +273,14 @@
  *  the driver sets host->wish_block = TRUE for all ISA boards.
  */
 
+#include <linux/version.h>
+
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
 #define MAX_INT_PARAM 10
+
 #if defined(MODULE)
 #include <linux/module.h>
-#include <linux/version.h>
+
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,26)
 MODULE_PARM(io_port, "1-" __MODULE_STRING(MAX_INT_PARAM) "i");
 MODULE_PARM(linked_comm, "i");
@@ -279,6 +289,7 @@
 MODULE_PARM(max_queue_depth, "i");
 MODULE_AUTHOR("Dario Ballabio");
 #endif
+
 #endif
 
 #include <linux/string.h>
@@ -483,7 +494,7 @@
 #define V2DEV(addr) ((addr) ? H2DEV(virt_to_bus((void *)addr)) : 0)
 #define DEV2V(addr) ((addr) ? DEV2H(bus_to_virt((unsigned long)addr)) : 0)
 
-static void u14_34f_interrupt_handler(int, void *, struct pt_regs *);
+static void interrupt_handler(int, void *, struct pt_regs *);
 static void flush_dev(Scsi_Device *, unsigned long, unsigned int, unsigned int);
 static int do_trace = FALSE;
 static int setup_done = FALSE;
@@ -683,7 +694,7 @@
    subversion = (in_byte & 0x0f);
 
    /* Board detected, allocate its IRQ */
-   if (request_irq(irq, u14_34f_interrupt_handler,
+   if (request_irq(irq, interrupt_handler,
              SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0),
              driver_name, (void *) &sha[j])) {
       printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
@@ -1309,6 +1320,7 @@
    unsigned int input_only = TRUE, overlap = FALSE;
    unsigned long sl[n_ready], pl[n_ready], ll[n_ready];
    unsigned long maxsec = 0, minsec = ULONG_MAX, seek = 0, iseek = 0;
+   unsigned long ioseek = 0;
 
    static unsigned int flushcount = 0, batchcount = 0, sortcount = 0;
    static unsigned int readycount = 0, ovlcount = 0, inputcount = 0;
@@ -1333,6 +1345,7 @@
       if (SCpnt->request.sector > maxsec) maxsec = SCpnt->request.sector;
 
       sl[n] = SCpnt->request.sector;
+      ioseek += SCpnt->request.nr_sectors;
 
       if (!n) continue;
 
@@ -1354,6 +1367,8 @@
 
    if (cursec > ((maxsec + minsec) / 2)) rev = TRUE;
 
+   if (ioseek > ((maxsec - minsec) / 2)) rev = FALSE;
+
    if (!((rev && r) || (!rev && s))) sort(sl, il, n_ready, rev);
 
    if (!input_only) for (n = 0; n < n_ready; n++) {
@@ -1431,8 +1446,7 @@
       }
 }
 
-static void u14_34f_interrupt_handler(int irq, void *shap,
-                                               struct pt_regs *regs) {
+static inline void ihdlr(int irq, void *shap, struct pt_regs *regs) {
    Scsi_Cmnd *SCpnt;
    unsigned int i, j, k, c, status, tstatus, reg, ret;
    struct mscp *spp;
@@ -1479,7 +1493,8 @@
    else if (HD(j)->cp_stat[i] == IN_RESET)
       printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
    else if (HD(j)->cp_stat[i] != IN_USE) 
-      panic("%s: ihdlr, mbox %d, invalid cp_stat.\n", BN(j), i);
+      panic("%s: ihdlr, mbox %d, invalid cp_stat: %d.\n", 
+            BN(j), i, HD(j)->cp_stat[i]);
 
    HD(j)->cp_stat[i] = FREE;
    SCpnt = spp->SCpnt;
@@ -1608,6 +1623,22 @@
                         HD(j)->iocount);
 
    return;
+}
+
+static void interrupt_handler(int irq, void *shap, struct pt_regs *regs) {
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,95)
+
+   unsigned long flags;
+   spin_lock_irqsave(&io_request_lock, flags);
+   ihdlr(irq, shap, regs);
+   spin_unlock_irqrestore(&io_request_lock, flags);
+
+#else
+
+   ihdlr(irq, shap, regs);
+
+#endif
 }
 
 int u14_34f_release(struct Scsi_Host *shpnt) {
diff -u --recursive --new-file v2.1.94/linux/drivers/scsi/u14-34f.h linux/drivers/scsi/u14-34f.h
--- v2.1.94/linux/drivers/scsi/u14-34f.h	Mon Apr  6 17:41:00 1998
+++ linux/drivers/scsi/u14-34f.h	Fri Apr 10 10:47:30 1998
@@ -4,6 +4,8 @@
 #ifndef _U14_34F_H
 #define _U14_34F_H
 
+#include <linux/version.h>
+
 int u14_34f_detect(Scsi_Host_Template *);
 int u14_34f_release(struct Scsi_Host *);
 int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
@@ -11,7 +13,7 @@
 int u14_34f_reset(Scsi_Cmnd *, unsigned int);
 int u14_34f_biosparam(Disk *, kdev_t, int *);
 
-#define U14_34F_VERSION "4.02.00"
+#define U14_34F_VERSION "4.04.00"
 
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
 
diff -u --recursive --new-file v2.1.94/linux/fs/dcache.c linux/fs/dcache.c
--- v2.1.94/linux/fs/dcache.c	Mon Apr  6 17:41:00 1998
+++ linux/fs/dcache.c	Thu Apr  9 13:15:40 1998
@@ -784,7 +784,7 @@
 
 	error = -ENOENT;
 	/* Has the current directory has been unlinked? */
-	if (pwd->d_parent != pwd && list_empty(&pwd->d_hash)) {
+	if (pwd->d_parent == pwd || !list_empty(&pwd->d_hash)) {
 		char *page = (char *) __get_free_page(GFP_USER);
 		error = -ENOMEM;
 		if (page) {
diff -u --recursive --new-file v2.1.94/linux/fs/proc/root.c linux/fs/proc/root.c
--- v2.1.94/linux/fs/proc/root.c	Tue Mar 17 22:18:15 1998
+++ linux/fs/proc/root.c	Thu Apr  9 13:16:18 1998
@@ -499,13 +499,6 @@
 	S_IFREG | S_IRUGO, 1, 0, 0,
 	0, &proc_array_inode_operations
 };
-#ifdef CONFIG_PCI_OLD_PROC
-static struct proc_dir_entry proc_root_pci = {
-	PROC_PCI, 3, "pci",
-	S_IFREG | S_IRUGO, 1, 0, 0,
-	0, &proc_array_inode_operations
-};
-#endif
 #ifdef CONFIG_ZORRO
 static struct proc_dir_entry proc_root_zorro = {
 	PROC_ZORRO, 5, "zorro",
@@ -640,9 +633,6 @@
 	proc_register(&proc_root, &proc_root_meminfo);
 	proc_register(&proc_root, &proc_root_kmsg);
 	proc_register(&proc_root, &proc_root_version);
-#ifdef CONFIG_PCI_OLD_PROC
-	proc_register(&proc_root, &proc_root_pci);
-#endif
 #ifdef CONFIG_ZORRO
 	proc_register(&proc_root, &proc_root_zorro);
 #endif
@@ -707,9 +697,6 @@
 #endif
 
 	proc_bus = create_proc_entry("bus", S_IFDIR, 0);
-#ifdef CONFIG_PCI
-	proc_bus_pci_init();
-#endif
 }
 
 /*
diff -u --recursive --new-file v2.1.94/linux/include/asm-i386/system.h linux/include/asm-i386/system.h
--- v2.1.94/linux/include/asm-i386/system.h	Thu Feb 12 20:56:12 1998
+++ linux/include/asm-i386/system.h	Fri Apr 10 10:08:11 1998
@@ -215,7 +215,12 @@
 	return x;
 }
 
-#define mb()  __asm__ __volatile__ (""   : : :"memory")
+/*
+ * Force strict CPU ordering.
+ * And yes, this is required on UP too when we're talking
+ * to devices.
+ */
+#define mb() 	__asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
 
 /* interrupt control.. */
 #define __sti() __asm__ __volatile__ ("sti": : :"memory")
diff -u --recursive --new-file v2.1.94/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.1.94/linux/include/linux/pci.h	Wed Apr  8 19:36:29 1998
+++ linux/include/linux/pci.h	Thu Apr  9 13:16:18 1998
@@ -977,9 +977,6 @@
 
 #ifdef __KERNEL__
 
-/* Create an index into the pci_dev base_address[] array from an offset.  */
-#define PCI_BASE_INDEX(o) (((o)-PCI_BASE_ADDRESS_0)>>2)
-
 /*
  * Error values that may be returned by the PCI bios.  Use
  * pcibios_strerror() to convert to a printable string.
@@ -1078,6 +1075,8 @@
 void pci_setup(char *str, int *ints);
 void pci_quirks_init(void);
 unsigned int pci_scan_bus(struct pci_bus *bus);
+void proc_bus_pci_init(void);
+void proc_old_pci_init(void);
 
 struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, struct pci_dev *from);
 struct pci_dev *pci_find_class (unsigned int class, struct pci_dev *from);
diff -u --recursive --new-file v2.1.94/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- v2.1.94/linux/include/linux/proc_fs.h	Mon Apr  6 17:41:01 1998
+++ linux/include/linux/proc_fs.h	Fri Apr 10 10:46:47 1998
@@ -275,7 +275,6 @@
 
 extern void proc_root_init(void);
 extern void proc_base_init(void);
-extern void proc_bus_pci_init(void);
 
 extern int proc_register(struct proc_dir_entry *, struct proc_dir_entry *);
 extern int proc_unregister(struct proc_dir_entry *, int);
