/* ppa.c   --  low level driver for the IOMEGA PPA3 
 * parallel port SCSI host adapter.
 * 
 * (The PPA3 is the embedded controller in the ZIP drive.)
 * 
 * (c) 1995,1996 Grant R. Guenther, grant@torque.net,
 * under the terms of the GNU General Public License.
 * 
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/parport.h>
#include <linux/workqueue.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <asm/io.h>

#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>


static void ppa_reset_pulse(unsigned int base);

typedef struct {
	struct pardevice *dev;	/* Parport device entry         */
	int base;		/* Actual port address          */
	int mode;		/* Transfer mode                */
	struct scsi_cmnd *cur_cmd;	/* Current queued command       */
	struct delayed_work ppa_tq;	/* Polling interrupt stuff       */
	unsigned long jstart;	/* Jiffies at start             */
	unsigned long recon_tmo;	/* How many usecs to wait for reconnection (6th bit) */
	unsigned int failed:1;	/* Failure flag                 */
	unsigned wanted:1;	/* Parport sharing busy flag    */
	wait_queue_head_t *waiting;
	struct Scsi_Host *host;
	struct list_head list;
} ppa_struct;

#include  "ppa.h"

static inline ppa_struct *ppa_dev(struct Scsi_Host *host)
{
	return *(ppa_struct **)&host->hostdata;
}

static DEFINE_SPINLOCK(arbitration_lock);

static void got_it(ppa_struct *dev)
{
	dev->base = dev->dev->port->base;
	if (dev->cur_cmd)
		dev->cur_cmd->SCp.phase = 1;
	else
		wake_up(dev->waiting);
}

static void ppa_wakeup(void *ref)
{
	ppa_struct *dev = (ppa_struct *) ref;
	unsigned long flags;

	spin_lock_irqsave(&arbitration_lock, flags);
	if (dev->wanted) {
		parport_claim(dev->dev);
		got_it(dev);
		dev->wanted = 0;
	}
	spin_unlock_irqrestore(&arbitration_lock, flags);
	return;
}

static int ppa_pb_claim(ppa_struct *dev)
{
	unsigned long flags;
	int res = 1;
	spin_lock_irqsave(&arbitration_lock, flags);
	if (parport_claim(dev->dev) == 0) {
		got_it(dev);
		res = 0;
	}
	dev->wanted = res;
	spin_unlock_irqrestore(&arbitration_lock, flags);
	return res;
}

static void ppa_pb_dismiss(ppa_struct *dev)
{
	unsigned long flags;
	int wanted;
	spin_lock_irqsave(&arbitration_lock, flags);
	wanted = dev->wanted;
	dev->wanted = 0;
	spin_unlock_irqrestore(&arbitration_lock, flags);
	if (!wanted)
		parport_release(dev->dev);
}

static inline void ppa_pb_release(ppa_struct *dev)
{
	parport_release(dev->dev);
}

/*
 * Start of Chipset kludges
 */

/* This is to give the ppa driver a way to modify the timings (and other
 * parameters) by writing to the /proc/scsi/ppa/0 file.
 * Very simple method really... (To simple, no error checking :( )
 * Reason: Kernel hackers HATE having to unload and reload modules for
 * testing...
 * Also gives a method to use a script to obtain optimum timings (TODO)
 */

static inline int ppa_proc_write(ppa_struct *dev, char *buffer, int length)
{
	unsigned long x;

	if ((length > 5) && (strncmp(buffer, "mode=", 5) == 0)) {
		x = simple_strtoul(buffer + 5, NULL, 0);
		dev->mode = x;
		return length;
	}
	if ((length > 10) && (strncmp(buffer, "recon_tmo=", 10) == 0)) {
		x = simple_strtoul(buffer + 10, NULL, 0);
		dev->recon_tmo = x;
		printk(KERN_INFO "ppa: recon_tmo set to %ld\n", x);
		return length;
	}
	printk(KERN_WARNING "ppa /proc: invalid variable\n");
	return -EINVAL;
}

static int ppa_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout)
{
	int len = 0;
	ppa_struct *dev = ppa_dev(host);

	if (inout)
		return ppa_proc_write(dev, buffer, length);

	len += sprintf(buffer + len, "Version : %s\n", PPA_VERSION);
	len +=
	    sprintf(buffer + len, "Parport : %s\n",
		    dev->dev->port->name);
	len +=
	    sprintf(buffer + len, "Mode    : %s\n",
		    PPA_MODE_STRING[dev->mode]);
#if PPA_DEBUG > 0
	len +=
	    sprintf(buffer + len, "recon_tmo : %lu\n", dev->recon_tmo);
#endif

	/* Request for beyond end of buffer */
	if (offset > length)
		return 0;

	*start = buffer + offset;
	len -= offset;
	if (len > length)
		len = length;
	return len;
}

