/* 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.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 <asm/io.h>
#include <asm/dma.h>
#include <asm/uaccess.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;
}

#ifdef CONFIG_PARPORT_1284
/* Find FIFO lossage; FIFO is reset */
#if 0
static int get_fifo_residue (struct parport *p)
{
	int residue;
	int cnfga;
	const struct parport_pc_private *priv = p->physport->private_data;

	/* Adjust for the contents of the FIFO. */
	for (residue = priv->fifo_depth; ; residue--) {
		if (inb (ECONTROL (p)) & 0x2)
				/* Full up. */
			break;

		outb (0, FIFO (p));
	}

	printk (KERN_DEBUG "%s: %d PWords were left in FIFO\n", p->name,
		residue);

	/* Reset the FIFO. */
	frob_set_mode (p, ECR_PS2);

	/* Now change to config mode and clean up. FIXME */
	frob_set_mode (p, ECR_CNF);
	cnfga = inb (CONFIGA (p));
	printk (KERN_DEBUG "%s: cnfgA contains 0x%02x\n", p->name, cnfga);

	if (!(cnfga & (1<<2))) {
		printk (KERN_DEBUG "%s: Accounting for extra byte\n", p->name);
		residue++;
	}

	/* Don't care about partial PWords until support is added for
	 * PWord != 1 byte. */

	/* Back to PS2 mode. */
	frob_set_mode (p, ECR_PS2);

	DPRINTK (KERN_DEBUG "*** get_fifo_residue: done residue collecting (ecr = 0x%2.2x)\n", inb (ECONTROL (p)));
	return residue;
}
#endif  /*  0 */
#endif /* IEEE 1284 support */
#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;
}

#if 0
static size_t parport_pc_ecp_read_block_pio (struct parport *port,
					     void *buf, size_t length,
					     int flags)
{
	size_t left = length;
	size_t fifofull;
	int r;
	const int fifo = FIFO(port);
	const struct parport_pc_private *priv = port->physport->private_data;
	const int fifo_depth = priv->fifo_depth;
	char *bufp = buf;

	port = port->physport;
DPRINTK (KERN_DEBUG "parport_pc: parport_pc_ecp_read_block_pio\n");
dump_parport_state ("enter fcn", port);

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

	if (port->ieee1284.mode == IEEE1284_MODE_ECPRLE) {
		/* If the peripheral is allowed to send RLE compressed
		 * data, it is possible for a byte to expand to 128
		 * bytes in the FIFO. */
		fifofull = 128;
	} else {
		fifofull = fifo_depth;
	}

	/* If the caller wants less than a full FIFO's worth of data,
	 * go through software emulation.  Otherwise we may have to throw
	 * away data. */
	if (length < fifofull)
		return parport_ieee1284_ecp_read_data (port, buf,
						       length, flags);

	if (port->ieee1284.phase != IEEE1284_PH_REV_IDLE) {
		/* change to reverse-idle phase (must be in forward-idle) */

		/* Event 38: Set nAutoFd low (also make sure nStrobe is high) */
		parport_frob_control (port,
				      PARPORT_CONTROL_AUTOFD
				      | PARPORT_CONTROL_STROBE,
				      PARPORT_CONTROL_AUTOFD);
		parport_pc_data_reverse (port); /* Must be in PS2 mode */
		udelay (5);
		/* Event 39: Set nInit low to initiate bus reversal */
		parport_frob_control (port,
				      PARPORT_CONTROL_INIT,
				      0);
		/* Event 40: Wait for  nAckReverse (PError) to go low */
		r = parport_wait_peripheral (port, PARPORT_STATUS_PAPEROUT, 0);
                if (r) {
                        printk (KERN_DEBUG "%s: PE timeout Event 40 (%d) "
				"in ecp_read_block_pio\n", port->name, r);
			return 0;
		}
	}

	/* Set up ECP FIFO mode.*/
/*	parport_pc_frob_control (port,
				 PARPORT_CONTROL_STROBE |
				 PARPORT_CONTROL_AUTOFD,
				 PARPORT_CONTROL_AUTOFD); */
	r = change_mode (port, ECR_ECP); /* ECP FIFO */
	if (r) printk (KERN_DEBUG "%s: Warning change_mode ECR_ECP failed\n", port->name);

	port->ieee1284.phase = IEEE1284_PH_REV_DATA;

	/* the first byte must be collected manually */
dump_parport_state ("pre 43", port);
	/* Event 43: Wait for nAck to go low */
	r = parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0);
	if (r) {
		/* timed out while reading -- no data */
		printk (KERN_DEBUG "PIO read timed out (initial byte)\n");
		goto out_no_data;
	}
	/* read byte */
	*bufp++ = inb (DATA (port));
	left--;
