/*
 *  Driver for Adaptec AHA-1542 SCSI host adapters
 *
 *  Copyright (C) 1992  Tommy Thorn
 *  Copyright (C) 1993, 1994, 1995 Eric Youngdale
 *  Copyright (C) 2015 Ondrej Zary
 */

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/isa.h>
#include <linux/pnp.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <asm/dma.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include "aha1542.h"

#define MAXBOARDS 4

static bool isapnp = 1;
module_param(isapnp, bool, 0);
MODULE_PARM_DESC(isapnp, "enable PnP support (default=1)");

static int io[MAXBOARDS] = { 0x330, 0x334, 0, 0 };
module_param_array(io, int, NULL, 0);
MODULE_PARM_DESC(io, "base IO address of controller (0x130,0x134,0x230,0x234,0x330,0x334, default=0x330,0x334)");

/* time AHA spends on the AT-bus during data transfer */
static int bus_on[MAXBOARDS] = { -1, -1, -1, -1 }; /* power-on default: 11us */
module_param_array(bus_on, int, NULL, 0);
MODULE_PARM_DESC(bus_on, "bus on time [us] (2-15, default=-1 [HW default: 11])");

/* time AHA spends off the bus (not to monopolize it) during data transfer  */
static int bus_off[MAXBOARDS] = { -1, -1, -1, -1 }; /* power-on default: 4us */
module_param_array(bus_off, int, NULL, 0);
MODULE_PARM_DESC(bus_off, "bus off time [us] (1-64, default=-1 [HW default: 4])");

/* default is jumper selected (J1 on 1542A), factory default = 5 MB/s */
static int dma_speed[MAXBOARDS] = { -1, -1, -1, -1 };
module_param_array(dma_speed, int, NULL, 0);
MODULE_PARM_DESC(dma_speed, "DMA speed [MB/s] (5,6,7,8,10, default=-1 [by jumper])");

#define BIOS_TRANSLATION_6432 1	/* Default case these days */
#define BIOS_TRANSLATION_25563 2	/* Big disk case */

struct aha1542_hostdata {
	/* This will effectively start both of them at the first mailbox */
	int bios_translation;	/* Mapping bios uses - for compatibility */
	int aha1542_last_mbi_used;
	int aha1542_last_mbo_used;
	struct scsi_cmnd *int_cmds[AHA1542_MAILBOXES];
	struct mailbox mb[2 * AHA1542_MAILBOXES];
	struct ccb ccb[AHA1542_MAILBOXES];
};

static inline void aha1542_intr_reset(u16 base)
{
	outb(IRST, CONTROL(base));
}

static inline bool wait_mask(u16 port, u8 mask, u8 allof, u8 noneof, int timeout)
{
	bool delayed = true;

	if (timeout == 0) {
		timeout = 3000000;
		delayed = false;
	}

	while (1) {
		u8 bits = inb(port) & mask;
		if ((bits & allof) == allof && ((bits & noneof) == 0))
			break;
		if (delayed)
			mdelay(1);
		if (--timeout == 0)
			return false;
	}

	return true;
}

static int aha1542_outb(unsigned int base, u8 val)
{
	if (!wait_mask(STATUS(base), CDF, 0, CDF, 0))
		return 1;
	outb(val, DATA(base));

	return 0;
}

static int aha1542_out(unsigned int base, u8 *buf, int len)
{
	while (len--) {
		if (!wait_mask(STATUS(base), CDF, 0, CDF, 0))
			return 1;
		outb(*buf++, DATA(base));
	}
	if (!wait_mask(INTRFLAGS(base), INTRMASK, HACC, 0, 0))
		return 1;

	return 0;
}

/* Only used at boot time, so we do not need to worry about latency as much
   here */

static int aha1542_in(unsigned int base, u8 *buf, int len, int timeout)
{
	while (len--) {
		if (!wait_mask(STATUS(base), DF, DF, 0, timeout))
			return 1;
		*buf++ = inb(DATA(base));
	}
	return 0;
}

