/*
 *
 * Copyright 1999 Digi International (www.digi.com)
 *     James Puzzo  <jamesp 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_net_ops.c
 *
 *  Description:
 *
 *     Handle the file operations required for the "network" devices.
 *     Includes those functions required to register the "net" devices
 *     in "/proc".
 *
 *  Author:
 *
 *     James A. Puzzo
 *
 */

#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/spinlock.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/ratelimit.h>
#include <asm/unaligned.h>

#define MYFLIPLEN	TBUF_MAX

#include "dgrp_common.h"

#define TTY_FLIPBUF_SIZE 512
#define DEVICE_NAME_SIZE 50

/*
 *  Generic helper function declarations
 */
static void   parity_scan(struct ch_struct *ch, unsigned char *cbuf,
				unsigned char *fbuf, int *len);

/*
 *  File operation declarations
 */
static int dgrp_net_open(struct inode *, struct file *);
static int dgrp_net_release(struct inode *, struct file *);
static ssize_t dgrp_net_read(struct file *, char __user *, size_t, loff_t *);
static ssize_t dgrp_net_write(struct file *, const char __user *, size_t,
			      loff_t *);
static long dgrp_net_ioctl(struct file *file, unsigned int cmd,
			   unsigned long arg);
static unsigned int dgrp_net_select(struct file *file,
				    struct poll_table_struct *table);

const struct file_operations dgrp_net_ops = {
	.owner   =  THIS_MODULE,
	.read    =  dgrp_net_read,
	.write   =  dgrp_net_write,
	.poll    =  dgrp_net_select,
	.unlocked_ioctl =  dgrp_net_ioctl,
	.open    =  dgrp_net_open,
	.release =  dgrp_net_release,
};

/**
 * dgrp_dump() -- prints memory for debugging purposes.
 * @mem: Memory location which should be printed to the console
 * @len: Number of bytes to be dumped
 */
static void dgrp_dump(u8 *mem, int len)
{
	int i;

	pr_debug("dgrp dump length = %d, data = ", len);
	for (i = 0; i < len; ++i)
		pr_debug("%.2x ", mem[i]);
	pr_debug("\n");
}

/**
 * dgrp_read_data_block() -- Read a data block
 * @ch: struct ch_struct *
 * @flipbuf: u8 *
 * @flipbuf_size: size of flipbuf
 */
static void dgrp_read_data_block(struct ch_struct *ch, u8 *flipbuf,
				 int flipbuf_size)
{
	int t;
	int n;

	if (flipbuf_size <= 0)
		return;

	t = RBUF_MAX - ch->ch_rout;
	n = flipbuf_size;

	if (n >= t) {
		memcpy(flipbuf, ch->ch_rbuf + ch->ch_rout, t);
		flipbuf += t;
		n -= t;
		ch->ch_rout = 0;
	}

	memcpy(flipbuf, ch->ch_rbuf + ch->ch_rout, n);
	flipbuf += n;
	ch->ch_rout += n;
}


/**
 * dgrp_input() -- send data to the line disipline
 * @ch: pointer to channel struct
 *
 * Copys the rbuf to the flipbuf and sends to line discipline.
 * Sends input buffer data to the line discipline.
 *
 */
static void dgrp_input(struct ch_struct *ch)
{
	struct nd_struct *nd;
	struct tty_struct *tty;
	int data_len;
	int len;
	int tty_count;
	ulong lock_flags;
	u8  *myflipbuf;
	u8  *myflipflagbuf;

	if (!ch)
		return;

	nd = ch->ch_nd;

	if (!nd)
		return;

	spin_lock_irqsave(&nd->nd_lock, lock_flags);

	myflipbuf = nd->nd_inputbuf;
	myflipflagbuf = nd->nd_inputflagbuf;

	if (!ch->ch_open_count) {
		ch->ch_rout = ch->ch_rin;
		goto out;
	}

	if (ch->ch_tun.un_flag & UN_CLOSING) {
		ch->ch_rout = ch->ch_rin;
		goto out;
	}

	tty = (ch->ch_tun).un_tty;


	if (!tty || tty->magic != TTY_MAGIC) {
		ch->ch_rout = ch->ch_rin;
		goto out;
	}

	tty_count = tty->count;
	if (!tty_count) {
		ch->ch_rout = ch->ch_rin;
		goto out;
	}

	if (tty->closing || test_bit(TTY_CLOSING, &tty->flags)) {
		ch->ch_rout = ch->ch_rin;
		goto out;
	}

	spin_unlock_irqrestore(&nd->nd_lock, lock_flags);

	/* data_len should be the number of chars that we read in */
	data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK;

	/* len is the amount of data we are going to transfer here */
	len = tty_buffer_request_room(&ch->port, data_len);

	/* Check DPA flow control */
	if ((nd->nd_dpa_debug) &&
	    (nd->nd_dpa_flag & DPA_WAIT_SPACE) &&
	    (nd->nd_dpa_port == MINOR(tty_devnum(ch->ch_tun.un_tty))))
		len = 0;

	if ((len) && !(ch->ch_flag & CH_RXSTOP)) {

		dgrp_read_data_block(ch, myflipbuf, len);

		if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty))
			parity_scan(ch, myflipbuf, myflipflagbuf, &len);
		else
			memset(myflipflagbuf, TTY_NORMAL, len);

		if ((nd->nd_dpa_debug) &&
		    (nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty)))))
			dgrp_dpa_data(nd, 1, myflipbuf, len);

		tty_insert_flip_string_flags(&ch->port, myflipbuf,
					     myflipflagbuf, len);
		tty_flip_buffer_push(&ch->port);

		ch->ch_rxcount += len;
	}

	/*
	 * Wake up any sleepers (maybe dgrp close) that might be waiting
	 * for a channel flag state change.
	 */
	wake_up_interruptible(&ch->ch_flag_wait);
	return;

out:
	spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
}


/*
 *  parity_scan
 *
 *  Loop to inspect each single character or 0xFF escape.
 *
 *  if PARMRK & ~DOSMODE:
 *     0xFF  0xFF           Normal 0xFF character, escaped
 *                          to eliminate confusion.
 *     0xFF  0x00  0x00     Break
 *     0xFF  0x00  CC       Error character CC.
 *     CC                   Normal character CC.
 *
 *  if PARMRK & DOSMODE:
 *     0xFF  0x18  0x00     Break
 *     0xFF  0x08  0x00     Framing Error
 *     0xFF  0x04  0x00     Parity error
 *     0xFF  0x0C  0x00     Both Framing and Parity error
 *
 *  TODO:  do we need to do the XMODEM, XOFF, XON, XANY processing??
 *         as per protocol
 */
static void parity_scan(struct ch_struct *ch, unsigned char *cbuf,
			unsigned char *fbuf, int *len)
{
	int l = *len;
	int count = 0;
	int DOS = ((ch->ch_iflag & IF_DOSMODE) == 0 ? 0 : 1);
	unsigned char *cout; /* character buffer */
	unsigned char *fout; /* flag buffer */
	unsigned char *in;
	unsigned char c;

	in = cbuf;
	cout = cbuf;
	fout = fbuf;

	while (l--) {
		c = *in;
		in++;

		switch (ch->ch_pscan_state) {
		default:
			/* reset to sanity and fall through */
			ch->ch_pscan_state = 0;

		case 0:
			/* No FF seen yet */
			if (c == 0xff) /* delete this character from stream */
				ch->ch_pscan_state = 1;
			else {
				*cout++ = c;
				*fout++ = TTY_NORMAL;
				count += 1;
			}
			break;

		case 1:
			/* first FF seen */
			if (c == 0xff) {
				/* doubled ff, transform to single ff */
				*cout++ = c;
				*fout++ = TTY_NORMAL;
				count += 1;
				ch->ch_pscan_state = 0;
			} else {
				/* save value examination in next state */
				ch->ch_pscan_savechar = c;
				ch->ch_pscan_state = 2;
			}
			break;

		case 2:
			/* third character of ff sequence */
			*cout++ = c;
			if (DOS) {
				if (ch->ch_pscan_savechar & 0x10)
					*fout++ = TTY_BREAK;
				else if (ch->ch_pscan_savechar & 0x08)
					*fout++ = TTY_FRAME;
				else
					/*
					 * either marked as a parity error,
					 * indeterminate, or not in DOSMODE
					 * call it a parity error
					 */
					*fout++ = TTY_PARITY;
			} else {
				/* case FF XX ?? where XX is not 00 */
				if (ch->ch_pscan_savechar & 0xff) {
					/* this should not happen */
					pr_info("%s: parity_scan: error unexpected byte\n",
						__func__);
					*fout++ = TTY_PARITY;
				}
				/* case FF 00 XX where XX is not 00 */
				else if (c == 0xff)
					*fout++ = TTY_PARITY;
				/* case FF 00 00 */
				else
					*fout++ = TTY_BREAK;

			}
			count += 1;
			ch->ch_pscan_state = 0;
		}
	}
	*len = count;
}


/**
 * dgrp_net_idle() -- Idle the network connection
 * @nd: pointer to node structure to idle
 */
static void dgrp_net_idle(struct nd_struct *nd)
{
	struct ch_struct *ch;
	int i;

	nd->nd_tx_work = 1;

	nd->nd_state = NS_IDLE;
	nd->nd_flag = 0;

	for (i = nd->nd_seq_out; ; i = (i + 1) & SEQ_MASK) {
		if (!nd->nd_seq_wait[i]) {
			nd->nd_seq_wait[i] = 0;
			wake_up_interruptible(&nd->nd_seq_wque[i]);
		}

		if (i == nd->nd_seq_in)
			break;
	}

	nd->nd_seq_out = nd->nd_seq_in;

	nd->nd_unack = 0;
	nd->nd_remain = 0;

	nd->nd_tx_module = 0x10;
	nd->nd_rx_module = 0x00;

	for (i = 0, ch = nd->nd_chan; i < CHAN_MAX; i++, ch++) {
		ch->ch_state = CS_IDLE;

		ch->ch_otype = 0;
		ch->ch_otype_waiting = 0;
	}
}

/*
 *  Increase the number of channels, waking up any
 *  threads that might be waiting for the channels
 *  to appear.
 */
static void increase_channel_count(struct nd_struct *nd, int n)
{
	struct ch_struct *ch;
	struct device *classp;
	char name[DEVICE_NAME_SIZE];
	int ret;
	u8 *buf;
	int i;

	for (i = nd->nd_chan_count; i < n; ++i) {
		ch = nd->nd_chan + i;

		/* FIXME: return a useful error instead! */
		buf = kmalloc(TBUF_MAX, GFP_KERNEL);
		if (!buf)
			return;

		if (ch->ch_tbuf)
			pr_info_ratelimited("%s - ch_tbuf was not NULL\n",
					    __func__);

		ch->ch_tbuf = buf;

		buf = kmalloc(RBUF_MAX, GFP_KERNEL);
		if (!buf)
			return;

		if (ch->ch_rbuf)
			pr_info("%s - ch_rbuf was not NULL\n",
				__func__);
		ch->ch_rbuf = buf;

		classp = tty_port_register_device(&ch->port,
						  nd->nd_serial_ttdriver, i,
						  NULL);

		ch->ch_tun.un_sysfs = classp;
		snprintf(name, DEVICE_NAME_SIZE, "tty_%d", i);

		dgrp_create_tty_sysfs(&ch->ch_tun, classp);
		ret = sysfs_create_link(&nd->nd_class_dev->kobj,
					&classp->kobj, name);

		/* NOTE: We don't support "cu" devices anymore,
		 * so you will notice we don't register them
		 * here anymore. */
		if (dgrp_register_prdevices) {
			classp = tty_register_device(nd->nd_xprint_ttdriver,
						     i, NULL);
			ch->ch_pun.un_sysfs = classp;
			snprintf(name, DEVICE_NAME_SIZE, "pr_%d", i);

			dgrp_create_tty_sysfs(&ch->ch_pun, classp);
			ret = sysfs_create_link(&nd->nd_class_dev->kobj,
						&classp->kobj, name);
		}

		nd->nd_chan_count = i + 1;
		wake_up_interruptible(&ch->ch_flag_wait);
	}
}

