/* esp.c: ESP Sun SCSI driver.
 *
 * Copyright (C) 1995, 1998, 2006 David S. Miller (davem@davemloft.net)
 */

/* 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/kernel.h>
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/module.h>

#include "esp.h"

#include <asm/sbus.h>
#include <asm/dma.h>
#include <asm/system.h>
#include <asm/ptrace.h>
#include <asm/pgtable.h>
#include <asm/oplib.h>
#include <asm/io.h>
#include <asm/irq.h>
#ifndef __sparc_v9__
#include <asm/machines.h>
#include <asm/idprom.h>
#endif

#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>

#define DRV_VERSION "1.101"

#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
};

/* Forward declarations. */
static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs);

/* Debugging routines */
struct esp_cmdstrings {
	u8 cmdchar;
	char *text;
} esp_cmd_strings[] = {
	/* Miscellaneous */
	{ ESP_CMD_NULL, "ESP_NOP", },
	{ ESP_CMD_FLUSH, "FIFO_FLUSH", },
	{ ESP_CMD_RC, "RSTESP", },
	{ ESP_CMD_RS, "RSTSCSI", },
	/* Disconnected State Group */
	{ ESP_CMD_RSEL, "RESLCTSEQ", },
	{ ESP_CMD_SEL, "SLCTNATN", },
	{ ESP_CMD_SELA, "SLCTATN", },
	{ ESP_CMD_SELAS, "SLCTATNSTOP", },
	{ ESP_CMD_ESEL, "ENSLCTRESEL", },
	{ ESP_CMD_DSEL, "DISSELRESEL", },
	{ ESP_CMD_SA3, "SLCTATN3", },
	{ ESP_CMD_RSEL3, "RESLCTSEQ", },
	/* Target State Group */
	{ ESP_CMD_SMSG, "SNDMSG", },
	{ ESP_CMD_SSTAT, "SNDSTATUS", },
	{ ESP_CMD_SDATA, "SNDDATA", },
	{ ESP_CMD_DSEQ, "DISCSEQ", },
	{ ESP_CMD_TSEQ, "TERMSEQ", },
	{ ESP_CMD_TCCSEQ, "TRGTCMDCOMPSEQ", },
	{ ESP_CMD_DCNCT, "DISC", },
	{ ESP_CMD_RMSG, "RCVMSG", },
	{ ESP_CMD_RCMD, "RCVCMD", },
	{ ESP_CMD_RDATA, "RCVDATA", },
	{ ESP_CMD_RCSEQ, "RCVCMDSEQ", },
	/* Initiator State Group */
	{ ESP_CMD_TI, "TRANSINFO", },
	{ ESP_CMD_ICCSEQ, "INICMDSEQCOMP", },
	{ ESP_CMD_MOK, "MSGACCEPTED", },
	{ ESP_CMD_TPAD, "TPAD", },
	{ ESP_CMD_SATN, "SATN", },
	{ ESP_CMD_RATN, "RATN", },
};
#define NUM_ESP_COMMANDS  ((sizeof(esp_cmd_strings)) / (sizeof(struct esp_cmdstrings)))

/* Print textual representation of an ESP command */
static inline void esp_print_cmd(u8 espcmd)
{
	u8 dma_bit = espcmd & ESP_CMD_DMA;
	int i;

	espcmd &= ~dma_bit;
	for (i = 0; i < NUM_ESP_COMMANDS; i++)
		if (esp_cmd_strings[i].cmdchar == espcmd)
			break;
	if (i == NUM_ESP_COMMANDS)
		printk("ESP_Unknown");
	else
		printk("%s%s", esp_cmd_strings[i].text,
		       ((dma_bit) ? "+DMA" : ""));
}

/* Print the status register's value */
static inline void esp_print_statreg(u8 statreg)
{
	u8 phase;

	printk("STATUS<");
	phase = statreg & ESP_STAT_PMASK;
	printk("%s,", (phase == ESP_DOP ? "DATA-OUT" :
		       (phase == ESP_DIP ? "DATA-IN" :
			(phase == ESP_CMDP ? "COMMAND" :
			 (phase == ESP_STATP ? "STATUS" :
			  (phase == ESP_MOP ? "MSG-OUT" :
			   (phase == ESP_MIP ? "MSG_IN" :
			    "unknown")))))));
	if (statreg & ESP_STAT_TDONE)
		printk("TRANS_DONE,");
	if (statreg & ESP_STAT_TCNT)
		printk("TCOUNT_ZERO,");
	if (statreg & ESP_STAT_PERR)
		printk("P_ERROR,");
	if (statreg & ESP_STAT_SPAM)
		printk("SPAM,");
	if (statreg & ESP_STAT_INTR)
		printk("IRQ,");
	printk(">");
}

/* Print the interrupt register's value */
static inline void esp_print_ireg(u8 intreg)
{
	printk("INTREG< ");
	if (intreg & ESP_INTR_S)
		printk("SLCT_NATN ");
	if (intreg & ESP_INTR_SATN)
		printk("SLCT_ATN ");
	if (intreg & ESP_INTR_RSEL)
		printk("RSLCT ");
	if (intreg & ESP_INTR_FDONE)
		printk("FDONE ");
	if (intreg & ESP_INTR_BSERV)
		printk("BSERV ");
	if (intreg & ESP_INTR_DC)
		printk("DISCNCT ");
	if (intreg & ESP_INTR_IC)
		printk("ILL_CMD ");
	if (intreg & ESP_INTR_SR)
		printk("SCSI_BUS_RESET ");
	printk(">");
}

/* Print the sequence step registers contents */
static inline void esp_print_seqreg(u8 stepreg)
{
	stepreg &= ESP_STEP_VBITS;
	printk("STEP<%s>",
	       (stepreg == ESP_STEP_ASEL ? "SLCT_ARB_CMPLT" :
		(stepreg == ESP_STEP_SID ? "1BYTE_MSG_SENT" :
		 (stepreg == ESP_STEP_NCMD ? "NOT_IN_CMD_PHASE" :
		  (stepreg == ESP_STEP_PPC ? "CMD_BYTES_LOST" :
		   (stepreg == ESP_STEP_FINI4 ? "CMD_SENT_OK" :
		    "UNKNOWN"))))));
}

static char *phase_string(int phase)
{
	switch (phase) {
	case not_issued:
		return "UNISSUED";
	case in_slct_norm:
		return "SLCTNORM";
	case in_slct_stop:
		return "SLCTSTOP";
	case in_slct_msg:
		return "SLCTMSG";
	case in_slct_tag:
		return "SLCTTAG";
	case in_slct_sneg:
		return "SLCTSNEG";
	case in_datain:
		return "DATAIN";
	case in_dataout:
		return "DATAOUT";
	case in_data_done:
		return "DATADONE";
	case in_msgin:
		return "MSGIN";
	case in_msgincont:
		return "MSGINCONT";
	case in_msgindone:
		return "MSGINDONE";
	case in_msgout:
		return "MSGOUT";
	case in_msgoutdone:
		return "MSGOUTDONE";
	case in_cmdbegin:
		return "CMDBEGIN";
	case in_cmdend:
		return "CMDEND";
	case in_status:
		return "STATUS";
	case in_freeing:
		return "FREEING";
	case in_the_dark:
		return "CLUELESS";
	case in_abortone:
		return "ABORTONE";
	case in_abortall:
		return "ABORTALL";
	case in_resetdev:
		return "RESETDEV";
	case in_resetbus:
		return "RESETBUS";
	case in_tgterror:
		return "TGTERROR";
	default:
		return "UNKNOWN";
	};
}

#ifdef DEBUG_STATE_MACHINE
static inline void esp_advance_phase(struct scsi_cmnd *s, int newphase)
{
	ESPLOG(("<%s>", phase_string(newphase)));
	s->SCp.sent_command = s->SCp.phase;
	s->SCp.phase = newphase;
}
#else
#define esp_advance_phase(__s, __newphase) \
	(__s)->SCp.sent_command = (__s)->SCp.phase; \
	(__s)->SCp.phase = (__newphase);
#endif

#ifdef DEBUG_ESP_CMDS
static inline void esp_cmd(struct esp *esp, u8 cmd)
{
	esp->espcmdlog[esp->espcmdent] = cmd;
	esp->espcmdent = (esp->espcmdent + 1) & 31;
	sbus_writeb(cmd, esp->eregs + ESP_CMD);
}
#else
#define esp_cmd(__esp, __cmd)	\
	sbus_writeb((__cmd), ((__esp)->eregs) + ESP_CMD)
#endif

#define ESP_INTSOFF(__dregs)	\
	sbus_writel(sbus_readl((__dregs)+DMA_CSR)&~(DMA_INT_ENAB), (__dregs)+DMA_CSR)
#define ESP_INTSON(__dregs)	\
	sbus_writel(sbus_readl((__dregs)+DMA_CSR)|DMA_INT_ENAB, (__dregs)+DMA_CSR)
#define ESP_IRQ_P(__dregs)	\
	(sbus_readl((__dregs)+DMA_CSR) & (DMA_HNDL_INTR|DMA_HNDL_ERROR))

/* How we use the various Linux SCSI data structures for operation.
 *
 * struct scsi_cmnd:
 *
 *   We keep track of the synchronous capabilities of a target
 *   in the device member, using sync_min_period and
 *   sync_max_offset.  These are the values we directly write
 *   into the ESP registers while running a command.  If offset
 *   is zero the ESP will use asynchronous transfers.
 *   If the borken flag is set we assume we shouldn't even bother
 *   trying to negotiate for synchronous transfer as this target
 *   is really stupid.  If we notice the target is dropping the
 *   bus, and we have been allowing it to disconnect, we clear
 *   the disconnect flag.
 */


/* Manipulation of the ESP command queues.  Thanks to the aha152x driver
 * and its author, Juergen E. Fischer, for the methods used here.
 * Note that these are per-ESP queues, not global queues like
 * the aha152x driver uses.
 */
static inline void append_SC(struct scsi_cmnd **SC, struct scsi_cmnd *new_SC)
{
	struct scsi_cmnd *end;

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

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

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

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

	for (ptr = *SC, prev = NULL;
	     ptr && ((ptr->device->id != target) || (ptr->device->lun != lun));
	     prev = ptr, ptr = (struct scsi_cmnd *) ptr->host_scribble)
		;
	if (ptr) {
		if (prev)
			prev->host_scribble=ptr->host_scribble;
		else
			*SC=(struct scsi_cmnd *)ptr->host_scribble;
	}
	return ptr;
}

/* Resetting various pieces of the ESP scsi driver chipset/buses. */
static void esp_reset_dma(struct esp *esp)
{
	int can_do_burst16, can_do_burst32, can_do_burst64;
	int can_do_sbus64;
	u32 tmp;

	can_do_burst16 = (esp->bursts & DMA_BURST16) != 0;
	can_do_burst32 = (esp->bursts & DMA_BURST32) != 0;
	can_do_burst64 = 0;
	can_do_sbus64 = 0;
	if (sbus_can_dma_64bit(esp->sdev))
		can_do_sbus64 = 1;
	if (sbus_can_burst64(esp->sdev))
		can_do_burst64 = (esp->bursts & DMA_BURST64) != 0;

	/* Punt the DVMA into a known state. */
	if (esp->dma->revision != dvmahme) {
		tmp = sbus_readl(esp->dregs + DMA_CSR);
		sbus_writel(tmp | DMA_RST_SCSI, esp->dregs + DMA_CSR);
		sbus_writel(tmp & ~DMA_RST_SCSI, esp->dregs + DMA_CSR);
	}
	switch (esp->dma->revision) {
	case dvmahme:
		/* This is the HME DVMA gate array. */

		sbus_writel(DMA_RESET_FAS366, esp->dregs + DMA_CSR);
		sbus_writel(DMA_RST_SCSI, esp->dregs + DMA_CSR);

		esp->prev_hme_dmacsr = (DMA_PARITY_OFF|DMA_2CLKS|DMA_SCSI_DISAB|DMA_INT_ENAB);
		esp->prev_hme_dmacsr &= ~(DMA_ENABLE|DMA_ST_WRITE|DMA_BRST_SZ);

		if (can_do_burst64)
			esp->prev_hme_dmacsr |= DMA_BRST64;
		else if (can_do_burst32)
			esp->prev_hme_dmacsr |= DMA_BRST32;

		if (can_do_sbus64) {
			esp->prev_hme_dmacsr |= DMA_SCSI_SBUS64;
			sbus_set_sbus64(esp->sdev, esp->bursts);
		}

		/* This chip is horrible. */
		while (sbus_readl(esp->dregs + DMA_CSR) & DMA_PEND_READ)
			udelay(1);

		sbus_writel(0, esp->dregs + DMA_CSR);
		sbus_writel(esp->prev_hme_dmacsr, esp->dregs + DMA_CSR);

		/* This is necessary to avoid having the SCSI channel
		 * engine lock up on us.
		 */
		sbus_writel(0, esp->dregs + DMA_ADDR);

		break;
	case dvmarev2:
		/* This is the gate array found in the sun4m
		 * NCR SBUS I/O subsystem.
		 */
		if (esp->erev != esp100) {
			tmp = sbus_readl(esp->dregs + DMA_CSR);
			sbus_writel(tmp | DMA_3CLKS, esp->dregs + DMA_CSR);
		}
		break;
	case dvmarev3:
		tmp = sbus_readl(esp->dregs + DMA_CSR);
		tmp &= ~DMA_3CLKS;
		tmp |= DMA_2CLKS;
		if (can_do_burst32) {
			tmp &= ~DMA_BRST_SZ;
			tmp |= DMA_BRST32;
		}
		sbus_writel(tmp, esp->dregs + DMA_CSR);
		break;
	case dvmaesc1:
		/* This is the DMA unit found on SCSI/Ether cards. */
		tmp = sbus_readl(esp->dregs + DMA_CSR);
		tmp |= DMA_ADD_ENABLE;
		tmp &= ~DMA_BCNT_ENAB;
		if (!can_do_burst32 && can_do_burst16) {
			tmp |= DMA_ESC_BURST;
		} else {
			tmp &= ~(DMA_ESC_BURST);
		}
		sbus_writel(tmp, esp->dregs + DMA_CSR);
		break;
	default:
		break;
	};
	ESP_INTSON(esp->dregs);
}

/* Reset the ESP chip, _not_ the SCSI bus. */
static void __init esp_reset_esp(struct esp *esp)
{
	u8 family_code, version;
	int i;

	/* Now reset the ESP chip */
	esp_cmd(esp, ESP_CMD_RC);
	esp_cmd(esp, ESP_CMD_NULL | ESP_CMD_DMA);
	esp_cmd(esp, ESP_CMD_NULL | ESP_CMD_DMA);

	/* Reload the configuration registers */
	sbus_writeb(esp->cfact, esp->eregs + ESP_CFACT);
	esp->prev_stp = 0;
	sbus_writeb(esp->prev_stp, esp->eregs + ESP_STP);
	esp->prev_soff = 0;
	sbus_writeb(esp->prev_soff, esp->eregs + ESP_SOFF);
	sbus_writeb(esp->neg_defp, esp->eregs + ESP_TIMEO);

	/* This is the only point at which it is reliable to read
	 * the ID-code for a fast ESP chip variants.
	 */
	esp->max_period = ((35 * esp->ccycle) / 1000);
	if (esp->erev == fast) {
		version = sbus_readb(esp->eregs + ESP_UID);
		family_code = (version & 0xf8) >> 3;
		if (family_code == 0x02)
			esp->erev = fas236;
		else if (family_code == 0x0a)
			esp->erev = fashme; /* Version is usually '5'. */
		else
			esp->erev = fas100a;
		ESPMISC(("esp%d: FAST chip is %s (family=%d, version=%d)\n",
			 esp->esp_id,
			 (esp->erev == fas236) ? "fas236" :
			 ((esp->erev == fas100a) ? "fas100a" :
			  "fasHME"), family_code, (version & 7)));

		esp->min_period = ((4 * esp->ccycle) / 1000);
	} else {
		esp->min_period = ((5 * esp->ccycle) / 1000);
	}
	esp->max_period = (esp->max_period + 3)>>2;
	esp->min_period = (esp->min_period + 3)>>2;

	sbus_writeb(esp->config1, esp->eregs + ESP_CFG1);
	switch (esp->erev) {
	case esp100:
		/* nothing to do */
		break;
	case esp100a:
		sbus_writeb(esp->config2, esp->eregs + ESP_CFG2);
		break;
	case esp236:
		/* Slow 236 */
		sbus_writeb(esp->config2, esp->eregs + ESP_CFG2);
		esp->prev_cfg3 = esp->config3[0];
		sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
		break;
	case fashme:
		esp->config2 |= (ESP_CONFIG2_HME32 | ESP_CONFIG2_HMEFENAB);
		/* fallthrough... */
	case fas236:
		/* Fast 236 or HME */
		sbus_writeb(esp->config2, esp->eregs + ESP_CFG2);
		for (i = 0; i < 16; i++) {
			if (esp->erev == fashme) {
				u8 cfg3;

				cfg3 = ESP_CONFIG3_FCLOCK | ESP_CONFIG3_OBPUSH;
				if (esp->scsi_id >= 8)
					cfg3 |= ESP_CONFIG3_IDBIT3;
				esp->config3[i] |= cfg3;
			} else {
				esp->config3[i] |= ESP_CONFIG3_FCLK;
			}
		}
		esp->prev_cfg3 = esp->config3[0];
		sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
		if (esp->erev == fashme) {
			esp->radelay = 80;
		} else {
			if (esp->diff)
				esp->radelay = 0;
			else
				esp->radelay = 96;
		}
		break;
	case fas100a:
		/* Fast 100a */
		sbus_writeb(esp->config2, esp->eregs + ESP_CFG2);
		for (i = 0; i < 16; i++)
			esp->config3[i] |= ESP_CONFIG3_FCLOCK;
		esp->prev_cfg3 = esp->config3[0];
		sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
		esp->radelay = 32;
		break;
	default:
		panic("esp: what could it be... I wonder...");
		break;
	};

	/* Eat any bitrot in the chip */
	sbus_readb(esp->eregs + ESP_INTRPT);
	udelay(100);
}