static int makecode(unsigned hosterr, unsigned scsierr)
{
	switch (hosterr) {
	case 0x0:
	case 0xa:		/* Linked command complete without error and linked normally */
	case 0xb:		/* Linked command complete without error, interrupt generated */
		hosterr = 0;
		break;

	case 0x11:		/* Selection time out-The initiator selection or target
				   reselection was not complete within the SCSI Time out period */
		hosterr = DID_TIME_OUT;
		break;

	case 0x12:		/* Data overrun/underrun-The target attempted to transfer more data
				   than was allocated by the Data Length field or the sum of the
				   Scatter / Gather Data Length fields. */

	case 0x13:		/* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */

	case 0x15:		/* MBO command was not 00, 01 or 02-The first byte of the CB was
				   invalid. This usually indicates a software failure. */

	case 0x16:		/* Invalid CCB Operation Code-The first byte of the CCB was invalid.
				   This usually indicates a software failure. */

	case 0x17:		/* Linked CCB does not have the same LUN-A subsequent CCB of a set
				   of linked CCB's does not specify the same logical unit number as
				   the first. */
	case 0x18:		/* Invalid Target Direction received from Host-The direction of a
				   Target Mode CCB was invalid. */

	case 0x19:		/* Duplicate CCB Received in Target Mode-More than once CCB was
				   received to service data transfer between the same target LUN
				   and initiator SCSI ID in the same direction. */

	case 0x1a:		/* Invalid CCB or Segment List Parameter-A segment list with a zero
				   length segment or invalid segment list boundaries was received.
				   A CCB parameter was invalid. */
#ifdef DEBUG
		printk("Aha1542: %x %x\n", hosterr, scsierr);
#endif
		hosterr = DID_ERROR;	/* Couldn't find any better */
		break;

	case 0x14:		/* Target bus phase sequence failure-An invalid bus phase or bus
				   phase sequence was requested by the target. The host adapter
				   will generate a SCSI Reset Condition, notifying the host with
				   a SCRD interrupt */
		hosterr = DID_RESET;
		break;
	default:
		printk(KERN_ERR "aha1542: makecode: unknown hoststatus %x\n", hosterr);
		break;
	}
	return scsierr | (hosterr << 16);
}

static int aha1542_test_port(struct Scsi_Host *sh)
{
	u8 inquiry_result[4];
	int i;

	/* Quick and dirty test for presence of the card. */
	if (inb(STATUS(sh->io_port)) == 0xff)
		return 0;

	/* Reset the adapter. I ought to make a hard reset, but it's not really necessary */

	/* In case some other card was probing here, reset interrupts */
	aha1542_intr_reset(sh->io_port);	/* reset interrupts, so they don't block */

	outb(SRST | IRST /*|SCRST */ , CONTROL(sh->io_port));

	mdelay(20);		/* Wait a little bit for things to settle down. */

	/* Expect INIT and IDLE, any of the others are bad */
	if (!wait_mask(STATUS(sh->io_port), STATMASK, INIT | IDLE, STST | DIAGF | INVDCMD | DF | CDF, 0))
		return 0;

	/* Shouldn't have generated any interrupts during reset */
	if (inb(INTRFLAGS(sh->io_port)) & INTRMASK)
		return 0;

	/* Perform a host adapter inquiry instead so we do not need to set
	   up the mailboxes ahead of time */

	aha1542_outb(sh->io_port, CMD_INQUIRY);

	for (i = 0; i < 4; i++) {
		if (!wait_mask(STATUS(sh->io_port), DF, DF, 0, 0))
			return 0;
		inquiry_result[i] = inb(DATA(sh->io_port));
	}

	/* Reading port should reset DF */
	if (inb(STATUS(sh->io_port)) & DF)
		return 0;

	/* When HACC, command is completed, and we're though testing */
	if (!wait_mask(INTRFLAGS(sh->io_port), HACC, HACC, 0, 0))
		return 0;

	/* Clear interrupts */
	outb(IRST, CONTROL(sh->io_port));

	return 1;
}

