Blame src/default.c

Packit d36e9b
/*
Packit d36e9b
 * libieee1284 - IEEE 1284 library
Packit d36e9b
 * Copyright (C) 2000-2001 Hewlett-Packard Company
Packit d36e9b
 * Integrated into libieee1284:
Packit d36e9b
 * Copyright (C) 2001-2003  Tim Waugh <twaugh@redhat.com>
Packit d36e9b
 *
Packit d36e9b
 * This program is free software; you can redistribute it and/or modify
Packit d36e9b
 * it under the terms of the GNU General Public License as published by
Packit d36e9b
 * the Free Software Foundation; either version 2 of the License, or
Packit d36e9b
 * (at your option) any later version.
Packit d36e9b
 *
Packit d36e9b
 * This program is distributed in the hope that it will be useful,
Packit d36e9b
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit d36e9b
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit d36e9b
 * GNU General Public License for more details.
Packit d36e9b
 *
Packit d36e9b
 * You should have received a copy of the GNU General Public License
Packit d36e9b
 * along with this program; if not, write to the Free Software
Packit d36e9b
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit d36e9b
 */
Packit d36e9b
Packit d36e9b
#include <string.h>
Packit d36e9b
#ifndef _MSC_VER
Packit d36e9b
#include <sys/time.h>
Packit d36e9b
#endif
Packit d36e9b
#include <sys/types.h>
Packit d36e9b
#ifdef __unix__
Packit d36e9b
#include <unistd.h>
Packit d36e9b
#endif
Packit d36e9b
#if defined __MINGW32__ || defined _MSC_VER
Packit d36e9b
#include <sys/timeb.h>
Packit d36e9b
#endif
Packit d36e9b
Packit d36e9b
#include "access.h"
Packit d36e9b
#include "debug.h"
Packit d36e9b
#include "delay.h"
Packit d36e9b
#include "detect.h"
Packit d36e9b
#include "ieee1284.h"
Packit d36e9b
Packit d36e9b
static const char *no_default = "no default implementation of %s\n";
Packit d36e9b
Packit d36e9b
int
Packit d36e9b
default_wait_data (struct parport_internal *port, unsigned char mask,
Packit d36e9b
		   unsigned char val, struct timeval *timeout)
Packit d36e9b
{
Packit d36e9b
  /* Simple-minded polling.  TODO: Use David Paschal's method for this. */
Packit d36e9b
#if !(defined __MINGW32__ || defined _MSC_VER)
Packit d36e9b
  struct timeval deadline, now;
Packit d36e9b
  gettimeofday (&deadline, NULL);
Packit d36e9b
  deadline.tv_sec += timeout->tv_sec;
Packit d36e9b
  deadline.tv_usec += timeout->tv_usec;
Packit d36e9b
  deadline.tv_sec += deadline.tv_usec / 1000000;
Packit d36e9b
  deadline.tv_usec %= 1000000;
Packit d36e9b
#else
Packit d36e9b
  struct timeb tb;
Packit d36e9b
  int deadline, now;
Packit d36e9b
  ftime (&tb);
Packit d36e9b
  deadline = tb.time * 1000 + tb.millitm +
Packit d36e9b
             timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
Packit d36e9b
#endif
Packit d36e9b
Packit d36e9b
  do
Packit d36e9b
    {
Packit d36e9b
      if ((port->fn->read_data (port) & mask) == val)
Packit d36e9b
        return E1284_OK;
Packit d36e9b
Packit d36e9b
      delay (IO_POLL_DELAY);
Packit d36e9b
#if !(defined __MINGW32__ || defined _MSC_VER)
Packit d36e9b
      gettimeofday (&now, NULL);
Packit d36e9b
    }
Packit d36e9b
  while (now.tv_sec < deadline.tv_sec ||
Packit d36e9b
	 (now.tv_sec == deadline.tv_sec &&
Packit d36e9b
	  now.tv_usec < deadline.tv_usec));
Packit d36e9b
#else
Packit d36e9b
      ftime (&tb);
Packit d36e9b
      now = tb.time * 1000 + tb.millitm;
Packit d36e9b
    }
Packit d36e9b
  while (now < deadline);
Packit d36e9b
#endif
Packit d36e9b
Packit d36e9b
  return E1284_TIMEDOUT;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
int
Packit d36e9b
default_do_nack_handshake (struct parport_internal *port,
Packit d36e9b
			   unsigned char ct_before,
Packit d36e9b
			   unsigned char ct_after,
Packit d36e9b
			   struct timeval *timeout)
