// SPDX-License-Identifier: GPL-2.0-only
/* imm.c   --  low level driver for the IOMEGA MatchMaker
 * parallel port SCSI host adapter.
 * 
 * (The IMM is the embedded controller in the ZIP Plus drive.)
 * 
 * My unofficial company acronym list is 21 pages long:
 *      FLA:    Four letter acronym with built in facility for
 *              future expansion to five letters.
 */

#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/slab.h>
#include <asm/io.h>

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

/* The following #define is to avoid a clash with hosts.c */
#define IMM_PROBE_SPP   0x0001
#define IMM_PROBE_PS2   0x0002
#define IMM_PROBE_ECR   0x0010
#define IMM_PROBE_EPP17 0x0100
#define IMM_PROBE_EPP19 0x0200


typedef struct {
	struct pardevice *dev;	/* Parport device entry         */
	int base;		/* Actual port address          */
	int base_hi;		/* Hi Base address for ECP-ISA chipset */
	int mode;		/* Transfer mode                */
	struct scsi_cmnd *cur_cmd;	/* Current queued command       */
	struct delayed_work imm_tq;	/* Polling interrupt stuff       */
	unsigned long jstart;	/* Jiffies at start             */
	unsigned failed:1;	/* Failure flag                 */
	unsigned dp:1;		/* Data phase present           */
	unsigned rd:1;		/* Read data in data phase      */
	unsigned wanted:1;	/* Parport sharing busy flag    */
	unsigned int dev_no;	/* Device number		*/
	wait_queue_head_t *waiting;
	struct Scsi_Host *host;
	struct list_head list;
} imm_struct;

static void imm_reset_pulse(unsigned int base);
static int device_check(imm_struct *dev, bool autodetect);

#include "imm.h"

static unsigned int mode = IMM_AUTODETECT;
module_param(mode, uint, 0644);
MODULE_PARM_DESC(mode, "Transfer mode (0 = Autodetect, 1 = SPP 4-bit, "
	"2 = SPP 8-bit, 3 = EPP 8-bit, 4 = EPP 16-bit, 5 = EPP 32-bit");

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

static DEFINE_SPINLOCK(arbitration_lock);

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

