root/drivers/char/cyclades.c

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

DEFINITIONS

This source file includes following definitions.
  1. serial_paranoia_check
  2. SP
  3. CP
  4. CP1
  5. CP2
  6. CP4
  7. CP8
  8. write_cy_cmd
  9. cy_stop
  10. cy_start
  11. cy_sched_event
  12. cy_probe
  13. cy_interrupt
  14. do_cyclades_bh
  15. do_softint
  16. grab_all_interrupts
  17. free_all_interrupts
  18. check_wild_interrupts
  19. get_auto_irq
  20. do_auto_irq
  21. startup
  22. start_xmit
  23. shutdown
  24. config_setup
  25. cy_put_char
  26. cy_flush_chars
  27. cy_write
  28. cy_write_room
  29. cy_chars_in_buffer
  30. cy_flush_buffer
  31. cy_throttle
  32. cy_unthrottle
  33. get_serial_info
  34. set_serial_info
  35. get_modem_info
  36. set_modem_info
  37. send_break
  38. cy_ioctl
  39. cy_set_termios
  40. cy_close
  41. cy_hangup
  42. block_til_ready
  43. cy_open
  44. show_version
  45. cy_init_card
  46. cy_init
  47. show_status

   1 static char rcsid[] =
   2 "$Revision: 1.35 $$Date: 1994/12/16 13:54:18 $";
   3 /*
   4  *  linux/kernel/cyclades.c
   5  *
   6  * Much of the design and some of the code came from serial.c
   7  * which was copyright (C) 1991, 1992  Linus Torvalds.  It was
   8  * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92,
   9  * and then fixed as suggested by Michael K. Johnson 12/12/92.
  10  *
  11  * This version does not support shared irq's.
  12  *
  13  * This module exports the following rs232 io functions:
  14  *   long cy_init(long);
  15  *   int  cy_open(struct tty_struct *tty, struct file *filp);
  16  *
  17  * $Log: cyclades.c,v $
  18  * Revision 1.35  1994/12/16  13:54:18  steffen
  19  * additional patch by Marcio Saito for board detection
  20  * Accidently left out in 1.34
  21  *
  22  * Revision 1.34  1994/12/10  12:37:12  steffen
  23  * This is the corrected version as suggested by Marcio Saito
  24  *
  25  * Revision 1.33  1994/12/01  22:41:18  bentson
  26  * add hooks to support more high speeds directly; add tytso
  27  * patch regarding CLOCAL wakeups
  28  *
  29  * Revision 1.32  1994/11/23  19:50:04  bentson
  30  * allow direct kernel control of higher signalling rates;
  31  * look for cards at additional locations
  32  *
  33  * Revision 1.31  1994/11/16  04:33:28  bentson
  34  * ANOTHER fix from Corey Minyard, minyard@wf-rch.cirr.com--
  35  * a problem in chars_in_buffer has been resolved by some
  36  * small changes;  this should yield smoother output
  37  *
  38  * Revision 1.30  1994/11/16  04:28:05  bentson
  39  * Fix from Corey Minyard, Internet: minyard@metronet.com,
  40  * UUCP: minyard@wf-rch.cirr.com, WORK: minyardbnr.ca, to
  41  * cy_hangup that appears to clear up much (all?) of the
  42  * DTR glitches; also he's added/cleaned-up diagnostic messages
  43  *
  44  * Revision 1.29  1994/11/16  04:16:07  bentson
  45  * add change proposed by Ralph Sims, ralphs@halcyon.com, to
  46  * operate higher speeds in same way as other serial ports;
  47  * add more serial ports (for up to two 16-port muxes).
  48  *
  49  * Revision 1.28  1994/11/04  00:13:16  root
  50  * turn off diagnostic messages
  51  *
  52  * Revision 1.27  1994/11/03  23:46:37  root
  53  * bunch of changes to bring driver into greater conformance
  54  * with the serial.c driver (looking for missed fixes)
  55  *
  56  * Revision 1.26  1994/11/03  22:40:36  root
  57  * automatic interrupt probing fixed.
  58  *
  59  * Revision 1.25  1994/11/03  20:17:02  root
  60  * start to implement auto-irq
  61  *
  62  * Revision 1.24  1994/11/03  18:01:55  root
  63  * still working on modem signals--trying not to drop DTR
  64  * during the getty/login processes
  65  *
  66  * Revision 1.23  1994/11/03  17:51:36  root
  67  * extend baud rate support; set receive threshold as function
  68  * of baud rate; fix some problems with RTS/CTS;
  69  *
  70  * Revision 1.22  1994/11/02  18:05:35  root
  71  * changed arguments to udelay to type long to get
  72  * delays to be of correct duration
  73  *
  74  * Revision 1.21  1994/11/02  17:37:30  root
  75  * employ udelay (after calibrating loops_per_second earlier
  76  * in init/main.c) instead of using home-grown delay routines
  77  *
  78  * Revision 1.20  1994/11/02  03:11:38  root
  79  * cy_chars_in_buffer forces a return value of 0 to let
  80  * login work (don't know why it does); some functions
  81  * that were returning EFAULT, now executes the code;
  82  * more work on deciding when to disable xmit interrupts;
  83  *
  84  * Revision 1.19  1994/11/01  20:10:14  root
  85  * define routine to start transmission interrupts (by enabling
  86  * transmit interrupts); directly enable/disable modem interrupts;
  87  *
  88  * Revision 1.18  1994/11/01  18:40:45  bentson
  89  * Don't always enable transmit interrupts in startup; interrupt on
  90  * TxMpty instead of TxRdy to help characters get out before shutdown;
  91  * restructure xmit interrupt to check for chars first and quit if
  92  * none are ready to go; modem status (MXVRx) is upright, _not_ inverted
  93  * (to my view);
  94  *
  95  * Revision 1.17  1994/10/30  04:39:45  bentson
  96  * rename serial_driver and callout_driver to cy_serial_driver and
  97  * cy_callout_driver to avoid linkage interference; initialize
  98  * info->type to PORT_CIRRUS; ruggedize paranoia test; elide ->port
  99  * from cyclades_port structure; add paranoia check to cy_close;
 100  *
 101  * Revision 1.16  1994/10/30  01:14:33  bentson
 102  * change major numbers; add some _early_ return statements;
 103  *
 104  * Revision 1.15  1994/10/29  06:43:15  bentson
 105  * final tidying up for clean compile;  enable some error reporting
 106  *
 107  * Revision 1.14  1994/10/28  20:30:22  Bentson
 108  * lots of changes to drag the driver towards the new tty_io
 109  * structures and operation.  not expected to work, but may
 110  * compile cleanly.
 111  *
 112  * Revision 1.13  1994/07/21  23:08:57  Bentson
 113  * add some diagnostic cruft; support 24 lines (for testing
 114  * both -8Y and -16Y cards; be more thorough in servicing all
 115  * chips during interrupt; add "volatile" a few places to
 116  * circumvent compiler optimizations; fix base & offset
 117  * computations in block_til_ready (was causing chip 0 to
 118  * stop operation)
 119  *
 120  * Revision 1.12  1994/07/19  16:42:11  Bentson
 121  * add some hackery for kernel version 1.1.8; expand
 122  * error messages; refine timing for delay loops and
 123  * declare loop params volatile
 124  *
 125  * Revision 1.11  1994/06/11  21:53:10  bentson
 126  * get use of save_car right in transmit interrupt service
 127  *
 128  * Revision 1.10.1.1  1994/06/11  21:31:18  bentson
 129  * add some diagnostic printing; try to fix save_car stuff
 130  *
 131  * Revision 1.10  1994/06/11  20:36:08  bentson
 132  * clean up compiler warnings
 133  *
 134  * Revision 1.9  1994/06/11  19:42:46  bentson
 135  * added a bunch of code to support modem signalling
 136  *
 137  * Revision 1.8  1994/06/11  17:57:07  bentson
 138  * recognize break & parity error
 139  *
 140  * Revision 1.7  1994/06/05  05:51:34  bentson
 141  * Reorder baud table to be monotonic; add cli to CP; discard
 142  * incoming characters and status if the line isn't open; start to
 143  * fold code into cy_throttle; start to port get_serial_info,
 144  * set_serial_info, get_modem_info, set_modem_info, and send_break
 145  * from serial.c; expand cy_ioctl; relocate and expand config_setup;
 146  * get flow control characters from tty struct; invalidate ports w/o
 147  * hardware;
 148  *
 149  * Revision 1.6  1994/05/31  18:42:21  bentson
 150  * add a loop-breaker in the interrupt service routine;
 151  * note when port is initialized so that it can be shut
 152  * down under the right conditions; receive works without
 153  * any obvious errors
 154  *
 155  * Revision 1.5  1994/05/30  00:55:02  bentson
 156  * transmit works without obvious errors
 157  *
 158  * Revision 1.4  1994/05/27  18:46:27  bentson
 159  * incorporated more code from lib_y.c; can now print short
 160  * strings under interrupt control to port zero; seems to
 161  * select ports/channels/lines correctly
 162  *
 163  * Revision 1.3  1994/05/25  22:12:44  bentson
 164  * shifting from multi-port on a card to proper multiplexor
 165  * data structures;  added skeletons of most routines
 166  *
 167  * Revision 1.2  1994/05/19  13:21:43  bentson
 168  * start to crib from other sources
 169  *
 170  */
 171 
 172 #include <linux/errno.h>
 173 #include <linux/signal.h>
 174 #include <linux/sched.h>
 175 #include <linux/timer.h>
 176 #include <linux/tty.h>
 177 #include <linux/serial.h>
 178 #include <linux/interrupt.h>
 179 #include <linux/string.h>
 180 #include <linux/fcntl.h>
 181 #include <linux/ptrace.h>
 182 #include <linux/cyclades.h>
 183 #include <linux/delay.h>
 184 #include <linux/major.h>
 185 
 186 #include <asm/system.h>
 187 #include <asm/io.h>
 188 #include <asm/segment.h>
 189 #include <asm/bitops.h>
 190 
 191 #define small_delay(x) for(j=0;j<x;j++)k++;
 192 
 193 
 194 #define SERIAL_PARANOIA_CHECK
 195 #undef  SERIAL_DEBUG_OPEN
 196 #undef  SERIAL_DEBUG_THROTTLE
 197 #undef  SERIAL_DEBUG_OTHER
 198 #undef  SERIAL_DEBUG_IO
 199 #undef  SERIAL_DEBUG_COUNT
 200 #undef  SERIAL_DEBUG_DTR
 201 
 202 #ifndef MIN
 203 #define MIN(a,b)        ((a) < (b) ? (a) : (b))
 204 #endif
 205 
 206 #define WAKEUP_CHARS 256
 207 
 208 #define STD_COM_FLAGS (0)
 209 
 210 #define SERIAL_TYPE_NORMAL  1
 211 #define SERIAL_TYPE_CALLOUT 2
 212 
 213 
 214 DECLARE_TASK_QUEUE(tq_cyclades);
 215 
 216 struct tty_driver cy_serial_driver, cy_callout_driver;
 217 
 218 static volatile int cy_irq_triggered;
 219 static volatile int cy_triggered;
 220 static int cy_wild_int_mask;
 221 static unsigned char *intr_base_addr;
 222 
 223 /* This is the per-card data structure */
 224 struct cyclades_card cy_card[] = {
 225  /* BASE_ADDR */
 226     {0xD0000,0},
 227     {0xD2000,0},
 228     {0xD4000,10},
 229     {0xD6000,11},
 230     {0xD8000,12},
 231     {0xDA000,15}
 232 };
 233 
 234 #define NR_CARDS        (sizeof(cy_card)/sizeof(struct cyclades_card))
 235 
 236 /*  No need has yet been found for this per-chip data structure
 237  *  struct cyclades_chip cy_chip[] = {
 238  *          {0}
 239  *  };
 240  *  #define NR_CHIPS  (sizeof(cy_chip)/sizeof(struct cyclades_chip))
 241  */
 242 
 243 /* This is the per-port data structure */
 244 struct cyclades_port cy_port[] = {
 245       /* CARD#  */
 246         {-1 },      /* ttyC0 */
 247         {-1 },      /* ttyC1 */
 248         {-1 },      /* ttyC2 */
 249         {-1 },      /* ttyC3 */
 250         {-1 },      /* ttyC4 */
 251         {-1 },      /* ttyC5 */
 252         {-1 },      /* ttyC6 */
 253         {-1 },      /* ttyC7 */
 254         {-1 },      /* ttyC8 */
 255         {-1 },      /* ttyC9 */
 256         {-1 },      /* ttyC10 */
 257         {-1 },      /* ttyC11 */
 258         {-1 },      /* ttyC12 */
 259         {-1 },      /* ttyC13 */
 260         {-1 },      /* ttyC14 */
 261         {-1 },      /* ttyC15 */
 262         {-1 },      /* ttyC16 */
 263         {-1 },      /* ttyC17 */
 264         {-1 },      /* ttyC18 */
 265         {-1 },      /* ttyC19 */
 266         {-1 },      /* ttyC20 */
 267         {-1 },      /* ttyC21 */
 268         {-1 },      /* ttyC22 */
 269         {-1 },      /* ttyC23 */
 270         {-1 },      /* ttyC24 */
 271         {-1 },      /* ttyC25 */
 272         {-1 },      /* ttyC26 */
 273         {-1 },      /* ttyC27 */
 274         {-1 },      /* ttyC28 */
 275         {-1 },      /* ttyC29 */
 276         {-1 },      /* ttyC30 */
 277         {-1 }       /* ttyC31 */
 278 };
 279 #define NR_PORTS        (sizeof(cy_port)/sizeof(struct cyclades_port))
 280 
 281 static int serial_refcount;
 282 
 283 static struct tty_struct *serial_table[NR_PORTS];
 284 static struct termios *serial_termios[NR_PORTS];
 285 static struct termios *serial_termios_locked[NR_PORTS];
 286 
 287 
 288 /* This is the per-irq data structure,
 289                it maps an irq to the corresponding card */
 290 struct cyclades_card * IRQ_cards[16];
 291 
 292 
 293 /*
 294  * tmp_buf is used as a temporary buffer by serial_write.  We need to
 295  * lock it in case the memcpy_fromfs blocks while swapping in a page,
 296  * and some other program tries to do a serial write at the same time.
 297  * Since the lock will only come under contention when the system is
 298  * swapping and available memory is low, it makes sense to share one
 299  * buffer across all the serial ports, since it significantly saves
 300  * memory if large numbers of serial ports are open.
 301  */
 302 static unsigned char *tmp_buf = 0;
 303 static struct semaphore tmp_buf_sem = MUTEX;
 304 
 305 /*
 306  * This is used to look up the divisor speeds and the timeouts
 307  * We're normally limited to 15 distinct baud rates.  The extra
 308  * are accessed via settings in info->flags.
 309  *         0,     1,     2,     3,     4,     5,     6,     7,     8,     9,
 310  *        10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
 311  *                                                  HI            VHI
 312  */
 313 static int baud_table[] = {
 314            0,    50,    75,   110,   134,   150,   200,   300,   600,  1200,
 315         1800,  2400,  4800,  9600, 19200, 38400, 57600, 76800,115200,150000,
 316         0};
 317 
 318 static char baud_co[] = {  /* 25 MHz clock option table */
 319         /* value =>    00    01   02    03    04 */
 320         /* divide by    8    32   128   512  2048 */
 321         0x00,  0x04,  0x04,  0x04,  0x04,  0x04,  0x03,  0x03,  0x03,  0x02,
 322         0x02,  0x02,  0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00};
 323 
 324 static char baud_bpr[] = {  /* 25 MHz baud rate period table */
 325         0x00,  0xf5,  0xa3,  0x6f,  0x5c,  0x51,  0xf5,  0xa3,  0x51,  0xa3,
 326         0x6d,  0x51,  0xa3,  0x51,  0xa3,  0x51,  0x36,  0x29,  0x1b,  0x15};
 327 
 328 static char baud_cor3[] = {  /* receive threshold */
 329         0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,
 330         0x0a,  0x0a,  0x0a,  0x08,  0x04,  0x02,  0x01,  0x01,  0x01,  0x01};
 331 
 332 
 333 
 334 static void shutdown(struct cyclades_port *);
 335 static int startup (struct cyclades_port *);
 336 static void cy_throttle(struct tty_struct *);
 337 static void cy_unthrottle(struct tty_struct *);
 338 static void config_setup(struct cyclades_port *);
 339 extern void console_print(const char *);
 340 static void show_status(int);
 341 
 342 
 343 
 344 static inline int
 345 serial_paranoia_check(struct cyclades_port *info,
     /* [previous][next][first][last][top][bottom][index][help] */
 346                         dev_t device, const char *routine)
 347 {
 348 #ifdef SERIAL_PARANOIA_CHECK
 349     static const char *badmagic =
 350         "Warning: bad magic number for serial struct (%d, %d) in %s\n";
 351     static const char *badinfo =
 352         "Warning: null cyclades_port for (%d, %d) in %s\n";
 353     static const char *badrange =
 354         "Warning: cyclades_port out of range for (%d, %d) in %s\n";
 355 
 356     if (!info) {
 357         printk(badinfo, MAJOR(device), MINOR(device), routine);
 358         return 1;
 359     }
 360 
 361     if( (long)info < (long)(&cy_port[0])
 362     || (long)(&cy_port[NR_PORTS]) < (long)info ){
 363         printk(badrange, MAJOR(device), MINOR(device), routine);
 364         return 1;
 365     }
 366 
 367     if (info->magic != CYCLADES_MAGIC) {
 368         printk(badmagic, MAJOR(device), MINOR(device), routine);
 369         return 1;
 370     }
 371 #endif
 372         return 0;
 373 } /* serial_paranoia_check */
 374 
 375 /* The following diagnostic routines allow the driver to spew
 376    information on the screen, even (especially!) during interrupts.
 377  */
 378 void
 379 SP(char *data){
     /* [previous][next][first][last][top][bottom][index][help] */
 380   unsigned long flags;
 381     save_flags(flags); cli();
 382         console_print(data);
 383     restore_flags(flags);
 384 }
 385 char scrn[2];
 386 void
 387 CP(char data){
     /* [previous][next][first][last][top][bottom][index][help] */
 388   unsigned long flags;
 389     save_flags(flags); cli();
 390         scrn[0] = data;
 391         console_print(scrn);
 392     restore_flags(flags);
 393 }/* CP */
 394 
 395 void CP1(int data) { (data<10)?  CP(data+'0'): CP(data+'A'-10); }/* CP1 */
     /* [previous][next][first][last][top][bottom][index][help] */
 396 void CP2(int data) { CP1((data>>4) & 0x0f); CP1( data & 0x0f); }/* CP2 */
     /* [previous][next][first][last][top][bottom][index][help] */
 397 void CP4(int data) { CP2((data>>8) & 0xff); CP2(data & 0xff); }/* CP4 */
     /* [previous][next][first][last][top][bottom][index][help] */
 398 void CP8(long data) { CP4((data>>16) & 0xffff); CP4(data & 0xffff); }/* CP8 */
     /* [previous][next][first][last][top][bottom][index][help] */
 399 
 400 
 401 /* This routine waits up to 100 micro-seconds for the previous
 402    command to the Cirrus chip to complete and then issues the
 403    new command.  An error is returned if the previous command
 404    didn't finish within the time limit.
 405  */
 406 u_short
 407 write_cy_cmd(u_char *base_addr, u_char cmd)
     /* [previous][next][first][last][top][bottom][index][help] */
 408 {
 409   unsigned long flags;
 410   volatile int  i;
 411 
 412     save_flags(flags); cli();
 413         /* Check to see that the previous command has completed */
 414         for(i = 0 ; i < 10000 ; i++){
 415             if (base_addr[CyCCR] == 0){
 416                 break;
 417             }
 418             udelay(10L);
 419         }
 420         /* if the CCR never cleared, the previous command
 421             didn't finish within the "reasonable time" */
 422         if ( i == 10 ) {
 423             restore_flags(flags);
 424             return (-1);
 425         }
 426 
 427         /* Issue the new command */
 428         base_addr[CyCCR] = cmd;
 429     restore_flags(flags);
 430     return(0);
 431 } /* write_cy_cmd */
 432 
 433 
 434 /* cy_start and cy_stop provide software output flow control as a
 435    function of XON/XOFF, software CTS, and other such stuff. */
 436 
 437 static void
 438 cy_stop(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 439 {
 440   struct cyclades_card *cinfo;
 441   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
 442   unsigned char *base_addr;
 443   int chip,channel;
 444   unsigned long flags;
 445 
 446 #ifdef SERIAL_DEBUG_OTHER
 447     printk("cy_stop ttyC%d\n", info->line); /* */
 448 #endif
 449 
 450     if (serial_paranoia_check(info, tty->device, "cy_stop"))
 451         return;
 452         
 453     cinfo = &cy_card[info->card];
 454     channel = info->line - cinfo->first_line;
 455     chip = channel>>2;
 456     channel &= 0x03;
 457     base_addr = (unsigned char*)
 458                    (cy_card[info->card].base_addr + chip * CyRegSize);
 459 
 460     save_flags(flags); cli();
 461         base_addr[CyCAR] = (u_char)(channel & 0x0003); /* index channel */
 462         base_addr[CySRER] &= ~CyTxMpty;
 463     restore_flags(flags);
 464 
 465     return;
 466 } /* cy_stop */
 467 
 468 static void
 469 cy_start(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 470 {
 471   struct cyclades_card *cinfo;
 472   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
 473   unsigned char *base_addr;
 474   int chip,channel;
 475   unsigned long flags;
 476 
 477 #ifdef SERIAL_DEBUG_OTHER
 478     printk("cy_start ttyC%d\n", info->line); /* */
 479 #endif
 480 
 481     if (serial_paranoia_check(info, tty->device, "cy_start"))
 482         return;
 483         
 484     cinfo = &cy_card[info->card];
 485     channel = info->line - cinfo->first_line;
 486     chip = channel>>2;
 487     channel &= 0x03;
 488     base_addr = (unsigned char*)
 489                    (cy_card[info->card].base_addr + chip * CyRegSize);
 490 
 491     save_flags(flags); cli();
 492         base_addr[CyCAR] = (u_char)(channel & 0x0003);
 493         base_addr[CySRER] |= CyTxMpty;
 494     restore_flags(flags);
 495 
 496     return;
 497 } /* cy_start */
 498 
 499 
 500 /*
 501  * This routine is used by the interrupt handler to schedule
 502  * processing in the software interrupt portion of the driver
 503  * (also known as the "bottom half").  This can be called any
 504  * number of times for any channel without harm.
 505  */
 506 static inline void
 507 cy_sched_event(struct cyclades_port *info, int event)
     /* [previous][next][first][last][top][bottom][index][help] */
 508 {
 509     info->event |= 1 << event; /* remember what kind of event and who */
 510     queue_task_irq_off(&info->tqueue, &tq_cyclades); /* it belongs to */
 511     mark_bh(CYCLADES_BH);                       /* then trigger event */
 512 } /* cy_sched_event */
 513 
 514 
 515 
 516 /*
 517  * This interrupt routine is used
 518  * while we are probing for submarines.
 519  */
 520 static void
 521 cy_probe(int irq, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 522 {
 523     cy_irq_triggered = irq;
 524     cy_triggered |= 1 << irq;
 525     return;
 526 } /* cy_probe */
 527 
 528 /* The real interrupt service routine is called
 529    whenever the card wants its hand held--chars
 530    received, out buffer empty, modem change, etc.
 531  */
 532 static void
 533 cy_interrupt(int irq, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 534 {
 535   struct tty_struct *tty;
 536   int status;
 537   struct cyclades_card *cinfo;
 538   struct cyclades_port *info;
 539   volatile unsigned char *base_addr, *card_base_addr;
 540   int chip;
 541   int save_xir, channel, save_car;
 542   char data;
 543   volatile char vdata;
 544   int char_count;
 545   int outch;
 546   int i,j;
 547   int too_many;
 548   int had_work;
 549   int mdm_change;
 550   int mdm_status;
 551 
 552     if((cinfo = IRQ_cards[irq]) == 0){
 553         return; /* spurious interrupt */
 554     }
 555 
 556     /* This loop checks all chips in the card.  Make a note whenever
 557        _any_ chip had some work to do, as this is considered an
 558        indication that there will be more to do.  Only when no chip
 559        has any work does this outermost loop exit.
 560      */
 561     do{
 562         had_work = 0;
 563         for ( chip = 0 ; chip < cinfo->num_chips ; chip ++) {
 564             base_addr = (unsigned char *)(cinfo->base_addr
 565                                              + CyRegSize * chip);
 566             too_many = 0;
 567             while ( (status = base_addr[CySVRR]) != 0x00) {
 568                 had_work++;
 569                 /* The purpose of the following test is to ensure that
 570                    no chip can monopolize the driver.  This forces the
 571                    chips to be checked in a round-robin fashion (after
 572                    draining each of a bunch (1000) of characters).
 573                  */
 574                 if(1000<too_many++){
 575                     break;
 576                 }
 577                 if (status & CySRReceive) {      /* reception interrupt */
 578 
 579                     /* determine the channel and change to that context */
 580                     save_xir = (u_char) base_addr[CyRIR];
 581                     channel = (u_short ) (save_xir & CyIRChannel);
 582                     i = channel + chip * 4 + cinfo->first_line;
 583                     info = &cy_port[i];
 584                     info->last_active = jiffies;
 585                     save_car = base_addr[CyCAR];
 586                     base_addr[CyCAR] = save_xir;
 587 
 588                     /* if there is nowhere to put the data, discard it */
 589                     if(info->tty == 0){
 590                         j = (base_addr[CyRIVR] & CyIVRMask);
 591                         if ( j == CyIVRRxEx ) { /* exception */
 592                             data = base_addr[CyRDSR];
 593                         } else { /* normal character reception */
 594                             char_count = base_addr[CyRDCR];
 595                             while(char_count--){
 596                                 data = base_addr[CyRDSR];
 597                             }
 598                         }
 599                     }else{ /* there is an open port for this data */
 600                         tty = info->tty;
 601                         j = (base_addr[CyRIVR] & CyIVRMask);
 602                         if ( j == CyIVRRxEx ) { /* exception */
 603                             data = base_addr[CyRDSR];
 604                             if(data & info->ignore_status_mask){
 605                                 continue;
 606                             }
 607                             if (tty->flip.count < TTY_FLIPBUF_SIZE){
 608                                 tty->flip.count++;
 609                                 if (data & info->read_status_mask){
 610                                     if(data & CyBREAK){
 611                                         *tty->flip.flag_buf_ptr++ =
 612                                                                 TTY_BREAK;
 613                                         *tty->flip.char_buf_ptr++ =
 614                                                         base_addr[CyRDSR];
 615                                         if (info->flags & ASYNC_SAK){
 616                                             do_SAK(tty);
 617                                         }
 618                                     }else if(data & CyFRAME){
 619                                         *tty->flip.flag_buf_ptr++ =
 620                                                                 TTY_FRAME;
 621                                         *tty->flip.char_buf_ptr++ =
 622                                                         base_addr[CyRDSR];
 623                                     }else if(data & CyPARITY){
 624                                         *tty->flip.flag_buf_ptr++ =
 625                                                                 TTY_PARITY;
 626                                         *tty->flip.char_buf_ptr++ =
 627                                                         base_addr[CyRDSR];
 628                                     }else if(data & CyOVERRUN){
 629                                         *tty->flip.flag_buf_ptr++ =
 630                                                                 TTY_OVERRUN;
 631                                         *tty->flip.char_buf_ptr++ = 0;
 632                                         /* If the flip buffer itself is
 633                                            overflowing, we still loose
 634                                            the next incoming character.
 635                                          */
 636                                         if(tty->flip.count < TTY_FLIPBUF_SIZE){
 637                                             tty->flip.count++;
 638                                             *tty->flip.flag_buf_ptr++ =
 639                                                                  TTY_NORMAL;
 640                                             *tty->flip.char_buf_ptr++ =
 641                                                         base_addr[CyRDSR];
 642                                         }
 643                                     /* These two conditions may imply */
 644                                     /* a normal read should be done. */
 645                                     /* }else if(data & CyTIMEOUT){ */
 646                                     /* }else if(data & CySPECHAR){ */
 647                                     }else{
 648                                         *tty->flip.flag_buf_ptr++ = 0;
 649                                         *tty->flip.char_buf_ptr++ = 0;
 650                                     }
 651                                 }else{
 652                                     *tty->flip.flag_buf_ptr++ = 0;
 653                                     *tty->flip.char_buf_ptr++ = 0;
 654                                 }
 655                             }else{
 656                                 /* there was a software buffer overrun
 657                                     and nothing could be done about it!!! */
 658                             }
 659                         } else { /* normal character reception */
 660                             /* load # characters available from the chip */
 661                             char_count = base_addr[CyRDCR];
 662 
 663                             while(char_count--){
 664                                 if (tty->flip.count >= TTY_FLIPBUF_SIZE){
 665                                         break;
 666                                 }
 667                                 tty->flip.count++;
 668                                 data = base_addr[CyRDSR];
 669                                 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
 670                                 *tty->flip.char_buf_ptr++ = data;
 671                             }
 672                         }
 673                         queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
 674                     }
 675                     /* end of service */
 676                     base_addr[CyRIR] = (save_xir & 0x3f);
 677                     base_addr[CyCAR] = (save_car);
 678                 }
 679 
 680 
 681                 if (status & CySRTransmit) {     /* transmission interrupt */
 682                     /* Since we only get here when the transmit buffer is empty,
 683                         we know we can always stuff a dozen characters. */
 684 
 685                     /* determine the channel and change to that context */
 686                     save_xir = (u_char) base_addr[CyTIR];
 687                     channel = (u_short ) (save_xir & CyIRChannel);
 688                     i = channel + chip * 4 + cinfo->first_line;
 689                     save_car = base_addr[CyCAR];
 690                     base_addr[CyCAR] = save_xir;
 691 
 692                     /* validate the port number (as configured and open) */
 693                     if( (i < 0) || (NR_PORTS <= i) ){
 694                         base_addr[CySRER] &= ~CyTxMpty;
 695                         goto txend;
 696                     }
 697                     info = &cy_port[i];
 698                     info->last_active = jiffies;
 699                     if(info->tty == 0){
 700                         base_addr[CySRER] &= ~CyTxMpty;
 701                         goto txdone;
 702                     }
 703 
 704                     /* load the on-chip space available for outbound data */
 705                     char_count = info->xmit_fifo_size;
 706 
 707 
 708                     if(info->x_char) { /* send special char */
 709                         outch = info->x_char;
 710                         base_addr[CyTDR] = outch;
 711                         char_count--;
 712                         info->x_char = 0;
 713                     }
 714 
 715                     if (info->x_break){
 716                         /*  The Cirrus chip requires the "Embedded Transmit
 717                             Commands" of start break, delay, and end break
 718                             sequences to be sent.  The duration of the
 719                             break is given in TICs, which runs at HZ
 720                             (typically 100) and the PPR runs at 200 Hz,
 721                             so the delay is duration * 200/HZ, and thus a
 722                             break can run from 1/100 sec to about 5/4 sec.
 723                          */
 724                         base_addr[CyTDR] = 0; /* start break */
 725                         base_addr[CyTDR] = 0x81;
 726                         base_addr[CyTDR] = 0; /* delay a bit */
 727                         base_addr[CyTDR] = 0x82;
 728                         base_addr[CyTDR] = info->x_break*200/HZ;
 729                         base_addr[CyTDR] = 0; /* terminate break */
 730                         base_addr[CyTDR] = 0x83;
 731                         char_count -= 7;
 732                         info->x_break = 0;
 733                     }
 734 
 735                     while (char_count-- > 0){
 736                         if (!info->xmit_cnt){
 737                             base_addr[CySRER] &= ~CyTxMpty;
 738                             goto txdone;
 739                         }
 740                         if (info->tty->stopped || info->tty->hw_stopped){
 741                             base_addr[CySRER] &= ~CyTxMpty;
 742                             goto txdone;
 743                         }
 744                         /* Because the Embedded Transmit Commands have been
 745                            enabled, we must check to see if the escape
 746                            character, NULL, is being sent.  If it is, we
 747                            must ensure that there is room for it to be
 748                            doubled in the output stream.  Therefore we
 749                            no longer advance the pointer when the character
 750                            is fetched, but rather wait until after the check
 751                            for a NULL output character. (This is necessary
 752                            because there may not be room for the two chars
 753                            needed to send a NULL.
 754                          */
 755                         outch = info->xmit_buf[info->xmit_tail];
 756                         if( outch ){
 757                             info->xmit_cnt--;
 758                             info->xmit_tail = (info->xmit_tail + 1)
 759                                                       & (PAGE_SIZE - 1);
 760                             base_addr[CyTDR] = outch;
 761                         }else{
 762                             if(char_count > 1){
 763                                 info->xmit_cnt--;
 764                                 info->xmit_tail = (info->xmit_tail + 1)
 765                                                           & (PAGE_SIZE - 1);
 766                                 base_addr[CyTDR] = outch;
 767                                 base_addr[CyTDR] = 0;
 768                                 char_count--;
 769                             }else{
 770                             }
 771                         }
 772                     }
 773 
 774         txdone:
 775                     if (info->xmit_cnt < WAKEUP_CHARS) {
 776                         cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
 777                     }
 778 
 779         txend:
 780                     /* end of service */
 781                     base_addr[CyTIR] = (save_xir & 0x3f);
 782                     base_addr[CyCAR] = (save_car);
 783                 }
 784 
 785                 if (status & CySRModem) {        /* modem interrupt */
 786 
 787                     /* determine the channel and change to that context */
 788                     save_xir = (u_char) base_addr[CyMIR];
 789                     channel = (u_short ) (save_xir & CyIRChannel);
 790                     info = &cy_port[channel + chip * 4 + cinfo->first_line];
 791                     info->last_active = jiffies;
 792                     save_car = base_addr[CyCAR];
 793                     base_addr[CyCAR] = save_xir;
 794 
 795                     mdm_change = base_addr[CyMISR];
 796                     mdm_status = base_addr[CyMSVR1];
 797 
 798                     if(info->tty == 0){ /* nowhere to put the data, ignore it */
 799                         ;
 800                     }else{
 801                         if((mdm_change & CyDCD)
 802                         && (info->flags & ASYNC_CHECK_CD)){
 803                             if(mdm_status & CyDCD){
 804 /* CP('!'); */
 805                                 cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP);
 806                             }else if(!((info->flags & ASYNC_CALLOUT_ACTIVE)
 807                                      &&(info->flags & ASYNC_CALLOUT_NOHUP))){
 808 /* CP('@'); */
 809                                 cy_sched_event(info, Cy_EVENT_HANGUP);
 810                             }
 811                         }
 812                         if((mdm_change & CyCTS)
 813                         && (info->flags & ASYNC_CTS_FLOW)){
 814                             if(info->tty->stopped){
 815                                 if(mdm_status & CyCTS){
 816                                     /* !!! cy_start isn't used because... */
 817                                     info->tty->stopped = 0;
 818                                     base_addr[CySRER] |= CyTxMpty;
 819                                     cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
 820                                 }
 821                             }else{
 822                                 if(!(mdm_status & CyCTS)){
 823                                     /* !!! cy_stop isn't used because... */
 824                                     info->tty->stopped = 1;
 825                                     base_addr[CySRER] &= ~CyTxMpty;
 826                                 }
 827                             }
 828                         }
 829                         if(mdm_status & CyDSR){
 830                         }
 831                         if(mdm_status & CyRI){
 832                         }
 833                     }
 834                     /* end of service */
 835                     base_addr[CyMIR] = (save_xir & 0x3f);
 836                     base_addr[CyCAR] = save_car;
 837                 }
 838             }          /* end while status != 0 */
 839         }            /* end loop for chips... */
 840     } while(had_work);
 841 
 842    /* clear interrupts */
 843     card_base_addr = (unsigned char *)cinfo->base_addr;
 844    vdata = *(card_base_addr + Cy_ClrIntr); /* Cy_ClrIntr is 0x1800 */
 845 
 846 } /* cy_interrupt */
 847 
 848 /*
 849  * This routine is used to handle the "bottom half" processing for the
 850  * serial driver, known also the "software interrupt" processing.
 851  * This processing is done at the kernel interrupt level, after the
 852  * cy_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
 853  * is where time-consuming activities which can not be done in the
 854  * interrupt driver proper are done; the interrupt driver schedules
 855  * them using cy_sched_event(), and they get done here.
 856  *
 857  * This is done through one level of indirection--the task queue.
 858  * When a hardware interrupt service routine wants service by the
 859  * driver's bottom half, it enqueues the appropriate tq_struct (one
 860  * per port) to the tq_cyclades work queue and sets a request flag
 861  * via mark_bh for processing that queue.  When the time is right,
 862  * do_cyclades_bh is called (because of the mark_bh) and it requests
 863  * that the work queue be processed.
 864  *
 865  * Although this may seem unwieldy, it gives the system a way to
 866  * pass an argument (in this case the pointer to the cyclades_port
 867  * structure) to the bottom half of the driver.  Previous kernels
 868  * had to poll every port to see if that port needed servicing.
 869  */
 870 static void
 871 do_cyclades_bh(void *unused)
     /* [previous][next][first][last][top][bottom][index][help] */
 872 {
 873     run_task_queue(&tq_cyclades);
 874 } /* do_cyclades_bh */
 875 
 876 static void
 877 do_softint(void *private_)
     /* [previous][next][first][last][top][bottom][index][help] */
 878 {
 879   struct cyclades_port *info = (struct cyclades_port *) private_;
 880   struct tty_struct    *tty;
 881 
 882     tty = info->tty;
 883     if (!tty)
 884         return;
 885 
 886     if (clear_bit(Cy_EVENT_HANGUP, &info->event)) {
 887         tty_hangup(info->tty);
 888         wake_up_interruptible(&info->open_wait);
 889         info->flags &= ~(ASYNC_NORMAL_ACTIVE|
 890                              ASYNC_CALLOUT_ACTIVE);
 891     }
 892     if (clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
 893         wake_up_interruptible(&info->open_wait);
 894     }
 895     if (clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
 896         if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP))
 897         && tty->ldisc.write_wakeup){
 898             (tty->ldisc.write_wakeup)(tty);
 899         }
 900         wake_up_interruptible(&tty->write_wait);
 901     }
 902 } /* do_softint */
 903 
 904 
 905 /*
 906  * Grab all interrupts in preparation for doing an automatic irq
 907  * detection.  dontgrab is a mask of irq's _not_ to grab.  Returns a
 908  * mask of irq's which were grabbed and should therefore be freed
 909  * using free_all_interrupts().
 910  */
 911 static int
 912 grab_all_interrupts(int dontgrab)
     /* [previous][next][first][last][top][bottom][index][help] */
 913 {
 914   int irq_lines = 0;
 915   int i, mask;
 916     
 917     for (i = 0, mask = 1; i < 16; i++, mask <<= 1) {
 918         if (!(mask & dontgrab)
 919         && !request_irq(i, cy_probe, SA_INTERRUPT, "serial probe")) {
 920             irq_lines |= mask;
 921         }
 922     }
 923     return irq_lines;
 924 } /* grab_all_interrupts */
 925 
 926 /*
 927  * Release all interrupts grabbed by grab_all_interrupts
 928  */
 929 static void
 930 free_all_interrupts(int irq_lines)
     /* [previous][next][first][last][top][bottom][index][help] */
 931 {
 932   int i;
 933     
 934     for (i = 0; i < 16; i++) {
 935         if (irq_lines & (1 << i))
 936             free_irq(i);
 937     }
 938 } /* free_all_interrupts */
 939 
 940 /*
 941  * This routine returns a bitfield of "wild interrupts".  Basically,
 942  * any unclaimed interrupts which is flapping around.
 943  */
 944 static int
 945 check_wild_interrupts(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 946 {
 947   int   i, mask;
 948   int   wild_interrupts = 0;
 949   int   irq_lines;
 950   unsigned long timeout;
 951   unsigned long flags;
 952         
 953     /*Turn on interrupts (they may be off) */
 954     save_flags(flags); sti();
 955 
 956         irq_lines = grab_all_interrupts(0);
 957        
 958         /*
 959          * Delay for 0.1 seconds -- we use a busy loop since this may 
 960          * occur during the bootup sequence
 961          */
 962         timeout = jiffies+10;
 963         while (timeout >= jiffies)
 964             ;
 965         
 966         cy_triggered = 0;       /* Reset after letting things settle */
 967 
 968         timeout = jiffies+10;
 969         while (timeout >= jiffies)
 970                 ;
 971         
 972         for (i = 0, mask = 1; i < 16; i++, mask <<= 1) {
 973             if ((cy_triggered & (1 << i)) &&
 974                 (irq_lines & (1 << i))) {
 975                     wild_interrupts |= mask;
 976             }
 977         }
 978         free_all_interrupts(irq_lines);
 979     restore_flags(flags);
 980     return wild_interrupts;
 981 } /* check_wild_interrupts */
 982 
 983 /*
 984  * This routine is called by do_auto_irq(); it attempts to determine
 985  * which interrupt a serial port is configured to use.  It is not
 986  * fool-proof, but it works a large part of the time.
 987  */
 988 static int
 989 get_auto_irq(int card)
     /* [previous][next][first][last][top][bottom][index][help] */
 990 {
 991   unsigned long timeout;
 992   unsigned char *base_addr;
 993   int save_xir, save_car;
 994   volatile char vdata;
 995 
 996     base_addr = (unsigned char*) (cy_card[card].base_addr);
 997     intr_base_addr = base_addr;
 998         
 999     /*
1000      * Enable interrupts and see who answers
1001      */
1002     cy_irq_triggered = 0;
1003     cli();
1004         base_addr[CyCAR] = 0;
1005         write_cy_cmd(base_addr,CyCHAN_CTL|CyENB_XMTR);
1006         base_addr[CySRER] |= CyTxMpty;
1007     sti();
1008     
1009     timeout = jiffies+2;
1010     while (timeout >= jiffies) {
1011         if (cy_irq_triggered)
1012             break;
1013     }
1014     /*
1015      * Now check to see if we got any business, and clean up.
1016      */
1017     cli();
1018         if(intr_base_addr[CySVRR] != 0){
1019             save_xir = (u_char) intr_base_addr[CyTIR];
1020             save_car = intr_base_addr[CyCAR];
1021             if ((save_xir & 0x3) != 0){
1022                 printk("channel %x requesting unexpected interrupt\n",save_xir);
1023             }
1024             intr_base_addr[CyCAR] = (save_xir & 0x3);
1025             intr_base_addr[CySRER] &= ~CyTxMpty;
1026             intr_base_addr[CyTIR] = (save_xir & 0x3f);
1027             intr_base_addr[CyCAR] = (save_car);
1028             vdata = *(intr_base_addr + Cy_ClrIntr); /* Cy_ClrIntr is 0x1800 */
1029         }
1030     sti();
1031 
1032     return(cy_irq_triggered);
1033 } /* get_auto_irq */
1034 
1035 /*
1036  * Calls get_auto_irq() multiple times, to make sure we don't get
1037  * faked out by random interrupts
1038  */
1039 static int
1040 do_auto_irq(int card)
     /* [previous][next][first][last][top][bottom][index][help] */
1041 {
1042   int                   irq_lines = 0;
1043   int                   irq_try_1 = 0, irq_try_2 = 0;
1044   int                   retries;
1045   unsigned long flags;
1046 
1047     /* Turn on interrupts (they may be off) */
1048     save_flags(flags); sti();
1049 
1050         cy_wild_int_mask = check_wild_interrupts();
1051 
1052         irq_lines = grab_all_interrupts(cy_wild_int_mask);
1053         
1054         for (retries = 0; retries < 5; retries++) {
1055             if (!irq_try_1)
1056                 irq_try_1 = get_auto_irq(card);
1057             if (!irq_try_2)
1058                 irq_try_2 = get_auto_irq(card);
1059             if (irq_try_1 && irq_try_2) {
1060                 if (irq_try_1 == irq_try_2)
1061                     break;
1062                 irq_try_1 = irq_try_2 = 0;
1063             }
1064         }
1065     restore_flags(flags);
1066     free_all_interrupts(irq_lines);
1067     return (irq_try_1 == irq_try_2) ? irq_try_1 : 0;
1068 } /* do_auto_irq */
1069 
1070 
1071 /* This is called whenever a port becomes active;
1072    interrupts are enabled and DTR & RTS are turned on.
1073  */
1074 static int
1075 startup(struct cyclades_port * info)
     /* [previous][next][first][last][top][bottom][index][help] */
1076 {
1077   unsigned long flags;
1078   unsigned char *base_addr;
1079   int card,chip,channel;
1080 
1081     if (info->flags & ASYNC_INITIALIZED){
1082         return 0;
1083     }
1084 
1085     if (!info->type){
1086         if (info->tty){
1087             set_bit(TTY_IO_ERROR, &info->tty->flags);
1088         }
1089         return 0;
1090     }
1091     if (!info->xmit_buf){
1092         info->xmit_buf = (unsigned char *) get_free_page (GFP_KERNEL);
1093         if (!info->xmit_buf){
1094             return -ENOMEM;
1095         }
1096     }
1097 
1098     config_setup(info);
1099 
1100     card = info->card;
1101     channel = (info->line) - (cy_card[card].first_line);
1102     chip = channel>>2;
1103     channel &= 0x03;
1104     base_addr = (unsigned char*)
1105                    (cy_card[card].base_addr + chip * CyRegSize);
1106 
1107 #ifdef SERIAL_DEBUG_OPEN
1108     printk("startup card %d, chip %d, channel %d, base_addr %lx",
1109          card, chip, channel, (long)base_addr);/**/
1110 #endif
1111 
1112     save_flags(flags); cli();
1113         base_addr[CyCAR] = (u_char)channel;
1114 
1115         base_addr[CyRTPR] = 0x20; /* 32ms rx timeout */
1116 
1117         write_cy_cmd(base_addr,CyCHAN_CTL|CyENB_RCVR|CyENB_XMTR);
1118 
1119         base_addr[CyCAR] = (u_char)channel; /* !!! Is this needed? */
1120         base_addr[CyMSVR1] = CyRTS;
1121 /* CP('S');CP('1'); */
1122         base_addr[CyMSVR2] = CyDTR;
1123 
1124 #ifdef SERIAL_DEBUG_DTR
1125         printk("cyc: %d: raising DTR\n", __LINE__);
1126         printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1127 #endif
1128 
1129         base_addr[CySRER] |= CyRxData;
1130         info->flags |= ASYNC_INITIALIZED;
1131 
1132         if (info->tty){
1133             clear_bit(TTY_IO_ERROR, &info->tty->flags);
1134         }
1135         info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1136 
1137     restore_flags(flags);
1138 
1139 #ifdef SERIAL_DEBUG_OPEN
1140     printk(" done\n");
1141 #endif
1142     return 0;
1143 } /* startup */
1144 
1145 void
1146 start_xmit( struct cyclades_port *info )
     /* [previous][next][first][last][top][bottom][index][help] */
1147 {
1148   unsigned long flags;
1149   unsigned char *base_addr;
1150   int card,chip,channel;
1151 
1152     card = info->card;
1153     channel = (info->line) - (cy_card[card].first_line);
1154     chip = channel>>2;
1155     channel &= 0x03;
1156     base_addr = (unsigned char*)
1157                    (cy_card[card].base_addr + chip * CyRegSize);
1158     save_flags(flags); cli();
1159         base_addr[CyCAR] = channel;
1160         base_addr[CySRER] |= CyTxMpty;
1161     restore_flags(flags);
1162 } /* start_xmit */
1163 
1164 /*
1165  * This routine shuts down a serial port; interrupts are disabled,
1166  * and DTR is dropped if the hangup on close termio flag is on.
1167  */
1168 static void
1169 shutdown(struct cyclades_port * info)
     /* [previous][next][first][last][top][bottom][index][help] */
1170 {
1171   unsigned long flags;
1172   unsigned char *base_addr;
1173   int card,chip,channel;
1174 
1175     if (!(info->flags & ASYNC_INITIALIZED)){
1176 /* CP('$'); */
1177         return;
1178     }
1179 
1180     card = info->card;
1181     channel = info->line - cy_card[card].first_line;
1182     chip = channel>>2;
1183     channel &= 0x03;
1184     base_addr = (unsigned char*)
1185                    (cy_card[card].base_addr + chip * CyRegSize);
1186 
1187 #ifdef SERIAL_DEBUG_OPEN
1188     printk("shutdown card %d, chip %d, channel %d, base_addr %lx\n",
1189             card, chip, channel, (long)base_addr);
1190 #endif
1191 
1192     /* !!! REALLY MUST WAIT FOR LAST CHARACTER TO BE
1193        SENT BEFORE DROPPING THE LINE !!!  (Perhaps
1194        set some flag that is read when XMTY happens.)
1195        Other choices are to delay some fixed interval
1196        or schedule some later processing.
1197      */
1198     save_flags(flags); cli();
1199         if (info->xmit_buf){
1200             free_page((unsigned long) info->xmit_buf);
1201             info->xmit_buf = 0;
1202         }
1203 
1204         base_addr[CyCAR] = (u_char)channel;
1205         if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
1206             base_addr[CyMSVR1] = ~CyRTS;
1207 /* CP('C');CP('1'); */
1208             base_addr[CyMSVR2] = ~CyDTR;
1209 #ifdef SERIAL_DEBUG_DTR
1210             printk("cyc: %d: dropping DTR\n", __LINE__);
1211             printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1212 #endif
1213         }
1214         write_cy_cmd(base_addr,CyCHAN_CTL|CyDIS_RCVR);
1215          /* it may be appropriate to clear _XMIT at
1216            some later date (after testing)!!! */
1217 
1218         if (info->tty){
1219             set_bit(TTY_IO_ERROR, &info->tty->flags);
1220         }
1221         info->flags &= ~ASYNC_INITIALIZED;
1222     restore_flags(flags);
1223 
1224 #ifdef SERIAL_DEBUG_OPEN
1225     printk(" done\n");
1226 #endif
1227     return;
1228 } /* shutdown */
1229 
1230 /*
1231  * This routine finds or computes the various line characteristics.
1232  */
1233 static void
1234 config_setup(struct cyclades_port * info)
     /* [previous][next][first][last][top][bottom][index][help] */