/* This places the ESP into a known state at boot time. */
static void __init esp_bootup_reset(struct esp *esp)
{
	u8 tmp;

	/* Reset the DMA */
	esp_reset_dma(esp);

	/* Reset the ESP */
	esp_reset_esp(esp);

	/* Reset the SCSI bus, but tell ESP not to generate an irq */
	tmp = sbus_readb(esp->eregs + ESP_CFG1);
	tmp |= ESP_CONFIG1_SRRDISAB;
	sbus_writeb(tmp, esp->eregs + ESP_CFG1);

	esp_cmd(esp, ESP_CMD_RS);
	udelay(400);

	sbus_writeb(esp->config1, esp->eregs + ESP_CFG1);

	/* Eat any bitrot in the chip and we are done... */
	sbus_readb(esp->eregs + ESP_INTRPT);
}

static 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,
			IRQF_SHARED, "ESP SCSI", esp)) {
		printk("esp%d: Cannot acquire irq line\n",
		       esp->esp_id);
		return -1;
	}

	printk("esp%d: IRQ %d ", esp->esp_id,
	       esp->ehost->irq);

	return 0;
}

static void __init esp_get_scsi_id(struct esp *esp)
{
	struct sbus_dev *sdev = esp->sdev;
	struct device_node *dp = sdev->ofdev.node;

	esp->scsi_id = of_getintprop_default(dp,
					     "initiator-id",
					     -1);
	if (esp->scsi_id == -1)
		esp->scsi_id = of_getintprop_default(dp,
						     "scsi-initiator-id",
						     -1);
	if (esp->scsi_id == -1)
		esp->scsi_id = (sdev->bus == NULL) ? 7 :
			of_getintprop_default(sdev->bus->ofdev.node,
					      "scsi-initiator-id",
					      7);
	esp->ehost->this_id = esp->scsi_id;
	esp->scsi_id_mask = (1 << esp->scsi_id);

}

static void __init esp_get_clock_params(struct esp *esp)
{
	struct sbus_dev *sdev = esp->sdev;
	int prom_node = esp->prom_node;
	int sbus_prom_node;
	unsigned int fmhz;
	u8 ccf;

	if (sdev != NULL && sdev->bus != NULL)
		sbus_prom_node = sdev->bus->prom_node;
	else
		sbus_prom_node = 0;

	/* This is getting messy but it has to be done
	 * correctly or else you get weird behavior all
	 * over the place.  We are trying to basically
	 * figure out three pieces of information.
	 *
	 * a) Clock Conversion Factor
	 *
	 *    This is a representation of the input
	 *    crystal clock frequency going into the
	 *    ESP on this machine.  Any operation whose
	 *    timing is longer than 400ns depends on this
	 *    value being correct.  For example, you'll
	 *    get blips for arbitration/selection during
	 *    high load or with multiple targets if this
	 *    is not set correctly.
	 *
	 * b) Selection Time-Out
	 *
	 *    The ESP isn't very bright and will arbitrate
	 *    for the bus and try to select a target
	 *    forever if you let it.  This value tells
	 *    the ESP when it has taken too long to
	 *    negotiate and that it should interrupt
	 *    the CPU so we can see what happened.
	 *    The value is computed as follows (from
	 *    NCR/Symbios chip docs).
	 *
	 *          (Time Out Period) *  (Input Clock)
	 *    STO = ----------------------------------
	 *          (8192) * (Clock Conversion Factor)
	 *
	 *    You usually want the time out period to be
	 *    around 250ms, I think we'll set it a little
	 *    bit higher to account for fully loaded SCSI
	 *    bus's and slow devices that don't respond so
	 *    quickly to selection attempts. (yeah, I know
	 *    this is out of spec. but there is a lot of
	 *    buggy pieces of firmware out there so bite me)
	 *
	 * c) Imperical constants for synchronous offset
	 *    and transfer period register values
	 *
	 *    This entails the smallest and largest sync
	 *    period we could ever handle on this ESP.
	 */

	fmhz = prom_getintdefault(prom_node, "clock-frequency", -1);
	if (fmhz == -1)
		fmhz = (!sbus_prom_node) ? 0 :
			prom_getintdefault(sbus_prom_node, "clock-frequency", -1);

	if (fmhz <= (5000000))
		ccf = 0;
	else
		ccf = (((5000000 - 1) + (fmhz))/(5000000));

	if (!ccf || ccf > 8) {
		/* If we can't find anything reasonable,
		 * just assume 20MHZ.  This is the clock
		 * frequency of the older sun4c's where I've
		 * been unable to find the clock-frequency
		 * PROM property.  All other machines provide
		 * useful values it seems.
		 */
		ccf = ESP_CCF_F4;
		fmhz = (20000000);
	}

	if (ccf == (ESP_CCF_F7 + 1))
		esp->cfact = ESP_CCF_F0;
	else if (ccf == ESP_CCF_NEVER)
		esp->cfact = ESP_CCF_F2;
	else
		esp->cfact = ccf;
	esp->raw_cfact = ccf;

	esp->cfreq = fmhz;
	esp->ccycle = ESP_MHZ_TO_CYCLE(fmhz);
	esp->ctick = ESP_TICK(ccf, esp->ccycle);
	esp->neg_defp = ESP_NEG_DEFP(fmhz, ccf);
	esp->sync_defp = SYNC_DEFP_SLOW;

	printk("SCSI ID %d Clk %dMHz CCYC=%d CCF=%d TOut %d ",
	       esp->scsi_id, (fmhz / 1000000),
	       (int)esp->ccycle, (int)ccf, (int) esp->neg_defp);
}

static void __init esp_get_bursts(struct esp *esp, struct sbus_dev *dma)
{
	struct sbus_dev *sdev = esp->sdev;
	u8 bursts;

	bursts = prom_getintdefault(esp->prom_node, "burst-sizes", 0xff);

	if (dma) {
		u8 tmp = prom_getintdefault(dma->prom_node,
					    "burst-sizes", 0xff);
		if (tmp != 0xff)
			bursts &= tmp;
	}

	if (sdev->bus) {
		u8 tmp = prom_getintdefault(sdev->bus->prom_node,
					    "burst-sizes", 0xff);
		if (tmp != 0xff)
			bursts &= tmp;
	}

	if (bursts == 0xff ||
	    (bursts & DMA_BURST16) == 0 ||
	    (bursts & DMA_BURST32) == 0)
		bursts = (DMA_BURST32 - 1);

	esp->bursts = bursts;
}

static void __init esp_get_revision(struct esp *esp)
{
	u8 tmp;

	esp->config1 = (ESP_CONFIG1_PENABLE | (esp->scsi_id & 7));
	esp->config2 = (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY);
	sbus_writeb(esp->config2, esp->eregs + ESP_CFG2);

	tmp = sbus_readb(esp->eregs + ESP_CFG2);
	tmp &= ~ESP_CONFIG2_MAGIC;
	if (tmp != (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY)) {
		/* If what we write to cfg2 does not come back, cfg2
		 * is not implemented, therefore this must be a plain
		 * esp100.
		 */
		esp->erev = esp100;
		printk("NCR53C90(esp100)\n");
	} else {
		esp->config2 = 0;
		esp->prev_cfg3 = esp->config3[0] = 5;
		sbus_writeb(esp->config2, esp->eregs + ESP_CFG2);
		sbus_writeb(0, esp->eregs + ESP_CFG3);
		sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);

		tmp = sbus_readb(esp->eregs + ESP_CFG3);
		if (tmp != 5) {
			/* The cfg2 register is implemented, however
			 * cfg3 is not, must be esp100a.
			 */
			esp->erev = esp100a;
			printk("NCR53C90A(esp100a)\n");
		} else {
			int target;

			for (target = 0; target < 16; target++)
				esp->config3[target] = 0;
			esp->prev_cfg3 = 0;
			sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);

			/* All of cfg{1,2,3} implemented, must be one of
			 * the fas variants, figure out which one.
			 */
			if (esp->raw_cfact > ESP_CCF_F5) {
				esp->erev = fast;
				esp->sync_defp = SYNC_DEFP_FAST;
				printk("NCR53C9XF(espfast)\n");
			} else {
				esp->erev = esp236;
				printk("NCR53C9x(esp236)\n");
			}
			esp->config2 = 0;
			sbus_writeb(esp->config2, esp->eregs + ESP_CFG2);
		}
	}
}

static void __init esp_init_swstate(struct esp *esp)
{
	int i;

	/* Command queues... */
	esp->current_SC = NULL;
	esp->disconnected_SC = NULL;
	esp->issue_SC = NULL;

	/* Target and current command state... */
	esp->targets_present = 0;
	esp->resetting_bus = 0;
	esp->snip = 0;

	init_waitqueue_head(&esp->reset_queue);

	/* Debugging... */
	for(i = 0; i < 32; i++)
		esp->espcmdlog[i] = 0;
	esp->espcmdent = 0;

	/* MSG phase state... */
	for(i = 0; i < 16; i++) {
		esp->cur_msgout[i] = 0;
		esp->cur_msgin[i] = 0;
	}
	esp->prevmsgout = esp->prevmsgin = 0;
	esp->msgout_len = esp->msgin_len = 0;

	/* Clear the one behind caches to hold unmatchable values. */
	esp->prev_soff = esp->prev_stp = esp->prev_cfg3 = 0xff;
	esp->prev_hme_dmacsr = 0xffffffff;
}

static int __init detect_one_esp(struct scsi_host_template *tpnt,
				 struct device *dev,
				 struct sbus_dev *esp_dev,
				 struct sbus_dev *espdma,
				 struct sbus_bus *sbus,
				 int hme)
{
	static int instance;
	struct Scsi_Host *esp_host = scsi_host_alloc(tpnt, sizeof(struct esp));
	struct esp *esp;
	
	if (!esp_host)
		return -ENOMEM;

	if (hme)
		esp_host->max_id = 16;
	esp = (struct esp *) esp_host->hostdata;
	esp->ehost = esp_host;
	esp->sdev = esp_dev;
	esp->esp_id = instance;
	esp->prom_node = esp_dev->prom_node;
	prom_getstring(esp->prom_node, "name", esp->prom_name,
		       sizeof(esp->prom_name));

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

	if (scsi_add_host(esp_host, dev))
		goto fail_free_irq;

	dev_set_drvdata(&esp_dev->ofdev.dev, esp);

	scsi_scan_host(esp_host);
	instance++;

	return 0;

fail_free_irq:
	free_irq(esp->ehost->irq, esp);

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:
	scsi_host_put(esp_host);
	return -1;
}

/* Detecting ESP chips on the machine.  This is the simple and easy
 * version.
 */
static int __devexit esp_remove_common(struct esp *esp)
{
	unsigned int irq = esp->ehost->irq;

	scsi_remove_host(esp->ehost);

	ESP_INTSOFF(esp->dregs);
#if 0
	esp_reset_dma(esp);
	esp_reset_esp(esp);
#endif

	free_irq(irq, esp);
	sbus_free_consistent(esp->sdev, 16,
			     (void *) esp->esp_command, esp->esp_command_dvma);
	sbus_iounmap(esp->eregs, ESP_REG_SIZE);
	esp->dma->allocated = 0;

	scsi_host_put(esp->ehost);

	return 0;
}


#ifdef CONFIG_SUN4

#include <asm/sun4paddr.h>

static struct sbus_dev sun4_esp_dev;

static int __init esp_sun4_probe(struct scsi_host_template *tpnt)
{
	if (sun4_esp_physaddr) {
		memset(&sun4_esp_dev, 0, sizeof(esp_dev));
		sun4_esp_dev.reg_addrs[0].phys_addr = sun4_esp_physaddr;
		sun4_esp_dev.irqs[0] = 4;
		sun4_esp_dev.resource[0].start = sun4_esp_physaddr;
		sun4_esp_dev.resource[0].end =
			sun4_esp_physaddr + ESP_REG_SIZE - 1;
		sun4_esp_dev.resource[0].flags = IORESOURCE_IO;

		return detect_one_esp(tpnt, NULL,
				      &sun4_esp_dev, NULL, NULL, 0);
	}
	return 0;
}

static int __devexit esp_sun4_remove(void)
{
	struct esp *esp = dev_get_drvdata(&dev->dev);

	return esp_remove_common(esp);
}

#else /* !CONFIG_SUN4 */

static int __devinit esp_sbus_probe(struct of_device *dev, const struct of_device_id *match)
{
	struct sbus_dev *sdev = to_sbus_device(&dev->dev);
	struct device_node *dp = dev->node;
	struct sbus_dev *dma_sdev = NULL;
	int hme = 0;

	if (dp->parent &&
	    (!strcmp(dp->parent->name, "espdma") ||
	     !strcmp(dp->parent->name, "dma")))
		dma_sdev = sdev->parent;
	else if (!strcmp(dp->name, "SUNW,fas")) {
		dma_sdev = sdev;
		hme = 1;
	}

	return detect_one_esp(match->data, &dev->dev,
			      sdev, dma_sdev, sdev->bus, hme);
}

static int __devexit esp_sbus_remove(struct of_device *dev)
{
	struct esp *esp = dev_get_drvdata(&dev->dev);

	return esp_remove_common(esp);
}

#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.
 */
static const char *esp_info(struct Scsi_Host *host)
{
	struct esp *esp;

	esp = (struct esp *) host->hostdata;
	switch (esp->erev) {
	case esp100:
		return "Sparc ESP100 (NCR53C90)";
	case esp100a:
		return "Sparc ESP100A (NCR53C90A)";
	case esp236:
		return "Sparc ESP236";
	case fas236:
		return "Sparc ESP236-FAST";
	case fashme:
		return "Sparc ESP366-HME";
	case fas100a:
		return "Sparc ESP100A-FAST";
	default:
		return "Bogon ESP revision";
	};
}

/* From Wolfgang Stanglmeier's NCR scsi driver. */
struct info_str
{
	char *buffer;
	int length;
	int offset;
	int pos;
};

static void copy_mem_info(struct info_str *info, char *data, int len)
{
	if (info->pos + len > info->length)
		len = info->length - info->pos;

	if (info->pos + len < info->offset) {
		info->pos += len;
		return;
	}
	if (info->pos < info->offset) {
		data += (info->offset - info->pos);
		len  -= (info->offset - info->pos);
	}

	if (len > 0) {
		memcpy(info->buffer + info->pos, data, len);
		info->pos += len;
	}
}

static int copy_info(struct info_str *info, char *fmt, ...)
{
	va_list args;
	char buf[81];
	int len;

	va_start(args, fmt);
	len = vsprintf(buf, fmt, args);
	va_end(args);

	copy_mem_info(info, buf, len);
	return len;
}

static int esp_host_info(struct esp *esp, char *ptr, off_t offset, int len)
{
	struct scsi_device *sdev;
	struct info_str info;
	int i;

	info.buffer	= ptr;
	info.length	= len;
	info.offset	= offset;
	info.pos	= 0;

	copy_info(&info, "Sparc ESP Host Adapter:\n");
	copy_info(&info, "\tPROM node\t\t%08x\n", (unsigned int) esp->prom_node);
	copy_info(&info, "\tPROM name\t\t%s\n", esp->prom_name);
	copy_info(&info, "\tESP Model\t\t");
	switch (esp->erev) {
	case esp100:
		copy_info(&info, "ESP100\n");
		break;
	case esp100a:
		copy_info(&info, "ESP100A\n");
		break;
	case esp236:
		copy_info(&info, "ESP236\n");
		break;
	case fas236:
		copy_info(&info, "FAS236\n");
		break;
	case fas100a:
		copy_info(&info, "FAS100A\n");
		break;
	case fast:
		copy_info(&info, "FAST\n");
		break;
	case fashme:
		copy_info(&info, "Happy Meal FAS\n");
		break;
	case espunknown:
	default:
		copy_info(&info, "Unknown!\n");
		break;
	};
	copy_info(&info, "\tDMA Revision\t\t");
	switch (esp->dma->revision) {
	case dvmarev0:
		copy_info(&info, "Rev 0\n");
		break;
	case dvmaesc1:
		copy_info(&info, "ESC Rev 1\n");
		break;
	case dvmarev1:
		copy_info(&info, "Rev 1\n");
		break;
	case dvmarev2:
		copy_info(&info, "Rev 2\n");
		break;
	case dvmarev3:
		copy_info(&info, "Rev 3\n");
		break;
	case dvmarevplus:
		copy_info(&info, "Rev 1+\n");
		break;
	case dvmahme:
		copy_info(&info, "Rev HME/FAS\n");
		break;
	default:
		copy_info(&info, "Unknown!\n");
		break;
	};
	copy_info(&info, "\tLive Targets\t\t[ ");
	for (i = 0; i < 15; i++) {
		if (esp->targets_present & (1 << i))
			copy_info(&info, "%d ", i);
	}
	copy_info(&info, "]\n\n");
	
	/* Now describe the state of each existing target. */
	copy_info(&info, "Target #\tconfig3\t\tSync Capabilities\tDisconnect\tWide\n");

	shost_for_each_device(sdev, esp->ehost) {
		struct esp_device *esp_dev = sdev->hostdata;
		uint id = sdev->id;

		if (!(esp->targets_present & (1 << id)))
			continue;

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

/* ESP proc filesystem code. */
static int esp_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
			 int length, int inout)
{
	struct esp *esp = (struct esp *) host->hostdata;

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

	if (start)
		*start = buffer;

	return esp_host_info(esp, buffer, offset, length);
}

static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
{
	if (sp->use_sg == 0) {
		sp->SCp.this_residual = sp->request_bufflen;
		sp->SCp.buffer = (struct scatterlist *) sp->request_buffer;
		sp->SCp.buffers_residual = 0;
		if (sp->request_bufflen) {
			sp->SCp.have_data_in = sbus_map_single(esp->sdev, sp->SCp.buffer,
							       sp->SCp.this_residual,
							       sp->sc_data_direction);
			sp->SCp.ptr = (char *) ((unsigned long)sp->SCp.have_data_in);
		} else {
			sp->SCp.ptr = NULL;
		}
	} else {
		sp->SCp.buffer = (struct scatterlist *) sp->buffer;
		sp->SCp.buffers_residual = sbus_map_sg(esp->sdev,
						       sp->SCp.buffer,
						       sp->use_sg,
						       sp->sc_data_direction);
		sp->SCp.this_residual = sg_dma_len(sp->SCp.buffer);
		sp->SCp.ptr = (char *) ((unsigned long)sg_dma_address(sp->SCp.buffer));
	}
}

static void esp_release_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
{
	if (sp->use_sg) {
		sbus_unmap_sg(esp->sdev, sp->buffer, sp->use_sg,
			      sp->sc_data_direction);
	} else if (sp->request_bufflen) {
		sbus_unmap_single(esp->sdev,
				  sp->SCp.have_data_in,
				  sp->request_bufflen,
				  sp->sc_data_direction);
	}
}

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

	sp->SCp.ptr = ep->saved_ptr;
	sp->SCp.buffer = ep->saved_buffer;
	sp->SCp.this_residual = ep->saved_this_residual;
	sp->SCp.buffers_residual = ep->saved_buffers_residual;
}

