/************************************************************************
 * Copyright 2003 Digi International (www.digi.com)
 *
 * Copyright (C) 2004 IBM Corporation. All rights reserved.
 *
 * 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., 59 * Temple Place - Suite 330, Boston,
 * MA  02111-1307, USA.
 *
 * Contact Information:
 * Scott H Kilau <Scott_Kilau@digi.com>
 * Ananda Venkatarman <mansarov@us.ibm.com>
 * Modifications:
 * 01/19/06:	changed jsm_input routine to use the dynamically allocated
 *		tty_buffer changes. Contributors: Scott Kilau and Ananda V.
 ***********************************************************************/
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_reg.h>
#include <linux/delay.h>	/* For udelay */
#include <linux/pci.h>

#include "jsm.h"

static void jsm_carrier(struct jsm_channel *ch);

static inline int jsm_get_mstat(struct jsm_channel *ch)
{
	unsigned char mstat;
	unsigned result;

	jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "start\n");

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

	result = 0;

	if (mstat & UART_MCR_DTR)
		result |= TIOCM_DTR;
	if (mstat & UART_MCR_RTS)
		result |= TIOCM_RTS;
	if (mstat & UART_MSR_CTS)
		result |= TIOCM_CTS;
	if (mstat & UART_MSR_DSR)
		result |= TIOCM_DSR;
	if (mstat & UART_MSR_RI)
		result |= TIOCM_RI;
	if (mstat & UART_MSR_DCD)
		result |= TIOCM_CD;

	jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n");
	return result;
}

static unsigned int jsm_tty_tx_empty(struct uart_port *port)
{
	return TIOCSER_TEMT;
}

/*
 * Return modem signals to ld.
 */
static unsigned int jsm_tty_get_mctrl(struct uart_port *port)
{
	int result;
	struct jsm_channel *channel = (struct jsm_channel *)port;

	jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n");

	result = jsm_get_mstat(channel);

	if (result < 0)
		return -ENXIO;

	jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n");

	return result;
}

/*
 * jsm_set_modem_info()
 *
 * Set modem signals, called by ld.
 */
static void jsm_tty_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	struct jsm_channel *channel = (struct jsm_channel *)port;

	jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n");

	if (mctrl & TIOCM_RTS)
		channel->ch_mostat |= UART_MCR_RTS;
	else
		channel->ch_mostat &= ~UART_MCR_RTS;

	if (mctrl & TIOCM_DTR)
		channel->ch_mostat |= UART_MCR_DTR;
	else
		channel->ch_mostat &= ~UART_MCR_DTR;

	channel->ch_bd->bd_ops->assert_modem_signals(channel);

	jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n");
	udelay(10);
}

static void jsm_tty_start_tx(struct uart_port *port)
{
	struct jsm_channel *channel = (struct jsm_channel *)port;

	jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n");

	channel->ch_flags &= ~(CH_STOP);
	jsm_tty_write(port);

	jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n");
}

static void jsm_tty_stop_tx(struct uart_port *port)
{
	struct jsm_channel *channel = (struct jsm_channel *)port;

	jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n");

	channel->ch_flags |= (CH_STOP);

	jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n");
}

static void jsm_tty_send_xchar(struct uart_port *port, char ch)
{
	unsigned long lock_flags;
	struct jsm_channel *channel = (struct jsm_channel *)port;
	struct termios *termios;

	spin_lock_irqsave(&port->lock, lock_flags);
	termios = port->info->tty->termios;
	if (ch == termios->c_cc[VSTART])
		channel->ch_bd->bd_ops->send_start_character(channel);

	if (ch == termios->c_cc[VSTOP])
		channel->ch_bd->bd_ops->send_stop_character(channel);
	spin_unlock_irqrestore(&port->lock, lock_flags);
}

static void jsm_tty_stop_rx(struct uart_port *port)
{
	struct jsm_channel *channel = (struct jsm_channel *)port;

	channel->ch_bd->bd_ops->disable_receiver(channel);
}

