root/drivers/char/serial.c

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

DEFINITIONS

This source file includes following definitions.
  1. serial_in
  2. serial_inp
  3. serial_out
  4. serial_outp
  5. rs_stop
  6. rs_start
  7. rs_probe
  8. rs_sched_event
  9. receive_chars
  10. transmit_chars
  11. check_modem_status
  12. figure_RS_timer
  13. rs_interrupt
  14. handle_rs_break
  15. do_softint
  16. rs_timer
  17. grab_all_interrupts
  18. free_all_interrupts
  19. figure_IRQ_timeout
  20. unlink_port
  21. link_port
  22. startup
  23. shutdown
  24. change_speed
  25. restart_port
  26. rs_write
  27. rs_throttle
  28. get_serial_info
  29. set_serial_info
  30. get_modem_info
  31. set_modem_info
  32. do_autoconfig
  33. send_break
  34. check_wild_interrupts
  35. rs_ioctl
  36. rs_set_termios
  37. rs_close
  38. block_til_ready
  39. rs_open
  40. show_serial_version
  41. get_auto_irq
  42. do_auto_irq
  43. autoconfig
  44. rs_init

   1 /*
   2  *  linux/kernel/serial.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  *
   6  *  Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92.  Now
   7  *  much more extensible to support other serial cards based on the
   8  *  16450/16550A UART's.  Added support for the AST FourPort and the
   9  *  Accent Async board.  
  10  *
  11  *  set_serial_info fixed to set the flags, custom divisor, and uart
  12  *      type fields.  Fix suggested by Michael K. Johnson 12/12/92.
  13  *
  14  * This module exports the following rs232 io functions:
  15  *
  16  *      long rs_init(long);
  17  *      int  rs_open(struct tty_struct * tty, struct file * filp)
  18  */
  19 
  20 #include <linux/errno.h>
  21 #include <linux/signal.h>
  22 #include <linux/sched.h>
  23 #include <linux/timer.h>
  24 #include <linux/tty.h>
  25 #include <linux/serial.h>
  26 #include <linux/interrupt.h>
  27 #include <linux/config.h>
  28 #include <linux/string.h>
  29 #include <linux/fcntl.h>
  30 #include <linux/ptrace.h>
  31 
  32 #include <asm/system.h>
  33 #include <asm/io.h>
  34 #include <asm/segment.h>
  35 #include <asm/bitops.h>
  36 
  37 /*
  38  * Serial driver configuration section.  Here are the various options:
  39  *
  40  * CONFIG_AUTO_IRQ
  41  *              Enables automatic IRQ detection.  I've put in some
  42  *              fixes to this which should make this work much more
  43  *              cleanly than it used to in 0.98pl2-6.  It should be
  44  *              much less vulnerable to false IRQs now.
  45  * 
  46  * CONFIG_AST_FOURPORT
  47  *              Enables support for the AST Fourport serial port.
  48  * 
  49  * CONFIG_ACCENT_ASYNC
  50  *              Enables support for the Accent Async 4 port serial
  51  *              port.
  52  *
  53  * CONFIG_HUB6
  54  *              Enables support for the venerable Bell Technologies
  55  *              HUB6 card.
  56  */
  57 
  58 #undef ISR_HACK
  59 
  60 #define WAKEUP_CHARS (3*TTY_BUF_SIZE/4)
  61 
  62 /*
  63  * rs_event             - Bitfield of serial lines that events pending
  64  *                              to be processed at the next clock tick.
  65  *
  66  * We assume here that int's are 32 bits, so an array of two gives us
  67  * 64 lines, which is the maximum we can support.
  68  */
  69 static int rs_event[2];
  70 
  71 static struct async_struct *IRQ_ports[16];
  72 static int IRQ_active;
  73 static unsigned long IRQ_timer[16];
  74 static int IRQ_timeout[16];
  75 static volatile int rs_irq_triggered;
  76 static volatile int rs_triggered;
  77 static int rs_wild_int_mask;
  78 
  79 static void autoconfig(struct async_struct * info);
  80         
  81 /*
  82  * This assumes you have a 1.8432 MHz clock for your UART.
  83  *
  84  * It'd be nice if someone built a serial card with a 24.576 MHz
  85  * clock, since the 16550A is capable of handling a top speed of 1.5
  86  * megabits/second; but this requires the faster clock.
  87  */
  88 #define BASE_BAUD ( 1843200 / 16 )
  89 
  90 #ifdef CONFIG_AUTO_IRQ
  91 #define AUTO_IRQ_FLAG ASYNC_AUTO_IRQ
  92 #else
  93 #define AUTO_IRQ_FLAG 0
  94 #endif
  95 
  96 /* Standard COM flags (except for COM4, because of the 8514 problem) */
  97 #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | AUTO_IRQ_FLAG)
  98 #define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | AUTO_IRQ_FLAG)
  99 
 100 #ifdef CONFIG_AST_FOURPORT
 101 #define FOURPORT_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_FOURPORT | AUTO_IRQ_FLAG)
 102 #else
 103 #define FOURPORT_FLAGS (ASYNC_FOURPORT | AUTO_IRQ_FLAG)
 104 #endif
 105 
 106 #ifdef CONFIG_ACCENT_ASYNC
 107 #define ACCENT_FLAGS (ASYNC_BOOT_AUTOCONF | AUTO_IRQ_FLAG)
 108 #else
 109 #define ACCENT_FLAGS AUTO_IRQ_FLAG
 110 #endif
 111 
 112 #ifdef CONFIG_BOCA
 113 #define BOCA_FLAGS (ASYNC_BOOT_AUTOCONF | AUTO_IRQ_FLAG)
 114 #else
 115 #define BOCA_FLAGS AUTO_IRQ_FLAG
 116 #endif
 117 
 118 #ifdef CONFIG_HUB6
 119 #define HUB6_FLAGS (ASYNC_BOOT_AUTOCONF)
 120 #else
 121 #define HUB6_FLAGS 0
 122 #endif
 123         
 124 /*
 125  * The following define the access methods for the HUB6 card. All
 126  * access is through two ports for all 24 possible chips. The card is
 127  * selected through the high 2 bits, the port on that card with the
 128  * "middle" 3 bits, and the register on that port with the bottom
 129  * 3 bits.
 130  *
 131  * While the access port and interrupt is configurable, the default
 132  * port locations are 0x302 for the port control register, and 0x303
 133  * for the data read/write register. Normally, the interrupt is at irq3
 134  * but can be anything from 3 to 7 inclusive. Note tht using 3 will
 135  * require disabling com2.
 136  */
 137 
 138 #define C_P(card,port) (((card)<<6|(port)<<3) + 1)
 139 
 140 struct async_struct rs_table[] = {
 141         /* UART CLK   PORT IRQ     FLAGS        */
 142         { BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },         /* ttyS0 */
 143         { BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },         /* ttyS1 */
 144         { BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },         /* ttyS2 */
 145         { BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },        /* ttyS3 */
 146 
 147         { BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS },        /* ttyS4 */
 148         { BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },        /* ttyS5 */
 149         { BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },        /* ttyS6 */
 150         { BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },        /* ttyS7 */
 151 
 152         { BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },        /* ttyS8 */
 153         { BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },        /* ttyS9 */
 154         { BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },        /* ttyS10 */
 155         { BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },        /* ttyS11 */
 156         
 157         { BASE_BAUD, 0x330, 4, ACCENT_FLAGS },          /* ttyS12 */
 158         { BASE_BAUD, 0x338, 4, ACCENT_FLAGS },          /* ttyS13 */
 159         { BASE_BAUD, 0x000, 0, 0 },     /* ttyS14 (spare; user configurable) */
 160         { BASE_BAUD, 0x000, 0, 0 },     /* ttyS15 (spare; user configurable) */
 161 
 162         { BASE_BAUD, 0x100, 12, BOCA_FLAGS },   /* ttyS16 */
 163         { BASE_BAUD, 0x108, 12, BOCA_FLAGS },   /* ttyS17 */
 164         { BASE_BAUD, 0x110, 12, BOCA_FLAGS },   /* ttyS18 */
 165         { BASE_BAUD, 0x118, 12, BOCA_FLAGS },   /* ttyS19 */
 166         { BASE_BAUD, 0x120, 12, BOCA_FLAGS },   /* ttyS20 */
 167         { BASE_BAUD, 0x128, 12, BOCA_FLAGS },   /* ttyS21 */
 168         { BASE_BAUD, 0x130, 12, BOCA_FLAGS },   /* ttyS22 */
 169         { BASE_BAUD, 0x138, 12, BOCA_FLAGS },   /* ttyS23 */
 170         { BASE_BAUD, 0x140, 12, BOCA_FLAGS },   /* ttyS24 */
 171         { BASE_BAUD, 0x148, 12, BOCA_FLAGS },   /* ttyS25 */
 172         { BASE_BAUD, 0x150, 12, BOCA_FLAGS },   /* ttyS26 */
 173         { BASE_BAUD, 0x158, 12, BOCA_FLAGS },   /* ttyS27 */
 174         { BASE_BAUD, 0x160, 12, BOCA_FLAGS },   /* ttyS28 */
 175         { BASE_BAUD, 0x168, 12, BOCA_FLAGS },   /* ttyS29 */
 176         { BASE_BAUD, 0x170, 12, BOCA_FLAGS },   /* ttyS30 */
 177         { BASE_BAUD, 0x178, 12, BOCA_FLAGS },   /* ttyS31 */
 178 
 179 /* You can have up to four HUB6's in the system, but I've only
 180  * included two cards here for a total of twelve ports.
 181  */
 182         { BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) },  /* ttyS32 */
 183         { BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) },  /* ttyS33 */
 184         { BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) },  /* ttyS34 */
 185         { BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) },  /* ttyS35 */
 186         { BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) },  /* ttyS36 */
 187         { BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) },  /* ttyS37 */
 188         { BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) },  /* ttyS32 */
 189         { BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) },  /* ttyS33 */
 190         { BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) },  /* ttyS34 */
 191         { BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) },  /* ttyS35 */
 192         { BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) },  /* ttyS36 */
 193         { BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) },  /* ttyS37 */
 194 };
 195 
 196 #define NR_PORTS        (sizeof(rs_table)/sizeof(struct async_struct))
 197 
 198 /*
 199  * This is used to figure out the divsor speeds and the timeouts
 200  */
 201 static int baud_table[] = {
 202         0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
 203         9600, 19200, 38400, 57600, 115200, 0 };
 204 
 205 static void rs_throttle(struct tty_struct * tty, int status);
 206 
 207 static inline unsigned int serial_in(struct async_struct *info, int offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 208 {
 209     if (info->hub6) {
 210         outb(info->hub6 - 1 + offset, info->port);
 211         return inb(info->port+1);
 212     } else
 213         return inb(info->port + offset);
 214 }
 215 
 216 static inline unsigned int serial_inp(struct async_struct *info, int offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 217 {
 218     if (info->hub6) {
 219         outb(info->hub6 - 1 + offset, info->port);
 220         return inb_p(info->port+1);
 221     } else
 222         return inb_p(info->port + offset);
 223 }
 224 
 225 static inline void serial_out(struct async_struct *info, int offset, int value)
     /* [previous][next][first][last][top][bottom][index][help] */
 226 {
 227     if (info->hub6) {
 228         outb(info->hub6 - 1 + offset, info->port);
 229         outb(value, info->port+1);
 230     } else
 231         outb(value, info->port+offset);
 232 }
 233 
 234 static inline void serial_outp(struct async_struct *info, int offset,
     /* [previous][next][first][last][top][bottom][index][help] */
 235                                int value)
 236 {
 237     if (info->hub6) {
 238         outb(info->hub6 - 1 + offset, info->port);
 239         outb_p(value, info->port+1);
 240     } else
 241         outb_p(value, info->port+offset);
 242 }
 243 
 244 /*
 245  * ------------------------------------------------------------
 246  * rs_stop() and rs_start()
 247  *
 248  * This routines are called before setting or resetting tty->stopped.
 249  * They enable or disable transmitter interrupts, as necessary.
 250  * ------------------------------------------------------------
 251  */
 252 static void rs_stop(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 253 {
 254         struct async_struct *info;
 255         
 256         info = rs_table + DEV_TO_SL(tty->line);
 257         
 258         info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
 259 #ifdef ISR_HACK
 260         serial_out(info, UART_IER, info->IER);
 261 #endif
 262 }
 263 
 264 static void rs_start(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 265 {
 266         struct async_struct *info;
 267         
 268         info = rs_table + DEV_TO_SL(tty->line);
 269         
 270         info->IER = (UART_IER_MSI | UART_IER_RLSI |
 271                      UART_IER_THRI | UART_IER_RDI);
 272 #ifdef ISR_HACK
 273         serial_out(info, UART_IER, info->IER);
 274 #endif
 275 }
 276 
 277 /*
 278  * ----------------------------------------------------------------------
 279  *
 280  * Here starts the interrupt handling routines.  All of the following
 281  * subroutines are declared as inline and are folded into
 282  * rs_interrupt().  They were separated out for readability's sake.
 283  *
 284  * Note: rs_interrupt() is a "fast" interrupt, which means that it
 285  * runs with interrupts turned off.  People who may want to modify
 286  * rs_interrupt() should try to keep the interrupt handler as fast as
 287  * possible.  After you are done making modifications, it is not a bad
 288  * idea to do:
 289  * 
 290  * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
 291  *
 292  * and look at the resulting assemble code in serial.s.
 293  *
 294  *                              - Ted Ts'o (tytso@mit.edu), 7-Mar-93
 295  * -----------------------------------------------------------------------
 296  */
 297 
 298 /*
 299  * This is the serial driver's interrupt routine while we are probing
 300  * for submarines.
 301  */
 302 static void rs_probe(int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
 303 {
 304         rs_irq_triggered = irq;
 305         rs_triggered |= 1 << irq;
 306         return;
 307 }
 308 
 309 /*
 310  * This routine is used by the interrupt handler to schedule
 311  * processing in the software interrupt portion of the driver.
 312  */
 313 static inline void rs_sched_event(struct async_struct *info,
     /* [previous][next][first][last][top][bottom][index][help] */
 314                                   int event)
 315 {
 316         info->event |= 1 << event;
 317         set_bit(info->line, rs_event);
 318         mark_bh(SERIAL_BH);
 319 }
 320 
 321 static inline void receive_chars(struct async_struct *info,
     /* [previous][next][first][last][top][bottom][index][help] */
 322                                  int *status)
 323 {
 324         struct tty_queue * queue;
 325         int head, tail, ch;
 326 
 327 /*
 328  * Just like the LEFT(x) macro, except it uses the loal tail
 329  * and head variables.
 330  */
 331 #define VLEFT ((tail-head-1)&(TTY_BUF_SIZE-1))
 332 
 333         queue = &info->tty->read_q;
 334         head = queue->head;
 335         tail = queue->tail;
 336         do {
 337                 ch = serial_inp(info, UART_RX);
 338                 /*
 339                  * There must be at least 2 characters
 340                  * free in the queue; otherwise we punt.
 341                  */
 342                 if (VLEFT < 2)
 343                         break;
 344                 if (*status & info->read_status_mask) {
 345                         set_bit(head, &info->tty->readq_flags);
 346                         if (*status & (UART_LSR_BI)) {
 347                                 queue->buf[head++]= TTY_BREAK;
 348                                 rs_sched_event(info, RS_EVENT_BREAK);
 349                         } else if (*status & UART_LSR_PE)
 350                                 queue->buf[head++]= TTY_PARITY;
 351                         else if (*status & UART_LSR_FE)
 352                                 queue->buf[head++]= TTY_FRAME;
 353                         head &= TTY_BUF_SIZE-1;
 354                 }
 355                 queue->buf[head++] = ch;
 356                 head &= TTY_BUF_SIZE-1;
 357         } while ((*status = serial_inp(info, UART_LSR)) & UART_LSR_DR);
 358         queue->head = head;
 359         if ((VLEFT < RQ_THRESHOLD_LW) && !set_bit(TTY_RQ_THROTTLED,
 360                                                   &info->tty->flags)) 
 361                 rs_throttle(info->tty, TTY_THROTTLE_RQ_FULL);
 362         rs_sched_event(info, RS_EVENT_READ_PROCESS);
 363 #ifdef SERIAL_DEBUG_INTR
 364         printk("DR...");
 365 #endif
 366 }
 367 
 368 static inline void transmit_chars(struct async_struct *info, int *done_work)
     /* [previous][next][first][last][top][bottom][index][help] */
 369 {
 370         struct tty_queue * queue;
 371         int head, tail, count;
 372         
 373         queue = &info->tty->write_q;
 374         head = queue->head;
 375         tail = queue->tail;
 376         if (head==tail && !info->x_char) {
 377                 info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
 378 #ifdef ISR_HACK
 379                 serial_out(info, UART_IER, info->IER);
 380 #endif
 381                 return;
 382         }
 383         count = info->xmit_fifo_size;
 384         if (info->x_char) {
 385                 serial_outp(info, UART_TX, info->x_char);
 386                 info->x_char = 0;
 387                 count--;
 388         }
 389         while (count-- && (tail != head)) {
 390                 serial_outp(info, UART_TX, queue->buf[tail++]);
 391                 tail &= TTY_BUF_SIZE-1;
 392         }
 393         queue->tail = tail;
 394         if (VLEFT > WAKEUP_CHARS) {
 395                 rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
 396                 if (info->tty->write_data_cnt) {
 397                         set_bit(info->tty->line, &tty_check_write);
 398                         mark_bh(TTY_BH);
 399                 }
 400         }
 401 #ifdef SERIAL_DEBUG_INTR
 402         printk("THRE...");
 403 #endif
 404         (*done_work)++;
 405 }
 406 
 407 static inline int check_modem_status(struct async_struct *info)
     /* [previous][next][first][last][top][bottom][index][help] */
 408 {
 409         int     status;
 410         
 411         status = serial_in(info, UART_MSR);
 412                 
 413         if ((status & UART_MSR_DDCD) && !C_LOCAL(info->tty)) {
 414 #ifdef SERIAL_DEBUG_INTR
 415                 printk("DDCD...");
 416 #endif
 417                 if (status & UART_MSR_DCD)
 418                         rs_sched_event(info, RS_EVENT_OPEN_WAKEUP);
 419                 else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
 420                            (info->flags & ASYNC_CALLOUT_NOHUP))) 
 421                         rs_sched_event(info, RS_EVENT_HANGUP);
 422         }
 423         if (C_RTSCTS(info->tty)) {
 424                 if (info->tty->stopped) {
 425                         if (status & UART_MSR_CTS) {
 426 #ifdef SERIAL_DEBUG_INTR
 427                                 printk("CTS tx start...");
 428 #endif
 429                                 info->tty->stopped = 0;
 430                                 rs_start(info->tty);
 431                                 return 1;
 432                         }
 433                 } else {
 434                         if (!(status & UART_MSR_CTS)) {
 435 #ifdef SERIAL_DEBUG_INTR
 436                                 printk("CTS tx stop...");
 437 #endif
 438                                 info->tty->stopped = 1;
 439                                 rs_stop(info->tty);
 440                         }
 441                 }
 442         }
 443         return 0;
 444 }
 445 
 446 static inline void figure_RS_timer(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 447 {
 448         int     timeout = 6000; /* 60 seconds; really big :-) */
 449         int     i, mask;
 450         
 451         if (!IRQ_active)
 452                 return;
 453         for (i=0, mask = 1; mask <= IRQ_active; i++, mask <<= 1) {
 454                 if (!(mask & IRQ_active))
 455                         continue;
 456                 if (IRQ_timer[i] < timeout)
 457                         timeout = IRQ_timer[i];
 458         }
 459         timer_table[RS_TIMER].expires = jiffies + timeout;
 460         timer_active |= 1 << RS_TIMER;
 461 }
 462 
 463 
 464 /*
 465  * This is the serial driver's generic interrupt routine
 466  */
 467 static void rs_interrupt(int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
 468 {
 469         int status;
 470         struct async_struct * info;
 471         int done, done_work, pass_number, recheck_count;
 472 
 473         rs_irq_triggered = irq;
 474         rs_triggered |= 1 << irq;
 475         
 476         info = IRQ_ports[irq];
 477         done = 1;
 478         done_work = 0;
 479         pass_number = 0;
 480         while (info) {
 481                 if (info->tty &&
 482                     (!pass_number ||
 483                      !(serial_inp(info, UART_IIR) & UART_IIR_NO_INT))) {
 484                         done = 0;
 485                         status = serial_inp(info, UART_LSR);
 486                         if (status & UART_LSR_DR) {
 487                                 receive_chars(info, &status);
 488                                 done_work++;
 489                         }
 490                 recheck_count = 0;
 491                 recheck_write:
 492                         if ((status & UART_LSR_THRE) &&
 493                             !info->tty->stopped) {
 494                                 transmit_chars(info, &done_work);
 495                         }
 496                         if (check_modem_status(info) &&
 497                             (recheck_count++ <= 64))
 498                                 goto recheck_write;
 499 #ifdef SERIAL_DEBUG_INTR
 500                         if (recheck_count > 16)
 501                                 printk("recheck_count = %d\n", recheck_count);
 502 #endif
 503                 }
 504 #ifdef ISR_HACK
 505                 serial_outp(info, UART_IER, 0);
 506                 serial_out(info, UART_IER, info->IER);
 507 #endif
 508                 
 509                 info = info->next_port;
 510                 if (!info && !done) {
 511                         info = IRQ_ports[irq];
 512                         done = 1;
 513                         if (pass_number++ > 64)
 514                                 break;          /* Prevent infinite loops */
 515                 }
 516         }
 517         if ((info = IRQ_ports[irq]) != NULL) {
 518 #ifdef 0
 519                 do {
 520                         serial_outp(info, UART_IER, 0);
 521                         serial_out(info, UART_IER, info->IER);
 522                         info = info->next_port;
 523                 } while (info);
 524 #endif                  
 525                 if (irq && !done_work)
 526                         IRQ_timer[irq] = jiffies + 1500;
 527                 else
 528                         IRQ_timer[irq] = jiffies + IRQ_timeout[irq];
 529                 IRQ_active |= 1 << irq;
 530         }
 531         figure_RS_timer();
 532 }
 533 
 534 /*
 535  * -------------------------------------------------------------------
 536  * Here ends the serial interrupt routines.
 537  * -------------------------------------------------------------------
 538  */
 539 
 540 /*
 541  * This routine is called when we receive a break on a serial line.
 542  * It is executed out of the software interrupt routine.
 543  */
 544 static inline void handle_rs_break(struct async_struct *info)
     /* [previous][next][first][last][top][bottom][index][help] */
 545 {
 546         if (info->flags & ASYNC_SAK)
 547                 do_SAK(info->tty);
 548                 
 549         if (I_BRKINT(info->tty)) {
 550                 flush_input(info->tty);
 551                 flush_output(info->tty);
 552                 if (info->tty->pgrp > 0)
 553                         kill_pg(info->tty->pgrp, SIGINT,1);
 554         }
 555 }
 556 
 557 /*
 558  * This routine is used to handle the "bottom half" processing for the
 559  * serial driver, known also the "software interrupt" processing.
 560  * This processing is done at the kernel interrupt level, after the
 561  * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
 562  * is where time-consuming activities which can not be done in the
 563  * interrupt driver proper are done; the interrupt driver schedules
 564  * them using rs_sched_event(), and they get done here.
 565  */
 566 static void do_softint(void *unused)
     /* [previous][next][first][last][top][bottom][index][help] */
 567 {
 568         int                     i;
 569         struct async_struct     *info;
 570         
 571         for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
 572                 if (clear_bit(i, rs_event)) {
 573                         if (!info->tty) 
 574                                 continue;
 575                         if (clear_bit(RS_EVENT_READ_PROCESS, &info->event)) {
 576                                 TTY_READ_FLUSH(info->tty);
 577                         }
 578                         if (clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
 579                                 wake_up_interruptible(&info->tty->write_q.proc_list);
 580                         }
 581                         if (clear_bit(RS_EVENT_HANGUP, &info->event)) {
 582                                 tty_hangup(info->tty);
 583                                 wake_up_interruptible(&info->open_wait);
 584                                 info->flags &= ~(ASYNC_NORMAL_ACTIVE|
 585                                                  ASYNC_CALLOUT_ACTIVE);
 586                         }
 587                         if (clear_bit(RS_EVENT_BREAK, &info->event))
 588                                 handle_rs_break(info);
 589                         if (clear_bit(RS_EVENT_OPEN_WAKEUP, &info->event)) {
 590                                 wake_up_interruptible(&info->open_wait);
 591                         }
 592                 }
 593         }
 594 }
 595 
 596 /*
 597  * This subroutine is called when the RS_TIMER goes off.  It is used
 598  * by the serial driver to run the rs_interrupt routine at certain
 599  * intervals, either because a serial interrupt might have been lost,
 600  * or because (in the case of IRQ=0) the serial port does not have an
 601  * interrupt, and is being checked only via the timer interrupts.
 602  */
 603 static void rs_timer(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 604 {
 605         int     i, mask;
 606         int     timeout = 0;
 607 
 608         for (i = 0, mask = 1; mask <= IRQ_active; i++, mask <<= 1) {
 609                 if ((mask & IRQ_active) && (IRQ_timer[i] <= jiffies)) {
 610                         IRQ_active &= ~mask;
 611                         cli();
 612                         rs_interrupt(i);
 613                         sti();
 614                 }
 615                 if (mask & IRQ_active) {
 616                         if (!timeout || (IRQ_timer[i] < timeout))
 617                                 timeout = IRQ_timer[i];
 618                 }
 619         }
 620         if (timeout) {
 621                 timer_table[RS_TIMER].expires = timeout;
 622                 timer_active |= 1 << RS_TIMER;
 623         }
 624 }
 625 
 626 /*
 627  * ---------------------------------------------------------------
 628  * Low level utility subroutines for the serial driver:  routines to
 629  * figure out the appropriate timeout for an interrupt chain, routines
 630  * to initialize and startup a serial port, and routines to shutdown a
 631  * serial port.  Useful stuff like that.
 632  * ---------------------------------------------------------------
 633  */
 634 
 635 /*
 636  * Grab all interrupts in preparation for doing an automatic irq
 637  * detection.  dontgrab is a mask of irq's _not_ to grab.  Returns a
 638  * mask of irq's which were grabbed and should therefore be freed
 639  * using free_all_interrupts().
 640  */
 641 static int grab_all_interrupts(int dontgrab)
     /* [previous][next][first][last][top][bottom][index][help] */
 642 {
 643         int                     irq_lines = 0;
 644         int                     i, mask;
 645         struct sigaction        sa;
 646         
 647         sa.sa_handler = rs_probe;
 648         sa.sa_flags = (SA_INTERRUPT);
 649         sa.sa_mask = 0;
 650         sa.sa_restorer = NULL;
 651         
 652         for (i = 0, mask = 1; i < 16; i++, mask <<= 1) {
 653                 if (!(mask & dontgrab) && !irqaction(i, &sa)) {
 654                         irq_lines |= mask;
 655                 }
 656         }
 657         return irq_lines;
 658 }
 659 
 660 /*
 661  * Release all interrupts grabbed by grab_all_interrupts
 662  */
 663 static void free_all_interrupts(int irq_lines)
     /* [previous][next][first][last][top][bottom][index][help] */
 664 {
 665         int     i;
 666         
 667         for (i = 0; i < 16; i++) {
 668                 if (irq_lines & (1 << i))
 669                         free_irq(i);
 670         }
 671 }
 672 
 673 /*
 674  * This routine figures out the correct timeout for a particular IRQ.
 675  * It uses the smallest timeout of all of the serial ports in a
 676  * particular interrupt chain.
 677  */
 678 static void figure_IRQ_timeout(int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
 679 {
 680         struct  async_struct    *info;
 681         int     timeout = 6000; /* 60 seconds === a long time :-) */
 682 
 683         info = IRQ_ports[irq];
 684         if (!info) {
 685                 IRQ_timeout[irq] = 6000;
 686                 return;
 687         }
 688         while (info) {
 689                 if (info->timeout < timeout)
 690                         timeout = info->timeout;
 691                 info = info->next_port;
 692         }
 693         if (!irq)
 694                 timeout = timeout / 2;
 695         IRQ_timeout[irq] = timeout ? timeout : 1;
 696 }
 697 
 698 static inline void unlink_port(struct async_struct *info)
     /* [previous][next][first][last][top][bottom][index][help] */
 699 {
 700 #ifdef SERIAL_DEBUG_OPEN
 701         printk("unlinking serial port %d from irq %d....", info->line,
 702                info->irq);
 703 #endif
 704         if (info->next_port)
 705                 info->next_port->prev_port = info->prev_port;
 706         if (info->prev_port)
 707                 info->prev_port->next_port = info->next_port;
 708         else
 709                 IRQ_ports[info->irq] = info->next_port;
 710         figure_IRQ_timeout(info->irq);
 711 }
 712 
 713 static inline void link_port(struct async_struct *info)
     /* [previous][next][first][last][top][bottom][index][help] */
 714 {
 715 #ifdef SERIAL_DEBUG_OPEN
 716         printk("linking serial port %d into irq %d...", info->line,
 717                info->irq);
 718 #endif
 719         info->prev_port = 0;
 720         info->next_port = IRQ_ports[info->irq];
 721         if (info->next_port)
 722                 info->next_port->prev_port = info;
 723         IRQ_ports[info->irq] = info;
 724         figure_IRQ_timeout(info->irq);
 725 }
 726 
 727 static void startup(struct async_struct * info)
     /* [previous][next][first][last][top][bottom][index][help] */
 728 {
 729         unsigned short ICP;
 730         unsigned long flags;
 731 
 732         save_flags(flags); cli();
 733 
 734         /*
 735          * First, clear the FIFO buffers and disable them
 736          */
 737         if (info->type == PORT_16550A)
 738                 serial_outp(info, UART_FCR, UART_FCR_CLEAR_CMD);
 739 
 740         /*
 741          * Next, clear the interrupt registers.
 742          */
 743         (void)serial_inp(info, UART_LSR);
 744         (void)serial_inp(info, UART_RX);
 745         (void)serial_inp(info, UART_IIR);
 746         (void)serial_inp(info, UART_MSR);
 747 
 748         /*
 749          * Now, initialize the UART 
 750          */
 751         serial_outp(info, UART_LCR, UART_LCR_WLEN8);    /* reset DLAB */
 752         if (info->flags & ASYNC_FOURPORT) 
 753                 serial_outp(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
 754         else
 755                 serial_outp(info, UART_MCR,
 756                             UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
 757         
 758         /*
 759          * Enable FIFO's if necessary
 760          */
 761         if (info->type == PORT_16550A) {
 762                 serial_outp(info, UART_FCR, UART_FCR_SETUP_CMD);
 763                 info->xmit_fifo_size = 16;
 764         } else {
 765                 info->xmit_fifo_size = 1;
 766         }
 767 
 768         /*
 769          * Finally, enable interrupts
 770          */
 771 #ifdef ISR_HACK
 772         info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
 773         serial_outp(info, UART_IER, info->IER); /* enable interrupts */
 774 #else
 775         info->IER = (UART_IER_MSI | UART_IER_RLSI |
 776                      UART_IER_THRI | UART_IER_RDI);
 777         serial_outp(info, UART_IER, info->IER); /* enable all intrs */
 778 #endif
 779         if (info->flags & ASYNC_FOURPORT) {
 780                 /* Enable interrupts on the AST Fourport board */
 781                 ICP = (info->port & 0xFE0) | 0x01F;
 782                 outb_p(0x80, ICP);
 783                 (void) inb_p(ICP);
 784         }
 785 
 786         /*
 787          * And clear the interrupt registers again for luck.
 788          */
 789         (void)serial_inp(info, UART_LSR);
 790         (void)serial_inp(info, UART_RX);
 791         (void)serial_inp(info, UART_IIR);
 792         (void)serial_inp(info, UART_MSR);
 793 
 794         info->flags |= ASYNC_INITIALIZED;
 795         if (info->tty)
 796                 clear_bit(TTY_IO_ERROR, &info->tty->flags);
 797         /*
 798          * Set up parity check flag
 799          */
 800         if (info->tty && info->tty->termios && I_INPCK(info->tty))
 801                 info->read_status_mask = (UART_LSR_OE | UART_LSR_BI |
 802                                           UART_LSR_FE | UART_LSR_PE);
 803         else
 804                 info->read_status_mask = (UART_LSR_OE | UART_LSR_BI |
 805                                           UART_LSR_FE);
 806         restore_flags(flags);
 807 }
 808 
 809 /*
 810  * This routine shutsdown a serial port; interrupts are disabled, and
 811  * DTR is dropped if the hangup on close termio flag is on.
 812  */
 813 static void shutdown(struct async_struct * info)
     /* [previous][next][first][last][top][bottom][index][help] */
 814 {
 815         unsigned long flags;
 816 
 817         save_flags(flags); cli();
 818         info->IER = 0;
 819         serial_outp(info, UART_IER, 0x00);      /* disable all intrs */
 820         if (info->flags & ASYNC_FOURPORT) {
 821                 /* reset interrupts on the AST Fourport board */
 822                 (void) inb((info->port & 0xFE0) | 0x01F);
 823         }
 824         if (info->tty && !(info->tty->termios->c_cflag & HUPCL))
 825                 serial_outp(info, UART_MCR, UART_MCR_DTR);
 826         else
 827                 /* reset DTR,RTS,OUT_2 */               
 828                 serial_outp(info, UART_MCR, 0x00);
 829         serial_outp(info, UART_FCR, UART_FCR_CLEAR_CMD); /* disable FIFO's */
 830         (void)serial_in(info, UART_RX);    /* read data port to reset things */
 831         info->flags &= ~ASYNC_INITIALIZED;
 832         if (info->tty)
 833                 set_bit(TTY_IO_ERROR, &info->tty->flags);
 834         restore_flags(flags);
 835 }
 836 
 837 /*
 838  * This routine is called to set the UART divisor registers to match
 839  * the specified baud rate for a serial port.
 840  */
 841 static void change_speed(unsigned int line)
     /* [previous][next][first][last][top][bottom][index][help] */
 842 {
 843         struct async_struct * info;
 844         unsigned short port;
 845         int     quot = 0;
 846         unsigned cflag,cval,mcr;
 847         int     i;
 848 
 849         if (line >= NR_PORTS)
 850                 return;
 851         info = rs_table + line;
 852         if (!info->tty || !info->tty->termios)
 853                 return;
 854         cflag = info->tty->termios->c_cflag;
 855         if (!(port = info->port))
 856                 return;
 857         i = cflag & CBAUD;
 858         if (i == 15) {
 859                 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
 860                         i += 1;
 861                 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
 862                         i += 2;
 863                 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
 864                         quot = info->custom_divisor;
 865         }
 866         if (quot) {
 867                 info->timeout = ((info->xmit_fifo_size*HZ*15*quot) /
 868                                  info->baud_base) + 2;
 869         } else if (baud_table[i] == 134) {
 870                 quot = (2*info->baud_base / 269);
 871                 info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
 872         } else if (baud_table[i]) {
 873                 quot = info->baud_base / baud_table[i];
 874                 info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
 875         } else {
 876                 quot = 0;
 877                 info->timeout = 0;
 878         }
 879         cli();
 880         mcr = serial_in(info, UART_MCR);
 881         if (quot) 
 882                 serial_out(info, UART_MCR, mcr | UART_MCR_DTR);
 883         else {
 884                 serial_out(info, UART_MCR, mcr & ~UART_MCR_DTR);
 885                 sti();
 886                 return;
 887         }
 888         sti();
 889         /* byte size and parity */
 890         cval = cflag & (CSIZE | CSTOPB);
 891         cval >>= 4;
 892         if (cflag & PARENB)
 893                 cval |= UART_LCR_PARITY;
 894         if (!(cflag & PARODD))
 895                 cval |= UART_LCR_EPAR;
 896         cli();
 897         serial_outp(info, UART_LCR, cval | UART_LCR_DLAB);      /* set DLAB */
 898         serial_outp(info, UART_DLL, quot & 0xff);       /* LS of divisor */
 899         serial_outp(info, UART_DLM, quot >> 8);         /* MS of divisor */
 900         serial_outp(info, UART_LCR, cval);              /* reset DLAB */
 901         sti();
 902 }
 903 
 904 /*
 905  * ------------------------------------------------------------
 906  * rs_write() and friends
 907  * ------------------------------------------------------------
 908  */
 909 
 910 /*
 911  * This routine is used by rs_write to restart transmitter interrupts,
 912  * which are disabled after we have a transmitter interrupt which went
 913  * unacknowledged because we had run out of data to transmit.
 914  * 
 915  * Note: this subroutine must be called with the interrupts *off*
 916  */
 917 static inline void restart_port(struct async_struct *info)
     /* [previous][next][first][last][top][bottom][index][help] */
 918 {
 919         struct tty_queue * queue;
 920         int head, tail, count;
 921         
 922         if (!info)
 923                 return;
 924 
 925         if (serial_inp(info, UART_LSR) & UART_LSR_THRE) {
 926                 if (info->x_char) {
 927                         serial_outp(info, UART_TX, info->x_char);
 928                         info->x_char = 0;
 929                 } else {
 930                         queue = &info->tty->write_q;
 931                         head = queue->head;
 932                         tail = queue->tail;
 933                         count = info->xmit_fifo_size;
 934                         while (count--) {
 935                                 if (tail == head)
 936                                         break;
 937                                 serial_outp(info, UART_TX, queue->buf[tail++]);
 938                                 tail &= TTY_BUF_SIZE-1;
 939                         }
 940                         queue->tail = tail;
 941                 }
 942         }
 943 }       
 944 
 945 /*
 946  * This routine gets called when tty_write has put something into
 947  * the write_queue.  
 948  */
 949 void rs_write(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 950 {
 951         struct async_struct *info;
 952 
 953         if (!tty || tty->stopped)
 954                 return;
 955         info = rs_table + DEV_TO_SL(tty->line);
 956         if (!info)
 957                 return;
 958         cli();
 959         restart_port(info);
 960         info->IER = (UART_IER_MSI | UART_IER_RLSI |
 961                      UART_IER_THRI | UART_IER_RDI);
 962 #ifdef ISR_HACK
 963         serial_out(info, UART_IER, info->IER);
 964 #endif
 965         sti();
 966 }
 967 
 968 /*
 969  * ------------------------------------------------------------
 970  * rs_throttle()
 971  * 
 972  * This routine is called by the upper-layer tty layer to signal that
 973  * incoming characters should be throttled (and that the throttle
 974  * should be released).
 975  * ------------------------------------------------------------
 976  */
 977 static void rs_throttle(struct tty_struct * tty, int status)
     /* [previous][next][first][last][top][bottom][index][help] */
 978 {
 979         struct async_struct *info;
 980         unsigned char mcr;
 981         unsigned long flags;
 982 
 983         save_flags(flags); cli();
 984 #if SERIAL_DEBUG_THROTTLE
 985         printk("throttle tty%d: %d (%d, %d)....\n", DEV_TO_SL(tty->line),
 986                status, LEFT(&tty->read_q), LEFT(&tty->secondary));
 987 #endif
 988         switch (status) {
 989         case TTY_THROTTLE_RQ_FULL:
 990                 info = rs_table + DEV_TO_SL(tty->line);
 991                 if (tty->termios->c_iflag & IXOFF) {
 992                         info->x_char = STOP_CHAR(tty);
 993                 } else {
 994                         mcr = serial_inp(info, UART_MCR);
 995                         mcr &= ~UART_MCR_RTS;
 996                         serial_out(info, UART_MCR, mcr);
 997                 }
 998                 break;
 999         case TTY_THROTTLE_RQ_AVAIL:
1000                 info = rs_table + DEV_TO_SL(tty->line);
1001                 if (tty->termios->c_iflag & IXOFF) {
1002                         if (info->x_char)
1003                                 info->x_char = 0;
1004                         else
1005                                 info->x_char = START_CHAR(tty);
1006                 } else {
1007                         mcr = serial_in(info, UART_MCR);
1008                         mcr |= UART_MCR_RTS;
1009                         serial_out(info, UART_MCR, mcr);
1010                 }
1011                 break;
1012         }
1013         restore_flags(flags);
1014 }
1015 
1016 /*
1017  * ------------------------------------------------------------
1018  * rs_ioctl() and friends
1019  * ------------------------------------------------------------
1020  */
1021 
1022 static int get_serial_info(struct async_struct * info,
     /* [previous][next][first][last][top][bottom][index][help] */
1023                            struct serial_struct * retinfo)
1024 {
1025         struct serial_struct tmp;
1026   
1027         if (!retinfo)
1028                 return -EFAULT;
1029         memset(&tmp, 0, sizeof(tmp));
1030         tmp.type = info->type;
1031         tmp.line = info->line;
1032         tmp.port = info->port;
1033         tmp.irq = info->irq;
1034         tmp.flags = info->flags;
1035         tmp.baud_base = info->baud_base;
1036         tmp.close_delay = info->close_delay;
1037         tmp.custom_divisor = info->custom_divisor;
1038         tmp.hub6 = info->hub6;
1039         memcpy_tofs(retinfo,&tmp,sizeof(*retinfo));
1040         return 0;
1041 }
1042 
1043 static int set_serial_info(struct async_struct * info,
     /* [previous][next][first][last][top][bottom][index][help] */
1044                            struct serial_struct * new_info)
1045 {
1046         struct serial_struct new_serial;
1047         struct async_struct old_info;
1048         unsigned int            i,change_irq,change_port;
1049         int                     retval;
1050         struct                  sigaction sa;
1051 
1052         if (!new_info)
1053                 return -EFAULT;
1054         memcpy_fromfs(&new_serial,new_info,sizeof(new_serial));
1055         old_info = *info;
1056 
1057         change_irq = new_serial.irq != info->irq;
1058         change_port = (new_serial.port != info->port) || (new_serial.hub6 != info->hub6);
1059 
1060         if (!suser()) {
1061                 if (change_irq || change_port ||
1062                     (new_serial.baud_base != info->baud_base) ||
1063                     (new_serial.type != info->type) ||
1064                     (new_serial.close_delay != info->close_delay) ||
1065                     ((new_serial.flags & ~ASYNC_USR_MASK) !=
1066                      (info->flags & ~ASYNC_USR_MASK)))
1067                         return -EPERM;
1068                 info->flags = ((info->flags & ~ASYNC_USR_MASK) |
1069                                (new_serial.flags & ASYNC_USR_MASK));
1070                 info->custom_divisor = new_serial.custom_divisor;
1071                 new_serial.port = 0;    /* Prevent initialization below */
1072                 goto check_and_exit;
1073         }
1074 
1075         if (new_serial.irq == 2)
1076                 new_serial.irq = 9;
1077 
1078         if ((new_serial.irq > 15) || (new_serial.port > 0xffff) ||
1079             (new_serial.type < PORT_UNKNOWN) || (new_serial.type > PORT_MAX)) {
1080                 return -EINVAL;
1081         }
1082 
1083         /* Make sure address is not already in use */
1084         for (i = 0 ; i < NR_PORTS; i++)
1085                 if ((info != &rs_table[i]) &&
1086                     (rs_table[i].port == new_serial.port) && rs_table[i].type)
1087                         return -EADDRINUSE;
1088 
1089         /*
1090          * If necessary, first we try to grab the new IRQ for serial
1091          * interrupts.  (We have to do this early, since we may get an
1092          * error trying to do this.)
1093          */
1094         if (new_serial.port && new_serial.type && new_serial.irq &&
1095             (change_irq || !(info->flags & ASYNC_INITIALIZED))) {
1096                 if (!IRQ_ports[new_serial.irq]) {
1097                         sa.sa_handler = rs_interrupt;
1098                         sa.sa_flags = (SA_INTERRUPT);
1099                         sa.sa_mask = 0;
1100                         sa.sa_restorer = NULL;
1101                         retval = irqaction(new_serial.irq,&sa);
1102                         if (retval)
1103                                 return retval;
1104                 }
1105         }
1106 
1107         if ((change_port || change_irq) && (info->count > 1))
1108                 return -EBUSY;
1109 
1110         /*
1111          * OK, past this point, all the error checking has been done.
1112          * At this point, we start making changes.....
1113          */
1114 
1115         info->baud_base = new_serial.baud_base;
1116         info->flags = ((info->flags & ~ASYNC_FLAGS) |
1117                         (new_serial.flags & ASYNC_FLAGS));
1118         info->custom_divisor = new_serial.custom_divisor;
1119         info->type = new_serial.type;
1120         info->close_delay = new_serial.close_delay;
1121 
1122         if (change_port || change_irq) {
1123                 /*
1124                  * We need to shutdown the serial port at the old
1125                  * port/irq combination.
1126                  */
1127                 if (info->flags & ASYNC_INITIALIZED) {
1128                         shutdown(info);
1129                         unlink_port(info);
1130                         if (change_irq && info->irq && !IRQ_ports[info->irq])
1131                                 free_irq(info->irq);
1132                 }
1133                 info->irq = new_serial.irq;
1134                 info->port = new_serial.port;
1135                 info->hub6 = new_serial.hub6;
1136         }
1137         
1138 check_and_exit:
1139         if (info->port && info->type && 
1140             !(info->flags & ASYNC_INITIALIZED)) {
1141                 /*
1142                  * Link the port into the new interrupt chain.
1143                  */
1144                 link_port(info);
1145                 startup(info);
1146                 change_speed(info->line);
1147         } else if (((old_info.flags & ASYNC_SPD_MASK) !=
1148                     (info->flags & ASYNC_SPD_MASK)) ||
1149                    (old_info.custom_divisor != info->custom_divisor))
1150                 change_speed(info->line);
1151 
1152         return 0;
1153 }
1154 
1155 static int get_modem_info(struct async_struct * info, unsigned int *value)
     /* [previous][next][first][last][top][bottom][index][help] */
1156 {
1157         unsigned char control, status;
1158         unsigned int result;
1159 
1160         cli();
1161         control = serial_in(info, UART_MCR);
1162         status = serial_in(info, UART_MSR);
1163         sti();
1164         result =  ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
1165                 | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
1166                 | ((status  & UART_MSR_DCD) ? TIOCM_CAR : 0)
1167                 | ((status  & UART_MSR_RI) ? TIOCM_RNG : 0)
1168                 | ((status  & UART_MSR_DSR) ? TIOCM_DSR : 0)
1169                 | ((status  & UART_MSR_CTS) ? TIOCM_CTS : 0);
1170         put_fs_long(result,(unsigned long *) value);
1171         return 0;
1172 }
1173 
1174 static int set_modem_info(struct async_struct * info, unsigned int cmd,
     /* [previous][next][first][last][top][bottom][index][help] */
1175                           unsigned int *value)
1176 {
1177         unsigned char control;
1178         unsigned int arg = get_fs_long((unsigned long *) value);
1179         
1180         cli();
1181         control = serial_in(info, UART_MCR);
1182         sti();
1183 
1184         switch (cmd) {
1185                 case TIOCMBIS:
1186                         if (arg & TIOCM_RTS)
1187                                 control |= UART_MCR_RTS;
1188                         if (arg & TIOCM_DTR)
1189                                 control |= UART_MCR_DTR;
1190                         break;
1191                 case TIOCMBIC:
1192                         if (arg & TIOCM_RTS)
1193                                 control &= ~UART_MCR_RTS;
1194                         if (arg & TIOCM_DTR)
1195                                 control &= ~UART_MCR_DTR;
1196                         break;
1197                 case TIOCMSET:
1198                         control = (control & ~(UART_MCR_RTS | UART_MCR_DTR))
1199                                 | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
1200                                 | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0);
1201                         break;
1202                 default:
1203                         return -EINVAL;
1204         }
1205         cli();
1206         serial_out(info, UART_MCR, control);
1207         sti();
1208         return 0;
1209 }
1210 
1211 static int do_autoconfig(struct async_struct * info)
     /* [previous][next][first][last][top][bottom][index][help] */
1212 {
1213         struct sigaction        sa;
1214         int                     retval;
1215         
1216         if (!suser())
1217                 return -EPERM;
1218         
1219         if (info->count > 1)
1220                 return -EBUSY;
1221         
1222         if (info->flags & ASYNC_INITIALIZED) {
1223                 shutdown(info);
1224                 unlink_port(info);
1225                 if (info->irq && !IRQ_ports[info->irq])
1226                         free_irq(info->irq);
1227         }
1228 
1229         cli();
1230         autoconfig(info);
1231         sti();
1232 
1233         if (info->port && info->type) {
1234                 if (info->irq && !IRQ_ports[info->irq]) {
1235                         sa.sa_handler = rs_interrupt;
1236                         sa.sa_flags = (SA_INTERRUPT);
1237                         sa.sa_mask = 0;
1238                         sa.sa_restorer = NULL;
1239                         retval = irqaction(info->irq,&sa);
1240                         if (retval)
1241                                 return retval;
1242                 }
1243                 link_port(info);
1244                 startup(info);
1245                 change_speed(info->line);
1246         }
1247         return 0;
1248 }
1249 
1250 
1251 /*
1252  * This routine sends a break character out the serial port.
1253  */
1254 static void send_break( struct async_struct * info, int duration)
     /* [previous][next][first][last][top][bottom][index][help] */
1255 {
1256         if (!info->port)
1257                 return;
1258         current->state = TASK_INTERRUPTIBLE;
1259         current->timeout = jiffies + duration;
1260         cli();
1261         serial_out(info, UART_LCR, serial_inp(info, UART_LCR) | UART_LCR_SBC);
1262         schedule();
1263         serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC);
1264         sti();
1265 }
1266 
1267 /*
1268  * This routine returns a bitfield of "wild interrupts".  Basically,
1269  * any unclaimed interrupts which is flapping around.
1270  */
1271 static int check_wild_interrupts(int doprint)
     /* [previous][next][first][last][top][bottom][index][help] */
1272 {
1273         int     i, mask;
1274         int     wild_interrupts = 0;
1275         int     irq_lines;
1276         unsigned long timeout;
1277         unsigned long flags;
1278         
1279         /* Turn on interrupts (they may be off) */
1280         save_flags(flags); sti();
1281 
1282         irq_lines = grab_all_interrupts(0);
1283         
1284         /*
1285          * Delay for 0.1 seconds -- we use a busy loop since this may 
1286          * occur during the bootup sequence
1287          */
1288         timeout = jiffies+10;
1289         while (timeout >= jiffies)
1290                 ;
1291         
1292         rs_triggered = 0;       /* Reset after letting things settle */
1293 
1294         timeout = jiffies+10;
1295         while (timeout >= jiffies)
1296                 ;
1297         
1298         for (i = 0, mask = 1; i < 16; i++, mask <<= 1) {
1299                 if ((rs_triggered & (1 << i)) &&
1300                     (irq_lines & (1 << i))) {
1301                         wild_interrupts |= mask;
1302                         if (doprint)
1303                                 printk("Wild interrupt?  (IRQ %d)\n", i);
1304                 }
1305         }
1306         free_all_interrupts(irq_lines);
1307         restore_flags(flags);
1308         return wild_interrupts;
1309 }
1310 
1311 static int rs_ioctl(struct tty_struct *tty, struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
1312                     unsigned int cmd, unsigned long arg)
1313 {
1314         int error, line;
1315         struct async_struct * info;
1316 
1317         line = DEV_TO_SL(tty->line);
1318         if (line < 0 || line >= NR_PORTS)
1319                 return -ENODEV;
1320         info = rs_table + line;
1321         
1322         switch (cmd) {
1323                 case TCSBRK:    /* SVID version: non-zero arg --> no break */
1324                         if (!arg)
1325                                 send_break(info, HZ/4); /* 1/4 second */
1326                         return 0;
1327                 case TCSBRKP:   /* support for POSIX tcsendbreak() */
1328                         send_break(info, arg ? arg*(HZ/10) : HZ/4);
1329                         return 0;
1330                 case TIOCGSOFTCAR:
1331                         error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
1332                         if (error)
1333                                 return error;
1334                         put_fs_long(C_LOCAL(tty) ? 1 : 0,
1335                                     (unsigned long *) arg);
1336                         return 0;
1337                 case TIOCSSOFTCAR:
1338                         arg = get_fs_long((unsigned long *) arg);
1339                         tty->termios->c_cflag =
1340                                 ((tty->termios->c_cflag & ~CLOCAL) |
1341                                  (arg ? CLOCAL : 0));
1342                         return 0;
1343                 case TIOCMGET:
1344                         error = verify_area(VERIFY_WRITE, (void *) arg,
1345                                 sizeof(unsigned int));
1346                         if (error)
1347                                 return error;
1348                         return get_modem_info(info, (unsigned int *) arg);
1349                 case TIOCMBIS:
1350                 case TIOCMBIC:
1351                 case TIOCMSET:
1352                         return set_modem_info(info, cmd, (unsigned int *) arg);
1353                 case TIOCGSERIAL:
1354                         error = verify_area(VERIFY_WRITE, (void *) arg,
1355                                                 sizeof(struct serial_struct));
1356                         if (error)
1357                                 return error;
1358                         return get_serial_info(info,
1359                                                (struct serial_struct *) arg);
1360                 case TIOCSSERIAL:
1361                         return set_serial_info(info,
1362                                                (struct serial_struct *) arg);
1363                 case TIOCSERCONFIG:
1364                         return do_autoconfig(info);
1365 
1366                 case TIOCSERGWILD:
1367                         error = verify_area(VERIFY_WRITE, (void *) arg,
1368                                             sizeof(int));
1369                         if (error)
1370                                 return error;
1371                         put_fs_long(rs_wild_int_mask, (unsigned long *) arg);
1372                         return 0;
1373 
1374                 case TIOCSERSWILD:
1375                         if (!suser())
1376                                 return -EPERM;
1377                         rs_wild_int_mask = get_fs_long((unsigned long *) arg);
1378                         if (rs_wild_int_mask < 0)
1379                                 rs_wild_int_mask = check_wild_interrupts(0);
1380                         return 0;
1381 
1382                 default:
1383                         return -EINVAL;
1384                 }
1385         return 0;
1386 }
1387 
1388 static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
     /* [previous][next][first][last][top][bottom][index][help] */
1389 {
1390         struct async_struct *info;
1391 
1392         if (tty->termios->c_cflag == old_termios->c_cflag)
1393                 return;
1394 
1395         info = &rs_table[DEV_TO_SL(tty->line)];
1396 
1397         change_speed(DEV_TO_SL(tty->line));
1398         
1399         if ((old_termios->c_cflag & CRTSCTS) &&
1400             !(tty->termios->c_cflag & CRTSCTS)) {
1401                 tty->stopped = 0;
1402                 rs_write(tty);
1403         }
1404 
1405         if (!(old_termios->c_cflag & CLOCAL) &&
1406             (tty->termios->c_cflag & CLOCAL))
1407                 wake_up_interruptible(&info->open_wait);
1408 
1409         if (I_INPCK(tty))
1410                 info->read_status_mask = (UART_LSR_OE | UART_LSR_BI |
1411                                           UART_LSR_FE | UART_LSR_PE);
1412         else
1413                 info->read_status_mask = (UART_LSR_OE | UART_LSR_BI |
1414                                           UART_LSR_FE);
1415 }
1416 
1417 /*
1418  * ------------------------------------------------------------
1419  * rs_close()
1420  * 
1421  * This routine is called when the serial port gets closed.  First, we
1422  * wait for the last remaining data to be sent.  Then, we unlink its
1423  * async structure from the interrupt chain if necessary, and we free
1424  * that IRQ if nothing is left in the chain.
1425  * ------------------------------------------------------------
1426  */
1427 static void rs_close(struct tty_struct *tty, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
1428 {
1429         struct async_struct * info;
1430         int line;
1431 
1432         line = DEV_TO_SL(tty->line);
1433         if ((line < 0) || (line >= NR_PORTS))
1434                 return;
1435         info = rs_table + line;
1436 #ifdef SERIAL_DEBUG_OPEN
1437         printk("rs_close ttys%d, count = %d\n", info->line, info->count);
1438 #endif
1439         if (--info->count > 0)
1440                 return;
1441         tty->stopped = 0;               /* Force flush to succeed */
1442         rs_start(tty);
1443         wait_until_sent(tty);
1444         clear_bit(line, rs_event);
1445         info->event = 0;
1446         info->count = 0;
1447         if (info->blocked_open) {
1448                 shutdown(info);
1449                 if (info->close_delay) {
1450                         tty->count++; /* avoid race condition */
1451                         current->state = TASK_INTERRUPTIBLE;
1452                         current->timeout = jiffies + info->close_delay;
1453                         schedule();
1454                         tty->count--;
1455                 }
1456                 startup(info);
1457                 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
1458                 if (tty->termios->c_cflag & CLOCAL)
1459                         wake_up_interruptible(&info->open_wait);
1460                 return;
1461         }
1462         if (info->flags & ASYNC_INITIALIZED) {
1463                 shutdown(info);
1464                 unlink_port(info);
1465                 if (info->irq && !IRQ_ports[info->irq])
1466                         free_irq(info->irq);
1467         }
1468         info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
1469         info->tty = 0;
1470 }
1471 
1472 /*
1473  * ------------------------------------------------------------
1474  * rs_open() and friends
1475  * ------------------------------------------------------------
1476  */
1477 static int block_til_ready(struct tty_struct *tty, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
1478                            struct async_struct *info)
1479 {
1480         struct wait_queue wait = { current, NULL };
1481         int             retval;
1482         int             do_clocal = C_LOCAL(tty);
1483         struct termios  orig_termios;
1484         int             tty_line = tty->line;
1485         
1486         /*
1487          * If this is a callout device, then just make sure the normal
1488          * device isn't being used.
1489          */
1490         if (MAJOR(filp->f_rdev) == 5) {
1491                 if (info->flags & ASYNC_NORMAL_ACTIVE)
1492                         return -EBUSY;
1493                 if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
1494                     (info->flags & ASYNC_SESSION_LOCKOUT) &&
1495                     (info->session != current->session))
1496                     return -EBUSY;
1497                 if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
1498                     (info->flags & ASYNC_PGRP_LOCKOUT) &&
1499                     (info->pgrp != current->pgrp))
1500                     return -EBUSY;
1501                 info->flags |= ASYNC_CALLOUT_ACTIVE;
1502                 return 0;
1503         }
1504         
1505         /*
1506          * If non-blocking mode is set, then make the check up front
1507          * and then exit.
1508          */
1509         if (filp->f_flags & O_NONBLOCK) {
1510                 if (info->flags & ASYNC_CALLOUT_ACTIVE)
1511                         return -EBUSY;
1512                 info->flags |= ASYNC_NORMAL_ACTIVE;
1513                 return 0;
1514         }
1515 
1516         /*
1517          * Block waiting for the carrier detect and the line to become
1518          * free (i.e., not in use by the callout).  While we are in
1519          * this loop, info->count is dropped by one, so that
1520          * rs_close() knows when to free things.  We restore it upon
1521          * exit, either normal or abnormal.
1522          */
1523         retval = 0;
1524         add_wait_queue(&info->open_wait, &wait);
1525 #ifdef SERIAL_DEBUG_OPEN
1526         printk("block_til_ready before block: ttys%d, count = %d\n",
1527                info->line, info->count);
1528 #endif
1529         info->count--;
1530         info->blocked_open++;
1531         memset(&orig_termios, 0, sizeof(orig_termios));
1532         if (tty_termios[tty_line])
1533                 orig_termios = *tty_termios[tty_line];
1534         while (1) {
1535                 cli();
1536                 if (!(info->flags & ASYNC_CALLOUT_ACTIVE))
1537                         serial_out(info, UART_MCR,
1538                                    serial_inp(info, UART_MCR) | UART_MCR_DTR);
1539                 sti();
1540                 current->state = TASK_INTERRUPTIBLE;
1541                 if (tty_hung_up_p(filp) && (info->flags & ASYNC_HUP_NOTIFY)) {
1542                         retval = -EAGAIN;
1543                         break;
1544                 }
1545                 if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
1546                     (do_clocal || (serial_in(info, UART_MSR) &
1547                                    UART_MSR_DCD))) {
1548                         if (tty_hung_up_p(filp))
1549                                 retval = -ERESTARTNOINTR;
1550                         break;
1551                 }
1552                 if (current->signal & ~current->blocked) {
1553                         retval = -ERESTARTSYS;
1554                         break;
1555                 }
1556 #ifdef SERIAL_DEBUG_OPEN
1557                 printk("block_til_ready blocking: ttys%d, count = %d\n",
1558                        info->line, info->count);
1559 #endif
1560                 schedule();
1561         }
1562         current->state = TASK_RUNNING;
1563         remove_wait_queue(&info->open_wait, &wait);
1564         info->count++;
1565         info->blocked_open--;
1566 #ifdef SERIAL_DEBUG_OPEN
1567         printk("block_til_ready after blocking: ttys%d, count = %d\n",
1568                info->line, info->count);
1569 #endif
1570         if (retval)
1571                 return retval;
1572         info->flags |= ASYNC_NORMAL_ACTIVE;
1573         if ((info->flags & ASYNC_TERMIOS_RESTORE) &&
1574             tty_termios[tty_line])
1575                 *tty_termios[tty_line] = orig_termios;
1576         return 0;
1577 }       
1578 
1579 /*
1580  * This routine is called whenever a serial port is opened.  It
1581  * enables interrupts for a serial port, linking in its async structure into
1582  * the IRQ chain.   It also performs the serial-speicific
1583  * initalization for the tty structure.
1584  */
1585 int rs_open(struct tty_struct *tty, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
1586 {
1587         struct async_struct     *info;
1588         int                     retval, line;
1589         struct sigaction        sa;
1590 
1591         line = DEV_TO_SL(tty->line);
1592         if ((line < 0) || (line >= NR_PORTS))
1593                 return -ENODEV;
1594         info = rs_table + line;
1595 #ifdef SERIAL_DEBUG_OPEN
1596         printk("rs_open ttys%d, count = %d\n", info->line, info->count);
1597 #endif
1598         info->count++;
1599         info->tty = tty;
1600         
1601         tty->write = rs_write;
1602         tty->close = rs_close;
1603         tty->ioctl = rs_ioctl;
1604         tty->throttle = rs_throttle;
1605         tty->set_termios = rs_set_termios;
1606         tty->stop = rs_stop;
1607         tty->start = rs_start;
1608 
1609         if (!(info->flags & ASYNC_INITIALIZED)) {
1610                 if (!info->port || !info->type) {
1611                         set_bit(TTY_IO_ERROR, &tty->flags);
1612                         return 0;
1613                 }
1614                 if (info->irq && !IRQ_ports[info->irq]) {
1615                         sa.sa_handler = rs_interrupt;
1616                         sa.sa_flags = (SA_INTERRUPT);
1617                         sa.sa_mask = 0;
1618                         sa.sa_restorer = NULL;
1619                         retval = irqaction(info->irq,&sa);
1620                         if (retval)
1621                                 return retval;
1622                 }
1623                 /*
1624                  * Link in port to IRQ chain
1625                  */
1626                 link_port(info);
1627                 startup(info);
1628                 change_speed(info->line);
1629                 if (!info->irq) {
1630                         IRQ_active |= info->line;
1631                         cli();
1632                         figure_RS_timer();
1633                         sti();
1634                 }
1635         }
1636 
1637         retval = block_til_ready(tty, filp, info);
1638         if (retval)
1639                 return retval;
1640 
1641         info->session = current->session;
1642         info->pgrp = current->pgrp;
1643         
1644         return 0;
1645 }
1646 
1647 /*
1648  * ---------------------------------------------------------------------
1649  * rs_init() and friends
1650  *
1651  * rs_init() is called at boot-time to initialize the serial driver.
1652  * ---------------------------------------------------------------------
1653  */
1654 
1655 /*
1656  * This routine prints out the appropriate serial driver version
1657  * number, and identifies which options were configured into this
1658  * driver.
1659  */
1660 static void show_serial_version(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1661 {
1662         printk("Serial driver version 3.96 with");
1663 #ifdef CONFIG_AST_FOURPORT
1664         printk(" AST_FOURPORT");
1665 #define SERIAL_OPT
1666 #endif
1667 #ifdef CONFIG_ACCENT_ASYNC
1668         printk(" ACCENT_ASYNC");
1669 #define SERIAL_OPT
1670 #endif
1671 #ifdef CONFIG_HUB6
1672         printk(" HUB-6");
1673 #define SERIAL_OPT
1674 #endif
1675 #ifdef CONFIG_AUTO_IRQ
1676         printk (" AUTO_IRQ");
1677 #define SERIAL_OPT
1678 #endif
1679 #ifdef SERIAL_OPT
1680         printk(" enabled\n");
1681 #else
1682         printk(" no serial options enabled\n");
1683 #endif
1684 #undef SERIAL_OPT
1685 }
1686 
1687 /*
1688  * This routine is called by do_auto_irq(); it attempts to determine
1689  * which interrupt a serial port is configured to use.  It is not
1690  * fool-proof, but it works a large part of the time.
1691  */
1692 static int get_auto_irq(struct async_struct *info)
     /* [previous][next][first][last][top][bottom][index][help] */
1693 {
1694         unsigned char save_MCR, save_IER, save_ICP=0;
1695         unsigned short ICP=0, port = info->port;
1696         unsigned long timeout;
1697         
1698         /*
1699          * Enable interrupts and see who answers
1700          */
1701         rs_irq_triggered = 0;
1702         cli();
1703         save_IER = serial_inp(info, UART_IER);
1704         save_MCR = serial_inp(info, UART_MCR);
1705         if (info->flags & ASYNC_FOURPORT)  {
1706                 serial_outp(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
1707                 serial_outp(info, UART_IER, 0x0f);      /* enable all intrs */
1708                 ICP = (port & 0xFE0) | 0x01F;
1709                 save_ICP = inb_p(ICP);
1710                 outb_p(0x80, ICP);
1711                 (void) inb_p(ICP);
1712         } else {
1713                 serial_outp(info, UART_MCR,
1714                             UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
1715                 serial_outp(info, UART_IER, 0x0f);      /* enable all intrs */
1716         }
1717         sti();
1718         /*
1719          * Next, clear the interrupt registers.
1720          */
1721         (void)serial_inp(info, UART_LSR);
1722         (void)serial_inp(info, UART_RX);
1723         (void)serial_inp(info, UART_IIR);
1724         (void)serial_inp(info, UART_MSR);
1725         
1726         timeout = jiffies+2;
1727         while (timeout >= jiffies) {
1728                 if (rs_irq_triggered)
1729                         break;
1730         }
1731         /*
1732          * Now check to see if we got any business, and clean up.
1733          */
1734         cli();
1735         serial_outp(info, UART_IER, save_IER);
1736         serial_outp(info, UART_MCR, save_MCR);
1737         if (info->flags & ASYNC_FOURPORT)
1738                 outb_p(save_ICP, ICP);
1739         sti();
1740         return(rs_irq_triggered);
1741 }
1742 
1743 /*
1744  * Calls get_auto_irq() multiple times, to make sure we don't get
1745  * faked out by random interrupts
1746  */
1747 static int do_auto_irq(struct async_struct * info)
     /* [previous][next][first][last][top][bottom][index][help] */
1748 {
1749         unsigned                port = info->port;
1750         int                     irq_lines = 0;
1751         int                     irq_try_1 = 0, irq_try_2 = 0;
1752         int                     retries;
1753         unsigned long flags;
1754 
1755         if (!port)
1756                 return 0;
1757 
1758         /* Turn on interrupts (they may be off) */
1759         save_flags(flags); sti();
1760 
1761         irq_lines = grab_all_interrupts(rs_wild_int_mask);
1762         
1763         for (retries = 0; retries < 5; retries++) {
1764                 if (!irq_try_1)
1765                         irq_try_1 = get_auto_irq(info);
1766                 if (!irq_try_2)
1767                         irq_try_2 = get_auto_irq(info);
1768                 if (irq_try_1 && irq_try_2) {
1769                         if (irq_try_1 == irq_try_2)
1770                                 break;
1771                         irq_try_1 = irq_try_2 = 0;
1772                 }
1773         }
1774         restore_flags(flags);
1775         free_all_interrupts(irq_lines);
1776         return (irq_try_1 == irq_try_2) ? irq_try_1 : 0;
1777 }
1778 
1779 /*
1780  * This routine is called by rs_init() to initialize a specific serial
1781  * port.  It determines what type of UART ship this serial port is
1782  * using: 8250, 16450, 16550, 16550A.  The important question is
1783  * whether or not this UART is a 16550A or not, since this will
1784  * determine whether or not we can use its FIFO features or not.
1785  */
1786 static void autoconfig(struct async_struct * info)
     /* [previous][next][first][last][top][bottom][index][help] */
1787 {
1788         unsigned char status1, status2, scratch, scratch2;
1789         unsigned port = info->port;
1790         unsigned long flags;
1791 
1792         info->type = PORT_UNKNOWN;
1793         
1794         if (!port)
1795                 return;
1796 
1797         save_flags(flags); cli();
1798         
1799         /*
1800          * Do a simple existence test first; if we fail this, there's
1801          * no point trying anything else.
1802          */
1803         scratch = serial_inp(info, UART_IER);
1804         serial_outp(info, UART_IER, 0);
1805         scratch2 = serial_inp(info, UART_IER);
1806         serial_outp(info, UART_IER, scratch);
1807         if (scratch2) {
1808                 restore_flags(flags);
1809                 return;         /* We failed; there's nothing here */
1810         }
1811 
1812         /* 
1813          * Check to see if a UART is really there.  Certain broken
1814          * internal modems based on the Rockwell chipset fail this
1815          * test, because they apparently don't implement the loopback
1816          * test mode.  So this test is skipped on the COM 1 through
1817          * COM 4 ports.  This *should* be safe, since no board
1818          * manufactucturer would be stupid enough to design a board
1819          * that conflicts with COM 1-4 --- we hope!
1820          */
1821         if (!(info->flags & ASYNC_SKIP_TEST)) {
1822                 scratch = serial_inp(info, UART_MCR);
1823                 serial_outp(info, UART_MCR, UART_MCR_LOOP | scratch);
1824                 scratch2 = serial_inp(info, UART_MSR);
1825                 serial_outp(info, UART_MCR, UART_MCR_LOOP | 0x0A);
1826                 status1 = serial_inp(info, UART_MSR) & 0xF0;
1827                 serial_outp(info, UART_MCR, scratch);
1828                 serial_outp(info, UART_MSR, scratch2);
1829                 if (status1 != 0x90) {
1830                         restore_flags(flags);
1831                         return;
1832                 }
1833         } 
1834         
1835         /*
1836          * If the AUTO_IRQ flag is set, try to do the automatic IRQ
1837          * detection.
1838          */
1839         if (info->flags & ASYNC_AUTO_IRQ)
1840                 info->irq = do_auto_irq(info);
1841                 
1842         serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
1843         scratch = serial_in(info, UART_IIR) >> 6;
1844         info->xmit_fifo_size = 1;
1845         switch (scratch) {
1846                 case 0:
1847                         info->type = PORT_16450;
1848                         break;
1849                 case 1:
1850                         info->type = PORT_UNKNOWN;
1851                         break;
1852                 case 2:
1853                         info->type = PORT_16550;
1854                         break;
1855                 case 3:
1856                         info->type = PORT_16550A;
1857                         info->xmit_fifo_size = 16;
1858                         break;
1859         }
1860         if (info->type == PORT_16450) {
1861                 scratch = serial_in(info, UART_SCR);
1862                 serial_outp(info, UART_SCR, 0xa5);
1863                 status1 = serial_in(info, UART_SCR);
1864                 serial_outp(info, UART_SCR, 0x5a);
1865                 status2 = serial_in(info, UART_SCR);
1866                 serial_outp(info, UART_SCR, scratch);
1867 
1868                 if ((status1 != 0xa5) || (status2 != 0x5a))
1869                         info->type = PORT_8250;
1870         }
1871         shutdown(info);
1872         restore_flags(flags);
1873 }
1874 
1875 /*
1876  * The serial driver boot-time initialization code!
1877  */
1878 long rs_init(long kmem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
1879 {
1880         int i;
1881         struct async_struct * info;
1882         
1883         memset(&rs_event, 0, sizeof(rs_event));
1884         bh_base[SERIAL_BH].routine = do_softint;
1885         timer_table[RS_TIMER].fn = rs_timer;
1886         timer_table[RS_TIMER].expires = 0;
1887         IRQ_active = 0;
1888 #ifdef CONFIG_AUTO_IRQ
1889         rs_wild_int_mask = check_wild_interrupts(1);
1890 #endif
1891 
1892         for (i = 0; i < 16; i++) {
1893                 IRQ_ports[i] = 0;
1894                 IRQ_timeout[i] = 0;
1895         }
1896         
1897         show_serial_version();
1898         for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
1899                 info->line = i;
1900                 info->tty = 0;
1901                 info->type = PORT_UNKNOWN;
1902                 info->custom_divisor = 0;
1903                 info->close_delay = 50;
1904                 info->x_char = 0;
1905                 info->event = 0;
1906                 info->count = 0;
1907                 info->blocked_open = 0;
1908                 info->open_wait = 0;
1909                 info->next_port = 0;
1910                 info->prev_port = 0;
1911                 if (info->irq == 2)
1912                         info->irq = 9;
1913                 if (!(info->flags & ASYNC_BOOT_AUTOCONF))
1914                         continue;
1915                 autoconfig(info);
1916                 if (info->type == PORT_UNKNOWN)
1917                         continue;
1918                 printk("tty%02d%s at 0x%04x (irq = %d)", info->line, 
1919                        (info->flags & ASYNC_FOURPORT) ? " FourPort" : "",
1920                        info->port, info->irq);
1921                 switch (info->type) {
1922                         case PORT_8250:
1923                                 printk(" is a 8250\n");
1924                                 break;
1925                         case PORT_16450:
1926                                 printk(" is a 16450\n");
1927                                 break;
1928                         case PORT_16550:
1929                                 printk(" is a 16550\n");
1930                                 break;
1931                         case PORT_16550A:
1932                                 printk(" is a 16550A\n");
1933                                 break;
1934                         default:
1935                                 printk("\n");
1936                                 break;
1937                 }
1938         }
1939         return kmem_start;
1940 }
1941 

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