--- 1.1	1994/06/20 19:44:23
+++ ./init/main.c	1994/06/23 17:25:44
@@ -78,6 +78,7 @@
 extern void sock_init(void);
 extern long rd_init(long mem_start, int length);
 unsigned long net_dev_init(unsigned long, unsigned long);
+extern long bios32_init(long, long);
 
 extern void hd_setup(char *str, int *ints);
 extern void bmouse_setup(char *str, int *ints);
@@ -405,6 +406,7 @@
 	prof_len >>= 2;
 	memory_start += prof_len * sizeof(unsigned long);
 #endif
+	memory_start = bios32_init(memory_start,memory_end);
 	memory_start = kmalloc_init(memory_start,memory_end);
 	memory_start = chr_dev_init(memory_start,memory_end);
 	memory_start = blk_dev_init(memory_start,memory_end);
--- 1.1	1994/06/20 19:44:15
+++ ./kernel/Makefile	1994/06/23 17:25:44
@@ -19,7 +19,7 @@
 OBJS  = sched.o sys_call.o traps.o irq.o dma.o fork.o \
  	panic.o printk.o vsprintf.o sys.o module.o ksyms.o exit.o \
 	signal.o ptrace.o ioport.o itimer.o \
-	info.o ldt.o time.o tqueue.o vm86.o
+	info.o ldt.o time.o tqueue.o vm86.o bios32.o splx.o
 
 all: kernel.o
 
--- 1.1	1994/06/20 21:47:57
+++ ./include/linux/kernel.h	1994/06/23 17:25:44
@@ -62,7 +62,7 @@
  * permissions checks first, and check suser() last.
  */
 #define suser() (current->euid == 0)
-
+extern int splx (int new_ipl);
 #endif /* __KERNEL__ */
 
 #define SI_LOAD_SHIFT	16
--- 1.1	1994/06/20 19:45:19
+++ ./drivers/scsi/g_NCR5380.c	1994/06/23 17:25:44
@@ -1,4 +1,5 @@
 #define AUTOSENSE
+#define NCR53C400
 
 /*
  * Generic Generic NCR5380 driver
@@ -43,9 +44,9 @@
  *     used on the LILO command line to override the defaults.
  *
  * 2.  With the GENERIC_NCR5380_OVERRIDE compile time define.  This is 
- *     specified as an array of address, irq tupples.  Ie, for
- *     one board at the default 0xcc000 address, IRQ5, no dma, I could 
- *     say  -DGENERIC_NCR5380_OVERRIDE={{0xcc000, 5, DMA_NONE}}
+ *     specified as an array of address, irq, dma, board tupples.  Ie, for
+ *     one board at 0x350, IRQ5, no dma, I could say  
+ *     -DGENERIC_NCR5380_OVERRIDE={{0xcc000, 5, DMA_NONE, BOARD_NORMAL}}
  * 
  * -1 should be specified for no or DMA interrupt, -2 to autoprobe for an 
  * 	IRQ line if overriden on the command line.
@@ -52,10 +53,7 @@
  */
  
 /*
- * $Log: g_NCR5380.c,v $
- * Revision 1.1  1994/06/20  19:45:19  drew
- * Initial revision
- *
+ * $Log: generic_NCR5380.c,v $
  */
 
 #include <linux/config.h>
@@ -78,6 +76,7 @@
     int port;
     int irq;
     int dma;
+    int board;	/* Use NCR53c400, Ricoh, etc. extensions ? */
 } overrides 
 #ifdef GENERIC_NCR5380_OVERRIDE 
     [] = GENERIC_NCR5380_OVERRIDE
@@ -88,28 +87,67 @@
 #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
 
 /*
- * Function : generic_NCR5380_setup(char *str, int *ints)
+ * Function : static internal_setup(int board, char *str, int *ints)
  *
  * Purpose : LILO command line initialization of the overrides array,
  * 
- * Inputs : str - unused, ints - array of integer paramters with ints[0]
- *	equal to the number of ints.
+ * Inputs : board - either BOARD_NCR5380 for a normal NCR5380 board, 
+ * 	or BOARD_NCR53C400 for a NCR53C400 board. str - unused, ints - 
+ *	array of integer paramters with ints[0] equal to the number of ints.
  *
  */
 
-void generic_NCR5380_setup(char *str, int *ints) {
+static void internal_setup(int board, char *str, int *ints) {
     static int commandline_current = 0;
-    if (ints[0] != 2) 
-	printk("generic_NCR5380_setup : usage ncr5380=port,irq,dma\n");
-    else 
-	if (commandline_current < NO_OVERRIDES) {
-	    overrides[commandline_current].port = ints[1];
-	    overrides[commandline_current].irq = ints[2];
+    switch (board) {
+    case BOARD_NCR5380:
+	if (ints[0] != 2 && ints[0] != 3) 
+	    printk("generic_NCR5380_setup : usage ncr5380=port,irq,dma\n");
+	return;
+    case BOARD_NCR53C400:
+	if (ints[0] != 2)
+	    printk("generic_NCR53C400_setup : usage ncr53c400=port,irq\n");
+	return;
+    }
+
+    if (commandline_current < NO_OVERRIDES) {
+	overrides[commandline_current].port = ints[1];
+	overrides[commandline_current].irq = ints[2];
+	if (ints[0] == 3) 
 	    overrides[commandline_current].dma = ints[3];
+	else 
+	    overrides[commandline_current].dma = DMA_NONE;
+	overrides[commandline_current].board = board;
 	    ++commandline_current;
-	}
+    }
+}
+
+/*
+ * Function : generic_NCR5380_setup (char *str, int *ints)
+ *
+ * Purpose : LILO command line initialization of the overrides array,
+ * 
+ * Inputs : str - unused, ints - array of integer paramters with ints[0] 
+ * 	equal to the number of ints.
+ */
+
+void generic_NCR5380_setup (char *str, int *ints) {
+    internal_setup (BOARD_NCR5380, str, ints);
 }
 
+/*
+ * Function : generic_NCR53C400_setup (char *str, int *ints)
+ *
+ * Purpose : LILO command line initialization of the overrides array,
+ * 
+ * Inputs : str - unused, ints - array of integer paramters with ints[0] 
+ * 	equal to the number of ints.
+ */
+
+void generic_NCR53C400_setup (char *str, int *ints) {
+    internal_setup (BOARD_NCR53400, str, ints);
+}
+
 static struct sigaction sa =  { generic_NCR5380_intr, 0, 
     SA_INTERRUPT , NULL };
 
@@ -128,6 +166,7 @@
 int generic_NCR5380_detect(int hostno) {
     static int current_override = 0;
     int count;
+    int flags;
     struct Scsi_Host *instance;
 
     for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
@@ -134,10 +173,19 @@
 	if (!(overrides[current_override].port))
 	    continue;
 
+	switch (overrides[current_override].board) {
+	case BOARD_NCR5380:
+	    flags = 0;
+	    break;
+	case BOARD_NCR53C400:
+	    flags = FLAG_NCR53C400;
+	    break;
+	}
+	
 	instance = scsi_register (hostno, sizeof(struct NCR5380_hostdata));
 	instance->io_port = overrides[current_override].port;
 
-	NCR5380_init(instance);
+	NCR5380_init(instance, flags);
 
 	if (overrides[current_override].irq != IRQ_AUTO)
 	    instance->irq = overrides[current_override].irq;
--- 1.1	1994/06/20 19:45:19
+++ ./drivers/scsi/g_NCR5380.h	1994/06/24 15:35:43
@@ -23,10 +23,7 @@
  */
 
 /*
- * $Log: g_NCR5380.h,v $
- * Revision 1.1  1994/06/20  19:45:19  drew
- * Initial revision
- *
+ * $Log: generic_NCR5380.h,v $
  */
 
 #ifndef GENERIC_NCR5380_H
@@ -61,7 +58,7 @@
 	generic_NCR5380_detect, generic_NCR5380_info, NULL, 		\
 	generic_NCR5380_queue_command, generic_NCR5380_abort, 		\
 	generic_NCR5380_reset, NULL, 					\
-	NULL, /* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL,		\
+	NULL, /* can queue */ CAN_QUEUE, /* id */ 7, 255 /* Old SG_ALL */,\
 	/* cmd per lun */ CMD_PER_LUN , 0, 0, DISABLE_CLUSTERING}
 
 #else
@@ -81,6 +78,9 @@
 #define NCR5380_queue_command generic_NCR5380_queue_command
 #define NCR5380_abort generic_NCR5380_abort
 #define NCR5380_reset generic_NCR5380_reset
+
+#define BOARD_NORMAL	0
+#define BOARD_NCR53C400	1
 
 #endif /* else def HOSTS_C */
 #endif /* ndef ASM */
--- 1.1	1994/06/20 19:45:19
+++ ./drivers/scsi/pas16.c	1994/06/23 17:25:45
@@ -1,6 +1,4 @@
 #define AUTOSENSE
-#define PSEUDO_DMA
-
 /*
  * This driver adapted from Drew Eckhardt's Trantor T128 driver
  *
@@ -41,7 +39,8 @@
  *      for commands that return with a CHECK CONDITION status. 
  *
  * PSEUDO_DMA - enables PSEUDO-DMA hardware, should give a 3-4X performance
- * increase compared to polled I/O.
+ * increase compared to polled I/O.  Note that this locks some systems 
+ * solid for no aparant reason.
  *
  * PARITY - enable parity checking.  Not supported.
  * 
@@ -64,7 +63,6 @@
  *     software after reset using the default_irq for the
  *     current board number.
  *
- *
  * 2.  With command line overrides - pas16=port,irq may be 
  *     used on the LILO command line to override the defaults.
  *     NOTE:  untested.
@@ -93,7 +91,6 @@
 #include "constants.h"
 
 
-
 int scsi_irq_translate[] =
 	{ 0,  0,  1,  2,  3,  4,  5,  6, 0,  0,  7,  8,  9,  0, 10, 11 };
 
@@ -332,7 +329,7 @@
 	instance = scsi_register (hostno, sizeof(struct NCR5380_hostdata));
 	instance->io_port = io_port;
 
-	NCR5380_init(instance);
+	NCR5380_init(instance, 0);
 
 	if (overrides[current_override].irq != IRQ_AUTO)
 	    instance->irq = overrides[current_override].irq;
@@ -423,8 +420,12 @@
 
     while ( inb(instance->io_port + P_STATUS_REG_OFFSET) & P_ST_RDY );
 
-    for (; i; --i) 
+    for (; i; --i) {
+#if 1
+    while ( inb(instance->io_port + P_STATUS_REG_OFFSET) & P_ST_RDY );
+#endif
 	*d++ = (unsigned char) inb(reg);
+    }
 
     if ( inb(instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET) & P_TS_TIM) {
         outb( P_TS_CT, instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET);
--- 1.1	1994/06/20 19:45:19
+++ ./drivers/scsi/pas16.h	1994/06/24 15:36:05
@@ -144,7 +144,7 @@
 #define MV_PAS16 {"Pro Audio Spectrum-16 SCSI", pas16_detect, pas16_info,\
 	NULL, pas16_queue_command, pas16_abort, pas16_reset, NULL, 	\
 	pas16_biosparam, 						\
-	/* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL,			\
+	/* can queue */ CAN_QUEUE, /* id */ 7, 255 /* Old SG_ALL */,	\
 	/* cmd per lun */ CMD_PER_LUN , 0, 0, DISABLE_CLUSTERING}
 
 #else
