/*
 * pc300_tty.c	Cyclades-PC300(tm) TTY Driver.
 *
 * Author:	Regina Kodato <reginak@cyclades.com>
 *
 * Copyright:	(c) 1999-2002 Cyclades Corp.
 *
 *	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 of the License, or (at your option) any later version.
 *   
 *  $Log: pc300_tty.c,v $
 *  Revision 3.7  2002/03/07 14:17:09  henrique
 *  License data fixed
 *
 *  Revision 3.6  2001/12/10 12:29:42  regina
 *  Fix the MLPPP bug
 *
 *  Revision 3.5  2001/10/31 11:20:05  regina
 *  automatic pppd starts
 *
 *  Revision 3.4  2001/08/06 12:01:51  regina
 *  problem in DSR_DE bit
 *
 *  Revision 3.3  2001/07/26 22:58:41  regina
 *  update EDA value
 *
 *  Revision 3.2  2001/07/12 13:11:20  regina
 *  bug fix - DCD-OFF in pc300 tty driver
 *
 *	DMA transmission bug fix
 *  
 *  Revision 3.1  2001/06/22 13:13:02  regina
 *  MLPPP implementation
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/if.h>
#include <linux/skbuff.h>
/* TTY includes */
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>

#include <asm/io.h>
#include <asm/uaccess.h>

#include "pc300.h"

/* defines and macros */
/* TTY Global definitions */
#define	CPC_TTY_NPORTS	8	/* maximum number of the sync tty connections */
#define	CPC_TTY_MAJOR	CYCLADES_MAJOR	
#define CPC_TTY_MINOR_START	240	/* minor of the first PC300 interface */

#define CPC_TTY_MAX_MTU	2000	

/* tty interface state */
#define	CPC_TTY_ST_IDLE	0
#define CPC_TTY_ST_INIT	1	/* configured with MLPPP and up */
#define CPC_TTY_ST_OPEN	2	/* opened by application */

#define	CPC_TTY_LOCK(card,flags)\
	do {\
		spin_lock_irqsave(&card->card_lock, flags);	\
	} while (0)

#define CPC_TTY_UNLOCK(card,flags)	\
	do {\
		spin_unlock_irqrestore(&card->card_lock, flags);	\
	} while (0)

//#define	CPC_TTY_DBG(format,a...)	printk(format,##a)
#define	CPC_TTY_DBG(format,a...)

/* data structures */
typedef struct _st_cpc_rx_buf {
	struct _st_cpc_rx_buf	*next;
	int		size;
	unsigned char	data[1];
} st_cpc_rx_buf;

struct st_cpc_rx_list {
	st_cpc_rx_buf	*first;
	st_cpc_rx_buf	*last;
};

typedef	struct _st_cpc_tty_area {
	int		state;		/* state of the TTY interface */
	int		num_open;	
	unsigned int 	tty_minor;	/* minor this interface */
	volatile struct st_cpc_rx_list buf_rx;	/* ptr. to reception buffer */
	unsigned char*	buf_tx;		/* ptr. to transmission buffer */
	pc300dev_t*	pc300dev;	/* ptr. to info struct in PC300 driver */
	unsigned char	name[20];	/* interf. name + "-tty" */
	struct tty_struct *tty;		
	struct work_struct tty_tx_work; /* tx work - tx interrupt */
	struct work_struct tty_rx_work; /* rx work - rx interrupt */
	} st_cpc_tty_area;

/* TTY data structures */
static struct tty_driver serial_drv;

/* local variables */
static st_cpc_tty_area	cpc_tty_area[CPC_TTY_NPORTS];

static int cpc_tty_cnt = 0;	/* number of intrfaces configured with MLPPP */
static int cpc_tty_unreg_flag = 0;

/* TTY functions prototype */
static int cpc_tty_open(struct tty_struct *tty, struct file *flip);
static void cpc_tty_close(struct tty_struct *tty, struct file *flip);
static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count);
static int cpc_tty_write_room(struct tty_struct *tty);
static int cpc_tty_chars_in_buffer(struct tty_struct *tty);
static void cpc_tty_flush_buffer(struct tty_struct *tty);
static void cpc_tty_hangup(struct tty_struct *tty);
static void cpc_tty_rx_work(struct work_struct *work);
static void cpc_tty_tx_work(struct work_struct *work);
static int cpc_tty_send_to_card(pc300dev_t *dev,void *buf, int len);
static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx);
static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char);
static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char);

static int pc300_tiocmset(struct tty_struct *, struct file *,
			  unsigned int, unsigned int);
static int pc300_tiocmget(struct tty_struct *, struct file *);

