/*
 *
 * Copyright 1999 Digi International (www.digi.com)
 *     Gene Olson    <Gene_Olson at digi dot com>
 *     James Puzzo   <jamesp at digi dot com>
 *     Jeff Randall
 *     Scott Kilau   <scottk 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.
 *
 */

/*
 *
 *  Filename:
 *
 *     dgrp_tty.c
 *
 *  Description:
 *
 *     This file implements the tty driver functionality for the
 *     RealPort driver software.
 *
 *  Author:
 *
 *     James A. Puzzo
 *     Ann-Marie Westgate
 *
 */

#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/sched.h>
#include <linux/uaccess.h>

#include "dgrp_common.h"

#ifndef _POSIX_VDISABLE
#define   _POSIX_VDISABLE ('\0')
#endif

/*
 *	forward declarations
 */

static void drp_param(struct ch_struct *);
static void dgrp_tty_close(struct tty_struct *, struct file *);

/* ioctl helper functions */
static int set_modem_info(struct ch_struct *, unsigned int, unsigned int *);
static int get_modem_info(struct ch_struct *, unsigned int *);
static void dgrp_set_custom_speed(struct ch_struct *, int);
static int dgrp_tty_digigetedelay(struct tty_struct *, int *);
static int dgrp_tty_digisetedelay(struct tty_struct *, int *);
static int dgrp_send_break(struct ch_struct *, int);

static ushort  tty_to_ch_flags(struct tty_struct *, char);
static tcflag_t ch_to_tty_flags(unsigned short, char);

static void dgrp_tty_input_start(struct tty_struct *);
static void dgrp_tty_input_stop(struct tty_struct *);

static void drp_wmove(struct ch_struct *, int, void*, int);

static int dgrp_tty_open(struct tty_struct *, struct file *);
static void dgrp_tty_close(struct tty_struct *, struct file *);
static int dgrp_tty_write(struct tty_struct *, const unsigned char *, int);
static int dgrp_tty_write_room(struct tty_struct *);
static void dgrp_tty_flush_buffer(struct tty_struct *);
static int dgrp_tty_chars_in_buffer(struct tty_struct *);
static int dgrp_tty_ioctl(struct tty_struct *, unsigned int, unsigned long);
static void dgrp_tty_set_termios(struct tty_struct *, struct ktermios *);
static void dgrp_tty_stop(struct tty_struct *);
static void dgrp_tty_start(struct tty_struct *);
static void dgrp_tty_throttle(struct tty_struct *);
static void dgrp_tty_unthrottle(struct tty_struct *);
static void dgrp_tty_hangup(struct tty_struct *);
static int dgrp_tty_put_char(struct tty_struct *, unsigned char);
static int dgrp_tty_tiocmget(struct tty_struct *);
static int dgrp_tty_tiocmset(struct tty_struct *, unsigned int, unsigned int);
static int dgrp_tty_send_break(struct tty_struct *, int);
static void dgrp_tty_send_xchar(struct tty_struct *, char);

/*
 *	tty defines
 */
#define	SERIAL_TYPE_NORMAL	1
#define	SERIAL_TYPE_CALLOUT	2
#define	SERIAL_TYPE_XPRINT	3


/*
 *	tty globals/statics
 */


#define PORTSERVER_DIVIDEND	1843200

/*
 *  Default transparent print information.
 */
static struct digi_struct 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 struct ktermios DefaultTermios = {
	.c_iflag = (ICRNL | IXON),
	.c_oflag = (OPOST | ONLCR),
	.c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL),
	.c_lflag = (ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL
		    | ECHOKE | IEXTEN),
	.c_cc    = INIT_C_CC,
	.c_line  = 0,
};

/* Define our tty operations struct */
static const struct tty_operations dgrp_tty_ops = {
	.open            = dgrp_tty_open,
	.close           = dgrp_tty_close,
	.write           = dgrp_tty_write,
	.write_room      = dgrp_tty_write_room,
	.flush_buffer    = dgrp_tty_flush_buffer,
	.chars_in_buffer = dgrp_tty_chars_in_buffer,
	.flush_chars     = NULL,
	.ioctl           = dgrp_tty_ioctl,
	.set_termios     = dgrp_tty_set_termios,
	.stop            = dgrp_tty_stop,
	.start           = dgrp_tty_start,
	.throttle        = dgrp_tty_throttle,
	.unthrottle      = dgrp_tty_unthrottle,
	.hangup          = dgrp_tty_hangup,
	.put_char        = dgrp_tty_put_char,
	.tiocmget        = dgrp_tty_tiocmget,
	.tiocmset        = dgrp_tty_tiocmset,
	.break_ctl       = dgrp_tty_send_break,
	.send_xchar      = dgrp_tty_send_xchar
};


static int calc_baud_rate(struct un_struct *un)
{
	int i;
	int brate;

	struct baud_rates {
		unsigned int rate;
		unsigned int cflag;
	};

	static struct baud_rates baud_rates[] = {
		{ 921600, B921600 },
		{ 460800, B460800 },
		{ 230400, B230400 },
		{ 115200, B115200 },
		{  57600, B57600  },
		{  38400, B38400  },
		{  19200, B19200  },
		{   9600, B9600   },
		{   4800, B4800   },
		{   2400, B2400   },
		{   1200, B1200   },
		{    600, B600    },
		{    300, B300    },
		{    200, B200    },
		{    150, B150    },
		{    134, B134    },
		{    110, B110    },
		{     75, B75     },
		{     50, B50     },
		{      0, B9600  }
	};

	brate = C_BAUD(un->un_tty);

	for (i = 0; baud_rates[i].rate; i++) {
		if (baud_rates[i].cflag == brate)
			break;
	}

	return baud_rates[i].rate;
}

