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