/*
 *  linux/drivers/acorn/scsi/acornscsi.c
 *
 *  Acorn SCSI 3 driver
 *  By R.M.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.
 *
 * Abandoned using the Select and Transfer command since there were
 * some nasty races between our software and the target devices that
 * were not easy to solve, and the device errata had a lot of entries
 * for this command, some of them quite nasty...
 *
 * Changelog:
 *  26-Sep-1997	RMK	Re-jigged to use the queue module.
 *			Re-coded state machine to be based on driver
 *			state not scsi state.  Should be easier to debug.
 *			Added acornscsi_release to clean up properly.
 *			Updated proc/scsi reporting.
 *  05-Oct-1997	RMK	Implemented writing to SCSI devices.
 *  06-Oct-1997	RMK	Corrected small (non-serious) bug with the connect/
 *			reconnect race condition causing a warning message.
 *  12-Oct-1997	RMK	Added catch for re-entering interrupt routine.
 *  15-Oct-1997	RMK	Improved handling of commands.
 *  27-Jun-1998	RMK	Changed asm/delay.h to linux/delay.h.
 *  13-Dec-1998	RMK	Better abort code and command handling.  Extra state
 *			transitions added to allow dodgy devices to work.
 */
#define DEBUG_NO_WRITE	1
#define DEBUG_QUEUES	2
#define DEBUG_DMA	4
#define DEBUG_ABORT	8
#define DEBUG_DISCON	16
#define DEBUG_CONNECT	32
#define DEBUG_PHASES	64
#define DEBUG_WRITE	128
#define DEBUG_LINK	256
#define DEBUG_MESSAGES	512
#define DEBUG_RESET	1024
#define DEBUG_ALL	(DEBUG_RESET|DEBUG_MESSAGES|DEBUG_LINK|DEBUG_WRITE|\
			 DEBUG_PHASES|DEBUG_CONNECT|DEBUG_DISCON|DEBUG_ABORT|\
			 DEBUG_DMA|DEBUG_QUEUES)

/* DRIVER CONFIGURATION
 *
 * SCSI-II Tagged queue support.
 *
 * I don't have any SCSI devices that support it, so it is totally untested
 * (except to make sure that it doesn't interfere with any non-tagging
 * devices).  It is not fully implemented either - what happens when a
 * tagging device reconnects???
 *
 * You can tell if you have a device that supports tagged queueing my
 * cating (eg) /proc/scsi/acornscsi/0 and see if the SCSI revision is reported
 * as '2 TAG'.
 *
 * Also note that CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE is normally set in the config
 * scripts, but disabled here.  Once debugged, remove the #undef, otherwise to debug,
 * comment out the undef.
 */
#undef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
/*
 * SCSI-II Linked command support.
 *
 * The higher level code doesn't support linked commands yet, and so the option
 * is undef'd here.
 */
#undef CONFIG_SCSI_ACORNSCSI_LINK
/*
 * SCSI-II Synchronous transfer support.
 *
 * Tried and tested...
 *
 * SDTR_SIZE	  - maximum number of un-acknowledged bytes (0 = off, 12 = max)
 * SDTR_PERIOD	  - period of REQ signal (min=125, max=1020)
 * DEFAULT_PERIOD - default REQ period.
 */
#define SDTR_SIZE	12
#define SDTR_PERIOD	125
#define DEFAULT_PERIOD	500

/*
 * Debugging information
 *
 * DEBUG	  - bit mask from list above
 * DEBUG_TARGET   - is defined to the target number if you want to debug
 *		    a specific target. [only recon/write/dma].
 */
#define DEBUG (DEBUG_RESET|DEBUG_WRITE|DEBUG_NO_WRITE)
/* only allow writing to SCSI device 0 */
#define NO_WRITE 0xFE
/*#define DEBUG_TARGET 2*/
/*
 * Select timeout time (in 10ms units)
 *
 * This is the timeout used between the start of selection and the WD33C93
 * chip deciding that the device isn't responding.
 */
#define TIMEOUT_TIME 10
/*
 * Define this if you want to have verbose explaination of SCSI
 * status/messages.
 */
#undef CONFIG_ACORNSCSI_CONSTANTS
/*
 * Define this if you want to use the on board DMAC [don't remove this option]
 * If not set, then use PIO mode (not currently supported).
 */
#define USE_DMAC

/*
 * ====================================================================================
 */

#ifdef DEBUG_TARGET
#define DBG(cmd,xxx...) \
  if (cmd->device->id == DEBUG_TARGET) { \
    xxx; \
  }
#else
#define DBG(cmd,xxx...) xxx
#endif

#ifndef STRINGIFY
#define STRINGIFY(x) #x
#endif
#define STRx(x) STRINGIFY(x)
#define NO_WRITE_STR STRx(NO_WRITE)

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/proc_fs.h>
#include <linux/ioport.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/bitops.h>

#include <asm/system.h>
#include <asm/io.h>
#include <asm/ecard.h>

#include "../scsi.h"
#include <scsi/scsi_dbg.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_spi.h>
#include "acornscsi.h"
#include "msgqueue.h"
#include "scsi.h"

#include <scsi/scsicam.h>

#define VER_MAJOR 2
#define VER_MINOR 0
#define VER_PATCH 6

#ifndef ABORT_TAG
#define ABORT_TAG 0xd
#else
#error "Yippee!  ABORT TAG is now defined!  Remove this error!"
#endif

#ifdef CONFIG_SCSI_ACORNSCSI_LINK
#error SCSI2 LINKed commands not supported (yet)!
#endif

#ifdef USE_DMAC
/*
 * DMAC setup parameters
 */ 
#define INIT_DEVCON0	(DEVCON0_RQL|DEVCON0_EXW|DEVCON0_CMP)
#define INIT_DEVCON1	(DEVCON1_BHLD)
#define DMAC_READ	(MODECON_READ)
#define DMAC_WRITE	(MODECON_WRITE)
#define INIT_SBICDMA	(CTRL_DMABURST)

#define scsi_xferred	have_data_in

/*
 * Size of on-board DMA buffer
 */
#define DMAC_BUFFER_SIZE	65536
#endif

#define STATUS_BUFFER_TO_PRINT	24

unsigned int sdtr_period = SDTR_PERIOD;
unsigned int sdtr_size   = SDTR_SIZE;

static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
			   unsigned int result);
static int acornscsi_reconnect_finish(AS_Host *host);
static void acornscsi_dma_cleanup(AS_Host *host);
static void acornscsi_abortcmd(AS_Host *host, unsigned char tag);

/* ====================================================================================
 * Miscellaneous
 */

static inline void
sbic_arm_write(unsigned int io_port, int reg, int value)
{
    __raw_writeb(reg, io_port);
    __raw_writeb(value, io_port + 4);
}

#define sbic_arm_writenext(io,val) \
	__raw_writeb((val), (io) + 4)

static inline
int sbic_arm_read(unsigned int io_port, int reg)
{
    if(reg == SBIC_ASR)
	   return __raw_readl(io_port) & 255;
    __raw_writeb(reg, io_port);
    return __raw_readl(io_port + 4) & 255;
}

#define sbic_arm_readnext(io) \
	__raw_readb((io) + 4)

#ifdef USE_DMAC
#define dmac_read(io_port,reg) \
	inb((io_port) + (reg))

#define dmac_write(io_port,reg,value) \
	({ outb((value), (io_port) + (reg)); })

#define dmac_clearintr(io_port) \
	({ outb(0, (io_port)); })

static inline
unsigned int dmac_address(unsigned int io_port)
{
    return dmac_read(io_port, DMAC_TXADRHI) << 16 |
	   dmac_read(io_port, DMAC_TXADRMD) << 8 |
	   dmac_read(io_port, DMAC_TXADRLO);
}

static
void acornscsi_dumpdma(AS_Host *host, char *where)
{
	unsigned int mode, addr, len;

	mode = dmac_read(host->dma.io_port, DMAC_MODECON);
	addr = dmac_address(host->dma.io_port);
	len  = dmac_read(host->dma.io_port, DMAC_TXCNTHI) << 8 |
	       dmac_read(host->dma.io_port, DMAC_TXCNTLO);

	printk("scsi%d: %s: DMAC %02x @%06x+%04x msk %02x, ",
		host->host->host_no, where,
		mode, addr, (len + 1) & 0xffff,
		dmac_read(host->dma.io_port, DMAC_MASKREG));

	printk("DMA @%06x, ", host->dma.start_addr);
	printk("BH @%p +%04x, ", host->scsi.SCp.ptr,
		host->scsi.SCp.this_residual);
	printk("DT @+%04x ST @+%04x", host->dma.transferred,
		host->scsi.SCp.scsi_xferred);
	printk("\n");
}
#endif

static
unsigned long acornscsi_sbic_xfcount(AS_Host *host)
{
    unsigned long length;

    length = sbic_arm_read(host->scsi.io_port, SBIC_TRANSCNTH) << 16;
    length |= sbic_arm_readnext(host->scsi.io_port) << 8;
    length |= sbic_arm_readnext(host->scsi.io_port);

    return length;
}

static int
acornscsi_sbic_wait(AS_Host *host, int stat_mask, int stat, int timeout, char *msg)
{
	int asr;

	do {
		asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);

		if ((asr & stat_mask) == stat)
			return 0;

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

	printk("scsi%d: timeout while %s\n", host->host->host_no, msg);

	return -1;
}

static
int acornscsi_sbic_issuecmd(AS_Host *host, int command)
{
    if (acornscsi_sbic_wait(host, ASR_CIP, 0, 1000, "issuing command"))
	return -1;

    sbic_arm_write(host->scsi.io_port, SBIC_CMND, command);

    return 0;
}

static void
acornscsi_csdelay(unsigned int cs)
{
    unsigned long target_jiffies, flags;

    target_jiffies = jiffies + 1 + cs * HZ / 100;

    local_save_flags(flags);
    local_irq_enable();

    while (time_before(jiffies, target_jiffies)) barrier();

    local_irq_restore(flags);
}

static
void acornscsi_resetcard(AS_Host *host)
{
    unsigned int i, timeout;

    /* assert reset line */
    host->card.page_reg = 0x80;
    outb(host->card.page_reg, host->card.io_page);

    /* wait 3 cs.  SCSI standard says 25ms. */
    acornscsi_csdelay(3);

    host->card.page_reg = 0;
    outb(host->card.page_reg, host->card.io_page);

    /*
     * Should get a reset from the card
     */
    timeout = 1000;
    do {
	if (inb(host->card.io_intr) & 8)
	    break;
	udelay(1);
    } while (--timeout);

    if (timeout == 0)
	printk("scsi%d: timeout while resetting card\n",
		host->host->host_no);

    sbic_arm_read(host->scsi.io_port, SBIC_ASR);
    sbic_arm_read(host->scsi.io_port, SBIC_SSR);

    /* setup sbic - WD33C93A */
    sbic_arm_write(host->scsi.io_port, SBIC_OWNID, OWNID_EAF | host->host->this_id);
    sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_RESET);

    /*
     * Command should cause a reset interrupt
     */
    timeout = 1000;
    do {
	if (inb(host->card.io_intr) & 8)
	    break;
	udelay(1);
    } while (--timeout);

    if (timeout == 0)
	printk("scsi%d: timeout while resetting card\n",
		host->host->host_no);

    sbic_arm_read(host->scsi.io_port, SBIC_ASR);
    if (sbic_arm_read(host->scsi.io_port, SBIC_SSR) != 0x01)
	printk(KERN_CRIT "scsi%d: WD33C93A didn't give enhanced reset interrupt\n",
		host->host->host_no);

    sbic_arm_write(host->scsi.io_port, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
    sbic_arm_write(host->scsi.io_port, SBIC_TIMEOUT, TIMEOUT_TIME);
    sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
    sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);

    host->card.page_reg = 0x40;
    outb(host->card.page_reg, host->card.io_page);

    /* setup dmac - uPC71071 */
    dmac_write(host->dma.io_port, DMAC_INIT, 0);
#ifdef USE_DMAC
    dmac_write(host->dma.io_port, DMAC_INIT, INIT_8BIT);
    dmac_write(host->dma.io_port, DMAC_CHANNEL, CHANNEL_0);
    dmac_write(host->dma.io_port, DMAC_DEVCON0, INIT_DEVCON0);
    dmac_write(host->dma.io_port, DMAC_DEVCON1, INIT_DEVCON1);
#endif

    host->SCpnt = NULL;
    host->scsi.phase = PHASE_IDLE;
    host->scsi.disconnectable = 0;

    memset(host->busyluns, 0, sizeof(host->busyluns));

    for (i = 0; i < 8; i++) {
	host->device[i].sync_state = SYNC_NEGOCIATE;
	host->device[i].disconnect_ok = 1;
    }

    /* wait 25 cs.  SCSI standard says 250ms. */
    acornscsi_csdelay(25);
}

