diff -u --recursive --new-file v1.2.5/linux/CREDITS linux/CREDITS
--- v1.2.5/linux/CREDITS	Wed Mar 29 06:52:56 1995
+++ linux/CREDITS	Sun Apr 16 08:12:01 1995
@@ -683,6 +683,10 @@
 D: CDROM driver "sonycd535" (Sony CDU-535/531)
 S: 
 
+N: Frederic Potter 
+E: Frederic.Potter@masi.ibp.fr 
+D: Some PCI kernel support
+
 N: Stefan Probst
 E: snprobst@immd4.informatik.uni-erlangen.de
 D: The Linux Support Team Erlangen
diff -u --recursive --new-file v1.2.5/linux/Makefile linux/Makefile
--- v1.2.5/linux/Makefile	Fri Apr 14 12:02:41 1995
+++ linux/Makefile	Fri Apr 14 12:05:10 1995
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 2
-SUBLEVEL = 5
+SUBLEVEL = 6
 
 ARCH = i386
 
diff -u --recursive --new-file v1.2.5/linux/arch/i386/config.in linux/arch/i386/config.in
--- v1.2.5/linux/arch/i386/config.in	Wed Feb 15 10:50:55 1995
+++ linux/arch/i386/config.in	Mon Apr 17 13:47:56 1995
@@ -74,6 +74,10 @@
 bool 'Scsi CDROM support' CONFIG_BLK_DEV_SR n
 bool 'Scsi generic support' CONFIG_CHR_DEV_SG n
 
+comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
+
+bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN n
+
 comment 'SCSI low-level drivers'
 
 bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n
diff -u --recursive --new-file v1.2.5/linux/drivers/char/ChangeLog linux/drivers/char/ChangeLog
--- v1.2.5/linux/drivers/char/ChangeLog	Fri Apr 14 12:02:41 1995
+++ linux/drivers/char/ChangeLog	Fri Apr 14 12:01:41 1995
@@ -4,7 +4,7 @@
 		rs_init):  Hangups are now scheduled via a separate tqueue
 		structure in the async_struct structure, tqueue_hangup.
 		This task is pushed on to the tq_schedule queue, so that
-		it is processed syncronously by the scheduler.
+		it is processed synchronously by the scheduler.
 
 Sat Feb 18 12:13:51 1995  Theodore Y. Ts'o  (tytso@rt-11)
 
diff -u --recursive --new-file v1.2.5/linux/drivers/char/serial.c linux/drivers/char/serial.c
--- v1.2.5/linux/drivers/char/serial.c	Fri Apr 14 12:02:41 1995
+++ linux/drivers/char/serial.c	Fri Apr 14 12:01:40 1995
@@ -733,7 +733,7 @@
 
 /*
  * This routine is called from the scheduler tqueue when the interrupt
- * routine has signalled that a hangup has occured.  The path of
+ * routine has signalled that a hangup has occurred.  The path of
  * hangup processing is:
  *
  * 	serial interrupt routine -> (scheduler tqueue) ->
diff -u --recursive --new-file v1.2.5/linux/drivers/net/lance.c linux/drivers/net/lance.c
--- v1.2.5/linux/drivers/net/lance.c	Fri Apr 14 12:02:41 1995
+++ linux/drivers/net/lance.c	Fri Apr 14 12:01:40 1995
@@ -15,7 +15,7 @@
 	   Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
 */
 
-static char *version = "lance.c:v1.07 1/18/95 becker@cesdis.gsfc.nasa.gov\n";
+static char *version = "lance.c:v1.08 4/10/95 dplatt@3do.com\n";
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -203,12 +203,18 @@
 	int dirty_rx, dirty_tx;		/* The ring entries to be free()ed. */
 	int dma;
 	struct enet_statistics stats;
-	char chip_version;			/* See lance_chip_type. */
+	unsigned char chip_version;			/* See lance_chip_type. */
 	char tx_full;
 	char lock;
 	int pad0, pad1;				/* Used for 8-byte alignment */
 };
 
+#define LANCE_MUST_PAD          0x00000001
+#define LANCE_ENABLE_AUTOSELECT 0x00000002
+#define LANCE_MUST_REINIT_RING  0x00000004
+#define LANCE_MUST_UNRESET      0x00000008
+#define LANCE_HAS_MISSED_FRAME  0x00000010
+
 /* A mapping from the chip ID number to the part number and features.
    These are from the datasheets -- in real life the '970 version
    reportedly has the same ID as the '965. */
@@ -217,14 +223,25 @@
 	char *name;
 	int flags;
 } chip_table[] = {
-	{0x0000, "LANCE 7990", 0},			/* Ancient lance chip.  */
-	{0x0003, "PCnet/ISA 79C960", 0},	/* 79C960 PCnet/ISA.  */
-	{0x2260, "PCnet/ISA+ 79C961", 0},	/* 79C961 PCnet/ISA+, Plug-n-Play.  */
-	{0x2420, "PCnet/PCI 79C970", 0},	/* 79C970 or 79C974 PCnet-SCSI, PCI. */
+	{0x0000, "LANCE 7990",				/* Ancient lance chip.  */
+		LANCE_MUST_PAD + LANCE_MUST_UNRESET},
+	{0x0003, "PCnet/ISA 79C960",		/* 79C960 PCnet/ISA.  */
+		LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
+			LANCE_HAS_MISSED_FRAME},
+	{0x2260, "PCnet/ISA+ 79C961",		/* 79C961 PCnet/ISA+, Plug-n-Play.  */
+		LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
+			LANCE_HAS_MISSED_FRAME},
+	{0x2420, "PCnet/PCI 79C970",		/* 79C970 or 79C974 PCnet-SCSI, PCI. */
+		LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
+			LANCE_HAS_MISSED_FRAME},
 	/* Bug: the PCnet/PCI actually uses the PCnet/VLB ID number, so just call
 		it the PCnet32. */
-	{0x2430, "PCnet32", 0},				/* 79C965 PCnet for VL bus. */
-	{0x0, 	 "PCnet (unknown)", 0},
+	{0x2430, "PCnet32",					/* 79C965 PCnet for VL bus. */
+		LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
+			LANCE_HAS_MISSED_FRAME},
+	{0x0, 	 "PCnet (unknown)",
+		LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
+			LANCE_HAS_MISSED_FRAME},
 };
 
 enum {OLD_LANCE = 0, PCNET_ISA=1, PCNET_ISAP=2, PCNET_PCI=3, PCNET_VLB=4, LANCE_UNKNOWN=5};
@@ -256,8 +273,6 @@
 	int *port;
 
 #if defined(CONFIG_PCI)
-#define AMD_VENDOR_ID 0x1022
-#define AMD_DEVICE_ID 0x2000
     if (pcibios_present()) {
 	    int pci_index;
 		printk("lance.c: PCI bios is present, checking for devices...\n");
@@ -266,7 +281,8 @@
 			unsigned long pci_ioaddr;
 			unsigned short pci_command;
 
-			if (pcibios_find_device (AMD_VENDOR_ID, AMD_DEVICE_ID, pci_index,
+			if (pcibios_find_device (PCI_VENDOR_ID_AMD,
+									 PCI_DEVICE_ID_AMD_LANCE, pci_index,
 									 &pci_bus, &pci_device_fn) != 0)
 				break;
 			pcibios_read_config_byte(pci_bus, pci_device_fn,
@@ -522,7 +538,7 @@
 		}
 	}
 
-	if (lp->chip_version !=  OLD_LANCE) {
+	if (chip_table[lp->chip_version].flags & LANCE_ENABLE_AUTOSELECT) {
 		/* Turn on auto-select of media (10baseT or BNC) so that the user
 		   can watch the LEDs even if the board isn't opened. */
 		outw(0x0002, ioaddr+LANCE_ADDR);
@@ -570,10 +586,10 @@
 	}
 
 	/* Un-Reset the LANCE, needed only for the NE2100. */
-	if (lp->chip_version == OLD_LANCE)
+	if (chip_table[lp->chip_version].flags & LANCE_MUST_UNRESET)
 		outw(0, ioaddr+LANCE_RESET);
 
-	if (lp->chip_version != OLD_LANCE) {
+	if (chip_table[lp->chip_version].flags & LANCE_ENABLE_AUTOSELECT) {
 		/* This is 79C960-specific: Turn on auto-select of media (AUI, BNC). */
 		outw(0x0002, ioaddr+LANCE_ADDR);
 		outw(0x0002, ioaddr+LANCE_BUS_IF);
@@ -617,6 +633,33 @@
 	return 0;					/* Always succeed */
 }
 
+/* The LANCE has been halted for one reason or another (busmaster memory
+   arbitration error, Tx FIFO underflow, driver stopped it to reconfigure,
+   etc.).  Modern LANCE variants always reload their ring-buffer
+   configuration when restarted, so we must reinitialize our ring
+   context before restarting.  As part of this reinitialization,
+   find all packets still on the Tx ring and pretend that they had been
+   sent (in effect, drop the packets on the floor) - the higher-level
+   protocols will time out and retransmit.  It'd be better to shuffle
+   these skbs to a temp list and then actually re-Tx them after
+   restarting the chip, but I'm too lazy to do so right now.  dplatt@3do.com
+*/
+
+static void 
+lance_purge_tx_ring(struct device *dev)
+{
+	struct lance_private *lp = (struct lance_private *)dev->priv;
+	int i;
+
+	for (i = 0; i < TX_RING_SIZE; i++) {
+		if (lp->tx_skbuff[i]) {
+			dev_kfree_skb(lp->tx_skbuff[i],FREE_WRITE);
+			lp->tx_skbuff[i] = NULL;
+		}
+	}
+}
+
+
 /* Initialize the LANCE Rx and Tx rings. */
 static void
 lance_init_ring(struct device *dev)
@@ -647,12 +690,27 @@
 	lp->init_block.tx_ring = (int)lp->tx_ring | TX_RING_LEN_BITS;
 }
 
+static void
+lance_restart(struct device *dev, unsigned int csr0_bits, int must_reinit)
+{
+	struct lance_private *lp = (struct lance_private *)dev->priv;
+
+	if (must_reinit ||
+		(chip_table[lp->chip_version].flags & LANCE_MUST_REINIT_RING)) {
+		lance_purge_tx_ring(dev);
+		lance_init_ring(dev);
+	}
+	outw(0x0000,    dev->base_addr + LANCE_ADDR);
+	outw(csr0_bits, dev->base_addr + LANCE_DATA);
+}
+
 static int
 lance_start_xmit(struct sk_buff *skb, struct device *dev)
 {
 	struct lance_private *lp = (struct lance_private *)dev->priv;
 	int ioaddr = dev->base_addr;
 	int entry;
+	unsigned long flags;
 
 	/* Transmitter timeout, serious problems. */
 	if (dev->tbusy) {
@@ -681,8 +739,7 @@
 			printk("\n");
 		}
 #endif
-		lance_init_ring(dev);
-		outw(0x0043, ioaddr+LANCE_DATA);
+		lance_restart(dev, 0x0043, 1);
 
 		dev->tbusy=0;
 		dev->trans_start = jiffies;
@@ -728,7 +785,7 @@
 	   with the "ownership" bits last. */
 
 	/* The old LANCE chips doesn't automatically pad buffers to min. size. */
-	if (lp->chip_version == OLD_LANCE) {
+	if (chip_table[lp->chip_version].flags & LANCE_MUST_PAD) {
 		lp->tx_ring[entry].length =
 			-(ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN);
 	} else
@@ -758,13 +815,14 @@
 
 	dev->trans_start = jiffies;
 
+	save_flags(flags);
 	cli();
 	lp->lock = 0;
 	if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base == 0)
 		dev->tbusy=0;
 	else
 		lp->tx_full = 1;
-	sti();
+	restore_flags(flags);
 
 	return 0;
 }
@@ -776,6 +834,7 @@
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	struct lance_private *lp;
 	int csr0, ioaddr, boguscnt=10;
+	int must_restart;
 
 	if (dev == NULL) {
 		printk ("lance_interrupt(): irq %d for unknown device.\n", irq);
@@ -795,6 +854,8 @@
 		/* Acknowledge all of the current interrupt sources ASAP. */
 		outw(csr0 & ~0x004f, dev->base_addr + LANCE_DATA);
 
+		must_restart = 0;
+
 		if (lance_debug > 5)
 			printk("%s: interrupt  csr0=%#2.2x new csr=%#2.2x.\n",
 				   dev->name, csr0, inw(dev->base_addr + LANCE_DATA));
@@ -828,7 +889,7 @@
 						printk("%s: Tx FIFO error! Status %4.4x.\n",
 							   dev->name, csr0);
 						/* Restart the chip. */
-						outw(0x0002, dev->base_addr + LANCE_DATA);
+						must_restart = 1;
 					}
 				} else {
 					if (status & 0x18000000)
@@ -871,7 +932,14 @@
 			printk("%s: Bus master arbitration failure, status %4.4x.\n",
 				   dev->name, csr0);
 			/* Restart the chip. */
-			outw(0x0002, dev->base_addr + LANCE_DATA);
+			must_restart = 1;
+		}
+
+		if (must_restart) {
+			/* stop the chip to clear the error condition, then restart */
+			outw(0x0000, dev->base_addr + LANCE_ADDR);
+			outw(0x0004, dev->base_addr + LANCE_DATA);
+			lance_restart(dev, 0x0002, 0);
 		}
 	}
 
@@ -961,7 +1029,7 @@
 	dev->start = 0;
 	dev->tbusy = 1;
 
-	if (lp->chip_version != OLD_LANCE) {
+	if (chip_table[lp->chip_version].flags & LANCE_HAS_MISSED_FRAME) {
 		outw(112, ioaddr+LANCE_ADDR);
 		lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
 	}
@@ -991,14 +1059,16 @@
 	struct lance_private *lp = (struct lance_private *)dev->priv;
 	short ioaddr = dev->base_addr;
 	short saved_addr;
+	unsigned long flags;
 
-	if (lp->chip_version != OLD_LANCE) {
+	if (chip_table[lp->chip_version].flags & LANCE_HAS_MISSED_FRAME) {
+		save_flags(flags);
 		cli();
 		saved_addr = inw(ioaddr+LANCE_ADDR);
 		outw(112, ioaddr+LANCE_ADDR);
 		lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
 		outw(saved_addr, ioaddr+LANCE_ADDR);
-		sti();
+		restore_flags(flags);
 	}
 
 	return &lp->stats;
@@ -1015,11 +1085,9 @@
 {
 	short ioaddr = dev->base_addr;
 
-	/* We take the simple way out and always enable promiscuous mode. */
 	outw(0, ioaddr+LANCE_ADDR);
 	outw(0x0004, ioaddr+LANCE_DATA); /* Temporarily stop the lance.	 */
 
-	outw(15, ioaddr+LANCE_ADDR);
 	if (num_addrs >= 0) {
 		short multicast_table[4];
 		int i;
@@ -1029,15 +1097,17 @@
 			outw(8 + i, ioaddr+LANCE_ADDR);
 			outw(multicast_table[i], ioaddr+LANCE_DATA);
 		}
+		outw(15, ioaddr+LANCE_ADDR);
 		outw(0x0000, ioaddr+LANCE_DATA); /* Unset promiscuous mode */
 	} else {
 		/* Log any net taps. */
 		printk("%s: Promiscuous mode enabled.\n", dev->name);
+		outw(15, ioaddr+LANCE_ADDR);
 		outw(0x8000, ioaddr+LANCE_DATA); /* Set promiscuous mode */
 	}
 
-	outw(0, ioaddr+LANCE_ADDR);
-	outw(0x0142, ioaddr+LANCE_DATA); /* Resume normal operation. */
+	lance_restart(dev, 0x0142, 0); /*  Resume normal operation */
+
 }
 
 
diff -u --recursive --new-file v1.2.5/linux/drivers/net/ne.c linux/drivers/net/ne.c
--- v1.2.5/linux/drivers/net/ne.c	Fri Apr 14 12:02:41 1995
+++ linux/drivers/net/ne.c	Thu Apr 20 11:24:55 1995
@@ -376,7 +376,6 @@
 {
     int retries = 0;
     int nic_base = NE_BASE;
-    unsigned long flags;
 
     /* Round the count up for word writes.  Do we need to do this?
        What effect will an odd byte count have on the 8390?
@@ -412,19 +411,7 @@
     SLOW_DOWN_IO;
 #endif  /* rw_bugfix */
 
-   /*
-    	Now the normal output. I believe that if we don't lock this, a
-	race condition will munge the remote byte count values, and then
-	the ne2k will hang the machine by holding I/O CH RDY because it
-	expects more data. Hopefully fixes the lockups. -- Paul Gortmaker.
-
-	Use save_flags/cli/restore_flags rather than cli/sti to avoid risk
-	of accidentally enabling interrupts which were disabled when we
-	were entered.   Dave Platt <dplatt@3do.com>
-    */
-
-    save_flags(flags);
-    cli();
+   /* Now the normal output. */
     outb_p(count & 0xff, nic_base + EN0_RCNTLO);
     outb_p(count >> 8,   nic_base + EN0_RCNTHI);
     outb_p(0x00, nic_base + EN0_RSARLO);
@@ -436,7 +423,6 @@
     } else {
 	outsb(NE_BASE + NE_DATAPORT, buf, count);
     }
-    restore_flags(flags);
 
 #ifdef CONFIG_NE_SANITY
     /* This was for the ALPHA version only, but enough people have
diff -u --recursive --new-file v1.2.5/linux/drivers/net/plip.c linux/drivers/net/plip.c
--- v1.2.5/linux/drivers/net/plip.c	Mon Feb 20 08:59:52 1995
+++ linux/drivers/net/plip.c	Mon Apr 17 13:47:56 1995
@@ -98,6 +98,7 @@
 #include <linux/ioport.h>
 #include <asm/bitops.h>
 #include <asm/irq.h>
+#include <asm/byteorder.h>
 
 /* Use 0 for production, 1 for verification, >2 for debug */
 #ifndef NET_DEBUG
@@ -165,26 +166,14 @@
 	enum plip_nibble_state nibble;
 	union {
 		struct {
-#if defined(__i386__)
+#if defined(LITTLE_ENDIAN)
 			unsigned char lsb;
 			unsigned char msb;
-#elif defined(__mc68000__)
+#elif defined(BIG_ENDIAN)
 			unsigned char msb;
 			unsigned char lsb;
-#elif defined(__sparc__)
-			unsigned char msb;
-			unsigned char lsb;
-#elif defined(__MIPSEL__)
-			unsigned char lsb;
-			unsigned char msb;
-#elif defined(__MIPSEB__)
-			unsigned char msb;
-			unsigned char lsb;
-#elif defined(__alpha__)
-			unsigned char lsb;
-			unsigned char msb;
 #else
-#error	"Adjust this structure to match your CPU"
+#error	"Please fix the endianness defines in <asm/byteorder.h>"
 #endif						
 		} b;
 		unsigned short h;
diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/53c7,8xx.c linux/drivers/scsi/53c7,8xx.c
--- v1.2.5/linux/drivers/scsi/53c7,8xx.c	Sun Feb 19 11:22:43 1995
+++ linux/drivers/scsi/53c7,8xx.c	Mon Apr 17 13:47:57 1995
@@ -5,8 +5,8 @@
  *	  weed out brain damaged main boards.
  */
 
-#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1)
 
+#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1)
 /*
  * Define SCSI_MALLOC to use scsi_malloc instead of kmalloc.  Other than
  * preventing deadlock, I'm not sure why we'd want to do this.
@@ -20,7 +20,7 @@
  *	Hannover, Germany
  *	hm@ix.de
  *
- * Copyright 1993, 1994 Drew Eckhardt
+ * Copyright 1993, 1994, 1995 Drew Eckhardt
  *      Visionary Computing 
  *      (Unix and Linux consulting and custom programming)
  *      drew@Colorado.EDU
@@ -28,8 +28,6 @@
  *
  * TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
  * 
- * PRE-ALPHA
- *
  * For more information, please consult 
  *
  *
@@ -156,6 +154,11 @@
  *
  */
 
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
+#include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <linux/delay.h>
@@ -176,7 +179,9 @@
 static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result);
 static int NCR53c8xx_run_tests (struct Scsi_Host *host);
 static int NCR53c8xx_script_len;
+static int NCR53c8xx_dsa_len;
 static void NCR53c7x0_intr(int irq, struct pt_regs * regs);
+static int halt (struct Scsi_Host *host);
 static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd 
     *cmd);
 static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
@@ -190,40 +195,11 @@
     NCR53c7x0_cmd *cmd);
 static void NCR53c8x0_soft_reset (struct Scsi_Host *host);
 