1235 {
1236   unsigned long flags;
1237   unsigned char *base_addr;
1238   int card,chip,channel;
1239   unsigned cflag;
1240   int   i;
1241 
1242     if (!info->tty || !info->tty->termios){
1243         return;
1244     }
1245     if (info->line == -1){
1246         return;
1247     }
1248     cflag = info->tty->termios->c_cflag;
1249 
1250     /* baud rate */
1251     i = cflag & CBAUD;
1252 #ifdef CBAUDEX
1253 /* Starting with kernel 1.1.65, there is direct support for
1254    higher baud rates.  The following code supports those
1255    changes.  The conditional aspect allows this driver to be
1256    used for earlier as well as later kernel versions.  (The
1257    mapping is slightly different from serial.c because there
1258    is still the possibility of supporting 75 kbit/sec with
1259    the Cyclades board.)
1260  */
1261     if (i & CBAUDEX) {
1262         if (i == B57600)
1263             i = 16;
1264         else if(i == B115200) 
1265             i = 18;
1266 #ifdef B78600
1267         else if(i == B78600) 
1268             i = 17;
1269 #endif
1270         else
1271             info->tty->termios->c_cflag &= ~CBAUDEX;
1272     }
1273 #endif
1274     if (i == 15) {
1275             if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1276                     i += 1;
1277             if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1278                     i += 3;
1279     }
1280     info->tbpr = baud_bpr[i]; /* Tx BPR */
1281     info->tco = baud_co[i]; /* Tx CO */
1282     info->rbpr = baud_bpr[i]; /* Rx BPR */
1283     info->rco = baud_co[i]; /* Rx CO */
1284     if (baud_table[i] == 134) {
1285         info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
1286         /* get it right for 134.5 baud */
1287     } else if (baud_table[i]) {
1288         info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
1289         /* this needs to be propagated into the card info */
1290     } else {
1291         info->timeout = 0;
1292     }
1293     /* By tradition (is it a standard?) a baud rate of zero
1294        implies the line should be/has been closed.  A bit
1295        later in this routine such a test is performed. */
1296 
1297     /* byte size and parity */
1298     info->cor5 = 0;
1299     info->cor4 = 0;
1300     info->cor3 = baud_cor3[i]; /* receive threshold */
1301     info->cor2 = CyETC;
1302     switch(cflag & CSIZE){
1303     case CS5:
1304         info->cor1 = Cy_5_BITS;
1305         break;
1306     case CS6:
1307         info->cor1 = Cy_6_BITS;
1308         break;
1309     case CS7:
1310         info->cor1 = Cy_7_BITS;
1311         break;
1312     case CS8:
1313         info->cor1 = Cy_8_BITS;
1314         break;
1315     }
1316     if(cflag & CSTOPB){
1317         info->cor1 |= Cy_2_STOP;
1318     }
1319     if (cflag & PARENB){
1320         if (cflag & PARODD){
1321             info->cor1 |= CyPARITY_O;
1322         }else{
1323             info->cor1 |= CyPARITY_E;
1324         }
1325     }else{
1326         info->cor1 |= CyPARITY_NONE;
1327     }
1328         
1329     /* CTS flow control flag */
1330     if (cflag & CRTSCTS)
1331         info->flags |= ASYNC_CTS_FLOW;
1332     else
1333         info->flags &= ~ASYNC_CTS_FLOW;
1334     if (cflag & CLOCAL)
1335         info->flags &= ~ASYNC_CHECK_CD;
1336     else
1337         info->flags |= ASYNC_CHECK_CD;
1338 
1339 
1340     card = info->card;
1341     channel = (info->line) - (cy_card[card].first_line);
1342     chip = channel>>2;
1343     channel &= 0x03;
1344     base_addr = (unsigned char*)
1345                    (cy_card[card].base_addr + chip * CyRegSize);
1346 
1347     save_flags(flags); cli();
1348         base_addr[CyCAR] = (u_char)channel;
1349 
1350        /* tx and rx baud rate */
1351 
1352         base_addr[CyTCOR] = info->tco;
1353         base_addr[CyTBPR] = info->tbpr;
1354         base_addr[CyRCOR] = info->rco;
1355         base_addr[CyRBPR] = info->rbpr;
1356 
1357         /* set line characteristics  according configuration */
1358 
1359         base_addr[CySCHR1] = START_CHAR(info->tty);
1360         base_addr[CySCHR2] = STOP_CHAR(info->tty);
1361         base_addr[CyCOR1] = info->cor1;
1362         base_addr[CyCOR2] = info->cor2;
1363         base_addr[CyCOR3] = info->cor3;
1364         base_addr[CyCOR4] = info->cor4;
1365         base_addr[CyCOR5] = info->cor5;
1366 
1367         write_cy_cmd(base_addr,CyCOR_CHANGE|CyCOR1ch|CyCOR2ch|CyCOR3ch);
1368 
1369         base_addr[CyCAR] = (u_char)channel; /* !!! Is this needed? */
1370 
1371         base_addr[CyRTPR] = 0x20; /* 32ms rx timeout */
1372 
1373         if (C_CLOCAL(info->tty)) {
1374             base_addr[CySRER] |= 0; /* without modem intr */
1375                                     /* ignore 1->0 modem transitions */
1376             base_addr[CyMCOR1] = 0x0;
1377                                     /* ignore 0->1 modem transitions */
1378             base_addr[CyMCOR2] = 0x0;
1379         } else {
1380             base_addr[CySRER] |= CyMdmCh; /* with modem intr */
1381                                     /* act on 1->0 modem transitions */
1382             base_addr[CyMCOR1] = CyDSR|CyCTS|CyRI|CyDCD;
1383                                     /* act on 0->1 modem transitions */
1384             base_addr[CyMCOR2] = CyDSR|CyCTS|CyRI|CyDCD;
1385         }
1386 
1387         if(i == 0){ /* baud rate is zero, turn off line */
1388             base_addr[CyMSVR2] = ~CyDTR;
1389 #ifdef SERIAL_DEBUG_DTR
1390             printk("cyc: %d: dropping DTR\n", __LINE__);
1391             printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1392 #endif
1393         }else{
1394             base_addr[CyMSVR2] = CyDTR;
1395 #ifdef SERIAL_DEBUG_DTR
1396             printk("cyc: %d: raising DTR\n", __LINE__);
1397             printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1398 #endif
1399         }
1400 
1401         /* The hardware option, CyRtsAO, presents RTS when
1402            the chip has characters to send.  Since most modems
1403            use RTS as reverse (inbound) flow control, this
1404            option is not used.  If inbound flow control is
1405            necessary, DTR can be programmed to provide the
1406            appropriate signals.  Contact Marcio Saito for
1407            details. */
1408         if (C_CRTSCTS(info->tty)) {
1409             info->cor2 |= CyCtsAE;
1410         }else{
1411             info->cor2 &= ~CyCtsAE;
1412         }
1413 
1414         if (info->tty){
1415             clear_bit(TTY_IO_ERROR, &info->tty->flags);
1416         }
1417 
1418     restore_flags(flags);
1419 
1420 } /* config_setup */
1421 
1422 
1423 static void
1424 cy_put_char(struct tty_struct *tty, unsigned char ch)
     /* [previous][next][first][last][top][bottom][index][help] */
