linux/drivers/tty/serial/jsm/jsm_cls.c
<<
>>
Prefs
   1/*
   2 * Copyright 2003 Digi International (www.digi.com)
   3 *      Scott H Kilau <Scott_Kilau at digi dot com>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License as published by
   7 * the Free Software Foundation; either version 2, or (at your option)
   8 * any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
  12 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  13 * PURPOSE.  See the GNU General Public License for more details.
  14 *
  15 *      NOTE TO LINUX KERNEL HACKERS:  DO NOT REFORMAT THIS CODE!
  16 *
  17 *      This is shared code between Digi's CVS archive and the
  18 *      Linux Kernel sources.
  19 *      Changing the source just for reformatting needlessly breaks
  20 *      our CVS diff history.
  21 *
  22 *      Send any bug fixes/changes to:  Eng.Linux at digi dot com.
  23 *      Thank you.
  24 *
  25 */
  26
  27#include <linux/delay.h>        /* For udelay */
  28#include <linux/io.h>           /* For read[bwl]/write[bwl] */
  29#include <linux/serial.h>       /* For struct async_serial */
  30#include <linux/serial_reg.h>   /* For the various UART offsets */
  31#include <linux/pci.h>
  32#include <linux/tty.h>
  33
  34#include "jsm.h"        /* Driver main header file */
  35
  36static struct {
  37        unsigned int rate;
  38        unsigned int cflag;
  39} baud_rates[] = {
  40        { 921600, B921600 },
  41        { 460800, B460800 },
  42        { 230400, B230400 },
  43        { 115200, B115200 },
  44        {  57600, B57600  },
  45        {  38400, B38400  },
  46        {  19200, B19200  },
  47        {   9600, B9600   },
  48        {   4800, B4800   },
  49        {   2400, B2400   },
  50        {   1200, B1200   },
  51        {    600, B600    },
  52        {    300, B300    },
  53        {    200, B200    },
  54        {    150, B150    },
  55        {    134, B134    },
  56        {    110, B110    },
  57        {     75, B75     },
  58        {     50, B50     },
  59};
  60
  61static void cls_set_cts_flow_control(struct jsm_channel *ch)
  62{
  63        u8 lcrb = readb(&ch->ch_cls_uart->lcr);
  64        u8 ier = readb(&ch->ch_cls_uart->ier);
  65        u8 isr_fcr = 0;
  66
  67        /*
  68         * The Enhanced Register Set may only be accessed when
  69         * the Line Control Register is set to 0xBFh.
  70         */
  71        writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
  72
  73        isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
  74
  75        /* Turn on CTS flow control, turn off IXON flow control */
  76        isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_CTSDSR);
  77        isr_fcr &= ~(UART_EXAR654_EFR_IXON);
  78
  79        writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
  80
  81        /* Write old LCR value back out, which turns enhanced access off */
  82        writeb(lcrb, &ch->ch_cls_uart->lcr);
  83
  84        /*
  85         * Enable interrupts for CTS flow, turn off interrupts for
  86         * received XOFF chars
  87         */
  88        ier |= (UART_EXAR654_IER_CTSDSR);
  89        ier &= ~(UART_EXAR654_IER_XOFF);
  90        writeb(ier, &ch->ch_cls_uart->ier);
  91
  92        /* Set the usual FIFO values */
  93        writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
  94
  95        writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_56 |
  96                UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
  97                &ch->ch_cls_uart->isr_fcr);
  98
  99        ch->ch_t_tlevel = 16;
 100}
 101
 102static void cls_set_ixon_flow_control(struct jsm_channel *ch)
 103{
 104        u8 lcrb = readb(&ch->ch_cls_uart->lcr);
 105        u8 ier = readb(&ch->ch_cls_uart->ier);
 106        u8 isr_fcr = 0;
 107
 108        /*
 109         * The Enhanced Register Set may only be accessed when
 110         * the Line Control Register is set to 0xBFh.
 111         */
 112        writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
 113
 114        isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
 115
 116        /* Turn on IXON flow control, turn off CTS flow control */
 117        isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_IXON);
 118        isr_fcr &= ~(UART_EXAR654_EFR_CTSDSR);
 119
 120        writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
 121
 122        /* Now set our current start/stop chars while in enhanced mode */
 123        writeb(ch->ch_startc, &ch->ch_cls_uart->mcr);
 124        writeb(0, &ch->ch_cls_uart->lsr);
 125        writeb(ch->ch_stopc, &ch->ch_cls_uart->msr);
 126        writeb(0, &ch->ch_cls_uart->spr);
 127
 128        /* Write old LCR value back out, which turns enhanced access off */
 129        writeb(lcrb, &ch->ch_cls_uart->lcr);
 130
 131        /*
 132         * Disable interrupts for CTS flow, turn on interrupts for
 133         * received XOFF chars
 134         */
 135        ier &= ~(UART_EXAR654_IER_CTSDSR);
 136        ier |= (UART_EXAR654_IER_XOFF);
 137        writeb(ier, &ch->ch_cls_uart->ier);
 138
 139        /* Set the usual FIFO values */
 140        writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
 141
 142        writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
 143                UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
 144                &ch->ch_cls_uart->isr_fcr);
 145}
 146
 147static void cls_set_no_output_flow_control(struct jsm_channel *ch)
 148{
 149        u8 lcrb = readb(&ch->ch_cls_uart->lcr);
 150        u8 ier = readb(&ch->ch_cls_uart->ier);
 151        u8 isr_fcr = 0;
 152
 153        /*
 154         * The Enhanced Register Set may only be accessed when
 155         * the Line Control Register is set to 0xBFh.
 156         */
 157        writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
 158
 159        isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
 160
 161        /* Turn off IXON flow control, turn off CTS flow control */
 162        isr_fcr |= (UART_EXAR654_EFR_ECB);
 163        isr_fcr &= ~(UART_EXAR654_EFR_CTSDSR | UART_EXAR654_EFR_IXON);
 164
 165        writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
 166
 167        /* Write old LCR value back out, which turns enhanced access off */
 168        writeb(lcrb, &ch->ch_cls_uart->lcr);
 169
 170        /*
 171         * Disable interrupts for CTS flow, turn off interrupts for
 172         * received XOFF chars
 173         */
 174        ier &= ~(UART_EXAR654_IER_CTSDSR);
 175        ier &= ~(UART_EXAR654_IER_XOFF);
 176        writeb(ier, &ch->ch_cls_uart->ier);
 177
 178        /* Set the usual FIFO values */
 179        writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
 180
 181        writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
 182                UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
 183                &ch->ch_cls_uart->isr_fcr);
 184
 185        ch->ch_r_watermark = 0;
 186        ch->ch_t_tlevel = 16;
 187        ch->ch_r_tlevel = 16;
 188}
 189
 190static void cls_set_rts_flow_control(struct jsm_channel *ch)
 191{
 192        u8 lcrb = readb(&ch->ch_cls_uart->lcr);
 193        u8 ier = readb(&ch->ch_cls_uart->ier);
 194        u8 isr_fcr = 0;
 195
 196        /*
 197         * The Enhanced Register Set may only be accessed when
 198         * the Line Control Register is set to 0xBFh.
 199         */
 200        writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
 201
 202        isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
 203
 204        /* Turn on RTS flow control, turn off IXOFF flow control */
 205        isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_RTSDTR);
 206        isr_fcr &= ~(UART_EXAR654_EFR_IXOFF);
 207
 208        writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
 209
 210        /* Write old LCR value back out, which turns enhanced access off */
 211        writeb(lcrb, &ch->ch_cls_uart->lcr);
 212
 213        /* Enable interrupts for RTS flow */
 214        ier |= (UART_EXAR654_IER_RTSDTR);
 215        writeb(ier, &ch->ch_cls_uart->ier);
 216
 217        /* Set the usual FIFO values */
 218        writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
 219
 220        writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_56 |
 221                UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
 222                &ch->ch_cls_uart->isr_fcr);
 223
 224        ch->ch_r_watermark = 4;
 225        ch->ch_r_tlevel = 8;
 226}
 227
 228static void cls_set_ixoff_flow_control(struct jsm_channel *ch)
 229{
 230        u8 lcrb = readb(&ch->ch_cls_uart->lcr);
 231        u8 ier = readb(&ch->ch_cls_uart->ier);
 232        u8 isr_fcr = 0;
 233
 234        /*
 235         * The Enhanced Register Set may only be accessed when
 236         * the Line Control Register is set to 0xBFh.
 237         */
 238        writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
 239
 240        isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
 241
 242        /* Turn on IXOFF flow control, turn off RTS flow control */
 243        isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_IXOFF);
 244        isr_fcr &= ~(UART_EXAR654_EFR_RTSDTR);
 245
 246        writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
 247
 248        /* Now set our current start/stop chars while in enhanced mode */
 249        writeb(ch->ch_startc, &ch->ch_cls_uart->mcr);
 250        writeb(0, &ch->ch_cls_uart->lsr);
 251        writeb(ch->ch_stopc, &ch->ch_cls_uart->msr);
 252        writeb(0, &ch->ch_cls_uart->spr);
 253
 254        /* Write old LCR value back out, which turns enhanced access off */
 255        writeb(lcrb, &ch->ch_cls_uart->lcr);
 256
 257        /* Disable interrupts for RTS flow */
 258        ier &= ~(UART_EXAR654_IER_RTSDTR);
 259        writeb(ier, &ch->ch_cls_uart->ier);
 260
 261        /* Set the usual FIFO values */
 262        writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
 263
 264        writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
 265                UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
 266                &ch->ch_cls_uart->isr_fcr);
 267}
 268
 269static void cls_set_no_input_flow_control(struct jsm_channel *ch)
 270{
 271        u8 lcrb = readb(&ch->ch_cls_uart->lcr);
 272        u8 ier = readb(&ch->ch_cls_uart->ier);
 273        u8 isr_fcr = 0;
 274
 275        /*
 276         * The Enhanced Register Set may only be accessed when
 277         * the Line Control Register is set to 0xBFh.
 278         */
 279        writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
 280
 281        isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
 282
 283        /* Turn off IXOFF flow control, turn off RTS flow control */
 284        isr_fcr |= (UART_EXAR654_EFR_ECB);
 285        isr_fcr &= ~(UART_EXAR654_EFR_RTSDTR | UART_EXAR654_EFR_IXOFF);
 286
 287        writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
 288
 289        /* Write old LCR value back out, which turns enhanced access off */
 290        writeb(lcrb, &ch->ch_cls_uart->lcr);
 291
 292        /* Disable interrupts for RTS flow */
 293        ier &= ~(UART_EXAR654_IER_RTSDTR);
 294        writeb(ier, &ch->ch_cls_uart->ier);
 295
 296        /* Set the usual FIFO values */
 297        writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
 298
 299        writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
 300                UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
 301                &ch->ch_cls_uart->isr_fcr);
 302
 303        ch->ch_t_tlevel = 16;
 304        ch->ch_r_tlevel = 16;
 305}
 306
 307/*
 308 * cls_clear_break.
 309 * Determines whether its time to shut off break condition.
 310 *
 311 * No locks are assumed to be held when calling this function.
 312 * channel lock is held and released in this function.
 313 */
 314static void cls_clear_break(struct jsm_channel *ch)
 315{
 316        unsigned long lock_flags;
 317
 318        spin_lock_irqsave(&ch->ch_lock, lock_flags);
 319
 320        /* Turn break off, and unset some variables */
 321        if (ch->ch_flags & CH_BREAK_SENDING) {
 322                u8 temp = readb(&ch->ch_cls_uart->lcr);
 323
 324                writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr);
 325
 326                ch->ch_flags &= ~(CH_BREAK_SENDING);
 327                jsm_dbg(IOCTL, &ch->ch_bd->pci_dev,
 328                        "clear break Finishing UART_LCR_SBC! finished: %lx\n",
 329                        jiffies);
 330        }
 331        spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
 332}
 333
 334static void cls_disable_receiver(struct jsm_channel *ch)
 335{
 336        u8 tmp = readb(&ch->ch_cls_uart->ier);
 337
 338        tmp &= ~(UART_IER_RDI);
 339        writeb(tmp, &ch->ch_cls_uart->ier);
 340}
 341
 342static void cls_enable_receiver(struct jsm_channel *ch)
 343{
 344        u8 tmp = readb(&ch->ch_cls_uart->ier);
 345
 346        tmp |= (UART_IER_RDI);
 347        writeb(tmp, &ch->ch_cls_uart->ier);
 348}
 349
 350/* Make the UART raise any of the output signals we want up */
 351static void cls_assert_modem_signals(struct jsm_channel *ch)
 352{
 353        if (!ch)
 354                return;
 355
 356        writeb(ch->ch_mostat, &ch->ch_cls_uart->mcr);
 357}
 358
 359static void cls_copy_data_from_uart_to_queue(struct jsm_channel *ch)
 360{
 361        int qleft = 0;
 362        u8 linestatus = 0;
 363        u8 error_mask = 0;
 364        u16 head;
 365        u16 tail;
 366        unsigned long flags;
 367
 368        if (!ch)
 369                return;
 370
 371        spin_lock_irqsave(&ch->ch_lock, flags);
 372
 373        /* cache head and tail of queue */
 374        head = ch->ch_r_head & RQUEUEMASK;
 375        tail = ch->ch_r_tail & RQUEUEMASK;
 376
 377        /* Get our cached LSR */
 378        linestatus = ch->ch_cached_lsr;
 379        ch->ch_cached_lsr = 0;
 380
 381        /* Store how much space we have left in the queue */
 382        qleft = tail - head - 1;
 383        if (qleft < 0)
 384                qleft += RQUEUEMASK + 1;
 385
 386        /*
 387         * Create a mask to determine whether we should
 388         * insert the character (if any) into our queue.
 389         */
 390        if (ch->ch_c_iflag & IGNBRK)
 391                error_mask |= UART_LSR_BI;
 392
 393        while (1) {
 394                /*
 395                 * Grab the linestatus register, we need to
 396                 * check to see if there is any data to read
 397                 */
 398                linestatus = readb(&ch->ch_cls_uart->lsr);
 399
 400                /* Break out if there is no data to fetch */
 401                if (!(linestatus & UART_LSR_DR))
 402                        break;
 403
 404                /*
 405                 * Discard character if we are ignoring the error mask
 406                 * which in this case is the break signal.
 407                 */
 408                if (linestatus & error_mask)  {
 409                        u8 discard;
 410
 411                        linestatus = 0;
 412                        discard = readb(&ch->ch_cls_uart->txrx);
 413                        continue;
 414                }
 415
 416                /*
 417                 * If our queue is full, we have no choice but to drop some
 418                 * data. The assumption is that HWFLOW or SWFLOW should have
 419                 * stopped things way way before we got to this point.
 420                 *
 421                 * I decided that I wanted to ditch the oldest data first,
 422                 * I hope thats okay with everyone? Yes? Good.
 423                 */
 424                while (qleft < 1) {
 425                        tail = (tail + 1) & RQUEUEMASK;
 426                        ch->ch_r_tail = tail;
 427                        ch->ch_err_overrun++;
 428                        qleft++;
 429                }
 430
 431                ch->ch_equeue[head] = linestatus & (UART_LSR_BI | UART_LSR_PE
 432                                                                 | UART_LSR_FE);
 433                ch->ch_rqueue[head] = readb(&ch->ch_cls_uart->txrx);
 434
 435                qleft--;
 436
 437                if (ch->ch_equeue[head] & UART_LSR_PE)
 438                        ch->ch_err_parity++;
 439                if (ch->ch_equeue[head] & UART_LSR_BI)
 440                        ch->ch_err_break++;
 441                if (ch->ch_equeue[head] & UART_LSR_FE)
 442                        ch->ch_err_frame++;
 443
 444                /* Add to, and flip head if needed */
 445                head = (head + 1) & RQUEUEMASK;
 446                ch->ch_rxcount++;
 447        }
 448
 449        /*
 450         * Write new final heads to channel structure.
 451         */
 452        ch->ch_r_head = head & RQUEUEMASK;
 453        ch->ch_e_head = head & EQUEUEMASK;
 454
 455        spin_unlock_irqrestore(&ch->ch_lock, flags);
 456}
 457
 458static void cls_copy_data_from_queue_to_uart(struct jsm_channel *ch)
 459{
 460        u16 tail;
 461        int n;
 462        int qlen;
 463        u32 len_written = 0;
 464        struct circ_buf *circ;
 465
 466        if (!ch)
 467                return;
 468
 469        circ = &ch->uart_port.state->xmit;
 470
 471        /* No data to write to the UART */
 472        if (uart_circ_empty(circ))
 473                return;
 474
 475        /* If port is "stopped", don't send any data to the UART */
 476        if ((ch->ch_flags & CH_STOP) || (ch->ch_flags & CH_BREAK_SENDING))
 477                return;
 478
 479        /* We have to do it this way, because of the EXAR TXFIFO count bug. */
 480        if (!(ch->ch_flags & (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM)))
 481                return;
 482
 483        n = 32;
 484
 485        /* cache tail of queue */
 486        tail = circ->tail & (UART_XMIT_SIZE - 1);
 487        qlen = uart_circ_chars_pending(circ);
 488
 489        /* Find minimum of the FIFO space, versus queue length */
 490        n = min(n, qlen);
 491
 492        while (n > 0) {
 493                writeb(circ->buf[tail], &ch->ch_cls_uart->txrx);
 494                tail = (tail + 1) & (UART_XMIT_SIZE - 1);
 495                n--;
 496                ch->ch_txcount++;
 497                len_written++;
 498        }
 499
 500        /* Update the final tail */
 501        circ->tail = tail & (UART_XMIT_SIZE - 1);
 502
 503        if (len_written > ch->ch_t_tlevel)
 504                ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
 505
 506        if (uart_circ_empty(circ))
 507                uart_write_wakeup(&ch->uart_port);
 508}
 509
 510static void cls_parse_modem(struct jsm_channel *ch, u8 signals)
 511{
 512        u8 msignals = signals;
 513
 514        jsm_dbg(MSIGS, &ch->ch_bd->pci_dev,
 515                "neo_parse_modem: port: %d msignals: %x\n",
 516                ch->ch_portnum, msignals);
 517
 518        /*
 519         * Scrub off lower bits.
 520         * They signify delta's, which I don't care about
 521         * Keep DDCD and DDSR though
 522         */
 523        msignals &= 0xf8;
 524
 525        if (msignals & UART_MSR_DDCD)
 526                uart_handle_dcd_change(&ch->uart_port, msignals & UART_MSR_DCD);
 527        if (msignals & UART_MSR_DDSR)
 528                uart_handle_dcd_change(&ch->uart_port, msignals & UART_MSR_CTS);
 529
 530        if (msignals & UART_MSR_DCD)
 531                ch->ch_mistat |= UART_MSR_DCD;
 532        else
 533                ch->ch_mistat &= ~UART_MSR_DCD;
 534
 535        if (msignals & UART_MSR_DSR)
 536                ch->ch_mistat |= UART_MSR_DSR;
 537        else
 538                ch->ch_mistat &= ~UART_MSR_DSR;
 539
 540        if (msignals & UART_MSR_RI)
 541                ch->ch_mistat |= UART_MSR_RI;
 542        else
 543                ch->ch_mistat &= ~UART_MSR_RI;
 544
 545        if (msignals & UART_MSR_CTS)
 546                ch->ch_mistat |= UART_MSR_CTS;
 547        else
 548                ch->ch_mistat &= ~UART_MSR_CTS;
 549
 550        jsm_dbg(MSIGS, &ch->ch_bd->pci_dev,
 551                "Port: %d DTR: %d RTS: %d CTS: %d DSR: %d " "RI: %d CD: %d\n",
 552                ch->ch_portnum,
 553                !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_DTR),
 554                !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_RTS),
 555                !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_CTS),
 556                !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_DSR),
 557                !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_RI),
 558                !!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_DCD));
 559}
 560
 561/* Parse the ISR register for the specific port */
 562static inline void cls_parse_isr(struct jsm_board *brd, uint port)
 563{
 564        struct jsm_channel *ch;
 565        u8 isr = 0;
 566        unsigned long flags;
 567
 568        /*
 569         * No need to verify board pointer, it was already
 570         * verified in the interrupt routine.
 571         */
 572
 573        if (port >= brd->nasync)
 574                return;
 575
 576        ch = brd->channels[port];
 577        if (!ch)
 578                return;
 579
 580        /* Here we try to figure out what caused the interrupt to happen */
 581        while (1) {
 582                isr = readb(&ch->ch_cls_uart->isr_fcr);
 583
 584                /* Bail if no pending interrupt on port */
 585                if (isr & UART_IIR_NO_INT)
 586                        break;
 587
 588                /* Receive Interrupt pending */
 589                if (isr & (UART_IIR_RDI | UART_IIR_RDI_TIMEOUT)) {
 590                        /* Read data from uart -> queue */
 591                        cls_copy_data_from_uart_to_queue(ch);
 592                        jsm_check_queue_flow_control(ch);
 593                }
 594
 595                /* Transmit Hold register empty pending */
 596                if (isr & UART_IIR_THRI) {
 597                        /* Transfer data (if any) from Write Queue -> UART. */
 598                        spin_lock_irqsave(&ch->ch_lock, flags);
 599                        ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
 600                        spin_unlock_irqrestore(&ch->ch_lock, flags);
 601                        cls_copy_data_from_queue_to_uart(ch);
 602                }
 603
 604                /*
 605                 * CTS/RTS change of state:
 606                 * Don't need to do anything, the cls_parse_modem
 607                 * below will grab the updated modem signals.
 608                 */
 609
 610                /* Parse any modem signal changes */
 611                cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr));
 612        }
 613}
 614
 615/* Channel lock MUST be held before calling this function! */
 616static void cls_flush_uart_write(struct jsm_channel *ch)
 617{
 618        u8 tmp = 0;
 619        u8 i = 0;
 620
 621        if (!ch)
 622                return;
 623
 624        writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT),
 625                                                &ch->ch_cls_uart->isr_fcr);
 626
 627        for (i = 0; i < 10; i++) {
 628                /* Check to see if the UART feels it completely flushed FIFO */
 629                tmp = readb(&ch->ch_cls_uart->isr_fcr);
 630                if (tmp & UART_FCR_CLEAR_XMIT) {
 631                        jsm_dbg(IOCTL, &ch->ch_bd->pci_dev,
 632                                "Still flushing TX UART... i: %d\n", i);
 633                        udelay(10);
 634                } else
 635                        break;
 636        }
 637
 638        ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
 639}
 640
 641/* Channel lock MUST be held before calling this function! */
 642static void cls_flush_uart_read(struct jsm_channel *ch)
 643{
 644        if (!ch)
 645                return;
 646
 647        /*
 648         * For complete POSIX compatibility, we should be purging the
 649         * read FIFO in the UART here.
 650         *
 651         * However, clearing the read FIFO (UART_FCR_CLEAR_RCVR) also
 652         * incorrectly flushes write data as well as just basically trashing the
 653         * FIFO.
 654         *
 655         * Presumably, this is a bug in this UART.
 656         */
 657
 658        udelay(10);
 659}
 660
 661static void cls_send_start_character(struct jsm_channel *ch)
 662{
 663        if (!ch)
 664                return;
 665
 666        if (ch->ch_startc != __DISABLED_CHAR) {
 667                ch->ch_xon_sends++;
 668                writeb(ch->ch_startc, &ch->ch_cls_uart->txrx);
 669        }
 670}
 671
 672static void cls_send_stop_character(struct jsm_channel *ch)
 673{
 674        if (!ch)
 675                return;
 676
 677        if (ch->ch_stopc != __DISABLED_CHAR) {
 678                ch->ch_xoff_sends++;
 679                writeb(ch->ch_stopc, &ch->ch_cls_uart->txrx);
 680        }
 681}
 682
 683/*
 684 * cls_param()
 685 * Send any/all changes to the line to the UART.
 686 */
 687static void cls_param(struct jsm_channel *ch)
 688{
 689        u8 lcr = 0;
 690        u8 uart_lcr = 0;
 691        u8 ier = 0;
 692        u32 baud = 9600;
 693        int quot = 0;
 694        struct jsm_board *bd;
 695        int i;
 696        unsigned int cflag;
 697
 698        bd = ch->ch_bd;
 699        if (!bd)
 700                return;
 701
 702        /*
 703         * If baud rate is zero, flush queues, and set mval to drop DTR.
 704         */
 705        if ((ch->ch_c_cflag & (CBAUD)) == 0) {
 706                ch->ch_r_head = 0;
 707                ch->ch_r_tail = 0;
 708                ch->ch_e_head = 0;
 709                ch->ch_e_tail = 0;
 710
 711                cls_flush_uart_write(ch);
 712                cls_flush_uart_read(ch);
 713
 714                /* The baudrate is B0 so all modem lines are to be dropped. */
 715                ch->ch_flags |= (CH_BAUD0);
 716                ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR);
 717                cls_assert_modem_signals(ch);
 718                return;
 719        }
 720
 721        cflag = C_BAUD(ch->uart_port.state->port.tty);
 722        baud = 9600;
 723        for (i = 0; i < ARRAY_SIZE(baud_rates); i++) {
 724                if (baud_rates[i].cflag == cflag) {
 725                        baud = baud_rates[i].rate;
 726                        break;
 727                }
 728        }
 729
 730        if (ch->ch_flags & CH_BAUD0)
 731                ch->ch_flags &= ~(CH_BAUD0);
 732
 733        if (ch->ch_c_cflag & PARENB)
 734                lcr |= UART_LCR_PARITY;
 735
 736        if (!(ch->ch_c_cflag & PARODD))
 737                lcr |= UART_LCR_EPAR;
 738
 739        /*
 740         * Not all platforms support mark/space parity,
 741         * so this will hide behind an ifdef.
 742         */
 743#ifdef CMSPAR
 744        if (ch->ch_c_cflag & CMSPAR)
 745                lcr |= UART_LCR_SPAR;
 746#endif
 747
 748        if (ch->ch_c_cflag & CSTOPB)
 749                lcr |= UART_LCR_STOP;
 750
 751        switch (ch->ch_c_cflag & CSIZE) {
 752        case CS5:
 753                lcr |= UART_LCR_WLEN5;
 754                break;
 755        case CS6:
 756                lcr |= UART_LCR_WLEN6;
 757                break;
 758        case CS7:
 759                lcr |= UART_LCR_WLEN7;
 760                break;
 761        case CS8:
 762        default:
 763                lcr |= UART_LCR_WLEN8;
 764                break;
 765        }
 766
 767        ier = readb(&ch->ch_cls_uart->ier);
 768        uart_lcr = readb(&ch->ch_cls_uart->lcr);
 769
 770        quot = ch->ch_bd->bd_dividend / baud;
 771
 772        if (quot != 0) {
 773                writeb(UART_LCR_DLAB, &ch->ch_cls_uart->lcr);
 774                writeb((quot & 0xff), &ch->ch_cls_uart->txrx);
 775                writeb((quot >> 8), &ch->ch_cls_uart->ier);
 776                writeb(lcr, &ch->ch_cls_uart->lcr);
 777        }
 778
 779        if (uart_lcr != lcr)
 780                writeb(lcr, &ch->ch_cls_uart->lcr);
 781
 782        if (ch->ch_c_cflag & CREAD)
 783                ier |= (UART_IER_RDI | UART_IER_RLSI);
 784
 785        ier |= (UART_IER_THRI | UART_IER_MSI);
 786
 787        writeb(ier, &ch->ch_cls_uart->ier);
 788
 789        if (ch->ch_c_cflag & CRTSCTS)
 790                cls_set_cts_flow_control(ch);
 791        else if (ch->ch_c_iflag & IXON) {
 792                /*
 793                 * If start/stop is set to disable,
 794                 * then we should disable flow control.
 795                 */
 796                if ((ch->ch_startc == __DISABLED_CHAR) ||
 797                        (ch->ch_stopc == __DISABLED_CHAR))
 798                        cls_set_no_output_flow_control(ch);
 799                else
 800                        cls_set_ixon_flow_control(ch);
 801        } else
 802                cls_set_no_output_flow_control(ch);
 803
 804        if (ch->ch_c_cflag & CRTSCTS)
 805                cls_set_rts_flow_control(ch);
 806        else if (ch->ch_c_iflag & IXOFF) {
 807                /*
 808                 * If start/stop is set to disable,
 809                 * then we should disable flow control.
 810                 */
 811                if ((ch->ch_startc == __DISABLED_CHAR) ||
 812                        (ch->ch_stopc == __DISABLED_CHAR))
 813                        cls_set_no_input_flow_control(ch);
 814                else
 815                        cls_set_ixoff_flow_control(ch);
 816        } else
 817                cls_set_no_input_flow_control(ch);
 818
 819        cls_assert_modem_signals(ch);
 820
 821        /* get current status of the modem signals now */
 822        cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr));
 823}
 824
 825/*
 826 * cls_intr()
 827 *
 828 * Classic specific interrupt handler.
 829 */
 830static irqreturn_t cls_intr(int irq, void *voidbrd)
 831{
 832        struct jsm_board *brd = voidbrd;
 833        unsigned long lock_flags;
 834        unsigned char uart_poll;
 835        uint i = 0;
 836
 837        /* Lock out the slow poller from running on this board. */
 838        spin_lock_irqsave(&brd->bd_intr_lock, lock_flags);
 839
 840        /*
 841         * Check the board's global interrupt offset to see if we
 842         * acctually do have an interrupt pending on us.
 843         */
 844        uart_poll = readb(brd->re_map_membase + UART_CLASSIC_POLL_ADDR_OFFSET);
 845
 846        jsm_dbg(INTR, &brd->pci_dev, "%s:%d uart_poll: %x\n",
 847                __FILE__, __LINE__, uart_poll);
 848
 849        if (!uart_poll) {
 850                jsm_dbg(INTR, &brd->pci_dev,
 851                        "Kernel interrupted to me, but no pending interrupts...\n");
 852                spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags);
 853                return IRQ_NONE;
 854        }
 855
 856        /* At this point, we have at least SOMETHING to service, dig further. */
 857
 858        /* Parse each port to find out what caused the interrupt */
 859        for (i = 0; i < brd->nasync; i++)
 860                cls_parse_isr(brd, i);
 861
 862        spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags);
 863
 864        return IRQ_HANDLED;
 865}
 866
 867/* Inits UART */
 868static void cls_uart_init(struct jsm_channel *ch)
 869{
 870        unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
 871        unsigned char isr_fcr = 0;
 872
 873        writeb(0, &ch->ch_cls_uart->ier);
 874
 875        /*
 876         * The Enhanced Register Set may only be accessed when
 877         * the Line Control Register is set to 0xBFh.
 878         */
 879        writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
 880
 881        isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
 882
 883        /* Turn on Enhanced/Extended controls */
 884        isr_fcr |= (UART_EXAR654_EFR_ECB);
 885
 886        writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
 887
 888        /* Write old LCR value back out, which turns enhanced access off */
 889        writeb(lcrb, &ch->ch_cls_uart->lcr);
 890
 891        /* Clear out UART and FIFO */
 892        readb(&ch->ch_cls_uart->txrx);
 893
 894        writeb((UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR|UART_FCR_CLEAR_XMIT),
 895                                                 &ch->ch_cls_uart->isr_fcr);
 896        udelay(10);
 897
 898        ch->ch_flags |= (CH_FIFO_ENABLED | CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
 899
 900        readb(&ch->ch_cls_uart->lsr);
 901        readb(&ch->ch_cls_uart->msr);
 902}
 903
 904/*
 905 * Turns off UART.
 906 */
 907static void cls_uart_off(struct jsm_channel *ch)
 908{
 909        /* Stop all interrupts from accurring. */
 910        writeb(0, &ch->ch_cls_uart->ier);
 911}
 912
 913/*
 914 * cls_get_uarts_bytes_left.
 915 * Returns 0 is nothing left in the FIFO, returns 1 otherwise.
 916 *
 917 * The channel lock MUST be held by the calling function.
 918 */
 919static u32 cls_get_uart_bytes_left(struct jsm_channel *ch)
 920{
 921        u8 left = 0;
 922        u8 lsr = readb(&ch->ch_cls_uart->lsr);
 923
 924        /* Determine whether the Transmitter is empty or not */
 925        if (!(lsr & UART_LSR_TEMT))
 926                left = 1;
 927        else {
 928                ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
 929                left = 0;
 930        }
 931
 932        return left;
 933}
 934
 935/*
 936 * cls_send_break.
 937 * Starts sending a break thru the UART.
 938 *
 939 * The channel lock MUST be held by the calling function.
 940 */
 941static void cls_send_break(struct jsm_channel *ch)
 942{
 943        /* Tell the UART to start sending the break */
 944        if (!(ch->ch_flags & CH_BREAK_SENDING)) {
 945                u8 temp = readb(&ch->ch_cls_uart->lcr);
 946
 947                writeb((temp | UART_LCR_SBC), &ch->ch_cls_uart->lcr);
 948                ch->ch_flags |= (CH_BREAK_SENDING);
 949        }
 950}
 951
 952/*
 953 * cls_send_immediate_char.
 954 * Sends a specific character as soon as possible to the UART,
 955 * jumping over any bytes that might be in the write queue.
 956 *
 957 * The channel lock MUST be held by the calling function.
 958 */
 959static void cls_send_immediate_char(struct jsm_channel *ch, unsigned char c)
 960{
 961        writeb(c, &ch->ch_cls_uart->txrx);
 962}
 963
 964struct board_ops jsm_cls_ops = {
 965        .intr =                         cls_intr,
 966        .uart_init =                    cls_uart_init,
 967        .uart_off =                     cls_uart_off,
 968        .param =                        cls_param,
 969        .assert_modem_signals =         cls_assert_modem_signals,
 970        .flush_uart_write =             cls_flush_uart_write,
 971        .flush_uart_read =              cls_flush_uart_read,
 972        .disable_receiver =             cls_disable_receiver,
 973        .enable_receiver =              cls_enable_receiver,
 974        .send_break =                   cls_send_break,
 975        .clear_break =                  cls_clear_break,
 976        .send_start_character =         cls_send_start_character,
 977        .send_stop_character =          cls_send_stop_character,
 978        .copy_data_from_queue_to_uart = cls_copy_data_from_queue_to_uart,
 979        .get_uart_bytes_left =          cls_get_uart_bytes_left,
 980        .send_immediate_char =          cls_send_immediate_char
 981};
 982
 983