+static int perm_options = PERM_OPTIONS;
+
 static struct Scsi_Host *first_host = NULL;	/* Head of list of NCR boards */
 static Scsi_Host_Template *the_template = NULL;	
 
-/* Allocate storage space for constant messages, etc. */
-
-static long NCR53c7xx_zero = 0;			
-static long NCR53c7xx_sink;
-static char NCR53c7xx_msg_reject = MESSAGE_REJECT;
-static char NCR53c7xx_msg_abort = ABORT;
-static char NCR53c7xx_msg_nop = NOP;
-
-/* Buffer for commands run before *malloc() works */
-/* 
- * XXX - if need be, replace this with normal wait.
- */
-static int scan_scsis_buf_busy = 0;
-static char scan_scsis_buf[512];
-
-
-/*
- * Spl-levels are evil. We shouldn't emulate braindamage.
- *		Linus
- */
-static int splx (int new_level)
-{
-    register int old_level, tmp;
-    save_flags(tmp);
-    old_level = (tmp & 0x200) ? 7 : 0;
-    if (new_level)
-	sti();
-    else 
-	cli();
-    return old_level;
-}
 
 /*
  * TODO : 
@@ -285,8 +261,7 @@
  *
  * For the very similar chips, we should probably hack the fixup code
  * and interrupt code so that it works everywhere, but I suspect the 
- * NCR53c700 is going
- * to need it's own fixup routine.
+ * NCR53c700 is going to need it's own fixup routine.
  */
 
 /*
@@ -420,7 +395,8 @@
  * 	field of the hostdata structure MUST have been set.
  */
 
-static int NCR53c7x0_init (struct Scsi_Host *host) {
+static int 
+NCR53c7x0_init (struct Scsi_Host *host) {
     NCR53c7x0_local_declare();
     /* unsigned char tmp; */
     int i, j, ccf;
@@ -450,13 +426,19 @@
 	return -1;
     }
 
+    /* Assign constants accessed by NCR */
+    hostdata->NCR53c7xx_zero = 0;			
+    hostdata->NCR53c7xx_msg_reject = MESSAGE_REJECT;
+    hostdata->NCR53c7xx_msg_abort = ABORT;
+    hostdata->NCR53c7xx_msg_nop = NOP;
+
     /*
      * Set up an interrupt handler if we aren't already sharing an IRQ
      * with another board.
      */
 
-    for (search = first_host; search && (search->hostt == the_template) &&
-	(search->irq != host->irq); search=search->next);
+    for (search = first_host; search && ((search->hostt != the_template) ||
+	(search->irq != host->irq)); search=search->next);
 
     if (!search) {
 	if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx")) {
@@ -479,6 +461,10 @@
     hostdata->istat = ((hostdata->chip / 100) == 8) ? 
     	ISTAT_REG_800 : ISTAT_REG_700;
 
+/* Only the ISTAT register is readable when the NCR is running, so make 
+   sure it's halted. */
+    halt(host);
+
 /* 
  * XXX - the NCR53c700 uses bitfielded registers for SCID, SDID, etc,
  *	as does the 710 with one bit per SCSI ID.  Conversely, the NCR
@@ -523,9 +509,9 @@
     hostdata->saved_dcntl = NCR53c7x0_read8(DCNTL_REG);
     
     if ((hostdata->chip / 100) == 8)
-	printk ("scsi%d : using %s interrupts.\n", host->host_no,
-	    (hostdata->saved_dcntl & DCNTL_800_IRQM) ? "level active" : 
-	    "edge triggered");
+	printk ("scsi%d : using %s interrupts\n", host->host_no,
+	    (hostdata->saved_dcntl & DCNTL_800_IRQM) ? "edge triggered" :
+	    "level active");
 
     /*
      * DMODE controls DMA burst length, and on 700 series chips,
@@ -547,8 +533,9 @@
 	    case DMODE_BL_4: i = 4; break;
 	    case DMODE_BL_8: i = 8; break;
 	    case DMODE_BL_16: i = 16; break;
+            default: i = 0;
 	    }
-	    printk ("scsi%d ; burst length %d\n", host->host_no, i);
+	    printk ("scsi%d : burst length %d\n", host->host_no, i);
 	}
     }
 
@@ -592,6 +579,7 @@
      */
 
     for (i = 0; i < 8; ++i) {
+    	hostdata->cmd_allocated[i] = 0;
     	for (j = 0; j < 8; ++j)
 	    hostdata->busy[i][j] = 0;
 	/* 
@@ -620,8 +608,8 @@
 
     hostdata->issue_queue = hostdata->running_list = 
     	hostdata->finished_queue = NULL;
-    hostdata->issue_dsa_head = 
-	hostdata->issue_dsa_tail = NULL;
+    hostdata->issue_dsa_head = NULL;
+    hostdata->issue_dsa_tail = NULL;
 
     if (hostdata->init_save_regs)
     	hostdata->init_save_regs (host);
@@ -688,11 +676,11 @@
     struct Scsi_Host *instance;
     struct NCR53c7x0_hostdata *hostdata;
     char chip_str[80];
-    int script_len = 0, size = 0;
+    int script_len = 0, dsa_len = 0, size = 0, max_cmd_size = 0;
     int ok = 0;
 
     
-    options |= PERM_OPTIONS;
+    options |= perm_options;
 
     switch (chip) {
     case 825:
@@ -700,6 +688,7 @@
     case 815:
     case 810:
 	script_len = NCR53c8xx_script_len;
+    	dsa_len = NCR53c8xx_dsa_len;
     	options |= OPTION_INTFLY;
     	sprintf (chip_str, "NCR53c%d", chip);
     	break;
@@ -718,7 +707,7 @@
     if ((chip / 100 == 8) && !pci_valid) 
 	printk ("scsi-ncr53c7,8xx : for better reliability and performance, please use the\n" 
 		"        PCI override instead.\n"
-		"	 Syntax : ncr53c8{10,20,25}=pci,<bus>,<device>,<function>\n"
+		"	 Syntax : ncr53c8{10,15,20,25}=pci,<bus>,<device>,<function>\n"
 		"	          <bus> and <device> are usually 0.\n");
 
     if (options & OPTION_DEBUG_PROBE_ONLY) {
@@ -726,9 +715,50 @@
     	return -1;
     }
 
-    size = sizeof(struct NCR53c7x0_hostdata) + script_len;
+    max_cmd_size = sizeof(struct NCR53c7x0_cmd) + dsa_len +
+    	/* Size of dynamic part of command structure : */
+	2 * /* Worst case : we don't know if we need DATA IN or DATA out */
+		( 2 * /* Current instructions per scatter/gather segment */ 
+        	  tpnt->sg_tablesize + 
+                  3 /* Current startup / termination required per phase */
+		) *
+	8 /* Each instruction is eight bytes */;
+    /* Note that alignment will be guaranteed, since we put the command
+       allocated at probe time after the fixed-up SCSI script, which 
+       consists of 32 bit words, aligned on a 32 bit boundary. */ 
+
+    /* Allocate fixed part of hostdata, dynamic part to hold appropriate
+       SCSI SCRIPT(tm) plus a single, maximum-sized NCR53c7x0_cmd structure.
+
+       We need a NCR53c7x0_cmd structure for scan_scsis() when we are 
+       not loaded as a module, and when we're loaded as a module, we 
+       can't use a non-dynamically allocated structure because modules
+       are vmalloc()'d, which can allow structures to cross page 
+       boundaries and breaks our physical/virtual address assumptions
+       for DMA.
+
+       So, we stick it past the end of our hostdata structure.
+
+       ASSUMPTION : 
+       	 Irregardless of how many simultaenous SCSI commands we allow,
+         the probe code only executes a _single_ instruction at a time,
+	 so we only need one here, and don't need to allocate NCR53c7x0_cmd
+	 structures for each target until we are no longer in scan_scsis
+	 and kmalloc() has become functional (memory_init() happens 
+	 after all device driver initialization).
+    */
+
+    size = sizeof(struct NCR53c7x0_hostdata) + script_len + max_cmd_size;
 
     instance = scsi_register (tpnt, size);
+    if (!instance)
+	return -1;
+
+
+    /* FIXME : if we ever support an ISA NCR53c7xx based board, we
+       need to check if the chip is running in a 16 bit mode, and if so 
+       unregister it if it is past the 16M (0x1000000) mark */
+   	
     hostdata = (struct NCR53c7x0_hostdata *) 
     	instance->hostdata;
     hostdata->size = size;
@@ -784,7 +814,18 @@
     instance->dma_channel = dma;
 
     hostdata->options = options;
-    
+    hostdata->dsa_size = dsa_len;
+    hostdata->max_cmd_size = max_cmd_size;
+    hostdata->num_cmds = 1;
+    /* Initialize single command */
+    hostdata->free = (struct NCR53c7x0_cmd *) 
+	(hostdata->script + hostdata->script_count);
+    hostdata->free->real = (void *) hostdata->free;
+    hostdata->free->size = max_cmd_size;
+    hostdata->free->free = NULL;
+    hostdata->free->next = NULL;
+
+
     return NCR53c7x0_init(instance);
 }
 
@@ -796,7 +837,7 @@
  * Purpose : initializes a NCR53c800 family based on the PCI
  *	bus, device, and function location of it.  Allows 
  * 	reprogramming of latency timer and determining addresses
- *	and weather bus mastering, etc. are OK.
+ *	and whether bus mastering, etc. are OK.
  *	
  *	Useful where a new NCR chip is backwards compatible with
  *	a supported chip, but the DEVICE ID has changed so it 
@@ -815,7 +856,8 @@
     unsigned short vendor_id, device_id, command;
     unsigned long base, io_port; 
     unsigned char irq, revision;
-    int error, expected_chip, expected_id, max_revision, min_revision;
+    int error, expected_chip;
+    int expected_id = -1, max_revision = -1, min_revision = -1;
     int i;
 
     printk("scsi-ncr53c7,8xx : at PCI bus %d, device %d,  function %d\n",
@@ -870,6 +912,8 @@
 	    io_port = 0;
 	} else
 	    io_port &= PCI_BASE_ADDRESS_IO_MASK;
+    } else {
+    	io_port = 0;
     }
 
     if (command & PCI_COMMAND_MEMORY) {
@@ -879,6 +923,8 @@
 	    base = 0;
 	} else 
 	    base &= PCI_BASE_ADDRESS_MEM_MASK;
+    } else {
+    	base = 0;
     }
 	
     if (!io_port && !base) {
@@ -932,7 +978,6 @@
  */
 
 int NCR53c7xx_detect(Scsi_Host_Template *tpnt) {
-    short current_chip;
     int i;
     int current_override;
     int count;			/* Number of boards detected */
@@ -979,6 +1024,7 @@
 
 #include "53c8xx_d.h"
 static int NCR53c8xx_script_len = sizeof (SCRIPT);
+static int NCR53c8xx_dsa_len = A_dsa_end + Ent_dsa_zero - Ent_dsa_code_template;
 
 /* 
  * Function : static void NCR53c8x0_init_fixup (struct Scsi_Host *host)
@@ -989,7 +1035,8 @@
  *
  */
 
-static void NCR53c8x0_init_fixup (struct Scsi_Host *host) {
+static void 
+NCR53c8x0_init_fixup (struct Scsi_Host *host) {
     NCR53c7x0_local_declare();
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
 	host->hostdata;
@@ -1008,6 +1055,16 @@
     for (i = 0; i < PATCHES; ++i) 
 	hostdata->script[LABELPATCHES[i]] += 
     	    (unsigned long) hostdata->script;
+    /* Fixup addresses of constants that used to be EXTERNAL */
+    
+    patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_abort, 
+    	(long) &(hostdata->NCR53c7xx_msg_abort));
+    patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_reject, 
+    	(long) &(hostdata->NCR53c7xx_msg_reject));
+    patch_abs_32 (hostdata->script, 0, NCR53c7xx_zero, 
+    	(long) &(hostdata->NCR53c7xx_zero));
+    patch_abs_32 (hostdata->script, 0, NCR53c7xx_sink, 
+    	(long) &(hostdata->NCR53c7xx_sink));
 
     /* 
      * Fixup absolutes set at boot-time.
@@ -1037,10 +1094,6 @@
     	ncr_to_ncr = memory_to_ncr = ncr_to_memory = tmp;
     }
 
-    printk ("scsi%d : m_to_n = 0x%x, n_to_m = 0x%x, n_to_n = 0x%x\n",
-	    (int) host->host_no, (int) memory_to_ncr, (int) 
-	    ncr_to_memory, ncr_to_ncr);
-
     patch_abs_32 (hostdata->script, 0, addr_scratch, base + SCRATCHA_REG_800);
     patch_abs_32 (hostdata->script, 0, addr_sfbr, base + SFBR_REG);
     patch_abs_32 (hostdata->script, 0, addr_temp, base + TEMP_REG);
@@ -1059,11 +1112,15 @@
     patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_memory, ncr_to_memory);
     patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_ncr, ncr_to_ncr);
 
-    patch_abs_32 (hostdata->script, 0, issue_dsa_head, (long) &(hostdata->issue_dsa_head));
+    patch_abs_32 (hostdata->script, 0, issue_dsa_head, 
+    	(long) &(hostdata->issue_dsa_head));
     patch_abs_32 (hostdata->script, 0, msg_buf, (long) &(hostdata->msg_buf));
-    patch_abs_32 (hostdata->script, 0, reconnect_dsa_head, (long) &(hostdata->reconnect_dsa_head));
-    patch_abs_32 (hostdata->script, 0, reselected_identify, (long) &(hostdata->reselected_identify));
-    patch_abs_32 (hostdata->script, 0, reselected_tag, (long) &(hostdata->reselected_tag));
+    patch_abs_32 (hostdata->script, 0, reconnect_dsa_head, 
+    	(long) &(hostdata->reconnect_dsa_head));
+    patch_abs_32 (hostdata->script, 0, reselected_identify, 
+    	(long) &(hostdata->reselected_identify));
+    patch_abs_32 (hostdata->script, 0, reselected_tag, 
+    	(long) &(hostdata->reselected_tag));
 
     patch_abs_32 (hostdata->script, 0, test_dest, (long) &(hostdata->test_dest));
     patch_abs_32 (hostdata->script, 0, test_src, (long) &(hostdata->test_source));
@@ -1145,17 +1202,18 @@
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
 	host->hostdata;
     unsigned long timeout, start;
-    int old_level, failed, i;
+    int failed, i;
+    unsigned long flags;
+	
     NCR53c7x0_local_setup(host);
 
-    printk("scsi%d : testing\n", host->host_no);
-
     /* The NCR chip _must_ be idle to run the test scripts */
 
-    old_level = splx(0);
+    save_flags(flags);
+    cli();
     if (!hostdata->idle) {
 	printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
-	splx(old_level);
+	restore_flags(flags);
 	return -1;
     }
 
@@ -1181,7 +1239,7 @@
 	printk ("scsi%d : test 1", host->host_no);
 	NCR53c7x0_write32 (DSP_REG, start);
 	printk (" started\n");
-	splx(7);
+	sti();
 
 	timeout = jiffies + 50;	/* arbitrary */
 	while ((hostdata->test_completed == -1) && jiffies < timeout);
@@ -1217,7 +1275,7 @@
 		(unsigned long) hostdata->script, start);
 	    printk ("scsi%d : DSPS = 0x%lx\n", host->host_no,
 		(unsigned long) NCR53c7x0_read32(DSPS_REG));
-	    splx(old_level);
+	    restore_flags(flags);
 	    return -1;
 	}
     	hostdata->test_running = 0;
