linux/drivers/staging/dgnc/dgnc_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
  16#include <linux/kernel.h>
  17#include <linux/sched.h>        /* For jiffies, task states */
  18#include <linux/interrupt.h>    /* For tasklet and interrupt structs/defines */
  19#include <linux/delay.h>        /* For udelay */
  20#include <linux/io.h>           /* For read[bwl]/write[bwl] */
  21#include <linux/serial.h>       /* For struct async_serial */
  22#include <linux/serial_reg.h>   /* For the various UART offsets */
  23#include <linux/pci.h>
  24
  25#include "dgnc_driver.h"        /* Driver main header file */
  26#include "dgnc_cls.h"
  27#include "dgnc_tty.h"
  28
  29static inline void cls_set_cts_flow_control(struct channel_t *ch)
  30{
  31        unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
  32        unsigned char ier = readb(&ch->ch_cls_uart->ier);
  33        unsigned char isr_fcr = 0;
  34
  35        /*
  36         * The Enhanced Register Set may only be accessed when
  37         * the Line Control Register is set to 0xBFh.
  38         */
  39        writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
  40
  41        isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
  42
  43        /* Turn on CTS flow control, turn off IXON flow control */
  44        isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_CTSDSR);
  45        isr_fcr &= ~(UART_EXAR654_EFR_IXON);
  46
  47        writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
  48
  49        /* Write old LCR value back out, which turns enhanced access off */
  50        writeb(lcrb, &ch->ch_cls_uart->lcr);
  51
  52        /*
  53         * Enable interrupts for CTS flow, turn off interrupts for
  54         * received XOFF chars
  55         */
  56        ier |= (UART_EXAR654_IER_CTSDSR);
  57        ier &= ~(UART_EXAR654_IER_XOFF);
  58        writeb(ier, &ch->ch_cls_uart->ier);
  59
  60        /* Set the usual FIFO values */
  61        writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
  62
  63        writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_56 |
  64                UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
  65                &ch->ch_cls_uart->isr_fcr);
  66
  67        ch->ch_t_tlevel = 16;
  68}
  69
  70static inline void cls_set_ixon_flow_control(struct channel_t *ch)
  71{
  72        unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
  73        unsigned char ier = readb(&ch->ch_cls_uart->ier);
  74        unsigned char isr_fcr = 0;
  75
  76        /*
  77         * The Enhanced Register Set may only be accessed when
  78         * the Line Control Register is set to 0xBFh.
  79         */
  80        writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
  81
  82        isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
  83
  84        /* Turn on IXON flow control, turn off CTS flow control */
  85        isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_IXON);
  86        isr_fcr &= ~(UART_EXAR654_EFR_CTSDSR);
  87
  88        writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
  89
  90        /* Now set our current start/stop chars while in enhanced mode */
  91        writeb(ch->ch_startc, &ch->ch_cls_uart->mcr);
  92        writeb(0, &ch->ch_cls_uart->lsr);
  93        writeb(ch->ch_stopc, &ch->ch_cls_uart->msr);
  94        writeb(0, &ch->ch_cls_uart->spr);
  95
  96        /* Write old LCR value back out, which turns enhanced access off */
  97        writeb(lcrb, &ch->ch_cls_uart->lcr);
  98
  99        /*
 100         * Disable interrupts for CTS flow, turn on interrupts for
 101         * received XOFF chars
 102         */
 103        ier &= ~(UART_EXAR654_IER_CTSDSR);
 104        ier |= (UART_EXAR654_IER_XOFF);
 105        writeb(ier, &ch->ch_cls_uart->ier);
 106
 107        /* Set the usual FIFO values */
 108        writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
 109
 110        writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
 111                UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
 112                &ch->ch_cls_uart->isr_fcr);
 113}
 114
 115static inline void cls_set_no_output_flow_control(struct channel_t *ch)
 116{
 117        unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
 118        unsigned char ier = readb(&ch->ch_cls_uart->ier);
 119        unsigned char isr_fcr = 0;
 120
 121        /*
 122         * The Enhanced Register Set may only be accessed when
 123         * the Line Control Register is set to 0xBFh.
 124         */
 125        writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
 126
 127        isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
 128
 129        /* Turn off IXON flow control, turn off CTS flow control */
 130        isr_fcr |= (UART_EXAR654_EFR_ECB);
 131        isr_fcr &= ~(UART_EXAR654_EFR_CTSDSR | UART_EXAR654_EFR_IXON);
 132
 133        writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
 134
 135        /* Write old LCR value back out, which turns enhanced access off */
 136        writeb(lcrb, &ch->ch_cls_uart->lcr);
 137
 138        /*
 139         * Disable interrupts for CTS flow, turn off interrupts for
 140         * received XOFF chars
 141         */
 142        ier &= ~(UART_EXAR654_IER_CTSDSR);
 143        ier &= ~(UART_EXAR654_IER_XOFF);
 144        writeb(ier, &ch->ch_cls_uart->ier);
 145
 146        /* Set the usual FIFO values */
 147        writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
 148
 149        writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
 150                UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
 151                &ch->ch_cls_uart->isr_fcr);
 152
 153        ch->ch_r_watermark = 0;
 154        ch->ch_t_tlevel = 16;
 155        ch->ch_r_tlevel = 16;
 156}
 157
 158static inline void cls_set_rts_flow_control(struct channel_t *ch)
 159{
 160        unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
 161        unsigned char ier = readb(&ch->ch_cls_uart->ier);
 162        unsigned char isr_fcr = 0;
 163
 164        /*
 165         * The Enhanced Register Set may only be accessed when
 166         * the Line Control Register is set to 0xBFh.
 167         */
 168        writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
 169
 170        isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
 171
 172        /* Turn on RTS flow control, turn off IXOFF flow control */
 173        isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_RTSDTR);
 174        isr_fcr &= ~(UART_EXAR654_EFR_IXOFF);
 175
 176        writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
 177
 178        /* Write old LCR value back out, which turns enhanced access off */
 179        writeb(lcrb, &ch->ch_cls_uart->lcr);
 180
 181        /* Enable interrupts for RTS flow */
 182        ier |= (UART_EXAR654_IER_RTSDTR);
 183        writeb(ier, &ch->ch_cls_uart->ier);
 184
 185        /* Set the usual FIFO values */
 186        writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
 187
 188        writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_56 |
 189                UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
 190                &ch->ch_cls_uart->isr_fcr);
 191
 192        ch->ch_r_watermark = 4;
 193        ch->ch_r_tlevel = 8;
 194}
 195
 196static inline void cls_set_ixoff_flow_control(struct channel_t *ch)
 197{
 198        unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
 199        unsigned char ier = readb(&ch->ch_cls_uart->ier);
 200        unsigned char isr_fcr = 0;
 201
 202        /*
 203         * The Enhanced Register Set may only be accessed when
 204         * the Line Control Register is set to 0xBFh.
 205         */
 206        writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
 207
 208        isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
 209
 210        /* Turn on IXOFF flow control, turn off RTS flow control */
 211        isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_IXOFF);
 212        isr_fcr &= ~(UART_EXAR654_EFR_RTSDTR);
 213
 214        writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
 215
 216        /* Now set our current start/stop chars while in enhanced mode */
 217        writeb(ch->ch_startc, &ch->ch_cls_uart->mcr);
 218        writeb(0, &ch->ch_cls_uart->lsr);
 219        writeb(ch->ch_stopc, &ch->ch_cls_uart->msr);
 220        writeb(0, &ch->ch_cls_uart->spr);
 221
 222        /* Write old LCR value back out, which turns enhanced access off */
 223        writeb(lcrb, &ch->ch_cls_uart->lcr);
 224
 225        /* Disable interrupts for RTS flow */
 226        ier &= ~(UART_EXAR654_IER_RTSDTR);
 227        writeb(ier, &ch->ch_cls_uart->ier);
 228
 229        /* Set the usual FIFO values */
 230        writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
 231
 232        writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
 233                UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
 234                &ch->ch_cls_uart->isr_fcr);
 235}
 236
 237static inline void cls_set_no_input_flow_control(struct channel_t *ch)
 238{
 239        unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
 240        unsigned char ier = readb(&ch->ch_cls_uart->ier);
 241        unsigned char isr_fcr = 0;
 242
 243        /*
 244         * The Enhanced Register Set may only be accessed when
 245         * the Line Control Register is set to 0xBFh.
 246         */
 247        writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
 248
 249        isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
 250
 251        /* Turn off IXOFF flow control, turn off RTS flow control */
 252        isr_fcr |= (UART_EXAR654_EFR_ECB);
 253        isr_fcr &= ~(UART_EXAR654_EFR_RTSDTR | UART_EXAR654_EFR_IXOFF);
 254
 255        writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
 256
 257        /* Write old LCR value back out, which turns enhanced access off */
 258        writeb(lcrb, &ch->ch_cls_uart->lcr);
 259
 260        /* Disable interrupts for RTS flow */
 261        ier &= ~(UART_EXAR654_IER_RTSDTR);
 262        writeb(ier, &ch->ch_cls_uart->ier);
 263
 264        /* Set the usual FIFO values */
 265        writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
 266
 267        writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
 268                UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
 269                &ch->ch_cls_uart->isr_fcr);
 270
 271        ch->ch_t_tlevel = 16;
 272        ch->ch_r_tlevel = 16;
 273}
 274
 275/*
 276 * cls_clear_break.
 277 * Determines whether its time to shut off break condition.
 278 *
 279 * No locks are assumed to be held when calling this function.
 280 * channel lock is held and released in this function.
 281 */
 282static inline void cls_clear_break(struct channel_t *ch, int force)
 283{
 284        unsigned long flags;
 285
 286        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
 287                return;
 288
 289        spin_lock_irqsave(&ch->ch_lock, flags);
 290
 291        /* Bail if we aren't currently sending a break. */
 292        if (!ch->ch_stop_sending_break) {
 293                spin_unlock_irqrestore(&ch->ch_lock, flags);
 294                return;
 295        }
 296
 297        /* Turn break off, and unset some variables */
 298        if (ch->ch_flags & CH_BREAK_SENDING) {
 299                if (time_after(jiffies, ch->ch_stop_sending_break) || force) {
 300                        unsigned char temp = readb(&ch->ch_cls_uart->lcr);
 301
 302                        writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr);
 303                        ch->ch_flags &= ~(CH_BREAK_SENDING);
 304                        ch->ch_stop_sending_break = 0;
 305                }
 306        }
 307        spin_unlock_irqrestore(&ch->ch_lock, flags);
 308}
 309
 310static void cls_copy_data_from_uart_to_queue(struct channel_t *ch)
 311{
 312        int qleft = 0;
 313        unsigned char linestatus = 0;
 314        unsigned char error_mask = 0;
 315        ushort head;
 316        ushort tail;
 317        unsigned long flags;
 318
 319        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
 320                return;
 321
 322        spin_lock_irqsave(&ch->ch_lock, flags);
 323
 324        /* cache head and tail of queue */
 325        head = ch->ch_r_head;
 326        tail = ch->ch_r_tail;
 327
 328        /* Store how much space we have left in the queue */
 329        qleft = tail - head - 1;
 330        if (qleft < 0)
 331                qleft += RQUEUEMASK + 1;
 332
 333        /*
 334         * Create a mask to determine whether we should
 335         * insert the character (if any) into our queue.
 336         */
 337        if (ch->ch_c_iflag & IGNBRK)
 338                error_mask |= UART_LSR_BI;
 339
 340        while (1) {
 341                linestatus = readb(&ch->ch_cls_uart->lsr);
 342
 343                if (!(linestatus & (UART_LSR_DR)))
 344                        break;
 345
 346                /*
 347                 * Discard character if we are ignoring the error mask.
 348                 */
 349                if (linestatus & error_mask)  {
 350                        linestatus = 0;
 351                        readb(&ch->ch_cls_uart->txrx);
 352                        continue;
 353                }
 354
 355                /*
 356                 * If our queue is full, we have no choice but to drop some
 357                 * data. The assumption is that HWFLOW or SWFLOW should have
 358                 * stopped things way way before we got to this point.
 359                 *
 360                 * I decided that I wanted to ditch the oldest data first,
 361                 * I hope thats okay with everyone? Yes? Good.
 362                 */
 363                while (qleft < 1) {
 364                        tail = (tail + 1) & RQUEUEMASK;
 365                        ch->ch_r_tail = tail;
 366                        ch->ch_err_overrun++;
 367                        qleft++;
 368                }
 369
 370                ch->ch_equeue[head] = linestatus & (UART_LSR_BI | UART_LSR_PE
 371                                                                 | UART_LSR_FE);
 372                ch->ch_rqueue[head] = readb(&ch->ch_cls_uart->txrx);
 373
 374                qleft--;
 375
 376                if (ch->ch_equeue[head] & UART_LSR_PE)
 377                        ch->ch_err_parity++;
 378                if (ch->ch_equeue[head] & UART_LSR_BI)
 379                        ch->ch_err_break++;
 380                if (ch->ch_equeue[head] & UART_LSR_FE)
 381                        ch->ch_err_frame++;
 382
 383                /* Add to, and flip head if needed */
 384                head = (head + 1) & RQUEUEMASK;
 385                ch->ch_rxcount++;
 386        }
 387
 388        /* Write new final heads to channel structure. */
 389
 390        ch->ch_r_head = head & RQUEUEMASK;
 391        ch->ch_e_head = head & EQUEUEMASK;
 392
 393        spin_unlock_irqrestore(&ch->ch_lock, flags);
 394}
 395
 396/* Make the UART raise any of the output signals we want up */
 397static void cls_assert_modem_signals(struct channel_t *ch)
 398{
 399        unsigned char out;
 400
 401        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
 402                return;
 403
 404        out = ch->ch_mostat;
 405
 406        if (ch->ch_flags & CH_LOOPBACK)
 407                out |= UART_MCR_LOOP;
 408
 409        writeb(out, &ch->ch_cls_uart->mcr);
 410
 411        /* Give time for the UART to actually drop the signals */
 412        udelay(10);
 413}
 414
 415static void cls_copy_data_from_queue_to_uart(struct channel_t *ch)
 416{
 417        ushort head;
 418        ushort tail;
 419        int n;
 420        int qlen;
 421        uint len_written = 0;
 422        unsigned long flags;
 423
 424        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
 425                return;
 426
 427        spin_lock_irqsave(&ch->ch_lock, flags);
 428
 429        /* No data to write to the UART */
 430        if (ch->ch_w_tail == ch->ch_w_head)
 431                goto exit_unlock;
 432
 433        /* If port is "stopped", don't send any data to the UART */
 434        if ((ch->ch_flags & CH_FORCED_STOP) ||
 435            (ch->ch_flags & CH_BREAK_SENDING))
 436                goto exit_unlock;
 437
 438        if (!(ch->ch_flags & (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM)))
 439                goto exit_unlock;
 440
 441        n = 32;
 442
 443        /* cache head and tail of queue */
 444        head = ch->ch_w_head & WQUEUEMASK;
 445        tail = ch->ch_w_tail & WQUEUEMASK;
 446        qlen = (head - tail) & WQUEUEMASK;
 447
 448        /* Find minimum of the FIFO space, versus queue length */
 449        n = min(n, qlen);
 450
 451        while (n > 0) {
 452                /*
 453                 * If RTS Toggle mode is on, turn on RTS now if not already set,
 454                 * and make sure we get an event when the data transfer has
 455                 * completed.
 456                 */
 457                if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) {
 458                        if (!(ch->ch_mostat & UART_MCR_RTS)) {
 459                                ch->ch_mostat |= (UART_MCR_RTS);
 460                                cls_assert_modem_signals(ch);
 461                        }
 462                        ch->ch_tun.un_flags |= (UN_EMPTY);
 463                }
 464
 465                /*
 466                 * If DTR Toggle mode is on, turn on DTR now if not already set,
 467                 * and make sure we get an event when the data transfer has
 468                 * completed.
 469                 */
 470                if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) {
 471                        if (!(ch->ch_mostat & UART_MCR_DTR)) {
 472                                ch->ch_mostat |= (UART_MCR_DTR);
 473                                cls_assert_modem_signals(ch);
 474                        }
 475                        ch->ch_tun.un_flags |= (UN_EMPTY);
 476                }
 477                writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_cls_uart->txrx);
 478                ch->ch_w_tail++;
 479                ch->ch_w_tail &= WQUEUEMASK;
 480                ch->ch_txcount++;
 481                len_written++;
 482                n--;
 483        }
 484
 485        if (len_written > 0)
 486                ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
 487
 488exit_unlock:
 489        spin_unlock_irqrestore(&ch->ch_lock, flags);
 490}
 491
 492static void cls_parse_modem(struct channel_t *ch, unsigned char signals)
 493{
 494        unsigned char msignals = signals;
 495        unsigned long flags;
 496
 497        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
 498                return;
 499
 500        /*
 501         * Do altpin switching. Altpin switches DCD and DSR.
 502         * This prolly breaks DSRPACE, so we should be more clever here.
 503         */
 504        spin_lock_irqsave(&ch->ch_lock, flags);
 505        if (ch->ch_digi.digi_flags & DIGI_ALTPIN) {
 506                unsigned char mswap = signals;
 507
 508                if (mswap & UART_MSR_DDCD) {
 509                        msignals &= ~UART_MSR_DDCD;
 510                        msignals |= UART_MSR_DDSR;
 511                }
 512                if (mswap & UART_MSR_DDSR) {
 513                        msignals &= ~UART_MSR_DDSR;
 514                        msignals |= UART_MSR_DDCD;
 515                }
 516                if (mswap & UART_MSR_DCD) {
 517                        msignals &= ~UART_MSR_DCD;
 518                        msignals |= UART_MSR_DSR;
 519                }
 520                if (mswap & UART_MSR_DSR) {
 521                        msignals &= ~UART_MSR_DSR;
 522                        msignals |= UART_MSR_DCD;
 523                }
 524        }
 525        spin_unlock_irqrestore(&ch->ch_lock, flags);
 526
 527        /*
 528         * Scrub off lower bits. They signify delta's, which I don't
 529         * care about
 530         */
 531        signals &= 0xf0;
 532
 533        spin_lock_irqsave(&ch->ch_lock, flags);
 534        if (msignals & UART_MSR_DCD)
 535                ch->ch_mistat |= UART_MSR_DCD;
 536        else
 537                ch->ch_mistat &= ~UART_MSR_DCD;
 538
 539        if (msignals & UART_MSR_DSR)
 540                ch->ch_mistat |= UART_MSR_DSR;
 541        else
 542                ch->ch_mistat &= ~UART_MSR_DSR;
 543
 544        if (msignals & UART_MSR_RI)
 545                ch->ch_mistat |= UART_MSR_RI;
 546        else
 547                ch->ch_mistat &= ~UART_MSR_RI;
 548
 549        if (msignals & UART_MSR_CTS)
 550                ch->ch_mistat |= UART_MSR_CTS;
 551        else
 552                ch->ch_mistat &= ~UART_MSR_CTS;
 553        spin_unlock_irqrestore(&ch->ch_lock, flags);
 554}
 555
 556/* Parse the ISR register for the specific port */
 557static inline void cls_parse_isr(struct dgnc_board *brd, uint port)
 558{
 559        struct channel_t *ch;
 560        unsigned char isr = 0;
 561        unsigned long flags;
 562
 563        /*
 564         * No need to verify board pointer, it was already
 565         * verified in the interrupt routine.
 566         */
 567
 568        if (port >= brd->nasync)
 569                return;
 570
 571        ch = brd->channels[port];
 572        if (ch->magic != DGNC_CHANNEL_MAGIC)
 573                return;
 574
 575        /* Here we try to figure out what caused the interrupt to happen */
 576        while (1) {
 577                isr = readb(&ch->ch_cls_uart->isr_fcr);
 578
 579                /* Bail if no pending interrupt on port */
 580                if (isr & UART_IIR_NO_INT)
 581                        break;
 582
 583                /* Receive Interrupt pending */
 584                if (isr & (UART_IIR_RDI | UART_IIR_RDI_TIMEOUT)) {
 585                        /* Read data from uart -> queue */
 586                        cls_copy_data_from_uart_to_queue(ch);
 587                        dgnc_check_queue_flow_control(ch);
 588                }
 589
 590                /* Transmit Hold register empty pending */
 591                if (isr & UART_IIR_THRI) {
 592                        /* Transfer data (if any) from Write Queue -> UART. */
 593                        spin_lock_irqsave(&ch->ch_lock, flags);
 594                        ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
 595                        spin_unlock_irqrestore(&ch->ch_lock, flags);
 596                        cls_copy_data_from_queue_to_uart(ch);
 597                }
 598
 599                /* Parse any modem signal changes */
 600                cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr));
 601        }
 602}
 603
 604/* Channel lock MUST be held before calling this function! */
 605static void cls_flush_uart_write(struct channel_t *ch)
 606{
 607        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
 608                return;
 609
 610        writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT),
 611               &ch->ch_cls_uart->isr_fcr);
 612        usleep_range(10, 20);
 613
 614        ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
 615}
 616
 617/* Channel lock MUST be held before calling this function! */
 618static void cls_flush_uart_read(struct channel_t *ch)
 619{
 620        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
 621                return;
 622
 623        /*
 624         * For complete POSIX compatibility, we should be purging the
 625         * read FIFO in the UART here.
 626         *
 627         * However, clearing the read FIFO (UART_FCR_CLEAR_RCVR) also
 628         * incorrectly flushes write data as well as just basically trashing the
 629         * FIFO.
 630         *
 631         * Presumably, this is a bug in this UART.
 632         */
 633
 634        udelay(10);
 635}
 636
 637/*
 638 * cls_param()
 639 * Send any/all changes to the line to the UART.
 640 */
 641static void cls_param(struct tty_struct *tty)
 642{
 643        unsigned char lcr = 0;
 644        unsigned char uart_lcr = 0;
 645        unsigned char ier = 0;
 646        unsigned char uart_ier = 0;
 647        uint baud = 9600;
 648        int quot = 0;
 649        struct dgnc_board *bd;
 650        struct channel_t *ch;
 651        struct un_t   *un;
 652
 653        if (!tty || tty->magic != TTY_MAGIC)
 654                return;
 655
 656        un = (struct un_t *)tty->driver_data;
 657        if (!un || un->magic != DGNC_UNIT_MAGIC)
 658                return;
 659
 660        ch = un->un_ch;
 661        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
 662                return;
 663
 664        bd = ch->ch_bd;
 665        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
 666                return;
 667
 668        /* If baud rate is zero, flush queues, and set mval to drop DTR. */
 669
 670        if ((ch->ch_c_cflag & (CBAUD)) == 0) {
 671                ch->ch_r_head = 0;
 672                ch->ch_r_tail = 0;
 673                ch->ch_e_head = 0;
 674                ch->ch_e_tail = 0;
 675                ch->ch_w_head = 0;
 676                ch->ch_w_tail = 0;
 677
 678                cls_flush_uart_write(ch);
 679                cls_flush_uart_read(ch);
 680
 681                /* The baudrate is B0 so all modem lines are to be dropped. */
 682                ch->ch_flags |= (CH_BAUD0);
 683                ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR);
 684                cls_assert_modem_signals(ch);
 685                ch->ch_old_baud = 0;
 686                return;
 687        } else if (ch->ch_custom_speed) {
 688                baud = ch->ch_custom_speed;
 689                /* Handle transition from B0 */
 690                if (ch->ch_flags & CH_BAUD0) {
 691                        ch->ch_flags &= ~(CH_BAUD0);
 692
 693                        /*
 694                         * Bring back up RTS and DTR...
 695                         * Also handle RTS or DTR toggle if set.
 696                         */
 697                        if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE))
 698                                ch->ch_mostat |= (UART_MCR_RTS);
 699                        if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE))
 700                                ch->ch_mostat |= (UART_MCR_DTR);
 701                }
 702
 703        } else {
 704                int iindex = 0;
 705                int jindex = 0;
 706
 707                ulong bauds[4][16] = {
 708                        { /* slowbaud */
 709                                0,      50,     75,     110,
 710                                134,    150,    200,    300,
 711                                600,    1200,   1800,   2400,
 712                                4800,   9600,   19200,  38400 },
 713                        { /* slowbaud & CBAUDEX */
 714                                0,      57600,  115200, 230400,
 715                                460800, 150,    200,    921600,
 716                                600,    1200,   1800,   2400,
 717                                4800,   9600,   19200,  38400 },
 718                        { /* fastbaud */
 719                                0,      57600,   76800, 115200,
 720                                131657, 153600, 230400, 460800,
 721                                921600, 1200,   1800,   2400,
 722                                4800,   9600,   19200,  38400 },
 723                        { /* fastbaud & CBAUDEX */
 724                                0,      57600,  115200, 230400,
 725                                460800, 150,    200,    921600,
 726                                600,    1200,   1800,   2400,
 727                                4800,   9600,   19200,  38400 }
 728                };
 729
 730                /*
 731                 * Only use the TXPrint baud rate if the terminal
 732                 * unit is NOT open
 733                 */
 734                if (!(ch->ch_tun.un_flags & UN_ISOPEN) &&
 735                    (un->un_type == DGNC_PRINT))
 736                        baud = C_BAUD(ch->ch_pun.un_tty) & 0xff;
 737                else
 738                        baud = C_BAUD(ch->ch_tun.un_tty) & 0xff;
 739
 740                if (ch->ch_c_cflag & CBAUDEX)
 741                        iindex = 1;
 742
 743                if (ch->ch_digi.digi_flags & DIGI_FAST)
 744                        iindex += 2;
 745
 746                jindex = baud;
 747
 748                if ((iindex >= 0) && (iindex < 4) && (jindex >= 0) &&
 749                    (jindex < 16)) {
 750                        baud = bauds[iindex][jindex];
 751                } else {
 752                        baud = 0;
 753                }
 754
 755                if (baud == 0)
 756                        baud = 9600;
 757
 758                /* Handle transition from B0 */
 759                if (ch->ch_flags & CH_BAUD0) {
 760                        ch->ch_flags &= ~(CH_BAUD0);
 761
 762                        /*
 763                         * Bring back up RTS and DTR...
 764                         * Also handle RTS or DTR toggle if set.
 765                         */
 766                        if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE))
 767                                ch->ch_mostat |= (UART_MCR_RTS);
 768                        if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE))
 769                                ch->ch_mostat |= (UART_MCR_DTR);
 770                }
 771        }
 772
 773        if (ch->ch_c_cflag & PARENB)
 774                lcr |= UART_LCR_PARITY;
 775
 776        if (!(ch->ch_c_cflag & PARODD))
 777                lcr |= UART_LCR_EPAR;
 778
 779        /*
 780         * Not all platforms support mark/space parity,
 781         * so this will hide behind an ifdef.
 782         */
 783#ifdef CMSPAR
 784        if (ch->ch_c_cflag & CMSPAR)
 785                lcr |= UART_LCR_SPAR;
 786#endif
 787
 788        if (ch->ch_c_cflag & CSTOPB)
 789                lcr |= UART_LCR_STOP;
 790
 791        switch (ch->ch_c_cflag & CSIZE) {
 792        case CS5:
 793                lcr |= UART_LCR_WLEN5;
 794                break;
 795        case CS6:
 796                lcr |= UART_LCR_WLEN6;
 797                break;
 798        case CS7:
 799                lcr |= UART_LCR_WLEN7;
 800                break;
 801        case CS8:
 802        default:
 803                lcr |= UART_LCR_WLEN8;
 804                break;
 805        }
 806
 807        uart_ier = readb(&ch->ch_cls_uart->ier);
 808        ier =  uart_ier;
 809        uart_lcr = readb(&ch->ch_cls_uart->lcr);
 810
 811        if (baud == 0)
 812                baud = 9600;
 813
 814        quot = ch->ch_bd->bd_dividend / baud;
 815
 816        if (quot != 0 && ch->ch_old_baud != baud) {
 817                ch->ch_old_baud = baud;
 818                writeb(UART_LCR_DLAB, &ch->ch_cls_uart->lcr);
 819                writeb((quot & 0xff), &ch->ch_cls_uart->txrx);
 820                writeb((quot >> 8), &ch->ch_cls_uart->ier);
 821                writeb(lcr, &ch->ch_cls_uart->lcr);
 822        }
 823
 824        if (uart_lcr != lcr)
 825                writeb(lcr, &ch->ch_cls_uart->lcr);
 826
 827        if (ch->ch_c_cflag & CREAD)
 828                ier |= (UART_IER_RDI | UART_IER_RLSI);
 829        else
 830                ier &= ~(UART_IER_RDI | UART_IER_RLSI);
 831
 832        /*
 833         * Have the UART interrupt on modem signal changes ONLY when
 834         * we are in hardware flow control mode, or CLOCAL/FORCEDCD is not set.
 835         */
 836        if ((ch->ch_digi.digi_flags & CTSPACE) ||
 837            (ch->ch_digi.digi_flags & RTSPACE) ||
 838            (ch->ch_c_cflag & CRTSCTS) ||
 839            !(ch->ch_digi.digi_flags & DIGI_FORCEDCD) ||
 840            !(ch->ch_c_cflag & CLOCAL))
 841                ier |= UART_IER_MSI;
 842        else
 843                ier &= ~UART_IER_MSI;
 844
 845        ier |= UART_IER_THRI;
 846
 847        if (ier != uart_ier)
 848                writeb(ier, &ch->ch_cls_uart->ier);
 849
 850        if (ch->ch_digi.digi_flags & CTSPACE || ch->ch_c_cflag & CRTSCTS) {
 851                cls_set_cts_flow_control(ch);
 852        } else if (ch->ch_c_iflag & IXON) {
 853                /*
 854                 * If start/stop is set to disable, then we should
 855                 * disable flow control
 856                 */
 857                if ((ch->ch_startc == _POSIX_VDISABLE) ||
 858                    (ch->ch_stopc == _POSIX_VDISABLE))
 859                        cls_set_no_output_flow_control(ch);
 860                else
 861                        cls_set_ixon_flow_control(ch);
 862        } else {
 863                cls_set_no_output_flow_control(ch);
 864        }
 865
 866        if (ch->ch_digi.digi_flags & RTSPACE || ch->ch_c_cflag & CRTSCTS) {
 867                cls_set_rts_flow_control(ch);
 868        } else if (ch->ch_c_iflag & IXOFF) {
 869                /*
 870                 * If start/stop is set to disable, then we should disable
 871                 * flow control
 872                 */
 873                if ((ch->ch_startc == _POSIX_VDISABLE) ||
 874                    (ch->ch_stopc == _POSIX_VDISABLE))
 875                        cls_set_no_input_flow_control(ch);
 876                else
 877                        cls_set_ixoff_flow_control(ch);
 878        } else {
 879                cls_set_no_input_flow_control(ch);
 880        }
 881
 882        cls_assert_modem_signals(ch);
 883
 884        /* Get current status of the modem signals now */
 885        cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr));
 886}
 887
 888/* Our board poller function. */
 889
 890static void cls_tasklet(unsigned long data)
 891{
 892        struct dgnc_board *bd = (struct dgnc_board *)data;
 893        struct channel_t *ch;
 894        unsigned long flags;
 895        int i;
 896        int state = 0;
 897        int ports = 0;
 898
 899        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
 900                return;
 901
 902        /* Cache a couple board values */
 903        spin_lock_irqsave(&bd->bd_lock, flags);
 904        state = bd->state;
 905        ports = bd->nasync;
 906        spin_unlock_irqrestore(&bd->bd_lock, flags);
 907
 908        /*
 909         * Do NOT allow the interrupt routine to read the intr registers
 910         * Until we release this lock.
 911         */
 912        spin_lock_irqsave(&bd->bd_intr_lock, flags);
 913
 914        /* If board is ready, parse deeper to see if there is anything to do. */
 915
 916        if ((state == BOARD_READY) && (ports > 0)) {
 917                /* Loop on each port */
 918                for (i = 0; i < ports; i++) {
 919                        ch = bd->channels[i];
 920
 921                        /*
 922                         * NOTE: Remember you CANNOT hold any channel
 923                         * locks when calling input.
 924                         * During input processing, its possible we
 925                         * will call ld, which might do callbacks back
 926                         * into us.
 927                         */
 928                        dgnc_input(ch);
 929
 930                        /*
 931                         * Channel lock is grabbed and then released
 932                         * inside this routine.
 933                         */
 934                        cls_copy_data_from_queue_to_uart(ch);
 935                        dgnc_wakeup_writes(ch);
 936
 937                        /* Check carrier function. */
 938
 939                        dgnc_carrier(ch);
 940
 941                        /*
 942                         * The timing check of turning off the break is done
 943                         * inside clear_break()
 944                         */
 945                        if (ch->ch_stop_sending_break)
 946                                cls_clear_break(ch, 0);
 947                }
 948        }
 949
 950        spin_unlock_irqrestore(&bd->bd_intr_lock, flags);
 951}
 952
 953/*
 954 * cls_intr()
 955 *
 956 * Classic specific interrupt handler.
 957 */
 958static irqreturn_t cls_intr(int irq, void *voidbrd)
 959{
 960        struct dgnc_board *brd = voidbrd;
 961        uint i = 0;
 962        unsigned char poll_reg;
 963        unsigned long flags;
 964
 965        /*
 966         * Check to make sure it didn't receive interrupt with a null board
 967         * associated or a board pointer that wasn't ours.
 968         */
 969        if (!brd || brd->magic != DGNC_BOARD_MAGIC)
 970                return IRQ_NONE;
 971
 972        spin_lock_irqsave(&brd->bd_intr_lock, flags);
 973
 974        /*
 975         * Check the board's global interrupt offset to see if we
 976         * we actually do have an interrupt pending for us.
 977         */
 978        poll_reg = readb(brd->re_map_membase + UART_CLASSIC_POLL_ADDR_OFFSET);
 979
 980        /* If 0, no interrupts pending */
 981        if (!poll_reg) {
 982                spin_unlock_irqrestore(&brd->bd_intr_lock, flags);
 983                return IRQ_NONE;
 984        }
 985
 986        /* Parse each port to find out what caused the interrupt */
 987        for (i = 0; i < brd->nasync; i++)
 988                cls_parse_isr(brd, i);
 989
 990        /* Schedule tasklet to more in-depth servicing at a better time. */
 991
 992        tasklet_schedule(&brd->helper_tasklet);
 993
 994        spin_unlock_irqrestore(&brd->bd_intr_lock, flags);
 995
 996        return IRQ_HANDLED;
 997}
 998
 999static void cls_disable_receiver(struct channel_t *ch)