static void imm_wakeup(void *ref)
{
	imm_struct *dev = (imm_struct *) ref;
	unsigned long flags;

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

static int imm_pb_claim(imm_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 imm_pb_dismiss(imm_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 imm_pb_release(imm_struct *dev)
{
	parport_release(dev->dev);
}

/* This is to give the imm driver a way to modify the timings (and other
 * parameters) by writing to the /proc/scsi/imm/0 file.
 * Very simple method really... (Too 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 int imm_write_info(struct Scsi_Host *host, char *buffer, int length)
{
	imm_struct *dev = imm_dev(host);

	if ((length > 5) && (strncmp(buffer, "mode=", 5) == 0)) {
		dev->mode = simple_strtoul(buffer + 5, NULL, 0);
		return length;
	}
	printk("imm /proc: invalid variable\n");
	return -EINVAL;
}

static int imm_show_info(struct seq_file *m, struct Scsi_Host *host)
{
	imm_struct *dev = imm_dev(host);

	seq_printf(m, "Version : %s\n", IMM_VERSION);
	seq_printf(m, "Parport : %s\n", dev->dev->port->name);
	seq_printf(m, "Mode    : %s\n", IMM_MODE_STRING[dev->mode]);
	return 0;
}

#if IMM_DEBUG > 0
#define imm_fail(x,y) printk("imm: imm_fail(%i) from %s at line %d\n",\
	   y, __func__, __LINE__); imm_fail_func(x,y);
static inline void
imm_fail_func(imm_struct *dev, int error_code)
#else
static inline void
imm_fail(imm_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 imm_wait(imm_struct *dev)
{
	int k;
	unsigned short ppb = dev->base;
	unsigned char r;

	w_ctr(ppb, 0x0c);

	k = IMM_SPIN_TMO;
	do {
		r = r_str(ppb);
		k--;
		udelay(1);
	}
	while (!(r & 0x80) && (k));

	/*
	 * STR register (LPT base+1) to SCSI mapping:
	 *
	 * STR      imm     imm
	 * ===================================
	 * 0x80     S_REQ   S_REQ
	 * 0x40     !S_BSY  (????)
	 * 0x20     !S_CD   !S_CD
	 * 0x10     !S_IO   !S_IO
	 * 0x08     (????)  !S_BSY
	 *
	 * imm      imm     meaning
	 * ==================================
	 * 0xf0     0xb8    Bit mask
	 * 0xc0     0x88    ZIP wants more data
	 * 0xd0     0x98    ZIP wants to send more data
	 * 0xe0     0xa8    ZIP is expecting SCSI command data
	 * 0xf0     0xb8    end of transfer, ZIP is sending status
	 */
	w_ctr(ppb, 0x04);
	if (k)
		return (r & 0xb8);

	/* Counter expired - Time out occurred */
	imm_fail(dev, DID_TIME_OUT);
	printk("imm timeout in imm_wait\n");
	return 0;		/* command timed out */
}

static int imm_negotiate(imm_struct * tmp)
{
	/*
	 * The following is supposedly the IEEE 1284-1994 negotiate
	 * sequence. I have yet to obtain a copy of the above standard
	 * so this is a bit of a guess...
	 *
	 * A fair chunk of this is based on the Linux parport implementation
	 * of IEEE 1284.
	 *
	 * Return 0 if data available
	 *        1 if no data available
	 */

	unsigned short base = tmp->base;
	unsigned char a, mode;

	switch (tmp->mode) {
	case IMM_NIBBLE:
		mode = 0x00;
		break;
	case IMM_PS2:
		mode = 0x01;
		break;
	default:
		return 0;
	}

	w_ctr(base, 0x04);
	udelay(5);
	w_dtr(base, mode);
	udelay(100);
	w_ctr(base, 0x06);
	udelay(5);
	a = (r_str(base) & 0x20) ? 0 : 1;
	udelay(5);
	w_ctr(base, 0x07);
	udelay(5);
	w_ctr(base, 0x06);

	if (a) {
		printk
		    ("IMM: IEEE1284 negotiate indicates no data available.\n");
		imm_fail(tmp, DID_ERROR);
	}
	return a;
}

/* 
 * 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(imm_struct *dev)
{
	int i, ppb_hi = dev->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("imm: ECP sync failed as data still present in FIFO.\n");
	}
}

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

	w_ctr(base, 0x4);	/* apparently a sane mode */
	for (i = len >> 1; i; i--) {
		w_dtr(base, *buffer++);
		w_ctr(base, 0x5);	/* Drop STROBE low */
		w_dtr(base, *buffer++);
		w_ctr(base, 0x0);	/* STROBE high + INIT low */
	}
	w_ctr(base, 0x4);	/* apparently a sane mode */
	return 1;		/* All went well - we hope! */
}

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

	/*
	 * The following is based on documented timing signals
	 */
	w_ctr(base, 0x4);
	for (i = len; i; i--) {
		w_ctr(base, 0x6);
		l = (r_str(base) & 0xf0) >> 4;
		w_ctr(base, 0x5);
		*buffer++ = (r_str(base) & 0xf0) | l;
		w_ctr(base, 0x4);
	}
	return 1;		/* All went well - we hope! */
}

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

	/*
	 * The following is based on documented timing signals
	 */
	w_ctr(base, 0x4);
	for (i = len; i; i--) {
		w_ctr(base, 0x26);
		*buffer++ = r_dtr(base);
		w_ctr(base, 0x25);
	}
	return 1;		/* All went well - we hope! */
}

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

	/*
	 * Make sure that:
	 * a) the SCSI bus is BUSY (device still listening)
	 * b) the device is listening
	 */
	if ((r & 0x18) != 0x08) {
		imm_fail(dev, DID_ERROR);
		printk("IMM: returned SCSI status %2x\n", r);
		return 0;
	}
	switch (dev->mode) {
	case IMM_EPP_32:
	case IMM_EPP_16:
	case IMM_EPP_8:
		epp_reset(ppb);
		w_ctr(ppb, 0x4);
		if (dev->mode == IMM_EPP_32 && !(((long) buffer | len) & 0x03))
			outsl(ppb + 4, buffer, len >> 2);
		else if (dev->mode == IMM_EPP_16 && !(((long) buffer | len) & 0x01))
			outsw(ppb + 4, buffer, len >> 1);
		else
			outsb(ppb + 4, buffer, len);
		w_ctr(ppb, 0xc);
		r = !(r_str(ppb) & 0x01);
		w_ctr(ppb, 0xc);
		ecp_sync(dev);
		break;

	case IMM_NIBBLE:
	case IMM_PS2:
		/* 8 bit output, with a loop */
		r = imm_byte_out(ppb, buffer, len);
		break;

	default:
		printk("IMM: bug in imm_out()\n");
		r = 0;
	}
	return r;
}

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

	/*
	 * Make sure that:
	 * a) the SCSI bus is BUSY (device still listening)
	 * b) the device is sending data
	 */
	if ((r & 0x18) != 0x18) {
		imm_fail(dev, DID_ERROR);
		return 0;
	}
	switch (dev->mode) {
	case IMM_NIBBLE:
		/* 4 bit input, with a loop */
		r = imm_nibble_in(ppb, buffer, len);
		w_ctr(ppb, 0xc);
		break;

	case IMM_PS2:
		/* 8 bit input, with a loop */
		r = imm_byte_in(ppb, buffer, len);
		w_ctr(ppb, 0xc);
		break;

	case IMM_EPP_32:
	case IMM_EPP_16:
	case IMM_EPP_8:
		epp_reset(ppb);
		w_ctr(ppb, 0x24);
		if (dev->mode == IMM_EPP_32 && !(((long) buffer | len) & 0x03))
			insw(ppb + 4, buffer, len >> 2);
		else if (dev->mode == IMM_EPP_16 && !(((long) buffer | len) & 0x01))
			insl(ppb + 4, buffer, len >> 1);
		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("IMM: bug in imm_ins()\n");
		r = 0;
		break;
	}
	return r;
}

