/*
 * 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.
 */

/*
 * This file implements the tty driver functionality for the
 * Neo and ClassicBoard PCI based product lines.
 */

#include <linux/kernel.h>
#include <linux/sched/signal.h>	/* For jiffies, task states, etc. */
#include <linux/interrupt.h>	/* For tasklet and interrupt structs/defines */
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/types.h>
#include <linux/serial_reg.h>
#include <linux/slab.h>
#include <linux/delay.h>	/* For udelay */
#include <linux/uaccess.h>	/* For copy_from_user/copy_to_user */
#include <linux/pci.h>
#include "dgnc_driver.h"
#include "dgnc_tty.h"
#include "dgnc_neo.h"
#include "dgnc_cls.h"
#include "dgnc_utils.h"

/* Default transparent print information. */

static const struct digi_t dgnc_digi_init = {
	.digi_flags =	DIGI_COOK,	/* Flags */
	.digi_maxcps =	100,		/* Max CPS */
	.digi_maxchar =	50,		/* Max chars in print queue */
	.digi_bufsize =	100,		/* Printer buffer size */
	.digi_onlen =	4,		/* size of printer on string */
	.digi_offlen =	4,		/* size of printer off string */
	.digi_onstr =	"\033[5i",	/* ANSI printer on string ] */
	.digi_offstr =	"\033[4i",	/* ANSI printer off string ] */
	.digi_term =	"ansi"		/* default terminal type */
};

/*
 * Define a local default termios struct. All ports will be created
 * with this termios initially.
 *
 * This defines a raw port at 9600 baud, 8 data bits, no parity,
 * 1 stop bit.
 */
static const struct ktermios default_termios = {
	.c_iflag =	(DEFAULT_IFLAGS),
	.c_oflag =	(DEFAULT_OFLAGS),
	.c_cflag =	(DEFAULT_CFLAGS),
	.c_lflag =	(DEFAULT_LFLAGS),
	.c_cc =		INIT_C_CC,
	.c_line =	0,
};

static int dgnc_tty_open(struct tty_struct *tty, struct file *file);
static void dgnc_tty_close(struct tty_struct *tty, struct file *file);
static int dgnc_block_til_ready(struct tty_struct *tty, struct file *file,
				struct channel_t *ch);
static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
			  unsigned long arg);
static int dgnc_tty_digigeta(struct tty_struct *tty,
			     struct digi_t __user *retinfo);
static int dgnc_tty_digiseta(struct tty_struct *tty,
			     struct digi_t __user *new_info);
static int dgnc_tty_write_room(struct tty_struct *tty);
static int dgnc_tty_put_char(struct tty_struct *tty, unsigned char c);
static int dgnc_tty_chars_in_buffer(struct tty_struct *tty);
static void dgnc_tty_start(struct tty_struct *tty);
static void dgnc_tty_stop(struct tty_struct *tty);
static void dgnc_tty_throttle(struct tty_struct *tty);
static void dgnc_tty_unthrottle(struct tty_struct *tty);
static void dgnc_tty_flush_chars(struct tty_struct *tty);
static void dgnc_tty_flush_buffer(struct tty_struct *tty);
static void dgnc_tty_hangup(struct tty_struct *tty);
static int dgnc_set_modem_info(struct channel_t *ch, unsigned int command,
			       unsigned int __user *value);
static int dgnc_get_modem_info(struct channel_t *ch,
			       unsigned int __user *value);
static int dgnc_tty_tiocmget(struct tty_struct *tty);
static int dgnc_tty_tiocmset(struct tty_struct *tty, unsigned int set,
			     unsigned int clear);
static int dgnc_tty_send_break(struct tty_struct *tty, int msec);
static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout);
static int dgnc_tty_write(struct tty_struct *tty, const unsigned char *buf,
			  int count);
static void dgnc_tty_set_termios(struct tty_struct *tty,
				 struct ktermios *old_termios);
static void dgnc_tty_send_xchar(struct tty_struct *tty, char ch);
static void dgnc_set_signal_low(struct channel_t *ch, const unsigned char line);
static void dgnc_wake_up_unit(struct un_t *unit);

static const struct tty_operations dgnc_tty_ops = {
	.open = dgnc_tty_open,
	.close = dgnc_tty_close,
	.write = dgnc_tty_write,
	.write_room = dgnc_tty_write_room,
	.flush_buffer = dgnc_tty_flush_buffer,
	.chars_in_buffer = dgnc_tty_chars_in_buffer,
	.flush_chars = dgnc_tty_flush_chars,
	.ioctl = dgnc_tty_ioctl,
	.set_termios = dgnc_tty_set_termios,
	.stop = dgnc_tty_stop,
	.start = dgnc_tty_start,
	.throttle = dgnc_tty_throttle,
	.unthrottle = dgnc_tty_unthrottle,
	.hangup = dgnc_tty_hangup,
	.put_char = dgnc_tty_put_char,
	.tiocmget = dgnc_tty_tiocmget,
	.tiocmset = dgnc_tty_tiocmset,
	.break_ctl = dgnc_tty_send_break,
	.wait_until_sent = dgnc_tty_wait_until_sent,
	.send_xchar = dgnc_tty_send_xchar
};

/* TTY Initialization/Cleanup Functions */

/**
 * dgnc_tty_register() - Init the tty subsystem for this board.
 */
int dgnc_tty_register(struct dgnc_board *brd)
{
	int rc;

	brd->serial_driver = tty_alloc_driver(brd->maxports,
					      TTY_DRIVER_REAL_RAW |
					      TTY_DRIVER_DYNAMIC_DEV |
					      TTY_DRIVER_HARDWARE_BREAK);
	if (IS_ERR(brd->serial_driver))
		return PTR_ERR(brd->serial_driver);

	snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgnc_%d_",
		 brd->boardnum);

	brd->serial_driver->name = brd->serial_name;
	brd->serial_driver->name_base = 0;
	brd->serial_driver->major = 0;
	brd->serial_driver->minor_start = 0;
	brd->serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
	brd->serial_driver->subtype = SERIAL_TYPE_NORMAL;
	brd->serial_driver->init_termios = default_termios;
	brd->serial_driver->driver_name = DRVSTR;

	/*
	 * Entry points for driver.  Called by the kernel from
	 * tty_io.c and n_tty.c.
	 */
	tty_set_operations(brd->serial_driver, &dgnc_tty_ops);

	rc = tty_register_driver(brd->serial_driver);
	if (rc < 0) {
		dev_dbg(&brd->pdev->dev,
			"Can't register tty device (%d)\n", rc);
		goto free_serial_driver;
	}

	/*
	 * If we're doing transparent print, we have to do all of the above
	 * again, separately so we don't get the LD confused about what major
	 * we are when we get into the dgnc_tty_open() routine.
	 */
	brd->print_driver = tty_alloc_driver(brd->maxports,
					     TTY_DRIVER_REAL_RAW |
					     TTY_DRIVER_DYNAMIC_DEV |
					     TTY_DRIVER_HARDWARE_BREAK);
	if (IS_ERR(brd->print_driver)) {
		rc = PTR_ERR(brd->print_driver);
		goto unregister_serial_driver;
	}

	snprintf(brd->print_name, MAXTTYNAMELEN, "pr_dgnc_%d_", brd->boardnum);

	brd->print_driver->name = brd->print_name;
	brd->print_driver->name_base = 0;
	brd->print_driver->major = brd->serial_driver->major;
	brd->print_driver->minor_start = 0x80;
	brd->print_driver->type = TTY_DRIVER_TYPE_SERIAL;
	brd->print_driver->subtype = SERIAL_TYPE_NORMAL;
	brd->print_driver->init_termios = default_termios;
	brd->print_driver->driver_name = DRVSTR;

	/*
	 * Entry points for driver.  Called by the kernel from
	 * tty_io.c and n_tty.c.
	 */
	tty_set_operations(brd->print_driver, &dgnc_tty_ops);

	rc = tty_register_driver(brd->print_driver);
	if (rc < 0) {
		dev_dbg(&brd->pdev->dev,
			"Can't register Transparent Print device(%d)\n",
			rc);
		goto free_print_driver;
	}

	return 0;

free_print_driver:
	put_tty_driver(brd->print_driver);
unregister_serial_driver:
	tty_unregister_driver(brd->serial_driver);
free_serial_driver:
	put_tty_driver(brd->serial_driver);

	return rc;
}

void dgnc_tty_unregister(struct dgnc_board *brd)
{
	tty_unregister_driver(brd->print_driver);
	tty_unregister_driver(brd->serial_driver);
	put_tty_driver(brd->print_driver);
	put_tty_driver(brd->serial_driver);
}

/**
 * dgnc_tty_init() - Initialize the tty subsystem.
 *
 * Called once per board after board has been downloaded and initialized.
 */
