/*
 *  linux/drivers/acorn/scsi/fas216.c
 *
 *  Copyright (C) 1997-2003 Russell King
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Based on information in qlogicfas.c by Tom Zerucha, Michael Griffith, and
 * other sources, including:
 *   the AMD Am53CF94 data sheet
 *   the AMD Am53C94 data sheet
 *
 * This is a generic driver.  To use it, have a look at cumana_2.c.  You
 * should define your own structure that overlays FAS216_Info, eg:
 * struct my_host_data {
 *    FAS216_Info info;
 *    ... my host specific data ...
 * };
 *
 * Changelog:
 *  30-08-1997	RMK	Created
 *  14-09-1997	RMK	Started disconnect support
 *  08-02-1998	RMK	Corrected real DMA support
 *  15-02-1998	RMK	Started sync xfer support
 *  06-04-1998	RMK	Tightened conditions for printing incomplete
 *			transfers
 *  02-05-1998	RMK	Added extra checks in fas216_reset
 *  24-05-1998	RMK	Fixed synchronous transfers with period >= 200ns
 *  27-06-1998	RMK	Changed asm/delay.h to linux/delay.h
 *  26-08-1998	RMK	Improved message support wrt MESSAGE_REJECT
 *  02-04-2000	RMK	Converted to use the new error handling, and
 *			automatically request sense data upon check
 *			condition status from targets.
 */
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/interrupt.h>

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

#include "../scsi.h"
#include <scsi/scsi_host.h>
#include "fas216.h"
#include "scsi.h"

/* NOTE: SCSI2 Synchronous transfers *require* DMA according to
 *  the data sheet.  This restriction is crazy, especially when
 *  you only want to send 16 bytes!  What were the guys who
 *  designed this chip on at that time?  Did they read the SCSI2
 *  spec at all?  The following sections are taken from the SCSI2
 *  standard (s2r10) concerning this:
 *
 * > IMPLEMENTORS NOTES:
 * >   (1)  Re-negotiation at every selection is not recommended, since a
 * >   significant performance impact is likely.
 *
 * >  The implied synchronous agreement shall remain in effect until a BUS DEVICE
 * >  RESET message is received, until a hard reset condition occurs, or until one
 * >  of the two SCSI devices elects to modify the agreement.  The default data
 * >  transfer mode is asynchronous data transfer mode.  The default data transfer
 * >  mode is entered at power on, after a BUS DEVICE RESET message, or after a hard
 * >  reset condition.
 *
 *  In total, this means that once you have elected to use synchronous
 *  transfers, you must always use DMA.
 *
 *  I was thinking that this was a good chip until I found this restriction ;(
 */
#define SCSI2_SYNC
#undef  SCSI2_TAG

#undef DEBUG_CONNECT
#undef DEBUG_MESSAGES

#undef CHECK_STRUCTURE

#define LOG_CONNECT		(1 << 0)
#define LOG_BUSSERVICE		(1 << 1)
#define LOG_FUNCTIONDONE	(1 << 2)
#define LOG_MESSAGES		(1 << 3)
#define LOG_BUFFER		(1 << 4)
#define LOG_ERROR		(1 << 8)

static int level_mask = LOG_ERROR;

module_param(level_mask, int, 0644);

static int __init fas216_log_setup(char *str)
{
	char *s;

	level_mask = 0;

	while ((s = strsep(&str, ",")) != NULL) {
		switch (s[0]) {
		case 'a':
			if (strcmp(s, "all") == 0)
				level_mask |= -1;
			break;
		case 'b':
			if (strncmp(s, "bus", 3) == 0)
				level_mask |= LOG_BUSSERVICE;
			if (strncmp(s, "buf", 3) == 0)
				level_mask |= LOG_BUFFER;
			break;
		case 'c':
			level_mask |= LOG_CONNECT;
			break;
		case 'e':
			level_mask |= LOG_ERROR;
			break;
		case 'm':
			level_mask |= LOG_MESSAGES;
			break;
		case 'n':
			if (strcmp(s, "none") == 0)
				level_mask = 0;
			break;
		case 's':
			level_mask |= LOG_FUNCTIONDONE;
			break;
		}
	}
	return 1;
}

__setup("fas216_logging=", fas216_log_setup);

static inline unsigned char fas216_readb(FAS216_Info *info, unsigned int reg)
{
	unsigned int off = reg << info->scsi.io_shift;
	return readb(info->scsi.io_base + off);
}

static inline void fas216_writeb(FAS216_Info *info, unsigned int reg, unsigned int val)
{
	unsigned int off = reg << info->scsi.io_shift;
	writeb(val, info->scsi.io_base + off);
}

static void fas216_dumpstate(FAS216_Info *info)
{
	unsigned char is, stat, inst;

	is   = fas216_readb(info, REG_IS);
	stat = fas216_readb(info, REG_STAT);
	inst = fas216_readb(info, REG_INST);
	
	printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
	       " INST=%02X IS=%02X CFIS=%02X",
		fas216_readb(info, REG_CTCL),
		fas216_readb(info, REG_CTCM),
		fas216_readb(info, REG_CMD),  stat, inst, is,
		fas216_readb(info, REG_CFIS));
	printk(" CNTL1=%02X CNTL2=%02X CNTL3=%02X CTCH=%02X\n",
		fas216_readb(info, REG_CNTL1),
		fas216_readb(info, REG_CNTL2),
		fas216_readb(info, REG_CNTL3),
		fas216_readb(info, REG_CTCH));
}

static void print_SCp(Scsi_Pointer *SCp, const char *prefix, const char *suffix)
{
	printk("%sptr %p this_residual 0x%x buffer %p buffers_residual 0x%x%s",
		prefix, SCp->ptr, SCp->this_residual, SCp->buffer,
		SCp->buffers_residual, suffix);
}

static void fas216_dumpinfo(FAS216_Info *info)
{
	static int used = 0;
	int i;

	if (used++)
		return;

	printk("FAS216_Info=\n");
	printk("  { magic_start=%lX host=%p SCpnt=%p origSCpnt=%p\n",
		info->magic_start, info->host, info->SCpnt,
		info->origSCpnt);
	printk("    scsi={ io_shift=%X irq=%X cfg={ %X %X %X %X }\n",
		info->scsi.io_shift, info->scsi.irq,
		info->scsi.cfg[0], info->scsi.cfg[1], info->scsi.cfg[2],
		info->scsi.cfg[3]);
	printk("           type=%p phase=%X\n",
		info->scsi.type, info->scsi.phase);
	print_SCp(&info->scsi.SCp, "           SCp={ ", " }\n");
	printk("      msgs async_stp=%X disconnectable=%d aborting=%d }\n",
		info->scsi.async_stp,
		info->scsi.disconnectable, info->scsi.aborting);
	printk("    stats={ queues=%X removes=%X fins=%X reads=%X writes=%X miscs=%X\n"
	       "            disconnects=%X aborts=%X bus_resets=%X host_resets=%X}\n",
		info->stats.queues, info->stats.removes, info->stats.fins,
		info->stats.reads, info->stats.writes, info->stats.miscs,
		info->stats.disconnects, info->stats.aborts, info->stats.bus_resets,
		info->stats.host_resets);
	printk("    ifcfg={ clockrate=%X select_timeout=%X asyncperiod=%X sync_max_depth=%X }\n",
		info->ifcfg.clockrate, info->ifcfg.select_timeout,
		info->ifcfg.asyncperiod, info->ifcfg.sync_max_depth);
	for (i = 0; i < 8; i++) {
		printk("    busyluns[%d]=%08lx dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }\n",
			i, info->busyluns[i], i,
			info->device[i].disconnect_ok, info->device[i].stp,
			info->device[i].sof, info->device[i].sync_state);
	}
	printk("    dma={ transfer_type=%X setup=%p pseudo=%p stop=%p }\n",
		info->dma.transfer_type, info->dma.setup,
		info->dma.pseudo, info->dma.stop);
	printk("    internal_done=%X magic_end=%lX }\n",
		info->internal_done, info->magic_end);
}

#ifdef CHECK_STRUCTURE
static void __fas216_checkmagic(FAS216_Info *info, const char *func)
{
	int corruption = 0;
	if (info->magic_start != MAGIC) {
		printk(KERN_CRIT "FAS216 Error: magic at start corrupted\n");
		corruption++;
	}
	if (info->magic_end != MAGIC) {
		printk(KERN_CRIT "FAS216 Error: magic at end corrupted\n");
		corruption++;
	}
	if (corruption) {
		fas216_dumpinfo(info);
		panic("scsi memory space corrupted in %s", func);
	}
}
#define fas216_checkmagic(info) __fas216_checkmagic((info), __FUNCTION__)
#else
#define fas216_checkmagic(info)
#endif

static const char *fas216_bus_phase(int stat)
{
	static const char *phases[] = {
		"DATA OUT", "DATA IN",
		"COMMAND", "STATUS",
		"MISC OUT", "MISC IN",
		"MESG OUT", "MESG IN"
	};

	return phases[stat & STAT_BUSMASK];
}

static const char *fas216_drv_phase(FAS216_Info *info)
{
	static const char *phases[] = {
		[PHASE_IDLE]		= "idle",
		[PHASE_SELECTION]	= "selection",
		[PHASE_COMMAND]		= "command",
		[PHASE_DATAOUT]		= "data out",
		[PHASE_DATAIN]		= "data in",
		[PHASE_MSGIN]		= "message in",
		[PHASE_MSGIN_DISCONNECT]= "disconnect",
		[PHASE_MSGOUT_EXPECT]	= "expect message out",
		[PHASE_MSGOUT]		= "message out",
		[PHASE_STATUS]		= "status",
		[PHASE_DONE]		= "done",
	};

	if (info->scsi.phase < ARRAY_SIZE(phases) &&
	    phases[info->scsi.phase])
		return phases[info->scsi.phase];
	return "???";
}

static char fas216_target(FAS216_Info *info)
{
	if (info->SCpnt)
		return '0' + info->SCpnt->device->id;
	else
		return 'H';
}

static void
fas216_do_log(FAS216_Info *info, char target, char *fmt, va_list ap)
{
	static char buf[1024];

	vsnprintf(buf, sizeof(buf), fmt, ap);
	printk("scsi%d.%c: %s", info->host->host_no, target, buf);
}

static void
fas216_log_command(FAS216_Info *info, int level, Scsi_Cmnd *SCpnt, char *fmt, ...)
{
	va_list args;

	if (level != 0 && !(level & level_mask))
		return;

	va_start(args, fmt);
	fas216_do_log(info, '0' + SCpnt->device->id, fmt, args);
	va_end(args);

	printk(" CDB: ");
	print_command(SCpnt->cmnd);
}

static void
fas216_log_target(FAS216_Info *info, int level, int target, char *fmt, ...)
{
	va_list args;

	if (level != 0 && !(level & level_mask))
		return;

	if (target < 0)
		target = 'H';
	else
		target += '0';

	va_start(args, fmt);
	fas216_do_log(info, target, fmt, args);
	va_end(args);

	printk("\n");
}

static void fas216_log(FAS216_Info *info, int level, char *fmt, ...)
{
	va_list args;

	if (level != 0 && !(level & level_mask))
		return;

	va_start(args, fmt);
	fas216_do_log(info, fas216_target(info), fmt, args);
	va_end(args);

	printk("\n");
}

#define PH_SIZE	32

static struct { int stat, ssr, isr, ph; } ph_list[PH_SIZE];
static int ph_ptr;

static void add_debug_list(int stat, int ssr, int isr, int ph)
{
	ph_list[ph_ptr].stat = stat;
	ph_list[ph_ptr].ssr = ssr;
	ph_list[ph_ptr].isr = isr;
	ph_list[ph_ptr].ph = ph;

	ph_ptr = (ph_ptr + 1) & (PH_SIZE-1);
}

