diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c
new file mode 100644
index 0000000..d8ab73b
--- /dev/null
+++ b/drivers/scsi/esp.c
@@ -0,0 +1,4402 @@
+/* $Id: esp.c,v 1.101 2002/01/15 06:48:55 davem Exp $
+ * esp.c:  EnhancedScsiProcessor Sun SCSI driver code.
+ *
+ * Copyright (C) 1995, 1998 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+/* TODO:
+ *
+ * 1) Maybe disable parity checking in config register one for SCSI1
+ *    targets.  (Gilmore says parity error on the SBus can lock up
+ *    old sun4c's)
+ * 2) Add support for DMA2 pipelining.
+ * 3) Add tagged queueing.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/blkdev.h>
+#include <linux/proc_fs.h>
+#include <linux/stat.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+
+#include "esp.h"
+
+#include <asm/sbus.h>
+#include <asm/dma.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+#include <asm/pgtable.h>
+#include <asm/oplib.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#ifndef __sparc_v9__
+#include <asm/machines.h>
+#include <asm/idprom.h>
+#endif
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
+
+#define DEBUG_ESP
+/* #define DEBUG_ESP_HME */
+/* #define DEBUG_ESP_DATA */
+/* #define DEBUG_ESP_QUEUE */
+/* #define DEBUG_ESP_DISCONNECT */
+/* #define DEBUG_ESP_STATUS */
+/* #define DEBUG_ESP_PHASES */
+/* #define DEBUG_ESP_WORKBUS */
+/* #define DEBUG_STATE_MACHINE */
+/* #define DEBUG_ESP_CMDS */
+/* #define DEBUG_ESP_IRQS */
+/* #define DEBUG_SDTR */
+/* #define DEBUG_ESP_SG */
+
+/* Use the following to sprinkle debugging messages in a way which
+ * suits you if combinations of the above become too verbose when
+ * trying to track down a specific problem.
+ */
+/* #define DEBUG_ESP_MISC */
+
+#if defined(DEBUG_ESP)
+#define ESPLOG(foo)  printk foo
+#else
+#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
+#define ESPDATA(foo)
+#endif
+
+#if defined(DEBUG_ESP_QUEUE)
+#define ESPQUEUE(foo)  printk foo
+#else
+#define ESPQUEUE(foo)
+#endif
+
+#if defined(DEBUG_ESP_DISCONNECT)
+#define ESPDISC(foo)  printk foo
+#else
+#define ESPDISC(foo)
+#endif
+
+#if defined(DEBUG_ESP_STATUS)
+#define ESPSTAT(foo)  printk foo
+#else
+#define ESPSTAT(foo)
+#endif
+
+#if defined(DEBUG_ESP_PHASES)
+#define ESPPHASE(foo)  printk foo
+#else
+#define ESPPHASE(foo)
+#endif
+
+#if defined(DEBUG_ESP_WORKBUS)
+#define ESPBUS(foo)  printk foo
+#else
+#define ESPBUS(foo)
+#endif
+
+#if defined(DEBUG_ESP_IRQS)
+#define ESPIRQ(foo)  printk foo
+#else
+#define ESPIRQ(foo)
+#endif
+
+#if defined(DEBUG_SDTR)
+#define ESPSDTR(foo)  printk foo
+#else
+#define ESPSDTR(foo)
+#endif
+
+#if defined(DEBUG_ESP_MISC)
+#define ESPMISC(foo)  printk foo
+#else
+#define ESPMISC(foo)
+#endif
+
+/* Command phase enumeration. */
+enum {
+	not_issued    = 0x00,  /* Still in the issue_SC queue.          */
+
+	/* Various forms of selecting a target. */
+#define in_slct_mask    0x10
+	in_slct_norm  = 0x10,  /* ESP is arbitrating, normal selection  */
+	in_slct_stop  = 0x11,  /* ESP will select, then stop with IRQ   */
+	in_slct_msg   = 0x12,  /* select, then send a message           */
+	in_slct_tag   = 0x13,  /* select and send tagged queue msg      */
+	in_slct_sneg  = 0x14,  /* select and acquire sync capabilities  */
+
+	/* Any post selection activity. */
+#define in_phases_mask  0x20
+	in_datain     = 0x20,  /* Data is transferring from the bus     */
+	in_dataout    = 0x21,  /* Data is transferring to the bus       */
+	in_data_done  = 0x22,  /* Last DMA data operation done (maybe)  */
+	in_msgin      = 0x23,  /* Eating message from target            */
+	in_msgincont  = 0x24,  /* Eating more msg bytes from target     */
+	in_msgindone  = 0x25,  /* Decide what to do with what we got    */
+	in_msgout     = 0x26,  /* Sending message to target             */
+	in_msgoutdone = 0x27,  /* Done sending msg out                  */
+	in_cmdbegin   = 0x28,  /* Sending cmd after abnormal selection  */
+	in_cmdend     = 0x29,  /* Done sending slow cmd                 */
+	in_status     = 0x2a,  /* Was in status phase, finishing cmd    */
+	in_freeing    = 0x2b,  /* freeing the bus for cmd cmplt or disc */
+	in_the_dark   = 0x2c,  /* Don't know what bus phase we are in   */
+
+	/* Special states, ie. not normal bus transitions... */
+#define in_spec_mask    0x80
+	in_abortone   = 0x80,  /* Aborting one command currently        */
+	in_abortall   = 0x81,  /* Blowing away all commands we have     */
+	in_resetdev   = 0x82,  /* SCSI target reset in progress         */
+	in_resetbus   = 0x83,  /* SCSI bus reset in progress            */
+	in_tgterror   = 0x84,  /* Target did something stupid           */
+};
+
+enum {
+	/* Zero has special meaning, see skipahead[12]. */
+/*0*/	do_never,
+
+/*1*/	do_phase_determine,
+/*2*/	do_reset_bus,
+/*3*/	do_reset_complete,
+/*4*/	do_work_bus,
+/*5*/	do_intr_end
+};
+
+/* The master ring of all esp hosts we are managing in this driver. */
+static struct esp *espchain;
+static DEFINE_SPINLOCK(espchain_lock);
+static int esps_running = 0;
+
+/* Forward declarations. */
+static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs);
+
+/* Debugging routines */
+struct esp_cmdstrings {
+	u8 cmdchar;
+	char *text;
+} esp_cmd_strings[] = {
+	/* Miscellaneous */
+	{ ESP_CMD_NULL, "ESP_NOP", },
+	{ ESP_CMD_FLUSH, "FIFO_FLUSH", },
+	{ ESP_CMD_RC, "RSTESP", },
+	{ ESP_CMD_RS, "RSTSCSI", },
+	/* Disconnected State Group */
+	{ ESP_CMD_RSEL, "RESLCTSEQ", },
+	{ ESP_CMD_SEL, "SLCTNATN", },
+	{ ESP_CMD_SELA, "SLCTATN", },
+	{ ESP_CMD_SELAS, "SLCTATNSTOP", },
+	{ ESP_CMD_ESEL, "ENSLCTRESEL", },
+	{ ESP_CMD_DSEL, "DISSELRESEL", },
+	{ ESP_CMD_SA3, "SLCTATN3", },
+	{ ESP_CMD_RSEL3, "RESLCTSEQ", },
+	/* Target State Group */
+	{ ESP_CMD_SMSG, "SNDMSG", },
+	{ ESP_CMD_SSTAT, "SNDSTATUS", },
+	{ ESP_CMD_SDATA, "SNDDATA", },
+	{ ESP_CMD_DSEQ, "DISCSEQ", },
+	{ ESP_CMD_TSEQ, "TERMSEQ", },
+	{ ESP_CMD_TCCSEQ, "TRGTCMDCOMPSEQ", },
+	{ ESP_CMD_DCNCT, "DISC", },
+	{ ESP_CMD_RMSG, "RCVMSG", },
+	{ ESP_CMD_RCMD, "RCVCMD", },
+	{ ESP_CMD_RDATA, "RCVDATA", },
+	{ ESP_CMD_RCSEQ, "RCVCMDSEQ", },
+	/* Initiator State Group */
+	{ ESP_CMD_TI, "TRANSINFO", },
+	{ ESP_CMD_ICCSEQ, "INICMDSEQCOMP", },
+	{ ESP_CMD_MOK, "MSGACCEPTED", },
+	{ ESP_CMD_TPAD, "TPAD", },
+	{ ESP_CMD_SATN, "SATN", },
+	{ ESP_CMD_RATN, "RATN", },
+};
+#define NUM_ESP_COMMANDS  ((sizeof(esp_cmd_strings)) / (sizeof(struct esp_cmdstrings)))
+
+/* Print textual representation of an ESP command */
+static inline void esp_print_cmd(u8 espcmd)
+{
+	u8 dma_bit = espcmd & ESP_CMD_DMA;
+	int i;
+
+	espcmd &= ~dma_bit;
+	for (i = 0; i < NUM_ESP_COMMANDS; i++)
+		if (esp_cmd_strings[i].cmdchar == espcmd)
+			break;
+	if (i == NUM_ESP_COMMANDS)
+		printk("ESP_Unknown");
+	else
+		printk("%s%s", esp_cmd_strings[i].text,
+		       ((dma_bit) ? "+DMA" : ""));
+}
+
+/* Print the status register's value */
+static inline void esp_print_statreg(u8 statreg)
+{
+	u8 phase;
+
+	printk("STATUS<");
+	phase = statreg & ESP_STAT_PMASK;
+	printk("%s,", (phase == ESP_DOP ? "DATA-OUT" :
+		       (phase == ESP_DIP ? "DATA-IN" :
+			(phase == ESP_CMDP ? "COMMAND" :
+			 (phase == ESP_STATP ? "STATUS" :
+			  (phase == ESP_MOP ? "MSG-OUT" :
+			   (phase == ESP_MIP ? "MSG_IN" :
+			    "unknown")))))));
+	if (statreg & ESP_STAT_TDONE)
+		printk("TRANS_DONE,");
+	if (statreg & ESP_STAT_TCNT)
+		printk("TCOUNT_ZERO,");
+	if (statreg & ESP_STAT_PERR)
+		printk("P_ERROR,");
+	if (statreg & ESP_STAT_SPAM)
+		printk("SPAM,");
+	if (statreg & ESP_STAT_INTR)
+		printk("IRQ,");
+	printk(">");
+}
+
+/* Print the interrupt register's value */
+static inline void esp_print_ireg(u8 intreg)
+{
+	printk("INTREG< ");
+	if (intreg & ESP_INTR_S)
+		printk("SLCT_NATN ");
+	if (intreg & ESP_INTR_SATN)
+		printk("SLCT_ATN ");
+	if (intreg & ESP_INTR_RSEL)
+		printk("RSLCT ");
+	if (intreg & ESP_INTR_FDONE)
+		printk("FDONE ");
+	if (intreg & ESP_INTR_BSERV)
+		printk("BSERV ");
+	if (intreg & ESP_INTR_DC)
+		printk("DISCNCT ");
+	if (intreg & ESP_INTR_IC)
+		printk("ILL_CMD ");
+	if (intreg & ESP_INTR_SR)
+		printk("SCSI_BUS_RESET ");
+	printk(">");
+}
+
+/* Print the sequence step registers contents */
+static inline void esp_print_seqreg(u8 stepreg)
+{
+	stepreg &= ESP_STEP_VBITS;
+	printk("STEP<%s>",
+	       (stepreg == ESP_STEP_ASEL ? "SLCT_ARB_CMPLT" :
+		(stepreg == ESP_STEP_SID ? "1BYTE_MSG_SENT" :
+		 (stepreg == ESP_STEP_NCMD ? "NOT_IN_CMD_PHASE" :
+		  (stepreg == ESP_STEP_PPC ? "CMD_BYTES_LOST" :
+		   (stepreg == ESP_STEP_FINI4 ? "CMD_SENT_OK" :
+		    "UNKNOWN"))))));
+}
+
+static char *phase_string(int phase)
+{
+	switch (phase) {
+	case not_issued:
+		return "UNISSUED";
+	case in_slct_norm:
+		return "SLCTNORM";
+	case in_slct_stop:
+		return "SLCTSTOP";
+	case in_slct_msg:
+		return "SLCTMSG";
+	case in_slct_tag:
+		return "SLCTTAG";
+	case in_slct_sneg:
+		return "SLCTSNEG";
+	case in_datain:
+		return "DATAIN";
+	case in_dataout:
+		return "DATAOUT";
+	case in_data_done:
+		return "DATADONE";
+	case in_msgin:
+		return "MSGIN";
+	case in_msgincont:
+		return "MSGINCONT";
+	case in_msgindone:
+		return "MSGINDONE";
+	case in_msgout:
+		return "MSGOUT";
+	case in_msgoutdone:
+		return "MSGOUTDONE";
+	case in_cmdbegin:
+		return "CMDBEGIN";
+	case in_cmdend:
+		return "CMDEND";
+	case in_status:
+		return "STATUS";
+	case in_freeing:
+		return "FREEING";
+	case in_the_dark:
+		return "CLUELESS";
+	case in_abortone:
+		return "ABORTONE";
+	case in_abortall:
+		return "ABORTALL";
+	case in_resetdev:
+		return "RESETDEV";
+	case in_resetbus:
+		return "RESETBUS";
+	case in_tgterror:
+		return "TGTERROR";
+	default:
+		return "UNKNOWN";
+	};
+}
+
+#ifdef DEBUG_STATE_MACHINE
+static inline void esp_advance_phase(struct scsi_cmnd *s, int newphase)
+{
+	ESPLOG(("<%s>", phase_string(newphase)));
+	s->SCp.sent_command = s->SCp.phase;
+	s->SCp.phase = newphase;
+}
+#else
+#define esp_advance_phase(__s, __newphase) \
+	(__s)->SCp.sent_command = (__s)->SCp.phase; \
+	(__s)->SCp.phase = (__newphase);
+#endif
+
+#ifdef DEBUG_ESP_CMDS
+static inline void esp_cmd(struct esp *esp, u8 cmd)
+{
+	esp->espcmdlog[esp->espcmdent] = cmd;
+	esp->espcmdent = (esp->espcmdent + 1) & 31;
+	sbus_writeb(cmd, esp->eregs + ESP_CMD);
+}
+#else
+#define esp_cmd(__esp, __cmd)	\
+	sbus_writeb((__cmd), ((__esp)->eregs) + ESP_CMD)
+#endif
+
+#define ESP_INTSOFF(__dregs)	\
+	sbus_writel(sbus_readl((__dregs)+DMA_CSR)&~(DMA_INT_ENAB), (__dregs)+DMA_CSR)
+#define ESP_INTSON(__dregs)	\
+	sbus_writel(sbus_readl((__dregs)+DMA_CSR)|DMA_INT_ENAB, (__dregs)+DMA_CSR)
+#define ESP_IRQ_P(__dregs)	\
+	(sbus_readl((__dregs)+DMA_CSR) & (DMA_HNDL_INTR|DMA_HNDL_ERROR))
+
+/* How we use the various Linux SCSI data structures for operation.
+ *
+ * struct scsi_cmnd:
+ *
+ *   We keep track of the synchronous capabilities of a target
+ *   in the device member, using sync_min_period and
+ *   sync_max_offset.  These are the values we directly write
+ *   into the ESP registers while running a command.  If offset
+ *   is zero the ESP will use asynchronous transfers.
+ *   If the borken flag is set we assume we shouldn't even bother
+ *   trying to negotiate for synchronous transfer as this target
+ *   is really stupid.  If we notice the target is dropping the
+ *   bus, and we have been allowing it to disconnect, we clear
+ *   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
+ * the aha152x driver uses.
+ */
+static inline void append_SC(struct scsi_cmnd **SC, struct scsi_cmnd *new_SC)
+{
+	struct scsi_cmnd *end;
+
+	new_SC->host_scribble = (unsigned char *) NULL;
+	if (!*SC)
+		*SC = new_SC;
+	else {
+		for (end=*SC;end->host_scribble;end=(struct scsi_cmnd *)end->host_scribble)
+			;
+		end->host_scribble = (unsigned char *) new_SC;
+	}
+}
+
+static inline void prepend_SC(struct scsi_cmnd **SC, struct scsi_cmnd *new_SC)
+{
+	new_SC->host_scribble = (unsigned char *) *SC;
+	*SC = new_SC;
+}
+
+static inline struct scsi_cmnd *remove_first_SC(struct scsi_cmnd **SC)
+{
+	struct scsi_cmnd *ptr;
+	ptr = *SC;
+	if (ptr)
+		*SC = (struct scsi_cmnd *) (*SC)->host_scribble;
+	return ptr;
+}
+
+static inline struct scsi_cmnd *remove_SC(struct scsi_cmnd **SC, int target, int lun)
+{
+	struct scsi_cmnd *ptr, *prev;
+
+	for (ptr = *SC, prev = NULL;
+	     ptr && ((ptr->device->id != target) || (ptr->device->lun != lun));
+	     prev = ptr, ptr = (struct scsi_cmnd *) ptr->host_scribble)
+		;
+	if (ptr) {
+		if (prev)
+			prev->host_scribble=ptr->host_scribble;
+		else
+			*SC=(struct scsi_cmnd *)ptr->host_scribble;
+	}
+	return ptr;
+}
+
+/* Resetting various pieces of the ESP scsi driver chipset/buses. */
+static void esp_reset_dma(struct esp *esp)
+{
+	int can_do_burst16, can_do_burst32, can_do_burst64;
+	int can_do_sbus64;
+	u32 tmp;
+
+	can_do_burst16 = (esp->bursts & DMA_BURST16) != 0;
+	can_do_burst32 = (esp->bursts & DMA_BURST32) != 0;
+	can_do_burst64 = 0;
+	can_do_sbus64 = 0;
+	if (sbus_can_dma_64bit(esp->sdev))
+		can_do_sbus64 = 1;
+	if (sbus_can_burst64(esp->sdev))
+		can_do_burst64 = (esp->bursts & DMA_BURST64) != 0;
+
+	/* Punt the DVMA into a known state. */
+	if (esp->dma->revision != dvmahme) {
+		tmp = sbus_readl(esp->dregs + DMA_CSR);
+		sbus_writel(tmp | DMA_RST_SCSI, esp->dregs + DMA_CSR);
+		sbus_writel(tmp & ~DMA_RST_SCSI, esp->dregs + DMA_CSR);
+	}
+	switch (esp->dma->revision) {
+	case dvmahme:
+		/* This is the HME DVMA gate array. */
+
+		sbus_writel(DMA_RESET_FAS366, esp->dregs + DMA_CSR);
+		sbus_writel(DMA_RST_SCSI, esp->dregs + DMA_CSR);
+
+		esp->prev_hme_dmacsr = (DMA_PARITY_OFF|DMA_2CLKS|DMA_SCSI_DISAB|DMA_INT_ENAB);
+		esp->prev_hme_dmacsr &= ~(DMA_ENABLE|DMA_ST_WRITE|DMA_BRST_SZ);
+
+		if (can_do_burst64)
+			esp->prev_hme_dmacsr |= DMA_BRST64;
+		else if (can_do_burst32)
+			esp->prev_hme_dmacsr |= DMA_BRST32;
+
+		if (can_do_sbus64) {
+			esp->prev_hme_dmacsr |= DMA_SCSI_SBUS64;
+			sbus_set_sbus64(esp->sdev, esp->bursts);
+		}
+
+		/* This chip is horrible. */
+		while (sbus_readl(esp->dregs + DMA_CSR) & DMA_PEND_READ)
+			udelay(1);
+
+		sbus_writel(0, esp->dregs + DMA_CSR);
+		sbus_writel(esp->prev_hme_dmacsr, esp->dregs + DMA_CSR);
+
+		/* This is necessary to avoid having the SCSI channel
+		 * engine lock up on us.
+		 */
+		sbus_writel(0, esp->dregs + DMA_ADDR);
+
+		break;
+	case dvmarev2:
+		/* This is the gate array found in the sun4m
+		 * NCR SBUS I/O subsystem.
+		 */
+		if (esp->erev != esp100) {
+			tmp = sbus_readl(esp->dregs + DMA_CSR);
+			sbus_writel(tmp | DMA_3CLKS, esp->dregs + DMA_CSR);
+		}
+		break;
+	case dvmarev3:
+		tmp = sbus_readl(esp->dregs + DMA_CSR);
+		tmp &= ~DMA_3CLKS;
+		tmp |= DMA_2CLKS;
+		if (can_do_burst32) {
+			tmp &= ~DMA_BRST_SZ;
+			tmp |= DMA_BRST32;
+		}
+		sbus_writel(tmp, esp->dregs + DMA_CSR);
+		break;
+	case dvmaesc1:
+		/* This is the DMA unit found on SCSI/Ether cards. */
+		tmp = sbus_readl(esp->dregs + DMA_CSR);
+		tmp |= DMA_ADD_ENABLE;
+		tmp &= ~DMA_BCNT_ENAB;
+		if (!can_do_burst32 && can_do_burst16) {
+			tmp |= DMA_ESC_BURST;
+		} else {
+			tmp &= ~(DMA_ESC_BURST);
+		}
+		sbus_writel(tmp, esp->dregs + DMA_CSR);
+		break;
+	default:
+		break;
+	};
+	ESP_INTSON(esp->dregs);
+}
+
+/* Reset the ESP chip, _not_ the SCSI bus. */
+static void __init esp_reset_esp(struct esp *esp)
+{
+	u8 family_code, version;
+	int i;
+
+	/* Now reset the ESP chip */
+	esp_cmd(esp, ESP_CMD_RC);
+	esp_cmd(esp, ESP_CMD_NULL | ESP_CMD_DMA);
+	esp_cmd(esp, ESP_CMD_NULL | ESP_CMD_DMA);
+
+	/* Reload the configuration registers */
+	sbus_writeb(esp->cfact, esp->eregs + ESP_CFACT);
+	esp->prev_stp = 0;
+	sbus_writeb(esp->prev_stp, esp->eregs + ESP_STP);
+	esp->prev_soff = 0;
+	sbus_writeb(esp->prev_soff, esp->eregs + ESP_SOFF);
+	sbus_writeb(esp->neg_defp, esp->eregs + ESP_TIMEO);
+
+	/* This is the only point at which it is reliable to read
+	 * the ID-code for a fast ESP chip variants.
+	 */
+	esp->max_period = ((35 * esp->ccycle) / 1000);
+	if (esp->erev == fast) {
+		version = sbus_readb(esp->eregs + ESP_UID);
+		family_code = (version & 0xf8) >> 3;
+		if (family_code == 0x02)
+			esp->erev = fas236;
+		else if (family_code == 0x0a)
+			esp->erev = fashme; /* Version is usually '5'. */
+		else
+			esp->erev = fas100a;
+		ESPMISC(("esp%d: FAST chip is %s (family=%d, version=%d)\n",
+			 esp->esp_id,
+			 (esp->erev == fas236) ? "fas236" :
+			 ((esp->erev == fas100a) ? "fas100a" :
+			  "fasHME"), family_code, (version & 7)));
+
+		esp->min_period = ((4 * esp->ccycle) / 1000);
+	} else {
+		esp->min_period = ((5 * esp->ccycle) / 1000);
+	}
+	esp->max_period = (esp->max_period + 3)>>2;
+	esp->min_period = (esp->min_period + 3)>>2;
+
+	sbus_writeb(esp->config1, esp->eregs + ESP_CFG1);
+	switch (esp->erev) {
+	case esp100:
+		/* nothing to do */
+		break;
+	case esp100a:
+		sbus_writeb(esp->config2, esp->eregs + ESP_CFG2);
+		break;
+	case esp236:
+		/* Slow 236 */
+		sbus_writeb(esp->config2, esp->eregs + ESP_CFG2);
+		esp->prev_cfg3 = esp->config3[0];
+		sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
+		break;
+	case fashme:
+		esp->config2 |= (ESP_CONFIG2_HME32 | ESP_CONFIG2_HMEFENAB);
+		/* fallthrough... */
+	case fas236:
+		/* Fast 236 or HME */
+		sbus_writeb(esp->config2, esp->eregs + ESP_CFG2);
+		for (i = 0; i < 16; i++) {
+			if (esp->erev == fashme) {
+				u8 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;
+			}
+		}
+		esp->prev_cfg3 = esp->config3[0];
+		sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
+		if (esp->erev == fashme) {
+			esp->radelay = 80;
+		} else {
+			if (esp->diff)
+				esp->radelay = 0;
+			else
+				esp->radelay = 96;
+		}
+		break;
+	case fas100a:
+		/* Fast 100a */
+		sbus_writeb(esp->config2, esp->eregs + ESP_CFG2);
+		for (i = 0; i < 16; i++)
+			esp->config3[i] |= ESP_CONFIG3_FCLOCK;
+		esp->prev_cfg3 = esp->config3[0];
+		sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
+		esp->radelay = 32;
+		break;
+	default:
+		panic("esp: what could it be... I wonder...");
+		break;
+	};
+
+	/* Eat any bitrot in the chip */
+	sbus_readb(esp->eregs + ESP_INTRPT);
+	udelay(100);
+}
+
+/* This places the ESP into a known state at boot time. */
+static void __init esp_bootup_reset(struct esp *esp)
+{
+	u8 tmp;
+
+	/* Reset the DMA */
+	esp_reset_dma(esp);
+
+	/* Reset the ESP */
+	esp_reset_esp(esp);
+
+	/* Reset the SCSI bus, but tell ESP not to generate an irq */
+	tmp = sbus_readb(esp->eregs + ESP_CFG1);
+	tmp |= ESP_CONFIG1_SRRDISAB;
+	sbus_writeb(tmp, esp->eregs + ESP_CFG1);
+
+	esp_cmd(esp, ESP_CMD_RS);
+	udelay(400);
+
+	sbus_writeb(esp->config1, esp->eregs + ESP_CFG1);
+
+	/* Eat any bitrot in the chip and we are done... */
+	sbus_readb(esp->eregs + ESP_INTRPT);
+}
+
+static void esp_chain_add(struct esp *esp)
+{
+	spin_lock_irq(&espchain_lock);
+	if (espchain) {
+		struct esp *elink = espchain;
+		while (elink->next)
+			elink = elink->next;
+		elink->next = esp;
+	} else {
+		espchain = esp;
+	}
+	esp->next = NULL;
+	spin_unlock_irq(&espchain_lock);
+}
+
+static void esp_chain_del(struct esp *esp)
+{
+	spin_lock_irq(&espchain_lock);
+	if (espchain == esp) {
+		espchain = esp->next;
+	} else {
+		struct esp *elink = espchain;
+		while (elink->next != esp)
+			elink = elink->next;
+		elink->next = esp->next;
+	}
+	esp->next = NULL;
+	spin_unlock_irq(&espchain_lock);
+}
+
+static int __init esp_find_dvma(struct esp *esp, struct sbus_dev *dma_sdev)
+{
+	struct sbus_dev *sdev = esp->sdev;
+	struct sbus_dma *dma;
+
+	if (dma_sdev != NULL) {
+		for_each_dvma(dma) {
+			if (dma->sdev == dma_sdev)
+				break;
+		}
+	} else {
+		for_each_dvma(dma) {
+			/* If allocated already, can't use it. */
+			if (dma->allocated)
+				continue;
+
+			if (dma->sdev == NULL)
+				break;
+
+			/* If bus + slot are the same and it has the
+			 * correct OBP name, it's ours.
+			 */
+			if (sdev->bus == dma->sdev->bus &&
+			    sdev->slot == dma->sdev->slot &&
+			    (!strcmp(dma->sdev->prom_name, "dma") ||
+			     !strcmp(dma->sdev->prom_name, "espdma")))
+				break;
+		}
+	}
+
+	/* If we don't know how to handle the dvma,
+	 * do not use this device.
+	 */
+	if (dma == NULL) {
+		printk("Cannot find dvma for ESP%d's SCSI\n", esp->esp_id);
+		return -1;
+	}
+	if (dma->allocated) {
+		printk("esp%d: can't use my espdma\n", esp->esp_id);
+		return -1;
+	}
+	dma->allocated = 1;
+	esp->dma = dma;
+	esp->dregs = dma->regs;
+
+	return 0;
+}
+
+static int __init esp_map_regs(struct esp *esp, int hme)
+{
+	struct sbus_dev *sdev = esp->sdev;
+	struct resource *res;
+
+	/* On HME, two reg sets exist, first is DVMA,
+	 * second is ESP registers.
+	 */
+	if (hme)
+		res = &sdev->resource[1];
+	else
+		res = &sdev->resource[0];
+
+	esp->eregs = sbus_ioremap(res, 0, ESP_REG_SIZE, "ESP Registers");
+
+	if (esp->eregs == 0)
+		return -1;
+	return 0;
+}
+
+static int __init esp_map_cmdarea(struct esp *esp)
+{
+	struct sbus_dev *sdev = esp->sdev;
+
+	esp->esp_command = sbus_alloc_consistent(sdev, 16,
+						 &esp->esp_command_dvma);
+	if (esp->esp_command == NULL ||
+	    esp->esp_command_dvma == 0)
+		return -1;
+	return 0;
+}
+
+static int __init esp_register_irq(struct esp *esp)
+{
+	esp->ehost->irq = esp->irq = esp->sdev->irqs[0];
+
+	/* We used to try various overly-clever things to
+	 * reduce the interrupt processing overhead on
+	 * sun4c/sun4m when multiple ESP's shared the
+	 * same IRQ.  It was too complex and messy to
+	 * sanely maintain.
+	 */
+	if (request_irq(esp->ehost->irq, esp_intr,
+			SA_SHIRQ, "ESP SCSI", esp)) {
+		printk("esp%d: Cannot acquire irq line\n",
+		       esp->esp_id);
+		return -1;
+	}
+
+	printk("esp%d: IRQ %s ", esp->esp_id,
+	       __irq_itoa(esp->ehost->irq));
+
+	return 0;
+}
+
+static void __init esp_get_scsi_id(struct esp *esp)
+{
+	struct sbus_dev *sdev = esp->sdev;
+
+	esp->scsi_id = prom_getintdefault(esp->prom_node,
+					  "initiator-id",
+					  -1);
+	if (esp->scsi_id == -1)
+		esp->scsi_id = prom_getintdefault(esp->prom_node,
+						  "scsi-initiator-id",
+						  -1);
+	if (esp->scsi_id == -1)
+		esp->scsi_id = (sdev->bus == NULL) ? 7 :
+			prom_getintdefault(sdev->bus->prom_node,
+					   "scsi-initiator-id",
+					   7);
+	esp->ehost->this_id = esp->scsi_id;
+	esp->scsi_id_mask = (1 << esp->scsi_id);
+
+}
+
+static void __init esp_get_clock_params(struct esp *esp)
+{
+	struct sbus_dev *sdev = esp->sdev;
+	int prom_node = esp->prom_node;
+	int sbus_prom_node;
+	unsigned int fmhz;
+	u8 ccf;
+
+	if (sdev != NULL && sdev->bus != NULL)
+		sbus_prom_node = sdev->bus->prom_node;
+	else
+		sbus_prom_node = 0;
+
+	/* This is getting messy but it has to be done
+	 * correctly or else you get weird behavior all
+	 * over the place.  We are trying to basically
+	 * figure out three pieces of information.
+	 *
+	 * a) Clock Conversion Factor
+	 *
+	 *    This is a representation of the input
+	 *    crystal clock frequency going into the
+	 *    ESP on this machine.  Any operation whose
+	 *    timing is longer than 400ns depends on this
+	 *    value being correct.  For example, you'll
+	 *    get blips for arbitration/selection during
+	 *    high load or with multiple targets if this
+	 *    is not set correctly.
+	 *
+	 * b) Selection Time-Out
+	 *
+	 *    The ESP isn't very bright and will arbitrate
+	 *    for the bus and try to select a target
+	 *    forever if you let it.  This value tells
+	 *    the ESP when it has taken too long to
+	 *    negotiate and that it should interrupt
+	 *    the CPU so we can see what happened.
+	 *    The value is computed as follows (from
+	 *    NCR/Symbios chip docs).
+	 *
+	 *          (Time Out Period) *  (Input Clock)
+	 *    STO = ----------------------------------
+	 *          (8192) * (Clock Conversion Factor)
+	 *
+	 *    You usually want the time out period to be
+	 *    around 250ms, I think we'll set it a little
+	 *    bit higher to account for fully loaded SCSI
+	 *    bus's and slow devices that don't respond so
+	 *    quickly to selection attempts. (yeah, I know
+	 *    this is out of spec. but there is a lot of
+	 *    buggy pieces of firmware out there so bite me)
+	 *
+	 * c) Imperical constants for synchronous offset
+	 *    and transfer period register values
+	 *
+	 *    This entails the smallest and largest sync
+	 *    period we could ever handle on this ESP.
+	 */
+
+	fmhz = prom_getintdefault(prom_node, "clock-frequency", -1);
+	if (fmhz == -1)
+		fmhz = (!sbus_prom_node) ? 0 :
+			prom_getintdefault(sbus_prom_node, "clock-frequency", -1);
+
+	if (fmhz <= (5000000))
+		ccf = 0;
+	else
+		ccf = (((5000000 - 1) + (fmhz))/(5000000));
+
+	if (!ccf || ccf > 8) {
+		/* If we can't find anything reasonable,
+		 * just assume 20MHZ.  This is the clock
+		 * frequency of the older sun4c's where I've
+		 * been unable to find the clock-frequency
+		 * PROM property.  All other machines provide
+		 * useful values it seems.
+		 */
+		ccf = ESP_CCF_F4;
+		fmhz = (20000000);
+	}
+
+	if (ccf == (ESP_CCF_F7 + 1))
+		esp->cfact = ESP_CCF_F0;
+	else if (ccf == ESP_CCF_NEVER)
+		esp->cfact = ESP_CCF_F2;
+	else
+		esp->cfact = ccf;
+	esp->raw_cfact = ccf;
+
+	esp->cfreq = fmhz;
+	esp->ccycle = ESP_MHZ_TO_CYCLE(fmhz);
+	esp->ctick = ESP_TICK(ccf, esp->ccycle);
+	esp->neg_defp = ESP_NEG_DEFP(fmhz, ccf);
+	esp->sync_defp = SYNC_DEFP_SLOW;
+
+	printk("SCSI ID %d Clk %dMHz CCYC=%d CCF=%d TOut %d ",
+	       esp->scsi_id, (fmhz / 1000000),
+	       (int)esp->ccycle, (int)ccf, (int) esp->neg_defp);
+}
+
+static void __init esp_get_bursts(struct esp *esp, struct sbus_dev *dma)
+{
+	struct sbus_dev *sdev = esp->sdev;
+	u8 bursts;
+
+	bursts = prom_getintdefault(esp->prom_node, "burst-sizes", 0xff);
+
+	if (dma) {
+		u8 tmp = prom_getintdefault(dma->prom_node,
+					    "burst-sizes", 0xff);
+		if (tmp != 0xff)
+			bursts &= tmp;
+	}
+
+	if (sdev->bus) {
+		u8 tmp = prom_getintdefault(sdev->bus->prom_node,
+					    "burst-sizes", 0xff);
+		if (tmp != 0xff)
+			bursts &= tmp;
+	}
+
+	if (bursts == 0xff ||
+	    (bursts & DMA_BURST16) == 0 ||
+	    (bursts & DMA_BURST32) == 0)
+		bursts = (DMA_BURST32 - 1);
+
+	esp->bursts = bursts;
+}
+
+static void __init esp_get_revision(struct esp *esp)
+{
+	u8 tmp;
+
+	esp->config1 = (ESP_CONFIG1_PENABLE | (esp->scsi_id & 7));
+	esp->config2 = (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY);
+	sbus_writeb(esp->config2, esp->eregs + ESP_CFG2);
+
+	tmp = sbus_readb(esp->eregs + ESP_CFG2);
+	tmp &= ~ESP_CONFIG2_MAGIC;
+	if (tmp != (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY)) {
+		/* If what we write to cfg2 does not come back, cfg2
+		 * is not implemented, therefore this must be a plain
+		 * esp100.
+		 */
+		esp->erev = esp100;
+		printk("NCR53C90(esp100)\n");
+	} else {
+		esp->config2 = 0;
+		esp->prev_cfg3 = esp->config3[0] = 5;
+		sbus_writeb(esp->config2, esp->eregs + ESP_CFG2);
+		sbus_writeb(0, esp->eregs + ESP_CFG3);
+		sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
+
+		tmp = sbus_readb(esp->eregs + ESP_CFG3);
+		if (tmp != 5) {
+			/* The cfg2 register is implemented, however
+			 * cfg3 is not, must be esp100a.
+			 */
+			esp->erev = esp100a;
+			printk("NCR53C90A(esp100a)\n");
+		} else {
+			int target;
+
+			for (target = 0; target < 16; target++)
+				esp->config3[target] = 0;
+			esp->prev_cfg3 = 0;
+			sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
+
+			/* All of cfg{1,2,3} implemented, must be one of
+			 * the fas variants, figure out which one.
+			 */
+			if (esp->raw_cfact > ESP_CCF_F5) {
+				esp->erev = fast;
+				esp->sync_defp = SYNC_DEFP_FAST;
+				printk("NCR53C9XF(espfast)\n");
+			} else {
+				esp->erev = esp236;
+				printk("NCR53C9x(esp236)\n");
+			}
+			esp->config2 = 0;
+			sbus_writeb(esp->config2, esp->eregs + ESP_CFG2);
+		}
+	}
+}
+
+static void __init esp_init_swstate(struct esp *esp)
+{
+	int i;
+
+	/* Command queues... */
+	esp->current_SC = NULL;
+	esp->disconnected_SC = NULL;
+	esp->issue_SC = NULL;
+
+	/* Target and current command state... */
+	esp->targets_present = 0;
+	esp->resetting_bus = 0;
+	esp->snip = 0;
+
+	init_waitqueue_head(&esp->reset_queue);
+
+	/* Debugging... */
+	for(i = 0; i < 32; i++)
+		esp->espcmdlog[i] = 0;
+	esp->espcmdent = 0;
+
+	/* MSG phase state... */
+	for(i = 0; i < 16; i++) {
+		esp->cur_msgout[i] = 0;
+		esp->cur_msgin[i] = 0;
+	}
+	esp->prevmsgout = esp->prevmsgin = 0;
+	esp->msgout_len = esp->msgin_len = 0;
+
+	/* Clear the one behind caches to hold unmatchable values. */
+	esp->prev_soff = esp->prev_stp = esp->prev_cfg3 = 0xff;
+	esp->prev_hme_dmacsr = 0xffffffff;
+}
+
+static int __init detect_one_esp(struct scsi_host_template *tpnt, struct sbus_dev *esp_dev,
+				 struct sbus_dev *espdma, struct sbus_bus *sbus,
+				 int id, int hme)
+{
+	struct Scsi_Host *esp_host = scsi_register(tpnt, sizeof(struct esp));
+	struct esp *esp;
+	
+	if (!esp_host) {
+		printk("ESP: Cannot register SCSI host\n");
+		return -1;
+	}
+	if (hme)
+		esp_host->max_id = 16;
+	esp = (struct esp *) esp_host->hostdata;
+	esp->ehost = esp_host;
+	esp->sdev = esp_dev;
+	esp->esp_id = id;
+	esp->prom_node = esp_dev->prom_node;
+	prom_getstring(esp->prom_node, "name", esp->prom_name,
+		       sizeof(esp->prom_name));
+
+	esp_chain_add(esp);
+	if (esp_find_dvma(esp, espdma) < 0)
+		goto fail_unlink;
+	if (esp_map_regs(esp, hme) < 0) {
+		printk("ESP registers unmappable");
+		goto fail_dvma_release;
+	}
+	if (esp_map_cmdarea(esp) < 0) {
+		printk("ESP DVMA transport area unmappable");
+		goto fail_unmap_regs;
+	}
+	if (esp_register_irq(esp) < 0)
+		goto fail_unmap_cmdarea;
+
+	esp_get_scsi_id(esp);
+
+	esp->diff = prom_getbool(esp->prom_node, "differential");
+	if (esp->diff)
+		printk("Differential ");
+
+	esp_get_clock_params(esp);
+	esp_get_bursts(esp, espdma);
+	esp_get_revision(esp);
+	esp_init_swstate(esp);
+
+	esp_bootup_reset(esp);
+
+	return 0;
+
+fail_unmap_cmdarea:
+	sbus_free_consistent(esp->sdev, 16,
+			     (void *) esp->esp_command,
+			     esp->esp_command_dvma);
+
+fail_unmap_regs:
+	sbus_iounmap(esp->eregs, ESP_REG_SIZE);
+
+fail_dvma_release:
+	esp->dma->allocated = 0;
+
+fail_unlink:
+	esp_chain_del(esp);
+	scsi_unregister(esp_host);
+	return -1;
+}
+
+/* Detecting ESP chips on the machine.  This is the simple and easy
+ * version.
+ */
+
+#ifdef CONFIG_SUN4
+
+#include <asm/sun4paddr.h>
+
+static int __init esp_detect(struct scsi_host_template *tpnt)
+{
+	static struct sbus_dev esp_dev;
+	int esps_in_use = 0;
+
+	espchain = 0;
+
+	if (sun4_esp_physaddr) {
+		memset (&esp_dev, 0, sizeof(esp_dev));
+		esp_dev.reg_addrs[0].phys_addr = sun4_esp_physaddr;
+		esp_dev.irqs[0] = 4;
+		esp_dev.resource[0].start = sun4_esp_physaddr;
+		esp_dev.resource[0].end = sun4_esp_physaddr + ESP_REG_SIZE - 1;
+		esp_dev.resource[0].flags = IORESOURCE_IO;
+
+		if (!detect_one_esp(tpnt, &esp_dev, NULL, NULL, 0, 0))
+			esps_in_use++;
+		printk("ESP: Total of 1 ESP hosts found, %d actually in use.\n", esps_in_use);
+		esps_running =  esps_in_use;
+	}
+	return esps_in_use;
+}
+
+#else /* !CONFIG_SUN4 */
+
+static int __init esp_detect(struct scsi_host_template *tpnt)
+{
+	struct sbus_bus *sbus;
+	struct sbus_dev *esp_dev, *sbdev_iter;
+	int nesps = 0, esps_in_use = 0;
+
+	espchain = 0;
+	if (!sbus_root) {
+#ifdef CONFIG_PCI
+		return 0;
+#else
+		panic("No SBUS in esp_detect()");
+#endif
+	}
+	for_each_sbus(sbus) {
+		for_each_sbusdev(sbdev_iter, sbus) {
+			struct sbus_dev *espdma = NULL;
+			int hme = 0;
+
+			/* Is it an esp sbus device? */
+			esp_dev = sbdev_iter;
+			if (strcmp(esp_dev->prom_name, "esp") &&
+			    strcmp(esp_dev->prom_name, "SUNW,esp")) {
+				if (!strcmp(esp_dev->prom_name, "SUNW,fas")) {
+					hme = 1;
+					espdma = esp_dev;
+				} else {
+					if (!esp_dev->child ||
+					    (strcmp(esp_dev->prom_name, "espdma") &&
+					     strcmp(esp_dev->prom_name, "dma")))
+						continue; /* nope... */
+					espdma = esp_dev;
+					esp_dev = esp_dev->child;
+					if (strcmp(esp_dev->prom_name, "esp") &&
+					    strcmp(esp_dev->prom_name, "SUNW,esp"))
+						continue; /* how can this happen? */
+				}
+			}
+			
+			if (detect_one_esp(tpnt, esp_dev, espdma, sbus, nesps++, hme) < 0)
+				continue;
+				
+			esps_in_use++;
+		} /* for each sbusdev */
+	} /* for each sbus */
+	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;
+}
+
+#endif /* !CONFIG_SUN4 */
+
+/*
+ */
+static int esp_release(struct Scsi_Host *host)
+{
+	struct esp *esp = (struct esp *) host->hostdata;
+
+	ESP_INTSOFF(esp->dregs);
+#if 0
+	esp_reset_dma(esp);
+	esp_reset_esp(esp);
+#endif
+
+	free_irq(esp->ehost->irq, esp);
+	sbus_free_consistent(esp->sdev, 16,
+			     (void *) esp->esp_command, esp->esp_command_dvma);
+	sbus_iounmap(esp->eregs, ESP_REG_SIZE);
+	esp->dma->allocated = 0;
+	esp_chain_del(esp);
+
+        return 0;
+}
+
+/* The info function will return whatever useful
+ * information the developer sees fit.  If not provided, then
+ * the name field will be used instead.
+ */
+static const char *esp_info(struct Scsi_Host *host)
+{
+	struct esp *esp;
+
+	esp = (struct esp *) host->hostdata;
+	switch (esp->erev) {
+	case esp100:
+		return "Sparc ESP100 (NCR53C90)";
+	case esp100a:
+		return "Sparc ESP100A (NCR53C90A)";
+	case esp236:
+		return "Sparc ESP236";
+	case fas236:
+		return "Sparc ESP236-FAST";
+	case fashme:
+		return "Sparc ESP366-HME";
+	case fas100a:
+		return "Sparc ESP100A-FAST";
+	default:
+		return "Bogon ESP revision";
+	};
+}
+
+/* From Wolfgang Stanglmeier's NCR scsi driver. */
+struct info_str
+{
+	char *buffer;
+	int length;
+	int offset;
+	int pos;
+};
+
+static void copy_mem_info(struct info_str *info, char *data, int len)
+{
+	if (info->pos + len > info->length)
+		len = info->length - info->pos;
+
+	if (info->pos + len < info->offset) {
+		info->pos += len;
+		return;
+	}
+	if (info->pos < info->offset) {
+		data += (info->offset - info->pos);
+		len  -= (info->offset - info->pos);
+	}
+
+	if (len > 0) {
+		memcpy(info->buffer + info->pos, data, len);
+		info->pos += len;
+	}
+}
+
+static int copy_info(struct info_str *info, char *fmt, ...)
+{
+	va_list args;
+	char buf[81];
+	int len;
+
+	va_start(args, fmt);
+	len = vsprintf(buf, fmt, args);
+	va_end(args);
+
+	copy_mem_info(info, buf, len);
+	return len;
+}
+
+static int esp_host_info(struct esp *esp, char *ptr, off_t offset, int len)
+{
+	struct scsi_device *sdev;
+	struct info_str info;
+	int i;
+
+	info.buffer	= ptr;
+	info.length	= len;
+	info.offset	= offset;
+	info.pos	= 0;
+
+	copy_info(&info, "Sparc ESP Host Adapter:\n");
+	copy_info(&info, "\tPROM node\t\t%08x\n", (unsigned int) esp->prom_node);
+	copy_info(&info, "\tPROM name\t\t%s\n", esp->prom_name);
+	copy_info(&info, "\tESP Model\t\t");
+	switch (esp->erev) {
+	case esp100:
+		copy_info(&info, "ESP100\n");
+		break;
+	case esp100a:
+		copy_info(&info, "ESP100A\n");
+		break;
+	case esp236:
+		copy_info(&info, "ESP236\n");
+		break;
+	case fas236:
+		copy_info(&info, "FAS236\n");
+		break;
+	case fas100a:
+		copy_info(&info, "FAS100A\n");
+		break;
+	case fast:
+		copy_info(&info, "FAST\n");
+		break;
+	case fashme:
+		copy_info(&info, "Happy Meal FAS\n");
+		break;
+	case espunknown:
+	default:
+		copy_info(&info, "Unknown!\n");
+		break;
+	};
+	copy_info(&info, "\tDMA Revision\t\t");
+	switch (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;
+	};
+	copy_info(&info, "\tLive Targets\t\t[ ");
+	for (i = 0; i < 15; i++) {
+		if (esp->targets_present & (1 << i))
+			copy_info(&info, "%d ", i);
+	}
+	copy_info(&info, "]\n\n");
+	
+	/* Now describe the state of each existing target. */
+	copy_info(&info, "Target #\tconfig3\t\tSync Capabilities\tDisconnect\tWide\n");
+
+	shost_for_each_device(sdev, esp->ehost) {
+		struct esp_device *esp_dev = sdev->hostdata;
+		uint id = sdev->id;
+
+		if (!(esp->targets_present & (1 << id)))
+			continue;
+
+		copy_info(&info, "%d\t\t", id);
+		copy_info(&info, "%08lx\t", esp->config3[id]);
+		copy_info(&info, "[%02lx,%02lx]\t\t\t",
+			esp_dev->sync_max_offset,
+			esp_dev->sync_min_period);
+		copy_info(&info, "%s\t\t",
+			esp_dev->disconnect ? "yes" : "no");
+		copy_info(&info, "%s\n",
+			(esp->config3[id] & ESP_CONFIG3_EWIDE) ? "yes" : "no");
+	}
+	return info.pos > info.offset? info.pos - info.offset : 0;
+}
+
+/* ESP proc filesystem code. */
+static int esp_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+			 int length, int inout)
+{
+	struct esp *esp;
+
+	if (inout)
+		return -EINVAL; /* not yet */
+
+	for_each_esp(esp) {
+		if (esp->ehost == host)
+			break;
+	}
+	if (!esp)
+		return -EINVAL;
+
+	if (start)
+		*start = buffer;
+
+	return esp_host_info(esp, buffer, offset, length);
+}
+
+static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
+{
+	if (sp->use_sg == 0) {
+		sp->SCp.this_residual = sp->request_bufflen;
+		sp->SCp.buffer = (struct scatterlist *) sp->request_buffer;
+		sp->SCp.buffers_residual = 0;
+		if (sp->request_bufflen) {
+			sp->SCp.have_data_in = sbus_map_single(esp->sdev, sp->SCp.buffer,
+							       sp->SCp.this_residual,
+							       sp->sc_data_direction);
+			sp->SCp.ptr = (char *) ((unsigned long)sp->SCp.have_data_in);
+		} else {
+			sp->SCp.ptr = NULL;
+		}
+	} else {
+		sp->SCp.buffer = (struct scatterlist *) sp->buffer;
+		sp->SCp.buffers_residual = sbus_map_sg(esp->sdev,
+						       sp->SCp.buffer,
+						       sp->use_sg,
+						       sp->sc_data_direction);
+		sp->SCp.this_residual = sg_dma_len(sp->SCp.buffer);
+		sp->SCp.ptr = (char *) ((unsigned long)sg_dma_address(sp->SCp.buffer));
+	}
+}
+
+static void esp_release_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
+{
+	if (sp->use_sg) {
+		sbus_unmap_sg(esp->sdev, sp->buffer, sp->use_sg,
+			      sp->sc_data_direction);
+	} else if (sp->request_bufflen) {
+		sbus_unmap_single(esp->sdev,
+				  sp->SCp.have_data_in,
+				  sp->request_bufflen,
+				  sp->sc_data_direction);
+	}
+}
+
+static void esp_restore_pointers(struct esp *esp, struct scsi_cmnd *sp)
+{
+	struct esp_pointers *ep = &esp->data_pointers[sp->device->id];
+
+	sp->SCp.ptr = ep->saved_ptr;
+	sp->SCp.buffer = ep->saved_buffer;
+	sp->SCp.this_residual = ep->saved_this_residual;
+	sp->SCp.buffers_residual = ep->saved_buffers_residual;
+}
+
+static void esp_save_pointers(struct esp *esp, struct scsi_cmnd *sp)
+{
+	struct esp_pointers *ep = &esp->data_pointers[sp->device->id];
+
+	ep->saved_ptr = sp->SCp.ptr;
+	ep->saved_buffer = sp->SCp.buffer;
+	ep->saved_this_residual = sp->SCp.this_residual;
+	ep->saved_buffers_residual = sp->SCp.buffers_residual;
+}
+
+/* Some rules:
+ *
+ *   1) Never ever panic while something is live on the bus.
+ *      If there is to be any chance of syncing the disks this
+ *      rule is to be obeyed.
+ *
+ *   2) Any target that causes a foul condition will no longer
+ *      have synchronous transfers done to it, no questions
+ *      asked.
+ *
+ *   3) Keep register accesses to a minimum.  Think about some
+ *      day when we have Xbus machines this is running on and
+ *      the ESP chip is on the other end of the machine on a
+ *      different board from the cpu where this is running.
+ */
+
+/* Fire off a command.  We assume the bus is free and that the only
+ * case where we could see an interrupt is where we have disconnected
+ * commands active and they are trying to reselect us.
+ */
+static inline void esp_check_cmd(struct esp *esp, struct scsi_cmnd *sp)
+{
+	switch (sp->cmd_len) {
+	case 6:
+	case 10:
+	case 12:
+		esp->esp_slowcmd = 0;
+		break;
+
+	default:
+		esp->esp_slowcmd = 1;
+		esp->esp_scmdleft = sp->cmd_len;
+		esp->esp_scmdp = &sp->cmnd[0];
+		break;
+	};
+}
+
+static inline void build_sync_nego_msg(struct esp *esp, int period, int offset)
+{
+	esp->cur_msgout[0] = EXTENDED_MESSAGE;
+	esp->cur_msgout[1] = 3;
+	esp->cur_msgout[2] = EXTENDED_SDTR;
+	esp->cur_msgout[3] = period;
+	esp->cur_msgout[4] = offset;
+	esp->msgout_len = 5;
+}
+
+/* SIZE is in bits, currently HME only supports 16 bit wide transfers. */
+static inline void build_wide_nego_msg(struct 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 esp *esp)
+{
+	struct scsi_cmnd *SCptr;
+	struct scsi_device *SDptr;
+	struct esp_device *esp_dev;
+	volatile u8 *cmdp = esp->esp_command;
+	u8 the_esp_command;
+	int lun, target;
+	int i;
+
+	/* Hold off if we have disconnected commands and
+	 * an IRQ is showing...
+	 */
+	if (esp->disconnected_SC && ESP_IRQ_P(esp->dregs))
+		return;
+
+	/* Grab first member of the issue queue. */
+	SCptr = esp->current_SC = remove_first_SC(&esp->issue_SC);
+
+	/* Safe to panic here because current_SC is null. */
+	if (!SCptr)
+		panic("esp: esp_exec_cmd and issue queue is NULL");
+
+	SDptr = SCptr->device;
+	esp_dev = SDptr->hostdata;
+	lun = SCptr->device->lun;
+	target = SCptr->device->id;
+
+	esp->snip = 0;
+	esp->msgout_len = 0;
+
+	/* Send it out whole, or piece by piece?   The ESP
+	 * only knows how to automatically send out 6, 10,
+	 * and 12 byte commands.  I used to think that the
+	 * Linux SCSI code would never throw anything other
+	 * than that to us, but then again there is the
+	 * SCSI generic driver which can send us anything.
+	 */
+	esp_check_cmd(esp, SCptr);
+
+	/* If arbitration/selection is successful, the ESP will leave
+	 * ATN asserted, causing the target to go into message out
+	 * phase.  The ESP will feed the target the identify and then
+	 * the target can only legally go to one of command,
+	 * datain/out, status, or message in phase, or stay in message
+	 * out phase (should we be trying to send a sync negotiation
+	 * message after the identify).  It is not allowed to drop
+	 * BSY, but some buggy targets do and we check for this
+	 * condition in the selection complete code.  Most of the time
+	 * we'll make the command bytes available to the ESP and it
+	 * will not interrupt us until it finishes command phase, we
+	 * cannot do this for command sizes the ESP does not
+	 * understand and in this case we'll get interrupted right
+	 * when the target goes into command phase.
+	 *
+	 * It is absolutely _illegal_ in the presence of SCSI-2 devices
+	 * to use the ESP select w/o ATN command.  When SCSI-2 devices are
+	 * present on the bus we _must_ always go straight to message out
+	 * phase with an identify message for the target.  Being that
+	 * selection attempts in SCSI-1 w/o ATN was an option, doing SCSI-2
+	 * selections should not confuse SCSI-1 we hope.
+	 */
+
+	if (esp_dev->sync) {
+		/* this targets sync is known */
+#ifndef __sparc_v9__
+do_sync_known:
+#endif
+		if (esp_dev->disconnect)
+			*cmdp++ = IDENTIFY(1, lun);
+		else
+			*cmdp++ = IDENTIFY(0, lun);
+
+		if (esp->esp_slowcmd) {
+			the_esp_command = (ESP_CMD_SELAS | ESP_CMD_DMA);
+			esp_advance_phase(SCptr, in_slct_stop);
+		} else {
+			the_esp_command = (ESP_CMD_SELA | ESP_CMD_DMA);
+			esp_advance_phase(SCptr, in_slct_norm);
+		}
+	} else if (!(esp->targets_present & (1<<target)) || !(esp_dev->disconnect)) {
+		/* After the bootup SCSI code sends both the
+		 * TEST_UNIT_READY and INQUIRY commands we want
+		 * to at least attempt allowing the device to
+		 * disconnect.
+		 */
+		ESPMISC(("esp: Selecting device for first time. target=%d "
+			 "lun=%d\n", target, SCptr->device->lun));
+		if (!SDptr->borken && !esp_dev->disconnect)
+			esp_dev->disconnect = 1;
+
+		*cmdp++ = IDENTIFY(0, lun);
+		esp->prevmsgout = NOP;
+		esp_advance_phase(SCptr, in_slct_norm);
+		the_esp_command = (ESP_CMD_SELA | ESP_CMD_DMA);
+
+		/* Take no chances... */
+		esp_dev->sync_max_offset = 0;
+		esp_dev->sync_min_period = 0;
+	} else {
+		/* Sorry, I have had way too many problems with
+		 * various CDROM devices on ESP. -DaveM
+		 */
+		int cdrom_hwbug_wkaround = 0;
+
+#ifndef __sparc_v9__
+		/* 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 and removable
+			 * disks (but not CDROMs) to disconnect.
+			 */
+			if(SDptr->type == TYPE_TAPE ||
+			   (SDptr->type != TYPE_ROM && SDptr->removable))
+				esp_dev->disconnect = 1;
+			else
+				esp_dev->disconnect = 0;
+			esp_dev->sync_max_offset = 0;
+			esp_dev->sync_min_period = 0;
+			esp_dev->sync = 1;
+			esp->snip = 0;
+			goto do_sync_known;
+		}
+#endif /* !(__sparc_v9__) */
+
+		/* 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 && !esp_dev->wide) {
+			if (!SDptr->borken &&
+			   SDptr->type != TYPE_ROM &&
+			   SDptr->removable == 0) {
+				build_wide_nego_msg(esp, 16);
+				esp_dev->wide = 1;
+				esp->wnip = 1;
+				goto after_nego_msg_built;
+			} else {
+				esp_dev->wide = 1;
+				/* Fall through and try sync. */
+			}
+		}
+
+		if (!SDptr->borken) {
+			if ((SDptr->type == TYPE_ROM)) {
+				/* Nice try sucker... */
+				ESPMISC(("esp%d: Disabling sync for buggy "
+					 "CDROM.\n", esp->esp_id));
+				cdrom_hwbug_wkaround = 1;
+				build_sync_nego_msg(esp, 0, 0);
+			} else if (SDptr->removable != 0) {
+				ESPMISC(("esp%d: Not negotiating sync/wide but "
+					 "allowing disconnect for removable media.\n",
+					 esp->esp_id));
+				build_sync_nego_msg(esp, 0, 0);
+			} else {
+				build_sync_nego_msg(esp, esp->sync_defp, 15);
+			}
+		} else {
+			build_sync_nego_msg(esp, 0, 0);
+		}
+		esp_dev->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
+		 * find a better fix.
+		 *
+		 * Addendum: This is funny, I figured out what was going
+		 *           on.  The blotzed SCSI1 target would disconnect,
+		 *           one of the other SCSI2 targets or both would be
+		 *           disconnected as well.  The SCSI1 target would
+		 *           stay disconnected long enough that we start
+		 *           up a command on one of the SCSI2 targets.  As
+		 *           the ESP is arbitrating for the bus the SCSI1
+		 *           target begins to arbitrate as well to reselect
+		 *           the ESP.  The SCSI1 target refuses to drop it's
+		 *           ID bit on the data bus even though the ESP is
+		 *           at ID 7 and is the obvious winner for any
+		 *           arbitration.  The ESP is a poor sport and refuses
+		 *           to lose arbitration, it will continue indefinitely
+		 *           trying to arbitrate for the bus and can only be
+		 *           stopped via a chip reset or SCSI bus reset.
+		 *           Therefore _no_ disconnects for SCSI1 targets
+		 *           thank you very much. ;-)
+		 */
+		if(((SDptr->scsi_level < 3) &&
+		    (SDptr->type != TYPE_TAPE) &&
+		    SDptr->removable == 0) ||
+		    cdrom_hwbug_wkaround || SDptr->borken) {
+			ESPMISC((KERN_INFO "esp%d: Disabling DISCONNECT for target %d "
+				 "lun %d\n", esp->esp_id, SCptr->device->id, SCptr->device->lun));
+			esp_dev->disconnect = 0;
+			*cmdp++ = IDENTIFY(0, lun);
+		} else {
+			*cmdp++ = IDENTIFY(1, lun);
+		}
+
+		/* ESP fifo is only so big...
+		 * Make this look like a slow command.
+		 */
+		esp->esp_slowcmd = 1;
+		esp->esp_scmdleft = SCptr->cmd_len;
+		esp->esp_scmdp = &SCptr->cmnd[0];
+
+		the_esp_command = (ESP_CMD_SELAS | ESP_CMD_DMA);
+		esp_advance_phase(SCptr, in_slct_msg);
+	}
+
+	if (!esp->esp_slowcmd)
+		for (i = 0; i < SCptr->cmd_len; i++)
+			*cmdp++ = SCptr->cmnd[i];
+
+	/* HME sucks... */
+	if (esp->erev == fashme)
+		sbus_writeb((target & 0xf) | (ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT),
+			    esp->eregs + ESP_BUSID);
+	else
+		sbus_writeb(target & 7, esp->eregs + ESP_BUSID);
+	if (esp->prev_soff != esp_dev->sync_max_offset ||
+	    esp->prev_stp  != esp_dev->sync_min_period ||
+	    (esp->erev > esp100a &&
+	     esp->prev_cfg3 != esp->config3[target])) {
+		esp->prev_soff = esp_dev->sync_max_offset;
+		esp->prev_stp = esp_dev->sync_min_period;
+		sbus_writeb(esp->prev_soff, esp->eregs + ESP_SOFF);
+		sbus_writeb(esp->prev_stp, esp->eregs + ESP_STP);
+		if (esp->erev > esp100a) {
+			esp->prev_cfg3 = esp->config3[target];
+			sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
+		}
+	}
+	i = (cmdp - esp->esp_command);
+
+	if (esp->erev == fashme) {
+		esp_cmd(esp, ESP_CMD_FLUSH); /* Grrr! */
+
+		/* Set up the DMA and HME counters */
+		sbus_writeb(i, esp->eregs + ESP_TCLOW);
+		sbus_writeb(0, esp->eregs + ESP_TCMED);
+		sbus_writeb(0, esp->eregs + FAS_RLO);
+		sbus_writeb(0, esp->eregs + FAS_RHI);
+		esp_cmd(esp, the_esp_command);
+
+		/* Talk about touchy hardware... */
+		esp->prev_hme_dmacsr = ((esp->prev_hme_dmacsr |
+					 (DMA_SCSI_DISAB | DMA_ENABLE)) &
+					~(DMA_ST_WRITE));
+		sbus_writel(16, esp->dregs + DMA_COUNT);
+		sbus_writel(esp->esp_command_dvma, esp->dregs + DMA_ADDR);
+		sbus_writel(esp->prev_hme_dmacsr, esp->dregs + DMA_CSR);
+	} else {
+		u32 tmp;
+
+		/* Set up the DMA and ESP counters */
+		sbus_writeb(i, esp->eregs + ESP_TCLOW);
+		sbus_writeb(0, esp->eregs + ESP_TCMED);
+		tmp = sbus_readl(esp->dregs + DMA_CSR);
+		tmp &= ~DMA_ST_WRITE;
+		tmp |= DMA_ENABLE;
+		sbus_writel(tmp, esp->dregs + DMA_CSR);
+		if (esp->dma->revision == dvmaesc1) {
+			if (i) /* Workaround ESC gate array SBUS rerun bug. */
+				sbus_writel(PAGE_SIZE, esp->dregs + DMA_COUNT);
+		}
+		sbus_writel(esp->esp_command_dvma, esp->dregs + DMA_ADDR);
+
+		/* Tell ESP to "go". */
+		esp_cmd(esp, the_esp_command);
+	}
+}
+
+/* Queue a SCSI command delivered from the mid-level Linux SCSI code. */
+static int esp_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+{
+	struct esp *esp;
+
+	/* Set up func ptr and initial driver cmd-phase. */
+	SCpnt->scsi_done = done;
+	SCpnt->SCp.phase = not_issued;
+
+	/* We use the scratch area. */
+	ESPQUEUE(("esp_queue: target=%d lun=%d ", SCpnt->device->id, SCpnt->device->lun));
+	ESPDISC(("N<%02x,%02x>", SCpnt->device->id, SCpnt->device->lun));
+
+	esp = (struct esp *) SCpnt->device->host->hostdata;
+	esp_get_dmabufs(esp, SCpnt);
+	esp_save_pointers(esp, SCpnt); /* FIXME for tag queueing */
+
+	SCpnt->SCp.Status           = CHECK_CONDITION;
+	SCpnt->SCp.Message          = 0xff;
+	SCpnt->SCp.sent_command     = 0;
+
+	/* Place into our queue. */
+	if (SCpnt->cmnd[0] == REQUEST_SENSE) {
+		ESPQUEUE(("RQSENSE\n"));
+		prepend_SC(&esp->issue_SC, SCpnt);
+	} else {
+		ESPQUEUE(("\n"));
+		append_SC(&esp->issue_SC, SCpnt);
+	}
+
+	/* Run it now if we can. */
+	if (!esp->current_SC && !esp->resetting_bus)
+		esp_exec_cmd(esp);
+
+	return 0;
+}
+
+/* Dump driver state. */
+static void esp_dump_cmd(struct scsi_cmnd *SCptr)
+{
+	ESPLOG(("[tgt<%02x> lun<%02x> "
+		"pphase<%s> cphase<%s>]",
+		SCptr->device->id, SCptr->device->lun,
+		phase_string(SCptr->SCp.sent_command),
+		phase_string(SCptr->SCp.phase)));
+}
+
+static void esp_dump_state(struct esp *esp)
+{
+	struct scsi_cmnd *SCptr = esp->current_SC;
+#ifdef DEBUG_ESP_CMDS
+	int i;
+#endif
+
+	ESPLOG(("esp%d: dumping state\n", esp->esp_id));
+	ESPLOG(("esp%d: dma -- cond_reg<%08x> addr<%08x>\n",
+		esp->esp_id,
+		sbus_readl(esp->dregs + DMA_CSR),
+		sbus_readl(esp->dregs + DMA_ADDR)));
+	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,
+		sbus_readb(esp->eregs + ESP_STATUS),
+		sbus_readb(esp->eregs + ESP_SSTEP),
+		sbus_readb(esp->eregs + ESP_INTRPT)));
+#ifdef DEBUG_ESP_CMDS
+	printk("esp%d: last ESP cmds [", esp->esp_id);
+	i = (esp->espcmdent - 1) & 31;
+	printk("<"); esp_print_cmd(esp->espcmdlog[i]); printk(">");
+	i = (i - 1) & 31;
+	printk("<"); esp_print_cmd(esp->espcmdlog[i]); printk(">");
+	i = (i - 1) & 31;
+	printk("<"); esp_print_cmd(esp->espcmdlog[i]); printk(">");
+	i = (i - 1) & 31;
+	printk("<"); esp_print_cmd(esp->espcmdlog[i]); printk(">");
+	printk("]\n");
+#endif /* (DEBUG_ESP_CMDS) */
+
+	if (SCptr) {
+		ESPLOG(("esp%d: current command ", esp->esp_id));
+		esp_dump_cmd(SCptr);
+	}
+	ESPLOG(("\n"));
+	SCptr = esp->disconnected_SC;
+	ESPLOG(("esp%d: disconnected ", esp->esp_id));
+	while (SCptr) {
+		esp_dump_cmd(SCptr);
+		SCptr = (struct scsi_cmnd *) SCptr->host_scribble;
+	}
+	ESPLOG(("\n"));
+}
+
+/* Abort a command.  The host_lock is acquired by caller. */
+static int esp_abort(struct scsi_cmnd *SCptr)
+{
+	struct esp *esp = (struct esp *) SCptr->device->host->hostdata;
+	int don;
+
+	ESPLOG(("esp%d: Aborting command\n", esp->esp_id));
+	esp_dump_state(esp);
+
+	/* Wheee, if this is the current command on the bus, the
+	 * best we can do is assert ATN and wait for msgout phase.
+	 * This should even fix a hung SCSI bus when we lose state
+	 * in the driver and timeout because the eventual phase change
+	 * will cause the ESP to (eventually) give an interrupt.
+	 */
+	if (esp->current_SC == SCptr) {
+		esp->cur_msgout[0] = ABORT;
+		esp->msgout_len = 1;
+		esp->msgout_ctr = 0;
+		esp_cmd(esp, ESP_CMD_SATN);
+		return SUCCESS;
+	}
+
+	/* If it is still in the issue queue then we can safely
+	 * call the completion routine and report abort success.
+	 */
+	don = (sbus_readl(esp->dregs + DMA_CSR) & DMA_INT_ENAB);
+	if (don) {
+		ESP_INTSOFF(esp->dregs);
+	}
+	if (esp->issue_SC) {
+		struct scsi_cmnd **prev, *this;
+		for (prev = (&esp->issue_SC), this = esp->issue_SC;
+		     this != NULL;
+		     prev = (struct scsi_cmnd **) &(this->host_scribble),
+			     this = (struct scsi_cmnd *) this->host_scribble) {
+
+			if (this == SCptr) {
+				*prev = (struct scsi_cmnd *) this->host_scribble;
+				this->host_scribble = NULL;
+
+				esp_release_dmabufs(esp, this);
+				this->result = DID_ABORT << 16;
+				this->scsi_done(this);
+
+				if (don)
+					ESP_INTSON(esp->dregs);
+
+				return SUCCESS;
+			}
+		}
+	}
+
+	/* Yuck, the command to abort is disconnected, it is not
+	 * worth trying to abort it now if something else is live
+	 * on the bus at this time.  So, we let the SCSI code wait
+	 * a little bit and try again later.
+	 */
+	if (esp->current_SC) {
+		if (don)
+			ESP_INTSON(esp->dregs);
+		return FAILED;
+	}
+
+	/* It's disconnected, we have to reconnect to re-establish
+	 * the nexus and tell the device to abort.  However, we really
+	 * cannot 'reconnect' per se.  Don't try to be fancy, just
+	 * indicate failure, which causes our caller to reset the whole
+	 * bus.
+	 */
+
+	if (don)
+		ESP_INTSON(esp->dregs);
+
+	return FAILED;
+}
+
+/* We've sent ESP_CMD_RS to the ESP, the interrupt had just
+ * arrived indicating the end of the SCSI bus reset.  Our job
+ * is to clean out the command queues and begin re-execution
+ * of SCSI commands once more.
+ */
+static int esp_finish_reset(struct esp *esp)
+{
+	struct scsi_cmnd *sp = esp->current_SC;
+
+	/* Clean up currently executing command, if any. */
+	if (sp != NULL) {
+		esp->current_SC = NULL;
+
+		esp_release_dmabufs(esp, sp);
+		sp->result = (DID_RESET << 16);
+
+		sp->scsi_done(sp);
+	}
+
+	/* Clean up disconnected queue, they have been invalidated
+	 * by the bus reset.
+	 */
+	if (esp->disconnected_SC) {
+		while ((sp = remove_first_SC(&esp->disconnected_SC)) != NULL) {
+			esp_release_dmabufs(esp, sp);
+			sp->result = (DID_RESET << 16);
+
+			sp->scsi_done(sp);
+		}
+	}
+
+	/* SCSI bus reset is complete. */
+	esp->resetting_bus = 0;
+	wake_up(&esp->reset_queue);
+
+	/* Ok, now it is safe to get commands going once more. */
+	if (esp->issue_SC)
+		esp_exec_cmd(esp);
+
+	return do_intr_end;
+}
+
+static int esp_do_resetbus(struct esp *esp)
+{
+	ESPLOG(("esp%d: Resetting scsi bus\n", esp->esp_id));
+	esp->resetting_bus = 1;
+	esp_cmd(esp, ESP_CMD_RS);
+
+	return do_intr_end;
+}
+
+/* Reset ESP chip, reset hanging bus, then kill active and
+ * disconnected commands for targets without soft reset.
+ *
+ * The host_lock is acquired by caller.
+ */
+static int esp_reset(struct scsi_cmnd *SCptr)
+{
+	struct esp *esp = (struct esp *) SCptr->device->host->hostdata;
+
+	(void) esp_do_resetbus(esp);
+
+	spin_unlock_irq(esp->ehost->host_lock);
+
+	wait_event(esp->reset_queue, (esp->resetting_bus == 0));
+
+	spin_lock_irq(esp->ehost->host_lock);
+
+	return SUCCESS;
+}
+
+/* Internal ESP done function. */
+static void esp_done(struct esp *esp, int error)
+{
+	struct scsi_cmnd *done_SC = esp->current_SC;
+
+	esp->current_SC = NULL;
+
+	esp_release_dmabufs(esp, done_SC);
+	done_SC->result = error;
+
+	done_SC->scsi_done(done_SC);
+
+	/* Bus is free, issue any commands in the queue. */
+	if (esp->issue_SC && !esp->current_SC)
+		esp_exec_cmd(esp);
+
+}
+
+/* Wheee, ESP interrupt engine. */  
+
+/* Forward declarations. */
+static int esp_do_phase_determine(struct esp *esp);
+static int esp_do_data_finale(struct esp *esp);
+static int esp_select_complete(struct esp *esp);
+static int esp_do_status(struct esp *esp);
+static int esp_do_msgin(struct esp *esp);
+static int esp_do_msgindone(struct esp *esp);
+static int esp_do_msgout(struct esp *esp);
+static int esp_do_cmdbegin(struct esp *esp);
+
+#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 esp *esp)
+{
+	u8 count = 0;
+	u8 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 = sbus_readb(esp->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++] =
+				sbus_readb(esp->eregs + ESP_FDATA);
+			esp->hme_fifo_workaround_buffer[count++] =
+				sbus_readb(esp->eregs + ESP_FDATA);
+			ESPHME(("<%02x,%02x>", esp->hme_fifo_workaround_buffer[count-2], esp->hme_fifo_workaround_buffer[count-1]));
+			fcnt--;
+		}
+		if (sbus_readb(esp->eregs + ESP_STATUS2) & ESP_STAT2_F1BYTE) {
+			ESPHME(("<poke_byte>"));
+			sbus_writeb(0, esp->eregs + ESP_FDATA);
+			esp->hme_fifo_workaround_buffer[count++] =
+				sbus_readb(esp->eregs + ESP_FDATA);
+			ESPHME(("<%02x,0x00>", esp->hme_fifo_workaround_buffer[count-1]));
+			ESPHME(("CMD_FLUSH"));
+			esp_cmd(esp, 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 esp *esp, u8 *bytes, u8 count)
+{
+	esp_cmd(esp, ESP_CMD_FLUSH);
+	while (count) {
+		u8 tmp = *bytes++;
+		sbus_writeb(tmp, esp->eregs + ESP_FDATA);
+		sbus_writeb(0, esp->eregs + ESP_FDATA);
+		count--;
+	}
+}
+
+/* We try to avoid some interrupts by jumping ahead and see if the ESP
+ * has gotten far enough yet.  Hence the following.
+ */
+static inline int skipahead1(struct esp *esp, struct scsi_cmnd *scp,
+			     int prev_phase, int new_phase)
+{
+	if (scp->SCp.sent_command != prev_phase)
+		return 0;
+	if (ESP_IRQ_P(esp->dregs)) {
+		/* Yes, we are able to save an interrupt. */
+		if (esp->erev == fashme)
+			esp->sreg2 = sbus_readb(esp->eregs + ESP_STATUS2);
+		esp->sreg = (sbus_readb(esp->eregs + ESP_STATUS) & ~(ESP_STAT_INTR));
+		esp->ireg = sbus_readb(esp->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);
+		}
+		if (!(esp->ireg & ESP_INTR_SR))
+			return 0;
+		else
+			return do_reset_complete;
+	}
+	/* Ho hum, target is taking forever... */
+	scp->SCp.sent_command = new_phase; /* so we don't recurse... */
+	return do_intr_end;
+}
+
+static inline int skipahead2(struct esp *esp, struct scsi_cmnd *scp,
+			     int prev_phase1, int prev_phase2, int new_phase)
+{
+	if (scp->SCp.sent_command != prev_phase1 &&
+	    scp->SCp.sent_command != prev_phase2)
+		return 0;
+	if (ESP_IRQ_P(esp->dregs)) {
+		/* Yes, we are able to save an interrupt. */
+		if (esp->erev == fashme)
+			esp->sreg2 = sbus_readb(esp->eregs + ESP_STATUS2);
+		esp->sreg = (sbus_readb(esp->eregs + ESP_STATUS) & ~(ESP_STAT_INTR));
+		esp->ireg = sbus_readb(esp->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);
+		}
+		if (!(esp->ireg & ESP_INTR_SR))
+			return 0;
+		else
+			return do_reset_complete;
+	}
+	/* Ho hum, target is taking forever... */
+	scp->SCp.sent_command = new_phase; /* so we don't recurse... */
+	return do_intr_end;
+}
+
+/* Now some dma helpers. */
+static void dma_setup(struct esp *esp, __u32 addr, int count, int write)
+{
+	u32 nreg = sbus_readl(esp->dregs + DMA_CSR);
+
+	if (write)
+		nreg |= DMA_ST_WRITE;
+	else
+		nreg &= ~(DMA_ST_WRITE);
+	nreg |= DMA_ENABLE;
+	sbus_writel(nreg, esp->dregs + DMA_CSR);
+	if (esp->dma->revision == dvmaesc1) {
+		/* This ESC gate array sucks! */
+		__u32 src = addr;
+		__u32 dest = src + count;
+
+		if (dest & (PAGE_SIZE - 1))
+			count = PAGE_ALIGN(count);
+		sbus_writel(count, esp->dregs + DMA_COUNT);
+	}
+	sbus_writel(addr, esp->dregs + DMA_ADDR);
+}
+
+static void dma_drain(struct esp *esp)
+{
+	u32 tmp;
+
+	if (esp->dma->revision == dvmahme)
+		return;
+	if ((tmp = sbus_readl(esp->dregs + DMA_CSR)) & DMA_FIFO_ISDRAIN) {
+		switch (esp->dma->revision) {
+		default:
+			tmp |= DMA_FIFO_STDRAIN;
+			sbus_writel(tmp, esp->dregs + DMA_CSR);
+
+		case dvmarev3:
+		case dvmaesc1:
+			while (sbus_readl(esp->dregs + DMA_CSR) & DMA_FIFO_ISDRAIN)
+				udelay(1);
+		};
+	}
+}
+
+static void dma_invalidate(struct esp *esp)
+{
+	u32 tmp;
+
+	if (esp->dma->revision == dvmahme) {
+		sbus_writel(DMA_RST_SCSI, esp->dregs + DMA_CSR);
+
+		esp->prev_hme_dmacsr = ((esp->prev_hme_dmacsr |
+					 (DMA_PARITY_OFF | DMA_2CLKS |
+					  DMA_SCSI_DISAB | DMA_INT_ENAB)) &
+					~(DMA_ST_WRITE | DMA_ENABLE));
+
+		sbus_writel(0, esp->dregs + DMA_CSR);
+		sbus_writel(esp->prev_hme_dmacsr, esp->dregs + DMA_CSR);
+
+		/* This is necessary to avoid having the SCSI channel
+		 * engine lock up on us.
+		 */
+		sbus_writel(0, esp->dregs + DMA_ADDR);
+	} else {
+		while ((tmp = sbus_readl(esp->dregs + DMA_CSR)) & DMA_PEND_READ)
+			udelay(1);
+
+		tmp &= ~(DMA_ENABLE | DMA_ST_WRITE | DMA_BCNT_ENAB);
+		tmp |= DMA_FIFO_INV;
+		sbus_writel(tmp, esp->dregs + DMA_CSR);
+		tmp &= ~DMA_FIFO_INV;
+		sbus_writel(tmp, esp->dregs + DMA_CSR);
+	}
+}
+
+static inline void dma_flashclear(struct esp *esp)
+{
+	dma_drain(esp);
+	dma_invalidate(esp);
+}
+
+static int dma_can_transfer(struct esp *esp, struct scsi_cmnd *sp)
+{
+	__u32 base, end, sz;
+
+	if (esp->dma->revision == dvmarev3) {
+		sz = sp->SCp.this_residual;
+		if (sz > 0x1000000)
+			sz = 0x1000000;
+	} else {
+		base = ((__u32)((unsigned long)sp->SCp.ptr));
+		base &= (0x1000000 - 1);
+		end = (base + sp->SCp.this_residual);
+		if (end > 0x1000000)
+			end = 0x1000000;
+		sz = (end - base);
+	}
+	return sz;
+}
+
+/* Misc. esp helper macros. */
+#define esp_setcount(__eregs, __cnt, __hme) \
+	sbus_writeb(((__cnt)&0xff), (__eregs) + ESP_TCLOW); \
+	sbus_writeb((((__cnt)>>8)&0xff), (__eregs) + ESP_TCMED); \
+	if (__hme) { \
+		sbus_writeb((((__cnt)>>16)&0xff), (__eregs) + FAS_RLO); \
+		sbus_writeb(0, (__eregs) + FAS_RHI); \
+	}
+
+#define esp_getcount(__eregs, __hme) \
+	((sbus_readb((__eregs) + ESP_TCLOW)&0xff) | \
+	 ((sbus_readb((__eregs) + ESP_TCMED)&0xff) << 8) | \
+         ((__hme) ? sbus_readb((__eregs) + FAS_RLO) << 16 : 0))
+
+#define fcount(__esp) \
+	(((__esp)->erev == fashme) ? \
+	  (__esp)->hme_fifo_workaround_count : \
+	  sbus_readb(((__esp)->eregs) + ESP_FFLAGS) & ESP_FF_FBYTES)
+
+#define fnzero(__esp) \
+	(((__esp)->erev == fashme) ? 0 : \
+	 sbus_readb(((__esp)->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
+ * XXX writes...
+ */
+#define esp_maybe_nop(__esp) \
+	if ((__esp)->erev == esp100) \
+		esp_cmd((__esp), ESP_CMD_NULL)
+
+#define sreg_to_dataphase(__sreg) \
+	((((__sreg) & ESP_STAT_PMASK) == ESP_DOP) ? in_dataout : in_datain)
+
+/* The ESP100 when in synchronous data phase, can mistake a long final
+ * REQ pulse from the target as an extra byte, it places whatever is on
+ * the data lines into the fifo.  For now, we will assume when this
+ * happens that the target is a bit quirky and we don't want to
+ * be talking synchronously to it anyways.  Regardless, we need to
+ * tell the ESP to eat the extraneous byte so that we can proceed
+ * to the next phase.
+ */
+static int esp100_sync_hwbug(struct esp *esp, struct scsi_cmnd *sp, int fifocnt)
+{
+	/* Do not touch this piece of code. */
+	if ((!(esp->erev == esp100)) ||
+	    (!(sreg_datainp((esp->sreg = sbus_readb(esp->eregs + ESP_STATUS))) &&
+	       !fifocnt) &&
+	     !(sreg_dataoutp(esp->sreg) && !fnzero(esp)))) {
+		if (sp->SCp.phase == in_dataout)
+			esp_cmd(esp, ESP_CMD_FLUSH);
+		return 0;
+	} else {
+		/* Async mode for this guy. */
+		build_sync_nego_msg(esp, 0, 0);
+
+		/* Ack the bogus byte, but set ATN first. */
+		esp_cmd(esp, ESP_CMD_SATN);
+		esp_cmd(esp, ESP_CMD_MOK);
+		return 1;
+	}
+}
+
+/* This closes the window during a selection with a reselect pending, because
+ * we use DMA for the selection process the FIFO should hold the correct
+ * contents if we get reselected during this process.  So we just need to
+ * ack the possible illegal cmd interrupt pending on the esp100.
+ */
+static inline int esp100_reconnect_hwbug(struct esp *esp)
+{
+	u8 tmp;
+
+	if (esp->erev != esp100)
+		return 0;
+	tmp = sbus_readb(esp->eregs + ESP_INTRPT);
+	if (tmp & ESP_INTR_SR)
+		return 1;
+	return 0;
+}
+
+/* This verifies the BUSID bits during a reselection so that we know which
+ * target is talking to us.
+ */
+static inline int reconnect_target(struct esp *esp)
+{
+	int it, me = esp->scsi_id_mask, targ = 0;
+
+	if (2 != fcount(esp))
+		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 = sbus_readb(esp->eregs + ESP_FDATA);
+		if (!(it & me))
+			return -1;
+		it &= ~me;
+		if (it & (it - 1))
+			return -1;
+		while (!(it & 1))
+			targ++, it >>= 1;
+	}
+	return targ;
+}
+
+/* This verifies the identify from the target so that we know which lun is
+ * being reconnected.
+ */
+static inline int reconnect_lun(struct esp *esp)
+{
+	int lun;
+
+	if ((esp->sreg & ESP_STAT_PMASK) != ESP_MIP)
+		return -1;
+	if (esp->erev == fashme)
+		lun = esp->hme_fifo_workaround_buffer[1];
+	else
+		lun = sbus_readb(esp->eregs + ESP_FDATA);
+
+	/* Yes, you read this correctly.  We report lun of zero
+	 * if we see parity error.  ESP reports parity error for
+	 * the lun byte, and this is the only way to hope to recover
+	 * because the target is connected.
+	 */
+	if (esp->sreg & ESP_STAT_PERR)
+		return 0;
+
+	/* Check for illegal bits being set in the lun. */
+	if ((lun & 0x40) || !(lun & 0x80))
+		return -1;
+
+	return lun & 7;
+}
+
+/* This puts the driver in a state where it can revitalize a command that
+ * is being continued due to reselection.
+ */
+static inline void esp_connect(struct esp *esp, struct scsi_cmnd *sp)
+{
+	struct esp_device *esp_dev = sp->device->hostdata;
+
+	if (esp->prev_soff  != esp_dev->sync_max_offset ||
+	    esp->prev_stp   != esp_dev->sync_min_period ||
+	    (esp->erev > esp100a &&
+	     esp->prev_cfg3 != esp->config3[sp->device->id])) {
+		esp->prev_soff = esp_dev->sync_max_offset;
+		esp->prev_stp = esp_dev->sync_min_period;
+		sbus_writeb(esp->prev_soff, esp->eregs + ESP_SOFF);
+		sbus_writeb(esp->prev_stp, esp->eregs + ESP_STP);
+		if (esp->erev > esp100a) {
+			esp->prev_cfg3 = esp->config3[sp->device->id];
+			sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
+		}
+	}
+	esp->current_SC = sp;
+}
+
+/* This will place the current working command back into the issue queue
+ * if we are to receive a reselection amidst a selection attempt.
+ */
+static inline void esp_reconnect(struct esp *esp, struct scsi_cmnd *sp)
+{
+	if (!esp->disconnected_SC)
+		ESPLOG(("esp%d: Weird, being reselected but disconnected "
+			"command queue is empty.\n", esp->esp_id));
+	esp->snip = 0;
+	esp->current_SC = 0;
+	sp->SCp.phase = not_issued;
+	append_SC(&esp->issue_SC, sp);
+}
+
+/* Begin message in phase. */
+static int esp_do_msgin(struct esp *esp)
+{
+	/* Must be very careful with the fifo on the HME */
+	if ((esp->erev != fashme) ||
+	    !(sbus_readb(esp->eregs + ESP_STATUS2) & ESP_STAT2_FEMPTY))
+		esp_cmd(esp, ESP_CMD_FLUSH);
+	esp_maybe_nop(esp);
+	esp_cmd(esp, ESP_CMD_TI);
+	esp->msgin_len = 1;
+	esp->msgin_ctr = 0;
+	esp_advance_phase(esp->current_SC, in_msgindone);
+	return do_work_bus;
+}
+
+/* This uses various DMA csr fields and the fifo flags count value to
+ * determine how many bytes were successfully sent/received by the ESP.
+ */
+static inline int esp_bytes_sent(struct esp *esp, int fifo_count)
+{
+	int rval = sbus_readl(esp->dregs + DMA_ADDR) - esp->esp_command_dvma;
+
+	if (esp->dma->revision == dvmarev1)
+		rval -= (4 - ((sbus_readl(esp->dregs + DMA_CSR) & DMA_READ_AHEAD)>>11));
+	return rval - fifo_count;
+}
+
+static inline void advance_sg(struct scsi_cmnd *sp)
+{
+	++sp->SCp.buffer;
+	--sp->SCp.buffers_residual;
+	sp->SCp.this_residual = sg_dma_len(sp->SCp.buffer);
+	sp->SCp.ptr = (char *)((unsigned long)sg_dma_address(sp->SCp.buffer));
+}
+
+/* Please note that the way I've coded these routines is that I _always_
+ * check for a disconnect during any and all information transfer
+ * phases.  The SCSI standard states that the target _can_ cause a BUS
+ * FREE condition by dropping all MSG/CD/IO/BSY signals.  Also note
+ * that during information transfer phases the target controls every
+ * change in phase, the only thing the initiator can do is "ask" for
+ * a message out phase by driving ATN true.  The target can, and sometimes
+ * will, completely ignore this request so we cannot assume anything when
+ * we try to force a message out phase to abort/reset a target.  Most of
+ * the time the target will eventually be nice and go to message out, so
+ * we may have to hold on to our state about what we want to tell the target
+ * for some period of time.
+ */
+
+/* I think I have things working here correctly.  Even partial transfers
+ * within a buffer or sub-buffer should not upset us at all no matter
+ * how bad the target and/or ESP fucks things up.
+ */
+static int esp_do_data(struct esp *esp)
+{
+	struct scsi_cmnd *SCptr = esp->current_SC;
+	int thisphase, hmuch;
+
+	ESPDATA(("esp_do_data: "));
+	esp_maybe_nop(esp);
+	thisphase = sreg_to_dataphase(esp->sreg);
+	esp_advance_phase(SCptr, thisphase);
+	ESPDATA(("newphase<%s> ", (thisphase == in_datain) ? "DATAIN" : "DATAOUT"));
+	hmuch = dma_can_transfer(esp, SCptr);
+	if (hmuch > (64 * 1024) && (esp->erev != fashme))
+		hmuch = (64 * 1024);
+	ESPDATA(("hmuch<%d> ", hmuch));
+	esp->current_transfer_size = hmuch;
+
+	if (esp->erev == fashme) {
+		u32 tmp = esp->prev_hme_dmacsr;
+
+		/* Always set the ESP count registers first. */
+		esp_setcount(esp->eregs, hmuch, 1);
+
+		/* Get the DMA csr computed. */
+		tmp |= (DMA_SCSI_DISAB | DMA_ENABLE);
+		if (thisphase == in_datain)
+			tmp |= DMA_ST_WRITE;
+		else
+			tmp &= ~(DMA_ST_WRITE);
+		esp->prev_hme_dmacsr = tmp;
+
+		ESPDATA(("DMA|TI --> do_intr_end\n"));
+		if (thisphase == in_datain) {
+			sbus_writel(hmuch, esp->dregs + DMA_COUNT);
+			esp_cmd(esp, ESP_CMD_DMA | ESP_CMD_TI);
+		} else {
+			esp_cmd(esp, ESP_CMD_DMA | ESP_CMD_TI);
+			sbus_writel(hmuch, esp->dregs + DMA_COUNT);
+		}
+		sbus_writel((__u32)((unsigned long)SCptr->SCp.ptr), esp->dregs+DMA_ADDR);
+		sbus_writel(esp->prev_hme_dmacsr, esp->dregs + DMA_CSR);
+	} else {
+		esp_setcount(esp->eregs, hmuch, 0);
+		dma_setup(esp, ((__u32)((unsigned long)SCptr->SCp.ptr)),
+			  hmuch, (thisphase == in_datain));
+		ESPDATA(("DMA|TI --> do_intr_end\n"));
+		esp_cmd(esp, ESP_CMD_DMA | ESP_CMD_TI);
+	}
+	return do_intr_end;
+}
+
+/* See how successful the data transfer was. */
+static int esp_do_data_finale(struct esp *esp)
+{
+	struct scsi_cmnd *SCptr = esp->current_SC;
+	struct esp_device *esp_dev = SCptr->device->hostdata;
+	int bogus_data = 0, bytes_sent = 0, fifocnt, ecount = 0;
+
+	ESPDATA(("esp_do_data_finale: "));
+
+	if (SCptr->SCp.phase == in_datain) {
+		if (esp->sreg & ESP_STAT_PERR) {
+			/* Yuck, parity error.  The ESP asserts ATN
+			 * so that we can go to message out phase
+			 * immediately and inform the target that
+			 * something bad happened.
+			 */
+			ESPLOG(("esp%d: data bad parity detected.\n",
+				esp->esp_id));
+			esp->cur_msgout[0] = INITIATOR_ERROR;
+			esp->msgout_len = 1;
+		}
+		dma_drain(esp);
+	}
+	dma_invalidate(esp);
+
+	/* This could happen for the above parity error case. */
+	if (esp->ireg != ESP_INTR_BSERV) {
+		/* Please go to msgout phase, please please please... */
+		ESPLOG(("esp%d: !BSERV after data, probably to msgout\n",
+			esp->esp_id));
+		return esp_do_phase_determine(esp);
+	}	
+
+	/* 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 synchronous
+	 * 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 = (sbus_readb(esp->eregs + ESP_FFLAGS) & ESP_FF_FBYTES);
+	if (esp->erev != fashme)
+		ecount = esp_getcount(esp->eregs, 0);
+	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(esp->eregs, 1);
+			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 (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));
+
+	/* If we were in synchronous mode, check for peculiarities. */
+	if (esp->erev == fashme) {
+		if (esp_dev->sync_max_offset) {
+			if (SCptr->SCp.phase == in_dataout)
+				esp_cmd(esp, ESP_CMD_FLUSH);
+		} else {
+			esp_cmd(esp, ESP_CMD_FLUSH);
+		}
+	} else {
+		if (esp_dev->sync_max_offset)
+			bogus_data = esp100_sync_hwbug(esp, SCptr, fifocnt);
+		else
+			esp_cmd(esp, ESP_CMD_FLUSH);
+	}
+
+	/* Until we are sure of what has happened, we are certainly
+	 * in the dark.
+	 */
+	esp_advance_phase(SCptr, in_the_dark);
+
+	if (bytes_sent < 0) {
+		/* I've seen this happen due to lost state in this
+		 * driver.  No idea why it happened, but allowing
+		 * this value to be negative caused things to
+		 * lock up.  This allows greater chance of recovery.
+		 * In fact every time I've seen this, it has been
+		 * a driver bug without question.
+		 */
+		ESPLOG(("esp%d: yieee, bytes_sent < 0!\n", esp->esp_id));
+		ESPLOG(("esp%d: csz=%d fifocount=%d ecount=%d\n",
+			esp->esp_id,
+			esp->current_transfer_size, fifocnt, ecount));
+		ESPLOG(("esp%d: use_sg=%d ptr=%p this_residual=%d\n",
+			esp->esp_id,
+			SCptr->use_sg, SCptr->SCp.ptr, SCptr->SCp.this_residual));
+		ESPLOG(("esp%d: Forcing async for target %d\n", esp->esp_id, 
+			SCptr->device->id));
+		SCptr->device->borken = 1;
+		esp_dev->sync = 0;
+		bytes_sent = 0;
+	}
+
+	/* Update the state of our transfer. */
+	SCptr->SCp.ptr += bytes_sent;
+	SCptr->SCp.this_residual -= bytes_sent;
+	if (SCptr->SCp.this_residual < 0) {
+		/* shit */
+		ESPLOG(("esp%d: Data transfer overrun.\n", esp->esp_id));
+		SCptr->SCp.this_residual = 0;
+	}
+
+	/* Maybe continue. */
+	if (!bogus_data) {
+		ESPDATA(("!bogus_data, "));
+
+		/* NO MATTER WHAT, we advance the scatterlist,
+		 * if the target should decide to disconnect
+		 * in between scatter chunks (which is common)
+		 * we could die horribly!  I used to have the sg
+		 * advance occur only if we are going back into
+		 * (or are staying in) a data phase, you can
+		 * imagine the hell I went through trying to
+		 * figure this out.
+		 */
+		if (SCptr->use_sg && !SCptr->SCp.this_residual)
+			advance_sg(SCptr);
+		if (sreg_datainp(esp->sreg) || sreg_dataoutp(esp->sreg)) {
+			ESPDATA(("to more data\n"));
+			return esp_do_data(esp);
+		}
+		ESPDATA(("to new phase\n"));
+		return esp_do_phase_determine(esp);
+	}
+	/* Bogus data, just wait for next interrupt. */
+	ESPLOG(("esp%d: bogus_data during end of data phase\n",
+		esp->esp_id));
+	return do_intr_end;
+}
+
+/* We received a non-good status return at the end of
+ * running a SCSI command.  This is used to decide if
+ * we should clear our synchronous transfer state for
+ * such a device when that happens.
+ *
+ * The idea is that when spinning up a disk or rewinding
+ * a tape, we don't want to go into a loop re-negotiating
+ * synchronous capabilities over and over.
+ */
+static int esp_should_clear_sync(struct scsi_cmnd *sp)
+{
+	u8 cmd1 = sp->cmnd[0];
+	u8 cmd2 = sp->data_cmnd[0];
+
+	/* These cases are for spinning up a disk and
+	 * waiting for that spinup to complete.
+	 */
+	if (cmd1 == START_STOP ||
+	    cmd2 == START_STOP)
+		return 0;
+
+	if (cmd1 == TEST_UNIT_READY ||
+	    cmd2 == TEST_UNIT_READY)
+		return 0;
+
+	/* One more special case for SCSI tape drives,
+	 * this is what is used to probe the device for
+	 * completion of a rewind or tape load operation.
+	 */
+	if (sp->device->type == TYPE_TAPE) {
+		if (cmd1 == MODE_SENSE ||
+		    cmd2 == MODE_SENSE)
+			return 0;
+	}
+
+	return 1;
+}
+
+/* Either a command is completing or a target is dropping off the bus
+ * to continue the command in the background so we can do other work.
+ */
+static int esp_do_freebus(struct esp *esp)
+{
+	struct scsi_cmnd *SCptr = esp->current_SC;
+	struct esp_device *esp_dev = SCptr->device->hostdata;
+	int rval;
+
+	rval = skipahead2(esp, SCptr, in_status, in_msgindone, in_freeing);
+	if (rval)
+		return rval;
+	if (esp->ireg != ESP_INTR_DC) {
+		ESPLOG(("esp%d: Target will not disconnect\n", esp->esp_id));
+		return do_reset_bus; /* target will not drop BSY... */
+	}
+	esp->msgout_len = 0;
+	esp->prevmsgout = NOP;
+	if (esp->prevmsgin == COMMAND_COMPLETE) {
+		/* Normal end of nexus. */
+		if (esp->disconnected_SC || (esp->erev == fashme))
+			esp_cmd(esp, ESP_CMD_ESEL);
+
+		if (SCptr->SCp.Status != GOOD &&
+		    SCptr->SCp.Status != CONDITION_GOOD &&
+		    ((1<<SCptr->device->id) & esp->targets_present) &&
+		    esp_dev->sync &&
+		    esp_dev->sync_max_offset) {
+			/* SCSI standard says that the synchronous capabilities
+			 * should be renegotiated at this point.  Most likely
+			 * we are about to request sense from this target
+			 * in which case we want to avoid using sync
+			 * transfers until we are sure of the current target
+			 * state.
+			 */
+			ESPMISC(("esp: Status <%d> for target %d lun %d\n",
+				 SCptr->SCp.Status, SCptr->device->id, SCptr->device->lun));
+
+			/* But don't do this when spinning up a disk at
+			 * boot time while we poll for completion as it
+			 * fills up the console with messages.  Also, tapes
+			 * can report not ready many times right after
+			 * loading up a tape.
+			 */
+			if (esp_should_clear_sync(SCptr) != 0)
+				esp_dev->sync = 0;
+		}
+		ESPDISC(("F<%02x,%02x>", SCptr->device->id, SCptr->device->lun));
+		esp_done(esp, ((SCptr->SCp.Status & 0xff) |
+			       ((SCptr->SCp.Message & 0xff)<<8) |
+			       (DID_OK << 16)));
+	} else if (esp->prevmsgin == DISCONNECT) {
+		/* Normal disconnect. */
+		esp_cmd(esp, ESP_CMD_ESEL);
+		ESPDISC(("D<%02x,%02x>", SCptr->device->id, SCptr->device->lun));
+		append_SC(&esp->disconnected_SC, SCptr);
+		esp->current_SC = NULL;
+		if (esp->issue_SC)
+			esp_exec_cmd(esp);
+	} else {
+		/* Driver bug, we do not expect a disconnect here
+		 * and should not have advanced the state engine
+		 * to in_freeing.
+		 */
+		ESPLOG(("esp%d: last msg not disc and not cmd cmplt.\n",
+			esp->esp_id));
+		return do_reset_bus;
+	}
+	return do_intr_end;
+}
+
+/* When a reselect occurs, and we cannot find the command to
+ * reconnect to in our queues, we do this.
+ */
+static int esp_bad_reconnect(struct esp *esp)
+{
+	struct scsi_cmnd *sp;
+
+	ESPLOG(("esp%d: Eieeee, reconnecting unknown command!\n",
+		esp->esp_id));
+	ESPLOG(("QUEUE DUMP\n"));
+	sp = esp->issue_SC;
+	ESPLOG(("esp%d: issue_SC[", esp->esp_id));
+	while (sp) {
+		ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun));
+		sp = (struct scsi_cmnd *) sp->host_scribble;
+	}
+	ESPLOG(("]\n"));
+	sp = esp->current_SC;
+	ESPLOG(("esp%d: current_SC[", esp->esp_id));
+	if (sp)
+		ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun));
+	else
+		ESPLOG(("<NULL>"));
+	ESPLOG(("]\n"));
+	sp = esp->disconnected_SC;
+	ESPLOG(("esp%d: disconnected_SC[", esp->esp_id));
+	while (sp) {
+		ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun));
+		sp = (struct scsi_cmnd *) sp->host_scribble;
+	}
+	ESPLOG(("]\n"));
+	return do_reset_bus;
+}
+
+/* Do the needy when a target tries to reconnect to us. */
+static int esp_do_reconnect(struct esp *esp)
+{
+	int lun, target;
+	struct scsi_cmnd *SCptr;
+
+	/* Check for all bogus conditions first. */
+	target = reconnect_target(esp);
+	if (target < 0) {
+		ESPDISC(("bad bus bits\n"));
+		return do_reset_bus;
+	}
+	lun = reconnect_lun(esp);
+	if (lun < 0) {
+		ESPDISC(("target=%2x, bad identify msg\n", target));
+		return do_reset_bus;
+	}
+
+	/* Things look ok... */
+	ESPDISC(("R<%02x,%02x>", target, lun));
+
+	/* Must not flush FIFO or DVMA on HME. */
+	if (esp->erev != fashme) {
+		esp_cmd(esp, ESP_CMD_FLUSH);
+		if (esp100_reconnect_hwbug(esp))
+			return do_reset_bus;
+		esp_cmd(esp, ESP_CMD_NULL);
+	}
+
+	SCptr = remove_SC(&esp->disconnected_SC, (u8) target, (u8) lun);
+	if (!SCptr)
+		return esp_bad_reconnect(esp);
+
+	esp_connect(esp, SCptr);
+	esp_cmd(esp, ESP_CMD_MOK);
+
+	if (esp->erev == fashme)
+		sbus_writeb(((SCptr->device->id & 0xf) |
+			     (ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT)),
+			    esp->eregs + ESP_BUSID);
+
+	/* Reconnect implies a restore pointers operation. */
+	esp_restore_pointers(esp, SCptr);
+
+	esp->snip = 0;
+	esp_advance_phase(SCptr, in_the_dark);
+	return do_intr_end;
+}
+
+/* End of NEXUS (hopefully), pick up status + message byte then leave if
+ * all goes well.
+ */
+static int esp_do_status(struct esp *esp)
+{
+	struct scsi_cmnd *SCptr = esp->current_SC;
+	int intr, rval;
+
+	rval = skipahead1(esp, SCptr, in_the_dark, in_status);
+	if (rval)
+		return rval;
+	intr = esp->ireg;
+	ESPSTAT(("esp_do_status: "));
+	if (intr != ESP_INTR_DC) {
+		int message_out = 0; /* for parity problems */
+
+		/* Ack the message. */
+		ESPSTAT(("ack msg, "));
+		esp_cmd(esp, ESP_CMD_MOK);
+
+		if (esp->erev != fashme) {
+			dma_flashclear(esp);
+
+			/* Wait till the first bits settle. */
+			while (esp->esp_command[0] == 0xff)
+				udelay(1);
+		} else {
+			esp->esp_command[0] = esp->hme_fifo_workaround_buffer[0];
+			esp->esp_command[1] = esp->hme_fifo_workaround_buffer[1];
+		}
+
+		ESPSTAT(("got something, "));
+		/* ESP chimes in with one of
+		 *
+		 * 1) function done interrupt:
+		 *	both status and message in bytes
+		 *	are available
+		 *
+		 * 2) bus service interrupt:
+		 *	only status byte was acquired
+		 *
+		 * 3) Anything else:
+		 *	can't happen, but we test for it
+		 *	anyways
+		 *
+		 * ALSO: If bad parity was detected on either
+		 *       the status _or_ the message byte then
+		 *       the ESP has asserted ATN on the bus
+		 *       and we must therefore wait for the
+		 *       next phase change.
+		 */
+		if (intr & ESP_INTR_FDONE) {
+			/* We got it all, hallejulia. */
+			ESPSTAT(("got both, "));
+			SCptr->SCp.Status = esp->esp_command[0];
+			SCptr->SCp.Message = esp->esp_command[1];
+			esp->prevmsgin = SCptr->SCp.Message;
+			esp->cur_msgin[0] = SCptr->SCp.Message;
+			if (esp->sreg & ESP_STAT_PERR) {
+				/* There was bad parity for the
+				 * message byte, the status byte
+				 * was ok.
+				 */
+				message_out = MSG_PARITY_ERROR;
+			}
+		} else if (intr == ESP_INTR_BSERV) {
+			/* Only got status byte. */
+			ESPLOG(("esp%d: got status only, ", esp->esp_id));
+			if (!(esp->sreg & ESP_STAT_PERR)) {
+				SCptr->SCp.Status = esp->esp_command[0];
+				SCptr->SCp.Message = 0xff;
+			} else {
+				/* The status byte had bad parity.
+				 * we leave the scsi_pointer Status
+				 * field alone as we set it to a default
+				 * of CHECK_CONDITION in esp_queue.
+				 */
+				message_out = INITIATOR_ERROR;
+			}
+		} else {
+			/* This shouldn't happen ever. */
+			ESPSTAT(("got bolixed\n"));
+			esp_advance_phase(SCptr, in_the_dark);
+			return esp_do_phase_determine(esp);
+		}
+
+		if (!message_out) {
+			ESPSTAT(("status=%2x msg=%2x, ", SCptr->SCp.Status,
+				SCptr->SCp.Message));
+			if (SCptr->SCp.Message == COMMAND_COMPLETE) {
+				ESPSTAT(("and was COMMAND_COMPLETE\n"));
+				esp_advance_phase(SCptr, in_freeing);
+				return esp_do_freebus(esp);
+			} else {
+				ESPLOG(("esp%d: and _not_ COMMAND_COMPLETE\n",
+					esp->esp_id));
+				esp->msgin_len = esp->msgin_ctr = 1;
+				esp_advance_phase(SCptr, in_msgindone);
+				return esp_do_msgindone(esp);
+			}
+		} else {
+			/* With luck we'll be able to let the target
+			 * know that bad parity happened, it will know
+			 * which byte caused the problems and send it
+			 * again.  For the case where the status byte
+			 * receives bad parity, I do not believe most
+			 * targets recover very well.  We'll see.
+			 */
+			ESPLOG(("esp%d: bad parity somewhere mout=%2x\n",
+				esp->esp_id, message_out));
+			esp->cur_msgout[0] = message_out;
+			esp->msgout_len = esp->msgout_ctr = 1;
+			esp_advance_phase(SCptr, in_the_dark);
+			return esp_do_phase_determine(esp);
+		}
+	} else {
+		/* If we disconnect now, all hell breaks loose. */
+		ESPLOG(("esp%d: whoops, disconnect\n", esp->esp_id));
+		esp_advance_phase(SCptr, in_the_dark);
+		return esp_do_phase_determine(esp);
+	}
+}
+
+static int esp_enter_status(struct esp *esp)
+{
+	u8 thecmd = ESP_CMD_ICCSEQ;
+
+	esp_cmd(esp, ESP_CMD_FLUSH);
+	if (esp->erev != fashme) {
+		u32 tmp;
+
+		esp->esp_command[0] = esp->esp_command[1] = 0xff;
+		sbus_writeb(2, esp->eregs + ESP_TCLOW);
+		sbus_writeb(0, esp->eregs + ESP_TCMED);
+		tmp = sbus_readl(esp->dregs + DMA_CSR);
+		tmp |= (DMA_ST_WRITE | DMA_ENABLE);
+		sbus_writel(tmp, esp->dregs + DMA_CSR);
+		if (esp->dma->revision == dvmaesc1)
+			sbus_writel(0x100, esp->dregs + DMA_COUNT);
+		sbus_writel(esp->esp_command_dvma, esp->dregs + DMA_ADDR);
+		thecmd |= ESP_CMD_DMA;
+	}
+	esp_cmd(esp, thecmd);
+	esp_advance_phase(esp->current_SC, in_status);
+
+	return esp_do_status(esp);
+}
+
+static int esp_disconnect_amidst_phases(struct esp *esp)
+{
+	struct scsi_cmnd *sp = esp->current_SC;
+	struct esp_device *esp_dev = sp->device->hostdata;
+
+	/* This means real problems if we see this
+	 * here.  Unless we were actually trying
+	 * to force the device to abort/reset.
+	 */
+	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 != NULL || (esp->erev == fashme))
+		esp_cmd(esp, ESP_CMD_ESEL);
+
+	switch (esp->cur_msgout[0]) {
+	default:
+		/* We didn't expect this to happen at all. */
+		ESPLOG(("device is bolixed\n"));
+		esp_advance_phase(sp, in_tgterror);
+		esp_done(esp, (DID_ERROR << 16));
+		break;
+
+	case BUS_DEVICE_RESET:
+		ESPLOG(("device reset successful\n"));
+		esp_dev->sync_max_offset = 0;
+		esp_dev->sync_min_period = 0;
+		esp_dev->sync = 0;
+		esp_advance_phase(sp, in_resetdev);
+		esp_done(esp, (DID_RESET << 16));
+		break;
+
+	case ABORT:
+		ESPLOG(("device abort successful\n"));
+		esp_advance_phase(sp, in_abortone);
+		esp_done(esp, (DID_ABORT << 16));
+		break;
+
+	};
+	return do_intr_end;
+}
+
+static int esp_enter_msgout(struct esp *esp)
+{
+	esp_advance_phase(esp->current_SC, in_msgout);
+	return esp_do_msgout(esp);
+}
+
+static int esp_enter_msgin(struct esp *esp)
+{
+	esp_advance_phase(esp->current_SC, in_msgin);
+	return esp_do_msgin(esp);
+}
+
+static int esp_enter_cmd(struct esp *esp)
+{
+	esp_advance_phase(esp->current_SC, in_cmdbegin);
+	return esp_do_cmdbegin(esp);
+}
+
+static int esp_enter_badphase(struct esp *esp)
+{
+	ESPLOG(("esp%d: Bizarre bus phase %2x.\n", esp->esp_id,
+		esp->sreg & ESP_STAT_PMASK));
+	return do_reset_bus;
+}
+
+typedef int (*espfunc_t)(struct esp *);
+
+static espfunc_t phase_vector[] = {
+	esp_do_data,		/* ESP_DOP */
+	esp_do_data,		/* ESP_DIP */
+	esp_enter_cmd,		/* ESP_CMDP */
+	esp_enter_status,	/* ESP_STATP */
+	esp_enter_badphase,	/* ESP_STAT_PMSG */
+	esp_enter_badphase,	/* ESP_STAT_PMSG | ESP_STAT_PIO */
+	esp_enter_msgout,	/* ESP_MOP */
+	esp_enter_msgin,	/* ESP_MIP */
+};
+
+/* The target has control of the bus and we have to see where it has
+ * taken us.
+ */
+static int esp_do_phase_determine(struct esp *esp)
+{
+	if ((esp->ireg & ESP_INTR_DC) != 0)
+		return esp_disconnect_amidst_phases(esp);
+	return phase_vector[esp->sreg & ESP_STAT_PMASK](esp);
+}
+
+/* First interrupt after exec'ing a cmd comes here. */
+static int esp_select_complete(struct esp *esp)
+{
+	struct scsi_cmnd *SCptr = esp->current_SC;
+	struct esp_device *esp_dev = SCptr->device->hostdata;
+	int cmd_bytes_sent, fcnt;
+
+	if (esp->erev != fashme)
+		esp->seqreg = (sbus_readb(esp->eregs + ESP_SSTEP) & ESP_STEP_VBITS);
+
+	if (esp->erev == fashme)
+		fcnt = esp->hme_fifo_workaround_count;
+	else
+		fcnt = (sbus_readb(esp->eregs + ESP_FFLAGS) & ESP_FF_FBYTES);
+
+	cmd_bytes_sent = esp_bytes_sent(esp, fcnt);
+	dma_invalidate(esp);
+
+	/* Let's check to see if a reselect happened
+	 * while we we're trying to select.  This must
+	 * be checked first.
+	 */
+	if (esp->ireg == (ESP_INTR_RSEL | ESP_INTR_FDONE)) {
+		esp_reconnect(esp, SCptr);
+		return esp_do_reconnect(esp);
+	}
+
+	/* Looks like things worked, we should see a bus service &
+	 * a function complete interrupt at this point.  Note we
+	 * are doing a direct comparison because we don't want to
+	 * be fooled into thinking selection was successful if
+	 * ESP_INTR_DC is set, see below.
+	 */
+	if (esp->ireg == (ESP_INTR_FDONE | ESP_INTR_BSERV)) {
+		/* target speaks... */
+		esp->targets_present |= (1<<SCptr->device->id);
+
+		/* What if the target ignores the sdtr? */
+		if (esp->snip)
+			esp_dev->sync = 1;
+
+		/* See how far, if at all, we got in getting
+		 * the information out to the target.
+		 */
+		switch (esp->seqreg) {
+		default:
+
+		case ESP_STEP_ASEL:
+			/* Arbitration won, target selected, but
+			 * we are in some phase which is not command
+			 * phase nor is it message out phase.
+			 *
+			 * XXX We've confused the target, obviously.
+			 * XXX So clear it's state, but we also end
+			 * XXX up clearing everyone elses.  That isn't
+			 * XXX so nice.  I'd like to just reset this
+			 * XXX target, but if I cannot even get it's
+			 * XXX attention and finish selection to talk
+			 * XXX to it, there is not much more I can do.
+			 * XXX If we have a loaded bus we're going to
+			 * XXX spend the next second or so renegotiating
+			 * XXX for synchronous transfers.
+			 */
+			ESPLOG(("esp%d: STEP_ASEL for tgt %d\n",
+				esp->esp_id, SCptr->device->id));
+
+		case ESP_STEP_SID:
+			/* Arbitration won, target selected, went
+			 * to message out phase, sent one message
+			 * byte, then we stopped.  ATN is asserted
+			 * on the SCSI bus and the target is still
+			 * there hanging on.  This is a legal
+			 * sequence step if we gave the ESP a select
+			 * and stop command.
+			 *
+			 * XXX See above, I could set the borken flag
+			 * XXX in the device struct and retry the
+			 * XXX command.  But would that help for
+			 * XXX tagged capable targets?
+			 */
+
+		case ESP_STEP_NCMD:
+			/* Arbitration won, target selected, maybe
+			 * sent the one message byte in message out
+			 * phase, but we did not go to command phase
+			 * in the end.  Actually, we could have sent
+			 * only some of the message bytes if we tried
+			 * to send out the entire identify and tag
+			 * message using ESP_CMD_SA3.
+			 */
+			cmd_bytes_sent = 0;
+			break;
+
+		case ESP_STEP_PPC:
+			/* No, not the powerPC pinhead.  Arbitration
+			 * won, all message bytes sent if we went to
+			 * message out phase, went to command phase
+			 * but only part of the command was sent.
+			 *
+			 * XXX I've seen this, but usually in conjunction
+			 * XXX with a gross error which appears to have
+			 * XXX occurred between the time I told the
+			 * XXX ESP to arbitrate and when I got the
+			 * XXX interrupt.  Could I have misloaded the
+			 * XXX command bytes into the fifo?  Actually,
+			 * XXX I most likely missed a phase, and therefore
+			 * XXX went into never never land and didn't even
+			 * XXX know it.  That was the old driver though.
+			 * XXX What is even more peculiar is that the ESP
+			 * XXX showed the proper function complete and
+			 * XXX bus service bits in the interrupt register.
+			 */
+
+		case ESP_STEP_FINI4:
+		case ESP_STEP_FINI5:
+		case ESP_STEP_FINI6:
+		case ESP_STEP_FINI7:
+			/* Account for the identify message */
+			if (SCptr->SCp.phase == in_slct_norm)
+				cmd_bytes_sent -= 1;
+		};
+
+		if (esp->erev != fashme)
+			esp_cmd(esp, 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... */
+		    /* either we are not doing synchronous transfers or... */
+		    (!esp_dev->sync_max_offset ||
+		     /* We are not going into data in phase. */
+		     ((esp->sreg & ESP_STAT_PMASK) != ESP_DIP)))
+			esp_cmd(esp, ESP_CMD_FLUSH); /* flush is safe */
+
+		/* See how far we got if this is not a slow command. */
+		if (!esp->esp_slowcmd) {
+			if (cmd_bytes_sent < 0)
+				cmd_bytes_sent = 0;
+			if (cmd_bytes_sent != SCptr->cmd_len) {
+				/* Crapola, mark it as a slowcmd
+				 * so that we have some chance of
+				 * keeping the command alive with
+				 * good luck.
+				 *
+				 * XXX Actually, if we didn't send it all
+				 * XXX this means either we didn't set things
+				 * XXX up properly (driver bug) or the target
+				 * XXX or the ESP detected parity on one of
+				 * XXX the command bytes.  This makes much
+				 * XXX more sense, and therefore this code
+				 * XXX should be changed to send out a
+				 * XXX parity error message or if the status
+				 * XXX register shows no parity error then
+				 * XXX just expect the target to bring the
+				 * XXX bus into message in phase so that it
+				 * XXX can send us the parity error message.
+				 * XXX SCSI sucks...
+				 */
+				esp->esp_slowcmd = 1;
+				esp->esp_scmdp = &(SCptr->cmnd[cmd_bytes_sent]);
+				esp->esp_scmdleft = (SCptr->cmd_len - cmd_bytes_sent);
+			}
+		}
+
+		/* Now figure out where we went. */
+		esp_advance_phase(SCptr, in_the_dark);
+		return esp_do_phase_determine(esp);
+	}
+
+	/* Did the target even make it? */
+	if (esp->ireg == ESP_INTR_DC) {
+		/* wheee... nobody there or they didn't like
+		 * what we told it to do, clean up.
+		 */
+
+		/* If anyone is off the bus, but working on
+		 * a command in the background for us, tell
+		 * the ESP to listen for them.
+		 */
+		if (esp->disconnected_SC)
+			esp_cmd(esp, ESP_CMD_ESEL);
+
+		if (((1<<SCptr->device->id) & esp->targets_present) &&
+		    esp->seqreg != 0 &&
+		    (esp->cur_msgout[0] == EXTENDED_MESSAGE) &&
+		    (SCptr->SCp.phase == in_slct_msg ||
+		     SCptr->SCp.phase == in_slct_stop)) {
+			/* shit */
+			esp->snip = 0;
+			ESPLOG(("esp%d: Failed synchronous negotiation for target %d "
+				"lun %d\n", esp->esp_id, SCptr->device->id, SCptr->device->lun));
+			esp_dev->sync_max_offset = 0;
+			esp_dev->sync_min_period = 0;
+			esp_dev->sync = 1; /* so we don't negotiate again */
+
+			/* Run the command again, this time though we
+			 * won't try to negotiate for synchronous transfers.
+			 *
+			 * XXX I'd like to do something like send an
+			 * XXX INITIATOR_ERROR or ABORT message to the
+			 * XXX target to tell it, "Sorry I confused you,
+			 * XXX please come back and I will be nicer next
+			 * XXX time".  But that requires having the target
+			 * XXX on the bus, and it has dropped BSY on us.
+			 */
+			esp->current_SC = NULL;
+			esp_advance_phase(SCptr, not_issued);
+			prepend_SC(&esp->issue_SC, SCptr);
+			esp_exec_cmd(esp);
+			return do_intr_end;
+		}
+
+		/* Ok, this is normal, this is what we see during boot
+		 * or whenever when we are scanning the bus for targets.
+		 * But first make sure that is really what is happening.
+		 */
+		if (((1<<SCptr->device->id) & esp->targets_present)) {
+			ESPLOG(("esp%d: Warning, live target %d not responding to "
+				"selection.\n", esp->esp_id, SCptr->device->id));
+
+			/* This _CAN_ happen.  The SCSI standard states that
+			 * the target is to _not_ respond to selection if
+			 * _it_ detects bad parity on the bus for any reason.
+			 * Therefore, we assume that if we've talked successfully
+			 * to this target before, bad parity is the problem.
+			 */
+			esp_done(esp, (DID_PARITY << 16));
+		} else {
+			/* Else, there really isn't anyone there. */
+			ESPMISC(("esp: selection failure, maybe nobody there?\n"));
+			ESPMISC(("esp: target %d lun %d\n",
+				 SCptr->device->id, SCptr->device->lun));
+			esp_done(esp, (DID_BAD_TARGET << 16));
+		}
+		return do_intr_end;
+	}
+
+	ESPLOG(("esp%d: Selection failure.\n", esp->esp_id));
+	printk("esp%d: Currently -- ", esp->esp_id);
+	esp_print_ireg(esp->ireg); printk(" ");
+	esp_print_statreg(esp->sreg); printk(" ");
+	esp_print_seqreg(esp->seqreg); printk("\n");
+	printk("esp%d: New -- ", esp->esp_id);
+	esp->sreg = sbus_readb(esp->eregs + ESP_STATUS);
+	esp->seqreg = sbus_readb(esp->eregs + ESP_SSTEP);
+	esp->ireg = sbus_readb(esp->eregs + ESP_INTRPT);
+	esp_print_ireg(esp->ireg); printk(" ");
+	esp_print_statreg(esp->sreg); printk(" ");
+	esp_print_seqreg(esp->seqreg); printk("\n");
+	ESPLOG(("esp%d: resetting bus\n", esp->esp_id));
+	return do_reset_bus; /* ugh... */
+}
+
+/* Continue reading bytes for msgin phase. */
+static int esp_do_msgincont(struct esp *esp)
+{
+	if (esp->ireg & ESP_INTR_BSERV) {
+		/* in the right phase too? */
+		if ((esp->sreg & ESP_STAT_PMASK) == ESP_MIP) {
+			/* phew... */
+			esp_cmd(esp, ESP_CMD_TI);
+			esp_advance_phase(esp->current_SC, in_msgindone);
+			return do_intr_end;
+		}
+
+		/* We changed phase but ESP shows bus service,
+		 * in this case it is most likely that we, the
+		 * hacker who has been up for 20hrs straight
+		 * staring at the screen, drowned in coffee
+		 * smelling like retched cigarette ashes
+		 * have miscoded something..... so, try to
+		 * recover as best we can.
+		 */
+		ESPLOG(("esp%d: message in mis-carriage.\n", esp->esp_id));
+	}
+	esp_advance_phase(esp->current_SC, in_the_dark);
+	return do_phase_determine;
+}
+
+static int check_singlebyte_msg(struct esp *esp)
+{
+	esp->prevmsgin = esp->cur_msgin[0];
+	if (esp->cur_msgin[0] & 0x80) {
+		/* wheee... */
+		ESPLOG(("esp%d: target sends identify amidst phases\n",
+			esp->esp_id));
+		esp_advance_phase(esp->current_SC, in_the_dark);
+		return 0;
+	} else if (((esp->cur_msgin[0] & 0xf0) == 0x20) ||
+		   (esp->cur_msgin[0] == EXTENDED_MESSAGE)) {
+		esp->msgin_len = 2;
+		esp_advance_phase(esp->current_SC, in_msgincont);
+		return 0;
+	}
+	esp_advance_phase(esp->current_SC, in_the_dark);
+	switch (esp->cur_msgin[0]) {
+	default:
+		/* We don't want to hear about it. */
+		ESPLOG(("esp%d: msg %02x which we don't know about\n", esp->esp_id,
+			esp->cur_msgin[0]));
+		return MESSAGE_REJECT;
+
+	case NOP:
+		ESPLOG(("esp%d: target %d sends a nop\n", esp->esp_id,
+			esp->current_SC->device->id));
+		return 0;
+
+	case RESTORE_POINTERS:
+		/* In this case we might also have to backup the
+		 * "slow command" pointer.  It is rare to get such
+		 * a save/restore pointer sequence so early in the
+		 * bus transition sequences, but cover it.
+		 */
+		if (esp->esp_slowcmd) {
+			esp->esp_scmdleft = esp->current_SC->cmd_len;
+			esp->esp_scmdp = &esp->current_SC->cmnd[0];
+		}
+		esp_restore_pointers(esp, esp->current_SC);
+		return 0;
+
+	case SAVE_POINTERS:
+		esp_save_pointers(esp, esp->current_SC);
+		return 0;
+
+	case COMMAND_COMPLETE:
+	case DISCONNECT:
+		/* Freeing the bus, let it go. */
+		esp->current_SC->SCp.phase = in_freeing;
+		return 0;
+
+	case MESSAGE_REJECT:
+		ESPMISC(("msg reject, "));
+		if (esp->prevmsgout == EXTENDED_MESSAGE) {
+			struct esp_device *esp_dev = esp->current_SC->device->hostdata;
+
+			/* Doesn't look like this target can
+			 * do synchronous or WIDE transfers.
+			 */
+			ESPSDTR(("got reject, was trying nego, clearing sync/WIDE\n"));
+			esp_dev->sync = 1;
+			esp_dev->wide = 1;
+			esp_dev->sync_min_period = 0;
+			esp_dev->sync_max_offset = 0;
+			return 0;
+		} else {
+			ESPMISC(("not sync nego, sending ABORT\n"));
+			return ABORT;
+		}
+	};
+}
+
+/* Target negotiates for synchronous transfers before we do, this
+ * is legal although very strange.  What is even funnier is that
+ * the SCSI2 standard specifically recommends against targets doing
+ * this because so many initiators cannot cope with this occurring.
+ */
+static int target_with_ants_in_pants(struct esp *esp,
+				     struct scsi_cmnd *SCptr,
+				     struct esp_device *esp_dev)
+{
+	if (esp_dev->sync || SCptr->device->borken) {
+		/* sorry, no can do */
+		ESPSDTR(("forcing to async, "));
+		build_sync_nego_msg(esp, 0, 0);
+		esp_dev->sync = 1;
+		esp->snip = 1;
+		ESPLOG(("esp%d: hoping for msgout\n", esp->esp_id));
+		esp_advance_phase(SCptr, in_the_dark);
+		return EXTENDED_MESSAGE;
+	}
+
+	/* Ok, we'll check them out... */
+	return 0;
+}
+
+static void sync_report(struct esp *esp)
+{
+	int msg3, msg4;
+	char *type;
+
+	msg3 = esp->cur_msgin[3];
+	msg4 = esp->cur_msgin[4];
+	if (msg4) {
+		int hz = 1000000000 / (msg3 * 4);
+		int integer = hz / 1000000;
+		int fraction = (hz - (integer * 1000000)) / 10000;
+		if ((esp->erev == fashme) &&
+		    (esp->config3[esp->current_SC->device->id] & ESP_CONFIG3_EWIDE)) {
+			type = "FAST-WIDE";
+			integer <<= 1;
+			fraction <<= 1;
+		} else if ((msg3 * 4) < 200) {
+			type = "FAST";
+		} else {
+			type = "synchronous";
+		}
+
+		/* Do not transform this back into one big printk
+		 * again, it triggers a bug in our sparc64-gcc272
+		 * sibling call optimization.  -DaveM
+		 */
+		ESPLOG((KERN_INFO "esp%d: target %d ",
+			esp->esp_id, esp->current_SC->device->id));
+		ESPLOG(("[period %dns offset %d %d.%02dMHz ",
+			(int) msg3 * 4, (int) msg4,
+			integer, fraction));
+		ESPLOG(("%s SCSI%s]\n", type,
+			(((msg3 * 4) < 200) ? "-II" : "")));
+	} else {
+		ESPLOG((KERN_INFO "esp%d: target %d asynchronous\n",
+			esp->esp_id, esp->current_SC->device->id));
+	}
+}
+
+static int check_multibyte_msg(struct esp *esp)
+{
+	struct scsi_cmnd *SCptr = esp->current_SC;
+	struct esp_device *esp_dev = SCptr->device->hostdata;
+	u8 regval = 0;
+	int message_out = 0;
+
+	ESPSDTR(("chk multibyte msg: "));
+	if (esp->cur_msgin[2] == EXTENDED_SDTR) {
+		int period = esp->cur_msgin[3];
+		int offset = esp->cur_msgin[4];
+
+		ESPSDTR(("is sync nego response, "));
+		if (!esp->snip) {
+			int rval;
+
+			/* Target negotiates first! */
+			ESPSDTR(("target jumps the gun, "));
+			message_out = EXTENDED_MESSAGE; /* we must respond */
+			rval = target_with_ants_in_pants(esp, SCptr, esp_dev);
+			if (rval)
+				return rval;
+		}
+
+		ESPSDTR(("examining sdtr, "));
+
+		/* Offset cannot be larger than ESP fifo size. */
+		if (offset > 15) {
+			ESPSDTR(("offset too big %2x, ", offset));
+			offset = 15;
+			ESPSDTR(("sending back new offset\n"));
+			build_sync_nego_msg(esp, period, offset);
+			return EXTENDED_MESSAGE;
+		}
+
+		if (offset && period > esp->max_period) {
+			/* Yeee, async for this slow device. */
+			ESPSDTR(("period too long %2x, ", period));
+			build_sync_nego_msg(esp, 0, 0);
+			ESPSDTR(("hoping for msgout\n"));
+			esp_advance_phase(esp->current_SC, in_the_dark);
+			return EXTENDED_MESSAGE;
+		} else if (offset && period < esp->min_period) {
+			ESPSDTR(("period too short %2x, ", period));
+			period = esp->min_period;
+			if (esp->erev > esp236)
+				regval = 4;
+			else
+				regval = 5;
+		} else if (offset) {
+			int tmp;
+
+			ESPSDTR(("period is ok, "));
+			tmp = esp->ccycle / 1000;
+			regval = (((period << 2) + tmp - 1) / tmp);
+			if (regval && ((esp->erev == fas100a ||
+					esp->erev == fas236  ||
+					esp->erev == fashme))) {
+				if (period >= 50)
+					regval--;
+			}
+		}
+
+		if (offset) {
+			u8 bit;
+
+			esp_dev->sync_min_period = (regval & 0x1f);
+			esp_dev->sync_max_offset = (offset | esp->radelay);
+			if (esp->erev == fas100a || esp->erev == fas236 || esp->erev == fashme) {
+				if ((esp->erev == fas100a) || (esp->erev == fashme))
+					bit = ESP_CONFIG3_FAST;
+				else
+					bit = ESP_CONFIG3_FSCSI;
+				if (period < 50) {
+					/* On FAS366, if using fast-20 synchronous transfers
+					 * we need to make sure the REQ/ACK assert/deassert
+					 * control bits are clear.
+					 */
+					if (esp->erev == fashme)
+						esp_dev->sync_max_offset &= ~esp->radelay;
+					esp->config3[SCptr->device->id] |= bit;
+				} else {
+					esp->config3[SCptr->device->id] &= ~bit;
+				}
+				esp->prev_cfg3 = esp->config3[SCptr->device->id];
+				sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
+			}
+			esp->prev_soff = esp_dev->sync_max_offset;
+			esp->prev_stp = esp_dev->sync_min_period;
+			sbus_writeb(esp->prev_soff, esp->eregs + ESP_SOFF);
+			sbus_writeb(esp->prev_stp, esp->eregs + ESP_STP);
+			ESPSDTR(("soff=%2x stp=%2x cfg3=%2x\n",
+				 esp_dev->sync_max_offset,
+				 esp_dev->sync_min_period,
+				 esp->config3[SCptr->device->id]));
+
+			esp->snip = 0;
+		} else if (esp_dev->sync_max_offset) {
+			u8 bit;
+
+			/* back to async mode */
+			ESPSDTR(("unaccaptable sync nego, forcing async\n"));
+			esp_dev->sync_max_offset = 0;
+			esp_dev->sync_min_period = 0;
+			esp->prev_soff = 0;
+			esp->prev_stp = 0;
+			sbus_writeb(esp->prev_soff, esp->eregs + ESP_SOFF);
+			sbus_writeb(esp->prev_stp, esp->eregs + ESP_STP);
+			if (esp->erev == fas100a || esp->erev == fas236 || esp->erev == fashme) {
+				if ((esp->erev == fas100a) || (esp->erev == fashme))
+					bit = ESP_CONFIG3_FAST;
+				else
+					bit = ESP_CONFIG3_FSCSI;
+				esp->config3[SCptr->device->id] &= ~bit;
+				esp->prev_cfg3 = esp->config3[SCptr->device->id];
+				sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
+			}
+		}
+
+		sync_report(esp);
+
+		ESPSDTR(("chk multibyte msg: sync is known, "));
+		esp_dev->sync = 1;
+
+		if (message_out) {
+			ESPLOG(("esp%d: sending sdtr back, hoping for msgout\n",
+				esp->esp_id));
+			build_sync_nego_msg(esp, period, offset);
+			esp_advance_phase(SCptr, in_the_dark);
+			return EXTENDED_MESSAGE;
+		}
+
+		ESPSDTR(("returning zero\n"));
+		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->device->id] |= 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->device->id] &= ~(ESP_CONFIG3_EWIDE);
+			}
+			esp->prev_cfg3 = esp->config3[SCptr->device->id];
+			sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
+
+			/* Regardless, next try for sync transfers. */
+			build_sync_nego_msg(esp, esp->sync_defp, 15);
+			esp_dev->sync = 1;
+			esp->snip = 1;
+			message_out = EXTENDED_MESSAGE;
+		}
+	} 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;
+}
+
+static int esp_do_msgindone(struct esp *esp)
+{
+	struct scsi_cmnd *SCptr = esp->current_SC;
+	int message_out = 0, it = 0, rval;
+
+	rval = skipahead1(esp, SCptr, in_msgin, in_msgindone);
+	if (rval)
+		return rval;
+	if (SCptr->SCp.sent_command != in_status) {
+		if (!(esp->ireg & ESP_INTR_DC)) {
+			if (esp->msgin_len && (esp->sreg & ESP_STAT_PERR)) {
+				message_out = MSG_PARITY_ERROR;
+				esp_cmd(esp, ESP_CMD_FLUSH);
+			} else if (esp->erev != fashme &&
+			  (it = (sbus_readb(esp->eregs + ESP_FFLAGS) & ESP_FF_FBYTES)) != 1) {
+				/* We certainly dropped the ball somewhere. */
+				message_out = INITIATOR_ERROR;
+				esp_cmd(esp, ESP_CMD_FLUSH);
+			} else if (!esp->msgin_len) {
+				if (esp->erev == fashme)
+					it = esp->hme_fifo_workaround_buffer[0];
+				else
+					it = sbus_readb(esp->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] =
+						sbus_readb(esp->eregs + ESP_FDATA);
+				esp->msgin_ctr++;
+			}
+		} else {
+			esp_advance_phase(SCptr, in_the_dark);
+			return do_work_bus;
+		}
+	} else {
+		it = esp->cur_msgin[0];
+	}
+	if (!message_out && esp->msgin_len) {
+		if (esp->msgin_ctr < esp->msgin_len) {
+			esp_advance_phase(SCptr, in_msgincont);
+		} else if (esp->msgin_len == 1) {
+			message_out = check_singlebyte_msg(esp);
+		} else if (esp->msgin_len == 2) {
+			if (esp->cur_msgin[0] == EXTENDED_MESSAGE) {
+				if ((it + 2) >= 15) {
+					message_out = MESSAGE_REJECT;
+				} else {
+					esp->msgin_len = (it + 2);
+					esp_advance_phase(SCptr, in_msgincont);
+				}
+			} else {
+				message_out = MESSAGE_REJECT; /* foo on you */
+			}
+		} else {
+			message_out = check_multibyte_msg(esp);
+		}
+	}
+	if (message_out < 0) {
+		return -message_out;
+	} else if (message_out) {
+		if (((message_out != 1) &&
+		     ((message_out < 0x20) || (message_out & 0x80))))
+			esp->msgout_len = 1;
+		esp->cur_msgout[0] = message_out;
+		esp_cmd(esp, ESP_CMD_SATN);
+		esp_advance_phase(SCptr, in_the_dark);
+		esp->msgin_len = 0;
+	}
+	esp->sreg = sbus_readb(esp->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, ESP_CMD_MOK);
+	if ((SCptr->SCp.sent_command == in_msgindone) &&
+	    (SCptr->SCp.phase == in_freeing))
+		return esp_do_freebus(esp);
+	return do_intr_end;
+}
+
+static int esp_do_cmdbegin(struct esp *esp)
+{
+	struct scsi_cmnd *SCptr = esp->current_SC;
+
+	esp_advance_phase(SCptr, in_cmdend);
+	if (esp->erev == fashme) {
+		u32 tmp = sbus_readl(esp->dregs + DMA_CSR);
+		int i;
+
+		for (i = 0; i < esp->esp_scmdleft; i++)
+			esp->esp_command[i] = *esp->esp_scmdp++;
+		esp->esp_scmdleft = 0;
+		esp_cmd(esp, ESP_CMD_FLUSH);
+		esp_setcount(esp->eregs, i, 1);
+		esp_cmd(esp, (ESP_CMD_DMA | ESP_CMD_TI));
+		tmp |= (DMA_SCSI_DISAB | DMA_ENABLE);
+		tmp &= ~(DMA_ST_WRITE);
+		sbus_writel(i, esp->dregs + DMA_COUNT);
+		sbus_writel(esp->esp_command_dvma, esp->dregs + DMA_ADDR);
+		sbus_writel(tmp, esp->dregs + DMA_CSR);
+	} else {
+		u8 tmp;
+
+		esp_cmd(esp, ESP_CMD_FLUSH);
+		tmp = *esp->esp_scmdp++;
+		esp->esp_scmdleft--;
+		sbus_writeb(tmp, esp->eregs + ESP_FDATA);
+		esp_cmd(esp, ESP_CMD_TI);
+	}
+	return do_intr_end;
+}
+
+static int esp_do_cmddone(struct esp *esp)
+{
+	if (esp->erev == fashme)
+		dma_invalidate(esp);
+	else
+		esp_cmd(esp, ESP_CMD_NULL);
+
+	if (esp->ireg & ESP_INTR_BSERV) {
+		esp_advance_phase(esp->current_SC, in_the_dark);
+		return esp_do_phase_determine(esp);
+	}
+
+	ESPLOG(("esp%d: in do_cmddone() but didn't get BSERV interrupt.\n",
+		esp->esp_id));
+	return do_reset_bus;
+}
+
+static int esp_do_msgout(struct esp *esp)
+{
+	esp_cmd(esp, ESP_CMD_FLUSH);
+	switch (esp->msgout_len) {
+	case 1:
+		if (esp->erev == fashme)
+			hme_fifo_push(esp, &esp->cur_msgout[0], 1);
+		else
+			sbus_writeb(esp->cur_msgout[0], esp->eregs + ESP_FDATA);
+
+		esp_cmd(esp, ESP_CMD_TI);
+		break;
+
+	case 2:
+		esp->esp_command[0] = esp->cur_msgout[0];
+		esp->esp_command[1] = esp->cur_msgout[1];
+
+		if (esp->erev == fashme) {
+			hme_fifo_push(esp, &esp->cur_msgout[0], 2);
+			esp_cmd(esp, ESP_CMD_TI);
+		} else {
+			dma_setup(esp, esp->esp_command_dvma, 2, 0);
+			esp_setcount(esp->eregs, 2, 0);
+			esp_cmd(esp, ESP_CMD_DMA | ESP_CMD_TI);
+		}
+		break;
+
+	case 4:
+		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];
+		esp->snip = 1;
+
+		if (esp->erev == fashme) {
+			hme_fifo_push(esp, &esp->cur_msgout[0], 4);
+			esp_cmd(esp, ESP_CMD_TI);
+		} else {
+			dma_setup(esp, esp->esp_command_dvma, 4, 0);
+			esp_setcount(esp->eregs, 4, 0);
+			esp_cmd(esp, ESP_CMD_DMA | ESP_CMD_TI);
+		}
+		break;
+
+	case 5:
+		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];
+		esp->esp_command[4] = esp->cur_msgout[4];
+		esp->snip = 1;
+
+		if (esp->erev == fashme) {
+			hme_fifo_push(esp, &esp->cur_msgout[0], 5);
+			esp_cmd(esp, ESP_CMD_TI);
+		} else {
+			dma_setup(esp, esp->esp_command_dvma, 5, 0);
+			esp_setcount(esp->eregs, 5, 0);
+			esp_cmd(esp, ESP_CMD_DMA | ESP_CMD_TI);
+		}
+		break;
+
+	default:
+		/* whoops */
+		ESPMISC(("bogus msgout sending NOP\n"));
+		esp->cur_msgout[0] = NOP;
+
+		if (esp->erev == fashme) {
+			hme_fifo_push(esp, &esp->cur_msgout[0], 1);
+		} else {
+			sbus_writeb(esp->cur_msgout[0], esp->eregs + ESP_FDATA);
+		}
+
+		esp->msgout_len = 1;
+		esp_cmd(esp, ESP_CMD_TI);
+		break;
+	};
+
+	esp_advance_phase(esp->current_SC, in_msgoutdone);
+	return do_intr_end;
+}
+
+static int esp_do_msgoutdone(struct esp *esp)
+{
+	if (esp->msgout_len > 1) {
+		/* XXX HME/FAS ATN deassert workaround required,
+		 * XXX no DMA flushing, only possible ESP_CMD_FLUSH
+		 * XXX to kill the fifo.
+		 */
+		if (esp->erev != fashme) {
+			u32 tmp;
+
+			while ((tmp = sbus_readl(esp->dregs + DMA_CSR)) & DMA_PEND_READ)
+				udelay(1);
+			tmp &= ~DMA_ENABLE;
+			sbus_writel(tmp, esp->dregs + DMA_CSR);
+			dma_invalidate(esp);
+		} else {
+			esp_cmd(esp, ESP_CMD_FLUSH);
+		}
+	}
+	if (!(esp->ireg & ESP_INTR_DC)) {
+		if (esp->erev != fashme)
+			esp_cmd(esp, ESP_CMD_NULL);
+		switch (esp->sreg & ESP_STAT_PMASK) {
+		case ESP_MOP:
+			/* whoops, parity error */
+			ESPLOG(("esp%d: still in msgout, parity error assumed\n",
+				esp->esp_id));
+			if (esp->msgout_len > 1)
+				esp_cmd(esp, ESP_CMD_SATN);
+			esp_advance_phase(esp->current_SC, in_msgout);
+			return do_work_bus;
+
+		case ESP_DIP:
+			break;
+
+		default:
+			/* Happy Meal fifo is touchy... */
+			if ((esp->erev != fashme) &&
+			    !fcount(esp) &&
+			    !(((struct esp_device *)esp->current_SC->device->hostdata)->sync_max_offset))
+				esp_cmd(esp, 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
+	 * our state.
+	 */
+	if (esp->cur_msgout[2] == EXTENDED_MESSAGE &&
+	    esp->cur_msgout[4] == EXTENDED_SDTR) {
+		esp->snip = 1; /* anal retentiveness... */
+	}
+
+	esp->prevmsgout = esp->cur_msgout[0];
+	esp->msgout_len = 0;
+	esp_advance_phase(esp->current_SC, in_the_dark);
+	return esp_do_phase_determine(esp);
+}
+
+static int esp_bus_unexpected(struct esp *esp)
+{
+	ESPLOG(("esp%d: command in weird state %2x\n",
+		esp->esp_id, esp->current_SC->SCp.phase));
+	return do_reset_bus;
+}
+
+static espfunc_t bus_vector[] = {
+	esp_do_data_finale,
+	esp_do_data_finale,
+	esp_bus_unexpected,
+	esp_do_msgin,
+	esp_do_msgincont,
+	esp_do_msgindone,
+	esp_do_msgout,
+	esp_do_msgoutdone,
+	esp_do_cmdbegin,
+	esp_do_cmddone,
+	esp_do_status,
+	esp_do_freebus,
+	esp_do_phase_determine,
+	esp_bus_unexpected,
+	esp_bus_unexpected,
+	esp_bus_unexpected,
+};
+
+/* This is the second tier in our dual-level SCSI state machine. */
+static int esp_work_bus(struct esp *esp)
+{
+	struct scsi_cmnd *SCptr = esp->current_SC;
+	unsigned int phase;
+
+	ESPBUS(("esp_work_bus: "));
+	if (!SCptr) {
+		ESPBUS(("reconnect\n"));
+		return esp_do_reconnect(esp);
+	}
+	phase = SCptr->SCp.phase;
+	if ((phase & 0xf0) == in_phases_mask)
+		return bus_vector[(phase & 0x0f)](esp);
+	else if ((phase & 0xf0) == in_slct_mask)
+		return esp_select_complete(esp);
+	else
+		return esp_bus_unexpected(esp);
+}
+
+static espfunc_t isvc_vector[] = {
+	0,
+	esp_do_phase_determine,
+	esp_do_resetbus,
+	esp_finish_reset,
+	esp_work_bus
+};
+
+/* Main interrupt handler for an esp adapter. */
+static void esp_handle(struct esp *esp)
+{
+	struct scsi_cmnd *SCptr;
+	int what_next = do_intr_end;
+
+	SCptr = esp->current_SC;
+
+	/* Check for errors. */
+	esp->sreg = sbus_readb(esp->eregs + ESP_STATUS);
+	esp->sreg &= (~ESP_STAT_INTR);
+	if (esp->erev == fashme) {
+		esp->sreg2 = sbus_readb(esp->eregs + ESP_STATUS2);
+		esp->seqreg = (sbus_readb(esp->eregs + ESP_SSTEP) & ESP_STEP_VBITS);
+	}
+
+	if (esp->sreg & (ESP_STAT_SPAM)) {
+		/* Gross error, could be due to one of:
+		 *
+		 * - top of fifo overwritten, could be because
+		 *   we tried to do a synchronous transfer with
+		 *   an offset greater than ESP fifo size
+		 *
+		 * - top of command register overwritten
+		 *
+		 * - DMA setup to go in one direction, SCSI
+		 *   bus points in the other, whoops
+		 *
+		 * - weird phase change during asynchronous
+		 *   data phase while we are initiator
+		 */
+		ESPLOG(("esp%d: Gross error sreg=%2x\n", esp->esp_id, esp->sreg));
+
+		/* If a command is live on the bus we cannot safely
+		 * reset the bus, so we'll just let the pieces fall
+		 * where they may.  Here we are hoping that the
+		 * target will be able to cleanly go away soon
+		 * so we can safely reset things.
+		 */
+		if (!SCptr) {
+			ESPLOG(("esp%d: No current cmd during gross error, "
+				"resetting bus\n", esp->esp_id));
+			what_next = do_reset_bus;
+			goto state_machine;
+		}
+	}
+
+	if (sbus_readl(esp->dregs + DMA_CSR) & 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,
+			sbus_readl(esp->dregs + DMA_CSR)));
+
+		/* DMA gate array itself must be reset to clear the
+		 * error condition.
+		 */
+		esp_reset_dma(esp);
+
+		what_next = do_reset_bus;
+		goto state_machine;
+	}
+
+	esp->ireg = sbus_readb(esp->eregs + ESP_INTRPT);   /* Unlatch intr reg */
+
+	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);
+		} 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.
+	 */
+	if (!SCptr && !esp->disconnected_SC && !(esp->ireg & ESP_INTR_SR)) {
+		/* Panic is safe, since current_SC is null. */
+		ESPLOG(("esp%d: no command in esp_handle()\n", esp->esp_id));
+		panic("esp_handle: current_SC == penguin within interrupt!");
+	}
+
+	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
+		 * ESP into an erroneous illegal command interrupt
+		 * because it does not scrape the FIFO properly
+		 * for reselection.  See esp100_reconnect_hwbug()
+		 * to see how we try very hard to avoid this.
+		 */
+		ESPLOG(("esp%d: invalid command\n", esp->esp_id));
+
+		esp_dump_state(esp);
+
+		if (SCptr != NULL) {
+			/* Devices with very buggy firmware can drop BSY
+			 * during a scatter list interrupt when using sync
+			 * mode transfers.  We continue the transfer as
+			 * expected, the target drops the bus, the ESP
+			 * gets confused, and we get a illegal command
+			 * interrupt because the bus is in the disconnected
+			 * state now and ESP_CMD_TI is only allowed when
+			 * a nexus is alive on the bus.
+			 */
+			ESPLOG(("esp%d: Forcing async and disabling disconnect for "
+				"target %d\n", esp->esp_id, SCptr->device->id));
+			SCptr->device->borken = 1; /* foo on you */
+		}
+
+		what_next = do_reset_bus;
+	} else if (!(esp->ireg & ~(ESP_INTR_FDONE | ESP_INTR_BSERV | ESP_INTR_DC))) {
+		if (SCptr) {
+			unsigned int phase = SCptr->SCp.phase;
+
+			if (phase & in_phases_mask) {
+				what_next = esp_work_bus(esp);
+			} else if (phase & in_slct_mask) {
+				what_next = esp_select_complete(esp);
+			} else {
+				ESPLOG(("esp%d: interrupt for no good reason...\n",
+					esp->esp_id));
+				what_next = do_intr_end;
+			}
+		} else {
+			ESPLOG(("esp%d: BSERV or FDONE or DC while SCptr==NULL\n",
+				esp->esp_id));
+			what_next = do_reset_bus;
+		}
+	} else if (esp->ireg & ESP_INTR_SR) {
+		ESPLOG(("esp%d: SCSI bus reset interrupt\n", esp->esp_id));
+		what_next = do_reset_complete;
+	} else if (esp->ireg & (ESP_INTR_S | ESP_INTR_SATN)) {
+		ESPLOG(("esp%d: AIEEE we have been selected by another initiator!\n",
+			esp->esp_id));
+		what_next = do_reset_bus;
+	} else if (esp->ireg & ESP_INTR_RSEL) {
+		if (SCptr == NULL) {
+			/* This is ok. */
+			what_next = esp_do_reconnect(esp);
+		} else if (SCptr->SCp.phase & in_slct_mask) {
+			/* Only selection code knows how to clean
+			 * up properly.
+			 */
+			ESPDISC(("Reselected during selection attempt\n"));
+			what_next = esp_select_complete(esp);
+		} else {
+			ESPLOG(("esp%d: Reselected while bus is busy\n",
+				esp->esp_id));
+			what_next = do_reset_bus;
+		}
+	}
+
+	/* This is tier-one in our dual level SCSI state machine. */
+state_machine:
+	while (what_next != do_intr_end) {
+		if (what_next >= do_phase_determine &&
+		    what_next < do_intr_end) {
+			what_next = isvc_vector[what_next](esp);
+		} else {
+			/* state is completely lost ;-( */
+			ESPLOG(("esp%d: interrupt engine loses state, resetting bus\n",
+				esp->esp_id));
+			what_next = do_reset_bus;
+		}
+	}
+}
+
+/* Service only the ESP described by dev_id. */
+static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
+{
+	struct esp *esp = dev_id;
+	unsigned long flags;
+
+	spin_lock_irqsave(esp->ehost->host_lock, flags);
+	if (ESP_IRQ_P(esp->dregs)) {
+		ESP_INTSOFF(esp->dregs);
+
+		ESPIRQ(("I[%d:%d](", smp_processor_id(), esp->esp_id));
+		esp_handle(esp);
+		ESPIRQ((")"));
+
+		ESP_INTSON(esp->dregs);
+	}
+	spin_unlock_irqrestore(esp->ehost->host_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static int esp_slave_alloc(struct scsi_device *SDptr)
+{
+	struct esp_device *esp_dev =
+		kmalloc(sizeof(struct esp_device), GFP_ATOMIC);
+
+	if (!esp_dev)
+		return -ENOMEM;
+	memset(esp_dev, 0, sizeof(struct esp_device));
+	SDptr->hostdata = esp_dev;
+	return 0;
+}
+
+static void esp_slave_destroy(struct scsi_device *SDptr)
+{
+	struct esp *esp = (struct esp *) SDptr->host->hostdata;
+
+	esp->targets_present &= ~(1 << SDptr->id);
+	kfree(SDptr->hostdata);
+	SDptr->hostdata = NULL;
+}
+
+static struct scsi_host_template driver_template = {
+	.proc_name		= "esp",
+	.proc_info		= esp_proc_info,
+	.name			= "Sun ESP 100/100a/200",
+	.detect			= esp_detect,
+	.slave_alloc		= esp_slave_alloc,
+	.slave_destroy		= esp_slave_destroy,
+	.release		= esp_release,
+	.info			= esp_info,
+	.queuecommand		= esp_queue,
+	.eh_abort_handler	= esp_abort,
+	.eh_bus_reset_handler	= esp_reset,
+	.can_queue		= 7,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 1,
+	.use_clustering		= ENABLE_CLUSTERING,
+};
+
+#include "scsi_module.c"
+
+MODULE_LICENSE("GPL");
+
