/*
 * Copyright 2003 Digi International (www.digi.com)
 *	Scott H Kilau <Scott_Kilau 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 *	NOTE TO LINUX KERNEL HACKERS:  DO NOT REFORMAT THIS CODE!
 *
 *	This is shared code between Digi's CVS archive and the
 *	Linux Kernel sources.
 *	Changing the source just for reformatting needlessly breaks
 *	our CVS diff history.
 *
 *	Send any bug fixes/changes to:  Eng.Linux at digi dot com.
 *	Thank you.
 *
 */

/************************************************************************
 *
 * This file implements the mgmt functionality for the
 * Neo and ClassicBoard based product lines.
 *
 ************************************************************************
 */
#include <linux/kernel.h>
#include <linux/ctype.h>
#include <linux/sched.h>	/* For jiffies, task states */
#include <linux/interrupt.h>	/* For tasklet and interrupt structs/defines */
#include <linux/serial_reg.h>
#include <linux/termios.h>
#include <linux/uaccess.h>	/* For copy_from_user/copy_to_user */

#include "dgnc_driver.h"
#include "dgnc_pci.h"
#include "dgnc_kcompat.h"	/* Kernel 2.4/2.6 compat includes */
#include "dgnc_mgmt.h"
#include "dpacompat.h"


/* Our "in use" variables, to enforce 1 open only */
static int dgnc_mgmt_in_use[MAXMGMTDEVICES];


/*
 * dgnc_mgmt_open()
 *
 * Open the mgmt/downld/dpa device
 */
int dgnc_mgmt_open(struct inode *inode, struct file *file)
{
	unsigned long lock_flags;
	unsigned int minor = iminor(inode);

	DPR_MGMT(("dgnc_mgmt_open start.\n"));

	DGNC_LOCK(dgnc_global_lock, lock_flags);

	/* mgmt device */
	if (minor < MAXMGMTDEVICES) {
		/* Only allow 1 open at a time on mgmt device */
		if (dgnc_mgmt_in_use[minor]) {
			DGNC_UNLOCK(dgnc_global_lock, lock_flags);
			return -EBUSY;
		}
		dgnc_mgmt_in_use[minor]++;
	} else {
		DGNC_UNLOCK(dgnc_global_lock, lock_flags);
		return -ENXIO;
	}

	DGNC_UNLOCK(dgnc_global_lock, lock_flags);

	DPR_MGMT(("dgnc_mgmt_open finish.\n"));

	return 0;
}


/*
 * dgnc_mgmt_close()
 *
 * Open the mgmt/dpa device
 */
int dgnc_mgmt_close(struct inode *inode, struct file *file)
{
	unsigned long lock_flags;
	unsigned int minor = iminor(inode);

	DPR_MGMT(("dgnc_mgmt_close start.\n"));

	DGNC_LOCK(dgnc_global_lock, lock_flags);

	/* mgmt device */
	if (minor < MAXMGMTDEVICES) {
		if (dgnc_mgmt_in_use[minor])
			dgnc_mgmt_in_use[minor] = 0;
	}
	DGNC_UNLOCK(dgnc_global_lock, lock_flags);

	DPR_MGMT(("dgnc_mgmt_close finish.\n"));

	return 0;
}


/*
 * dgnc_mgmt_ioctl()
 *
 * ioctl the mgmt/dpa device
 */