/* functions called by PC300 driver */
void cpc_tty_init(pc300dev_t *dev);
void cpc_tty_unregister_service(pc300dev_t *pc300dev);
void cpc_tty_receive(pc300dev_t *pc300dev);
void cpc_tty_trigger_poll(pc300dev_t *pc300dev);
void cpc_tty_reset_var(void);

/*
 * PC300 TTY clear "signal"
 */
static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char signal)
{
	pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; 
	pc300_t *card = (pc300_t *) pc300chan->card; 
	int ch = pc300chan->channel; 
	unsigned long flags; 

	CPC_TTY_DBG("%s-tty: Clear signal %x\n",
		pc300dev->dev->name, signal);
	CPC_TTY_LOCK(card, flags); 
	cpc_writeb(card->hw.scabase + M_REG(CTL,ch), 
		cpc_readb(card->hw.scabase+M_REG(CTL,ch))& signal);
	CPC_TTY_UNLOCK(card,flags); 
}

/*
 * PC300 TTY set "signal" to ON
 */
static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char signal)
{
	pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; 
	pc300_t *card = (pc300_t *) pc300chan->card; 
	int ch = pc300chan->channel; 
	unsigned long flags; 

	CPC_TTY_DBG("%s-tty: Set signal %x\n",
		pc300dev->dev->name, signal);
	CPC_TTY_LOCK(card, flags); 
	cpc_writeb(card->hw.scabase + M_REG(CTL,ch), 
		cpc_readb(card->hw.scabase+M_REG(CTL,ch))& ~signal);
	CPC_TTY_UNLOCK(card,flags); 
}

/*
 * PC300 TTY initialization routine
 *
 * This routine is called by the PC300 driver during board configuration 
 * (ioctl=SIOCSP300CONF). At this point the adapter is completely
 * initialized.
 * o verify kernel version (only 2.4.x)
 * o register TTY driver
 * o init cpc_tty_area struct
 */
void cpc_tty_init(pc300dev_t *pc300dev)
{
	unsigned long port;
	int aux;
	st_cpc_tty_area * cpc_tty;

	/* hdlcX - X=interface number */
	port = pc300dev->dev->name[4] - '0';
	if (port >= CPC_TTY_NPORTS) {
		printk("%s-tty: invalid interface selected (0-%i): %li",
			pc300dev->dev->name,
			CPC_TTY_NPORTS-1,port);
		return;
	}

	if (cpc_tty_cnt == 0) { /* first TTY connection -> register driver */
		CPC_TTY_DBG("%s-tty: driver init, major:%i, minor range:%i=%i\n",
			pc300dev->dev->name,
			CPC_TTY_MAJOR, CPC_TTY_MINOR_START,
			CPC_TTY_MINOR_START+CPC_TTY_NPORTS);
		/* initialize tty driver struct */
		memset(&serial_drv,0,sizeof(struct tty_driver));
		serial_drv.magic = TTY_DRIVER_MAGIC;
		serial_drv.owner = THIS_MODULE;
		serial_drv.driver_name = "pc300_tty";
		serial_drv.name = "ttyCP";
		serial_drv.major = CPC_TTY_MAJOR;
		serial_drv.minor_start = CPC_TTY_MINOR_START;
		serial_drv.num = CPC_TTY_NPORTS;
		serial_drv.type = TTY_DRIVER_TYPE_SERIAL;
		serial_drv.subtype = SERIAL_TYPE_NORMAL;

		serial_drv.init_termios = tty_std_termios;
		serial_drv.init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
		serial_drv.flags = TTY_DRIVER_REAL_RAW;

		/* interface routines from the upper tty layer to the tty driver */
		serial_drv.open = cpc_tty_open;
		serial_drv.close = cpc_tty_close;
		serial_drv.write = cpc_tty_write; 
		serial_drv.write_room = cpc_tty_write_room; 
		serial_drv.chars_in_buffer = cpc_tty_chars_in_buffer; 
		serial_drv.tiocmset = pc300_tiocmset;
		serial_drv.tiocmget = pc300_tiocmget;
		serial_drv.flush_buffer = cpc_tty_flush_buffer; 
		serial_drv.hangup = cpc_tty_hangup;

		/* register the TTY driver */
		if (tty_register_driver(&serial_drv)) { 
			printk("%s-tty: Failed to register serial driver! ",
				pc300dev->dev->name);
		   	return;
		} 

		memset((void *)cpc_tty_area, 0,
								sizeof(st_cpc_tty_area) * CPC_TTY_NPORTS);
	}

	cpc_tty = &cpc_tty_area[port];
	
	if (cpc_tty->state != CPC_TTY_ST_IDLE) {
		CPC_TTY_DBG("%s-tty: TTY port %i, already in use.\n",
				pc300dev->dev->name, port);
		return;
	}

	cpc_tty_cnt++;
	cpc_tty->state = CPC_TTY_ST_INIT; 
	cpc_tty->num_open= 0;
	cpc_tty->tty_minor = port + CPC_TTY_MINOR_START;
	cpc_tty->pc300dev = pc300dev; 

	INIT_WORK(&cpc_tty->tty_tx_work, cpc_tty_tx_work);
	INIT_WORK(&cpc_tty->tty_rx_work, cpc_tty_rx_work);
	
	cpc_tty->buf_rx.first = cpc_tty->buf_rx.last = NULL;

	pc300dev->cpc_tty = (void *)cpc_tty; 
	
	aux = strlen(pc300dev->dev->name);
	memcpy(cpc_tty->name, pc300dev->dev->name, aux);
	memcpy(&cpc_tty->name[aux], "-tty", 5);
	
	cpc_open(pc300dev->dev);
	cpc_tty_signal_off(pc300dev, CTL_DTR);

	CPC_TTY_DBG("%s: Initializing TTY Sync Driver, tty major#%d minor#%i\n",
			cpc_tty->name,CPC_TTY_MAJOR,cpc_tty->tty_minor); 
	return; 
} 

