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

static const struct file_operations 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,
};

static struct inode_operations net_inode_ops = {
	.permission = dgrp_inode_permission
};

void dgrp_register_net_hook(struct proc_dir_entry *de)
{
	struct nd_struct *node = de->data;

	de->proc_iops = &net_inode_ops;
	de->proc_fops = &net_ops;
	node->nd_net_de = de;
	sema_init(&node->nd_net_semaphore, 1);
	node->nd_state = NS_CLOSED;
	dgrp_create_node_class_sysfs_files(node);
}


/**
 * 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;
	struct proc_dir_entry *de;
	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.
	 */
	de = PDE(inode);
	if (!de) {
		rtn = -ENXIO;
		goto done;
	}

	nd = (struct nd_struct *) de->data;
	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((void *)(&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);
}
