/*----------------------------------------------------------------*/
/*
   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 unsigned int ql_pcmd(struct scsi_cmnd *cmd)
{
	unsigned int i, j;
	unsigned long k;
	unsigned int result;	/* ultimate return result */
	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) {
		return (DID_NO_CONNECT << 16);
	}
	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);
		return (DID_BAD_INTR << 16);
	}
	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);
		return (DID_ERROR << 16);
	}
	result = DID_OK;
	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;
				return ((priv->qabort == 1 ?
					 DID_ABORT : DID_RESET) << 16);
			}
			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)))
			return (k << 16);
		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);
		return (DID_TIME_OUT << 16);
	}

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

	if (priv->qabort)
		return ((priv->qabort == 1 ? DID_ABORT : DID_RESET) << 16);

	outb(0x11, qbase + 3);	/* get status and message */
	if ((k = ql_wai(priv)))
		return (k << 16);
	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);
		result = DID_ERROR;
	}
	outb(0x12, qbase + 3);	/* done, disconnect */
	rtrc(1)
	if ((k = ql_wai(priv)))
		return (k << 16);

	/*
	 *	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)
		return ((priv->qabort == 1 ? DID_ABORT : DID_RESET) << 16);
		
	return (result << 16) | (message << 8) | (status & STATUS_MASK);
}

/*
 *	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;
	icmd->result = 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);
	if (scmd_id(cmd) == priv->qinitid) {
		cmd->result = DID_BAD_TARGET << 16;
		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);

