/* IEEE-1284 operations for parport.
 *
 * This file is for generic IEEE 1284 operations.  The idea is that
 * they are used by the low-level drivers.  If they have a special way
 * of doing something, they can provide their own routines (and put
 * the function pointers in port->ops); if not, they can just use these
 * as a fallback.
 *
 * Note: Make no assumptions about hardware or architecture in this file!
 *
 * Author: Tim Waugh <tim@cyberelk.demon.co.uk>
 * Fixed AUTOFD polarity in ecp_forward_to_reverse().  Fred Barnes, 1999
 * Software emulated EPP fixes, Fred Barnes, 04/2001.
 */


#include <linux/config.h>
#include <linux/module.h>
#include <linux/parport.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <asm/uaccess.h>

#undef DEBUG /* undef me for production */

#ifdef CONFIG_LP_CONSOLE
#undef DEBUG /* Don't want a garbled console */
#endif

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

/***                                *
 * One-way data transfer functions. *
 *                                ***/

/* Compatibility mode. */
size_t parport_ieee1284_write_compat (struct parport *port,
				      const void *buffer, size_t len,
				      int flags)
{
	int no_irq = 1;
	ssize_t count = 0;
	const unsigned char *addr = buffer;
	unsigned char byte;
	struct pardevice *dev = port->physport->cad;
	unsigned char ctl = (PARPORT_CONTROL_SELECT
			     | PARPORT_CONTROL_INIT);

	if (port->irq != PARPORT_IRQ_NONE) {
		parport_enable_irq (port);
		no_irq = 0;
	}

	port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA;
	parport_write_control (port, ctl);
	parport_data_forward (port);
	while (count < len) {
		unsigned long expire = jiffies + dev->timeout;
		long wait = msecs_to_jiffies(10);
		unsigned char mask = (PARPORT_STATUS_ERROR
				      | PARPORT_STATUS_BUSY);
		unsigned char val = (PARPORT_STATUS_ERROR
				     | PARPORT_STATUS_BUSY);

		/* Wait until the peripheral's ready */
		do {
			/* Is the peripheral ready yet? */
			if (!parport_wait_peripheral (port, mask, val))
				/* Skip the loop */
				goto ready;

			/* Is the peripheral upset? */
			if ((parport_read_status (port) &
			     (PARPORT_STATUS_PAPEROUT |
			      PARPORT_STATUS_SELECT |
			      PARPORT_STATUS_ERROR))
			    != (PARPORT_STATUS_SELECT |
				PARPORT_STATUS_ERROR))
				/* If nFault is asserted (i.e. no
				 * error) and PAPEROUT and SELECT are
				 * just red herrings, give the driver
				 * a chance to check it's happy with
				 * that before continuing. */
				goto stop;

			/* Have we run out of time? */
			if (!time_before (jiffies, expire))
				break;

			/* Yield the port for a while.  If this is the
                           first time around the loop, don't let go of
                           the port.  This way, we find out if we have
                           our interrupt handler called. */
			if (count && no_irq) {
				parport_release (dev);
				schedule_timeout_interruptible(wait);
				parport_claim_or_block (dev);
			}
			else
				/* We must have the device claimed here */
				parport_wait_event (port, wait);

			/* Is there a signal pending? */
			if (signal_pending (current))
				break;

			/* Wait longer next time. */
			wait *= 2;
		} while (time_before (jiffies, expire));

		if (signal_pending (current))
			break;

		DPRINTK (KERN_DEBUG "%s: Timed out\n", port->name);
		break;

	ready:
		/* Write the character to the data lines. */
		byte = *addr++;
		parport_write_data (port, byte);
		udelay (1);

		/* Pulse strobe. */
		parport_write_control (port, ctl | PARPORT_CONTROL_STROBE);
		udelay (1); /* strobe */

		parport_write_control (port, ctl);
		udelay (1); /* hold */

		/* Assume the peripheral received it. */
		count++;

                /* Let another process run if it needs to. */
		if (time_before (jiffies, expire))
			if (!parport_yield_blocking (dev)
			    && need_resched())
				schedule ();
	}
 stop:
	port->physport->ieee1284.phase = IEEE1284_PH_FWD_IDLE;

	return count;
}