dump_parport_state ("43-44", port);
	/* Event 44: nAutoFd (HostAck) goes high to acknowledge */
	parport_pc_frob_control (port,
				 PARPORT_CONTROL_AUTOFD,
				 0);
dump_parport_state ("pre 45", port);
	/* Event 45: Wait for nAck to go high */
/*	r = parport_wait_peripheral (port, PARPORT_STATUS_ACK, PARPORT_STATUS_ACK); */
dump_parport_state ("post 45", port);
r = 0;
	if (r) {
		/* timed out while waiting for peripheral to respond to ack */
		printk (KERN_DEBUG "ECP PIO read timed out (waiting for nAck)\n");

		/* keep hold of the byte we've got already */
		goto out_no_data;
	}
	/* Event 46: nAutoFd (HostAck) goes low to accept more data */
	parport_pc_frob_control (port,
				 PARPORT_CONTROL_AUTOFD,
				 PARPORT_CONTROL_AUTOFD);


dump_parport_state ("rev idle", port);
	/* Do the transfer. */
	while (left > fifofull) {
		int ret;
		unsigned long expire = jiffies + port->cad->timeout;
		unsigned char ecrval = inb (ECONTROL (port));

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

		/* At this point, the FIFO may already be full. In
                 * that case ECP is already holding back the
                 * peripheral (assuming proper design) with a delayed
                 * handshake.  Work fast to avoid a peripheral
                 * timeout.  */

		if (ecrval & 0x01) {
			/* FIFO is empty. Wait for interrupt. */
dump_parport_state ("FIFO empty", port);

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

			/* Clear serviceIntr */
			ECR_WRITE (port, ecrval & ~(1<<2));
		false_alarm:
dump_parport_state ("waiting", port);
			ret = parport_wait_event (port, HZ);
DPRINTK (KERN_DEBUG "parport_wait_event returned %d\n", ret);
			if (ret < 0)
				break;
			ret = 0;
			if (!time_before (jiffies, expire)) {
				/* Timed out. */
dump_parport_state ("timeout", port);
				printk (KERN_DEBUG "PIO read timed out\n");
				break;
			}
			ecrval = inb (ECONTROL (port));
			if (!(ecrval & (1<<2))) {
				if (need_resched() &&
				    time_before (jiffies, expire)) {
					schedule ();
				}
				goto false_alarm;
			}

			/* Depending on how the FIFO threshold was
                         * set, how long interrupt service took, and
                         * how fast the peripheral is, we might be
                         * lucky and have a just filled FIFO. */
			continue;
		}

		if (ecrval & 0x02) {
			/* FIFO is full. */
dump_parport_state ("FIFO full", port);
			insb (fifo, bufp, fifo_depth);
			bufp += fifo_depth;
			left -= fifo_depth;
			continue;
		}

DPRINTK (KERN_DEBUG "*** ecp_read_block_pio: reading one byte from the FIFO\n");

		/* FIFO not filled.  We will cycle this loop for a while
                 * and either the peripheral will fill it faster,
                 * tripping a fast empty with insb, or we empty it. */
		*bufp++ = inb (fifo);
		left--;
	}

	/* scoop up anything left in the FIFO */
	while (left && !(inb (ECONTROL (port) & 0x01))) {
		*bufp++ = inb (fifo);
		left--;
	}

	port->ieee1284.phase = IEEE1284_PH_REV_IDLE;
dump_parport_state ("rev idle2", port);

out_no_data:

	/* Go to forward idle mode to shut the peripheral up (event 47). */
	parport_frob_control (port, PARPORT_CONTROL_INIT, PARPORT_CONTROL_INIT);

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

	port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;

	/* Finish up. */
	{
		int lost = get_fifo_residue (port);
		if (lost)
			/* Shouldn't happen with compliant peripherals. */
			printk (KERN_DEBUG "%s: DATA LOSS (%d bytes)!\n",
				port->name, lost);
	}

dump_parport_state ("fwd idle", port);
	return length - left;
}
#endif  /*  0  */
#endif /* IEEE 1284 support */
#endif /* Allowed to use FIFO/DMA */


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