/*
 * Decrease the number of channels, and wake up any threads that might
 * be waiting on the channels that vanished.
 */
static void decrease_channel_count(struct nd_struct *nd, int n)
{
	struct ch_struct *ch;
	char name[DEVICE_NAME_SIZE];
	int i;

	for (i = nd->nd_chan_count - 1; i >= n; --i) {
		ch = nd->nd_chan + i;

		/*
		 *  Make any open ports inoperative.
		 */
		ch->ch_state = CS_IDLE;

		ch->ch_otype = 0;
		ch->ch_otype_waiting = 0;

		/*
		 *  Only "HANGUP" if we care about carrier
		 *  transitions and we are already open.
		 */
		if (ch->ch_open_count != 0) {
			ch->ch_flag |= CH_HANGUP;
			dgrp_carrier(ch);
		}

		/*
		 * Unlike the CH_HANGUP flag above, use another
		 * flag to indicate to the RealPort state machine
		 * that this port has disappeared.
		 */
		if (ch->ch_open_count != 0)
			ch->ch_flag |= CH_PORT_GONE;

		wake_up_interruptible(&ch->ch_flag_wait);

		nd->nd_chan_count = i;

		kfree(ch->ch_tbuf);
		ch->ch_tbuf = NULL;

		kfree(ch->ch_rbuf);
		ch->ch_rbuf = NULL;

		nd->nd_chan_count = i;

		dgrp_remove_tty_sysfs(ch->ch_tun.un_sysfs);
		snprintf(name, DEVICE_NAME_SIZE, "tty_%d", i);
		sysfs_remove_link(&nd->nd_class_dev->kobj, name);
		tty_unregister_device(nd->nd_serial_ttdriver, i);

		/*
		 * NOTE: We don't support "cu" devices anymore, so don't
		 * unregister them here anymore.
		 */

		if (dgrp_register_prdevices) {
			dgrp_remove_tty_sysfs(ch->ch_pun.un_sysfs);
			snprintf(name, DEVICE_NAME_SIZE, "pr_%d", i);
			sysfs_remove_link(&nd->nd_class_dev->kobj, name);
			tty_unregister_device(nd->nd_xprint_ttdriver, i);
		}
	}
}

/**
 * dgrp_chan_count() -- Adjust the node channel count.
 * @nd: pointer to a node structure
 * @n: new value for channel count
 *
 * Adjusts the node channel count.  If new ports have appeared, it tries
 * to signal those processes that might have been waiting for ports to
 * appear.  If ports have disappeared it tries to signal those processes
 * that might be hung waiting for a response for the now non-existant port.
 */
static void dgrp_chan_count(struct nd_struct *nd, int n)
{
	if (n == nd->nd_chan_count)
		return;

	if (n > nd->nd_chan_count)
		increase_channel_count(nd, n);

	if (n < nd->nd_chan_count)
		decrease_channel_count(nd, n);
}

/**
 * dgrp_monitor() -- send data to the device monitor queue
 * @nd: pointer to a node structure
 * @buf: data to copy to the monitoring buffer
 * @len: number of bytes to transfer to the buffer
 *
 * Called by the net device routines to send data to the device
 * monitor queue.  If the device monitor buffer is too full to
 * accept the data, it waits until the buffer is ready.
 */
static void dgrp_monitor(struct nd_struct *nd, u8 *buf, int len)
{
	int n;
	int r;
	int rtn;

	/*
	 *  Grab monitor lock.
	 */
	down(&nd->nd_mon_semaphore);

	/*
	 *  Loop while data remains.
	 */
	while ((len > 0) && (nd->nd_mon_buf)) {
		/*
		 *  Determine the amount of available space left in the
		 *  buffer.  If there's none, wait until some appears.
		 */

		n = (nd->nd_mon_out - nd->nd_mon_in - 1) & MON_MASK;

		if (!n) {
			nd->nd_mon_flag |= MON_WAIT_SPACE;

			up(&nd->nd_mon_semaphore);

			/*
			 * Go to sleep waiting until the condition becomes true.
			 */
			rtn = wait_event_interruptible(nd->nd_mon_wqueue,
						       ((nd->nd_mon_flag & MON_WAIT_SPACE) == 0));

/* FIXME: really ignore rtn? */

			/*
			 *  We can't exit here if we receive a signal, since
			 *  to do so would trash the debug stream.
			 */

			down(&nd->nd_mon_semaphore);

			continue;
		}

		/*
		 * Copy as much data as will fit.
		 */

		if (n > len)
			n = len;

		r = MON_MAX - nd->nd_mon_in;

		if (r <= n) {
			memcpy(nd->nd_mon_buf + nd->nd_mon_in, buf, r);

			n -= r;

			nd->nd_mon_in = 0;

			buf += r;
			len -= r;
		}

		memcpy(nd->nd_mon_buf + nd->nd_mon_in, buf, n);

		nd->nd_mon_in += n;

		buf += n;
		len -= n;

		if (nd->nd_mon_in >= MON_MAX)
			pr_info_ratelimited("%s - nd_mon_in (%i) >= MON_MAX\n",
					    __func__, nd->nd_mon_in);

		/*
		 *  Wakeup any thread waiting for data
		 */

		if (nd->nd_mon_flag & MON_WAIT_DATA) {
			nd->nd_mon_flag &= ~MON_WAIT_DATA;
			wake_up_interruptible(&nd->nd_mon_wqueue);
		}
	}

	/*
	 *  Release the monitor lock.
	 */
	up(&nd->nd_mon_semaphore);
}

/**
 * dgrp_encode_time() -- Encodes rpdump time into a 4-byte quantity.
 * @nd: pointer to a node structure
 * @buf: destination buffer
 *
 * Encodes "rpdump" time into a 4-byte quantity.  Time is measured since
 * open.
 */
static void dgrp_encode_time(struct nd_struct *nd, u8 *buf)
{
	ulong t;

	/*
	 *  Convert time in HZ since open to time in milliseconds
	 *  since open.
	 */
	t = jiffies - nd->nd_mon_lbolt;
	t = 1000 * (t / HZ) + 1000 * (t % HZ) / HZ;

	put_unaligned_be32((uint)(t & 0xffffffff), buf);
}



/**
 * dgrp_monitor_message() -- Builds a rpdump style message.
 * @nd: pointer to a node structure
 * @message: destination buffer
 */
static void dgrp_monitor_message(struct nd_struct *nd, char *message)
{
	u8 header[7];
	int n;

	header[0] = RPDUMP_MESSAGE;

	dgrp_encode_time(nd, header + 1);

	n = strlen(message);

	put_unaligned_be16(n, header + 5);

	dgrp_monitor(nd, header, sizeof(header));
	dgrp_monitor(nd, (u8 *) message, n);
}



/**
 * dgrp_monitor_reset() -- Note a reset in the monitoring buffer.
 * @nd: pointer to a node structure
 */
static void dgrp_monitor_reset(struct nd_struct *nd)
{
	u8 header[5];

	header[0] = RPDUMP_RESET;

	dgrp_encode_time(nd, header + 1);

	dgrp_monitor(nd, header, sizeof(header));
}

/**
 * dgrp_monitor_data() -- builds a monitor data packet
 * @nd: pointer to a node structure
 * @type: type of message to be logged
 * @buf: data to be logged
 * @size: number of bytes in the buffer
 */
static void dgrp_monitor_data(struct nd_struct *nd, u8 type, u8 *buf, int size)
{
	u8 header[7];

	header[0] = type;

	dgrp_encode_time(nd, header + 1);

	put_unaligned_be16(size, header + 5);

	dgrp_monitor(nd, header, sizeof(header));
	dgrp_monitor(nd, buf, size);
}

static int alloc_nd_buffers(struct nd_struct *nd)
{

	nd->nd_iobuf = NULL;
	nd->nd_writebuf = NULL;
	nd->nd_inputbuf = NULL;
	nd->nd_inputflagbuf = NULL;

	/*
	 *  Allocate the network read/write buffer.
	 */
	nd->nd_iobuf = kzalloc(UIO_MAX + 10, GFP_KERNEL);
	if (!nd->nd_iobuf)
		goto out_err;

	/*
	 * Allocate a buffer for doing the copy from user space to
	 * kernel space in the write routines.
	 */
	nd->nd_writebuf = kzalloc(WRITEBUFLEN, GFP_KERNEL);
	if (!nd->nd_writebuf)
		goto out_err;

	/*
	 * Allocate a buffer for doing the copy from kernel space to
	 * tty buffer space in the read routines.
	 */
	nd->nd_inputbuf = kzalloc(MYFLIPLEN, GFP_KERNEL);
	if (!nd->nd_inputbuf)
		goto out_err;

	/*
	 * Allocate a buffer for doing the copy from kernel space to
	 * tty buffer space in the read routines.
	 */
	nd->nd_inputflagbuf = kzalloc(MYFLIPLEN, GFP_KERNEL);
	if (!nd->nd_inputflagbuf)
		goto out_err;

	return 0;

out_err:
	kfree(nd->nd_iobuf);
	kfree(nd->nd_writebuf);
	kfree(nd->nd_inputbuf);
	kfree(nd->nd_inputflagbuf);
	return -ENOMEM;
}

/*
 * dgrp_net_open() -- Open the NET device for a particular PortServer
 */
static int dgrp_net_open(struct inode *inode, struct file *file)
{
	struct nd_struct *nd;
	ulong  lock_flags;
	int rtn;

	rtn = try_module_get(THIS_MODULE);
	if (!rtn)
		return -EAGAIN;

	if (!capable(CAP_SYS_ADMIN)) {
		rtn = -EPERM;
		goto done;
	}

	/*
	 *  Make sure that the "private_data" field hasn't already been used.
	 */
	if (file->private_data) {
		rtn = -EINVAL;
		goto done;
	}

	/*
	 *  Get the node pointer, and fail if it doesn't exist.
	 */
	nd = PDE_DATA(inode);
	if (!nd) {
		rtn = -ENXIO;
		goto done;
	}

	file->private_data = (void *) nd;

	/*
	 *  Grab the NET lock.
	 */
	down(&nd->nd_net_semaphore);

	if (nd->nd_state != NS_CLOSED) {
		rtn = -EBUSY;
		goto unlock;
	}

	/*
	 *  Initialize the link speed parameters.
	 */

	nd->nd_link.lk_fast_rate = UIO_MAX;
	nd->nd_link.lk_slow_rate = UIO_MAX;

	nd->nd_link.lk_fast_delay = 1000;
	nd->nd_link.lk_slow_delay = 1000;

	nd->nd_link.lk_header_size = 46;


	rtn = alloc_nd_buffers(nd);
	if (rtn)
		goto unlock;

	/*
	 *  The port is now open, so move it to the IDLE state
	 */
	dgrp_net_idle(nd);

	nd->nd_tx_time = jiffies;

	/*
	 *  If the polling routing is not running, start it running here
	 */
	spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);

	if (!dgrp_poll_data.node_active_count) {
		dgrp_poll_data.node_active_count = 2;
		dgrp_poll_data.timer.expires = jiffies +
			dgrp_poll_tick * HZ / 1000;
		add_timer(&dgrp_poll_data.timer);
	}

	spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);

	dgrp_monitor_message(nd, "Net Open");

