Resent-Date: Mon, 11 Jan 1999 16:05:59 +0100 (MET)
Date: Mon, 11 Jan 1999 14:54:35 +0100
From: Kars de Jong <jongk@cs.utwente.nl>
To: linux-m68k@lists.linux-m68k.org
Subject: NCR53C9x diff and other things
Mail-Followup-To: linux-m68k@lists.linux-m68k.org
Resent-From: linux-m68k@phil.uni-sb.de

Hi all,

The following patch is included:

NCR53C9x:
- Introduce esp_read()/esp_write() macros for ESP register accesses.
- Remove FAS366/HME support, it was kludgy and only used by the Sparc
  people who refuse to use the unified driver.
- Put module support back in, it was never ported back from the 2.0
  kernels. This is done for all Amiga drivers. The Mips, Mac and MCA
  people have to do it themselves, if desired.
General SCSI:
- Make more use of dep_tristate in the config file.
Module fix:
- Don't export symbols for strtok() and strpbrk().
Amiga internal serial port:
- According to the Amiga Hardware Reference Manual, the calculation for
  setting SERPER is (color_clock/baudrate) - 1. The - 1 was missing.
  This is not too bad for low speeds, but at high speeds it is fatal.
  Still too many overruns to be really usable though, even on a '060.

Oh, a peculiar thing when booting 2.2.0pre4 (with or without Andreas'
pinguin relocation patch): as soon as the screen is full the rest of
the kernel boot messages are printed on the first line of the screen.
It doesn't scroll.

Kars.

diff -ur linux-2.2.0pre4/arch/m68k/config.in linux/arch/m68k/config.in
--- linux-2.2.0pre4/arch/m68k/config.in	Fri Jan  8 13:37:18 1999
+++ linux/arch/m68k/config.in	Mon Jan 11 14:27:29 1999
@@ -129,19 +129,19 @@
 comment 'SCSI low-level drivers'
 
 if [ "$CONFIG_AMIGA" = "y" ]; then
-  tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI
+  dep_tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI $CONFIG_SCSI
   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
     bool 'A4000T SCSI support' CONFIG_A4000T_SCSI
   fi
 fi
 if [ "$CONFIG_ZORRO" = "y" ]; then
-  tristate 'A2091 WD33C93A support' CONFIG_A2091_SCSI
-  tristate 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI
-  bool 'CyberStorm SCSI support' CONFIG_CYBERSTORM_SCSI
-  bool 'CyberStorm Mk II SCSI support' CONFIG_CYBERSTORMII_SCSI
-  bool 'Blizzard 2060 SCSI support' CONFIG_BLZ2060_SCSI
-  bool 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI
-  bool 'Fastlane SCSI support' CONFIG_FASTLANE_SCSI
+  dep_tristate 'A2091 WD33C93A support' CONFIG_A2091_SCSI $CONFIG_SCSI
+  dep_tristate 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI $CONFIG_SCSI
+  dep_tristate 'CyberStorm SCSI support' CONFIG_CYBERSTORM_SCSI $CONFIG_SCSI
+  dep_tristate 'CyberStorm Mk II SCSI support' CONFIG_CYBERSTORMII_SCSI $CONFIG_SCSI
+  dep_tristate 'Blizzard 2060 SCSI support' CONFIG_BLZ2060_SCSI $CONFIG_SCSI
+  dep_tristate 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI $CONFIG_SCSI
+  dep_tristate 'Fastlane SCSI support' CONFIG_FASTLANE_SCSI $CONFIG_SCSI
   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
     bool 'A4091 SCSI support' CONFIG_A4091_SCSI
     bool 'WarpEngine SCSI support' CONFIG_WARPENGINE_SCSI
@@ -162,7 +162,7 @@
 fi
 if [ "$CONFIG_MAC" = "y" ]; then
   bool 'MAC NCR5380 SCSI' CONFIG_MAC_SCSI
-  bool 'MAC NCR53c9[46] SCSI' CONFIG_SCSI_MAC_ESP
+  dep_tristate 'MAC NCR53c9[46] SCSI' CONFIG_SCSI_MAC_ESP $CONFIG_SCSI
 fi
 #dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI
 
diff -ur linux-2.2.0pre4/arch/m68k/kernel/m68k_ksyms.c linux/arch/m68k/kernel/m68k_ksyms.c
--- linux-2.2.0pre4/arch/m68k/kernel/m68k_ksyms.c	Fri Jan  8 13:37:18 1999
+++ linux/arch/m68k/kernel/m68k_ksyms.c	Mon Jan 11 02:41:22 1999
@@ -45,8 +45,6 @@
 EXPORT_SYMBOL(strnlen);
 EXPORT_SYMBOL(strrchr);
 EXPORT_SYMBOL(strstr);
-EXPORT_SYMBOL(strtok);
-EXPORT_SYMBOL(strpbrk);
 EXPORT_SYMBOL(local_irq_count);
 EXPORT_SYMBOL(local_bh_count);
 EXPORT_SYMBOL(enable_irq);
diff -ur linux-2.2.0pre4/drivers/char/amiga_ser.c linux/drivers/char/amiga_ser.c
--- linux-2.2.0pre4/drivers/char/amiga_ser.c	Wed Aug 19 18:32:19 1998
+++ linux/drivers/char/amiga_ser.c	Mon Jan 11 02:45:27 1999
@@ -95,7 +95,7 @@
 };
 
 /* Standard speeds table */
-static int baud_table[17] = {
+static int baud_table[19] = {
     /* B0     */ 0,
     /* B50    */ 50,
     /* B75    */ 75,
@@ -112,7 +112,9 @@
     /* B9600  */ 9600,
     /* B19200 */ 19200,
     /* B38400 */ 38400,
-    /* B57600 */ 57600
+    /* B57600 */ 57600,
+    /* B115200*/ 115200,
+    /* B230400*/ 230400
 };
 	
 static __inline__ void ser_DTRoff(void)
@@ -363,11 +365,11 @@
 	    }
     }
     if (!div){
-	/* Maximum  speed is 57600 :-( */
-	if (baud > 16) baud = 16;
+	/* Maximum speed is 230400 :-) */
+	if (baud > 18) baud = 18;
 	realbaud = baud_table[baud];
 	if (realbaud)
-	    div = (amiga_colorclock+realbaud/2)/realbaud;
+	    div = (amiga_colorclock+realbaud/2)/realbaud - 1;
     }
 
     if (div) {
diff -ur linux-2.2.0pre4/drivers/scsi/NCR53C9x.c linux/drivers/scsi/NCR53C9x.c
--- linux-2.2.0pre4/drivers/scsi/NCR53C9x.c	Fri Dec 18 18:33:08 1998
+++ linux/drivers/scsi/NCR53C9x.c	Mon Jan 11 14:30:15 1999
@@ -18,6 +18,10 @@
  * 4) Maybe change use of "esp" to something more "NCR"'ish.
  */
 
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
@@ -33,15 +37,6 @@
 #include "hosts.h"
 #include "NCR53C9x.h"
 
-#ifdef CONFIG_SCSI_SUNESP
-#include "sparc_esp.h"
-#include <asm/sbus.h>
-#include <asm/dma.h>
-#include <asm/machines.h>
-#include <asm/oplib.h>
-#include <asm/idprom.h>
-#endif
-
 #include <asm/system.h>
 #include <asm/ptrace.h>
 #include <asm/pgtable.h>
@@ -303,10 +298,10 @@
 {
 	esp->espcmdlog[esp->espcmdent] = cmd;
 	esp->espcmdent = (esp->espcmdent + 1) & 31;
-	eregs->esp_cmd = cmd;
+	esp_write(eregs->esp_cmnd, cmd);
 }
 #else
-#define esp_cmd(__esp, __eregs, __cmd)	(__eregs)->esp_cmd = (__cmd)
+#define esp_cmd(__esp, __eregs, __cmd)	esp_write((__eregs)->esp_cmnd, (__cmd))
 #endif
 
 /* How we use the various Linux SCSI data structures for operation.
@@ -325,7 +320,6 @@
  *   the disconnect flag.
  */
 
-
 /* Manipulation of the ESP command queues.  Thanks to the aha152x driver
  * and its author, Juergen E. Fischer, for the methods used here.
  * Note that these are per-ESP queues, not global queues like
@@ -390,7 +384,7 @@
 	esp_cmd(esp, eregs, ESP_CMD_RC);
 	esp_cmd(esp, eregs, ESP_CMD_NULL | ESP_CMD_DMA);
 	if(esp->erev == fast)
-		eregs->esp_cfg2 = ESP_CONFIG2_FENAB;
+		esp_write(eregs->esp_cfg2, ESP_CONFIG2_FENAB);
 	esp_cmd(esp, eregs, ESP_CMD_NULL | ESP_CMD_DMA);
 
 	/* This is the only point at which it is reliable to read
@@ -399,16 +393,16 @@
 	esp->max_period = ((35 * esp->ccycle) / 1000);
 	if(esp->erev == fast) {
 		char *erev2string[] = {
-			"fas236",
-			"fas100a",
+			"Emulex FAS236",
+			"Emulex FPESP100A",
 			"fast",
-			"fasHME",
-			"fas216",
-			"SYM53CF9x-2 (FSC)",
+			"QLogic FAS366",
+			"Emulex FAS216",
+			"Symbios Logic 53CF9x-2",
 			"unknown!"
 		};
 			
-		version = eregs->esp_uid;
+		version = esp_read(eregs->esp_uid);
 		family_code = (version & 0xf8) >> 3;
 		if(family_code == 0x02) {
 		        if ((version & 7) == 2)
@@ -416,8 +410,13 @@
                         else
 			        esp->erev = fas236;
 		} else if(family_code == 0x0a)
-			esp->erev = fashme; /* Version is usually '5'. */
-		else if(family_code == 0x14) {
+			esp->erev = fas366; /* Version is usually '5'. */
+		else if(family_code == 0x00) {
+			if ((version & 7) == 2)
+				esp->erev = fas100a; /* NCR53C9X */
+			else
+				esp->erev = espunknown;
+		} else if(family_code == 0x14) {
 			if ((version & 7) == 2)
 				esp->erev = fsc;
 		        else
@@ -439,71 +438,63 @@
 	}
 
 	/* Reload the configuration registers */
-	eregs->esp_cfact = esp->cfact;
-	eregs->esp_stp   = esp->prev_stp = 0;
-	eregs->esp_soff  = esp->prev_soff = 0;
-	eregs->esp_timeo = esp->neg_defp;
+	esp_write(eregs->esp_cfact, esp->cfact);
+	esp->prev_stp = 0;
+	esp_write(eregs->esp_stp, 0);
+	esp->prev_soff = 0;
+	esp_write(eregs->esp_soff, 0);
+	esp_write(eregs->esp_timeo, esp->neg_defp);
 	esp->max_period = (esp->max_period + 3)>>2;
 	esp->min_period = (esp->min_period + 3)>>2;
 
-	eregs->esp_cfg1  = esp->config1;
+	esp_write(eregs->esp_cfg1, esp->config1);
 	switch(esp->erev) {
 	case esp100:
 		/* nothing to do */
 		break;
 	case esp100a:
-		eregs->esp_cfg2 = esp->config2;
+		esp_write(eregs->esp_cfg2, esp->config2);
 		break;
 	case esp236:
 		/* Slow 236 */
-		eregs->esp_cfg2 = esp->config2;
-		eregs->esp_cfg3 = esp->prev_cfg3 = esp->config3[0];
+		esp_write(eregs->esp_cfg2, esp->config2);
+		esp->prev_cfg3 = esp->config3[0];
+		esp_write(eregs->esp_cfg3, esp->prev_cfg3);
+		break;
+	case fas366:
+		panic("esp: FAS366 support not present, please notify "
+		      "jongk@cs.utwente.nl");
 		break;
-	case fashme:
-		esp->config2 |= (ESP_CONFIG2_HME32 | ESP_CONFIG2_HMEFENAB);
-		/* fallthrough... */
-	case fas216:	    
+	case fas216:
 	case fas236:
 	case fsc:
-		/* Fast 236 or HME */
-		eregs->esp_cfg2 = esp->config2;
-		for(i=0; i<8; i++) {
-			if(esp->erev == fashme) {
-				unsigned char cfg3;
-
-				cfg3 = ESP_CONFIG3_FCLOCK | ESP_CONFIG3_OBPUSH;
-				if (esp->scsi_id >= 8)
-					cfg3 |= ESP_CONFIG3_IDBIT3;
-				esp->config3[i] |= cfg3;
-			} else {
-				esp->config3[i] |= ESP_CONFIG3_FCLK;
-			}
-		}
-		eregs->esp_cfg3 = esp->prev_cfg3 = esp->config3[0];
-		if(esp->erev == fashme) {
-			esp->radelay = 80;
-		} else {
-			if(esp->diff)
-				esp->radelay = 0;
-			else
-				esp->radelay = 96;
-		}
-		if(esp->erev == fsc) {
-			/* Different timeout constant for FSC */
-			esp->neg_defp =
-				FSC_NEG_DEFP(esp->cfreq,
-					     (esp->cfact == ESP_CCF_F0 ?
-					      ESP_CCF_F7 + 1 : esp->cfact));
-			eregs->esp_timeo = esp->neg_defp;
-			eregs->esp_cfg4 = ESP_CONFIG4_EAN;
-		}
+		/* Fast ESP variants */
+		esp_write(eregs->esp_cfg2, esp->config2);
+		for(i=0; i<8; i++)
+			esp->config3[i] |= ESP_CONFIG3_FCLK;
+		esp->prev_cfg3 = esp->config3[0];
+		esp_write(eregs->esp_cfg3, esp->prev_cfg3);
+		if(esp->diff)
+			esp->radelay = 0;
+		else
+			esp->radelay = 16;
+		/* Different timeout constant for these chips */
+		esp->neg_defp =
+			FSC_NEG_DEFP(esp->cfreq,
+				     (esp->cfact == ESP_CCF_F0 ?
+				      ESP_CCF_F7 + 1 : esp->cfact));
+		esp_write(eregs->esp_timeo, esp->neg_defp);
+		/* Enable Active Negotiation if possible */
+		if((esp->erev == fsc) && !esp->diff)
+			esp_write(eregs->esp_cfg4, ESP_CONFIG4_EAN);
 		break;
 	case fas100a:
 		/* Fast 100a */
-		eregs->esp_cfg2 = esp->config2;
+		esp_write(eregs->esp_cfg2, esp->config2);
 		for(i=0; i<8; i++)
 			esp->config3[i] |= ESP_CONFIG3_FCLOCK;
-		eregs->esp_cfg3 = esp->prev_cfg3 = esp->config3[0];
+		esp->prev_cfg3 = esp->config3[0];
+		esp_write(eregs->esp_cfg3, esp->prev_cfg3);
 		esp->radelay = 32;
 		break;
 	default:
@@ -512,7 +503,7 @@
 	};
 
 	/* Eat any bitrot in the chip */
-	trash = eregs->esp_intrpt;
+	trash = esp_read(eregs->esp_intrpt);
 	udelay(100);
 }
 
