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