/*----------------------------------------------------------------*/
/*
   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@redhat.com> 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(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(cmd->device->id, 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(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 */
	struct scatterlist *sglist;	/* scatter-gather list pointer */
	unsigned int sgcount;	/* sg counter */
	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 = cmd->request_bufflen;
	/* note that it won't work if transfers > 16M are requested */
	if (reqlen && !((phase = inb(qbase + 4)) & 6)) {	/* data phase */
		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;
		if (!cmd->use_sg)
			ql_pdma(priv, phase, cmd->request_buffer,
				cmd->request_bufflen);
		else {
			sgcount = cmd->use_sg;
			sglist = cmd->request_buffer;
			while (sgcount--) {
				if (priv->qabort) {
					REG0;
					return ((priv->qabort == 1 ?
						DID_ABORT : DID_RESET) << 16);
				}
				buf = page_address(sglist->page) + sglist->offset;
				if (ql_pdma(priv, phase, buf, sglist->length))
					break;
				sglist++;
			}
		}
		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(int irq, void *dev_id, struct pt_regs *regs)
{
	Scsi_Cmnd *icmd;
	struct Scsi_Host *host = (struct Scsi_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, struct pt_regs *regs)
{
	unsigned long flags;
	struct Scsi_Host *host = dev_id;

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

/*
 *	Queued command
 */

int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
{
	struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
	if (cmd->device->id == 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;
}

/* 
 *	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(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_bus_reset(Scsi_Cmnd * cmd)
{
	struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
	priv->qabort = 2;
	ql_zap(priv);
	return SUCCESS;
}

/* 
 *	Reset SCSI host controller
 */

int qlogicfas408_host_reset(Scsi_Cmnd * cmd)
{
	return FAILED;
}

/* 
 *	Reset SCSI device
 */

int qlogicfas408_device_reset(Scsi_Cmnd * cmd)
{
	return FAILED;
}

/*
 *	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_bus_reset);
EXPORT_SYMBOL(qlogicfas408_device_reset);
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);

