root/drivers/char/scc.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. InReg
  2. OutReg
  3. wr
  4. or
  5. cl
  6. scc_alloc_buffer_pool
  7. scc_count_used_buffers
  8. scc_get_buffer
  9. scc_return_buffer
  10. scc_free_chain
  11. scc_append_to_chain
  12. scc_enqueue
  13. scc_isr_dispatch
  14. scc_isr
  15. prepare_next_txframe
  16. scc_txint
  17. scc_toss_buffer
  18. flush_FIFO
  19. scc_exint
  20. scc_rxint
  21. kick_rx_timer
  22. scc_spint
  23. set_brg
  24. set_speed
  25. init_brg
  26. init_channel
  27. scc_key_trx
  28. is_grouped
  29. dw_slot_timeout
  30. txdel_timeout
  31. tail_timeout
  32. busy_timeout
  33. maxk_idle_timeout
  34. check_rcv_queue
  35. scc_timer
  36. scc_init_timer
  37. scc_rx_timer
  38. kiss_set_param
  39. kiss_interpret_frame
  40. kiss_store_byte
  41. kiss_decode
  42. kiss_encode
  43. z8530_init
  44. scc_paranoia_check
  45. scc_open
  46. scc_close
  47. scc_change_speed
  48. scc_ioctl
  49. scc_set_termios
  50. check_tx_queue
  51. scc_write
  52. scc_put_char
  53. scc_flush_chars
  54. scc_write_room
  55. scc_chars_in_buffer
  56. scc_flush_buffer
  57. scc_throttle
  58. scc_unthrottle
  59. scc_start
  60. scc_stop
  61. scc_init

   1 #include <linux/autoconf.h>     /* fastest method */
   2 #ifdef CONFIG_SCC
   3 
   4 #define RCS_ID "$Id: scc.c,v 1.26 1995/09/07 14:46:19 jreuter Exp jreuter $"
   5 
   6 #define BANNER "Z8530 SCC driver v1.9.dl1bke (beta) by dl1bke\n"
   7 
   8 /*
   9 
  10    ********************************************************************
  11    *   SCC.C - Linux driver for Z8530 based HDLC cards for AX.25      *
  12    ********************************************************************
  13 
  14 
  15    ********************************************************************
  16 
  17         (c) 1993 - 1995 by Joerg Reuter DL1BKE
  18 
  19         portions (c) 1994 Hans Alblas PE1AYX 
  20         and      (c) 1993 Guido ten Dolle PE1NNZ
  21 
  22    ********************************************************************
  23    
  24    The driver and the programs in this archive are UNDER CONSTRUCTION.
  25    The code is likely to fail, and so your kernel could --- even 
  26    a whole network. 
  27 
  28    This driver is intended for Amateur Radio use. If you are running it
  29    for commercial purposes, please drop me a note. I am nosy...
  30 
  31    ...BUT:
  32  
  33    ! You  m u s t  recognize the appropriate legislations of your country !
  34    ! before you connect a radio to the SCC board and start to transmit or !
  35    ! receive. The GPL allows you to use the  d r i v e r,  NOT the RADIO! !
  36 
  37    For non-Amateur-Radio use please note that you might need a special
  38    allowance/licence from the designer of the SCC Board and/or the
  39    MODEM. 
  40 
  41    This program is free software; you can redistribute it and/or modify 
  42    it under the terms of the (modified) GNU General Public License 
  43    delivered with the LinuX kernel source.
  44    
  45    This program is distributed in the hope that it will be useful,
  46    but WITHOUT ANY WARRANTY; without even the implied warranty of
  47    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  48    GNU General Public License for more details.
  49 
  50    You should find a copy of the GNU General Public License in 
  51    /usr/src/linux/COPYING; 
  52    
  53    ******************************************************************** 
  54 
  55 
  56    ...If you find any portions of the code that are copyrighted to you,
  57    and you don't want to see in here, please send me a private (!) 
  58    message to my internet site. I will change it as soon as possible. 
  59    Please don't flame to the tcp-group or anywhere else. Thanks!
  60 
  61    Joerg Reuter ampr-net: dl1bke@db0pra.ampr.org
  62                 AX-25   : DL1BKE @ DB0ACH.#NRW.DEU.EU
  63                 Internet: jreuter@lykos.tng.oche.de
  64                 
  65                 
  66    History of z8530drv:
  67    --------------------
  68 
  69    940913       - started to write the driver, rescued most of my own
  70                   code (and Hans Alblas' memory buffer pool concept) from 
  71                   an earlier project "sccdrv" which was initiated by 
  72                   Guido ten Dolle. Not much of the old driver survived, 
  73                   though. The first version I put my hands on was sccdrv1.3
  74                   from August 1993. The memory buffer pool concept
  75                   appeared in an unauthorized sccdrv version (1.5) from
  76                   August 1994.
  77 
  78    950131       - changed copyright notice to GPL without limitations.
  79    
  80    950228       - (hopefully) fixed the reason for kernel panics in
  81                   chk_rcv_queue() [stupid error]
  82                   
  83    950304       - fixed underrun/zcount handling
  84    
  85    950305       - the driver registers port addresses now
  86    
  87    950314       - fixed underrun interrupt handling again
  88    
  89    950512       - (hope to have) fixed hidden re-entrance problem
  90                   in scc_timer()
  91                   
  92    950824       - received frames will be sent to the application
  93                   faster, clean-up of z8530_init()
  94 
  95    Thanks to:
  96    ----------
  97    
  98    PE1CHL Rob   - for a lot of good ideas from his SCC driver for DOS
  99    PE1NNZ Guido - for his port of the original driver to Linux
 100    KA9Q   Phil  - from whom we stole the mbuf-structure
 101    PA3AYX Hans  - who rewrote parts of the memory management and some 
 102                   minor, but nevertheless useful changes
 103    DL8MBT Flori - for support
 104    DG0FT  Rene  - for the BayCom USCC support
 105    PA3AOU Harry - for ESCC testing, information supply and support
 106    
 107    PE1KOX Rob, DG1RTF Thomas, ON5QK Roland, 
 108    
 109    and all who sent me bug reports and ideas... 
 110    
 111    
 112    NB -- if you find errors, change something, please let me know
 113          first before you distribute it... And please don't touch
 114          the version number. Just replace my callsign in
 115          "v1.9.dl1bke" with your own. Just to avoid confusion...
 116          
 117    If you want to add your modification to the linux distribution
 118    please (!) contact me first.
 119           
 120    Jörg Reuter DL1BKE
 121   
 122 */
 123 
 124 #include <linux/errno.h>
 125 #include <linux/signal.h>
 126 #include <linux/sched.h>
 127 #include <linux/timer.h>
 128 #include <linux/tqueue.h>
 129 #include <linux/tty.h>
 130 #include <linux/tty_driver.h>
 131 #include <linux/tty_flip.h>
 132 #include <linux/major.h>
 133 #include <linux/termios.h>
 134 #include <linux/serial.h>
 135 #include <linux/interrupt.h>
 136 #include <linux/ioport.h>
 137 #include <linux/config.h>
 138 #include <linux/string.h>
 139 #include <linux/fcntl.h>
 140 #include <linux/ptrace.h>
 141 #include <linux/malloc.h>
 142 #include <linux/scc.h>
 143 #include <linux/delay.h>
 144 #include "scc_config.h"
 145 
 146 #include <asm/system.h>
 147 #include <asm/io.h>
 148 #include <asm/segment.h>
 149 #include <asm/bitops.h>
 150 
 151 #include <stdlib.h>
 152 #include <stdio.h>
 153 #include <ctype.h>
 154 #include <time.h>
 155 #include <linux/kernel.h>
 156 
 157 #ifndef Z8530_MAJOR
 158 #define Z8530_MAJOR 34
 159 #endif
 160 
 161 int scc_init(void);
 162 
 163 int scc_open(struct tty_struct *tty, struct file *filp);
 164 static void scc_close(struct tty_struct *tty, struct file *filp);
 165 int scc_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count);
 166 static void scc_put_char(struct tty_struct *tty, unsigned char ch);
 167 static void scc_flush_chars(struct tty_struct *tty);
 168 static int scc_write_room(struct tty_struct *tty);
 169 static int scc_chars_in_buffer(struct tty_struct *tty);
 170 static void scc_flush_buffer(struct tty_struct *tty);
 171 static int scc_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
 172 static void scc_set_termios(struct tty_struct *tty, struct termios *old_termios);
 173 static void scc_throttle(struct tty_struct *tty);
 174 static void scc_unthrottle(struct tty_struct *tty);
 175 static void scc_start(struct tty_struct *tty);
 176 static void scc_stop(struct tty_struct *tty);
 177 
 178 static void z8530_init(void);
 179 
 180 static void scc_change_speed(struct scc_channel *scc);
 181 static void kiss_encode(struct scc_channel *scc);
 182 
 183 static void init_channel(struct scc_channel *scc);
 184 static void scc_key_trx (struct scc_channel *scc, char tx);
 185 static void scc_txint(register struct scc_channel *scc);
 186 static void scc_exint(register struct scc_channel *scc);
 187 static void scc_rxint(register struct scc_channel *scc);
 188 static void scc_spint(register struct scc_channel *scc);
 189 static void scc_isr(int irq, struct pt_regs *regs);
 190 static void scc_timer(void);
 191 static void scc_init_timer(struct scc_channel *scc);
 192 static void scc_rx_timer(void);
 193 
 194 /* from serial.c */
 195 
 196 static int baud_table[] = {
 197         0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
 198         9600, 19200, 38400, 57600, 115200, 0 };
 199 
 200 
 201 struct tty_driver scc_driver;
 202 static int scc_refcount;
 203 static struct tty_struct *scc_table[2*MAXSCC];
 204 static struct termios scc_termios[2 * MAXSCC];
 205 static struct termios scc_termios_locked[2 * MAXSCC];
 206         
 207 struct scc_channel SCC_Info[2 * MAXSCC];         /* information per channel */
 208 
 209 unsigned char Random = 0;               /* random number for p-persist */
 210 unsigned char Driver_Initialized = 0;
 211 static struct sccbuf *sccfreelist[MAX_IBUFS] = {0};
 212 static int allocated_ibufs = 0;
 213 
 214 static struct rx_timer_CB rx_timer_cb;
 215 
 216 /* ******************************************************************** */
 217 /* *                    Port Access Functions                         * */
 218 /* ******************************************************************** */
 219 
 220 static inline unsigned char
 221 InReg(register io_port port, register unsigned char reg)
     /* [previous][next][first][last][top][bottom][index][help] */
 222 {
 223 #ifdef SCC_LDELAY
 224         register unsigned char r;
 225         Outb(port, reg);
 226         udelay(5);
 227         r=Inb(port);
 228         udelay(5);
 229         return r;
 230 #else
 231         Outb(port, reg);
 232         return Inb(port);
 233 #endif
 234 }
 235 
 236 static inline void
 237 OutReg(register io_port port, register unsigned char reg, register unsigned char val)
     /* [previous][next][first][last][top][bottom][index][help] */
 238 {
 239 #ifdef SCC_LDELAY
 240         Outb(port, reg); udelay(5);
 241         Outb(port, val); udelay(5);
 242 #else
 243         Outb(port, reg);
 244         Outb(port, val);
 245 #endif
 246 }
 247 
 248 static inline void
 249 wr(register struct scc_channel *scc, register unsigned char reg, register unsigned char val)
     /* [previous][next][first][last][top][bottom][index][help] */
 250 {
 251         OutReg(scc->ctrl, reg, (scc->wreg[reg] = val));
 252 }
 253 
 254 static inline void
 255 or(register struct scc_channel *scc, register unsigned char reg, register unsigned char val)
     /* [previous][next][first][last][top][bottom][index][help] */
 256 {
 257         OutReg(scc->ctrl, reg, (scc->wreg[reg] |= val));
 258 }
 259 
 260 static inline void
 261 cl(register struct scc_channel *scc, register unsigned char reg, register unsigned char val)
     /* [previous][next][first][last][top][bottom][index][help] */
 262 {
 263         OutReg(scc->ctrl, reg, (scc->wreg[reg] &= ~val));
 264 }
 265 
 266 /* ******************************************************************** */
 267 /* *                    Memory Buffer Management                        */
 268 /* ******************************************************************** */
 269 
 270 /* mbuf concept lent from KA9Q. Tnx PE1AYX for the buffer pool concept  */
 271 /* (sorry, do you have any better ideas?) */
 272 
 273 
 274 /* allocate memory for the interrupt buffer pool */
 275 
 276 void scc_alloc_buffer_pool(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 277 {
 278         int i;
 279         struct sccbuf *sccb;
 280         struct mbuf   *bp;
 281         
 282         for (i = 0 ; i < MAX_IBUFS ; i++)
 283         {
 284                 sccb = (struct sccbuf *)kmalloc(sizeof(struct sccbuf), GFP_ATOMIC);
 285                 bp = (struct mbuf *)kmalloc(sizeof(struct mbuf), GFP_ATOMIC);
 286                 
 287                 if ( !(sccb && bp) )
 288                 {
 289                         allocated_ibufs = --i;
 290                         
 291                         if (allocated_ibufs < 0)
 292                                 panic("scc_alloc_buffer_pool() - can't get buffer space");
 293                         else
 294                                 printk("Warning: scc_alloc_buffer_pool() - allocated only %i buffers\n",i);
 295                                 
 296                         return;
 297                 }
 298                 
 299                 sccfreelist[i] = sccb;
 300                 sccfreelist[i]->bp = bp;
 301                 memset(sccfreelist[i]->bp ,0,sizeof(struct mbuf));
 302                 sccfreelist[i]->inuse = 0;
 303                 sccfreelist[i]->bp->type = 0;
 304                 sccfreelist[i]->bp->refcnt = 0;
 305                 sccfreelist[i]->bp->size = BUFSIZE;
 306         }
 307         allocated_ibufs = MAX_IBUFS;
 308 }
 309 
 310 unsigned int scc_count_used_buffers(unsigned int * rx, unsigned int * tx)
     /* [previous][next][first][last][top][bottom][index][help] */
 311 {
 312         unsigned int i, used = 0;
 313         
 314         if (rx) *rx = 0;
 315         if (tx) *tx = 0;
 316         
 317         for (i = 0 ; i < allocated_ibufs ; i++)
 318         {
 319                 if (sccfreelist[i]->inuse)
 320                 {
 321                         switch (sccfreelist[i]->bp->type)
 322                         {
 323                                 case BT_RECEIVE:
 324                                         if (rx) (*rx)++; break;
 325                                 case BT_TRANSMIT:
 326                                         if (tx) (*tx)++; break;
 327                         }
 328                         
 329                         used++;
 330                 }
 331         }
 332         
 333         return used;
 334 }
 335 
 336 
 337 /* Allocate mbuf */
 338 struct mbuf *
 339 scc_get_buffer(char type)
     /* [previous][next][first][last][top][bottom][index][help] */
 340 {
 341         int i;
 342         unsigned long flags;
 343 
 344         save_flags(flags); cli();       /* just to be sure */
 345 
 346         for (i = 0 ; i < allocated_ibufs ; i++)
 347         {
 348                 if(sccfreelist[i]->inuse == 0)
 349                 {
 350                         sccfreelist[i]->inuse = 1;
 351                         sccfreelist[i]->bp->type = type;
 352                         sccfreelist[i]->bp->next = NULLBUF;
 353                         sccfreelist[i]->bp->anext = NULLBUF;
 354                         sccfreelist[i]->bp->dup = NULLBUF;
 355                         sccfreelist[i]->bp->size = BUFSIZE;
 356                         sccfreelist[i]->bp->refcnt = 1;
 357                         sccfreelist[i]->bp->cnt = 0;
 358                         sccfreelist[i]->bp->in_use = 0;
 359                 
 360                         restore_flags(flags);
 361                         return sccfreelist[i]->bp;
 362                 }
 363         }
 364         
 365         printk("\nSCC scc_get_buffer(): buffer pool empty\n");  /* should never happen */
 366         restore_flags(flags);
 367         return NULLBUF;
 368 }
 369 
 370 
 371 /* Decrement the reference pointer in an mbuf. If it goes to zero,
 372  * free all resources associated with mbuf.
 373  * Return pointer to next mbuf in packet chain
 374  */
 375 struct mbuf *
 376 scc_return_buffer(register struct mbuf *bp, char type)
     /* [previous][next][first][last][top][bottom][index][help] */
 377 {
 378         struct mbuf *bpnext;
 379         int i;
 380         unsigned long flags;
 381         
 382         if(!bp)
 383                 return NULLBUF;
 384                 
 385         save_flags(flags); cli();
 386         bpnext = bp->next;
 387         
 388         if (bp->dup)
 389         {
 390                 for(i = 0 ; i < allocated_ibufs ; i++)
 391                 {
 392                         if(sccfreelist[i]->bp == bp->dup)
 393                         {
 394                               if (sccfreelist[i]->bp->type != type)
 395                               {
 396                                    printk("scc_return_buffer(bp->dup, %i): wrong buffer type %i",
 397                                           type,sccfreelist[i]->bp->type);
 398                               }
 399                               
 400                               sccfreelist[i]->bp->cnt = 0;
 401                               sccfreelist[i]->bp->refcnt = 0;
 402                               sccfreelist[i]->bp->in_use = 0;
 403                               sccfreelist[i]->inuse = 0;
 404                               bp->dup = NULLBUF;
 405                         }
 406                 }
 407         }
 408         
 409         /* Decrement reference count. If it has gone to zero, free it. */
 410         if(--bp->refcnt <= 0)
 411         {
 412                 for(i = 0 ; i < allocated_ibufs ; i++)
 413                 {
 414                         if(sccfreelist[i]->bp == bp)
 415                         {
 416                                 if (sccfreelist[i]->bp->type != type)
 417                                 {
 418                                         printk("scc_return_buffer(bp, %i): wrong buffer type %i",
 419                                                 type,sccfreelist[i]->bp->type);
 420                                 }                               
 421                              
 422                                 sccfreelist[i]->bp->cnt = 0;
 423                                 sccfreelist[i]->bp->refcnt = 0;
 424                                 sccfreelist[i]->inuse = 0;
 425                                 restore_flags(flags);
 426                                 return bpnext;
 427                         }
 428                 }
 429         }
 430                 
 431         printk("\nscc_return_buffer(): bogus pointer %p\n",bp);
 432         restore_flags(flags);
 433         return bpnext;
 434 } 
 435 
 436 
 437 /* Free packet (a chain of mbufs). Return pointer to next packet on queue,
 438  * if any
 439  */
 440 struct mbuf *
 441 scc_free_chain(register struct mbuf *bp, char type)
     /* [previous][next][first][last][top][bottom][index][help] */
 442 {
 443         register struct mbuf *abp;
 444         unsigned long flags;
 445 
 446         if(!bp) 
 447                 return NULLBUF;
 448                 
 449         save_flags(flags); cli();       
 450         
 451         abp = bp->anext;
 452         while (bp) bp = scc_return_buffer(bp, type);
 453                 
 454         restore_flags(flags);
 455         return abp;
 456 }
 457 
 458 
 459 /* Append mbuf to end of mbuf chain */
 460 void
 461 scc_append_to_chain(struct mbuf **bph,struct mbuf *bp)
     /* [previous][next][first][last][top][bottom][index][help] */
 462 {
 463         register struct mbuf *p;
 464         unsigned long flags;
 465 
 466         if(bph == NULLBUFP || bp == NULLBUF)
 467                 return;
 468         
 469         save_flags(flags); cli();
 470         
 471         if(*bph == NULLBUF)
 472         {
 473                 /* First one on chain */
 474                 *bph = bp;
 475         } else {
 476                 for(p = *bph ; p->next != NULLBUF ; p = p->next)
 477                         ;
 478                 p->next = bp;
 479         }
 480         
 481         restore_flags(flags);
 482 }
 483 
 484 
 485 /* Append packet (chain of mbufs) to end of packet queue */
 486 void
 487 scc_enqueue(struct mbuf **queue,struct mbuf *bp)
     /* [previous][next][first][last][top][bottom][index][help] */
 488 {
 489         register struct mbuf *p;
 490         unsigned long flags;
 491 
 492         if(queue == NULLBUFP || bp == NULLBUF)
 493                 return;
 494                 
 495         save_flags(flags); cli();
 496         
 497         if(*queue == NULLBUF)
 498         {
 499                 /* List is empty, stick at front */
 500                 *queue = bp;
 501         } else {
 502                 for(p = *queue ; p->anext != NULLBUF ; p = p->anext)
 503                         ;
 504                 p->anext = bp;
 505         }
 506         restore_flags(flags);
 507 }
 508 
 509 
 510 /* ******************************************************************** */
 511 /* *                    Interrupt Service Routines                    * */
 512 /* ******************************************************************** */
 513 
 514 /* ----> interrupt service routine for the 8530 <---- */
 515 
 516 /* it's recommendet to keep this function "inline" ;-) */
 517 
 518 static inline void
 519 scc_isr_dispatch(register struct scc_channel *scc, register int vector)
     /* [previous][next][first][last][top][bottom][index][help] */
 520 {
 521         switch (vector & VECTOR_MASK)
 522         {
 523                 case TXINT: scc_txint(scc); break;
 524                 case EXINT: scc_exint(scc); break;
 525                 case RXINT: scc_rxint(scc); break;
 526                 case SPINT: scc_spint(scc); break;
 527                 default   : printk("scc_isr(): unknown interrupt status (addr %4.4x, state %2.2x)\n",scc->ctrl,vector);
 528         }
 529 }
 530 
 531 
 532 
 533 
 534 
 535 /* If the card has a latch for the interrupt vector (like the PA0HZP card)
 536    use it to get the number of the chip that generated the int.
 537    If not: poll all defined chips.
 538  */
 539 
 540 static void
 541 scc_isr(int irq, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 542 {
 543         register unsigned char vector;  
 544         register struct scc_channel *scc;
 545         register io_port q;
 546         register io_port *p;
 547         register int k;
 548 
 549 
 550         cli();
 551         
 552         if (Vector_Latch)
 553         {
 554                 while(1)                           /* forever...? */
 555                 { 
 556                         Outb(Vector_Latch, 0);      /* Generate INTACK */
 557         
 558                         /* Read the vector */
 559                         if((vector=Inb(Vector_Latch)) >= 16 * Nchips) break; 
 560                                                 /* ...not forever! */
 561           
 562                         /* Extract channel number and status from vector. */
 563                         /* Isolate channel nummer */
 564                         /* Call handler */
 565                 
 566                         if (vector & 0x01) break; 
 567                  
 568                         scc=&SCC_Info[(((vector>>1)&0x7c)^0x04) >> 2];
 569         
 570                         if (!scc->tty) break;
 571 
 572                         scc_isr_dispatch(scc, vector);
 573                         
 574                         Outb(scc->ctrl,0x38);              /* Reset Highest IUS" opcode to WR0 */
 575                 }  
 576                 
 577                 sti();  
 578                 return;
 579         }
 580         
 581         
 582         /* Find the SCC generating the interrupt by polling all attached SCCs
 583          * reading RR3A (the interrupt pending register)
 584          */
 585 
 586         k = 0;
 587         p = SCC_ctrl;
 588         
 589         while (k++ < Nchips)
 590         {
 591                 if (!(q=*p++)) break;
 592                 
 593                 Outb(q,3);
 594                 
 595                 if (Inb(q))
 596                 {
 597                         if (!(q=*p++)) break;
 598                         
 599                         Outb(q,2);
 600                         vector=Inb(q);                  /* Read the vector */
 601         
 602                         /* Extract channel number and status from vector. */
 603                         /* Isolate channel nummer */
 604                         /* Call handler */
 605         
 606 
 607                         if (vector & 1) break; 
 608         
 609                         scc = &SCC_Info[(((vector >> 1) & 0x7c) ^ 0x04) >> 2];
 610         
 611                         if (!scc->tty) break;
 612 
 613                         /* Isolate status info from vector, call handler */
 614                         
 615                         scc_isr_dispatch(scc, vector);
 616 
 617                         k = 0;
 618                         p = SCC_ctrl;
 619 
 620                 } else p++;
 621         }    
 622         
 623         sti();
 624 }
 625 
 626 
 627 
 628 /* ----> four different interrupt handlers for Tx, Rx, changing of      */
 629 /*       DCD/CTS and Rx/Tx errors                                       */
 630 
 631 
 632 static inline void prepare_next_txframe(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
 633 {
 634         if ((scc->tbp = scc->sndq))
 635         {
 636                 scc->sndq = scc->sndq->anext;
 637                 scc->stat.tx_state = TXS_NEWFRAME;
 638 
 639         } else {
 640                 scc->stat.tx_state = TXS_BUSY;
 641                 scc->t_tail = scc->kiss.tailtime;
 642         }
 643 }
 644 
 645 
 646 /* Transmitter interrupt handler */
 647 static void
 648 scc_txint(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
 649 {
 650         register struct mbuf *bp;
 651 
 652         scc->stat.txints++;
 653 
 654         bp = scc->tbp;
 655                         
 656         while (bp && !bp->cnt)      /* find next buffer */
 657                 bp = scc_return_buffer(bp, BT_TRANSMIT);
 658                                 
 659         if (bp == NULLBUF)                      /* no more buffers in this frame */
 660         {
 661                 if (--scc->stat.tx_queued < 0)
 662                         scc->stat.tx_queued = 0;
 663                         
 664                 Outb(scc->ctrl,RES_Tx_P);       /* reset pending int */                                 
 665                 cl(scc,R10,ABUNDER);            /* frame complete, allow CRC transmit */ 
 666                 prepare_next_txframe(scc);
 667                 
 668         } else {                                /* okay, send byte */
 669         
 670                 if (scc->stat.tx_state == TXS_NEWFRAME)
 671                 {                               /* first byte ? */
 672                         Outb(scc->ctrl, RES_Tx_CRC);    /* reset CRC generator */
 673                         or(scc,R10,ABUNDER);            /* re-install underrun protection */
 674                         Outb(scc->data,bp->data[bp->in_use++]);
 675                                                         /* send byte */
 676                         if (!scc->enhanced)             /* reset EOM latch */
 677                                 Outb(scc->ctrl, RES_EOM_L);
 678                                 
 679                         scc->stat.tx_state = TXS_ACTIVE;/* next byte... */
 680                 } else {
 681                         Outb(scc->data,bp->data[bp->in_use++]);
 682                 }
 683                 
 684                 bp->cnt--;                      /* decrease byte count */
 685                 scc->tbp=bp;                    /* store buffer address */
 686         }
 687 }
 688 
 689 /* Throw away received mbuf(s) when an error occurred */
 690 
 691 static inline void
 692 scc_toss_buffer(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
 693 {
 694         register struct mbuf *bp;
 695         
 696         if((bp = scc->rbp) != NULLBUF)
 697         {
 698                 scc_free_chain(bp->next, BT_RECEIVE);
 699                 bp->next = NULLBUF;
 700                 scc->rbp1 = bp;         /* Don't throw this one away */
 701                 bp->cnt = 0;            /* Simply rewind it */
 702                 bp->in_use = 0;
 703         }
 704 }
 705 
 706 static inline void
 707 flush_FIFO(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
 708 {
 709         register int k;
 710         
 711         for (k=0; k<3; k++)
 712                 Inb(scc->data);
 713                 
 714         if(scc->rbp != NULLBUF) /* did we receive something? */
 715         {
 716                 if(scc->rbp->next != NULLBUF || scc->rbp->cnt > 0)
 717                         scc->stat.rxerrs++;  /* then count it as an error */
 718                         
 719                 scc_toss_buffer(scc);         /* throw away buffer */
 720         }
 721 }
 722 
 723 
 724 
 725 /* External/Status interrupt handler */
 726 static void
 727 scc_exint(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
 728 {
 729         register unsigned char status,changes,chg_and_stat;
 730 
 731         scc->stat.exints++;
 732 
 733         status = InReg(scc->ctrl,R0);
 734         changes = status ^ scc->status;
 735         chg_and_stat = changes & status;
 736         
 737         /* ABORT: generated whenever DCD drops while receiving */
 738 
 739         if (chg_and_stat & BRK_ABRT)            /* Received an ABORT */
 740                 flush_FIFO(scc);
 741                         
 742                 
 743         /* DCD: on = start to receive packet, off = ABORT condition */
 744         /* (a successfully received packet generates a special condition int) */
 745         
 746         if(changes & DCD)                       /* DCD input changed state */
 747         {
 748                 if(status & DCD)                /* DCD is now ON */
 749                 {
 750                         if (scc->modem.clocksrc != CLK_EXTERNAL)
 751                                 OutReg(scc->ctrl,R14,SEARCH|scc->wreg[R14]); /* DPLL: enter search mode */
 752                                 
 753                         or(scc,R3,ENT_HM|RxENABLE); /* enable the receiver, hunt mode */
 754                 } else {                        /* DCD is now OFF */
 755                         cl(scc,R3,ENT_HM|RxENABLE); /* disable the receiver */
 756                         flush_FIFO(scc);
 757                 }
 758         }
 759 
 760 
 761         /* CTS: use external TxDelay (what's that good for?!) */
 762         
 763         if (chg_and_stat & CTS)                 /* CTS is now ON */
 764         {                       
 765                 if (!Running(t_txdel) && scc->kiss.txdelay == 0) /* zero TXDELAY = wait for CTS */
 766                         scc->t_txdel = 0;       /* kick it! */          
 767                 
 768         }
 769         
 770         if ((scc->stat.tx_state == TXS_ACTIVE) && (status & TxEOM))
 771         {
 772                 scc->stat.tx_under++;     /* oops, an underrun! count 'em */
 773                 Outb(scc->ctrl, RES_Tx_P);
 774                 Outb(scc->ctrl, RES_EXT_INT);   /* reset ext/status interrupts */
 775                 scc->t_maxk = 1;
 776                 scc->tbp = scc_free_chain(scc->tbp, BT_TRANSMIT);
 777                 
 778                 if (--scc->stat.tx_queued < 0) scc->stat.tx_queued = 0;
 779                 or(scc,R10,ABUNDER);
 780         }
 781                 
 782         if (status & ZCOUNT)               /* Oops? */
 783         {
 784                 scc->stat.tx_under = 9999;  /* errr... yes. */
 785                 Outb(scc->ctrl, RES_Tx_P); /* just to be sure */
 786                 scc->t_maxk = 1;
 787                 scc->tbp = scc_free_chain(scc->tbp, BT_TRANSMIT);
 788                 if (--scc->stat.tx_queued < 0) scc->stat.tx_queued = 0;
 789                 scc->kiss.tx_inhibit = 1;       /* don't try it again! */
 790         }
 791                 
 792         
 793         scc->status = status;
 794         Outb(scc->ctrl,RES_EXT_INT);
 795 }
 796 
 797 
 798 /* Receiver interrupt handler */
 799 static void
 800 scc_rxint(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
 801 {
 802         register struct mbuf *bp;
 803 
 804         scc->stat.rxints++;
 805 
 806         if( Running(t_maxk) && !(scc->kiss.fulldup))
 807         {
 808                 Inb(scc->data);         /* discard char */
 809                 or(scc,R3,ENT_HM);      /* enter hunt mode for next flag */
 810                 return;
 811         }
 812 
 813         if ((bp = scc->rbp1) == NULLBUF || bp->cnt >= bp->size) 
 814         {                               /* no buffer available or buffer full */
 815                 if (scc->rbp == NULLBUF)
 816                 {
 817                         if ((bp = scc_get_buffer(BT_RECEIVE)) != NULLBUF)
 818                                 scc->rbp = scc->rbp1 = bp;
 819                                 
 820                 }
 821                 else if ((bp = scc_get_buffer(BT_RECEIVE)))
 822                 {
 823                         scc_append_to_chain(&scc->rbp, bp);
 824                         scc->rbp1 = bp;
 825                 }
 826                 
 827                 if (bp == NULLBUF)              /* no buffer available? */
 828                 {
 829                         Inb(scc->data);         /* discard character */
 830                         or(scc,R3,ENT_HM);      /* enter hunt mode */
 831                         scc_toss_buffer(scc);   /* throw away buffers */
 832                         scc->stat.nospace++;    /* and count this error */
 833                         return;
 834                 }
 835         }
 836 
 837         /* now, we have a buffer. read character and store it */
 838         bp->data[bp->cnt++] = Inb(scc->data);
 839 }
 840 
 841 /* kick rx_timer (try to send received frame or part of it ASAP) */
 842 /* !experimental! */
 843 
 844 static inline void
 845 kick_rx_timer(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
 846 {
 847         register unsigned long expires;
 848 
 849         if (!rx_timer_cb.lock)
 850         {
 851                 expires = timer_table[SCC_TIMER].expires - jiffies;
 852 
 853                 rx_timer_cb.expires = (expires > 1)? expires:1;
 854                 rx_timer_cb.scc = scc;
 855                 rx_timer_cb.lock = 1;
 856         
 857                 timer_table[SCC_TIMER].fn = scc_rx_timer;
 858                 timer_table[SCC_TIMER].expires = jiffies + 1;
 859                 timer_active |= 1 << SCC_TIMER;
 860         }
 861 }
 862 
 863 /* Receive Special Condition interrupt handler */
 864 static void
 865 scc_spint(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
 866 {
 867         register unsigned char status;
 868         register struct mbuf *bp;
 869 
 870         scc->stat.spints++;
 871 
 872         status = InReg(scc->ctrl,R1);           /* read receiver status */
 873         
 874         Inb(scc->data);                         /* throw away Rx byte */
 875 
 876         if(status & Rx_OVR)                     /* receiver overrun */
 877         {
 878                 scc->stat.rx_over++;                /* count them */
 879                 or(scc,R3,ENT_HM);              /* enter hunt mode for next flag */
 880                 scc_toss_buffer(scc);                 /* rewind the buffer and toss */
 881         }
 882         
 883         if(status & END_FR && scc->rbp != NULLBUF)      /* end of frame */
 884         {
 885                 /* CRC okay, frame ends on 8 bit boundary and received something ? */
 886                 
 887                 if (!(status & CRC_ERR) && (status & 0xe) == RES8 && scc->rbp->cnt)
 888                 {
 889                         /* ignore last received byte (first of the CRC bytes) */
 890                         
 891                         for (bp = scc->rbp; bp->next != NULLBUF; bp = bp->next) ;
 892                                 bp->cnt--;              /* last byte is first CRC byte */
 893                                 
 894                         scc_enqueue(&scc->rcvq,scc->rbp);
 895                         scc->rbp = scc->rbp1 = NULLBUF;
 896                         scc->stat.rxframes++;
 897                         scc->stat.rx_queued++;
 898                         kick_rx_timer(scc);
 899                 } else {                                /* a bad frame */
 900                         scc_toss_buffer(scc);           /* throw away frame */
 901                         scc->stat.rxerrs++;
 902                 }
 903         }
 904         
 905         Outb(scc->ctrl,ERR_RES);
 906 }
 907 
 908 
 909 /* ******************************************************************** */
 910 /* *                    Init Channel                                    */
 911 /* ******************************************************************** */
 912 
 913 
 914 /* ----> set SCC channel speed <---- */
 915 
 916 static inline void set_brg(register struct scc_channel *scc, unsigned int tc)
     /* [previous][next][first][last][top][bottom][index][help] */
 917 {
 918         unsigned long flags;
 919 
 920         save_flags(flags); cli();       /* 2-step register accesses... */
 921 
 922         cl(scc,R14,BRENABL);            /* disable baudrate generator */
 923         wr(scc,R12,tc & 255);           /* brg rate LOW */
 924         wr(scc,R13,tc >> 8);            /* brg rate HIGH */
 925         or(scc,R14,BRENABL);            /* enable baudrate generator */
 926 
 927         restore_flags(flags);
 928 }
 929 
 930 static inline void set_speed(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
 931 {
 932         set_brg(scc, (unsigned) (Clock / (scc->modem.speed * 64)) - 2);
 933 }
 934 
 935 
 936 /* ----> initialize a SCC channel <---- */
 937 
 938 static inline void init_brg(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
 939 {
 940         wr(scc, R14, BRSRC);                            /* BRG source = PCLK */
 941         OutReg(scc->ctrl, R14, SSBR|scc->wreg[R14]);    /* DPLL source = BRG */
 942         OutReg(scc->ctrl, R14, SNRZI|scc->wreg[R14]);   /* DPLL NRZI mode */
 943 }
 944 
 945 static void
 946 init_channel(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
 947 {
 948         unsigned long flags;
 949 
 950         save_flags(flags); cli();
 951 
 952         wr(scc,R1,0);                   /* no W/REQ operation */
 953         wr(scc,R3,Rx8|RxCRC_ENAB);      /* RX 8 bits/char, CRC, disabled */     
 954         wr(scc,R4,X1CLK|SDLC);          /* *1 clock, SDLC mode */
 955         wr(scc,R5,Tx8|DTR|TxCRC_ENAB);  /* TX 8 bits/char, disabled, DTR */
 956         wr(scc,R6,0);                   /* SDLC address zero (not used) */
 957         wr(scc,R7,FLAG);                /* SDLC flag value */
 958         wr(scc,R10,(scc->modem.nrz? NRZ : NRZI)|CRCPS|ABUNDER); /* abort on underrun, preset CRC generator, NRZ(I) */
 959         wr(scc,R14, 0);
 960 
 961 
 962 /* set clock sources:
 963 
 964    CLK_DPLL: normal halfduplex operation
 965    
 966                 RxClk: use DPLL
 967                 TxClk: use DPLL
 968                 TRxC mode DPLL output
 969                 
 970    CLK_EXTERNAL: external clocking (G3RUH or DF9IC modem)
 971    
 972                 BayCom:                 others:
 973                 
 974                 TxClk = pin RTxC        TxClk = pin TRxC
 975                 RxClk = pin TRxC        RxClk = pin RTxC
 976              
 977 
 978    CLK_DIVIDER:
 979                 RxClk = use DPLL
 980                 TxClk = pin RTxC
 981                 
 982                 BayCom:                 others:
 983                 pin TRxC = DPLL         pin TRxC = BRG
 984                 (RxClk * 1)             (RxClk * 32)
 985 */  
 986 
 987                 
 988         switch(scc->modem.clocksrc)
 989         {
 990                 case CLK_DPLL:
 991                         wr(scc, R11, RCDPLL|TCDPLL|TRxCOI|TRxCDP);
 992                         init_brg(scc);
 993                         break;
 994 
 995                 case CLK_DIVIDER:
 996                         wr(scc, R11, ((Board & BAYCOM)? TRxCDP : TRxCBR) | RCDPLL|TCRTxCP|TRxCOI);
 997                         init_brg(scc);
 998                         break;
 999 
1000                 case CLK_EXTERNAL:
1001                         wr(scc, R11, (Board & BAYCOM)? RCTRxCP|TCRTxCP : RCRTxCP|TCTRxCP);
1002                         OutReg(scc->ctrl, R14, DISDPLL);
1003                         break;
1004 
1005         }
1006         
1007         /* enable CTS (not for Baycom), ABORT & DCD interrupts */
1008         wr(scc,R15,((Board & BAYCOM) ? 0 : CTSIE)|BRKIE|DCDIE|TxUIE);
1009 
1010         if(scc->enhanced)
1011         {
1012                 or(scc,R15,SHDLCE|FIFOE);       /* enable FIFO, SDLC/HDLC Enhancements (From now R7 is R7') */
1013                 wr(scc,R7,AUTOEOM);
1014         }
1015 
1016         if((InReg(scc->ctrl,R0)) & DCD)         /* DCD is now ON */
1017         {
1018                 if (scc->modem.clocksrc != CLK_EXTERNAL)
1019                         or(scc,R14, SEARCH);
1020                         
1021                 or(scc,R3,ENT_HM|RxENABLE);     /* enable the receiver, hunt mode */
1022         }
1023         
1024         Outb(scc->ctrl,RES_EXT_INT);    /* reset ext/status interrupts */
1025         Outb(scc->ctrl,RES_EXT_INT);    /* must be done twice */
1026         
1027         scc->status = InReg(scc->ctrl,R0);      /* read initial status */
1028 
1029         or(scc,R1,INT_ALL_Rx|TxINT_ENAB|EXT_INT_ENAB); /* enable interrupts */
1030         or(scc,R9,MIE);                 /* master interrupt enable */
1031                         
1032         restore_flags(flags);
1033         
1034         set_speed(scc); 
1035 }
1036 
1037 
1038 
1039 
1040 /* ******************************************************************** */
1041 /* *                    SCC timer functions                           * */
1042 /* ******************************************************************** */
1043 
1044 
1045 /* ----> scc_key_trx sets the time constant for the baudrate 
1046          generator and keys the transmitter                  <---- */
1047 
1048 static void
1049 scc_key_trx(struct scc_channel *scc, char tx)
     /* [previous][next][first][last][top][bottom][index][help] */
1050 {
1051         unsigned int time_const;
1052 
1053         if (scc->modem.speed < baud_table[1]) 
1054                 scc->modem.speed = 1200;
1055                 
1056         if (Board & PRIMUS)
1057                 Outb(scc->ctrl + 4, Option | (tx? 0x80 : 0));
1058         
1059         time_const = (unsigned) (Clock / (scc->modem.speed * (tx? 2:64))) - 2;
1060         
1061         if (scc->modem.clocksrc == CLK_DPLL)
1062         {                               /* simplex operation */
1063                 if (tx)
1064                 {
1065                         cl(scc,R3,RxENABLE|ENT_HM);     /* then switch off receiver */
1066                         
1067                         set_brg(scc, time_const);       /* reprogram baudrate generator */
1068 
1069                         /* DPLL -> Rx clk, BRG -> Tx CLK, TRxC mode output, TRxC = BRG */
1070                         wr(scc, R11, RCDPLL|TCBR|TRxCOI|TRxCBR);
1071                         
1072                         or(scc,R5,RTS|TxENAB);          /* set the RTS line and enable TX */
1073                 } else {
1074                         cl(scc,R5,RTS|TxENAB);
1075                         
1076                         set_brg(scc, time_const);       /* reprogram baudrate generator */
1077                         
1078                         /* DPLL -> Rx clk, DPLL -> Tx CLK, TRxC mode output, TRxC = DPLL */
1079                         wr(scc, R11, RCDPLL|TCDPLL|TRxCOI|TRxCDP);
1080                         
1081                         or(scc,R3,RxENABLE|ENT_HM);
1082                 }
1083         } else {
1084                 if (tx)
1085                         or(scc,R5,RTS|TxENAB);          /* enable tx */
1086                 else
1087                         cl(scc,R5,RTS|TxENAB);          /* disable tx */
1088         }
1089 }
1090 
1091 
1092 /* ----> SCC timer interrupt handler and friends. Will be called every 1/TPS s <---- */
1093 
1094 static unsigned char Rand = 17;
1095 
1096 static inline int is_grouped(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
1097 {
1098         int k;
1099         struct scc_channel *scc2;
1100         unsigned char grp1, grp2;
1101 
1102         grp1 = scc->kiss.group;
1103         
1104         for (k = 0; k < (Nchips * 2); k++)
1105         {
1106                 scc2 = &SCC_Info[k];
1107                 grp2 = scc2->kiss.group;
1108                 
1109                 if (scc2 == scc || !(scc2->tty && grp2)) 
1110                         return 0;
1111                 
1112                 if ((grp1 & 0x3f) == (grp2 & 0x3f))
1113                 {
1114                         if ( (grp1 & TXGROUP) && (scc2->wreg[R5] & RTS) )
1115                                 return 1;
1116                         
1117                         if ( (grp1 & RXGROUP) && (scc2->status & DCD) )
1118                                 return 1;
1119                 }
1120         }
1121         return 0;
1122 }
1123                 
1124 
1125 static inline void dw_slot_timeout(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
1126 {
1127         scc->t_dwait = TIMER_STOPPED;
1128         scc->t_slot = TIMER_STOPPED;
1129         
1130         if (!scc->kiss.fulldup)
1131         {
1132                 Rand = Rand * 17 + 31;
1133                 
1134                 if ( (scc->kiss.softdcd? !(scc->status & SYNC_HUNT):(scc->status & DCD))  || (scc->kiss.persist) < Rand || (scc->kiss.group && is_grouped(scc)) )
1135                 {
1136                         if (scc->t_mbusy == TIMER_STOPPED)
1137                                 scc->t_mbusy = TPS * scc->kiss.maxdefer;
1138                                 
1139                         scc->t_slot = scc->kiss.slottime;
1140                         return ;
1141                         
1142                 }
1143         }
1144         
1145         if ( !(scc->wreg[R5] & RTS) )
1146         {
1147                 scc->t_txdel = scc->kiss.txdelay;
1148                 scc_key_trx(scc, TX_ON);
1149         } else {
1150                 scc->t_txdel = 0;
1151         }
1152 }
1153 
1154 
1155 
1156 
1157 static inline void txdel_timeout(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
1158 {
1159         scc->t_txdel = TIMER_STOPPED;
1160         
1161         scc->t_maxk = TPS * scc->kiss.maxkeyup;
1162         prepare_next_txframe(scc);
1163         
1164         if (scc->stat.tx_state != TXS_BUSY)
1165                 scc_txint(scc);         
1166 }
1167         
1168 
1169 
1170 static inline void tail_timeout(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
1171 {
1172         scc->t_tail = TIMER_STOPPED;
1173         
1174         /* when fulldup is 0 or 1, switch off the transmitter.
1175          * when frames are still queued (because of transmit time limit),
1176          * restart the procedure to get the channel after MINTIME.
1177          * when fulldup is 2, the transmitter remains keyed and we
1178          * continue sending after waiting for waittime. IDLETIME is an 
1179          * idle timeout in this case.
1180          */ 
1181          
1182          if (scc->kiss.fulldup < 2)
1183          {
1184                 if (scc->sndq)          /* we had a timeout? */
1185                 {
1186                         scc->stat.tx_state = TXS_BUSY;
1187                         scc->t_dwait = TPS * scc->kiss.mintime; /* try again */
1188                 }
1189                 
1190                 scc->stat.tx_state = TXS_IDLE;
1191                 scc->t_maxk = TIMER_STOPPED;
1192                 scc_key_trx(scc, TX_OFF);
1193                 return;
1194          }
1195          
1196          if (scc->sndq)                 /* maxkeyup expired */ /* ?! */
1197          {
1198                 scc->stat.tx_state = TXS_BUSY;
1199                 scc->t_txdel = TPS * scc->kiss.waittime;
1200          }
1201          else
1202          
1203                 scc->t_idle = TPS * scc->kiss.idletime;
1204 }
1205 
1206 
1207 static inline void busy_timeout(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
1208 {
1209 #ifdef  THROW_AWAY_AFTER_BUSY_TIMEOUT
1210         register struct mbuf *bp;               /* not tested */
1211 
1212         bp = scc->sndq;
1213         
1214         while (bp) bp = scc_free_chain(bp, BT_TRANSMIT);
1215         
1216         scc->sndq = NULLBUF;
1217         scc->stat.tx_state = TXS_IDLE;
1218         
1219 #else
1220         scc->t_txdel = scc->kiss.txdelay;       /* brute force ... */
1221 #endif
1222         scc->t_mbusy = TIMER_STOPPED;
1223         
1224 }
1225 
1226 
1227 static inline void maxk_idle_timeout(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
1228 {
1229         scc->t_maxk = TIMER_STOPPED;
1230         scc->t_idle = TIMER_STOPPED;
1231         
1232         scc->stat.tx_state = TXS_BUSY;
1233         scc->t_tail = scc->kiss.tailtime;
1234 }
1235 
1236 static inline void check_rcv_queue(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
1237 {
1238         register struct mbuf *bp;
1239         
1240         if (scc->stat.rx_queued > QUEUE_THRES)
1241         {
1242                 if (scc->rcvq == NULLBUF)
1243                 {
1244                         printk("z8530drv: Warning - scc->stat.rx_queued shows overflow"
1245                                " (%d) but queue is empty\n", scc->stat.rx_queued);
1246                                
1247                         scc->stat.rx_queued = 0;        /* correct it */
1248                         scc->stat.nospace = 12345;      /* draw attention to it */
1249                         return;
1250                 }
1251                         
1252                 bp = scc->rcvq->anext;  /* don't use the one we currently use */
1253                 
1254                 while (bp && (scc->stat.rx_queued > QUEUE_HYST))
1255                 {
1256                         bp = scc_free_chain(bp, BT_RECEIVE);
1257                         scc->stat.rx_queued--;
1258                         scc->stat.nospace++;
1259                 }
1260                 
1261                 scc->rcvq->anext = bp;
1262         }
1263 }
1264 
1265 static void
1266 scc_timer(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1267 {
1268         register struct scc_channel *scc;
1269         register int chan;
1270         unsigned long flags;
1271                 
1272 
1273         for (chan = 0; chan < (Nchips * 2); chan++)
1274         {
1275                 scc = &SCC_Info[chan];
1276                 
1277                 if (scc->tty && scc->init)
1278                 {
1279                         kiss_encode(scc);
1280                         
1281                         save_flags(flags); cli();
1282                         
1283                         check_rcv_queue(scc);
1284                         
1285                         /* KISS-TNC emulation */
1286                         
1287                         if (Expired(t_dwait)) dw_slot_timeout(scc)      ; else
1288                         if (Expired(t_slot))  dw_slot_timeout(scc)      ; else
1289                         if (Expired(t_txdel)) txdel_timeout(scc)        ; else
1290                         if (Expired(t_tail))  tail_timeout(scc)         ;
1291                         
1292                         /* watchdogs */
1293                         
1294                         if (Expired(t_mbusy)) busy_timeout(scc);
1295                         if (Expired(t_maxk))  maxk_idle_timeout(scc);
1296                         if (Expired(t_idle))  maxk_idle_timeout(scc);
1297                         
1298                         restore_flags(flags);
1299                 }
1300         }
1301         
1302         save_flags(flags); cli();
1303         
1304         timer_table[SCC_TIMER].fn = scc_timer;
1305         timer_table[SCC_TIMER].expires = jiffies + HZ/TPS;
1306         timer_active |= 1 << SCC_TIMER; 
1307         
1308         restore_flags(flags);
1309 }
1310                         
1311 
1312 static void
1313 scc_init_timer(struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
1314 {
1315         unsigned long flags;
1316         
1317         save_flags(flags); cli();
1318         
1319         Stop_Timer(t_dwait);
1320         Stop_Timer(t_slot);
1321         Stop_Timer(t_txdel);
1322         Stop_Timer(t_tail);
1323         Stop_Timer(t_mbusy);
1324         Stop_Timer(t_maxk);
1325         Stop_Timer(t_idle);
1326         scc->stat.tx_state = TXS_IDLE;
1327         
1328         restore_flags(flags);
1329 }
1330 
1331 
1332 static void
1333 scc_rx_timer(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1334 {
1335         unsigned long flags;
1336         
1337         kiss_encode(rx_timer_cb.scc);
1338         
1339         save_flags(flags); cli();
1340         
1341         timer_table[SCC_TIMER].fn = scc_timer;
1342         timer_table[SCC_TIMER].expires = jiffies + rx_timer_cb.expires;
1343         timer_active |= 1 << SCC_TIMER;
1344         
1345         rx_timer_cb.lock = 0;
1346         
1347         restore_flags(flags);
1348 }
1349 
1350 
1351 /* ******************************************************************** */
1352 /* *                    KISS interpreter                              * */
1353 /* ******************************************************************** */
1354 
1355 
1356 /*
1357  * this will set the "kiss" parameters through kiss itself
1358  */
1359  
1360 static void
1361 kiss_set_param(struct scc_channel *scc,char cmd, unsigned int val)
     /* [previous][next][first][last][top][bottom][index][help] */
1362 {
1363 
1364 #define  VAL val=val*TPS/100
1365 #define SVAL val? val:TIMER_STOPPED
1366 
1367         switch(cmd){
1368         case PARAM_TXDELAY:
1369                 scc->kiss.txdelay = VAL; break;
1370         case PARAM_PERSIST:
1371                 scc->kiss.persist = val; break;
1372         case PARAM_SLOTTIME:
1373                 scc->kiss.slottime = VAL; break;
1374         case PARAM_TXTAIL:
1375                 scc->kiss.tailtime = VAL; break;
1376         case PARAM_FULLDUP:
1377                 scc->kiss.fulldup = val; break;
1378         case PARAM_WAIT:
1379                 scc->kiss.waittime = VAL; break;
1380         case PARAM_MAXKEY:
1381                 scc->kiss.maxkeyup = SVAL; break;
1382         case PARAM_MIN:
1383                 scc->kiss.mintime = SVAL; break;
1384         case PARAM_IDLE:
1385                 scc->kiss.idletime = val; break;
1386         case PARAM_MAXDEFER:
1387                 scc->kiss.maxdefer = SVAL; break;
1388         case PARAM_GROUP:
1389                 scc->kiss.group = val;  break;
1390         case PARAM_TX:
1391                 scc->kiss.tx_inhibit = val;
1392         case PARAM_SOFTDCD:
1393                 scc->kiss.softdcd = val;
1394         }
1395         return;
1396 
1397 #undef  VAL
1398 #undef SVAL
1399 }
1400 
1401 
1402 /* interpret frame: strip CRC and decode KISS */
1403 
1404 static void kiss_interpret_frame(struct scc_channel * scc)
     /* [previous][next][first][last][top][bottom][index][help] */
1405 {
1406         unsigned char kisscmd;
1407         unsigned long flags;
1408 
1409         if (scc->sndq1->cnt < 2)
1410         {
1411                 if (scc->sndq1) 
1412                         scc_free_chain(scc->sndq1, BT_TRANSMIT);
1413                 else
1414                         scc->sndq1 = NULLBUF;
1415                         
1416                 scc->sndq2 = NULLBUF;
1417                 return;
1418         }
1419         
1420         
1421         
1422         if (scc->kiss.not_slip)
1423         {
1424                 kisscmd = scc->sndq1->data[scc->sndq1->in_use++];
1425                 scc->sndq1->cnt--;
1426         } else {
1427                 kisscmd = 0;
1428         }
1429 
1430         if (kisscmd & 0xa0)
1431         {
1432                 if (scc->sndq1->cnt > 2)
1433                         scc->sndq1->cnt -= 2;
1434                 else
1435                 {
1436                         scc_free_chain(scc->sndq1, BT_TRANSMIT);
1437                         scc->sndq2 = NULLBUF;
1438                         return;
1439                 }
1440         }
1441         
1442         
1443         kisscmd &= 0x1f;
1444         
1445                 
1446         if (kisscmd)
1447         {
1448                 kiss_set_param(scc, kisscmd, scc->sndq1->data[scc->sndq1->in_use]);
1449                 scc->sndq1->cnt=0;
1450                 scc->sndq1->in_use=0;
1451                                         
1452                 scc_free_chain(scc->sndq1, BT_TRANSMIT);
1453                 scc->sndq2 = NULLBUF;
1454                 return;
1455         }
1456         
1457         scc_enqueue(&scc->sndq,scc->sndq1); /* scc_enqueue packet */
1458         scc->stat.txframes++;
1459         scc->stat.tx_queued++;
1460         scc->sndq2 = NULLBUF;           /* acquire a new buffer next time */
1461 
1462         save_flags(flags); cli();
1463 
1464         if(scc->stat.tx_state == TXS_IDLE)
1465         {                               /* when transmitter is idle */
1466                 scc_init_timer(scc);
1467                 scc->stat.tx_state = TXS_BUSY;
1468                 scc->t_dwait = (scc->kiss.fulldup? 0:scc->kiss.waittime);
1469         }
1470         
1471         restore_flags(flags);
1472 }
1473 
1474 static void kiss_store_byte(struct scc_channel *scc, unsigned char ch)
     /* [previous][next][first][last][top][bottom][index][help] */
1475 {
1476         if (scc->sndq2 == NULLBUF) return;
1477         
1478         if(scc->sndq2->cnt == scc->sndq2->size)         /* buffer full? */
1479         {
1480                 if((scc->sndq2 = scc_get_buffer(BT_TRANSMIT)) == NULLBUF)
1481                 {
1482                         printk("\nsccdrv: running out of memory\n");
1483                         return;
1484                 }
1485                 scc_append_to_chain(&scc->sndq1,scc->sndq2);         /* add buffer */
1486         }
1487         
1488         scc->sndq2->data[scc->sndq2->cnt++] = ch;
1489 }
1490 
1491 static inline int kiss_decode(struct scc_channel *scc, unsigned char ch)
     /* [previous][next][first][last][top][bottom][index][help] */
1492 {
1493         switch (scc->stat.tx_kiss_state) 
1494         {
1495                 case KISS_IDLE:
1496                         if (ch == FEND)
1497                         {
1498                                 if (!(scc->sndq2 = scc->sndq1 = scc_get_buffer(BT_TRANSMIT)))
1499                                         return 0;
1500                                         
1501                                 scc->stat.tx_kiss_state = KISS_DATA;
1502                         } else scc->stat.txerrs++;
1503                         break;
1504                                         
1505                 case KISS_DATA:
1506                         if (ch == FESC)
1507                                 scc->stat.tx_kiss_state = KISS_ESCAPE;
1508                         else if (ch == FEND)
1509                         {
1510                                 kiss_interpret_frame(scc);      
1511                                 scc->stat.tx_kiss_state = KISS_IDLE;
1512                         }
1513                         else kiss_store_byte(scc, ch);
1514                         break;
1515                                         
1516                 case KISS_ESCAPE:
1517                         if (ch == TFEND)
1518                         {
1519                                 kiss_store_byte(scc, FEND);
1520                                 scc->stat.tx_kiss_state = KISS_DATA;
1521                         }
1522                         else if (ch == TFESC)
1523                         {
1524                                 kiss_store_byte(scc, FESC);
1525                                 scc->stat.tx_kiss_state = KISS_DATA;
1526                         }
1527                         else
1528                         {
1529                                 scc_free_chain(scc->sndq1, BT_TRANSMIT);
1530                                 scc->sndq2 = NULLBUF;
1531                                 scc->stat.txerrs++;
1532                                 scc->stat.tx_kiss_state = KISS_IDLE;
1533                         }
1534                         break;
1535         } /* switch */
1536         
1537         return 0;
1538         
1539 }
1540 
1541 /* ----> Encode received data and write it to the flip-buffer  <---- */
1542 
1543 /* receive raw frame from SCC. used for AX.25 */
1544 static void
1545 kiss_encode(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
1546 {
1547         struct mbuf *bp,*bp2;
1548         struct tty_struct * tty = scc->tty;
1549         unsigned long flags; 
1550         unsigned char ch;
1551 
1552         if(!scc->rcvq)
1553         {
1554                 scc->stat.rx_kiss_state = KISS_IDLE;
1555                 return;
1556         }
1557         
1558         /* worst case: FEND 0 FESC TFEND -> 4 bytes */
1559         
1560         while(tty->flip.count < TTY_FLIPBUF_SIZE-3)
1561         { 
1562                 if (scc->rcvq->cnt)
1563                 {
1564                         bp = scc->rcvq;
1565                         
1566                         if (scc->stat.rx_kiss_state == KISS_IDLE)
1567                         {
1568                                 tty_insert_flip_char(tty, FEND, 0);
1569                                 
1570                                 if (scc->kiss.not_slip)
1571                                         tty_insert_flip_char(tty, 0, 0);
1572                                         
1573                                 scc->stat.rx_kiss_state = KISS_RXFRAME;
1574                         }
1575                                 
1576                         switch(ch = bp->data[bp->in_use++])
1577                         {
1578                                 case FEND:
1579                                         tty_insert_flip_char(tty, FESC, 0);
1580                                         tty_insert_flip_char(tty, TFEND, 0);
1581                                         break;
1582                                 case FESC:
1583                                         tty_insert_flip_char(tty, FESC, 0);
1584                                         tty_insert_flip_char(tty, TFESC, 0);
1585                                         break;
1586                                 default:
1587                                         tty_insert_flip_char(tty, ch, 0);
1588                         }
1589                         
1590                         bp->cnt--;
1591                         
1592                 } else {
1593                         save_flags(flags); cli();
1594                         
1595                         while (!scc->rcvq->cnt)
1596                         {                                /* buffer empty? */
1597                                 bp  = scc->rcvq->next;  /* next buffer */
1598                                 bp2 = scc->rcvq->anext; /* next packet */
1599                                 
1600                                 
1601                                 scc_return_buffer(scc->rcvq, BT_RECEIVE);
1602                                 
1603                                 if (!bp)        /* end of frame ? */
1604                                 {
1605                                         scc->rcvq = bp2;
1606                                         
1607                                         if (--scc->stat.rx_queued < 0)
1608                                                 scc->stat.rx_queued = 0;
1609                                         
1610                                         if (scc->stat.rx_kiss_state == KISS_RXFRAME)    /* new packet? */
1611                                         {
1612                                                 tty_insert_flip_char(tty, FEND, 0); /* send FEND for old frame */
1613                                                 scc->stat.rx_kiss_state = KISS_IDLE; /* generate FEND for new frame */
1614                                         }
1615                                         
1616                                         restore_flags(flags);
1617                                         queue_task(&tty->flip.tqueue, &tq_timer);
1618                                         return;
1619                                         
1620                                 } else scc->rcvq = bp; /* next buffer */
1621                         }
1622                         
1623                         restore_flags(flags);
1624                 }                                               
1625                 
1626         }
1627         
1628         queue_task(&tty->flip.tqueue, &tq_timer); /* kick it... */
1629 }
1630 
1631 
1632 /* ******************************************************************* */
1633 /* *            Init channel structures, special HW, etc...          * */
1634 /* ******************************************************************* */
1635 
1636 
1637 static void
1638 z8530_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1639 {
1640         struct scc_channel *scc;
1641         int chip;
1642         unsigned long flags;
1643 
1644         /* reset and pre-init all chips in the system */
1645         for (chip = 0; chip < Nchips; chip++)
1646         {
1647                 /* Special SCC cards */
1648 
1649                 if(Board & EAGLE)                       /* this is an EAGLE card */
1650                         Outb(Special_Port,0x08);        /* enable interrupt on the board */
1651                         
1652                 if(Board & (PC100 | PRIMUS))            /* this is a PC100/EAGLE card */
1653                         Outb(Special_Port,Option);      /* set the MODEM mode (0x22) */
1654                         
1655                 /* Init SCC */
1656                 
1657                 scc=&SCC_Info[2*chip];
1658                 if (!scc->ctrl) continue;
1659                 
1660                 save_flags(flags); cli();
1661                 
1662                 /* some general init we can do now */
1663                 
1664                 Outb(scc->ctrl, 0);
1665                 OutReg(scc->ctrl,R9,FHWRES);            /* force hardware reset */
1666                 udelay(100);                            /* give it 'a bit' more time than required */
1667                 wr(scc, R2, chip*16);                   /* interrupt vector */
1668                 wr(scc, R9, VIS);                       /* vector includes status */
1669 
1670                 restore_flags(flags);
1671         }
1672 
1673         if (Ivec == 2) Ivec = 9;                        /* this f... IBM AT-design! */
1674         request_irq(Ivec, scc_isr,   SA_INTERRUPT, "AX.25 SCC");
1675  
1676         Driver_Initialized = 1;
1677 }
1678 
1679 
1680 /* ******************************************************************** */
1681 /* *    Filesystem Routines: open, close, ioctl, settermios, etc      * */
1682 /* ******************************************************************** */
1683 
1684 
1685 
1686 /* scc_paranoia_check(): warn user if something went wrong              */
1687 
1688 static inline int scc_paranoia_check(struct scc_channel *scc, kdev_t device,
     /* [previous][next][first][last][top][bottom][index][help] */
1689                                      const char *routine)
1690 {
1691 #ifdef SCC_PARANOIA_CHECK
1692         static const char *badmagic =
1693                 "Warning: bad magic number for Z8530 SCC struct (%s) in %s\n";
1694         static const char *badinfo =
1695                 "Warning: Z8530 not found for (%s) in %s\n";
1696        
1697         if (!scc->init) 
1698         {
1699                 printk(badinfo, kdevname(device), routine);
1700                 return 1;
1701         }
1702         if (scc->magic != SCC_MAGIC) {
1703                 printk(badmagic, kdevname(device), routine);
1704                 return 1;
1705         }
1706 #endif
1707 
1708         return 0;
1709 }
1710 
1711 
1712 /* ----> this one is called whenever you open the device <---- */
1713 
1714 int scc_open(struct tty_struct *tty, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
1715 {
1716         struct scc_channel *scc;
1717         int chan;
1718         
1719         chan = MINOR(tty->device) - tty->driver.minor_start;
1720         if ((chan < 0) || (chan >= (Nchips * 2)))
1721                 return -ENODEV;
1722  
1723         scc = &SCC_Info[chan];
1724         
1725         tty->driver_data = scc;
1726         tty->termios->c_cflag &= ~CBAUD; 
1727         
1728         if (!Driver_Initialized)
1729                 return 0;
1730         
1731         if (scc->magic != SCC_MAGIC)
1732         {
1733                 printk("ERROR: scc_open(): bad magic number for device ("
1734                        "%s)",
1735                        kdevname(tty->device));
1736                 return -ENODEV;
1737         }               
1738         
1739         if(scc->tty != NULL)
1740         {
1741                 scc->tty_opened++;
1742                 return 0;
1743         }
1744 
1745         if(!scc->init) return 0;
1746                          
1747         scc->tty = tty;
1748         init_channel(scc);
1749 
1750         scc->stat.tx_kiss_state = KISS_IDLE;    /* don't change this... */
1751         scc->stat.rx_kiss_state = KISS_IDLE;    /* ...or this */
1752         
1753         scc_init_timer(scc);
1754         
1755         timer_table[SCC_TIMER].fn = scc_timer;
1756         timer_table[SCC_TIMER].expires = 0;     /* now! */
1757         timer_active |= 1 << SCC_TIMER;
1758         
1759         return 0;
1760 }
1761 
1762 
1763 /* ----> and this whenever you close the device <---- */
1764 
1765 static void
1766 scc_close(struct tty_struct *tty, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
1767 {
1768         struct scc_channel *scc = tty->driver_data;
1769         unsigned long flags;
1770 
1771         if (!scc || (scc->magic != SCC_MAGIC))
1772                 return;
1773         
1774         if(scc->tty_opened)
1775         {
1776                 scc->tty_opened--;
1777                 return;
1778         }
1779         
1780         tty->driver_data = NULLBUF;
1781         
1782         save_flags(flags); cli();
1783         
1784         Outb(scc->ctrl,0);              /* Make sure pointer is written */
1785         wr(scc,R1,0);                   /* disable interrupts */
1786         wr(scc,R3,0);
1787         
1788         scc->tty = NULL;
1789         
1790         restore_flags(flags);
1791         tty->stopped = 0;               
1792 }
1793 
1794 
1795 
1796 
1797 /*
1798  * change scc_speed
1799  */
1800  
1801 static void
1802 scc_change_speed(struct scc_channel * scc)
     /* [previous][next][first][last][top][bottom][index][help] */
1803 {
1804         if (scc->tty == NULL)
1805                 return;
1806                 
1807         scc->modem.speed = baud_table[scc->tty->termios->c_cflag & CBAUD];
1808         
1809         if (scc->stat.tx_state == 0)    /* only switch baudrate on rx... ;-) */
1810                 set_speed(scc);
1811 }
1812 
1813 
1814 /* ----> ioctl-routine of the driver <---- */
1815 
1816 /* perform ioctl on SCC (sdlc) channel
1817  * this is used for AX.25 mode, and will set the "kiss" parameters
1818  */
1819  
1820 /* TIOCMGET     - get modem status      arg: (unsigned long *) arg
1821  * TIOCMBIS     - set PTT               arg: ---
1822  * TIOCMBIC     - reset PTT             arg: ---
1823  * TIOCMBIC     - set PTT               arg: ---
1824  * TIOCSCCINI   - initialize driver     arg: ---
1825  * TIOCCHANINI  - initialize channel    arg: (struct scc_modem *) arg
1826  * TIOCGKISS    - get level 1 parameter arg: (struct ioctl_command *) arg
1827  * TIOCSKISS    - set level 1 parameter arg: (struct ioctl_command *) arg
1828  * TIOCSCCSTAT  - get driver status     arg: (struct scc_stat *) arg
1829  */
1830  
1831 
1832 static int
1833 scc_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1834 {
1835         struct scc_channel * scc = tty->driver_data;
1836         unsigned long flags, r;
1837         unsigned int result;
1838         unsigned int value;
1839         struct ioctl_command kiss_cmd;
1840         int error;
1841 
1842         if (scc->magic != SCC_MAGIC) 
1843         {
1844                 printk("ERROR: scc_ioctl(): bad magic number for device %s", 
1845                         kdevname(tty->device));
1846                         
1847                 return -ENODEV;
1848         }
1849                                                          
1850         r = NO_SUCH_PARAM;
1851         
1852         if (!Driver_Initialized)
1853         {
1854                 if (cmd == TIOCSCCINI)
1855                 {
1856                         if (!suser())
1857                                 return -EPERM;
1858                         
1859                         scc_alloc_buffer_pool();
1860                         z8530_init();
1861                         return 0;
1862                 }
1863                 
1864                 return -EINVAL; /* confuse the user */
1865         }
1866         
1867         if (!scc->init)
1868         {
1869 
1870                 if (cmd == TIOCCHANINI)
1871                 {
1872                         if (!arg)
1873                                 return -EFAULT;
1874                                 
1875                         if (!suser())
1876                                 return -EPERM;
1877                         
1878                         memcpy_fromfs(&scc->modem, (void *) arg, sizeof(struct scc_modem));
1879                         
1880                         /* default KISS Params */
1881                 
1882                         if (scc->modem.speed < 4800)
1883                         {
1884                                 scc->kiss.txdelay = 36*TPS/100;    /* 360 ms */
1885                                 scc->kiss.persist = 42;            /* 25% persistence */                        /* was 25 */
1886                                 scc->kiss.slottime = 16*TPS/100;   /* 160 ms */
1887                                 scc->kiss.tailtime = 4;            /* minimal reasonable value */
1888                                 scc->kiss.fulldup = 0;             /* CSMA */
1889                                 scc->kiss.waittime = 50*TPS/100;   /* 500 ms */
1890                                 scc->kiss.maxkeyup = 10;           /* 10 s */
1891                                 scc->kiss.mintime = 3;             /* 3 s */
1892                                 scc->kiss.idletime = 30;           /* 30 s */
1893                                 scc->kiss.maxdefer = 120;          /* 2 min */
1894                                 scc->kiss.not_slip = 1;            /* KISS mode */
1895                                 scc->kiss.softdcd = 0;             /* hardware dcd */
1896                         } else {
1897                                 scc->kiss.txdelay = 10*TPS/100;    /* 100 ms */
1898                                 scc->kiss.persist = 64;            /* 25% persistence */                        /* was 25 */
1899                                 scc->kiss.slottime = 8*TPS/100;    /* 160 ms */
1900                                 scc->kiss.tailtime = 1;            /* minimal reasonable value */
1901                                 scc->kiss.fulldup = 0;             /* CSMA */
1902                                 scc->kiss.waittime = 50*TPS/100;   /* 500 ms */
1903                                 scc->kiss.maxkeyup = 7;            /* 7 s */
1904                                 scc->kiss.mintime = 3;             /* 3 s */
1905                                 scc->kiss.idletime = 30;           /* 30 s */
1906                                 scc->kiss.maxdefer = 120;          /* 2 min */
1907                                 scc->kiss.not_slip = 1;            /* KISS mode */
1908                                 scc->kiss.softdcd = 0;             /* hardware dcd */
1909                         }
1910                         
1911                         scc->init = 1;                  
1912                         
1913                         return 0;
1914                 }
1915                 
1916                 return -EINVAL;
1917         }
1918 
1919         switch(cmd){
1920         case TCSBRK:
1921                 return 0;
1922         case TIOCMGET:
1923                 error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(unsigned int *));
1924                 if (error)
1925                         return error;
1926 
1927                 save_flags(flags); cli();
1928                 
1929                 result =  ((scc->wreg[R5] & RTS) ? TIOCM_RTS : 0)
1930                         | ((scc->wreg[R5] & DTR) ? TIOCM_DTR : 0)
1931                         | ((InReg(scc->ctrl,R0) & DCD)  ? TIOCM_CAR : 0)
1932                         | ((InReg(scc->ctrl,R0) & CTS)  ? TIOCM_CTS : 0);
1933                 
1934                 restore_flags(flags);
1935                         
1936                 put_user_long(result,(unsigned int *) arg);
1937                 return 0;
1938         case TIOCMBIS:
1939         case TIOCMBIC:
1940         case TIOCMSET:
1941                 switch (cmd) {
1942                 case TIOCMBIS:
1943                         scc->wreg[R5] |= DTR;
1944                         scc->wreg[R5] |= RTS;
1945                         break;
1946                 case TIOCMBIC:
1947                         scc->wreg[R5] &= ~DTR;
1948                         scc->wreg[R5] &= ~RTS;
1949                         break;
1950                 case TIOCMSET:
1951                         value = get_user_long((unsigned int *) arg);
1952                         
1953                         if(value & TIOCM_DTR)
1954                                 scc->wreg[R5] |= DTR;
1955                         else
1956                                 scc->wreg[R5] &= ~DTR;
1957                         if(value & TIOCM_RTS)
1958                                 scc->wreg[R5] |= RTS;
1959                         else
1960                                 scc->wreg[R5] &= ~RTS;
1961                         break;
1962                 }
1963                 
1964                 save_flags(flags); cli();
1965                 
1966                 if(scc->stat.tx_state == TXS_IDLE && !Running(t_idle))
1967                         maxk_idle_timeout(scc);
1968                         
1969                 restore_flags(flags);
1970                 
1971                 return 0;
1972                 
1973         case TCGETS:
1974                 error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct termios));
1975                 if (error)
1976                         return error;
1977                 if (!arg) 
1978                         return -EFAULT;
1979                         
1980                 memcpy_tofs((void *) arg, scc->tty->termios, sizeof(struct termios));
1981                 return 0;
1982                 
1983         case TCSETS:
1984         case TCSETSF:           /* should flush first, but... */
1985         case TCSETSW:           /* should wait 'till flush, but... */
1986                 if (!suser())
1987                         return -EPERM;
1988                 if (!arg)
1989                         return -EFAULT;
1990                 
1991                 memcpy_fromfs(scc->tty->termios, (void *) arg, sizeof(struct termios));
1992                 scc_change_speed(scc);
1993                 return 0;
1994                 
1995                 
1996         case TIOCSCCSTAT:
1997                 error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(struct scc_stat));
1998                 if (error)
1999                         return error;
2000                 
2001                 if (!arg)
2002                         return -EFAULT;
2003                         
2004                 scc->stat.used_buf = scc_count_used_buffers(&scc->stat.rx_alloc, 
2005                                                             &scc->stat.tx_alloc);
2006                         
2007                 memcpy_tofs((void *) arg, &scc->stat, sizeof(struct scc_stat));
2008                 return 0;
2009                 
2010 #define TICKS (100/TPS)
2011 #define CAST(x) (unsigned long)(x)
2012 #define  Val    kiss_cmd.param
2013 #define  VAL    kiss_cmd.param*TPS/100
2014 #define SVAL    kiss_cmd.param? kiss_cmd.param:TIMER_STOPPED
2015 
2016         case TIOCGKISS:
2017                 error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(struct ioctl_command));
2018                 if (error)
2019                         return error;
2020                         
2021                 if (!arg)
2022                         return -EFAULT;
2023                         
2024                 memcpy_fromfs(&kiss_cmd, (void *) arg, sizeof(struct ioctl_command));
2025 
2026                 switch (kiss_cmd.command)
2027                 {
2028                         case PARAM_TXDELAY:     r = CAST(scc->kiss.txdelay*TICKS);      break;
2029                         case PARAM_PERSIST:     r = CAST(scc->kiss.persist);            break;
2030                         case PARAM_SLOTTIME:    r = CAST(scc->kiss.slottime*TICKS);     break;
2031                         case PARAM_TXTAIL:      r = CAST(scc->kiss.tailtime*TICKS);     break;
2032                         case PARAM_FULLDUP:     r = CAST(scc->kiss.fulldup);            break;
2033                         case PARAM_SOFTDCD:     r = CAST(scc->kiss.softdcd);            break;
2034                         case PARAM_DTR:         r = CAST((scc->wreg[R5] & DTR)? 1:0); break;
2035                         case PARAM_RTS:         r = CAST((scc->wreg[R5] & RTS)? 1:0); break;
2036                         case PARAM_SPEED:       r = CAST(scc->modem.speed);     break;
2037                         case PARAM_GROUP:       r = CAST(scc->kiss.group);              break;
2038                         case PARAM_IDLE:        r = CAST(scc->kiss.idletime);           break;
2039                         case PARAM_MIN:         r = CAST(scc->kiss.mintime);            break;
2040                         case PARAM_MAXKEY:      r = CAST(scc->kiss.maxkeyup);           break;
2041                         case PARAM_WAIT:        r = CAST(scc->kiss.waittime);           break;
2042                         case PARAM_MAXDEFER:    r = CAST(scc->kiss.maxdefer);           break;
2043                         case PARAM_TX:          r = CAST(scc->kiss.tx_inhibit); break;
2044                         case PARAM_SLIP:        r = CAST(!scc->kiss.not_slip);          break;
2045                         default:                r = NO_SUCH_PARAM;
2046                 }
2047                 
2048                 kiss_cmd.param = r;
2049                 
2050                 memcpy_tofs((void *) arg, &kiss_cmd, sizeof(struct ioctl_command));
2051                 return 0;
2052                 break;
2053                 
2054         case TIOCSKISS:
2055                 if (!arg)
2056                         return -EFAULT;
2057 
2058                 if (!suser())
2059                         return -EPERM;
2060                         
2061                 memcpy_fromfs(&kiss_cmd, (void *) arg, sizeof(struct ioctl_command));
2062                 
2063                 switch (kiss_cmd.command)
2064                 {
2065                         case PARAM_TXDELAY:     scc->kiss.txdelay=VAL;          break;
2066                         case PARAM_PERSIST:     scc->kiss.persist=Val;          break;
2067                         case PARAM_SLOTTIME:    scc->kiss.slottime=VAL;         break;
2068                         case PARAM_TXTAIL:      scc->kiss.tailtime=VAL;         break;
2069                         case PARAM_FULLDUP:     scc->kiss.fulldup=Val;          break;
2070                         case PARAM_SOFTDCD:     scc->kiss.softdcd=Val;          break;
2071                         case PARAM_DTR:         break; /* does someone need this? */
2072                         case PARAM_RTS:         break; /* or this? */
2073                         case PARAM_SPEED:       scc->modem.speed=Val;           break;
2074                         case PARAM_GROUP:       scc->kiss.group=Val;            break;
2075                         case PARAM_IDLE:        scc->kiss.idletime=Val;         break;
2076                         case PARAM_MIN:         scc->kiss.mintime=SVAL;         break;
2077                         case PARAM_MAXKEY:      scc->kiss.maxkeyup=SVAL;        break;
2078                         case PARAM_WAIT:        scc->kiss.waittime=Val;         break;
2079                         case PARAM_MAXDEFER:    scc->kiss.maxdefer=SVAL;        break;
2080                         case PARAM_TX:          scc->kiss.tx_inhibit=Val;       break;
2081                         case PARAM_SLIP:        scc->kiss.not_slip=!Val;        break;
2082                         default:                return -ENOIOCTLCMD;
2083                 }
2084                 
2085                 return 0;
2086                 break;
2087 #undef TICKS
2088 #undef CAST
2089 #undef VAL
2090 #undef SVAL
2091 #undef Val
2092                 
2093         default:
2094                 return -ENOIOCTLCMD;
2095     }
2096 }
2097 
2098 
2099 /* ----- TERMIOS function ----- */
2100 
2101 static void
2102 scc_set_termios(struct tty_struct * tty, struct termios * old_termios)
     /* [previous][next][first][last][top][bottom][index][help] */
2103 {
2104         if (tty->termios->c_cflag == old_termios->c_cflag) 
2105                 return;
2106         scc_change_speed(tty->driver_data);
2107 }
2108 
2109 
2110 static inline void check_tx_queue(register struct scc_channel *scc)
     /* [previous][next][first][last][top][bottom][index][help] */
2111 {
2112         register struct mbuf *bp;
2113         
2114         if (scc->stat.tx_queued > QUEUE_THRES)
2115         {
2116                 if (scc->sndq1 == NULLBUF)
2117                 {
2118                         printk("z8530drv: Warning - scc->stat.tx_queued shows overflow"
2119                                " (%d) but queue is empty\n", scc->stat.tx_queued);
2120                                
2121                         scc->stat.tx_queued = 0;        /* correct it */
2122                         scc->stat.nospace = 54321;      /* draw attention to it */
2123                         return;
2124                 }
2125                         
2126                 bp = scc->sndq1->anext; /* don't use the one we currently use */
2127                 
2128                 while (bp && (scc->stat.tx_queued > QUEUE_HYST))
2129                 {
2130                         bp = scc_free_chain(bp, BT_TRANSMIT);
2131                         scc->stat.tx_queued--;
2132                         scc->stat.nospace++;
2133                 }
2134                 
2135                 scc->sndq1->anext = bp;
2136         }
2137 }
2138 
2139 
2140 
2141 /* ----> tx routine: decode KISS data and scc_enqueue it <---- */
2142 
2143 /* send raw frame to SCC. used for AX.25 */
2144 int scc_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
2145 {
2146         struct scc_channel * scc = tty->driver_data;
2147         unsigned char tbuf[BUFSIZE], *p;
2148         int cnt, cnt2;
2149         
2150         if (!tty) return count;
2151         
2152         if (scc_paranoia_check(scc, tty->device, "scc_write"))
2153                 return 0;
2154 
2155         if (scc->kiss.tx_inhibit) return count;
2156         
2157         check_tx_queue(scc);
2158 
2159         cnt2 = count;
2160         
2161         while (cnt2)
2162         {
2163                 cnt   = cnt2 > BUFSIZE? BUFSIZE:cnt2;
2164                 cnt2 -= cnt;
2165                 
2166                 if (from_user)
2167                         memcpy_fromfs(tbuf, buf, cnt);
2168                 else
2169                         memcpy(tbuf, buf, cnt);
2170                 
2171                 buf += cnt;
2172                         
2173                 p=tbuf;
2174                 
2175                 while(cnt--) 
2176                   if (kiss_decode(scc, *p++))
2177                   {
2178                         scc->stat.nospace++;
2179                         return 0;
2180                   }
2181                         
2182         } /* while cnt2 */
2183         
2184         return count;
2185 }
2186                                 
2187 
2188 /* put a single char into the buffer */
2189 
2190 static void scc_put_char(struct tty_struct * tty, unsigned char ch)
     /* [previous][next][first][last][top][bottom][index][help] */
2191 {
2192         struct scc_channel *scc = tty->driver_data;
2193         unsigned char ch2;
2194         
2195         if (scc_paranoia_check(scc, tty->device, "scc_put_char"))
2196                 return;
2197                 
2198         ch2 = ch;
2199         scc_write(tty, 0, &ch2, 1);     /* that's all */
2200 }
2201 
2202 static void scc_flush_chars(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
2203 {
2204         struct scc_channel *scc = tty->driver_data;
2205         
2206         scc_paranoia_check(scc, tty->device, "scc_flush_chars"); /* just to annoy the user... */
2207         
2208         return; /* no flush needed */
2209 }
2210 
2211 /* the kernel does NOT use this routine yet... */
2212 
2213 static int scc_write_room(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
2214 {
2215         struct scc_channel *scc = tty->driver_data;
2216         
2217         if (scc_paranoia_check(scc, tty->device, "scc_write_room"))
2218                 return 0;
2219         
2220         if (scc->stat.tx_alloc >= QUEUE_THRES)
2221         {
2222                 printk("scc_write_room(): buffer full (ignore)\n");
2223                 return 0;
2224         }
2225                 
2226         return BUFSIZE;
2227 }
2228 
2229 static int scc_chars_in_buffer(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
2230 {
2231         struct scc_channel *scc = tty->driver_data;
2232         
2233         if (scc && scc->sndq2)
2234                 return scc->sndq2->cnt;
2235         else
2236                 return 0;
2237 }
2238 
2239 static void scc_flush_buffer(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
2240 {
2241         struct scc_channel *scc = tty->driver_data;
2242         
2243         if (scc_paranoia_check(scc, tty->device, "scc_flush_buffer"))
2244                 return;
2245                 
2246         scc->stat.tx_kiss_state = KISS_IDLE;
2247         
2248         wake_up_interruptible(&tty->write_wait);
2249         if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
2250             tty->ldisc.write_wakeup)
2251                 (tty->ldisc.write_wakeup)(tty);
2252 }
2253 
2254 static void scc_throttle(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
2255 {
2256         struct scc_channel *scc = tty->driver_data;
2257         
2258         if (scc_paranoia_check(scc, tty->device, "scc_throttle"))
2259                 return;
2260                 
2261                 
2262         /* dummy */
2263 }
2264 
2265 static void scc_unthrottle(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
2266 {
2267         struct scc_channel *scc = tty->driver_data;
2268         
2269         if (scc_paranoia_check(scc, tty->device, "scc_unthrottle"))
2270                 return;
2271                 
2272         /* dummy */
2273 }
2274 
2275 static void scc_start(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
2276 {
2277         struct scc_channel *scc = tty->driver_data;
2278         
2279         if (scc_paranoia_check(scc, tty->device, "scc_start"))
2280                 return;
2281                 
2282         /* dummy */
2283 }
2284                                                         
2285 
2286 static void scc_stop(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
2287 {
2288         struct scc_channel *scc = tty->driver_data;
2289         
2290         if (scc_paranoia_check(scc, tty->device, "scc_stop"))
2291                 return;
2292                 
2293         /* dummy */
2294 }
2295 
2296 
2297 /* ******************************************************************** */
2298 /* *                    Init SCC driver                               * */
2299 /* ******************************************************************** */
2300 
2301 int scc_init (void)
     /* [previous][next][first][last][top][bottom][index][help] */
2302 {
2303         int chip, chan;
2304         register io_port ctrl;
2305         long flags;
2306         
2307         
2308         memset(&scc_driver, 0, sizeof(struct tty_driver));
2309         scc_driver.magic = TTY_DRIVER_MAGIC;
2310         scc_driver.name = "sc";
2311         scc_driver.major = Z8530_MAJOR;         
2312         scc_driver.minor_start = 0;
2313         scc_driver.num = Nchips*2;
2314         scc_driver.type = TTY_DRIVER_TYPE_SERIAL;
2315         scc_driver.subtype = 0;                 /* not needed */
2316         scc_driver.init_termios = tty_std_termios;
2317         scc_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2318         scc_driver.flags = TTY_DRIVER_REAL_RAW;
2319         scc_driver.refcount = &scc_refcount;    /* not needed yet */
2320         scc_driver.table = scc_table;
2321         scc_driver.termios = (struct termios **) scc_termios;
2322         scc_driver.termios_locked = (struct termios **) scc_termios_locked;
2323         scc_driver.open = scc_open;
2324         scc_driver.close = scc_close;
2325         scc_driver.write = scc_write;
2326         scc_driver.start = scc_start;
2327         scc_driver.stop = scc_stop;
2328         
2329         scc_driver.put_char = scc_put_char;
2330         scc_driver.flush_chars = scc_flush_chars;        
2331         scc_driver.write_room = scc_write_room;
2332         scc_driver.chars_in_buffer = scc_chars_in_buffer;
2333         scc_driver.flush_buffer = scc_flush_buffer;
2334         
2335         scc_driver.throttle = scc_throttle;
2336         scc_driver.unthrottle = scc_unthrottle;
2337         
2338         scc_driver.ioctl = scc_ioctl;
2339         scc_driver.set_termios = scc_set_termios;
2340         
2341         if (tty_register_driver(&scc_driver))
2342            panic("Couldn't register Z8530 SCC driver\n");
2343                                 
2344         printk (BANNER);
2345         
2346         if (Nchips > MAXSCC) Nchips = MAXSCC;   /* to avoid the "DAU" (duemmster anzunehmender User) */
2347 
2348         /* reset and pre-init all chips in the system */
2349         
2350         for (chip = 0; chip < Nchips; chip++)
2351         {
2352                 memset((char *) &SCC_Info[2*chip  ], 0, sizeof(struct scc_channel));
2353                 memset((char *) &SCC_Info[2*chip+1], 0, sizeof(struct scc_channel));
2354                 
2355                 ctrl = SCC_ctrl[chip * 2];
2356                 if (!ctrl) continue;
2357 
2358                 save_flags(flags); cli();       /* because of 2-step accesses */
2359                 
2360 
2361 /* Hmm... this may fail on fast systems with cards who don't delay the INTACK */
2362 /* If you are sure you specified the right port addresses and the driver doesn't */
2363 /* recognize the chips, define DONT_CHECK in scc_config.h */
2364 
2365 #ifndef DONT_CHECK
2366                 check_region(ctrl, 1);
2367 
2368                 Outb(ctrl, 0);
2369                 OutReg(ctrl,R13,0x55);          /* is this chip realy there? */
2370                 
2371                 if (InReg(ctrl,R13) != 0x55 )
2372                 {
2373                         restore_flags(flags);
2374                         continue;
2375                 }
2376 #endif
2377                 
2378                 SCC_Info[2*chip  ].magic    = SCC_MAGIC;
2379                 SCC_Info[2*chip  ].ctrl     = SCC_ctrl[2*chip];
2380                 SCC_Info[2*chip  ].data     = SCC_data[2*chip];
2381                 SCC_Info[2*chip  ].enhanced = SCC_Enhanced[chip];
2382                         
2383                 SCC_Info[2*chip+1].magic    = SCC_MAGIC;
2384                 SCC_Info[2*chip+1].ctrl     = SCC_ctrl[2*chip+1];
2385                 SCC_Info[2*chip+1].data     = SCC_data[2*chip+1];
2386                 SCC_Info[2*chip+1].enhanced = SCC_Enhanced[chip];
2387 
2388  
2389                 restore_flags(flags);
2390         }
2391 
2392 #ifdef DO_FAST_RX
2393         rx_timer_cb.lock = 0;
2394 #else
2395         rx_timer_cb.lock = 1;
2396 #endif
2397         
2398 #ifdef VERBOSE_BOOTMSG
2399         printk("Init Z8530 driver: %u channels, using irq %u\n",Nchips*2,Ivec);
2400         
2401 
2402         for (chan = 0; chan < Nchips * 2 ; chan++)
2403         {
2404                 printk("/dev/%s%i: data port = 0x%3.3x  control port = 0x%3.3x -- %s\n",
2405                         scc_driver.name, chan, SCC_data[chan], SCC_ctrl[chan],
2406                         SCC_Info[chan].ctrl? "found"   : "missing");
2407                         
2408                 if (SCC_Info[chan].ctrl == 0) 
2409                 {
2410                         SCC_ctrl[chan] = 0;
2411                 } else {
2412                         request_region(SCC_ctrl[chan], 1, "scc ctrl");
2413                         request_region(SCC_data[chan], 1, "scc data");
2414                 }
2415         }
2416 #else
2417         printk("Init Z8530 driver: %u channels\n",Nchips*2);
2418 #endif
2419 
2420         
2421         return 0;
2422 }
2423 #endif

/* [previous][next][first][last][top][bottom][index][help] */