static void jsm_tty_break(struct uart_port *port, int break_state)
{
	unsigned long lock_flags;
	struct jsm_channel *channel = (struct jsm_channel *)port;

	spin_lock_irqsave(&port->lock, lock_flags);
	if (break_state == -1)
		channel->ch_bd->bd_ops->send_break(channel);
	else
		channel->ch_bd->bd_ops->clear_break(channel, 0);

	spin_unlock_irqrestore(&port->lock, lock_flags);
}

static int jsm_tty_open(struct uart_port *port)
{
	struct jsm_board *brd;
	int rc = 0;
	struct jsm_channel *channel = (struct jsm_channel *)port;
	struct termios *termios;

	/* Get board pointer from our array of majors we have allocated */
	brd = channel->ch_bd;

	/*
	 * Allocate channel buffers for read/write/error.
	 * Set flag, so we don't get trounced on.
	 */
	channel->ch_flags |= (CH_OPENING);

	/* Drop locks, as malloc with GFP_KERNEL can sleep */

	if (!channel->ch_rqueue) {
		channel->ch_rqueue = (u8 *) kmalloc(RQUEUESIZE, GFP_KERNEL);
		if (!channel->ch_rqueue) {
			jsm_printk(INIT, ERR, &channel->ch_bd->pci_dev,
				"unable to allocate read queue buf");
			return -ENOMEM;
		}
		memset(channel->ch_rqueue, 0, RQUEUESIZE);
	}
	if (!channel->ch_equeue) {
		channel->ch_equeue = (u8 *) kmalloc(EQUEUESIZE, GFP_KERNEL);
		if (!channel->ch_equeue) {
			jsm_printk(INIT, ERR, &channel->ch_bd->pci_dev,
				"unable to allocate error queue buf");
			return -ENOMEM;
		}
		memset(channel->ch_equeue, 0, EQUEUESIZE);
	}
	if (!channel->ch_wqueue) {
		channel->ch_wqueue = (u8 *) kmalloc(WQUEUESIZE, GFP_KERNEL);
		if (!channel->ch_wqueue) {
			jsm_printk(INIT, ERR, &channel->ch_bd->pci_dev,
				"unable to allocate write queue buf");
			return -ENOMEM;
		}
		memset(channel->ch_wqueue, 0, WQUEUESIZE);
	}

	channel->ch_flags &= ~(CH_OPENING);
	/*
	 * Initialize if neither terminal is open.
	 */
	jsm_printk(OPEN, INFO, &channel->ch_bd->pci_dev,
		"jsm_open: initializing channel in open...\n");

	/*
	 * Flush input queues.
	 */
	channel->ch_r_head = channel->ch_r_tail = 0;
	channel->ch_e_head = channel->ch_e_tail = 0;
	channel->ch_w_head = channel->ch_w_tail = 0;

	brd->bd_ops->flush_uart_write(channel);
	brd->bd_ops->flush_uart_read(channel);

	channel->ch_flags = 0;
	channel->ch_cached_lsr = 0;
	channel->ch_stops_sent = 0;

	termios = port->info->tty->termios;
	channel->ch_c_cflag	= termios->c_cflag;
	channel->ch_c_iflag	= termios->c_iflag;
	channel->ch_c_oflag	= termios->c_oflag;
	channel->ch_c_lflag	= termios->c_lflag;
	channel->ch_startc	= termios->c_cc[VSTART];
	channel->ch_stopc	= termios->c_cc[VSTOP];

	/* Tell UART to init itself */
	brd->bd_ops->uart_init(channel);

	/*
	 * Run param in case we changed anything
	 */
	brd->bd_ops->param(channel);

	jsm_carrier(channel);

	channel->ch_open_count++;

	jsm_printk(OPEN, INFO, &channel->ch_bd->pci_dev, "finish\n");
	return rc;
}

