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/fcntl.h>
  91#include <linux/major.h>
  92#include <linux/delay.h>
  93#include <linux/pci.h>
  94#include <linux/init.h>
  95#include <linux/uaccess.h>
  96#include <linux/gfp.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        while (count--)
 650                tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL);
 651        tty_flip_buffer_push(tty);
 652        func_exit();
 653}
 654
 655
 656static void sx_transmit(struct specialix_board *bp)
 657{
 658        struct specialix_port *port;
 659        struct tty_struct *tty;
 660        unsigned char count;
 661
 662        func_enter();
 663        port = sx_get_port(bp, "Transmit");
 664        if (port == NULL) {
 665                func_exit();
 666                return;
 667        }
 668        dprintk(SX_DEBUG_TX, "port: %p\n", port);
 669        tty = port->port.tty;
 670
 671        if (port->IER & IER_TXEMPTY) {
 672                /* FIFO drained */
 673                sx_out(bp, CD186x_CAR, port_No(port));
 674                port->IER &= ~IER_TXEMPTY;
 675                sx_out(bp, CD186x_IER, port->IER);
 676                func_exit();
 677                return;
 678        }
 679
 680        if ((port->xmit_cnt <= 0 && !port->break_length)
 681            || tty->stopped || tty->hw_stopped) {
 682                sx_out(bp, CD186x_CAR, port_No(port));
 683                port->IER &= ~IER_TXRDY;
 684                sx_out(bp, CD186x_IER, port->IER);
 685                func_exit();
 686                return;
 687        }
 688
 689        if (port->break_length) {
 690                if (port->break_length > 0) {
 691                        if (port->COR2 & COR2_ETC) {
 692                                sx_out(bp, CD186x_TDR, CD186x_C_ESC);
 693                                sx_out(bp, CD186x_TDR, CD186x_C_SBRK);
 694                                port->COR2 &= ~COR2_ETC;
 695                        }
 696                        count = min_t(int, port->break_length, 0xff);
 697                        sx_out(bp, CD186x_TDR, CD186x_C_ESC);
 698                        sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
 699                        sx_out(bp, CD186x_TDR, count);
 700                        port->break_length -= count;
 701                        if (port->break_length == 0)
 702                                port->break_length--;
 703                } else {
 704                        sx_out(bp, CD186x_TDR, CD186x_C_ESC);
 705                        sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
 706                        sx_out(bp, CD186x_COR2, port->COR2);
 707                        sx_wait_CCR(bp);
 708                        sx_out(bp, CD186x_CCR, CCR_CORCHG2);
 709                        port->break_length = 0;
 710                }
 711
 712                func_exit();
 713                return;
 714        }
 715
 716        count = CD186x_NFIFO;
 717        do {
 718                sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
 719                port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
 720                if (--port->xmit_cnt <= 0)
 721                        break;
 722        } while (--count > 0);
 723
 724        if (port->xmit_cnt <= 0) {
 725                sx_out(bp, CD186x_CAR, port_No(port));
 726                port->IER &= ~IER_TXRDY;
 727                sx_out(bp, CD186x_IER, port->IER);
 728        }
 729        if (port->xmit_cnt <= port->wakeup_chars)
 730                tty_wakeup(tty);
 731
 732        func_exit();
 733}
 734
 735
 736static void sx_check_modem(struct specialix_board *bp)
 737{
 738        struct specialix_port *port;
 739        struct tty_struct *tty;
 740        unsigned char mcr;
 741        int msvr_cd;
 742
 743        dprintk(SX_DEBUG_SIGNALS, "Modem intr. ");
 744        port = sx_get_port(bp, "Modem");
 745        if (port == NULL)
 746                return;
 747
 748        tty = port->port.tty;
 749
 750        mcr = sx_in(bp, CD186x_MCR);
 751
 752        if ((mcr & MCR_CDCHG)) {
 753                dprintk(SX_DEBUG_SIGNALS, "CD just changed... ");
 754                msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
 755                if (msvr_cd) {
 756                        dprintk(SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
 757                        wake_up_interruptible(&port->port.open_wait);
 758                } else {
 759                        dprintk(SX_DEBUG_SIGNALS, "Sending HUP.\n");
 760                        tty_hangup(tty);
 761                }
 762        }
 763
 764#ifdef SPECIALIX_BRAIN_DAMAGED_CTS
 765        if (mcr & MCR_CTSCHG) {
 766                if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
 767                        tty->hw_stopped = 0;
 768                        port->IER |= IER_TXRDY;
 769                        if (port->xmit_cnt <= port->wakeup_chars)
 770                                tty_wakeup(tty);
 771                } else {
 772                        tty->hw_stopped = 1;
 773                        port->IER &= ~IER_TXRDY;
 774                }
 775                sx_out(bp, CD186x_IER, port->IER);
 776        }
 777        if (mcr & MCR_DSSXHG) {
 778                if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
 779                        tty->hw_stopped = 0;
 780                        port->IER |= IER_TXRDY;
 781                        if (port->xmit_cnt <= port->wakeup_chars)
 782                                tty_wakeup(tty);
 783                } else {
 784                        tty->hw_stopped = 1;
 785                        port->IER &= ~IER_TXRDY;
 786                }
 787                sx_out(bp, CD186x_IER, port->IER);
 788        }
 789#endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
 790
 791        /* Clear change bits */
 792        sx_out(bp, CD186x_MCR, 0);
 793}
 794
 795
 796/* The main interrupt processing routine */
 797static irqreturn_t sx_interrupt(int dummy, void *dev_id)
 798{
 799        unsigned char status;
 800        unsigned char ack;
 801        struct specialix_board *bp = dev_id;
 802        unsigned long loop = 0;
 803        int saved_reg;
 804        unsigned long flags;
 805
 806        func_enter();
 807
 808        spin_lock_irqsave(&bp->lock, flags);
 809
 810        dprintk(SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__,
 811                port_No(sx_get_port(bp, "INT")),
 812                SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
 813        if (!(bp->flags & SX_BOARD_ACTIVE)) {
 814                dprintk(SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n",
 815                                                                bp->irq);
 816                spin_unlock_irqrestore(&bp->lock, flags);
 817                func_exit();
 818                return IRQ_NONE;
 819        }
 820
 821        saved_reg = bp->reg;
 822
 823        while (++loop < 16) {
 824                status = sx_in(bp, CD186x_SRSR) &
 825                                (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint);
 826                if (status == 0)
 827                        break;
 828                if (status & SRSR_RREQint) {
 829                        ack = sx_in(bp, CD186x_RRAR);
 830
 831                        if (ack == (SX_ID | GIVR_IT_RCV))
 832                                sx_receive(bp);
 833                        else if (ack == (SX_ID | GIVR_IT_REXC))
 834                                sx_receive_exc(bp);
 835                        else
 836                                printk(KERN_ERR
 837                                "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
 838                                                board_No(bp), status, ack);
 839
 840                } else if (status & SRSR_TREQint) {
 841                        ack = sx_in(bp, CD186x_TRAR);
 842
 843                        if (ack == (SX_ID | GIVR_IT_TX))
 844                                sx_transmit(bp);
 845                        else
 846                                printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
 847                                        board_No(bp), status, ack,
 848                                        port_No(sx_get_port(bp, "Int")));
 849                } else if (status & SRSR_MREQint) {
 850                        ack = sx_in(bp, CD186x_MRAR);
 851
 852                        if (ack == (SX_ID | GIVR_IT_MODEM))
 853                                sx_check_modem(bp);
 854                        else
 855                                printk(KERN_ERR
 856                                  "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
 857                                       board_No(bp), status, ack);
 858
 859                }
 860
 861                sx_out(bp, CD186x_EOIR, 0);   /* Mark end of interrupt */
 862        }
 863        bp->reg = saved_reg;
 864        outb(bp->reg, bp->base + SX_ADDR_REG);
 865        spin_unlock_irqrestore(&bp->lock, flags);
 866        func_exit();
 867        return IRQ_HANDLED;
 868}
 869
 870
 871/*
 872 *  Routines for open & close processing.
 873 */
 874
 875static void turn_ints_off(struct specialix_board *bp)
 876{
 877        unsigned long flags;
 878
 879        func_enter();
 880        spin_lock_irqsave(&bp->lock, flags);
 881        (void) sx_in_off(bp, 0); /* Turn off interrupts. */
 882        spin_unlock_irqrestore(&bp->lock, flags);
 883
 884        func_exit();
 885}
 886
 887static void turn_ints_on(struct specialix_board *bp)
 888{
 889        unsigned long flags;
 890
 891        func_enter();
 892
 893        spin_lock_irqsave(&bp->lock, flags);
 894        (void) sx_in(bp, 0); /* Turn ON interrupts. */
 895        spin_unlock_irqrestore(&bp->lock, flags);
 896
 897        func_exit();
 898}
 899
 900
 901/* Called with disabled interrupts */
 902static int sx_setup_board(struct specialix_board *bp)
 903{
 904        int error;
 905
 906        if (bp->flags & SX_BOARD_ACTIVE)
 907                return 0;
 908
 909        if (bp->flags & SX_BOARD_IS_PCI)
 910                error = request_irq(bp->irq, sx_interrupt,
 911                        IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp);
 912        else
 913                error = request_irq(bp->irq, sx_interrupt,
 914                        IRQF_DISABLED, "specialix IO8+", bp);
 915
 916        if (error)
 917                return error;
 918
 919        turn_ints_on(bp);
 920        bp->flags |= SX_BOARD_ACTIVE;
 921
 922        return 0;
 923}
 924
 925
 926/* Called with disabled interrupts */
 927static void sx_shutdown_board(struct specialix_board *bp)
 928{
 929        func_enter();
 930
 931        if (!(bp->flags & SX_BOARD_ACTIVE)) {
 932                func_exit();
 933                return;
 934        }
 935
 936        bp->flags &= ~SX_BOARD_ACTIVE;
 937
 938        dprintk(SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
 939                 bp->irq, board_No(bp));
 940        free_irq(bp->irq, bp);
 941        turn_ints_off(bp);
 942        func_exit();
 943}
 944
 945static unsigned int sx_crtscts(struct tty_struct *tty)
 946{
 947        if (sx_rtscts)
 948                return C_CRTSCTS(tty);
 949        return 1;
 950}
 951
 952/*
 953 * Setting up port characteristics.
 954 * Must be called with disabled interrupts
 955 */
 956static void sx_change_speed(struct specialix_board *bp,
 957                                                struct specialix_port *port)
 958{
 959        struct tty_struct *tty;
 960        unsigned long baud;
 961        long tmp;
 962        unsigned char cor1 = 0, cor3 = 0;
 963        unsigned char mcor1 = 0, mcor2 = 0;
 964        static unsigned long again;
 965        unsigned long flags;
 966
 967        func_enter();
 968
 969        tty = port->port.tty;
 970        if (!tty || !tty->termios) {
 971                func_exit();
 972                return;
 973        }
 974
 975        port->IER  = 0;
 976        port->COR2 = 0;
 977        /* Select port on the board */
 978        spin_lock_irqsave(&bp->lock, flags);
 979        sx_out(bp, CD186x_CAR, port_No(port));
 980
 981        /* The Specialix board doens't implement the RTS lines.
 982           They are used to set the IRQ level. Don't touch them. */
 983        if (sx_crtscts(tty))
 984                port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
 985        else
 986                port->MSVR =  (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
 987        spin_unlock_irqrestore(&bp->lock, flags);
 988        dprintk(SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
 989        baud = tty_get_baud_rate(tty);
 990
 991        if (baud == 38400) {
 992                if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
 993                        baud = 57600;
 994                if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
 995                        baud = 115200;
 996        }
 997
 998        if (!baud) {
 999                /* Drop DTR & exit */
1000                dprintk(SX_DEBUG_TERMIOS, "Dropping DTR...  Hmm....\n");
1001                if (!sx_crtscts(tty)) {
1002                        port->MSVR &= ~MSVR_DTR;
1003                        spin_lock_irqsave(&bp->lock, flags);
1004                        sx_out(bp, CD186x_MSVR, port->MSVR);
1005                        spin_unlock_irqrestore(&bp->lock, flags);
1006                } else
1007                        dprintk(SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1008                return;
1009        } else {
1010                /* Set DTR on */
1011                if (!sx_crtscts(tty))
1012                        port->MSVR |= MSVR_DTR;
1013        }
1014
1015        /*
1016         * Now we must calculate some speed depended things
1017         */
1018
1019        /* Set baud rate for port */
1020        tmp = port->custom_divisor ;
1021        if (tmp)
1022                printk(KERN_INFO
1023                        "sx%d: Using custom baud rate divisor %ld. \n"
1024                        "This is an untested option, please be careful.\n",
1025                                                        port_No(port), tmp);
1026        else
1027                tmp = (((SX_OSCFREQ + baud/2) / baud + CD186x_TPC/2) /
1028                                                                CD186x_TPC);
1029
1030        if (tmp < 0x10 && time_before(again, jiffies)) {
1031                again = jiffies + HZ * 60;
1032                /* Page 48 of version 2.0 of the CL-CD1865 databook */
1033                if (tmp >= 12) {
1034                        printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1035                                "Performance degradation is possible.\n"
1036                                "Read specialix.txt for more info.\n",
1037                                                port_No(port), tmp);
1038                } else {
1039                        printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1040                "Warning: overstressing Cirrus chip. This might not work.\n"
1041                "Read specialix.txt for more info.\n", port_No(port), tmp);
1042                }
1043        }
1044        spin_lock_irqsave(&bp->lock, flags);
1045        sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1046        sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1047        sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1048        sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1049        spin_unlock_irqrestore(&bp->lock, flags);
1050        if (port->custom_divisor)
1051                baud = (SX_OSCFREQ + port->custom_divisor/2) /
1052                                                        port->custom_divisor;
1053        baud = (baud + 5) / 10;         /* Estimated CPS */
1054
1055        /* Two timer ticks seems enough to wakeup something like SLIP driver */
1056        tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1057        port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1058                                              SERIAL_XMIT_SIZE - 1 : tmp);
1059
1060        /* Receiver timeout will be transmission time for 1.5 chars */
1061        tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1062        tmp = (tmp > 0xff) ? 0xff : tmp;
1063        spin_lock_irqsave(&bp->lock, flags);
1064        sx_out(bp, CD186x_RTPR, tmp);
1065        spin_unlock_irqrestore(&bp->lock, flags);
1066        switch (C_CSIZE(tty)) {
1067        case CS5:
1068                cor1 |= COR1_5BITS;
1069                break;
1070        case CS6:
1071                cor1 |= COR1_6BITS;
1072                break;
1073        case CS7:
1074                cor1 |= COR1_7BITS;
1075                break;
1076        case CS8:
1077                cor1 |= COR1_8BITS;
1078                break;
1079        }
1080
1081        if (C_CSTOPB(tty))
1082                cor1 |= COR1_2SB;
1083
1084        cor1 |= COR1_IGNORE;
1085        if (C_PARENB(tty)) {
1086                cor1 |= COR1_NORMPAR;
1087                if (C_PARODD(tty))
1088                        cor1 |= COR1_ODDP;
1089                if (I_INPCK(tty))
1090                        cor1 &= ~COR1_IGNORE;
1091        }
1092        /* Set marking of some errors */
1093        port->mark_mask = RCSR_OE | RCSR_TOUT;
1094        if (I_INPCK(tty))
1095                port->mark_mask |= RCSR_FE | RCSR_PE;
1096        if (I_BRKINT(tty) || I_PARMRK(tty))
1097                port->mark_mask |= RCSR_BREAK;
1098        if (I_IGNPAR(tty))
1099                port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1100        if (I_IGNBRK(tty)) {
1101                port->mark_mask &= ~RCSR_BREAK;
1102                if (I_IGNPAR(tty))
1103                        /* Real raw mode. Ignore all */
1104                        port->mark_mask &= ~RCSR_OE;
1105        }
1106        /* Enable Hardware Flow Control */
1107        if (C_CRTSCTS(tty)) {
1108#ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1109                port->IER |= IER_DSR | IER_CTS;
1110                mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1111                mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1112                spin_lock_irqsave(&bp->lock, flags);
1113                tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) &
1114                                                        (MSVR_CTS|MSVR_DSR));
1115                spin_unlock_irqrestore(&bp->lock, flags);
1116#else
1117                port->COR2 |= COR2_CTSAE;
1118#endif
1119        }
1120        /* Enable Software Flow Control. FIXME: I'm not sure about this */
1121        /* Some people reported that it works, but I still doubt it */
1122        if (I_IXON(tty)) {
1123                port->COR2 |= COR2_TXIBE;
1124                cor3 |= (COR3_FCT | COR3_SCDE);
1125                if (I_IXANY(tty))
1126                        port->COR2 |= COR2_IXM;
1127                spin_lock_irqsave(&bp->lock, flags);
1128                sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1129                sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1130                sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1131                sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1132                spin_unlock_irqrestore(&bp->lock, flags);
1133        }
1134        if (!C_CLOCAL(tty)) {
1135                /* Enable CD check */
1136                port->IER |= IER_CD;
1137                mcor1 |= MCOR1_CDZD;
1138                mcor2 |= MCOR2_CDOD;
1139        }
1140
1141        if (C_CREAD(tty))
1142                /* Enable receiver */
1143                port->IER |= IER_RXD;
1144
1145        /* Set input FIFO size (1-8 bytes) */
1146        cor3 |= sx_rxfifo;
1147        /* Setting up CD186x channel registers */
1148        spin_lock_irqsave(&bp->lock, flags);
1149        sx_out(bp, CD186x_COR1, cor1);
1150        sx_out(bp, CD186x_COR2, port->COR2);
1151        sx_out(bp, CD186x_COR3, cor3);
1152        spin_unlock_irqrestore(&bp->lock, flags);
1153        /* Make CD186x know about registers change */
1154        sx_wait_CCR(bp);
1155        spin_lock_irqsave(&bp->lock, flags);
1156        sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1157        /* Setting up modem option registers */
1158        dprintk(SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n",
1159                                                                mcor1, mcor2);
1160        sx_out(bp, CD186x_MCOR1, mcor1);
1161        sx_out(bp, CD186x_MCOR2, mcor2);
1162        spin_unlock_irqrestore(&bp->lock, flags);
1163        /* Enable CD186x transmitter & receiver */
1164        sx_wait_CCR(bp);
1165        spin_lock_irqsave(&bp->lock, flags);
1166        sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1167        /* Enable interrupts */
1168        sx_out(bp, CD186x_IER, port->IER);
1169        /* And finally set the modem lines... */
1170        sx_out(bp, CD186x_MSVR, port->MSVR);
1171        spin_unlock_irqrestore(&bp->lock, flags);
1172
1173        func_exit();
1174}
1175
1176
1177/* Must be called with interrupts enabled */
1178static int sx_setup_port(struct specialix_board *bp,
1179                                                struct specialix_port *port)
1180{
1181        unsigned long flags;
1182
1183        func_enter();
1184
1185        if (port->port.flags & ASYNC_INITIALIZED) {
1186                func_exit();
1187                return 0;
1188        }
1189
1190        if (!port->xmit_buf) {
1191                /* We may sleep in get_zeroed_page() */
1192                unsigned long tmp;
1193
1194                tmp = get_zeroed_page(GFP_KERNEL);
1195                if (tmp == 0L) {
1196                        func_exit();
1197                        return -ENOMEM;
1198                }
1199
1200                if (port->xmit_buf) {
1201                        free_page(tmp);
1202                        func_exit();
1203                        return -ERESTARTSYS;
1204                }
1205                port->xmit_buf = (unsigned char *) tmp;
1206        }
1207
1208        spin_lock_irqsave(&port->lock, flags);
1209
1210        if (port->port.tty)
1211                clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
1212
1213        port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1214        sx_change_speed(bp, port);
1215        port->port.flags |= ASYNC_INITIALIZED;
1216
1217        spin_unlock_irqrestore(&port->lock, flags);
1218
1219
1220        func_exit();
1221        return 0;
1222}
1223
1224
1225/* Must be called with interrupts disabled */
1226static void sx_shutdown_port(struct specialix_board *bp,
1227                                                struct specialix_port *port)
1228{
1229        struct tty_struct *tty;
1230        int i;
1231        unsigned long flags;
1232
1233        func_enter();
1234
1235        if (!(port->port.flags & ASYNC_INITIALIZED)) {
1236                func_exit();
1237                return;
1238        }
1239
1240        if (sx_debug & SX_DEBUG_FIFO) {
1241                dprintk(SX_DEBUG_FIFO,
1242                        "sx%d: port %d: %ld overruns, FIFO hits [ ",
1243                                board_No(bp), port_No(port), port->overrun);
1244                for (i = 0; i < 10; i++)
1245                        dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1246                dprintk(SX_DEBUG_FIFO, "].\n");
1247        }
1248
1249        if (port->xmit_buf) {
1250                free_page((unsigned long) port->xmit_buf);
1251                port->xmit_buf = NULL;
1252        }
1253
1254        /* Select port */
1255        spin_lock_irqsave(&bp->lock, flags);
1256        sx_out(bp, CD186x_CAR, port_No(port));
1257
1258        tty = port->port.tty;
1259        if (tty == NULL || C_HUPCL(tty)) {
1260                /* Drop DTR */
1261                sx_out(bp, CD186x_MSVDTR, 0);
1262        }
1263        spin_unlock_irqrestore(&bp->lock, flags);
1264        /* Reset port */
1265        sx_wait_CCR(bp);
1266        spin_lock_irqsave(&bp->lock, flags);
1267        sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1268        /* Disable all interrupts from this port */
1269        port->IER = 0;
1270        sx_out(bp, CD186x_IER, port->IER);
1271        spin_unlock_irqrestore(&bp->lock, flags);
1272        if (tty)
1273                set_bit(TTY_IO_ERROR, &tty->flags);
1274        port->port.flags &= ~ASYNC_INITIALIZED;
1275
1276        if (!bp->count)
1277                sx_shutdown_board(bp);
1278        func_exit();
1279}
1280
1281
1282static int block_til_ready(struct tty_struct *tty, struct file *filp,
1283                                                struct specialix_port *port)
1284{
1285        DECLARE_WAITQUEUE(wait,  current);
1286        struct specialix_board *bp = port_Board(port);
1287        int    retval;
1288        int    do_clocal = 0;
1289        int    CD;
1290        unsigned long flags;
1291
1292        func_enter();
1293
1294        /*
1295         * If the device is in the middle of being closed, then block
1296         * until it's done, and then try again.
1297         */
1298        if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
1299                interruptible_sleep_on(&port->port.close_wait);
1300                if (port->port.flags & ASYNC_HUP_NOTIFY) {
1301                        func_exit();
1302                        return -EAGAIN;
1303                } else {
1304                        func_exit();
1305                        return -ERESTARTSYS;
1306                }
1307        }
1308
1309        /*
1310         * If non-blocking mode is set, or the port is not enabled,
1311         * then make the check up front and then exit.
1312         */
1313        if ((filp->f_flags & O_NONBLOCK) ||
1314            (tty->flags & (1 << TTY_IO_ERROR))) {
1315                port->port.flags |= ASYNC_NORMAL_ACTIVE;
1316                func_exit();
1317                return 0;
1318        }
1319
1320        if (C_CLOCAL(tty))
1321                do_clocal = 1;
1322
1323        /*
1324         * Block waiting for the carrier detect and the line to become
1325         * free (i.e., not in use by the callout).  While we are in
1326         * this loop, info->count is dropped by one, so that
1327         * rs_close() knows when to free things.  We restore it upon
1328         * exit, either normal or abnormal.
1329         */
1330        retval = 0;
1331        add_wait_queue(&port->port.open_wait, &wait);
1332        spin_lock_irqsave(&port->lock, flags);
1333        if (!tty_hung_up_p(filp))
1334                port->port.count--;
1335        spin_unlock_irqrestore(&port->lock, flags);
1336        port->port.blocked_open++;
1337        while (1) {
1338                spin_lock_irqsave(&bp->lock, flags);
1339                sx_out(bp, CD186x_CAR, port_No(port));
1340                CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1341                if (sx_crtscts(tty)) {
1342                        /* Activate RTS */
1343                        port->MSVR |= MSVR_DTR;         /* WTF? */
1344                        sx_out(bp, CD186x_MSVR, port->MSVR);
1345                } else {
1346                        /* Activate DTR */
1347                        port->MSVR |= MSVR_DTR;
1348                        sx_out(bp, CD186x_MSVR, port->MSVR);
1349                }
1350                spin_unlock_irqrestore(&bp->lock, flags);
1351                set_current_state(TASK_INTERRUPTIBLE);
1352                if (tty_hung_up_p(filp) ||
1353                    !(port->port.flags & ASYNC_INITIALIZED)) {
1354                        if (port->port.flags & ASYNC_HUP_NOTIFY)
1355                                retval = -EAGAIN;
1356                        else
1357                                retval = -ERESTARTSYS;
1358                        break;
1359                }
1360                if (!(port->port.flags & ASYNC_CLOSING) &&
1361                    (do_clocal || CD))
1362                        break;
1363                if (signal_pending(current)) {
1364                        retval = -ERESTARTSYS;
1365                        break;
1366                }
1367                tty_unlock();
1368                schedule();
1369                tty_lock();
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        mutex_lock(&port->port.mutex);
1868        change_speed = ((port->port.flags & ASYNC_SPD_MASK) !=
1869                        (tmp.flags & ASYNC_SPD_MASK));
1870        change_speed |= (tmp.custom_divisor != port->custom_divisor);
1871
1872        if (!capable(CAP_SYS_ADMIN)) {
1873                if ((tmp.close_delay != port->port.close_delay) ||
1874                    (tmp.closing_wait != port->port.closing_wait) ||
1875                    ((tmp.flags & ~ASYNC_USR_MASK) !=
1876                     (port->port.flags & ~ASYNC_USR_MASK))) {
1877                        func_exit();
1878                        mutex_unlock(&port->port.mutex);
1879                        return -EPERM;
1880                }
1881                port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1882                                                (tmp.flags & ASYNC_USR_MASK));
1883                port->custom_divisor = tmp.custom_divisor;
1884        } else {
1885                port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1886                                                (tmp.flags & ASYNC_FLAGS));
1887                port->port.close_delay = tmp.close_delay;
1888                port->port.closing_wait = tmp.closing_wait;
1889                port->custom_divisor = tmp.custom_divisor;
1890        }
1891        if (change_speed)
1892                sx_change_speed(bp, port);
1893
1894        func_exit();
1895        mutex_unlock(&port->port.mutex);
1896        return 0;
1897}
1898
1899
1900static int sx_get_serial_info(struct specialix_port *port,
1901                                     struct serial_struct __user *retinfo)
1902{
1903        struct serial_struct tmp;
1904        struct specialix_board *bp = port_Board(port);
1905
1906        func_enter();
1907
1908        memset(&tmp, 0, sizeof(tmp));
1909        mutex_lock(&port->port.mutex);
1910        tmp.type = PORT_CIRRUS;
1911        tmp.line = port - sx_port;
1912        tmp.port = bp->base;
1913        tmp.irq  = bp->irq;
1914        tmp.flags = port->port.flags;
1915        tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
1916        tmp.close_delay = port->port.close_delay * HZ/100;
1917        tmp.closing_wait = port->port.closing_wait * HZ/100;
1918        tmp.custom_divisor =  port->custom_divisor;
1919        tmp.xmit_fifo_size = CD186x_NFIFO;
1920        mutex_unlock(&port->port.mutex);
1921        if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
1922                func_exit();
1923                return -EFAULT;
1924        }
1925
1926        func_exit();
1927        return 0;
1928}
1929
1930
1931static int sx_ioctl(struct tty_struct *tty, struct file *filp,
1932                                unsigned int cmd, unsigned long arg)
1933{
1934        struct specialix_port *port = tty->driver_data;
1935        void __user *argp = (void __user *)arg;
1936
1937        func_enter();
1938
1939        if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
1940                func_exit();
1941                return -ENODEV;
1942        }
1943
1944        switch (cmd) {
1945        case TIOCGSERIAL:
1946                func_exit();
1947                return sx_get_serial_info(port, argp);
1948        case TIOCSSERIAL:
1949                func_exit();
1950                return sx_set_serial_info(port, argp);
1951        default:
1952                func_exit();
1953                return -ENOIOCTLCMD;
1954        }
1955        func_exit();
1956        return 0;
1957}
1958
1959
1960static void sx_throttle(struct tty_struct *tty)
1961{
1962        struct specialix_port *port = tty->driver_data;
1963        struct specialix_board *bp;
1964        unsigned long flags;
1965
1966        func_enter();
1967
1968        if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
1969                func_exit();
1970                return;
1971        }
1972
1973        bp = port_Board(port);
1974
1975        /* Use DTR instead of RTS ! */
1976        if (sx_crtscts(tty))
1977                port->MSVR &= ~MSVR_DTR;
1978        else {
1979                /* Auch!!! I think the system shouldn't call this then. */
1980                /* Or maybe we're supposed (allowed?) to do our side of hw
1981                   handshake anyway, even when hardware handshake is off.
1982                   When you see this in your logs, please report.... */
1983                printk(KERN_ERR
1984                   "sx%d: Need to throttle, but can't (hardware hs is off)\n",
1985                                                        port_No(port));
1986        }
1987        spin_lock_irqsave(&bp->lock, flags);
1988        sx_out(bp, CD186x_CAR, port_No(port));
1989        spin_unlock_irqrestore(&bp->lock, flags);
1990        if (I_IXOFF(tty)) {
1991                sx_wait_CCR(bp);
1992                spin_lock_irqsave(&bp->lock, flags);
1993                sx_out(bp, CD186x_CCR, CCR_SSCH2);
1994                spin_unlock_irqrestore(&bp->lock, flags);
1995                sx_wait_CCR(bp);
1996        }
1997        spin_lock_irqsave(&bp->lock, flags);
1998        sx_out(bp, CD186x_MSVR, port->MSVR);
1999        spin_unlock_irqrestore(&bp->lock, flags);
2000
2001        func_exit();
2002}
2003
2004
2005static void sx_unthrottle(struct tty_struct *tty)
2006{
2007        struct specialix_port *port = tty->driver_data;
2008        struct specialix_board *bp;
2009        unsigned long flags;
2010
2011        func_enter();
2012
2013        if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
2014                func_exit();
2015                return;
2016        }
2017
2018        bp = port_Board(port);
2019
2020        spin_lock_irqsave(&port->lock, flags);
2021        /* XXXX Use DTR INSTEAD???? */
2022        if (sx_crtscts(tty))
2023                port->MSVR |= MSVR_DTR;
2024        /* Else clause: see remark in "sx_throttle"... */
2025        spin_lock(&bp->lock);
2026        sx_out(bp, CD186x_CAR, port_No(port));
2027        spin_unlock(&bp->lock);
2028        if (I_IXOFF(tty)) {
2029                spin_unlock_irqrestore(&port->lock, flags);
2030                sx_wait_CCR(bp);
2031                spin_lock_irqsave(&bp->lock, flags);
2032                sx_out(bp, CD186x_CCR, CCR_SSCH1);
2033                spin_unlock_irqrestore(&bp->lock, flags);
2034                sx_wait_CCR(bp);
2035                spin_lock_irqsave(&port->lock, flags);
2036        }
2037        spin_lock(&bp->lock);
2038        sx_out(bp, CD186x_MSVR, port->MSVR);
2039        spin_unlock(&bp->lock);
2040        spin_unlock_irqrestore(&port->lock, flags);
2041
2042        func_exit();
2043}
2044
2045
2046static void sx_stop(struct tty_struct *tty)
2047{
2048        struct specialix_port *port = tty->driver_data;
2049        struct specialix_board *bp;
2050        unsigned long flags;
2051
2052        func_enter();
2053
2054        if (sx_paranoia_check(port, tty->name, "sx_stop")) {
2055                func_exit();
2056                return;
2057        }
2058
2059        bp = port_Board(port);
2060
2061        spin_lock_irqsave(&port->lock, flags);
2062        port->IER &= ~IER_TXRDY;
2063        spin_lock(&bp->lock);
2064        sx_out(bp, CD186x_CAR, port_No(port));
2065        sx_out(bp, CD186x_IER, port->IER);
2066        spin_unlock(&bp->lock);
2067        spin_unlock_irqrestore(&port->lock, flags);
2068
2069        func_exit();
2070}
2071
2072
2073static void sx_start(struct tty_struct *tty)
2074{
2075        struct specialix_port *port = tty->driver_data;
2076        struct specialix_board *bp;
2077        unsigned long flags;
2078
2079        func_enter();
2080
2081        if (sx_paranoia_check(port, tty->name, "sx_start")) {
2082                func_exit();
2083                return;
2084        }
2085
2086        bp = port_Board(port);
2087
2088        spin_lock_irqsave(&port->lock, flags);
2089        if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2090                port->IER |= IER_TXRDY;
2091                spin_lock(&bp->lock);
2092                sx_out(bp, CD186x_CAR, port_No(port));
2093                sx_out(bp, CD186x_IER, port->IER);
2094                spin_unlock(&bp->lock);
2095        }
2096        spin_unlock_irqrestore(&port->lock, flags);
2097
2098        func_exit();
2099}
2100
2101static void sx_hangup(struct tty_struct *tty)
2102{
2103        struct specialix_port *port = tty->driver_data;
2104        struct specialix_board *bp;
2105        unsigned long flags;
2106
2107        func_enter();
2108
2109        if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2110                func_exit();
2111                return;
2112        }
2113
2114        bp = port_Board(port);
2115
2116        sx_shutdown_port(bp, port);
2117        spin_lock_irqsave(&port->lock, flags);
2118        bp->count -= port->port.count;
2119        if (bp->count < 0) {
2120                printk(KERN_ERR
2121                        "sx%d: sx_hangup: bad board count: %d port: %d\n",
2122                                        board_No(bp), bp->count, tty->index);
2123                bp->count = 0;
2124        }
2125        port->port.count = 0;
2126        port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
2127        port->port.tty = NULL;
2128        spin_unlock_irqrestore(&port->lock, flags);
2129        wake_up_interruptible(&port->port.open_wait);
2130
2131        func_exit();
2132}
2133
2134
2135static void sx_set_termios(struct tty_struct *tty,
2136                                        struct ktermios *old_termios)
2137{
2138        struct specialix_port *port = tty->driver_data;
2139        unsigned long flags;
2140        struct specialix_board  *bp;
2141
2142        if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2143                return;
2144
2145        bp = port_Board(port);
2146        spin_lock_irqsave(&port->lock, flags);
2147        sx_change_speed(port_Board(port), port);
2148        spin_unlock_irqrestore(&port->lock, flags);
2149
2150        if ((old_termios->c_cflag & CRTSCTS) &&
2151            !(tty->termios->c_cflag & CRTSCTS)) {
2152                tty->hw_stopped = 0;
2153                sx_start(tty);
2154        }
2155}
2156
2157static const struct tty_operations sx_ops = {
2158        .open  = sx_open,
2159        .close = sx_close,
2160        .write = sx_write,
2161        .put_char = sx_put_char,
2162        .flush_chars = sx_flush_chars,
2163        .write_room = sx_write_room,
2164        .chars_in_buffer = sx_chars_in_buffer,
2165        .flush_buffer = sx_flush_buffer,
2166        .ioctl = sx_ioctl,
2167        .throttle = sx_throttle,
2168        .unthrottle = sx_unthrottle,
2169        .set_termios = sx_set_termios,
2170        .stop = sx_stop,
2171        .start = sx_start,
2172        .hangup = sx_hangup,
2173        .tiocmget = sx_tiocmget,
2174        .tiocmset = sx_tiocmset,
2175        .break_ctl = sx_send_break,
2176};
2177
2178static int sx_init_drivers(void)
2179{
2180        int error;
2181        int i;
2182
2183        func_enter();
2184
2185        specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT);
2186        if (!specialix_driver) {
2187                printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n");
2188                func_exit();
2189                return 1;
2190        }
2191
2192        specialix_driver->owner = THIS_MODULE;
2193        specialix_driver->name = "ttyW";
2194        specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
2195        specialix_driver->type = TTY_DRIVER_TYPE_SERIAL;
2196        specialix_driver->subtype = SERIAL_TYPE_NORMAL;
2197        specialix_driver->init_termios = tty_std_termios;
2198        specialix_driver->init_termios.c_cflag =
2199                B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2200        specialix_driver->init_termios.c_ispeed = 9600;
2201        specialix_driver->init_termios.c_ospeed = 9600;
2202        specialix_driver->flags = TTY_DRIVER_REAL_RAW |
2203                                                TTY_DRIVER_HARDWARE_BREAK;
2204        tty_set_operations(specialix_driver, &sx_ops);
2205
2206        error = tty_register_driver(specialix_driver);
2207        if (error) {
2208                put_tty_driver(specialix_driver);
2209                printk(KERN_ERR
2210                  "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2211                                                                error);
2212                func_exit();
2213                return 1;
2214        }
2215        memset(sx_port, 0, sizeof(sx_port));
2216        for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2217                sx_port[i].magic = SPECIALIX_MAGIC;
2218                tty_port_init(&sx_port[i].port);
2219                spin_lock_init(&sx_port[i].lock);
2220        }
2221
2222        func_exit();
2223        return 0;
2224}
2225
2226static void sx_release_drivers(void)
2227{
2228        func_enter();
2229
2230        tty_unregister_driver(specialix_driver);
2231        put_tty_driver(specialix_driver);
2232        func_exit();
2233}
2234
2235/*
2236 * This routine must be called by kernel at boot time
2237 */
2238static int __init specialix_init(void)
2239{
2240        int i;
2241        int found = 0;
2242
2243        func_enter();
2244
2245        printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
2246        printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2247        if (sx_rtscts)
2248                printk(KERN_INFO
2249                        "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2250        else
2251                printk(KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
2252
2253        for (i = 0; i < SX_NBOARD; i++)
2254                spin_lock_init(&sx_board[i].lock);
2255
2256        if (sx_init_drivers()) {
2257                func_exit();
2258                return -EIO;
2259        }
2260
2261        for (i = 0; i < SX_NBOARD; i++)
2262                if (sx_board[i].base && !sx_probe(&sx_board[i]))
2263                        found++;
2264
2265#ifdef CONFIG_PCI
2266        {
2267                struct pci_dev *pdev = NULL;
2268
2269                i = 0;
2270                while (i < SX_NBOARD) {
2271                        if (sx_board[i].flags & SX_BOARD_PRESENT) {
2272                                i++;
2273                                continue;
2274                        }
2275                        pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX,
2276                                        PCI_DEVICE_ID_SPECIALIX_IO8, pdev);
2277                        if (!pdev)
2278                                break;
2279
2280                        if (pci_enable_device(pdev))
2281                                continue;
2282
2283                        sx_board[i].irq = pdev->irq;
2284
2285                        sx_board[i].base = pci_resource_start(pdev, 2);
2286
2287                        sx_board[i].flags |= SX_BOARD_IS_PCI;
2288                        if (!sx_probe(&sx_board[i]))
2289                                found++;
2290                }
2291                /* May exit pci_get sequence early with lots of boards */
2292                if (pdev != NULL)
2293                        pci_dev_put(pdev);
2294        }
2295#endif
2296
2297        if (!found) {
2298                sx_release_drivers();
2299                printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
2300                func_exit();
2301                return -EIO;
2302        }
2303
2304        func_exit();
2305        return 0;
2306}
2307
2308static int iobase[SX_NBOARD]  = {0,};
2309static int irq[SX_NBOARD] = {0,};
2310
2311module_param_array(iobase, int, NULL, 0);
2312module_param_array(irq, int, NULL, 0);
2313module_param(sx_debug, int, 0);
2314module_param(sx_rtscts, int, 0);
2315module_param(sx_rxfifo, int, 0);
2316
2317/*
2318 * You can setup up to 4 boards.
2319 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2320 * You should specify the IRQs too in that case "irq=....,...".
2321 *
2322 * More than 4 boards in one computer is not possible, as the card can
2323 * only use 4 different interrupts.
2324 *
2325 */
2326static int __init specialix_init_module(void)
2327{
2328        int i;
2329
2330        func_enter();
2331
2332        if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2333                for (i = 0; i < SX_NBOARD; i++) {
2334                        sx_board[i].base = iobase[i];
2335                        sx_board[i].irq = irq[i];
2336                        sx_board[i].count = 0;
2337                }
2338        }
2339
2340        func_exit();
2341
2342        return specialix_init();
2343}
2344
2345static void __exit specialix_exit_module(void)
2346{
2347        int i;
2348
2349        func_enter();
2350
2351        sx_release_drivers();
2352        for (i = 0; i < SX_NBOARD; i++)
2353                if (sx_board[i].flags & SX_BOARD_PRESENT)
2354                        sx_release_io_range(&sx_board[i]);
2355        func_exit();
2356}
2357
2358static struct pci_device_id specialx_pci_tbl[] __devinitdata __used = {
2359        { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) },
2360        { }
2361};
2362MODULE_DEVICE_TABLE(pci, specialx_pci_tbl);
2363
2364module_init(specialix_init_module);
2365module_exit(specialix_exit_module);
2366
2367MODULE_LICENSE("GPL");
2368MODULE_ALIAS_CHARDEV_MAJOR(SPECIALIX_NORMAL_MAJOR);
2369