static int calc_fastbaud_rate(struct un_struct *un, struct ktermios *uts)
{
	int i;
	int brate;

	ulong bauds[2][16] = {
		{ /* 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 }
	};

	brate = C_BAUD(un->un_tty) & 0xff;

	i = (uts->c_cflag & CBAUDEX) ? 1 : 0;


	if ((i >= 0) && (i < 2) && (brate >= 0) && (brate < 16))
		brate = bauds[i][brate];
	else
		brate = 0;

	return brate;
}

/**
 * drp_param() -- send parameter values to be sent to the node
 * @ch: channel structure of port to modify
 *
 * Interprets the tty and modem changes made by an application
 * program (by examining the termios structures) and sets up
 * parameter values to be sent to the node.
 */
static void drp_param(struct ch_struct *ch)
{
	struct nd_struct *nd;
	struct un_struct *un;
	int   brate;
	int   mflow;
	int   xflag;
	int   iflag;
	struct ktermios *tts, *pts, *uts;

	nd = ch->ch_nd;

	/*
	 *  If the terminal device is open, use it to set up all tty
	 *  modes and functions.  Otherwise use the printer device.
	 */

	if (ch->ch_tun.un_open_count) {

		un = &ch->ch_tun;
		tts = &ch->ch_tun.un_tty->termios;

		/*
		 *  If both devices are open, copy critical line
		 *  parameters from the tty device to the printer,
		 *  so that if the tty is closed, the printer will
		 *  continue without disruption.
		 */

		if (ch->ch_pun.un_open_count) {

			pts = &ch->ch_pun.un_tty->termios;

			pts->c_cflag ^=
				(pts->c_cflag ^ tts->c_cflag) &
				(CBAUD  | CSIZE | CSTOPB | CREAD | PARENB |
				 PARODD | HUPCL | CLOCAL);

			pts->c_iflag ^=
				(pts->c_iflag ^ tts->c_iflag) &
				(IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK |
				 ISTRIP | IXON   | IXANY  | IXOFF);

			pts->c_cc[VSTART] = tts->c_cc[VSTART];
			pts->c_cc[VSTOP] = tts->c_cc[VSTOP];
		}
	} else if (ch->ch_pun.un_open_count == 0) {
		pr_warn("%s - ch_pun.un_open_count shouldn't be 0\n",
		       __func__);
		return;
	} else {
		un = &ch->ch_pun;
	}

	uts = &un->un_tty->termios;

	/*
	 * Determine if FAST writes can be performed.
	 */

	if ((ch->ch_digi.digi_flags & DIGI_COOK) != 0 &&
	    (ch->ch_tun.un_open_count != 0)  &&
	    !((un->un_tty)->ldisc->ops->flags & LDISC_FLAG_DEFINED) &&
	    !(L_XCASE(un->un_tty))) {
		ch->ch_flag |= CH_FAST_WRITE;
	} else {
		ch->ch_flag &= ~CH_FAST_WRITE;
	}

	/*
	 *  If FAST writes can be performed, and OPOST is on in the
	 *  terminal device, do OPOST handling in the server.
	 */

	if ((ch->ch_flag & CH_FAST_WRITE) &&
	      O_OPOST(un->un_tty) != 0) {
		int oflag = tty_to_ch_flags(un->un_tty, 'o');

		/* add to ch_ocook any processing flags set in the termio */
		ch->ch_ocook |= oflag & (OF_OLCUC |
					 OF_ONLCR |
					 OF_OCRNL |
					 OF_ONLRET |
					 OF_TABDLY);

		/*
		 * the hpux driver clears any flags set in ch_ocook
		 * from the termios oflag.  It is STILL reported though
		 * by a TCGETA
		 */

		oflag = ch_to_tty_flags(ch->ch_ocook, 'o');
		uts->c_oflag &= ~oflag;

	} else {
		/* clear the ch->ch_ocook flag */
		int oflag = ch_to_tty_flags(ch->ch_ocook, 'o');
		uts->c_oflag |= oflag;
		ch->ch_ocook = 0;
	}

	ch->ch_oflag = ch->ch_ocook;


	ch->ch_flag &= ~CH_FAST_READ;

	/*
	 *  Generate channel flags
	 */

	if (C_BAUD(un->un_tty) == B0) {
		if (!(ch->ch_flag & CH_BAUD0)) {
			/* TODO : the HPUX driver flushes line */
			/* TODO : discipline, I assume I don't have to */

			ch->ch_tout = ch->ch_tin;
			ch->ch_rout = ch->ch_rin;

			ch->ch_break_time = 0;

			ch->ch_send |= RR_TX_FLUSH | RR_RX_FLUSH;

			ch->ch_mout &= ~(DM_DTR | DM_RTS);

			ch->ch_flag |= CH_BAUD0;
		}
	} else if (ch->ch_custom_speed) {
		ch->ch_brate = PORTSERVER_DIVIDEND / ch->ch_custom_speed ;

		if (ch->ch_flag & CH_BAUD0) {
			ch->ch_mout |= DM_DTR | DM_RTS;

			ch->ch_flag &= ~CH_BAUD0;
		}
	} else {
		/*
		 * Baud rate mapping.
		 *
		 * If FASTBAUD isn't on, we can scan the new baud rate list
		 * as required.
		 *
		 * However, if FASTBAUD is on, we must go to the old
		 * baud rate mapping that existed many many moons ago,
		 * for compatibility reasons.
		 */

		if (!(ch->ch_digi.digi_flags & DIGI_FAST))
			brate = calc_baud_rate(un);
		else
			brate = calc_fastbaud_rate(un, uts);

		if (brate == 0)
			brate = 9600;

		ch->ch_brate = PORTSERVER_DIVIDEND / brate;

		if (ch->ch_flag & CH_BAUD0) {
			ch->ch_mout |= DM_DTR | DM_RTS;

			ch->ch_flag &= ~CH_BAUD0;
		}
	}

	/*
	 *  Generate channel cflags from the termio.
	 */

	ch->ch_cflag = tty_to_ch_flags(un->un_tty, 'c');

	/*
	 *  Generate channel iflags from the termio.
	 */

	iflag = (int) tty_to_ch_flags(un->un_tty, 'i');

	if (START_CHAR(un->un_tty) == _POSIX_VDISABLE ||
	    STOP_CHAR(un->un_tty) == _POSIX_VDISABLE) {
		iflag &= ~(IF_IXON | IF_IXANY | IF_IXOFF);
	}

	ch->ch_iflag = iflag;

	/*
	 *  Generate flow control characters
	 */

	/*
	 * From the POSIX.1 spec (7.1.2.6): "If {_POSIX_VDISABLE}
	 * is defined for the terminal device file, and the value
	 * of one of the changable special control characters (see
	 * 7.1.1.9) is {_POSIX_VDISABLE}, that function shall be
	 * disabled, that is, no input data shall be recognized as
	 * the disabled special character."
	 *
	 * OK, so we don't ever assign S/DXB XON or XOFF to _POSIX_VDISABLE.
	 */

	if (uts->c_cc[VSTART] != _POSIX_VDISABLE)
		ch->ch_xon = uts->c_cc[VSTART];
	if (uts->c_cc[VSTOP] != _POSIX_VDISABLE)
		ch->ch_xoff = uts->c_cc[VSTOP];

	ch->ch_lnext = (uts->c_cc[VLNEXT] == _POSIX_VDISABLE ? 0 :
			uts->c_cc[VLNEXT]);

	/*
	 * Also, if either c_cc[START] or c_cc[STOP] is set to
	 * _POSIX_VDISABLE, we can't really do software flow
	 * control--in either direction--so we turn it off as
	 * far as S/DXB is concerned.  In essence, if you disable
	 * one, you disable the other too.
	 */
	if ((uts->c_cc[VSTART] == _POSIX_VDISABLE) ||
	    (uts->c_cc[VSTOP] == _POSIX_VDISABLE))
		ch->ch_iflag &= ~(IF_IXOFF | IF_IXON);

	/*
	 *  Update xflags.
	 */

	xflag = 0;

	if (ch->ch_digi.digi_flags & DIGI_AIXON)
		xflag = XF_XIXON;

	if ((ch->ch_xxon == _POSIX_VDISABLE) ||
	    (ch->ch_xxoff == _POSIX_VDISABLE))
		xflag &= ~XF_XIXON;

	ch->ch_xflag = xflag;


	/*
	 *  Figure effective DCD value.
	 */

	if (C_CLOCAL(un->un_tty))
		ch->ch_flag |= CH_CLOCAL;
	else
		ch->ch_flag &= ~CH_CLOCAL;

	/*
	 *  Check modem signals
	 */

	dgrp_carrier(ch);

	/*
	 *  Get hardware handshake value.
	 */

	mflow = 0;

	if (C_CRTSCTS(un->un_tty))
		mflow |= (DM_RTS | DM_CTS);

	if (ch->ch_digi.digi_flags & RTSPACE)
		mflow |= DM_RTS;

	if (ch->ch_digi.digi_flags & DTRPACE)
		mflow |= DM_DTR;

	if (ch->ch_digi.digi_flags & CTSPACE)
		mflow |= DM_CTS;

	if (ch->ch_digi.digi_flags & DSRPACE)
		mflow |= DM_DSR;

	if (ch->ch_digi.digi_flags & DCDPACE)
		mflow |= DM_CD;

	if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)
		mflow |= DM_RTS_TOGGLE;

	ch->ch_mflow = mflow;

	/*
	 *  Send the changes to the server.
	 */

	ch->ch_flag |= CH_PARAM;
	(ch->ch_nd)->nd_tx_work = 1;

	if (waitqueue_active(&ch->ch_flag_wait))
		wake_up_interruptible(&ch->ch_flag_wait);
}

/*
 * This function is just used as a callback for timeouts
 * waiting on the ch_sleep flag.
 */
static void wake_up_drp_sleep_timer(unsigned long ptr)
{
	struct ch_struct *ch = (struct ch_struct *) ptr;
	if (ch)
		wake_up(&ch->ch_sleep);
}


/*
 * Set up our own sleep that can't be cancelled
 * until our timeout occurs.
 */
static void drp_my_sleep(struct ch_struct *ch)
{
	struct timer_list drp_wakeup_timer;
	DECLARE_WAITQUEUE(wait, current);

	/*
	 * First make sure we're ready to receive the wakeup.
	 */

	add_wait_queue(&ch->ch_sleep, &wait);
	current->state = TASK_UNINTERRUPTIBLE;

	/*
	 * Since we are uninterruptible, set a timer to
	 * unset the uninterruptable state in 1 second.
	 */

	init_timer(&drp_wakeup_timer);
	drp_wakeup_timer.function = wake_up_drp_sleep_timer;
	drp_wakeup_timer.data = (unsigned long) ch;
	drp_wakeup_timer.expires = jiffies + (1 * HZ);
	add_timer(&drp_wakeup_timer);

	schedule();

	del_timer(&drp_wakeup_timer);

	remove_wait_queue(&ch->ch_sleep, &wait);
}

/*
 * dgrp_tty_open()
 *
 * returns:
 *    -EBUSY    - this is a callout device and the normal device is active
 *              - there is an error in opening the tty
 *    -ENODEV   - the channel does not exist
 *    -EAGAIN   - we are in the middle of hanging up or closing
 *              - IMMEDIATE_OPEN fails
 *    -ENXIO or -EAGAIN
 *              - if the port is outside physical range
 *    -EINTR    - the open is interrupted
 *
 */
static int dgrp_tty_open(struct tty_struct *tty, struct file *file)
{
	int    retval = 0;
	struct nd_struct  *nd;
	struct ch_struct *ch;
	struct un_struct  *un;
	int    port;
	int    delay_error;
	int    otype;
	int    unf;
	int    wait_carrier;
	int    category;
	int    counts_were_incremented = 0;
	ulong lock_flags;
	DECLARE_WAITQUEUE(wait, current);

	/*
	 * Do some initial checks to see if the node and port exist
	 */

	nd = nd_struct_get(MAJOR(tty_devnum(tty)));
	port = PORT_NUM(MINOR(tty_devnum(tty)));
	category = OPEN_CATEGORY(MINOR(tty_devnum(tty)));

	if (!nd)
		return -ENODEV;

	if (port >= CHAN_MAX)
		return -ENODEV;

	/*
	 *  The channel exists.
	 */

	ch = nd->nd_chan + port;

	un = IS_PRINT(MINOR(tty_devnum(tty))) ? &ch->ch_pun : &ch->ch_tun;
	un->un_tty = tty;
	tty->driver_data = un;

	/*
	 * If we are in the middle of hanging up,
	 * then return an error
	 */
	if (tty_hung_up_p(file)) {
		retval = ((un->un_flag & UN_HUP_NOTIFY) ?
			   -EAGAIN : -ERESTARTSYS);
		goto done;
	}

	/*
	 * If the port is in the middle of closing, then block
	 * until it is done, then try again.
	 */
	retval = wait_event_interruptible(un->un_close_wait,
			((un->un_flag & UN_CLOSING) == 0));

	if (retval)
		goto done;

	/*
	 * If the port is in the middle of a reopen after a network disconnect,
	 * wait until it is done, then try again.
	 */
	retval = wait_event_interruptible(ch->ch_flag_wait,
			((ch->ch_flag & CH_PORT_GONE) == 0));

	if (retval)
		goto done;

	/*
	 * If this is a callout device, then just make sure the normal
	 * device isn't being used.
	 */

	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
		if (un->un_flag & UN_NORMAL_ACTIVE) {
			retval = -EBUSY;
			goto done;
		} else {
			un->un_flag |= UN_CALLOUT_ACTIVE;
		}
	}

	/*
	 *  Loop waiting until the open can be successfully completed.
	 */

	spin_lock_irqsave(&nd->nd_lock, lock_flags);

	nd->nd_tx_work = 1;

	for (;;) {
		wait_carrier = 0;

		/*
		 * Determine the open type from the flags provided.
		 */

		/*
		 * If the port is not enabled, then exit
		 */
		if (test_bit(TTY_IO_ERROR, &tty->flags)) {
			/* there was an error in opening the tty */
			if (un->un_flag & UN_CALLOUT_ACTIVE)
				retval = -EBUSY;
			else
				un->un_flag |= UN_NORMAL_ACTIVE;
			goto unlock;
		}

		if (file->f_flags & O_NONBLOCK) {

			/*
			 * if the O_NONBLOCK is set, errors on read and write
			 * must return -EAGAIN immediately and NOT sleep
			 * on the waitqs.
			 */
			otype = OTYPE_IMMEDIATE;
			delay_error = -EAGAIN;

		} else if (!OPEN_WAIT_AVAIL(category) ||
			  (file->f_flags & O_NDELAY) != 0) {
			otype = OTYPE_IMMEDIATE;
			delay_error = -EBUSY;

		} else if (!OPEN_WAIT_CARRIER(category) ||
			  ((ch->ch_digi.digi_flags & DIGI_FORCEDCD) != 0) ||
			  C_CLOCAL(tty)) {
			otype = OTYPE_PERSISTENT;
			delay_error = 0;

		} else {
			otype = OTYPE_INCOMING;
			delay_error = 0;
		}

		/*
		 * Handle port currently outside physical port range.
		 */

		if (port >= nd->nd_chan_count) {
			if (otype == OTYPE_IMMEDIATE) {
				retval = (nd->nd_state == NS_READY) ?
						-ENXIO : -EAGAIN;
				goto unlock;
			}
		}

		/*
		 *  Handle port not currently open.
		 */

		else if (ch->ch_open_count == 0) {
			/*
			 * Return an error when an Incoming Open
			 * response indicates the port is busy.
			 */

			if (ch->ch_open_error != 0 && otype == ch->ch_otype) {
				retval = (ch->ch_open_error <= 2) ?
					  delay_error : -ENXIO ;
				goto unlock;
			}

			/*
			 * Fail any new Immediate open if we do not have
			 * a normal connection to the server.
			 */

			if (nd->nd_state != NS_READY &&
			    otype == OTYPE_IMMEDIATE) {
				retval = -EAGAIN;
				goto unlock;
			}

			/*
			 * If a Realport open of the correct type has
			 * succeeded, complete the open.
			 */

			if (ch->ch_state == CS_READY && ch->ch_otype == otype)
				break;
		}

		/*
		 * Handle port already open and active as a device
		 * of same category.
		 */

		else if ((ch->ch_category == category) ||
			  IS_PRINT(MINOR(tty_devnum(tty)))) {
			/*
			 * Fail if opening the device now would
			 * violate exclusive use.
			 */
			unf = ch->ch_tun.un_flag | ch->ch_pun.un_flag;

			if ((file->f_flags & O_EXCL) || (unf & UN_EXCL)) {
				retval = -EBUSY;
				goto unlock;
			}

			/*
			 * If the open device is in the hangup state, all
			 * system calls fail except close().
			 */

			/* TODO : check on hangup_p calls */

			if (ch->ch_flag & CH_HANGUP) {
				retval = -ENXIO;
				goto unlock;
			}

			/*
			 * If the port is ready, and carrier is ignored
			 * or present, then complete the open.
			 */

			if (ch->ch_state == CS_READY &&
			    (otype != OTYPE_INCOMING ||
			    ch->ch_flag & CH_VIRT_CD))
				break;

			wait_carrier = 1;
		}

		/*
		 *  Handle port active with a different category device.
		 */

		else {
			if (otype == OTYPE_IMMEDIATE) {
				retval = delay_error;
				goto unlock;
			}
		}

		/*
		 * Wait until conditions change, then take another
		 * try at the open.
		 */

		ch->ch_wait_count[otype]++;

		if (wait_carrier)
			ch->ch_wait_carrier++;

		/*
		 * Prepare the task to accept the wakeup, then
		 * release our locks and release control.
		 */

		add_wait_queue(&ch->ch_flag_wait, &wait);
		current->state = TASK_INTERRUPTIBLE;

		spin_unlock_irqrestore(&nd->nd_lock, lock_flags);

		/*
		 * Give up control, we'll come back if we're
		 * interrupted or are woken up.
		 */
		schedule();
		remove_wait_queue(&ch->ch_flag_wait, &wait);

		spin_lock_irqsave(&nd->nd_lock, lock_flags);

		current->state = TASK_RUNNING;

		ch->ch_wait_count[otype]--;

		if (wait_carrier)
			ch->ch_wait_carrier--;

		nd->nd_tx_work = 1;

		if (signal_pending(current)) {
			retval = -EINTR;
			goto unlock;
		}
	} /* end for(;;) */

	/*
	 *  The open has succeeded.  No turning back.
	 */
	counts_were_incremented = 1;
	un->un_open_count++;
	ch->ch_open_count++;

	/*
	 * Initialize the channel, if it's not already open.
	 */

	if (ch->ch_open_count == 1) {
		ch->ch_flag = 0;
		ch->ch_inwait = 0;
		ch->ch_category = category;
		ch->ch_pscan_state = 0;

		/* TODO : find out what PS-1 bug Gene was referring to */
		/* TODO : in the following comment. */

		ch->ch_send = RR_TX_START | RR_RX_START;  /* PS-1 bug */

		if (C_CLOCAL(tty) ||
		    ch->ch_s_mlast & DM_CD ||
		    ch->ch_digi.digi_flags & DIGI_FORCEDCD)
			ch->ch_flag |= CH_VIRT_CD;
		else if (OPEN_FORCES_CARRIER(category))
			ch->ch_flag |= CH_VIRT_CD;

	}

	/*
	 *  Initialize the unit, if it is not already open.
	 */

	if (un->un_open_count == 1) {
		/*
		 *  Since all terminal options are always sticky in Linux,
		 *  we don't need the UN_STICKY flag to be handled specially.
		 */
		/* clears all the digi flags, leaves serial flags */
		un->un_flag &= ~UN_DIGI_MASK;

		if (file->f_flags & O_EXCL)
			un->un_flag |= UN_EXCL;

		/* TODO : include "session" and "pgrp" */

		/*
		 *  In Linux, all terminal parameters are intended to be sticky.
		 *  as a result, we "remove" the code which once reset the ports
		 *  to sane values.
		 */

		drp_param(ch);

	}

	un->un_flag |= UN_INITIALIZED;

	retval = 0;

unlock:

	spin_unlock_irqrestore(&nd->nd_lock, lock_flags);

done:
	/*
	 * Linux does a close for every open, even failed ones!
	 */
	if (!counts_were_incremented) {
		un->un_open_count++;
		ch->ch_open_count++;
	}

	if (retval)
		dev_err(tty->dev, "tty open bad return (%i)\n", retval);

	return retval;
}




/*
 * dgrp_tty_close() -- close function for tty_operations
 */
static void dgrp_tty_close(struct tty_struct *tty, struct file *file)
{
	struct ch_struct *ch;
	struct un_struct *un;
	struct nd_struct *nd;
	int	tpos;
	int	port;
	int	err = 0;
	int	s = 0;
	ulong  waketime;
	ulong  lock_flags;
	int sent_printer_offstr = 0;

	port = PORT_NUM(MINOR(tty_devnum(tty)));

	un = tty->driver_data;

	if (!un)
		return;

	ch = un->un_ch;

	if (!ch)
		return;

	nd = ch->ch_nd;

	if (!nd)
		return;

	spin_lock_irqsave(&nd->nd_lock, lock_flags);


	/* Used to be on channel basis, now we check on a unit basis. */
	if (un->un_open_count != 1)
		goto unlock;

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

	/*
	 * Notify the discipline to only process XON/XOFF characters.
	 */
	tty->closing = 1;

	/*
	 * Wait for output to drain only if this is
	 * the last close against the channel
	 */

	if (ch->ch_open_count == 1) {
		/*
		 * If its the print device, we need to ensure at all costs that
		 * the offstr will fit. If it won't, flush our tbuf.
		 */
		if (IS_PRINT(MINOR(tty_devnum(tty))) &&
		    (((ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK) <
		    ch->ch_digi.digi_offlen))
			ch->ch_tin = ch->ch_tout;

		/*
		 * Turn off the printer.  Don't bother checking to see if its
		 * IS_PRINT... Since this is the last close the flag is going
		 * to be cleared, so we MUST make sure the offstr gets inserted
		 * into tbuf.
		 */

		if ((ch->ch_flag & CH_PRON) != 0) {
			drp_wmove(ch, 0, ch->ch_digi.digi_offstr,
				  ch->ch_digi.digi_offlen);
			ch->ch_flag &= ~CH_PRON;
			sent_printer_offstr = 1;
		}
	}

	/*
	 *  Wait until either the output queue has drained, or we see
	 *  absolutely no progress for 15 seconds.
	 */

	tpos = ch->ch_s_tpos;

	waketime = jiffies + 15 * HZ;

	for (;;) {

		/*
		 *  Make sure the port still exists.
		 */

		if (port >= nd->nd_chan_count) {
			err = 1;
			break;
		}

		if (signal_pending(current)) {
			err = 1;
			break;
		}

		/*
		 * If the port is idle (not opened on the server), we have
		 * no way of draining/flushing/closing the port on that server.
		 * So break out of loop.
		 */
		if (ch->ch_state == CS_IDLE)
			break;

		nd->nd_tx_work = 1;

		/*
		 *  Exit if the queues for this unit are empty,
		 *  and either the other unit is still open or all
		 *  data has drained.
		 */

		if ((un->un_tty)->ops->chars_in_buffer ?
		    ((un->un_tty)->ops->chars_in_buffer)(un->un_tty) == 0 : 1) {

			/*
			 * We don't need to wait for a buffer to drain
			 * if the other unit is open.
			 */

			if (ch->ch_open_count != un->un_open_count)
				break;

			/*
			 *  The wait is complete when all queues are
			 *  drained, and any break in progress is complete.
			 */

			if (ch->ch_tin == ch->ch_tout &&
			    ch->ch_s_tin == ch->ch_s_tpos &&
			    (ch->ch_send & RR_TX_BREAK) == 0) {
				break;
			}
		}

		/*
		 * Flush TX data and exit the wait if NDELAY is set,
		 * or this is not a DIGI printer, and the close timeout
		 * expires.
		 */

		if ((file->f_flags & (O_NDELAY | O_NONBLOCK)) ||
		    ((long)(jiffies - waketime) >= 0 &&
		      (ch->ch_digi.digi_flags & DIGI_PRINTER) == 0)) {

				/*
				 * If we sent the printer off string, we cannot
				 * flush our internal buffers, or we might lose
				 * the offstr.
				 */
				if (!sent_printer_offstr)
					dgrp_tty_flush_buffer(tty);

				tty_ldisc_flush(tty);
				break;
		}

		/*
		 *  Otherwise take a short nap.
		 */

		ch->ch_flag |= CH_DRAIN;

		spin_unlock_irqrestore(&nd->nd_lock, lock_flags);

		schedule_timeout_interruptible(1);
		s = signal_pending(current);

		spin_lock_irqsave(&nd->nd_lock, lock_flags);

		if (s) {
			/*
			 * If we had sent the printer off string, we now have
			 * some problems.
			 *
			 * The system won't let us sleep since we got an error
			 * back from sleep, presumably because the user did
			 * a ctrl-c...
			 * But we need to ensure that the offstr gets sent!
			 * Thus, we have to do something else besides sleeping.
			 * The plan:
			 * 1) Make this task uninterruptable.
			 * 2) Set up a timer to go off in 1 sec.
			 * 3) Act as tho we just got out of the sleep above.
			 *
			 * Thankfully, in the real world, this just
			 * never happens.
			 */

			if (sent_printer_offstr) {
				spin_unlock_irqrestore(&nd->nd_lock,
						       lock_flags);
				drp_my_sleep(ch);
				spin_lock_irqsave(&nd->nd_lock, lock_flags);
			} else {
				err = 1;
				break;
			}
		}

		/*
		 *  Restart the wait if any progress is seen.
		 */

		if (ch->ch_s_tpos != tpos) {
			tpos = ch->ch_s_tpos;

			/* TODO:  this gives us timeout problems with nist ?? */
			waketime = jiffies + 15 * HZ;
		}
	}

	/*
	 *  Close the line discipline
	 */

	/* this is done in tty_io.c */
	/* if ((un->un_tty)->ldisc.close)
	 *	((un->un_tty)->ldisc.close)(un->un_tty);
	 */

	/* don't do this here */
	/* un->un_flag = 0; */

	/*
	 *  Flush the receive buffer on terminal unit close only.
	 */

	if (!IS_PRINT(MINOR(tty_devnum(tty))))
		ch->ch_rout = ch->ch_rin;


	/*
	 * Don't permit the close to happen until we get any pending
	 * sync request responses.
	 * There could be other ports depending upon the response as well.
	 *
	 * Also, don't permit the close to happen until any parameter
	 * changes have been sent out from the state machine as well.
	 * This is required because of a ditty -a race with -HUPCL
	 * We MUST make sure all channel parameters have been sent to the
	 * Portserver before sending a close.
	 */

	if ((err != 1) && (ch->ch_state != CS_IDLE)) {
		spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
		s = wait_event_interruptible(ch->ch_flag_wait,
			((ch->ch_flag & (CH_WAITING_SYNC | CH_PARAM)) == 0));
		spin_lock_irqsave(&nd->nd_lock, lock_flags);
	}

	/*
	 * Cleanup the channel if last unit open.
	 */

	if (ch->ch_open_count == 1) {
		ch->ch_flag = 0;
		ch->ch_category = 0;
		ch->ch_send = 0;
		ch->ch_expect = 0;
		ch->ch_tout = ch->ch_tin;
		/* (un->un_tty)->device = 0; */

		if (ch->ch_state == CS_READY)
			ch->ch_state = CS_SEND_CLOSE;
	}

	/*
	 * Send the changes to the server
	 */
	if (ch->ch_state != CS_IDLE) {
		ch->ch_flag |= CH_PARAM;
		wake_up_interruptible(&ch->ch_flag_wait);
	}

	nd->nd_tx_work = 1;
	nd->nd_tx_ready = 1;

unlock:
	tty->closing = 0;

	if (ch->ch_open_count <= 0)
		dev_info(tty->dev,
			 "%s - unexpected value for ch->ch_open_count: %i\n",
			 __func__, ch->ch_open_count);
	else
		ch->ch_open_count--;

	if (un->un_open_count <= 0)
		dev_info(tty->dev,
			 "%s - unexpected value for un->un_open_count: %i\n",
			 __func__, un->un_open_count);
	else
		un->un_open_count--;

	un->un_flag &= ~(UN_NORMAL_ACTIVE | UN_CALLOUT_ACTIVE | UN_CLOSING);
	if (waitqueue_active(&un->un_close_wait))
		wake_up_interruptible(&un->un_close_wait);

	spin_unlock_irqrestore(&nd->nd_lock, lock_flags);

	return;

}

static void drp_wmove(struct ch_struct *ch, int from_user, void *buf, int count)
{
	int n;
	int ret = 0;

	ch->ch_nd->nd_tx_work = 1;

	n = TBUF_MAX - ch->ch_tin;

	if (count >= n) {
		if (from_user)
			ret = copy_from_user(ch->ch_tbuf + ch->ch_tin,
					     (void __user *) buf, n);
		else
			memcpy(ch->ch_tbuf + ch->ch_tin, buf, n);

		buf = (char *) buf + n;
		count -= n;
		ch->ch_tin = 0;
	}

	if (from_user)
		ret = copy_from_user(ch->ch_tbuf + ch->ch_tin,
				     (void __user *) buf, count);
	else
		memcpy(ch->ch_tbuf + ch->ch_tin, buf, count);

	ch->ch_tin += count;
}


static int dgrp_calculate_txprint_bounds(struct ch_struct *ch, int space,
					 int *un_flag)
{
	clock_t tt;
	clock_t mt;
	unsigned short tmax = 0;

	/*
	 * If the terminal device is busy, reschedule when
	 * the terminal device becomes idle.
	 */

	if (ch->ch_tun.un_open_count != 0 &&
	    ch->ch_tun.un_tty->ops->chars_in_buffer &&
	    ((ch->ch_tun.un_tty->ops->chars_in_buffer)(ch->ch_tun.un_tty) != 0)) {
		*un_flag = UN_PWAIT;
		return 0;
	}

	/*
	 * Assure that whenever there is printer data in the output
	 * buffer, there always remains enough space after it to
	 * turn the printer off.
	 */
	space -= ch->ch_digi.digi_offlen;

	if (space <= 0) {
		*un_flag = UN_EMPTY;
		return 0;
	}

	/*
	 * We measure printer CPS speed by incrementing
	 * ch_cpstime by (HZ / digi_maxcps) for every
	 * character we output, restricting output so
	 * that ch_cpstime never exceeds lbolt.
	 *
	 * However if output has not been done for some
	 * time, lbolt will grow to very much larger than
	 * ch_cpstime, which would allow essentially
	 * unlimited amounts of output until ch_cpstime
	 * finally caught up.   To avoid this, we adjust
	 * cps_time when necessary so the difference
	 * between lbolt and ch_cpstime never results
	 * in sending more than digi_bufsize characters.
	 *
	 * This nicely models a printer with an internal
	 * buffer of digi_bufsize characters.
	 *
	 * Get the time between lbolt and ch->ch_cpstime;
	 */

	tt = jiffies - ch->ch_cpstime;

	/*
	 * Compute the time required to send digi_bufsize
	 * characters.
	 */

	mt = HZ * ch->ch_digi.digi_bufsize / ch->ch_digi.digi_maxcps;

	/*
	 * Compute the number of characters that can be sent
	 * without violating the time constraint.   If the
	 * direct calculation of this number is bigger than
	 * digi_bufsize, limit the number to digi_bufsize,
	 * and adjust cpstime to match.
	 */

	if ((clock_t)(tt + HZ) > (clock_t)(mt + HZ)) {
		tmax = ch->ch_digi.digi_bufsize;
		ch->ch_cpstime = jiffies - mt;
	} else {
		tmax = ch->ch_digi.digi_maxcps * tt / HZ;
	}

	/*
	 * If the time constraint now binds, limit the transmit
	 * count accordingly, and tentatively arrange to be
	 * rescheduled based on time.
	 */

	if (tmax < space) {
		*un_flag = UN_TIME;
		space = tmax;
	}

	/*
	 * Compute the total number of characters we can
	 * output before the total number of characters known
	 * to be in the output queue exceeds digi_maxchar.
	 */

	tmax = (ch->ch_digi.digi_maxchar -
		((ch->ch_tin - ch->ch_tout) & TBUF_MASK) -
		((ch->ch_s_tin - ch->ch_s_tpos) & 0xffff));


	/*
	 * If the digi_maxchar constraint now holds, limit
	 * the transmit count accordingly, and arrange to
	 * be rescheduled when the queue becomes empty.
	 */

	if (space > tmax) {
		*un_flag = UN_EMPTY;
		space = tmax;
	}

	if (space <= 0)
		*un_flag |= UN_EMPTY;

	return space;
}


static int dgrp_tty_write(struct tty_struct *tty,
			  const unsigned char *buf,
			  int count)
{
	struct nd_struct *nd;
	struct un_struct *un;
	struct ch_struct *ch;
	int	space;
	int	n;
	int	t;
	int sendcount;
	int un_flag;
	ulong lock_flags;

	if (tty == NULL)
		return 0;

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

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

	nd = ch->ch_nd;
	if (!nd)
		return 0;

	/*
	 * Ignore the request if the channel is not ready.
	 */
	if (ch->ch_state != CS_READY)
		return 0;

	spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);

	/*
	 * Ignore the request if output is blocked.
	 */
	if ((un->un_flag & (UN_EMPTY | UN_LOW | UN_TIME | UN_PWAIT)) != 0) {
		count = 0;
		goto out;
	}

	/*
	 * Also ignore the request if DPA has this port open,
	 * and is flow controlled on reading more data.
	 */
	if (nd->nd_dpa_debug && nd->nd_dpa_flag & DPA_WAIT_SPACE &&
		nd->nd_dpa_port == MINOR(tty_devnum(ch->ch_tun.un_tty))) {
		count = 0;
		goto out;
	}

	/*
	 *	Limit amount we will write to the amount of space
	 *	available in the channel buffer.
	 */
	sendcount = 0;

	space = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK;

	/*
	 * Handle the printer device.
	 */

	un_flag = UN_LOW;

	if (IS_PRINT(MINOR(tty_devnum(tty)))) {
		clock_t tt;
		clock_t mt;
		unsigned short tmax = 0;

		/*
		 * If the terminal device is busy, reschedule when
		 * the terminal device becomes idle.
		 */

		if (ch->ch_tun.un_open_count != 0 &&
		    ((ch->ch_tun.un_tty->ops->chars_in_buffer)(ch->ch_tun.un_tty) != 0)) {
			un->un_flag |= UN_PWAIT;
			count = 0;
			goto out;
		}

		/*
		 * Assure that whenever there is printer data in the output
		 * buffer, there always remains enough space after it to
		 * turn the printer off.
		 */
		space -= ch->ch_digi.digi_offlen;

		/*
		 * Output the printer on string.
		 */

		if ((ch->ch_flag & CH_PRON) == 0) {
			space -= ch->ch_digi.digi_onlen;

			if (space < 0) {
				un->un_flag |= UN_EMPTY;
				(ch->ch_nd)->nd_tx_work = 1;
				count = 0;
				goto out;
			}

			drp_wmove(ch, 0, ch->ch_digi.digi_onstr,
				ch->ch_digi.digi_onlen);

			ch->ch_flag |= CH_PRON;
		}

		/*
		 * We measure printer CPS speed by incrementing
		 * ch_cpstime by (HZ / digi_maxcps) for every
		 * character we output, restricting output so
		 * that ch_cpstime never exceeds lbolt.
		 *
		 * However if output has not been done for some
		 * time, lbolt will grow to very much larger than
		 * ch_cpstime, which would allow essentially
		 * unlimited amounts of output until ch_cpstime
		 * finally caught up.   To avoid this, we adjust
		 * cps_time when necessary so the difference
		 * between lbolt and ch_cpstime never results
		 * in sending more than digi_bufsize characters.
		 *
		 * This nicely models a printer with an internal
		 * buffer of digi_bufsize characters.
		 *
		 * Get the time between lbolt and ch->ch_cpstime;
		 */

		tt = jiffies - ch->ch_cpstime;

		/*
		 * Compute the time required to send digi_bufsize
		 * characters.
		 */

		mt = HZ * ch->ch_digi.digi_bufsize / ch->ch_digi.digi_maxcps;

		/*
		 * Compute the number of characters that can be sent
		 * without violating the time constraint.   If the
		 * direct calculation of this number is bigger than
		 * digi_bufsize, limit the number to digi_bufsize,
		 * and adjust cpstime to match.
		 */

		if ((clock_t)(tt + HZ) > (clock_t)(mt + HZ)) {
			tmax = ch->ch_digi.digi_bufsize;
			ch->ch_cpstime = jiffies - mt;
		} else {
			tmax = ch->ch_digi.digi_maxcps * tt / HZ;
		}

		/*
		 * If the time constraint now binds, limit the transmit
		 * count accordingly, and tentatively arrange to be
		 * rescheduled based on time.
		 */

		if (tmax < space) {
			space = tmax;
			un_flag = UN_TIME;
		}

		/*
		 * Compute the total number of characters we can
		 * output before the total number of characters known
		 * to be in the output queue exceeds digi_maxchar.
		 */

		tmax = (ch->ch_digi.digi_maxchar -
			((ch->ch_tin - ch->ch_tout) & TBUF_MASK) -
			((ch->ch_s_tin - ch->ch_s_tpos) & 0xffff));


		/*
		 * If the digi_maxchar constraint now holds, limit
		 * the transmit count accordingly, and arrange to
		 * be rescheduled when the queue becomes empty.
		 */

		if (space > tmax) {
			space = tmax;
			un_flag = UN_EMPTY;
		}

	}
	/*
	 * Handle the terminal device.
	 */
	else {

		/*
		 * If the printer device is on, turn it off.
		 */

		if ((ch->ch_flag & CH_PRON) != 0) {

			space -= ch->ch_digi.digi_offlen;

			drp_wmove(ch, 0, ch->ch_digi.digi_offstr,
				  ch->ch_digi.digi_offlen);

			ch->ch_flag &= ~CH_PRON;
		}
	}

	/*
	 *	If space is 0 and its because the ch->tbuf
	 *	is full, then Linux will handle a callback when queue
	 *	space becomes available.
	 *	tty_write returns count = 0
	 */

	if (space <= 0) {
		/* the linux tty_io.c handles this if we return 0 */
		/* if (fp->flags & O_NONBLOCK) return -EAGAIN; */

		un->un_flag |= UN_EMPTY;
		(ch->ch_nd)->nd_tx_work = 1;
		count = 0;
		goto out;
	}

	count = min(count, space);

	if (count > 0) {

		un->un_tbusy++;

		/*
		 *	Copy the buffer contents to the ch_tbuf
		 *	being careful to wrap around the circular queue
		 */

		t = TBUF_MAX - ch->ch_tin;
		n = count;

		if (n >= t) {
			memcpy(ch->ch_tbuf + ch->ch_tin, buf, t);
			if (nd->nd_dpa_debug && nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(un->un_tty))))
				dgrp_dpa_data(nd, 0, (char *) buf, t);
			buf += t;
			n -= t;
			ch->ch_tin = 0;
			sendcount += n;
		}

		memcpy(ch->ch_tbuf + ch->ch_tin, buf, n);
		if (nd->nd_dpa_debug && nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(un->un_tty))))
			dgrp_dpa_data(nd, 0, (char *) buf, n);
		buf += n;
		ch->ch_tin += n;
		sendcount += n;

		un->un_tbusy--;
		(ch->ch_nd)->nd_tx_work = 1;
		if (ch->ch_edelay != DGRP_RTIME) {
			(ch->ch_nd)->nd_tx_ready = 1;
			wake_up_interruptible(&nd->nd_tx_waitq);
		}
	}

	ch->ch_txcount += count;

	if (IS_PRINT(MINOR(tty_devnum(tty)))) {

		/*
		 * Adjust ch_cpstime to account
		 * for the characters just output.
		 */

		if (sendcount > 0) {
			int cc = HZ * sendcount + ch->ch_cpsrem;

			ch->ch_cpstime += cc / ch->ch_digi.digi_maxcps;
			ch->ch_cpsrem   = cc % ch->ch_digi.digi_maxcps;
		}

		/*
		 * If we are now waiting on time, schedule ourself
		 * back when we'll be able to send a block of
		 * digi_maxchar characters.
		 */

		if ((un_flag & UN_TIME) != 0) {
			ch->ch_waketime = (ch->ch_cpstime +
				(ch->ch_digi.digi_maxchar * HZ /
				ch->ch_digi.digi_maxcps));
		}
	}

	/*
	 * If the printer unit is waiting for completion
	 * of terminal output, get him going again.
	 */

	if ((ch->ch_pun.un_flag & UN_PWAIT) != 0)
		(ch->ch_nd)->nd_tx_work = 1;