/* Nibble mode. */
size_t parport_ieee1284_read_nibble (struct parport *port, 
				     void *buffer, size_t len,
				     int flags)
{
#ifndef CONFIG_PARPORT_1284
	return 0;
#else
	unsigned char *buf = buffer;
	int i;
	unsigned char byte = 0;

	len *= 2; /* in nibbles */
	for (i=0; i < len; i++) {
		unsigned char nibble;

		/* Does the error line indicate end of data? */
		if (((i & 1) == 0) &&
		    (parport_read_status(port) & PARPORT_STATUS_ERROR)) {
			port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
			DPRINTK (KERN_DEBUG
				"%s: No more nibble data (%d bytes)\n",
				port->name, i/2);

			/* Go to reverse idle phase. */
			parport_frob_control (port,
					      PARPORT_CONTROL_AUTOFD,
					      PARPORT_CONTROL_AUTOFD);
			port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
			break;
		}

		/* Event 7: Set nAutoFd low. */
		parport_frob_control (port,
				      PARPORT_CONTROL_AUTOFD,
				      PARPORT_CONTROL_AUTOFD);

		/* Event 9: nAck goes low. */
		port->ieee1284.phase = IEEE1284_PH_REV_DATA;
		if (parport_wait_peripheral (port,
					     PARPORT_STATUS_ACK, 0)) {
			/* Timeout -- no more data? */
			DPRINTK (KERN_DEBUG
				 "%s: Nibble timeout at event 9 (%d bytes)\n",
				 port->name, i/2);
			parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
			break;
		}


		/* Read a nibble. */
		nibble = parport_read_status (port) >> 3;
		nibble &= ~8;
		if ((nibble & 0x10) == 0)
			nibble |= 8;
		nibble &= 0xf;

		/* Event 10: Set nAutoFd high. */
		parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);

		/* Event 11: nAck goes high. */
		if (parport_wait_peripheral (port,
					     PARPORT_STATUS_ACK,
					     PARPORT_STATUS_ACK)) {
			/* Timeout -- no more data? */
			DPRINTK (KERN_DEBUG
				 "%s: Nibble timeout at event 11\n",
				 port->name);
			break;
		}

		if (i & 1) {
			/* Second nibble */
			byte |= nibble << 4;
			*buf++ = byte;
		} else 
			byte = nibble;
	}

	i /= 2; /* i is now in bytes */

	if (i == len) {
		/* Read the last nibble without checking data avail. */
		port = port->physport;
		if (parport_read_status (port) & PARPORT_STATUS_ERROR)
			port->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
		else
			port->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
	}

	return i;
#endif /* IEEE1284 support */
}