static int device_check(ppa_struct *dev);

#if PPA_DEBUG > 0
#define ppa_fail(x,y) printk("ppa: ppa_fail(%i) from %s at line %d\n",\
	   y, __FUNCTION__, __LINE__); ppa_fail_func(x,y);
static inline void ppa_fail_func(ppa_struct *dev, int error_code)
#else
static inline void ppa_fail(ppa_struct *dev, int error_code)
#endif
{
	/* If we fail a device then we trash status / message bytes */
	if (dev->cur_cmd) {
		dev->cur_cmd->result = error_code << 16;
		dev->failed = 1;
	}
}

/*
 * Wait for the high bit to be set.
 * 
 * In principle, this could be tied to an interrupt, but the adapter
 * doesn't appear to be designed to support interrupts.  We spin on
 * the 0x80 ready bit. 
 */
static unsigned char ppa_wait(ppa_struct *dev)
{
	int k;
	unsigned short ppb = dev->base;
	unsigned char r;

	k = PPA_SPIN_TMO;
	/* Wait for bit 6 and 7 - PJC */
	for (r = r_str(ppb); ((r & 0xc0) != 0xc0) && (k); k--) {
		udelay(1);
		r = r_str(ppb);
	}

	/*
	 * return some status information.
	 * Semantics: 0xc0 = ZIP wants more data
	 *            0xd0 = ZIP wants to send more data
	 *            0xe0 = ZIP is expecting SCSI command data
	 *            0xf0 = end of transfer, ZIP is sending status
	 */
	if (k)
		return (r & 0xf0);

	/* Counter expired - Time out occurred */
	ppa_fail(dev, DID_TIME_OUT);
	printk(KERN_WARNING "ppa timeout in ppa_wait\n");
	return 0;		/* command timed out */
}

/*
 * Clear EPP Timeout Bit 
 */
static inline void epp_reset(unsigned short ppb)
{
	int i;

	i = r_str(ppb);
	w_str(ppb, i);
	w_str(ppb, i & 0xfe);
}

/* 
 * Wait for empty ECP fifo (if we are in ECP fifo mode only)
 */
static inline void ecp_sync(ppa_struct *dev)
{
	int i, ppb_hi = dev->dev->port->base_hi;

	if (ppb_hi == 0)
		return;

	if ((r_ecr(ppb_hi) & 0xe0) == 0x60) {	/* mode 011 == ECP fifo mode */
		for (i = 0; i < 100; i++) {
			if (r_ecr(ppb_hi) & 0x01)
				return;
			udelay(5);
		}
		printk(KERN_WARNING "ppa: ECP sync failed as data still present in FIFO.\n");
	}
}

static int ppa_byte_out(unsigned short base, const char *buffer, int len)
{
	int i;

	for (i = len; i; i--) {
		w_dtr(base, *buffer++);
		w_ctr(base, 0xe);
		w_ctr(base, 0xc);
	}
	return 1;		/* All went well - we hope! */
}

static int ppa_byte_in(unsigned short base, char *buffer, int len)
{
	int i;

	for (i = len; i; i--) {
		*buffer++ = r_dtr(base);
		w_ctr(base, 0x27);
		w_ctr(base, 0x25);
	}
	return 1;		/* All went well - we hope! */
}

static int ppa_nibble_in(unsigned short base, char *buffer, int len)
{
	for (; len; len--) {
		unsigned char h;

		w_ctr(base, 0x4);
		h = r_str(base) & 0xf0;
		w_ctr(base, 0x6);
		*buffer++ = h | ((r_str(base) & 0xf0) >> 4);
	}
	return 1;		/* All went well - we hope! */
}

