/*
	Copyright (C) 1996  Digi International.

	For technical support please email digiLinux@dgii.com or
	call Digi tech support at (612) 912-3456

	** This driver is no longer supported by Digi **

	Much of this design and code came from epca.c which was
	copyright (C) 1994, 1995 Troy De Jongh, and subsquently
	modified by David Nugent, Christoph Lameter, Mike McLagan.

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* See README.epca for change history --DAT*/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/serial.h>
#include <linux/delay.h>
#include <linux/ctype.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/smp_lock.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
#include "digiPCI.h"


#include "digi1.h"
#include "digiFep1.h"
#include "epca.h"
#include "epcaconfig.h"

#define VERSION            "1.3.0.1-LK2.6"

/* This major needs to be submitted to Linux to join the majors list */
#define DIGIINFOMAJOR       35  /* For Digi specific ioctl */


#define MAXCARDS 7
#define epcaassert(x, msg)  if (!(x)) epca_error(__LINE__, msg)

#define PFX "epca: "

static int nbdevs, num_cards, liloconfig;
static int digi_poller_inhibited = 1 ;

static int setup_error_code;
static int invalid_lilo_config;

/*
 * The ISA boards do window flipping into the same spaces so its only sane with
 * a single lock. It's still pretty efficient. This lock guards the hardware
 * and the tty_port lock guards the kernel side stuff like use counts. Take
 * this lock inside the port lock if you must take both.
 */
static DEFINE_SPINLOCK(epca_lock);

/* MAXBOARDS is typically 12, but ISA and EISA cards are restricted
   to 7 below. */
static struct board_info boards[MAXBOARDS];

static struct tty_driver *pc_driver;
static struct tty_driver *pc_info;

/* ------------------ Begin Digi specific structures -------------------- */

/*
 * digi_channels represents an array of structures that keep track of each
 * channel of the Digi product. Information such as transmit and receive
 * pointers, termio data, and signal definitions (DTR, CTS, etc ...) are stored
 * here. This structure is NOT used to overlay the cards physical channel
 * structure.
 */
static struct channel digi_channels[MAX_ALLOC];

/*
 * card_ptr is an array used to hold the address of the first channel structure
 * of each card. This array will hold the addresses of various channels located
 * in digi_channels.
 */
static struct channel *card_ptr[MAXCARDS];

static struct timer_list epca_timer;

/*
 * Begin generic memory functions. These functions will be alias (point at)
 * more specific functions dependent on the board being configured.
 */
static void memwinon(struct board_info *b, unsigned int win);
static void memwinoff(struct board_info *b, unsigned int win);
static void globalwinon(struct channel *ch);
static void rxwinon(struct channel *ch);
static void txwinon(struct channel *ch);
static void memoff(struct channel *ch);
static void assertgwinon(struct channel *ch);
static void assertmemoff(struct channel *ch);

/* ---- Begin more 'specific' memory functions for cx_like products --- */

static void pcxem_memwinon(struct board_info *b, unsigned int win);
static void pcxem_memwinoff(struct board_info *b, unsigned int win);
static void pcxem_globalwinon(struct channel *ch);
static void pcxem_rxwinon(struct channel *ch);
static void pcxem_txwinon(struct channel *ch);
static void pcxem_memoff(struct channel *ch);

/* ------ Begin more 'specific' memory functions for the pcxe ------- */

static void pcxe_memwinon(struct board_info *b, unsigned int win);
static void pcxe_memwinoff(struct board_info *b, unsigned int win);
static void pcxe_globalwinon(struct channel *ch);
static void pcxe_rxwinon(struct channel *ch);
static void pcxe_txwinon(struct channel *ch);
static void pcxe_memoff(struct channel *ch);

/* ---- Begin more 'specific' memory functions for the pc64xe and pcxi ---- */
/* Note : pc64xe and pcxi share the same windowing routines */

static void pcxi_memwinon(struct board_info *b, unsigned int win);
static void pcxi_memwinoff(struct board_info *b, unsigned int win);
static void pcxi_globalwinon(struct channel *ch);
static void pcxi_rxwinon(struct channel *ch);
static void pcxi_txwinon(struct channel *ch);
static void pcxi_memoff(struct channel *ch);

/* - Begin 'specific' do nothing memory functions needed for some cards - */

static void dummy_memwinon(struct board_info *b, unsigned int win);
static void dummy_memwinoff(struct board_info *b, unsigned int win);
static void dummy_globalwinon(struct channel *ch);
static void dummy_rxwinon(struct channel *ch);
static void dummy_txwinon(struct channel *ch);
static void dummy_memoff(struct channel *ch);
static void dummy_assertgwinon(struct channel *ch);
static void dummy_assertmemoff(struct channel *ch);

static struct channel *verifyChannel(struct tty_struct *);
static void pc_sched_event(struct channel *, int);
static void epca_error(int, char *);
static void pc_close(struct tty_struct *, struct file *);
static void shutdown(struct channel *, struct tty_struct *tty);
static void pc_hangup(struct tty_struct *);
static int pc_write_room(struct tty_struct *);
static int pc_chars_in_buffer(struct tty_struct *);
static void pc_flush_buffer(struct tty_struct *);
static void pc_flush_chars(struct tty_struct *);
static int pc_open(struct tty_struct *, struct file *);
static void post_fep_init(unsigned int crd);
static void epcapoll(unsigned long);
static void doevent(int);
static void fepcmd(struct channel *, int, int, int, int, int);
static unsigned termios2digi_h(struct channel *ch, unsigned);
static unsigned termios2digi_i(struct channel *ch, unsigned);
static unsigned termios2digi_c(struct channel *ch, unsigned);
static void epcaparam(struct tty_struct *, struct channel *);
static void receive_data(struct channel *, struct tty_struct *tty);
static int pc_ioctl(struct tty_struct *, struct file *,
			unsigned int, unsigned long);
static int info_ioctl(struct tty_struct *, struct file *,
			unsigned int, unsigned long);
static void pc_set_termios(struct tty_struct *, struct ktermios *);
static void do_softint(struct work_struct *work);
static void pc_stop(struct tty_struct *);
static void pc_start(struct tty_struct *);
static void pc_throttle(struct tty_struct *tty);
static void pc_unthrottle(struct tty_struct *tty);
static int pc_send_break(struct tty_struct *tty, int msec);
static void setup_empty_event(struct tty_struct *tty, struct channel *ch);

static int pc_write(struct tty_struct *, const unsigned char *, int);
static int pc_init(void);
static int init_PCI(void);

/*
 * Table of functions for each board to handle memory. Mantaining parallelism
 * is a *very* good idea here. The idea is for the runtime code to blindly call
 * these functions, not knowing/caring about the underlying hardware. This
 * stuff should contain no conditionals; if more functionality is needed a
 * different entry should be established. These calls are the interface calls
 * and are the only functions that should be accessed. Anyone caught making
 * direct calls deserves what they get.
 */
static void memwinon(struct board_info *b, unsigned int win)
{
	b->memwinon(b, win);
}

static void memwinoff(struct board_info *b, unsigned int win)
{
	b->memwinoff(b, win);
}

static void globalwinon(struct channel *ch)
{
	ch->board->globalwinon(ch);
}

static void rxwinon(struct channel *ch)
{
	ch->board->rxwinon(ch);
}

static void txwinon(struct channel *ch)
{
	ch->board->txwinon(ch);
}

static void memoff(struct channel *ch)
{
	ch->board->memoff(ch);
}
static void assertgwinon(struct channel *ch)
{
	ch->board->assertgwinon(ch);
}

static void assertmemoff(struct channel *ch)
{
	ch->board->assertmemoff(ch);
}

/* PCXEM windowing is the same as that used in the PCXR and CX series cards. */
static void pcxem_memwinon(struct board_info *b, unsigned int win)
{
	outb_p(FEPWIN | win, b->port + 1);
}

static void pcxem_memwinoff(struct board_info *b, unsigned int win)
{
	outb_p(0, b->port + 1);
}

static void pcxem_globalwinon(struct channel *ch)
{
	outb_p(FEPWIN, (int)ch->board->port + 1);
}

static void pcxem_rxwinon(struct channel *ch)
{
	outb_p(ch->rxwin, (int)ch->board->port + 1);
}

static void pcxem_txwinon(struct channel *ch)
{
	outb_p(ch->txwin, (int)ch->board->port + 1);
}

static void pcxem_memoff(struct channel *ch)
{
	outb_p(0, (int)ch->board->port + 1);
}

/* ----------------- Begin pcxe memory window stuff ------------------ */
static void pcxe_memwinon(struct board_info *b, unsigned int win)
{
	outb_p(FEPWIN | win, b->port + 1);
}

static void pcxe_memwinoff(struct board_info *b, unsigned int win)
{
	outb_p(inb(b->port) & ~FEPMEM, b->port + 1);
	outb_p(0, b->port + 1);
}

static void pcxe_globalwinon(struct channel *ch)
{
	outb_p(FEPWIN, (int)ch->board->port + 1);
}

static void pcxe_rxwinon(struct channel *ch)
{
	outb_p(ch->rxwin, (int)ch->board->port + 1);
}

static void pcxe_txwinon(struct channel *ch)
{
	outb_p(ch->txwin, (int)ch->board->port + 1);
}

static void pcxe_memoff(struct channel *ch)
{
	outb_p(0, (int)ch->board->port);
	outb_p(0, (int)ch->board->port + 1);
}

/* ------------- Begin pc64xe and pcxi memory window stuff -------------- */
static void pcxi_memwinon(struct board_info *b, unsigned int win)
{
	outb_p(inb(b->port) | FEPMEM, b->port);
}

static void pcxi_memwinoff(struct board_info *b, unsigned int win)
{
	outb_p(inb(b->port) & ~FEPMEM, b->port);
}

static void pcxi_globalwinon(struct channel *ch)
{
	outb_p(FEPMEM, ch->board->port);
}

static void pcxi_rxwinon(struct channel *ch)
{
	outb_p(FEPMEM, ch->board->port);
}

static void pcxi_txwinon(struct channel *ch)
{
	outb_p(FEPMEM, ch->board->port);
}

static void pcxi_memoff(struct channel *ch)
{
	outb_p(0, ch->board->port);
}

static void pcxi_assertgwinon(struct channel *ch)
{
	epcaassert(inb(ch->board->port) & FEPMEM, "Global memory off");
}

static void pcxi_assertmemoff(struct channel *ch)
{
	epcaassert(!(inb(ch->board->port) & FEPMEM), "Memory on");
}

/*
 * Not all of the cards need specific memory windowing routines. Some cards
 * (Such as PCI) needs no windowing routines at all. We provide these do
 * nothing routines so that the same code base can be used. The driver will
 * ALWAYS call a windowing routine if it thinks it needs to; regardless of the
 * card. However, dependent on the card the routine may or may not do anything.
 */
static void dummy_memwinon(struct board_info *b, unsigned int win)
{
}

static void dummy_memwinoff(struct board_info *b, unsigned int win)
{
}

static void dummy_globalwinon(struct channel *ch)
{
}

static void dummy_rxwinon(struct channel *ch)
{
}

static void dummy_txwinon(struct channel *ch)
{
}

