OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [char/] [rocket.c] - Blame information for rev 65

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.