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

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