--- 1.1	1994/06/20 19:45:19
+++ ./drivers/scsi/scsi.c	1994/06/24 15:39:08
@@ -69,6 +69,8 @@
 */
 	
 int NR_SCSI_DEVICES=0;
+/* Process ID of SCSI commands */
+unsigned long scsi_pid;
 
 Scsi_Device * scsi_devices = NULL;
 
@@ -154,6 +156,7 @@
 				 * controller, which causes SCSI code to reset bus.*/
    {"TEXEL","CD-ROM","1.06"},   /* causes failed REQUEST SENSE on lun 1 for seagate
 				 * controller, which causes SCSI code to reset bus.*/
+   {"QUANTUM","LPS525S","3110"},/* Locks sometimes if polled for lun != 0 */
    {NULL, NULL, NULL}};	
 
 static int blacklisted(unsigned char * response_data){
@@ -182,7 +185,7 @@
  *	scsi_do_cmd() function.
  */
 
-static volatile int in_scan = 0;
+volatile int in_scan_scsis = 0;
 static int the_result;
 static void scan_scsis_done (Scsi_Cmnd * SCpnt)
 	{
@@ -222,7 +225,7 @@
   struct Scsi_Host * shpnt;
   Scsi_Cmnd  SCmd;
   
-  ++in_scan;
+  ++in_scan_scsis;
   lun = 0;
   
   SCmd.next = NULL;
@@ -240,6 +243,7 @@
 	    for (lun = 0; lun < max_scsi_luns; ++lun)
 	      {
 		scsi_devices[NR_SCSI_DEVICES].host = shpnt;
+		scsi_devices[NR_SCSI_DEVICES].hostdata = NULL;
 		scsi_devices[NR_SCSI_DEVICES].id = dev;
 		scsi_devices[NR_SCSI_DEVICES].lun = lun;
 		scsi_devices[NR_SCSI_DEVICES].index = NR_SCSI_DEVICES;
@@ -321,7 +325,8 @@
 		if (!the_result)
 			printk("scsi: INQUIRY successful\n");
 		else
-			printk("scsi: INQUIRY failed with code %08x\n");
+			printk("scsi: INQUIRY failed with code 0x%x\n",
+			    the_result);
 #endif
 
 		if(the_result) break; 
@@ -501,7 +506,7 @@
     printk("%d CD-ROM drive%s ", MAX_SR, (MAX_SR != 1) ? "s" : "");
 
   printk("total.\n");
-  in_scan = 0;
+  in_scan_scsis = 0;
 }       /* scan_scsis  ends */
 
 /*
@@ -523,12 +528,15 @@
  	switch (SCpnt->internal_timeout & (IN_ABORT | IN_RESET))
 		{
 		case NORMAL_TIMEOUT:
-			if (!in_scan) {
-			  printk("SCSI host %d timed out - aborting command\n",
-				 SCpnt->host->host_no);
 #ifdef DEBUG_TIMEOUT
-			  scsi_dump_status();
+    	    	    	scsi_dump_status();
 #endif
+			if (!in_scan_scsis) {
+			      printk("scsi : aborting command due to timeout : pid %lu, scsi%d, id %d, lun %d ",
+				SCpnt->pid, SCpnt->host->host_no, (int) SCpnt->target, (int) 
+				SCpnt->lun);
+				print_command (SCpnt->cmnd);
+			      printk("\n");
 			}
 			
 			if (!scsi_abort	(SCpnt, DID_TIME_OUT))
@@ -874,6 +882,8 @@
 	ourselves.
 */
 
+	SCpnt->pid = scsi_pid++; 
+
 	while (1==1){
 	  cli();
 	  if (host->hostt->can_queue
@@ -1704,6 +1714,10 @@
 unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end)
 	{
 	int i;
+	unsigned long old_start = memory_start;
+#ifdef DEBUG_MEMORY
+	int old_dma_sectors;
+#endif
 	struct Scsi_Host * host;
 	Scsi_Cmnd * SCpnt;
 #ifdef FOO_ON_YOU
@@ -1723,7 +1737,13 @@
         memory_start = st_init1(memory_start, memory_end);
 	memory_start = sr_init1(memory_start, memory_end);
 	memory_start = sg_init1(memory_start, memory_end);
+#ifdef DEBUG_MEMORY
+	printk ("scsi : %d bytes used in pass 1 allocation\n",
+	    memory_start - old_start);
+	old_start = memory_start;
+#endif
 
+
 	last_cmnd = (Scsi_Cmnd *) memory_start;
 
 	SCpnt = last_cmnd;
@@ -1771,6 +1791,11 @@
 	};
 
 	memory_start = (int) SCpnt;
+#ifdef DEBUG_MEMORY
+	printk ("scsi : %d bytes used for %d SCSI devices \n",
+	    memory_start - old_start, NR_SCSI_DEVICES);
+#endif
+	old_start = memory_start;
 
 	if (NR_SD > 0 || NR_SR > 0 || NR_ST > 0)
 	  dma_sectors = 16;  /* Base value we use */
@@ -1778,7 +1803,13 @@
 	for (i = 0; i < NR_SCSI_DEVICES; ++i) {
 	  struct Scsi_Host * host;
 	  host = scsi_devices[i].host;
-	  
+#ifdef DEBUG_MEMORY
+	  old_dma_sectors = dma_sectors;
+	  printk ("scsi%d : sg_tablesize %d, cmd per lun %d, scatter list is %d bytes\n",
+		host->host_no, host->sg_tablesize, host->hostt->cmd_per_lun,
+		sizeof(struct scatterlist));
+#endif
+	 
 	  if(scsi_devices[i].type != TYPE_TAPE)
 	    dma_sectors += ((host->sg_tablesize * 
 			     sizeof(struct scatterlist) + 511) >> 9) * 
@@ -1787,13 +1818,24 @@
 	  if(host->unchecked_isa_dma &&
 	     memory_end > ISA_DMA_THRESHOLD &&
 	     scsi_devices[i].type != TYPE_TAPE) {
+	    printk ("scsi%d : using unchecked ISA DMA\n",
+		host->host_no);
 	    dma_sectors += (PAGE_SIZE >> 9) * host->sg_tablesize *
 	      host->hostt->cmd_per_lun;
 	    need_isa_buffer++;
 	  };
+#ifdef DEBUG_MEMORY
+	  printk("scsi%d : %d buffers for target %d lun %d\n",
+	    host->host_no, dma_sectors - old_dma_sectors, 
+	    scsi_devices[i].id, scsi_devices[i].lun);
+#endif
 	};
 
 	dma_sectors = (dma_sectors + 15) & 0xfff0;
+#ifdef DEBUG_MEMORY
+	printk ("scsi : using %d buffers totaling %d bytes\n",
+	    dma_sectors, dma_sectors * 512);
+#endif
 	dma_free_sectors = dma_sectors;  /* This must be a multiple of 16 */
 
 	memory_start = (memory_start + 3) & 0xfffffffc;
@@ -1801,15 +1843,45 @@
 	memory_start += dma_sectors >> 3;
 	memset(dma_malloc_freelist, 0, dma_sectors >> 3);
 
-	if(memory_start & 1) memory_start++; /* Some host adapters require
-						buffers to be word aligned */
+
+	/* Some host adapters require buffers to be word aligned,
+	   others dword aligned.  */
+	if(memory_start & 1) memory_start++; 
+	if(memory_start & 2) memory_start += 2;
+							
 	dma_malloc_buffer = (unsigned char *) memory_start;
 	memory_start += dma_sectors << 9;
+	printk ("scsi : %d buffers total %d bytes\n", 
+	    dma_sectors, memory_start - old_start);
+#ifdef DEBUG_MEMORY
+	old_start = memory_start;
+#endif
 
 	memory_start = sd_init(memory_start, memory_end); /* init scsi disks */
+#ifdef DEBUG_MEMORY
+	printk ("scsi : %d bytes used in sd pass 2 allocation\n",
+	    memory_start - old_start);
+	old_start = memory_start;
+#endif
         memory_start = st_init(memory_start, memory_end); /* init scsi tapes */
+#ifdef DEBUG_MEMORY
+	printk ("scsi : %d bytes used in st pass 2 allocation\n",
+	    memory_start - old_start);
+	old_start = memory_start;
+#endif
 	memory_start = sr_init(memory_start, memory_end); /* init scsi CDROMs */
+#ifdef DEBUG_MEMORY
+	printk ("scsi : %d bytes used in sr pass 2 allocation\n",
+	    memory_start - old_start);
+	old_start = memory_start;
+#endif
 	memory_start = sg_init(memory_start, memory_end); /* init scsi generic */
+
+#ifdef DEBUG_MEMORY
+	printk ("scsi : %d bytes used in sg pass 2 allocation\n",
+	    memory_start - old_start);
+	old_start = memory_start;
+#endif
 	
 	return memory_start;
 	}
--- 1.1	1994/06/20 19:45:19
+++ ./drivers/scsi/scsi.h	1994/07/05 07:34:39
@@ -76,6 +76,7 @@
 #define MODE_SELECT_10		0x55
 #define MODE_SENSE_10		0x5a
 
+extern volatile int in_scan_scsis;
 extern const unsigned char scsi_command_size[8];
 #define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7]
 
@@ -85,6 +86,10 @@
 
 #define COMMAND_COMPLETE	0x00
 #define EXTENDED_MESSAGE	0x01
+#define 	EXTENDED_MODIFY_DATA_POINTER	0x00
+#define 	EXTENDED_SDTR			0x01
+#define 	EXTENDED_EXTENDED_IDENTIFY	0x02	/* SCSI-I only */
+#define 	EXTENDED_WDTR			0x03
 #define SAVE_POINTERS		0x02
 #define RESTORE_POINTERS 	0x03
 #define DISCONNECT		0x04
@@ -97,6 +102,9 @@
 #define LINKED_FLG_CMD_COMPLETE	0x0b
 #define BUS_DEVICE_RESET	0x0c
 
+#define INITIATE_RECOVERY	0x0f			/* SCSI-II only */
+#define RELEASE_RECOVERY	0x10			/* SCSI-II only */
+
 #define SIMPLE_QUEUE_TAG	0x20
 #define HEAD_OF_QUEUE_TAG	0x21
 #define ORDERED_QUEUE_TAG	0x22
@@ -263,6 +271,7 @@
 	struct wait_queue * device_wait;  /* Used to wait if device is busy */
 	struct Scsi_Host * host;
 	void (*scsi_request_fn)(void); /* Used to jumpstart things after an ioctl */
+	void *hostdata;                   /* available to low-level driver */
 	char type;
 	char scsi_level;
 	unsigned writeable:1;
@@ -478,6 +487,7 @@
 	int result;                   /* Status code from lower level driver */
 
 	unsigned char tag;		/* SCSI-II queued command tag */
+	unsigned long pid;		/* Process ID, starts at 0 */
 	} Scsi_Cmnd;		 
 
 /*
--- 1.1	1994/06/20 19:45:19
+++ ./drivers/scsi/sd.c	1994/06/23 17:25:45
@@ -146,7 +146,7 @@
   int this_count = SCpnt->bufflen >> 9;
 
 #ifdef DEBUG
-  printk("sd%d : rw_intr(%d, %d)\n", MINOR(SCpnt->request.dev), SCpnt->host->host_no, result);
+  printk("sd%c : rw_intr(%d, %d)\n", 'a' + MINOR(SCpnt->request.dev), SCpnt->host->host_no, result);
 #endif
 
 /*
@@ -158,7 +158,7 @@
   if (!result) {
 
 #ifdef DEBUG
-    printk("sd%d : %d sectors remain.\n", MINOR(SCpnt->request.dev), SCpnt->request.nr_sectors);
+    printk("sd%c : %d sectors remain.\n", 'a' + MINOR(SCpnt->request.dev), SCpnt->request.nr_sectors);
     printk("use_sg is %d\n ",SCpnt->use_sg);
 #endif
     if (SCpnt->use_sg) {
@@ -200,8 +200,8 @@
 	if (!SCpnt->request.bh)
 	  {
 #ifdef DEBUG
-	    printk("sd%d : handling page request, no buffer\n",
-		   MINOR(SCpnt->request.dev));
+	    printk("sd%c : handling page request, no buffer\n",
+		   'a' + MINOR(SCpnt->request.dev));
 #endif
 /*
   The SCpnt->request.nr_sectors field is always done in 512 byte sectors,
@@ -424,7 +424,7 @@
 		}
 
 #ifdef DEBUG
-	printk("sd%d : real dev = /dev/sd%d, block = %d\n", MINOR(SCpnt->request.dev), dev, block);
+	printk("sd%c : real dev = /dev/sd%c, block = %d\n", 'a' + MINOR(SCpnt->request.dev), dev, block);
 #endif
 
 	switch (SCpnt->request.cmd)
@@ -672,7 +672,7 @@
 	  };
 	};
 #ifdef DEBUG
-	printk("sd%d : %s %d/%d 512 byte blocks.\n", MINOR(SCpnt->request.dev),
+	printk("sd%c : %s %d/%d 512 byte blocks.\n", 'a' + MINOR(SCpnt->request.dev),
 		(SCpnt->request.cmd == WRITE) ? "writing" : "reading",
 		this_count, SCpnt->request.nr_sectors);
 #endif
@@ -824,7 +824,7 @@
 	 SCpnt->sense_buffer[2] == NOT_READY) {
 	int time1;
 	if(!spintime){
-	  printk( "sd%d: Spinning up disk...", i );
+	  printk( "sd%c: Spinning up disk...", 'a' + i );
 	  cmd[0] = START_STOP;
 	  cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
 	  cmd[1] |= 1;  /* Return immediately */
@@ -908,9 +908,9 @@
 
   if (the_result)
     {
-      printk ("sd%d : READ CAPACITY failed.\n"
-	      "sd%d : status = %x, message = %02x, host = %d, driver = %02x \n",
-	      i,i,
+      printk ("sd%c : READ CAPACITY failed.\n"
+	      "sd%c : status = %x, message = %02x, host = %d, driver = %02x \n",
+	      'a' + i, 'a' + i,
 	      status_byte(the_result),
 	      msg_byte(the_result),
 	      host_byte(the_result),
@@ -917,11 +917,11 @@
 	      driver_byte(the_result)
 	      );
       if (driver_byte(the_result)  & DRIVER_SENSE)
-	printk("sd%d : extended sense code = %1x \n", i, SCpnt->sense_buffer[2] & 0xf);
+	printk("sd%c : extended sense code = %1x \n", 'a' + i, SCpnt->sense_buffer[2] & 0xf);
       else
-	printk("sd%d : sense not available. \n", i);
+	printk("sd%c : sense not available. \n", 'a' + i);
 
-      printk("sd%d : block size assumed to be 512 bytes, disk size 1GB.  \n", i);
+      printk("sd%c : block size assumed to be 512 bytes, disk size 1GB.  \n", 'a' + i);
       rscsi_disks[i].capacity = 0x1fffff;
       rscsi_disks[i].sector_size = 512;
 
@@ -946,8 +946,8 @@
 	  rscsi_disks[i].sector_size != 1024 &&
 	  rscsi_disks[i].sector_size != 256)
 	{
-	  printk ("sd%d : unsupported sector size %d.\n",
-		  i, rscsi_disks[i].sector_size);
+	  printk ("sd%c : unsupported sector size %d.\n",
+		  'a' + i, rscsi_disks[i].sector_size);
 	  if(rscsi_disks[i].device->removable){
 	    rscsi_disks[i].capacity = 0;
 	  } else {
--- 1.1	1994/06/20 19:45:19
+++ ./drivers/scsi/t128.c	1994/06/23 17:25:58
@@ -104,9 +104,6 @@
  
 /*
  * $Log: t128.c,v $
- * Revision 1.1  1994/06/20  19:45:19  drew
- * Initial revision
- *
  */
 
 #include <asm/system.h>
@@ -234,7 +231,7 @@
 	instance = scsi_register (hostno, sizeof(struct NCR5380_hostdata));
 	instance->base = base;
 
-	NCR5380_init(instance);
+	NCR5380_init(instance, 0);
 
 	if (overrides[current_override].irq != IRQ_AUTO)
 	    instance->irq = overrides[current_override].irq;
@@ -322,10 +319,16 @@
 	T_DATA_REG_OFFSET), *d = dst;
     register i = len;
 
-    while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY);
 
-    for (; i; --i) 
+#if 0
+    for (; i; --i) {
+	while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY);
+#else
+    while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY);
+    for (; i; --i) {
+#endif
 	*d++ = *reg;
+    }
 
     if (*(instance->base + T_STATUS_REG_OFFSET) & T_ST_TIM) {
 	unsigned char tmp;
@@ -334,7 +337,7 @@
 	tmp = *foo;
 	*foo = tmp | T_CR_CT;
 	*foo = tmp;
-	printk("scsi%d : watchdog timer fired in NCR5480_pread()\n",
+	printk("scsi%d : watchdog timer fired in NCR5380_pread()\n",
 	    instance->host_no);
 	return -1;
     } else
@@ -360,9 +363,15 @@
 	T_DATA_REG_OFFSET), *s = src;
     register i = len;
 
+#if 0
+    for (; i; --i) {
+	while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY);
+#else
     while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY);