@@ -529,13 +520,13 @@
 	esp_reset_esp(esp, eregs);
 
 	/* Reset the SCSI bus, but tell ESP not to generate an irq */
-	eregs->esp_cfg1 |= ESP_CONFIG1_SRRDISAB;
+	esp_write(eregs->esp_cfg1, (esp_read(eregs->esp_cfg1) | ESP_CONFIG1_SRRDISAB));
 	esp_cmd(esp, eregs, ESP_CMD_RS);
 	udelay(400);
-	eregs->esp_cfg1 = esp->config1;
+	esp_write(eregs->esp_cfg1, esp->config1);
 
 	/* Eat any bitrot in the chip and we are done... */
-	trash = eregs->esp_intrpt;
+	trash = esp_read(eregs->esp_intrpt);
 }
 
 /* Allocate structure and insert basic data such as SCSI chip frequency
@@ -672,16 +663,16 @@
 	/* Probe the revision of this esp */
 	esp->config1 = (ESP_CONFIG1_PENABLE | (esp->scsi_id & 7));
 	esp->config2 = (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY);
-	eregs->esp_cfg2 = esp->config2;
-	if((eregs->esp_cfg2 & ~(ESP_CONFIG2_MAGIC)) !=
+	esp_write(eregs->esp_cfg2, esp->config2);
+	if((esp_read(eregs->esp_cfg2) & ~(ESP_CONFIG2_MAGIC)) !=
 	   (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY)) {
 		printk("NCR53C90(esp100)\n");
 		esp->erev = esp100;
 	} else {
-		eregs->esp_cfg2 = esp->config2 = 0;
-		eregs->esp_cfg3 = 0;
-		eregs->esp_cfg3 = esp->prev_cfg3 = esp->config3[0] = 5;
-		if(eregs->esp_cfg3 != 5) {
+		esp->config2 = 0;
+		esp_write(eregs->esp_cfg2, 0);
+		esp_write(eregs->esp_cfg3, 5);
+		if(esp_read(eregs->esp_cfg3) != 5) {
 			printk("NCR53C90A(esp100a)\n");
 			esp->erev = esp100a;
 		} else {
@@ -689,16 +680,15 @@
 
 			for(target=0; target<8; target++)
 				esp->config3[target] = 0;
-			eregs->esp_cfg3 = esp->prev_cfg3 = 0;
+			esp->prev_cfg3 = 0;
+			esp_write(eregs->esp_cfg3, 0);
 			if(ccf > ESP_CCF_F5) {
 				printk("NCR53C9XF(espfast)\n");
 				esp->erev = fast;
-				eregs->esp_cfg2 = esp->config2 = 0;
 				esp->sync_defp = SYNC_DEFP_FAST;
 			} else {
 				printk("NCR53C9x(esp236)\n");
 				esp->erev = esp236;
-				eregs->esp_cfg2 = esp->config2 = 0;
 			}
 		}
 	}				
@@ -712,7 +702,7 @@
 	esp->targets_present = 0;
 	esp->resetting_bus = 0;
 	esp->snip = 0;
-	esp->targets_present = 0;
+	esp->fas_premature_intr_workaround = 0;
 	for(i = 0; i < 32; i++)
 		esp->espcmdlog[i] = 0;
 	esp->espcmdent = 0;
@@ -725,11 +715,13 @@
 
 	/* Clear the one behind caches to hold unmatchable values. */
 	esp->prev_soff = esp->prev_stp = esp->prev_cfg3 = 0xff;
-	esp->prev_hme_dmacsr = 0xffffffff;
 
 	/* Reset the thing before we try anything... */
 	esp_bootup_reset(esp, eregs);
 
+#ifdef MODULE
+	MOD_INC_USE_COUNT;
+#endif
 	esps_in_use++;
 }
 
@@ -748,17 +740,17 @@
 	case esp100a:
 		return "ESP100A (NCR53C90A)";
 	case esp236:
-		return "ESP236";
+		return "ESP236 (NCR53C9x)";
 	case fas216:
-		return "ESP216-FAST";
+		return "Emulex FAS216";
 	case fas236:
-		return "ESP236-FAST";
-	case fashme:
-		return "ESP366-HME";
+		return "Emulex FAS236";
+	case fas366:
+		return "QLogic FAS366";
 	case fas100a:
-		return "ESP100A-FAST";
+		return "FPESP100A";
 	case fsc:
-		return "FSC (SYM53CF9x-2)";
+		return "Symbios Logic 53CF9x-2";
 	default:
 		panic("Bogon ESP revision");
 	};
@@ -817,72 +809,41 @@
 	info.offset	= offset;
 	info.pos	= 0;
 
-	copy_info(&info, "Sparc ESP Host Adapter:\n");
-	copy_info(&info, "\tPROM node\t\t%08lx\n", (unsigned long) esp->prom_node);
-	copy_info(&info, "\tPROM name\t\t%s\n", esp->prom_name);
+	copy_info(&info, "ESP Host Adapter:\n");
 	copy_info(&info, "\tESP Model\t\t");
 	switch(esp->erev) {
 	case esp100:
-		copy_info(&info, "ESP100\n");
+		copy_info(&info, "ESP100 (NCR53C90)\n");
 		break;
 	case esp100a:
-		copy_info(&info, "ESP100A\n");
+		copy_info(&info, "ESP100A (NCR53C90A)\n");
 		break;
 	case esp236:
-		copy_info(&info, "ESP236\n");
+		copy_info(&info, "ESP236 (NCR53C9x)\n");
 		break;
 	case fas216:
-		copy_info(&info, "FAS216\n");
+		copy_info(&info, "Emulex FAS216\n");
 		break;
 	case fas236:
-		copy_info(&info, "FAS236\n");
+		copy_info(&info, "Emulex FAS236\n");
 		break;
 	case fas100a:
-		copy_info(&info, "FAS100A\n");
+		copy_info(&info, "FPESP100A\n");
 		break;
 	case fast:
-		copy_info(&info, "FAST\n");
+		copy_info(&info, "Generic FAST\n");
 		break;
-	case fashme:
-		copy_info(&info, "Happy Meal FAS\n");
+	case fas366:
+		copy_info(&info, "QLogic FAS366\n");
 		break;
 	case fsc:
-		copy_info(&info, "FSC\n");
+		copy_info(&info, "Symbios Logic 53C9x-2\n");
 		break;
 	case espunknown:
 	default:
 		copy_info(&info, "Unknown!\n");
 		break;
 	};
-#ifdef CONFIG_SCSI_SUNESP
-	copy_info(&info, "\tDMA Revision\t\t");
-	switch(((struct Linux_SBus_DMA*) (esp->dma))->revision) {
-	case dvmarev0:
-		copy_info(&info, "Rev 0\n");
-		break;
-	case dvmaesc1:
-		copy_info(&info, "ESC Rev 1\n");
-		break;
-	case dvmarev1:
-		copy_info(&info, "Rev 1\n");
-		break;
-	case dvmarev2:
-		copy_info(&info, "Rev 2\n");
-		break;
-	case dvmarev3:
-		copy_info(&info, "Rev 3\n");
-		break;
-	case dvmarevplus:
-		copy_info(&info, "Rev 1+\n");
-		break;
-	case dvmahme:
-		copy_info(&info, "Rev HME/FAS\n");
-		break;
-	default:
-		copy_info(&info, "Unknown!\n");
-		break;
-	};
-#endif
 	copy_info(&info, "\tLive Targets\t\t[ ");
 	for(i = 0; i < 15; i++) {
 		if(esp->targets_present & (1 << i))
@@ -891,7 +852,7 @@
 	copy_info(&info, "]\n\n");
 	
 	/* Now describe the state of each existing target. */
-	copy_info(&info, "Target #\tconfig3\t\tSync Capabilities\tDisconnect\tWide\n");
+	copy_info(&info, "Target #\tconfig3\t\tSync Capabilities\tDisconnect\n");
 	for(i = 0; i < 15; i++) {
 		if(esp->targets_present & (1 << i)) {
 			Scsi_Device *SDptr = esp->ehost->host_queue;
@@ -905,9 +866,7 @@
 			copy_info(&info, "%08lx\t", esp->config3[i]);
 			copy_info(&info, "[%02lx,%02lx]\t\t\t", SDptr->sync_max_offset,
 				  SDptr->sync_min_period);
-			copy_info(&info, "%s\t\t", SDptr->disconnect ? "yes" : "no");
-			copy_info(&info, "%s\n",
-				  (esp->config3[i] & ESP_CONFIG3_EWIDE) ? "yes" : "no");
+			copy_info(&info, "%s\n", SDptr->disconnect ? "yes" : "no");
 		}
 	}
 
@@ -1037,28 +996,6 @@
 	esp->msgout_len = 5;
 }
 