static void dummy_memoff(struct channel *ch)
{
}

static void dummy_assertgwinon(struct channel *ch)
{
}

static void dummy_assertmemoff(struct channel *ch)
{
}

static struct channel *verifyChannel(struct tty_struct *tty)
{
	/*
	 * This routine basically provides a sanity check. It insures that the
	 * channel returned is within the proper range of addresses as well as
	 * properly initialized. If some bogus info gets passed in
	 * through tty->driver_data this should catch it.
	 */
	if (tty) {
		struct channel *ch = tty->driver_data;
		if (ch >= &digi_channels[0] && ch < &digi_channels[nbdevs]) {
			if (ch->magic == EPCA_MAGIC)
				return ch;
		}
	}
	return NULL;
}

static void pc_sched_event(struct channel *ch, int event)
{
	/*
	 * We call this to schedule interrupt processing on some event. The
	 * kernel sees our request and calls the related routine in OUR driver.
	 */
	ch->event |= 1 << event;
	schedule_work(&ch->tqueue);
}

static void epca_error(int line, char *msg)
{
	printk(KERN_ERR "epca_error (Digi): line = %d %s\n", line, msg);
}

static void pc_close(struct tty_struct *tty, struct file *filp)
{
	struct channel *ch;
	struct tty_port *port;
	/*
	 * verifyChannel returns the channel from the tty struct if it is
	 * valid. This serves as a sanity check.
	 */
	ch = verifyChannel(tty);
	if (ch == NULL)
		return;
	port = &ch->port;

	if (tty_port_close_start(port, tty, filp) == 0)
		return;

	pc_flush_buffer(tty);
	shutdown(ch, tty);

	tty_port_close_end(port, tty);
	ch->event = 0;	/* FIXME: review ch->event locking */
	tty_port_tty_set(port, NULL);
}

static void shutdown(struct channel *ch, struct tty_struct *tty)
{
	unsigned long flags;
	struct board_chan __iomem *bc;
	struct tty_port *port = &ch->port;

	if (!(port->flags & ASYNC_INITIALIZED))
		return;

	spin_lock_irqsave(&epca_lock, flags);

	globalwinon(ch);
	bc = ch->brdchan;

	/*
	 * In order for an event to be generated on the receipt of data the
	 * idata flag must be set. Since we are shutting down, this is not
	 * necessary clear this flag.
	 */
	if (bc)
		writeb(0, &bc->idata);

	/* If we're a modem control device and HUPCL is on, drop RTS & DTR. */
	if (tty->termios->c_cflag & HUPCL)  {
		ch->omodem &= ~(ch->m_rts | ch->m_dtr);
		fepcmd(ch, SETMODEM, 0, ch->m_dtr | ch->m_rts, 10, 1);
	}
	memoff(ch);

	/*
	 * The channel has officialy been closed. The next time it is opened it
	 * will have to reinitialized. Set a flag to indicate this.
	 */
	/* Prevent future Digi programmed interrupts from coming active */
	port->flags &= ~ASYNC_INITIALIZED;
	spin_unlock_irqrestore(&epca_lock, flags);
}

static void pc_hangup(struct tty_struct *tty)
{
	struct channel *ch;

	/*
	 * verifyChannel returns the channel from the tty struct if it is
	 * valid. This serves as a sanity check.
	 */
	ch = verifyChannel(tty);
	if (ch != NULL) {
		pc_flush_buffer(tty);
		tty_ldisc_flush(tty);
		shutdown(ch, tty);

		ch->event = 0;	/* FIXME: review locking of ch->event */
		tty_port_hangup(&ch->port);
	}
}

static int pc_write(struct tty_struct *tty,
			const unsigned char *buf, int bytesAvailable)
{
	unsigned int head, tail;
	int dataLen;
	int size;
	int amountCopied;
	struct channel *ch;
	unsigned long flags;
	int remain;
	struct board_chan __iomem *bc;

	/*
	 * pc_write is primarily called directly by the kernel routine
	 * tty_write (Though it can also be called by put_char) found in
	 * tty_io.c. pc_write is passed a line discipline buffer where the data
	 * to be written out is stored. The line discipline implementation
	 * itself is done at the kernel level and is not brought into the
	 * driver.
	 */

	/*
	 * verifyChannel returns the channel from the tty struct if it is
	 * valid. This serves as a sanity check.
	 */
	ch = verifyChannel(tty);
	if (ch == NULL)
		return 0;

	/* Make a pointer to the channel data structure found on the board. */
	bc   = ch->brdchan;
	size = ch->txbufsize;
	amountCopied = 0;

	spin_lock_irqsave(&epca_lock, flags);
	globalwinon(ch);

	head = readw(&bc->tin) & (size - 1);
	tail = readw(&bc->tout);

	if (tail != readw(&bc->tout))
		tail = readw(&bc->tout);
	tail &= (size - 1);

	if (head >= tail) {
		/* head has not wrapped */
		/*
		 * remain (much like dataLen above) represents the total amount
		 * of space available on the card for data. Here dataLen
		 * represents the space existing between the head pointer and
		 * the end of buffer. This is important because a memcpy cannot
		 * be told to automatically wrap around when it hits the buffer
		 * end.
		 */
		dataLen = size - head;
		remain = size - (head - tail) - 1;
	} else {
		/* head has wrapped around */
		remain = tail - head - 1;
		dataLen = remain;
	}
	/*
	 * Check the space on the card. If we have more data than space; reduce
	 * the amount of data to fit the space.
	 */
	bytesAvailable = min(remain, bytesAvailable);
	txwinon(ch);
	while (bytesAvailable > 0) {
		/* there is data to copy onto card */

		/*
		 * If head is not wrapped, the below will make sure the first
		 * data copy fills to the end of card buffer.
		 */
		dataLen = min(bytesAvailable, dataLen);
		memcpy_toio(ch->txptr + head, buf, dataLen);
		buf += dataLen;
		head += dataLen;
		amountCopied += dataLen;
		bytesAvailable -= dataLen;

		if (head >= size) {
			head = 0;
			dataLen = tail;
		}
	}
	ch->statusflags |= TXBUSY;
	globalwinon(ch);
	writew(head, &bc->tin);

	if ((ch->statusflags & LOWWAIT) == 0)  {
		ch->statusflags |= LOWWAIT;
		writeb(1, &bc->ilow);
	}
	memoff(ch);
	spin_unlock_irqrestore(&epca_lock, flags);
	return amountCopied;
}

static int pc_write_room(struct tty_struct *tty)
{
	int remain = 0;
	struct channel *ch;
	unsigned long flags;
	unsigned int head, tail;
	struct board_chan __iomem *bc;
	/*
	 * verifyChannel returns the channel from the tty struct if it is
	 * valid. This serves as a sanity check.
	 */
	ch = verifyChannel(tty);
	if (ch != NULL) {
		spin_lock_irqsave(&epca_lock, flags);
		globalwinon(ch);

		bc   = ch->brdchan;
		head = readw(&bc->tin) & (ch->txbufsize - 1);
		tail = readw(&bc->tout);

		if (tail != readw(&bc->tout))
			tail = readw(&bc->tout);
		/* Wrap tail if necessary */
		tail &= (ch->txbufsize - 1);
		remain = tail - head - 1;
		if (remain < 0)
			remain += ch->txbufsize;

		if (remain && (ch->statusflags & LOWWAIT) == 0) {
			ch->statusflags |= LOWWAIT;
			writeb(1, &bc->ilow);
		}
		memoff(ch);
		spin_unlock_irqrestore(&epca_lock, flags);
	}
	/* Return how much room is left on card */
	return remain;
}

static int pc_chars_in_buffer(struct tty_struct *tty)
{
	int chars;
	unsigned int ctail, head, tail;
	int remain;
	unsigned long flags;
	struct channel *ch;
	struct board_chan __iomem *bc;
	/*
	 * verifyChannel returns the channel from the tty struct if it is
	 * valid. This serves as a sanity check.
	 */
	ch = verifyChannel(tty);
	if (ch == NULL)
		return 0;

	spin_lock_irqsave(&epca_lock, flags);
	globalwinon(ch);

	bc = ch->brdchan;
	tail = readw(&bc->tout);
	head = readw(&bc->tin);
	ctail = readw(&ch->mailbox->cout);

	if (tail == head && readw(&ch->mailbox->cin) == ctail &&
						readb(&bc->tbusy) == 0)
		chars = 0;
	else  { /* Begin if some space on the card has been used */
		head = readw(&bc->tin) & (ch->txbufsize - 1);
		tail &= (ch->txbufsize - 1);
		/*
		 * The logic here is basically opposite of the above
		 * pc_write_room here we are finding the amount of bytes in the
		 * buffer filled. Not the amount of bytes empty.
		 */
		remain = tail - head - 1;
		if (remain < 0)
			remain += ch->txbufsize;
		chars = (int)(ch->txbufsize - remain);
		/*
		 * Make it possible to wakeup anything waiting for output in
		 * tty_ioctl.c, etc.
		 *
		 * If not already set. Setup an event to indicate when the
		 * transmit buffer empties.
		 */
		if (!(ch->statusflags & EMPTYWAIT))
			setup_empty_event(tty, ch);
	} /* End if some space on the card has been used */
	memoff(ch);
	spin_unlock_irqrestore(&epca_lock, flags);
	/* Return number of characters residing on card. */
	return chars;
}

static void pc_flush_buffer(struct tty_struct *tty)
{
	unsigned int tail;
	unsigned long flags;
	struct channel *ch;
	struct board_chan __iomem *bc;
	/*
	 * verifyChannel returns the channel from the tty struct if it is
	 * valid. This serves as a sanity check.
	 */
	ch = verifyChannel(tty);
	if (ch == NULL)
		return;

	spin_lock_irqsave(&epca_lock, flags);
	globalwinon(ch);
	bc   = ch->brdchan;
	tail = readw(&bc->tout);
	/* Have FEP move tout pointer; effectively flushing transmit buffer */
	fepcmd(ch, STOUT, (unsigned) tail, 0, 0, 0);
	memoff(ch);
	spin_unlock_irqrestore(&epca_lock, flags);
	tty_wakeup(tty);
}

static void pc_flush_chars(struct tty_struct *tty)
{
	struct channel *ch;
	/*
	 * verifyChannel returns the channel from the tty struct if it is
	 * valid. This serves as a sanity check.
	 */
	ch = verifyChannel(tty);
	if (ch != NULL) {
		unsigned long flags;
		spin_lock_irqsave(&epca_lock, flags);
		/*
		 * If not already set and the transmitter is busy setup an
		 * event to indicate when the transmit empties.
		 */
		if ((ch->statusflags & TXBUSY) &&
				!(ch->statusflags & EMPTYWAIT))
			setup_empty_event(tty, ch);
		spin_unlock_irqrestore(&epca_lock, flags);
	}
}

static int epca_carrier_raised(struct tty_port *port)
{
	struct channel *ch = container_of(port, struct channel, port);
	if (ch->imodem & ch->dcd)
		return 1;
	return 0;
}

static void epca_dtr_rts(struct tty_port *port, int onoff)
{
}

