/* Low-level parallel-port routines for 8255-based PC-style hardware.
 *
 * Authors: Phil Blundell <philb@gnu.org>
 *          Tim Waugh <tim@cyberelk.demon.co.uk>
 *	    Jose Renau <renau@acm.org>
 *          David Campbell
 *          Andrea Arcangeli
 *
 * based on work by Grant Guenther <grant@torque.net> and Phil Blundell.
 *
 * Cleaned up include files - Russell King <linux@arm.uk.linux.org>
 * DMA support - Bert De Jonghe <bert@sophis.be>
 * Many ECP bugs fixed.  Fred Barnes & Jamie Lokier, 1999
 * More PCI support now conditional on CONFIG_PCI, 03/2001, Paul G.
 * Various hacks, Fred Barnes, 04/2001
 * Updated probing logic - Adam Belay <ambx1@neo.rr.com>
 */

/* This driver should work with any hardware that is broadly compatible
 * with that in the IBM PC.  This applies to the majority of integrated
 * I/O chipsets that are commonly available.  The expected register
 * layout is:
 *
 *	base+0		data
 *	base+1		status
 *	base+2		control
 *
 * In addition, there are some optional registers:
 *
 *	base+3		EPP address
 *	base+4		EPP data
 *	base+0x400	ECP config A
 *	base+0x401	ECP config B
 *	base+0x402	ECP control
 *
 * All registers are 8 bits wide and read/write.  If your hardware differs
 * only in register addresses (eg because your registers are on 32-bit
 * word boundaries) then you can alter the constants in parport_pc.h to
 * accommodate this.
 *
 * Note that the ECP registers may not start at offset 0x400 for PCI cards,
 * but rather will start at port->base_hi.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched/signal.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/pci.h>
#include <linux/pnp.h>
#include <linux/platform_device.h>
#include <linux/sysctl.h>
#include <linux/io.h>
#include <linux/uaccess.h>

#include <asm/dma.h>

#include <linux/parport.h>
#include <linux/parport_pc.h>
#include <linux/via.h>
#include <asm/parport.h>

#define PARPORT_PC_MAX_PORTS PARPORT_MAX

#ifdef CONFIG_ISA_DMA_API
#define HAS_DMA
#endif

/* ECR modes */
#define ECR_SPP 00
#define ECR_PS2 01
#define ECR_PPF 02
#define ECR_ECP 03
#define ECR_EPP 04
#define ECR_VND 05
#define ECR_TST 06
#define ECR_CNF 07
#define ECR_MODE_MASK 0xe0
#define ECR_WRITE(p, v) frob_econtrol((p), 0xff, (v))

#undef DEBUG

#ifdef DEBUG
#define DPRINTK  printk
#else
#define DPRINTK(stuff...)
#endif


#define NR_SUPERIOS 3
static struct superio_struct {	/* For Super-IO chips autodetection */
	int io;
	int irq;
	int dma;
} superios[NR_SUPERIOS] = { {0,},};

static int user_specified;
#if defined(CONFIG_PARPORT_PC_SUPERIO) || \
       (defined(CONFIG_PARPORT_1284) && defined(CONFIG_PARPORT_PC_FIFO))
static int verbose_probing;
#endif
static int pci_registered_parport;
static int pnp_registered_parport;

/* frob_control, but for ECR */
static void frob_econtrol(struct parport *pb, unsigned char m,
			   unsigned char v)
{
	unsigned char ectr = 0;

	if (m != 0xff)
		ectr = inb(ECONTROL(pb));

	DPRINTK(KERN_DEBUG "frob_econtrol(%02x,%02x): %02x -> %02x\n",
		m, v, ectr, (ectr & ~m) ^ v);

	outb((ectr & ~m) ^ v, ECONTROL(pb));
}

static inline void frob_set_mode(struct parport *p, int mode)
{
	frob_econtrol(p, ECR_MODE_MASK, mode << 5);
}

#ifdef CONFIG_PARPORT_PC_FIFO
/* Safely change the mode bits in the ECR
   Returns:
	    0    : Success
	   -EBUSY: Could not drain FIFO in some finite amount of time,
		   mode not changed!
 */
static int change_mode(struct parport *p, int m)
{
	const struct parport_pc_private *priv = p->physport->private_data;
	unsigned char oecr;
	int mode;

	DPRINTK(KERN_INFO "parport change_mode ECP-ISA to mode 0x%02x\n", m);

	if (!priv->ecr) {
		printk(KERN_DEBUG "change_mode: but there's no ECR!\n");
		return 0;
	}

	/* Bits <7:5> contain the mode. */
	oecr = inb(ECONTROL(p));
	mode = (oecr >> 5) & 0x7;
	if (mode == m)
		return 0;

	if (mode >= 2 && !(priv->ctr & 0x20)) {
		/* This mode resets the FIFO, so we may
		 * have to wait for it to drain first. */
		unsigned long expire = jiffies + p->physport->cad->timeout;
		int counter;
		switch (mode) {
		case ECR_PPF: /* Parallel Port FIFO mode */
		case ECR_ECP: /* ECP Parallel Port mode */
			/* Busy wait for 200us */
			for (counter = 0; counter < 40; counter++) {
				if (inb(ECONTROL(p)) & 0x01)
					break;
				if (signal_pending(current))
					break;
				udelay(5);
			}

			/* Poll slowly. */
			while (!(inb(ECONTROL(p)) & 0x01)) {
				if (time_after_eq(jiffies, expire))
					/* The FIFO is stuck. */
					return -EBUSY;
				schedule_timeout_interruptible(
							msecs_to_jiffies(10));
				if (signal_pending(current))
					break;
			}
		}
	}

	if (mode >= 2 && m >= 2) {
		/* We have to go through mode 001 */
		oecr &= ~(7 << 5);
		oecr |= ECR_PS2 << 5;
		ECR_WRITE(p, oecr);
	}

	/* Set the mode. */
	oecr &= ~(7 << 5);
	oecr |= m << 5;
	ECR_WRITE(p, oecr);
	return 0;
}
#endif /* FIFO support */

/*
 * Clear TIMEOUT BIT in EPP MODE
 *
 * This is also used in SPP detection.
 */
static int clear_epp_timeout(struct parport *pb)
{
	unsigned char r;

	if (!(parport_pc_read_status(pb) & 0x01))
		return 1;

	/* To clear timeout some chips require double read */
	parport_pc_read_status(pb);
	r = parport_pc_read_status(pb);
	outb(r | 0x01, STATUS(pb)); /* Some reset by writing 1 */
	outb(r & 0xfe, STATUS(pb)); /* Others by writing 0 */
	r = parport_pc_read_status(pb);

	return !(r & 0x01);
}

/*
 * Access functions.
 *
 * Most of these aren't static because they may be used by the
 * parport_xxx_yyy macros.  extern __inline__ versions of several
 * of these are in parport_pc.h.
 */

static void parport_pc_init_state(struct pardevice *dev,
						struct parport_state *s)
{
	s->u.pc.ctr = 0xc;
	if (dev->irq_func &&
	    dev->port->irq != PARPORT_IRQ_NONE)
		/* Set ackIntEn */
		s->u.pc.ctr |= 0x10;

	s->u.pc.ecr = 0x34; /* NetMos chip can cause problems 0x24;
			     * D.Gruszka VScom */
}

static void parport_pc_save_state(struct parport *p, struct parport_state *s)
{
	const struct parport_pc_private *priv = p->physport->private_data;
	s->u.pc.ctr = priv->ctr;
	if (priv->ecr)
		s->u.pc.ecr = inb(ECONTROL(p));
}

static void parport_pc_restore_state(struct parport *p,
						struct parport_state *s)
{
	struct parport_pc_private *priv = p->physport->private_data;
	register unsigned char c = s->u.pc.ctr & priv->ctr_writable;
	outb(c, CONTROL(p));
	priv->ctr = c;
	if (priv->ecr)
		ECR_WRITE(p, s->u.pc.ecr);
}

#ifdef CONFIG_PARPORT_1284
static size_t parport_pc_epp_read_data(struct parport *port, void *buf,
				       size_t length, int flags)
{
	size_t got = 0;

	if (flags & PARPORT_W91284PIC) {
		unsigned char status;
		size_t left = length;

		/* use knowledge about data lines..:
		 *  nFault is 0 if there is at least 1 byte in the Warp's FIFO
		 *  pError is 1 if there are 16 bytes in the Warp's FIFO
		 */
		status = inb(STATUS(port));

		while (!(status & 0x08) && got < length) {
			if (left >= 16 && (status & 0x20) && !(status & 0x08)) {
				/* can grab 16 bytes from warp fifo */
				if (!((long)buf & 0x03))
					insl(EPPDATA(port), buf, 4);
				else
					insb(EPPDATA(port), buf, 16);
				buf += 16;
				got += 16;
				left -= 16;
			} else {
				/* grab single byte from the warp fifo */
				*((char *)buf) = inb(EPPDATA(port));
				buf++;
				got++;
				left--;
			}
			status = inb(STATUS(port));
			if (status & 0x01) {
				/* EPP timeout should never occur... */
				printk(KERN_DEBUG
"%s: EPP timeout occurred while talking to w91284pic (should not have done)\n", port->name);
				clear_epp_timeout(port);
			}
		}
		return got;
	}
	if ((flags & PARPORT_EPP_FAST) && (length > 1)) {
		if (!(((long)buf | length) & 0x03))
			insl(EPPDATA(port), buf, (length >> 2));
		else
			insb(EPPDATA(port), buf, length);
		if (inb(STATUS(port)) & 0x01) {
			clear_epp_timeout(port);
			return -EIO;
		}
		return length;
	}
	for (; got < length; got++) {
		*((char *)buf) = inb(EPPDATA(port));
		buf++;
		if (inb(STATUS(port)) & 0x01) {
			/* EPP timeout */
			clear_epp_timeout(port);
			break;
		}
	}

	return got;
}

static size_t parport_pc_epp_write_data(struct parport *port, const void *buf,
					size_t length, int flags)
{
	size_t written = 0;

	if ((flags & PARPORT_EPP_FAST) && (length > 1)) {
		if (!(((long)buf | length) & 0x03))
			outsl(EPPDATA(port), buf, (length >> 2));
		else
			outsb(EPPDATA(port), buf, length);
		if (inb(STATUS(port)) & 0x01) {
			clear_epp_timeout(port);
			return -EIO;
		}
		return length;
	}
	for (; written < length; written++) {
		outb(*((char *)buf), EPPDATA(port));
		buf++;
		if (inb(STATUS(port)) & 0x01) {
			clear_epp_timeout(port);
			break;
		}
	}

	return written;
}

static size_t parport_pc_epp_read_addr(struct parport *port, void *buf,
					size_t length, int flags)
{
	size_t got = 0;

	if ((flags & PARPORT_EPP_FAST) && (length > 1)) {
		insb(EPPADDR(port), buf, length);
		if (inb(STATUS(port)) & 0x01) {
			clear_epp_timeout(port);
			return -EIO;
		}
		return length;
	}
	for (; got < length; got++) {
		*((char *)buf) = inb(EPPADDR(port));
		buf++;
		if (inb(STATUS(port)) & 0x01) {
			clear_epp_timeout(port);
			break;
		}
	}

	return got;
}

static size_t parport_pc_epp_write_addr(struct parport *port,
					 const void *buf, size_t length,
					 int flags)
{
	size_t written = 0;

	if ((flags & PARPORT_EPP_FAST) && (length > 1)) {
		outsb(EPPADDR(port), buf, length);
		if (inb(STATUS(port)) & 0x01) {
			clear_epp_timeout(port);
			return -EIO;
		}
		return length;
	}
	for (; written < length; written++) {
		outb(*((char *)buf), EPPADDR(port));
		buf++;
		if (inb(STATUS(port)) & 0x01) {
			clear_epp_timeout(port);
			break;
		}
	}

	return written;
}

static size_t parport_pc_ecpepp_read_data(struct parport *port, void *buf,
					  size_t length, int flags)
{
	size_t got;

	frob_set_mode(port, ECR_EPP);
	parport_pc_data_reverse(port);
	parport_pc_write_control(port, 0x4);
	got = parport_pc_epp_read_data(port, buf, length, flags);
	frob_set_mode(port, ECR_PS2);

	return got;
}

static size_t parport_pc_ecpepp_write_data(struct parport *port,
					   const void *buf, size_t length,
					   int flags)
{
	size_t written;

	frob_set_mode(port, ECR_EPP);
	parport_pc_write_control(port, 0x4);
	parport_pc_data_forward(port);
	written = parport_pc_epp_write_data(port, buf, length, flags);
	frob_set_mode(port, ECR_PS2);

	return written;
}

static size_t parport_pc_ecpepp_read_addr(struct parport *port, void *buf,
					  size_t length, int flags)
{
	size_t got;

	frob_set_mode(port, ECR_EPP);
	parport_pc_data_reverse(port);
	parport_pc_write_control(port, 0x4);
	got = parport_pc_epp_read_addr(port, buf, length, flags);
	frob_set_mode(port, ECR_PS2);

	return got;
}

static size_t parport_pc_ecpepp_write_addr(struct parport *port,
					    const void *buf, size_t length,
					    int flags)
{
	size_t written;

	frob_set_mode(port, ECR_EPP);
	parport_pc_write_control(port, 0x4);
	parport_pc_data_forward(port);
	written = parport_pc_epp_write_addr(port, buf, length, flags);
	frob_set_mode(port, ECR_PS2);

	return written;
}
#endif /* IEEE 1284 support */