static int ppa_out(ppa_struct *dev, char *buffer, int len)
{
	int r;
	unsigned short ppb = dev->base;

	r = ppa_wait(dev);

	if ((r & 0x50) != 0x40) {
		ppa_fail(dev, DID_ERROR);
		return 0;
	}
	switch (dev->mode) {
	case PPA_NIBBLE:
	case PPA_PS2:
		/* 8 bit output, with a loop */
		r = ppa_byte_out(ppb, buffer, len);
		break;

	case PPA_EPP_32:
	case PPA_EPP_16:
	case PPA_EPP_8:
		epp_reset(ppb);
		w_ctr(ppb, 0x4);
#ifdef CONFIG_SCSI_IZIP_EPP16
		if (!(((long) buffer | len) & 0x01))
			outsw(ppb + 4, buffer, len >> 1);
#else
		if (!(((long) buffer | len) & 0x03))
			outsl(ppb + 4, buffer, len >> 2);
#endif
		else
			outsb(ppb + 4, buffer, len);
		w_ctr(ppb, 0xc);
		r = !(r_str(ppb) & 0x01);
		w_ctr(ppb, 0xc);
		ecp_sync(dev);
		break;

	default:
		printk(KERN_ERR "PPA: bug in ppa_out()\n");
		r = 0;
	}
	return r;
}

static int ppa_in(ppa_struct *dev, char *buffer, int len)
{
	int r;
	unsigned short ppb = dev->base;

	r = ppa_wait(dev);

	if ((r & 0x50) != 0x50) {
		ppa_fail(dev, DID_ERROR);
		return 0;
	}
	switch (dev->mode) {
	case PPA_NIBBLE:
		/* 4 bit input, with a loop */
		r = ppa_nibble_in(ppb, buffer, len);
		w_ctr(ppb, 0xc);
		break;

	case PPA_PS2:
		/* 8 bit input, with a loop */
		w_ctr(ppb, 0x25);
		r = ppa_byte_in(ppb, buffer, len);
		w_ctr(ppb, 0x4);
		w_ctr(ppb, 0xc);
		break;

	case PPA_EPP_32:
	case PPA_EPP_16:
	case PPA_EPP_8:
		epp_reset(ppb);
		w_ctr(ppb, 0x24);
#ifdef CONFIG_SCSI_IZIP_EPP16
		if (!(((long) buffer | len) & 0x01))
			insw(ppb + 4, buffer, len >> 1);
#else
		if (!(((long) buffer | len) & 0x03))
			insl(ppb + 4, buffer, len >> 2);
#endif
		else
			insb(ppb + 4, buffer, len);
		w_ctr(ppb, 0x2c);
		r = !(r_str(ppb) & 0x01);
		w_ctr(ppb, 0x2c);
		ecp_sync(dev);
		break;

	default:
		printk(KERN_ERR "PPA: bug in ppa_ins()\n");
		r = 0;
		break;
	}
	return r;
}

/* end of ppa_io.h */
static inline void ppa_d_pulse(unsigned short ppb, unsigned char b)
{
	w_dtr(ppb, b);
	w_ctr(ppb, 0xc);
	w_ctr(ppb, 0xe);
	w_ctr(ppb, 0xc);
	w_ctr(ppb, 0x4);
	w_ctr(ppb, 0xc);
}

static void ppa_disconnect(ppa_struct *dev)
{
	unsigned short ppb = dev->base;

	ppa_d_pulse(ppb, 0);
	ppa_d_pulse(ppb, 0x3c);
	ppa_d_pulse(ppb, 0x20);
	ppa_d_pulse(ppb, 0xf);
}

static inline void ppa_c_pulse(unsigned short ppb, unsigned char b)
{
	w_dtr(ppb, b);
	w_ctr(ppb, 0x4);
	w_ctr(ppb, 0x6);
	w_ctr(ppb, 0x4);
	w_ctr(ppb, 0xc);
}

static inline void ppa_connect(ppa_struct *dev, int flag)
{
	unsigned short ppb = dev->base;

	ppa_c_pulse(ppb, 0);
	ppa_c_pulse(ppb, 0x3c);
	ppa_c_pulse(ppb, 0x20);
	if ((flag == CONNECT_EPP_MAYBE) && IN_EPP_MODE(dev->mode))
		ppa_c_pulse(ppb, 0xcf);
	else
		ppa_c_pulse(ppb, 0x8f);
}