static int pc_open(struct tty_struct *tty, struct file *filp)
{
	struct channel *ch;
	struct tty_port *port;
	unsigned long flags;
	int line, retval, boardnum;
	struct board_chan __iomem *bc;
	unsigned int head;

	line = tty->index;
	if (line < 0 || line >= nbdevs)
		return -ENODEV;

	ch = &digi_channels[line];
	port = &ch->port;
	boardnum = ch->boardnum;

	/* Check status of board configured in system.  */

	/*
	 * I check to see if the epca_setup routine detected a user error. It
	 * might be better to put this in pc_init, but for the moment it goes
	 * here.
	 */
	if (invalid_lilo_config) {
		if (setup_error_code & INVALID_BOARD_TYPE)
			printk(KERN_ERR "epca: pc_open: Invalid board type specified in kernel options.\n");
		if (setup_error_code & INVALID_NUM_PORTS)
			printk(KERN_ERR "epca: pc_open: Invalid number of ports specified in kernel options.\n");
		if (setup_error_code & INVALID_MEM_BASE)
			printk(KERN_ERR "epca: pc_open: Invalid board memory address specified in kernel options.\n");
		if (setup_error_code & INVALID_PORT_BASE)
			printk(KERN_ERR "epca; pc_open: Invalid board port address specified in kernel options.\n");
		if (setup_error_code & INVALID_BOARD_STATUS)
			printk(KERN_ERR "epca: pc_open: Invalid board status specified in kernel options.\n");
		if (setup_error_code & INVALID_ALTPIN)
			printk(KERN_ERR "epca: pc_open: Invalid board altpin specified in kernel options;\n");
		tty->driver_data = NULL;   /* Mark this device as 'down' */
		return -ENODEV;
	}
	if (boardnum >= num_cards || boards[boardnum].status == DISABLED)  {
		tty->driver_data = NULL;   /* Mark this device as 'down' */
		return(-ENODEV);
	}

	bc = ch->brdchan;
	if (bc == NULL) {
		tty->driver_data = NULL;
		return -ENODEV;
	}

	spin_lock_irqsave(&port->lock, flags);
	/*
	 * Every time a channel is opened, increment a counter. This is
	 * necessary because we do not wish to flush and shutdown the channel
	 * until the last app holding the channel open, closes it.
	 */
	port->count++;
	/*
	 * Set a kernel structures pointer to our local channel structure. This
	 * way we can get to it when passed only a tty struct.
	 */
	tty->driver_data = ch;
	port->tty = tty;
	/*
	 * If this is the first time the channel has been opened, initialize
	 * the tty->termios struct otherwise let pc_close handle it.
	 */
	spin_lock(&epca_lock);
	globalwinon(ch);
	ch->statusflags = 0;

	/* Save boards current modem status */
	ch->imodem = readb(&bc->mstat);

	/*
	 * Set receive head and tail ptrs to each other. This indicates no data
	 * available to read.
	 */
	head = readw(&bc->rin);
	writew(head, &bc->rout);

	/* Set the channels associated tty structure */

	/*
	 * The below routine generally sets up parity, baud, flow control
	 * issues, etc.... It effect both control flags and input flags.
	 */
	epcaparam(tty, ch);
	memoff(ch);
	spin_unlock(&epca_lock);
	port->flags |= ASYNC_INITIALIZED;
	spin_unlock_irqrestore(&port->lock, flags);

	retval = tty_port_block_til_ready(port, tty, filp);
	if (retval)
		return retval;
	/*
	 * Set this again in case a hangup set it to zero while this open() was
	 * waiting for the line...
	 */
	spin_lock_irqsave(&port->lock, flags);
	port->tty = tty;
	spin_lock(&epca_lock);
	globalwinon(ch);
	/* Enable Digi Data events */
	writeb(1, &bc->idata);
	memoff(ch);
	spin_unlock(&epca_lock);
	spin_unlock_irqrestore(&port->lock, flags);
	return 0;
}

static int __init epca_module_init(void)
{
	return pc_init();
}
module_init(epca_module_init);

static struct pci_driver epca_driver;

static void __exit epca_module_exit(void)
{
	int               count, crd;
	struct board_info *bd;
	struct channel    *ch;

	del_timer_sync(&epca_timer);

	if (tty_unregister_driver(pc_driver) ||
				tty_unregister_driver(pc_info)) {
		printk(KERN_WARNING "epca: cleanup_module failed to un-register tty driver\n");
		return;
	}
	put_tty_driver(pc_driver);
	put_tty_driver(pc_info);

	for (crd = 0; crd < num_cards; crd++) {
		bd = &boards[crd];
		if (!bd) { /* sanity check */
			printk(KERN_ERR "<Error> - Digi : cleanup_module failed\n");
			return;
		}
		ch = card_ptr[crd];
		for (count = 0; count < bd->numports; count++, ch++) {
			struct tty_struct *tty = tty_port_tty_get(&ch->port);
			if (tty) {
				tty_hangup(tty);
				tty_kref_put(tty);
			}
		}
	}
	pci_unregister_driver(&epca_driver);
}
module_exit(epca_module_exit);

static const struct tty_operations pc_ops = {
	.open = pc_open,
	.close = pc_close,
	.write = pc_write,
	.write_room = pc_write_room,
	.flush_buffer = pc_flush_buffer,
	.chars_in_buffer = pc_chars_in_buffer,
	.flush_chars = pc_flush_chars,
	.ioctl = pc_ioctl,
	.set_termios = pc_set_termios,
	.stop = pc_stop,
	.start = pc_start,
	.throttle = pc_throttle,
	.unthrottle = pc_unthrottle,
	.hangup = pc_hangup,
	.break_ctl = pc_send_break
};

static const struct tty_port_operations epca_port_ops = {
	.carrier_raised = epca_carrier_raised,
	.dtr_rts = epca_dtr_rts,
};

static int info_open(struct tty_struct *tty, struct file *filp)
{
	return 0;
}

static const struct tty_operations info_ops = {
	.open = info_open,
	.ioctl = info_ioctl,
};

static int __init pc_init(void)
{
	int crd;
	struct board_info *bd;
	unsigned char board_id = 0;
	int err = -ENOMEM;

	int pci_boards_found, pci_count;

	pci_count = 0;

	pc_driver = alloc_tty_driver(MAX_ALLOC);
	if (!pc_driver)
		goto out1;

	pc_info = alloc_tty_driver(MAX_ALLOC);
	if (!pc_info)
		goto out2;

	/*
	 * If epca_setup has not been ran by LILO set num_cards to defaults;
	 * copy board structure defined by digiConfig into drivers board
	 * structure. Note : If LILO has ran epca_setup then epca_setup will
	 * handle defining num_cards as well as copying the data into the board
	 * structure.
	 */
	if (!liloconfig) {
		/* driver has been configured via. epcaconfig */
		nbdevs = NBDEVS;
		num_cards = NUMCARDS;
		memcpy(&boards, &static_boards,
		       sizeof(struct board_info) * NUMCARDS);
	}

	/*
	 * Note : If lilo was used to configure the driver and the ignore
	 * epcaconfig option was choosen (digiepca=2) then nbdevs and num_cards
	 * will equal 0 at this point. This is okay; PCI cards will still be
	 * picked up if detected.
	 */

	/*
	 * Set up interrupt, we will worry about memory allocation in
	 * post_fep_init.
	 */
	printk(KERN_INFO "DIGI epca driver version %s loaded.\n", VERSION);

	/*
	 * NOTE : This code assumes that the number of ports found in the
	 * boards array is correct. This could be wrong if the card in question
	 * is PCI (And therefore has no ports entry in the boards structure.)
	 * The rest of the information will be valid for PCI because the
	 * beginning of pc_init scans for PCI and determines i/o and base
	 * memory addresses. I am not sure if it is possible to read the number
	 * of ports supported by the card prior to it being booted (Since that
	 * is the state it is in when pc_init is run). Because it is not
	 * possible to query the number of supported ports until after the card
	 * has booted; we are required to calculate the card_ptrs as the card
	 * is initialized (Inside post_fep_init). The negative thing about this
	 * approach is that digiDload's call to GET_INFO will have a bad port
	 * value. (Since this is called prior to post_fep_init.)
	 */
	pci_boards_found = 0;
	if (num_cards < MAXBOARDS)
		pci_boards_found += init_PCI();
	num_cards += pci_boards_found;

	pc_driver->owner = THIS_MODULE;
	pc_driver->name = "ttyD";
	pc_driver->major = DIGI_MAJOR;
	pc_driver->minor_start = 0;
	pc_driver->type = TTY_DRIVER_TYPE_SERIAL;
	pc_driver->subtype = SERIAL_TYPE_NORMAL;
	pc_driver->init_termios = tty_std_termios;
	pc_driver->init_termios.c_iflag = 0;
	pc_driver->init_termios.c_oflag = 0;
	pc_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
	pc_driver->init_termios.c_lflag = 0;
	pc_driver->init_termios.c_ispeed = 9600;
	pc_driver->init_termios.c_ospeed = 9600;
	pc_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_HARDWARE_BREAK;
	tty_set_operations(pc_driver, &pc_ops);

	pc_info->owner = THIS_MODULE;
	pc_info->name = "digi_ctl";
	pc_info->major = DIGIINFOMAJOR;
	pc_info->minor_start = 0;
	pc_info->type = TTY_DRIVER_TYPE_SERIAL;
	pc_info->subtype = SERIAL_TYPE_INFO;
	pc_info->init_termios = tty_std_termios;
	pc_info->init_termios.c_iflag = 0;
	pc_info->init_termios.c_oflag = 0;
	pc_info->init_termios.c_lflag = 0;
	pc_info->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
	pc_info->init_termios.c_ispeed = 9600;
	pc_info->init_termios.c_ospeed = 9600;
	pc_info->flags = TTY_DRIVER_REAL_RAW;
	tty_set_operations(pc_info, &info_ops);


	for (crd = 0; crd < num_cards; crd++) {
		/*
		 * This is where the appropriate memory handlers for the
		 * hardware is set. Everything at runtime blindly jumps through
		 * these vectors.
		 */

		/* defined in epcaconfig.h */
		bd = &boards[crd];

		switch (bd->type) {
		case PCXEM:
		case EISAXEM:
			bd->memwinon     = pcxem_memwinon;
			bd->memwinoff    = pcxem_memwinoff;
			bd->globalwinon  = pcxem_globalwinon;
			bd->txwinon      = pcxem_txwinon;
			bd->rxwinon      = pcxem_rxwinon;
			bd->memoff       = pcxem_memoff;
			bd->assertgwinon = dummy_assertgwinon;
			bd->assertmemoff = dummy_assertmemoff;
			break;

		case PCIXEM:
		case PCIXRJ:
		case PCIXR:
			bd->memwinon     = dummy_memwinon;
			bd->memwinoff    = dummy_memwinoff;
			bd->globalwinon  = dummy_globalwinon;
			bd->txwinon      = dummy_txwinon;
			bd->rxwinon      = dummy_rxwinon;
			bd->memoff       = dummy_memoff;
			bd->assertgwinon = dummy_assertgwinon;
			bd->assertmemoff = dummy_assertmemoff;
			break;

		case PCXE:
		case PCXEVE:
			bd->memwinon     = pcxe_memwinon;
			bd->memwinoff    = pcxe_memwinoff;
			bd->globalwinon  = pcxe_globalwinon;
			bd->txwinon      = pcxe_txwinon;
			bd->rxwinon      = pcxe_rxwinon;
			bd->memoff       = pcxe_memoff;
			bd->assertgwinon = dummy_assertgwinon;
			bd->assertmemoff = dummy_assertmemoff;
			break;

		case PCXI:
		case PC64XE:
			bd->memwinon     = pcxi_memwinon;
			bd->memwinoff    = pcxi_memwinoff;
			bd->globalwinon  = pcxi_globalwinon;
			bd->txwinon      = pcxi_txwinon;
			bd->rxwinon      = pcxi_rxwinon;
			bd->memoff       = pcxi_memoff;
			bd->assertgwinon = pcxi_assertgwinon;
			bd->assertmemoff = pcxi_assertmemoff;
			break;

		default:
			break;
		}

		/*
		 * Some cards need a memory segment to be defined for use in
		 * transmit and receive windowing operations. These boards are
		 * listed in the below switch. In the case of the XI the amount
		 * of memory on the board is variable so the memory_seg is also
		 * variable. This code determines what they segment should be.
		 */
		switch (bd->type) {
		case PCXE:
		case PCXEVE:
		case PC64XE:
			bd->memory_seg = 0xf000;
			break;

		case PCXI:
			board_id = inb((int)bd->port);
			if ((board_id & 0x1) == 0x1) {
				/* it's an XI card */
				/* Is it a 64K board */
				if ((board_id & 0x30) == 0)
					bd->memory_seg = 0xf000;

				/* Is it a 128K board */
				if ((board_id & 0x30) == 0x10)
					bd->memory_seg = 0xe000;

				/* Is is a 256K board */
				if ((board_id & 0x30) == 0x20)
					bd->memory_seg = 0xc000;

				/* Is it a 512K board */
				if ((board_id & 0x30) == 0x30)
					bd->memory_seg = 0x8000;
			} else
				printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n", (int)bd->port);
			break;
		}
	}

	err = tty_register_driver(pc_driver);
	if (err) {
		printk(KERN_ERR "Couldn't register Digi PC/ driver");
		goto out3;
	}

	err = tty_register_driver(pc_info);
	if (err) {
		printk(KERN_ERR "Couldn't register Digi PC/ info ");
		goto out4;
	}

	/* Start up the poller to check for events on all enabled boards */
	init_timer(&epca_timer);
	epca_timer.function = epcapoll;
	mod_timer(&epca_timer, jiffies + HZ/25);
	return 0;

out4:
	tty_unregister_driver(pc_driver);
out3:
	put_tty_driver(pc_info);
out2:
	put_tty_driver(pc_driver);
out1:
	return err;
}