-/* SIZE is in bits, currently HME only supports 16 bit wide transfers. */
-static inline void build_wide_nego_msg(struct NCR_ESP *esp, int size)
-{
-	esp->cur_msgout[0] = EXTENDED_MESSAGE;
-	esp->cur_msgout[1] = 2;
-	esp->cur_msgout[2] = EXTENDED_WDTR;
-	switch(size) {
-	case 32:
-		esp->cur_msgout[3] = 2;
-		break;
-	case 16:
-		esp->cur_msgout[3] = 1;
-		break;
-	case 8:
-	default:
-		esp->cur_msgout[3] = 0;
-		break;
-	};
-
-	esp->msgout_len = 4;
-}
-
 static void esp_exec_cmd(struct NCR_ESP *esp)
 {
 	struct ESP_regs *eregs = esp->eregs;
@@ -1123,7 +1060,7 @@
 
 	if(SDptr->sync) {
 		/* this targets sync is known */
-#if defined(CONFIG_SCSI_SUNESP) || defined(CONFIG_SCSI_MAC_ESP)
+#ifdef CONFIG_SCSI_MAC_ESP
 do_sync_known:
 #endif
 		if(SDptr->disconnect)
@@ -1160,26 +1097,6 @@
 	} else {
 		int toshiba_cdrom_hwbug_wkaround = 0;
 
-#ifdef CONFIG_SCSI_SUNESP
-		/* Never allow disconnects or synchronous transfers on
-		 * SparcStation1 and SparcStation1+.  Allowing those
-		 * to be enabled seems to lockup the machine completely.
-		 */
-		if((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) ||
-		   (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) {
-			/* But we are nice and allow tapes to disconnect. */
-			if(SDptr->type == TYPE_TAPE)
-				SDptr->disconnect = 1;
-			else
-				SDptr->disconnect = 0;
-			SDptr->sync_max_offset = 0;
-			SDptr->sync_min_period = 0;
-			SDptr->sync = 1;
-			esp->snip = 0;
-			goto do_sync_known;
-		}
-#endif
-
 #ifdef CONFIG_SCSI_MAC_ESP
 		/* Never allow synchronous transfers (disconnect OK) on
 		 * Macintosh. Well, maybe later when we figured out how to 
@@ -1193,24 +1110,9 @@
 		goto do_sync_known;
 #endif
 		/* We've talked to this guy before,
-		 * but never negotiated.  Let's try,
-		 * need to attempt WIDE first, before
-		 * sync nego, as per SCSI 2 standard.
-		 */
-		if(esp->erev == fashme && !SDptr->wide) {
-			if(!SDptr->borken &&
-			   (SDptr->type != TYPE_ROM ||
-			    strncmp(SDptr->vendor, "TOSHIBA", 7))) {
-				build_wide_nego_msg(esp, 16);
-				SDptr->wide = 1;
-				esp->wnip = 1;
-				goto after_nego_msg_built;
-			} else {
-				SDptr->wide = 1;
-				/* Fall through and try sync. */
-			}
-		}
-
+		 * but never negotiated.  Let's try
+		 * sync negotiation.
+		 */
 		if(!SDptr->borken) {
 			if((SDptr->type == TYPE_ROM) &&
 			   (!strncmp(SDptr->vendor, "TOSHIBA", 7))) {
@@ -1228,7 +1130,6 @@
 		SDptr->sync = 1;
 		esp->snip = 1;
 
-after_nego_msg_built:
 		/* A fix for broken SCSI1 targets, when they disconnect
 		 * they lock up the bus and confuse ESP.  So disallow
 		 * disconnects for SCSI1 targets for now until we
@@ -1277,22 +1178,19 @@
 		for(i = 0; i < SCptr->cmd_len; i++)
 			*cmdp++ = SCptr->cmnd[i];
 
-	/* HME sucks... */
-	if(esp->erev == fashme)
-		eregs->esp_busid = (target & 0xf) |
-			(ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT);
-	else
-		eregs->esp_busid = (target & 7);
+	esp_write(eregs->esp_busid, (target & 7));
 	if (esp->prev_soff != SDptr->sync_max_offset ||
 	    esp->prev_stp  != SDptr->sync_min_period ||
 	    (esp->erev > esp100a &&
 	     esp->prev_cfg3 != esp->config3[target])) {
-		eregs->esp_soff = esp->prev_soff = SDptr->sync_max_offset;
-		eregs->esp_stp  = esp->prev_stp  = SDptr->sync_min_period;
-		if(esp->erev > esp100a)
-			eregs->esp_cfg3 =
-				esp->prev_cfg3 =
-				esp->config3[target];
+		esp->prev_soff = SDptr->sync_max_offset;
+		esp_write(eregs->esp_soff, esp->prev_soff);
+		esp->prev_stp = SDptr->sync_min_period;
+		esp_write(eregs->esp_stp, esp->prev_stp); 
+		if(esp->erev > esp100a) {
+			esp->prev_cfg3 = esp->config3[target];
+			esp_write(eregs->esp_cfg3, esp->prev_cfg3);
+		}
 	}
 	i = (cmdp - esp->esp_command);
 
@@ -1309,31 +1207,19 @@
 		esp_cmd(esp, eregs, ESP_CMD_FLUSH);
 
 		for(;j<i;j++)
-			eregs->esp_fdata = esp->esp_command[j];
+			esp_write(eregs->esp_fdata, esp->esp_command[j]);
 		the_esp_command &= ~ESP_CMD_DMA;
 
 		/* Tell ESP to "go". */
 		esp_cmd(esp, eregs, the_esp_command);
 	} else {
-		if(esp->erev == fashme) {
-			esp_cmd(esp, eregs, ESP_CMD_FLUSH); /* Grrr! */
-
-			/* Set up the HME counters */
-			eregs->esp_tclow = i;
-			eregs->esp_tcmed = 0;
-			eregs->fas_rlo = 0;
-			eregs->fas_rhi = 0;
-			esp_cmd(esp, eregs, the_esp_command);
-			esp->dma_init_write(esp, esp->esp_command_dvma, 16);
-		} else {
-			/* Set up the ESP counters */
-			eregs->esp_tclow = i;
-			eregs->esp_tcmed = 0;
-			esp->dma_init_write(esp, esp->esp_command_dvma, i);
+		/* Set up the ESP counters */
+		esp_write(eregs->esp_tclow, i);
+		esp_write(eregs->esp_tcmed, 0);
+		esp->dma_init_write(esp, esp->esp_command_dvma, i);
 
-			/* Tell ESP to "go". */
-			esp_cmd(esp, eregs, the_esp_command);
-		}
+		/* Tell ESP to "go". */
+		esp_cmd(esp, eregs, the_esp_command);
 	}
 }
 
@@ -1415,7 +1301,8 @@
 	ESPLOG(("esp%d: SW [sreg<%02x> sstep<%02x> ireg<%02x>]\n",
 		esp->esp_id, esp->sreg, esp->seqreg, esp->ireg));
 	ESPLOG(("esp%d: HW reread [sreg<%02x> sstep<%02x> ireg<%02x>]\n",
-		esp->esp_id, eregs->esp_status, eregs->esp_sstep, eregs->esp_intrpt));
+		esp->esp_id, esp_read(eregs->esp_status), esp_read(eregs->esp_sstep),
+		esp_read(eregs->esp_intrpt)));
 #ifdef DEBUG_ESP_CMDS
 	printk("esp%d: last ESP cmds [", esp->esp_id);
 	i = (esp->espcmdent - 1) & 31;
@@ -1625,62 +1512,6 @@
 #define sreg_datainp(__sreg)  (((__sreg) & ESP_STAT_PMASK) == ESP_DIP)
 #define sreg_dataoutp(__sreg) (((__sreg) & ESP_STAT_PMASK) == ESP_DOP)
 
-/* Read any bytes found in the FAS366 fifo, storing them into
- * the ESP driver software state structure.
- */
-static void hme_fifo_read(struct NCR_ESP *esp,
-			  struct ESP_regs *eregs)
-{
-	unsigned long count = 0;
-	unchar status = esp->sreg;
-
-	/* Cannot safely frob the fifo for these following cases, but
-	 * we must always read the fifo when the reselect interrupt
-	 * is pending.
-	 */
-	if(((esp->ireg & ESP_INTR_RSEL) == 0)	&&
-	   (sreg_datainp(status)		||
-	    sreg_dataoutp(status)		||
-	    (esp->current_SC &&
-	     esp->current_SC->SCp.phase == in_data_done))) {
-		ESPHME(("<wkaround_skipped>"));
-	} else {
-		unsigned long fcnt = eregs->esp_fflags & ESP_FF_FBYTES;
-
-		/* The HME stores bytes in multiples of 2 in the fifo. */
-		ESPHME(("hme_fifo[fcnt=%d", (int)fcnt));
-		while(fcnt) {
-			esp->hme_fifo_workaround_buffer[count++] = eregs->esp_fdata;
-			esp->hme_fifo_workaround_buffer[count++] = eregs->esp_fdata;
-			ESPHME(("<%02x,%02x>", esp->hme_fifo_workaround_buffer[count-2], esp->hme_fifo_workaround_buffer[count-1]));
-			fcnt--;
-		}
-		if(eregs->esp_status2 & ESP_STAT2_F1BYTE) {
-			ESPHME(("<poke_byte>"));
-			eregs->esp_fdata = 0;
-			esp->hme_fifo_workaround_buffer[count++] = eregs->esp_fdata;
-			ESPHME(("<%02x,0x00>", esp->hme_fifo_workaround_buffer[count-1]));
-			ESPHME(("CMD_FLUSH"));
-			esp_cmd(esp, eregs, ESP_CMD_FLUSH);
-		} else {
-			ESPHME(("no_xtra_byte"));
-		}
-	}
-	ESPHME(("wkarnd_cnt=%d]", (int)count));
-	esp->hme_fifo_workaround_count = count;
-}
-
-static inline void hme_fifo_push(struct NCR_ESP *esp, struct ESP_regs *eregs,
-				 unchar *bytes, unchar count)
-{
-	esp_cmd(esp, eregs, ESP_CMD_FLUSH);
-	while(count) {
-		eregs->esp_fdata = *bytes++;
-		eregs->esp_fdata = 0;
-		count--;
-	}
-}
-
 /* We try to avoid some interrupts by jumping ahead and see if the ESP
  * has gotten far enough yet.  Hence the following.
  */
@@ -1692,23 +1523,8 @@
 
 	if(esp->dma_irq_p(esp)) {
 		/* Yes, we are able to save an interrupt. */
-		if (esp->erev == fashme)
-			esp->sreg2 = eregs->esp_status2;
-		esp->sreg = (eregs->esp_status & ~(ESP_STAT_INTR));
-		esp->ireg = eregs->esp_intrpt;
-		if(esp->erev == fashme) {
-			/* This chip is really losing. */
-			ESPHME(("HME["));
-			/* Must latch fifo before reading the interrupt
-			 * register else garbage ends up in the FIFO
-			 * which confuses the driver utterly.
-			 * Happy Meal indeed....
-			 */
-			ESPHME(("fifo_workaround]"));
-			if(!(esp->sreg2 & ESP_STAT2_FEMPTY) ||
-			   (esp->sreg2 & ESP_STAT2_F1BYTE))
-				hme_fifo_read(esp, eregs);
-		}
+		esp->sreg = (esp_read(eregs->esp_status) & ~(ESP_STAT_INTR));
+		esp->ireg = esp_read(eregs->esp_intrpt);
 		if(!(esp->ireg & ESP_INTR_SR))
 			return 0;
 		else
@@ -1729,24 +1545,8 @@
 		return 0;
 	if(esp->dma_irq_p(esp)) {
 		/* Yes, we are able to save an interrupt. */
-		if (esp->erev == fashme)
-			esp->sreg2 = eregs->esp_status2;
-		esp->sreg = (eregs->esp_status & ~(ESP_STAT_INTR));
-		esp->ireg = eregs->esp_intrpt;
-		if(esp->erev == fashme) {
-			/* This chip is really losing. */
-			ESPHME(("HME["));
-
-			/* Must latch fifo before reading the interrupt
-			 * register else garbage ends up in the FIFO
-			 * which confuses the driver utterly.
-			 * Happy Meal indeed....
-			 */
-			ESPHME(("fifo_workaround]"));
-			if(!(esp->sreg2 & ESP_STAT2_FEMPTY) ||
-			   (esp->sreg2 & ESP_STAT2_F1BYTE))
-				hme_fifo_read(esp, eregs);
-		}
+		esp->sreg = (esp_read(eregs->esp_status) & ~(ESP_STAT_INTR));
+		esp->ireg = esp_read(eregs->esp_intrpt);
 		if(!(esp->ireg & ESP_INTR_SR))
 			return 0;
 		else
@@ -1758,26 +1558,19 @@
 }
 
 /* Misc. esp helper macros. */
-#define esp_setcount(__eregs, __cnt, __hme) \
-	(__eregs)->esp_tclow = ((__cnt) & 0xff); \
-	(__eregs)->esp_tcmed = (((__cnt) >> 8) & 0xff); \
-	if(__hme) { \
-		(__eregs)->fas_rlo = 0; \
-		(__eregs)->fas_rhi = 0; \
-	}
+#define esp_setcount(__eregs, __cnt) \
+	esp_write((__eregs)->esp_tclow, ((__cnt) & 0xff)); \
+	esp_write((__eregs)->esp_tcmed, (((__cnt) >> 8) & 0xff))
 
 #define esp_getcount(__eregs) \
-	((((__eregs)->esp_tclow)&0xff) | \
-	 ((((__eregs)->esp_tcmed)&0xff) << 8))
+	((esp_read((__eregs)->esp_tclow)&0xff) | \
+	 ((esp_read((__eregs)->esp_tcmed)&0xff) << 8))
 
 #define fcount(__esp, __eregs) \
-	(((__esp)->erev == fashme) ? \
-	  (__esp)->hme_fifo_workaround_count : \
-	  (__eregs)->esp_fflags & ESP_FF_FBYTES)
+	(esp_read((__eregs)->esp_fflags) & ESP_FF_FBYTES)
 
 #define fnzero(__esp, __eregs) \
-	(((__esp)->erev == fashme) ? 0 : \
-	 (__eregs)->esp_fflags & ESP_FF_ONOTZERO)
+	(esp_read((__eregs)->esp_fflags) & ESP_FF_ONOTZERO)
 
 /* XXX speculative nops unnecessary when continuing amidst a data phase
  * XXX even on esp100!!!  another case of flooding the bus with I/O reg
@@ -1803,7 +1596,7 @@
 {
 	/* Do not touch this piece of code. */
 	if((!(esp->erev == esp100)) ||
-	   (!(sreg_datainp((esp->sreg = eregs->esp_status)) && !fifocnt) &&
+	   (!(sreg_datainp((esp->sreg = esp_read(eregs->esp_status))) && !fifocnt) &&
 	    !(sreg_dataoutp(esp->sreg) && !fnzero(esp, eregs)))) {
 		if(sp->SCp.phase == in_dataout)
 			esp_cmd(esp, eregs, ESP_CMD_FLUSH);
@@ -1831,7 +1624,7 @@
 
 	if(esp->erev != esp100)
 		return 0;
-	junk = eregs->esp_intrpt;
+	junk = esp_read(eregs->esp_intrpt);
 
 	if(junk & ESP_INTR_SR)
 		return 1;
@@ -1847,24 +1640,14 @@
 
 	if(2 != fcount(esp, eregs))
 		return -1;
-	if(esp->erev == fashme) {
-		/* HME does not latch it's own BUS ID bits during
-		 * a reselection.  Also the target number is given
-		 * as an unsigned char, not as a sole bit number
-		 * like the other ESP's do.
-		 * Happy Meal indeed....
-		 */
-		targ = esp->hme_fifo_workaround_buffer[0];
-	} else {
-		it = eregs->esp_fdata;
-		if(!(it & me))
-			return -1;
-		it &= ~me;
-		if(it & (it - 1))
-			return -1;
-		while(!(it & 1))
-			targ++, it >>= 1;
-	}
+	it = esp_read(eregs->esp_fdata);
+	if(!(it & me))
+		return -1;
+	it &= ~me;
+	if(it & (it - 1))
+		return -1;
+	while(!(it & 1))
+		targ++, it >>= 1;
 	return targ;
 }
 
@@ -1877,10 +1660,7 @@
 
 	if((esp->sreg & ESP_STAT_PMASK) != ESP_MIP)
 		return -1;
-	if(esp->erev == fashme)
-		lun = esp->hme_fifo_workaround_buffer[1];
-	else
-		lun = eregs->esp_fdata;
+	lun = esp_read(eregs->esp_fdata);
 
 	/* Yes, you read this correctly.  We report lun of zero
 	 * if we see parity error.  ESP reports parity error for
@@ -1909,12 +1689,14 @@
 	   esp->prev_stp   != dp->sync_min_period ||
 	   (esp->erev > esp100a &&
 	    esp->prev_cfg3 != esp->config3[sp->target])) {
-		eregs->esp_soff = esp->prev_soff = dp->sync_max_offset;
-		eregs->esp_stp  = esp->prev_stp = dp->sync_min_period;
-		if(esp->erev > esp100a)
-			eregs->esp_cfg3 =
-				esp->prev_cfg3 =
-				esp->config3[sp->target];
+		esp->prev_soff = dp->sync_max_offset;
+		esp_write(eregs->esp_soff, esp->prev_soff);
+		esp->prev_stp = dp->sync_min_period;
+		esp_write(eregs->esp_stp, esp->prev_stp);
+		if(esp->erev > esp100a) {
+			esp->prev_cfg3 = esp->config3[sp->target];
+			esp_write(eregs->esp_cfg3, esp->prev_cfg3);
+		} 
 	}
 	esp->current_SC = sp;
 }
@@ -1936,9 +1718,7 @@
 /* Begin message in phase. */
 static int esp_do_msgin(struct NCR_ESP *esp, struct ESP_regs *eregs)
 {
-	/* Must be very careful with the fifo on the HME */
-	if((esp->erev != fashme) || !(eregs->esp_status2 & ESP_STAT2_FEMPTY))
-		esp_cmd(esp, eregs, ESP_CMD_FLUSH);
+	esp_cmd(esp, eregs, ESP_CMD_FLUSH);
 	esp_maybe_nop(esp, eregs);
 	esp_cmd(esp, eregs, ESP_CMD_TI);
 	esp->msgin_len = 1;
@@ -1952,10 +1732,10 @@
 	++sp->SCp.buffer;
 	--sp->SCp.buffers_residual;
 	sp->SCp.this_residual = sp->SCp.buffer->length;
-        if (esp->dma_advance_sg)
-	       esp->dma_advance_sg (sp);
-        else
-	       sp->SCp.ptr = (char *)virt_to_phys(sp->SCp.buffer->address);
+	if (esp->dma_advance_sg)
+		esp->dma_advance_sg (sp);
+	else
+		sp->SCp.ptr = (char *)virt_to_phys(sp->SCp.buffer->address);
 }
 
 /* Please note that the way I've coded these routines is that I _always_
@@ -1997,31 +1777,12 @@
 		 */
 		ESPDATA(("hmuch<%d> ", hmuch));
 		esp->current_transfer_size = hmuch;
-
-		if(esp->erev == fashme) {
-			/* Always set the ESP count registers first. */
-			esp_setcount(eregs, hmuch, 1);
-
-			/* Get the DMA csr computed. */
-
-			if (thisphase == in_datain)
-				esp->dma_init_read(esp, (__u32)((unsigned long)SCptr->SCp.ptr), hmuch);
-			else
-				esp->dma_init_write(esp, (__u32)((unsigned long)SCptr->SCp.ptr), hmuch);
-
-			if (thisphase == in_datain) {
-				esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
-			} else {
-				esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
-			}
-		} else {
-			esp_setcount(eregs, hmuch, 0);
-			esp->dma_setup(esp, 
-				       (__u32)((unsigned long)SCptr->SCp.ptr), 
-				       hmuch, (thisphase == in_datain));
-			ESPDATA(("DMA|TI --> do_intr_end\n"));
-			esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
-		}
+		esp_setcount(eregs, (esp->fas_premature_intr_workaround ?
+				     (hmuch + 0x40) : hmuch));
+		esp->dma_setup(esp, (__u32)((unsigned long)SCptr->SCp.ptr), 
+			       hmuch, (thisphase == in_datain));
+		ESPDATA(("DMA|TI --> do_intr_end\n"));
+		esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
 		return do_intr_end;
 		/*
 		 * end DMA
@@ -2050,7 +1811,7 @@
 		esp->current_transfer_size = hmuch;
 
 		/* tell the ESP ... */
-		esp_setcount(eregs, hmuch, 0);
+		esp_setcount(eregs, hmuch);
 
 		/* loop */
 		while (hmuch) {
@@ -2072,7 +1833,7 @@
 
 				/* wait for data */
 				timeout = 1000000;
-				while (!((esp->sreg=eregs->esp_status) & ESP_STAT_INTR) && --timeout)
+				while (!((esp->sreg=esp_read(eregs->esp_status)) & ESP_STAT_INTR) && --timeout)
 					udelay(2);
 				if (timeout == 0)
 					printk("DRQ datain timeout! \n");
@@ -2080,7 +1841,7 @@
 				newphase = esp->sreg & ESP_STAT_PMASK;
 
 				/* see how much we got ... */
-				fifocnt = (eregs->esp_fflags & ESP_FF_FBYTES);
+				fifocnt = (esp_read(eregs->esp_fflags) & ESP_FF_FBYTES);
 
 				if (!fifocnt)
 					fifo_stuck++;
@@ -2091,7 +1852,7 @@
 
 				/* read fifo */
 				for(j=0;j<fifocnt;j++)
-					SCptr->SCp.ptr[i++] = eregs->esp_fdata;
+					SCptr->SCp.ptr[i++] = esp_read(eregs->esp_fdata);
 
 				ESPDATA(("(%d) ", i));
 
@@ -2101,7 +1862,7 @@
 				/* break if status phase !! */
 				if(newphase == ESP_STATP) {
 					/* clear int. */
-					esp->ireg = eregs->esp_intrpt;
+					esp->ireg = esp_read(eregs->esp_intrpt);
 					break;
 				}
 			} else {
@@ -2113,7 +1874,7 @@
 
 				/* fill fifo */
 				for(j=0;j<this_count;j++)
-					eregs->esp_fdata = SCptr->SCp.ptr[i++];
+					esp_write(eregs->esp_fdata, SCptr->SCp.ptr[i++]);
 
 				/* how many left if this goes out ?? */
 				hmuch -= this_count;
@@ -2123,7 +1884,7 @@
 
 				/* wait for 'got it' */
 				timeout = 1000000;
-				while (!((esp->sreg=eregs->esp_status) & ESP_STAT_INTR) && --timeout)
+				while (!((esp->sreg=esp_read(eregs->esp_status)) & ESP_STAT_INTR) && --timeout)
 					udelay(2);
 				if (timeout == 0)
 					printk("DRQ dataout timeout!  \n");
@@ -2131,7 +1892,7 @@
 				newphase = esp->sreg & ESP_STAT_PMASK;
 
 				/* need to check how much was sent ?? */
-				fifocnt = (eregs->esp_fflags & ESP_FF_FBYTES);
+				fifocnt = (esp_read(eregs->esp_fflags) & ESP_FF_FBYTES);
 
 				ESPDATA(("\rsent %d st %x ph %x", this_count - fifocnt, esp->sreg, newphase));
 
@@ -2140,14 +1901,14 @@
 				/* break if status phase !! */
 				if(newphase == ESP_STATP) {
 					/* clear int. */
-					esp->ireg = eregs->esp_intrpt;
+					esp->ireg = esp_read(eregs->esp_intrpt);
 					break;
 				}
 
 			}
 
 			/* clear int. */
-			esp->ireg = eregs->esp_intrpt;
+			esp->ireg = esp_read(eregs->esp_intrpt);
 
 			ESPDATA(("ir %x ... ", esp->ireg));
 
@@ -2239,89 +2000,76 @@
 		return esp_do_phase_determine(esp, eregs);
 	}	
 
-	/* Check for partial transfers and other horrible events.
-	 * Note, here we read the real fifo flags register even
-	 * on HME broken adapters because we skip the HME fifo
-	 * workaround code in esp_handle() if we are doing data
-	 * phase things.  We don't want to fuck directly with
-	 * the fifo like that, especially if doing syncronous
-	 * transfers!  Also, will need to double the count on
-	 * HME if we are doing wide transfers, as the HME fifo
-	 * will move and count 16-bit quantities during wide data.
-	 * SMCC _and_ Qlogic can both bite me.
-	 */
-	fifocnt = eregs->esp_fflags & ESP_FF_FBYTES;
-	if(esp->erev != fashme)
-		ecount = esp_getcount(eregs);
+	/* Check for partial transfers and other horrible events. */
+	fifocnt = (esp_read(eregs->esp_fflags) & ESP_FF_FBYTES);
+	ecount = esp_getcount(eregs);
+	if(esp->fas_premature_intr_workaround)
+		ecount -= 0x40;
 	bytes_sent = esp->current_transfer_size;
 
 	ESPDATA(("trans_sz=%d, ", bytes_sent));
-	if(esp->erev == fashme) {
-		if(!(esp->sreg & ESP_STAT_TCNT)) {
-			ecount = esp_getcount(eregs);
-			bytes_sent -= ecount;
-		}
-
-		/* Always subtract any cruft remaining in the FIFO. */
-		if(esp->prev_cfg3 & ESP_CONFIG3_EWIDE)
-			fifocnt <<= 1;
-		if(SCptr->SCp.phase == in_dataout)
-			bytes_sent -= fifocnt;
-
-		/* I have an IBM disk which exhibits the following
-		 * behavior during writes to it.  It disconnects in
-		 * the middle of a partial transfer, the current sglist
-		 * buffer is 1024 bytes, the disk stops data transfer
-		 * at 512 bytes.
-		 *
-		 * However the FAS366 reports that 32 more bytes were
-		 * transferred than really were.  This is precisely
-		 * the size of a fully loaded FIFO in wide scsi mode.
-		 * The FIFO state recorded indicates that it is empty.
-		 *
-		 * I have no idea if this is a bug in the FAS366 chip
-		 * or a bug in the firmware on this IBM disk.  In any
-		 * event the following seems to be a good workaround.  -DaveM
-		 */
-		if (bytes_sent != esp->current_transfer_size &&
-		    SCptr->SCp.phase == in_dataout) {
-			int mask = (64 - 1);
-
-			if((esp->prev_cfg3 & ESP_CONFIG3_EWIDE) == 0)
-				mask >>= 1;
+	if(!(esp->sreg & ESP_STAT_TCNT))
+		bytes_sent -= ecount;
+	if(SCptr->SCp.phase == in_dataout)
+		bytes_sent -= fifocnt;
 
-			if (bytes_sent & mask)
-				bytes_sent -= (bytes_sent & mask);
-		}
-	} else {
-		if(!(esp->sreg & ESP_STAT_TCNT))
-			bytes_sent -= ecount;
-		if(SCptr->SCp.phase == in_dataout)
-			bytes_sent -= fifocnt;
-	}
-
-	ESPDATA(("bytes_sent=%d, ", bytes_sent));
+	ESPDATA(("bytes_sent=%d (ecount=%d, fifocnt=%d), ", bytes_sent,
+		 ecount, fifocnt));
 
 	/* If we were in synchronous mode, check for peculiarities. */
-	if(esp->erev == fashme) {
-		if(SCptr->device->sync_max_offset) {
-			if(SCptr->SCp.phase == in_dataout)
-				esp_cmd(esp, eregs, ESP_CMD_FLUSH);
-		} else {
-			esp_cmd(esp, eregs, ESP_CMD_FLUSH);
-		}
-	} else {
-		if(SCptr->device->sync_max_offset)
-			bogus_data = esp100_sync_hwbug(esp, eregs, SCptr, fifocnt);
-		else
-			esp_cmd(esp, eregs, ESP_CMD_FLUSH);
-	}
+	if(SCptr->device->sync_max_offset)
+		bogus_data = esp100_sync_hwbug(esp, eregs, SCptr, fifocnt);
+	else
+		esp_cmd(esp, eregs, ESP_CMD_FLUSH);
 
 	/* Until we are sure of what has happened, we are certainly
 	 * in the dark.
 	 */
 	esp_advance_phase(SCptr, in_the_dark);
 
+	/* Check for premature interrupt condition. Can happen on FAS2x6
+	 * chips. QLogic recommends a workaround by overprogramming the
+	 * transfer counters, but this makes doing scatter-gather impossible.
+	 * Until there is a way to disable scatter-gather for a single target,
+	 * and not only for the entire host adapter as it is now, the workaround
+	 * is way to expensive performance wise.
+	 * Instead, it turns out that when this happens the target has disconnected
+	 * allready but it doesn't show in the interrupt register. Compensate for
+	 * that here to try and avoid a SCSI bus reset.
+	 */
+	if(!esp->fas_premature_intr_workaround && (fifocnt == 1) &&
+	   sreg_dataoutp(esp->sreg)) {
+		ESPLOG(("esp%d: Premature interrupt, enabling workaround\n",
+			esp->esp_id));
+#if 0
+		/* Disable scatter-gather operations, they are not possible
+		 * when using this workaround.
+		 */
+		esp->ehost->sg_tablesize = 0;
+		esp->ehost->use_clustering = ENABLE_CLUSTERING;
+		esp->fas_premature_intr_workaround = 1;
+		bytes_sent = 0;
+		if(SCptr->use_sg) {
+			ESPLOG(("esp%d: Aborting scatter-gather operation\n",
+				esp->esp_id));
+			esp->cur_msgout[0] = ABORT;
+			esp->msgout_len = 1;
+			esp->msgout_ctr = 0;
+			esp_cmd(esp, eregs, ESP_CMD_SATN);
+			esp_setcount(eregs, 0xffff);
+			esp_cmd(esp, eregs, ESP_CMD_NULL);
+			esp_cmd(esp, eregs, ESP_CMD_TPAD | ESP_CMD_DMA);
+			return do_intr_end;
+		}
+#else
+		/* Just set the disconnected bit. That's what appears to
+		 * happen anyway. The state machine will pick it up when
+		 * we return.
+		 */
+		esp->ireg |= ESP_INTR_DC;
+#endif
+        }
+
 	if(bytes_sent < 0) {
 		/* I've seen this happen due to lost state in this
 		 * driver.  No idea why it happened, but allowing
@@ -2365,20 +2113,15 @@
 		 * imagine the hell I went through trying to
 		 * figure this out.
 		 */
-		if(SCptr->use_sg && !SCptr->SCp.this_residual)
+		if(!SCptr->SCp.this_residual && SCptr->SCp.buffers_residual)
 			advance_sg(esp, SCptr);
+#ifdef DEBUG_ESP_DATA
 		if(sreg_datainp(esp->sreg) || sreg_dataoutp(esp->sreg)) {
 			ESPDATA(("to more data\n"));
-			/*
-			 * XXX MSch:
-			 *
-			 * required for proper termination of data transfer 
-			 * phase in PIO mode
-			 */
-			if (!((esp->sreg & ESP_STAT_PMASK) == ESP_STATP))
-				return esp_do_data(esp, eregs);
+		} else {
+			ESPDATA(("to new phase\n"));
 		}
-		ESPDATA(("to new phase\n"));
+#endif
 		return esp_do_phase_determine(esp, eregs);
 	}
 	/* Bogus data, just wait for next interrupt. */
@@ -2445,7 +2188,7 @@
 	esp->prevmsgout = NOP;
 	if(esp->prevmsgin == COMMAND_COMPLETE) {
 		/* Normal end of nexus. */
-		if(esp->disconnected_SC || (esp->erev == fashme))
+		if(esp->disconnected_SC)
 			esp_cmd(esp, eregs, ESP_CMD_ESEL);
 
 		if(SCptr->SCp.Status != GOOD &&
@@ -2552,13 +2295,10 @@
 	/* Things look ok... */
 	ESPDISC(("R<%02x,%02x>", target, lun));
 
-	/* Must not flush FIFO or DVMA on HME. */
-	if(esp->erev != fashme) {
-		esp_cmd(esp, eregs, ESP_CMD_FLUSH);
-		if(esp100_reconnect_hwbug(esp, eregs))
-			return do_reset_bus;
-		esp_cmd(esp, eregs, ESP_CMD_NULL);
-	}
+	esp_cmd(esp, eregs, ESP_CMD_FLUSH);
+	if(esp100_reconnect_hwbug(esp, eregs))
+		return do_reset_bus;
+	esp_cmd(esp, eregs, ESP_CMD_NULL);
 
 	SCptr = remove_SC(&esp->disconnected_SC, (unchar) target, (unchar) lun);
 	if(!SCptr)
@@ -2567,10 +2307,6 @@
 	esp_connect(esp, eregs, SCptr);
 	esp_cmd(esp, eregs, ESP_CMD_MOK);
 
-	if(esp->erev == fashme)
-		eregs->esp_busid = (SCptr->target & 0xf) |
-			(ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT);
-
 	/* Reconnect implies a restore pointers operation. */
 	esp_restore_pointers(esp, SCptr);
 
@@ -2705,18 +2441,16 @@
 	if(esp->do_pio_cmds) {
 		esp_advance_phase(esp->current_SC, in_status);
 		esp_cmd(esp, eregs, thecmd);
-		while(!(esp->eregs->esp_status & ESP_STAT_INTR));
-		esp->esp_command[0] = eregs->esp_fdata;
-                while(!(esp->eregs->esp_status & ESP_STAT_INTR));
-                esp->esp_command[1] = eregs->esp_fdata;
-	} else {
-		if(esp->erev != fashme) {
-			esp->esp_command[0] = esp->esp_command[1] = 0xff;
-			eregs->esp_tclow = 2;
-			eregs->esp_tcmed = 0;
-			esp->dma_init_read(esp, esp->esp_command_dvma, 2);
-			thecmd |= ESP_CMD_DMA;
-		}
+		while(!(esp_read(esp->eregs->esp_status) & ESP_STAT_INTR));
+		esp->esp_command[0] = esp_read(eregs->esp_fdata);
+                while(!(esp_read(esp->eregs->esp_status) & ESP_STAT_INTR));
+                esp->esp_command[1] = esp_read(eregs->esp_fdata);
+	} else {
+		esp->esp_command[0] = esp->esp_command[1] = 0xff;
+		esp_write(eregs->esp_tclow, 2);
+		esp_write(eregs->esp_tcmed, 0);
+		esp->dma_init_read(esp, esp->esp_command_dvma, 2);
+		thecmd |= ESP_CMD_DMA;
 		esp_cmd(esp, eregs, thecmd);
 		esp_advance_phase(esp->current_SC, in_status);
 	}
@@ -2734,12 +2468,12 @@
 	 * here.  Unless we were actually trying
 	 * to force the device to abort/reset.
 	 */
-	ESPLOG(("esp%d Disconnect amidst phases, ", esp->esp_id));
+	ESPLOG(("esp%d: Disconnect amidst phases, ", esp->esp_id));
 	ESPLOG(("pphase<%s> cphase<%s>, ",
 		phase_string(sp->SCp.phase),
 		phase_string(sp->SCp.sent_command)));
 
-	if(esp->disconnected_SC || (esp->erev == fashme))
+	if(esp->disconnected_SC)
 		esp_cmd(esp, eregs, ESP_CMD_ESEL);
 
 	switch(esp->cur_msgout[0]) {
@@ -2830,12 +2564,7 @@
 	Scsi_Device *SDptr = SCptr->device;
 	int cmd_bytes_sent, fcnt;
 
-	if(esp->erev != fashme)
-		esp->seqreg = (eregs->esp_sstep & ESP_STEP_VBITS);
-	if(esp->erev == fashme)
-		fcnt = esp->hme_fifo_workaround_count;
-	else
-		fcnt = (eregs->esp_fflags & ESP_FF_FBYTES);
+	fcnt = (esp_read(eregs->esp_fflags) & ESP_FF_FBYTES);
 	cmd_bytes_sent = esp->dma_bytes_sent(esp, fcnt);
 	if(esp->dma_invalidate)
 		esp->dma_invalidate(esp);
@@ -2943,14 +2672,12 @@
 			if(SCptr->SCp.phase == in_slct_norm)
 				cmd_bytes_sent -= 1;
 		};
-		if(esp->erev != fashme)
-			esp_cmd(esp, eregs, ESP_CMD_NULL);
+		esp_cmd(esp, eregs, ESP_CMD_NULL);
 
 		/* Be careful, we could really get fucked during synchronous
 		 * data transfers if we try to flush the fifo now.
 		 */
-		if((esp->erev != fashme) && /* not a Happy Meal and... */
-		   !fcnt && /* Fifo is empty and... */
+		if(!fcnt && /* Fifo is empty and... */
 		   /* either we are not doing synchronous transfers or... */
 		   (!SDptr->sync_max_offset ||
 		    /* We are not going into data in phase. */
@@ -3069,9 +2796,9 @@
 	esp_print_seqreg(esp->seqreg);
 	printk("\n");
 	printk("esp%d: New -- ", esp->esp_id);
-	esp->sreg = eregs->esp_status;
-	esp->seqreg = eregs->esp_sstep;
-	esp->ireg = eregs->esp_intrpt;
+	esp->sreg = esp_read(eregs->esp_status);
+	esp->seqreg = esp_read(eregs->esp_sstep);
+	esp->ireg = esp_read(eregs->esp_intrpt);
 	esp_print_ireg(esp->ireg);
 	printk(" ");
 	esp_print_statreg(esp->sreg);
@@ -3216,12 +2943,7 @@
 		int hz = 1000000000 / (msg3 * 4);
 		int integer = hz / 1000000;
 		int fraction = (hz - (integer * 1000000)) / 10000;
-		if((esp->erev == fashme) &&
-		   (esp->config3[esp->current_SC->target] & ESP_CONFIG3_EWIDE)) {
-			type = "FAST-WIDE";
-			integer <<= 1;
-			fraction <<= 1;
-		} else if((msg3 * 4) < 200) {
+		if((msg3 * 4) < 200) {
 			type = "FAST";
 		} else {
 			type = "synchronous";
@@ -3312,7 +3034,7 @@
 			SDptr->sync_min_period = (regval & 0x1f);
 			SDptr->sync_max_offset = (offset | esp->radelay);
 			if(esp->erev > esp236) {
-				if((esp->erev == fas100a) || (esp->erev == fashme))
+				if(esp->erev == fas100a)
 					bit = ESP_CONFIG3_FAST;
 				else
 					bit = ESP_CONFIG3_FSCSI;
@@ -3320,10 +3042,13 @@
 					esp->config3[SCptr->target] |= bit;
 				else
 					esp->config3[SCptr->target] &= ~bit;
-				eregs->esp_cfg3 = esp->prev_cfg3 = esp->config3[SCptr->target];
+				esp->prev_cfg3 = esp->config3[SCptr->target];
+				esp_write(eregs->esp_cfg3, esp->prev_cfg3);
 			}
-			eregs->esp_soff = esp->prev_soff = SDptr->sync_min_period;
-			eregs->esp_stp  = esp->prev_stp  = SDptr->sync_max_offset;
+			esp->prev_soff = SDptr->sync_min_period;
+			esp_write(eregs->esp_soff, esp->prev_soff);
+			esp->prev_stp = SDptr->sync_max_offset;
+			esp_write(eregs->esp_stp, esp->prev_stp);
 
 			ESPSDTR(("soff=%2x stp=%2x cfg3=%2x\n",
 				SDptr->sync_max_offset,
@@ -3338,15 +3063,18 @@
 			ESPSDTR(("unaccaptable sync nego, forcing async\n"));
 			SDptr->sync_max_offset = 0;
 			SDptr->sync_min_period = 0;
-			eregs->esp_soff = esp->prev_soff = 0;
-			eregs->esp_stp = esp->prev_stp = 0;
+			esp->prev_soff = 0;
+			esp_write(eregs->esp_soff, 0);
+			esp->prev_stp = 0;
+			esp_write(eregs->esp_stp, 0);
 			if(esp->erev > esp236) {
-				if((esp->erev == fas100a) || (esp->erev == fashme))
+				if(esp->erev == fas100a)
 					bit = ESP_CONFIG3_FAST;
 				else
 					bit = ESP_CONFIG3_FSCSI;
 				esp->config3[SCptr->target] &= ~bit;
-				eregs->esp_cfg3 = esp->prev_cfg3 = esp->config3[SCptr->target];
+				esp->prev_cfg3 = esp->config3[SCptr->target];
+				esp_write(eregs->esp_cfg3, esp->prev_cfg3);
 			}
 		}
 
@@ -3367,46 +3095,12 @@
 		esp_advance_phase(SCptr, in_the_dark); /* ...or else! */
 		return 0;
 	} else if(esp->cur_msgin[2] == EXTENDED_WDTR) {
-		int size = 8 << esp->cur_msgin[3];
-
-		esp->wnip = 0;
-		if(esp->erev != fashme) {
-			ESPLOG(("esp%d: AIEEE wide msg received and not HME.\n",
-				esp->esp_id));
-			message_out = MESSAGE_REJECT;
-		} else if(size > 16) {
-			ESPLOG(("esp%d: AIEEE wide transfer for %d size "
-				"not supported.\n", esp->esp_id, size));
-			message_out = MESSAGE_REJECT;
-		} else {
-			/* Things look good; let's see what we got. */
-			if(size == 16) {
-				/* Set config 3 register for this target. */
-				esp->config3[SCptr->target] |= ESP_CONFIG3_EWIDE;
-			} else {
-				/* Just make sure it was one byte sized. */
-				if(size != 8) {
-					ESPLOG(("esp%d: Aieee, wide nego of %d size.\n",
-						esp->esp_id, size));
-					message_out = MESSAGE_REJECT;
-					goto finish;
-				}
-				/* Pure paranoia. */
-				esp->config3[SCptr->target] &= ~(ESP_CONFIG3_EWIDE);
-			}
-			eregs->esp_cfg3 = esp->prev_cfg3 = esp->config3[SCptr->target];
-
-			/* Regardless, next try for sync transfers. */
-			build_sync_nego_msg(esp, esp->sync_defp, 15);
-			SDptr->sync = 1;
-			esp->snip = 1;
-			message_out = EXTENDED_MESSAGE;
-		}
+		ESPLOG(("esp%d: AIEEE wide msg received\n", esp->esp_id));
+		message_out = MESSAGE_REJECT;
 	} else if(esp->cur_msgin[2] == EXTENDED_MODIFY_DATA_POINTER) {
 		ESPLOG(("esp%d: rejecting modify data ptr msg\n", esp->esp_id));
 		message_out = MESSAGE_REJECT;
 	}
-finish:
 	esp_advance_phase(SCptr, in_the_dark);
 	return message_out;
 }
@@ -3424,25 +3118,17 @@
 			if(esp->msgin_len && (esp->sreg & ESP_STAT_PERR)) {
 				message_out = MSG_PARITY_ERROR;
 				esp_cmd(esp, eregs, ESP_CMD_FLUSH);
-			} else if(esp->erev != fashme &&
-				  (it = (eregs->esp_fflags & ESP_FF_FBYTES))!=1) {
+			} else if((it = (esp_read(eregs->esp_fflags) & ESP_FF_FBYTES))!=1) {
 				/* We certainly dropped the ball somewhere. */
 				message_out = INITIATOR_ERROR;
 				esp_cmd(esp, eregs, ESP_CMD_FLUSH);
 			} else if(!esp->msgin_len) {
-				if(esp->erev == fashme)
-					it = esp->hme_fifo_workaround_buffer[0];
-				else
-					it = eregs->esp_fdata;
+				it = esp_read(eregs->esp_fdata);
 				esp_advance_phase(SCptr, in_msgincont);
 			} else {
 				/* it is ok and we want it */
-				if(esp->erev == fashme)
-					it = esp->cur_msgin[esp->msgin_ctr] =
-						esp->hme_fifo_workaround_buffer[0];
-				else
-					it = esp->cur_msgin[esp->msgin_ctr] =
-						eregs->esp_fdata;
+				it = esp->cur_msgin[esp->msgin_ctr] =
+					esp_read(eregs->esp_fdata);
 				esp->msgin_ctr++;
 			}
 		} else {
@@ -3483,7 +3169,7 @@
 		esp_advance_phase(SCptr, in_the_dark);
 		esp->msgin_len = 0;
 	}
-	esp->sreg = eregs->esp_status;
+	esp->sreg = esp_read(eregs->esp_status);
 	esp->sreg &= ~(ESP_STAT_INTR);
 	if((esp->sreg & (ESP_STAT_PMSG|ESP_STAT_PCD)) == (ESP_STAT_PMSG|ESP_STAT_PCD))
 		esp_cmd(esp, eregs, ESP_CMD_MOK);
@@ -3495,37 +3181,21 @@
 
 static int esp_do_cmdbegin(struct NCR_ESP *esp, struct ESP_regs *eregs)
 {
+	unsigned char tmp;
 	Scsi_Cmnd *SCptr = esp->current_SC;
 
 	esp_advance_phase(SCptr, in_cmdend);
-	if(esp->erev == fashme) {
-		int i;
-
-		for(i = 0; i < esp->esp_scmdleft; i++)
-			esp->esp_command[i] = *esp->esp_scmdp++;
-		esp->esp_scmdleft = 0;
-		esp_cmd(esp, eregs, ESP_CMD_FLUSH);
-		esp_setcount(eregs, i, 1);
-		esp_cmd(esp, eregs, (ESP_CMD_DMA | ESP_CMD_TI));
-		esp->dma_init_write(esp, esp->esp_command_dvma, i);
-	} else {
-		unsigned char tmp;
-		esp_cmd(esp, eregs, ESP_CMD_FLUSH);
-		tmp = *esp->esp_scmdp++;
-		esp->esp_scmdleft--;
-		eregs->esp_fdata = tmp;
-		esp_cmd(esp, eregs, ESP_CMD_TI);
-	}
+	esp_cmd(esp, eregs, ESP_CMD_FLUSH);
+	tmp = *esp->esp_scmdp++;
+	esp->esp_scmdleft--;
+	esp_write(eregs->esp_fdata, tmp);
+	esp_cmd(esp, eregs, ESP_CMD_TI);
 	return do_intr_end;
 }
 
 static int esp_do_cmddone(struct NCR_ESP *esp, struct ESP_regs *eregs)
 {
-	if(esp->erev == fashme){
-		if(esp->dma_invalidate)
-			esp->dma_invalidate(esp);
-	} else
-		esp_cmd(esp, eregs, ESP_CMD_NULL);
+	esp_cmd(esp, eregs, ESP_CMD_NULL);
 	if(esp->ireg & ESP_INTR_BSERV) {
 		esp_advance_phase(esp->current_SC, in_the_dark);
 		return esp_do_phase_determine(esp, eregs);
@@ -3540,64 +3210,51 @@
 	esp_cmd(esp, eregs, ESP_CMD_FLUSH);
 	switch(esp->msgout_len) {
 	case 1:
-		if(esp->erev == fashme)
-			hme_fifo_push(esp, eregs, &esp->cur_msgout[0], 1);
-		else
-			eregs->esp_fdata = esp->cur_msgout[0];
+		esp_write(eregs->esp_fdata, esp->cur_msgout[0]);
 		esp_cmd(esp, eregs, ESP_CMD_TI);
 		break;
 
 	case 2:
 		if(esp->do_pio_cmds){
-			eregs->esp_fdata = esp->cur_msgout[0];
-			eregs->esp_fdata = esp->cur_msgout[1];
+			esp_write(eregs->esp_fdata, esp->cur_msgout[0]);
+			esp_write(eregs->esp_fdata, esp->cur_msgout[1]);
 			esp_cmd(esp, eregs, ESP_CMD_TI);
 		} else {
 			esp->esp_command[0] = esp->cur_msgout[0];
 			esp->esp_command[1] = esp->cur_msgout[1];
-			if(esp->erev == fashme) {
-				hme_fifo_push(esp, eregs, &esp->cur_msgout[0], 2);
-				esp_cmd(esp, eregs, ESP_CMD_TI);
-			} else {
-				esp->dma_setup(esp, esp->esp_command_dvma, 2, 0);
-				esp_setcount(eregs, 2, 0);
-				esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
-			}
+			esp->dma_setup(esp, esp->esp_command_dvma, 2, 0);
+			esp_setcount(eregs, 2);
+			esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
 		}
 		break;
 
 	case 4:
 		esp->snip = 1;
 		if(esp->do_pio_cmds){
-			eregs->esp_fdata = esp->cur_msgout[0];
-			eregs->esp_fdata = esp->cur_msgout[1];
-			eregs->esp_fdata = esp->cur_msgout[2];
-			eregs->esp_fdata = esp->cur_msgout[3];
+			esp_write(eregs->esp_fdata, esp->cur_msgout[0]);
+			esp_write(eregs->esp_fdata, esp->cur_msgout[1]);
+			esp_write(eregs->esp_fdata, esp->cur_msgout[2]);
+			esp_write(eregs->esp_fdata, esp->cur_msgout[3]);
 			esp_cmd(esp, eregs, ESP_CMD_TI);
 		} else {
 			esp->esp_command[0] = esp->cur_msgout[0];
 			esp->esp_command[1] = esp->cur_msgout[1];
 			esp->esp_command[2] = esp->cur_msgout[2];
 			esp->esp_command[3] = esp->cur_msgout[3];
-			if(esp->erev == fashme) {
-				hme_fifo_push(esp, eregs, &esp->cur_msgout[0], 4);
-				esp_cmd(esp, eregs, ESP_CMD_TI);
-			} else {
-				esp->dma_setup(esp, esp->esp_command_dvma, 4, 0);
-				esp_setcount(eregs, 4, 0);
-				esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
-			}
+			esp->dma_setup(esp, esp->esp_command_dvma, 4, 0);
+			esp_setcount(eregs, 4);
+			esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
 		}
 		break;
 
 	case 5:
 		esp->snip = 1;
 		if(esp->do_pio_cmds){
-			eregs->esp_fdata = esp->cur_msgout[0];
-			eregs->esp_fdata = esp->cur_msgout[1];
-			eregs->esp_fdata = esp->cur_msgout[2];
-			eregs->esp_fdata = esp->cur_msgout[3];
-			eregs->esp_fdata = esp->cur_msgout[4];
+			esp_write(eregs->esp_fdata, esp->cur_msgout[0]);
+			esp_write(eregs->esp_fdata, esp->cur_msgout[1]);
+			esp_write(eregs->esp_fdata, esp->cur_msgout[2]);
+			esp_write(eregs->esp_fdata, esp->cur_msgout[3]);
+			esp_write(eregs->esp_fdata, esp->cur_msgout[4]);
 			esp_cmd(esp, eregs, ESP_CMD_TI);
 		} else {
 			esp->esp_command[0] = esp->cur_msgout[0];
@@ -3605,14 +3262,9 @@
 			esp->esp_command[2] = esp->cur_msgout[2];
 			esp->esp_command[3] = esp->cur_msgout[3];
 			esp->esp_command[4] = esp->cur_msgout[4];
-			if(esp->erev == fashme) {
-				hme_fifo_push(esp, eregs, &esp->cur_msgout[0], 5);
-				esp_cmd(esp, eregs, ESP_CMD_TI);
-			} else {
-				esp->dma_setup(esp, esp->esp_command_dvma, 5, 0);
-				esp_setcount(eregs, 5, 0);
-				esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
-			}
+			esp->dma_setup(esp, esp->esp_command_dvma, 5, 0);
+			esp_setcount(eregs, 5);
+			esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI);
 		}
 		break;
 
@@ -3620,11 +3272,7 @@
 		/* whoops */
 		ESPMISC(("bogus msgout sending NOP\n"));
 		esp->cur_msgout[0] = NOP;
-		if(esp->erev == fashme) {
-			hme_fifo_push(esp, eregs, &esp->cur_msgout[0], 1);
-		} else {
-			eregs->esp_fdata = esp->cur_msgout[0];
-		}
+		esp_write(eregs->esp_fdata, esp->cur_msgout[0]);
 		esp->msgout_len = 1;
 		esp_cmd(esp, eregs, ESP_CMD_TI);
 		break;
@@ -3640,8 +3288,7 @@
 		esp->dma_barrier(esp);
 
 	if(!(esp->ireg & ESP_INTR_DC)) {
-		if(esp->erev != fashme)
-			esp_cmd(esp, eregs, ESP_CMD_NULL);
+		esp_cmd(esp, eregs, ESP_CMD_NULL);
 		switch(esp->sreg & ESP_STAT_PMASK) {
 		case ESP_MOP:
 			/* whoops, parity error */
@@ -3656,17 +3303,12 @@
 			break;
 
 		default:
-			/* Happy Meal fifo is touchy... */
-			if((esp->erev != fashme) &&
-			   !fcount(esp, eregs) &&
+			if(!fcount(esp, eregs) &&
 			   !(esp->current_SC->device->sync_max_offset))
 				esp_cmd(esp, eregs, ESP_CMD_FLUSH);
 			break;
 
 		};
-	} else {
-		ESPLOG(("esp%d: disconnect, resetting bus\n", esp->esp_id));
-		return do_reset_bus;
 	}
 
 	/* If we sent out a synchronous negotiation message, update
@@ -3743,10 +3385,6 @@
 	struct ESP_regs *eregs;
 	Scsi_Cmnd *SCptr;
 	int what_next = do_intr_end;
-#ifdef CONFIG_SCSI_SUNESP
-	struct sparc_dma_registers *dregs = 
-	  (struct sparc_dma_registers*) esp->dregs;
-#endif
 	eregs = esp->eregs;
 	SCptr = esp->current_SC;
 
@@ -3754,12 +3392,12 @@
 		esp->dma_irq_entry(esp);
 
 	/* Check for errors. */
-	esp->sreg = eregs->esp_status;
+	esp->sreg = esp_read(eregs->esp_status);
 	esp->sreg &= (~ESP_STAT_INTR);
-	if(esp->erev == fashme) {
-		esp->sreg2 = eregs->esp_status2;
-		esp->seqreg = (eregs->esp_sstep & ESP_STEP_VBITS);
-	}
+	esp->seqreg = (esp_read(eregs->esp_sstep) & ESP_STEP_VBITS);
+	esp->ireg = eregs->esp_intrpt;   /* Unlatch intr and stat regs */
+	ESPIRQ(("handle_irq: [sreg<%02x> sstep<%02x> ireg<%02x>]\n",
+		esp->sreg, esp->seqreg, esp->ireg));
 	if(esp->sreg & (ESP_STAT_SPAM)) {
 		/* Gross error, could be due to one of:
 		 *
@@ -3791,49 +3429,6 @@
 		}
 	}
 
-#ifdef CONFIG_SCSI_SUNESP
-	if(dregs->cond_reg & DMA_HNDL_ERROR) {
-		/* A DMA gate array error.  Here we must
-		 * be seeing one of two things.  Either the
-		 * virtual to physical address translation
-		 * on the SBUS could not occur, else the
-		 * translation it did get pointed to a bogus
-		 * page.  Ho hum...
-		 */
-		ESPLOG(("esp%d: DMA error %08x\n", esp->esp_id,
-			dregs->cond_reg));
-
-		/* DMA gate array itself must be reset to clear the
-		 * error condition.
-		 */
-		if(esp->dma_reset)
-			esp->dma_reset(esp);
-
-		what_next = do_reset_bus;
-		goto state_machine;
-	}
-#endif /* CONFIG_SCSI_SUNESP */
-
-	esp->ireg = eregs->esp_intrpt;   /* Unlatch intr and stat regs */
-
-	if(esp->erev == fashme) {
-		/* This chip is really losing. */
-		ESPHME(("HME["));
-
-		ESPHME(("sreg2=%02x,", esp->sreg2));
-		/* Must latch fifo before reading the interrupt
-		 * register else garbage ends up in the FIFO
-		 * which confuses the driver utterly.
-		 */
-		if(!(esp->sreg2 & ESP_STAT2_FEMPTY) ||
-		   (esp->sreg2 & ESP_STAT2_F1BYTE)) {
-			ESPHME(("fifo_workaround]"));
-			hme_fifo_read(esp, eregs);
-		} else {
-			ESPHME(("no_fifo_workaround]"));
-		}
-	}
-
 	/* No current cmd is only valid at this point when there are
 	 * commands off the bus or we are trying a reset.
 	 */
@@ -3846,7 +3441,7 @@
 	if(esp->ireg & (ESP_INTR_IC)) {
 		/* Illegal command fed to ESP.  Outside of obvious
 		 * software bugs that could cause this, there is
-		 * a condition with esp100 where we can confuse the
+		 * a condition with ESP100 where we can confuse the
 		 * ESP into an erroneous illegal command interrupt
 		 * because it does not scrape the FIFO properly
 		 * for reselection.  See esp100_reconnect_hwbug()
@@ -3932,8 +3527,6 @@
 		esp->dma_irq_exit(esp);
 }
 
-#ifndef __sparc_v9__
-
 #ifndef __SMP__
 void esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
 {
@@ -3997,23 +3590,11 @@
 }
 #endif
 
-#else /* __sparc_v9__ */
-
-static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
+#ifdef MODULE
+int init_module(void) { return 0; }
+void cleanup_module(void) {}
+void esp_release(void)
 {
-	struct NCR_ESP *esp = dev_id;
-	unsigned long flags;
-
-	spin_lock_irqsave(&io_request_lock, flags);
-	if(esp->dma_irq_p(esp)) {
-		esp->dma_ints_off(dregs);
-
-		ESPIRQ(("I[%d:%d](", smp_processor_id(), esp->esp_id));
-		esp_handle(esp);
-		ESPIRQ((")"));
-
-		esp->dma_ints_on(esp);
-	}
-	spin_unlock_irqrestore(&io_request_lock, flags);
+	MOD_DEC_USE_COUNT;
 }
 #endif
diff -ur linux-2.2.0pre4/drivers/scsi/NCR53C9x.h linux/drivers/scsi/NCR53C9x.h
--- linux-2.2.0pre4/drivers/scsi/NCR53C9x.h	Fri Dec 18 18:33:08 1998
+++ linux/drivers/scsi/NCR53C9x.h	Mon Jan 11 02:19:53 1999
@@ -23,7 +23,6 @@
 /* Macros for debugging messages */
 
 #define DEBUG_ESP
-/* #define DEBUG_ESP_HME */
 /* #define DEBUG_ESP_DATA */
 /* #define DEBUG_ESP_QUEUE */
 /* #define DEBUG_ESP_DISCONNECT */
@@ -48,12 +47,6 @@
 #define ESPLOG(foo)
 #endif /* (DEBUG_ESP) */
 
-#if defined(DEBUG_ESP_HME)
-#define ESPHME(foo)  printk foo
-#else
-#define ESPHME(foo)
-#endif
-
 #if defined(DEBUG_ESP_DATA)
 #define ESPDATA(foo)  printk foo
 #else
@@ -131,6 +124,11 @@
  * apart with a big-endian ordering to the bytes.
  */
 
+#ifndef __i386__
+
+#define esp_write(__reg, __val) ((__reg) = (__val))
+#define esp_read(__reg) (__reg)
+
 struct ESP_regs {
                                 /* Access    Description              Offset */
     volatile unchar esp_tclow;  /* rw  Low bits of the transfer count 0x00   */
@@ -139,7 +137,7 @@
                                 EREGS_PAD(fdpad);
     volatile unchar esp_fdata;  /* rw  FIFO data bits                 0x08   */
                                 EREGS_PAD(cbpad);
-    volatile unchar esp_cmd;    /* rw  SCSI command bits              0x0c   */
+    volatile unchar esp_cmnd;   /* rw  SCSI command bits              0x0c   */
                                 EREGS_PAD(stpad);
     volatile unchar esp_status; /* ro  ESP status register            0x10   */
 #define esp_busid   esp_status  /* wo  Bus ID for select/reselect     0x10   */
@@ -156,7 +154,6 @@
     volatile unchar esp_cfg1;   /* rw  First configuration register   0x20   */
                                 EREGS_PAD(cfpad);
     volatile unchar esp_cfact;  /* wo  Clock conversion factor        0x24   */
-#define esp_status2 esp_cfact   /* ro  HME status2 register           0x24   */
                                 EREGS_PAD(ctpad);
     volatile unchar esp_ctest;  /* wo  Chip test register             0x28   */
                                 EREGS_PAD(cf2pd);
@@ -171,12 +168,47 @@
     /* The following is found on all chips except the NCR53C90 (ESP100) */
     volatile unchar esp_tchi;   /* rw  High bits of transfer count    0x38  */
 #define esp_uid     esp_tchi    /* ro  Unique ID code                 0x38  */
-#define fas_rlo     esp_tchi    /* rw  HME extended counter           0x38  */
                                 EREGS_PAD(fgpad);    
     volatile unchar esp_fgrnd;  /* rw  Data base for fifo             0x3c  */
-#define fas_rhi     esp_fgrnd   /* rw  HME extended counter           0x3c  */
 };
 
+#else /* !defined __i386__ */
+
+#define esp_write(__reg, __val) outb((__reg), (__val))
+#define esp_read(__reg) inb((__reg))
+
+struct ESP_regs {
+    unsigned int io_addr;
+                                  /* Access    Description              Offset */
+#define esp_tclow   io_addr      /* rw  Low bits of the transfer count 0x00   */
+#define esp_tcmed   io_addr + 1  /* rw  Mid bits of the transfer count 0x04   */
+#define esp_fdata   io_addr + 2  /* rw  FIFO data bits                 0x08   */
+#define esp_cmnd    io_addr + 3  /* rw  SCSI command bits              0x0c   */
+#define esp_status  io_addr + 4  /* ro  ESP status register            0x10   */
+#define esp_busid   esp_status   /* wo  Bus ID for select/reselect     0x10   */
+#define esp_intrpt  io_addr + 5  /* ro  Kind of interrupt              0x14   */
+#define esp_timeo   esp_intrpt   /* wo  Timeout value for select/resel 0x14   */
+#define esp_sstep   io_addr + 6  /* ro  Sequence step register         0x18   */
+#define esp_stp     esp_sstep    /* wo  Transfer period per sync       0x18   */
+#define esp_fflags  io_addr + 7  /* ro  Bits of current FIFO info      0x1c   */
+#define esp_soff    esp_fflags   /* wo  Sync offset                    0x1c   */
+#define esp_cfg1    io_addr + 8  /* rw  First configuration register   0x20   */
+#define esp_cfact   io_addr + 9  /* wo  Clock conversion factor        0x24   */
+#define esp_ctest   io_addr + 10 /* wo  Chip test register             0x28   */
+#define esp_cfg2    io_addr + 11 /* rw  Second configuration register  0x2c   */
+
+    /* The following is only found on the 53C9X series SCSI chips */
+#define esp_cfg3    io_addr + 12 /* rw  Third configuration register   0x30  */
+#define esp_cfg4    io_addr + 13 /* rw  Fourth configuration register  0x34  */
+
+    /* The following is found on all chips except the NCR53C90 (ESP100) */
+#define esp_tchi    io_addr + 14 /* rw  High bits of transfer count    0x38  */
+#define esp_uid     esp_tchi     /* ro  Unique ID code                 0x38  */
+#define esp_fgrnd   io_addr + 15 /* rw  Data base for fifo             0x3c  */
+};
+
+#endif /* !defined(__i386__) */
+
 /* Various revisions of the ESP board. */
 enum esp_rev {
   esp100     = 0x00,  /* NCR53C90 - very broken */
@@ -185,9 +217,9 @@
   fas236     = 0x03,
   fas100a    = 0x04,
   fast       = 0x05,
-  fashme     = 0x06,
+  fas366     = 0x06,
   fas216     = 0x07,
-  fsc        = 0x08,  /* NCR53C94-2 */
+  fsc        = 0x08,  /* SYM53C94-2 */
   espunknown = 0x09
 };
 
@@ -195,13 +227,11 @@
 struct NCR_ESP {
   struct NCR_ESP *next;                   /* Next ESP on probed or NULL */
   struct ESP_regs *eregs;	          /* All esp registers */
-  struct Linux_DMA *dma;                  /* Who I do transfers with. */
+  int dma;                                /* Who I do transfers with. */
   void *dregs;		  		  /* And his registers. */
   struct Scsi_Host *ehost;                /* Backpointer to SCSI Host */
 
   void *edev;        		          /* Pointer to controller base/SBus */
-  char prom_name[64];                     /* Name of ESP device from prom */
-  int prom_node;                          /* Prom node where ESP found */
   int esp_id;                             /* Unique per-ESP ID number */
 
   /* ESP Configuration Registers */
@@ -231,21 +261,18 @@
   unchar ireg;                            /* Copy of ESP interrupt register */
   unchar sreg;                            /* Same for ESP status register */
   unchar seqreg;                          /* The ESP sequence register */
-  unchar sreg2;                           /* Copy of HME status2 register */
+
+  /* The following is set when a premature interrupt condition is detected
+   * in some FAS revisions.
+   */
+  unchar fas_premature_intr_workaround;
 
   /* To save register writes to the ESP, which can be expensive, we
    * keep track of the previous value that various registers had for
    * the last target we connected to.  If they are the same for the
    * current target, we skip the register writes as they are not needed.
    */
-  unchar prev_soff, prev_stp, prev_cfg3, __cache_pad;
-
-  /* We also keep a cache of the previous FAS/HME DMA CSR register value.  */
-  unsigned int prev_hme_dmacsr;
-
-  /* The HME is the biggest piece of shit I have ever seen. */
-  unchar hme_fifo_workaround_buffer[16 * 2]; /* 16-bit/entry fifo for wide scsi */
-  unchar hme_fifo_workaround_count;
+  unchar prev_soff, prev_stp, prev_cfg3;
 
   /* For each target we keep track of save/restore data
    * pointer information.  This needs to be updated majorly
@@ -287,11 +314,11 @@
 
   /* Misc. info about this ESP */
   enum esp_rev erev;                      /* ESP revision */
-  int irq;                                /* SBus IRQ for this ESP */
+  int irq;                                /* IRQ for this ESP */
   int scsi_id;                            /* Who am I as initiator? */
   int scsi_id_mask;                       /* Bitmask of 'me'. */
   int diff;                               /* Differential SCSI bus? */
-  int bursts;                             /* Burst sizes our DVMA supports */
+  int slot;                               /* Slot the adapter occupies */
 
   /* Our command queues, only one cmd lives in the current_SC queue. */
   Scsi_Cmnd *issue_SC;           /* Commands to be issued */
@@ -363,36 +390,30 @@
 #define ESP_CONFIG2_HI        0x10             /* High Impedance DREQ ???  */
 #define ESP_CONFIG2_HMEFENAB  0x10             /* HME features enable */
 #define ESP_CONFIG2_BCM       0x20             /* Enable byte-ctrl (236,fsc)   */
-#define ESP_CONFIG2_DISPINT   0x20             /* Disable pause irq (hme) */
 #define ESP_CONFIG2_FENAB     0x40             /* Enable features (fas100,esp216,fsc)      */
 #define ESP_CONFIG2_SPL       0x40             /* Enable status-phase latch (esp236)   */
-#define ESP_CONFIG2_MKDONE    0x40             /* HME magic feature */
 #define ESP_CONFIG2_RFB       0x80             /* Reserve FIFO byte (fsc) */
-#define ESP_CONFIG2_HME32     0x80             /* HME 32 extended */
 #define ESP_CONFIG2_MAGIC     0xe0             /* Invalid bits... */
 
-/* ESP config register 3 read-write, found only esp236+fas236+fas100a+hme+fsc chips */
-#define ESP_CONFIG3_FCLOCK    0x01             /* FAST SCSI clock rate (esp100a/hme) */
+/* ESP config register 3 read-write, found only esp236+fas236+fas100a+fsc chips */
+#define ESP_CONFIG3_FCLOCK    0x01             /* FAST SCSI clock rate (esp100a/fas366) */
 #define ESP_CONFIG3_TEM       0x01             /* Enable thresh-8 mode (esp/fas236/fsc)  */
-#define ESP_CONFIG3_FAST      0x02             /* Enable FAST SCSI     (esp100a/hme) */
+#define ESP_CONFIG3_FAST      0x02             /* Enable FAST SCSI     (esp100a) */
 #define ESP_CONFIG3_ADMA      0x02             /* Enable alternate-dma (esp/fas236/fsc)  */
-#define ESP_CONFIG3_TENB      0x04             /* group2 SCSI2 support (esp100a/hme) */
+#define ESP_CONFIG3_TENB      0x04             /* group2 SCSI2 support (esp100a) */
 #define ESP_CONFIG3_SRB       0x04             /* Save residual byte   (esp/fas236/fsc)  */
-#define ESP_CONFIG3_TMS       0x08             /* Three-byte msg's ok  (esp100a/hme) */
+#define ESP_CONFIG3_TMS       0x08             /* Three-byte msg's ok  (esp100a) */
 #define ESP_CONFIG3_FCLK      0x08             /* Fast SCSI clock rate (esp/fas236/fsc)  */
-#define ESP_CONFIG3_IDMSG     0x10             /* ID message checking  (esp100a/hme) */
+#define ESP_CONFIG3_IDMSG     0x10             /* ID message checking  (esp100a) */
 #define ESP_CONFIG3_FSCSI     0x10             /* Enable FAST SCSI     (esp/fas236/fsc)  */
 #define ESP_CONFIG3_GTM       0x20             /* group2 SCSI2 support (esp/fas236/fsc)  */
-#define ESP_CONFIG3_IDBIT3    0x20             /* Bit 3 of HME SCSI-ID (hme)         */
 #define ESP_CONFIG3_TBMS      0x40             /* Three-byte msg's ok  (esp/fas236/fsc)  */
-#define ESP_CONFIG3_EWIDE     0x40             /* Enable Wide-SCSI     (hme)         */
 #define ESP_CONFIG3_IMS       0x80             /* ID msg chk'ng        (esp/fas236/fsc)  */
-#define ESP_CONFIG3_OBPUSH    0x80             /* Push odd-byte to dma (hme)         */
 
 /* ESP config register 4 read-write, found only on fsc chips */
-#define ESP_CONFIG4_BBTE      0x01;            /* Back-to-Back transfer enable */
-#define ESP_CONFIG4_TEST      0x02;            /* Transfer counter test mode */
-#define ESP_CONFIG4_EAN       0x04;            /* Enable Active Negotiation */
+#define ESP_CONFIG4_BBTE      0x01             /* Back-to-Back transfer enable */
+#define ESP_CONFIG4_TEST      0x02             /* Transfer counter test mode */
+#define ESP_CONFIG4_EAN       0x04             /* Enable Active Negotiation */
 
 /* ESP command register read-write */
 /* Group 1 commands:  These may be sent at any point in time to the ESP
@@ -443,10 +464,9 @@
 #define ESP_CMD_SA3           0x46             /* Select w/ATN3 */
 #define ESP_CMD_RSEL3         0x47             /* Reselect3 */
 
-/* This bit enables the ESP's DMA on the SBus */
+/* This bit enables the ESP's DMA */
 #define ESP_CMD_DMA           0x80             /* Do DMA? */
 
-
 /* ESP status register read-only */
 #define ESP_STAT_PIO          0x01             /* IO phase bit */
 #define ESP_STAT_PCD          0x02             /* CD phase bit */
@@ -456,21 +476,11 @@
 #define ESP_STAT_TCNT         0x10             /* Transfer Counter Is Zero */
 #define ESP_STAT_PERR         0x20             /* Parity error */
 #define ESP_STAT_SPAM         0x40             /* Real bad error */
-/* This indicates the 'interrupt pending' condition on esp236, it is a reserved
- * bit on other revs of the ESP.
+/* This indicates the 'interrupt pending' condition, it is a reserved
+ * bit on old revs of the ESP (ESP100, ESP100A, FAS100A).
  */
 #define ESP_STAT_INTR         0x80             /* Interrupt */
 
-/* HME only: status 2 register */
-#define ESP_STAT2_SCHBIT      0x01 /* Upper bits 3-7 of sstep enabled */
-#define ESP_STAT2_FFLAGS      0x02 /* The fifo flags are now latched */
-#define ESP_STAT2_XCNT        0x04 /* The transfer counter is latched */
-#define ESP_STAT2_CREGA       0x08 /* The command reg is active now */
-#define ESP_STAT2_WIDE        0x10 /* Interface on this adapter is wide */
-#define ESP_STAT2_F1BYTE      0x20 /* There is one byte at top of fifo */
-#define ESP_STAT2_FMSB        0x40 /* Next byte in fifo is most significant */
-#define ESP_STAT2_FEMPTY      0x80 /* FIFO is empty */
-
 /* The status register can be masked with ESP_STAT_PMASK and compared
  * with the following values to determine the current phase the ESP
  * (at least thinks it) is in.  For our purposes we also add our own
@@ -524,8 +534,8 @@
 #define ESP_TEST_TS           0x04             /* Tristate test mode */
 
 /* ESP unique ID register read-only, found on fas236+fas100a+fsc only */
-#define ESP_UID_F100A         0x00             /* ESP FAS100A  */
-#define ESP_UID_F236          0x02             /* ESP FAS236   */
+#define ESP_UID_F100A         0x00             /* FAS100A  */
+#define ESP_UID_F236          0x02             /* FAS236   */
 #define ESP_UID_FSC           0xa2             /* NCR53CF9x-2  */
 #define ESP_UID_REV           0x07             /* ESP revision */
 #define ESP_UID_FAM           0xf8             /* ESP family   */
@@ -546,10 +556,6 @@
 #define ESP_CCF_F6            0x06             /* 25.01MHz - 30MHz */
 #define ESP_CCF_F7            0x07             /* 30.01MHz - 35MHz */
 
-/* HME only... */
-#define ESP_BUSID_RESELID     0x10
-#define ESP_BUSID_CTR32BIT    0x40
-
 #define ESP_BUS_TIMEOUT        275             /* In milli-seconds */
 #define ESP_TIMEO_CONST       8192
 #define FSC_TIMEO_CONST       7668
@@ -575,6 +581,7 @@
 extern inline void esp_cmd(struct NCR_ESP *esp, struct ESP_regs *eregs,
 			   unchar cmd);
 extern struct NCR_ESP *esp_allocate(Scsi_Host_Template *, void *);
+extern void esp_release(void);
 extern void esp_initialize(struct NCR_ESP *);
 extern void esp_intr(int, void *, struct pt_regs *);
 #endif /* !(NCR53C9X_H) */
diff -ur linux-2.2.0pre4/drivers/scsi/blz1230.c linux/drivers/scsi/blz1230.c
--- linux-2.2.0pre4/drivers/scsi/blz1230.c	Fri Nov 13 01:56:20 1998
+++ linux/drivers/scsi/blz1230.c	Mon Jan 11 14:30:24 1999
@@ -14,6 +14,8 @@
  *    routines in this file used to be inline!
  */
 
+#include <linux/module.h>
+
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/types.h>
@@ -131,24 +133,24 @@
 
 		/* Set the command buffer */
 		esp->esp_command = (volatile unsigned char*) cmd_buffer;
-		esp->esp_command_dvma = virt_to_bus((unsigned long) cmd_buffer);
+		esp->esp_command_dvma = virt_to_bus(cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
+		esp->slot = key;
 		request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, 
 			    "Blizzard 1230 SCSI IV", esp_intr);
 
 		/* Figure out our scsi ID on the bus */
 		esp->scsi_id = 7;
 		
-		/* Check for differential SCSI-bus */
-		/* What is this stuff? */
+		/* We don't have a differential SCSI-bus. */
 		esp->diff = 0;
 
 		esp_initialize(esp);
 
 		zorro_config_board(key, 0);
 
-		printk("\nESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use);
+		printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use);
 		esps_running = esps_in_use;
 		return esps_in_use;
 	}
@@ -267,4 +269,29 @@
 	} else {
 		dma_init_write(esp, addr, count);
 	}
+}
+
+#ifdef MODULE
+
+#define HOSTS_C
+
+#include "blz1230.h"
+
+Scsi_Host_Template driver_template = SCSI_BLZ1230;
+
+#include "scsi_module.c"
+
+#endif
+
+int blz1230_esp_release(struct Scsi_Host *instance)
+{
+#ifdef MODULE
+	unsigned int key;
+
+	key = ((struct NCR_ESP *)instance->hostdata)->slot;
+	esp_release();
+	zorro_unconfig_board(key, 0);
+	free_irq(IRQ_AMIGA_PORTS, esp_intr);
+#endif
+	return 1;
 }
diff -ur linux-2.2.0pre4/drivers/scsi/blz1230.h linux/drivers/scsi/blz1230.h
--- linux-2.2.0pre4/drivers/scsi/blz1230.h	Tue May 19 18:52:36 1998
+++ linux/drivers/scsi/blz1230.h	Mon Jan 11 14:30:24 1999
@@ -48,6 +48,7 @@
 #define BLZ1230_DMA_WRITE 0x80000000
 
 extern int blz1230_esp_detect(struct SHT *);
+extern int blz1230_esp_release(struct Scsi_Host *);
 extern const char *esp_info(struct Scsi_Host *);
 extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 extern int esp_command(Scsi_Cmnd *);
@@ -57,9 +58,11 @@
 			 int hostno, int inout);
 
 #define SCSI_BLZ1230      { proc_dir:		&proc_scsi_esp, \
+			    proc_info:		esp_proc_info, \
 			    name:		"Blizzard1230 SCSI IV", \
 			    detect:		blz1230_esp_detect, \
-			    release:		NULL, \
+			    release:		blz1230_esp_release, \
+			    command:		esp_command, \
 			    queuecommand:	esp_queue, \
 			    abort:		esp_abort, \
 			    reset:		esp_reset, \
@@ -67,6 +70,6 @@
 			    this_id:		7, \
 			    sg_tablesize:	SG_ALL, \
 			    cmd_per_lun:	1, \
-			    use_clustering:	DISABLE_CLUSTERING }
+			    use_clustering:	ENABLE_CLUSTERING }
 
 #endif /* BLZ1230_H */
diff -ur linux-2.2.0pre4/drivers/scsi/blz2060.c linux/drivers/scsi/blz2060.c
--- linux-2.2.0pre4/drivers/scsi/blz2060.c	Fri Nov 13 01:56:20 1998
+++ linux/drivers/scsi/blz2060.c	Mon Jan 11 14:30:28 1999
@@ -14,6 +14,8 @@
  *    routines in this file used to be inline!
  */
 
+#include <linux/module.h>
+
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/types.h>
@@ -107,24 +109,24 @@
 		
 		/* Set the command buffer */
 		esp->esp_command = (volatile unsigned char*) cmd_buffer;
-		esp->esp_command_dvma = virt_to_bus((unsigned long) cmd_buffer);
+		esp->esp_command_dvma = virt_to_bus(cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
+		esp->slot = key;
 		request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, 
 			    "Blizzard 2060 SCSI", esp_intr);
 
 		/* Figure out our scsi ID on the bus */
 		esp->scsi_id = 7;
 		
-		/* Check for differential SCSI-bus */
-		/* What is this stuff? */
+		/* We don't have a differential SCSI-bus. */
 		esp->diff = 0;
 
 		esp_initialize(esp);
 
 		zorro_config_board(key, 0);
 
-		printk("\nESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use);
+		printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use);
 		esps_running = esps_in_use;
 		return esps_in_use;
 	}
@@ -230,4 +232,29 @@
 	} else {
 		dma_init_write(esp, addr, count);
 	}
+}
+
+#ifdef MODULE
+
+#define HOSTS_C
+
+#include "blz2060.h"
+
+Scsi_Host_Template driver_template = SCSI_BLZ2060;
+
+#include "scsi_module.c"
+
+#endif
+
+int blz2060_esp_release(struct Scsi_Host *instance)
+{
+#ifdef MODULE
+	unsigned int key;
+
+	key = ((struct NCR_ESP *)instance->hostdata)->slot;
+	esp_release();
+	zorro_unconfig_board(key, 0);
+	free_irq(IRQ_AMIGA_PORTS, esp_intr);
+#endif
+	return 1;
 }
diff -ur linux-2.2.0pre4/drivers/scsi/blz2060.h linux/drivers/scsi/blz2060.h
--- linux-2.2.0pre4/drivers/scsi/blz2060.h	Tue May 19 18:52:36 1998
+++ linux/drivers/scsi/blz2060.h	Mon Jan 11 14:30:28 1999
@@ -44,6 +44,7 @@
 #define BLZ2060_DMA_LED    0x02		/* HD led control 1 = off */
 
 extern int blz2060_esp_detect(struct SHT *);
+extern int blz2060_esp_release(struct Scsi_Host *);
 extern const char *esp_info(struct Scsi_Host *);
 extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 extern int esp_command(Scsi_Cmnd *);
@@ -53,9 +54,10 @@
 			 int hostno, int inout);
 
 #define SCSI_BLZ2060      { proc_dir:		&proc_scsi_esp, \
+			    proc_info:		esp_proc_info, \
 			    name:		"Blizzard2060 SCSI", \
 			    detect:		blz2060_esp_detect, \
-			    release:		NULL, \
+			    release:		blz2060_esp_release, \
 			    queuecommand:	esp_queue, \
 			    abort:		esp_abort, \
 			    reset:		esp_reset, \
@@ -63,6 +65,6 @@
 			    this_id:		7, \
 			    sg_tablesize:	SG_ALL, \
 			    cmd_per_lun:	1, \
-			    use_clustering:	DISABLE_CLUSTERING }
+			    use_clustering:	ENABLE_CLUSTERING }
 
 #endif /* BLZ2060_H */
