/* esp_scsi.c: ESP SCSI driver.
 *
 * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/completion.h>
#include <linux/kallsyms.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/irqreturn.h>

#include <asm/irq.h>
#include <asm/io.h>
#include <asm/dma.h>

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

#include "esp_scsi.h"

#define DRV_MODULE_NAME		"esp"
#define PFX DRV_MODULE_NAME	": "
#define DRV_VERSION		"2.000"
#define DRV_MODULE_RELDATE	"April 19, 2007"

/* SCSI bus reset settle time in seconds.  */
static int esp_bus_reset_settle = 3;

static u32 esp_debug;
#define ESP_DEBUG_INTR		0x00000001
#define ESP_DEBUG_SCSICMD	0x00000002
#define ESP_DEBUG_RESET		0x00000004
#define ESP_DEBUG_MSGIN		0x00000008
#define ESP_DEBUG_MSGOUT	0x00000010
#define ESP_DEBUG_CMDDONE	0x00000020
#define ESP_DEBUG_DISCONNECT	0x00000040
#define ESP_DEBUG_DATASTART	0x00000080
#define ESP_DEBUG_DATADONE	0x00000100
#define ESP_DEBUG_RECONNECT	0x00000200
#define ESP_DEBUG_AUTOSENSE	0x00000400
#define ESP_DEBUG_EVENT		0x00000800
#define ESP_DEBUG_COMMAND	0x00001000