/*=============================================================================================
 * Utility routines (eg. debug)
 */
#ifdef CONFIG_ACORNSCSI_CONSTANTS
static char *acornscsi_interrupttype[] = {
  "rst",  "suc",  "p/a",  "3",
  "term", "5",	  "6",	  "7",
  "serv", "9",	  "a",	  "b",
  "c",	  "d",	  "e",	  "f"
};

static signed char acornscsi_map[] = {
  0,  1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
 -1,  2, -1, -1,  -1, -1,  3, -1,   4,	5,  6,	7,   8,  9, 10, 11,
 12, 13, 14, -1,  -1, -1, -1, -1,   4,	5,  6,	7,   8,  9, 10, 11,
 -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
 15, 16, 17, 18,  19, -1, -1, 20,   4,	5,  6,	7,   8,  9, 10, 11,
 -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
 -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
 -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
 21, 22, -1, -1,  -1, 23, -1, -1,   4,	5,  6,	7,   8,  9, 10, 11,
 -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
 -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
 -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
 -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
 -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
 -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
 -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1
};      

static char *acornscsi_interruptcode[] = {
    /* 0 */
    "reset - normal mode",	/* 00 */
    "reset - advanced mode",	/* 01 */

    /* 2 */
    "sel",			/* 11 */
    "sel+xfer", 		/* 16 */
    "data-out", 		/* 18 */
    "data-in",			/* 19 */
    "cmd",			/* 1A */
    "stat",			/* 1B */
    "??-out",			/* 1C */
    "??-in",			/* 1D */
    "msg-out",			/* 1E */
    "msg-in",			/* 1F */

    /* 12 */
    "/ACK asserted",		/* 20 */
    "save-data-ptr",		/* 21 */
    "{re}sel",			/* 22 */

    /* 15 */
    "inv cmd",			/* 40 */
    "unexpected disconnect",	/* 41 */
    "sel timeout",		/* 42 */
    "P err",			/* 43 */
    "P err+ATN",		/* 44 */
    "bad status byte",		/* 47 */

    /* 21 */
    "resel, no id",		/* 80 */
    "resel",			/* 81 */
    "discon",			/* 85 */
};

static
void print_scsi_status(unsigned int ssr)
{
    if (acornscsi_map[ssr] != -1)
	printk("%s:%s",
		acornscsi_interrupttype[(ssr >> 4)],
		acornscsi_interruptcode[acornscsi_map[ssr]]);
    else
	printk("%X:%X", ssr >> 4, ssr & 0x0f);    
}    
#endif

static
void print_sbic_status(int asr, int ssr, int cmdphase)
{
#ifdef CONFIG_ACORNSCSI_CONSTANTS
    printk("sbic: %c%c%c%c%c%c ",
	    asr & ASR_INT ? 'I' : 'i',
	    asr & ASR_LCI ? 'L' : 'l',
	    asr & ASR_BSY ? 'B' : 'b',
	    asr & ASR_CIP ? 'C' : 'c',
	    asr & ASR_PE  ? 'P' : 'p',
	    asr & ASR_DBR ? 'D' : 'd');
    printk("scsi: ");
    print_scsi_status(ssr);
    printk(" ph %02X\n", cmdphase);
#else
    printk("sbic: %02X scsi: %X:%X ph: %02X\n",
	    asr, (ssr & 0xf0)>>4, ssr & 0x0f, cmdphase);
#endif
}

static void
acornscsi_dumplogline(AS_Host *host, int target, int line)
{
	unsigned long prev;
	signed int ptr;

	ptr = host->status_ptr[target] - STATUS_BUFFER_TO_PRINT;
	if (ptr < 0)
		ptr += STATUS_BUFFER_SIZE;

	printk("%c: %3s:", target == 8 ? 'H' : '0' + target,
		line == 0 ? "ph" : line == 1 ? "ssr" : "int");

	prev = host->status[target][ptr].when;

	for (; ptr != host->status_ptr[target]; ptr = (ptr + 1) & (STATUS_BUFFER_SIZE - 1)) {
		unsigned long time_diff;

		if (!host->status[target][ptr].when)
			continue;

		switch (line) {
		case 0:
			printk("%c%02X", host->status[target][ptr].irq ? '-' : ' ',
					 host->status[target][ptr].ph);
			break;

		case 1:
			printk(" %02X", host->status[target][ptr].ssr);
			break;

		case 2:
			time_diff = host->status[target][ptr].when - prev;
			prev = host->status[target][ptr].when;
			if (time_diff == 0)
				printk("==^");
			else if (time_diff >= 100)
				printk("   ");
			else
				printk(" %02ld", time_diff);
			break;
		}
	}

	printk("\n");
}

static
void acornscsi_dumplog(AS_Host *host, int target)
{
    do {
	acornscsi_dumplogline(host, target, 0);
	acornscsi_dumplogline(host, target, 1);
	acornscsi_dumplogline(host, target, 2);

	if (target == 8)
	    break;

	target = 8;
    } while (1);
}

static
char acornscsi_target(AS_Host *host)
{
	if (host->SCpnt)
		return '0' + host->SCpnt->device->id;
	return 'H';
}

/*
 * Prototype: cmdtype_t acornscsi_cmdtype(int command)
 * Purpose  : differentiate READ from WRITE from other commands
 * Params   : command - command to interpret
 * Returns  : CMD_READ	- command reads data,
 *	      CMD_WRITE - command writes data,
 *	      CMD_MISC	- everything else
 */
static inline
cmdtype_t acornscsi_cmdtype(int command)
{
    switch (command) {
    case WRITE_6:  case WRITE_10:  case WRITE_12:
	return CMD_WRITE;
    case READ_6:   case READ_10:   case READ_12:
	return CMD_READ;
    default:
	return CMD_MISC;
    }
}

/*
 * Prototype: int acornscsi_datadirection(int command)
 * Purpose  : differentiate between commands that have a DATA IN phase
 *	      and a DATA OUT phase
 * Params   : command - command to interpret
 * Returns  : DATADIR_OUT - data out phase expected
 *	      DATADIR_IN  - data in phase expected
 */
static
datadir_t acornscsi_datadirection(int command)
{
    switch (command) {
    case CHANGE_DEFINITION:	case COMPARE:		case COPY:
    case COPY_VERIFY:		case LOG_SELECT:	case MODE_SELECT:
    case MODE_SELECT_10:	case SEND_DIAGNOSTIC:	case WRITE_BUFFER:
    case FORMAT_UNIT:		case REASSIGN_BLOCKS:	case RESERVE:
    case SEARCH_EQUAL:		case SEARCH_HIGH:	case SEARCH_LOW:
    case WRITE_6:		case WRITE_10:		case WRITE_VERIFY:
    case UPDATE_BLOCK:		case WRITE_LONG:	case WRITE_SAME:
    case SEARCH_HIGH_12:	case SEARCH_EQUAL_12:	case SEARCH_LOW_12:
    case WRITE_12:		case WRITE_VERIFY_12:	case SET_WINDOW:
    case MEDIUM_SCAN:		case SEND_VOLUME_TAG:	case 0xea:
	return DATADIR_OUT;
    default:
	return DATADIR_IN;
    }
}

/*
 * Purpose  : provide values for synchronous transfers with 33C93.
 * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
 *	Modified by Russell King for 8MHz WD33C93A
 */
static struct sync_xfer_tbl {
    unsigned int period_ns;
    unsigned char reg_value;
} sync_xfer_table[] = {
    {	1, 0x20 },    { 249, 0x20 },	{ 374, 0x30 },
    { 499, 0x40 },    { 624, 0x50 },	{ 749, 0x60 },
    { 874, 0x70 },    { 999, 0x00 },	{   0,	  0 }
};

/*
 * Prototype: int acornscsi_getperiod(unsigned char syncxfer)
 * Purpose  : period for the synchronous transfer setting
 * Params   : syncxfer SYNCXFER register value
 * Returns  : period in ns.
 */
static
int acornscsi_getperiod(unsigned char syncxfer)
{
    int i;

    syncxfer &= 0xf0;
    if (syncxfer == 0x10)
	syncxfer = 0;

    for (i = 1; sync_xfer_table[i].period_ns; i++)
	if (syncxfer == sync_xfer_table[i].reg_value)
	    return sync_xfer_table[i].period_ns;
    return 0;
}

/*
 * Prototype: int round_period(unsigned int period)
 * Purpose  : return index into above table for a required REQ period
 * Params   : period - time (ns) for REQ
 * Returns  : table index
 * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
 */
static inline
int round_period(unsigned int period)
{
    int i;

    for (i = 1; sync_xfer_table[i].period_ns; i++) {
	if ((period <= sync_xfer_table[i].period_ns) &&
	    (period > sync_xfer_table[i - 1].period_ns))
	    return i;
    }
    return 7;
}

/*
 * Prototype: unsigned char calc_sync_xfer(unsigned int period, unsigned int offset)
 * Purpose  : calculate value for 33c93s SYNC register
 * Params   : period - time (ns) for REQ
 *	      offset - offset in bytes between REQ/ACK
 * Returns  : value for SYNC register
 * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
 */
static
unsigned char calc_sync_xfer(unsigned int period, unsigned int offset)
{
    return sync_xfer_table[round_period(period)].reg_value |
		((offset < SDTR_SIZE) ? offset : SDTR_SIZE);
}

/* ====================================================================================
 * Command functions
 */
/*
 * Function: acornscsi_kick(AS_Host *host)
 * Purpose : kick next command to interface
 * Params  : host - host to send command to
 * Returns : INTR_IDLE if idle, otherwise INTR_PROCESSING
 * Notes   : interrupts are always disabled!
 */
static
intr_ret_t acornscsi_kick(AS_Host *host)
{
    int from_queue = 0;
    struct scsi_cmnd *SCpnt;

    /* first check to see if a command is waiting to be executed */
    SCpnt = host->origSCpnt;
    host->origSCpnt = NULL;

    /* retrieve next command */
    if (!SCpnt) {
	SCpnt = queue_remove_exclude(&host->queues.issue, host->busyluns);
	if (!SCpnt)
	    return INTR_IDLE;

	from_queue = 1;
    }

    if (host->scsi.disconnectable && host->SCpnt) {
	queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
	host->scsi.disconnectable = 0;
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
	DBG(host->SCpnt, printk("scsi%d.%c: moved command to disconnected queue\n",
		host->host->host_no, acornscsi_target(host)));
#endif
	host->SCpnt = NULL;
    }

    /*
     * If we have an interrupt pending, then we may have been reselected.
     * In this case, we don't want to write to the registers
     */
    if (!(sbic_arm_read(host->scsi.io_port, SBIC_ASR) & (ASR_INT|ASR_BSY|ASR_CIP))) {
	sbic_arm_write(host->scsi.io_port, SBIC_DESTID, SCpnt->device->id);
	sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_SELWITHATN);
    }

    /*
     * claim host busy - all of these must happen atomically wrt
     * our interrupt routine.  Failure means command loss.
     */
    host->scsi.phase = PHASE_CONNECTING;
    host->SCpnt = SCpnt;
    host->scsi.SCp = SCpnt->SCp;
    host->dma.xfer_setup = 0;
    host->dma.xfer_required = 0;
    host->dma.xfer_done = 0;

#if (DEBUG & (DEBUG_ABORT|DEBUG_CONNECT))
    DBG(SCpnt,printk("scsi%d.%c: starting cmd %02X\n",
	    host->host->host_no, '0' + SCpnt->device->id,
	    SCpnt->cmnd[0]));
#endif

    if (from_queue) {
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
	/*
	 * tagged queueing - allocate a new tag to this command
	 */
	if (SCpnt->device->simple_tags) {
	    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, host->busyluns);

	host->stats.removes += 1;

	switch (acornscsi_cmdtype(SCpnt->cmnd[0])) {
	case CMD_WRITE:
	    host->stats.writes += 1;
	    break;
	case CMD_READ:
	    host->stats.reads += 1;
	    break;
	case CMD_MISC:
	    host->stats.miscs += 1;
	    break;
	}
    }

    return INTR_PROCESSING;
}    

/*
 * Function: void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, unsigned int result)
 * Purpose : complete processing for command
 * Params  : host   - interface that completed
 *	     result - driver byte of result
 */
