/*
	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/serial.h>
#include <linux/delay.h>
#include <linux/ctype.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/slab.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 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");