@@ -1253,10 +1311,10 @@
     	dsa[11] = (unsigned long) &msg;
 
 	for (i = 0; i < 3; ++i) {
-	    splx(0);
+    	    cli();
 	    if (!hostdata->idle) {
 		printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
-		splx(old_level);
+		restore_flags(flags);
 		return -1;
 	    }
 
@@ -1269,7 +1327,7 @@
 	    hostdata->state = STATE_RUNNING;
 	    NCR53c7x0_write32 (DSA_REG, (unsigned long) dsa);
 	    NCR53c7x0_write32 (DSP_REG, start);
-	    splx(7);
+	    sti();
 
 	    timeout = jiffies + 500;	/* arbitrary */
 	    while ((hostdata->test_completed == -1) && jiffies < timeout);
@@ -1289,12 +1347,12 @@
 		    host->host_no, i);
 		if (!hostdata->idle) {
 		    printk("scsi%d : not idle\n", host->host_no);
-		    splx(old_level);
+		    restore_flags(flags);
 		    return -1;
 		}
 	    } else if (hostdata->test_completed == -1) {
 		printk ("scsi%d : test 2 timed out\n", host->host_no);
-		splx(old_level);
+		restore_flags(flags);
 		return -1;
 	    } 
 	    hostdata->test_running = 0;
@@ -1305,9 +1363,8 @@
 	}
 	}
     }
-    printk ("scsi%d : tests complete.\n", host->host_no);
 
-    splx(old_level);
+    restore_flags(flags);
     return 0;
 }
 
@@ -1364,11 +1421,12 @@
     struct Scsi_Host *host = c->host;
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
     	host->hostdata;
-    int old_level;
+    unsigned long flags;
     char **prev, *search;
     int i;
 