diff -ur linux-2.2.0pre4/drivers/scsi/cyberstorm.c linux/drivers/scsi/cyberstorm.c
--- linux-2.2.0pre4/drivers/scsi/cyberstorm.c	Fri Nov 13 01:56:20 1998
+++ linux/drivers/scsi/cyberstorm.c	Mon Jan 11 14:30:33 1999
@@ -17,6 +17,8 @@
  *    routines in this file used to be inline!
  */
 
+#include <linux/module.h>
+
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/types.h>
@@ -127,9 +129,10 @@
 		
 		/* Set the command buffer */
 		esp->esp_command = (volatile unsigned char*) cmd_buffer;
-		esp->esp_command_dvma = virt_to_bus((unsigned long) cmd_buffer);
+		esp->esp_command_dvma = virt_to_bus(cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
+		esp->slot = key;
 		request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, 
 			    "CyberStorm SCSI", esp_intr);
 		/* Figure out our scsi ID on the bus */
@@ -140,15 +143,14 @@
 		 */
 		esp->scsi_id = 7;
 		
-		/* Check for differential SCSI-bus */
-		/* What is this stuff? */
+		/* We don't have a differential SCSI-bus. */
 		esp->diff = 0;
 
 		esp_initialize(esp);
 
 		zorro_config_board(key, 0);
 