static struct { int command; void *from; } cmd_list[8];
static int cmd_ptr;

static void fas216_cmd(FAS216_Info *info, unsigned int command)
{
	cmd_list[cmd_ptr].command = command;
	cmd_list[cmd_ptr].from = __builtin_return_address(0);

	cmd_ptr = (cmd_ptr + 1) & 7;

	fas216_writeb(info, REG_CMD, command);
}

static void print_debug_list(void)
{
	int i;

	i = ph_ptr;

	printk(KERN_ERR "SCSI IRQ trail\n");
	do {
		printk(" %02x:%02x:%02x:%1x",
			ph_list[i].stat, ph_list[i].ssr,
			ph_list[i].isr, ph_list[i].ph);
		i = (i + 1) & (PH_SIZE - 1);
		if (((i ^ ph_ptr) & 7) == 0)
			printk("\n");
	} while (i != ph_ptr);
	if ((i ^ ph_ptr) & 7)
		printk("\n");

	i = cmd_ptr;
	printk(KERN_ERR "FAS216 commands: ");
	do {
		printk("%02x:%p ", cmd_list[i].command, cmd_list[i].from);
		i = (i + 1) & 7;
	} while (i != cmd_ptr);
	printk("\n");
}

static void fas216_done(FAS216_Info *info, unsigned int result);

/**
 * fas216_get_last_msg - retrive last message from the list
 * @info: interface to search
 * @pos: current fifo position
 *
 * Retrieve a last message from the list, using position in fifo.
 */
static inline unsigned short
fas216_get_last_msg(FAS216_Info *info, int pos)
{
	unsigned short packed_msg = NOP;
	struct message *msg;
	int msgnr = 0;

	while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
		if (pos >= msg->fifo)
			break;
	}

	if (msg) {
		if (msg->msg[0] == EXTENDED_MESSAGE)
			packed_msg = EXTENDED_MESSAGE | msg->msg[2] << 8;
		else
			packed_msg = msg->msg[0];
	}

	fas216_log(info, LOG_MESSAGES,
		"Message: %04x found at position %02x\n", packed_msg, pos);

	return packed_msg;
}

/**
 * fas216_syncperiod - calculate STP register value
 * @info: state structure for interface connected to device
 * @ns: period in ns (between subsequent bytes)
 *
 * Calculate value to be loaded into the STP register for a given period
 * in ns. Returns a value suitable for REG_STP.
 */
static int fas216_syncperiod(FAS216_Info *info, int ns)
{
	int value = (info->ifcfg.clockrate * ns) / 1000;

	fas216_checkmagic(info);

	if (value < 4)
		value = 4;
	else if (value > 35)
		value = 35;

	return value & 31;
}

/**
 * fas216_set_sync - setup FAS216 chip for specified transfer period.
 * @info: state structure for interface connected to device
 * @target: target
 *
 * Correctly setup FAS216 chip for specified transfer period.
 * Notes   : we need to switch the chip out of FASTSCSI mode if we have
 *           a transfer period >= 200ns - otherwise the chip will violate
 *           the SCSI timings.
 */
static void fas216_set_sync(FAS216_Info *info, int target)
{
	unsigned int cntl3;

	fas216_writeb(info, REG_SOF, info->device[target].sof);
	fas216_writeb(info, REG_STP, info->device[target].stp);

	cntl3 = info->scsi.cfg[2];
	if (info->device[target].period >= (200 / 4))
		cntl3 = cntl3 & ~CNTL3_FASTSCSI;

	fas216_writeb(info, REG_CNTL3, cntl3);
}

/* Synchronous transfer support
 *
 * Note: The SCSI II r10 spec says (5.6.12):
 *
 *  (2)  Due to historical problems with early host adapters that could
 *  not accept an SDTR message, some targets may not initiate synchronous
 *  negotiation after a power cycle as required by this standard.  Host
 *  adapters that support synchronous mode may avoid the ensuing failure
 *  modes when the target is independently power cycled by initiating a
 *  synchronous negotiation on each REQUEST SENSE and INQUIRY command.
 *  This approach increases the SCSI bus overhead and is not recommended
 *  for new implementations.  The correct method is to respond to an
 *  SDTR message with a MESSAGE REJECT message if the either the
 *  initiator or target devices does not support synchronous transfers
 *  or does not want to negotiate for synchronous transfers at the time.
 *  Using the correct method assures compatibility with wide data
 *  transfers and future enhancements.
 *
 * We will always initiate a synchronous transfer negotiation request on
 * every INQUIRY or REQUEST SENSE message, unless the target itself has
 * at some point performed a synchronous transfer negotiation request, or
 * we have synchronous transfers disabled for this device.
 */

/**
 * fas216_handlesync - Handle a synchronous transfer message
 * @info: state structure for interface
 * @msg: message from target
 *
 * Handle a synchronous transfer message from the target
 */
static void fas216_handlesync(FAS216_Info *info, char *msg)
{
	struct fas216_device *dev = &info->device[info->SCpnt->device->id];
	enum { sync, async, none, reject } res = none;

#ifdef SCSI2_SYNC
	switch (msg[0]) {
	case MESSAGE_REJECT:
		/* Synchronous transfer request failed.
		 * Note: SCSI II r10:
		 *
		 *  SCSI devices that are capable of synchronous
		 *  data transfers shall not respond to an SDTR
		 *  message with a MESSAGE REJECT message.
		 *
		 * Hence, if we get this condition, we disable
		 * negotiation for this device.
		 */
		if (dev->sync_state == neg_inprogress) {
			dev->sync_state = neg_invalid;
			res = async;
		}
		break;

	case EXTENDED_MESSAGE:
		switch (dev->sync_state) {
		/* We don't accept synchronous transfer requests.
		 * Respond with a MESSAGE_REJECT to prevent a
		 * synchronous transfer agreement from being reached.
		 */
		case neg_invalid:
			res = reject;
			break;

		/* We were not negotiating a synchronous transfer,
		 * but the device sent us a negotiation request.
		 * Honour the request by sending back a SDTR
		 * message containing our capability, limited by
		 * the targets capability.
		 */
		default:
			fas216_cmd(info, CMD_SETATN);
			if (msg[4] > info->ifcfg.sync_max_depth)
				msg[4] = info->ifcfg.sync_max_depth;
			if (msg[3] < 1000 / info->ifcfg.clockrate)
				msg[3] = 1000 / info->ifcfg.clockrate;

			msgqueue_flush(&info->scsi.msgs);
			msgqueue_addmsg(&info->scsi.msgs, 5,
					EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
					msg[3], msg[4]);
			info->scsi.phase = PHASE_MSGOUT_EXPECT;

			/* This is wrong.  The agreement is not in effect
			 * until this message is accepted by the device
			 */
			dev->sync_state = neg_targcomplete;
			res = sync;
			break;

		/* We initiated the synchronous transfer negotiation,
		 * and have successfully received a response from the
		 * target.  The synchronous transfer agreement has been
		 * reached.  Note: if the values returned are out of our
		 * bounds, we must reject the message.
		 */
		case neg_inprogress:
			res = reject;
			if (msg[4] <= info->ifcfg.sync_max_depth &&
			    msg[3] >= 1000 / info->ifcfg.clockrate) {
				dev->sync_state = neg_complete;
				res = sync;
			}
			break;
		}
	}
#else
	res = reject;
#endif

	switch (res) {
	case sync:
		dev->period = msg[3];
		dev->sof    = msg[4];
		dev->stp    = fas216_syncperiod(info, msg[3] * 4);
		fas216_set_sync(info, info->SCpnt->device->id);
		break;

	case reject:
		fas216_cmd(info, CMD_SETATN);
		msgqueue_flush(&info->scsi.msgs);
		msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
		info->scsi.phase = PHASE_MSGOUT_EXPECT;

	case async:
		dev->period = info->ifcfg.asyncperiod / 4;
		dev->sof    = 0;
		dev->stp    = info->scsi.async_stp;
		fas216_set_sync(info, info->SCpnt->device->id);
		break;

	case none:
		break;
	}
}

/**
 * fas216_updateptrs - update data pointers after transfer suspended/paused
 * @info: interface's local pointer to update
 * @bytes_transferred: number of bytes transferred
 *
 * Update data pointers after transfer suspended/paused
 */
static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
{
	Scsi_Pointer *SCp = &info->scsi.SCp;

	fas216_checkmagic(info);

	BUG_ON(bytes_transferred < 0);

	info->SCpnt->request_bufflen -= bytes_transferred;

	while (bytes_transferred != 0) {
		if (SCp->this_residual > bytes_transferred)
			break;
		/*
		 * We have used up this buffer.  Move on to the
		 * next buffer.
		 */
		bytes_transferred -= SCp->this_residual;
		if (!next_SCp(SCp) && bytes_transferred) {
			printk(KERN_WARNING "scsi%d.%c: out of buffers\n",
				info->host->host_no, '0' + info->SCpnt->device->id);
			return;
		}
	}

	SCp->this_residual -= bytes_transferred;
	if (SCp->this_residual)
		SCp->ptr += bytes_transferred;
	else
		SCp->ptr = NULL;
}

/**
 * fas216_pio - transfer data off of/on to card using programmed IO
 * @info: interface to transfer data to/from
 * @direction: direction to transfer data (DMA_OUT/DMA_IN)
 *
 * Transfer data off of/on to card using programmed IO.
 * Notes: this is incredibly slow.
 */
static void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
{
	Scsi_Pointer *SCp = &info->scsi.SCp;

	fas216_checkmagic(info);

	if (direction == DMA_OUT)
		fas216_writeb(info, REG_FF, get_next_SCp_byte(SCp));
	else
		put_next_SCp_byte(SCp, fas216_readb(info, REG_FF));

	if (SCp->this_residual == 0)
		next_SCp(SCp);
}

static void fas216_set_stc(FAS216_Info *info, unsigned int length)
{
	fas216_writeb(info, REG_STCL, length);
	fas216_writeb(info, REG_STCM, length >> 8);
	fas216_writeb(info, REG_STCH, length >> 16);
}

static unsigned int fas216_get_ctc(FAS216_Info *info)
{
	return fas216_readb(info, REG_CTCL) +
	       (fas216_readb(info, REG_CTCM) << 8) +
	       (fas216_readb(info, REG_CTCH) << 16);
}

/**
 * fas216_cleanuptransfer - clean up after a transfer has completed.
 * @info: interface to clean up
 *
 * Update the data pointers according to the number of bytes transferred
 * on the SCSI bus.
 */
static void fas216_cleanuptransfer(FAS216_Info *info)
{
	unsigned long total, residual, fifo;
	fasdmatype_t dmatype = info->dma.transfer_type;

	info->dma.transfer_type = fasdma_none;

	/*
	 * PIO transfers do not need to be cleaned up.
	 */
	if (dmatype == fasdma_pio || dmatype == fasdma_none)
		return;

	if (dmatype == fasdma_real_all)
		total = info->SCpnt->request_bufflen;
	else
		total = info->scsi.SCp.this_residual;

	residual = fas216_get_ctc(info);

	fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;

	fas216_log(info, LOG_BUFFER, "cleaning up from previous "
		   "transfer: length 0x%06x, residual 0x%x, fifo %d",
		   total, residual, fifo);

	/*
	 * If we were performing Data-Out, the transfer counter
	 * counts down each time a byte is transferred by the
	 * host to the FIFO.  This means we must include the
	 * bytes left in the FIFO from the transfer counter.
	 */
	if (info->scsi.phase == PHASE_DATAOUT)
		residual += fifo;

	fas216_updateptrs(info, total - residual);
}

