linux/drivers/char/riscom8.c
<<
>>
Prefs
   1/*
   2 *      linux/drivers/char/riscom.c  -- RISCom/8 multiport serial driver.
   3 *
   4 *      Copyright (C) 1994-1996  Dmitry Gorodchanin (pgmdsg@ibi.com)
   5 *
   6 *      This code is loosely based on the Linux serial driver, written by
   7 *      Linus Torvalds, Theodore T'so and others. The RISCom/8 card
   8 *      programming info was obtained from various drivers for other OSes
   9 *      (FreeBSD, ISC, etc), but no source code from those drivers were
  10 *      directly included in this driver.
  11 *
  12 *
  13 *      This program is free software; you can redistribute it and/or modify
  14 *      it under the terms of the GNU General Public License as published by
  15 *      the Free Software Foundation; either version 2 of the License, or
  16 *      (at your option) any later version.
  17 *
  18 *      This program is distributed in the hope that it will be useful,
  19 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  20 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21 *      GNU General Public License for more details.
  22 *
  23 *      You should have received a copy of the GNU General Public License
  24 *      along with this program; if not, write to the Free Software
  25 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  26 *
  27 *      Revision 1.1
  28 *
  29 *      ChangeLog:
  30 *      Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 27-Jun-2001
  31 *      - get rid of check_region and several cleanups
  32 */
  33
  34#include <linux/module.h>
  35
  36#include <linux/io.h>
  37#include <linux/kernel.h>
  38#include <linux/sched.h>
  39#include <linux/ioport.h>
  40#include <linux/interrupt.h>
  41#include <linux/errno.h>
  42#include <linux/tty.h>
  43#include <linux/mm.h>
  44#include <linux/serial.h>
  45#include <linux/fcntl.h>
  46#include <linux/major.h>
  47#include <linux/init.h>
  48#include <linux/delay.h>
  49#include <linux/tty_flip.h>
  50#include <linux/smp_lock.h>
  51#include <linux/spinlock.h>
  52#include <linux/device.h>
  53
  54#include <linux/uaccess.h>
  55
  56#include "riscom8.h"
  57#include "riscom8_reg.h"
  58
  59/* Am I paranoid or not ? ;-) */
  60#define RISCOM_PARANOIA_CHECK
  61
  62/*
  63 * Crazy InteliCom/8 boards sometimes have swapped CTS & DSR signals.
  64 * You can slightly speed up things by #undefing the following option,
  65 * if you are REALLY sure that your board is correct one.
  66 */
  67
  68#define RISCOM_BRAIN_DAMAGED_CTS
  69
  70/*
  71 * The following defines are mostly for testing purposes. But if you need
  72 * some nice reporting in your syslog, you can define them also.
  73 */
  74#undef RC_REPORT_FIFO
  75#undef RC_REPORT_OVERRUN
  76
  77
  78#define RISCOM_LEGAL_FLAGS \
  79        (ASYNC_HUP_NOTIFY   | ASYNC_SAK          | ASYNC_SPLIT_TERMIOS   | \
  80         ASYNC_SPD_HI       | ASYNC_SPEED_VHI    | ASYNC_SESSION_LOCKOUT | \
  81         ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
  82
  83static struct tty_driver *riscom_driver;
  84
  85static DEFINE_SPINLOCK(riscom_lock);
  86
  87static struct riscom_board rc_board[RC_NBOARD] =  {
  88        {
  89                .base   = RC_IOBASE1,
  90        },
  91        {
  92                .base   = RC_IOBASE2,
  93        },
  94        {
  95                .base   = RC_IOBASE3,
  96        },
  97        {
  98                .base   = RC_IOBASE4,
  99        },
 100};
 101
 102static struct riscom_port rc_port[RC_NBOARD * RC_NPORT];
 103
 104/* RISCom/8 I/O ports addresses (without address translation) */
 105static unsigned short rc_ioport[] =  {
 106#if 1
 107        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c,
 108#else
 109        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, 0x10,
 110        0x11, 0x12, 0x18, 0x28, 0x31, 0x32, 0x39, 0x3a, 0x40, 0x41, 0x61, 0x62,
 111        0x63, 0x64, 0x6b, 0x70, 0x71, 0x78, 0x7a, 0x7b, 0x7f, 0x100, 0x101
 112#endif
 113};
 114#define RC_NIOPORT      ARRAY_SIZE(rc_ioport)
 115
 116
 117static int rc_paranoia_check(struct riscom_port const *port,
 118                                    char *name, const char *routine)
 119{
 120#ifdef RISCOM_PARANOIA_CHECK
 121        static const char badmagic[] = KERN_INFO
 122                "rc: Warning: bad riscom port magic number for device %s in %s\n";
 123        static const char badinfo[] = KERN_INFO
 124                "rc: Warning: null riscom port for device %s in %s\n";
 125
 126        if (!port) {
 127                printk(badinfo, name, routine);
 128                return 1;
 129        }
 130        if (port->magic != RISCOM8_MAGIC) {
 131                printk(badmagic, name, routine);
 132                return 1;
 133        }
 134#endif
 135        return 0;
 136}
 137
 138/*
 139 *
 140 *  Service functions for RISCom/8 driver.
 141 *
 142 */
 143
 144/* Get board number from pointer */
 145static inline int board_No(struct riscom_board const *bp)
 146{
 147        return bp - rc_board;
 148}
 149
 150/* Get port number from pointer */
 151static inline int port_No(struct riscom_port const *port)
 152{
 153        return RC_PORT(port - rc_port);
 154}
 155
 156/* Get pointer to board from pointer to port */
 157static inline struct riscom_board *port_Board(struct riscom_port const *port)
 158{
 159        return &rc_board[RC_BOARD(port - rc_port)];
 160}
 161
 162/* Input Byte from CL CD180 register */
 163static inline unsigned char rc_in(struct riscom_board const *bp,
 164                                                        unsigned short reg)
 165{
 166        return inb(bp->base + RC_TO_ISA(reg));
 167}
 168
 169/* Output Byte to CL CD180 register */
 170static inline void rc_out(struct riscom_board const *bp, unsigned short reg,
 171                          unsigned char val)
 172{
 173        outb(val, bp->base + RC_TO_ISA(reg));
 174}
 175
 176/* Wait for Channel Command Register ready */
 177static void rc_wait_CCR(struct riscom_board const *bp)
 178{
 179        unsigned long delay;
 180
 181        /* FIXME: need something more descriptive then 100000 :) */
 182        for (delay = 100000; delay; delay--)
 183                if (!rc_in(bp, CD180_CCR))
 184                        return;
 185
 186        printk(KERN_INFO "rc%d: Timeout waiting for CCR.\n", board_No(bp));
 187}
 188
 189/*
 190 *  RISCom/8 probe functions.
 191 */
 192
 193static int rc_request_io_range(struct riscom_board * const bp)
 194{
 195        int i;
 196
 197        for (i = 0; i < RC_NIOPORT; i++)
 198                if (!request_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1,
 199                                   "RISCom/8"))  {
 200                        goto out_release;
 201                }
 202        return 0;
 203out_release:
 204        printk(KERN_INFO "rc%d: Skipping probe at 0x%03x. IO address in use.\n",
 205                         board_No(bp), bp->base);
 206        while (--i >= 0)
 207                release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1);
 208        return 1;
 209}
 210
 211static void rc_release_io_range(struct riscom_board * const bp)
 212{
 213        int i;
 214
 215        for (i = 0; i < RC_NIOPORT; i++)
 216                release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1);
 217}
 218
 219/* Reset and setup CD180 chip */
 220static void __init rc_init_CD180(struct riscom_board const *bp)
 221{
 222        unsigned long flags;
 223
 224        spin_lock_irqsave(&riscom_lock, flags);
 225
 226        rc_out(bp, RC_CTOUT, 0);                   /* Clear timeout        */
 227        rc_wait_CCR(bp);                           /* Wait for CCR ready   */
 228        rc_out(bp, CD180_CCR, CCR_HARDRESET);      /* Reset CD180 chip     */
 229        spin_unlock_irqrestore(&riscom_lock, flags);
 230        msleep(50);                                /* Delay 0.05 sec       */
 231        spin_lock_irqsave(&riscom_lock, flags);
 232        rc_out(bp, CD180_GIVR, RC_ID);             /* Set ID for this chip */
 233        rc_out(bp, CD180_GICR, 0);                 /* Clear all bits       */
 234        rc_out(bp, CD180_PILR1, RC_ACK_MINT);      /* Prio for modem intr  */
 235        rc_out(bp, CD180_PILR2, RC_ACK_TINT);      /* Prio for tx intr     */
 236        rc_out(bp, CD180_PILR3, RC_ACK_RINT);      /* Prio for rx intr     */
 237
 238        /* Setting up prescaler. We need 4 ticks per 1 ms */
 239        rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8);
 240        rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff);
 241
 242        spin_unlock_irqrestore(&riscom_lock, flags);
 243}
 244
 245/* Main probing routine, also sets irq. */
 246static int __init rc_probe(struct riscom_board *bp)
 247{
 248        unsigned char val1, val2;
 249        int irqs = 0;
 250        int retries;
 251
 252        bp->irq = 0;
 253
 254        if (rc_request_io_range(bp))
 255                return 1;
 256
 257        /* Are the I/O ports here ? */
 258        rc_out(bp, CD180_PPRL, 0x5a);
 259        outb(0xff, 0x80);
 260        val1 = rc_in(bp, CD180_PPRL);
 261        rc_out(bp, CD180_PPRL, 0xa5);
 262        outb(0x00, 0x80);
 263        val2 = rc_in(bp, CD180_PPRL);
 264
 265        if ((val1 != 0x5a) || (val2 != 0xa5))  {
 266                printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not found.\n",
 267                       board_No(bp), bp->base);
 268                goto out_release;
 269        }
 270
 271        /* It's time to find IRQ for this board */
 272        for (retries = 0; retries < 5 && irqs <= 0; retries++) {
 273                irqs = probe_irq_on();
 274                rc_init_CD180(bp);               /* Reset CD180 chip         */
 275                rc_out(bp, CD180_CAR, 2);        /* Select port 2            */
 276                rc_wait_CCR(bp);
 277                rc_out(bp, CD180_CCR, CCR_TXEN); /* Enable transmitter       */
 278                rc_out(bp, CD180_IER, IER_TXRDY);/* Enable tx empty intr     */
 279                msleep(50);
 280                irqs = probe_irq_off(irqs);
 281                val1 = rc_in(bp, RC_BSR);       /* Get Board Status reg      */
 282                val2 = rc_in(bp, RC_ACK_TINT);  /* ACK interrupt             */
 283                rc_init_CD180(bp);              /* Reset CD180 again         */
 284
 285                if ((val1 & RC_BSR_TINT) || (val2 != (RC_ID | GIVR_IT_TX)))  {
 286                        printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not "
 287                                        "found.\n", board_No(bp), bp->base);
 288                        goto out_release;
 289                }
 290        }
 291
 292        if (irqs <= 0)  {
 293                printk(KERN_ERR "rc%d: Can't find IRQ for RISCom/8 board "
 294                                "at 0x%03x.\n", board_No(bp), bp->base);
 295                goto out_release;
 296        }
 297        bp->irq = irqs;
 298        bp->flags |= RC_BOARD_PRESENT;
 299
 300        printk(KERN_INFO "rc%d: RISCom/8 Rev. %c board detected at "
 301                         "0x%03x, IRQ %d.\n",
 302               board_No(bp),
 303               (rc_in(bp, CD180_GFRCR) & 0x0f) + 'A',   /* Board revision */
 304               bp->base, bp->irq);
 305
 306        return 0;
 307out_release:
 308        rc_release_io_range(bp);
 309        return 1;
 310}
 311
 312/*
 313 *
 314 *  Interrupt processing routines.
 315 *
 316 */
 317
 318static struct riscom_port *rc_get_port(struct riscom_board const *bp,
 319                                               unsigned char const *what)
 320{
 321        unsigned char channel;
 322        struct riscom_port *port;
 323
 324        channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF;
 325        if (channel < CD180_NCH)  {
 326                port = &rc_port[board_No(bp) * RC_NPORT + channel];
 327                if (port->port.flags & ASYNC_INITIALIZED)
 328                        return port;
 329        }
 330        printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n",
 331               board_No(bp), what, channel);
 332        return NULL;
 333}
 334
 335static void rc_receive_exc(struct riscom_board const *bp)
 336{
 337        struct riscom_port *port;
 338        struct tty_struct *tty;
 339        unsigned char status;
 340        unsigned char ch, flag;
 341
 342        port = rc_get_port(bp, "Receive");
 343        if (port == NULL)
 344                return;
 345
 346        tty = tty_port_tty_get(&port->port);
 347
 348#ifdef RC_REPORT_OVERRUN
 349        status = rc_in(bp, CD180_RCSR);
 350        if (status & RCSR_OE)
 351                port->overrun++;
 352        status &= port->mark_mask;
 353#else
 354        status = rc_in(bp, CD180_RCSR) & port->mark_mask;
 355#endif
 356        ch = rc_in(bp, CD180_RDR);
 357        if (!status)
 358                goto out;
 359        if (status & RCSR_TOUT)  {
 360                printk(KERN_WARNING "rc%d: port %d: Receiver timeout. "
 361                                    "Hardware problems ?\n",
 362                       board_No(bp), port_No(port));
 363                goto out;
 364
 365        } else if (status & RCSR_BREAK)  {
 366                printk(KERN_INFO "rc%d: port %d: Handling break...\n",
 367                       board_No(bp), port_No(port));
 368                flag = TTY_BREAK;
 369                if (tty && (port->port.flags & ASYNC_SAK))
 370                        do_SAK(tty);
 371
 372        } else if (status & RCSR_PE)
 373                flag = TTY_PARITY;
 374
 375        else if (status & RCSR_FE)
 376                flag = TTY_FRAME;
 377
 378        else if (status & RCSR_OE)
 379                flag = TTY_OVERRUN;
 380        else
 381                flag = TTY_NORMAL;
 382
 383        if (tty) {
 384                tty_insert_flip_char(tty, ch, flag);
 385                tty_flip_buffer_push(tty);
 386        }
 387out:
 388        tty_kref_put(tty);
 389}
 390
 391static void rc_receive(struct riscom_board const *bp)
 392{
 393        struct riscom_port *port;
 394        struct tty_struct *tty;
 395        unsigned char count;
 396
 397        port = rc_get_port(bp, "Receive");
 398        if (port == NULL)
 399                return;
 400
 401        tty = tty_port_tty_get(&port->port);
 402
 403        count = rc_in(bp, CD180_RDCR);
 404
 405#ifdef RC_REPORT_FIFO
 406        port->hits[count > 8 ? 9 : count]++;
 407#endif
 408
 409        while (count--)  {
 410                u8 ch = rc_in(bp, CD180_RDR);
 411                if (tty)
 412                        tty_insert_flip_char(tty, ch, TTY_NORMAL);
 413        }
 414        if (tty) {
 415                tty_flip_buffer_push(tty);
 416                tty_kref_put(tty);
 417        }
 418}
 419
 420static void rc_transmit(struct riscom_board const *bp)
 421{
 422        struct riscom_port *port;
 423        struct tty_struct *tty;
 424        unsigned char count;
 425
 426        port = rc_get_port(bp, "Transmit");
 427        if (port == NULL)
 428                return;
 429
 430        tty = tty_port_tty_get(&port->port);
 431
 432        if (port->IER & IER_TXEMPTY) {
 433                /* FIFO drained */
 434                rc_out(bp, CD180_CAR, port_No(port));
 435                port->IER &= ~IER_TXEMPTY;
 436                rc_out(bp, CD180_IER, port->IER);
 437                goto out;
 438        }
 439
 440        if ((port->xmit_cnt <= 0 && !port->break_length)
 441            || (tty && (tty->stopped || tty->hw_stopped)))  {
 442                rc_out(bp, CD180_CAR, port_No(port));
 443                port->IER &= ~IER_TXRDY;
 444                rc_out(bp, CD180_IER, port->IER);
 445                goto out;
 446        }
 447
 448        if (port->break_length)  {
 449                if (port->break_length > 0)  {
 450                        if (port->COR2 & COR2_ETC)  {
 451                                rc_out(bp, CD180_TDR, CD180_C_ESC);
 452                                rc_out(bp, CD180_TDR, CD180_C_SBRK);
 453                                port->COR2 &= ~COR2_ETC;
 454                        }
 455                        count = min_t(int, port->break_length, 0xff);
 456                        rc_out(bp, CD180_TDR, CD180_C_ESC);
 457                        rc_out(bp, CD180_TDR, CD180_C_DELAY);
 458                        rc_out(bp, CD180_TDR, count);
 459                        port->break_length -= count;
 460                        if (port->break_length == 0)
 461                                port->break_length--;
 462                } else  {
 463                        rc_out(bp, CD180_TDR, CD180_C_ESC);
 464                        rc_out(bp, CD180_TDR, CD180_C_EBRK);
 465                        rc_out(bp, CD180_COR2, port->COR2);
 466                        rc_wait_CCR(bp);
 467                        rc_out(bp, CD180_CCR, CCR_CORCHG2);
 468                        port->break_length = 0;
 469                }
 470                goto out;
 471        }
 472
 473        count = CD180_NFIFO;
 474        do {
 475                rc_out(bp, CD180_TDR, port->port.xmit_buf[port->xmit_tail++]);
 476                port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
 477                if (--port->xmit_cnt <= 0)
 478                        break;
 479        } while (--count > 0);
 480
 481        if (port->xmit_cnt <= 0)  {
 482                rc_out(bp, CD180_CAR, port_No(port));
 483                port->IER &= ~IER_TXRDY;
 484                rc_out(bp, CD180_IER, port->IER);
 485        }
 486        if (tty && port->xmit_cnt <= port->wakeup_chars)
 487                tty_wakeup(tty);
 488out:
 489        tty_kref_put(tty);
 490}
 491
 492static void rc_check_modem(struct riscom_board const *bp)
 493{
 494        struct riscom_port *port;
 495        struct tty_struct *tty;
 496        unsigned char mcr;
 497
 498        port = rc_get_port(bp, "Modem");
 499        if (port == NULL)
 500                return;
 501
 502        tty = tty_port_tty_get(&port->port);
 503
 504        mcr = rc_in(bp, CD180_MCR);
 505        if (mcr & MCR_CDCHG) {
 506                if (rc_in(bp, CD180_MSVR) & MSVR_CD)
 507                        wake_up_interruptible(&port->port.open_wait);
 508                else if (tty)
 509                        tty_hangup(tty);
 510        }
 511
 512#ifdef RISCOM_BRAIN_DAMAGED_CTS
 513        if (mcr & MCR_CTSCHG)  {
 514                if (rc_in(bp, CD180_MSVR) & MSVR_CTS)  {
 515                        port->IER |= IER_TXRDY;
 516                        if (tty) {
 517                                tty->hw_stopped = 0;
 518                                if (port->xmit_cnt <= port->wakeup_chars)
 519                                        tty_wakeup(tty);
 520                        }
 521                } else  {
 522                        if (tty)
 523                                tty->hw_stopped = 1;
 524                        port->IER &= ~IER_TXRDY;
 525                }
 526                rc_out(bp, CD180_IER, port->IER);
 527        }
 528        if (mcr & MCR_DSRCHG)  {
 529                if (rc_in(bp, CD180_MSVR) & MSVR_DSR)  {
 530                        port->IER |= IER_TXRDY;
 531                        if (tty) {
 532                                tty->hw_stopped = 0;
 533                                if (port->xmit_cnt <= port->wakeup_chars)
 534                                        tty_wakeup(tty);
 535                        }
 536                } else  {
 537                        if (tty)
 538                                tty->hw_stopped = 1;
 539                        port->IER &= ~IER_TXRDY;
 540                }
 541                rc_out(bp, CD180_IER, port->IER);
 542        }
 543#endif /* RISCOM_BRAIN_DAMAGED_CTS */
 544
 545        /* Clear change bits */
 546        rc_out(bp, CD180_MCR, 0);
 547        tty_kref_put(tty);
 548}
 549
 550/* The main interrupt processing routine */
 551static irqreturn_t rc_interrupt(int dummy, void *dev_id)
 552{
 553        unsigned char status;
 554        unsigned char ack;
 555        struct riscom_board *bp = dev_id;
 556        unsigned long loop = 0;
 557        int handled = 0;
 558
 559        if (!(bp->flags & RC_BOARD_ACTIVE))
 560                return IRQ_NONE;
 561
 562        while ((++loop < 16) && ((status = ~(rc_in(bp, RC_BSR))) &
 563                                 (RC_BSR_TOUT | RC_BSR_TINT |
 564                                  RC_BSR_MINT | RC_BSR_RINT))) {
 565                handled = 1;
 566                if (status & RC_BSR_TOUT)
 567                        printk(KERN_WARNING "rc%d: Got timeout. Hardware "
 568                                            "error?\n", board_No(bp));
 569                else if (status & RC_BSR_RINT) {
 570                        ack = rc_in(bp, RC_ACK_RINT);
 571                        if (ack == (RC_ID | GIVR_IT_RCV))
 572                                rc_receive(bp);
 573                        else if (ack == (RC_ID | GIVR_IT_REXC))
 574                                rc_receive_exc(bp);
 575                        else
 576                                printk(KERN_WARNING "rc%d: Bad receive ack "
 577                                                    "0x%02x.\n",
 578                                       board_No(bp), ack);
 579                } else if (status & RC_BSR_TINT) {
 580                        ack = rc_in(bp, RC_ACK_TINT);
 581                        if (ack == (RC_ID | GIVR_IT_TX))
 582                                rc_transmit(bp);
 583                        else
 584                                printk(KERN_WARNING "rc%d: Bad transmit ack "
 585                                                    "0x%02x.\n",
 586                                       board_No(bp), ack);
 587                } else /* if (status & RC_BSR_MINT) */ {
 588                        ack = rc_in(bp, RC_ACK_MINT);
 589                        if (ack == (RC_ID | GIVR_IT_MODEM))
 590                                rc_check_modem(bp);
 591                        else
 592                                printk(KERN_WARNING "rc%d: Bad modem ack "
 593                                                    "0x%02x.\n",
 594                                       board_No(bp), ack);
 595                }
 596                rc_out(bp, CD180_EOIR, 0);   /* Mark end of interrupt */
 597                rc_out(bp, RC_CTOUT, 0);     /* Clear timeout flag    */
 598        }
 599        return IRQ_RETVAL(handled);
 600}
 601
 602/*
 603 *  Routines for open & close processing.
 604 */
 605
 606/* Called with disabled interrupts */
 607static int rc_setup_board(struct riscom_board *bp)
 608{
 609        int error;
 610
 611        if (bp->flags & RC_BOARD_ACTIVE)
 612                return 0;
 613
 614        error = request_irq(bp->irq, rc_interrupt, IRQF_DISABLED,
 615                            "RISCom/8", bp);
 616        if (error)
 617                return error;
 618
 619        rc_out(bp, RC_CTOUT, 0);                /* Just in case         */
 620        bp->DTR = ~0;
 621        rc_out(bp, RC_DTR, bp->DTR);            /* Drop DTR on all ports */
 622
 623        bp->flags |= RC_BOARD_ACTIVE;
 624
 625        return 0;
 626}
 627
 628/* Called with disabled interrupts */
 629static void rc_shutdown_board(struct riscom_board *bp)
 630{
 631        if (!(bp->flags & RC_BOARD_ACTIVE))
 632                return;
 633
 634        bp->flags &= ~RC_BOARD_ACTIVE;
 635
 636        free_irq(bp->irq, NULL);
 637
 638        bp->DTR = ~0;
 639        rc_out(bp, RC_DTR, bp->DTR);           /* Drop DTR on all ports */
 640
 641}
 642
 643/*
 644 * Setting up port characteristics.
 645 * Must be called with disabled interrupts
 646 */
 647static void rc_change_speed(struct tty_struct *tty, struct riscom_board *bp,
 648                                                struct riscom_port *port)
 649{
 650        unsigned long baud;
 651        long tmp;
 652        unsigned char cor1 = 0, cor3 = 0;
 653        unsigned char mcor1 = 0, mcor2 = 0;
 654
 655        port->IER  = 0;
 656        port->COR2 = 0;
 657        port->MSVR = MSVR_RTS;
 658
 659        baud = tty_get_baud_rate(tty);
 660
 661        /* Select port on the board */
 662        rc_out(bp, CD180_CAR, port_No(port));
 663
 664        if (!baud)  {
 665                /* Drop DTR & exit */
 666                bp->DTR |= (1u << port_No(port));
 667                rc_out(bp, RC_DTR, bp->DTR);
 668                return;
 669        } else  {
 670                /* Set DTR on */
 671                bp->DTR &= ~(1u << port_No(port));
 672                rc_out(bp, RC_DTR, bp->DTR);
 673        }
 674
 675        /*
 676         * Now we must calculate some speed depended things
 677         */
 678
 679        /* Set baud rate for port */
 680        tmp = (((RC_OSCFREQ + baud/2) / baud +
 681                CD180_TPC/2) / CD180_TPC);
 682
 683        rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff);
 684        rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff);
 685        rc_out(bp, CD180_RBPRL, tmp & 0xff);
 686        rc_out(bp, CD180_TBPRL, tmp & 0xff);
 687
 688        baud = (baud + 5) / 10;   /* Estimated CPS */
 689
 690        /* Two timer ticks seems enough to wakeup something like SLIP driver */
 691        tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;
 692        port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
 693                                              SERIAL_XMIT_SIZE - 1 : tmp);
 694
 695        /* Receiver timeout will be transmission time for 1.5 chars */
 696        tmp = (RISCOM_TPS + RISCOM_TPS/2 + baud/2) / baud;
 697        tmp = (tmp > 0xff) ? 0xff : tmp;
 698        rc_out(bp, CD180_RTPR, tmp);
 699
 700        switch (C_CSIZE(tty)) {
 701        case CS5:
 702                cor1 |= COR1_5BITS;
 703                break;
 704        case CS6:
 705                cor1 |= COR1_6BITS;
 706                break;
 707        case CS7:
 708                cor1 |= COR1_7BITS;
 709                break;
 710        case CS8:
 711                cor1 |= COR1_8BITS;
 712                break;
 713        }
 714        if (C_CSTOPB(tty))
 715                cor1 |= COR1_2SB;
 716
 717        cor1 |= COR1_IGNORE;
 718        if (C_PARENB(tty)) {
 719                cor1 |= COR1_NORMPAR;
 720                if (C_PARODD(tty))
 721                        cor1 |= COR1_ODDP;
 722                if (I_INPCK(tty))
 723                        cor1 &= ~COR1_IGNORE;
 724        }
 725        /* Set marking of some errors */
 726        port->mark_mask = RCSR_OE | RCSR_TOUT;
 727        if (I_INPCK(tty))
 728                port->mark_mask |= RCSR_FE | RCSR_PE;
 729        if (I_BRKINT(tty) || I_PARMRK(tty))
 730                port->mark_mask |= RCSR_BREAK;
 731        if (I_IGNPAR(tty))
 732                port->mark_mask &= ~(RCSR_FE | RCSR_PE);
 733        if (I_IGNBRK(tty)) {
 734                port->mark_mask &= ~RCSR_BREAK;
 735                if (I_IGNPAR(tty))
 736                        /* Real raw mode. Ignore all */
 737                        port->mark_mask &= ~RCSR_OE;
 738        }
 739        /* Enable Hardware Flow Control */
 740        if (C_CRTSCTS(tty))  {
 741#ifdef RISCOM_BRAIN_DAMAGED_CTS
 742                port->IER |= IER_DSR | IER_CTS;
 743                mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
 744                mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
 745                tty->hw_stopped = !(rc_in(bp, CD180_MSVR) &
 746                                                (MSVR_CTS|MSVR_DSR));
 747#else
 748                port->COR2 |= COR2_CTSAE;
 749#endif
 750        }
 751        /* Enable Software Flow Control. FIXME: I'm not sure about this */
 752        /* Some people reported that it works, but I still doubt */
 753        if (I_IXON(tty))  {
 754                port->COR2 |= COR2_TXIBE;
 755                cor3 |= (COR3_FCT | COR3_SCDE);
 756                if (I_IXANY(tty))
 757                        port->COR2 |= COR2_IXM;
 758                rc_out(bp, CD180_SCHR1, START_CHAR(tty));
 759                rc_out(bp, CD180_SCHR2, STOP_CHAR(tty));
 760                rc_out(bp, CD180_SCHR3, START_CHAR(tty));
 761                rc_out(bp, CD180_SCHR4, STOP_CHAR(tty));
 762        }
 763        if (!C_CLOCAL(tty))  {
 764                /* Enable CD check */
 765                port->IER |= IER_CD;
 766                mcor1 |= MCOR1_CDZD;
 767                mcor2 |= MCOR2_CDOD;
 768        }
 769
 770        if (C_CREAD(tty))
 771                /* Enable receiver */
 772                port->IER |= IER_RXD;
 773
 774        /* Set input FIFO size (1-8 bytes) */
 775        cor3 |= RISCOM_RXFIFO;
 776        /* Setting up CD180 channel registers */
 777        rc_out(bp, CD180_COR1, cor1);
 778        rc_out(bp, CD180_COR2, port->COR2);
 779        rc_out(bp, CD180_COR3, cor3);
 780        /* Make CD180 know about registers change */
 781        rc_wait_CCR(bp);
 782        rc_out(bp, CD180_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
 783        /* Setting up modem option registers */
 784        rc_out(bp, CD180_MCOR1, mcor1);
 785        rc_out(bp, CD180_MCOR2, mcor2);
 786        /* Enable CD180 transmitter & receiver */
 787        rc_wait_CCR(bp);
 788        rc_out(bp, CD180_CCR, CCR_TXEN | CCR_RXEN);
 789        /* Enable interrupts */
 790        rc_out(bp, CD180_IER, port->IER);
 791        /* And finally set RTS on */
 792        rc_out(bp, CD180_MSVR, port->MSVR);
 793}
 794
 795/* Must be called with interrupts enabled */
 796static int rc_activate_port(struct tty_port *port, struct tty_struct *tty)
 797{
 798        struct riscom_port *rp = container_of(port, struct riscom_port, port);
 799        struct riscom_board *bp = port_Board(rp);
 800        unsigned long flags;
 801
 802        if (tty_port_alloc_xmit_buf(port) < 0)
 803                return -ENOMEM;
 804
 805        spin_lock_irqsave(&riscom_lock, flags);
 806
 807        clear_bit(TTY_IO_ERROR, &tty->flags);
 808        bp->count++;
 809        rp->xmit_cnt = rp->xmit_head = rp->xmit_tail = 0;
 810        rc_change_speed(tty, bp, rp);
 811        spin_unlock_irqrestore(&riscom_lock, flags);
 812        return 0;
 813}
 814
 815/* Must be called with interrupts disabled */
 816static void rc_shutdown_port(struct tty_struct *tty,
 817                        struct riscom_board *bp, struct riscom_port *port)
 818{
 819#ifdef RC_REPORT_OVERRUN
 820        printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n",
 821               board_No(bp), port_No(port), port->overrun);
 822#endif
 823#ifdef RC_REPORT_FIFO
 824        {
 825                int i;
 826
 827                printk(KERN_INFO "rc%d: port %d: FIFO hits [ ",
 828                       board_No(bp), port_No(port));
 829                for (i = 0; i < 10; i++)
 830                        printk("%ld ", port->hits[i]);
 831                printk("].\n");
 832        }
 833#endif
 834        tty_port_free_xmit_buf(&port->port);
 835
 836        /* Select port */
 837        rc_out(bp, CD180_CAR, port_No(port));
 838        /* Reset port */
 839        rc_wait_CCR(bp);
 840        rc_out(bp, CD180_CCR, CCR_SOFTRESET);
 841        /* Disable all interrupts from this port */
 842        port->IER = 0;
 843        rc_out(bp, CD180_IER, port->IER);
 844
 845        set_bit(TTY_IO_ERROR, &tty->flags);
 846
 847        if (--bp->count < 0)  {
 848                printk(KERN_INFO "rc%d: rc_shutdown_port: "
 849                                 "bad board count: %d\n",
 850                       board_No(bp), bp->count);
 851                bp->count = 0;
 852        }
 853        /*
 854         * If this is the last opened port on the board
 855         * shutdown whole board
 856         */
 857        if (!bp->count)
 858                rc_shutdown_board(bp);
 859}
 860
 861static int carrier_raised(struct tty_port *port)
 862{
 863        struct riscom_port *p = container_of(port, struct riscom_port, port);
 864        struct riscom_board *bp = port_Board(p);
 865        unsigned long flags;
 866        int CD;
 867        
 868        spin_lock_irqsave(&riscom_lock, flags);
 869        rc_out(bp, CD180_CAR, port_No(p));
 870        CD = rc_in(bp, CD180_MSVR) & MSVR_CD;
 871        rc_out(bp, CD180_MSVR, MSVR_RTS);
 872        bp->DTR &= ~(1u << port_No(p));
 873        rc_out(bp, RC_DTR, bp->DTR);
 874        spin_unlock_irqrestore(&riscom_lock, flags);
 875        return CD;
 876}
 877
 878static void dtr_rts(struct tty_port *port, int onoff)
 879{
 880        struct riscom_port *p = container_of(port, struct riscom_port, port);
 881        struct riscom_board *bp = port_Board(p);
 882        unsigned long flags;
 883
 884        spin_lock_irqsave(&riscom_lock, flags);
 885        bp->DTR &= ~(1u << port_No(p));
 886        if (onoff == 0)
 887                bp->DTR |= (1u << port_No(p));
 888        rc_out(bp, RC_DTR, bp->DTR);
 889        spin_unlock_irqrestore(&riscom_lock, flags);
 890}
 891
 892static int rc_open(struct tty_struct *tty, struct file *filp)
 893{
 894        int board;
 895        int error;
 896        struct riscom_port *port;
 897        struct riscom_board *bp;
 898
 899        board = RC_BOARD(tty->index);
 900        if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT))
 901                return -ENODEV;
 902
 903        bp = &rc_board[board];
 904        port = rc_port + board * RC_NPORT + RC_PORT(tty->index);
 905        if (rc_paranoia_check(port, tty->name, "rc_open"))
 906                return -ENODEV;
 907
 908        error = rc_setup_board(bp);
 909        if (error)
 910                return error;
 911
 912        tty->driver_data = port;
 913        return tty_port_open(&port->port, tty, filp);
 914}
 915
 916static void rc_flush_buffer(struct tty_struct *tty)
 917{
 918        struct riscom_port *port = tty->driver_data;
 919        unsigned long flags;
 920
 921        if (rc_paranoia_check(port, tty->name, "rc_flush_buffer"))
 922                return;
 923
 924        spin_lock_irqsave(&riscom_lock, flags);
 925        port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
 926        spin_unlock_irqrestore(&riscom_lock, flags);
 927
 928        tty_wakeup(tty);
 929}
 930
 931static void rc_close_port(struct tty_port *port)
 932{
 933        unsigned long flags;
 934        struct riscom_port *rp = container_of(port, struct riscom_port, port);
 935        struct riscom_board *bp = port_Board(rp);
 936        unsigned long timeout;
 937        
 938        /*
 939         * At this point we stop accepting input.  To do this, we
 940         * disable the receive line status interrupts, and tell the
 941         * interrupt driver to stop checking the data ready bit in the
 942         * line status register.
 943         */
 944
 945        spin_lock_irqsave(&riscom_lock, flags);
 946        rp->IER &= ~IER_RXD;
 947
 948        rp->IER &= ~IER_TXRDY;
 949        rp->IER |= IER_TXEMPTY;
 950        rc_out(bp, CD180_CAR, port_No(rp));
 951        rc_out(bp, CD180_IER, rp->IER);
 952        /*
 953         * Before we drop DTR, make sure the UART transmitter
 954         * has completely drained; this is especially
 955         * important if there is a transmit FIFO!
 956         */
 957        timeout = jiffies + HZ;
 958        while (rp->IER & IER_TXEMPTY) {
 959                spin_unlock_irqrestore(&riscom_lock, flags);
 960                msleep_interruptible(jiffies_to_msecs(rp->timeout));
 961                spin_lock_irqsave(&riscom_lock, flags);
 962                if (time_after(jiffies, timeout))
 963                        break;
 964        }
 965        rc_shutdown_port(port->tty, bp, rp);
 966        spin_unlock_irqrestore(&riscom_lock, flags);
 967}
 968
 969static void rc_close(struct tty_struct *tty, struct file *filp)
 970{
 971        struct riscom_port *port = tty->driver_data;
 972
 973        if (!port || rc_paranoia_check(port, tty->name, "close"))
 974                return;
 975        tty_port_close(&port->port, tty, filp);
 976}
 977
 978static int rc_write(struct tty_struct *tty,
 979                    const unsigned char *buf, int count)
 980{
 981        struct riscom_port *port = tty->driver_data;
 982        struct riscom_board *bp;
 983        int c, total = 0;
 984        unsigned long flags;
 985
 986        if (rc_paranoia_check(port, tty->name, "rc_write"))
 987                return 0;
 988
 989        bp = port_Board(port);
 990
 991        while (1) {
 992                spin_lock_irqsave(&riscom_lock, flags);
 993
 994                c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
 995                                          SERIAL_XMIT_SIZE - port->xmit_head));
 996                if (c <= 0)
 997                        break;  /* lock continues to be held */
 998
 999                memcpy(port->port.xmit_buf + port->xmit_head, buf, c);