static void jsm_tty_close(struct uart_port *port)
{
	struct jsm_board *bd;
	struct termios *ts;
	struct jsm_channel *channel = (struct jsm_channel *)port;

	jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n");

	bd = channel->ch_bd;
	ts = channel->uart_port.info->tty->termios;

	channel->ch_flags &= ~(CH_STOPI);

	channel->ch_open_count--;

	/*
	 * If we have HUPCL set, lower DTR and RTS
	 */
	if (channel->ch_c_cflag & HUPCL) {
		jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev,
			"Close. HUPCL set, dropping DTR/RTS\n");

		/* Drop RTS/DTR */
		channel->ch_mostat &= ~(UART_MCR_DTR | UART_MCR_RTS);
		bd->bd_ops->assert_modem_signals(channel);
	}

	channel->ch_old_baud = 0;

	/* Turn off UART interrupts for this port */
	channel->ch_bd->bd_ops->uart_off(channel);

	jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "finish\n");
}

static void jsm_tty_set_termios(struct uart_port *port,
				 struct termios *termios,
				 struct termios *old_termios)
{
	unsigned long lock_flags;
	struct jsm_channel *channel = (struct jsm_channel *)port;

	spin_lock_irqsave(&port->lock, lock_flags);
	channel->ch_c_cflag	= termios->c_cflag;
	channel->ch_c_iflag	= termios->c_iflag;
	channel->ch_c_oflag	= termios->c_oflag;
	channel->ch_c_lflag	= termios->c_lflag;
	channel->ch_startc	= termios->c_cc[VSTART];
	channel->ch_stopc	= termios->c_cc[VSTOP];

	channel->ch_bd->bd_ops->param(channel);
	jsm_carrier(channel);
	spin_unlock_irqrestore(&port->lock, lock_flags);
}

static const char *jsm_tty_type(struct uart_port *port)
{
	return "jsm";
}

static void jsm_tty_release_port(struct uart_port *port)
{
}

static int jsm_tty_request_port(struct uart_port *port)
{
	return 0;
}

static void jsm_config_port(struct uart_port *port, int flags)
{
	port->type = PORT_JSM;
}

static struct uart_ops jsm_ops = {
	.tx_empty	= jsm_tty_tx_empty,
	.set_mctrl	= jsm_tty_set_mctrl,
	.get_mctrl	= jsm_tty_get_mctrl,
	.stop_tx	= jsm_tty_stop_tx,
	.start_tx	= jsm_tty_start_tx,
	.send_xchar	= jsm_tty_send_xchar,
	.stop_rx	= jsm_tty_stop_rx,
	.break_ctl	= jsm_tty_break,
	.startup	= jsm_tty_open,
	.shutdown	= jsm_tty_close,
	.set_termios	= jsm_tty_set_termios,
	.type		= jsm_tty_type,
	.release_port	= jsm_tty_release_port,
	.request_port	= jsm_tty_request_port,
	.config_port	= jsm_config_port,
};

/*
 * jsm_tty_init()
 *
 * Init the tty subsystem.  Called once per board after board has been
 * downloaded and init'ed.
 */