/* GCC is not inlining extern inline function later overwriten 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
/* Super-IO chipset detection, Winbond, SMSC */
static void __devinit show_parconfig_smsc37c669(int io, int key)
{
	int cr1,cr4,cra,cr23,cr26,cr27,i=0;
	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 */
		while((superios[i].io!= 0) && (i<NR_SUPERIOS))
			i++;
		if(i==NR_SUPERIOS)
			printk(KERN_INFO "Super-IO: too many chips!\n");
		else {
			int d;
			switch (cr23*4) {
				case 0x3bc:
					superios[i].io = 0x3bc;
					superios[i].irq = 7;
					break;
				case 0x378:
					superios[i].io = 0x378;
					superios[i].irq = 7;
					break;
				case 0x278:
					superios[i].io = 0x278;
					superios[i].irq = 5;
			}
			d=(cr26 &0x0f);
			if((d==1) || (d==3)) 
				superios[i].dma= d;
			else
				superios[i].dma= PARPORT_DMA_NONE;
		}
 	}
}


static void __devinit show_parconfig_winbond(int io, int key)
{
	int cr30,cr60,cr61,cr70,cr74,crf0,i=0;
	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)
			printk("dma=none\n");
		else
			printk("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 ... */
		while((superios[i].io!= 0) && (i<NR_SUPERIOS))
			i++;
		if(i==NR_SUPERIOS) 
			printk(KERN_INFO "Super-IO: too many chips!\n");
		else {
			superios[i].io = (cr60<<8)|cr61;
			superios[i].irq = cr70&0x0f;
			superios[i].dma = (((cr74 & 0x07) > 3) ?
					   PARPORT_DMA_NONE : (cr74 & 0x07));
		}
	}
}

static void __devinit 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 __devinit 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 __devinit winbond_check(int io, int key)
{
	int devid,devrev,oldid,x_devid,x_devrev,x_oldid;

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

	/* 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
                             funtion 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 */

	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 __devinit winbond_check2(int io,int key)
{
        int devid,devrev,oldid,x_devid,x_devrev,x_oldid;

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

	/* 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
                             funtion 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 */

	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 __devinit smsc_check(int io, int key)
{
        int id,rev,oldid,oldrev,x_id,x_rev,x_oldid,x_oldrev;

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

	/* 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
                             funtion 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 */

	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 __devinit 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 __devinit 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 __devinit detect_and_report_it87(void)
{
	u16 dev;
	u8 r;
	if (verbose_probing)
		printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n");
	if (!request_region(0x2e, 1, __FUNCTION__))
		return;
	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);
	}
	release_region(0x2e, 1);
}
#endif /* CONFIG_PARPORT_PC_SUPERIO */

static int get_superio_dma (struct parport *p)
{
	int i=0;
	while( (superios[i].io != p->base) && (i<NR_SUPERIOS))
		i++;
	if (i!=NR_SUPERIOS)
		return superios[i].dma;
	return PARPORT_DMA_NONE;
}

static int get_superio_irq (struct parport *p)
{
	int i=0;
        while( (superios[i].io != p->base) && (i<NR_SUPERIOS))
                i++;
        if (i!=NR_SUPERIOS)
                return superios[i].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);
		/* 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)
			printk("%d",intrline[(configb >>3) & 0x07]);
		else
			printk("<none or set by other means>");
		printk (" dma=");
		if( (configb & 0x03 ) == 0x00)
			printk("<none or set by other means>\n");
		else
			printk("%d\n",configb & 0x07);
	}

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

	return 1;
}
#endif

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)
{
	const struct parport_pc_private *priv = pb->private_data;

	/*
	 * 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 (priv->ecr) {
		unsigned char i;
		for (i = 0x00; i < 0x80; i += 0x20) {
			ECR_WRITE (pb, i);
			if (clear_epp_timeout (pb)) {
				/* Phony EPP in ECP. */
				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 __devinit 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 __devinit parport_EPP_supported(struct parport *pb) { return 0; }
static int __devinit parport_ECPEPP_supported(struct parport *pb){return 0;}
static int __devinit 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)
		p->dma = programmable_dma_support(p); /* ask ECP chipset first */
	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)
{
	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;

	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;
	}

	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(" (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(", 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(", dma %d", p->dma);
			p->modes |= PARPORT_MODE_DMA;
		}
		else printk(", using FIFO");
	}
	else
		/* We can't use the DMA channel after all. */
		p->dma = PARPORT_DMA_NONE;
#endif /* Allowed to use FIFO/DMA */

	printk(" [");