/* Byte mode. */
size_t parport_ieee1284_read_byte (struct parport *port,
				   void *buffer, size_t len,
				   int flags)
{
#ifndef CONFIG_PARPORT_1284
	return 0;
#else
	unsigned char *buf = buffer;
	ssize_t count = 0;

	for (count = 0; count < len; count++) {
		unsigned char byte;

		/* Data available? */
		if (parport_read_status (port) & PARPORT_STATUS_ERROR) {
			port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
			DPRINTK (KERN_DEBUG
				 "%s: No more byte data (%Zd bytes)\n",
				 port->name, count);

			/* Go to reverse idle phase. */
			parport_frob_control (port,
					      PARPORT_CONTROL_AUTOFD,
					      PARPORT_CONTROL_AUTOFD);
			port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
			break;
		}

		/* Event 14: Place data bus in high impedance state. */
		parport_data_reverse (port);

		/* Event 7: Set nAutoFd low. */
		parport_frob_control (port,
				      PARPORT_CONTROL_AUTOFD,
				      PARPORT_CONTROL_AUTOFD);

		/* Event 9: nAck goes low. */
		port->physport->ieee1284.phase = IEEE1284_PH_REV_DATA;
		if (parport_wait_peripheral (port,
					     PARPORT_STATUS_ACK,
					     0)) {
			/* Timeout -- no more data? */
			parport_frob_control (port, PARPORT_CONTROL_AUTOFD,
						 0);
			DPRINTK (KERN_DEBUG "%s: Byte timeout at event 9\n",
				 port->name);
			break;
		}

		byte = parport_read_data (port);
		*buf++ = byte;

		/* Event 10: Set nAutoFd high */
		parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);

		/* Event 11: nAck goes high. */
		if (parport_wait_peripheral (port,
					     PARPORT_STATUS_ACK,
					     PARPORT_STATUS_ACK)) {
			/* Timeout -- no more data? */
			DPRINTK (KERN_DEBUG "%s: Byte timeout at event 11\n",
				 port->name);
			break;
		}

		/* Event 16: Set nStrobe low. */
		parport_frob_control (port,
				      PARPORT_CONTROL_STROBE,
				      PARPORT_CONTROL_STROBE);
		udelay (5);

		/* Event 17: Set nStrobe high. */
		parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
	}

	if (count == len) {
		/* Read the last byte without checking data avail. */
		port = port->physport;
		if (parport_read_status (port) & PARPORT_STATUS_ERROR)
			port->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
		else
			port->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
	}

	return count;
#endif /* IEEE1284 support */
}

/***              *
 * ECP Functions. *
 *              ***/

#ifdef CONFIG_PARPORT_1284

static inline
int ecp_forward_to_reverse (struct parport *port)
{
	int retval;

	/* Event 38: Set nAutoFd low */
	parport_frob_control (port,
			      PARPORT_CONTROL_AUTOFD,
			      PARPORT_CONTROL_AUTOFD);
	parport_data_reverse (port);
	udelay (5);

	/* Event 39: Set nInit low to initiate bus reversal */
	parport_frob_control (port,
			      PARPORT_CONTROL_INIT,
			      0);

	/* Event 40: PError goes low */
	retval = parport_wait_peripheral (port,
					  PARPORT_STATUS_PAPEROUT, 0);

	if (!retval) {
		DPRINTK (KERN_DEBUG "%s: ECP direction: reverse\n",
			 port->name);
		port->ieee1284.phase = IEEE1284_PH_REV_IDLE;
	} else {
		DPRINTK (KERN_DEBUG "%s: ECP direction: failed to reverse\n",
			 port->name);
		port->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN;
	}

	return retval;
}

static inline
int ecp_reverse_to_forward (struct parport *port)
{
	int retval;

	/* 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 */
	retval = parport_wait_peripheral (port,
					  PARPORT_STATUS_PAPEROUT,
					  PARPORT_STATUS_PAPEROUT);

	if (!retval) {
		parport_data_forward (port);
		DPRINTK (KERN_DEBUG "%s: ECP direction: forward\n",
			 port->name);
		port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;
	} else {
		DPRINTK (KERN_DEBUG
			 "%s: ECP direction: failed to switch forward\n",
			 port->name);
		port->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN;
	}


	return retval;
}

#endif /* IEEE1284 support */