static int imm_cpp(unsigned short ppb, unsigned char b)
{
	/*
	 * Comments on udelay values refer to the
	 * Command Packet Protocol (CPP) timing diagram.
	 */

	unsigned char s1, s2, s3;
	w_ctr(ppb, 0x0c);
	udelay(2);		/* 1 usec - infinite */
	w_dtr(ppb, 0xaa);
	udelay(10);		/* 7 usec - infinite */
	w_dtr(ppb, 0x55);
	udelay(10);		/* 7 usec - infinite */
	w_dtr(ppb, 0x00);
	udelay(10);		/* 7 usec - infinite */
	w_dtr(ppb, 0xff);
	udelay(10);		/* 7 usec - infinite */
	s1 = r_str(ppb) & 0xb8;
	w_dtr(ppb, 0x87);
	udelay(10);		/* 7 usec - infinite */
	s2 = r_str(ppb) & 0xb8;
	w_dtr(ppb, 0x78);
	udelay(10);		/* 7 usec - infinite */
	s3 = r_str(ppb) & 0x38;
	/*
	 * Values for b are:
	 * 0000 00aa    Assign address aa to current device
	 * 0010 00aa    Select device aa in EPP Winbond mode
	 * 0010 10aa    Select device aa in EPP mode
	 * 0011 xxxx    Deselect all devices
	 * 0110 00aa    Test device aa
	 * 1101 00aa    Select device aa in ECP mode
	 * 1110 00aa    Select device aa in Compatible mode
	 */
	w_dtr(ppb, b);
	udelay(2);		/* 1 usec - infinite */
	w_ctr(ppb, 0x0c);
	udelay(10);		/* 7 usec - infinite */
	w_ctr(ppb, 0x0d);
	udelay(2);		/* 1 usec - infinite */
	w_ctr(ppb, 0x0c);
	udelay(10);		/* 7 usec - infinite */
	w_dtr(ppb, 0xff);
	udelay(10);		/* 7 usec - infinite */

	/*
	 * The following table is electrical pin values.
	 * (BSY is inverted at the CTR register)
	 *
	 *       BSY  ACK  POut SEL  Fault
	 * S1    0    X    1    1    1
	 * S2    1    X    0    1    1
	 * S3    L    X    1    1    S
	 *
	 * L => Last device in chain
	 * S => Selected
	 *
	 * Observered values for S1,S2,S3 are:
	 * Disconnect => f8/58/78
	 * Connect    => f8/58/70
	 */
	if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x30))
		return 1;	/* Connected */
	if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x38))
		return 0;	/* Disconnected */

	return -1;		/* No device present */
}