static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
{
	struct Scsi_Host *sh = dev_id;
	struct aha1542_hostdata *aha1542 = shost_priv(sh);
	void (*my_done)(struct scsi_cmnd *) = NULL;
	int errstatus, mbi, mbo, mbistatus;
	int number_serviced;
	unsigned long flags;
	struct scsi_cmnd *tmp_cmd;
	int flag;
	struct mailbox *mb = aha1542->mb;
	struct ccb *ccb = aha1542->ccb;

#ifdef DEBUG
	{
		flag = inb(INTRFLAGS(sh->io_port));
		shost_printk(KERN_DEBUG, sh, "aha1542_intr_handle: ");
		if (!(flag & ANYINTR))
			printk("no interrupt?");
		if (flag & MBIF)
			printk("MBIF ");
		if (flag & MBOA)
			printk("MBOF ");
		if (flag & HACC)
			printk("HACC ");
		if (flag & SCRD)
			printk("SCRD ");
		printk("status %02x\n", inb(STATUS(sh->io_port)));
	};
#endif
	number_serviced = 0;

	spin_lock_irqsave(sh->host_lock, flags);
	while (1) {
		flag = inb(INTRFLAGS(sh->io_port));

		/* Check for unusual interrupts.  If any of these happen, we should
		   probably do something special, but for now just printing a message
		   is sufficient.  A SCSI reset detected is something that we really
		   need to deal with in some way. */
		if (flag & ~MBIF) {
			if (flag & MBOA)
				printk("MBOF ");
			if (flag & HACC)
				printk("HACC ");
			if (flag & SCRD)
				printk("SCRD ");
		}
		aha1542_intr_reset(sh->io_port);

		mbi = aha1542->aha1542_last_mbi_used + 1;
		if (mbi >= 2 * AHA1542_MAILBOXES)
			mbi = AHA1542_MAILBOXES;

		do {
			if (mb[mbi].status != 0)
				break;
			mbi++;
			if (mbi >= 2 * AHA1542_MAILBOXES)
				mbi = AHA1542_MAILBOXES;
		} while (mbi != aha1542->aha1542_last_mbi_used);

		if (mb[mbi].status == 0) {
			spin_unlock_irqrestore(sh->host_lock, flags);
			/* Hmm, no mail.  Must have read it the last time around */
			if (!number_serviced)
				shost_printk(KERN_WARNING, sh, "interrupt received, but no mail.\n");
			return IRQ_HANDLED;
		};

		mbo = (scsi2int(mb[mbi].ccbptr) - (isa_virt_to_bus(&ccb[0]))) / sizeof(struct ccb);
		mbistatus = mb[mbi].status;
		mb[mbi].status = 0;
		aha1542->aha1542_last_mbi_used = mbi;

#ifdef DEBUG
		if (ccb[mbo].tarstat | ccb[mbo].hastat)
			shost_printk(KERN_DEBUG, sh, "aha1542_command: returning %x (status %d)\n",
			       ccb[mbo].tarstat + ((int) ccb[mbo].hastat << 16), mb[mbi].status);
#endif

		if (mbistatus == 3)
			continue;	/* Aborted command not found */

#ifdef DEBUG
		shost_printk(KERN_DEBUG, sh, "...done %d %d\n", mbo, mbi);
#endif

		tmp_cmd = aha1542->int_cmds[mbo];

		if (!tmp_cmd || !tmp_cmd->scsi_done) {
			spin_unlock_irqrestore(sh->host_lock, flags);
			shost_printk(KERN_WARNING, sh, "Unexpected interrupt\n");
			shost_printk(KERN_WARNING, sh, "tarstat=%x, hastat=%x idlun=%x ccb#=%d\n", ccb[mbo].tarstat,
			       ccb[mbo].hastat, ccb[mbo].idlun, mbo);
			return IRQ_HANDLED;
		}
		my_done = tmp_cmd->scsi_done;
		kfree(tmp_cmd->host_scribble);
		tmp_cmd->host_scribble = NULL;
		/* Fetch the sense data, and tuck it away, in the required slot.  The
		   Adaptec automatically fetches it, and there is no guarantee that
		   we will still have it in the cdb when we come back */
		if (ccb[mbo].tarstat == 2)
			memcpy(tmp_cmd->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen],
			       SCSI_SENSE_BUFFERSIZE);


		/* is there mail :-) */

		/* more error checking left out here */
		if (mbistatus != 1)
			/* This is surely wrong, but I don't know what's right */
			errstatus = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
		else
			errstatus = 0;

#ifdef DEBUG
		if (errstatus)
			shost_printk(KERN_DEBUG, sh, "(aha1542 error:%x %x %x) ", errstatus,
			       ccb[mbo].hastat, ccb[mbo].tarstat);
		if (ccb[mbo].tarstat == 2)
			print_hex_dump_bytes("sense: ", DUMP_PREFIX_NONE, &ccb[mbo].cdb[ccb[mbo].cdblen], 12);
		if (errstatus)
			printk("aha1542_intr_handle: returning %6x\n", errstatus);
#endif
		tmp_cmd->result = errstatus;
		aha1542->int_cmds[mbo] = NULL;	/* This effectively frees up the mailbox slot, as
						   far as queuecommand is concerned */
		my_done(tmp_cmd);
		number_serviced++;
	};
}

