Root/drivers/tty/rocket.c

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

Archive Download this file



interactive