1000{
1001        unsigned char tmp = readb(&ch->ch_cls_uart->ier);
1002
1003        tmp &= ~(UART_IER_RDI);
1004        writeb(tmp, &ch->ch_cls_uart->ier);
1005}
1006
1007static void cls_enable_receiver(struct channel_t *ch)
1008{
1009        unsigned char tmp = readb(&ch->ch_cls_uart->ier);
1010
1011        tmp |= (UART_IER_RDI);
1012        writeb(tmp, &ch->ch_cls_uart->ier);
1013}
1014
1015/*
1016 * This function basically goes to sleep for secs, or until
1017 * it gets signalled that the port has fully drained.
1018 */
1019static int cls_drain(struct tty_struct *tty, uint seconds)
1020{
1021        unsigned long flags;
1022        struct channel_t *ch;
1023        struct un_t *un;
1024
1025        if (!tty || tty->magic != TTY_MAGIC)
1026                return -ENXIO;
1027
1028        un = (struct un_t *)tty->driver_data;
1029        if (!un || un->magic != DGNC_UNIT_MAGIC)
1030                return -ENXIO;
1031
1032        ch = un->un_ch;
1033        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1034                return -ENXIO;
1035
1036        spin_lock_irqsave(&ch->ch_lock, flags);
1037        un->un_flags |= UN_EMPTY;
1038        spin_unlock_irqrestore(&ch->ch_lock, flags);
1039
1040        /* NOTE: Do something with time passed in. */
1041
1042        /* If ret is non-zero, user ctrl-c'ed us */
1043
1044        return wait_event_interruptible(un->un_flags_wait,
1045                                         ((un->un_flags & UN_EMPTY) == 0));
1046}
1047
1048static void cls_send_start_character(struct channel_t *ch)
1049{
1050        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1051                return;
1052
1053        if (ch->ch_startc != _POSIX_VDISABLE) {
1054                ch->ch_xon_sends++;
1055                writeb(ch->ch_startc, &ch->ch_cls_uart->txrx);
1056        }
1057}
1058
1059static void cls_send_stop_character(struct channel_t *ch)
1060{
1061        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1062                return;
1063
1064        if (ch->ch_stopc != _POSIX_VDISABLE) {
1065                ch->ch_xoff_sends++;
1066                writeb(ch->ch_stopc, &ch->ch_cls_uart->txrx);
1067        }
1068}
1069
1070/* Inits UART */
1071static void cls_uart_init(struct channel_t *ch)
1072{
1073        unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
1074        unsigned char isr_fcr = 0;
1075
1076        writeb(0, &ch->ch_cls_uart->ier);
1077
1078        /*
1079         * The Enhanced Register Set may only be accessed when
1080         * the Line Control Register is set to 0xBFh.
1081         */
1082        writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
1083
1084        isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
1085
1086        /* Turn on Enhanced/Extended controls */
1087        isr_fcr |= (UART_EXAR654_EFR_ECB);
1088
1089        writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
1090
1091        /* Write old LCR value back out, which turns enhanced access off */
1092        writeb(lcrb, &ch->ch_cls_uart->lcr);
1093
1094        /* Clear out UART and FIFO */
1095        readb(&ch->ch_cls_uart->txrx);
1096
1097        writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
1098               &ch->ch_cls_uart->isr_fcr);
1099        udelay(10);
1100
1101        ch->ch_flags |= (CH_FIFO_ENABLED | CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
1102
1103        readb(&ch->ch_cls_uart->lsr);
1104        readb(&ch->ch_cls_uart->msr);
1105}
1106
1107/* Turns off UART.  */
1108
1109static void cls_uart_off(struct channel_t *ch)
1110{
1111        writeb(0, &ch->ch_cls_uart->ier);
1112}
1113
1114/*
1115 * cls_get_uarts_bytes_left.
1116 * Returns 0 is nothing left in the FIFO, returns 1 otherwise.
1117 *
1118 * The channel lock MUST be held by the calling function.
1119 */
1120static uint cls_get_uart_bytes_left(struct channel_t *ch)
1121{
1122        unsigned char left = 0;
1123        unsigned char lsr = 0;
1124
1125        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1126                return 0;
1127
1128        lsr = readb(&ch->ch_cls_uart->lsr);
1129
1130        /* Determine whether the Transmitter is empty or not */
1131        if (!(lsr & UART_LSR_TEMT)) {
1132                if (ch->ch_flags & CH_TX_FIFO_EMPTY)
1133                        tasklet_schedule(&ch->ch_bd->helper_tasklet);
1134                left = 1;
1135        } else {
1136                ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
1137                left = 0;
1138        }
1139
1140        return left;
1141}
1142
1143/*
1144 * cls_send_break.
1145 * Starts sending a break thru the UART.
1146 *
1147 * The channel lock MUST be held by the calling function.
1148 */
1149static void cls_send_break(struct channel_t *ch, int msecs)
1150{
1151        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1152                return;
1153
1154        /* If we receive a time of 0, this means turn off the break. */
1155
1156        if (msecs == 0) {
1157                /* Turn break off, and unset some variables */
1158                if (ch->ch_flags & CH_BREAK_SENDING) {
1159                        unsigned char temp = readb(&ch->ch_cls_uart->lcr);
1160
1161                        writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr);
1162                        ch->ch_flags &= ~(CH_BREAK_SENDING);
1163                        ch->ch_stop_sending_break = 0;
1164                }
1165                return;
1166        }
1167
1168        /*
1169         * Set the time we should stop sending the break.
1170         * If we are already sending a break, toss away the existing
1171         * time to stop, and use this new value instead.
1172         */
1173        ch->ch_stop_sending_break = jiffies + dgnc_jiffies_from_ms(msecs);
1174
1175        /* Tell the UART to start sending the break */
1176        if (!(ch->ch_flags & CH_BREAK_SENDING)) {
1177                unsigned char temp = readb(&ch->ch_cls_uart->lcr);
1178
1179                writeb((temp | UART_LCR_SBC), &ch->ch_cls_uart->lcr);
1180                ch->ch_flags |= (CH_BREAK_SENDING);
1181        }
1182}
1183
1184/*
1185 * cls_send_immediate_char.
1186 * Sends a specific character as soon as possible to the UART,
1187 * jumping over any bytes that might be in the write queue.
1188 *
1189 * The channel lock MUST be held by the calling function.
1190 */
1191static void cls_send_immediate_char(struct channel_t *ch, unsigned char c)
1192{
1193        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1194                return;
1195
1196        writeb(c, &ch->ch_cls_uart->txrx);
1197}
1198
1199static void cls_vpd(struct dgnc_board *brd)
1200{
1201        ulong           vpdbase;        /* Start of io base of the card */
1202        u8 __iomem           *re_map_vpdbase;/* Remapped memory of the card */
1203        int i = 0;
1204
1205        vpdbase = pci_resource_start(brd->pdev, 3);
1206
1207        /* No VPD */
1208        if (!vpdbase)
1209                return;
1210
1211        re_map_vpdbase = ioremap(vpdbase, 0x400);
1212
1213        if (!re_map_vpdbase)
1214                return;
1215
1216        /* Store the VPD into our buffer */
1217        for (i = 0; i < 0x40; i++) {
1218                brd->vpd[i] = readb(re_map_vpdbase + i);
1219                pr_info("%x ", brd->vpd[i]);
1220        }
1221        pr_info("\n");
1222
1223        iounmap(re_map_vpdbase);
1224}
1225
1226struct board_ops dgnc_cls_ops = {
1227        .tasklet =                      cls_tasklet,
1228        .intr =                         cls_intr,
1229        .uart_init =                    cls_uart_init,
1230        .uart_off =                     cls_uart_off,
1231        .drain =                        cls_drain,
1232        .param =                        cls_param,
1233        .vpd =                          cls_vpd,
1234        .assert_modem_signals =         cls_assert_modem_signals,
1235        .flush_uart_write =             cls_flush_uart_write,
1236        .flush_uart_read =              cls_flush_uart_read,
1237        .disable_receiver =             cls_disable_receiver,
1238        .enable_receiver =              cls_enable_receiver,
1239        .send_break =                   cls_send_break,
1240        .send_start_character =         cls_send_start_character,
1241        .send_stop_character =          cls_send_stop_character,
1242        .copy_data_from_queue_to_uart = cls_copy_data_from_queue_to_uart,
1243        .get_uart_bytes_left =          cls_get_uart_bytes_left,
1244        .send_immediate_char =          cls_send_immediate_char
1245};
1246