static void post_fep_init(unsigned int crd)
{
	int i;
	void __iomem *memaddr;
	struct global_data __iomem *gd;
	struct board_info *bd;
	struct board_chan __iomem *bc;
	struct channel *ch;
	int shrinkmem = 0, lowwater;

	/*
	 * This call is made by the user via. the ioctl call DIGI_INIT. It is
	 * responsible for setting up all the card specific stuff.
	 */
	bd = &boards[crd];

	/*
	 * If this is a PCI board, get the port info. Remember PCI cards do not
	 * have entries into the epcaconfig.h file, so we can't get the number
	 * of ports from it. Unfortunetly, this means that anyone doing a
	 * DIGI_GETINFO before the board has booted will get an invalid number
	 * of ports returned (It should return 0). Calls to DIGI_GETINFO after
	 * DIGI_INIT has been called will return the proper values.
	 */
	if (bd->type >= PCIXEM) { /* Begin get PCI number of ports */
		/*
		 * Below we use XEMPORTS as a memory offset regardless of which
		 * PCI card it is. This is because all of the supported PCI
		 * cards have the same memory offset for the channel data. This
		 * will have to be changed if we ever develop a PCI/XE card.
		 * NOTE : The FEP manual states that the port offset is 0xC22
		 * as opposed to 0xC02. This is only true for PC/XE, and PC/XI
		 * cards; not for the XEM, or CX series. On the PCI cards the
		 * number of ports is determined by reading a ID PROM located
		 * in the box attached to the card. The card can then determine
		 * the index the id to determine the number of ports available.
		 * (FYI - The id should be located at 0x1ac (And may use up to
		 * 4 bytes if the box in question is a XEM or CX)).
		 */
		/* PCI cards are already remapped at this point ISA are not */
		bd->numports = readw(bd->re_map_membase + XEMPORTS);
		epcaassert(bd->numports <= 64, "PCI returned a invalid number of ports");
		nbdevs += (bd->numports);
	} else {
		/* Fix up the mappings for ISA/EISA etc */
		/* FIXME: 64K - can we be smarter ? */
		bd->re_map_membase = ioremap_nocache(bd->membase, 0x10000);
	}

	if (crd != 0)
		card_ptr[crd] = card_ptr[crd-1] + boards[crd-1].numports;
	else
		card_ptr[crd] = &digi_channels[crd]; /* <- For card 0 only */

	ch = card_ptr[crd];
	epcaassert(ch <= &digi_channels[nbdevs - 1], "ch out of range");

	memaddr = bd->re_map_membase;

	/*
	 * The below assignment will set bc to point at the BEGINING of the
	 * cards channel structures. For 1 card there will be between 8 and 64
	 * of these structures.
	 */
	bc = memaddr + CHANSTRUCT;

	/*
	 * The below assignment will set gd to point at the BEGINING of global
	 * memory address 0xc00. The first data in that global memory actually
	 * starts at address 0xc1a. The command in pointer begins at 0xd10.
	 */
	gd = memaddr + GLOBAL;

	/*
	 * XEPORTS (address 0xc22) points at the number of channels the card
	 * supports. (For 64XE, XI, XEM, and XR use 0xc02)
	 */
	if ((bd->type == PCXEVE || bd->type == PCXE) &&
					(readw(memaddr + XEPORTS) < 3))
		shrinkmem = 1;
	if (bd->type < PCIXEM)
		if (!request_region((int)bd->port, 4, board_desc[bd->type]))
			return;
	memwinon(bd, 0);

	/*
	 * Remember ch is the main drivers channels structure, while bc is the
	 * cards channel structure.
	 */
	for (i = 0; i < bd->numports; i++, ch++, bc++) {
		unsigned long flags;
		u16 tseg, rseg;

		tty_port_init(&ch->port);
		ch->port.ops = &epca_port_ops;
		ch->brdchan = bc;
		ch->mailbox = gd;
		INIT_WORK(&ch->tqueue, do_softint);
		ch->board = &boards[crd];

		spin_lock_irqsave(&epca_lock, flags);
		switch (bd->type) {
		/*
		 * Since some of the boards use different bitmaps for
		 * their control signals we cannot hard code these
		 * values and retain portability. We virtualize this
		 * data here.
		 */
		case EISAXEM:
		case PCXEM:
		case PCIXEM:
		case PCIXRJ:
		case PCIXR:
			ch->m_rts = 0x02;
			ch->m_dcd = 0x80;
			ch->m_dsr = 0x20;
			ch->m_cts = 0x10;
			ch->m_ri  = 0x40;
			ch->m_dtr = 0x01;
			break;

		case PCXE:
		case PCXEVE:
		case PCXI:
		case PC64XE:
			ch->m_rts = 0x02;
			ch->m_dcd = 0x08;
			ch->m_dsr = 0x10;
			ch->m_cts = 0x20;
			ch->m_ri  = 0x40;
			ch->m_dtr = 0x80;
			break;
		}

		if (boards[crd].altpin) {
			ch->dsr = ch->m_dcd;
			ch->dcd = ch->m_dsr;
			ch->digiext.digi_flags |= DIGI_ALTPIN;
		} else {
			ch->dcd = ch->m_dcd;
			ch->dsr = ch->m_dsr;
		}

		ch->boardnum   = crd;
		ch->channelnum = i;
		ch->magic      = EPCA_MAGIC;
		tty_port_tty_set(&ch->port, NULL);

		if (shrinkmem) {
			fepcmd(ch, SETBUFFER, 32, 0, 0, 0);
			shrinkmem = 0;
		}

		tseg = readw(&bc->tseg);
		rseg = readw(&bc->rseg);

		switch (bd->type) {
		case PCIXEM:
		case PCIXRJ:
		case PCIXR:
			/* Cover all the 2MEG cards */
			ch->txptr = memaddr + ((tseg << 4) & 0x1fffff);
			ch->rxptr = memaddr + ((rseg << 4) & 0x1fffff);
			ch->txwin = FEPWIN | (tseg >> 11);
			ch->rxwin = FEPWIN | (rseg >> 11);
			break;

		case PCXEM:
		case EISAXEM:
			/* Cover all the 32K windowed cards */
			/* Mask equal to window size - 1 */
			ch->txptr = memaddr + ((tseg << 4) & 0x7fff);
			ch->rxptr = memaddr + ((rseg << 4) & 0x7fff);
			ch->txwin = FEPWIN | (tseg >> 11);
			ch->rxwin = FEPWIN | (rseg >> 11);
			break;

		case PCXEVE:
		case PCXE:
			ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4)
								& 0x1fff);
			ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9);
			ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4)
								& 0x1fff);
			ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >> 9);
			break;

		case PCXI:
		case PC64XE:
			ch->txptr = memaddr + ((tseg - bd->memory_seg) << 4);
			ch->rxptr = memaddr + ((rseg - bd->memory_seg) << 4);
			ch->txwin = ch->rxwin = 0;
			break;
		}

		ch->txbufhead = 0;
		ch->txbufsize = readw(&bc->tmax) + 1;

		ch->rxbufhead = 0;
		ch->rxbufsize = readw(&bc->rmax) + 1;

		lowwater = ch->txbufsize >= 2000 ? 1024 : (ch->txbufsize / 2);

		/* Set transmitter low water mark */
		fepcmd(ch, STXLWATER, lowwater, 0, 10, 0);

		/* Set receiver low water mark */
		fepcmd(ch, SRXLWATER, (ch->rxbufsize / 4), 0, 10, 0);

		/* Set receiver high water mark */
		fepcmd(ch, SRXHWATER, (3 * ch->rxbufsize / 4), 0, 10, 0);

		writew(100, &bc->edelay);
		writeb(1, &bc->idata);

		ch->startc  = readb(&bc->startc);
		ch->stopc   = readb(&bc->stopc);
		ch->startca = readb(&bc->startca);
		ch->stopca  = readb(&bc->stopca);

		ch->fepcflag = 0;
		ch->fepiflag = 0;
		ch->fepoflag = 0;
		ch->fepstartc = 0;
		ch->fepstopc = 0;
		ch->fepstartca = 0;
		ch->fepstopca = 0;

		ch->port.close_delay = 50;

		spin_unlock_irqrestore(&epca_lock, flags);
	}

	printk(KERN_INFO
	"Digi PC/Xx Driver V%s:  %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n",
				VERSION, board_desc[bd->type], (long)bd->port,
					(long)bd->membase, bd->numports);
	memwinoff(bd, 0);
}