/* ECP mode, forward channel, data. */
size_t parport_ieee1284_ecp_write_data (struct parport *port,
					const void *buffer, size_t len,
					int flags)
{
#ifndef CONFIG_PARPORT_1284
	return 0;
#else
	const unsigned char *buf = buffer;
	size_t written;
	int retry;

	port = port->physport;

	if (port->ieee1284.phase != IEEE1284_PH_FWD_IDLE)
		if (ecp_reverse_to_forward (port))
			return 0;

	port->ieee1284.phase = IEEE1284_PH_FWD_DATA;

	/* HostAck high (data, not command) */
	parport_frob_control (port,
			      PARPORT_CONTROL_AUTOFD
			      | PARPORT_CONTROL_STROBE
			      | PARPORT_CONTROL_INIT,
			      PARPORT_CONTROL_INIT);
	for (written = 0; written < len; written++, buf++) {
		unsigned long expire = jiffies + port->cad->timeout;
		unsigned char byte;

		byte = *buf;
	try_again:
		parport_write_data (port, byte);
		parport_frob_control (port, PARPORT_CONTROL_STROBE,
				      PARPORT_CONTROL_STROBE);
		udelay (5);
		for (retry = 0; retry < 100; retry++) {
			if (!parport_wait_peripheral (port,
						      PARPORT_STATUS_BUSY, 0))
				goto success;

			if (signal_pending (current)) {
				parport_frob_control (port,
						      PARPORT_CONTROL_STROBE,
						      0);
				break;
			}
		}

		/* Time for Host Transfer Recovery (page 41 of IEEE1284) */
		DPRINTK (KERN_DEBUG "%s: ECP transfer stalled!\n", port->name);

		parport_frob_control (port, PARPORT_CONTROL_INIT,
				      PARPORT_CONTROL_INIT);
		udelay (50);
		if (parport_read_status (port) & PARPORT_STATUS_PAPEROUT) {
			/* It's buggered. */
			parport_frob_control (port, PARPORT_CONTROL_INIT, 0);
			break;
		}

		parport_frob_control (port, PARPORT_CONTROL_INIT, 0);
		udelay (50);
		if (!(parport_read_status (port) & PARPORT_STATUS_PAPEROUT))
			break;

		DPRINTK (KERN_DEBUG "%s: Host transfer recovered\n",
			 port->name);

		if (time_after_eq (jiffies, expire)) break;
		goto try_again;
	success:
		parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
		udelay (5);
		if (parport_wait_peripheral (port,
					     PARPORT_STATUS_BUSY,
					     PARPORT_STATUS_BUSY))
			/* Peripheral hasn't accepted the data. */
			break;
	}

	port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;

	return written;
#endif /* IEEE1284 support */
}