#define printmode(x) {if(p->modes&PARPORT_MODE_##x){printk("%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 ("(,...)");
#endif /* CONFIG_PARPORT_1284 */
	printk("]\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,
				 0, 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_put_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_put_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 __devinit 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 };
	struct resource *base_res;
	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++) {
		base_res = request_region(inta_addr[i], 32, "it887x");
		if (base_res) {
			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], 0x8);
		}
	}
	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");
		return 0;
	case 0x8:
		DPRINTK (KERN_DEBUG "parport_pc: ITE8874 found (2S)\n");
		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");
		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_resource(base_res);
	if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi,
				   irq, PARPORT_DMA_NONE, &pdev->dev)) {
		printk (KERN_INFO
			"parport_pc: ITE 8872 parallel port: io=0x%X",
			ite8872_lpt);
		if (irq != PARPORT_IRQ_NONE)
			printk (", irq=%d", irq);
		printk ("\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 __devinitdata parport_init_mode = 0;

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

static int __devinit 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)) {
		printk (KERN_INFO
			"parport_pc: VIA parallel port: io=0x%X", port1);
		if (irq != PARPORT_IRQ_NONE)
			printk (", irq=%d", irq);
		if (dma != PARPORT_DMA_NONE)
			printk (", dma=%d", dma);
		printk ("\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[] __devinitdata = {
	{ 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_4078a,
	timedia_4079h,
	timedia_4085h,
	timedia_4088a,
	timedia_4089a,
	timedia_4095a,
	timedia_4096a,
	timedia_4078u,
	timedia_4079a,
	timedia_4085u,
	timedia_4079r,
	timedia_4079s,
	timedia_4079d,
	timedia_4079e,
	timedia_4079f,
	timedia_9079a,
	timedia_9079b,
	timedia_9079c,
	timedia_4006a,
	timedia_4014,
	timedia_4008a,
	timedia_4018,
	timedia_9018a,
	syba_2p_epp,
	syba_1p_ecp,
	titan_010l,
	titan_1284p1,
	titan_1284p2,
	avlab_1p,
	avlab_2p,
	oxsemi_952,
	oxsemi_954,
	oxsemi_840,
	aks_0100,
	mobility_pp,
	netmos_9705,
	netmos_9715,
	netmos_9755,
	netmos_9805,
	netmos_9815,
	quatech_sppxp100,
};


/* 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_4078a */		{ 1, { { 2, -1 }, } },
	/* timedia_4079h */             { 1, { { 2, 3 }, } },
	/* timedia_4085h */             { 2, { { 2, -1 }, { 4, -1 }, } },
	/* timedia_4088a */             { 2, { { 2, 3 }, { 4, 5 }, } },
	/* timedia_4089a */             { 2, { { 2, 3 }, { 4, 5 }, } },
	/* timedia_4095a */             { 2, { { 2, 3 }, { 4, 5 }, } },
	/* timedia_4096a */             { 2, { { 2, 3 }, { 4, 5 }, } },
	/* timedia_4078u */             { 1, { { 2, -1 }, } },
	/* timedia_4079a */             { 1, { { 2, 3 }, } },
	/* timedia_4085u */             { 2, { { 2, -1 }, { 4, -1 }, } },
	/* timedia_4079r */             { 1, { { 2, 3 }, } },
	/* timedia_4079s */             { 1, { { 2, 3 }, } },
	/* timedia_4079d */             { 1, { { 2, 3 }, } },
	/* timedia_4079e */             { 1, { { 2, 3 }, } },
	/* timedia_4079f */             { 1, { { 2, 3 }, } },
	/* timedia_9079a */             { 1, { { 2, 3 }, } },
	/* timedia_9079b */             { 1, { { 2, 3 }, } },
	/* timedia_9079c */             { 1, { { 2, 3 }, } },
	/* 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 }, } },
	/* titan_1284p1 */              { 1, { { 0, 1 }, } },
	/* titan_1284p2 */		{ 2, { { 0, 1 }, { 2, 3 }, } },
	/* 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 }, } },
	/* aks_0100 */                  { 1, { { 0, -1 }, } },
	/* mobility_pp */		{ 1, { { 0, 1 }, } },
	/* netmos_9705 */               { 1, { { 0, -1 }, } }, /* untested */
        /* netmos_9715 */               { 2, { { 0, 1 }, { 2, 3 },} }, /* untested */
        /* netmos_9755 */               { 2, { { 0, 1 }, { 2, 3 },} }, /* untested */
	/* netmos_9805 */               { 1, { { 0, -1 }, } }, /* untested */
	/* netmos_9815 */               { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */
	/* quatech_sppxp100 */		{ 1, { { 0, 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, 0x7168, 0x1409, 0x4078, 0, 0, timedia_4078a },
	{ 0x1409, 0x7168, 0x1409, 0x4079, 0, 0, timedia_4079h },
	{ 0x1409, 0x7168, 0x1409, 0x4085, 0, 0, timedia_4085h },
	{ 0x1409, 0x7168, 0x1409, 0x4088, 0, 0, timedia_4088a },
	{ 0x1409, 0x7168, 0x1409, 0x4089, 0, 0, timedia_4089a },
	{ 0x1409, 0x7168, 0x1409, 0x4095, 0, 0, timedia_4095a },
	{ 0x1409, 0x7168, 0x1409, 0x4096, 0, 0, timedia_4096a },
	{ 0x1409, 0x7168, 0x1409, 0x5078, 0, 0, timedia_4078u },
	{ 0x1409, 0x7168, 0x1409, 0x5079, 0, 0, timedia_4079a },
	{ 0x1409, 0x7168, 0x1409, 0x5085, 0, 0, timedia_4085u },
	{ 0x1409, 0x7168, 0x1409, 0x6079, 0, 0, timedia_4079r },
	{ 0x1409, 0x7168, 0x1409, 0x7079, 0, 0, timedia_4079s },
	{ 0x1409, 0x7168, 0x1409, 0x8079, 0, 0, timedia_4079d },
	{ 0x1409, 0x7168, 0x1409, 0x9079, 0, 0, timedia_4079e },
	{ 0x1409, 0x7168, 0x1409, 0xa079, 0, 0, timedia_4079f },
	{ 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a },
	{ 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b },
	{ 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c },
	{ 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 },
	{ 0x14f2, 0x0121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, mobility_pp },
	{ 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 },
	{ 0x9710, 0x9805, 0x1000, 0x0010, 0, 0, titan_1284p1 },
	{ 0x9710, 0x9815, 0x1000, 0x0020, 0, 0, titan_1284p2 },
	/* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
	{ 0x14db, 0x2120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1p}, /* AFAVLAB_TK9902 */
	{ 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_AKS, PCI_DEVICE_ID_AKS_ALADDINCARD,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, aks_0100 },
	/* 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 },
	/* 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 },
	{ 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;
	if ((err = pci_enable_device (dev)) != 0)
		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;
		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 */
		printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, "
			"I/O at %#lx(%#lx)\n",
			parport_pc_pci_tbl[i + last_sio].vendor,
			parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi);
		data->ports[count] =
			parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
					       PARPORT_DMA_NONE, &dev->dev);
		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 __devexit parport_pc_pci_remove(struct pci_dev *dev)
{
	struct pci_parport_data *data = pci_get_drvdata(dev);
	int i;

	pci_set_drvdata(dev, NULL);

	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		= __devexit_p(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 */


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);
	if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, &dev->dev)))
		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,
};


