/*
 * Copyright 2003 Digi International (www.digi.com)
 *	Scott H Kilau <Scott_Kilau at digi dot com>
 *
 * 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, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 */

#include <linux/kernel.h>
#include <linux/sched.h>	/* For jiffies, task states */
#include <linux/interrupt.h>    /* For tasklet and interrupt structs/defines */
#include <linux/delay.h>	/* For udelay */
#include <linux/io.h>		/* For read[bwl]/write[bwl] */
#include <linux/serial.h>	/* For struct async_serial */
#include <linux/serial_reg.h>	/* For the various UART offsets */

#include "dgnc_driver.h"	/* Driver main header file */
#include "dgnc_neo.h"		/* Our header file */
#include "dgnc_tty.h"

static inline void neo_parse_lsr(struct dgnc_board *brd, uint port);
static inline void neo_parse_isr(struct dgnc_board *brd, uint port);
static void neo_copy_data_from_uart_to_queue(struct channel_t *ch);
static inline void neo_clear_break(struct channel_t *ch, int force);
static inline void neo_set_cts_flow_control(struct channel_t *ch);
static inline void neo_set_rts_flow_control(struct channel_t *ch);
static inline void neo_set_ixon_flow_control(struct channel_t *ch);
static inline void neo_set_ixoff_flow_control(struct channel_t *ch);
static inline void neo_set_no_output_flow_control(struct channel_t *ch);
static inline void neo_set_no_input_flow_control(struct channel_t *ch);
static inline void neo_set_new_start_stop_chars(struct channel_t *ch);
static void neo_parse_modem(struct channel_t *ch, unsigned char signals);
static void neo_tasklet(unsigned long data);
static void neo_vpd(struct dgnc_board *brd);
static void neo_uart_init(struct channel_t *ch);
static void neo_uart_off(struct channel_t *ch);
static int neo_drain(struct tty_struct *tty, uint seconds);
static void neo_param(struct tty_struct *tty);
static void neo_assert_modem_signals(struct channel_t *ch);
static void neo_flush_uart_write(struct channel_t *ch);
static void neo_flush_uart_read(struct channel_t *ch);
static void neo_disable_receiver(struct channel_t *ch);
static void neo_enable_receiver(struct channel_t *ch);
static void neo_send_break(struct channel_t *ch, int msecs);
static void neo_send_start_character(struct channel_t *ch);
static void neo_send_stop_character(struct channel_t *ch);
static void neo_copy_data_from_queue_to_uart(struct channel_t *ch);
static uint neo_get_uart_bytes_left(struct channel_t *ch);
static void neo_send_immediate_char(struct channel_t *ch, unsigned char c);
static irqreturn_t neo_intr(int irq, void *voidbrd);

struct board_ops dgnc_neo_ops = {
	.tasklet =			neo_tasklet,
	.intr =				neo_intr,
	.uart_init =			neo_uart_init,
	.uart_off =			neo_uart_off,
	.drain =			neo_drain,
	.param =			neo_param,
	.vpd =				neo_vpd,
	.assert_modem_signals =		neo_assert_modem_signals,
	.flush_uart_write =		neo_flush_uart_write,
	.flush_uart_read =		neo_flush_uart_read,
	.disable_receiver =		neo_disable_receiver,
	.enable_receiver =		neo_enable_receiver,
	.send_break =			neo_send_break,
	.send_start_character =		neo_send_start_character,
	.send_stop_character =		neo_send_stop_character,
	.copy_data_from_queue_to_uart =	neo_copy_data_from_queue_to_uart,
	.get_uart_bytes_left =		neo_get_uart_bytes_left,
	.send_immediate_char =		neo_send_immediate_char
};

static uint dgnc_offset_table[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };

/*
 * This function allows calls to ensure that all outstanding
 * PCI writes have been completed, by doing a PCI read against
 * a non-destructive, read-only location on the Neo card.
 *
 * In this case, we are reading the DVID (Read-only Device Identification)
 * value of the Neo card.
 */
static inline void neo_pci_posting_flush(struct dgnc_board *bd)
{
	readb(bd->re_map_membase + 0x8D);
}

static inline void neo_set_cts_flow_control(struct channel_t *ch)
{
	unsigned char ier = readb(&ch->ch_neo_uart->ier);
	unsigned char efr = readb(&ch->ch_neo_uart->efr);

	/* Turn on auto CTS flow control */
#if 1
	ier |= UART_17158_IER_CTSDSR;
#else
	ier &= ~(UART_17158_IER_CTSDSR);
#endif

	efr |= (UART_17158_EFR_ECB | UART_17158_EFR_CTSDSR);

	/* Turn off auto Xon flow control */
	efr &= ~UART_17158_EFR_IXON;

	/* Why? Becuz Exar's spec says we have to zero it out before setting it */
	writeb(0, &ch->ch_neo_uart->efr);

	/* Turn on UART enhanced bits */
	writeb(efr, &ch->ch_neo_uart->efr);

	/* Turn on table D, with 8 char hi/low watermarks */
	writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_4DELAY), &ch->ch_neo_uart->fctr);

	/* Feed the UART our trigger levels */
	writeb(8, &ch->ch_neo_uart->tfifo);
	ch->ch_t_tlevel = 8;

	writeb(ier, &ch->ch_neo_uart->ier);

	neo_pci_posting_flush(ch->ch_bd);
}

static inline void neo_set_rts_flow_control(struct channel_t *ch)
{
	unsigned char ier = readb(&ch->ch_neo_uart->ier);
	unsigned char efr = readb(&ch->ch_neo_uart->efr);

	/* Turn on auto RTS flow control */
#if 1
	ier |= UART_17158_IER_RTSDTR;
#else
	ier &= ~(UART_17158_IER_RTSDTR);
#endif
	efr |= (UART_17158_EFR_ECB | UART_17158_EFR_RTSDTR);

	/* Turn off auto Xoff flow control */
	ier &= ~UART_17158_IER_XOFF;
	efr &= ~UART_17158_EFR_IXOFF;

	/* Why? Becuz Exar's spec says we have to zero it out before setting it */
	writeb(0, &ch->ch_neo_uart->efr);

	/* Turn on UART enhanced bits */
	writeb(efr, &ch->ch_neo_uart->efr);

	writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_4DELAY), &ch->ch_neo_uart->fctr);
	ch->ch_r_watermark = 4;

	writeb(32, &ch->ch_neo_uart->rfifo);
	ch->ch_r_tlevel = 32;

	writeb(ier, &ch->ch_neo_uart->ier);

	/*
	 * From the Neo UART spec sheet:
	 * The auto RTS/DTR function must be started by asserting
	 * RTS/DTR# output pin (MCR bit-0 or 1 to logic 1 after
	 * it is enabled.
	 */
	ch->ch_mostat |= UART_MCR_RTS;

	neo_pci_posting_flush(ch->ch_bd);
}