static void esp_save_pointers(struct esp *esp, struct scsi_cmnd *sp)
{
	struct esp_pointers *ep = &esp->data_pointers[sp->device->id];

	ep->saved_ptr = sp->SCp.ptr;
	ep->saved_buffer = sp->SCp.buffer;
	ep->saved_this_residual = sp->SCp.this_residual;
	ep->saved_buffers_residual = sp->SCp.buffers_residual;
}

/* Some rules:
 *
 *   1) Never ever panic while something is live on the bus.
 *      If there is to be any chance of syncing the disks this
 *      rule is to be obeyed.
 *
 *   2) Any target that causes a foul condition will no longer
 *      have synchronous transfers done to it, no questions
 *      asked.
 *
 *   3) Keep register accesses to a minimum.  Think about some
 *      day when we have Xbus machines this is running on and
 *      the ESP chip is on the other end of the machine on a
 *      different board from the cpu where this is running.
 */

/* Fire off a command.  We assume the bus is free and that the only
 * case where we could see an interrupt is where we have disconnected
 * commands active and they are trying to reselect us.
 */
static inline void esp_check_cmd(struct esp *esp, struct scsi_cmnd *sp)
{
	switch (sp->cmd_len) {
	case 6:
	case 10:
	case 12:
		esp->esp_slowcmd = 0;
		break;

	default:
		esp->esp_slowcmd = 1;
		esp->esp_scmdleft = sp->cmd_len;
		esp->esp_scmdp = &sp->cmnd[0];
		break;
	};
}

static inline void build_sync_nego_msg(struct esp *esp, int period, int offset)
{
	esp->cur_msgout[0] = EXTENDED_MESSAGE;
	esp->cur_msgout[1] = 3;
	esp->cur_msgout[2] = EXTENDED_SDTR;
	esp->cur_msgout[3] = period;
	esp->cur_msgout[4] = offset;
	esp->msgout_len = 5;
}

/* SIZE is in bits, currently HME only supports 16 bit wide transfers. */
static inline void build_wide_nego_msg(struct esp *esp, int size)
{
	esp->cur_msgout[0] = EXTENDED_MESSAGE;
	esp->cur_msgout[1] = 2;
	esp->cur_msgout[2] = EXTENDED_WDTR;
	switch (size) {
	case 32:
		esp->cur_msgout[3] = 2;
		break;
	case 16:
		esp->cur_msgout[3] = 1;
		break;
	case 8:
	default:
		esp->cur_msgout[3] = 0;
		break;
	};

	esp->msgout_len = 4;
}

static void esp_exec_cmd(struct esp *esp)
{
	struct scsi_cmnd *SCptr;
	struct scsi_device *SDptr;
	struct esp_device *esp_dev;
	volatile u8 *cmdp = esp->esp_command;
	u8 the_esp_command;
	int lun, target;
	int i;

	/* Hold off if we have disconnected commands and
	 * an IRQ is showing...
	 */
	if (esp->disconnected_SC && ESP_IRQ_P(esp->dregs))
		return;

	/* Grab first member of the issue queue. */
	SCptr = esp->current_SC = remove_first_SC(&esp->issue_SC);

	/* Safe to panic here because current_SC is null. */
	if (!SCptr)
		panic("esp: esp_exec_cmd and issue queue is NULL");

	SDptr = SCptr->device;
	esp_dev = SDptr->hostdata;
	lun = SCptr->device->lun;
	target = SCptr->device->id;

	esp->snip = 0;
	esp->msgout_len = 0;

	/* Send it out whole, or piece by piece?   The ESP
	 * only knows how to automatically send out 6, 10,
	 * and 12 byte commands.  I used to think that the
	 * Linux SCSI code would never throw anything other
	 * than that to us, but then again there is the
	 * SCSI generic driver which can send us anything.
	 */
	esp_check_cmd(esp, SCptr);

	/* If arbitration/selection is successful, the ESP will leave
	 * ATN asserted, causing the target to go into message out
	 * phase.  The ESP will feed the target the identify and then
	 * the target can only legally go to one of command,
	 * datain/out, status, or message in phase, or stay in message
	 * out phase (should we be trying to send a sync negotiation
	 * message after the identify).  It is not allowed to drop
	 * BSY, but some buggy targets do and we check for this
	 * condition in the selection complete code.  Most of the time
	 * we'll make the command bytes available to the ESP and it
	 * will not interrupt us until it finishes command phase, we
	 * cannot do this for command sizes the ESP does not
	 * understand and in this case we'll get interrupted right
	 * when the target goes into command phase.
	 *
	 * It is absolutely _illegal_ in the presence of SCSI-2 devices
	 * to use the ESP select w/o ATN command.  When SCSI-2 devices are
	 * present on the bus we _must_ always go straight to message out
	 * phase with an identify message for the target.  Being that
	 * selection attempts in SCSI-1 w/o ATN was an option, doing SCSI-2
	 * selections should not confuse SCSI-1 we hope.
	 */

	if (esp_dev->sync) {
		/* this targets sync is known */
#ifndef __sparc_v9__
do_sync_known:
#endif
		if (esp_dev->disconnect)
			*cmdp++ = IDENTIFY(1, lun);
		else
			*cmdp++ = IDENTIFY(0, lun);

		if (esp->esp_slowcmd) {
			the_esp_command = (ESP_CMD_SELAS | ESP_CMD_DMA);
			esp_advance_phase(SCptr, in_slct_stop);
		} else {
			the_esp_command = (ESP_CMD_SELA | ESP_CMD_DMA);
			esp_advance_phase(SCptr, in_slct_norm);
		}
	} else if (!(esp->targets_present & (1<<target)) || !(esp_dev->disconnect)) {
		/* After the bootup SCSI code sends both the
		 * TEST_UNIT_READY and INQUIRY commands we want
		 * to at least attempt allowing the device to
		 * disconnect.
		 */
		ESPMISC(("esp: Selecting device for first time. target=%d "
			 "lun=%d\n", target, SCptr->device->lun));
		if (!SDptr->borken && !esp_dev->disconnect)
			esp_dev->disconnect = 1;

		*cmdp++ = IDENTIFY(0, lun);
		esp->prevmsgout = NOP;
		esp_advance_phase(SCptr, in_slct_norm);
		the_esp_command = (ESP_CMD_SELA | ESP_CMD_DMA);

		/* Take no chances... */
		esp_dev->sync_max_offset = 0;
		esp_dev->sync_min_period = 0;
	} else {
		/* Sorry, I have had way too many problems with
		 * various CDROM devices on ESP. -DaveM
		 */
		int cdrom_hwbug_wkaround = 0;

#ifndef __sparc_v9__
		/* Never allow disconnects or synchronous transfers on
		 * SparcStation1 and SparcStation1+.  Allowing those
		 * to be enabled seems to lockup the machine completely.
		 */
		if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) ||
		    (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) {
			/* But we are nice and allow tapes and removable
			 * disks (but not CDROMs) to disconnect.
			 */
			if(SDptr->type == TYPE_TAPE ||
			   (SDptr->type != TYPE_ROM && SDptr->removable))
				esp_dev->disconnect = 1;
			else
				esp_dev->disconnect = 0;
			esp_dev->sync_max_offset = 0;
			esp_dev->sync_min_period = 0;
			esp_dev->sync = 1;
			esp->snip = 0;
			goto do_sync_known;
		}
#endif /* !(__sparc_v9__) */

		/* We've talked to this guy before,
		 * but never negotiated.  Let's try,
		 * need to attempt WIDE first, before
		 * sync nego, as per SCSI 2 standard.
		 */
		if (esp->erev == fashme && !esp_dev->wide) {
			if (!SDptr->borken &&
			   SDptr->type != TYPE_ROM &&
			   SDptr->removable == 0) {
				build_wide_nego_msg(esp, 16);
				esp_dev->wide = 1;
				esp->wnip = 1;
				goto after_nego_msg_built;
			} else {
				esp_dev->wide = 1;
				/* Fall through and try sync. */
			}
		}

		if (!SDptr->borken) {
			if ((SDptr->type == TYPE_ROM)) {
				/* Nice try sucker... */
				ESPMISC(("esp%d: Disabling sync for buggy "
					 "CDROM.\n", esp->esp_id));
				cdrom_hwbug_wkaround = 1;
				build_sync_nego_msg(esp, 0, 0);
			} else if (SDptr->removable != 0) {
				ESPMISC(("esp%d: Not negotiating sync/wide but "
					 "allowing disconnect for removable media.\n",
					 esp->esp_id));
				build_sync_nego_msg(esp, 0, 0);
			} else {
				build_sync_nego_msg(esp, esp->sync_defp, 15);
			}
		} else {
			build_sync_nego_msg(esp, 0, 0);
		}
		esp_dev->sync = 1;
		esp->snip = 1;

after_nego_msg_built:
		/* A fix for broken SCSI1 targets, when they disconnect
		 * they lock up the bus and confuse ESP.  So disallow
		 * disconnects for SCSI1 targets for now until we
		 * find a better fix.
		 *
		 * Addendum: This is funny, I figured out what was going
		 *           on.  The blotzed SCSI1 target would disconnect,
		 *           one of the other SCSI2 targets or both would be
		 *           disconnected as well.  The SCSI1 target would
		 *           stay disconnected long enough that we start
		 *           up a command on one of the SCSI2 targets.  As
		 *           the ESP is arbitrating for the bus the SCSI1
		 *           target begins to arbitrate as well to reselect
		 *           the ESP.  The SCSI1 target refuses to drop it's
		 *           ID bit on the data bus even though the ESP is
		 *           at ID 7 and is the obvious winner for any
		 *           arbitration.  The ESP is a poor sport and refuses
		 *           to lose arbitration, it will continue indefinitely
		 *           trying to arbitrate for the bus and can only be
		 *           stopped via a chip reset or SCSI bus reset.
		 *           Therefore _no_ disconnects for SCSI1 targets
		 *           thank you very much. ;-)
		 */
		if(((SDptr->scsi_level < 3) &&
		    (SDptr->type != TYPE_TAPE) &&
		    SDptr->removable == 0) ||
		    cdrom_hwbug_wkaround || SDptr->borken) {
			ESPMISC((KERN_INFO "esp%d: Disabling DISCONNECT for target %d "
				 "lun %d\n", esp->esp_id, SCptr->device->id, SCptr->device->lun));
			esp_dev->disconnect = 0;
			*cmdp++ = IDENTIFY(0, lun);
		} else {
			*cmdp++ = IDENTIFY(1, lun);
		}

		/* ESP fifo is only so big...
		 * Make this look like a slow command.
		 */
		esp->esp_slowcmd = 1;
		esp->esp_scmdleft = SCptr->cmd_len;
		esp->esp_scmdp = &SCptr->cmnd[0];

		the_esp_command = (ESP_CMD_SELAS | ESP_CMD_DMA);
		esp_advance_phase(SCptr, in_slct_msg);
	}

	if (!esp->esp_slowcmd)
		for (i = 0; i < SCptr->cmd_len; i++)
			*cmdp++ = SCptr->cmnd[i];

	/* HME sucks... */
	if (esp->erev == fashme)
		sbus_writeb((target & 0xf) | (ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT),
			    esp->eregs + ESP_BUSID);
	else
		sbus_writeb(target & 7, esp->eregs + ESP_BUSID);
	if (esp->prev_soff != esp_dev->sync_max_offset ||
	    esp->prev_stp  != esp_dev->sync_min_period ||
	    (esp->erev > esp100a &&
	     esp->prev_cfg3 != esp->config3[target])) {
		esp->prev_soff = esp_dev->sync_max_offset;
		esp->prev_stp = esp_dev->sync_min_period;
		sbus_writeb(esp->prev_soff, esp->eregs + ESP_SOFF);
		sbus_writeb(esp->prev_stp, esp->eregs + ESP_STP);
		if (esp->erev > esp100a) {
			esp->prev_cfg3 = esp->config3[target];
			sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
		}
	}
	i = (cmdp - esp->esp_command);

	if (esp->erev == fashme) {
		esp_cmd(esp, ESP_CMD_FLUSH); /* Grrr! */

		/* Set up the DMA and HME counters */
		sbus_writeb(i, esp->eregs + ESP_TCLOW);
		sbus_writeb(0, esp->eregs + ESP_TCMED);
		sbus_writeb(0, esp->eregs + FAS_RLO);
		sbus_writeb(0, esp->eregs + FAS_RHI);
		esp_cmd(esp, the_esp_command);

		/* Talk about touchy hardware... */
		esp->prev_hme_dmacsr = ((esp->prev_hme_dmacsr |
					 (DMA_SCSI_DISAB | DMA_ENABLE)) &
					~(DMA_ST_WRITE));
		sbus_writel(16, esp->dregs + DMA_COUNT);
		sbus_writel(esp->esp_command_dvma, esp->dregs + DMA_ADDR);
		sbus_writel(esp->prev_hme_dmacsr, esp->dregs + DMA_CSR);
	} else {
		u32 tmp;

		/* Set up the DMA and ESP counters */
		sbus_writeb(i, esp->eregs + ESP_TCLOW);
		sbus_writeb(0, esp->eregs + ESP_TCMED);
		tmp = sbus_readl(esp->dregs + DMA_CSR);
		tmp &= ~DMA_ST_WRITE;
		tmp |= DMA_ENABLE;
		sbus_writel(tmp, esp->dregs + DMA_CSR);
		if (esp->dma->revision == dvmaesc1) {
			if (i) /* Workaround ESC gate array SBUS rerun bug. */
				sbus_writel(PAGE_SIZE, esp->dregs + DMA_COUNT);
		}
		sbus_writel(esp->esp_command_dvma, esp->dregs + DMA_ADDR);

		/* Tell ESP to "go". */
		esp_cmd(esp, the_esp_command);
	}
}

/* Queue a SCSI command delivered from the mid-level Linux SCSI code. */
static int esp_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
{
	struct esp *esp;

	/* Set up func ptr and initial driver cmd-phase. */
	SCpnt->scsi_done = done;
	SCpnt->SCp.phase = not_issued;

	/* We use the scratch area. */
	ESPQUEUE(("esp_queue: target=%d lun=%d ", SCpnt->device->id, SCpnt->device->lun));
	ESPDISC(("N<%02x,%02x>", SCpnt->device->id, SCpnt->device->lun));

	esp = (struct esp *) SCpnt->device->host->hostdata;
	esp_get_dmabufs(esp, SCpnt);
	esp_save_pointers(esp, SCpnt); /* FIXME for tag queueing */

	SCpnt->SCp.Status           = CHECK_CONDITION;
	SCpnt->SCp.Message          = 0xff;
	SCpnt->SCp.sent_command     = 0;

	/* Place into our queue. */
	if (SCpnt->cmnd[0] == REQUEST_SENSE) {
		ESPQUEUE(("RQSENSE\n"));
		prepend_SC(&esp->issue_SC, SCpnt);
	} else {
		ESPQUEUE(("\n"));
		append_SC(&esp->issue_SC, SCpnt);
	}

	/* Run it now if we can. */
	if (!esp->current_SC && !esp->resetting_bus)
		esp_exec_cmd(esp);

	return 0;
}

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

static void esp_dump_state(struct esp *esp)
{
	struct scsi_cmnd *SCptr = esp->current_SC;
#ifdef DEBUG_ESP_CMDS
	int i;
#endif

	ESPLOG(("esp%d: dumping state\n", esp->esp_id));
	ESPLOG(("esp%d: dma -- cond_reg<%08x> addr<%08x>\n",
		esp->esp_id,
		sbus_readl(esp->dregs + DMA_CSR),
		sbus_readl(esp->dregs + DMA_ADDR)));
	ESPLOG(("esp%d: SW [sreg<%02x> sstep<%02x> ireg<%02x>]\n",
		esp->esp_id, esp->sreg, esp->seqreg, esp->ireg));
	ESPLOG(("esp%d: HW reread [sreg<%02x> sstep<%02x> ireg<%02x>]\n",
		esp->esp_id,
		sbus_readb(esp->eregs + ESP_STATUS),
		sbus_readb(esp->eregs + ESP_SSTEP),
		sbus_readb(esp->eregs + ESP_INTRPT)));
#ifdef DEBUG_ESP_CMDS
	printk("esp%d: last ESP cmds [", esp->esp_id);
	i = (esp->espcmdent - 1) & 31;
	printk("<"); esp_print_cmd(esp->espcmdlog[i]); printk(">");
	i = (i - 1) & 31;
	printk("<"); esp_print_cmd(esp->espcmdlog[i]); printk(">");
	i = (i - 1) & 31;
	printk("<"); esp_print_cmd(esp->espcmdlog[i]); printk(">");
	i = (i - 1) & 31;
	printk("<"); esp_print_cmd(esp->espcmdlog[i]); printk(">");
	printk("]\n");
#endif /* (DEBUG_ESP_CMDS) */

	if (SCptr) {
		ESPLOG(("esp%d: current command ", esp->esp_id));
		esp_dump_cmd(SCptr);
	}
	ESPLOG(("\n"));
	SCptr = esp->disconnected_SC;
	ESPLOG(("esp%d: disconnected ", esp->esp_id));
	while (SCptr) {
		esp_dump_cmd(SCptr);
		SCptr = (struct scsi_cmnd *) SCptr->host_scribble;
	}
	ESPLOG(("\n"));
}

