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