/*
 *
 * 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_dpa_ops.c
 *
 *  Description:
 *
 *     Handle the file operations required for the "dpa" devices.
 *     Includes those functions required to register the "dpa" devices
 *     in "/proc".
 *
 *  Author:
 *
 *     James A. Puzzo
 *
 */

#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/tty.h>
#include <linux/poll.h>
#include <linux/cred.h>
#include <linux/sched.h>
#include <linux/ratelimit.h>
#include <linux/slab.h>
#include <asm/unaligned.h>

#include "dgrp_common.h"

/* File operation declarations */
static int dgrp_dpa_open(struct inode *, struct file *);
static int dgrp_dpa_release(struct inode *, struct file *);
static ssize_t dgrp_dpa_read(struct file *, char __user *, size_t, loff_t *);
static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd,
			   unsigned long arg);
static unsigned int dgrp_dpa_select(struct file *, struct poll_table_struct *);

const struct file_operations dgrp_dpa_ops = {
	.owner   =  THIS_MODULE,
	.read    =  dgrp_dpa_read,
	.poll    =  dgrp_dpa_select,
	.unlocked_ioctl =  dgrp_dpa_ioctl,
	.open    =  dgrp_dpa_open,
	.release =  dgrp_dpa_release,
};

struct digi_node {
	uint	nd_state;		/* Node state: 1 = up, 0 = down. */
	uint	nd_chan_count;		/* Number of channels found */
	uint	nd_tx_byte;		/* Tx data count */
	uint	nd_rx_byte;		/* RX data count */
	u8	nd_ps_desc[MAX_DESC_LEN]; /* Description from PS */
};

#define DIGI_GETNODE      (('d'<<8) | 249)	/* get board info */


struct digi_chan {
	uint	ch_port;	/* Port number to get info on */
	uint	ch_open;	/* 1 if open, 0 if not */
	uint	ch_txcount;	/* TX data count  */
	uint	ch_rxcount;	/* RX data count  */
	uint	ch_s_brate;	/* Realport BRATE */
	uint	ch_s_estat;	/* Realport ELAST */
	uint	ch_s_cflag;	/* Realport CFLAG */
	uint	ch_s_iflag;	/* Realport IFLAG */
	uint	ch_s_oflag;	/* Realport OFLAG */
	uint	ch_s_xflag;	/* Realport XFLAG */
	uint	ch_s_mstat;	/* Realport MLAST */
};

#define DIGI_GETCHAN      (('d'<<8) | 248)	/* get channel info */


struct digi_vpd {
	int vpd_len;
	char vpd_data[VPDSIZE];
};

#define DIGI_GETVPD       (('d'<<8) | 246)	/* get VPD info */


struct digi_debug {
	int onoff;
	int port;
};

#define DIGI_SETDEBUG      (('d'<<8) | 247)	/* set debug info */


/*
 * dgrp_dpa_open -- open the DPA device for a particular PortServer
 */
static int dgrp_dpa_open(struct inode *inode, struct file *file)
{
	struct nd_struct *nd;
	int rtn = 0;

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

	rtn = 0;

	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;

	/*
	 * Allocate the DPA buffer.
	 */

	if (nd->nd_dpa_buf) {
		rtn = -EBUSY;
	} else {
		nd->nd_dpa_buf = kmalloc(DPA_MAX, GFP_KERNEL);

		if (!nd->nd_dpa_buf) {
			rtn = -ENOMEM;
		} else {
			nd->nd_dpa_out = 0;
			nd->nd_dpa_in = 0;
			nd->nd_dpa_lbolt = jiffies;
		}
	}

done:

	if (rtn)
		module_put(THIS_MODULE);
	return rtn;
}

/*
 * dgrp_dpa_release -- close the DPA device for a particular PortServer
 */