static void epcapoll(unsigned long ignored)
{
	unsigned long flags;
	int crd;
	unsigned int head, tail;
	struct channel *ch;
	struct board_info *bd;

	/*
	 * This routine is called upon every timer interrupt. Even though the
	 * Digi series cards are capable of generating interrupts this method
	 * of non-looping polling is more efficient. This routine checks for
	 * card generated events (Such as receive data, are transmit buffer
	 * empty) and acts on those events.
	 */
	for (crd = 0; crd < num_cards; crd++) {
		bd = &boards[crd];
		ch = card_ptr[crd];

		if ((bd->status == DISABLED) || digi_poller_inhibited)
			continue;

		/*
		 * assertmemoff is not needed here; indeed it is an empty
		 * subroutine. It is being kept because future boards may need
		 * this as well as some legacy boards.
		 */
		spin_lock_irqsave(&epca_lock, flags);

		assertmemoff(ch);

		globalwinon(ch);

		/*
		 * In this case head and tail actually refer to the event queue
		 * not the transmit or receive queue.
		 */
		head = readw(&ch->mailbox->ein);
		tail = readw(&ch->mailbox->eout);

		/* If head isn't equal to tail we have an event */
		if (head != tail)
			doevent(crd);
		memoff(ch);

		spin_unlock_irqrestore(&epca_lock, flags);
	} /* End for each card */
	mod_timer(&epca_timer, jiffies + (HZ / 25));
}

static void doevent(int crd)
{
	void __iomem *eventbuf;
	struct channel *ch, *chan0;
	static struct tty_struct *tty;
	struct board_info *bd;
	struct board_chan __iomem *bc;
	unsigned int tail, head;
	int event, channel;
	int mstat, lstat;

	/*
	 * This subroutine is called by epcapoll when an event is detected
	 * in the event queue. This routine responds to those events.
	 */
	bd = &boards[crd];

	chan0 = card_ptr[crd];
	epcaassert(chan0 <= &digi_channels[nbdevs - 1], "ch out of range");
	assertgwinon(chan0);
	while ((tail = readw(&chan0->mailbox->eout)) !=
			(head = readw(&chan0->mailbox->ein))) {
		/* Begin while something in event queue */
		assertgwinon(chan0);
		eventbuf = bd->re_map_membase + tail + ISTART;
		/* Get the channel the event occurred on */
		channel = readb(eventbuf);
		/* Get the actual event code that occurred */
		event = readb(eventbuf + 1);
		/*
		 * The two assignments below get the current modem status
		 * (mstat) and the previous modem status (lstat). These are
		 * useful becuase an event could signal a change in modem
		 * signals itself.
		 */
		mstat = readb(eventbuf + 2);
		lstat = readb(eventbuf + 3);

		ch = chan0 + channel;
		if ((unsigned)channel >= bd->numports || !ch)  {
			if (channel >= bd->numports)
				ch = chan0;
			bc = ch->brdchan;
			goto next;
		}

		bc = ch->brdchan;
		if (bc == NULL)
			goto next;

		tty = tty_port_tty_get(&ch->port);
		if (event & DATA_IND)  { /* Begin DATA_IND */
			receive_data(ch, tty);
			assertgwinon(ch);
		} /* End DATA_IND */
		/* else *//* Fix for DCD transition missed bug */
		if (event & MODEMCHG_IND) {
			/* A modem signal change has been indicated */
			ch->imodem = mstat;
			if (test_bit(ASYNCB_CHECK_CD, &ch->port.flags)) {
				/* We are now receiving dcd */
				if (mstat & ch->dcd)
					wake_up_interruptible(&ch->port.open_wait);
				else	/* No dcd; hangup */
					pc_sched_event(ch, EPCA_EVENT_HANGUP);
			}
		}
		if (tty) {
			if (event & BREAK_IND) {
				/* A break has been indicated */
				tty_insert_flip_char(tty, 0, TTY_BREAK);
				tty_schedule_flip(tty);
			} else if (event & LOWTX_IND)  {
				if (ch->statusflags & LOWWAIT) {
					ch->statusflags &= ~LOWWAIT;
					tty_wakeup(tty);
				}
			} else if (event & EMPTYTX_IND) {
				/* This event is generated by
				   setup_empty_event */
				ch->statusflags &= ~TXBUSY;
				if (ch->statusflags & EMPTYWAIT) {
					ch->statusflags &= ~EMPTYWAIT;
					tty_wakeup(tty);
				}
			}
			tty_kref_put(tty);
		}
next:
		globalwinon(ch);
		BUG_ON(!bc);
		writew(1, &bc->idata);
		writew((tail + 4) & (IMAX - ISTART - 4), &chan0->mailbox->eout);
		globalwinon(chan0);
	} /* End while something in event queue */
}

static void fepcmd(struct channel *ch, int cmd, int word_or_byte,
					int byte2, int ncmds, int bytecmd)
{
	unchar __iomem *memaddr;
	unsigned int head, cmdTail, cmdStart, cmdMax;
	long count;
	int n;

	/* This is the routine in which commands may be passed to the card. */

	if (ch->board->status == DISABLED)
		return;
	assertgwinon(ch);
	/* Remember head (As well as max) is just an offset not a base addr */
	head = readw(&ch->mailbox->cin);
	/* cmdStart is a base address */
	cmdStart = readw(&ch->mailbox->cstart);
	/*
	 * We do the addition below because we do not want a max pointer
	 * relative to cmdStart. We want a max pointer that points at the
	 * physical end of the command queue.
	 */
	cmdMax = (cmdStart + 4 + readw(&ch->mailbox->cmax));
	memaddr = ch->board->re_map_membase;

	if (head >= (cmdMax - cmdStart) || (head & 03))  {
		printk(KERN_ERR "line %d: Out of range, cmd = %x, head = %x\n",
						__LINE__,  cmd, head);
		printk(KERN_ERR "line %d: Out of range, cmdMax = %x, cmdStart = %x\n",
						__LINE__,  cmdMax, cmdStart);
		return;
	}
	if (bytecmd)  {
		writeb(cmd, memaddr + head + cmdStart + 0);
		writeb(ch->channelnum,  memaddr + head + cmdStart + 1);
		/* Below word_or_byte is bits to set */
		writeb(word_or_byte,  memaddr + head + cmdStart + 2);
		/* Below byte2 is bits to reset */
		writeb(byte2, memaddr + head + cmdStart + 3);
	}  else {
		writeb(cmd, memaddr + head + cmdStart + 0);
		writeb(ch->channelnum,  memaddr + head + cmdStart + 1);
		writeb(word_or_byte,  memaddr + head + cmdStart + 2);
	}
	head = (head + 4) & (cmdMax - cmdStart - 4);
	writew(head, &ch->mailbox->cin);
	count = FEPTIMEOUT;

	for (;;) {
		count--;
		if (count == 0)  {
			printk(KERN_ERR "<Error> - Fep not responding in fepcmd()\n");
			return;
		}
		head = readw(&ch->mailbox->cin);
		cmdTail = readw(&ch->mailbox->cout);
		n = (head - cmdTail) & (cmdMax - cmdStart - 4);
		/*
		 * Basically this will break when the FEP acknowledges the
		 * command by incrementing cmdTail (Making it equal to head).
		 */
		if (n <= ncmds * (sizeof(short) * 4))
			break;
	}
}

/*
 * Digi products use fields in their channels structures that are very similar
 * to the c_cflag and c_iflag fields typically found in UNIX termios
 * structures. The below three routines allow mappings between these hardware
 * "flags" and their respective Linux flags.
 */
static unsigned termios2digi_h(struct channel *ch, unsigned cflag)
{
	unsigned res = 0;

	if (cflag & CRTSCTS) {
		ch->digiext.digi_flags |= (RTSPACE | CTSPACE);
		res |= ((ch->m_cts) | (ch->m_rts));
	}

	if (ch->digiext.digi_flags & RTSPACE)
		res |= ch->m_rts;

	if (ch->digiext.digi_flags & DTRPACE)
		res |= ch->m_dtr;

	if (ch->digiext.digi_flags & CTSPACE)
		res |= ch->m_cts;

	if (ch->digiext.digi_flags & DSRPACE)
		res |= ch->dsr;

	if (ch->digiext.digi_flags & DCDPACE)
		res |= ch->dcd;

	if (res & (ch->m_rts))
		ch->digiext.digi_flags |= RTSPACE;

	if (res & (ch->m_cts))
		ch->digiext.digi_flags |= CTSPACE;

	return res;
}

static unsigned termios2digi_i(struct channel *ch, unsigned iflag)
{
	unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK |
					INPCK | ISTRIP | IXON | IXANY | IXOFF);
	if (ch->digiext.digi_flags & DIGI_AIXON)
		res |= IAIXON;
	return res;
}

static unsigned termios2digi_c(struct channel *ch, unsigned cflag)
{
	unsigned res = 0;
	if (cflag & CBAUDEX) {
		ch->digiext.digi_flags |= DIGI_FAST;
		/*
		 * HUPCL bit is used by FEP to indicate fast baud table is to
		 * be used.
		 */
		res |= FEP_HUPCL;
	} else
		ch->digiext.digi_flags &= ~DIGI_FAST;
	/*
	 * CBAUD has bit position 0x1000 set these days to indicate Linux
	 * baud rate remap. Digi hardware can't handle the bit assignment.
	 * (We use a different bit assignment for high speed.). Clear this
	 * bit out.
	 */
	res |= cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | CSTOPB | CSIZE);
	/*
	 * This gets a little confusing. The Digi cards have their own
	 * representation of c_cflags controlling baud rate. For the most part
	 * this is identical to the Linux implementation. However; Digi
	 * supports one rate (76800) that Linux doesn't. This means that the
	 * c_cflag entry that would normally mean 76800 for Digi actually means
	 * 115200 under Linux. Without the below mapping, a stty 115200 would
	 * only drive the board at 76800. Since the rate 230400 is also found
	 * after 76800, the same problem afflicts us when we choose a rate of
	 * 230400. Without the below modificiation stty 230400 would actually
	 * give us 115200.
	 *
	 * There are two additional differences. The Linux value for CLOCAL
	 * (0x800; 0004000) has no meaning to the Digi hardware. Also in later
	 * releases of Linux; the CBAUD define has CBAUDEX (0x1000; 0010000)
	 * ored into it (CBAUD = 0x100f as opposed to 0xf). CBAUDEX should be
	 * checked for a screened out prior to termios2digi_c returning. Since
	 * CLOCAL isn't used by the board this can be ignored as long as the
	 * returned value is used only by Digi hardware.
	 */
	if (cflag & CBAUDEX) {
		/*
		 * The below code is trying to guarantee that only baud rates
		 * 115200 and 230400 are remapped. We use exclusive or because
		 * the various baud rates share common bit positions and
		 * therefore can't be tested for easily.
		 */
		if ((!((cflag & 0x7) ^ (B115200 & ~CBAUDEX))) ||
		    (!((cflag & 0x7) ^ (B230400 & ~CBAUDEX))))
			res += 1;
	}
	return res;
}