/**
 * fas216_transfer - Perform a DMA/PIO transfer off of/on to card
 * @info: interface from which device disconnected from
 *
 * Start a DMA/PIO transfer off of/on to card
 */
static void fas216_transfer(FAS216_Info *info)
{
	fasdmadir_t direction;
	fasdmatype_t dmatype;

	fas216_log(info, LOG_BUFFER,
		   "starttransfer: buffer %p length 0x%06x reqlen 0x%06x",
		   info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
		   info->SCpnt->request_bufflen);

	if (!info->scsi.SCp.ptr) {
		fas216_log(info, LOG_ERROR, "null buffer passed to "
			   "fas216_starttransfer");
		print_SCp(&info->scsi.SCp, "SCp: ", "\n");
		print_SCp(&info->SCpnt->SCp, "Cmnd SCp: ", "\n");
		return;
	}

	/*
	 * If we have a synchronous transfer agreement in effect, we must
	 * use DMA mode.  If we are using asynchronous transfers, we may
	 * use DMA mode or PIO mode.
	 */
	if (info->device[info->SCpnt->device->id].sof)
		dmatype = fasdma_real_all;
	else
		dmatype = fasdma_pio;

	if (info->scsi.phase == PHASE_DATAOUT)
		direction = DMA_OUT;
	else
		direction = DMA_IN;

	if (info->dma.setup)
		dmatype = info->dma.setup(info->host, &info->scsi.SCp,
					  direction, dmatype);
	info->dma.transfer_type = dmatype;

	if (dmatype == fasdma_real_all)
		fas216_set_stc(info, info->SCpnt->request_bufflen);
	else
		fas216_set_stc(info, info->scsi.SCp.this_residual);

	switch (dmatype) {
	case fasdma_pio:
		fas216_log(info, LOG_BUFFER, "PIO transfer");
		fas216_writeb(info, REG_SOF, 0);
		fas216_writeb(info, REG_STP, info->scsi.async_stp);
		fas216_cmd(info, CMD_TRANSFERINFO);
		fas216_pio(info, direction);
		break;

	case fasdma_pseudo:
		fas216_log(info, LOG_BUFFER, "pseudo transfer");
		fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
		info->dma.pseudo(info->host, &info->scsi.SCp,
				 direction, info->SCpnt->transfersize);
		break;

	case fasdma_real_block:
		fas216_log(info, LOG_BUFFER, "block dma transfer");
		fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
		break;

	case fasdma_real_all:
		fas216_log(info, LOG_BUFFER, "total dma transfer");
		fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
		break;

	default:
		fas216_log(info, LOG_BUFFER | LOG_ERROR,
			   "invalid FAS216 DMA type");
		break;
	}
}

/**
 * fas216_stoptransfer - Stop a DMA transfer onto / off of the card
 * @info: interface from which device disconnected from
 *
 * Called when we switch away from DATA IN or DATA OUT phases.
 */
static void fas216_stoptransfer(FAS216_Info *info)
{
	fas216_checkmagic(info);

	if (info->dma.transfer_type == fasdma_real_all ||
	    info->dma.transfer_type == fasdma_real_block)
		info->dma.stop(info->host, &info->scsi.SCp);

	fas216_cleanuptransfer(info);

	if (info->scsi.phase == PHASE_DATAIN) {
		unsigned int fifo;

		/*
		 * If we were performing Data-In, then the FIFO counter
		 * contains the number of bytes not transferred via DMA
		 * from the on-board FIFO.  Read them manually.
		 */
		fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
		while (fifo && info->scsi.SCp.ptr) {
			*info->scsi.SCp.ptr = fas216_readb(info, REG_FF);
			fas216_updateptrs(info, 1);
			fifo--;
		}
	} else {
		/*
		 * After a Data-Out phase, there may be unsent
		 * bytes left in the FIFO.  Flush them out.
		 */
		fas216_cmd(info, CMD_FLUSHFIFO);
	}
}

static void fas216_aborttransfer(FAS216_Info *info)
{
	fas216_checkmagic(info);

	if (info->dma.transfer_type == fasdma_real_all ||
	    info->dma.transfer_type == fasdma_real_block)
		info->dma.stop(info->host, &info->scsi.SCp);

	info->dma.transfer_type = fasdma_none;
	fas216_cmd(info, CMD_FLUSHFIFO);
}

static void fas216_kick(FAS216_Info *info);

/**
 * fas216_disconnected_intr - handle device disconnection
 * @info: interface from which device disconnected from
 *
 * Handle device disconnection
 */
static void fas216_disconnect_intr(FAS216_Info *info)
{
	unsigned long flags;

	fas216_checkmagic(info);

	fas216_log(info, LOG_CONNECT, "disconnect phase=%02x",
		   info->scsi.phase);

	msgqueue_flush(&info->scsi.msgs);

	switch (info->scsi.phase) {
	case PHASE_SELECTION:			/* while selecting - no target		*/
	case PHASE_SELSTEPS:
		fas216_done(info, DID_NO_CONNECT);
		break;

	case PHASE_MSGIN_DISCONNECT:		/* message in - disconnecting		*/
		info->scsi.disconnectable = 1;
		info->scsi.phase = PHASE_IDLE;
		info->stats.disconnects += 1;
		spin_lock_irqsave(&info->host_lock, flags);
		if (info->scsi.phase == PHASE_IDLE)
			fas216_kick(info);
		spin_unlock_irqrestore(&info->host_lock, flags);
		break;

	case PHASE_DONE:			/* at end of command - complete		*/
		fas216_done(info, DID_OK);
		break;

	case PHASE_MSGOUT:			/* message out - possible ABORT message	*/
		if (fas216_get_last_msg(info, info->scsi.msgin_fifo) == ABORT) {
			info->scsi.aborting = 0;
			fas216_done(info, DID_ABORT);
			break;
		}

	default:				/* huh?					*/
		printk(KERN_ERR "scsi%d.%c: unexpected disconnect in phase %s\n",
			info->host->host_no, fas216_target(info), fas216_drv_phase(info));
		print_debug_list();
		fas216_stoptransfer(info);
		fas216_done(info, DID_ERROR);
		break;
	}
}

/**
 * fas216_reselected_intr - start reconnection of a device
 * @info: interface which was reselected
 *
 * Start reconnection of a device
 */