static inline int imm_connect(imm_struct *dev, int flag)
{
	unsigned short ppb = dev->base;

	imm_cpp(ppb, 0xe0);	/* Select device 0 in compatible mode */
	imm_cpp(ppb, 0x30);	/* Disconnect all devices */

	if ((dev->mode == IMM_EPP_8) ||
	    (dev->mode == IMM_EPP_16) ||
	    (dev->mode == IMM_EPP_32))
		return imm_cpp(ppb, 0x28);	/* Select device 0 in EPP mode */
	return imm_cpp(ppb, 0xe0);	/* Select device 0 in compatible mode */
}

static void imm_disconnect(imm_struct *dev)
{
	imm_cpp(dev->base, 0x30);	/* Disconnect all devices */
}

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

	/*
	 * Firstly we want to make sure there is nothing
	 * holding onto the SCSI bus.
	 */
	w_ctr(ppb, 0xc);

	k = IMM_SELECT_TMO;
	do {
		k--;
	} while ((r_str(ppb) & 0x08) && (k));

	if (!k)
		return 0;

	/*
	 * Now assert the SCSI ID (HOST and TARGET) on the data bus
	 */
	w_ctr(ppb, 0x4);
	w_dtr(ppb, 0x80 | (1 << target));
	udelay(1);

	/*
	 * Deassert SELIN first followed by STROBE
	 */
	w_ctr(ppb, 0xc);
	w_ctr(ppb, 0xd);

	/*
	 * ACK should drop low while SELIN is deasserted.
	 * FAULT should drop low when the SCSI device latches the bus.
	 */
	k = IMM_SELECT_TMO;
	do {
		k--;
	}
	while (!(r_str(ppb) & 0x08) && (k));

	/*
	 * Place the interface back into a sane state (status mode)
	 */
	w_ctr(ppb, 0xc);
	return (k) ? 1 : 0;
}