int dgnc_tty_init(struct dgnc_board *brd)
{
	int i;
	int rc;
	void __iomem *vaddr;
	struct channel_t *ch;

	if (!brd)
		return -ENXIO;

	/* Initialize board structure elements. */

	vaddr = brd->re_map_membase;

	brd->nasync = brd->maxports;

	for (i = 0; i < brd->nasync; i++) {
		brd->channels[i] = kzalloc(sizeof(*brd->channels[i]),
					   GFP_KERNEL);
		if (!brd->channels[i]) {
			rc = -ENOMEM;
			goto err_free_channels;
		}
	}

	ch = brd->channels[0];
	vaddr = brd->re_map_membase;

	/* Set up channel variables */
	for (i = 0; i < brd->nasync; i++, ch = brd->channels[i]) {
		spin_lock_init(&ch->ch_lock);

		ch->ch_tun.un_ch = ch;
		ch->ch_tun.un_type = DGNC_SERIAL;
		ch->ch_tun.un_dev = i;

		ch->ch_pun.un_ch = ch;
		ch->ch_pun.un_type = DGNC_PRINT;
		ch->ch_pun.un_dev = i + 128;

		if (brd->bd_uart_offset == 0x200)
			ch->ch_neo_uart = vaddr + (brd->bd_uart_offset * i);
		else
			ch->ch_cls_uart = vaddr + (brd->bd_uart_offset * i);

		ch->ch_bd = brd;
		ch->ch_portnum = i;
		ch->ch_digi = dgnc_digi_init;

		/* .25 second delay */
		ch->ch_close_delay = 250;

		init_waitqueue_head(&ch->ch_flags_wait);
		init_waitqueue_head(&ch->ch_tun.un_flags_wait);
		init_waitqueue_head(&ch->ch_pun.un_flags_wait);

		{
			struct device *classp;

			classp = tty_register_device(brd->serial_driver, i,
						     &ch->ch_bd->pdev->dev);
			ch->ch_tun.un_sysfs = classp;

			classp = tty_register_device(brd->print_driver, i,
						     &ch->ch_bd->pdev->dev);
			ch->ch_pun.un_sysfs = classp;
		}
	}

	return 0;

err_free_channels:
	for (i = i - 1; i >= 0; --i) {
		kfree(brd->channels[i]);
		brd->channels[i] = NULL;
	}

	return rc;
}

/**
 * dgnc_cleanup_tty() - Cleanup driver.
 *
 * Uninitialize the TTY portion of this driver.  Free all memory and
 * resources.
 */
void dgnc_cleanup_tty(struct dgnc_board *brd)
{
	int i = 0;

	for (i = 0; i < brd->nasync; i++)
		tty_unregister_device(brd->serial_driver, i);

	tty_unregister_driver(brd->serial_driver);

	for (i = 0; i < brd->nasync; i++)
		tty_unregister_device(brd->print_driver, i);

	tty_unregister_driver(brd->print_driver);

	put_tty_driver(brd->serial_driver);
	put_tty_driver(brd->print_driver);
}

/**
 * dgnc_wmove() - Write data to transmit queue.
 * @ch: Pointer to channel structure.
 * @buf: Pointer to characters to be moved.
 * @n: Number of characters to move.
 */
static void dgnc_wmove(struct channel_t *ch, char *buf, uint n)
{
	int	remain;
	uint	head;

	if (!ch)
		return;

	head = ch->ch_w_head & WQUEUEMASK;

	/*
	 * If the write wraps over the top of the circular buffer,
	 * move the portion up to the wrap point, and reset the
	 * pointers to the bottom.
	 */
	remain = WQUEUESIZE - head;

	if (n >= remain) {
		n -= remain;
		memcpy(ch->ch_wqueue + head, buf, remain);
		head = 0;
		buf += remain;
	}

	if (n > 0) {
		/* Move rest of data. */
		remain = n;
		memcpy(ch->ch_wqueue + head, buf, remain);
		head += remain;
	}

	head &= WQUEUEMASK;
	ch->ch_w_head = head;
}

/**
 * dgnc_input() - Process received data.
 * @ch: Pointer to channel structure.
 */
void dgnc_input(struct channel_t *ch)
{
	struct dgnc_board *bd;
	struct tty_struct *tp;
	struct tty_ldisc *ld = NULL;
	uint	rmask;
	ushort	head;
	ushort	tail;
	int	data_len;
	unsigned long flags;
	int flip_len;
	int len = 0;
	int n = 0;
	int s = 0;
	int i = 0;

	if (!ch)
		return;

	tp = ch->ch_tun.un_tty;

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

	spin_lock_irqsave(&ch->ch_lock, flags);

	rmask = RQUEUEMASK;
	head = ch->ch_r_head & rmask;
	tail = ch->ch_r_tail & rmask;
	data_len = (head - tail) & rmask;

	if (data_len == 0)
		goto exit_unlock;

	/*
	 * If the device is not open, or CREAD is off,
	 * flush input data and return immediately.
	 */
	if (!tp ||
	    !(ch->ch_tun.un_flags & UN_ISOPEN) ||
	    !C_CREAD(tp) ||
	    (ch->ch_tun.un_flags & UN_CLOSING)) {
		ch->ch_r_head = tail;

		/* Force queue flow control to be released, if needed */
		dgnc_check_queue_flow_control(ch);

		goto exit_unlock;
	}

	if (ch->ch_flags & CH_FORCED_STOPI)
		goto exit_unlock;

	flip_len = TTY_FLIPBUF_SIZE;

	len = min(data_len, flip_len);
	len = min(len, (N_TTY_BUF_SIZE - 1));

	ld = tty_ldisc_ref(tp);
	if (!ld) {
		len = 0;
	} else {
		if (!ld->ops->receive_buf) {
			ch->ch_r_head = ch->ch_r_tail;
			len = 0;
		}
	}

	if (len <= 0)
		goto exit_unlock;

	/*
	 * The tty layer in the kernel has changed in 2.6.16+.
	 *
	 * The flip buffers in the tty structure are no longer exposed,
	 * and probably will be going away eventually.
	 *
	 * If we are completely raw, we don't need to go through a lot
	 * of the tty layers that exist.
	 * In this case, we take the shortest and fastest route we
	 * can to relay the data to the user.
	 *
	 * On the other hand, if we are not raw, we need to go through
	 * the new 2.6.16+ tty layer, which has its API more well defined.
	 */
	len = tty_buffer_request_room(tp->port, len);
	n = len;

	/*
	 * n now contains the most amount of data we can copy,
	 * bounded either by how much the Linux tty layer can handle,
	 * or the amount of data the card actually has pending...
	 */
	while (n) {
		unsigned char *ch_pos = ch->ch_equeue + tail;

		s = ((head >= tail) ? head : RQUEUESIZE) - tail;
		s = min(s, n);

		if (s <= 0)
			break;

		/*
		 * If conditions are such that ld needs to see all
		 * UART errors, we will have to walk each character
		 * and error byte and send them to the buffer one at
		 * a time.
		 */
		if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) {
			for (i = 0; i < s; i++) {
				unsigned char ch = *(ch_pos + i);
				char flag = TTY_NORMAL;

				if (ch & UART_LSR_BI)
					flag = TTY_BREAK;
				else if (ch & UART_LSR_PE)
					flag = TTY_PARITY;
				else if (ch & UART_LSR_FE)
					flag = TTY_FRAME;

				tty_insert_flip_char(tp->port, ch, flag);
			}
		} else {
			tty_insert_flip_string(tp->port, ch_pos, s);
		}

		tail += s;
		n -= s;
		/* Flip queue if needed */
		tail &= rmask;
	}

	ch->ch_r_tail = tail & rmask;
	ch->ch_e_tail = tail & rmask;
	dgnc_check_queue_flow_control(ch);
	spin_unlock_irqrestore(&ch->ch_lock, flags);

	/* Tell the tty layer its okay to "eat" the data now */
	tty_flip_buffer_push(tp->port);

	if (ld)
		tty_ldisc_deref(ld);
	return;

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

/**
 * dgnc_carrier()
 *
 * Determines when CARRIER changes state and takes appropriate
 * action.
 */
void dgnc_carrier(struct channel_t *ch)
{
	int virt_carrier = 0;
	int phys_carrier = 0;

	if (!ch)
		return;

	if (ch->ch_mistat & UART_MSR_DCD)
		phys_carrier = 1;

	if (ch->ch_digi.digi_flags & DIGI_FORCEDCD)
		virt_carrier = 1;

	if (ch->ch_c_cflag & CLOCAL)
		virt_carrier = 1;

	/* Test for a VIRTUAL carrier transition to HIGH. */

	if (((ch->ch_flags & CH_FCAR) == 0) && (virt_carrier == 1)) {
		/*
		 * When carrier rises, wake any threads waiting
		 * for carrier in the open routine.
		 */
		if (waitqueue_active(&ch->ch_flags_wait))
			wake_up_interruptible(&ch->ch_flags_wait);
	}

	/* Test for a PHYSICAL carrier transition to HIGH. */

	if (((ch->ch_flags & CH_CD) == 0) && (phys_carrier == 1)) {
		/*
		 * When carrier rises, wake any threads waiting
		 * for carrier in the open routine.
		 */
		if (waitqueue_active(&ch->ch_flags_wait))
			wake_up_interruptible(&ch->ch_flags_wait);
	}

	/*
	 *  Test for a PHYSICAL transition to low, so long as we aren't
	 *  currently ignoring physical transitions (which is what "virtual
	 *  carrier" indicates).
	 *
	 *  The transition of the virtual carrier to low really doesn't
	 *  matter... it really only means "ignore carrier state", not
	 *  "make pretend that carrier is there".
	 */
	if ((virt_carrier == 0) && ((ch->ch_flags & CH_CD) != 0) &&
	    (phys_carrier == 0)) {
		/*
		 *   When carrier drops:
		 *
		 *   Drop carrier on all open units.
		 *
		 *   Flush queues, waking up any task waiting in the
		 *   line discipline.
		 *
		 *   Send a hangup to the control terminal.
		 *
		 *   Enable all select calls.
		 */
		if (waitqueue_active(&ch->ch_flags_wait))
			wake_up_interruptible(&ch->ch_flags_wait);

		if (ch->ch_tun.un_open_count > 0)
			tty_hangup(ch->ch_tun.un_tty);

		if (ch->ch_pun.un_open_count > 0)
			tty_hangup(ch->ch_pun.un_tty);
	}

	/*  Make sure that our cached values reflect the current reality. */

	if (virt_carrier == 1)
		ch->ch_flags |= CH_FCAR;
	else
		ch->ch_flags &= ~CH_FCAR;

	if (phys_carrier == 1)
		ch->ch_flags |= CH_CD;
	else
		ch->ch_flags &= ~CH_CD;
}