static void
fas216_reselected_intr(FAS216_Info *info)
{
	unsigned int cfis, i;
	unsigned char msg[4];
	unsigned char target, lun, tag;

	fas216_checkmagic(info);

	WARN_ON(info->scsi.phase == PHASE_SELECTION ||
		info->scsi.phase == PHASE_SELSTEPS);

	cfis = fas216_readb(info, REG_CFIS);

	fas216_log(info, LOG_CONNECT, "reconnect phase=%02x cfis=%02x",
		   info->scsi.phase, cfis);

	cfis &= CFIS_CF;

	if (cfis < 2 || cfis > 4) {
		printk(KERN_ERR "scsi%d.H: incorrect number of bytes after reselect\n",
			info->host->host_no);
		goto bad_message;
	}

	for (i = 0; i < cfis; i++)
		msg[i] = fas216_readb(info, REG_FF);

	if (!(msg[0] & (1 << info->host->this_id)) ||
	    !(msg[1] & 0x80))
		goto initiator_error;

	target = msg[0] & ~(1 << info->host->this_id);
	target = ffs(target) - 1;
	lun = msg[1] & 7;
	tag = 0;

	if (cfis >= 3) {
		if (msg[2] != SIMPLE_QUEUE_TAG)
			goto initiator_error;

		tag = msg[3];
	}

	/* set up for synchronous transfers */
	fas216_writeb(info, REG_SDID, target);
	fas216_set_sync(info, target);
	msgqueue_flush(&info->scsi.msgs);

	fas216_log(info, LOG_CONNECT, "Reconnected: target %1x lun %1x tag %02x",
		   target, lun, tag);

	if (info->scsi.disconnectable && info->SCpnt) {
		info->scsi.disconnectable = 0;
		if (info->SCpnt->device->id  == target &&
		    info->SCpnt->device->lun == lun &&
		    info->SCpnt->tag         == tag) {
			fas216_log(info, LOG_CONNECT, "reconnected previously executing command");
		} else {
			queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
			fas216_log(info, LOG_CONNECT, "had to move command to disconnected queue");
			info->SCpnt = NULL;
		}
	}
	if (!info->SCpnt) {
		info->SCpnt = queue_remove_tgtluntag(&info->queues.disconnected,
					target, lun, tag);
		fas216_log(info, LOG_CONNECT, "had to get command");
	}

	if (info->SCpnt) {
		/*
		 * Restore data pointer from SAVED data pointer
		 */
		info->scsi.SCp = info->SCpnt->SCp;

		fas216_log(info, LOG_CONNECT, "data pointers: [%p, %X]",
			info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
		info->scsi.phase = PHASE_MSGIN;
	} else {
		/*
		 * Our command structure not found - abort the
		 * command on the target.  Since we have no
		 * record of this command, we can't send
		 * an INITIATOR DETECTED ERROR message.
		 */
		fas216_cmd(info, CMD_SETATN);

#if 0
		if (tag)
			msgqueue_addmsg(&info->scsi.msgs, 2, ABORT_TAG, tag);
		else
#endif
			msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
		info->scsi.phase = PHASE_MSGOUT_EXPECT;
		info->scsi.aborting = 1;
	}

	fas216_cmd(info, CMD_MSGACCEPTED);
	return;

 initiator_error:
	printk(KERN_ERR "scsi%d.H: error during reselection: bytes",
		info->host->host_no);
	for (i = 0; i < cfis; i++)
		printk(" %02x", msg[i]);
	printk("\n");
 bad_message:
	fas216_cmd(info, CMD_SETATN);
	msgqueue_flush(&info->scsi.msgs);
	msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
	info->scsi.phase = PHASE_MSGOUT_EXPECT;
	fas216_cmd(info, CMD_MSGACCEPTED);
}

static void fas216_parse_message(FAS216_Info *info, unsigned char *message, int msglen)
{
	int i;

	switch (message[0]) {
	case COMMAND_COMPLETE:
		if (msglen != 1)
			goto unrecognised;

		printk(KERN_ERR "scsi%d.%c: command complete with no "
			"status in MESSAGE_IN?\n",
			info->host->host_no, fas216_target(info));
		break;

	case SAVE_POINTERS:
		if (msglen != 1)
			goto unrecognised;

		/*
		 * Save current data pointer to SAVED data pointer
		 * SCSI II standard says that we must not acknowledge
		 * this until we have really saved pointers.
		 * NOTE: we DO NOT save the command nor status pointers
		 * as required by the SCSI II standard.  These always
		 * point to the start of their respective areas.
		 */
		info->SCpnt->SCp = info->scsi.SCp;
		info->SCpnt->SCp.sent_command = 0;
		fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER,
			"save data pointers: [%p, %X]",
			info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
		break;

	case RESTORE_POINTERS:
		if (msglen != 1)
			goto unrecognised;

		/*
		 * Restore current data pointer from SAVED data pointer
		 */
		info->scsi.SCp = info->SCpnt->SCp;
		fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER,
			"restore data pointers: [%p, 0x%x]",
			info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
		break;

	case DISCONNECT:
		if (msglen != 1)
			goto unrecognised;

		info->scsi.phase = PHASE_MSGIN_DISCONNECT;
		break;

	case MESSAGE_REJECT:
		if (msglen != 1)
			goto unrecognised;

		switch (fas216_get_last_msg(info, info->scsi.msgin_fifo)) {
		case EXTENDED_MESSAGE | EXTENDED_SDTR << 8:
			fas216_handlesync(info, message);
			break;

		default:
			fas216_log(info, 0, "reject, last message 0x%04x",
				fas216_get_last_msg(info, info->scsi.msgin_fifo));
		}
		break;

	case NOP:
		break;

	case EXTENDED_MESSAGE:
		if (msglen < 3)
			goto unrecognised;

		switch (message[2]) {
		case EXTENDED_SDTR:	/* Sync transfer negotiation request/reply */
			fas216_handlesync(info, message);
			break;

		default:
			goto unrecognised;
		}
		break;

	default:
		goto unrecognised;
	}
	return;

unrecognised:
	fas216_log(info, 0, "unrecognised message, rejecting");
	printk("scsi%d.%c: message was", info->host->host_no, fas216_target(info));
	for (i = 0; i < msglen; i++)
		printk("%s%02X", i & 31 ? " " : "\n  ", message[i]);
	printk("\n");

	/*
	 * Something strange seems to be happening here -
	 * I can't use SETATN since the chip gives me an
	 * invalid command interrupt when I do.  Weird.
	 */
fas216_cmd(info, CMD_NOP);
fas216_dumpstate(info);
	fas216_cmd(info, CMD_SETATN);
	msgqueue_flush(&info->scsi.msgs);
	msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
	info->scsi.phase = PHASE_MSGOUT_EXPECT;
fas216_dumpstate(info);
}

static int fas216_wait_cmd(FAS216_Info *info, int cmd)
{
	int tout;
	int stat;

	fas216_cmd(info, cmd);

	for (tout = 1000; tout; tout -= 1) {
		stat = fas216_readb(info, REG_STAT);
		if (stat & (STAT_INT|STAT_PARITYERROR))
			break;
		udelay(1);
	}

	return stat;
}

static int fas216_get_msg_byte(FAS216_Info *info)
{
	unsigned int stat = fas216_wait_cmd(info, CMD_MSGACCEPTED);

	if ((stat & STAT_INT) == 0)
		goto timedout;

	if ((stat & STAT_BUSMASK) != STAT_MESGIN)
		goto unexpected_phase_change;

	fas216_readb(info, REG_INST);

	stat = fas216_wait_cmd(info, CMD_TRANSFERINFO);

	if ((stat & STAT_INT) == 0)
		goto timedout;

	if (stat & STAT_PARITYERROR)
		goto parity_error;

	if ((stat & STAT_BUSMASK) != STAT_MESGIN)
		goto unexpected_phase_change;

	fas216_readb(info, REG_INST);

	return fas216_readb(info, REG_FF);

timedout:
	fas216_log(info, LOG_ERROR, "timed out waiting for message byte");
	return -1;

unexpected_phase_change:
	fas216_log(info, LOG_ERROR, "unexpected phase change: status = %02x", stat);
	return -2;

parity_error:
	fas216_log(info, LOG_ERROR, "parity error during message in phase");
	return -3;
}

/**
 * fas216_message - handle a function done interrupt from FAS216 chip
 * @info: interface which caused function done interrupt
 *
 * Handle a function done interrupt from FAS216 chip
 */
static void fas216_message(FAS216_Info *info)
{
	unsigned char *message = info->scsi.message;
	unsigned int msglen = 1;
	int msgbyte = 0;

	fas216_checkmagic(info);

	message[0] = fas216_readb(info, REG_FF);

	if (message[0] == EXTENDED_MESSAGE) {
		msgbyte = fas216_get_msg_byte(info);

		if (msgbyte >= 0) {
			message[1] = msgbyte;

			for (msglen = 2; msglen < message[1] + 2; msglen++) {
				msgbyte = fas216_get_msg_byte(info);

				if (msgbyte >= 0)
					message[msglen] = msgbyte;
				else
					break;
			}
		}
	}

	if (msgbyte == -3)
		goto parity_error;

#ifdef DEBUG_MESSAGES
	{
		int i;

		printk("scsi%d.%c: message in: ",
			info->host->host_no, fas216_target(info));
		for (i = 0; i < msglen; i++)
			printk("%02X ", message[i]);
		printk("\n");
	}
#endif

	fas216_parse_message(info, message, msglen);
	fas216_cmd(info, CMD_MSGACCEPTED);
	return;

parity_error:
	fas216_cmd(info, CMD_SETATN);
	msgqueue_flush(&info->scsi.msgs);
	msgqueue_addmsg(&info->scsi.msgs, 1, MSG_PARITY_ERROR);
	info->scsi.phase = PHASE_MSGOUT_EXPECT;
	fas216_cmd(info, CMD_MSGACCEPTED);
	return;
}

/**
 * fas216_send_command - send command after all message bytes have been sent
 * @info: interface which caused bus service
 *
 * Send a command to a target after all message bytes have been sent
 */
static void fas216_send_command(FAS216_Info *info)
{
	int i;

	fas216_checkmagic(info);

	fas216_cmd(info, CMD_NOP|CMD_WITHDMA);
	fas216_cmd(info, CMD_FLUSHFIFO);

	/* load command */
	for (i = info->scsi.SCp.sent_command; i < info->SCpnt->cmd_len; i++)
		fas216_writeb(info, REG_FF, info->SCpnt->cmnd[i]);

	fas216_cmd(info, CMD_TRANSFERINFO);

	info->scsi.phase = PHASE_COMMAND;
}

/**
 * fas216_send_messageout - handle bus service to send a message
 * @info: interface which caused bus service
 *
 * Handle bus service to send a message.
 * Note: We do not allow the device to change the data direction!
 */
static void fas216_send_messageout(FAS216_Info *info, int start)
{
	unsigned int tot_msglen = msgqueue_msglength(&info->scsi.msgs);

	fas216_checkmagic(info);

	fas216_cmd(info, CMD_FLUSHFIFO);

	if (tot_msglen) {
		struct message *msg;
		int msgnr = 0;

		while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
			int i;

			for (i = start; i < msg->length; i++)
				fas216_writeb(info, REG_FF, msg->msg[i]);

			msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF);
			start = 0;
		}
	} else
		fas216_writeb(info, REG_FF, NOP);

	fas216_cmd(info, CMD_TRANSFERINFO);

	info->scsi.phase = PHASE_MSGOUT;
}

/**
 * fas216_busservice_intr - handle bus service interrupt from FAS216 chip
 * @info: interface which caused bus service interrupt
 * @stat: Status register contents
 * @is: SCSI Status register contents
 *
 * Handle a bus service interrupt from FAS216 chip
 */
static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int is)
{
	fas216_checkmagic(info);

	fas216_log(info, LOG_BUSSERVICE,
		   "bus service: stat=%02x is=%02x phase=%02x",
		   stat, is, info->scsi.phase);

	switch (info->scsi.phase) {
	case PHASE_SELECTION:
		if ((is & IS_BITS) != IS_MSGBYTESENT)
			goto bad_is;
		break;

	case PHASE_SELSTEPS:
		switch (is & IS_BITS) {
		case IS_SELARB:
		case IS_MSGBYTESENT:
			goto bad_is;

		case IS_NOTCOMMAND:
		case IS_EARLYPHASE:
			if ((stat & STAT_BUSMASK) == STAT_MESGIN)
				break;
			goto bad_is;

		case IS_COMPLETE:
			break;
		}

	default:
		break;
	}

	fas216_cmd(info, CMD_NOP);

#define STATE(st,ph) ((ph) << 3 | (st))
	/* This table describes the legal SCSI state transitions,
	 * as described by the SCSI II spec.
	 */
	switch (STATE(stat & STAT_BUSMASK, info->scsi.phase)) {
	case STATE(STAT_DATAIN, PHASE_SELSTEPS):/* Sel w/ steps -> Data In      */
	case STATE(STAT_DATAIN, PHASE_MSGOUT):  /* Message Out  -> Data In      */
	case STATE(STAT_DATAIN, PHASE_COMMAND): /* Command      -> Data In      */
	case STATE(STAT_DATAIN, PHASE_MSGIN):   /* Message In   -> Data In      */
		info->scsi.phase = PHASE_DATAIN;
		fas216_transfer(info);
		return;

	case STATE(STAT_DATAIN, PHASE_DATAIN):  /* Data In      -> Data In      */
	case STATE(STAT_DATAOUT, PHASE_DATAOUT):/* Data Out     -> Data Out     */
		fas216_cleanuptransfer(info);
		fas216_transfer(info);
		return;

	case STATE(STAT_DATAOUT, PHASE_SELSTEPS):/* Sel w/ steps-> Data Out     */
	case STATE(STAT_DATAOUT, PHASE_MSGOUT): /* Message Out  -> Data Out     */
	case STATE(STAT_DATAOUT, PHASE_COMMAND):/* Command      -> Data Out     */
	case STATE(STAT_DATAOUT, PHASE_MSGIN):  /* Message In   -> Data Out     */
		fas216_cmd(info, CMD_FLUSHFIFO);
		info->scsi.phase = PHASE_DATAOUT;
		fas216_transfer(info);
		return;

	case STATE(STAT_STATUS, PHASE_DATAOUT): /* Data Out     -> Status       */
	case STATE(STAT_STATUS, PHASE_DATAIN):  /* Data In      -> Status       */
		fas216_stoptransfer(info);
	case STATE(STAT_STATUS, PHASE_SELSTEPS):/* Sel w/ steps -> Status       */
	case STATE(STAT_STATUS, PHASE_MSGOUT):  /* Message Out  -> Status       */
	case STATE(STAT_STATUS, PHASE_COMMAND): /* Command      -> Status       */
	case STATE(STAT_STATUS, PHASE_MSGIN):   /* Message In   -> Status       */
		fas216_cmd(info, CMD_INITCMDCOMPLETE);
		info->scsi.phase = PHASE_STATUS;
		return;

	case STATE(STAT_MESGIN, PHASE_DATAOUT): /* Data Out     -> Message In   */
	case STATE(STAT_MESGIN, PHASE_DATAIN):  /* Data In      -> Message In   */
		fas216_stoptransfer(info);
	case STATE(STAT_MESGIN, PHASE_COMMAND):	/* Command	-> Message In	*/
	case STATE(STAT_MESGIN, PHASE_SELSTEPS):/* Sel w/ steps -> Message In   */
	case STATE(STAT_MESGIN, PHASE_MSGOUT):  /* Message Out  -> Message In   */
		info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
		fas216_cmd(info, CMD_FLUSHFIFO);
		fas216_cmd(info, CMD_TRANSFERINFO);
		info->scsi.phase = PHASE_MSGIN;
		return;

	case STATE(STAT_MESGIN, PHASE_MSGIN):
		info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
		fas216_cmd(info, CMD_TRANSFERINFO);
		return;

	case STATE(STAT_COMMAND, PHASE_MSGOUT): /* Message Out  -> Command      */
	case STATE(STAT_COMMAND, PHASE_MSGIN):  /* Message In   -> Command      */
		fas216_send_command(info);
		info->scsi.phase = PHASE_COMMAND;
		return;


	/*
	 * Selection    -> Message Out
	 */
	case STATE(STAT_MESGOUT, PHASE_SELECTION):
		fas216_send_messageout(info, 1);
		return;

	/*
	 * Message Out  -> Message Out
	 */
	case STATE(STAT_MESGOUT, PHASE_SELSTEPS):
	case STATE(STAT_MESGOUT, PHASE_MSGOUT):
		/*
		 * If we get another message out phase, this usually
		 * means some parity error occurred.  Resend complete
		 * set of messages.  If we have more than one byte to
		 * send, we need to assert ATN again.
		 */
		if (info->device[info->SCpnt->device->id].parity_check) {
			/*
			 * We were testing... good, the device
			 * supports parity checking.
			 */
			info->device[info->SCpnt->device->id].parity_check = 0;
			info->device[info->SCpnt->device->id].parity_enabled = 1;
			fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
		}

		if (msgqueue_msglength(&info->scsi.msgs) > 1)
			fas216_cmd(info, CMD_SETATN);
		/*FALLTHROUGH*/

	/*
	 * Any          -> Message Out
	 */
	case STATE(STAT_MESGOUT, PHASE_MSGOUT_EXPECT):
		fas216_send_messageout(info, 0);
		return;

	/* Error recovery rules.
	 *   These either attempt to abort or retry the operation.
	 * TODO: we need more of these
	 */
	case STATE(STAT_COMMAND, PHASE_COMMAND):/* Command      -> Command      */
		/* error - we've sent out all the command bytes
		 * we have.
		 * NOTE: we need SAVE DATA POINTERS/RESTORE DATA POINTERS
		 * to include the command bytes sent for this to work
		 * correctly.
		 */
		printk(KERN_ERR "scsi%d.%c: "
			"target trying to receive more command bytes\n",
			info->host->host_no, fas216_target(info));
		fas216_cmd(info, CMD_SETATN);
		fas216_set_stc(info, 15);
		fas216_cmd(info, CMD_PADBYTES | CMD_WITHDMA);
		msgqueue_flush(&info->scsi.msgs);
		msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
		info->scsi.phase = PHASE_MSGOUT_EXPECT;
		return;
	}

	if (info->scsi.phase == PHASE_MSGIN_DISCONNECT) {
		printk(KERN_ERR "scsi%d.%c: disconnect message received, but bus service %s?\n",
			info->host->host_no, fas216_target(info),
			fas216_bus_phase(stat));
		msgqueue_flush(&info->scsi.msgs);
		fas216_cmd(info, CMD_SETATN);
		msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
		info->scsi.phase = PHASE_MSGOUT_EXPECT;
		info->scsi.aborting = 1;
		fas216_cmd(info, CMD_TRANSFERINFO);
		return;
	}
	printk(KERN_ERR "scsi%d.%c: bus phase %s after %s?\n",
		info->host->host_no, fas216_target(info),
		fas216_bus_phase(stat),
		fas216_drv_phase(info));
	print_debug_list();
	return;

bad_is:
	fas216_log(info, 0, "bus service at step %d?", is & IS_BITS);
	fas216_dumpstate(info);
	print_debug_list();

	fas216_done(info, DID_ERROR);
}