/*
 * PC300 TTY OPEN routine
 *
 * This routine is called by the tty driver to open the interface 
 * o verify minor
 * o allocate buffer to Rx and Tx
 */
static int cpc_tty_open(struct tty_struct *tty, struct file *flip)
{
	int port ;
	st_cpc_tty_area *cpc_tty;

	if (!tty) { 
		return -ENODEV;
	} 

	port = tty->index;

	if ((port < 0) || (port >= CPC_TTY_NPORTS)){ 
		CPC_TTY_DBG("pc300_tty: open invalid port %d\n", port);
		return -ENODEV;
	} 

	cpc_tty = &cpc_tty_area[port];
	
	if (cpc_tty->state == CPC_TTY_ST_IDLE){
		CPC_TTY_DBG("%s: open - invalid interface, port=%d\n",
					cpc_tty->name, tty->index);
		return -ENODEV;
	}

	if (cpc_tty->num_open == 0) { /* first open of this tty */
		if (!cpc_tty_area[port].buf_tx){
			cpc_tty_area[port].buf_tx = kmalloc(CPC_TTY_MAX_MTU,GFP_KERNEL);
			if (cpc_tty_area[port].buf_tx == 0){
				CPC_TTY_DBG("%s: error in memory allocation\n",cpc_tty->name);
				return -ENOMEM;
			}
		} 

		if (cpc_tty_area[port].buf_rx.first) {
			unsigned char * aux;
			while (cpc_tty_area[port].buf_rx.first) {
				aux = (unsigned char *)cpc_tty_area[port].buf_rx.first;
				cpc_tty_area[port].buf_rx.first = cpc_tty_area[port].buf_rx.first->next;
				kfree(aux);
			}
			cpc_tty_area[port].buf_rx.first = NULL;
			cpc_tty_area[port].buf_rx.last = NULL;
		}

		cpc_tty_area[port].state = CPC_TTY_ST_OPEN;
		cpc_tty_area[port].tty = tty;
		tty->driver_data = &cpc_tty_area[port];

		cpc_tty_signal_on(cpc_tty->pc300dev, CTL_DTR);
	} 

	cpc_tty->num_open++;

	CPC_TTY_DBG("%s: opening TTY driver\n", cpc_tty->name);
	
	/* avisar driver PC300 */ 
	return 0; 
}

/*
 * PC300 TTY CLOSE routine
 *
 * This routine is called by the tty driver to close the interface 
 * o call close channel in PC300 driver (cpc_closech)
 * o free Rx and Tx buffers
 */