static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
{
	struct aha1542_hostdata *aha1542 = shost_priv(sh);
	u8 direction;
	u8 target = cmd->device->id;
	u8 lun = cmd->device->lun;
	unsigned long flags;
	int bufflen = scsi_bufflen(cmd);
	int mbo, sg_count;
	struct mailbox *mb = aha1542->mb;
	struct ccb *ccb = aha1542->ccb;
	struct chain *cptr;

	if (*cmd->cmnd == REQUEST_SENSE) {
		/* Don't do the command - we have the sense data already */
		cmd->result = 0;
		cmd->scsi_done(cmd);
		return 0;
	}
#ifdef DEBUG
	{
		int i = -1;
		if (*cmd->cmnd == READ_10 || *cmd->cmnd == WRITE_10)
			i = xscsi2int(cmd->cmnd + 2);
		else if (*cmd->cmnd == READ_6 || *cmd->cmnd == WRITE_6)
			i = scsi2int(cmd->cmnd + 2);
		shost_printk(KERN_DEBUG, sh, "aha1542_queuecommand: dev %d cmd %02x pos %d len %d",
						target, *cmd->cmnd, i, bufflen);
		print_hex_dump_bytes("command: ", DUMP_PREFIX_NONE, cmd->cmnd, cmd->cmd_len);
	}
#endif
	if (bufflen) {	/* allocate memory before taking host_lock */
		sg_count = scsi_sg_count(cmd);
		cptr = kmalloc(sizeof(*cptr) * sg_count, GFP_KERNEL | GFP_DMA);
		if (!cptr)
			return SCSI_MLQUEUE_HOST_BUSY;
	} else {
		sg_count = 0;
		cptr = NULL;
	}

	/* Use the outgoing mailboxes in a round-robin fashion, because this
	   is how the host adapter will scan for them */

	spin_lock_irqsave(sh->host_lock, flags);
	mbo = aha1542->aha1542_last_mbo_used + 1;
	if (mbo >= AHA1542_MAILBOXES)
		mbo = 0;

	do {
		if (mb[mbo].status == 0 && aha1542->int_cmds[mbo] == NULL)
			break;
		mbo++;
		if (mbo >= AHA1542_MAILBOXES)
			mbo = 0;
	} while (mbo != aha1542->aha1542_last_mbo_used);

	if (mb[mbo].status || aha1542->int_cmds[mbo])
		panic("Unable to find empty mailbox for aha1542.\n");

	aha1542->int_cmds[mbo] = cmd;	/* This will effectively prevent someone else from
					   screwing with this cdb. */

	aha1542->aha1542_last_mbo_used = mbo;

#ifdef DEBUG
	shost_printk(KERN_DEBUG, sh, "Sending command (%d %p)...", mbo, cmd->scsi_done);
#endif

	any2scsi(mb[mbo].ccbptr, isa_virt_to_bus(&ccb[mbo]));	/* This gets trashed for some reason */

	memset(&ccb[mbo], 0, sizeof(struct ccb));

	ccb[mbo].cdblen = cmd->cmd_len;

	direction = 0;
	if (*cmd->cmnd == READ_10 || *cmd->cmnd == READ_6)
		direction = 8;
	else if (*cmd->cmnd == WRITE_10 || *cmd->cmnd == WRITE_6)
		direction = 16;

	memcpy(ccb[mbo].cdb, cmd->cmnd, ccb[mbo].cdblen);

	if (bufflen) {
		struct scatterlist *sg;
		int i;

		ccb[mbo].op = 2;	/* SCSI Initiator Command  w/scatter-gather */
		cmd->host_scribble = (void *)cptr;
		scsi_for_each_sg(cmd, sg, sg_count, i) {
			any2scsi(cptr[i].dataptr, isa_page_to_bus(sg_page(sg))
								+ sg->offset);
			any2scsi(cptr[i].datalen, sg->length);
		};
		any2scsi(ccb[mbo].datalen, sg_count * sizeof(struct chain));
		any2scsi(ccb[mbo].dataptr, isa_virt_to_bus(cptr));
#ifdef DEBUG
		shost_printk(KERN_DEBUG, sh, "cptr %p: ", cptr);
		print_hex_dump_bytes("cptr: ", DUMP_PREFIX_NONE, cptr, 18);
#endif
	} else {
		ccb[mbo].op = 0;	/* SCSI Initiator Command */
		cmd->host_scribble = NULL;
		any2scsi(ccb[mbo].datalen, 0);
		any2scsi(ccb[mbo].dataptr, 0);
	};
	ccb[mbo].idlun = (target & 7) << 5 | direction | (lun & 7);	/*SCSI Target Id */
	ccb[mbo].rsalen = 16;
	ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;
	ccb[mbo].commlinkid = 0;

#ifdef DEBUG
	print_hex_dump_bytes("sending: ", DUMP_PREFIX_NONE, &ccb[mbo], sizeof(ccb[mbo]) - 10);
	printk("aha1542_queuecommand: now waiting for interrupt ");
#endif
	mb[mbo].status = 1;
	aha1542_outb(cmd->device->host->io_port, CMD_START_SCSI);
	spin_unlock_irqrestore(sh->host_lock, flags);

	return 0;
}