/**
 * fas216_funcdone_intr - handle a function done interrupt from FAS216 chip
 * @info: interface which caused function done interrupt
 * @stat: Status register contents
 * @is: SCSI Status register contents
 *
 * Handle a function done interrupt from FAS216 chip
 */
static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int is)
{
	unsigned int fifo_len = fas216_readb(info, REG_CFIS) & CFIS_CF;

	fas216_checkmagic(info);

	fas216_log(info, LOG_FUNCTIONDONE,
		   "function done: stat=%02x is=%02x phase=%02x",
		   stat, is, info->scsi.phase);

	switch (info->scsi.phase) {
	case PHASE_STATUS:			/* status phase - read status and msg	*/
		if (fifo_len != 2) {
			fas216_log(info, 0, "odd number of bytes in FIFO: %d", fifo_len);
		}
		/*
		 * Read status then message byte.
		 */
		info->scsi.SCp.Status = fas216_readb(info, REG_FF);
		info->scsi.SCp.Message = fas216_readb(info, REG_FF);
		info->scsi.phase = PHASE_DONE;
		fas216_cmd(info, CMD_MSGACCEPTED);
		break;

	case PHASE_IDLE:
	case PHASE_SELECTION:
	case PHASE_SELSTEPS:
		break;

	case PHASE_MSGIN:			/* message in phase			*/
		if ((stat & STAT_BUSMASK) == STAT_MESGIN) {
			info->scsi.msgin_fifo = fifo_len;
			fas216_message(info);
			break;
		}

	default:
		fas216_log(info, 0, "internal phase %s for function done?"
			"  What do I do with this?",
			fas216_target(info), fas216_drv_phase(info));
	}
}

static void fas216_bus_reset(FAS216_Info *info)
{
	neg_t sync_state;
	int i;

	msgqueue_flush(&info->scsi.msgs);

	sync_state = neg_invalid;

#ifdef SCSI2_SYNC
	if (info->ifcfg.capabilities & (FASCAP_DMA|FASCAP_PSEUDODMA))
		sync_state = neg_wait;
#endif

	info->scsi.phase = PHASE_IDLE;
	info->SCpnt = NULL; /* bug! */
	memset(&info->scsi.SCp, 0, sizeof(info->scsi.SCp));

	for (i = 0; i < 8; i++) {
		info->device[i].disconnect_ok	= info->ifcfg.disconnect_ok;
		info->device[i].sync_state	= sync_state;
		info->device[i].period		= info->ifcfg.asyncperiod / 4;
		info->device[i].stp		= info->scsi.async_stp;
		info->device[i].sof		= 0;
		info->device[i].wide_xfer	= 0;
	}

	info->rst_bus_status = 1;
	wake_up(&info->eh_wait);
}

/**
 * fas216_intr - handle interrupts to progress a command
 * @info: interface to service
 *
 * Handle interrupts from the interface to progress a command
 */
irqreturn_t fas216_intr(FAS216_Info *info)
{
	unsigned char inst, is, stat;
	int handled = IRQ_NONE;

	fas216_checkmagic(info);

	stat = fas216_readb(info, REG_STAT);
	is = fas216_readb(info, REG_IS);
	inst = fas216_readb(info, REG_INST);

	add_debug_list(stat, is, inst, info->scsi.phase);

	if (stat & STAT_INT) {
		if (inst & INST_BUSRESET) {
			fas216_log(info, 0, "bus reset detected");
			fas216_bus_reset(info);
			scsi_report_bus_reset(info->host, 0);
		} else if (inst & INST_ILLEGALCMD) {
			fas216_log(info, LOG_ERROR, "illegal command given\n");
			fas216_dumpstate(info);
			print_debug_list();
		} else if (inst & INST_DISCONNECT)
			fas216_disconnect_intr(info);
		else if (inst & INST_RESELECTED)	/* reselected			*/
			fas216_reselected_intr(info);
		else if (inst & INST_BUSSERVICE)	/* bus service request		*/
			fas216_busservice_intr(info, stat, is);
		else if (inst & INST_FUNCDONE)		/* function done		*/
			fas216_funcdone_intr(info, stat, is);
		else
		    	fas216_log(info, 0, "unknown interrupt received:"
				" phase %s inst %02X is %02X stat %02X",
				fas216_drv_phase(info), inst, is, stat);
		handled = IRQ_HANDLED;
	}
	return handled;
}

static void __fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
{
	int tot_msglen;

	/* following what the ESP driver says */
	fas216_set_stc(info, 0);
	fas216_cmd(info, CMD_NOP | CMD_WITHDMA);

	/* flush FIFO */
	fas216_cmd(info, CMD_FLUSHFIFO);

	/* load bus-id and timeout */
	fas216_writeb(info, REG_SDID, BUSID(SCpnt->device->id));
	fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);

	/* synchronous transfers */
	fas216_set_sync(info, SCpnt->device->id);

	tot_msglen = msgqueue_msglength(&info->scsi.msgs);

#ifdef DEBUG_MESSAGES
	{
		struct message *msg;
		int msgnr = 0, i;

		printk("scsi%d.%c: message out: ",
			info->host->host_no, '0' + SCpnt->device->id);
		while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
			printk("{ ");
			for (i = 0; i < msg->length; i++)
				printk("%02x ", msg->msg[i]);
			printk("} ");
		}
		printk("\n");
	}
#endif

	if (tot_msglen == 1 || tot_msglen == 3) {
		/*
		 * We have an easy message length to send...
		 */
		struct message *msg;
		int msgnr = 0, i;

		info->scsi.phase = PHASE_SELSTEPS;

		/* load message bytes */
		while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
			for (i = 0; i < msg->length; i++)
				fas216_writeb(info, REG_FF, msg->msg[i]);
			msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF);
		}

		/* load command */
		for (i = 0; i < SCpnt->cmd_len; i++)
			fas216_writeb(info, REG_FF, SCpnt->cmnd[i]);

		if (tot_msglen == 1)
			fas216_cmd(info, CMD_SELECTATN);
		else
			fas216_cmd(info, CMD_SELECTATN3);
	} else {
		/*
		 * We have an unusual number of message bytes to send.
		 *  Load first byte into fifo, and issue SELECT with ATN and
		 *  stop steps.
		 */
		struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0);

		fas216_writeb(info, REG_FF, msg->msg[0]);
		msg->fifo = 1;

		fas216_cmd(info, CMD_SELECTATNSTOP);
	}
}

/*
 * Decide whether we need to perform a parity test on this device.
 * Can also be used to force parity error conditions during initial
 * information transfer phase (message out) for test purposes.
 */
static int parity_test(FAS216_Info *info, int target)
{
#if 0
	if (target == 3) {
		info->device[target].parity_check = 0;
		return 1;
	}
#endif
	return info->device[target].parity_check;
}

static void fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
{
	int disconnect_ok;

	/*
	 * claim host busy
	 */
	info->scsi.phase = PHASE_SELECTION;
	info->scsi.SCp = SCpnt->SCp;
	info->SCpnt = SCpnt;
	info->dma.transfer_type = fasdma_none;

	if (parity_test(info, SCpnt->device->id))
		fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_PTE);
	else
		fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);

	/*
	 * Don't allow request sense commands to disconnect.
	 */
	disconnect_ok = SCpnt->cmnd[0] != REQUEST_SENSE &&
			info->device[SCpnt->device->id].disconnect_ok;

	/*
	 * build outgoing message bytes
	 */
	msgqueue_flush(&info->scsi.msgs);
	msgqueue_addmsg(&info->scsi.msgs, 1, IDENTIFY(disconnect_ok, SCpnt->device->lun));

	/*
	 * add tag message if required
	 */
	if (SCpnt->tag)
		msgqueue_addmsg(&info->scsi.msgs, 2, SIMPLE_QUEUE_TAG, SCpnt->tag);

	do {
#ifdef SCSI2_SYNC
		if ((info->device[SCpnt->device->id].sync_state == neg_wait ||
		     info->device[SCpnt->device->id].sync_state == neg_complete) &&
		    (SCpnt->cmnd[0] == REQUEST_SENSE ||
		     SCpnt->cmnd[0] == INQUIRY)) {
			info->device[SCpnt->device->id].sync_state = neg_inprogress;
			msgqueue_addmsg(&info->scsi.msgs, 5,
					EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
					1000 / info->ifcfg.clockrate,
					info->ifcfg.sync_max_depth);
			break;
		}
#endif
	} while (0);

	__fas216_start_command(info, SCpnt);
}

static void fas216_allocate_tag(FAS216_Info *info, Scsi_Cmnd *SCpnt)
{
#ifdef SCSI2_TAG
	/*
	 * tagged queuing - allocate a new tag to this command
	 */
	if (SCpnt->device->simple_tags && SCpnt->cmnd[0] != REQUEST_SENSE &&
	    SCpnt->cmnd[0] != INQUIRY) {
	    SCpnt->device->current_tag += 1;
		if (SCpnt->device->current_tag == 0)
		    SCpnt->device->current_tag = 1;
			SCpnt->tag = SCpnt->device->current_tag;
	} else
#endif
		set_bit(SCpnt->device->id * 8 + SCpnt->device->lun, info->busyluns);

	info->stats.removes += 1;
	switch (SCpnt->cmnd[0]) {
	case WRITE_6:
	case WRITE_10:
	case WRITE_12:
		info->stats.writes += 1;
		break;
	case READ_6:
	case READ_10:
	case READ_12:
		info->stats.reads += 1;
		break;
	default:
		info->stats.miscs += 1;
		break;
	}
}