1000                port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1001                port->xmit_cnt += c;
1002
1003                spin_unlock_irqrestore(&riscom_lock, flags);
1004
1005                buf += c;
1006                count -= c;
1007                total += c;
1008        }
1009
1010        if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1011            !(port->IER & IER_TXRDY)) {
1012                port->IER |= IER_TXRDY;
1013                rc_out(bp, CD180_CAR, port_No(port));
1014                rc_out(bp, CD180_IER, port->IER);
1015        }
1016
1017        spin_unlock_irqrestore(&riscom_lock, flags);
1018
1019        return total;
1020}
1021
1022static int rc_put_char(struct tty_struct *tty, unsigned char ch)
1023{
1024        struct riscom_port *port = tty->driver_data;
1025        unsigned long flags;
1026        int ret = 0;
1027
1028        if (rc_paranoia_check(port, tty->name, "rc_put_char"))
1029                return 0;
1030
1031        spin_lock_irqsave(&riscom_lock, flags);
1032
1033        if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
1034                goto out;
1035
1036        port->port.xmit_buf[port->xmit_head++] = ch;
1037        port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1038        port->xmit_cnt++;
1039        ret = 1;
1040
1041out:
1042        spin_unlock_irqrestore(&riscom_lock, flags);
1043        return ret;
1044}
1045
1046static void rc_flush_chars(struct tty_struct *tty)
1047{
1048        struct riscom_port *port = tty->driver_data;
1049        unsigned long flags;
1050
1051        if (rc_paranoia_check(port, tty->name, "rc_flush_chars"))
1052                return;
1053
1054        if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped)
1055                return;
1056
1057        spin_lock_irqsave(&riscom_lock, flags);
1058
1059        port->IER |= IER_TXRDY;
1060        rc_out(port_Board(port), CD180_CAR, port_No(port));
1061        rc_out(port_Board(port), CD180_IER, port->IER);
1062
1063        spin_unlock_irqrestore(&riscom_lock, flags);
1064}
1065
1066static int rc_write_room(struct tty_struct *tty)
1067{
1068        struct riscom_port *port = tty->driver_data;
1069        int     ret;
1070
1071        if (rc_paranoia_check(port, tty->name, "rc_write_room"))
1072                return 0;
1073
1074        ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1075        if (ret < 0)
1076                ret = 0;
1077        return ret;
1078}
1079
1080static int rc_chars_in_buffer(struct tty_struct *tty)
1081{
1082        struct riscom_port *port = tty->driver_data;
1083
1084        if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer"))
1085                return 0;
1086
1087        return port->xmit_cnt;
1088}
1089
1090static int rc_tiocmget(struct tty_struct *tty, struct file *file)
1091{
1092        struct riscom_port *port = tty->driver_data;
1093        struct riscom_board *bp;
1094        unsigned char status;
1095        unsigned int result;
1096        unsigned long flags;
1097
1098        if (rc_paranoia_check(port, tty->name, __func__))
1099                return -ENODEV;
1100
1101        bp = port_Board(port);
1102
1103        spin_lock_irqsave(&riscom_lock, flags);
1104
1105        rc_out(bp, CD180_CAR, port_No(port));
1106        status = rc_in(bp, CD180_MSVR);
1107        result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG;
1108
1109        spin_unlock_irqrestore(&riscom_lock, flags);
1110
1111        result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0)
1112                | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1113                | ((status & MSVR_CD)  ? TIOCM_CAR : 0)
1114                | ((status & MSVR_DSR) ? TIOCM_DSR : 0)
1115                | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1116        return result;
1117}
1118
1119static int rc_tiocmset(struct tty_struct *tty, struct file *file,
1120                       unsigned int set, unsigned int clear)
1121{
1122        struct riscom_port *port = tty->driver_data;
1123        unsigned long flags;
1124        struct riscom_board *bp;
1125
1126        if (rc_paranoia_check(port, tty->name, __func__))
1127                return -ENODEV;
1128
1129        bp = port_Board(port);
1130
1131        spin_lock_irqsave(&riscom_lock, flags);
1132
1133        if (set & TIOCM_RTS)
1134                port->MSVR |= MSVR_RTS;
1135        if (set & TIOCM_DTR)
1136                bp->DTR &= ~(1u << port_No(port));
1137
1138        if (clear & TIOCM_RTS)
1139                port->MSVR &= ~MSVR_RTS;
1140        if (clear & TIOCM_DTR)
1141                bp->DTR |= (1u << port_No(port));
1142
1143        rc_out(bp, CD180_CAR, port_No(port));
1144        rc_out(bp, CD180_MSVR, port->MSVR);
1145        rc_out(bp, RC_DTR, bp->DTR);
1146
1147        spin_unlock_irqrestore(&riscom_lock, flags);
1148
1149        return 0;
1150}
1151
1152static int rc_send_break(struct tty_struct *tty, int length)
1153{
1154        struct riscom_port *port = tty->driver_data;
1155        struct riscom_board *bp = port_Board(port);
1156        unsigned long flags;
1157
1158        if (length == 0 || length == -1)
1159                return -EOPNOTSUPP;
1160
1161        spin_lock_irqsave(&riscom_lock, flags);
1162
1163        port->break_length = RISCOM_TPS / HZ * length;
1164        port->COR2 |= COR2_ETC;
1165        port->IER  |= IER_TXRDY;
1166        rc_out(bp, CD180_CAR, port_No(port));
1167        rc_out(bp, CD180_COR2, port->COR2);
1168        rc_out(bp, CD180_IER, port->IER);
1169        rc_wait_CCR(bp);
1170        rc_out(bp, CD180_CCR, CCR_CORCHG2);
1171        rc_wait_CCR(bp);
1172
1173        spin_unlock_irqrestore(&riscom_lock, flags);
1174        return 0;
1175}
1176
1177static int rc_set_serial_info(struct tty_struct *tty, struct riscom_port *port,
1178                                     struct serial_struct __user *newinfo)
1179{
1180        struct serial_struct tmp;
1181        struct riscom_board *bp = port_Board(port);
1182        int change_speed;
1183
1184        if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
1185                return -EFAULT;
1186
1187        change_speed = ((port->port.flags & ASYNC_SPD_MASK) !=
1188                        (tmp.flags & ASYNC_SPD_MASK));
1189
1190        if (!capable(CAP_SYS_ADMIN)) {
1191                if ((tmp.close_delay != port->port.close_delay) ||
1192                    (tmp.closing_wait != port->port.closing_wait) ||
1193                    ((tmp.flags & ~ASYNC_USR_MASK) !=
1194                     (port->port.flags & ~ASYNC_USR_MASK)))
1195                        return -EPERM;
1196                port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1197                               (tmp.flags & ASYNC_USR_MASK));
1198        } else  {
1199                port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1200                               (tmp.flags & ASYNC_FLAGS));
1201                port->port.close_delay = tmp.close_delay;
1202                port->port.closing_wait = tmp.closing_wait;
1203        }
1204        if (change_speed)  {
1205                unsigned long flags;
1206
1207                spin_lock_irqsave(&riscom_lock, flags);
1208                rc_change_speed(tty, bp, port);
1209                spin_unlock_irqrestore(&riscom_lock, flags);
1210        }
1211        return 0;
1212}
1213
1214static int rc_get_serial_info(struct riscom_port *port,
1215                                     struct serial_struct __user *retinfo)
1216{
1217        struct serial_struct tmp;
1218        struct riscom_board *bp = port_Board(port);
1219
1220        memset(&tmp, 0, sizeof(tmp));
1221        tmp.type = PORT_CIRRUS;
1222        tmp.line = port - rc_port;
1223        tmp.port = bp->base;
1224        tmp.irq  = bp->irq;
1225        tmp.flags = port->port.flags;
1226        tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC;
1227        tmp.close_delay = port->port.close_delay * HZ/100;
1228        tmp.closing_wait = port->port.closing_wait * HZ/100;
1229        tmp.xmit_fifo_size = CD180_NFIFO;
1230        return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0;
1231}
1232
1233static int rc_ioctl(struct tty_struct *tty, struct file *filp,
1234                    unsigned int cmd, unsigned long arg)
1235{
1236        struct riscom_port *port = tty->driver_data;
1237        void __user *argp = (void __user *)arg;
1238        int retval;
1239
1240        if (rc_paranoia_check(port, tty->name, "rc_ioctl"))
1241                return -ENODEV;
1242
1243        switch (cmd) {
1244        case TIOCGSERIAL:
1245                lock_kernel();
1246                retval = rc_get_serial_info(port, argp);
1247                unlock_kernel();
1248                break;
1249        case TIOCSSERIAL:
1250                lock_kernel();
1251                retval = rc_set_serial_info(tty, port, argp);
1252                unlock_kernel();
1253                break;
1254        default:
1255                retval = -ENOIOCTLCMD;
1256        }
1257        return retval;
1258}
1259
1260static void rc_throttle(struct tty_struct *tty)
1261{
1262        struct riscom_port *port = tty->driver_data;
1263        struct riscom_board *bp;
1264        unsigned long flags;
1265
1266        if (rc_paranoia_check(port, tty->name, "rc_throttle"))
1267                return;
1268        bp = port_Board(port);
1269
1270        spin_lock_irqsave(&riscom_lock, flags);
1271        port->MSVR &= ~MSVR_RTS;
1272        rc_out(bp, CD180_CAR, port_No(port));
1273        if (I_IXOFF(tty)) {
1274                rc_wait_CCR(bp);
1275                rc_out(bp, CD180_CCR, CCR_SSCH2);
1276                rc_wait_CCR(bp);
1277        }
1278        rc_out(bp, CD180_MSVR, port->MSVR);
1279        spin_unlock_irqrestore(&riscom_lock, flags);
1280}
1281
1282static void rc_unthrottle(struct tty_struct *tty)
1283{
1284        struct riscom_port *port = tty->driver_data;
1285        struct riscom_board *bp;
1286        unsigned long flags;
1287
1288        if (rc_paranoia_check(port, tty->name, "rc_unthrottle"))
1289                return;
1290        bp = port_Board(port);
1291
1292        spin_lock_irqsave(&riscom_lock, flags);
1293        port->MSVR |= MSVR_RTS;
1294        rc_out(bp, CD180_CAR, port_No(port));
1295        if (I_IXOFF(tty))  {
1296                rc_wait_CCR(bp);
1297                rc_out(bp, CD180_CCR, CCR_SSCH1);
1298                rc_wait_CCR(bp);
1299        }
1300        rc_out(bp, CD180_MSVR, port->MSVR);
1301        spin_unlock_irqrestore(&riscom_lock, flags);
1302}
1303
1304static void rc_stop(struct tty_struct *tty)
1305{
1306        struct riscom_port *port = tty->driver_data;
1307        struct riscom_board *bp;
1308        unsigned long flags;
1309
1310        if (rc_paranoia_check(port, tty->name, "rc_stop"))
1311                return;
1312
1313        bp = port_Board(port);
1314
1315        spin_lock_irqsave(&riscom_lock, flags);
1316        port->IER &= ~IER_TXRDY;
1317        rc_out(bp, CD180_CAR, port_No(port));
1318        rc_out(bp, CD180_IER, port->IER);
1319        spin_unlock_irqrestore(&riscom_lock, flags);
1320}
1321
1322static void rc_start(struct tty_struct *tty)
1323{
1324        struct riscom_port *port = tty->driver_data;
1325        struct riscom_board *bp;
1326        unsigned long flags;
1327
1328        if (rc_paranoia_check(port, tty->name, "rc_start"))
1329                return;
1330
1331        bp = port_Board(port);
1332
1333        spin_lock_irqsave(&riscom_lock, flags);
1334
1335        if (port->xmit_cnt && port->port.xmit_buf && !(port->IER & IER_TXRDY)) {
1336                port->IER |= IER_TXRDY;
1337                rc_out(bp, CD180_CAR, port_No(port));
1338                rc_out(bp, CD180_IER, port->IER);
1339        }
1340        spin_unlock_irqrestore(&riscom_lock, flags);
1341}
1342
1343static void rc_hangup(struct tty_struct *tty)
1344{
1345        struct riscom_port *port = tty->driver_data;
1346
1347        if (rc_paranoia_check(port, tty->name, "rc_hangup"))
1348                return;
1349
1350        tty_port_hangup(&port->port);
1351}
1352
1353static void rc_set_termios(struct tty_struct *tty,
1354                                        struct ktermios *old_termios)
1355{
1356        struct riscom_port *port = tty->driver_data;
1357        unsigned long flags;
1358
1359        if (rc_paranoia_check(port, tty->name, "rc_set_termios"))
1360                return;
1361
1362        spin_lock_irqsave(&riscom_lock, flags);
1363        rc_change_speed(tty, port_Board(port), port);
1364        spin_unlock_irqrestore(&riscom_lock, flags);
1365
1366        if ((old_termios->c_cflag & CRTSCTS) &&
1367            !(tty->termios->c_cflag & CRTSCTS)) {
1368                tty->hw_stopped = 0;
1369                rc_start(tty);
1370        }
1371}
1372
1373static const struct tty_operations riscom_ops = {
1374        .open  = rc_open,
1375        .close = rc_close,
1376        .write = rc_write,
1377        .put_char = rc_put_char,
1378        .flush_chars = rc_flush_chars,
1379        .write_room = rc_write_room,
1380        .chars_in_buffer = rc_chars_in_buffer,
1381        .flush_buffer = rc_flush_buffer,
1382        .ioctl = rc_ioctl,
1383        .throttle = rc_throttle,
1384        .unthrottle = rc_unthrottle,
1385        .set_termios = rc_set_termios,
1386        .stop = rc_stop,
1387        .start = rc_start,
1388        .hangup = rc_hangup,
1389        .tiocmget = rc_tiocmget,
1390        .tiocmset = rc_tiocmset,
1391        .break_ctl = rc_send_break,
1392};
1393
1394static const struct tty_port_operations riscom_port_ops = {
1395        .carrier_raised = carrier_raised,
1396        .dtr_rts = dtr_rts,
1397        .shutdown = rc_close_port,
1398        .activate = rc_activate_port,
1399};
1400
1401
1402static int __init rc_init_drivers(void)
1403{
1404        int error;
1405        int i;
1406
1407        riscom_driver = alloc_tty_driver(RC_NBOARD * RC_NPORT);
1408        if (!riscom_driver)
1409                return -ENOMEM;
1410
1411        riscom_driver->owner = THIS_MODULE;
1412        riscom_driver->name = "ttyL";
1413        riscom_driver->major = RISCOM8_NORMAL_MAJOR;
1414        riscom_driver->type = TTY_DRIVER_TYPE_SERIAL;
1415        riscom_driver->subtype = SERIAL_TYPE_NORMAL;
1416        riscom_driver->init_termios = tty_std_termios;
1417        riscom_driver->init_termios.c_cflag =
1418                B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1419        riscom_driver->init_termios.c_ispeed = 9600;
1420        riscom_driver->init_termios.c_ospeed = 9600;
1421        riscom_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_HARDWARE_BREAK;
1422        tty_set_operations(riscom_driver, &riscom_ops);
1423        error = tty_register_driver(riscom_driver);
1424        if (error != 0) {
1425                put_tty_driver(riscom_driver);
1426                printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, "
1427                                "error = %d\n", error);
1428                return 1;
1429        }
1430        memset(rc_port, 0, sizeof(rc_port));
1431        for (i = 0; i < RC_NPORT * RC_NBOARD; i++)  {
1432                tty_port_init(&rc_port[i].port);
1433                rc_port[i].port.ops = &riscom_port_ops;
1434                rc_port[i].magic = RISCOM8_MAGIC;
1435        }
1436        return 0;
1437}
1438
1439static void rc_release_drivers(void)
1440{
1441        tty_unregister_driver(riscom_driver);
1442        put_tty_driver(riscom_driver);
1443}
1444
1445#ifndef MODULE
1446/*
1447 * Called at boot time.
1448 *
1449 * You can specify IO base for up to RC_NBOARD cards,
1450 * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt.
1451 * Note that there will be no probing at default
1452 * addresses in this case.
1453 *
1454 */
1455static int __init riscom8_setup(char *str)
1456{
1457        int ints[RC_NBOARD];
1458        int i;
1459
1460        str = get_options(str, ARRAY_SIZE(ints), ints);
1461
1462        for (i = 0; i < RC_NBOARD; i++) {
1463                if (i < ints[0])
1464                        rc_board[i].base = ints[i+1];
1465                else
1466                        rc_board[i].base = 0;
1467        }
1468        return 1;
1469}
1470
1471__setup("riscom8=", riscom8_setup);
1472#endif
1473
1474static char banner[] __initdata =
1475        KERN_INFO "rc: SDL RISCom/8 card driver v1.1, (c) D.Gorodchanin "
1476                  "1994-1996.\n";
1477static char no_boards_msg[] __initdata =
1478        KERN_INFO "rc: No RISCom/8 boards detected.\n";
1479
1480/*
1481 * This routine must be called by kernel at boot time
1482 */
1483static int __init riscom8_init(void)
1484{
1485        int i;
1486        int found = 0;
1487
1488        printk(banner);
1489
1490        if (rc_init_drivers())
1491                return -EIO;
1492
1493        for (i = 0; i < RC_NBOARD; i++)
1494                if (rc_board[i].base && !rc_probe(&rc_board[i]))
1495                        found++;
1496        if (!found)  {
1497                rc_release_drivers();
1498                printk(no_boards_msg);
1499                return -EIO;
1500        }
1501        return 0;
1502}
1503
1504#ifdef MODULE
1505static int iobase;
1506static int iobase1;
1507static int iobase2;
1508static int iobase3;
1509module_param(iobase, int, 0);
1510module_param(iobase1, int, 0);
1511module_param(iobase2, int, 0);
1512module_param(iobase3, int, 0);
1513
1514MODULE_LICENSE("GPL");
1515MODULE_ALIAS_CHARDEV_MAJOR(RISCOM8_NORMAL_MAJOR);
1516#endif /* MODULE */
1517
1518/*
1519 * You can setup up to 4 boards (current value of RC_NBOARD)
1520 * by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter.
1521 *
1522 */
1523static int __init riscom8_init_module(void)
1524{
1525#ifdef MODULE
1526        int i;
1527
1528        if (iobase || iobase1 || iobase2 || iobase3) {
1529                for (i = 0; i < RC_NBOARD; i++)
1530                        rc_board[i].base = 0;
1531        }
1532
1533        if (iobase)
1534                rc_board[0].base = iobase;
1535        if (iobase1)
1536                rc_board[1].base = iobase1;
1537        if (iobase2)
1538                rc_board[2].base = iobase2;
1539        if (iobase3)
1540                rc_board[3].base = iobase3;
1541#endif /* MODULE */
1542
1543        return riscom8_init();
1544}
1545
1546static void __exit riscom8_exit_module(void)
1547{
1548        int i;
1549
1550        rc_release_drivers();
1551        for (i = 0; i < RC_NBOARD; i++)
1552                if (rc_board[i].flags & RC_BOARD_PRESENT)
1553                        rc_release_io_range(&rc_board[i]);
1554
1555}
1556
1557module_init(riscom8_init_module);
1558module_exit(riscom8_exit_module);
1559
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.