#ifdef CONFIG_PARPORT_PC_FIFO
static size_t parport_pc_fifo_write_block_pio(struct parport *port,
					       const void *buf, size_t length)
{
	int ret = 0;
	const unsigned char *bufp = buf;
	size_t left = length;
	unsigned long expire = jiffies + port->physport->cad->timeout;
	const int fifo = FIFO(port);
	int poll_for = 8; /* 80 usecs */
	const struct parport_pc_private *priv = port->physport->private_data;
	const int fifo_depth = priv->fifo_depth;

	port = port->physport;

	/* We don't want to be interrupted every character. */
	parport_pc_disable_irq(port);
	/* set nErrIntrEn and serviceIntr */
	frob_econtrol(port, (1<<4) | (1<<2), (1<<4) | (1<<2));

	/* Forward mode. */
	parport_pc_data_forward(port); /* Must be in PS2 mode */

	while (left) {
		unsigned char byte;
		unsigned char ecrval = inb(ECONTROL(port));
		int i = 0;

		if (need_resched() && time_before(jiffies, expire))
			/* Can't yield the port. */
			schedule();

		/* Anyone else waiting for the port? */
		if (port->waithead) {
			printk(KERN_DEBUG "Somebody wants the port\n");
			break;
		}

		if (ecrval & 0x02) {
			/* FIFO is full. Wait for interrupt. */

			/* Clear serviceIntr */
			ECR_WRITE(port, ecrval & ~(1<<2));
false_alarm:
			ret = parport_wait_event(port, HZ);
			if (ret < 0)
				break;
			ret = 0;
			if (!time_before(jiffies, expire)) {
				/* Timed out. */
				printk(KERN_DEBUG "FIFO write timed out\n");
				break;
			}
			ecrval = inb(ECONTROL(port));
			if (!(ecrval & (1<<2))) {
				if (need_resched() &&
				    time_before(jiffies, expire))
					schedule();

				goto false_alarm;
			}

			continue;
		}

		/* Can't fail now. */
		expire = jiffies + port->cad->timeout;

poll:
		if (signal_pending(current))
			break;

		if (ecrval & 0x01) {
			/* FIFO is empty. Blast it full. */
			const int n = left < fifo_depth ? left : fifo_depth;
			outsb(fifo, bufp, n);
			bufp += n;
			left -= n;

			/* Adjust the poll time. */
			if (i < (poll_for - 2))
				poll_for--;
			continue;
		} else if (i++ < poll_for) {
			udelay(10);
			ecrval = inb(ECONTROL(port));
			goto poll;
		}

		/* Half-full(call me an optimist) */
		byte = *bufp++;
		outb(byte, fifo);
		left--;
	}
	dump_parport_state("leave fifo_write_block_pio", port);
	return length - left;
}

#ifdef HAS_DMA
static size_t parport_pc_fifo_write_block_dma(struct parport *port,
					       const void *buf, size_t length)
{
	int ret = 0;
	unsigned long dmaflag;
	size_t left = length;
	const struct parport_pc_private *priv = port->physport->private_data;
	struct device *dev = port->physport->dev;
	dma_addr_t dma_addr, dma_handle;
	size_t maxlen = 0x10000; /* max 64k per DMA transfer */
	unsigned long start = (unsigned long) buf;
	unsigned long end = (unsigned long) buf + length - 1;

	dump_parport_state("enter fifo_write_block_dma", port);
	if (end < MAX_DMA_ADDRESS) {
		/* If it would cross a 64k boundary, cap it at the end. */
		if ((start ^ end) & ~0xffffUL)
			maxlen = 0x10000 - (start & 0xffff);

		dma_addr = dma_handle = dma_map_single(dev, (void *)buf, length,
						       DMA_TO_DEVICE);
	} else {
		/* above 16 MB we use a bounce buffer as ISA-DMA
		   is not possible */
		maxlen   = PAGE_SIZE;          /* sizeof(priv->dma_buf) */
		dma_addr = priv->dma_handle;
		dma_handle = 0;
	}

	port = port->physport;

	/* We don't want to be interrupted every character. */
	parport_pc_disable_irq(port);
	/* set nErrIntrEn and serviceIntr */
	frob_econtrol(port, (1<<4) | (1<<2), (1<<4) | (1<<2));

	/* Forward mode. */
	parport_pc_data_forward(port); /* Must be in PS2 mode */

	while (left) {
		unsigned long expire = jiffies + port->physport->cad->timeout;

		size_t count = left;

		if (count > maxlen)
			count = maxlen;

		if (!dma_handle)   /* bounce buffer ! */
			memcpy(priv->dma_buf, buf, count);

		dmaflag = claim_dma_lock();
		disable_dma(port->dma);
		clear_dma_ff(port->dma);
		set_dma_mode(port->dma, DMA_MODE_WRITE);
		set_dma_addr(port->dma, dma_addr);
		set_dma_count(port->dma, count);

		/* Set DMA mode */
		frob_econtrol(port, 1<<3, 1<<3);

		/* Clear serviceIntr */
		frob_econtrol(port, 1<<2, 0);

		enable_dma(port->dma);
		release_dma_lock(dmaflag);

		/* assume DMA will be successful */
		left -= count;
		buf  += count;
		if (dma_handle)
			dma_addr += count;

		/* Wait for interrupt. */
false_alarm:
		ret = parport_wait_event(port, HZ);
		if (ret < 0)
			break;
		ret = 0;
		if (!time_before(jiffies, expire)) {
			/* Timed out. */
			printk(KERN_DEBUG "DMA write timed out\n");
			break;
		}
		/* Is serviceIntr set? */
		if (!(inb(ECONTROL(port)) & (1<<2))) {
			cond_resched();

			goto false_alarm;
		}

		dmaflag = claim_dma_lock();
		disable_dma(port->dma);
		clear_dma_ff(port->dma);
		count = get_dma_residue(port->dma);
		release_dma_lock(dmaflag);

		cond_resched(); /* Can't yield the port. */

		/* Anyone else waiting for the port? */
		if (port->waithead) {
			printk(KERN_DEBUG "Somebody wants the port\n");
			break;
		}

		/* update for possible DMA residue ! */
		buf  -= count;
		left += count;
		if (dma_handle)
			dma_addr -= count;
	}

	/* Maybe got here through break, so adjust for DMA residue! */
	dmaflag = claim_dma_lock();
	disable_dma(port->dma);
	clear_dma_ff(port->dma);
	left += get_dma_residue(port->dma);
	release_dma_lock(dmaflag);

	/* Turn off DMA mode */
	frob_econtrol(port, 1<<3, 0);

	if (dma_handle)
		dma_unmap_single(dev, dma_handle, length, DMA_TO_DEVICE);

	dump_parport_state("leave fifo_write_block_dma", port);
	return length - left;
}
#endif

static inline size_t parport_pc_fifo_write_block(struct parport *port,
					       const void *buf, size_t length)
{
#ifdef HAS_DMA
	if (port->dma != PARPORT_DMA_NONE)
		return parport_pc_fifo_write_block_dma(port, buf, length);
#endif
	return parport_pc_fifo_write_block_pio(port, buf, length);
}

/* Parallel Port FIFO mode (ECP chipsets) */
static size_t parport_pc_compat_write_block_pio(struct parport *port,
						 const void *buf, size_t length,
						 int flags)
{
	size_t written;
	int r;
	unsigned long expire;
	const struct parport_pc_private *priv = port->physport->private_data;

	/* Special case: a timeout of zero means we cannot call schedule().
	 * Also if O_NONBLOCK is set then use the default implementation. */
	if (port->physport->cad->timeout <= PARPORT_INACTIVITY_O_NONBLOCK)
		return parport_ieee1284_write_compat(port, buf,
						      length, flags);

	/* Set up parallel port FIFO mode.*/
	parport_pc_data_forward(port); /* Must be in PS2 mode */
	parport_pc_frob_control(port, PARPORT_CONTROL_STROBE, 0);
	r = change_mode(port, ECR_PPF); /* Parallel port FIFO */
	if (r)
		printk(KERN_DEBUG "%s: Warning change_mode ECR_PPF failed\n",
								port->name);

	port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;

	/* Write the data to the FIFO. */
	written = parport_pc_fifo_write_block(port, buf, length);

	/* Finish up. */
	/* For some hardware we don't want to touch the mode until
	 * the FIFO is empty, so allow 4 seconds for each position
	 * in the fifo.
	 */
	expire = jiffies + (priv->fifo_depth * HZ * 4);
	do {
		/* Wait for the FIFO to empty */
		r = change_mode(port, ECR_PS2);
		if (r != -EBUSY)
			break;
	} while (time_before(jiffies, expire));
	if (r == -EBUSY) {

		printk(KERN_DEBUG "%s: FIFO is stuck\n", port->name);

		/* Prevent further data transfer. */
		frob_set_mode(port, ECR_TST);

		/* Adjust for the contents of the FIFO. */
		for (written -= priv->fifo_depth; ; written++) {
			if (inb(ECONTROL(port)) & 0x2) {
				/* Full up. */
				break;
			}
			outb(0, FIFO(port));
		}

		/* Reset the FIFO and return to PS2 mode. */
		frob_set_mode(port, ECR_PS2);
	}

	r = parport_wait_peripheral(port,
				     PARPORT_STATUS_BUSY,
				     PARPORT_STATUS_BUSY);
	if (r)
		printk(KERN_DEBUG
			"%s: BUSY timeout (%d) in compat_write_block_pio\n",
			port->name, r);

	port->physport->ieee1284.phase = IEEE1284_PH_FWD_IDLE;

	return written;
}

/* ECP */
#ifdef CONFIG_PARPORT_1284
static size_t parport_pc_ecp_write_block_pio(struct parport *port,
					      const void *buf, size_t length,
					      int flags)
{
	size_t written;
	int r;
	unsigned long expire;
	const struct parport_pc_private *priv = port->physport->private_data;

	/* Special case: a timeout of zero means we cannot call schedule().
	 * Also if O_NONBLOCK is set then use the default implementation. */
	if (port->physport->cad->timeout <= PARPORT_INACTIVITY_O_NONBLOCK)
		return parport_ieee1284_ecp_write_data(port, buf,
							length, flags);

	/* Switch to forward mode if necessary. */
	if (port->physport->ieee1284.phase != IEEE1284_PH_FWD_IDLE) {
		/* Event 47: Set nInit high. */
		parport_frob_control(port,
				      PARPORT_CONTROL_INIT
				      | PARPORT_CONTROL_AUTOFD,
				      PARPORT_CONTROL_INIT
				      | PARPORT_CONTROL_AUTOFD);

		/* Event 49: PError goes high. */
		r = parport_wait_peripheral(port,
					     PARPORT_STATUS_PAPEROUT,
					     PARPORT_STATUS_PAPEROUT);
		if (r) {
			printk(KERN_DEBUG "%s: PError timeout (%d) "
				"in ecp_write_block_pio\n", port->name, r);
		}
	}

	/* Set up ECP parallel port mode.*/
	parport_pc_data_forward(port); /* Must be in PS2 mode */
	parport_pc_frob_control(port,
				 PARPORT_CONTROL_STROBE |
				 PARPORT_CONTROL_AUTOFD,
				 0);
	r = change_mode(port, ECR_ECP); /* ECP FIFO */
	if (r)
		printk(KERN_DEBUG "%s: Warning change_mode ECR_ECP failed\n",
								port->name);
	port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;

	/* Write the data to the FIFO. */
	written = parport_pc_fifo_write_block(port, buf, length);

	/* Finish up. */
	/* For some hardware we don't want to touch the mode until
	 * the FIFO is empty, so allow 4 seconds for each position
	 * in the fifo.
	 */
	expire = jiffies + (priv->fifo_depth * (HZ * 4));
	do {
		/* Wait for the FIFO to empty */
		r = change_mode(port, ECR_PS2);
		if (r != -EBUSY)
			break;
	} while (time_before(jiffies, expire));
	if (r == -EBUSY) {

		printk(KERN_DEBUG "%s: FIFO is stuck\n", port->name);

		/* Prevent further data transfer. */
		frob_set_mode(port, ECR_TST);

		/* Adjust for the contents of the FIFO. */
		for (written -= priv->fifo_depth; ; written++) {
			if (inb(ECONTROL(port)) & 0x2) {
				/* Full up. */
				break;
			}
			outb(0, FIFO(port));
		}

		/* Reset the FIFO and return to PS2 mode. */
		frob_set_mode(port, ECR_PS2);

		/* Host transfer recovery. */
		parport_pc_data_reverse(port); /* Must be in PS2 mode */
		udelay(5);
		parport_frob_control(port, PARPORT_CONTROL_INIT, 0);
		r = parport_wait_peripheral(port, PARPORT_STATUS_PAPEROUT, 0);
		if (r)
			printk(KERN_DEBUG "%s: PE,1 timeout (%d) "
				"in ecp_write_block_pio\n", port->name, r);

		parport_frob_control(port,
				      PARPORT_CONTROL_INIT,
				      PARPORT_CONTROL_INIT);
		r = parport_wait_peripheral(port,
					     PARPORT_STATUS_PAPEROUT,
					     PARPORT_STATUS_PAPEROUT);
		if (r)
			printk(KERN_DEBUG "%s: PE,2 timeout (%d) "
				"in ecp_write_block_pio\n", port->name, r);
	}

	r = parport_wait_peripheral(port,
				     PARPORT_STATUS_BUSY,
				     PARPORT_STATUS_BUSY);
	if (r)
		printk(KERN_DEBUG
			"%s: BUSY timeout (%d) in ecp_write_block_pio\n",
			port->name, r);

	port->physport->ieee1284.phase = IEEE1284_PH_FWD_IDLE;

	return written;
}
#endif /* IEEE 1284 support */
#endif /* Allowed to use FIFO/DMA */


/*
 *	******************************************
 *	INITIALISATION AND MODULE STUFF BELOW HERE
 *	******************************************
 */

/* GCC is not inlining extern inline function later overwritten to non-inline,
   so we use outlined_ variants here.  */