static inline void neo_set_ixon_flow_control(struct channel_t *ch)
{
	unsigned char ier = readb(&ch->ch_neo_uart->ier);
	unsigned char efr = readb(&ch->ch_neo_uart->efr);

	/* Turn off auto CTS flow control */
	ier &= ~UART_17158_IER_CTSDSR;
	efr &= ~UART_17158_EFR_CTSDSR;

	/* Turn on auto Xon flow control */
	efr |= (UART_17158_EFR_ECB | UART_17158_EFR_IXON);

	/* Why? Becuz Exar's spec says we have to zero it out before setting it */
	writeb(0, &ch->ch_neo_uart->efr);

	/* Turn on UART enhanced bits */
	writeb(efr, &ch->ch_neo_uart->efr);

	writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), &ch->ch_neo_uart->fctr);
	ch->ch_r_watermark = 4;

	writeb(32, &ch->ch_neo_uart->rfifo);
	ch->ch_r_tlevel = 32;

	/* Tell UART what start/stop chars it should be looking for */
	writeb(ch->ch_startc, &ch->ch_neo_uart->xonchar1);
	writeb(0, &ch->ch_neo_uart->xonchar2);

	writeb(ch->ch_stopc, &ch->ch_neo_uart->xoffchar1);
	writeb(0, &ch->ch_neo_uart->xoffchar2);

	writeb(ier, &ch->ch_neo_uart->ier);

	neo_pci_posting_flush(ch->ch_bd);
}

static inline void neo_set_ixoff_flow_control(struct channel_t *ch)
{
	unsigned char ier = readb(&ch->ch_neo_uart->ier);
	unsigned char efr = readb(&ch->ch_neo_uart->efr);

	/* Turn off auto RTS flow control */
	ier &= ~UART_17158_IER_RTSDTR;
	efr &= ~UART_17158_EFR_RTSDTR;

	/* Turn on auto Xoff flow control */
	ier |= UART_17158_IER_XOFF;
	efr |= (UART_17158_EFR_ECB | UART_17158_EFR_IXOFF);

	/* Why? Becuz Exar's spec says we have to zero it out before setting it */
	writeb(0, &ch->ch_neo_uart->efr);

	/* Turn on UART enhanced bits */
	writeb(efr, &ch->ch_neo_uart->efr);

	/* Turn on table D, with 8 char hi/low watermarks */
	writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), &ch->ch_neo_uart->fctr);

	writeb(8, &ch->ch_neo_uart->tfifo);
	ch->ch_t_tlevel = 8;

	/* Tell UART what start/stop chars it should be looking for */
	writeb(ch->ch_startc, &ch->ch_neo_uart->xonchar1);
	writeb(0, &ch->ch_neo_uart->xonchar2);

	writeb(ch->ch_stopc, &ch->ch_neo_uart->xoffchar1);
	writeb(0, &ch->ch_neo_uart->xoffchar2);

	writeb(ier, &ch->ch_neo_uart->ier);

	neo_pci_posting_flush(ch->ch_bd);
}

static inline void neo_set_no_input_flow_control(struct channel_t *ch)
{
	unsigned char ier = readb(&ch->ch_neo_uart->ier);
	unsigned char efr = readb(&ch->ch_neo_uart->efr);

	/* Turn off auto RTS flow control */
	ier &= ~UART_17158_IER_RTSDTR;
	efr &= ~UART_17158_EFR_RTSDTR;

	/* Turn off auto Xoff flow control */
	ier &= ~UART_17158_IER_XOFF;
	if (ch->ch_c_iflag & IXON)
		efr &= ~(UART_17158_EFR_IXOFF);
	else
		efr &= ~(UART_17158_EFR_ECB | UART_17158_EFR_IXOFF);

	/* Why? Becuz Exar's spec says we have to zero it out before setting it */
	writeb(0, &ch->ch_neo_uart->efr);

	/* Turn on UART enhanced bits */
	writeb(efr, &ch->ch_neo_uart->efr);

	/* Turn on table D, with 8 char hi/low watermarks */
	writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), &ch->ch_neo_uart->fctr);

	ch->ch_r_watermark = 0;

	writeb(16, &ch->ch_neo_uart->tfifo);
	ch->ch_t_tlevel = 16;

	writeb(16, &ch->ch_neo_uart->rfifo);
	ch->ch_r_tlevel = 16;

	writeb(ier, &ch->ch_neo_uart->ier);

	neo_pci_posting_flush(ch->ch_bd);
}

static inline void neo_set_no_output_flow_control(struct channel_t *ch)
{
	unsigned char ier = readb(&ch->ch_neo_uart->ier);
	unsigned char efr = readb(&ch->ch_neo_uart->efr);

	/* Turn off auto CTS flow control */
	ier &= ~UART_17158_IER_CTSDSR;
	efr &= ~UART_17158_EFR_CTSDSR;

	/* Turn off auto Xon flow control */
	if (ch->ch_c_iflag & IXOFF)
		efr &= ~UART_17158_EFR_IXON;
	else
		efr &= ~(UART_17158_EFR_ECB | UART_17158_EFR_IXON);

	/* Why? Becuz Exar's spec says we have to zero it out before setting it */
	writeb(0, &ch->ch_neo_uart->efr);

	/* Turn on UART enhanced bits */
	writeb(efr, &ch->ch_neo_uart->efr);

	/* Turn on table D, with 8 char hi/low watermarks */
	writeb((UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY), &ch->ch_neo_uart->fctr);

	ch->ch_r_watermark = 0;

	writeb(16, &ch->ch_neo_uart->tfifo);
	ch->ch_t_tlevel = 16;

	writeb(16, &ch->ch_neo_uart->rfifo);
	ch->ch_r_tlevel = 16;

	writeb(ier, &ch->ch_neo_uart->ier);

	neo_pci_posting_flush(ch->ch_bd);
}

/* change UARTs start/stop chars */
static inline void neo_set_new_start_stop_chars(struct channel_t *ch)
{
	/* if hardware flow control is set, then skip this whole thing */
	if (ch->ch_digi.digi_flags & (CTSPACE | RTSPACE) || ch->ch_c_cflag & CRTSCTS)
		return;

	/* Tell UART what start/stop chars it should be looking for */
	writeb(ch->ch_startc, &ch->ch_neo_uart->xonchar1);
	writeb(0, &ch->ch_neo_uart->xonchar2);

	writeb(ch->ch_stopc, &ch->ch_neo_uart->xoffchar1);
	writeb(0, &ch->ch_neo_uart->xoffchar2);

	neo_pci_posting_flush(ch->ch_bd);
}

/*
 * No locks are assumed to be held when calling this function.
 */
static inline void neo_clear_break(struct channel_t *ch, int force)
{
	unsigned long flags;

	spin_lock_irqsave(&ch->ch_lock, flags);

	/* Bail if we aren't currently sending a break. */
	if (!ch->ch_stop_sending_break) {
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		return;
	}

	/* Turn break off, and unset some variables */
	if (ch->ch_flags & CH_BREAK_SENDING) {
		if (time_after_eq(jiffies, ch->ch_stop_sending_break)
		    || force) {
			unsigned char temp = readb(&ch->ch_neo_uart->lcr);

			writeb((temp & ~UART_LCR_SBC), &ch->ch_neo_uart->lcr);
			neo_pci_posting_flush(ch->ch_bd);
			ch->ch_flags &= ~(CH_BREAK_SENDING);
			ch->ch_stop_sending_break = 0;
		}
	}
	spin_unlock_irqrestore(&ch->ch_lock, flags);
}

/*
 * Parse the ISR register.
 */