/*  Assign the custom baud rate to the channel structure */
static void dgnc_set_custom_speed(struct channel_t *ch, uint newrate)
{
	int testdiv;
	int testrate_high;
	int testrate_low;
	int deltahigh;
	int deltalow;

	if (newrate <= 0) {
		ch->ch_custom_speed = 0;
		return;
	}

	/*
	 *  Since the divisor is stored in a 16-bit integer, we make sure
	 *  we don't allow any rates smaller than a 16-bit integer would allow.
	 *  And of course, rates above the dividend won't fly.
	 */
	if (newrate && newrate < ((ch->ch_bd->bd_dividend / 0xFFFF) + 1))
		newrate = (ch->ch_bd->bd_dividend / 0xFFFF) + 1;

	if (newrate && newrate > ch->ch_bd->bd_dividend)
		newrate = ch->ch_bd->bd_dividend;

	if (newrate > 0) {
		testdiv = ch->ch_bd->bd_dividend / newrate;

		/*
		 *  If we try to figure out what rate the board would use
		 *  with the test divisor, it will be either equal or higher
		 *  than the requested baud rate.  If we then determine the
		 *  rate with a divisor one higher, we will get the next lower
		 *  supported rate below the requested.
		 */
		testrate_high = ch->ch_bd->bd_dividend / testdiv;
		testrate_low  = ch->ch_bd->bd_dividend / (testdiv + 1);

		/*
		 *  If the rate for the requested divisor is correct, just
		 *  use it and be done.
		 */
		if (testrate_high != newrate) {
			/*
			 *  Otherwise, pick the rate that is closer
			 *  (i.e. whichever rate has a smaller delta).
			 */
			deltahigh = testrate_high - newrate;
			deltalow = newrate - testrate_low;

			if (deltahigh < deltalow)
				newrate = testrate_high;
			else
				newrate = testrate_low;
		}
	}

	ch->ch_custom_speed = newrate;
}

void dgnc_check_queue_flow_control(struct channel_t *ch)
{
	int qleft;

	qleft = ch->ch_r_tail - ch->ch_r_head - 1;
	if (qleft < 0)
		qleft += RQUEUEMASK + 1;

	/*
	 * Check to see if we should enforce flow control on our queue because
	 * the ld (or user) isn't reading data out of our queue fast enuf.
	 *
	 * NOTE: This is done based on what the current flow control of the
	 * port is set for.
	 *
	 * 1) HWFLOW (RTS) - Turn off the UART's Receive interrupt.
	 *	This will cause the UART's FIFO to back up, and force
	 *	the RTS signal to be dropped.
	 * 2) SWFLOW (IXOFF) - Keep trying to send a stop character to
	 *	the other side, in hopes it will stop sending data to us.
	 * 3) NONE - Nothing we can do.  We will simply drop any extra data
	 *	that gets sent into us when the queue fills up.
	 */
	if (qleft < 256) {
		/* HWFLOW */
		if (ch->ch_digi.digi_flags & CTSPACE ||
		    ch->ch_c_cflag & CRTSCTS) {
			if (!(ch->ch_flags & CH_RECEIVER_OFF)) {
				ch->ch_bd->bd_ops->disable_receiver(ch);
				ch->ch_flags |= (CH_RECEIVER_OFF);
			}
		}
		/* SWFLOW */
		else if (ch->ch_c_iflag & IXOFF) {
			if (ch->ch_stops_sent <= MAX_STOPS_SENT) {
				ch->ch_bd->bd_ops->send_stop_character(ch);
				ch->ch_stops_sent++;
			}
		}
	}

	/*
	 * Check to see if we should unenforce flow control because
	 * ld (or user) finally read enuf data out of our queue.
	 *
	 * NOTE: This is done based on what the current flow control of the
	 * port is set for.
	 *
	 * 1) HWFLOW (RTS) - Turn back on the UART's Receive interrupt.
	 *	This will cause the UART's FIFO to raise RTS back up,
	 *	which will allow the other side to start sending data again.
	 * 2) SWFLOW (IXOFF) - Send a start character to
	 *	the other side, so it will start sending data to us again.
	 * 3) NONE - Do nothing. Since we didn't do anything to turn off the
	 *	other side, we don't need to do anything now.
	 */
	if (qleft > (RQUEUESIZE / 2)) {
		/* HWFLOW */
		if (ch->ch_digi.digi_flags & RTSPACE ||
		    ch->ch_c_cflag & CRTSCTS) {
			if (ch->ch_flags & CH_RECEIVER_OFF) {
				ch->ch_bd->bd_ops->enable_receiver(ch);
				ch->ch_flags &= ~(CH_RECEIVER_OFF);
			}
		}
		/* SWFLOW */
		else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) {
			ch->ch_stops_sent = 0;
			ch->ch_bd->bd_ops->send_start_character(ch);
		}
	}
}

static void dgnc_set_signal_low(struct channel_t *ch, const unsigned char sig)
{
	ch->ch_mostat &= ~(sig);
	ch->ch_bd->bd_ops->assert_modem_signals(ch);
}

void dgnc_wakeup_writes(struct channel_t *ch)
{
	int qlen = 0;
	unsigned long flags;

	if (!ch)
		return;

	spin_lock_irqsave(&ch->ch_lock, flags);

	/* If channel now has space, wake up anyone waiting on the condition. */

	qlen = ch->ch_w_head - ch->ch_w_tail;
	if (qlen < 0)
		qlen += WQUEUESIZE;

	if (qlen >= (WQUEUESIZE - 256)) {
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		return;
	}

	if (ch->ch_tun.un_flags & UN_ISOPEN) {
		tty_wakeup(ch->ch_tun.un_tty);

		/*
		 * If unit is set to wait until empty, check to make sure
		 * the queue AND FIFO are both empty.
		 */
		if (ch->ch_tun.un_flags & UN_EMPTY) {
			if ((qlen == 0) &&
			    (ch->ch_bd->bd_ops->get_uart_bytes_left(ch) == 0)) {
				ch->ch_tun.un_flags &= ~(UN_EMPTY);

				/*
				 * If RTS Toggle mode is on, whenever
				 * the queue and UART is empty, keep RTS low.
				 */
				if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)
					dgnc_set_signal_low(ch, UART_MCR_RTS);

				/*
				 * If DTR Toggle mode is on, whenever
				 * the queue and UART is empty, keep DTR low.
				 */
				if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE)
					dgnc_set_signal_low(ch, UART_MCR_DTR);
			}
		}

		wake_up_interruptible(&ch->ch_tun.un_flags_wait);
	}

	if (ch->ch_pun.un_flags & UN_ISOPEN) {
		tty_wakeup(ch->ch_pun.un_tty);

		/*
		 * If unit is set to wait until empty, check to make sure
		 * the queue AND FIFO are both empty.
		 */
		if (ch->ch_pun.un_flags & UN_EMPTY) {
			if ((qlen == 0) &&
			    (ch->ch_bd->bd_ops->get_uart_bytes_left(ch) == 0))
				ch->ch_pun.un_flags &= ~(UN_EMPTY);
		}

		wake_up_interruptible(&ch->ch_pun.un_flags_wait);
	}

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

static struct dgnc_board *find_board_by_major(unsigned int major)
{
	int i;

	for (i = 0; i < MAXBOARDS; i++) {
		struct dgnc_board *brd = dgnc_board[i];

		if (!brd)
			return NULL;

		if (major == brd->serial_driver->major ||
		    major == brd->print_driver->major)
			return brd;
	}

	return NULL;
}

/* TTY Entry points and helper functions */