static const struct parport_operations parport_pc_ops = {
	.write_data	= parport_pc_write_data,
	.read_data	= parport_pc_read_data,

	.write_control	= parport_pc_write_control,
	.read_control	= parport_pc_read_control,
	.frob_control	= parport_pc_frob_control,

	.read_status	= parport_pc_read_status,

	.enable_irq	= parport_pc_enable_irq,
	.disable_irq	= parport_pc_disable_irq,

	.data_forward	= parport_pc_data_forward,
	.data_reverse	= parport_pc_data_reverse,

	.init_state	= parport_pc_init_state,
	.save_state	= parport_pc_save_state,
	.restore_state	= parport_pc_restore_state,

	.epp_write_data	= parport_ieee1284_epp_write_data,
	.epp_read_data	= parport_ieee1284_epp_read_data,
	.epp_write_addr	= parport_ieee1284_epp_write_addr,
	.epp_read_addr	= parport_ieee1284_epp_read_addr,

	.ecp_write_data	= parport_ieee1284_ecp_write_data,
	.ecp_read_data	= parport_ieee1284_ecp_read_data,
	.ecp_write_addr	= parport_ieee1284_ecp_write_addr,

	.compat_write_data	= parport_ieee1284_write_compat,
	.nibble_read_data	= parport_ieee1284_read_nibble,
	.byte_read_data		= parport_ieee1284_read_byte,

	.owner		= THIS_MODULE,
};

#ifdef CONFIG_PARPORT_PC_SUPERIO

static struct superio_struct *find_free_superio(void)
{
	int i;
	for (i = 0; i < NR_SUPERIOS; i++)
		if (superios[i].io == 0)
			return &superios[i];
	return NULL;
}


/* Super-IO chipset detection, Winbond, SMSC */
static void show_parconfig_smsc37c669(int io, int key)
{
	int cr1, cr4, cra, cr23, cr26, cr27;
	struct superio_struct *s;

	static const char *const modes[] = {
		"SPP and Bidirectional (PS/2)",
		"EPP and SPP",
		"ECP",
		"ECP and EPP" };

	outb(key, io);
	outb(key, io);
	outb(1, io);
	cr1 = inb(io + 1);
	outb(4, io);
	cr4 = inb(io + 1);
	outb(0x0a, io);
	cra = inb(io + 1);
	outb(0x23, io);
	cr23 = inb(io + 1);
	outb(0x26, io);
	cr26 = inb(io + 1);
	outb(0x27, io);
	cr27 = inb(io + 1);
	outb(0xaa, io);

	if (verbose_probing) {
		printk(KERN_INFO
			"SMSC 37c669 LPT Config: cr_1=0x%02x, 4=0x%02x, "
			"A=0x%2x, 23=0x%02x, 26=0x%02x, 27=0x%02x\n",
			cr1, cr4, cra, cr23, cr26, cr27);

		/* The documentation calls DMA and IRQ-Lines by letters, so
		   the board maker can/will wire them
		   appropriately/randomly...  G=reserved H=IDE-irq, */
		printk(KERN_INFO
	"SMSC LPT Config: io=0x%04x, irq=%c, dma=%c, fifo threshold=%d\n",
				cr23 * 4,
				(cr27 & 0x0f) ? 'A' - 1 + (cr27 & 0x0f) : '-',
				(cr26 & 0x0f) ? 'A' - 1 + (cr26 & 0x0f) : '-',
				cra & 0x0f);
		printk(KERN_INFO "SMSC LPT Config: enabled=%s power=%s\n",
		       (cr23 * 4 >= 0x100) ? "yes" : "no",
		       (cr1 & 4) ? "yes" : "no");
		printk(KERN_INFO
			"SMSC LPT Config: Port mode=%s, EPP version =%s\n",
				(cr1 & 0x08) ? "Standard mode only (SPP)"
					      : modes[cr4 & 0x03],
				(cr4 & 0x40) ? "1.7" : "1.9");
	}

	/* Heuristics !  BIOS setup for this mainboard device limits
	   the choices to standard settings, i.e. io-address and IRQ
	   are related, however DMA can be 1 or 3, assume DMA_A=DMA1,
	   DMA_C=DMA3 (this is true e.g. for TYAN 1564D Tomcat IV) */
	if (cr23 * 4 >= 0x100) { /* if active */
		s = find_free_superio();
		if (s == NULL)
			printk(KERN_INFO "Super-IO: too many chips!\n");
		else {
			int d;
			switch (cr23 * 4) {
			case 0x3bc:
				s->io = 0x3bc;
				s->irq = 7;
				break;
			case 0x378:
				s->io = 0x378;
				s->irq = 7;
				break;
			case 0x278:
				s->io = 0x278;
				s->irq = 5;
			}
			d = (cr26 & 0x0f);
			if (d == 1 || d == 3)
				s->dma = d;
			else
				s->dma = PARPORT_DMA_NONE;
		}
	}
}


static void show_parconfig_winbond(int io, int key)
{
	int cr30, cr60, cr61, cr70, cr74, crf0;
	struct superio_struct *s;
	static const char *const modes[] = {
		"Standard (SPP) and Bidirectional(PS/2)", /* 0 */
		"EPP-1.9 and SPP",
		"ECP",
		"ECP and EPP-1.9",
		"Standard (SPP)",
		"EPP-1.7 and SPP",		/* 5 */
		"undefined!",
		"ECP and EPP-1.7" };
	static char *const irqtypes[] = {
		"pulsed low, high-Z",
		"follows nACK" };

	/* The registers are called compatible-PnP because the
	   register layout is modelled after ISA-PnP, the access
	   method is just another ... */
	outb(key, io);
	outb(key, io);
	outb(0x07, io);   /* Register 7: Select Logical Device */
	outb(0x01, io + 1); /* LD1 is Parallel Port */
	outb(0x30, io);
	cr30 = inb(io + 1);
	outb(0x60, io);
	cr60 = inb(io + 1);
	outb(0x61, io);
	cr61 = inb(io + 1);
	outb(0x70, io);
	cr70 = inb(io + 1);
	outb(0x74, io);
	cr74 = inb(io + 1);
	outb(0xf0, io);
	crf0 = inb(io + 1);
	outb(0xaa, io);

	if (verbose_probing) {
		printk(KERN_INFO
    "Winbond LPT Config: cr_30=%02x 60,61=%02x%02x 70=%02x 74=%02x, f0=%02x\n",
					cr30, cr60, cr61, cr70, cr74, crf0);
		printk(KERN_INFO "Winbond LPT Config: active=%s, io=0x%02x%02x irq=%d, ",
		       (cr30 & 0x01) ? "yes" : "no", cr60, cr61, cr70 & 0x0f);
		if ((cr74 & 0x07) > 3)
			pr_cont("dma=none\n");
		else
			pr_cont("dma=%d\n", cr74 & 0x07);
		printk(KERN_INFO
		    "Winbond LPT Config: irqtype=%s, ECP fifo threshold=%d\n",
					irqtypes[crf0>>7], (crf0>>3)&0x0f);
		printk(KERN_INFO "Winbond LPT Config: Port mode=%s\n",
					modes[crf0 & 0x07]);
	}

	if (cr30 & 0x01) { /* the settings can be interrogated later ... */
		s = find_free_superio();
		if (s == NULL)
			printk(KERN_INFO "Super-IO: too many chips!\n");
		else {
			s->io = (cr60 << 8) | cr61;
			s->irq = cr70 & 0x0f;
			s->dma = (((cr74 & 0x07) > 3) ?
					   PARPORT_DMA_NONE : (cr74 & 0x07));
		}
	}
}

static void decode_winbond(int efer, int key, int devid, int devrev, int oldid)
{
	const char *type = "unknown";
	int id, progif = 2;

	if (devid == devrev)
		/* simple heuristics, we happened to read some
		   non-winbond register */
		return;

	id = (devid << 8) | devrev;

	/* Values are from public data sheets pdf files, I can just
	   confirm 83977TF is correct :-) */
	if (id == 0x9771)
		type = "83977F/AF";
	else if (id == 0x9773)
		type = "83977TF / SMSC 97w33x/97w34x";
	else if (id == 0x9774)
		type = "83977ATF";
	else if ((id & ~0x0f) == 0x5270)
		type = "83977CTF / SMSC 97w36x";
	else if ((id & ~0x0f) == 0x52f0)
		type = "83977EF / SMSC 97w35x";
	else if ((id & ~0x0f) == 0x5210)
		type = "83627";
	else if ((id & ~0x0f) == 0x6010)
		type = "83697HF";
	else if ((oldid & 0x0f) == 0x0a) {
		type = "83877F";
		progif = 1;
	} else if ((oldid & 0x0f) == 0x0b) {
		type = "83877AF";
		progif = 1;
	} else if ((oldid & 0x0f) == 0x0c) {
		type = "83877TF";
		progif = 1;
	} else if ((oldid & 0x0f) == 0x0d) {
		type = "83877ATF";
		progif = 1;
	} else
		progif = 0;

	if (verbose_probing)
		printk(KERN_INFO "Winbond chip at EFER=0x%x key=0x%02x "
		       "devid=%02x devrev=%02x oldid=%02x type=%s\n",
		       efer, key, devid, devrev, oldid, type);

	if (progif == 2)
		show_parconfig_winbond(efer, key);
}

static void decode_smsc(int efer, int key, int devid, int devrev)
{
	const char *type = "unknown";
	void (*func)(int io, int key);
	int id;

	if (devid == devrev)
		/* simple heuristics, we happened to read some
		   non-smsc register */
		return;

	func = NULL;
	id = (devid << 8) | devrev;

	if (id == 0x0302) {
		type = "37c669";
		func = show_parconfig_smsc37c669;
	} else if (id == 0x6582)
		type = "37c665IR";
	else if	(devid == 0x65)
		type = "37c665GT";
	else if	(devid == 0x66)
		type = "37c666GT";

	if (verbose_probing)
		printk(KERN_INFO "SMSC chip at EFER=0x%x "
		       "key=0x%02x devid=%02x devrev=%02x type=%s\n",
		       efer, key, devid, devrev, type);

	if (func)
		func(efer, key);
}


static void winbond_check(int io, int key)
{
	int origval, devid, devrev, oldid, x_devid, x_devrev, x_oldid;

	if (!request_region(io, 3, __func__))
		return;

	origval = inb(io); /* Save original value */

	/* First probe without key */
	outb(0x20, io);
	x_devid = inb(io + 1);
	outb(0x21, io);
	x_devrev = inb(io + 1);
	outb(0x09, io);
	x_oldid = inb(io + 1);

	outb(key, io);
	outb(key, io);     /* Write Magic Sequence to EFER, extended
			      function enable register */
	outb(0x20, io);    /* Write EFIR, extended function index register */
	devid = inb(io + 1);  /* Read EFDR, extended function data register */
	outb(0x21, io);
	devrev = inb(io + 1);
	outb(0x09, io);
	oldid = inb(io + 1);
	outb(0xaa, io);    /* Magic Seal */

	outb(origval, io); /* in case we poked some entirely different hardware */

	if ((x_devid == devid) && (x_devrev == devrev) && (x_oldid == oldid))
		goto out; /* protection against false positives */

	decode_winbond(io, key, devid, devrev, oldid);
out:
	release_region(io, 3);
}

static void winbond_check2(int io, int key)
{
	int origval[3], devid, devrev, oldid, x_devid, x_devrev, x_oldid;

	if (!request_region(io, 3, __func__))
		return;

	origval[0] = inb(io); /* Save original values */
	origval[1] = inb(io + 1);
	origval[2] = inb(io + 2);

	/* First probe without the key */
	outb(0x20, io + 2);
	x_devid = inb(io + 2);
	outb(0x21, io + 1);
	x_devrev = inb(io + 2);
	outb(0x09, io + 1);
	x_oldid = inb(io + 2);

	outb(key, io);     /* Write Magic Byte to EFER, extended
			      function enable register */
	outb(0x20, io + 2);  /* Write EFIR, extended function index register */
	devid = inb(io + 2);  /* Read EFDR, extended function data register */
	outb(0x21, io + 1);
	devrev = inb(io + 2);
	outb(0x09, io + 1);
	oldid = inb(io + 2);
	outb(0xaa, io);    /* Magic Seal */

	outb(origval[0], io); /* in case we poked some entirely different hardware */
	outb(origval[1], io + 1);
	outb(origval[2], io + 2);

	if (x_devid == devid && x_devrev == devrev && x_oldid == oldid)
		goto out; /* protection against false positives */

	decode_winbond(io, key, devid, devrev, oldid);
out:
	release_region(io, 3);
}

static void smsc_check(int io, int key)
{
	int origval, id, rev, oldid, oldrev, x_id, x_rev, x_oldid, x_oldrev;

	if (!request_region(io, 3, __func__))
		return;

	origval = inb(io); /* Save original value */

	/* First probe without the key */
	outb(0x0d, io);
	x_oldid = inb(io + 1);
	outb(0x0e, io);
	x_oldrev = inb(io + 1);
	outb(0x20, io);
	x_id = inb(io + 1);
	outb(0x21, io);
	x_rev = inb(io + 1);

	outb(key, io);
	outb(key, io);     /* Write Magic Sequence to EFER, extended
			      function enable register */
	outb(0x0d, io);    /* Write EFIR, extended function index register */
	oldid = inb(io + 1);  /* Read EFDR, extended function data register */
	outb(0x0e, io);
	oldrev = inb(io + 1);
	outb(0x20, io);
	id = inb(io + 1);
	outb(0x21, io);
	rev = inb(io + 1);
	outb(0xaa, io);    /* Magic Seal */

	outb(origval, io); /* in case we poked some entirely different hardware */

	if (x_id == id && x_oldrev == oldrev &&
	    x_oldid == oldid && x_rev == rev)
		goto out; /* protection against false positives */

	decode_smsc(io, key, oldid, oldrev);
out:
	release_region(io, 3);
}