/* Caller must hold the locks */
static void epcaparam(struct tty_struct *tty, struct channel *ch)
{
	unsigned int cmdHead;
	struct ktermios *ts;
	struct board_chan __iomem *bc;
	unsigned mval, hflow, cflag, iflag;

	bc = ch->brdchan;
	epcaassert(bc != NULL, "bc out of range");

	assertgwinon(ch);
	ts = tty->termios;
	if ((ts->c_cflag & CBAUD) == 0)  { /* Begin CBAUD detected */
		cmdHead = readw(&bc->rin);
		writew(cmdHead, &bc->rout);
		cmdHead = readw(&bc->tin);
		/* Changing baud in mid-stream transmission can be wonderful */
		/*
		 * Flush current transmit buffer by setting cmdTail pointer
		 * (tout) to cmdHead pointer (tin). Hopefully the transmit
		 * buffer is empty.
		 */
		fepcmd(ch, STOUT, (unsigned) cmdHead, 0, 0, 0);
		mval = 0;
	} else { /* Begin CBAUD not detected */
		/*
		 * c_cflags have changed but that change had nothing to do with
		 * BAUD. Propagate the change to the card.
		 */
		cflag = termios2digi_c(ch, ts->c_cflag);
		if (cflag != ch->fepcflag)  {
			ch->fepcflag = cflag;
			/* Set baud rate, char size, stop bits, parity */
			fepcmd(ch, SETCTRLFLAGS, (unsigned) cflag, 0, 0, 0);
		}
		/*
		 * If the user has not forced CLOCAL and if the device is not a
		 * CALLOUT device (Which is always CLOCAL) we set flags such
		 * that the driver will wait on carrier detect.
		 */
		if (ts->c_cflag & CLOCAL)
			clear_bit(ASYNCB_CHECK_CD, &ch->port.flags);
		else
			set_bit(ASYNCB_CHECK_CD, &ch->port.flags);
		mval = ch->m_dtr | ch->m_rts;
	} /* End CBAUD not detected */
	iflag = termios2digi_i(ch, ts->c_iflag);
	/* Check input mode flags */
	if (iflag != ch->fepiflag)  {
		ch->fepiflag = iflag;
		/*
		 * Command sets channels iflag structure on the board. Such
		 * things as input soft flow control, handling of parity
		 * errors, and break handling are all set here.
		 *
		 * break handling, parity handling, input stripping,
		 * flow control chars
		 */
		fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0);
	}
	/*
	 * Set the board mint value for this channel. This will cause hardware
	 * events to be generated each time the DCD signal (Described in mint)
	 * changes.
	 */
	writeb(ch->dcd, &bc->mint);
	if ((ts->c_cflag & CLOCAL) || (ch->digiext.digi_flags & DIGI_FORCEDCD))
		if (ch->digiext.digi_flags & DIGI_FORCEDCD)
			writeb(0, &bc->mint);
	ch->imodem = readb(&bc->mstat);
	hflow = termios2digi_h(ch, ts->c_cflag);
	if (hflow != ch->hflow)  {
		ch->hflow = hflow;
		/*
		 * Hard flow control has been selected but the board is not
		 * using it. Activate hard flow control now.
		 */
		fepcmd(ch, SETHFLOW, hflow, 0xff, 0, 1);
	}
	mval ^= ch->modemfake & (mval ^ ch->modem);

	if (ch->omodem ^ mval)  {
		ch->omodem = mval;
		/*
		 * The below command sets the DTR and RTS mstat structure. If
		 * hard flow control is NOT active these changes will drive the
		 * output of the actual DTR and RTS lines. If hard flow control
		 * is active, the changes will be saved in the mstat structure
		 * and only asserted when hard flow control is turned off.
		 */

		/* First reset DTR & RTS; then set them */
		fepcmd(ch, SETMODEM, 0, ((ch->m_dtr)|(ch->m_rts)), 0, 1);
		fepcmd(ch, SETMODEM, mval, 0, 0, 1);
	}
	if (ch->startc != ch->fepstartc || ch->stopc != ch->fepstopc)  {
		ch->fepstartc = ch->startc;
		ch->fepstopc = ch->stopc;
		/*
		 * The XON / XOFF characters have changed; propagate these
		 * changes to the card.
		 */
		fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1);
	}
	if (ch->startca != ch->fepstartca || ch->stopca != ch->fepstopca)  {
		ch->fepstartca = ch->startca;
		ch->fepstopca = ch->stopca;
		/*
		 * Similar to the above, this time the auxilarly XON / XOFF
		 * characters have changed; propagate these changes to the card.
		 */
		fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1);
	}
}

/* Caller holds lock */
static void receive_data(struct channel *ch, struct tty_struct *tty)
{
	unchar *rptr;
	struct ktermios *ts = NULL;
	struct board_chan __iomem *bc;
	int dataToRead, wrapgap, bytesAvailable;
	unsigned int tail, head;
	unsigned int wrapmask;

	/*
	 * This routine is called by doint when a receive data event has taken
	 * place.
	 */
	globalwinon(ch);
	if (ch->statusflags & RXSTOPPED)
		return;
	if (tty)
		ts = tty->termios;
	bc = ch->brdchan;
	BUG_ON(!bc);
	wrapmask = ch->rxbufsize - 1;

	/*
	 * Get the head and tail pointers to the receiver queue. Wrap the head
	 * pointer if it has reached the end of the buffer.
	 */
	head = readw(&bc->rin);
	head &= wrapmask;
	tail = readw(&bc->rout) & wrapmask;

	bytesAvailable = (head - tail) & wrapmask;
	if (bytesAvailable == 0)
		return;

	/* If CREAD bit is off or device not open, set TX tail to head */
	if (!tty || !ts || !(ts->c_cflag & CREAD)) {
		writew(head, &bc->rout);
		return;
	}

	if (tty_buffer_request_room(tty, bytesAvailable + 1) == 0)
		return;

	if (readb(&bc->orun)) {
		writeb(0, &bc->orun);
		printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n",
								tty->name);
		tty_insert_flip_char(tty, 0, TTY_OVERRUN);
	}
	rxwinon(ch);
	while (bytesAvailable > 0) {
		/* Begin while there is data on the card */
		wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail;
		/*
		 * Even if head has wrapped around only report the amount of
		 * data to be equal to the size - tail. Remember memcpy can't
		 * automaticly wrap around the receive buffer.
		 */
		dataToRead = (wrapgap < bytesAvailable) ? wrapgap
							: bytesAvailable;
		/* Make sure we don't overflow the buffer */
		dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead);
		if (dataToRead == 0)
			break;
		/*
		 * Move data read from our card into the line disciplines
		 * buffer for translation if necessary.
		 */
		memcpy_fromio(rptr, ch->rxptr + tail, dataToRead);
		tail = (tail + dataToRead) & wrapmask;
		bytesAvailable -= dataToRead;
	} /* End while there is data on the card */
	globalwinon(ch);
	writew(tail, &bc->rout);
	/* Must be called with global data */
	tty_schedule_flip(tty);
}

static int info_ioctl(struct tty_struct *tty, struct file *file,
		    unsigned int cmd, unsigned long arg)
{
	switch (cmd) {
	case DIGI_GETINFO:
		{
			struct digi_info di;
			int brd;

			if (get_user(brd, (unsigned int __user *)arg))
				return -EFAULT;
			if (brd < 0 || brd >= num_cards || num_cards == 0)
				return -ENODEV;

			memset(&di, 0, sizeof(di));

			di.board = brd;
			di.status = boards[brd].status;
			di.type = boards[brd].type ;
			di.numports = boards[brd].numports ;
			/* Legacy fixups - just move along nothing to see */
			di.port = (unsigned char *)boards[brd].port ;
			di.membase = (unsigned char *)boards[brd].membase ;

			if (copy_to_user((void __user *)arg, &di, sizeof(di)))
				return -EFAULT;
			break;

		}

	case DIGI_POLLER:
		{
			int brd = arg & 0xff000000 >> 16;
			unsigned char state = arg & 0xff;

			if (brd < 0 || brd >= num_cards) {
				printk(KERN_ERR "epca: DIGI POLLER : brd not valid!\n");
				return -ENODEV;
			}
			digi_poller_inhibited = state;
			break;
		}

	case DIGI_INIT:
		{
			/*
			 * This call is made by the apps to complete the
			 * initialization of the board(s). This routine is
			 * responsible for setting the card to its initial
			 * state and setting the drivers control fields to the
			 * sutianle settings for the card in question.
			 */
			int crd;
			for (crd = 0; crd < num_cards; crd++)
				post_fep_init(crd);
			break;
		}
	default:
		return -ENOTTY;
	}
	return 0;
}

static int pc_tiocmget(struct tty_struct *tty, struct file *file)
{
	struct channel *ch = tty->driver_data;
	struct board_chan __iomem *bc;
	unsigned int mstat, mflag = 0;
	unsigned long flags;

	if (ch)
		bc = ch->brdchan;
	else
		return -EINVAL;

	spin_lock_irqsave(&epca_lock, flags);
	globalwinon(ch);
	mstat = readb(&bc->mstat);
	memoff(ch);
	spin_unlock_irqrestore(&epca_lock, flags);

	if (mstat & ch->m_dtr)
		mflag |= TIOCM_DTR;
	if (mstat & ch->m_rts)
		mflag |= TIOCM_RTS;
	if (mstat & ch->m_cts)
		mflag |= TIOCM_CTS;
	if (mstat & ch->dsr)
		mflag |= TIOCM_DSR;
	if (mstat & ch->m_ri)
		mflag |= TIOCM_RI;
	if (mstat & ch->dcd)
		mflag |= TIOCM_CD;
	return mflag;
}

static int pc_tiocmset(struct tty_struct *tty, struct file *file,
		       unsigned int set, unsigned int clear)
{
	struct channel *ch = tty->driver_data;
	unsigned long flags;

	if (!ch)
		return -EINVAL;

	spin_lock_irqsave(&epca_lock, flags);
	/*
	 * I think this modemfake stuff is broken. It doesn't correctly reflect
	 * the behaviour desired by the TIOCM* ioctls. Therefore this is
	 * probably broken.
	 */
	if (set & TIOCM_RTS) {
		ch->modemfake |= ch->m_rts;
		ch->modem |= ch->m_rts;
	}
	if (set & TIOCM_DTR) {
		ch->modemfake |= ch->m_dtr;
		ch->modem |= ch->m_dtr;
	}
	if (clear & TIOCM_RTS) {
		ch->modemfake |= ch->m_rts;
		ch->modem &= ~ch->m_rts;
	}
	if (clear & TIOCM_DTR) {
		ch->modemfake |= ch->m_dtr;
		ch->modem &= ~ch->m_dtr;
	}
	globalwinon(ch);
	/*
	 * The below routine generally sets up parity, baud, flow control
	 * issues, etc.... It effect both control flags and input flags.
	 */
	epcaparam(tty, ch);
	memoff(ch);
	spin_unlock_irqrestore(&epca_lock, flags);
	return 0;
}