static void fas216_do_bus_device_reset(FAS216_Info *info, Scsi_Cmnd *SCpnt)
{
	struct message *msg;

	/*
	 * claim host busy
	 */
	info->scsi.phase = PHASE_SELECTION;
	info->scsi.SCp = SCpnt->SCp;
	info->SCpnt = SCpnt;
	info->dma.transfer_type = fasdma_none;

	fas216_log(info, LOG_ERROR, "sending bus device reset");

	msgqueue_flush(&info->scsi.msgs);
	msgqueue_addmsg(&info->scsi.msgs, 1, BUS_DEVICE_RESET);

	/* following what the ESP driver says */
	fas216_set_stc(info, 0);
	fas216_cmd(info, CMD_NOP | CMD_WITHDMA);

	/* flush FIFO */
	fas216_cmd(info, CMD_FLUSHFIFO);

	/* load bus-id and timeout */
	fas216_writeb(info, REG_SDID, BUSID(SCpnt->device->id));
	fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);

	/* synchronous transfers */
	fas216_set_sync(info, SCpnt->device->id);

	msg = msgqueue_getmsg(&info->scsi.msgs, 0);

	fas216_writeb(info, REG_FF, BUS_DEVICE_RESET);
	msg->fifo = 1;

	fas216_cmd(info, CMD_SELECTATNSTOP);
}

/**
 * fas216_kick - kick a command to the interface
 * @info: our host interface to kick
 *
 * Kick a command to the interface, interface should be idle.
 * Notes: Interrupts are always disabled!
 */
static void fas216_kick(FAS216_Info *info)
{
	Scsi_Cmnd *SCpnt = NULL;
#define TYPE_OTHER	0
#define TYPE_RESET	1
#define TYPE_QUEUE	2
	int where_from = TYPE_OTHER;

	fas216_checkmagic(info);

	/*
	 * Obtain the next command to process.
	 */
	do {
		if (info->rstSCpnt) {
			SCpnt = info->rstSCpnt;
			/* don't remove it */
			where_from = TYPE_RESET;
			break;
		}

		if (info->reqSCpnt) {
			SCpnt = info->reqSCpnt;
			info->reqSCpnt = NULL;
			break;
		}

		if (info->origSCpnt) {
			SCpnt = info->origSCpnt;
			info->origSCpnt = NULL;
			break;
		}

		/* retrieve next command */
		if (!SCpnt) {
			SCpnt = queue_remove_exclude(&info->queues.issue,
						     info->busyluns);
			where_from = TYPE_QUEUE;
			break;
		}
	} while (0);

	if (!SCpnt) {
		/*
		 * no command pending, so enable reselection.
		 */
		fas216_cmd(info, CMD_ENABLESEL);
		return;
	}

	/*
	 * We're going to start a command, so disable reselection
	 */
	fas216_cmd(info, CMD_DISABLESEL);

	if (info->scsi.disconnectable && info->SCpnt) {
		fas216_log(info, LOG_CONNECT,
			"moved command for %d to disconnected queue",
			info->SCpnt->device->id);
		queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
		info->scsi.disconnectable = 0;
		info->SCpnt = NULL;
	}

	fas216_log_command(info, LOG_CONNECT | LOG_MESSAGES, SCpnt,
			   "starting");

	switch (where_from) {
	case TYPE_QUEUE:
		fas216_allocate_tag(info, SCpnt);
	case TYPE_OTHER:
		fas216_start_command(info, SCpnt);
		break;
	case TYPE_RESET:
		fas216_do_bus_device_reset(info, SCpnt);
		break;
	}

	fas216_log(info, LOG_CONNECT, "select: data pointers [%p, %X]",
		info->scsi.SCp.ptr, info->scsi.SCp.this_residual);

	/*
	 * should now get either DISCONNECT or
	 * (FUNCTION DONE with BUS SERVICE) interrupt
	 */
}

/*
 * Clean up from issuing a BUS DEVICE RESET message to a device.
 */
static void
fas216_devicereset_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
{
	fas216_log(info, LOG_ERROR, "fas216 device reset complete");

	info->rstSCpnt = NULL;
	info->rst_dev_status = 1;
	wake_up(&info->eh_wait);
}

/**
 * fas216_rq_sns_done - Finish processing automatic request sense command
 * @info: interface that completed
 * @SCpnt: command that completed
 * @result: driver byte of result
 *
 * Finish processing automatic request sense command
 */
static void
fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
{
	fas216_log_target(info, LOG_CONNECT, SCpnt->device->id,
		   "request sense complete, result=0x%04x%02x%02x",
		   result, SCpnt->SCp.Message, SCpnt->SCp.Status);

	if (result != DID_OK || SCpnt->SCp.Status != GOOD)
		/*
		 * Something went wrong.  Make sure that we don't
		 * have valid data in the sense buffer that could
		 * confuse the higher levels.
		 */
		memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
//printk("scsi%d.%c: sense buffer: ", info->host->host_no, '0' + SCpnt->device->id);
//{ int i; for (i = 0; i < 32; i++) printk("%02x ", SCpnt->sense_buffer[i]); printk("\n"); }
	/*
	 * Note that we don't set SCpnt->result, since that should
	 * reflect the status of the command that we were asked by
	 * the upper layers to process.  This would have been set
	 * correctly by fas216_std_done.
	 */
	SCpnt->scsi_done(SCpnt);
}

/**
 * fas216_std_done - finish processing of standard command
 * @info: interface that completed
 * @SCpnt: command that completed
 * @result: driver byte of result
 *
 * Finish processing of standard command
 */
static void
fas216_std_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
{
	info->stats.fins += 1;

	SCpnt->result = result << 16 | info->scsi.SCp.Message << 8 |
			info->scsi.SCp.Status;

	fas216_log_command(info, LOG_CONNECT, SCpnt,
		"command complete, result=0x%08x", SCpnt->result);

	/*
	 * If the driver detected an error, we're all done.
	 */
	if (host_byte(SCpnt->result) != DID_OK ||
	    msg_byte(SCpnt->result) != COMMAND_COMPLETE)
		goto done;

	/*
	 * If the command returned CHECK_CONDITION or COMMAND_TERMINATED
	 * status, request the sense information.
	 */
	if (status_byte(SCpnt->result) == CHECK_CONDITION ||
	    status_byte(SCpnt->result) == COMMAND_TERMINATED)
		goto request_sense;

	/*
	 * If the command did not complete with GOOD status,
	 * we are all done here.
	 */
	if (status_byte(SCpnt->result) != GOOD)
		goto done;

	/*
	 * We have successfully completed a command.  Make sure that
	 * we do not have any buffers left to transfer.  The world
	 * is not perfect, and we seem to occasionally hit this.
	 * It can be indicative of a buggy driver, target or the upper
	 * levels of the SCSI code.
	 */
	if (info->scsi.SCp.ptr) {
		switch (SCpnt->cmnd[0]) {
		case INQUIRY:
		case START_STOP:
		case MODE_SENSE:
			break;

		default:
			printk(KERN_ERR "scsi%d.%c: incomplete data transfer "
				"detected: res=%08X ptr=%p len=%X CDB: ",
				info->host->host_no, '0' + SCpnt->device->id,
				SCpnt->result, info->scsi.SCp.ptr,
				info->scsi.SCp.this_residual);
			print_command(SCpnt->cmnd);
			SCpnt->result &= ~(255 << 16);
			SCpnt->result |= DID_BAD_TARGET << 16;
			goto request_sense;
		}
	}

done:
	if (SCpnt->scsi_done) {
		SCpnt->scsi_done(SCpnt);
		return;
	}

	panic("scsi%d.H: null scsi_done function in fas216_done",
		info->host->host_no);


request_sense:
	if (SCpnt->cmnd[0] == REQUEST_SENSE)
		goto done;

	fas216_log_target(info, LOG_CONNECT, SCpnt->device->id,
			  "requesting sense");
	memset(SCpnt->cmnd, 0, sizeof (SCpnt->cmnd));
	SCpnt->cmnd[0] = REQUEST_SENSE;
	SCpnt->cmnd[1] = SCpnt->device->lun << 5;
	SCpnt->cmnd[4] = sizeof(SCpnt->sense_buffer);
	SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
	SCpnt->SCp.buffer = NULL;
	SCpnt->SCp.buffers_residual = 0;
	SCpnt->SCp.ptr = (char *)SCpnt->sense_buffer;
	SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer);
	SCpnt->SCp.Message = 0;
	SCpnt->SCp.Status = 0;
	SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer);
	SCpnt->sc_data_direction = SCSI_DATA_READ;
	SCpnt->use_sg = 0;
	SCpnt->tag = 0;
	SCpnt->host_scribble = (void *)fas216_rq_sns_done;

	/*
	 * Place this command into the high priority "request
	 * sense" slot.  This will be the very next command
	 * executed, unless a target connects to us.
	 */
	if (info->reqSCpnt)
		printk(KERN_WARNING "scsi%d.%c: loosing request command\n",
			info->host->host_no, '0' + SCpnt->device->id);
	info->reqSCpnt = SCpnt;
}

/**
 * fas216_done - complete processing for current command
 * @info: interface that completed
 * @result: driver byte of result
 *
 * Complete processing for current command
 */
static void fas216_done(FAS216_Info *info, unsigned int result)
{
	void (*fn)(FAS216_Info *, Scsi_Cmnd *, unsigned int);
	Scsi_Cmnd *SCpnt;
	unsigned long flags;

	fas216_checkmagic(info);

	if (!info->SCpnt)
		goto no_command;

	SCpnt = info->SCpnt;
	info->SCpnt = NULL;
    	info->scsi.phase = PHASE_IDLE;

	if (info->scsi.aborting) {
		fas216_log(info, 0, "uncaught abort - returning DID_ABORT");
		result = DID_ABORT;
		info->scsi.aborting = 0;
	}

	/*
	 * Sanity check the completion - if we have zero bytes left
	 * to transfer, we should not have a valid pointer.
	 */
	if (info->scsi.SCp.ptr && info->scsi.SCp.this_residual == 0) {
		printk("scsi%d.%c: zero bytes left to transfer, but "
		       "buffer pointer still valid: ptr=%p len=%08x CDB: ",
		       info->host->host_no, '0' + SCpnt->device->id,
		       info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
		info->scsi.SCp.ptr = NULL;
		print_command(SCpnt->cmnd);
	}

	/*
	 * Clear down this command as completed.  If we need to request
	 * the sense information, fas216_kick will re-assert the busy
	 * status.
	 */
	info->device[SCpnt->device->id].parity_check = 0;
	clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, info->busyluns);

	fn = (void (*)(FAS216_Info *, Scsi_Cmnd *, unsigned int))SCpnt->host_scribble;
	fn(info, SCpnt, result);

	if (info->scsi.irq != NO_IRQ) {
		spin_lock_irqsave(&info->host_lock, flags);
		if (info->scsi.phase == PHASE_IDLE)
			fas216_kick(info);
		spin_unlock_irqrestore(&info->host_lock, flags);
	}
	return;

no_command:
	panic("scsi%d.H: null command in fas216_done",
		info->host->host_no);
}

/**
 * fas216_queue_command - queue a command for adapter to process.
 * @SCpnt: Command to queue
 * @done: done function to call once command is complete
 *
 * Queue a command for adapter to process.
 * Returns: 0 on success, else error.
 * Notes: io_request_lock is held, interrupts are disabled.
 */