-    old_level = splx(0);
+    save_flags(flags);
+    cli();
     for (i = 0; i < 2; ++i) {
     	for (search = (char *) (i ? hostdata->issue_dsa_head : 
     	    	hostdata->reconnect_dsa_head), prev = (char **) (i ? 
@@ -1390,21 +1448,14 @@
     if (hostdata->running_list == cmd)
     	hostdata->running_list = cmd->next;
 
-    if (!scan_scsis_buf_busy) {
-#ifdef SCSI_MALLOC
-	scsi_free ((void *) cmd->real, cmd->size);
-#else
-	kfree_s (cmd->real, cmd->size);
-#endif
-    } else {
-	scan_scsis_buf_busy = 0;
-    }
+    cmd->next = hostdata->free;
+    hostdata->free = cmd;
 
     c->host_scribble = NULL;
     c->result = result;
     c->scsi_done(c);
 
-    splx(old_level);
+    restore_flags(flags);
 }
 
 /* 
@@ -1429,7 +1480,7 @@
     unsigned long *dsp;
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
 	host->hostdata;		
-    int old_level;
+    unsigned long flags;
     NCR53c7x0_local_setup(host);
 
     /*
@@ -1437,8 +1488,8 @@
      * dump the appropriate debugging information to standard 
      * output.  
      */
-
-    old_level = splx(0);
+    save_flags(flags);
+    cli();
     dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
     for (bp = hostdata->breakpoints; bp && bp->address != dsp; 
     	bp = bp->next);
@@ -1460,7 +1511,7 @@
      * instruction in bytes.
      */
 
-    splx(old_level);
+    restore_flags(flags);
 }
 
 /*
@@ -1575,7 +1626,7 @@
 	hostdata->sync[target].select_indirect = (scntl3 << 24) | (target << 16) | 
 		(sxfer << 8);
 
-	script = hostdata->sync[target].script;
+	script = (long *) hostdata->sync[target].script;
 
 	/* XXX - add NCR53c7x0 code to reprogram SCF bits if we want to */
 	if ((hostdata->chip / 100) == 8) {
@@ -1630,7 +1681,7 @@
 	printk ("scsi%d : message", host->host_no);
 	if (cmd) 
 	    printk (" from target %d lun %d", c->target, c->lun);
-	print_msg (hostdata->msg_buf);
+	print_msg ((unsigned char *) hostdata->msg_buf);
 	printk("\n");
 	switch (hostdata->msg_buf[0]) {
 	/* 
@@ -1665,7 +1716,8 @@
    	 */
 	    if (cmd->flags & CMD_FLAG_SDTR) {
 		cmd->flags &= ~CMD_FLAG_SDTR; 
-		synchronous (host, c->target, hostdata->msg_buf);
+		synchronous (host, c->target, (unsigned char *) 
+		    hostdata->msg_buf);
 		hostdata->dsp = hostdata->script + hostdata->E_accept_message /
 		    sizeof(long);
 		hostdata->dsp_changed = 1;
@@ -1673,7 +1725,8 @@
 	    } else {
 		if (hostdata->options & OPTION_SYNCHRONOUS)  {
 		    cmd->flags |= CMD_FLAG_DID_SDTR;
-		    synchronous (host, c->target, hostdata->msg_buf);
+		    synchronous (host, c->target, (unsigned char *)
+		    	hostdata->msg_buf);
 		} else {
 		    hostdata->msg_buf[4] = 0;		/* 0 offset = async */
 		}
@@ -1948,15 +2001,16 @@
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
 	instance->hostdata;
     struct NCR53c7x0_break *bp, **prev;
-    int old_level;
-    old_level = splx(0);
+    unsigned long flags;
+    save_flags(flags);
+    cli();
     for (bp = (struct NCR53c7x0_break *) instance->breakpoints,
 	    prev = (struct NCR53c7x0_break **) &instance->breakpoints;
 	    bp; prev = (struct NCR53c7x0_break **) &(bp->next),
 	    bp = (struct NCR53c7x0_break *) bp->next);
 
     if (!bp) {
-	splx(old_level);
+	restore_flags(flags);
 	return -EIO;
     }
 
@@ -1969,7 +2023,7 @@
     if (prev)
 	*prev = bp->next;
 
-    splx(old_level);
+    restore_flags(flags);
     return 0;
 }
 
@@ -1981,7 +2035,7 @@
     struct NCR53c7x0_break *bp;
     char buf[80];
     size_t len;
-    int old_level;
+    unsigned long flags;
     /* 
      * XXX - we need to insure that the processor is halted 
      * here in order to prevent a race condition.  So, if the 
@@ -1992,7 +2046,8 @@
 	host->host_no);
     debugger_kernel_write (host, buf, strlen(buf));
 
-    old_level=splx(0);
+    save_flags(flags);
+    cli();
     for (bp = (struct NCR53c7x0_break *) host->breakpoints;
 	    bp; bp = (struct NCR53c7x0_break *) bp->next); {
 	    sprintf (buf, "scsi%d : bp : success : at %08x, replaces %08x %08x",
@@ -2007,7 +2062,7 @@
 	    len = strlen(buf);
 	    debugger_kernel_write (host, buf, len);
     }
-    splx(old_level);
+    restore_flags(flags);
     return 0;
 }
 
@@ -2018,20 +2073,21 @@
     struct NCR53c7x0_break *bp;
     char buf[80];
     size_t len;
-    int old_level;
-    old_level=splx(0);
+    unsigned long flags;
+    save_flags(flags);
+    cli();
 
     if (hostdata->state != STATE_HALTED) {
 	sprintf (buf, "scsi%d : bs : failure : NCR not halted\n", host->host_no);
 	debugger_kernel_write (host, buf, strlen(buf));
-	splx(old_level);
+	restore_flags(flags);
 	return -1;
     }
 
     if (!(bp = kmalloc (sizeof (struct NCR53c7x0_break)))) {
 	printk ("scsi%d : kmalloc(%d) of breakpoint structure failed, try again\n",
 	    host->host_no, sizeof(struct NCR53c7x0_break));
-	splx(old_level);
+	restore_flags(flags);
 	return -1;
     }
 
@@ -2043,7 +2099,7 @@
     hostdata->breakpoints = bp->next;
     memcpy ((void *) bp->address, (void *) hostdata->E_debug_break, 8);
     
-    splx(old_level);
+    restore_flags(flags);
     return 0;
 }
 
@@ -2132,9 +2188,10 @@
     buflen) {
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
 	host->hostdata;
-    int copy, left, old_level;
-    
-    old_level = splx(0);
+    int copy, left;
+    unsigned long flags;
+    save_flags(flags);
+    cli();
     while (buflen) {
 	left = (hostdata->debug_buf + hostdata->debug_size - 1) -
 	    hostdata->debug_write;
@@ -2147,7 +2204,7 @@
 	    (hostdata->debug_buf + hostdata->debug_size))
 	    hosdata->debug_write = hostdata->debug_buf;
     }
-    (void) splx(old_level);
+    restore_flags(flags);
 }
 
 #endif /* def NCRDEBUG */
@@ -2164,7 +2221,8 @@
  * 
  */
 
-static void NCR53c8x0_soft_reset (struct Scsi_Host *host) {
+static void 
+NCR53c8x0_soft_reset (struct Scsi_Host *host) {
     NCR53c7x0_local_declare();
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
 	host->hostdata;
@@ -2187,14 +2245,18 @@
 
 
     /* 
-     * Respond to selection and reselection by targets and 
-     * use our _initiator_ SCSI ID for arbitration. 
+     * Respond to reselection by targets and use our _initiator_ SCSI ID 
+     * for arbitration. If notyet, also respond to SCSI selection.
      *
      * XXX - Note : we must reprogram this when reselecting as 
      *	a target.
      */
 
+#ifdef notyet
     NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE|SCID_800_SRE);
+#else
+    NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE);
+#endif
     NCR53c7x0_write8(RESPID_REG_800, hostdata->this_id_mask);
 
     /*
@@ -2222,8 +2284,7 @@
 
     
     NCR53c7x0_write8(SIEN0_REG_800, ((hostdata->options & OPTION_PARITY) ?
-	    SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_800_SEL |
-    	    SIEN_800_RESEL | SIEN_MA);
+	    SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA);
     NCR53c7x0_write8(SIEN1_REG_800, SIEN1_800_STO | SIEN1_800_HTH);
 
     /* 
@@ -2243,11 +2304,13 @@
 /*
  * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) 
  *
- * Purpose : Using scsi_malloc() if the system is initialized,
- *	scan_scsis_buf if not, allocate space to store the variable
- *	length NCR53c7x0_cmd structure.  Initialize it based on 
- *	the Scsi_Cmnd structure passed in, including dsa and 
- *	Linux field initialization, and dsa code relocation.
+ * Purpose : If we have not allready allocated enough NCR53c7x0_cmd
+ *	structures to satisfy any allowable number of simultaenous 
+ *	commands for this host; do so (using either scsi_malloc()
+ *	or kmalloc() depending on configuration), and add them to the 
+ *	hostdata free list.  Take the first structure off the free list, 
+ *	initialize it based on the Scsi_Cmnd structure passed in, 
+ *	including dsa and Linux field initialization, and dsa code relocation.
  *
  * Inputs : cmd - SCSI command
  *
@@ -2255,26 +2318,86 @@
  *	NULL on failure.
  */
 
-static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
+static struct NCR53c7x0_cmd *
+create_cmd (Scsi_Cmnd *cmd) {
     NCR53c7x0_local_declare();
     struct Scsi_Host *host = cmd->host;
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
         host->hostdata;	
-    int size;			/* Size of *tmp */
-    struct NCR53c7x0_cmd *tmp; 	/* NCR53c7x0_cmd structure for this command */
+    struct NCR53c7x0_cmd *tmp = NULL; 	/* NCR53c7x0_cmd structure for this command */
     int datain,  		/* Number of instructions per phase */
 	dataout;
     int data_transfer_instructions, /* Count of dynamic instructions */
-    	i,			/* Counter */
-	alignment;		/* Alignment adjustment (0 - 4) */
+    	i;			/* Counter */
     unsigned long *cmd_datain,	/* Address of datain/dataout code */
 	*cmd_dataout;		/* Incremented as we assemble */
+#ifdef notyet
     void *real;			/* Real address */
+    int size;			/* Size of *tmp */
+    int	alignment;		/* Alignment adjustment (0 - 4) */
+#endif
+    unsigned long flags;
     NCR53c7x0_local_setup(cmd->host);
 
+/* FIXME : when we start doing multiple simultaenous commands per LUN, 
+   we will need to either
+    	- Do an attach_slave() and detach_slave() the right way (alocate
+    	  memory in attach_slave() as we do in scsi_register).
+    	- Make sure this code works
+    with the former being cleaner.  At the same time, we can also go with
+    a per-device host_scribble, and introduce a NCR53c7x0_device structure
+    to replace the messy fixed length arrays we're starting to use. */
+
+#ifdef notyet
+
+    if (hostdata->num_commands < host->can_queue &&
+    	!in_scan_scsis && 
+    	!(hostdata->cmd_allocated[cmd->target] & (1 << cmd->lun))) {
+    	for (i = host->hostt->cmd_per_lun - 1; i >= 0  --i) {
+#ifdef SCSI_MALLOC
+    /* scsi_malloc must allocate with a 512 byte granularity, but allways
+       returns buffers which are aligned on a 512 boundary */
+	    size = (hostdata->max_cmd_size + 511) / 512 * 512;
+	    tmp = (struct NCR53c7x0_cmd *) scsi_malloc (size);
+	    if (!tmp)
+		break;
+	    tmp->real = (void *) tmp; 
+#else
+    /* kmalloc() can allocate any size, but historically has returned 
+       unaligned addresses, so we need to allow for alignment */
+	    size = hostdata->max_cmd_size + 4;
+	    real = kmalloc (size, GFP_ATOMIC);
+	    alignment = 4 - (((unsigned) real) & 3);
+	    tmp = (struct NCR53c7x0_cmd *) (((char *) real) + alignment);
+	    if (!tmp)
+		break;
+	    tmp->real = real;
+#endif /* def SCSI_MALLOC */
+    	    tmp->size = size;			
+	    /* Insert all but last into list */
+	    if (i > 0) {
+		tmp->next = hostdata->free;
+		hostdata->free = tmp;
+	    }
+	}
+    }
+#endif /* def notyet */
+    if (!tmp) {
+    	save_flags(flags);
+    	cli();
+    	tmp = (struct NCR53c7x0_cmd *) hostdata->free;
+	if (tmp) {
+    	    hostdata->free = tmp->next;
+	    restore_flags(flags);
+    	} else {
+    	    restore_flags(flags);
+    	    return NULL;
+    	}
+    }
+
 
     /*
-     * Decide weather we need to generate commands for DATA IN,
+     * Decide whether we need to generate commands for DATA IN,
      * DATA OUT, neither, or both based on the SCSI command 
      */
 
@@ -2323,10 +2446,6 @@
 	datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
     }
 
-    /*
-     * Allocate memory for the NCR53c7x0_cmd structure.  
-     */
-
     /* 
      * For each data phase implemented, we need a JUMP instruction
      * to return control to other_transfer.  We also need a MOVE
@@ -2344,63 +2463,11 @@
     if (data_transfer_instructions < 2)
     	data_transfer_instructions = 2;
 
-    /* 
-     * We need enough space to store the base NCR53c7x0 structure,
-     * DSA, and data transfer instructions at 2 long words each,
-     * as well as padding out to the next 512 bytes for scsi_malloc.
-     *
-     * We also need to guarantee alignment of _4_ bytes. 
-     */
-
-#ifdef SCSI_MALLOC
-    size = ((sizeof (struct NCR53c7x0_cmd) + (hostdata->dsa_end - 
-    	hostdata->dsa_start) + 2 * sizeof(long) * 
-    	data_transfer_instructions + 4 + 511) / 512) * 512;		
-#else
-    size = sizeof (struct NCR53c7x0_cmd) + (hostdata->dsa_end - 
-    	hostdata->dsa_start) + 2 * sizeof(long) * 
-    	data_transfer_instructions + 4;
-#endif
-
-
-#if 0
-    if (size > 512) {
-	printk("scsi%d : size = %d\n", host->host_no, size);
-    }
-#endif
-
-#ifdef SCSI_MALLOC
-    real = in_scan_scsis ? NULL : scsi_malloc (size);
-#else
-    real = kmalloc (size, GFP_ATOMIC);
-#endif
-
-    if (!real) {
-	if (!scan_scsis_buf_busy && size <= sizeof(scan_scsis_buf)) {
-	    scan_scsis_buf_busy = 1;
-	    real = scan_scsis_buf;
-	} else {
-	    panic ("scsi%d : scan_scsis_buf too small (need %d bytes)\n",
-		host->host_no, size);
-	}
-    }
-
-    alignment = 4 - (((unsigned) real) & 3);
-
-    tmp = (struct NCR53c7x0_cmd *) (((char *) real) + alignment);
-
-    tmp->real = real;
-
-
-    if (((unsigned long) tmp->dsa) & 0x3) 
-	panic ("scsi%d : pid %d dsa structure not dword aligned!\n",
-	    host->host_no, cmd->pid);
 
     /*
      * Initialize Linux specific fields.
      */
 
-    tmp->size = size;			
     tmp->cmd = cmd;
     tmp->next = NULL;
     tmp->prev = NULL;
@@ -2434,7 +2501,7 @@
     patch_dsa_32(tmp->dsa, dsa_select, 0, hostdata->sync[cmd->target].
     	select_indirect);
     /*
-     * XXX - we need to figure this size based on weather
+     * XXX - we need to figure this size based on whether
      * or not we'll be using any additional messages.
      */
     patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1);
@@ -2462,7 +2529,7 @@
     patch_dsa_32(tmp->dsa, dsa_status, 1, &cmd->result);
     patch_dsa_32(tmp->dsa, dsa_msgout_other, 0, 1);
     patch_dsa_32(tmp->dsa, dsa_msgout_other, 1, 
-    	&NCR53c7xx_msg_nop);
+    	&(hostdata->NCR53c7xx_msg_nop));
 
     
     /*
@@ -2486,8 +2553,8 @@
 #endif
 
 /* 
- * XXX - I'm undecided weather all of this nonsense is faster
- * in the long run, or weather I should just go and implement a loop
+ * XXX - I'm undecided whether all of this nonsense is faster
+ * in the long run, or whether I should just go and implement a loop
  * on the NCR chip using table indirect mode?
  *
  * In any case, this is how it _must_ be done for 53c700/700-66 chips,
@@ -2516,8 +2583,8 @@
 	    cmd_datain[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL | 
 		DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) | 
 		DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE;
-	    cmd_datain[3] = hostdata->script + hostdata->E_msg_in / 
-		sizeof(long);
+	    cmd_datain[3] = (unsigned long) hostdata->script + 
+    	    	hostdata->E_msg_in;
 #if 0
 	    print_insn (host, cmd_datain, "dynamic ", 1);
 	    print_insn (host, cmd_datain + 2, "dynamic ", 1);
@@ -2530,8 +2597,8 @@
 	    cmd_dataout[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL | 
 		DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) | 
 		DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE;
-	    cmd_dataout[3] = hostdata->script + hostdata->E_msg_in /
-		sizeof(long);
+	    cmd_dataout[3] = (unsigned long) hostdata->script + 
+    	    	hostdata->E_msg_in;
 #if 0
 	    print_insn (host, cmd_dataout, "dynamic ", 1);
 	    print_insn (host, cmd_dataout + 2, "dynamic ", 1);
@@ -2548,8 +2615,8 @@
     if (datain) {
 	cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
     	    DBC_TCI_TRUE;
-	cmd_datain[1] = hostdata->script + hostdata->E_other_transfer
-	    / sizeof(long);
+	cmd_datain[1] = (unsigned long) hostdata->script + 
+    	    hostdata->E_other_transfer;
 #if 0
 	print_insn (host, cmd_datain, "dynamic jump ", 1);
 #endif
@@ -2567,8 +2634,8 @@
     if (dataout) {
 	cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
     	    DBC_TCI_TRUE;
-	cmd_dataout[1] = hostdata->script + hostdata->E_other_transfer
-	    / sizeof(long);
+	cmd_dataout[1] = (unsigned long) hostdata->script + 
+    	    hostdata->E_other_transfer;
 #if 0
 	print_insn (host, cmd_dataout, "dynamic jump ", 1);
 #endif
@@ -2603,7 +2670,7 @@
     struct Scsi_Host *host = cmd->host;
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
 	host->hostdata;
-    int old_level;
+    unsigned long flags;
     unsigned char target_was_busy;
     NCR53c7x0_local_setup(host);
     
@@ -2671,7 +2738,8 @@
      * valid while the condition exists.
      */
 
-    old_level = splx(0);
+    save_flags(flags);
+    cli();
 
     /* 
      * Consider a target busy if there are _any_ commands running
@@ -2764,7 +2832,7 @@
     	    tmp->next; tmp = (struct NCR53c7x0_cmd *) tmp->next);
     	tmp->next = tmp;
     }
-    splx(old_level);
+    restore_flags(flags);
     return 0;
 }
 
@@ -2848,9 +2916,9 @@
     
     if (sstat0_sist0 & SSTAT0_UDC) {
 	fatal = 1;
-	printk("scsi%d : target %d lun %d unexpected disconnect\n",
-	    host->host_no, cmd->cmd->target, cmd->cmd->lun);
 	if (cmd) {
+	    printk("scsi%d : target %d lun %d unexpected disconnect\n",
+		host->host_no, cmd->cmd->target, cmd->cmd->lun);
 	    abnormal_finished(cmd, DID_ERROR << 16);
 	}
 	hostdata->dsp = hostdata->script + hostdata->E_schedule / 
@@ -2950,7 +3018,7 @@
 						   should terminate */
     int interrupted = 0;			/* This HA generated 
 						   an interrupt */
-    int old_level;				
+    unsigned long flags;				
 
 #ifdef NCR_DEBUG
     char buf[80];				/* Debugging sprintf buffer */
@@ -3011,12 +3079,14 @@
 		     */
 
 
-		    old_level = splx(0);
+		    save_flags(flags);
+		    cli();
 restart:
 		    for (cmd_prev_ptr = (struct NCR53c7x0_cmd **) 
-			&(hostdata->running_list), cmd = (struct NCR53c7x0_cmd *)
-			hostdata->running_list; cmd ; cmd_prev_ptr = 
-			&(cmd->next), cmd = (struct NCR53c7x0_cmd *) cmd->next) {
+			 &(hostdata->running_list), cmd = 
+                         (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
+                         cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next), 
+    	    	    	 cmd = (struct NCR53c7x0_cmd *) cmd->next) {
 			Scsi_Cmnd *tmp;
 
 			if (!cmd) {
@@ -3045,7 +3115,7 @@
 			if (cmd->prev)
 			    cmd->prev->next = cmd->next;
 			if (cmd_prev_ptr)
-			    *cmd_prev_ptr = cmd->next;
+			    *cmd_prev_ptr = (struct NCR53c7x0_cmd *) cmd->next;
 
 #ifdef LUN_BUSY
 			/* Check for next command for target, add to issue queue */
@@ -3054,16 +3124,8 @@
 #endif
 
 
-			if (!scan_scsis_buf_busy) {
-#ifdef SCSI_MALLOC
-			    scsi_free ((void *) cmd->real, cmd->size);
-#else
-			    kfree_s ((void *) cmd->real, cmd->size);
-#endif
-			} else {
-			    scan_scsis_buf_busy = 0;
-			}
-
+    	    	    	cmd->next = hostdata->free;
+    	    	    	hostdata->free = cmd;
 
     	    	    	tmp->host_scribble = NULL;
 
@@ -3081,7 +3143,7 @@
 			goto restart;
 
 		    }
-		    splx(old_level);
+		    restore_flags(flags);
 
 		    if (!search_found)  {
 			printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
@@ -3204,7 +3266,8 @@
  *
  */
 
-static int abort_connected (struct Scsi_Host *host) {
+static int 
+abort_connected (struct Scsi_Host *host) {
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
 	host->hostdata;
 
@@ -3398,15 +3461,13 @@
     NCR53c7x0_local_declare();
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
 	host->hostdata;
-    unsigned char dstat,	/* DSTAT */	
-	dbc_dcmd;		/* DCMD (high eight bits) + DBC */
+    unsigned char dstat;	/* DSTAT */	
     unsigned long *dsp,
 	*next_dsp,		/* Current dsp */
-    	*dsa;
-    	
-
-    int ipl,			/* Old ipl from splx(0) */
-	tmp;
+    	*dsa,
+	dbc_dcmd;		/* DCMD (high eight bits) + DBC */
+    int tmp;
+    unsigned long flags;
     NCR53c7x0_local_setup(host);
 
     if (!hostdata->dstat_valid) {
@@ -3460,12 +3521,13 @@
 	if (hostdata->options & OPTION_DEBUG_TRACE) {
 	} else if (hostdata->options & OPTION_DEBUG_SINGLE) {
 	    print_insn (host, dsp, "s ", 0);
-	    ipl = splx(0);
+	    save_flags(flags);
+	    cli();
 /* XXX - should we do this, or can we get away with writing dsp? */
 
 	    NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) & 
     	    	~DCNTL_SSM) | DCNTL_STD);
-	    splx(ipl);
+	    restore_flags(flags);
 	} else {
 	    printk("scsi%d : unexpected single step interrupt at\n"
 		   "         ", host->host_no);
@@ -3654,9 +3716,10 @@
     struct Scsi_Host *host = cmd->host;
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) 
 	host->hostdata;
-    int old_level;
+    unsigned long flags;
     struct NCR53c7x0_cmd *curr, **prev;
-    old_level = splx(0);
+    save_flags(flags);
+    cli();
 
 /*
  * The command could be hiding in the issue_queue.  This would be very
@@ -3668,28 +3731,23 @@
  * pull the command out of the old queue, and call it aborted.
  */
 
-    for (curr = hostdata->issue_queue, prev = &(hostdata->issue_queue);
-	curr && curr->cmd != cmd; prev = &(curr->next), curr = curr->next);
+    for (curr = (struct NCR53c7x0_cmd *) hostdata->issue_queue, 
+         prev = (struct NCR53c7x0_cmd **) &(hostdata->issue_queue);
+	 curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **)
+         &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
 
     if (curr) {
-	*prev = curr->next;
+	*prev = (struct NCR53c7x0_cmd *) curr->next;
 /* XXX - get rid of DLL ? */
 	if (curr->prev)
 	    curr->prev->next = curr->next;
 
-	if (!scan_scsis_buf_busy) {
-#ifdef SCSI_MALLOC
-	    scsi_free ((void *) curr->real, curr->size);
-#else
-	    kfree_s ((void *) curr->real, curr->size);
-#endif
-	} else {
-	    scan_scsis_buf_busy = 0;
-	}
+    	curr->next = hostdata->free;
+    	hostdata->free = curr;
 
 	cmd->result = 0;
 	cmd->scsi_done(cmd);
-	splx(old_level);
+	restore_flags(flags);
 	return SCSI_ABORT_SUCCESS;
     }
 
@@ -3698,11 +3756,13 @@
  * commands.  If this is the case, drastic measures are called for.  
  */ 
 
-    for (curr = hostdata->running_list, prev = &(hostdata->running_list);
-	curr && curr->cmd != cmd; prev = &(curr->next), curr = curr->next);
+    for (curr = (struct NCR53c7x0_cmd *) hostdata->running_list, 
+    	 prev = (struct NCR53c7x0_cmd **) &(hostdata->running_list);
+	 curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **) 
+         &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
 
     if (curr) {
-	splx(old_level);
+	restore_flags(flags);
 	printk ("scsi%d : DANGER : command in running list, can not abort.\n",
 	    cmd->host->host_no);
 	return SCSI_ABORT_SNOOZE;
@@ -3715,16 +3775,8 @@
  */
 
     curr = (struct NCR53c7x0_cmd *) cmd->host_scribble;
-
-    if (!scan_scsis_buf_busy) {
-#ifdef SCSI_MALLOC
-	scsi_free ((void *) curr->real, curr->size);
-#else
-	kfree_s ((void *) curr->real, curr->size);
-#endif
-    } else {
-	scan_scsis_buf_busy = 0;
-    }
+    curr->next = hostdata->free;
+    hostdata->free = curr;
 
     if (((cmd->result & 0xff00) == 0xff00) ||
 	((cmd->result & 0xff) == 0xff)) {
@@ -3734,7 +3786,7 @@
 	    host->host_no);
     }
     cmd->scsi_done(cmd);
-    splx(old_level);
+    restore_flags(flags);
     return SCSI_ABORT_SNOOZE;
 }
 
@@ -3749,17 +3801,47 @@
  * Returns : 0 on success.
  */
  
-int NCR53c7xx_reset (Scsi_Cmnd *cmd) {
+int 
+NCR53c7xx_reset (Scsi_Cmnd *cmd) {
     NCR53c7x0_local_declare();
-    struct Scsi_Host *host = cmd ? cmd->host : NULL;
+    unsigned long flags;
+    int found;
+    struct NCR53c7x0_cmd * c;
+    Scsi_Cmnd *tmp;
+    struct Scsi_Host *host = cmd->host;
     struct NCR53c7x0_hostdata *hostdata = host ? 
-	(struct NCR53c7x0_hostdata *) host->hostdata : NULL;
-    if (host) NCR53c7x0_local_setup(host);
-    
+    (struct NCR53c7x0_hostdata *) host->hostdata : NULL;
+    NCR53c7x0_local_setup(host);
+    save_flags(flags);
+    halt (host);
+    NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
+    udelay(25);	/* Minimum ammount of time to assert RST */
+    NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
+    for (c = (struct NCR53c7x0_cmd *) hostdata->running_list, found = 0; c; 
+    	c = (struct NCR53c7x0_cmd *) c->next)  {
+	tmp = c->cmd;
+    	c->next = hostdata->free;
+    	hostdata->free = c;
+
+	if (tmp == cmd)
+	    found = 1; 
+    	tmp->result = DID_RESET << 16;
+	tmp->scsi_done(tmp);
+    }
+    if (!found) {
+    	c = (struct NCR53c7x0_cmd *) cmd->host_scribble;
+    	if (c) {
+    	    c->next = hostdata->free;
+    	    hostdata->free = c;
+    	}
+    	cmd->result = DID_RESET << 16;
+    	cmd->scsi_done(cmd);
+    }
+    restore_flags(flags);
 
     printk ("scsi%d : DANGER : NCR53c7xx_reset is NOP\n",
 	cmd->host->host_no);
-    return SCSI_RESET_SNOOZE;
+    return SCSI_RESET_SUCCESS;
 }
 
 /*
@@ -3770,13 +3852,11 @@
 static void print_dsa (struct Scsi_Host *host, unsigned long *dsa) {
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
 	host->hostdata;
-    Scsi_Cmnd * cmd;
-    struct NCR53c7x0_cmd * c;
     int i, len;
     char *ptr;
 
     printk("scsi%d : dsa at 0x%x\n"
-	    "        + %d : dsa_msgout length = %d, data = 0x%x\n" ,
+	    "        + %ld : dsa_msgout length = %lu, data = 0x%lx\n" ,
     	    host->host_no, (unsigned) dsa, hostdata->dsa_msgout,
     	    dsa[hostdata->dsa_msgout / sizeof(long)],
 	    dsa[hostdata->dsa_msgout / sizeof(long) + 1]);
@@ -3790,3 +3870,108 @@
     }
 }
 
+/*
+ * Function : static int shutdown (struct Scsi_Host *host)
+ * 
+ * Purpose : does a clean (we hope) shutdown of the NCR SCSI 
+ *	chip.  Use prior to dumping core, unloading the NCR driver,
+ *	etc.
+ * 
+ * Returns : 0 on success
+ */
+#ifdef MODULE
+static int 
+shutdown (struct Scsi_Host *host) {
+    NCR53c7x0_local_declare();
+    unsigned long flags;
+    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
+	host->hostdata;
+    NCR53c7x0_local_setup(host);
+    save_flags (flags);
+    cli();
+    halt (host);
+    hostdata->soft_reset(host);
+/* 
+ * For now, we take the simplest solution : reset the SCSI bus. Eventually,
+ * - If a command is connected, kill it with an ABORT message
+ * - If commands are disconnected, connect to each target/LUN and 
+ *	do a ABORT, followed by a SOFT reset, followed by a hard 
+ *	reset.  
+ */
+    NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
+    udelay(25);	/* Minimum ammount of time to assert RST */
+    NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
+    restore_flags (flags);
+    return 0;
+}
+#endif
+
+
+/*
+ * Function : static int halt (struct Scsi_Host *host)
+ * 
+ * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
+ *
+ * Inputs : host - SCSI chip to halt
+ *
+ * Returns : 0 on success
+ */
+
+static int 
+halt (struct Scsi_Host *host) {
+    NCR53c7x0_local_declare();
+    unsigned long flags;
+    unsigned char istat, tmp;
+    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
+	host->hostdata;
+    NCR53c7x0_local_setup(host);
+
+    save_flags(flags);
+    cli();
+    NCR53c7x0_write8(hostdata->istat, ISTAT_ABRT);
+    /* Eat interrupts until we find what we're looking for */
+    for (;;) {
+	istat = NCR53c7x0_read8 (hostdata->istat);
+	if (istat & ISTAT_SIP) {
+	    if ((hostdata->chip / 100) == 8) {
+		tmp = NCR53c7x0_read8(SIST0_REG_800);
+		udelay(1);
+		tmp = NCR53c7x0_read8(SIST1_REG_800);
+	    } else {
+		tmp = NCR53c7x0_read8(SSTAT0_REG);
+	    }
+	} else if (istat & ISTAT_DIP) {
+            NCR53c7x0_write8(hostdata->istat, 0);
+	    tmp = NCR53c7x0_read8(DSTAT_REG);
+	    if (tmp & DSTAT_ABRT)
+		break;
+	    else
+		panic("scsi%d: could not halt NCR chip\n", host->host_no);
+	}
+    }
+    hostdata->state = STATE_HALTED;
+    restore_flags(flags);
+    return 0;
+}
+
+#ifdef MODULE
+int NCR53c7x0_release(struct Scsi_Host *host) {
+    shutdown (host);
+/* FIXME : need to recursively free tpnt structure */
+    if (host->irq != IRQ_NONE)
+	{
+	    int irq_count;
+	    struct Scsi_Host *tmp;
+	    for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next)
+		if (tmp->hostt == the_template && tmp->irq == host->irq)
+		    ++irq_count;
+	    if (irq_count == 1)
+		free_irq(host->irq);
+	}
+    if (host->dma_channel != DMA_NONE)
+	free_dma(host->dma_channel);
+    return 1;
+}
+Scsi_Host_Template driver_template = NCR53c7xx;
+#include "scsi_module.c"
+#endif /* def MODULE */
diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/53c7,8xx.h linux/drivers/scsi/53c7,8xx.h
--- v1.2.5/linux/drivers/scsi/53c7,8xx.h	Wed Jan 25 09:06:17 1995
+++ linux/drivers/scsi/53c7,8xx.h	Mon Apr 17 13:47:57 1995
@@ -46,20 +46,27 @@
  * array.
  */
 
-#ifdef HOSTS_C 
+#if defined(HOSTS_C) || defined(MODULE)
 #include <linux/scsicam.h>
 extern int NCR53c7xx_abort(Scsi_Cmnd *);
 extern int NCR53c7xx_detect(Scsi_Host_Template *tpnt);
 extern int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 extern int NCR53c7xx_reset(Scsi_Cmnd *);
-
-#define NCR53c7xx {NULL, NULL, "NCR53c{7,8}xx (rel 3)", NCR53c7xx_detect, 	\
-    	NULL, NULL,						\
-	NULL, NCR53c7xx_queue_command, NCR53c7xx_abort, NCR53c7xx_reset,\
-        NULL, scsicam_bios_param, 					\
-	/* can queue */ 1, /* id */ 7, 127 /* old SG_ALL */, 		\
-	/* cmd per lun */ 1 , 0, 0, DISABLE_CLUSTERING}
+#ifdef MODULE
+extern int NCR53c7xx_release(struct Scsi_Host *);
 #else
+#define NCR53c7xx_release NULL
+#endif
+
+#define NCR53c7xx {NULL, NULL, "NCR53c{7,8}xx (rel 4)", NCR53c7xx_detect, 	\
+    	NULL, /* info */ NULL, /* command, depricated */ NULL, 		\
+	NCR53c7xx_queue_command, NCR53c7xx_abort, NCR53c7xx_reset,	\
+        NULL /* slave attach */, scsicam_bios_param, /* can queue */ 1, \
+	/* id */ 7, 127 /* old SG_ALL */, /* cmd per lun */ 1 , 	\
+        /* present */ 0, /* unchecked isa dma */ 0, DISABLE_CLUSTERING} 
+#endif /* defined(HOSTS_C) || defined(MODULE) */ 
+
+#ifndef HOSTS_C
 /* Register addresses, ordered numerically */
 
 
