/* $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/blk.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/spinlock.h>

#include "scsi.h"
#include "hosts.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 <linux/module.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 spinlock_t espchain_lock = SPIN_LOCK_UNLOCKED;
static int esps_running = 0;

/* Forward declarations. */
static void 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(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
extern 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(Scsi_Cmnd **SC, Scsi_Cmnd *new_SC)
{
	Scsi_Cmnd *end;

	new_SC->host_scribble = (unsigned char *) NULL;
	if (!*SC)
		*SC = new_SC;
	else {
		for (end=*SC;end->host_scribble;end=(Scsi_Cmnd *)end->host_scribble)
			;
		end->host_scribble = (unsigned char *) new_SC;
	}
}

static inline void prepend_SC(Scsi_Cmnd **SC, Scsi_Cmnd *new_SC)
{
	new_SC->host_scribble = (unsigned char *) *SC;
	*SC = new_SC;
}

static inline Scsi_Cmnd *remove_first_SC(Scsi_Cmnd **SC)
{
	Scsi_Cmnd *ptr;
	ptr = *SC;
	if (ptr)
		*SC = (Scsi_Cmnd *) (*SC)->host_scribble;
	return ptr;
}

static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, int target, int lun)
{
	Scsi_Cmnd *ptr, *prev;

	for (ptr = *SC, prev = NULL;
	     ptr && ((ptr->target != target) || (ptr->lun != lun));
	     prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble)
		;
	if (ptr) {
		if (prev)
			prev->host_scribble=ptr->host_scribble;
		else
			*SC=(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)
{
	unsigned long flags;
	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. */

		save_flags(flags); cli(); /* I really hate this chip. */

		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);

		restore_flags(flags);
		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;

	/* 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(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>

int __init esp_detect(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 */

int __init esp_detect(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 */

/* The info function will return whatever useful
 * information the developer sees fit.  If not provided, then
 * the name field will be used instead.
 */
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 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");
	for (i = 0; i < 15; i++) {
		if (esp->targets_present & (1 << i)) {
			Scsi_Device *SDptr = esp->ehost->host_queue;

			while ((SDptr->host != esp->ehost) &&
			       (SDptr->id != i) &&
			       (SDptr->next))
				SDptr = SDptr->next;

			copy_info(&info, "%d\t\t", i);
			copy_info(&info, "%08lx\t", esp->config3[i]);
			copy_info(&info, "[%02lx,%02lx]\t\t\t", SDptr->sync_max_offset,
				  SDptr->sync_min_period);
			copy_info(&info, "%s\t\t", SDptr->disconnect ? "yes" : "no");
			copy_info(&info, "%s\n",
				  (esp->config3[i] & ESP_CONFIG3_EWIDE) ? "yes" : "no");
		}
	}
	return info.pos > info.offset? info.pos - info.offset : 0;
}

/* ESP proc filesystem code. */
int esp_proc_info(char *buffer, char **start, off_t offset, int length,
		  int hostno, int inout)
{
	struct esp *esp;

	if (inout)
		return -EINVAL; /* not yet */

	for_each_esp(esp) {
		if (esp->ehost->host_no == hostno)
			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, 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,
							       scsi_to_sbus_dma_dir(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,
						       scsi_to_sbus_dma_dir(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, Scsi_Cmnd *sp)
{
	if (sp->use_sg) {
		sbus_unmap_sg(esp->sdev, sp->buffer, sp->use_sg,
			      scsi_to_sbus_dma_dir(sp->sc_data_direction));
	} else if (sp->request_bufflen) {
		sbus_unmap_single(esp->sdev,
				  sp->SCp.have_data_in,
				  sp->request_bufflen,
				  scsi_to_sbus_dma_dir(sp->sc_data_direction));
	}
}

static void esp_restore_pointers(struct esp *esp, Scsi_Cmnd *sp)
{
	struct esp_pointers *ep = &esp->data_pointers[sp->target];

	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, Scsi_Cmnd *sp)
{
	struct esp_pointers *ep = &esp->data_pointers[sp->target];

	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, 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)
{
	Scsi_Cmnd *SCptr;
	Scsi_Device *SDptr;
	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;
	lun = SCptr->lun;
	target = SCptr->target;

	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 (SDptr->sync) {
		/* this targets sync is known */
#ifndef __sparc_v9__
do_sync_known:
#endif
		if (SDptr->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)) || !(SDptr->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->lun));
		if (!SDptr->borken && !SDptr->disconnect)
			SDptr->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... */
		SDptr->sync_max_offset = 0;
		SDptr->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))
				SDptr->disconnect = 1;
			else
				SDptr->disconnect = 0;
			SDptr->sync_max_offset = 0;
			SDptr->sync_min_period = 0;
			SDptr->sync = 1;
			esp->snip = 0;
			goto do_sync_known;
		}
#endif /* !(__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 && !SDptr->wide) {
			if (!SDptr->borken &&
			   SDptr->type != TYPE_ROM &&
			   SDptr->removable == 0) {
				build_wide_nego_msg(esp, 16);
				SDptr->wide = 1;
				esp->wnip = 1;
				goto after_nego_msg_built;
			} else {
				SDptr->wide = 1;
				/* Fall through and try sync. */
			}
		}

		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);
		}
		SDptr->sync = 1;
		esp->snip = 1;