static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
			   unsigned int result)
{
	struct scsi_cmnd *SCpnt = *SCpntp;

    /* clean up */
    sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);

    host->stats.fins += 1;

    if (SCpnt) {
	*SCpntp = NULL;

	acornscsi_dma_cleanup(host);

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

	/*
	 * In theory, this should not happen.  In practice, it seems to.
	 * Only trigger an error if the device attempts to report all happy
	 * but with untransferred buffers...  If we don't do something, then
	 * data loss will occur.  Should we check SCpnt->underflow here?
	 * It doesn't appear to be set to something meaningful by the higher
	 * levels all the time.
	 */
	if (result == DID_OK) {
		int xfer_warn = 0;

		if (SCpnt->underflow == 0) {
			if (host->scsi.SCp.ptr &&
			    acornscsi_cmdtype(SCpnt->cmnd[0]) != CMD_MISC)
				xfer_warn = 1;
		} else {
			if (host->scsi.SCp.scsi_xferred < SCpnt->underflow ||
			    host->scsi.SCp.scsi_xferred != host->dma.transferred)
				xfer_warn = 1;
		}

		/* ANSI standard says: (SCSI-2 Rev 10c Sect 5.6.6)
		 *  Targets which break data transfers into multiple
		 *  connections shall end each successful connection
		 *  (except possibly the last) with a SAVE DATA
		 *  POINTER - DISCONNECT message sequence.
		 *
		 * This makes it difficult to ensure that a transfer has
		 * completed.  If we reach the end of a transfer during
		 * the command, then we can only have finished the transfer.
		 * therefore, if we seem to have some data remaining, this
		 * is not a problem.
		 */
		if (host->dma.xfer_done)
			xfer_warn = 0;

		if (xfer_warn) {
		    switch (status_byte(SCpnt->result)) {
		    case CHECK_CONDITION:
		    case COMMAND_TERMINATED:
		    case BUSY:
		    case QUEUE_FULL:
		    case RESERVATION_CONFLICT:
			break;

		    default:
			printk(KERN_ERR "scsi%d.H: incomplete data transfer detected: result=%08X command=",
				host->host->host_no, SCpnt->result);
			__scsi_print_command(SCpnt->cmnd);
			acornscsi_dumpdma(host, "done");
		 	acornscsi_dumplog(host, SCpnt->device->id);
			SCpnt->result &= 0xffff;
			SCpnt->result |= DID_ERROR << 16;
		    }
		}
	}

	if (!SCpnt->scsi_done)
	    panic("scsi%d.H: null scsi_done function in acornscsi_done", host->host->host_no);

	clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, host->busyluns);

	SCpnt->scsi_done(SCpnt);
    } else
	printk("scsi%d: null command in acornscsi_done", host->host->host_no);

    host->scsi.phase = PHASE_IDLE;
}

/* ====================================================================================
 * DMA routines
 */
/*
 * Purpose  : update SCSI Data Pointer
 * Notes    : this will only be one SG entry or less
 */
static
void acornscsi_data_updateptr(AS_Host *host, struct scsi_pointer *SCp, unsigned int length)
{
    SCp->ptr += length;
    SCp->this_residual -= length;

    if (SCp->this_residual == 0 && next_SCp(SCp) == 0)
	host->dma.xfer_done = 1;
}

/*
 * Prototype: void acornscsi_data_read(AS_Host *host, char *ptr,
 *				unsigned int start_addr, unsigned int length)
 * Purpose  : read data from DMA RAM
 * Params   : host - host to transfer from
 *	      ptr  - DRAM address
 *	      start_addr - host mem address
 *	      length - number of bytes to transfer
 * Notes    : this will only be one SG entry or less
 */
static
void acornscsi_data_read(AS_Host *host, char *ptr,
				 unsigned int start_addr, unsigned int length)
{
    extern void __acornscsi_in(int port, char *buf, int len);
    unsigned int page, offset, len = length;

    page = (start_addr >> 12);
    offset = start_addr & ((1 << 12) - 1);

    outb((page & 0x3f) | host->card.page_reg, host->card.io_page);

    while (len > 0) {
	unsigned int this_len;

	if (len + offset > (1 << 12))
	    this_len = (1 << 12) - offset;
	else
	    this_len = len;

	__acornscsi_in(host->card.io_ram + (offset << 1), ptr, this_len);

	offset += this_len;
	ptr += this_len;
	len -= this_len;

	if (offset == (1 << 12)) {
	    offset = 0;
	    page ++;
	    outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
	}
    }
    outb(host->card.page_reg, host->card.io_page);
}

/*
 * Prototype: void acornscsi_data_write(AS_Host *host, char *ptr,
 *				unsigned int start_addr, unsigned int length)
 * Purpose  : write data to DMA RAM
 * Params   : host - host to transfer from
 *	      ptr  - DRAM address
 *	      start_addr - host mem address
 *	      length - number of bytes to transfer
 * Notes    : this will only be one SG entry or less
 */
static
void acornscsi_data_write(AS_Host *host, char *ptr,
				 unsigned int start_addr, unsigned int length)
{
    extern void __acornscsi_out(int port, char *buf, int len);
    unsigned int page, offset, len = length;

    page = (start_addr >> 12);
    offset = start_addr & ((1 << 12) - 1);

    outb((page & 0x3f) | host->card.page_reg, host->card.io_page);

    while (len > 0) {
	unsigned int this_len;

	if (len + offset > (1 << 12))
	    this_len = (1 << 12) - offset;
	else
	    this_len = len;

	__acornscsi_out(host->card.io_ram + (offset << 1), ptr, this_len);

	offset += this_len;
	ptr += this_len;
	len -= this_len;

	if (offset == (1 << 12)) {
	    offset = 0;
	    page ++;
	    outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
	}
    }
    outb(host->card.page_reg, host->card.io_page);
}

/* =========================================================================================
 * On-board DMA routines
 */
#ifdef USE_DMAC
/*
 * Prototype: void acornscsi_dmastop(AS_Host *host)
 * Purpose  : stop all DMA
 * Params   : host - host on which to stop DMA
 * Notes    : This is called when leaving DATA IN/OUT phase,
 *	      or when interface is RESET
 */
static inline
void acornscsi_dma_stop(AS_Host *host)
{
    dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON);
    dmac_clearintr(host->dma.io_intr_clear);

#if (DEBUG & DEBUG_DMA)
    DBG(host->SCpnt, acornscsi_dumpdma(host, "stop"));
#endif
}

/*
 * Function: void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
 * Purpose : setup DMA controller for data transfer
 * Params  : host - host to setup
 *	     direction - data transfer direction
 * Notes   : This is called when entering DATA I/O phase, not
 *	     while we're in a DATA I/O phase
 */
static
void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
{
    unsigned int address, length, mode;

    host->dma.direction = direction;

    dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON);

    if (direction == DMA_OUT) {
#if (DEBUG & DEBUG_NO_WRITE)
	if (NO_WRITE & (1 << host->SCpnt->device->id)) {
	    printk(KERN_CRIT "scsi%d.%c: I can't handle DMA_OUT!\n",
		    host->host->host_no, acornscsi_target(host));
	    return;
	}
#endif
	mode = DMAC_WRITE;
    } else
	mode = DMAC_READ;

    /*
     * Allocate some buffer space, limited to half the buffer size
     */
    length = min_t(unsigned int, host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2);
    if (length) {
	host->dma.start_addr = address = host->dma.free_addr;
	host->dma.free_addr = (host->dma.free_addr + length) &
				(DMAC_BUFFER_SIZE - 1);

	/*
	 * Transfer data to DMA memory
	 */
	if (direction == DMA_OUT)
	    acornscsi_data_write(host, host->scsi.SCp.ptr, host->dma.start_addr,
				length);

	length -= 1;
	dmac_write(host->dma.io_port, DMAC_TXCNTLO, length);
	dmac_write(host->dma.io_port, DMAC_TXCNTHI, length >> 8);
	dmac_write(host->dma.io_port, DMAC_TXADRLO, address);
	dmac_write(host->dma.io_port, DMAC_TXADRMD, address >> 8);
	dmac_write(host->dma.io_port, DMAC_TXADRHI, 0);
	dmac_write(host->dma.io_port, DMAC_MODECON, mode);
	dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_OFF);

#if (DEBUG & DEBUG_DMA)
	DBG(host->SCpnt, acornscsi_dumpdma(host, "strt"));
#endif
	host->dma.xfer_setup = 1;
    }
}

/*
 * Function: void acornscsi_dma_cleanup(AS_Host *host)
 * Purpose : ensure that all DMA transfers are up-to-date & host->scsi.SCp is correct
 * Params  : host - host to finish
 * Notes   : This is called when a command is:
 *		terminating, RESTORE_POINTERS, SAVE_POINTERS, DISCONECT
 *	   : This must not return until all transfers are completed.
 */
static
void acornscsi_dma_cleanup(AS_Host *host)
{
    dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON);
    dmac_clearintr(host->dma.io_intr_clear);

    /*
     * Check for a pending transfer
     */
    if (host->dma.xfer_required) {
	host->dma.xfer_required = 0;
	if (host->dma.direction == DMA_IN)
	    acornscsi_data_read(host, host->dma.xfer_ptr,
				 host->dma.xfer_start, host->dma.xfer_length);
    }

    /*
     * Has a transfer been setup?
     */
    if (host->dma.xfer_setup) {
	unsigned int transferred;

	host->dma.xfer_setup = 0;

#if (DEBUG & DEBUG_DMA)
	DBG(host->SCpnt, acornscsi_dumpdma(host, "cupi"));
#endif

	/*
	 * Calculate number of bytes transferred from DMA.
	 */
	transferred = dmac_address(host->dma.io_port) - host->dma.start_addr;
	host->dma.transferred += transferred;

	if (host->dma.direction == DMA_IN)
	    acornscsi_data_read(host, host->scsi.SCp.ptr,
				 host->dma.start_addr, transferred);

	/*
	 * Update SCSI pointers
	 */
	acornscsi_data_updateptr(host, &host->scsi.SCp, transferred);
#if (DEBUG & DEBUG_DMA)
	DBG(host->SCpnt, acornscsi_dumpdma(host, "cupo"));
#endif
    }
}

/*
 * Function: void acornscsi_dmacintr(AS_Host *host)
 * Purpose : handle interrupts from DMAC device
 * Params  : host - host to process
 * Notes   : If reading, we schedule the read to main memory &
 *	     allow the transfer to continue.
 *	   : If writing, we fill the onboard DMA memory from main
 *	     memory.
 *	   : Called whenever DMAC finished it's current transfer.
 */
static
void acornscsi_dma_intr(AS_Host *host)
{
    unsigned int address, length, transferred;

#if (DEBUG & DEBUG_DMA)
    DBG(host->SCpnt, acornscsi_dumpdma(host, "inti"));
#endif

    dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_ON);
    dmac_clearintr(host->dma.io_intr_clear);

    /*
     * Calculate amount transferred via DMA
     */
    transferred = dmac_address(host->dma.io_port) - host->dma.start_addr;
    host->dma.transferred += transferred;

    /*
     * Schedule DMA transfer off board
     */
    if (host->dma.direction == DMA_IN) {
	host->dma.xfer_start = host->dma.start_addr;
	host->dma.xfer_length = transferred;
	host->dma.xfer_ptr = host->scsi.SCp.ptr;
	host->dma.xfer_required = 1;
    }

    acornscsi_data_updateptr(host, &host->scsi.SCp, transferred);

    /*
     * Allocate some buffer space, limited to half the on-board RAM size
     */
    length = min_t(unsigned int, host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2);
    if (length) {
	host->dma.start_addr = address = host->dma.free_addr;
	host->dma.free_addr = (host->dma.free_addr + length) &
				(DMAC_BUFFER_SIZE - 1);

	/*
	 * Transfer data to DMA memory
	 */
	if (host->dma.direction == DMA_OUT)
	    acornscsi_data_write(host, host->scsi.SCp.ptr, host->dma.start_addr,
				length);

	length -= 1;
	dmac_write(host->dma.io_port, DMAC_TXCNTLO, length);
	dmac_write(host->dma.io_port, DMAC_TXCNTHI, length >> 8);
	dmac_write(host->dma.io_port, DMAC_TXADRLO, address);
	dmac_write(host->dma.io_port, DMAC_TXADRMD, address >> 8);
	dmac_write(host->dma.io_port, DMAC_TXADRHI, 0);
	dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_OFF);

#if (DEBUG & DEBUG_DMA)
	DBG(host->SCpnt, acornscsi_dumpdma(host, "into"));
#endif
    } else {
	host->dma.xfer_setup = 0;
#if 0
	/*
	 * If the interface still wants more, then this is an error.
	 * We give it another byte, but we also attempt to raise an
	 * attention condition.  We continue giving one byte until
	 * the device recognises the attention.
	 */
	if (dmac_read(host->dma.io_port, DMAC_STATUS) & STATUS_RQ0) {
	    acornscsi_abortcmd(host, host->SCpnt->tag);

	    dmac_write(host->dma.io_port, DMAC_TXCNTLO, 0);
	    dmac_write(host->dma.io_port, DMAC_TXCNTHI, 0);
	    dmac_write(host->dma.io_port, DMAC_TXADRLO, 0);
	    dmac_write(host->dma.io_port, DMAC_TXADRMD, 0);
	    dmac_write(host->dma.io_port, DMAC_TXADRHI, 0);
	    dmac_write(host->dma.io_port, DMAC_MASKREG, MASK_OFF);
	}
#endif
    }
}