@@ -932,6 +939,9 @@
 
 struct NCR53c7x0_cmd {
     void *real;				/* Real, unaligned address */
+    void (* free)(void *);		/* Command to deallocate; NULL
+					   for structures allocated with
+					   scsi_register, etc. */
     Scsi_Cmnd *cmd;			/* Associated Scsi_Cmnd 
 					   structure, Scsi_Cmnd points
 					   at NCR53c7x0_cmd using 
@@ -949,7 +959,11 @@
 					 */
 
 
-    struct NCR53c7x0_cmd *next, *prev;	/* Linux maintained lists */
+    volatile struct NCR53c7x0_cmd *next, *prev;	
+                                        /* Linux maintained lists.  Note that
+					   hostdata->free is a singly linked
+					   list; the rest are doubly linked */
+    					 
 
 
     unsigned long *data_transfer_start;	/* Start of data transfer routines */
@@ -986,10 +1000,12 @@
 /* Indicates that the NCR is executing other code. */
 #define STATE_RUNNING	2		
 /* 
- * Indicates that the NCR was being aborted.  Only used when running 
- * NCR53c700 compatible scripts.  
+ * Indicates that the NCR was being aborted.
  */
 #define STATE_ABORTING	3
+/* 
+ * Indicates that the NCR was successfully aborted. */
+#define STATE_ABORTED 4
     
 
 /* 
@@ -1072,6 +1088,7 @@
 
     int (* dstat_sir_intr)(struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
 
+    long dsa_size; /* Size of DSA structure */
 
     /*
      * Location of DSA fields for the SCSI SCRIPT corresponding to this 
@@ -1160,11 +1177,13 @@
 	*breakpoint_current;		/* Current breakpoint being stepped 
 					   through, NULL if we are running 
 					   normally. */
+#ifdef NCR_DEBUG
     int debug_size;			/* Size of debug buffer */
     volatile int debug_count;		/* Current data count */
     volatile char *debug_buf;		/* Output ring buffer */
     volatile char *debug_write;		/* Current write pointer */
     volatile char *debug_read;		/* Current read pointer */
+#endif /* def NCR_DEBUG */
 
     /* XXX - primitive debugging junk, remove when working ? */
     int debug_print_limit;		/* Number of commands to print
@@ -1203,6 +1222,21 @@
 						   nexus, ONLY valid for
 						   NCR53c700/NCR53c700-66
 						 */
+
+    volatile struct NCR53c7x0_cmd *spare;	/* pointer to spare,
+    	    	    	    	    	    	   allocated at probe time,
+    	    	    	    	    	    	   which we can use for 
+						   initialization */
+    volatile struct NCR53c7x0_cmd *free;
+    int max_cmd_size;				/* Maximum size of NCR53c7x0_cmd
+					    	   based on number of 
+						   scatter/gather segments, etc.
+						   */
+    volatile int num_cmds;			/* Number of commands 
+						   allocated */
+    volatile unsigned char cmd_allocated[8];	/* Have we allocated commands
+						   for this target yet?  If not,
+						   do so ASAP */
     volatile unsigned char busy[8][8];     	/* number of commands 
 						   executing on each target
     	    	    	    	    	    	 */
@@ -1226,13 +1260,21 @@
     volatile unsigned char msg_buf[16];		/* buffer for messages
 						   other than the command
 						   complete message */
-    volatile struct NCR53c7x0_cmd *reconnect_dsa_head;	
+    volatile unsigned char *reconnect_dsa_head;	
 						/* disconnected commands,
 						   maintained by NCR */
     /* Data identifying nexus we are trying to match during reselection */
     volatile unsigned char reselected_identify; /* IDENTIFY message */
     volatile unsigned char reselected_tag;	/* second byte of queue tag 
 						   message or 0 */
+    /* These were static variables before we moved them */
+
+    long NCR53c7xx_zero;
+    long NCR53c7xx_sink;
+    char NCR53c7xx_msg_reject;
+    char NCR53c7xx_msg_abort;
+    char NCR53c7xx_msg_nop;
+
     int script_count;				/* Size of script in longs */
     unsigned long script[0];			/* Relocated SCSI script */
 
diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/53c7,8xx.scr linux/drivers/scsi/53c7,8xx.scr
--- v1.2.5/linux/drivers/scsi/53c7,8xx.scr	Thu Mar  9 20:37:34 1995
+++ linux/drivers/scsi/53c7,8xx.scr	Mon Apr 17 13:52:38 1995
@@ -221,10 +221,10 @@
 ABSOLUTE int_test_2 = 0x04010000		; Test 2 complete
 ABSOLUTE int_test_3 = 0x04020000		; Test 3 complete
 						
-EXTERNAL NCR53c7xx_msg_abort 		; Pointer to abort message
-EXTERNAL NCR53c7xx_msg_reject 		; Pointer to reject message
-EXTERNAL NCR53c7xx_zero			; long with zero in it, use for source
-EXTERNAL NCR53c7xx_sink			; long to dump worthless data in
+ABSOLUTE NCR53c7xx_msg_abort = 0	; Pointer to abort message
+ABSOLUTE NCR53c7xx_msg_reject = 0       ; Pointer to reject message
+ABSOLUTE NCR53c7xx_zero	= 0		; long with zero in it, use for source
+ABSOLUTE NCR53c7xx_sink = 0		; long to dump worthless data in
 
 ; Pointer to final bytes of multi-byte messages
 ABSOLUTE msg_buf = 0
@@ -881,13 +881,23 @@
 wait_reselect_failed:
 ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
     MOVE CTEST2 & 0x40 TO SFBR	
-    JUMP selected, IF NOT 0x40
+    JUMP schedule, IF 0x40
+    MOVE SIST0 & 0x20 TO SFBR
+    JUMP selected, IF 0x20
+; FIXME : Something bogus happened, and we shouldn't fail silently.
     JUMP schedule
 
 select_failed:
-    MOVE ISTAT & 0x20 TO SFBR
-    JUMP reselected, IF NOT 0x20
-    MOVE ISTAT & 0xdf TO ISTAT
+; If SIGP is set, the user just gave us another command, and
+; we should restart or return to the scheduler.
+; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
+    MOVE CTEST2 & 0x40 TO SFBR	
+    JUMP select, IF 0x40
+; Otherwise, mask the selected and reselected bits off SIST0
+    MOVE SIST0 & 0x30 TO SFBR
+    JUMP selected, IF 0x20
+    JUMP reselected, IF 0x10 
+; FIXME : Something bogus happened, and we shouldn't fail silently.
     JUMP schedule
 
 ;
@@ -980,7 +990,10 @@
 ; If DSP points here, and a phase mismatch is encountered, we need to 
 ; do a bus reset.
 ;
+    
+    MOVE SCNTL2 & 0x7f TO SCNTL2
     MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
+    WAIT DISCONNECT
     INT int_norm_aborted
 
 ;
diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/53c8xx_d.h linux/drivers/scsi/53c8xx_d.h
--- v1.2.5/linux/drivers/scsi/53c8xx_d.h	Thu Mar  9 20:37:34 1995
+++ linux/drivers/scsi/53c8xx_d.h	Mon Apr 17 13:52:55 1995
@@ -127,7 +127,7 @@
 /*
 	CALL scratch_to_dsa
 
-at 0x0000000a : */	0x88080000,0x00000800,
+at 0x0000000a : */	0x88080000,0x00000830,
 /*
 	JUMP reselected_check_next
 
@@ -283,10 +283,10 @@
 ABSOLUTE int_test_2 = 0x04010000		; Test 2 complete
 ABSOLUTE int_test_3 = 0x04020000		; Test 3 complete
 						
-EXTERNAL NCR53c7xx_msg_abort 		; Pointer to abort message
-EXTERNAL NCR53c7xx_msg_reject 		; Pointer to reject message
-EXTERNAL NCR53c7xx_zero			; long with zero in it, use for source
-EXTERNAL NCR53c7xx_sink			; long to dump worthless data in
+ABSOLUTE NCR53c7xx_msg_abort = 0	; Pointer to abort message
+ABSOLUTE NCR53c7xx_msg_reject = 0       ; Pointer to reject message
+ABSOLUTE NCR53c7xx_zero	= 0		; long with zero in it, use for source
+ABSOLUTE NCR53c7xx_sink = 0		; long to dump worthless data in
 
 ; Pointer to final bytes of multi-byte messages
 ABSOLUTE msg_buf = 0
@@ -325,7 +325,7 @@
 ;
     CALL dsa_to_scratch
 
-at 0x0000002d : */	0x88080000,0x000007b8,
+at 0x0000002d : */	0x88080000,0x000007e8,
 /*
 ; XXX - we need to deal with the NCR53c710, which lacks an add with
 ;	carry instruction, by moving around the DSA alignment to avoid
@@ -370,7 +370,7 @@
 ; And update the head pointer.
     CALL dsa_to_scratch
 
-at 0x00000041 : */	0x88080000,0x000007b8,
+at 0x00000041 : */	0x88080000,0x000007e8,
 /*
     MOVE dmode_ncr_to_memory TO DMODE	
 
@@ -422,7 +422,7 @@
 
     CALL scratch_to_dsa
 
-at 0x00000053 : */	0x88080000,0x00000800,
+at 0x00000053 : */	0x88080000,0x00000830,
 /*
 
 
@@ -514,7 +514,7 @@
 
     SELECT ATN FROM dsa_select, select_failed
 
-at 0x00000067 : */	0x4300003c,0x00000694,
+at 0x00000067 : */	0x4300003c,0x000006a4,
 /*
     JUMP select_msgout, WHEN MSG_OUT
 
@@ -539,7 +539,7 @@
 
     CALL dsa_to_scratch
 
-at 0x0000006d : */	0x88080000,0x000007b8,
+at 0x0000006d : */	0x88080000,0x000007e8,
 /*
 
     MOVE SCRATCH0 + dsa_next TO SCRATCH0
@@ -711,7 +711,7 @@
 do_dataout:
     CALL dsa_to_scratch
 
-at 0x0000009b : */	0x88080000,0x000007b8,
+at 0x0000009b : */	0x88080000,0x000007e8,
 /*
     MOVE SCRATCH0 + dsa_dataout TO SCRATCH0	
 
@@ -756,7 +756,7 @@
 do_datain:
     CALL dsa_to_scratch
 
-at 0x000000b1 : */	0x88080000,0x000007b8,
+at 0x000000b1 : */	0x88080000,0x000007e8,
 /*
     MOVE SCRATCH0 + dsa_datain TO SCRATCH0	
 
@@ -1100,7 +1100,7 @@
 /*
     MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT
 
-at 0x00000132 : */	0x0e000001,((unsigned long)&NCR53c7xx_msg_reject),
+at 0x00000132 : */	0x0e000001,0x00000000,
 /*
     RETURN
 
@@ -1295,7 +1295,7 @@
 reselected_notag:    
     MOVE MEMORY 1, NCR53c7xx_zero, reselected_tag
 
-at 0x0000015c : */	0xc0000001,((unsigned long)&NCR53c7xx_zero),0x00000000,
+at 0x0000015c : */	0xc0000001,0x00000000,0x00000000,
 /*
 
 
@@ -1317,7 +1317,7 @@
 /*
     CALL scratch_to_dsa
 
-at 0x00000166 : */	0x88080000,0x00000800,
+at 0x00000166 : */	0x88080000,0x00000830,
 /*
 
     ; Fix the update-next pointer so that the reconnect_dsa_head
@@ -1477,31 +1477,53 @@
 
 at 0x0000019f : */	0x741a4000,0x00000000,
 /*
-    JUMP selected, IF NOT 0x40
+    JUMP schedule, IF 0x40
 
-at 0x000001a1 : */	0x80040040,0x00000674,
+at 0x000001a1 : */	0x800c0040,0x00000130,
 /*
+    MOVE SIST0 & 0x20 TO SFBR
+
+at 0x000001a3 : */	0x74422000,0x00000000,
+/*
+    JUMP selected, IF 0x20
+
+at 0x000001a5 : */	0x800c0020,0x00000674,
+/*
+; FIXME : Something bogus happened, and we shouldn't fail silently.
     JUMP schedule
 
-at 0x000001a3 : */	0x80080000,0x00000130,
+at 0x000001a7 : */	0x80080000,0x00000130,
 /*
 
 select_failed:
-    MOVE ISTAT & 0x20 TO SFBR
+; If SIGP is set, the user just gave us another command, and
+; we should restart or return to the scheduler.
+; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
+    MOVE CTEST2 & 0x40 TO SFBR	
+
+at 0x000001a9 : */	0x741a4000,0x00000000,
+/*
+    JUMP select, IF 0x40
 
-at 0x000001a5 : */	0x74142000,0x00000000,
+at 0x000001ab : */	0x800c0040,0x00000194,
 /*
-    JUMP reselected, IF NOT 0x20
+; Otherwise, mask the selected and reselected bits off SIST0
+    MOVE SIST0 & 0x30 TO SFBR
 
-at 0x000001a7 : */	0x80040020,0x00000568,
+at 0x000001ad : */	0x74423000,0x00000000,
 /*
-    MOVE ISTAT & 0xdf TO ISTAT
+    JUMP selected, IF 0x20
 
-at 0x000001a9 : */	0x7c14df00,0x00000000,
+at 0x000001af : */	0x800c0020,0x00000674,
 /*
+    JUMP reselected, IF 0x10 
+
+at 0x000001b1 : */	0x800c0010,0x00000568,
+/*
+; FIXME : Something bogus happened, and we shouldn't fail silently.
     JUMP schedule
 
-at 0x000001ab : */	0x80080000,0x00000130,
+at 0x000001b3 : */	0x80080000,0x00000130,
 /*
 
 ;
@@ -1525,11 +1547,11 @@
 test_1:
     MOVE MEMORY 4, test_src, test_dest
 
-at 0x000001ad : */	0xc0000004,0x00000000,0x00000000,
+at 0x000001b5 : */	0xc0000004,0x00000000,0x00000000,
 /*
     INT int_test_1
 
-at 0x000001b0 : */	0x98080000,0x04000000,
+at 0x000001b8 : */	0x98080000,0x04000000,
 /*
 
 ;
@@ -1540,61 +1562,61 @@
 test_2:
     CLEAR TARGET
 
-at 0x000001b2 : */	0x60000200,0x00000000,
+at 0x000001ba : */	0x60000200,0x00000000,
 /*
     SELECT ATN FROM 0, test_2_fail
 
-at 0x000001b4 : */	0x43000000,0x00000720,
+at 0x000001bc : */	0x43000000,0x00000740,
 /*
     JUMP test_2_msgout, WHEN MSG_OUT
 
-at 0x000001b6 : */	0x860b0000,0x000006e0,
+at 0x000001be : */	0x860b0000,0x00000700,
 /*
 ENTRY test_2_msgout
 test_2_msgout:
     MOVE FROM 8, WHEN MSG_OUT
 
-at 0x000001b8 : */	0x1e000000,0x00000008,
+at 0x000001c0 : */	0x1e000000,0x00000008,
 /*
     MOVE FROM 16, WHEN CMD 
 
-at 0x000001ba : */	0x1a000000,0x00000010,
+at 0x000001c2 : */	0x1a000000,0x00000010,
 /*
     MOVE FROM 24, WHEN DATA_IN
 
-at 0x000001bc : */	0x19000000,0x00000018,
+at 0x000001c4 : */	0x19000000,0x00000018,
 /*
     MOVE FROM 32, WHEN STATUS
 
-at 0x000001be : */	0x1b000000,0x00000020,
+at 0x000001c6 : */	0x1b000000,0x00000020,
 /*
     MOVE FROM 40, WHEN MSG_IN
 
-at 0x000001c0 : */	0x1f000000,0x00000028,
+at 0x000001c8 : */	0x1f000000,0x00000028,
 /*
     MOVE SCNTL2 & 0x7f TO SCNTL2
 
-at 0x000001c2 : */	0x7c027f00,0x00000000,
+at 0x000001ca : */	0x7c027f00,0x00000000,
 /*
     CLEAR ACK
 
-at 0x000001c4 : */	0x60000040,0x00000000,
+at 0x000001cc : */	0x60000040,0x00000000,
 /*
     WAIT DISCONNECT
 
-at 0x000001c6 : */	0x48000000,0x00000000,
+at 0x000001ce : */	0x48000000,0x00000000,
 /*
 test_2_fail:
     INT int_test_2
 
-at 0x000001c8 : */	0x98080000,0x04010000,
+at 0x000001d0 : */	0x98080000,0x04010000,
 /*
 
 ENTRY debug_break
 debug_break:
     INT int_debug_break
 
-at 0x000001ca : */	0x98080000,0x03000000,
+at 0x000001d2 : */	0x98080000,0x03000000,
 /*
 
 ;
@@ -1610,26 +1632,26 @@
 target_abort:
     SET TARGET
 
-at 0x000001cc : */	0x58000200,0x00000000,
+at 0x000001d4 : */	0x58000200,0x00000000,
 /*
     DISCONNECT
 
-at 0x000001ce : */	0x48000000,0x00000000,
+at 0x000001d6 : */	0x48000000,0x00000000,
 /*
     CLEAR TARGET
 
-at 0x000001d0 : */	0x60000200,0x00000000,
+at 0x000001d8 : */	0x60000200,0x00000000,
 /*
     JUMP schedule
 
-at 0x000001d2 : */	0x80080000,0x00000130,
+at 0x000001da : */	0x80080000,0x00000130,
 /*
     
 ENTRY initiator_abort
 initiator_abort:
     SET ATN
 
-at 0x000001d4 : */	0x58000008,0x00000000,
+at 0x000001dc : */	0x58000008,0x00000000,
 /*
 ; In order to abort the currently established nexus, we 
 ; need to source/sink up to one byte of data in any SCSI phase, 
@@ -1637,60 +1659,69 @@
 ; false->true
     JUMP no_eat_cmd, WHEN NOT CMD
 
-at 0x000001d6 : */	0x82030000,0x00000768,
+at 0x000001de : */	0x82030000,0x00000788,
 /*
     MOVE 1, NCR53c7xx_zero, WHEN CMD
 
-at 0x000001d8 : */	0x0a000001,((unsigned long)&NCR53c7xx_zero),
+at 0x000001e0 : */	0x0a000001,0x00000000,
 /*
 no_eat_cmd:
     JUMP no_eat_msg, WHEN NOT MSG_IN
 
-at 0x000001da : */	0x87030000,0x00000778,
+at 0x000001e2 : */	0x87030000,0x00000798,
 /*
     MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
 
-at 0x000001dc : */	0x0f000001,((unsigned long)&NCR53c7xx_sink),
+at 0x000001e4 : */	0x0f000001,0x00000000,
 /*
 no_eat_msg:
     JUMP no_eat_data, WHEN NOT DATA_IN
 
-at 0x000001de : */	0x81030000,0x00000788,
+at 0x000001e6 : */	0x81030000,0x000007a8,
 /*
     MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
 
-at 0x000001e0 : */	0x09000001,((unsigned long)&NCR53c7xx_sink),
+at 0x000001e8 : */	0x09000001,0x00000000,
 /*
 no_eat_data:
     JUMP no_eat_status, WHEN NOT STATUS
 
-at 0x000001e2 : */	0x83030000,0x00000798,
+at 0x000001ea : */	0x83030000,0x000007b8,
 /*
     MOVE 1, NCR53c7xx_sink, WHEN STATUS
 
-at 0x000001e4 : */	0x0b000001,((unsigned long)&NCR53c7xx_sink),
+at 0x000001ec : */	0x0b000001,0x00000000,
 /*
 no_eat_status:
     JUMP no_source_data, WHEN NOT DATA_OUT
 
-at 0x000001e6 : */	0x80030000,0x000007a8,
+at 0x000001ee : */	0x80030000,0x000007c8,
 /*
     MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
 
-at 0x000001e8 : */	0x08000001,((unsigned long)&NCR53c7xx_zero),
+at 0x000001f0 : */	0x08000001,0x00000000,
 /*
 no_source_data:
 ;
 ; If DSP points here, and a phase mismatch is encountered, we need to 
 ; do a bus reset.
 ;
+    
+    MOVE SCNTL2 & 0x7f TO SCNTL2
+
+at 0x000001f2 : */	0x7c027f00,0x00000000,
+/*
     MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
 
-at 0x000001ea : */	0x0e000001,((unsigned long)&NCR53c7xx_msg_abort),
+at 0x000001f4 : */	0x0e000001,0x00000000,
+/*
+    WAIT DISCONNECT
+
+at 0x000001f6 : */	0x48000000,0x00000000,
 /*
     INT int_norm_aborted
 
-at 0x000001ec : */	0x98080000,0x02040000,
+at 0x000001f8 : */	0x98080000,0x02040000,
 /*
 
 ;
@@ -1711,77 +1742,101 @@
 dsa_to_scratch:
     MOVE DSA0 TO SFBR
 
-at 0x000001ee : */	0x72100000,0x00000000,
+at 0x000001fa : */	0x72100000,0x00000000,
 /*
     MOVE SFBR TO SCRATCH0
 
-at 0x000001f0 : */	0x6a340000,0x00000000,
+at 0x000001fc : */	0x6a340000,0x00000000,
 /*
     MOVE DSA1 TO SFBR
 
-at 0x000001f2 : */	0x72110000,0x00000000,
+at 0x000001fe : */	0x72110000,0x00000000,
 /*
     MOVE SFBR TO SCRATCH1
 
-at 0x000001f4 : */	0x6a350000,0x00000000,
+at 0x00000200 : */	0x6a350000,0x00000000,
 /*
     MOVE DSA2 TO SFBR
 
-at 0x000001f6 : */	0x72120000,0x00000000,
+at 0x00000202 : */	0x72120000,0x00000000,
 /*
     MOVE SFBR TO SCRATCH2
 
-at 0x000001f8 : */	0x6a360000,0x00000000,
+at 0x00000204 : */	0x6a360000,0x00000000,
 /*
     MOVE DSA3 TO SFBR
 
-at 0x000001fa : */	0x72130000,0x00000000,
+at 0x00000206 : */	0x72130000,0x00000000,
 /*
     MOVE SFBR TO SCRATCH3
 
-at 0x000001fc : */	0x6a370000,0x00000000,
+at 0x00000208 : */	0x6a370000,0x00000000,
 /*
     RETURN
 
-at 0x000001fe : */	0x90080000,0x00000000,
+at 0x0000020a : */	0x90080000,0x00000000,
 /*
 
 scratch_to_dsa:
     MOVE SCRATCH0 TO SFBR
 
-at 0x00000200 : */	0x72340000,0x00000000,
+at 0x0000020c : */	0x72340000,0x00000000,
 /*
     MOVE SFBR TO DSA0
 
-at 0x00000202 : */	0x6a100000,0x00000000,
+at 0x0000020e : */	0x6a100000,0x00000000,
 /*
     MOVE SCRATCH1 TO SFBR
 
-at 0x00000204 : */	0x72350000,0x00000000,
+at 0x00000210 : */	0x72350000,0x00000000,
 /*
     MOVE SFBR TO DSA1
 
-at 0x00000206 : */	0x6a110000,0x00000000,
+at 0x00000212 : */	0x6a110000,0x00000000,
 /*
     MOVE SCRATCH2 TO SFBR
 
-at 0x00000208 : */	0x72360000,0x00000000,
+at 0x00000214 : */	0x72360000,0x00000000,
 /*
     MOVE SFBR TO DSA2
 
-at 0x0000020a : */	0x6a120000,0x00000000,
+at 0x00000216 : */	0x6a120000,0x00000000,
 /*
     MOVE SCRATCH3 TO SFBR
 
-at 0x0000020c : */	0x72370000,0x00000000,
+at 0x00000218 : */	0x72370000,0x00000000,
 /*
     MOVE SFBR TO DSA3
 
-at 0x0000020e : */	0x6a130000,0x00000000,
+at 0x0000021a : */	0x6a130000,0x00000000,
 /*
     RETURN
 
-at 0x00000210 : */	0x90080000,0x00000000,
+at 0x0000021c : */	0x90080000,0x00000000,
+};
+
+#define A_NCR53c7xx_msg_abort	0x00000000
+unsigned long A_NCR53c7xx_msg_abort_used[] = {
+	0x000001f5,
+};
+
+#define A_NCR53c7xx_msg_reject	0x00000000
+unsigned long A_NCR53c7xx_msg_reject_used[] = {
+	0x00000133,
+};
+
+#define A_NCR53c7xx_sink	0x00000000
+unsigned long A_NCR53c7xx_sink_used[] = {
+	0x000001e5,
+	0x000001e9,
+	0x000001ed,
+};
+
+#define A_NCR53c7xx_zero	0x00000000
+unsigned long A_NCR53c7xx_zero_used[] = {
+	0x0000015d,
+	0x000001e1,
+	0x000001f1,
 };
 
 #define A_addr_scratch	0x00000000