static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
{
	struct dgnc_board	*brd;
	struct channel_t *ch;
	struct un_t	*un;
	uint		major = 0;
	uint		minor = 0;
	int		rc = 0;
	unsigned long flags;

	rc = 0;

	major = MAJOR(tty_devnum(tty));
	minor = MINOR(tty_devnum(tty));

	if (major > 255)
		return -ENXIO;

	brd = find_board_by_major(major);
	if (!brd)
		return -ENXIO;

	rc = wait_event_interruptible(brd->state_wait,
				      (brd->state & BOARD_READY));
	if (rc)
		return rc;

	spin_lock_irqsave(&brd->bd_lock, flags);

	if (PORT_NUM(minor) >= brd->nasync) {
		rc = -ENXIO;
		goto err_brd_unlock;
	}

	ch = brd->channels[PORT_NUM(minor)];
	if (!ch) {
		rc = -ENXIO;
		goto err_brd_unlock;
	}

	spin_unlock_irqrestore(&brd->bd_lock, flags);

	spin_lock_irqsave(&ch->ch_lock, flags);

	/* Figure out our type */
	if (!IS_PRINT(minor)) {
		un = &brd->channels[PORT_NUM(minor)]->ch_tun;
		un->un_type = DGNC_SERIAL;
	} else if (IS_PRINT(minor)) {
		un = &brd->channels[PORT_NUM(minor)]->ch_pun;
		un->un_type = DGNC_PRINT;
	} else {
		rc = -ENXIO;
		goto err_ch_unlock;
	}

	/*
	 * If the port is still in a previous open, and in a state
	 * where we simply cannot safely keep going, wait until the
	 * state clears.
	 */
	spin_unlock_irqrestore(&ch->ch_lock, flags);

	rc = wait_event_interruptible(ch->ch_flags_wait,
				      ((ch->ch_flags & CH_OPENING) == 0));
	/* If ret is non-zero, user ctrl-c'ed us */
	if (rc)
		return -EINTR;

	/*
	 * If either unit is in the middle of the fragile part of close,
	 * we just cannot touch the channel safely.
	 * Go to sleep, knowing that when the channel can be
	 * touched safely, the close routine will signal the
	 * ch_flags_wait to wake us back up.
	 */
	rc = wait_event_interruptible(
				ch->ch_flags_wait,
				(((ch->ch_tun.un_flags |
				ch->ch_pun.un_flags) & UN_CLOSING) == 0));
	/* If ret is non-zero, user ctrl-c'ed us */
	if (rc)
		return -EINTR;

	spin_lock_irqsave(&ch->ch_lock, flags);

	tty->driver_data = un;

	/* Initialize tty's */

	if (!(un->un_flags & UN_ISOPEN)) {
		un->un_tty = tty;

		/* Maybe do something here to the TTY struct as well? */
	}

	/*
	 * Allocate channel buffers for read/write/error.
	 * Set flag, so we don't get trounced on.
	 */
	ch->ch_flags |= (CH_OPENING);

	spin_unlock_irqrestore(&ch->ch_lock, flags);

	if (!ch->ch_rqueue)
		ch->ch_rqueue = kzalloc(RQUEUESIZE, GFP_KERNEL);
	if (!ch->ch_equeue)
		ch->ch_equeue = kzalloc(EQUEUESIZE, GFP_KERNEL);
	if (!ch->ch_wqueue)
		ch->ch_wqueue = kzalloc(WQUEUESIZE, GFP_KERNEL);

	if (!ch->ch_rqueue || !ch->ch_equeue || !ch->ch_wqueue) {
		kfree(ch->ch_rqueue);
		kfree(ch->ch_equeue);
		kfree(ch->ch_wqueue);
		return -ENOMEM;
	}

	spin_lock_irqsave(&ch->ch_lock, flags);

	ch->ch_flags &= ~(CH_OPENING);
	wake_up_interruptible(&ch->ch_flags_wait);

	/* Initialize if neither terminal or printer is open. */

	if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_ISOPEN)) {
		/* Flush input queues. */
		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;

		brd->bd_ops->flush_uart_write(ch);
		brd->bd_ops->flush_uart_read(ch);

		ch->ch_flags = 0;
		ch->ch_cached_lsr = 0;
		ch->ch_stop_sending_break = 0;
		ch->ch_stops_sent = 0;

		ch->ch_c_cflag   = tty->termios.c_cflag;
		ch->ch_c_iflag   = tty->termios.c_iflag;
		ch->ch_c_oflag   = tty->termios.c_oflag;
		ch->ch_c_lflag   = tty->termios.c_lflag;
		ch->ch_startc = tty->termios.c_cc[VSTART];
		ch->ch_stopc  = tty->termios.c_cc[VSTOP];

		/*
		 * Bring 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);

		/* Tell UART to init itself */
		brd->bd_ops->uart_init(ch);
	}

	brd->bd_ops->param(tty);

	dgnc_carrier(ch);

	spin_unlock_irqrestore(&ch->ch_lock, flags);

	rc = dgnc_block_til_ready(tty, file, ch);

	spin_lock_irqsave(&ch->ch_lock, flags);
	ch->ch_open_count++;
	un->un_open_count++;
	un->un_flags |= (UN_ISOPEN);
	spin_unlock_irqrestore(&ch->ch_lock, flags);

	return rc;

err_brd_unlock:
	spin_unlock_irqrestore(&brd->bd_lock, flags);

	return rc;
err_ch_unlock:
	spin_unlock_irqrestore(&ch->ch_lock, flags);

	return rc;
}

/* Wait for DCD, if needed. */
static int dgnc_block_til_ready(struct tty_struct *tty,
				struct file *file,
				struct channel_t *ch)
{
	int rc = 0;
	struct un_t *un = tty->driver_data;
	unsigned long flags;
	uint	old_flags = 0;
	int	sleep_on_un_flags = 0;

	if (!file)
		return -ENXIO;

	spin_lock_irqsave(&ch->ch_lock, flags);

	ch->ch_wopen++;

	while (1) {
		sleep_on_un_flags = 0;

		if (ch->ch_bd->state == BOARD_FAILED) {
			rc = -ENXIO;
			break;
		}

		if (tty_hung_up_p(file)) {
			rc = -EAGAIN;
			break;
		}

		/*
		 * If either unit is in the middle of the fragile part of close,
		 * we just cannot touch the channel safely.
		 * Go back to sleep, knowing that when the channel can be
		 * touched safely, the close routine will signal the
		 * ch_wait_flags to wake us back up.
		 */
		if (!((ch->ch_tun.un_flags |
		    ch->ch_pun.un_flags) &
		    UN_CLOSING)) {
			/*
			 * Our conditions to leave cleanly and happily:
			 * 1) NONBLOCKING on the tty is set.
			 * 2) CLOCAL is set.
			 * 3) DCD (fake or real) is active.
			 */

			if (file->f_flags & O_NONBLOCK)
				break;

			if (tty_io_error(tty)) {
				rc = -EIO;
				break;
			}

			if (ch->ch_flags & CH_CD)
				break;

			if (ch->ch_flags & CH_FCAR)
				break;
		} else {
			sleep_on_un_flags = 1;
		}

		/*
		 * If there is a signal pending, the user probably
		 * interrupted (ctrl-c) us.
		 */
		if (signal_pending(current)) {
			rc = -ERESTARTSYS;
			break;
		}

		if (sleep_on_un_flags)
			old_flags = ch->ch_tun.un_flags | ch->ch_pun.un_flags;
		else
			old_flags = ch->ch_flags;

		/*
		 * Let go of channel lock before calling schedule.
		 * Our poller will get any FEP events and wake us up when DCD
		 * eventually goes active.
		 */

		spin_unlock_irqrestore(&ch->ch_lock, flags);

		/*
		 * Wait for something in the flags to change
		 * from the current value.
		 */
		if (sleep_on_un_flags)
			rc = wait_event_interruptible
				(un->un_flags_wait,
				 (old_flags != (ch->ch_tun.un_flags |
						ch->ch_pun.un_flags)));
		else
			rc = wait_event_interruptible(
					ch->ch_flags_wait,
					(old_flags != ch->ch_flags));

		/*
		 * We got woken up for some reason.
		 * Before looping around, grab our channel lock.
		 */
		spin_lock_irqsave(&ch->ch_lock, flags);
	}

	ch->ch_wopen--;

	spin_unlock_irqrestore(&ch->ch_lock, flags);

	return rc;
}

/* Hangup the port.  Like a close, but don't wait for output to drain. */
static void dgnc_tty_hangup(struct tty_struct *tty)
{
	if (!tty)
		return;

	/* flush the transmit queues */
	dgnc_tty_flush_buffer(tty);
}