static int ppa_select(ppa_struct *dev, int target)
{
	int k;
	unsigned short ppb = dev->base;

	/*
	 * Bit 6 (0x40) is the device selected bit.
	 * First we must wait till the current device goes off line...
	 */
	k = PPA_SELECT_TMO;
	do {
		k--;
		udelay(1);
	} while ((r_str(ppb) & 0x40) && (k));
	if (!k)
		return 0;

	w_dtr(ppb, (1 << target));
	w_ctr(ppb, 0xe);
	w_ctr(ppb, 0xc);
	w_dtr(ppb, 0x80);	/* This is NOT the initator */
	w_ctr(ppb, 0x8);

	k = PPA_SELECT_TMO;
	do {
		k--;
		udelay(1);
	}
	while (!(r_str(ppb) & 0x40) && (k));
	if (!k)
		return 0;

	return 1;
}

/* 
 * This is based on a trace of what the Iomega DOS 'guest' driver does.
 * I've tried several different kinds of parallel ports with guest and
 * coded this to react in the same ways that it does.
 * 
 * The return value from this function is just a hint about where the
 * handshaking failed.
 * 
 */
static int ppa_init(ppa_struct *dev)
{
	int retv;
	unsigned short ppb = dev->base;

	ppa_disconnect(dev);
	ppa_connect(dev, CONNECT_NORMAL);

	retv = 2;		/* Failed */

	w_ctr(ppb, 0xe);
	if ((r_str(ppb) & 0x08) == 0x08)
		retv--;

	w_ctr(ppb, 0xc);
	if ((r_str(ppb) & 0x08) == 0x00)
		retv--;

	if (!retv)
		ppa_reset_pulse(ppb);
	udelay(1000);		/* Allow devices to settle down */
	ppa_disconnect(dev);
	udelay(1000);		/* Another delay to allow devices to settle */

	if (retv)
		return -EIO;

	return device_check(dev);
}

static inline int ppa_send_command(struct scsi_cmnd *cmd)
{
	ppa_struct *dev = ppa_dev(cmd->device->host);
	int k;

	w_ctr(dev->base, 0x0c);

	for (k = 0; k < cmd->cmd_len; k++)
		if (!ppa_out(dev, &cmd->cmnd[k], 1))
			return 0;
	return 1;
}

/*
 * The bulk flag enables some optimisations in the data transfer loops,
 * it should be true for any command that transfers data in integral
 * numbers of sectors.
 * 
 * The driver appears to remain stable if we speed up the parallel port
 * i/o in this function, but not elsewhere.
 */
static int ppa_completion(struct scsi_cmnd *cmd)
{
	/* Return codes:
	 * -1     Error
	 *  0     Told to schedule
	 *  1     Finished data transfer
	 */
	ppa_struct *dev = ppa_dev(cmd->device->host);
	unsigned short ppb = dev->base;
	unsigned long start_jiffies = jiffies;

	unsigned char r, v;
	int fast, bulk, status;

	v = cmd->cmnd[0];
	bulk = ((v == READ_6) ||
		(v == READ_10) || (v == WRITE_6) || (v == WRITE_10));

	/*
	 * We only get here if the drive is ready to comunicate,
	 * hence no need for a full ppa_wait.
	 */
	r = (r_str(ppb) & 0xf0);

	while (r != (unsigned char) 0xf0) {
		/*
		 * If we have been running for more than a full timer tick
		 * then take a rest.
		 */
		if (time_after(jiffies, start_jiffies + 1))
			return 0;

		if ((cmd->SCp.this_residual <= 0)) {
			ppa_fail(dev, DID_ERROR);
			return -1;	/* ERROR_RETURN */
		}

		/* On some hardware we have SCSI disconnected (6th bit low)
		 * for about 100usecs. It is too expensive to wait a 
		 * tick on every loop so we busy wait for no more than
		 * 500usecs to give the drive a chance first. We do not 
		 * change things for "normal" hardware since generally 
		 * the 6th bit is always high.
		 * This makes the CPU load higher on some hardware 
		 * but otherwise we can not get more than 50K/secs 
		 * on this problem hardware.
		 */
		if ((r & 0xc0) != 0xc0) {
			/* Wait for reconnection should be no more than 
			 * jiffy/2 = 5ms = 5000 loops
			 */
			unsigned long k = dev->recon_tmo;
			for (; k && ((r = (r_str(ppb) & 0xf0)) & 0xc0) != 0xc0;
			     k--)
				udelay(1);

			if (!k)
				return 0;
		}

		/* determine if we should use burst I/O */
		fast = (bulk && (cmd->SCp.this_residual >= PPA_BURST_SIZE))
		    ? PPA_BURST_SIZE : 1;

		if (r == (unsigned char) 0xc0)
			status = ppa_out(dev, cmd->SCp.ptr, fast);
		else
			status = ppa_in(dev, cmd->SCp.ptr, fast);

		cmd->SCp.ptr += fast;
		cmd->SCp.this_residual -= fast;

		if (!status) {
			ppa_fail(dev, DID_BUS_BUSY);
			return -1;	/* ERROR_RETURN */
		}
		if (cmd->SCp.buffer && !cmd->SCp.this_residual) {
			/* if scatter/gather, advance to the next segment */
			if (cmd->SCp.buffers_residual--) {
				cmd->SCp.buffer++;
				cmd->SCp.this_residual =
				    cmd->SCp.buffer->length;
				cmd->SCp.ptr =
				    page_address(cmd->SCp.buffer->page) +
				    cmd->SCp.buffer->offset;
			}
		}
		/* Now check to see if the drive is ready to comunicate */
		r = (r_str(ppb) & 0xf0);
		/* If not, drop back down to the scheduler and wait a timer tick */
		if (!(r & 0x80))
			return 0;
	}
	return 1;		/* FINISH_RETURN */
}

