linux/drivers/tty/rocket.c
<<
>>
Prefs
   1/*
   2 * RocketPort device driver for Linux
   3 *
   4 * Written by Theodore Ts'o, 1995, 1996, 1997, 1998, 1999, 2000.
   5 * 
   6 * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2003 by Comtrol, Inc.
   7 * 
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of the
  11 * License, or (at your option) any later version.
  12 * 
  13 * This program is distributed in the hope that it will be useful, but
  14 * WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16 * General Public License for more details.
  17 * 
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21 */
  22
  23/*
  24 * Kernel Synchronization:
  25 *
  26 * This driver has 2 kernel control paths - exception handlers (calls into the driver
  27 * from user mode) and the timer bottom half (tasklet).  This is a polled driver, interrupts
  28 * are not used.
  29 *
  30 * Critical data: 
  31 * -  rp_table[], accessed through passed "info" pointers, is a global (static) array of 
  32 *    serial port state information and the xmit_buf circular buffer.  Protected by 
  33 *    a per port spinlock.
  34 * -  xmit_flags[], an array of ints indexed by line (port) number, indicating that there
  35 *    is data to be transmitted.  Protected by atomic bit operations.
  36 * -  rp_num_ports, int indicating number of open ports, protected by atomic operations.
  37 * 
  38 * rp_write() and rp_write_char() functions use a per port semaphore to protect against
  39 * simultaneous access to the same port by more than one process.
  40 */
  41
  42/****** Defines ******/
  43#define ROCKET_PARANOIA_CHECK
  44#define ROCKET_DISABLE_SIMUSAGE
  45
  46#undef ROCKET_SOFT_FLOW
  47#undef ROCKET_DEBUG_OPEN
  48#undef ROCKET_DEBUG_INTR
  49#undef ROCKET_DEBUG_WRITE
  50#undef ROCKET_DEBUG_FLOW
  51#undef ROCKET_DEBUG_THROTTLE
  52#undef ROCKET_DEBUG_WAIT_UNTIL_SENT
  53#undef ROCKET_DEBUG_RECEIVE
  54#undef ROCKET_DEBUG_HANGUP
  55#undef REV_PCI_ORDER
  56#undef ROCKET_DEBUG_IO
  57
  58#define POLL_PERIOD (HZ/100)    /*  Polling period .01 seconds (10ms) */
  59
  60/****** Kernel includes ******/
  61
  62#include <linux/module.h>
  63#include <linux/errno.h>
  64#include <linux/major.h>
  65#include <linux/kernel.h>
  66#include <linux/signal.h>
  67#include <linux/slab.h>
  68#include <linux/mm.h>
  69#include <linux/sched.h>
  70#include <linux/timer.h>
  71#include <linux/interrupt.h>
  72#include <linux/tty.h>
  73#include <linux/tty_driver.h>
  74#include <linux/tty_flip.h>
  75#include <linux/serial.h>
  76#include <linux/string.h>
  77#include <linux/fcntl.h>
  78#include <linux/ptrace.h>
  79#include <linux/mutex.h>
  80#include <linux/ioport.h>
  81#include <linux/delay.h>
  82#include <linux/completion.h>
  83#include <linux/wait.h>
  84#include <linux/pci.h>
  85#include <linux/uaccess.h>
  86#include <linux/atomic.h>
  87#include <asm/unaligned.h>
  88#include <linux/bitops.h>
  89#include <linux/spinlock.h>
  90#include <linux/init.h>
  91
  92/****** RocketPort includes ******/
  93
  94#include "rocket_int.h"
  95#include "rocket.h"
  96
  97#define ROCKET_VERSION "2.09"
  98#define ROCKET_DATE "12-June-2003"
  99
 100/****** RocketPort Local Variables ******/
 101
 102static void rp_do_poll(unsigned long dummy);
 103
 104static struct tty_driver *rocket_driver;
 105
 106static struct rocket_version driver_version = { 
 107        ROCKET_VERSION, ROCKET_DATE
 108};
 109
 110static struct r_port *rp_table[MAX_RP_PORTS];          /*  The main repository of serial port state information. */
 111static unsigned int xmit_flags[NUM_BOARDS];            /*  Bit significant, indicates port had data to transmit. */
 112                                                       /*  eg.  Bit 0 indicates port 0 has xmit data, ...        */
 113static atomic_t rp_num_ports_open;                     /*  Number of serial ports open                           */
 114static DEFINE_TIMER(rocket_timer, rp_do_poll, 0, 0);
 115
 116static unsigned long board1;                           /* ISA addresses, retrieved from rocketport.conf          */
 117static unsigned long board2;
 118static unsigned long board3;
 119static unsigned long board4;
 120static unsigned long controller;
 121static bool support_low_speed;
 122static unsigned long modem1;
 123static unsigned long modem2;
 124static unsigned long modem3;
 125static unsigned long modem4;
 126static unsigned long pc104_1[8];
 127static unsigned long pc104_2[8];
 128static unsigned long pc104_3[8];
 129static unsigned long pc104_4[8];
 130static unsigned long *pc104[4] = { pc104_1, pc104_2, pc104_3, pc104_4 };
 131
 132static int rp_baud_base[NUM_BOARDS];                   /*  Board config info (Someday make a per-board structure)  */
 133static unsigned long rcktpt_io_addr[NUM_BOARDS];
 134static int rcktpt_type[NUM_BOARDS];
 135static int is_PCI[NUM_BOARDS];
 136static rocketModel_t rocketModel[NUM_BOARDS];
 137static int max_board;
 138static const struct tty_port_operations rocket_port_ops;
 139
 140/*
 141 * The following arrays define the interrupt bits corresponding to each AIOP.
 142 * These bits are different between the ISA and regular PCI boards and the
 143 * Universal PCI boards.
 144 */
 145
 146static Word_t aiop_intr_bits[AIOP_CTL_SIZE] = {
 147        AIOP_INTR_BIT_0,
 148        AIOP_INTR_BIT_1,
 149        AIOP_INTR_BIT_2,
 150        AIOP_INTR_BIT_3
 151};
 152
 153static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = {
 154        UPCI_AIOP_INTR_BIT_0,
 155        UPCI_AIOP_INTR_BIT_1,
 156        UPCI_AIOP_INTR_BIT_2,
 157        UPCI_AIOP_INTR_BIT_3
 158};
 159
 160static Byte_t RData[RDATASIZE] = {
 161        0x00, 0x09, 0xf6, 0x82,
 162        0x02, 0x09, 0x86, 0xfb,
 163        0x04, 0x09, 0x00, 0x0a,
 164        0x06, 0x09, 0x01, 0x0a,
 165        0x08, 0x09, 0x8a, 0x13,
 166        0x0a, 0x09, 0xc5, 0x11,
 167        0x0c, 0x09, 0x86, 0x85,
 168        0x0e, 0x09, 0x20, 0x0a,
 169        0x10, 0x09, 0x21, 0x0a,
 170        0x12, 0x09, 0x41, 0xff,
 171        0x14, 0x09, 0x82, 0x00,
 172        0x16, 0x09, 0x82, 0x7b,
 173        0x18, 0x09, 0x8a, 0x7d,
 174        0x1a, 0x09, 0x88, 0x81,
 175        0x1c, 0x09, 0x86, 0x7a,
 176        0x1e, 0x09, 0x84, 0x81,
 177        0x20, 0x09, 0x82, 0x7c,
 178        0x22, 0x09, 0x0a, 0x0a
 179};
 180
 181static Byte_t RRegData[RREGDATASIZE] = {
 182        0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */
 183        0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */
 184        0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */
 185        0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */
 186        0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */
 187        0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */
 188        0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */
 189        0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */
 190        0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */
 191        0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */
 192        0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */
 193        0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */
 194        0x22, 0x09, 0x0a, 0x0a  /* 30: Rx FIFO Enable */
 195};
 196
 197static CONTROLLER_T sController[CTL_SIZE] = {
 198        {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
 199         {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
 200        {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
 201         {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
 202        {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
 203         {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
 204        {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
 205         {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
 206};
 207
 208static Byte_t sBitMapClrTbl[8] = {
 209        0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
 210};
 211
 212static Byte_t sBitMapSetTbl[8] = {
 213        0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
 214};
 215
 216static int sClockPrescale = 0x14;
 217
 218/*
 219 *  Line number is the ttySIx number (x), the Minor number.  We 
 220 *  assign them sequentially, starting at zero.  The following 
 221 *  array keeps track of the line number assigned to a given board/aiop/channel.
 222 */
 223static unsigned char lineNumbers[MAX_RP_PORTS];
 224static unsigned long nextLineNumber;
 225
 226/*****  RocketPort Static Prototypes   *********/
 227static int __init init_ISA(int i);
 228static void rp_wait_until_sent(struct tty_struct *tty, int timeout);
 229static void rp_flush_buffer(struct tty_struct *tty);
 230static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model);
 231static unsigned char GetLineNumber(int ctrl, int aiop, int ch);
 232static unsigned char SetLineNumber(int ctrl, int aiop, int ch);
 233static void rp_start(struct tty_struct *tty);
 234static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
 235                     int ChanNum);
 236static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
 237static void sFlushRxFIFO(CHANNEL_T * ChP);
 238static void sFlushTxFIFO(CHANNEL_T * ChP);
 239static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
 240static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
 241static void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
 242static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
 243static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
 244static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
 245                              ByteIO_t * AiopIOList, int AiopIOListSize,
 246                              WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
 247                              int PeriodicOnly, int altChanRingIndicator,
 248                              int UPCIRingInd);
 249static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
 250                           ByteIO_t * AiopIOList, int AiopIOListSize,
 251                           int IRQNum, Byte_t Frequency, int PeriodicOnly);
 252static int sReadAiopID(ByteIO_t io);
 253static int sReadAiopNumChan(WordIO_t io);
 254
 255MODULE_AUTHOR("Theodore Ts'o");
 256MODULE_DESCRIPTION("Comtrol RocketPort driver");
 257module_param(board1, ulong, 0);
 258MODULE_PARM_DESC(board1, "I/O port for (ISA) board #1");
 259module_param(board2, ulong, 0);
 260MODULE_PARM_DESC(board2, "I/O port for (ISA) board #2");
 261module_param(board3, ulong, 0);
 262MODULE_PARM_DESC(board3, "I/O port for (ISA) board #3");
 263module_param(board4, ulong, 0);
 264MODULE_PARM_DESC(board4, "I/O port for (ISA) board #4");
 265module_param(controller, ulong, 0);
 266MODULE_PARM_DESC(controller, "I/O port for (ISA) rocketport controller");
 267module_param(support_low_speed, bool, 0);
 268MODULE_PARM_DESC(support_low_speed, "1 means support 50 baud, 0 means support 460400 baud");
 269module_param(modem1, ulong, 0);
 270MODULE_PARM_DESC(modem1, "1 means (ISA) board #1 is a RocketModem");
 271module_param(modem2, ulong, 0);
 272MODULE_PARM_DESC(modem2, "1 means (ISA) board #2 is a RocketModem");
 273module_param(modem3, ulong, 0);
 274MODULE_PARM_DESC(modem3, "1 means (ISA) board #3 is a RocketModem");
 275module_param(modem4, ulong, 0);
 276MODULE_PARM_DESC(modem4, "1 means (ISA) board #4 is a RocketModem");
 277module_param_array(pc104_1, ulong, NULL, 0);
 278MODULE_PARM_DESC(pc104_1, "set interface types for ISA(PC104) board #1 (e.g. pc104_1=232,232,485,485,...");
 279module_param_array(pc104_2, ulong, NULL, 0);
 280MODULE_PARM_DESC(pc104_2, "set interface types for ISA(PC104) board #2 (e.g. pc104_2=232,232,485,485,...");
 281module_param_array(pc104_3, ulong, NULL, 0);
 282MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc104_3=232,232,485,485,...");
 283module_param_array(pc104_4, ulong, NULL, 0);
 284MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,...");
 285
 286static int rp_init(void);
 287static void rp_cleanup_module(void);
 288
 289module_init(rp_init);
 290module_exit(rp_cleanup_module);
 291
 292
 293MODULE_LICENSE("Dual BSD/GPL");
 294
 295/*************************************************************************/
 296/*                     Module code starts here                           */
 297
 298static inline int rocket_paranoia_check(struct r_port *info,
 299                                        const char *routine)
 300{
 301#ifdef ROCKET_PARANOIA_CHECK
 302        if (!info)
 303                return 1;
 304        if (info->magic != RPORT_MAGIC) {
 305                printk(KERN_WARNING "Warning: bad magic number for rocketport "
 306                                "struct in %s\n", routine);
 307                return 1;
 308        }
 309#endif
 310        return 0;
 311}
 312
 313
 314/*  Serial port receive data function.  Called (from timer poll) when an AIOPIC signals 
 315 *  that receive data is present on a serial port.  Pulls data from FIFO, moves it into the 
 316 *  tty layer.  
 317 */
 318static void rp_do_receive(struct r_port *info, CHANNEL_t *cp,
 319                unsigned int ChanStatus)
 320{
 321        unsigned int CharNStat;
 322        int ToRecv, wRecv, space;
 323        unsigned char *cbuf;
 324
 325        ToRecv = sGetRxCnt(cp);
 326#ifdef ROCKET_DEBUG_INTR
 327        printk(KERN_INFO "rp_do_receive(%d)...\n", ToRecv);
 328#endif
 329        if (ToRecv == 0)
 330                return;
 331
 332        /*
 333         * if status indicates there are errored characters in the
 334         * FIFO, then enter status mode (a word in FIFO holds
 335         * character and status).
 336         */
 337        if (ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) {
 338                if (!(ChanStatus & STATMODE)) {
 339#ifdef ROCKET_DEBUG_RECEIVE
 340                        printk(KERN_INFO "Entering STATMODE...\n");
 341#endif
 342                        ChanStatus |= STATMODE;
 343                        sEnRxStatusMode(cp);
 344                }
 345        }
 346
 347        /* 
 348         * if we previously entered status mode, then read down the
 349         * FIFO one word at a time, pulling apart the character and
 350         * the status.  Update error counters depending on status
 351         */
 352        if (ChanStatus & STATMODE) {
 353#ifdef ROCKET_DEBUG_RECEIVE
 354                printk(KERN_INFO "Ignore %x, read %x...\n",
 355                        info->ignore_status_mask, info->read_status_mask);
 356#endif
 357                while (ToRecv) {
 358                        char flag;
 359
 360                        CharNStat = sInW(sGetTxRxDataIO(cp));
 361#ifdef ROCKET_DEBUG_RECEIVE
 362                        printk(KERN_INFO "%x...\n", CharNStat);
 363#endif
 364                        if (CharNStat & STMBREAKH)
 365                                CharNStat &= ~(STMFRAMEH | STMPARITYH);
 366                        if (CharNStat & info->ignore_status_mask) {
 367                                ToRecv--;
 368                                continue;
 369                        }
 370                        CharNStat &= info->read_status_mask;
 371                        if (CharNStat & STMBREAKH)
 372                                flag = TTY_BREAK;
 373                        else if (CharNStat & STMPARITYH)
 374                                flag = TTY_PARITY;
 375                        else if (CharNStat & STMFRAMEH)
 376                                flag = TTY_FRAME;
 377                        else if (CharNStat & STMRCVROVRH)
 378                                flag = TTY_OVERRUN;
 379                        else
 380                                flag = TTY_NORMAL;
 381                        tty_insert_flip_char(&info->port, CharNStat & 0xff,
 382                                        flag);
 383                        ToRecv--;
 384                }
 385
 386                /*
 387                 * after we've emptied the FIFO in status mode, turn
 388                 * status mode back off
 389                 */
 390                if (sGetRxCnt(cp) == 0) {
 391#ifdef ROCKET_DEBUG_RECEIVE
 392                        printk(KERN_INFO "Status mode off.\n");
 393#endif
 394                        sDisRxStatusMode(cp);
 395                }
 396        } else {
 397                /*
 398                 * we aren't in status mode, so read down the FIFO two
 399                 * characters at time by doing repeated word IO
 400                 * transfer.
 401                 */
 402                space = tty_prepare_flip_string(&info->port, &cbuf, ToRecv);
 403                if (space < ToRecv) {
 404#ifdef ROCKET_DEBUG_RECEIVE
 405                        printk(KERN_INFO "rp_do_receive:insufficient space ToRecv=%d space=%d\n", ToRecv, space);
 406#endif
 407                        if (space <= 0)
 408                                return;
 409                        ToRecv = space;
 410                }
 411                wRecv = ToRecv >> 1;
 412                if (wRecv)
 413                        sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv);
 414                if (ToRecv & 1)
 415                        cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp));
 416        }
 417        /*  Push the data up to the tty layer */
 418        tty_flip_buffer_push(&info->port);
 419}
 420
 421/*
 422 *  Serial port transmit data function.  Called from the timer polling loop as a 
 423 *  result of a bit set in xmit_flags[], indicating data (from the tty layer) is ready
 424 *  to be sent out the serial port.  Data is buffered in rp_table[line].xmit_buf, it is 
 425 *  moved to the port's xmit FIFO.  *info is critical data, protected by spinlocks.
 426 */
 427static void rp_do_transmit(struct r_port *info)
 428{
 429        int c;
 430        CHANNEL_t *cp = &info->channel;
 431        struct tty_struct *tty;
 432        unsigned long flags;
 433
 434#ifdef ROCKET_DEBUG_INTR
 435        printk(KERN_DEBUG "%s\n", __func__);
 436#endif
 437        if (!info)
 438                return;
 439        tty = tty_port_tty_get(&info->port);
 440
 441        if (tty == NULL) {
 442                printk(KERN_WARNING "rp: WARNING %s called with tty==NULL\n", __func__);
 443                clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
 444                return;
 445        }
 446
 447        spin_lock_irqsave(&info->slock, flags);
 448        info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
 449
 450        /*  Loop sending data to FIFO until done or FIFO full */
 451        while (1) {
 452                if (tty->stopped || tty->hw_stopped)
 453                        break;
 454                c = min(info->xmit_fifo_room, info->xmit_cnt);
 455                c = min(c, XMIT_BUF_SIZE - info->xmit_tail);
 456                if (c <= 0 || info->xmit_fifo_room <= 0)
 457                        break;
 458                sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) (info->xmit_buf + info->xmit_tail), c / 2);
 459                if (c & 1)
 460                        sOutB(sGetTxRxDataIO(cp), info->xmit_buf[info->xmit_tail + c - 1]);
 461                info->xmit_tail += c;
 462                info->xmit_tail &= XMIT_BUF_SIZE - 1;
 463                info->xmit_cnt -= c;
 464                info->xmit_fifo_room -= c;
 465#ifdef ROCKET_DEBUG_INTR
 466                printk(KERN_INFO "tx %d chars...\n", c);
 467#endif
 468        }
 469
 470        if (info->xmit_cnt == 0)
 471                clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
 472
 473        if (info->xmit_cnt < WAKEUP_CHARS) {
 474                tty_wakeup(tty);
 475#ifdef ROCKETPORT_HAVE_POLL_WAIT
 476                wake_up_interruptible(&tty->poll_wait);
 477#endif
 478        }
 479
 480        spin_unlock_irqrestore(&info->slock, flags);
 481        tty_kref_put(tty);
 482
 483#ifdef ROCKET_DEBUG_INTR
 484        printk(KERN_DEBUG "(%d,%d,%d,%d)...\n", info->xmit_cnt, info->xmit_head,
 485               info->xmit_tail, info->xmit_fifo_room);
 486#endif
 487}
 488
 489/*
 490 *  Called when a serial port signals it has read data in it's RX FIFO.
 491 *  It checks what interrupts are pending and services them, including
 492 *  receiving serial data.  
 493 */
 494static void rp_handle_port(struct r_port *info)
 495{
 496        CHANNEL_t *cp;
 497        unsigned int IntMask, ChanStatus;
 498
 499        if (!info)
 500                return;
 501
 502        if ((info->port.flags & ASYNC_INITIALIZED) == 0) {
 503                printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
 504                                "info->flags & NOT_INIT\n");
 505                return;
 506        }
 507
 508        cp = &info->channel;
 509
 510        IntMask = sGetChanIntID(cp) & info->intmask;
 511#ifdef ROCKET_DEBUG_INTR
 512        printk(KERN_INFO "rp_interrupt %02x...\n", IntMask);
 513#endif
 514        ChanStatus = sGetChanStatus(cp);
 515        if (IntMask & RXF_TRIG) {       /* Rx FIFO trigger level */
 516                rp_do_receive(info, cp, ChanStatus);
 517        }
 518        if (IntMask & DELTA_CD) {       /* CD change  */
 519#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_INTR) || defined(ROCKET_DEBUG_HANGUP))
 520                printk(KERN_INFO "ttyR%d CD now %s...\n", info->line,
 521                       (ChanStatus & CD_ACT) ? "on" : "off");
 522#endif
 523                if (!(ChanStatus & CD_ACT) && info->cd_status) {
 524                        struct tty_struct *tty;
 525#ifdef ROCKET_DEBUG_HANGUP
 526                        printk(KERN_INFO "CD drop, calling hangup.\n");
 527#endif
 528                        tty = tty_port_tty_get(&info->port);
 529                        if (tty) {
 530                                tty_hangup(tty);
 531                                tty_kref_put(tty);
 532                        }
 533                }
 534                info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0;
 535                wake_up_interruptible(&info->port.open_wait);
 536        }
 537#ifdef ROCKET_DEBUG_INTR
 538        if (IntMask & DELTA_CTS) {      /* CTS change */
 539                printk(KERN_INFO "CTS change...\n");
 540        }
 541        if (IntMask & DELTA_DSR) {      /* DSR change */
 542                printk(KERN_INFO "DSR change...\n");
 543        }
 544#endif
 545}
 546
 547/*
 548 *  The top level polling routine.  Repeats every 1/100 HZ (10ms).
 549 */
 550static void rp_do_poll(unsigned long dummy)
 551{
 552        CONTROLLER_t *ctlp;
 553        int ctrl, aiop, ch, line;
 554        unsigned int xmitmask, i;
 555        unsigned int CtlMask;
 556        unsigned char AiopMask;
 557        Word_t bit;
 558
 559        /*  Walk through all the boards (ctrl's) */
 560        for (ctrl = 0; ctrl < max_board; ctrl++) {
 561                if (rcktpt_io_addr[ctrl] <= 0)
 562                        continue;
 563
 564                /*  Get a ptr to the board's control struct */
 565                ctlp = sCtlNumToCtlPtr(ctrl);
 566
 567                /*  Get the interrupt status from the board */
 568#ifdef CONFIG_PCI
 569                if (ctlp->BusType == isPCI)
 570                        CtlMask = sPCIGetControllerIntStatus(ctlp);
 571                else
 572#endif
 573                        CtlMask = sGetControllerIntStatus(ctlp);
 574
 575                /*  Check if any AIOP read bits are set */
 576                for (aiop = 0; CtlMask; aiop++) {
 577                        bit = ctlp->AiopIntrBits[aiop];
 578                        if (CtlMask & bit) {
 579                                CtlMask &= ~bit;
 580                                AiopMask = sGetAiopIntStatus(ctlp, aiop);
 581
 582                                /*  Check if any port read bits are set */
 583                                for (ch = 0; AiopMask;  AiopMask >>= 1, ch++) {
 584                                        if (AiopMask & 1) {
 585
 586                                                /*  Get the line number (/dev/ttyRx number). */
 587                                                /*  Read the data from the port. */
 588                                                line = GetLineNumber(ctrl, aiop, ch);
 589                                                rp_handle_port(rp_table[line]);
 590                                        }
 591                                }
 592                        }
 593                }
 594
 595                xmitmask = xmit_flags[ctrl];
 596
 597                /*
 598                 *  xmit_flags contains bit-significant flags, indicating there is data
 599                 *  to xmit on the port. Bit 0 is port 0 on this board, bit 1 is port 
 600                 *  1, ... (32 total possible).  The variable i has the aiop and ch 
 601                 *  numbers encoded in it (port 0-7 are aiop0, 8-15 are aiop1, etc).
 602                 */
 603                if (xmitmask) {
 604                        for (i = 0; i < rocketModel[ctrl].numPorts; i++) {
 605                                if (xmitmask & (1 << i)) {
 606                                        aiop = (i & 0x18) >> 3;
 607                                        ch = i & 0x07;
 608                                        line = GetLineNumber(ctrl, aiop, ch);
 609                                        rp_do_transmit(rp_table[line]);
 610                                }
 611                        }
 612                }
 613        }
 614
 615        /*
 616         * Reset the timer so we get called at the next clock tick (10ms).
 617         */
 618        if (atomic_read(&rp_num_ports_open))
 619                mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
 620}
 621
 622/*
 623 *  Initializes the r_port structure for a port, as well as enabling the port on 
 624 *  the board.  
 625 *  Inputs:  board, aiop, chan numbers
 626 */
 627static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
 628{
 629        unsigned rocketMode;
 630        struct r_port *info;
 631        int line;
 632        CONTROLLER_T *ctlp;
 633
 634        /*  Get the next available line number */
 635        line = SetLineNumber(board, aiop, chan);
 636
 637        ctlp = sCtlNumToCtlPtr(board);
 638
 639        /*  Get a r_port struct for the port, fill it in and save it globally, indexed by line number */
 640        info = kzalloc(sizeof (struct r_port), GFP_KERNEL);
 641        if (!info) {
 642                printk(KERN_ERR "Couldn't allocate info struct for line #%d\n",
 643                                line);
 644                return;
 645        }
 646
 647        info->magic = RPORT_MAGIC;
 648        info->line = line;
 649        info->ctlp = ctlp;
 650        info->board = board;
 651        info->aiop = aiop;
 652        info->chan = chan;
 653        tty_port_init(&info->port);
 654        info->port.ops = &rocket_port_ops;
 655        init_completion(&info->close_wait);
 656        info->flags &= ~ROCKET_MODE_MASK;
 657        switch (pc104[board][line]) {
 658        case 422:
 659                info->flags |= ROCKET_MODE_RS422;
 660                break;
 661        case 485:
 662                info->flags |= ROCKET_MODE_RS485;
 663                break;
 664        case 232:
 665        default:
 666                info->flags |= ROCKET_MODE_RS232;
 667                break;
 668        }
 669
 670        info->intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR;
 671        if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) {
 672                printk(KERN_ERR "RocketPort sInitChan(%d, %d, %d) failed!\n",
 673                                board, aiop, chan);
 674                tty_port_destroy(&info->port);
 675                kfree(info);
 676                return;
 677        }
 678
 679        rocketMode = info->flags & ROCKET_MODE_MASK;
 680
 681        if ((info->flags & ROCKET_RTS_TOGGLE) || (rocketMode == ROCKET_MODE_RS485))
 682                sEnRTSToggle(&info->channel);
 683        else
 684                sDisRTSToggle(&info->channel);
 685
 686        if (ctlp->boardType == ROCKET_TYPE_PC104) {
 687                switch (rocketMode) {
 688                case ROCKET_MODE_RS485:
 689                        sSetInterfaceMode(&info->channel, InterfaceModeRS485);
 690                        break;
 691                case ROCKET_MODE_RS422:
 692                        sSetInterfaceMode(&info->channel, InterfaceModeRS422);
 693                        break;
 694                case ROCKET_MODE_RS232:
 695                default:
 696                        if (info->flags & ROCKET_RTS_TOGGLE)
 697                                sSetInterfaceMode(&info->channel, InterfaceModeRS232T);
 698                        else
 699                                sSetInterfaceMode(&info->channel, InterfaceModeRS232);
 700                        break;
 701                }
 702        }
 703        spin_lock_init(&info->slock);
 704        mutex_init(&info->write_mtx);
 705        rp_table[line] = info;
 706        tty_port_register_device(&info->port, rocket_driver, line,
 707                        pci_dev ? &pci_dev->dev : NULL);
 708}
 709
 710/*
 711 *  Configures a rocketport port according to its termio settings.  Called from 
 712 *  user mode into the driver (exception handler).  *info CD manipulation is spinlock protected.
 713 */
 714static void configure_r_port(struct tty_struct *tty, struct r_port *info,
 715                             struct ktermios *old_termios)
 716{
 717        unsigned cflag;
 718        unsigned long flags;
 719        unsigned rocketMode;
 720        int bits, baud, divisor;
 721        CHANNEL_t *cp;
 722        struct ktermios *t = &tty->termios;
 723
 724        cp = &info->channel;
 725        cflag = t->c_cflag;
 726
 727        /* Byte size and parity */
 728        if ((cflag & CSIZE) == CS8) {
 729                sSetData8(cp);
 730                bits = 10;
 731        } else {
 732                sSetData7(cp);
 733                bits = 9;
 734        }
 735        if (cflag & CSTOPB) {
 736                sSetStop2(cp);
 737                bits++;
 738        } else {
 739                sSetStop1(cp);
 740        }
 741
 742        if (cflag & PARENB) {
 743                sEnParity(cp);
 744                bits++;
 745                if (cflag & PARODD) {
 746                        sSetOddParity(cp);
 747                } else {
 748                        sSetEvenParity(cp);
 749                }
 750        } else {
 751                sDisParity(cp);
 752        }
 753
 754        /* baud rate */
 755        baud = tty_get_baud_rate(tty);
 756        if (!baud)
 757                baud = 9600;
 758        divisor = ((rp_baud_base[info->board] + (baud >> 1)) / baud) - 1;
 759        if ((divisor >= 8192 || divisor < 0) && old_termios) {
 760                baud = tty_termios_baud_rate(old_termios);
 761                if (!baud)
 762                        baud = 9600;
 763                divisor = (rp_baud_base[info->board] / baud) - 1;
 764        }
 765        if (divisor >= 8192 || divisor < 0) {
 766                baud = 9600;
 767                divisor = (rp_baud_base[info->board] / baud) - 1;
 768        }
 769        info->cps = baud / bits;
 770        sSetBaud(cp, divisor);
 771
 772        /* FIXME: Should really back compute a baud rate from the divisor */
 773        tty_encode_baud_rate(tty, baud, baud);
 774
 775        if (cflag & CRTSCTS) {
 776                info->intmask |= DELTA_CTS;
 777                sEnCTSFlowCtl(cp);
 778        } else {
 779                info->intmask &= ~DELTA_CTS;
 780                sDisCTSFlowCtl(cp);
 781        }
 782        if (cflag & CLOCAL) {
 783                info->intmask &= ~DELTA_CD;
 784        } else {
 785                spin_lock_irqsave(&info->slock, flags);
 786                if (sGetChanStatus(cp) & CD_ACT)
 787                        info->cd_status = 1;
 788                else
 789                        info->cd_status = 0;
 790                info->intmask |= DELTA_CD;
 791                spin_unlock_irqrestore(&info->slock, flags);
 792        }
 793
 794        /*
 795         * Handle software flow control in the board
 796         */
 797#ifdef ROCKET_SOFT_FLOW
 798        if (I_IXON(tty)) {
 799                sEnTxSoftFlowCtl(cp);
 800                if (I_IXANY(tty)) {
 801                        sEnIXANY(cp);
 802                } else {
 803                        sDisIXANY(cp);
 804                }
 805                sSetTxXONChar(cp, START_CHAR(tty));
 806                sSetTxXOFFChar(cp, STOP_CHAR(tty));
 807        } else {
 808                sDisTxSoftFlowCtl(cp);
 809                sDisIXANY(cp);
 810                sClrTxXOFF(cp);
 811        }
 812#endif
 813
 814        /*
 815         * Set up ignore/read mask words
 816         */
 817        info->read_status_mask = STMRCVROVRH | 0xFF;
 818        if (I_INPCK(tty))
 819                info->read_status_mask |= STMFRAMEH | STMPARITYH;
 820        if (I_BRKINT(tty) || I_PARMRK(tty))
 821                info->read_status_mask |= STMBREAKH;
 822
 823        /*
 824         * Characters to ignore
 825         */
 826        info->ignore_status_mask = 0;
 827        if (I_IGNPAR(tty))
 828                info->ignore_status_mask |= STMFRAMEH | STMPARITYH;
 829        if (I_IGNBRK(tty)) {
 830                info->ignore_status_mask |= STMBREAKH;
 831                /*
 832                 * If we're ignoring parity and break indicators,
 833                 * ignore overruns too.  (For real raw support).
 834                 */
 835                if (I_IGNPAR(tty))
 836                        info->ignore_status_mask |= STMRCVROVRH;
 837        }
 838
 839        rocketMode = info->flags & ROCKET_MODE_MASK;
 840
 841        if ((info->flags & ROCKET_RTS_TOGGLE)
 842            || (rocketMode == ROCKET_MODE_RS485))
 843                sEnRTSToggle(cp);
 844        else
 845                sDisRTSToggle(cp);
 846
 847        sSetRTS(&info->channel);
 848
 849        if (cp->CtlP->boardType == ROCKET_TYPE_PC104) {
 850                switch (rocketMode) {
 851                case ROCKET_MODE_RS485:
 852                        sSetInterfaceMode(cp, InterfaceModeRS485);
 853                        break;
 854                case ROCKET_MODE_RS422:
 855                        sSetInterfaceMode(cp, InterfaceModeRS422);
 856                        break;
 857                case ROCKET_MODE_RS232:
 858                default:
 859                        if (info->flags & ROCKET_RTS_TOGGLE)
 860                                sSetInterfaceMode(cp, InterfaceModeRS232T);
 861                        else
 862                                sSetInterfaceMode(cp, InterfaceModeRS232);
 863                        break;
 864                }
 865        }
 866}
 867
 868static int carrier_raised(struct tty_port *port)
 869{
 870        struct r_port *info = container_of(port, struct r_port, port);
 871        return (sGetChanStatusLo(&info->channel) & CD_ACT) ? 1 : 0;
 872}
 873
 874static void dtr_rts(struct tty_port *port, int on)
 875{
 876        struct r_port *info = container_of(port, struct r_port, port);
 877        if (on) {
 878                sSetDTR(&info->channel);
 879                sSetRTS(&info->channel);
 880        } else {
 881                sClrDTR(&info->channel);
 882                sClrRTS(&info->channel);
 883        }
 884}
 885
 886/*
 887 *  Exception handler that opens a serial port.  Creates xmit_buf storage, fills in 
 888 *  port's r_port struct.  Initializes the port hardware.  
 889 */
 890static int rp_open(struct tty_struct *tty, struct file *filp)
 891{
 892        struct r_port *info;
 893        struct tty_port *port;
 894        int retval;
 895        CHANNEL_t *cp;
 896        unsigned long page;
 897
 898        info = rp_table[tty->index];
 899        if (info == NULL)
 900                return -ENXIO;
 901        port = &info->port;
 902        
 903        page = __get_free_page(GFP_KERNEL);
 904        if (!page)
 905                return -ENOMEM;
 906
 907        if (port->flags & ASYNC_CLOSING) {
 908                retval = wait_for_completion_interruptible(&info->close_wait);
 909                free_page(page);
 910                if (retval)
 911                        return retval;
 912                return ((port->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
 913        }
 914
 915        /*
 916         * We must not sleep from here until the port is marked fully in use.
 917         */
 918        if (info->xmit_buf)
 919                free_page(page);
 920        else
 921                info->xmit_buf = (unsigned char *) page;
 922
 923        tty->driver_data = info;
 924        tty_port_tty_set(port, tty);
 925
 926        if (port->count++ == 0) {
 927                atomic_inc(&rp_num_ports_open);
 928
 929#ifdef ROCKET_DEBUG_OPEN
 930                printk(KERN_INFO "rocket mod++ = %d...\n",
 931                                atomic_read(&rp_num_ports_open));
 932#endif
 933        }
 934#ifdef ROCKET_DEBUG_OPEN
 935        printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->port.count);
 936#endif
 937
 938        /*
 939         * Info->count is now 1; so it's safe to sleep now.
 940         */
 941        if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
 942                cp = &info->channel;
 943                sSetRxTrigger(cp, TRIG_1);
 944                if (sGetChanStatus(cp) & CD_ACT)
 945                        info->cd_status = 1;
 946                else
 947                        info->cd_status = 0;
 948                sDisRxStatusMode(cp);
 949                sFlushRxFIFO(cp);
 950                sFlushTxFIFO(cp);
 951
 952                sEnInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
 953                sSetRxTrigger(cp, TRIG_1);
 954
 955                sGetChanStatus(cp);
 956                sDisRxStatusMode(cp);
 957                sClrTxXOFF(cp);
 958
 959                sDisCTSFlowCtl(cp);
 960                sDisTxSoftFlowCtl(cp);
 961
 962                sEnRxFIFO(cp);
 963                sEnTransmit(cp);
 964
 965                set_bit(ASYNCB_INITIALIZED, &info->port.flags);
 966
 967                /*
 968                 * Set up the tty->alt_speed kludge
 969                 */
 970                if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
 971                        tty->alt_speed = 57600;
 972                if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
 973                        tty->alt_speed = 115200;
 974                if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
 975                        tty->alt_speed = 230400;
 976                if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
 977                        tty->alt_speed = 460800;
 978
 979                configure_r_port(tty, info, NULL);
 980                if (tty->termios.c_cflag & CBAUD) {
 981                        sSetDTR(cp);
 982                        sSetRTS(cp);
 983                }
 984        }
 985        /*  Starts (or resets) the maint polling loop */
 986        mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
 987
 988        retval = tty_port_block_til_ready(port, tty, filp);
 989        if (retval) {
 990#ifdef ROCKET_DEBUG_OPEN
 991                printk(KERN_INFO "rp_open returning after block_til_ready with %d\n", retval);
 992#endif
 993                return retval;
 994        }
 995        return 0;
 996}
 997
 998/*
 999 *  Exception handler that closes a serial port. info->port.count is considered critical.
1000 */
1001static void rp_close(struct tty_struct *tty, struct file *filp)
1002{
1003        struct r_port *info = tty->driver_data;
1004        struct tty_port *port = &info->port;
1005        int timeout;
1006        CHANNEL_t *cp;
1007        
1008        if (rocket_paranoia_check(info, "rp_close"))
1009                return;
1010
1011#ifdef ROCKET_DEBUG_OPEN
1012        printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->port.count);
1013#endif
1014
1015        if (tty_port_close_start(port, tty, filp) == 0)
1016                return;
1017
1018        mutex_lock(&port->mutex);
1019        cp = &info->channel;
1020        /*
1021         * Before we drop DTR, make sure the UART transmitter
1022         * has completely drained; this is especially
1023         * important if there is a transmit FIFO!
1024         */
1025        timeout = (sGetTxCnt(cp) + 1) * HZ / info->cps;
1026        if (timeout == 0)
1027                timeout = 1;
1028        rp_wait_until_sent(tty, timeout);
1029        clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1030
1031        sDisTransmit(cp);
1032        sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
1033        sDisCTSFlowCtl(cp);
1034        sDisTxSoftFlowCtl(cp);
1035        sClrTxXOFF(cp);
1036        sFlushRxFIFO(cp);
1037        sFlushTxFIFO(cp);
1038        sClrRTS(cp);
1039        if (C_HUPCL(tty))
1040                sClrDTR(cp);
1041
1042        rp_flush_buffer(tty);
1043                
1044        tty_ldisc_flush(tty);
1045
1046        clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1047
1048        /* We can't yet use tty_port_close_end as the buffer handling in this
1049           driver is a bit different to the usual */
1050
1051        if (port->blocked_open) {
1052                if (port->close_delay) {
1053                        msleep_interruptible(jiffies_to_msecs(port->close_delay));
1054                }
1055                wake_up_interruptible(&port->open_wait);
1056        } else {
1057                if (info->xmit_buf) {
1058                        free_page((unsigned long) info->xmit_buf);
1059                        info->xmit_buf = NULL;
1060                }
1061        }
1062        spin_lock_irq(&port->lock);
1063        info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE);
1064        tty->closing = 0;
1065        spin_unlock_irq(&port->lock);
1066        mutex_unlock(&port->mutex);
1067        tty_port_tty_set(port, NULL);
1068
1069        wake_up_interruptible(&port->close_wait);
1070        complete_all(&info->close_wait);
1071        atomic_dec(&rp_num_ports_open);
1072
1073#ifdef ROCKET_DEBUG_OPEN
1074        printk(KERN_INFO "rocket mod-- = %d...\n",
1075                        atomic_read(&rp_num_ports_open));
1076        printk(KERN_INFO "rp_close ttyR%d complete shutdown\n", info->line);
1077#endif
1078
1079}
1080
1081static void rp_set_termios(struct tty_struct *tty,
1082                           struct ktermios *old_termios)
1083{
1084        struct r_port *info = tty->driver_data;
1085        CHANNEL_t *cp;
1086        unsigned cflag;
1087
1088        if (rocket_paranoia_check(info, "rp_set_termios"))
1089                return;
1090
1091        cflag = tty->termios.c_cflag;
1092
1093        /*
1094         * This driver doesn't support CS5 or CS6
1095         */
1096        if (((cflag & CSIZE) == CS5) || ((cflag & CSIZE) == CS6))
1097                tty->termios.c_cflag =
1098                    ((cflag & ~CSIZE) | (old_termios->c_cflag & CSIZE));
1099        /* Or CMSPAR */
1100        tty->termios.c_cflag &= ~CMSPAR;
1101
1102        configure_r_port(tty, info, old_termios);
1103
1104        cp = &info->channel;
1105
1106        /* Handle transition to B0 status */
1107        if ((old_termios->c_cflag & CBAUD) && !(tty->termios.c_cflag & CBAUD)) {
1108                sClrDTR(cp);
1109                sClrRTS(cp);
1110        }
1111
1112        /* Handle transition away from B0 status */
1113        if (!(old_termios->c_cflag & CBAUD) && (tty->termios.c_cflag & CBAUD)) {
1114                if (!tty->hw_stopped || !(tty->termios.c_cflag & CRTSCTS))
1115                        sSetRTS(cp);
1116                sSetDTR(cp);
1117        }
1118
1119        if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios.c_cflag & CRTSCTS)) {
1120                tty->hw_stopped = 0;
1121                rp_start(tty);
1122        }
1123}
1124
1125static int rp_break(struct tty_struct *tty, int break_state)
1126{
1127        struct r_port *info = tty->driver_data;
1128        unsigned long flags;
1129
1130        if (rocket_paranoia_check(info, "rp_break"))
1131                return -EINVAL;
1132
1133        spin_lock_irqsave(&info->slock, flags);
1134        if (break_state == -1)
1135                sSendBreak(&info->channel);
1136        else
1137                sClrBreak(&info->channel);
1138        spin_unlock_irqrestore(&info->slock, flags);
1139        return 0;
1140}
1141
1142/*
1143 * sGetChanRI used to be a macro in rocket_int.h. When the functionality for
1144 * the UPCI boards was added, it was decided to make this a function because
1145 * the macro was getting too complicated. All cases except the first one
1146 * (UPCIRingInd) are taken directly from the original macro.
1147 */
1148static int sGetChanRI(CHANNEL_T * ChP)
1149{
1150        CONTROLLER_t *CtlP = ChP->CtlP;
1151        int ChanNum = ChP->ChanNum;
1152        int RingInd = 0;
1153
1154        if (CtlP->UPCIRingInd)
1155                RingInd = !(sInB(CtlP->UPCIRingInd) & sBitMapSetTbl[ChanNum]);
1156        else if (CtlP->AltChanRingIndicator)
1157                RingInd = sInB((ByteIO_t) (ChP->ChanStat + 8)) & DSR_ACT;
1158        else if (CtlP->boardType == ROCKET_TYPE_PC104)
1159                RingInd = !(sInB(CtlP->AiopIO[3]) & sBitMapSetTbl[ChanNum]);
1160
1161        return RingInd;
1162}
1163
1164/********************************************************************************************/
1165/*  Here are the routines used by rp_ioctl.  These are all called from exception handlers.  */
1166
1167/*
1168 *  Returns the state of the serial modem control lines.  These next 2 functions 
1169 *  are the way kernel versions > 2.5 handle modem control lines rather than IOCTLs.
1170 */
1171static int rp_tiocmget(struct tty_struct *tty)
1172{
1173        struct r_port *info = tty->driver_data;
1174        unsigned int control, result, ChanStatus;
1175
1176        ChanStatus = sGetChanStatusLo(&info->channel);
1177        control = info->channel.TxControl[3];
1178        result = ((control & SET_RTS) ? TIOCM_RTS : 0) | 
1179                ((control & SET_DTR) ?  TIOCM_DTR : 0) |
1180                ((ChanStatus & CD_ACT) ? TIOCM_CAR : 0) |
1181                (sGetChanRI(&info->channel) ? TIOCM_RNG : 0) |
1182                ((ChanStatus & DSR_ACT) ? TIOCM_DSR : 0) |
1183                ((ChanStatus & CTS_ACT) ? TIOCM_CTS : 0);
1184
1185        return result;
1186}
1187
1188/* 
1189 *  Sets the modem control lines
1190 */
1191static int rp_tiocmset(struct tty_struct *tty,
1192                                unsigned int set, unsigned int clear)
1193{
1194        struct r_port *info = tty->driver_data;
1195
1196        if (set & TIOCM_RTS)
1197                info->channel.TxControl[3] |= SET_RTS;
1198        if (set & TIOCM_DTR)
1199                info->channel.TxControl[3] |= SET_DTR;
1200        if (clear & TIOCM_RTS)
1201                info->channel.TxControl[3] &= ~SET_RTS;
1202        if (clear & TIOCM_DTR)
1203                info->channel.TxControl[3] &= ~SET_DTR;
1204
1205        out32(info->channel.IndexAddr, info->channel.TxControl);
1206        return 0;
1207}
1208
1209static int get_config(struct r_port *info, struct rocket_config __user *retinfo)
1210{
1211        struct rocket_config tmp;
1212
1213        if (!retinfo)
1214                return -EFAULT;
1215        memset(&tmp, 0, sizeof (tmp));
1216        mutex_lock(&info->port.mutex);
1217        tmp.line = info->line;
1218        tmp.flags = info->flags;
1219        tmp.close_delay = info->port.close_delay;
1220        tmp.closing_wait = info->port.closing_wait;
1221        tmp.port = rcktpt_io_addr[(info->line >> 5) & 3];
1222        mutex_unlock(&info->port.mutex);
1223
1224        if (copy_to_user(retinfo, &tmp, sizeof (*retinfo)))
1225                return -EFAULT;
1226        return 0;
1227}
1228
1229static int set_config(struct tty_struct *tty, struct r_port *info,
1230                                        struct rocket_config __user *new_info)
1231{
1232        struct rocket_config new_serial;
1233
1234        if (copy_from_user(&new_serial, new_info, sizeof (new_serial)))
1235                return -EFAULT;
1236
1237        mutex_lock(&info->port.mutex);
1238        if (!capable(CAP_SYS_ADMIN))
1239        {
1240                if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK)) {
1241                        mutex_unlock(&info->port.mutex);
1242                        return -EPERM;
1243                }
1244                info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK));
1245                configure_r_port(tty, info, NULL);
1246                mutex_unlock(&info->port.mutex);
1247                return 0;
1248        }
1249
1250        info->flags = ((info->flags & ~ROCKET_FLAGS) | (new_serial.flags & ROCKET_FLAGS));
1251        info->port.close_delay = new_serial.close_delay;
1252        info->port.closing_wait = new_serial.closing_wait;
1253
1254        if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
1255                tty->alt_speed = 57600;
1256        if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
1257                tty->alt_speed = 115200;
1258        if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
1259                tty->alt_speed = 230400;
1260        if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
1261                tty->alt_speed = 460800;
1262        mutex_unlock(&info->port.mutex);
1263
1264        configure_r_port(tty, info, NULL);
1265        return 0;
1266}
1267
1268/*
1269 *  This function fills in a rocket_ports struct with information
1270 *  about what boards/ports are in the system.  This info is passed
1271 *  to user space.  See setrocket.c where the info is used to create
1272 *  the /dev/ttyRx ports.
1273 */
1274static int get_ports(struct r_port *info, struct rocket_ports __user *retports)
1275{
1276        struct rocket_ports tmp;
1277        int board;
1278
1279        if (!retports)
1280                return -EFAULT;
1281        memset(&tmp, 0, sizeof (tmp));
1282        tmp.tty_major = rocket_driver->major;
1283
1284        for (board = 0; board < 4; board++) {
1285                tmp.rocketModel[board].model = rocketModel[board].model;
1286                strcpy(tmp.rocketModel[board].modelString, rocketModel[board].modelString);
1287                tmp.rocketModel[board].numPorts = rocketModel[board].numPorts;
1288                tmp.rocketModel[board].loadrm2 = rocketModel[board].loadrm2;
1289                tmp.rocketModel[board].startingPortNumber = rocketModel[board].startingPortNumber;
1290        }
1291        if (copy_to_user(retports, &tmp, sizeof (*retports)))
1292                return -EFAULT;
1293        return 0;
1294}
1295
1296static int reset_rm2(struct r_port *info, void __user *arg)
1297{
1298        int reset;
1299
1300        if (!capable(CAP_SYS_ADMIN))
1301                return -EPERM;
1302
1303        if (copy_from_user(&reset, arg, sizeof (int)))
1304                return -EFAULT;
1305        if (reset)
1306                reset = 1;
1307
1308        if (rcktpt_type[info->board] != ROCKET_TYPE_MODEMII &&
1309            rcktpt_type[info->board] != ROCKET_TYPE_MODEMIII)
1310                return -EINVAL;
1311
1312        if (info->ctlp->BusType == isISA)
1313                sModemReset(info->ctlp, info->chan, reset);
1314        else
1315                sPCIModemReset(info->ctlp, info->chan, reset);
1316
1317        return 0;
1318}
1319
1320static int get_version(struct r_port *info, struct rocket_version __user *retvers)
1321{
1322        if (copy_to_user(retvers, &driver_version, sizeof (*retvers)))
1323                return -EFAULT;
1324        return 0;
1325}
1326
1327/*  IOCTL call handler into the driver */
1328static int rp_ioctl(struct tty_struct *tty,
1329                    unsigned int cmd, unsigned long arg)
1330{
1331        struct r_port *info = tty->driver_data;
1332        void __user *argp = (void __user *)arg;
1333        int ret = 0;
1334
1335        if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl"))
1336                return -ENXIO;
1337
1338        switch (cmd) {
1339        case RCKP_GET_STRUCT:
1340                if (copy_to_user(argp, info, sizeof (struct r_port)))
1341                        ret = -EFAULT;
1342                break;
1343        case RCKP_GET_CONFIG:
1344                ret = get_config(info, argp);
1345                break;
1346        case RCKP_SET_CONFIG:
1347                ret = set_config(tty, info, argp);
1348                break;
1349        case RCKP_GET_PORTS:
1350                ret = get_ports(info, argp);
1351                break;
1352        case RCKP_RESET_RM2:
1353                ret = reset_rm2(info, argp);
1354                break;
1355        case RCKP_GET_VERSION:
1356                ret = get_version(info, argp);
1357                break;
1358        default:
1359                ret = -ENOIOCTLCMD;
1360        }
1361        return ret;
1362}
1363
1364static void rp_send_xchar(struct tty_struct *tty, char ch)
1365{
1366        struct r_port *info = tty->driver_data;
1367        CHANNEL_t *cp;
1368
1369        if (rocket_paranoia_check(info, "rp_send_xchar"))
1370                return;
1371
1372        cp = &info->channel;
1373        if (sGetTxCnt(cp))
1374                sWriteTxPrioByte(cp, ch);
1375        else
1376                sWriteTxByte(sGetTxRxDataIO(cp), ch);
1377}
1378
1379static void rp_throttle(struct tty_struct *tty)
1380{
1381        struct r_port *info = tty->driver_data;
1382
1383#ifdef ROCKET_DEBUG_THROTTLE
1384        printk(KERN_INFO "throttle %s: %d....\n", tty->name,
1385               tty->ldisc.chars_in_buffer(tty));
1386#endif
1387
1388        if (rocket_paranoia_check(info, "rp_throttle"))
1389                return;
1390
1391        if (I_IXOFF(tty))
1392                rp_send_xchar(tty, STOP_CHAR(tty));
1393
1394        sClrRTS(&info->channel);
1395}
1396
1397static void rp_unthrottle(struct tty_struct *tty)
1398{
1399        struct r_port *info = tty->driver_data;
1400#ifdef ROCKET_DEBUG_THROTTLE
1401        printk(KERN_INFO "unthrottle %s: %d....\n", tty->name,
1402               tty->ldisc.chars_in_buffer(tty));
1403#endif
1404
1405        if (rocket_paranoia_check(info, "rp_throttle"))
1406                return;
1407
1408        if (I_IXOFF(tty))
1409                rp_send_xchar(tty, START_CHAR(tty));
1410
1411        sSetRTS(&info->channel);
1412}
1413
1414/*
1415 * ------------------------------------------------------------
1416 * rp_stop() and rp_start()
1417 *
1418 * This routines are called before setting or resetting tty->stopped.
1419 * They enable or disable transmitter interrupts, as necessary.
1420 * ------------------------------------------------------------
1421 */
1422static void rp_stop(struct tty_struct *tty)
1423{
1424        struct r_port *info = tty->driver_data;
1425
1426#ifdef ROCKET_DEBUG_FLOW
1427        printk(KERN_INFO "stop %s: %d %d....\n", tty->name,
1428               info->xmit_cnt, info->xmit_fifo_room);
1429#endif
1430
1431        if (rocket_paranoia_check(info, "rp_stop"))
1432                return;
1433
1434        if (sGetTxCnt(&info->channel))
1435                sDisTransmit(&info->channel);
1436}
1437
1438static void rp_start(struct tty_struct *tty)
1439{
1440        struct r_port *info = tty->driver_data;
1441
1442#ifdef ROCKET_DEBUG_FLOW
1443        printk(KERN_INFO "start %s: %d %d....\n", tty->name,
1444               info->xmit_cnt, info->xmit_fifo_room);
1445#endif
1446
1447        if (rocket_paranoia_check(info, "rp_stop"))
1448                return;
1449
1450        sEnTransmit(&info->channel);
1451        set_bit((info->aiop * 8) + info->chan,
1452                (void *) &xmit_flags[info->board]);
1453}
1454
1455/*
1456 * rp_wait_until_sent() --- wait until the transmitter is empty
1457 */
1458static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
1459{
1460        struct r_port *info = tty->driver_data;
1461        CHANNEL_t *cp;
1462        unsigned long orig_jiffies;
1463        int check_time, exit_time;
1464        int txcnt;
1465
1466        if (rocket_paranoia_check(info, "rp_wait_until_sent"))
1467                return;
1468
1469        cp = &info->channel;
1470
1471        orig_jiffies = jiffies;
1472#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1473        printk(KERN_INFO "In RP_wait_until_sent(%d) (jiff=%lu)...\n", timeout,
1474               jiffies);
1475        printk(KERN_INFO "cps=%d...\n", info->cps);
1476#endif
1477        while (1) {
1478                txcnt = sGetTxCnt(cp);
1479                if (!txcnt) {
1480                        if (sGetChanStatusLo(cp) & TXSHRMT)
1481                                break;
1482                        check_time = (HZ / info->cps) / 5;
1483                } else {
1484                        check_time = HZ * txcnt / info->cps;
1485                }
1486                if (timeout) {
1487                        exit_time = orig_jiffies + timeout - jiffies;
1488                        if (exit_time <= 0)
1489                                break;
1490                        if (exit_time < check_time)
1491                                check_time = exit_time;
1492                }
1493                if (check_time == 0)
1494                        check_time = 1;
1495#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1496                printk(KERN_INFO "txcnt = %d (jiff=%lu,check=%d)...\n", txcnt,
1497                                jiffies, check_time);
1498#endif
1499                msleep_interruptible(jiffies_to_msecs(check_time));
1500                if (signal_pending(current))
1501                        break;
1502        }
1503        __set_current_state(TASK_RUNNING);
1504#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1505        printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
1506#endif
1507}
1508
1509/*
1510 * rp_hangup() --- called by tty_hangup() when a hangup is signaled.
1511 */
1512static void rp_hangup(struct tty_struct *tty)
1513{
1514        CHANNEL_t *cp;
1515        struct r_port *info = tty->driver_data;
1516        unsigned long flags;
1517
1518        if (rocket_paranoia_check(info, "rp_hangup"))
1519                return;
1520
1521#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_HANGUP))
1522        printk(KERN_INFO "rp_hangup of ttyR%d...\n", info->line);
1523#endif
1524        rp_flush_buffer(tty);
1525        spin_lock_irqsave(&info->port.lock, flags);
1526        if (info->port.flags & ASYNC_CLOSING) {
1527                spin_unlock_irqrestore(&info->port.lock, flags);
1528                return;
1529        }
1530        if (info->port.count)
1531                atomic_dec(&rp_num_ports_open);
1532        clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1533        spin_unlock_irqrestore(&info->port.lock, flags);
1534
1535        tty_port_hangup(&info->port);
1536
1537        cp = &info->channel;
1538        sDisRxFIFO(cp);
1539        sDisTransmit(cp);
1540        sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
1541        sDisCTSFlowCtl(cp);
1542        sDisTxSoftFlowCtl(cp);
1543        sClrTxXOFF(cp);
1544        clear_bit(ASYNCB_INITIALIZED, &info->port.flags);
1545
1546        wake_up_interruptible(&info->port.open_wait);
1547}
1548
1549/*
1550 *  Exception handler - write char routine.  The RocketPort driver uses a
1551 *  double-buffering strategy, with the twist that if the in-memory CPU
1552 *  buffer is empty, and there's space in the transmit FIFO, the
1553 *  writing routines will write directly to transmit FIFO.
1554 *  Write buffer and counters protected by spinlocks
1555 */
1556static int rp_put_char(struct tty_struct *tty, unsigned char ch)
1557{
1558        struct r_port *info = tty->driver_data;
1559        CHANNEL_t *cp;
1560        unsigned long flags;
1561
1562        if (rocket_paranoia_check(info, "rp_put_char"))
1563                return 0;
1564
1565        /*
1566         * Grab the port write mutex, locking out other processes that try to
1567         * write to this port
1568         */
1569        mutex_lock(&info->write_mtx);
1570
1571#ifdef ROCKET_DEBUG_WRITE
1572        printk(KERN_INFO "rp_put_char %c...\n", ch);
1573#endif
1574
1575        spin_lock_irqsave(&info->slock, flags);
1576        cp = &info->channel;
1577
1578        if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room == 0)
1579                info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
1580
1581        if (tty->stopped || tty->hw_stopped || info->xmit_fifo_room == 0 || info->xmit_cnt != 0) {
1582                info->xmit_buf[info->xmit_head++] = ch;
1583                info->xmit_head &= XMIT_BUF_SIZE - 1;
1584                info->xmit_cnt++;
1585                set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1586        } else {
1587                sOutB(sGetTxRxDataIO(cp), ch);
1588                info->xmit_fifo_room--;
1589        }
1590        spin_unlock_irqrestore(&info->slock, flags);
1591        mutex_unlock(&info->write_mtx);
1592        return 1;
1593}
1594
1595/*
1596 *  Exception handler - write routine, called when user app writes to the device.
1597 *  A per port write mutex is used to protect from another process writing to
1598 *  this port at the same time.  This other process could be running on the other CPU
1599 *  or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out). 
1600 *  Spinlocks protect the info xmit members.
1601 */
1602static int rp_write(struct tty_struct *tty,
1603                    const unsigned char *buf, int count)
1604{
1605        struct r_port *info = tty->driver_data;
1606        CHANNEL_t *cp;
1607        const unsigned char *b;
1608        int c, retval = 0;
1609        unsigned long flags;
1610
1611        if (count <= 0 || rocket_paranoia_check(info, "rp_write"))
1612                return 0;
1613
1614        if (mutex_lock_interruptible(&info->write_mtx))
1615                return -ERESTARTSYS;
1616
1617#ifdef ROCKET_DEBUG_WRITE
1618        printk(KERN_INFO "rp_write %d chars...\n", count);
1619#endif
1620        cp = &info->channel;
1621
1622        if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room < count)
1623                info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
1624
1625        /*
1626         *  If the write queue for the port is empty, and there is FIFO space, stuff bytes 
1627         *  into FIFO.  Use the write queue for temp storage.
1628         */
1629        if (!tty->stopped && !tty->hw_stopped && info->xmit_cnt == 0 && info->xmit_fifo_room > 0) {
1630                c = min(count, info->xmit_fifo_room);
1631                b = buf;
1632
1633                /*  Push data into FIFO, 2 bytes at a time */
1634                sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) b, c / 2);
1635
1636                /*  If there is a byte remaining, write it */
1637                if (c & 1)
1638                        sOutB(sGetTxRxDataIO(cp), b[c - 1]);
1639
1640                retval += c;
1641                buf += c;
1642                count -= c;
1643
1644                spin_lock_irqsave(&info->slock, flags);
1645                info->xmit_fifo_room -= c;
1646                spin_unlock_irqrestore(&info->slock, flags);
1647        }
1648
1649        /* If count is zero, we wrote it all and are done */
1650        if (!count)
1651                goto end;
1652
1653        /*  Write remaining data into the port's xmit_buf */
1654        while (1) {
1655                /* Hung up ? */
1656                if (!test_bit(ASYNCB_NORMAL_ACTIVE, &info->port.flags))
1657                        goto end;
1658                c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
1659                c = min(c, XMIT_BUF_SIZE - info->xmit_head);
1660                if (c <= 0)
1661                        break;
1662
1663                b = buf;
1664                memcpy(info->xmit_buf + info->xmit_head, b, c);
1665
1666                spin_lock_irqsave(&info->slock, flags);
1667                info->xmit_head =
1668                    (info->xmit_head + c) & (XMIT_BUF_SIZE - 1);
1669                info->xmit_cnt += c;
1670                spin_unlock_irqrestore(&info->slock, flags);
1671
1672                buf += c;
1673                count -= c;
1674                retval += c;
1675        }
1676
1677        if ((retval > 0) && !tty->stopped && !tty->hw_stopped)
1678                set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1679        
1680end:
1681        if (info->xmit_cnt < WAKEUP_CHARS) {
1682                tty_wakeup(tty);
1683#ifdef ROCKETPORT_HAVE_POLL_WAIT
1684                wake_up_interruptible(&tty->poll_wait);
1685#endif
1686        }
1687        mutex_unlock(&info->write_mtx);
1688        return retval;
1689}
1690
1691/*
1692 * Return the number of characters that can be sent.  We estimate
1693 * only using the in-memory transmit buffer only, and ignore the
1694 * potential space in the transmit FIFO.
1695 */
1696static int rp_write_room(struct tty_struct *tty)
1697{
1698        struct r_port *info = tty->driver_data;
1699        int ret;
1700
1701        if (rocket_paranoia_check(info, "rp_write_room"))
1702                return 0;
1703
1704        ret = XMIT_BUF_SIZE - info->xmit_cnt - 1;
1705        if (ret < 0)
1706                ret = 0;
1707#ifdef ROCKET_DEBUG_WRITE
1708        printk(KERN_INFO "rp_write_room returns %d...\n", ret);
1709#endif
1710        return ret;
1711}
1712
1713/*
1714 * Return the number of characters in the buffer.  Again, this only
1715 * counts those characters in the in-memory transmit buffer.
1716 */
1717static int rp_chars_in_buffer(struct tty_struct *tty)
1718{
1719        struct r_port *info = tty->driver_data;
1720
1721        if (rocket_paranoia_check(info, "rp_chars_in_buffer"))
1722                return 0;
1723
1724#ifdef ROCKET_DEBUG_WRITE
1725        printk(KERN_INFO "rp_chars_in_buffer returns %d...\n", info->xmit_cnt);
1726#endif
1727        return info->xmit_cnt;
1728}
1729
1730/*
1731 *  Flushes the TX fifo for a port, deletes data in the xmit_buf stored in the
1732 *  r_port struct for the port.  Note that spinlock are used to protect info members,
1733 *  do not call this function if the spinlock is already held.
1734 */
1735static void rp_flush_buffer(struct tty_struct *tty)
1736{
1737        struct r_port *info = tty->driver_data;
1738        CHANNEL_t *cp;
1739        unsigned long flags;
1740
1741        if (rocket_paranoia_check(info, "rp_flush_buffer"))
1742                return;
1743
1744        spin_lock_irqsave(&info->slock, flags);
1745        info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1746        spin_unlock_irqrestore(&info->slock, flags);
1747
1748#ifdef ROCKETPORT_HAVE_POLL_WAIT
1749        wake_up_interruptible(&tty->poll_wait);
1750#endif
1751        tty_wakeup(tty);
1752
1753        cp = &info->channel;
1754        sFlushTxFIFO(cp);
1755}
1756
1757#ifdef CONFIG_PCI
1758
1759static DEFINE_PCI_DEVICE_TABLE(rocket_pci_ids) = {
1760        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP4QUAD) },
1761        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP8OCTA) },
1762        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_URP8OCTA) },
1763        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP8INTF) },
1764        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_URP8INTF) },
1765        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP8J) },
1766        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP4J) },
1767        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP8SNI) },
1768        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP16SNI) },
1769        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP16INTF) },
1770        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_URP16INTF) },
1771        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_CRP16INTF) },
1772        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP32INTF) },
1773        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_URP32INTF) },
1774        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RPP4) },
1775        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RPP8) },
1776        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP2_232) },
1777        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP2_422) },
1778        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP6M) },
1779        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP4M) },
1780        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_UPCI_RM3_8PORT) },
1781        { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_UPCI_RM3_4PORT) },
1782        { }
1783};
1784MODULE_DEVICE_TABLE(pci, rocket_pci_ids);
1785
1786/*
1787 *  Called when a PCI card is found.  Retrieves and stores model information,
1788 *  init's aiopic and serial port hardware.
1789 *  Inputs:  i is the board number (0-n)
1790 */
1791static __init int register_PCI(int i, struct pci_dev *dev)
1792{
1793        int num_aiops, aiop, max_num_aiops, num_chan, chan;
1794        unsigned int aiopio[MAX_AIOPS_PER_BOARD];
1795        CONTROLLER_t *ctlp;
1796
1797        int fast_clock = 0;
1798        int altChanRingIndicator = 0;
1799        int ports_per_aiop = 8;
1800        WordIO_t ConfigIO = 0;
1801        ByteIO_t UPCIRingInd = 0;
1802
1803        if (!dev || !pci_match_id(rocket_pci_ids, dev) ||
1804            pci_enable_device(dev))
1805                return 0;
1806
1807        rcktpt_io_addr[i] = pci_resource_start(dev, 0);
1808
1809        rcktpt_type[i] = ROCKET_TYPE_NORMAL;
1810        rocketModel[i].loadrm2 = 0;
1811        rocketModel[i].startingPortNumber = nextLineNumber;
1812
1813        /*  Depending on the model, set up some config variables */
1814        switch (dev->device) {
1815        case PCI_DEVICE_ID_RP4QUAD:
1816                max_num_aiops = 1;
1817                ports_per_aiop = 4;
1818                rocketModel[i].model = MODEL_RP4QUAD;
1819                strcpy(rocketModel[i].modelString, "RocketPort 4 port w/quad cable");
1820                rocketModel[i].numPorts = 4;
1821                break;
1822        case PCI_DEVICE_ID_RP8OCTA:
1823                max_num_aiops = 1;
1824                rocketModel[i].model = MODEL_RP8OCTA;
1825                strcpy(rocketModel[i].modelString, "RocketPort 8 port w/octa cable");
1826                rocketModel[i].numPorts = 8;
1827                break;
1828        case PCI_DEVICE_ID_URP8OCTA:
1829                max_num_aiops = 1;
1830                rocketModel[i].model = MODEL_UPCI_RP8OCTA;
1831                strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/octa cable");
1832                rocketModel[i].numPorts = 8;
1833                break;
1834        case PCI_DEVICE_ID_RP8INTF:
1835                max_num_aiops = 1;
1836                rocketModel[i].model = MODEL_RP8INTF;
1837                strcpy(rocketModel[i].modelString, "RocketPort 8 port w/external I/F");
1838                rocketModel[i].numPorts = 8;
1839                break;
1840        case PCI_DEVICE_ID_URP8INTF:
1841                max_num_aiops = 1;
1842                rocketModel[i].model = MODEL_UPCI_RP8INTF;
1843                strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/external I/F");
1844                rocketModel[i].numPorts = 8;
1845                break;
1846        case PCI_DEVICE_ID_RP8J:
1847                max_num_aiops = 1;
1848                rocketModel[i].model = MODEL_RP8J;
1849                strcpy(rocketModel[i].modelString, "RocketPort 8 port w/RJ11 connectors");
1850                rocketModel[i].numPorts = 8;
1851                break;
1852        case PCI_DEVICE_ID_RP4J:
1853                max_num_aiops = 1;
1854                ports_per_aiop = 4;
1855                rocketModel[i].model = MODEL_RP4J;
1856                strcpy(rocketModel[i].modelString, "RocketPort 4 port w/RJ45 connectors");
1857                rocketModel[i].numPorts = 4;
1858                break;
1859        case PCI_DEVICE_ID_RP8SNI:
1860                max_num_aiops = 1;
1861                rocketModel[i].model = MODEL_RP8SNI;
1862                strcpy(rocketModel[i].modelString, "RocketPort 8 port w/ custom DB78");
1863                rocketModel[i].numPorts = 8;
1864                break;
1865        case PCI_DEVICE_ID_RP16SNI:
1866                max_num_aiops = 2;
1867                rocketModel[i].model = MODEL_RP16SNI;
1868                strcpy(rocketModel[i].modelString, "RocketPort 16 port w/ custom DB78");
1869                rocketModel[i].numPorts = 16;
1870                break;
1871        case PCI_DEVICE_ID_RP16INTF:
1872                max_num_aiops = 2;
1873                rocketModel[i].model = MODEL_RP16INTF;
1874                strcpy(rocketModel[i].modelString, "RocketPort 16 port w/external I/F");
1875                rocketModel[i].numPorts = 16;
1876                break;
1877        case PCI_DEVICE_ID_URP16INTF:
1878                max_num_aiops = 2;
1879                rocketModel[i].model = MODEL_UPCI_RP16INTF;
1880                strcpy(rocketModel[i].modelString, "RocketPort UPCI 16 port w/external I/F");
1881                rocketModel[i].numPorts = 16;
1882                break;
1883        case PCI_DEVICE_ID_CRP16INTF:
1884                max_num_aiops = 2;
1885                rocketModel[i].model = MODEL_CPCI_RP16INTF;
1886                strcpy(rocketModel[i].modelString, "RocketPort Compact PCI 16 port w/external I/F");
1887                rocketModel[i].numPorts = 16;
1888                break;
1889        case PCI_DEVICE_ID_RP32INTF:
1890                max_num_aiops = 4;
1891                rocketModel[i].model = MODEL_RP32INTF;
1892                strcpy(rocketModel[i].modelString, "RocketPort 32 port w/external I/F");
1893                rocketModel[i].numPorts = 32;
1894                break;
1895        case PCI_DEVICE_ID_URP32INTF:
1896                max_num_aiops = 4;
1897                rocketModel[i].model = MODEL_UPCI_RP32INTF;
1898                strcpy(rocketModel[i].modelString, "RocketPort UPCI 32 port w/external I/F");
1899                rocketModel[i].numPorts = 32;
1900                break;
1901        case PCI_DEVICE_ID_RPP4:
1902                max_num_aiops = 1;
1903                ports_per_aiop = 4;
1904                altChanRingIndicator++;
1905                fast_clock++;
1906                rocketModel[i].model = MODEL_RPP4;
1907                strcpy(rocketModel[i].modelString, "RocketPort Plus 4 port");
1908                rocketModel[i].numPorts = 4;
1909                break;
1910        case PCI_DEVICE_ID_RPP8:
1911                max_num_aiops = 2;
1912                ports_per_aiop = 4;
1913                altChanRingIndicator++;
1914                fast_clock++;
1915                rocketModel[i].model = MODEL_RPP8;
1916                strcpy(rocketModel[i].modelString, "RocketPort Plus 8 port");
1917                rocketModel[i].numPorts = 8;
1918                break;
1919        case PCI_DEVICE_ID_RP2_232:
1920                max_num_aiops = 1;
1921                ports_per_aiop = 2;
1922                altChanRingIndicator++;
1923                fast_clock++;
1924                rocketModel[i].model = MODEL_RP2_232;
1925                strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS232");
1926                rocketModel[i].numPorts = 2;
1927                break;
1928        case PCI_DEVICE_ID_RP2_422:
1929                max_num_aiops = 1;
1930                ports_per_aiop = 2;
1931                altChanRingIndicator++;
1932                fast_clock++;
1933                rocketModel[i].model = MODEL_RP2_422;
1934                strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS422");
1935                rocketModel[i].numPorts = 2;
1936                break;
1937        case PCI_DEVICE_ID_RP6M:
1938
1939                max_num_aiops = 1;
1940                ports_per_aiop = 6;
1941
1942                /*  If revision is 1, the rocketmodem flash must be loaded.
1943                 *  If it is 2 it is a "socketed" version. */
1944                if (dev->revision == 1) {
1945                        rcktpt_type[i] = ROCKET_TYPE_MODEMII;
1946                        rocketModel[i].loadrm2 = 1;
1947                } else {
1948                        rcktpt_type[i] = ROCKET_TYPE_MODEM;
1949                }
1950
1951                rocketModel[i].model = MODEL_RP6M;
1952                strcpy(rocketModel[i].modelString, "RocketModem 6 port");
1953                rocketModel[i].numPorts = 6;
1954                break;
1955        case PCI_DEVICE_ID_RP4M:
1956                max_num_aiops = 1;
1957                ports_per_aiop = 4;
1958                if (dev->revision == 1) {
1959                        rcktpt_type[i] = ROCKET_TYPE_MODEMII;
1960                        rocketModel[i].loadrm2 = 1;
1961                } else {
1962                        rcktpt_type[i] = ROCKET_TYPE_MODEM;
1963                }
1964
1965                rocketModel[i].model = MODEL_RP4M;
1966                strcpy(rocketModel[i].modelString, "RocketModem 4 port");
1967                rocketModel[i].numPorts = 4;
1968                break;
1969        default:
1970                max_num_aiops = 0;
1971                break;
1972        }
1973
1974        /*
1975         * Check for UPCI boards.
1976         */
1977
1978        switch (dev->device) {
1979        case PCI_DEVICE_ID_URP32INTF:
1980        case PCI_DEVICE_ID_URP8INTF:
1981        case PCI_DEVICE_ID_URP16INTF:
1982        case PCI_DEVICE_ID_CRP16INTF:
1983        case PCI_DEVICE_ID_URP8OCTA:
1984                rcktpt_io_addr[i] = pci_resource_start(dev, 2);
1985                ConfigIO = pci_resource_start(dev, 1);
1986                if (dev->device == PCI_DEVICE_ID_URP8OCTA) {
1987                        UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
1988
1989                        /*
1990                         * Check for octa or quad cable.
1991                         */
1992                        if (!
1993                            (sInW(ConfigIO + _PCI_9030_GPIO_CTRL) &
1994                             PCI_GPIO_CTRL_8PORT)) {
1995                                ports_per_aiop = 4;
1996                                rocketModel[i].numPorts = 4;
1997                        }
1998                }
1999                break;
2000        case PCI_DEVICE_ID_UPCI_RM3_8PORT:
2001                max_num_aiops = 1;
2002                rocketModel[i].model = MODEL_UPCI_RM3_8PORT;
2003                strcpy(rocketModel[i].modelString, "RocketModem III 8 port");
2004                rocketModel[i].numPorts = 8;
2005                rcktpt_io_addr[i] = pci_resource_start(dev, 2);
2006                UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
2007                ConfigIO = pci_resource_start(dev, 1);
2008                rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
2009                break;
2010        case PCI_DEVICE_ID_UPCI_RM3_4PORT:
2011                max_num_aiops = 1;
2012                rocketModel[i].model = MODEL_UPCI_RM3_4PORT;
2013                strcpy(rocketModel[i].modelString, "RocketModem III 4 port");
2014                rocketModel[i].numPorts = 4;
2015                rcktpt_io_addr[i] = pci_resource_start(dev, 2);
2016                UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
2017                ConfigIO = pci_resource_start(dev, 1);
2018                rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
2019                break;
2020        default:
2021                break;
2022        }
2023
2024        if (fast_clock) {
2025                sClockPrescale = 0x12;  /* mod 2 (divide by 3) */
2026                rp_baud_base[i] = 921600;
2027        } else {
2028                /*
2029                 * If support_low_speed is set, use the slow clock
2030                 * prescale, which supports 50 bps
2031                 */
2032                if (support_low_speed) {
2033                        /* mod 9 (divide by 10) prescale */
2034                        sClockPrescale = 0x19;
2035                        rp_baud_base[i] = 230400;
2036                } else {
2037                        /* mod 4 (divide by 5) prescale */
2038                        sClockPrescale = 0x14;
2039                        rp_baud_base[i] = 460800;
2040                }
2041        }
2042
2043        for (aiop = 0; aiop < max_num_aiops; aiop++)
2044                aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x40);
2045        ctlp = sCtlNumToCtlPtr(i);
2046        num_aiops = sPCIInitController(ctlp, i, aiopio, max_num_aiops, ConfigIO, 0, FREQ_DIS, 0, altChanRingIndicator, UPCIRingInd);
2047        for (aiop = 0; aiop < max_num_aiops; aiop++)
2048                ctlp->AiopNumChan[aiop] = ports_per_aiop;
2049
2050        dev_info(&dev->dev, "comtrol PCI controller #%d found at "
2051                "address %04lx, %d AIOP(s) (%s), creating ttyR%d - %ld\n",
2052                i, rcktpt_io_addr[i], num_aiops, rocketModel[i].modelString,
2053                rocketModel[i].startingPortNumber,
2054                rocketModel[i].startingPortNumber + rocketModel[i].numPorts-1);
2055
2056        if (num_aiops <= 0) {
2057                rcktpt_io_addr[i] = 0;
2058                return (0);
2059        }
2060        is_PCI[i] = 1;
2061
2062        /*  Reset the AIOPIC, init the serial ports */
2063        for (aiop = 0; aiop < num_aiops; aiop++) {
2064                sResetAiopByNum(ctlp, aiop);
2065                num_chan = ports_per_aiop;
2066                for (chan = 0; chan < num_chan; chan++)
2067                        init_r_port(i, aiop, chan, dev);
2068        }
2069
2070        /*  Rocket modems must be reset */
2071        if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) ||
2072            (rcktpt_type[i] == ROCKET_TYPE_MODEMII) ||
2073            (rcktpt_type[i] == ROCKET_TYPE_MODEMIII)) {
2074                num_chan = ports_per_aiop;
2075                for (chan = 0; chan < num_chan; chan++)
2076                        sPCIModemReset(ctlp, chan, 1);
2077                msleep(500);
2078                for (chan = 0; chan < num_chan; chan++)
2079                        sPCIModemReset(ctlp, chan, 0);
2080                msleep(500);
2081                rmSpeakerReset(ctlp, rocketModel[i].model);
2082        }
2083        return (1);
2084}
2085
2086/*
2087 *  Probes for PCI cards, inits them if found
2088 *  Input:   board_found = number of ISA boards already found, or the
2089 *           starting board number
2090 *  Returns: Number of PCI boards found
2091 */
2092static int __init init_PCI(int boards_found)
2093{
2094        struct pci_dev *dev = NULL;
2095        int count = 0;
2096
2097        /*  Work through the PCI device list, pulling out ours */
2098        while ((dev = pci_get_device(PCI_VENDOR_ID_RP, PCI_ANY_ID, dev))) {
2099                if (register_PCI(count + boards_found, dev))
2100                        count++;
2101        }
2102        return (count);
2103}
2104
2105#endif                          /* CONFIG_PCI */
2106
2107/*
2108 *  Probes for ISA cards
2109 *  Input:   i = the board number to look for
2110 *  Returns: 1 if board found, 0 else
2111 */
2112static int __init init_ISA(int i)
2113{
2114        int num_aiops, num_chan = 0, total_num_chan = 0;
2115        int aiop, chan;
2116        unsigned int aiopio[MAX_AIOPS_PER_BOARD];
2117        CONTROLLER_t *ctlp;
2118        char *type_string;
2119
2120        /*  If io_addr is zero, no board configured */
2121        if (rcktpt_io_addr[i] == 0)
2122                return (0);
2123
2124        /*  Reserve the IO region */
2125        if (!request_region(rcktpt_io_addr[i], 64, "Comtrol RocketPort")) {
2126                printk(KERN_ERR "Unable to reserve IO region for configured "
2127                                "ISA RocketPort at address 0x%lx, board not "
2128                                "installed...\n", rcktpt_io_addr[i]);
2129                rcktpt_io_addr[i] = 0;
2130                return (0);
2131        }
2132
2133        ctlp = sCtlNumToCtlPtr(i);
2134
2135        ctlp->boardType = rcktpt_type[i];
2136
2137        switch (rcktpt_type[i]) {
2138        case ROCKET_TYPE_PC104:
2139                type_string = "(PC104)";
2140                break;
2141        case ROCKET_TYPE_MODEM:
2142                type_string = "(RocketModem)";
2143                break;
2144        case ROCKET_TYPE_MODEMII:
2145                type_string = "(RocketModem II)";
2146                break;
2147        default:
2148                type_string = "";
2149                break;
2150        }
2151
2152        /*
2153         * If support_low_speed is set, use the slow clock prescale,
2154         * which supports 50 bps
2155         */
2156        if (support_low_speed) {
2157                sClockPrescale = 0x19;  /* mod 9 (divide by 10) prescale */
2158                rp_baud_base[i] = 230400;
2159        } else {
2160                sClockPrescale = 0x14;  /* mod 4 (divide by 5) prescale */
2161                rp_baud_base[i] = 460800;
2162        }
2163
2164        for (aiop = 0; aiop < MAX_AIOPS_PER_BOARD; aiop++)
2165                aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x400);
2166
2167        num_aiops = sInitController(ctlp, i, controller + (i * 0x400), aiopio,  MAX_AIOPS_PER_BOARD, 0, FREQ_DIS, 0);
2168
2169        if (ctlp->boardType == ROCKET_TYPE_PC104) {
2170                sEnAiop(ctlp, 2);       /* only one AIOPIC, but these */
2171                sEnAiop(ctlp, 3);       /* CSels used for other stuff */
2172        }
2173
2174        /*  If something went wrong initing the AIOP's release the ISA IO memory */
2175        if (num_aiops <= 0) {
2176                release_region(rcktpt_io_addr[i], 64);
2177                rcktpt_io_addr[i] = 0;
2178                return (0);
2179        }
2180  
2181        rocketModel[i].startingPortNumber = nextLineNumber;
2182
2183        for (aiop = 0; aiop < num_aiops; aiop++) {
2184                sResetAiopByNum(ctlp, aiop);
2185                sEnAiop(ctlp, aiop);
2186                num_chan = sGetAiopNumChan(ctlp, aiop);
2187                total_num_chan += num_chan;
2188                for (chan = 0; chan < num_chan; chan++)
2189                        init_r_port(i, aiop, chan, NULL);
2190        }
2191        is_PCI[i] = 0;
2192        if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) || (rcktpt_type[i] == ROCKET_TYPE_MODEMII)) {
2193                num_chan = sGetAiopNumChan(ctlp, 0);
2194                total_num_chan = num_chan;
2195                for (chan = 0; chan < num_chan; chan++)
2196                        sModemReset(ctlp, chan, 1);
2197                msleep(500);
2198                for (chan = 0; chan < num_chan; chan++)
2199                        sModemReset(ctlp, chan, 0);
2200                msleep(500);
2201                strcpy(rocketModel[i].modelString, "RocketModem ISA");
2202        } else {
2203                strcpy(rocketModel[i].modelString, "RocketPort ISA");
2204        }
2205        rocketModel[i].numPorts = total_num_chan;
2206        rocketModel[i].model = MODEL_ISA;
2207
2208        printk(KERN_INFO "RocketPort ISA card #%d found at 0x%lx - %d AIOPs %s\n", 
2209               i, rcktpt_io_addr[i], num_aiops, type_string);
2210
2211        printk(KERN_INFO "Installing %s, creating /dev/ttyR%d - %ld\n",
2212               rocketModel[i].modelString,
2213               rocketModel[i].startingPortNumber,
2214               rocketModel[i].startingPortNumber +
2215               rocketModel[i].numPorts - 1);
2216
2217        return (1);
2218}
2219
2220static const struct tty_operations rocket_ops = {
2221        .open = rp_open,
2222        .close = rp_close,
2223        .write = rp_write,
2224        .put_char = rp_put_char,
2225        .write_room = rp_write_room,
2226        .chars_in_buffer = rp_chars_in_buffer,
2227        .flush_buffer = rp_flush_buffer,
2228        .ioctl = rp_ioctl,
2229        .throttle = rp_throttle,
2230        .unthrottle = rp_unthrottle,
2231        .set_termios = rp_set_termios,
2232        .stop = rp_stop,
2233        .start = rp_start,
2234        .hangup = rp_hangup,
2235        .break_ctl = rp_break,
2236        .send_xchar = rp_send_xchar,
2237        .wait_until_sent = rp_wait_until_sent,
2238        .tiocmget = rp_tiocmget,
2239        .tiocmset = rp_tiocmset,
2240};
2241
2242static const struct tty_port_operations rocket_port_ops = {
2243        .carrier_raised = carrier_raised,
2244        .dtr_rts = dtr_rts,
2245};
2246
2247/*
2248 * The module "startup" routine; it's run when the module is loaded.
2249 */
2250static int __init rp_init(void)
2251{
2252        int ret = -ENOMEM, pci_boards_found, isa_boards_found, i;
2253
2254        printk(KERN_INFO "RocketPort device driver module, version %s, %s\n",
2255               ROCKET_VERSION, ROCKET_DATE);
2256
2257        rocket_driver = alloc_tty_driver(MAX_RP_PORTS);
2258        if (!rocket_driver)
2259                goto err;
2260
2261        /*
2262         *  If board 1 is non-zero, there is at least one ISA configured.  If controller is 
2263         *  zero, use the default controller IO address of board1 + 0x40.
2264         */
2265        if (board1) {
2266                if (controller == 0)
2267                        controller = board1 + 0x40;
2268        } else {
2269                controller = 0;  /*  Used as a flag, meaning no ISA boards */
2270        }
2271
2272        /*  If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */
2273        if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) {
2274                printk(KERN_ERR "Unable to reserve IO region for first "
2275                        "configured ISA RocketPort controller 0x%lx.  "
2276                        "Driver exiting\n", controller);
2277                ret = -EBUSY;
2278                goto err_tty;
2279        }
2280
2281        /*  Store ISA variable retrieved from command line or .conf file. */
2282        rcktpt_io_addr[0] = board1;
2283        rcktpt_io_addr[1] = board2;
2284        rcktpt_io_addr[2] = board3;
2285        rcktpt_io_addr[3] = board4;
2286
2287        rcktpt_type[0] = modem1 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2288        rcktpt_type[0] = pc104_1[0] ? ROCKET_TYPE_PC104 : rcktpt_type[0];
2289        rcktpt_type[1] = modem2 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2290        rcktpt_type[1] = pc104_2[0] ? ROCKET_TYPE_PC104 : rcktpt_type[1];
2291        rcktpt_type[2] = modem3 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2292        rcktpt_type[2] = pc104_3[0] ? ROCKET_TYPE_PC104 : rcktpt_type[2];
2293        rcktpt_type[3] = modem4 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2294        rcktpt_type[3] = pc104_4[0] ? ROCKET_TYPE_PC104 : rcktpt_type[3];
2295
2296        /*
2297         * Set up the tty driver structure and then register this
2298         * driver with the tty layer.
2299         */
2300
2301        rocket_driver->flags = TTY_DRIVER_DYNAMIC_DEV;
2302        rocket_driver->name = "ttyR";
2303        rocket_driver->driver_name = "Comtrol RocketPort";
2304        rocket_driver->major = TTY_ROCKET_MAJOR;
2305        rocket_driver->minor_start = 0;
2306        rocket_driver->type = TTY_DRIVER_TYPE_SERIAL;
2307        rocket_driver->subtype = SERIAL_TYPE_NORMAL;
2308        rocket_driver->init_termios = tty_std_termios;
2309        rocket_driver->init_termios.c_cflag =
2310            B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2311        rocket_driver->init_termios.c_ispeed = 9600;
2312        rocket_driver->init_termios.c_ospeed = 9600;
2313#ifdef ROCKET_SOFT_FLOW
2314        rocket_driver->flags |= TTY_DRIVER_REAL_RAW;
2315#endif
2316        tty_set_operations(rocket_driver, &rocket_ops);
2317
2318        ret = tty_register_driver(rocket_driver);
2319        if (ret < 0) {
2320                printk(KERN_ERR "Couldn't install tty RocketPort driver\n");
2321                goto err_controller;
2322        }
2323
2324#ifdef ROCKET_DEBUG_OPEN
2325        printk(KERN_INFO "RocketPort driver is major %d\n", rocket_driver.major);
2326#endif
2327
2328        /*
2329         *  OK, let's probe each of the controllers looking for boards.  Any boards found
2330         *  will be initialized here.
2331         */
2332        isa_boards_found = 0;
2333        pci_boards_found = 0;
2334
2335        for (i = 0; i < NUM_BOARDS; i++) {
2336                if (init_ISA(i))
2337                        isa_boards_found++;
2338        }
2339
2340#ifdef CONFIG_PCI
2341        if (isa_boards_found < NUM_BOARDS)
2342                pci_boards_found = init_PCI(isa_boards_found);
2343#endif
2344
2345        max_board = pci_boards_found + isa_boards_found;
2346
2347        if (max_board == 0) {
2348                printk(KERN_ERR "No rocketport ports found; unloading driver\n");
2349                ret = -ENXIO;
2350                goto err_ttyu;
2351        }
2352
2353        return 0;
2354err_ttyu:
2355        tty_unregister_driver(rocket_driver);
2356err_controller:
2357        if (controller)
2358                release_region(controller, 4);
2359err_tty:
2360        put_tty_driver(rocket_driver);
2361err:
2362        return ret;
2363}
2364
2365
2366static void rp_cleanup_module(void)
2367{
2368        int retval;
2369        int i;
2370
2371        del_timer_sync(&rocket_timer);
2372
2373        retval = tty_unregister_driver(rocket_driver);
2374        if (retval)
2375                printk(KERN_ERR "Error %d while trying to unregister "
2376                       "rocketport driver\n", -retval);
2377
2378        for (i = 0; i < MAX_RP_PORTS; i++)
2379                if (rp_table[i]) {
2380                        tty_unregister_device(rocket_driver, i);
2381                        tty_port_destroy(&rp_table[i]->port);
2382                        kfree(rp_table[i]);
2383                }
2384
2385        put_tty_driver(rocket_driver);
2386
2387        for (i = 0; i < NUM_BOARDS; i++) {
2388                if (rcktpt_io_addr[i] <= 0 || is_PCI[i])
2389                        continue;
2390                release_region(rcktpt_io_addr[i], 64);
2391        }
2392        if (controller)
2393                release_region(controller, 4);
2394}
2395
2396/***************************************************************************
2397Function: sInitController
2398Purpose:  Initialization of controller global registers and controller
2399          structure.
2400Call:     sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize,
2401                          IRQNum,Frequency,PeriodicOnly)
2402          CONTROLLER_T *CtlP; Ptr to controller structure
2403          int CtlNum; Controller number
2404          ByteIO_t MudbacIO; Mudbac base I/O address.
2405          ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
2406             This list must be in the order the AIOPs will be found on the
2407             controller.  Once an AIOP in the list is not found, it is
2408             assumed that there are no more AIOPs on the controller.
2409          int AiopIOListSize; Number of addresses in AiopIOList
2410          int IRQNum; Interrupt Request number.  Can be any of the following:
2411                         0: Disable global interrupts
2412                         3: IRQ 3
2413                         4: IRQ 4
2414                         5: IRQ 5
2415                         9: IRQ 9
2416                         10: IRQ 10
2417                         11: IRQ 11
2418                         12: IRQ 12
2419                         15: IRQ 15
2420          Byte_t Frequency: A flag identifying the frequency
2421                   of the periodic interrupt, can be any one of the following:
2422                      FREQ_DIS - periodic interrupt disabled
2423                      FREQ_137HZ - 137 Hertz
2424                      FREQ_69HZ - 69 Hertz
2425                      FREQ_34HZ - 34 Hertz
2426                      FREQ_17HZ - 17 Hertz
2427                      FREQ_9HZ - 9 Hertz
2428                      FREQ_4HZ - 4 Hertz
2429                   If IRQNum is set to 0 the Frequency parameter is
2430                   overidden, it is forced to a value of FREQ_DIS.
2431          int PeriodicOnly: 1 if all interrupts except the periodic
2432                               interrupt are to be blocked.
2433                            0 is both the periodic interrupt and
2434                               other channel interrupts are allowed.
2435                            If IRQNum is set to 0 the PeriodicOnly parameter is
2436                               overidden, it is forced to a value of 0.
2437Return:   int: Number of AIOPs on the controller, or CTLID_NULL if controller
2438               initialization failed.
2439
2440Comments:
2441          If periodic interrupts are to be disabled but AIOP interrupts
2442          are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
2443
2444          If interrupts are to be completely disabled set IRQNum to 0.
2445
2446          Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
2447          invalid combination.
2448
2449          This function performs initialization of global interrupt modes,
2450          but it does not actually enable global interrupts.  To enable
2451          and disable global interrupts use functions sEnGlobalInt() and
2452          sDisGlobalInt().  Enabling of global interrupts is normally not
2453          done until all other initializations are complete.
2454
2455          Even if interrupts are globally enabled, they must also be
2456          individually enabled for each channel that is to generate
2457          interrupts.
2458
2459Warnings: No range checking on any of the parameters is done.
2460
2461          No context switches are allowed while executing this function.
2462
2463          After this function all AIOPs on the controller are disabled,
2464          they can be enabled with sEnAiop().
2465*/
2466static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
2467                           ByteIO_t * AiopIOList, int AiopIOListSize,
2468                           int IRQNum, Byte_t Frequency, int PeriodicOnly)
2469{
2470        int i;
2471        ByteIO_t io;
2472        int done;
2473
2474        CtlP->AiopIntrBits = aiop_intr_bits;
2475        CtlP->AltChanRingIndicator = 0;
2476        CtlP->CtlNum = CtlNum;
2477        CtlP->CtlID = CTLID_0001;       /* controller release 1 */
2478        CtlP->BusType = isISA;
2479        CtlP->MBaseIO = MudbacIO;
2480        CtlP->MReg1IO = MudbacIO + 1;
2481        CtlP->MReg2IO = MudbacIO + 2;
2482        CtlP->MReg3IO = MudbacIO + 3;
2483#if 1
2484        CtlP->MReg2 = 0;        /* interrupt disable */
2485        CtlP->MReg3 = 0;        /* no periodic interrupts */
2486#else
2487        if (sIRQMap[IRQNum] == 0) {     /* interrupts globally disabled */
2488                CtlP->MReg2 = 0;        /* interrupt disable */
2489                CtlP->MReg3 = 0;        /* no periodic interrupts */
2490        } else {
2491                CtlP->MReg2 = sIRQMap[IRQNum];  /* set IRQ number */
2492                CtlP->MReg3 = Frequency;        /* set frequency */
2493                if (PeriodicOnly) {     /* periodic interrupt only */
2494                        CtlP->MReg3 |= PERIODIC_ONLY;
2495                }
2496        }
2497#endif
2498        sOutB(CtlP->MReg2IO, CtlP->MReg2);
2499        sOutB(CtlP->MReg3IO, CtlP->MReg3);
2500        sControllerEOI(CtlP);   /* clear EOI if warm init */
2501        /* Init AIOPs */
2502        CtlP->NumAiop = 0;
2503        for (i = done = 0; i < AiopIOListSize; i++) {
2504                io = AiopIOList[i];
2505                CtlP->AiopIO[i] = (WordIO_t) io;
2506                CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
2507                sOutB(CtlP->MReg2IO, CtlP->MReg2 | (i & 0x03)); /* AIOP index */
2508                sOutB(MudbacIO, (Byte_t) (io >> 6));    /* set up AIOP I/O in MUDBAC */
2509                if (done)
2510                        continue;
2511                sEnAiop(CtlP, i);       /* enable the AIOP */
2512                CtlP->AiopID[i] = sReadAiopID(io);      /* read AIOP ID */
2513                if (CtlP->AiopID[i] == AIOPID_NULL)     /* if AIOP does not exist */
2514                        done = 1;       /* done looking for AIOPs */
2515                else {
2516                        CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */
2517                        sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE);    /* clock prescaler */
2518                        sOutB(io + _INDX_DATA, sClockPrescale);
2519                        CtlP->NumAiop++;        /* bump count of AIOPs */
2520                }
2521                sDisAiop(CtlP, i);      /* disable AIOP */
2522        }
2523
2524        if (CtlP->NumAiop == 0)
2525                return (-1);
2526        else
2527                return (CtlP->NumAiop);
2528}
2529
2530/***************************************************************************
2531Function: sPCIInitController
2532Purpose:  Initialization of controller global registers and controller
2533          structure.
2534Call:     sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize,
2535                          IRQNum,Frequency,PeriodicOnly)
2536          CONTROLLER_T *CtlP; Ptr to controller structure
2537          int CtlNum; Controller number
2538          ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
2539             This list must be in the order the AIOPs will be found on the
2540             controller.  Once an AIOP in the list is not found, it is
2541             assumed that there are no more AIOPs on the controller.
2542          int AiopIOListSize; Number of addresses in AiopIOList
2543          int IRQNum; Interrupt Request number.  Can be any of the following:
2544                         0: Disable global interrupts
2545                         3: IRQ 3
2546                         4: IRQ 4
2547                         5: IRQ 5
2548                         9: IRQ 9
2549                         10: IRQ 10
2550                         11: IRQ 11
2551                         12: IRQ 12
2552                         15: IRQ 15
2553          Byte_t Frequency: A flag identifying the frequency
2554                   of the periodic interrupt, can be any one of the following:
2555                      FREQ_DIS - periodic interrupt disabled
2556                      FREQ_137HZ - 137 Hertz
2557                      FREQ_69HZ - 69 Hertz
2558                      FREQ_34HZ - 34 Hertz
2559                      FREQ_17HZ - 17 Hertz
2560                      FREQ_9HZ - 9 Hertz
2561                      FREQ_4HZ - 4 Hertz
2562                   If IRQNum is set to 0 the Frequency parameter is
2563                   overidden, it is forced to a value of FREQ_DIS.
2564          int PeriodicOnly: 1 if all interrupts except the periodic
2565                               interrupt are to be blocked.
2566                            0 is both the periodic interrupt and
2567                               other channel interrupts are allowed.
2568                            If IRQNum is set to 0 the PeriodicOnly parameter is
2569                               overidden, it is forced to a value of 0.
2570Return:   int: Number of AIOPs on the controller, or CTLID_NULL if controller
2571               initialization failed.
2572
2573Comments:
2574          If periodic interrupts are to be disabled but AIOP interrupts
2575          are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
2576
2577          If interrupts are to be completely disabled set IRQNum to 0.
2578
2579          Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
2580          invalid combination.
2581
2582          This function performs initialization of global interrupt modes,
2583          but it does not actually enable global interrupts.  To enable
2584          and disable global interrupts use functions sEnGlobalInt() and
2585          sDisGlobalInt().  Enabling of global interrupts is normally not
2586          done until all other initializations are complete.
2587
2588          Even if interrupts are globally enabled, they must also be
2589          individually enabled for each channel that is to generate
2590          interrupts.
2591
2592Warnings: No range checking on any of the parameters is done.
2593
2594          No context switches are allowed while executing this function.
2595
2596          After this function all AIOPs on the controller are disabled,
2597          they can be enabled with sEnAiop().
2598*/
2599static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
2600                              ByteIO_t * AiopIOList, int AiopIOListSize,
2601                              WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
2602                              int PeriodicOnly, int altChanRingIndicator,
2603                              int UPCIRingInd)
2604{
2605        int i;
2606        ByteIO_t io;
2607
2608        CtlP->AltChanRingIndicator = altChanRingIndicator;
2609        CtlP->UPCIRingInd = UPCIRingInd;
2610        CtlP->CtlNum = CtlNum;
2611        CtlP->CtlID = CTLID_0001;       /* controller release 1 */
2612        CtlP->BusType = isPCI;  /* controller release 1 */
2613
2614        if (ConfigIO) {
2615                CtlP->isUPCI = 1;
2616                CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL;
2617                CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL;
2618                CtlP->AiopIntrBits = upci_aiop_intr_bits;
2619        } else {
2620                CtlP->isUPCI = 0;
2621                CtlP->PCIIO =
2622                    (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC);
2623                CtlP->AiopIntrBits = aiop_intr_bits;
2624        }
2625
2626        sPCIControllerEOI(CtlP);        /* clear EOI if warm init */
2627        /* Init AIOPs */
2628        CtlP->NumAiop = 0;
2629        for (i = 0; i < AiopIOListSize; i++) {
2630                io = AiopIOList[i];
2631                CtlP->AiopIO[i] = (WordIO_t) io;
2632                CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
2633
2634                CtlP->AiopID[i] = sReadAiopID(io);      /* read AIOP ID */
2635                if (CtlP->AiopID[i] == AIOPID_NULL)     /* if AIOP does not exist */
2636                        break;  /* done looking for AIOPs */
2637
2638                CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */
2639                sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE);    /* clock prescaler */
2640                sOutB(io + _INDX_DATA, sClockPrescale);
2641                CtlP->NumAiop++;        /* bump count of AIOPs */
2642        }
2643
2644        if (CtlP->NumAiop == 0)
2645                return (-1);
2646        else
2647                return (CtlP->NumAiop);
2648}
2649
2650/***************************************************************************
2651Function: sReadAiopID
2652Purpose:  Read the AIOP idenfication number directly from an AIOP.
2653Call:     sReadAiopID(io)
2654          ByteIO_t io: AIOP base I/O address
2655Return:   int: Flag AIOPID_XXXX if a valid AIOP is found, where X
2656                 is replace by an identifying number.
2657          Flag AIOPID_NULL if no valid AIOP is found
2658Warnings: No context switches are allowed while executing this function.
2659
2660*/
2661static int sReadAiopID(ByteIO_t io)
2662{
2663        Byte_t AiopID;          /* ID byte from AIOP */
2664
2665        sOutB(io + _CMD_REG, RESET_ALL);        /* reset AIOP */
2666        sOutB(io + _CMD_REG, 0x0);
2667        AiopID = sInW(io + _CHN_STAT0) & 0x07;
2668        if (AiopID == 0x06)
2669                return (1);
2670        else                    /* AIOP does not exist */
2671                return (-1);
2672}
2673
2674/***************************************************************************
2675Function: sReadAiopNumChan
2676Purpose:  Read the number of channels available in an AIOP directly from
2677          an AIOP.
2678Call:     sReadAiopNumChan(io)
2679          WordIO_t io: AIOP base I/O address
2680Return:   int: The number of channels available
2681Comments: The number of channels is determined by write/reads from identical
2682          offsets within the SRAM address spaces for channels 0 and 4.
2683          If the channel 4 space is mirrored to channel 0 it is a 4 channel
2684          AIOP, otherwise it is an 8 channel.
2685Warnings: No context switches are allowed while executing this function.
2686*/
2687static int sReadAiopNumChan(WordIO_t io)
2688{
2689        Word_t x;
2690        static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 };
2691
2692        /* write to chan 0 SRAM */
2693        out32((DWordIO_t) io + _INDX_ADDR, R);
2694        sOutW(io + _INDX_ADDR, 0);      /* read from SRAM, chan 0 */
2695        x = sInW(io + _INDX_DATA);
2696        sOutW(io + _INDX_ADDR, 0x4000); /* read from SRAM, chan 4 */
2697        if (x != sInW(io + _INDX_DATA)) /* if different must be 8 chan */
2698                return (8);
2699        else
2700                return (4);
2701}
2702
2703/***************************************************************************
2704Function: sInitChan
2705Purpose:  Initialization of a channel and channel structure
2706Call:     sInitChan(CtlP,ChP,AiopNum,ChanNum)
2707          CONTROLLER_T *CtlP; Ptr to controller structure
2708          CHANNEL_T *ChP; Ptr to channel structure
2709          int AiopNum; AIOP number within controller
2710          int ChanNum; Channel number within AIOP
2711Return:   int: 1 if initialization succeeded, 0 if it fails because channel
2712               number exceeds number of channels available in AIOP.
2713Comments: This function must be called before a channel can be used.
2714Warnings: No range checking on any of the parameters is done.
2715
2716          No context switches are allowed while executing this function.
2717*/
2718static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
2719                     int ChanNum)
2720{
2721        int i;
2722        WordIO_t AiopIO;
2723        WordIO_t ChIOOff;
2724        Byte_t *ChR;
2725        Word_t ChOff;
2726        static Byte_t R[4];
2727        int brd9600;
2728
2729        if (ChanNum >= CtlP->AiopNumChan[AiopNum])
2730                return 0;       /* exceeds num chans in AIOP */
2731
2732        /* Channel, AIOP, and controller identifiers */
2733        ChP->CtlP = CtlP;
2734        ChP->ChanID = CtlP->AiopID[AiopNum];
2735        ChP->AiopNum = AiopNum;
2736        ChP->ChanNum = ChanNum;
2737
2738        /* Global direct addresses */
2739        AiopIO = CtlP->AiopIO[AiopNum];
2740        ChP->Cmd = (ByteIO_t) AiopIO + _CMD_REG;
2741        ChP->IntChan = (ByteIO_t) AiopIO + _INT_CHAN;
2742        ChP->IntMask = (ByteIO_t) AiopIO + _INT_MASK;
2743        ChP->IndexAddr = (DWordIO_t) AiopIO + _INDX_ADDR;
2744        ChP->IndexData = AiopIO + _INDX_DATA;
2745
2746        /* Channel direct addresses */
2747        ChIOOff = AiopIO + ChP->ChanNum * 2;
2748        ChP->TxRxData = ChIOOff + _TD0;
2749        ChP->ChanStat = ChIOOff + _CHN_STAT0;
2750        ChP->TxRxCount = ChIOOff + _FIFO_CNT0;
2751        ChP->IntID = (ByteIO_t) AiopIO + ChP->ChanNum + _INT_ID0;
2752
2753        /* Initialize the channel from the RData array */
2754        for (i = 0; i < RDATASIZE; i += 4) {
2755                R[0] = RData[i];
2756                R[1] = RData[i + 1] + 0x10 * ChanNum;
2757                R[2] = RData[i + 2];
2758                R[3] = RData[i + 3];
2759                out32(ChP->IndexAddr, R);
2760        }
2761
2762        ChR = ChP->R;
2763        for (i = 0; i < RREGDATASIZE; i += 4) {
2764                ChR[i] = RRegData[i];
2765                ChR[i + 1] = RRegData[i + 1] + 0x10 * ChanNum;
2766                ChR[i + 2] = RRegData[i + 2];
2767                ChR[i + 3] = RRegData[i + 3];
2768        }
2769
2770        /* Indexed registers */
2771        ChOff = (Word_t) ChanNum *0x1000;
2772
2773        if (sClockPrescale == 0x14)
2774                brd9600 = 47;
2775        else
2776                brd9600 = 23;
2777
2778        ChP->BaudDiv[0] = (Byte_t) (ChOff + _BAUD);
2779        ChP->BaudDiv[1] = (Byte_t) ((ChOff + _BAUD) >> 8);
2780        ChP->BaudDiv[2] = (Byte_t) brd9600;
2781        ChP->BaudDiv[3] = (Byte_t) (brd9600 >> 8);
2782        out32(ChP->IndexAddr, ChP->BaudDiv);
2783
2784        ChP->TxControl[0] = (Byte_t) (ChOff + _TX_CTRL);
2785        ChP->TxControl[1] = (Byte_t) ((ChOff + _TX_CTRL) >> 8);
2786        ChP->TxControl[2] = 0;
2787        ChP->TxControl[3] = 0;
2788        out32(ChP->IndexAddr, ChP->TxControl);
2789
2790        ChP->RxControl[0] = (Byte_t) (ChOff + _RX_CTRL);
2791        ChP->RxControl[1] = (Byte_t) ((ChOff + _RX_CTRL) >> 8);
2792        ChP->RxControl[2] = 0;
2793        ChP->RxControl[3] = 0;
2794        out32(ChP->IndexAddr, ChP->RxControl);
2795
2796        ChP->TxEnables[0] = (Byte_t) (ChOff + _TX_ENBLS);
2797        ChP->TxEnables[1] = (Byte_t) ((ChOff + _TX_ENBLS) >> 8);
2798        ChP->TxEnables[2] = 0;
2799        ChP->TxEnables[3] = 0;
2800        out32(ChP->IndexAddr, ChP->TxEnables);
2801
2802        ChP->TxCompare[0] = (Byte_t) (ChOff + _TXCMP1);
2803        ChP->TxCompare[1] = (Byte_t) ((ChOff + _TXCMP1) >> 8);
2804        ChP->TxCompare[2] = 0;
2805        ChP->TxCompare[3] = 0;
2806        out32(ChP->IndexAddr, ChP->TxCompare);
2807
2808        ChP->TxReplace1[0] = (Byte_t) (ChOff + _TXREP1B1);
2809        ChP->TxReplace1[1] = (Byte_t) ((ChOff + _TXREP1B1) >> 8);
2810        ChP->TxReplace1[2] = 0;
2811        ChP->TxReplace1[3] = 0;
2812        out32(ChP->IndexAddr, ChP->TxReplace1);
2813
2814        ChP->TxReplace2[0] = (Byte_t) (ChOff + _TXREP2);
2815        ChP->TxReplace2[1] = (Byte_t) ((ChOff + _TXREP2) >> 8);
2816        ChP->TxReplace2[2] = 0;
2817        ChP->TxReplace2[3] = 0;
2818        out32(ChP->IndexAddr, ChP->TxReplace2);
2819
2820        ChP->TxFIFOPtrs = ChOff + _TXF_OUTP;
2821        ChP->TxFIFO = ChOff + _TX_FIFO;
2822
2823        sOutB(ChP->Cmd, (Byte_t) ChanNum | RESTXFCNT);  /* apply reset Tx FIFO count */
2824        sOutB(ChP->Cmd, (Byte_t) ChanNum);      /* remove reset Tx FIFO count */
2825        sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs);      /* clear Tx in/out ptrs */
2826        sOutW(ChP->IndexData, 0);
2827        ChP->RxFIFOPtrs = ChOff + _RXF_OUTP;
2828        ChP->RxFIFO = ChOff + _RX_FIFO;
2829
2830        sOutB(ChP->Cmd, (Byte_t) ChanNum | RESRXFCNT);  /* apply reset Rx FIFO count */
2831        sOutB(ChP->Cmd, (Byte_t) ChanNum);      /* remove reset Rx FIFO count */
2832        sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs);      /* clear Rx out ptr */
2833        sOutW(ChP->IndexData, 0);
2834        sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2);  /* clear Rx in ptr */
2835        sOutW(ChP->IndexData, 0);
2836        ChP->TxPrioCnt = ChOff + _TXP_CNT;
2837        sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioCnt);
2838        sOutB(ChP->IndexData, 0);
2839        ChP->TxPrioPtr = ChOff + _TXP_PNTR;
2840        sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioPtr);
2841        sOutB(ChP->IndexData, 0);
2842        ChP->TxPrioBuf = ChOff + _TXP_BUF;
2843        sEnRxProcessor(ChP);    /* start the Rx processor */
2844
2845        return 1;
2846}
2847
2848/***************************************************************************
2849Function: sStopRxProcessor
2850Purpose:  Stop the receive processor from processing a channel.
2851Call:     sStopRxProcessor(ChP)
2852          CHANNEL_T *ChP; Ptr to channel structure
2853
2854Comments: The receive processor can be started again with sStartRxProcessor().
2855          This function causes the receive processor to skip over the
2856          stopped channel.  It does not stop it from processing other channels.
2857
2858Warnings: No context switches are allowed while executing this function.
2859
2860          Do not leave the receive processor stopped for more than one
2861          character time.
2862
2863          After calling this function a delay of 4 uS is required to ensure
2864          that the receive processor is no longer processing this channel.
2865*/
2866static void sStopRxProcessor(CHANNEL_T * ChP)
2867{
2868        Byte_t R[4];
2869
2870        R[0] = ChP->R[0];
2871        R[1] = ChP->R[1];
2872        R[2] = 0x0a;
2873        R[3] = ChP->R[3];
2874        out32(ChP->IndexAddr, R);
2875}
2876
2877/***************************************************************************
2878Function: sFlushRxFIFO
2879Purpose:  Flush the Rx FIFO
2880Call:     sFlushRxFIFO(ChP)
2881          CHANNEL_T *ChP; Ptr to channel structure
2882Return:   void
2883Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
2884          while it is being flushed the receive processor is stopped
2885          and the transmitter is disabled.  After these operations a
2886          4 uS delay is done before clearing the pointers to allow
2887          the receive processor to stop.  These items are handled inside
2888          this function.
2889Warnings: No context switches are allowed while executing this function.
2890*/
2891static void sFlushRxFIFO(CHANNEL_T * ChP)
2892{
2893        int i;
2894        Byte_t Ch;              /* channel number within AIOP */
2895        int RxFIFOEnabled;      /* 1 if Rx FIFO enabled */
2896
2897        if (sGetRxCnt(ChP) == 0)        /* Rx FIFO empty */
2898                return;         /* don't need to flush */
2899
2900        RxFIFOEnabled = 0;
2901        if (ChP->R[0x32] == 0x08) {     /* Rx FIFO is enabled */
2902                RxFIFOEnabled = 1;
2903                sDisRxFIFO(ChP);        /* disable it */
2904                for (i = 0; i < 2000 / 200; i++)        /* delay 2 uS to allow proc to disable FIFO */
2905                        sInB(ChP->IntChan);     /* depends on bus i/o timing */
2906        }
2907        sGetChanStatus(ChP);    /* clear any pending Rx errors in chan stat */
2908        Ch = (Byte_t) sGetChanNum(ChP);
2909        sOutB(ChP->Cmd, Ch | RESRXFCNT);        /* apply reset Rx FIFO count */
2910        sOutB(ChP->Cmd, Ch);    /* remove reset Rx FIFO count */
2911        sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs);      /* clear Rx out ptr */
2912        sOutW(ChP->IndexData, 0);
2913        sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2);  /* clear Rx in ptr */
2914        sOutW(ChP->IndexData, 0);
2915        if (RxFIFOEnabled)
2916                sEnRxFIFO(ChP); /* enable Rx FIFO */
2917}
2918
2919/***************************************************************************
2920Function: sFlushTxFIFO
2921Purpose:  Flush the Tx FIFO
2922Call:     sFlushTxFIFO(ChP)
2923          CHANNEL_T *ChP; Ptr to channel structure
2924Return:   void
2925Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
2926          while it is being flushed the receive processor is stopped
2927          and the transmitter is disabled.  After these operations a
2928          4 uS delay is done before clearing the pointers to allow
2929          the receive processor to stop.  These items are handled inside
2930          this function.
2931Warnings: No context switches are allowed while executing this function.
2932*/
2933static void sFlushTxFIFO(CHANNEL_T * ChP)
2934{
2935        int i;
2936        Byte_t Ch;              /* channel number within AIOP */
2937        int TxEnabled;          /* 1 if transmitter enabled */
2938
2939        if (sGetTxCnt(ChP) == 0)        /* Tx FIFO empty */
2940                return;         /* don't need to flush */
2941
2942        TxEnabled = 0;
2943        if (ChP->TxControl[3] & TX_ENABLE) {
2944                TxEnabled = 1;
2945                sDisTransmit(ChP);      /* disable transmitter */
2946        }
2947        sStopRxProcessor(ChP);  /* stop Rx processor */
2948        for (i = 0; i < 4000 / 200; i++)        /* delay 4 uS to allow proc to stop */
2949                sInB(ChP->IntChan);     /* depends on bus i/o timing */
2950        Ch = (Byte_t) sGetChanNum(ChP);
2951        sOutB(ChP->Cmd, Ch | RESTXFCNT);        /* apply reset Tx FIFO count */
2952        sOutB(ChP->Cmd, Ch);    /* remove reset Tx FIFO count */
2953        sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs);      /* clear Tx in/out ptrs */
2954        sOutW(ChP->IndexData, 0);
2955        if (TxEnabled)
2956                sEnTransmit(ChP);       /* enable transmitter */
2957        sStartRxProcessor(ChP); /* restart Rx processor */
2958}
2959
2960/***************************************************************************
2961Function: sWriteTxPrioByte
2962Purpose:  Write a byte of priority transmit data to a channel
2963Call:     sWriteTxPrioByte(ChP,Data)
2964          CHANNEL_T *ChP; Ptr to channel structure
2965          Byte_t Data; The transmit data byte
2966
2967Return:   int: 1 if the bytes is successfully written, otherwise 0.
2968
2969Comments: The priority byte is transmitted before any data in the Tx FIFO.
2970
2971Warnings: No context switches are allowed while executing this function.
2972*/
2973static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
2974{
2975        Byte_t DWBuf[4];        /* buffer for double word writes */
2976        Word_t *WordPtr;        /* must be far because Win SS != DS */
2977        register DWordIO_t IndexAddr;
2978
2979        if (sGetTxCnt(ChP) > 1) {       /* write it to Tx priority buffer */
2980                IndexAddr = ChP->IndexAddr;
2981                sOutW((WordIO_t) IndexAddr, ChP->TxPrioCnt);    /* get priority buffer status */
2982                if (sInB((ByteIO_t) ChP->IndexData) & PRI_PEND) /* priority buffer busy */
2983                        return (0);     /* nothing sent */
2984
2985                WordPtr = (Word_t *) (&DWBuf[0]);
2986                *WordPtr = ChP->TxPrioBuf;      /* data byte address */
2987
2988                DWBuf[2] = Data;        /* data byte value */
2989                out32(IndexAddr, DWBuf);        /* write it out */
2990
2991                *WordPtr = ChP->TxPrioCnt;      /* Tx priority count address */
2992
2993                DWBuf[2] = PRI_PEND + 1;        /* indicate 1 byte pending */
2994                DWBuf[3] = 0;   /* priority buffer pointer */
2995                out32(IndexAddr, DWBuf);        /* write it out */
2996        } else {                /* write it to Tx FIFO */
2997
2998                sWriteTxByte(sGetTxRxDataIO(ChP), Data);
2999        }
3000        return (1);             /* 1 byte sent */
3001}
3002
3003/***************************************************************************
3004Function: sEnInterrupts
3005Purpose:  Enable one or more interrupts for a channel
3006Call:     sEnInterrupts(ChP,Flags)
3007          CHANNEL_T *ChP; Ptr to channel structure
3008          Word_t Flags: Interrupt enable flags, can be any combination
3009             of the following flags:
3010                TXINT_EN:   Interrupt on Tx FIFO empty
3011                RXINT_EN:   Interrupt on Rx FIFO at trigger level (see
3012                            sSetRxTrigger())
3013                SRCINT_EN:  Interrupt on SRC (Special Rx Condition)
3014                MCINT_EN:   Interrupt on modem input change
3015                CHANINT_EN: Allow channel interrupt signal to the AIOP's
3016                            Interrupt Channel Register.
3017Return:   void
3018Comments: If an interrupt enable flag is set in Flags, that interrupt will be
3019          enabled.  If an interrupt enable flag is not set in Flags, that
3020          interrupt will not be changed.  Interrupts can be disabled with
3021          function sDisInterrupts().
3022
3023          This function sets the appropriate bit for the channel in the AIOP's
3024          Interrupt Mask Register if the CHANINT_EN flag is set.  This allows
3025          this channel's bit to be set in the AIOP's Interrupt Channel Register.
3026
3027          Interrupts must also be globally enabled before channel interrupts
3028          will be passed on to the host.  This is done with function
3029          sEnGlobalInt().
3030
3031          In some cases it may be desirable to disable interrupts globally but
3032          enable channel interrupts.  This would allow the global interrupt
3033          status register to be used to determine which AIOPs need service.
3034*/
3035static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
3036{
3037        Byte_t Mask;            /* Interrupt Mask Register */
3038
3039        ChP->RxControl[2] |=
3040            ((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
3041
3042        out32(ChP->IndexAddr, ChP->RxControl);
3043
3044        ChP->TxControl[2] |= ((Byte_t) Flags & TXINT_EN);
3045
3046        out32(ChP->IndexAddr, ChP->TxControl);
3047
3048        if (Flags & CHANINT_EN) {
3049                Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum];
3050                sOutB(ChP->IntMask, Mask);
3051        }
3052}
3053
3054/***************************************************************************
3055Function: sDisInterrupts
3056Purpose:  Disable one or more interrupts for a channel
3057Call:     sDisInterrupts(ChP,Flags)
3058          CHANNEL_T *ChP; Ptr to channel structure
3059          Word_t Flags: Interrupt flags, can be any combination
3060             of the following flags:
3061                TXINT_EN:   Interrupt on Tx FIFO empty
3062                RXINT_EN:   Interrupt on Rx FIFO at trigger level (see
3063                            sSetRxTrigger())
3064                SRCINT_EN:  Interrupt on SRC (Special Rx Condition)
3065                MCINT_EN:   Interrupt on modem input change
3066                CHANINT_EN: Disable channel interrupt signal to the
3067                            AIOP's Interrupt Channel Register.
3068Return:   void
3069Comments: If an interrupt flag is set in Flags, that interrupt will be
3070          disabled.  If an interrupt flag is not set in Flags, that
3071          interrupt will not be changed.  Interrupts can be enabled with
3072          function sEnInterrupts().
3073
3074          This function clears the appropriate bit for the channel in the AIOP's
3075          Interrupt Mask Register if the CHANINT_EN flag is set.  This blocks
3076          this channel's bit from being set in the AIOP's Interrupt Channel
3077          Register.
3078*/
3079static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
3080{
3081        Byte_t Mask;            /* Interrupt Mask Register */
3082
3083        ChP->RxControl[2] &=
3084            ~((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
3085        out32(ChP->IndexAddr, ChP->RxControl);
3086        ChP->TxControl[2] &= ~((Byte_t) Flags & TXINT_EN);
3087        out32(ChP->IndexAddr, ChP->TxControl);
3088
3089        if (Flags & CHANINT_EN) {
3090                Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum];
3091                sOutB(ChP->IntMask, Mask);
3092        }
3093}
3094
3095static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
3096{
3097        sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum);
3098}
3099
3100/*
3101 *  Not an official SSCI function, but how to reset RocketModems.
3102 *  ISA bus version
3103 */
3104static void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
3105{
3106        ByteIO_t addr;
3107        Byte_t val;
3108
3109        addr = CtlP->AiopIO[0] + 0x400;
3110        val = sInB(CtlP->MReg3IO);
3111        /* if AIOP[1] is not enabled, enable it */
3112        if ((val & 2) == 0) {
3113                val = sInB(CtlP->MReg2IO);
3114                sOutB(CtlP->MReg2IO, (val & 0xfc) | (1 & 0x03));
3115                sOutB(CtlP->MBaseIO, (unsigned char) (addr >> 6));
3116        }
3117
3118        sEnAiop(CtlP, 1);
3119        if (!on)
3120                addr += 8;
3121        sOutB(addr + chan, 0);  /* apply or remove reset */
3122        sDisAiop(CtlP, 1);
3123}
3124
3125/*
3126 *  Not an official SSCI function, but how to reset RocketModems.
3127 *  PCI bus version
3128 */
3129static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
3130{
3131        ByteIO_t addr;
3132
3133        addr = CtlP->AiopIO[0] + 0x40;  /* 2nd AIOP */
3134        if (!on)
3135                addr += 8;
3136        sOutB(addr + chan, 0);  /* apply or remove reset */
3137}
3138
3139/*  Resets the speaker controller on RocketModem II and III devices */
3140static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model)
3141{
3142        ByteIO_t addr;
3143
3144        /* RocketModem II speaker control is at the 8th port location of offset 0x40 */
3145        if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) {
3146                addr = CtlP->AiopIO[0] + 0x4F;
3147                sOutB(addr, 0);
3148        }
3149
3150        /* RocketModem III speaker control is at the 1st port location of offset 0x80 */
3151        if ((model == MODEL_UPCI_RM3_8PORT)
3152            || (model == MODEL_UPCI_RM3_4PORT)) {
3153                addr = CtlP->AiopIO[0] + 0x88;
3154                sOutB(addr, 0);
3155        }
3156}
3157
3158/*  Returns the line number given the controller (board), aiop and channel number */
3159static unsigned char GetLineNumber(int ctrl, int aiop, int ch)
3160{
3161        return lineNumbers[(ctrl << 5) | (aiop << 3) | ch];
3162}
3163
3164/*
3165 *  Stores the line number associated with a given controller (board), aiop
3166 *  and channel number.  
3167 *  Returns:  The line number assigned 
3168 */
3169static unsigned char SetLineNumber(int ctrl, int aiop, int ch)
3170{
3171        lineNumbers[(ctrl << 5) | (aiop << 3) | ch] = nextLineNumber++;
3172        return (nextLineNumber - 1);
3173}
3174
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.