int jsm_tty_init(struct jsm_board *brd)
{
	int i;
	void __iomem *vaddr;
	struct jsm_channel *ch;

	if (!brd)
		return -ENXIO;

	jsm_printk(INIT, INFO, &brd->pci_dev, "start\n");

	/*
	 * Initialize board structure elements.
	 */

	brd->nasync = brd->maxports;

	/*
	 * Allocate channel memory that might not have been allocated
	 * when the driver was first loaded.
	 */
	for (i = 0; i < brd->nasync; i++) {
		if (!brd->channels[i]) {

			/*
			 * Okay to malloc with GFP_KERNEL, we are not at
			 * interrupt context, and there are no locks held.
			 */
			brd->channels[i] = kmalloc(sizeof(struct jsm_channel), GFP_KERNEL);
			if (!brd->channels[i]) {
				jsm_printk(CORE, ERR, &brd->pci_dev,
					"%s:%d Unable to allocate memory for channel struct\n",
							 __FILE__, __LINE__);
			}
			memset(brd->channels[i], 0, sizeof(struct jsm_channel));
		}
	}

	ch = brd->channels[0];
	vaddr = brd->re_map_membase;

	/* Set up channel variables */
	for (i = 0; i < brd->nasync; i++, ch = brd->channels[i]) {

		if (!brd->channels[i])
			continue;

		spin_lock_init(&ch->ch_lock);

		if (brd->bd_uart_offset == 0x200)
			ch->ch_neo_uart =  vaddr + (brd->bd_uart_offset * i);

		ch->ch_bd = brd;
		ch->ch_portnum = i;

		/* .25 second delay */
		ch->ch_close_delay = 250;

		init_waitqueue_head(&ch->ch_flags_wait);
	}

	jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n");
	return 0;
}

int jsm_uart_port_init(struct jsm_board *brd)
{
	int i;
	struct jsm_channel *ch;

	if (!brd)
		return -ENXIO;

	jsm_printk(INIT, INFO, &brd->pci_dev, "start\n");

	/*
	 * Initialize board structure elements.
	 */

	brd->nasync = brd->maxports;

	/* Set up channel variables */
	for (i = 0; i < brd->nasync; i++, ch = brd->channels[i]) {

		if (!brd->channels[i])
			continue;

		brd->channels[i]->uart_port.irq = brd->irq;
		brd->channels[i]->uart_port.type = PORT_JSM;
		brd->channels[i]->uart_port.iotype = UPIO_MEM;
		brd->channels[i]->uart_port.membase = brd->re_map_membase;
		brd->channels[i]->uart_port.fifosize = 16;
		brd->channels[i]->uart_port.ops = &jsm_ops;
		brd->channels[i]->uart_port.line = brd->channels[i]->ch_portnum + brd->boardnum * 2;
		if (uart_add_one_port (&jsm_uart_driver, &brd->channels[i]->uart_port))
			printk(KERN_INFO "Added device failed\n");
		else
			printk(KERN_INFO "Added device \n");
	}

	jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n");
	return 0;
}

int jsm_remove_uart_port(struct jsm_board *brd)
{
	int i;
	struct jsm_channel *ch;

	if (!brd)
		return -ENXIO;

	jsm_printk(INIT, INFO, &brd->pci_dev, "start\n");

	/*
	 * Initialize board structure elements.
	 */

	brd->nasync = brd->maxports;

	/* Set up channel variables */
	for (i = 0; i < brd->nasync; i++) {

		if (!brd->channels[i])
			continue;

		ch = brd->channels[i];

		uart_remove_one_port(&jsm_uart_driver, &brd->channels[i]->uart_port);
	}

	jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n");
	return 0;
}

