/*----------------------------------------------------------------*/
/*
   Qlogic linux driver - work in progress. No Warranty express or implied.
   Use at your own risk.  Support Tort Reform so you won't have to read all
   these silly disclaimers.

   Copyright 1994, Tom Zerucha.
   tz@execpc.com

   Additional Code, and much appreciated help by
   Michael A. Griffith
   grif@cs.ucr.edu

   Thanks to Eric Youngdale and Dave Hinds for loadable module and PCMCIA
   help respectively, and for suffering through my foolishness during the
   debugging process.

   Reference Qlogic FAS408 Technical Manual, 53408-510-00A, May 10, 1994
   (you can reference it, but it is incomplete and inaccurate in places)

   Version 0.46 1/30/97 - kernel 1.2.0+

   Functions as standalone, loadable, and PCMCIA driver, the latter from
   Dave Hinds' PCMCIA package.

   Cleaned up 26/10/2002 by Alan Cox <alan@lxorguk.ukuu.org.uk> as part of the 2.5
   SCSI driver cleanup and audit. This driver still needs work on the
   following
	-	Non terminating hardware waits
	-	Some layering violations with its pcmcia stub

   Redistributable under terms of the GNU General Public License

   For the avoidance of doubt the "preferred form" of this code is one which
   is in an open non patent encumbered format. Where cryptographic key signing
   forms part of the process of creating an executable the information
   including keys needed to generate an equivalently functional executable
   are deemed to be part of the source code.

*/

#include <linux/module.h>
#include <linux/blkdev.h>		/* to get disk capacity */
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/proc_fs.h>
#include <linux/unistd.h>
#include <linux/spinlock.h>
#include <linux/stat.h>

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

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

/*----------------------------------------------------------------*/
static int qlcfg5 = (XTALFREQ << 5);	/* 15625/512 */
static int qlcfg6 = SYNCXFRPD;
static int qlcfg7 = SYNCOFFST;
static int qlcfg8 = (SLOWCABLE << 7) | (QL_ENABLE_PARITY << 4);
static int qlcfg9 = ((XTALFREQ + 4) / 5);
static int qlcfgc = (FASTCLK << 3) | (FASTSCSI << 4);

/*----------------------------------------------------------------*/

/*----------------------------------------------------------------*/
/* local functions */
/*----------------------------------------------------------------*/

/* error recovery - reset everything */

static void ql_zap(struct qlogicfas408_priv *priv)
{
	int x;
	int qbase = priv->qbase;
	int int_type = priv->int_type;

	x = inb(qbase + 0xd);
	REG0;
	outb(3, qbase + 3);	/* reset SCSI */
	outb(2, qbase + 3);	/* reset chip */
	if (x & 0x80)
		REG1;
}

/*
 *	Do a pseudo-dma tranfer
 */