-    for (; i; --i)
+    for (; i; --i) {
+#endif
 	*reg = *s++;
+    }
 
     if (*(instance->base + T_STATUS_REG_OFFSET) & T_ST_TIM) {
 	unsigned char tmp;
@@ -371,7 +380,7 @@
 	tmp = *foo;
 	*foo = tmp | T_CR_CT;
 	*foo = tmp;
-	printk("scsi%d : watchdog timer fired in NCR5480_pwrite()\n",
+	printk("scsi%d : watchdog timer fired in NCR5380_pwrite()\n",
 	    instance->host_no);
 	return -1;
     } else 
--- 1.1	1994/06/20 19:45:19
+++ ./drivers/scsi/t128.h	1994/06/24 15:37:14
@@ -36,9 +36,6 @@
 
 /*
  * $Log: t128.h,v $
- * Revision 1.1  1994/06/20  19:45:19  drew
- * Initial revision
- *
  */
 
 #ifndef T128_H
@@ -124,7 +121,7 @@
 #define TRANTOR_T128 {"Trantor T128/T128F/T228", t128_detect, t128_info,\
 	NULL, t128_queue_command, t128_abort, t128_reset, NULL, 	\
 	t128_biosparam, 						\
-	/* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL,			\
+	/* can queue */ CAN_QUEUE, /* id */ 7, 255 /* Old SG_ALL */,	\
 	/* cmd per lun */ CMD_PER_LUN , 0, 0, DISABLE_CLUSTERING}
 
 #else