@@ -1940,7 +1995,7 @@
 
 #define A_int_debug_break	0x03000000
 unsigned long A_int_debug_break_used[] = {
-	0x000001cb,
+	0x000001d3,
 };
 
 #define A_int_debug_dsa_loaded	0x03030000
@@ -2013,7 +2068,7 @@
 
 #define A_int_norm_aborted	0x02040000
 unsigned long A_int_norm_aborted_used[] = {
-	0x000001ed,
+	0x000001f9,
 };
 
 #define A_int_norm_command_complete	0x02020000
@@ -2038,12 +2093,12 @@
 
 #define A_int_test_1	0x04000000
 unsigned long A_int_test_1_used[] = {
-	0x000001b1,
+	0x000001b9,
 };
 
 #define A_int_test_2	0x04010000
 unsigned long A_int_test_2_used[] = {
-	0x000001c9,
+	0x000001d1,
 };
 
 #define A_int_test_3	0x04020000
@@ -2087,26 +2142,26 @@
 
 #define A_test_dest	0x00000000
 unsigned long A_test_dest_used[] = {
-	0x000001af,
+	0x000001b7,
 };
 
 #define A_test_src	0x00000000
 unsigned long A_test_src_used[] = {
-	0x000001ae,
+	0x000001b6,
 };
 
 #define Ent_accept_message	0x000004d8
 #define Ent_cmdout_cmdout	0x0000022c
 #define Ent_command_complete	0x00000508
 #define Ent_command_complete_msgin	0x00000518