static int ql_pdma(struct qlogicfas408_priv *priv, int phase, char *request,
		   int reqlen)
{
	int j;
	int qbase = priv->qbase;
	j = 0;
	if (phase & 1) {	/* in */
#if QL_TURBO_PDMA
		rtrc(4)
		/* empty fifo in large chunks */
		if (reqlen >= 128 && (inb(qbase + 8) & 2)) {	/* full */
			insl(qbase + 4, request, 32);
			reqlen -= 128;
			request += 128;
		}
		while (reqlen >= 84 && !(j & 0xc0))	/* 2/3 */
			if ((j = inb(qbase + 8)) & 4)
			{
				insl(qbase + 4, request, 21);
				reqlen -= 84;
				request += 84;
			}
		if (reqlen >= 44 && (inb(qbase + 8) & 8)) {	/* 1/3 */
			insl(qbase + 4, request, 11);
			reqlen -= 44;
			request += 44;
		}
#endif
		/* until both empty and int (or until reclen is 0) */
		rtrc(7)
		j = 0;
		while (reqlen && !((j & 0x10) && (j & 0xc0)))
		{
			/* while bytes to receive and not empty */
			j &= 0xc0;
			while (reqlen && !((j = inb(qbase + 8)) & 0x10))
			{
				*request++ = inb(qbase + 4);
				reqlen--;
			}
			if (j & 0x10)
				j = inb(qbase + 8);

		}
	} else {		/* out */
#if QL_TURBO_PDMA
		rtrc(4)
		if (reqlen >= 128 && inb(qbase + 8) & 0x10) {	/* empty */
			outsl(qbase + 4, request, 32);
			reqlen -= 128;
			request += 128;
		}
		while (reqlen >= 84 && !(j & 0xc0))	/* 1/3 */
			if (!((j = inb(qbase + 8)) & 8)) {
				outsl(qbase + 4, request, 21);
				reqlen -= 84;
				request += 84;
			}
		if (reqlen >= 40 && !(inb(qbase + 8) & 4)) {	/* 2/3 */
			outsl(qbase + 4, request, 10);
			reqlen -= 40;
			request += 40;
		}
#endif
		/* until full and int (or until reclen is 0) */
		rtrc(7)
		    j = 0;
		while (reqlen && !((j & 2) && (j & 0xc0))) {
			/* while bytes to send and not full */
			while (reqlen && !((j = inb(qbase + 8)) & 2))
			{
				outb(*request++, qbase + 4);
				reqlen--;
			}
			if (j & 2)
				j = inb(qbase + 8);
		}
	}
	/* maybe return reqlen */
	return inb(qbase + 8) & 0xc0;
}

/*
 *	Wait for interrupt flag (polled - not real hardware interrupt)
 */

static int ql_wai(struct qlogicfas408_priv *priv)
{
	int k;
	int qbase = priv->qbase;
	unsigned long i;

	k = 0;
	i = jiffies + WATCHDOG;
	while (time_before(jiffies, i) && !priv->qabort &&
					!((k = inb(qbase + 4)) & 0xe0)) {
		barrier();
		cpu_relax();
	}
	if (time_after_eq(jiffies, i))
		return (DID_TIME_OUT);
	if (priv->qabort)
		return (priv->qabort == 1 ? DID_ABORT : DID_RESET);
	if (k & 0x60)
		ql_zap(priv);
	if (k & 0x20)
		return (DID_PARITY);
	if (k & 0x40)
		return (DID_ERROR);
	return 0;
}

/*
 *	Initiate scsi command - queueing handler
 *	caller must hold host lock
 */

static void ql_icmd(struct scsi_cmnd *cmd)
{
	struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
	int	qbase = priv->qbase;
	int	int_type = priv->int_type;
	unsigned int i;

	priv->qabort = 0;

	REG0;
	/* clearing of interrupts and the fifo is needed */

	inb(qbase + 5);		/* clear interrupts */
	if (inb(qbase + 5))	/* if still interrupting */
		outb(2, qbase + 3);	/* reset chip */
	else if (inb(qbase + 7) & 0x1f)
		outb(1, qbase + 3);	/* clear fifo */
	while (inb(qbase + 5));	/* clear ints */
	REG1;
	outb(1, qbase + 8);	/* set for PIO pseudo DMA */
	outb(0, qbase + 0xb);	/* disable ints */
	inb(qbase + 8);		/* clear int bits */
	REG0;
	outb(0x40, qbase + 0xb);	/* enable features */

	/* configurables */
	outb(qlcfgc, qbase + 0xc);
	/* config: no reset interrupt, (initiator) bus id */
	outb(0x40 | qlcfg8 | priv->qinitid, qbase + 8);
	outb(qlcfg7, qbase + 7);
	outb(qlcfg6, qbase + 6);
	outb(qlcfg5, qbase + 5);	/* select timer */
	outb(qlcfg9 & 7, qbase + 9);	/* prescaler */
/*	outb(0x99, qbase + 5);	*/
	outb(scmd_id(cmd), qbase + 4);

	for (i = 0; i < cmd->cmd_len; i++)
		outb(cmd->cmnd[i], qbase + 2);

	priv->qlcmd = cmd;
	outb(0x41, qbase + 3);	/* select and send command */
}

