/* 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)) {
			goto end_of_data;
		}

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

	if (i == len) {
		/* Read the last nibble without checking data avail. */
		if (parport_read_status (port) & PARPORT_STATUS_ERROR) {
		end_of_data:
			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;
		}
		else
			port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
	}

	return i/2;
#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) {
			goto end_of_data;
		}

		/* 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. */
		if (parport_read_status (port) & PARPORT_STATUS_ERROR) {
		end_of_data:
			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;
		}
		else
			port->physport->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);