/*
 * Since the PPA itself doesn't generate interrupts, we use
 * the scheduler's task queue to generate a stream of call-backs and
 * complete the request when the drive is ready.
 */
static void ppa_interrupt(struct work_struct *work)
{
	ppa_struct *dev = container_of(work, ppa_struct, ppa_tq.work);
	struct scsi_cmnd *cmd = dev->cur_cmd;

	if (!cmd) {
		printk(KERN_ERR "PPA: bug in ppa_interrupt\n");
		return;
	}
	if (ppa_engine(dev, cmd)) {
		schedule_delayed_work(&dev->ppa_tq, 1);
		return;
	}
	/* Command must of completed hence it is safe to let go... */
#if PPA_DEBUG > 0
	switch ((cmd->result >> 16) & 0xff) {
	case DID_OK:
		break;
	case DID_NO_CONNECT:
		printk(KERN_DEBUG "ppa: no device at SCSI ID %i\n", cmd->device->target);
		break;
	case DID_BUS_BUSY:
		printk(KERN_DEBUG "ppa: BUS BUSY - EPP timeout detected\n");
		break;
	case DID_TIME_OUT:
		printk(KERN_DEBUG "ppa: unknown timeout\n");
		break;
	case DID_ABORT:
		printk(KERN_DEBUG "ppa: told to abort\n");
		break;
	case DID_PARITY:
		printk(KERN_DEBUG "ppa: parity error (???)\n");
		break;
	case DID_ERROR:
		printk(KERN_DEBUG "ppa: internal driver error\n");
		break;
	case DID_RESET:
		printk(KERN_DEBUG "ppa: told to reset device\n");
		break;
	case DID_BAD_INTR:
		printk(KERN_WARNING "ppa: bad interrupt (???)\n");
		break;
	default:
		printk(KERN_WARNING "ppa: bad return code (%02x)\n",
		       (cmd->result >> 16) & 0xff);
	}
#endif

	if (cmd->SCp.phase > 1)
		ppa_disconnect(dev);

	ppa_pb_dismiss(dev);

	dev->cur_cmd = NULL;

	cmd->scsi_done(cmd);
}