static void detect_and_report_winbond(void)
{
	if (verbose_probing)
		printk(KERN_DEBUG "Winbond Super-IO detection, now testing ports 3F0,370,250,4E,2E ...\n");
	winbond_check(0x3f0, 0x87);
	winbond_check(0x370, 0x87);
	winbond_check(0x2e , 0x87);
	winbond_check(0x4e , 0x87);
	winbond_check(0x3f0, 0x86);
	winbond_check2(0x250, 0x88);
	winbond_check2(0x250, 0x89);
}

static void detect_and_report_smsc(void)
{
	if (verbose_probing)
		printk(KERN_DEBUG "SMSC Super-IO detection, now testing Ports 2F0, 370 ...\n");
	smsc_check(0x3f0, 0x55);
	smsc_check(0x370, 0x55);
	smsc_check(0x3f0, 0x44);
	smsc_check(0x370, 0x44);
}

static void detect_and_report_it87(void)
{
	u16 dev;
	u8 origval, r;
	if (verbose_probing)
		printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n");
	if (!request_muxed_region(0x2e, 2, __func__))
		return;
	origval = inb(0x2e);		/* Save original value */
	outb(0x87, 0x2e);
	outb(0x01, 0x2e);
	outb(0x55, 0x2e);
	outb(0x55, 0x2e);
	outb(0x20, 0x2e);
	dev = inb(0x2f) << 8;
	outb(0x21, 0x2e);
	dev |= inb(0x2f);
	if (dev == 0x8712 || dev == 0x8705 || dev == 0x8715 ||
	    dev == 0x8716 || dev == 0x8718 || dev == 0x8726) {
		printk(KERN_INFO "IT%04X SuperIO detected.\n", dev);
		outb(0x07, 0x2E);	/* Parallel Port */
		outb(0x03, 0x2F);
		outb(0xF0, 0x2E);	/* BOOT 0x80 off */
		r = inb(0x2f);
		outb(0xF0, 0x2E);
		outb(r | 8, 0x2F);
		outb(0x02, 0x2E);	/* Lock */
		outb(0x02, 0x2F);
	} else {
		outb(origval, 0x2e);	/* Oops, sorry to disturb */
	}
	release_region(0x2e, 2);
}
#endif /* CONFIG_PARPORT_PC_SUPERIO */

static struct superio_struct *find_superio(struct parport *p)
{
	int i;
	for (i = 0; i < NR_SUPERIOS; i++)
		if (superios[i].io != p->base)
			return &superios[i];
	return NULL;
}

static int get_superio_dma(struct parport *p)
{
	struct superio_struct *s = find_superio(p);
	if (s)
		return s->dma;
	return PARPORT_DMA_NONE;
}

static int get_superio_irq(struct parport *p)
{
	struct superio_struct *s = find_superio(p);
	if (s)
		return s->irq;
	return PARPORT_IRQ_NONE;
}


/* --- Mode detection ------------------------------------- */

/*
 * Checks for port existence, all ports support SPP MODE
 * Returns:
 *         0           :  No parallel port at this address
 *  PARPORT_MODE_PCSPP :  SPP port detected
 *                        (if the user specified an ioport himself,
 *                         this shall always be the case!)
 *
 */
static int parport_SPP_supported(struct parport *pb)
{
	unsigned char r, w;

	/*
	 * first clear an eventually pending EPP timeout
	 * I (sailer@ife.ee.ethz.ch) have an SMSC chipset
	 * that does not even respond to SPP cycles if an EPP
	 * timeout is pending
	 */
	clear_epp_timeout(pb);

	/* Do a simple read-write test to make sure the port exists. */
	w = 0xc;
	outb(w, CONTROL(pb));

	/* Is there a control register that we can read from?  Some
	 * ports don't allow reads, so read_control just returns a
	 * software copy. Some ports _do_ allow reads, so bypass the
	 * software copy here.  In addition, some bits aren't
	 * writable. */
	r = inb(CONTROL(pb));
	if ((r & 0xf) == w) {
		w = 0xe;
		outb(w, CONTROL(pb));
		r = inb(CONTROL(pb));
		outb(0xc, CONTROL(pb));
		if ((r & 0xf) == w)
			return PARPORT_MODE_PCSPP;
	}

	if (user_specified)
		/* That didn't work, but the user thinks there's a
		 * port here. */
		printk(KERN_INFO "parport 0x%lx (WARNING): CTR: "
			"wrote 0x%02x, read 0x%02x\n", pb->base, w, r);

	/* Try the data register.  The data lines aren't tri-stated at
	 * this stage, so we expect back what we wrote. */
	w = 0xaa;
	parport_pc_write_data(pb, w);
	r = parport_pc_read_data(pb);
	if (r == w) {
		w = 0x55;
		parport_pc_write_data(pb, w);
		r = parport_pc_read_data(pb);
		if (r == w)
			return PARPORT_MODE_PCSPP;
	}

	if (user_specified) {
		/* Didn't work, but the user is convinced this is the
		 * place. */
		printk(KERN_INFO "parport 0x%lx (WARNING): DATA: "
			"wrote 0x%02x, read 0x%02x\n", pb->base, w, r);
		printk(KERN_INFO "parport 0x%lx: You gave this address, "
			"but there is probably no parallel port there!\n",
			pb->base);
	}

	/* It's possible that we can't read the control register or
	 * the data register.  In that case just believe the user. */
	if (user_specified)
		return PARPORT_MODE_PCSPP;

	return 0;
}

/* Check for ECR
 *
 * Old style XT ports alias io ports every 0x400, hence accessing ECR
 * on these cards actually accesses the CTR.
 *
 * Modern cards don't do this but reading from ECR will return 0xff
 * regardless of what is written here if the card does NOT support
 * ECP.
 *
 * We first check to see if ECR is the same as CTR.  If not, the low
 * two bits of ECR aren't writable, so we check by writing ECR and
 * reading it back to see if it's what we expect.
 */
static int parport_ECR_present(struct parport *pb)
{
	struct parport_pc_private *priv = pb->private_data;
	unsigned char r = 0xc;

	outb(r, CONTROL(pb));
	if ((inb(ECONTROL(pb)) & 0x3) == (r & 0x3)) {
		outb(r ^ 0x2, CONTROL(pb)); /* Toggle bit 1 */

		r = inb(CONTROL(pb));
		if ((inb(ECONTROL(pb)) & 0x2) == (r & 0x2))
			goto no_reg; /* Sure that no ECR register exists */
	}

	if ((inb(ECONTROL(pb)) & 0x3) != 0x1)
		goto no_reg;

	ECR_WRITE(pb, 0x34);
	if (inb(ECONTROL(pb)) != 0x35)
		goto no_reg;

	priv->ecr = 1;
	outb(0xc, CONTROL(pb));

	/* Go to mode 000 */
	frob_set_mode(pb, ECR_SPP);

	return 1;

 no_reg:
	outb(0xc, CONTROL(pb));
	return 0;
}

#ifdef CONFIG_PARPORT_1284
/* Detect PS/2 support.
 *
 * Bit 5 (0x20) sets the PS/2 data direction; setting this high
 * allows us to read data from the data lines.  In theory we would get back
 * 0xff but any peripheral attached to the port may drag some or all of the
 * lines down to zero.  So if we get back anything that isn't the contents
 * of the data register we deem PS/2 support to be present.
 *
 * Some SPP ports have "half PS/2" ability - you can't turn off the line
 * drivers, but an external peripheral with sufficiently beefy drivers of
 * its own can overpower them and assert its own levels onto the bus, from
 * where they can then be read back as normal.  Ports with this property
 * and the right type of device attached are likely to fail the SPP test,
 * (as they will appear to have stuck bits) and so the fact that they might
 * be misdetected here is rather academic.
 */

static int parport_PS2_supported(struct parport *pb)
{
	int ok = 0;

	clear_epp_timeout(pb);

	/* try to tri-state the buffer */
	parport_pc_data_reverse(pb);

	parport_pc_write_data(pb, 0x55);
	if (parport_pc_read_data(pb) != 0x55)
		ok++;

	parport_pc_write_data(pb, 0xaa);
	if (parport_pc_read_data(pb) != 0xaa)
		ok++;

	/* cancel input mode */
	parport_pc_data_forward(pb);

	if (ok) {
		pb->modes |= PARPORT_MODE_TRISTATE;
	} else {
		struct parport_pc_private *priv = pb->private_data;
		priv->ctr_writable &= ~0x20;
	}

	return ok;
}

#ifdef CONFIG_PARPORT_PC_FIFO
static int parport_ECP_supported(struct parport *pb)
{
	int i;
	int config, configb;
	int pword;
	struct parport_pc_private *priv = pb->private_data;
	/* Translate ECP intrLine to ISA irq value */
	static const int intrline[] = { 0, 7, 9, 10, 11, 14, 15, 5 };

	/* If there is no ECR, we have no hope of supporting ECP. */
	if (!priv->ecr)
		return 0;

	/* Find out FIFO depth */
	ECR_WRITE(pb, ECR_SPP << 5); /* Reset FIFO */
	ECR_WRITE(pb, ECR_TST << 5); /* TEST FIFO */
	for (i = 0; i < 1024 && !(inb(ECONTROL(pb)) & 0x02); i++)
		outb(0xaa, FIFO(pb));

	/*
	 * Using LGS chipset it uses ECR register, but
	 * it doesn't support ECP or FIFO MODE
	 */
	if (i == 1024) {
		ECR_WRITE(pb, ECR_SPP << 5);
		return 0;
	}

	priv->fifo_depth = i;
	if (verbose_probing)
		printk(KERN_DEBUG "0x%lx: FIFO is %d bytes\n", pb->base, i);

	/* Find out writeIntrThreshold */
	frob_econtrol(pb, 1<<2, 1<<2);
	frob_econtrol(pb, 1<<2, 0);
	for (i = 1; i <= priv->fifo_depth; i++) {
		inb(FIFO(pb));
		udelay(50);
		if (inb(ECONTROL(pb)) & (1<<2))
			break;
	}

	if (i <= priv->fifo_depth) {
		if (verbose_probing)
			printk(KERN_DEBUG "0x%lx: writeIntrThreshold is %d\n",
				pb->base, i);
	} else
		/* Number of bytes we know we can write if we get an
		   interrupt. */
		i = 0;

	priv->writeIntrThreshold = i;

	/* Find out readIntrThreshold */
	frob_set_mode(pb, ECR_PS2); /* Reset FIFO and enable PS2 */
	parport_pc_data_reverse(pb); /* Must be in PS2 mode */
	frob_set_mode(pb, ECR_TST); /* Test FIFO */
	frob_econtrol(pb, 1<<2, 1<<2);
	frob_econtrol(pb, 1<<2, 0);
	for (i = 1; i <= priv->fifo_depth; i++) {
		outb(0xaa, FIFO(pb));
		if (inb(ECONTROL(pb)) & (1<<2))
			break;
	}

	if (i <= priv->fifo_depth) {
		if (verbose_probing)
			printk(KERN_INFO "0x%lx: readIntrThreshold is %d\n",
				pb->base, i);
	} else
		/* Number of bytes we can read if we get an interrupt. */
		i = 0;

	priv->readIntrThreshold = i;

	ECR_WRITE(pb, ECR_SPP << 5); /* Reset FIFO */
	ECR_WRITE(pb, 0xf4); /* Configuration mode */
	config = inb(CONFIGA(pb));
	pword = (config >> 4) & 0x7;
	switch (pword) {
	case 0:
		pword = 2;
		printk(KERN_WARNING "0x%lx: Unsupported pword size!\n",
			pb->base);
		break;
	case 2:
		pword = 4;
		printk(KERN_WARNING "0x%lx: Unsupported pword size!\n",
			pb->base);
		break;
	default:
		printk(KERN_WARNING "0x%lx: Unknown implementation ID\n",
			pb->base);
		/* Fall through - Assume 1 */
	case 1:
		pword = 1;
	}
	priv->pword = pword;

	if (verbose_probing) {
		printk(KERN_DEBUG "0x%lx: PWord is %d bits\n",
			pb->base, 8 * pword);

		printk(KERN_DEBUG "0x%lx: Interrupts are ISA-%s\n", pb->base,
			config & 0x80 ? "Level" : "Pulses");

		configb = inb(CONFIGB(pb));
		printk(KERN_DEBUG "0x%lx: ECP port cfgA=0x%02x cfgB=0x%02x\n",
			pb->base, config, configb);
		printk(KERN_DEBUG "0x%lx: ECP settings irq=", pb->base);
		if ((configb >> 3) & 0x07)
			pr_cont("%d", intrline[(configb >> 3) & 0x07]);
		else
			pr_cont("<none or set by other means>");
		pr_cont(" dma=");
		if ((configb & 0x03) == 0x00)
			pr_cont("<none or set by other means>\n");
		else
			pr_cont("%d\n", configb & 0x07);
	}

	/* Go back to mode 000 */
	frob_set_mode(pb, ECR_SPP);

	return 1;
}
#endif

#ifdef CONFIG_X86_32
static int intel_bug_present_check_epp(struct parport *pb)
{
	const struct parport_pc_private *priv = pb->private_data;
	int bug_present = 0;

	if (priv->ecr) {
		/* store value of ECR */
		unsigned char ecr = inb(ECONTROL(pb));
		unsigned char i;
		for (i = 0x00; i < 0x80; i += 0x20) {
			ECR_WRITE(pb, i);
			if (clear_epp_timeout(pb)) {
				/* Phony EPP in ECP. */
				bug_present = 1;
				break;
			}
		}
		/* return ECR into the inital state */
		ECR_WRITE(pb, ecr);
	}

	return bug_present;
}
static int intel_bug_present(struct parport *pb)
{
/* Check whether the device is legacy, not PCI or PCMCIA. Only legacy is known to be affected. */
	if (pb->dev != NULL) {
		return 0;
	}

	return intel_bug_present_check_epp(pb);
}
#else
static int intel_bug_present(struct parport *pb)
{
	return 0;
}
#endif /* CONFIG_X86_32 */