static void cpc_tty_close(struct tty_struct *tty, struct file *flip)
{
	st_cpc_tty_area    *cpc_tty;
	unsigned long flags;
	int res;

	if (!tty || !tty->driver_data ) {
		CPC_TTY_DBG("hdlx-tty: no TTY in close \n");
		return;
	}

	cpc_tty = (st_cpc_tty_area *) tty->driver_data;

	if ((cpc_tty->tty != tty)|| (cpc_tty->state != CPC_TTY_ST_OPEN)) {
		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
		return;
	}
   	
	if (!cpc_tty->num_open) {
		CPC_TTY_DBG("%s: TTY is closed\n",cpc_tty->name);
		return;
	}

	if (--cpc_tty->num_open > 0) {
		CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name);
		return;
	}

	cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR);

	CPC_TTY_LOCK(cpc_tty->pc300dev->chan->card, flags);  /* lock irq */ 
	cpc_tty->tty = NULL;
	cpc_tty->state = CPC_TTY_ST_INIT;
	CPC_TTY_UNLOCK(cpc_tty->pc300dev->chan->card, flags); /* unlock irq */ 
	
	if (cpc_tty->buf_rx.first) {
		unsigned char * aux;
		while (cpc_tty->buf_rx.first) {
			aux = (unsigned char *)cpc_tty->buf_rx.first;
			cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next;
			kfree(aux);
		}
		cpc_tty->buf_rx.first = NULL;
		cpc_tty->buf_rx.last = NULL;
	}
	
	kfree(cpc_tty->buf_tx);
	cpc_tty->buf_tx = NULL;

	CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name);
	
	if (!serial_drv.refcount && cpc_tty_unreg_flag) {
		cpc_tty_unreg_flag = 0;
		CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name);
		if ((res=tty_unregister_driver(&serial_drv))) { 
			CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
							cpc_tty->name,res);
		}
	}
	return; 
} 

/*
 * PC300 TTY WRITE routine
 *
 * This routine is called by the tty driver to write a series of characters
 * to the tty device. The characters may come from user or kernel space.
 * o verify the DCD signal
 * o send characters to board and start the transmission
 */
static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
	st_cpc_tty_area    *cpc_tty; 
	pc300ch_t *pc300chan; 
	pc300_t *card; 
	int ch; 
	unsigned long flags; 
	struct net_device_stats *stats; 

	if (!tty || !tty->driver_data ) { 
		CPC_TTY_DBG("hdlcX-tty: no TTY in write\n");
		return -ENODEV;
	} 

	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 

	if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
		CPC_TTY_DBG("%s: TTY is not opened\n", cpc_tty->name);
		return -ENODEV; 
	}

	if (count > CPC_TTY_MAX_MTU) { 
		CPC_TTY_DBG("%s: count is invalid\n",cpc_tty->name);
		return -EINVAL;        /* frame too big */ 
	}

	CPC_TTY_DBG("%s: cpc_tty_write data len=%i\n",cpc_tty->name,count);
	
	pc300chan = (pc300ch_t *)((pc300dev_t*)cpc_tty->pc300dev)->chan; 
	stats = hdlc_stats(((pc300dev_t*)cpc_tty->pc300dev)->dev);
	card = (pc300_t *) pc300chan->card;
	ch = pc300chan->channel; 

	/* verify DCD signal*/ 
	if (cpc_readb(card->hw.scabase + M_REG(ST3,ch)) & ST3_DCD) { 
		/* DCD is OFF */ 
		CPC_TTY_DBG("%s : DCD is OFF\n", cpc_tty->name);
		stats->tx_errors++;
		stats->tx_carrier_errors++;
		CPC_TTY_LOCK(card, flags); 
		cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR); 
		
		if (card->hw.type == PC300_TE) { 
			cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, 
				cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & 
				~(CPLD_REG2_FALC_LED1 << (2 *ch))); 
		}

		CPC_TTY_UNLOCK(card, flags); 

		return -EINVAL; 
	}

	if (cpc_tty_send_to_card(cpc_tty->pc300dev, (void*)buf, count)) { 
	   /* failed to send */
	   CPC_TTY_DBG("%s: trasmition error\n", cpc_tty->name);
	   return 0;
	}
	return count; 
} 

/*
 * PC300 TTY Write Room routine
 * 
 * This routine returns the numbers of characteres the tty driver will accept
 * for queuing to be written. 
 * o return MTU
 */
static int cpc_tty_write_room(struct tty_struct *tty)
{
	st_cpc_tty_area    *cpc_tty; 

	if (!tty || !tty->driver_data ) { 
		CPC_TTY_DBG("hdlcX-tty: no TTY to write room\n");
		return -ENODEV;
	}

	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 

	if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
		return -ENODEV; 
	}
   	
	CPC_TTY_DBG("%s: write room\n",cpc_tty->name);
	
	return CPC_TTY_MAX_MTU;
} 

/*
 * PC300 TTY chars in buffer routine
 * 
 * This routine returns the chars number in the transmission buffer 
 * o returns 0
 */
static int cpc_tty_chars_in_buffer(struct tty_struct *tty)
{
	st_cpc_tty_area    *cpc_tty; 

	if (!tty || !tty->driver_data ) {
		CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n");
		return -ENODEV; 
	}

	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 

	if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
		return -ENODEV; 
	}
   
	return(0); 
} 