out:
	spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);

	return count;
}


/*
 *	Put a character into ch->ch_buf
 *
 *	- used by the line discipline for OPOST processing
 */

static int dgrp_tty_put_char(struct tty_struct *tty, unsigned char new_char)
{
	struct un_struct *un;
	struct ch_struct *ch;
	ulong  lock_flags;
	int space;
	int retval = 0;

	if (tty == NULL)
		return 0;

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

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

	if (ch->ch_state != CS_READY)
		return 0;

	spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);


	/*
	 *	If space is 0 and its because the ch->tbuf
	 *	Warn and dump the character, there isn't anything else
	 *	we can do about it.  David_Fries@digi.com
	 */

	space = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK;

	un->un_tbusy++;

	/*
	 * Output the printer on string if device is TXPrint.
	 */
	if (IS_PRINT(MINOR(tty_devnum(tty))) && (ch->ch_flag & CH_PRON) == 0) {
		if (space < ch->ch_digi.digi_onlen) {
			un->un_tbusy--;
			goto out;
		}
		space -= ch->ch_digi.digi_onlen;
		drp_wmove(ch, 0, ch->ch_digi.digi_onstr,
			  ch->ch_digi.digi_onlen);
		ch->ch_flag |= CH_PRON;
	}

	/*
	 * Output the printer off string if device is NOT TXPrint.
	 */

	if (!IS_PRINT(MINOR(tty_devnum(tty))) &&
	    ((ch->ch_flag & CH_PRON) != 0)) {
		if (space < ch->ch_digi.digi_offlen) {
			un->un_tbusy--;
			goto out;
		}

		space -= ch->ch_digi.digi_offlen;
		drp_wmove(ch, 0, ch->ch_digi.digi_offstr,
			  ch->ch_digi.digi_offlen);
		ch->ch_flag &= ~CH_PRON;
	}

	if (!space) {
		un->un_tbusy--;
		goto out;
	}

	/*
	 *	Copy the character to the ch_tbuf being
	 *	careful to wrap around the circular queue
	 */
	ch->ch_tbuf[ch->ch_tin] = new_char;
	ch->ch_tin = (1 + ch->ch_tin) & TBUF_MASK;

	if (IS_PRINT(MINOR(tty_devnum(tty)))) {

		/*
		 * Adjust ch_cpstime to account
		 * for the character just output.
		 */

		int cc = HZ + ch->ch_cpsrem;

		ch->ch_cpstime += cc / ch->ch_digi.digi_maxcps;
		ch->ch_cpsrem   = cc % ch->ch_digi.digi_maxcps;

		/*
		 * If we are now waiting on time, schedule ourself
		 * back when we'll be able to send a block of
		 * digi_maxchar characters.
		 */

		ch->ch_waketime = (ch->ch_cpstime +
			(ch->ch_digi.digi_maxchar * HZ /
			ch->ch_digi.digi_maxcps));
	}


	un->un_tbusy--;
	(ch->ch_nd)->nd_tx_work = 1;

	retval = 1;
