root/drivers/char/cyclades.c

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

DEFINITIONS

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

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

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