int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
{
	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
	int result;

	fas216_checkmagic(info);

	fas216_log_command(info, LOG_CONNECT, SCpnt,
			   "received command (%p)", SCpnt);

	SCpnt->scsi_done = done;
	SCpnt->host_scribble = (void *)fas216_std_done;
	SCpnt->result = 0;

	init_SCp(SCpnt);

	info->stats.queues += 1;
	SCpnt->tag = 0;

	spin_lock(&info->host_lock);

	/*
	 * Add command into execute queue and let it complete under
	 * whatever scheme we're using.
	 */
	result = !queue_add_cmd_ordered(&info->queues.issue, SCpnt);

	/*
	 * If we successfully added the command,
	 * kick the interface to get it moving.
	 */
	if (result == 0 && info->scsi.phase == PHASE_IDLE)
		fas216_kick(info);
	spin_unlock(&info->host_lock);

	fas216_log_target(info, LOG_CONNECT, -1, "queue %s",
		result ? "failure" : "success");

	return result;
}

/**
 * fas216_internal_done - trigger restart of a waiting thread in fas216_noqueue_command
 * @SCpnt: Command to wake
 *
 * Trigger restart of a waiting thread in fas216_command
 */
static void fas216_internal_done(Scsi_Cmnd *SCpnt)
{
	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;

	fas216_checkmagic(info);

	info->internal_done = 1;
}

/**
 * fas216_noqueue_command - process a command for the adapter.
 * @SCpnt: Command to queue
 *
 * Queue a command for adapter to process.
 * Returns: scsi result code.
 * Notes: io_request_lock is held, interrupts are disabled.
 */
int fas216_noqueue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
{
	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;

	fas216_checkmagic(info);

	/*
	 * We should only be using this if we don't have an interrupt.
	 * Provide some "incentive" to use the queueing code.
	 */
	BUG_ON(info->scsi.irq != NO_IRQ);

	info->internal_done = 0;
	fas216_queue_command(SCpnt, fas216_internal_done);

	/*
	 * This wastes time, since we can't return until the command is
	 * complete. We can't sleep either since we may get re-entered!
	 * However, we must re-enable interrupts, or else we'll be
	 * waiting forever.
	 */
	spin_unlock_irq(info->host->host_lock);

	while (!info->internal_done) {
		/*
		 * If we don't have an IRQ, then we must poll the card for
		 * it's interrupt, and use that to call this driver's
		 * interrupt routine.  That way, we keep the command
		 * progressing.  Maybe we can add some inteligence here
		 * and go to sleep if we know that the device is going
		 * to be some time (eg, disconnected).
		 */
		if (fas216_readb(info, REG_STAT) & STAT_INT) {
			spin_lock_irq(info->host->host_lock);
			fas216_intr(info);
			spin_unlock_irq(info->host->host_lock);
		}
	}

	spin_lock_irq(info->host->host_lock);

	done(SCpnt);

	return 0;
}

/*
 * Error handler timeout function.  Indicate that we timed out,
 * and wake up any error handler process so it can continue.
 */
static void fas216_eh_timer(unsigned long data)
{
	FAS216_Info *info = (FAS216_Info *)data;

	fas216_log(info, LOG_ERROR, "error handling timed out\n");

	del_timer(&info->eh_timer);

	if (info->rst_bus_status == 0)
		info->rst_bus_status = -1;
	if (info->rst_dev_status == 0)
		info->rst_dev_status = -1;

	wake_up(&info->eh_wait);
}

enum res_find {
	res_failed,		/* not found			*/
	res_success,		/* command on issue queue	*/
	res_hw_abort		/* command on disconnected dev	*/
};

/**
 * fas216_do_abort - decide how to abort a command
 * @SCpnt: command to abort
 *
 * Decide how to abort a command.
 * Returns: abort status
 */
static enum res_find fas216_find_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
{
	enum res_find res = res_failed;

	if (queue_remove_cmd(&info->queues.issue, SCpnt)) {
		/*
		 * The command was on the issue queue, and has not been
		 * issued yet.  We can remove the command from the queue,
		 * and acknowledge the abort.  Neither the device nor the
		 * interface know about the command.
		 */
		printk("on issue queue ");

		res = res_success;
	} else if (queue_remove_cmd(&info->queues.disconnected, SCpnt)) {
		/*
		 * The command was on the disconnected queue.  We must
		 * reconnect with the device if possible, and send it
		 * an abort message.
		 */
		printk("on disconnected queue ");

		res = res_hw_abort;
	} else if (info->SCpnt == SCpnt) {
		printk("executing ");

		switch (info->scsi.phase) {
		/*
		 * If the interface is idle, and the command is 'disconnectable',
		 * then it is the same as on the disconnected queue.
		 */
		case PHASE_IDLE:
			if (info->scsi.disconnectable) {
				info->scsi.disconnectable = 0;
				info->SCpnt = NULL;
				res = res_hw_abort;
			}
			break;

		default:
			break;
		}
	} else if (info->origSCpnt == SCpnt) {
		/*
		 * The command will be executed next, but a command
		 * is currently using the interface.  This is similar to
		 * being on the issue queue, except the busylun bit has
		 * been set.
		 */
		info->origSCpnt = NULL;
		clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, info->busyluns);
		printk("waiting for execution ");
		res = res_success;
	} else
		printk("unknown ");

	return res;
}

/**
 * fas216_eh_abort - abort this command
 * @SCpnt: command to abort
 *
 * Abort this command.
 * Returns: FAILED if unable to abort
 * Notes: io_request_lock is taken, and irqs are disabled
 */
int fas216_eh_abort(Scsi_Cmnd *SCpnt)
{
	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
	int result = FAILED;

	fas216_checkmagic(info);

	info->stats.aborts += 1;

	printk(KERN_WARNING "scsi%d: abort command ", info->host->host_no);
	print_command(SCpnt->data_cmnd);

	print_debug_list();
	fas216_dumpstate(info);

	printk(KERN_WARNING "scsi%d: abort %p ", info->host->host_no, SCpnt);

	switch (fas216_find_command(info, SCpnt)) {
	/*
	 * We found the command, and cleared it out.  Either
	 * the command is still known to be executing on the
	 * target, or the busylun bit is not set.
	 */
	case res_success:
		printk("success\n");
		result = SUCCESS;
		break;

	/*
	 * We need to reconnect to the target and send it an
	 * ABORT or ABORT_TAG message.  We can only do this
	 * if the bus is free.
	 */
	case res_hw_abort:
		

	/*
	 * We are unable to abort the command for some reason.
	 */
	default:
	case res_failed:
		printk("failed\n");
		break;
	}

	return result;
}

/**
 * fas216_eh_device_reset - Reset the device associated with this command
 * @SCpnt: command specifing device to reset
 *
 * Reset the device associated with this command.
 * Returns: FAILED if unable to reset.
 * Notes: We won't be re-entered, so we'll only have one device
 * reset on the go at one time.
 */
int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
{
	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
	unsigned long flags;
	int i, res = FAILED, target = SCpnt->device->id;

	fas216_log(info, LOG_ERROR, "device reset for target %d", target);

	spin_lock_irqsave(&info->host_lock, flags);

	do {
		/*
		 * If we are currently connected to a device, and
		 * it is the device we want to reset, there is
		 * nothing we can do here.  Chances are it is stuck,
		 * and we need a bus reset.
		 */
		if (info->SCpnt && !info->scsi.disconnectable &&
		    info->SCpnt->device->id == SCpnt->device->id)
			break;

		/*
		 * We're going to be resetting this device.  Remove
		 * all pending commands from the driver.  By doing
		 * so, we guarantee that we won't touch the command
		 * structures except to process the reset request.
		 */
		queue_remove_all_target(&info->queues.issue, target);
		queue_remove_all_target(&info->queues.disconnected, target);
		if (info->origSCpnt && info->origSCpnt->device->id == target)
			info->origSCpnt = NULL;
		if (info->reqSCpnt && info->reqSCpnt->device->id == target)
			info->reqSCpnt = NULL;
		for (i = 0; i < 8; i++)
			clear_bit(target * 8 + i, info->busyluns);

		/*
		 * Hijack this SCSI command structure to send
		 * a bus device reset message to this device.
		 */
		SCpnt->host_scribble = (void *)fas216_devicereset_done;

		info->rst_dev_status = 0;
		info->rstSCpnt = SCpnt;

		if (info->scsi.phase == PHASE_IDLE)
			fas216_kick(info);

		mod_timer(&info->eh_timer, 30 * HZ);
		spin_unlock_irqrestore(&info->host_lock, flags);

		/*
		 * Wait up to 30 seconds for the reset to complete.
		 */
		wait_event(info->eh_wait, info->rst_dev_status);

		del_timer_sync(&info->eh_timer);
		spin_lock_irqsave(&info->host_lock, flags);
		info->rstSCpnt = NULL;

		if (info->rst_dev_status == 1)
			res = SUCCESS;
	} while (0);

	SCpnt->host_scribble = NULL;
	spin_unlock_irqrestore(&info->host_lock, flags);

	fas216_log(info, LOG_ERROR, "device reset complete: %s\n",
		   res == SUCCESS ? "success" : "failed");

	return res;
}

/**
 * fas216_eh_bus_reset - Reset the bus associated with the command
 * @SCpnt: command specifing bus to reset
 *
 * Reset the bus associated with the command.
 * Returns: FAILED if unable to reset.
 * Notes: Further commands are blocked.
 */
int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
{
	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
	unsigned long flags;
	Scsi_Device *SDpnt;

	fas216_checkmagic(info);
	fas216_log(info, LOG_ERROR, "resetting bus");

	info->stats.bus_resets += 1;

	spin_lock_irqsave(&info->host_lock, flags);

	/*
	 * Stop all activity on this interface.
	 */
	fas216_aborttransfer(info);
	fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]);

	/*
	 * Clear any pending interrupts.
	 */
	while (fas216_readb(info, REG_STAT) & STAT_INT)
		fas216_readb(info, REG_INST);

	info->rst_bus_status = 0;

	/*
	 * For each attached hard-reset device, clear out
	 * all command structures.  Leave the running
	 * command in place.
	 */
	shost_for_each_device(SDpnt, info->host) {
		int i;

		if (SDpnt->soft_reset)
			continue;

		queue_remove_all_target(&info->queues.issue, SDpnt->id);
		queue_remove_all_target(&info->queues.disconnected, SDpnt->id);
		if (info->origSCpnt && info->origSCpnt->device->id == SDpnt->id)
			info->origSCpnt = NULL;
		if (info->reqSCpnt && info->reqSCpnt->device->id == SDpnt->id)
			info->reqSCpnt = NULL;
		info->SCpnt = NULL;

		for (i = 0; i < 8; i++)
			clear_bit(SDpnt->id * 8 + i, info->busyluns);
	}

	info->scsi.phase = PHASE_IDLE;

	/*
	 * Reset the SCSI bus.  Device cleanup happens in
	 * the interrupt handler.
	 */
	fas216_cmd(info, CMD_RESETSCSI);

	mod_timer(&info->eh_timer, jiffies + HZ);
	spin_unlock_irqrestore(&info->host_lock, flags);

	/*
	 * Wait one second for the interrupt.
	 */
	wait_event(info->eh_wait, info->rst_bus_status);
	del_timer_sync(&info->eh_timer);

	fas216_log(info, LOG_ERROR, "bus reset complete: %s\n",
		   info->rst_bus_status == 1 ? "success" : "failed");

	return info->rst_bus_status == 1 ? SUCCESS : FAILED;
}

/**
 * fas216_init_chip - Initialise FAS216 state after reset
 * @info: state structure for interface
 *
 * Initialise FAS216 state after reset
 */
static void fas216_init_chip(FAS216_Info *info)
{
	unsigned int clock = ((info->ifcfg.clockrate - 1) / 5 + 1) & 7;
	fas216_writeb(info, REG_CLKF, clock);
	fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
	fas216_writeb(info, REG_CNTL2, info->scsi.cfg[1]);
	fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]);
	fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
	fas216_writeb(info, REG_SOF, 0);
	fas216_writeb(info, REG_STP, info->scsi.async_stp);
	fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
}