static int dgrp_dpa_release(struct inode *inode, struct file *file)
{
	struct nd_struct *nd;
	u8 *buf;
	unsigned long lock_flags;

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

	/*
	 *  Free the dpa buffer.
	 */

	spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);

	buf = nd->nd_dpa_buf;

	nd->nd_dpa_buf = NULL;
	nd->nd_dpa_out = nd->nd_dpa_in;

	/*
	 *  Wakeup any thread waiting for buffer space.
	 */

	if (nd->nd_dpa_flag & DPA_WAIT_SPACE) {
		nd->nd_dpa_flag &= ~DPA_WAIT_SPACE;
		wake_up_interruptible(&nd->nd_dpa_wqueue);
	}

	spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);

	kfree(buf);

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

/*
 * dgrp_dpa_read
 *
 * Copy data from the monitoring buffer to the user, freeing space
 * in the monitoring buffer for more messages
 */
static ssize_t dgrp_dpa_read(struct file *file, char __user *buf, size_t count,
			     loff_t *ppos)
{
	struct nd_struct *nd;
	int n;
	int r;
	int offset = 0;
	int res = 0;
	ssize_t rtn;
	unsigned long lock_flags;

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

	/*
	 *  Wait for some data to appear in the buffer.
	 */

	spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);

	for (;;) {
		n = (nd->nd_dpa_in - nd->nd_dpa_out) & DPA_MASK;

		if (n != 0)
			break;

		nd->nd_dpa_flag |= DPA_WAIT_DATA;

		spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);

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

		if (rtn)
			return rtn;

		spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
	}

	/*
	 *  Read whatever is there.
	 */

	if (n > count)
		n = count;

	res = n;

	r = DPA_MAX - nd->nd_dpa_out;

	if (r <= n) {

		spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
		rtn = copy_to_user((void __user *)buf,
				   nd->nd_dpa_buf + nd->nd_dpa_out, r);
		spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);

		if (rtn) {
			rtn = -EFAULT;
			goto done;
		}

		nd->nd_dpa_out = 0;
		n -= r;
		offset = r;
	}

	spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
	rtn = copy_to_user((void __user *)buf + offset,
			   nd->nd_dpa_buf + nd->nd_dpa_out, n);
	spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);

	if (rtn) {
		rtn = -EFAULT;
		goto done;
	}

	nd->nd_dpa_out += n;

	*ppos += res;

	rtn = res;

	/*
	 *  Wakeup any thread waiting for buffer space.
	 */

	n = (nd->nd_dpa_in - nd->nd_dpa_out) & DPA_MASK;

	if (nd->nd_dpa_flag & DPA_WAIT_SPACE &&
	    (DPA_MAX - n) > DPA_HIGH_WATER) {
		nd->nd_dpa_flag &= ~DPA_WAIT_SPACE;
		wake_up_interruptible(&nd->nd_dpa_wqueue);
	}

 done:
	spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
	return rtn;
}

static unsigned int dgrp_dpa_select(struct file *file,
				    struct poll_table_struct *table)
{
	unsigned int retval = 0;
	struct nd_struct *nd = file->private_data;

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

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

	return retval;
}