/* ECP mode, reverse channel, data. */
size_t parport_ieee1284_ecp_read_data (struct parport *port,
				       void *buffer, size_t len, int flags)
{
#ifndef CONFIG_PARPORT_1284
	return 0;
#else
	struct pardevice *dev = port->cad;
	unsigned char *buf = buffer;
	int rle_count = 0; /* shut gcc up */
	unsigned char ctl;
	int rle = 0;
	ssize_t count = 0;

	port = port->physport;

	if (port->ieee1284.phase != IEEE1284_PH_REV_IDLE)
		if (ecp_forward_to_reverse (port))
			return 0;

	port->ieee1284.phase = IEEE1284_PH_REV_DATA;

	/* Set HostAck low to start accepting data. */
	ctl = parport_read_control (port);
	ctl &= ~(PARPORT_CONTROL_STROBE | PARPORT_CONTROL_INIT |
		 PARPORT_CONTROL_AUTOFD);
	parport_write_control (port,
			       ctl | PARPORT_CONTROL_AUTOFD);
	while (count < len) {
		unsigned long expire = jiffies + dev->timeout;
		unsigned char byte;
		int command;

		/* Event 43: Peripheral sets nAck low. It can take as
                   long as it wants. */
		while (parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0)) {
			/* The peripheral hasn't given us data in
			   35ms.  If we have data to give back to the
			   caller, do it now. */
			if (count)
				goto out;

			/* If we've used up all the time we were allowed,
			   give up altogether. */
			if (!time_before (jiffies, expire))
				goto out;

			/* Yield the port for a while. */
			if (count && dev->port->irq != PARPORT_IRQ_NONE) {
				parport_release (dev);
				schedule_timeout_interruptible(msecs_to_jiffies(40));
				parport_claim_or_block (dev);
			}
			else
				/* We must have the device claimed here. */
				parport_wait_event (port, msecs_to_jiffies(40));

			/* Is there a signal pending? */
			if (signal_pending (current))
				goto out;
		}

		/* Is this a command? */
		if (rle)
			/* The last byte was a run-length count, so
                           this can't be as well. */
			command = 0;
		else
			command = (parport_read_status (port) &
				   PARPORT_STATUS_BUSY) ? 1 : 0;

		/* Read the data. */
		byte = parport_read_data (port);

		/* If this is a channel command, rather than an RLE
                   command or a normal data byte, don't accept it. */
		if (command) {
			if (byte & 0x80) {
				DPRINTK (KERN_DEBUG "%s: stopping short at "
					 "channel command (%02x)\n",
					 port->name, byte);
				goto out;
			}
			else if (port->ieee1284.mode != IEEE1284_MODE_ECPRLE)
				DPRINTK (KERN_DEBUG "%s: device illegally "
					 "using RLE; accepting anyway\n",
					 port->name);

			rle_count = byte + 1;

			/* Are we allowed to read that many bytes? */
			if (rle_count > (len - count)) {
				DPRINTK (KERN_DEBUG "%s: leaving %d RLE bytes "
					 "for next time\n", port->name,
					 rle_count);
				break;
			}

			rle = 1;
		}

		/* Event 44: Set HostAck high, acknowledging handshake. */
		parport_write_control (port, ctl);

		/* Event 45: The peripheral has 35ms to set nAck high. */
		if (parport_wait_peripheral (port, PARPORT_STATUS_ACK,
					     PARPORT_STATUS_ACK)) {
			/* It's gone wrong.  Return what data we have
                           to the caller. */
			DPRINTK (KERN_DEBUG "ECP read timed out at 45\n");

			if (command)
				printk (KERN_WARNING
					"%s: command ignored (%02x)\n",
					port->name, byte);

			break;
		}

		/* Event 46: Set HostAck low and accept the data. */
		parport_write_control (port,
				       ctl | PARPORT_CONTROL_AUTOFD);

		/* If we just read a run-length count, fetch the data. */
		if (command)
			continue;

		/* If this is the byte after a run-length count, decompress. */
		if (rle) {
			rle = 0;
			memset (buf, byte, rle_count);
			buf += rle_count;
			count += rle_count;
			DPRINTK (KERN_DEBUG "%s: decompressed to %d bytes\n",
				 port->name, rle_count);
		} else {
			/* Normal data byte. */
			*buf = byte;
			buf++, count++;
		}
	}

 out:
	port->ieee1284.phase = IEEE1284_PH_REV_IDLE;
	return count;
#endif /* IEEE1284 support */
}

/* ECP mode, forward channel, commands. */
size_t parport_ieee1284_ecp_write_addr (struct parport *port,
					const void *buffer, size_t len,
					int flags)
{
#ifndef CONFIG_PARPORT_1284
	return 0;
#else
	const unsigned char *buf = buffer;
	size_t written;
	int retry;

	port = port->physport;

	if (port->ieee1284.phase != IEEE1284_PH_FWD_IDLE)
		if (ecp_reverse_to_forward (port))
			return 0;

	port->ieee1284.phase = IEEE1284_PH_FWD_DATA;

	/* HostAck low (command, not data) */
	parport_frob_control (port,
			      PARPORT_CONTROL_AUTOFD
			      | PARPORT_CONTROL_STROBE
			      | PARPORT_CONTROL_INIT,
			      PARPORT_CONTROL_AUTOFD
			      | PARPORT_CONTROL_INIT);
	for (written = 0; written < len; written++, buf++) {
		unsigned long expire = jiffies + port->cad->timeout;
		unsigned char byte;

		byte = *buf;
	try_again:
		parport_write_data (port, byte);
		parport_frob_control (port, PARPORT_CONTROL_STROBE,
				      PARPORT_CONTROL_STROBE);
		udelay (5);
		for (retry = 0; retry < 100; retry++) {
			if (!parport_wait_peripheral (port,
						      PARPORT_STATUS_BUSY, 0))
				goto success;

			if (signal_pending (current)) {
				parport_frob_control (port,
						      PARPORT_CONTROL_STROBE,
						      0);
				break;
			}
		}

		/* Time for Host Transfer Recovery (page 41 of IEEE1284) */
		DPRINTK (KERN_DEBUG "%s: ECP transfer stalled!\n", port->name);

		parport_frob_control (port, PARPORT_CONTROL_INIT,
				      PARPORT_CONTROL_INIT);
		udelay (50);
		if (parport_read_status (port) & PARPORT_STATUS_PAPEROUT) {
			/* It's buggered. */
			parport_frob_control (port, PARPORT_CONTROL_INIT, 0);
			break;
		}

		parport_frob_control (port, PARPORT_CONTROL_INIT, 0);
		udelay (50);
		if (!(parport_read_status (port) & PARPORT_STATUS_PAPEROUT))
			break;

		DPRINTK (KERN_DEBUG "%s: Host transfer recovered\n",
			 port->name);

		if (time_after_eq (jiffies, expire)) break;
		goto try_again;
	success:
		parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
		udelay (5);
		if (parport_wait_peripheral (port,
					     PARPORT_STATUS_BUSY,
					     PARPORT_STATUS_BUSY))
			/* Peripheral hasn't accepted the data. */
			break;
	}

	port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;

	return written;
#endif /* IEEE1284 support */
}