/**
 * fas216_eh_host_reset - Reset the host associated with this command
 * @SCpnt: command specifing host to reset
 *
 * Reset the host associated with this command.
 * Returns: FAILED if unable to reset.
 * Notes: io_request_lock is taken, and irqs are disabled
 */
int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
{
	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;

	fas216_checkmagic(info);

	printk("scsi%d.%c: %s: resetting host\n",
		info->host->host_no, '0' + SCpnt->device->id, __FUNCTION__);

	/*
	 * Reset the SCSI chip.
	 */
	fas216_cmd(info, CMD_RESETCHIP);

	/*
	 * Ugly ugly ugly!
	 * We need to release the host_lock and enable
	 * IRQs if we sleep, but we must relock and disable
	 * IRQs after the sleep.
	 */
	spin_unlock_irq(info->host->host_lock);
	msleep(50 * 1000/100);
	spin_lock_irq(info->host->host_lock);

	/*
	 * Release the SCSI reset.
	 */
	fas216_cmd(info, CMD_NOP);

	fas216_init_chip(info);

	return SUCCESS;
}

#define TYPE_UNKNOWN	0
#define TYPE_NCR53C90	1
#define TYPE_NCR53C90A	2
#define TYPE_NCR53C9x	3
#define TYPE_Am53CF94	4
#define TYPE_EmFAS216	5
#define TYPE_QLFAS216	6

static char *chip_types[] = {
	"unknown",
	"NS NCR53C90",
	"NS NCR53C90A",
	"NS NCR53C9x",
	"AMD Am53CF94",
	"Emulex FAS216",
	"QLogic FAS216"
};

static int fas216_detect_type(FAS216_Info *info)
{
	int family, rev;

	/*
	 * Reset the chip.
	 */
	fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
	udelay(50);
	fas216_writeb(info, REG_CMD, CMD_NOP);

	/*
	 * Check to see if control reg 2 is present.
	 */
	fas216_writeb(info, REG_CNTL3, 0);
	fas216_writeb(info, REG_CNTL2, CNTL2_S2FE);

	/*
	 * If we are unable to read back control reg 2
	 * correctly, it is not present, and we have a
	 * NCR53C90.
	 */
	if ((fas216_readb(info, REG_CNTL2) & (~0xe0)) != CNTL2_S2FE)
		return TYPE_NCR53C90;

	/*
	 * Now, check control register 3
	 */
	fas216_writeb(info, REG_CNTL2, 0);
	fas216_writeb(info, REG_CNTL3, 0);
	fas216_writeb(info, REG_CNTL3, 5);

	/*
	 * If we are unable to read the register back
	 * correctly, we have a NCR53C90A
	 */
	if (fas216_readb(info, REG_CNTL3) != 5)
		return TYPE_NCR53C90A;

	/*
	 * Now read the ID from the chip.
	 */
	fas216_writeb(info, REG_CNTL3, 0);

	fas216_writeb(info, REG_CNTL3, CNTL3_ADIDCHK);
	fas216_writeb(info, REG_CNTL3, 0);

	fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
	udelay(50);
	fas216_writeb(info, REG_CMD, CMD_WITHDMA | CMD_NOP);

	fas216_writeb(info, REG_CNTL2, CNTL2_ENF);
	fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
	udelay(50);
	fas216_writeb(info, REG_CMD, CMD_NOP);

	rev     = fas216_readb(info, REG_ID);
	family  = rev >> 3;
	rev    &= 7;

	switch (family) {
	case 0x01:
		if (rev == 4)
			return TYPE_Am53CF94;
		break;

	case 0x02:
		switch (rev) {
		case 2:
			return TYPE_EmFAS216;
		case 3:
			return TYPE_QLFAS216;
		}
		break;

	default:
		break;
	}
	printk("family %x rev %x\n", family, rev);
	return TYPE_NCR53C9x;
}

/**
 * fas216_reset_state - Initialise driver internal state
 * @info: state to initialise
 *
 * Initialise driver internal state
 */
static void fas216_reset_state(FAS216_Info *info)
{
	int i;

	fas216_checkmagic(info);

	fas216_bus_reset(info);

	/*
	 * Clear out all stale info in our state structure
	 */
	memset(info->busyluns, 0, sizeof(info->busyluns));
	info->scsi.disconnectable = 0;
	info->scsi.aborting = 0;

	for (i = 0; i < 8; i++) {
		info->device[i].parity_enabled	= 0;
		info->device[i].parity_check	= 1;
	}

	/*
	 * Drain all commands on disconnected queue
	 */
	while (queue_remove(&info->queues.disconnected) != NULL);

	/*
	 * Remove executing commands.
	 */
	info->SCpnt     = NULL;
	info->reqSCpnt  = NULL;
	info->rstSCpnt  = NULL;
	info->origSCpnt = NULL;
}

/**
 * fas216_init - initialise FAS/NCR/AMD SCSI structures.
 * @host: a driver-specific filled-out structure
 *
 * Initialise FAS/NCR/AMD SCSI structures.
 * Returns: 0 on success
 */
int fas216_init(struct Scsi_Host *host)
{
	FAS216_Info *info = (FAS216_Info *)host->hostdata;

	info->magic_start    = MAGIC;
	info->magic_end      = MAGIC;
	info->host           = host;
	info->scsi.cfg[0]    = host->this_id | CNTL1_PERE;
	info->scsi.cfg[1]    = CNTL2_ENF | CNTL2_S2FE;
	info->scsi.cfg[2]    = info->ifcfg.cntl3 |
			       CNTL3_ADIDCHK | CNTL3_QTAG | CNTL3_G2CB | CNTL3_LBTM;
	info->scsi.async_stp = fas216_syncperiod(info, info->ifcfg.asyncperiod);

	info->rst_dev_status = -1;
	info->rst_bus_status = -1;
	init_waitqueue_head(&info->eh_wait);
	init_timer(&info->eh_timer);
	info->eh_timer.data  = (unsigned long)info;
	info->eh_timer.function = fas216_eh_timer;
	
	spin_lock_init(&info->host_lock);

	memset(&info->stats, 0, sizeof(info->stats));

	msgqueue_initialise(&info->scsi.msgs);

	if (!queue_initialise(&info->queues.issue))
		return -ENOMEM;

	if (!queue_initialise(&info->queues.disconnected)) {
		queue_free(&info->queues.issue);
		return -ENOMEM;
	}

	return 0;
}

/**
 * fas216_add - initialise FAS/NCR/AMD SCSI ic.
 * @host: a driver-specific filled-out structure
 * @dev: parent device
 *
 * Initialise FAS/NCR/AMD SCSI ic.
 * Returns: 0 on success
 */
int fas216_add(struct Scsi_Host *host, struct device *dev)
{
	FAS216_Info *info = (FAS216_Info *)host->hostdata;
	int type, ret;

	if (info->ifcfg.clockrate <= 10 || info->ifcfg.clockrate > 40) {
		printk(KERN_CRIT "fas216: invalid clock rate %u MHz\n",
			info->ifcfg.clockrate);
		return -EINVAL;
	}

	fas216_reset_state(info);
	type = fas216_detect_type(info);
	info->scsi.type = chip_types[type];

	udelay(300);

	/*
	 * Initialise the chip correctly.
	 */
	fas216_init_chip(info);

	/*
	 * Reset the SCSI bus.  We don't want to see
	 * the resulting reset interrupt, so mask it
	 * out.
	 */
	fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_DISR);
	fas216_writeb(info, REG_CMD, CMD_RESETSCSI);

	/*
	 * scsi standard says wait 250ms
	 */
	spin_unlock_irq(info->host->host_lock);
	msleep(100*1000/100);
	spin_lock_irq(info->host->host_lock);

	fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
	fas216_readb(info, REG_INST);

	fas216_checkmagic(info);

	ret = scsi_add_host(host, dev);
	if (ret)
		fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
	else
		scsi_scan_host(host);

	return ret;
}

void fas216_remove(struct Scsi_Host *host)
{
	FAS216_Info *info = (FAS216_Info *)host->hostdata;

	fas216_checkmagic(info);
	scsi_remove_host(host);

	fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
	scsi_host_put(host);
}

/**
 * fas216_release - release all resources for FAS/NCR/AMD SCSI ic.
 * @host: a driver-specific filled-out structure
 *
 * release all resources and put everything to bed for FAS/NCR/AMD SCSI ic.
 */
void fas216_release(struct Scsi_Host *host)
{
	FAS216_Info *info = (FAS216_Info *)host->hostdata;

	queue_free(&info->queues.disconnected);
	queue_free(&info->queues.issue);
}

int fas216_print_host(FAS216_Info *info, char *buffer)
{
	return sprintf(buffer,
			"\n"
			"Chip    : %s\n"
			" Address: 0x%p\n"
			" IRQ    : %d\n"
			" DMA    : %d\n",
			info->scsi.type, info->scsi.io_base,
			info->scsi.irq, info->scsi.dma);
}

int fas216_print_stats(FAS216_Info *info, char *buffer)
{
	char *p = buffer;

	p += sprintf(p, "\n"
			"Command Statistics:\n"
			" Queued     : %u\n"
			" Issued     : %u\n"
			" Completed  : %u\n"
			" Reads      : %u\n"
			" Writes     : %u\n"
			" Others     : %u\n"
			" Disconnects: %u\n"
			" Aborts     : %u\n"
			" Bus resets : %u\n"
			" Host resets: %u\n",
			info->stats.queues,	 info->stats.removes,
			info->stats.fins,	 info->stats.reads,
			info->stats.writes,	 info->stats.miscs,
			info->stats.disconnects, info->stats.aborts,
			info->stats.bus_resets,	 info->stats.host_resets);

	return p - buffer;
}

int fas216_print_devices(FAS216_Info *info, char *buffer)
{
	struct fas216_device *dev;
	Scsi_Device *scd;
	char *p = buffer;

	p += sprintf(p, "Device/Lun TaggedQ       Parity   Sync\n");

	shost_for_each_device(scd, info->host) {
		dev = &info->device[scd->id];
		p += sprintf(p, "     %d/%d   ", scd->id, scd->lun);
		if (scd->tagged_supported)
			p += sprintf(p, "%3sabled(%3d) ",
				     scd->simple_tags ? "en" : "dis",
				     scd->current_tag);
		else
			p += sprintf(p, "unsupported   ");

		p += sprintf(p, "%3sabled ", dev->parity_enabled ? "en" : "dis");

		if (dev->sof)
			p += sprintf(p, "offset %d, %d ns\n",
				     dev->sof, dev->period * 4);
		else
			p += sprintf(p, "async\n");
	}

	return p - buffer;
}

EXPORT_SYMBOL(fas216_init);
EXPORT_SYMBOL(fas216_add);
EXPORT_SYMBOL(fas216_queue_command);
EXPORT_SYMBOL(fas216_noqueue_command);
EXPORT_SYMBOL(fas216_intr);
EXPORT_SYMBOL(fas216_remove);
EXPORT_SYMBOL(fas216_release);
EXPORT_SYMBOL(fas216_eh_abort);
EXPORT_SYMBOL(fas216_eh_device_reset);
EXPORT_SYMBOL(fas216_eh_bus_reset);
EXPORT_SYMBOL(fas216_eh_host_reset);
EXPORT_SYMBOL(fas216_print_host);
EXPORT_SYMBOL(fas216_print_stats);
EXPORT_SYMBOL(fas216_print_devices);

MODULE_AUTHOR("Russell King");
MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver core");
MODULE_LICENSE("GPL");