static void dgnc_tty_close(struct tty_struct *tty, struct file *file)
{
	struct dgnc_board *bd;
	struct channel_t *ch;
	struct un_t *un;
	unsigned long flags;

	if (!tty)
		return;

	un = tty->driver_data;
	if (!un)
		return;

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

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

	spin_lock_irqsave(&ch->ch_lock, flags);

	/*
	 * Determine if this is the last close or not - and if we agree about
	 * which type of close it is with the Line Discipline
	 */
	if ((tty->count == 1) && (un->un_open_count != 1)) {
		/*
		 * Uh, oh.  tty->count is 1, which means that the tty
		 * structure will be freed.  un_open_count should always
		 * be one in these conditions.  If it's greater than
		 * one, we've got real problems, since it means the
		 * serial port won't be shutdown.
		 */
		dev_dbg(tty->dev,
			"tty->count is 1, un open count is %d\n",
			un->un_open_count);
		un->un_open_count = 1;
	}

	if (un->un_open_count)
		un->un_open_count--;
	else
		dev_dbg(tty->dev,
			"bad serial port open count of %d\n",
			un->un_open_count);

	ch->ch_open_count--;

	if (ch->ch_open_count && un->un_open_count) {
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		return;
	}

	/* OK, its the last close on the unit */
	un->un_flags |= UN_CLOSING;

	tty->closing = 1;

	/*
	 * Only officially close channel if count is 0 and
	 * DIGI_PRINTER bit is not set.
	 */
	if ((ch->ch_open_count == 0) &&
	    !(ch->ch_digi.digi_flags & DIGI_PRINTER)) {
		ch->ch_flags &= ~(CH_STOPI | CH_FORCED_STOPI);

		/* turn off print device when closing print device. */

		if ((un->un_type == DGNC_PRINT) && (ch->ch_flags & CH_PRON)) {
			dgnc_wmove(ch, ch->ch_digi.digi_offstr,
				   (int)ch->ch_digi.digi_offlen);
			ch->ch_flags &= ~CH_PRON;
		}

		spin_unlock_irqrestore(&ch->ch_lock, flags);
		/* wait for output to drain */
		/* This will also return if we take an interrupt */

		bd->bd_ops->drain(tty, 0);

		dgnc_tty_flush_buffer(tty);
		tty_ldisc_flush(tty);

		spin_lock_irqsave(&ch->ch_lock, flags);

		tty->closing = 0;

		/* If we have HUPCL set, lower DTR and RTS */

		if (ch->ch_c_cflag & HUPCL) {
			/* Drop RTS/DTR */
			ch->ch_mostat &= ~(UART_MCR_DTR | UART_MCR_RTS);
			bd->bd_ops->assert_modem_signals(ch);

			/*
			 * Go to sleep to ensure RTS/DTR
			 * have been dropped for modems to see it.
			 */
			if (ch->ch_close_delay) {
				spin_unlock_irqrestore(&ch->ch_lock,
						       flags);
				dgnc_ms_sleep(ch->ch_close_delay);
				spin_lock_irqsave(&ch->ch_lock, flags);
			}
		}

		ch->ch_old_baud = 0;

		/* Turn off UART interrupts for this port */
		ch->ch_bd->bd_ops->uart_off(ch);
	} else {
		/* turn off print device when closing print device. */

		if ((un->un_type == DGNC_PRINT) && (ch->ch_flags & CH_PRON)) {
			dgnc_wmove(ch, ch->ch_digi.digi_offstr,
				   (int)ch->ch_digi.digi_offlen);
			ch->ch_flags &= ~CH_PRON;
		}
	}

	un->un_tty = NULL;
	un->un_flags &= ~(UN_ISOPEN | UN_CLOSING);

	wake_up_interruptible(&ch->ch_flags_wait);
	wake_up_interruptible(&un->un_flags_wait);

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

/*
 * Return number of characters that have not been transmitted yet.
 *
 * This routine is used by the line discipline to determine if there
 * is data waiting to be transmitted/drained/flushed or not.
 */
static int dgnc_tty_chars_in_buffer(struct tty_struct *tty)
{
	struct channel_t *ch = NULL;
	struct un_t *un = NULL;
	ushort thead;
	ushort ttail;
	uint tmask;
	uint chars;
	unsigned long flags;

	if (!tty)
		return 0;

	un = tty->driver_data;
	if (!un)
		return 0;

	ch = un->un_ch;
	if (!ch)
		return 0;

	spin_lock_irqsave(&ch->ch_lock, flags);

	tmask = WQUEUEMASK;
	thead = ch->ch_w_head & tmask;
	ttail = ch->ch_w_tail & tmask;

	spin_unlock_irqrestore(&ch->ch_lock, flags);

	if (ttail == thead)
		chars = 0;
	else if (thead > ttail)
		chars = thead - ttail;
	else
		chars = thead - ttail + WQUEUESIZE;

	return chars;
}

/*
 * Reduces bytes_available to the max number of characters
 * that can be sent currently given the maxcps value, and
 * returns the new bytes_available.  This only affects printer
 * output.
 */
static int dgnc_maxcps_room(struct channel_t *ch, int bytes_available)
{
	int rc = bytes_available;

	if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0) {
		int cps_limit = 0;
		unsigned long current_time = jiffies;
		unsigned long buffer_time = current_time +
			(HZ * ch->ch_digi.digi_bufsize) /
			ch->ch_digi.digi_maxcps;

		if (ch->ch_cpstime < current_time) {
			/* buffer is empty */
			ch->ch_cpstime = current_time;	/* reset ch_cpstime */
			cps_limit = ch->ch_digi.digi_bufsize;
		} else if (ch->ch_cpstime < buffer_time) {
			/* still room in the buffer */
			cps_limit = ((buffer_time - ch->ch_cpstime) *
					ch->ch_digi.digi_maxcps) / HZ;
		} else {
			/* no room in the buffer */
			cps_limit = 0;
		}

		rc = min(cps_limit, bytes_available);
	}

	return rc;
}

/* Return room available in Tx buffer */
static int dgnc_tty_write_room(struct tty_struct *tty)
{
	struct channel_t *ch = NULL;
	struct un_t *un = NULL;
	ushort head;
	ushort tail;
	ushort tmask;
	int room = 0;
	unsigned long flags;

	if (!tty)
		return 0;

	un = tty->driver_data;
	if (!un)
		return 0;

	ch = un->un_ch;
	if (!ch)
		return 0;

	spin_lock_irqsave(&ch->ch_lock, flags);

	tmask = WQUEUEMASK;
	head = (ch->ch_w_head) & tmask;
	tail = (ch->ch_w_tail) & tmask;

	room = tail - head - 1;
	if (room < 0)
		room += WQUEUESIZE;

	/* Limit printer to maxcps */
	if (un->un_type != DGNC_PRINT)
		room = dgnc_maxcps_room(ch, room);

	/*
	 * If we are printer device, leave room for
	 * possibly both the on and off strings.
	 */
	if (un->un_type == DGNC_PRINT) {
		if (!(ch->ch_flags & CH_PRON))
			room -= ch->ch_digi.digi_onlen;
		room -= ch->ch_digi.digi_offlen;
	} else {
		if (ch->ch_flags & CH_PRON)
			room -= ch->ch_digi.digi_offlen;
	}

	if (room < 0)
		room = 0;

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

/*
 * Put a character into ch->ch_buf
 * Used by the line discipline for OPOST processing
 */
static int dgnc_tty_put_char(struct tty_struct *tty, unsigned char c)
{
	dgnc_tty_write(tty, &c, 1);
	return 1;
}

/*
 * Take data from the user or kernel and send it out to the FEP.
 * In here exists all the Transparent Print magic as well.
 */
static int dgnc_tty_write(struct tty_struct *tty,
			  const unsigned char *buf, int count)
{
	struct channel_t *ch = NULL;
	struct un_t *un = NULL;
	int bufcount = 0, n = 0;
	unsigned long flags;
	ushort head;
	ushort tail;
	ushort tmask;
	uint remain;

	if (!tty)
		return 0;

	un = tty->driver_data;
	if (!un)
		return 0;

	ch = un->un_ch;
	if (!ch)
		return 0;

	if (!count)
		return 0;

	/*
	 * Store original amount of characters passed in.
	 * This helps to figure out if we should ask the FEP
	 * to send us an event when it has more space available.
	 */

	spin_lock_irqsave(&ch->ch_lock, flags);

	tmask = WQUEUEMASK;
	head = (ch->ch_w_head) & tmask;
	tail = (ch->ch_w_tail) & tmask;

	bufcount = tail - head - 1;
	if (bufcount < 0)
		bufcount += WQUEUESIZE;

	/*
	 * Limit printer output to maxcps overall, with bursts allowed
	 * up to bufsize characters.
	 */
	if (un->un_type != DGNC_PRINT)
		bufcount = dgnc_maxcps_room(ch, bufcount);

	count = min(count, bufcount);
	if (count <= 0)
		goto exit_retry;

	/*
	 * Output the printer ON string, if we are in terminal mode, but
	 * need to be in printer mode.
	 */
	if ((un->un_type == DGNC_PRINT) && !(ch->ch_flags & CH_PRON)) {
		dgnc_wmove(ch, ch->ch_digi.digi_onstr,
			   (int)ch->ch_digi.digi_onlen);
		head = (ch->ch_w_head) & tmask;
		ch->ch_flags |= CH_PRON;
	}

	/*
	 * On the other hand, output the printer OFF string, if we are
	 * currently in printer mode, but need to output to the terminal.
	 */
	if ((un->un_type != DGNC_PRINT) && (ch->ch_flags & CH_PRON)) {
		dgnc_wmove(ch, ch->ch_digi.digi_offstr,
			   (int)ch->ch_digi.digi_offlen);
		head = (ch->ch_w_head) & tmask;
		ch->ch_flags &= ~CH_PRON;
	}

	n = count;

	/*
	 * If the write wraps over the top of the circular buffer,
	 * move the portion up to the wrap point, and reset the
	 * pointers to the bottom.
	 */
	remain = WQUEUESIZE - head;

	if (n >= remain) {
		n -= remain;
		memcpy(ch->ch_wqueue + head, buf, remain);
		head = 0;
		buf += remain;
	}

	if (n > 0) {
		/* Move rest of data. */
		remain = n;
		memcpy(ch->ch_wqueue + head, buf, remain);
		head += remain;
	}

	if (count) {
		head &= tmask;
		ch->ch_w_head = head;
	}

	/* Update printer buffer empty time. */
	if ((un->un_type == DGNC_PRINT) && (ch->ch_digi.digi_maxcps > 0) &&
	    (ch->ch_digi.digi_bufsize > 0)) {
		ch->ch_cpstime += (HZ * count) / ch->ch_digi.digi_maxcps;
	}

	spin_unlock_irqrestore(&ch->ch_lock, flags);

	if (count)
		ch->ch_bd->bd_ops->copy_data_from_queue_to_uart(ch);

	return count;

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

	return 0;
}

/* Return modem signals to ld. */
static int dgnc_tty_tiocmget(struct tty_struct *tty)
{
	struct channel_t *ch;
	struct un_t *un;
	int rc;
	unsigned char mstat = 0;
	unsigned long flags;

	if (!tty)
		return -EIO;

	un = tty->driver_data;
	if (!un)
		return -EIO;

	ch = un->un_ch;
	if (!ch)
		return -EIO;

	spin_lock_irqsave(&ch->ch_lock, flags);

	mstat = ch->ch_mostat | ch->ch_mistat;

	spin_unlock_irqrestore(&ch->ch_lock, flags);

	rc = 0;

	if (mstat & UART_MCR_DTR)
		rc |= TIOCM_DTR;
	if (mstat & UART_MCR_RTS)
		rc |= TIOCM_RTS;
	if (mstat & UART_MSR_CTS)
		rc |= TIOCM_CTS;
	if (mstat & UART_MSR_DSR)
		rc |= TIOCM_DSR;
	if (mstat & UART_MSR_RI)
		rc |= TIOCM_RI;
	if (mstat & UART_MSR_DCD)
		rc |= TIOCM_CD;

	return rc;
}

/* Set modem signals, called by ld. */
static int dgnc_tty_tiocmset(struct tty_struct *tty,
			     unsigned int set, unsigned int clear)
{
	struct dgnc_board *bd;
	struct channel_t *ch;
	struct un_t *un;
	unsigned long flags;

	if (!tty)
		return -EIO;

	un = tty->driver_data;
	if (!un)
		return -EIO;

	ch = un->un_ch;
	if (!ch)
		return -EIO;

	bd = ch->ch_bd;
	if (!bd)
		return -EIO;

	spin_lock_irqsave(&ch->ch_lock, flags);

	if (set & TIOCM_RTS)
		ch->ch_mostat |= UART_MCR_RTS;

	if (set & TIOCM_DTR)
		ch->ch_mostat |= UART_MCR_DTR;

	if (clear & TIOCM_RTS)
		ch->ch_mostat &= ~(UART_MCR_RTS);

	if (clear & TIOCM_DTR)
		ch->ch_mostat &= ~(UART_MCR_DTR);

	bd->bd_ops->assert_modem_signals(ch);

	spin_unlock_irqrestore(&ch->ch_lock, flags);

	return 0;
}

/* Send a Break, called by ld. */
static int dgnc_tty_send_break(struct tty_struct *tty, int msec)
{
	struct dgnc_board *bd;
	struct channel_t *ch;
	struct un_t *un;
	unsigned long flags;

	if (!tty)
		return -EIO;

	un = tty->driver_data;
	if (!un)
		return -EIO;

	ch = un->un_ch;
	if (!ch)
		return -EIO;

	bd = ch->ch_bd;
	if (!bd)
		return -EIO;

	if (msec < 0)
		msec = 0xFFFF;

	spin_lock_irqsave(&ch->ch_lock, flags);

	bd->bd_ops->send_break(ch, msec);

	spin_unlock_irqrestore(&ch->ch_lock, flags);

	return 0;
}

/* wait until data has been transmitted, called by ld. */
static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout)
{
	struct dgnc_board *bd;
	struct channel_t *ch;
	struct un_t *un;

	if (!tty)
		return;

	un = tty->driver_data;
	if (!un)
		return;

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

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

	bd->bd_ops->drain(tty, 0);
}

