// SPDX-License-Identifier: GPL-2.0-only
/* 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)