long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	unsigned long lock_flags;
	void __user *uarg = (void __user *) arg;

	DPR_MGMT(("dgnc_mgmt_ioctl start.\n"));

	switch (cmd) {

	case DIGI_GETDD:
	{
		/*
		 * This returns the total number of boards
		 * in the system, as well as driver version
		 * and has space for a reserved entry
		 */
		struct digi_dinfo ddi;

		DGNC_LOCK(dgnc_global_lock, lock_flags);

		ddi.dinfo_nboards = dgnc_NumBoards;
		sprintf(ddi.dinfo_version, "%s", DG_PART);

		DGNC_UNLOCK(dgnc_global_lock, lock_flags);

		DPR_MGMT(("DIGI_GETDD returning numboards: %d version: %s\n",
			ddi.dinfo_nboards, ddi.dinfo_version));

		if (copy_to_user(uarg, &ddi, sizeof(ddi)))
			return -EFAULT;

		break;
	}

	case DIGI_GETBD:
	{
		int brd;

		struct digi_info di;

		if (copy_from_user(&brd, uarg, sizeof(int)))
			return -EFAULT;

		DPR_MGMT(("DIGI_GETBD asking about board: %d\n", brd));

		if ((brd < 0) || (brd > dgnc_NumBoards) ||
		    (dgnc_NumBoards == 0))
			return -ENODEV;

		memset(&di, 0, sizeof(di));

		di.info_bdnum = brd;

		DGNC_LOCK(dgnc_Board[brd]->bd_lock, lock_flags);

		di.info_bdtype = dgnc_Board[brd]->dpatype;
		di.info_bdstate = dgnc_Board[brd]->dpastatus;
		di.info_ioport = 0;
		di.info_physaddr = (ulong) dgnc_Board[brd]->membase;
		di.info_physsize = (ulong) dgnc_Board[brd]->membase - dgnc_Board[brd]->membase_end;
		if (dgnc_Board[brd]->state != BOARD_FAILED)
			di.info_nports = dgnc_Board[brd]->nasync;
		else
			di.info_nports = 0;

		DGNC_UNLOCK(dgnc_Board[brd]->bd_lock, lock_flags);

		DPR_MGMT(("DIGI_GETBD returning type: %x state: %x ports: %x size: %x\n",
			di.info_bdtype, di.info_bdstate, di.info_nports, di.info_physsize));

		if (copy_to_user(uarg, &di, sizeof(di)))
			return -EFAULT;

		break;
	}

	case DIGI_GET_NI_INFO:
	{
		struct channel_t *ch;
		struct ni_info ni;
		uchar mstat = 0;
		uint board = 0;
		uint channel = 0;

		if (copy_from_user(&ni, uarg, sizeof(ni)))
			return -EFAULT;

		DPR_MGMT(("DIGI_GETBD asking about board: %d channel: %d\n",
			ni.board, ni.channel));

		board = ni.board;
		channel = ni.channel;

		/* Verify boundaries on board */
		if ((board > dgnc_NumBoards) || (dgnc_NumBoards == 0))
			return -ENODEV;

		/* Verify boundaries on channel */
		if ((channel < 0) || (channel > dgnc_Board[board]->nasync))
			return -ENODEV;

		ch = dgnc_Board[board]->channels[channel];

		if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
			return -ENODEV;

		memset(&ni, 0, sizeof(ni));
		ni.board = board;
		ni.channel = channel;

		DGNC_LOCK(ch->ch_lock, lock_flags);

		mstat = (ch->ch_mostat | ch->ch_mistat);

		if (mstat & UART_MCR_DTR) {
			ni.mstat |= TIOCM_DTR;
			ni.dtr = TIOCM_DTR;
		}
		if (mstat & UART_MCR_RTS) {
			ni.mstat |= TIOCM_RTS;
			ni.rts = TIOCM_RTS;
		}
		if (mstat & UART_MSR_CTS) {
			ni.mstat |= TIOCM_CTS;
			ni.cts = TIOCM_CTS;
		}
		if (mstat & UART_MSR_RI) {
			ni.mstat |= TIOCM_RI;
			ni.ri = TIOCM_RI;
		}
		if (mstat & UART_MSR_DCD) {
			ni.mstat |= TIOCM_CD;
			ni.dcd = TIOCM_CD;
		}
		if (mstat & UART_MSR_DSR)
			ni.mstat |= TIOCM_DSR;

		ni.iflag = ch->ch_c_iflag;
		ni.oflag = ch->ch_c_oflag;
		ni.cflag = ch->ch_c_cflag;
		ni.lflag = ch->ch_c_lflag;

		if (ch->ch_digi.digi_flags & CTSPACE ||
		    ch->ch_c_cflag & CRTSCTS)
			ni.hflow = 1;
		else
			ni.hflow = 0;

		if ((ch->ch_flags & CH_STOPI) ||
		    (ch->ch_flags & CH_FORCED_STOPI))
			ni.recv_stopped = 1;
		else
			ni.recv_stopped = 0;

		if ((ch->ch_flags & CH_STOP) || (ch->ch_flags & CH_FORCED_STOP))
			ni.xmit_stopped = 1;
		else
			ni.xmit_stopped = 0;

		ni.curtx = ch->ch_txcount;
		ni.currx = ch->ch_rxcount;

		ni.baud = ch->ch_old_baud;

		DGNC_UNLOCK(ch->ch_lock, lock_flags);

		if (copy_to_user(uarg, &ni, sizeof(ni)))
			return -EFAULT;

		break;
	}


	}

	DPR_MGMT(("dgnc_mgmt_ioctl finish.\n"));

	return 0;
}