static int __devinit 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 = {
		.owner	= THIS_MODULE,
		.name	= "parport_pc",
	},
	.probe		= parport_pc_platform_probe,
};

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

	if (parport_pc_probe_port(0x3bc, 0x7bc, autoirq, autodma, NULL))
		count++;
	if (parport_pc_probe_port(0x378, 0x778, autoirq, autodma, NULL))
		count++;
	if (parport_pc_probe_port(0x278, 0x678, autoirq, autodma, NULL))
		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", 4))
		*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 const char *irq[PARPORT_PC_MAX_PORTS];
static const char *dma[PARPORT_PC_MAX_PORTS];

MODULE_PARM_DESC(io, "Base I/O address (SPP regs)");
module_param_array(io, int, NULL, 0);
MODULE_PARM_DESC(io_hi, "Base I/O address (ECR)");
module_param_array(io_hi, int, NULL, 0);
MODULE_PARM_DESC(irq, "IRQ line");
module_param_array(irq, charp, NULL, 0);
MODULE_PARM_DESC(dma, "DMA channel");
module_param_array(dma, charp, 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 = 0;

/*
 * 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);
		}
	} 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;
		priv = list_entry(ports_list.next,
				  struct parport_pc_private, list);
		port = priv->port;
		if (port->dev && port->dev->bus == &platform_bus_type)
			platform_device_unregister(
				to_platform_device(port->dev));
		parport_pc_unregister_port(port);
	}
}

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)