/***              *
 * EPP functions. *
 *              ***/

/* EPP mode, forward channel, data. */
size_t parport_ieee1284_epp_write_data (struct parport *port,
					const void *buffer, size_t len,
					int flags)
{
	unsigned char *bp = (unsigned char *) buffer;
	size_t ret = 0;

	/* set EPP idle state (just to make sure) with strobe low */
	parport_frob_control (port,
			      PARPORT_CONTROL_STROBE |
			      PARPORT_CONTROL_AUTOFD |
			      PARPORT_CONTROL_SELECT |
			      PARPORT_CONTROL_INIT,
			      PARPORT_CONTROL_STROBE |
			      PARPORT_CONTROL_INIT);
	port->ops->data_forward (port);
	for (; len > 0; len--, bp++) {
		/* Event 62: Write data and set autofd low */
		parport_write_data (port, *bp);
		parport_frob_control (port, PARPORT_CONTROL_AUTOFD,
				      PARPORT_CONTROL_AUTOFD);

		/* Event 58: wait for busy (nWait) to go high */
		if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY, 0, 10))
			break;

		/* Event 63: set nAutoFd (nDStrb) high */
		parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);

		/* Event 60: wait for busy (nWait) to go low */
		if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,
					     PARPORT_STATUS_BUSY, 5))
			break;

		ret++;
	}

	/* Event 61: set strobe (nWrite) high */
	parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);

	return ret;
}

/* EPP mode, reverse channel, data. */
size_t parport_ieee1284_epp_read_data (struct parport *port,
				       void *buffer, size_t len,
				       int flags)
{
	unsigned char *bp = (unsigned char *) buffer;
	unsigned ret = 0;

	/* set EPP idle state (just to make sure) with strobe high */
	parport_frob_control (port,
			      PARPORT_CONTROL_STROBE |
			      PARPORT_CONTROL_AUTOFD |
			      PARPORT_CONTROL_SELECT |
			      PARPORT_CONTROL_INIT,
			      PARPORT_CONTROL_INIT);
	port->ops->data_reverse (port);
	for (; len > 0; len--, bp++) {
		/* Event 67: set nAutoFd (nDStrb) low */
		parport_frob_control (port,
				      PARPORT_CONTROL_AUTOFD,
				      PARPORT_CONTROL_AUTOFD);
		/* Event 58: wait for Busy to go high */
		if (parport_wait_peripheral (port, PARPORT_STATUS_BUSY, 0)) {
			break;
		}

		*bp = parport_read_data (port);

		/* Event 63: set nAutoFd (nDStrb) high */
		parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);

		/* Event 60: wait for Busy to go low */
		if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,
					     PARPORT_STATUS_BUSY, 5)) {
			break;
		}

		ret++;
	}
	port->ops->data_forward (port);

	return ret;
}

