/*
 *
 * 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 ?
					    ((jiffies - ch->ch_waketime) >= 0) :
					    (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) ? MAX_DESC_LEN :
							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);
}