static inline void neo_parse_isr(struct dgnc_board *brd, uint port)
{
	struct channel_t *ch;
	unsigned char isr;
	unsigned char cause;
	unsigned long flags;

	if (!brd || brd->magic != DGNC_BOARD_MAGIC)
		return;

	if (port >= brd->maxports)
		return;

	ch = brd->channels[port];
	if (ch->magic != DGNC_CHANNEL_MAGIC)
		return;

	/* Here we try to figure out what caused the interrupt to happen */
	while (1) {
		isr = readb(&ch->ch_neo_uart->isr_fcr);

		/* Bail if no pending interrupt */
		if (isr & UART_IIR_NO_INT)
			break;

		/*
		 * Yank off the upper 2 bits, which just show that the FIFO's are enabled.
		 */
		isr &= ~(UART_17158_IIR_FIFO_ENABLED);

		if (isr & (UART_17158_IIR_RDI_TIMEOUT | UART_IIR_RDI)) {
			/* Read data from uart -> queue */
			brd->intr_rx++;
			ch->ch_intr_rx++;
			neo_copy_data_from_uart_to_queue(ch);

			/* Call our tty layer to enforce queue flow control if needed. */
			spin_lock_irqsave(&ch->ch_lock, flags);
			dgnc_check_queue_flow_control(ch);
			spin_unlock_irqrestore(&ch->ch_lock, flags);
		}

		if (isr & UART_IIR_THRI) {
			brd->intr_tx++;
			ch->ch_intr_tx++;
			/* Transfer data (if any) from Write Queue -> UART. */
			spin_lock_irqsave(&ch->ch_lock, flags);
			ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
			spin_unlock_irqrestore(&ch->ch_lock, flags);
			neo_copy_data_from_queue_to_uart(ch);
		}

		if (isr & UART_17158_IIR_XONXOFF) {
			cause = readb(&ch->ch_neo_uart->xoffchar1);

			/*
			 * Since the UART detected either an XON or
			 * XOFF match, we need to figure out which
			 * one it was, so we can suspend or resume data flow.
			 */
			if (cause == UART_17158_XON_DETECT) {
				/* Is output stopped right now, if so, resume it */
				if (brd->channels[port]->ch_flags & CH_STOP) {
					spin_lock_irqsave(&ch->ch_lock,
							  flags);
					ch->ch_flags &= ~(CH_STOP);
					spin_unlock_irqrestore(&ch->ch_lock,
							       flags);
				}
			} else if (cause == UART_17158_XOFF_DETECT) {
				if (!(brd->channels[port]->ch_flags & CH_STOP)) {
					spin_lock_irqsave(&ch->ch_lock,
							  flags);
					ch->ch_flags |= CH_STOP;
					spin_unlock_irqrestore(&ch->ch_lock,
							       flags);
				}
			}
		}

		if (isr & UART_17158_IIR_HWFLOW_STATE_CHANGE) {
			/*
			 * If we get here, this means the hardware is doing auto flow control.
			 * Check to see whether RTS/DTR or CTS/DSR caused this interrupt.
			 */
			brd->intr_modem++;
			ch->ch_intr_modem++;
			cause = readb(&ch->ch_neo_uart->mcr);
			/* Which pin is doing auto flow? RTS or DTR? */
			if ((cause & 0x4) == 0) {
				if (cause & UART_MCR_RTS) {
					spin_lock_irqsave(&ch->ch_lock,
							  flags);
					ch->ch_mostat |= UART_MCR_RTS;
					spin_unlock_irqrestore(&ch->ch_lock,
							       flags);
				} else {
					spin_lock_irqsave(&ch->ch_lock,
							  flags);
					ch->ch_mostat &= ~(UART_MCR_RTS);
					spin_unlock_irqrestore(&ch->ch_lock,
							       flags);
				}
			} else {
				if (cause & UART_MCR_DTR) {
					spin_lock_irqsave(&ch->ch_lock,
							  flags);
					ch->ch_mostat |= UART_MCR_DTR;
					spin_unlock_irqrestore(&ch->ch_lock,
							       flags);
				} else {
					spin_lock_irqsave(&ch->ch_lock,
							  flags);
					ch->ch_mostat &= ~(UART_MCR_DTR);
					spin_unlock_irqrestore(&ch->ch_lock,
							       flags);
				}
			}
		}

		/* Parse any modem signal changes */
		neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr));
	}
}

static inline void neo_parse_lsr(struct dgnc_board *brd, uint port)
{
	struct channel_t *ch;
	int linestatus;
	unsigned long flags;

	/*
	 * Check to make sure it didn't receive interrupt with a null board
	 * associated or a board pointer that wasn't ours.
	 */
	if (!brd || brd->magic != DGNC_BOARD_MAGIC)
		return;

	if (port >= brd->maxports)
		return;

	ch = brd->channels[port];
	if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
		return;

	linestatus = readb(&ch->ch_neo_uart->lsr);

	ch->ch_cached_lsr |= linestatus;

	if (ch->ch_cached_lsr & UART_LSR_DR) {
		brd->intr_rx++;
		ch->ch_intr_rx++;
		/* Read data from uart -> queue */
		neo_copy_data_from_uart_to_queue(ch);
		spin_lock_irqsave(&ch->ch_lock, flags);
		dgnc_check_queue_flow_control(ch);
		spin_unlock_irqrestore(&ch->ch_lock, flags);
	}

	/*
	 * The next 3 tests should *NOT* happen, as the above test
	 * should encapsulate all 3... At least, thats what Exar says.
	 */

	if (linestatus & UART_LSR_PE)
		ch->ch_err_parity++;

	if (linestatus & UART_LSR_FE)
		ch->ch_err_frame++;

	if (linestatus & UART_LSR_BI)
		ch->ch_err_break++;

	if (linestatus & UART_LSR_OE) {
		/*
		 * Rx Oruns. Exar says that an orun will NOT corrupt
		 * the FIFO. It will just replace the holding register
		 * with this new data byte. So basically just ignore this.
		 * Probably we should eventually have an orun stat in our driver...
		 */
		ch->ch_err_overrun++;
	}

	if (linestatus & UART_LSR_THRE) {
		brd->intr_tx++;
		ch->ch_intr_tx++;
		spin_lock_irqsave(&ch->ch_lock, flags);
		ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
		spin_unlock_irqrestore(&ch->ch_lock, flags);

		/* Transfer data (if any) from Write Queue -> UART. */
		neo_copy_data_from_queue_to_uart(ch);
	} else if (linestatus & UART_17158_TX_AND_FIFO_CLR) {
		brd->intr_tx++;
		ch->ch_intr_tx++;
		spin_lock_irqsave(&ch->ch_lock, flags);
		ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
		spin_unlock_irqrestore(&ch->ch_lock, flags);

		/* Transfer data (if any) from Write Queue -> UART. */
		neo_copy_data_from_queue_to_uart(ch);
	}
}

/*
 * neo_param()
 * Send any/all changes to the line to the UART.
 */