/*
 * Function: void acornscsi_dma_xfer(AS_Host *host)
 * Purpose : transfer data between AcornSCSI and memory
 * Params  : host - host to process
 */
static
void acornscsi_dma_xfer(AS_Host *host)
{
    host->dma.xfer_required = 0;

    if (host->dma.direction == DMA_IN)
	acornscsi_data_read(host, host->dma.xfer_ptr,
				host->dma.xfer_start, host->dma.xfer_length);
}

/*
 * Function: void acornscsi_dma_adjust(AS_Host *host)
 * Purpose : adjust DMA pointers & count for bytes transferred to
 *	     SBIC but not SCSI bus.
 * Params  : host - host to adjust DMA count for
 */
static
void acornscsi_dma_adjust(AS_Host *host)
{
    if (host->dma.xfer_setup) {
	signed long transferred;
#if (DEBUG & (DEBUG_DMA|DEBUG_WRITE))
	DBG(host->SCpnt, acornscsi_dumpdma(host, "adji"));
#endif
	/*
	 * Calculate correct DMA address - DMA is ahead of SCSI bus while
	 * writing.
	 *  host->scsi.SCp.scsi_xferred is the number of bytes
	 *  actually transferred to/from the SCSI bus.
	 *  host->dma.transferred is the number of bytes transferred
	 *  over DMA since host->dma.start_addr was last set.
	 *
	 * real_dma_addr = host->dma.start_addr + host->scsi.SCp.scsi_xferred
	 *		   - host->dma.transferred
	 */
	transferred = host->scsi.SCp.scsi_xferred - host->dma.transferred;
	if (transferred < 0)
	    printk("scsi%d.%c: Ack! DMA write correction %ld < 0!\n",
		    host->host->host_no, acornscsi_target(host), transferred);
	else if (transferred == 0)
	    host->dma.xfer_setup = 0;
	else {
	    transferred += host->dma.start_addr;
	    dmac_write(host->dma.io_port, DMAC_TXADRLO, transferred);
	    dmac_write(host->dma.io_port, DMAC_TXADRMD, transferred >> 8);
	    dmac_write(host->dma.io_port, DMAC_TXADRHI, transferred >> 16);
#if (DEBUG & (DEBUG_DMA|DEBUG_WRITE))
	    DBG(host->SCpnt, acornscsi_dumpdma(host, "adjo"));
#endif
	}
    }
}
#endif

/* =========================================================================================
 * Data I/O
 */
static int
acornscsi_write_pio(AS_Host *host, char *bytes, int *ptr, int len, unsigned int max_timeout)
{
	unsigned int asr, timeout = max_timeout;
	int my_ptr = *ptr;

	while (my_ptr < len) {
		asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);

		if (asr & ASR_DBR) {
			timeout = max_timeout;

			sbic_arm_write(host->scsi.io_port, SBIC_DATA, bytes[my_ptr++]);
		} else if (asr & ASR_INT)
			break;
		else if (--timeout == 0)
			break;
		udelay(1);
	}

	*ptr = my_ptr;

	return (timeout == 0) ? -1 : 0;
}

/*
 * Function: void acornscsi_sendcommand(AS_Host *host)
 * Purpose : send a command to a target
 * Params  : host - host which is connected to target
 */
static void
acornscsi_sendcommand(AS_Host *host)
{
	struct scsi_cmnd *SCpnt = host->SCpnt;

    sbic_arm_write(host->scsi.io_port, SBIC_TRANSCNTH, 0);
    sbic_arm_writenext(host->scsi.io_port, 0);
    sbic_arm_writenext(host->scsi.io_port, SCpnt->cmd_len - host->scsi.SCp.sent_command);

    acornscsi_sbic_issuecmd(host, CMND_XFERINFO);

    if (acornscsi_write_pio(host, SCpnt->cmnd,
	(int *)&host->scsi.SCp.sent_command, SCpnt->cmd_len, 1000000))
	printk("scsi%d: timeout while sending command\n", host->host->host_no);

    host->scsi.phase = PHASE_COMMAND;
}

static
void acornscsi_sendmessage(AS_Host *host)
{
    unsigned int message_length = msgqueue_msglength(&host->scsi.msgs);
    unsigned int msgnr;
    struct message *msg;

#if (DEBUG & DEBUG_MESSAGES)
    printk("scsi%d.%c: sending message ",
	    host->host->host_no, acornscsi_target(host));
#endif

    switch (message_length) {
    case 0:
	acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);

	acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 1");

	sbic_arm_write(host->scsi.io_port, SBIC_DATA, NOP);

	host->scsi.last_message = NOP;
#if (DEBUG & DEBUG_MESSAGES)
	printk("NOP");
#endif
	break;

    case 1:
	acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);
	msg = msgqueue_getmsg(&host->scsi.msgs, 0);

	acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 2");

	sbic_arm_write(host->scsi.io_port, SBIC_DATA, msg->msg[0]);

	host->scsi.last_message = msg->msg[0];
#if (DEBUG & DEBUG_MESSAGES)
	spi_print_msg(msg->msg);
#endif
	break;

    default:
	/*
	 * ANSI standard says: (SCSI-2 Rev 10c Sect 5.6.14)
	 * 'When a target sends this (MESSAGE_REJECT) message, it
	 *  shall change to MESSAGE IN phase and send this message
	 *  prior to requesting additional message bytes from the
	 *  initiator.  This provides an interlock so that the
	 *  initiator can determine which message byte is rejected.
	 */
	sbic_arm_write(host->scsi.io_port, SBIC_TRANSCNTH, 0);
	sbic_arm_writenext(host->scsi.io_port, 0);
	sbic_arm_writenext(host->scsi.io_port, message_length);
	acornscsi_sbic_issuecmd(host, CMND_XFERINFO);

	msgnr = 0;
	while ((msg = msgqueue_getmsg(&host->scsi.msgs, msgnr++)) != NULL) {
	    unsigned int i;
#if (DEBUG & DEBUG_MESSAGES)
	    spi_print_msg(msg);
#endif
	    i = 0;
	    if (acornscsi_write_pio(host, msg->msg, &i, msg->length, 1000000))
		printk("scsi%d: timeout while sending message\n", host->host->host_no);

	    host->scsi.last_message = msg->msg[0];
	    if (msg->msg[0] == EXTENDED_MESSAGE)
		host->scsi.last_message |= msg->msg[2] << 8;

	    if (i != msg->length)
		break;
	}
	break;
    }
#if (DEBUG & DEBUG_MESSAGES)
    printk("\n");
#endif
}

/*
 * Function: void acornscsi_readstatusbyte(AS_Host *host)
 * Purpose : Read status byte from connected target
 * Params  : host - host connected to target
 */
static
void acornscsi_readstatusbyte(AS_Host *host)
{
    acornscsi_sbic_issuecmd(host, CMND_XFERINFO|CMND_SBT);
    acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "reading status byte");
    host->scsi.SCp.Status = sbic_arm_read(host->scsi.io_port, SBIC_DATA);
}

/*
 * Function: unsigned char acornscsi_readmessagebyte(AS_Host *host)
 * Purpose : Read one message byte from connected target
 * Params  : host - host connected to target
 */
static
unsigned char acornscsi_readmessagebyte(AS_Host *host)
{
    unsigned char message;

    acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);

    acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "for message byte");

    message = sbic_arm_read(host->scsi.io_port, SBIC_DATA);

    /* wait for MSGIN-XFER-PAUSED */
    acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after message byte");

    sbic_arm_read(host->scsi.io_port, SBIC_SSR);

    return message;
}

/*
 * Function: void acornscsi_message(AS_Host *host)
 * Purpose : Read complete message from connected target & action message
 * Params  : host - host connected to target
 */
static
void acornscsi_message(AS_Host *host)
{
    unsigned char message[16];
    unsigned int msgidx = 0, msglen = 1;

    do {
	message[msgidx] = acornscsi_readmessagebyte(host);

	switch (msgidx) {
	case 0:
	    if (message[0] == EXTENDED_MESSAGE ||
		(message[0] >= 0x20 && message[0] <= 0x2f))
		msglen = 2;
	    break;

	case 1:
	    if (message[0] == EXTENDED_MESSAGE)
		msglen += message[msgidx];
	    break;
	}
	msgidx += 1;
	if (msgidx < msglen) {
	    acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);

	    /* wait for next msg-in */
	    acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after negate ack");
	    sbic_arm_read(host->scsi.io_port, SBIC_SSR);
	}
    } while (msgidx < msglen);

#if (DEBUG & DEBUG_MESSAGES)
    printk("scsi%d.%c: message in: ",
	    host->host->host_no, acornscsi_target(host));
    spi_print_msg(message);
    printk("\n");
#endif

    if (host->scsi.phase == PHASE_RECONNECTED) {
	/*
	 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.17)
	 * 'Whenever a target reconnects to an initiator to continue
	 *  a tagged I/O process, the SIMPLE QUEUE TAG message shall
	 *  be sent immediately following the IDENTIFY message...'
	 */
	if (message[0] == SIMPLE_QUEUE_TAG)
	    host->scsi.reconnected.tag = message[1];
	if (acornscsi_reconnect_finish(host))
	    host->scsi.phase = PHASE_MSGIN;
    }

    switch (message[0]) {
    case ABORT:
    case ABORT_TAG:
    case COMMAND_COMPLETE:
	if (host->scsi.phase != PHASE_STATUSIN) {
	    printk(KERN_ERR "scsi%d.%c: command complete following non-status in phase?\n",
		    host->host->host_no, acornscsi_target(host));
	    acornscsi_dumplog(host, host->SCpnt->device->id);
	}
	host->scsi.phase = PHASE_DONE;
	host->scsi.SCp.Message = message[0];
	break;

    case SAVE_POINTERS:
	/*
	 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.20)
	 * 'The SAVE DATA POINTER message is sent from a target to
	 *  direct the initiator to copy the active data pointer to
	 *  the saved data pointer for the current I/O process.
	 */
	acornscsi_dma_cleanup(host);
	host->SCpnt->SCp = host->scsi.SCp;
	host->SCpnt->SCp.sent_command = 0;
	host->scsi.phase = PHASE_MSGIN;
	break;

    case RESTORE_POINTERS:
	/*
	 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.19)
	 * 'The RESTORE POINTERS message is sent from a target to
	 *  direct the initiator to copy the most recently saved
	 *  command, data, and status pointers for the I/O process
	 *  to the corresponding active pointers.  The command and
	 *  status pointers shall be restored to the beginning of
	 *  the present command and status areas.'
	 */
	acornscsi_dma_cleanup(host);
	host->scsi.SCp = host->SCpnt->SCp;
	host->scsi.phase = PHASE_MSGIN;
	break;

    case DISCONNECT:
	/*
	 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 6.4.2)
	 * 'On those occasions when an error or exception condition occurs
	 *  and the target elects to repeat the information transfer, the
	 *  target may repeat the transfer either issuing a RESTORE POINTERS
	 *  message or by disconnecting without issuing a SAVE POINTERS
	 *  message.  When reconnection is completed, the most recent
	 *  saved pointer values are restored.'
	 */
	acornscsi_dma_cleanup(host);
	host->scsi.phase = PHASE_DISCONNECT;
	break;

    case MESSAGE_REJECT:
#if 0 /* this isn't needed any more */
	/*
	 * If we were negociating sync transfer, we don't yet know if
	 * this REJECT is for the sync transfer or for the tagged queue/wide
	 * transfer.  Re-initiate sync transfer negociation now, and if
	 * we got a REJECT in response to SDTR, then it'll be set to DONE.
	 */
	if (host->device[host->SCpnt->device->id].sync_state == SYNC_SENT_REQUEST)
	    host->device[host->SCpnt->device->id].sync_state = SYNC_NEGOCIATE;
#endif

	/*
	 * If we have any messages waiting to go out, then assert ATN now
	 */
	if (msgqueue_msglength(&host->scsi.msgs))
	    acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);

	switch (host->scsi.last_message) {
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
	case HEAD_OF_QUEUE_TAG:
	case ORDERED_QUEUE_TAG:
	case SIMPLE_QUEUE_TAG:
	    /*
	     * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.17)
	     *  If a target does not implement tagged queuing and a queue tag
	     *  message is received, it shall respond with a MESSAGE REJECT
	     *  message and accept the I/O process as if it were untagged.
	     */
	    printk(KERN_NOTICE "scsi%d.%c: disabling tagged queueing\n",
		    host->host->host_no, acornscsi_target(host));
	    host->SCpnt->device->simple_tags = 0;
	    set_bit(host->SCpnt->device->id * 8 + host->SCpnt->device->lun, host->busyluns);
	    break;
#endif
	case EXTENDED_MESSAGE | (EXTENDED_SDTR << 8):
	    /*
	     * Target can't handle synchronous transfers
	     */
	    printk(KERN_NOTICE "scsi%d.%c: Using asynchronous transfer\n",
		    host->host->host_no, acornscsi_target(host));
	    host->device[host->SCpnt->device->id].sync_xfer = SYNCHTRANSFER_2DBA;
	    host->device[host->SCpnt->device->id].sync_state = SYNC_ASYNCHRONOUS;
	    sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
	    break;

	default:
	    break;
	}
	break;

    case QUEUE_FULL:
	/* TODO: target queue is full */
	break;

    case SIMPLE_QUEUE_TAG:
	/* tag queue reconnect... message[1] = queue tag.  Print something to indicate something happened! */
	printk("scsi%d.%c: reconnect queue tag %02X\n",
		host->host->host_no, acornscsi_target(host),
		message[1]);
	break;

    case EXTENDED_MESSAGE:
	switch (message[2]) {
#ifdef CONFIG_SCSI_ACORNSCSI_SYNC
	case EXTENDED_SDTR:
	    if (host->device[host->SCpnt->device->id].sync_state == SYNC_SENT_REQUEST) {
		/*
		 * We requested synchronous transfers.  This isn't quite right...
		 * We can only say if this succeeded if we proceed on to execute the
		 * command from this message.  If we get a MESSAGE PARITY ERROR,
		 * and the target retries fail, then we fallback to asynchronous mode
		 */
		host->device[host->SCpnt->device->id].sync_state = SYNC_COMPLETED;
		printk(KERN_NOTICE "scsi%d.%c: Using synchronous transfer, offset %d, %d ns\n",
			host->host->host_no, acornscsi_target(host),
			message[4], message[3] * 4);
		host->device[host->SCpnt->device->id].sync_xfer =
			calc_sync_xfer(message[3] * 4, message[4]);
	    } else {
		unsigned char period, length;
		/*
		 * Target requested synchronous transfers.  The agreement is only
		 * to be in operation AFTER the target leaves message out phase.
		 */
		acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
		period = max_t(unsigned int, message[3], sdtr_period / 4);
		length = min_t(unsigned int, message[4], sdtr_size);
		msgqueue_addmsg(&host->scsi.msgs, 5, EXTENDED_MESSAGE, 3,
				 EXTENDED_SDTR, period, length);
		host->device[host->SCpnt->device->id].sync_xfer =
			calc_sync_xfer(period * 4, length);
	    }
	    sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
	    break;
#else
	    /* We do not accept synchronous transfers.  Respond with a
	     * MESSAGE_REJECT.
	     */
#endif

	case EXTENDED_WDTR:
	    /* The WD33C93A is only 8-bit.  We respond with a MESSAGE_REJECT
	     * to a wide data transfer request.
	     */
	default:
	    acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
	    msgqueue_flush(&host->scsi.msgs);
	    msgqueue_addmsg(&host->scsi.msgs, 1, MESSAGE_REJECT);
	    break;
	}
	break;