out:
	spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);
	return retval;
}



/*
 *	Flush TX buffer (make in == out)
 *
 *	check tty_ioctl.c  -- this is called after TCOFLUSH
 */
static void dgrp_tty_flush_buffer(struct tty_struct *tty)
{
	struct un_struct *un;
	struct ch_struct *ch;

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

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

	ch->ch_tout = ch->ch_tin;
	/* do NOT do this here! */
	/* ch->ch_s_tpos = ch->ch_s_tin = 0; */

	/* send the flush output command now */
	ch->ch_send |= RR_TX_FLUSH;
	(ch->ch_nd)->nd_tx_ready = 1;
	(ch->ch_nd)->nd_tx_work = 1;
	wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);

	if (waitqueue_active(&tty->write_wait))
		wake_up_interruptible(&tty->write_wait);

	tty_wakeup(tty);

}

/*
 *	Return space available in Tx buffer
 *	count = ( ch->ch_tout - ch->ch_tin ) mod (TBUF_MAX - 1)
 */
static int dgrp_tty_write_room(struct tty_struct *tty)
{
	struct un_struct *un;
	struct ch_struct *ch;
	int	count;

	if (!tty)
		return 0;

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

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

	count = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK;

	/* We *MUST* check this, and return 0 if the Printer Unit cannot
	 * take any more data within its time constraints...  If we don't
	 * return 0 and the printer has hit it time constraint, the ld will
	 * call us back doing a put_char, which cannot be rejected!!!
	 */
	if (IS_PRINT(MINOR(tty_devnum(tty)))) {
		int un_flag = 0;
		count = dgrp_calculate_txprint_bounds(ch, count, &un_flag);
		if (count <= 0)
			count = 0;

		ch->ch_pun.un_flag |= un_flag;
		(ch->ch_nd)->nd_tx_work = 1;
	}

	return count;
}

