Showing error 831

User: Jiri Slaby
Error type: Resource Leak
Error type description: The code omits to put the resource to the system for reuse
File location: drivers/char/isicom.c
Line in file: 981
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Entered: 2011-11-07 22:40:13 UTC


Source:

   1/*
   2 *        This program is free software; you can redistribute it and/or
   3 *        modify it under the terms of the GNU General Public License
   4 *        as published by the Free Software Foundation; either version
   5 *        2 of the License, or (at your option) any later version.
   6 *
   7 *        Original driver code supplied by Multi-Tech
   8 *
   9 *        Changes
  10 *        1/9/98        alan@lxorguk.ukuu.org.uk
  11 *                                        Merge to 2.0.x kernel tree
  12 *                                        Obtain and use official major/minors
  13 *                                        Loader switched to a misc device
  14 *                                        (fixed range check bug as a side effect)
  15 *                                        Printk clean up
  16 *        9/12/98        alan@lxorguk.ukuu.org.uk
  17 *                                        Rough port to 2.1.x
  18 *
  19 *        10/6/99 sameer                        Merged the ISA and PCI drivers to
  20 *                                        a new unified driver.
  21 *
  22 *        3/9/99        sameer                        Added support for ISI4616 cards.
  23 *
  24 *        16/9/99        sameer                        We do not force RTS low anymore.
  25 *                                        This is to prevent the firmware
  26 *                                        from getting confused.
  27 *
  28 *        26/10/99 sameer                        Cosmetic changes:The driver now
  29 *                                        dumps the Port Count information
  30 *                                        along with I/O address and IRQ.
  31 *
  32 *        13/12/99 sameer                        Fixed the problem with IRQ sharing.
  33 *
  34 *        10/5/00  sameer                        Fixed isicom_shutdown_board()
  35 *                                        to not lower DTR on all the ports
  36 *                                        when the last port on the card is
  37 *                                        closed.
  38 *
  39 *        10/5/00  sameer                        Signal mask setup command added
  40 *                                        to  isicom_setup_port and
  41 *                                        isicom_shutdown_port.
  42 *
  43 *        24/5/00  sameer                        The driver is now SMP aware.
  44 *
  45 *
  46 *        27/11/00 Vinayak P Risbud        Fixed the Driver Crash Problem
  47 *
  48 *
  49 *        03/01/01  anil .s                Added support for resetting the
  50 *                                        internal modems on ISI cards.
  51 *
  52 *        08/02/01  anil .s                Upgraded the driver for kernel
  53 *                                        2.4.x
  54 *
  55 *        11/04/01  Kevin                        Fixed firmware load problem with
  56 *                                        ISIHP-4X card
  57 *
  58 *        30/04/01  anil .s                Fixed the remote login through
  59 *                                        ISI port problem. Now the link
  60 *                                        does not go down before password
  61 *                                        prompt.
  62 *
  63 *        03/05/01  anil .s                Fixed the problem with IRQ sharing
  64 *                                        among ISI-PCI cards.
  65 *
  66 *        03/05/01  anil .s                Added support to display the version
  67 *                                        info during insmod as well as module
  68 *                                        listing by lsmod.
  69 *
  70 *        10/05/01  anil .s                Done the modifications to the source
  71 *                                        file and Install script so that the
  72 *                                        same installation can be used for
  73 *                                        2.2.x and 2.4.x kernel.
  74 *
  75 *        06/06/01  anil .s                Now we drop both dtr and rts during
  76 *                                        shutdown_port as well as raise them
  77 *                                        during isicom_config_port.
  78 *
  79 *        09/06/01 acme@conectiva.com.br        use capable, not suser, do
  80 *                                        restore_flags on failure in
  81 *                                        isicom_send_break, verify put_user
  82 *                                        result
  83 *
  84 *        11/02/03  ranjeeth                Added support for 230 Kbps and 460 Kbps
  85 *                                        Baud index extended to 21
  86 *
  87 *        20/03/03  ranjeeth                Made to work for Linux Advanced server.
  88 *                                        Taken care of license warning.
  89 *
  90 *        10/12/03  Ravindra                Made to work for Fedora Core 1 of
  91 *                                        Red Hat Distribution
  92 *
  93 *        06/01/05  Alan Cox                 Merged the ISI and base kernel strands
  94 *                                        into a single 2.6 driver
  95 *
  96 *        ***********************************************************
  97 *
  98 *        To use this driver you also need the support package. You
  99 *        can find this in RPM format on
 100 *                ftp://ftp.linux.org.uk/pub/linux/alan
 101 *
 102 *        You can find the original tools for this direct from Multitech
 103 *                ftp://ftp.multitech.com/ISI-Cards/
 104 *
 105 *        Having installed the cards the module options (/etc/modprobe.conf)
 106 *
 107 *        options isicom   io=card1,card2,card3,card4 irq=card1,card2,card3,card4
 108 *
 109 *        Omit those entries for boards you don't have installed.
 110 *
 111 *        TODO
 112 *                Merge testing
 113 *                64-bit verification
 114 */
 115
 116#include <linux/module.h>
 117#include <linux/firmware.h>
 118#include <linux/kernel.h>
 119#include <linux/tty.h>
 120#include <linux/tty_flip.h>
 121#include <linux/termios.h>
 122#include <linux/fs.h>
 123#include <linux/sched.h>
 124#include <linux/serial.h>
 125#include <linux/mm.h>
 126#include <linux/interrupt.h>
 127#include <linux/timer.h>
 128#include <linux/delay.h>
 129#include <linux/ioport.h>
 130
 131#include <linux/uaccess.h>
 132#include <linux/io.h>
 133#include <asm/system.h>
 134
 135#include <linux/pci.h>
 136
 137#include <linux/isicom.h>
 138
 139#define InterruptTheCard(base) outw(0, (base) + 0xc)
 140#define ClearInterrupt(base) inw((base) + 0x0a)
 141
 142#define pr_dbg(str...) pr_debug("ISICOM: " str)
 143#ifdef DEBUG
 144#define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c))
 145#else
 146#define isicom_paranoia_check(a, b, c) 0
 147#endif
 148
 149static int isicom_probe(struct pci_dev *, const struct pci_device_id *);
 150static void __devexit isicom_remove(struct pci_dev *);
 151
 152static struct pci_device_id isicom_pci_tbl[] = {
 153        { PCI_DEVICE(VENDOR_ID, 0x2028) },
 154        { PCI_DEVICE(VENDOR_ID, 0x2051) },
 155        { PCI_DEVICE(VENDOR_ID, 0x2052) },
 156        { PCI_DEVICE(VENDOR_ID, 0x2053) },
 157        { PCI_DEVICE(VENDOR_ID, 0x2054) },
 158        { PCI_DEVICE(VENDOR_ID, 0x2055) },
 159        { PCI_DEVICE(VENDOR_ID, 0x2056) },
 160        { PCI_DEVICE(VENDOR_ID, 0x2057) },
 161        { PCI_DEVICE(VENDOR_ID, 0x2058) },
 162        { 0 }
 163};
 164MODULE_DEVICE_TABLE(pci, isicom_pci_tbl);
 165
 166static struct pci_driver isicom_driver = {
 167        .name                = "isicom",
 168        .id_table        = isicom_pci_tbl,
 169        .probe                = isicom_probe,
 170        .remove                = __devexit_p(isicom_remove)
 171};
 172
 173static int prev_card = 3;        /*        start servicing isi_card[0]        */
 174static struct tty_driver *isicom_normal;
 175
 176static void isicom_tx(unsigned long _data);
 177static void isicom_start(struct tty_struct *tty);
 178
 179static DEFINE_TIMER(tx, isicom_tx, 0, 0);
 180
 181/*   baud index mappings from linux defns to isi */
 182
 183static signed char linuxb_to_isib[] = {
 184        -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21
 185};
 186
 187struct        isi_board {
 188        unsigned long                base;
 189        int                        irq;
 190        unsigned char                port_count;
 191        unsigned short                status;
 192        unsigned short                port_status; /* each bit for each port */
 193        unsigned short                shift_count;
 194        struct isi_port                *ports;
 195        signed char                count;
 196        spinlock_t                card_lock; /* Card wide lock 11/5/00 -sameer */
 197        unsigned long                flags;
 198        unsigned int                index;
 199};
 200
 201struct        isi_port {
 202        unsigned short                magic;
 203        struct tty_port                port;
 204        u16                        channel;
 205        u16                        status;
 206        struct isi_board        *card;
 207        unsigned char                *xmit_buf;
 208        int                        xmit_head;
 209        int                        xmit_tail;
 210        int                        xmit_cnt;
 211};
 212
 213static struct isi_board isi_card[BOARD_COUNT];
 214static struct isi_port  isi_ports[PORT_COUNT];
 215
 216/*
 217 *        Locking functions for card level locking. We need to own both
 218 *        the kernel lock for the card and have the card in a position that
 219 *        it wants to talk.
 220 */
 221
 222static inline int WaitTillCardIsFree(unsigned long base)
 223{
 224        unsigned int count = 0;
 225        unsigned int a = in_atomic(); /* do we run under spinlock? */
 226
 227        while (!(inw(base + 0xe) & 0x1) && count++ < 100)
 228                if (a)
 229                        mdelay(1);
 230                else
 231                        msleep(1);
 232
 233        return !(inw(base + 0xe) & 0x1);
 234}
 235
 236static int lock_card(struct isi_board *card)
 237{
 238        unsigned long base = card->base;
 239        unsigned int retries, a;
 240
 241        for (retries = 0; retries < 10; retries++) {
 242                spin_lock_irqsave(&card->card_lock, card->flags);
 243                for (a = 0; a < 10; a++) {
 244                        if (inw(base + 0xe) & 0x1)
 245                                return 1;
 246                        udelay(10);
 247                }
 248                spin_unlock_irqrestore(&card->card_lock, card->flags);
 249                msleep(10);
 250        }
 251        printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%lx)\n",
 252                card->base);
 253
 254        return 0;        /* Failed to acquire the card! */
 255}
 256
 257static void unlock_card(struct isi_board *card)
 258{
 259        spin_unlock_irqrestore(&card->card_lock, card->flags);
 260}
 261
 262/*
 263 *  ISI Card specific ops ...
 264 */
 265
 266/* card->lock HAS to be held */
 267static void raise_dtr(struct isi_port *port)
 268{
 269        struct isi_board *card = port->card;
 270        unsigned long base = card->base;
 271        u16 channel = port->channel;
 272
 273        if (WaitTillCardIsFree(base))
 274                return;
 275
 276        outw(0x8000 | (channel << card->shift_count) | 0x02, base);
 277        outw(0x0504, base);
 278        InterruptTheCard(base);
 279        port->status |= ISI_DTR;
 280}
 281
 282/* card->lock HAS to be held */
 283static inline void drop_dtr(struct isi_port *port)
 284{
 285        struct isi_board *card = port->card;
 286        unsigned long base = card->base;
 287        u16 channel = port->channel;
 288
 289        if (WaitTillCardIsFree(base))
 290                return;
 291
 292        outw(0x8000 | (channel << card->shift_count) | 0x02, base);
 293        outw(0x0404, base);
 294        InterruptTheCard(base);
 295        port->status &= ~ISI_DTR;
 296}
 297
 298/* card->lock HAS to be held */
 299static inline void raise_rts(struct isi_port *port)
 300{
 301        struct isi_board *card = port->card;
 302        unsigned long base = card->base;
 303        u16 channel = port->channel;
 304
 305        if (WaitTillCardIsFree(base))
 306                return;
 307
 308        outw(0x8000 | (channel << card->shift_count) | 0x02, base);
 309        outw(0x0a04, base);
 310        InterruptTheCard(base);
 311        port->status |= ISI_RTS;
 312}
 313
 314/* card->lock HAS to be held */
 315static inline void drop_rts(struct isi_port *port)
 316{
 317        struct isi_board *card = port->card;
 318        unsigned long base = card->base;
 319        u16 channel = port->channel;
 320
 321        if (WaitTillCardIsFree(base))
 322                return;
 323
 324        outw(0x8000 | (channel << card->shift_count) | 0x02, base);
 325        outw(0x0804, base);
 326        InterruptTheCard(base);
 327        port->status &= ~ISI_RTS;
 328}
 329
 330/* card->lock MUST NOT be held */
 331static inline void raise_dtr_rts(struct isi_port *port)
 332{
 333        struct isi_board *card = port->card;
 334        unsigned long base = card->base;
 335        u16 channel = port->channel;
 336
 337        if (!lock_card(card))
 338                return;
 339
 340        outw(0x8000 | (channel << card->shift_count) | 0x02, base);
 341        outw(0x0f04, base);
 342        InterruptTheCard(base);
 343        port->status |= (ISI_DTR | ISI_RTS);
 344        unlock_card(card);
 345}
 346
 347/* card->lock HAS to be held */
 348static void drop_dtr_rts(struct isi_port *port)
 349{
 350        struct isi_board *card = port->card;
 351        unsigned long base = card->base;
 352        u16 channel = port->channel;
 353
 354        if (WaitTillCardIsFree(base))
 355                return;
 356
 357        outw(0x8000 | (channel << card->shift_count) | 0x02, base);
 358        outw(0x0c04, base);
 359        InterruptTheCard(base);
 360        port->status &= ~(ISI_RTS | ISI_DTR);
 361}
 362
 363/*
 364 *        ISICOM Driver specific routines ...
 365 *
 366 */
 367
 368static inline int __isicom_paranoia_check(struct isi_port const *port,
 369        char *name, const char *routine)
 370{
 371        if (!port) {
 372                printk(KERN_WARNING "ISICOM: Warning: bad isicom magic for "
 373                        "dev %s in %s.\n", name, routine);
 374                return 1;
 375        }
 376        if (port->magic != ISICOM_MAGIC) {
 377                printk(KERN_WARNING "ISICOM: Warning: NULL isicom port for "
 378                        "dev %s in %s.\n", name, routine);
 379                return 1;
 380        }
 381
 382        return 0;
 383}
 384
 385/*
 386 *        Transmitter.
 387 *
 388 *        We shovel data into the card buffers on a regular basis. The card
 389 *        will do the rest of the work for us.
 390 */
 391
 392static void isicom_tx(unsigned long _data)
 393{
 394        unsigned long flags, base;
 395        unsigned int retries;
 396        short count = (BOARD_COUNT-1), card;
 397        short txcount, wrd, residue, word_count, cnt;
 398        struct isi_port *port;
 399        struct tty_struct *tty;
 400
 401        /*        find next active board        */
 402        card = (prev_card + 1) & 0x0003;
 403        while (count-- > 0) {
 404                if (isi_card[card].status & BOARD_ACTIVE)
 405                        break;
 406                card = (card + 1) & 0x0003;
 407        }
 408        if (!(isi_card[card].status & BOARD_ACTIVE))
 409                goto sched_again;
 410
 411        prev_card = card;
 412
 413        count = isi_card[card].port_count;
 414        port = isi_card[card].ports;
 415        base = isi_card[card].base;
 416
 417        spin_lock_irqsave(&isi_card[card].card_lock, flags);
 418        for (retries = 0; retries < 100; retries++) {
 419                if (inw(base + 0xe) & 0x1)
 420                        break;
 421                udelay(2);
 422        }
 423        if (retries >= 100)
 424                goto unlock;
 425
 426        tty = tty_port_tty_get(&port->port);
 427        if (tty == NULL)
 428                goto put_unlock;
 429
 430        for (; count > 0; count--, port++) {
 431                /* port not active or tx disabled to force flow control */
 432                if (!(port->port.flags & ASYNC_INITIALIZED) ||
 433                                !(port->status & ISI_TXOK))
 434                        continue;
 435
 436                txcount = min_t(short, TX_SIZE, port->xmit_cnt);
 437                if (txcount <= 0 || tty->stopped || tty->hw_stopped)
 438                        continue;
 439
 440                if (!(inw(base + 0x02) & (1 << port->channel)))
 441                        continue;
 442
 443                pr_dbg("txing %d bytes, port%d.\n", txcount,
 444                        port->channel + 1);
 445                outw((port->channel << isi_card[card].shift_count) | txcount,
 446                        base);
 447                residue = NO;
 448                wrd = 0;
 449                while (1) {
 450                        cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE
 451                                        - port->xmit_tail));
 452                        if (residue == YES) {
 453                                residue = NO;
 454                                if (cnt > 0) {
 455                                        wrd |= (port->port.xmit_buf[port->xmit_tail]
 456                                                                        << 8);
 457                                        port->xmit_tail = (port->xmit_tail + 1)
 458                                                & (SERIAL_XMIT_SIZE - 1);
 459                                        port->xmit_cnt--;
 460                                        txcount--;
 461                                        cnt--;
 462                                        outw(wrd, base);
 463                                } else {
 464                                        outw(wrd, base);
 465                                        break;
 466                                }
 467                        }
 468                        if (cnt <= 0)
 469                                break;
 470                        word_count = cnt >> 1;
 471                        outsw(base, port->port.xmit_buf+port->xmit_tail, word_count);
 472                        port->xmit_tail = (port->xmit_tail
 473                                + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
 474                        txcount -= (word_count << 1);
 475                        port->xmit_cnt -= (word_count << 1);
 476                        if (cnt & 0x0001) {
 477                                residue = YES;
 478                                wrd = port->port.xmit_buf[port->xmit_tail];
 479                                port->xmit_tail = (port->xmit_tail + 1)
 480                                        & (SERIAL_XMIT_SIZE - 1);
 481                                port->xmit_cnt--;
 482                                txcount--;
 483                        }
 484                }
 485
 486                InterruptTheCard(base);
 487                if (port->xmit_cnt <= 0)
 488                        port->status &= ~ISI_TXOK;
 489                if (port->xmit_cnt <= WAKEUP_CHARS)
 490                        tty_wakeup(tty);
 491        }
 492
 493put_unlock:
 494        tty_kref_put(tty);
 495unlock:
 496        spin_unlock_irqrestore(&isi_card[card].card_lock, flags);
 497        /*        schedule another tx for hopefully in about 10ms        */
 498sched_again:
 499        mod_timer(&tx, jiffies + msecs_to_jiffies(10));
 500}
 501
 502/*
 503 *        Main interrupt handler routine
 504 */
 505
 506static irqreturn_t isicom_interrupt(int irq, void *dev_id)
 507{
 508        struct isi_board *card = dev_id;
 509        struct isi_port *port;
 510        struct tty_struct *tty;
 511        unsigned long base;
 512        u16 header, word_count, count, channel;
 513        short byte_count;
 514        unsigned char *rp;
 515
 516        if (!card || !(card->status & FIRMWARE_LOADED))
 517                return IRQ_NONE;
 518
 519        base = card->base;
 520
 521        /* did the card interrupt us? */
 522        if (!(inw(base + 0x0e) & 0x02))
 523                return IRQ_NONE;
 524
 525        spin_lock(&card->card_lock);
 526
 527        /*
 528         * disable any interrupts from the PCI card and lower the
 529         * interrupt line
 530         */
 531        outw(0x8000, base+0x04);
 532        ClearInterrupt(base);
 533
 534        inw(base);                /* get the dummy word out */
 535        header = inw(base);
 536        channel = (header & 0x7800) >> card->shift_count;
 537        byte_count = header & 0xff;
 538
 539        if (channel + 1 > card->port_count) {
 540                printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): "
 541                        "%d(channel) > port_count.\n", base, channel+1);
 542                outw(0x0000, base+0x04); /* enable interrupts */
 543                spin_unlock(&card->card_lock);
 544                return IRQ_HANDLED;
 545        }
 546        port = card->ports + channel;
 547        if (!(port->port.flags & ASYNC_INITIALIZED)) {
 548                outw(0x0000, base+0x04); /* enable interrupts */
 549                spin_unlock(&card->card_lock);
 550                return IRQ_HANDLED;
 551        }
 552
 553        tty = tty_port_tty_get(&port->port);
 554        if (tty == NULL) {
 555                word_count = byte_count >> 1;
 556                while (byte_count > 1) {
 557                        inw(base);
 558                        byte_count -= 2;
 559                }
 560                if (byte_count & 0x01)
 561                        inw(base);
 562                outw(0x0000, base+0x04); /* enable interrupts */
 563                spin_unlock(&card->card_lock);
 564                return IRQ_HANDLED;
 565        }
 566
 567        if (header & 0x8000) {                /* Status Packet */
 568                header = inw(base);
 569                switch (header & 0xff) {
 570                case 0:        /* Change in EIA signals */
 571                        if (port->port.flags & ASYNC_CHECK_CD) {
 572                                if (port->status & ISI_DCD) {
 573                                        if (!(header & ISI_DCD)) {
 574                                        /* Carrier has been lost  */
 575                                                pr_dbg("interrupt: DCD->low.\n"
 576                                                        );
 577                                                port->status &= ~ISI_DCD;
 578                                                tty_hangup(tty);
 579                                        }
 580                                } else if (header & ISI_DCD) {
 581                                /* Carrier has been detected */
 582                                        pr_dbg("interrupt: DCD->high.\n");
 583                                        port->status |= ISI_DCD;
 584                                        wake_up_interruptible(&port->port.open_wait);
 585                                }
 586                        } else {
 587                                if (header & ISI_DCD)
 588                                        port->status |= ISI_DCD;
 589                                else
 590                                        port->status &= ~ISI_DCD;
 591                        }
 592
 593                        if (port->port.flags & ASYNC_CTS_FLOW) {
 594                                if (tty->hw_stopped) {
 595                                        if (header & ISI_CTS) {
 596                                                port->port.tty->hw_stopped = 0;
 597                                                /* start tx ing */
 598                                                port->status |= (ISI_TXOK
 599                                                        | ISI_CTS);
 600                                                tty_wakeup(tty);
 601                                        }
 602                                } else if (!(header & ISI_CTS)) {
 603                                        tty->hw_stopped = 1;
 604                                        /* stop tx ing */
 605                                        port->status &= ~(ISI_TXOK | ISI_CTS);
 606                                }
 607                        } else {
 608                                if (header & ISI_CTS)
 609                                        port->status |= ISI_CTS;
 610                                else
 611                                        port->status &= ~ISI_CTS;
 612                        }
 613
 614                        if (header & ISI_DSR)
 615                                port->status |= ISI_DSR;
 616                        else
 617                                port->status &= ~ISI_DSR;
 618
 619                        if (header & ISI_RI)
 620                                port->status |= ISI_RI;
 621                        else
 622                                port->status &= ~ISI_RI;
 623
 624                        break;
 625
 626                case 1:        /* Received Break !!! */
 627                        tty_insert_flip_char(tty, 0, TTY_BREAK);
 628                        if (port->port.flags & ASYNC_SAK)
 629                                do_SAK(tty);
 630                        tty_flip_buffer_push(tty);
 631                        break;
 632
 633                case 2:        /* Statistics                 */
 634                        pr_dbg("isicom_interrupt: stats!!!.\n");
 635                        break;
 636
 637                default:
 638                        pr_dbg("Intr: Unknown code in status packet.\n");
 639                        break;
 640                }
 641        } else {                                /* Data   Packet */
 642
 643                count = tty_prepare_flip_string(tty, &rp, byte_count & ~1);
 644                pr_dbg("Intr: Can rx %d of %d bytes.\n", count, byte_count);
 645                word_count = count >> 1;
 646                insw(base, rp, word_count);
 647                byte_count -= (word_count << 1);
 648                if (count & 0x0001) {
 649                        tty_insert_flip_char(tty,  inw(base) & 0xff,
 650                                TTY_NORMAL);
 651                        byte_count -= 2;
 652                }
 653                if (byte_count > 0) {
 654                        pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping "
 655                                "bytes...\n", base, channel + 1);
 656                /* drain out unread xtra data */
 657                while (byte_count > 0) {
 658                                inw(base);
 659                                byte_count -= 2;
 660                        }
 661                }
 662                tty_flip_buffer_push(tty);
 663        }
 664        outw(0x0000, base+0x04); /* enable interrupts */
 665        spin_unlock(&card->card_lock);
 666        tty_kref_put(tty);
 667
 668        return IRQ_HANDLED;
 669}
 670
 671static void isicom_config_port(struct tty_struct *tty)
 672{
 673        struct isi_port *port = tty->driver_data;
 674        struct isi_board *card = port->card;
 675        unsigned long baud;
 676        unsigned long base = card->base;
 677        u16 channel_setup, channel = port->channel,
 678                shift_count = card->shift_count;
 679        unsigned char flow_ctrl;
 680
 681        /* FIXME: Switch to new tty baud API */
 682        baud = C_BAUD(tty);
 683        if (baud & CBAUDEX) {
 684                baud &= ~CBAUDEX;
 685
 686                /*  if CBAUDEX bit is on and the baud is set to either 50 or 75
 687                 *  then the card is programmed for 57.6Kbps or 115Kbps
 688                 *  respectively.
 689                 */
 690
 691                /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
 692                if (baud < 1 || baud > 4)
 693                        tty->termios->c_cflag &= ~CBAUDEX;
 694                else
 695                        baud += 15;
 696        }
 697        if (baud == 15) {
 698
 699                /*  the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set
 700                 *  by the set_serial_info ioctl ... this is done by
 701                 *  the 'setserial' utility.
 702                 */
 703
 704                if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
 705                        baud++; /*  57.6 Kbps */
 706                if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
 707                        baud += 2; /*  115  Kbps */
 708                if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
 709                        baud += 3; /* 230 kbps*/
 710                if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
 711                        baud += 4; /* 460 kbps*/
 712        }
 713        if (linuxb_to_isib[baud] == -1) {
 714                /* hang up */
 715                drop_dtr(port);
 716                return;
 717        } else
 718                raise_dtr(port);
 719
 720        if (WaitTillCardIsFree(base) == 0) {
 721                outw(0x8000 | (channel << shift_count) | 0x03, base);
 722                outw(linuxb_to_isib[baud] << 8 | 0x03, base);
 723                channel_setup = 0;
 724                switch (C_CSIZE(tty)) {
 725                case CS5:
 726                        channel_setup |= ISICOM_CS5;
 727                        break;
 728                case CS6:
 729                        channel_setup |= ISICOM_CS6;
 730                        break;
 731                case CS7:
 732                        channel_setup |= ISICOM_CS7;
 733                        break;
 734                case CS8:
 735                        channel_setup |= ISICOM_CS8;
 736                        break;
 737                }
 738
 739                if (C_CSTOPB(tty))
 740                        channel_setup |= ISICOM_2SB;
 741                if (C_PARENB(tty)) {
 742                        channel_setup |= ISICOM_EVPAR;
 743                        if (C_PARODD(tty))
 744                                channel_setup |= ISICOM_ODPAR;
 745                }
 746                outw(channel_setup, base);
 747                InterruptTheCard(base);
 748        }
 749        if (C_CLOCAL(tty))
 750                port->port.flags &= ~ASYNC_CHECK_CD;
 751        else
 752                port->port.flags |= ASYNC_CHECK_CD;
 753
 754        /* flow control settings ...*/
 755        flow_ctrl = 0;
 756        port->port.flags &= ~ASYNC_CTS_FLOW;
 757        if (C_CRTSCTS(tty)) {
 758                port->port.flags |= ASYNC_CTS_FLOW;
 759                flow_ctrl |= ISICOM_CTSRTS;
 760        }
 761        if (I_IXON(tty))
 762                flow_ctrl |= ISICOM_RESPOND_XONXOFF;
 763        if (I_IXOFF(tty))
 764                flow_ctrl |= ISICOM_INITIATE_XONXOFF;
 765
 766        if (WaitTillCardIsFree(base) == 0) {
 767                outw(0x8000 | (channel << shift_count) | 0x04, base);
 768                outw(flow_ctrl << 8 | 0x05, base);
 769                outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
 770                InterruptTheCard(base);
 771        }
 772
 773        /*        rx enabled -> enable port for rx on the card        */
 774        if (C_CREAD(tty)) {
 775                card->port_status |= (1 << channel);
 776                outw(card->port_status, base + 0x02);
 777        }
 778}
 779
 780/* open et all */
 781
 782static inline void isicom_setup_board(struct isi_board *bp)
 783{
 784        int channel;
 785        struct isi_port *port;
 786        unsigned long flags;
 787
 788        spin_lock_irqsave(&bp->card_lock, flags);
 789        if (bp->status & BOARD_ACTIVE) {
 790                spin_unlock_irqrestore(&bp->card_lock, flags);
 791                return;
 792        }
 793        port = bp->ports;
 794        bp->status |= BOARD_ACTIVE;
 795        for (channel = 0; channel < bp->port_count; channel++, port++)
 796                drop_dtr_rts(port);
 797        spin_unlock_irqrestore(&bp->card_lock, flags);
 798}
 799
 800static int isicom_setup_port(struct tty_struct *tty)
 801{
 802        struct isi_port *port = tty->driver_data;
 803        struct isi_board *card = port->card;
 804        unsigned long flags;
 805
 806        if (port->port.flags & ASYNC_INITIALIZED)
 807                return 0;
 808        if (tty_port_alloc_xmit_buf(&port->port) < 0)
 809                return -ENOMEM;
 810
 811        spin_lock_irqsave(&card->card_lock, flags);
 812        clear_bit(TTY_IO_ERROR, &tty->flags);
 813        if (port->port.count == 1)
 814                card->count++;
 815
 816        port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
 817
 818        /*        discard any residual data        */
 819        if (WaitTillCardIsFree(card->base) == 0) {
 820                outw(0x8000 | (port->channel << card->shift_count) | 0x02,
 821                                card->base);
 822                outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base);
 823                InterruptTheCard(card->base);
 824        }
 825
 826        isicom_config_port(tty);
 827        port->port.flags |= ASYNC_INITIALIZED;
 828        spin_unlock_irqrestore(&card->card_lock, flags);
 829
 830        return 0;
 831}
 832
 833static int block_til_ready(struct tty_struct *tty, struct file *filp,
 834        struct isi_port *port)
 835{
 836        struct isi_board *card = port->card;
 837        int do_clocal = 0, retval;
 838        unsigned long flags;
 839        DECLARE_WAITQUEUE(wait, current);
 840
 841        /* block if port is in the process of being closed */
 842
 843        if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
 844                pr_dbg("block_til_ready: close in progress.\n");
 845                interruptible_sleep_on(&port->port.close_wait);
 846                if (port->port.flags & ASYNC_HUP_NOTIFY)
 847                        return -EAGAIN;
 848                else
 849                        return -ERESTARTSYS;
 850        }
 851
 852        /* if non-blocking mode is set ... */
 853
 854        if ((filp->f_flags & O_NONBLOCK) ||
 855                        (tty->flags & (1 << TTY_IO_ERROR))) {
 856                pr_dbg("block_til_ready: non-block mode.\n");
 857                port->port.flags |= ASYNC_NORMAL_ACTIVE;
 858                return 0;
 859        }
 860
 861        if (C_CLOCAL(tty))
 862                do_clocal = 1;
 863
 864        /* block waiting for DCD to be asserted, and while
 865                                                callout dev is busy */
 866        retval = 0;
 867        add_wait_queue(&port->port.open_wait, &wait);
 868
 869        spin_lock_irqsave(&card->card_lock, flags);
 870        if (!tty_hung_up_p(filp))
 871                port->port.count--;
 872        port->port.blocked_open++;
 873        spin_unlock_irqrestore(&card->card_lock, flags);
 874
 875        while (1) {
 876                raise_dtr_rts(port);
 877
 878                set_current_state(TASK_INTERRUPTIBLE);
 879                if (tty_hung_up_p(filp) || !(port->port.flags & ASYNC_INITIALIZED)) {
 880                        if (port->port.flags & ASYNC_HUP_NOTIFY)
 881                                retval = -EAGAIN;
 882                        else
 883                                retval = -ERESTARTSYS;
 884                        break;
 885                }
 886                if (!(port->port.flags & ASYNC_CLOSING) &&
 887                                (do_clocal || (port->status & ISI_DCD))) {
 888                        break;
 889                }
 890                if (signal_pending(current)) {
 891                        retval = -ERESTARTSYS;
 892                        break;
 893                }
 894                schedule();
 895        }
 896        set_current_state(TASK_RUNNING);
 897        remove_wait_queue(&port->port.open_wait, &wait);
 898        spin_lock_irqsave(&card->card_lock, flags);
 899        if (!tty_hung_up_p(filp))
 900                port->port.count++;
 901        port->port.blocked_open--;
 902        spin_unlock_irqrestore(&card->card_lock, flags);
 903        if (retval)
 904                return retval;
 905        port->port.flags |= ASYNC_NORMAL_ACTIVE;
 906        return 0;
 907}
 908
 909static int isicom_open(struct tty_struct *tty, struct file *filp)
 910{
 911        struct isi_port *port;
 912        struct isi_board *card;
 913        unsigned int board;
 914        int error, line;
 915
 916        line = tty->index;
 917        if (line < 0 || line > PORT_COUNT-1)
 918                return -ENODEV;
 919        board = BOARD(line);
 920        card = &isi_card[board];
 921
 922        if (!(card->status & FIRMWARE_LOADED))
 923                return -ENODEV;
 924
 925        /*  open on a port greater than the port count for the card !!! */
 926        if (line > ((board * 16) + card->port_count - 1))
 927                return -ENODEV;
 928
 929        port = &isi_ports[line];
 930        if (isicom_paranoia_check(port, tty->name, "isicom_open"))
 931                return -ENODEV;
 932
 933        isicom_setup_board(card);
 934
 935        port->port.count++;
 936        tty->driver_data = port;
 937        tty_port_tty_set(&port->port, tty);
 938        error = isicom_setup_port(tty);
 939        if (error == 0)
 940                error = block_til_ready(tty, filp, port);
 941        return error;
 942}
 943
 944/* close et all */
 945
 946static inline void isicom_shutdown_board(struct isi_board *bp)
 947{
 948        if (bp->status & BOARD_ACTIVE)
 949                bp->status &= ~BOARD_ACTIVE;
 950}
 951
 952/* card->lock HAS to be held */
 953static void isicom_shutdown_port(struct isi_port *port)
 954{
 955        struct isi_board *card = port->card;
 956        struct tty_struct *tty;
 957
 958        tty = tty_port_tty_get(&port->port);
 959
 960        if (!(port->port.flags & ASYNC_INITIALIZED)) {
 961                tty_kref_put(tty);
 962                return;
 963        }
 964
 965        tty_port_free_xmit_buf(&port->port);
 966        port->port.flags &= ~ASYNC_INITIALIZED;
 967        /* 3rd October 2000 : Vinayak P Risbud */
 968        tty_port_tty_set(&port->port, NULL);
 969
 970        /*Fix done by Anil .S on 30-04-2001
 971        remote login through isi port has dtr toggle problem
 972        due to which the carrier drops before the password prompt
 973        appears on the remote end. Now we drop the dtr only if the
 974        HUPCL(Hangup on close) flag is set for the tty*/
 975
 976        if (C_HUPCL(tty))
 977                /* drop dtr on this port */
 978                drop_dtr(port);
 979
 980        /* any other port uninits  */
 981        if (tty)
 982                set_bit(TTY_IO_ERROR, &tty->flags);
 983
 984        if (--card->count < 0) {
 985                pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n",
 986                        card->base, card->count);
 987                card->count = 0;
 988        }
 989
 990        /* last port was closed, shutdown that boad too */
 991        if (C_HUPCL(tty)) {
 992                if (!card->count)
 993                        isicom_shutdown_board(card);
 994        }
 995}
 996
 997static void isicom_flush_buffer(struct tty_struct *tty)
 998{
 999        struct isi_port *port = tty->driver_data;
1000        struct isi_board *card = port->card;
1001        unsigned long flags;
1002
1003        if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
1004                return;
1005
1006        spin_lock_irqsave(&card->card_lock, flags);
1007        port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1008        spin_unlock_irqrestore(&card->card_lock, flags);
1009
1010        tty_wakeup(tty);
1011}
1012
1013static void isicom_close(struct tty_struct *tty, struct file *filp)
1014{
1015        struct isi_port *port = tty->driver_data;
1016        struct isi_board *card;
1017        unsigned long flags;
1018
1019        if (!port)
1020                return;
1021        card = port->card;
1022        if (isicom_paranoia_check(port, tty->name, "isicom_close"))
1023                return;
1024
1025        pr_dbg("Close start!!!.\n");
1026
1027        spin_lock_irqsave(&card->card_lock, flags);
1028        if (tty_hung_up_p(filp)) {
1029                spin_unlock_irqrestore(&card->card_lock, flags);
1030                return;
1031        }
1032
1033        if (tty->count == 1 && port->port.count != 1) {
1034                printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1035                        "count tty->count = 1 port count = %d.\n",
1036                        card->base, port->port.count);
1037                port->port.count = 1;
1038        }
1039        if (--port->port.count < 0) {
1040                printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1041                        "count for channel%d = %d", card->base, port->channel,
1042                        port->port.count);
1043                port->port.count = 0;
1044        }
1045
1046        if (port->port.count) {
1047                spin_unlock_irqrestore(&card->card_lock, flags);
1048                return;
1049        }
1050        port->port.flags |= ASYNC_CLOSING;
1051        tty->closing = 1;
1052        spin_unlock_irqrestore(&card->card_lock, flags);
1053
1054        if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1055                tty_wait_until_sent(tty, port->port.closing_wait);
1056        /* indicate to the card that no more data can be received
1057           on this port */
1058        spin_lock_irqsave(&card->card_lock, flags);
1059        if (port->port.flags & ASYNC_INITIALIZED) {
1060                card->port_status &= ~(1 << port->channel);
1061                outw(card->port_status, card->base + 0x02);
1062        }
1063        isicom_shutdown_port(port);
1064        spin_unlock_irqrestore(&card->card_lock, flags);
1065
1066        isicom_flush_buffer(tty);
1067        tty_ldisc_flush(tty);
1068
1069        spin_lock_irqsave(&card->card_lock, flags);
1070        tty->closing = 0;
1071
1072        if (port->port.blocked_open) {
1073                spin_unlock_irqrestore(&card->card_lock, flags);
1074                if (port->port.close_delay) {
1075                        pr_dbg("scheduling until time out.\n");
1076                        msleep_interruptible(
1077                                jiffies_to_msecs(port->port.close_delay));
1078                }
1079                spin_lock_irqsave(&card->card_lock, flags);
1080                wake_up_interruptible(&port->port.open_wait);
1081        }
1082        port->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1083        wake_up_interruptible(&port->port.close_wait);
1084        spin_unlock_irqrestore(&card->card_lock, flags);
1085}
1086
1087/* write et all */
1088static int isicom_write(struct tty_struct *tty,        const unsigned char *buf,
1089        int count)
1090{
1091        struct isi_port *port = tty->driver_data;
1092        struct isi_board *card = port->card;
1093        unsigned long flags;
1094        int cnt, total = 0;
1095
1096        if (isicom_paranoia_check(port, tty->name, "isicom_write"))
1097                return 0;
1098
1099        spin_lock_irqsave(&card->card_lock, flags);
1100
1101        while (1) {
1102                cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
1103                                - 1, SERIAL_XMIT_SIZE - port->xmit_head));
1104                if (cnt <= 0)
1105                        break;
1106
1107                memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt);
1108                port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
1109                        - 1);
1110                port->xmit_cnt += cnt;
1111                buf += cnt;
1112                count -= cnt;
1113                total += cnt;
1114        }
1115        if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped)
1116                port->status |= ISI_TXOK;
1117        spin_unlock_irqrestore(&card->card_lock, flags);
1118        return total;
1119}
1120
1121/* put_char et all */
1122static int isicom_put_char(struct tty_struct *tty, unsigned char ch)
1123{
1124        struct isi_port *port = tty->driver_data;
1125        struct isi_board *card = port->card;
1126        unsigned long flags;
1127
1128        if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
1129                return 0;
1130
1131        spin_lock_irqsave(&card->card_lock, flags);
1132        if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
1133                spin_unlock_irqrestore(&card->card_lock, flags);
1134                return 0;
1135        }
1136
1137        port->port.xmit_buf[port->xmit_head++] = ch;
1138        port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
1139        port->xmit_cnt++;
1140        spin_unlock_irqrestore(&card->card_lock, flags);
1141        return 1;
1142}
1143
1144/* flush_chars et all */
1145static void isicom_flush_chars(struct tty_struct *tty)
1146{
1147        struct isi_port *port = tty->driver_data;
1148
1149        if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars"))
1150                return;
1151
1152        if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1153                        !port->port.xmit_buf)
1154                return;
1155
1156        /* this tells the transmitter to consider this port for
1157           data output to the card ... that's the best we can do. */
1158        port->status |= ISI_TXOK;
1159}
1160
1161/* write_room et all */
1162static int isicom_write_room(struct tty_struct *tty)
1163{
1164        struct isi_port *port = tty->driver_data;
1165        int free;
1166
1167        if (isicom_paranoia_check(port, tty->name, "isicom_write_room"))
1168                return 0;
1169
1170        free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1171        if (free < 0)
1172                free = 0;
1173        return free;
1174}
1175
1176/* chars_in_buffer et all */
1177static int isicom_chars_in_buffer(struct tty_struct *tty)
1178{
1179        struct isi_port *port = tty->driver_data;
1180        if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer"))
1181                return 0;
1182        return port->xmit_cnt;
1183}
1184
1185/* ioctl et all */
1186static int isicom_send_break(struct tty_struct *tty, int length)
1187{
1188        struct isi_port *port = tty->driver_data;
1189        struct isi_board *card = port->card;
1190        unsigned long base = card->base;
1191
1192        if (length == -1)
1193                return -EOPNOTSUPP;
1194
1195        if (!lock_card(card))
1196                return -EINVAL;
1197
1198        outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
1199        outw((length & 0xff) << 8 | 0x00, base);
1200        outw((length & 0xff00), base);
1201        InterruptTheCard(base);
1202
1203        unlock_card(card);
1204        return 0;
1205}
1206
1207static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
1208{
1209        struct isi_port *port = tty->driver_data;
1210        /* just send the port status */
1211        u16 status = port->status;
1212
1213        if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1214                return -ENODEV;
1215
1216        return  ((status & ISI_RTS) ? TIOCM_RTS : 0) |
1217                ((status & ISI_DTR) ? TIOCM_DTR : 0) |
1218                ((status & ISI_DCD) ? TIOCM_CAR : 0) |
1219                ((status & ISI_DSR) ? TIOCM_DSR : 0) |
1220                ((status & ISI_CTS) ? TIOCM_CTS : 0) |
1221                ((status & ISI_RI ) ? TIOCM_RI  : 0);
1222}
1223
1224static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
1225        unsigned int set, unsigned int clear)
1226{
1227        struct isi_port *port = tty->driver_data;
1228        unsigned long flags;
1229
1230        if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1231                return -ENODEV;
1232
1233        spin_lock_irqsave(&port->card->card_lock, flags);
1234        if (set & TIOCM_RTS)
1235                raise_rts(port);
1236        if (set & TIOCM_DTR)
1237                raise_dtr(port);
1238
1239        if (clear & TIOCM_RTS)
1240                drop_rts(port);
1241        if (clear & TIOCM_DTR)
1242                drop_dtr(port);
1243        spin_unlock_irqrestore(&port->card->card_lock, flags);
1244
1245        return 0;
1246}
1247
1248static int isicom_set_serial_info(struct tty_struct *tty,
1249                                        struct serial_struct __user *info)
1250{
1251        struct isi_port *port = tty->driver_data;
1252        struct serial_struct newinfo;
1253        int reconfig_port;
1254
1255        if (copy_from_user(&newinfo, info, sizeof(newinfo)))
1256                return -EFAULT;
1257
1258        lock_kernel();
1259
1260        reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) !=
1261                (newinfo.flags & ASYNC_SPD_MASK));
1262
1263        if (!capable(CAP_SYS_ADMIN)) {
1264                if ((newinfo.close_delay != port->port.close_delay) ||
1265                                (newinfo.closing_wait != port->port.closing_wait) ||
1266                                ((newinfo.flags & ~ASYNC_USR_MASK) !=
1267                                (port->port.flags & ~ASYNC_USR_MASK))) {
1268                        unlock_kernel();
1269                        return -EPERM;
1270                }
1271                port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1272                                (newinfo.flags & ASYNC_USR_MASK));
1273        } else {
1274                port->port.close_delay = newinfo.close_delay;
1275                port->port.closing_wait = newinfo.closing_wait;
1276                port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1277                                (newinfo.flags & ASYNC_FLAGS));
1278        }
1279        if (reconfig_port) {
1280                unsigned long flags;
1281                spin_lock_irqsave(&port->card->card_lock, flags);
1282                isicom_config_port(tty);
1283                spin_unlock_irqrestore(&port->card->card_lock, flags);
1284        }
1285        unlock_kernel();
1286        return 0;
1287}
1288
1289static int isicom_get_serial_info(struct isi_port *port,
1290        struct serial_struct __user *info)
1291{
1292        struct serial_struct out_info;
1293
1294        lock_kernel();
1295        memset(&out_info, 0, sizeof(out_info));
1296/*        out_info.type = ? */
1297        out_info.line = port - isi_ports;
1298        out_info.port = port->card->base;
1299        out_info.irq = port->card->irq;
1300        out_info.flags = port->port.flags;
1301/*        out_info.baud_base = ? */
1302        out_info.close_delay = port->port.close_delay;
1303        out_info.closing_wait = port->port.closing_wait;
1304        unlock_kernel();
1305        if (copy_to_user(info, &out_info, sizeof(out_info)))
1306                return -EFAULT;
1307        return 0;
1308}
1309
1310static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1311        unsigned int cmd, unsigned long arg)
1312{
1313        struct isi_port *port = tty->driver_data;
1314        void __user *argp = (void __user *)arg;
1315
1316        if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
1317                return -ENODEV;
1318
1319        switch (cmd) {
1320        case TIOCGSERIAL:
1321                return isicom_get_serial_info(port, argp);
1322
1323        case TIOCSSERIAL:
1324                return isicom_set_serial_info(tty, argp);
1325
1326        default:
1327                return -ENOIOCTLCMD;
1328        }
1329        return 0;
1330}
1331
1332/* set_termios et all */
1333static void isicom_set_termios(struct tty_struct *tty,
1334        struct ktermios *old_termios)
1335{
1336        struct isi_port *port = tty->driver_data;
1337        unsigned long flags;
1338
1339        if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
1340                return;
1341
1342        if (tty->termios->c_cflag == old_termios->c_cflag &&
1343                        tty->termios->c_iflag == old_termios->c_iflag)
1344                return;
1345
1346        spin_lock_irqsave(&port->card->card_lock, flags);
1347        isicom_config_port(tty);
1348        spin_unlock_irqrestore(&port->card->card_lock, flags);
1349
1350        if ((old_termios->c_cflag & CRTSCTS) &&
1351                        !(tty->termios->c_cflag & CRTSCTS)) {
1352                tty->hw_stopped = 0;
1353                isicom_start(tty);
1354        }
1355}
1356
1357/* throttle et all */
1358static void isicom_throttle(struct tty_struct *tty)
1359{
1360        struct isi_port *port = tty->driver_data;
1361        struct isi_board *card = port->card;
1362
1363        if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
1364                return;
1365
1366        /* tell the card that this port cannot handle any more data for now */
1367        card->port_status &= ~(1 << port->channel);
1368        outw(card->port_status, card->base + 0x02);
1369}
1370
1371/* unthrottle et all */
1372static void isicom_unthrottle(struct tty_struct *tty)
1373{
1374        struct isi_port *port = tty->driver_data;
1375        struct isi_board *card = port->card;
1376
1377        if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
1378                return;
1379
1380        /* tell the card that this port is ready to accept more data */
1381        card->port_status |= (1 << port->channel);
1382        outw(card->port_status, card->base + 0x02);
1383}
1384
1385/* stop et all */
1386static void isicom_stop(struct tty_struct *tty)
1387{
1388        struct isi_port *port = tty->driver_data;
1389
1390        if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
1391                return;
1392
1393        /* this tells the transmitter not to consider this port for
1394           data output to the card. */
1395        port->status &= ~ISI_TXOK;
1396}
1397
1398/* start et all */
1399static void isicom_start(struct tty_struct *tty)
1400{
1401        struct isi_port *port = tty->driver_data;
1402
1403        if (isicom_paranoia_check(port, tty->name, "isicom_start"))
1404                return;
1405
1406        /* this tells the transmitter to consider this port for
1407           data output to the card. */
1408        port->status |= ISI_TXOK;
1409}
1410
1411static void isicom_hangup(struct tty_struct *tty)
1412{
1413        struct isi_port *port = tty->driver_data;
1414        unsigned long flags;
1415
1416        if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
1417                return;
1418
1419        spin_lock_irqsave(&port->card->card_lock, flags);
1420        isicom_shutdown_port(port);
1421        spin_unlock_irqrestore(&port->card->card_lock, flags);
1422
1423        port->port.count = 0;
1424        port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1425        tty_port_tty_set(&port->port, NULL);
1426        wake_up_interruptible(&port->port.open_wait);
1427}
1428
1429
1430/*
1431 * Driver init and deinit functions
1432 */
1433
1434static const struct tty_operations isicom_ops = {
1435        .open                        = isicom_open,
1436        .close                        = isicom_close,
1437        .write                        = isicom_write,
1438        .put_char                = isicom_put_char,
1439        .flush_chars                = isicom_flush_chars,
1440        .write_room                = isicom_write_room,
1441        .chars_in_buffer        = isicom_chars_in_buffer,
1442        .ioctl                        = isicom_ioctl,
1443        .set_termios                = isicom_set_termios,
1444        .throttle                = isicom_throttle,
1445        .unthrottle                = isicom_unthrottle,
1446        .stop                        = isicom_stop,
1447        .start                        = isicom_start,
1448        .hangup                        = isicom_hangup,
1449        .flush_buffer                = isicom_flush_buffer,
1450        .tiocmget                = isicom_tiocmget,
1451        .tiocmset                = isicom_tiocmset,
1452        .break_ctl                = isicom_send_break,
1453};
1454
1455static int __devinit reset_card(struct pci_dev *pdev,
1456        const unsigned int card, unsigned int *signature)
1457{
1458        struct isi_board *board = pci_get_drvdata(pdev);
1459        unsigned long base = board->base;
1460        unsigned int sig, portcount = 0;
1461        int retval = 0;
1462
1463        dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
1464                base);
1465
1466        inw(base + 0x8);
1467
1468        msleep(10);
1469
1470        outw(0, base + 0x8); /* Reset */
1471
1472        msleep(1000);
1473
1474        sig = inw(base + 0x4) & 0xff;
1475
1476        if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd &&
1477                        sig != 0xee) {
1478                dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible "
1479                        "bad I/O Port Address 0x%lx).\n", card + 1, base);
1480                dev_dbg(&pdev->dev, "Sig=0x%x\n", sig);
1481                retval = -EIO;
1482                goto end;
1483        }
1484
1485        msleep(10);
1486
1487        portcount = inw(base + 0x2);
1488        if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 &&
1489                                portcount != 8 && portcount != 16)) {
1490                dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
1491                        card + 1);
1492                retval = -EIO;
1493                goto end;
1494        }
1495
1496        switch (sig) {
1497        case 0xa5:
1498        case 0xbb:
1499        case 0xdd:
1500                board->port_count = (portcount == 4) ? 4 : 8;
1501                board->shift_count = 12;
1502                break;
1503        case 0xcc:
1504        case 0xee:
1505                board->port_count = 16;
1506                board->shift_count = 11;
1507                break;
1508        }
1509        dev_info(&pdev->dev, "-Done\n");
1510        *signature = sig;
1511
1512end:
1513        return retval;
1514}
1515
1516static int __devinit load_firmware(struct pci_dev *pdev,
1517        const unsigned int index, const unsigned int signature)
1518{
1519        struct isi_board *board = pci_get_drvdata(pdev);
1520        const struct firmware *fw;
1521        unsigned long base = board->base;
1522        unsigned int a;
1523        u16 word_count, status;
1524        int retval = -EIO;
1525        char *name;
1526        u8 *data;
1527
1528        struct stframe {
1529                u16        addr;
1530                u16        count;
1531                u8        data[0];
1532        } *frame;
1533
1534        switch (signature) {
1535        case 0xa5:
1536                name = "isi608.bin";
1537                break;
1538        case 0xbb:
1539                name = "isi608em.bin";
1540                break;
1541        case 0xcc:
1542                name = "isi616em.bin";
1543                break;
1544        case 0xdd:
1545                name = "isi4608.bin";
1546                break;
1547        case 0xee:
1548                name = "isi4616.bin";
1549                break;
1550        default:
1551                dev_err(&pdev->dev, "Unknown signature.\n");
1552                goto end;
1553        }
1554
1555        retval = request_firmware(&fw, name, &pdev->dev);
1556        if (retval)
1557                goto end;
1558
1559        retval = -EIO;
1560
1561        for (frame = (struct stframe *)fw->data;
1562                        frame < (struct stframe *)(fw->data + fw->size);
1563                        frame = (struct stframe *)((u8 *)(frame + 1) +
1564                                frame->count)) {
1565                if (WaitTillCardIsFree(base))
1566                        goto errrelfw;
1567
1568                outw(0xf0, base);        /* start upload sequence */
1569                outw(0x00, base);
1570                outw(frame->addr, base); /* lsb of address */
1571
1572                word_count = frame->count / 2 + frame->count % 2;
1573                outw(word_count, base);
1574                InterruptTheCard(base);
1575
1576                udelay(100); /* 0x2f */
1577
1578                if (WaitTillCardIsFree(base))
1579                        goto errrelfw;
1580
1581                status = inw(base + 0x4);
1582                if (status != 0) {
1583                        dev_warn(&pdev->dev, "Card%d rejected load header:\n"
1584                                KERN_WARNING "Address:0x%x\n"
1585                                KERN_WARNING "Count:0x%x\n"
1586                                KERN_WARNING "Status:0x%x\n",
1587                                index + 1, frame->addr, frame->count, status);
1588                        goto errrelfw;
1589                }
1590                outsw(base, frame->data, word_count);
1591
1592                InterruptTheCard(base);
1593
1594                udelay(50); /* 0x0f */
1595
1596                if (WaitTillCardIsFree(base))
1597                        goto errrelfw;
1598
1599                status = inw(base + 0x4);
1600                if (status != 0) {
1601                        dev_err(&pdev->dev, "Card%d got out of sync.Card "
1602                                "Status:0x%x\n", index + 1, status);
1603                        goto errrelfw;
1604                }
1605        }
1606
1607/* XXX: should we test it by reading it back and comparing with original like
1608 * in load firmware package? */
1609        for (frame = (struct stframe *)fw->data;
1610                        frame < (struct stframe *)(fw->data + fw->size);
1611                        frame = (struct stframe *)((u8 *)(frame + 1) +
1612                                frame->count)) {
1613                if (WaitTillCardIsFree(base))
1614                        goto errrelfw;
1615
1616                outw(0xf1, base); /* start download sequence */
1617                outw(0x00, base);
1618                outw(frame->addr, base); /* lsb of address */
1619
1620                word_count = (frame->count >> 1) + frame->count % 2;
1621                outw(word_count + 1, base);
1622                InterruptTheCard(base);
1623
1624                udelay(50); /* 0xf */
1625
1626                if (WaitTillCardIsFree(base))
1627                        goto errrelfw;
1628
1629                status = inw(base + 0x4);
1630                if (status != 0) {
1631                        dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
1632                                KERN_WARNING "Address:0x%x\n"
1633                                KERN_WARNING "Count:0x%x\n"
1634                                KERN_WARNING "Status: 0x%x\n",
1635                                index + 1, frame->addr, frame->count, status);
1636                        goto errrelfw;
1637                }
1638
1639                data = kmalloc(word_count * 2, GFP_KERNEL);
1640                if (data == NULL) {
1641                        dev_err(&pdev->dev, "Card%d, firmware upload "
1642                                "failed, not enough memory\n", index + 1);
1643                        goto errrelfw;
1644                }
1645                inw(base);
1646                insw(base, data, word_count);
1647                InterruptTheCard(base);
1648
1649                for (a = 0; a < frame->count; a++)
1650                        if (data[a] != frame->data[a]) {
1651                                kfree(data);
1652                                dev_err(&pdev->dev, "Card%d, firmware upload "
1653                                        "failed\n", index + 1);
1654                                goto errrelfw;
1655                        }
1656                kfree(data);
1657
1658                udelay(50); /* 0xf */
1659
1660                if (WaitTillCardIsFree(base))
1661                        goto errrelfw;
1662
1663                status = inw(base + 0x4);
1664                if (status != 0) {
1665                        dev_err(&pdev->dev, "Card%d verify got out of sync. "
1666                                "Card Status:0x%x\n", index + 1, status);
1667                        goto errrelfw;
1668                }
1669        }
1670
1671        /* xfer ctrl */
1672        if (WaitTillCardIsFree(base))
1673                goto errrelfw;
1674
1675        outw(0xf2, base);
1676        outw(0x800, base);
1677        outw(0x0, base);
1678        outw(0x0, base);
1679        InterruptTheCard(base);
1680        outw(0x0, base + 0x4); /* for ISI4608 cards */
1681
1682        board->status |= FIRMWARE_LOADED;
1683        retval = 0;
1684
1685errrelfw:
1686        release_firmware(fw);
1687end:
1688        return retval;
1689}
1690
1691/*
1692 *        Insmod can set static symbols so keep these static
1693 */
1694static unsigned int card_count;
1695
1696static int __devinit isicom_probe(struct pci_dev *pdev,
1697        const struct pci_device_id *ent)
1698{
1699        unsigned int signature, index;
1700        int retval = -EPERM;
1701        struct isi_board *board = NULL;
1702
1703        if (card_count >= BOARD_COUNT)
1704                goto err;
1705
1706        retval = pci_enable_device(pdev);
1707        if (retval) {
1708                dev_err(&pdev->dev, "failed to enable\n");
1709                goto err;
1710        }
1711
1712        dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
1713
1714        /* allot the first empty slot in the array */
1715        for (index = 0; index < BOARD_COUNT; index++)
1716                if (isi_card[index].base == 0) {
1717                        board = &isi_card[index];
1718                        break;
1719                }
1720
1721        board->index = index;
1722        board->base = pci_resource_start(pdev, 3);
1723        board->irq = pdev->irq;
1724        card_count++;
1725
1726        pci_set_drvdata(pdev, board);
1727
1728        retval = pci_request_region(pdev, 3, ISICOM_NAME);
1729        if (retval) {
1730                dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
1731                        "will be disabled.\n", board->base, board->base + 15,
1732                        index + 1);
1733                retval = -EBUSY;
1734                goto errdec;
1735        }
1736
1737        retval = request_irq(board->irq, isicom_interrupt,
1738                        IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
1739        if (retval < 0) {
1740                dev_err(&pdev->dev, "Could not install handler at Irq %d. "
1741                        "Card%d will be disabled.\n", board->irq, index + 1);
1742                goto errunrr;
1743        }
1744
1745        retval = reset_card(pdev, index, &signature);
1746        if (retval < 0)
1747                goto errunri;
1748
1749        retval = load_firmware(pdev, index, signature);
1750        if (retval < 0)
1751                goto errunri;
1752
1753        for (index = 0; index < board->port_count; index++)
1754                tty_register_device(isicom_normal, board->index * 16 + index,
1755                                &pdev->dev);
1756
1757        return 0;
1758
1759errunri:
1760        free_irq(board->irq, board);
1761errunrr:
1762        pci_release_region(pdev, 3);
1763errdec:
1764        board->base = 0;
1765        card_count--;
1766        pci_disable_device(pdev);
1767err:
1768        return retval;
1769}
1770
1771static void __devexit isicom_remove(struct pci_dev *pdev)
1772{
1773        struct isi_board *board = pci_get_drvdata(pdev);
1774        unsigned int i;
1775
1776        for (i = 0; i < board->port_count; i++)
1777                tty_unregister_device(isicom_normal, board->index * 16 + i);
1778
1779        free_irq(board->irq, board);
1780        pci_release_region(pdev, 3);
1781        board->base = 0;
1782        card_count--;
1783        pci_disable_device(pdev);
1784}
1785
1786static int __init isicom_init(void)
1787{
1788        int retval, idx, channel;
1789        struct isi_port *port;
1790
1791        for (idx = 0; idx < BOARD_COUNT; idx++) {
1792                port = &isi_ports[idx * 16];
1793                isi_card[idx].ports = port;
1794                spin_lock_init(&isi_card[idx].card_lock);
1795                for (channel = 0; channel < 16; channel++, port++) {
1796                        tty_port_init(&port->port);
1797                        port->magic = ISICOM_MAGIC;
1798                        port->card = &isi_card[idx];
1799                        port->channel = channel;
1800                        port->port.close_delay = 50 * HZ/100;
1801                        port->port.closing_wait = 3000 * HZ/100;
1802                        port->status = 0;
1803                        /*  . . .  */
1804                }
1805                isi_card[idx].base = 0;
1806                isi_card[idx].irq = 0;
1807        }
1808
1809        /* tty driver structure initialization */
1810        isicom_normal = alloc_tty_driver(PORT_COUNT);
1811        if (!isicom_normal) {
1812                retval = -ENOMEM;
1813                goto error;
1814        }
1815
1816        isicom_normal->owner                        = THIS_MODULE;
1817        isicom_normal->name                         = "ttyM";
1818        isicom_normal->major                        = ISICOM_NMAJOR;
1819        isicom_normal->minor_start                = 0;
1820        isicom_normal->type                        = TTY_DRIVER_TYPE_SERIAL;
1821        isicom_normal->subtype                        = SERIAL_TYPE_NORMAL;
1822        isicom_normal->init_termios                = tty_std_termios;
1823        isicom_normal->init_termios.c_cflag        = B9600 | CS8 | CREAD | HUPCL |
1824                CLOCAL;
1825        isicom_normal->flags                        = TTY_DRIVER_REAL_RAW |
1826                TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK;
1827        tty_set_operations(isicom_normal, &isicom_ops);
1828
1829        retval = tty_register_driver(isicom_normal);
1830        if (retval) {
1831                pr_dbg("Couldn't register the dialin driver\n");
1832                goto err_puttty;
1833        }
1834
1835        retval = pci_register_driver(&isicom_driver);
1836        if (retval < 0) {
1837                printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
1838                goto err_unrtty;
1839        }
1840
1841        mod_timer(&tx, jiffies + 1);
1842
1843        return 0;
1844err_unrtty:
1845        tty_unregister_driver(isicom_normal);
1846err_puttty:
1847        put_tty_driver(isicom_normal);
1848error:
1849        return retval;
1850}
1851
1852static void __exit isicom_exit(void)
1853{
1854        del_timer_sync(&tx);
1855
1856        pci_unregister_driver(&isicom_driver);
1857        tty_unregister_driver(isicom_normal);
1858        put_tty_driver(isicom_normal);
1859}
1860
1861module_init(isicom_init);
1862module_exit(isicom_exit);
1863
1864MODULE_AUTHOR("MultiTech");
1865MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
1866MODULE_LICENSE("GPL");