static int imm_init(imm_struct *dev)
{
	bool autodetect = dev->mode == IMM_AUTODETECT;

	if (autodetect) {
		int modes = dev->dev->port->modes;

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

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

	if (imm_connect(dev, 0) != 1)
		return -EIO;
	imm_reset_pulse(dev->base);
	mdelay(1);	/* Delay to allow devices to settle */
	imm_disconnect(dev);
	mdelay(1);	/* Another delay to allow devices to settle */

	return device_check(dev, autodetect);
}

static inline int imm_send_command(struct scsi_cmnd *cmd)
{
	imm_struct *dev = imm_dev(cmd->device->host);
	int k;

	/* NOTE: IMM uses byte pairs */
	for (k = 0; k < cmd->cmd_len; k += 2)
		if (!imm_out(dev, &cmd->cmnd[k], 2))
			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 imm_completion(struct scsi_cmnd *const cmd)
{
	/* Return codes:
	 * -1     Error
	 *  0     Told to schedule
	 *  1     Finished data transfer
	 */
	struct scsi_pointer *scsi_pointer = imm_scsi_pointer(cmd);
	imm_struct *dev = imm_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 imm_wait.
	 */
	w_ctr(ppb, 0x0c);
	r = (r_str(ppb) & 0xb8);

	/*
	 * while (device is not ready to send status byte)
	 *     loop;
	 */
	while (r != (unsigned char) 0xb8) {
		/*
		 * 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;

		/*
		 * FAIL if:
		 * a) Drive status is screwy (!ready && !present)
		 * b) Drive is requesting/sending more data than expected
		 */
		if ((r & 0x88) != 0x88 || scsi_pointer->this_residual <= 0) {
			imm_fail(dev, DID_ERROR);
			return -1;	/* ERROR_RETURN */
		}
		/* determine if we should use burst I/O */
		if (dev->rd == 0) {
			fast = bulk && scsi_pointer->this_residual >=
				IMM_BURST_SIZE ? IMM_BURST_SIZE : 2;
			status = imm_out(dev, scsi_pointer->ptr, fast);
		} else {
			fast = bulk && scsi_pointer->this_residual >=
				IMM_BURST_SIZE ? IMM_BURST_SIZE : 1;
			status = imm_in(dev, scsi_pointer->ptr, fast);
		}

		scsi_pointer->ptr += fast;
		scsi_pointer->this_residual -= fast;

		if (!status) {
			imm_fail(dev, DID_BUS_BUSY);
			return -1;	/* ERROR_RETURN */
		}
		if (scsi_pointer->buffer && !scsi_pointer->this_residual) {
			/* if scatter/gather, advance to the next segment */
			if (scsi_pointer->buffers_residual--) {
				scsi_pointer->buffer =
					sg_next(scsi_pointer->buffer);
				scsi_pointer->this_residual =
				    scsi_pointer->buffer->length;
				scsi_pointer->ptr = sg_virt(scsi_pointer->buffer);

				/*
				 * Make sure that we transfer even number of bytes
				 * otherwise it makes imm_byte_out() messy.
				 */
				if (scsi_pointer->this_residual & 0x01)
					scsi_pointer->this_residual++;
			}
		}
		/* Now check to see if the drive is ready to comunicate */
		w_ctr(ppb, 0x0c);
		r = (r_str(ppb) & 0xb8);

		/* If not, drop back down to the scheduler and wait a timer tick */
		if (!(r & 0x80))
			return 0;
	}
	return 1;		/* FINISH_RETURN */
}

/*
 * Since the IMM 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 imm_interrupt(struct work_struct *work)
{
	imm_struct *dev = container_of(work, imm_struct, imm_tq.work);
	struct scsi_cmnd *cmd = dev->cur_cmd;
	struct Scsi_Host *host = cmd->device->host;
	unsigned long flags;

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

	if (imm_scsi_pointer(cmd)->phase > 1)
		imm_disconnect(dev);

	imm_pb_dismiss(dev);

	spin_lock_irqsave(host->host_lock, flags);
	dev->cur_cmd = NULL;
	scsi_done(cmd);
	spin_unlock_irqrestore(host->host_lock, flags);
	return;
}

static int imm_engine(imm_struct *dev, struct scsi_cmnd *const cmd)
{
	struct scsi_pointer *scsi_pointer = imm_scsi_pointer(cmd);
	unsigned short ppb = dev->base;
	unsigned char l = 0, h = 0;
	int retv, x;

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

	switch (scsi_pointer->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
			 */
			imm_fail(dev, DID_BUS_BUSY);
			return 0;
		}
		return 1;	/* wait until imm_wakeup claims parport */

	case 1:		/* Phase 1 - Connected */
		imm_connect(dev, CONNECT_EPP_MAYBE);
		scsi_pointer->phase++;
		fallthrough;

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

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

		if (!imm_send_command(cmd))
			return 0;
		scsi_pointer->phase++;
		fallthrough;

	case 4:		/* Phase 4 - Setup scatter/gather buffers */
		if (scsi_bufflen(cmd)) {
			scsi_pointer->buffer = scsi_sglist(cmd);
			scsi_pointer->this_residual = scsi_pointer->buffer->length;
			scsi_pointer->ptr = sg_virt(scsi_pointer->buffer);
		} else {
			scsi_pointer->buffer = NULL;
			scsi_pointer->this_residual = 0;
			scsi_pointer->ptr = NULL;
		}
		scsi_pointer->buffers_residual = scsi_sg_count(cmd) - 1;
		scsi_pointer->phase++;
		if (scsi_pointer->this_residual & 0x01)
			scsi_pointer->this_residual++;
		fallthrough;

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

		/* Require negotiation for read requests */
		x = (r_str(ppb) & 0xb8);
		dev->rd = (x & 0x10) ? 1 : 0;
		dev->dp = (x & 0x20) ? 0 : 1;

		if ((dev->dp) && (dev->rd))
			if (imm_negotiate(dev))
				return 0;
		scsi_pointer->phase++;
		fallthrough;

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

		if (dev->dp) {
			retv = imm_completion(cmd);
			if (retv == -1)
				return 0;
			if (retv == 0)
				return 1;
		}
		scsi_pointer->phase++;
		fallthrough;

	case 7:		/* Phase 7 - Post data transfer stage */
		if ((dev->dp) && (dev->rd)) {
			if ((dev->mode == IMM_NIBBLE) || (dev->mode == IMM_PS2)) {
				w_ctr(ppb, 0x4);
				w_ctr(ppb, 0xc);
				w_ctr(ppb, 0xe);
				w_ctr(ppb, 0x4);
			}
		}
		scsi_pointer->phase++;
		fallthrough;

	case 8:		/* Phase 8 - Read status/message */
		/* Check for data overrun */
		if (imm_wait(dev) != (unsigned char) 0xb8) {
			imm_fail(dev, DID_ERROR);
			return 0;
		}
		if (imm_negotiate(dev))
			return 0;
		if (imm_in(dev, &l, 1)) {	/* read status byte */
			/* Check for optional message byte */
			if (imm_wait(dev) == (unsigned char) 0xb8)
				imm_in(dev, &h, 1);
			cmd->result = (DID_OK << 16) | (l & STATUS_MASK);
		}
		if ((dev->mode == IMM_NIBBLE) || (dev->mode == IMM_PS2)) {
			w_ctr(ppb, 0x4);
			w_ctr(ppb, 0xc);
			w_ctr(ppb, 0xe);
			w_ctr(ppb, 0x4);
		}
		return 0;	/* Finished */

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

static int imm_queuecommand_lck(struct scsi_cmnd *cmd)
{
	imm_struct *dev = imm_dev(cmd->device->host);

	if (dev->cur_cmd) {
		printk("IMM: bug in imm_queuecommand\n");
		return 0;
	}
	dev->failed = 0;
	dev->jstart = jiffies;
	dev->cur_cmd = cmd;
	cmd->result = DID_ERROR << 16;	/* default return code */
	imm_scsi_pointer(cmd)->phase = 0;	/* bus free */

	schedule_delayed_work(&dev->imm_tq, 0);

	imm_pb_claim(dev);

	return 0;
}

static DEF_SCSI_QCMD(imm_queuecommand)

/*
 * 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 imm_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]);
	}
	return 0;
}

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

	switch (imm_scsi_pointer(cmd)->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;
	default:		/* SCSI command sent, can not abort */
		return FAILED;
	}
}