/* EPP mode, forward channel, addresses. */
size_t parport_ieee1284_epp_write_addr (struct parport *port,
					const void *buffer, size_t len,
					int flags)
{
	unsigned char *bp = (unsigned char *) buffer;
	size_t ret = 0;

	/* set EPP idle state (just to make sure) with strobe low */
	parport_frob_control (port,
			      PARPORT_CONTROL_STROBE |
			      PARPORT_CONTROL_AUTOFD |
			      PARPORT_CONTROL_SELECT |
			      PARPORT_CONTROL_INIT,
			      PARPORT_CONTROL_STROBE |
			      PARPORT_CONTROL_INIT);
	port->ops->data_forward (port);
	for (; len > 0; len--, bp++) {
		/* Event 56: Write data and set nAStrb low. */
		parport_write_data (port, *bp);
		parport_frob_control (port, PARPORT_CONTROL_SELECT,
				      PARPORT_CONTROL_SELECT);

		/* Event 58: wait for busy (nWait) to go high */
		if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY, 0, 10))
			break;

		/* Event 59: set nAStrb high */
		parport_frob_control (port, PARPORT_CONTROL_SELECT, 0);

		/* Event 60: wait for busy (nWait) to go low */
		if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY,
					     PARPORT_STATUS_BUSY, 5))
			break;

		ret++;
	}

	/* Event 61: set strobe (nWrite) high */
	parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);

	return ret;
}

/* EPP mode, reverse channel, addresses. */
size_t parport_ieee1284_epp_read_addr (struct parport *port,
				       void *buffer, size_t len,
				       int flags)
{
	unsigned char *bp = (unsigned char *) buffer;
	unsigned ret = 0;

	/* Set EPP idle state (just to make sure) with strobe high */
	parport_frob_control (port,
			      PARPORT_CONTROL_STROBE |
			      PARPORT_CONTROL_AUTOFD |
			      PARPORT_CONTROL_SELECT |
			      PARPORT_CONTROL_INIT,
			      PARPORT_CONTROL_INIT);
	port->ops->data_reverse (port);
	for (; len > 0; len--, bp++) {
		/* Event 64: set nSelectIn (nAStrb) low */
		parport_frob_control (port, PARPORT_CONTROL_SELECT,
				      PARPORT_CONTROL_SELECT);

		/* Event 58: wait for Busy to go high */
		if (parport_wait_peripheral (port, PARPORT_STATUS_BUSY, 0)) {
			break;
		}

		*bp = parport_read_data (port);

		/* Event 59: set nSelectIn (nAStrb) high */
		parport_frob_control (port, PARPORT_CONTROL_SELECT,
				      PARPORT_CONTROL_SELECT);

		/* Event 60: wait for Busy to go low */
		if (parport_poll_peripheral (port, PARPORT_STATUS_BUSY, 
					     PARPORT_STATUS_BUSY, 5))
			break;

		ret++;
	}
	port->ops->data_forward (port);

	return ret;
}

EXPORT_SYMBOL(parport_ieee1284_ecp_write_data);
EXPORT_SYMBOL(parport_ieee1284_ecp_read_data);
EXPORT_SYMBOL(parport_ieee1284_ecp_write_addr);
EXPORT_SYMBOL(parport_ieee1284_write_compat);
EXPORT_SYMBOL(parport_ieee1284_read_nibble);
EXPORT_SYMBOL(parport_ieee1284_read_byte);
EXPORT_SYMBOL(parport_ieee1284_epp_write_data);
EXPORT_SYMBOL(parport_ieee1284_epp_read_data);
EXPORT_SYMBOL(parport_ieee1284_epp_write_addr);
EXPORT_SYMBOL(parport_ieee1284_epp_read_addr);