static void neo_param(struct tty_struct *tty)
{
	unsigned char lcr = 0;
	unsigned char uart_lcr = 0;
	unsigned char ier = 0;
	unsigned char uart_ier = 0;
	uint baud = 9600;
	int quot = 0;
	struct dgnc_board *bd;
	struct channel_t *ch;
	struct un_t   *un;

	if (!tty || tty->magic != TTY_MAGIC)
		return;

	un = (struct un_t *)tty->driver_data;
	if (!un || un->magic != DGNC_UNIT_MAGIC)
		return;

	ch = un->un_ch;
	if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
		return;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGNC_BOARD_MAGIC)
		return;

	/*
	 * If baud rate is zero, flush queues, and set mval to drop DTR.
	 */
	if ((ch->ch_c_cflag & (CBAUD)) == 0) {
		ch->ch_r_head = 0;
		ch->ch_r_tail = 0;
		ch->ch_e_head = 0;
		ch->ch_e_tail = 0;
		ch->ch_w_head = 0;
		ch->ch_w_tail = 0;

		neo_flush_uart_write(ch);
		neo_flush_uart_read(ch);

		/* The baudrate is B0 so all modem lines are to be dropped. */
		ch->ch_flags |= (CH_BAUD0);
		ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR);
		neo_assert_modem_signals(ch);
		ch->ch_old_baud = 0;
		return;

	} else if (ch->ch_custom_speed) {
		baud = ch->ch_custom_speed;
		/* Handle transition from B0 */
		if (ch->ch_flags & CH_BAUD0) {
			ch->ch_flags &= ~(CH_BAUD0);

			/*
			 * Bring back up RTS and DTR...
			 * Also handle RTS or DTR toggle if set.
			 */
			if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE))
				ch->ch_mostat |= (UART_MCR_RTS);
			if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE))
				ch->ch_mostat |= (UART_MCR_DTR);
		}
	} else {
		int iindex = 0;
		int jindex = 0;

		ulong bauds[4][16] = {
			{ /* slowbaud */
				0,      50,     75,     110,
				134,    150,    200,    300,
				600,    1200,   1800,   2400,
				4800,   9600,   19200,  38400 },
			{ /* slowbaud & CBAUDEX */
				0,      57600,  115200, 230400,
				460800, 150,    200,    921600,
				600,    1200,   1800,   2400,
				4800,   9600,   19200,  38400 },
			{ /* fastbaud */
				0,      57600,   76800, 115200,
				131657, 153600, 230400, 460800,
				921600, 1200,   1800,   2400,
				4800,   9600,   19200,  38400 },
			{ /* fastbaud & CBAUDEX */
				0,      57600,  115200, 230400,
				460800, 150,    200,    921600,
				600,    1200,   1800,   2400,
				4800,   9600,   19200,  38400 }
		};

		/* Only use the TXPrint baud rate if the terminal unit is NOT open */
		if (!(ch->ch_tun.un_flags & UN_ISOPEN) && (un->un_type == DGNC_PRINT))
			baud = C_BAUD(ch->ch_pun.un_tty) & 0xff;
		else
			baud = C_BAUD(ch->ch_tun.un_tty) & 0xff;

		if (ch->ch_c_cflag & CBAUDEX)
			iindex = 1;

		if (ch->ch_digi.digi_flags & DIGI_FAST)
			iindex += 2;

		jindex = baud;

		if ((iindex >= 0) && (iindex < 4) && (jindex >= 0) && (jindex < 16))
			baud = bauds[iindex][jindex];
		else
			baud = 0;

		if (baud == 0)
			baud = 9600;

		/* Handle transition from B0 */
		if (ch->ch_flags & CH_BAUD0) {
			ch->ch_flags &= ~(CH_BAUD0);

			/*
			 * Bring back up RTS and DTR...
			 * Also handle RTS or DTR toggle if set.
			 */
			if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE))
				ch->ch_mostat |= (UART_MCR_RTS);
			if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE))
				ch->ch_mostat |= (UART_MCR_DTR);
		}
	}

	if (ch->ch_c_cflag & PARENB)
		lcr |= UART_LCR_PARITY;

	if (!(ch->ch_c_cflag & PARODD))
		lcr |= UART_LCR_EPAR;

	/*
	 * Not all platforms support mark/space parity,
	 * so this will hide behind an ifdef.
	 */
#ifdef CMSPAR
	if (ch->ch_c_cflag & CMSPAR)
		lcr |= UART_LCR_SPAR;
#endif

	if (ch->ch_c_cflag & CSTOPB)
		lcr |= UART_LCR_STOP;

	switch (ch->ch_c_cflag & CSIZE) {
	case CS5:
		lcr |= UART_LCR_WLEN5;
		break;
	case CS6:
		lcr |= UART_LCR_WLEN6;
		break;
	case CS7:
		lcr |= UART_LCR_WLEN7;
		break;
	case CS8:
	default:
		lcr |= UART_LCR_WLEN8;
		break;
	}

	uart_ier = readb(&ch->ch_neo_uart->ier);
	ier = uart_ier;

	uart_lcr = readb(&ch->ch_neo_uart->lcr);

	if (baud == 0)
		baud = 9600;

	quot = ch->ch_bd->bd_dividend / baud;

	if (quot != 0 && ch->ch_old_baud != baud) {
		ch->ch_old_baud = baud;
		writeb(UART_LCR_DLAB, &ch->ch_neo_uart->lcr);
		writeb((quot & 0xff), &ch->ch_neo_uart->txrx);
		writeb((quot >> 8), &ch->ch_neo_uart->ier);
		writeb(lcr, &ch->ch_neo_uart->lcr);
	}

	if (uart_lcr != lcr)
		writeb(lcr, &ch->ch_neo_uart->lcr);

	if (ch->ch_c_cflag & CREAD)
		ier |= (UART_IER_RDI | UART_IER_RLSI);
	else
		ier &= ~(UART_IER_RDI | UART_IER_RLSI);

	/*
	 * Have the UART interrupt on modem signal changes ONLY when
	 * we are in hardware flow control mode, or CLOCAL/FORCEDCD is not set.
	 */
	if ((ch->ch_digi.digi_flags & CTSPACE) ||
	    (ch->ch_digi.digi_flags & RTSPACE) ||
	    (ch->ch_c_cflag & CRTSCTS) ||
	    !(ch->ch_digi.digi_flags & DIGI_FORCEDCD) ||
	    !(ch->ch_c_cflag & CLOCAL))
		ier |= UART_IER_MSI;
	else
		ier &= ~UART_IER_MSI;

	ier |= UART_IER_THRI;

	if (ier != uart_ier)
		writeb(ier, &ch->ch_neo_uart->ier);

	/* Set new start/stop chars */
	neo_set_new_start_stop_chars(ch);

	if (ch->ch_digi.digi_flags & CTSPACE || ch->ch_c_cflag & CRTSCTS) {
		neo_set_cts_flow_control(ch);
	} else if (ch->ch_c_iflag & IXON) {
		/* If start/stop is set to disable, then we should disable flow control */
		if ((ch->ch_startc == _POSIX_VDISABLE) || (ch->ch_stopc == _POSIX_VDISABLE))
			neo_set_no_output_flow_control(ch);
		else
			neo_set_ixon_flow_control(ch);
	} else {
		neo_set_no_output_flow_control(ch);
	}

	if (ch->ch_digi.digi_flags & RTSPACE || ch->ch_c_cflag & CRTSCTS) {
		neo_set_rts_flow_control(ch);
	} else if (ch->ch_c_iflag & IXOFF) {
		/* If start/stop is set to disable, then we should disable flow control */
		if ((ch->ch_startc == _POSIX_VDISABLE) || (ch->ch_stopc == _POSIX_VDISABLE))
			neo_set_no_input_flow_control(ch);
		else
			neo_set_ixoff_flow_control(ch);
	} else {
		neo_set_no_input_flow_control(ch);
	}

	/*
	 * Adjust the RX FIFO Trigger level if baud is less than 9600.
	 * Not exactly elegant, but this is needed because of the Exar chip's
	 * delay on firing off the RX FIFO interrupt on slower baud rates.
	 */
	if (baud < 9600) {
		writeb(1, &ch->ch_neo_uart->rfifo);
		ch->ch_r_tlevel = 1;
	}

	neo_assert_modem_signals(ch);

	/* Get current status of the modem signals now */
	neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr));
}

