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

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