-#define Ent_debug_break	0x00000728
+#define Ent_debug_break	0x00000748
 #define Ent_dsa_code_check_reselect	0x00000038
 #define Ent_dsa_code_template	0x00000000
 #define Ent_dsa_code_template_end	0x000000b4
 #define Ent_dsa_jump_resume	0x00000088
 #define Ent_dsa_schedule	0x000000b4
 #define Ent_dsa_zero	0x00000090
-#define Ent_initiator_abort	0x00000750
+#define Ent_initiator_abort	0x00000770
 #define Ent_msg_in	0x00000354
 #define Ent_other_transfer	0x0000031c
 #define Ent_reject_message	0x000004b8
@@ -2115,10 +2170,10 @@
 #define Ent_schedule	0x00000130
 #define Ent_select	0x00000194
 #define Ent_select_msgout	0x000001ac
-#define Ent_target_abort	0x00000730
-#define Ent_test_1	0x000006b4
-#define Ent_test_2	0x000006c8
-#define Ent_test_2_msgout	0x000006e0
+#define Ent_target_abort	0x00000750
+#define Ent_test_1	0x000006d4
+#define Ent_test_2	0x000006e8
+#define Ent_test_2_msgout	0x00000700
 unsigned long LABELPATCHES[] = {
 	0x00000002,
 	0x0000000b,
@@ -2178,18 +2233,21 @@
 	0x0000017a,
 	0x00000191,
 	0x000001a2,
-	0x000001a4,
+	0x000001a6,
 	0x000001a8,
 	0x000001ac,
-	0x000001b5,
-	0x000001b7,
-	0x000001d3,
-	0x000001d7,
+	0x000001b0,
+	0x000001b2,
+	0x000001b4,
+	0x000001bd,
+	0x000001bf,
 	0x000001db,
 	0x000001df,
 	0x000001e3,
 	0x000001e7,
+	0x000001eb,
+	0x000001ef,
 };
 
-unsigned long INSTRUCTIONS	= 0x000000fe;
-unsigned long PATCHES	= 0x00000045;
+unsigned long INSTRUCTIONS	= 0x00000104;
+unsigned long PATCHES	= 0x00000048;
diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/53c8xx_u.h linux/drivers/scsi/53c8xx_u.h
--- v1.2.5/linux/drivers/scsi/53c8xx_u.h	Tue Aug  2 11:29:17 1994
+++ linux/drivers/scsi/53c8xx_u.h	Mon Apr 17 13:48:24 1995
@@ -1,3 +1,7 @@
+#undef A_NCR53c7xx_msg_abort
+#undef A_NCR53c7xx_msg_reject
+#undef A_NCR53c7xx_sink
+#undef A_NCR53c7xx_zero
 #undef A_addr_scratch
 #undef A_addr_sfbr
 #undef A_addr_temp
diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/ChangeLog linux/drivers/scsi/ChangeLog
--- v1.2.5/linux/drivers/scsi/ChangeLog	Tue Jan 31 09:39:01 1995
+++ linux/drivers/scsi/ChangeLog	Fri Apr 21 08:51:27 1995
@@ -1,3 +1,296 @@
+Wed Apr 12 15:25:52 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.5 released.
+
+	* buslogic.c: Update to version 1.15 (From Dave G, I expect).
+	Fixed interrupt routine to avoid races when handling multiple
+	complete commands per interrupt.  Seems to come up with faster
+	cards.
+
+	* eata_dma.c: Modularize.  Update to 2.3.5r.
+
+	* scsi.c: If we get a FMK, EOM, or ILI when attempting to scan
+	the bus, assume that it was just noise on the bus, and ignore
+	the device.
+
+	* scsi.h: Update and add a bunch of missing commands which we
+	were never using.
+
+	* sd.c: Use restore_flags in do_sd_request - this may result in
+	latency conditions, but it gets rid of races and crashes.
+	Do not save flags again when searching for a second command to
+	queue.
+
+	* st.c: Use bytes, not STP->buffer->buffer_size when reading
+	from tape.
+
+
+Tue Apr  4 09:42:08 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.4 released.
+
+	* st.c: Fix typo - restoring wrong flags.
+
+Wed Mar 29 06:55:12 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.3 released.
+
+	* st.c: Perform some waiting operations with interrupts off.
+	Is this correct???
+
+Wed Mar 22 10:34:26 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.2 released.
+
+	* aha152x.c: Modularize.  Add support for PCMCIA.
+
+	* eata.c: Update to version 2.0.  Fixed bug preventing media
+	detection.  If scsi_register_host returns NULL, fail gracefully.
+
+	* scsi.c: Detect as NEC (for photo-cd purposes) for the 84
+	and 25 models as "NEC_OLDCDR".
+
+	* scsi.h: Add define for NEC_OLDCDR
+
+	* sr.c: Add handling for NEC_OLDCDR.  Treat as unknown.
+
+	* u14-34f.c: Update to version 2.0.  Fixed same bug as in
+	eata.c.
+
+
+Mon Mar  6 11:11:20 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.0 released.  Yeah!!!
+
+	* Minor spelling/punctuation changes throughout.  Nothing
+	substantive.
+
+Mon Feb 20 21:33:03 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.95 released.
+
+	* qlogic.c: Update to version 0.41.
+
+	* seagate.c: Change some message to be more descriptive about what
+	we detected.
+
+	* sr.c: spelling/whitespace changes.
+
+Mon Feb 20 21:33:03 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.94 released.
+
+Mon Feb 20 08:57:17 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.93 released.
+
+	* hosts.h: Change io_port to long int from short.
+
+	* 53c7,8xx.c: crash on AEN fixed, SCSI reset is no longer a NOP,
+	  NULL pointer panic on odd UDCs fixed, two bugs in diagnostic output 
+	  fixed, should initialize correctly if left running, now loadable, 
+ 	  new memory allocation, extraneous diagnostic output supressed,
+	  splx() replaced with save/restore flags. [ Drew ]
+
+	* hosts.c, hosts.h, scsi_ioctl.c, sd.c, sd_ioctl.c, sg.c, sr.c,
+	sr_ioctl.c: Add special junk at end that Emacs will use for
+	formatting the file.
+
+	* qlogic.c: Update to v0.40a.  Improve parity handling.
+
+	* scsi.c: Add Hitachi DK312C to blacklist.  Change "};" to "}" in
+	many places.  Use scsi_init_malloc to get command block - may
+	need this to be dma compatible for some host adapters.
+	Restore interrupts after unregistering a host.
+
+	* sd.c: Use sti instead of restore flags - causes latency problems.
+
+	* seagate.c: Use controller_type to determine string used when
+	registering irq.
+
+	* sr.c: More photo-cd hacks to make sure we get the xa stuff right.
+	* sr.h, sr.c: Change is_xa to xa_flags field.
+
+	* st.c: Diable retries for write operations.
+
+Wed Feb 15 10:52:56 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.92 released.
+
+	* eata.c: Update to 1.17.
+
+	* eata_dma.c: Add more support for /proc/scsi, add HBA_interpret flag.
+
+	* hosts.c: If we remove last host registered, reuse host number.
+	When freeing memory from host being deregistered, free extra_bytes
+	too.
+
+	* scsi.c (scan_scsis): memset(SDpnt, 0) and set SCmd.device to SDpnt.
+	Change memory allocation to work around bugs in __get_dma_pages.
+	Do not free host if usage count is not zero (for modules).
+
+	* sr_ioctl.c: Increase IOCTL_TIMEOUT to 3000.
+
+	* st.c: Allow for ST_EXTRA_DEVS in st data structures.
+
+	* u14-34f.c: Update to 1.17.
+
+Thu Feb  9 10:11:16 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.91 released.
+
+	* eata.c: Update to 1.16.  Use wish_block instead of host->block.
+
+	* hosts.c: Initialize wish_block to 0.
+
+	* hosts.h: Add wish_block.
+
+	* scsi.c: Use wish_block as indicator that the host should be added
+	to block list.
+
+	* sg.c: Add SG_EXTRA_DEVS to number of slots.
+
+	* u14-34f.c: Use wish_block.
+
+Tue Feb  7 11:46:04 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.90 released.
+
+	* eata.c: Change naming from eata_* to eata2x_*.  Now at vers 1.15.
+	Update interrupt handler to take pt_regs as arg.  Allow blocking
+	even if loaded as module.  Initialize target_time_out array.
+	Do not put sti(); in timing loop.
+
+	* hosts.c: Do not reuse host numbers.
+	Use scsi_make_blocked_list to generate blocking list.
+
+	* script_asm.pl:  Beats me.  Don't know perl.  Something to do with
+	phase index.
+
+	* scsi.c (scsi_make_blocked_list): New function - code copied from
+	hosts.c.
+
+	* scsi.c: Update code to disable photo CD for Toshiba cdroms.
+	Use just manufacturer name, not model number.
+
+	* sr.c: Fix setting density for Toshiba drives.
+
+	* u14-34f.c: Clear target_time_out array during reset.
+
+Wed Feb  1 09:20:45 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.89 released.
+
+	* Makefile, u14-34f.c: Modulariz.e
+
+	* Makefile, eata.c: Modularize.  Now version 1.14
+
+	* NCR5380.c: Update interrupt handler with new arglist.  Minor
+	cleanups.
+
+	* eata_dma.c: Modularize.  Add hooks for /proc/scsi.  
+	New version 2.3.0a.
+	
+	* hosts.c: Initialize ->dma_channel and ->io_port when registering
+	a new host.
+
+	* qlogic.c: Modularize and add PCMCIA support.
+
+	* scsi.c: Add Hitachi to blacklist.
+
+	* scsi.c: Change default to no lun scan (too many problem devices).
+
+	* scsi.h: Define QUEUE_FULL condition.
+
+	* sd.c: Do not check for non-existant partition until after
+	new media check.
+
+	* sg.c: Undo previous change which was wrong.
+
+	* sr_ioctl.c: Increase IOCTL_TIMEOUT to 2000.
+
+	* st.c: Patches from Kai - improve filemark handling.
+
+Tue Jan 31 17:32:12 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.88 released.
+
+	* Throughout - spelling/grammar fixups.
+
+	* scsi.c: Make sure that all buffers are 16 byte aligned - some
+	drivers (buslogic) need this.
+
+	* scsi.c (scan_scsis): Remove message printed.
+
+	* scsi.c (scsi_init): Move message here.
+
+Mon Jan 30 06:40:25 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.87 released.
+
+	* sr.c: Photo-cd related changes. (Gerd Knorr??).
+
+	* st.c: Changes from Kai related to EOM detection.
+
+Mon Jan 23 23:53:10 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.86 released.
+
+	* 53c7,8xx.h: Change SG size to 127.
+
+	* eata_dma: Update to version 0i.
+
+	* scsi.c: Test for Toshiba XM-3401TA and exclude from detection
+	as toshiba drive - photo cd does not work with this drive.
+
+	* sr.c:  Update photocd code.
+
+Mon Jan 23 23:53:10 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.85 released.
+
+	* st.c, st_ioctl.c, sg.c, sd_ioctl.c, scsi_ioctl.c, hosts.c:
+	include linux/mm.h
+
+	* qlogic.c, buslogic.c, aha1542.c: Include linux/module.h.
+
+Sun Jan 22 22:08:46 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.84 released.
+
+	* Makefile: Support for loadable QLOGIC boards.
+
+	* aha152x.c: Update to version 1.8 from Juergen.
+
+	* eata_dma.c: Update from Michael Neuffer
+
+	* in2000.c: Fix biosparam to support large disks.
+
+	* qlogic.c: Minor changes (change sti -> restore_flags).
+
+Wed Jan 18 23:33:09 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.83 released.
+
+	* aha1542.c(aha1542_intr_handle): Use arguments handed down to find
+	which irq.
+
+	* buslogic.c: Likewise.
+
+	* eata_dma.c: Use min of 2 cmd_per_lun for OCS_enabled boards.
+
+	* scsi.c: Make RECOVERED_ERROR a SUGGEST_IS_OK.
+
+	* sd.c: Fail if we are opening a non-existant partition.
+
+	* sr.c: Bump SR_TIMEOUT to 15000.
+	Do not probe for media size at boot time(hard on changers).
+	Flag device as needing sector size instead.
+
+	* sr_ioctl.c: Remove CDROMMULTISESSION_SYS ioctl.
+
+	* ultrastor.c: Fix bug in call to ultrastor_interrupt (wrong #args).
+
 Mon Jan 16 07:18:23 1995  Eric Youngdale  (eric@andante)
 
 	* Linux 1.1.82 released.
diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile
--- v1.2.5/linux/drivers/scsi/Makefile	Fri Apr 14 12:02:42 1995
+++ linux/drivers/scsi/Makefile	Mon Apr 17 13:53:22 1995
@@ -127,6 +127,8 @@
 ifdef CONFIG_SCSI_NCR53C7xx
 SCSI_OBJS := $(SCSI_OBJS) 53c7,8xx.o 
 SCSI_SRCS := $(SCSI_SRCS) 53c7,8xx.c
+else
+SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) 53c7,8xx.o
 endif
 
 ifdef CONFIG_SCSI_PAS16
@@ -190,7 +192,7 @@
 
 53c8xx_d.h 53c8xx_u.h : 53c7,8xx.scr script_asm.pl
 	ln 53c7,8xx.scr fake.c
-	$(CPP) -DCHIP=810 fake.c | grep -v ^# | perl script_asm.pl 
+	$(CPP) -traditional -DCHIP=810 fake.c | grep -v '^#' | perl script_asm.pl 
 	mv script.h 53c8xx_d.h
 	mv scriptu.h 53c8xx_u.h
 	rm fake.c
diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/buslogic.c linux/drivers/scsi/buslogic.c
--- v1.2.5/linux/drivers/scsi/buslogic.c	Fri Apr 14 12:02:42 1995
+++ linux/drivers/scsi/buslogic.c	Sun Apr 23 19:18:13 1995
@@ -469,10 +469,7 @@
     interrupt_flags = inb(INTERRUPT(base));
 
     if (!(interrupt_flags & INTV))
-      {
-	buslogic_printk("interrupt received, but INTV not set\n");
-	return;
-      }
+      buslogic_printk("interrupt received, but INTV not set\n");
 
     /*
       Reset the Host Adapter Interrupt Register.  It appears to be
@@ -504,16 +501,27 @@
     while (mb[mbi].status != MBX_NOT_IN_USE && found < BUSLOGIC_MAILBOXES)
       {
 	int mbo = (struct ccb *)mb[mbi].ccbptr - ccb;
-	int result = 0;
 
-	saved_mbo[found++] = mbo;
+	sctmp = HOSTDATA(shpnt)->sc[mbo];
+
+	/*
+	  If sctmp has become NULL, higher level code must have aborted
+	  this operation and called the necessary completion routine.
+	*/
+
+	if (sctmp != NULL && mb[mbi].status != MBX_COMPLETION_NOT_FOUND)
+	  {
+	    int result = 0;
+
+	    saved_mbo[found++] = mbo;
 
-	if (mb[mbi].status != MBX_COMPLETION_OK)
-	  result = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
+	    if (mb[mbi].status != MBX_COMPLETION_OK)
+	      result = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
 
-	HOSTDATA(shpnt)->sc[mbo]->result = result;
+	    sctmp->result = result;
 
-	mb[mbi].status = MBX_NOT_IN_USE;
+	    mb[mbi].status = MBX_NOT_IN_USE;
+	  }
 
 	HOSTDATA(shpnt)->last_mbi_used = mbi;
 