--- 1.1	1994/06/20 19:45:19
+++ ./drivers/scsi/constants.c	1994/06/23 17:25:59
@@ -7,11 +7,15 @@
 #include "../block/blk.h"
 #include <linux/kernel.h>
 #include "scsi.h"
+#include "hosts.h"
 
 #define CONST_COMMAND 	0x01
 #define CONST_STATUS 	0x02
 #define CONST_SENSE 	0x04
 #define CONST_XSENSE 	0x08
+#define CONST_CMND	0x10
+#define CONST_MSG	0x20
+
 static const char unknown[] = "UNKNOWN";
 
 #ifdef CONFIG_SCSI_CONSTANTS
@@ -18,7 +22,7 @@
 #ifdef CONSTANTS
 #undef CONSTANTS
 #endif
-#define CONSTANTS (CONST_COMMAND | CONST_STATUS | CONST_SENSE | CONST_XSENSE)
+#define CONSTANTS (CONST_COMMAND | CONST_STATUS | CONST_SENSE | CONST_XSENSE | CONST_CMND | CONST_MSG)
 #endif
 
 #if (CONSTANTS & CONST_COMMAND)
@@ -85,7 +89,7 @@
   	printk("%s(0x%02x) ", vendor, opcode); 
   	break;
   default:
-  	printk("%s ",table[opcode & 0x31]);
+  	printk("%s ",table[opcode & 0x1f]);
   }
 }
 #else /* CONST & CONST_COMMAND */
@@ -451,14 +455,14 @@
 /* 0x0a */ "Linked Command Complete", "Linked Command Complete w/flag",
 /* 0x0c */ "Bus device reset", "Abort Tag", "Clear Queue", 
 /* 0x0f */ "Initiate Recovery", "Release Recovery"
-}
+};
 
 #define NO_ONE_BYTE_MSGS (sizeof(one_byte_msgs)  / sizeof (const char *))
 
-static const char *queue_tag_msgs[] = {
+static const char *two_byte_msgs[] = {
 /* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag"
 /* 0x23 */ "Ignore Wide Residue"
-}
+};
 
 #define NO_TWO_BYTE_MSGS (sizeof(two_byte_msgs)  / sizeof (const char *))
 