/*
 *	Return number of characters that have not been transmitted yet.
 *	chars_in_buffer = ( ch->ch_tin - ch->ch_tout ) mod (TBUF_MAX - 1)
 *			+ ( ch->ch_s_tin - ch->ch_s_tout ) mod (0xffff)
 *			= number of characters "in transit"
 *
 * Remember that sequence number math is always with a sixteen bit
 * mask, not the TBUF_MASK.
 */

static int dgrp_tty_chars_in_buffer(struct tty_struct *tty)
{
	struct un_struct *un;
	struct ch_struct *ch;
	int	count;
	int	count1;

	if (!tty)
		return 0;

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

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

	count1 = count = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
	count += (ch->ch_s_tin - ch->ch_s_tpos) & 0xffff;
	/* one for tbuf, one for the PS */

	/*
	 * If we are busy transmitting add 1
	 */
	count += un->un_tbusy;

	return count;
}


/*****************************************************************************
 *
 * Helper applications for dgrp_tty_ioctl()
 *
 *****************************************************************************
 */


/**
 * ch_to_tty_flags() -- convert channel flags to termio flags
 * @ch_flag: Digi channel flags
 * @flagtype: type of ch_flag (iflag, oflag or cflag)
 *
 * take the channel flags of the specified type and return the
 * corresponding termio flag
 */
static tcflag_t ch_to_tty_flags(ushort ch_flag, char flagtype)
{
	tcflag_t retval = 0;

	switch (flagtype) {
	case 'i':
		retval = ((ch_flag & IF_IGNBRK) ? IGNBRK : 0)
		     | ((ch_flag & IF_BRKINT) ? BRKINT : 0)
		     | ((ch_flag & IF_IGNPAR) ? IGNPAR : 0)
		     | ((ch_flag & IF_PARMRK) ? PARMRK : 0)
		     | ((ch_flag & IF_INPCK) ? INPCK  : 0)
		     | ((ch_flag & IF_ISTRIP) ? ISTRIP : 0)
		     | ((ch_flag & IF_IXON) ? IXON   : 0)
		     | ((ch_flag & IF_IXANY) ? IXANY  : 0)
		     | ((ch_flag & IF_IXOFF) ? IXOFF  : 0);
		break;

	case 'o':
		retval = ((ch_flag & OF_OLCUC) ? OLCUC : 0)
		     | ((ch_flag & OF_ONLCR) ? ONLCR  : 0)
		     | ((ch_flag & OF_OCRNL) ? OCRNL  : 0)
		     | ((ch_flag & OF_ONOCR) ? ONOCR  : 0)
		     | ((ch_flag & OF_ONLRET) ? ONLRET : 0)
		  /* | ((ch_flag & OF_OTAB3) ? OFILL  : 0) */
		     | ((ch_flag & OF_TABDLY) ? TABDLY : 0);
		break;

	case 'c':
		retval = ((ch_flag & CF_CSTOPB) ? CSTOPB : 0)
		     | ((ch_flag & CF_CREAD) ? CREAD  : 0)
		     | ((ch_flag & CF_PARENB) ? PARENB : 0)
		     | ((ch_flag & CF_PARODD) ? PARODD : 0)
		     | ((ch_flag & CF_HUPCL) ? HUPCL  : 0);

		switch (ch_flag & CF_CSIZE) {
		case CF_CS5:
			retval |= CS5;
			break;
		case CF_CS6:
			retval |= CS6;
			break;
		case CF_CS7:
			retval |= CS7;
			break;
		case CF_CS8:
			retval |= CS8;
			break;
		default:
			retval |= CS8;
			break;
		}
		break;
	case 'x':
		break;
	case 'l':
		break;
	default:
		return 0;
	}

	return retval;
}


/**
 * tty_to_ch_flags() -- convert termio flags to digi channel flags
 * @tty: pointer to a TTY structure holding flag to be converted
 * @flagtype: identifies which flag (iflags, oflags, or cflags) should
 *                 be converted
 *
 * take the termio flag of the specified type and return the
 * corresponding Digi version of the flags
 */