#ifdef CONFIG_SCSI_ACORNSCSI_LINK
    case LINKED_CMD_COMPLETE:
    case LINKED_FLG_CMD_COMPLETE:
	/*
	 * We don't support linked commands yet
	 */
	if (0) {
#if (DEBUG & DEBUG_LINK)
	    printk("scsi%d.%c: lun %d tag %d linked command complete\n",
		    host->host->host_no, acornscsi_target(host), host->SCpnt->tag);
#endif
	    /*
	     * A linked command should only terminate with one of these messages
	     * if there are more linked commands available.
	     */
	    if (!host->SCpnt->next_link) {
		printk(KERN_WARNING "scsi%d.%c: lun %d tag %d linked command complete, but no next_link\n",
			instance->host_no, acornscsi_target(host), host->SCpnt->tag);
		acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
		msgqueue_addmsg(&host->scsi.msgs, 1, ABORT);
	    } else {
		struct scsi_cmnd *SCpnt = host->SCpnt;

		acornscsi_dma_cleanup(host);

		host->SCpnt = host->SCpnt->next_link;
		host->SCpnt->tag = SCpnt->tag;
		SCpnt->result = DID_OK | host->scsi.SCp.Message << 8 | host->Scsi.SCp.Status;
		SCpnt->done(SCpnt);

		/* initialise host->SCpnt->SCp */
	    }
	    break;
	}
#endif

    default: /* reject message */
	printk(KERN_ERR "scsi%d.%c: unrecognised message %02X, rejecting\n",
		host->host->host_no, acornscsi_target(host),
		message[0]);
	acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
	msgqueue_flush(&host->scsi.msgs);
	msgqueue_addmsg(&host->scsi.msgs, 1, MESSAGE_REJECT);
	host->scsi.phase = PHASE_MSGIN;
	break;
    }
    acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);
}

/*
 * Function: int acornscsi_buildmessages(AS_Host *host)
 * Purpose : build the connection messages for a host
 * Params  : host - host to add messages to
 */
static
void acornscsi_buildmessages(AS_Host *host)
{
#if 0
    /* does the device need resetting? */
    if (cmd_reset) {
	msgqueue_addmsg(&host->scsi.msgs, 1, BUS_DEVICE_RESET);
	return;
    }
#endif

    msgqueue_addmsg(&host->scsi.msgs, 1,
		     IDENTIFY(host->device[host->SCpnt->device->id].disconnect_ok,
			     host->SCpnt->device->lun));

#if 0
    /* does the device need the current command aborted */
    if (cmd_aborted) {
	acornscsi_abortcmd(host->SCpnt->tag);
	return;
    }
#endif

#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
    if (host->SCpnt->tag) {
	unsigned int tag_type;

	if (host->SCpnt->cmnd[0] == REQUEST_SENSE ||
	    host->SCpnt->cmnd[0] == TEST_UNIT_READY ||
	    host->SCpnt->cmnd[0] == INQUIRY)
	    tag_type = HEAD_OF_QUEUE_TAG;
	else
	    tag_type = SIMPLE_QUEUE_TAG;
	msgqueue_addmsg(&host->scsi.msgs, 2, tag_type, host->SCpnt->tag);
    }
#endif

#ifdef CONFIG_SCSI_ACORNSCSI_SYNC
    if (host->device[host->SCpnt->device->id].sync_state == SYNC_NEGOCIATE) {
	host->device[host->SCpnt->device->id].sync_state = SYNC_SENT_REQUEST;
	msgqueue_addmsg(&host->scsi.msgs, 5,
			 EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
			 sdtr_period / 4, sdtr_size);
    }
#endif
}

/*
 * Function: int acornscsi_starttransfer(AS_Host *host)
 * Purpose : transfer data to/from connected target
 * Params  : host - host to which target is connected
 * Returns : 0 if failure
 */
static
int acornscsi_starttransfer(AS_Host *host)
{
    int residual;

    if (!host->scsi.SCp.ptr /*&& host->scsi.SCp.this_residual*/) {
	printk(KERN_ERR "scsi%d.%c: null buffer passed to acornscsi_starttransfer\n",
		host->host->host_no, acornscsi_target(host));
	return 0;
    }

    residual = host->SCpnt->request_bufflen - host->scsi.SCp.scsi_xferred;

    sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
    sbic_arm_writenext(host->scsi.io_port, residual >> 16);
    sbic_arm_writenext(host->scsi.io_port, residual >> 8);
    sbic_arm_writenext(host->scsi.io_port, residual);
    acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
    return 1;
}

/* =========================================================================================
 * Connection & Disconnection
 */
/*
 * Function : acornscsi_reconnect(AS_Host *host)
 * Purpose  : reconnect a previously disconnected command
 * Params   : host - host specific data
 * Remarks  : SCSI spec says:
 *		'The set of active pointers is restored from the set
 *		 of saved pointers upon reconnection of the I/O process'
 */
static
int acornscsi_reconnect(AS_Host *host)
{
    unsigned int target, lun, ok = 0;

    target = sbic_arm_read(host->scsi.io_port, SBIC_SOURCEID);

    if (!(target & 8))
	printk(KERN_ERR "scsi%d: invalid source id after reselection "
		"- device fault?\n",
		host->host->host_no);

    target &= 7;

    if (host->SCpnt && !host->scsi.disconnectable) {
	printk(KERN_ERR "scsi%d.%d: reconnected while command in "
		"progress to target %d?\n",
		host->host->host_no, target, host->SCpnt->device->id);
	host->SCpnt = NULL;
    }

    lun = sbic_arm_read(host->scsi.io_port, SBIC_DATA) & 7;

    host->scsi.reconnected.target = target;
    host->scsi.reconnected.lun = lun;
    host->scsi.reconnected.tag = 0;

    if (host->scsi.disconnectable && host->SCpnt &&
	host->SCpnt->device->id == target && host->SCpnt->device->lun == lun)
	ok = 1;

    if (!ok && queue_probetgtlun(&host->queues.disconnected, target, lun))
	ok = 1;

    ADD_STATUS(target, 0x81, host->scsi.phase, 0);

    if (ok) {
	host->scsi.phase = PHASE_RECONNECTED;
    } else {
	/* this doesn't seem to work */
	printk(KERN_ERR "scsi%d.%c: reselected with no command "
		"to reconnect with\n",
		host->host->host_no, '0' + target);
	acornscsi_dumplog(host, target);
	acornscsi_abortcmd(host, 0);
	if (host->SCpnt) {
	    queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
	    host->SCpnt = NULL;
	}
    }
    acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);
    return !ok;
}

/*
 * Function: int acornscsi_reconect_finish(AS_Host *host)
 * Purpose : finish reconnecting a command
 * Params  : host - host to complete
 * Returns : 0 if failed
 */
static
int acornscsi_reconnect_finish(AS_Host *host)
{
    if (host->scsi.disconnectable && host->SCpnt) {
	host->scsi.disconnectable = 0;
	if (host->SCpnt->device->id  == host->scsi.reconnected.target &&
	    host->SCpnt->device->lun == host->scsi.reconnected.lun &&
	    host->SCpnt->tag         == host->scsi.reconnected.tag) {
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
	    DBG(host->SCpnt, printk("scsi%d.%c: reconnected",
		    host->host->host_no, acornscsi_target(host)));
#endif
	} else {
	    queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
	    DBG(host->SCpnt, printk("scsi%d.%c: had to move command "
		    "to disconnected queue\n",
		    host->host->host_no, acornscsi_target(host)));
#endif
	    host->SCpnt = NULL;
	}
    }
    if (!host->SCpnt) {
	host->SCpnt = queue_remove_tgtluntag(&host->queues.disconnected,
				host->scsi.reconnected.target,
				host->scsi.reconnected.lun,
				host->scsi.reconnected.tag);
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
	DBG(host->SCpnt, printk("scsi%d.%c: had to get command",
		host->host->host_no, acornscsi_target(host)));
#endif
    }

    if (!host->SCpnt)
	acornscsi_abortcmd(host, host->scsi.reconnected.tag);
    else {
	/*
	 * Restore data pointer from SAVED pointers.
	 */
	host->scsi.SCp = host->SCpnt->SCp;
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
	printk(", data pointers: [%p, %X]",
		host->scsi.SCp.ptr, host->scsi.SCp.this_residual);
#endif
    }
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
    printk("\n");
#endif

    host->dma.transferred = host->scsi.SCp.scsi_xferred;

    return host->SCpnt != NULL;
}

/*
 * Function: void acornscsi_disconnect_unexpected(AS_Host *host)
 * Purpose : handle an unexpected disconnect
 * Params  : host - host on which disconnect occurred
 */
static
void acornscsi_disconnect_unexpected(AS_Host *host)
{
    printk(KERN_ERR "scsi%d.%c: unexpected disconnect\n",
	    host->host->host_no, acornscsi_target(host));
#if (DEBUG & DEBUG_ABORT)
    acornscsi_dumplog(host, 8);
#endif

    acornscsi_done(host, &host->SCpnt, DID_ERROR);
}

/*
 * Function: void acornscsi_abortcmd(AS_host *host, unsigned char tag)
 * Purpose : abort a currently executing command
 * Params  : host - host with connected command to abort
 *	     tag  - tag to abort
 */
static
void acornscsi_abortcmd(AS_Host *host, unsigned char tag)
{
    host->scsi.phase = PHASE_ABORTED;
    sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_ASSERTATN);

    msgqueue_flush(&host->scsi.msgs);
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
    if (tag)
	msgqueue_addmsg(&host->scsi.msgs, 2, ABORT_TAG, tag);
    else
#endif
	msgqueue_addmsg(&host->scsi.msgs, 1, ABORT);
}

/* ==========================================================================================
 * Interrupt routines.
 */
/*
 * Function: int acornscsi_sbicintr(AS_Host *host)
 * Purpose : handle interrupts from SCSI device
 * Params  : host - host to process
 * Returns : INTR_PROCESS if expecting another SBIC interrupt
 *	     INTR_IDLE if no interrupt
 *	     INTR_NEXT_COMMAND if we have finished processing the command
 */
