linux/drivers/tty/amiserial.c
<<
>>
Prefs
   1/*
   2 * Serial driver for the amiga builtin port.
   3 *
   4 * This code was created by taking serial.c version 4.30 from kernel
   5 * release 2.3.22, replacing all hardware related stuff with the
   6 * corresponding amiga hardware actions, and removing all irrelevant
   7 * code. As a consequence, it uses many of the constants and names
   8 * associated with the registers and bits of 16550 compatible UARTS -
   9 * but only to keep track of status, etc in the state variables. It
  10 * was done this was to make it easier to keep the code in line with
  11 * (non hardware specific) changes to serial.c.
  12 *
  13 * The port is registered with the tty driver as minor device 64, and
  14 * therefore other ports should should only use 65 upwards.
  15 *
  16 * Richard Lucock 28/12/99
  17 *
  18 *  Copyright (C) 1991, 1992  Linus Torvalds
  19 *  Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 
  20 *              1998, 1999  Theodore Ts'o
  21 *
  22 */
  23
  24/*
  25 * Serial driver configuration section.  Here are the various options:
  26 *
  27 * SERIAL_PARANOIA_CHECK
  28 *              Check the magic number for the async_structure where
  29 *              ever possible.
  30 */
  31
  32#include <linux/delay.h>
  33
  34#undef SERIAL_PARANOIA_CHECK
  35#define SERIAL_DO_RESTART
  36
  37/* Set of debugging defines */
  38
  39#undef SERIAL_DEBUG_INTR
  40#undef SERIAL_DEBUG_OPEN
  41#undef SERIAL_DEBUG_FLOW
  42#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
  43
  44/* Sanity checks */
  45
  46#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
  47#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
  48 tty->name, (info->tport.flags), serial_driver->refcount,info->count,tty->count,s)
  49#else
  50#define DBG_CNT(s)
  51#endif
  52
  53/*
  54 * End of serial driver configuration section.
  55 */
  56
  57#include <linux/module.h>
  58
  59#include <linux/types.h>
  60#include <linux/serial.h>
  61#include <linux/serial_reg.h>
  62static char *serial_version = "4.30";
  63
  64#include <linux/errno.h>
  65#include <linux/signal.h>
  66#include <linux/sched.h>
  67#include <linux/kernel.h>
  68#include <linux/timer.h>
  69#include <linux/interrupt.h>
  70#include <linux/tty.h>
  71#include <linux/tty_flip.h>
  72#include <linux/circ_buf.h>
  73#include <linux/console.h>
  74#include <linux/major.h>
  75#include <linux/string.h>
  76#include <linux/fcntl.h>
  77#include <linux/ptrace.h>
  78#include <linux/ioport.h>
  79#include <linux/mm.h>
  80#include <linux/seq_file.h>
  81#include <linux/slab.h>
  82#include <linux/init.h>
  83#include <linux/bitops.h>
  84#include <linux/platform_device.h>
  85
  86#include <asm/setup.h>
  87
  88
  89#include <asm/irq.h>
  90
  91#include <asm/amigahw.h>
  92#include <asm/amigaints.h>
  93
  94struct serial_state {
  95        struct tty_port         tport;
  96        struct circ_buf         xmit;
  97        struct async_icount     icount;
  98
  99        unsigned long           port;
 100        int                     baud_base;
 101        int                     xmit_fifo_size;
 102        int                     custom_divisor;
 103        int                     read_status_mask;
 104        int                     ignore_status_mask;
 105        int                     timeout;
 106        int                     quot;
 107        int                     IER;    /* Interrupt Enable Register */
 108        int                     MCR;    /* Modem control register */
 109        int                     x_char; /* xon/xoff character */
 110};
 111
 112#define custom amiga_custom
 113static char *serial_name = "Amiga-builtin serial driver";
 114
 115static struct tty_driver *serial_driver;
 116
 117/* number of characters left in xmit buffer before we ask for more */
 118#define WAKEUP_CHARS 256
 119
 120static unsigned char current_ctl_bits;
 121
 122static void change_speed(struct tty_struct *tty, struct serial_state *info,
 123                struct ktermios *old);
 124static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
 125
 126
 127static struct serial_state rs_table[1];
 128
 129#define NR_PORTS ARRAY_SIZE(rs_table)
 130
 131#include <asm/uaccess.h>
 132
 133#define serial_isroot() (capable(CAP_SYS_ADMIN))
 134
 135
 136static inline int serial_paranoia_check(struct serial_state *info,
 137                                        char *name, const char *routine)
 138{
 139#ifdef SERIAL_PARANOIA_CHECK
 140        static const char *badmagic =
 141                "Warning: bad magic number for serial struct (%s) in %s\n";
 142        static const char *badinfo =
 143                "Warning: null async_struct for (%s) in %s\n";
 144
 145        if (!info) {
 146                printk(badinfo, name, routine);
 147                return 1;
 148        }
 149        if (info->magic != SERIAL_MAGIC) {
 150                printk(badmagic, name, routine);
 151                return 1;
 152        }
 153#endif
 154        return 0;
 155}
 156
 157/* some serial hardware definitions */
 158#define SDR_OVRUN   (1<<15)
 159#define SDR_RBF     (1<<14)
 160#define SDR_TBE     (1<<13)
 161#define SDR_TSRE    (1<<12)
 162
 163#define SERPER_PARENB    (1<<15)
 164
 165#define AC_SETCLR   (1<<15)
 166#define AC_UARTBRK  (1<<11)
 167
 168#define SER_DTR     (1<<7)
 169#define SER_RTS     (1<<6)
 170#define SER_DCD     (1<<5)
 171#define SER_CTS     (1<<4)
 172#define SER_DSR     (1<<3)
 173
 174static __inline__ void rtsdtr_ctrl(int bits)
 175{
 176    ciab.pra = ((bits & (SER_RTS | SER_DTR)) ^ (SER_RTS | SER_DTR)) | (ciab.pra & ~(SER_RTS | SER_DTR));
 177}
 178
 179/*
 180 * ------------------------------------------------------------
 181 * rs_stop() and rs_start()
 182 *
 183 * This routines are called before setting or resetting tty->stopped.
 184 * They enable or disable transmitter interrupts, as necessary.
 185 * ------------------------------------------------------------
 186 */
 187static void rs_stop(struct tty_struct *tty)
 188{
 189        struct serial_state *info = tty->driver_data;
 190        unsigned long flags;
 191
 192        if (serial_paranoia_check(info, tty->name, "rs_stop"))
 193                return;
 194
 195        local_irq_save(flags);
 196        if (info->IER & UART_IER_THRI) {
 197                info->IER &= ~UART_IER_THRI;
 198                /* disable Tx interrupt and remove any pending interrupts */
 199                custom.intena = IF_TBE;
 200                mb();
 201                custom.intreq = IF_TBE;
 202                mb();
 203        }
 204        local_irq_restore(flags);
 205}
 206
 207static void rs_start(struct tty_struct *tty)
 208{
 209        struct serial_state *info = tty->driver_data;
 210        unsigned long flags;
 211
 212        if (serial_paranoia_check(info, tty->name, "rs_start"))
 213                return;
 214
 215        local_irq_save(flags);
 216        if (info->xmit.head != info->xmit.tail
 217            && info->xmit.buf
 218            && !(info->IER & UART_IER_THRI)) {
 219                info->IER |= UART_IER_THRI;
 220                custom.intena = IF_SETCLR | IF_TBE;
 221                mb();
 222                /* set a pending Tx Interrupt, transmitter should restart now */
 223                custom.intreq = IF_SETCLR | IF_TBE;
 224                mb();
 225        }
 226        local_irq_restore(flags);
 227}
 228
 229/*
 230 * ----------------------------------------------------------------------
 231 *
 232 * Here starts the interrupt handling routines.  All of the following
 233 * subroutines are declared as inline and are folded into
 234 * rs_interrupt().  They were separated out for readability's sake.
 235 *
 236 * Note: rs_interrupt() is a "fast" interrupt, which means that it
 237 * runs with interrupts turned off.  People who may want to modify
 238 * rs_interrupt() should try to keep the interrupt handler as fast as
 239 * possible.  After you are done making modifications, it is not a bad
 240 * idea to do:
 241 * 
 242 * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
 243 *
 244 * and look at the resulting assemble code in serial.s.
 245 *
 246 *                              - Ted Ts'o (tytso@mit.edu), 7-Mar-93
 247 * -----------------------------------------------------------------------
 248 */
 249
 250static void receive_chars(struct serial_state *info)
 251{
 252        int status;
 253        int serdatr;
 254        unsigned char ch, flag;
 255        struct  async_icount *icount;
 256        int oe = 0;
 257
 258        icount = &info->icount;
 259
 260        status = UART_LSR_DR; /* We obviously have a character! */
 261        serdatr = custom.serdatr;
 262        mb();
 263        custom.intreq = IF_RBF;
 264        mb();
 265
 266        if((serdatr & 0x1ff) == 0)
 267            status |= UART_LSR_BI;
 268        if(serdatr & SDR_OVRUN)
 269            status |= UART_LSR_OE;
 270
 271        ch = serdatr & 0xff;
 272        icount->rx++;
 273
 274#ifdef SERIAL_DEBUG_INTR
 275        printk("DR%02x:%02x...", ch, status);
 276#endif
 277        flag = TTY_NORMAL;
 278
 279        /*
 280         * We don't handle parity or frame errors - but I have left
 281         * the code in, since I'm not sure that the errors can't be
 282         * detected.
 283         */
 284
 285        if (status & (UART_LSR_BI | UART_LSR_PE |
 286                      UART_LSR_FE | UART_LSR_OE)) {
 287          /*
 288           * For statistics only
 289           */
 290          if (status & UART_LSR_BI) {
 291            status &= ~(UART_LSR_FE | UART_LSR_PE);
 292            icount->brk++;
 293          } else if (status & UART_LSR_PE)
 294            icount->parity++;
 295          else if (status & UART_LSR_FE)
 296            icount->frame++;
 297          if (status & UART_LSR_OE)
 298            icount->overrun++;
 299
 300          /*
 301           * Now check to see if character should be
 302           * ignored, and mask off conditions which
 303           * should be ignored.
 304           */
 305          if (status & info->ignore_status_mask)
 306            goto out;
 307
 308          status &= info->read_status_mask;
 309
 310          if (status & (UART_LSR_BI)) {
 311#ifdef SERIAL_DEBUG_INTR
 312            printk("handling break....");
 313#endif
 314            flag = TTY_BREAK;
 315            if (info->tport.flags & ASYNC_SAK)
 316              do_SAK(info->tport.tty);
 317          } else if (status & UART_LSR_PE)
 318            flag = TTY_PARITY;
 319          else if (status & UART_LSR_FE)
 320            flag = TTY_FRAME;
 321          if (status & UART_LSR_OE) {
 322            /*
 323             * Overrun is special, since it's
 324             * reported immediately, and doesn't
 325             * affect the current character
 326             */
 327             oe = 1;
 328          }
 329        }
 330        tty_insert_flip_char(&info->tport, ch, flag);
 331        if (oe == 1)
 332                tty_insert_flip_char(&info->tport, 0, TTY_OVERRUN);
 333        tty_flip_buffer_push(&info->tport);
 334out:
 335        return;
 336}
 337
 338static void transmit_chars(struct serial_state *info)
 339{
 340        custom.intreq = IF_TBE;
 341        mb();
 342        if (info->x_char) {
 343                custom.serdat = info->x_char | 0x100;
 344                mb();
 345                info->icount.tx++;
 346                info->x_char = 0;
 347                return;
 348        }
 349        if (info->xmit.head == info->xmit.tail
 350            || info->tport.tty->stopped
 351            || info->tport.tty->hw_stopped) {
 352                info->IER &= ~UART_IER_THRI;
 353                custom.intena = IF_TBE;
 354                mb();
 355                return;
 356        }
 357
 358        custom.serdat = info->xmit.buf[info->xmit.tail++] | 0x100;
 359        mb();
 360        info->xmit.tail = info->xmit.tail & (SERIAL_XMIT_SIZE-1);
 361        info->icount.tx++;
 362
 363        if (CIRC_CNT(info->xmit.head,
 364                     info->xmit.tail,
 365                     SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
 366                tty_wakeup(info->tport.tty);
 367
 368#ifdef SERIAL_DEBUG_INTR
 369        printk("THRE...");
 370#endif
 371        if (info->xmit.head == info->xmit.tail) {
 372                custom.intena = IF_TBE;
 373                mb();
 374                info->IER &= ~UART_IER_THRI;
 375        }
 376}
 377
 378static void check_modem_status(struct serial_state *info)
 379{
 380        struct tty_port *port = &info->tport;
 381        unsigned char status = ciab.pra & (SER_DCD | SER_CTS | SER_DSR);
 382        unsigned char dstatus;
 383        struct  async_icount *icount;
 384
 385        /* Determine bits that have changed */
 386        dstatus = status ^ current_ctl_bits;
 387        current_ctl_bits = status;
 388
 389        if (dstatus) {
 390                icount = &info->icount;
 391                /* update input line counters */
 392                if (dstatus & SER_DSR)
 393                        icount->dsr++;
 394                if (dstatus & SER_DCD) {
 395                        icount->dcd++;
 396                }
 397                if (dstatus & SER_CTS)
 398                        icount->cts++;
 399                wake_up_interruptible(&port->delta_msr_wait);
 400        }
 401
 402        if ((port->flags & ASYNC_CHECK_CD) && (dstatus & SER_DCD)) {
 403#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
 404                printk("ttyS%d CD now %s...", info->line,
 405                       (!(status & SER_DCD)) ? "on" : "off");
 406#endif
 407                if (!(status & SER_DCD))
 408                        wake_up_interruptible(&port->open_wait);
 409                else {
 410#ifdef SERIAL_DEBUG_OPEN
 411                        printk("doing serial hangup...");
 412#endif
 413                        if (port->tty)
 414                                tty_hangup(port->tty);
 415                }
 416        }
 417        if (tty_port_cts_enabled(port)) {
 418                if (port->tty->hw_stopped) {
 419                        if (!(status & SER_CTS)) {
 420#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
 421                                printk("CTS tx start...");
 422#endif
 423                                port->tty->hw_stopped = 0;
 424                                info->IER |= UART_IER_THRI;
 425                                custom.intena = IF_SETCLR | IF_TBE;
 426                                mb();
 427                                /* set a pending Tx Interrupt, transmitter should restart now */
 428                                custom.intreq = IF_SETCLR | IF_TBE;
 429                                mb();
 430                                tty_wakeup(port->tty);
 431                                return;
 432                        }
 433                } else {
 434                        if ((status & SER_CTS)) {
 435#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
 436                                printk("CTS tx stop...");
 437#endif
 438                                port->tty->hw_stopped = 1;
 439                                info->IER &= ~UART_IER_THRI;
 440                                /* disable Tx interrupt and remove any pending interrupts */
 441                                custom.intena = IF_TBE;
 442                                mb();
 443                                custom.intreq = IF_TBE;
 444                                mb();
 445                        }
 446                }
 447        }
 448}
 449
 450static irqreturn_t ser_vbl_int( int irq, void *data)
 451{
 452        /* vbl is just a periodic interrupt we tie into to update modem status */
 453        struct serial_state *info = data;
 454        /*
 455         * TBD - is it better to unregister from this interrupt or to
 456         * ignore it if MSI is clear ?
 457         */
 458        if(info->IER & UART_IER_MSI)
 459          check_modem_status(info);
 460        return IRQ_HANDLED;
 461}
 462
 463static irqreturn_t ser_rx_int(int irq, void *dev_id)
 464{
 465        struct serial_state *info = dev_id;
 466
 467#ifdef SERIAL_DEBUG_INTR
 468        printk("ser_rx_int...");
 469#endif
 470
 471        if (!info->tport.tty)
 472                return IRQ_NONE;
 473
 474        receive_chars(info);
 475#ifdef SERIAL_DEBUG_INTR
 476        printk("end.\n");
 477#endif
 478        return IRQ_HANDLED;
 479}
 480
 481static irqreturn_t ser_tx_int(int irq, void *dev_id)
 482{
 483        struct serial_state *info = dev_id;
 484
 485        if (custom.serdatr & SDR_TBE) {
 486#ifdef SERIAL_DEBUG_INTR
 487          printk("ser_tx_int...");
 488#endif
 489
 490          if (!info->tport.tty)
 491                return IRQ_NONE;
 492
 493          transmit_chars(info);
 494#ifdef SERIAL_DEBUG_INTR
 495          printk("end.\n");
 496#endif
 497        }
 498        return IRQ_HANDLED;
 499}
 500
 501/*
 502 * -------------------------------------------------------------------
 503 * Here ends the serial interrupt routines.
 504 * -------------------------------------------------------------------
 505 */
 506
 507/*
 508 * ---------------------------------------------------------------
 509 * Low level utility subroutines for the serial driver:  routines to
 510 * figure out the appropriate timeout for an interrupt chain, routines
 511 * to initialize and startup a serial port, and routines to shutdown a
 512 * serial port.  Useful stuff like that.
 513 * ---------------------------------------------------------------
 514 */
 515
 516static int startup(struct tty_struct *tty, struct serial_state *info)
 517{
 518        struct tty_port *port = &info->tport;
 519        unsigned long flags;
 520        int     retval=0;
 521        unsigned long page;
 522
 523        page = get_zeroed_page(GFP_KERNEL);
 524        if (!page)
 525                return -ENOMEM;
 526
 527        local_irq_save(flags);
 528
 529        if (port->flags & ASYNC_INITIALIZED) {
 530                free_page(page);
 531                goto errout;
 532        }
 533
 534        if (info->xmit.buf)
 535                free_page(page);
 536        else
 537                info->xmit.buf = (unsigned char *) page;
 538
 539#ifdef SERIAL_DEBUG_OPEN
 540        printk("starting up ttys%d ...", info->line);
 541#endif
 542
 543        /* Clear anything in the input buffer */
 544
 545        custom.intreq = IF_RBF;
 546        mb();
 547
 548        retval = request_irq(IRQ_AMIGA_VERTB, ser_vbl_int, 0, "serial status", info);
 549        if (retval) {
 550          if (serial_isroot()) {
 551              set_bit(TTY_IO_ERROR, &tty->flags);
 552            retval = 0;
 553          }
 554          goto errout;
 555        }
 556
 557        /* enable both Rx and Tx interrupts */
 558        custom.intena = IF_SETCLR | IF_RBF | IF_TBE;
 559        mb();
 560        info->IER = UART_IER_MSI;
 561
 562        /* remember current state of the DCD and CTS bits */
 563        current_ctl_bits = ciab.pra & (SER_DCD | SER_CTS | SER_DSR);
 564
 565        info->MCR = 0;
 566        if (C_BAUD(tty))
 567          info->MCR = SER_DTR | SER_RTS;
 568        rtsdtr_ctrl(info->MCR);
 569
 570        clear_bit(TTY_IO_ERROR, &tty->flags);
 571        info->xmit.head = info->xmit.tail = 0;
 572
 573        /*
 574         * Set up the tty->alt_speed kludge
 575         */
 576        if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
 577                tty->alt_speed = 57600;
 578        if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
 579                tty->alt_speed = 115200;
 580        if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
 581                tty->alt_speed = 230400;
 582        if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
 583                tty->alt_speed = 460800;
 584
 585        /*
 586         * and set the speed of the serial port
 587         */
 588        change_speed(tty, info, NULL);
 589
 590        port->flags |= ASYNC_INITIALIZED;
 591        local_irq_restore(flags);
 592        return 0;
 593
 594errout:
 595        local_irq_restore(flags);
 596        return retval;
 597}
 598
 599/*
 600 * This routine will shutdown a serial port; interrupts are disabled, and
 601 * DTR is dropped if the hangup on close termio flag is on.
 602 */
 603static void shutdown(struct tty_struct *tty, struct serial_state *info)
 604{
 605        unsigned long   flags;
 606        struct serial_state *state;
 607
 608        if (!(info->tport.flags & ASYNC_INITIALIZED))
 609                return;
 610
 611        state = info;
 612
 613#ifdef SERIAL_DEBUG_OPEN
 614        printk("Shutting down serial port %d ....\n", info->line);
 615#endif
 616
 617        local_irq_save(flags); /* Disable interrupts */
 618
 619        /*
 620         * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
 621         * here so the queue might never be waken up
 622         */
 623        wake_up_interruptible(&info->tport.delta_msr_wait);
 624
 625        /*
 626         * Free the IRQ, if necessary
 627         */
 628        free_irq(IRQ_AMIGA_VERTB, info);
 629
 630        if (info->xmit.buf) {
 631                free_page((unsigned long) info->xmit.buf);
 632                info->xmit.buf = NULL;
 633        }
 634
 635        info->IER = 0;
 636        custom.intena = IF_RBF | IF_TBE;
 637        mb();
 638
 639        /* disable break condition */
 640        custom.adkcon = AC_UARTBRK;
 641        mb();
 642
 643        if (tty->termios.c_cflag & HUPCL)
 644                info->MCR &= ~(SER_DTR|SER_RTS);
 645        rtsdtr_ctrl(info->MCR);
 646
 647        set_bit(TTY_IO_ERROR, &tty->flags);
 648
 649        info->tport.flags &= ~ASYNC_INITIALIZED;
 650        local_irq_restore(flags);
 651}
 652
 653
 654/*
 655 * This routine is called to set the UART divisor registers to match
 656 * the specified baud rate for a serial port.
 657 */
 658static void change_speed(struct tty_struct *tty, struct serial_state *info,
 659                         struct ktermios *old_termios)
 660{
 661        struct tty_port *port = &info->tport;
 662        int     quot = 0, baud_base, baud;
 663        unsigned cflag, cval = 0;
 664        int     bits;
 665        unsigned long   flags;
 666
 667        cflag = tty->termios.c_cflag;
 668
 669        /* Byte size is always 8 bits plus parity bit if requested */
 670
 671        cval = 3; bits = 10;
 672        if (cflag & CSTOPB) {
 673                cval |= 0x04;
 674                bits++;
 675        }
 676        if (cflag & PARENB) {
 677                cval |= UART_LCR_PARITY;
 678                bits++;
 679        }
 680        if (!(cflag & PARODD))
 681                cval |= UART_LCR_EPAR;
 682#ifdef CMSPAR
 683        if (cflag & CMSPAR)
 684                cval |= UART_LCR_SPAR;
 685#endif
 686
 687        /* Determine divisor based on baud rate */
 688        baud = tty_get_baud_rate(tty);
 689        if (!baud)
 690                baud = 9600;    /* B0 transition handled in rs_set_termios */
 691        baud_base = info->baud_base;
 692        if (baud == 38400 && (port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
 693                quot = info->custom_divisor;
 694        else {
 695                if (baud == 134)
 696                        /* Special case since 134 is really 134.5 */
 697                        quot = (2*baud_base / 269);
 698                else if (baud)
 699                        quot = baud_base / baud;
 700        }
 701        /* If the quotient is zero refuse the change */
 702        if (!quot && old_termios) {
 703                /* FIXME: Will need updating for new tty in the end */
 704                tty->termios.c_cflag &= ~CBAUD;
 705                tty->termios.c_cflag |= (old_termios->c_cflag & CBAUD);
 706                baud = tty_get_baud_rate(tty);
 707                if (!baud)
 708                        baud = 9600;
 709                if (baud == 38400 &&
 710                    (port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
 711                        quot = info->custom_divisor;
 712                else {
 713                        if (baud == 134)
 714                                /* Special case since 134 is really 134.5 */
 715                                quot = (2*baud_base / 269);
 716                        else if (baud)
 717                                quot = baud_base / baud;
 718                }
 719        }
 720        /* As a last resort, if the quotient is zero, default to 9600 bps */
 721        if (!quot)
 722                quot = baud_base / 9600;
 723        info->quot = quot;
 724        info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
 725        info->timeout += HZ/50;         /* Add .02 seconds of slop */
 726
 727        /* CTS flow control flag and modem status interrupts */
 728        info->IER &= ~UART_IER_MSI;
 729        if (port->flags & ASYNC_HARDPPS_CD)
 730                info->IER |= UART_IER_MSI;
 731        if (cflag & CRTSCTS) {
 732                port->flags |= ASYNC_CTS_FLOW;
 733                info->IER |= UART_IER_MSI;
 734        } else
 735                port->flags &= ~ASYNC_CTS_FLOW;
 736        if (cflag & CLOCAL)
 737                port->flags &= ~ASYNC_CHECK_CD;
 738        else {
 739                port->flags |= ASYNC_CHECK_CD;
 740                info->IER |= UART_IER_MSI;
 741        }
 742        /* TBD:
 743         * Does clearing IER_MSI imply that we should disable the VBL interrupt ?
 744         */
 745
 746        /*
 747         * Set up parity check flag
 748         */
 749
 750        info->read_status_mask = UART_LSR_OE | UART_LSR_DR;
 751        if (I_INPCK(tty))
 752                info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
 753        if (I_BRKINT(tty) || I_PARMRK(tty))
 754                info->read_status_mask |= UART_LSR_BI;
 755
 756        /*
 757         * Characters to ignore
 758         */
 759        info->ignore_status_mask = 0;
 760        if (I_IGNPAR(tty))
 761                info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
 762        if (I_IGNBRK(tty)) {
 763                info->ignore_status_mask |= UART_LSR_BI;
 764                /*
 765                 * If we're ignore parity and break indicators, ignore 
 766                 * overruns too.  (For real raw support).
 767                 */
 768                if (I_IGNPAR(tty))
 769                        info->ignore_status_mask |= UART_LSR_OE;
 770        }
 771        /*
 772         * !!! ignore all characters if CREAD is not set
 773         */
 774        if ((cflag & CREAD) == 0)
 775                info->ignore_status_mask |= UART_LSR_DR;
 776        local_irq_save(flags);
 777
 778        {
 779          short serper;
 780
 781        /* Set up the baud rate */
 782          serper = quot - 1;
 783
 784        /* Enable or disable parity bit */
 785
 786        if(cval & UART_LCR_PARITY)
 787          serper |= (SERPER_PARENB);
 788
 789        custom.serper = serper;
 790        mb();
 791        }
 792
 793        local_irq_restore(flags);
 794}
 795
 796static int rs_put_char(struct tty_struct *tty, unsigned char ch)
 797{
 798        struct serial_state *info;
 799        unsigned long flags;
 800
 801        info = tty->driver_data;
 802
 803        if (serial_paranoia_check(info, tty->name, "rs_put_char"))
 804                return 0;
 805
 806        if (!info->xmit.buf)
 807                return 0;
 808
 809        local_irq_save(flags);
 810        if (CIRC_SPACE(info->xmit.head,
 811                       info->xmit.tail,
 812                       SERIAL_XMIT_SIZE) == 0) {
 813                local_irq_restore(flags);
 814                return 0;
 815        }
 816
 817        info->xmit.buf[info->xmit.head++] = ch;
 818        info->xmit.head &= SERIAL_XMIT_SIZE-1;
 819        local_irq_restore(flags);
 820        return 1;
 821}
 822
 823static void rs_flush_chars(struct tty_struct *tty)
 824{
 825        struct serial_state *info = tty->driver_data;
 826        unsigned long flags;
 827
 828        if (serial_paranoia_check(info, tty->name, "rs_flush_chars"))
 829                return;
 830
 831        if (info->xmit.head == info->xmit.tail
 832            || tty->stopped
 833            || tty->hw_stopped
 834            || !info->xmit.buf)
 835                return;
 836
 837        local_irq_save(flags);
 838        info->IER |= UART_IER_THRI;
 839        custom.intena = IF_SETCLR | IF_TBE;
 840        mb();
 841        /* set a pending Tx Interrupt, transmitter should restart now */
 842        custom.intreq = IF_SETCLR | IF_TBE;
 843        mb();
 844        local_irq_restore(flags);
 845}
 846
 847static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count)
 848{
 849        int     c, ret = 0;
 850        struct serial_state *info = tty->driver_data;
 851        unsigned long flags;
 852
 853        if (serial_paranoia_check(info, tty->name, "rs_write"))
 854                return 0;
 855
 856        if (!info->xmit.buf)
 857                return 0;
 858
 859        local_irq_save(flags);
 860        while (1) {
 861                c = CIRC_SPACE_TO_END(info->xmit.head,
 862                                      info->xmit.tail,
 863                                      SERIAL_XMIT_SIZE);
 864                if (count < c)
 865                        c = count;
 866                if (c <= 0) {
 867                        break;
 868                }
 869                memcpy(info->xmit.buf + info->xmit.head, buf, c);
 870                info->xmit.head = ((info->xmit.head + c) &
 871                                   (SERIAL_XMIT_SIZE-1));
 872                buf += c;
 873                count -= c;
 874                ret += c;
 875        }
 876        local_irq_restore(flags);
 877
 878        if (info->xmit.head != info->xmit.tail
 879            && !tty->stopped
 880            && !tty->hw_stopped
 881            && !(info->IER & UART_IER_THRI)) {
 882                info->IER |= UART_IER_THRI;
 883                local_irq_disable();
 884                custom.intena = IF_SETCLR | IF_TBE;
 885                mb();
 886                /* set a pending Tx Interrupt, transmitter should restart now */
 887                custom.intreq = IF_SETCLR | IF_TBE;
 888                mb();
 889                local_irq_restore(flags);
 890        }
 891        return ret;
 892}
 893
 894static int rs_write_room(struct tty_struct *tty)
 895{
 896        struct serial_state *info = tty->driver_data;
 897
 898        if (serial_paranoia_check(info, tty->name, "rs_write_room"))
 899                return 0;
 900        return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
 901}
 902
 903static int rs_chars_in_buffer(struct tty_struct *tty)
 904{
 905        struct serial_state *info = tty->driver_data;
 906
 907        if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer"))
 908                return 0;
 909        return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
 910}
 911
 912static void rs_flush_buffer(struct tty_struct *tty)
 913{
 914        struct serial_state *info = tty->driver_data;
 915        unsigned long flags;
 916
 917        if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
 918                return;
 919        local_irq_save(flags);
 920        info->xmit.head = info->xmit.tail = 0;
 921        local_irq_restore(flags);
 922        tty_wakeup(tty);
 923}
 924
 925/*
 926 * This function is used to send a high-priority XON/XOFF character to
 927 * the device
 928 */
 929static void rs_send_xchar(struct tty_struct *tty, char ch)
 930{
 931        struct serial_state *info = tty->driver_data;
 932        unsigned long flags;
 933
 934        if (serial_paranoia_check(info, tty->name, "rs_send_char"))
 935                return;
 936
 937        info->x_char = ch;
 938        if (ch) {
 939                /* Make sure transmit interrupts are on */
 940
 941                /* Check this ! */
 942                local_irq_save(flags);
 943                if(!(custom.intenar & IF_TBE)) {
 944                    custom.intena = IF_SETCLR | IF_TBE;
 945                    mb();
 946                    /* set a pending Tx Interrupt, transmitter should restart now */
 947                    custom.intreq = IF_SETCLR | IF_TBE;
 948                    mb();
 949                }
 950                local_irq_restore(flags);
 951
 952                info->IER |= UART_IER_THRI;
 953        }
 954}
 955
 956/*
 957 * ------------------------------------------------------------
 958 * rs_throttle()
 959 * 
 960 * This routine is called by the upper-layer tty layer to signal that
 961 * incoming characters should be throttled.
 962 * ------------------------------------------------------------
 963 */
 964static void rs_throttle(struct tty_struct * tty)
 965{
 966        struct serial_state *info = tty->driver_data;
 967        unsigned long flags;
 968#ifdef SERIAL_DEBUG_THROTTLE
 969        char    buf[64];
 970
 971        printk("throttle %s: %d....\n", tty_name(tty, buf),
 972               tty->ldisc.chars_in_buffer(tty));
 973#endif
 974
 975        if (serial_paranoia_check(info, tty->name, "rs_throttle"))
 976                return;
 977
 978        if (I_IXOFF(tty))
 979                rs_send_xchar(tty, STOP_CHAR(tty));
 980
 981        if (tty->termios.c_cflag & CRTSCTS)
 982                info->MCR &= ~SER_RTS;
 983
 984        local_irq_save(flags);
 985        rtsdtr_ctrl(info->MCR);
 986        local_irq_restore(flags);
 987}
 988
 989static void rs_unthrottle(struct tty_struct * tty)
 990{
 991        struct serial_state *info = tty->driver_data;
 992        unsigned long flags;
 993#ifdef SERIAL_DEBUG_THROTTLE
 994        char    buf[64];
 995
 996        printk("unthrottle %s: %d....\n", tty_name(tty, buf),
 997               tty->ldisc.chars_in_buffer(tty));
 998#endif
 999
1000        if (serial_paranoia_check(info, tty->name, "rs_unthrottle"))
1001                return;
1002
1003        if (I_IXOFF(tty)) {
1004                if (info->x_char)
1005                        info->x_char = 0;
1006                else
1007                        rs_send_xchar(tty, START_CHAR(tty));
1008        }
1009        if (tty->termios.c_cflag & CRTSCTS)
1010                info->MCR |= SER_RTS;
1011        local_irq_save(flags);
1012        rtsdtr_ctrl(info->MCR);
1013        local_irq_restore(flags);
1014}
1015
1016/*
1017 * ------------------------------------------------------------
1018 * rs_ioctl() and friends
1019 * ------------------------------------------------------------
1020 */
1021
1022static int get_serial_info(struct tty_struct *tty, struct serial_state *state,
1023                           struct serial_struct __user * retinfo)
1024{
1025        struct serial_struct tmp;
1026   
1027        if (!retinfo)
1028                return -EFAULT;
1029        memset(&tmp, 0, sizeof(tmp));
1030        tty_lock(tty);
1031        tmp.line = tty->index;
1032        tmp.port = state->port;
1033        tmp.flags = state->tport.flags;
1034        tmp.xmit_fifo_size = state->xmit_fifo_size;
1035        tmp.baud_base = state->baud_base;
1036        tmp.close_delay = state->tport.close_delay;
1037        tmp.closing_wait = state->tport.closing_wait;
1038        tmp.custom_divisor = state->custom_divisor;
1039        tty_unlock(tty);
1040        if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
1041                return -EFAULT;
1042        return 0;
1043}
1044
1045static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
1046                           struct serial_struct __user * new_info)
1047{
1048        struct tty_port *port = &state->tport;
1049        struct serial_struct new_serial;
1050        bool change_spd;
1051        int                     retval = 0;
1052
1053        if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
1054                return -EFAULT;
1055
1056        tty_lock(tty);
1057        change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) ||
1058                new_serial.custom_divisor != state->custom_divisor;
1059        if (new_serial.irq || new_serial.port != state->port ||
1060                        new_serial.xmit_fifo_size != state->xmit_fifo_size) {
1061                tty_unlock(tty);
1062                return -EINVAL;
1063        }
1064  
1065        if (!serial_isroot()) {
1066                if ((new_serial.baud_base != state->baud_base) ||
1067                    (new_serial.close_delay != port->close_delay) ||
1068                    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
1069                    ((new_serial.flags & ~ASYNC_USR_MASK) !=
1070                     (port->flags & ~ASYNC_USR_MASK))) {
1071                        tty_unlock(tty);
1072                        return -EPERM;
1073                }
1074                port->flags = ((port->flags & ~ASYNC_USR_MASK) |
1075                               (new_serial.flags & ASYNC_USR_MASK));
1076                state->custom_divisor = new_serial.custom_divisor;
1077                goto check_and_exit;
1078        }
1079
1080        if (new_serial.baud_base < 9600) {
1081                tty_unlock(tty);
1082                return -EINVAL;
1083        }
1084
1085        /*
1086         * OK, past this point, all the error checking has been done.
1087         * At this point, we start making changes.....
1088         */
1089
1090        state->baud_base = new_serial.baud_base;
1091        port->flags = ((port->flags & ~ASYNC_FLAGS) |
1092                        (new_serial.flags & ASYNC_FLAGS));
1093        state->custom_divisor = new_serial.custom_divisor;
1094        port->close_delay = new_serial.close_delay * HZ/100;
1095        port->closing_wait = new_serial.closing_wait * HZ/100;
1096        port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1097
1098check_and_exit:
1099        if (port->flags & ASYNC_INITIALIZED) {
1100                if (change_spd) {
1101                        if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1102                                tty->alt_speed = 57600;
1103                        if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1104                                tty->alt_speed = 115200;
1105                        if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
1106                                tty->alt_speed = 230400;
1107                        if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
1108                                tty->alt_speed = 460800;
1109                        change_speed(tty, state, NULL);
1110                }
1111        } else
1112                retval = startup(tty, state);
1113        tty_unlock(tty);
1114        return retval;
1115}
1116
1117
1118/*
1119 * get_lsr_info - get line status register info
1120 *
1121 * Purpose: Let user call ioctl() to get info when the UART physically
1122 *          is emptied.  On bus types like RS485, the transmitter must
1123 *          release the bus after transmitting. This must be done when
1124 *          the transmit shift register is empty, not be done when the
1125 *          transmit holding register is empty.  This functionality
1126 *          allows an RS485 driver to be written in user space. 
1127 */
1128static int get_lsr_info(struct serial_state *info, unsigned int __user *value)
1129{
1130        unsigned char status;
1131        unsigned int result;
1132        unsigned long flags;
1133
1134        local_irq_save(flags);
1135        status = custom.serdatr;
1136        mb();
1137        local_irq_restore(flags);
1138        result = ((status & SDR_TSRE) ? TIOCSER_TEMT : 0);
1139        if (copy_to_user(value, &result, sizeof(int)))
1140                return -EFAULT;
1141        return 0;
1142}
1143
1144
1145static int rs_tiocmget(struct tty_struct *tty)
1146{
1147        struct serial_state *info = tty->driver_data;
1148        unsigned char control, status;
1149        unsigned long flags;
1150
1151        if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
1152                return -ENODEV;
1153        if (tty->flags & (1 << TTY_IO_ERROR))
1154                return -EIO;
1155
1156        control = info->MCR;
1157        local_irq_save(flags);
1158        status = ciab.pra;
1159        local_irq_restore(flags);
1160        return    ((control & SER_RTS) ? TIOCM_RTS : 0)
1161                | ((control & SER_DTR) ? TIOCM_DTR : 0)
1162                | (!(status  & SER_DCD) ? TIOCM_CAR : 0)
1163                | (!(status  & SER_DSR) ? TIOCM_DSR : 0)
1164                | (!(status  & SER_CTS) ? TIOCM_CTS : 0);
1165}
1166
1167static int rs_tiocmset(struct tty_struct *tty, unsigned int set,
1168                                                unsigned int clear)
1169{
1170        struct serial_state *info = tty->driver_data;
1171        unsigned long flags;
1172
1173        if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
1174                return -ENODEV;
1175        if (tty->flags & (1 << TTY_IO_ERROR))
1176                return -EIO;
1177
1178        local_irq_save(flags);
1179        if (set & TIOCM_RTS)
1180                info->MCR |= SER_RTS;
1181        if (set & TIOCM_DTR)
1182                info->MCR |= SER_DTR;
1183        if (clear & TIOCM_RTS)
1184                info->MCR &= ~SER_RTS;
1185        if (clear & TIOCM_DTR)
1186                info->MCR &= ~SER_DTR;
1187        rtsdtr_ctrl(info->MCR);
1188        local_irq_restore(flags);
1189        return 0;
1190}
1191
1192/*
1193 * rs_break() --- routine which turns the break handling on or off
1194 */
1195static int rs_break(struct tty_struct *tty, int break_state)
1196{
1197        struct serial_state *info = tty->driver_data;
1198        unsigned long flags;
1199
1200        if (serial_paranoia_check(info, tty->name, "rs_break"))
1201                return -EINVAL;
1202
1203        local_irq_save(flags);
1204        if (break_state == -1)
1205          custom.adkcon = AC_SETCLR | AC_UARTBRK;
1206        else
1207          custom.adkcon = AC_UARTBRK;
1208        mb();
1209        local_irq_restore(flags);
1210        return 0;
1211}
1212
1213/*
1214 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
1215 * Return: write counters to the user passed counter struct
1216 * NB: both 1->0 and 0->1 transitions are counted except for
1217 *     RI where only 0->1 is counted.
1218 */
1219static int rs_get_icount(struct tty_struct *tty,
1220                                struct serial_icounter_struct *icount)
1221{
1222        struct serial_state *info = tty->driver_data;
1223        struct async_icount cnow;
1224        unsigned long flags;
1225
1226        local_irq_save(flags);
1227        cnow = info->icount;
1228        local_irq_restore(flags);
1229        icount->cts = cnow.cts;
1230        icount->dsr = cnow.dsr;
1231        icount->rng = cnow.rng;
1232        icount->dcd = cnow.dcd;
1233        icount->rx = cnow.rx;
1234        icount->tx = cnow.tx;
1235        icount->frame = cnow.frame;
1236        icount->overrun = cnow.overrun;
1237        icount->parity = cnow.parity;
1238        icount->brk = cnow.brk;
1239        icount->buf_overrun = cnow.buf_overrun;
1240
1241        return 0;
1242}
1243
1244static int rs_ioctl(struct tty_struct *tty,
1245                    unsigned int cmd, unsigned long arg)
1246{
1247        struct serial_state *info = tty->driver_data;
1248        struct async_icount cprev, cnow;        /* kernel counter temps */
1249        void __user *argp = (void __user *)arg;
1250        unsigned long flags;
1251
1252        if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
1253                return -ENODEV;
1254
1255        if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
1256            (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
1257            (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
1258                if (tty->flags & (1 << TTY_IO_ERROR))
1259                    return -EIO;
1260        }
1261
1262        switch (cmd) {
1263                case TIOCGSERIAL:
1264                        return get_serial_info(tty, info, argp);
1265                case TIOCSSERIAL:
1266                        return set_serial_info(tty, info, argp);
1267                case TIOCSERCONFIG:
1268                        return 0;
1269
1270                case TIOCSERGETLSR: /* Get line status register */
1271                        return get_lsr_info(info, argp);
1272
1273                case TIOCSERGSTRUCT:
1274                        if (copy_to_user(argp,
1275                                         info, sizeof(struct serial_state)))
1276                                return -EFAULT;
1277                        return 0;
1278
1279                /*
1280                 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
1281                 * - mask passed in arg for lines of interest
1282                 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
1283                 * Caller should use TIOCGICOUNT to see which one it was
1284                 */
1285                case TIOCMIWAIT:
1286                        local_irq_save(flags);
1287                        /* note the counters on entry */
1288                        cprev = info->icount;
1289                        local_irq_restore(flags);
1290                        while (1) {
1291                                interruptible_sleep_on(&info->tport.delta_msr_wait);
1292                                /* see if a signal did it */
1293                                if (signal_pending(current))
1294                                        return -ERESTARTSYS;
1295                                local_irq_save(flags);
1296                                cnow = info->icount; /* atomic copy */
1297                                local_irq_restore(flags);
1298                                if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
1299                                    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
1300                                        return -EIO; /* no change => error */
1301                                if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
1302                                     ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
1303                                     ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
1304                                     ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
1305                                        return 0;
1306                                }
1307                                cprev = cnow;
1308                        }
1309                        /* NOTREACHED */
1310
1311                case TIOCSERGWILD:
1312                case TIOCSERSWILD:
1313                        /* "setserial -W" is called in Debian boot */
1314                        printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
1315                        return 0;
1316
1317                default:
1318                        return -ENOIOCTLCMD;
1319                }
1320        return 0;
1321}
1322
1323static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
1324{
1325        struct serial_state *info = tty->driver_data;
1326        unsigned long flags;
1327        unsigned int cflag = tty->termios.c_cflag;
1328
1329        change_speed(tty, info, old_termios);
1330
1331        /* Handle transition to B0 status */
1332        if ((old_termios->c_cflag & CBAUD) &&
1333            !(cflag & CBAUD)) {
1334                info->MCR &= ~(SER_DTR|SER_RTS);
1335                local_irq_save(flags);
1336                rtsdtr_ctrl(info->MCR);
1337                local_irq_restore(flags);
1338        }
1339
1340        /* Handle transition away from B0 status */
1341        if (!(old_termios->c_cflag & CBAUD) &&
1342            (cflag & CBAUD)) {
1343                info->MCR |= SER_DTR;
1344                if (!(tty->termios.c_cflag & CRTSCTS) || 
1345                    !test_bit(TTY_THROTTLED, &tty->flags)) {
1346                        info->MCR |= SER_RTS;
1347                }
1348                local_irq_save(flags);
1349                rtsdtr_ctrl(info->MCR);
1350                local_irq_restore(flags);
1351        }
1352
1353        /* Handle turning off CRTSCTS */
1354        if ((old_termios->c_cflag & CRTSCTS) &&
1355            !(tty->termios.c_cflag & CRTSCTS)) {
1356                tty->hw_stopped = 0;
1357                rs_start(tty);
1358        }
1359
1360#if 0
1361        /*
1362         * No need to wake up processes in open wait, since they
1363         * sample the CLOCAL flag once, and don't recheck it.
1364         * XXX  It's not clear whether the current behavior is correct
1365         * or not.  Hence, this may change.....
1366         */
1367        if (!(old_termios->c_cflag & CLOCAL) &&
1368            (tty->termios.c_cflag & CLOCAL))
1369                wake_up_interruptible(&info->open_wait);
1370#endif
1371}
1372
1373/*
1374 * ------------------------------------------------------------
1375 * rs_close()
1376 * 
1377 * This routine is called when the serial port gets closed.  First, we
1378 * wait for the last remaining data to be sent.  Then, we unlink its
1379 * async structure from the interrupt chain if necessary, and we free
1380 * that IRQ if nothing is left in the chain.
1381 * ------------------------------------------------------------
1382 */
1383static void rs_close(struct tty_struct *tty, struct file * filp)
1384{
1385        struct serial_state *state = tty->driver_data;
1386        struct tty_port *port = &state->tport;
1387
1388        if (serial_paranoia_check(state, tty->name, "rs_close"))
1389                return;
1390
1391        if (tty_port_close_start(port, tty, filp) == 0)
1392                return;
1393
1394        /*
1395         * At this point we stop accepting input.  To do this, we
1396         * disable the receive line status interrupts, and tell the
1397         * interrupt driver to stop checking the data ready bit in the
1398         * line status register.
1399         */
1400        state->read_status_mask &= ~UART_LSR_DR;
1401        if (port->flags & ASYNC_INITIALIZED) {
1402                /* disable receive interrupts */
1403                custom.intena = IF_RBF;
1404                mb();
1405                /* clear any pending receive interrupt */
1406                custom.intreq = IF_RBF;
1407                mb();
1408
1409                /*
1410                 * Before we drop DTR, make sure the UART transmitter
1411                 * has completely drained; this is especially
1412                 * important if there is a transmit FIFO!
1413                 */
1414                rs_wait_until_sent(tty, state->timeout);
1415        }
1416        shutdown(tty, state);
1417        rs_flush_buffer(tty);
1418                
1419        tty_ldisc_flush(tty);
1420        port->tty = NULL;
1421
1422        tty_port_close_end(port, tty);
1423}
1424
1425/*
1426 * rs_wait_until_sent() --- wait until the transmitter is empty
1427 */
1428static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
1429{
1430        struct serial_state *info = tty->driver_data;
1431        unsigned long orig_jiffies, char_time;
1432        int lsr;
1433
1434        if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
1435                return;
1436
1437        if (info->xmit_fifo_size == 0)
1438                return; /* Just in case.... */
1439
1440        orig_jiffies = jiffies;
1441
1442        /*
1443         * Set the check interval to be 1/5 of the estimated time to
1444         * send a single character, and make it at least 1.  The check
1445         * interval should also be less than the timeout.
1446         * 
1447         * Note: we have to use pretty tight timings here to satisfy
1448         * the NIST-PCTS.
1449         */
1450        char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
1451        char_time = char_time / 5;
1452        if (char_time == 0)
1453                char_time = 1;
1454        if (timeout)
1455          char_time = min_t(unsigned long, char_time, timeout);
1456        /*
1457         * If the transmitter hasn't cleared in twice the approximate
1458         * amount of time to send the entire FIFO, it probably won't
1459         * ever clear.  This assumes the UART isn't doing flow
1460         * control, which is currently the case.  Hence, if it ever
1461         * takes longer than info->timeout, this is probably due to a
1462         * UART bug of some kind.  So, we clamp the timeout parameter at
1463         * 2*info->timeout.
1464         */
1465        if (!timeout || timeout > 2*info->timeout)
1466                timeout = 2*info->timeout;
1467#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
1468        printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
1469        printk("jiff=%lu...", jiffies);
1470#endif
1471        while(!((lsr = custom.serdatr) & SDR_TSRE)) {
1472#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
1473                printk("serdatr = %d (jiff=%lu)...", lsr, jiffies);
1474#endif
1475                msleep_interruptible(jiffies_to_msecs(char_time));
1476                if (signal_pending(current))
1477                        break;
1478                if (timeout && time_after(jiffies, orig_jiffies + timeout))
1479                        break;
1480        }
1481        __set_current_state(TASK_RUNNING);
1482
1483#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
1484        printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
1485#endif
1486}
1487
1488/*
1489 * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
1490 */
1491static void rs_hangup(struct tty_struct *tty)
1492{
1493        struct serial_state *info = tty->driver_data;
1494
1495        if (serial_paranoia_check(info, tty->name, "rs_hangup"))
1496                return;
1497
1498        rs_flush_buffer(tty);
1499        shutdown(tty, info);
1500        info->tport.count = 0;
1501        info->tport.flags &= ~ASYNC_NORMAL_ACTIVE;
1502        info->tport.tty = NULL;
1503        wake_up_interruptible(&info->tport.open_wait);
1504}
1505
1506/*
1507 * This routine is called whenever a serial port is opened.  It
1508 * enables interrupts for a serial port, linking in its async structure into
1509 * the IRQ chain.   It also performs the serial-specific
1510 * initialization for the tty structure.
1511 */
1512static int rs_open(struct tty_struct *tty, struct file * filp)
1513{
1514        struct serial_state *info = rs_table + tty->index;
1515        struct tty_port *port = &info->tport;
1516        int retval;
1517
1518        port->count++;
1519        port->tty = tty;
1520        tty->driver_data = info;
1521        tty->port = port;
1522        if (serial_paranoia_check(info, tty->name, "rs_open"))
1523                return -ENODEV;
1524
1525        port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1526
1527        retval = startup(tty, info);
1528        if (retval) {
1529                return retval;
1530        }
1531
1532        return tty_port_block_til_ready(port, tty, filp);
1533}
1534
1535/*
1536 * /proc fs routines....
1537 */
1538
1539static inline void line_info(struct seq_file *m, int line,
1540                struct serial_state *state)
1541{
1542        char    stat_buf[30], control, status;
1543        unsigned long flags;
1544
1545        seq_printf(m, "%d: uart:amiga_builtin", line);
1546
1547        local_irq_save(flags);
1548        status = ciab.pra;
1549        control = (state->tport.flags & ASYNC_INITIALIZED) ? state->MCR : status;
1550        local_irq_restore(flags);
1551
1552        stat_buf[0] = 0;
1553        stat_buf[1] = 0;
1554        if(!(control & SER_RTS))
1555                strcat(stat_buf, "|RTS");
1556        if(!(status & SER_CTS))
1557                strcat(stat_buf, "|CTS");
1558        if(!(control & SER_DTR))
1559                strcat(stat_buf, "|DTR");
1560        if(!(status & SER_DSR))
1561                strcat(stat_buf, "|DSR");
1562        if(!(status & SER_DCD))
1563                strcat(stat_buf, "|CD");
1564
1565        if (state->quot)
1566                seq_printf(m, " baud:%d", state->baud_base / state->quot);
1567
1568        seq_printf(m, " tx:%d rx:%d", state->icount.tx, state->icount.rx);
1569
1570        if (state->icount.frame)
1571                seq_printf(m, " fe:%d", state->icount.frame);
1572
1573        if (state->icount.parity)
1574                seq_printf(m, " pe:%d", state->icount.parity);
1575
1576        if (state->icount.brk)
1577                seq_printf(m, " brk:%d", state->icount.brk);
1578
1579        if (state->icount.overrun)
1580                seq_printf(m, " oe:%d", state->icount.overrun);
1581
1582        /*
1583         * Last thing is the RS-232 status lines
1584         */
1585        seq_printf(m, " %s\n", stat_buf+1);
1586}
1587
1588static int rs_proc_show(struct seq_file *m, void *v)
1589{
1590        seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version);
1591        line_info(m, 0, &rs_table[0]);
1592        return 0;
1593}
1594
1595static int rs_proc_open(struct inode *inode, struct file *file)
1596{
1597        return single_open(file, rs_proc_show, NULL);
1598}
1599
1600static const struct file_operations rs_proc_fops = {
1601        .owner          = THIS_MODULE,
1602        .open           = rs_proc_open,
1603        .read           = seq_read,
1604        .llseek         = seq_lseek,
1605        .release        = single_release,
1606};
1607
1608/*
1609 * ---------------------------------------------------------------------
1610 * rs_init() and friends
1611 *
1612 * rs_init() is called at boot-time to initialize the serial driver.
1613 * ---------------------------------------------------------------------
1614 */
1615
1616/*
1617 * This routine prints out the appropriate serial driver version
1618 * number, and identifies which options were configured into this
1619 * driver.
1620 */
1621static void show_serial_version(void)
1622{
1623        printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
1624}
1625
1626
1627static const struct tty_operations serial_ops = {
1628        .open = rs_open,
1629        .close = rs_close,
1630        .write = rs_write,
1631        .put_char = rs_put_char,
1632        .flush_chars = rs_flush_chars,
1633        .write_room = rs_write_room,
1634        .chars_in_buffer = rs_chars_in_buffer,
1635        .flush_buffer = rs_flush_buffer,
1636        .ioctl = rs_ioctl,
1637        .throttle = rs_throttle,
1638        .unthrottle = rs_unthrottle,
1639        .set_termios = rs_set_termios,
1640        .stop = rs_stop,
1641        .start = rs_start,
1642        .hangup = rs_hangup,
1643        .break_ctl = rs_break,
1644        .send_xchar = rs_send_xchar,
1645        .wait_until_sent = rs_wait_until_sent,
1646        .tiocmget = rs_tiocmget,
1647        .tiocmset = rs_tiocmset,
1648        .get_icount = rs_get_icount,
1649        .proc_fops = &rs_proc_fops,
1650};
1651
1652static int amiga_carrier_raised(struct tty_port *port)
1653{
1654        return !(ciab.pra & SER_DCD);
1655}
1656
1657static void amiga_dtr_rts(struct tty_port *port, int raise)
1658{
1659        struct serial_state *info = container_of(port, struct serial_state,
1660                        tport);
1661        unsigned long flags;
1662
1663        if (raise)
1664                info->MCR |= SER_DTR|SER_RTS;
1665        else
1666                info->MCR &= ~(SER_DTR|SER_RTS);
1667
1668        local_irq_save(flags);
1669        rtsdtr_ctrl(info->MCR);
1670        local_irq_restore(flags);
1671}
1672
1673static const struct tty_port_operations amiga_port_ops = {
1674        .carrier_raised = amiga_carrier_raised,
1675        .dtr_rts = amiga_dtr_rts,
1676};
1677
1678/*
1679 * The serial driver boot-time initialization code!
1680 */
1681static int __init amiga_serial_probe(struct platform_device *pdev)
1682{
1683        unsigned long flags;
1684        struct serial_state * state;
1685        int error;
1686
1687        serial_driver = alloc_tty_driver(NR_PORTS);
1688        if (!serial_driver)
1689                return -ENOMEM;
1690
1691        show_serial_version();
1692
1693        /* Initialize the tty_driver structure */
1694
1695        serial_driver->driver_name = "amiserial";
1696        serial_driver->name = "ttyS";
1697        serial_driver->major = TTY_MAJOR;
1698        serial_driver->minor_start = 64;
1699        serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
1700        serial_driver->subtype = SERIAL_TYPE_NORMAL;
1701        serial_driver->init_termios = tty_std_termios;
1702        serial_driver->init_termios.c_cflag =
1703                B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1704        serial_driver->flags = TTY_DRIVER_REAL_RAW;
1705        tty_set_operations(serial_driver, &serial_ops);
1706
1707        state = rs_table;
1708        state->port = (int)&custom.serdatr; /* Just to give it a value */
1709        state->custom_divisor = 0;
1710        state->icount.cts = state->icount.dsr = 
1711          state->icount.rng = state->icount.dcd = 0;
1712        state->icount.rx = state->icount.tx = 0;
1713        state->icount.frame = state->icount.parity = 0;
1714        state->icount.overrun = state->icount.brk = 0;
1715        tty_port_init(&state->tport);
1716        state->tport.ops = &amiga_port_ops;
1717        tty_port_link_device(&state->tport, serial_driver, 0);
1718
1719        error = tty_register_driver(serial_driver);
1720        if (error)
1721                goto fail_put_tty_driver;
1722
1723        printk(KERN_INFO "ttyS0 is the amiga builtin serial port\n");
1724
1725        /* Hardware set up */
1726
1727        state->baud_base = amiga_colorclock;
1728        state->xmit_fifo_size = 1;
1729
1730        /* set ISRs, and then disable the rx interrupts */
1731        error = request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state);
1732        if (error)
1733                goto fail_unregister;
1734
1735        error = request_irq(IRQ_AMIGA_RBF, ser_rx_int, 0,
1736                            "serial RX", state);
1737        if (error)
1738                goto fail_free_irq;
1739
1740        local_irq_save(flags);
1741
1742        /* turn off Rx and Tx interrupts */
1743        custom.intena = IF_RBF | IF_TBE;
1744        mb();
1745
1746        /* clear any pending interrupt */
1747        custom.intreq = IF_RBF | IF_TBE;
1748        mb();
1749
1750        local_irq_restore(flags);
1751
1752        /*
1753         * set the appropriate directions for the modem control flags,
1754         * and clear RTS and DTR
1755         */
1756        ciab.ddra |= (SER_DTR | SER_RTS);   /* outputs */
1757        ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR);  /* inputs */
1758
1759        platform_set_drvdata(pdev, state);
1760
1761        return 0;
1762
1763fail_free_irq:
1764        free_irq(IRQ_AMIGA_TBE, state);
1765fail_unregister:
1766        tty_unregister_driver(serial_driver);
1767fail_put_tty_driver:
1768        tty_port_destroy(&state->tport);
1769        put_tty_driver(serial_driver);
1770        return error;
1771}
1772
1773static int __exit amiga_serial_remove(struct platform_device *pdev)
1774{
1775        int error;
1776        struct serial_state *state = platform_get_drvdata(pdev);
1777
1778        /* printk("Unloading %s: version %s\n", serial_name, serial_version); */
1779        if ((error = tty_unregister_driver(serial_driver)))
1780                printk("SERIAL: failed to unregister serial driver (%d)\n",
1781                       error);
1782        put_tty_driver(serial_driver);
1783        tty_port_destroy(&state->tport);
1784
1785        free_irq(IRQ_AMIGA_TBE, state);
1786        free_irq(IRQ_AMIGA_RBF, state);
1787
1788        return error;
1789}
1790
1791static struct platform_driver amiga_serial_driver = {
1792        .remove = __exit_p(amiga_serial_remove),
1793        .driver   = {
1794                .name   = "amiga-serial",
1795                .owner  = THIS_MODULE,
1796        },
1797};
1798
1799module_platform_driver_probe(amiga_serial_driver, amiga_serial_probe);
1800
1801
1802#if defined(CONFIG_SERIAL_CONSOLE) && !defined(MODULE)
1803
1804/*
1805 * ------------------------------------------------------------
1806 * Serial console driver
1807 * ------------------------------------------------------------
1808 */
1809
1810static void amiga_serial_putc(char c)
1811{
1812        custom.serdat = (unsigned char)c | 0x100;
1813        while (!(custom.serdatr & 0x2000))
1814                barrier();
1815}
1816
1817/*
1818 *      Print a string to the serial port trying not to disturb
1819 *      any possible real use of the port...
1820 *
1821 *      The console must be locked when we get here.
1822 */
1823static void serial_console_write(struct console *co, const char *s,
1824                                unsigned count)
1825{
1826        unsigned short intena = custom.intenar;
1827
1828        custom.intena = IF_TBE;
1829
1830        while (count--) {
1831                if (*s == '\n')
1832                        amiga_serial_putc('\r');
1833                amiga_serial_putc(*s++);
1834        }
1835
1836        custom.intena = IF_SETCLR | (intena & IF_TBE);
1837}
1838
1839static struct tty_driver *serial_console_device(struct console *c, int *index)
1840{
1841        *index = 0;
1842        return serial_driver;
1843}
1844
1845static struct console sercons = {
1846        .name =         "ttyS",
1847        .write =        serial_console_write,
1848        .device =       serial_console_device,
1849        .flags =        CON_PRINTBUFFER,
1850        .index =        -1,
1851};
1852
1853/*
1854 *      Register console.
1855 */
1856static int __init amiserial_console_init(void)
1857{
1858        register_console(&sercons);
1859        return 0;
1860}
1861console_initcall(amiserial_console_init);
1862
1863#endif /* CONFIG_SERIAL_CONSOLE && !MODULE */
1864
1865MODULE_LICENSE("GPL");
1866MODULE_ALIAS("platform:amiga-serial");
1867
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.