static ushort tty_to_ch_flags(struct tty_struct *tty, char flagtype)
{
	ushort retval = 0;
	tcflag_t tflag = 0;

	switch (flagtype) {
	case 'i':
		tflag  = tty->termios.c_iflag;
		retval = (I_IGNBRK(tty) ? IF_IGNBRK : 0)
		      | (I_BRKINT(tty) ? IF_BRKINT : 0)
		      | (I_IGNPAR(tty) ? IF_IGNPAR : 0)
		      | (I_PARMRK(tty) ? IF_PARMRK : 0)
		      | (I_INPCK(tty)  ? IF_INPCK  : 0)
		      | (I_ISTRIP(tty) ? IF_ISTRIP : 0)
		      | (I_IXON(tty)   ? IF_IXON   : 0)
		      | (I_IXANY(tty)  ? IF_IXANY  : 0)
		      | (I_IXOFF(tty)  ? IF_IXOFF  : 0);
		break;
	case 'o':
		tflag  = tty->termios.c_oflag;
		/*
		 * If OPOST is set, then do the post processing in the
		 * firmware by setting all the processing flags on.
		 * If ~OPOST, then make sure we are not doing any
		 * output processing!!
		 */
		if (!O_OPOST(tty))
			retval = 0;
		else
			retval = (O_OLCUC(tty) ? OF_OLCUC : 0)
			     | (O_ONLCR(tty)  ? OF_ONLCR  : 0)
			     | (O_OCRNL(tty)  ? OF_OCRNL  : 0)
			     | (O_ONOCR(tty)  ? OF_ONOCR  : 0)
			     | (O_ONLRET(tty) ? OF_ONLRET : 0)
			  /* | (O_OFILL(tty)  ? OF_TAB3   : 0) */
			     | (O_TABDLY(tty) ? OF_TABDLY : 0);
		break;
	case 'c':
		tflag  = tty->termios.c_cflag;
		retval = (C_CSTOPB(tty) ? CF_CSTOPB : 0)
		     | (C_CREAD(tty)  ? CF_CREAD  : 0)
		     | (C_PARENB(tty) ? CF_PARENB : 0)
		     | (C_PARODD(tty) ? CF_PARODD : 0)
		     | (C_HUPCL(tty)  ? CF_HUPCL  : 0);
		switch (C_CSIZE(tty)) {
		case CS8:
			retval |= CF_CS8;
			break;
		case CS7:
			retval |= CF_CS7;
			break;
		case CS6:
			retval |= CF_CS6;
			break;
		case CS5:
			retval |= CF_CS5;
			break;
		default:
			retval |= CF_CS8;
			break;
		}
		break;
	case 'x':
		break;
	case 'l':
		break;
	default:
		return 0;
	}

	return retval;
}


static int dgrp_tty_send_break(struct tty_struct *tty, int msec)
{
	struct un_struct *un;
	struct ch_struct *ch;
	int ret = -EIO;

	if (!tty)
		return ret;

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

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

	dgrp_send_break(ch, msec);
	return 0;
}


/*
 * This routine sends a break character out the serial port.
 *
 * duration is in 1/1000's of a second
 */
static int dgrp_send_break(struct ch_struct *ch, int msec)
{
	ulong x;

	wait_event_interruptible(ch->ch_flag_wait,
		((ch->ch_flag & CH_TX_BREAK) == 0));
	ch->ch_break_time += max(msec, 250);
	ch->ch_send |= RR_TX_BREAK;
	ch->ch_flag |= CH_TX_BREAK;
	(ch->ch_nd)->nd_tx_work = 1;

	x = (msec * HZ) / 1000;
	wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);

	return 0;
}


/*
 * Return modem signals to ld.
 */
static int dgrp_tty_tiocmget(struct tty_struct *tty)
{
	unsigned int mlast;
	struct un_struct *un = tty->driver_data;
	struct ch_struct *ch;

	if (!un)
		return -ENODEV;

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

	mlast = ((ch->ch_s_mlast & ~(DM_RTS | DM_DTR)) |
		(ch->ch_mout & (DM_RTS | DM_DTR)));

	/* defined in /usr/include/asm/termios.h */
	mlast =   ((mlast & DM_RTS) ? TIOCM_RTS : 0)
		| ((mlast & DM_DTR) ? TIOCM_DTR : 0)
		| ((mlast & DM_CD)  ? TIOCM_CAR : 0)
		| ((mlast & DM_RI)  ? TIOCM_RNG : 0)
		| ((mlast & DM_DSR) ? TIOCM_DSR : 0)
		| ((mlast & DM_CTS) ? TIOCM_CTS : 0);

	return mlast;
}


/*
 *      Set modem lines
 */
static int dgrp_tty_tiocmset(struct tty_struct *tty,
			     unsigned int set, unsigned int clear)
{
	ulong lock_flags;
	struct un_struct *un = tty->driver_data;
	struct ch_struct *ch;

	if (!un)
		return -ENODEV;

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

	if (set & TIOCM_RTS)
		ch->ch_mout |= DM_RTS;

	if (set & TIOCM_DTR)
		ch->ch_mout |= DM_DTR;

	if (clear & TIOCM_RTS)
		ch->ch_mout &= ~(DM_RTS);

	if (clear & TIOCM_DTR)
		ch->ch_mout &= ~(DM_DTR);

	spin_lock_irqsave(&(ch->ch_nd)->nd_lock, lock_flags);
	ch->ch_flag |= CH_PARAM;
	(ch->ch_nd)->nd_tx_work = 1;
	wake_up_interruptible(&ch->ch_flag_wait);

	spin_unlock_irqrestore(&(ch->ch_nd)->nd_lock, lock_flags);

	return 0;
}



/*
 *      Get current modem status
 */
static int get_modem_info(struct ch_struct *ch, unsigned int *value)
{
	unsigned int mlast;

	mlast = ((ch->ch_s_mlast & ~(DM_RTS | DM_DTR)) |
		(ch->ch_mout    &  (DM_RTS | DM_DTR)));

	/* defined in /usr/include/asm/termios.h */
	mlast =   ((mlast & DM_RTS) ? TIOCM_RTS : 0)
		| ((mlast & DM_DTR) ? TIOCM_DTR : 0)
		| ((mlast & DM_CD)  ? TIOCM_CAR : 0)
		| ((mlast & DM_RI)  ? TIOCM_RNG : 0)
		| ((mlast & DM_DSR) ? TIOCM_DSR : 0)
		| ((mlast & DM_CTS) ? TIOCM_CTS : 0);
	put_user(mlast, (unsigned int __user *) value);

	return 0;
}

/*
 *      Set modem lines
 */
static int set_modem_info(struct ch_struct *ch, unsigned int command,
			  unsigned int *value)
{
	int error;
	unsigned int arg;
	int mval = 0;
	ulong lock_flags;

	error = access_ok(VERIFY_READ, (void __user *) value, sizeof(int));
	if (error == 0)
		return -EFAULT;

	get_user(arg, (unsigned int __user *) value);
	mval |= ((arg & TIOCM_RTS) ? DM_RTS : 0)
		| ((arg & TIOCM_DTR) ? DM_DTR : 0);

	switch (command) {
	case TIOCMBIS:  /* set flags */
		ch->ch_mout |= mval;
		break;
	case TIOCMBIC:  /* clear flags */
		ch->ch_mout &= ~mval;
		break;
	case TIOCMSET:
		ch->ch_mout = mval;
		break;
	default:
		return -EINVAL;
	}

	spin_lock_irqsave(&(ch->ch_nd)->nd_lock, lock_flags);

	ch->ch_flag |= CH_PARAM;
	(ch->ch_nd)->nd_tx_work = 1;
	wake_up_interruptible(&ch->ch_flag_wait);

	spin_unlock_irqrestore(&(ch->ch_nd)->nd_lock, lock_flags);

	return 0;
}


/*
 *  Assign the custom baud rate to the channel structure
 */
static void dgrp_set_custom_speed(struct ch_struct *ch, int newrate)
{
	int testdiv;
	int testrate_high;
	int testrate_low;

	int deltahigh, deltalow;

	if (newrate < 0)
		newrate = 0;

	/*
	 * 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 < ((PORTSERVER_DIVIDEND / 0xFFFF) + 1))
		newrate = ((PORTSERVER_DIVIDEND / 0xFFFF) + 1);
	if (newrate && newrate > PORTSERVER_DIVIDEND)
		newrate = PORTSERVER_DIVIDEND;

	while (newrate > 0) {
		testdiv = PORTSERVER_DIVIDEND / newrate;

		/*
		 * If we try to figure out what rate the PortServer 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 = PORTSERVER_DIVIDEND / testdiv;
		testrate_low  = PORTSERVER_DIVIDEND / (testdiv + 1);

		/*
		 * If the rate for the requested divisor is correct, just
		 * use it and be done.
		 */
		if (testrate_high == newrate)
			break;

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

		break;
	}

	ch->ch_custom_speed = newrate;

	drp_param(ch);

	return;
}


/*
 # dgrp_tty_digiseta()
 *
 * Ioctl to set the information from ditty.
 *
 * NOTE: DIGI_IXON, DSRPACE, DCDPACE, and DTRPACE are unsupported.  JAR 990922
 */
static int dgrp_tty_digiseta(struct tty_struct *tty,
			     struct digi_struct *new_info)
{
	struct un_struct *un = tty->driver_data;
	struct ch_struct *ch;

	if (!un)
		return -ENODEV;

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

	if (copy_from_user(&ch->ch_digi, (void __user *) new_info,
			   sizeof(struct digi_struct)))
		return -EFAULT;

	if ((ch->ch_digi.digi_flags & RTSPACE) ||
	    (ch->ch_digi.digi_flags & CTSPACE))
		tty->termios.c_cflag |= CRTSCTS;
	else
		tty->termios.c_cflag &= ~CRTSCTS;

	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;

	/* make the changes now */
	drp_param(ch);

	return 0;
}



/*
 * dgrp_tty_digigetedelay()
 *
 * Ioctl to get the current edelay setting.
 *
 *
 *
 */
static int dgrp_tty_digigetedelay(struct tty_struct *tty, int *retinfo)
{
	struct un_struct *un;
	struct ch_struct *ch;
	int tmp;

	if (!retinfo)
		return -EFAULT;

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

	un = tty->driver_data;

	if (!un)
		return -ENODEV;

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

	tmp = ch->ch_edelay;

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

	return 0;
}


/*
 * dgrp_tty_digisetedelay()
 *
 * Ioctl to set the EDELAY setting
 *
 */
static int dgrp_tty_digisetedelay(struct tty_struct *tty, int *new_info)
{
	struct un_struct *un;
	struct ch_struct *ch;
	int new_digi;

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

	un = tty->driver_data;

	if (!un)
		return -ENODEV;

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

	if (copy_from_user(&new_digi, (void __user *)new_info, sizeof(int)))
		return -EFAULT;

	ch->ch_edelay = new_digi;

	/* make the changes now */
	drp_param(ch);

	return 0;
}


/*
 *	The usual assortment of ioctl's
 *
 *	note:  use tty_check_change to make sure that we are not
 *	changing the state of a terminal when we are not a process
 *	in the forground.  See tty_io.c
 *		rc = tty_check_change(tty);
 *		if (rc) return rc;
 */