/*
 * Our board poller function.
 */
static void neo_tasklet(unsigned long data)
{
	struct dgnc_board *bd = (struct dgnc_board *)data;
	struct channel_t *ch;
	unsigned long flags;
	int i;
	int state = 0;
	int ports = 0;

	if (!bd || bd->magic != DGNC_BOARD_MAGIC)
		return;

	/* Cache a couple board values */
	spin_lock_irqsave(&bd->bd_lock, flags);
	state = bd->state;
	ports = bd->nasync;
	spin_unlock_irqrestore(&bd->bd_lock, flags);

	/*
	 * Do NOT allow the interrupt routine to read the intr registers
	 * Until we release this lock.
	 */
	spin_lock_irqsave(&bd->bd_intr_lock, flags);

	/*
	 * If board is ready, parse deeper to see if there is anything to do.
	 */
	if ((state == BOARD_READY) && (ports > 0)) {
		/* Loop on each port */
		for (i = 0; i < ports; i++) {
			ch = bd->channels[i];

			/* Just being careful... */
			if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
				continue;

			/*
			 * NOTE: Remember you CANNOT hold any channel
			 * locks when calling the input routine.
			 *
			 * During input processing, its possible we
			 * will call the Linux ld, which might in turn,
			 * do a callback right back into us, resulting
			 * in us trying to grab the channel lock twice!
			 */
			dgnc_input(ch);

			/*
			 * Channel lock is grabbed and then released
			 * inside both of these routines, but neither
			 * call anything else that could call back into us.
			 */
			neo_copy_data_from_queue_to_uart(ch);
			dgnc_wakeup_writes(ch);

			/*
			 * Call carrier carrier function, in case something
			 * has changed.
			 */
			dgnc_carrier(ch);

			/*
			 * Check to see if we need to turn off a sending break.
			 * The timing check is done inside clear_break()
			 */
			if (ch->ch_stop_sending_break)
				neo_clear_break(ch, 0);
		}
	}

	/* Allow interrupt routine to access the interrupt register again */
	spin_unlock_irqrestore(&bd->bd_intr_lock, flags);
}

/*
 * dgnc_neo_intr()
 *
 * Neo specific interrupt handler.
 */
static irqreturn_t neo_intr(int irq, void *voidbrd)
{
	struct dgnc_board *brd = voidbrd;
	struct channel_t *ch;
	int port = 0;
	int type = 0;
	int current_port;
	u32 tmp;
	u32 uart_poll;
	unsigned long flags;
	unsigned long flags2;

	/*
	 * Check to make sure it didn't receive interrupt with a null board
	 * associated or a board pointer that wasn't ours.
	 */
	if (!brd || brd->magic != DGNC_BOARD_MAGIC)
		return IRQ_NONE;

	brd->intr_count++;

	/* Lock out the slow poller from running on this board. */
	spin_lock_irqsave(&brd->bd_intr_lock, flags);

	/*
	 * Read in "extended" IRQ information from the 32bit Neo register.
	 * Bits 0-7: What port triggered the interrupt.
	 * Bits 8-31: Each 3bits indicate what type of interrupt occurred.
	 */
	uart_poll = readl(brd->re_map_membase + UART_17158_POLL_ADDR_OFFSET);

	/*
	 * If 0, no interrupts pending.
	 * This can happen if the IRQ is shared among a couple Neo/Classic boards.
	 */
	if (!uart_poll) {
		spin_unlock_irqrestore(&brd->bd_intr_lock, flags);
		return IRQ_NONE;
	}

	/* At this point, we have at least SOMETHING to service, dig further... */

	current_port = 0;

	/* Loop on each port */
	while ((uart_poll & 0xff) != 0) {
		tmp = uart_poll;

		/* Check current port to see if it has interrupt pending */
		if ((tmp & dgnc_offset_table[current_port]) != 0) {
			port = current_port;
			type = tmp >> (8 + (port * 3));
			type &= 0x7;
		} else {
			current_port++;
			continue;
		}

		/* Remove this port + type from uart_poll */
		uart_poll &= ~(dgnc_offset_table[port]);

		if (!type) {
			/* If no type, just ignore it, and move onto next port */
			continue;
		}

		/* Switch on type of interrupt we have */
		switch (type) {
		case UART_17158_RXRDY_TIMEOUT:
			/*
			 * RXRDY Time-out is cleared by reading data in the
			 * RX FIFO until it falls below the trigger level.
			 */

			/* Verify the port is in range. */
			if (port >= brd->nasync)
				continue;

			ch = brd->channels[port];
			neo_copy_data_from_uart_to_queue(ch);

			/* Call our tty layer to enforce queue flow control if needed. */
			spin_lock_irqsave(&ch->ch_lock, flags2);
			dgnc_check_queue_flow_control(ch);
			spin_unlock_irqrestore(&ch->ch_lock, flags2);

			continue;

		case UART_17158_RX_LINE_STATUS:
			/*
			 * RXRDY and RX LINE Status (logic OR of LSR[4:1])
			 */
			neo_parse_lsr(brd, port);
			continue;

		case UART_17158_TXRDY:
			/*
			 * TXRDY interrupt clears after reading ISR register for the UART channel.
			 */

			/*
			 * Yes, this is odd...
			 * Why would I check EVERY possibility of type of
			 * interrupt, when we know its TXRDY???
			 * Becuz for some reason, even tho we got triggered for TXRDY,
			 * it seems to be occasionally wrong. Instead of TX, which
			 * it should be, I was getting things like RXDY too. Weird.
			 */
			neo_parse_isr(brd, port);
			continue;

		case UART_17158_MSR:
			/*
			 * MSR or flow control was seen.
			 */
			neo_parse_isr(brd, port);
			continue;

		default:
			/*
			 * The UART triggered us with a bogus interrupt type.
			 * It appears the Exar chip, when REALLY bogged down, will throw
			 * these once and awhile.
			 * Its harmless, just ignore it and move on.
			 */
			continue;
		}
	}

	/*
	 * Schedule tasklet to more in-depth servicing at a better time.
	 */
	tasklet_schedule(&brd->helper_tasklet);

	spin_unlock_irqrestore(&brd->bd_intr_lock, flags);

	return IRQ_HANDLED;
}

/*
 * Neo specific way of turning off the receiver.
 * Used as a way to enforce queue flow control when in
 * hardware flow control mode.
 */
static void neo_disable_receiver(struct channel_t *ch)
{
	unsigned char tmp = readb(&ch->ch_neo_uart->ier);

	tmp &= ~(UART_IER_RDI);
	writeb(tmp, &ch->ch_neo_uart->ier);
	neo_pci_posting_flush(ch->ch_bd);
}

/*
 * Neo specific way of turning on the receiver.
 * Used as a way to un-enforce queue flow control when in
 * hardware flow control mode.
 */
static void neo_enable_receiver(struct channel_t *ch)
{
	unsigned char tmp = readb(&ch->ch_neo_uart->ier);

	tmp |= (UART_IER_RDI);
	writeb(tmp, &ch->ch_neo_uart->ier);
	neo_pci_posting_flush(ch->ch_bd);
}