/* send a high priority character, called by ld. */
static void dgnc_tty_send_xchar(struct tty_struct *tty, char c)
{
	struct dgnc_board *bd;
	struct channel_t *ch;
	struct un_t *un;
	unsigned long flags;

	if (!tty)
		return;

	un = tty->driver_data;
	if (!un)
		return;

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

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

	spin_lock_irqsave(&ch->ch_lock, flags);
	bd->bd_ops->send_immediate_char(ch, c);
	spin_unlock_irqrestore(&ch->ch_lock, flags);
}

/* Return modem signals to ld. */
static inline int dgnc_get_mstat(struct channel_t *ch)
{
	unsigned char mstat;
	unsigned long flags;
	int rc;

	if (!ch)
		return -ENXIO;

	spin_lock_irqsave(&ch->ch_lock, flags);

	mstat = ch->ch_mostat | ch->ch_mistat;

	spin_unlock_irqrestore(&ch->ch_lock, flags);

	rc = 0;

	if (mstat & UART_MCR_DTR)
		rc |= TIOCM_DTR;
	if (mstat & UART_MCR_RTS)
		rc |= TIOCM_RTS;
	if (mstat & UART_MSR_CTS)
		rc |= TIOCM_CTS;
	if (mstat & UART_MSR_DSR)
		rc |= TIOCM_DSR;
	if (mstat & UART_MSR_RI)
		rc |= TIOCM_RI;
	if (mstat & UART_MSR_DCD)
		rc |= TIOCM_CD;

	return rc;
}

/* Return modem signals to ld. */
static int dgnc_get_modem_info(struct channel_t *ch,
			       unsigned int  __user *value)
{
	return put_user(dgnc_get_mstat(ch), value);
}

/* Set modem signals, called by ld. */
static int dgnc_set_modem_info(struct channel_t *ch,
			       unsigned int command,
			       unsigned int __user *value)
{
	int rc;
	unsigned int arg = 0;
	unsigned long flags;

	rc = get_user(arg, value);
	if (rc)
		return rc;

	switch (command) {
	case TIOCMBIS:
		if (arg & TIOCM_RTS)
			ch->ch_mostat |= UART_MCR_RTS;

		if (arg & TIOCM_DTR)
			ch->ch_mostat |= UART_MCR_DTR;

		break;

	case TIOCMBIC:
		if (arg & TIOCM_RTS)
			ch->ch_mostat &= ~(UART_MCR_RTS);

		if (arg & TIOCM_DTR)
			ch->ch_mostat &= ~(UART_MCR_DTR);

		break;

	case TIOCMSET:

		if (arg & TIOCM_RTS)
			ch->ch_mostat |= UART_MCR_RTS;
		else
			ch->ch_mostat &= ~(UART_MCR_RTS);

		if (arg & TIOCM_DTR)
			ch->ch_mostat |= UART_MCR_DTR;
		else
			ch->ch_mostat &= ~(UART_MCR_DTR);

		break;

	default:
		return -EINVAL;
	}

	spin_lock_irqsave(&ch->ch_lock, flags);

	ch->ch_bd->bd_ops->assert_modem_signals(ch);

	spin_unlock_irqrestore(&ch->ch_lock, flags);

	return 0;
}

/* Ioctl to get the information for ditty. */
static int dgnc_tty_digigeta(struct tty_struct *tty,
			     struct digi_t __user *retinfo)
{
	struct channel_t *ch;
	struct un_t *un;
	struct digi_t tmp;
	unsigned long flags;

	if (!retinfo)
		return -EFAULT;

	if (!tty)
		return -EFAULT;

	un = tty->driver_data;
	if (!un)
		return -EFAULT;

	ch = un->un_ch;
	if (!ch)
		return -EFAULT;

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

	spin_lock_irqsave(&ch->ch_lock, flags);
	memcpy(&tmp, &ch->ch_digi, sizeof(tmp));
	spin_unlock_irqrestore(&ch->ch_lock, flags);

	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
		return -EFAULT;

	return 0;
}

/* Ioctl to set the information for ditty. */
static int dgnc_tty_digiseta(struct tty_struct *tty,
			     struct digi_t __user *new_info)
{
	struct dgnc_board *bd;
	struct channel_t *ch;
	struct un_t *un;
	struct digi_t new_digi;
	unsigned long flags;

	if (!tty)
		return -EFAULT;

	un = tty->driver_data;
	if (!un)
		return -EFAULT;

	ch = un->un_ch;
	if (!ch)
		return -EFAULT;

	bd = ch->ch_bd;
	if (!bd)
		return -EFAULT;

	if (copy_from_user(&new_digi, new_info, sizeof(new_digi)))
		return -EFAULT;

	spin_lock_irqsave(&ch->ch_lock, flags);

	/* Handle transitions to and from RTS Toggle. */