static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd)
{
	unsigned short ppb = dev->base;
	unsigned char l = 0, h = 0;
	int retv;

	/* First check for any errors that may of occurred
	 * Here we check for internal errors
	 */
	if (dev->failed)
		return 0;

	switch (cmd->SCp.phase) {
	case 0:		/* Phase 0 - Waiting for parport */
		if (time_after(jiffies, dev->jstart + HZ)) {
			/*
			 * We waited more than a second
			 * for parport to call us
			 */
			ppa_fail(dev, DID_BUS_BUSY);
			return 0;
		}
		return 1;	/* wait until ppa_wakeup claims parport */
	case 1:		/* Phase 1 - Connected */
		{		/* Perform a sanity check for cable unplugged */
			int retv = 2;	/* Failed */

			ppa_connect(dev, CONNECT_EPP_MAYBE);

			w_ctr(ppb, 0xe);
			if ((r_str(ppb) & 0x08) == 0x08)
				retv--;

			w_ctr(ppb, 0xc);
			if ((r_str(ppb) & 0x08) == 0x00)
				retv--;

			if (retv) {
				if (time_after(jiffies, dev->jstart + (1 * HZ))) {
					printk(KERN_ERR "ppa: Parallel port cable is unplugged.\n");
					ppa_fail(dev, DID_BUS_BUSY);
					return 0;
				} else {
					ppa_disconnect(dev);
					return 1;	/* Try again in a jiffy */
				}
			}
			cmd->SCp.phase++;
		}

	case 2:		/* Phase 2 - We are now talking to the scsi bus */
		if (!ppa_select(dev, scmd_id(cmd))) {
			ppa_fail(dev, DID_NO_CONNECT);
			return 0;
		}
		cmd->SCp.phase++;

	case 3:		/* Phase 3 - Ready to accept a command */
		w_ctr(ppb, 0x0c);
		if (!(r_str(ppb) & 0x80))
			return 1;

		if (!ppa_send_command(cmd))
			return 0;
		cmd->SCp.phase++;

	case 4:		/* Phase 4 - Setup scatter/gather buffers */
		if (cmd->use_sg) {
			/* if many buffers are available, start filling the first */
			cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
			cmd->SCp.this_residual = cmd->SCp.buffer->length;
			cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
			    cmd->SCp.buffer->offset;
		} else {
			/* else fill the only available buffer */
			cmd->SCp.buffer = NULL;
			cmd->SCp.this_residual = cmd->request_bufflen;
			cmd->SCp.ptr = cmd->request_buffer;
		}
		cmd->SCp.buffers_residual = cmd->use_sg - 1;
		cmd->SCp.phase++;

	case 5:		/* Phase 5 - Data transfer stage */
		w_ctr(ppb, 0x0c);
		if (!(r_str(ppb) & 0x80))
			return 1;

		retv = ppa_completion(cmd);
		if (retv == -1)
			return 0;
		if (retv == 0)
			return 1;
		cmd->SCp.phase++;

	case 6:		/* Phase 6 - Read status/message */
		cmd->result = DID_OK << 16;
		/* Check for data overrun */
		if (ppa_wait(dev) != (unsigned char) 0xf0) {
			ppa_fail(dev, DID_ERROR);
			return 0;
		}
		if (ppa_in(dev, &l, 1)) {	/* read status byte */
			/* Check for optional message byte */
			if (ppa_wait(dev) == (unsigned char) 0xf0)
				ppa_in(dev, &h, 1);
			cmd->result =
			    (DID_OK << 16) + (h << 8) + (l & STATUS_MASK);
		}
		return 0;	/* Finished */
		break;

	default:
		printk(KERN_ERR "ppa: Invalid scsi phase\n");
	}
	return 0;
}

static int ppa_queuecommand(struct scsi_cmnd *cmd,
		void (*done) (struct scsi_cmnd *))
{
	ppa_struct *dev = ppa_dev(cmd->device->host);

	if (dev->cur_cmd) {
		printk(KERN_ERR "PPA: bug in ppa_queuecommand\n");
		return 0;
	}
	dev->failed = 0;
	dev->jstart = jiffies;
	dev->cur_cmd = cmd;
	cmd->scsi_done = done;
	cmd->result = DID_ERROR << 16;	/* default return code */
	cmd->SCp.phase = 0;	/* bus free */

	schedule_delayed_work(&dev->ppa_tq, 0);

	ppa_pb_claim(dev);

	return 0;
}

/*
 * Apparently the disk->capacity attribute is off by 1 sector 
 * for all disk drives.  We add the one here, but it should really
 * be done in sd.c.  Even if it gets fixed there, this will still
 * work.
 */
static int ppa_biosparam(struct scsi_device *sdev, struct block_device *dev,
	      sector_t capacity, int ip[])
{
	ip[0] = 0x40;
	ip[1] = 0x20;
	ip[2] = ((unsigned long) capacity + 1) / (ip[0] * ip[1]);
	if (ip[2] > 1024) {
		ip[0] = 0xff;
		ip[1] = 0x3f;
		ip[2] = ((unsigned long) capacity + 1) / (ip[0] * ip[1]);
		if (ip[2] > 1023)
			ip[2] = 1023;
	}
	return 0;
}

static int ppa_abort(struct scsi_cmnd *cmd)
{
	ppa_struct *dev = ppa_dev(cmd->device->host);
	/*
	 * There is no method for aborting commands since Iomega
	 * have tied the SCSI_MESSAGE line high in the interface
	 */

	switch (cmd->SCp.phase) {
	case 0:		/* Do not have access to parport */
	case 1:		/* Have not connected to interface */
		dev->cur_cmd = NULL;	/* Forget the problem */
		return SUCCESS;
		break;
	default:		/* SCSI command sent, can not abort */
		return FAILED;
		break;
	}
}

