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