static int pc300_tiocmset(struct tty_struct *tty, struct file *file,
			  unsigned int set, unsigned int clear)
{
	st_cpc_tty_area    *cpc_tty; 

	CPC_TTY_DBG("%s: set:%x clear:%x\n", __FUNCTION__, set, clear);

	if (!tty || !tty->driver_data ) {
	   	CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n");	
		return -ENODEV; 
	}

	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 

	if (set & TIOCM_RTS)
		cpc_tty_signal_on(cpc_tty->pc300dev, CTL_RTS);
	if (set & TIOCM_DTR)
		cpc_tty_signal_on(cpc_tty->pc300dev, CTL_DTR);

	if (clear & TIOCM_RTS)
		cpc_tty_signal_off(cpc_tty->pc300dev, CTL_RTS);
	if (clear & TIOCM_DTR)
		cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR);

	return 0;
}

static int pc300_tiocmget(struct tty_struct *tty, struct file *file)
{
	unsigned int result;
	unsigned char status;
	unsigned long flags;
	st_cpc_tty_area  *cpc_tty = (st_cpc_tty_area *) tty->driver_data;
	pc300dev_t *pc300dev = cpc_tty->pc300dev;
	pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan;
	pc300_t *card = (pc300_t *) pc300chan->card;
	int ch = pc300chan->channel;

	cpc_tty = (st_cpc_tty_area *) tty->driver_data;

	CPC_TTY_DBG("%s-tty: tiocmget\n",
		((struct net_device*)(pc300dev->hdlc))->name);

	CPC_TTY_LOCK(card, flags);
	status = cpc_readb(card->hw.scabase+M_REG(CTL,ch));
	CPC_TTY_UNLOCK(card,flags);

	result = ((status & CTL_DTR) ? TIOCM_DTR : 0) |
		 ((status & CTL_RTS) ? TIOCM_RTS : 0);

	return result;
}

/*
 * PC300 TTY Flush Buffer routine
 *
 * This routine resets the transmission buffer 
 */
static void cpc_tty_flush_buffer(struct tty_struct *tty)
{ 
	st_cpc_tty_area    *cpc_tty; 
	
	if (!tty || !tty->driver_data ) {
	   	CPC_TTY_DBG("hdlcX-tty: no TTY to flush buffer\n");	
		return; 
	}

	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 

	if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
		return; 
	}

	CPC_TTY_DBG("%s: call wake_up_interruptible\n",cpc_tty->name);

	tty_wakeup(tty);	
	return; 
} 

/*
 * PC300 TTY Hangup routine
 *
 * This routine is called by the tty driver to hangup the interface 
 * o clear DTR signal
 */

static void cpc_tty_hangup(struct tty_struct *tty)
{ 
	st_cpc_tty_area    *cpc_tty; 
	int res;

	if (!tty || !tty->driver_data ) {
		CPC_TTY_DBG("hdlcX-tty: no TTY to hangup\n");	
		return ; 
	}

	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 

	if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) {
		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
		return ;
	}
	if (!serial_drv.refcount && cpc_tty_unreg_flag) {
		cpc_tty_unreg_flag = 0;
		CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name);
		if ((res=tty_unregister_driver(&serial_drv))) { 
			CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
							cpc_tty->name,res);
		}
	}
	cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR);
}

/*
 * PC300 TTY RX work routine
 * This routine treats RX work
 * o verify read buffer
 * o call the line disc. read
 * o free memory
 */
static void cpc_tty_rx_work(struct work_struct *work)
{
	st_cpc_tty_area *cpc_tty;
	unsigned long port;
	int i, j;
	volatile st_cpc_rx_buf *buf;
	char flags=0,flg_rx=1; 
	struct tty_ldisc *ld;

	if (cpc_tty_cnt == 0) return;
	
	for (i=0; (i < 4) && flg_rx ; i++) {
		flg_rx = 0;

		cpc_tty = container_of(work, st_cpc_tty_area, tty_rx_work);
		port = cpc_tty - cpc_tty_area;

		for (j=0; j < CPC_TTY_NPORTS; j++) {
			cpc_tty = &cpc_tty_area[port];
		
			if ((buf=cpc_tty->buf_rx.first) != 0) {
				if (cpc_tty->tty) {
					ld = tty_ldisc_ref(cpc_tty->tty);
					if (ld) {
						if (ld->receive_buf) {
							CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name);
							ld->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size);
						}
						tty_ldisc_deref(ld);
					}
				}	
				cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next;
				kfree((void *)buf);
				buf = cpc_tty->buf_rx.first;
				flg_rx = 1;
			}
			if (++port == CPC_TTY_NPORTS) port = 0;
		}
	}
} 