static int pc_ioctl(struct tty_struct *tty, struct file *file,
					unsigned int cmd, unsigned long arg)
{
	digiflow_t dflow;
	unsigned long flags;
	unsigned int mflag, mstat;
	unsigned char startc, stopc;
	struct board_chan __iomem *bc;
	struct channel *ch = tty->driver_data;
	void __user *argp = (void __user *)arg;

	if (ch)
		bc = ch->brdchan;
	else
		return -EINVAL;
	switch (cmd) {
	case TIOCMODG:
		mflag = pc_tiocmget(tty, file);
		if (put_user(mflag, (unsigned long __user *)argp))
			return -EFAULT;
		break;
	case TIOCMODS:
		if (get_user(mstat, (unsigned __user *)argp))
			return -EFAULT;
		return pc_tiocmset(tty, file, mstat, ~mstat);
	case TIOCSDTR:
		spin_lock_irqsave(&epca_lock, flags);
		ch->omodem |= ch->m_dtr;
		globalwinon(ch);
		fepcmd(ch, SETMODEM, ch->m_dtr, 0, 10, 1);
		memoff(ch);
		spin_unlock_irqrestore(&epca_lock, flags);
		break;

	case TIOCCDTR:
		spin_lock_irqsave(&epca_lock, flags);
		ch->omodem &= ~ch->m_dtr;
		globalwinon(ch);
		fepcmd(ch, SETMODEM, 0, ch->m_dtr, 10, 1);
		memoff(ch);
		spin_unlock_irqrestore(&epca_lock, flags);
		break;
	case DIGI_GETA:
		if (copy_to_user(argp, &ch->digiext, sizeof(digi_t)))
			return -EFAULT;
		break;
	case DIGI_SETAW:
	case DIGI_SETAF:
		lock_kernel();
		if (cmd == DIGI_SETAW) {
			/* Setup an event to indicate when the transmit
			   buffer empties */
			spin_lock_irqsave(&epca_lock, flags);
			setup_empty_event(tty, ch);
			spin_unlock_irqrestore(&epca_lock, flags);
			tty_wait_until_sent(tty, 0);
		} else {
			/* ldisc lock already held in ioctl */
			if (tty->ldisc->ops->flush_buffer)
				tty->ldisc->ops->flush_buffer(tty);
		}
		unlock_kernel();
		/* Fall Thru */
	case DIGI_SETA:
		if (copy_from_user(&ch->digiext, argp, sizeof(digi_t)))
			return -EFAULT;

		if (ch->digiext.digi_flags & DIGI_ALTPIN)  {
			ch->dcd = ch->m_dsr;
			ch->dsr = ch->m_dcd;
		} else {
			ch->dcd = ch->m_dcd;
			ch->dsr = ch->m_dsr;
			}

		spin_lock_irqsave(&epca_lock, flags);
		globalwinon(ch);

		/*
		 * The below routine generally sets up parity, baud, flow
		 * control issues, etc.... It effect both control flags and
		 * input flags.
		 */
		epcaparam(tty, ch);
		memoff(ch);
		spin_unlock_irqrestore(&epca_lock, flags);
		break;

	case DIGI_GETFLOW:
	case DIGI_GETAFLOW:
		spin_lock_irqsave(&epca_lock, flags);
		globalwinon(ch);
		if (cmd == DIGI_GETFLOW) {
			dflow.startc = readb(&bc->startc);
			dflow.stopc = readb(&bc->stopc);
		} else {
			dflow.startc = readb(&bc->startca);
			dflow.stopc = readb(&bc->stopca);
		}
		memoff(ch);
		spin_unlock_irqrestore(&epca_lock, flags);

		if (copy_to_user(argp, &dflow, sizeof(dflow)))
			return -EFAULT;
		break;

	case DIGI_SETAFLOW:
	case DIGI_SETFLOW:
		if (cmd == DIGI_SETFLOW) {
			startc = ch->startc;
			stopc = ch->stopc;
		} else {
			startc = ch->startca;
			stopc = ch->stopca;
		}

		if (copy_from_user(&dflow, argp, sizeof(dflow)))
			return -EFAULT;

		if (dflow.startc != startc || dflow.stopc != stopc) {
			/* Begin  if setflow toggled */
			spin_lock_irqsave(&epca_lock, flags);
			globalwinon(ch);

			if (cmd == DIGI_SETFLOW) {
				ch->fepstartc = ch->startc = dflow.startc;
				ch->fepstopc = ch->stopc = dflow.stopc;
				fepcmd(ch, SONOFFC, ch->fepstartc,
						ch->fepstopc, 0, 1);
			} else {
				ch->fepstartca = ch->startca = dflow.startc;
				ch->fepstopca  = ch->stopca = dflow.stopc;
				fepcmd(ch, SAUXONOFFC, ch->fepstartca,
						ch->fepstopca, 0, 1);
			}

			if (ch->statusflags & TXSTOPPED)
				pc_start(tty);

			memoff(ch);
			spin_unlock_irqrestore(&epca_lock, flags);
		} /* End if setflow toggled */
		break;
	default:
		return -ENOIOCTLCMD;
	}
	return 0;
}

static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
{
	struct channel *ch;
	unsigned long flags;
	/*
	 * verifyChannel returns the channel from the tty struct if it is
	 * valid. This serves as a sanity check.
	 */
	ch = verifyChannel(tty);

	if (ch != NULL)  { /* Begin if channel valid */
		spin_lock_irqsave(&epca_lock, flags);
		globalwinon(ch);
		epcaparam(tty, ch);
		memoff(ch);
		spin_unlock_irqrestore(&epca_lock, flags);

		if ((old_termios->c_cflag & CRTSCTS) &&
			 ((tty->termios->c_cflag & CRTSCTS) == 0))
			tty->hw_stopped = 0;

		if (!(old_termios->c_cflag & CLOCAL) &&
			 (tty->termios->c_cflag & CLOCAL))
			wake_up_interruptible(&ch->port.open_wait);

	} /* End if channel valid */
}

static void do_softint(struct work_struct *work)
{
	struct channel *ch = container_of(work, struct channel, tqueue);
	/* Called in response to a modem change event */
	if (ch && ch->magic == EPCA_MAGIC) {
		struct tty_struct *tty = tty_port_tty_get(&ch->port);

		if (tty && tty->driver_data) {
			if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) {
				tty_hangup(tty);
				wake_up_interruptible(&ch->port.open_wait);
				clear_bit(ASYNCB_NORMAL_ACTIVE,
						&ch->port.flags);
			}
		}
		tty_kref_put(tty);
	}
}

/*
 * pc_stop and pc_start provide software flow control to the routine and the
 * pc_ioctl routine.
 */
static void pc_stop(struct tty_struct *tty)
{
	struct channel *ch;
	unsigned long flags;
	/*
	 * verifyChannel returns the channel from the tty struct if it is
	 * valid. This serves as a sanity check.
	 */
	ch = verifyChannel(tty);
	if (ch != NULL) {
		spin_lock_irqsave(&epca_lock, flags);
		if ((ch->statusflags & TXSTOPPED) == 0) {
			/* Begin if transmit stop requested */
			globalwinon(ch);
			/* STOP transmitting now !! */
			fepcmd(ch, PAUSETX, 0, 0, 0, 0);
			ch->statusflags |= TXSTOPPED;
			memoff(ch);
		} /* End if transmit stop requested */
		spin_unlock_irqrestore(&epca_lock, flags);
	}
}

static void pc_start(struct tty_struct *tty)
{
	struct channel *ch;
	/*
	 * verifyChannel returns the channel from the tty struct if it is
	 * valid. This serves as a sanity check.
	 */
	ch = verifyChannel(tty);
	if (ch != NULL) {
		unsigned long flags;
		spin_lock_irqsave(&epca_lock, flags);
		/* Just in case output was resumed because of a change
		   in Digi-flow */
		if (ch->statusflags & TXSTOPPED)  {
			/* Begin transmit resume requested */
			struct board_chan __iomem *bc;
			globalwinon(ch);
			bc = ch->brdchan;
			if (ch->statusflags & LOWWAIT)
				writeb(1, &bc->ilow);
			/* Okay, you can start transmitting again... */
			fepcmd(ch, RESUMETX, 0, 0, 0, 0);
			ch->statusflags &= ~TXSTOPPED;
			memoff(ch);
		} /* End transmit resume requested */
		spin_unlock_irqrestore(&epca_lock, flags);
	}
}

/*
 * The below routines pc_throttle and pc_unthrottle are used to slow (And
 * resume) the receipt of data into the kernels receive buffers. The exact
 * occurrence of this depends on the size of the kernels receive buffer and
 * what the 'watermarks' are set to for that buffer. See the n_ttys.c file for
 * more details.
 */
static void pc_throttle(struct tty_struct *tty)
{
	struct channel *ch;
	unsigned long flags;
	/*
	 * verifyChannel returns the channel from the tty struct if it is
	 * valid. This serves as a sanity check.
	 */
	ch = verifyChannel(tty);
	if (ch != NULL) {
		spin_lock_irqsave(&epca_lock, flags);
		if ((ch->statusflags & RXSTOPPED) == 0) {
			globalwinon(ch);
			fepcmd(ch, PAUSERX, 0, 0, 0, 0);
			ch->statusflags |= RXSTOPPED;
			memoff(ch);
		}
		spin_unlock_irqrestore(&epca_lock, flags);
	}
}

static void pc_unthrottle(struct tty_struct *tty)
{
	struct channel *ch;
	unsigned long flags;
	/*
	 * verifyChannel returns the channel from the tty struct if it is
	 * valid. This serves as a sanity check.
	 */
	ch = verifyChannel(tty);
	if (ch != NULL) {
		/* Just in case output was resumed because of a change
		   in Digi-flow */
		spin_lock_irqsave(&epca_lock, flags);
		if (ch->statusflags & RXSTOPPED) {
			globalwinon(ch);
			fepcmd(ch, RESUMERX, 0, 0, 0, 0);
			ch->statusflags &= ~RXSTOPPED;
			memoff(ch);
		}
		spin_unlock_irqrestore(&epca_lock, flags);
	}
}

static int pc_send_break(struct tty_struct *tty, int msec)
{
	struct channel *ch = tty->driver_data;
	unsigned long flags;

	if (msec == -1)
		msec = 0xFFFF;
	else if (msec > 0xFFFE)
		msec = 0xFFFE;
	else if (msec < 1)
		msec = 1;

	spin_lock_irqsave(&epca_lock, flags);
	globalwinon(ch);
	/*
	 * Maybe I should send an infinite break here, schedule() for msec
	 * amount of time, and then stop the break. This way, the user can't
	 * screw up the FEP by causing digi_send_break() to be called (i.e. via
	 * an ioctl()) more than once in msec amount of time.
	 * Try this for now...
	 */
	fepcmd(ch, SENDBREAK, msec, 0, 10, 0);
	memoff(ch);
	spin_unlock_irqrestore(&epca_lock, flags);
	return 0;
}

/* Caller MUST hold the lock */
static void setup_empty_event(struct tty_struct *tty, struct channel *ch)
{
	struct board_chan __iomem *bc = ch->brdchan;

	globalwinon(ch);
	ch->statusflags |= EMPTYWAIT;
	/*
	 * When set the iempty flag request a event to be generated when the
	 * transmit buffer is empty (If there is no BREAK in progress).
	 */
	writeb(1, &bc->iempty);
	memoff(ch);
}