/* Abort a command.  The host_lock is acquired by caller. */
static int esp_abort(struct scsi_cmnd *SCptr)
{
	struct esp *esp = (struct esp *) SCptr->device->host->hostdata;
	int don;

	ESPLOG(("esp%d: Aborting command\n", esp->esp_id));
	esp_dump_state(esp);

	/* Wheee, if this is the current command on the bus, the
	 * best we can do is assert ATN and wait for msgout phase.
	 * This should even fix a hung SCSI bus when we lose state
	 * in the driver and timeout because the eventual phase change
	 * will cause the ESP to (eventually) give an interrupt.
	 */
	if (esp->current_SC == SCptr) {
		esp->cur_msgout[0] = ABORT;
		esp->msgout_len = 1;
		esp->msgout_ctr = 0;
		esp_cmd(esp, ESP_CMD_SATN);
		return SUCCESS;
	}

	/* If it is still in the issue queue then we can safely
	 * call the completion routine and report abort success.
	 */
	don = (sbus_readl(esp->dregs + DMA_CSR) & DMA_INT_ENAB);
	if (don) {
		ESP_INTSOFF(esp->dregs);
	}
	if (esp->issue_SC) {
		struct scsi_cmnd **prev, *this;
		for (prev = (&esp->issue_SC), this = esp->issue_SC;
		     this != NULL;
		     prev = (struct scsi_cmnd **) &(this->host_scribble),
			     this = (struct scsi_cmnd *) this->host_scribble) {

			if (this == SCptr) {
				*prev = (struct scsi_cmnd *) this->host_scribble;
				this->host_scribble = NULL;

				esp_release_dmabufs(esp, this);
				this->result = DID_ABORT << 16;
				this->scsi_done(this);

				if (don)
					ESP_INTSON(esp->dregs);

				return SUCCESS;
			}
		}
	}

	/* Yuck, the command to abort is disconnected, it is not
	 * worth trying to abort it now if something else is live
	 * on the bus at this time.  So, we let the SCSI code wait
	 * a little bit and try again later.
	 */
	if (esp->current_SC) {
		if (don)
			ESP_INTSON(esp->dregs);
		return FAILED;
	}

	/* It's disconnected, we have to reconnect to re-establish
	 * the nexus and tell the device to abort.  However, we really
	 * cannot 'reconnect' per se.  Don't try to be fancy, just
	 * indicate failure, which causes our caller to reset the whole
	 * bus.
	 */

	if (don)
		ESP_INTSON(esp->dregs);

	return FAILED;
}

/* We've sent ESP_CMD_RS to the ESP, the interrupt had just
 * arrived indicating the end of the SCSI bus reset.  Our job
 * is to clean out the command queues and begin re-execution
 * of SCSI commands once more.
 */
static int esp_finish_reset(struct esp *esp)
{
	struct scsi_cmnd *sp = esp->current_SC;

	/* Clean up currently executing command, if any. */
	if (sp != NULL) {
		esp->current_SC = NULL;

		esp_release_dmabufs(esp, sp);
		sp->result = (DID_RESET << 16);

		sp->scsi_done(sp);
	}

	/* Clean up disconnected queue, they have been invalidated
	 * by the bus reset.
	 */
	if (esp->disconnected_SC) {
		while ((sp = remove_first_SC(&esp->disconnected_SC)) != NULL) {
			esp_release_dmabufs(esp, sp);
			sp->result = (DID_RESET << 16);

			sp->scsi_done(sp);
		}
	}

	/* SCSI bus reset is complete. */
	esp->resetting_bus = 0;
	wake_up(&esp->reset_queue);

	/* Ok, now it is safe to get commands going once more. */
	if (esp->issue_SC)
		esp_exec_cmd(esp);

	return do_intr_end;
}

static int esp_do_resetbus(struct esp *esp)
{
	ESPLOG(("esp%d: Resetting scsi bus\n", esp->esp_id));
	esp->resetting_bus = 1;
	esp_cmd(esp, ESP_CMD_RS);

	return do_intr_end;
}

/* Reset ESP chip, reset hanging bus, then kill active and
 * disconnected commands for targets without soft reset.
 *
 * The host_lock is acquired by caller.
 */
static int esp_reset(struct scsi_cmnd *SCptr)
{
	struct esp *esp = (struct esp *) SCptr->device->host->hostdata;

	spin_lock_irq(esp->ehost->host_lock);
	(void) esp_do_resetbus(esp);
	spin_unlock_irq(esp->ehost->host_lock);

	wait_event(esp->reset_queue, (esp->resetting_bus == 0));

	return SUCCESS;
}

/* Internal ESP done function. */
static void esp_done(struct esp *esp, int error)
{
	struct scsi_cmnd *done_SC = esp->current_SC;

	esp->current_SC = NULL;

	esp_release_dmabufs(esp, done_SC);
	done_SC->result = error;

	done_SC->scsi_done(done_SC);

	/* Bus is free, issue any commands in the queue. */
	if (esp->issue_SC && !esp->current_SC)
		esp_exec_cmd(esp);

}

/* Wheee, ESP interrupt engine. */  

/* Forward declarations. */
static int esp_do_phase_determine(struct esp *esp);
static int esp_do_data_finale(struct esp *esp);
static int esp_select_complete(struct esp *esp);
static int esp_do_status(struct esp *esp);
static int esp_do_msgin(struct esp *esp);
static int esp_do_msgindone(struct esp *esp);
static int esp_do_msgout(struct esp *esp);
static int esp_do_cmdbegin(struct esp *esp);

#define sreg_datainp(__sreg)  (((__sreg) & ESP_STAT_PMASK) == ESP_DIP)
#define sreg_dataoutp(__sreg) (((__sreg) & ESP_STAT_PMASK) == ESP_DOP)

/* Read any bytes found in the FAS366 fifo, storing them into
 * the ESP driver software state structure.
 */
static void hme_fifo_read(struct esp *esp)
{
	u8 count = 0;
	u8 status = esp->sreg;

	/* Cannot safely frob the fifo for these following cases, but
	 * we must always read the fifo when the reselect interrupt
	 * is pending.
	 */
	if (((esp->ireg & ESP_INTR_RSEL) == 0)	&&
	    (sreg_datainp(status)		||
	     sreg_dataoutp(status)		||
	     (esp->current_SC &&
	      esp->current_SC->SCp.phase == in_data_done))) {
		ESPHME(("<wkaround_skipped>"));
	} else {
		unsigned long fcnt = sbus_readb(esp->eregs + ESP_FFLAGS) & ESP_FF_FBYTES;

		/* The HME stores bytes in multiples of 2 in the fifo. */
		ESPHME(("hme_fifo[fcnt=%d", (int)fcnt));
		while (fcnt) {
			esp->hme_fifo_workaround_buffer[count++] =
				sbus_readb(esp->eregs + ESP_FDATA);
			esp->hme_fifo_workaround_buffer[count++] =
				sbus_readb(esp->eregs + ESP_FDATA);
			ESPHME(("<%02x,%02x>", esp->hme_fifo_workaround_buffer[count-2], esp->hme_fifo_workaround_buffer[count-1]));
			fcnt--;
		}
		if (sbus_readb(esp->eregs + ESP_STATUS2) & ESP_STAT2_F1BYTE) {
			ESPHME(("<poke_byte>"));
			sbus_writeb(0, esp->eregs + ESP_FDATA);
			esp->hme_fifo_workaround_buffer[count++] =
				sbus_readb(esp->eregs + ESP_FDATA);
			ESPHME(("<%02x,0x00>", esp->hme_fifo_workaround_buffer[count-1]));
			ESPHME(("CMD_FLUSH"));
			esp_cmd(esp, ESP_CMD_FLUSH);
		} else {
			ESPHME(("no_xtra_byte"));
		}
	}
	ESPHME(("wkarnd_cnt=%d]", (int)count));
	esp->hme_fifo_workaround_count = count;
}

static inline void hme_fifo_push(struct esp *esp, u8 *bytes, u8 count)
{
	esp_cmd(esp, ESP_CMD_FLUSH);
	while (count) {
		u8 tmp = *bytes++;
		sbus_writeb(tmp, esp->eregs + ESP_FDATA);
		sbus_writeb(0, esp->eregs + ESP_FDATA);
		count--;
	}
}

/* We try to avoid some interrupts by jumping ahead and see if the ESP
 * has gotten far enough yet.  Hence the following.
 */
static inline int skipahead1(struct esp *esp, struct scsi_cmnd *scp,
			     int prev_phase, int new_phase)
{
	if (scp->SCp.sent_command != prev_phase)
		return 0;
	if (ESP_IRQ_P(esp->dregs)) {
		/* Yes, we are able to save an interrupt. */
		if (esp->erev == fashme)
			esp->sreg2 = sbus_readb(esp->eregs + ESP_STATUS2);
		esp->sreg = (sbus_readb(esp->eregs + ESP_STATUS) & ~(ESP_STAT_INTR));
		esp->ireg = sbus_readb(esp->eregs + ESP_INTRPT);
		if (esp->erev == fashme) {
			/* This chip is really losing. */
			ESPHME(("HME["));
			/* Must latch fifo before reading the interrupt
			 * register else garbage ends up in the FIFO
			 * which confuses the driver utterly.
			 * Happy Meal indeed....
			 */
			ESPHME(("fifo_workaround]"));
			if (!(esp->sreg2 & ESP_STAT2_FEMPTY) ||
			    (esp->sreg2 & ESP_STAT2_F1BYTE))
				hme_fifo_read(esp);
		}
		if (!(esp->ireg & ESP_INTR_SR))
			return 0;
		else
			return do_reset_complete;
	}
	/* Ho hum, target is taking forever... */
	scp->SCp.sent_command = new_phase; /* so we don't recurse... */
	return do_intr_end;
}

static inline int skipahead2(struct esp *esp, struct scsi_cmnd *scp,
			     int prev_phase1, int prev_phase2, int new_phase)
{
	if (scp->SCp.sent_command != prev_phase1 &&
	    scp->SCp.sent_command != prev_phase2)
		return 0;
	if (ESP_IRQ_P(esp->dregs)) {
		/* Yes, we are able to save an interrupt. */
		if (esp->erev == fashme)
			esp->sreg2 = sbus_readb(esp->eregs + ESP_STATUS2);
		esp->sreg = (sbus_readb(esp->eregs + ESP_STATUS) & ~(ESP_STAT_INTR));
		esp->ireg = sbus_readb(esp->eregs + ESP_INTRPT);
		if (esp->erev == fashme) {
			/* This chip is really losing. */
			ESPHME(("HME["));

			/* Must latch fifo before reading the interrupt
			 * register else garbage ends up in the FIFO
			 * which confuses the driver utterly.
			 * Happy Meal indeed....
			 */
			ESPHME(("fifo_workaround]"));
			if (!(esp->sreg2 & ESP_STAT2_FEMPTY) ||
			    (esp->sreg2 & ESP_STAT2_F1BYTE))
				hme_fifo_read(esp);
		}
		if (!(esp->ireg & ESP_INTR_SR))
			return 0;
		else
			return do_reset_complete;
	}
	/* Ho hum, target is taking forever... */
	scp->SCp.sent_command = new_phase; /* so we don't recurse... */
	return do_intr_end;
}

/* Now some dma helpers. */
static void dma_setup(struct esp *esp, __u32 addr, int count, int write)
{
	u32 nreg = sbus_readl(esp->dregs + DMA_CSR);

	if (write)
		nreg |= DMA_ST_WRITE;
	else
		nreg &= ~(DMA_ST_WRITE);
	nreg |= DMA_ENABLE;
	sbus_writel(nreg, esp->dregs + DMA_CSR);
	if (esp->dma->revision == dvmaesc1) {
		/* This ESC gate array sucks! */
		__u32 src = addr;
		__u32 dest = src + count;

		if (dest & (PAGE_SIZE - 1))
			count = PAGE_ALIGN(count);
		sbus_writel(count, esp->dregs + DMA_COUNT);
	}
	sbus_writel(addr, esp->dregs + DMA_ADDR);
}

static void dma_drain(struct esp *esp)
{
	u32 tmp;

	if (esp->dma->revision == dvmahme)
		return;
	if ((tmp = sbus_readl(esp->dregs + DMA_CSR)) & DMA_FIFO_ISDRAIN) {
		switch (esp->dma->revision) {
		default:
			tmp |= DMA_FIFO_STDRAIN;
			sbus_writel(tmp, esp->dregs + DMA_CSR);

		case dvmarev3:
		case dvmaesc1:
			while (sbus_readl(esp->dregs + DMA_CSR) & DMA_FIFO_ISDRAIN)
				udelay(1);
		};
	}
}

static void dma_invalidate(struct esp *esp)
{
	u32 tmp;

	if (esp->dma->revision == dvmahme) {
		sbus_writel(DMA_RST_SCSI, esp->dregs + DMA_CSR);

		esp->prev_hme_dmacsr = ((esp->prev_hme_dmacsr |
					 (DMA_PARITY_OFF | DMA_2CLKS |
					  DMA_SCSI_DISAB | DMA_INT_ENAB)) &
					~(DMA_ST_WRITE | DMA_ENABLE));

		sbus_writel(0, esp->dregs + DMA_CSR);
		sbus_writel(esp->prev_hme_dmacsr, esp->dregs + DMA_CSR);

		/* This is necessary to avoid having the SCSI channel
		 * engine lock up on us.
		 */
		sbus_writel(0, esp->dregs + DMA_ADDR);
	} else {
		while ((tmp = sbus_readl(esp->dregs + DMA_CSR)) & DMA_PEND_READ)
			udelay(1);

		tmp &= ~(DMA_ENABLE | DMA_ST_WRITE | DMA_BCNT_ENAB);
		tmp |= DMA_FIFO_INV;
		sbus_writel(tmp, esp->dregs + DMA_CSR);
		tmp &= ~DMA_FIFO_INV;
		sbus_writel(tmp, esp->dregs + DMA_CSR);
	}
}

static inline void dma_flashclear(struct esp *esp)
{
	dma_drain(esp);
	dma_invalidate(esp);
}

static int dma_can_transfer(struct esp *esp, struct scsi_cmnd *sp)
{
	__u32 base, end, sz;

	if (esp->dma->revision == dvmarev3) {
		sz = sp->SCp.this_residual;
		if (sz > 0x1000000)
			sz = 0x1000000;
	} else {
		base = ((__u32)((unsigned long)sp->SCp.ptr));
		base &= (0x1000000 - 1);
		end = (base + sp->SCp.this_residual);
		if (end > 0x1000000)
			end = 0x1000000;
		sz = (end - base);
	}
	return sz;
}

/* Misc. esp helper macros. */
#define esp_setcount(__eregs, __cnt, __hme) \
	sbus_writeb(((__cnt)&0xff), (__eregs) + ESP_TCLOW); \
	sbus_writeb((((__cnt)>>8)&0xff), (__eregs) + ESP_TCMED); \
	if (__hme) { \
		sbus_writeb((((__cnt)>>16)&0xff), (__eregs) + FAS_RLO); \
		sbus_writeb(0, (__eregs) + FAS_RHI); \
	}

#define esp_getcount(__eregs, __hme) \
	((sbus_readb((__eregs) + ESP_TCLOW)&0xff) | \
	 ((sbus_readb((__eregs) + ESP_TCMED)&0xff) << 8) | \
         ((__hme) ? sbus_readb((__eregs) + FAS_RLO) << 16 : 0))

#define fcount(__esp) \
	(((__esp)->erev == fashme) ? \
	  (__esp)->hme_fifo_workaround_count : \
	  sbus_readb(((__esp)->eregs) + ESP_FFLAGS) & ESP_FF_FBYTES)

#define fnzero(__esp) \
	(((__esp)->erev == fashme) ? 0 : \
	 sbus_readb(((__esp)->eregs) + ESP_FFLAGS) & ESP_FF_ONOTZERO)

/* XXX speculative nops unnecessary when continuing amidst a data phase
 * XXX even on esp100!!!  another case of flooding the bus with I/O reg
 * XXX writes...
 */
#define esp_maybe_nop(__esp) \
	if ((__esp)->erev == esp100) \
		esp_cmd((__esp), ESP_CMD_NULL)

#define sreg_to_dataphase(__sreg) \
	((((__sreg) & ESP_STAT_PMASK) == ESP_DOP) ? in_dataout : in_datain)

/* The ESP100 when in synchronous data phase, can mistake a long final
 * REQ pulse from the target as an extra byte, it places whatever is on
 * the data lines into the fifo.  For now, we will assume when this
 * happens that the target is a bit quirky and we don't want to
 * be talking synchronously to it anyways.  Regardless, we need to
 * tell the ESP to eat the extraneous byte so that we can proceed
 * to the next phase.
 */
static int esp100_sync_hwbug(struct esp *esp, struct scsi_cmnd *sp, int fifocnt)
{
	/* Do not touch this piece of code. */
	if ((!(esp->erev == esp100)) ||
	    (!(sreg_datainp((esp->sreg = sbus_readb(esp->eregs + ESP_STATUS))) &&
	       !fifocnt) &&
	     !(sreg_dataoutp(esp->sreg) && !fnzero(esp)))) {
		if (sp->SCp.phase == in_dataout)
			esp_cmd(esp, ESP_CMD_FLUSH);
		return 0;
	} else {
		/* Async mode for this guy. */
		build_sync_nego_msg(esp, 0, 0);

		/* Ack the bogus byte, but set ATN first. */
		esp_cmd(esp, ESP_CMD_SATN);
		esp_cmd(esp, ESP_CMD_MOK);
		return 1;
	}
}

/* This closes the window during a selection with a reselect pending, because
 * we use DMA for the selection process the FIFO should hold the correct
 * contents if we get reselected during this process.  So we just need to
 * ack the possible illegal cmd interrupt pending on the esp100.
 */
static inline int esp100_reconnect_hwbug(struct esp *esp)
{
	u8 tmp;

	if (esp->erev != esp100)
		return 0;
	tmp = sbus_readb(esp->eregs + ESP_INTRPT);
	if (tmp & ESP_INTR_SR)
		return 1;
	return 0;
}

/* This verifies the BUSID bits during a reselection so that we know which
 * target is talking to us.
 */
static inline int reconnect_target(struct esp *esp)
{
	int it, me = esp->scsi_id_mask, targ = 0;

	if (2 != fcount(esp))
		return -1;
	if (esp->erev == fashme) {
		/* HME does not latch it's own BUS ID bits during
		 * a reselection.  Also the target number is given
		 * as an unsigned char, not as a sole bit number
		 * like the other ESP's do.
		 * Happy Meal indeed....
		 */
		targ = esp->hme_fifo_workaround_buffer[0];
	} else {
		it = sbus_readb(esp->eregs + ESP_FDATA);
		if (!(it & me))
			return -1;
		it &= ~me;
		if (it & (it - 1))
			return -1;
		while (!(it & 1))
			targ++, it >>= 1;
	}
	return targ;
}