static void ppa_reset_pulse(unsigned int base)
{
	w_dtr(base, 0x40);
	w_ctr(base, 0x8);
	udelay(30);
	w_ctr(base, 0xc);
}

static int ppa_reset(struct scsi_cmnd *cmd)
{
	ppa_struct *dev = ppa_dev(cmd->device->host);

	if (cmd->SCp.phase)
		ppa_disconnect(dev);
	dev->cur_cmd = NULL;	/* Forget the problem */

	ppa_connect(dev, CONNECT_NORMAL);
	ppa_reset_pulse(dev->base);
	mdelay(1);		/* device settle delay */
	ppa_disconnect(dev);
	mdelay(1);		/* device settle delay */
	return SUCCESS;
}

static int device_check(ppa_struct *dev)
{
	/* This routine looks for a device and then attempts to use EPP
	   to send a command. If all goes as planned then EPP is available. */

	static u8 cmd[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
	int loop, old_mode, status, k, ppb = dev->base;
	unsigned char l;

	old_mode = dev->mode;
	for (loop = 0; loop < 8; loop++) {
		/* Attempt to use EPP for Test Unit Ready */
		if ((ppb & 0x0007) == 0x0000)
			dev->mode = PPA_EPP_32;

second_pass:
		ppa_connect(dev, CONNECT_EPP_MAYBE);
		/* Select SCSI device */
		if (!ppa_select(dev, loop)) {
			ppa_disconnect(dev);
			continue;
		}
		printk(KERN_INFO "ppa: Found device at ID %i, Attempting to use %s\n",
		       loop, PPA_MODE_STRING[dev->mode]);

		/* Send SCSI command */
		status = 1;
		w_ctr(ppb, 0x0c);
		for (l = 0; (l < 6) && (status); l++)
			status = ppa_out(dev, cmd, 1);

		if (!status) {
			ppa_disconnect(dev);
			ppa_connect(dev, CONNECT_EPP_MAYBE);
			w_dtr(ppb, 0x40);
			w_ctr(ppb, 0x08);
			udelay(30);
			w_ctr(ppb, 0x0c);
			udelay(1000);
			ppa_disconnect(dev);
			udelay(1000);
			if (dev->mode == PPA_EPP_32) {
				dev->mode = old_mode;
				goto second_pass;
			}
			return -EIO;
		}
		w_ctr(ppb, 0x0c);
		k = 1000000;	/* 1 Second */
		do {
			l = r_str(ppb);
			k--;
			udelay(1);
		} while (!(l & 0x80) && (k));

		l &= 0xf0;

		if (l != 0xf0) {
			ppa_disconnect(dev);
			ppa_connect(dev, CONNECT_EPP_MAYBE);
			ppa_reset_pulse(ppb);
			udelay(1000);
			ppa_disconnect(dev);
			udelay(1000);
			if (dev->mode == PPA_EPP_32) {
				dev->mode = old_mode;
				goto second_pass;
			}
			return -EIO;
		}
		ppa_disconnect(dev);
		printk(KERN_INFO "ppa: Communication established with ID %i using %s\n",
		       loop, PPA_MODE_STRING[dev->mode]);
		ppa_connect(dev, CONNECT_EPP_MAYBE);
		ppa_reset_pulse(ppb);
		udelay(1000);
		ppa_disconnect(dev);
		udelay(1000);
		return 0;
	}
	return -ENODEV;
}

static int ppa_adjust_queue(struct scsi_device *device)
{
	blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH);
	return 0;
}

static struct scsi_host_template ppa_template = {
	.module			= THIS_MODULE,
	.proc_name		= "ppa",
	.proc_info		= ppa_proc_info,
	.name			= "Iomega VPI0 (ppa) interface",
	.queuecommand		= ppa_queuecommand,
	.eh_abort_handler	= ppa_abort,
	.eh_bus_reset_handler	= ppa_reset,
	.eh_host_reset_handler	= ppa_reset,
	.bios_param		= ppa_biosparam,
	.this_id		= -1,
	.sg_tablesize		= SG_ALL,
	.cmd_per_lun		= 1,
	.use_clustering		= ENABLE_CLUSTERING,
	.can_queue		= 1,
	.slave_alloc		= ppa_adjust_queue,
};