	if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) &&
	    (new_digi.digi_flags & DIGI_RTS_TOGGLE))
		ch->ch_mostat &= ~(UART_MCR_RTS);
	if ((ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) &&
	    !(new_digi.digi_flags & DIGI_RTS_TOGGLE))
		ch->ch_mostat |= (UART_MCR_RTS);

	/* Handle transitions to and from DTR Toggle. */

	if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) &&
	    (new_digi.digi_flags & DIGI_DTR_TOGGLE))
		ch->ch_mostat &= ~(UART_MCR_DTR);
	if ((ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) &&
	    !(new_digi.digi_flags & DIGI_DTR_TOGGLE))
		ch->ch_mostat |= (UART_MCR_DTR);

	memcpy(&ch->ch_digi, &new_digi, sizeof(new_digi));

	if (ch->ch_digi.digi_maxcps < 1)
		ch->ch_digi.digi_maxcps = 1;

	if (ch->ch_digi.digi_maxcps > 10000)
		ch->ch_digi.digi_maxcps = 10000;

	if (ch->ch_digi.digi_bufsize < 10)
		ch->ch_digi.digi_bufsize = 10;

	if (ch->ch_digi.digi_maxchar < 1)
		ch->ch_digi.digi_maxchar = 1;

	if (ch->ch_digi.digi_maxchar > ch->ch_digi.digi_bufsize)
		ch->ch_digi.digi_maxchar = ch->ch_digi.digi_bufsize;

	if (ch->ch_digi.digi_onlen > DIGI_PLEN)
		ch->ch_digi.digi_onlen = DIGI_PLEN;

	if (ch->ch_digi.digi_offlen > DIGI_PLEN)
		ch->ch_digi.digi_offlen = DIGI_PLEN;

	bd->bd_ops->param(tty);

	spin_unlock_irqrestore(&ch->ch_lock, flags);

	return 0;
}

static void dgnc_tty_set_termios(struct tty_struct *tty,
				 struct ktermios *old_termios)
{
	struct dgnc_board *bd;
	struct channel_t *ch;
	struct un_t *un;
	unsigned long flags;

	if (!tty)
		return;

	un = tty->driver_data;
	if (!un)
		return;

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

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

	spin_lock_irqsave(&ch->ch_lock, flags);

	ch->ch_c_cflag   = tty->termios.c_cflag;
	ch->ch_c_iflag   = tty->termios.c_iflag;
	ch->ch_c_oflag   = tty->termios.c_oflag;
	ch->ch_c_lflag   = tty->termios.c_lflag;
	ch->ch_startc = tty->termios.c_cc[VSTART];
	ch->ch_stopc  = tty->termios.c_cc[VSTOP];

