linux/drivers/char/specialix.c
<<
>>
Prefs
   1/*
   2 *      specialix.c  -- specialix IO8+ multiport serial driver.
   3 *
   4 *      Copyright (C) 1997  Roger Wolff (R.E.Wolff@BitWizard.nl)
   5 *      Copyright (C) 1994-1996  Dmitry Gorodchanin (pgmdsg@ibi.com)
   6 *
   7 *      Specialix pays for the development and support of this driver.
   8 *      Please DO contact io8-linux@specialix.co.uk if you require
   9 *      support. But please read the documentation (specialix.txt)
  10 *      first.
  11 *
  12 *      This driver was developped in the BitWizard linux device
  13 *      driver service. If you require a linux device driver for your
  14 *      product, please contact devices@BitWizard.nl for a quote.
  15 *
  16 *      This code is firmly based on the riscom/8 serial driver,
  17 *      written by Dmitry Gorodchanin. The specialix IO8+ card
  18 *      programming information was obtained from the CL-CD1865 Data
  19 *      Book, and Specialix document number 6200059: IO8+ Hardware
  20 *      Functional Specification.
  21 *
  22 *      This program is free software; you can redistribute it and/or
  23 *      modify it under the terms of the GNU General Public License as
  24 *      published by the Free Software Foundation; either version 2 of
  25 *      the License, or (at your option) any later version.
  26 *
  27 *      This program is distributed in the hope that it will be
  28 *      useful, but WITHOUT ANY WARRANTY; without even the implied
  29 *      warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  30 *      PURPOSE.  See the GNU General Public License for more details.
  31 *
  32 *      You should have received a copy of the GNU General Public
  33 *      License along with this program; if not, write to the Free
  34 *      Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
  35 *      USA.
  36 *
  37 * Revision history:
  38 *
  39 * Revision 1.0:  April 1st 1997.
  40 *                Initial release for alpha testing.
  41 * Revision 1.1:  April 14th 1997.
  42 *                Incorporated Richard Hudsons suggestions,
  43 *                removed some debugging printk's.
  44 * Revision 1.2:  April 15th 1997.
  45 *                Ported to 2.1.x kernels.
  46 * Revision 1.3:  April 17th 1997
  47 *                Backported to 2.0. (Compatibility macros).
  48 * Revision 1.4:  April 18th 1997
  49 *                Fixed DTR/RTS bug that caused the card to indicate
  50 *                "don't send data" to a modem after the password prompt.
  51 *                Fixed bug for premature (fake) interrupts.
  52 * Revision 1.5:  April 19th 1997
  53 *                fixed a minor typo in the header file, cleanup a little.
  54 *                performance warnings are now MAXed at once per minute.
  55 * Revision 1.6:  May 23 1997
  56 *                Changed the specialix=... format to include interrupt.
  57 * Revision 1.7:  May 27 1997
  58 *                Made many more debug printk's a compile time option.
  59 * Revision 1.8:  Jul 1  1997
  60 *                port to linux-2.1.43 kernel.
  61 * Revision 1.9:  Oct 9  1998
  62 *                Added stuff for the IO8+/PCI version.
  63 * Revision 1.10: Oct 22  1999 / Jan 21 2000.
  64 *                Added stuff for setserial.
  65 *                Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr)
  66 *
  67 */
  68
  69#define VERSION "1.11"
  70
  71
  72/*
  73 * There is a bunch of documentation about the card, jumpers, config
  74 * settings, restrictions, cables, device names and numbers in
  75 * Documentation/serial/specialix.txt
  76 */
  77
  78#include <linux/module.h>
  79
  80#include <linux/io.h>
  81#include <linux/kernel.h>
  82#include <linux/sched.h>
  83#include <linux/ioport.h>
  84#include <linux/interrupt.h>
  85#include <linux/errno.h>
  86#include <linux/tty.h>
  87#include <linux/tty_flip.h>
  88#include <linux/mm.h>
  89#include <linux/serial.h>
  90#include <linux/smp_lock.h>
  91#include <linux/fcntl.h>
  92#include <linux/major.h>
  93#include <linux/delay.h>
  94#include <linux/pci.h>
  95#include <linux/init.h>
  96#include <linux/uaccess.h>
  97
  98#include "specialix_io8.h"
  99#include "cd1865.h"
 100
 101
 102/*
 103   This driver can spew a whole lot of debugging output at you. If you
 104   need maximum performance, you should disable the DEBUG define. To
 105   aid in debugging in the field, I'm leaving the compile-time debug
 106   features enabled, and disable them "runtime". That allows me to
 107   instruct people with problems to enable debugging without requiring
 108   them to recompile...
 109*/
 110#define DEBUG
 111
 112static int sx_debug;
 113static int sx_rxfifo = SPECIALIX_RXFIFO;
 114static int sx_rtscts;
 115
 116#ifdef DEBUG
 117#define dprintk(f, str...) if (sx_debug & f) printk(str)
 118#else
 119#define dprintk(f, str...) /* nothing */
 120#endif
 121
 122#define SX_DEBUG_FLOW    0x0001
 123#define SX_DEBUG_DATA    0x0002
 124#define SX_DEBUG_PROBE   0x0004
 125#define SX_DEBUG_CHAN    0x0008
 126#define SX_DEBUG_INIT    0x0010
 127#define SX_DEBUG_RX      0x0020
 128#define SX_DEBUG_TX      0x0040
 129#define SX_DEBUG_IRQ     0x0080
 130#define SX_DEBUG_OPEN    0x0100
 131#define SX_DEBUG_TERMIOS 0x0200
 132#define SX_DEBUG_SIGNALS 0x0400
 133#define SX_DEBUG_FIFO    0x0800
 134
 135
 136#define func_enter() dprintk(SX_DEBUG_FLOW, "io8: enter %s\n", __func__)
 137#define func_exit()  dprintk(SX_DEBUG_FLOW, "io8: exit  %s\n", __func__)
 138
 139
 140/* Configurable options: */
 141
 142/* Am I paranoid or not ? ;-) */
 143#define SPECIALIX_PARANOIA_CHECK
 144
 145/*
 146 * The following defines are mostly for testing purposes. But if you need
 147 * some nice reporting in your syslog, you can define them also.
 148 */
 149#undef SX_REPORT_FIFO
 150#undef SX_REPORT_OVERRUN
 151
 152
 153
 154
 155#define SPECIALIX_LEGAL_FLAGS \
 156        (ASYNC_HUP_NOTIFY   | ASYNC_SAK          | ASYNC_SPLIT_TERMIOS   | \
 157         ASYNC_SPD_HI       | ASYNC_SPEED_VHI    | ASYNC_SESSION_LOCKOUT | \
 158         ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
 159
 160static struct tty_driver *specialix_driver;
 161
 162static struct specialix_board sx_board[SX_NBOARD] =  {
 163        { 0, SX_IOBASE1,  9, },
 164        { 0, SX_IOBASE2, 11, },
 165        { 0, SX_IOBASE3, 12, },
 166        { 0, SX_IOBASE4, 15, },
 167};
 168
 169static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
 170
 171
 172static int sx_paranoia_check(struct specialix_port const *port,
 173                                    char *name, const char *routine)
 174{
 175#ifdef SPECIALIX_PARANOIA_CHECK
 176        static const char *badmagic = KERN_ERR
 177          "sx: Warning: bad specialix port magic number for device %s in %s\n";
 178        static const char *badinfo = KERN_ERR
 179          "sx: Warning: null specialix port for device %s in %s\n";
 180
 181        if (!port) {
 182                printk(badinfo, name, routine);
 183                return 1;
 184        }
 185        if (port->magic != SPECIALIX_MAGIC) {
 186                printk(badmagic, name, routine);
 187                return 1;
 188        }
 189#endif
 190        return 0;
 191}
 192
 193
 194/*
 195 *
 196 *  Service functions for specialix IO8+ driver.
 197 *
 198 */
 199
 200/* Get board number from pointer */
 201static inline int board_No(struct specialix_board *bp)
 202{
 203        return bp - sx_board;
 204}
 205
 206
 207/* Get port number from pointer */
 208static inline int port_No(struct specialix_port const *port)
 209{
 210        return SX_PORT(port - sx_port);
 211}
 212
 213
 214/* Get pointer to board from pointer to port */
 215static inline struct specialix_board *port_Board(
 216                                        struct specialix_port const *port)
 217{
 218        return &sx_board[SX_BOARD(port - sx_port)];
 219}
 220
 221
 222/* Input Byte from CL CD186x register */
 223static inline unsigned char sx_in(struct specialix_board *bp,
 224                                                        unsigned short reg)
 225{
 226        bp->reg = reg | 0x80;
 227        outb(reg | 0x80, bp->base + SX_ADDR_REG);
 228        return inb(bp->base + SX_DATA_REG);
 229}
 230
 231
 232/* Output Byte to CL CD186x register */
 233static inline void sx_out(struct specialix_board *bp, unsigned short reg,
 234                          unsigned char val)
 235{
 236        bp->reg = reg | 0x80;
 237        outb(reg | 0x80, bp->base + SX_ADDR_REG);
 238        outb(val, bp->base + SX_DATA_REG);
 239}
 240
 241
 242/* Input Byte from CL CD186x register */
 243static inline unsigned char sx_in_off(struct specialix_board *bp,
 244                                unsigned short reg)
 245{
 246        bp->reg = reg;
 247        outb(reg, bp->base + SX_ADDR_REG);
 248        return inb(bp->base + SX_DATA_REG);
 249}
 250
 251
 252/* Output Byte to CL CD186x register */
 253static inline void sx_out_off(struct specialix_board  *bp,
 254                                unsigned short reg, unsigned char val)
 255{
 256        bp->reg = reg;
 257        outb(reg, bp->base + SX_ADDR_REG);
 258        outb(val, bp->base + SX_DATA_REG);
 259}
 260
 261
 262/* Wait for Channel Command Register ready */
 263static void sx_wait_CCR(struct specialix_board  *bp)
 264{
 265        unsigned long delay, flags;
 266        unsigned char ccr;
 267
 268        for (delay = SX_CCR_TIMEOUT; delay; delay--) {
 269                spin_lock_irqsave(&bp->lock, flags);
 270                ccr = sx_in(bp, CD186x_CCR);
 271                spin_unlock_irqrestore(&bp->lock, flags);
 272                if (!ccr)
 273                        return;
 274                udelay(1);
 275        }
 276
 277        printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
 278}
 279
 280
 281/* Wait for Channel Command Register ready */
 282static void sx_wait_CCR_off(struct specialix_board  *bp)
 283{
 284        unsigned long delay;
 285        unsigned char crr;
 286        unsigned long flags;
 287
 288        for (delay = SX_CCR_TIMEOUT; delay; delay--) {
 289                spin_lock_irqsave(&bp->lock, flags);
 290                crr = sx_in_off(bp, CD186x_CCR);
 291                spin_unlock_irqrestore(&bp->lock, flags);
 292                if (!crr)
 293                        return;
 294                udelay(1);
 295        }
 296
 297        printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
 298}
 299
 300
 301/*
 302 *  specialix IO8+ IO range functions.
 303 */
 304
 305static int sx_request_io_range(struct specialix_board *bp)
 306{
 307        return request_region(bp->base,
 308                bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
 309                "specialix IO8+") == NULL;
 310}
 311
 312
 313static void sx_release_io_range(struct specialix_board *bp)
 314{
 315        release_region(bp->base, bp->flags & SX_BOARD_IS_PCI ?
 316                                        SX_PCI_IO_SPACE : SX_IO_SPACE);
 317}
 318
 319
 320/* Set the IRQ using the RTS lines that run to the PAL on the board.... */
 321static int sx_set_irq(struct specialix_board *bp)
 322{
 323        int virq;
 324        int i;
 325        unsigned long flags;
 326
 327        if (bp->flags & SX_BOARD_IS_PCI)
 328                return 1;
 329        switch (bp->irq) {
 330        /* In the same order as in the docs... */
 331        case 15:
 332                virq = 0;
 333                break;
 334        case 12:
 335                virq = 1;
 336                break;
 337        case 11:
 338                virq = 2;
 339                break;
 340        case 9:
 341                virq = 3;
 342                break;
 343        default:printk(KERN_ERR
 344                            "Speclialix: cannot set irq to %d.\n", bp->irq);
 345                return 0;
 346        }
 347        spin_lock_irqsave(&bp->lock, flags);
 348        for (i = 0; i < 2; i++) {
 349                sx_out(bp, CD186x_CAR, i);
 350                sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
 351        }
 352        spin_unlock_irqrestore(&bp->lock, flags);
 353        return 1;
 354}
 355
 356
 357/* Reset and setup CD186x chip */
 358static int sx_init_CD186x(struct specialix_board  *bp)
 359{
 360        unsigned long flags;
 361        int scaler;
 362        int rv = 1;
 363
 364        func_enter();
 365        sx_wait_CCR_off(bp);                       /* Wait for CCR ready        */
 366        spin_lock_irqsave(&bp->lock, flags);
 367        sx_out_off(bp, CD186x_CCR, CCR_HARDRESET);      /* Reset CD186x chip          */
 368        spin_unlock_irqrestore(&bp->lock, flags);
 369        msleep(50);                                     /* Delay 0.05 sec            */
 370        spin_lock_irqsave(&bp->lock, flags);
 371        sx_out_off(bp, CD186x_GIVR, SX_ID);             /* Set ID for this chip      */
 372        sx_out_off(bp, CD186x_GICR, 0);                 /* Clear all bits            */
 373        sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT);      /* Prio for modem intr       */
 374        sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT);      /* Prio for transmitter intr */
 375        sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT);      /* Prio for receiver intr    */
 376        /* Set RegAckEn */
 377        sx_out_off(bp, CD186x_SRCR, sx_in(bp, CD186x_SRCR) | SRCR_REGACKEN);
 378
 379        /* Setting up prescaler. We need 4 ticks per 1 ms */
 380        scaler =  SX_OSCFREQ/SPECIALIX_TPS;
 381
 382        sx_out_off(bp, CD186x_PPRH, scaler >> 8);
 383        sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
 384        spin_unlock_irqrestore(&bp->lock, flags);
 385
 386        if (!sx_set_irq(bp)) {
 387                /* Figure out how to pass this along... */
 388                printk(KERN_ERR "Cannot set irq to %d.\n", bp->irq);
 389                rv = 0;
 390        }
 391
 392        func_exit();
 393        return rv;
 394}
 395
 396
 397static int read_cross_byte(struct specialix_board *bp, int reg, int bit)
 398{
 399        int i;
 400        int t;
 401        unsigned long flags;
 402
 403        spin_lock_irqsave(&bp->lock, flags);
 404        for (i = 0, t = 0; i < 8; i++) {
 405                sx_out_off(bp, CD186x_CAR, i);
 406                if (sx_in_off(bp, reg) & bit)
 407                        t |= 1 << i;
 408        }
 409        spin_unlock_irqrestore(&bp->lock, flags);
 410
 411        return t;
 412}
 413
 414
 415/* Main probing routine, also sets irq. */
 416static int sx_probe(struct specialix_board *bp)
 417{
 418        unsigned char val1, val2;
 419        int rev;
 420        int chip;
 421
 422        func_enter();
 423
 424        if (sx_request_io_range(bp)) {
 425                func_exit();
 426                return 1;
 427        }
 428
 429        /* Are the I/O ports here ? */
 430        sx_out_off(bp, CD186x_PPRL, 0x5a);
 431        udelay(1);
 432        val1 = sx_in_off(bp, CD186x_PPRL);
 433
 434        sx_out_off(bp, CD186x_PPRL, 0xa5);
 435        udelay(1);
 436        val2 = sx_in_off(bp, CD186x_PPRL);
 437
 438
 439        if (val1 != 0x5a || val2 != 0xa5) {
 440                printk(KERN_INFO
 441                        "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
 442                                                board_No(bp), bp->base);
 443                sx_release_io_range(bp);
 444                func_exit();
 445                return 1;
 446        }
 447
 448        /* Check the DSR lines that Specialix uses as board
 449           identification */
 450        val1 = read_cross_byte(bp, CD186x_MSVR, MSVR_DSR);
 451        val2 = read_cross_byte(bp, CD186x_MSVR, MSVR_RTS);
 452        dprintk(SX_DEBUG_INIT,
 453                        "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
 454                                        board_No(bp), val1, val2);
 455
 456        /* They managed to switch the bit order between the docs and
 457           the IO8+ card. The new PCI card now conforms to old docs.
 458           They changed the PCI docs to reflect the situation on the
 459           old card. */
 460        val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
 461        if (val1 != val2) {
 462                printk(KERN_INFO
 463                  "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
 464                       board_No(bp), val2, bp->base, val1);
 465                sx_release_io_range(bp);
 466                func_exit();
 467                return 1;
 468        }
 469
 470
 471        /* Reset CD186x again  */
 472        if (!sx_init_CD186x(bp)) {
 473                sx_release_io_range(bp);
 474                func_exit();
 475                return 1;
 476        }
 477
 478        sx_request_io_range(bp);
 479        bp->flags |= SX_BOARD_PRESENT;
 480
 481        /* Chip           revcode   pkgtype
 482                          GFRCR     SRCR bit 7
 483           CD180 rev B    0x81      0
 484           CD180 rev C    0x82      0
 485           CD1864 rev A   0x82      1
 486           CD1865 rev A   0x83      1  -- Do not use!!! Does not work.
 487           CD1865 rev B   0x84      1
 488         -- Thanks to Gwen Wang, Cirrus Logic.
 489         */
 490
 491        switch (sx_in_off(bp, CD186x_GFRCR)) {
 492        case 0x82:
 493                chip = 1864;
 494                rev = 'A';
 495                break;
 496        case 0x83:
 497                chip = 1865;
 498                rev = 'A';
 499                break;
 500        case 0x84:
 501                chip = 1865;
 502                rev = 'B';
 503                break;
 504        case 0x85:
 505                chip = 1865;
 506                rev = 'C';
 507                break; /* Does not exist at this time */
 508        default:
 509                chip = -1;
 510                rev = 'x';
 511        }
 512
 513        dprintk(SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR));
 514
 515        printk(KERN_INFO
 516    "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
 517                                board_No(bp), bp->base, bp->irq, chip, rev);
 518
 519        func_exit();
 520        return 0;
 521}
 522
 523/*
 524 *
 525 *  Interrupt processing routines.
 526 * */
 527
 528static struct specialix_port *sx_get_port(struct specialix_board *bp,
 529                                               unsigned char const *what)
 530{
 531        unsigned char channel;
 532        struct specialix_port *port = NULL;
 533
 534        channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
 535        dprintk(SX_DEBUG_CHAN, "channel: %d\n", channel);
 536        if (channel < CD186x_NCH) {
 537                port = &sx_port[board_No(bp) * SX_NPORT + channel];
 538                dprintk(SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n",
 539                        board_No(bp) * SX_NPORT + channel,  port,
 540                        port->port.flags & ASYNC_INITIALIZED);
 541
 542                if (port->port.flags & ASYNC_INITIALIZED) {
 543                        dprintk(SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
 544                        func_exit();
 545                        return port;
 546                }
 547        }
 548        printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
 549               board_No(bp), what, channel);
 550        return NULL;
 551}
 552
 553
 554static void sx_receive_exc(struct specialix_board *bp)
 555{
 556        struct specialix_port *port;
 557        struct tty_struct *tty;
 558        unsigned char status;
 559        unsigned char ch, flag;
 560
 561        func_enter();
 562
 563        port = sx_get_port(bp, "Receive");
 564        if (!port) {
 565                dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n");
 566                func_exit();
 567                return;
 568        }
 569        tty = port->port.tty;
 570
 571        status = sx_in(bp, CD186x_RCSR);
 572
 573        dprintk(SX_DEBUG_RX, "status: 0x%x\n", status);
 574        if (status & RCSR_OE) {
 575                port->overrun++;
 576                dprintk(SX_DEBUG_FIFO,
 577                        "sx%d: port %d: Overrun. Total %ld overruns.\n",
 578                                board_No(bp), port_No(port), port->overrun);
 579        }
 580        status &= port->mark_mask;
 581
 582        /* This flip buffer check needs to be below the reading of the
 583           status register to reset the chip's IRQ.... */
 584        if (tty_buffer_request_room(tty, 1) == 0) {
 585                dprintk(SX_DEBUG_FIFO,
 586                    "sx%d: port %d: Working around flip buffer overflow.\n",
 587                                        board_No(bp), port_No(port));
 588                func_exit();
 589                return;
 590        }
 591
 592        ch = sx_in(bp, CD186x_RDR);
 593        if (!status) {
 594                func_exit();
 595                return;
 596        }
 597        if (status & RCSR_TOUT) {
 598                printk(KERN_INFO
 599                    "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
 600                                        board_No(bp), port_No(port));
 601                func_exit();
 602                return;
 603
 604        } else if (status & RCSR_BREAK) {
 605                dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
 606                       board_No(bp), port_No(port));
 607                flag = TTY_BREAK;
 608                if (port->port.flags & ASYNC_SAK)
 609                        do_SAK(tty);
 610
 611        } else if (status & RCSR_PE)
 612                flag = TTY_PARITY;
 613
 614        else if (status & RCSR_FE)
 615                flag = TTY_FRAME;
 616
 617        else if (status & RCSR_OE)
 618                flag = TTY_OVERRUN;
 619
 620        else
 621                flag = TTY_NORMAL;
 622
 623        if (tty_insert_flip_char(tty, ch, flag))
 624                tty_flip_buffer_push(tty);
 625        func_exit();
 626}
 627
 628
 629static void sx_receive(struct specialix_board *bp)
 630{
 631        struct specialix_port *port;
 632        struct tty_struct *tty;
 633        unsigned char count;
 634
 635        func_enter();
 636
 637        port = sx_get_port(bp, "Receive");
 638        if (port == NULL) {
 639                dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n");
 640                func_exit();
 641                return;
 642        }
 643        tty = port->port.tty;
 644
 645        count = sx_in(bp, CD186x_RDCR);
 646        dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
 647        port->hits[count > 8 ? 9 : count]++;
 648
 649        tty_buffer_request_room(tty, count);
 650
 651        while (count--)
 652                tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL);
 653        tty_flip_buffer_push(tty);
 654        func_exit();
 655}
 656
 657
 658static void sx_transmit(struct specialix_board *bp)
 659{
 660        struct specialix_port *port;
 661        struct tty_struct *tty;
 662        unsigned char count;
 663
 664        func_enter();
 665        port = sx_get_port(bp, "Transmit");
 666        if (port == NULL) {
 667                func_exit();
 668                return;
 669        }
 670        dprintk(SX_DEBUG_TX, "port: %p\n", port);
 671        tty = port->port.tty;
 672
 673        if (port->IER & IER_TXEMPTY) {
 674                /* FIFO drained */
 675                sx_out(bp, CD186x_CAR, port_No(port));
 676                port->IER &= ~IER_TXEMPTY;
 677                sx_out(bp, CD186x_IER, port->IER);
 678                func_exit();
 679                return;
 680        }
 681
 682        if ((port->xmit_cnt <= 0 && !port->break_length)
 683            || tty->stopped || tty->hw_stopped) {
 684                sx_out(bp, CD186x_CAR, port_No(port));
 685                port->IER &= ~IER_TXRDY;
 686                sx_out(bp, CD186x_IER, port->IER);
 687                func_exit();
 688                return;
 689        }
 690
 691        if (port->break_length) {
 692                if (port->break_length > 0) {
 693                        if (port->COR2 & COR2_ETC) {
 694                                sx_out(bp, CD186x_TDR, CD186x_C_ESC);
 695                                sx_out(bp, CD186x_TDR, CD186x_C_SBRK);
 696                                port->COR2 &= ~COR2_ETC;
 697                        }
 698                        count = min_t(int, port->break_length, 0xff);
 699                        sx_out(bp, CD186x_TDR, CD186x_C_ESC);
 700                        sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
 701                        sx_out(bp, CD186x_TDR, count);
 702                        port->break_length -= count;
 703                        if (port->break_length == 0)
 704                                port->break_length--;
 705                } else {
 706                        sx_out(bp, CD186x_TDR, CD186x_C_ESC);
 707                        sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
 708                        sx_out(bp, CD186x_COR2, port->COR2);
 709                        sx_wait_CCR(bp);
 710                        sx_out(bp, CD186x_CCR, CCR_CORCHG2);
 711                        port->break_length = 0;
 712                }
 713
 714                func_exit();
 715                return;
 716        }
 717
 718        count = CD186x_NFIFO;
 719        do {
 720                sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
 721                port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
 722                if (--port->xmit_cnt <= 0)
 723                        break;
 724        } while (--count > 0);
 725
 726        if (port->xmit_cnt <= 0) {
 727                sx_out(bp, CD186x_CAR, port_No(port));
 728                port->IER &= ~IER_TXRDY;
 729                sx_out(bp, CD186x_IER, port->IER);
 730        }
 731        if (port->xmit_cnt <= port->wakeup_chars)
 732                tty_wakeup(tty);
 733
 734        func_exit();
 735}
 736
 737
 738static void sx_check_modem(struct specialix_board *bp)
 739{
 740        struct specialix_port *port;
 741        struct tty_struct *tty;
 742        unsigned char mcr;
 743        int msvr_cd;
 744
 745        dprintk(SX_DEBUG_SIGNALS, "Modem intr. ");
 746        port = sx_get_port(bp, "Modem");
 747        if (port == NULL)
 748                return;
 749
 750        tty = port->port.tty;
 751
 752        mcr = sx_in(bp, CD186x_MCR);
 753
 754        if ((mcr & MCR_CDCHG)) {
 755                dprintk(SX_DEBUG_SIGNALS, "CD just changed... ");
 756                msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
 757                if (msvr_cd) {
 758                        dprintk(SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
 759                        wake_up_interruptible(&port->port.open_wait);
 760                } else {
 761                        dprintk(SX_DEBUG_SIGNALS, "Sending HUP.\n");
 762                        tty_hangup(tty);
 763                }
 764        }
 765
 766#ifdef SPECIALIX_BRAIN_DAMAGED_CTS
 767        if (mcr & MCR_CTSCHG) {
 768                if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
 769                        tty->hw_stopped = 0;
 770                        port->IER |= IER_TXRDY;
 771                        if (port->xmit_cnt <= port->wakeup_chars)
 772                                tty_wakeup(tty);
 773                } else {
 774                        tty->hw_stopped = 1;
 775                        port->IER &= ~IER_TXRDY;
 776                }
 777                sx_out(bp, CD186x_IER, port->IER);
 778        }
 779        if (mcr & MCR_DSSXHG) {
 780                if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
 781                        tty->hw_stopped = 0;
 782                        port->IER |= IER_TXRDY;
 783                        if (port->xmit_cnt <= port->wakeup_chars)
 784                                tty_wakeup(tty);
 785                } else {
 786                        tty->hw_stopped = 1;
 787                        port->IER &= ~IER_TXRDY;
 788                }
 789                sx_out(bp, CD186x_IER, port->IER);
 790        }
 791#endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
 792
 793        /* Clear change bits */
 794        sx_out(bp, CD186x_MCR, 0);
 795}
 796
 797
 798/* The main interrupt processing routine */
 799static irqreturn_t sx_interrupt(int dummy, void *dev_id)
 800{
 801        unsigned char status;
 802        unsigned char ack;
 803        struct specialix_board *bp = dev_id;
 804        unsigned long loop = 0;
 805        int saved_reg;
 806        unsigned long flags;
 807
 808        func_enter();
 809
 810        spin_lock_irqsave(&bp->lock, flags);
 811
 812        dprintk(SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__,
 813                port_No(sx_get_port(bp, "INT")),
 814                SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
 815        if (!(bp->flags & SX_BOARD_ACTIVE)) {
 816                dprintk(SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n",
 817                                                                bp->irq);
 818                spin_unlock_irqrestore(&bp->lock, flags);
 819                func_exit();
 820                return IRQ_NONE;
 821        }
 822
 823        saved_reg = bp->reg;
 824
 825        while (++loop < 16) {
 826                status = sx_in(bp, CD186x_SRSR) &
 827                                (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint);
 828                if (status == 0)
 829                        break;
 830                if (status & SRSR_RREQint) {
 831                        ack = sx_in(bp, CD186x_RRAR);
 832
 833                        if (ack == (SX_ID | GIVR_IT_RCV))
 834                                sx_receive(bp);
 835                        else if (ack == (SX_ID | GIVR_IT_REXC))
 836                                sx_receive_exc(bp);
 837                        else
 838                                printk(KERN_ERR
 839                                "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
 840                                                board_No(bp), status, ack);
 841
 842                } else if (status & SRSR_TREQint) {
 843                        ack = sx_in(bp, CD186x_TRAR);
 844
 845                        if (ack == (SX_ID | GIVR_IT_TX))
 846                                sx_transmit(bp);
 847                        else
 848                                printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
 849                                        board_No(bp), status, ack,
 850                                        port_No(sx_get_port(bp, "Int")));
 851                } else if (status & SRSR_MREQint) {
 852                        ack = sx_in(bp, CD186x_MRAR);
 853
 854                        if (ack == (SX_ID | GIVR_IT_MODEM))
 855                                sx_check_modem(bp);
 856                        else
 857                                printk(KERN_ERR
 858                                  "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
 859                                       board_No(bp), status, ack);
 860
 861                }
 862
 863                sx_out(bp, CD186x_EOIR, 0);   /* Mark end of interrupt */
 864        }
 865        bp->reg = saved_reg;
 866        outb(bp->reg, bp->base + SX_ADDR_REG);
 867        spin_unlock_irqrestore(&bp->lock, flags);
 868        func_exit();
 869        return IRQ_HANDLED;
 870}
 871
 872
 873/*
 874 *  Routines for open & close processing.
 875 */
 876
 877static void turn_ints_off(struct specialix_board *bp)
 878{
 879        unsigned long flags;
 880
 881        func_enter();
 882        spin_lock_irqsave(&bp->lock, flags);
 883        (void) sx_in_off(bp, 0); /* Turn off interrupts. */
 884        spin_unlock_irqrestore(&bp->lock, flags);
 885
 886        func_exit();
 887}
 888
 889static void turn_ints_on(struct specialix_board *bp)
 890{
 891        unsigned long flags;
 892
 893        func_enter();
 894
 895        spin_lock_irqsave(&bp->lock, flags);
 896        (void) sx_in(bp, 0); /* Turn ON interrupts. */
 897        spin_unlock_irqrestore(&bp->lock, flags);
 898
 899        func_exit();
 900}
 901
 902
 903/* Called with disabled interrupts */
 904static int sx_setup_board(struct specialix_board *bp)
 905{
 906        int error;
 907
 908        if (bp->flags & SX_BOARD_ACTIVE)
 909                return 0;
 910
 911        if (bp->flags & SX_BOARD_IS_PCI)
 912                error = request_irq(bp->irq, sx_interrupt,
 913                        IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp);
 914        else
 915                error = request_irq(bp->irq, sx_interrupt,
 916                        IRQF_DISABLED, "specialix IO8+", bp);
 917
 918        if (error)
 919                return error;
 920
 921        turn_ints_on(bp);
 922        bp->flags |= SX_BOARD_ACTIVE;
 923
 924        return 0;
 925}
 926
 927
 928/* Called with disabled interrupts */
 929static void sx_shutdown_board(struct specialix_board *bp)
 930{
 931        func_enter();
 932
 933        if (!(bp->flags & SX_BOARD_ACTIVE)) {
 934                func_exit();
 935                return;
 936        }
 937
 938        bp->flags &= ~SX_BOARD_ACTIVE;
 939
 940        dprintk(SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
 941                 bp->irq, board_No(bp));
 942        free_irq(bp->irq, bp);
 943        turn_ints_off(bp);
 944        func_exit();
 945}
 946
 947static unsigned int sx_crtscts(struct tty_struct *tty)
 948{
 949        if (sx_rtscts)
 950                return C_CRTSCTS(tty);
 951        return 1;
 952}
 953
 954/*
 955 * Setting up port characteristics.
 956 * Must be called with disabled interrupts
 957 */
 958static void sx_change_speed(struct specialix_board *bp,
 959                                                struct specialix_port *port)
 960{
 961        struct tty_struct *tty;
 962        unsigned long baud;
 963        long tmp;
 964        unsigned char cor1 = 0, cor3 = 0;
 965        unsigned char mcor1 = 0, mcor2 = 0;
 966        static unsigned long again;
 967        unsigned long flags;
 968
 969        func_enter();
 970
 971        tty = port->port.tty;
 972        if (!tty || !tty->termios) {
 973                func_exit();
 974                return;
 975        }
 976
 977        port->IER  = 0;
 978        port->COR2 = 0;
 979        /* Select port on the board */
 980        spin_lock_irqsave(&bp->lock, flags);
 981        sx_out(bp, CD186x_CAR, port_No(port));
 982
 983        /* The Specialix board doens't implement the RTS lines.
 984           They are used to set the IRQ level. Don't touch them. */
 985        if (sx_crtscts(tty))
 986                port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
 987        else
 988                port->MSVR =  (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
 989        spin_unlock_irqrestore(&bp->lock, flags);
 990        dprintk(SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
 991        baud = tty_get_baud_rate(tty);
 992
 993        if (baud == 38400) {
 994                if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
 995                        baud = 57600;
 996                if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
 997                        baud = 115200;
 998        }
 999
1000        if (!baud) {
1001                /* Drop DTR & exit */
1002                dprintk(SX_DEBUG_TERMIOS, "Dropping DTR...  Hmm....\n");
1003                if (!sx_crtscts(tty)) {
1004                        port->MSVR &= ~MSVR_DTR;
1005                        spin_lock_irqsave(&bp->lock, flags);
1006                        sx_out(bp, CD186x_MSVR, port->MSVR);
1007                        spin_unlock_irqrestore(&bp->lock, flags);
1008                } else
1009                        dprintk(SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1010                return;
1011        } else {
1012                /* Set DTR on */
1013                if (!sx_crtscts(tty))
1014                        port->MSVR |= MSVR_DTR;
1015        }
1016
1017        /*
1018         * Now we must calculate some speed depended things
1019         */
1020
1021        /* Set baud rate for port */
1022        tmp = port->custom_divisor ;
1023        if (tmp)
1024                printk(KERN_INFO
1025                        "sx%d: Using custom baud rate divisor %ld. \n"
1026                        "This is an untested option, please be careful.\n",
1027                                                        port_No(port), tmp);
1028        else
1029                tmp = (((SX_OSCFREQ + baud/2) / baud + CD186x_TPC/2) /
1030                                                                CD186x_TPC);
1031
1032        if (tmp < 0x10 && time_before(again, jiffies)) {
1033                again = jiffies + HZ * 60;
1034                /* Page 48 of version 2.0 of the CL-CD1865 databook */
1035                if (tmp >= 12) {
1036                        printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1037                                "Performance degradation is possible.\n"
1038                                "Read specialix.txt for more info.\n",
1039                                                port_No(port), tmp);
1040                } else {
1041                        printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1042                "Warning: overstressing Cirrus chip. This might not work.\n"
1043                "Read specialix.txt for more info.\n", port_No(port), tmp);
1044                }
1045        }
1046        spin_lock_irqsave(&bp->lock, flags);
1047        sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1048        sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1049        sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1050        sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1051        spin_unlock_irqrestore(&bp->lock, flags);
1052        if (port->custom_divisor)
1053                baud = (SX_OSCFREQ + port->custom_divisor/2) /
1054                                                        port->custom_divisor;
1055        baud = (baud + 5) / 10;         /* Estimated CPS */
1056
1057        /* Two timer ticks seems enough to wakeup something like SLIP driver */
1058        tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1059        port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1060                                              SERIAL_XMIT_SIZE - 1 : tmp);
1061
1062        /* Receiver timeout will be transmission time for 1.5 chars */
1063        tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1064        tmp = (tmp > 0xff) ? 0xff : tmp;
1065        spin_lock_irqsave(&bp->lock, flags);
1066        sx_out(bp, CD186x_RTPR, tmp);
1067        spin_unlock_irqrestore(&bp->lock, flags);
1068        switch (C_CSIZE(tty)) {
1069        case CS5:
1070                cor1 |= COR1_5BITS;
1071                break;
1072        case CS6:
1073                cor1 |= COR1_6BITS;
1074                break;
1075        case CS7:
1076                cor1 |= COR1_7BITS;
1077                break;
1078        case CS8:
1079                cor1 |= COR1_8BITS;
1080                break;
1081        }
1082
1083        if (C_CSTOPB(tty))
1084                cor1 |= COR1_2SB;
1085
1086        cor1 |= COR1_IGNORE;
1087        if (C_PARENB(tty)) {
1088                cor1 |= COR1_NORMPAR;
1089                if (C_PARODD(tty))
1090                        cor1 |= COR1_ODDP;
1091                if (I_INPCK(tty))
1092                        cor1 &= ~COR1_IGNORE;
1093        }
1094        /* Set marking of some errors */
1095        port->mark_mask = RCSR_OE | RCSR_TOUT;
1096        if (I_INPCK(tty))
1097                port->mark_mask |= RCSR_FE | RCSR_PE;
1098        if (I_BRKINT(tty) || I_PARMRK(tty))
1099                port->mark_mask |= RCSR_BREAK;
1100        if (I_IGNPAR(tty))
1101                port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1102        if (I_IGNBRK(tty)) {
1103                port->mark_mask &= ~RCSR_BREAK;
1104                if (I_IGNPAR(tty))
1105                        /* Real raw mode. Ignore all */
1106                        port->mark_mask &= ~RCSR_OE;
1107        }
1108        /* Enable Hardware Flow Control */
1109        if (C_CRTSCTS(tty)) {
1110#ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1111                port->IER |= IER_DSR | IER_CTS;
1112                mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1113                mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1114                spin_lock_irqsave(&bp->lock, flags);
1115                tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) &
1116                                                        (MSVR_CTS|MSVR_DSR));
1117                spin_unlock_irqrestore(&bp->lock, flags);
1118#else
1119                port->COR2 |= COR2_CTSAE;
1120#endif
1121        }
1122        /* Enable Software Flow Control. FIXME: I'm not sure about this */
1123        /* Some people reported that it works, but I still doubt it */
1124        if (I_IXON(tty)) {
1125                port->COR2 |= COR2_TXIBE;
1126                cor3 |= (COR3_FCT | COR3_SCDE);
1127                if (I_IXANY(tty))
1128                        port->COR2 |= COR2_IXM;
1129                spin_lock_irqsave(&bp->lock, flags);
1130                sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1131                sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1132                sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1133                sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1134                spin_unlock_irqrestore(&bp->lock, flags);
1135        }
1136        if (!C_CLOCAL(tty)) {
1137                /* Enable CD check */
1138                port->IER |= IER_CD;
1139                mcor1 |= MCOR1_CDZD;
1140                mcor2 |= MCOR2_CDOD;
1141        }
1142
1143        if (C_CREAD(tty))
1144                /* Enable receiver */
1145                port->IER |= IER_RXD;
1146
1147        /* Set input FIFO size (1-8 bytes) */
1148        cor3 |= sx_rxfifo;
1149        /* Setting up CD186x channel registers */
1150        spin_lock_irqsave(&bp->lock, flags);
1151        sx_out(bp, CD186x_COR1, cor1);
1152        sx_out(bp, CD186x_COR2, port->COR2);
1153        sx_out(bp, CD186x_COR3, cor3);
1154        spin_unlock_irqrestore(&bp->lock, flags);
1155        /* Make CD186x know about registers change */
1156        sx_wait_CCR(bp);
1157        spin_lock_irqsave(&bp->lock, flags);
1158        sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1159        /* Setting up modem option registers */
1160        dprintk(SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n",
1161                                                                mcor1, mcor2);
1162        sx_out(bp, CD186x_MCOR1, mcor1);
1163        sx_out(bp, CD186x_MCOR2, mcor2);
1164        spin_unlock_irqrestore(&bp->lock, flags);
1165        /* Enable CD186x transmitter & receiver */
1166        sx_wait_CCR(bp);
1167        spin_lock_irqsave(&bp->lock, flags);
1168        sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1169        /* Enable interrupts */
1170        sx_out(bp, CD186x_IER, port->IER);
1171        /* And finally set the modem lines... */
1172        sx_out(bp, CD186x_MSVR, port->MSVR);
1173        spin_unlock_irqrestore(&bp->lock, flags);
1174
1175        func_exit();
1176}
1177
1178
1179/* Must be called with interrupts enabled */
1180static int sx_setup_port(struct specialix_board *bp,
1181                                                struct specialix_port *port)
1182{
1183        unsigned long flags;
1184
1185        func_enter();
1186
1187        if (port->port.flags & ASYNC_INITIALIZED) {
1188                func_exit();
1189                return 0;
1190        }
1191
1192        if (!port->xmit_buf) {
1193                /* We may sleep in get_zeroed_page() */
1194                unsigned long tmp;
1195
1196                tmp = get_zeroed_page(GFP_KERNEL);
1197                if (tmp == 0L) {
1198                        func_exit();
1199                        return -ENOMEM;
1200                }
1201
1202                if (port->xmit_buf) {
1203                        free_page(tmp);
1204                        func_exit();
1205                        return -ERESTARTSYS;
1206                }
1207                port->xmit_buf = (unsigned char *) tmp;
1208        }
1209
1210        spin_lock_irqsave(&port->lock, flags);
1211
1212        if (port->port.tty)
1213                clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
1214
1215        port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1216        sx_change_speed(bp, port);
1217        port->port.flags |= ASYNC_INITIALIZED;
1218
1219        spin_unlock_irqrestore(&port->lock, flags);
1220
1221
1222        func_exit();
1223        return 0;
1224}
1225
1226
1227/* Must be called with interrupts disabled */
1228static void sx_shutdown_port(struct specialix_board *bp,
1229                                                struct specialix_port *port)
1230{
1231        struct tty_struct *tty;
1232        int i;
1233        unsigned long flags;
1234
1235        func_enter();
1236
1237        if (!(port->port.flags & ASYNC_INITIALIZED)) {
1238                func_exit();
1239                return;
1240        }
1241
1242        if (sx_debug & SX_DEBUG_FIFO) {
1243                dprintk(SX_DEBUG_FIFO,
1244                        "sx%d: port %d: %ld overruns, FIFO hits [ ",
1245                                board_No(bp), port_No(port), port->overrun);
1246                for (i = 0; i < 10; i++)
1247                        dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1248                dprintk(SX_DEBUG_FIFO, "].\n");
1249        }
1250
1251        if (port->xmit_buf) {
1252                free_page((unsigned long) port->xmit_buf);
1253                port->xmit_buf = NULL;
1254        }
1255
1256        /* Select port */
1257        spin_lock_irqsave(&bp->lock, flags);
1258        sx_out(bp, CD186x_CAR, port_No(port));
1259
1260        tty = port->port.tty;
1261        if (tty == NULL || C_HUPCL(tty)) {
1262                /* Drop DTR */
1263                sx_out(bp, CD186x_MSVDTR, 0);
1264        }
1265        spin_unlock_irqrestore(&bp->lock, flags);
1266        /* Reset port */
1267        sx_wait_CCR(bp);
1268        spin_lock_irqsave(&bp->lock, flags);
1269        sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1270        /* Disable all interrupts from this port */
1271        port->IER = 0;
1272        sx_out(bp, CD186x_IER, port->IER);
1273        spin_unlock_irqrestore(&bp->lock, flags);
1274        if (tty)
1275                set_bit(TTY_IO_ERROR, &tty->flags);
1276        port->port.flags &= ~ASYNC_INITIALIZED;
1277
1278        if (!bp->count)
1279                sx_shutdown_board(bp);
1280        func_exit();
1281}
1282
1283
1284static int block_til_ready(struct tty_struct *tty, struct file *filp,
1285                                                struct specialix_port *port)
1286{
1287        DECLARE_WAITQUEUE(wait,  current);
1288        struct specialix_board *bp = port_Board(port);
1289        int    retval;
1290        int    do_clocal = 0;
1291        int    CD;
1292        unsigned long flags;
1293
1294        func_enter();
1295
1296        /*
1297         * If the device is in the middle of being closed, then block
1298         * until it's done, and then try again.
1299         */
1300        if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
1301                interruptible_sleep_on(&port->port.close_wait);
1302                if (port->port.flags & ASYNC_HUP_NOTIFY) {
1303                        func_exit();
1304                        return -EAGAIN;
1305                } else {
1306                        func_exit();
1307                        return -ERESTARTSYS;
1308                }
1309        }
1310
1311        /*
1312         * If non-blocking mode is set, or the port is not enabled,
1313         * then make the check up front and then exit.
1314         */
1315        if ((filp->f_flags & O_NONBLOCK) ||
1316            (tty->flags & (1 << TTY_IO_ERROR))) {
1317                port->port.flags |= ASYNC_NORMAL_ACTIVE;
1318                func_exit();
1319                return 0;
1320        }
1321
1322        if (C_CLOCAL(tty))
1323                do_clocal = 1;
1324
1325        /*
1326         * Block waiting for the carrier detect and the line to become
1327         * free (i.e., not in use by the callout).  While we are in
1328         * this loop, info->count is dropped by one, so that
1329         * rs_close() knows when to free things.  We restore it upon
1330         * exit, either normal or abnormal.
1331         */
1332        retval = 0;
1333        add_wait_queue(&port->port.open_wait, &wait);
1334        spin_lock_irqsave(&port->lock, flags);
1335        if (!tty_hung_up_p(filp))
1336                port->port.count--;
1337        spin_unlock_irqrestore(&port->lock, flags);
1338        port->port.blocked_open++;
1339        while (1) {
1340                spin_lock_irqsave(&bp->lock, flags);
1341                sx_out(bp, CD186x_CAR, port_No(port));
1342                CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1343                if (sx_crtscts(tty)) {
1344                        /* Activate RTS */
1345                        port->MSVR |= MSVR_DTR;         /* WTF? */
1346                        sx_out(bp, CD186x_MSVR, port->MSVR);
1347                } else {
1348                        /* Activate DTR */
1349                        port->MSVR |= MSVR_DTR;
1350                        sx_out(bp, CD186x_MSVR, port->MSVR);
1351                }
1352                spin_unlock_irqrestore(&bp->lock, flags);
1353                set_current_state(TASK_INTERRUPTIBLE);
1354                if (tty_hung_up_p(filp) ||
1355                    !(port->port.flags & ASYNC_INITIALIZED)) {
1356                        if (port->port.flags & ASYNC_HUP_NOTIFY)
1357                                retval = -EAGAIN;
1358                        else
1359                                retval = -ERESTARTSYS;
1360                        break;
1361                }
1362                if (!(port->port.flags & ASYNC_CLOSING) &&
1363                    (do_clocal || CD))
1364                        break;
1365                if (signal_pending(current)) {
1366                        retval = -ERESTARTSYS;
1367                        break;
1368                }
1369                schedule();
1370        }
1371
1372        set_current_state(TASK_RUNNING);
1373        remove_wait_queue(&port->port.open_wait, &wait);
1374        spin_lock_irqsave(&port->lock, flags);
1375        if (!tty_hung_up_p(filp))
1376                port->port.count++;
1377        port->port.blocked_open--;
1378        spin_unlock_irqrestore(&port->lock, flags);
1379        if (retval) {
1380                func_exit();
1381                return retval;
1382        }
1383
1384        port->port.flags |= ASYNC_NORMAL_ACTIVE;
1385        func_exit();
1386        return 0;
1387}
1388
1389
1390static int sx_open(struct tty_struct *tty, struct file *filp)
1391{
1392        int board;
1393        int error;
1394        struct specialix_port *port;
1395        struct specialix_board *bp;
1396        int i;
1397        unsigned long flags;
1398
1399        func_enter();
1400
1401        board = SX_BOARD(tty->index);
1402
1403        if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1404                func_exit();
1405                return -ENODEV;
1406        }
1407
1408        bp = &sx_board[board];
1409        port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1410        port->overrun = 0;
1411        for (i = 0; i < 10; i++)
1412                port->hits[i] = 0;
1413
1414        dprintk(SX_DEBUG_OPEN,
1415                        "Board = %d, bp = %p, port = %p, portno = %d.\n",
1416                                 board, bp, port, SX_PORT(tty->index));
1417
1418        if (sx_paranoia_check(port, tty->name, "sx_open")) {
1419                func_enter();
1420                return -ENODEV;
1421        }
1422
1423        error = sx_setup_board(bp);
1424        if (error) {
1425                func_exit();
1426                return error;
1427        }
1428
1429        spin_lock_irqsave(&bp->lock, flags);
1430        port->port.count++;
1431        bp->count++;
1432        tty->driver_data = port;
1433        port->port.tty = tty;
1434        spin_unlock_irqrestore(&bp->lock, flags);
1435
1436        error = sx_setup_port(bp, port);
1437        if (error) {
1438                func_enter();
1439                return error;
1440        }
1441
1442        error = block_til_ready(tty, filp, port);
1443        if (error) {
1444                func_enter();
1445                return error;
1446        }
1447
1448        func_exit();
1449        return 0;
1450}
1451
1452static void sx_flush_buffer(struct tty_struct *tty)
1453{
1454        struct specialix_port *port = tty->driver_data;
1455        unsigned long flags;
1456        struct specialix_board  *bp;
1457
1458        func_enter();
1459
1460        if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
1461                func_exit();
1462                return;
1463        }
1464
1465        bp = port_Board(port);
1466        spin_lock_irqsave(&port->lock, flags);
1467        port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1468        spin_unlock_irqrestore(&port->lock, flags);
1469        tty_wakeup(tty);
1470
1471        func_exit();
1472}
1473
1474static void sx_close(struct tty_struct *tty, struct file *filp)
1475{
1476        struct specialix_port *port = tty->driver_data;
1477        struct specialix_board *bp;
1478        unsigned long flags;
1479        unsigned long timeout;
1480
1481        func_enter();
1482        if (!port || sx_paranoia_check(port, tty->name, "close")) {
1483                func_exit();
1484                return;
1485        }
1486        spin_lock_irqsave(&port->lock, flags);
1487
1488        if (tty_hung_up_p(filp)) {
1489                spin_unlock_irqrestore(&port->lock, flags);
1490                func_exit();
1491                return;
1492        }
1493
1494        bp = port_Board(port);
1495        if (tty->count == 1 && port->port.count != 1) {
1496                printk(KERN_ERR "sx%d: sx_close: bad port count;"
1497                       " tty->count is 1, port count is %d\n",
1498                       board_No(bp), port->port.count);
1499                port->port.count = 1;
1500        }
1501
1502        if (port->port.count > 1) {
1503                port->port.count--;
1504                bp->count--;
1505
1506                spin_unlock_irqrestore(&port->lock, flags);
1507
1508                func_exit();
1509                return;
1510        }
1511        port->port.flags |= ASYNC_CLOSING;
1512        /*
1513         * Now we wait for the transmit buffer to clear; and we notify
1514         * the line discipline to only process XON/XOFF characters.
1515         */
1516        tty->closing = 1;
1517        spin_unlock_irqrestore(&port->lock, flags);
1518        dprintk(SX_DEBUG_OPEN, "Closing\n");
1519        if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1520                tty_wait_until_sent(tty, port->port.closing_wait);
1521        /*
1522         * At this point we stop accepting input.  To do this, we
1523         * disable the receive line status interrupts, and tell the
1524         * interrupt driver to stop checking the data ready bit in the
1525         * line status register.
1526         */
1527        dprintk(SX_DEBUG_OPEN, "Closed\n");
1528        port->IER &= ~IER_RXD;
1529        if (port->port.flags & ASYNC_INITIALIZED) {
1530                port->IER &= ~IER_TXRDY;
1531                port->IER |= IER_TXEMPTY;
1532                spin_lock_irqsave(&bp->lock, flags);
1533                sx_out(bp, CD186x_CAR, port_No(port));
1534                sx_out(bp, CD186x_IER, port->IER);
1535                spin_unlock_irqrestore(&bp->lock, flags);
1536                /*
1537                 * Before we drop DTR, make sure the UART transmitter
1538                 * has completely drained; this is especially
1539                 * important if there is a transmit FIFO!
1540                 */
1541                timeout = jiffies+HZ;
1542                while (port->IER & IER_TXEMPTY) {
1543                        set_current_state(TASK_INTERRUPTIBLE);
1544                        msleep_interruptible(jiffies_to_msecs(port->timeout));
1545                        if (time_after(jiffies, timeout)) {
1546                                printk(KERN_INFO "Timeout waiting for close\n");
1547                                break;
1548                        }
1549                }
1550
1551        }
1552
1553        if (--bp->count < 0) {
1554                printk(KERN_ERR
1555                    "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1556                                board_No(bp), bp->count, tty->index);
1557                bp->count = 0;
1558        }
1559        if (--port->port.count < 0) {
1560                printk(KERN_ERR
1561                        "sx%d: sx_close: bad port count for tty%d: %d\n",
1562                                board_No(bp), port_No(port), port->port.count);
1563                port->port.count = 0;
1564        }
1565
1566        sx_shutdown_port(bp, port);
1567        sx_flush_buffer(tty);
1568        tty_ldisc_flush(tty);
1569        spin_lock_irqsave(&port->lock, flags);
1570        tty->closing = 0;
1571        port->port.tty = NULL;
1572        spin_unlock_irqrestore(&port->lock, flags);
1573        if (port->port.blocked_open) {
1574                if (port->port.close_delay)
1575                        msleep_interruptible(
1576                                jiffies_to_msecs(port->port.close_delay));
1577                wake_up_interruptible(&port->port.open_wait);
1578        }
1579        port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1580        wake_up_interruptible(&port->port.close_wait);
1581
1582        func_exit();
1583}
1584
1585
1586static int sx_write(struct tty_struct *tty,
1587                                        const unsigned char *buf, int count)
1588{
1589        struct specialix_port *port = tty->driver_data;
1590        struct specialix_board *bp;
1591        int c, total = 0;
1592        unsigned long flags;
1593
1594        func_enter();
1595        if (sx_paranoia_check(port, tty->name, "sx_write")) {
1596                func_exit();
1597                return 0;
1598        }
1599
1600        bp = port_Board(port);
1601
1602        if (!port->xmit_buf) {
1603                func_exit();
1604                return 0;
1605        }
1606
1607        while (1) {
1608                spin_lock_irqsave(&port->lock, flags);
1609                c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1610                                   SERIAL_XMIT_SIZE - port->xmit_head));
1611                if (c <= 0) {
1612                        spin_unlock_irqrestore(&port->lock, flags);
1613                        break;
1614                }
1615                memcpy(port->xmit_buf + port->xmit_head, buf, c);
1616                port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1617                port->xmit_cnt += c;
1618                spin_unlock_irqrestore(&port->lock, flags);
1619
1620                buf += c;
1621                count -= c;
1622                total += c;
1623        }
1624
1625        spin_lock_irqsave(&bp->lock, flags);
1626        if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1627            !(port->IER & IER_TXRDY)) {
1628                port->IER |= IER_TXRDY;
1629                sx_out(bp, CD186x_CAR, port_No(port));
1630                sx_out(bp, CD186x_IER, port->IER);
1631        }
1632        spin_unlock_irqrestore(&bp->lock, flags);
1633        func_exit();
1634
1635        return total;
1636}
1637
1638
1639static int sx_put_char(struct tty_struct *tty, unsigned char ch)
1640{
1641        struct specialix_port *port = tty->driver_data;
1642        unsigned long flags;
1643        struct specialix_board  *bp;
1644
1645        func_enter();
1646
1647        if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1648                func_exit();
1649                return 0;
1650        }
1651        dprintk(SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1652        if (!port->xmit_buf) {
1653                func_exit();
1654                return 0;
1655        }
1656        bp = port_Board(port);
1657        spin_lock_irqsave(&port->lock, flags);
1658
1659        dprintk(SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n",
1660                                        port->xmit_cnt, port->xmit_buf);
1661        if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1 || !port->xmit_buf) {
1662                spin_unlock_irqrestore(&port->lock, flags);
1663                dprintk(SX_DEBUG_TX, "Exit size\n");
1664                func_exit();
1665                return 0;
1666        }
1667        dprintk(SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
1668        port->xmit_buf[port->xmit_head++] = ch;
1669        port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1670        port->xmit_cnt++;
1671        spin_unlock_irqrestore(&port->lock, flags);
1672
1673        func_exit();
1674        return 1;
1675}
1676
1677
1678static void sx_flush_chars(struct tty_struct *tty)
1679{
1680        struct specialix_port *port = tty->driver_data;
1681        unsigned long flags;
1682        struct specialix_board  *bp = port_Board(port);
1683
1684        func_enter();
1685
1686        if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1687                func_exit();
1688                return;
1689        }
1690        if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1691            !port->xmit_buf) {
1692                func_exit();
1693                return;
1694        }
1695        spin_lock_irqsave(&bp->lock, flags);
1696        port->IER |= IER_TXRDY;
1697        sx_out(port_Board(port), CD186x_CAR, port_No(port));
1698        sx_out(port_Board(port), CD186x_IER, port->IER);
1699        spin_unlock_irqrestore(&bp->lock, flags);
1700
1701        func_exit();
1702}
1703
1704
1705static int sx_write_room(struct tty_struct *tty)
1706{
1707        struct specialix_port *port = tty->driver_data;
1708        int     ret;
1709
1710        func_enter();
1711
1712        if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1713                func_exit();
1714                return 0;
1715        }
1716
1717        ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1718        if (ret < 0)
1719                ret = 0;
1720
1721        func_exit();
1722        return ret;
1723}
1724
1725
1726static int sx_chars_in_buffer(struct tty_struct *tty)
1727{
1728        struct specialix_port *port = tty->driver_data;
1729
1730        func_enter();
1731
1732        if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
1733                func_exit();
1734                return 0;
1735        }
1736        func_exit();
1737        return port->xmit_cnt;
1738}
1739
1740static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1741{
1742        struct specialix_port *port = tty->driver_data;
1743        struct specialix_board *bp;
1744        unsigned char status;
1745        unsigned int result;
1746        unsigned long flags;
1747
1748        func_enter();
1749
1750        if (sx_paranoia_check(port, tty->name, __func__)) {
1751                func_exit();
1752                return -ENODEV;
1753        }
1754
1755        bp = port_Board(port);
1756        spin_lock_irqsave(&bp->lock, flags);
1757        sx_out(bp, CD186x_CAR, port_No(port));
1758        status = sx_in(bp, CD186x_MSVR);
1759        spin_unlock_irqrestore(&bp->lock, flags);
1760        dprintk(SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1761                        port_No(port), status, sx_in(bp, CD186x_CAR));
1762        dprintk(SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1763        if (sx_crtscts(port->port.tty)) {
1764                result  = TIOCM_DTR | TIOCM_DSR
1765                          |   ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1766                          |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
1767                          |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1768        } else {
1769                result  = TIOCM_RTS | TIOCM_DSR
1770                          |   ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1771                          |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
1772                          |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1773        }
1774
1775        func_exit();
1776
1777        return result;
1778}
1779
1780
1781static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1782                       unsigned int set, unsigned int clear)
1783{
1784        struct specialix_port *port = tty->driver_data;
1785        unsigned long flags;
1786        struct specialix_board *bp;
1787
1788        func_enter();
1789
1790        if (sx_paranoia_check(port, tty->name, __func__)) {
1791                func_exit();
1792                return -ENODEV;
1793        }
1794
1795        bp = port_Board(port);
1796
1797        spin_lock_irqsave(&port->lock, flags);
1798        if (sx_crtscts(port->port.tty)) {
1799                if (set & TIOCM_RTS)
1800                        port->MSVR |= MSVR_DTR;
1801        } else {
1802                if (set & TIOCM_DTR)
1803                        port->MSVR |= MSVR_DTR;
1804        }
1805        if (sx_crtscts(port->port.tty)) {
1806                if (clear & TIOCM_RTS)
1807                        port->MSVR &= ~MSVR_DTR;
1808        } else {
1809                if (clear & TIOCM_DTR)
1810                        port->MSVR &= ~MSVR_DTR;
1811        }
1812        spin_lock(&bp->lock);
1813        sx_out(bp, CD186x_CAR, port_No(port));
1814        sx_out(bp, CD186x_MSVR, port->MSVR);
1815        spin_unlock(&bp->lock);
1816        spin_unlock_irqrestore(&port->lock, flags);
1817        func_exit();
1818        return 0;
1819}
1820
1821
1822static int sx_send_break(struct tty_struct *tty, int length)
1823{
1824        struct specialix_port *port = tty->driver_data;
1825        struct specialix_board *bp = port_Board(port);
1826        unsigned long flags;
1827
1828        func_enter();
1829        if (length == 0 || length == -1)
1830                return -EOPNOTSUPP;
1831
1832        spin_lock_irqsave(&port->lock, flags);
1833        port->break_length = SPECIALIX_TPS / HZ * length;
1834        port->COR2 |= COR2_ETC;
1835        port->IER  |= IER_TXRDY;
1836        spin_lock(&bp->lock);
1837        sx_out(bp, CD186x_CAR, port_No(port));
1838        sx_out(bp, CD186x_COR2, port->COR2);
1839        sx_out(bp, CD186x_IER, port->IER);
1840        spin_unlock(&bp->lock);
1841        spin_unlock_irqrestore(&port->lock, flags);
1842        sx_wait_CCR(bp);
1843        spin_lock_irqsave(&bp->lock, flags);
1844        sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1845        spin_unlock_irqrestore(&bp->lock, flags);
1846        sx_wait_CCR(bp);
1847
1848        func_exit();
1849        return 0;
1850}
1851
1852
1853static int sx_set_serial_info(struct specialix_port *port,
1854                                        struct serial_struct __user *newinfo)
1855{
1856        struct serial_struct tmp;
1857        struct specialix_board *bp = port_Board(port);
1858        int change_speed;
1859
1860        func_enter();
1861
1862        if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
1863                func_enter();
1864                return -EFAULT;
1865        }
1866
1867        lock_kernel();
1868
1869        change_speed = ((port->port.flags & ASYNC_SPD_MASK) !=
1870                        (tmp.flags & ASYNC_SPD_MASK));
1871        change_speed |= (tmp.custom_divisor != port->custom_divisor);
1872
1873        if (!capable(CAP_SYS_ADMIN)) {
1874                if ((tmp.close_delay != port->port.close_delay) ||
1875                    (tmp.closing_wait != port->port.closing_wait) ||
1876                    ((tmp.flags & ~ASYNC_USR_MASK) !=
1877                     (port->port.flags & ~ASYNC_USR_MASK))) {
1878                        func_exit();
1879                        unlock_kernel();
1880                        return -EPERM;
1881                }
1882                port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1883                                                (tmp.flags & ASYNC_USR_MASK));
1884                port->custom_divisor = tmp.custom_divisor;
1885        } else {
1886                port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1887                                                (tmp.flags & ASYNC_FLAGS));
1888                port->port.close_delay = tmp.close_delay;
1889                port->port.closing_wait = tmp.closing_wait;
1890                port->custom_divisor = tmp.custom_divisor;
1891        }
1892        if (change_speed)
1893                sx_change_speed(bp, port);
1894
1895        func_exit();
1896        unlock_kernel();
1897        return 0;
1898}
1899
1900
1901static int sx_get_serial_info(struct specialix_port *port,
1902                                     struct serial_struct __user *retinfo)
1903{
1904        struct serial_struct tmp;
1905        struct specialix_board *bp = port_Board(port);
1906
1907        func_enter();
1908
1909        memset(&tmp, 0, sizeof(tmp));
1910        lock_kernel();
1911        tmp.type = PORT_CIRRUS;
1912        tmp.line = port - sx_port;
1913        tmp.port = bp->base;
1914        tmp.irq  = bp->irq;
1915        tmp.flags = port->port.flags;
1916        tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
1917        tmp.close_delay = port->port.close_delay * HZ/100;
1918        tmp.closing_wait = port->port.closing_wait * HZ/100;
1919        tmp.custom_divisor =  port->custom_divisor;
1920        tmp.xmit_fifo_size = CD186x_NFIFO;
1921        unlock_kernel();
1922        if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
1923                func_exit();
1924                return -EFAULT;
1925        }
1926
1927        func_exit();
1928        return 0;
1929}
1930
1931
1932static int sx_ioctl(struct tty_struct *tty, struct file *filp,
1933                                unsigned int cmd, unsigned long arg)
1934{
1935        struct specialix_port *port = tty->driver_data;
1936        void __user *argp = (void __user *)arg;
1937
1938        func_enter();
1939
1940        if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
1941                func_exit();
1942                return -ENODEV;
1943        }
1944
1945        switch (cmd) {
1946        case TIOCGSERIAL:
1947                func_exit();
1948                return sx_get_serial_info(port, argp);
1949        case TIOCSSERIAL:
1950                func_exit();
1951                return sx_set_serial_info(port, argp);
1952        default:
1953                func_exit();
1954                return -ENOIOCTLCMD;
1955        }
1956        func_exit();
1957        return 0;
1958}
1959
1960
1961static void sx_throttle(struct tty_struct *tty)
1962{
1963        struct specialix_port *port = tty->driver_data;
1964        struct specialix_board *bp;
1965        unsigned long flags;
1966
1967        func_enter();
1968
1969        if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
1970                func_exit();
1971                return;
1972        }
1973
1974        bp = port_Board(port);
1975
1976        /* Use DTR instead of RTS ! */
1977        if (sx_crtscts(tty))
1978                port->MSVR &= ~MSVR_DTR;
1979        else {
1980                /* Auch!!! I think the system shouldn't call this then. */
1981                /* Or maybe we're supposed (allowed?) to do our side of hw
1982                   handshake anyway, even when hardware handshake is off.
1983                   When you see this in your logs, please report.... */
1984                printk(KERN_ERR
1985                   "sx%d: Need to throttle, but can't (hardware hs is off)\n",
1986                                                        port_No(port));
1987        }
1988        spin_lock_irqsave(&bp->lock, flags);
1989        sx_out(bp, CD186x_CAR, port_No(port));
1990        spin_unlock_irqrestore(&bp->lock, flags);
1991        if (I_IXOFF(tty)) {
1992                sx_wait_CCR(bp);
1993                spin_lock_irqsave(&bp->lock, flags);
1994                sx_out(bp, CD186x_CCR, CCR_SSCH2);
1995                spin_unlock_irqrestore(&bp->lock, flags);
1996                sx_wait_CCR(bp);
1997        }
1998        spin_lock_irqsave(&bp->lock, flags);
1999        sx_out(bp, CD186x_MSVR, port->MSVR);
2000        spin_unlock_irqrestore(&bp->lock, flags);
2001
2002        func_exit();
2003}
2004
2005
2006static void sx_unthrottle(struct tty_struct *tty)
2007{
2008        struct specialix_port *port = tty->driver_data;
2009        struct specialix_board *bp;
2010        unsigned long flags;
2011
2012        func_enter();
2013
2014        if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
2015                func_exit();
2016                return;
2017        }
2018
2019        bp = port_Board(port);
2020
2021        spin_lock_irqsave(&port->lock, flags);
2022        /* XXXX Use DTR INSTEAD???? */
2023        if (sx_crtscts(tty))
2024                port->MSVR |= MSVR_DTR;
2025        /* Else clause: see remark in "sx_throttle"... */
2026        spin_lock(&bp->lock);
2027        sx_out(bp, CD186x_CAR, port_No(port));
2028        spin_unlock(&bp->lock);
2029        if (I_IXOFF(tty)) {
2030                spin_unlock_irqrestore(&port->lock, flags);
2031                sx_wait_CCR(bp);
2032                spin_lock_irqsave(&bp->lock, flags);
2033                sx_out(bp, CD186x_CCR, CCR_SSCH1);
2034                spin_unlock_irqrestore(&bp->lock, flags);
2035                sx_wait_CCR(bp);
2036                spin_lock_irqsave(&port->lock, flags);
2037        }
2038        spin_lock(&bp->lock);
2039        sx_out(bp, CD186x_MSVR, port->MSVR);
2040        spin_unlock(&bp->lock);
2041        spin_unlock_irqrestore(&port->lock, flags);
2042
2043        func_exit();
2044}
2045
2046
2047static void sx_stop(struct tty_struct *tty)
2048{
2049        struct specialix_port *port = tty->driver_data;
2050        struct specialix_board *bp;
2051        unsigned long flags;
2052
2053        func_enter();
2054
2055        if (sx_paranoia_check(port, tty->name, "sx_stop")) {
2056                func_exit();
2057                return;
2058        }
2059
2060        bp = port_Board(port);
2061
2062        spin_lock_irqsave(&port->lock, flags);
2063        port->IER &= ~IER_TXRDY;
2064        spin_lock(&bp->lock);
2065        sx_out(bp, CD186x_CAR, port_No(port));
2066        sx_out(bp, CD186x_IER, port->IER);
2067        spin_unlock(&bp->lock);
2068        spin_unlock_irqrestore(&port->lock, flags);
2069
2070        func_exit();
2071}
2072
2073
2074static void sx_start(struct tty_struct *tty)
2075{
2076        struct specialix_port *port = tty->driver_data;
2077        struct specialix_board *bp;
2078        unsigned long flags;
2079
2080        func_enter();
2081
2082        if (sx_paranoia_check(port, tty->name, "sx_start")) {
2083                func_exit();
2084                return;
2085        }
2086
2087        bp = port_Board(port);
2088
2089        spin_lock_irqsave(&port->lock, flags);
2090        if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2091                port->IER |= IER_TXRDY;
2092                spin_lock(&bp->lock);
2093                sx_out(bp, CD186x_CAR, port_No(port));
2094                sx_out(bp, CD186x_IER, port->IER);
2095                spin_unlock(&bp->lock);
2096        }
2097        spin_unlock_irqrestore(&port->lock, flags);
2098
2099        func_exit();
2100}
2101
2102static void sx_hangup(struct tty_struct *tty)
2103{
2104        struct specialix_port *port = tty->driver_data;
2105        struct specialix_board *bp;
2106        unsigned long flags;
2107
2108        func_enter();
2109
2110        if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2111                func_exit();
2112                return;
2113        }
2114
2115        bp = port_Board(port);
2116
2117        sx_shutdown_port(bp, port);
2118        spin_lock_irqsave(&port->lock, flags);
2119        bp->count -= port->port.count;
2120        if (bp->count < 0) {
2121                printk(KERN_ERR
2122                        "sx%d: sx_hangup: bad board count: %d port: %d\n",
2123                                        board_No(bp), bp->count, tty->index);
2124                bp->count = 0;
2125        }
2126        port->port.count = 0;
2127        port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
2128        port->port.tty = NULL;
2129        spin_unlock_irqrestore(&port->lock, flags);
2130        wake_up_interruptible(&port->port.open_wait);
2131
2132        func_exit();
2133}
2134
2135
2136static void sx_set_termios(struct tty_struct *tty,
2137                                        struct ktermios *old_termios)
2138{
2139        struct specialix_port *port = tty->driver_data;
2140        unsigned long flags;
2141        struct specialix_board  *bp;
2142
2143        if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2144                return;
2145
2146        bp = port_Board(port);
2147        spin_lock_irqsave(&port->lock, flags);
2148        sx_change_speed(port_Board(port), port);
2149        spin_unlock_irqrestore(&port->lock, flags);
2150
2151        if ((old_termios->c_cflag & CRTSCTS) &&
2152            !(tty->termios->c_cflag & CRTSCTS)) {
2153                tty->hw_stopped = 0;
2154                sx_start(tty);
2155        }
2156}
2157
2158static const struct tty_operations sx_ops = {
2159        .open  = sx_open,
2160        .close = sx_close,
2161        .write = sx_write,
2162        .put_char = sx_put_char,
2163        .flush_chars = sx_flush_chars,
2164        .write_room = sx_write_room,
2165        .chars_in_buffer = sx_chars_in_buffer,
2166        .flush_buffer = sx_flush_buffer,
2167        .ioctl = sx_ioctl,
2168        .throttle = sx_throttle,
2169        .unthrottle = sx_unthrottle,
2170        .set_termios = sx_set_termios,
2171        .stop = sx_stop,
2172        .start = sx_start,
2173        .hangup = sx_hangup,
2174        .tiocmget = sx_tiocmget,
2175        .tiocmset = sx_tiocmset,
2176        .break_ctl = sx_send_break,
2177};
2178
2179static int sx_init_drivers(void)
2180{
2181        int error;
2182        int i;
2183
2184        func_enter();
2185
2186        specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT);
2187        if (!specialix_driver) {
2188                printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n");
2189                func_exit();
2190                return 1;
2191        }
2192
2193        specialix_driver->owner = THIS_MODULE;
2194        specialix_driver->name = "ttyW";
2195        specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
2196        specialix_driver->type = TTY_DRIVER_TYPE_SERIAL;
2197        specialix_driver->subtype = SERIAL_TYPE_NORMAL;
2198        specialix_driver->init_termios = tty_std_termios;
2199        specialix_driver->init_termios.c_cflag =
2200                B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2201        specialix_driver->init_termios.c_ispeed = 9600;
2202        specialix_driver->init_termios.c_ospeed = 9600;
2203        specialix_driver->flags = TTY_DRIVER_REAL_RAW |
2204                                                TTY_DRIVER_HARDWARE_BREAK;
2205        tty_set_operations(specialix_driver, &sx_ops);
2206
2207        error = tty_register_driver(specialix_driver);
2208        if (error) {
2209                put_tty_driver(specialix_driver);
2210                printk(KERN_ERR
2211                  "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2212                                                                error);
2213                func_exit();
2214                return 1;
2215        }
2216        memset(sx_port, 0, sizeof(sx_port));
2217        for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2218                sx_port[i].magic = SPECIALIX_MAGIC;
2219                tty_port_init(&sx_port[i].port);
2220                spin_lock_init(&sx_port[i].lock);
2221        }
2222
2223        func_exit();
2224        return 0;
2225}
2226
2227static void sx_release_drivers(void)
2228{
2229        func_enter();
2230
2231        tty_unregister_driver(specialix_driver);
2232        put_tty_driver(specialix_driver);
2233        func_exit();
2234}
2235
2236/*
2237 * This routine must be called by kernel at boot time
2238 */
2239static int __init specialix_init(void)
2240{
2241        int i;
2242        int found = 0;
2243
2244        func_enter();
2245
2246        printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
2247        printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2248        if (sx_rtscts)
2249                printk(KERN_INFO
2250                        "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2251        else
2252                printk(KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
2253
2254        for (i = 0; i < SX_NBOARD; i++)
2255                spin_lock_init(&sx_board[i].lock);
2256
2257        if (sx_init_drivers()) {
2258                func_exit();
2259                return -EIO;
2260        }
2261
2262        for (i = 0; i < SX_NBOARD; i++)
2263                if (sx_board[i].base && !sx_probe(&sx_board[i]))
2264                        found++;
2265
2266#ifdef CONFIG_PCI
2267        {
2268                struct pci_dev *pdev = NULL;
2269
2270                i = 0;
2271                while (i < SX_NBOARD) {
2272                        if (sx_board[i].flags & SX_BOARD_PRESENT) {
2273                                i++;
2274                                continue;
2275                        }
2276                        pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX,
2277                                        PCI_DEVICE_ID_SPECIALIX_IO8, pdev);
2278                        if (!pdev)
2279                                break;
2280
2281                        if (pci_enable_device(pdev))
2282                                continue;
2283
2284                        sx_board[i].irq = pdev->irq;
2285
2286                        sx_board[i].base = pci_resource_start(pdev, 2);
2287
2288                        sx_board[i].flags |= SX_BOARD_IS_PCI;
2289                        if (!sx_probe(&sx_board[i]))
2290                                found++;
2291                }
2292                /* May exit pci_get sequence early with lots of boards */
2293                if (pdev != NULL)
2294                        pci_dev_put(pdev);
2295        }
2296#endif
2297
2298        if (!found) {
2299                sx_release_drivers();
2300                printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
2301                func_exit();
2302                return -EIO;
2303        }
2304
2305        func_exit();
2306        return 0;
2307}
2308
2309static int iobase[SX_NBOARD]  = {0,};
2310static int irq[SX_NBOARD] = {0,};
2311
2312module_param_array(iobase, int, NULL, 0);
2313module_param_array(irq, int, NULL, 0);
2314module_param(sx_debug, int, 0);
2315module_param(sx_rtscts, int, 0);
2316module_param(sx_rxfifo, int, 0);
2317
2318/*
2319 * You can setup up to 4 boards.
2320 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2321 * You should specify the IRQs too in that case "irq=....,...".
2322 *
2323 * More than 4 boards in one computer is not possible, as the card can
2324 * only use 4 different interrupts.
2325 *
2326 */
2327static int __init specialix_init_module(void)
2328{
2329        int i;
2330
2331        func_enter();
2332
2333        if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2334                for (i = 0; i < SX_NBOARD; i++) {
2335                        sx_board[i].base = iobase[i];
2336                        sx_board[i].irq = irq[i];
2337                        sx_board[i].count = 0;
2338                }
2339        }
2340
2341        func_exit();
2342
2343        return specialix_init();
2344}
2345
2346static void __exit specialix_exit_module(void)
2347{
2348        int i;
2349
2350        func_enter();
2351
2352        sx_release_drivers();
2353        for (i = 0; i < SX_NBOARD; i++)
2354                if (sx_board[i].flags & SX_BOARD_PRESENT)
2355                        sx_release_io_range(&sx_board[i]);
2356        func_exit();
2357}
2358
2359static struct pci_device_id specialx_pci_tbl[] __devinitdata = {
2360        { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) },
2361        { }
2362};
2363MODULE_DEVICE_TABLE(pci, specialx_pci_tbl);
2364
2365module_init(specialix_init_module);
2366module_exit(specialix_exit_module);
2367
2368MODULE_LICENSE("GPL");
2369MODULE_ALIAS_CHARDEV_MAJOR(SPECIALIX_NORMAL_MAJOR);
2370