void jsm_input(struct jsm_channel *ch)
{
	struct jsm_board *bd;
	struct tty_struct *tp;
	struct tty_ldisc *ld;
	u32 rmask;
	u16 head;
	u16 tail;
	int data_len;
	unsigned long lock_flags;
	int flip_len = 0;
	int len = 0;
	int n = 0;
	int s = 0;
	int i = 0;

	jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start\n");

	if (!ch)
		return;

	tp = ch->uart_port.info->tty;

	bd = ch->ch_bd;
	if(!bd)
		return;

	spin_lock_irqsave(&ch->ch_lock, lock_flags);

	/*
	 *Figure the number of characters in the buffer.
	 *Exit immediately if none.
	 */

	rmask = RQUEUEMASK;

	head = ch->ch_r_head & rmask;
	tail = ch->ch_r_tail & rmask;

	data_len = (head - tail) & rmask;
	if (data_len == 0) {
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
		return;
	}

	jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start\n");

	/*
	 *If the device is not open, or CREAD is off, flush
	 *input data and return immediately.
	 */
	if (!tp ||
		!(tp->termios->c_cflag & CREAD) ) {

		jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
			"input. dropping %d bytes on port %d...\n", data_len, ch->ch_portnum);
		ch->ch_r_head = tail;

		/* Force queue flow control to be released, if needed */
		jsm_check_queue_flow_control(ch);

		spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
		return;
	}

	/*
	 * If we are throttled, simply don't read any data.
	 */
	if (ch->ch_flags & CH_STOPI) {
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
		jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
			"Port %d throttled, not reading any data. head: %x tail: %x\n",
			ch->ch_portnum, head, tail);
		return;
	}

	jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start 2\n");

	/*
	 * If the rxbuf is empty and we are not throttled, put as much
	 * as we can directly into the linux TTY buffer.
	 *
	 */
	flip_len = TTY_FLIPBUF_SIZE;

	len = min(data_len, flip_len);
	len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt);
	ld = tty_ldisc_ref(tp);

	/*
	 * If the DONT_FLIP flag is on, don't flush our buffer, and act
	 * like the ld doesn't have any space to put the data right now.
	 */
	if (test_bit(TTY_DONT_FLIP, &tp->flags))
		len = 0;

	/*
	 * If we were unable to get a reference to the ld,
	 * don't flush our buffer, and act like the ld doesn't
	 * have any space to put the data right now.
	 */
	if (!ld) {
		len = 0;
	} else {
		/*
		 * If ld doesn't have a pointer to a receive_buf function,
		 * flush the data, then act like the ld doesn't have any
		 * space to put the data right now.
		 */
		if (!ld->receive_buf) {
				ch->ch_r_head = ch->ch_r_tail;
				len = 0;
		}
	}

	if (len <= 0) {
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
		jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n");
		if (ld)
			tty_ldisc_deref(ld);
		return;
	}

	len = tty_buffer_request_room(tp, len);
	n = len;

	/*
	 * n now contains the most amount of data we can copy,
	 * bounded either by the flip buffer size or the amount
	 * of data the card actually has pending...
	 */
	while (n) {
		s = ((head >= tail) ? head : RQUEUESIZE) - tail;
		s = min(s, n);

		if (s <= 0)
			break;

			/*
			 * If conditions are such that ld needs to see all
			 * UART errors, we will have to walk each character
			 * and error byte and send them to the buffer one at
			 * a time.
			 */

		if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) {
			for (i = 0; i < s; i++) {
				/*
				 * Give the Linux ld the flags in the
				 * format it likes.
				 */
				if (*(ch->ch_equeue +tail +i) & UART_LSR_BI)
					tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i),  TTY_BREAK);
				else if (*(ch->ch_equeue +tail +i) & UART_LSR_PE)
					tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_PARITY);
				else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE)
					tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_FRAME);
				else
				tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_NORMAL);
			}
		} else {
			tty_insert_flip_string(tp, ch->ch_rqueue + tail, s) ;
		}
		tail += s;
		n -= s;
		/* Flip queue if needed */
		tail &= rmask;
	}

	ch->ch_r_tail = tail & rmask;
	ch->ch_e_tail = tail & rmask;
	jsm_check_queue_flow_control(ch);
	spin_unlock_irqrestore(&ch->ch_lock, lock_flags);

	/* Tell the tty layer its okay to "eat" the data now */
	tty_flip_buffer_push(tp);

	if (ld)
		tty_ldisc_deref(ld);

	jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n");
}