unlock:
	/*
	 *  Release the NET lock.
	 */
	up(&nd->nd_net_semaphore);

done:
	if (rtn)
		module_put(THIS_MODULE);

	return rtn;
}

/* dgrp_net_release() -- close the NET device for a particular PortServer */
static int dgrp_net_release(struct inode *inode, struct file *file)
{
	struct nd_struct *nd;
	ulong  lock_flags;

	nd = (struct nd_struct *)(file->private_data);
	if (!nd)
		goto done;

/* TODO : historical locking placeholder */
/*
 *  In the HPUX version of the RealPort driver (which served as a basis
 *  for this driver) this locking code was used.  Saved if ever we need
 *  to review the locking under Linux.
 */
/*	spinlock(&nd->nd_lock); */


	/*
	 *  Grab the NET lock.
	 */
	down(&nd->nd_net_semaphore);

	/*
	 *  Before "closing" the internal connection, make sure all
	 *  ports are "idle".
	 */
	dgrp_net_idle(nd);

	nd->nd_state = NS_CLOSED;
	nd->nd_flag = 0;

	/*
	 *  TODO ... must the wait queue be reset on close?
	 *  should any pending waiters be reset?
	 *  Let's decide to assert that the waitq is empty... and see
	 *  how soon we break.
	 */
	if (waitqueue_active(&nd->nd_tx_waitq))
		pr_info("%s - expected waitqueue_active to be false\n",
			__func__);

	nd->nd_send = 0;

	kfree(nd->nd_iobuf);
	nd->nd_iobuf = NULL;

/* TODO : historical locking placeholder */
/*
 *  In the HPUX version of the RealPort driver (which served as a basis
 *  for this driver) this locking code was used.  Saved if ever we need
 *  to review the locking under Linux.
 */
/*	spinunlock( &nd->nd_lock ); */


	kfree(nd->nd_writebuf);
	nd->nd_writebuf = NULL;

	kfree(nd->nd_inputbuf);
	nd->nd_inputbuf = NULL;

	kfree(nd->nd_inputflagbuf);
	nd->nd_inputflagbuf = NULL;

/* TODO : historical locking placeholder */
/*
 *  In the HPUX version of the RealPort driver (which served as a basis
 *  for this driver) this locking code was used.  Saved if ever we need
 *  to review the locking under Linux.
 */
/*	spinlock(&nd->nd_lock); */

	/*
	 *  Set the active port count to zero.
	 */
	dgrp_chan_count(nd, 0);

/* TODO : historical locking placeholder */
/*
 *  In the HPUX version of the RealPort driver (which served as a basis
 *  for this driver) this locking code was used.  Saved if ever we need
 *  to review the locking under Linux.
 */
/*	spinunlock(&nd->nd_lock); */

	/*
	 *  Release the NET lock.
	 */
	up(&nd->nd_net_semaphore);

	/*
	 *  Cause the poller to stop scheduling itself if this is
	 *  the last active node.
	 */
	spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);

	if (dgrp_poll_data.node_active_count == 2) {
		del_timer(&dgrp_poll_data.timer);
		dgrp_poll_data.node_active_count = 0;
	}

	spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);

	down(&nd->nd_net_semaphore);

	dgrp_monitor_message(nd, "Net Close");

	up(&nd->nd_net_semaphore);

done:
	module_put(THIS_MODULE);
	file->private_data = NULL;
	return 0;
}

/* used in dgrp_send to setup command header */
static inline u8 *set_cmd_header(u8 *b, u8 port, u8 cmd)
{
	*b++ = 0xb0 + (port & 0x0f);
	*b++ = cmd;
	return b;
}

/**
 * dgrp_send() -- build a packet for transmission to the server
 * @nd: pointer to a node structure
 * @tmax: maximum bytes to transmit
 *
 * returns number of bytes sent
 */