static void neo_copy_data_from_uart_to_queue(struct channel_t *ch)
{
	int qleft = 0;
	unsigned char linestatus = 0;
	unsigned char error_mask = 0;
	int n = 0;
	int total = 0;
	ushort head;
	ushort tail;
	unsigned long flags;

	if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
		return;

	spin_lock_irqsave(&ch->ch_lock, flags);

	/* cache head and tail of queue */
	head = ch->ch_r_head & RQUEUEMASK;
	tail = ch->ch_r_tail & RQUEUEMASK;

	/* Get our cached LSR */
	linestatus = ch->ch_cached_lsr;
	ch->ch_cached_lsr = 0;

	/* Store how much space we have left in the queue */
	qleft = tail - head - 1;
	if (qleft < 0)
		qleft += RQUEUEMASK + 1;

	/*
	 * If the UART is not in FIFO mode, force the FIFO copy to
	 * NOT be run, by setting total to 0.
	 *
	 * On the other hand, if the UART IS in FIFO mode, then ask
	 * the UART to give us an approximation of data it has RX'ed.
	 */
	if (!(ch->ch_flags & CH_FIFO_ENABLED)) {
		total = 0;
	} else {
		total = readb(&ch->ch_neo_uart->rfifo);

		/*
		 * EXAR chip bug - RX FIFO COUNT - Fudge factor.
		 *
		 * This resolves a problem/bug with the Exar chip that sometimes
		 * returns a bogus value in the rfifo register.
		 * The count can be any where from 0-3 bytes "off".
		 * Bizarre, but true.
		 */
		if ((ch->ch_bd->dvid & 0xf0) >= UART_XR17E158_DVID)
			total -= 1;
		else
			total -= 3;
	}

	/*
	 * Finally, bound the copy to make sure we don't overflow
	 * our own queue...
	 * The byte by byte copy loop below this loop this will
	 * deal with the queue overflow possibility.
	 */
	total = min(total, qleft);

	while (total > 0) {
		/*
		 * Grab the linestatus register, we need to check
		 * to see if there are any errors in the FIFO.
		 */
		linestatus = readb(&ch->ch_neo_uart->lsr);

		/*
		 * Break out if there is a FIFO error somewhere.
		 * This will allow us to go byte by byte down below,
		 * finding the exact location of the error.
		 */
		if (linestatus & UART_17158_RX_FIFO_DATA_ERROR)
			break;

		/* Make sure we don't go over the end of our queue */
		n = min(((uint)total), (RQUEUESIZE - (uint)head));

		/*
		 * Cut down n even further if needed, this is to fix
		 * a problem with memcpy_fromio() with the Neo on the
		 * IBM pSeries platform.
		 * 15 bytes max appears to be the magic number.
		 */
		n = min_t(uint, n, 12);

		/*
		 * Since we are grabbing the linestatus register, which
		 * will reset some bits after our read, we need to ensure
		 * we don't miss our TX FIFO emptys.
		 */
		if (linestatus & (UART_LSR_THRE | UART_17158_TX_AND_FIFO_CLR))
			ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);

		linestatus = 0;

		/* Copy data from uart to the queue */
		memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, n);

		/*
		 * Since RX_FIFO_DATA_ERROR was 0, we are guaranteed
		 * that all the data currently in the FIFO is free of
		 * breaks and parity/frame/orun errors.
		 */
		memset(ch->ch_equeue + head, 0, n);

		/* Add to and flip head if needed */
		head = (head + n) & RQUEUEMASK;
		total -= n;
		qleft -= n;
		ch->ch_rxcount += n;
	}

	/*
	 * Create a mask to determine whether we should
	 * insert the character (if any) into our queue.
	 */
	if (ch->ch_c_iflag & IGNBRK)
		error_mask |= UART_LSR_BI;

	/*
	 * Now cleanup any leftover bytes still in the UART.
	 * Also deal with any possible queue overflow here as well.
	 */
	while (1) {
		/*
		 * Its possible we have a linestatus from the loop above
		 * this, so we "OR" on any extra bits.
		 */
		linestatus |= readb(&ch->ch_neo_uart->lsr);

		/*
		 * If the chip tells us there is no more data pending to
		 * be read, we can then leave.
		 * But before we do, cache the linestatus, just in case.
		 */
		if (!(linestatus & UART_LSR_DR)) {
			ch->ch_cached_lsr = linestatus;
			break;
		}

		/* No need to store this bit */
		linestatus &= ~UART_LSR_DR;

		/*
		 * Since we are grabbing the linestatus register, which
		 * will reset some bits after our read, we need to ensure
		 * we don't miss our TX FIFO emptys.
		 */
		if (linestatus & (UART_LSR_THRE | UART_17158_TX_AND_FIFO_CLR)) {
			linestatus &= ~(UART_LSR_THRE | UART_17158_TX_AND_FIFO_CLR);
			ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
		}

		/*
		 * Discard character if we are ignoring the error mask.
		 */
		if (linestatus & error_mask)  {
			unsigned char discard;

			linestatus = 0;
			memcpy_fromio(&discard, &ch->ch_neo_uart->txrxburst, 1);
			continue;
		}

		/*
		 * If our queue is full, we have no choice but to drop some data.
		 * The assumption is that HWFLOW or SWFLOW should have stopped
		 * things way way before we got to this point.
		 *
		 * I decided that I wanted to ditch the oldest data first,
		 * I hope thats okay with everyone? Yes? Good.
		 */
		while (qleft < 1) {
			tail = (tail + 1) & RQUEUEMASK;
			ch->ch_r_tail = tail;
			ch->ch_err_overrun++;
			qleft++;
		}

		memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, 1);
		ch->ch_equeue[head] = (unsigned char)linestatus;

		/* Ditch any remaining linestatus value. */
		linestatus = 0;

		/* Add to and flip head if needed */
		head = (head + 1) & RQUEUEMASK;

		qleft--;
		ch->ch_rxcount++;
	}

	/*
	 * Write new final heads to channel structure.
	 */
	ch->ch_r_head = head & RQUEUEMASK;
	ch->ch_e_head = head & EQUEUEMASK;

	spin_unlock_irqrestore(&ch->ch_lock, flags);
}

/*
 * This function basically goes to sleep for secs, or until
 * it gets signalled that the port has fully drained.
 */
static int neo_drain(struct tty_struct *tty, uint seconds)
{
	unsigned long flags;
	struct channel_t *ch;
	struct un_t *un;
	int rc = 0;

	if (!tty || tty->magic != TTY_MAGIC)
		return -ENXIO;

	un = (struct un_t *)tty->driver_data;
	if (!un || un->magic != DGNC_UNIT_MAGIC)
		return -ENXIO;

	ch = un->un_ch;
	if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
		return -ENXIO;

	spin_lock_irqsave(&ch->ch_lock, flags);
	un->un_flags |= UN_EMPTY;
	spin_unlock_irqrestore(&ch->ch_lock, flags);

	/*
	 * Go to sleep waiting for the tty layer to wake me back up when
	 * the empty flag goes away.
	 */
	rc = wait_event_interruptible_timeout(un->un_flags_wait,
					      ((un->un_flags & UN_EMPTY) == 0),
					      msecs_to_jiffies(seconds * 1000));

	/* If ret is non-zero, user ctrl-c'ed us */
	return rc;
}

/*
 * Flush the WRITE FIFO on the Neo.
 *
 * NOTE: Channel lock MUST be held before calling this function!
 */