/* This verifies the identify from the target so that we know which lun is
 * being reconnected.
 */
static inline int reconnect_lun(struct esp *esp)
{
	int lun;

	if ((esp->sreg & ESP_STAT_PMASK) != ESP_MIP)
		return -1;
	if (esp->erev == fashme)
		lun = esp->hme_fifo_workaround_buffer[1];
	else
		lun = sbus_readb(esp->eregs + ESP_FDATA);

	/* Yes, you read this correctly.  We report lun of zero
	 * if we see parity error.  ESP reports parity error for
	 * the lun byte, and this is the only way to hope to recover
	 * because the target is connected.
	 */
	if (esp->sreg & ESP_STAT_PERR)
		return 0;

	/* Check for illegal bits being set in the lun. */
	if ((lun & 0x40) || !(lun & 0x80))
		return -1;

	return lun & 7;
}

/* This puts the driver in a state where it can revitalize a command that
 * is being continued due to reselection.
 */
static inline void esp_connect(struct esp *esp, struct scsi_cmnd *sp)
{
	struct esp_device *esp_dev = sp->device->hostdata;

	if (esp->prev_soff  != esp_dev->sync_max_offset ||
	    esp->prev_stp   != esp_dev->sync_min_period ||
	    (esp->erev > esp100a &&
	     esp->prev_cfg3 != esp->config3[sp->device->id])) {
		esp->prev_soff = esp_dev->sync_max_offset;
		esp->prev_stp = esp_dev->sync_min_period;
		sbus_writeb(esp->prev_soff, esp->eregs + ESP_SOFF);
		sbus_writeb(esp->prev_stp, esp->eregs + ESP_STP);
		if (esp->erev > esp100a) {
			esp->prev_cfg3 = esp->config3[sp->device->id];
			sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
		}
	}
	esp->current_SC = sp;
}

/* This will place the current working command back into the issue queue
 * if we are to receive a reselection amidst a selection attempt.
 */
static inline void esp_reconnect(struct esp *esp, struct scsi_cmnd *sp)
{
	if (!esp->disconnected_SC)
		ESPLOG(("esp%d: Weird, being reselected but disconnected "
			"command queue is empty.\n", esp->esp_id));
	esp->snip = 0;
	esp->current_SC = NULL;
	sp->SCp.phase = not_issued;
	append_SC(&esp->issue_SC, sp);
}

/* Begin message in phase. */
static int esp_do_msgin(struct esp *esp)
{
	/* Must be very careful with the fifo on the HME */
	if ((esp->erev != fashme) ||
	    !(sbus_readb(esp->eregs + ESP_STATUS2) & ESP_STAT2_FEMPTY))
		esp_cmd(esp, ESP_CMD_FLUSH);
	esp_maybe_nop(esp);
	esp_cmd(esp, ESP_CMD_TI);
	esp->msgin_len = 1;
	esp->msgin_ctr = 0;
	esp_advance_phase(esp->current_SC, in_msgindone);
	return do_work_bus;
}

/* This uses various DMA csr fields and the fifo flags count value to
 * determine how many bytes were successfully sent/received by the ESP.
 */
static inline int esp_bytes_sent(struct esp *esp, int fifo_count)
{
	int rval = sbus_readl(esp->dregs + DMA_ADDR) - esp->esp_command_dvma;

	if (esp->dma->revision == dvmarev1)
		rval -= (4 - ((sbus_readl(esp->dregs + DMA_CSR) & DMA_READ_AHEAD)>>11));
	return rval - fifo_count;
}

static inline void advance_sg(struct scsi_cmnd *sp)
{
	++sp->SCp.buffer;
	--sp->SCp.buffers_residual;
	sp->SCp.this_residual = sg_dma_len(sp->SCp.buffer);
	sp->SCp.ptr = (char *)((unsigned long)sg_dma_address(sp->SCp.buffer));
}

/* Please note that the way I've coded these routines is that I _always_
 * check for a disconnect during any and all information transfer
 * phases.  The SCSI standard states that the target _can_ cause a BUS
 * FREE condition by dropping all MSG/CD/IO/BSY signals.  Also note
 * that during information transfer phases the target controls every
 * change in phase, the only thing the initiator can do is "ask" for
 * a message out phase by driving ATN true.  The target can, and sometimes
 * will, completely ignore this request so we cannot assume anything when
 * we try to force a message out phase to abort/reset a target.  Most of
 * the time the target will eventually be nice and go to message out, so
 * we may have to hold on to our state about what we want to tell the target
 * for some period of time.
 */

/* I think I have things working here correctly.  Even partial transfers
 * within a buffer or sub-buffer should not upset us at all no matter
 * how bad the target and/or ESP fucks things up.
 */
static int esp_do_data(struct esp *esp)
{
	struct scsi_cmnd *SCptr = esp->current_SC;
	int thisphase, hmuch;

	ESPDATA(("esp_do_data: "));
	esp_maybe_nop(esp);
	thisphase = sreg_to_dataphase(esp->sreg);
	esp_advance_phase(SCptr, thisphase);
	ESPDATA(("newphase<%s> ", (thisphase == in_datain) ? "DATAIN" : "DATAOUT"));
	hmuch = dma_can_transfer(esp, SCptr);
	if (hmuch > (64 * 1024) && (esp->erev != fashme))
		hmuch = (64 * 1024);
	ESPDATA(("hmuch<%d> ", hmuch));
	esp->current_transfer_size = hmuch;

	if (esp->erev == fashme) {
		u32 tmp = esp->prev_hme_dmacsr;

		/* Always set the ESP count registers first. */
		esp_setcount(esp->eregs, hmuch, 1);

		/* Get the DMA csr computed. */
		tmp |= (DMA_SCSI_DISAB | DMA_ENABLE);
		if (thisphase == in_datain)
			tmp |= DMA_ST_WRITE;
		else
			tmp &= ~(DMA_ST_WRITE);
		esp->prev_hme_dmacsr = tmp;

		ESPDATA(("DMA|TI --> do_intr_end\n"));
		if (thisphase == in_datain) {
			sbus_writel(hmuch, esp->dregs + DMA_COUNT);
			esp_cmd(esp, ESP_CMD_DMA | ESP_CMD_TI);
		} else {
			esp_cmd(esp, ESP_CMD_DMA | ESP_CMD_TI);
			sbus_writel(hmuch, esp->dregs + DMA_COUNT);
		}
		sbus_writel((__u32)((unsigned long)SCptr->SCp.ptr), esp->dregs+DMA_ADDR);
		sbus_writel(esp->prev_hme_dmacsr, esp->dregs + DMA_CSR);
	} else {
		esp_setcount(esp->eregs, hmuch, 0);
		dma_setup(esp, ((__u32)((unsigned long)SCptr->SCp.ptr)),
			  hmuch, (thisphase == in_datain));
		ESPDATA(("DMA|TI --> do_intr_end\n"));
		esp_cmd(esp, ESP_CMD_DMA | ESP_CMD_TI);
	}
	return do_intr_end;
}

/* See how successful the data transfer was. */
static int esp_do_data_finale(struct esp *esp)
{
	struct scsi_cmnd *SCptr = esp->current_SC;
	struct esp_device *esp_dev = SCptr->device->hostdata;
	int bogus_data = 0, bytes_sent = 0, fifocnt, ecount = 0;

	ESPDATA(("esp_do_data_finale: "));

	if (SCptr->SCp.phase == in_datain) {
		if (esp->sreg & ESP_STAT_PERR) {
			/* Yuck, parity error.  The ESP asserts ATN
			 * so that we can go to message out phase
			 * immediately and inform the target that
			 * something bad happened.
			 */
			ESPLOG(("esp%d: data bad parity detected.\n",
				esp->esp_id));
			esp->cur_msgout[0] = INITIATOR_ERROR;
			esp->msgout_len = 1;
		}
		dma_drain(esp);
	}
	dma_invalidate(esp);

	/* This could happen for the above parity error case. */
	if (esp->ireg != ESP_INTR_BSERV) {
		/* Please go to msgout phase, please please please... */
		ESPLOG(("esp%d: !BSERV after data, probably to msgout\n",
			esp->esp_id));
		return esp_do_phase_determine(esp);
	}	

	/* Check for partial transfers and other horrible events.
	 * Note, here we read the real fifo flags register even
	 * on HME broken adapters because we skip the HME fifo
	 * workaround code in esp_handle() if we are doing data
	 * phase things.  We don't want to fuck directly with
	 * the fifo like that, especially if doing synchronous
	 * transfers!  Also, will need to double the count on
	 * HME if we are doing wide transfers, as the HME fifo
	 * will move and count 16-bit quantities during wide data.
	 * SMCC _and_ Qlogic can both bite me.
	 */
	fifocnt = (sbus_readb(esp->eregs + ESP_FFLAGS) & ESP_FF_FBYTES);
	if (esp->erev != fashme)
		ecount = esp_getcount(esp->eregs, 0);
	bytes_sent = esp->current_transfer_size;

	ESPDATA(("trans_sz(%d), ", bytes_sent));
	if (esp->erev == fashme) {
		if (!(esp->sreg & ESP_STAT_TCNT)) {
			ecount = esp_getcount(esp->eregs, 1);
			bytes_sent -= ecount;
		}

		/* Always subtract any cruft remaining in the FIFO. */
		if (esp->prev_cfg3 & ESP_CONFIG3_EWIDE)
			fifocnt <<= 1;
		if (SCptr->SCp.phase == in_dataout)
			bytes_sent -= fifocnt;

		/* I have an IBM disk which exhibits the following
		 * behavior during writes to it.  It disconnects in
		 * the middle of a partial transfer, the current sglist
		 * buffer is 1024 bytes, the disk stops data transfer
		 * at 512 bytes.
		 *
		 * However the FAS366 reports that 32 more bytes were
		 * transferred than really were.  This is precisely
		 * the size of a fully loaded FIFO in wide scsi mode.
		 * The FIFO state recorded indicates that it is empty.
		 *
		 * I have no idea if this is a bug in the FAS366 chip
		 * or a bug in the firmware on this IBM disk.  In any
		 * event the following seems to be a good workaround.  -DaveM
		 */
		if (bytes_sent != esp->current_transfer_size &&
		    SCptr->SCp.phase == in_dataout) {
			int mask = (64 - 1);

			if ((esp->prev_cfg3 & ESP_CONFIG3_EWIDE) == 0)
				mask >>= 1;

			if (bytes_sent & mask)
				bytes_sent -= (bytes_sent & mask);
		}
	} else {
		if (!(esp->sreg & ESP_STAT_TCNT))
			bytes_sent -= ecount;
		if (SCptr->SCp.phase == in_dataout)
			bytes_sent -= fifocnt;
	}

	ESPDATA(("bytes_sent(%d), ", bytes_sent));

	/* If we were in synchronous mode, check for peculiarities. */
	if (esp->erev == fashme) {
		if (esp_dev->sync_max_offset) {
			if (SCptr->SCp.phase == in_dataout)
				esp_cmd(esp, ESP_CMD_FLUSH);
		} else {
			esp_cmd(esp, ESP_CMD_FLUSH);
		}
	} else {
		if (esp_dev->sync_max_offset)
			bogus_data = esp100_sync_hwbug(esp, SCptr, fifocnt);
		else
			esp_cmd(esp, ESP_CMD_FLUSH);
	}

	/* Until we are sure of what has happened, we are certainly
	 * in the dark.
	 */
	esp_advance_phase(SCptr, in_the_dark);

	if (bytes_sent < 0) {
		/* I've seen this happen due to lost state in this
		 * driver.  No idea why it happened, but allowing
		 * this value to be negative caused things to
		 * lock up.  This allows greater chance of recovery.
		 * In fact every time I've seen this, it has been
		 * a driver bug without question.
		 */
		ESPLOG(("esp%d: yieee, bytes_sent < 0!\n", esp->esp_id));
		ESPLOG(("esp%d: csz=%d fifocount=%d ecount=%d\n",
			esp->esp_id,
			esp->current_transfer_size, fifocnt, ecount));
		ESPLOG(("esp%d: use_sg=%d ptr=%p this_residual=%d\n",
			esp->esp_id,
			SCptr->use_sg, SCptr->SCp.ptr, SCptr->SCp.this_residual));
		ESPLOG(("esp%d: Forcing async for target %d\n", esp->esp_id, 
			SCptr->device->id));
		SCptr->device->borken = 1;
		esp_dev->sync = 0;
		bytes_sent = 0;
	}

	/* Update the state of our transfer. */
	SCptr->SCp.ptr += bytes_sent;
	SCptr->SCp.this_residual -= bytes_sent;
	if (SCptr->SCp.this_residual < 0) {
		/* shit */
		ESPLOG(("esp%d: Data transfer overrun.\n", esp->esp_id));
		SCptr->SCp.this_residual = 0;
	}

	/* Maybe continue. */
	if (!bogus_data) {
		ESPDATA(("!bogus_data, "));

		/* NO MATTER WHAT, we advance the scatterlist,
		 * if the target should decide to disconnect
		 * in between scatter chunks (which is common)
		 * we could die horribly!  I used to have the sg
		 * advance occur only if we are going back into
		 * (or are staying in) a data phase, you can
		 * imagine the hell I went through trying to
		 * figure this out.
		 */
		if (SCptr->use_sg && !SCptr->SCp.this_residual)
			advance_sg(SCptr);
		if (sreg_datainp(esp->sreg) || sreg_dataoutp(esp->sreg)) {
			ESPDATA(("to more data\n"));
			return esp_do_data(esp);
		}
		ESPDATA(("to new phase\n"));
		return esp_do_phase_determine(esp);
	}
	/* Bogus data, just wait for next interrupt. */
	ESPLOG(("esp%d: bogus_data during end of data phase\n",
		esp->esp_id));
	return do_intr_end;
}

/* We received a non-good status return at the end of
 * running a SCSI command.  This is used to decide if
 * we should clear our synchronous transfer state for
 * such a device when that happens.
 *
 * The idea is that when spinning up a disk or rewinding
 * a tape, we don't want to go into a loop re-negotiating
 * synchronous capabilities over and over.
 */
static int esp_should_clear_sync(struct scsi_cmnd *sp)
{
	u8 cmd1 = sp->cmnd[0];
	u8 cmd2 = sp->data_cmnd[0];

	/* These cases are for spinning up a disk and
	 * waiting for that spinup to complete.
	 */
	if (cmd1 == START_STOP ||
	    cmd2 == START_STOP)
		return 0;

	if (cmd1 == TEST_UNIT_READY ||
	    cmd2 == TEST_UNIT_READY)
		return 0;

	/* One more special case for SCSI tape drives,
	 * this is what is used to probe the device for
	 * completion of a rewind or tape load operation.
	 */
	if (sp->device->type == TYPE_TAPE) {
		if (cmd1 == MODE_SENSE ||
		    cmd2 == MODE_SENSE)
			return 0;
	}

	return 1;
}

/* Either a command is completing or a target is dropping off the bus
 * to continue the command in the background so we can do other work.
 */
static int esp_do_freebus(struct esp *esp)
{
	struct scsi_cmnd *SCptr = esp->current_SC;
	struct esp_device *esp_dev = SCptr->device->hostdata;
	int rval;

	rval = skipahead2(esp, SCptr, in_status, in_msgindone, in_freeing);
	if (rval)
		return rval;
	if (esp->ireg != ESP_INTR_DC) {
		ESPLOG(("esp%d: Target will not disconnect\n", esp->esp_id));
		return do_reset_bus; /* target will not drop BSY... */
	}
	esp->msgout_len = 0;
	esp->prevmsgout = NOP;
	if (esp->prevmsgin == COMMAND_COMPLETE) {
		/* Normal end of nexus. */
		if (esp->disconnected_SC || (esp->erev == fashme))
			esp_cmd(esp, ESP_CMD_ESEL);

		if (SCptr->SCp.Status != GOOD &&
		    SCptr->SCp.Status != CONDITION_GOOD &&
		    ((1<<SCptr->device->id) & esp->targets_present) &&
		    esp_dev->sync &&
		    esp_dev->sync_max_offset) {
			/* SCSI standard says that the synchronous capabilities
			 * should be renegotiated at this point.  Most likely
			 * we are about to request sense from this target
			 * in which case we want to avoid using sync
			 * transfers until we are sure of the current target
			 * state.
			 */
			ESPMISC(("esp: Status <%d> for target %d lun %d\n",
				 SCptr->SCp.Status, SCptr->device->id, SCptr->device->lun));

			/* But don't do this when spinning up a disk at
			 * boot time while we poll for completion as it
			 * fills up the console with messages.  Also, tapes
			 * can report not ready many times right after
			 * loading up a tape.
			 */
			if (esp_should_clear_sync(SCptr) != 0)
				esp_dev->sync = 0;
		}
		ESPDISC(("F<%02x,%02x>", SCptr->device->id, SCptr->device->lun));
		esp_done(esp, ((SCptr->SCp.Status & 0xff) |
			       ((SCptr->SCp.Message & 0xff)<<8) |
			       (DID_OK << 16)));
	} else if (esp->prevmsgin == DISCONNECT) {
		/* Normal disconnect. */
		esp_cmd(esp, ESP_CMD_ESEL);
		ESPDISC(("D<%02x,%02x>", SCptr->device->id, SCptr->device->lun));
		append_SC(&esp->disconnected_SC, SCptr);
		esp->current_SC = NULL;
		if (esp->issue_SC)
			esp_exec_cmd(esp);
	} else {
		/* Driver bug, we do not expect a disconnect here
		 * and should not have advanced the state engine
		 * to in_freeing.
		 */
		ESPLOG(("esp%d: last msg not disc and not cmd cmplt.\n",
			esp->esp_id));
		return do_reset_bus;
	}
	return do_intr_end;
}

/* When a reselect occurs, and we cannot find the command to
 * reconnect to in our queues, we do this.
 */
