Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
   1/*
   2 * pc300_tty.c	Cyclades-PC300(tm) TTY Driver.
   3 *
   4 * Author:	Regina Kodato <reginak@cyclades.com>
   5 *
   6 * Copyright:	(c) 1999-2002 Cyclades Corp.
   7 *
   8 *	This program is free software; you can redistribute it and/or
   9 *  modify it under the terms of the GNU General Public License
  10 *  as published by the Free Software Foundation; either version
  11 *  2 of the License, or (at your option) any later version.
  12 *   
  13 *  $Log: pc300_tty.c,v $
  14 *  Revision 3.7  2002/03/07 14:17:09  henrique
  15 *  License data fixed
  16 *
  17 *  Revision 3.6  2001/12/10 12:29:42  regina
  18 *  Fix the MLPPP bug
  19 *
  20 *  Revision 3.5  2001/10/31 11:20:05  regina
  21 *  automatic pppd starts
  22 *
  23 *  Revision 3.4  2001/08/06 12:01:51  regina
  24 *  problem in DSR_DE bit
  25 *
  26 *  Revision 3.3  2001/07/26 22:58:41  regina
  27 *  update EDA value
  28 *
  29 *  Revision 3.2  2001/07/12 13:11:20  regina
  30 *  bug fix - DCD-OFF in pc300 tty driver
  31 *
  32 *	DMA transmission bug fix
  33 *  
  34 *  Revision 3.1  2001/06/22 13:13:02  regina
  35 *  MLPPP implementation
  36 *
  37 */
  38
  39#include <linux/module.h>
  40#include <linux/kernel.h>
  41#include <linux/errno.h>
  42#include <linux/string.h>
  43#include <linux/init.h>
  44#include <linux/netdevice.h>
  45#include <linux/spinlock.h>
  46#include <linux/slab.h>
  47#include <linux/if.h>
  48#include <linux/skbuff.h>
  49/* TTY includes */
  50#include <linux/tty.h>
  51#include <linux/tty_flip.h>
  52#include <linux/serial.h>
  53
  54#include <asm/io.h>
  55#include <asm/uaccess.h>
  56
  57#include "pc300.h"
  58
  59/* defines and macros */
  60/* TTY Global definitions */
  61#define	CPC_TTY_NPORTS	8	/* maximum number of the sync tty connections */
  62#define	CPC_TTY_MAJOR	CYCLADES_MAJOR	
  63#define CPC_TTY_MINOR_START	240	/* minor of the first PC300 interface */
  64
  65#define CPC_TTY_MAX_MTU	2000	
  66
  67/* tty interface state */
  68#define	CPC_TTY_ST_IDLE	0
  69#define CPC_TTY_ST_INIT	1	/* configured with MLPPP and up */
  70#define CPC_TTY_ST_OPEN	2	/* opened by application */
  71
  72#define	CPC_TTY_LOCK(card,flags)\
  73	do {\
  74		spin_lock_irqsave(&card->card_lock, flags);	\
  75	} while (0)
  76
  77#define CPC_TTY_UNLOCK(card,flags)	\
  78	do {\
  79		spin_unlock_irqrestore(&card->card_lock, flags);	\
  80	} while (0)
  81
  82//#define	CPC_TTY_DBG(format,a...)	printk(format,##a)
  83#define	CPC_TTY_DBG(format,a...)
  84
  85/* data structures */
  86typedef struct _st_cpc_rx_buf {
  87	struct _st_cpc_rx_buf	*next;
  88	int		size;
  89	unsigned char	data[1];
  90} st_cpc_rx_buf;
  91
  92struct st_cpc_rx_list {
  93	st_cpc_rx_buf	*first;
  94	st_cpc_rx_buf	*last;
  95};
  96
  97typedef	struct _st_cpc_tty_area {
  98	int		state;		/* state of the TTY interface */
  99	int		num_open;	
 100	unsigned int 	tty_minor;	/* minor this interface */
 101	volatile struct st_cpc_rx_list buf_rx;	/* ptr. to reception buffer */
 102	unsigned char*	buf_tx;		/* ptr. to transmission buffer */
 103	pc300dev_t*	pc300dev;	/* ptr. to info struct in PC300 driver */
 104	unsigned char	name[20];	/* interf. name + "-tty" */
 105	struct tty_struct *tty;		
 106	struct work_struct tty_tx_work; /* tx work - tx interrupt */
 107	struct work_struct tty_rx_work; /* rx work - rx interrupt */
 108	} st_cpc_tty_area;
 109
 110/* TTY data structures */
 111static struct tty_driver serial_drv;
 112
 113/* local variables */
 114static st_cpc_tty_area	cpc_tty_area[CPC_TTY_NPORTS];
 115
 116static int cpc_tty_cnt = 0;	/* number of intrfaces configured with MLPPP */
 117static int cpc_tty_unreg_flag = 0;
 118
 119/* TTY functions prototype */
 120static int cpc_tty_open(struct tty_struct *tty, struct file *flip);
 121static void cpc_tty_close(struct tty_struct *tty, struct file *flip);
 122static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count);
 123static int cpc_tty_write_room(struct tty_struct *tty);
 124static int cpc_tty_chars_in_buffer(struct tty_struct *tty);
 125static void cpc_tty_flush_buffer(struct tty_struct *tty);
 126static void cpc_tty_hangup(struct tty_struct *tty);
 127static void cpc_tty_rx_work(struct work_struct *work);
 128static void cpc_tty_tx_work(struct work_struct *work);
 129static int cpc_tty_send_to_card(pc300dev_t *dev,void *buf, int len);
 130static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx);
 131static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char);
 132static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char);
 133
 134static int pc300_tiocmset(struct tty_struct *, unsigned int, unsigned int);
 135static int pc300_tiocmget(struct tty_struct *);
 136
 137/* functions called by PC300 driver */
 138void cpc_tty_init(pc300dev_t *dev);
 139void cpc_tty_unregister_service(pc300dev_t *pc300dev);
 140void cpc_tty_receive(pc300dev_t *pc300dev);
 141void cpc_tty_trigger_poll(pc300dev_t *pc300dev);
 142void cpc_tty_reset_var(void);
 143
 144/*
 145 * PC300 TTY clear "signal"
 146 */
 147static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char signal)
 148{
 149	pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; 
 150	pc300_t *card = (pc300_t *) pc300chan->card; 
 151	int ch = pc300chan->channel; 
 152	unsigned long flags; 
 153
 154	CPC_TTY_DBG("%s-tty: Clear signal %x\n",
 155		pc300dev->dev->name, signal);
 156	CPC_TTY_LOCK(card, flags); 
 157	cpc_writeb(card->hw.scabase + M_REG(CTL,ch), 
 158		cpc_readb(card->hw.scabase+M_REG(CTL,ch))& signal);
 159	CPC_TTY_UNLOCK(card,flags); 
 160}
 161
 162/*
 163 * PC300 TTY set "signal" to ON
 164 */
 165static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char signal)
 166{
 167	pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; 
 168	pc300_t *card = (pc300_t *) pc300chan->card; 
 169	int ch = pc300chan->channel; 
 170	unsigned long flags; 
 171
 172	CPC_TTY_DBG("%s-tty: Set signal %x\n",
 173		pc300dev->dev->name, signal);
 174	CPC_TTY_LOCK(card, flags); 
 175	cpc_writeb(card->hw.scabase + M_REG(CTL,ch), 
 176		cpc_readb(card->hw.scabase+M_REG(CTL,ch))& ~signal);
 177	CPC_TTY_UNLOCK(card,flags); 
 178}
 179
 180
 181static const struct tty_operations pc300_ops = {
 182	.open = cpc_tty_open,
 183	.close = cpc_tty_close,
 184	.write = cpc_tty_write,
 185	.write_room = cpc_tty_write_room,
 186	.chars_in_buffer = cpc_tty_chars_in_buffer,
 187	.tiocmset = pc300_tiocmset,
 188	.tiocmget = pc300_tiocmget,
 189	.flush_buffer = cpc_tty_flush_buffer,
 190	.hangup = cpc_tty_hangup,
 191};
 192
 193
 194/*
 195 * PC300 TTY initialization routine
 196 *
 197 * This routine is called by the PC300 driver during board configuration 
 198 * (ioctl=SIOCSP300CONF). At this point the adapter is completely
 199 * initialized.
 200 * o verify kernel version (only 2.4.x)
 201 * o register TTY driver
 202 * o init cpc_tty_area struct
 203 */
 204void cpc_tty_init(pc300dev_t *pc300dev)
 205{
 206	unsigned long port;
 207	int aux;
 208	st_cpc_tty_area * cpc_tty;
 209
 210	/* hdlcX - X=interface number */
 211	port = pc300dev->dev->name[4] - '0';
 212	if (port >= CPC_TTY_NPORTS) {
 213		printk("%s-tty: invalid interface selected (0-%i): %li",
 214			pc300dev->dev->name,
 215			CPC_TTY_NPORTS-1,port);
 216		return;
 217	}
 218
 219	if (cpc_tty_cnt == 0) { /* first TTY connection -> register driver */
 220		CPC_TTY_DBG("%s-tty: driver init, major:%i, minor range:%i=%i\n",
 221			pc300dev->dev->name,
 222			CPC_TTY_MAJOR, CPC_TTY_MINOR_START,
 223			CPC_TTY_MINOR_START+CPC_TTY_NPORTS);
 224		/* initialize tty driver struct */
 225		memset(&serial_drv,0,sizeof(struct tty_driver));
 226		serial_drv.magic = TTY_DRIVER_MAGIC;
 227		serial_drv.owner = THIS_MODULE;
 228		serial_drv.driver_name = "pc300_tty";
 229		serial_drv.name = "ttyCP";
 230		serial_drv.major = CPC_TTY_MAJOR;
 231		serial_drv.minor_start = CPC_TTY_MINOR_START;
 232		serial_drv.num = CPC_TTY_NPORTS;
 233		serial_drv.type = TTY_DRIVER_TYPE_SERIAL;
 234		serial_drv.subtype = SERIAL_TYPE_NORMAL;
 235
 236		serial_drv.init_termios = tty_std_termios;
 237		serial_drv.init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
 238		serial_drv.flags = TTY_DRIVER_REAL_RAW;
 239
 240		/* interface routines from the upper tty layer to the tty driver */
 241		tty_set_operations(&serial_drv, &pc300_ops);
 242
 243		/* register the TTY driver */
 244		if (tty_register_driver(&serial_drv)) { 
 245			printk("%s-tty: Failed to register serial driver! ",
 246				pc300dev->dev->name);
 247		   	return;
 248		} 
 249
 250		memset((void *)cpc_tty_area, 0,
 251								sizeof(st_cpc_tty_area) * CPC_TTY_NPORTS);
 252	}
 253
 254	cpc_tty = &cpc_tty_area[port];
 255	
 256	if (cpc_tty->state != CPC_TTY_ST_IDLE) {
 257		CPC_TTY_DBG("%s-tty: TTY port %i, already in use.\n",
 258				pc300dev->dev->name, port);
 259		return;
 260	}
 261
 262	cpc_tty_cnt++;
 263	cpc_tty->state = CPC_TTY_ST_INIT; 
 264	cpc_tty->num_open= 0;
 265	cpc_tty->tty_minor = port + CPC_TTY_MINOR_START;
 266	cpc_tty->pc300dev = pc300dev; 
 267
 268	INIT_WORK(&cpc_tty->tty_tx_work, cpc_tty_tx_work);
 269	INIT_WORK(&cpc_tty->tty_rx_work, cpc_tty_rx_work);
 270	
 271	cpc_tty->buf_rx.first = cpc_tty->buf_rx.last = NULL;
 272
 273	pc300dev->cpc_tty = (void *)cpc_tty; 
 274	
 275	aux = strlen(pc300dev->dev->name);
 276	memcpy(cpc_tty->name, pc300dev->dev->name, aux);
 277	memcpy(&cpc_tty->name[aux], "-tty", 5);
 278	
 279	cpc_open(pc300dev->dev);
 280	cpc_tty_signal_off(pc300dev, CTL_DTR);
 281
 282	CPC_TTY_DBG("%s: Initializing TTY Sync Driver, tty major#%d minor#%i\n",
 283			cpc_tty->name,CPC_TTY_MAJOR,cpc_tty->tty_minor); 
 284	return; 
 285} 
 286
 287/*
 288 * PC300 TTY OPEN routine
 289 *
 290 * This routine is called by the tty driver to open the interface 
 291 * o verify minor
 292 * o allocate buffer to Rx and Tx
 293 */
 294static int cpc_tty_open(struct tty_struct *tty, struct file *flip)
 295{
 296	int port ;
 297	st_cpc_tty_area *cpc_tty;
 298
 299	if (!tty) { 
 300		return -ENODEV;
 301	} 
 302
 303	port = tty->index;
 304
 305	if ((port < 0) || (port >= CPC_TTY_NPORTS)){ 
 306		CPC_TTY_DBG("pc300_tty: open invalid port %d\n", port);
 307		return -ENODEV;
 308	} 
 309
 310	cpc_tty = &cpc_tty_area[port];
 311	
 312	if (cpc_tty->state == CPC_TTY_ST_IDLE){
 313		CPC_TTY_DBG("%s: open - invalid interface, port=%d\n",
 314					cpc_tty->name, tty->index);
 315		return -ENODEV;
 316	}
 317
 318	if (cpc_tty->num_open == 0) { /* first open of this tty */
 319		if (!cpc_tty_area[port].buf_tx){
 320			cpc_tty_area[port].buf_tx = kmalloc(CPC_TTY_MAX_MTU,GFP_KERNEL);
 321			if (!cpc_tty_area[port].buf_tx) {
 322				CPC_TTY_DBG("%s: error in memory allocation\n",cpc_tty->name);
 323				return -ENOMEM;
 324			}
 325		} 
 326
 327		if (cpc_tty_area[port].buf_rx.first) {
 328			unsigned char * aux;
 329			while (cpc_tty_area[port].buf_rx.first) {
 330				aux = (unsigned char *)cpc_tty_area[port].buf_rx.first;
 331				cpc_tty_area[port].buf_rx.first = cpc_tty_area[port].buf_rx.first->next;
 332				kfree(aux);
 333			}
 334			cpc_tty_area[port].buf_rx.first = NULL;
 335			cpc_tty_area[port].buf_rx.last = NULL;
 336		}
 337
 338		cpc_tty_area[port].state = CPC_TTY_ST_OPEN;
 339		cpc_tty_area[port].tty = tty;
 340		tty->driver_data = &cpc_tty_area[port];
 341
 342		cpc_tty_signal_on(cpc_tty->pc300dev, CTL_DTR);
 343	} 
 344
 345	cpc_tty->num_open++;
 346
 347	CPC_TTY_DBG("%s: opening TTY driver\n", cpc_tty->name);
 348	
 349	/* avisar driver PC300 */ 
 350	return 0; 
 351}
 352
 353/*
 354 * PC300 TTY CLOSE routine
 355 *
 356 * This routine is called by the tty driver to close the interface 
 357 * o call close channel in PC300 driver (cpc_closech)
 358 * o free Rx and Tx buffers
 359 */
 360
 361static void cpc_tty_close(struct tty_struct *tty, struct file *flip)
 362{
 363	st_cpc_tty_area    *cpc_tty;
 364	unsigned long flags;
 365	int res;
 366
 367	if (!tty || !tty->driver_data ) {
 368		CPC_TTY_DBG("hdlx-tty: no TTY in close\n");
 369		return;
 370	}
 371
 372	cpc_tty = (st_cpc_tty_area *) tty->driver_data;
 373
 374	if ((cpc_tty->tty != tty)|| (cpc_tty->state != CPC_TTY_ST_OPEN)) {
 375		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
 376		return;
 377	}
 378   	
 379	if (!cpc_tty->num_open) {
 380		CPC_TTY_DBG("%s: TTY is closed\n",cpc_tty->name);
 381		return;
 382	}
 383
 384	if (--cpc_tty->num_open > 0) {
 385		CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name);
 386		return;
 387	}
 388
 389	cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR);
 390
 391	CPC_TTY_LOCK(cpc_tty->pc300dev->chan->card, flags);  /* lock irq */ 
 392	cpc_tty->tty = NULL;
 393	cpc_tty->state = CPC_TTY_ST_INIT;
 394	CPC_TTY_UNLOCK(cpc_tty->pc300dev->chan->card, flags); /* unlock irq */ 
 395	
 396	if (cpc_tty->buf_rx.first) {
 397		unsigned char * aux;
 398		while (cpc_tty->buf_rx.first) {
 399			aux = (unsigned char *)cpc_tty->buf_rx.first;
 400			cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next;
 401			kfree(aux);
 402		}
 403		cpc_tty->buf_rx.first = NULL;
 404		cpc_tty->buf_rx.last = NULL;
 405	}
 406	
 407	kfree(cpc_tty->buf_tx);
 408	cpc_tty->buf_tx = NULL;
 409
 410	CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name);
 411	
 412	if (!serial_drv.refcount && cpc_tty_unreg_flag) {
 413		cpc_tty_unreg_flag = 0;
 414		CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name);
 415		if ((res=tty_unregister_driver(&serial_drv))) { 
 416			CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
 417							cpc_tty->name,res);
 418		}
 419	}
 420	return; 
 421} 
 422
 423/*
 424 * PC300 TTY WRITE routine
 425 *
 426 * This routine is called by the tty driver to write a series of characters
 427 * to the tty device. The characters may come from user or kernel space.
 428 * o verify the DCD signal
 429 * o send characters to board and start the transmission
 430 */
 431static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
 432{
 433	st_cpc_tty_area    *cpc_tty; 
 434	pc300ch_t *pc300chan; 
 435	pc300_t *card; 
 436	int ch; 
 437	unsigned long flags; 
 438	struct net_device_stats *stats; 
 439
 440	if (!tty || !tty->driver_data ) { 
 441		CPC_TTY_DBG("hdlcX-tty: no TTY in write\n");
 442		return -ENODEV;
 443	} 
 444
 445	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
 446
 447	if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
 448		CPC_TTY_DBG("%s: TTY is not opened\n", cpc_tty->name);
 449		return -ENODEV; 
 450	}
 451
 452	if (count > CPC_TTY_MAX_MTU) { 
 453		CPC_TTY_DBG("%s: count is invalid\n",cpc_tty->name);
 454		return -EINVAL;        /* frame too big */ 
 455	}
 456
 457	CPC_TTY_DBG("%s: cpc_tty_write data len=%i\n",cpc_tty->name,count);
 458	
 459	pc300chan = (pc300ch_t *)((pc300dev_t*)cpc_tty->pc300dev)->chan; 
 460	stats = &cpc_tty->pc300dev->dev->stats;
 461	card = (pc300_t *) pc300chan->card;
 462	ch = pc300chan->channel; 
 463
 464	/* verify DCD signal*/ 
 465	if (cpc_readb(card->hw.scabase + M_REG(ST3,ch)) & ST3_DCD) { 
 466		/* DCD is OFF */ 
 467		CPC_TTY_DBG("%s : DCD is OFF\n", cpc_tty->name);
 468		stats->tx_errors++;
 469		stats->tx_carrier_errors++;
 470		CPC_TTY_LOCK(card, flags); 
 471		cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR); 
 472		
 473		if (card->hw.type == PC300_TE) { 
 474			cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, 
 475				cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & 
 476				~(CPLD_REG2_FALC_LED1 << (2 *ch))); 
 477		}
 478
 479		CPC_TTY_UNLOCK(card, flags); 
 480
 481		return -EINVAL; 
 482	}
 483
 484	if (cpc_tty_send_to_card(cpc_tty->pc300dev, (void*)buf, count)) { 
 485	   /* failed to send */
 486	   CPC_TTY_DBG("%s: trasmition error\n", cpc_tty->name);
 487	   return 0;
 488	}
 489	return count; 
 490} 
 491
 492/*
 493 * PC300 TTY Write Room routine
 494 * 
 495 * This routine returns the numbers of characteres the tty driver will accept
 496 * for queuing to be written. 
 497 * o return MTU
 498 */
 499static int cpc_tty_write_room(struct tty_struct *tty)
 500{
 501	st_cpc_tty_area    *cpc_tty; 
 502
 503	if (!tty || !tty->driver_data ) { 
 504		CPC_TTY_DBG("hdlcX-tty: no TTY to write room\n");
 505		return -ENODEV;
 506	}
 507
 508	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
 509
 510	if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
 511		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
 512		return -ENODEV; 
 513	}
 514   	
 515	CPC_TTY_DBG("%s: write room\n",cpc_tty->name);
 516	
 517	return CPC_TTY_MAX_MTU;
 518} 
 519
 520/*
 521 * PC300 TTY chars in buffer routine
 522 * 
 523 * This routine returns the chars number in the transmission buffer 
 524 * o returns 0
 525 */
 526static int cpc_tty_chars_in_buffer(struct tty_struct *tty)
 527{
 528	st_cpc_tty_area    *cpc_tty; 
 529
 530	if (!tty || !tty->driver_data ) {
 531		CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n");
 532		return -ENODEV; 
 533	}
 534
 535	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
 536
 537	if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
 538		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
 539		return -ENODEV; 
 540	}
 541   
 542	return 0;
 543} 
 544
 545static int pc300_tiocmset(struct tty_struct *tty,
 546			  unsigned int set, unsigned int clear)
 547{
 548	st_cpc_tty_area    *cpc_tty; 
 549
 550	CPC_TTY_DBG("%s: set:%x clear:%x\n", __func__, set, clear);
 551
 552	if (!tty || !tty->driver_data ) {
 553	   	CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n");	
 554		return -ENODEV; 
 555	}
 556
 557	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
 558
 559	if (set & TIOCM_RTS)
 560		cpc_tty_signal_on(cpc_tty->pc300dev, CTL_RTS);
 561	if (set & TIOCM_DTR)
 562		cpc_tty_signal_on(cpc_tty->pc300dev, CTL_DTR);
 563
 564	if (clear & TIOCM_RTS)
 565		cpc_tty_signal_off(cpc_tty->pc300dev, CTL_RTS);
 566	if (clear & TIOCM_DTR)
 567		cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR);
 568
 569	return 0;
 570}
 571
 572static int pc300_tiocmget(struct tty_struct *tty)
 573{
 574	unsigned int result;
 575	unsigned char status;
 576	unsigned long flags;
 577	st_cpc_tty_area  *cpc_tty = (st_cpc_tty_area *) tty->driver_data;
 578	pc300dev_t *pc300dev = cpc_tty->pc300dev;
 579	pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan;
 580	pc300_t *card = (pc300_t *) pc300chan->card;
 581	int ch = pc300chan->channel;
 582
 583	cpc_tty = (st_cpc_tty_area *) tty->driver_data;
 584
 585	CPC_TTY_DBG("%s-tty: tiocmget\n",
 586		((struct net_device*)(pc300dev->hdlc))->name);
 587
 588	CPC_TTY_LOCK(card, flags);
 589	status = cpc_readb(card->hw.scabase+M_REG(CTL,ch));
 590	CPC_TTY_UNLOCK(card,flags);
 591
 592	result = ((status & CTL_DTR) ? TIOCM_DTR : 0) |
 593		 ((status & CTL_RTS) ? TIOCM_RTS : 0);
 594
 595	return result;
 596}
 597
 598/*
 599 * PC300 TTY Flush Buffer routine
 600 *
 601 * This routine resets the transmission buffer 
 602 */
 603static void cpc_tty_flush_buffer(struct tty_struct *tty)
 604{ 
 605	st_cpc_tty_area    *cpc_tty; 
 606	
 607	if (!tty || !tty->driver_data ) {
 608	   	CPC_TTY_DBG("hdlcX-tty: no TTY to flush buffer\n");	
 609		return; 
 610	}
 611
 612	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
 613
 614	if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
 615		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
 616		return; 
 617	}
 618
 619	CPC_TTY_DBG("%s: call wake_up_interruptible\n",cpc_tty->name);
 620
 621	tty_wakeup(tty);	
 622	return; 
 623} 
 624
 625/*
 626 * PC300 TTY Hangup routine
 627 *
 628 * This routine is called by the tty driver to hangup the interface 
 629 * o clear DTR signal
 630 */
 631
 632static void cpc_tty_hangup(struct tty_struct *tty)
 633{ 
 634	st_cpc_tty_area    *cpc_tty; 
 635	int res;
 636
 637	if (!tty || !tty->driver_data ) {
 638		CPC_TTY_DBG("hdlcX-tty: no TTY to hangup\n");	
 639		return ; 
 640	}
 641
 642	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
 643
 644	if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) {
 645		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
 646		return ;
 647	}
 648	if (!serial_drv.refcount && cpc_tty_unreg_flag) {
 649		cpc_tty_unreg_flag = 0;
 650		CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name);
 651		if ((res=tty_unregister_driver(&serial_drv))) { 
 652			CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
 653							cpc_tty->name,res);
 654		}
 655	}
 656	cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR);
 657}
 658
 659/*
 660 * PC300 TTY RX work routine
 661 * This routine treats RX work
 662 * o verify read buffer
 663 * o call the line disc. read
 664 * o free memory
 665 */
 666static void cpc_tty_rx_work(struct work_struct *work)
 667{
 668	st_cpc_tty_area *cpc_tty;
 669	unsigned long port;
 670	int i, j;
 671	volatile st_cpc_rx_buf *buf;
 672	char flags=0,flg_rx=1; 
 673	struct tty_ldisc *ld;
 674
 675	if (cpc_tty_cnt == 0) return;
 676	
 677	for (i=0; (i < 4) && flg_rx ; i++) {
 678		flg_rx = 0;
 679
 680		cpc_tty = container_of(work, st_cpc_tty_area, tty_rx_work);
 681		port = cpc_tty - cpc_tty_area;
 682
 683		for (j=0; j < CPC_TTY_NPORTS; j++) {
 684			cpc_tty = &cpc_tty_area[port];
 685		
 686			if ((buf=cpc_tty->buf_rx.first) != NULL) {
 687				if (cpc_tty->tty) {
 688					ld = tty_ldisc_ref(cpc_tty->tty);
 689					if (ld) {
 690						if (ld->ops->receive_buf) {
 691							CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name);
 692							ld->ops->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size);
 693						}
 694						tty_ldisc_deref(ld);
 695					}
 696				}	
 697				cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next;
 698				kfree((void *)buf);
 699				buf = cpc_tty->buf_rx.first;
 700				flg_rx = 1;
 701			}
 702			if (++port == CPC_TTY_NPORTS) port = 0;
 703		}
 704	}
 705} 
 706
 707/*
 708 * PC300 TTY RX work routine
 709 *
 710 * This routine treats RX interrupt. 
 711 * o read all frames in card
 712 * o verify the frame size
 713 * o read the frame in rx buffer
 714 */
 715static void cpc_tty_rx_disc_frame(pc300ch_t *pc300chan)
 716{
 717	volatile pcsca_bd_t __iomem * ptdescr; 
 718	volatile unsigned char status; 
 719	pc300_t *card = (pc300_t *)pc300chan->card; 
 720	int ch = pc300chan->channel; 
 721
 722	/* dma buf read */ 
 723	ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
 724				RX_BD_ADDR(ch, pc300chan->rx_first_bd)); 
 725	while (pc300chan->rx_first_bd != pc300chan->rx_last_bd) { 
 726		status = cpc_readb(&ptdescr->status); 
 727		cpc_writeb(&ptdescr->status, 0); 
 728		cpc_writeb(&ptdescr->len, 0); 
 729		pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & 
 730					(N_DMA_RX_BUF - 1); 
 731		if (status & DST_EOM) { 
 732			break; /* end of message */
 733		}
 734		ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + cpc_readl(&ptdescr->next)); 
 735	}
 736}
 737
 738void cpc_tty_receive(pc300dev_t *pc300dev)
 739{
 740	st_cpc_tty_area *cpc_tty; 
 741	pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; 
 742	pc300_t *card = (pc300_t *)pc300chan->card; 
 743	int ch = pc300chan->channel; 
 744	volatile pcsca_bd_t  __iomem * ptdescr; 
 745	struct net_device_stats *stats = &pc300dev->dev->stats;
 746	int rx_len, rx_aux; 
 747	volatile unsigned char status; 
 748	unsigned short first_bd = pc300chan->rx_first_bd;
 749	st_cpc_rx_buf *new = NULL;
 750	unsigned char dsr_rx;
 751
 752	if (pc300dev->cpc_tty == NULL) { 
 753		return; 
 754	}
 755
 756	dsr_rx = cpc_readb(card->hw.scabase + DSR_RX(ch));
 757
 758	cpc_tty = pc300dev->cpc_tty;
 759
 760	while (1) { 
 761		rx_len = 0;
 762		ptdescr = (pcsca_bd_t  __iomem *)(card->hw.rambase + RX_BD_ADDR(ch, first_bd));
 763		while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
 764			rx_len += cpc_readw(&ptdescr->len);
 765			first_bd = (first_bd + 1) & (N_DMA_RX_BUF - 1);
 766			if (status & DST_EOM) {
 767				break;
 768			}
 769			ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase+cpc_readl(&ptdescr->next));
 770		}
 771			
 772		if (!rx_len) { 
 773			if (dsr_rx & DSR_BOF) {
 774				/* update EDA */ 
 775				cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), 
 776						RX_BD_ADDR(ch, pc300chan->rx_last_bd)); 
 777			}
 778			kfree(new);
 779			return; 
 780		}
 781		
 782		if (rx_len > CPC_TTY_MAX_MTU) { 
 783			/* Free RX descriptors */ 
 784			CPC_TTY_DBG("%s: frame size is invalid.\n",cpc_tty->name);
 785			stats->rx_errors++; 
 786			stats->rx_frame_errors++; 
 787			cpc_tty_rx_disc_frame(pc300chan);
 788			continue;
 789		} 
 790		
 791		new = kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC);
 792		if (!new) {
 793			cpc_tty_rx_disc_frame(pc300chan);
 794			continue;
 795		}
 796		
 797		/* dma buf read */ 
 798		ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
 799				RX_BD_ADDR(ch, pc300chan->rx_first_bd)); 
 800
 801		rx_len = 0;	/* counter frame size */
 802		
 803		while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
 804			rx_aux = cpc_readw(&ptdescr->len);
 805			if ((status & (DST_OVR | DST_CRC | DST_RBIT |  DST_SHRT | DST_ABT))
 806				|| (rx_aux > BD_DEF_LEN)) {
 807				CPC_TTY_DBG("%s: reception error\n", cpc_tty->name);
 808				stats->rx_errors++; 
 809				if (status & DST_OVR) { 
 810					stats->rx_fifo_errors++; 
 811				}
 812				if (status & DST_CRC) { 
 813					stats->rx_crc_errors++; 
 814				}
 815				if ((status & (DST_RBIT | DST_SHRT | DST_ABT)) ||
 816					(rx_aux > BD_DEF_LEN))	{ 
 817					stats->rx_frame_errors++; 
 818				} 
 819				/* discard remainig descriptors used by the bad frame */ 
 820				CPC_TTY_DBG("%s: reception error - discard descriptors",
 821						cpc_tty->name);
 822				cpc_tty_rx_disc_frame(pc300chan);
 823				rx_len = 0;
 824				kfree(new);
 825				new = NULL;
 826				break; /* read next frame - while(1) */
 827			}
 828
 829			if (cpc_tty->state != CPC_TTY_ST_OPEN) {
 830				/* Free RX descriptors */ 
 831				cpc_tty_rx_disc_frame(pc300chan);
 832				stats->rx_dropped++; 
 833				rx_len = 0; 
 834				kfree(new);
 835				new = NULL;
 836				break; /* read next frame - while(1) */
 837			}
 838
 839			/* read the segment of the frame */
 840			if (rx_aux != 0) {
 841				memcpy_fromio((new->data + rx_len), 
 842					(void __iomem *)(card->hw.rambase + 
 843					 cpc_readl(&ptdescr->ptbuf)), rx_aux);
 844				rx_len += rx_aux; 
 845			}
 846			cpc_writeb(&ptdescr->status,0); 
 847			cpc_writeb(&ptdescr->len, 0); 
 848			pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & 
 849					(N_DMA_RX_BUF -1); 
 850			if (status & DST_EOM)break;
 851			
 852			ptdescr = (pcsca_bd_t __iomem *) (card->hw.rambase + 
 853					cpc_readl(&ptdescr->next)); 
 854		}
 855		/* update pointer */ 
 856		pc300chan->rx_last_bd = (pc300chan->rx_first_bd - 1) & 
 857					(N_DMA_RX_BUF - 1) ; 
 858		if (!(dsr_rx & DSR_BOF)) {
 859			/* update EDA */ 
 860			cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), 
 861					RX_BD_ADDR(ch, pc300chan->rx_last_bd)); 
 862		}
 863		if (rx_len != 0) { 
 864			stats->rx_bytes += rx_len; 
 865		
 866			if (pc300dev->trace_on) { 
 867				cpc_tty_trace(pc300dev, new->data,rx_len, 'R'); 
 868			} 
 869			new->size = rx_len;
 870			new->next = NULL;
 871			if (cpc_tty->buf_rx.first == NULL) {
 872				cpc_tty->buf_rx.first = new;
 873				cpc_tty->buf_rx.last = new;
 874			} else {
 875				cpc_tty->buf_rx.last->next = new;
 876				cpc_tty->buf_rx.last = new;
 877			}
 878			schedule_work(&(cpc_tty->tty_rx_work));
 879			stats->rx_packets++;
 880		}
 881	} 
 882} 
 883
 884/*
 885 * PC300 TTY TX work routine
 886 * 
 887 * This routine treats TX interrupt. 
 888 * o if need call line discipline wakeup
 889 * o call wake_up_interruptible
 890 */
 891static void cpc_tty_tx_work(struct work_struct *work)
 892{
 893	st_cpc_tty_area *cpc_tty =
 894		container_of(work, st_cpc_tty_area, tty_tx_work);
 895	struct tty_struct *tty; 
 896
 897	CPC_TTY_DBG("%s: cpc_tty_tx_work init\n",cpc_tty->name);
 898	
 899	if ((tty = cpc_tty->tty) == NULL) { 
 900		CPC_TTY_DBG("%s: the interface is not opened\n",cpc_tty->name);
 901		return; 
 902	}
 903	tty_wakeup(tty);
 904}
 905
 906/*
 907 * PC300 TTY send to card routine
 908 * 
 909 * This routine send data to card. 
 910 * o clear descriptors
 911 * o write data to DMA buffers
 912 * o start the transmission
 913 */
 914static int cpc_tty_send_to_card(pc300dev_t *dev,void* buf, int len)
 915{
 916	pc300ch_t *chan = (pc300ch_t *)dev->chan; 
 917	pc300_t *card = (pc300_t *)chan->card; 
 918	int ch = chan->channel; 
 919	struct net_device_stats *stats = &dev->dev->stats;
 920	unsigned long flags; 
 921	volatile pcsca_bd_t __iomem *ptdescr; 
 922	int i, nchar;
 923	int tosend = len;
 924	int nbuf = ((len - 1)/BD_DEF_LEN) + 1;
 925	unsigned char *pdata=buf;
 926
 927	CPC_TTY_DBG("%s:cpc_tty_send_to_cars len=%i", 
 928			(st_cpc_tty_area *)dev->cpc_tty->name,len);	
 929
 930	if (nbuf >= card->chan[ch].nfree_tx_bd) {
 931		return 1;
 932	}
 933	
 934	/* write buffer to DMA buffers */ 
 935	CPC_TTY_DBG("%s: call dma_buf_write\n",
 936			(st_cpc_tty_area *)dev->cpc_tty->name);	
 937	for (i = 0 ; i < nbuf ; i++) {
 938		ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
 939			TX_BD_ADDR(ch, card->chan[ch].tx_next_bd));
 940		nchar = (BD_DEF_LEN > tosend) ? tosend : BD_DEF_LEN;
 941		if (cpc_readb(&ptdescr->status) & DST_OSB) {
 942			memcpy_toio((void __iomem *)(card->hw.rambase + 
 943				cpc_readl(&ptdescr->ptbuf)), 
 944				&pdata[len - tosend], 
 945				nchar);
 946			card->chan[ch].nfree_tx_bd--;
 947			if ((i + 1) == nbuf) {
 948				/* This must be the last BD to be used */
 949				cpc_writeb(&ptdescr->status, DST_EOM);
 950			} else {
 951				cpc_writeb(&ptdescr->status, 0);
 952			}
 953			cpc_writew(&ptdescr->len, nchar);
 954		} else {
 955			CPC_TTY_DBG("%s: error in dma_buf_write\n",
 956					(st_cpc_tty_area *)dev->cpc_tty->name);	
 957			stats->tx_dropped++;
 958			return 1; 
 959		}
 960		tosend -= nchar;
 961		card->chan[ch].tx_next_bd = 
 962			(card->chan[ch].tx_next_bd + 1) & (N_DMA_TX_BUF - 1);
 963	}
 964
 965	if (dev->trace_on) { 
 966		cpc_tty_trace(dev, buf, len,'T'); 
 967	}
 968
 969	/* start transmission */ 
 970	CPC_TTY_DBG("%s: start transmission\n",
 971		(st_cpc_tty_area *)dev->cpc_tty->name);	
 972	
 973	CPC_TTY_LOCK(card, flags); 
 974	cpc_writeb(card->hw.scabase + DTX_REG(EDAL, ch), 
 975			TX_BD_ADDR(ch, chan->tx_next_bd)); 
 976	cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA); 
 977	cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE); 
 978
 979	if (card->hw.type == PC300_TE) { 
 980		cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, 
 981			cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) |
 982			(CPLD_REG2_FALC_LED1 << (2 * ch))); 
 983	}
 984	CPC_TTY_UNLOCK(card, flags); 
 985	return 0; 
 986} 
 987
 988/*
 989 *	PC300 TTY trace routine
 990 *
 991 *  This routine send trace of connection to application. 
 992 *  o clear descriptors
 993 *  o write data to DMA buffers
 994 *  o start the transmission
 995 */
 996
 997static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx)
 998{
 999	struct sk_buff *skb; 
1000
1001	if ((skb = dev_alloc_skb(10 + len)) == NULL) { 
1002		/* out of memory */ 
1003		CPC_TTY_DBG("%s: tty_trace - out of memory\n", dev->dev->name);
1004		return; 
1005	}
1006
1007	skb_put (skb, 10 + len); 
1008	skb->dev = dev->dev; 
1009	skb->protocol = htons(ETH_P_CUST); 
1010	skb_reset_mac_header(skb);
1011	skb->pkt_type = PACKET_HOST; 
1012	skb->len = 10 + len; 
1013
1014	skb_copy_to_linear_data(skb, dev->dev->name, 5);
1015	skb->data[5] = '['; 
1016	skb->data[6] = rxtx; 
1017	skb->data[7] = ']'; 
1018	skb->data[8] = ':'; 
1019	skb->data[9] = ' '; 
1020	skb_copy_to_linear_data_offset(skb, 10, buf, len);
1021	netif_rx(skb); 
1022} 	
1023
1024/*
1025 *	PC300 TTY unregister service routine
1026 *
1027 *	This routine unregister one interface. 
1028 */
1029void cpc_tty_unregister_service(pc300dev_t *pc300dev)
1030{
1031	st_cpc_tty_area *cpc_tty; 
1032	ulong flags;
1033	int res;
1034
1035	if ((cpc_tty= (st_cpc_tty_area *) pc300dev->cpc_tty) == NULL) {
1036		CPC_TTY_DBG("%s: interface is not TTY\n", pc300dev->dev->name);
1037		return; 
1038	}
1039	CPC_TTY_DBG("%s: cpc_tty_unregister_service", cpc_tty->name);
1040
1041	if (cpc_tty->pc300dev != pc300dev) { 
1042		CPC_TTY_DBG("%s: invalid tty ptr=%s\n", 
1043		pc300dev->dev->name, cpc_tty->name);
1044		return; 
1045	}
1046
1047	if (--cpc_tty_cnt == 0) { 
1048		if (serial_drv.refcount) {
1049			CPC_TTY_DBG("%s: unregister is not possible, refcount=%d",
1050							cpc_tty->name, serial_drv.refcount);
1051			cpc_tty_cnt++;
1052			cpc_tty_unreg_flag = 1;
1053			return;
1054		} else { 
1055			CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name);
1056			if ((res=tty_unregister_driver(&serial_drv))) { 
1057				CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
1058								cpc_tty->name,res);
1059			}
1060		}
1061	}
1062	CPC_TTY_LOCK(pc300dev->chan->card,flags);
1063	cpc_tty->tty = NULL; 
1064	CPC_TTY_UNLOCK(pc300dev->chan->card, flags);
1065	cpc_tty->tty_minor = 0; 
1066	cpc_tty->state = CPC_TTY_ST_IDLE; 
1067} 
1068
1069/*
1070 * PC300 TTY trigger poll routine
1071 * This routine is called by pc300driver to treats Tx interrupt. 
1072 */
1073void cpc_tty_trigger_poll(pc300dev_t *pc300dev)
1074{
1075	st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *)pc300dev->cpc_tty; 
1076	if (!cpc_tty) {
1077		return;
1078	}
1079	schedule_work(&(cpc_tty->tty_tx_work)); 
1080} 
1081
1082/*
1083 * PC300 TTY reset var routine
1084 * This routine is called by pc300driver to init the TTY area. 
1085 */
1086
1087void cpc_tty_reset_var(void)
1088{
1089	int i ; 
1090
1091	CPC_TTY_DBG("hdlcX-tty: reset variables\n");
1092	/* reset  the tty_driver structure - serial_drv */ 
1093	memset(&serial_drv, 0, sizeof(struct tty_driver));
1094	for (i=0; i < CPC_TTY_NPORTS; i++){
1095		memset(&cpc_tty_area[i],0, sizeof(st_cpc_tty_area)); 
1096	}
1097}