static int parport_ECPPS2_supported(struct parport *pb)
{
	const struct parport_pc_private *priv = pb->private_data;
	int result;
	unsigned char oecr;

	if (!priv->ecr)
		return 0;

	oecr = inb(ECONTROL(pb));
	ECR_WRITE(pb, ECR_PS2 << 5);
	result = parport_PS2_supported(pb);
	ECR_WRITE(pb, oecr);
	return result;
}

/* EPP mode detection  */

static int parport_EPP_supported(struct parport *pb)
{
	/*
	 * Theory:
	 *	Bit 0 of STR is the EPP timeout bit, this bit is 0
	 *	when EPP is possible and is set high when an EPP timeout
	 *	occurs (EPP uses the HALT line to stop the CPU while it does
	 *	the byte transfer, an EPP timeout occurs if the attached
	 *	device fails to respond after 10 micro seconds).
	 *
	 *	This bit is cleared by either reading it (National Semi)
	 *	or writing a 1 to the bit (SMC, UMC, WinBond), others ???
	 *	This bit is always high in non EPP modes.
	 */

	/* If EPP timeout bit clear then EPP available */
	if (!clear_epp_timeout(pb))
		return 0;  /* No way to clear timeout */

	/* Check for Intel bug. */
	if (intel_bug_present(pb))
		return 0;

	pb->modes |= PARPORT_MODE_EPP;

	/* Set up access functions to use EPP hardware. */
	pb->ops->epp_read_data = parport_pc_epp_read_data;
	pb->ops->epp_write_data = parport_pc_epp_write_data;
	pb->ops->epp_read_addr = parport_pc_epp_read_addr;
	pb->ops->epp_write_addr = parport_pc_epp_write_addr;

	return 1;
}

static int parport_ECPEPP_supported(struct parport *pb)
{
	struct parport_pc_private *priv = pb->private_data;
	int result;
	unsigned char oecr;

	if (!priv->ecr)
		return 0;

	oecr = inb(ECONTROL(pb));
	/* Search for SMC style EPP+ECP mode */
	ECR_WRITE(pb, 0x80);
	outb(0x04, CONTROL(pb));
	result = parport_EPP_supported(pb);

	ECR_WRITE(pb, oecr);

	if (result) {
		/* Set up access functions to use ECP+EPP hardware. */
		pb->ops->epp_read_data = parport_pc_ecpepp_read_data;
		pb->ops->epp_write_data = parport_pc_ecpepp_write_data;
		pb->ops->epp_read_addr = parport_pc_ecpepp_read_addr;
		pb->ops->epp_write_addr = parport_pc_ecpepp_write_addr;
	}

	return result;
}

#else /* No IEEE 1284 support */

/* Don't bother probing for modes we know we won't use. */
static int parport_PS2_supported(struct parport *pb) { return 0; }
#ifdef CONFIG_PARPORT_PC_FIFO
static int parport_ECP_supported(struct parport *pb)
{
	return 0;
}
#endif
static int parport_EPP_supported(struct parport *pb)
{
	return 0;
}

static int parport_ECPEPP_supported(struct parport *pb)
{
	return 0;
}

static int parport_ECPPS2_supported(struct parport *pb)
{
	return 0;
}

#endif /* No IEEE 1284 support */

/* --- IRQ detection -------------------------------------- */

/* Only if supports ECP mode */
static int programmable_irq_support(struct parport *pb)
{
	int irq, intrLine;
	unsigned char oecr = inb(ECONTROL(pb));
	static const int lookup[8] = {
		PARPORT_IRQ_NONE, 7, 9, 10, 11, 14, 15, 5
	};

	ECR_WRITE(pb, ECR_CNF << 5); /* Configuration MODE */

	intrLine = (inb(CONFIGB(pb)) >> 3) & 0x07;
	irq = lookup[intrLine];

	ECR_WRITE(pb, oecr);
	return irq;
}

static int irq_probe_ECP(struct parport *pb)
{
	int i;
	unsigned long irqs;

	irqs = probe_irq_on();

	ECR_WRITE(pb, ECR_SPP << 5); /* Reset FIFO */
	ECR_WRITE(pb, (ECR_TST << 5) | 0x04);
	ECR_WRITE(pb, ECR_TST << 5);

	/* If Full FIFO sure that writeIntrThreshold is generated */
	for (i = 0; i < 1024 && !(inb(ECONTROL(pb)) & 0x02) ; i++)
		outb(0xaa, FIFO(pb));

	pb->irq = probe_irq_off(irqs);
	ECR_WRITE(pb, ECR_SPP << 5);

	if (pb->irq <= 0)
		pb->irq = PARPORT_IRQ_NONE;

	return pb->irq;
}

/*
 * This detection seems that only works in National Semiconductors
 * This doesn't work in SMC, LGS, and Winbond
 */
static int irq_probe_EPP(struct parport *pb)
{
#ifndef ADVANCED_DETECT
	return PARPORT_IRQ_NONE;
#else
	int irqs;
	unsigned char oecr;

	if (pb->modes & PARPORT_MODE_PCECR)
		oecr = inb(ECONTROL(pb));

	irqs = probe_irq_on();

	if (pb->modes & PARPORT_MODE_PCECR)
		frob_econtrol(pb, 0x10, 0x10);

	clear_epp_timeout(pb);
	parport_pc_frob_control(pb, 0x20, 0x20);
	parport_pc_frob_control(pb, 0x10, 0x10);
	clear_epp_timeout(pb);

	/* Device isn't expecting an EPP read
	 * and generates an IRQ.
	 */
	parport_pc_read_epp(pb);
	udelay(20);

	pb->irq = probe_irq_off(irqs);
	if (pb->modes & PARPORT_MODE_PCECR)
		ECR_WRITE(pb, oecr);
	parport_pc_write_control(pb, 0xc);

	if (pb->irq <= 0)
		pb->irq = PARPORT_IRQ_NONE;

	return pb->irq;
#endif /* Advanced detection */
}

static int irq_probe_SPP(struct parport *pb)
{
	/* Don't even try to do this. */
	return PARPORT_IRQ_NONE;
}

/* We will attempt to share interrupt requests since other devices
 * such as sound cards and network cards seem to like using the
 * printer IRQs.
 *
 * When ECP is available we can autoprobe for IRQs.
 * NOTE: If we can autoprobe it, we can register the IRQ.
 */
static int parport_irq_probe(struct parport *pb)
{
	struct parport_pc_private *priv = pb->private_data;

	if (priv->ecr) {
		pb->irq = programmable_irq_support(pb);

		if (pb->irq == PARPORT_IRQ_NONE)
			pb->irq = irq_probe_ECP(pb);
	}

	if ((pb->irq == PARPORT_IRQ_NONE) && priv->ecr &&
	    (pb->modes & PARPORT_MODE_EPP))
		pb->irq = irq_probe_EPP(pb);

	clear_epp_timeout(pb);

	if (pb->irq == PARPORT_IRQ_NONE && (pb->modes & PARPORT_MODE_EPP))
		pb->irq = irq_probe_EPP(pb);

	clear_epp_timeout(pb);

	if (pb->irq == PARPORT_IRQ_NONE)
		pb->irq = irq_probe_SPP(pb);

	if (pb->irq == PARPORT_IRQ_NONE)
		pb->irq = get_superio_irq(pb);

	return pb->irq;
}

/* --- DMA detection -------------------------------------- */

/* Only if chipset conforms to ECP ISA Interface Standard */
static int programmable_dma_support(struct parport *p)
{
	unsigned char oecr = inb(ECONTROL(p));
	int dma;

	frob_set_mode(p, ECR_CNF);

	dma = inb(CONFIGB(p)) & 0x07;
	/* 000: Indicates jumpered 8-bit DMA if read-only.
	   100: Indicates jumpered 16-bit DMA if read-only. */
	if ((dma & 0x03) == 0)
		dma = PARPORT_DMA_NONE;

	ECR_WRITE(p, oecr);
	return dma;
}

static int parport_dma_probe(struct parport *p)
{
	const struct parport_pc_private *priv = p->private_data;
	if (priv->ecr)		/* ask ECP chipset first */
		p->dma = programmable_dma_support(p);
	if (p->dma == PARPORT_DMA_NONE) {
		/* ask known Super-IO chips proper, although these
		   claim ECP compatible, some don't report their DMA
		   conforming to ECP standards */
		p->dma = get_superio_dma(p);
	}

	return p->dma;
}

/* --- Initialisation code -------------------------------- */

static LIST_HEAD(ports_list);
static DEFINE_SPINLOCK(ports_lock);

struct parport *parport_pc_probe_port(unsigned long int base,
				      unsigned long int base_hi,
				      int irq, int dma,
				      struct device *dev,
				      int irqflags)
{
	struct parport_pc_private *priv;
	struct parport_operations *ops;
	struct parport *p;
	int probedirq = PARPORT_IRQ_NONE;
	struct resource *base_res;
	struct resource	*ECR_res = NULL;
	struct resource	*EPP_res = NULL;
	struct platform_device *pdev = NULL;
	int ret;

	if (!dev) {
		/* We need a physical device to attach to, but none was
		 * provided. Create our own. */
		pdev = platform_device_register_simple("parport_pc",
						       base, NULL, 0);
		if (IS_ERR(pdev))
			return NULL;
		dev = &pdev->dev;

		ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(24));
		if (ret) {
			dev_err(dev, "Unable to set coherent dma mask: disabling DMA\n");
			dma = PARPORT_DMA_NONE;
		}
	}

	ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL);
	if (!ops)
		goto out1;

	priv = kmalloc(sizeof(struct parport_pc_private), GFP_KERNEL);
	if (!priv)
		goto out2;

	/* a misnomer, actually - it's allocate and reserve parport number */
	p = parport_register_port(base, irq, dma, ops);
	if (!p)
		goto out3;

	base_res = request_region(base, 3, p->name);
	if (!base_res)
		goto out4;

	memcpy(ops, &parport_pc_ops, sizeof(struct parport_operations));
	priv->ctr = 0xc;
	priv->ctr_writable = ~0x10;
	priv->ecr = 0;
	priv->fifo_depth = 0;
	priv->dma_buf = NULL;
	priv->dma_handle = 0;
	INIT_LIST_HEAD(&priv->list);
	priv->port = p;

	p->dev = dev;
	p->base_hi = base_hi;
	p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT;
	p->private_data = priv;

	if (base_hi) {
		ECR_res = request_region(base_hi, 3, p->name);
		if (ECR_res)
			parport_ECR_present(p);
	}

	if (base != 0x3bc) {
		EPP_res = request_region(base+0x3, 5, p->name);
		if (EPP_res)
			if (!parport_EPP_supported(p))
				parport_ECPEPP_supported(p);
	}
	if (!parport_SPP_supported(p))
		/* No port. */
		goto out5;
	if (priv->ecr)
		parport_ECPPS2_supported(p);
	else
		parport_PS2_supported(p);

	p->size = (p->modes & PARPORT_MODE_EPP) ? 8 : 3;

	printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base);
	if (p->base_hi && priv->ecr)
		printk(KERN_CONT " (0x%lx)", p->base_hi);
	if (p->irq == PARPORT_IRQ_AUTO) {
		p->irq = PARPORT_IRQ_NONE;
		parport_irq_probe(p);
	} else if (p->irq == PARPORT_IRQ_PROBEONLY) {
		p->irq = PARPORT_IRQ_NONE;
		parport_irq_probe(p);
		probedirq = p->irq;
		p->irq = PARPORT_IRQ_NONE;
	}
	if (p->irq != PARPORT_IRQ_NONE) {
		printk(KERN_CONT ", irq %d", p->irq);
		priv->ctr_writable |= 0x10;

		if (p->dma == PARPORT_DMA_AUTO) {
			p->dma = PARPORT_DMA_NONE;
			parport_dma_probe(p);
		}
	}
	if (p->dma == PARPORT_DMA_AUTO) /* To use DMA, giving the irq
					   is mandatory (see above) */
		p->dma = PARPORT_DMA_NONE;

#ifdef CONFIG_PARPORT_PC_FIFO
	if (parport_ECP_supported(p) &&
	    p->dma != PARPORT_DMA_NOFIFO &&
	    priv->fifo_depth > 0 && p->irq != PARPORT_IRQ_NONE) {
		p->modes |= PARPORT_MODE_ECP | PARPORT_MODE_COMPAT;
		p->ops->compat_write_data = parport_pc_compat_write_block_pio;
#ifdef CONFIG_PARPORT_1284
		p->ops->ecp_write_data = parport_pc_ecp_write_block_pio;
		/* currently broken, but working on it.. (FB) */
		/* p->ops->ecp_read_data = parport_pc_ecp_read_block_pio; */
#endif /* IEEE 1284 support */
		if (p->dma != PARPORT_DMA_NONE) {
			printk(KERN_CONT ", dma %d", p->dma);
			p->modes |= PARPORT_MODE_DMA;
		} else
			printk(KERN_CONT ", using FIFO");
	} else
		/* We can't use the DMA channel after all. */
		p->dma = PARPORT_DMA_NONE;
#endif /* Allowed to use FIFO/DMA */

	printk(KERN_CONT " [");