static int esp_bad_reconnect(struct esp *esp)
{
	struct scsi_cmnd *sp;

	ESPLOG(("esp%d: Eieeee, reconnecting unknown command!\n",
		esp->esp_id));
	ESPLOG(("QUEUE DUMP\n"));
	sp = esp->issue_SC;
	ESPLOG(("esp%d: issue_SC[", esp->esp_id));
	while (sp) {
		ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun));
		sp = (struct scsi_cmnd *) sp->host_scribble;
	}
	ESPLOG(("]\n"));
	sp = esp->current_SC;
	ESPLOG(("esp%d: current_SC[", esp->esp_id));
	if (sp)
		ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun));
	else
		ESPLOG(("<NULL>"));
	ESPLOG(("]\n"));
	sp = esp->disconnected_SC;
	ESPLOG(("esp%d: disconnected_SC[", esp->esp_id));
	while (sp) {
		ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun));
		sp = (struct scsi_cmnd *) sp->host_scribble;
	}
	ESPLOG(("]\n"));
	return do_reset_bus;
}

/* Do the needy when a target tries to reconnect to us. */
static int esp_do_reconnect(struct esp *esp)
{
	int lun, target;
	struct scsi_cmnd *SCptr;

	/* Check for all bogus conditions first. */
	target = reconnect_target(esp);
	if (target < 0) {
		ESPDISC(("bad bus bits\n"));
		return do_reset_bus;
	}
	lun = reconnect_lun(esp);
	if (lun < 0) {
		ESPDISC(("target=%2x, bad identify msg\n", target));
		return do_reset_bus;
	}

	/* Things look ok... */
	ESPDISC(("R<%02x,%02x>", target, lun));

	/* Must not flush FIFO or DVMA on HME. */
	if (esp->erev != fashme) {
		esp_cmd(esp, ESP_CMD_FLUSH);
		if (esp100_reconnect_hwbug(esp))
			return do_reset_bus;
		esp_cmd(esp, ESP_CMD_NULL);
	}

	SCptr = remove_SC(&esp->disconnected_SC, (u8) target, (u8) lun);
	if (!SCptr)
		return esp_bad_reconnect(esp);

	esp_connect(esp, SCptr);
	esp_cmd(esp, ESP_CMD_MOK);

	if (esp->erev == fashme)
		sbus_writeb(((SCptr->device->id & 0xf) |
			     (ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT)),
			    esp->eregs + ESP_BUSID);

	/* Reconnect implies a restore pointers operation. */
	esp_restore_pointers(esp, SCptr);

	esp->snip = 0;
	esp_advance_phase(SCptr, in_the_dark);
	return do_intr_end;
}

/* End of NEXUS (hopefully), pick up status + message byte then leave if
 * all goes well.
 */
static int esp_do_status(struct esp *esp)
{
	struct scsi_cmnd *SCptr = esp->current_SC;
	int intr, rval;

	rval = skipahead1(esp, SCptr, in_the_dark, in_status);
	if (rval)
		return rval;
	intr = esp->ireg;
	ESPSTAT(("esp_do_status: "));
	if (intr != ESP_INTR_DC) {
		int message_out = 0; /* for parity problems */

		/* Ack the message. */
		ESPSTAT(("ack msg, "));
		esp_cmd(esp, ESP_CMD_MOK);

		if (esp->erev != fashme) {
			dma_flashclear(esp);

			/* Wait till the first bits settle. */
			while (esp->esp_command[0] == 0xff)
				udelay(1);
		} else {
			esp->esp_command[0] = esp->hme_fifo_workaround_buffer[0];
			esp->esp_command[1] = esp->hme_fifo_workaround_buffer[1];
		}

		ESPSTAT(("got something, "));
		/* ESP chimes in with one of
		 *
		 * 1) function done interrupt:
		 *	both status and message in bytes
		 *	are available
		 *
		 * 2) bus service interrupt:
		 *	only status byte was acquired
		 *
		 * 3) Anything else:
		 *	can't happen, but we test for it
		 *	anyways
		 *
		 * ALSO: If bad parity was detected on either
		 *       the status _or_ the message byte then
		 *       the ESP has asserted ATN on the bus
		 *       and we must therefore wait for the
		 *       next phase change.
		 */
		if (intr & ESP_INTR_FDONE) {
			/* We got it all, hallejulia. */
			ESPSTAT(("got both, "));
			SCptr->SCp.Status = esp->esp_command[0];
			SCptr->SCp.Message = esp->esp_command[1];
			esp->prevmsgin = SCptr->SCp.Message;
			esp->cur_msgin[0] = SCptr->SCp.Message;
			if (esp->sreg & ESP_STAT_PERR) {
				/* There was bad parity for the
				 * message byte, the status byte
				 * was ok.
				 */
				message_out = MSG_PARITY_ERROR;
			}
		} else if (intr == ESP_INTR_BSERV) {
			/* Only got status byte. */
			ESPLOG(("esp%d: got status only, ", esp->esp_id));
			if (!(esp->sreg & ESP_STAT_PERR)) {
				SCptr->SCp.Status = esp->esp_command[0];
				SCptr->SCp.Message = 0xff;
			} else {
				/* The status byte had bad parity.
				 * we leave the scsi_pointer Status
				 * field alone as we set it to a default
				 * of CHECK_CONDITION in esp_queue.
				 */
				message_out = INITIATOR_ERROR;
			}
		} else {
			/* This shouldn't happen ever. */
			ESPSTAT(("got bolixed\n"));
			esp_advance_phase(SCptr, in_the_dark);
			return esp_do_phase_determine(esp);
		}

		if (!message_out) {
			ESPSTAT(("status=%2x msg=%2x, ", SCptr->SCp.Status,
				SCptr->SCp.Message));
			if (SCptr->SCp.Message == COMMAND_COMPLETE) {
				ESPSTAT(("and was COMMAND_COMPLETE\n"));
				esp_advance_phase(SCptr, in_freeing);
				return esp_do_freebus(esp);
			} else {
				ESPLOG(("esp%d: and _not_ COMMAND_COMPLETE\n",
					esp->esp_id));
				esp->msgin_len = esp->msgin_ctr = 1;
				esp_advance_phase(SCptr, in_msgindone);
				return esp_do_msgindone(esp);
			}
		} else {
			/* With luck we'll be able to let the target
			 * know that bad parity happened, it will know
			 * which byte caused the problems and send it
			 * again.  For the case where the status byte
			 * receives bad parity, I do not believe most
			 * targets recover very well.  We'll see.
			 */
			ESPLOG(("esp%d: bad parity somewhere mout=%2x\n",
				esp->esp_id, message_out));
			esp->cur_msgout[0] = message_out;
			esp->msgout_len = esp->msgout_ctr = 1;
			esp_advance_phase(SCptr, in_the_dark);
			return esp_do_phase_determine(esp);
		}
	} else {
		/* If we disconnect now, all hell breaks loose. */
		ESPLOG(("esp%d: whoops, disconnect\n", esp->esp_id));
		esp_advance_phase(SCptr, in_the_dark);
		return esp_do_phase_determine(esp);
	}
}

static int esp_enter_status(struct esp *esp)
{
	u8 thecmd = ESP_CMD_ICCSEQ;

	esp_cmd(esp, ESP_CMD_FLUSH);
	if (esp->erev != fashme) {
		u32 tmp;

		esp->esp_command[0] = esp->esp_command[1] = 0xff;
		sbus_writeb(2, esp->eregs + ESP_TCLOW);
		sbus_writeb(0, esp->eregs + ESP_TCMED);
		tmp = sbus_readl(esp->dregs + DMA_CSR);
		tmp |= (DMA_ST_WRITE | DMA_ENABLE);
		sbus_writel(tmp, esp->dregs + DMA_CSR);
		if (esp->dma->revision == dvmaesc1)
			sbus_writel(0x100, esp->dregs + DMA_COUNT);
		sbus_writel(esp->esp_command_dvma, esp->dregs + DMA_ADDR);
		thecmd |= ESP_CMD_DMA;
	}
	esp_cmd(esp, thecmd);
	esp_advance_phase(esp->current_SC, in_status);

	return esp_do_status(esp);
}

static int esp_disconnect_amidst_phases(struct esp *esp)
{
	struct scsi_cmnd *sp = esp->current_SC;
	struct esp_device *esp_dev = sp->device->hostdata;

	/* This means real problems if we see this
	 * here.  Unless we were actually trying
	 * to force the device to abort/reset.
	 */
	ESPLOG(("esp%d Disconnect amidst phases, ", esp->esp_id));
	ESPLOG(("pphase<%s> cphase<%s>, ",
		phase_string(sp->SCp.phase),
		phase_string(sp->SCp.sent_command)));

	if (esp->disconnected_SC != NULL || (esp->erev == fashme))
		esp_cmd(esp, ESP_CMD_ESEL);

	switch (esp->cur_msgout[0]) {
	default:
		/* We didn't expect this to happen at all. */
		ESPLOG(("device is bolixed\n"));
		esp_advance_phase(sp, in_tgterror);
		esp_done(esp, (DID_ERROR << 16));
		break;

	case BUS_DEVICE_RESET:
		ESPLOG(("device reset successful\n"));
		esp_dev->sync_max_offset = 0;
		esp_dev->sync_min_period = 0;
		esp_dev->sync = 0;
		esp_advance_phase(sp, in_resetdev);
		esp_done(esp, (DID_RESET << 16));
		break;

	case ABORT:
		ESPLOG(("device abort successful\n"));
		esp_advance_phase(sp, in_abortone);
		esp_done(esp, (DID_ABORT << 16));
		break;

	};
	return do_intr_end;
}

static int esp_enter_msgout(struct esp *esp)
{
	esp_advance_phase(esp->current_SC, in_msgout);
	return esp_do_msgout(esp);
}

static int esp_enter_msgin(struct esp *esp)
{
	esp_advance_phase(esp->current_SC, in_msgin);
	return esp_do_msgin(esp);
}

static int esp_enter_cmd(struct esp *esp)
{
	esp_advance_phase(esp->current_SC, in_cmdbegin);
	return esp_do_cmdbegin(esp);
}

static int esp_enter_badphase(struct esp *esp)
{
	ESPLOG(("esp%d: Bizarre bus phase %2x.\n", esp->esp_id,
		esp->sreg & ESP_STAT_PMASK));
	return do_reset_bus;
}

typedef int (*espfunc_t)(struct esp *);

static espfunc_t phase_vector[] = {
	esp_do_data,		/* ESP_DOP */
	esp_do_data,		/* ESP_DIP */
	esp_enter_cmd,		/* ESP_CMDP */
	esp_enter_status,	/* ESP_STATP */
	esp_enter_badphase,	/* ESP_STAT_PMSG */
	esp_enter_badphase,	/* ESP_STAT_PMSG | ESP_STAT_PIO */
	esp_enter_msgout,	/* ESP_MOP */
	esp_enter_msgin,	/* ESP_MIP */
};

/* The target has control of the bus and we have to see where it has
 * taken us.
 */
static int esp_do_phase_determine(struct esp *esp)
{
	if ((esp->ireg & ESP_INTR_DC) != 0)
		return esp_disconnect_amidst_phases(esp);
	return phase_vector[esp->sreg & ESP_STAT_PMASK](esp);
}

/* First interrupt after exec'ing a cmd comes here. */
static int esp_select_complete(struct esp *esp)
{
	struct scsi_cmnd *SCptr = esp->current_SC;
	struct esp_device *esp_dev = SCptr->device->hostdata;
	int cmd_bytes_sent, fcnt;

	if (esp->erev != fashme)
		esp->seqreg = (sbus_readb(esp->eregs + ESP_SSTEP) & ESP_STEP_VBITS);

	if (esp->erev == fashme)
		fcnt = esp->hme_fifo_workaround_count;
	else
		fcnt = (sbus_readb(esp->eregs + ESP_FFLAGS) & ESP_FF_FBYTES);

	cmd_bytes_sent = esp_bytes_sent(esp, fcnt);
	dma_invalidate(esp);

	/* Let's check to see if a reselect happened
	 * while we we're trying to select.  This must
	 * be checked first.
	 */
	if (esp->ireg == (ESP_INTR_RSEL | ESP_INTR_FDONE)) {
		esp_reconnect(esp, SCptr);
		return esp_do_reconnect(esp);
	}

	/* Looks like things worked, we should see a bus service &
	 * a function complete interrupt at this point.  Note we
	 * are doing a direct comparison because we don't want to
	 * be fooled into thinking selection was successful if
	 * ESP_INTR_DC is set, see below.
	 */
	if (esp->ireg == (ESP_INTR_FDONE | ESP_INTR_BSERV)) {
		/* target speaks... */
		esp->targets_present |= (1<<SCptr->device->id);

		/* What if the target ignores the sdtr? */
		if (esp->snip)
			esp_dev->sync = 1;

		/* See how far, if at all, we got in getting
		 * the information out to the target.
		 */
		switch (esp->seqreg) {
		default:

		case ESP_STEP_ASEL:
			/* Arbitration won, target selected, but
			 * we are in some phase which is not command
			 * phase nor is it message out phase.
			 *
			 * XXX We've confused the target, obviously.
			 * XXX So clear it's state, but we also end
			 * XXX up clearing everyone elses.  That isn't
			 * XXX so nice.  I'd like to just reset this
			 * XXX target, but if I cannot even get it's
			 * XXX attention and finish selection to talk
			 * XXX to it, there is not much more I can do.
			 * XXX If we have a loaded bus we're going to
			 * XXX spend the next second or so renegotiating
			 * XXX for synchronous transfers.
			 */
			ESPLOG(("esp%d: STEP_ASEL for tgt %d\n",
				esp->esp_id, SCptr->device->id));

		case ESP_STEP_SID:
			/* Arbitration won, target selected, went
			 * to message out phase, sent one message
			 * byte, then we stopped.  ATN is asserted
			 * on the SCSI bus and the target is still
			 * there hanging on.  This is a legal
			 * sequence step if we gave the ESP a select
			 * and stop command.
			 *
			 * XXX See above, I could set the borken flag
			 * XXX in the device struct and retry the
			 * XXX command.  But would that help for
			 * XXX tagged capable targets?
			 */

		case ESP_STEP_NCMD:
			/* Arbitration won, target selected, maybe
			 * sent the one message byte in message out
			 * phase, but we did not go to command phase
			 * in the end.  Actually, we could have sent
			 * only some of the message bytes if we tried
			 * to send out the entire identify and tag
			 * message using ESP_CMD_SA3.
			 */
			cmd_bytes_sent = 0;
			break;

		case ESP_STEP_PPC:
			/* No, not the powerPC pinhead.  Arbitration
			 * won, all message bytes sent if we went to
			 * message out phase, went to command phase
			 * but only part of the command was sent.
			 *
			 * XXX I've seen this, but usually in conjunction
			 * XXX with a gross error which appears to have
			 * XXX occurred between the time I told the
			 * XXX ESP to arbitrate and when I got the
			 * XXX interrupt.  Could I have misloaded the
			 * XXX command bytes into the fifo?  Actually,
			 * XXX I most likely missed a phase, and therefore
			 * XXX went into never never land and didn't even
			 * XXX know it.  That was the old driver though.
			 * XXX What is even more peculiar is that the ESP
			 * XXX showed the proper function complete and
			 * XXX bus service bits in the interrupt register.
			 */

		case ESP_STEP_FINI4:
		case ESP_STEP_FINI5:
		case ESP_STEP_FINI6:
		case ESP_STEP_FINI7:
			/* Account for the identify message */
			if (SCptr->SCp.phase == in_slct_norm)
				cmd_bytes_sent -= 1;
		};

		if (esp->erev != fashme)
			esp_cmd(esp, ESP_CMD_NULL);

		/* Be careful, we could really get fucked during synchronous
		 * data transfers if we try to flush the fifo now.
		 */
		if ((esp->erev != fashme) && /* not a Happy Meal and... */
		    !fcnt && /* Fifo is empty and... */
		    /* either we are not doing synchronous transfers or... */
		    (!esp_dev->sync_max_offset ||
		     /* We are not going into data in phase. */
		     ((esp->sreg & ESP_STAT_PMASK) != ESP_DIP)))
			esp_cmd(esp, ESP_CMD_FLUSH); /* flush is safe */

		/* See how far we got if this is not a slow command. */
		if (!esp->esp_slowcmd) {
			if (cmd_bytes_sent < 0)
				cmd_bytes_sent = 0;
			if (cmd_bytes_sent != SCptr->cmd_len) {
				/* Crapola, mark it as a slowcmd
				 * so that we have some chance of
				 * keeping the command alive with
				 * good luck.
				 *
				 * XXX Actually, if we didn't send it all
				 * XXX this means either we didn't set things
				 * XXX up properly (driver bug) or the target
				 * XXX or the ESP detected parity on one of
				 * XXX the command bytes.  This makes much
				 * XXX more sense, and therefore this code
				 * XXX should be changed to send out a
				 * XXX parity error message or if the status
				 * XXX register shows no parity error then
				 * XXX just expect the target to bring the
				 * XXX bus into message in phase so that it
				 * XXX can send us the parity error message.
				 * XXX SCSI sucks...
				 */
				esp->esp_slowcmd = 1;
				esp->esp_scmdp = &(SCptr->cmnd[cmd_bytes_sent]);
				esp->esp_scmdleft = (SCptr->cmd_len - cmd_bytes_sent);
			}
		}

		/* Now figure out where we went. */
		esp_advance_phase(SCptr, in_the_dark);
		return esp_do_phase_determine(esp);
	}

	/* Did the target even make it? */
	if (esp->ireg == ESP_INTR_DC) {
		/* wheee... nobody there or they didn't like
		 * what we told it to do, clean up.
		 */

		/* If anyone is off the bus, but working on
		 * a command in the background for us, tell
		 * the ESP to listen for them.
		 */
		if (esp->disconnected_SC)
			esp_cmd(esp, ESP_CMD_ESEL);

		if (((1<<SCptr->device->id) & esp->targets_present) &&
		    esp->seqreg != 0 &&
		    (esp->cur_msgout[0] == EXTENDED_MESSAGE) &&
		    (SCptr->SCp.phase == in_slct_msg ||
		     SCptr->SCp.phase == in_slct_stop)) {
			/* shit */
			esp->snip = 0;
			ESPLOG(("esp%d: Failed synchronous negotiation for target %d "
				"lun %d\n", esp->esp_id, SCptr->device->id, SCptr->device->lun));
			esp_dev->sync_max_offset = 0;
			esp_dev->sync_min_period = 0;
			esp_dev->sync = 1; /* so we don't negotiate again */

			/* Run the command again, this time though we
			 * won't try to negotiate for synchronous transfers.
			 *
			 * XXX I'd like to do something like send an
			 * XXX INITIATOR_ERROR or ABORT message to the
			 * XXX target to tell it, "Sorry I confused you,
			 * XXX please come back and I will be nicer next
			 * XXX time".  But that requires having the target
			 * XXX on the bus, and it has dropped BSY on us.
			 */
			esp->current_SC = NULL;
			esp_advance_phase(SCptr, not_issued);
			prepend_SC(&esp->issue_SC, SCptr);
			esp_exec_cmd(esp);
			return do_intr_end;
		}

		/* Ok, this is normal, this is what we see during boot
		 * or whenever when we are scanning the bus for targets.
		 * But first make sure that is really what is happening.
		 */
		if (((1<<SCptr->device->id) & esp->targets_present)) {
			ESPLOG(("esp%d: Warning, live target %d not responding to "
				"selection.\n", esp->esp_id, SCptr->device->id));

			/* This _CAN_ happen.  The SCSI standard states that
			 * the target is to _not_ respond to selection if
			 * _it_ detects bad parity on the bus for any reason.
			 * Therefore, we assume that if we've talked successfully
			 * to this target before, bad parity is the problem.
			 */
			esp_done(esp, (DID_PARITY << 16));
		} else {
			/* Else, there really isn't anyone there. */
			ESPMISC(("esp: selection failure, maybe nobody there?\n"));
			ESPMISC(("esp: target %d lun %d\n",
				 SCptr->device->id, SCptr->device->lun));
			esp_done(esp, (DID_BAD_TARGET << 16));
		}
		return do_intr_end;
	}

	ESPLOG(("esp%d: Selection failure.\n", esp->esp_id));
	printk("esp%d: Currently -- ", esp->esp_id);
	esp_print_ireg(esp->ireg); printk(" ");
	esp_print_statreg(esp->sreg); printk(" ");
	esp_print_seqreg(esp->seqreg); printk("\n");
	printk("esp%d: New -- ", esp->esp_id);
	esp->sreg = sbus_readb(esp->eregs + ESP_STATUS);
	esp->seqreg = sbus_readb(esp->eregs + ESP_SSTEP);
	esp->ireg = sbus_readb(esp->eregs + ESP_INTRPT);
	esp_print_ireg(esp->ireg); printk(" ");
	esp_print_statreg(esp->sreg); printk(" ");
	esp_print_seqreg(esp->seqreg); printk("\n");
	ESPLOG(("esp%d: resetting bus\n", esp->esp_id));
	return do_reset_bus; /* ugh... */
}

