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


static const struct tty_operations pc300_ops = {
	.open = cpc_tty_open,
	.close = cpc_tty_close,
	.write = cpc_tty_write,
	.write_room = cpc_tty_write_room,
	.chars_in_buffer = cpc_tty_chars_in_buffer,
	.tiocmset = pc300_tiocmset,
	.tiocmget = pc300_tiocmget,
	.flush_buffer = cpc_tty_flush_buffer,
	.hangup = cpc_tty_hangup,
};


/*
 * 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 */
		tty_set_operations(&serial_drv, &pc300_ops);

		/* 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) {
				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 = &cpc_tty->pc300dev->dev->stats;
	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) != NULL) {
				if (cpc_tty->tty) {
					ld = tty_ldisc_ref(cpc_tty->tty);
					if (ld) {
						if (ld->ops->receive_buf) {
							CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name);
							ld->ops->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 = &pc300dev->dev->stats;
	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) {
			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 == NULL) {
				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) == NULL) { 
		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 = &dev->dev->stats;
	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) == NULL) {
		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)); 
	}
}