static void jsm_carrier(struct jsm_channel *ch)
{
	struct jsm_board *bd;

	int virt_carrier = 0;
	int phys_carrier = 0;

	jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev, "start\n");
	if (!ch)
		return;

	bd = ch->ch_bd;

	if (!bd)
		return;

	if (ch->ch_mistat & UART_MSR_DCD) {
		jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev,
			"mistat: %x D_CD: %x\n", ch->ch_mistat, ch->ch_mistat & UART_MSR_DCD);
		phys_carrier = 1;
	}

	if (ch->ch_c_cflag & CLOCAL)
		virt_carrier = 1;

	jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev,
		"DCD: physical: %d virt: %d\n", phys_carrier, virt_carrier);

	/*
	 * Test for a VIRTUAL carrier transition to HIGH.
	 */
	if (((ch->ch_flags & CH_FCAR) == 0) && (virt_carrier == 1)) {

		/*
		 * When carrier rises, wake any threads waiting
		 * for carrier in the open routine.
		 */

		jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev,
			"carrier: virt DCD rose\n");

		if (waitqueue_active(&(ch->ch_flags_wait)))
			wake_up_interruptible(&ch->ch_flags_wait);
	}

	/*
	 * Test for a PHYSICAL carrier transition to HIGH.
	 */
	if (((ch->ch_flags & CH_CD) == 0) && (phys_carrier == 1)) {

		/*
		 * When carrier rises, wake any threads waiting
		 * for carrier in the open routine.
		 */

		jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev,
			"carrier: physical DCD rose\n");

		if (waitqueue_active(&(ch->ch_flags_wait)))
			wake_up_interruptible(&ch->ch_flags_wait);
	}

	/*
	 *  Test for a PHYSICAL transition to low, so long as we aren't
	 *  currently ignoring physical transitions (which is what "virtual
	 *  carrier" indicates).
	 *
	 *  The transition of the virtual carrier to low really doesn't
	 *  matter... it really only means "ignore carrier state", not
	 *  "make pretend that carrier is there".
	 */
	if ((virt_carrier == 0) && ((ch->ch_flags & CH_CD) != 0)
			&& (phys_carrier == 0)) {
		/*
		 *	When carrier drops:
		 *
		 *	Drop carrier on all open units.
		 *
		 *	Flush queues, waking up any task waiting in the
		 *	line discipline.
		 *
		 *	Send a hangup to the control terminal.
		 *
		 *	Enable all select calls.
		 */
		if (waitqueue_active(&(ch->ch_flags_wait)))
			wake_up_interruptible(&ch->ch_flags_wait);
	}

	/*
	 *  Make sure that our cached values reflect the current reality.
	 */
	if (virt_carrier == 1)
		ch->ch_flags |= CH_FCAR;
	else
		ch->ch_flags &= ~CH_FCAR;

	if (phys_carrier == 1)
		ch->ch_flags |= CH_CD;
	else
		ch->ch_flags &= ~CH_CD;
}