static
intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq)
{
    unsigned int asr, ssr;

    asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
    if (!(asr & ASR_INT))
	return INTR_IDLE;

    ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR);

#if (DEBUG & DEBUG_PHASES)
    print_sbic_status(asr, ssr, host->scsi.phase);
#endif

    ADD_STATUS(8, ssr, host->scsi.phase, in_irq);

    if (host->SCpnt && !host->scsi.disconnectable)
	ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, in_irq);

    switch (ssr) {
    case 0x00:				/* reset state - not advanced			*/
	printk(KERN_ERR "scsi%d: reset in standard mode but wanted advanced mode.\n",
		host->host->host_no);
	/* setup sbic - WD33C93A */
	sbic_arm_write(host->scsi.io_port, SBIC_OWNID, OWNID_EAF | host->host->this_id);
	sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_RESET);
	return INTR_IDLE;

    case 0x01:				/* reset state - advanced			*/
	sbic_arm_write(host->scsi.io_port, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
	sbic_arm_write(host->scsi.io_port, SBIC_TIMEOUT, TIMEOUT_TIME);
	sbic_arm_write(host->scsi.io_port, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
	sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
	msgqueue_flush(&host->scsi.msgs);
	return INTR_IDLE;

    case 0x41:				/* unexpected disconnect aborted command	*/
	acornscsi_disconnect_unexpected(host);
	return INTR_NEXT_COMMAND;
    }

    switch (host->scsi.phase) {
    case PHASE_CONNECTING:		/* STATE: command removed from issue queue	*/
	switch (ssr) {
	case 0x11:			/* -> PHASE_CONNECTED				*/
	    /* BUS FREE -> SELECTION */
	    host->scsi.phase = PHASE_CONNECTED;
	    msgqueue_flush(&host->scsi.msgs);
	    host->dma.transferred = host->scsi.SCp.scsi_xferred;
	    /* 33C93 gives next interrupt indicating bus phase */
	    asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
	    if (!(asr & ASR_INT))
		break;
	    ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR);
	    ADD_STATUS(8, ssr, host->scsi.phase, 1);
	    ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, 1);
	    goto connected;
	    
	case 0x42:			/* select timed out				*/
					/* -> PHASE_IDLE				*/
	    acornscsi_done(host, &host->SCpnt, DID_NO_CONNECT);
	    return INTR_NEXT_COMMAND;

	case 0x81:			/* -> PHASE_RECONNECTED or PHASE_ABORTED	*/
	    /* BUS FREE -> RESELECTION */
	    host->origSCpnt = host->SCpnt;
	    host->SCpnt = NULL;
	    msgqueue_flush(&host->scsi.msgs);
	    acornscsi_reconnect(host);
	    break;

	default:
	    printk(KERN_ERR "scsi%d.%c: PHASE_CONNECTING, SSR %02X?\n",
		    host->host->host_no, acornscsi_target(host), ssr);
	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
	    acornscsi_abortcmd(host, host->SCpnt->tag);
	}
	return INTR_PROCESSING;

    connected:
    case PHASE_CONNECTED:		/* STATE: device selected ok			*/
	switch (ssr) {
#ifdef NONSTANDARD
	case 0x8a:			/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED	*/
	    /* SELECTION -> COMMAND */
	    acornscsi_sendcommand(host);
	    break;

	case 0x8b:			/* -> PHASE_STATUS				*/
	    /* SELECTION -> STATUS */
	    acornscsi_readstatusbyte(host);
	    host->scsi.phase = PHASE_STATUSIN;
	    break;
#endif

	case 0x8e:			/* -> PHASE_MSGOUT				*/
	    /* SELECTION ->MESSAGE OUT */
	    host->scsi.phase = PHASE_MSGOUT;
	    acornscsi_buildmessages(host);
	    acornscsi_sendmessage(host);
	    break;

	/* these should not happen */
	case 0x85:			/* target disconnected				*/
	    acornscsi_done(host, &host->SCpnt, DID_ERROR);
	    break;

	default:
	    printk(KERN_ERR "scsi%d.%c: PHASE_CONNECTED, SSR %02X?\n",
		    host->host->host_no, acornscsi_target(host), ssr);
	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
	    acornscsi_abortcmd(host, host->SCpnt->tag);
	}
	return INTR_PROCESSING;

    case PHASE_MSGOUT:			/* STATE: connected & sent IDENTIFY message	*/
	/*
	 * SCSI standard says that MESSAGE OUT phases can be followed by a
	 * DATA phase, STATUS phase, MESSAGE IN phase or COMMAND phase
	 */
	switch (ssr) {
	case 0x8a:			/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED	*/
	case 0x1a:			/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED	*/
	    /* MESSAGE OUT -> COMMAND */
	    acornscsi_sendcommand(host);
	    break;

	case 0x8b:			/* -> PHASE_STATUS				*/
	case 0x1b:			/* -> PHASE_STATUS				*/
	    /* MESSAGE OUT -> STATUS */
	    acornscsi_readstatusbyte(host);
	    host->scsi.phase = PHASE_STATUSIN;
	    break;

	case 0x8e:			/* -> PHASE_MSGOUT				*/
	    /* MESSAGE_OUT(MESSAGE_IN) ->MESSAGE OUT */
	    acornscsi_sendmessage(host);
	    break;

	case 0x4f:			/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/
	case 0x1f:			/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/
	    /* MESSAGE OUT -> MESSAGE IN */
	    acornscsi_message(host);
	    break;

	default:
	    printk(KERN_ERR "scsi%d.%c: PHASE_MSGOUT, SSR %02X?\n",
		    host->host->host_no, acornscsi_target(host), ssr);
	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
	}
	return INTR_PROCESSING;

    case PHASE_COMMAND: 		/* STATE: connected & command sent		*/
	switch (ssr) {
	case 0x18:			/* -> PHASE_DATAOUT				*/
	    /* COMMAND -> DATA OUT */
	    if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len)
		acornscsi_abortcmd(host, host->SCpnt->tag);
	    acornscsi_dma_setup(host, DMA_OUT);
	    if (!acornscsi_starttransfer(host))
		acornscsi_abortcmd(host, host->SCpnt->tag);
	    host->scsi.phase = PHASE_DATAOUT;
	    return INTR_IDLE;

	case 0x19:			/* -> PHASE_DATAIN				*/
	    /* COMMAND -> DATA IN */
	    if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len)
		acornscsi_abortcmd(host, host->SCpnt->tag);
	    acornscsi_dma_setup(host, DMA_IN);
	    if (!acornscsi_starttransfer(host))
		acornscsi_abortcmd(host, host->SCpnt->tag);
	    host->scsi.phase = PHASE_DATAIN;
	    return INTR_IDLE;

	case 0x1b:			/* -> PHASE_STATUS				*/
	    /* COMMAND -> STATUS */
	    acornscsi_readstatusbyte(host);
	    host->scsi.phase = PHASE_STATUSIN;
	    break;

	case 0x1e:			/* -> PHASE_MSGOUT				*/
	    /* COMMAND -> MESSAGE OUT */
	    acornscsi_sendmessage(host);
	    break;

	case 0x1f:			/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/
	    /* COMMAND -> MESSAGE IN */
	    acornscsi_message(host);
	    break;

	default:
	    printk(KERN_ERR "scsi%d.%c: PHASE_COMMAND, SSR %02X?\n",
		    host->host->host_no, acornscsi_target(host), ssr);
	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
	}
	return INTR_PROCESSING;

    case PHASE_DISCONNECT:		/* STATE: connected, received DISCONNECT msg	*/
	if (ssr == 0x85) {		/* -> PHASE_IDLE				*/
	    host->scsi.disconnectable = 1;
	    host->scsi.reconnected.tag = 0;
	    host->scsi.phase = PHASE_IDLE;
	    host->stats.disconnects += 1;
	} else {
	    printk(KERN_ERR "scsi%d.%c: PHASE_DISCONNECT, SSR %02X instead of disconnect?\n",
		    host->host->host_no, acornscsi_target(host), ssr);
	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
	}
	return INTR_NEXT_COMMAND;

    case PHASE_IDLE:			/* STATE: disconnected				*/
	if (ssr == 0x81)		/* -> PHASE_RECONNECTED or PHASE_ABORTED	*/
	    acornscsi_reconnect(host);
	else {
	    printk(KERN_ERR "scsi%d.%c: PHASE_IDLE, SSR %02X while idle?\n",
		    host->host->host_no, acornscsi_target(host), ssr);
	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
	}
	return INTR_PROCESSING;

    case PHASE_RECONNECTED:		/* STATE: device reconnected to initiator	*/
	/*
	 * Command reconnected - if MESGIN, get message - it may be
	 * the tag.  If not, get command out of disconnected queue
	 */
	/*
	 * If we reconnected and we're not in MESSAGE IN phase after IDENTIFY,
	 * reconnect I_T_L command
	 */
	if (ssr != 0x8f && !acornscsi_reconnect_finish(host))
	    return INTR_IDLE;
	ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, in_irq);
	switch (ssr) {
	case 0x88:			/* data out phase				*/
					/* -> PHASE_DATAOUT				*/
	    /* MESSAGE IN -> DATA OUT */
	    acornscsi_dma_setup(host, DMA_OUT);
	    if (!acornscsi_starttransfer(host))
		acornscsi_abortcmd(host, host->SCpnt->tag);
	    host->scsi.phase = PHASE_DATAOUT;
	    return INTR_IDLE;

	case 0x89:			/* data in phase				*/
					/* -> PHASE_DATAIN				*/
	    /* MESSAGE IN -> DATA IN */
	    acornscsi_dma_setup(host, DMA_IN);
	    if (!acornscsi_starttransfer(host))
		acornscsi_abortcmd(host, host->SCpnt->tag);
	    host->scsi.phase = PHASE_DATAIN;
	    return INTR_IDLE;

	case 0x8a:			/* command out					*/
	    /* MESSAGE IN -> COMMAND */
	    acornscsi_sendcommand(host);/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED	*/
	    break;

	case 0x8b:			/* status in					*/
					/* -> PHASE_STATUSIN				*/
	    /* MESSAGE IN -> STATUS */
	    acornscsi_readstatusbyte(host);
	    host->scsi.phase = PHASE_STATUSIN;
	    break;

	case 0x8e:			/* message out					*/
					/* -> PHASE_MSGOUT				*/
	    /* MESSAGE IN -> MESSAGE OUT */
	    acornscsi_sendmessage(host);
	    break;

	case 0x8f:			/* message in					*/
	    acornscsi_message(host);	/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/
	    break;

	default:
	    printk(KERN_ERR "scsi%d.%c: PHASE_RECONNECTED, SSR %02X after reconnect?\n",
		    host->host->host_no, acornscsi_target(host), ssr);
	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
	}
	return INTR_PROCESSING;

    case PHASE_DATAIN:			/* STATE: transferred data in			*/
	/*
	 * This is simple - if we disconnect then the DMA address & count is
	 * correct.
	 */
	switch (ssr) {
	case 0x19:			/* -> PHASE_DATAIN				*/
	case 0x89:			/* -> PHASE_DATAIN				*/
	    acornscsi_abortcmd(host, host->SCpnt->tag);
	    return INTR_IDLE;

	case 0x1b:			/* -> PHASE_STATUSIN				*/
	case 0x4b:			/* -> PHASE_STATUSIN				*/
	case 0x8b:			/* -> PHASE_STATUSIN				*/
	    /* DATA IN -> STATUS */
	    host->scsi.SCp.scsi_xferred = host->SCpnt->request_bufflen -
					  acornscsi_sbic_xfcount(host);
	    acornscsi_dma_stop(host);
	    acornscsi_readstatusbyte(host);
	    host->scsi.phase = PHASE_STATUSIN;
	    break;

	case 0x1e:			/* -> PHASE_MSGOUT				*/
	case 0x4e:			/* -> PHASE_MSGOUT				*/
	case 0x8e:			/* -> PHASE_MSGOUT				*/
	    /* DATA IN -> MESSAGE OUT */
	    host->scsi.SCp.scsi_xferred = host->SCpnt->request_bufflen -
					  acornscsi_sbic_xfcount(host);
	    acornscsi_dma_stop(host);
	    acornscsi_sendmessage(host);
	    break;

	case 0x1f:			/* message in					*/
	case 0x4f:			/* message in					*/
	case 0x8f:			/* message in					*/
	    /* DATA IN -> MESSAGE IN */
	    host->scsi.SCp.scsi_xferred = host->SCpnt->request_bufflen -
					  acornscsi_sbic_xfcount(host);
	    acornscsi_dma_stop(host);
	    acornscsi_message(host);	/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/
	    break;

	default:
	    printk(KERN_ERR "scsi%d.%c: PHASE_DATAIN, SSR %02X?\n",
		    host->host->host_no, acornscsi_target(host), ssr);
	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
	}
	return INTR_PROCESSING;

    case PHASE_DATAOUT: 		/* STATE: transferred data out			*/
	/*
	 * This is more complicated - if we disconnect, the DMA could be 12
	 * bytes ahead of us.  We need to correct this.
	 */
	switch (ssr) {
	case 0x18:			/* -> PHASE_DATAOUT				*/
	case 0x88:			/* -> PHASE_DATAOUT				*/
	    acornscsi_abortcmd(host, host->SCpnt->tag);
	    return INTR_IDLE;

	case 0x1b:			/* -> PHASE_STATUSIN				*/
	case 0x4b:			/* -> PHASE_STATUSIN				*/
	case 0x8b:			/* -> PHASE_STATUSIN				*/
	    /* DATA OUT -> STATUS */
	    host->scsi.SCp.scsi_xferred = host->SCpnt->request_bufflen -
					  acornscsi_sbic_xfcount(host);
	    acornscsi_dma_stop(host);
	    acornscsi_dma_adjust(host);
	    acornscsi_readstatusbyte(host);
	    host->scsi.phase = PHASE_STATUSIN;
	    break;

	case 0x1e:			/* -> PHASE_MSGOUT				*/
	case 0x4e:			/* -> PHASE_MSGOUT				*/
	case 0x8e:			/* -> PHASE_MSGOUT				*/
	    /* DATA OUT -> MESSAGE OUT */
	    host->scsi.SCp.scsi_xferred = host->SCpnt->request_bufflen -
					  acornscsi_sbic_xfcount(host);
	    acornscsi_dma_stop(host);
	    acornscsi_dma_adjust(host);
	    acornscsi_sendmessage(host);
	    break;

	case 0x1f:			/* message in					*/
	case 0x4f:			/* message in					*/
	case 0x8f:			/* message in					*/
	    /* DATA OUT -> MESSAGE IN */
	    host->scsi.SCp.scsi_xferred = host->SCpnt->request_bufflen -
					  acornscsi_sbic_xfcount(host);
	    acornscsi_dma_stop(host);
	    acornscsi_dma_adjust(host);
	    acornscsi_message(host);	/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/
	    break;

	default:
	    printk(KERN_ERR "scsi%d.%c: PHASE_DATAOUT, SSR %02X?\n",
		    host->host->host_no, acornscsi_target(host), ssr);
	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
	}
	return INTR_PROCESSING;

    case PHASE_STATUSIN:		/* STATE: status in complete			*/
	switch (ssr) {
	case 0x1f:			/* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
	case 0x8f:			/* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
	    /* STATUS -> MESSAGE IN */
	    acornscsi_message(host);
	    break;

	case 0x1e:			/* -> PHASE_MSGOUT				*/
	case 0x8e:			/* -> PHASE_MSGOUT				*/
	    /* STATUS -> MESSAGE OUT */
	    acornscsi_sendmessage(host);
	    break;

	default:
	    printk(KERN_ERR "scsi%d.%c: PHASE_STATUSIN, SSR %02X instead of MESSAGE_IN?\n",
		    host->host->host_no, acornscsi_target(host), ssr);
	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
	}
	return INTR_PROCESSING;

    case PHASE_MSGIN:			/* STATE: message in				*/
	switch (ssr) {
	case 0x1e:			/* -> PHASE_MSGOUT				*/
	case 0x4e:			/* -> PHASE_MSGOUT				*/
	case 0x8e:			/* -> PHASE_MSGOUT				*/
	    /* MESSAGE IN -> MESSAGE OUT */
	    acornscsi_sendmessage(host);
	    break;

	case 0x1f:			/* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
	case 0x2f:
	case 0x4f:
	case 0x8f:
	    acornscsi_message(host);
	    break;

	case 0x85:
	    printk("scsi%d.%c: strange message in disconnection\n",
		host->host->host_no, acornscsi_target(host));
	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
	    acornscsi_done(host, &host->SCpnt, DID_ERROR);
	    break;

	default:
	    printk(KERN_ERR "scsi%d.%c: PHASE_MSGIN, SSR %02X after message in?\n",
		    host->host->host_no, acornscsi_target(host), ssr);
	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
	}
	return INTR_PROCESSING;

    case PHASE_DONE:			/* STATE: received status & message		*/
	switch (ssr) {
	case 0x85:			/* -> PHASE_IDLE				*/
	    acornscsi_done(host, &host->SCpnt, DID_OK);
	    return INTR_NEXT_COMMAND;

	case 0x1e:
	case 0x8e:
	    acornscsi_sendmessage(host);
	    break;

	default:
	    printk(KERN_ERR "scsi%d.%c: PHASE_DONE, SSR %02X instead of disconnect?\n",
		    host->host->host_no, acornscsi_target(host), ssr);
	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
	}
	return INTR_PROCESSING;

    case PHASE_ABORTED:
	switch (ssr) {
	case 0x85:
	    if (host->SCpnt)
		acornscsi_done(host, &host->SCpnt, DID_ABORT);
	    else {
		clear_bit(host->scsi.reconnected.target * 8 + host->scsi.reconnected.lun,
			  host->busyluns);
		host->scsi.phase = PHASE_IDLE;
	    }
	    return INTR_NEXT_COMMAND;

	case 0x1e:
	case 0x2e:
	case 0x4e:
	case 0x8e:
	    acornscsi_sendmessage(host);
	    break;

	default:
	    printk(KERN_ERR "scsi%d.%c: PHASE_ABORTED, SSR %02X?\n",
		    host->host->host_no, acornscsi_target(host), ssr);
	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
	}
	return INTR_PROCESSING;

    default:
	printk(KERN_ERR "scsi%d.%c: unknown driver phase %d\n",
		host->host->host_no, acornscsi_target(host), ssr);
	acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
    }
    return INTR_PROCESSING;
}

