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_xchar"))
 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        printk("throttle %s: %d....\n", tty_name(tty),
 970               tty->ldisc.chars_in_buffer(tty));
 971#endif
 972
 973        if (serial_paranoia_check(info, tty->name, "rs_throttle"))
 974                return;
 975
 976        if (I_IXOFF(tty))
 977                rs_send_xchar(tty, STOP_CHAR(tty));
 978
 979        if (tty->termios.c_cflag & CRTSCTS)
 980                info->MCR &= ~SER_RTS;
 981
 982        local_irq_save(flags);
 983        rtsdtr_ctrl(info->MCR);
 984        local_irq_restore(flags);
 985}
 986
 987static void rs_unthrottle(struct tty_struct * tty)
 988{
 989        struct serial_state *info = tty->driver_data;
 990        unsigned long flags;
 991#ifdef SERIAL_DEBUG_THROTTLE
 992        printk("unthrottle %s: %d....\n", tty_name(tty),
 993               tty->ldisc.chars_in_buffer(tty));
 994#endif
 995
 996        if (serial_paranoia_check(info, tty->name, "rs_unthrottle"))
 997                return;
 998
 999        if (I_IXOFF(tty)) {
1000                if (info->x_char)
1001                        info->x_char = 0;
1002                else
1003                        rs_send_xchar(tty, START_CHAR(tty));
1004        }
1005        if (tty->termios.c_cflag & CRTSCTS)
1006                info->MCR |= SER_RTS;
1007        local_irq_save(flags);
1008        rtsdtr_ctrl(info->MCR);
1009        local_irq_restore(flags);
1010}
1011
1012/*
1013 * ------------------------------------------------------------
1014 * rs_ioctl() and friends
1015 * ------------------------------------------------------------
1016 */
1017
1018static int get_serial_info(struct tty_struct *tty, struct serial_state *state,
1019                           struct serial_struct __user * retinfo)
1020{
1021        struct serial_struct tmp;
1022   
1023        if (!retinfo)
1024                return -EFAULT;
1025        memset(&tmp, 0, sizeof(tmp));
1026        tty_lock(tty);
1027        tmp.line = tty->index;
1028        tmp.port = state->port;
1029        tmp.flags = state->tport.flags;
1030        tmp.xmit_fifo_size = state->xmit_fifo_size;
1031        tmp.baud_base = state->baud_base;
1032        tmp.close_delay = state->tport.close_delay;
1033        tmp.closing_wait = state->tport.closing_wait;
1034        tmp.custom_divisor = state->custom_divisor;
1035        tty_unlock(tty);
1036        if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
1037                return -EFAULT;
1038        return 0;
1039}
1040
1041static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
1042                           struct serial_struct __user * new_info)
1043{
1044        struct tty_port *port = &state->tport;
1045        struct serial_struct new_serial;
1046        bool change_spd;
1047        int                     retval = 0;
1048
1049        if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
1050                return -EFAULT;
1051
1052        tty_lock(tty);
1053        change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) ||
1054                new_serial.custom_divisor != state->custom_divisor;
1055        if (new_serial.irq || new_serial.port != state->port ||
1056                        new_serial.xmit_fifo_size != state->xmit_fifo_size) {
1057                tty_unlock(tty);
1058                return -EINVAL;
1059        }
1060  
1061        if (!serial_isroot()) {
1062                if ((new_serial.baud_base != state->baud_base) ||
1063                    (new_serial.close_delay != port->close_delay) ||
1064                    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
1065                    ((new_serial.flags & ~ASYNC_USR_MASK) !=
1066                     (port->flags & ~ASYNC_USR_MASK))) {
1067                        tty_unlock(tty);
1068                        return -EPERM;
1069                }
1070                port->flags = ((port->flags & ~ASYNC_USR_MASK) |
1071                               (new_serial.flags & ASYNC_USR_MASK));
1072                state->custom_divisor = new_serial.custom_divisor;
1073                goto check_and_exit;
1074        }
1075
1076        if (new_serial.baud_base < 9600) {
1077                tty_unlock(tty);
1078                return -EINVAL;
1079        }
1080
1081        /*
1082         * OK, past this point, all the error checking has been done.
1083         * At this point, we start making changes.....
1084         */
1085
1086        state->baud_base = new_serial.baud_base;
1087        port->flags = ((port->flags & ~ASYNC_FLAGS) |
1088                        (new_serial.flags & ASYNC_FLAGS));
1089        state->custom_divisor = new_serial.custom_divisor;
1090        port->close_delay = new_serial.close_delay * HZ/100;
1091        port->closing_wait = new_serial.closing_wait * HZ/100;
1092        port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1093
1094check_and_exit:
1095        if (port->flags & ASYNC_INITIALIZED) {
1096                if (change_spd) {
1097                        if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1098                                tty->alt_speed = 57600;
1099                        if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1100                                tty->alt_speed = 115200;
1101                        if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
1102                                tty->alt_speed = 230400;
1103                        if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
1104                                tty->alt_speed = 460800;
1105                        change_speed(tty, state, NULL);
1106                }
1107        } else
1108                retval = startup(tty, state);
1109        tty_unlock(tty);
1110        return retval;
1111}
1112
1113
1114/*
1115 * get_lsr_info - get line status register info
1116 *
1117 * Purpose: Let user call ioctl() to get info when the UART physically
1118 *          is emptied.  On bus types like RS485, the transmitter must
1119 *          release the bus after transmitting. This must be done when
1120 *          the transmit shift register is empty, not be done when the
1121 *          transmit holding register is empty.  This functionality
1122 *          allows an RS485 driver to be written in user space. 
1123 */
1124static int get_lsr_info(struct serial_state *info, unsigned int __user *value)
1125{
1126        unsigned char status;
1127        unsigned int result;
1128        unsigned long flags;
1129
1130        local_irq_save(flags);
1131        status = custom.serdatr;
1132        mb();
1133        local_irq_restore(flags);
1134        result = ((status & SDR_TSRE) ? TIOCSER_TEMT : 0);
1135        if (copy_to_user(value, &result, sizeof(int)))
1136                return -EFAULT;
1137        return 0;
1138}
1139
1140
1141static int rs_tiocmget(struct tty_struct *tty)
1142{
1143        struct serial_state *info = tty->driver_data;
1144        unsigned char control, status;
1145        unsigned long flags;
1146
1147        if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
1148                return -ENODEV;
1149        if (tty->flags & (1 << TTY_IO_ERROR))
1150                return -EIO;
1151
1152        control = info->MCR;
1153        local_irq_save(flags);
1154        status = ciab.pra;
1155        local_irq_restore(flags);
1156        return    ((control & SER_RTS) ? TIOCM_RTS : 0)
1157                | ((control & SER_DTR) ? TIOCM_DTR : 0)
1158                | (!(status  & SER_DCD) ? TIOCM_CAR : 0)
1159                | (!(status  & SER_DSR) ? TIOCM_DSR : 0)
1160                | (!(status  & SER_CTS) ? TIOCM_CTS : 0);
1161}
1162
1163static int rs_tiocmset(struct tty_struct *tty, unsigned int set,
1164                                                unsigned int clear)
1165{
1166        struct serial_state *info = tty->driver_data;
1167        unsigned long flags;
1168
1169        if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
1170                return -ENODEV;
1171        if (tty->flags & (1 << TTY_IO_ERROR))
1172                return -EIO;
1173
1174        local_irq_save(flags);
1175        if (set & TIOCM_RTS)
1176                info->MCR |= SER_RTS;
1177        if (set & TIOCM_DTR)
1178                info->MCR |= SER_DTR;
1179        if (clear & TIOCM_RTS)
1180                info->MCR &= ~SER_RTS;
1181        if (clear & TIOCM_DTR)
1182                info->MCR &= ~SER_DTR;
1183        rtsdtr_ctrl(info->MCR);
1184        local_irq_restore(flags);
1185        return 0;
1186}
1187
1188/*
1189 * rs_break() --- routine which turns the break handling on or off
1190 */
1191static int rs_break(struct tty_struct *tty, int break_state)
1192{
1193        struct serial_state *info = tty->driver_data;
1194        unsigned long flags;
1195
1196        if (serial_paranoia_check(info, tty->name, "rs_break"))
1197                return -EINVAL;
1198
1199        local_irq_save(flags);
1200        if (break_state == -1)
1201          custom.adkcon = AC_SETCLR | AC_UARTBRK;
1202        else
1203          custom.adkcon = AC_UARTBRK;
1204        mb();
1205        local_irq_restore(flags);
1206        return 0;
1207}
1208
1209/*
1210 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
1211 * Return: write counters to the user passed counter struct
1212 * NB: both 1->0 and 0->1 transitions are counted except for
1213 *     RI where only 0->1 is counted.
1214 */
1215static int rs_get_icount(struct tty_struct *tty,
1216                                struct serial_icounter_struct *icount)
1217{
1218        struct serial_state *info = tty->driver_data;
1219        struct async_icount cnow;
1220        unsigned long flags;
1221
1222        local_irq_save(flags);
1223        cnow = info->icount;
1224        local_irq_restore(flags);
1225        icount->cts = cnow.cts;
1226        icount->dsr = cnow.dsr;
1227        icount->rng = cnow.rng;
1228        icount->dcd = cnow.dcd;
1229        icount->rx = cnow.rx;
1230        icount->tx = cnow.tx;
1231        icount->frame = cnow.frame;
1232        icount->overrun = cnow.overrun;
1233        icount->parity = cnow.parity;
1234        icount->brk = cnow.brk;
1235        icount->buf_overrun = cnow.buf_overrun;
1236
1237        return 0;
1238}
1239
1240static int rs_ioctl(struct tty_struct *tty,
1241                    unsigned int cmd, unsigned long arg)
1242{
1243        struct serial_state *info = tty->driver_data;
1244        struct async_icount cprev, cnow;        /* kernel counter temps */
1245        void __user *argp = (void __user *)arg;
1246        unsigned long flags;
1247        DEFINE_WAIT(wait);
1248        int ret;
1249
1250        if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
1251                return -ENODEV;
1252
1253        if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
1254            (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
1255            (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
1256                if (tty->flags & (1 << TTY_IO_ERROR))
1257                    return -EIO;
1258        }
1259
1260        switch (cmd) {
1261                case TIOCGSERIAL:
1262                        return get_serial_info(tty, info, argp);
1263                case TIOCSSERIAL:
1264                        return set_serial_info(tty, info, argp);
1265                case TIOCSERCONFIG:
1266                        return 0;
1267
1268                case TIOCSERGETLSR: /* Get line status register */
1269                        return get_lsr_info(info, argp);
1270
1271                case TIOCSERGSTRUCT:
1272                        if (copy_to_user(argp,
1273                                         info, sizeof(struct serial_state)))
1274                                return -EFAULT;
1275                        return 0;
1276
1277                /*
1278                 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
1279                 * - mask passed in arg for lines of interest
1280                 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
1281                 * Caller should use TIOCGICOUNT to see which one it was
1282                 */
1283                case TIOCMIWAIT:
1284                        local_irq_save(flags);
1285                        /* note the counters on entry */
1286                        cprev = info->icount;
1287                        local_irq_restore(flags);
1288                        while (1) {
1289                                prepare_to_wait(&info->tport.delta_msr_wait,
1290                                                &wait, TASK_INTERRUPTIBLE);
1291                                local_irq_save(flags);
1292                                cnow = info->icount; /* atomic copy */
1293                                local_irq_restore(flags);
1294                                if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
1295                                    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
1296                                        ret = -EIO; /* no change => error */
1297                                        break;
1298                                }
1299                                if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
1300                                     ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
1301                                     ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
1302                                     ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
1303                                        ret = 0;
1304                                        break;
1305                                }
1306                                schedule();
1307                                /* see if a signal did it */
1308                                if (signal_pending(current)) {
1309                                        ret = -ERESTARTSYS;
1310                                        break;
1311                                }
1312                                cprev = cnow;
1313                        }
1314                        finish_wait(&info->tport.delta_msr_wait, &wait);
1315                        return ret;
1316
1317                case TIOCSERGWILD:
1318                case TIOCSERSWILD:
1319                        /* "setserial -W" is called in Debian boot */
1320                        printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
1321                        return 0;
1322
1323                default:
1324                        return -ENOIOCTLCMD;
1325                }
1326        return 0;
1327}
1328
1329static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
1330{
1331        struct serial_state *info = tty->driver_data;
1332        unsigned long flags;
1333        unsigned int cflag = tty->termios.c_cflag;
1334
1335        change_speed(tty, info, old_termios);
1336
1337        /* Handle transition to B0 status */
1338        if ((old_termios->c_cflag & CBAUD) &&
1339            !(cflag & CBAUD)) {
1340                info->MCR &= ~(SER_DTR|SER_RTS);
1341                local_irq_save(flags);
1342                rtsdtr_ctrl(info->MCR);
1343                local_irq_restore(flags);
1344        }
1345
1346        /* Handle transition away from B0 status */
1347        if (!(old_termios->c_cflag & CBAUD) &&
1348            (cflag & CBAUD)) {
1349                info->MCR |= SER_DTR;
1350                if (!(tty->termios.c_cflag & CRTSCTS) || 
1351                    !test_bit(TTY_THROTTLED, &tty->flags)) {
1352                        info->MCR |= SER_RTS;
1353                }
1354                local_irq_save(flags);
1355                rtsdtr_ctrl(info->MCR);
1356                local_irq_restore(flags);
1357        }
1358
1359        /* Handle turning off CRTSCTS */
1360        if ((old_termios->c_cflag & CRTSCTS) &&
1361            !(tty->termios.c_cflag & CRTSCTS)) {
1362                tty->hw_stopped = 0;
1363                rs_start(tty);
1364        }
1365
1366#if 0
1367        /*
1368         * No need to wake up processes in open wait, since they
1369         * sample the CLOCAL flag once, and don't recheck it.
1370         * XXX  It's not clear whether the current behavior is correct
1371         * or not.  Hence, this may change.....
1372         */
1373        if (!(old_termios->c_cflag & CLOCAL) &&
1374            (tty->termios.c_cflag & CLOCAL))
1375                wake_up_interruptible(&info->open_wait);
1376#endif
1377}
1378
1379/*
1380 * ------------------------------------------------------------
1381 * rs_close()
1382 * 
1383 * This routine is called when the serial port gets closed.  First, we
1384 * wait for the last remaining data to be sent.  Then, we unlink its
1385 * async structure from the interrupt chain if necessary, and we free
1386 * that IRQ if nothing is left in the chain.
1387 * ------------------------------------------------------------
1388 */
1389static void rs_close(struct tty_struct *tty, struct file * filp)
1390{
1391        struct serial_state *state = tty->driver_data;
1392        struct tty_port *port = &state->tport;
1393
1394        if (serial_paranoia_check(state, tty->name, "rs_close"))
1395                return;
1396
1397        if (tty_port_close_start(port, tty, filp) == 0)
1398                return;
1399
1400        /*
1401         * At this point we stop accepting input.  To do this, we
1402         * disable the receive line status interrupts, and tell the
1403         * interrupt driver to stop checking the data ready bit in the
1404         * line status register.
1405         */
1406        state->read_status_mask &= ~UART_LSR_DR;
1407        if (port->flags & ASYNC_INITIALIZED) {
1408                /* disable receive interrupts */
1409                custom.intena = IF_RBF;
1410                mb();
1411                /* clear any pending receive interrupt */
1412                custom.intreq = IF_RBF;
1413                mb();
1414
1415                /*
1416                 * Before we drop DTR, make sure the UART transmitter
1417                 * has completely drained; this is especially
1418                 * important if there is a transmit FIFO!
1419                 */
1420                rs_wait_until_sent(tty, state->timeout);
1421        }
1422        shutdown(tty, state);
1423        rs_flush_buffer(tty);
1424                
1425        tty_ldisc_flush(tty);
1426        port->tty = NULL;
1427
1428        tty_port_close_end(port, tty);
1429}
1430
1431/*
1432 * rs_wait_until_sent() --- wait until the transmitter is empty
1433 */
1434static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
1435{
1436        struct serial_state *info = tty->driver_data;
1437        unsigned long orig_jiffies, char_time;
1438        int lsr;
1439
1440        if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
1441                return;
1442
1443        if (info->xmit_fifo_size == 0)
1444                return; /* Just in case.... */
1445
1446        orig_jiffies = jiffies;
1447
1448        /*
1449         * Set the check interval to be 1/5 of the estimated time to
1450         * send a single character, and make it at least 1.  The check
1451         * interval should also be less than the timeout.
1452         * 
1453         * Note: we have to use pretty tight timings here to satisfy
1454         * the NIST-PCTS.
1455         */
1456        char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
1457        char_time = char_time / 5;
1458        if (char_time == 0)
1459                char_time = 1;
1460        if (timeout)
1461          char_time = min_t(unsigned long, char_time, timeout);
1462        /*
1463         * If the transmitter hasn't cleared in twice the approximate
1464         * amount of time to send the entire FIFO, it probably won't
1465         * ever clear.  This assumes the UART isn't doing flow
1466         * control, which is currently the case.  Hence, if it ever
1467         * takes longer than info->timeout, this is probably due to a
1468         * UART bug of some kind.  So, we clamp the timeout parameter at
1469         * 2*info->timeout.
1470         */
1471        if (!timeout || timeout > 2*info->timeout)
1472                timeout = 2*info->timeout;
1473#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
1474        printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
1475        printk("jiff=%lu...", jiffies);
1476#endif
1477        while(!((lsr = custom.serdatr) & SDR_TSRE)) {
1478#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
1479                printk("serdatr = %d (jiff=%lu)...", lsr, jiffies);
1480#endif
1481                msleep_interruptible(jiffies_to_msecs(char_time));
1482                if (signal_pending(current))
1483                        break;
1484                if (timeout && time_after(jiffies, orig_jiffies + timeout))
1485                        break;
1486        }
1487        __set_current_state(TASK_RUNNING);
1488
1489#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
1490        printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
1491#endif
1492}
1493
1494/*
1495 * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
1496 */
1497static void rs_hangup(struct tty_struct *tty)
1498{
1499        struct serial_state *info = tty->driver_data;
1500
1501        if (serial_paranoia_check(info, tty->name, "rs_hangup"))
1502                return;
1503
1504        rs_flush_buffer(tty);
1505        shutdown(tty, info);
1506        info->tport.count = 0;
1507        info->tport.flags &= ~ASYNC_NORMAL_ACTIVE;
1508        info->tport.tty = NULL;
1509        wake_up_interruptible(&info->tport.open_wait);
1510}
1511
1512/*
1513 * This routine is called whenever a serial port is opened.  It
1514 * enables interrupts for a serial port, linking in its async structure into
1515 * the IRQ chain.   It also performs the serial-specific
1516 * initialization for the tty structure.
1517 */
1518static int rs_open(struct tty_struct *tty, struct file * filp)
1519{
1520        struct serial_state *info = rs_table + tty->index;
1521        struct tty_port *port = &info->tport;
1522        int retval;
1523
1524        port->count++;
1525        port->tty = tty;
1526        tty->driver_data = info;
1527        tty->port = port;
1528        if (serial_paranoia_check(info, tty->name, "rs_open"))
1529                return -ENODEV;
1530
1531        port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1532
1533        retval = startup(tty, info);
1534        if (retval) {
1535                return retval;
1536        }
1537
1538        return tty_port_block_til_ready(port, tty, filp);
1539}
1540
1541/*
1542 * /proc fs routines....
1543 */
1544
1545static inline void line_info(struct seq_file *m, int line,
1546                struct serial_state *state)
1547{
1548        char    stat_buf[30], control, status;
1549        unsigned long flags;
1550
1551        seq_printf(m, "%d: uart:amiga_builtin", line);
1552
1553        local_irq_save(flags);
1554        status = ciab.pra;
1555        control = (state->tport.flags & ASYNC_INITIALIZED) ? state->MCR : status;
1556        local_irq_restore(flags);
1557
1558        stat_buf[0] = 0;
1559        stat_buf[1] = 0;
1560        if(!(control & SER_RTS))
1561                strcat(stat_buf, "|RTS");
1562        if(!(status & SER_CTS))
1563                strcat(stat_buf, "|CTS");
1564        if(!(control & SER_DTR))
1565                strcat(stat_buf, "|DTR");
1566        if(!(status & SER_DSR))
1567                strcat(stat_buf, "|DSR");
1568        if(!(status & SER_DCD))
1569                strcat(stat_buf, "|CD");
1570
1571        if (state->quot)
1572                seq_printf(m, " baud:%d", state->baud_base / state->quot);
1573
1574        seq_printf(m, " tx:%d rx:%d", state->icount.tx, state->icount.rx);
1575
1576        if (state->icount.frame)
1577                seq_printf(m, " fe:%d", state->icount.frame);
1578
1579        if (state->icount.parity)
1580                seq_printf(m, " pe:%d", state->icount.parity);
1581
1582        if (state->icount.brk)
1583                seq_printf(m, " brk:%d", state->icount.brk);
1584
1585        if (state->icount.overrun)
1586                seq_printf(m, " oe:%d", state->icount.overrun);
1587
1588        /*
1589         * Last thing is the RS-232 status lines
1590         */
1591        seq_printf(m, " %s\n", stat_buf+1);
1592}
1593
1594static int rs_proc_show(struct seq_file *m, void *v)
1595{
1596        seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version);
1597        line_info(m, 0, &rs_table[0]);
1598        return 0;
1599}
1600
1601static int rs_proc_open(struct inode *inode, struct file *file)
1602{
1603        return single_open(file, rs_proc_show, NULL);
1604}
1605
1606static const struct file_operations rs_proc_fops = {
1607        .owner          = THIS_MODULE,
1608        .open           = rs_proc_open,
1609        .read           = seq_read,
1610        .llseek         = seq_lseek,
1611        .release        = single_release,
1612};
1613
1614/*
1615 * ---------------------------------------------------------------------
1616 * rs_init() and friends
1617 *
1618 * rs_init() is called at boot-time to initialize the serial driver.
1619 * ---------------------------------------------------------------------
1620 */
1621
1622/*
1623 * This routine prints out the appropriate serial driver version
1624 * number, and identifies which options were configured into this
1625 * driver.
1626 */
1627static void show_serial_version(void)
1628{
1629        printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
1630}
1631
1632
1633static const struct tty_operations serial_ops = {
1634        .open = rs_open,
1635        .close = rs_close,
1636        .write = rs_write,
1637        .put_char = rs_put_char,
1638        .flush_chars = rs_flush_chars,
1639        .write_room = rs_write_room,
1640        .chars_in_buffer = rs_chars_in_buffer,
1641        .flush_buffer = rs_flush_buffer,
1642        .ioctl = rs_ioctl,
1643        .throttle = rs_throttle,
1644        .unthrottle = rs_unthrottle,
1645        .set_termios = rs_set_termios,
1646        .stop = rs_stop,
1647        .start = rs_start,
1648        .hangup = rs_hangup,
1649        .break_ctl = rs_break,
1650        .send_xchar = rs_send_xchar,
1651        .wait_until_sent = rs_wait_until_sent,
1652        .tiocmget = rs_tiocmget,
1653        .tiocmset = rs_tiocmset,
1654        .get_icount = rs_get_icount,
1655        .proc_fops = &rs_proc_fops,
1656};
1657
1658static int amiga_carrier_raised(struct tty_port *port)
1659{
1660        return !(ciab.pra & SER_DCD);
1661}
1662
1663static void amiga_dtr_rts(struct tty_port *port, int raise)
1664{
1665        struct serial_state *info = container_of(port, struct serial_state,
1666                        tport);
1667        unsigned long flags;
1668
1669        if (raise)
1670                info->MCR |= SER_DTR|SER_RTS;
1671        else
1672                info->MCR &= ~(SER_DTR|SER_RTS);
1673
1674        local_irq_save(flags);
1675        rtsdtr_ctrl(info->MCR);
1676        local_irq_restore(flags);
1677}
1678
1679static const struct tty_port_operations amiga_port_ops = {
1680        .carrier_raised = amiga_carrier_raised,
1681        .dtr_rts = amiga_dtr_rts,
1682};
1683
1684/*
1685 * The serial driver boot-time initialization code!
1686 */
1687static int __init amiga_serial_probe(struct platform_device *pdev)
1688{
1689        unsigned long flags;
1690        struct serial_state * state;
1691        int error;
1692
1693        serial_driver = alloc_tty_driver(NR_PORTS);
1694        if (!serial_driver)
1695                return -ENOMEM;
1696
1697        show_serial_version();
1698
1699        /* Initialize the tty_driver structure */
1700
1701        serial_driver->driver_name = "amiserial";
1702        serial_driver->name = "ttyS";
1703        serial_driver->major = TTY_MAJOR;
1704        serial_driver->minor_start = 64;
1705        serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
1706        serial_driver->subtype = SERIAL_TYPE_NORMAL;
1707        serial_driver->init_termios = tty_std_termios;
1708        serial_driver->init_termios.c_cflag =
1709                B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1710        serial_driver->flags = TTY_DRIVER_REAL_RAW;
1711        tty_set_operations(serial_driver, &serial_ops);
1712
1713        state = rs_table;
1714        state->port = (int)&custom.serdatr; /* Just to give it a value */
1715        state->custom_divisor = 0;
1716        state->icount.cts = state->icount.dsr = 
1717          state->icount.rng = state->icount.dcd = 0;
1718        state->icount.rx = state->icount.tx = 0;
1719        state->icount.frame = state->icount.parity = 0;
1720        state->icount.overrun = state->icount.brk = 0;
1721        tty_port_init(&state->tport);
1722        state->tport.ops = &amiga_port_ops;
1723        tty_port_link_device(&state->tport, serial_driver, 0);
1724
1725        error = tty_register_driver(serial_driver);
1726        if (error)
1727                goto fail_put_tty_driver;
1728
1729        printk(KERN_INFO "ttyS0 is the amiga builtin serial port\n");
1730
1731        /* Hardware set up */
1732
1733        state->baud_base = amiga_colorclock;
1734        state->xmit_fifo_size = 1;
1735
1736        /* set ISRs, and then disable the rx interrupts */
1737        error = request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state);
1738        if (error)
1739                goto fail_unregister;
1740
1741        error = request_irq(IRQ_AMIGA_RBF, ser_rx_int, 0,
1742                            "serial RX", state);
1743        if (error)
1744                goto fail_free_irq;
1745
1746        local_irq_save(flags);
1747
1748        /* turn off Rx and Tx interrupts */
1749        custom.intena = IF_RBF | IF_TBE;
1750        mb();
1751
1752        /* clear any pending interrupt */
1753        custom.intreq = IF_RBF | IF_TBE;
1754        mb();
1755
1756        local_irq_restore(flags);
1757
1758        /*
1759         * set the appropriate directions for the modem control flags,
1760         * and clear RTS and DTR
1761         */
1762        ciab.ddra |= (SER_DTR | SER_RTS);   /* outputs */
1763        ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR);  /* inputs */
1764
1765        platform_set_drvdata(pdev, state);
1766
1767        return 0;
1768
1769fail_free_irq:
1770        free_irq(IRQ_AMIGA_TBE, state);
1771fail_unregister:
1772        tty_unregister_driver(serial_driver);
1773fail_put_tty_driver:
1774        tty_port_destroy(&state->tport);
1775        put_tty_driver(serial_driver);
1776        return error;
1777}
1778
1779static int __exit amiga_serial_remove(struct platform_device *pdev)
1780{
1781        int error;
1782        struct serial_state *state = platform_get_drvdata(pdev);
1783
1784        /* printk("Unloading %s: version %s\n", serial_name, serial_version); */
1785        error = tty_unregister_driver(serial_driver);
1786        if (error)
1787                printk("SERIAL: failed to unregister serial driver (%d)\n",
1788                       error);
1789        put_tty_driver(serial_driver);
1790        tty_port_destroy(&state->tport);
1791
1792        free_irq(IRQ_AMIGA_TBE, state);
1793        free_irq(IRQ_AMIGA_RBF, state);
1794
1795        return error;
1796}
1797
1798static struct platform_driver amiga_serial_driver = {
1799        .remove = __exit_p(amiga_serial_remove),
1800        .driver   = {
1801                .name   = "amiga-serial",
1802        },
1803};
1804
1805module_platform_driver_probe(amiga_serial_driver, amiga_serial_probe);
1806
1807
1808#if defined(CONFIG_SERIAL_CONSOLE) && !defined(MODULE)
1809
1810/*
1811 * ------------------------------------------------------------
1812 * Serial console driver
1813 * ------------------------------------------------------------
1814 */
1815
1816static void amiga_serial_putc(char c)
1817{
1818        custom.serdat = (unsigned char)c | 0x100;
1819        while (!(custom.serdatr & 0x2000))
1820                barrier();
1821}
1822
1823/*
1824 *      Print a string to the serial port trying not to disturb
1825 *      any possible real use of the port...
1826 *
1827 *      The console must be locked when we get here.
1828 */
1829static void serial_console_write(struct console *co, const char *s,
1830                                unsigned count)
1831{
1832        unsigned short intena = custom.intenar;
1833
1834        custom.intena = IF_TBE;
1835
1836        while (count--) {
1837                if (*s == '\n')
1838                        amiga_serial_putc('\r');
1839                amiga_serial_putc(*s++);
1840        }
1841
1842        custom.intena = IF_SETCLR | (intena & IF_TBE);
1843}
1844
1845static struct tty_driver *serial_console_device(struct console *c, int *index)
1846{
1847        *index = 0;
1848        return serial_driver;
1849}
1850
1851static struct console sercons = {
1852        .name =         "ttyS",
1853        .write =        serial_console_write,
1854        .device =       serial_console_device,
1855        .flags =        CON_PRINTBUFFER,
1856        .index =        -1,
1857};
1858
1859/*
1860 *      Register console.
1861 */
1862static int __init amiserial_console_init(void)
1863{
1864        if (!MACH_IS_AMIGA)
1865                return -ENODEV;
1866
1867        register_console(&sercons);
1868        return 0;
1869}
1870console_initcall(amiserial_console_init);
1871
1872#endif /* CONFIG_SERIAL_CONSOLE && !MODULE */
1873
1874MODULE_LICENSE("GPL");
1875MODULE_ALIAS("platform:amiga-serial");
1876