// SPDX-License-Identifier: GPL-2.0-only
/*
 *  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_hw_array(io, int, ioport, 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;
	dma_addr_t mb_handle;
	struct ccb *ccb;
	dma_addr_t ccb_handle;
};

#define AHA1542_MAX_SECTORS       16

struct aha1542_cmd {
	/* bounce buffer */
	void *data_buffer;
	dma_addr_t data_buffer_handle;
};

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 void aha1542_free_cmd(struct scsi_cmnd *cmd)
{
	struct aha1542_cmd *acmd = scsi_cmd_priv(cmd);

	if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
		struct request *rq = scsi_cmd_to_rq(cmd);
		void *buf = acmd->data_buffer;
		struct req_iterator iter;
		struct bio_vec bv;

		rq_for_each_segment(bv, rq, iter) {
			memcpy_to_page(bv.bv_page, bv.bv_offset, buf,
				       bv.bv_len);
			buf += bv.bv_len;
		}
	}

	scsi_dma_unmap(cmd);
}

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) - (unsigned long)aha1542->ccb_handle) / 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;
		aha1542_free_cmd(tmp_cmd);
		/*
		 * 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_cmd *acmd = scsi_cmd_priv(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;
	struct mailbox *mb = aha1542->mb;
	struct ccb *ccb = aha1542->ccb;

	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 (cmd->sc_data_direction == DMA_TO_DEVICE) {
		struct request *rq = scsi_cmd_to_rq(cmd);
		void *buf = acmd->data_buffer;
		struct req_iterator iter;
		struct bio_vec bv;

		rq_for_each_segment(bv, rq, iter) {
			memcpy_from_page(buf, bv.bv_page, bv.bv_offset,
					 bv.bv_len);
			buf += bv.bv_len;
		}
	}

	/*
	 * 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

	/* This gets trashed for some reason */
	any2scsi(mb[mbo].ccbptr, aha1542->ccb_handle + mbo * sizeof(*ccb));

	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);
	ccb[mbo].op = 0;	/* SCSI Initiator Command */
	any2scsi(ccb[mbo].datalen, bufflen);
	if (bufflen)
		any2scsi(ccb[mbo].dataptr, acmd->data_buffer_handle);
	else
		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);
	u8 mb_cmd[5] = { CMD_MBINIT, AHA1542_MAILBOXES, 0, 0, 0};
	int i;

	for (i = 0; i < AHA1542_MAILBOXES; i++) {
		aha1542->mb[i].status = 0;
		any2scsi(aha1542->mb[i].ccbptr,
			 aha1542->ccb_handle + i * sizeof(struct ccb));
		aha1542->mb[AHA1542_MAILBOXES + i].status = 0;
	};
	aha1542_intr_reset(sh->io_port);	/* reset interrupts, so they don't block */
	any2scsi(mb_cmd + 2, aha1542->mb_handle);
	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");

	if (dma_set_mask_and_coherent(pdev, DMA_BIT_MASK(24)) < 0)
		goto unregister;

	aha1542->mb = dma_alloc_coherent(pdev,
			AHA1542_MAILBOXES * 2 * sizeof(struct mailbox),
			&aha1542->mb_handle, GFP_KERNEL);
	if (!aha1542->mb)
		goto unregister;

	aha1542->ccb = dma_alloc_coherent(pdev,
			AHA1542_MAILBOXES * sizeof(struct ccb),
			&aha1542->ccb_handle, GFP_KERNEL);
	if (!aha1542->ccb)
		goto free_mb;

	setup_mailboxes(sh);

	if (request_irq(sh->irq, aha1542_interrupt, 0, "aha1542", sh)) {
		shost_printk(KERN_ERR, sh, "Unable to allocate IRQ.\n");
		goto free_ccb;
	}
	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);
free_ccb:
	dma_free_coherent(pdev, AHA1542_MAILBOXES * sizeof(struct ccb),
			  aha1542->ccb, aha1542->ccb_handle);
free_mb:
	dma_free_coherent(pdev, AHA1542_MAILBOXES * 2 * sizeof(struct mailbox),
			  aha1542->mb, aha1542->mb_handle);
unregister:
	scsi_host_put(sh);
release:
	release_region(base_io, AHA1542_REGION_SIZE);

	return NULL;
}

static int aha1542_release(struct Scsi_Host *sh)
{
	struct aha1542_hostdata *aha1542 = shost_priv(sh);
	struct device *dev = sh->dma_dev;

	scsi_remove_host(sh);
	if (sh->dma_channel != 0xff)
		free_dma(sh->dma_channel);
	dma_free_coherent(dev, AHA1542_MAILBOXES * sizeof(struct ccb),
			  aha1542->ccb, aha1542->ccb_handle);
	dma_free_coherent(dev, AHA1542_MAILBOXES * 2 * sizeof(struct mailbox),
			  aha1542->mb, aha1542->mb_handle);
	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;

	/* This gets trashed for some reason */
	any2scsi(mb[mbo].ccbptr, aha1542->ccb_handle + mbo * sizeof(*ccb));

	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;
			}
			aha1542_free_cmd(tmp_cmd);
			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 int aha1542_init_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
{
	struct aha1542_cmd *acmd = scsi_cmd_priv(cmd);

	acmd->data_buffer = dma_alloc_coherent(shost->dma_dev,
			SECTOR_SIZE * AHA1542_MAX_SECTORS,
			&acmd->data_buffer_handle, GFP_KERNEL);
	if (!acmd->data_buffer)
		return -ENOMEM;
	return 0;
}

static int aha1542_exit_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
{
	struct aha1542_cmd *acmd = scsi_cmd_priv(cmd);

	dma_free_coherent(shost->dma_dev, SECTOR_SIZE * AHA1542_MAX_SECTORS,
			acmd->data_buffer, acmd->data_buffer_handle);
	return 0;
}

static struct scsi_host_template driver_template = {
	.module			= THIS_MODULE,
	.proc_name		= "aha1542",
	.name			= "Adaptec 1542",
	.cmd_size		= sizeof(struct aha1542_cmd),
	.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,
	.init_cmd_priv		= aha1542_init_cmd_priv,
	.exit_cmd_priv		= aha1542_exit_cmd_priv,
	.can_queue		= AHA1542_MAILBOXES,
	.this_id		= 7,
	.max_sectors		= AHA1542_MAX_SECTORS,
	.sg_tablesize		= SG_ALL,
};

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 void aha1542_isa_remove(struct device *pdev,
				    unsigned int ndev)
{
	aha1542_release(dev_get_drvdata(pdev));
	dev_set_drvdata(pdev, NULL);
}

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