/*
 * Prototype: void acornscsi_intr(int irq, void *dev_id)
 * Purpose  : handle interrupts from Acorn SCSI card
 * Params   : irq    - interrupt number
 *	      dev_id - device specific data (AS_Host structure)
 */
static irqreturn_t
acornscsi_intr(int irq, void *dev_id)
{
    AS_Host *host = (AS_Host *)dev_id;
    intr_ret_t ret;
    int iostatus;
    int in_irq = 0;

    do {
	ret = INTR_IDLE;

	iostatus = inb(host->card.io_intr);

	if (iostatus & 2) {
	    acornscsi_dma_intr(host);
	    iostatus = inb(host->card.io_intr);
	}

	if (iostatus & 8)
	    ret = acornscsi_sbicintr(host, in_irq);

	/*
	 * If we have a transfer pending, start it.
	 * Only start it if the interface has already started transferring
	 * it's data
	 */
	if (host->dma.xfer_required)
	    acornscsi_dma_xfer(host);

	if (ret == INTR_NEXT_COMMAND)
	    ret = acornscsi_kick(host);

	in_irq = 1;
    } while (ret != INTR_IDLE);

    return IRQ_HANDLED;
}

/*=============================================================================================
 * Interfaces between interrupt handler and rest of scsi code
 */

/*
 * Function : acornscsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 * Purpose  : queues a SCSI command
 * Params   : cmd  - SCSI command
 *	      done - function called on completion, with pointer to command descriptor
 * Returns  : 0, or < 0 on error.
 */
int acornscsi_queuecmd(struct scsi_cmnd *SCpnt,
		       void (*done)(struct scsi_cmnd *))
{
    AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;

    if (!done) {
	/* there should be some way of rejecting errors like this without panicing... */
	panic("scsi%d: queuecommand called with NULL done function [cmd=%p]",
		host->host->host_no, SCpnt);
	return -EINVAL;
    }

#if (DEBUG & DEBUG_NO_WRITE)
    if (acornscsi_cmdtype(SCpnt->cmnd[0]) == CMD_WRITE && (NO_WRITE & (1 << SCpnt->device->id))) {
	printk(KERN_CRIT "scsi%d.%c: WRITE attempted with NO_WRITE flag set\n",
	    host->host->host_no, '0' + SCpnt->device->id);
	SCpnt->result = DID_NO_CONNECT << 16;
	done(SCpnt);
	return 0;
    }
#endif

    SCpnt->scsi_done = done;
    SCpnt->host_scribble = NULL;
    SCpnt->result = 0;
    SCpnt->tag = 0;
    SCpnt->SCp.phase = (int)acornscsi_datadirection(SCpnt->cmnd[0]);
    SCpnt->SCp.sent_command = 0;
    SCpnt->SCp.scsi_xferred = 0;

    init_SCp(SCpnt);

    host->stats.queues += 1;

    {
	unsigned long flags;

	if (!queue_add_cmd_ordered(&host->queues.issue, SCpnt)) {
	    SCpnt->result = DID_ERROR << 16;
	    done(SCpnt);
	    return 0;
	}
	local_irq_save(flags);
	if (host->scsi.phase == PHASE_IDLE)
	    acornscsi_kick(host);
	local_irq_restore(flags);
    }
    return 0;
}

/*
 * Prototype: void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1, struct scsi_cmnd **SCpntp2, int result)
 * Purpose  : pass a result to *SCpntp1, and check if *SCpntp1 = *SCpntp2
 * Params   : SCpntp1 - pointer to command to return
 *	      SCpntp2 - pointer to command to check
 *	      result  - result to pass back to mid-level done function
 * Returns  : *SCpntp2 = NULL if *SCpntp1 is the same command structure as *SCpntp2.
 */
static inline void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1,
					  struct scsi_cmnd **SCpntp2,
					  int result)
{
	struct scsi_cmnd *SCpnt = *SCpntp1;

    if (SCpnt) {
	*SCpntp1 = NULL;

	SCpnt->result = result;
	SCpnt->scsi_done(SCpnt);
    }

    if (SCpnt == *SCpntp2)
	*SCpntp2 = NULL;
}

enum res_abort { res_not_running, res_success, res_success_clear, res_snooze };

/*
 * Prototype: enum res acornscsi_do_abort(struct scsi_cmnd *SCpnt)
 * Purpose  : abort a command on this host
 * Params   : SCpnt - command to abort
 * Returns  : our abort status
 */
static enum res_abort acornscsi_do_abort(AS_Host *host, struct scsi_cmnd *SCpnt)
{
	enum res_abort res = res_not_running;

	if (queue_remove_cmd(&host->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 devices nor the
		 * interface know about the command.
		 */
//#if (DEBUG & DEBUG_ABORT)
		printk("on issue queue ");
//#endif
		res = res_success;
	} else if (queue_remove_cmd(&host->queues.disconnected, SCpnt)) {
		/*
		 * The command was on the disconnected queue.  Simply
		 * acknowledge the abort condition, and when the target
		 * reconnects, we will give it an ABORT message.  The
		 * target should then disconnect, and we will clear
		 * the busylun bit.
		 */
//#if (DEBUG & DEBUG_ABORT)
		printk("on disconnected queue ");
//#endif
		res = res_success;
	} else if (host->SCpnt == SCpnt) {
		unsigned long flags;

//#if (DEBUG & DEBUG_ABORT)
		printk("executing ");
//#endif

		local_irq_save(flags);
		switch (host->scsi.phase) {
		/*
		 * If the interface is idle, and the command is 'disconnectable',
		 * then it is the same as on the disconnected queue.  We simply
		 * remove all traces of the command.  When the target reconnects,
		 * we will give it an ABORT message since the command could not
		 * be found.  When the target finally disconnects, we will clear
		 * the busylun bit.
		 */
		case PHASE_IDLE:
			if (host->scsi.disconnectable) {
				host->scsi.disconnectable = 0;
				host->SCpnt = NULL;
				res = res_success;
			}
			break;

		/*
		 * If the command has connected and done nothing further,
		 * simply force a disconnect.  We also need to clear the
		 * busylun bit.
		 */
		case PHASE_CONNECTED:
			sbic_arm_write(host->scsi.io_port, SBIC_CMND, CMND_DISCONNECT);
			host->SCpnt = NULL;
			res = res_success_clear;
			break;

		default:
			acornscsi_abortcmd(host, host->SCpnt->tag);
			res = res_snooze;
		}
		local_irq_restore(flags);
	} else if (host->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.
		 */
		host->origSCpnt = NULL;
//#if (DEBUG & DEBUG_ABORT)
		printk("waiting for execution ");
//#endif
		res = res_success_clear;
	} else
		printk("unknown ");

	return res;
}

/*
 * Prototype: int acornscsi_abort(struct scsi_cmnd *SCpnt)
 * Purpose  : abort a command on this host
 * Params   : SCpnt - command to abort
 * Returns  : one of SCSI_ABORT_ macros
 */
int acornscsi_abort(struct scsi_cmnd *SCpnt)
{
	AS_Host *host = (AS_Host *) SCpnt->device->host->hostdata;
	int result;

	host->stats.aborts += 1;

#if (DEBUG & DEBUG_ABORT)
	{
		int asr, ssr;
		asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
		ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR);

		printk(KERN_WARNING "acornscsi_abort: ");
		print_sbic_status(asr, ssr, host->scsi.phase);
		acornscsi_dumplog(host, SCpnt->device->id);
	}
#endif