@@ -475,15 +479,30 @@
     if (msg[0] == EXTENDED_MESSAGE) {
 	len = 3 + msg[1];
 #if (CONSTANTS & CONST_MSG)
-	printk("Extended Message code %s arguments ", 
-	    (msg[2] < NO_EXTENDED_MESSAGES) ?
-	    printk("%s " extended_msgs[msg[2]]),
-	    reserved);
-	for (i = 3; i < msg[1]; ++i) 
+	if (msg[2] < NO_EXTENDED_MSGS)
+	    printk ("%s ", extended_msgs[msg[2]]); 
+	else 
+	    printk ("Extended Message, reserved code (0x%02x) ", (int) msg[2]);
+	switch (msg[2]) {
+	case EXTENDED_MODIFY_DATA_POINTER:
+	    printk("pointer = %d", (int) (msg[3] << 24) | (msg[4] << 16) | 
+		(msg[5] << 8) | msg[6]);
+	    break;
+	case EXTENDED_SDTR:
+	    printk("period = %d ns, offset = %d", (int) msg[3] * 4, (int) 
+		msg[4]);
+	    break;
+	case EXTENDED_WDTR:
+	    printk("width = 2^%d bytes", msg[3]);
+	    break;
+	default:
+	    for (i = 2; i < len; ++i) 
+		printk("%02x ", msg[i]);
+	}
 #else
-	for (i = 0; i < msg[1]; ++i)
-#endif
+	for (i = 0; i < len; ++i)
 	    printk("%02x ", msg[i]);
+#endif
     /* Identify */
     } else if (msg[0] & 0x80) {
 #if (CONSTANTS & CONST_MSG)
@@ -509,7 +528,7 @@
     /* Two byte */
     } else if (msg[0] <= 0x2f) {
 #if (CONSTANTS & CONST_MSG)
-	if ((msg[0] - 0x20) < NO_TWO_BYTE_MESSAGES) 
+	if ((msg[0] - 0x20) < NO_TWO_BYTE_MSGS)
 	    printk("%s %02x ", two_byte_msgs[msg[0] - 0x20], 
 		msg[1]);
 	else 
@@ -526,4 +545,13 @@
 	printk("%02x ", msg[0]);
 #endif
     return len;
+}
+
+void print_Scsi_Cmnd (Scsi_Cmnd *cmd) {
+    printk("scsi%d : destination target %d, lun %d\n", 
+    cmd->host->host_no, 
+    cmd->target, 
+    cmd->lun);
+    printk("        command = ");
+    print_command (cmd->cmnd);
 }
--- 1.1	1994/06/20 19:45:27
+++ ./drivers/scsi/Makefile	1994/07/05 05:37:54
@@ -1,4 +1,4 @@
-#
+
 # Makefile for kernel/blk_drv/scsi
 #
 # Note! Dependencies are done automagically by 'make dep', which also
@@ -24,8 +24,8 @@
 
 ifdef CONFIG_SCSI
 
-SCSI_OBJS := hosts.o scsi.o scsi_ioctl.o constants.o
-SCSI_SRCS := hosts.c scsi.c scsi_ioctl.c constants.c
+SCSI_OBJS := hosts.o scsi.o scsi_ioctl.o constants.o scsicam.o
+SCSI_SRCS := hosts.c scsi.c scsi_ioctl.c constants.c scsicam.c
 
 ifdef CONFIG_CHR_DEV_ST
 SCSI_OBJS := $(SCSI_OBJS) st.o
@@ -87,6 +87,11 @@
 SCSI_SRCS := $(SCSI_SRCS) g_NCR5380.c
 endif
 
+#ifdef CONFIG_SCSI_NCR53C7xx
+SCSI_OBJS := $(SCSI_OBJS) 53c7,8xx.o 
+SCSI_SRCS := $(SCSI_SRCS) 53c7,8xx.c
+#endif
+
 ifdef CONFIG_SCSI_PAS16
 SCSI_OBJS := $(SCSI_OBJS) pas16.o
 SCSI_SRCS := $(SCSI_SRCS) pas16.c
@@ -130,6 +135,17 @@
 
 seagate.o: seagate.c
 	$(CC) $(CFLAGS) -DARBITRATE -DSLOW_HANDSHAKE -DFAST32 -c seagate.c 
+
+# For debugging, use the -g flag
+53c7,8xx.o : 53c7,8xx.c
+	$(CC) $(CFLAGS) -g -c 53c7,8xx.c
+
+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 
+	mv script.h 53c8xx_d.h
+	mv scriptu.h 53c8xx_u.h
+	rm fake.c
 
 dep:
 	$(CPP) -M $(AHA152X) $(SCSI_SRCS) > .depend
--- 1.1	1994/06/20 20:04:15
+++ ./drivers/scsi/NCR5380.c	1994/06/23 17:25:59
@@ -1,3 +1,4 @@
+#define NDEBUG (NDEBUG_RESTART_SELECT)
 /* 
  * NCR 5380 generic driver routines.  These should make it *trivial*
  * 	to implement 5380 SCSI drivers under Linux with a non-trantor
@@ -11,7 +12,7 @@
  * 	drew@colorado.edu
  *	+1 (303) 666-5836
  *
- * DISTRIBUTION REALEASE 4. 
+ * DISTRIBUTION REALEASE 6. 
  *
  * For more information, please consult 
  *
@@ -691,13 +689,65 @@
     printk(" USLEEP, USLEEP_POLL=%d USLEEP_SLEEP=%d", USLEEP_POLL, USLEEP_SLEEP);
 #endif
     printk(" generic release=%d", NCR5380_PUBLIC_RELEASE);
+#ifdef NCR53C400
+    if (hostdata->flags & FLAG_NCR53C400) {
+	printk(" ncr53c400 release=%d", NCR53C400_PUBLIC_RELEASE);
+    }
+#endif
+}
+
+/*
+ * Function : void NCR5380_print_status (struct Scsi_Host *instance)
+ *
+ * Purpose : print commands in the various queues, called from
+ *	NCR5380_abort and NCR5380_debug to aid debugging.
+ *
+ * Inputs : instance, pointer to this instance.  
+ */
+
+void NCR5380_print_status (struct Scsi_Host *instance) {
+    struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
+	instance->hostdata;
+    Scsi_Cmnd *ptr;
+
+
+    printk("NCR5380 : coroutine is%s running.\n",
+	main_running ? "" : "n't");
+    
+#ifdef NDEBUG
+    NCR5380_print (instance);
+    NCR5380_print_phase (instance);
+#endif
+
+    cli();
+    if (!hostdata->connected) {
+	printk ("scsi%d: no currently connected command\n",
+	    instance->host_no);
+    } else {
+	print_Scsi_Cmnd ((Scsi_Cmnd *) hostdata->connected);
+    }
+
+    printk ("scsi%d: issue_queue\n", instance->host_no);
+
+    for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; 
+	ptr = (Scsi_Cmnd *) ptr->host_scribble) 
+	print_Scsi_Cmnd (ptr);
+
+    printk ("scsi%d: disconnected_queue\n", instance->host_no);
+
+    for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; 
+	ptr = (Scsi_Cmnd *) ptr->host_scribble) 
+	print_Scsi_Cmnd (ptr);
+    
+    sti();
 }
 
 
 /* 
- * Function : void NCR5380_init (struct Scsi_Host *instance)
+ * Function : void NCR5380_init (struct Scsi_Host *instance, flags)
  *
- * Purpose : initializies *instance and corresponding 5380 chip.
+ * Purpose : initializies *instance and corresponding 5380 chip,
+ *	with flags OR'd into the initial flags value.
  *
  * Inputs : instance - instantiation of the 5380 driver.  
  *
@@ -706,15 +756,25 @@
  * 
  */
 