static void neo_flush_uart_write(struct channel_t *ch)
{
	unsigned char tmp = 0;
	int i = 0;

	if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
		return;

	writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT), &ch->ch_neo_uart->isr_fcr);
	neo_pci_posting_flush(ch->ch_bd);

	for (i = 0; i < 10; i++) {
		/* Check to see if the UART feels it completely flushed the FIFO. */
		tmp = readb(&ch->ch_neo_uart->isr_fcr);
		if (tmp & 4)
			udelay(10);
		else
			break;
	}

	ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
}

/*
 * Flush the READ FIFO on the Neo.
 *
 * NOTE: Channel lock MUST be held before calling this function!
 */
static void neo_flush_uart_read(struct channel_t *ch)
{
	unsigned char tmp = 0;
	int i = 0;

	if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
		return;

	writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR), &ch->ch_neo_uart->isr_fcr);
	neo_pci_posting_flush(ch->ch_bd);

	for (i = 0; i < 10; i++) {
		/* Check to see if the UART feels it completely flushed the FIFO. */
		tmp = readb(&ch->ch_neo_uart->isr_fcr);
		if (tmp & 2)
			udelay(10);
		else
			break;
	}
}

static void neo_copy_data_from_queue_to_uart(struct channel_t *ch)
{
	ushort head;
	ushort tail;
	int n;
	int s;
	int qlen;
	uint len_written = 0;
	unsigned long flags;

	if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
		return;

	spin_lock_irqsave(&ch->ch_lock, flags);

	/* No data to write to the UART */
	if (ch->ch_w_tail == ch->ch_w_head)
		goto exit_unlock;

	/* If port is "stopped", don't send any data to the UART */
	if ((ch->ch_flags & CH_FORCED_STOP) ||
	    (ch->ch_flags & CH_BREAK_SENDING))
		goto exit_unlock;

	/*
	 * If FIFOs are disabled. Send data directly to txrx register
	 */
	if (!(ch->ch_flags & CH_FIFO_ENABLED)) {
		unsigned char lsrbits = readb(&ch->ch_neo_uart->lsr);

		/* Cache the LSR bits for later parsing */
		ch->ch_cached_lsr |= lsrbits;
		if (ch->ch_cached_lsr & UART_LSR_THRE) {
			ch->ch_cached_lsr &= ~(UART_LSR_THRE);

			/*
			 * If RTS Toggle mode is on, turn on RTS now if not already set,
			 * and make sure we get an event when the data transfer has completed.
			 */
			if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) {
				if (!(ch->ch_mostat & UART_MCR_RTS)) {
					ch->ch_mostat |= (UART_MCR_RTS);
					neo_assert_modem_signals(ch);
				}
				ch->ch_tun.un_flags |= (UN_EMPTY);
			}
			/*
			 * If DTR Toggle mode is on, turn on DTR now if not already set,
			 * and make sure we get an event when the data transfer has completed.
			 */
			if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) {
				if (!(ch->ch_mostat & UART_MCR_DTR)) {
					ch->ch_mostat |= (UART_MCR_DTR);
					neo_assert_modem_signals(ch);
				}
				ch->ch_tun.un_flags |= (UN_EMPTY);
			}

			writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_neo_uart->txrx);
			ch->ch_w_tail++;
			ch->ch_w_tail &= WQUEUEMASK;
			ch->ch_txcount++;
		}

		goto exit_unlock;
	}

	/*
	 * We have to do it this way, because of the EXAR TXFIFO count bug.
	 */
	if ((ch->ch_bd->dvid & 0xf0) < UART_XR17E158_DVID) {
		if (!(ch->ch_flags & (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM)))
			goto exit_unlock;

		len_written = 0;

		n = readb(&ch->ch_neo_uart->tfifo);

		if ((unsigned int)n > ch->ch_t_tlevel)
			goto exit_unlock;

		n = UART_17158_TX_FIFOSIZE - ch->ch_t_tlevel;
	} else {
		n = UART_17158_TX_FIFOSIZE - readb(&ch->ch_neo_uart->tfifo);
	}

	/* cache head and tail of queue */
	head = ch->ch_w_head & WQUEUEMASK;
	tail = ch->ch_w_tail & WQUEUEMASK;
	qlen = (head - tail) & WQUEUEMASK;

	/* Find minimum of the FIFO space, versus queue length */
	n = min(n, qlen);

	while (n > 0) {
		s = ((head >= tail) ? head : WQUEUESIZE) - tail;
		s = min(s, n);

		if (s <= 0)
			break;

		/*
		 * If RTS Toggle mode is on, turn on RTS now if not already set,
		 * and make sure we get an event when the data transfer has completed.
		 */
		if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) {
			if (!(ch->ch_mostat & UART_MCR_RTS)) {
				ch->ch_mostat |= (UART_MCR_RTS);
				neo_assert_modem_signals(ch);
			}
			ch->ch_tun.un_flags |= (UN_EMPTY);
		}

		/*
		 * If DTR Toggle mode is on, turn on DTR now if not already set,
		 * and make sure we get an event when the data transfer has completed.
		 */
		if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) {
			if (!(ch->ch_mostat & UART_MCR_DTR)) {
				ch->ch_mostat |= (UART_MCR_DTR);
				neo_assert_modem_signals(ch);
			}
			ch->ch_tun.un_flags |= (UN_EMPTY);
		}

		memcpy_toio(&ch->ch_neo_uart->txrxburst, ch->ch_wqueue + tail, s);

		/* Add and flip queue if needed */
		tail = (tail + s) & WQUEUEMASK;
		n -= s;
		ch->ch_txcount += s;
		len_written += s;
	}

	/* Update the final tail */
	ch->ch_w_tail = tail & WQUEUEMASK;

	if (len_written > 0) {
		neo_pci_posting_flush(ch->ch_bd);
		ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
	}

exit_unlock:
	spin_unlock_irqrestore(&ch->ch_lock, flags);
}

static void neo_parse_modem(struct channel_t *ch, unsigned char signals)
{
	unsigned char msignals = signals;

	if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
		return;

	/*
	 * Do altpin switching. Altpin switches DCD and DSR.
	 * This prolly breaks DSRPACE, so we should be more clever here.
	 */
	if (ch->ch_digi.digi_flags & DIGI_ALTPIN) {
		unsigned char mswap = msignals;

		if (mswap & UART_MSR_DDCD) {
			msignals &= ~UART_MSR_DDCD;
			msignals |= UART_MSR_DDSR;
		}
		if (mswap & UART_MSR_DDSR) {
			msignals &= ~UART_MSR_DDSR;
			msignals |= UART_MSR_DDCD;
		}
		if (mswap & UART_MSR_DCD) {
			msignals &= ~UART_MSR_DCD;
			msignals |= UART_MSR_DSR;
		}
		if (mswap & UART_MSR_DSR) {
			msignals &= ~UART_MSR_DSR;
			msignals |= UART_MSR_DCD;
		}
	}

	/* Scrub off lower bits. They signify delta's, which I don't care about */
	msignals &= 0xf0;

	if (msignals & UART_MSR_DCD)
		ch->ch_mistat |= UART_MSR_DCD;
	else
		ch->ch_mistat &= ~UART_MSR_DCD;

	if (msignals & UART_MSR_DSR)
		ch->ch_mistat |= UART_MSR_DSR;
	else
		ch->ch_mistat &= ~UART_MSR_DSR;

	if (msignals & UART_MSR_RI)
		ch->ch_mistat |= UART_MSR_RI;
	else
		ch->ch_mistat &= ~UART_MSR_RI;

	if (msignals & UART_MSR_CTS)
		ch->ch_mistat |= UART_MSR_CTS;
	else
		ch->ch_mistat &= ~UART_MSR_CTS;
}