-		printk("\nESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use);
+		printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use);
 		esps_running = esps_in_use;
 		return esps_in_use;
 	}
@@ -295,4 +297,29 @@
 	} else {
 		dma_init_write(esp, addr, count);
 	}
+}
+
+#ifdef MODULE
+
+#define HOSTS_C
+
+#include "cyberstorm.h"
+
+Scsi_Host_Template driver_template = SCSI_CYBERSTORM;
+
+#include "scsi_module.c"
+
+#endif
+
+int cyber_esp_release(struct Scsi_Host *instance)
+{
+#ifdef MODULE
+	unsigned int key;
+
+	key = ((struct NCR_ESP *)instance->hostdata)->slot;
+	esp_release();
+	zorro_unconfig_board(key, 0);
+	free_irq(IRQ_AMIGA_PORTS, esp_intr);
+#endif
+	return 1;
 }
diff -ur linux-2.2.0pre4/drivers/scsi/cyberstorm.h linux/drivers/scsi/cyberstorm.h
--- linux-2.2.0pre4/drivers/scsi/cyberstorm.h	Tue May 19 18:52:36 1998
+++ linux/drivers/scsi/cyberstorm.h	Mon Jan 11 14:30:33 1999
@@ -46,6 +46,7 @@
 #define CYBER_SLOW_CABLE 0x08	/* If *not* set, assume SLOW_CABLE */
 
 extern int cyber_esp_detect(struct SHT *);