static int dgrp_send(struct nd_struct *nd, long tmax)
{
	struct ch_struct *ch = nd->nd_chan;
	u8 *b;
	u8 *buf;
	u8 *mbuf;
	u8 port;
	int mod;
	long send;
	int maxport;
	long lastport = -1;
	ushort rwin;
	long in;
	ushort n;
	long t;
	long ttotal;
	long tchan;
	long tsend;
	ushort tsafe;
	long work;
	long send_sync;
	long wanted_sync_port = -1;
	ushort tdata[CHAN_MAX];
	long used_buffer;

	mbuf = nd->nd_iobuf + UIO_BASE;
	buf = b = mbuf;

	send_sync = nd->nd_link.lk_slow_rate < UIO_MAX;

	ttotal = 0;
	tchan = 0;

	memset(tdata, 0, sizeof(tdata));


	/*
	 * If there are any outstanding requests to be serviced,
	 * service them here.
	 */
	if (nd->nd_send & NR_PASSWORD) {

		/*
		 *  Send Password response.
		 */

		b[0] = 0xfc;
		b[1] = 0x20;
		put_unaligned_be16(strlen(nd->password), b + 2);
		b += 4;
		b += strlen(nd->password);
		nd->nd_send &= ~(NR_PASSWORD);
	}


	/*
	 *  Loop over all modules to generate commands, and determine
	 *  the amount of data queued for transmit.
	 */

	for (mod = 0, port = 0; port < nd->nd_chan_count; mod++) {
		/*
		 *  If this is not the current module, enter a module select
		 *  code in the buffer.
		 */

		if (mod != nd->nd_tx_module)
			mbuf = ++b;

		/*
		 *  Loop to process one module.
		 */

		maxport = port + 16;

		if (maxport > nd->nd_chan_count)
			maxport = nd->nd_chan_count;

		for (; port < maxport; port++, ch++) {
			/*
			 *  Switch based on channel state.
			 */

			switch (ch->ch_state) {
			/*
			 *  Send requests when the port is closed, and there
			 *  are no Open, Close or Cancel requests expected.
			 */

			case CS_IDLE:
				/*
				 * Wait until any open error code
				 * has been delivered to all
				 * associated ports.
				 */

				if (ch->ch_open_error) {
					if (ch->ch_wait_count[ch->ch_otype]) {
						work = 1;
						break;
					}

					ch->ch_open_error = 0;
				}

				/*
				 *  Wait until the channel HANGUP flag is reset
				 *  before sending the first open.  We can only
				 *  get to this state after a server disconnect.
				 */

				if ((ch->ch_flag & CH_HANGUP) != 0)
					break;

				/*
				 *  If recovering from a TCP disconnect, or if
				 *  there is an immediate open pending, send an
				 *  Immediate Open request.
				 */
				if ((ch->ch_flag & CH_PORT_GONE) ||
				    ch->ch_wait_count[OTYPE_IMMEDIATE] != 0) {
					b = set_cmd_header(b, port, 10);
					*b++ = 0;

					ch->ch_state = CS_WAIT_OPEN;
					ch->ch_otype = OTYPE_IMMEDIATE;
					break;
				}

	/*
	 *  If there is no Persistent or Incoming Open on the wait
	 *  list in the server, and a thread is waiting for a
	 *  Persistent or Incoming Open, send a Persistent or Incoming
	 *  Open Request.
	 */
				if (ch->ch_otype_waiting == 0) {
					if (ch->ch_wait_count[OTYPE_PERSISTENT] != 0) {
						b = set_cmd_header(b, port, 10);
						*b++ = 1;

						ch->ch_state = CS_WAIT_OPEN;
						ch->ch_otype = OTYPE_PERSISTENT;
					} else if (ch->ch_wait_count[OTYPE_INCOMING] != 0) {
						b = set_cmd_header(b, port, 10);
						*b++ = 2;

						ch->ch_state = CS_WAIT_OPEN;
						ch->ch_otype = OTYPE_INCOMING;
					}
					break;
				}

				/*
				 *  If a Persistent or Incoming Open is pending in
				 *  the server, but there is no longer an open
				 *  thread waiting for it, cancel the request.
				 */

				if (ch->ch_wait_count[ch->ch_otype_waiting] == 0) {
					b = set_cmd_header(b, port, 10);
					*b++ = 4;

					ch->ch_state = CS_WAIT_CANCEL;
					ch->ch_otype = ch->ch_otype_waiting;
				}
				break;

				/*
				 *  Send port parameter queries.
				 */
			case CS_SEND_QUERY:
				/*
				 *  Clear out all FEP state that might remain
				 *  from the last connection.
				 */

				ch->ch_flag |= CH_PARAM;

				ch->ch_flag &= ~CH_RX_FLUSH;

				ch->ch_expect = 0;

				ch->ch_s_tin   = 0;
				ch->ch_s_tpos  = 0;
				ch->ch_s_tsize = 0;
				ch->ch_s_treq  = 0;
				ch->ch_s_elast = 0;

				ch->ch_s_rin   = 0;
				ch->ch_s_rwin  = 0;
				ch->ch_s_rsize = 0;

				ch->ch_s_tmax  = 0;
				ch->ch_s_ttime = 0;
				ch->ch_s_rmax  = 0;
				ch->ch_s_rtime = 0;
				ch->ch_s_rlow  = 0;
				ch->ch_s_rhigh = 0;

				ch->ch_s_brate = 0;
				ch->ch_s_iflag = 0;
				ch->ch_s_cflag = 0;
				ch->ch_s_oflag = 0;
				ch->ch_s_xflag = 0;

				ch->ch_s_mout  = 0;
				ch->ch_s_mflow = 0;
				ch->ch_s_mctrl = 0;
				ch->ch_s_xon   = 0;
				ch->ch_s_xoff  = 0;
				ch->ch_s_lnext = 0;
				ch->ch_s_xxon  = 0;
				ch->ch_s_xxoff = 0;

				/* Send Sequence Request */
				b = set_cmd_header(b, port, 14);

				/* Configure Event Conditions Packet */
				b = set_cmd_header(b, port, 42);
				put_unaligned_be16(0x02c0, b);
				b += 2;
				*b++ = (DM_DTR | DM_RTS | DM_CTS |
					DM_DSR | DM_RI | DM_CD);

				/* Send Status Request */
				b = set_cmd_header(b, port, 16);

				/* Send Buffer Request  */
				b = set_cmd_header(b, port, 20);

				/* Send Port Capability Request */
				b = set_cmd_header(b, port, 22);

				ch->ch_expect = (RR_SEQUENCE |
						 RR_STATUS  |
						 RR_BUFFER |
						 RR_CAPABILITY);

				ch->ch_state = CS_WAIT_QUERY;

				/* Raise modem signals */
				b = set_cmd_header(b, port, 44);

				if (ch->ch_flag & CH_PORT_GONE)
					ch->ch_s_mout = ch->ch_mout;
				else
					ch->ch_s_mout = ch->ch_mout = DM_DTR | DM_RTS;

				*b++ = ch->ch_mout;
				*b++ = ch->ch_s_mflow = 0;
				*b++ = ch->ch_s_mctrl = ch->ch_mctrl = 0;

				if (ch->ch_flag & CH_PORT_GONE)
					ch->ch_flag &= ~CH_PORT_GONE;

				break;

			/*
			 *  Handle normal open and ready mode.
			 */

			case CS_READY:

				/*
				 *  If the port is not open, and there are no
				 *  no longer any ports requesting an open,
				 *  then close the port.
				 */

				if (ch->ch_open_count == 0 &&
				    ch->ch_wait_count[ch->ch_otype] == 0) {
					goto send_close;
				}

	/*
	 *  Process waiting input.
	 *
	 *  If there is no one to read it, discard the data.
	 *
	 *  Otherwise if we are not in fastcook mode, or if there is a
	 *  fastcook thread waiting for data, send the data to the
	 *  line discipline.
	 */
				if (ch->ch_rin != ch->ch_rout) {
					if (ch->ch_tun.un_open_count == 0 ||
					     (ch->ch_tun.un_flag & UN_CLOSING) ||
					    (ch->ch_cflag & CF_CREAD) == 0) {
						ch->ch_rout = ch->ch_rin;
					} else if ((ch->ch_flag & CH_FAST_READ) == 0 ||
							ch->ch_inwait != 0) {
						dgrp_input(ch);

						if (ch->ch_rin != ch->ch_rout)
							work = 1;
					}
				}

				/*
				 *  Handle receive flush, and changes to
				 *  server port parameters.
				 */

				if (ch->ch_flag & (CH_RX_FLUSH | CH_PARAM)) {
				/*
				 *  If we are in receive flush mode,
				 *  and enough data has gone by, reset
				 *  receive flush mode.
				 */
					if (ch->ch_flag & CH_RX_FLUSH) {
						if (((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >
						    ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK))
							ch->ch_flag &= ~CH_RX_FLUSH;
						else
							work = 1;
					}

					/*
					 *  Send TMAX, TTIME.
					 */

					if (ch->ch_s_tmax  != ch->ch_tmax ||
					    ch->ch_s_ttime != ch->ch_ttime) {
						b = set_cmd_header(b, port, 48);

						ch->ch_s_tmax = ch->ch_tmax;
						ch->ch_s_ttime = ch->ch_ttime;

						put_unaligned_be16(ch->ch_s_tmax,
								   b);
						b += 2;

						put_unaligned_be16(ch->ch_s_ttime,
								   b);
						b += 2;
					}

					/*
					 *  Send RLOW, RHIGH.
					 */

					if (ch->ch_s_rlow  != ch->ch_rlow ||
					    ch->ch_s_rhigh != ch->ch_rhigh) {
						b = set_cmd_header(b, port, 45);

						ch->ch_s_rlow  = ch->ch_rlow;
						ch->ch_s_rhigh = ch->ch_rhigh;

						put_unaligned_be16(ch->ch_s_rlow,
								   b);
						b += 2;

						put_unaligned_be16(ch->ch_s_rhigh,
								   b);
						b += 2;
					}

					/*
					 *  Send BRATE, CFLAG, IFLAG,
					 *  OFLAG, XFLAG.
					 */

					if (ch->ch_s_brate != ch->ch_brate ||
					    ch->ch_s_cflag != ch->ch_cflag ||
					    ch->ch_s_iflag != ch->ch_iflag ||
					    ch->ch_s_oflag != ch->ch_oflag ||
					    ch->ch_s_xflag != ch->ch_xflag) {
						b = set_cmd_header(b, port, 40);

						ch->ch_s_brate = ch->ch_brate;
						ch->ch_s_cflag = ch->ch_cflag;
						ch->ch_s_iflag = ch->ch_iflag;
						ch->ch_s_oflag = ch->ch_oflag;
						ch->ch_s_xflag = ch->ch_xflag;

						put_unaligned_be16(ch->ch_s_brate,
								   b);
						b += 2;

						put_unaligned_be16(ch->ch_s_cflag,
								   b);
						b += 2;

						put_unaligned_be16(ch->ch_s_iflag,
								   b);
						b += 2;

						put_unaligned_be16(ch->ch_s_oflag,
								   b);
						b += 2;

						put_unaligned_be16(ch->ch_s_xflag,
								   b);
						b += 2;
					}

					/*
					 *  Send MOUT, MFLOW, MCTRL.
					 */

					if (ch->ch_s_mout  != ch->ch_mout  ||
					    ch->ch_s_mflow != ch->ch_mflow ||
					    ch->ch_s_mctrl != ch->ch_mctrl) {
						b = set_cmd_header(b, port, 44);

						*b++ = ch->ch_s_mout  = ch->ch_mout;
						*b++ = ch->ch_s_mflow = ch->ch_mflow;
						*b++ = ch->ch_s_mctrl = ch->ch_mctrl;
					}

					/*
					 *  Send Flow control characters.
					 */

					if (ch->ch_s_xon   != ch->ch_xon   ||
					    ch->ch_s_xoff  != ch->ch_xoff  ||
					    ch->ch_s_lnext != ch->ch_lnext ||
					    ch->ch_s_xxon  != ch->ch_xxon  ||
					    ch->ch_s_xxoff != ch->ch_xxoff) {
						b = set_cmd_header(b, port, 46);

						*b++ = ch->ch_s_xon   = ch->ch_xon;
						*b++ = ch->ch_s_xoff  = ch->ch_xoff;
						*b++ = ch->ch_s_lnext = ch->ch_lnext;
						*b++ = ch->ch_s_xxon  = ch->ch_xxon;
						*b++ = ch->ch_s_xxoff = ch->ch_xxoff;
					}

					/*
					 *  Send RMAX, RTIME.
					 */

					if (ch->ch_s_rmax != ch->ch_rmax ||
					    ch->ch_s_rtime != ch->ch_rtime) {
						b = set_cmd_header(b, port, 47);

						ch->ch_s_rmax  = ch->ch_rmax;
						ch->ch_s_rtime = ch->ch_rtime;

						put_unaligned_be16(ch->ch_s_rmax,
								   b);
						b += 2;

						put_unaligned_be16(ch->ch_s_rtime,
								   b);
						b += 2;
					}

					ch->ch_flag &= ~CH_PARAM;
					wake_up_interruptible(&ch->ch_flag_wait);
				}


				/*
				 *  Handle action commands.
				 */

				if (ch->ch_send != 0) {
					/* int send = ch->ch_send & ~ch->ch_expect; */
					send = ch->ch_send & ~ch->ch_expect;

					/* Send character immediate */
					if ((send & RR_TX_ICHAR) != 0) {
						b = set_cmd_header(b, port, 60);

						*b++ = ch->ch_xon;
						ch->ch_expect |= RR_TX_ICHAR;
					}

					/* BREAK request */
					if ((send & RR_TX_BREAK) != 0) {
						if (ch->ch_break_time != 0) {
							b = set_cmd_header(b, port, 61);
							put_unaligned_be16(ch->ch_break_time,
									   b);
							b += 2;

							ch->ch_expect |= RR_TX_BREAK;
							ch->ch_break_time = 0;
						} else {
							ch->ch_send &= ~RR_TX_BREAK;
							ch->ch_flag &= ~CH_TX_BREAK;
							wake_up_interruptible(&ch->ch_flag_wait);
						}
					}

					/*
					 *  Flush input/output buffers.
					 */

					if ((send & (RR_RX_FLUSH | RR_TX_FLUSH)) != 0) {
						b = set_cmd_header(b, port, 62);

						*b++ = ((send & RR_TX_FLUSH) == 0 ? 1 :
							(send & RR_RX_FLUSH) == 0 ? 2 : 3);

						if (send & RR_RX_FLUSH) {
							ch->ch_flush_seq = nd->nd_seq_in;
							ch->ch_flag |= CH_RX_FLUSH;
							work = 1;
							send_sync = 1;
							wanted_sync_port = port;
						}

						ch->ch_send &= ~(RR_RX_FLUSH | RR_TX_FLUSH);
					}

					/*  Pause input/output */
					if ((send & (RR_RX_STOP | RR_TX_STOP)) != 0) {
						b = set_cmd_header(b, port, 63);
						*b = 0;

						if ((send & RR_TX_STOP) != 0)
							*b |= EV_OPU;

						if ((send & RR_RX_STOP) != 0)
							*b |= EV_IPU;

						b++;

						ch->ch_send &= ~(RR_RX_STOP | RR_TX_STOP);
					}

					/* Start input/output */
					if ((send & (RR_RX_START | RR_TX_START)) != 0) {
						b = set_cmd_header(b, port, 64);
						*b = 0;

						if ((send & RR_TX_START) != 0)
							*b |= EV_OPU | EV_OPS | EV_OPX;

						if ((send & RR_RX_START) != 0)
							*b |= EV_IPU | EV_IPS;

						b++;

						ch->ch_send &= ~(RR_RX_START | RR_TX_START);
					}
				}


				/*
				 *  Send a window sequence to acknowledge received data.
				 */

				rwin = (ch->ch_s_rin +
					((ch->ch_rout - ch->ch_rin - 1) & RBUF_MASK));

				n = (rwin - ch->ch_s_rwin) & 0xffff;

				if (n >= RBUF_MAX / 4) {
					b[0] = 0xa0 + (port & 0xf);
					ch->ch_s_rwin = rwin;
					put_unaligned_be16(rwin, b + 1);
					b += 3;
				}

				/*
				 *  If the terminal is waiting on LOW
				 *  water or EMPTY, and the condition
				 *  is now satisfied, call the line
				 *  discipline to put more data in the
				 *  buffer.
				 */

				n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;

				if ((ch->ch_tun.un_flag & (UN_EMPTY|UN_LOW)) != 0) {
					if ((ch->ch_tun.un_flag & UN_LOW) != 0 ?
					    (n <= TBUF_LOW) :
					    (n == 0 && ch->ch_s_tpos == ch->ch_s_tin)) {
						ch->ch_tun.un_flag &= ~(UN_EMPTY|UN_LOW);

						if (waitqueue_active(&((ch->ch_tun.un_tty)->write_wait)))
							wake_up_interruptible(&((ch->ch_tun.un_tty)->write_wait));
						tty_wakeup(ch->ch_tun.un_tty);
						n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
					}
				}

				/*
				 * If the printer is waiting on LOW
				 * water, TIME, EMPTY or PWAIT, and is
				 * now ready to put more data in the
				 * buffer, call the line discipline to
				 * do the job.
				 */

				/* FIXME: jiffies - ch->ch_waketime can never
				   be < 0. Someone needs to work out what is
				   actually intended here */
				if (ch->ch_pun.un_open_count &&
				    (ch->ch_pun.un_flag &
				    (UN_EMPTY|UN_TIME|UN_LOW|UN_PWAIT)) != 0) {

					if ((ch->ch_pun.un_flag & UN_LOW) != 0 ?
					    (n <= TBUF_LOW) :
					    (ch->ch_pun.un_flag & UN_TIME) != 0 ?
					    time_is_before_jiffies(ch->ch_waketime) :
					    (n == 0 && ch->ch_s_tpos == ch->ch_s_tin) &&
					    ((ch->ch_pun.un_flag & UN_EMPTY) != 0 ||
					    ((ch->ch_tun.un_open_count &&
					      ch->ch_tun.un_tty->ops->chars_in_buffer) ?
					     (ch->ch_tun.un_tty->ops->chars_in_buffer)(ch->ch_tun.un_tty) == 0
					     : 1
					    )
					    )) {
						ch->ch_pun.un_flag &= ~(UN_EMPTY | UN_TIME | UN_LOW | UN_PWAIT);

						if (waitqueue_active(&((ch->ch_pun.un_tty)->write_wait)))
							wake_up_interruptible(&((ch->ch_pun.un_tty)->write_wait));
						tty_wakeup(ch->ch_pun.un_tty);
						n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;

					} else if ((ch->ch_pun.un_flag & UN_TIME) != 0) {
						work = 1;
					}
				}


				/*
				 *  Determine the max number of bytes
				 *  this port can send, including
				 *  packet header overhead.
				 */

				t = ((ch->ch_s_tsize + ch->ch_s_tpos - ch->ch_s_tin) & 0xffff);

				if (n > t)
					n = t;

				if (n != 0) {
					n += (n <= 8 ? 1 : n <= 255 ? 2 : 3);

					tdata[tchan++] = n;
					ttotal += n;
				}
				break;

			/*
			 *  Close the port.
			 */

send_close:
			case CS_SEND_CLOSE:
				b = set_cmd_header(b, port, 10);
				if (ch->ch_otype == OTYPE_IMMEDIATE)
					*b++ = 3;
				else
					*b++ = 4;

				ch->ch_state = CS_WAIT_CLOSE;
				break;

			/*
			 *  Wait for a previous server request.
			 */

			case CS_WAIT_OPEN:
			case CS_WAIT_CANCEL:
			case CS_WAIT_FAIL:
			case CS_WAIT_QUERY:
			case CS_WAIT_CLOSE:
				break;

			default:
				pr_info("%s - unexpected channel state (%i)\n",
					__func__, ch->ch_state);
			}
		}

		/*
		 *  If a module select code is needed, drop one in.  If space
		 *  was reserved for one, but none is needed, recover the space.
		 */

		if (mod != nd->nd_tx_module) {
			if (b != mbuf) {
				mbuf[-1] = 0xf0 | mod;
				nd->nd_tx_module = mod;
			} else {
				b--;
			}
		}
	}

	/*
	 *  Adjust "tmax" so that under worst case conditions we do
	 *  not overflow either the daemon buffer or the internal
	 *  buffer in the loop that follows.   Leave a safe area
	 *  of 64 bytes so we start getting asserts before we start
	 *  losing data or clobbering memory.
	 */

	n = UIO_MAX - UIO_BASE;

	if (tmax > n)
		tmax = n;

	tmax -= 64;

	tsafe = tmax;

	/*
	 *  Allocate space for 5 Module Selects, 1 Sequence Request,
	 *  and 1 Set TREQ for each active channel.
	 */

	tmax -= 5 + 3 + 4 * nd->nd_chan_count;

	/*
	 *  Further reduce "tmax" to the available transmit credit.
	 *  Note that this is a soft constraint;  The transmit credit
	 *  can go negative for a time and then recover.
	 */

	n = nd->nd_tx_deposit - nd->nd_tx_charge - nd->nd_link.lk_header_size;

	if (tmax > n)
		tmax = n;

	/*
	 *  Finally reduce tmax by the number of bytes already in
	 *  the buffer.
	 */

	tmax -= b - buf;

	/*
	 *  Suspend data transmit unless every ready channel can send
	 *  at least 1 character.
	 */
	if (tmax < 2 * nd->nd_chan_count) {
		tsend = 1;

	} else if (tchan > 1 && ttotal > tmax) {

		/*
		 *  If transmit is limited by the credit budget, find the
		 *  largest number of characters we can send without driving
		 *  the credit negative.
		 */

		long tm = tmax;
		int tc = tchan;
		int try;

		tsend = tm / tc;

		for (try = 0; try < 3; try++) {
			int i;
			int c = 0;

			for (i = 0; i < tc; i++) {
				if (tsend < tdata[i])
					tdata[c++] = tdata[i];
				else
					tm -= tdata[i];
			}

			if (c == tc)
				break;

			tsend = tm / c;

			if (c == 1)
				break;

			tc = c;
		}

		tsend = tm / nd->nd_chan_count;

		if (tsend < 2)
			tsend = 1;

	} else {
		/*
		 *  If no budgetary constraints, or only one channel ready
		 *  to send, set the character limit to the remaining
		 *  buffer size.
		 */

		tsend = tmax;
	}

	tsend -= (tsend <= 9) ? 1 : (tsend <= 257) ? 2 : 3;

	/*
	 *  Loop over all channels, sending queued data.
	 */

	port = 0;
	ch = nd->nd_chan;
	used_buffer = tmax;

	for (mod = 0; port < nd->nd_chan_count; mod++) {
		/*
		 *  If this is not the current module, enter a module select
		 *  code in the buffer.
		 */

		if (mod != nd->nd_tx_module)
			mbuf = ++b;

		/*
		 *  Loop to process one module.
		 */

		maxport = port + 16;

		if (maxport > nd->nd_chan_count)
			maxport = nd->nd_chan_count;

		for (; port < maxport; port++, ch++) {
			if (ch->ch_state != CS_READY)
				continue;

			lastport = port;

			n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;

			/*
			 *  If there is data that can be sent, send it.
			 */

			if (n != 0 && used_buffer > 0) {
				t = (ch->ch_s_tsize + ch->ch_s_tpos - ch->ch_s_tin) & 0xffff;

				if (n > t)
					n = t;

				if (n > tsend) {
					work = 1;
					n = tsend;
				}

				if (n > used_buffer) {
					work = 1;
					n = used_buffer;
				}

				if (n <= 0)
					continue;

				/*
				 *  Create the correct size transmit header,
				 *  depending on the amount of data to transmit.
				 */

				if (n <= 8) {

					b[0] = ((n - 1) << 4) + (port & 0xf);
					b += 1;

				} else if (n <= 255) {

					b[0] = 0x80 + (port & 0xf);
					b[1] = n;
					b += 2;

				} else {

					b[0] = 0x90 + (port & 0xf);
					put_unaligned_be16(n, b + 1);
					b += 3;
				}

				ch->ch_s_tin = (ch->ch_s_tin + n) & 0xffff;

				/*
				 *  Copy transmit data to the packet.
				 */

				t = TBUF_MAX - ch->ch_tout;

				if (n >= t) {
					memcpy(b, ch->ch_tbuf + ch->ch_tout, t);
					b += t;
					n -= t;
					used_buffer -= t;
					ch->ch_tout = 0;
				}

				memcpy(b, ch->ch_tbuf + ch->ch_tout, n);
				b += n;
				used_buffer -= n;
				ch->ch_tout += n;
				n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
			}

			/*
			 *  Wake any terminal unit process waiting in the
			 *  dgrp_write routine for low water.
			 */

			if (n > TBUF_LOW)
				continue;

			if ((ch->ch_flag & CH_LOW) != 0) {
				ch->ch_flag &= ~CH_LOW;
				wake_up_interruptible(&ch->ch_flag_wait);
			}

			/* selwakeup tty_sel */
			if (ch->ch_tun.un_open_count) {
				struct tty_struct *tty = (ch->ch_tun.un_tty);

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

				tty_wakeup(tty);
			}

			if (ch->ch_pun.un_open_count) {
				struct tty_struct *tty = (ch->ch_pun.un_tty);

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

				tty_wakeup(tty);
			}

			/*
			 *  Do EMPTY processing.
			 */

			if (n != 0)
				continue;

			if ((ch->ch_flag & (CH_EMPTY | CH_DRAIN)) != 0 ||
			    (ch->ch_pun.un_flag & UN_EMPTY) != 0) {
				/*
				 *  If there is still data in the server, ask the server
				 *  to notify us when its all gone.
				 */

				if (ch->ch_s_treq != ch->ch_s_tin) {
					b = set_cmd_header(b, port, 43);

					ch->ch_s_treq = ch->ch_s_tin;
					put_unaligned_be16(ch->ch_s_treq,
							   b);
					b += 2;
				}

				/*
				 *  If there is a thread waiting for buffer empty,
				 *  and we are truly empty, wake the thread.
				 */

				else if ((ch->ch_flag & CH_EMPTY) != 0 &&
					(ch->ch_send & RR_TX_BREAK) == 0) {
					ch->ch_flag &= ~CH_EMPTY;

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

		/*
		 *  If a module select code is needed, drop one in.  If space
		 *  was reserved for one, but none is needed, recover the space.
		 */

		if (mod != nd->nd_tx_module) {
			if (b != mbuf) {
				mbuf[-1] = 0xf0 | mod;
				nd->nd_tx_module = mod;
			} else {
				b--;
			}
		}
	}

	/*
	 *  Send a synchronization sequence associated with the last open
	 *  channel that sent data, and remember the time when the data was
	 *  sent.
	 */

	in = nd->nd_seq_in;

	if ((send_sync || nd->nd_seq_wait[in] != 0) && lastport >= 0) {
		u8 *bb = b;

		/*
		 * Attempt the use the port that really wanted the sync.
		 * This gets around a race condition where the "lastport" is in
		 * the middle of the close() routine, and by the time we
		 * send this command, it will have already acked the close, and
		 * thus not send the sync response.
		 */
		if (wanted_sync_port >= 0)
			lastport = wanted_sync_port;
		/*
		 * Set a flag just in case the port is in the middle of a close,
		 * it will not be permitted to actually close until we get an
		 * sync response, and clear the flag there.
		 */
		ch = nd->nd_chan + lastport;
		ch->ch_flag |= CH_WAITING_SYNC;

		mod = lastport >> 4;

		if (mod != nd->nd_tx_module) {
			bb[0] = 0xf0 + mod;
			bb += 1;

			nd->nd_tx_module = mod;
		}

		bb = set_cmd_header(bb, lastport, 12);
		*bb++ = in;

		nd->nd_seq_size[in] = bb - buf;
		nd->nd_seq_time[in] = jiffies;

		if (++in >= SEQ_MAX)
			in = 0;

		if (in != nd->nd_seq_out) {
			b = bb;
			nd->nd_seq_in = in;
			nd->nd_unack += b - buf;
		}
	}

	/*
	 *  If there are no open ports, a sync cannot be sent.
	 *  There is nothing left to wait for anyway, so wake any
	 *  thread waiting for an acknowledgement.
	 */

	else if (nd->nd_seq_wait[in] != 0) {
		nd->nd_seq_wait[in] = 0;

		wake_up_interruptible(&nd->nd_seq_wque[in]);
	}

	/*
	 *  If there is no traffic for an interval of IDLE_MAX, then
	 *  send a single byte packet.
	 */

	if (b != buf) {
		nd->nd_tx_time = jiffies;
	} else if ((ulong)(jiffies - nd->nd_tx_time) >= IDLE_MAX) {
		*b++ = 0xf0 | nd->nd_tx_module;
		nd->nd_tx_time = jiffies;
	}

	n = b - buf;

	if (n >= tsafe)
		pr_info("%s - n(%i) >= tsafe(%i)\n",
			__func__, n, tsafe);

	if (tsend < 0)
		dgrp_dump(buf, n);

	nd->nd_tx_work = work;

	return n;
}

/*
 * dgrp_net_read()
 * Data to be sent TO the PortServer from the "async." half of the driver.
 */
static ssize_t dgrp_net_read(struct file *file, char __user *buf, size_t count,
			     loff_t *ppos)
{
	struct nd_struct *nd;
	long n;
	u8 *local_buf;
	u8 *b;
	ssize_t rtn;

	/*
	 *  Get the node pointer, and quit if it doesn't exist.
	 */
	nd = (struct nd_struct *)(file->private_data);
	if (!nd)
		return -ENXIO;

	if (count < UIO_MIN)
		return -EINVAL;

	/*
	 *  Only one read/write operation may be in progress at
	 *  any given time.
	 */

	/*
	 *  Grab the NET lock.
	 */
	down(&nd->nd_net_semaphore);

	nd->nd_read_count++;

	nd->nd_tx_ready = 0;

	/*
	 *  Determine the effective size of the buffer.
	 */

	if (nd->nd_remain > UIO_BASE)
		pr_info_ratelimited("%s - nd_remain(%i) > UIO_BASE\n",
				    __func__, nd->nd_remain);

	b = local_buf = nd->nd_iobuf + UIO_BASE;

	/*
	 *  Generate data according to the node state.
	 */

	switch (nd->nd_state) {
	/*
	 *  Initialize the connection.
	 */

	case NS_IDLE:
		if (nd->nd_mon_buf)
			dgrp_monitor_reset(nd);

		/*
		 *  Request a Product ID Packet.
		 */

		b[0] = 0xfb;
		b[1] = 0x01;
		b += 2;

		nd->nd_expect |= NR_IDENT;

		/*
		 *  Request a Server Capability ID Response.
		 */

		b[0] = 0xfb;
		b[1] = 0x02;
		b += 2;

		nd->nd_expect |= NR_CAPABILITY;

		/*
		 *  Request a Server VPD Response.
		 */

		b[0] = 0xfb;
		b[1] = 0x18;
		b += 2;

		nd->nd_expect |= NR_VPD;

		nd->nd_state = NS_WAIT_QUERY;
		break;

	/*
	 *  We do serious communication with the server only in
	 *  the READY state.
	 */

	case NS_READY:
		b = dgrp_send(nd, count) + local_buf;
		break;

	/*
	 *  Send off an error after receiving a bogus message
	 *  from the server.
	 */

	case NS_SEND_ERROR:
		n = strlen(nd->nd_error);

		b[0] = 0xff;
		b[1] = n;
		memcpy(b + 2, nd->nd_error, n);
		b += 2 + n;

		dgrp_net_idle(nd);
		/*
		 *  Set the active port count to zero.
		 */
		dgrp_chan_count(nd, 0);
		break;

	default:
		break;
	}

	n = b - local_buf;

	if (n != 0) {
		nd->nd_send_count++;

		nd->nd_tx_byte   += n + nd->nd_link.lk_header_size;
		nd->nd_tx_charge += n + nd->nd_link.lk_header_size;
	}

	rtn = copy_to_user((void __user *)buf, local_buf, n);
	if (rtn) {
		rtn = -EFAULT;
		goto done;
	}

	*ppos += n;

	rtn = n;

	if (nd->nd_mon_buf)
		dgrp_monitor_data(nd, RPDUMP_CLIENT, local_buf, n);

	/*
	 *  Release the NET lock.
	 */
done:
	up(&nd->nd_net_semaphore);

	return rtn;
}

/**
 * dgrp_receive() -- decode data packets received from the remote PortServer.
 * @nd: pointer to a node structure
 */
static void dgrp_receive(struct nd_struct *nd)
{
	struct ch_struct *ch;
	u8 *buf;
	u8 *b;
	u8 *dbuf;
	char *error;
	long port;
	long dlen;
	long plen;
	long remain;
	long n;
	long mlast;
	long elast;
	long mstat;
	long estat;

	char ID[3];

	nd->nd_tx_time = jiffies;

	ID_TO_CHAR(nd->nd_ID, ID);

	b = buf = nd->nd_iobuf;
	remain = nd->nd_remain;

	/*
	 *  Loop to process Realport protocol packets.
	 */

	while (remain > 0) {
		int n0 = b[0] >> 4;
		int n1 = b[0] & 0x0f;

		if (n0 <= 12) {
			port = (nd->nd_rx_module << 4) + n1;

			if (port >= nd->nd_chan_count) {
				error = "Improper Port Number";
				goto prot_error;
			}

			ch = nd->nd_chan + port;
		} else {
			port = -1;
			ch = NULL;
		}

		/*
		 *  Process by major packet type.
		 */

		switch (n0) {

		/*
		 *  Process 1-byte header data packet.
		 */

		case 0:
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
			dlen = n0 + 1;
			plen = dlen + 1;

			dbuf = b + 1;
			goto data;

		/*
		 *  Process 2-byte header data packet.
		 */

		case 8:
			if (remain < 3)
				goto done;

			dlen = b[1];
			plen = dlen + 2;

			dbuf = b + 2;
			goto data;

		/*
		 *  Process 3-byte header data packet.
		 */

		case 9:
			if (remain < 4)
				goto done;

			dlen = get_unaligned_be16(b + 1);
			plen = dlen + 3;

			dbuf = b + 3;

		/*
		 *  Common packet handling code.
		 */

data:
			nd->nd_tx_work = 1;

			/*
			 *  Otherwise data should appear only when we are
			 *  in the CS_READY state.
			 */

			if (ch->ch_state < CS_READY) {
				error = "Data received before RWIN established";
				goto prot_error;
			}

			/*
			 *  Assure that the data received is within the
			 *  allowable window.
			 */

			n = (ch->ch_s_rwin - ch->ch_s_rin) & 0xffff;

			if (dlen > n) {
				error = "Receive data overrun";
				goto prot_error;
			}

			/*
			 *  If we received 3 or less characters,
			 *  assume it is a human typing, and set RTIME
			 *  to 10 milliseconds.
			 *
			 *  If we receive 10 or more characters,
			 *  assume its not a human typing, and set RTIME
			 *  to 100 milliseconds.
			 */

			if (ch->ch_edelay != DGRP_RTIME) {
				if (ch->ch_rtime != ch->ch_edelay) {
					ch->ch_rtime = ch->ch_edelay;
					ch->ch_flag |= CH_PARAM;
				}
			} else if (dlen <= 3) {
				if (ch->ch_rtime != 10) {
					ch->ch_rtime = 10;
					ch->ch_flag |= CH_PARAM;
				}
			} else {
				if (ch->ch_rtime != DGRP_RTIME) {
					ch->ch_rtime = DGRP_RTIME;
					ch->ch_flag |= CH_PARAM;
				}
			}

			/*
			 *  If a portion of the packet is outside the
			 *  buffer, shorten the effective length of the
			 *  data packet to be the amount of data received.
			 */

			if (remain < plen)
				dlen -= plen - remain;

			/*
			 *  Detect if receive flush is now complete.
			 */

			if ((ch->ch_flag & CH_RX_FLUSH) != 0 &&
			    ((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >=
			    ((nd->nd_seq_in    - nd->nd_seq_out) & SEQ_MASK)) {
				ch->ch_flag &= ~CH_RX_FLUSH;
			}

			/*
			 *  If we are ready to receive, move the data into
			 *  the receive buffer.
			 */

			ch->ch_s_rin = (ch->ch_s_rin + dlen) & 0xffff;

			if (ch->ch_state == CS_READY &&
			    (ch->ch_tun.un_open_count != 0) &&
			    (ch->ch_tun.un_flag & UN_CLOSING) == 0 &&
			    (ch->ch_cflag & CF_CREAD) != 0 &&
			    (ch->ch_flag & (CH_BAUD0 | CH_RX_FLUSH)) == 0 &&
			    (ch->ch_send & RR_RX_FLUSH) == 0) {

				if (ch->ch_rin + dlen >= RBUF_MAX) {
					n = RBUF_MAX - ch->ch_rin;

					memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, n);

					ch->ch_rin = 0;
					dbuf += n;
					dlen -= n;
				}

				memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, dlen);

				ch->ch_rin += dlen;


				/*
				 *  If we are not in fastcook mode, or
				 *  if there is a fastcook thread
				 *  waiting for data, send the data to
				 *  the line discipline.
				 */

				if ((ch->ch_flag & CH_FAST_READ) == 0 ||
				    ch->ch_inwait != 0) {
					dgrp_input(ch);
				}

				/*
				 *  If there is a read thread waiting
				 *  in select, and we are in fastcook
				 *  mode, wake him up.
				 */

				if (waitqueue_active(&ch->ch_tun.un_tty->read_wait) &&
				    (ch->ch_flag & CH_FAST_READ) != 0)
					wake_up_interruptible(&ch->ch_tun.un_tty->read_wait);

				/*
				 * Wake any thread waiting in the
				 * fastcook loop.
				 */

				if ((ch->ch_flag & CH_INPUT) != 0) {
					ch->ch_flag &= ~CH_INPUT;

					wake_up_interruptible(&ch->ch_flag_wait);
				}
			}

			/*
			 *  Fabricate and insert a data packet header to
			 *  preced the remaining data when it comes in.
			 */

			if (remain < plen) {
				dlen = plen - remain;
				b = buf;

				b[0] = 0x90 + n1;
				put_unaligned_be16(dlen, b + 1);

				remain = 3;
				goto done;
			}
			break;

		/*
		 *  Handle Window Sequence packets.
		 */

		case 10:
			plen = 3;
			if (remain < plen)
				goto done;

			nd->nd_tx_work = 1;

			{
				ushort tpos   = get_unaligned_be16(b + 1);

				ushort ack    = (tpos          - ch->ch_s_tpos) & 0xffff;
				ushort unack  = (ch->ch_s_tin  - ch->ch_s_tpos) & 0xffff;
				ushort notify = (ch->ch_s_treq - ch->ch_s_tpos) & 0xffff;

				if (ch->ch_state < CS_READY || ack > unack) {
					error = "Improper Window Sequence";
					goto prot_error;
				}

				ch->ch_s_tpos = tpos;

				if (notify <= ack)
					ch->ch_s_treq = tpos;
			}
			break;

		/*
		 *  Handle Command response packets.
		 */

		case 11:

			/*
			 * RealPort engine fix - 03/11/2004
			 *
			 * This check did not used to be here.
			 *
			 * We were using b[1] without verifying that the data
			 * is actually there and valid. On a split packet, it
			 * might not be yet.
			 *
			 * NOTE:  I have never actually seen the failure happen
			 *        under Linux,  but since I have seen it occur
			 *        under both Solaris and HP-UX,  the assumption
			 *        is that it *could* happen here as well...
			 */
			if (remain < 2)
				goto done;


			switch (b[1]) {

			/*
			 *  Handle Open Response.
			 */

			case 11:
				plen = 6;
				if (remain < plen)
					goto done;

				nd->nd_tx_work = 1;

				{
					int req = b[2];
					int resp = b[3];
					port = get_unaligned_be16(b + 4);

					if (port >= nd->nd_chan_count) {
						error = "Open channel number out of range";
						goto prot_error;
					}

					ch = nd->nd_chan + port;

					/*
					 *  How we handle an open response depends primarily
					 *  on our current channel state.
					 */

					switch (ch->ch_state) {
					case CS_IDLE:

						/*
						 *  Handle a delayed open.
						 */

						if (ch->ch_otype_waiting != 0 &&
						    req == ch->ch_otype_waiting &&
						    resp == 0) {
							ch->ch_otype = req;
							ch->ch_otype_waiting = 0;
							ch->ch_state = CS_SEND_QUERY;
							break;
						}
						goto open_error;

					case CS_WAIT_OPEN:

						/*
						 *  Handle the open response.
						 */

						if (req == ch->ch_otype) {
							switch (resp) {

							/*
							 *  On successful response, open the
							 *  port and proceed normally.
							 */

							case 0:
								ch->ch_state = CS_SEND_QUERY;
								break;

							/*
							 *  On a busy response to a persistent open,
							 *  remember that the open is pending.
							 */

							case 1:
							case 2:
								if (req != OTYPE_IMMEDIATE) {
									ch->ch_otype_waiting = req;
									ch->ch_state = CS_IDLE;
									break;
								}

							/*
							 *  Otherwise the server open failed.  If
							 *  the Unix port is open, hang it up.
							 */

							default:
								if (ch->ch_open_count != 0) {
									ch->ch_flag |= CH_HANGUP;
									dgrp_carrier(ch);
									ch->ch_state = CS_IDLE;
									break;
								}

								ch->ch_open_error = resp;
								ch->ch_state = CS_IDLE;

								wake_up_interruptible(&ch->ch_flag_wait);
							}
							break;
						}

						/*
						 *  Handle delayed response arrival preceding
						 *  the open response we are waiting for.
						 */

						if (ch->ch_otype_waiting != 0 &&
						    req == ch->ch_otype_waiting &&
						    resp == 0) {
							ch->ch_otype = ch->ch_otype_waiting;
							ch->ch_otype_waiting = 0;
							ch->ch_state = CS_WAIT_FAIL;
							break;
						}
						goto open_error;


					case CS_WAIT_FAIL:

						/*
						 *  Handle response to immediate open arriving
						 *  after a delayed open success.
						 */

						if (req == OTYPE_IMMEDIATE) {
							ch->ch_state = CS_SEND_QUERY;
							break;
						}
						goto open_error;


					case CS_WAIT_CANCEL:
						/*
						 *  Handle delayed open response arriving before
						 *  the cancel response.
						 */

						if (req == ch->ch_otype_waiting &&
						    resp == 0) {
							ch->ch_otype_waiting = 0;
							break;
						}

						/*
						 *  Handle cancel response.
						 */

						if (req == 4 && resp == 0) {
							ch->ch_otype_waiting = 0;
							ch->ch_state = CS_IDLE;
							break;
						}
						goto open_error;


					case CS_WAIT_CLOSE:
						/*
						 *  Handle a successful response to a port
						 *  close.
						 */

						if (req >= 3) {
							ch->ch_state = CS_IDLE;
							break;
						}
						goto open_error;

open_error:
					default:
						{
							error = "Improper Open Response";
							goto prot_error;
						}
					}
				}
				break;

			/*
			 *  Handle Synchronize Response.
			 */

			case 13:
				plen = 3;
				if (remain < plen)
					goto done;
				{
					int seq = b[2];
					int s;

					/*
					 * If channel was waiting for this sync response,
					 * unset the flag, and wake up anyone waiting
					 * on the event.
					 */
					if (ch->ch_flag & CH_WAITING_SYNC) {
						ch->ch_flag &= ~(CH_WAITING_SYNC);
						wake_up_interruptible(&ch->ch_flag_wait);
					}

					if (((seq - nd->nd_seq_out) & SEQ_MASK) >=
					    ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) {
						break;
					}

					for (s = nd->nd_seq_out;; s = (s + 1) & SEQ_MASK) {
						if (nd->nd_seq_wait[s] != 0) {
							nd->nd_seq_wait[s] = 0;

							wake_up_interruptible(&nd->nd_seq_wque[s]);
						}

						nd->nd_unack -= nd->nd_seq_size[s];

						if (s == seq)
							break;
					}

					nd->nd_seq_out = (seq + 1) & SEQ_MASK;
				}
				break;

			/*
			 *  Handle Sequence Response.
			 */

			case 15:
				plen = 6;
				if (remain < plen)
					goto done;

				{
				/* Record that we have received the Sequence
				 * Response, but we aren't interested in the
				 * sequence numbers.  We were using RIN like it
				 * was ROUT and that was causing problems,
				 * fixed 7-13-2001 David Fries. See comment in
				 * drp.h for ch_s_rin variable.
					int rin = get_unaligned_be16(b + 2);
					int tpos = get_unaligned_be16(b + 4);
				*/

					ch->ch_send   &= ~RR_SEQUENCE;
					ch->ch_expect &= ~RR_SEQUENCE;
				}
				goto check_query;

			/*
			 *  Handle Status Response.
			 */

			case 17:
				plen = 5;
				if (remain < plen)
					goto done;

				{
					ch->ch_s_elast = get_unaligned_be16(b + 2);
					ch->ch_s_mlast = b[4];

					ch->ch_expect &= ~RR_STATUS;
					ch->ch_send   &= ~RR_STATUS;

					/*
					 *  CH_PHYS_CD is cleared because something _could_ be
					 *  waiting for the initial sense of carrier... and if
					 *  carrier is high immediately, we want to be sure to
					 *  wake them as soon as possible.
					 */
					ch->ch_flag &= ~CH_PHYS_CD;

					dgrp_carrier(ch);
				}
				goto check_query;

			/*
			 *  Handle Line Error Response.
			 */

			case 19:
				plen = 14;
				if (remain < plen)
					goto done;

				break;

			/*
			 *  Handle Buffer Response.
			 */

			case 21:
				plen = 6;
				if (remain < plen)
					goto done;

				{
					ch->ch_s_rsize = get_unaligned_be16(b + 2);
					ch->ch_s_tsize = get_unaligned_be16(b + 4);

					ch->ch_send   &= ~RR_BUFFER;
					ch->ch_expect &= ~RR_BUFFER;
				}
				goto check_query;

			/*
			 *  Handle Port Capability Response.
			 */

			case 23:
				plen = 32;
				if (remain < plen)
					goto done;

				{
					ch->ch_send   &= ~RR_CAPABILITY;
					ch->ch_expect &= ~RR_CAPABILITY;
				}

			/*
			 *  When all queries are complete, set those parameters
			 *  derived from the query results, then transition
			 *  to the READY state.
			 */

check_query:
				if (ch->ch_state == CS_WAIT_QUERY &&
				    (ch->ch_expect & (RR_SEQUENCE |
							RR_STATUS |
							RR_BUFFER |
							RR_CAPABILITY)) == 0) {
					ch->ch_tmax  = ch->ch_s_tsize / 4;

					if (ch->ch_edelay == DGRP_TTIME)
						ch->ch_ttime = DGRP_TTIME;
					else
						ch->ch_ttime = ch->ch_edelay;

					ch->ch_rmax = ch->ch_s_rsize / 4;

					if (ch->ch_edelay == DGRP_RTIME)
						ch->ch_rtime = DGRP_RTIME;
					else
						ch->ch_rtime = ch->ch_edelay;

					ch->ch_rlow  = 2 * ch->ch_s_rsize / 8;
					ch->ch_rhigh = 6 * ch->ch_s_rsize / 8;

					ch->ch_state = CS_READY;

					nd->nd_tx_work = 1;
					wake_up_interruptible(&ch->ch_flag_wait);

				}
				break;

			default:
				goto decode_error;
			}
			break;

		/*
		 *  Handle Events.
		 */

		case 12:
			plen = 4;
			if (remain < plen)
				goto done;

			mlast = ch->ch_s_mlast;
			elast = ch->ch_s_elast;

			mstat = ch->ch_s_mlast = b[1];
			estat = ch->ch_s_elast = get_unaligned_be16(b + 2);

			/*
			 *  Handle modem changes.
			 */

			if (((mstat ^ mlast) & DM_CD) != 0)
				dgrp_carrier(ch);


			/*
			 *  Handle received break.
			 */

			if ((estat & ~elast & EV_RXB) != 0 &&
			    (ch->ch_tun.un_open_count != 0) &&
			    I_BRKINT(ch->ch_tun.un_tty) &&
			    !(I_IGNBRK(ch->ch_tun.un_tty))) {

				tty_buffer_request_room(&ch->port, 1);
				tty_insert_flip_char(&ch->port, 0, TTY_BREAK);
				tty_flip_buffer_push(&ch->port);

			}

			/*
			 *  On transmit break complete, if more break traffic
			 *  is waiting then send it.  Otherwise wake any threads
			 *  waiting for transmitter empty.
			 */

			if ((~estat & elast & EV_TXB) != 0 &&
			    (ch->ch_expect & RR_TX_BREAK) != 0) {

				nd->nd_tx_work = 1;

				ch->ch_expect &= ~RR_TX_BREAK;

				if (ch->ch_break_time != 0) {
					ch->ch_send |= RR_TX_BREAK;
				} else {
					ch->ch_send &= ~RR_TX_BREAK;
					ch->ch_flag &= ~CH_TX_BREAK;
					wake_up_interruptible(&ch->ch_flag_wait);
				}
			}
			break;

		case 13:
		case 14:
			error = "Unrecognized command";
			goto prot_error;

		/*
		 *  Decode Special Codes.
		 */

		case 15:
			switch (n1) {
			/*
			 *  One byte module select.
			 */

			case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
				plen = 1;
				nd->nd_rx_module = n1;
				break;

			/*
			 *  Two byte module select.
			 */

			case 8:
				plen = 2;
				if (remain < plen)
					goto done;

				nd->nd_rx_module = b[1];
				break;

			/*
			 *  ID Request packet.
			 */

			case 11:
				if (remain < 4)
					goto done;

				plen = get_unaligned_be16(b + 2);

				if (plen < 12 || plen > 1000) {
					error = "Response Packet length error";
					goto prot_error;
				}

				nd->nd_tx_work = 1;

				switch (b[1]) {
				/*
				 *  Echo packet.
				 */

				case 0:
					nd->nd_send |= NR_ECHO;
					break;

				/*
				 *  ID Response packet.
				 */

				case 1:
					nd->nd_send |= NR_IDENT;
					break;

				/*
				 *  ID Response packet.
				 */

				case 32:
					nd->nd_send |= NR_PASSWORD;
					break;

				}
				break;

			/*
			 *  Various node-level response packets.
			 */

			case 12:
				if (remain < 4)
					goto done;

				plen = get_unaligned_be16(b + 2);

				if (plen < 4 || plen > 1000) {
					error = "Response Packet length error";
					goto prot_error;
				}

				nd->nd_tx_work = 1;

				switch (b[1]) {
				/*
				 *  Echo packet.
				 */

				case 0:
					nd->nd_expect &= ~NR_ECHO;
					break;

				/*
				 *  Product Response Packet.
				 */

				case 1:
					{
						int desclen;

						nd->nd_hw_ver = (b[8] << 8) | b[9];
						nd->nd_sw_ver = (b[10] << 8) | b[11];
						nd->nd_hw_id = b[6];
						desclen = (plen - 12 > MAX_DESC_LEN - 1) ? MAX_DESC_LEN - 1 :
							plen - 12;

						if (desclen <= 0) {
							error = "Response Packet desclen error";
							goto prot_error;
						}

						strncpy(nd->nd_ps_desc, b + 12, desclen);
						nd->nd_ps_desc[desclen] = 0;
					}

					nd->nd_expect &= ~NR_IDENT;
					break;

				/*
				 *  Capability Response Packet.
				 */

				case 2:
					{
						int nn = get_unaligned_be16(b + 4);

						if (nn > CHAN_MAX)
							nn = CHAN_MAX;

						dgrp_chan_count(nd, nn);
					}

					nd->nd_expect &= ~NR_CAPABILITY;
					break;

				/*
				 *  VPD Response Packet.
				 */

				case 15:
					/*
					 * NOTE: case 15 is here ONLY because the EtherLite
					 * is broken, and sends a response to 24 back as 15.
					 * To resolve this, the EtherLite firmware is now
					 * fixed to send back 24 correctly, but, for backwards
					 * compatibility, we now have reserved 15 for the
					 * bad EtherLite response to 24 as well.
					 */

					/* Fallthru! */

				case 24:

					/*
					 * If the product doesn't support VPD,
					 * it will send back a null IDRESP,
					 * which is a length of 4 bytes.
					 */
					if (plen > 4) {
						memcpy(nd->nd_vpd, b + 4, min(plen - 4, (long) VPDSIZE));
						nd->nd_vpd_len = min(plen - 4, (long) VPDSIZE);
					}

					nd->nd_expect &= ~NR_VPD;
					break;

				default:
					goto decode_error;
				}

				if (nd->nd_expect == 0 &&
				    nd->nd_state == NS_WAIT_QUERY) {
					nd->nd_state = NS_READY;
				}
				break;

			/*
			 *  Debug packet.
			 */

			case 14:
				if (remain < 4)
					goto done;

				plen = get_unaligned_be16(b + 2) + 4;

				if (plen > 1000) {
					error = "Debug Packet too large";
					goto prot_error;
				}

				if (remain < plen)
					goto done;
				break;

			/*
			 *  Handle reset packet.
			 */

			case 15:
				if (remain < 2)
					goto done;

				plen = 2 + b[1];

				if (remain < plen)
					goto done;

				nd->nd_tx_work = 1;

				n = b[plen];
				b[plen] = 0;

				b[plen] = n;

				error = "Client Reset Acknowledge";
				goto prot_error;

			default:
				goto decode_error;
			}
			break;

		default:
			goto decode_error;
		}

		b += plen;
		remain -= plen;
	}

	/*
	 *  When the buffer is exhausted, copy any data left at the
	 *  top of the buffer back down to the bottom for the next
	 *  read request.
	 */

done:
	if (remain > 0 && b != buf)
		memcpy(buf, b, remain);

	nd->nd_remain = remain;
	return;

/*
 *  Handle a decode error.
 */

decode_error:
	error = "Protocol decode error";

/*
 *  Handle a general protocol error.
 */

prot_error:
	nd->nd_remain = 0;
	nd->nd_state = NS_SEND_ERROR;
	nd->nd_error = error;
}

/*
 * dgrp_net_write() -- write data to the network device.
 *
 * A zero byte write indicates that the connection to the RealPort
 * device has been broken.
 *
 * A non-zero write indicates data from the RealPort device.
 */
static ssize_t dgrp_net_write(struct file *file, const char __user *buf,
			      size_t count, loff_t *ppos)
{
	struct nd_struct *nd;
	ssize_t rtn = 0;
	long n;
	long total = 0;

	/*
	 *  Get the node pointer, and quit if it doesn't exist.
	 */
	nd = (struct nd_struct *)(file->private_data);
	if (!nd)
		return -ENXIO;

	/*
	 *  Grab the NET lock.
	 */
	down(&nd->nd_net_semaphore);

	nd->nd_write_count++;

	/*
	 *  Handle disconnect.
	 */

	if (count == 0) {
		dgrp_net_idle(nd);
		/*
		 *  Set the active port count to zero.
		 */
		dgrp_chan_count(nd, 0);
		goto unlock;
	}

	/*
	 *  Loop to process entire receive packet.
	 */

	while (count > 0) {
		n = UIO_MAX - nd->nd_remain;

		if (n > count)
			n = count;

		nd->nd_rx_byte += n + nd->nd_link.lk_header_size;

		rtn = copy_from_user(nd->nd_iobuf + nd->nd_remain,
				     (void __user *) buf + total, n);
		if (rtn) {
			rtn = -EFAULT;
			goto unlock;
		}

		*ppos += n;

		total += n;

		count -= n;

		if (nd->nd_mon_buf)
			dgrp_monitor_data(nd, RPDUMP_SERVER,
					  nd->nd_iobuf + nd->nd_remain, n);

		nd->nd_remain += n;

		dgrp_receive(nd);
	}

	rtn = total;

unlock:
	/*
	 *  Release the NET lock.
	 */
	up(&nd->nd_net_semaphore);

	return rtn;
}


/*
 * dgrp_net_select()
 *  Determine whether a device is ready to be read or written to, and
 *  sleep if not.
 */
static unsigned int dgrp_net_select(struct file *file,
				    struct poll_table_struct *table)
{
	unsigned int retval = 0;
	struct nd_struct *nd = file->private_data;

	poll_wait(file, &nd->nd_tx_waitq, table);

	if (nd->nd_tx_ready)
		retval |= POLLIN | POLLRDNORM; /* Conditionally readable */

	retval |= POLLOUT | POLLWRNORM;        /* Always writeable */

	return retval;
}

/*
 * dgrp_net_ioctl
 *
 * Implement those functions which allow the network daemon to control
 * the network parameters in the driver.  The ioctls include ones to
 * get and set the link speed parameters for the PortServer.
 */
static long dgrp_net_ioctl(struct file *file, unsigned int cmd,
			   unsigned long arg)
{
	struct nd_struct  *nd;
	int    rtn = 0;
	long   size = _IOC_SIZE(cmd);
	struct link_struct link;

	nd = file->private_data;

	if (_IOC_DIR(cmd) & _IOC_READ)
		rtn = access_ok(VERIFY_WRITE, (void __user *) arg, size);
	else if (_IOC_DIR(cmd) & _IOC_WRITE)
		rtn = access_ok(VERIFY_READ,  (void __user *) arg, size);

	if (!rtn)
		return rtn;

	switch (cmd) {
	case DIGI_SETLINK:
		if (size != sizeof(struct link_struct))
			return -EINVAL;

		if (copy_from_user(&link, (void __user *)arg, size))
			return -EFAULT;

		if (link.lk_fast_rate < 9600)
			link.lk_fast_rate = 9600;

		if (link.lk_slow_rate < 2400)
			link.lk_slow_rate = 2400;

		if (link.lk_fast_rate > 10000000)
			link.lk_fast_rate = 10000000;

		if (link.lk_slow_rate > link.lk_fast_rate)
			link.lk_slow_rate = link.lk_fast_rate;

		if (link.lk_fast_delay > 2000)
			link.lk_fast_delay = 2000;

		if (link.lk_slow_delay > 10000)
			link.lk_slow_delay = 10000;

		if (link.lk_fast_delay < 60)
			link.lk_fast_delay = 60;

		if (link.lk_slow_delay < link.lk_fast_delay)
			link.lk_slow_delay = link.lk_fast_delay;

		if (link.lk_header_size < 2)
			link.lk_header_size = 2;

		if (link.lk_header_size > 128)
			link.lk_header_size = 128;

		link.lk_fast_rate /= 8 * 1000 / dgrp_poll_tick;
		link.lk_slow_rate /= 8 * 1000 / dgrp_poll_tick;

		link.lk_fast_delay /= dgrp_poll_tick;
		link.lk_slow_delay /= dgrp_poll_tick;

		nd->nd_link = link;

		break;

	case DIGI_GETLINK:
		if (size != sizeof(struct link_struct))
			return -EINVAL;

		if (copy_to_user((void __user *)arg, (void *)(&nd->nd_link),
				 size))
			return -EFAULT;

		break;

	default:
		return -EINVAL;

	}

	return 0;
}

/**
 * dgrp_poll_handler() -- handler for poll timer
 *
 * As each timer expires, it determines (a) whether the "transmit"
 * waiter needs to be woken up, and (b) whether the poller needs to
 * be rescheduled.
 */
void dgrp_poll_handler(unsigned long arg)
{
	struct dgrp_poll_data *poll_data;
	struct nd_struct *nd;
	struct link_struct *lk;
	ulong time;
	ulong poll_time;
	ulong freq;
	ulong lock_flags;

	poll_data = (struct dgrp_poll_data *) arg;
	freq = 1000 / poll_data->poll_tick;
	poll_data->poll_round += 17;

	if (poll_data->poll_round >= freq)
		poll_data->poll_round -= freq;

	/*
	 * Loop to process all open nodes.
	 *
	 * For each node, determine the rate at which it should
	 * be transmitting data.  Then if the node should wake up
	 * and transmit data now, enable the net receive select
	 * to get the transmit going.
	 */

	list_for_each_entry(nd, &nd_struct_list, list) {

		lk = &nd->nd_link;

		/*
		 * Decrement statistics.  These are only for use with
		 * KME, so don't worry that the operations are done
		 * unlocked, and so the results are occasionally wrong.
		 */

		nd->nd_read_count -= (nd->nd_read_count +
				      poll_data->poll_round) / freq;
		nd->nd_write_count -= (nd->nd_write_count +
				       poll_data->poll_round) / freq;
		nd->nd_send_count -= (nd->nd_send_count +
				      poll_data->poll_round) / freq;
		nd->nd_tx_byte -= (nd->nd_tx_byte +
				   poll_data->poll_round) / freq;
		nd->nd_rx_byte -= (nd->nd_rx_byte +
				   poll_data->poll_round) / freq;

		/*
		 * Wake the daemon to transmit data only when there is
		 * enough byte credit to send data.
		 *
		 * The results are approximate because the operations
		 * are performed unlocked, and we are inspecting
		 * data asynchronously updated elsewhere.  The whole
		 * thing is just approximation anyway, so that should
		 * be okay.
		 */

		if (lk->lk_slow_rate >= UIO_MAX) {

			nd->nd_delay = 0;
			nd->nd_rate = UIO_MAX;

			nd->nd_tx_deposit = nd->nd_tx_charge + 3 * UIO_MAX;
			nd->nd_tx_credit  = 3 * UIO_MAX;

		} else {

			long rate;
			long delay;
			long deposit;
			long charge;
			long size;
			long excess;

			long seq_in = nd->nd_seq_in;
			long seq_out = nd->nd_seq_out;

			/*
			 * If there are no outstanding packets, run at the
			 * fastest rate.
			 */

			if (seq_in == seq_out) {
				delay = 0;
				rate = lk->lk_fast_rate;
			}

			/*
			 * Otherwise compute the transmit rate based on the
			 * delay since the oldest packet.
			 */

			else {
				/*
				 * The actual delay is computed as the
				 * time since the oldest unacknowledged
				 * packet was sent, minus the time it
				 * took to send that packet to the server.
				 */

				delay = ((jiffies - nd->nd_seq_time[seq_out])
					- (nd->nd_seq_size[seq_out] /
					lk->lk_fast_rate));

				/*
				 * If the delay is less than the "fast"
				 * delay, transmit full speed.  If greater
				 * than the "slow" delay, transmit at the
				 * "slow" speed.   In between, interpolate
				 * between the fast and slow speeds.
				 */

				rate =
				  (delay <= lk->lk_fast_delay ?
				    lk->lk_fast_rate :
				    delay >= lk->lk_slow_delay ?
				      lk->lk_slow_rate :
				      (lk->lk_slow_rate +
				       (lk->lk_slow_delay - delay) *
				       (lk->lk_fast_rate - lk->lk_slow_rate) /
				       (lk->lk_slow_delay - lk->lk_fast_delay)
				      )
				  );
			}

			nd->nd_delay = delay;
			nd->nd_rate = rate;

			/*
			 * Increase the transmit credit by depositing the
			 * current transmit rate.
			 */

			deposit = nd->nd_tx_deposit;
			charge  = nd->nd_tx_charge;

			deposit += rate;

			/*
			 * If the available transmit credit becomes too large,
			 * reduce the deposit to correct the value.
			 *
			 * Too large is the max of:
			 *		6 times the header size
			 *		3 times the current transmit rate.
			 */

			size = 2 * nd->nd_link.lk_header_size;

			if (size < rate)
				size = rate;

			size *= 3;

			excess = deposit - charge - size;

			if (excess > 0)
				deposit -= excess;

			nd->nd_tx_deposit = deposit;
			nd->nd_tx_credit  = deposit - charge;

			/*
			 * Wake the transmit task only if the transmit credit
			 * is at least 3 times the transmit header size.
			 */

			size = 3 * lk->lk_header_size;

			if (nd->nd_tx_credit < size)
				continue;
		}


		/*
		 * Enable the READ select to wake the daemon if there
		 * is useful work for the drp_read routine to perform.
		 */

		if (waitqueue_active(&nd->nd_tx_waitq) &&
		    (nd->nd_tx_work != 0 ||
		    (ulong)(jiffies - nd->nd_tx_time) >= IDLE_MAX)) {
			nd->nd_tx_ready = 1;

			wake_up_interruptible(&nd->nd_tx_waitq);

			/* not needed */
			/* nd->nd_flag &= ~ND_SELECT; */
		}
	}


	/*
	 * Schedule ourself back at the nominal wakeup interval.
	 */
	spin_lock_irqsave(&poll_data->poll_lock, lock_flags);

	poll_data->node_active_count--;
	if (poll_data->node_active_count > 0) {
		poll_data->node_active_count++;
		poll_time = poll_data->timer.expires +
			poll_data->poll_tick * HZ / 1000;

		time = poll_time - jiffies;

		if (time >= 2 * poll_data->poll_tick)
			poll_time = jiffies + dgrp_poll_tick * HZ / 1000;

		poll_data->timer.expires = poll_time;
		add_timer(&poll_data->timer);
	}

	spin_unlock_irqrestore(&poll_data->poll_lock, lock_flags);
}