static void imm_reset_pulse(unsigned int base)
{
	w_ctr(base, 0x04);
	w_dtr(base, 0x40);
	udelay(1);
	w_ctr(base, 0x0c);
	w_ctr(base, 0x0d);
	udelay(50);
	w_ctr(base, 0x0c);
	w_ctr(base, 0x04);
}

static int imm_reset(struct scsi_cmnd *cmd)
{
	imm_struct *dev = imm_dev(cmd->device->host);

	if (imm_scsi_pointer(cmd)->phase)
		imm_disconnect(dev);
	dev->cur_cmd = NULL;	/* Forget the problem */

	imm_connect(dev, CONNECT_NORMAL);
	imm_reset_pulse(dev->base);
	mdelay(1);		/* device settle delay */
	imm_disconnect(dev);
	mdelay(1);		/* device settle delay */
	return SUCCESS;
}

static int device_check(imm_struct *dev, bool autodetect)
{
	/* 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 (autodetect && (ppb & 0x0007) == 0x0000)
			dev->mode = IMM_EPP_8;

	      second_pass:
		imm_connect(dev, CONNECT_EPP_MAYBE);
		/* Select SCSI device */
		if (!imm_select(dev, loop)) {
			imm_disconnect(dev);
			continue;
		}
		printk("imm: Found device at ID %i, Attempting to use %s\n",
		       loop, IMM_MODE_STRING[dev->mode]);

		/* Send SCSI command */
		status = 1;
		w_ctr(ppb, 0x0c);
		for (l = 0; (l < 3) && (status); l++)
			status = imm_out(dev, &cmd[l << 1], 2);

		if (!status) {
			imm_disconnect(dev);
			imm_connect(dev, CONNECT_EPP_MAYBE);
			imm_reset_pulse(dev->base);
			udelay(1000);
			imm_disconnect(dev);
			udelay(1000);
			if (dev->mode != old_mode) {
				dev->mode = old_mode;
				goto second_pass;
			}
			printk("imm: Unable to establish communication\n");
			return -EIO;
		}
		w_ctr(ppb, 0x0c);

		k = 1000000;	/* 1 Second */
		do {
			l = r_str(ppb);
			k--;
			udelay(1);
		} while (!(l & 0x80) && (k));

		l &= 0xb8;

		if (l != 0xb8) {
			imm_disconnect(dev);
			imm_connect(dev, CONNECT_EPP_MAYBE);
			imm_reset_pulse(dev->base);
			udelay(1000);
			imm_disconnect(dev);
			udelay(1000);
			if (dev->mode != old_mode) {
				dev->mode = old_mode;
				goto second_pass;
			}
			printk
			    ("imm: Unable to establish communication\n");
			return -EIO;
		}
		imm_disconnect(dev);
		printk
		    ("imm: Communication established at 0x%x with ID %i using %s\n",
		     ppb, loop, IMM_MODE_STRING[dev->mode]);
		imm_connect(dev, CONNECT_EPP_MAYBE);
		imm_reset_pulse(dev->base);
		udelay(1000);
		imm_disconnect(dev);
		udelay(1000);
		return 0;
	}
	printk("imm: No devices found\n");
	return -ENODEV;
}