after_nego_msg_built:
		/* A fix for broken SCSI1 targets, when they disconnect
		 * they lock up the bus and confuse ESP.  So disallow
		 * disconnects for SCSI1 targets for now until we
		 * 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 indefinately
		 *           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->target, SCptr->lun));
			SDptr->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 != SDptr->sync_max_offset ||
	    esp->prev_stp  != SDptr->sync_min_period ||
	    (esp->erev > esp100a &&
	     esp->prev_cfg3 != esp->config3[target])) {
		esp->prev_soff = SDptr->sync_max_offset;
		esp->prev_stp = SDptr->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. */
int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(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->target, SCpnt->lun));
	ESPDISC(("N<%02x,%02x>", SCpnt->target, SCpnt->lun));

	esp = (struct esp *) SCpnt->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;
}

/* Only queuing supported in this ESP driver. */
int esp_command(Scsi_Cmnd *SCpnt)
{
	struct esp *esp = (struct esp *) SCpnt->host->hostdata;

	ESPLOG(("esp%d: esp_command() called...\n", esp->esp_id));
	return -1;
}

/* Dump driver state. */
static void esp_dump_cmd(Scsi_Cmnd *SCptr)
{
	ESPLOG(("[tgt<%02x> lun<%02x> "
		"pphase<%s> cphase<%s>]",
		SCptr->target, SCptr->lun,
		phase_string(SCptr->SCp.sent_command),
		phase_string(SCptr->SCp.phase)));
}

static void esp_dump_state(struct esp *esp)
{
	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 = (Scsi_Cmnd *) SCptr->host_scribble;
	}
	ESPLOG(("\n"));
}

/* Abort a command. */
int esp_abort(Scsi_Cmnd *SCptr)
{
	struct esp *esp = (struct esp *) SCptr->host->hostdata;
	unsigned long flags;
	int don;

	spin_lock_irqsave(esp->ehost->host_lock, flags);

	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);
		spin_unlock_irqrestore(esp->ehost->host_lock, flags);
		return SCSI_ABORT_PENDING;
	}

	/* 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) {
		Scsi_Cmnd **prev, *this;
		for (prev = (&esp->issue_SC), this = esp->issue_SC;
		     this != NULL;
		     prev = (Scsi_Cmnd **) &(this->host_scribble),
			     this = (Scsi_Cmnd *) this->host_scribble) {

			if (this == SCptr) {
				*prev = (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);

				spin_unlock_irqrestore(esp->ehost->host_lock, flags);
				return SCSI_ABORT_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);
		spin_unlock_irqrestore(esp->ehost->host_lock, flags);
		return SCSI_ABORT_BUSY;
	}

	/* 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, therefore we tell the upper layer
	 * the safest thing we can.  This is, wait a bit, if nothing
	 * happens, we are really hung so reset the bus.
	 */

	if (don)
		ESP_INTSON(esp->dregs);
	spin_unlock_irqrestore(esp->ehost->host_lock, flags);
	return SCSI_ABORT_SNOOZE;
}

/* 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)
{
	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;

	/* 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.
 */
int esp_reset(Scsi_Cmnd *SCptr, unsigned int how)
{
	struct esp *esp = (struct esp *) SCptr->host->hostdata;
	unsigned long flags;

	spin_lock_irqsave(esp->ehost->host_lock, flags);
	(void) esp_do_resetbus(esp);
	spin_unlock_irqrestore(esp->ehost->host_lock, flags);

	return SCSI_RESET_PENDING;
}