#define printmode(x) \
	{\
		if (p->modes & PARPORT_MODE_##x) {\
			printk(KERN_CONT "%s%s", f ? "," : "", #x);\
			f++;\
		} \
	}

	{
		int f = 0;
		printmode(PCSPP);
		printmode(TRISTATE);
		printmode(COMPAT)
		printmode(EPP);
		printmode(ECP);
		printmode(DMA);
	}
#undef printmode
#ifndef CONFIG_PARPORT_1284
	printk(KERN_CONT "(,...)");
#endif /* CONFIG_PARPORT_1284 */
	printk(KERN_CONT "]\n");
	if (probedirq != PARPORT_IRQ_NONE)
		printk(KERN_INFO "%s: irq %d detected\n", p->name, probedirq);

	/* If No ECP release the ports grabbed above. */
	if (ECR_res && (p->modes & PARPORT_MODE_ECP) == 0) {
		release_region(base_hi, 3);
		ECR_res = NULL;
	}
	/* Likewise for EEP ports */
	if (EPP_res && (p->modes & PARPORT_MODE_EPP) == 0) {
		release_region(base+3, 5);
		EPP_res = NULL;
	}
	if (p->irq != PARPORT_IRQ_NONE) {
		if (request_irq(p->irq, parport_irq_handler,
				 irqflags, p->name, p)) {
			printk(KERN_WARNING "%s: irq %d in use, "
				"resorting to polled operation\n",
				p->name, p->irq);
			p->irq = PARPORT_IRQ_NONE;
			p->dma = PARPORT_DMA_NONE;
		}

#ifdef CONFIG_PARPORT_PC_FIFO
#ifdef HAS_DMA
		if (p->dma != PARPORT_DMA_NONE) {
			if (request_dma(p->dma, p->name)) {
				printk(KERN_WARNING "%s: dma %d in use, "
					"resorting to PIO operation\n",
					p->name, p->dma);
				p->dma = PARPORT_DMA_NONE;
			} else {
				priv->dma_buf =
				  dma_alloc_coherent(dev,
						       PAGE_SIZE,
						       &priv->dma_handle,
						       GFP_KERNEL);
				if (!priv->dma_buf) {
					printk(KERN_WARNING "%s: "
						"cannot get buffer for DMA, "
						"resorting to PIO operation\n",
						p->name);
					free_dma(p->dma);
					p->dma = PARPORT_DMA_NONE;
				}
			}
		}
#endif
#endif
	}

	/* Done probing.  Now put the port into a sensible start-up state. */
	if (priv->ecr)
		/*
		 * Put the ECP detected port in PS2 mode.
		 * Do this also for ports that have ECR but don't do ECP.
		 */
		ECR_WRITE(p, 0x34);

	parport_pc_write_data(p, 0);
	parport_pc_data_forward(p);

	/* Now that we've told the sharing engine about the port, and
	   found out its characteristics, let the high-level drivers
	   know about it. */
	spin_lock(&ports_lock);
	list_add(&priv->list, &ports_list);
	spin_unlock(&ports_lock);
	parport_announce_port(p);

	return p;

out5:
	if (ECR_res)
		release_region(base_hi, 3);
	if (EPP_res)
		release_region(base+0x3, 5);
	release_region(base, 3);
out4:
	parport_del_port(p);
out3:
	kfree(priv);
out2:
	kfree(ops);
out1:
	if (pdev)
		platform_device_unregister(pdev);
	return NULL;
}
EXPORT_SYMBOL(parport_pc_probe_port);

void parport_pc_unregister_port(struct parport *p)
{
	struct parport_pc_private *priv = p->private_data;
	struct parport_operations *ops = p->ops;

	parport_remove_port(p);
	spin_lock(&ports_lock);
	list_del_init(&priv->list);
	spin_unlock(&ports_lock);
#if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA)
	if (p->dma != PARPORT_DMA_NONE)
		free_dma(p->dma);
#endif
	if (p->irq != PARPORT_IRQ_NONE)
		free_irq(p->irq, p);
	release_region(p->base, 3);
	if (p->size > 3)
		release_region(p->base + 3, p->size - 3);
	if (p->modes & PARPORT_MODE_ECP)
		release_region(p->base_hi, 3);
#if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA)
	if (priv->dma_buf)
		dma_free_coherent(p->physport->dev, PAGE_SIZE,
				    priv->dma_buf,
				    priv->dma_handle);
#endif
	kfree(p->private_data);
	parport_del_port(p);
	kfree(ops); /* hope no-one cached it */
}
EXPORT_SYMBOL(parport_pc_unregister_port);

#ifdef CONFIG_PCI

/* ITE support maintained by Rich Liu <richliu@poorman.org> */
static int sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, int autodma,
			      const struct parport_pc_via_data *via)
{
	short inta_addr[6] = { 0x2A0, 0x2C0, 0x220, 0x240, 0x1E0 };
	u32 ite8872set;
	u32 ite8872_lpt, ite8872_lpthi;
	u8 ite8872_irq, type;
	int irq;
	int i;

	DPRINTK(KERN_DEBUG "sio_ite_8872_probe()\n");

	/* make sure which one chip */
	for (i = 0; i < 5; i++) {
		if (request_region(inta_addr[i], 32, "it887x")) {
			int test;
			pci_write_config_dword(pdev, 0x60,
						0xe5000000 | inta_addr[i]);
			pci_write_config_dword(pdev, 0x78,
						0x00000000 | inta_addr[i]);
			test = inb(inta_addr[i]);
			if (test != 0xff)
				break;
			release_region(inta_addr[i], 32);
		}
	}
	if (i >= 5) {
		printk(KERN_INFO "parport_pc: cannot find ITE8872 INTA\n");
		return 0;
	}

	type = inb(inta_addr[i] + 0x18);
	type &= 0x0f;

	switch (type) {
	case 0x2:
		printk(KERN_INFO "parport_pc: ITE8871 found (1P)\n");
		ite8872set = 0x64200000;
		break;
	case 0xa:
		printk(KERN_INFO "parport_pc: ITE8875 found (1P)\n");
		ite8872set = 0x64200000;
		break;
	case 0xe:
		printk(KERN_INFO "parport_pc: ITE8872 found (2S1P)\n");
		ite8872set = 0x64e00000;
		break;
	case 0x6:
		printk(KERN_INFO "parport_pc: ITE8873 found (1S)\n");
		release_region(inta_addr[i], 32);
		return 0;
	case 0x8:
		printk(KERN_INFO "parport_pc: ITE8874 found (2S)\n");
		release_region(inta_addr[i], 32);
		return 0;
	default:
		printk(KERN_INFO "parport_pc: unknown ITE887x\n");
		printk(KERN_INFO "parport_pc: please mail 'lspci -nvv' "
			"output to Rich.Liu@ite.com.tw\n");
		release_region(inta_addr[i], 32);
		return 0;
	}

	pci_read_config_byte(pdev, 0x3c, &ite8872_irq);
	pci_read_config_dword(pdev, 0x1c, &ite8872_lpt);
	ite8872_lpt &= 0x0000ff00;
	pci_read_config_dword(pdev, 0x20, &ite8872_lpthi);
	ite8872_lpthi &= 0x0000ff00;
	pci_write_config_dword(pdev, 0x6c, 0xe3000000 | ite8872_lpt);
	pci_write_config_dword(pdev, 0x70, 0xe3000000 | ite8872_lpthi);
	pci_write_config_dword(pdev, 0x80, (ite8872_lpthi<<16) | ite8872_lpt);
	/* SET SPP&EPP , Parallel Port NO DMA , Enable All Function */
	/* SET Parallel IRQ */
	pci_write_config_dword(pdev, 0x9c,
				ite8872set | (ite8872_irq * 0x11111));

	DPRINTK(KERN_DEBUG "ITE887x: The IRQ is %d.\n", ite8872_irq);
	DPRINTK(KERN_DEBUG "ITE887x: The PARALLEL I/O port is 0x%x.\n",
		 ite8872_lpt);
	DPRINTK(KERN_DEBUG "ITE887x: The PARALLEL I/O porthi is 0x%x.\n",
		 ite8872_lpthi);

	/* Let the user (or defaults) steer us away from interrupts */
	irq = ite8872_irq;
	if (autoirq != PARPORT_IRQ_AUTO)
		irq = PARPORT_IRQ_NONE;

	/*
	 * Release the resource so that parport_pc_probe_port can get it.
	 */
	release_region(inta_addr[i], 32);
	if (parport_pc_probe_port(ite8872_lpt, ite8872_lpthi,
				   irq, PARPORT_DMA_NONE, &pdev->dev, 0)) {
		printk(KERN_INFO
			"parport_pc: ITE 8872 parallel port: io=0x%X",
								ite8872_lpt);
		if (irq != PARPORT_IRQ_NONE)
			pr_cont(", irq=%d", irq);
		pr_cont("\n");
		return 1;
	}

	return 0;
}

/* VIA 8231 support by Pavel Fedin <sonic_amiga@rambler.ru>
   based on VIA 686a support code by Jeff Garzik <jgarzik@pobox.com> */
static int parport_init_mode;

/* Data for two known VIA chips */
static struct parport_pc_via_data via_686a_data = {
	0x51,
	0x50,
	0x85,
	0x02,
	0xE2,
	0xF0,
	0xE6
};
static struct parport_pc_via_data via_8231_data = {
	0x45,
	0x44,
	0x50,
	0x04,
	0xF2,
	0xFA,
	0xF6
};

static int sio_via_probe(struct pci_dev *pdev, int autoirq, int autodma,
			 const struct parport_pc_via_data *via)
{
	u8 tmp, tmp2, siofunc;
	u8 ppcontrol = 0;
	int dma, irq;
	unsigned port1, port2;
	unsigned have_epp = 0;

	printk(KERN_DEBUG "parport_pc: VIA 686A/8231 detected\n");

	switch (parport_init_mode) {
	case 1:
		printk(KERN_DEBUG "parport_pc: setting SPP mode\n");
		siofunc = VIA_FUNCTION_PARPORT_SPP;
		break;
	case 2:
		printk(KERN_DEBUG "parport_pc: setting PS/2 mode\n");
		siofunc = VIA_FUNCTION_PARPORT_SPP;
		ppcontrol = VIA_PARPORT_BIDIR;
		break;
	case 3:
		printk(KERN_DEBUG "parport_pc: setting EPP mode\n");
		siofunc = VIA_FUNCTION_PARPORT_EPP;
		ppcontrol = VIA_PARPORT_BIDIR;
		have_epp = 1;
		break;
	case 4:
		printk(KERN_DEBUG "parport_pc: setting ECP mode\n");
		siofunc = VIA_FUNCTION_PARPORT_ECP;
		ppcontrol = VIA_PARPORT_BIDIR;
		break;
	case 5:
		printk(KERN_DEBUG "parport_pc: setting EPP+ECP mode\n");
		siofunc = VIA_FUNCTION_PARPORT_ECP;
		ppcontrol = VIA_PARPORT_BIDIR|VIA_PARPORT_ECPEPP;
		have_epp = 1;
		break;
	default:
		printk(KERN_DEBUG
			"parport_pc: probing current configuration\n");
		siofunc = VIA_FUNCTION_PROBE;
		break;
	}
	/*
	 * unlock super i/o configuration
	 */
	pci_read_config_byte(pdev, via->via_pci_superio_config_reg, &tmp);
	tmp |= via->via_pci_superio_config_data;
	pci_write_config_byte(pdev, via->via_pci_superio_config_reg, tmp);

	/* Bits 1-0: Parallel Port Mode / Enable */
	outb(via->viacfg_function, VIA_CONFIG_INDEX);
	tmp = inb(VIA_CONFIG_DATA);
	/* Bit 5: EPP+ECP enable; bit 7: PS/2 bidirectional port enable */
	outb(via->viacfg_parport_control, VIA_CONFIG_INDEX);
	tmp2 = inb(VIA_CONFIG_DATA);
	if (siofunc == VIA_FUNCTION_PROBE) {
		siofunc = tmp & VIA_FUNCTION_PARPORT_DISABLE;
		ppcontrol = tmp2;
	} else {
		tmp &= ~VIA_FUNCTION_PARPORT_DISABLE;
		tmp |= siofunc;
		outb(via->viacfg_function, VIA_CONFIG_INDEX);
		outb(tmp, VIA_CONFIG_DATA);
		tmp2 &= ~(VIA_PARPORT_BIDIR|VIA_PARPORT_ECPEPP);
		tmp2 |= ppcontrol;
		outb(via->viacfg_parport_control, VIA_CONFIG_INDEX);
		outb(tmp2, VIA_CONFIG_DATA);
	}

	/* Parallel Port I/O Base Address, bits 9-2 */
	outb(via->viacfg_parport_base, VIA_CONFIG_INDEX);
	port1 = inb(VIA_CONFIG_DATA) << 2;

	printk(KERN_DEBUG "parport_pc: Current parallel port base: 0x%X\n",
									port1);
	if (port1 == 0x3BC && have_epp) {
		outb(via->viacfg_parport_base, VIA_CONFIG_INDEX);
		outb((0x378 >> 2), VIA_CONFIG_DATA);
		printk(KERN_DEBUG
			"parport_pc: Parallel port base changed to 0x378\n");
		port1 = 0x378;
	}

	/*
	 * lock super i/o configuration
	 */
	pci_read_config_byte(pdev, via->via_pci_superio_config_reg, &tmp);
	tmp &= ~via->via_pci_superio_config_data;
	pci_write_config_byte(pdev, via->via_pci_superio_config_reg, tmp);

	if (siofunc == VIA_FUNCTION_PARPORT_DISABLE) {
		printk(KERN_INFO "parport_pc: VIA parallel port disabled in BIOS\n");
		return 0;
	}

	/* Bits 7-4: PnP Routing for Parallel Port IRQ */
	pci_read_config_byte(pdev, via->via_pci_parport_irq_reg, &tmp);
	irq = ((tmp & VIA_IRQCONTROL_PARALLEL) >> 4);

	if (siofunc == VIA_FUNCTION_PARPORT_ECP) {
		/* Bits 3-2: PnP Routing for Parallel Port DMA */
		pci_read_config_byte(pdev, via->via_pci_parport_dma_reg, &tmp);
		dma = ((tmp & VIA_DMACONTROL_PARALLEL) >> 2);
	} else
		/* if ECP not enabled, DMA is not enabled, assumed
		   bogus 'dma' value */
		dma = PARPORT_DMA_NONE;

	/* Let the user (or defaults) steer us away from interrupts and DMA */
	if (autoirq == PARPORT_IRQ_NONE) {
		irq = PARPORT_IRQ_NONE;
		dma = PARPORT_DMA_NONE;
	}
	if (autodma == PARPORT_DMA_NONE)
		dma = PARPORT_DMA_NONE;

	switch (port1) {
	case 0x3bc:
		port2 = 0x7bc; break;
	case 0x378:
		port2 = 0x778; break;
	case 0x278:
		port2 = 0x678; break;
	default:
		printk(KERN_INFO
			"parport_pc: Weird VIA parport base 0x%X, ignoring\n",
									port1);
		return 0;
	}

	/* filter bogus IRQs */
	switch (irq) {
	case 0:
	case 2:
	case 8:
	case 13:
		irq = PARPORT_IRQ_NONE;
		break;

	default: /* do nothing */
		break;
	}

	/* finally, do the probe with values obtained */
	if (parport_pc_probe_port(port1, port2, irq, dma, &pdev->dev, 0)) {
		printk(KERN_INFO
			"parport_pc: VIA parallel port: io=0x%X", port1);
		if (irq != PARPORT_IRQ_NONE)
			pr_cont(", irq=%d", irq);
		if (dma != PARPORT_DMA_NONE)
			pr_cont(", dma=%d", dma);
		pr_cont("\n");
		return 1;
	}

	printk(KERN_WARNING "parport_pc: Strange, can't probe VIA parallel port: io=0x%X, irq=%d, dma=%d\n",
		port1, irq, dma);
	return 0;
}