1425 {
1426   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1427   unsigned long flags;
1428 
1429 #ifdef SERIAL_DEBUG_IO
1430     printk("cy_put_char ttyC%d\n", info->line);
1431 #endif
1432 
1433     if (serial_paranoia_check(info, tty->device, "cy_put_char"))
1434         return;
1435 
1436     if (!tty || !info->xmit_buf)
1437         return;
1438 
1439     save_flags(flags); cli();
1440         if (info->xmit_cnt >= PAGE_SIZE - 1) {
1441             restore_flags(flags);
1442             return;
1443         }
1444 
1445         info->xmit_buf[info->xmit_head++] = ch;
1446         info->xmit_head &= PAGE_SIZE - 1;
1447         info->xmit_cnt++;
1448     restore_flags(flags);
1449 } /* cy_put_char */
1450 
1451 
1452 static void
1453 cy_flush_chars(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
1454 {
1455   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1456   unsigned long flags;
1457   unsigned char *base_addr;
1458   int card,chip,channel;
1459                                 
1460 #ifdef SERIAL_DEBUG_IO
1461     printk("cy_flush_chars ttyC%d\n", info->line); /* */
1462 #endif
1463 
1464     if (serial_paranoia_check(info, tty->device, "cy_flush_chars"))
1465         return;
1466 
1467     if (info->xmit_cnt <= 0 || tty->stopped
1468     || tty->hw_stopped || !info->xmit_buf)
1469         return;
1470 
1471     card = info->card;
1472     channel = info->line - cy_card[card].first_line;
1473     chip = channel>>2;
1474     channel &= 0x03;
1475     base_addr = (unsigned char*)
1476                    (cy_card[card].base_addr + chip * CyRegSize);
1477 
1478     save_flags(flags); cli();
1479         base_addr[CyCAR] = channel;
1480         base_addr[CySRER] |= CyTxMpty;
1481     restore_flags(flags);
1482 } /* cy_flush_chars */
1483 
1484 
1485 /* This routine gets called when tty_write has put something into
1486     the write_queue.  If the port is not already transmitting stuff,
1487     start it off by enabling interrupts.  The interrupt service
1488     routine will then ensure that the characters are sent.  If the
1489     port is already active, there is no need to kick it.
1490  */
1491 static int
1492 cy_write(struct tty_struct * tty, int from_user,
     /* [previous][next][first][last][top][bottom][index][help] */
1493            unsigned char *buf, int count)
1494 {
1495   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1496   unsigned long flags;
1497   int c, total = 0;
1498 
1499 #ifdef SERIAL_DEBUG_IO
1500     printk("cy_write ttyC%d\n", info->line); /* */
1501 #endif
1502 
1503     if (serial_paranoia_check(info, tty->device, "cy_write")){
1504         return 0;
1505     }
1506         
1507     if (!tty || !info->xmit_buf || !tmp_buf){
1508         return 0;
1509     }
1510 
1511     while (1) {
1512         save_flags(flags); cli();               
1513         c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
1514                            SERIAL_XMIT_SIZE - info->xmit_head));
1515         if (c <= 0){
1516             restore_flags(flags);
1517             break;
1518         }
1519 
1520         if (from_user) {
1521             down(&tmp_buf_sem);
1522             memcpy_fromfs(tmp_buf, buf, c);
1523             c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
1524                        SERIAL_XMIT_SIZE - info->xmit_head));
1525             memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
1526             up(&tmp_buf_sem);
1527         } else
1528             memcpy(info->xmit_buf + info->xmit_head, buf, c);
1529         info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1530         info->xmit_cnt += c;
1531         restore_flags(flags);
1532         buf += c;
1533         count -= c;
1534         total += c;
1535     }
1536 
1537 
1538     if (info->xmit_cnt
1539     && !tty->stopped
1540     && !tty->hw_stopped ) {
1541         start_xmit(info);
1542     }
1543     return total;
1544 } /* cy_write */
1545 
1546 
1547 static int
1548 cy_write_room(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
1549 {
1550   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1551   int   ret;
1552                                 
1553 #ifdef SERIAL_DEBUG_IO
1554     printk("cy_write_room ttyC%d\n", info->line); /* */
1555 #endif
1556 
1557     if (serial_paranoia_check(info, tty->device, "cy_write_room"))
1558         return 0;
1559     ret = PAGE_SIZE - info->xmit_cnt - 1;
1560     if (ret < 0)
1561         ret = 0;
1562     return ret;
1563 } /* cy_write_room */
1564 
1565 
1566 static int
1567 cy_chars_in_buffer(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
1568 {
1569   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1570                                 
1571 #ifdef SERIAL_DEBUG_IO
1572     printk("cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt); /* */
1573 #endif
1574 
1575     if (serial_paranoia_check(info, tty->device, "cy_chars_in_buffer"))
1576         return 0;
1577 
1578     return info->xmit_cnt;
1579 } /* cy_chars_in_buffer */
1580 
1581 
1582 static void
1583 cy_flush_buffer(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
1584 {
1585   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1586   unsigned long flags;
1587                                 
1588 #ifdef SERIAL_DEBUG_IO
1589     printk("cy_flush_buffer ttyC%d\n", info->line); /* */
1590 #endif
1591 
1592     if (serial_paranoia_check(info, tty->device, "cy_flush_buffer"))
1593         return;
1594     save_flags(flags); cli();
1595         info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1596     restore_flags(flags);
1597     wake_up_interruptible(&tty->write_wait);
1598     if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
1599     && tty->ldisc.write_wakeup)
1600         (tty->ldisc.write_wakeup)(tty);
1601 } /* cy_flush_buffer */
1602 
1603 
1604 /* This routine is called by the upper-layer tty layer to signal
1605    that incoming characters should be throttled or that the
1606    throttle should be released.
1607  */
1608 static void
1609 cy_throttle(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
1610 {
1611   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1612   unsigned long flags;
1613   unsigned char *base_addr;
1614   int card,chip,channel;
1615 
1616 #ifdef SERIAL_DEBUG_THROTTLE
1617   char buf[64];
1618         
1619     printk("throttle %s: %d....\n", _tty_name(tty, buf),
1620            tty->ldisc.chars_in_buffer(tty));
1621     printk("cy_throttle ttyC%d\n", info->line);
1622 #endif
1623 
1624     if (serial_paranoia_check(info, tty->device, "cy_nthrottle")){
1625             return;
1626     }
1627 
1628     if (I_IXOFF(tty)) {
1629         info->x_char = STOP_CHAR(tty);
1630             /* Should use the "Send Special Character" feature!!! */
1631     }
1632 
1633     card = info->card;
1634     channel = info->line - cy_card[card].first_line;
1635     chip = channel>>2;
1636     channel &= 0x03;
1637     base_addr = (unsigned char*)
1638                    (cy_card[card].base_addr + chip * CyRegSize);
1639 
1640     save_flags(flags); cli();
1641         base_addr[CyCAR] = (u_char)channel;
1642         base_addr[CyMSVR1] = ~CyRTS;
1643     restore_flags(flags);
1644 
1645     return;
1646 } /* cy_throttle */
1647 
1648 
1649 static void
1650 cy_unthrottle(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
1651 {
1652   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1653   unsigned long flags;
1654   unsigned char *base_addr;
1655   int card,chip,channel;
1656 
1657 #ifdef SERIAL_DEBUG_THROTTLE
1658   char buf[64];
1659         
1660     printk("throttle %s: %d....\n", _tty_name(tty, buf),
1661            tty->ldisc.chars_in_buffer(tty));
1662     printk("cy_unthrottle ttyC%d\n", info->line);
1663 #endif
1664 
1665     if (serial_paranoia_check(info, tty->device, "cy_nthrottle")){
1666             return;
1667     }
1668 
1669     if (I_IXOFF(tty)) {
1670         info->x_char = START_CHAR(tty);
1671         /* Should use the "Send Special Character" feature!!! */
1672     }
1673 
1674     card = info->card;
1675     channel = info->line - cy_card[card].first_line;
1676     chip = channel>>2;
1677     channel &= 0x03;
1678     base_addr = (unsigned char*)
1679                    (cy_card[card].base_addr + chip * CyRegSize);
1680 
1681     save_flags(flags); cli();
1682         base_addr[CyCAR] = (u_char)channel;
1683         base_addr[CyMSVR1] = CyRTS;
1684     restore_flags(flags);
1685 
1686     return;
1687 } /* cy_unthrottle */
1688 
1689 static int
1690 get_serial_info(struct cyclades_port * info,
     /* [previous][next][first][last][top][bottom][index][help] */
1691                            struct serial_struct * retinfo)
1692 {
1693   struct serial_struct tmp;
1694   struct cyclades_card *cinfo = &cy_card[info->card];
1695 
1696 /* CP('g'); */
1697     if (!retinfo)
1698             return -EFAULT;
1699     memset(&tmp, 0, sizeof(tmp));
1700     tmp.type = info->type;
1701     tmp.line = info->line;
1702     tmp.port = info->card * 0x100 + info->line - cinfo->first_line;
1703     tmp.irq = cinfo->irq;
1704     tmp.flags = info->flags;
1705     tmp.baud_base = 0;          /*!!!*/
1706     tmp.close_delay = info->close_delay;
1707     tmp.custom_divisor = 0;     /*!!!*/
1708     tmp.hub6 = 0;               /*!!!*/
1709     memcpy_tofs(retinfo,&tmp,sizeof(*retinfo));
1710     return 0;
1711 } /* get_serial_info */
1712 
1713 static int
1714 set_serial_info(struct cyclades_port * info,
     /* [previous][next][first][last][top][bottom][index][help] */
1715                            struct serial_struct * new_info)
1716 {
1717   struct serial_struct new_serial;
1718   struct cyclades_port old_info;
1719 
1720 /* CP('s'); */
1721     if (!new_info)
1722             return -EFAULT;
1723     memcpy_fromfs(&new_serial,new_info,sizeof(new_serial));
1724     old_info = *info;
1725 
1726     if (!suser()) {
1727             if ((new_serial.close_delay != info->close_delay) ||
1728                 ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) !=
1729                  (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)))
1730                     return -EPERM;
1731             info->flags = ((info->flags & ~ASYNC_USR_MASK) |
1732                            (new_serial.flags & ASYNC_USR_MASK));
1733             goto check_and_exit;
1734     }
1735 
1736 
1737     /*
1738      * OK, past this point, all the error checking has been done.
1739      * At this point, we start making changes.....
1740      */
1741 
1742     info->flags = ((info->flags & ~ASYNC_FLAGS) |
1743                     (new_serial.flags & ASYNC_FLAGS));
1744     info->close_delay = new_serial.close_delay;
1745 
1746 
1747 check_and_exit:
1748     if (info->flags & ASYNC_INITIALIZED){
1749         config_setup(info);
1750         return 0;
1751     }else{
1752         return startup(info);
1753     }
1754 } /* set_serial_info */
1755 
1756 static int
1757 get_modem_info(struct cyclades_port * info, unsigned int *value)
     /* [previous][next][first][last][top][bottom][index][help] */
1758 {
1759   int card,chip,channel;
1760   unsigned char *base_addr;
1761   unsigned long flags;
1762   unsigned char status;
1763   unsigned int result;
1764 
1765     card = info->card;
1766     channel = (info->line) - (cy_card[card].first_line);
1767     chip = channel>>2;
1768     channel &= 0x03;
1769     base_addr = (unsigned char*)
1770                    (cy_card[card].base_addr + chip * CyRegSize);
1771 
1772     save_flags(flags); cli();
1773         base_addr[CyCAR] = (u_char)channel;
1774         status = base_addr[CyMSVR1] | base_addr[CyMSVR2];
1775     restore_flags(flags);
1776 
1777     result =  ((status  & CyRTS) ? TIOCM_RTS : 0)
1778             | ((status  & CyDTR) ? TIOCM_DTR : 0)
1779             | ((status  & CyDCD) ? TIOCM_CAR : 0)
1780             | ((status  & CyRI) ? TIOCM_RNG : 0)
1781             | ((status  & CyDSR) ? TIOCM_DSR : 0)
1782             | ((status  & CyCTS) ? TIOCM_CTS : 0);
1783     put_fs_long(result,(unsigned long *) value);
1784     return 0;
1785 } /* get_modem_info */
1786 
1787 static int
1788 set_modem_info(struct cyclades_port * info, unsigned int cmd,
     /* [previous][next][first][last][top][bottom][index][help] */
1789                           unsigned int *value)
1790 {
1791   int card,chip,channel;
1792   unsigned char *base_addr;
1793   unsigned long flags;
1794   unsigned int arg = get_fs_long((unsigned long *) value);
1795 
1796     card = info->card;
1797     channel = (info->line) - (cy_card[card].first_line);
1798     chip = channel>>2;
1799     channel &= 0x03;
1800     base_addr = (unsigned char*)
1801                    (cy_card[card].base_addr + chip * CyRegSize);
1802 
1803     switch (cmd) {
1804     case TIOCMBIS:
1805         if (arg & TIOCM_RTS){
1806             save_flags(flags); cli();
1807                 base_addr[CyCAR] = (u_char)channel;
1808                 base_addr[CyMSVR1] = CyRTS;
1809             restore_flags(flags);
1810         }
1811         if (arg & TIOCM_DTR){
1812             save_flags(flags); cli();
1813             base_addr[CyCAR] = (u_char)channel;
1814 /* CP('S');CP('2'); */
1815             base_addr[CyMSVR2] = CyDTR;
1816 #ifdef SERIAL_DEBUG_DTR
1817             printk("cyc: %d: raising DTR\n", __LINE__);
1818             printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1819 #endif
1820             restore_flags(flags);
1821         }
1822         break;
1823     case TIOCMBIC:
1824         if (arg & TIOCM_RTS){
1825             save_flags(flags); cli();
1826                 base_addr[CyCAR] = (u_char)channel;
1827                 base_addr[CyMSVR1] = ~CyRTS;
1828             restore_flags(flags);
1829         }
1830         if (arg & TIOCM_DTR){
1831             save_flags(flags); cli();
1832             base_addr[CyCAR] = (u_char)channel;
1833 /* CP('C');CP('2'); */
1834             base_addr[CyMSVR2] = ~CyDTR;
1835 #ifdef SERIAL_DEBUG_DTR
1836             printk("cyc: %d: dropping DTR\n", __LINE__);
1837             printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1838 #endif
1839             restore_flags(flags);
1840         }
1841         break;
1842     case TIOCMSET:
1843         if (arg & TIOCM_RTS){
1844             save_flags(flags); cli();
1845                 base_addr[CyCAR] = (u_char)channel;
1846                 base_addr[CyMSVR1] = CyRTS;
1847             restore_flags(flags);
1848         }else{
1849             save_flags(flags); cli();
1850                 base_addr[CyCAR] = (u_char)channel;
1851                 base_addr[CyMSVR1] = ~CyRTS;
1852             restore_flags(flags);
1853         }
1854         if (arg & TIOCM_DTR){
1855             save_flags(flags); cli();
1856             base_addr[CyCAR] = (u_char)channel;
1857 /* CP('S');CP('3'); */
1858             base_addr[CyMSVR2] = CyDTR;
1859 #ifdef SERIAL_DEBUG_DTR
1860             printk("cyc: %d: raising DTR\n", __LINE__);
1861             printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1862 #endif
1863             restore_flags(flags);
1864         }else{
1865             save_flags(flags); cli();
1866             base_addr[CyCAR] = (u_char)channel;
1867 /* CP('C');CP('3'); */
1868             base_addr[CyMSVR2] = ~CyDTR;
1869 #ifdef SERIAL_DEBUG_DTR
1870             printk("cyc: %d: dropping DTR\n", __LINE__);
1871             printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
1872 #endif
1873             restore_flags(flags);
1874         }
1875         break;
1876     default:
1877                 return -EINVAL;
1878         }
1879     return 0;
1880 } /* set_modem_info */
1881 
1882 static void
1883 send_break( struct cyclades_port * info, int duration)
     /* [previous][next][first][last][top][bottom][index][help] */
1884 { /* Let the transmit ISR take care of this (since it
1885      requires stuffing characters into the output stream).
1886    */
1887     info->x_break = duration;
1888     if (!info->xmit_cnt ) {
1889         start_xmit(info);
1890     }
1891 } /* send_break */
1892 
1893 
1894 static int
1895 cy_ioctl(struct tty_struct *tty, struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
1896             unsigned int cmd, unsigned long arg)
1897 {
1898   int error;
1899   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
1900   int ret_val = 0;
1901 
1902 #ifdef SERIAL_DEBUG_OTHER
1903     printk("cy_ioctl ttyC%d, cmd = %x arg = %lx\n", info->line, cmd, arg); /* */
1904 #endif
1905 
1906     switch (cmd) {
1907         case TCSBRK:    /* SVID version: non-zero arg --> no break */
1908             ret_val = tty_check_change(tty);
1909             if (ret_val)
1910                 return ret_val;
1911             wait_until_sent(tty,0);
1912             if (!arg)
1913                 send_break(info, HZ/4); /* 1/4 second */
1914             break;
1915         case TCSBRKP:   /* support for POSIX tcsendbreak() */
1916             ret_val = tty_check_change(tty);
1917             if (ret_val)
1918                 return ret_val;
1919             wait_until_sent(tty,0);
1920             send_break(info, arg ? arg*(HZ/10) : HZ/4);
1921             break;
1922         case TIOCMBIS:
1923         case TIOCMBIC:
1924         case TIOCMSET:
1925             ret_val = set_modem_info(info, cmd, (unsigned int *) arg);
1926 
1927 /* The following commands are incompletely implemented!!! */
1928         case TIOCGSOFTCAR:
1929             error = verify_area(VERIFY_WRITE, (void *) arg
1930                                 ,sizeof(unsigned int *));
1931             if (error){
1932                 ret_val = error;
1933                 break;
1934             }
1935             put_fs_long(C_CLOCAL(tty) ? 1 : 0,
1936                         (unsigned long *) arg);
1937             break;
1938         case TIOCSSOFTCAR:
1939             arg = get_fs_long((unsigned long *) arg);
1940             tty->termios->c_cflag =
1941                     ((tty->termios->c_cflag & ~CLOCAL) |
1942                      (arg ? CLOCAL : 0));
1943             break;
1944         case TIOCMGET:
1945             error = verify_area(VERIFY_WRITE, (void *) arg
1946                                 ,sizeof(unsigned int *));
1947             if (error){
1948                 ret_val = error;
1949                 break;
1950             }
1951             ret_val = get_modem_info(info, (unsigned int *) arg);
1952             break;
1953         case TIOCGSERIAL:
1954             error = verify_area(VERIFY_WRITE, (void *) arg
1955                                 ,sizeof(struct serial_struct));
1956             if (error){
1957                 ret_val = error;
1958                 break;
1959             }
1960             ret_val = get_serial_info(info,
1961                                    (struct serial_struct *) arg);
1962             break;
1963         case TIOCSSERIAL:
1964             ret_val = set_serial_info(info,
1965                                    (struct serial_struct *) arg);
1966             break;
1967         default:
1968             ret_val = -ENOIOCTLCMD;
1969     }
1970 
1971 #ifdef SERIAL_DEBUG_OTHER
1972     printk("cy_ioctl done\n");
1973 #endif
1974 
1975     return ret_val;
1976 } /* cy_ioctl */
1977 
1978 
1979 
1980 
1981 static void
1982 cy_set_termios(struct tty_struct *tty, struct termios * old_termios)
     /* [previous][next][first][last][top][bottom][index][help] */
1983 {
1984   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
1985 
1986 #ifdef SERIAL_DEBUG_OTHER
1987     printk("cy_set_termios ttyC%d\n", info->line);
1988 #endif
1989 
1990     if (tty->termios->c_cflag == old_termios->c_cflag)
1991         return;
1992     config_setup(info);
1993 
1994     if ((old_termios->c_cflag & CRTSCTS) &&
1995         !(tty->termios->c_cflag & CRTSCTS)) {
1996             tty->stopped = 0;
1997             cy_start(tty);
1998     }
1999 #ifdef tytso_patch_94Nov25_1726
2000     if (!(old_termios->c_cflag & CLOCAL) &&
2001         (tty->termios->c_cflag & CLOCAL))
2002             wake_up_interruptible(&info->open_wait);
2003 #endif
2004 
2005     return;
2006 } /* cy_set_termios */
2007 
2008 
2009 static void
2010 cy_close(struct tty_struct * tty, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
2011 {
2012   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
2013 
2014 /* CP('C'); */
2015 #ifdef SERIAL_DEBUG_OTHER
2016     printk("cy_close ttyC%d\n", info->line);
2017 #endif
2018 
2019     if (!info
2020     || serial_paranoia_check(info, tty->device, "cy_close")){
2021         return;
2022     }
2023 #ifdef SERIAL_DEBUG_OPEN
2024     printk("cy_close ttyC%d, count = %d\n", info->line, info->count);
2025 #endif
2026 
2027     if ((tty->count == 1) && (info->count != 1)) {
2028         /*
2029          * Uh, oh.  tty->count is 1, which means that the tty
2030          * structure will be freed.  Info->count should always
2031          * be one in these conditions.  If it's greater than
2032          * one, we've got real problems, since it means the
2033          * serial port won't be shutdown.
2034          */
2035         printk("cy_close: bad serial port count; tty->count is 1, "
2036            "info->count is %d\n", info->count);
2037         info->count = 1;
2038     }
2039 #ifdef SERIAL_DEBUG_COUNT
2040     printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count - 1);
2041 #endif
2042     if (--info->count < 0) {
2043         printk("cy_close: bad serial port count for ttys%d: %d\n",
2044                info->line, info->count);
2045 #ifdef SERIAL_DEBUG_COUNT
2046     printk("cyc: %d: setting count to 0\n", __LINE__);
2047 #endif
2048         info->count = 0;
2049     }
2050     if (info->count)
2051         return;
2052     info->flags |= ASYNC_CLOSING;
2053     /*
2054      * Save the termios structure, since this port may have
2055      * separate termios for callout and dialin.
2056      */
2057     if (info->flags & ASYNC_NORMAL_ACTIVE)
2058         info->normal_termios = *tty->termios;
2059     if (info->flags & ASYNC_CALLOUT_ACTIVE)
2060         info->callout_termios = *tty->termios;
2061     if (info->flags & ASYNC_INITIALIZED)
2062         wait_until_sent(tty, 3000); /* 30 seconds timeout */
2063     shutdown(info);
2064     if (tty->driver.flush_buffer)
2065         tty->driver.flush_buffer(tty);
2066     if (tty->ldisc.flush_buffer)
2067         tty->ldisc.flush_buffer(tty);
2068     info->event = 0;
2069     info->tty = 0;
2070     if (tty->ldisc.num != ldiscs[N_TTY].num) {
2071         if (tty->ldisc.close)
2072             (tty->ldisc.close)(tty);
2073         tty->ldisc = ldiscs[N_TTY];
2074         tty->termios->c_line = N_TTY;
2075         if (tty->ldisc.open)
2076             (tty->ldisc.open)(tty);
2077     }
2078     if (info->blocked_open) {
2079         if (info->close_delay) {
2080             current->state = TASK_INTERRUPTIBLE;
2081             current->timeout = jiffies + info->close_delay;
2082             schedule();
2083         }
2084         wake_up_interruptible(&info->open_wait);
2085     }
2086     info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
2087                      ASYNC_CLOSING);
2088     wake_up_interruptible(&info->close_wait);
2089 
2090 #ifdef SERIAL_DEBUG_OTHER
2091     printk("cy_close done\n");
2092 #endif
2093 
2094     return;
2095 } /* cy_close */
2096 
2097 /*
2098  * cy_hangup() --- called by tty_hangup() when a hangup is signaled.
2099  */
2100 void
2101 cy_hangup(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
2102 {
2103   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
2104         
2105 #ifdef SERIAL_DEBUG_OTHER
2106     printk("cy_hangup ttyC%d\n", info->line); /* */
2107 #endif
2108 
2109     if (serial_paranoia_check(info, tty->device, "cy_hangup"))
2110         return;
2111     
2112     shutdown(info);
2113 #if 0
2114     info->event = 0;
2115     info->count = 0;
2116 #ifdef SERIAL_DEBUG_COUNT
2117     printk("cyc: %d: setting count to 0\n", __LINE__);
2118 #endif
2119     info->tty = 0;
2120 #endif
2121     info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
2122     wake_up_interruptible(&info->open_wait);
2123 } /* cy_hangup */
2124 
2125 
2126 
2127 /*
2128  * ------------------------------------------------------------
2129  * cy_open() and friends
2130  * ------------------------------------------------------------
2131  */
2132 
2133 static int
2134 block_til_ready(struct tty_struct *tty, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
2135                            struct cyclades_port *info)
2136 {
2137   struct wait_queue wait = { current, NULL };
2138   struct cyclades_card *cinfo;
2139   unsigned long flags;
2140   int chip, channel;
2141   int retval;
2142   char *base_addr;
2143 
2144     /*
2145      * If the device is in the middle of being closed, then block
2146      * until it's done, and then try again.
2147      */
2148     if (info->flags & ASYNC_CLOSING) {
2149         interruptible_sleep_on(&info->close_wait);
2150         if (info->flags & ASYNC_HUP_NOTIFY){
2151             return -EAGAIN;
2152         }else{
2153             return -ERESTARTSYS;
2154         }
2155     }
2156 
2157     /*
2158      * If this is a callout device, then just make sure the normal
2159      * device isn't being used.
2160      */
2161     if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
2162         if (info->flags & ASYNC_NORMAL_ACTIVE){
2163             return -EBUSY;
2164         }
2165         if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
2166             (info->flags & ASYNC_SESSION_LOCKOUT) &&
2167             (info->session != current->session)){
2168             return -EBUSY;
2169         }
2170         if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
2171             (info->flags & ASYNC_PGRP_LOCKOUT) &&
2172             (info->pgrp != current->pgrp)){
2173             return -EBUSY;
2174         }
2175         info->flags |= ASYNC_CALLOUT_ACTIVE;
2176         return 0;
2177     }
2178 
2179     /*
2180      * If non-blocking mode is set, then make the check up front
2181      * and then exit.
2182      */
2183     if (filp->f_flags & O_NONBLOCK) {
2184         if (info->flags & ASYNC_CALLOUT_ACTIVE){
2185             return -EBUSY;
2186         }
2187         info->flags |= ASYNC_NORMAL_ACTIVE;
2188         return 0;
2189     }
2190 
2191     /*
2192      * Block waiting for the carrier detect and the line to become
2193      * free (i.e., not in use by the callout).  While we are in
2194      * this loop, info->count is dropped by one, so that
2195      * cy_close() knows when to free things.  We restore it upon
2196      * exit, either normal or abnormal.
2197      */
2198     retval = 0;
2199     add_wait_queue(&info->open_wait, &wait);
2200 #ifdef SERIAL_DEBUG_OPEN
2201     printk("block_til_ready before block: ttyC%d, count = %d\n",
2202            info->line, info->count);/**/
2203 #endif
2204     info->count--;
2205 #ifdef SERIAL_DEBUG_COUNT
2206     printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count);
2207 #endif
2208     info->blocked_open++;
2209 
2210     cinfo = &cy_card[info->card];
2211     channel = info->line - cinfo->first_line;
2212     chip = channel>>2;
2213     channel &= 0x03;
2214     base_addr = (char *) (cinfo->base_addr + chip * CyRegSize);
2215 
2216     while (1) {
2217         save_flags(flags); cli();
2218             if (!(info->flags & ASYNC_CALLOUT_ACTIVE)){
2219                 base_addr[CyCAR] = (u_char)channel;
2220                 base_addr[CyMSVR1] = CyRTS;
2221 /* CP('S');CP('4'); */
2222                 base_addr[CyMSVR2] = CyDTR;
2223 #ifdef SERIAL_DEBUG_DTR
2224                 printk("cyc: %d: raising DTR\n", __LINE__);
2225                 printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
2226 #endif
2227             }
2228         restore_flags(flags);
2229         current->state = TASK_INTERRUPTIBLE;
2230         if (tty_hung_up_p(filp)
2231         || !(info->flags & ASYNC_INITIALIZED) ){
2232             if (info->flags & ASYNC_HUP_NOTIFY) {
2233                 retval = -EAGAIN;
2234             }else{
2235                 retval = -ERESTARTSYS;
2236             }
2237             break;
2238         }
2239         save_flags(flags); cli();
2240             base_addr[CyCAR] = (u_char)channel;
2241 /* CP('L');CP1(1 && C_CLOCAL(tty)); CP1(1 && (base_addr[CyMSVR1] & CyDCD) ); */
2242             if (!(info->flags & ASYNC_CALLOUT_ACTIVE)
2243             && !(info->flags & ASYNC_CLOSING)
2244             && (C_CLOCAL(tty)
2245                 || (base_addr[CyMSVR1] & CyDCD))) {
2246                     restore_flags(flags);
2247                     break;
2248             }
2249         restore_flags(flags);
2250         if (current->signal & ~current->blocked) {
2251             retval = -ERESTARTSYS;
2252             break;
2253         }
2254 #ifdef SERIAL_DEBUG_OPEN
2255         printk("block_til_ready blocking: ttyC%d, count = %d\n",
2256                info->line, info->count);/**/
2257 #endif
2258         schedule();
2259     }
2260     current->state = TASK_RUNNING;
2261     remove_wait_queue(&info->open_wait, &wait);
2262     if (!tty_hung_up_p(filp)){
2263         info->count++;
2264 #ifdef SERIAL_DEBUG_COUNT
2265     printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
2266 #endif
2267     }
2268     info->blocked_open--;
2269 #ifdef SERIAL_DEBUG_OPEN
2270     printk("block_til_ready after blocking: ttyC%d, count = %d\n",
2271            info->line, info->count);/**/
2272 #endif
2273     if (retval)
2274             return retval;
2275     info->flags |= ASYNC_NORMAL_ACTIVE;
2276     return 0;
2277 } /* block_til_ready */
2278 
2279 /*
2280  * This routine is called whenever a serial port is opened.  It
2281  * performs the serial-specific initialization for the tty structure.
2282  */
2283 int
2284 cy_open(struct tty_struct *tty, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
2285 {
2286   struct cyclades_port  *info;
2287   int retval, line;
2288 
2289 /* CP('O'); */
2290     line = MINOR(tty->device) - tty->driver.minor_start;
2291     if ((line < 0) || (NR_PORTS <= line)){
2292         return -ENODEV;
2293     }
2294     info = &cy_port[line];
2295 #ifdef SERIAL_DEBUG_OTHER
2296     printk("cy_open ttyC%d\n", info->line); /* */
2297 #endif
2298     if (serial_paranoia_check(info, tty->device, "cy_open")){
2299         return -ENODEV;
2300     }
2301 #ifdef SERIAL_DEBUG_OPEN
2302     printk("cy_open ttyC%d, count = %d\n", info->line, info->count);/**/
2303 #endif
2304     info->count++;
2305 #ifdef SERIAL_DEBUG_COUNT
2306     printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
2307 #endif
2308     tty->driver_data = info;
2309     info->tty = tty;
2310 
2311     if (!tmp_buf) {
2312         tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL);
2313         if (!tmp_buf){
2314             return -ENOMEM;
2315         }
2316     }
2317 
2318     if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
2319         if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
2320             *tty->termios = info->normal_termios;
2321         else 
2322             *tty->termios = info->callout_termios;
2323     }
2324     /*
2325      * Start up serial port
2326      */
2327     retval = startup(info);
2328     if (retval){
2329         return retval;
2330     }
2331 
2332     retval = block_til_ready(tty, filp, info);
2333     if (retval) {
2334 #ifdef SERIAL_DEBUG_OPEN
2335         printk("cy_open returning after block_til_ready with %d\n",
2336                retval);
2337 #endif
2338         return retval;
2339     }
2340 
2341     info->session = current->session;
2342     info->pgrp = current->pgrp;
2343 
2344 #ifdef SERIAL_DEBUG_OPEN
2345     printk("cy_open done\n");/**/
2346 #endif
2347     return 0;
2348 } /* cy_open */
2349 
2350 
2351 
2352 /*
2353  * ---------------------------------------------------------------------
2354  * cy_init() and friends
2355  *
2356  * cy_init() is called at boot-time to initialize the serial driver.
2357  * ---------------------------------------------------------------------
2358  */
2359 
2360 /*
2361  * This routine prints out the appropriate serial driver version
2362  * number, and identifies which options were configured into this
2363  * driver.
2364  */
2365 static void
2366 show_version(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2367 {
2368     printk("Cyclom driver %s\n",rcsid);
2369 } /* show_version */
2370 
2371 /* initialize chips on card -- return number of valid
2372    chips (which is number of ports/4) */
2373 int
2374 cy_init_card(unsigned char *base_addr)
     /* [previous][next][first][last][top][bottom][index][help] */
2375 {
2376   volatile unsigned short discard;
2377   unsigned int chip_number;
2378 
2379     discard = base_addr[Cy_HwReset]; /* Cy_HwReset is 0x1400 */
2380     discard = base_addr[Cy_ClrIntr]; /* Cy_ClrIntr is 0x1800 */
2381     udelay(500L);
2382 
2383     for(chip_number=0; chip_number<CyMaxChipsPerCard; chip_number++){
2384         udelay(1000L);
2385         if(base_addr[CyCCR] != 0x00){
2386             /*************
2387             printk(" chip #%d at %#6lx is never idle (CCR != 0)\n",
2388                chip_number, (unsigned long)base_addr);
2389             *************/
2390             return chip_number;
2391         }
2392 
2393         base_addr[CyGFRCR] = 0;
2394         udelay(10L);
2395 
2396         base_addr[CyCCR] = CyCHIP_RESET;
2397         udelay(1000L);
2398 
2399         if(base_addr[CyGFRCR] == 0x00){
2400             printk(" chip #%d at %#6lx is not responding (GFRCR stayed 0)\n",
2401                chip_number, (unsigned long)base_addr);
2402             return chip_number;
2403         }
2404         if((0xf0 & base_addr[CyGFRCR]) != 0x40){
2405             printk(" chip #%d at %#6lx is not valid (GFRCR == %#2x)\n",
2406                chip_number, (unsigned long)base_addr, base_addr[CyGFRCR]);
2407             return chip_number;
2408         }
2409         base_addr[CyGCR] = CyCH0_SERIAL;
2410         base_addr[CyPPR] = CyCLOCK_25_1MS * 5; /* run clock at 200 Hz */
2411 
2412         printk(" chip #%d at %#6lx is rev 0x%2x\n",
2413                chip_number, (unsigned long)base_addr, base_addr[CyGFRCR]);
2414 
2415         /* advance to next chip on card */
2416         base_addr += CyRegSize;
2417     }
2418 
2419     return chip_number;
2420 } /* cy_init_card */
2421 
2422 /* The serial driver boot-time initialization code!
2423     Hardware I/O ports are mapped to character special devices on a
2424     first found, first allocated manner.  That is, this code searches
2425     for Cyclom cards in the system.  As each is found, it is probed
2426     to discover how many chips (and thus how many ports) are present.
2427     These ports are mapped to the tty ports 32 and upward in monotonic
2428     fashion.  If an 8-port card is replaced with a 16-port card, the
2429     port mapping on a following card will shift.
2430 
2431     This approach is different from what is used in the other serial
2432     device driver because the Cyclom is more properly a multiplexer,
2433     not just an aggregation of serial ports on one card.
2434 
2435     If there are more cards with more ports than have been statically
2436     allocated above, a warning is printed and the extra ports are ignored.
2437  */
2438 long
2439 cy_init(long kmem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
2440 {
2441   struct cyclades_port *info;
2442   struct cyclades_card *cinfo;
2443   int good_ports = 0;
2444   int port_num = 0;
2445   int index;
2446 #ifdef notyet
2447   struct sigaction sa;
2448 #endif
2449   int retval;
2450 
2451 scrn[1] = '\0';
2452     show_version();
2453 
2454     /* Initialize the tty_driver structure */
2455     
2456     memset(&cy_serial_driver, 0, sizeof(struct tty_driver));
2457     cy_serial_driver.magic = TTY_DRIVER_MAGIC;
2458     cy_serial_driver.name = "ttyC";
2459     cy_serial_driver.major = 19 /* TTY_MAJOR */;
2460     cy_serial_driver.minor_start = 32;
2461     cy_serial_driver.num = NR_PORTS;
2462     cy_serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
2463     cy_serial_driver.subtype = SERIAL_TYPE_NORMAL;
2464     cy_serial_driver.init_termios = tty_std_termios;
2465     cy_serial_driver.init_termios.c_cflag =
2466             B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2467     cy_serial_driver.flags = TTY_DRIVER_REAL_RAW;
2468     cy_serial_driver.refcount = &serial_refcount;
2469     cy_serial_driver.table = serial_table;
2470     cy_serial_driver.termios = serial_termios;
2471     cy_serial_driver.termios_locked = serial_termios_locked;
2472     cy_serial_driver.open = cy_open;
2473     cy_serial_driver.close = cy_close;
2474     cy_serial_driver.write = cy_write;
2475     cy_serial_driver.put_char = cy_put_char;
2476     cy_serial_driver.flush_chars = cy_flush_chars;
2477     cy_serial_driver.write_room = cy_write_room;
2478     cy_serial_driver.chars_in_buffer = cy_chars_in_buffer;
2479     cy_serial_driver.flush_buffer = cy_flush_buffer;
2480     cy_serial_driver.ioctl = cy_ioctl;
2481     cy_serial_driver.throttle = cy_throttle;
2482     cy_serial_driver.unthrottle = cy_unthrottle;
2483     cy_serial_driver.set_termios = cy_set_termios;
2484     cy_serial_driver.stop = cy_stop;
2485     cy_serial_driver.start = cy_start;
2486     cy_serial_driver.hangup = cy_hangup;
2487 
2488     /*
2489      * The callout device is just like normal device except for
2490      * major number and the subtype code.
2491      */
2492     cy_callout_driver = cy_serial_driver;
2493     cy_callout_driver.name = "cub";
2494     cy_callout_driver.major = 20 /* TTYAUX_MAJOR */;
2495     cy_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
2496 
2497     if (tty_register_driver(&cy_serial_driver))
2498             panic("Couldn't register Cyclom serial driver\n");
2499     if (tty_register_driver(&cy_callout_driver))
2500             panic("Couldn't register Cyclom callout driver\n");
2501 
2502     bh_base[CYCLADES_BH].routine = do_cyclades_bh;
2503 
2504     for (index = 0; index < 16; index++) {
2505             IRQ_cards[index] = 0;
2506     }
2507 
2508     port_num = 0;
2509     info = cy_port;
2510     for (index = 0, cinfo = cy_card; index < NR_CARDS; index++,cinfo++) {
2511         /*** initialize card ***/
2512         if(0 == (cinfo->num_chips =
2513                     cy_init_card((unsigned char *)cinfo->base_addr))){
2514             /* this card is not present */
2515             continue;
2516         }
2517 
2518 #ifndef CY_DONT_PROBE
2519         /* find out the board's irq by probing */
2520         cinfo->irq = do_auto_irq(index);
2521 #endif
2522 
2523         /** bind IRQ to card **/
2524         if (cinfo->irq) {
2525             retval = request_irq(cinfo->irq, cy_interrupt,
2526                                 SA_INTERRUPT, "cyclades");
2527             if (retval){
2528                 printk("request_irq returned %d\n",retval);
2529                 /* return retval; */
2530             }
2531             IRQ_cards[cinfo->irq] = cinfo;
2532         }else{
2533             printk("couldn't get board's irq\n");
2534             continue;
2535         }
2536 
2537         printk("  share IRQ %d: ", cinfo->irq);
2538         good_ports = 4 * cinfo->num_chips;
2539 
2540         if(port_num < NR_PORTS){
2541             cinfo->first_line = port_num;
2542             while( good_ports-- && port_num < NR_PORTS){
2543                 /*** initialize port ***/
2544                 info->magic = CYCLADES_MAGIC;
2545                 info->type = PORT_CIRRUS;
2546                 info->card = index;
2547                 info->line = port_num;
2548                 info->flags = STD_COM_FLAGS;
2549                 info->tty = 0;
2550                 info->xmit_fifo_size = 12;
2551                 info->cor1 = CyPARITY_NONE|Cy_1_STOP|Cy_8_BITS;
2552                 info->cor2 = CyETC;
2553                 info->cor3 = 0x08; /* _very_ small receive threshold */
2554                 info->cor4 = 0;
2555                 info->cor5 = 0;
2556                 info->tbpr = baud_bpr[13]; /* Tx BPR */
2557                 info->tco = baud_co[13]; /* Tx CO */
2558                 info->rbpr = baud_bpr[13]; /* Rx BPR */
2559                 info->rco = baud_co[13]; /* Rx CO */
2560                 info->close_delay = 0;
2561                 info->x_char = 0;
2562                 info->event = 0;
2563                 info->count = 0;
2564 #ifdef SERIAL_DEBUG_COUNT
2565     printk("cyc: %d: setting count to 0\n", __LINE__);
2566 #endif
2567                 info->blocked_open = 0;
2568                 info->tqueue.routine = do_softint;
2569                 info->tqueue.data = info;
2570                 info->callout_termios =cy_callout_driver.init_termios;
2571                 info->normal_termios = cy_serial_driver.init_termios;
2572                 info->open_wait = 0;
2573                 info->close_wait = 0;
2574                 /* info->session */
2575                 /* info->pgrp */
2576                 /* info->read_status_mask */
2577                 /* info->timeout */
2578 
2579                 printk("ttyC%1d ", info->line);
2580                 port_num++;info++;
2581                 if(!(port_num & 7)){
2582                     printk("\n               ");
2583                 }
2584             }
2585         }else{
2586             cinfo->first_line = -1;
2587         }
2588         printk("\n");
2589     }
2590     while( port_num < NR_PORTS){
2591         info->line = -1;
2592         port_num++;info++;
2593     }
2594     return kmem_start;
2595     
2596 } /* cy_init */
2597 
2598 static void
2599 show_status(int line_num)
     /* [previous][next][first][last][top][bottom][index][help] */
2600 {
2601   unsigned char *base_addr;
2602   int card,chip,channel;
2603   struct cyclades_port * info;
2604   unsigned long flags;
2605 
2606     info = &cy_port[line_num];
2607     card = info->card;
2608     channel = (info->line) - (cy_card[card].first_line);
2609     chip = channel>>2;
2610     channel &= 0x03;
2611     printk("  card %d, chip %d, channel %d\n", card, chip, channel);/**/
2612 
2613     printk(" cy_card\n");
2614     printk("  irq base_addr num_chips first_line = %d %lx %d %d\n",
2615            cy_card[card].irq, (long)cy_card[card].base_addr,
2616            cy_card[card].num_chips, cy_card[card].first_line);
2617 
2618     printk(" cy_port\n");
2619     printk("  card line flags = %d %d %x\n",
2620                  info->card, info->line, info->flags);
2621     printk("  *tty read_status_mask timeout xmit_fifo_size = %lx %x %x %x\n",
2622                  (long)info->tty, info->read_status_mask,
2623                  info->timeout, info->xmit_fifo_size);
2624     printk("  cor1,cor2,cor3,cor4,cor5 = %x %x %x %x %x\n",
2625              info->cor1, info->cor2, info->cor3, info->cor4, info->cor5);
2626     printk("  tbpr,tco,rbpr,rco = %d %d %d %d\n",
2627              info->tbpr, info->tco, info->rbpr, info->rco);
2628     printk("  close_delay event count = %d %d %d\n",
2629              info->close_delay, info->event, info->count);
2630     printk("  x_char blocked_open = %x %x\n",
2631              info->x_char, info->blocked_open);
2632     printk("  session pgrp open_wait = %lx %lx %lx\n",
2633              info->session, info->pgrp, (long)info->open_wait);
2634 
2635 
2636     save_flags(flags); cli();
2637 
2638         base_addr = (unsigned char*)
2639                        (cy_card[card].base_addr + chip * CyRegSize);
2640 
2641 /* Global Registers */
2642 
2643         printk(" CyGFRCR %x\n", base_addr[CyGFRCR]);
2644         printk(" CyCAR %x\n", base_addr[CyCAR]);
2645         printk(" CyGCR %x\n", base_addr[CyGCR]);
2646         printk(" CySVRR %x\n", base_addr[CySVRR]);
2647         printk(" CyRICR %x\n", base_addr[CyRICR]);
2648         printk(" CyTICR %x\n", base_addr[CyTICR]);
2649         printk(" CyMICR %x\n", base_addr[CyMICR]);
2650         printk(" CyRIR %x\n", base_addr[CyRIR]);
2651         printk(" CyTIR %x\n", base_addr[CyTIR]);
2652         printk(" CyMIR %x\n", base_addr[CyMIR]);
2653         printk(" CyPPR %x\n", base_addr[CyPPR]);
2654 
2655         base_addr[CyCAR] = (u_char)channel;
2656 
2657 /* Virtual Registers */
2658 
2659         printk(" CyRIVR %x\n", base_addr[CyRIVR]);
2660         printk(" CyTIVR %x\n", base_addr[CyTIVR]);
2661         printk(" CyMIVR %x\n", base_addr[CyMIVR]);
2662         printk(" CyMISR %x\n", base_addr[CyMISR]);
2663 
2664 /* Channel Registers */
2665 
2666         printk(" CyCCR %x\n", base_addr[CyCCR]);
2667         printk(" CySRER %x\n", base_addr[CySRER]);
2668         printk(" CyCOR1 %x\n", base_addr[CyCOR1]);
2669         printk(" CyCOR2 %x\n", base_addr[CyCOR2]);
2670         printk(" CyCOR3 %x\n", base_addr[CyCOR3]);
2671         printk(" CyCOR4 %x\n", base_addr[CyCOR4]);
2672         printk(" CyCOR5 %x\n", base_addr[CyCOR5]);
2673         printk(" CyCCSR %x\n", base_addr[CyCCSR]);
2674         printk(" CyRDCR %x\n", base_addr[CyRDCR]);
2675         printk(" CySCHR1 %x\n", base_addr[CySCHR1]);
2676         printk(" CySCHR2 %x\n", base_addr[CySCHR2]);
2677         printk(" CySCHR3 %x\n", base_addr[CySCHR3]);
2678         printk(" CySCHR4 %x\n", base_addr[CySCHR4]);
2679         printk(" CySCRL %x\n", base_addr[CySCRL]);
2680         printk(" CySCRH %x\n", base_addr[CySCRH]);
2681         printk(" CyLNC %x\n", base_addr[CyLNC]);
2682         printk(" CyMCOR1 %x\n", base_addr[CyMCOR1]);
2683         printk(" CyMCOR2 %x\n", base_addr[CyMCOR2]);
2684         printk(" CyRTPR %x\n", base_addr[CyRTPR]);
2685         printk(" CyMSVR1 %x\n", base_addr[CyMSVR1]);
2686         printk(" CyMSVR2 %x\n", base_addr[CyMSVR2]);
2687         printk(" CyRBPR %x\n", base_addr[CyRBPR]);
2688         printk(" CyRCOR %x\n", base_addr[CyRCOR]);
2689         printk(" CyTBPR %x\n", base_addr[CyTBPR]);
2690         printk(" CyTCOR %x\n", base_addr[CyTCOR]);
2691 
2692     restore_flags(flags);
2693 } /* show_status */
2694 
2695 

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