Packit d36e9b
{
Packit d36e9b
  /* There is a possible implementation using /proc/interrupts on Linux.. */
Packit d36e9b
  debugprintf (no_default, "no_nack_handshake");
Packit d36e9b
  return E1284_NOTIMPL;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
int
Packit d36e9b
default_negotiate (struct parport_internal *port, int mode)
Packit d36e9b
{
Packit d36e9b
  const struct parport_access_methods *fn = port->fn;
Packit d36e9b
  int ret = E1284_NEGFAILED;
Packit d36e9b
  struct timeval tv;
Packit d36e9b
  int m = mode;
Packit d36e9b
Packit d36e9b
  debugprintf ("==> default_negotiate (to %#02x)\n", mode);
Packit d36e9b
Packit d36e9b
  if (mode == port->current_mode)
Packit d36e9b
    {
Packit d36e9b
      debugprintf ("<== E1284_OK (nothing to do!)\n");
Packit d36e9b
      return E1284_OK;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
  if (mode == M1284_COMPAT)
Packit d36e9b
    {
Packit d36e9b
      ret = E1284_OK;
Packit d36e9b
      goto abort;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
  switch (mode)
Packit d36e9b
    {
Packit d36e9b
    case M1284_ECPSWE:
Packit d36e9b
      m = M1284_ECP;
Packit d36e9b
      break;
Packit d36e9b
    case M1284_EPPSL:
Packit d36e9b
    case M1284_EPPSWE:
Packit d36e9b
      m = M1284_EPP;
Packit d36e9b
      break;
Packit d36e9b
    case M1284_BECP:
Packit d36e9b
      m = 0x18;
Packit d36e9b
      break;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
  if (mode & M1284_FLAG_EXT_LINK)
Packit d36e9b
    m = 1<<7; /* Request extensibility link */
Packit d36e9b
Packit d36e9b
  /* Event 0: Write extensibility request to data lines. */
Packit d36e9b
  fn->write_data (port, (unsigned char)m);
Packit d36e9b
  debugprintf ("IEEE 1284 mode %#02x\n", m);
Packit d36e9b
Packit d36e9b
  /* Event 1: nSelectIn=1, nAutoFd=0, nStrobe=1, nInit=1. */
Packit d36e9b
  fn->frob_control (port,
Packit d36e9b
		    C1284_NSELECTIN|C1284_NSTROBE|C1284_NINIT
Packit d36e9b
		    |C1284_NAUTOFD,
Packit d36e9b
		    C1284_NSELECTIN|C1284_NSTROBE|C1284_NINIT);
Packit d36e9b
Packit d36e9b
  /* Event 2: PError=1, Select=1, nFault=1, nAck=0. */
Packit d36e9b
  lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
  if (fn->wait_status (port,
Packit d36e9b
		       S1284_PERROR|S1284_SELECT|S1284_NFAULT
Packit d36e9b
		       |S1284_NACK,
Packit d36e9b
		       S1284_PERROR|S1284_SELECT|S1284_NFAULT, &tv))
Packit d36e9b
  {
Packit d36e9b
    debugprintf ("Failed at event 2\n");
Packit d36e9b
    goto abort;
Packit d36e9b
  }
Packit d36e9b
Packit d36e9b
  /* Event 3: nStrobe=0. */
Packit d36e9b
  fn->frob_control (port, C1284_NSTROBE, 0);
Packit d36e9b
  delay (TIMEVAL_STROBE_DELAY);
Packit d36e9b
Packit d36e9b
  /* Event 4: nStrobe=1, nAutoFd=1. */
Packit d36e9b
  fn->frob_control (port, C1284_NSTROBE|C1284_NAUTOFD,
Packit d36e9b
		    C1284_NSTROBE|C1284_NAUTOFD);
Packit d36e9b
Packit d36e9b
  /* Event 6: nAck=1. */
Packit d36e9b
  lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
  if (fn->wait_status (port, S1284_NACK, S1284_NACK, &tv))
Packit d36e9b
  {
Packit d36e9b
    debugprintf ("Failed at event 6\n");
Packit d36e9b
    goto abort;
Packit d36e9b
  }
Packit d36e9b
Packit d36e9b
  /* Event 5: Select=0 for nibble-0, =1 for other modes. */
Packit d36e9b
  port->current_mode = !mode;
Packit d36e9b
  if ((fn->read_status (port) & S1284_SELECT) !=
Packit d36e9b
      (mode ? S1284_SELECT : 0))
Packit d36e9b
    {
Packit d36e9b
      ret = E1284_REJECTED;
Packit d36e9b
      debugprintf ("Mode rejected\n");
Packit d36e9b
      goto abort;
Packit d36e9b
    }
Packit d36e9b
  port->current_mode = mode;
Packit d36e9b
Packit d36e9b
  /* Extra signalling for ECP mode. */
Packit d36e9b
  if (m & M1284_ECP)
Packit d36e9b
    {
Packit d36e9b
      /* Event 30: nAutoFd=0. */
Packit d36e9b
      fn->frob_control (port, C1284_NAUTOFD, 0);
Packit d36e9b
Packit d36e9b
      /* Event 31: PError=1. */
Packit d36e9b
      lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
      if (fn->wait_status (port, S1284_PERROR, S1284_PERROR, &tv))
Packit d36e9b
      {
Packit d36e9b
	debugprintf ("Failed at event 31\n");
Packit d36e9b
	goto abort;
Packit d36e9b
      }
Packit d36e9b
Packit d36e9b
      port->current_channel=0;
Packit d36e9b
      port->current_phase = PH1284_FWD_IDLE;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
  debugprintf ("<== E1284_OK\n");
Packit d36e9b
  return E1284_OK;
Packit d36e9b
Packit d36e9b
 abort:
Packit d36e9b
  fn->terminate(port);
Packit d36e9b
  debugprintf ("<== %d\n", ret);
Packit d36e9b
  return ret;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
void
Packit d36e9b
default_terminate (struct parport_internal *port)
Packit d36e9b
{
Packit d36e9b
  const struct parport_access_methods *fn = port->fn;
Packit d36e9b
  struct timeval tv;
Packit d36e9b
Packit d36e9b
  /* Termination may only be accomplished from the forward phase */
Packit d36e9b
  if (port->current_phase == PH1284_REV_IDLE) 
Packit d36e9b
    /* even if this fails we're trucking on */
Packit d36e9b
    fn->ecp_rev_to_fwd(port);
Packit d36e9b
Packit d36e9b
  fn->write_control (port, C1284_NINIT | C1284_NAUTOFD | C1284_NSTROBE);
Packit d36e9b
Packit d36e9b
  /* Even if this fails we are now implicitly back in compat mode because we 
Packit d36e9b
   * have dropped nSelectIn */
Packit d36e9b
  port->current_mode = M1284_COMPAT;
Packit d36e9b
Packit d36e9b
  lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
  if (fn->wait_status (port, S1284_NACK, 0, &tv) != E1284_OK)
Packit d36e9b
    return;
Packit d36e9b
	
Packit d36e9b
  fn->write_control (port, C1284_NINIT | C1284_NSTROBE);
Packit d36e9b
Packit d36e9b
  lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
  if (fn->wait_status (port, S1284_NACK, S1284_NACK, 
Packit d36e9b
		       &tv) != E1284_OK)
Packit d36e9b
    return;
Packit d36e9b
Packit d36e9b
  fn->write_control (port, C1284_NINIT | C1284_NAUTOFD | C1284_NSTROBE);
Packit d36e9b
Packit d36e9b
  return;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
int
Packit d36e9b
default_ecp_fwd_to_rev (struct parport_internal *port)
Packit d36e9b
{
Packit d36e9b
  const struct parport_access_methods *fn = port->fn;
Packit d36e9b
  int retval;
Packit d36e9b
  struct timeval tv;
Packit d36e9b
Packit d36e9b
  debugprintf ("==> default_ecp_fwd_to_rev\n");
Packit d36e9b
Packit d36e9b
  /* Event 38: Set nAutoFd low */
Packit d36e9b
  fn->frob_control (port, C1284_NAUTOFD, 0);
Packit d36e9b
Packit d36e9b
  /* This will always work. If it won't then this method isn't available */
Packit d36e9b
  fn->data_dir (port, 1);
Packit d36e9b
  udelay (5);
Packit d36e9b
Packit d36e9b
  /* Event 39: Set nInit low to initiate bus reversal */
Packit d36e9b
  fn->frob_control (port, C1284_NINIT, 0);
Packit d36e9b
Packit d36e9b
  /* Event 40: PError goes low */
Packit d36e9b
  lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
  retval = fn->wait_status (port, S1284_PERROR, 0, &tv;;
Packit d36e9b
Packit d36e9b
  if (retval) {
Packit d36e9b
    debugprintf ("ECP direction: failed to reverse\n");
Packit d36e9b
    port->current_phase = PH1284_ECP_DIR_UNKNOWN;
Packit d36e9b
  } else {
Packit d36e9b
    port->current_phase = PH1284_REV_IDLE;
Packit d36e9b
  }
Packit d36e9b
Packit d36e9b
  debugprintf ("<== %d default_ecp_fwd_to_rev\n", retval);
Packit d36e9b
  return retval;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
int
Packit d36e9b
default_ecp_rev_to_fwd (struct parport_internal *port)
Packit d36e9b
{
Packit d36e9b
  const struct parport_access_methods *fn = port->fn;
Packit d36e9b
  int retval;
Packit d36e9b
  struct timeval tv;
Packit d36e9b
Packit d36e9b
  debugprintf ("==> default_ecp_rev_to_fwd\n");
Packit d36e9b
Packit d36e9b
  /* Event 47: Set nInit high */
Packit d36e9b
  fn->frob_control (port, C1284_NINIT | C1284_NAUTOFD, 
Packit d36e9b
	            C1284_NINIT | C1284_NAUTOFD);
Packit d36e9b
Packit d36e9b
  /* Event 49: PError goes high */
Packit d36e9b
  lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
  retval = fn->wait_status (port, S1284_PERROR, S1284_PERROR, &tv;;
Packit d36e9b
Packit d36e9b
  if (!retval) {
Packit d36e9b
    fn->data_dir (port, 0);
Packit d36e9b
    port->current_phase = PH1284_FWD_IDLE;
Packit d36e9b
  } else {
Packit d36e9b
    debugprintf ("ECP direction: failed to switch forward\n");
Packit d36e9b
    port->current_phase = PH1284_ECP_DIR_UNKNOWN;
Packit d36e9b
  }
Packit d36e9b
Packit d36e9b
  debugprintf ("<== %d default_ecp_rev_to_fwd\n", retval);
Packit d36e9b
  return retval;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
ssize_t
Packit d36e9b
default_nibble_read (struct parport_internal *port, int flags,
Packit d36e9b
		     char *buffer, size_t len)
Packit d36e9b
{
Packit d36e9b
  const struct parport_access_methods *fn = port->fn;
Packit d36e9b
  size_t count = 0;
Packit d36e9b
  int datain;
Packit d36e9b
  int low, high;
Packit d36e9b
  struct timeval tv;
Packit d36e9b
Packit d36e9b
  debugprintf ("==> default_nibble_read\n");
Packit d36e9b
Packit d36e9b
  /* start of reading data from the scanner */
Packit d36e9b
  while (count < len)
Packit d36e9b
    {
Packit d36e9b
      /* More data? */
Packit d36e9b
      if ((count & 1) == 0 &&
Packit d36e9b
	  (fn->read_status (port) & S1284_NFAULT))
Packit d36e9b
	{
Packit d36e9b
	  debugprintf ("No more data\n");
Packit d36e9b
	  fn->frob_control (port, C1284_NAUTOFD, 0);
Packit d36e9b
	  break;
Packit d36e9b
	}
Packit d36e9b
Packit d36e9b
      fn->write_control (port, C1284_NSTROBE | C1284_NINIT | C1284_NSELECTIN);
Packit d36e9b
Packit d36e9b
      lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
      if (fn->wait_status (port, S1284_NACK, 0, &tv) 
Packit d36e9b
	  != E1284_OK)
Packit d36e9b
	goto error;
Packit d36e9b
Packit d36e9b
      low = fn->read_status (port) >> 3;
Packit d36e9b
      low = (low & 0x07) + ((low & 0x10) >> 1);
Packit d36e9b
Packit d36e9b
      fn->write_control (port, C1284_NSTROBE | C1284_NINIT | C1284_NSELECTIN
Packit d36e9b
			 | C1284_NAUTOFD);
Packit d36e9b
Packit d36e9b
      lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
      if (fn->wait_status (port, S1284_NACK, S1284_NACK, &tv) 
Packit d36e9b
	  != E1284_OK)
Packit d36e9b
	goto error;
Packit d36e9b
Packit d36e9b
      fn->write_control (port, C1284_NSTROBE | C1284_NINIT | C1284_NSELECTIN);
Packit d36e9b
Packit d36e9b
      lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
      if (fn->wait_status (port, S1284_NACK, 0, &tv) 
Packit d36e9b
	  != E1284_OK)
Packit d36e9b
	goto error;
Packit d36e9b
Packit d36e9b
      high = fn->read_status (port) >> 3;
Packit d36e9b
      high = (high & 0x07) | ((high & 0x10) >> 1);
Packit d36e9b
Packit d36e9b
      fn->write_control (port, C1284_NSTROBE | C1284_NINIT | C1284_NSELECTIN
Packit d36e9b
			 | C1284_NAUTOFD);
Packit d36e9b
Packit d36e9b
      lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
      if (fn->wait_status (port, S1284_NACK, S1284_NACK, &tv) 
Packit d36e9b
	  != E1284_OK)
Packit d36e9b
	goto error;
Packit d36e9b
Packit d36e9b
      datain = (high << 4) + low;
Packit d36e9b
Packit d36e9b
      buffer[count] = datain & 0xff;
Packit d36e9b
      count++;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
  debugprintf ("<== %d\n", len);
Packit d36e9b
  return len; 
Packit d36e9b
Packit d36e9b
 error:
Packit d36e9b
  fn->terminate (port);
Packit d36e9b
  debugprintf ("<== %d (terminated on error)\n", count);
Packit d36e9b
  return count;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
ssize_t
Packit d36e9b
default_compat_write (struct parport_internal *port, int flags,
Packit d36e9b
		      const char *buffer, size_t len)
Packit d36e9b
{
Packit d36e9b
  const struct parport_access_methods *fn = port->fn;
Packit d36e9b
  size_t count = 0;
Packit d36e9b
  struct timeval tv;
Packit d36e9b
Packit d36e9b
  debugprintf ("==> default_compat_write\n");
Packit d36e9b
Packit d36e9b
  while (count < len)
Packit d36e9b
    {		
Packit d36e9b
      lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
      if (fn->wait_status (port, S1284_BUSY, 0, &tv) != E1284_OK)
Packit d36e9b
	goto error;
Packit d36e9b
Packit d36e9b
      /* Tsetup: 750ns min. */
Packit d36e9b
      delay (TIMEVAL_STROBE_DELAY);
Packit d36e9b
Packit d36e9b
      /* Get the data byte ready */
Packit d36e9b
      fn->write_data (port, buffer[count]);
Packit d36e9b
Packit d36e9b
      /* Pulse nStrobe low */
Packit d36e9b
      fn->write_control (port, C1284_NINIT | C1284_NAUTOFD);
Packit d36e9b
Packit d36e9b
      /* Tstrobe: 750ns - 500us */
Packit d36e9b
      delay (TIMEVAL_STROBE_DELAY);
Packit d36e9b
Packit d36e9b
      /* And raise it */
Packit d36e9b
      fn->write_control (port, C1284_NINIT | C1284_NAUTOFD | C1284_NSTROBE);
Packit d36e9b
Packit d36e9b
      /* Thold: 750ns min. */
Packit d36e9b
      delay (TIMEVAL_STROBE_DELAY);
Packit d36e9b
Packit d36e9b
      count++;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
  debugprintf ("<== %d\n", len);
Packit d36e9b
  return len;
Packit d36e9b
Packit d36e9b
 error:
Packit d36e9b
  fn->terminate (port);
Packit d36e9b
  debugprintf ("<== %d (terminated on error)\n", count);
Packit d36e9b
  return count;  
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
ssize_t
Packit d36e9b
default_byte_read (struct parport_internal *port, int flags,
Packit d36e9b
		   char *buffer, size_t len)
Packit d36e9b
{
Packit d36e9b
Packit d36e9b
  const struct parport_access_methods *fn = port->fn;
Packit d36e9b
  unsigned char *buf = buffer;
Packit d36e9b
  size_t count = 0;
Packit d36e9b
  struct timeval tv;
Packit d36e9b
Packit d36e9b
  /* FIXME: Untested as yet, copied from ieee1284_op.c,
Packit d36e9b
   * inverted appropriate signals  */
Packit d36e9b
Packit d36e9b
  debugprintf ("==> default_byte_read\n");
Packit d36e9b
Packit d36e9b
  for (count = 0; count < len; count++) {
Packit d36e9b
    unsigned char byte;
Packit d36e9b
Packit d36e9b
    /* Data available? */
Packit d36e9b
    if (fn->read_status (port) & S1284_PERROR) {
Packit d36e9b
      /* Go to reverse idle phase. */
Packit d36e9b
      fn->frob_control (port, C1284_NAUTOFD, C1284_NAUTOFD);
Packit d36e9b
      break;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
    /* Event 14: Place data bus in high impedance state. */
Packit d36e9b
    fn->data_dir (port, 1);
Packit d36e9b
Packit d36e9b
    /* Event 7: Set nAutoFd low. */
Packit d36e9b
    fn->frob_control (port, C1284_NAUTOFD, 0);
Packit d36e9b
Packit d36e9b
    /* Event 9: nAck goes low. */
Packit d36e9b
    lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
    if (fn->wait_status (port, S1284_NACK, 0, &tv)) {
Packit d36e9b
      /* Timeout -- no more data? */
Packit d36e9b
      fn->frob_control (port, C1284_NAUTOFD, C1284_NAUTOFD);
Packit d36e9b
      debugprintf ("Byte timeout at event 9\n");
Packit d36e9b
      break;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
    byte = fn->read_data (port);
Packit d36e9b
    *buf++ = byte;
Packit d36e9b
Packit d36e9b
    /* Event 10: Set nAutoFd high */
Packit d36e9b
    fn->frob_control (port, C1284_NAUTOFD, C1284_NAUTOFD);
Packit d36e9b
Packit d36e9b
    /* Event 11: nAck goes high. */
Packit d36e9b
    lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
    if (fn->wait_status (port, S1284_NACK, S1284_NACK, &tv)) {
Packit d36e9b
      /* Timeout -- no more data? */
Packit d36e9b
      debugprintf ("Byte timeout at event 11\n");
Packit d36e9b
      break;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
    /* Event 16: Set nStrobe low. */
Packit d36e9b
    fn->frob_control (port, C1284_NSTROBE, 0);
Packit d36e9b
    udelay (5);
Packit d36e9b
Packit d36e9b
    /* Event 17: Set nStrobe high. */
Packit d36e9b
    fn->frob_control (port, C1284_NSTROBE, C1284_NSTROBE);
Packit d36e9b
  }
Packit d36e9b
Packit d36e9b
  debugprintf ("<== %d default_byte_read\n", count);
Packit d36e9b
Packit d36e9b
  return count;
Packit d36e9b
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
ssize_t
Packit d36e9b
default_epp_read_data (struct parport_internal *port, int flags,
Packit d36e9b
		       char *buffer, size_t len)
Packit d36e9b
{
Packit d36e9b
  const struct parport_access_methods *fn = port->fn;
Packit d36e9b
  unsigned char *buf = buffer;
Packit d36e9b
  ssize_t count = 0;
Packit d36e9b
  struct timeval tv;
Packit d36e9b
Packit d36e9b
  /* FIXME: Untested as yet, copied from ieee1284_op.c, 
Packit d36e9b
   * inverted appropriate signals  */
Packit d36e9b
Packit d36e9b
  debugprintf ("==> default_epp_read_data\n");
Packit d36e9b
Packit d36e9b
  /* set EPP idle state (just to make sure) with strobe high */
Packit d36e9b
  fn->frob_control (port, C1284_NSTROBE | C1284_NAUTOFD | 
Packit d36e9b
	                  C1284_NSELECTIN | C1284_NINIT,
Packit d36e9b
	                  C1284_NSTROBE | C1284_NINIT);
Packit d36e9b
  fn->data_dir (port, 1);
Packit d36e9b
Packit d36e9b
  for (; len > 0; len--, buf++) {
Packit d36e9b
    /* Event 67: set nAutoFd (nDStrb) low */
Packit d36e9b
    fn->frob_control (port, C1284_NAUTOFD, 0);
Packit d36e9b
    /* Event 58: wait for Busy to go high */
Packit d36e9b
    lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
    if (fn->wait_status (port, S1284_BUSY, S1284_BUSY, &tv)) {
Packit d36e9b
      break;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
    *buf = fn->read_data (port);
Packit d36e9b
Packit d36e9b
    /* Event 63: set nAutoFd (nDStrb) high */
Packit d36e9b
    fn->frob_control (port, C1284_NAUTOFD, C1284_NAUTOFD);
Packit d36e9b
Packit d36e9b
    /* Event 60: wait for Busy to go low */
Packit d36e9b
    lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
    if (fn->wait_status (port, S1284_BUSY, 0, &tv)) {
Packit d36e9b
      break;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
    count++;
Packit d36e9b
  }
Packit d36e9b
  fn->data_dir (port, 0);
Packit d36e9b
Packit d36e9b
  debugprintf ("<== default_epp_read_data\n");
Packit d36e9b
  return count;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
static int poll_port (struct parport_internal *port, unsigned char mask,
Packit d36e9b
		      unsigned char result, int usec)
Packit d36e9b
{
Packit d36e9b
  const struct parport_access_methods *fn = port->fn;
Packit d36e9b
  int count = usec / 5 + 2;
Packit d36e9b
  int i;
Packit d36e9b
Packit d36e9b
  for (i = 0; i < count; i++)
Packit d36e9b
    {
Packit d36e9b
      unsigned char status = fn->read_status (port);
Packit d36e9b
Packit d36e9b
      if ((status & mask) == result)
Packit d36e9b
	return E1284_OK;
Packit d36e9b
Packit d36e9b
      if (i >= 2)
Packit d36e9b
	udelay (5);
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
  return E1284_TIMEDOUT;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
ssize_t
Packit d36e9b
default_epp_write_data (struct parport_internal *port, int flags,
Packit d36e9b
			const char *buffer, size_t len)
Packit d36e9b
{
Packit d36e9b
  const struct parport_access_methods *fn = port->fn;
Packit d36e9b
  ssize_t ret = 0;
Packit d36e9b
Packit d36e9b
  debugprintf ("==> default_epp_write_data\n");
Packit d36e9b
Packit d36e9b
  /* Set EPP idle state (just to make sure).  Also set nStrobe low. */
Packit d36e9b
  fn->frob_control (port,
Packit d36e9b
		    C1284_NSTROBE | C1284_NAUTOFD
Packit d36e9b
		    | C1284_NSELECTIN | C1284_NINIT,
Packit d36e9b
		    C1284_NAUTOFD | C1284_NSELECTIN | C1284_NINIT);
Packit d36e9b
Packit d36e9b
  fn->data_dir (port, 0);
Packit d36e9b
Packit d36e9b
  for (; len > 0; len--, buffer++)
Packit d36e9b
    {
Packit d36e9b
      /* Event 62: Write data and set nAutoFd low */
Packit d36e9b
      fn->write_data (port, *buffer);
Packit d36e9b
      fn->frob_control (port, C1284_NAUTOFD, 0);
Packit d36e9b
Packit d36e9b
      /* Event 58: wait for busy (nWait) to go high */
Packit d36e9b
      if (poll_port (port, S1284_BUSY, S1284_BUSY, 10) != E1284_OK)
Packit d36e9b
	{
Packit d36e9b
	  debugprintf ("Failed at event 58\n");
Packit d36e9b
	  break;
Packit d36e9b
	}
Packit d36e9b
Packit d36e9b
      /* Event 63: set nAutoFd (nDStrb) high */
Packit d36e9b
      fn->frob_control (port, C1284_NAUTOFD, C1284_NAUTOFD);
Packit d36e9b
Packit d36e9b
      /* Event 60: wait for busy (nWait) to go low */
Packit d36e9b
      if (poll_port (port, S1284_BUSY, 0, 5) != E1284_OK)
Packit d36e9b
	{
Packit d36e9b
	  debugprintf ("Failed at event 60\n");
Packit d36e9b
	  break;
Packit d36e9b
	}
Packit d36e9b
Packit d36e9b
      ret++;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
  debugprintf ("<== %d\n", ret);
Packit d36e9b
  return ret;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
ssize_t
Packit d36e9b
default_epp_read_addr (struct parport_internal *port, int flags,
Packit d36e9b
		       char *buffer, size_t len)
Packit d36e9b
{
Packit d36e9b
  return E1284_NOTIMPL;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
ssize_t
Packit d36e9b
default_epp_write_addr (struct parport_internal *port, int flags,
Packit d36e9b
			const char *buffer, size_t len)
Packit d36e9b
{
Packit d36e9b
  return E1284_NOTIMPL;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
ssize_t
Packit d36e9b
default_ecp_read_data (struct parport_internal *port, int flags,
Packit d36e9b
		       char *buffer, size_t len)
Packit d36e9b
{
Packit d36e9b
  /* FIXME: RLE Not tested yet because it's not reported as being available
Packit d36e9b
   * by the upper layers */
Packit d36e9b
Packit d36e9b
  const struct parport_access_methods *fn = port->fn;
Packit d36e9b
  
Packit d36e9b
  unsigned char *buf = buffer;
Packit d36e9b
  size_t rle_count = 0; /* shut gcc up */
Packit d36e9b
  int rle = 0;
Packit d36e9b
  size_t count = 0;
Packit d36e9b
  struct timeval tv;
Packit d36e9b
Packit d36e9b
  debugprintf ("==> default_ecp_read_data\n");
Packit d36e9b
Packit d36e9b
  if (port->current_phase != PH1284_REV_IDLE)
Packit d36e9b
    if (fn->ecp_fwd_to_rev(port))
Packit d36e9b
      return 0;
Packit d36e9b
    
Packit d36e9b
  port->current_phase = PH1284_REV_DATA;
Packit d36e9b
Packit d36e9b
  /* Event 46: Set HostAck (nAutoFd) low to start accepting data. */
Packit d36e9b
  fn->frob_control (port, C1284_NAUTOFD | C1284_NSTROBE | C1284_NINIT, 
Packit d36e9b
		  C1284_NSTROBE);
Packit d36e9b
Packit d36e9b
  while (count < len) {
Packit d36e9b
    unsigned char byte;
Packit d36e9b
    int command; 
Packit d36e9b
Packit d36e9b
    /* Event 43: Peripheral sets nAck low. It can take as long as it wants.. */
Packit d36e9b
    /* FIXME: Should we impose some sensible limit here? */
Packit d36e9b
    lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
    while(fn->wait_status (port, S1284_NACK, 0, &tv)) { } 
Packit d36e9b
Packit d36e9b
    /* Is this a command? */
Packit d36e9b
    if (rle)
Packit d36e9b
      /* The last byte was a run-length count, so this can't be as well. */
Packit d36e9b
      command = 0;
Packit d36e9b
    else
Packit d36e9b
      /* note: test reversed from kernel because BUSY pin is inverted */
Packit d36e9b
      command = (fn->read_status (port) & S1284_BUSY) ? 0 : 1;
Packit d36e9b
Packit d36e9b
Packit d36e9b
    /* Read the data. */
Packit d36e9b
    byte = fn->read_data (port);
Packit d36e9b
Packit d36e9b
    /* If this is a channel command, rather than an RLE
Packit d36e9b
     * command or a normal data byte, don't accept it. */
Packit d36e9b
    if (command) {
Packit d36e9b
      if (byte & 0x80) {
Packit d36e9b
	debugprintf ("Stopping short at channel command (%02x)\n", byte);
Packit d36e9b
	port->current_phase = PH1284_REV_IDLE;
Packit d36e9b
	return count;
Packit d36e9b
      }
Packit d36e9b
      else if (!(flags & F1284_RLE))
Packit d36e9b
	debugprintf ("Device illegally using RLE; accepting anyway\n");
Packit d36e9b
Packit d36e9b
      rle_count = byte + 1;
Packit d36e9b
Packit d36e9b
      /* Are we allowed to read that many bytes? */
Packit d36e9b
      if (rle_count > (len - count)) {
Packit d36e9b
	debugprintf ("Leaving %d RLE bytes for next time\n", 
Packit d36e9b
	    rle_count);
Packit d36e9b
	break;
Packit d36e9b
      }
Packit d36e9b
Packit d36e9b
      rle = 1;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
    /* Event 44: Set HostAck high, acknowledging handshake. */
Packit d36e9b
    fn->frob_control (port, C1284_NAUTOFD, C1284_NAUTOFD);
Packit d36e9b
Packit d36e9b
    /* Event 45: The peripheral has 35ms to set nAck high. */
Packit d36e9b
    lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
    if (fn->wait_status (port, S1284_NACK, S1284_NACK, &tv)) {
Packit d36e9b
      /* It's gone wrong.  Return what data we have to the caller. */
Packit d36e9b
      debugprintf ("ECP read timed out at 45\n");
Packit d36e9b
Packit d36e9b
      if (command)
Packit d36e9b
	debugprintf ("Command ignored (%02x)\n", byte);
Packit d36e9b
Packit d36e9b
      break;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
    /* Event 46: Set HostAck low and accept the data. */
Packit d36e9b
    fn->frob_control (port, C1284_NAUTOFD, 0);
Packit d36e9b
Packit d36e9b
    /* If we just read a run-length count, fetch the data. */
Packit d36e9b
    if (command)
Packit d36e9b
      continue;
Packit d36e9b
    /* If this is the byte after a run-length count, decompress. */
Packit d36e9b
    if (rle) {
Packit d36e9b
      rle = 0;
Packit d36e9b
      memset (buf, byte, rle_count);
Packit d36e9b
      buf += rle_count;
Packit d36e9b
      count += rle_count;
Packit d36e9b
      debugprintf ("Decompressed to %d bytes\n", rle_count);
Packit d36e9b
    } else {
Packit d36e9b
      /* Normal data byte. */
Packit d36e9b
      *buf = byte;
Packit d36e9b
      buf++, count++;
Packit d36e9b
    }
Packit d36e9b
  }
Packit d36e9b
Packit d36e9b
  port->current_phase = PH1284_REV_IDLE;
Packit d36e9b
Packit d36e9b
  debugprintf ("<== default_ecp_read_data\n");
Packit d36e9b
Packit d36e9b
  return count;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
Packit d36e9b
ssize_t
Packit d36e9b
default_ecp_write_data (struct parport_internal *port, int flags,
Packit d36e9b
			const char *buffer, size_t len)
Packit d36e9b
{
Packit d36e9b
Packit d36e9b
  const struct parport_access_methods *fn = port->fn;
Packit d36e9b
  const unsigned char *buf = buffer;
Packit d36e9b
  size_t written;
Packit d36e9b
  int retry;
Packit d36e9b
  struct timeval tv;
Packit d36e9b
Packit d36e9b
  debugprintf ("==> default_ecp_write_data\n");
Packit d36e9b
Packit d36e9b
  if (port->current_phase != PH1284_FWD_IDLE)
Packit d36e9b
    if (fn->ecp_rev_to_fwd(port))
Packit d36e9b
      return 0;
Packit d36e9b
Packit d36e9b
  port->current_phase = PH1284_FWD_DATA;
Packit d36e9b
Packit d36e9b
  /* HostAck high (data, not command) */
Packit d36e9b
  fn->frob_control (port, C1284_NAUTOFD | C1284_NINIT, 
Packit d36e9b
	           C1284_NAUTOFD | C1284_NINIT);
Packit d36e9b
Packit d36e9b
  for (written = 0; written < len; written++, buf++) {
Packit d36e9b
    unsigned char byte;
Packit d36e9b
Packit d36e9b
    byte = *buf;
Packit d36e9b
try_again:
Packit d36e9b
    fn->write_data (port, byte);
Packit d36e9b
    /* Event 35: Set NSTROBE low */
Packit d36e9b
    fn->frob_control (port, C1284_NSTROBE, 0);
Packit d36e9b
    udelay (5);
Packit d36e9b
    lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
    for (retry = 0; retry < 100; retry++) {
Packit d36e9b
      /* Event 36: peripheral sets BUSY high */
Packit d36e9b
      if (!fn->wait_status (port, S1284_BUSY, S1284_BUSY, &tv))
Packit d36e9b
	goto success;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
    /* Time for Host Transfer Recovery (page 41 of IEEE1284) */
Packit d36e9b
    debugprintf ("ECP transfer stalled!\n");
Packit d36e9b
Packit d36e9b
    fn->frob_control (port, C1284_NINIT, C1284_NINIT);
Packit d36e9b
    udelay (50);
Packit d36e9b
    if (fn->read_status (port) & S1284_PERROR) {
Packit d36e9b
      /* It's buggered. */
Packit d36e9b
      fn->frob_control (port, C1284_NINIT, 0);
Packit d36e9b
      break;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
    fn->frob_control (port, C1284_NINIT, 0);
Packit d36e9b
    udelay (50);
Packit d36e9b
    if (!(fn->read_status (port) & S1284_PERROR))
Packit d36e9b
      break;
Packit d36e9b
Packit d36e9b
    debugprintf ("Host transfer recovered\n");
Packit d36e9b
Packit d36e9b
    /* FIXME: Check for timeout here ? */
Packit d36e9b
    goto try_again;
Packit d36e9b
success:
Packit d36e9b
    /* Event 37: HostClk (nStrobe) high */
Packit d36e9b
    fn->frob_control (port, C1284_NSTROBE, C1284_NSTROBE);
Packit d36e9b
    udelay (5);
Packit d36e9b
    lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
    if (fn->wait_status (port, S1284_BUSY, 0, &tv))
Packit d36e9b
      /* Peripheral hasn't accepted the data. */
Packit d36e9b
      break;
Packit d36e9b
  }
Packit d36e9b
Packit d36e9b
  debugprintf ("<== default_ecp_write_data\n");
Packit d36e9b
Packit d36e9b
  port->current_phase = PH1284_FWD_IDLE;
Packit d36e9b
Packit d36e9b
  return written;
Packit d36e9b
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
ssize_t
Packit d36e9b
default_ecp_read_addr (struct parport_internal *port, int flags,
Packit d36e9b
		       char *buffer, size_t len)
Packit d36e9b
{
Packit d36e9b
  return E1284_NOTIMPL;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
ssize_t
Packit d36e9b
default_ecp_write_addr (struct parport_internal *port, int flags,
Packit d36e9b
			const char *buffer, size_t len)
Packit d36e9b
{
Packit d36e9b
  const struct parport_access_methods *fn = port->fn;
Packit d36e9b
  const unsigned char *buf = buffer;
Packit d36e9b
  size_t written;
Packit d36e9b
  int retry;
Packit d36e9b
  struct timeval tv;
Packit d36e9b
Packit d36e9b
  debugprintf ("==> default_ecp_write_addr\n");
Packit d36e9b
Packit d36e9b
  if (port->current_phase != PH1284_FWD_IDLE)
Packit d36e9b
    if (fn->ecp_rev_to_fwd(port))
Packit d36e9b
      return 0;
Packit d36e9b
  port->current_phase = PH1284_FWD_DATA;
Packit d36e9b
Packit d36e9b
  /* HostAck (nAutoFd) low (command mode) */
Packit d36e9b
  fn->frob_control (port, C1284_NAUTOFD | C1284_NINIT, 
Packit d36e9b
		    C1284_NINIT);
Packit d36e9b
Packit d36e9b
  for (written = 0; written < len; written++, buf++)
Packit d36e9b
    {
Packit d36e9b
      unsigned char byte;
Packit d36e9b
      byte = *buf;
Packit d36e9b
Packit d36e9b
      /* FIXME: should we do RLE here? */
Packit d36e9b
    try_again:
Packit d36e9b
      fn->write_data (port, byte);
Packit d36e9b
      /* Event 35: Set NSTROBE low */
Packit d36e9b
      fn->frob_control (port, C1284_NSTROBE, 0);
Packit d36e9b
      udelay (5);
Packit d36e9b
      lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
      for (retry = 0; retry < 100; retry++)
Packit d36e9b
	{
Packit d36e9b
	  /* Event 36: peripheral sets BUSY high */
Packit d36e9b
	  if (!fn->wait_status (port, S1284_BUSY, S1284_BUSY, &tv))
Packit d36e9b
	    goto success;
Packit d36e9b
	}
Packit d36e9b
Packit d36e9b
      /* Time for Host Transfer Recovery (page 41 of IEEE1284) */
Packit d36e9b
      debugprintf ("ECP address transfer stalled!\n");
Packit d36e9b
Packit d36e9b
      fn->frob_control (port, C1284_NINIT, C1284_NINIT);
Packit d36e9b
      udelay (50);
Packit d36e9b
      if (fn->read_status (port) & S1284_PERROR)
Packit d36e9b
	{      
Packit d36e9b
	  /* It's buggered. */
Packit d36e9b
	  fn->frob_control (port, C1284_NINIT, 0);
Packit d36e9b
	  break;
Packit d36e9b
	}
Packit d36e9b
Packit d36e9b
      fn->frob_control (port, C1284_NINIT, 0);
Packit d36e9b
      udelay (50);
Packit d36e9b
      if (!(fn->read_status (port) & S1284_PERROR))
Packit d36e9b
	break;
Packit d36e9b
Packit d36e9b
      debugprintf ("Host address transfer recovered\n");
Packit d36e9b
Packit d36e9b
      /* FIXME: Check for timeout here ? */
Packit d36e9b
      goto try_again;
Packit d36e9b
    success:
Packit d36e9b
      /* Event 37: HostClk (nStrobe) high */
Packit d36e9b
      fn->frob_control (port, C1284_NSTROBE, C1284_NSTROBE);
Packit d36e9b
      udelay (5);
Packit d36e9b
      lookup_delay (TIMEVAL_SIGNAL_TIMEOUT, &tv;;
Packit d36e9b
      if (fn->wait_status (port, S1284_BUSY, 0, &tv))
Packit d36e9b
	/* Peripheral hasn't accepted the data. */
Packit d36e9b
	break;
Packit d36e9b
    }
Packit d36e9b
Packit d36e9b
  debugprintf ("<== default_ecp_write_addr\n");
Packit d36e9b
  port->current_phase = PH1284_FWD_IDLE;
Packit d36e9b
  return written;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
struct timeval *
Packit d36e9b
default_set_timeout (struct parport_internal *port, struct timeval *timeout)
Packit d36e9b
{
Packit d36e9b
  static struct timeval to;
Packit d36e9b
  to.tv_sec = 9999;
Packit d36e9b
  to.tv_usec = 0;
Packit d36e9b
  return &to;
Packit d36e9b
}
Packit d36e9b
Packit d36e9b
/*
Packit d36e9b
 * Local Variables:
Packit d36e9b
 * eval: (c-set-style "gnu")
Packit d36e9b
 * End:
Packit d36e9b
 */