/* Initialize mailboxes */
static void setup_mailboxes(struct Scsi_Host *sh)
{
	struct aha1542_hostdata *aha1542 = shost_priv(sh);
	int i;
	struct mailbox *mb = aha1542->mb;
	struct ccb *ccb = aha1542->ccb;

	u8 mb_cmd[5] = { CMD_MBINIT, AHA1542_MAILBOXES, 0, 0, 0};

	for (i = 0; i < AHA1542_MAILBOXES; i++) {
		mb[i].status = mb[AHA1542_MAILBOXES + i].status = 0;
		any2scsi(mb[i].ccbptr, isa_virt_to_bus(&ccb[i]));
	};
	aha1542_intr_reset(sh->io_port);	/* reset interrupts, so they don't block */
	any2scsi((mb_cmd + 2), isa_virt_to_bus(mb));
	if (aha1542_out(sh->io_port, mb_cmd, 5))
		shost_printk(KERN_ERR, sh, "failed setting up mailboxes\n");
	aha1542_intr_reset(sh->io_port);
}

static int aha1542_getconfig(struct Scsi_Host *sh)
{
	u8 inquiry_result[3];
	int i;
	i = inb(STATUS(sh->io_port));
	if (i & DF) {
		i = inb(DATA(sh->io_port));
	};
	aha1542_outb(sh->io_port, CMD_RETCONF);
	aha1542_in(sh->io_port, inquiry_result, 3, 0);
	if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 0))
		shost_printk(KERN_ERR, sh, "error querying board settings\n");
	aha1542_intr_reset(sh->io_port);
	switch (inquiry_result[0]) {
	case 0x80:
		sh->dma_channel = 7;
		break;
	case 0x40:
		sh->dma_channel = 6;
		break;
	case 0x20:
		sh->dma_channel = 5;
		break;
	case 0x01:
		sh->dma_channel = 0;
		break;
	case 0:
		/* This means that the adapter, although Adaptec 1542 compatible, doesn't use a DMA channel.
		   Currently only aware of the BusLogic BT-445S VL-Bus adapter which needs this. */
		sh->dma_channel = 0xFF;
		break;
	default:
		shost_printk(KERN_ERR, sh, "Unable to determine DMA channel.\n");
		return -1;
	};
	switch (inquiry_result[1]) {
	case 0x40:
		sh->irq = 15;
		break;
	case 0x20:
		sh->irq = 14;
		break;
	case 0x8:
		sh->irq = 12;
		break;
	case 0x4:
		sh->irq = 11;
		break;
	case 0x2:
		sh->irq = 10;
		break;
	case 0x1:
		sh->irq = 9;
		break;
	default:
		shost_printk(KERN_ERR, sh, "Unable to determine IRQ level.\n");
		return -1;
	};
	sh->this_id = inquiry_result[2] & 7;
	return 0;
}

/* This function should only be called for 1542C boards - we can detect
   the special firmware settings and unlock the board */

static int aha1542_mbenable(struct Scsi_Host *sh)
{
	static u8 mbenable_cmd[3];
	static u8 mbenable_result[2];
	int retval;

	retval = BIOS_TRANSLATION_6432;

	aha1542_outb(sh->io_port, CMD_EXTBIOS);
	if (aha1542_in(sh->io_port, mbenable_result, 2, 100))
		return retval;
	if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 100))
		goto fail;
	aha1542_intr_reset(sh->io_port);

	if ((mbenable_result[0] & 0x08) || mbenable_result[1]) {
		mbenable_cmd[0] = CMD_MBENABLE;
		mbenable_cmd[1] = 0;
		mbenable_cmd[2] = mbenable_result[1];

		if ((mbenable_result[0] & 0x08) && (mbenable_result[1] & 0x03))
			retval = BIOS_TRANSLATION_25563;

		if (aha1542_out(sh->io_port, mbenable_cmd, 3))
			goto fail;
	};
	while (0) {
fail:
		shost_printk(KERN_ERR, sh, "Mailbox init failed\n");
	}
	aha1542_intr_reset(sh->io_port);
	return retval;
}

/* Query the board to find out if it is a 1542 or a 1740, or whatever. */
static int aha1542_query(struct Scsi_Host *sh)
{
	struct aha1542_hostdata *aha1542 = shost_priv(sh);
	u8 inquiry_result[4];
	int i;
	i = inb(STATUS(sh->io_port));
	if (i & DF) {
		i = inb(DATA(sh->io_port));
	};
	aha1542_outb(sh->io_port, CMD_INQUIRY);
	aha1542_in(sh->io_port, inquiry_result, 4, 0);
	if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 0))
		shost_printk(KERN_ERR, sh, "error querying card type\n");
	aha1542_intr_reset(sh->io_port);

	aha1542->bios_translation = BIOS_TRANSLATION_6432;	/* Default case */

	/* For an AHA1740 series board, we ignore the board since there is a
	   hardware bug which can lead to wrong blocks being returned if the board
	   is operating in the 1542 emulation mode.  Since there is an extended mode
	   driver, we simply ignore the board and let the 1740 driver pick it up.
	 */

	if (inquiry_result[0] == 0x43) {
		shost_printk(KERN_INFO, sh, "Emulation mode not supported for AHA-1740 hardware, use aha1740 driver instead.\n");
		return 1;
	};

	/* Always call this - boards that do not support extended bios translation
	   will ignore the command, and we will set the proper default */

	aha1542->bios_translation = aha1542_mbenable(sh);

	return 0;
}