static const struct scsi_host_template imm_template = {
	.module			= THIS_MODULE,
	.proc_name		= "imm",
	.show_info		= imm_show_info,
	.write_info		= imm_write_info,
	.name			= "Iomega VPI2 (imm) interface",
	.queuecommand		= imm_queuecommand,
	.eh_abort_handler	= imm_abort,
	.eh_host_reset_handler	= imm_reset,
	.bios_param		= imm_biosparam,
	.this_id		= 7,
	.sg_tablesize		= SG_ALL,
	.can_queue		= 1,
	.cmd_size		= sizeof(struct scsi_pointer),
};

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

static LIST_HEAD(imm_hosts);

/*
 * Finds the first available device number that can be alloted to the
 * new imm device and returns the address of the previous node so that
 * we can add to the tail and have a list in the ascending order.
 */

static inline imm_struct *find_parent(void)
{
	imm_struct *dev, *par = NULL;
	unsigned int cnt = 0;

	if (list_empty(&imm_hosts))
		return NULL;

	list_for_each_entry(dev, &imm_hosts, list) {
		if (dev->dev_no != cnt)
			return par;
		cnt++;
		par = dev;
	}

	return par;
}

static int __imm_attach(struct parport *pb)
{
	struct Scsi_Host *host;
	imm_struct *dev, *temp;
	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting);
	DEFINE_WAIT(wait);
	int ports;
	int err = -ENOMEM;
	struct pardev_cb imm_cb;

	init_waitqueue_head(&waiting);

	dev = kzalloc(sizeof(imm_struct), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;


	dev->base = -1;
	dev->mode = mode < IMM_UNKNOWN ? mode : IMM_AUTODETECT;
	INIT_LIST_HEAD(&dev->list);

	temp = find_parent();
	if (temp)
		dev->dev_no = temp->dev_no + 1;

	memset(&imm_cb, 0, sizeof(imm_cb));
	imm_cb.private = dev;
	imm_cb.wakeup = imm_wakeup;

	dev->dev = parport_register_dev_model(pb, "imm", &imm_cb, dev->dev_no);
	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 (imm_pb_claim(dev))
		schedule_timeout(3 * HZ);
	if (dev->wanted) {
		printk(KERN_ERR "imm%d: failed to claim parport because "
			"a pardevice is owning the port for too long "
			"time!\n", pb->number);
		imm_pb_dismiss(dev);
		dev->waiting = NULL;
		finish_wait(&waiting, &wait);
		goto out1;
	}
	dev->waiting = NULL;
	finish_wait(&waiting, &wait);
	dev->base = dev->dev->port->base;
	dev->base_hi = dev->dev->port->base_hi;
	w_ctr(dev->base, 0x0c);

	/* Done configuration */

	err = imm_init(dev);

	imm_pb_release(dev);

	if (err)
		goto out1;

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

	INIT_DELAYED_WORK(&dev->imm_tq, imm_interrupt);

	err = -ENOMEM;
	host = scsi_host_alloc(&imm_template, sizeof(imm_struct *));
	if (!host)
		goto out1;
	host->no_highmem = true;
	host->io_port = pb->base;
	host->n_io_port = ports;
	host->dma_channel = -1;
	host->unique_id = pb->number;
	*(imm_struct **)&host->hostdata = dev;
	dev->host = host;
	if (!temp)
		list_add_tail(&dev->list, &imm_hosts);
	else
		list_add_tail(&dev->list, &temp->list);
	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 imm_attach(struct parport *pb)
{
	__imm_attach(pb);
}

static void imm_detach(struct parport *pb)
{
	imm_struct *dev;
	list_for_each_entry(dev, &imm_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 imm_driver = {
	.name		= "imm",
	.match_port	= imm_attach,
	.detach		= imm_detach,
};
module_parport_driver(imm_driver);

MODULE_DESCRIPTION("IOMEGA MatchMaker parallel port SCSI host adapter driver");
MODULE_LICENSE("GPL");