/* Internal ESP done function. */
static void esp_done(struct esp *esp, int error)
{
	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, 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, 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, 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, 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, Scsi_Cmnd *sp)
{
	Scsi_Device *dp = sp->device;

	if (esp->prev_soff  != dp->sync_max_offset ||
	    esp->prev_stp   != dp->sync_min_period ||
	    (esp->erev > esp100a &&
	     esp->prev_cfg3 != esp->config3[sp->target])) {
		esp->prev_soff = dp->sync_max_offset;
		esp->prev_stp = dp->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->target];
			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, 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(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)
{
	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)
{
	Scsi_Cmnd *SCptr = esp->current_SC;
	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 (SCptr->device->sync_max_offset) {
			if (SCptr->SCp.phase == in_dataout)
				esp_cmd(esp, ESP_CMD_FLUSH);
		} else {
			esp_cmd(esp, ESP_CMD_FLUSH);
		}
	} else {
		if (SCptr->device->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->target));
		SCptr->device->borken = 1;
		SCptr->device->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(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)
{
	Scsi_Cmnd *SCptr = esp->current_SC;
	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->target) & esp->targets_present) &&
		    SCptr->device->sync &&
		    SCptr->device->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->target, SCptr->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)
				SCptr->device->sync = 0;
		}
		ESPDISC(("F<%02x,%02x>", SCptr->target, SCptr->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->target, SCptr->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)
{
	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->target, sp->lun));
		sp = (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->target, sp->lun));
	else
		ESPLOG(("<NULL>"));
	ESPLOG(("]\n"));
	sp = esp->disconnected_SC;
	ESPLOG(("esp%d: disconnected_SC[", esp->esp_id));
	while (sp) {
		ESPLOG(("<%02x,%02x>", sp->target, sp->lun));
		sp = (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;
	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->target & 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)
{
	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)
{
	Scsi_Cmnd *sp = esp->current_SC;
	Scsi_Device *dp = sp->device;

	/* 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"));
		dp->sync_max_offset = 0;
		dp->sync_min_period = 0;
		dp->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)
{
	Scsi_Cmnd *SCptr = esp->current_SC;
	Scsi_Device *SDptr = SCptr->device;
	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->target);

		/* What if the target ignores the sdtr? */
		if (esp->snip)
			SDptr->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->target));

		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... */
		    (!SDptr->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->target) & 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->target, SCptr->lun));
			SDptr->sync_max_offset = 0;
			SDptr->sync_min_period = 0;
			SDptr->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->target) & esp->targets_present)) {
			ESPLOG(("esp%d: Warning, live target %d not responding to "
				"selection.\n", esp->esp_id, SCptr->target));

			/* 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->target, SCptr->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->target));
		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) {
			Scsi_Device *SDptr = esp->current_SC->device;

			/* Doesn't look like this target can
			 * do synchronous or WIDE transfers.
			 */
			ESPSDTR(("got reject, was trying nego, clearing sync/WIDE\n"));
			SDptr->sync = 1;
			SDptr->wide = 1;
			SDptr->sync_min_period = 0;
			SDptr->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 occuring.
 */
static int target_with_ants_in_pants(struct esp *esp,
				     Scsi_Cmnd *SCptr,
				     Scsi_Device *SDptr)
{
	if (SDptr->sync || SDptr->borken) {
		/* sorry, no can do */
		ESPSDTR(("forcing to async, "));
		build_sync_nego_msg(esp, 0, 0);
		SDptr->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->target] & 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->target));
		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->target));
	}
}

static int check_multibyte_msg(struct esp *esp)
{
	Scsi_Cmnd *SCptr = esp->current_SC;
	Scsi_Device *SDptr = SCptr->device;
	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, SDptr);
			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;

			SDptr->sync_min_period = (regval & 0x1f);
			SDptr->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)
						SDptr->sync_max_offset &= ~esp->radelay;
					esp->config3[SCptr->target] |= bit;
				} else {
					esp->config3[SCptr->target] &= ~bit;
				}
				esp->prev_cfg3 = esp->config3[SCptr->target];
				sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
			}
			esp->prev_soff = SDptr->sync_max_offset;
			esp->prev_stp = SDptr->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",
				 SDptr->sync_max_offset,
				 SDptr->sync_min_period,
				 esp->config3[SCptr->target]));

			esp->snip = 0;
		} else if (SDptr->sync_max_offset) {
			u8 bit;

			/* back to async mode */
			ESPSDTR(("unaccaptable sync nego, forcing async\n"));
			SDptr->sync_max_offset = 0;
			SDptr->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->target] &= ~bit;
				esp->prev_cfg3 = esp->config3[SCptr->target];
				sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
			}
		}

		sync_report(esp);

		ESPSDTR(("chk multibyte msg: sync is known, "));
		SDptr->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->target] |= ESP_CONFIG3_EWIDE;
			} else {
				/* Just make sure it was one byte sized. */
				if (size != 8) {
					ESPLOG(("esp%d: Aieee, wide nego of %d size.\n",
						esp->esp_id, size));
					message_out = MESSAGE_REJECT;
					goto finish;
				}
				/* Pure paranoia. */
				esp->config3[SCptr->target] &= ~(ESP_CONFIG3_EWIDE);
			}
			esp->prev_cfg3 = esp->config3[SCptr->target];
			sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);

			/* Regardless, next try for sync transfers. */
			build_sync_nego_msg(esp, esp->sync_defp, 15);
			SDptr->sync = 1;
			esp->snip = 1;
			message_out = EXTENDED_MESSAGE;
		}
	} 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)
{
	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)
{
	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) &&
			    !(esp->current_SC->device->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)
{
	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)
{
	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: illegal 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->target));
			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 void 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);
}

int esp_revoke(Scsi_Device* SDptr)
{
	struct esp *esp = (struct esp *) SDptr->host->hostdata;
	esp->targets_present &= ~(1 << SDptr->id);
	return 0;
}

static Scsi_Host_Template driver_template = SCSI_SPARC_ESP;

#include "scsi_module.c"