	bd->bd_ops->param(tty);
	dgnc_carrier(ch);

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

static void dgnc_tty_throttle(struct tty_struct *tty)
{
	struct channel_t *ch;
	struct un_t *un;
	unsigned long flags;

	if (!tty)
		return;

	un = tty->driver_data;
	if (!un)
		return;

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

	spin_lock_irqsave(&ch->ch_lock, flags);

	ch->ch_flags |= (CH_FORCED_STOPI);

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

static void dgnc_tty_unthrottle(struct tty_struct *tty)
{
	struct channel_t *ch;
	struct un_t *un;
	unsigned long flags;

	if (!tty)
		return;

	un = tty->driver_data;
	if (!un)
		return;

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

	spin_lock_irqsave(&ch->ch_lock, flags);

	ch->ch_flags &= ~(CH_FORCED_STOPI);

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

static void dgnc_tty_start(struct tty_struct *tty)
{
	struct dgnc_board *bd;
	struct channel_t *ch;
	struct un_t *un;
	unsigned long flags;

	if (!tty)
		return;

	un = tty->driver_data;
	if (!un)
		return;

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

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

	spin_lock_irqsave(&ch->ch_lock, flags);

	ch->ch_flags &= ~(CH_FORCED_STOP);

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

static void dgnc_tty_stop(struct tty_struct *tty)
{
	struct dgnc_board *bd;
	struct channel_t *ch;
	struct un_t *un;
	unsigned long flags;

	if (!tty)
		return;

	un = tty->driver_data;
	if (!un)
		return;

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

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

	spin_lock_irqsave(&ch->ch_lock, flags);

	ch->ch_flags |= (CH_FORCED_STOP);

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

/*
 * Flush the cook buffer
 *
 * Note to self, and any other poor souls who venture here:
 *
 * flush in this case DOES NOT mean dispose of the data.
 * instead, it means "stop buffering and send it if you
 * haven't already."  Just guess how I figured that out...   SRW 2-Jun-98
 *
 * It is also always called in interrupt context - JAR 8-Sept-99
 */
static void dgnc_tty_flush_chars(struct tty_struct *tty)
{
	struct dgnc_board *bd;
	struct channel_t *ch;
	struct un_t *un;
	unsigned long flags;

	if (!tty)
		return;

	un = tty->driver_data;
	if (!un)
		return;

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

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

	spin_lock_irqsave(&ch->ch_lock, flags);

	/* Do something maybe here */

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

/* Flush Tx buffer (make in == out) */
static void dgnc_tty_flush_buffer(struct tty_struct *tty)
{
	struct channel_t *ch;
	struct un_t *un;
	unsigned long flags;

	if (!tty)
		return;

	un = tty->driver_data;
	if (!un)
		return;

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

	spin_lock_irqsave(&ch->ch_lock, flags);

	ch->ch_flags &= ~CH_STOP;

	/* Flush our write queue */
	ch->ch_w_head = ch->ch_w_tail;

	/* Flush UARTs transmit FIFO */
	ch->ch_bd->bd_ops->flush_uart_write(ch);

	if (ch->ch_tun.un_flags & (UN_LOW | UN_EMPTY)) {
		ch->ch_tun.un_flags &= ~(UN_LOW | UN_EMPTY);
		wake_up_interruptible(&ch->ch_tun.un_flags_wait);
	}
	if (ch->ch_pun.un_flags & (UN_LOW | UN_EMPTY)) {
		ch->ch_pun.un_flags &= ~(UN_LOW | UN_EMPTY);
		wake_up_interruptible(&ch->ch_pun.un_flags_wait);
	}

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

/* Wakes up processes waiting in the unit's (teminal/printer) wait queue */
static void dgnc_wake_up_unit(struct un_t *unit)
{
	unit->un_flags &= ~(UN_LOW | UN_EMPTY);
	wake_up_interruptible(&unit->un_flags_wait);
}

/* The IOCTL function and all of its helpers */

/* The usual assortment of ioctl's */
static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
			  unsigned long arg)
{
	struct dgnc_board *bd;
	struct board_ops *ch_bd_ops;
	struct channel_t *ch;
	struct un_t *un;
	int rc;
	unsigned long flags;
	void __user *uarg = (void __user *)arg;

	if (!tty)
		return -ENODEV;

	un = tty->driver_data;
	if (!un)
		return -ENODEV;

	ch = un->un_ch;
	if (!ch)
		return -ENODEV;

	bd = ch->ch_bd;
	if (!bd)
		return -ENODEV;

	ch_bd_ops = bd->bd_ops;

	spin_lock_irqsave(&ch->ch_lock, flags);

	if (un->un_open_count <= 0) {
		rc = -EIO;
		goto err_unlock;
	}

	switch (cmd) {
	/* Here are all the standard ioctl's that we MUST implement */

	case TCSBRK:
		/*
		 * TCSBRK is SVID version: non-zero arg --> no break
		 * this behaviour is exploited by tcdrain().
		 *
		 * According to POSIX.1 spec (7.2.2.1.2) breaks should be
		 * between 0.25 and 0.5 seconds so we'll ask for something
		 * in the middle: 0.375 seconds.
		 */
		rc = tty_check_change(tty);
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		if (rc)
			return rc;

		rc = ch_bd_ops->drain(tty, 0);
		if (rc)
			return -EINTR;

		spin_lock_irqsave(&ch->ch_lock, flags);

		if (((cmd == TCSBRK) && (!arg)) || (cmd == TCSBRKP))
			ch_bd_ops->send_break(ch, 250);

		spin_unlock_irqrestore(&ch->ch_lock, flags);

		return 0;

	case TCSBRKP:
		/*
		 * support for POSIX tcsendbreak()
		 * According to POSIX.1 spec (7.2.2.1.2) breaks should be
		 * between 0.25 and 0.5 seconds so we'll ask for something
		 * in the middle: 0.375 seconds.
		 */
		rc = tty_check_change(tty);
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		if (rc)
			return rc;

		rc = ch_bd_ops->drain(tty, 0);
		if (rc)
			return -EINTR;

		spin_lock_irqsave(&ch->ch_lock, flags);

		ch_bd_ops->send_break(ch, 250);

		spin_unlock_irqrestore(&ch->ch_lock, flags);

		return 0;

	case TIOCSBRK:
		rc = tty_check_change(tty);
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		if (rc)
			return rc;

		rc = ch_bd_ops->drain(tty, 0);
		if (rc)
			return -EINTR;

		spin_lock_irqsave(&ch->ch_lock, flags);

		ch_bd_ops->send_break(ch, 250);

		spin_unlock_irqrestore(&ch->ch_lock, flags);

		return 0;

	case TIOCCBRK:
		/* Do Nothing */
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		return 0;

	case TIOCGSOFTCAR:

		spin_unlock_irqrestore(&ch->ch_lock, flags);

		return put_user(C_CLOCAL(tty) ? 1 : 0,
				(unsigned long __user *)arg);

	case TIOCSSOFTCAR:

		spin_unlock_irqrestore(&ch->ch_lock, flags);
		rc = get_user(arg, (unsigned long __user *)arg);
		if (rc)
			return rc;

		spin_lock_irqsave(&ch->ch_lock, flags);
		tty->termios.c_cflag = ((tty->termios.c_cflag & ~CLOCAL) |
				       (arg ? CLOCAL : 0));
		ch_bd_ops->param(tty);
		spin_unlock_irqrestore(&ch->ch_lock, flags);

		return 0;

	case TIOCMGET:
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		return dgnc_get_modem_info(ch, uarg);

	case TIOCMBIS:
	case TIOCMBIC:
	case TIOCMSET:
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		return dgnc_set_modem_info(ch, cmd, uarg);

		/* Here are any additional ioctl's that we want to implement */

	case TCFLSH:
		/*
		 * The linux tty driver doesn't have a flush
		 * input routine for the driver, assuming all backed
		 * up data is in the line disc. buffers.  However,
		 * we all know that's not the case.  Here, we
		 * act on the ioctl, but then lie and say we didn't
		 * so the line discipline will process the flush
		 * also.
		 */
		rc = tty_check_change(tty);
		if (rc)
			goto err_unlock;

		if ((arg == TCIFLUSH) || (arg == TCIOFLUSH)) {
			ch->ch_r_head = ch->ch_r_tail;
			ch_bd_ops->flush_uart_read(ch);
			/* Force queue flow control to be released, if needed */
			dgnc_check_queue_flow_control(ch);
		}

		if ((arg == TCOFLUSH) || (arg == TCIOFLUSH)) {
			if (!(un->un_type == DGNC_PRINT)) {
				ch->ch_w_head = ch->ch_w_tail;
				ch_bd_ops->flush_uart_write(ch);

				if (ch->ch_tun.un_flags & (UN_LOW | UN_EMPTY))
					dgnc_wake_up_unit(&ch->ch_tun);

				if (ch->ch_pun.un_flags & (UN_LOW | UN_EMPTY))
					dgnc_wake_up_unit(&ch->ch_pun);
			}
		}

		/* pretend we didn't recognize this IOCTL */
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		return -ENOIOCTLCMD;
	case TCSETSF:
	case TCSETSW:
		/*
		 * The linux tty driver doesn't have a flush
		 * input routine for the driver, assuming all backed
		 * up data is in the line disc. buffers.  However,
		 * we all know that's not the case.  Here, we
		 * act on the ioctl, but then lie and say we didn't
		 * so the line discipline will process the flush
		 * also.
		 */
		if (cmd == TCSETSF) {
			/* flush rx */
			ch->ch_flags &= ~CH_STOP;
			ch->ch_r_head = ch->ch_r_tail;
			ch_bd_ops->flush_uart_read(ch);
			/* Force queue flow control to be released, if needed */
			dgnc_check_queue_flow_control(ch);
		}

		/* now wait for all the output to drain */
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		rc = ch_bd_ops->drain(tty, 0);
		if (rc)
			return -EINTR;

		/* pretend we didn't recognize this */
		return -ENOIOCTLCMD;

	case TCSETAW:

		spin_unlock_irqrestore(&ch->ch_lock, flags);
		rc = ch_bd_ops->drain(tty, 0);
		if (rc)
			return -EINTR;

		/* pretend we didn't recognize this */
		return -ENOIOCTLCMD;

	case TCXONC:
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		/* Make the ld do it */
		return -ENOIOCTLCMD;

	case DIGI_GETA:
		/* get information for ditty */
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		return dgnc_tty_digigeta(tty, uarg);

	case DIGI_SETAW:
	case DIGI_SETAF:

		/* set information for ditty */
		if (cmd == (DIGI_SETAW)) {
			spin_unlock_irqrestore(&ch->ch_lock, flags);
			rc = ch_bd_ops->drain(tty, 0);
			if (rc)
				return -EINTR;

			spin_lock_irqsave(&ch->ch_lock, flags);
		} else {
			tty_ldisc_flush(tty);
		}
		/* fall thru */

	case DIGI_SETA:
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		return dgnc_tty_digiseta(tty, uarg);

	case DIGI_LOOPBACK:
		{
			uint loopback = 0;
			/*
			 * Let go of locks when accessing user space,
			 * could sleep
			 */
			spin_unlock_irqrestore(&ch->ch_lock, flags);
			rc = get_user(loopback, (unsigned int __user *)arg);
			if (rc)
				return rc;
			spin_lock_irqsave(&ch->ch_lock, flags);

			/* Enable/disable internal loopback for this port */
			if (loopback)
				ch->ch_flags |= CH_LOOPBACK;
			else
				ch->ch_flags &= ~(CH_LOOPBACK);

			ch_bd_ops->param(tty);
			spin_unlock_irqrestore(&ch->ch_lock, flags);
			return 0;
		}

	case DIGI_GETCUSTOMBAUD:
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		return put_user(ch->ch_custom_speed,
				(unsigned int __user *)arg);

	case DIGI_SETCUSTOMBAUD:
	{
		int new_rate;

		spin_unlock_irqrestore(&ch->ch_lock, flags);
		rc = get_user(new_rate, (int __user *)arg);
		if (rc)
			return rc;
		spin_lock_irqsave(&ch->ch_lock, flags);
		dgnc_set_custom_speed(ch, new_rate);
		ch_bd_ops->param(tty);
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		return 0;
	}

	/*
	 * This ioctl allows insertion of a character into the front
	 * of any pending data to be transmitted.
	 *
	 * This ioctl is to satisfy the "Send Character Immediate"
	 * call that the RealPort protocol spec requires.
	 */
	case DIGI_REALPORT_SENDIMMEDIATE:
	{
		unsigned char c;

		spin_unlock_irqrestore(&ch->ch_lock, flags);
		rc = get_user(c, (unsigned char __user *)arg);
		if (rc)
			return rc;
		spin_lock_irqsave(&ch->ch_lock, flags);
		ch_bd_ops->send_immediate_char(ch, c);
		spin_unlock_irqrestore(&ch->ch_lock, flags);
		return 0;
	}

	/*
	 * This ioctl returns all the current counts for the port.
	 *
	 * This ioctl is to satisfy the "Line Error Counters"
	 * call that the RealPort protocol spec requires.
	 */
	case DIGI_REALPORT_GETCOUNTERS:
	{
		struct digi_getcounter buf;

		buf.norun = ch->ch_err_overrun;
		buf.noflow = 0;		/* The driver doesn't keep this stat */
		buf.nframe = ch->ch_err_frame;
		buf.nparity = ch->ch_err_parity;
		buf.nbreak = ch->ch_err_break;
		buf.rbytes = ch->ch_rxcount;
		buf.tbytes = ch->ch_txcount;

		spin_unlock_irqrestore(&ch->ch_lock, flags);

		if (copy_to_user(uarg, &buf, sizeof(buf)))
			return -EFAULT;

		return 0;
	}

	/*
	 * This ioctl returns all current events.
	 *
	 * This ioctl is to satisfy the "Event Reporting"
	 * call that the RealPort protocol spec requires.
	 */
	case DIGI_REALPORT_GETEVENTS:
	{
		unsigned int events = 0;

		/* NOTE: MORE EVENTS NEEDS TO BE ADDED HERE */
		if (ch->ch_flags & CH_BREAK_SENDING)
			events |= EV_TXB;
		if ((ch->ch_flags & CH_STOP) ||
		    (ch->ch_flags & CH_FORCED_STOP))
			events |= (EV_OPU | EV_OPS);

		if ((ch->ch_flags & CH_STOPI) ||
		    (ch->ch_flags & CH_FORCED_STOPI))
			events |= (EV_IPU | EV_IPS);

		spin_unlock_irqrestore(&ch->ch_lock, flags);
		return put_user(events, (unsigned int __user *)arg);
	}

	/*
	 * This ioctl returns TOUT and TIN counters based
	 * upon the values passed in by the RealPort Server.
	 * It also passes back whether the UART Transmitter is
	 * empty as well.
	 */
	case DIGI_REALPORT_GETBUFFERS:
	{
		struct digi_getbuffer buf;
		int tdist;
		int count;

		spin_unlock_irqrestore(&ch->ch_lock, flags);

		if (copy_from_user(&buf, uarg, sizeof(buf)))
			return -EFAULT;

		spin_lock_irqsave(&ch->ch_lock, flags);

		/* Figure out how much data is in our RX and TX queues. */

		buf.rxbuf = (ch->ch_r_head - ch->ch_r_tail) & RQUEUEMASK;
		buf.txbuf = (ch->ch_w_head - ch->ch_w_tail) & WQUEUEMASK;

		/*
		 * Is the UART empty?
		 * Add that value to whats in our TX queue.
		 */

		count = buf.txbuf + ch_bd_ops->get_uart_bytes_left(ch);

		/*
		 * Figure out how much data the RealPort Server believes should
		 * be in our TX queue.
		 */
		tdist = (buf.tx_in - buf.tx_out) & 0xffff;

		/*
		 * If we have more data than the RealPort Server believes we
		 * should have, reduce our count to its amount.
		 *
		 * This count difference CAN happen because the Linux LD can
		 * insert more characters into our queue for OPOST processing
		 * that the RealPort Server doesn't know about.
		 */
		if (buf.txbuf > tdist)
			buf.txbuf = tdist;

		/* Report whether our queue and UART TX are completely empty. */

		if (count)
			buf.txdone = 0;
		else
			buf.txdone = 1;

		spin_unlock_irqrestore(&ch->ch_lock, flags);

		if (copy_to_user(uarg, &buf, sizeof(buf)))
			return -EFAULT;

		return 0;
	}
	default:
		spin_unlock_irqrestore(&ch->ch_lock, flags);

		return -ENOIOCTLCMD;
	}
err_unlock:
	spin_unlock_irqrestore(&ch->ch_lock, flags);

	return rc;
}
