/*
 *
 * 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/device.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 changeable 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);
	return put_user(mlast, (unsigned int __user *) value);
}

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

	if (get_user(arg, (unsigned int __user *) value))
		return -EFAULT;
	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 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 structure.  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:
		if (put_user(ch->ch_custom_speed, (unsigned int __user *) arg))
			return -EFAULT;
		break;

	case DIGI_SETCUSTOMBAUD:
	{
		int new_rate;

		if (get_user(new_rate, (unsigned int __user *) arg))
			return -EFAULT;
		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 receiver
 */
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)
{
	unsigned int i;
	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;
	}
	for (i = 0; i < CHAN_MAX; i++)
		tty_port_destroy(&nd->nd_chan[i].port);
}



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