[PATCH] sysctl: x86_64: remove unnecessary use of insert_at_head
[linux-2.6.git] / drivers / char / rocket.c
blob76357c855ce3b0324c5dd26873ec85cf3971cc78
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 #ifdef PCI_NUM_RESOURCES
44 #define PCI_BASE_ADDRESS(dev, r) ((dev)->resource[r].start)
45 #else
46 #define PCI_BASE_ADDRESS(dev, r) ((dev)->base_address[r])
47 #endif
49 #define ROCKET_PARANOIA_CHECK
50 #define ROCKET_DISABLE_SIMUSAGE
52 #undef ROCKET_SOFT_FLOW
53 #undef ROCKET_DEBUG_OPEN
54 #undef ROCKET_DEBUG_INTR
55 #undef ROCKET_DEBUG_WRITE
56 #undef ROCKET_DEBUG_FLOW
57 #undef ROCKET_DEBUG_THROTTLE
58 #undef ROCKET_DEBUG_WAIT_UNTIL_SENT
59 #undef ROCKET_DEBUG_RECEIVE
60 #undef ROCKET_DEBUG_HANGUP
61 #undef REV_PCI_ORDER
62 #undef ROCKET_DEBUG_IO
64 #define POLL_PERIOD HZ/100 /* Polling period .01 seconds (10ms) */
66 /****** Kernel includes ******/
68 #ifdef MODVERSIONS
69 #include <config/modversions.h>
70 #endif
72 #include <linux/module.h>
73 #include <linux/errno.h>
74 #include <linux/major.h>
75 #include <linux/kernel.h>
76 #include <linux/signal.h>
77 #include <linux/slab.h>
78 #include <linux/mm.h>
79 #include <linux/sched.h>
80 #include <linux/timer.h>
81 #include <linux/interrupt.h>
82 #include <linux/tty.h>
83 #include <linux/tty_driver.h>
84 #include <linux/tty_flip.h>
85 #include <linux/string.h>
86 #include <linux/fcntl.h>
87 #include <linux/ptrace.h>
88 #include <linux/ioport.h>
89 #include <linux/delay.h>
90 #include <linux/wait.h>
91 #include <linux/pci.h>
92 #include <asm/uaccess.h>
93 #include <asm/atomic.h>
94 #include <linux/bitops.h>
95 #include <linux/spinlock.h>
96 #include <asm/semaphore.h>
97 #include <linux/init.h>
99 /****** RocketPort includes ******/
101 #include "rocket_int.h"
102 #include "rocket.h"
104 #define ROCKET_VERSION "2.09"
105 #define ROCKET_DATE "12-June-2003"
107 /****** RocketPort Local Variables ******/
109 static void rp_do_poll(unsigned long dummy);
111 static struct tty_driver *rocket_driver;
113 static struct rocket_version driver_version = {
114 ROCKET_VERSION, ROCKET_DATE
117 static struct r_port *rp_table[MAX_RP_PORTS]; /* The main repository of serial port state information. */
118 static unsigned int xmit_flags[NUM_BOARDS]; /* Bit significant, indicates port had data to transmit. */
119 /* eg. Bit 0 indicates port 0 has xmit data, ... */
120 static atomic_t rp_num_ports_open; /* Number of serial ports open */
121 static DEFINE_TIMER(rocket_timer, rp_do_poll, 0, 0);
123 static unsigned long board1; /* ISA addresses, retrieved from rocketport.conf */
124 static unsigned long board2;
125 static unsigned long board3;
126 static unsigned long board4;
127 static unsigned long controller;
128 static int support_low_speed;
129 static unsigned long modem1;
130 static unsigned long modem2;
131 static unsigned long modem3;
132 static unsigned long modem4;
133 static unsigned long pc104_1[8];
134 static unsigned long pc104_2[8];
135 static unsigned long pc104_3[8];
136 static unsigned long pc104_4[8];
137 static unsigned long *pc104[4] = { pc104_1, pc104_2, pc104_3, pc104_4 };
139 static int rp_baud_base[NUM_BOARDS]; /* Board config info (Someday make a per-board structure) */
140 static unsigned long rcktpt_io_addr[NUM_BOARDS];
141 static int rcktpt_type[NUM_BOARDS];
142 static int is_PCI[NUM_BOARDS];
143 static rocketModel_t rocketModel[NUM_BOARDS];
144 static int max_board;
147 * The following arrays define the interrupt bits corresponding to each AIOP.
148 * These bits are different between the ISA and regular PCI boards and the
149 * Universal PCI boards.
152 static Word_t aiop_intr_bits[AIOP_CTL_SIZE] = {
153 AIOP_INTR_BIT_0,
154 AIOP_INTR_BIT_1,
155 AIOP_INTR_BIT_2,
156 AIOP_INTR_BIT_3
159 static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = {
160 UPCI_AIOP_INTR_BIT_0,
161 UPCI_AIOP_INTR_BIT_1,
162 UPCI_AIOP_INTR_BIT_2,
163 UPCI_AIOP_INTR_BIT_3
166 static Byte_t RData[RDATASIZE] = {
167 0x00, 0x09, 0xf6, 0x82,
168 0x02, 0x09, 0x86, 0xfb,
169 0x04, 0x09, 0x00, 0x0a,
170 0x06, 0x09, 0x01, 0x0a,
171 0x08, 0x09, 0x8a, 0x13,
172 0x0a, 0x09, 0xc5, 0x11,
173 0x0c, 0x09, 0x86, 0x85,
174 0x0e, 0x09, 0x20, 0x0a,
175 0x10, 0x09, 0x21, 0x0a,
176 0x12, 0x09, 0x41, 0xff,
177 0x14, 0x09, 0x82, 0x00,
178 0x16, 0x09, 0x82, 0x7b,
179 0x18, 0x09, 0x8a, 0x7d,
180 0x1a, 0x09, 0x88, 0x81,
181 0x1c, 0x09, 0x86, 0x7a,
182 0x1e, 0x09, 0x84, 0x81,
183 0x20, 0x09, 0x82, 0x7c,
184 0x22, 0x09, 0x0a, 0x0a
187 static Byte_t RRegData[RREGDATASIZE] = {
188 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */
189 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */
190 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */
191 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */
192 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */
193 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */
194 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */
195 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */
196 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */
197 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */
198 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */
199 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */
200 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */
203 static CONTROLLER_T sController[CTL_SIZE] = {
204 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
205 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
206 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
207 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
208 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
209 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
210 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
211 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
214 static Byte_t sBitMapClrTbl[8] = {
215 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
218 static Byte_t sBitMapSetTbl[8] = {
219 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
222 static int sClockPrescale = 0x14;
225 * Line number is the ttySIx number (x), the Minor number. We
226 * assign them sequentially, starting at zero. The following
227 * array keeps track of the line number assigned to a given board/aiop/channel.
229 static unsigned char lineNumbers[MAX_RP_PORTS];
230 static unsigned long nextLineNumber;
232 /***** RocketPort Static Prototypes *********/
233 static int __init init_ISA(int i);
234 static void rp_wait_until_sent(struct tty_struct *tty, int timeout);
235 static void rp_flush_buffer(struct tty_struct *tty);
236 static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model);
237 static unsigned char GetLineNumber(int ctrl, int aiop, int ch);
238 static unsigned char SetLineNumber(int ctrl, int aiop, int ch);
239 static void rp_start(struct tty_struct *tty);
240 static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
241 int ChanNum);
242 static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
243 static void sFlushRxFIFO(CHANNEL_T * ChP);
244 static void sFlushTxFIFO(CHANNEL_T * ChP);
245 static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
246 static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
247 static void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
248 static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
249 static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
250 static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
251 ByteIO_t * AiopIOList, int AiopIOListSize,
252 WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
253 int PeriodicOnly, int altChanRingIndicator,
254 int UPCIRingInd);
255 static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
256 ByteIO_t * AiopIOList, int AiopIOListSize,
257 int IRQNum, Byte_t Frequency, int PeriodicOnly);
258 static int sReadAiopID(ByteIO_t io);
259 static int sReadAiopNumChan(WordIO_t io);
261 MODULE_AUTHOR("Theodore Ts'o");
262 MODULE_DESCRIPTION("Comtrol RocketPort driver");
263 module_param(board1, ulong, 0);
264 MODULE_PARM_DESC(board1, "I/O port for (ISA) board #1");
265 module_param(board2, ulong, 0);
266 MODULE_PARM_DESC(board2, "I/O port for (ISA) board #2");
267 module_param(board3, ulong, 0);
268 MODULE_PARM_DESC(board3, "I/O port for (ISA) board #3");
269 module_param(board4, ulong, 0);
270 MODULE_PARM_DESC(board4, "I/O port for (ISA) board #4");
271 module_param(controller, ulong, 0);
272 MODULE_PARM_DESC(controller, "I/O port for (ISA) rocketport controller");
273 module_param(support_low_speed, bool, 0);
274 MODULE_PARM_DESC(support_low_speed, "1 means support 50 baud, 0 means support 460400 baud");
275 module_param(modem1, ulong, 0);
276 MODULE_PARM_DESC(modem1, "1 means (ISA) board #1 is a RocketModem");
277 module_param(modem2, ulong, 0);
278 MODULE_PARM_DESC(modem2, "1 means (ISA) board #2 is a RocketModem");
279 module_param(modem3, ulong, 0);
280 MODULE_PARM_DESC(modem3, "1 means (ISA) board #3 is a RocketModem");
281 module_param(modem4, ulong, 0);
282 MODULE_PARM_DESC(modem4, "1 means (ISA) board #4 is a RocketModem");
283 module_param_array(pc104_1, ulong, NULL, 0);
284 MODULE_PARM_DESC(pc104_1, "set interface types for ISA(PC104) board #1 (e.g. pc104_1=232,232,485,485,...");
285 module_param_array(pc104_2, ulong, NULL, 0);
286 MODULE_PARM_DESC(pc104_2, "set interface types for ISA(PC104) board #2 (e.g. pc104_2=232,232,485,485,...");
287 module_param_array(pc104_3, ulong, NULL, 0);
288 MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc104_3=232,232,485,485,...");
289 module_param_array(pc104_4, ulong, NULL, 0);
290 MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,...");
292 static int rp_init(void);
293 static void rp_cleanup_module(void);
295 module_init(rp_init);
296 module_exit(rp_cleanup_module);
299 MODULE_LICENSE("Dual BSD/GPL");
301 /*************************************************************************/
302 /* Module code starts here */
304 static inline int rocket_paranoia_check(struct r_port *info,
305 const char *routine)
307 #ifdef ROCKET_PARANOIA_CHECK
308 if (!info)
309 return 1;
310 if (info->magic != RPORT_MAGIC) {
311 printk(KERN_INFO "Warning: bad magic number for rocketport struct in %s\n",
312 routine);
313 return 1;
315 #endif
316 return 0;
320 /* Serial port receive data function. Called (from timer poll) when an AIOPIC signals
321 * that receive data is present on a serial port. Pulls data from FIFO, moves it into the
322 * tty layer.
324 static void rp_do_receive(struct r_port *info,
325 struct tty_struct *tty,
326 CHANNEL_t * cp, unsigned int ChanStatus)
328 unsigned int CharNStat;
329 int ToRecv, wRecv, space;
330 unsigned char *cbuf;
332 ToRecv = sGetRxCnt(cp);
333 #ifdef ROCKET_DEBUG_INTR
334 printk(KERN_INFO "rp_do_receive(%d)...", ToRecv);
335 #endif
336 if (ToRecv == 0)
337 return;
340 * if status indicates there are errored characters in the
341 * FIFO, then enter status mode (a word in FIFO holds
342 * character and status).
344 if (ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) {
345 if (!(ChanStatus & STATMODE)) {
346 #ifdef ROCKET_DEBUG_RECEIVE
347 printk(KERN_INFO "Entering STATMODE...");
348 #endif
349 ChanStatus |= STATMODE;
350 sEnRxStatusMode(cp);
355 * if we previously entered status mode, then read down the
356 * FIFO one word at a time, pulling apart the character and
357 * the status. Update error counters depending on status
359 if (ChanStatus & STATMODE) {
360 #ifdef ROCKET_DEBUG_RECEIVE
361 printk(KERN_INFO "Ignore %x, read %x...", info->ignore_status_mask,
362 info->read_status_mask);
363 #endif
364 while (ToRecv) {
365 char flag;
367 CharNStat = sInW(sGetTxRxDataIO(cp));
368 #ifdef ROCKET_DEBUG_RECEIVE
369 printk(KERN_INFO "%x...", CharNStat);
370 #endif
371 if (CharNStat & STMBREAKH)
372 CharNStat &= ~(STMFRAMEH | STMPARITYH);
373 if (CharNStat & info->ignore_status_mask) {
374 ToRecv--;
375 continue;
377 CharNStat &= info->read_status_mask;
378 if (CharNStat & STMBREAKH)
379 flag = TTY_BREAK;
380 else if (CharNStat & STMPARITYH)
381 flag = TTY_PARITY;
382 else if (CharNStat & STMFRAMEH)
383 flag = TTY_FRAME;
384 else if (CharNStat & STMRCVROVRH)
385 flag = TTY_OVERRUN;
386 else
387 flag = TTY_NORMAL;
388 tty_insert_flip_char(tty, CharNStat & 0xff, flag);
389 ToRecv--;
393 * after we've emptied the FIFO in status mode, turn
394 * status mode back off
396 if (sGetRxCnt(cp) == 0) {
397 #ifdef ROCKET_DEBUG_RECEIVE
398 printk(KERN_INFO "Status mode off.\n");
399 #endif
400 sDisRxStatusMode(cp);
402 } else {
404 * we aren't in status mode, so read down the FIFO two
405 * characters at time by doing repeated word IO
406 * transfer.
408 space = tty_prepare_flip_string(tty, &cbuf, ToRecv);
409 if (space < ToRecv) {
410 #ifdef ROCKET_DEBUG_RECEIVE
411 printk(KERN_INFO "rp_do_receive:insufficient space ToRecv=%d space=%d\n", ToRecv, space);
412 #endif
413 if (space <= 0)
414 return;
415 ToRecv = space;
417 wRecv = ToRecv >> 1;
418 if (wRecv)
419 sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv);
420 if (ToRecv & 1)
421 cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp));
423 /* Push the data up to the tty layer */
424 tty_flip_buffer_push(tty);
428 * Serial port transmit data function. Called from the timer polling loop as a
429 * result of a bit set in xmit_flags[], indicating data (from the tty layer) is ready
430 * to be sent out the serial port. Data is buffered in rp_table[line].xmit_buf, it is
431 * moved to the port's xmit FIFO. *info is critical data, protected by spinlocks.
433 static void rp_do_transmit(struct r_port *info)
435 int c;
436 CHANNEL_t *cp = &info->channel;
437 struct tty_struct *tty;
438 unsigned long flags;
440 #ifdef ROCKET_DEBUG_INTR
441 printk(KERN_INFO "rp_do_transmit ");
442 #endif
443 if (!info)
444 return;
445 if (!info->tty) {
446 printk(KERN_INFO "rp: WARNING rp_do_transmit called with info->tty==NULL\n");
447 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
448 return;
451 spin_lock_irqsave(&info->slock, flags);
452 tty = info->tty;
453 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
455 /* Loop sending data to FIFO until done or FIFO full */
456 while (1) {
457 if (tty->stopped || tty->hw_stopped)
458 break;
459 c = min(info->xmit_fifo_room, min(info->xmit_cnt, XMIT_BUF_SIZE - info->xmit_tail));
460 if (c <= 0 || info->xmit_fifo_room <= 0)
461 break;
462 sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) (info->xmit_buf + info->xmit_tail), c / 2);
463 if (c & 1)
464 sOutB(sGetTxRxDataIO(cp), info->xmit_buf[info->xmit_tail + c - 1]);
465 info->xmit_tail += c;
466 info->xmit_tail &= XMIT_BUF_SIZE - 1;
467 info->xmit_cnt -= c;
468 info->xmit_fifo_room -= c;
469 #ifdef ROCKET_DEBUG_INTR
470 printk(KERN_INFO "tx %d chars...", c);
471 #endif
474 if (info->xmit_cnt == 0)
475 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
477 if (info->xmit_cnt < WAKEUP_CHARS) {
478 tty_wakeup(tty);
479 #ifdef ROCKETPORT_HAVE_POLL_WAIT
480 wake_up_interruptible(&tty->poll_wait);
481 #endif
484 spin_unlock_irqrestore(&info->slock, flags);
486 #ifdef ROCKET_DEBUG_INTR
487 printk(KERN_INFO "(%d,%d,%d,%d)...", info->xmit_cnt, info->xmit_head,
488 info->xmit_tail, info->xmit_fifo_room);
489 #endif
493 * Called when a serial port signals it has read data in it's RX FIFO.
494 * It checks what interrupts are pending and services them, including
495 * receiving serial data.
497 static void rp_handle_port(struct r_port *info)
499 CHANNEL_t *cp;
500 struct tty_struct *tty;
501 unsigned int IntMask, ChanStatus;
503 if (!info)
504 return;
506 if ((info->flags & ROCKET_INITIALIZED) == 0) {
507 printk(KERN_INFO "rp: WARNING: rp_handle_port called with info->flags & NOT_INIT\n");
508 return;
510 if (!info->tty) {
511 printk(KERN_INFO "rp: WARNING: rp_handle_port called with info->tty==NULL\n");
512 return;
514 cp = &info->channel;
515 tty = info->tty;
517 IntMask = sGetChanIntID(cp) & info->intmask;
518 #ifdef ROCKET_DEBUG_INTR
519 printk(KERN_INFO "rp_interrupt %02x...", 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...", 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->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
550 * The top level polling routine. Repeats every 1/100 HZ (10ms).
552 static void rp_do_poll(unsigned long dummy)
554 CONTROLLER_t *ctlp;
555 int ctrl, aiop, ch, line, i;
556 unsigned int xmitmask;
557 unsigned int CtlMask;
558 unsigned char AiopMask;
559 Word_t bit;
561 /* Walk through all the boards (ctrl's) */
562 for (ctrl = 0; ctrl < max_board; ctrl++) {
563 if (rcktpt_io_addr[ctrl] <= 0)
564 continue;
566 /* Get a ptr to the board's control struct */
567 ctlp = sCtlNumToCtlPtr(ctrl);
569 /* Get the interupt status from the board */
570 #ifdef CONFIG_PCI
571 if (ctlp->BusType == isPCI)
572 CtlMask = sPCIGetControllerIntStatus(ctlp);
573 else
574 #endif
575 CtlMask = sGetControllerIntStatus(ctlp);
577 /* Check if any AIOP read bits are set */
578 for (aiop = 0; CtlMask; aiop++) {
579 bit = ctlp->AiopIntrBits[aiop];
580 if (CtlMask & bit) {
581 CtlMask &= ~bit;
582 AiopMask = sGetAiopIntStatus(ctlp, aiop);
584 /* Check if any port read bits are set */
585 for (ch = 0; AiopMask; AiopMask >>= 1, ch++) {
586 if (AiopMask & 1) {
588 /* Get the line number (/dev/ttyRx number). */
589 /* Read the data from the port. */
590 line = GetLineNumber(ctrl, aiop, ch);
591 rp_handle_port(rp_table[line]);
597 xmitmask = xmit_flags[ctrl];
600 * xmit_flags contains bit-significant flags, indicating there is data
601 * to xmit on the port. Bit 0 is port 0 on this board, bit 1 is port
602 * 1, ... (32 total possible). The variable i has the aiop and ch
603 * numbers encoded in it (port 0-7 are aiop0, 8-15 are aiop1, etc).
605 if (xmitmask) {
606 for (i = 0; i < rocketModel[ctrl].numPorts; i++) {
607 if (xmitmask & (1 << i)) {
608 aiop = (i & 0x18) >> 3;
609 ch = i & 0x07;
610 line = GetLineNumber(ctrl, aiop, ch);
611 rp_do_transmit(rp_table[line]);
618 * Reset the timer so we get called at the next clock tick (10ms).
620 if (atomic_read(&rp_num_ports_open))
621 mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
625 * Initializes the r_port structure for a port, as well as enabling the port on
626 * the board.
627 * Inputs: board, aiop, chan numbers
629 static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
631 unsigned rocketMode;
632 struct r_port *info;
633 int line;
634 CONTROLLER_T *ctlp;
636 /* Get the next available line number */
637 line = SetLineNumber(board, aiop, chan);
639 ctlp = sCtlNumToCtlPtr(board);
641 /* Get a r_port struct for the port, fill it in and save it globally, indexed by line number */
642 info = kmalloc(sizeof (struct r_port), GFP_KERNEL);
643 if (!info) {
644 printk(KERN_INFO "Couldn't allocate info struct for line #%d\n", line);
645 return;
647 memset(info, 0, sizeof (struct r_port));
649 info->magic = RPORT_MAGIC;
650 info->line = line;
651 info->ctlp = ctlp;
652 info->board = board;
653 info->aiop = aiop;
654 info->chan = chan;
655 info->closing_wait = 3000;
656 info->close_delay = 50;
657 init_waitqueue_head(&info->open_wait);
658 init_waitqueue_head(&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_INFO "RocketPort sInitChan(%d, %d, %d) failed!\n", board, aiop, chan);
676 kfree(info);
677 return;
680 rocketMode = info->flags & ROCKET_MODE_MASK;
682 if ((info->flags & ROCKET_RTS_TOGGLE) || (rocketMode == ROCKET_MODE_RS485))
683 sEnRTSToggle(&info->channel);
684 else
685 sDisRTSToggle(&info->channel);
687 if (ctlp->boardType == ROCKET_TYPE_PC104) {
688 switch (rocketMode) {
689 case ROCKET_MODE_RS485:
690 sSetInterfaceMode(&info->channel, InterfaceModeRS485);
691 break;
692 case ROCKET_MODE_RS422:
693 sSetInterfaceMode(&info->channel, InterfaceModeRS422);
694 break;
695 case ROCKET_MODE_RS232:
696 default:
697 if (info->flags & ROCKET_RTS_TOGGLE)
698 sSetInterfaceMode(&info->channel, InterfaceModeRS232T);
699 else
700 sSetInterfaceMode(&info->channel, InterfaceModeRS232);
701 break;
704 spin_lock_init(&info->slock);
705 sema_init(&info->write_sem, 1);
706 rp_table[line] = info;
707 if (pci_dev)
708 tty_register_device(rocket_driver, line, &pci_dev->dev);
712 * Configures a rocketport port according to its termio settings. Called from
713 * user mode into the driver (exception handler). *info CD manipulation is spinlock protected.
715 static void configure_r_port(struct r_port *info,
716 struct ktermios *old_termios)
718 unsigned cflag;
719 unsigned long flags;
720 unsigned rocketMode;
721 int bits, baud, divisor;
722 CHANNEL_t *cp;
724 if (!info->tty || !info->tty->termios)
725 return;
726 cp = &info->channel;
727 cflag = info->tty->termios->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(info->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 info->tty->termios->c_cflag &= ~CBAUD;
763 info->tty->termios->c_cflag |=
764 (old_termios->c_cflag & CBAUD);
765 baud = tty_get_baud_rate(info->tty);
766 if (!baud)
767 baud = 9600;
768 divisor = (rp_baud_base[info->board] / baud) - 1;
770 if (divisor >= 8192 || divisor < 0) {
771 baud = 9600;
772 divisor = (rp_baud_base[info->board] / baud) - 1;
774 info->cps = baud / bits;
775 sSetBaud(cp, divisor);
777 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(info->tty)) {
801 sEnTxSoftFlowCtl(cp);
802 if (I_IXANY(info->tty)) {
803 sEnIXANY(cp);
804 } else {
805 sDisIXANY(cp);
807 sSetTxXONChar(cp, START_CHAR(info->tty));
808 sSetTxXOFFChar(cp, STOP_CHAR(info->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(info->tty))
821 info->read_status_mask |= STMFRAMEH | STMPARITYH;
822 if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
823 info->read_status_mask |= STMBREAKH;
826 * Characters to ignore
828 info->ignore_status_mask = 0;
829 if (I_IGNPAR(info->tty))
830 info->ignore_status_mask |= STMFRAMEH | STMPARITYH;
831 if (I_IGNBRK(info->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(info->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 /* info->count is considered critical, protected by spinlocks. */
871 static int block_til_ready(struct tty_struct *tty, struct file *filp,
872 struct r_port *info)
874 DECLARE_WAITQUEUE(wait, current);
875 int retval;
876 int do_clocal = 0, extra_count = 0;
877 unsigned long flags;
880 * If the device is in the middle of being closed, then block
881 * until it's done, and then try again.
883 if (tty_hung_up_p(filp))
884 return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
885 if (info->flags & ROCKET_CLOSING) {
886 interruptible_sleep_on(&info->close_wait);
887 return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
891 * If non-blocking mode is set, or the port is not enabled,
892 * then make the check up front and then exit.
894 if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
895 info->flags |= ROCKET_NORMAL_ACTIVE;
896 return 0;
898 if (tty->termios->c_cflag & CLOCAL)
899 do_clocal = 1;
902 * Block waiting for the carrier detect and the line to become free. While we are in
903 * this loop, info->count is dropped by one, so that rp_close() knows when to free things.
904 * We restore it upon exit, either normal or abnormal.
906 retval = 0;
907 add_wait_queue(&info->open_wait, &wait);
908 #ifdef ROCKET_DEBUG_OPEN
909 printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, info->count);
910 #endif
911 spin_lock_irqsave(&info->slock, flags);
913 #ifdef ROCKET_DISABLE_SIMUSAGE
914 info->flags |= ROCKET_NORMAL_ACTIVE;
915 #else
916 if (!tty_hung_up_p(filp)) {
917 extra_count = 1;
918 info->count--;
920 #endif
921 info->blocked_open++;
923 spin_unlock_irqrestore(&info->slock, flags);
925 while (1) {
926 if (tty->termios->c_cflag & CBAUD) {
927 sSetDTR(&info->channel);
928 sSetRTS(&info->channel);
930 set_current_state(TASK_INTERRUPTIBLE);
931 if (tty_hung_up_p(filp) || !(info->flags & ROCKET_INITIALIZED)) {
932 if (info->flags & ROCKET_HUP_NOTIFY)
933 retval = -EAGAIN;
934 else
935 retval = -ERESTARTSYS;
936 break;
938 if (!(info->flags & ROCKET_CLOSING) && (do_clocal || (sGetChanStatusLo(&info->channel) & CD_ACT)))
939 break;
940 if (signal_pending(current)) {
941 retval = -ERESTARTSYS;
942 break;
944 #ifdef ROCKET_DEBUG_OPEN
945 printk(KERN_INFO "block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n",
946 info->line, info->count, info->flags);
947 #endif
948 schedule(); /* Don't hold spinlock here, will hang PC */
950 current->state = TASK_RUNNING;
951 remove_wait_queue(&info->open_wait, &wait);
953 spin_lock_irqsave(&info->slock, flags);
955 if (extra_count)
956 info->count++;
957 info->blocked_open--;
959 spin_unlock_irqrestore(&info->slock, flags);
961 #ifdef ROCKET_DEBUG_OPEN
962 printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n",
963 info->line, info->count);
964 #endif
965 if (retval)
966 return retval;
967 info->flags |= ROCKET_NORMAL_ACTIVE;
968 return 0;
972 * Exception handler that opens a serial port. Creates xmit_buf storage, fills in
973 * port's r_port struct. Initializes the port hardware.
975 static int rp_open(struct tty_struct *tty, struct file *filp)
977 struct r_port *info;
978 int line = 0, retval;
979 CHANNEL_t *cp;
980 unsigned long page;
982 line = TTY_GET_LINE(tty);
983 if ((line < 0) || (line >= MAX_RP_PORTS) || ((info = rp_table[line]) == NULL))
984 return -ENXIO;
986 page = __get_free_page(GFP_KERNEL);
987 if (!page)
988 return -ENOMEM;
990 if (info->flags & ROCKET_CLOSING) {
991 interruptible_sleep_on(&info->close_wait);
992 free_page(page);
993 return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
997 * We must not sleep from here until the port is marked fully in use.
999 if (info->xmit_buf)
1000 free_page(page);
1001 else
1002 info->xmit_buf = (unsigned char *) page;
1004 tty->driver_data = info;
1005 info->tty = tty;
1007 if (info->count++ == 0) {
1008 atomic_inc(&rp_num_ports_open);
1010 #ifdef ROCKET_DEBUG_OPEN
1011 printk(KERN_INFO "rocket mod++ = %d...", atomic_read(&rp_num_ports_open));
1012 #endif
1014 #ifdef ROCKET_DEBUG_OPEN
1015 printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->count);
1016 #endif
1019 * Info->count is now 1; so it's safe to sleep now.
1021 info->session = process_session(current);
1022 info->pgrp = process_group(current);
1024 if ((info->flags & ROCKET_INITIALIZED) == 0) {
1025 cp = &info->channel;
1026 sSetRxTrigger(cp, TRIG_1);
1027 if (sGetChanStatus(cp) & CD_ACT)
1028 info->cd_status = 1;
1029 else
1030 info->cd_status = 0;
1031 sDisRxStatusMode(cp);
1032 sFlushRxFIFO(cp);
1033 sFlushTxFIFO(cp);
1035 sEnInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
1036 sSetRxTrigger(cp, TRIG_1);
1038 sGetChanStatus(cp);
1039 sDisRxStatusMode(cp);
1040 sClrTxXOFF(cp);
1042 sDisCTSFlowCtl(cp);
1043 sDisTxSoftFlowCtl(cp);
1045 sEnRxFIFO(cp);
1046 sEnTransmit(cp);
1048 info->flags |= ROCKET_INITIALIZED;
1051 * Set up the tty->alt_speed kludge
1053 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
1054 info->tty->alt_speed = 57600;
1055 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
1056 info->tty->alt_speed = 115200;
1057 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
1058 info->tty->alt_speed = 230400;
1059 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
1060 info->tty->alt_speed = 460800;
1062 configure_r_port(info, NULL);
1063 if (tty->termios->c_cflag & CBAUD) {
1064 sSetDTR(cp);
1065 sSetRTS(cp);
1068 /* Starts (or resets) the maint polling loop */
1069 mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
1071 retval = block_til_ready(tty, filp, info);
1072 if (retval) {
1073 #ifdef ROCKET_DEBUG_OPEN
1074 printk(KERN_INFO "rp_open returning after block_til_ready with %d\n", retval);
1075 #endif
1076 return retval;
1078 return 0;
1082 * Exception handler that closes a serial port. info->count is considered critical.
1084 static void rp_close(struct tty_struct *tty, struct file *filp)
1086 struct r_port *info = (struct r_port *) tty->driver_data;
1087 unsigned long flags;
1088 int timeout;
1089 CHANNEL_t *cp;
1091 if (rocket_paranoia_check(info, "rp_close"))
1092 return;
1094 #ifdef ROCKET_DEBUG_OPEN
1095 printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->count);
1096 #endif
1098 if (tty_hung_up_p(filp))
1099 return;
1100 spin_lock_irqsave(&info->slock, flags);
1102 if ((tty->count == 1) && (info->count != 1)) {
1104 * Uh, oh. tty->count is 1, which means that the tty
1105 * structure will be freed. Info->count should always
1106 * be one in these conditions. If it's greater than
1107 * one, we've got real problems, since it means the
1108 * serial port won't be shutdown.
1110 printk(KERN_INFO "rp_close: bad serial port count; tty->count is 1, "
1111 "info->count is %d\n", info->count);
1112 info->count = 1;
1114 if (--info->count < 0) {
1115 printk(KERN_INFO "rp_close: bad serial port count for ttyR%d: %d\n",
1116 info->line, info->count);
1117 info->count = 0;
1119 if (info->count) {
1120 spin_unlock_irqrestore(&info->slock, flags);
1121 return;
1123 info->flags |= ROCKET_CLOSING;
1124 spin_unlock_irqrestore(&info->slock, flags);
1126 cp = &info->channel;
1129 * Notify the line discpline to only process XON/XOFF characters
1131 tty->closing = 1;
1134 * If transmission was throttled by the application request,
1135 * just flush the xmit buffer.
1137 if (tty->flow_stopped)
1138 rp_flush_buffer(tty);
1141 * Wait for the transmit buffer to clear
1143 if (info->closing_wait != ROCKET_CLOSING_WAIT_NONE)
1144 tty_wait_until_sent(tty, info->closing_wait);
1146 * Before we drop DTR, make sure the UART transmitter
1147 * has completely drained; this is especially
1148 * important if there is a transmit FIFO!
1150 timeout = (sGetTxCnt(cp) + 1) * HZ / info->cps;
1151 if (timeout == 0)
1152 timeout = 1;
1153 rp_wait_until_sent(tty, timeout);
1154 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1156 sDisTransmit(cp);
1157 sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
1158 sDisCTSFlowCtl(cp);
1159 sDisTxSoftFlowCtl(cp);
1160 sClrTxXOFF(cp);
1161 sFlushRxFIFO(cp);
1162 sFlushTxFIFO(cp);
1163 sClrRTS(cp);
1164 if (C_HUPCL(tty))
1165 sClrDTR(cp);
1167 if (TTY_DRIVER_FLUSH_BUFFER_EXISTS(tty))
1168 TTY_DRIVER_FLUSH_BUFFER(tty);
1170 tty_ldisc_flush(tty);
1172 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1174 if (info->blocked_open) {
1175 if (info->close_delay) {
1176 msleep_interruptible(jiffies_to_msecs(info->close_delay));
1178 wake_up_interruptible(&info->open_wait);
1179 } else {
1180 if (info->xmit_buf) {
1181 free_page((unsigned long) info->xmit_buf);
1182 info->xmit_buf = NULL;
1185 info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE);
1186 tty->closing = 0;
1187 wake_up_interruptible(&info->close_wait);
1188 atomic_dec(&rp_num_ports_open);
1190 #ifdef ROCKET_DEBUG_OPEN
1191 printk(KERN_INFO "rocket mod-- = %d...", atomic_read(&rp_num_ports_open));
1192 printk(KERN_INFO "rp_close ttyR%d complete shutdown\n", info->line);
1193 #endif
1197 static void rp_set_termios(struct tty_struct *tty,
1198 struct ktermios *old_termios)
1200 struct r_port *info = (struct r_port *) tty->driver_data;
1201 CHANNEL_t *cp;
1202 unsigned cflag;
1204 if (rocket_paranoia_check(info, "rp_set_termios"))
1205 return;
1207 cflag = tty->termios->c_cflag;
1209 if (cflag == old_termios->c_cflag)
1210 return;
1213 * This driver doesn't support CS5 or CS6
1215 if (((cflag & CSIZE) == CS5) || ((cflag & CSIZE) == CS6))
1216 tty->termios->c_cflag =
1217 ((cflag & ~CSIZE) | (old_termios->c_cflag & CSIZE));
1219 configure_r_port(info, old_termios);
1221 cp = &info->channel;
1223 /* Handle transition to B0 status */
1224 if ((old_termios->c_cflag & CBAUD) && !(tty->termios->c_cflag & CBAUD)) {
1225 sClrDTR(cp);
1226 sClrRTS(cp);
1229 /* Handle transition away from B0 status */
1230 if (!(old_termios->c_cflag & CBAUD) && (tty->termios->c_cflag & CBAUD)) {
1231 if (!tty->hw_stopped || !(tty->termios->c_cflag & CRTSCTS))
1232 sSetRTS(cp);
1233 sSetDTR(cp);
1236 if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
1237 tty->hw_stopped = 0;
1238 rp_start(tty);
1242 static void rp_break(struct tty_struct *tty, int break_state)
1244 struct r_port *info = (struct r_port *) tty->driver_data;
1245 unsigned long flags;
1247 if (rocket_paranoia_check(info, "rp_break"))
1248 return;
1250 spin_lock_irqsave(&info->slock, flags);
1251 if (break_state == -1)
1252 sSendBreak(&info->channel);
1253 else
1254 sClrBreak(&info->channel);
1255 spin_unlock_irqrestore(&info->slock, flags);
1259 * sGetChanRI used to be a macro in rocket_int.h. When the functionality for
1260 * the UPCI boards was added, it was decided to make this a function because
1261 * the macro was getting too complicated. All cases except the first one
1262 * (UPCIRingInd) are taken directly from the original macro.
1264 static int sGetChanRI(CHANNEL_T * ChP)
1266 CONTROLLER_t *CtlP = ChP->CtlP;
1267 int ChanNum = ChP->ChanNum;
1268 int RingInd = 0;
1270 if (CtlP->UPCIRingInd)
1271 RingInd = !(sInB(CtlP->UPCIRingInd) & sBitMapSetTbl[ChanNum]);
1272 else if (CtlP->AltChanRingIndicator)
1273 RingInd = sInB((ByteIO_t) (ChP->ChanStat + 8)) & DSR_ACT;
1274 else if (CtlP->boardType == ROCKET_TYPE_PC104)
1275 RingInd = !(sInB(CtlP->AiopIO[3]) & sBitMapSetTbl[ChanNum]);
1277 return RingInd;
1280 /********************************************************************************************/
1281 /* Here are the routines used by rp_ioctl. These are all called from exception handlers. */
1284 * Returns the state of the serial modem control lines. These next 2 functions
1285 * are the way kernel versions > 2.5 handle modem control lines rather than IOCTLs.
1287 static int rp_tiocmget(struct tty_struct *tty, struct file *file)
1289 struct r_port *info = (struct r_port *)tty->driver_data;
1290 unsigned int control, result, ChanStatus;
1292 ChanStatus = sGetChanStatusLo(&info->channel);
1293 control = info->channel.TxControl[3];
1294 result = ((control & SET_RTS) ? TIOCM_RTS : 0) |
1295 ((control & SET_DTR) ? TIOCM_DTR : 0) |
1296 ((ChanStatus & CD_ACT) ? TIOCM_CAR : 0) |
1297 (sGetChanRI(&info->channel) ? TIOCM_RNG : 0) |
1298 ((ChanStatus & DSR_ACT) ? TIOCM_DSR : 0) |
1299 ((ChanStatus & CTS_ACT) ? TIOCM_CTS : 0);
1301 return result;
1305 * Sets the modem control lines
1307 static int rp_tiocmset(struct tty_struct *tty, struct file *file,
1308 unsigned int set, unsigned int clear)
1310 struct r_port *info = (struct r_port *)tty->driver_data;
1312 if (set & TIOCM_RTS)
1313 info->channel.TxControl[3] |= SET_RTS;
1314 if (set & TIOCM_DTR)
1315 info->channel.TxControl[3] |= SET_DTR;
1316 if (clear & TIOCM_RTS)
1317 info->channel.TxControl[3] &= ~SET_RTS;
1318 if (clear & TIOCM_DTR)
1319 info->channel.TxControl[3] &= ~SET_DTR;
1321 sOutDW(info->channel.IndexAddr, *(DWord_t *) & (info->channel.TxControl[0]));
1322 return 0;
1325 static int get_config(struct r_port *info, struct rocket_config __user *retinfo)
1327 struct rocket_config tmp;
1329 if (!retinfo)
1330 return -EFAULT;
1331 memset(&tmp, 0, sizeof (tmp));
1332 tmp.line = info->line;
1333 tmp.flags = info->flags;
1334 tmp.close_delay = info->close_delay;
1335 tmp.closing_wait = info->closing_wait;
1336 tmp.port = rcktpt_io_addr[(info->line >> 5) & 3];
1338 if (copy_to_user(retinfo, &tmp, sizeof (*retinfo)))
1339 return -EFAULT;
1340 return 0;
1343 static int set_config(struct r_port *info, struct rocket_config __user *new_info)
1345 struct rocket_config new_serial;
1347 if (copy_from_user(&new_serial, new_info, sizeof (new_serial)))
1348 return -EFAULT;
1350 if (!capable(CAP_SYS_ADMIN))
1352 if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK))
1353 return -EPERM;
1354 info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK));
1355 configure_r_port(info, NULL);
1356 return 0;
1359 info->flags = ((info->flags & ~ROCKET_FLAGS) | (new_serial.flags & ROCKET_FLAGS));
1360 info->close_delay = new_serial.close_delay;
1361 info->closing_wait = new_serial.closing_wait;
1363 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
1364 info->tty->alt_speed = 57600;
1365 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
1366 info->tty->alt_speed = 115200;
1367 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
1368 info->tty->alt_speed = 230400;
1369 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
1370 info->tty->alt_speed = 460800;
1372 configure_r_port(info, NULL);
1373 return 0;
1377 * This function fills in a rocket_ports struct with information
1378 * about what boards/ports are in the system. This info is passed
1379 * to user space. See setrocket.c where the info is used to create
1380 * the /dev/ttyRx ports.
1382 static int get_ports(struct r_port *info, struct rocket_ports __user *retports)
1384 struct rocket_ports tmp;
1385 int board;
1387 if (!retports)
1388 return -EFAULT;
1389 memset(&tmp, 0, sizeof (tmp));
1390 tmp.tty_major = rocket_driver->major;
1392 for (board = 0; board < 4; board++) {
1393 tmp.rocketModel[board].model = rocketModel[board].model;
1394 strcpy(tmp.rocketModel[board].modelString, rocketModel[board].modelString);
1395 tmp.rocketModel[board].numPorts = rocketModel[board].numPorts;
1396 tmp.rocketModel[board].loadrm2 = rocketModel[board].loadrm2;
1397 tmp.rocketModel[board].startingPortNumber = rocketModel[board].startingPortNumber;
1399 if (copy_to_user(retports, &tmp, sizeof (*retports)))
1400 return -EFAULT;
1401 return 0;
1404 static int reset_rm2(struct r_port *info, void __user *arg)
1406 int reset;
1408 if (copy_from_user(&reset, arg, sizeof (int)))
1409 return -EFAULT;
1410 if (reset)
1411 reset = 1;
1413 if (rcktpt_type[info->board] != ROCKET_TYPE_MODEMII &&
1414 rcktpt_type[info->board] != ROCKET_TYPE_MODEMIII)
1415 return -EINVAL;
1417 if (info->ctlp->BusType == isISA)
1418 sModemReset(info->ctlp, info->chan, reset);
1419 else
1420 sPCIModemReset(info->ctlp, info->chan, reset);
1422 return 0;
1425 static int get_version(struct r_port *info, struct rocket_version __user *retvers)
1427 if (copy_to_user(retvers, &driver_version, sizeof (*retvers)))
1428 return -EFAULT;
1429 return 0;
1432 /* IOCTL call handler into the driver */
1433 static int rp_ioctl(struct tty_struct *tty, struct file *file,
1434 unsigned int cmd, unsigned long arg)
1436 struct r_port *info = (struct r_port *) tty->driver_data;
1437 void __user *argp = (void __user *)arg;
1439 if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl"))
1440 return -ENXIO;
1442 switch (cmd) {
1443 case RCKP_GET_STRUCT:
1444 if (copy_to_user(argp, info, sizeof (struct r_port)))
1445 return -EFAULT;
1446 return 0;
1447 case RCKP_GET_CONFIG:
1448 return get_config(info, argp);
1449 case RCKP_SET_CONFIG:
1450 return set_config(info, argp);
1451 case RCKP_GET_PORTS:
1452 return get_ports(info, argp);
1453 case RCKP_RESET_RM2:
1454 return reset_rm2(info, argp);
1455 case RCKP_GET_VERSION:
1456 return get_version(info, argp);
1457 default:
1458 return -ENOIOCTLCMD;
1460 return 0;
1463 static void rp_send_xchar(struct tty_struct *tty, char ch)
1465 struct r_port *info = (struct r_port *) tty->driver_data;
1466 CHANNEL_t *cp;
1468 if (rocket_paranoia_check(info, "rp_send_xchar"))
1469 return;
1471 cp = &info->channel;
1472 if (sGetTxCnt(cp))
1473 sWriteTxPrioByte(cp, ch);
1474 else
1475 sWriteTxByte(sGetTxRxDataIO(cp), ch);
1478 static void rp_throttle(struct tty_struct *tty)
1480 struct r_port *info = (struct r_port *) tty->driver_data;
1481 CHANNEL_t *cp;
1483 #ifdef ROCKET_DEBUG_THROTTLE
1484 printk(KERN_INFO "throttle %s: %d....\n", tty->name,
1485 tty->ldisc.chars_in_buffer(tty));
1486 #endif
1488 if (rocket_paranoia_check(info, "rp_throttle"))
1489 return;
1491 cp = &info->channel;
1492 if (I_IXOFF(tty))
1493 rp_send_xchar(tty, STOP_CHAR(tty));
1495 sClrRTS(&info->channel);
1498 static void rp_unthrottle(struct tty_struct *tty)
1500 struct r_port *info = (struct r_port *) tty->driver_data;
1501 CHANNEL_t *cp;
1502 #ifdef ROCKET_DEBUG_THROTTLE
1503 printk(KERN_INFO "unthrottle %s: %d....\n", tty->name,
1504 tty->ldisc.chars_in_buffer(tty));
1505 #endif
1507 if (rocket_paranoia_check(info, "rp_throttle"))
1508 return;
1510 cp = &info->channel;
1511 if (I_IXOFF(tty))
1512 rp_send_xchar(tty, START_CHAR(tty));
1514 sSetRTS(&info->channel);
1518 * ------------------------------------------------------------
1519 * rp_stop() and rp_start()
1521 * This routines are called before setting or resetting tty->stopped.
1522 * They enable or disable transmitter interrupts, as necessary.
1523 * ------------------------------------------------------------
1525 static void rp_stop(struct tty_struct *tty)
1527 struct r_port *info = (struct r_port *) tty->driver_data;
1529 #ifdef ROCKET_DEBUG_FLOW
1530 printk(KERN_INFO "stop %s: %d %d....\n", tty->name,
1531 info->xmit_cnt, info->xmit_fifo_room);
1532 #endif
1534 if (rocket_paranoia_check(info, "rp_stop"))
1535 return;
1537 if (sGetTxCnt(&info->channel))
1538 sDisTransmit(&info->channel);
1541 static void rp_start(struct tty_struct *tty)
1543 struct r_port *info = (struct r_port *) tty->driver_data;
1545 #ifdef ROCKET_DEBUG_FLOW
1546 printk(KERN_INFO "start %s: %d %d....\n", tty->name,
1547 info->xmit_cnt, info->xmit_fifo_room);
1548 #endif
1550 if (rocket_paranoia_check(info, "rp_stop"))
1551 return;
1553 sEnTransmit(&info->channel);
1554 set_bit((info->aiop * 8) + info->chan,
1555 (void *) &xmit_flags[info->board]);
1559 * rp_wait_until_sent() --- wait until the transmitter is empty
1561 static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
1563 struct r_port *info = (struct r_port *) tty->driver_data;
1564 CHANNEL_t *cp;
1565 unsigned long orig_jiffies;
1566 int check_time, exit_time;
1567 int txcnt;
1569 if (rocket_paranoia_check(info, "rp_wait_until_sent"))
1570 return;
1572 cp = &info->channel;
1574 orig_jiffies = jiffies;
1575 #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1576 printk(KERN_INFO "In RP_wait_until_sent(%d) (jiff=%lu)...", timeout,
1577 jiffies);
1578 printk(KERN_INFO "cps=%d...", info->cps);
1579 #endif
1580 while (1) {
1581 txcnt = sGetTxCnt(cp);
1582 if (!txcnt) {
1583 if (sGetChanStatusLo(cp) & TXSHRMT)
1584 break;
1585 check_time = (HZ / info->cps) / 5;
1586 } else {
1587 check_time = HZ * txcnt / info->cps;
1589 if (timeout) {
1590 exit_time = orig_jiffies + timeout - jiffies;
1591 if (exit_time <= 0)
1592 break;
1593 if (exit_time < check_time)
1594 check_time = exit_time;
1596 if (check_time == 0)
1597 check_time = 1;
1598 #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1599 printk(KERN_INFO "txcnt = %d (jiff=%lu,check=%d)...", txcnt, jiffies, check_time);
1600 #endif
1601 msleep_interruptible(jiffies_to_msecs(check_time));
1602 if (signal_pending(current))
1603 break;
1605 current->state = TASK_RUNNING;
1606 #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1607 printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
1608 #endif
1612 * rp_hangup() --- called by tty_hangup() when a hangup is signaled.
1614 static void rp_hangup(struct tty_struct *tty)
1616 CHANNEL_t *cp;
1617 struct r_port *info = (struct r_port *) tty->driver_data;
1619 if (rocket_paranoia_check(info, "rp_hangup"))
1620 return;
1622 #if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_HANGUP))
1623 printk(KERN_INFO "rp_hangup of ttyR%d...", info->line);
1624 #endif
1625 rp_flush_buffer(tty);
1626 if (info->flags & ROCKET_CLOSING)
1627 return;
1628 if (info->count)
1629 atomic_dec(&rp_num_ports_open);
1630 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1632 info->count = 0;
1633 info->flags &= ~ROCKET_NORMAL_ACTIVE;
1634 info->tty = NULL;
1636 cp = &info->channel;
1637 sDisRxFIFO(cp);
1638 sDisTransmit(cp);
1639 sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
1640 sDisCTSFlowCtl(cp);
1641 sDisTxSoftFlowCtl(cp);
1642 sClrTxXOFF(cp);
1643 info->flags &= ~ROCKET_INITIALIZED;
1645 wake_up_interruptible(&info->open_wait);
1649 * Exception handler - write char routine. The RocketPort driver uses a
1650 * double-buffering strategy, with the twist that if the in-memory CPU
1651 * buffer is empty, and there's space in the transmit FIFO, the
1652 * writing routines will write directly to transmit FIFO.
1653 * Write buffer and counters protected by spinlocks
1655 static void rp_put_char(struct tty_struct *tty, unsigned char ch)
1657 struct r_port *info = (struct r_port *) tty->driver_data;
1658 CHANNEL_t *cp;
1659 unsigned long flags;
1661 if (rocket_paranoia_check(info, "rp_put_char"))
1662 return;
1664 /* Grab the port write semaphore, locking out other processes that try to write to this port */
1665 down(&info->write_sem);
1667 #ifdef ROCKET_DEBUG_WRITE
1668 printk(KERN_INFO "rp_put_char %c...", ch);
1669 #endif
1671 spin_lock_irqsave(&info->slock, flags);
1672 cp = &info->channel;
1674 if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room == 0)
1675 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
1677 if (tty->stopped || tty->hw_stopped || info->xmit_fifo_room == 0 || info->xmit_cnt != 0) {
1678 info->xmit_buf[info->xmit_head++] = ch;
1679 info->xmit_head &= XMIT_BUF_SIZE - 1;
1680 info->xmit_cnt++;
1681 set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1682 } else {
1683 sOutB(sGetTxRxDataIO(cp), ch);
1684 info->xmit_fifo_room--;
1686 spin_unlock_irqrestore(&info->slock, flags);
1687 up(&info->write_sem);
1691 * Exception handler - write routine, called when user app writes to the device.
1692 * A per port write semaphore is used to protect from another process writing to
1693 * this port at the same time. This other process could be running on the other CPU
1694 * or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out).
1695 * Spinlocks protect the info xmit members.
1697 static int rp_write(struct tty_struct *tty,
1698 const unsigned char *buf, int count)
1700 struct r_port *info = (struct r_port *) tty->driver_data;
1701 CHANNEL_t *cp;
1702 const unsigned char *b;
1703 int c, retval = 0;
1704 unsigned long flags;
1706 if (count <= 0 || rocket_paranoia_check(info, "rp_write"))
1707 return 0;
1709 down_interruptible(&info->write_sem);
1711 #ifdef ROCKET_DEBUG_WRITE
1712 printk(KERN_INFO "rp_write %d chars...", count);
1713 #endif
1714 cp = &info->channel;
1716 if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room < count)
1717 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
1720 * If the write queue for the port is empty, and there is FIFO space, stuff bytes
1721 * into FIFO. Use the write queue for temp storage.
1723 if (!tty->stopped && !tty->hw_stopped && info->xmit_cnt == 0 && info->xmit_fifo_room > 0) {
1724 c = min(count, info->xmit_fifo_room);
1725 b = buf;
1727 /* Push data into FIFO, 2 bytes at a time */
1728 sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) b, c / 2);
1730 /* If there is a byte remaining, write it */
1731 if (c & 1)
1732 sOutB(sGetTxRxDataIO(cp), b[c - 1]);
1734 retval += c;
1735 buf += c;
1736 count -= c;
1738 spin_lock_irqsave(&info->slock, flags);
1739 info->xmit_fifo_room -= c;
1740 spin_unlock_irqrestore(&info->slock, flags);
1743 /* If count is zero, we wrote it all and are done */
1744 if (!count)
1745 goto end;
1747 /* Write remaining data into the port's xmit_buf */
1748 while (1) {
1749 if (info->tty == 0) /* Seemingly obligatory check... */
1750 goto end;
1752 c = min(count, min(XMIT_BUF_SIZE - info->xmit_cnt - 1, XMIT_BUF_SIZE - info->xmit_head));
1753 if (c <= 0)
1754 break;
1756 b = buf;
1757 memcpy(info->xmit_buf + info->xmit_head, b, c);
1759 spin_lock_irqsave(&info->slock, flags);
1760 info->xmit_head =
1761 (info->xmit_head + c) & (XMIT_BUF_SIZE - 1);
1762 info->xmit_cnt += c;
1763 spin_unlock_irqrestore(&info->slock, flags);
1765 buf += c;
1766 count -= c;
1767 retval += c;
1770 if ((retval > 0) && !tty->stopped && !tty->hw_stopped)
1771 set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1773 end:
1774 if (info->xmit_cnt < WAKEUP_CHARS) {
1775 tty_wakeup(tty);
1776 #ifdef ROCKETPORT_HAVE_POLL_WAIT
1777 wake_up_interruptible(&tty->poll_wait);
1778 #endif
1780 up(&info->write_sem);
1781 return retval;
1785 * Return the number of characters that can be sent. We estimate
1786 * only using the in-memory transmit buffer only, and ignore the
1787 * potential space in the transmit FIFO.
1789 static int rp_write_room(struct tty_struct *tty)
1791 struct r_port *info = (struct r_port *) tty->driver_data;
1792 int ret;
1794 if (rocket_paranoia_check(info, "rp_write_room"))
1795 return 0;
1797 ret = XMIT_BUF_SIZE - info->xmit_cnt - 1;
1798 if (ret < 0)
1799 ret = 0;
1800 #ifdef ROCKET_DEBUG_WRITE
1801 printk(KERN_INFO "rp_write_room returns %d...", ret);
1802 #endif
1803 return ret;
1807 * Return the number of characters in the buffer. Again, this only
1808 * counts those characters in the in-memory transmit buffer.
1810 static int rp_chars_in_buffer(struct tty_struct *tty)
1812 struct r_port *info = (struct r_port *) tty->driver_data;
1813 CHANNEL_t *cp;
1815 if (rocket_paranoia_check(info, "rp_chars_in_buffer"))
1816 return 0;
1818 cp = &info->channel;
1820 #ifdef ROCKET_DEBUG_WRITE
1821 printk(KERN_INFO "rp_chars_in_buffer returns %d...", info->xmit_cnt);
1822 #endif
1823 return info->xmit_cnt;
1827 * Flushes the TX fifo for a port, deletes data in the xmit_buf stored in the
1828 * r_port struct for the port. Note that spinlock are used to protect info members,
1829 * do not call this function if the spinlock is already held.
1831 static void rp_flush_buffer(struct tty_struct *tty)
1833 struct r_port *info = (struct r_port *) tty->driver_data;
1834 CHANNEL_t *cp;
1835 unsigned long flags;
1837 if (rocket_paranoia_check(info, "rp_flush_buffer"))
1838 return;
1840 spin_lock_irqsave(&info->slock, flags);
1841 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1842 spin_unlock_irqrestore(&info->slock, flags);
1844 #ifdef ROCKETPORT_HAVE_POLL_WAIT
1845 wake_up_interruptible(&tty->poll_wait);
1846 #endif
1847 tty_wakeup(tty);
1849 cp = &info->channel;
1850 sFlushTxFIFO(cp);
1853 #ifdef CONFIG_PCI
1856 * Called when a PCI card is found. Retrieves and stores model information,
1857 * init's aiopic and serial port hardware.
1858 * Inputs: i is the board number (0-n)
1860 static __init int register_PCI(int i, struct pci_dev *dev)
1862 int num_aiops, aiop, max_num_aiops, num_chan, chan;
1863 unsigned int aiopio[MAX_AIOPS_PER_BOARD];
1864 char *str, *board_type;
1865 CONTROLLER_t *ctlp;
1867 int fast_clock = 0;
1868 int altChanRingIndicator = 0;
1869 int ports_per_aiop = 8;
1870 int ret;
1871 unsigned int class_rev;
1872 WordIO_t ConfigIO = 0;
1873 ByteIO_t UPCIRingInd = 0;
1875 if (!dev || pci_enable_device(dev))
1876 return 0;
1878 rcktpt_io_addr[i] = pci_resource_start(dev, 0);
1879 ret = pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
1881 if (ret) {
1882 printk(KERN_INFO " Error during register_PCI(), unable to read config dword \n");
1883 return 0;
1886 rcktpt_type[i] = ROCKET_TYPE_NORMAL;
1887 rocketModel[i].loadrm2 = 0;
1888 rocketModel[i].startingPortNumber = nextLineNumber;
1890 /* Depending on the model, set up some config variables */
1891 switch (dev->device) {
1892 case PCI_DEVICE_ID_RP4QUAD:
1893 str = "Quadcable";
1894 max_num_aiops = 1;
1895 ports_per_aiop = 4;
1896 rocketModel[i].model = MODEL_RP4QUAD;
1897 strcpy(rocketModel[i].modelString, "RocketPort 4 port w/quad cable");
1898 rocketModel[i].numPorts = 4;
1899 break;
1900 case PCI_DEVICE_ID_RP8OCTA:
1901 str = "Octacable";
1902 max_num_aiops = 1;
1903 rocketModel[i].model = MODEL_RP8OCTA;
1904 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/octa cable");
1905 rocketModel[i].numPorts = 8;
1906 break;
1907 case PCI_DEVICE_ID_URP8OCTA:
1908 str = "Octacable";
1909 max_num_aiops = 1;
1910 rocketModel[i].model = MODEL_UPCI_RP8OCTA;
1911 strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/octa cable");
1912 rocketModel[i].numPorts = 8;
1913 break;
1914 case PCI_DEVICE_ID_RP8INTF:
1915 str = "8";
1916 max_num_aiops = 1;
1917 rocketModel[i].model = MODEL_RP8INTF;
1918 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/external I/F");
1919 rocketModel[i].numPorts = 8;
1920 break;
1921 case PCI_DEVICE_ID_URP8INTF:
1922 str = "8";
1923 max_num_aiops = 1;
1924 rocketModel[i].model = MODEL_UPCI_RP8INTF;
1925 strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/external I/F");
1926 rocketModel[i].numPorts = 8;
1927 break;
1928 case PCI_DEVICE_ID_RP8J:
1929 str = "8J";
1930 max_num_aiops = 1;
1931 rocketModel[i].model = MODEL_RP8J;
1932 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/RJ11 connectors");
1933 rocketModel[i].numPorts = 8;
1934 break;
1935 case PCI_DEVICE_ID_RP4J:
1936 str = "4J";
1937 max_num_aiops = 1;
1938 ports_per_aiop = 4;
1939 rocketModel[i].model = MODEL_RP4J;
1940 strcpy(rocketModel[i].modelString, "RocketPort 4 port w/RJ45 connectors");
1941 rocketModel[i].numPorts = 4;
1942 break;
1943 case PCI_DEVICE_ID_RP8SNI:
1944 str = "8 (DB78 Custom)";
1945 max_num_aiops = 1;
1946 rocketModel[i].model = MODEL_RP8SNI;
1947 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/ custom DB78");
1948 rocketModel[i].numPorts = 8;
1949 break;
1950 case PCI_DEVICE_ID_RP16SNI:
1951 str = "16 (DB78 Custom)";
1952 max_num_aiops = 2;
1953 rocketModel[i].model = MODEL_RP16SNI;
1954 strcpy(rocketModel[i].modelString, "RocketPort 16 port w/ custom DB78");
1955 rocketModel[i].numPorts = 16;
1956 break;
1957 case PCI_DEVICE_ID_RP16INTF:
1958 str = "16";
1959 max_num_aiops = 2;
1960 rocketModel[i].model = MODEL_RP16INTF;
1961 strcpy(rocketModel[i].modelString, "RocketPort 16 port w/external I/F");
1962 rocketModel[i].numPorts = 16;
1963 break;
1964 case PCI_DEVICE_ID_URP16INTF:
1965 str = "16";
1966 max_num_aiops = 2;
1967 rocketModel[i].model = MODEL_UPCI_RP16INTF;
1968 strcpy(rocketModel[i].modelString, "RocketPort UPCI 16 port w/external I/F");
1969 rocketModel[i].numPorts = 16;
1970 break;
1971 case PCI_DEVICE_ID_CRP16INTF:
1972 str = "16";
1973 max_num_aiops = 2;
1974 rocketModel[i].model = MODEL_CPCI_RP16INTF;
1975 strcpy(rocketModel[i].modelString, "RocketPort Compact PCI 16 port w/external I/F");
1976 rocketModel[i].numPorts = 16;
1977 break;
1978 case PCI_DEVICE_ID_RP32INTF:
1979 str = "32";
1980 max_num_aiops = 4;
1981 rocketModel[i].model = MODEL_RP32INTF;
1982 strcpy(rocketModel[i].modelString, "RocketPort 32 port w/external I/F");
1983 rocketModel[i].numPorts = 32;
1984 break;
1985 case PCI_DEVICE_ID_URP32INTF:
1986 str = "32";
1987 max_num_aiops = 4;
1988 rocketModel[i].model = MODEL_UPCI_RP32INTF;
1989 strcpy(rocketModel[i].modelString, "RocketPort UPCI 32 port w/external I/F");
1990 rocketModel[i].numPorts = 32;
1991 break;
1992 case PCI_DEVICE_ID_RPP4:
1993 str = "Plus Quadcable";
1994 max_num_aiops = 1;
1995 ports_per_aiop = 4;
1996 altChanRingIndicator++;
1997 fast_clock++;
1998 rocketModel[i].model = MODEL_RPP4;
1999 strcpy(rocketModel[i].modelString, "RocketPort Plus 4 port");
2000 rocketModel[i].numPorts = 4;
2001 break;
2002 case PCI_DEVICE_ID_RPP8:
2003 str = "Plus Octacable";
2004 max_num_aiops = 2;
2005 ports_per_aiop = 4;
2006 altChanRingIndicator++;
2007 fast_clock++;
2008 rocketModel[i].model = MODEL_RPP8;
2009 strcpy(rocketModel[i].modelString, "RocketPort Plus 8 port");
2010 rocketModel[i].numPorts = 8;
2011 break;
2012 case PCI_DEVICE_ID_RP2_232:
2013 str = "Plus 2 (RS-232)";
2014 max_num_aiops = 1;
2015 ports_per_aiop = 2;
2016 altChanRingIndicator++;
2017 fast_clock++;
2018 rocketModel[i].model = MODEL_RP2_232;
2019 strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS232");
2020 rocketModel[i].numPorts = 2;
2021 break;
2022 case PCI_DEVICE_ID_RP2_422:
2023 str = "Plus 2 (RS-422)";
2024 max_num_aiops = 1;
2025 ports_per_aiop = 2;
2026 altChanRingIndicator++;
2027 fast_clock++;
2028 rocketModel[i].model = MODEL_RP2_422;
2029 strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS422");
2030 rocketModel[i].numPorts = 2;
2031 break;
2032 case PCI_DEVICE_ID_RP6M:
2034 max_num_aiops = 1;
2035 ports_per_aiop = 6;
2036 str = "6-port";
2038 /* If class_rev is 1, the rocketmodem flash must be loaded. If it is 2 it is a "socketed" version. */
2039 if ((class_rev & 0xFF) == 1) {
2040 rcktpt_type[i] = ROCKET_TYPE_MODEMII;
2041 rocketModel[i].loadrm2 = 1;
2042 } else {
2043 rcktpt_type[i] = ROCKET_TYPE_MODEM;
2046 rocketModel[i].model = MODEL_RP6M;
2047 strcpy(rocketModel[i].modelString, "RocketModem 6 port");
2048 rocketModel[i].numPorts = 6;
2049 break;
2050 case PCI_DEVICE_ID_RP4M:
2051 max_num_aiops = 1;
2052 ports_per_aiop = 4;
2053 str = "4-port";
2054 if ((class_rev & 0xFF) == 1) {
2055 rcktpt_type[i] = ROCKET_TYPE_MODEMII;
2056 rocketModel[i].loadrm2 = 1;
2057 } else {
2058 rcktpt_type[i] = ROCKET_TYPE_MODEM;
2061 rocketModel[i].model = MODEL_RP4M;
2062 strcpy(rocketModel[i].modelString, "RocketModem 4 port");
2063 rocketModel[i].numPorts = 4;
2064 break;
2065 default:
2066 str = "(unknown/unsupported)";
2067 max_num_aiops = 0;
2068 break;
2072 * Check for UPCI boards.
2075 switch (dev->device) {
2076 case PCI_DEVICE_ID_URP32INTF:
2077 case PCI_DEVICE_ID_URP8INTF:
2078 case PCI_DEVICE_ID_URP16INTF:
2079 case PCI_DEVICE_ID_CRP16INTF:
2080 case PCI_DEVICE_ID_URP8OCTA:
2081 rcktpt_io_addr[i] = pci_resource_start(dev, 2);
2082 ConfigIO = pci_resource_start(dev, 1);
2083 if (dev->device == PCI_DEVICE_ID_URP8OCTA) {
2084 UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
2087 * Check for octa or quad cable.
2089 if (!
2090 (sInW(ConfigIO + _PCI_9030_GPIO_CTRL) &
2091 PCI_GPIO_CTRL_8PORT)) {
2092 str = "Quadcable";
2093 ports_per_aiop = 4;
2094 rocketModel[i].numPorts = 4;
2097 break;
2098 case PCI_DEVICE_ID_UPCI_RM3_8PORT:
2099 str = "8 ports";
2100 max_num_aiops = 1;
2101 rocketModel[i].model = MODEL_UPCI_RM3_8PORT;
2102 strcpy(rocketModel[i].modelString, "RocketModem III 8 port");
2103 rocketModel[i].numPorts = 8;
2104 rcktpt_io_addr[i] = pci_resource_start(dev, 2);
2105 UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
2106 ConfigIO = pci_resource_start(dev, 1);
2107 rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
2108 break;
2109 case PCI_DEVICE_ID_UPCI_RM3_4PORT:
2110 str = "4 ports";
2111 max_num_aiops = 1;
2112 rocketModel[i].model = MODEL_UPCI_RM3_4PORT;
2113 strcpy(rocketModel[i].modelString, "RocketModem III 4 port");
2114 rocketModel[i].numPorts = 4;
2115 rcktpt_io_addr[i] = pci_resource_start(dev, 2);
2116 UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
2117 ConfigIO = pci_resource_start(dev, 1);
2118 rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
2119 break;
2120 default:
2121 break;
2124 switch (rcktpt_type[i]) {
2125 case ROCKET_TYPE_MODEM:
2126 board_type = "RocketModem";
2127 break;
2128 case ROCKET_TYPE_MODEMII:
2129 board_type = "RocketModem II";
2130 break;
2131 case ROCKET_TYPE_MODEMIII:
2132 board_type = "RocketModem III";
2133 break;
2134 default:
2135 board_type = "RocketPort";
2136 break;
2139 if (fast_clock) {
2140 sClockPrescale = 0x12; /* mod 2 (divide by 3) */
2141 rp_baud_base[i] = 921600;
2142 } else {
2144 * If support_low_speed is set, use the slow clock
2145 * prescale, which supports 50 bps
2147 if (support_low_speed) {
2148 /* mod 9 (divide by 10) prescale */
2149 sClockPrescale = 0x19;
2150 rp_baud_base[i] = 230400;
2151 } else {
2152 /* mod 4 (devide by 5) prescale */
2153 sClockPrescale = 0x14;
2154 rp_baud_base[i] = 460800;
2158 for (aiop = 0; aiop < max_num_aiops; aiop++)
2159 aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x40);
2160 ctlp = sCtlNumToCtlPtr(i);
2161 num_aiops = sPCIInitController(ctlp, i, aiopio, max_num_aiops, ConfigIO, 0, FREQ_DIS, 0, altChanRingIndicator, UPCIRingInd);
2162 for (aiop = 0; aiop < max_num_aiops; aiop++)
2163 ctlp->AiopNumChan[aiop] = ports_per_aiop;
2165 printk("Comtrol PCI controller #%d ID 0x%x found in bus:slot:fn %s at address %04lx, "
2166 "%d AIOP(s) (%s)\n", i, dev->device, pci_name(dev),
2167 rcktpt_io_addr[i], num_aiops, rocketModel[i].modelString);
2168 printk(KERN_INFO "Installing %s, creating /dev/ttyR%d - %ld\n",
2169 rocketModel[i].modelString,
2170 rocketModel[i].startingPortNumber,
2171 rocketModel[i].startingPortNumber +
2172 rocketModel[i].numPorts - 1);
2174 if (num_aiops <= 0) {
2175 rcktpt_io_addr[i] = 0;
2176 return (0);
2178 is_PCI[i] = 1;
2180 /* Reset the AIOPIC, init the serial ports */
2181 for (aiop = 0; aiop < num_aiops; aiop++) {
2182 sResetAiopByNum(ctlp, aiop);
2183 num_chan = ports_per_aiop;
2184 for (chan = 0; chan < num_chan; chan++)
2185 init_r_port(i, aiop, chan, dev);
2188 /* Rocket modems must be reset */
2189 if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) ||
2190 (rcktpt_type[i] == ROCKET_TYPE_MODEMII) ||
2191 (rcktpt_type[i] == ROCKET_TYPE_MODEMIII)) {
2192 num_chan = ports_per_aiop;
2193 for (chan = 0; chan < num_chan; chan++)
2194 sPCIModemReset(ctlp, chan, 1);
2195 mdelay(500);
2196 for (chan = 0; chan < num_chan; chan++)
2197 sPCIModemReset(ctlp, chan, 0);
2198 mdelay(500);
2199 rmSpeakerReset(ctlp, rocketModel[i].model);
2201 return (1);
2205 * Probes for PCI cards, inits them if found
2206 * Input: board_found = number of ISA boards already found, or the
2207 * starting board number
2208 * Returns: Number of PCI boards found
2210 static int __init init_PCI(int boards_found)
2212 struct pci_dev *dev = NULL;
2213 int count = 0;
2215 /* Work through the PCI device list, pulling out ours */
2216 while ((dev = pci_get_device(PCI_VENDOR_ID_RP, PCI_ANY_ID, dev))) {
2217 if (register_PCI(count + boards_found, dev))
2218 count++;
2220 return (count);
2223 #endif /* CONFIG_PCI */
2226 * Probes for ISA cards
2227 * Input: i = the board number to look for
2228 * Returns: 1 if board found, 0 else
2230 static int __init init_ISA(int i)
2232 int num_aiops, num_chan = 0, total_num_chan = 0;
2233 int aiop, chan;
2234 unsigned int aiopio[MAX_AIOPS_PER_BOARD];
2235 CONTROLLER_t *ctlp;
2236 char *type_string;
2238 /* If io_addr is zero, no board configured */
2239 if (rcktpt_io_addr[i] == 0)
2240 return (0);
2242 /* Reserve the IO region */
2243 if (!request_region(rcktpt_io_addr[i], 64, "Comtrol RocketPort")) {
2244 printk(KERN_INFO "Unable to reserve IO region for configured ISA RocketPort at address 0x%lx, board not installed...\n", rcktpt_io_addr[i]);
2245 rcktpt_io_addr[i] = 0;
2246 return (0);
2249 ctlp = sCtlNumToCtlPtr(i);
2251 ctlp->boardType = rcktpt_type[i];
2253 switch (rcktpt_type[i]) {
2254 case ROCKET_TYPE_PC104:
2255 type_string = "(PC104)";
2256 break;
2257 case ROCKET_TYPE_MODEM:
2258 type_string = "(RocketModem)";
2259 break;
2260 case ROCKET_TYPE_MODEMII:
2261 type_string = "(RocketModem II)";
2262 break;
2263 default:
2264 type_string = "";
2265 break;
2269 * If support_low_speed is set, use the slow clock prescale,
2270 * which supports 50 bps
2272 if (support_low_speed) {
2273 sClockPrescale = 0x19; /* mod 9 (divide by 10) prescale */
2274 rp_baud_base[i] = 230400;
2275 } else {
2276 sClockPrescale = 0x14; /* mod 4 (devide by 5) prescale */
2277 rp_baud_base[i] = 460800;
2280 for (aiop = 0; aiop < MAX_AIOPS_PER_BOARD; aiop++)
2281 aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x400);
2283 num_aiops = sInitController(ctlp, i, controller + (i * 0x400), aiopio, MAX_AIOPS_PER_BOARD, 0, FREQ_DIS, 0);
2285 if (ctlp->boardType == ROCKET_TYPE_PC104) {
2286 sEnAiop(ctlp, 2); /* only one AIOPIC, but these */
2287 sEnAiop(ctlp, 3); /* CSels used for other stuff */
2290 /* If something went wrong initing the AIOP's release the ISA IO memory */
2291 if (num_aiops <= 0) {
2292 release_region(rcktpt_io_addr[i], 64);
2293 rcktpt_io_addr[i] = 0;
2294 return (0);
2297 rocketModel[i].startingPortNumber = nextLineNumber;
2299 for (aiop = 0; aiop < num_aiops; aiop++) {
2300 sResetAiopByNum(ctlp, aiop);
2301 sEnAiop(ctlp, aiop);
2302 num_chan = sGetAiopNumChan(ctlp, aiop);
2303 total_num_chan += num_chan;
2304 for (chan = 0; chan < num_chan; chan++)
2305 init_r_port(i, aiop, chan, NULL);
2307 is_PCI[i] = 0;
2308 if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) || (rcktpt_type[i] == ROCKET_TYPE_MODEMII)) {
2309 num_chan = sGetAiopNumChan(ctlp, 0);
2310 total_num_chan = num_chan;
2311 for (chan = 0; chan < num_chan; chan++)
2312 sModemReset(ctlp, chan, 1);
2313 mdelay(500);
2314 for (chan = 0; chan < num_chan; chan++)
2315 sModemReset(ctlp, chan, 0);
2316 mdelay(500);
2317 strcpy(rocketModel[i].modelString, "RocketModem ISA");
2318 } else {
2319 strcpy(rocketModel[i].modelString, "RocketPort ISA");
2321 rocketModel[i].numPorts = total_num_chan;
2322 rocketModel[i].model = MODEL_ISA;
2324 printk(KERN_INFO "RocketPort ISA card #%d found at 0x%lx - %d AIOPs %s\n",
2325 i, rcktpt_io_addr[i], num_aiops, type_string);
2327 printk(KERN_INFO "Installing %s, creating /dev/ttyR%d - %ld\n",
2328 rocketModel[i].modelString,
2329 rocketModel[i].startingPortNumber,
2330 rocketModel[i].startingPortNumber +
2331 rocketModel[i].numPorts - 1);
2333 return (1);
2336 static const struct tty_operations rocket_ops = {
2337 .open = rp_open,
2338 .close = rp_close,
2339 .write = rp_write,
2340 .put_char = rp_put_char,
2341 .write_room = rp_write_room,
2342 .chars_in_buffer = rp_chars_in_buffer,
2343 .flush_buffer = rp_flush_buffer,
2344 .ioctl = rp_ioctl,
2345 .throttle = rp_throttle,
2346 .unthrottle = rp_unthrottle,
2347 .set_termios = rp_set_termios,
2348 .stop = rp_stop,
2349 .start = rp_start,
2350 .hangup = rp_hangup,
2351 .break_ctl = rp_break,
2352 .send_xchar = rp_send_xchar,
2353 .wait_until_sent = rp_wait_until_sent,
2354 .tiocmget = rp_tiocmget,
2355 .tiocmset = rp_tiocmset,
2359 * The module "startup" routine; it's run when the module is loaded.
2361 static int __init rp_init(void)
2363 int retval, pci_boards_found, isa_boards_found, i;
2365 printk(KERN_INFO "RocketPort device driver module, version %s, %s\n",
2366 ROCKET_VERSION, ROCKET_DATE);
2368 rocket_driver = alloc_tty_driver(MAX_RP_PORTS);
2369 if (!rocket_driver)
2370 return -ENOMEM;
2373 * Initialize the array of pointers to our own internal state
2374 * structures.
2376 memset(rp_table, 0, sizeof (rp_table));
2377 memset(xmit_flags, 0, sizeof (xmit_flags));
2379 for (i = 0; i < MAX_RP_PORTS; i++)
2380 lineNumbers[i] = 0;
2381 nextLineNumber = 0;
2382 memset(rocketModel, 0, sizeof (rocketModel));
2385 * If board 1 is non-zero, there is at least one ISA configured. If controller is
2386 * zero, use the default controller IO address of board1 + 0x40.
2388 if (board1) {
2389 if (controller == 0)
2390 controller = board1 + 0x40;
2391 } else {
2392 controller = 0; /* Used as a flag, meaning no ISA boards */
2395 /* If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */
2396 if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) {
2397 printk(KERN_INFO "Unable to reserve IO region for first configured ISA RocketPort controller 0x%lx. Driver exiting \n", controller);
2398 return -EBUSY;
2401 /* Store ISA variable retrieved from command line or .conf file. */
2402 rcktpt_io_addr[0] = board1;
2403 rcktpt_io_addr[1] = board2;
2404 rcktpt_io_addr[2] = board3;
2405 rcktpt_io_addr[3] = board4;
2407 rcktpt_type[0] = modem1 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2408 rcktpt_type[0] = pc104_1[0] ? ROCKET_TYPE_PC104 : rcktpt_type[0];
2409 rcktpt_type[1] = modem2 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2410 rcktpt_type[1] = pc104_2[0] ? ROCKET_TYPE_PC104 : rcktpt_type[1];
2411 rcktpt_type[2] = modem3 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2412 rcktpt_type[2] = pc104_3[0] ? ROCKET_TYPE_PC104 : rcktpt_type[2];
2413 rcktpt_type[3] = modem4 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2414 rcktpt_type[3] = pc104_4[0] ? ROCKET_TYPE_PC104 : rcktpt_type[3];
2417 * Set up the tty driver structure and then register this
2418 * driver with the tty layer.
2421 rocket_driver->owner = THIS_MODULE;
2422 rocket_driver->flags = TTY_DRIVER_DYNAMIC_DEV;
2423 rocket_driver->name = "ttyR";
2424 rocket_driver->driver_name = "Comtrol RocketPort";
2425 rocket_driver->major = TTY_ROCKET_MAJOR;
2426 rocket_driver->minor_start = 0;
2427 rocket_driver->type = TTY_DRIVER_TYPE_SERIAL;
2428 rocket_driver->subtype = SERIAL_TYPE_NORMAL;
2429 rocket_driver->init_termios = tty_std_termios;
2430 rocket_driver->init_termios.c_cflag =
2431 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2432 rocket_driver->init_termios.c_ispeed = 9600;
2433 rocket_driver->init_termios.c_ospeed = 9600;
2434 #ifdef ROCKET_SOFT_FLOW
2435 rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
2436 #endif
2437 tty_set_operations(rocket_driver, &rocket_ops);
2439 retval = tty_register_driver(rocket_driver);
2440 if (retval < 0) {
2441 printk(KERN_INFO "Couldn't install tty RocketPort driver (error %d)\n", -retval);
2442 put_tty_driver(rocket_driver);
2443 return -1;
2446 #ifdef ROCKET_DEBUG_OPEN
2447 printk(KERN_INFO "RocketPort driver is major %d\n", rocket_driver.major);
2448 #endif
2451 * OK, let's probe each of the controllers looking for boards. Any boards found
2452 * will be initialized here.
2454 isa_boards_found = 0;
2455 pci_boards_found = 0;
2457 for (i = 0; i < NUM_BOARDS; i++) {
2458 if (init_ISA(i))
2459 isa_boards_found++;
2462 #ifdef CONFIG_PCI
2463 if (isa_boards_found < NUM_BOARDS)
2464 pci_boards_found = init_PCI(isa_boards_found);
2465 #endif
2467 max_board = pci_boards_found + isa_boards_found;
2469 if (max_board == 0) {
2470 printk(KERN_INFO "No rocketport ports found; unloading driver.\n");
2471 del_timer_sync(&rocket_timer);
2472 tty_unregister_driver(rocket_driver);
2473 put_tty_driver(rocket_driver);
2474 return -ENXIO;
2477 return 0;
2481 static void rp_cleanup_module(void)
2483 int retval;
2484 int i;
2486 del_timer_sync(&rocket_timer);
2488 retval = tty_unregister_driver(rocket_driver);
2489 if (retval)
2490 printk(KERN_INFO "Error %d while trying to unregister "
2491 "rocketport driver\n", -retval);
2492 put_tty_driver(rocket_driver);
2494 for (i = 0; i < MAX_RP_PORTS; i++)
2495 kfree(rp_table[i]);
2497 for (i = 0; i < NUM_BOARDS; i++) {
2498 if (rcktpt_io_addr[i] <= 0 || is_PCI[i])
2499 continue;
2500 release_region(rcktpt_io_addr[i], 64);
2502 if (controller)
2503 release_region(controller, 4);
2506 /***************************************************************************
2507 Function: sInitController
2508 Purpose: Initialization of controller global registers and controller
2509 structure.
2510 Call: sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize,
2511 IRQNum,Frequency,PeriodicOnly)
2512 CONTROLLER_T *CtlP; Ptr to controller structure
2513 int CtlNum; Controller number
2514 ByteIO_t MudbacIO; Mudbac base I/O address.
2515 ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
2516 This list must be in the order the AIOPs will be found on the
2517 controller. Once an AIOP in the list is not found, it is
2518 assumed that there are no more AIOPs on the controller.
2519 int AiopIOListSize; Number of addresses in AiopIOList
2520 int IRQNum; Interrupt Request number. Can be any of the following:
2521 0: Disable global interrupts
2522 3: IRQ 3
2523 4: IRQ 4
2524 5: IRQ 5
2525 9: IRQ 9
2526 10: IRQ 10
2527 11: IRQ 11
2528 12: IRQ 12
2529 15: IRQ 15
2530 Byte_t Frequency: A flag identifying the frequency
2531 of the periodic interrupt, can be any one of the following:
2532 FREQ_DIS - periodic interrupt disabled
2533 FREQ_137HZ - 137 Hertz
2534 FREQ_69HZ - 69 Hertz
2535 FREQ_34HZ - 34 Hertz
2536 FREQ_17HZ - 17 Hertz
2537 FREQ_9HZ - 9 Hertz
2538 FREQ_4HZ - 4 Hertz
2539 If IRQNum is set to 0 the Frequency parameter is
2540 overidden, it is forced to a value of FREQ_DIS.
2541 int PeriodicOnly: 1 if all interrupts except the periodic
2542 interrupt are to be blocked.
2543 0 is both the periodic interrupt and
2544 other channel interrupts are allowed.
2545 If IRQNum is set to 0 the PeriodicOnly parameter is
2546 overidden, it is forced to a value of 0.
2547 Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
2548 initialization failed.
2550 Comments:
2551 If periodic interrupts are to be disabled but AIOP interrupts
2552 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
2554 If interrupts are to be completely disabled set IRQNum to 0.
2556 Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
2557 invalid combination.
2559 This function performs initialization of global interrupt modes,
2560 but it does not actually enable global interrupts. To enable
2561 and disable global interrupts use functions sEnGlobalInt() and
2562 sDisGlobalInt(). Enabling of global interrupts is normally not
2563 done until all other initializations are complete.
2565 Even if interrupts are globally enabled, they must also be
2566 individually enabled for each channel that is to generate
2567 interrupts.
2569 Warnings: No range checking on any of the parameters is done.
2571 No context switches are allowed while executing this function.
2573 After this function all AIOPs on the controller are disabled,
2574 they can be enabled with sEnAiop().
2576 static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
2577 ByteIO_t * AiopIOList, int AiopIOListSize,
2578 int IRQNum, Byte_t Frequency, int PeriodicOnly)
2580 int i;
2581 ByteIO_t io;
2582 int done;
2584 CtlP->AiopIntrBits = aiop_intr_bits;
2585 CtlP->AltChanRingIndicator = 0;
2586 CtlP->CtlNum = CtlNum;
2587 CtlP->CtlID = CTLID_0001; /* controller release 1 */
2588 CtlP->BusType = isISA;
2589 CtlP->MBaseIO = MudbacIO;
2590 CtlP->MReg1IO = MudbacIO + 1;
2591 CtlP->MReg2IO = MudbacIO + 2;
2592 CtlP->MReg3IO = MudbacIO + 3;
2593 #if 1
2594 CtlP->MReg2 = 0; /* interrupt disable */
2595 CtlP->MReg3 = 0; /* no periodic interrupts */
2596 #else
2597 if (sIRQMap[IRQNum] == 0) { /* interrupts globally disabled */
2598 CtlP->MReg2 = 0; /* interrupt disable */
2599 CtlP->MReg3 = 0; /* no periodic interrupts */
2600 } else {
2601 CtlP->MReg2 = sIRQMap[IRQNum]; /* set IRQ number */
2602 CtlP->MReg3 = Frequency; /* set frequency */
2603 if (PeriodicOnly) { /* periodic interrupt only */
2604 CtlP->MReg3 |= PERIODIC_ONLY;
2607 #endif
2608 sOutB(CtlP->MReg2IO, CtlP->MReg2);
2609 sOutB(CtlP->MReg3IO, CtlP->MReg3);
2610 sControllerEOI(CtlP); /* clear EOI if warm init */
2611 /* Init AIOPs */
2612 CtlP->NumAiop = 0;
2613 for (i = done = 0; i < AiopIOListSize; i++) {
2614 io = AiopIOList[i];
2615 CtlP->AiopIO[i] = (WordIO_t) io;
2616 CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
2617 sOutB(CtlP->MReg2IO, CtlP->MReg2 | (i & 0x03)); /* AIOP index */
2618 sOutB(MudbacIO, (Byte_t) (io >> 6)); /* set up AIOP I/O in MUDBAC */
2619 if (done)
2620 continue;
2621 sEnAiop(CtlP, i); /* enable the AIOP */
2622 CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */
2623 if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */
2624 done = 1; /* done looking for AIOPs */
2625 else {
2626 CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */
2627 sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */
2628 sOutB(io + _INDX_DATA, sClockPrescale);
2629 CtlP->NumAiop++; /* bump count of AIOPs */
2631 sDisAiop(CtlP, i); /* disable AIOP */
2634 if (CtlP->NumAiop == 0)
2635 return (-1);
2636 else
2637 return (CtlP->NumAiop);
2640 /***************************************************************************
2641 Function: sPCIInitController
2642 Purpose: Initialization of controller global registers and controller
2643 structure.
2644 Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize,
2645 IRQNum,Frequency,PeriodicOnly)
2646 CONTROLLER_T *CtlP; Ptr to controller structure
2647 int CtlNum; Controller number
2648 ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
2649 This list must be in the order the AIOPs will be found on the
2650 controller. Once an AIOP in the list is not found, it is
2651 assumed that there are no more AIOPs on the controller.
2652 int AiopIOListSize; Number of addresses in AiopIOList
2653 int IRQNum; Interrupt Request number. Can be any of the following:
2654 0: Disable global interrupts
2655 3: IRQ 3
2656 4: IRQ 4
2657 5: IRQ 5
2658 9: IRQ 9
2659 10: IRQ 10
2660 11: IRQ 11
2661 12: IRQ 12
2662 15: IRQ 15
2663 Byte_t Frequency: A flag identifying the frequency
2664 of the periodic interrupt, can be any one of the following:
2665 FREQ_DIS - periodic interrupt disabled
2666 FREQ_137HZ - 137 Hertz
2667 FREQ_69HZ - 69 Hertz
2668 FREQ_34HZ - 34 Hertz
2669 FREQ_17HZ - 17 Hertz
2670 FREQ_9HZ - 9 Hertz
2671 FREQ_4HZ - 4 Hertz
2672 If IRQNum is set to 0 the Frequency parameter is
2673 overidden, it is forced to a value of FREQ_DIS.
2674 int PeriodicOnly: 1 if all interrupts except the periodic
2675 interrupt are to be blocked.
2676 0 is both the periodic interrupt and
2677 other channel interrupts are allowed.
2678 If IRQNum is set to 0 the PeriodicOnly parameter is
2679 overidden, it is forced to a value of 0.
2680 Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
2681 initialization failed.
2683 Comments:
2684 If periodic interrupts are to be disabled but AIOP interrupts
2685 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
2687 If interrupts are to be completely disabled set IRQNum to 0.
2689 Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
2690 invalid combination.
2692 This function performs initialization of global interrupt modes,
2693 but it does not actually enable global interrupts. To enable
2694 and disable global interrupts use functions sEnGlobalInt() and
2695 sDisGlobalInt(). Enabling of global interrupts is normally not
2696 done until all other initializations are complete.
2698 Even if interrupts are globally enabled, they must also be
2699 individually enabled for each channel that is to generate
2700 interrupts.
2702 Warnings: No range checking on any of the parameters is done.
2704 No context switches are allowed while executing this function.
2706 After this function all AIOPs on the controller are disabled,
2707 they can be enabled with sEnAiop().
2709 static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
2710 ByteIO_t * AiopIOList, int AiopIOListSize,
2711 WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
2712 int PeriodicOnly, int altChanRingIndicator,
2713 int UPCIRingInd)
2715 int i;
2716 ByteIO_t io;
2718 CtlP->AltChanRingIndicator = altChanRingIndicator;
2719 CtlP->UPCIRingInd = UPCIRingInd;
2720 CtlP->CtlNum = CtlNum;
2721 CtlP->CtlID = CTLID_0001; /* controller release 1 */
2722 CtlP->BusType = isPCI; /* controller release 1 */
2724 if (ConfigIO) {
2725 CtlP->isUPCI = 1;
2726 CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL;
2727 CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL;
2728 CtlP->AiopIntrBits = upci_aiop_intr_bits;
2729 } else {
2730 CtlP->isUPCI = 0;
2731 CtlP->PCIIO =
2732 (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC);
2733 CtlP->AiopIntrBits = aiop_intr_bits;
2736 sPCIControllerEOI(CtlP); /* clear EOI if warm init */
2737 /* Init AIOPs */
2738 CtlP->NumAiop = 0;
2739 for (i = 0; i < AiopIOListSize; i++) {
2740 io = AiopIOList[i];
2741 CtlP->AiopIO[i] = (WordIO_t) io;
2742 CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
2744 CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */
2745 if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */
2746 break; /* done looking for AIOPs */
2748 CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */
2749 sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */
2750 sOutB(io + _INDX_DATA, sClockPrescale);
2751 CtlP->NumAiop++; /* bump count of AIOPs */
2754 if (CtlP->NumAiop == 0)
2755 return (-1);
2756 else
2757 return (CtlP->NumAiop);
2760 /***************************************************************************
2761 Function: sReadAiopID
2762 Purpose: Read the AIOP idenfication number directly from an AIOP.
2763 Call: sReadAiopID(io)
2764 ByteIO_t io: AIOP base I/O address
2765 Return: int: Flag AIOPID_XXXX if a valid AIOP is found, where X
2766 is replace by an identifying number.
2767 Flag AIOPID_NULL if no valid AIOP is found
2768 Warnings: No context switches are allowed while executing this function.
2771 static int sReadAiopID(ByteIO_t io)
2773 Byte_t AiopID; /* ID byte from AIOP */
2775 sOutB(io + _CMD_REG, RESET_ALL); /* reset AIOP */
2776 sOutB(io + _CMD_REG, 0x0);
2777 AiopID = sInW(io + _CHN_STAT0) & 0x07;
2778 if (AiopID == 0x06)
2779 return (1);
2780 else /* AIOP does not exist */
2781 return (-1);
2784 /***************************************************************************
2785 Function: sReadAiopNumChan
2786 Purpose: Read the number of channels available in an AIOP directly from
2787 an AIOP.
2788 Call: sReadAiopNumChan(io)
2789 WordIO_t io: AIOP base I/O address
2790 Return: int: The number of channels available
2791 Comments: The number of channels is determined by write/reads from identical
2792 offsets within the SRAM address spaces for channels 0 and 4.
2793 If the channel 4 space is mirrored to channel 0 it is a 4 channel
2794 AIOP, otherwise it is an 8 channel.
2795 Warnings: No context switches are allowed while executing this function.
2797 static int sReadAiopNumChan(WordIO_t io)
2799 Word_t x;
2800 static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 };
2802 /* write to chan 0 SRAM */
2803 sOutDW((DWordIO_t) io + _INDX_ADDR, *((DWord_t *) & R[0]));
2804 sOutW(io + _INDX_ADDR, 0); /* read from SRAM, chan 0 */
2805 x = sInW(io + _INDX_DATA);
2806 sOutW(io + _INDX_ADDR, 0x4000); /* read from SRAM, chan 4 */
2807 if (x != sInW(io + _INDX_DATA)) /* if different must be 8 chan */
2808 return (8);
2809 else
2810 return (4);
2813 /***************************************************************************
2814 Function: sInitChan
2815 Purpose: Initialization of a channel and channel structure
2816 Call: sInitChan(CtlP,ChP,AiopNum,ChanNum)
2817 CONTROLLER_T *CtlP; Ptr to controller structure
2818 CHANNEL_T *ChP; Ptr to channel structure
2819 int AiopNum; AIOP number within controller
2820 int ChanNum; Channel number within AIOP
2821 Return: int: 1 if initialization succeeded, 0 if it fails because channel
2822 number exceeds number of channels available in AIOP.
2823 Comments: This function must be called before a channel can be used.
2824 Warnings: No range checking on any of the parameters is done.
2826 No context switches are allowed while executing this function.
2828 static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
2829 int ChanNum)
2831 int i;
2832 WordIO_t AiopIO;
2833 WordIO_t ChIOOff;
2834 Byte_t *ChR;
2835 Word_t ChOff;
2836 static Byte_t R[4];
2837 int brd9600;
2839 if (ChanNum >= CtlP->AiopNumChan[AiopNum])
2840 return 0; /* exceeds num chans in AIOP */
2842 /* Channel, AIOP, and controller identifiers */
2843 ChP->CtlP = CtlP;
2844 ChP->ChanID = CtlP->AiopID[AiopNum];
2845 ChP->AiopNum = AiopNum;
2846 ChP->ChanNum = ChanNum;
2848 /* Global direct addresses */
2849 AiopIO = CtlP->AiopIO[AiopNum];
2850 ChP->Cmd = (ByteIO_t) AiopIO + _CMD_REG;
2851 ChP->IntChan = (ByteIO_t) AiopIO + _INT_CHAN;
2852 ChP->IntMask = (ByteIO_t) AiopIO + _INT_MASK;
2853 ChP->IndexAddr = (DWordIO_t) AiopIO + _INDX_ADDR;
2854 ChP->IndexData = AiopIO + _INDX_DATA;
2856 /* Channel direct addresses */
2857 ChIOOff = AiopIO + ChP->ChanNum * 2;
2858 ChP->TxRxData = ChIOOff + _TD0;
2859 ChP->ChanStat = ChIOOff + _CHN_STAT0;
2860 ChP->TxRxCount = ChIOOff + _FIFO_CNT0;
2861 ChP->IntID = (ByteIO_t) AiopIO + ChP->ChanNum + _INT_ID0;
2863 /* Initialize the channel from the RData array */
2864 for (i = 0; i < RDATASIZE; i += 4) {
2865 R[0] = RData[i];
2866 R[1] = RData[i + 1] + 0x10 * ChanNum;
2867 R[2] = RData[i + 2];
2868 R[3] = RData[i + 3];
2869 sOutDW(ChP->IndexAddr, *((DWord_t *) & R[0]));
2872 ChR = ChP->R;
2873 for (i = 0; i < RREGDATASIZE; i += 4) {
2874 ChR[i] = RRegData[i];
2875 ChR[i + 1] = RRegData[i + 1] + 0x10 * ChanNum;
2876 ChR[i + 2] = RRegData[i + 2];
2877 ChR[i + 3] = RRegData[i + 3];
2880 /* Indexed registers */
2881 ChOff = (Word_t) ChanNum *0x1000;
2883 if (sClockPrescale == 0x14)
2884 brd9600 = 47;
2885 else
2886 brd9600 = 23;
2888 ChP->BaudDiv[0] = (Byte_t) (ChOff + _BAUD);
2889 ChP->BaudDiv[1] = (Byte_t) ((ChOff + _BAUD) >> 8);
2890 ChP->BaudDiv[2] = (Byte_t) brd9600;
2891 ChP->BaudDiv[3] = (Byte_t) (brd9600 >> 8);
2892 sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->BaudDiv[0]);
2894 ChP->TxControl[0] = (Byte_t) (ChOff + _TX_CTRL);
2895 ChP->TxControl[1] = (Byte_t) ((ChOff + _TX_CTRL) >> 8);
2896 ChP->TxControl[2] = 0;
2897 ChP->TxControl[3] = 0;
2898 sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxControl[0]);
2900 ChP->RxControl[0] = (Byte_t) (ChOff + _RX_CTRL);
2901 ChP->RxControl[1] = (Byte_t) ((ChOff + _RX_CTRL) >> 8);
2902 ChP->RxControl[2] = 0;
2903 ChP->RxControl[3] = 0;
2904 sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->RxControl[0]);
2906 ChP->TxEnables[0] = (Byte_t) (ChOff + _TX_ENBLS);
2907 ChP->TxEnables[1] = (Byte_t) ((ChOff + _TX_ENBLS) >> 8);
2908 ChP->TxEnables[2] = 0;
2909 ChP->TxEnables[3] = 0;
2910 sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxEnables[0]);
2912 ChP->TxCompare[0] = (Byte_t) (ChOff + _TXCMP1);
2913 ChP->TxCompare[1] = (Byte_t) ((ChOff + _TXCMP1) >> 8);
2914 ChP->TxCompare[2] = 0;
2915 ChP->TxCompare[3] = 0;
2916 sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxCompare[0]);
2918 ChP->TxReplace1[0] = (Byte_t) (ChOff + _TXREP1B1);
2919 ChP->TxReplace1[1] = (Byte_t) ((ChOff + _TXREP1B1) >> 8);
2920 ChP->TxReplace1[2] = 0;
2921 ChP->TxReplace1[3] = 0;
2922 sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxReplace1[0]);
2924 ChP->TxReplace2[0] = (Byte_t) (ChOff + _TXREP2);
2925 ChP->TxReplace2[1] = (Byte_t) ((ChOff + _TXREP2) >> 8);
2926 ChP->TxReplace2[2] = 0;
2927 ChP->TxReplace2[3] = 0;
2928 sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxReplace2[0]);
2930 ChP->TxFIFOPtrs = ChOff + _TXF_OUTP;
2931 ChP->TxFIFO = ChOff + _TX_FIFO;
2933 sOutB(ChP->Cmd, (Byte_t) ChanNum | RESTXFCNT); /* apply reset Tx FIFO count */
2934 sOutB(ChP->Cmd, (Byte_t) ChanNum); /* remove reset Tx FIFO count */
2935 sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
2936 sOutW(ChP->IndexData, 0);
2937 ChP->RxFIFOPtrs = ChOff + _RXF_OUTP;
2938 ChP->RxFIFO = ChOff + _RX_FIFO;
2940 sOutB(ChP->Cmd, (Byte_t) ChanNum | RESRXFCNT); /* apply reset Rx FIFO count */
2941 sOutB(ChP->Cmd, (Byte_t) ChanNum); /* remove reset Rx FIFO count */
2942 sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs); /* clear Rx out ptr */
2943 sOutW(ChP->IndexData, 0);
2944 sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
2945 sOutW(ChP->IndexData, 0);
2946 ChP->TxPrioCnt = ChOff + _TXP_CNT;
2947 sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioCnt);
2948 sOutB(ChP->IndexData, 0);
2949 ChP->TxPrioPtr = ChOff + _TXP_PNTR;
2950 sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioPtr);
2951 sOutB(ChP->IndexData, 0);
2952 ChP->TxPrioBuf = ChOff + _TXP_BUF;
2953 sEnRxProcessor(ChP); /* start the Rx processor */
2955 return 1;
2958 /***************************************************************************
2959 Function: sStopRxProcessor
2960 Purpose: Stop the receive processor from processing a channel.
2961 Call: sStopRxProcessor(ChP)
2962 CHANNEL_T *ChP; Ptr to channel structure
2964 Comments: The receive processor can be started again with sStartRxProcessor().
2965 This function causes the receive processor to skip over the
2966 stopped channel. It does not stop it from processing other channels.
2968 Warnings: No context switches are allowed while executing this function.
2970 Do not leave the receive processor stopped for more than one
2971 character time.
2973 After calling this function a delay of 4 uS is required to ensure
2974 that the receive processor is no longer processing this channel.
2976 static void sStopRxProcessor(CHANNEL_T * ChP)
2978 Byte_t R[4];
2980 R[0] = ChP->R[0];
2981 R[1] = ChP->R[1];
2982 R[2] = 0x0a;
2983 R[3] = ChP->R[3];
2984 sOutDW(ChP->IndexAddr, *(DWord_t *) & R[0]);
2987 /***************************************************************************
2988 Function: sFlushRxFIFO
2989 Purpose: Flush the Rx FIFO
2990 Call: sFlushRxFIFO(ChP)
2991 CHANNEL_T *ChP; Ptr to channel structure
2992 Return: void
2993 Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
2994 while it is being flushed the receive processor is stopped
2995 and the transmitter is disabled. After these operations a
2996 4 uS delay is done before clearing the pointers to allow
2997 the receive processor to stop. These items are handled inside
2998 this function.
2999 Warnings: No context switches are allowed while executing this function.
3001 static void sFlushRxFIFO(CHANNEL_T * ChP)
3003 int i;
3004 Byte_t Ch; /* channel number within AIOP */
3005 int RxFIFOEnabled; /* 1 if Rx FIFO enabled */
3007 if (sGetRxCnt(ChP) == 0) /* Rx FIFO empty */
3008 return; /* don't need to flush */
3010 RxFIFOEnabled = 0;
3011 if (ChP->R[0x32] == 0x08) { /* Rx FIFO is enabled */
3012 RxFIFOEnabled = 1;
3013 sDisRxFIFO(ChP); /* disable it */
3014 for (i = 0; i < 2000 / 200; i++) /* delay 2 uS to allow proc to disable FIFO */
3015 sInB(ChP->IntChan); /* depends on bus i/o timing */
3017 sGetChanStatus(ChP); /* clear any pending Rx errors in chan stat */
3018 Ch = (Byte_t) sGetChanNum(ChP);
3019 sOutB(ChP->Cmd, Ch | RESRXFCNT); /* apply reset Rx FIFO count */
3020 sOutB(ChP->Cmd, Ch); /* remove reset Rx FIFO count */
3021 sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs); /* clear Rx out ptr */
3022 sOutW(ChP->IndexData, 0);
3023 sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
3024 sOutW(ChP->IndexData, 0);
3025 if (RxFIFOEnabled)
3026 sEnRxFIFO(ChP); /* enable Rx FIFO */
3029 /***************************************************************************
3030 Function: sFlushTxFIFO
3031 Purpose: Flush the Tx FIFO
3032 Call: sFlushTxFIFO(ChP)
3033 CHANNEL_T *ChP; Ptr to channel structure
3034 Return: void
3035 Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
3036 while it is being flushed the receive processor is stopped
3037 and the transmitter is disabled. After these operations a
3038 4 uS delay is done before clearing the pointers to allow
3039 the receive processor to stop. These items are handled inside
3040 this function.
3041 Warnings: No context switches are allowed while executing this function.
3043 static void sFlushTxFIFO(CHANNEL_T * ChP)
3045 int i;
3046 Byte_t Ch; /* channel number within AIOP */
3047 int TxEnabled; /* 1 if transmitter enabled */
3049 if (sGetTxCnt(ChP) == 0) /* Tx FIFO empty */
3050 return; /* don't need to flush */
3052 TxEnabled = 0;
3053 if (ChP->TxControl[3] & TX_ENABLE) {
3054 TxEnabled = 1;
3055 sDisTransmit(ChP); /* disable transmitter */
3057 sStopRxProcessor(ChP); /* stop Rx processor */
3058 for (i = 0; i < 4000 / 200; i++) /* delay 4 uS to allow proc to stop */
3059 sInB(ChP->IntChan); /* depends on bus i/o timing */
3060 Ch = (Byte_t) sGetChanNum(ChP);
3061 sOutB(ChP->Cmd, Ch | RESTXFCNT); /* apply reset Tx FIFO count */
3062 sOutB(ChP->Cmd, Ch); /* remove reset Tx FIFO count */
3063 sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
3064 sOutW(ChP->IndexData, 0);
3065 if (TxEnabled)
3066 sEnTransmit(ChP); /* enable transmitter */
3067 sStartRxProcessor(ChP); /* restart Rx processor */
3070 /***************************************************************************
3071 Function: sWriteTxPrioByte
3072 Purpose: Write a byte of priority transmit data to a channel
3073 Call: sWriteTxPrioByte(ChP,Data)
3074 CHANNEL_T *ChP; Ptr to channel structure
3075 Byte_t Data; The transmit data byte
3077 Return: int: 1 if the bytes is successfully written, otherwise 0.
3079 Comments: The priority byte is transmitted before any data in the Tx FIFO.
3081 Warnings: No context switches are allowed while executing this function.
3083 static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
3085 Byte_t DWBuf[4]; /* buffer for double word writes */
3086 Word_t *WordPtr; /* must be far because Win SS != DS */
3087 register DWordIO_t IndexAddr;
3089 if (sGetTxCnt(ChP) > 1) { /* write it to Tx priority buffer */
3090 IndexAddr = ChP->IndexAddr;
3091 sOutW((WordIO_t) IndexAddr, ChP->TxPrioCnt); /* get priority buffer status */
3092 if (sInB((ByteIO_t) ChP->IndexData) & PRI_PEND) /* priority buffer busy */
3093 return (0); /* nothing sent */
3095 WordPtr = (Word_t *) (&DWBuf[0]);
3096 *WordPtr = ChP->TxPrioBuf; /* data byte address */
3098 DWBuf[2] = Data; /* data byte value */
3099 sOutDW(IndexAddr, *((DWord_t *) (&DWBuf[0]))); /* write it out */
3101 *WordPtr = ChP->TxPrioCnt; /* Tx priority count address */
3103 DWBuf[2] = PRI_PEND + 1; /* indicate 1 byte pending */
3104 DWBuf[3] = 0; /* priority buffer pointer */
3105 sOutDW(IndexAddr, *((DWord_t *) (&DWBuf[0]))); /* write it out */
3106 } else { /* write it to Tx FIFO */
3108 sWriteTxByte(sGetTxRxDataIO(ChP), Data);
3110 return (1); /* 1 byte sent */
3113 /***************************************************************************
3114 Function: sEnInterrupts
3115 Purpose: Enable one or more interrupts for a channel
3116 Call: sEnInterrupts(ChP,Flags)
3117 CHANNEL_T *ChP; Ptr to channel structure
3118 Word_t Flags: Interrupt enable flags, can be any combination
3119 of the following flags:
3120 TXINT_EN: Interrupt on Tx FIFO empty
3121 RXINT_EN: Interrupt on Rx FIFO at trigger level (see
3122 sSetRxTrigger())
3123 SRCINT_EN: Interrupt on SRC (Special Rx Condition)
3124 MCINT_EN: Interrupt on modem input change
3125 CHANINT_EN: Allow channel interrupt signal to the AIOP's
3126 Interrupt Channel Register.
3127 Return: void
3128 Comments: If an interrupt enable flag is set in Flags, that interrupt will be
3129 enabled. If an interrupt enable flag is not set in Flags, that
3130 interrupt will not be changed. Interrupts can be disabled with
3131 function sDisInterrupts().
3133 This function sets the appropriate bit for the channel in the AIOP's
3134 Interrupt Mask Register if the CHANINT_EN flag is set. This allows
3135 this channel's bit to be set in the AIOP's Interrupt Channel Register.
3137 Interrupts must also be globally enabled before channel interrupts
3138 will be passed on to the host. This is done with function
3139 sEnGlobalInt().
3141 In some cases it may be desirable to disable interrupts globally but
3142 enable channel interrupts. This would allow the global interrupt
3143 status register to be used to determine which AIOPs need service.
3145 static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
3147 Byte_t Mask; /* Interrupt Mask Register */
3149 ChP->RxControl[2] |=
3150 ((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
3152 sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->RxControl[0]);
3154 ChP->TxControl[2] |= ((Byte_t) Flags & TXINT_EN);
3156 sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxControl[0]);
3158 if (Flags & CHANINT_EN) {
3159 Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum];
3160 sOutB(ChP->IntMask, Mask);
3164 /***************************************************************************
3165 Function: sDisInterrupts
3166 Purpose: Disable one or more interrupts for a channel
3167 Call: sDisInterrupts(ChP,Flags)
3168 CHANNEL_T *ChP; Ptr to channel structure
3169 Word_t Flags: Interrupt flags, can be any combination
3170 of the following flags:
3171 TXINT_EN: Interrupt on Tx FIFO empty
3172 RXINT_EN: Interrupt on Rx FIFO at trigger level (see
3173 sSetRxTrigger())
3174 SRCINT_EN: Interrupt on SRC (Special Rx Condition)
3175 MCINT_EN: Interrupt on modem input change
3176 CHANINT_EN: Disable channel interrupt signal to the
3177 AIOP's Interrupt Channel Register.
3178 Return: void
3179 Comments: If an interrupt flag is set in Flags, that interrupt will be
3180 disabled. If an interrupt flag is not set in Flags, that
3181 interrupt will not be changed. Interrupts can be enabled with
3182 function sEnInterrupts().
3184 This function clears the appropriate bit for the channel in the AIOP's
3185 Interrupt Mask Register if the CHANINT_EN flag is set. This blocks
3186 this channel's bit from being set in the AIOP's Interrupt Channel
3187 Register.
3189 static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
3191 Byte_t Mask; /* Interrupt Mask Register */
3193 ChP->RxControl[2] &=
3194 ~((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
3195 sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->RxControl[0]);
3196 ChP->TxControl[2] &= ~((Byte_t) Flags & TXINT_EN);
3197 sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxControl[0]);
3199 if (Flags & CHANINT_EN) {
3200 Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum];
3201 sOutB(ChP->IntMask, Mask);
3205 static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
3207 sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum);
3211 * Not an official SSCI function, but how to reset RocketModems.
3212 * ISA bus version
3214 static void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
3216 ByteIO_t addr;
3217 Byte_t val;
3219 addr = CtlP->AiopIO[0] + 0x400;
3220 val = sInB(CtlP->MReg3IO);
3221 /* if AIOP[1] is not enabled, enable it */
3222 if ((val & 2) == 0) {
3223 val = sInB(CtlP->MReg2IO);
3224 sOutB(CtlP->MReg2IO, (val & 0xfc) | (1 & 0x03));
3225 sOutB(CtlP->MBaseIO, (unsigned char) (addr >> 6));
3228 sEnAiop(CtlP, 1);
3229 if (!on)
3230 addr += 8;
3231 sOutB(addr + chan, 0); /* apply or remove reset */
3232 sDisAiop(CtlP, 1);
3236 * Not an official SSCI function, but how to reset RocketModems.
3237 * PCI bus version
3239 static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
3241 ByteIO_t addr;
3243 addr = CtlP->AiopIO[0] + 0x40; /* 2nd AIOP */
3244 if (!on)
3245 addr += 8;
3246 sOutB(addr + chan, 0); /* apply or remove reset */
3249 /* Resets the speaker controller on RocketModem II and III devices */
3250 static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model)
3252 ByteIO_t addr;
3254 /* RocketModem II speaker control is at the 8th port location of offset 0x40 */
3255 if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) {
3256 addr = CtlP->AiopIO[0] + 0x4F;
3257 sOutB(addr, 0);
3260 /* RocketModem III speaker control is at the 1st port location of offset 0x80 */
3261 if ((model == MODEL_UPCI_RM3_8PORT)
3262 || (model == MODEL_UPCI_RM3_4PORT)) {
3263 addr = CtlP->AiopIO[0] + 0x88;
3264 sOutB(addr, 0);
3268 /* Returns the line number given the controller (board), aiop and channel number */
3269 static unsigned char GetLineNumber(int ctrl, int aiop, int ch)
3271 return lineNumbers[(ctrl << 5) | (aiop << 3) | ch];
3275 * Stores the line number associated with a given controller (board), aiop
3276 * and channel number.
3277 * Returns: The line number assigned
3279 static unsigned char SetLineNumber(int ctrl, int aiop, int ch)
3281 lineNumbers[(ctrl << 5) | (aiop << 3) | ch] = nextLineNumber++;
3282 return (nextLineNumber - 1);