/*
 * PC300 TTY RX work routine
 *
 * This routine treats RX interrupt. 
 * o read all frames in card
 * o verify the frame size
 * o read the frame in rx buffer
 */
static void cpc_tty_rx_disc_frame(pc300ch_t *pc300chan)
{
	volatile pcsca_bd_t __iomem * ptdescr; 
	volatile unsigned char status; 
	pc300_t *card = (pc300_t *)pc300chan->card; 
	int ch = pc300chan->channel; 

	/* dma buf read */ 
	ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
				RX_BD_ADDR(ch, pc300chan->rx_first_bd)); 
	while (pc300chan->rx_first_bd != pc300chan->rx_last_bd) { 
		status = cpc_readb(&ptdescr->status); 
		cpc_writeb(&ptdescr->status, 0); 
		cpc_writeb(&ptdescr->len, 0); 
		pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & 
					(N_DMA_RX_BUF - 1); 
		if (status & DST_EOM) { 
			break; /* end of message */
		}
		ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + cpc_readl(&ptdescr->next)); 
	}
}

void cpc_tty_receive(pc300dev_t *pc300dev)
{
	st_cpc_tty_area *cpc_tty; 
	pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; 
	pc300_t *card = (pc300_t *)pc300chan->card; 
	int ch = pc300chan->channel; 
	volatile pcsca_bd_t  __iomem * ptdescr; 
	struct net_device_stats *stats = hdlc_stats(pc300dev->dev);
	int rx_len, rx_aux; 
	volatile unsigned char status; 
	unsigned short first_bd = pc300chan->rx_first_bd;
	st_cpc_rx_buf *new = NULL;
	unsigned char dsr_rx;

	if (pc300dev->cpc_tty == NULL) { 
		return; 
	}

	dsr_rx = cpc_readb(card->hw.scabase + DSR_RX(ch));

	cpc_tty = (st_cpc_tty_area *)pc300dev->cpc_tty; 

	while (1) { 
		rx_len = 0;
		ptdescr = (pcsca_bd_t  __iomem *)(card->hw.rambase + RX_BD_ADDR(ch, first_bd));
		while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
			rx_len += cpc_readw(&ptdescr->len);
			first_bd = (first_bd + 1) & (N_DMA_RX_BUF - 1);
			if (status & DST_EOM) {
				break;
			}
			ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase+cpc_readl(&ptdescr->next));
		}
			
		if (!rx_len) { 
			if (dsr_rx & DSR_BOF) {
				/* update EDA */ 
				cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), 
						RX_BD_ADDR(ch, pc300chan->rx_last_bd)); 
			}
			kfree(new);
			return; 
		}
		
		if (rx_len > CPC_TTY_MAX_MTU) { 
			/* Free RX descriptors */ 
			CPC_TTY_DBG("%s: frame size is invalid.\n",cpc_tty->name);
			stats->rx_errors++; 
			stats->rx_frame_errors++; 
			cpc_tty_rx_disc_frame(pc300chan);
			continue;
		} 
		
		new = kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC);
		if (new == 0) {
			cpc_tty_rx_disc_frame(pc300chan);
			continue;
		}
		
		/* dma buf read */ 
		ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
				RX_BD_ADDR(ch, pc300chan->rx_first_bd)); 

		rx_len = 0;	/* counter frame size */
		
		while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
			rx_aux = cpc_readw(&ptdescr->len);
			if ((status & (DST_OVR | DST_CRC | DST_RBIT |  DST_SHRT | DST_ABT))
				|| (rx_aux > BD_DEF_LEN)) {
				CPC_TTY_DBG("%s: reception error\n", cpc_tty->name);
				stats->rx_errors++; 
				if (status & DST_OVR) { 
					stats->rx_fifo_errors++; 
				}
				if (status & DST_CRC) { 
					stats->rx_crc_errors++; 
				}
				if ((status & (DST_RBIT | DST_SHRT | DST_ABT)) ||
					(rx_aux > BD_DEF_LEN))	{ 
					stats->rx_frame_errors++; 
				} 
				/* discard remainig descriptors used by the bad frame */ 
				CPC_TTY_DBG("%s: reception error - discard descriptors",
						cpc_tty->name);
				cpc_tty_rx_disc_frame(pc300chan);
				rx_len = 0;
				kfree(new);
				new = NULL;
				break; /* read next frame - while(1) */
			}

			if (cpc_tty->state != CPC_TTY_ST_OPEN) {
				/* Free RX descriptors */ 
				cpc_tty_rx_disc_frame(pc300chan);
				stats->rx_dropped++; 
				rx_len = 0; 
				kfree(new);
				new = NULL;
				break; /* read next frame - while(1) */
			}

			/* read the segment of the frame */
			if (rx_aux != 0) {
				memcpy_fromio((new->data + rx_len), 
					(void __iomem *)(card->hw.rambase + 
					 cpc_readl(&ptdescr->ptbuf)), rx_aux);
				rx_len += rx_aux; 
			}
			cpc_writeb(&ptdescr->status,0); 
			cpc_writeb(&ptdescr->len, 0); 
			pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & 
					(N_DMA_RX_BUF -1); 
			if (status & DST_EOM)break;
			
			ptdescr = (pcsca_bd_t __iomem *) (card->hw.rambase + 
					cpc_readl(&ptdescr->next)); 
		}
		/* update pointer */ 
		pc300chan->rx_last_bd = (pc300chan->rx_first_bd - 1) & 
					(N_DMA_RX_BUF - 1) ; 
		if (!(dsr_rx & DSR_BOF)) {
			/* update EDA */ 
			cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), 
					RX_BD_ADDR(ch, pc300chan->rx_last_bd)); 
		}
		if (rx_len != 0) { 
			stats->rx_bytes += rx_len; 
		
			if (pc300dev->trace_on) { 
				cpc_tty_trace(pc300dev, new->data,rx_len, 'R'); 
			} 
			new->size = rx_len;
			new->next = NULL;
			if (cpc_tty->buf_rx.first == 0) {
				cpc_tty->buf_rx.first = new;
				cpc_tty->buf_rx.last = new;
			} else {
				cpc_tty->buf_rx.last->next = new;
				cpc_tty->buf_rx.last = new;
			}
			schedule_work(&(cpc_tty->tty_rx_work));
			stats->rx_packets++;
		}
	} 
} 