+extern int cyber_esp_release(struct Scsi_Host *);
 extern const char *esp_info(struct Scsi_Host *);
 extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 extern int esp_command(Scsi_Cmnd *);
@@ -56,9 +57,10 @@
 
 
 #define SCSI_CYBERSTORM   { proc_dir:		&proc_scsi_esp, \
+			    proc_info:		esp_proc_info, \
 			    name:		"CyberStorm SCSI", \
 			    detect:		cyber_esp_detect, \
-			    release:		NULL, \
+			    release:		cyber_esp_release, \
 			    queuecommand:	esp_queue, \
 			    abort:		esp_abort, \
 			    reset:		esp_reset, \
@@ -66,7 +68,6 @@
 			    this_id:		7, \
 			    sg_tablesize:	SG_ALL, \
 			    cmd_per_lun:	1, \
-			    use_clustering:	DISABLE_CLUSTERING }
+			    use_clustering:	ENABLE_CLUSTERING }
 
 #endif /* CYBER_ESP_H */
-
diff -ur linux-2.2.0pre4/drivers/scsi/cyberstormII.c linux/drivers/scsi/cyberstormII.c
--- linux-2.2.0pre4/drivers/scsi/cyberstormII.c	Thu Sep 10 20:45:46 1998
+++ linux/drivers/scsi/cyberstormII.c	Mon Jan 11 14:30:36 1999
@@ -13,6 +13,8 @@
  *    routines in this file used to be inline!
  */
 
