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