/*
 * PC300 TTY TX work routine
 * 
 * This routine treats TX interrupt. 
 * o if need call line discipline wakeup
 * o call wake_up_interruptible
 */
static void cpc_tty_tx_work(struct work_struct *work)
{
	st_cpc_tty_area *cpc_tty =
		container_of(work, st_cpc_tty_area, tty_tx_work);
	struct tty_struct *tty; 

	CPC_TTY_DBG("%s: cpc_tty_tx_work init\n",cpc_tty->name);
	
	if ((tty = cpc_tty->tty) == 0) { 
		CPC_TTY_DBG("%s: the interface is not opened\n",cpc_tty->name);
		return; 
	}
	tty_wakeup(tty);
}

/*
 * PC300 TTY send to card routine
 * 
 * This routine send data to card. 
 * o clear descriptors
 * o write data to DMA buffers
 * o start the transmission
 */
static int cpc_tty_send_to_card(pc300dev_t *dev,void* buf, int len)
{
	pc300ch_t *chan = (pc300ch_t *)dev->chan; 
	pc300_t *card = (pc300_t *)chan->card; 
	int ch = chan->channel; 
	struct net_device_stats *stats = hdlc_stats(dev->dev);
	unsigned long flags; 
	volatile pcsca_bd_t __iomem *ptdescr; 
	int i, nchar;
	int tosend = len;
	int nbuf = ((len - 1)/BD_DEF_LEN) + 1;
	unsigned char *pdata=buf;

	CPC_TTY_DBG("%s:cpc_tty_send_to_cars len=%i", 
			(st_cpc_tty_area *)dev->cpc_tty->name,len);	

	if (nbuf >= card->chan[ch].nfree_tx_bd) {
		return 1;
	}
	
	/* write buffer to DMA buffers */ 
	CPC_TTY_DBG("%s: call dma_buf_write\n",
			(st_cpc_tty_area *)dev->cpc_tty->name);	
	for (i = 0 ; i < nbuf ; i++) {
		ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
			TX_BD_ADDR(ch, card->chan[ch].tx_next_bd));
		nchar = (BD_DEF_LEN > tosend) ? tosend : BD_DEF_LEN;
		if (cpc_readb(&ptdescr->status) & DST_OSB) {
			memcpy_toio((void __iomem *)(card->hw.rambase + 
				cpc_readl(&ptdescr->ptbuf)), 
				&pdata[len - tosend], 
				nchar);
			card->chan[ch].nfree_tx_bd--;
			if ((i + 1) == nbuf) {
				/* This must be the last BD to be used */
				cpc_writeb(&ptdescr->status, DST_EOM);
			} else {
				cpc_writeb(&ptdescr->status, 0);
			}
			cpc_writew(&ptdescr->len, nchar);
		} else {
			CPC_TTY_DBG("%s: error in dma_buf_write\n",
					(st_cpc_tty_area *)dev->cpc_tty->name);	
			stats->tx_dropped++;
			return 1; 
		}
		tosend -= nchar;
		card->chan[ch].tx_next_bd = 
			(card->chan[ch].tx_next_bd + 1) & (N_DMA_TX_BUF - 1);
	}

	if (dev->trace_on) { 
		cpc_tty_trace(dev, buf, len,'T'); 
	}

	/* start transmission */ 
	CPC_TTY_DBG("%s: start transmission\n",
		(st_cpc_tty_area *)dev->cpc_tty->name);	
	
	CPC_TTY_LOCK(card, flags); 
	cpc_writeb(card->hw.scabase + DTX_REG(EDAL, ch), 
			TX_BD_ADDR(ch, chan->tx_next_bd)); 
	cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA); 
	cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE); 

	if (card->hw.type == PC300_TE) { 
		cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, 
			cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) |
			(CPLD_REG2_FALC_LED1 << (2 * ch))); 
	}
	CPC_TTY_UNLOCK(card, flags); 
	return 0; 
} 