enum parport_pc_sio_types {
	sio_via_686a = 0,   /* Via VT82C686A motherboard Super I/O */
	sio_via_8231,	    /* Via VT8231 south bridge integrated Super IO */
	sio_ite_8872,
	last_sio
};

/* each element directly indexed from enum list, above */
static struct parport_pc_superio {
	int (*probe) (struct pci_dev *pdev, int autoirq, int autodma,
		      const struct parport_pc_via_data *via);
	const struct parport_pc_via_data *via;
} parport_pc_superio_info[] = {
	{ sio_via_probe, &via_686a_data, },
	{ sio_via_probe, &via_8231_data, },
	{ sio_ite_8872_probe, NULL, },
};

enum parport_pc_pci_cards {
	siig_1p_10x = last_sio,
	siig_2p_10x,
	siig_1p_20x,
	siig_2p_20x,
	lava_parallel,
	lava_parallel_dual_a,
	lava_parallel_dual_b,
	boca_ioppar,
	plx_9050,
	timedia_4006a,
	timedia_4014,
	timedia_4008a,
	timedia_4018,
	timedia_9018a,
	syba_2p_epp,
	syba_1p_ecp,
	titan_010l,
	avlab_1p,
	avlab_2p,
	oxsemi_952,
	oxsemi_954,
	oxsemi_840,
	oxsemi_pcie_pport,
	aks_0100,
	mobility_pp,
	netmos_9705,
	netmos_9715,
	netmos_9755,
	netmos_9805,
	netmos_9815,
	netmos_9901,
	netmos_9865,
	quatech_sppxp100,
	wch_ch382l,
};


/* each element directly indexed from enum list, above
 * (but offset by last_sio) */
static struct parport_pc_pci {
	int numports;
	struct { /* BAR (base address registers) numbers in the config
		    space header */
		int lo;
		int hi;
		/* -1 if not there, >6 for offset-method (max BAR is 6) */
	} addr[4];

	/* If set, this is called immediately after pci_enable_device.
	 * If it returns non-zero, no probing will take place and the
	 * ports will not be used. */
	int (*preinit_hook) (struct pci_dev *pdev, int autoirq, int autodma);

	/* If set, this is called after probing for ports.  If 'failed'
	 * is non-zero we couldn't use any of the ports. */
	void (*postinit_hook) (struct pci_dev *pdev, int failed);
} cards[] = {
	/* siig_1p_10x */		{ 1, { { 2, 3 }, } },
	/* siig_2p_10x */		{ 2, { { 2, 3 }, { 4, 5 }, } },
	/* siig_1p_20x */		{ 1, { { 0, 1 }, } },
	/* siig_2p_20x */		{ 2, { { 0, 1 }, { 2, 3 }, } },
	/* lava_parallel */		{ 1, { { 0, -1 }, } },
	/* lava_parallel_dual_a */	{ 1, { { 0, -1 }, } },
	/* lava_parallel_dual_b */	{ 1, { { 0, -1 }, } },
	/* boca_ioppar */		{ 1, { { 0, -1 }, } },
	/* plx_9050 */			{ 2, { { 4, -1 }, { 5, -1 }, } },
	/* timedia_4006a */             { 1, { { 0, -1 }, } },
	/* timedia_4014  */             { 2, { { 0, -1 }, { 2, -1 }, } },
	/* timedia_4008a */             { 1, { { 0, 1 }, } },
	/* timedia_4018  */             { 2, { { 0, 1 }, { 2, 3 }, } },
	/* timedia_9018a */             { 2, { { 0, 1 }, { 2, 3 }, } },
					/* SYBA uses fixed offsets in
					   a 1K io window */
	/* syba_2p_epp AP138B */	{ 2, { { 0, 0x078 }, { 0, 0x178 }, } },
	/* syba_1p_ecp W83787 */	{ 1, { { 0, 0x078 }, } },
	/* titan_010l */		{ 1, { { 3, -1 }, } },
	/* avlab_1p		*/	{ 1, { { 0, 1}, } },
	/* avlab_2p		*/	{ 2, { { 0, 1}, { 2, 3 },} },
	/* The Oxford Semi cards are unusual: 954 doesn't support ECP,
	 * and 840 locks up if you write 1 to bit 2! */
	/* oxsemi_952 */		{ 1, { { 0, 1 }, } },
	/* oxsemi_954 */		{ 1, { { 0, -1 }, } },
	/* oxsemi_840 */		{ 1, { { 0, 1 }, } },
	/* oxsemi_pcie_pport */		{ 1, { { 0, 1 }, } },
	/* aks_0100 */                  { 1, { { 0, -1 }, } },
	/* mobility_pp */		{ 1, { { 0, 1 }, } },

	/* The netmos entries below are untested */
	/* netmos_9705 */               { 1, { { 0, -1 }, } },
	/* netmos_9715 */               { 2, { { 0, 1 }, { 2, 3 },} },
	/* netmos_9755 */               { 2, { { 0, 1 }, { 2, 3 },} },
	/* netmos_9805 */		{ 1, { { 0, 1 }, } },
	/* netmos_9815 */		{ 2, { { 0, 1 }, { 2, 3 }, } },
	/* netmos_9901 */               { 1, { { 0, -1 }, } },
	/* netmos_9865 */               { 1, { { 0, -1 }, } },
	/* quatech_sppxp100 */		{ 1, { { 0, 1 }, } },
	/* wch_ch382l */		{ 1, { { 2, -1 }, } },
};

static const struct pci_device_id parport_pc_pci_tbl[] = {
	/* Super-IO onboard chips */
	{ 0x1106, 0x0686, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sio_via_686a },
	{ 0x1106, 0x8231, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sio_via_8231 },
	{ PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8872,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, sio_ite_8872 },

	/* PCI cards */
	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1P_10x,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1p_10x },
	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P_10x,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p_10x },
	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1P_20x,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1p_20x },
	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P_20x,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p_20x },
	{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PARALLEL,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, lava_parallel },
	{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DUAL_PAR_A,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, lava_parallel_dual_a },
	{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DUAL_PAR_B,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, lava_parallel_dual_b },
	{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_BOCA_IOPPAR,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, boca_ioppar },
	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
	  PCI_SUBVENDOR_ID_EXSYS, PCI_SUBDEVICE_ID_EXSYS_4014, 0, 0, plx_9050 },
	/* PCI_VENDOR_ID_TIMEDIA/SUNIX has many differing cards ...*/
	{ 0x1409, 0x7268, 0x1409, 0x0101, 0, 0, timedia_4006a },
	{ 0x1409, 0x7268, 0x1409, 0x0102, 0, 0, timedia_4014 },
	{ 0x1409, 0x7268, 0x1409, 0x0103, 0, 0, timedia_4008a },
	{ 0x1409, 0x7268, 0x1409, 0x0104, 0, 0, timedia_4018 },
	{ 0x1409, 0x7268, 0x1409, 0x9018, 0, 0, timedia_9018a },
	{ PCI_VENDOR_ID_SYBA, PCI_DEVICE_ID_SYBA_2P_EPP,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, syba_2p_epp },
	{ PCI_VENDOR_ID_SYBA, PCI_DEVICE_ID_SYBA_1P_ECP,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, syba_1p_ecp },
	{ PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_010L,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_010l },
	/* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
	/* AFAVLAB_TK9902 */
	{ 0x14db, 0x2120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1p},
	{ 0x14db, 0x2121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2p},
	{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952PP,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_952 },
	{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954PP,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_954 },
	{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_12PCI840,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_840 },
	{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe840,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
	{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe840_G,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
	{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe952_0,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
	{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe952_0_G,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
	{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe952_1,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
	{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe952_1_G,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
	{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe952_1_U,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
	{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_PCIe952_1_GU,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport },
	{ PCI_VENDOR_ID_AKS, PCI_DEVICE_ID_AKS_ALADDINCARD,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, aks_0100 },
	{ 0x14f2, 0x0121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, mobility_pp },
	/* NetMos communication controllers */
	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9705,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9705 },
	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9715,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9715 },
	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9755,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9755 },
	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9805,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 },
	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 },
	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901,
	  0xA000, 0x2000, 0, 0, netmos_9901 },
	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
	  0xA000, 0x1000, 0, 0, netmos_9865 },
	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
	  0xA000, 0x2000, 0, 0, netmos_9865 },
	/* Quatech SPPXP-100 Parallel port PCI ExpressCard */
	{ PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 },
	/* WCH CH382L PCI-E single parallel port card */
	{ 0x1c00, 0x3050, 0x1c00, 0x3050, 0, 0, wch_ch382l },
	{ 0, } /* terminate list */
};
MODULE_DEVICE_TABLE(pci, parport_pc_pci_tbl);

struct pci_parport_data {
	int num;
	struct parport *ports[2];
};