#ifndef MODULE
static void __init epca_setup(char *str, int *ints)
{
	struct board_info board;
	int               index, loop, last;
	char              *temp, *t2;
	unsigned          len;

	/*
	 * If this routine looks a little strange it is because it is only
	 * called if a LILO append command is given to boot the kernel with
	 * parameters. In this way, we can provide the user a method of
	 * changing his board configuration without rebuilding the kernel.
	 */
	if (!liloconfig)
		liloconfig = 1;

	memset(&board, 0, sizeof(board));

	/* Assume the data is int first, later we can change it */
	/* I think that array position 0 of ints holds the number of args */
	for (last = 0, index = 1; index <= ints[0]; index++)
		switch (index) { /* Begin parse switch */
		case 1:
			board.status = ints[index];
			/*
			 * We check for 2 (As opposed to 1; because 2 is a flag
			 * instructing the driver to ignore epcaconfig.) For
			 * this reason we check for 2.
			 */
			if (board.status == 2) {
			/* Begin ignore epcaconfig as well as lilo cmd line */
				nbdevs = 0;
				num_cards = 0;
				return;
			} /* End ignore epcaconfig as well as lilo cmd line */

			if (board.status > 2) {
				printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n",
						board.status);
				invalid_lilo_config = 1;
				setup_error_code |= INVALID_BOARD_STATUS;
				return;
			}
			last = index;
			break;
		case 2:
			board.type = ints[index];
			if (board.type >= PCIXEM)  {
				printk(KERN_ERR "epca_setup: Invalid board type 0x%x\n", board.type);
				invalid_lilo_config = 1;
				setup_error_code |= INVALID_BOARD_TYPE;
				return;
			}
			last = index;
			break;
		case 3:
			board.altpin = ints[index];
			if (board.altpin > 1) {
				printk(KERN_ERR "epca_setup: Invalid board altpin 0x%x\n", board.altpin);
				invalid_lilo_config = 1;
				setup_error_code |= INVALID_ALTPIN;
				return;
			}
			last = index;
			break;

		case 4:
			board.numports = ints[index];
			if (board.numports < 2 || board.numports > 256) {
				printk(KERN_ERR "epca_setup: Invalid board numports 0x%x\n", board.numports);
				invalid_lilo_config = 1;
				setup_error_code |= INVALID_NUM_PORTS;
				return;
			}
			nbdevs += board.numports;
			last = index;
			break;

		case 5:
			board.port = ints[index];
			if (ints[index] <= 0) {
				printk(KERN_ERR "epca_setup: Invalid io port 0x%x\n", (unsigned int)board.port);
				invalid_lilo_config = 1;
				setup_error_code |= INVALID_PORT_BASE;
				return;
			}
			last = index;
			break;

		case 6:
			board.membase = ints[index];
			if (ints[index] <= 0) {
				printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n",
					(unsigned int)board.membase);
				invalid_lilo_config = 1;
				setup_error_code |= INVALID_MEM_BASE;
				return;
			}
			last = index;
			break;

		default:
			printk(KERN_ERR "<Error> - epca_setup: Too many integer parms\n");
			return;

		} /* End parse switch */

	while (str && *str)  { /* Begin while there is a string arg */
		/* find the next comma or terminator */
		temp = str;
		/* While string is not null, and a comma hasn't been found */
		while (*temp && (*temp != ','))
			temp++;
		if (!*temp)
			temp = NULL;
		else
			*temp++ = 0;
		/* Set index to the number of args + 1 */
		index = last + 1;

		switch (index) {
		case 1:
			len = strlen(str);
			if (strncmp("Disable", str, len) == 0)
				board.status = 0;
			else if (strncmp("Enable", str, len) == 0)
				board.status = 1;
			else {
				printk(KERN_ERR "epca_setup: Invalid status %s\n", str);
				invalid_lilo_config = 1;
				setup_error_code |= INVALID_BOARD_STATUS;
				return;
			}
			last = index;
			break;

		case 2:
			for (loop = 0; loop < EPCA_NUM_TYPES; loop++)
				if (strcmp(board_desc[loop], str) == 0)
					break;
			/*
			 * If the index incremented above refers to a
			 * legitamate board type set it here.
			 */
			if (index < EPCA_NUM_TYPES)
				board.type = loop;
			else {
				printk(KERN_ERR "epca_setup: Invalid board type: %s\n", str);
				invalid_lilo_config = 1;
				setup_error_code |= INVALID_BOARD_TYPE;
				return;
			}
			last = index;
			break;

		case 3:
			len = strlen(str);
			if (strncmp("Disable", str, len) == 0)
				board.altpin = 0;
			else if (strncmp("Enable", str, len) == 0)
				board.altpin = 1;
			else {
				printk(KERN_ERR "epca_setup: Invalid altpin %s\n", str);
				invalid_lilo_config = 1;
				setup_error_code |= INVALID_ALTPIN;
				return;
			}
			last = index;
			break;

		case 4:
			t2 = str;
			while (isdigit(*t2))
				t2++;

			if (*t2) {
				printk(KERN_ERR "epca_setup: Invalid port count %s\n", str);
				invalid_lilo_config = 1;
				setup_error_code |= INVALID_NUM_PORTS;
				return;
			}

			/*
			 * There is not a man page for simple_strtoul but the
			 * code can be found in vsprintf.c. The first argument
			 * is the string to translate (To an unsigned long
			 * obviously), the second argument can be the address
			 * of any character variable or a NULL. If a variable
			 * is given, the end pointer of the string will be
			 * stored in that variable; if a NULL is given the end
			 * pointer will not be returned. The last argument is
			 * the base to use. If a 0 is indicated, the routine
			 * will attempt to determine the proper base by looking
			 * at the values prefix (A '0' for octal, a 'x' for
			 * hex, etc ... If a value is given it will use that
			 * value as the base.
			 */
			board.numports = simple_strtoul(str, NULL, 0);
			nbdevs += board.numports;
			last = index;
			break;

		case 5:
			t2 = str;
			while (isxdigit(*t2))
				t2++;

			if (*t2) {
				printk(KERN_ERR "epca_setup: Invalid i/o address %s\n", str);
				invalid_lilo_config = 1;
				setup_error_code |= INVALID_PORT_BASE;
				return;
			}

			board.port = simple_strtoul(str, NULL, 16);
			last = index;
			break;

		case 6:
			t2 = str;
			while (isxdigit(*t2))
				t2++;

			if (*t2) {
				printk(KERN_ERR "epca_setup: Invalid memory base %s\n", str);
				invalid_lilo_config = 1;
				setup_error_code |= INVALID_MEM_BASE;
				return;
			}
			board.membase = simple_strtoul(str, NULL, 16);
			last = index;
			break;
		default:
			printk(KERN_ERR "epca: Too many string parms\n");
			return;
		}
		str = temp;
	} /* End while there is a string arg */

	if (last < 6) {
		printk(KERN_ERR "epca: Insufficient parms specified\n");
		return;
	}

	/* I should REALLY validate the stuff here */
	/* Copies our local copy of board into boards */
	memcpy((void *)&boards[num_cards], (void *)&board, sizeof(board));
	/* Does this get called once per lilo arg are what ? */
	printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n",
		num_cards, board_desc[board.type],
		board.numports, (int)board.port, (unsigned int) board.membase);
	num_cards++;
}

static int __init epca_real_setup(char *str)
{
	int ints[11];

	epca_setup(get_options(str, 11, ints), ints);
	return 1;
}

__setup("digiepca", epca_real_setup);
#endif

enum epic_board_types {
	brd_xr = 0,
	brd_xem,
	brd_cx,
	brd_xrj,
};

/* indexed directly by epic_board_types enum */
static struct {
	unsigned char board_type;
	unsigned bar_idx;		/* PCI base address region */
} epca_info_tbl[] = {
	{ PCIXR, 0, },
	{ PCIXEM, 0, },
	{ PCICX, 0, },
	{ PCIXRJ, 2, },
};

static int __devinit epca_init_one(struct pci_dev *pdev,
				 const struct pci_device_id *ent)
{
	static int board_num = -1;
	int board_idx, info_idx = ent->driver_data;
	unsigned long addr;

	if (pci_enable_device(pdev))
		return -EIO;

	board_num++;
	board_idx = board_num + num_cards;
	if (board_idx >= MAXBOARDS)
		goto err_out;

	addr = pci_resource_start(pdev, epca_info_tbl[info_idx].bar_idx);
	if (!addr) {
		printk(KERN_ERR PFX "PCI region #%d not available (size 0)\n",
			epca_info_tbl[info_idx].bar_idx);
		goto err_out;
	}

	boards[board_idx].status = ENABLED;
	boards[board_idx].type = epca_info_tbl[info_idx].board_type;
	boards[board_idx].numports = 0x0;
	boards[board_idx].port = addr + PCI_IO_OFFSET;
	boards[board_idx].membase = addr;

	if (!request_mem_region(addr + PCI_IO_OFFSET, 0x200000, "epca")) {
		printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n",
			0x200000, addr + PCI_IO_OFFSET);
		goto err_out;
	}

	boards[board_idx].re_map_port = ioremap_nocache(addr + PCI_IO_OFFSET,
								0x200000);
	if (!boards[board_idx].re_map_port) {
		printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n",
			0x200000, addr + PCI_IO_OFFSET);
		goto err_out_free_pciio;
	}

	if (!request_mem_region(addr, 0x200000, "epca")) {
		printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n",
			0x200000, addr);
		goto err_out_free_iounmap;
	}

	boards[board_idx].re_map_membase = ioremap_nocache(addr, 0x200000);
	if (!boards[board_idx].re_map_membase) {
		printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n",
			0x200000, addr + PCI_IO_OFFSET);
		goto err_out_free_memregion;
	}

	/*
	 * I don't know what the below does, but the hardware guys say its
	 * required on everything except PLX (In this case XRJ).
	 */
	if (info_idx != brd_xrj) {
		pci_write_config_byte(pdev, 0x40, 0);
		pci_write_config_byte(pdev, 0x46, 0);
	}

	return 0;

err_out_free_memregion:
	release_mem_region(addr, 0x200000);
err_out_free_iounmap:
	iounmap(boards[board_idx].re_map_port);
err_out_free_pciio:
	release_mem_region(addr + PCI_IO_OFFSET, 0x200000);
err_out:
	return -ENODEV;
}


static struct pci_device_id epca_pci_tbl[] = {
	{ PCI_VENDOR_DIGI, PCI_DEVICE_XR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xr },
	{ PCI_VENDOR_DIGI, PCI_DEVICE_XEM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xem },
	{ PCI_VENDOR_DIGI, PCI_DEVICE_CX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_cx },
	{ PCI_VENDOR_DIGI, PCI_DEVICE_XRJ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xrj },
	{ 0, }
};

MODULE_DEVICE_TABLE(pci, epca_pci_tbl);

static int __init init_PCI(void)
{
	memset(&epca_driver, 0, sizeof(epca_driver));
	epca_driver.name = "epca";
	epca_driver.id_table = epca_pci_tbl;
	epca_driver.probe = epca_init_one;

	return pci_register_driver(&epca_driver);
}

MODULE_LICENSE("GPL");
