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. init_module
  57. cleanup_module
  58. cy_detect_isa
  59. cy_detect_pci
  60. show_status

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

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