/*
 *	PC300 TTY trace routine
 *
 *  This routine send trace of connection to application. 
 *  o clear descriptors
 *  o write data to DMA buffers
 *  o start the transmission
 */

static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx)
{
	struct sk_buff *skb; 

	if ((skb = dev_alloc_skb(10 + len)) == NULL) { 
		/* out of memory */ 
		CPC_TTY_DBG("%s: tty_trace - out of memory\n", dev->dev->name);
		return; 
	}

	skb_put (skb, 10 + len); 
	skb->dev = dev->dev; 
	skb->protocol = htons(ETH_P_CUST); 
	skb_reset_mac_header(skb);
	skb->pkt_type = PACKET_HOST; 
	skb->len = 10 + len; 

	skb_copy_to_linear_data(skb, dev->dev->name, 5);
	skb->data[5] = '['; 
	skb->data[6] = rxtx; 
	skb->data[7] = ']'; 
	skb->data[8] = ':'; 
	skb->data[9] = ' '; 
	skb_copy_to_linear_data_offset(skb, 10, buf, len);
	netif_rx(skb); 
} 	

/*
 *	PC300 TTY unregister service routine
 *
 *	This routine unregister one interface. 
 */
void cpc_tty_unregister_service(pc300dev_t *pc300dev)
{
	st_cpc_tty_area *cpc_tty; 
	ulong flags;
	int res;

	if ((cpc_tty= (st_cpc_tty_area *) pc300dev->cpc_tty) == 0) { 
		CPC_TTY_DBG("%s: interface is not TTY\n", pc300dev->dev->name);
		return; 
	}
	CPC_TTY_DBG("%s: cpc_tty_unregister_service", cpc_tty->name);

	if (cpc_tty->pc300dev != pc300dev) { 
		CPC_TTY_DBG("%s: invalid tty ptr=%s\n", 
		pc300dev->dev->name, cpc_tty->name);
		return; 
	}

	if (--cpc_tty_cnt == 0) { 
		if (serial_drv.refcount) {
			CPC_TTY_DBG("%s: unregister is not possible, refcount=%d",
							cpc_tty->name, serial_drv.refcount);
			cpc_tty_cnt++;
			cpc_tty_unreg_flag = 1;
			return;
		} else { 
			CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name);
			if ((res=tty_unregister_driver(&serial_drv))) { 
				CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
								cpc_tty->name,res);
			}
		}
	}
	CPC_TTY_LOCK(pc300dev->chan->card,flags);
	cpc_tty->tty = NULL; 
	CPC_TTY_UNLOCK(pc300dev->chan->card, flags);
	cpc_tty->tty_minor = 0; 
	cpc_tty->state = CPC_TTY_ST_IDLE; 
} 

/*
 * PC300 TTY trigger poll routine
 * This routine is called by pc300driver to treats Tx interrupt. 
 */
void cpc_tty_trigger_poll(pc300dev_t *pc300dev)
{
	st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *)pc300dev->cpc_tty; 
	if (!cpc_tty) {
		return;
	}
	schedule_work(&(cpc_tty->tty_tx_work)); 
} 

/*
 * PC300 TTY reset var routine
 * This routine is called by pc300driver to init the TTY area. 
 */

void cpc_tty_reset_var(void)
{
	int i ; 

	CPC_TTY_DBG("hdlcX-tty: reset variables\n");
	/* reset  the tty_driver structure - serial_drv */ 
	memset(&serial_drv, 0, sizeof(struct tty_driver));
	for (i=0; i < CPC_TTY_NPORTS; i++){
		memset(&cpc_tty_area[i],0, sizeof(st_cpc_tty_area)); 
	}
}
