Showing error 1685

User: Jiri Slaby
Error type: Double Lock
Error type description: Some lock is locked twice unintentionally in a sequence
File location: drivers/char/specialix.c
Line in file: 1835
Project: Linux Kernel
Project version: 2.6.28
Confirmation: Fixed by 254702568da63ce6f5ad68e77d83b427da693654
Tools: Smatch (1.59)
Entered: 2013-09-10 14:01:52 UTC


Source:

   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
  97#include "specialix_io8.h"
  98#include "cd1865.h"
  99
 100
 101/*
 102   This driver can spew a whole lot of debugging output at you. If you
 103   need maximum performance, you should disable the DEBUG define. To
 104   aid in debugging in the field, I'm leaving the compile-time debug
 105   features enabled, and disable them "runtime". That allows me to
 106   instruct people with problems to enable debugging without requiring
 107   them to recompile...
 108*/
 109#define DEBUG
 110
 111static int sx_debug;
 112static int sx_rxfifo = SPECIALIX_RXFIFO;
 113static int sx_rtscts;
 114
 115#ifdef DEBUG
 116#define dprintk(f, str...) if (sx_debug & f) printk(str)
 117#else
 118#define dprintk(f, str...) /* nothing */
 119#endif
 120
 121#define SX_DEBUG_FLOW    0x0001
 122#define SX_DEBUG_DATA    0x0002
 123#define SX_DEBUG_PROBE   0x0004
 124#define SX_DEBUG_CHAN    0x0008
 125#define SX_DEBUG_INIT    0x0010
 126#define SX_DEBUG_RX      0x0020
 127#define SX_DEBUG_TX      0x0040
 128#define SX_DEBUG_IRQ     0x0080
 129#define SX_DEBUG_OPEN    0x0100
 130#define SX_DEBUG_TERMIOS 0x0200
 131#define SX_DEBUG_SIGNALS 0x0400
 132#define SX_DEBUG_FIFO    0x0800
 133
 134
 135#define func_enter() dprintk(SX_DEBUG_FLOW, "io8: enter %s\n", __func__)
 136#define func_exit()  dprintk(SX_DEBUG_FLOW, "io8: exit  %s\n", __func__)
 137
 138
 139/* Configurable options: */
 140
 141/* Am I paranoid or not ? ;-) */
 142#define SPECIALIX_PARANOIA_CHECK
 143
 144/*
 145 * The following defines are mostly for testing purposes. But if you need
 146 * some nice reporting in your syslog, you can define them also.
 147 */
 148#undef SX_REPORT_FIFO
 149#undef SX_REPORT_OVERRUN
 150
 151
 152
 153
 154#define SPECIALIX_LEGAL_FLAGS \
 155        (ASYNC_HUP_NOTIFY   | ASYNC_SAK          | ASYNC_SPLIT_TERMIOS   | \
 156         ASYNC_SPD_HI       | ASYNC_SPEED_VHI    | ASYNC_SESSION_LOCKOUT | \
 157         ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
 158
 159static struct tty_driver *specialix_driver;
 160
 161static struct specialix_board sx_board[SX_NBOARD] =  {
 162        { 0, SX_IOBASE1,  9, },
 163        { 0, SX_IOBASE2, 11, },
 164        { 0, SX_IOBASE3, 12, },
 165        { 0, SX_IOBASE4, 15, },
 166};
 167
 168static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
 169
 170
 171static int sx_paranoia_check(struct specialix_port const *port,
 172                                    char *name, const char *routine)
 173{
 174#ifdef SPECIALIX_PARANOIA_CHECK
 175        static const char *badmagic = KERN_ERR
 176          "sx: Warning: bad specialix port magic number for device %s in %s\n";
 177        static const char *badinfo = KERN_ERR
 178          "sx: Warning: null specialix port for device %s in %s\n";
 179
 180        if (!port) {
 181                printk(badinfo, name, routine);
 182                return 1;
 183        }
 184        if (port->magic != SPECIALIX_MAGIC) {
 185                printk(badmagic, name, routine);
 186                return 1;
 187        }
 188#endif
 189        return 0;
 190}
 191
 192
 193/*
 194 *
 195 *  Service functions for specialix IO8+ driver.
 196 *
 197 */
 198
 199/* Get board number from pointer */
 200static inline int board_No(struct specialix_board *bp)
 201{
 202        return bp - sx_board;
 203}
 204
 205
 206/* Get port number from pointer */
 207static inline int port_No(struct specialix_port const *port)
 208{
 209        return SX_PORT(port - sx_port);
 210}
 211
 212
 213/* Get pointer to board from pointer to port */
 214static inline struct specialix_board *port_Board(
 215                                        struct specialix_port const *port)
 216{
 217        return &sx_board[SX_BOARD(port - sx_port)];
 218}
 219
 220
 221/* Input Byte from CL CD186x register */
 222static inline unsigned char sx_in(struct specialix_board *bp,
 223                                                        unsigned short reg)
 224{
 225        bp->reg = reg | 0x80;
 226        outb(reg | 0x80, bp->base + SX_ADDR_REG);
 227        return inb(bp->base + SX_DATA_REG);
 228}
 229
 230
 231/* Output Byte to CL CD186x register */
 232static inline void sx_out(struct specialix_board *bp, unsigned short reg,
 233                          unsigned char val)
 234{
 235        bp->reg = reg | 0x80;
 236        outb(reg | 0x80, bp->base + SX_ADDR_REG);
 237        outb(val, bp->base + SX_DATA_REG);
 238}
 239
 240
 241/* Input Byte from CL CD186x register */
 242static inline unsigned char sx_in_off(struct specialix_board *bp,
 243                                unsigned short reg)
 244{
 245        bp->reg = reg;
 246        outb(reg, bp->base + SX_ADDR_REG);
 247        return inb(bp->base + SX_DATA_REG);
 248}
 249
 250
 251/* Output Byte to CL CD186x register */
 252static inline void sx_out_off(struct specialix_board  *bp,
 253                                unsigned short reg, unsigned char val)
 254{
 255        bp->reg = reg;
 256        outb(reg, bp->base + SX_ADDR_REG);
 257        outb(val, bp->base + SX_DATA_REG);
 258}
 259
 260
 261/* Wait for Channel Command Register ready */
 262static void sx_wait_CCR(struct specialix_board  *bp)
 263{
 264        unsigned long delay, flags;
 265        unsigned char ccr;
 266
 267        for (delay = SX_CCR_TIMEOUT; delay; delay--) {
 268                spin_lock_irqsave(&bp->lock, flags);
 269                ccr = sx_in(bp, CD186x_CCR);
 270                spin_unlock_irqrestore(&bp->lock, flags);
 271                if (!ccr)
 272                        return;
 273                udelay(1);
 274        }
 275
 276        printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
 277}
 278
 279
 280/* Wait for Channel Command Register ready */
 281static void sx_wait_CCR_off(struct specialix_board  *bp)
 282{
 283        unsigned long delay;
 284        unsigned char crr;
 285        unsigned long flags;
 286
 287        for (delay = SX_CCR_TIMEOUT; delay; delay--) {
 288                spin_lock_irqsave(&bp->lock, flags);
 289                crr = sx_in_off(bp, CD186x_CCR);
 290                spin_unlock_irqrestore(&bp->lock, flags);
 291                if (!crr)
 292                        return;
 293                udelay(1);
 294        }
 295
 296        printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
 297}
 298
 299
 300/*
 301 *  specialix IO8+ IO range functions.
 302 */
 303
 304static int sx_request_io_range(struct specialix_board *bp)
 305{
 306        return request_region(bp->base,
 307                bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
 308                "specialix IO8+") == NULL;
 309}
 310
 311
 312static void sx_release_io_range(struct specialix_board *bp)
 313{
 314        release_region(bp->base, bp->flags & SX_BOARD_IS_PCI ?
 315                                        SX_PCI_IO_SPACE : SX_IO_SPACE);
 316}
 317
 318
 319/* Set the IRQ using the RTS lines that run to the PAL on the board.... */
 320static int sx_set_irq(struct specialix_board *bp)
 321{
 322        int virq;
 323        int i;
 324        unsigned long flags;
 325
 326        if (bp->flags & SX_BOARD_IS_PCI)
 327                return 1;
 328        switch (bp->irq) {
 329        /* In the same order as in the docs... */
 330        case 15:
 331                virq = 0;
 332                break;
 333        case 12:
 334                virq = 1;
 335                break;
 336        case 11:
 337                virq = 2;
 338                break;
 339        case 9:
 340                virq = 3;
 341                break;
 342        default:printk(KERN_ERR
 343                            "Speclialix: cannot set irq to %d.\n", bp->irq);
 344                return 0;
 345        }
 346        spin_lock_irqsave(&bp->lock, flags);
 347        for (i = 0; i < 2; i++) {
 348                sx_out(bp, CD186x_CAR, i);
 349                sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
 350        }
 351        spin_unlock_irqrestore(&bp->lock, flags);
 352        return 1;
 353}
 354
 355
 356/* Reset and setup CD186x chip */
 357static int sx_init_CD186x(struct specialix_board  *bp)
 358{
 359        unsigned long flags;
 360        int scaler;
 361        int rv = 1;
 362
 363        func_enter();
 364        sx_wait_CCR_off(bp);                           /* Wait for CCR ready        */
 365        spin_lock_irqsave(&bp->lock, flags);
 366        sx_out_off(bp, CD186x_CCR, CCR_HARDRESET);      /* Reset CD186x chip          */
 367        spin_unlock_irqrestore(&bp->lock, flags);
 368        msleep(50);                                        /* Delay 0.05 sec            */
 369        spin_lock_irqsave(&bp->lock, flags);
 370        sx_out_off(bp, CD186x_GIVR, SX_ID);             /* Set ID for this chip      */
 371        sx_out_off(bp, CD186x_GICR, 0);                 /* Clear all bits            */
 372        sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT);      /* Prio for modem intr       */
 373        sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT);      /* Prio for transmitter intr */
 374        sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT);      /* Prio for receiver intr    */
 375        /* Set RegAckEn */
 376        sx_out_off(bp, CD186x_SRCR, sx_in(bp, CD186x_SRCR) | SRCR_REGACKEN);
 377
 378        /* Setting up prescaler. We need 4 ticks per 1 ms */
 379        scaler =  SX_OSCFREQ/SPECIALIX_TPS;
 380
 381        sx_out_off(bp, CD186x_PPRH, scaler >> 8);
 382        sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
 383        spin_unlock_irqrestore(&bp->lock, flags);
 384
 385        if (!sx_set_irq(bp)) {
 386                /* Figure out how to pass this along... */
 387                printk(KERN_ERR "Cannot set irq to %d.\n", bp->irq);
 388                rv = 0;
 389        }
 390
 391        func_exit();
 392        return rv;
 393}
 394
 395
 396static int read_cross_byte(struct specialix_board *bp, int reg, int bit)
 397{
 398        int i;
 399        int t;
 400        unsigned long flags;
 401
 402        spin_lock_irqsave(&bp->lock, flags);
 403        for (i = 0, t = 0; i < 8; i++) {
 404                sx_out_off(bp, CD186x_CAR, i);
 405                if (sx_in_off(bp, reg) & bit)
 406                        t |= 1 << i;
 407        }
 408        spin_unlock_irqrestore(&bp->lock, flags);
 409
 410        return t;
 411}
 412
 413
 414/* Main probing routine, also sets irq. */
 415static int sx_probe(struct specialix_board *bp)
 416{
 417        unsigned char val1, val2;
 418        int rev;
 419        int chip;
 420
 421        func_enter();
 422
 423        if (sx_request_io_range(bp)) {
 424                func_exit();
 425                return 1;
 426        }
 427
 428        /* Are the I/O ports here ? */
 429        sx_out_off(bp, CD186x_PPRL, 0x5a);
 430        udelay(1);
 431        val1 = sx_in_off(bp, CD186x_PPRL);
 432
 433        sx_out_off(bp, CD186x_PPRL, 0xa5);
 434        udelay(1);
 435        val2 = sx_in_off(bp, CD186x_PPRL);
 436
 437
 438        if (val1 != 0x5a || val2 != 0xa5) {
 439                printk(KERN_INFO
 440                        "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
 441                                                board_No(bp), bp->base);
 442                sx_release_io_range(bp);
 443                func_exit();
 444                return 1;
 445        }
 446
 447        /* Check the DSR lines that Specialix uses as board
 448           identification */
 449        val1 = read_cross_byte(bp, CD186x_MSVR, MSVR_DSR);
 450        val2 = read_cross_byte(bp, CD186x_MSVR, MSVR_RTS);
 451        dprintk(SX_DEBUG_INIT,
 452                        "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
 453                                        board_No(bp), val1, val2);
 454
 455        /* They managed to switch the bit order between the docs and
 456           the IO8+ card. The new PCI card now conforms to old docs.
 457           They changed the PCI docs to reflect the situation on the
 458           old card. */
 459        val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
 460        if (val1 != val2) {
 461                printk(KERN_INFO
 462                  "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
 463                       board_No(bp), val2, bp->base, val1);
 464                sx_release_io_range(bp);
 465                func_exit();
 466                return 1;
 467        }
 468
 469
 470        /* Reset CD186x again  */
 471        if (!sx_init_CD186x(bp)) {
 472                sx_release_io_range(bp);
 473                func_exit();
 474                return 1;
 475        }
 476
 477        sx_request_io_range(bp);
 478        bp->flags |= SX_BOARD_PRESENT;
 479
 480        /* Chip           revcode   pkgtype
 481                          GFRCR     SRCR bit 7
 482           CD180 rev B    0x81      0
 483           CD180 rev C    0x82      0
 484           CD1864 rev A   0x82      1
 485           CD1865 rev A   0x83      1  -- Do not use!!! Does not work.
 486           CD1865 rev B   0x84      1
 487         -- Thanks to Gwen Wang, Cirrus Logic.
 488         */
 489
 490        switch (sx_in_off(bp, CD186x_GFRCR)) {
 491        case 0x82:
 492                chip = 1864;
 493                rev = 'A';
 494                break;
 495        case 0x83:
 496                chip = 1865;
 497                rev = 'A';
 498                break;
 499        case 0x84:
 500                chip = 1865;
 501                rev = 'B';
 502                break;
 503        case 0x85:
 504                chip = 1865;
 505                rev = 'C';
 506                break; /* Does not exist at this time */
 507        default:
 508                chip = -1;
 509                rev = 'x';
 510        }
 511
 512        dprintk(SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR));
 513
 514        printk(KERN_INFO
 515    "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
 516                                board_No(bp), bp->base, bp->irq, chip, rev);
 517
 518        func_exit();
 519        return 0;
 520}
 521
 522/*
 523 *
 524 *  Interrupt processing routines.
 525 * */
 526
 527static struct specialix_port *sx_get_port(struct specialix_board *bp,
 528                                               unsigned char const *what)
 529{
 530        unsigned char channel;
 531        struct specialix_port *port = NULL;
 532
 533        channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
 534        dprintk(SX_DEBUG_CHAN, "channel: %d\n", channel);
 535        if (channel < CD186x_NCH) {
 536                port = &sx_port[board_No(bp) * SX_NPORT + channel];
 537                dprintk(SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n",
 538                        board_No(bp) * SX_NPORT + channel,  port,
 539                        port->port.flags & ASYNC_INITIALIZED);
 540
 541                if (port->port.flags & ASYNC_INITIALIZED) {
 542                        dprintk(SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
 543                        func_exit();
 544                        return port;
 545                }
 546        }
 547        printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
 548               board_No(bp), what, channel);
 549        return NULL;
 550}
 551
 552
 553static void sx_receive_exc(struct specialix_board *bp)
 554{
 555        struct specialix_port *port;
 556        struct tty_struct *tty;
 557        unsigned char status;
 558        unsigned char ch, flag;
 559
 560        func_enter();
 561
 562        port = sx_get_port(bp, "Receive");
 563        if (!port) {
 564                dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n");
 565                func_exit();
 566                return;
 567        }
 568        tty = port->port.tty;
 569
 570        status = sx_in(bp, CD186x_RCSR);
 571
 572        dprintk(SX_DEBUG_RX, "status: 0x%x\n", status);
 573        if (status & RCSR_OE) {
 574                port->overrun++;
 575                dprintk(SX_DEBUG_FIFO,
 576                        "sx%d: port %d: Overrun. Total %ld overruns.\n",
 577                                board_No(bp), port_No(port), port->overrun);
 578        }
 579        status &= port->mark_mask;
 580
 581        /* This flip buffer check needs to be below the reading of the
 582           status register to reset the chip's IRQ.... */
 583        if (tty_buffer_request_room(tty, 1) == 0) {
 584                dprintk(SX_DEBUG_FIFO,
 585                    "sx%d: port %d: Working around flip buffer overflow.\n",
 586                                        board_No(bp), port_No(port));
 587                func_exit();
 588                return;
 589        }
 590
 591        ch = sx_in(bp, CD186x_RDR);
 592        if (!status) {
 593                func_exit();
 594                return;
 595        }
 596        if (status & RCSR_TOUT) {
 597                printk(KERN_INFO
 598                    "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
 599                                        board_No(bp), port_No(port));
 600                func_exit();
 601                return;
 602
 603        } else if (status & RCSR_BREAK) {
 604                dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
 605                       board_No(bp), port_No(port));
 606                flag = TTY_BREAK;
 607                if (port->port.flags & ASYNC_SAK)
 608                        do_SAK(tty);
 609
 610        } else if (status & RCSR_PE)
 611                flag = TTY_PARITY;
 612
 613        else if (status & RCSR_FE)
 614                flag = TTY_FRAME;
 615
 616        else if (status & RCSR_OE)
 617                flag = TTY_OVERRUN;
 618
 619        else
 620                flag = TTY_NORMAL;
 621
 622        if (tty_insert_flip_char(tty, ch, flag))
 623                tty_flip_buffer_push(tty);
 624        func_exit();
 625}
 626
 627
 628static void sx_receive(struct specialix_board *bp)
 629{
 630        struct specialix_port *port;
 631        struct tty_struct *tty;
 632        unsigned char count;
 633
 634        func_enter();
 635
 636        port = sx_get_port(bp, "Receive");
 637        if (port == NULL) {
 638                dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n");
 639                func_exit();
 640                return;
 641        }
 642        tty = port->port.tty;
 643
 644        count = sx_in(bp, CD186x_RDCR);
 645        dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
 646        port->hits[count > 8 ? 9 : count]++;
 647
 648        tty_buffer_request_room(tty, count);
 649
 650        while (count--)
 651                tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL);
 652        tty_flip_buffer_push(tty);
 653        func_exit();
 654}
 655
 656
 657static void sx_transmit(struct specialix_board *bp)
 658{
 659        struct specialix_port *port;
 660        struct tty_struct *tty;
 661        unsigned char count;
 662
 663        func_enter();
 664        port = sx_get_port(bp, "Transmit");
 665        if (port == NULL) {
 666                func_exit();
 667                return;
 668        }
 669        dprintk(SX_DEBUG_TX, "port: %p\n", port);
 670        tty = port->port.tty;
 671
 672        if (port->IER & IER_TXEMPTY) {
 673                /* FIFO drained */
 674                sx_out(bp, CD186x_CAR, port_No(port));
 675                port->IER &= ~IER_TXEMPTY;
 676                sx_out(bp, CD186x_IER, port->IER);
 677                func_exit();
 678                return;
 679        }
 680
 681        if ((port->xmit_cnt <= 0 && !port->break_length)
 682            || tty->stopped || tty->hw_stopped) {
 683                sx_out(bp, CD186x_CAR, port_No(port));
 684                port->IER &= ~IER_TXRDY;
 685                sx_out(bp, CD186x_IER, port->IER);
 686                func_exit();
 687                return;
 688        }
 689
 690        if (port->break_length) {
 691                if (port->break_length > 0) {
 692                        if (port->COR2 & COR2_ETC) {
 693                                sx_out(bp, CD186x_TDR, CD186x_C_ESC);
 694                                sx_out(bp, CD186x_TDR, CD186x_C_SBRK);
 695                                port->COR2 &= ~COR2_ETC;
 696                        }
 697                        count = min_t(int, port->break_length, 0xff);
 698                        sx_out(bp, CD186x_TDR, CD186x_C_ESC);
 699                        sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
 700                        sx_out(bp, CD186x_TDR, count);
 701                        port->break_length -= count;
 702                        if (port->break_length == 0)
 703                                port->break_length--;
 704                } else {
 705                        sx_out(bp, CD186x_TDR, CD186x_C_ESC);
 706                        sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
 707                        sx_out(bp, CD186x_COR2, port->COR2);
 708                        sx_wait_CCR(bp);
 709                        sx_out(bp, CD186x_CCR, CCR_CORCHG2);
 710                        port->break_length = 0;
 711                }
 712
 713                func_exit();
 714                return;
 715        }
 716
 717        count = CD186x_NFIFO;
 718        do {
 719                sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
 720                port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
 721                if (--port->xmit_cnt <= 0)
 722                        break;
 723        } while (--count > 0);
 724
 725        if (port->xmit_cnt <= 0) {
 726                sx_out(bp, CD186x_CAR, port_No(port));
 727                port->IER &= ~IER_TXRDY;
 728                sx_out(bp, CD186x_IER, port->IER);
 729        }
 730        if (port->xmit_cnt <= port->wakeup_chars)
 731                tty_wakeup(tty);
 732
 733        func_exit();
 734}
 735
 736
 737static void sx_check_modem(struct specialix_board *bp)
 738{
 739        struct specialix_port *port;
 740        struct tty_struct *tty;
 741        unsigned char mcr;
 742        int msvr_cd;
 743
 744        dprintk(SX_DEBUG_SIGNALS, "Modem intr. ");
 745        port = sx_get_port(bp, "Modem");
 746        if (port == NULL)
 747                return;
 748
 749        tty = port->port.tty;
 750
 751        mcr = sx_in(bp, CD186x_MCR);
 752
 753        if ((mcr & MCR_CDCHG)) {
 754                dprintk(SX_DEBUG_SIGNALS, "CD just changed... ");
 755                msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
 756                if (msvr_cd) {
 757                        dprintk(SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
 758                        wake_up_interruptible(&port->port.open_wait);
 759                } else {
 760                        dprintk(SX_DEBUG_SIGNALS, "Sending HUP.\n");
 761                        tty_hangup(tty);
 762                }
 763        }
 764
 765#ifdef SPECIALIX_BRAIN_DAMAGED_CTS
 766        if (mcr & MCR_CTSCHG) {
 767                if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
 768                        tty->hw_stopped = 0;
 769                        port->IER |= IER_TXRDY;
 770                        if (port->xmit_cnt <= port->wakeup_chars)
 771                                tty_wakeup(tty);
 772                } else {
 773                        tty->hw_stopped = 1;
 774                        port->IER &= ~IER_TXRDY;
 775                }
 776                sx_out(bp, CD186x_IER, port->IER);
 777        }
 778        if (mcr & MCR_DSSXHG) {
 779                if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
 780                        tty->hw_stopped = 0;
 781                        port->IER |= IER_TXRDY;
 782                        if (port->xmit_cnt <= port->wakeup_chars)
 783                                tty_wakeup(tty);
 784                } else {
 785                        tty->hw_stopped = 1;
 786                        port->IER &= ~IER_TXRDY;
 787                }
 788                sx_out(bp, CD186x_IER, port->IER);
 789        }
 790#endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
 791
 792        /* Clear change bits */
 793        sx_out(bp, CD186x_MCR, 0);
 794}
 795
 796
 797/* The main interrupt processing routine */
 798static irqreturn_t sx_interrupt(int dummy, void *dev_id)
 799{
 800        unsigned char status;
 801        unsigned char ack;
 802        struct specialix_board *bp = dev_id;
 803        unsigned long loop = 0;
 804        int saved_reg;
 805        unsigned long flags;
 806
 807        func_enter();
 808
 809        spin_lock_irqsave(&bp->lock, flags);
 810
 811        dprintk(SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__,
 812                port_No(sx_get_port(bp, "INT")),
 813                SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
 814        if (!(bp->flags & SX_BOARD_ACTIVE)) {
 815                dprintk(SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n",
 816                                                                bp->irq);
 817                spin_unlock_irqrestore(&bp->lock, flags);
 818                func_exit();
 819                return IRQ_NONE;
 820        }
 821
 822        saved_reg = bp->reg;
 823
 824        while (++loop < 16) {
 825                status = sx_in(bp, CD186x_SRSR) &
 826                                (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint);
 827                if (status == 0)
 828                        break;
 829                if (status & SRSR_RREQint) {
 830                        ack = sx_in(bp, CD186x_RRAR);
 831
 832                        if (ack == (SX_ID | GIVR_IT_RCV))
 833                                sx_receive(bp);
 834                        else if (ack == (SX_ID | GIVR_IT_REXC))
 835                                sx_receive_exc(bp);
 836                        else
 837                                printk(KERN_ERR
 838                                "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
 839                                                board_No(bp), status, ack);
 840
 841                } else if (status & SRSR_TREQint) {
 842                        ack = sx_in(bp, CD186x_TRAR);
 843
 844                        if (ack == (SX_ID | GIVR_IT_TX))
 845                                sx_transmit(bp);
 846                        else
 847                                printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
 848                                        board_No(bp), status, ack,
 849                                        port_No(sx_get_port(bp, "Int")));
 850                } else if (status & SRSR_MREQint) {
 851                        ack = sx_in(bp, CD186x_MRAR);
 852
 853                        if (ack == (SX_ID | GIVR_IT_MODEM))
 854                                sx_check_modem(bp);
 855                        else
 856                                printk(KERN_ERR
 857                                  "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
 858                                       board_No(bp), status, ack);
 859
 860                }
 861
 862                sx_out(bp, CD186x_EOIR, 0);   /* Mark end of interrupt */
 863        }
 864        bp->reg = saved_reg;
 865        outb(bp->reg, bp->base + SX_ADDR_REG);
 866        spin_unlock_irqrestore(&bp->lock, flags);
 867        func_exit();
 868        return IRQ_HANDLED;
 869}
 870
 871
 872/*
 873 *  Routines for open & close processing.
 874 */
 875
 876static void turn_ints_off(struct specialix_board *bp)
 877{
 878        unsigned long flags;
 879
 880        func_enter();
 881        spin_lock_irqsave(&bp->lock, flags);
 882        (void) sx_in_off(bp, 0); /* Turn off interrupts. */
 883        spin_unlock_irqrestore(&bp->lock, flags);
 884
 885        func_exit();
 886}
 887
 888static void turn_ints_on(struct specialix_board *bp)
 889{
 890        unsigned long flags;
 891
 892        func_enter();
 893
 894        spin_lock_irqsave(&bp->lock, flags);
 895        (void) sx_in(bp, 0); /* Turn ON interrupts. */
 896        spin_unlock_irqrestore(&bp->lock, flags);
 897
 898        func_exit();
 899}
 900
 901
 902/* Called with disabled interrupts */
 903static int sx_setup_board(struct specialix_board *bp)
 904{
 905        int error;
 906
 907        if (bp->flags & SX_BOARD_ACTIVE)
 908                return 0;
 909
 910        if (bp->flags & SX_BOARD_IS_PCI)
 911                error = request_irq(bp->irq, sx_interrupt,
 912                        IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp);
 913        else
 914                error = request_irq(bp->irq, sx_interrupt,
 915                        IRQF_DISABLED, "specialix IO8+", bp);
 916
 917        if (error)
 918                return error;
 919
 920        turn_ints_on(bp);
 921        bp->flags |= SX_BOARD_ACTIVE;
 922
 923        return 0;
 924}
 925
 926
 927/* Called with disabled interrupts */
 928static void sx_shutdown_board(struct specialix_board *bp)
 929{
 930        func_enter();
 931
 932        if (!(bp->flags & SX_BOARD_ACTIVE)) {
 933                func_exit();
 934                return;
 935        }
 936
 937        bp->flags &= ~SX_BOARD_ACTIVE;
 938
 939        dprintk(SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
 940                 bp->irq, board_No(bp));
 941        free_irq(bp->irq, bp);
 942        turn_ints_off(bp);
 943        func_exit();
 944}
 945
 946static unsigned int sx_crtscts(struct tty_struct *tty)
 947{
 948        if (sx_rtscts)
 949                return C_CRTSCTS(tty);
 950        return 1;
 951}
 952
 953/*
 954 * Setting up port characteristics.
 955 * Must be called with disabled interrupts
 956 */
 957static void sx_change_speed(struct specialix_board *bp,
 958                                                struct specialix_port *port)
 959{
 960        struct tty_struct *tty;
 961        unsigned long baud;
 962        long tmp;
 963        unsigned char cor1 = 0, cor3 = 0;
 964        unsigned char mcor1 = 0, mcor2 = 0;
 965        static unsigned long again;
 966        unsigned long flags;
 967
 968        func_enter();
 969
 970        tty = port->port.tty;
 971        if (!tty || !tty->termios) {
 972                func_exit();
 973                return;
 974        }
 975
 976        port->IER  = 0;
 977        port->COR2 = 0;
 978        /* Select port on the board */
 979        spin_lock_irqsave(&bp->lock, flags);
 980        sx_out(bp, CD186x_CAR, port_No(port));
 981
 982        /* The Specialix board doens't implement the RTS lines.
 983           They are used to set the IRQ level. Don't touch them. */
 984        if (sx_crtscts(tty))
 985                port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
 986        else
 987                port->MSVR =  (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
 988        spin_unlock_irqrestore(&bp->lock, flags);
 989        dprintk(SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
 990        baud = tty_get_baud_rate(tty);
 991
 992        if (baud == 38400) {
 993                if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
 994                        baud = 57600;
 995                if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
 996                        baud = 115200;
 997        }
 998
 999        if (!baud) {
1000                /* Drop DTR & exit */
1001                dprintk(SX_DEBUG_TERMIOS, "Dropping DTR...  Hmm....\n");
1002                if (!sx_crtscts(tty)) {
1003                        port->MSVR &= ~MSVR_DTR;
1004                        spin_lock_irqsave(&bp->lock, flags);
1005                        sx_out(bp, CD186x_MSVR, port->MSVR);
1006                        spin_unlock_irqrestore(&bp->lock, flags);
1007                } else
1008                        dprintk(SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1009                return;
1010        } else {
1011                /* Set DTR on */
1012                if (!sx_crtscts(tty))
1013                        port->MSVR |= MSVR_DTR;
1014        }
1015
1016        /*
1017         * Now we must calculate some speed depended things
1018         */
1019
1020        /* Set baud rate for port */
1021        tmp = port->custom_divisor ;
1022        if (tmp)
1023                printk(KERN_INFO
1024                        "sx%d: Using custom baud rate divisor %ld. \n"
1025                        "This is an untested option, please be careful.\n",
1026                                                        port_No(port), tmp);
1027        else
1028                tmp = (((SX_OSCFREQ + baud/2) / baud + CD186x_TPC/2) /
1029                                                                CD186x_TPC);
1030
1031        if (tmp < 0x10 && time_before(again, jiffies)) {
1032                again = jiffies + HZ * 60;
1033                /* Page 48 of version 2.0 of the CL-CD1865 databook */
1034                if (tmp >= 12) {
1035                        printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1036                                "Performance degradation is possible.\n"
1037                                "Read specialix.txt for more info.\n",
1038                                                port_No(port), tmp);
1039                } else {
1040                        printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1041                "Warning: overstressing Cirrus chip. This might not work.\n"
1042                "Read specialix.txt for more info.\n", port_No(port), tmp);
1043                }
1044        }
1045        spin_lock_irqsave(&bp->lock, flags);
1046        sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1047        sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1048        sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1049        sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1050        spin_unlock_irqrestore(&bp->lock, flags);
1051        if (port->custom_divisor)
1052                baud = (SX_OSCFREQ + port->custom_divisor/2) /
1053                                                        port->custom_divisor;
1054        baud = (baud + 5) / 10;                /* Estimated CPS */
1055
1056        /* Two timer ticks seems enough to wakeup something like SLIP driver */
1057        tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1058        port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1059                                              SERIAL_XMIT_SIZE - 1 : tmp);
1060
1061        /* Receiver timeout will be transmission time for 1.5 chars */
1062        tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1063        tmp = (tmp > 0xff) ? 0xff : tmp;
1064        spin_lock_irqsave(&bp->lock, flags);
1065        sx_out(bp, CD186x_RTPR, tmp);
1066        spin_unlock_irqrestore(&bp->lock, flags);
1067        switch (C_CSIZE(tty)) {
1068        case CS5:
1069                cor1 |= COR1_5BITS;
1070                break;
1071        case CS6:
1072                cor1 |= COR1_6BITS;
1073                break;
1074        case CS7:
1075                cor1 |= COR1_7BITS;
1076                break;
1077        case CS8:
1078                cor1 |= COR1_8BITS;
1079                break;
1080        }
1081
1082        if (C_CSTOPB(tty))
1083                cor1 |= COR1_2SB;
1084
1085        cor1 |= COR1_IGNORE;
1086        if (C_PARENB(tty)) {
1087                cor1 |= COR1_NORMPAR;
1088                if (C_PARODD(tty))
1089                        cor1 |= COR1_ODDP;
1090                if (I_INPCK(tty))
1091                        cor1 &= ~COR1_IGNORE;
1092        }
1093        /* Set marking of some errors */
1094        port->mark_mask = RCSR_OE | RCSR_TOUT;
1095        if (I_INPCK(tty))
1096                port->mark_mask |= RCSR_FE | RCSR_PE;
1097        if (I_BRKINT(tty) || I_PARMRK(tty))
1098                port->mark_mask |= RCSR_BREAK;
1099        if (I_IGNPAR(tty))
1100                port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1101        if (I_IGNBRK(tty)) {
1102                port->mark_mask &= ~RCSR_BREAK;
1103                if (I_IGNPAR(tty))
1104                        /* Real raw mode. Ignore all */
1105                        port->mark_mask &= ~RCSR_OE;
1106        }
1107        /* Enable Hardware Flow Control */
1108        if (C_CRTSCTS(tty)) {
1109#ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1110                port->IER |= IER_DSR | IER_CTS;
1111                mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1112                mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1113                spin_lock_irqsave(&bp->lock, flags);
1114                tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) &
1115                                                        (MSVR_CTS|MSVR_DSR));
1116                spin_unlock_irqrestore(&bp->lock, flags);
1117#else
1118                port->COR2 |= COR2_CTSAE;
1119#endif
1120        }
1121        /* Enable Software Flow Control. FIXME: I'm not sure about this */
1122        /* Some people reported that it works, but I still doubt it */
1123        if (I_IXON(tty)) {
1124                port->COR2 |= COR2_TXIBE;
1125                cor3 |= (COR3_FCT | COR3_SCDE);
1126                if (I_IXANY(tty))
1127                        port->COR2 |= COR2_IXM;
1128                spin_lock_irqsave(&bp->lock, flags);
1129                sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1130                sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1131                sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1132                sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1133                spin_unlock_irqrestore(&bp->lock, flags);
1134        }
1135        if (!C_CLOCAL(tty)) {
1136                /* Enable CD check */
1137                port->IER |= IER_CD;
1138                mcor1 |= MCOR1_CDZD;
1139                mcor2 |= MCOR2_CDOD;
1140        }
1141
1142        if (C_CREAD(tty))
1143                /* Enable receiver */
1144                port->IER |= IER_RXD;
1145
1146        /* Set input FIFO size (1-8 bytes) */
1147        cor3 |= sx_rxfifo;
1148        /* Setting up CD186x channel registers */
1149        spin_lock_irqsave(&bp->lock, flags);
1150        sx_out(bp, CD186x_COR1, cor1);
1151        sx_out(bp, CD186x_COR2, port->COR2);
1152        sx_out(bp, CD186x_COR3, cor3);
1153        spin_unlock_irqrestore(&bp->lock, flags);
1154        /* Make CD186x know about registers change */
1155        sx_wait_CCR(bp);
1156        spin_lock_irqsave(&bp->lock, flags);
1157        sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1158        /* Setting up modem option registers */
1159        dprintk(SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n",
1160                                                                mcor1, mcor2);
1161        sx_out(bp, CD186x_MCOR1, mcor1);
1162        sx_out(bp, CD186x_MCOR2, mcor2);
1163        spin_unlock_irqrestore(&bp->lock, flags);
1164        /* Enable CD186x transmitter & receiver */
1165        sx_wait_CCR(bp);
1166        spin_lock_irqsave(&bp->lock, flags);
1167        sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1168        /* Enable interrupts */
1169        sx_out(bp, CD186x_IER, port->IER);
1170        /* And finally set the modem lines... */
1171        sx_out(bp, CD186x_MSVR, port->MSVR);
1172        spin_unlock_irqrestore(&bp->lock, flags);
1173
1174        func_exit();
1175}
1176
1177
1178/* Must be called with interrupts enabled */
1179static int sx_setup_port(struct specialix_board *bp,
1180                                                struct specialix_port *port)
1181{
1182        unsigned long flags;
1183
1184        func_enter();
1185
1186        if (port->port.flags & ASYNC_INITIALIZED) {
1187                func_exit();
1188                return 0;
1189        }
1190
1191        if (!port->xmit_buf) {
1192                /* We may sleep in get_zeroed_page() */
1193                unsigned long tmp;
1194
1195                tmp = get_zeroed_page(GFP_KERNEL);
1196                if (tmp == 0L) {
1197                        func_exit();
1198                        return -ENOMEM;
1199                }
1200
1201                if (port->xmit_buf) {
1202                        free_page(tmp);
1203                        func_exit();
1204                        return -ERESTARTSYS;
1205                }
1206                port->xmit_buf = (unsigned char *) tmp;
1207        }
1208
1209        spin_lock_irqsave(&port->lock, flags);
1210
1211        if (port->port.tty)
1212                clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
1213
1214        port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1215        sx_change_speed(bp, port);
1216        port->port.flags |= ASYNC_INITIALIZED;
1217
1218        spin_unlock_irqrestore(&port->lock, flags);
1219
1220
1221        func_exit();
1222        return 0;
1223}
1224
1225
1226/* Must be called with interrupts disabled */
1227static void sx_shutdown_port(struct specialix_board *bp,
1228                                                struct specialix_port *port)
1229{
1230        struct tty_struct *tty;
1231        int i;
1232        unsigned long flags;
1233
1234        func_enter();
1235
1236        if (!(port->port.flags & ASYNC_INITIALIZED)) {
1237                func_exit();
1238                return;
1239        }
1240
1241        if (sx_debug & SX_DEBUG_FIFO) {
1242                dprintk(SX_DEBUG_FIFO,
1243                        "sx%d: port %d: %ld overruns, FIFO hits [ ",
1244                                board_No(bp), port_No(port), port->overrun);
1245                for (i = 0; i < 10; i++)
1246                        dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1247                dprintk(SX_DEBUG_FIFO, "].\n");
1248        }
1249
1250        if (port->xmit_buf) {
1251                free_page((unsigned long) port->xmit_buf);
1252                port->xmit_buf = NULL;
1253        }
1254
1255        /* Select port */
1256        spin_lock_irqsave(&bp->lock, flags);
1257        sx_out(bp, CD186x_CAR, port_No(port));
1258
1259        tty = port->port.tty;
1260        if (tty == NULL || C_HUPCL(tty)) {
1261                /* Drop DTR */
1262                sx_out(bp, CD186x_MSVDTR, 0);
1263        }
1264        spin_unlock_irqrestore(&bp->lock, flags);
1265        /* Reset port */
1266        sx_wait_CCR(bp);
1267        spin_lock_irqsave(&bp->lock, flags);
1268        sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1269        /* Disable all interrupts from this port */
1270        port->IER = 0;
1271        sx_out(bp, CD186x_IER, port->IER);
1272        spin_unlock_irqrestore(&bp->lock, flags);
1273        if (tty)
1274                set_bit(TTY_IO_ERROR, &tty->flags);
1275        port->port.flags &= ~ASYNC_INITIALIZED;
1276
1277        if (!bp->count)
1278                sx_shutdown_board(bp);
1279        func_exit();
1280}
1281
1282
1283static int block_til_ready(struct tty_struct *tty, struct file *filp,
1284                                                struct specialix_port *port)
1285{
1286        DECLARE_WAITQUEUE(wait,  current);
1287        struct specialix_board *bp = port_Board(port);
1288        int    retval;
1289        int    do_clocal = 0;
1290        int    CD;
1291        unsigned long flags;
1292
1293        func_enter();
1294
1295        /*
1296         * If the device is in the middle of being closed, then block
1297         * until it's done, and then try again.
1298         */
1299        if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
1300                interruptible_sleep_on(&port->port.close_wait);
1301                if (port->port.flags & ASYNC_HUP_NOTIFY) {
1302                        func_exit();
1303                        return -EAGAIN;
1304                } else {
1305                        func_exit();
1306                        return -ERESTARTSYS;
1307                }
1308        }
1309
1310        /*
1311         * If non-blocking mode is set, or the port is not enabled,
1312         * then make the check up front and then exit.
1313         */
1314        if ((filp->f_flags & O_NONBLOCK) ||
1315            (tty->flags & (1 << TTY_IO_ERROR))) {
1316                port->port.flags |= ASYNC_NORMAL_ACTIVE;
1317                func_exit();
1318                return 0;
1319        }
1320
1321        if (C_CLOCAL(tty))
1322                do_clocal = 1;
1323
1324        /*
1325         * Block waiting for the carrier detect and the line to become
1326         * free (i.e., not in use by the callout).  While we are in
1327         * this loop, info->count is dropped by one, so that
1328         * rs_close() knows when to free things.  We restore it upon
1329         * exit, either normal or abnormal.
1330         */
1331        retval = 0;
1332        add_wait_queue(&port->port.open_wait, &wait);
1333        spin_lock_irqsave(&port->lock, flags);
1334        if (!tty_hung_up_p(filp))
1335                port->port.count--;
1336        spin_unlock_irqrestore(&port->lock, flags);
1337        port->port.blocked_open++;
1338        while (1) {
1339                spin_lock_irqsave(&bp->lock, flags);
1340                sx_out(bp, CD186x_CAR, port_No(port));
1341                CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1342                if (sx_crtscts(tty)) {
1343                        /* Activate RTS */
1344                        port->MSVR |= MSVR_DTR;                /* WTF? */
1345                        sx_out(bp, CD186x_MSVR, port->MSVR);
1346                } else {
1347                        /* Activate DTR */
1348                        port->MSVR |= MSVR_DTR;
1349                        sx_out(bp, CD186x_MSVR, port->MSVR);
1350                }
1351                spin_unlock_irqrestore(&bp->lock, flags);
1352                set_current_state(TASK_INTERRUPTIBLE);
1353                if (tty_hung_up_p(filp) ||
1354                    !(port->port.flags & ASYNC_INITIALIZED)) {
1355                        if (port->port.flags & ASYNC_HUP_NOTIFY)
1356                                retval = -EAGAIN;
1357                        else
1358                                retval = -ERESTARTSYS;
1359                        break;
1360                }
1361                if (!(port->port.flags & ASYNC_CLOSING) &&
1362                    (do_clocal || CD))
1363                        break;
1364                if (signal_pending(current)) {
1365                        retval = -ERESTARTSYS;
1366                        break;
1367                }
1368                schedule();
1369        }
1370
1371        set_current_state(TASK_RUNNING);
1372        remove_wait_queue(&port->port.open_wait, &wait);
1373        spin_lock_irqsave(&port->lock, flags);
1374        if (!tty_hung_up_p(filp))
1375                port->port.count++;
1376        port->port.blocked_open--;
1377        spin_unlock_irqrestore(&port->lock, flags);
1378        if (retval) {
1379                func_exit();
1380                return retval;
1381        }
1382
1383        port->port.flags |= ASYNC_NORMAL_ACTIVE;
1384        func_exit();
1385        return 0;
1386}
1387
1388
1389static int sx_open(struct tty_struct *tty, struct file *filp)
1390{
1391        int board;
1392        int error;
1393        struct specialix_port *port;
1394        struct specialix_board *bp;
1395        int i;
1396        unsigned long flags;
1397
1398        func_enter();
1399
1400        board = SX_BOARD(tty->index);
1401
1402        if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1403                func_exit();
1404                return -ENODEV;
1405        }
1406
1407        bp = &sx_board[board];
1408        port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1409        port->overrun = 0;
1410        for (i = 0; i < 10; i++)
1411                port->hits[i] = 0;
1412
1413        dprintk(SX_DEBUG_OPEN,
1414                        "Board = %d, bp = %p, port = %p, portno = %d.\n",
1415                                 board, bp, port, SX_PORT(tty->index));
1416
1417        if (sx_paranoia_check(port, tty->name, "sx_open")) {
1418                func_enter();
1419                return -ENODEV;
1420        }
1421
1422        error = sx_setup_board(bp);
1423        if (error) {
1424                func_exit();
1425                return error;
1426        }
1427
1428        spin_lock_irqsave(&bp->lock, flags);
1429        port->port.count++;
1430        bp->count++;
1431        tty->driver_data = port;
1432        port->port.tty = tty;
1433        spin_unlock_irqrestore(&bp->lock, flags);
1434
1435        error = sx_setup_port(bp, port);
1436        if (error) {
1437                func_enter();
1438                return error;
1439        }
1440
1441        error = block_til_ready(tty, filp, port);
1442        if (error) {
1443                func_enter();
1444                return error;
1445        }
1446
1447        func_exit();
1448        return 0;
1449}
1450
1451static void sx_flush_buffer(struct tty_struct *tty)
1452{
1453        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1454        unsigned long flags;
1455        struct specialix_board  *bp;
1456
1457        func_enter();
1458
1459        if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
1460                func_exit();
1461                return;
1462        }
1463
1464        bp = port_Board(port);
1465        spin_lock_irqsave(&port->lock, flags);
1466        port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1467        spin_unlock_irqrestore(&port->lock, flags);
1468        tty_wakeup(tty);
1469
1470        func_exit();
1471}
1472
1473static void sx_close(struct tty_struct *tty, struct file *filp)
1474{
1475        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1476        struct specialix_board *bp;
1477        unsigned long flags;
1478        unsigned long timeout;
1479
1480        func_enter();
1481        if (!port || sx_paranoia_check(port, tty->name, "close")) {
1482                func_exit();
1483                return;
1484        }
1485        spin_lock_irqsave(&port->lock, flags);
1486
1487        if (tty_hung_up_p(filp)) {
1488                spin_unlock_irqrestore(&port->lock, flags);
1489                func_exit();
1490                return;
1491        }
1492
1493        bp = port_Board(port);
1494        if (tty->count == 1 && port->port.count != 1) {
1495                printk(KERN_ERR "sx%d: sx_close: bad port count;"
1496                       " tty->count is 1, port count is %d\n",
1497                       board_No(bp), port->port.count);
1498                port->port.count = 1;
1499        }
1500
1501        if (port->port.count > 1) {
1502                port->port.count--;
1503                bp->count--;
1504
1505                spin_unlock_irqrestore(&port->lock, flags);
1506
1507                func_exit();
1508                return;
1509        }
1510        port->port.flags |= ASYNC_CLOSING;
1511        /*
1512         * Now we wait for the transmit buffer to clear; and we notify
1513         * the line discipline to only process XON/XOFF characters.
1514         */
1515        tty->closing = 1;
1516        spin_unlock_irqrestore(&port->lock, flags);
1517        dprintk(SX_DEBUG_OPEN, "Closing\n");
1518        if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1519                tty_wait_until_sent(tty, port->port.closing_wait);
1520        /*
1521         * At this point we stop accepting input.  To do this, we
1522         * disable the receive line status interrupts, and tell the
1523         * interrupt driver to stop checking the data ready bit in the
1524         * line status register.
1525         */
1526        dprintk(SX_DEBUG_OPEN, "Closed\n");
1527        port->IER &= ~IER_RXD;
1528        if (port->port.flags & ASYNC_INITIALIZED) {
1529                port->IER &= ~IER_TXRDY;
1530                port->IER |= IER_TXEMPTY;
1531                spin_lock_irqsave(&bp->lock, flags);
1532                sx_out(bp, CD186x_CAR, port_No(port));
1533                sx_out(bp, CD186x_IER, port->IER);
1534                spin_unlock_irqrestore(&bp->lock, flags);
1535                /*
1536                 * Before we drop DTR, make sure the UART transmitter
1537                 * has completely drained; this is especially
1538                 * important if there is a transmit FIFO!
1539                 */
1540                timeout = jiffies+HZ;
1541                while (port->IER & IER_TXEMPTY) {
1542                        set_current_state(TASK_INTERRUPTIBLE);
1543                        msleep_interruptible(jiffies_to_msecs(port->timeout));
1544                        if (time_after(jiffies, timeout)) {
1545                                printk(KERN_INFO "Timeout waiting for close\n");
1546                                break;
1547                        }
1548                }
1549
1550        }
1551
1552        if (--bp->count < 0) {
1553                printk(KERN_ERR
1554                    "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1555                                board_No(bp), bp->count, tty->index);
1556                bp->count = 0;
1557        }
1558        if (--port->port.count < 0) {
1559                printk(KERN_ERR
1560                        "sx%d: sx_close: bad port count for tty%d: %d\n",
1561                                board_No(bp), port_No(port), port->port.count);
1562                port->port.count = 0;
1563        }
1564
1565        sx_shutdown_port(bp, port);
1566        sx_flush_buffer(tty);
1567        tty_ldisc_flush(tty);
1568        spin_lock_irqsave(&port->lock, flags);
1569        tty->closing = 0;
1570        port->port.tty = NULL;
1571        spin_unlock_irqrestore(&port->lock, flags);
1572        if (port->port.blocked_open) {
1573                if (port->port.close_delay)
1574                        msleep_interruptible(
1575                                jiffies_to_msecs(port->port.close_delay));
1576                wake_up_interruptible(&port->port.open_wait);
1577        }
1578        port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1579        wake_up_interruptible(&port->port.close_wait);
1580
1581        func_exit();
1582}
1583
1584
1585static int sx_write(struct tty_struct *tty,
1586                                        const unsigned char *buf, int count)
1587{
1588        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1589        struct specialix_board *bp;
1590        int c, total = 0;
1591        unsigned long flags;
1592
1593        func_enter();
1594        if (sx_paranoia_check(port, tty->name, "sx_write")) {
1595                func_exit();
1596                return 0;
1597        }
1598
1599        bp = port_Board(port);
1600
1601        if (!port->xmit_buf) {
1602                func_exit();
1603                return 0;
1604        }
1605
1606        while (1) {
1607                spin_lock_irqsave(&port->lock, flags);
1608                c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1609                                   SERIAL_XMIT_SIZE - port->xmit_head));
1610                if (c <= 0) {
1611                        spin_unlock_irqrestore(&port->lock, flags);
1612                        break;
1613                }
1614                memcpy(port->xmit_buf + port->xmit_head, buf, c);
1615                port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1616                port->xmit_cnt += c;
1617                spin_unlock_irqrestore(&port->lock, flags);
1618
1619                buf += c;
1620                count -= c;
1621                total += c;
1622        }
1623
1624        spin_lock_irqsave(&bp->lock, flags);
1625        if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1626            !(port->IER & IER_TXRDY)) {
1627                port->IER |= IER_TXRDY;
1628                sx_out(bp, CD186x_CAR, port_No(port));
1629                sx_out(bp, CD186x_IER, port->IER);
1630        }
1631        spin_unlock_irqrestore(&bp->lock, flags);
1632        func_exit();
1633
1634        return total;
1635}
1636
1637
1638static int sx_put_char(struct tty_struct *tty, unsigned char ch)
1639{
1640        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1641        unsigned long flags;
1642        struct specialix_board  *bp;
1643
1644        func_enter();
1645
1646        if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1647                func_exit();
1648                return 0;
1649        }
1650        dprintk(SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1651        if (!port->xmit_buf) {
1652                func_exit();
1653                return 0;
1654        }
1655        bp = port_Board(port);
1656        spin_lock_irqsave(&port->lock, flags);
1657
1658        dprintk(SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n",
1659                                        port->xmit_cnt, port->xmit_buf);
1660        if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1 || !port->xmit_buf) {
1661                spin_unlock_irqrestore(&port->lock, flags);
1662                dprintk(SX_DEBUG_TX, "Exit size\n");
1663                func_exit();
1664                return 0;
1665        }
1666        dprintk(SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
1667        port->xmit_buf[port->xmit_head++] = ch;
1668        port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1669        port->xmit_cnt++;
1670        spin_unlock_irqrestore(&port->lock, flags);
1671
1672        func_exit();
1673        return 1;
1674}
1675
1676
1677static void sx_flush_chars(struct tty_struct *tty)
1678{
1679        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1680        unsigned long flags;
1681        struct specialix_board  *bp = port_Board(port);
1682
1683        func_enter();
1684
1685        if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1686                func_exit();
1687                return;
1688        }
1689        if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1690            !port->xmit_buf) {
1691                func_exit();
1692                return;
1693        }
1694        spin_lock_irqsave(&bp->lock, flags);
1695        port->IER |= IER_TXRDY;
1696        sx_out(port_Board(port), CD186x_CAR, port_No(port));
1697        sx_out(port_Board(port), CD186x_IER, port->IER);
1698        spin_unlock_irqrestore(&bp->lock, flags);
1699
1700        func_exit();
1701}
1702
1703
1704static int sx_write_room(struct tty_struct *tty)
1705{
1706        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1707        int        ret;
1708
1709        func_enter();
1710
1711        if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1712                func_exit();
1713                return 0;
1714        }
1715
1716        ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1717        if (ret < 0)
1718                ret = 0;
1719
1720        func_exit();
1721        return ret;
1722}
1723
1724
1725static int sx_chars_in_buffer(struct tty_struct *tty)
1726{
1727        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1728
1729        func_enter();
1730
1731        if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
1732                func_exit();
1733                return 0;
1734        }
1735        func_exit();
1736        return port->xmit_cnt;
1737}
1738
1739static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1740{
1741        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1742        struct specialix_board *bp;
1743        unsigned char status;
1744        unsigned int result;
1745        unsigned long flags;
1746
1747        func_enter();
1748
1749        if (sx_paranoia_check(port, tty->name, __func__)) {
1750                func_exit();
1751                return -ENODEV;
1752        }
1753
1754        bp = port_Board(port);
1755        spin_lock_irqsave(&bp->lock, flags);
1756        sx_out(bp, CD186x_CAR, port_No(port));
1757        status = sx_in(bp, CD186x_MSVR);
1758        spin_unlock_irqrestore(&bp->lock, flags);
1759        dprintk(SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1760                        port_No(port), status, sx_in(bp, CD186x_CAR));
1761        dprintk(SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1762        if (sx_crtscts(port->port.tty)) {
1763                result  = TIOCM_DTR | TIOCM_DSR
1764                          |   ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1765                          |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
1766                          |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1767        } else {
1768                result  = TIOCM_RTS | TIOCM_DSR
1769                          |   ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1770                          |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
1771                          |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1772        }
1773
1774        func_exit();
1775
1776        return result;
1777}
1778
1779
1780static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1781                       unsigned int set, unsigned int clear)
1782{
1783        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1784        unsigned long flags;
1785        struct specialix_board *bp;
1786
1787        func_enter();
1788
1789        if (sx_paranoia_check(port, tty->name, __func__)) {
1790                func_exit();
1791                return -ENODEV;
1792        }
1793
1794        bp = port_Board(port);
1795
1796        spin_lock_irqsave(&port->lock, flags);
1797        if (sx_crtscts(port->port.tty)) {
1798                if (set & TIOCM_RTS)
1799                        port->MSVR |= MSVR_DTR;
1800        } else {
1801                if (set & TIOCM_DTR)
1802                        port->MSVR |= MSVR_DTR;
1803        }
1804        if (sx_crtscts(port->port.tty)) {
1805                if (clear & TIOCM_RTS)
1806                        port->MSVR &= ~MSVR_DTR;
1807        } else {
1808                if (clear & TIOCM_DTR)
1809                        port->MSVR &= ~MSVR_DTR;
1810        }
1811        spin_lock_irqsave(&bp->lock, flags);
1812        sx_out(bp, CD186x_CAR, port_No(port));
1813        sx_out(bp, CD186x_MSVR, port->MSVR);
1814        spin_unlock_irqrestore(&bp->lock, flags);
1815        spin_unlock_irqrestore(&port->lock, flags);
1816        func_exit();
1817        return 0;
1818}
1819
1820
1821static int sx_send_break(struct tty_struct *tty, int length)
1822{
1823        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1824        struct specialix_board *bp = port_Board(port);
1825        unsigned long flags;
1826
1827        func_enter();
1828        if (length == 0 || length == -1)
1829                return -EOPNOTSUPP;
1830
1831        spin_lock_irqsave(&port->lock, flags);
1832        port->break_length = SPECIALIX_TPS / HZ * length;
1833        port->COR2 |= COR2_ETC;
1834        port->IER  |= IER_TXRDY;
1835        spin_lock_irqsave(&bp->lock, flags);
1836        sx_out(bp, CD186x_CAR, port_No(port));
1837        sx_out(bp, CD186x_COR2, port->COR2);
1838        sx_out(bp, CD186x_IER, port->IER);
1839        spin_unlock_irqrestore(&bp->lock, flags);
1840        spin_unlock_irqrestore(&port->lock, flags);
1841        sx_wait_CCR(bp);
1842        spin_lock_irqsave(&bp->lock, flags);
1843        sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1844        spin_unlock_irqrestore(&bp->lock, flags);
1845        sx_wait_CCR(bp);
1846
1847        func_exit();
1848        return 0;
1849}
1850
1851
1852static int sx_set_serial_info(struct specialix_port *port,
1853                                        struct serial_struct __user *newinfo)
1854{
1855        struct serial_struct tmp;
1856        struct specialix_board *bp = port_Board(port);
1857        int change_speed;
1858
1859        func_enter();
1860
1861        if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
1862                func_enter();
1863                return -EFAULT;
1864        }
1865
1866        lock_kernel();
1867
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                        unlock_kernel();
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        unlock_kernel();
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        lock_kernel();
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        unlock_kernel();
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 = (struct specialix_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 = (struct specialix_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 = (struct specialix_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_irqsave(&bp->lock, flags);
2026        sx_out(bp, CD186x_CAR, port_No(port));
2027        spin_unlock_irqrestore(&bp->lock, flags);
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_irqsave(&bp->lock, flags);
2038        sx_out(bp, CD186x_MSVR, port->MSVR);
2039        spin_unlock_irqrestore(&bp->lock, flags);
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 = (struct specialix_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_irqsave(&bp->lock, flags);
2064        sx_out(bp, CD186x_CAR, port_No(port));
2065        sx_out(bp, CD186x_IER, port->IER);
2066        spin_unlock_irqrestore(&bp->lock, flags);
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 = (struct specialix_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_irqsave(&bp->lock, flags);
2092                sx_out(bp, CD186x_CAR, port_No(port));
2093                sx_out(bp, CD186x_IER, port->IER);
2094                spin_unlock_irqrestore(&bp->lock, flags);
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 = (struct specialix_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 = (struct specialix_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 = {
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");