/***************************************************************************
 *                   Parallel port probing routines                        *
 ***************************************************************************/

static LIST_HEAD(ppa_hosts);

static int __ppa_attach(struct parport *pb)
{
	struct Scsi_Host *host;
	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting);
	DEFINE_WAIT(wait);
	ppa_struct *dev;
	int ports;
	int modes, ppb, ppb_hi;
	int err = -ENOMEM;

	dev = kzalloc(sizeof(ppa_struct), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;
	dev->base = -1;
	dev->mode = PPA_AUTODETECT;
	dev->recon_tmo = PPA_RECON_TMO;
	init_waitqueue_head(&waiting);
	dev->dev = parport_register_device(pb, "ppa", NULL, ppa_wakeup,
					    NULL, 0, dev);

	if (!dev->dev)
		goto out;

	/* Claim the bus so it remembers what we do to the control
	 * registers. [ CTR and ECP ]
	 */
	err = -EBUSY;
	dev->waiting = &waiting;
	prepare_to_wait(&waiting, &wait, TASK_UNINTERRUPTIBLE);
	if (ppa_pb_claim(dev))
		schedule_timeout(3 * HZ);
	if (dev->wanted) {
		printk(KERN_ERR "ppa%d: failed to claim parport because "
				"a pardevice is owning the port for too long "
				"time!\n", pb->number);
		ppa_pb_dismiss(dev);
		dev->waiting = NULL;
		finish_wait(&waiting, &wait);
		goto out1;
	}
	dev->waiting = NULL;
	finish_wait(&waiting, &wait);
	ppb = dev->base = dev->dev->port->base;
	ppb_hi = dev->dev->port->base_hi;
	w_ctr(ppb, 0x0c);
	modes = dev->dev->port->modes;

	/* Mode detection works up the chain of speed
	 * This avoids a nasty if-then-else-if-... tree
	 */
	dev->mode = PPA_NIBBLE;

	if (modes & PARPORT_MODE_TRISTATE)
		dev->mode = PPA_PS2;

	if (modes & PARPORT_MODE_ECP) {
		w_ecr(ppb_hi, 0x20);
		dev->mode = PPA_PS2;
	}
	if ((modes & PARPORT_MODE_EPP) && (modes & PARPORT_MODE_ECP))
		w_ecr(ppb_hi, 0x80);

	/* Done configuration */

	err = ppa_init(dev);
	ppa_pb_release(dev);

	if (err)
		goto out1;

	/* now the glue ... */
	if (dev->mode == PPA_NIBBLE || dev->mode == PPA_PS2)
		ports = 3;
	else
		ports = 8;

	INIT_DELAYED_WORK(&dev->ppa_tq, ppa_interrupt);

	err = -ENOMEM;
	host = scsi_host_alloc(&ppa_template, sizeof(ppa_struct *));
	if (!host)
		goto out1;
	host->io_port = pb->base;
	host->n_io_port = ports;
	host->dma_channel = -1;
	host->unique_id = pb->number;
	*(ppa_struct **)&host->hostdata = dev;
	dev->host = host;
	list_add_tail(&dev->list, &ppa_hosts);
	err = scsi_add_host(host, NULL);
	if (err)
		goto out2;
	scsi_scan_host(host);
	return 0;
out2:
	list_del_init(&dev->list);
	scsi_host_put(host);
out1:
	parport_unregister_device(dev->dev);
out:
	kfree(dev);
	return err;
}

static void ppa_attach(struct parport *pb)
{
	__ppa_attach(pb);
}

static void ppa_detach(struct parport *pb)
{
	ppa_struct *dev;
	list_for_each_entry(dev, &ppa_hosts, list) {
		if (dev->dev->port == pb) {
			list_del_init(&dev->list);
			scsi_remove_host(dev->host);
			scsi_host_put(dev->host);
			parport_unregister_device(dev->dev);
			kfree(dev);
			break;
		}
	}
}

static struct parport_driver ppa_driver = {
	.name	= "ppa",
	.attach	= ppa_attach,
	.detach	= ppa_detach,
};

static int __init ppa_driver_init(void)
{
	printk(KERN_INFO "ppa: Version %s\n", PPA_VERSION);
	return parport_register_driver(&ppa_driver);
}

static void __exit ppa_driver_exit(void)
{
	parport_unregister_driver(&ppa_driver);
}

module_init(ppa_driver_init);
module_exit(ppa_driver_exit);
MODULE_LICENSE("GPL");