static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd,
			   unsigned long arg)
{

	struct nd_struct  *nd;
	struct digi_chan getchan;
	struct digi_node getnode;
	struct ch_struct *ch;
	struct digi_debug setdebug;
	struct digi_vpd vpd;
	unsigned int port;
	void __user *uarg = (void __user *) arg;

	nd = file->private_data;

	switch (cmd) {
	case DIGI_GETCHAN:
		if (copy_from_user(&getchan, uarg, sizeof(struct digi_chan)))
			return -EFAULT;

		port = getchan.ch_port;

		if (port > nd->nd_chan_count)
			return -EINVAL;

		ch = nd->nd_chan + port;

		getchan.ch_open = (ch->ch_open_count > 0) ? 1 : 0;
		getchan.ch_txcount = ch->ch_txcount;
		getchan.ch_rxcount = ch->ch_rxcount;
		getchan.ch_s_brate = ch->ch_s_brate;
		getchan.ch_s_estat = ch->ch_s_elast;
		getchan.ch_s_cflag = ch->ch_s_cflag;
		getchan.ch_s_iflag = ch->ch_s_iflag;
		getchan.ch_s_oflag = ch->ch_s_oflag;
		getchan.ch_s_xflag = ch->ch_s_xflag;
		getchan.ch_s_mstat = ch->ch_s_mlast;

		if (copy_to_user(uarg, &getchan, sizeof(struct digi_chan)))
			return -EFAULT;
		break;


	case DIGI_GETNODE:
		getnode.nd_state = (nd->nd_state & NS_READY) ? 1 : 0;
		getnode.nd_chan_count = nd->nd_chan_count;
		getnode.nd_tx_byte = nd->nd_tx_byte;
		getnode.nd_rx_byte = nd->nd_rx_byte;

		memset(&getnode.nd_ps_desc, 0, MAX_DESC_LEN);
		strlcpy(getnode.nd_ps_desc, nd->nd_ps_desc, MAX_DESC_LEN);

		if (copy_to_user(uarg, &getnode, sizeof(struct digi_node)))
			return -EFAULT;
		break;


	case DIGI_SETDEBUG:
		if (copy_from_user(&setdebug, uarg, sizeof(struct digi_debug)))
			return -EFAULT;

		nd->nd_dpa_debug = setdebug.onoff;
		nd->nd_dpa_port = setdebug.port;
		break;


	case DIGI_GETVPD:
		memset(&vpd, 0, sizeof(vpd));
		if (nd->nd_vpd_len > 0) {
			vpd.vpd_len = nd->nd_vpd_len;
			memcpy(&vpd.vpd_data, &nd->nd_vpd, nd->nd_vpd_len);
		} else {
			vpd.vpd_len = 0;
		}

		if (copy_to_user(uarg, &vpd, sizeof(struct digi_vpd)))
			return -EFAULT;
		break;
	}

	return 0;
}

/**
 * dgrp_dpa() -- send data to the device monitor queue
 * @nd: pointer to a node structure
 * @buf: buffer of 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_dpa(struct nd_struct *nd, u8 *buf, int nbuf)
{
	int n;
	int r;
	unsigned long lock_flags;

	/*
	 *  Grab DPA lock.
	 */
	spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);

	/*
	 *  Loop while data remains.
	 */
	while (nbuf > 0 && nd->nd_dpa_buf != NULL) {

		n = (nd->nd_dpa_out - nd->nd_dpa_in - 1) & DPA_MASK;

		/*
		 * Enforce flow control on the DPA device.
		 */
		if (n < (DPA_MAX - DPA_HIGH_WATER))
			nd->nd_dpa_flag |= DPA_WAIT_SPACE;

		/*
		 * This should never happen, as the flow control above
		 * should have stopped things before they got to this point.
		 */
		if (n == 0) {
			spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
			return;
		}

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

		if (n > nbuf)
			n = nbuf;

		r = DPA_MAX - nd->nd_dpa_in;

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

			n -= r;

			nd->nd_dpa_in = 0;

			buf += r;
			nbuf -= r;
		}

		memcpy(nd->nd_dpa_buf + nd->nd_dpa_in, buf, n);

		nd->nd_dpa_in += n;

		buf += n;
		nbuf -= n;

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

		/*
		 *  Wakeup any thread waiting for data
		 */
		if (nd->nd_dpa_flag & DPA_WAIT_DATA) {
			nd->nd_dpa_flag &= ~DPA_WAIT_DATA;
			wake_up_interruptible(&nd->nd_dpa_wqueue);
		}
	}

	/*
	 *  Release the DPA lock.
	 */
	spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
}

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

	header[0] = type;

	put_unaligned_be32(size, header + 1);

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