/* Continue reading bytes for msgin phase. */
static int esp_do_msgincont(struct esp *esp)
{
	if (esp->ireg & ESP_INTR_BSERV) {
		/* in the right phase too? */
		if ((esp->sreg & ESP_STAT_PMASK) == ESP_MIP) {
			/* phew... */
			esp_cmd(esp, ESP_CMD_TI);
			esp_advance_phase(esp->current_SC, in_msgindone);
			return do_intr_end;
		}

		/* We changed phase but ESP shows bus service,
		 * in this case it is most likely that we, the
		 * hacker who has been up for 20hrs straight
		 * staring at the screen, drowned in coffee
		 * smelling like retched cigarette ashes
		 * have miscoded something..... so, try to
		 * recover as best we can.
		 */
		ESPLOG(("esp%d: message in mis-carriage.\n", esp->esp_id));
	}
	esp_advance_phase(esp->current_SC, in_the_dark);
	return do_phase_determine;
}

static int check_singlebyte_msg(struct esp *esp)
{
	esp->prevmsgin = esp->cur_msgin[0];
	if (esp->cur_msgin[0] & 0x80) {
		/* wheee... */
		ESPLOG(("esp%d: target sends identify amidst phases\n",
			esp->esp_id));
		esp_advance_phase(esp->current_SC, in_the_dark);
		return 0;
	} else if (((esp->cur_msgin[0] & 0xf0) == 0x20) ||
		   (esp->cur_msgin[0] == EXTENDED_MESSAGE)) {
		esp->msgin_len = 2;
		esp_advance_phase(esp->current_SC, in_msgincont);
		return 0;
	}
	esp_advance_phase(esp->current_SC, in_the_dark);
	switch (esp->cur_msgin[0]) {
	default:
		/* We don't want to hear about it. */
		ESPLOG(("esp%d: msg %02x which we don't know about\n", esp->esp_id,
			esp->cur_msgin[0]));
		return MESSAGE_REJECT;

	case NOP:
		ESPLOG(("esp%d: target %d sends a nop\n", esp->esp_id,
			esp->current_SC->device->id));
		return 0;

	case RESTORE_POINTERS:
		/* In this case we might also have to backup the
		 * "slow command" pointer.  It is rare to get such
		 * a save/restore pointer sequence so early in the
		 * bus transition sequences, but cover it.
		 */
		if (esp->esp_slowcmd) {
			esp->esp_scmdleft = esp->current_SC->cmd_len;
			esp->esp_scmdp = &esp->current_SC->cmnd[0];
		}
		esp_restore_pointers(esp, esp->current_SC);
		return 0;

	case SAVE_POINTERS:
		esp_save_pointers(esp, esp->current_SC);
		return 0;

	case COMMAND_COMPLETE:
	case DISCONNECT:
		/* Freeing the bus, let it go. */
		esp->current_SC->SCp.phase = in_freeing;
		return 0;

	case MESSAGE_REJECT:
		ESPMISC(("msg reject, "));
		if (esp->prevmsgout == EXTENDED_MESSAGE) {
			struct esp_device *esp_dev = esp->current_SC->device->hostdata;

			/* Doesn't look like this target can
			 * do synchronous or WIDE transfers.
			 */
			ESPSDTR(("got reject, was trying nego, clearing sync/WIDE\n"));
			esp_dev->sync = 1;
			esp_dev->wide = 1;
			esp_dev->sync_min_period = 0;
			esp_dev->sync_max_offset = 0;
			return 0;
		} else {
			ESPMISC(("not sync nego, sending ABORT\n"));
			return ABORT;
		}
	};
}

/* Target negotiates for synchronous transfers before we do, this
 * is legal although very strange.  What is even funnier is that
 * the SCSI2 standard specifically recommends against targets doing
 * this because so many initiators cannot cope with this occurring.
 */
static int target_with_ants_in_pants(struct esp *esp,
				     struct scsi_cmnd *SCptr,
				     struct esp_device *esp_dev)
{
	if (esp_dev->sync || SCptr->device->borken) {
		/* sorry, no can do */
		ESPSDTR(("forcing to async, "));
		build_sync_nego_msg(esp, 0, 0);
		esp_dev->sync = 1;
		esp->snip = 1;
		ESPLOG(("esp%d: hoping for msgout\n", esp->esp_id));
		esp_advance_phase(SCptr, in_the_dark);
		return EXTENDED_MESSAGE;
	}

	/* Ok, we'll check them out... */
	return 0;
}

static void sync_report(struct esp *esp)
{
	int msg3, msg4;
	char *type;

	msg3 = esp->cur_msgin[3];
	msg4 = esp->cur_msgin[4];
	if (msg4) {
		int hz = 1000000000 / (msg3 * 4);
		int integer = hz / 1000000;
		int fraction = (hz - (integer * 1000000)) / 10000;
		if ((esp->erev == fashme) &&
		    (esp->config3[esp->current_SC->device->id] & ESP_CONFIG3_EWIDE)) {
			type = "FAST-WIDE";
			integer <<= 1;
			fraction <<= 1;
		} else if ((msg3 * 4) < 200) {
			type = "FAST";
		} else {
			type = "synchronous";
		}

		/* Do not transform this back into one big printk
		 * again, it triggers a bug in our sparc64-gcc272
		 * sibling call optimization.  -DaveM
		 */
		ESPLOG((KERN_INFO "esp%d: target %d ",
			esp->esp_id, esp->current_SC->device->id));
		ESPLOG(("[period %dns offset %d %d.%02dMHz ",
			(int) msg3 * 4, (int) msg4,
			integer, fraction));
		ESPLOG(("%s SCSI%s]\n", type,
			(((msg3 * 4) < 200) ? "-II" : "")));
	} else {
		ESPLOG((KERN_INFO "esp%d: target %d asynchronous\n",
			esp->esp_id, esp->current_SC->device->id));
	}
}

static int check_multibyte_msg(struct esp *esp)
{
	struct scsi_cmnd *SCptr = esp->current_SC;
	struct esp_device *esp_dev = SCptr->device->hostdata;
	u8 regval = 0;
	int message_out = 0;

	ESPSDTR(("chk multibyte msg: "));
	if (esp->cur_msgin[2] == EXTENDED_SDTR) {
		int period = esp->cur_msgin[3];
		int offset = esp->cur_msgin[4];

		ESPSDTR(("is sync nego response, "));
		if (!esp->snip) {
			int rval;

			/* Target negotiates first! */
			ESPSDTR(("target jumps the gun, "));
			message_out = EXTENDED_MESSAGE; /* we must respond */
			rval = target_with_ants_in_pants(esp, SCptr, esp_dev);
			if (rval)
				return rval;
		}

		ESPSDTR(("examining sdtr, "));

		/* Offset cannot be larger than ESP fifo size. */
		if (offset > 15) {
			ESPSDTR(("offset too big %2x, ", offset));
			offset = 15;
			ESPSDTR(("sending back new offset\n"));
			build_sync_nego_msg(esp, period, offset);
			return EXTENDED_MESSAGE;
		}

		if (offset && period > esp->max_period) {
			/* Yeee, async for this slow device. */
			ESPSDTR(("period too long %2x, ", period));
			build_sync_nego_msg(esp, 0, 0);
			ESPSDTR(("hoping for msgout\n"));
			esp_advance_phase(esp->current_SC, in_the_dark);
			return EXTENDED_MESSAGE;
		} else if (offset && period < esp->min_period) {
			ESPSDTR(("period too short %2x, ", period));
			period = esp->min_period;
			if (esp->erev > esp236)
				regval = 4;
			else
				regval = 5;
		} else if (offset) {
			int tmp;

			ESPSDTR(("period is ok, "));
			tmp = esp->ccycle / 1000;
			regval = (((period << 2) + tmp - 1) / tmp);
			if (regval && ((esp->erev == fas100a ||
					esp->erev == fas236  ||
					esp->erev == fashme))) {
				if (period >= 50)
					regval--;
			}
		}

		if (offset) {
			u8 bit;

			esp_dev->sync_min_period = (regval & 0x1f);
			esp_dev->sync_max_offset = (offset | esp->radelay);
			if (esp->erev == fas100a || esp->erev == fas236 || esp->erev == fashme) {
				if ((esp->erev == fas100a) || (esp->erev == fashme))
					bit = ESP_CONFIG3_FAST;
				else
					bit = ESP_CONFIG3_FSCSI;
				if (period < 50) {
					/* On FAS366, if using fast-20 synchronous transfers
					 * we need to make sure the REQ/ACK assert/deassert
					 * control bits are clear.
					 */
					if (esp->erev == fashme)
						esp_dev->sync_max_offset &= ~esp->radelay;
					esp->config3[SCptr->device->id] |= bit;
				} else {
					esp->config3[SCptr->device->id] &= ~bit;
				}
				esp->prev_cfg3 = esp->config3[SCptr->device->id];
				sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
			}
			esp->prev_soff = esp_dev->sync_max_offset;
			esp->prev_stp = esp_dev->sync_min_period;
			sbus_writeb(esp->prev_soff, esp->eregs + ESP_SOFF);
			sbus_writeb(esp->prev_stp, esp->eregs + ESP_STP);
			ESPSDTR(("soff=%2x stp=%2x cfg3=%2x\n",
				 esp_dev->sync_max_offset,
				 esp_dev->sync_min_period,
				 esp->config3[SCptr->device->id]));

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

			/* back to async mode */
			ESPSDTR(("unaccaptable sync nego, forcing async\n"));
			esp_dev->sync_max_offset = 0;
			esp_dev->sync_min_period = 0;
			esp->prev_soff = 0;
			esp->prev_stp = 0;
			sbus_writeb(esp->prev_soff, esp->eregs + ESP_SOFF);
			sbus_writeb(esp->prev_stp, esp->eregs + ESP_STP);
			if (esp->erev == fas100a || esp->erev == fas236 || esp->erev == fashme) {
				if ((esp->erev == fas100a) || (esp->erev == fashme))
					bit = ESP_CONFIG3_FAST;
				else
					bit = ESP_CONFIG3_FSCSI;
				esp->config3[SCptr->device->id] &= ~bit;
				esp->prev_cfg3 = esp->config3[SCptr->device->id];
				sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
			}
		}

		sync_report(esp);

		ESPSDTR(("chk multibyte msg: sync is known, "));
		esp_dev->sync = 1;

		if (message_out) {
			ESPLOG(("esp%d: sending sdtr back, hoping for msgout\n",
				esp->esp_id));
			build_sync_nego_msg(esp, period, offset);
			esp_advance_phase(SCptr, in_the_dark);
			return EXTENDED_MESSAGE;
		}

		ESPSDTR(("returning zero\n"));
		esp_advance_phase(SCptr, in_the_dark); /* ...or else! */
		return 0;
	} else if (esp->cur_msgin[2] == EXTENDED_WDTR) {
		int size = 8 << esp->cur_msgin[3];

		esp->wnip = 0;
		if (esp->erev != fashme) {
			ESPLOG(("esp%d: AIEEE wide msg received and not HME.\n",
				esp->esp_id));
			message_out = MESSAGE_REJECT;
		} else if (size > 16) {
			ESPLOG(("esp%d: AIEEE wide transfer for %d size "
				"not supported.\n", esp->esp_id, size));
			message_out = MESSAGE_REJECT;
		} else {
			/* Things look good; let's see what we got. */
			if (size == 16) {
				/* Set config 3 register for this target. */
				esp->config3[SCptr->device->id] |= ESP_CONFIG3_EWIDE;
			} else {
				/* Just make sure it was one byte sized. */
				if (size != 8) {
					ESPLOG(("esp%d: Aieee, wide nego of %d size.\n",
						esp->esp_id, size));
					message_out = MESSAGE_REJECT;
					goto finish;
				}
				/* Pure paranoia. */
				esp->config3[SCptr->device->id] &= ~(ESP_CONFIG3_EWIDE);
			}
			esp->prev_cfg3 = esp->config3[SCptr->device->id];
			sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);

			/* Regardless, next try for sync transfers. */
			build_sync_nego_msg(esp, esp->sync_defp, 15);
			esp_dev->sync = 1;
			esp->snip = 1;
			message_out = EXTENDED_MESSAGE;
		}
	} else if (esp->cur_msgin[2] == EXTENDED_MODIFY_DATA_POINTER) {
		ESPLOG(("esp%d: rejecting modify data ptr msg\n", esp->esp_id));
		message_out = MESSAGE_REJECT;
	}
finish:
	esp_advance_phase(SCptr, in_the_dark);
	return message_out;
}

static int esp_do_msgindone(struct esp *esp)
{
	struct scsi_cmnd *SCptr = esp->current_SC;
	int message_out = 0, it = 0, rval;

	rval = skipahead1(esp, SCptr, in_msgin, in_msgindone);
	if (rval)
		return rval;
	if (SCptr->SCp.sent_command != in_status) {
		if (!(esp->ireg & ESP_INTR_DC)) {
			if (esp->msgin_len && (esp->sreg & ESP_STAT_PERR)) {
				message_out = MSG_PARITY_ERROR;
				esp_cmd(esp, ESP_CMD_FLUSH);
			} else if (esp->erev != fashme &&
			  (it = (sbus_readb(esp->eregs + ESP_FFLAGS) & ESP_FF_FBYTES)) != 1) {
				/* We certainly dropped the ball somewhere. */
				message_out = INITIATOR_ERROR;
				esp_cmd(esp, ESP_CMD_FLUSH);
			} else if (!esp->msgin_len) {
				if (esp->erev == fashme)
					it = esp->hme_fifo_workaround_buffer[0];
				else
					it = sbus_readb(esp->eregs + ESP_FDATA);
				esp_advance_phase(SCptr, in_msgincont);
			} else {
				/* it is ok and we want it */
				if (esp->erev == fashme)
					it = esp->cur_msgin[esp->msgin_ctr] =
						esp->hme_fifo_workaround_buffer[0];
				else
					it = esp->cur_msgin[esp->msgin_ctr] =
						sbus_readb(esp->eregs + ESP_FDATA);
				esp->msgin_ctr++;
			}
		} else {
			esp_advance_phase(SCptr, in_the_dark);
			return do_work_bus;
		}
	} else {
		it = esp->cur_msgin[0];
	}
	if (!message_out && esp->msgin_len) {
		if (esp->msgin_ctr < esp->msgin_len) {
			esp_advance_phase(SCptr, in_msgincont);
		} else if (esp->msgin_len == 1) {
			message_out = check_singlebyte_msg(esp);
		} else if (esp->msgin_len == 2) {
			if (esp->cur_msgin[0] == EXTENDED_MESSAGE) {
				if ((it + 2) >= 15) {
					message_out = MESSAGE_REJECT;
				} else {
					esp->msgin_len = (it + 2);
					esp_advance_phase(SCptr, in_msgincont);
				}
			} else {
				message_out = MESSAGE_REJECT; /* foo on you */
			}
		} else {
			message_out = check_multibyte_msg(esp);
		}
	}
	if (message_out < 0) {
		return -message_out;
	} else if (message_out) {
		if (((message_out != 1) &&
		     ((message_out < 0x20) || (message_out & 0x80))))
			esp->msgout_len = 1;
		esp->cur_msgout[0] = message_out;
		esp_cmd(esp, ESP_CMD_SATN);
		esp_advance_phase(SCptr, in_the_dark);
		esp->msgin_len = 0;
	}
	esp->sreg = sbus_readb(esp->eregs + ESP_STATUS);
	esp->sreg &= ~(ESP_STAT_INTR);
	if ((esp->sreg & (ESP_STAT_PMSG|ESP_STAT_PCD)) == (ESP_STAT_PMSG|ESP_STAT_PCD))
		esp_cmd(esp, ESP_CMD_MOK);
	if ((SCptr->SCp.sent_command == in_msgindone) &&
	    (SCptr->SCp.phase == in_freeing))
		return esp_do_freebus(esp);
	return do_intr_end;
}