+#include <linux/module.h>
+
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/types.h>
@@ -118,24 +120,24 @@
 		
 		/* Set the command buffer */
 		esp->esp_command = (volatile unsigned char*) cmd_buffer;
-		esp->esp_command_dvma = virt_to_bus((unsigned long) cmd_buffer);
+		esp->esp_command_dvma = virt_to_bus(cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
+		esp->slot = key;
 		request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, 
 			    "CyberStorm SCSI Mk II", esp_intr);
 
 		/* Figure out our scsi ID on the bus */
 		esp->scsi_id = 7;
 		
-		/* Check for differential SCSI-bus */
-		/* What is this stuff? */
+		/* We don't have a differential SCSI-bus. */
 		esp->diff = 0;
 
 		esp_initialize(esp);
 
 		zorro_config_board(key, 0);
 
-		printk("\nESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use);
+		printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use);
 		esps_running = esps_in_use;
 		return esps_in_use;
 	}
@@ -242,4 +244,29 @@
 	} else {
 		dma_init_write(esp, addr, count);
 	}
+}
+
+#ifdef MODULE
+
+#define HOSTS_C
+
+#include "cyberstormII.h"
+
+Scsi_Host_Template driver_template = SCSI_CYBERSTORMII;
+
+#include "scsi_module.c"
+
+#endif
+
+int cyberII_esp_release(struct Scsi_Host *instance)
+{
+#ifdef MODULE
+	unsigned int key;
+
+	key = ((struct NCR_ESP *)instance->hostdata)->slot;
+	esp_release();
+	zorro_unconfig_board(key, 0);
+	free_irq(IRQ_AMIGA_PORTS, esp_intr);
+#endif
+	return 1;
 }
