diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
new file mode 100644
index 0000000..96b4522
--- /dev/null
+++ b/drivers/scsi/ppa.c
@@ -0,0 +1,1150 @@
+/* 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.
+ * 
+ * Current Maintainer: David Campbell (Perth, Western Australia, GMT+0800)
+ *                     campbell@torque.net
+ */
+
+#include <linux/config.h>
+#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 <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 work_struct 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("ppa: recon_tmo set to %ld\n", x);
+		return length;
+	}
+	printk("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("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("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("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("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(void *data)
+{
+	ppa_struct *dev = (ppa_struct *) data;
+	struct scsi_cmnd *cmd = dev->cur_cmd;
+
+	if (!cmd) {
+		printk("PPA: bug in ppa_interrupt\n");
+		return;
+	}
+	if (ppa_engine(dev, cmd)) {
+		dev->ppa_tq.data = (void *) dev;
+		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("ppa: no device at SCSI ID %i\n", cmd->device->target);
+		break;
+	case DID_BUS_BUSY:
+		printk("ppa: BUS BUSY - EPP timeout detected\n");
+		break;
+	case DID_TIME_OUT:
+		printk("ppa: unknown timeout\n");
+		break;
+	case DID_ABORT:
+		printk("ppa: told to abort\n");
+		break;
+	case DID_PARITY:
+		printk("ppa: parity error (???)\n");
+		break;
+	case DID_ERROR:
+		printk("ppa: internal driver error\n");
+		break;
+	case DID_RESET:
+		printk("ppa: told to reset device\n");
+		break;
+	case DID_BAD_INTR:
+		printk("ppa: bad interrupt (???)\n");
+		break;
+	default:
+		printk("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 ((jiffies - dev->jstart) > (1 * HZ)) {
+					printk
+					    ("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, cmd->device->id)) {
+			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("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("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 */
+
+	dev->ppa_tq.data = dev;
+	schedule_work(&dev->ppa_tq);
+
+	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);
+	udelay(1000);		/* device settle delay */
+	ppa_disconnect(dev);
+	udelay(1000);		/* 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 char 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("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("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 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,
+};
+
+/***************************************************************************
+ *                   Parallel port probing routines                        *
+ ***************************************************************************/
+
+static LIST_HEAD(ppa_hosts);
+
+static int __ppa_attach(struct parport *pb)
+{
+	struct Scsi_Host *host;
+	DECLARE_WAIT_QUEUE_HEAD(waiting);
+	DEFINE_WAIT(wait);
+	ppa_struct *dev;
+	int ports;
+	int modes, ppb, ppb_hi;
+	int err = -ENOMEM;
+
+	dev = kmalloc(sizeof(ppa_struct), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+	memset(dev, 0, sizeof(ppa_struct));
+	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_WORK(&dev->ppa_tq, ppa_interrupt, dev);
+
+	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("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");
