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

Archive Download this file



interactive