-static void NCR5380_init (struct Scsi_Host *instance) {
+static void NCR5380_init (struct Scsi_Host *instance, int flags) {
     NCR5380_local_declare();
     int i;
     struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
 	instance->hostdata;
+
+    /* 
+     * On NCR53C400 boards, NCR5380 registers are mapped 8 past 
+     * the base address.
+     */
+
+    if (flags & FLAG_NCR53C400)
+	instance->io_port += 8;
+
     NCR5380_setup(instance);
 
     NCR5380_all_init();
 
+    hostdata->aborted = 0;
     hostdata->id_mask = 1 << instance->this_id;
     for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
 	if (i > hostdata->id_mask)
@@ -724,10 +784,11 @@
 #ifdef REAL_DMA
     hostdata->dmalen = 0;
 #endif
+    hostdata->targets_present = 0;
     hostdata->connected = NULL;
     hostdata->issue_queue = NULL;
     hostdata->disconnected_queue = NULL;
-    hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT;
+    hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT | flags;
 
     if (!the_template) {
 	the_template = instance->hostt;
@@ -751,6 +812,11 @@
     NCR5380_write(MODE_REG, MR_BASE);
     NCR5380_write(TARGET_COMMAND_REG, 0);
     NCR5380_write(SELECT_ENABLE_REG, 0);
+#ifdef NCR53C400
+    if (hostdata->flags & FLAG_NCR53C400) {
+	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
+    }
+#endif
 }
 
 /* 
@@ -863,8 +929,8 @@
     do {
 	cli(); /* Freeze request queues */
 	done = 1;
-	for (instance = first_instance; instance && instance->hostt == the_template; 
-	    instance=instance->next) {
+	for (instance = first_instance; instance && 
+	    instance->hostt == the_template; instance=instance->next) {
 	    hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	    cli();
 	    if (!hostdata->connected) {
@@ -992,12 +1058,16 @@
 #endif
 			NCR5380_reselect(instance);
 			(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-		    } else if (basr & 
-			BASR_PARITY_ERROR) {
+		    } else if (basr & BASR_PARITY_ERROR) {
 #if (NDEBUG & NDEBUG_INTR)
 			printk("scsi%d : PARITY interrupt\n", instance->host_no);
 #endif
 			(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+ 		    } else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
+#if (NDEBUG & NDEBUG_INTR)
+ 			printk("scsi%d : RESET interrupt\n", instance->host_no);
+#endif
+			(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 		    } else {
 /*  
  * XXX the rest of the interrupt conditions should *only* occur during a 
@@ -1026,9 +1096,19 @@
 			    hostdata->dmalen = 0;
 
 			    (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-
-			    while (NCR5380_read(BUS_AND_STATUS_REG) & 
-				BASR_ACK));
+#if NCR_TIMEOUT
+			    {
+			      unsigned long timeout = jiffies + NCR_TIMEOUT;
+
+			      while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK
+				     && jiffies < timeout)
+				;
+			      if (jiffies >= timeout)
+			        printk("scsi: timeout at %d\n", __LINE__);
+			    }
+#else /* NCR_TIMEOUT */
+			    while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK);
+#endif
 
 			    NCR5380_write(MODE_REG, MR_BASE);
 			    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1089,11 +1169,13 @@
     unsigned long timeout;
     NCR5380_setup(instance);
 
+    hostdata->restart_select = 0;
 #if defined (NDEBUG) && (NDEBUG & NDEBUG_ARBITRATION) 
     NCR5380_print(instance);
     printk("scsi%d : starting arbitration, id = %d\n", instance->host_no,
 	instance->this_id);
 #endif
+    cli(); 
 
     /* 
      * Set the phase bits to 0, otherwise the NCR5380 won't drive the 
@@ -1102,12 +1184,35 @@
 
     NCR5380_write(TARGET_COMMAND_REG, 0);
 
-    /* Start arbitration */ 
+
+    /* 
+     * Start arbitration.
+     */
+    
     NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
     NCR5380_write(MODE_REG, MR_ARBITRATE);
 
+    sti();
+
     /* Wait for arbitration logic to complete */
+#if NCR_TIMEOUT
+    {
+      unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
+
+      while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
+	   && jiffies < timeout)
+	;
+      if (jiffies >= timeout)
+      {
+	printk("scsi: arbitration timeout at %d\n", __LINE__);
+	NCR5380_write(MODE_REG, MR_BASE);
+	NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+	return -1;
+      }
+    }
+#else /* NCR_TIMEOUT */
     while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS));
+#endif
 
 #if (NDEBUG & NDEBUG_ARBITRATION) 
     printk("scsi%d : arbitration complete\n", instance->host_no);
@@ -1136,6 +1241,8 @@
 	return -1;
     }
 
+
+
     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
     
     if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) {
@@ -1159,6 +1266,7 @@
     printk("scsi%d : won arbitration\n", instance->host_no);
 #endif
 
+
     /* 
      * Now that we have won arbitration, start Selection process, asserting 
      * the host and target ID's on the SCSI bus.
@@ -1219,12 +1327,33 @@
      * and it's detecting as true.  Sigh.
      */
 
-    while ((jiffies < timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY));
+    while ((jiffies < timeout) && !(NCR5380_read(STATUS_REG) & 
+	(SR_BSY | SR_IO)));
+
+    if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == 
+	    (SR_SEL | SR_IO)) {
+	    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	    NCR5380_reselect(instance);
+	    printk ("scsi%d : reselection after won arbitration?\n",
+		instance->host_no);
+	    NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+	    return -1;
+    }
 
     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 
     if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	if (hostdata->targets_present & (1 << cmd->target)) {
+	    printk("scsi%d : wierdness\n", instance->host_no);
+	    if (hostdata->restart_select)
+		printk("\trestart select\n");
+#ifdef NDEBUG
+	    NCR5380_print (instance);
+#endif
+	    NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+	    return -1;
+	}
 	cmd->result = DID_BAD_TARGET << 16;
 	cmd->scsi_done(cmd);
 	NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
@@ -1232,9 +1361,12 @@
 	printk("scsi%d : target did not respond within 250ms\n", 
 	    instance->host_no);
 #endif
+	NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 	return 0;
     } 
 
+    hostdata->targets_present |= (1 << cmd->target);
+
     /*
      * Since we followed the SCSI spec, and raised ATN while SEL 
      * was true but before BSY was false during selection, the information
@@ -1297,6 +1429,7 @@
 
     initialize_SCp(cmd);
 
+
     return 0;
 }
 
@@ -1407,10 +1540,23 @@
 	    printk("scsi%d : req false, handshake complete\n", instance->host_no);
 #endif
 
-	if (!(p == PHASE_MSGOUT && c > 1))
-	    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	else
-	    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
+/*
+ * We have several special cases to consider during REQ/ACK handshaking : 
+ * 1.  We were in MSGOUT phase, and we are on the last byte of the 
+ *	message.  ATN must be dropped as ACK is dropped.
+ *
+ * 2.  We are in a MSGIN phase, and we are on the last byte of the  
+ *	message.  We must exit with ACK asserted, so that the calling
+ *	code may raise ATN before dropping ACK to reject the message.
+ *
+ * 3.  ACK and ATN are clear and the target may proceed as normal.
+ */
+	if (!(p == PHASE_MSGIN && c == 1)) {  
+	    if (p == PHASE_MSGOUT && c > 1)
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
+	    else
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	} 
     } while (--c);
 
 #if (NDEBUG & NDEBUG_PIO) 
@@ -1743,7 +1889,7 @@
     unsigned char msgout = NOP;
     int len, transfersize;
     unsigned char *data;
-    unsigned char phase, tmp, old_phase=0xff;
+    unsigned char phase, tmp, extended_msg[10], old_phase=0xff;
     Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected;
     NCR5380_setup(instance);
 
@@ -1827,12 +1973,6 @@
 		    &cmd->SCp.ptr);
 		break;
 	    case PHASE_MSGIN:
-		/* 
-		 * XXX - we don't handle multi-byte messages here, since we 
-		 * shouldn't get them after the I_T_L_Q nexus is established
-		 * for tagged queuing, and the host should initiate any 
-		 * negotiations for sync. SCSI, etc.
-		 */
 		len = 1;
 		data = &tmp;
 		NCR5380_transfer_pio(instance, &phase, &len, &data);
@@ -1852,6 +1992,9 @@
 #ifdef LINKED
 		case LINKED_CMD_COMPLETE:
 		case LINKED_FLG_CMD_COMPLETE:
+		    /* Accept message by clearing ACK */
+		    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+		    
 #if (NDEBUG & NDEBUG_LINKED) 
 		    printk("scsi%d : target %d lun %d linked command complete.\n",
 			instance->host_no, cmd->target, cmd->lun);
@@ -1885,6 +2028,8 @@
 #endif /* def LINKED */
 		case ABORT:
 		case COMMAND_COMPLETE: 
+		    /* Accept message by clearing ACK */
+		    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		    hostdata->connected = NULL;
 #if (NDEBUG & NDEBUG_QUEUES)
 		    printk("scsi%d : command for target %d, lun %d completed\n",
@@ -1945,11 +2090,18 @@
 			cmd->scsi_done(cmd);
 
 		    NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+		    /* 
+		     * Restore phase bits to 0 so an interrupted selection, 
+		     * arbitration can resume.
+		     */
+		    NCR5380_write(TARGET_COMMAND_REG, 0);
 		    
 		    while ((NCR5380_read(STATUS_REG) & SR_BSY) && 
 			!hostdata->connected);
 		    return;
 		case MESSAGE_REJECT:
+		    /* Accept message by clearing ACK */
+		    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		    switch (hostdata->last_message) {
 		    case HEAD_OF_QUEUE_TAG:
 		    case ORDERED_QUEUE_TAG:
@@ -1961,6 +2113,8 @@
 			break;
 		    }
 		case DISCONNECT:
+		    /* Accept message by clearing ACK */
+		    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		    scsi_devices[cmd->index].disconnect = 1;
 		    cli();
 		    cmd->host_scribble = (unsigned char *) 
@@ -1973,7 +2127,12 @@
 		           "  the disconnected_queue\n", instance->host_no, 
 			    cmd->target, cmd->lun);
 #endif
