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. get_mon_info
  39. set_threshold
  40. get_threshold
  41. set_default_threshold
  42. get_default_threshold
  43. set_timeout
  44. get_timeout
  45. set_default_timeout
  46. get_default_timeout
  47. cy_ioctl
  48. cy_set_termios
  49. cy_close
  50. cy_hangup
  51. block_til_ready
  52. cy_open
  53. show_version
  54. cy_init_card
  55. cy_init
  56. show_status

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

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