/*
 *	Process scsi command - usually after interrupt
 */

static void ql_pcmd(struct scsi_cmnd *cmd)
{
	unsigned int i, j;
	unsigned long k;
	unsigned int status;	/* scsi returned status */
	unsigned int message;	/* scsi returned message */
	unsigned int phase;	/* recorded scsi phase */
	unsigned int reqlen;	/* total length of transfer */
	char *buf;
	struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
	int qbase = priv->qbase;
	int int_type = priv->int_type;

	rtrc(1)
	j = inb(qbase + 6);
	i = inb(qbase + 5);
	if (i == 0x20) {
		set_host_byte(cmd, DID_NO_CONNECT);
		return;
	}
	i |= inb(qbase + 5);	/* the 0x10 bit can be set after the 0x08 */
	if (i != 0x18) {
		printk(KERN_ERR "Ql:Bad Interrupt status:%02x\n", i);
		ql_zap(priv);
		set_host_byte(cmd, DID_BAD_INTR);
		return;
	}
	j &= 7;			/* j = inb( qbase + 7 ) >> 5; */

	/* correct status is supposed to be step 4 */
	/* it sometimes returns step 3 but with 0 bytes left to send */
	/* We can try stuffing the FIFO with the max each time, but we will get a
	   sequence of 3 if any bytes are left (but we do flush the FIFO anyway */

	if (j != 3 && j != 4) {
		printk(KERN_ERR "Ql:Bad sequence for command %d, int %02X, cmdleft = %d\n",
		     j, i, inb(qbase + 7) & 0x1f);
		ql_zap(priv);
		set_host_byte(cmd, DID_ERROR);
		return;
	}

	if (inb(qbase + 7) & 0x1f)	/* if some bytes in fifo */
		outb(1, qbase + 3);	/* clear fifo */
	/* note that request_bufflen is the total xfer size when sg is used */
	reqlen = scsi_bufflen(cmd);
	/* note that it won't work if transfers > 16M are requested */
	if (reqlen && !((phase = inb(qbase + 4)) & 6)) {	/* data phase */
		struct scatterlist *sg;
		rtrc(2)
		outb(reqlen, qbase);	/* low-mid xfer cnt */
		outb(reqlen >> 8, qbase + 1);	/* low-mid xfer cnt */
		outb(reqlen >> 16, qbase + 0xe);	/* high xfer cnt */
		outb(0x90, qbase + 3);	/* command do xfer */
		/* PIO pseudo DMA to buffer or sglist */
		REG1;

		scsi_for_each_sg(cmd, sg, scsi_sg_count(cmd), i) {
			if (priv->qabort) {
				REG0;
				set_host_byte(cmd,
					      priv->qabort == 1 ?
					      DID_ABORT : DID_RESET);
			}
			buf = sg_virt(sg);
			if (ql_pdma(priv, phase, buf, sg->length))
				break;
		}
		REG0;
		rtrc(2);
		/*
		 *	Wait for irq (split into second state of irq handler
		 *	if this can take time)
		 */
		if ((k = ql_wai(priv))) {
			set_host_byte(cmd, k);
			return;
		}
		k = inb(qbase + 5);	/* should be 0x10, bus service */
	}

	/*
	 *	Enter Status (and Message In) Phase
	 */

	k = jiffies + WATCHDOG;

	while (time_before(jiffies, k) && !priv->qabort &&
						!(inb(qbase + 4) & 6))
		cpu_relax();	/* wait for status phase */

	if (time_after_eq(jiffies, k)) {
		ql_zap(priv);
		set_host_byte(cmd, DID_TIME_OUT);
		return;
	}

	/* FIXME: timeout ?? */
	while (inb(qbase + 5))
		cpu_relax();	/* clear pending ints */

	if (priv->qabort) {
		set_host_byte(cmd,
			      priv->qabort == 1 ? DID_ABORT : DID_RESET);
		return;
	}

	outb(0x11, qbase + 3);	/* get status and message */
	if ((k = ql_wai(priv))) {
		set_host_byte(cmd, k);
		return;
	}
	i = inb(qbase + 5);	/* get chip irq stat */
	j = inb(qbase + 7) & 0x1f;	/* and bytes rec'd */
	status = inb(qbase + 2);
	message = inb(qbase + 2);

	/*
	 *	Should get function complete int if Status and message, else
	 *	bus serv if only status
	 */
	if (!((i == 8 && j == 2) || (i == 0x10 && j == 1))) {
		printk(KERN_ERR "Ql:Error during status phase, int=%02X, %d bytes recd\n", i, j);
		set_host_byte(cmd, DID_ERROR);
	}
	outb(0x12, qbase + 3);	/* done, disconnect */
	rtrc(1);
	if ((k = ql_wai(priv))) {
		set_host_byte(cmd, k);
		return;
	}

	/*
	 *	Should get bus service interrupt and disconnect interrupt
	 */

	i = inb(qbase + 5);	/* should be bus service */
	while (!priv->qabort && ((i & 0x20) != 0x20)) {
		barrier();
		cpu_relax();
		i |= inb(qbase + 5);
	}
	rtrc(0);

	if (priv->qabort) {
		set_host_byte(cmd,
			      priv->qabort == 1 ? DID_ABORT : DID_RESET);
		return;
	}

	set_host_byte(cmd, DID_OK);
	if (message != COMMAND_COMPLETE)
		scsi_msg_to_host_byte(cmd, message);
	set_status_byte(cmd, status);
	return;
}