@@ -535,6 +543,7 @@
       {
 	int mbo = saved_mbo[i];
 	sctmp = HOSTDATA(shpnt)->sc[mbo];
+	if (sctmp == NULL) continue;
 	/*
 	  First, free any storage allocated for a scatter/gather
 	  data segment list.
@@ -542,14 +551,15 @@
 	if (sctmp->host_scribble)
 	  scsi_free(sctmp->host_scribble, BUSLOGIC_SG_MALLOC);
 	/*
-	  Next, call the SCSI command completion handler.
+	  Next, mark the SCSI Command as completed so it may be reused
+	  for another command by buslogic_queuecommand.  This also signals
+	  to buslogic_reset that the command is no longer active.
 	*/
-	sctmp->scsi_done(sctmp);
+	HOSTDATA(shpnt)->sc[mbo] = NULL;
 	/*
-	  Finally, mark the SCSI Command as completed so it may be reused
-	  for another command by buslogic_queuecommand.
+	  Finally, call the SCSI command completion handler.
 	*/
-	HOSTDATA(shpnt)->sc[mbo] = NULL;
+	sctmp->scsi_done(sctmp);
       }
 }
 
@@ -1344,7 +1354,7 @@
 #if 1
     static const unsigned char buscmd[] = { CMD_START_SCSI };
     struct mailbox *mb;
-    size_t mbi, mbo;
+    int mbi, mbo, last_mbi;
     unsigned long flags;
     unsigned int i;
 
@@ -1355,28 +1365,30 @@
     save_flags(flags);
     cli();
     mb = HOSTDATA(scpnt->host)->mb;
-    mbi = HOSTDATA(scpnt->host)->last_mbi_used + 1;
+    last_mbi = HOSTDATA(scpnt->host)->last_mbi_used;
+    mbi = last_mbi + 1;
     if (mbi >= 2 * BUSLOGIC_MAILBOXES)
 	mbi = BUSLOGIC_MAILBOXES;
 
     do {
 	if (mb[mbi].status != MBX_NOT_IN_USE)
 	    break;
+	last_mbi = mbi;
 	mbi++;
 	if (mbi >= 2 * BUSLOGIC_MAILBOXES)
 	    mbi = BUSLOGIC_MAILBOXES;
     } while (mbi != HOSTDATA(scpnt->host)->last_mbi_used);
-    restore_flags(flags);
 
     if (mb[mbi].status != MBX_NOT_IN_USE) {
-	buslogic_printk("lost interrupt discovered on irq %d"
+	buslogic_printk("lost interrupt discovered on irq %d, "
 			" - attempting to recover...\n",
 			scpnt->host->irq);
-	{
-	    buslogic_interrupt(scpnt->host->irq, NULL);
-	    return SCSI_ABORT_SUCCESS;
-	}
+	HOSTDATA(scpnt->host)->last_mbi_used = last_mbi;
+	buslogic_interrupt(scpnt->host->irq, NULL);
+	restore_flags(flags);
+	return SCSI_ABORT_SUCCESS;
     }
+    restore_flags(flags);
 
     /* OK, no lost interrupt.  Try looking to see how many pending commands we
        think we have. */
diff -u --recursive --new-file v1.2.5/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c
--- v1.2.5/linux/drivers/scsi/eata_dma.c	Fri Apr 14 12:02:42 1995
+++ linux/drivers/scsi/eata_dma.c	Fri Apr 14 12:01:41 1995
@@ -710,7 +710,7 @@
 	    while (inb((uint) base + HA_RSTATUS) & HA_SDRQ) 
 	        inw((uint) base + HA_RDATA);
             if (warning == TRUE)
-                printk("Warning: HBA with IO on 0x%p dectected,\n"
+                printk("Warning: HBA with IO on 0x%p detected,\n"
                        "         this IO space is already allocated, probably by the IDE driver.\n"
                        "         This might lead to problems.", base);
  	    return (TRUE);
diff -u --recursive --new-file v1.2.5/linux/fs/nfs/file.c linux/fs/nfs/file.c
--- v1.2.5/linux/fs/nfs/file.c	Mon Jan 23 10:38:29 1995
+++ linux/fs/nfs/file.c	Mon Apr 17 13:41:26 1995
@@ -123,7 +123,7 @@
 		if ((cache[i].inode_num == inode->i_ino)
 			&& (cache[i].file_pos <= pos)
 			&& (cache[i].file_pos + cache[i].len >= pos + count)
-			&& (abs(jiffies - cache[i].time) <= EXPIRE_CACHE))
+			&& (abs(jiffies - cache[i].time) < EXPIRE_CACHE))
 			break;
 	if (i < READ_CACHE_SIZE) {
 		++cache[i].in_use;
diff -u --recursive --new-file v1.2.5/linux/fs/select.c linux/fs/select.c
--- v1.2.5/linux/fs/select.c	Mon Jan 23 23:04:10 1995
+++ linux/fs/select.c	Tue Apr 18 08:57:32 1995
@@ -237,11 +237,10 @@
 	}
 	current->timeout = timeout;
 	i = do_select(n, &in, &out, &ex, &res_in, &res_out, &res_ex);
-	if (current->timeout > jiffies)
-		timeout = current->timeout - jiffies;
-	else
-		timeout = 0;
+	timeout = current->timeout - jiffies - 1;
 	current->timeout = 0;
+	if ((long) timeout < 0)
+		timeout = 0;
 	if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
 		put_fs_long(timeout/HZ, (unsigned long *) &tvp->tv_sec);
 		timeout %= HZ;
diff -u --recursive --new-file v1.2.5/linux/include/asm-alpha/byteorder.h linux/include/asm-alpha/byteorder.h
--- v1.2.5/linux/include/asm-alpha/byteorder.h	Tue Feb 21 09:05:02 1995
+++ linux/include/asm-alpha/byteorder.h	Mon Apr 17 13:47:56 1995
@@ -6,6 +6,9 @@
 #undef htonl
 #undef htons
 
+#define LITTLE_ENDIAN
+#define LITTLE_ENDIAN_BITFIELD
+
 extern unsigned long int	ntohl(unsigned long int);
 extern unsigned short int	ntohs(unsigned short int);
 extern unsigned long int	htonl(unsigned long int);
diff -u --recursive --new-file v1.2.5/linux/include/asm-i386/byteorder.h linux/include/asm-i386/byteorder.h
--- v1.2.5/linux/include/asm-i386/byteorder.h	Tue Feb 21 09:02:02 1995
+++ linux/include/asm-i386/byteorder.h	Mon Apr 17 13:47:56 1995
@@ -6,6 +6,9 @@
 #undef htonl
 #undef htons
 
+#define LITTLE_ENDIAN 1234
+#define LITTLE_ENDIAN_BITFIELD
+
 extern unsigned long int	ntohl(unsigned long int);
 extern unsigned short int	ntohs(unsigned short int);
 extern unsigned long int	htonl(unsigned long int);
diff -u --recursive --new-file v1.2.5/linux/include/asm-mips/byteorder.h linux/include/asm-mips/byteorder.h
--- v1.2.5/linux/include/asm-mips/byteorder.h	Sat Jan 14 02:27:06 1995
+++ linux/include/asm-mips/byteorder.h	Mon Apr 17 13:47:56 1995
@@ -6,6 +6,16 @@
 #undef htonl
 #undef htons
 
+#ifdef MIPSEL
+#define LITTLE_ENDIAN
+#define LITTLE_ENDIAN_BITFIELD
+#elif MIPSEB
+#define BIG_ENDIAN
+#define BIG_ENDIAN_BITFIELD
+#else
+#error "MIPS but neither MIPSEL nor MIPSEB?"
+#endif
+
 extern unsigned long int	ntohl(unsigned long int);
 extern unsigned short int	ntohs(unsigned short int);
 extern unsigned long int	htonl(unsigned long int);
diff -u --recursive --new-file v1.2.5/linux/include/asm-sparc/byteorder.h linux/include/asm-sparc/byteorder.h
--- v1.2.5/linux/include/asm-sparc/byteorder.h	Thu Feb  2 08:42:35 1995
+++ linux/include/asm-sparc/byteorder.h	Mon Apr 17 13:47:56 1995
@@ -6,6 +6,9 @@
 #undef htonl
 #undef htons
 
+#define BIG_ENDIAN
+#define BIG_ENDIAN_BITFIELD
+
 extern unsigned long int	ntohl(unsigned long int);
 extern unsigned short int	ntohs(unsigned short int);
 extern unsigned long int	htonl(unsigned long int);
diff -u --recursive --new-file v1.2.5/linux/include/linux/bios32.h linux/include/linux/bios32.h
--- v1.2.5/linux/include/linux/bios32.h	Fri Feb  3 19:28:28 1995
+++ linux/include/linux/bios32.h	Mon Apr 17 13:48:18 1995
@@ -48,5 +48,5 @@
     unsigned char device_fn, unsigned char where, unsigned short value);
 extern pcibios_write_config_dword (unsigned char bus,
     unsigned char device_fn, unsigned char where, unsigned long value);
-
+extern char *pcibios_strerror (int error);
 #endif /* ndef BIOS32_H */
diff -u --recursive --new-file v1.2.5/linux/include/linux/ip.h linux/include/linux/ip.h
--- v1.2.5/linux/include/linux/ip.h	Mon Feb 20 08:59:52 1995
+++ linux/include/linux/ip.h	Mon Apr 17 13:47:56 1995
@@ -16,7 +16,7 @@
  */
 #ifndef _LINUX_IP_H
 #define _LINUX_IP_H
-
+#include <asm/byteorder.h>
 
 #define IPOPT_END	0
 #define IPOPT_NOOP	1
@@ -34,26 +34,14 @@
 	__u8	len;
 	__u8	ptr;
 	union {
-#if defined(__i386__)
-	__u8	flags:4,
-		overflow:4;
-#elif defined(__mc68000__)
-	__u8	overflow:4,
-		flags:4;
-#elif defined(__MIPSEL__) 
-	__u8	flags:4,
-		overflow:4;
-#elif defined(__MIPSEB__)
-	__u8	overflow:4,
-		flags:4;
-#elif defined(__alpha__)
+#if defined(LITTLE_ENDIAN_BITFIELD)
 	__u8	flags:4,
 		overflow:4;
-#elif defined(__sparc__)
+#elif defined(BIG_ENDIAN_BITFIELD)
 	__u8	overflow:4,
 		flags:4;
 #else
-#error	"Adjust this structure to match your CPU"
+#error	"Please fix <asm/byteorder.h>"
 #endif						
 	__u8	full_char;
 	} x;
@@ -84,26 +72,14 @@
 
 
 struct iphdr {
-#if defined(__i386__)
-	__u8	ihl:4,
-		version:4;
-#elif defined (__mc68000__)
-	__u8	version:4,
-  		ihl:4;
-#elif defined(__MIPSEL__)
-	__u8	ihl:4,
-		version:4;
-#elif defined(__MIPSEB__)
-	__u8	version:4,
-  		ihl:4;
-#elif defined(__alpha__)
+#if defined(LITTLE_ENDIAN_BITFIELD)
 	__u8	ihl:4,
 		version:4;
-#elif defined (__sparc__)
+#elif defined (BIG_ENDIAN_BITFIELD)
 	__u8	version:4,
   		ihl:4;
 #else
-#error "Adjust this structure to match your CPU"
+#error	"Please fix <asm/byteorder.h>"
 #endif
 	__u8	tos;
 	__u16	tot_len;
diff -u --recursive --new-file v1.2.5/linux/include/linux/tcp.h linux/include/linux/tcp.h
--- v1.2.5/linux/include/linux/tcp.h	Mon Feb 20 08:59:52 1995
+++ linux/include/linux/tcp.h	Mon Apr 17 13:47:56 1995
@@ -26,7 +26,7 @@
 	__u16	dest;
 	__u32	seq;
 	__u32	ack_seq;
-#if defined(__i386__)
+#if defined(LITTLE_ENDIAN_BITFIELD)
 	__u16	res1:4,
 		doff:4,
 		fin:1,
@@ -36,47 +36,7 @@
 		ack:1,
 		urg:1,
 		res2:2;
-#elif defined(__mc68000__)
-	__u16	res2:2,
-		urg:1,
-		ack:1,
-		psh:1,
-		rst:1,
-		syn:1,
-		fin:1,
-		doff:4,
-		res1:4;
-#elif defined(__MIPSEL__)
-	__u16	res1:4,
-		doff:4,
-		fin:1,
-		syn:1,
-		rst:1,
-		psh:1,
-		ack:1,
-		urg:1,
-		res2:2;
-#elif defined(__MIPSEB__)
-	__u16	res2:2,
-		urg:1,
-		ack:1,
-		psh:1,
-		rst:1,
-		syn:1,
-		fin:1,
-		doff:4,
-		res1:4;
-#elif defined(__alpha__)
-	__u16	res1:4,
-		doff:4,
-		fin:1,
-		syn:1,
-		rst:1,
-		psh:1,
-		ack:1,
-		urg:1,
-		res2:2;
-#elif defined(__sparc__)
+#elif defined(BIG_ENDIAN_BITFIELD)
 	__u16	res2:2,
 		urg:1,
 		ack:1,
@@ -87,7 +47,7 @@
 		doff:4,
 		res1:4;
 #else
-#error	"Adjust this structure for your cpu alignment rules"
+#error	"Adjust your <asm/byteorder.h> defines"
 #endif	
 	__u16	window;
 	__u16	check;
diff -u --recursive --new-file v1.2.5/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v1.2.5/linux/kernel/ksyms.c	Fri Apr 14 12:02:43 1995
+++ linux/kernel/ksyms.c	Mon Apr 17 13:48:23 1995
@@ -34,9 +34,10 @@
 #include <linux/delay.h>
 #include <linux/config.h>
 
-#ifdef CONFIG_INET
+#ifdef CONFIG_NET
 #include <linux/net.h>
 #include <linux/netdevice.h>
+#ifdef CONFIG_INET
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include "../net/inet/protocol.h"
@@ -45,6 +46,7 @@
 #include "../drivers/net/slhc.h"
 #endif
 #endif
+#endif
 #ifdef CONFIG_PCI
 #include <linux/pci.h>
 #endif
@@ -105,6 +107,7 @@
 	X(pcibios_read_config_byte),
 	X(pcibios_read_config_word),
 	X(pcibios_read_config_dword),
+    	X(pcibios_strerror),
 	X(pcibios_write_config_byte),
 	X(pcibios_write_config_word),
 	X(pcibios_write_config_dword),
@@ -277,6 +280,7 @@
 	X(inet_add_protocol),
 	X(inet_del_protocol),
 #if defined(CONFIG_PPP) || defined(CONFIG_SLIP)
+    	/* VJ header compression */
 	X(slhc_init),
 	X(slhc_free),
 	X(slhc_remember),
@@ -321,6 +325,11 @@
 #endif
 #ifdef CONFIG_SCSI
 	/* Supports loadable scsi drivers */
+    	/* 
+ 	 * in_scan_scsis is a hack, and should go away once the new 
+	 * memory allocation code is in the NCR driver 
+	 */
+    	X(in_scan_scsis),
 	X(scsi_register_module),
 	X(scsi_unregister_module),
 	X(scsi_free),
@@ -331,6 +340,8 @@
         X(scsi_init_malloc),
         X(scsi_init_free),
 	X(print_command),
+    	X(print_msg),
+	X(print_status),
 #endif
 	/* Added to make file system as module */
 	X(set_writetime),
diff -u --recursive --new-file v1.2.5/linux/mm/swap.c linux/mm/swap.c
--- v1.2.5/linux/mm/swap.c	Sun Apr  9 11:59:57 1995
+++ linux/mm/swap.c	Fri Apr 21 13:41:36 1995
@@ -523,7 +523,7 @@
 	int loop, counter;
 	struct task_struct *p;
 
-	counter = 2*nr_tasks >> priority;
+	counter = 6*nr_tasks >> priority;
 	for(; counter >= 0; counter--) {
 		/*
 		 * Check that swap_task is suitable for swapping.  If not, look for
@@ -605,7 +605,7 @@
 			if (swap_out(i))
 				return 1;
 			state = 0;
-		} while(--i);
+		} while(i--);
 	}
 	return 0;
 }