#define esp_log_intr(f, a...) \
do {	if (esp_debug & ESP_DEBUG_INTR) \
		shost_printk(KERN_DEBUG, esp->host, f, ## a);	\
} while (0)

#define esp_log_reset(f, a...) \
do {	if (esp_debug & ESP_DEBUG_RESET) \
		shost_printk(KERN_DEBUG, esp->host, f, ## a);	\
} while (0)

#define esp_log_msgin(f, a...) \
do {	if (esp_debug & ESP_DEBUG_MSGIN) \
		shost_printk(KERN_DEBUG, esp->host, f, ## a);	\
} while (0)

#define esp_log_msgout(f, a...) \
do {	if (esp_debug & ESP_DEBUG_MSGOUT) \
		shost_printk(KERN_DEBUG, esp->host, f, ## a);	\
} while (0)

#define esp_log_cmddone(f, a...) \
do {	if (esp_debug & ESP_DEBUG_CMDDONE) \
		shost_printk(KERN_DEBUG, esp->host, f, ## a);	\
} while (0)

#define esp_log_disconnect(f, a...) \
do {	if (esp_debug & ESP_DEBUG_DISCONNECT) \
		shost_printk(KERN_DEBUG, esp->host, f, ## a);	\
} while (0)

#define esp_log_datastart(f, a...) \
do {	if (esp_debug & ESP_DEBUG_DATASTART) \
		shost_printk(KERN_DEBUG, esp->host, f, ## a);	\
} while (0)

#define esp_log_datadone(f, a...) \
do {	if (esp_debug & ESP_DEBUG_DATADONE) \
		shost_printk(KERN_DEBUG, esp->host, f, ## a);	\
} while (0)

#define esp_log_reconnect(f, a...) \
do {	if (esp_debug & ESP_DEBUG_RECONNECT) \
		shost_printk(KERN_DEBUG, esp->host, f, ## a);	\
} while (0)

#define esp_log_autosense(f, a...) \
do {	if (esp_debug & ESP_DEBUG_AUTOSENSE) \
		shost_printk(KERN_DEBUG, esp->host, f, ## a);	\
} while (0)

#define esp_log_event(f, a...) \
do {   if (esp_debug & ESP_DEBUG_EVENT)	\
		shost_printk(KERN_DEBUG, esp->host, f, ## a);	\
} while (0)

#define esp_log_command(f, a...) \
do {   if (esp_debug & ESP_DEBUG_COMMAND)	\
		shost_printk(KERN_DEBUG, esp->host, f, ## a);	\
} while (0)

#define esp_read8(REG)		esp->ops->esp_read8(esp, REG)
#define esp_write8(VAL,REG)	esp->ops->esp_write8(esp, VAL, REG)

static void esp_log_fill_regs(struct esp *esp,
			      struct esp_event_ent *p)
{
	p->sreg = esp->sreg;
	p->seqreg = esp->seqreg;
	p->sreg2 = esp->sreg2;
	p->ireg = esp->ireg;
	p->select_state = esp->select_state;
	p->event = esp->event;
}

void scsi_esp_cmd(struct esp *esp, u8 val)
{
	struct esp_event_ent *p;
	int idx = esp->esp_event_cur;

	p = &esp->esp_event_log[idx];
	p->type = ESP_EVENT_TYPE_CMD;
	p->val = val;
	esp_log_fill_regs(esp, p);

	esp->esp_event_cur = (idx + 1) & (ESP_EVENT_LOG_SZ - 1);

	esp_log_command("cmd[%02x]\n", val);
	esp_write8(val, ESP_CMD);
}
EXPORT_SYMBOL(scsi_esp_cmd);

static void esp_send_dma_cmd(struct esp *esp, int len, int max_len, int cmd)
{
	if (esp->flags & ESP_FLAG_USE_FIFO) {
		int i;

		scsi_esp_cmd(esp, ESP_CMD_FLUSH);
		for (i = 0; i < len; i++)
			esp_write8(esp->command_block[i], ESP_FDATA);
		scsi_esp_cmd(esp, cmd);
	} else {
		if (esp->rev == FASHME)
			scsi_esp_cmd(esp, ESP_CMD_FLUSH);
		cmd |= ESP_CMD_DMA;
		esp->ops->send_dma_cmd(esp, esp->command_block_dma,
				       len, max_len, 0, cmd);
	}
}

static void esp_event(struct esp *esp, u8 val)
{
	struct esp_event_ent *p;
	int idx = esp->esp_event_cur;

	p = &esp->esp_event_log[idx];
	p->type = ESP_EVENT_TYPE_EVENT;
	p->val = val;
	esp_log_fill_regs(esp, p);

	esp->esp_event_cur = (idx + 1) & (ESP_EVENT_LOG_SZ - 1);

	esp->event = val;
}

static void esp_dump_cmd_log(struct esp *esp)
{
	int idx = esp->esp_event_cur;
	int stop = idx;

	shost_printk(KERN_INFO, esp->host, "Dumping command log\n");
	do {
		struct esp_event_ent *p = &esp->esp_event_log[idx];

		shost_printk(KERN_INFO, esp->host,
			     "ent[%d] %s val[%02x] sreg[%02x] seqreg[%02x] "
			     "sreg2[%02x] ireg[%02x] ss[%02x] event[%02x]\n",
			     idx,
			     p->type == ESP_EVENT_TYPE_CMD ? "CMD" : "EVENT",
			     p->val, p->sreg, p->seqreg,
			     p->sreg2, p->ireg, p->select_state, p->event);

		idx = (idx + 1) & (ESP_EVENT_LOG_SZ - 1);
	} while (idx != stop);
}

static void esp_flush_fifo(struct esp *esp)
{
	scsi_esp_cmd(esp, ESP_CMD_FLUSH);
	if (esp->rev == ESP236) {
		int lim = 1000;

		while (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES) {
			if (--lim == 0) {
				shost_printk(KERN_ALERT, esp->host,
					     "ESP_FF_BYTES will not clear!\n");
				break;
			}
			udelay(1);
		}
	}
}

static void hme_read_fifo(struct esp *esp)
{
	int fcnt = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES;
	int idx = 0;

	while (fcnt--) {
		esp->fifo[idx++] = esp_read8(ESP_FDATA);
		esp->fifo[idx++] = esp_read8(ESP_FDATA);
	}
	if (esp->sreg2 & ESP_STAT2_F1BYTE) {
		esp_write8(0, ESP_FDATA);
		esp->fifo[idx++] = esp_read8(ESP_FDATA);
		scsi_esp_cmd(esp, ESP_CMD_FLUSH);
	}
	esp->fifo_cnt = idx;
}

static void esp_set_all_config3(struct esp *esp, u8 val)
{
	int i;

	for (i = 0; i < ESP_MAX_TARGET; i++)
		esp->target[i].esp_config3 = val;
}

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

	/* Now reset the ESP chip */
	scsi_esp_cmd(esp, ESP_CMD_RC);
	scsi_esp_cmd(esp, ESP_CMD_NULL | ESP_CMD_DMA);
	if (esp->rev == FAST)
		esp_write8(ESP_CONFIG2_FENAB, ESP_CFG2);
	scsi_esp_cmd(esp, ESP_CMD_NULL | ESP_CMD_DMA);

	/* 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->rev == FAST) {
		version = esp_read8(ESP_UID);
		family_code = (version & 0xf8) >> 3;
		if (family_code == 0x02)
			esp->rev = FAS236;
		else if (family_code == 0x0a)
			esp->rev = FASHME; /* Version is usually '5'. */
		else
			esp->rev = FAS100A;
		esp->min_period = ((4 * esp->ccycle) / 1000);
	} else {
		esp->min_period = ((5 * esp->ccycle) / 1000);
	}
	if (esp->rev == FAS236) {
		/*
		 * The AM53c974 chip returns the same ID as FAS236;
		 * try to configure glitch eater.
		 */
		u8 config4 = ESP_CONFIG4_GE1;
		esp_write8(config4, ESP_CFG4);
		config4 = esp_read8(ESP_CFG4);
		if (config4 & ESP_CONFIG4_GE1) {
			esp->rev = PCSCSI;
			esp_write8(esp->config4, ESP_CFG4);
		}
	}
	esp->max_period = (esp->max_period + 3)>>2;
	esp->min_period = (esp->min_period + 3)>>2;

	esp_write8(esp->config1, ESP_CFG1);
	switch (esp->rev) {
	case ESP100:
		/* nothing to do */
		break;

	case ESP100A:
		esp_write8(esp->config2, ESP_CFG2);
		break;

	case ESP236:
		/* Slow 236 */
		esp_write8(esp->config2, ESP_CFG2);
		esp->prev_cfg3 = esp->target[0].esp_config3;
		esp_write8(esp->prev_cfg3, ESP_CFG3);
		break;

	case FASHME:
		esp->config2 |= (ESP_CONFIG2_HME32 | ESP_CONFIG2_HMEFENAB);
		/* fallthrough... */

	case FAS236:
	case PCSCSI:
		/* Fast 236, AM53c974 or HME */
		esp_write8(esp->config2, ESP_CFG2);
		if (esp->rev == FASHME) {
			u8 cfg3 = esp->target[0].esp_config3;

			cfg3 |= ESP_CONFIG3_FCLOCK | ESP_CONFIG3_OBPUSH;
			if (esp->scsi_id >= 8)
				cfg3 |= ESP_CONFIG3_IDBIT3;
			esp_set_all_config3(esp, cfg3);
		} else {
			u32 cfg3 = esp->target[0].esp_config3;

			cfg3 |= ESP_CONFIG3_FCLK;
			esp_set_all_config3(esp, cfg3);
		}
		esp->prev_cfg3 = esp->target[0].esp_config3;
		esp_write8(esp->prev_cfg3, ESP_CFG3);
		if (esp->rev == FASHME) {
			esp->radelay = 80;
		} else {
			if (esp->flags & ESP_FLAG_DIFFERENTIAL)
				esp->radelay = 0;
			else
				esp->radelay = 96;
		}
		break;

	case FAS100A:
		/* Fast 100a */
		esp_write8(esp->config2, ESP_CFG2);
		esp_set_all_config3(esp,
				    (esp->target[0].esp_config3 |
				     ESP_CONFIG3_FCLOCK));
		esp->prev_cfg3 = esp->target[0].esp_config3;
		esp_write8(esp->prev_cfg3, ESP_CFG3);
		esp->radelay = 32;
		break;

	default:
		break;
	}

	/* Reload the configuration registers */
	esp_write8(esp->cfact, ESP_CFACT);

	esp->prev_stp = 0;
	esp_write8(esp->prev_stp, ESP_STP);

	esp->prev_soff = 0;
	esp_write8(esp->prev_soff, ESP_SOFF);

	esp_write8(esp->neg_defp, ESP_TIMEO);

	/* Eat any bitrot in the chip */
	esp_read8(ESP_INTRPT);
	udelay(100);
}

static void esp_map_dma(struct esp *esp, struct scsi_cmnd *cmd)
{
	struct esp_cmd_priv *spriv = ESP_CMD_PRIV(cmd);
	struct scatterlist *sg = scsi_sglist(cmd);
	int total = 0, i;

	if (cmd->sc_data_direction == DMA_NONE)
		return;

	if (esp->flags & ESP_FLAG_NO_DMA_MAP) {
		/*
		 * For pseudo DMA and PIO we need the virtual address instead of
		 * a dma address, so perform an identity mapping.
		 */
		spriv->num_sg = scsi_sg_count(cmd);
		for (i = 0; i < spriv->num_sg; i++) {
			sg[i].dma_address = (uintptr_t)sg_virt(&sg[i]);
			total += sg_dma_len(&sg[i]);
		}
	} else {
		spriv->num_sg = scsi_dma_map(cmd);
		for (i = 0; i < spriv->num_sg; i++)
			total += sg_dma_len(&sg[i]);
	}
	spriv->cur_residue = sg_dma_len(sg);
	spriv->cur_sg = sg;
	spriv->tot_residue = total;
}

static dma_addr_t esp_cur_dma_addr(struct esp_cmd_entry *ent,
				   struct scsi_cmnd *cmd)
{
	struct esp_cmd_priv *p = ESP_CMD_PRIV(cmd);

	if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
		return ent->sense_dma +
			(ent->sense_ptr - cmd->sense_buffer);
	}

	return sg_dma_address(p->cur_sg) +
		(sg_dma_len(p->cur_sg) -
		 p->cur_residue);
}

static unsigned int esp_cur_dma_len(struct esp_cmd_entry *ent,
				    struct scsi_cmnd *cmd)
{
	struct esp_cmd_priv *p = ESP_CMD_PRIV(cmd);

	if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
		return SCSI_SENSE_BUFFERSIZE -
			(ent->sense_ptr - cmd->sense_buffer);
	}
	return p->cur_residue;
}

static void esp_advance_dma(struct esp *esp, struct esp_cmd_entry *ent,
			    struct scsi_cmnd *cmd, unsigned int len)
{
	struct esp_cmd_priv *p = ESP_CMD_PRIV(cmd);

	if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
		ent->sense_ptr += len;
		return;
	}

	p->cur_residue -= len;
	p->tot_residue -= len;
	if (p->cur_residue < 0 || p->tot_residue < 0) {
		shost_printk(KERN_ERR, esp->host,
			     "Data transfer overflow.\n");
		shost_printk(KERN_ERR, esp->host,
			     "cur_residue[%d] tot_residue[%d] len[%u]\n",
			     p->cur_residue, p->tot_residue, len);
		p->cur_residue = 0;
		p->tot_residue = 0;
	}
	if (!p->cur_residue && p->tot_residue) {
		p->cur_sg++;
		p->cur_residue = sg_dma_len(p->cur_sg);
	}
}

static void esp_unmap_dma(struct esp *esp, struct scsi_cmnd *cmd)
{
	if (!(esp->flags & ESP_FLAG_NO_DMA_MAP))
		scsi_dma_unmap(cmd);
}

static void esp_save_pointers(struct esp *esp, struct esp_cmd_entry *ent)
{
	struct scsi_cmnd *cmd = ent->cmd;
	struct esp_cmd_priv *spriv = ESP_CMD_PRIV(cmd);

	if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
		ent->saved_sense_ptr = ent->sense_ptr;
		return;
	}
	ent->saved_cur_residue = spriv->cur_residue;
	ent->saved_cur_sg = spriv->cur_sg;
	ent->saved_tot_residue = spriv->tot_residue;
}

static void esp_restore_pointers(struct esp *esp, struct esp_cmd_entry *ent)
{
	struct scsi_cmnd *cmd = ent->cmd;
	struct esp_cmd_priv *spriv = ESP_CMD_PRIV(cmd);

	if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
		ent->sense_ptr = ent->saved_sense_ptr;
		return;
	}
	spriv->cur_residue = ent->saved_cur_residue;
	spriv->cur_sg = ent->saved_cur_sg;
	spriv->tot_residue = ent->saved_tot_residue;
}

static void esp_write_tgt_config3(struct esp *esp, int tgt)
{
	if (esp->rev > ESP100A) {
		u8 val = esp->target[tgt].esp_config3;

		if (val != esp->prev_cfg3) {
			esp->prev_cfg3 = val;
			esp_write8(val, ESP_CFG3);
		}
	}
}

static void esp_write_tgt_sync(struct esp *esp, int tgt)
{
	u8 off = esp->target[tgt].esp_offset;
	u8 per = esp->target[tgt].esp_period;

	if (off != esp->prev_soff) {
		esp->prev_soff = off;
		esp_write8(off, ESP_SOFF);
	}
	if (per != esp->prev_stp) {
		esp->prev_stp = per;
		esp_write8(per, ESP_STP);
	}
}

static u32 esp_dma_length_limit(struct esp *esp, u32 dma_addr, u32 dma_len)
{
	if (esp->rev == FASHME) {
		/* Arbitrary segment boundaries, 24-bit counts.  */
		if (dma_len > (1U << 24))
			dma_len = (1U << 24);
	} else {
		u32 base, end;

		/* ESP chip limits other variants by 16-bits of transfer
		 * count.  Actually on FAS100A and FAS236 we could get
		 * 24-bits of transfer count by enabling ESP_CONFIG2_FENAB
		 * in the ESP_CFG2 register but that causes other unwanted
		 * changes so we don't use it currently.
		 */
		if (dma_len > (1U << 16))
			dma_len = (1U << 16);

		/* All of the DMA variants hooked up to these chips
		 * cannot handle crossing a 24-bit address boundary.
		 */
		base = dma_addr & ((1U << 24) - 1U);
		end = base + dma_len;
		if (end > (1U << 24))
			end = (1U <<24);
		dma_len = end - base;
	}
	return dma_len;
}

static int esp_need_to_nego_wide(struct esp_target_data *tp)
{
	struct scsi_target *target = tp->starget;

	return spi_width(target) != tp->nego_goal_width;
}

static int esp_need_to_nego_sync(struct esp_target_data *tp)
{
	struct scsi_target *target = tp->starget;

	/* When offset is zero, period is "don't care".  */
	if (!spi_offset(target) && !tp->nego_goal_offset)
		return 0;

	if (spi_offset(target) == tp->nego_goal_offset &&
	    spi_period(target) == tp->nego_goal_period)
		return 0;

	return 1;
}

static int esp_alloc_lun_tag(struct esp_cmd_entry *ent,
			     struct esp_lun_data *lp)
{
	if (!ent->orig_tag[0]) {
		/* Non-tagged, slot already taken?  */
		if (lp->non_tagged_cmd)
			return -EBUSY;

		if (lp->hold) {
			/* We are being held by active tagged
			 * commands.
			 */
			if (lp->num_tagged)
				return -EBUSY;

			/* Tagged commands completed, we can unplug
			 * the queue and run this untagged command.
			 */
			lp->hold = 0;
		} else if (lp->num_tagged) {
			/* Plug the queue until num_tagged decreases
			 * to zero in esp_free_lun_tag.
			 */
			lp->hold = 1;
			return -EBUSY;
		}

		lp->non_tagged_cmd = ent;
		return 0;
	}

	/* Tagged command. Check that it isn't blocked by a non-tagged one. */
	if (lp->non_tagged_cmd || lp->hold)
		return -EBUSY;

	BUG_ON(lp->tagged_cmds[ent->orig_tag[1]]);

	lp->tagged_cmds[ent->orig_tag[1]] = ent;
	lp->num_tagged++;

	return 0;
}

static void esp_free_lun_tag(struct esp_cmd_entry *ent,
			     struct esp_lun_data *lp)
{
	if (ent->orig_tag[0]) {
		BUG_ON(lp->tagged_cmds[ent->orig_tag[1]] != ent);
		lp->tagged_cmds[ent->orig_tag[1]] = NULL;
		lp->num_tagged--;
	} else {
		BUG_ON(lp->non_tagged_cmd != ent);
		lp->non_tagged_cmd = NULL;
	}
}

static void esp_map_sense(struct esp *esp, struct esp_cmd_entry *ent)
{
	ent->sense_ptr = ent->cmd->sense_buffer;
	if (esp->flags & ESP_FLAG_NO_DMA_MAP) {
		ent->sense_dma = (uintptr_t)ent->sense_ptr;
		return;
	}

	ent->sense_dma = dma_map_single(esp->dev, ent->sense_ptr,
					SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
}

static void esp_unmap_sense(struct esp *esp, struct esp_cmd_entry *ent)
{
	if (!(esp->flags & ESP_FLAG_NO_DMA_MAP))
		dma_unmap_single(esp->dev, ent->sense_dma,
				 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
	ent->sense_ptr = NULL;
}

/* When a contingent allegiance conditon is created, we force feed a
 * REQUEST_SENSE command to the device to fetch the sense data.  I
 * tried many other schemes, relying on the scsi error handling layer
 * to send out the REQUEST_SENSE automatically, but this was difficult
 * to get right especially in the presence of applications like smartd
 * which use SG_IO to send out their own REQUEST_SENSE commands.
 */
static void esp_autosense(struct esp *esp, struct esp_cmd_entry *ent)
{
	struct scsi_cmnd *cmd = ent->cmd;
	struct scsi_device *dev = cmd->device;
	int tgt, lun;
	u8 *p, val;

	tgt = dev->id;
	lun = dev->lun;


	if (!ent->sense_ptr) {
		esp_log_autosense("Doing auto-sense for tgt[%d] lun[%d]\n",
				  tgt, lun);
		esp_map_sense(esp, ent);
	}
	ent->saved_sense_ptr = ent->sense_ptr;

	esp->active_cmd = ent;

	p = esp->command_block;
	esp->msg_out_len = 0;

	*p++ = IDENTIFY(0, lun);
	*p++ = REQUEST_SENSE;
	*p++ = ((dev->scsi_level <= SCSI_2) ?
		(lun << 5) : 0);
	*p++ = 0;
	*p++ = 0;
	*p++ = SCSI_SENSE_BUFFERSIZE;
	*p++ = 0;

	esp->select_state = ESP_SELECT_BASIC;

	val = tgt;
	if (esp->rev == FASHME)
		val |= ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT;
	esp_write8(val, ESP_BUSID);

	esp_write_tgt_sync(esp, tgt);
	esp_write_tgt_config3(esp, tgt);

	val = (p - esp->command_block);

	esp_send_dma_cmd(esp, val, 16, ESP_CMD_SELA);
}

static struct esp_cmd_entry *find_and_prep_issuable_command(struct esp *esp)
{
	struct esp_cmd_entry *ent;

	list_for_each_entry(ent, &esp->queued_cmds, list) {
		struct scsi_cmnd *cmd = ent->cmd;
		struct scsi_device *dev = cmd->device;
		struct esp_lun_data *lp = dev->hostdata;

		if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
			ent->tag[0] = 0;
			ent->tag[1] = 0;
			return ent;
		}

		if (!spi_populate_tag_msg(&ent->tag[0], cmd)) {
			ent->tag[0] = 0;
			ent->tag[1] = 0;
		}
		ent->orig_tag[0] = ent->tag[0];
		ent->orig_tag[1] = ent->tag[1];

		if (esp_alloc_lun_tag(ent, lp) < 0)
			continue;

		return ent;
	}

	return NULL;
}

static void esp_maybe_execute_command(struct esp *esp)
{
	struct esp_target_data *tp;
	struct scsi_device *dev;
	struct scsi_cmnd *cmd;
	struct esp_cmd_entry *ent;
	bool select_and_stop = false;
	int tgt, lun, i;
	u32 val, start_cmd;
	u8 *p;

	if (esp->active_cmd ||
	    (esp->flags & ESP_FLAG_RESETTING))
		return;

	ent = find_and_prep_issuable_command(esp);
	if (!ent)
		return;

	if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
		esp_autosense(esp, ent);
		return;
	}

	cmd = ent->cmd;
	dev = cmd->device;
	tgt = dev->id;
	lun = dev->lun;
	tp = &esp->target[tgt];

	list_move(&ent->list, &esp->active_cmds);

	esp->active_cmd = ent;

	esp_map_dma(esp, cmd);
	esp_save_pointers(esp, ent);

	if (!(cmd->cmd_len == 6 || cmd->cmd_len == 10 || cmd->cmd_len == 12))
		select_and_stop = true;

	p = esp->command_block;

	esp->msg_out_len = 0;
	if (tp->flags & ESP_TGT_CHECK_NEGO) {
		/* Need to negotiate.  If the target is broken
		 * go for synchronous transfers and non-wide.
		 */
		if (tp->flags & ESP_TGT_BROKEN) {
			tp->flags &= ~ESP_TGT_DISCONNECT;
			tp->nego_goal_period = 0;
			tp->nego_goal_offset = 0;
			tp->nego_goal_width = 0;
			tp->nego_goal_tags = 0;
		}

		/* If the settings are not changing, skip this.  */
		if (spi_width(tp->starget) == tp->nego_goal_width &&
		    spi_period(tp->starget) == tp->nego_goal_period &&
		    spi_offset(tp->starget) == tp->nego_goal_offset) {
			tp->flags &= ~ESP_TGT_CHECK_NEGO;
			goto build_identify;
		}

		if (esp->rev == FASHME && esp_need_to_nego_wide(tp)) {
			esp->msg_out_len =
				spi_populate_width_msg(&esp->msg_out[0],
						       (tp->nego_goal_width ?
							1 : 0));
			tp->flags |= ESP_TGT_NEGO_WIDE;
		} else if (esp_need_to_nego_sync(tp)) {
			esp->msg_out_len =
				spi_populate_sync_msg(&esp->msg_out[0],
						      tp->nego_goal_period,
						      tp->nego_goal_offset);
			tp->flags |= ESP_TGT_NEGO_SYNC;
		} else {
			tp->flags &= ~ESP_TGT_CHECK_NEGO;
		}

		/* If there are multiple message bytes, use Select and Stop */
		if (esp->msg_out_len)
			select_and_stop = true;
	}

build_identify:
	*p++ = IDENTIFY(tp->flags & ESP_TGT_DISCONNECT, lun);

	if (ent->tag[0] && esp->rev == ESP100) {
		/* ESP100 lacks select w/atn3 command, use select
		 * and stop instead.
		 */
		select_and_stop = true;
	}

	if (select_and_stop) {
		esp->cmd_bytes_left = cmd->cmd_len;
		esp->cmd_bytes_ptr = &cmd->cmnd[0];

		if (ent->tag[0]) {
			for (i = esp->msg_out_len - 1;
			     i >= 0; i--)
				esp->msg_out[i + 2] = esp->msg_out[i];
			esp->msg_out[0] = ent->tag[0];
			esp->msg_out[1] = ent->tag[1];
			esp->msg_out_len += 2;
		}

		start_cmd = ESP_CMD_SELAS;
		esp->select_state = ESP_SELECT_MSGOUT;
	} else {
		start_cmd = ESP_CMD_SELA;
		if (ent->tag[0]) {
			*p++ = ent->tag[0];
			*p++ = ent->tag[1];

			start_cmd = ESP_CMD_SA3;
		}

		for (i = 0; i < cmd->cmd_len; i++)
			*p++ = cmd->cmnd[i];

		esp->select_state = ESP_SELECT_BASIC;
	}
	val = tgt;
	if (esp->rev == FASHME)
		val |= ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT;
	esp_write8(val, ESP_BUSID);

	esp_write_tgt_sync(esp, tgt);
	esp_write_tgt_config3(esp, tgt);

	val = (p - esp->command_block);

	if (esp_debug & ESP_DEBUG_SCSICMD) {
		printk("ESP: tgt[%d] lun[%d] scsi_cmd [ ", tgt, lun);
		for (i = 0; i < cmd->cmd_len; i++)
			printk("%02x ", cmd->cmnd[i]);
		printk("]\n");
	}

	esp_send_dma_cmd(esp, val, 16, start_cmd);
}

static struct esp_cmd_entry *esp_get_ent(struct esp *esp)
{
	struct list_head *head = &esp->esp_cmd_pool;
	struct esp_cmd_entry *ret;

	if (list_empty(head)) {
		ret = kzalloc(sizeof(struct esp_cmd_entry), GFP_ATOMIC);
	} else {
		ret = list_entry(head->next, struct esp_cmd_entry, list);
		list_del(&ret->list);
		memset(ret, 0, sizeof(*ret));
	}
	return ret;
}

static void esp_put_ent(struct esp *esp, struct esp_cmd_entry *ent)
{
	list_add(&ent->list, &esp->esp_cmd_pool);
}

static void esp_cmd_is_done(struct esp *esp, struct esp_cmd_entry *ent,
			    struct scsi_cmnd *cmd, unsigned int result)
{
	struct scsi_device *dev = cmd->device;
	int tgt = dev->id;
	int lun = dev->lun;

	esp->active_cmd = NULL;
	esp_unmap_dma(esp, cmd);
	esp_free_lun_tag(ent, dev->hostdata);
	cmd->result = result;

	if (ent->eh_done) {
		complete(ent->eh_done);
		ent->eh_done = NULL;
	}

	if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
		esp_unmap_sense(esp, ent);

		/* Restore the message/status bytes to what we actually
		 * saw originally.  Also, report that we are providing
		 * the sense data.
		 */
		cmd->result = ((DRIVER_SENSE << 24) |
			       (DID_OK << 16) |
			       (COMMAND_COMPLETE << 8) |
			       (SAM_STAT_CHECK_CONDITION << 0));

		ent->flags &= ~ESP_CMD_FLAG_AUTOSENSE;
		if (esp_debug & ESP_DEBUG_AUTOSENSE) {
			int i;

			printk("esp%d: tgt[%d] lun[%d] AUTO SENSE[ ",
			       esp->host->unique_id, tgt, lun);
			for (i = 0; i < 18; i++)
				printk("%02x ", cmd->sense_buffer[i]);
			printk("]\n");
		}
	}

	cmd->scsi_done(cmd);

	list_del(&ent->list);
	esp_put_ent(esp, ent);

	esp_maybe_execute_command(esp);
}

static unsigned int compose_result(unsigned int status, unsigned int message,
				   unsigned int driver_code)
{
	return (status | (message << 8) | (driver_code << 16));
}

static void esp_event_queue_full(struct esp *esp, struct esp_cmd_entry *ent)
{
	struct scsi_device *dev = ent->cmd->device;
	struct esp_lun_data *lp = dev->hostdata;

	scsi_track_queue_full(dev, lp->num_tagged - 1);
}

static int esp_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
	struct scsi_device *dev = cmd->device;
	struct esp *esp = shost_priv(dev->host);
	struct esp_cmd_priv *spriv;
	struct esp_cmd_entry *ent;

	ent = esp_get_ent(esp);
	if (!ent)
		return SCSI_MLQUEUE_HOST_BUSY;

	ent->cmd = cmd;

	cmd->scsi_done = done;

	spriv = ESP_CMD_PRIV(cmd);
	spriv->num_sg = 0;

	list_add_tail(&ent->list, &esp->queued_cmds);

	esp_maybe_execute_command(esp);

	return 0;
}

static DEF_SCSI_QCMD(esp_queuecommand)

static int esp_check_gross_error(struct esp *esp)
{
	if (esp->sreg & ESP_STAT_SPAM) {
		/* Gross Error, could be one of:
		 * - top of fifo overwritten
		 * - top of command register overwritten
		 * - DMA programmed with wrong direction
		 * - improper phase change
		 */
		shost_printk(KERN_ERR, esp->host,
			     "Gross error sreg[%02x]\n", esp->sreg);
		/* XXX Reset the chip. XXX */
		return 1;
	}
	return 0;
}

static int esp_check_spur_intr(struct esp *esp)
{
	switch (esp->rev) {
	case ESP100:
	case ESP100A:
		/* The interrupt pending bit of the status register cannot
		 * be trusted on these revisions.
		 */
		esp->sreg &= ~ESP_STAT_INTR;
		break;

	default:
		if (!(esp->sreg & ESP_STAT_INTR)) {
			if (esp->ireg & ESP_INTR_SR)
				return 1;

			/* If the DMA is indicating interrupt pending and the
			 * ESP is not, the only possibility is a DMA error.
			 */
			if (!esp->ops->dma_error(esp)) {
				shost_printk(KERN_ERR, esp->host,
					     "Spurious irq, sreg=%02x.\n",
					     esp->sreg);
				return -1;
			}

			shost_printk(KERN_ERR, esp->host, "DMA error\n");

			/* XXX Reset the chip. XXX */
			return -1;
		}
		break;
	}

	return 0;
}

static void esp_schedule_reset(struct esp *esp)
{
	esp_log_reset("esp_schedule_reset() from %pf\n",
		      __builtin_return_address(0));
	esp->flags |= ESP_FLAG_RESETTING;
	esp_event(esp, ESP_EVENT_RESET);
}

/* In order to avoid having to add a special half-reconnected state
 * into the driver we just sit here and poll through the rest of
 * the reselection process to get the tag message bytes.
 */
static struct esp_cmd_entry *esp_reconnect_with_tag(struct esp *esp,
						    struct esp_lun_data *lp)
{
	struct esp_cmd_entry *ent;
	int i;

	if (!lp->num_tagged) {
		shost_printk(KERN_ERR, esp->host,
			     "Reconnect w/num_tagged==0\n");
		return NULL;
	}

	esp_log_reconnect("reconnect tag, ");

	for (i = 0; i < ESP_QUICKIRQ_LIMIT; i++) {
		if (esp->ops->irq_pending(esp))
			break;
	}
	if (i == ESP_QUICKIRQ_LIMIT) {
		shost_printk(KERN_ERR, esp->host,
			     "Reconnect IRQ1 timeout\n");
		return NULL;
	}

	esp->sreg = esp_read8(ESP_STATUS);
	esp->ireg = esp_read8(ESP_INTRPT);

	esp_log_reconnect("IRQ(%d:%x:%x), ",
			  i, esp->ireg, esp->sreg);

	if (esp->ireg & ESP_INTR_DC) {
		shost_printk(KERN_ERR, esp->host,
			     "Reconnect, got disconnect.\n");
		return NULL;
	}

	if ((esp->sreg & ESP_STAT_PMASK) != ESP_MIP) {
		shost_printk(KERN_ERR, esp->host,
			     "Reconnect, not MIP sreg[%02x].\n", esp->sreg);
		return NULL;
	}

	/* DMA in the tag bytes... */
	esp->command_block[0] = 0xff;
	esp->command_block[1] = 0xff;
	esp->ops->send_dma_cmd(esp, esp->command_block_dma,
			       2, 2, 1, ESP_CMD_DMA | ESP_CMD_TI);

	/* ACK the message.  */
	scsi_esp_cmd(esp, ESP_CMD_MOK);

	for (i = 0; i < ESP_RESELECT_TAG_LIMIT; i++) {
		if (esp->ops->irq_pending(esp)) {
			esp->sreg = esp_read8(ESP_STATUS);
			esp->ireg = esp_read8(ESP_INTRPT);
			if (esp->ireg & ESP_INTR_FDONE)
				break;
		}
		udelay(1);
	}
	if (i == ESP_RESELECT_TAG_LIMIT) {
		shost_printk(KERN_ERR, esp->host, "Reconnect IRQ2 timeout\n");
		return NULL;
	}
	esp->ops->dma_drain(esp);
	esp->ops->dma_invalidate(esp);

	esp_log_reconnect("IRQ2(%d:%x:%x) tag[%x:%x]\n",
			  i, esp->ireg, esp->sreg,
			  esp->command_block[0],
			  esp->command_block[1]);

	if (esp->command_block[0] < SIMPLE_QUEUE_TAG ||
	    esp->command_block[0] > ORDERED_QUEUE_TAG) {
		shost_printk(KERN_ERR, esp->host,
			     "Reconnect, bad tag type %02x.\n",
			     esp->command_block[0]);
		return NULL;
	}

	ent = lp->tagged_cmds[esp->command_block[1]];
	if (!ent) {
		shost_printk(KERN_ERR, esp->host,
			     "Reconnect, no entry for tag %02x.\n",
			     esp->command_block[1]);
		return NULL;
	}

	return ent;
}

static int esp_reconnect(struct esp *esp)
{
	struct esp_cmd_entry *ent;
	struct esp_target_data *tp;
	struct esp_lun_data *lp;
	struct scsi_device *dev;
	int target, lun;

	BUG_ON(esp->active_cmd);
	if (esp->rev == FASHME) {
		/* FASHME puts the target and lun numbers directly
		 * into the fifo.
		 */
		target = esp->fifo[0];
		lun = esp->fifo[1] & 0x7;
	} else {
		u8 bits = esp_read8(ESP_FDATA);

		/* Older chips put the lun directly into the fifo, but
		 * the target is given as a sample of the arbitration
		 * lines on the bus at reselection time.  So we should
		 * see the ID of the ESP and the one reconnecting target
		 * set in the bitmap.
		 */
		if (!(bits & esp->scsi_id_mask))
			goto do_reset;
		bits &= ~esp->scsi_id_mask;
		if (!bits || (bits & (bits - 1)))
			goto do_reset;

		target = ffs(bits) - 1;
		lun = (esp_read8(ESP_FDATA) & 0x7);

		scsi_esp_cmd(esp, ESP_CMD_FLUSH);
		if (esp->rev == ESP100) {
			u8 ireg = esp_read8(ESP_INTRPT);
			/* This chip has a bug during reselection that can
			 * cause a spurious illegal-command interrupt, which
			 * we simply ACK here.  Another possibility is a bus
			 * reset so we must check for that.
			 */
			if (ireg & ESP_INTR_SR)
				goto do_reset;
		}
		scsi_esp_cmd(esp, ESP_CMD_NULL);
	}

	esp_write_tgt_sync(esp, target);
	esp_write_tgt_config3(esp, target);

	scsi_esp_cmd(esp, ESP_CMD_MOK);

	if (esp->rev == FASHME)
		esp_write8(target | ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT,
			   ESP_BUSID);

	tp = &esp->target[target];
	dev = __scsi_device_lookup_by_target(tp->starget, lun);
	if (!dev) {
		shost_printk(KERN_ERR, esp->host,
			     "Reconnect, no lp tgt[%u] lun[%u]\n",
			     target, lun);
		goto do_reset;
	}
	lp = dev->hostdata;

	ent = lp->non_tagged_cmd;
	if (!ent) {
		ent = esp_reconnect_with_tag(esp, lp);
		if (!ent)
			goto do_reset;
	}

	esp->active_cmd = ent;

	esp_event(esp, ESP_EVENT_CHECK_PHASE);
	esp_restore_pointers(esp, ent);
	esp->flags |= ESP_FLAG_QUICKIRQ_CHECK;
	return 1;

do_reset:
	esp_schedule_reset(esp);
	return 0;
}

static int esp_finish_select(struct esp *esp)
{
	struct esp_cmd_entry *ent;
	struct scsi_cmnd *cmd;

	/* No longer selecting.  */
	esp->select_state = ESP_SELECT_NONE;

	esp->seqreg = esp_read8(ESP_SSTEP) & ESP_STEP_VBITS;
	ent = esp->active_cmd;
	cmd = ent->cmd;

	if (esp->ops->dma_error(esp)) {
		/* If we see a DMA error during or as a result of selection,
		 * all bets are off.
		 */
		esp_schedule_reset(esp);
		esp_cmd_is_done(esp, ent, cmd, (DID_ERROR << 16));
		return 0;
	}

	esp->ops->dma_invalidate(esp);

	if (esp->ireg == (ESP_INTR_RSEL | ESP_INTR_FDONE)) {
		struct esp_target_data *tp = &esp->target[cmd->device->id];

		/* Carefully back out of the selection attempt.  Release
		 * resources (such as DMA mapping & TAG) and reset state (such
		 * as message out and command delivery variables).
		 */
		if (!(ent->flags & ESP_CMD_FLAG_AUTOSENSE)) {
			esp_unmap_dma(esp, cmd);
			esp_free_lun_tag(ent, cmd->device->hostdata);
			tp->flags &= ~(ESP_TGT_NEGO_SYNC | ESP_TGT_NEGO_WIDE);
			esp->cmd_bytes_ptr = NULL;
			esp->cmd_bytes_left = 0;
		} else {
			esp_unmap_sense(esp, ent);
		}

		/* Now that the state is unwound properly, put back onto
		 * the issue queue.  This command is no longer active.
		 */
		list_move(&ent->list, &esp->queued_cmds);
		esp->active_cmd = NULL;

		/* Return value ignored by caller, it directly invokes
		 * esp_reconnect().
		 */
		return 0;
	}

	if (esp->ireg == ESP_INTR_DC) {
		struct scsi_device *dev = cmd->device;

		/* Disconnect.  Make sure we re-negotiate sync and
		 * wide parameters if this target starts responding
		 * again in the future.
		 */
		esp->target[dev->id].flags |= ESP_TGT_CHECK_NEGO;

		scsi_esp_cmd(esp, ESP_CMD_ESEL);
		esp_cmd_is_done(esp, ent, cmd, (DID_BAD_TARGET << 16));
		return 1;
	}

	if (esp->ireg == (ESP_INTR_FDONE | ESP_INTR_BSERV)) {
		/* Selection successful.  On pre-FAST chips we have
		 * to do a NOP and possibly clean out the FIFO.
		 */
		if (esp->rev <= ESP236) {
			int fcnt = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES;

			scsi_esp_cmd(esp, ESP_CMD_NULL);

			if (!fcnt &&
			    (!esp->prev_soff ||
			     ((esp->sreg & ESP_STAT_PMASK) != ESP_DIP)))
				esp_flush_fifo(esp);
		}

		/* If we are doing a Select And Stop command, negotiation, etc.
		 * we'll do the right thing as we transition to the next phase.
		 */
		esp_event(esp, ESP_EVENT_CHECK_PHASE);
		return 0;
	}

	shost_printk(KERN_INFO, esp->host,
		     "Unexpected selection completion ireg[%x]\n", esp->ireg);
	esp_schedule_reset(esp);
	return 0;
}

static int esp_data_bytes_sent(struct esp *esp, struct esp_cmd_entry *ent,
			       struct scsi_cmnd *cmd)
{
	int fifo_cnt, ecount, bytes_sent, flush_fifo;

	fifo_cnt = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES;
	if (esp->prev_cfg3 & ESP_CONFIG3_EWIDE)
		fifo_cnt <<= 1;

	ecount = 0;
	if (!(esp->sreg & ESP_STAT_TCNT)) {
		ecount = ((unsigned int)esp_read8(ESP_TCLOW) |
			  (((unsigned int)esp_read8(ESP_TCMED)) << 8));
		if (esp->rev == FASHME)
			ecount |= ((unsigned int)esp_read8(FAS_RLO)) << 16;
		if (esp->rev == PCSCSI && (esp->config2 & ESP_CONFIG2_FENAB))
			ecount |= ((unsigned int)esp_read8(ESP_TCHI)) << 16;
	}

	bytes_sent = esp->data_dma_len;
	bytes_sent -= ecount;
	bytes_sent -= esp->send_cmd_residual;

	/*
	 * The am53c974 has a DMA 'pecularity'. The doc states:
	 * In some odd byte conditions, one residual byte will
	 * be left in the SCSI FIFO, and the FIFO Flags will
	 * never count to '0 '. When this happens, the residual
	 * byte should be retrieved via PIO following completion
	 * of the BLAST operation.
	 */
	if (fifo_cnt == 1 && ent->flags & ESP_CMD_FLAG_RESIDUAL) {
		size_t count = 1;
		size_t offset = bytes_sent;
		u8 bval = esp_read8(ESP_FDATA);

		if (ent->flags & ESP_CMD_FLAG_AUTOSENSE)
			ent->sense_ptr[bytes_sent] = bval;
		else {
			struct esp_cmd_priv *p = ESP_CMD_PRIV(cmd);
			u8 *ptr;

			ptr = scsi_kmap_atomic_sg(p->cur_sg, p->num_sg,
						  &offset, &count);
			if (likely(ptr)) {
				*(ptr + offset) = bval;
				scsi_kunmap_atomic_sg(ptr);
			}
		}
		bytes_sent += fifo_cnt;
		ent->flags &= ~ESP_CMD_FLAG_RESIDUAL;
	}
	if (!(ent->flags & ESP_CMD_FLAG_WRITE))
		bytes_sent -= fifo_cnt;

	flush_fifo = 0;
	if (!esp->prev_soff) {
		/* Synchronous data transfer, always flush fifo. */
		flush_fifo = 1;
	} else {
		if (esp->rev == ESP100) {
			u32 fflags, phase;

			/* ESP100 has a chip bug where in the synchronous data
			 * phase it can mistake a final long REQ pulse from the
			 * target as an extra data byte.  Fun.
			 *
			 * To detect this case we resample the status register
			 * and fifo flags.  If we're still in a data phase and
			 * we see spurious chunks in the fifo, we return error
			 * to the caller which should reset and set things up
			 * such that we only try future transfers to this
			 * target in synchronous mode.
			 */
			esp->sreg = esp_read8(ESP_STATUS);
			phase = esp->sreg & ESP_STAT_PMASK;
			fflags = esp_read8(ESP_FFLAGS);

			if ((phase == ESP_DOP &&
			     (fflags & ESP_FF_ONOTZERO)) ||
			    (phase == ESP_DIP &&
			     (fflags & ESP_FF_FBYTES)))
				return -1;
		}
		if (!(ent->flags & ESP_CMD_FLAG_WRITE))
			flush_fifo = 1;
	}

	if (flush_fifo)
		esp_flush_fifo(esp);

	return bytes_sent;
}

static void esp_setsync(struct esp *esp, struct esp_target_data *tp,
			u8 scsi_period, u8 scsi_offset,
			u8 esp_stp, u8 esp_soff)
{
	spi_period(tp->starget) = scsi_period;
	spi_offset(tp->starget) = scsi_offset;
	spi_width(tp->starget) = (tp->flags & ESP_TGT_WIDE) ? 1 : 0;

	if (esp_soff) {
		esp_stp &= 0x1f;
		esp_soff |= esp->radelay;
		if (esp->rev >= FAS236) {
			u8 bit = ESP_CONFIG3_FSCSI;
			if (esp->rev >= FAS100A)
				bit = ESP_CONFIG3_FAST;

			if (scsi_period < 50) {
				if (esp->rev == FASHME)
					esp_soff &= ~esp->radelay;
				tp->esp_config3 |= bit;
			} else {
				tp->esp_config3 &= ~bit;
			}
			esp->prev_cfg3 = tp->esp_config3;
			esp_write8(esp->prev_cfg3, ESP_CFG3);
		}
	}

	tp->esp_period = esp->prev_stp = esp_stp;
	tp->esp_offset = esp->prev_soff = esp_soff;

	esp_write8(esp_soff, ESP_SOFF);
	esp_write8(esp_stp, ESP_STP);

	tp->flags &= ~(ESP_TGT_NEGO_SYNC | ESP_TGT_CHECK_NEGO);

	spi_display_xfer_agreement(tp->starget);
}

static void esp_msgin_reject(struct esp *esp)
{
	struct esp_cmd_entry *ent = esp->active_cmd;
	struct scsi_cmnd *cmd = ent->cmd;
	struct esp_target_data *tp;
	int tgt;

	tgt = cmd->device->id;
	tp = &esp->target[tgt];

	if (tp->flags & ESP_TGT_NEGO_WIDE) {
		tp->flags &= ~(ESP_TGT_NEGO_WIDE | ESP_TGT_WIDE);

		if (!esp_need_to_nego_sync(tp)) {
			tp->flags &= ~ESP_TGT_CHECK_NEGO;
			scsi_esp_cmd(esp, ESP_CMD_RATN);
		} else {
			esp->msg_out_len =
				spi_populate_sync_msg(&esp->msg_out[0],
						      tp->nego_goal_period,
						      tp->nego_goal_offset);
			tp->flags |= ESP_TGT_NEGO_SYNC;
			scsi_esp_cmd(esp, ESP_CMD_SATN);
		}
		return;
	}

	if (tp->flags & ESP_TGT_NEGO_SYNC) {
		tp->flags &= ~(ESP_TGT_NEGO_SYNC | ESP_TGT_CHECK_NEGO);
		tp->esp_period = 0;
		tp->esp_offset = 0;
		esp_setsync(esp, tp, 0, 0, 0, 0);
		scsi_esp_cmd(esp, ESP_CMD_RATN);
		return;
	}

	shost_printk(KERN_INFO, esp->host, "Unexpected MESSAGE REJECT\n");
	esp_schedule_reset(esp);
}

static void esp_msgin_sdtr(struct esp *esp, struct esp_target_data *tp)
{
	u8 period = esp->msg_in[3];
	u8 offset = esp->msg_in[4];
	u8 stp;

	if (!(tp->flags & ESP_TGT_NEGO_SYNC))
		goto do_reject;

	if (offset > 15)
		goto do_reject;

	if (offset) {
		int one_clock;

		if (period > esp->max_period) {
			period = offset = 0;
			goto do_sdtr;
		}
		if (period < esp->min_period)
			goto do_reject;

		one_clock = esp->ccycle / 1000;
		stp = DIV_ROUND_UP(period << 2, one_clock);
		if (stp && esp->rev >= FAS236) {
			if (stp >= 50)
				stp--;
		}
	} else {
		stp = 0;
	}

	esp_setsync(esp, tp, period, offset, stp, offset);
	return;

do_reject:
	esp->msg_out[0] = MESSAGE_REJECT;
	esp->msg_out_len = 1;
	scsi_esp_cmd(esp, ESP_CMD_SATN);
	return;

do_sdtr:
	tp->nego_goal_period = period;
	tp->nego_goal_offset = offset;
	esp->msg_out_len =
		spi_populate_sync_msg(&esp->msg_out[0],
				      tp->nego_goal_period,
				      tp->nego_goal_offset);
	scsi_esp_cmd(esp, ESP_CMD_SATN);
}

static void esp_msgin_wdtr(struct esp *esp, struct esp_target_data *tp)
{
	int size = 8 << esp->msg_in[3];
	u8 cfg3;

	if (esp->rev != FASHME)
		goto do_reject;

	if (size != 8 && size != 16)
		goto do_reject;

	if (!(tp->flags & ESP_TGT_NEGO_WIDE))
		goto do_reject;

	cfg3 = tp->esp_config3;
	if (size == 16) {
		tp->flags |= ESP_TGT_WIDE;
		cfg3 |= ESP_CONFIG3_EWIDE;
	} else {
		tp->flags &= ~ESP_TGT_WIDE;
		cfg3 &= ~ESP_CONFIG3_EWIDE;
	}
	tp->esp_config3 = cfg3;
	esp->prev_cfg3 = cfg3;
	esp_write8(cfg3, ESP_CFG3);

	tp->flags &= ~ESP_TGT_NEGO_WIDE;

	spi_period(tp->starget) = 0;
	spi_offset(tp->starget) = 0;
	if (!esp_need_to_nego_sync(tp)) {
		tp->flags &= ~ESP_TGT_CHECK_NEGO;
		scsi_esp_cmd(esp, ESP_CMD_RATN);
	} else {
		esp->msg_out_len =
			spi_populate_sync_msg(&esp->msg_out[0],
					      tp->nego_goal_period,
					      tp->nego_goal_offset);
		tp->flags |= ESP_TGT_NEGO_SYNC;
		scsi_esp_cmd(esp, ESP_CMD_SATN);
	}
	return;

do_reject:
	esp->msg_out[0] = MESSAGE_REJECT;
	esp->msg_out_len = 1;
	scsi_esp_cmd(esp, ESP_CMD_SATN);
}

static void esp_msgin_extended(struct esp *esp)
{
	struct esp_cmd_entry *ent = esp->active_cmd;
	struct scsi_cmnd *cmd = ent->cmd;
	struct esp_target_data *tp;
	int tgt = cmd->device->id;

	tp = &esp->target[tgt];
	if (esp->msg_in[2] == EXTENDED_SDTR) {
		esp_msgin_sdtr(esp, tp);
		return;
	}
	if (esp->msg_in[2] == EXTENDED_WDTR) {
		esp_msgin_wdtr(esp, tp);
		return;
	}

	shost_printk(KERN_INFO, esp->host,
		     "Unexpected extended msg type %x\n", esp->msg_in[2]);

	esp->msg_out[0] = MESSAGE_REJECT;
	esp->msg_out_len = 1;
	scsi_esp_cmd(esp, ESP_CMD_SATN);
}

/* Analyze msgin bytes received from target so far.  Return non-zero
 * if there are more bytes needed to complete the message.
 */
static int esp_msgin_process(struct esp *esp)
{
	u8 msg0 = esp->msg_in[0];
	int len = esp->msg_in_len;

	if (msg0 & 0x80) {
		/* Identify */
		shost_printk(KERN_INFO, esp->host,
			     "Unexpected msgin identify\n");
		return 0;
	}

	switch (msg0) {
	case EXTENDED_MESSAGE:
		if (len == 1)
			return 1;
		if (len < esp->msg_in[1] + 2)
			return 1;
		esp_msgin_extended(esp);
		return 0;

	case IGNORE_WIDE_RESIDUE: {
		struct esp_cmd_entry *ent;
		struct esp_cmd_priv *spriv;
		if (len == 1)
			return 1;

		if (esp->msg_in[1] != 1)
			goto do_reject;

		ent = esp->active_cmd;
		spriv = ESP_CMD_PRIV(ent->cmd);

		if (spriv->cur_residue == sg_dma_len(spriv->cur_sg)) {
			spriv->cur_sg--;
			spriv->cur_residue = 1;
		} else
			spriv->cur_residue++;
		spriv->tot_residue++;
		return 0;
	}
	case NOP:
		return 0;
	case RESTORE_POINTERS:
		esp_restore_pointers(esp, esp->active_cmd);
		return 0;
	case SAVE_POINTERS:
		esp_save_pointers(esp, esp->active_cmd);
		return 0;

	case COMMAND_COMPLETE:
	case DISCONNECT: {
		struct esp_cmd_entry *ent = esp->active_cmd;

		ent->message = msg0;
		esp_event(esp, ESP_EVENT_FREE_BUS);
		esp->flags |= ESP_FLAG_QUICKIRQ_CHECK;
		return 0;
	}
	case MESSAGE_REJECT:
		esp_msgin_reject(esp);
		return 0;

	default:
	do_reject:
		esp->msg_out[0] = MESSAGE_REJECT;
		esp->msg_out_len = 1;
		scsi_esp_cmd(esp, ESP_CMD_SATN);
		return 0;
	}
}

static int esp_process_event(struct esp *esp)
{
	int write, i;

again:
	write = 0;
	esp_log_event("process event %d phase %x\n",
		      esp->event, esp->sreg & ESP_STAT_PMASK);
	switch (esp->event) {
	case ESP_EVENT_CHECK_PHASE:
		switch (esp->sreg & ESP_STAT_PMASK) {
		case ESP_DOP:
			esp_event(esp, ESP_EVENT_DATA_OUT);
			break;
		case ESP_DIP:
			esp_event(esp, ESP_EVENT_DATA_IN);
			break;
		case ESP_STATP:
			esp_flush_fifo(esp);
			scsi_esp_cmd(esp, ESP_CMD_ICCSEQ);
			esp_event(esp, ESP_EVENT_STATUS);
			esp->flags |= ESP_FLAG_QUICKIRQ_CHECK;
			return 1;

		case ESP_MOP:
			esp_event(esp, ESP_EVENT_MSGOUT);
			break;

		case ESP_MIP:
			esp_event(esp, ESP_EVENT_MSGIN);
			break;

		case ESP_CMDP:
			esp_event(esp, ESP_EVENT_CMD_START);
			break;

		default:
			shost_printk(KERN_INFO, esp->host,
				     "Unexpected phase, sreg=%02x\n",
				     esp->sreg);
			esp_schedule_reset(esp);
			return 0;
		}
		goto again;

	case ESP_EVENT_DATA_IN:
		write = 1;
		/* fallthru */

	case ESP_EVENT_DATA_OUT: {
		struct esp_cmd_entry *ent = esp->active_cmd;
		struct scsi_cmnd *cmd = ent->cmd;
		dma_addr_t dma_addr = esp_cur_dma_addr(ent, cmd);
		unsigned int dma_len = esp_cur_dma_len(ent, cmd);

		if (esp->rev == ESP100)
			scsi_esp_cmd(esp, ESP_CMD_NULL);

		if (write)
			ent->flags |= ESP_CMD_FLAG_WRITE;
		else
			ent->flags &= ~ESP_CMD_FLAG_WRITE;

		if (esp->ops->dma_length_limit)
			dma_len = esp->ops->dma_length_limit(esp, dma_addr,
							     dma_len);
		else
			dma_len = esp_dma_length_limit(esp, dma_addr, dma_len);

		esp->data_dma_len = dma_len;

		if (!dma_len) {
			shost_printk(KERN_ERR, esp->host,
				     "DMA length is zero!\n");
			shost_printk(KERN_ERR, esp->host,
				     "cur adr[%08llx] len[%08x]\n",
				     (unsigned long long)esp_cur_dma_addr(ent, cmd),
				     esp_cur_dma_len(ent, cmd));
			esp_schedule_reset(esp);
			return 0;
		}

		esp_log_datastart("start data addr[%08llx] len[%u] write(%d)\n",
				  (unsigned long long)dma_addr, dma_len, write);

		esp->ops->send_dma_cmd(esp, dma_addr, dma_len, dma_len,
				       write, ESP_CMD_DMA | ESP_CMD_TI);
		esp_event(esp, ESP_EVENT_DATA_DONE);
		break;
	}
	case ESP_EVENT_DATA_DONE: {
		struct esp_cmd_entry *ent = esp->active_cmd;
		struct scsi_cmnd *cmd = ent->cmd;
		int bytes_sent;

		if (esp->ops->dma_error(esp)) {
			shost_printk(KERN_INFO, esp->host,
				     "data done, DMA error, resetting\n");
			esp_schedule_reset(esp);
			return 0;
		}

		if (ent->flags & ESP_CMD_FLAG_WRITE) {
			/* XXX parity errors, etc. XXX */

			esp->ops->dma_drain(esp);
		}
		esp->ops->dma_invalidate(esp);

		if (esp->ireg != ESP_INTR_BSERV) {
			/* We should always see exactly a bus-service
			 * interrupt at the end of a successful transfer.
			 */
			shost_printk(KERN_INFO, esp->host,
				     "data done, not BSERV, resetting\n");
			esp_schedule_reset(esp);
			return 0;
		}

		bytes_sent = esp_data_bytes_sent(esp, ent, cmd);

		esp_log_datadone("data done flgs[%x] sent[%d]\n",
				 ent->flags, bytes_sent);

		if (bytes_sent < 0) {
			/* XXX force sync mode for this target XXX */
			esp_schedule_reset(esp);
			return 0;
		}

		esp_advance_dma(esp, ent, cmd, bytes_sent);
		esp_event(esp, ESP_EVENT_CHECK_PHASE);
		goto again;
	}

	case ESP_EVENT_STATUS: {
		struct esp_cmd_entry *ent = esp->active_cmd;

		if (esp->ireg & ESP_INTR_FDONE) {
			ent->status = esp_read8(ESP_FDATA);
			ent->message = esp_read8(ESP_FDATA);
			scsi_esp_cmd(esp, ESP_CMD_MOK);
		} else if (esp->ireg == ESP_INTR_BSERV) {
			ent->status = esp_read8(ESP_FDATA);
			ent->message = 0xff;
			esp_event(esp, ESP_EVENT_MSGIN);
			return 0;
		}

		if (ent->message != COMMAND_COMPLETE) {
			shost_printk(KERN_INFO, esp->host,
				     "Unexpected message %x in status\n",
				     ent->message);
			esp_schedule_reset(esp);
			return 0;
		}

		esp_event(esp, ESP_EVENT_FREE_BUS);
		esp->flags |= ESP_FLAG_QUICKIRQ_CHECK;
		break;
	}
	case ESP_EVENT_FREE_BUS: {
		struct esp_cmd_entry *ent = esp->active_cmd;
		struct scsi_cmnd *cmd = ent->cmd;

		if (ent->message == COMMAND_COMPLETE ||
		    ent->message == DISCONNECT)
			scsi_esp_cmd(esp, ESP_CMD_ESEL);

		if (ent->message == COMMAND_COMPLETE) {
			esp_log_cmddone("Command done status[%x] message[%x]\n",
					ent->status, ent->message);
			if (ent->status == SAM_STAT_TASK_SET_FULL)
				esp_event_queue_full(esp, ent);

			if (ent->status == SAM_STAT_CHECK_CONDITION &&
			    !(ent->flags & ESP_CMD_FLAG_AUTOSENSE)) {
				ent->flags |= ESP_CMD_FLAG_AUTOSENSE;
				esp_autosense(esp, ent);
			} else {
				esp_cmd_is_done(esp, ent, cmd,
						compose_result(ent->status,
							       ent->message,
							       DID_OK));
			}
		} else if (ent->message == DISCONNECT) {
			esp_log_disconnect("Disconnecting tgt[%d] tag[%x:%x]\n",
					   cmd->device->id,
					   ent->tag[0], ent->tag[1]);

			esp->active_cmd = NULL;
			esp_maybe_execute_command(esp);
		} else {
			shost_printk(KERN_INFO, esp->host,
				     "Unexpected message %x in freebus\n",
				     ent->message);
			esp_schedule_reset(esp);
			return 0;
		}
		if (esp->active_cmd)
			esp->flags |= ESP_FLAG_QUICKIRQ_CHECK;
		break;
	}
	case ESP_EVENT_MSGOUT: {
		scsi_esp_cmd(esp, ESP_CMD_FLUSH);

		if (esp_debug & ESP_DEBUG_MSGOUT) {
			int i;
			printk("ESP: Sending message [ ");
			for (i = 0; i < esp->msg_out_len; i++)
				printk("%02x ", esp->msg_out[i]);
			printk("]\n");
		}

		if (esp->rev == FASHME) {
			int i;

			/* Always use the fifo.  */
			for (i = 0; i < esp->msg_out_len; i++) {
				esp_write8(esp->msg_out[i], ESP_FDATA);
				esp_write8(0, ESP_FDATA);
			}
			scsi_esp_cmd(esp, ESP_CMD_TI);
		} else {
			if (esp->msg_out_len == 1) {
				esp_write8(esp->msg_out[0], ESP_FDATA);
				scsi_esp_cmd(esp, ESP_CMD_TI);
			} else if (esp->flags & ESP_FLAG_USE_FIFO) {
				for (i = 0; i < esp->msg_out_len; i++)
					esp_write8(esp->msg_out[i], ESP_FDATA);
				scsi_esp_cmd(esp, ESP_CMD_TI);
			} else {
				/* Use DMA. */
				memcpy(esp->command_block,
				       esp->msg_out,
				       esp->msg_out_len);

				esp->ops->send_dma_cmd(esp,
						       esp->command_block_dma,
						       esp->msg_out_len,
						       esp->msg_out_len,
						       0,
						       ESP_CMD_DMA|ESP_CMD_TI);
			}
		}
		esp_event(esp, ESP_EVENT_MSGOUT_DONE);
		break;
	}
	case ESP_EVENT_MSGOUT_DONE:
		if (esp->rev == FASHME) {
			scsi_esp_cmd(esp, ESP_CMD_FLUSH);
		} else {
			if (esp->msg_out_len > 1)
				esp->ops->dma_invalidate(esp);

			/* XXX if the chip went into disconnected mode,
			 * we can't run the phase state machine anyway.
			 */
			if (!(esp->ireg & ESP_INTR_DC))
				scsi_esp_cmd(esp, ESP_CMD_NULL);
		}

		esp->msg_out_len = 0;

		esp_event(esp, ESP_EVENT_CHECK_PHASE);
		goto again;
	case ESP_EVENT_MSGIN:
		if (esp->ireg & ESP_INTR_BSERV) {
			if (esp->rev == FASHME) {
				if (!(esp_read8(ESP_STATUS2) &
				      ESP_STAT2_FEMPTY))
					scsi_esp_cmd(esp, ESP_CMD_FLUSH);
			} else {
				scsi_esp_cmd(esp, ESP_CMD_FLUSH);
				if (esp->rev == ESP100)
					scsi_esp_cmd(esp, ESP_CMD_NULL);
			}
			scsi_esp_cmd(esp, ESP_CMD_TI);
			esp->flags |= ESP_FLAG_QUICKIRQ_CHECK;
			return 1;
		}
		if (esp->ireg & ESP_INTR_FDONE) {
			u8 val;

			if (esp->rev == FASHME)
				val = esp->fifo[0];
			else
				val = esp_read8(ESP_FDATA);
			esp->msg_in[esp->msg_in_len++] = val;

			esp_log_msgin("Got msgin byte %x\n", val);

			if (!esp_msgin_process(esp))
				esp->msg_in_len = 0;

			if (esp->rev == FASHME)
				scsi_esp_cmd(esp, ESP_CMD_FLUSH);

			scsi_esp_cmd(esp, ESP_CMD_MOK);

			/* Check whether a bus reset is to be done next */
			if (esp->event == ESP_EVENT_RESET)
				return 0;

			if (esp->event != ESP_EVENT_FREE_BUS)
				esp_event(esp, ESP_EVENT_CHECK_PHASE);
		} else {
			shost_printk(KERN_INFO, esp->host,
				     "MSGIN neither BSERV not FDON, resetting");
			esp_schedule_reset(esp);
			return 0;
		}
		break;
	case ESP_EVENT_CMD_START:
		memcpy(esp->command_block, esp->cmd_bytes_ptr,
		       esp->cmd_bytes_left);
		esp_send_dma_cmd(esp, esp->cmd_bytes_left, 16, ESP_CMD_TI);
		esp_event(esp, ESP_EVENT_CMD_DONE);
		esp->flags |= ESP_FLAG_QUICKIRQ_CHECK;
		break;
	case ESP_EVENT_CMD_DONE:
		esp->ops->dma_invalidate(esp);
		if (esp->ireg & ESP_INTR_BSERV) {
			esp_event(esp, ESP_EVENT_CHECK_PHASE);
			goto again;
		}
		esp_schedule_reset(esp);
		return 0;

	case ESP_EVENT_RESET:
		scsi_esp_cmd(esp, ESP_CMD_RS);
		break;

	default:
		shost_printk(KERN_INFO, esp->host,
			     "Unexpected event %x, resetting\n", esp->event);
		esp_schedule_reset(esp);
		return 0;
	}
	return 1;
}

static void esp_reset_cleanup_one(struct esp *esp, struct esp_cmd_entry *ent)
{
	struct scsi_cmnd *cmd = ent->cmd;

	esp_unmap_dma(esp, cmd);
	esp_free_lun_tag(ent, cmd->device->hostdata);
	cmd->result = DID_RESET << 16;

	if (ent->flags & ESP_CMD_FLAG_AUTOSENSE)
		esp_unmap_sense(esp, ent);

	cmd->scsi_done(cmd);
	list_del(&ent->list);
	esp_put_ent(esp, ent);
}

static void esp_clear_hold(struct scsi_device *dev, void *data)
{
	struct esp_lun_data *lp = dev->hostdata;

	BUG_ON(lp->num_tagged);
	lp->hold = 0;
}

static void esp_reset_cleanup(struct esp *esp)
{
	struct esp_cmd_entry *ent, *tmp;
	int i;

	list_for_each_entry_safe(ent, tmp, &esp->queued_cmds, list) {
		struct scsi_cmnd *cmd = ent->cmd;

		list_del(&ent->list);
		cmd->result = DID_RESET << 16;
		cmd->scsi_done(cmd);
		esp_put_ent(esp, ent);
	}

	list_for_each_entry_safe(ent, tmp, &esp->active_cmds, list) {
		if (ent == esp->active_cmd)
			esp->active_cmd = NULL;
		esp_reset_cleanup_one(esp, ent);
	}

	BUG_ON(esp->active_cmd != NULL);

	/* Force renegotiation of sync/wide transfers.  */
	for (i = 0; i < ESP_MAX_TARGET; i++) {
		struct esp_target_data *tp = &esp->target[i];

		tp->esp_period = 0;
		tp->esp_offset = 0;
		tp->esp_config3 &= ~(ESP_CONFIG3_EWIDE |
				     ESP_CONFIG3_FSCSI |
				     ESP_CONFIG3_FAST);
		tp->flags &= ~ESP_TGT_WIDE;
		tp->flags |= ESP_TGT_CHECK_NEGO;

		if (tp->starget)
			__starget_for_each_device(tp->starget, NULL,
						  esp_clear_hold);
	}
	esp->flags &= ~ESP_FLAG_RESETTING;
}

/* Runs under host->lock */
static void __esp_interrupt(struct esp *esp)
{
	int finish_reset, intr_done;
	u8 phase;

       /*
	* Once INTRPT is read STATUS and SSTEP are cleared.
	*/
	esp->sreg = esp_read8(ESP_STATUS);
	esp->seqreg = esp_read8(ESP_SSTEP);
	esp->ireg = esp_read8(ESP_INTRPT);

	if (esp->flags & ESP_FLAG_RESETTING) {
		finish_reset = 1;
	} else {
		if (esp_check_gross_error(esp))
			return;

		finish_reset = esp_check_spur_intr(esp);
		if (finish_reset < 0)
			return;
	}

	if (esp->ireg & ESP_INTR_SR)
		finish_reset = 1;

	if (finish_reset) {
		esp_reset_cleanup(esp);
		if (esp->eh_reset) {
			complete(esp->eh_reset);
			esp->eh_reset = NULL;
		}
		return;
	}

	phase = (esp->sreg & ESP_STAT_PMASK);
	if (esp->rev == FASHME) {
		if (((phase != ESP_DIP && phase != ESP_DOP) &&
		     esp->select_state == ESP_SELECT_NONE &&
		     esp->event != ESP_EVENT_STATUS &&
		     esp->event != ESP_EVENT_DATA_DONE) ||
		    (esp->ireg & ESP_INTR_RSEL)) {
			esp->sreg2 = esp_read8(ESP_STATUS2);
			if (!(esp->sreg2 & ESP_STAT2_FEMPTY) ||
			    (esp->sreg2 & ESP_STAT2_F1BYTE))
				hme_read_fifo(esp);
		}
	}

	esp_log_intr("intr sreg[%02x] seqreg[%02x] "
		     "sreg2[%02x] ireg[%02x]\n",
		     esp->sreg, esp->seqreg, esp->sreg2, esp->ireg);

	intr_done = 0;

	if (esp->ireg & (ESP_INTR_S | ESP_INTR_SATN | ESP_INTR_IC)) {
		shost_printk(KERN_INFO, esp->host,
			     "unexpected IREG %02x\n", esp->ireg);
		if (esp->ireg & ESP_INTR_IC)
			esp_dump_cmd_log(esp);

		esp_schedule_reset(esp);
	} else {
		if (esp->ireg & ESP_INTR_RSEL) {
			if (esp->active_cmd)
				(void) esp_finish_select(esp);
			intr_done = esp_reconnect(esp);
		} else {
			/* Some combination of FDONE, BSERV, DC. */
			if (esp->select_state != ESP_SELECT_NONE)
				intr_done = esp_finish_select(esp);
		}
	}
	while (!intr_done)
		intr_done = esp_process_event(esp);
}

irqreturn_t scsi_esp_intr(int irq, void *dev_id)
{
	struct esp *esp = dev_id;
	unsigned long flags;
	irqreturn_t ret;

	spin_lock_irqsave(esp->host->host_lock, flags);
	ret = IRQ_NONE;
	if (esp->ops->irq_pending(esp)) {
		ret = IRQ_HANDLED;
		for (;;) {
			int i;

			__esp_interrupt(esp);
			if (!(esp->flags & ESP_FLAG_QUICKIRQ_CHECK))
				break;
			esp->flags &= ~ESP_FLAG_QUICKIRQ_CHECK;

			for (i = 0; i < ESP_QUICKIRQ_LIMIT; i++) {
				if (esp->ops->irq_pending(esp))
					break;
			}
			if (i == ESP_QUICKIRQ_LIMIT)
				break;
		}
	}
	spin_unlock_irqrestore(esp->host->host_lock, flags);

	return ret;
}
EXPORT_SYMBOL(scsi_esp_intr);

static void esp_get_revision(struct esp *esp)
{
	u8 val;

	esp->config1 = (ESP_CONFIG1_PENABLE | (esp->scsi_id & 7));
	if (esp->config2 == 0) {
		esp->config2 = (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY);
		esp_write8(esp->config2, ESP_CFG2);

		val = esp_read8(ESP_CFG2);
		val &= ~ESP_CONFIG2_MAGIC;

		esp->config2 = 0;
		if (val != (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->rev = ESP100;
			return;
		}
	}

	esp_set_all_config3(esp, 5);
	esp->prev_cfg3 = 5;
	esp_write8(esp->config2, ESP_CFG2);
	esp_write8(0, ESP_CFG3);
	esp_write8(esp->prev_cfg3, ESP_CFG3);

	val = esp_read8(ESP_CFG3);
	if (val != 5) {
		/* The cfg2 register is implemented, however
		 * cfg3 is not, must be esp100a.
		 */
		esp->rev = ESP100A;
	} else {
		esp_set_all_config3(esp, 0);
		esp->prev_cfg3 = 0;
		esp_write8(esp->prev_cfg3, ESP_CFG3);

		/* All of cfg{1,2,3} implemented, must be one of
		 * the fas variants, figure out which one.
		 */
		if (esp->cfact == 0 || esp->cfact > ESP_CCF_F5) {
			esp->rev = FAST;
			esp->sync_defp = SYNC_DEFP_FAST;
		} else {
			esp->rev = ESP236;
		}
	}
}

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

	INIT_LIST_HEAD(&esp->queued_cmds);
	INIT_LIST_HEAD(&esp->active_cmds);
	INIT_LIST_HEAD(&esp->esp_cmd_pool);

	/* Start with a clear state, domain validation (via ->slave_configure,
	 * spi_dv_device()) will attempt to enable SYNC, WIDE, and tagged
	 * commands.
	 */
	for (i = 0 ; i < ESP_MAX_TARGET; i++) {
		esp->target[i].flags = 0;
		esp->target[i].nego_goal_period = 0;
		esp->target[i].nego_goal_offset = 0;
		esp->target[i].nego_goal_width = 0;
		esp->target[i].nego_goal_tags = 0;
	}
}

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

	/* Reset the DMA */
	esp->ops->reset_dma(esp);

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

	/* Reset the SCSI bus, but tell ESP not to generate an irq */
	val = esp_read8(ESP_CFG1);
	val |= ESP_CONFIG1_SRRDISAB;
	esp_write8(val, ESP_CFG1);

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

	esp_write8(esp->config1, ESP_CFG1);

	/* Eat any bitrot in the chip and we are done... */
	esp_read8(ESP_INTRPT);
}

static void esp_set_clock_params(struct esp *esp)
{
	int fhz;
	u8 ccf;

	/* 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)
	 *
	 *    We use a time out period of 250ms (ESP_BUS_TIMEOUT).
	 *
	 * 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.
	 */
	fhz = esp->cfreq;

	ccf = ((fhz / 1000000) + 4) / 5;
	if (ccf == 1)
		ccf = 2;

	/* 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.
	 */
	if (fhz <= 5000000 || ccf < 1 || ccf > 8) {
		fhz = 20000000;
		ccf = 4;
	}

	esp->cfact = (ccf == 8 ? 0 : ccf);
	esp->cfreq = fhz;
	esp->ccycle = ESP_HZ_TO_CYCLE(fhz);
	esp->ctick = ESP_TICK(ccf, esp->ccycle);
	esp->neg_defp = ESP_NEG_DEFP(fhz, ccf);
	esp->sync_defp = SYNC_DEFP_SLOW;
}

static const char *esp_chip_names[] = {
	"ESP100",
	"ESP100A",
	"ESP236",
	"FAS236",
	"FAS100A",
	"FAST",
	"FASHME",
	"AM53C974",
};

static struct scsi_transport_template *esp_transport_template;

int scsi_esp_register(struct esp *esp)
{
	static int instance;
	int err;

	if (!esp->num_tags)
		esp->num_tags = ESP_DEFAULT_TAGS;
	esp->host->transportt = esp_transport_template;
	esp->host->max_lun = ESP_MAX_LUN;
	esp->host->cmd_per_lun = 2;
	esp->host->unique_id = instance;

	esp_set_clock_params(esp);

	esp_get_revision(esp);

	esp_init_swstate(esp);

	esp_bootup_reset(esp);

	dev_printk(KERN_INFO, esp->dev, "esp%u: regs[%1p:%1p] irq[%u]\n",
		   esp->host->unique_id, esp->regs, esp->dma_regs,
		   esp->host->irq);
	dev_printk(KERN_INFO, esp->dev,
		   "esp%u: is a %s, %u MHz (ccf=%u), SCSI ID %u\n",
		   esp->host->unique_id, esp_chip_names[esp->rev],
		   esp->cfreq / 1000000, esp->cfact, esp->scsi_id);

	/* Let the SCSI bus reset settle. */
	ssleep(esp_bus_reset_settle);

	err = scsi_add_host(esp->host, esp->dev);
	if (err)
		return err;

	instance++;

	scsi_scan_host(esp->host);

	return 0;
}
EXPORT_SYMBOL(scsi_esp_register);

void scsi_esp_unregister(struct esp *esp)
{
	scsi_remove_host(esp->host);
}
EXPORT_SYMBOL(scsi_esp_unregister);

static int esp_target_alloc(struct scsi_target *starget)
{
	struct esp *esp = shost_priv(dev_to_shost(&starget->dev));
	struct esp_target_data *tp = &esp->target[starget->id];

	tp->starget = starget;

	return 0;
}

static void esp_target_destroy(struct scsi_target *starget)
{
	struct esp *esp = shost_priv(dev_to_shost(&starget->dev));
	struct esp_target_data *tp = &esp->target[starget->id];

	tp->starget = NULL;
}

static int esp_slave_alloc(struct scsi_device *dev)
{
	struct esp *esp = shost_priv(dev->host);
	struct esp_target_data *tp = &esp->target[dev->id];
	struct esp_lun_data *lp;

	lp = kzalloc(sizeof(*lp), GFP_KERNEL);
	if (!lp)
		return -ENOMEM;
	dev->hostdata = lp;

	spi_min_period(tp->starget) = esp->min_period;
	spi_max_offset(tp->starget) = 15;

	if (esp->flags & ESP_FLAG_WIDE_CAPABLE)
		spi_max_width(tp->starget) = 1;
	else
		spi_max_width(tp->starget) = 0;

	return 0;
}

static int esp_slave_configure(struct scsi_device *dev)
{
	struct esp *esp = shost_priv(dev->host);
	struct esp_target_data *tp = &esp->target[dev->id];

	if (dev->tagged_supported)
		scsi_change_queue_depth(dev, esp->num_tags);

	tp->flags |= ESP_TGT_DISCONNECT;

	if (!spi_initial_dv(dev->sdev_target))
		spi_dv_device(dev);

	return 0;
}

static void esp_slave_destroy(struct scsi_device *dev)
{
	struct esp_lun_data *lp = dev->hostdata;

	kfree(lp);
	dev->hostdata = NULL;
}

static int esp_eh_abort_handler(struct scsi_cmnd *cmd)
{
	struct esp *esp = shost_priv(cmd->device->host);
	struct esp_cmd_entry *ent, *tmp;
	struct completion eh_done;
	unsigned long flags;

	/* XXX This helps a lot with debugging but might be a bit
	 * XXX much for the final driver.
	 */
	spin_lock_irqsave(esp->host->host_lock, flags);
	shost_printk(KERN_ERR, esp->host, "Aborting command [%p:%02x]\n",
		     cmd, cmd->cmnd[0]);
	ent = esp->active_cmd;
	if (ent)
		shost_printk(KERN_ERR, esp->host,
			     "Current command [%p:%02x]\n",
			     ent->cmd, ent->cmd->cmnd[0]);
	list_for_each_entry(ent, &esp->queued_cmds, list) {
		shost_printk(KERN_ERR, esp->host, "Queued command [%p:%02x]\n",
			     ent->cmd, ent->cmd->cmnd[0]);
	}
	list_for_each_entry(ent, &esp->active_cmds, list) {
		shost_printk(KERN_ERR, esp->host, " Active command [%p:%02x]\n",
			     ent->cmd, ent->cmd->cmnd[0]);
	}
	esp_dump_cmd_log(esp);
	spin_unlock_irqrestore(esp->host->host_lock, flags);

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

	ent = NULL;
	list_for_each_entry(tmp, &esp->queued_cmds, list) {
		if (tmp->cmd == cmd) {
			ent = tmp;
			break;
		}
	}

	if (ent) {
		/* Easiest case, we didn't even issue the command
		 * yet so it is trivial to abort.
		 */
		list_del(&ent->list);

		cmd->result = DID_ABORT << 16;
		cmd->scsi_done(cmd);

		esp_put_ent(esp, ent);

		goto out_success;
	}

	init_completion(&eh_done);

	ent = esp->active_cmd;
	if (ent && ent->cmd == cmd) {
		/* Command is the currently active command on
		 * the bus.  If we already have an output message
		 * pending, no dice.
		 */
		if (esp->msg_out_len)
			goto out_failure;

		/* Send out an abort, encouraging the target to
		 * go to MSGOUT phase by asserting ATN.
		 */
		esp->msg_out[0] = ABORT_TASK_SET;
		esp->msg_out_len = 1;
		ent->eh_done = &eh_done;

		scsi_esp_cmd(esp, ESP_CMD_SATN);
	} else {
		/* The command is disconnected.  This is not easy to
		 * abort.  For now we fail and let the scsi error
		 * handling layer go try a scsi bus reset or host
		 * reset.
		 *
		 * What we could do is put together a scsi command
		 * solely for the purpose of sending an abort message
		 * to the target.  Coming up with all the code to
		 * cook up scsi commands, special case them everywhere,
		 * etc. is for questionable gain and it would be better
		 * if the generic scsi error handling layer could do at
		 * least some of that for us.
		 *
		 * Anyways this is an area for potential future improvement
		 * in this driver.
		 */
		goto out_failure;
	}

	spin_unlock_irqrestore(esp->host->host_lock, flags);

	if (!wait_for_completion_timeout(&eh_done, 5 * HZ)) {
		spin_lock_irqsave(esp->host->host_lock, flags);
		ent->eh_done = NULL;
		spin_unlock_irqrestore(esp->host->host_lock, flags);

		return FAILED;
	}

	return SUCCESS;

out_success:
	spin_unlock_irqrestore(esp->host->host_lock, flags);
	return SUCCESS;

out_failure:
	/* XXX This might be a good location to set ESP_TGT_BROKEN
	 * XXX since we know which target/lun in particular is
	 * XXX causing trouble.
	 */
	spin_unlock_irqrestore(esp->host->host_lock, flags);
	return FAILED;
}

static int esp_eh_bus_reset_handler(struct scsi_cmnd *cmd)
{
	struct esp *esp = shost_priv(cmd->device->host);
	struct completion eh_reset;
	unsigned long flags;

	init_completion(&eh_reset);

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

	esp->eh_reset = &eh_reset;

	/* XXX This is too simple... We should add lots of
	 * XXX checks here so that if we find that the chip is
	 * XXX very wedged we return failure immediately so
	 * XXX that we can perform a full chip reset.
	 */
	esp->flags |= ESP_FLAG_RESETTING;
	scsi_esp_cmd(esp, ESP_CMD_RS);

	spin_unlock_irqrestore(esp->host->host_lock, flags);

	ssleep(esp_bus_reset_settle);

	if (!wait_for_completion_timeout(&eh_reset, 5 * HZ)) {
		spin_lock_irqsave(esp->host->host_lock, flags);
		esp->eh_reset = NULL;
		spin_unlock_irqrestore(esp->host->host_lock, flags);

		return FAILED;
	}

	return SUCCESS;
}

/* All bets are off, reset the entire device.  */
static int esp_eh_host_reset_handler(struct scsi_cmnd *cmd)
{
	struct esp *esp = shost_priv(cmd->device->host);
	unsigned long flags;

	spin_lock_irqsave(esp->host->host_lock, flags);
	esp_bootup_reset(esp);
	esp_reset_cleanup(esp);
	spin_unlock_irqrestore(esp->host->host_lock, flags);

	ssleep(esp_bus_reset_settle);

	return SUCCESS;
}

static const char *esp_info(struct Scsi_Host *host)
{
	return "esp";
}

struct scsi_host_template scsi_esp_template = {
	.module			= THIS_MODULE,
	.name			= "esp",
	.info			= esp_info,
	.queuecommand		= esp_queuecommand,
	.target_alloc		= esp_target_alloc,
	.target_destroy		= esp_target_destroy,
	.slave_alloc		= esp_slave_alloc,
	.slave_configure	= esp_slave_configure,
	.slave_destroy		= esp_slave_destroy,
	.eh_abort_handler	= esp_eh_abort_handler,
	.eh_bus_reset_handler	= esp_eh_bus_reset_handler,
	.eh_host_reset_handler	= esp_eh_host_reset_handler,
	.can_queue		= 7,
	.this_id		= 7,
	.sg_tablesize		= SG_ALL,
	.max_sectors		= 0xffff,
	.skip_settle_delay	= 1,
};
EXPORT_SYMBOL(scsi_esp_template);

static void esp_get_signalling(struct Scsi_Host *host)
{
	struct esp *esp = shost_priv(host);
	enum spi_signal_type type;

	if (esp->flags & ESP_FLAG_DIFFERENTIAL)
		type = SPI_SIGNAL_HVD;
	else
		type = SPI_SIGNAL_SE;

	spi_signalling(host) = type;
}

static void esp_set_offset(struct scsi_target *target, int offset)
{
	struct Scsi_Host *host = dev_to_shost(target->dev.parent);
	struct esp *esp = shost_priv(host);
	struct esp_target_data *tp = &esp->target[target->id];

	if (esp->flags & ESP_FLAG_DISABLE_SYNC)
		tp->nego_goal_offset = 0;
	else
		tp->nego_goal_offset = offset;
	tp->flags |= ESP_TGT_CHECK_NEGO;
}

static void esp_set_period(struct scsi_target *target, int period)
{
	struct Scsi_Host *host = dev_to_shost(target->dev.parent);
	struct esp *esp = shost_priv(host);
	struct esp_target_data *tp = &esp->target[target->id];

	tp->nego_goal_period = period;
	tp->flags |= ESP_TGT_CHECK_NEGO;
}

static void esp_set_width(struct scsi_target *target, int width)
{
	struct Scsi_Host *host = dev_to_shost(target->dev.parent);
	struct esp *esp = shost_priv(host);
	struct esp_target_data *tp = &esp->target[target->id];

	tp->nego_goal_width = (width ? 1 : 0);
	tp->flags |= ESP_TGT_CHECK_NEGO;
}

static struct spi_function_template esp_transport_ops = {
	.set_offset		= esp_set_offset,
	.show_offset		= 1,
	.set_period		= esp_set_period,
	.show_period		= 1,
	.set_width		= esp_set_width,
	.show_width		= 1,
	.get_signalling		= esp_get_signalling,
};

static int __init esp_init(void)
{
	BUILD_BUG_ON(sizeof(struct scsi_pointer) <
		     sizeof(struct esp_cmd_priv));

	esp_transport_template = spi_attach_transport(&esp_transport_ops);
	if (!esp_transport_template)
		return -ENODEV;

	return 0;
}

static void __exit esp_exit(void)
{
	spi_release_transport(esp_transport_template);
}

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

module_param(esp_bus_reset_settle, int, 0);
MODULE_PARM_DESC(esp_bus_reset_settle,
		 "ESP scsi bus reset delay in seconds");

module_param(esp_debug, int, 0);
MODULE_PARM_DESC(esp_debug,
"ESP bitmapped debugging message enable value:\n"
"	0x00000001	Log interrupt events\n"
"	0x00000002	Log scsi commands\n"
"	0x00000004	Log resets\n"
"	0x00000008	Log message in events\n"
"	0x00000010	Log message out events\n"
"	0x00000020	Log command completion\n"
"	0x00000040	Log disconnects\n"
"	0x00000080	Log data start\n"
"	0x00000100	Log data done\n"
"	0x00000200	Log reconnects\n"
"	0x00000400	Log auto-sense data\n"
);

module_init(esp_init);
module_exit(esp_exit);

#ifdef CONFIG_SCSI_ESP_PIO
static inline unsigned int esp_wait_for_fifo(struct esp *esp)
{
	int i = 500000;

	do {
		unsigned int fbytes = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES;

		if (fbytes)
			return fbytes;

		udelay(1);
	} while (--i);

	shost_printk(KERN_ERR, esp->host, "FIFO is empty. sreg [%02x]\n",
		     esp_read8(ESP_STATUS));
	return 0;
}

static inline int esp_wait_for_intr(struct esp *esp)
{
	int i = 500000;

	do {
		esp->sreg = esp_read8(ESP_STATUS);
		if (esp->sreg & ESP_STAT_INTR)
			return 0;

		udelay(1);
	} while (--i);

	shost_printk(KERN_ERR, esp->host, "IRQ timeout. sreg [%02x]\n",
		     esp->sreg);
	return 1;
}

#define ESP_FIFO_SIZE 16

void esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
		      u32 dma_count, int write, u8 cmd)
{
	u8 phase = esp->sreg & ESP_STAT_PMASK;

	cmd &= ~ESP_CMD_DMA;
	esp->send_cmd_error = 0;

	if (write) {
		u8 *dst = (u8 *)addr;
		u8 mask = ~(phase == ESP_MIP ? ESP_INTR_FDONE : ESP_INTR_BSERV);

		scsi_esp_cmd(esp, cmd);

		while (1) {
			if (!esp_wait_for_fifo(esp))
				break;

			*dst++ = readb(esp->fifo_reg);
			--esp_count;

			if (!esp_count)
				break;

			if (esp_wait_for_intr(esp)) {
				esp->send_cmd_error = 1;
				break;
			}

			if ((esp->sreg & ESP_STAT_PMASK) != phase)
				break;

			esp->ireg = esp_read8(ESP_INTRPT);
			if (esp->ireg & mask) {
				esp->send_cmd_error = 1;
				break;
			}

			if (phase == ESP_MIP)
				esp_write8(ESP_CMD_MOK, ESP_CMD);

			esp_write8(ESP_CMD_TI, ESP_CMD);
		}
	} else {
		unsigned int n = ESP_FIFO_SIZE;
		u8 *src = (u8 *)addr;

		scsi_esp_cmd(esp, ESP_CMD_FLUSH);

		if (n > esp_count)
			n = esp_count;
		writesb(esp->fifo_reg, src, n);
		src += n;
		esp_count -= n;

		scsi_esp_cmd(esp, cmd);

		while (esp_count) {
			if (esp_wait_for_intr(esp)) {
				esp->send_cmd_error = 1;
				break;
			}

			if ((esp->sreg & ESP_STAT_PMASK) != phase)
				break;

			esp->ireg = esp_read8(ESP_INTRPT);
			if (esp->ireg & ~ESP_INTR_BSERV) {
				esp->send_cmd_error = 1;
				break;
			}

			n = ESP_FIFO_SIZE -
			    (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES);

			if (n > esp_count)
				n = esp_count;
			writesb(esp->fifo_reg, src, n);
			src += n;
			esp_count -= n;

			esp_write8(ESP_CMD_TI, ESP_CMD);
		}
	}

	esp->send_cmd_residual = esp_count;
}
EXPORT_SYMBOL(esp_send_pio_cmd);
#endif