static int esp_do_cmdbegin(struct esp *esp)
{
	struct scsi_cmnd *SCptr = esp->current_SC;

	esp_advance_phase(SCptr, in_cmdend);
	if (esp->erev == fashme) {
		u32 tmp = sbus_readl(esp->dregs + DMA_CSR);
		int i;

		for (i = 0; i < esp->esp_scmdleft; i++)
			esp->esp_command[i] = *esp->esp_scmdp++;
		esp->esp_scmdleft = 0;
		esp_cmd(esp, ESP_CMD_FLUSH);
		esp_setcount(esp->eregs, i, 1);
		esp_cmd(esp, (ESP_CMD_DMA | ESP_CMD_TI));
		tmp |= (DMA_SCSI_DISAB | DMA_ENABLE);
		tmp &= ~(DMA_ST_WRITE);
		sbus_writel(i, esp->dregs + DMA_COUNT);
		sbus_writel(esp->esp_command_dvma, esp->dregs + DMA_ADDR);
		sbus_writel(tmp, esp->dregs + DMA_CSR);
	} else {
		u8 tmp;

		esp_cmd(esp, ESP_CMD_FLUSH);
		tmp = *esp->esp_scmdp++;
		esp->esp_scmdleft--;
		sbus_writeb(tmp, esp->eregs + ESP_FDATA);
		esp_cmd(esp, ESP_CMD_TI);
	}
	return do_intr_end;
}

static int esp_do_cmddone(struct esp *esp)
{
	if (esp->erev == fashme)
		dma_invalidate(esp);
	else
		esp_cmd(esp, ESP_CMD_NULL);

	if (esp->ireg & ESP_INTR_BSERV) {
		esp_advance_phase(esp->current_SC, in_the_dark);
		return esp_do_phase_determine(esp);
	}

	ESPLOG(("esp%d: in do_cmddone() but didn't get BSERV interrupt.\n",
		esp->esp_id));
	return do_reset_bus;
}

static int esp_do_msgout(struct esp *esp)
{
	esp_cmd(esp, ESP_CMD_FLUSH);
	switch (esp->msgout_len) {
	case 1:
		if (esp->erev == fashme)
			hme_fifo_push(esp, &esp->cur_msgout[0], 1);
		else
			sbus_writeb(esp->cur_msgout[0], esp->eregs + ESP_FDATA);

		esp_cmd(esp, ESP_CMD_TI);
		break;

	case 2:
		esp->esp_command[0] = esp->cur_msgout[0];
		esp->esp_command[1] = esp->cur_msgout[1];

		if (esp->erev == fashme) {
			hme_fifo_push(esp, &esp->cur_msgout[0], 2);
			esp_cmd(esp, ESP_CMD_TI);
		} else {
			dma_setup(esp, esp->esp_command_dvma, 2, 0);
			esp_setcount(esp->eregs, 2, 0);
			esp_cmd(esp, ESP_CMD_DMA | ESP_CMD_TI);
		}
		break;

	case 4:
		esp->esp_command[0] = esp->cur_msgout[0];
		esp->esp_command[1] = esp->cur_msgout[1];
		esp->esp_command[2] = esp->cur_msgout[2];
		esp->esp_command[3] = esp->cur_msgout[3];
		esp->snip = 1;

		if (esp->erev == fashme) {
			hme_fifo_push(esp, &esp->cur_msgout[0], 4);
			esp_cmd(esp, ESP_CMD_TI);
		} else {
			dma_setup(esp, esp->esp_command_dvma, 4, 0);
			esp_setcount(esp->eregs, 4, 0);
			esp_cmd(esp, ESP_CMD_DMA | ESP_CMD_TI);
		}
		break;

	case 5:
		esp->esp_command[0] = esp->cur_msgout[0];
		esp->esp_command[1] = esp->cur_msgout[1];
		esp->esp_command[2] = esp->cur_msgout[2];
		esp->esp_command[3] = esp->cur_msgout[3];
		esp->esp_command[4] = esp->cur_msgout[4];
		esp->snip = 1;

		if (esp->erev == fashme) {
			hme_fifo_push(esp, &esp->cur_msgout[0], 5);
			esp_cmd(esp, ESP_CMD_TI);
		} else {
			dma_setup(esp, esp->esp_command_dvma, 5, 0);
			esp_setcount(esp->eregs, 5, 0);
			esp_cmd(esp, ESP_CMD_DMA | ESP_CMD_TI);
		}
		break;

	default:
		/* whoops */
		ESPMISC(("bogus msgout sending NOP\n"));
		esp->cur_msgout[0] = NOP;

		if (esp->erev == fashme) {
			hme_fifo_push(esp, &esp->cur_msgout[0], 1);
		} else {
			sbus_writeb(esp->cur_msgout[0], esp->eregs + ESP_FDATA);
		}

		esp->msgout_len = 1;
		esp_cmd(esp, ESP_CMD_TI);
		break;
	};

	esp_advance_phase(esp->current_SC, in_msgoutdone);
	return do_intr_end;
}

static int esp_do_msgoutdone(struct esp *esp)
{
	if (esp->msgout_len > 1) {
		/* XXX HME/FAS ATN deassert workaround required,
		 * XXX no DMA flushing, only possible ESP_CMD_FLUSH
		 * XXX to kill the fifo.
		 */
		if (esp->erev != fashme) {
			u32 tmp;

			while ((tmp = sbus_readl(esp->dregs + DMA_CSR)) & DMA_PEND_READ)
				udelay(1);
			tmp &= ~DMA_ENABLE;
			sbus_writel(tmp, esp->dregs + DMA_CSR);
			dma_invalidate(esp);
		} else {
			esp_cmd(esp, ESP_CMD_FLUSH);
		}
	}
	if (!(esp->ireg & ESP_INTR_DC)) {
		if (esp->erev != fashme)
			esp_cmd(esp, ESP_CMD_NULL);
		switch (esp->sreg & ESP_STAT_PMASK) {
		case ESP_MOP:
			/* whoops, parity error */
			ESPLOG(("esp%d: still in msgout, parity error assumed\n",
				esp->esp_id));
			if (esp->msgout_len > 1)
				esp_cmd(esp, ESP_CMD_SATN);
			esp_advance_phase(esp->current_SC, in_msgout);
			return do_work_bus;

		case ESP_DIP:
			break;

		default:
			/* Happy Meal fifo is touchy... */
			if ((esp->erev != fashme) &&
			    !fcount(esp) &&
			    !(((struct esp_device *)esp->current_SC->device->hostdata)->sync_max_offset))
				esp_cmd(esp, ESP_CMD_FLUSH);
			break;

		};
	} else {
		ESPLOG(("esp%d: disconnect, resetting bus\n", esp->esp_id));
		return do_reset_bus;
	}

	/* If we sent out a synchronous negotiation message, update
	 * our state.
	 */
	if (esp->cur_msgout[2] == EXTENDED_MESSAGE &&
	    esp->cur_msgout[4] == EXTENDED_SDTR) {
		esp->snip = 1; /* anal retentiveness... */
	}

	esp->prevmsgout = esp->cur_msgout[0];
	esp->msgout_len = 0;
	esp_advance_phase(esp->current_SC, in_the_dark);
	return esp_do_phase_determine(esp);
}

static int esp_bus_unexpected(struct esp *esp)
{
	ESPLOG(("esp%d: command in weird state %2x\n",
		esp->esp_id, esp->current_SC->SCp.phase));
	return do_reset_bus;
}

static espfunc_t bus_vector[] = {
	esp_do_data_finale,
	esp_do_data_finale,
	esp_bus_unexpected,
	esp_do_msgin,
	esp_do_msgincont,
	esp_do_msgindone,
	esp_do_msgout,
	esp_do_msgoutdone,
	esp_do_cmdbegin,
	esp_do_cmddone,
	esp_do_status,
	esp_do_freebus,
	esp_do_phase_determine,
	esp_bus_unexpected,
	esp_bus_unexpected,
	esp_bus_unexpected,
};

/* This is the second tier in our dual-level SCSI state machine. */
static int esp_work_bus(struct esp *esp)
{
	struct scsi_cmnd *SCptr = esp->current_SC;
	unsigned int phase;

	ESPBUS(("esp_work_bus: "));
	if (!SCptr) {
		ESPBUS(("reconnect\n"));
		return esp_do_reconnect(esp);
	}
	phase = SCptr->SCp.phase;
	if ((phase & 0xf0) == in_phases_mask)
		return bus_vector[(phase & 0x0f)](esp);
	else if ((phase & 0xf0) == in_slct_mask)
		return esp_select_complete(esp);
	else
		return esp_bus_unexpected(esp);
}

static espfunc_t isvc_vector[] = {
	NULL,
	esp_do_phase_determine,
	esp_do_resetbus,
	esp_finish_reset,
	esp_work_bus
};

/* Main interrupt handler for an esp adapter. */
static void esp_handle(struct esp *esp)
{
	struct scsi_cmnd *SCptr;
	int what_next = do_intr_end;

	SCptr = esp->current_SC;

	/* Check for errors. */
	esp->sreg = sbus_readb(esp->eregs + ESP_STATUS);
	esp->sreg &= (~ESP_STAT_INTR);
	if (esp->erev == fashme) {
		esp->sreg2 = sbus_readb(esp->eregs + ESP_STATUS2);
		esp->seqreg = (sbus_readb(esp->eregs + ESP_SSTEP) & ESP_STEP_VBITS);
	}

	if (esp->sreg & (ESP_STAT_SPAM)) {
		/* Gross error, could be due to one of:
		 *
		 * - top of fifo overwritten, could be because
		 *   we tried to do a synchronous transfer with
		 *   an offset greater than ESP fifo size
		 *
		 * - top of command register overwritten
		 *
		 * - DMA setup to go in one direction, SCSI
		 *   bus points in the other, whoops
		 *
		 * - weird phase change during asynchronous
		 *   data phase while we are initiator
		 */
		ESPLOG(("esp%d: Gross error sreg=%2x\n", esp->esp_id, esp->sreg));

		/* If a command is live on the bus we cannot safely
		 * reset the bus, so we'll just let the pieces fall
		 * where they may.  Here we are hoping that the
		 * target will be able to cleanly go away soon
		 * so we can safely reset things.
		 */
		if (!SCptr) {
			ESPLOG(("esp%d: No current cmd during gross error, "
				"resetting bus\n", esp->esp_id));
			what_next = do_reset_bus;
			goto state_machine;
		}
	}

	if (sbus_readl(esp->dregs + DMA_CSR) & DMA_HNDL_ERROR) {
		/* A DMA gate array error.  Here we must
		 * be seeing one of two things.  Either the
		 * virtual to physical address translation
		 * on the SBUS could not occur, else the
		 * translation it did get pointed to a bogus
		 * page.  Ho hum...
		 */
		ESPLOG(("esp%d: DMA error %08x\n", esp->esp_id,
			sbus_readl(esp->dregs + DMA_CSR)));

		/* DMA gate array itself must be reset to clear the
		 * error condition.
		 */
		esp_reset_dma(esp);

		what_next = do_reset_bus;
		goto state_machine;
	}

	esp->ireg = sbus_readb(esp->eregs + ESP_INTRPT);   /* Unlatch intr reg */

	if (esp->erev == fashme) {
		/* This chip is really losing. */
		ESPHME(("HME["));

		ESPHME(("sreg2=%02x,", esp->sreg2));
		/* Must latch fifo before reading the interrupt
		 * register else garbage ends up in the FIFO
		 * which confuses the driver utterly.
		 */
		if (!(esp->sreg2 & ESP_STAT2_FEMPTY) ||
		    (esp->sreg2 & ESP_STAT2_F1BYTE)) {
			ESPHME(("fifo_workaround]"));
			hme_fifo_read(esp);
		} else {
			ESPHME(("no_fifo_workaround]"));
		}
	}

	/* No current cmd is only valid at this point when there are
	 * commands off the bus or we are trying a reset.
	 */
	if (!SCptr && !esp->disconnected_SC && !(esp->ireg & ESP_INTR_SR)) {
		/* Panic is safe, since current_SC is null. */
		ESPLOG(("esp%d: no command in esp_handle()\n", esp->esp_id));
		panic("esp_handle: current_SC == penguin within interrupt!");
	}

	if (esp->ireg & (ESP_INTR_IC)) {
		/* Illegal command fed to ESP.  Outside of obvious
		 * software bugs that could cause this, there is
		 * a condition with esp100 where we can confuse the
		 * ESP into an erroneous illegal command interrupt
		 * because it does not scrape the FIFO properly
		 * for reselection.  See esp100_reconnect_hwbug()
		 * to see how we try very hard to avoid this.
		 */
		ESPLOG(("esp%d: invalid command\n", esp->esp_id));

		esp_dump_state(esp);

		if (SCptr != NULL) {
			/* Devices with very buggy firmware can drop BSY
			 * during a scatter list interrupt when using sync
			 * mode transfers.  We continue the transfer as
			 * expected, the target drops the bus, the ESP
			 * gets confused, and we get a illegal command
			 * interrupt because the bus is in the disconnected
			 * state now and ESP_CMD_TI is only allowed when
			 * a nexus is alive on the bus.
			 */
			ESPLOG(("esp%d: Forcing async and disabling disconnect for "
				"target %d\n", esp->esp_id, SCptr->device->id));
			SCptr->device->borken = 1; /* foo on you */
		}

		what_next = do_reset_bus;
	} else if (!(esp->ireg & ~(ESP_INTR_FDONE | ESP_INTR_BSERV | ESP_INTR_DC))) {
		if (SCptr) {
			unsigned int phase = SCptr->SCp.phase;

			if (phase & in_phases_mask) {
				what_next = esp_work_bus(esp);
			} else if (phase & in_slct_mask) {
				what_next = esp_select_complete(esp);
			} else {
				ESPLOG(("esp%d: interrupt for no good reason...\n",
					esp->esp_id));
				what_next = do_intr_end;
			}
		} else {
			ESPLOG(("esp%d: BSERV or FDONE or DC while SCptr==NULL\n",
				esp->esp_id));
			what_next = do_reset_bus;
		}
	} else if (esp->ireg & ESP_INTR_SR) {
		ESPLOG(("esp%d: SCSI bus reset interrupt\n", esp->esp_id));
		what_next = do_reset_complete;
	} else if (esp->ireg & (ESP_INTR_S | ESP_INTR_SATN)) {
		ESPLOG(("esp%d: AIEEE we have been selected by another initiator!\n",
			esp->esp_id));
		what_next = do_reset_bus;
	} else if (esp->ireg & ESP_INTR_RSEL) {
		if (SCptr == NULL) {
			/* This is ok. */
			what_next = esp_do_reconnect(esp);
		} else if (SCptr->SCp.phase & in_slct_mask) {
			/* Only selection code knows how to clean
			 * up properly.
			 */
			ESPDISC(("Reselected during selection attempt\n"));
			what_next = esp_select_complete(esp);
		} else {
			ESPLOG(("esp%d: Reselected while bus is busy\n",
				esp->esp_id));
			what_next = do_reset_bus;
		}
	}

	/* This is tier-one in our dual level SCSI state machine. */
state_machine:
	while (what_next != do_intr_end) {
		if (what_next >= do_phase_determine &&
		    what_next < do_intr_end) {
			what_next = isvc_vector[what_next](esp);
		} else {
			/* state is completely lost ;-( */
			ESPLOG(("esp%d: interrupt engine loses state, resetting bus\n",
				esp->esp_id));
			what_next = do_reset_bus;
		}
	}
}

/* Service only the ESP described by dev_id. */
static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
{
	struct esp *esp = dev_id;
	unsigned long flags;

	spin_lock_irqsave(esp->ehost->host_lock, flags);
	if (ESP_IRQ_P(esp->dregs)) {
		ESP_INTSOFF(esp->dregs);

		ESPIRQ(("I[%d:%d](", smp_processor_id(), esp->esp_id));
		esp_handle(esp);
		ESPIRQ((")"));

		ESP_INTSON(esp->dregs);
	}
	spin_unlock_irqrestore(esp->ehost->host_lock, flags);

	return IRQ_HANDLED;
}

static int esp_slave_alloc(struct scsi_device *SDptr)
{
	struct esp_device *esp_dev =
		kmalloc(sizeof(struct esp_device), GFP_ATOMIC);

	if (!esp_dev)
		return -ENOMEM;
	memset(esp_dev, 0, sizeof(struct esp_device));
	SDptr->hostdata = esp_dev;
	return 0;
}

static void esp_slave_destroy(struct scsi_device *SDptr)
{
	struct esp *esp = (struct esp *) SDptr->host->hostdata;

	esp->targets_present &= ~(1 << SDptr->id);
	kfree(SDptr->hostdata);
	SDptr->hostdata = NULL;
}

static struct scsi_host_template esp_template = {
	.module			= THIS_MODULE,
	.name			= "esp",
	.info			= esp_info,
	.slave_alloc		= esp_slave_alloc,
	.slave_destroy		= esp_slave_destroy,
	.queuecommand		= esp_queue,
	.eh_abort_handler	= esp_abort,
	.eh_bus_reset_handler	= esp_reset,
	.can_queue		= 7,
	.this_id		= 7,
	.sg_tablesize		= SG_ALL,
	.cmd_per_lun		= 1,
	.use_clustering		= ENABLE_CLUSTERING,
	.proc_name		= "esp",
	.proc_info		= esp_proc_info,
};

#ifndef CONFIG_SUN4
static struct of_device_id esp_match[] = {
	{
		.name = "SUNW,esp",
		.data = &esp_template,
	},
	{
		.name = "SUNW,fas",
		.data = &esp_template,
	},
	{
		.name = "esp",
		.data = &esp_template,
	},
	{},
};
MODULE_DEVICE_TABLE(of, esp_match);

static struct of_platform_driver esp_sbus_driver = {
	.name		= "esp",
	.match_table	= esp_match,
	.probe		= esp_sbus_probe,
	.remove		= __devexit_p(esp_sbus_remove),
};
#endif

static int __init esp_init(void)
{
#ifdef CONFIG_SUN4
	return esp_sun4_probe(&esp_template);
#else
	return of_register_driver(&esp_sbus_driver, &sbus_bus_type);
#endif
}

static void __exit esp_exit(void)
{
#ifdef CONFIG_SUN4
	esp_sun4_remove();
#else
	of_unregister_driver(&esp_sbus_driver);
#endif
}

MODULE_DESCRIPTION("ESP Sun SCSI driver");
MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

module_init(esp_init);
module_exit(esp_exit);