static u8 dma_speed_hw(int dma_speed)
{
	switch (dma_speed) {
	case 5:
		return 0x00;
	case 6:
		return 0x04;
	case 7:
		return 0x01;
	case 8:
		return 0x02;
	case 10:
		return 0x03;
	}

	return 0xff;	/* invalid */
}

/* Set the Bus on/off-times as not to ruin floppy performance */
static void aha1542_set_bus_times(struct Scsi_Host *sh, int bus_on, int bus_off, int dma_speed)
{
	if (bus_on > 0) {
		u8 oncmd[] = { CMD_BUSON_TIME, clamp(bus_on, 2, 15) };

		aha1542_intr_reset(sh->io_port);
		if (aha1542_out(sh->io_port, oncmd, 2))
			goto fail;
	}

	if (bus_off > 0) {
		u8 offcmd[] = { CMD_BUSOFF_TIME, clamp(bus_off, 1, 64) };

		aha1542_intr_reset(sh->io_port);
		if (aha1542_out(sh->io_port, offcmd, 2))
			goto fail;
	}

	if (dma_speed_hw(dma_speed) != 0xff) {
		u8 dmacmd[] = { CMD_DMASPEED, dma_speed_hw(dma_speed) };

		aha1542_intr_reset(sh->io_port);
		if (aha1542_out(sh->io_port, dmacmd, 2))
			goto fail;
	}
	aha1542_intr_reset(sh->io_port);
	return;
fail:
	shost_printk(KERN_ERR, sh, "setting bus on/off-time failed\n");
	aha1542_intr_reset(sh->io_port);
}

/* return non-zero on detection */
static struct Scsi_Host *aha1542_hw_init(struct scsi_host_template *tpnt, struct device *pdev, int indx)
{
	unsigned int base_io = io[indx];
	struct Scsi_Host *sh;
	struct aha1542_hostdata *aha1542;
	char dma_info[] = "no DMA";

	if (base_io == 0)
		return NULL;

	if (!request_region(base_io, AHA1542_REGION_SIZE, "aha1542"))
		return NULL;

	sh = scsi_host_alloc(tpnt, sizeof(struct aha1542_hostdata));
	if (!sh)
		goto release;
	aha1542 = shost_priv(sh);

	sh->unique_id = base_io;
	sh->io_port = base_io;
	sh->n_io_port = AHA1542_REGION_SIZE;
	aha1542->aha1542_last_mbi_used = 2 * AHA1542_MAILBOXES - 1;
	aha1542->aha1542_last_mbo_used = AHA1542_MAILBOXES - 1;

	if (!aha1542_test_port(sh))
		goto unregister;

	aha1542_set_bus_times(sh, bus_on[indx], bus_off[indx], dma_speed[indx]);
	if (aha1542_query(sh))
		goto unregister;
	if (aha1542_getconfig(sh) == -1)
		goto unregister;

	if (sh->dma_channel != 0xFF)
		snprintf(dma_info, sizeof(dma_info), "DMA %d", sh->dma_channel);
	shost_printk(KERN_INFO, sh, "Adaptec AHA-1542 (SCSI-ID %d) at IO 0x%x, IRQ %d, %s\n",
				sh->this_id, base_io, sh->irq, dma_info);
	if (aha1542->bios_translation == BIOS_TRANSLATION_25563)
		shost_printk(KERN_INFO, sh, "Using extended bios translation\n");

	setup_mailboxes(sh);

	if (request_irq(sh->irq, aha1542_interrupt, 0, "aha1542", sh)) {
		shost_printk(KERN_ERR, sh, "Unable to allocate IRQ.\n");
		goto unregister;
	}
	if (sh->dma_channel != 0xFF) {
		if (request_dma(sh->dma_channel, "aha1542")) {
			shost_printk(KERN_ERR, sh, "Unable to allocate DMA channel.\n");
			goto free_irq;
		}
		if (sh->dma_channel == 0 || sh->dma_channel >= 5) {
			set_dma_mode(sh->dma_channel, DMA_MODE_CASCADE);
			enable_dma(sh->dma_channel);
		}
	}

	if (scsi_add_host(sh, pdev))
		goto free_dma;

	scsi_scan_host(sh);

	return sh;
free_dma:
	if (sh->dma_channel != 0xff)
		free_dma(sh->dma_channel);
free_irq:
	free_irq(sh->irq, sh);
unregister:
	scsi_host_put(sh);
release:
	release_region(base_io, AHA1542_REGION_SIZE);

	return NULL;
}