/*
 *	Interrupt handler
 */

static void ql_ihandl(void *dev_id)
{
	struct scsi_cmnd *icmd;
	struct Scsi_Host *host = dev_id;
	struct qlogicfas408_priv *priv = get_priv_by_host(host);
	int qbase = priv->qbase;
	REG0;

	if (!(inb(qbase + 4) & 0x80))	/* false alarm? */
		return;

	if (priv->qlcmd == NULL) {	/* no command to process? */
		int i;
		i = 16;
		while (i-- && inb(qbase + 5));	/* maybe also ql_zap() */
		return;
	}
	icmd = priv->qlcmd;
	ql_pcmd(icmd);
	priv->qlcmd = NULL;
	/*
	 *	If result is CHECK CONDITION done calls qcommand to request
	 *	sense
	 */
	(icmd->scsi_done) (icmd);
}

irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id)
{
	unsigned long flags;
	struct Scsi_Host *host = dev_id;

	spin_lock_irqsave(host->host_lock, flags);
	ql_ihandl(dev_id);
	spin_unlock_irqrestore(host->host_lock, flags);
	return IRQ_HANDLED;
}

/*
 *	Queued command
 */

static int qlogicfas408_queuecommand_lck(struct scsi_cmnd *cmd,
			      void (*done) (struct scsi_cmnd *))
{
	struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);

	set_host_byte(cmd, DID_OK);
	set_status_byte(cmd, SAM_STAT_GOOD);
	if (scmd_id(cmd) == priv->qinitid) {
		set_host_byte(cmd, DID_BAD_TARGET);
		done(cmd);
		return 0;
	}

	cmd->scsi_done = done;
	/* wait for the last command's interrupt to finish */
	while (priv->qlcmd != NULL) {
		barrier();
		cpu_relax();
	}
	ql_icmd(cmd);
	return 0;
}

DEF_SCSI_QCMD(qlogicfas408_queuecommand)

/*
 *	Return bios parameters
 */