static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
			  unsigned long arg)
{
	struct un_struct *un;
	struct ch_struct *ch;
	int rc;
	struct digiflow_struct   dflow;

	if (!tty)
		return -ENODEV;

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

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

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

		rc = tty_check_change(tty);
		if (rc)
			return rc;
		tty_wait_until_sent(tty, 0);

		if (!arg)
			rc = dgrp_send_break(ch, 250); /* 1/4 second */

		if (dgrp_tty_chars_in_buffer(tty) != 0)
			return -EINTR;

		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);
		if (rc)
			return rc;
		tty_wait_until_sent(tty, 0);

		rc = dgrp_send_break(ch, arg ? arg*250 : 250);

		if (dgrp_tty_chars_in_buffer(tty) != 0)
			return -EINTR;
		return 0;

	case TIOCSBRK:
		rc = tty_check_change(tty);
		if (rc)
			return rc;
		tty_wait_until_sent(tty, 0);

		/*
		 * RealPort doesn't support turning on a break unconditionally.
		 * The RealPort device will stop sending a break automatically
		 * after the specified time value that we send in.
		 */
		rc = dgrp_send_break(ch, 250); /* 1/4 second */

		if (dgrp_tty_chars_in_buffer(tty) != 0)
			return -EINTR;
		return 0;

	case TIOCCBRK:
		/*
		 * RealPort doesn't support turning off a break unconditionally.
		 * The RealPort device will stop sending a break automatically
		 * after the specified time value that was sent when turning on
		 * the break.
		 */
		return 0;

	case TIOCGSOFTCAR:
		rc = access_ok(VERIFY_WRITE, (void __user *) arg,
			       sizeof(long));
		if (rc == 0)
			return -EFAULT;
		put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) arg);
		return 0;

	case TIOCSSOFTCAR:
		get_user(arg, (unsigned long __user *) arg);
		tty->termios.c_cflag =
			((tty->termios.c_cflag & ~CLOCAL) |
			 (arg ? CLOCAL : 0));
		return 0;

	case TIOCMGET:
		rc = access_ok(VERIFY_WRITE, (void __user *) arg,
				 sizeof(unsigned int));
		if (rc == 0)
			return -EFAULT;
		return get_modem_info(ch, (unsigned int *) arg);

	case TIOCMBIS:
	case TIOCMBIC:
	case TIOCMSET:
		return set_modem_info(ch, cmd, (unsigned int *) arg);

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

		switch (arg) {
		case TCIFLUSH:
		case TCIOFLUSH:
			/* only flush input if this is the only open unit */
			if (!IS_PRINT(MINOR(tty_devnum(tty)))) {
				ch->ch_rout = ch->ch_rin;
				ch->ch_send |= RR_RX_FLUSH;
				(ch->ch_nd)->nd_tx_work = 1;
				(ch->ch_nd)->nd_tx_ready = 1;
				wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
			}
			if (arg == TCIFLUSH)
				break;

		case TCOFLUSH: /* flush output, or the receive buffer */
			/*
			 * This is handled in the tty_ioctl.c code
			 * calling tty_flush_buffer
			 */
			break;

		default:
			/* POSIX.1 says return EINVAL if we got a bad arg */
			return -EINVAL;
		}
		/* pretend we didn't recognize this IOCTL */
		return -ENOIOCTLCMD;

#ifdef TIOCGETP
	case TIOCGETP:
#endif
	/*****************************************
	Linux		HPUX		Function
	TCSETA		TCSETA		- set the termios
	TCSETAF		TCSETAF		- wait for drain first, then set termios
	TCSETAW		TCSETAW		- wait for drain, flush the input queue, then set termios
	- looking at the tty_ioctl code, these command all call our
	tty_set_termios at the driver's end, when a TCSETA* is sent,
	it is expecting the tty to have a termio structure,
	NOT a termios stucture.  These two structures differ in size
	and the tty_ioctl code does a conversion before processing them both.
	- we should treat the TCSETAW TCSETAF ioctls the same, and let
	the tty_ioctl code do the conversion stuff.

	TCSETS
	TCSETSF		(none)
	TCSETSW
	- the associated tty structure has a termios structure.
	*****************************************/

	case TCGETS:
	case TCGETA:
		return -ENOIOCTLCMD;

	case TCSETAW:
	case TCSETAF:
	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.
		 */

		/*
		 * Also, now that we have TXPrint, we have to check
		 * if this is the TXPrint device and the terminal
		 * device is open. If so, do NOT run check_change,
		 * as the terminal device is ALWAYS the parent.
		 */
		if (!IS_PRINT(MINOR(tty_devnum(tty))) ||
		    !ch->ch_tun.un_open_count) {
			rc = tty_check_change(tty);
			if (rc)
				return rc;
		}

		/* wait for all the characters in tbuf to drain */
		tty_wait_until_sent(tty, 0);

		if ((cmd == TCSETSF) || (cmd == TCSETAF)) {
			/* flush the contents of the rbuf queue */
			/* TODO:  check if this is print device? */
			ch->ch_send |= RR_RX_FLUSH;
			(ch->ch_nd)->nd_tx_ready = 1;
			(ch->ch_nd)->nd_tx_work = 1;
			wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
			/* do we need to do this?  just to be safe! */
			ch->ch_rout = ch->ch_rin;
		}

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

	case TCXONC:
		/*
		 * The Linux Line Discipline (LD) would do this for us if we
		 * let it, but we have the special firmware options to do this
		 * the "right way" regardless of hardware or software flow
		 * control so we'll do it outselves instead of letting the LD
		 * do it.
		 */
		rc = tty_check_change(tty);
		if (rc)
			return rc;

		switch (arg) {
		case TCOON:
			dgrp_tty_start(tty);
			return 0;
		case TCOOFF:
			dgrp_tty_stop(tty);
			return 0;
		case TCION:
			dgrp_tty_input_start(tty);
			return 0;
		case TCIOFF:
			dgrp_tty_input_stop(tty);
			return 0;
		default:
			return -EINVAL;
		}

	case DIGI_GETA:
		/* get information for ditty */
		if (copy_to_user((struct digi_struct __user *) arg,
				 &ch->ch_digi, sizeof(struct digi_struct)))
			return -EFAULT;
		break;

	case DIGI_SETAW:
	case DIGI_SETAF:
		/* wait for all the characters in tbuf to drain */
		tty_wait_until_sent(tty, 0);

		if (cmd == DIGI_SETAF) {
			/* flush the contents of the rbuf queue */
			/* send down a packet with RR_RX_FLUSH set */
			ch->ch_send |= RR_RX_FLUSH;
			(ch->ch_nd)->nd_tx_ready = 1;
			(ch->ch_nd)->nd_tx_work = 1;
			wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
			/* do we need to do this?  just to be safe! */
			ch->ch_rout = ch->ch_rin;
		}

		/* pretend we didn't recognize this */

	case DIGI_SETA:
		return dgrp_tty_digiseta(tty, (struct digi_struct *) arg);

	case DIGI_SEDELAY:
		return dgrp_tty_digisetedelay(tty, (int *) arg);

	case DIGI_GEDELAY:
		return dgrp_tty_digigetedelay(tty, (int *) arg);

	case DIGI_GETFLOW:
	case DIGI_GETAFLOW:
		if (cmd == (DIGI_GETFLOW)) {
			dflow.startc = tty->termios.c_cc[VSTART];
			dflow.stopc = tty->termios.c_cc[VSTOP];
		} else {
			dflow.startc = ch->ch_xxon;
			dflow.stopc = ch->ch_xxoff;
		}

		if (copy_to_user((char __user *)arg, &dflow, sizeof(dflow)))
			return -EFAULT;
		break;

	case DIGI_SETFLOW:
	case DIGI_SETAFLOW:

		if (copy_from_user(&dflow, (char __user *)arg, sizeof(dflow)))
			return -EFAULT;

		if (cmd == (DIGI_SETFLOW)) {
			tty->termios.c_cc[VSTART] = dflow.startc;
			tty->termios.c_cc[VSTOP] = dflow.stopc;
		} else {
			ch->ch_xxon = dflow.startc;
			ch->ch_xxoff = dflow.stopc;
		}
		break;

	case DIGI_GETCUSTOMBAUD:
		rc = access_ok(VERIFY_WRITE, (void __user *) arg, sizeof(int));
		if (rc == 0)
			return -EFAULT;
		put_user(ch->ch_custom_speed, (unsigned int __user *) arg);
		break;

	case DIGI_SETCUSTOMBAUD:
	{
		int new_rate;

		get_user(new_rate, (unsigned int __user *) arg);
		dgrp_set_custom_speed(ch, new_rate);

		break;
	}

	default:
		return -ENOIOCTLCMD;
	}

	return 0;
}

/*
 *  This routine allows the tty driver to be notified when
 *  the device's termios setting have changed.  Note that we
 *  should be prepared to accept the case where old == NULL
 *  and try to do something rational.
 *
 *  So we need to make sure that our copies of ch_oflag,
 *  ch_clag, and ch_iflag reflect the tty->termios flags.
 */
static void dgrp_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
{
	struct ktermios *ts;
	struct ch_struct *ch;
	struct un_struct *un;

	/* seems silly, but we have to check all these! */
	if (!tty)
		return;

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

	ts = &tty->termios;

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

	drp_param(ch);

	/* the CLOCAL flag has just been set */
	if (!(old->c_cflag & CLOCAL) && C_CLOCAL(tty))
		wake_up_interruptible(&un->un_open_wait);
}


/*
 *	Throttle receiving data.  We just set a bit and stop reading
 *	data out of the channel buffer.  It will back up and the
 *	FEP will do whatever is necessary to stop the far end.
 */
static void dgrp_tty_throttle(struct tty_struct *tty)
{
	struct ch_struct *ch;

	if (!tty)
		return;

	ch = ((struct un_struct *) tty->driver_data)->un_ch;
	if (!ch)
		return;

	ch->ch_flag |= CH_RXSTOP;
}


static void dgrp_tty_unthrottle(struct tty_struct *tty)
{
	struct ch_struct *ch;

	if (!tty)
		return;

	ch = ((struct un_struct *) tty->driver_data)->un_ch;
	if (!ch)
		return;

	ch->ch_flag &= ~CH_RXSTOP;
}

/*
 *	Stop the transmitter
 */
static void dgrp_tty_stop(struct tty_struct *tty)
{
	struct ch_struct *ch;

	if (!tty)
		return;

	ch = ((struct un_struct *) tty->driver_data)->un_ch;
	if (!ch)
		return;

	ch->ch_send |= RR_TX_STOP;
	ch->ch_send &= ~RR_TX_START;

	/* make the change NOW! */
	(ch->ch_nd)->nd_tx_ready = 1;
	if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
		wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
}

/*
 *	Start the transmitter
 */
static void dgrp_tty_start(struct tty_struct *tty)
{
	struct ch_struct *ch;

	if (!tty)
		return;

	ch = ((struct un_struct *) tty->driver_data)->un_ch;
	if (!ch)
		return;

	/* TODO: don't do anything if the transmitter is not stopped */

	ch->ch_send |= RR_TX_START;
	ch->ch_send &= ~RR_TX_STOP;

	/* make the change NOW! */
	(ch->ch_nd)->nd_tx_ready = 1;
	(ch->ch_nd)->nd_tx_work = 1;
	if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
		wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);

}

/*
 *	Stop the reciever
 */
static void dgrp_tty_input_stop(struct tty_struct *tty)
{
	struct ch_struct *ch;

	if (!tty)
		return;

	ch = ((struct un_struct *) tty->driver_data)->un_ch;
	if (!ch)
		return;

	ch->ch_send |= RR_RX_STOP;
	ch->ch_send &= ~RR_RX_START;
	(ch->ch_nd)->nd_tx_ready = 1;
	if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
		wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);

}