void jsm_check_queue_flow_control(struct jsm_channel *ch)
{
	struct board_ops *bd_ops = ch->ch_bd->bd_ops;
	int qleft = 0;

	/* Store how much space we have left in the queue */
	if ((qleft = ch->ch_r_tail - ch->ch_r_head - 1) < 0)
		qleft += RQUEUEMASK + 1;

	/*
	 * Check to see if we should enforce flow control on our queue because
	 * the ld (or user) isn't reading data out of our queue fast enuf.
	 *
	 * NOTE: This is done based on what the current flow control of the
	 * port is set for.
	 *
	 * 1) HWFLOW (RTS) - Turn off the UART's Receive interrupt.
	 *	This will cause the UART's FIFO to back up, and force
	 *	the RTS signal to be dropped.
	 * 2) SWFLOW (IXOFF) - Keep trying to send a stop character to
	 *	the other side, in hopes it will stop sending data to us.
	 * 3) NONE - Nothing we can do.  We will simply drop any extra data
	 *	that gets sent into us when the queue fills up.
	 */
	if (qleft < 256) {
		/* HWFLOW */
		if (ch->ch_c_cflag & CRTSCTS) {
			if(!(ch->ch_flags & CH_RECEIVER_OFF)) {
				bd_ops->disable_receiver(ch);
				ch->ch_flags |= (CH_RECEIVER_OFF);
				jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
					"Internal queue hit hilevel mark (%d)! Turning off interrupts.\n",
					qleft);
			}
		}
		/* SWFLOW */
		else if (ch->ch_c_iflag & IXOFF) {
			if (ch->ch_stops_sent <= MAX_STOPS_SENT) {
				bd_ops->send_stop_character(ch);
				ch->ch_stops_sent++;
				jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
					"Sending stop char! Times sent: %x\n", ch->ch_stops_sent);
			}
		}
	}

	/*
	 * Check to see if we should unenforce flow control because
	 * ld (or user) finally read enuf data out of our queue.
	 *
	 * NOTE: This is done based on what the current flow control of the
	 * port is set for.
	 *
	 * 1) HWFLOW (RTS) - Turn back on the UART's Receive interrupt.
	 *	This will cause the UART's FIFO to raise RTS back up,
	 *	which will allow the other side to start sending data again.
	 * 2) SWFLOW (IXOFF) - Send a start character to
	 *	the other side, so it will start sending data to us again.
	 * 3) NONE - Do nothing. Since we didn't do anything to turn off the
	 *	other side, we don't need to do anything now.
	 */
	if (qleft > (RQUEUESIZE / 2)) {
		/* HWFLOW */
		if (ch->ch_c_cflag & CRTSCTS) {
			if (ch->ch_flags & CH_RECEIVER_OFF) {
				bd_ops->enable_receiver(ch);
				ch->ch_flags &= ~(CH_RECEIVER_OFF);
				jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
					"Internal queue hit lowlevel mark (%d)! Turning on interrupts.\n",
					qleft);
			}
		}
		/* SWFLOW */
		else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) {
			ch->ch_stops_sent = 0;
			bd_ops->send_start_character(ch);
			jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Sending start char!\n");
		}
	}
}

/*
 * jsm_tty_write()
 *
 * Take data from the user or kernel and send it out to the FEP.
 * In here exists all the Transparent Print magic as well.
 */
int jsm_tty_write(struct uart_port *port)
{
	int bufcount = 0, n = 0;
	int data_count = 0,data_count1 =0;
	u16 head;
	u16 tail;
	u16 tmask;
	u32 remain;
	int temp_tail = port->info->xmit.tail;
	struct jsm_channel *channel = (struct jsm_channel *)port;

	tmask = WQUEUEMASK;
	head = (channel->ch_w_head) & tmask;
	tail = (channel->ch_w_tail) & tmask;

	if ((bufcount = tail - head - 1) < 0)
		bufcount += WQUEUESIZE;

	n = bufcount;

	n = min(n, 56);
	remain = WQUEUESIZE - head;

	data_count = 0;
	if (n >= remain) {
		n -= remain;
		while ((port->info->xmit.head != temp_tail) &&
		(data_count < remain)) {
			channel->ch_wqueue[head++] =
			port->info->xmit.buf[temp_tail];

			temp_tail++;
			temp_tail &= (UART_XMIT_SIZE - 1);
			data_count++;
		}
		if (data_count == remain) head = 0;
	}

	data_count1 = 0;
	if (n > 0) {
		remain = n;
		while ((port->info->xmit.head != temp_tail) &&
			(data_count1 < remain)) {
			channel->ch_wqueue[head++] =
				port->info->xmit.buf[temp_tail];

			temp_tail++;
			temp_tail &= (UART_XMIT_SIZE - 1);
			data_count1++;

		}
	}

	port->info->xmit.tail = temp_tail;

	data_count += data_count1;
	if (data_count) {
		head &= tmask;
		channel->ch_w_head = head;
	}

	if (data_count) {
		channel->ch_bd->bd_ops->copy_data_from_queue_to_uart(channel);
	}

	return data_count;
}