diff -ur linux-2.2.0pre4/drivers/scsi/cyberstormII.h linux/drivers/scsi/cyberstormII.h
--- linux-2.2.0pre4/drivers/scsi/cyberstormII.h	Tue May 19 18:52:36 1998
+++ linux/drivers/scsi/cyberstormII.h	Mon Jan 11 14:30:36 1999
@@ -34,6 +34,7 @@
 
 
 extern int cyberII_esp_detect(struct SHT *);
+extern int cyberII_esp_release(struct Scsi_Host *);
 extern const char *esp_info(struct Scsi_Host *);
 extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 extern int esp_command(Scsi_Cmnd *);
@@ -43,9 +44,10 @@
 			 int hostno, int inout);
 
 #define SCSI_CYBERSTORMII { proc_dir:		&proc_scsi_esp, \
+			    proc_info:		esp_proc_info, \
 			    name:		"CyberStorm Mk II SCSI", \
 			    detect:		cyberII_esp_detect, \
-			    release:		NULL, \
+			    release:		cyberII_esp_release, \
 			    queuecommand:	esp_queue, \
 			    abort:		esp_abort, \
 			    reset:		esp_reset, \
@@ -53,7 +55,6 @@
 			    this_id:		7, \
 			    sg_tablesize:	SG_ALL, \
 			    cmd_per_lun:	1, \
-			    use_clustering:	DISABLE_CLUSTERING }
+			    use_clustering:	ENABLE_CLUSTERING }
 
 #endif /* CYBERII_ESP_H */
-
diff -ur linux-2.2.0pre4/drivers/scsi/fastlane.c linux/drivers/scsi/fastlane.c
--- linux-2.2.0pre4/drivers/scsi/fastlane.c	Fri Nov 13 01:56:21 1998
+++ linux/drivers/scsi/fastlane.c	Mon Jan 11 14:30:40 1999
@@ -22,6 +22,8 @@
  *    routines in this file used to be inline!
  */
 
+#include <linux/module.h>
+
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/types.h>
@@ -163,17 +165,17 @@
 		
 		/* Set the command buffer */
 		esp->esp_command = (volatile unsigned char*) cmd_buffer;
-		esp->esp_command_dvma = virt_to_bus((unsigned long) cmd_buffer);
+		esp->esp_command_dvma = virt_to_bus(cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
+		esp->slot = key;
 		request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, 
 			    "Fastlane SCSI", esp_intr);
 
 		/* Controller ID */
 		esp->scsi_id = 7;
 		
-		/* Check for differential SCSI-bus */
-		/* What is this stuff? */
+		/* We don't have a differential SCSI-bus. */
 		esp->diff = 0;
 
 		dma_clear(esp);
@@ -181,7 +183,7 @@
 
 		zorro_config_board(key, 0);
 
-		printk("\nESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use);
+		printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use);
 		esps_running = esps_in_use;
 		return esps_in_use;
 	}
@@ -342,4 +344,29 @@
 	} else {
 		dma_init_write(esp, addr, count);
 	}
+}
+
+#ifdef MODULE
+
+#define HOSTS_C
+
+#include "fastlane.h"
+
+Scsi_Host_Template driver_template = SCSI_FASTLANE;
+
+#include "scsi_module.c"
+
+#endif
+
+int fastlane_esp_release(struct Scsi_Host *instance)
+{
+#ifdef MODULE
+	unsigned int key;
+
+	key = ((struct NCR_ESP *)instance->hostdata)->slot;
+	esp_release();
+	zorro_unconfig_board(key, 0);
+	free_irq(IRQ_AMIGA_PORTS, esp_intr);
+#endif
+	return 1;
 }
diff -ur linux-2.2.0pre4/drivers/scsi/fastlane.h linux/drivers/scsi/fastlane.h
--- linux-2.2.0pre4/drivers/scsi/fastlane.h	Tue May 19 18:52:37 1998
+++ linux/drivers/scsi/fastlane.h	Mon Jan 11 14:30:40 1999
@@ -39,6 +39,7 @@
 #define FASTLANE_DMA_ESI   0x01	/* Enable SCSI IRQ */
 
 extern int fastlane_esp_detect(struct SHT *);
+extern int fastlane_esp_release(struct Scsi_Host *);
 extern const char *esp_info(struct Scsi_Host *);
 extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 extern int esp_command(Scsi_Cmnd *);
@@ -48,9 +49,10 @@
 			 int hostno, int inout);
 
 #define SCSI_FASTLANE     { proc_dir:		&proc_scsi_esp, \
+			    proc_info:		esp_proc_info, \
 			    name:		"Fastlane SCSI", \
 			    detect:		fastlane_esp_detect, \
-			    release:		NULL, \
+			    release:		fastlane_esp_release, \
 			    queuecommand:	esp_queue, \
 			    abort:		esp_abort, \
 			    reset:		esp_reset, \
@@ -58,6 +60,6 @@
 			    this_id:		7, \
 			    sg_tablesize:	SG_ALL, \
 			    cmd_per_lun:	1, \
-			    use_clustering:	DISABLE_CLUSTERING }
+			    use_clustering:	ENABLE_CLUSTERING }
 
 #endif /* FASTLANE_H */