/* Make the UART raise any of the output signals we want up */
static void neo_assert_modem_signals(struct channel_t *ch)
{
	unsigned char out;

	if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
		return;

	out = ch->ch_mostat;

	if (ch->ch_flags & CH_LOOPBACK)
		out |= UART_MCR_LOOP;

	writeb(out, &ch->ch_neo_uart->mcr);
	neo_pci_posting_flush(ch->ch_bd);

	/* Give time for the UART to actually raise/drop the signals */
	udelay(10);
}

static void neo_send_start_character(struct channel_t *ch)
{
	if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
		return;

	if (ch->ch_startc != _POSIX_VDISABLE) {
		ch->ch_xon_sends++;
		writeb(ch->ch_startc, &ch->ch_neo_uart->txrx);
		neo_pci_posting_flush(ch->ch_bd);
		udelay(10);
	}
}

static void neo_send_stop_character(struct channel_t *ch)
{
	if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
		return;

	if (ch->ch_stopc != _POSIX_VDISABLE) {
		ch->ch_xoff_sends++;
		writeb(ch->ch_stopc, &ch->ch_neo_uart->txrx);
		neo_pci_posting_flush(ch->ch_bd);
		udelay(10);
	}
}

/*
 * neo_uart_init
 */
static void neo_uart_init(struct channel_t *ch)
{
	writeb(0, &ch->ch_neo_uart->ier);
	writeb(0, &ch->ch_neo_uart->efr);
	writeb(UART_EFR_ECB, &ch->ch_neo_uart->efr);

	/* Clear out UART and FIFO */
	readb(&ch->ch_neo_uart->txrx);
	writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), &ch->ch_neo_uart->isr_fcr);
	readb(&ch->ch_neo_uart->lsr);
	readb(&ch->ch_neo_uart->msr);

	ch->ch_flags |= CH_FIFO_ENABLED;

	/* Assert any signals we want up */
	writeb(ch->ch_mostat, &ch->ch_neo_uart->mcr);
	neo_pci_posting_flush(ch->ch_bd);
}

/*
 * Make the UART completely turn off.
 */
static void neo_uart_off(struct channel_t *ch)
{
	/* Turn off UART enhanced bits */
	writeb(0, &ch->ch_neo_uart->efr);

	/* Stop all interrupts from occurring. */
	writeb(0, &ch->ch_neo_uart->ier);
	neo_pci_posting_flush(ch->ch_bd);
}

static uint neo_get_uart_bytes_left(struct channel_t *ch)
{
	unsigned char left = 0;
	unsigned char lsr = readb(&ch->ch_neo_uart->lsr);

	/* We must cache the LSR as some of the bits get reset once read... */
	ch->ch_cached_lsr |= lsr;

	/* Determine whether the Transmitter is empty or not */
	if (!(lsr & UART_LSR_TEMT)) {
		if (ch->ch_flags & CH_TX_FIFO_EMPTY)
			tasklet_schedule(&ch->ch_bd->helper_tasklet);
		left = 1;
	} else {
		ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
		left = 0;
	}

	return left;
}

/* Channel lock MUST be held by the calling function! */
static void neo_send_break(struct channel_t *ch, int msecs)
{
	/*
	 * If we receive a time of 0, this means turn off the break.
	 */
	if (msecs == 0) {
		if (ch->ch_flags & CH_BREAK_SENDING) {
			unsigned char temp = readb(&ch->ch_neo_uart->lcr);

			writeb((temp & ~UART_LCR_SBC), &ch->ch_neo_uart->lcr);
			neo_pci_posting_flush(ch->ch_bd);
			ch->ch_flags &= ~(CH_BREAK_SENDING);
			ch->ch_stop_sending_break = 0;
		}
		return;
	}

	/*
	 * Set the time we should stop sending the break.
	 * If we are already sending a break, toss away the existing
	 * time to stop, and use this new value instead.
	 */
	ch->ch_stop_sending_break = jiffies + dgnc_jiffies_from_ms(msecs);

	/* Tell the UART to start sending the break */
	if (!(ch->ch_flags & CH_BREAK_SENDING)) {
		unsigned char temp = readb(&ch->ch_neo_uart->lcr);

		writeb((temp | UART_LCR_SBC), &ch->ch_neo_uart->lcr);
		neo_pci_posting_flush(ch->ch_bd);
		ch->ch_flags |= (CH_BREAK_SENDING);
	}
}

/*
 * neo_send_immediate_char.
 *
 * Sends a specific character as soon as possible to the UART,
 * jumping over any bytes that might be in the write queue.
 *
 * The channel lock MUST be held by the calling function.
 */
static void neo_send_immediate_char(struct channel_t *ch, unsigned char c)
{
	if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
		return;

	writeb(c, &ch->ch_neo_uart->txrx);
	neo_pci_posting_flush(ch->ch_bd);
}

static unsigned int neo_read_eeprom(unsigned char __iomem *base, unsigned int address)
{
	unsigned int enable;
	unsigned int bits;
	unsigned int databit;
	unsigned int val;

	/* enable chip select */
	writeb(NEO_EECS, base + NEO_EEREG);
	/* READ */
	enable = address | 0x180;

	for (bits = 9; bits--; ) {
		databit = (enable & (1 << bits)) ? NEO_EEDI : 0;
		/* Set read address */
		writeb(databit | NEO_EECS, base + NEO_EEREG);
		writeb(databit | NEO_EECS | NEO_EECK, base + NEO_EEREG);
	}

	val = 0;

	for (bits = 17; bits--; ) {
		/* clock to EEPROM */
		writeb(NEO_EECS, base + NEO_EEREG);
		writeb(NEO_EECS | NEO_EECK, base + NEO_EEREG);
		val <<= 1;
		/* read EEPROM */
		if (readb(base + NEO_EEREG) & NEO_EEDO)
			val |= 1;
	}

	/* clock falling edge */
	writeb(NEO_EECS, base + NEO_EEREG);

	/* drop chip select */
	writeb(0x00, base + NEO_EEREG);

	return val;
}

static void neo_vpd(struct dgnc_board *brd)
{
	unsigned int i = 0;
	unsigned int a;

	if (!brd || brd->magic != DGNC_BOARD_MAGIC)
		return;

	if (!brd->re_map_membase)
		return;

	/* Store the VPD into our buffer */
	for (i = 0; i < NEO_VPD_IMAGESIZE; i++) {
		a = neo_read_eeprom(brd->re_map_membase, i);
		brd->vpd[i * 2] = a & 0xff;
		brd->vpd[(i * 2) + 1] = (a >> 8) & 0xff;
	}

	if  (((brd->vpd[0x08] != 0x82)	   /* long resource name tag */
		&&  (brd->vpd[0x10] != 0x82))   /* long resource name tag (PCI-66 files)*/
		||  (brd->vpd[0x7F] != 0x78)) { /* small resource end tag */

		memset(brd->vpd, '\0', NEO_VPD_IMAGESIZE);
	} else {
		/* Search for the serial number */
		for (i = 0; i < NEO_VPD_IMAGEBYTES - 3; i++)
			if (brd->vpd[i] == 'S' && brd->vpd[i + 1] == 'N')
				strncpy(brd->serial_num, &brd->vpd[i + 3], 9);
	}
}
