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

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