static void dgrp_tty_send_xchar(struct tty_struct *tty, char c)
{
	struct un_struct *un;
	struct ch_struct *ch;

	if (!tty)
		return;

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

	ch = un->un_ch;
	if (!ch)
		return;
	if (c == STOP_CHAR(tty))
		ch->ch_send |= RR_RX_STOP;
	else if (c == START_CHAR(tty))
		ch->ch_send |= RR_RX_START;

	ch->ch_nd->nd_tx_ready = 1;
	ch->ch_nd->nd_tx_work = 1;

	return;
}


static void dgrp_tty_input_start(struct tty_struct *tty)
{
	struct ch_struct *ch;

	if (!tty)
		return;

	ch = ((struct un_struct *) tty->driver_data)->un_ch;
	if (!ch)
		return;

	ch->ch_send |= RR_RX_START;
	ch->ch_send &= ~RR_RX_STOP;
	(ch->ch_nd)->nd_tx_ready = 1;
	(ch->ch_nd)->nd_tx_work = 1;
	if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
		wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);

}


/*
 *	Hangup the port.  Like a close, but don't wait for output
 *	to drain.
 *
 *	How do we close all the channels that are open?
 */
static void dgrp_tty_hangup(struct tty_struct *tty)
{
	struct ch_struct *ch;
	struct nd_struct *nd;
	struct un_struct *un;

	if (!tty)
		return;

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

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

	nd = ch->ch_nd;

	if (C_HUPCL(tty)) {
		/* LOWER DTR */
		ch->ch_mout &= ~DM_DTR;
		/* Don't do this here */
		/* ch->ch_flag |= CH_HANGUP; */
		ch->ch_nd->nd_tx_ready = 1;
		ch->ch_nd->nd_tx_work  = 1;
		if (waitqueue_active(&ch->ch_flag_wait))
			wake_up_interruptible(&ch->ch_flag_wait);
	}

}

/************************************************************************/
/*                                                                      */
/*       TTY Initialization/Cleanup Functions                           */
/*                                                                      */
/************************************************************************/

/*
 *	Uninitialize the TTY portion of the supplied node.  Free all
 *      memory and resources associated with this node.  Do it in reverse
 *      allocation order: this might possibly result in less fragmentation
 *      of memory, though I don't know this for sure.
 */
void
dgrp_tty_uninit(struct nd_struct *nd)
{
	char id[3];

	ID_TO_CHAR(nd->nd_ID, id);

	if (nd->nd_ttdriver_flags & SERIAL_TTDRV_REG) {
		tty_unregister_driver(nd->nd_serial_ttdriver);

		kfree(nd->nd_serial_ttdriver->ttys);
		nd->nd_serial_ttdriver->ttys = NULL;

		put_tty_driver(nd->nd_serial_ttdriver);
		nd->nd_ttdriver_flags &= ~SERIAL_TTDRV_REG;
	}

	if (nd->nd_ttdriver_flags & CALLOUT_TTDRV_REG) {
		tty_unregister_driver(nd->nd_callout_ttdriver);

		kfree(nd->nd_callout_ttdriver->ttys);
		nd->nd_callout_ttdriver->ttys = NULL;

		put_tty_driver(nd->nd_callout_ttdriver);
		nd->nd_ttdriver_flags &= ~CALLOUT_TTDRV_REG;
	}

	if (nd->nd_ttdriver_flags & XPRINT_TTDRV_REG) {
		tty_unregister_driver(nd->nd_xprint_ttdriver);

		kfree(nd->nd_xprint_ttdriver->ttys);
		nd->nd_xprint_ttdriver->ttys = NULL;

		put_tty_driver(nd->nd_xprint_ttdriver);
		nd->nd_ttdriver_flags &= ~XPRINT_TTDRV_REG;
	}
}



/*
 *     Initialize the TTY portion of the supplied node.
 */
int
dgrp_tty_init(struct nd_struct *nd)
{
	char id[3];
	int  rc;
	int  i;

	ID_TO_CHAR(nd->nd_ID, id);

	/*
	 *  Initialize the TTDRIVER structures.
	 */

	nd->nd_serial_ttdriver = alloc_tty_driver(CHAN_MAX);
	if (!nd->nd_serial_ttdriver)
		return -ENOMEM;

	sprintf(nd->nd_serial_name,  "tty_dgrp_%s_", id);

	nd->nd_serial_ttdriver->owner = THIS_MODULE;
	nd->nd_serial_ttdriver->name = nd->nd_serial_name;
	nd->nd_serial_ttdriver->name_base = 0;
	nd->nd_serial_ttdriver->major = 0;
	nd->nd_serial_ttdriver->minor_start = 0;
	nd->nd_serial_ttdriver->type = TTY_DRIVER_TYPE_SERIAL;
	nd->nd_serial_ttdriver->subtype = SERIAL_TYPE_NORMAL;
	nd->nd_serial_ttdriver->init_termios = DefaultTermios;
	nd->nd_serial_ttdriver->driver_name = "dgrp";
	nd->nd_serial_ttdriver->flags = (TTY_DRIVER_REAL_RAW |
					 TTY_DRIVER_DYNAMIC_DEV |
					 TTY_DRIVER_HARDWARE_BREAK);

	/* The kernel wants space to store pointers to tty_structs. */
	nd->nd_serial_ttdriver->ttys =
		kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL);
	if (!nd->nd_serial_ttdriver->ttys)
		return -ENOMEM;

	tty_set_operations(nd->nd_serial_ttdriver, &dgrp_tty_ops);

	if (!(nd->nd_ttdriver_flags & SERIAL_TTDRV_REG)) {
		/*
		 *   Register tty devices
		 */
		rc = tty_register_driver(nd->nd_serial_ttdriver);
		if (rc < 0) {
			/*
			 * If errno is EBUSY, this means there are no more
			 * slots available to have us auto-majored.
			 * (Which is currently supported up to 256)
			 *
			 * We can still request majors above 256,
			 * we just have to do it manually.
			 */
			if (rc == -EBUSY) {
				int i;
				int max_majors = 1U << (32 - MINORBITS);
				for (i = 256; i < max_majors; i++) {
					nd->nd_serial_ttdriver->major = i;
					rc = tty_register_driver(nd->nd_serial_ttdriver);
					if (rc >= 0)
						break;
				}
				/* Really fail now, since we ran out
				 * of majors to try. */
				if (i == max_majors)
					return rc;

			} else {
				return rc;
			}
		}
		nd->nd_ttdriver_flags |= SERIAL_TTDRV_REG;
	}

	nd->nd_callout_ttdriver = alloc_tty_driver(CHAN_MAX);
	if (!nd->nd_callout_ttdriver)
		return -ENOMEM;

	sprintf(nd->nd_callout_name, "cu_dgrp_%s_",  id);

	nd->nd_callout_ttdriver->owner = THIS_MODULE;
	nd->nd_callout_ttdriver->name = nd->nd_callout_name;
	nd->nd_callout_ttdriver->name_base = 0;
	nd->nd_callout_ttdriver->major = nd->nd_serial_ttdriver->major;
	nd->nd_callout_ttdriver->minor_start = 0x40;
	nd->nd_callout_ttdriver->type = TTY_DRIVER_TYPE_SERIAL;
	nd->nd_callout_ttdriver->subtype = SERIAL_TYPE_CALLOUT;
	nd->nd_callout_ttdriver->init_termios = DefaultTermios;
	nd->nd_callout_ttdriver->driver_name = "dgrp";
	nd->nd_callout_ttdriver->flags = (TTY_DRIVER_REAL_RAW |
					  TTY_DRIVER_DYNAMIC_DEV |
					  TTY_DRIVER_HARDWARE_BREAK);

	/* The kernel wants space to store pointers to tty_structs. */
	nd->nd_callout_ttdriver->ttys =
		kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL);
	if (!nd->nd_callout_ttdriver->ttys)
		return -ENOMEM;

	tty_set_operations(nd->nd_callout_ttdriver, &dgrp_tty_ops);

	if (dgrp_register_cudevices) {
		if (!(nd->nd_ttdriver_flags & CALLOUT_TTDRV_REG)) {
			/*
			 *   Register cu devices
			 */
			rc = tty_register_driver(nd->nd_callout_ttdriver);
			if (rc < 0)
				return rc;
			nd->nd_ttdriver_flags |= CALLOUT_TTDRV_REG;
		}
	}


	nd->nd_xprint_ttdriver = alloc_tty_driver(CHAN_MAX);
	if (!nd->nd_xprint_ttdriver)
		return -ENOMEM;

	sprintf(nd->nd_xprint_name,  "pr_dgrp_%s_", id);

	nd->nd_xprint_ttdriver->owner = THIS_MODULE;
	nd->nd_xprint_ttdriver->name = nd->nd_xprint_name;
	nd->nd_xprint_ttdriver->name_base = 0;
	nd->nd_xprint_ttdriver->major = nd->nd_serial_ttdriver->major;
	nd->nd_xprint_ttdriver->minor_start = 0x80;
	nd->nd_xprint_ttdriver->type = TTY_DRIVER_TYPE_SERIAL;
	nd->nd_xprint_ttdriver->subtype = SERIAL_TYPE_XPRINT;
	nd->nd_xprint_ttdriver->init_termios = DefaultTermios;
	nd->nd_xprint_ttdriver->driver_name = "dgrp";
	nd->nd_xprint_ttdriver->flags = (TTY_DRIVER_REAL_RAW |
					 TTY_DRIVER_DYNAMIC_DEV |
					 TTY_DRIVER_HARDWARE_BREAK);

	/* The kernel wants space to store pointers to tty_structs. */
	nd->nd_xprint_ttdriver->ttys =
		kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL);
	if (!nd->nd_xprint_ttdriver->ttys)
		return -ENOMEM;

	tty_set_operations(nd->nd_xprint_ttdriver, &dgrp_tty_ops);

	if (dgrp_register_prdevices) {
		if (!(nd->nd_ttdriver_flags & XPRINT_TTDRV_REG)) {
			/*
			 *   Register transparent print devices
			 */
			rc = tty_register_driver(nd->nd_xprint_ttdriver);
			if (rc < 0)
				return rc;
			nd->nd_ttdriver_flags |= XPRINT_TTDRV_REG;
		}
	}

	for (i = 0; i < CHAN_MAX; i++) {
		struct ch_struct *ch = nd->nd_chan + i;

		ch->ch_nd = nd;
		ch->ch_digi = digi_init;
		ch->ch_edelay = 100;
		ch->ch_custom_speed = 0;
		ch->ch_portnum = i;
		ch->ch_tun.un_ch = ch;
		ch->ch_pun.un_ch = ch;
		ch->ch_tun.un_type = SERIAL_TYPE_NORMAL;
		ch->ch_pun.un_type = SERIAL_TYPE_XPRINT;

		init_waitqueue_head(&(ch->ch_flag_wait));
		init_waitqueue_head(&(ch->ch_sleep));

		init_waitqueue_head(&(ch->ch_tun.un_open_wait));
		init_waitqueue_head(&(ch->ch_tun.un_close_wait));

		init_waitqueue_head(&(ch->ch_pun.un_open_wait));
		init_waitqueue_head(&(ch->ch_pun.un_close_wait));
		tty_port_init(&ch->port);
		tty_port_init(&ch->port);
	}
	return 0;
}