static int aha1542_release(struct Scsi_Host *sh)
{
	scsi_remove_host(sh);
	if (sh->dma_channel != 0xff)
		free_dma(sh->dma_channel);
	if (sh->irq)
		free_irq(sh->irq, sh);
	if (sh->io_port && sh->n_io_port)
		release_region(sh->io_port, sh->n_io_port);
	scsi_host_put(sh);
	return 0;
}


/*
 * This is a device reset.  This is handled by sending a special command
 * to the device.
 */
static int aha1542_dev_reset(struct scsi_cmnd *cmd)
{
	struct Scsi_Host *sh = cmd->device->host;
	struct aha1542_hostdata *aha1542 = shost_priv(sh);
	unsigned long flags;
	struct mailbox *mb = aha1542->mb;
	u8 target = cmd->device->id;
	u8 lun = cmd->device->lun;
	int mbo;
	struct ccb *ccb = aha1542->ccb;

	spin_lock_irqsave(sh->host_lock, flags);
	mbo = aha1542->aha1542_last_mbo_used + 1;
	if (mbo >= AHA1542_MAILBOXES)
		mbo = 0;

	do {
		if (mb[mbo].status == 0 && aha1542->int_cmds[mbo] == NULL)
			break;
		mbo++;
		if (mbo >= AHA1542_MAILBOXES)
			mbo = 0;
	} while (mbo != aha1542->aha1542_last_mbo_used);

	if (mb[mbo].status || aha1542->int_cmds[mbo])
		panic("Unable to find empty mailbox for aha1542.\n");

	aha1542->int_cmds[mbo] = cmd;	/* This will effectively
					   prevent someone else from
					   screwing with this cdb. */

	aha1542->aha1542_last_mbo_used = mbo;

	any2scsi(mb[mbo].ccbptr, isa_virt_to_bus(&ccb[mbo]));	/* This gets trashed for some reason */

	memset(&ccb[mbo], 0, sizeof(struct ccb));

	ccb[mbo].op = 0x81;	/* BUS DEVICE RESET */

	ccb[mbo].idlun = (target & 7) << 5 | (lun & 7);		/*SCSI Target Id */

	ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;
	ccb[mbo].commlinkid = 0;

	/* 
	 * Now tell the 1542 to flush all pending commands for this 
	 * target 
	 */
	aha1542_outb(sh->io_port, CMD_START_SCSI);
	spin_unlock_irqrestore(sh->host_lock, flags);

	scmd_printk(KERN_WARNING, cmd,
		"Trying device reset for target\n");

	return SUCCESS;
}

static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
{
	struct Scsi_Host *sh = cmd->device->host;
	struct aha1542_hostdata *aha1542 = shost_priv(sh);
	unsigned long flags;
	int i;

	spin_lock_irqsave(sh->host_lock, flags);
	/* 
	 * This does a scsi reset for all devices on the bus.
	 * In principle, we could also reset the 1542 - should
	 * we do this?  Try this first, and we can add that later
	 * if it turns out to be useful.
	 */
	outb(reset_cmd, CONTROL(cmd->device->host->io_port));

	if (!wait_mask(STATUS(cmd->device->host->io_port),
	     STATMASK, IDLE, STST | DIAGF | INVDCMD | DF | CDF, 0)) {
		spin_unlock_irqrestore(sh->host_lock, flags);
		return FAILED;
	}

	/*
	 * We need to do this too before the 1542 can interact with
	 * us again after host reset.
	 */
	if (reset_cmd & HRST)
		setup_mailboxes(cmd->device->host);

	/*
	 * Now try to pick up the pieces.  For all pending commands,
	 * free any internal data structures, and basically clear things
	 * out.  We do not try and restart any commands or anything - 
	 * the strategy handler takes care of that crap.
	 */
	shost_printk(KERN_WARNING, cmd->device->host, "Sent BUS RESET to scsi host %d\n", cmd->device->host->host_no);

	for (i = 0; i < AHA1542_MAILBOXES; i++) {
		if (aha1542->int_cmds[i] != NULL) {
			struct scsi_cmnd *tmp_cmd;
			tmp_cmd = aha1542->int_cmds[i];

			if (tmp_cmd->device->soft_reset) {
				/*
				 * If this device implements the soft reset option,
				 * then it is still holding onto the command, and
				 * may yet complete it.  In this case, we don't
				 * flush the data.
				 */
				continue;
			}
			kfree(tmp_cmd->host_scribble);
			tmp_cmd->host_scribble = NULL;
			aha1542->int_cmds[i] = NULL;
			aha1542->mb[i].status = 0;
		}
	}

	spin_unlock_irqrestore(sh->host_lock, flags);
	return SUCCESS;
}