static int parport_pc_pci_probe(struct pci_dev *dev,
					   const struct pci_device_id *id)
{
	int err, count, n, i = id->driver_data;
	struct pci_parport_data *data;

	if (i < last_sio)
		/* This is an onboard Super-IO and has already been probed */
		return 0;

	/* This is a PCI card */
	i -= last_sio;
	count = 0;
	err = pci_enable_device(dev);
	if (err)
		return err;

	data = kmalloc(sizeof(struct pci_parport_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	if (cards[i].preinit_hook &&
	    cards[i].preinit_hook(dev, PARPORT_IRQ_NONE, PARPORT_DMA_NONE)) {
		kfree(data);
		return -ENODEV;
	}

	for (n = 0; n < cards[i].numports; n++) {
		int lo = cards[i].addr[n].lo;
		int hi = cards[i].addr[n].hi;
		int irq;
		unsigned long io_lo, io_hi;
		io_lo = pci_resource_start(dev, lo);
		io_hi = 0;
		if ((hi >= 0) && (hi <= 6))
			io_hi = pci_resource_start(dev, hi);
		else if (hi > 6)
			io_lo += hi; /* Reinterpret the meaning of
					"hi" as an offset (see SYBA
					def.) */
		/* TODO: test if sharing interrupts works */
		irq = dev->irq;
		if (irq == IRQ_NONE) {
			printk(KERN_DEBUG
	"PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx)\n",
				id->vendor, id->device, io_lo, io_hi);
			irq = PARPORT_IRQ_NONE;
		} else {
			printk(KERN_DEBUG
	"PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx), IRQ %d\n",
				id->vendor, id->device, io_lo, io_hi, irq);
		}
		data->ports[count] =
			parport_pc_probe_port(io_lo, io_hi, irq,
					       PARPORT_DMA_NONE, &dev->dev,
					       IRQF_SHARED);
		if (data->ports[count])
			count++;
	}

	data->num = count;

	if (cards[i].postinit_hook)
		cards[i].postinit_hook(dev, count == 0);

	if (count) {
		pci_set_drvdata(dev, data);
		return 0;
	}

	kfree(data);

	return -ENODEV;
}

static void parport_pc_pci_remove(struct pci_dev *dev)
{
	struct pci_parport_data *data = pci_get_drvdata(dev);
	int i;

	if (data) {
		for (i = data->num - 1; i >= 0; i--)
			parport_pc_unregister_port(data->ports[i]);

		kfree(data);
	}
}

static struct pci_driver parport_pc_pci_driver = {
	.name		= "parport_pc",
	.id_table	= parport_pc_pci_tbl,
	.probe		= parport_pc_pci_probe,
	.remove		= parport_pc_pci_remove,
};

static int __init parport_pc_init_superio(int autoirq, int autodma)
{
	const struct pci_device_id *id;
	struct pci_dev *pdev = NULL;
	int ret = 0;

	for_each_pci_dev(pdev) {
		id = pci_match_id(parport_pc_pci_tbl, pdev);
		if (id == NULL || id->driver_data >= last_sio)
			continue;

		if (parport_pc_superio_info[id->driver_data].probe(
			pdev, autoirq, autodma,
			parport_pc_superio_info[id->driver_data].via)) {
			ret++;
		}
	}

	return ret; /* number of devices found */
}
#else
static struct pci_driver parport_pc_pci_driver;
static int __init parport_pc_init_superio(int autoirq, int autodma)
{
	return 0;
}
#endif /* CONFIG_PCI */

#ifdef CONFIG_PNP

static const struct pnp_device_id parport_pc_pnp_tbl[] = {
	/* Standard LPT Printer Port */
	{.id = "PNP0400", .driver_data = 0},
	/* ECP Printer Port */
	{.id = "PNP0401", .driver_data = 0},
	{ }
};

MODULE_DEVICE_TABLE(pnp, parport_pc_pnp_tbl);

static int parport_pc_pnp_probe(struct pnp_dev *dev,
						const struct pnp_device_id *id)
{
	struct parport *pdata;
	unsigned long io_lo, io_hi;
	int dma, irq;

	if (pnp_port_valid(dev, 0) &&
		!(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
		io_lo = pnp_port_start(dev, 0);
	} else
		return -EINVAL;

	if (pnp_port_valid(dev, 1) &&
		!(pnp_port_flags(dev, 1) & IORESOURCE_DISABLED)) {
		io_hi = pnp_port_start(dev, 1);
	} else
		io_hi = 0;

	if (pnp_irq_valid(dev, 0) &&
		!(pnp_irq_flags(dev, 0) & IORESOURCE_DISABLED)) {
		irq = pnp_irq(dev, 0);
	} else
		irq = PARPORT_IRQ_NONE;

	if (pnp_dma_valid(dev, 0) &&
		!(pnp_dma_flags(dev, 0) & IORESOURCE_DISABLED)) {
		dma = pnp_dma(dev, 0);
	} else
		dma = PARPORT_DMA_NONE;

	dev_info(&dev->dev, "reported by %s\n", dev->protocol->name);
	pdata = parport_pc_probe_port(io_lo, io_hi, irq, dma, &dev->dev, 0);
	if (pdata == NULL)
		return -ENODEV;

	pnp_set_drvdata(dev, pdata);
	return 0;
}

static void parport_pc_pnp_remove(struct pnp_dev *dev)
{
	struct parport *pdata = (struct parport *)pnp_get_drvdata(dev);
	if (!pdata)
		return;

	parport_pc_unregister_port(pdata);
}

/* we only need the pnp layer to activate the device, at least for now */
static struct pnp_driver parport_pc_pnp_driver = {
	.name		= "parport_pc",
	.id_table	= parport_pc_pnp_tbl,
	.probe		= parport_pc_pnp_probe,
	.remove		= parport_pc_pnp_remove,
};

#else
static struct pnp_driver parport_pc_pnp_driver;
#endif /* CONFIG_PNP */

static int parport_pc_platform_probe(struct platform_device *pdev)
{
	/* Always succeed, the actual probing is done in
	 * parport_pc_probe_port(). */
	return 0;
}

static struct platform_driver parport_pc_platform_driver = {
	.driver = {
		.name	= "parport_pc",
	},
	.probe		= parport_pc_platform_probe,
};

/* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */
static int __attribute__((unused))
parport_pc_find_isa_ports(int autoirq, int autodma)
{
	int count = 0;

	if (parport_pc_probe_port(0x3bc, 0x7bc, autoirq, autodma, NULL, 0))
		count++;
	if (parport_pc_probe_port(0x378, 0x778, autoirq, autodma, NULL, 0))
		count++;
	if (parport_pc_probe_port(0x278, 0x678, autoirq, autodma, NULL, 0))
		count++;

	return count;
}

/* This function is called by parport_pc_init if the user didn't
 * specify any ports to probe.  Its job is to find some ports.  Order
 * is important here -- we want ISA ports to be registered first,
 * followed by PCI cards (for least surprise), but before that we want
 * to do chipset-specific tests for some onboard ports that we know
 * about.
 *
 * autoirq is PARPORT_IRQ_NONE, PARPORT_IRQ_AUTO, or PARPORT_IRQ_PROBEONLY
 * autodma is PARPORT_DMA_NONE or PARPORT_DMA_AUTO
 */
static void __init parport_pc_find_ports(int autoirq, int autodma)
{
	int count = 0, err;

#ifdef CONFIG_PARPORT_PC_SUPERIO
	detect_and_report_it87();
	detect_and_report_winbond();
	detect_and_report_smsc();
#endif

	/* Onboard SuperIO chipsets that show themselves on the PCI bus. */
	count += parport_pc_init_superio(autoirq, autodma);

	/* PnP ports, skip detection if SuperIO already found them */
	if (!count) {
		err = pnp_register_driver(&parport_pc_pnp_driver);
		if (!err)
			pnp_registered_parport = 1;
	}

	/* ISA ports and whatever (see asm/parport.h). */
	parport_pc_find_nonpci_ports(autoirq, autodma);

	err = pci_register_driver(&parport_pc_pci_driver);
	if (!err)
		pci_registered_parport = 1;
}

/*
 *	Piles of crap below pretend to be a parser for module and kernel
 *	parameters.  Say "thank you" to whoever had come up with that
 *	syntax and keep in mind that code below is a cleaned up version.
 */

static int __initdata io[PARPORT_PC_MAX_PORTS+1] = {
	[0 ... PARPORT_PC_MAX_PORTS] = 0
};
static int __initdata io_hi[PARPORT_PC_MAX_PORTS+1] = {
	[0 ... PARPORT_PC_MAX_PORTS] = PARPORT_IOHI_AUTO
};
static int __initdata dmaval[PARPORT_PC_MAX_PORTS] = {
	[0 ... PARPORT_PC_MAX_PORTS-1] = PARPORT_DMA_NONE
};
static int __initdata irqval[PARPORT_PC_MAX_PORTS] = {
	[0 ... PARPORT_PC_MAX_PORTS-1] = PARPORT_IRQ_PROBEONLY
};

static int __init parport_parse_param(const char *s, int *val,
				int automatic, int none, int nofifo)
{
	if (!s)
		return 0;
	if (!strncmp(s, "auto", 4))
		*val = automatic;
	else if (!strncmp(s, "none", 4))
		*val = none;
	else if (nofifo && !strncmp(s, "nofifo", 6))
		*val = nofifo;
	else {
		char *ep;
		unsigned long r = simple_strtoul(s, &ep, 0);
		if (ep != s)
			*val = r;
		else {
			printk(KERN_ERR "parport: bad specifier `%s'\n", s);
			return -1;
		}
	}
	return 0;
}

static int __init parport_parse_irq(const char *irqstr, int *val)
{
	return parport_parse_param(irqstr, val, PARPORT_IRQ_AUTO,
				     PARPORT_IRQ_NONE, 0);
}

static int __init parport_parse_dma(const char *dmastr, int *val)
{
	return parport_parse_param(dmastr, val, PARPORT_DMA_AUTO,
				     PARPORT_DMA_NONE, PARPORT_DMA_NOFIFO);
}

#ifdef CONFIG_PCI
static int __init parport_init_mode_setup(char *str)
{
	printk(KERN_DEBUG
	     "parport_pc.c: Specified parameter parport_init_mode=%s\n", str);

	if (!strcmp(str, "spp"))
		parport_init_mode = 1;
	if (!strcmp(str, "ps2"))
		parport_init_mode = 2;
	if (!strcmp(str, "epp"))
		parport_init_mode = 3;
	if (!strcmp(str, "ecp"))
		parport_init_mode = 4;
	if (!strcmp(str, "ecpepp"))
		parport_init_mode = 5;
	return 1;
}
#endif

#ifdef MODULE
static char *irq[PARPORT_PC_MAX_PORTS];
static char *dma[PARPORT_PC_MAX_PORTS];

MODULE_PARM_DESC(io, "Base I/O address (SPP regs)");
module_param_hw_array(io, int, ioport, NULL, 0);
MODULE_PARM_DESC(io_hi, "Base I/O address (ECR)");
module_param_hw_array(io_hi, int, ioport, NULL, 0);
MODULE_PARM_DESC(irq, "IRQ line");
module_param_hw_array(irq, charp, irq, NULL, 0);
MODULE_PARM_DESC(dma, "DMA channel");
module_param_hw_array(dma, charp, dma, NULL, 0);
#if defined(CONFIG_PARPORT_PC_SUPERIO) || \
       (defined(CONFIG_PARPORT_1284) && defined(CONFIG_PARPORT_PC_FIFO))
MODULE_PARM_DESC(verbose_probing, "Log chit-chat during initialisation");
module_param(verbose_probing, int, 0644);
#endif
#ifdef CONFIG_PCI
static char *init_mode;
MODULE_PARM_DESC(init_mode,
	"Initialise mode for VIA VT8231 port (spp, ps2, epp, ecp or ecpepp)");
module_param(init_mode, charp, 0);
#endif

static int __init parse_parport_params(void)
{
	unsigned int i;
	int val;

#ifdef CONFIG_PCI
	if (init_mode)
		parport_init_mode_setup(init_mode);
#endif

	for (i = 0; i < PARPORT_PC_MAX_PORTS && io[i]; i++) {
		if (parport_parse_irq(irq[i], &val))
			return 1;
		irqval[i] = val;
		if (parport_parse_dma(dma[i], &val))
			return 1;
		dmaval[i] = val;
	}
	if (!io[0]) {
		/* The user can make us use any IRQs or DMAs we find. */
		if (irq[0] && !parport_parse_irq(irq[0], &val))
			switch (val) {
			case PARPORT_IRQ_NONE:
			case PARPORT_IRQ_AUTO:
				irqval[0] = val;
				break;
			default:
				printk(KERN_WARNING
					"parport_pc: irq specified "
					"without base address.  Use 'io=' "
					"to specify one\n");
			}

		if (dma[0] && !parport_parse_dma(dma[0], &val))
			switch (val) {
			case PARPORT_DMA_NONE:
			case PARPORT_DMA_AUTO:
				dmaval[0] = val;
				break;
			default:
				printk(KERN_WARNING
					"parport_pc: dma specified "
					"without base address.  Use 'io=' "
					"to specify one\n");
			}
	}
	return 0;
}

#else

static int parport_setup_ptr __initdata;

/*
 * Acceptable parameters:
 *
 * parport=0
 * parport=auto
 * parport=0xBASE[,IRQ[,DMA]]
 *
 * IRQ/DMA may be numeric or 'auto' or 'none'
 */
static int __init parport_setup(char *str)
{
	char *endptr;
	char *sep;
	int val;

	if (!str || !*str || (*str == '0' && !*(str+1))) {
		/* Disable parport if "parport=0" in cmdline */
		io[0] = PARPORT_DISABLE;
		return 1;
	}

	if (!strncmp(str, "auto", 4)) {
		irqval[0] = PARPORT_IRQ_AUTO;
		dmaval[0] = PARPORT_DMA_AUTO;
		return 1;
	}

	val = simple_strtoul(str, &endptr, 0);
	if (endptr == str) {
		printk(KERN_WARNING "parport=%s not understood\n", str);
		return 1;
	}

	if (parport_setup_ptr == PARPORT_PC_MAX_PORTS) {
		printk(KERN_ERR "parport=%s ignored, too many ports\n", str);
		return 1;
	}

	io[parport_setup_ptr] = val;
	irqval[parport_setup_ptr] = PARPORT_IRQ_NONE;
	dmaval[parport_setup_ptr] = PARPORT_DMA_NONE;

	sep = strchr(str, ',');
	if (sep++) {
		if (parport_parse_irq(sep, &val))
			return 1;
		irqval[parport_setup_ptr] = val;
		sep = strchr(sep, ',');
		if (sep++) {
			if (parport_parse_dma(sep, &val))
				return 1;
			dmaval[parport_setup_ptr] = val;
		}
	}
	parport_setup_ptr++;
	return 1;
}

static int __init parse_parport_params(void)
{
	return io[0] == PARPORT_DISABLE;
}

__setup("parport=", parport_setup);

/*
 * Acceptable parameters:
 *
 * parport_init_mode=[spp|ps2|epp|ecp|ecpepp]
 */
#ifdef CONFIG_PCI
__setup("parport_init_mode=", parport_init_mode_setup);
#endif
#endif

/* "Parser" ends here */

static int __init parport_pc_init(void)
{
	int err;

	if (parse_parport_params())
		return -EINVAL;

	err = platform_driver_register(&parport_pc_platform_driver);
	if (err)
		return err;

	if (io[0]) {
		int i;
		/* Only probe the ports we were given. */
		user_specified = 1;
		for (i = 0; i < PARPORT_PC_MAX_PORTS; i++) {
			if (!io[i])
				break;
			if (io_hi[i] == PARPORT_IOHI_AUTO)
				io_hi[i] = 0x400 + io[i];
			parport_pc_probe_port(io[i], io_hi[i],
					irqval[i], dmaval[i], NULL, 0);
		}
	} else
		parport_pc_find_ports(irqval[0], dmaval[0]);

	return 0;
}

static void __exit parport_pc_exit(void)
{
	if (pci_registered_parport)
		pci_unregister_driver(&parport_pc_pci_driver);
	if (pnp_registered_parport)
		pnp_unregister_driver(&parport_pc_pnp_driver);
	platform_driver_unregister(&parport_pc_platform_driver);

	while (!list_empty(&ports_list)) {
		struct parport_pc_private *priv;
		struct parport *port;
		struct device *dev;
		priv = list_entry(ports_list.next,
				  struct parport_pc_private, list);
		port = priv->port;
		dev = port->dev;
		parport_pc_unregister_port(port);
		if (dev && dev->bus == &platform_bus_type)
			platform_device_unregister(to_platform_device(dev));
	}
}

MODULE_AUTHOR("Phil Blundell, Tim Waugh, others");
MODULE_DESCRIPTION("PC-style parallel port driver");
MODULE_LICENSE("GPL");
module_init(parport_pc_init)
module_exit(parport_pc_exit)