	printk("scsi%d: ", host->host->host_no);

	switch (acornscsi_do_abort(host, SCpnt)) {
	/*
	 * We managed to find the command and cleared it out.
	 * We do not expect the command to be executing on the
	 * target, but we have set the busylun bit.
	 */
	case res_success_clear:
//#if (DEBUG & DEBUG_ABORT)
		printk("clear ");
//#endif
		clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, host->busyluns);

	/*
	 * 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:
//#if (DEBUG & DEBUG_ABORT)
		printk("success\n");
//#endif
		SCpnt->result = DID_ABORT << 16;
		SCpnt->scsi_done(SCpnt);
		result = SCSI_ABORT_SUCCESS;
		break;

	/*
	 * We did find the command, but unfortunately we couldn't
	 * unhook it from ourselves.  Wait some more, and if it
	 * still doesn't complete, reset the interface.
	 */
	case res_snooze:
//#if (DEBUG & DEBUG_ABORT)
		printk("snooze\n");
//#endif
		result = SCSI_ABORT_SNOOZE;
		break;

	/*
	 * The command could not be found (either because it completed,
	 * or it got dropped.
	 */
	default:
	case res_not_running:
		acornscsi_dumplog(host, SCpnt->device->id);
#if (DEBUG & DEBUG_ABORT)
		result = SCSI_ABORT_SNOOZE;
#else
		result = SCSI_ABORT_NOT_RUNNING;
#endif
//#if (DEBUG & DEBUG_ABORT)
		printk("not running\n");
//#endif
		break;
	}

	return result;
}

/*
 * Prototype: int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags)
 * Purpose  : reset a command on this host/reset this host
 * Params   : SCpnt  - command causing reset
 *	      result - what type of reset to perform
 * Returns  : one of SCSI_RESET_ macros
 */
int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags)
{
	AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
	struct scsi_cmnd *SCptr;
    
    host->stats.resets += 1;

#if (DEBUG & DEBUG_RESET)
    {
	int asr, ssr;

	asr = sbic_arm_read(host->scsi.io_port, SBIC_ASR);
	ssr = sbic_arm_read(host->scsi.io_port, SBIC_SSR);

	printk(KERN_WARNING "acornscsi_reset: ");
	print_sbic_status(asr, ssr, host->scsi.phase);
	acornscsi_dumplog(host, SCpnt->device->id);
    }
#endif

    acornscsi_dma_stop(host);

    SCptr = host->SCpnt;

    /*
     * do hard reset.  This resets all devices on this host, and so we
     * must set the reset status on all commands.
     */
    acornscsi_resetcard(host);

    /*
     * report reset on commands current connected/disconnected
     */
    acornscsi_reportstatus(&host->SCpnt, &SCptr, DID_RESET);

    while ((SCptr = queue_remove(&host->queues.disconnected)) != NULL)
	acornscsi_reportstatus(&SCptr, &SCpnt, DID_RESET);

    if (SCpnt) {
	SCpnt->result = DID_RESET << 16;
	SCpnt->scsi_done(SCpnt);
    }

    return SCSI_RESET_BUS_RESET | SCSI_RESET_HOST_RESET | SCSI_RESET_SUCCESS;
}

/*==============================================================================================
 * initialisation & miscellaneous support
 */

/*
 * Function: char *acornscsi_info(struct Scsi_Host *host)
 * Purpose : return a string describing this interface
 * Params  : host - host to give information on
 * Returns : a constant string
 */
const
char *acornscsi_info(struct Scsi_Host *host)
{
    static char string[100], *p;

    p = string;
    
    p += sprintf(string, "%s at port %08lX irq %d v%d.%d.%d"
#ifdef CONFIG_SCSI_ACORNSCSI_SYNC
    " SYNC"
#endif
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
    " TAG"
#endif
#ifdef CONFIG_SCSI_ACORNSCSI_LINK
    " LINK"
#endif
#if (DEBUG & DEBUG_NO_WRITE)
    " NOWRITE ("NO_WRITE_STR")"
#endif
		, host->hostt->name, host->io_port, host->irq,
		VER_MAJOR, VER_MINOR, VER_PATCH);
    return string;
}

int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start, off_t offset,
			int length, int inout)
{
    int pos, begin = 0, devidx;
    struct scsi_device *scd;
    AS_Host *host;
    char *p = buffer;

    if (inout == 1)
	return -EINVAL;

    host  = (AS_Host *)instance->hostdata;
    
    p += sprintf(p, "AcornSCSI driver v%d.%d.%d"
#ifdef CONFIG_SCSI_ACORNSCSI_SYNC
    " SYNC"
#endif
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
    " TAG"
#endif
#ifdef CONFIG_SCSI_ACORNSCSI_LINK
    " LINK"
#endif
#if (DEBUG & DEBUG_NO_WRITE)
    " NOWRITE ("NO_WRITE_STR")"
#endif
		"\n\n", VER_MAJOR, VER_MINOR, VER_PATCH);

    p += sprintf(p,	"SBIC: WD33C93A  Address: %08X  IRQ : %d\n",
			host->scsi.io_port, host->scsi.irq);
#ifdef USE_DMAC
    p += sprintf(p,	"DMAC: uPC71071  Address: %08X  IRQ : %d\n\n",
			host->dma.io_port, host->scsi.irq);
#endif

    p += sprintf(p,	"Statistics:\n"
			"Queued commands: %-10u    Issued commands: %-10u\n"
			"Done commands  : %-10u    Reads          : %-10u\n"
			"Writes         : %-10u    Others         : %-10u\n"
			"Disconnects    : %-10u    Aborts         : %-10u\n"
			"Resets         : %-10u\n\nLast phases:",
			host->stats.queues,		host->stats.removes,
			host->stats.fins,		host->stats.reads,
			host->stats.writes,		host->stats.miscs,
			host->stats.disconnects,	host->stats.aborts,
			host->stats.resets);

    for (devidx = 0; devidx < 9; devidx ++) {
	unsigned int statptr, prev;

	p += sprintf(p, "\n%c:", devidx == 8 ? 'H' : ('0' + devidx));
	statptr = host->status_ptr[devidx] - 10;

	if ((signed int)statptr < 0)
	    statptr += STATUS_BUFFER_SIZE;

	prev = host->status[devidx][statptr].when;

	for (; statptr != host->status_ptr[devidx]; statptr = (statptr + 1) & (STATUS_BUFFER_SIZE - 1)) {
	    if (host->status[devidx][statptr].when) {
		p += sprintf(p, "%c%02X:%02X+%2ld",
			host->status[devidx][statptr].irq ? '-' : ' ',
			host->status[devidx][statptr].ph,
			host->status[devidx][statptr].ssr,
			(host->status[devidx][statptr].when - prev) < 100 ?
				(host->status[devidx][statptr].when - prev) : 99);
		prev = host->status[devidx][statptr].when;
	    }
	}
    }

    p += sprintf(p, "\nAttached devices:\n");

    shost_for_each_device(scd, instance) {
	p += sprintf(p, "Device/Lun TaggedQ      Sync\n");
	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  ");

	if (host->device[scd->id].sync_xfer & 15)
		p += sprintf(p, "offset %d, %d ns\n",
			     host->device[scd->id].sync_xfer & 15,
			     acornscsi_getperiod(host->device[scd->id].sync_xfer));
	else
		p += sprintf(p, "async\n");

	pos = p - buffer;
	if (pos + begin < offset) {
	    begin += pos;
	    p = buffer;
	}
	pos = p - buffer;
	if (pos + begin > offset + length) {
	    scsi_device_put(scd);
	    break;
	}
    }

    pos = p - buffer;

    *start = buffer + (offset - begin);
    pos -= offset - begin;

    if (pos > length)
	pos = length;

    return pos;
}

static struct scsi_host_template acornscsi_template = {
	.module			= THIS_MODULE,
	.proc_info		= acornscsi_proc_info,
	.name			= "AcornSCSI",
	.info			= acornscsi_info,
	.queuecommand		= acornscsi_queuecmd,
#warning fixme
	.abort			= acornscsi_abort,
	.reset			= acornscsi_reset,
	.can_queue		= 16,
	.this_id		= 7,
	.sg_tablesize		= SG_ALL,
	.cmd_per_lun		= 2,
	.unchecked_isa_dma	= 0,
	.use_clustering		= DISABLE_CLUSTERING,
	.proc_name		= "acornscsi",
};

static int __devinit
acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
{
	struct Scsi_Host *host;
	AS_Host *ashost;
	int ret = -ENOMEM;

	host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host));
	if (!host)
		goto out;

	ashost = (AS_Host *)host->hostdata;

	host->io_port = ecard_address(ec, ECARD_MEMC, 0);
	host->irq = ec->irq;

	ashost->host		= host;
	ashost->scsi.io_port	= ioaddr(host->io_port + 0x800);
	ashost->scsi.irq	= host->irq;
	ashost->card.io_intr	= POD_SPACE(host->io_port) + 0x800;
	ashost->card.io_page	= POD_SPACE(host->io_port) + 0xc00;
	ashost->card.io_ram	= ioaddr(host->io_port);
	ashost->dma.io_port	= host->io_port + 0xc00;
	ashost->dma.io_intr_clear = POD_SPACE(host->io_port) + 0x800;

	ec->irqaddr	= (char *)ioaddr(ashost->card.io_intr);
	ec->irqmask	= 0x0a;

	ret = -EBUSY;
	if (!request_region(host->io_port + 0x800, 2, "acornscsi(sbic)"))
		goto err_1;
	if (!request_region(ashost->card.io_intr, 1, "acornscsi(intr)"))
		goto err_2;
	if (!request_region(ashost->card.io_page, 1, "acornscsi(page)"))
		goto err_3;
#ifdef USE_DMAC
	if (!request_region(ashost->dma.io_port, 256, "acornscsi(dmac)"))
		goto err_4;
#endif
	if (!request_region(host->io_port, 2048, "acornscsi(ram)"))
		goto err_5;

	ret = request_irq(host->irq, acornscsi_intr, IRQF_DISABLED, "acornscsi", ashost);
	if (ret) {
		printk(KERN_CRIT "scsi%d: IRQ%d not free: %d\n",
			host->host_no, ashost->scsi.irq, ret);
		goto err_6;
	}

	memset(&ashost->stats, 0, sizeof (ashost->stats));
	queue_initialise(&ashost->queues.issue);
	queue_initialise(&ashost->queues.disconnected);
	msgqueue_initialise(&ashost->scsi.msgs);

	acornscsi_resetcard(ashost);

	ret = scsi_add_host(host, &ec->dev);
	if (ret)
		goto err_7;

	scsi_scan_host(host);
	goto out;

 err_7:
	free_irq(host->irq, ashost);
 err_6:
	release_region(host->io_port, 2048);
 err_5:
#ifdef USE_DMAC
	release_region(ashost->dma.io_port, 256);
#endif
 err_4:
	release_region(ashost->card.io_page, 1);
 err_3:
	release_region(ashost->card.io_intr, 1);    
 err_2:
	release_region(host->io_port + 0x800, 2);
 err_1:
	scsi_host_put(host);
 out:
	return ret;
}

static void __devexit acornscsi_remove(struct expansion_card *ec)
{
	struct Scsi_Host *host = ecard_get_drvdata(ec);
	AS_Host *ashost = (AS_Host *)host->hostdata;

	ecard_set_drvdata(ec, NULL);
	scsi_remove_host(host);

	/*
	 * Put card into RESET state
	 */
	outb(0x80, ashost->card.io_page);

	free_irq(host->irq, ashost);

	release_region(host->io_port + 0x800, 2);
	release_region(ashost->card.io_intr, 1);
	release_region(ashost->card.io_page, 1);
	release_region(ashost->dma.io_port, 256);
	release_region(host->io_port, 2048);

	msgqueue_free(&ashost->scsi.msgs);
	queue_free(&ashost->queues.disconnected);
	queue_free(&ashost->queues.issue);
	scsi_host_put(host);
}

static const struct ecard_id acornscsi_cids[] = {
	{ MANU_ACORN, PROD_ACORN_SCSI },
	{ 0xffff, 0xffff },
};

static struct ecard_driver acornscsi_driver = {
	.probe		= acornscsi_probe,
	.remove		= __devexit_p(acornscsi_remove),
	.id_table	= acornscsi_cids,
	.drv = {
		.name		= "acornscsi",
	},
};

static int __init acornscsi_init(void)
{
	return ecard_register_driver(&acornscsi_driver);
}

static void __exit acornscsi_exit(void)
{
	ecard_remove_driver(&acornscsi_driver);
}

module_init(acornscsi_init);
module_exit(acornscsi_exit);

MODULE_AUTHOR("Russell King");
MODULE_DESCRIPTION("AcornSCSI driver");
MODULE_LICENSE("GPL");