static int aha1542_bus_reset(struct scsi_cmnd *cmd)
{
	return aha1542_reset(cmd, SCRST);
}

static int aha1542_host_reset(struct scsi_cmnd *cmd)
{
	return aha1542_reset(cmd, HRST | SCRST);
}

static int aha1542_biosparam(struct scsi_device *sdev,
		struct block_device *bdev, sector_t capacity, int geom[])
{
	struct aha1542_hostdata *aha1542 = shost_priv(sdev->host);

	if (capacity >= 0x200000 &&
			aha1542->bios_translation == BIOS_TRANSLATION_25563) {
		/* Please verify that this is the same as what DOS returns */
		geom[0] = 255;	/* heads */
		geom[1] = 63;	/* sectors */
	} else {
		geom[0] = 64;	/* heads */
		geom[1] = 32;	/* sectors */
	}
	geom[2] = sector_div(capacity, geom[0] * geom[1]);	/* cylinders */

	return 0;
}
MODULE_LICENSE("GPL");

static struct scsi_host_template driver_template = {
	.module			= THIS_MODULE,
	.proc_name		= "aha1542",
	.name			= "Adaptec 1542",
	.queuecommand		= aha1542_queuecommand,
	.eh_device_reset_handler= aha1542_dev_reset,
	.eh_bus_reset_handler	= aha1542_bus_reset,
	.eh_host_reset_handler	= aha1542_host_reset,
	.bios_param		= aha1542_biosparam,
	.can_queue		= AHA1542_MAILBOXES, 
	.this_id		= 7,
	.sg_tablesize		= 16,
	.unchecked_isa_dma	= 1, 
	.use_clustering		= ENABLE_CLUSTERING,
};

static int aha1542_isa_match(struct device *pdev, unsigned int ndev)
{
	struct Scsi_Host *sh = aha1542_hw_init(&driver_template, pdev, ndev);

	if (!sh)
		return 0;

	dev_set_drvdata(pdev, sh);
	return 1;
}

static int aha1542_isa_remove(struct device *pdev,
				    unsigned int ndev)
{
	aha1542_release(dev_get_drvdata(pdev));
	dev_set_drvdata(pdev, NULL);
	return 0;
}

static struct isa_driver aha1542_isa_driver = {
	.match		= aha1542_isa_match,
	.remove		= aha1542_isa_remove,
	.driver		= {
		.name	= "aha1542"
	},
};
static int isa_registered;

#ifdef CONFIG_PNP
static struct pnp_device_id aha1542_pnp_ids[] = {
	{ .id = "ADP1542" },
	{ .id = "" }
};
MODULE_DEVICE_TABLE(pnp, aha1542_pnp_ids);

static int aha1542_pnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *id)
{
	int indx;
	struct Scsi_Host *sh;

	for (indx = 0; indx < ARRAY_SIZE(io); indx++) {
		if (io[indx])
			continue;

		if (pnp_activate_dev(pdev) < 0)
			continue;

		io[indx] = pnp_port_start(pdev, 0);

		/* The card can be queried for its DMA, we have
		   the DMA set up that is enough */

		dev_info(&pdev->dev, "ISAPnP found an AHA1535 at I/O 0x%03X", io[indx]);
	}

	sh = aha1542_hw_init(&driver_template, &pdev->dev, indx);
	if (!sh)
		return -ENODEV;

	pnp_set_drvdata(pdev, sh);
	return 0;
}

static void aha1542_pnp_remove(struct pnp_dev *pdev)
{
	aha1542_release(pnp_get_drvdata(pdev));
	pnp_set_drvdata(pdev, NULL);
}

static struct pnp_driver aha1542_pnp_driver = {
	.name		= "aha1542",
	.id_table	= aha1542_pnp_ids,
	.probe		= aha1542_pnp_probe,
	.remove		= aha1542_pnp_remove,
};
static int pnp_registered;
#endif /* CONFIG_PNP */

static int __init aha1542_init(void)
{
	int ret = 0;

#ifdef CONFIG_PNP
	if (isapnp) {
		ret = pnp_register_driver(&aha1542_pnp_driver);
		if (!ret)
			pnp_registered = 1;
	}
#endif
	ret = isa_register_driver(&aha1542_isa_driver, MAXBOARDS);
	if (!ret)
		isa_registered = 1;

#ifdef CONFIG_PNP
	if (pnp_registered)
		ret = 0;
#endif
	if (isa_registered)
		ret = 0;

	return ret;
}

static void __exit aha1542_exit(void)
{
#ifdef CONFIG_PNP
	if (pnp_registered)
		pnp_unregister_driver(&aha1542_pnp_driver);
#endif
	if (isa_registered)
		isa_unregister_driver(&aha1542_isa_driver);
}

module_init(aha1542_init);
module_exit(aha1542_exit);