-
+		    /* 
+		     * Restore phase bits to 0 so an interrupted selection, 
+		     * arbitration can resume.
+		     */
+		    NCR5380_write(TARGET_COMMAND_REG, 0);
+ 
 		    /* Enable reselect interupts */
 		    NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		    /* Wait for bus free to avoid nasty timeouts */
@@ -1992,24 +2151,94 @@
 		 */
 		case SAVE_POINTERS:
 		case RESTORE_POINTERS:
+		    /* Accept message by clearing ACK */
+		    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		    break;
-		default:
+		case EXTENDED_MESSAGE:
 /* 
- * XXX rejected messages should be handled in the pio data transfer phase,
- * since ATN should be raised before ACK goes false when we reject a message
- */
+ * Extended messages are sent in the following format :
+ * Byte 	
+ * 0		EXTENDED_MESSAGE == 1
+ * 1		length (includes one byte for code, doesn't 
+ *		include first two bytes)
+ * 2 		code
+ * 3..length+1	arguments
+ *
+ * Start the extended message buffer with the EXTENDED_MESSAGE
+ * byte, since print_msg() wants the whole thing.  
+ */
+		    extended_msg[0] = EXTENDED_MESSAGE;
+		    /* Accept first byte by clearing ACK */
+		    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
-		    printk("Unknown message!\n");
+#if (NDEBUG & NDEBUG_EXTENDED)
+		    printk("scsi%d : receiving extended message\n",
+			instance->host_no);
+#endif
 
-#ifdef notyet
+		    len = 2;
+		    data = extended_msg + 1;
+		    phase = PHASE_MSGIN;
+		    NCR5380_transfer_pio(instance, &phase, &len, &data);
+
+#if (NDEBUG & NDEBUG_EXTENDED)
+		    printk("scsi%d : length=%d, code=0x%02x\n", 
+			instance->host_no, (int) extended_msg[1],
+			(int) extended_msg[2]);
+#endif
+
+		    if (!len && extended_msg[1] <= 
+			(sizeof (extended_msg) - 1)) {
+			/* Accept third byte by clearing ACK */
+			NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+			len = extended_msg[1] - 1;
+			data = extended_msg + 3;
+			phase = PHASE_MSGIN;
+
+			NCR5380_transfer_pio(instance, &phase, &len, &data);
+
+#if (NDEBUG & NDEBUG_EXTENDED)
+		    printk("scsi%d : message received, residual %d\n",
+			instance->host_no, len);
+#endif
+
+			switch (extended_msg[2]) {
+			case EXTENDED_SDTR:
+			case EXTENDED_WDTR:
+			case EXTENDED_MODIFY_DATA_POINTER:
+			case EXTENDED_EXTENDED_IDENTIFY:
+			    tmp = 0;
+			}
+		    } else if (len) {
+			printk("scsi%d: error recieving extended message\n",
+			    instance->host_no);
+			tmp = 0;
+		    } else {
+			printk("scsi%d: extended message code %02x length %d is too long\n",
+			    instance->host_no, extended_msg[2], extended_msg[1]);
+			tmp = 0;
+		    }
+		/* Fall through to reject message */
+		    
 		/* 
   		 * If we get something wierd that we aren't expecting, 
  		 * reject it.
 		 */
+		default:
+		    if (!tmp) {
+			printk("scsi%d: rejecting message ", instance->host_no);
+			print_msg (extended_msg);
+			printk("\n");
+		    } else if (tmp != EXTENDED_MESSAGE)
+			printk("scsi%d: rejecting unknown message %02x from target %d, lun %d\n",
+			    instance->host_no, tmp, cmd->target, cmd->lun);
+		    else
+			printk("scsi%d: rejecting unknown extended message code %02x, legnth %d from target %d, lun %d\n",
+			    instance->host_no, extended_msg[1], extended_msg[0], cmd->target, cmd->lun);
+    
 		    msgout = MESSAGE_REJECT;
 		    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
 			ICR_ASSERT_ATN);
-#endif 
 		    break;
 		} /* switch (tmp) */
 		break;
@@ -2108,6 +2337,14 @@
     int abort = 0;
     NCR5380_setup(instance);
 
+    /*
+     * Disable arbitration, etc. since the host adapter obviously
+     * lost, and tell an interrupted NCR5380_select() to restart.
+     */
+
+    NCR5380_write(MODE_REG, MR_BASE);
+    hostdata->restart_select = 1;
+
     target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
 
 #if (NDEBUG & NDEBUG_RESELECTION)
@@ -2134,30 +2371,11 @@
 
     while (!(NCR5380_read(STATUS_REG) & SR_REQ));
 
-    len = 3;
+    len = 1;
     data = msg;
     phase = PHASE_MSGIN;
     NCR5380_transfer_pio(instance, &phase, &len, &data);
 
-#ifdef SCSI2
-    /*
-     * If there was no residual from the attempt to transfer three bytes, then
-     * the target sent the one byte IDENTIFY message followed by a two byte
-     * queue message.
-     *
-     * If there were two bytes of residual, we got the IDENTIFY message
-     * only.
-     *
-     * If there was one byte of residual, we got the IDENTIFY message
-     * followed by a RESTORE pointers message (which was ignored - 
-     * see MSGIN phase of the NCR5380_information_transfer() function.
-     */
-
-    if (!len) 
-	tag = msg[2];
-    else
-	tag = 0;
-#endif
 
     if (!msg[0] & 0x80) {
 	printk("scsi%d : expecting IDENTIFY message, got ",
@@ -2165,14 +2383,26 @@
 	print_msg(msg);
 	abort = 1;
     } else {
-
+	/* Accept message by clearing ACK */
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 	lun = (msg[0] & 0x07);
 
 	/* 
+	 * We need to add code for SCSI-II to track which devices have
+	 * I_T_L_Q nexuses established, and which have simple I_T_L
+	 * nexuses so we can chose to do additional data transfer.
+ 	 */
+
+#ifdef SCSI2
+#error "SCSI-II tagged queueing is not supported yet"
+#endif
+
+	/* 
 	 * Find the command corresponding to the I_T_L or I_T_L_Q  nexus we 
 	 * just restablished, and remove it from the disconnected queue.
 	 */
 
+
 	for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; 
 	    tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble) 
 	    if ((target_mask == (1 << tmp->target)) && (lun == tmp->lun)
@@ -2215,7 +2445,7 @@
 	hostdata->connected = tmp;
 #if (NDEBUG & NDEBUG_RESELECTION)
 	printk"scsi%d : nexus established, target = %d, lun = %d, tag = %d\n",
-	    instance->host_no, cmd->target, cmd->lun, cmd->tag);
+	    instance->host_no, tmp->target, tmp->lun, tmp->tag);
 #endif
     }
 }
@@ -2297,6 +2527,11 @@
     unsigned char msg, phase, *msgptr;
     int len;
 
+    printk("scsi%d : aborting command\n", instance->host_no);
+    print_Scsi_Cmnd (cmd);
+
+    NCR5380_print_status (instance);
+
     cli();
     NCR5380_setup(instance);
     
@@ -2305,8 +2540,42 @@
     printk("        basr 0x%X, sr 0x%X\n", 
 	   NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG));
 #endif