int qlogicfas408_biosparam(struct scsi_device *disk, struct block_device *dev,
			   sector_t capacity, int ip[])
{
/* This should mimic the DOS Qlogic driver's behavior exactly */
	ip[0] = 0x40;
	ip[1] = 0x20;
	ip[2] = (unsigned long) capacity / (ip[0] * ip[1]);
	if (ip[2] > 1024) {
		ip[0] = 0xff;
		ip[1] = 0x3f;
		ip[2] = (unsigned long) capacity / (ip[0] * ip[1]);
#if 0
		if (ip[2] > 1023)
			ip[2] = 1023;
#endif
	}
	return 0;
}

/*
 *	Abort a command in progress
 */

int qlogicfas408_abort(struct scsi_cmnd *cmd)
{
	struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
	priv->qabort = 1;
	ql_zap(priv);
	return SUCCESS;
}

/*
 *	Reset SCSI bus
 *	FIXME: This function is invoked with cmd = NULL directly by
 *	the PCMCIA qlogic_stub code. This wants fixing
 */

int qlogicfas408_host_reset(struct scsi_cmnd *cmd)
{
	struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
	unsigned long flags;

	priv->qabort = 2;

	spin_lock_irqsave(cmd->device->host->host_lock, flags);
	ql_zap(priv);
	spin_unlock_irqrestore(cmd->device->host->host_lock, flags);

	return SUCCESS;
}

/*
 *	Return info string
 */

const char *qlogicfas408_info(struct Scsi_Host *host)
{
	struct qlogicfas408_priv *priv = get_priv_by_host(host);
	return priv->qinfo;
}

/*
 *	Get type of chip
 */

int qlogicfas408_get_chip_type(int qbase, int int_type)
{
	REG1;
	return inb(qbase + 0xe) & 0xf8;
}

/*
 *	Perform initialization tasks
 */

void qlogicfas408_setup(int qbase, int id, int int_type)
{
	outb(1, qbase + 8);	/* set for PIO pseudo DMA */
	REG0;
	outb(0x40 | qlcfg8 | id, qbase + 8);	/* (ini) bus id, disable scsi rst */
	outb(qlcfg5, qbase + 5);	/* select timer */
	outb(qlcfg9, qbase + 9);	/* prescaler */

#if QL_RESET_AT_START
	outb(3, qbase + 3);

	REG1;
	/* FIXME: timeout */
	while (inb(qbase + 0xf) & 4)
		cpu_relax();

	REG0;
#endif
}

/*
 *	Checks if this is a QLogic FAS 408
 */

int qlogicfas408_detect(int qbase, int int_type)
{
	REG1;
	return (((inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7) &&
		((inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7));
}

/*
 *	Disable interrupts
 */

void qlogicfas408_disable_ints(struct qlogicfas408_priv *priv)
{
	int qbase = priv->qbase;
	int int_type = priv->int_type;

	REG1;
	outb(0, qbase + 0xb);	/* disable ints */
}

/*
 *	Init and exit functions
 */

static int __init qlogicfas408_init(void)
{
	return 0;
}

static void __exit qlogicfas408_exit(void)
{

}

MODULE_AUTHOR("Tom Zerucha, Michael Griffith");
MODULE_DESCRIPTION("Driver for the Qlogic FAS SCSI controllers");
MODULE_LICENSE("GPL");
module_init(qlogicfas408_init);
module_exit(qlogicfas408_exit);

EXPORT_SYMBOL(qlogicfas408_info);
EXPORT_SYMBOL(qlogicfas408_queuecommand);
EXPORT_SYMBOL(qlogicfas408_abort);
EXPORT_SYMBOL(qlogicfas408_host_reset);
EXPORT_SYMBOL(qlogicfas408_biosparam);
EXPORT_SYMBOL(qlogicfas408_ihandl);
EXPORT_SYMBOL(qlogicfas408_get_chip_type);
EXPORT_SYMBOL(qlogicfas408_setup);
EXPORT_SYMBOL(qlogicfas408_detect);
EXPORT_SYMBOL(qlogicfas408_disable_ints);

