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. send_break
  6. rs_sched_event
  7. rs_interrupt
  8. rs_probe
  9. do_softint
  10. rs_timer
  11. restart_port
  12. rs_write
  13. rs_throttle
  14. rs_close
  15. startup
  16. shutdown
  17. change_speed
  18. get_serial_info
  19. set_serial_info
  20. get_modem_info
  21. set_modem_info
  22. rs_ioctl
  23. rs_set_termios
  24. rs_open
  25. block_til_ready
  26. show_serial_version
  27. get_auto_irq
  28. init
  29. 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 
  31 #include <asm/system.h>
  32 #include <asm/io.h>
  33 #include <asm/segment.h>
  34 #include <asm/bitops.h>
  35 
  36 /*
  37  * Serial driver configuration section.  Here are the various options:
  38  *
  39  * CONFIG_AUTO_IRQ
  40  *              Enables automatic IRQ detection.  I've put in some
  41  *              fixes to this which should make this work much more
  42  *              cleanly than it used to in 0.98pl2-6.  It should be
  43  *              much less vulnerable to false IRQ's now.
  44  * 
  45  * CONFIG_AST_FOURPORT
  46  *              Enables support for the AST Fourport serial port.
  47  * 
  48  * CONFIG_ACCENT_ASYNC
  49  *              Enables support for the Accent Async 4 port serial
  50  *              port.
  51  * 
  52  */
  53         
  54 #define WAKEUP_CHARS (3*TTY_BUF_SIZE/4)
  55 
  56 /*
  57  * rs_event             - Bitfield of serial lines that events pending
  58  *                              to be processed at the next clock tick.
  59  * rs_write_active      - Bitfield of serial lines that are actively
  60  *                              transmitting (and therefore have a
  61  *                              write timeout pending, in case the
  62  *                              THRE interrupt gets lost.)
  63  *
  64  * We assume here that int's are 32 bits, so an array of two gives us
  65  * 64 lines, which is the maximum we can support.
  66  */
  67 static int rs_event[2];
  68 static int rs_write_active[2];
  69 
  70 static struct async_struct *IRQ_ports[16];
  71 
  72 /*
  73  * This assumes you have a 1.8432 MHz clock for your UART.
  74  *
  75  * It'd be nice if someone built a serial card with a 24.576 MHz
  76  * clock, since the 16550A is capable of handling a top speed of 1.5
  77  * megabits/second; but this requires the faster clock.
  78  */
  79 #define BASE_BAUD ( 1843200 / 16 ) 
  80 
  81 struct async_struct rs_table[] = {
  82         { BASE_BAUD, 0x3F8, 4, 0, },
  83         { BASE_BAUD, 0x2F8, 3, 0, },
  84         { BASE_BAUD, 0x3E8, 4, 0, },
  85         { BASE_BAUD, 0x2E8, 3, 0, },
  86 #ifdef CONFIG_AST_FOURPORT
  87         { BASE_BAUD, 0x1A0, 2, ASYNC_FOURPORT },
  88         { BASE_BAUD, 0x1A8, 2, ASYNC_FOURPORT },
  89         { BASE_BAUD, 0x1B0, 2, ASYNC_FOURPORT },
  90         { BASE_BAUD, 0x1B8, 2, ASYNC_FOURPORT },
  91 
  92         { BASE_BAUD, 0x2A0, 5, ASYNC_FOURPORT },
  93         { BASE_BAUD, 0x2A8, 5, ASYNC_FOURPORT },
  94         { BASE_BAUD, 0x2B0, 5, ASYNC_FOURPORT },
  95         { BASE_BAUD, 0x2B8, 5, ASYNC_FOURPORT },
  96 #else /* CONFIG_AST_FOURPORT */
  97         { BASE_BAUD, 0x000, 0 }, 
  98         { BASE_BAUD, 0x000, 0 }, 
  99         { BASE_BAUD, 0x000, 0 },
 100         { BASE_BAUD, 0x000, 0 }, 
 101 
 102         { BASE_BAUD, 0x000, 0 },
 103         { BASE_BAUD, 0x000, 0 }, 
 104         { BASE_BAUD, 0x000, 0 },
 105         { BASE_BAUD, 0x000, 0 },
 106 #endif /* CONFIG_AST_FOURPORT */
 107         
 108 #ifdef CONFIG_ACCENT_ASYNC
 109         { BASE_BAUD, 0x330, 4, 0 },
 110         { BASE_BAUD, 0x338, 4, 0 },
 111 #else /* CONFIG_ACCENT_ASYNC */
 112         { BASE_BAUD, 0x000, 0 },
 113         { BASE_BAUD, 0x000, 0 },
 114 #endif /* CONFIG_ACCENT_ASYNC */
 115         { BASE_BAUD, 0x000, 0 },
 116         { BASE_BAUD, 0x000, 0 },
 117 
 118         { BASE_BAUD, 0x100, 4, 0 },
 119         { BASE_BAUD, 0x108, 4, 0 },
 120         { BASE_BAUD, 0x110, 4, 0 },
 121         { BASE_BAUD, 0x118, 4, 0 },
 122         { BASE_BAUD, 0x120, 4, 0 },
 123         { BASE_BAUD, 0x128, 4, 0 },
 124         { BASE_BAUD, 0x130, 4, 0 },
 125         { BASE_BAUD, 0x138, 4, 0 },
 126         { BASE_BAUD, 0x140, 4, 0 },
 127         { BASE_BAUD, 0x148, 4, 0 },
 128         { BASE_BAUD, 0x150, 4, 0 },
 129         { BASE_BAUD, 0x158, 4, 0 },
 130         { BASE_BAUD, 0x160, 4, 0 },
 131         { BASE_BAUD, 0x168, 4, 0 },
 132         { BASE_BAUD, 0x170, 4, 0 },
 133         { BASE_BAUD, 0x178, 4, 0 },
 134 };
 135 
 136 #define NR_PORTS        (sizeof(rs_table)/sizeof(struct async_struct))
 137 
 138 /*
 139  * This is used to figure out the divsor speeds and the timeouts
 140  */
 141 static int baud_table[] = {
 142         0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
 143         9600, 19200, 38400, 57600, 115200, 0 };
 144 
 145 static void startup(struct async_struct * info);
 146 static void shutdown(struct async_struct * info);
 147 static void rs_throttle(struct tty_struct * tty, int status);
 148 static void restart_port(struct async_struct *info);
 149 static int block_til_ready(struct tty_struct *tty, struct file * filp,
 150                            struct async_struct *info);
 151 
 152 static inline unsigned int serial_in(struct async_struct *info, int offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 153 {
 154         return inb(info->port + offset);
 155 }
 156 
 157 static inline unsigned int serial_inp(struct async_struct *info, int offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 158 {
 159         return inb_p(info->port + offset);
 160 }
 161 
 162 static inline void serial_out(struct async_struct *info, int offset, int value)
     /* [previous][next][first][last][top][bottom][index][help] */
 163 {
 164         outb(value, info->port+offset);
 165 }
 166 
 167 static inline void serial_outp(struct async_struct *info, int offset,
     /* [previous][next][first][last][top][bottom][index][help] */
 168                                int value)
 169 {
 170         outb_p(value, info->port+offset);
 171 }
 172 
 173 static void send_break( struct async_struct * info)
     /* [previous][next][first][last][top][bottom][index][help] */
 174 {
 175         if (!info->port)
 176                 return;
 177         current->state = TASK_INTERRUPTIBLE;
 178         current->timeout = jiffies + 25;
 179         serial_out(info, UART_LCR, serial_inp(info, UART_LCR) | UART_LCR_SBC);
 180         schedule();
 181         serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC);
 182 }
 183 
 184 static inline void rs_sched_event(struct async_struct *info,
     /* [previous][next][first][last][top][bottom][index][help] */
 185                                   int event)
 186 {
 187         info->event |= 1 << event;
 188         set_bit(info->line, rs_event);
 189         mark_bh(SERIAL_BH);
 190 }
 191 
 192 
 193 /*
 194  * This is the serial driver's generic interrupt routine
 195  */
 196 static void rs_interrupt(int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
 197 {
 198         unsigned char status;
 199         struct async_struct * info;
 200         struct tty_queue * queue;
 201         int head, tail, count, ch;
 202         int done;
 203         
 204         /*
 205          * Just like the LEFT(x) macro, except it uses the loal tail
 206          * and head variables.
 207          */
 208 #define VLEFT ((tail-head-1)&(TTY_BUF_SIZE-1))
 209 #define IFLAG (info->tty->termios->c_iflag)
 210 #define CFLAG (info->tty->termios->c_cflag)
 211 
 212         info = IRQ_ports[irq];
 213         done = 1;
 214         while (info) {
 215 #ifdef SERIAL_INT_DEBUG
 216                 printk("rsint(%d)...", info->line);
 217 #endif
 218                 if (serial_inp(info, UART_IIR) & UART_IIR_NO_INT)
 219                         goto next_loop;
 220                 done = 0;
 221                 
 222                 status = serial_inp(info, UART_LSR);
 223                 if (status & UART_LSR_DR) {
 224 #ifdef SERIAL_INT_DEBUG
 225                         printk("DR...");
 226 #endif
 227                         queue = &info->tty->read_q;
 228                         head = queue->head;
 229                         tail = queue->tail;
 230                         do {
 231                                 ch = serial_in(info, UART_RX);
 232                                 /*
 233                                  * There must be at least 3 characters
 234                                  * free in the queue; otherwise we punt.
 235                                  */
 236                                 if (VLEFT < 3)
 237                                         continue;
 238                                 if (status & (UART_LSR_BI |
 239                                               UART_LSR_FE |
 240                                               UART_LSR_PE)) {
 241                                         if (status & (UART_LSR_BI)) {
 242                                                 if (info->flags & ASYNC_SAK)
 243                         rs_sched_event(info, RS_EVENT_DO_SAK);
 244                                                 else if (IFLAG & IGNBRK)
 245                                                         continue;
 246                                                 else if (IFLAG & BRKINT) 
 247                         rs_sched_event(info, RS_EVENT_BREAK_INT);
 248                                                 else
 249                                                         ch = 0;
 250                                         } else if (IFLAG & IGNPAR)
 251                                                 continue;
 252                                         if (IFLAG & PARMRK) {
 253                                                 queue->buf[head++] = 0xff;
 254                                                 head &= TTY_BUF_SIZE-1;
 255                                                 queue->buf[head++] = 0;
 256                                                 head &= TTY_BUF_SIZE-1;
 257                                         } else
 258                                                 ch = 0;
 259                                 } else if ((IFLAG & PARMRK) && (ch == 0xff)) {
 260                                         queue->buf[head++] = 0xff;
 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)) &
 266                                  UART_LSR_DR);
 267                         queue->head = head;
 268                         if ((VLEFT < RQ_THRESHOLD_LW)
 269                             && !set_bit(TTY_RQ_THROTTLED, &info->tty->flags)) 
 270                                 rs_throttle(info->tty, TTY_THROTTLE_RQ_FULL);
 271                         rs_sched_event(info, RS_EVENT_READ_PROCESS);
 272                 }
 273                 if ((status & UART_LSR_THRE) &&
 274                     !info->tty->stopped) {
 275                         queue = &info->tty->write_q;
 276                         head = queue->head;
 277                         tail = queue->tail;
 278                         if (head==tail && !info->x_char)
 279                                 goto no_xmit;
 280                         if (info->x_char) {
 281                                 serial_outp(info, UART_TX, info->x_char);
 282                                 info->x_char = 0;
 283                         } else {
 284                                 count = info->xmit_fifo_size;
 285                                 while (count--) {
 286                                         if (tail == head)
 287                                                 break;
 288                                         serial_outp(info, UART_TX,
 289                                                     queue->buf[tail++]);
 290                                         tail &= TTY_BUF_SIZE-1;
 291                                 }
 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,
 298                                                 &tty_check_write);
 299                                         mark_bh(TTY_BH);
 300                                 }
 301                         }
 302                         info->timer = jiffies + info->timeout;
 303                         if (info->timer < timer_table[RS_TIMER].expires)
 304                                 timer_table[RS_TIMER].expires = info->timer;
 305                         set_bit(info->line, rs_write_active);
 306                         timer_active |= 1 << RS_TIMER;
 307 #ifdef SERIAL_INT_DEBUG
 308                         printk("THRE...");
 309 #endif
 310                 }
 311         no_xmit:
 312                 status = serial_in(info, UART_MSR);
 313                 
 314                 if (!(CFLAG & CLOCAL) && (status & UART_MSR_DDCD)) {
 315                         if (status & UART_MSR_DCD) {
 316 #ifdef SERIAL_INT_DEBUG
 317                                 printk("DCD on...");
 318 #endif
 319                                 rs_sched_event(info, RS_EVENT_OPEN_WAKEUP);
 320                         } else {
 321 #ifdef SERIAL_INT_DEBUG
 322                                 printk("DCD off...");
 323 #endif
 324                                 rs_sched_event(info, RS_EVENT_HUP_PGRP);
 325                         }
 326                 }
 327                 if (CFLAG & CRTSCTS) {
 328                         if (info->tty->stopped) {
 329                                 if (status & UART_MSR_CTS) {
 330                                         info->tty->stopped = 0;
 331                                         restart_port(info);
 332                                 }
 333                         } else 
 334                                 info->tty->stopped = !(status & UART_MSR_CTS);
 335                 }
 336         next_loop:
 337                 info = info->next_port;
 338                 if (!info && !done) {
 339 #ifdef SERIAL_INT_DEBUG
 340                         printk("repeating...");
 341 #endif
 342                         info = IRQ_ports[irq];
 343                         done = 1;
 344                 }
 345         }
 346 }
 347 
 348 #ifdef CONFIG_AUTO_IRQ
 349 /*
 350  * This is the serial driver's interrupt routine while we are probing
 351  * for submarines.
 352  */
 353 static volatile int rs_irq_triggered;
 354 static volatile int rs_triggered;
 355 
 356 static void rs_probe(int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
 357 {
 358         rs_irq_triggered = irq;
 359         rs_triggered |= 1 << irq;
 360         return;
 361 }
 362 #endif
 363 
 364 static void do_softint()
     /* [previous][next][first][last][top][bottom][index][help] */
 365 {
 366         int                     i;
 367         struct async_struct     *info;
 368         
 369         for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
 370                 if (!clear_bit(i, rs_event)) {
 371                         if (!info->tty) 
 372                                 continue;
 373                         if (!clear_bit(RS_EVENT_READ_PROCESS, &info->event)) {
 374                                 TTY_READ_FLUSH(info->tty);
 375                         }
 376                         if (!clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
 377                                 wake_up_interruptible(&info->tty->write_q.proc_list);
 378                         }
 379                         if (!clear_bit(RS_EVENT_HUP_PGRP, &info->event))
 380                                 tty_hangup(info->tty);
 381                         if (!clear_bit(RS_EVENT_BREAK_INT, &info->event)) {
 382                                 flush_input(info->tty);
 383                                 flush_output(info->tty);
 384                                 if (info->tty->pgrp > 0)
 385                                         kill_pg(info->tty->pgrp, SIGINT,1);
 386                         }
 387                         if (!clear_bit(RS_EVENT_DO_SAK, &info->event)) {
 388                                 do_SAK(info->tty);
 389                         }
 390                         if (!clear_bit(RS_EVENT_OPEN_WAKEUP, &info->event)) {
 391                                 wake_up_interruptible(&info->open_wait);
 392                         }
 393                 }
 394         }
 395 }
 396 
 397 /*
 398  * This subroutine handles all of the timer functionality required for
 399  * the serial ports.
 400  */
 401 
 402 static void rs_timer(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 403 {
 404         int                     i;
 405         struct async_struct     *info;
 406 
 407         for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
 408                 if (test_bit(i, rs_write_active) && (info->timer <= jiffies)) {
 409                         clear_bit(i, rs_write_active);
 410                         rs_write(info->tty);
 411                 }
 412         }
 413 }
 414 
 415 /*
 416  * Note: this subroutine must be called with the interrupts *off*
 417  */
 418 static void restart_port(struct async_struct *info)
     /* [previous][next][first][last][top][bottom][index][help] */
 419 {
 420         struct tty_queue * queue;
 421         int head, tail, count;
 422         
 423         if (serial_inp(info, UART_LSR) & UART_LSR_THRE) {
 424                 if (info->x_char) {
 425                         serial_outp(info, UART_TX, info->x_char);
 426                         info->x_char = 0;
 427                 } else {
 428                         queue = &info->tty->write_q;
 429                         head = queue->head;
 430                         tail = queue->tail;
 431                         count = info->xmit_fifo_size;
 432                         while (count--) {
 433                                 if (tail == head)
 434                                         break;
 435                                 serial_outp(info, UART_TX, queue->buf[tail++]);
 436                                 tail &= TTY_BUF_SIZE-1;
 437                         }
 438                         queue->tail = tail;
 439                 }
 440         }
 441 }       
 442 
 443 /*
 444  * This routine gets called when tty_write has put something into
 445  * the write_queue.  
 446  */
 447 void rs_write(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 448 {
 449         struct async_struct *info;
 450 
 451         if (!tty || tty->stopped)
 452                 return;
 453         info = rs_table + DEV_TO_SL(tty->line);
 454         cli();
 455         restart_port(info);
 456         sti();
 457 }
 458 
 459 static void rs_throttle(struct tty_struct * tty, int status)
     /* [previous][next][first][last][top][bottom][index][help] */
 460 {
 461         struct async_struct *info;
 462         unsigned char mcr;
 463 
 464 #ifdef notdef
 465         printk("throttle tty%d: %d (%d, %d)....\n", DEV_TO_SL(tty->line),
 466                status, LEFT(&tty->read_q), LEFT(&tty->secondary));
 467 #endif
 468         switch (status) {
 469         case TTY_THROTTLE_RQ_FULL:
 470                 info = rs_table + DEV_TO_SL(tty->line);
 471                 if (tty->termios->c_iflag & IXOFF) {
 472                         info->x_char = STOP_CHAR(tty);
 473                 } else {
 474                         mcr = serial_inp(info, UART_MCR);
 475                         mcr &= ~UART_MCR_RTS;
 476                         serial_out(info, UART_MCR, mcr);
 477                 }
 478                 break;
 479         case TTY_THROTTLE_RQ_AVAIL:
 480                 info = rs_table + DEV_TO_SL(tty->line);
 481                 if (tty->termios->c_iflag & IXOFF) {
 482                         cli();
 483                         if (info->x_char)
 484                                 info->x_char = 0;
 485                         else
 486                                 info->x_char = START_CHAR(tty);
 487                         sti();
 488                 } else {
 489                         mcr = serial_in(info, UART_MCR);
 490                         mcr |= UART_MCR_RTS;
 491                         serial_out(info, UART_MCR, mcr);
 492                 }
 493                 break;
 494         }
 495 }
 496 
 497 /*
 498  * This routine is called when the serial port gets closed.  First, we
 499  * wait for the last remaining data to be sent.  Then, we unlink its
 500  * async structure from the interrupt chain if necessary, and we free
 501  * that IRQ if nothing is left in the chain.
 502  */
 503 static void rs_close(struct tty_struct *tty, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 504 {
 505         struct async_struct * info;
 506         int irq, line;
 507 
 508         line = DEV_TO_SL(tty->line);
 509         if ((line < 0) || (line >= NR_PORTS))
 510                 return;
 511         info = rs_table + line;
 512 #ifdef SERIAL_DEBUG_OPEN
 513         printk("rs_close ttys%d, count = %d\n", info->line, info->count);
 514 #endif
 515         if (--info->count > 0)
 516                 return;
 517         tty->stopped = 0;               /* Force flush to succeed */
 518         wait_until_sent(tty);
 519         clear_bit(line, rs_write_active);
 520         clear_bit(line, rs_event);
 521         info->event = 0;
 522         info->count = 0;
 523         info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
 524         if (info->blocked_open) {
 525                 shutdown(info);
 526                 startup(info);
 527                 return;
 528         }
 529         if (info->flags & ASYNC_INITIALIZED) {
 530                 shutdown(info);
 531                 irq = info->irq;
 532                 if (irq == 2)
 533                         irq = 9;
 534                 if (irq) {
 535                         if (info->next_port)
 536                                 info->next_port->prev_port = info->prev_port;
 537                         if (info->prev_port)
 538                                 info->prev_port->next_port = info->next_port;
 539                         else
 540                                 IRQ_ports[irq] = info->next_port;
 541                         if (!IRQ_ports[irq])
 542                                 free_irq(irq);
 543                 }
 544         }
 545         info->tty = 0;
 546 }
 547 
 548 static void startup(struct async_struct * info)
     /* [previous][next][first][last][top][bottom][index][help] */
 549 {
 550         unsigned short ICP;
 551         unsigned long flags;
 552 
 553         __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
 554 
 555         /*
 556          * First, clear the FIFO buffers and disable them
 557          */
 558         if (info->type == PORT_16550A)
 559                 serial_outp(info, UART_FCR, UART_FCR_CLEAR_CMD);
 560 
 561         /*
 562          * Next, clear the interrupt registers.
 563          */
 564         (void)serial_inp(info, UART_LSR);
 565         (void)serial_inp(info, UART_RX);
 566         (void)serial_inp(info, UART_IIR);
 567         (void)serial_inp(info, UART_MSR);
 568 
 569         /*
 570          * Now, initialize the UART 
 571          */
 572         serial_outp(info, UART_LCR, UART_LCR_WLEN8);    /* reset DLAB */
 573         if (info->flags & ASYNC_FOURPORT) 
 574                 serial_outp(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
 575         else
 576                 serial_outp(info, UART_MCR,
 577                             UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
 578         
 579         /*
 580          * Enable FIFO's if necessary
 581          */
 582         if (info->type == PORT_16550A) {
 583                 serial_outp(info, UART_FCR, UART_FCR_SETUP_CMD);
 584                 info->xmit_fifo_size = 16;
 585         } else {
 586                 info->xmit_fifo_size = 1;
 587         }
 588 
 589         /*
 590          * Finally, enable interrupts
 591          */
 592         serial_outp(info, UART_IER, 0x0f);      /* enable all intrs */
 593         if (info->flags & ASYNC_FOURPORT) {
 594                 /* Enable interrupts on the AST Fourport board */
 595                 ICP = (info->port & 0xFE0) | 0x01F;
 596                 outb_p(0x80, ICP);
 597                 (void) inb_p(ICP);
 598         }
 599 
 600         /*
 601          * And clear the interrupt registers again for luck.
 602          */
 603         (void)serial_inp(info, UART_LSR);
 604         (void)serial_inp(info, UART_RX);
 605         (void)serial_inp(info, UART_IIR);
 606         (void)serial_inp(info, UART_MSR);
 607 
 608         info->flags |= ASYNC_INITIALIZED;
 609         if (info->tty)
 610                 clear_bit(TTY_IO_ERROR, &info->tty->flags);
 611         __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
 612 }
 613 
 614 static void shutdown(struct async_struct * info)
     /* [previous][next][first][last][top][bottom][index][help] */
 615 {
 616         unsigned long flags;
 617 
 618         __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
 619         serial_outp(info, UART_IER, 0x00);      /* disable all intrs */
 620         if (info->tty && !(info->tty->termios->c_cflag & HUPCL))
 621                 serial_outp(info, UART_MCR, UART_MCR_DTR);
 622         else
 623                 /* reset DTR,RTS,OUT_2 */               
 624                 serial_outp(info, UART_MCR, 0x00);
 625         serial_outp(info, UART_FCR, UART_FCR_CLEAR_CMD); /* disable FIFO's */
 626         (void)serial_in(info, UART_RX);    /* read data port to reset things */
 627         info->flags &= ~ASYNC_INITIALIZED;
 628         if (info->tty)
 629                 set_bit(TTY_IO_ERROR, &info->tty->flags);
 630         __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
 631 }
 632 
 633 static void change_speed(unsigned int line)
     /* [previous][next][first][last][top][bottom][index][help] */
 634 {
 635         struct async_struct * info;
 636         unsigned short port;
 637         int     quot = 0;
 638         unsigned cflag,cval,mcr;
 639         int     i;
 640 
 641         if (line >= NR_PORTS)
 642                 return;
 643         info = rs_table + line;
 644         if (!info->tty || !info->tty->termios)
 645                 return;
 646         cflag = info->tty->termios->c_cflag;
 647         if (!(port = info->port))
 648                 return;
 649         i = cflag & CBAUD;
 650         if (i == 15) {
 651                 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
 652                         i += 1;
 653                 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
 654                         i += 2;
 655                 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
 656                         quot = info->custom_divisor;
 657         }
 658         if (quot) {
 659                 info->timeout = ((info->xmit_fifo_size*HZ*15*quot) /
 660                                  info->baud_base) + 2;
 661         } else if (baud_table[i] == 134) {
 662                 quot = (2*info->baud_base / 269);
 663                 info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
 664         } else if (baud_table[i]) {
 665                 quot = info->baud_base / baud_table[i];
 666                 info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
 667         } else {
 668                 quot = 0;
 669                 info->timeout = 0;
 670         }
 671         mcr = serial_in(info, UART_MCR);
 672         if (quot) 
 673                 serial_out(info, UART_MCR, mcr | UART_MCR_DTR);
 674         else {
 675                 serial_out(info, UART_MCR, mcr & ~UART_MCR_DTR);
 676                 return;
 677         }
 678         /* byte size and parity */
 679         cval = cflag & (CSIZE | CSTOPB);
 680         cval >>= 4;
 681         if (cflag & PARENB)
 682                 cval |= 8;
 683         if (!(cflag & PARODD))
 684                 cval |= 16;
 685         cli();
 686         serial_outp(info, UART_LCR, cval | UART_LCR_DLAB);      /* set DLAB */
 687         serial_outp(info, UART_DLL, quot & 0xff);       /* LS of divisor */
 688         serial_outp(info, UART_DLM, quot >> 8);         /* MS of divisor */
 689         serial_outp(info, UART_LCR, cval);              /* reset DLAB */
 690         sti();
 691 }
 692 
 693 static int get_serial_info(struct async_struct * info,
     /* [previous][next][first][last][top][bottom][index][help] */
 694                            struct serial_struct * retinfo)
 695 {
 696         struct serial_struct tmp;
 697   
 698         if (!retinfo)
 699                 return -EFAULT;
 700         tmp.type = info->type;
 701         tmp.line = info->line;
 702         tmp.port = info->port;
 703         tmp.irq = info->irq;
 704         tmp.flags = info->flags;
 705         tmp.baud_base = info->baud_base;
 706         memcpy_tofs(retinfo,&tmp,sizeof(*retinfo));
 707         return 0;
 708 }
 709 
 710 static int set_serial_info(struct async_struct * info,
     /* [previous][next][first][last][top][bottom][index][help] */
 711                            struct serial_struct * new_info)
 712 {
 713         struct serial_struct new;
 714         unsigned int            irq,check_irq;
 715         int                     retval;
 716         struct                  sigaction sa;
 717         struct async_struct     old_info;
 718 
 719         if (!new_info)
 720                 return -EFAULT;
 721         memcpy_fromfs(&new,new_info,sizeof(new));
 722 
 723         check_irq = 0;
 724         old_info = *info;
 725         if (!suser()) {
 726                 info->flags = ((info->flags & ~ASYNC_SPD_MASK) |
 727                                (new.flags & ASYNC_SPD_MASK));
 728                 info->custom_divisor = new.custom_divisor;
 729                 new.port = 0;   /* Prevent initialization below */
 730                 goto check_and_exit;
 731         }
 732 
 733         if ((new.irq > 15) || (new.port > 0xffff) ||
 734             (new.type < PORT_UNKNOWN) || (new.type > PORT_MAX)) {
 735                 return -EINVAL;
 736         }
 737         
 738         info->baud_base = new.baud_base;
 739         info->flags = ((info->flags & ~ASYNC_FLAGS) |
 740                         (new.flags & ASYNC_FLAGS));
 741         info->custom_divisor = new.custom_divisor;
 742         info->type = new.type;
 743         
 744         if (new.irq == 2)
 745                 new.irq = 9;
 746         irq = info->irq;
 747         if (irq == 2)
 748                 irq = 9;
 749         
 750         /*
 751          * If necessary, first we try to grab the new IRQ for serial
 752          * interrupts.  (We have to do this early, since we may get an
 753          * error trying to do this.)
 754          */
 755         if (new.port && new.irq && info->type &&
 756             ((irq != new.irq) || !(info->flags & ASYNC_INITIALIZED))) {
 757                 if (!IRQ_ports[new.irq]) {
 758                         sa.sa_handler = rs_interrupt;
 759                         sa.sa_flags = (SA_INTERRUPT);
 760                         sa.sa_mask = 0;
 761                         sa.sa_restorer = NULL;
 762                         retval = irqaction(new.irq,&sa);
 763                         if (retval) {
 764                                 *info = old_info;
 765                                 return retval;
 766                         }
 767                 }
 768         }
 769 
 770         if ((new.irq != irq) ||
 771             (new.port != info->port)) {
 772                 /*
 773                  * We need to shutdown the serial port at the old
 774                  * port/irq combination.
 775                  */
 776                 if (info->flags & ASYNC_INITIALIZED) {
 777                         shutdown(info);
 778                         if (info->next_port)
 779                                 info->next_port->prev_port = info->prev_port;
 780                         if (info->prev_port)
 781                                 info->prev_port->next_port = info->next_port;
 782                         else
 783                                 IRQ_ports[irq] = info->next_port;
 784                         check_irq = irq; /* Check later if we need to */
 785                                          /* free the IRQ */
 786                 }
 787                 info->irq = new.irq;
 788                 info->port = new.port;
 789         }
 790         
 791 check_and_exit:
 792         if (new.port && new.irq && info->type &&
 793             !(info->flags & ASYNC_INITIALIZED)) {
 794                 /*
 795                  * Link the port into the new interrupt chain.
 796                  */
 797                 info->prev_port = 0;
 798                 info->next_port = IRQ_ports[info->irq];
 799                 if (info->next_port)
 800                         info->next_port->prev_port = info;
 801                 IRQ_ports[info->irq] = info;
 802                 startup(info);
 803                 change_speed(info->line);
 804         } else if (((old_info.flags & ASYNC_SPD_MASK) !=
 805                     (info->flags & ASYNC_SPD_MASK)) ||
 806                    (old_info.custom_divisor != info->custom_divisor))
 807                 change_speed(info->line);
 808 
 809         if (check_irq && !IRQ_ports[check_irq])
 810                 free_irq(check_irq);
 811         
 812         return 0;
 813 }
 814 
 815 static int get_modem_info(struct async_struct * info, unsigned int *value)
     /* [previous][next][first][last][top][bottom][index][help] */
 816 {
 817         unsigned char control, status;
 818         unsigned int result;
 819 
 820         control = serial_in(info, UART_MCR);
 821         status = serial_in(info, UART_MSR);
 822         result =  ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
 823                 | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
 824                 | ((status  & UART_MSR_DCD) ? TIOCM_CAR : 0)
 825                 | ((status  & UART_MSR_RI) ? TIOCM_RNG : 0)
 826                 | ((status  & UART_MSR_DSR) ? TIOCM_DSR : 0)
 827                 | ((status  & UART_MSR_CTS) ? TIOCM_CTS : 0);
 828         put_fs_long(result,(unsigned long *) value);
 829         return 0;
 830 }
 831 
 832 static int set_modem_info(struct async_struct * info, unsigned int cmd,
     /* [previous][next][first][last][top][bottom][index][help] */
 833                           unsigned int *value)
 834 {
 835         unsigned char control;
 836         unsigned int arg = get_fs_long((unsigned long *) value);
 837         
 838         control = serial_in(info, UART_MCR);
 839 
 840         switch (cmd) {
 841                 case TIOCMBIS:
 842                         if (arg & TIOCM_RTS)
 843                                 control |= UART_MCR_RTS;
 844                         if (arg & TIOCM_DTR)
 845                                 control |= UART_MCR_DTR;
 846                         break;
 847                 case TIOCMBIC:
 848                         if (arg & TIOCM_RTS)
 849                                 control &= ~UART_MCR_RTS;
 850                         if (arg & TIOCM_DTR)
 851                                 control &= ~UART_MCR_DTR;
 852                         break;
 853                 case TIOCMSET:
 854                         control = (control & ~0x03)
 855                                 | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
 856                                 | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0);
 857                         break;
 858                 default:
 859                         return -EINVAL;
 860         }
 861         serial_out(info, UART_MCR, control);
 862         return 0;
 863 }
 864 
 865 static int rs_ioctl(struct tty_struct *tty, struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
 866                     unsigned int cmd, unsigned int arg)
 867 {
 868         int     line;
 869         struct async_struct * info;
 870 
 871         line = DEV_TO_SL(tty->line);
 872         if (line < 0 || line >= NR_PORTS)
 873                 return -ENODEV;
 874         info = rs_table + line;
 875         
 876         switch (cmd) {
 877                 case TCSBRK:
 878                         wait_until_sent(tty);
 879                         if (!arg)
 880                                 send_break(info);
 881                         return 0;
 882                 case TIOCMGET:
 883                         verify_area((void *) arg,sizeof(unsigned int *));
 884                         return get_modem_info(info, (unsigned int *) arg);
 885                 case TIOCMBIS:
 886                 case TIOCMBIC:
 887                 case TIOCMSET:
 888                         return set_modem_info(info, cmd, (unsigned int *) arg);
 889                 case TIOCGSERIAL:
 890                         verify_area((void *) arg,sizeof(struct serial_struct));
 891                         return get_serial_info(info,
 892                                                (struct serial_struct *) arg);
 893                 case TIOCSSERIAL:
 894                         return set_serial_info(info,
 895                                                (struct serial_struct *) arg);
 896                 
 897         default:
 898                 return -EINVAL;
 899         }
 900         return 0;
 901 }
 902 
 903 static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
     /* [previous][next][first][last][top][bottom][index][help] */
 904 {
 905         if (tty->termios->c_cflag == old_termios->c_cflag)
 906                 return;
 907 
 908         change_speed(DEV_TO_SL(tty->line));
 909         
 910         if ((old_termios->c_cflag & CRTSCTS) &&
 911             !(tty->termios->c_cflag & CRTSCTS)) {
 912                 tty->stopped = 0;
 913                 rs_write(tty);
 914         }
 915 
 916         if (!(old_termios->c_cflag & CLOCAL) &&
 917             (tty->termios->c_cflag & CLOCAL))
 918                 wake_up_interruptible(&rs_table[DEV_TO_SL(tty->line)].open_wait);
 919 }
 920 
 921 /*
 922  * This routine is called whenever a serial port is opened.  It
 923  * enables interrupts for a serial port, linking in its async structure into
 924  * the IRQ chain.   It also performs the serial-speicific
 925  * initalization for the tty structure.
 926  */
 927 int rs_open(struct tty_struct *tty, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 928 {
 929         struct async_struct     *info;
 930         int                     irq, retval, line;
 931         struct sigaction        sa;
 932 
 933         line = DEV_TO_SL(tty->line);
 934         if ((line < 0) || (line >= NR_PORTS))
 935                 return -ENODEV;
 936         info = rs_table + line;
 937 #ifdef SERIAL_DEBUG_OPEN
 938         printk("rs_open ttys%d, count = %d\n", info->line, info->count);
 939 #endif
 940         info->count++;
 941         info->tty = tty;
 942         
 943         tty->write = rs_write;
 944         tty->close = rs_close;
 945         tty->ioctl = rs_ioctl;
 946         tty->throttle = rs_throttle;
 947         tty->set_termios = rs_set_termios;
 948 
 949         if (!(info->flags & ASYNC_INITIALIZED)) {
 950                 if (!info->port || !info->irq || !info->type) {
 951                         set_bit(TTY_IO_ERROR, &tty->flags);
 952                         return 0;
 953                 }
 954                 irq = info->irq;
 955                 if (irq == 2)
 956                         irq = 9;
 957                 if (!IRQ_ports[irq]) {
 958                         sa.sa_handler = rs_interrupt;
 959                         sa.sa_flags = (SA_INTERRUPT);
 960                         sa.sa_mask = 0;
 961                         sa.sa_restorer = NULL;
 962                         retval = irqaction(irq,&sa);
 963                         if (retval)
 964                                 return retval;
 965                 }
 966                 /*
 967                  * Link in port to IRQ chain
 968                  */
 969                 info->prev_port = 0;
 970                 info->next_port = IRQ_ports[irq];
 971                 if (info->next_port)
 972                         info->next_port->prev_port = info;
 973                 IRQ_ports[irq] = info;
 974                 
 975                 startup(info);
 976                 change_speed(info->line);
 977         }
 978 
 979         retval = block_til_ready(tty, filp, info);
 980         if (retval)
 981                 return retval;
 982         
 983         return 0;
 984 
 985 }
 986 
 987 static int block_til_ready(struct tty_struct *tty, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
 988                            struct async_struct *info)
 989 {
 990         struct wait_queue wait = { current, NULL };
 991         int     retval;
 992         
 993         /*
 994          * If this is a callout device, then just make sure the normal
 995          * device isn't being used.
 996          */
 997         if (MAJOR(filp->f_rdev) == 5) {
 998                 if (info->flags & ASYNC_NORMAL_ACTIVE)
 999                         return -EBUSY;
1000                 info->flags |= ASYNC_CALLOUT_ACTIVE;
1001                 return 0;
1002         }
1003         
1004         /*
1005          * If non-blocking mode is set, then make the check up front
1006          * and then exit.
1007          */
1008         if (filp->f_flags & O_NONBLOCK) {
1009                 if (info->flags & ASYNC_CALLOUT_ACTIVE)
1010                         return -EBUSY;
1011                 info->flags |= ASYNC_NORMAL_ACTIVE;
1012                 return 0;
1013         }
1014 
1015         /*
1016          * Block waiting for the carrier detect and the line to become
1017          * free (i.e., not in use by the callout).  While we are in
1018          * this loop, info->count is dropped by one, so that
1019          * rs_close() knows when to free things.  We restore it upon
1020          * exit, either normal or abnormal.
1021          */
1022         retval = 0;
1023         add_wait_queue(&info->open_wait, &wait);
1024 #ifdef SERIAL_DEBUG_OPEN
1025         printk("block_til_ready before block: ttys%d, count = %d\n",
1026                info->line, info->count);
1027 #endif
1028         info->count--;
1029         info->blocked_open++;
1030         while (1) {
1031                 serial_out(info, UART_MCR,
1032                            serial_inp(info, UART_MCR) | UART_MCR_DTR);
1033                 current->state = TASK_INTERRUPTIBLE;
1034                 if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
1035                     ((tty->termios->c_cflag & CLOCAL) ||
1036                      (serial_in(info, UART_MSR) & UART_MSR_DCD)))
1037                         break;
1038                 if (current->signal & ~current->blocked) {
1039                         retval = -ERESTARTSYS;
1040                         break;
1041                 }
1042 #ifdef SERIAL_DEBUG_OPEN
1043                 printk("block_til_ready blocking: ttys%d, count = %d\n",
1044                        info->line, info->count);
1045 #endif
1046                 schedule();
1047         }
1048         current->state = TASK_RUNNING;
1049         remove_wait_queue(&info->open_wait, &wait);
1050         info->count++;
1051         info->blocked_open--;
1052 #ifdef SERIAL_DEBUG_OPEN
1053         printk("block_til_ready after blocking: ttys%d, count = %d\n",
1054                info->line, info->count);
1055 #endif
1056         if (retval)
1057                 return retval;
1058         info->flags |= ASYNC_NORMAL_ACTIVE;
1059         tty_unhangup(filp);     /* To make sure fops is OK */
1060         return 0;
1061 }       
1062 
1063 
1064 static void show_serial_version()
     /* [previous][next][first][last][top][bottom][index][help] */
1065 {
1066         printk("Serial driver version 3.91 with");
1067 #ifdef CONFIG_AST_FOURPORT
1068         printk(" AST_FOURPORT");
1069 #define SERIAL_OPT
1070 #endif
1071 #ifdef CONFIG_ACCENT_ASYNC
1072         printk(" ACCENT_ASYNC");
1073 #define SERIAL_OPT
1074 #endif
1075 #ifdef CONFIG_AUTO_IRQ
1076         printk (" AUTO_IRQ");
1077 #define SERIAL_OPT
1078 #endif
1079 #ifdef SERIAL_OPT
1080         printk(" enabled\n");
1081 #else
1082         printk(" no serial options enabled\n");
1083 #endif
1084 #undef SERIAL_OPT
1085 }
1086 
1087 #ifdef CONFIG_AUTO_IRQ
1088 static int get_auto_irq(struct async_struct *info)
     /* [previous][next][first][last][top][bottom][index][help] */
1089 {
1090         unsigned char save_MCR, save_IER, save_ICP=0;
1091         unsigned short ICP=0, port = info->port;
1092         unsigned long timeout;
1093         
1094         /*
1095          * Enable interrupts and see who answers
1096          */
1097         rs_irq_triggered = 0;
1098         save_IER = serial_inp(info, UART_IER);
1099         save_MCR = serial_inp(info, UART_MCR);
1100         if (info->flags & ASYNC_FOURPORT)  {
1101                 serial_outp(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
1102                 serial_outp(info, UART_IER, 0x0f);      /* enable all intrs */
1103                 ICP = (port & 0xFE0) | 0x01F;
1104                 save_ICP = inb_p(ICP);
1105                 outb_p(0x80, ICP);
1106                 (void) inb_p(ICP);
1107         } else {
1108                 serial_outp(info, UART_MCR,
1109                             UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
1110                 serial_outp(info, UART_IER, 0x0f);      /* enable all intrs */
1111         }
1112         /*
1113          * Next, clear the interrupt registers.
1114          */
1115         (void)serial_inp(info, UART_LSR);
1116         (void)serial_inp(info, UART_RX);
1117         (void)serial_inp(info, UART_IIR);
1118         (void)serial_inp(info, UART_MSR);
1119         
1120         timeout = jiffies+2;
1121         while (timeout >= jiffies) {
1122                 if (rs_irq_triggered)
1123                         break;
1124         }
1125         /*
1126          * Now check to see if we got any business, and clean up.
1127          */
1128         serial_outp(info, UART_IER, save_IER);
1129         serial_outp(info, UART_MCR, save_MCR);
1130         if (info->flags & ASYNC_FOURPORT)
1131                 outb_p(save_ICP, ICP);
1132         return(rs_irq_triggered);
1133 }
1134 #endif
1135 
1136 
1137 static void init(struct async_struct * info)
     /* [previous][next][first][last][top][bottom][index][help] */
1138 {
1139         unsigned char status1, status2, scratch, scratch2;
1140         unsigned port = info->port;
1141 #ifdef CONFIG_AUTO_IRQ
1142         int retries;
1143         
1144         if (!port)
1145                 return;
1146 
1147         scratch2 = 0;
1148         for (retries = 0; retries < 5; retries++) {
1149                 if (!scratch)
1150                         scratch = get_auto_irq(info);
1151                 if (!scratch2)
1152                         scratch2 = get_auto_irq(info);
1153                 if (scratch && scratch2) {
1154                         if (scratch == scratch2)
1155                                 break;
1156                         scratch = scratch2 = 0;
1157                 }
1158         }
1159         if (scratch && (scratch == scratch2))
1160                 info->irq = scratch;
1161         else {
1162                 info->type = PORT_UNKNOWN;
1163                 return;
1164         }
1165         
1166 #else /* CONFIG_AUTO_IRQ */
1167 
1168         if (!port)
1169                 return;
1170                         
1171         /* 
1172          * Check to see if a UART is really there.  
1173          */
1174         scratch = serial_inp(info, UART_MCR);
1175         serial_outp(info, UART_MCR, UART_MCR_LOOP | scratch);
1176         scratch2 = serial_inp(info, UART_MSR);
1177         serial_outp(info, UART_MCR, UART_MCR_LOOP | 0x0A);
1178         status1 = serial_inp(info, UART_MSR) & 0xF0;
1179         serial_outp(info, UART_MCR, scratch);
1180         serial_outp(info, UART_MSR, scratch2);
1181         if (status1 != 0x90) {
1182                 info->type = PORT_UNKNOWN;
1183                 return;
1184         }
1185 #endif /* CONFIG_AUTO_IRQ */
1186         
1187         outb_p(UART_FCR_ENABLE_FIFO, UART_FCR + port);
1188         scratch = inb(UART_IIR + port) >> 6;
1189         info->xmit_fifo_size = 1;
1190         switch (scratch) {
1191                 case 0:
1192                         info->type = PORT_16450;
1193                         break;
1194                 case 1:
1195                         info->type = PORT_UNKNOWN;
1196                         break;
1197                 case 2:
1198                         info->type = PORT_16550;
1199                         break;
1200                 case 3:
1201                         info->type = PORT_16550A;
1202                         info->xmit_fifo_size = 16;
1203                         break;
1204         }
1205         if (info->type == PORT_16450) {
1206                 scratch = inb(UART_SCR + port);
1207                 outb_p(0xa5, UART_SCR + port);
1208                 status1 = inb(UART_SCR + port);
1209                 outb_p(0x5a, UART_SCR + port);
1210                 status2 = inb(UART_SCR + port);
1211                 outb_p(scratch, UART_SCR + port);
1212                 if ((status1 != 0xa5) || (status2 != 0x5a))
1213                         info->type = PORT_8250;
1214         }
1215         shutdown(info);
1216 }
1217 
1218 long rs_init(long kmem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
1219 {
1220         int i;
1221         struct async_struct * info;
1222 #ifdef CONFIG_AUTO_IRQ
1223         int irq_lines = 0;
1224         struct sigaction sa;
1225         unsigned long timeout;
1226         
1227         /*
1228          *  We will be auto probing for irq's, so turn on interrupts now!
1229          */
1230         sti();
1231         
1232         rs_triggered = 0;
1233         sa.sa_handler = rs_probe;
1234         sa.sa_flags = (SA_INTERRUPT);
1235         sa.sa_mask = 0;
1236         sa.sa_restorer = NULL;
1237 #endif  
1238         timer_table[RS_TIMER].fn = rs_timer;
1239         timer_table[RS_TIMER].expires = 0;
1240         
1241         for (i = 0; i < 16; i++) {
1242                 IRQ_ports[i] = 0;
1243 #ifdef CONFIG_AUTO_IRQ
1244                 if (!irqaction(i, &sa))
1245                         irq_lines |= 1 << i;
1246 #endif
1247         }
1248 #ifdef CONFIG_AUTO_IRQ
1249         timeout = jiffies+5;
1250         while (timeout >= jiffies)
1251                 ;
1252         for (i = 0; i < 16; i++) {
1253                 if ((rs_triggered & (1 << i)) &&
1254                     (irq_lines & (1 << i))) {
1255                         irq_lines &= ~(1 << i);
1256                         printk("Wild interrupt?  (IRQ %d)\n", i);
1257                         free_irq(i);
1258                 }
1259         }
1260 #endif
1261         show_serial_version();
1262         for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
1263                 info->line = i;
1264                 info->tty = 0;
1265                 info->type = PORT_UNKNOWN;
1266                 info->timer = 0;
1267                 info->custom_divisor = 0;
1268                 info->x_char = 0;
1269                 info->event = 0;
1270                 info->count = 0;
1271                 info->blocked_open = 0;
1272                 info->open_wait = 0;
1273                 info->next_port = 0;
1274                 info->prev_port = 0;
1275                 init(info);
1276                 if (info->type == PORT_UNKNOWN)
1277                         continue;
1278                 printk("tty%02d%s at 0x%04x (irq = %d)", info->line, 
1279                        (info->flags & ASYNC_FOURPORT) ? " FourPort" : "",
1280                        info->port, info->irq);
1281                 switch (info->type) {
1282                         case PORT_8250:
1283                                 printk(" is a 8250\n");
1284                                 break;
1285                         case PORT_16450:
1286                                 printk(" is a 16450\n");
1287                                 break;
1288                         case PORT_16550:
1289                                 printk(" is a 16550\n");
1290                                 break;
1291                         case PORT_16550A:
1292                                 printk(" is a 16550A\n");
1293                                 break;
1294                         default:
1295                                 printk("\n");
1296                                 break;
1297                 }
1298         }
1299 #ifdef CONFIG_AUTO_IRQ
1300         /*
1301          * Turn interrupts back off, since they were off when we
1302          * started this.  See start_kernel() in init/main.c.
1303          */
1304         cli();
1305         for (i = 0; i < 16; i++) {
1306                 if (irq_lines & (1 << i))
1307                         free_irq(i);
1308         }
1309 #endif
1310         bh_base[SERIAL_BH].routine = do_softint;
1311         memset(&rs_event, 0, sizeof(rs_event));
1312         memset(&rs_write_active, 0, sizeof(rs_write_active));
1313         return kmem_start;
1314 }
1315 

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