+
+#if 0
+/*
+ * Case 1 : If the command is the currently executing command, 
+ * we'll set the aborted flag and return control so that 
+ * information transfer routine can exit cleanly.
+ */
+
+    if (hostdata->connected == cmd) {
+#if (NDEBUG & NDEBUG_ABORT)
+	printk("scsi%d : aborting connected command\n", instance->host_no);
+#endif
+	hostdata->aborted = 1;
+/*
+ * We should perform BSY checking, and make sure we haven't slipped
+ * into BUS FREE.
+ */
+
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN);
+/* 
+ * Since we can't change phases until we've completed the current 
+ * handshake, we have to source or sink a byte of data if the current
+ * phase is not MSGOUT.
+ */
+
+/* 
+ * Return control to the executing NCR drive so we can clear the
+ * aborted flag and get back into our main loop.
+ */ 
+ 
+	return 0;
+    }
+#endif
+
 /* 
- * Case 1 : If the command hasn't been issued yet, we simply remove it 
+ * Case 2 : If the command hasn't been issued yet, we simply remove it 
  * 	    from the issue queue.
  */
     for (prev = (Scsi_Cmnd **) &(hostdata->issue_queue), 
@@ -2327,7 +2596,7 @@
 	}
 
 /* 
- * Case 2 : If any commands are connected, we're going to fail the abort
+ * Case 3 : If any commands are connected, we're going to fail the abort
  *	    and let the high level SCSI driver retry at a later time or 
  *	    issue a reset.
  *
@@ -2346,7 +2615,7 @@
     }
 
 /*
- * Case 3: If the command is currently disconnected from the bus, and 
+ * Case 4: If the command is currently disconnected from the bus, and 
  * 	there are no connected commands, we reconnect the I_T_L or 
  *	I_T_L_Q nexus associated with it, go into message out, and send 
  *      an abort message.
@@ -2408,7 +2677,7 @@
 	}
 
 /*
- * Case 4 : If we reached this point, the command was not found in any of 
+ * Case 5 : If we reached this point, the command was not found in any of 
  *	    the queues.
  *
  * We probably reached this point because of an unlikely race condition
@@ -2440,9 +2709,11 @@
     NCR5380_local_declare();
     NCR5380_setup(cmd->host);
 
+    NCR5380_print_status (cmd->host);
+
     cli();
     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
-    udelay(1);
+    udelay(25);
     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
     sti();
 
--- 1.1	1994/06/20 20:04:15
+++ ./drivers/scsi/NCR5380.h	1994/06/23 17:26:49
@@ -7,7 +7,7 @@
  * 	drew@colorado.edu
  *      +1 (303) 666-5836
  *
- * DISTRIBUTION RELEASE 4
+ * DISTRIBUTION RELEASE 6
  *
  * For more information, please consult 
  *
@@ -23,26 +23,15 @@
 
 /*
  * $Log: NCR5380.h,v $
- * Revision 1.1  1994/06/20  20:04:15  drew
- * Initial revision
- *
- * Revision 1.3  1994/01/19  05:24:40  drew
- * Added support for TCR LAST_BYTE_SENT bit.
- *
- * Revision 1.3  1994/01/19  05:24:40  drew
- * Added support for TCR LAST_BYTE_SENT bit.
- *
- * Revision 1.2  1994/01/15  06:14:11  drew
- * REAL DMA support, bug fixes.
- *
- * Revision 1.1  1994/01/15  06:00:54  drew
- * Initial revision
  */
 
 #ifndef NCR5380_H
 #define NCR5380_H
 
-#define NCR5380_PUBLIC_RELEASE 4
+#define NCR5380_PUBLIC_RELEASE 6
+#ifdef NCR53C400
+#define NCR53C400_PUBLIC_RELEASE 1
+#endif
 
 #define NDEBUG_ARBITRATION	0x1
 #define NDEBUG_AUTOSENSE	0x2
@@ -62,6 +51,8 @@
 #define NDEBUG_SELECTION	0x8000
 #define NDEBUG_USLEEP		0x10000
 #define NDEBUG_LAST_BYTE_SENT	0x20000
+#define NDEBUG_RESTART_SELECT	0x40000
+#define NDEBUG_EXTENDED		0x80000
 
 /* 
  * The contents of the OUTPUT DATA register are asserted on the bus when
@@ -167,6 +158,33 @@
 /* Write any value to this register to start an ini mode DMA recieve */
 #define START_DMA_INITIATOR_RECIEVE_REG 7	/* wo */
 
+#ifdef NCR53C400
+#define C400_CONTROL_STATUS_REG                -8      /* rw */
+
+#define CSR_RESET              0x80    /* wo  Resets 53c400 */
+#define CSR_53C80_REG          0x80    /* ro  5380 registers busy */
+#define CSR_TRANS_DIR          0x40    /* rw  Data transfer direction */
+#define CSR_SCSI_BUFF_INTR     0x20    /* rw  Enable int on transfer ready */
+#define CSR_53C80_INTR         0x10    /* rw  Enable 53c80 interupts */
+#define CSR_SHARED_INTR                0x08    /* rw  Interupt sharing */
+#define CSR_HOST_BUF_NOT_RDY   0x04    /* ro  Is Host buffer ready */
+#define CSR_SCSI_BUF_RDY       0x02    /* ro  SCSI buffer read */
+#define CSR_GATED_53C80_IRQ    0x01    /* ro  Last block xferred */
+
+#define CSR_BASE CSR_SCSI_BUFF_INTR | CSR_53C80_INTR
+
+/* Number of 128-byte blocks to be transferred */
+#define C400_CLOCK_COUNTER_REG         -7      /* rw */
+
+/* Resume transfer after disconnect */
+#define C400_RESUME_TRANSFER_REG       -6      /* wo */
+
+/* Access to host buffer stack */
+#define C400_HOST_BUFFER                       -4      /* rw */
+
+#endif /* NCR53C400 */
+
+
 /* Note : PHASE_* macros are based on the values of the STATUS register */
 #define PHASE_MASK 	(SR_MSG | SR_CD | SR_IO)
 
@@ -218,11 +236,15 @@
 
 #define FLAG_HAS_LAST_BYTE_SENT		1	/* NCR53c81 or better */
 #define FLAG_CHECK_LAST_BYTE_SENT	2	/* Only test once */
+#define FLAG_NCR53C400			4	/* NCR53c400 */
 
 #ifndef ASM
 struct NCR5380_hostdata {
     NCR5380_implementation_fields;		/* implmenentation specific */
     unsigned char id_mask, id_higher_mask;	/* 1 << id, all bits greater */
+    unsigned char targets_present;		/* targets we have connected
+						   to, so we can call a select
+						   failure a retryable condition */
     volatile unsigned char busy[8];		/* index = target, bit = lun */
 #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
     volatile int dma_len;			/* requested length of DMA */
@@ -231,6 +253,10 @@
     volatile Scsi_Cmnd *connected;		/* currently connected command */
     volatile Scsi_Cmnd *issue_queue;		/* waiting to be issued */
     volatile Scsi_Cmnd *disconnected_queue;	/* waiting for reconnect */
+    volatile int restart_select;		/* we have disconnected,
+						   used to restart 
+						   NCR5380_select() */
+    volatile unsigned aborted:1;		/* flag, says aborted */
     int flags;
 #ifdef USLEEP
     unsigned long time_expires;			/* in jiffies, set prior to sleeping */
@@ -244,7 +270,7 @@
 #if defined(AUTOPROBE_IRQ)
 static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible);
 #endif
-static void NCR5380_init (struct Scsi_Host *instance);
+static void NCR5380_init (struct Scsi_Host *instance, int flags);
 static void NCR5380_information_transfer (struct Scsi_Host *instance);
 static void NCR5380_intr (int irq);
 static void NCR5380_main (void);
--- 1.1	1994/06/20 20:13:58
+++ ./drivers/scsi/hosts.h	1994/06/23 17:25:59
@@ -108,9 +108,6 @@
 		can be filled in with the appropriate reason why we wanted
 		the abort in the first place, and this will be used
 		in the mid-level code instead of the host_byte().
-		If non-zero, the code passed to it 
-		will be used as the return code, otherwise 
-		DID_ABORT  should be returned.
 
 		Note that the scsi driver should "clean up" after itself, 
 		resetting the bus, etc.  if necessary. 
--- 1.1	1994/06/20 20:22:01
+++ ./drivers/scsi/hosts.c	1994/06/23 17:25:59
@@ -67,6 +67,10 @@
 #include "t128.h"
 #endif
 
+#ifdef CONFIG_SCSI_NCR53C7xx
+#include "53c7,8xx.h"
+#endif
+
 #ifdef CONFIG_SCSI_ULTRASTOR
 #include "ultrastor.h"
 #endif
@@ -143,6 +147,9 @@
 #endif
 #ifdef CONFIG_SCSI_T128
         TRANTOR_T128,
+#endif
+#ifdef CONFIG_SCSI_NCR53C7xx
+	NCR53c7xx,
 #endif
 #ifdef CONFIG_SCSI_7000FASST
 	WD7000,
diff -u -r1.1 -r2.1
--- 1.1	1994/06/20 20:24:37
+++ config.in	1994/06/20 20:50:36
@@ -50,10 +50,11 @@
 bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n
 bool 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 y
 bool 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 n
+#bool 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 n
 bool 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n
 bool 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n
 bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 n
-#bool 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 n
+bool 'NCR53c7,8xx SCSI support'  CONFIG_SCSI_NCR53C7xx n
 bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 n
 bool 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE n
 bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 n
