2 * RocketPort device driver for Linux
4 * Written by Theodore Ts'o, 1995, 1996, 1997, 1998, 1999, 2000.
6 * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2003 by Comtrol, Inc.
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
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)
46 #define PCI_BASE_ADDRESS(dev, r) ((dev)->base_address[r])
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
62 #undef ROCKET_DEBUG_IO
64 #define POLL_PERIOD HZ/100 /* Polling period .01 seconds (10ms) */
66 /****** Kernel includes ******/
69 #include <config/modversions.h>
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>
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"
104 #define ROCKET_VERSION "2.09"
105 #define ROCKET_DATE "12-June-2003"
107 /****** RocketPort Local Variables ******/
109 static struct tty_driver
*rocket_driver
;
111 static struct rocket_version driver_version
= {
112 ROCKET_VERSION
, ROCKET_DATE
115 static struct r_port
*rp_table
[MAX_RP_PORTS
]; /* The main repository of serial port state information. */
116 static unsigned int xmit_flags
[NUM_BOARDS
]; /* Bit significant, indicates port had data to transmit. */
117 /* eg. Bit 0 indicates port 0 has xmit data, ... */
118 static atomic_t rp_num_ports_open
; /* Number of serial ports open */
119 static struct timer_list rocket_timer
;
121 static unsigned long board1
; /* ISA addresses, retrieved from rocketport.conf */
122 static unsigned long board2
;
123 static unsigned long board3
;
124 static unsigned long board4
;
125 static unsigned long controller
;
126 static int support_low_speed
;
127 static unsigned long modem1
;
128 static unsigned long modem2
;
129 static unsigned long modem3
;
130 static unsigned long modem4
;
131 static unsigned long pc104_1
[8];
132 static unsigned long pc104_2
[8];
133 static unsigned long pc104_3
[8];
134 static unsigned long pc104_4
[8];
135 static unsigned long *pc104
[4] = { pc104_1
, pc104_2
, pc104_3
, pc104_4
};
137 static int rp_baud_base
[NUM_BOARDS
]; /* Board config info (Someday make a per-board structure) */
138 static unsigned long rcktpt_io_addr
[NUM_BOARDS
];
139 static int rcktpt_type
[NUM_BOARDS
];
140 static int is_PCI
[NUM_BOARDS
];
141 static rocketModel_t rocketModel
[NUM_BOARDS
];
142 static int max_board
;
145 * The following arrays define the interrupt bits corresponding to each AIOP.
146 * These bits are different between the ISA and regular PCI boards and the
147 * Universal PCI boards.
150 static Word_t aiop_intr_bits
[AIOP_CTL_SIZE
] = {
157 static Word_t upci_aiop_intr_bits
[AIOP_CTL_SIZE
] = {
158 UPCI_AIOP_INTR_BIT_0
,
159 UPCI_AIOP_INTR_BIT_1
,
160 UPCI_AIOP_INTR_BIT_2
,
165 * Line number is the ttySIx number (x), the Minor number. We
166 * assign them sequentially, starting at zero. The following
167 * array keeps track of the line number assigned to a given board/aiop/channel.
169 static unsigned char lineNumbers
[MAX_RP_PORTS
];
170 static unsigned long nextLineNumber
;
172 /***** RocketPort Static Prototypes *********/
173 static int __init
init_ISA(int i
);
174 static void rp_wait_until_sent(struct tty_struct
*tty
, int timeout
);
175 static void rp_flush_buffer(struct tty_struct
*tty
);
176 static void rmSpeakerReset(CONTROLLER_T
* CtlP
, unsigned long model
);
177 static unsigned char GetLineNumber(int ctrl
, int aiop
, int ch
);
178 static unsigned char SetLineNumber(int ctrl
, int aiop
, int ch
);
179 static void rp_start(struct tty_struct
*tty
);
182 MODULE_AUTHOR("Theodore Ts'o");
183 MODULE_DESCRIPTION("Comtrol RocketPort driver");
184 module_param(board1
, ulong
, 0);
185 MODULE_PARM_DESC(board1
, "I/O port for (ISA) board #1");
186 module_param(board2
, ulong
, 0);
187 MODULE_PARM_DESC(board2
, "I/O port for (ISA) board #2");
188 module_param(board3
, ulong
, 0);
189 MODULE_PARM_DESC(board3
, "I/O port for (ISA) board #3");
190 module_param(board4
, ulong
, 0);
191 MODULE_PARM_DESC(board4
, "I/O port for (ISA) board #4");
192 module_param(controller
, ulong
, 0);
193 MODULE_PARM_DESC(controller
, "I/O port for (ISA) rocketport controller");
194 module_param(support_low_speed
, bool, 0);
195 MODULE_PARM_DESC(support_low_speed
, "1 means support 50 baud, 0 means support 460400 baud");
196 module_param(modem1
, ulong
, 0);
197 MODULE_PARM_DESC(modem1
, "1 means (ISA) board #1 is a RocketModem");
198 module_param(modem2
, ulong
, 0);
199 MODULE_PARM_DESC(modem2
, "1 means (ISA) board #2 is a RocketModem");
200 module_param(modem3
, ulong
, 0);
201 MODULE_PARM_DESC(modem3
, "1 means (ISA) board #3 is a RocketModem");
202 module_param(modem4
, ulong
, 0);
203 MODULE_PARM_DESC(modem4
, "1 means (ISA) board #4 is a RocketModem");
204 module_param_array(pc104_1
, ulong
, NULL
, 0);
205 MODULE_PARM_DESC(pc104_1
, "set interface types for ISA(PC104) board #1 (e.g. pc104_1=232,232,485,485,...");
206 module_param_array(pc104_2
, ulong
, NULL
, 0);
207 MODULE_PARM_DESC(pc104_2
, "set interface types for ISA(PC104) board #2 (e.g. pc104_2=232,232,485,485,...");
208 module_param_array(pc104_3
, ulong
, NULL
, 0);
209 MODULE_PARM_DESC(pc104_3
, "set interface types for ISA(PC104) board #3 (e.g. pc104_3=232,232,485,485,...");
210 module_param_array(pc104_4
, ulong
, NULL
, 0);
211 MODULE_PARM_DESC(pc104_4
, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,...");
214 static void rp_cleanup_module(void);
216 module_init(rp_init
);
217 module_exit(rp_cleanup_module
);
221 #ifdef MODULE_LICENSE
222 MODULE_LICENSE("Dual BSD/GPL");
225 /*************************************************************************/
226 /* Module code starts here */
228 static inline int rocket_paranoia_check(struct r_port
*info
,
231 #ifdef ROCKET_PARANOIA_CHECK
234 if (info
->magic
!= RPORT_MAGIC
) {
235 printk(KERN_INFO
"Warning: bad magic number for rocketport struct in %s\n",
244 /* Serial port receive data function. Called (from timer poll) when an AIOPIC signals
245 * that receive data is present on a serial port. Pulls data from FIFO, moves it into the
248 static void rp_do_receive(struct r_port
*info
,
249 struct tty_struct
*tty
,
250 CHANNEL_t
* cp
, unsigned int ChanStatus
)
252 unsigned int CharNStat
;
253 int ToRecv
, wRecv
, space
= 0, count
;
256 struct tty_ldisc
*ld
;
258 ld
= tty_ldisc_ref(tty
);
260 ToRecv
= sGetRxCnt(cp
);
262 space
= ld
->receive_room(tty
);
263 if (space
> 2 * TTY_FLIPBUF_SIZE
)
264 space
= 2 * TTY_FLIPBUF_SIZE
;
265 cbuf
= tty
->flip
.char_buf
;
266 fbuf
= tty
->flip
.flag_buf
;
268 #ifdef ROCKET_DEBUG_INTR
269 printk(KERN_INFO
"rp_do_receive(%d, %d)...", ToRecv
, space
);
273 * determine how many we can actually read in. If we can't
274 * read any in then we have a software overrun condition.
283 * if status indicates there are errored characters in the
284 * FIFO, then enter status mode (a word in FIFO holds
285 * character and status).
287 if (ChanStatus
& (RXFOVERFL
| RXBREAK
| RXFRAME
| RXPARITY
)) {
288 if (!(ChanStatus
& STATMODE
)) {
289 #ifdef ROCKET_DEBUG_RECEIVE
290 printk(KERN_INFO
"Entering STATMODE...");
292 ChanStatus
|= STATMODE
;
298 * if we previously entered status mode, then read down the
299 * FIFO one word at a time, pulling apart the character and
300 * the status. Update error counters depending on status
302 if (ChanStatus
& STATMODE
) {
303 #ifdef ROCKET_DEBUG_RECEIVE
304 printk(KERN_INFO
"Ignore %x, read %x...", info
->ignore_status_mask
,
305 info
->read_status_mask
);
308 CharNStat
= sInW(sGetTxRxDataIO(cp
));
309 #ifdef ROCKET_DEBUG_RECEIVE
310 printk(KERN_INFO
"%x...", CharNStat
);
312 if (CharNStat
& STMBREAKH
)
313 CharNStat
&= ~(STMFRAMEH
| STMPARITYH
);
314 if (CharNStat
& info
->ignore_status_mask
) {
318 CharNStat
&= info
->read_status_mask
;
319 if (CharNStat
& STMBREAKH
)
321 else if (CharNStat
& STMPARITYH
)
322 *fbuf
++ = TTY_PARITY
;
323 else if (CharNStat
& STMFRAMEH
)
325 else if (CharNStat
& STMRCVROVRH
)
326 *fbuf
++ = TTY_OVERRUN
;
329 *cbuf
++ = CharNStat
& 0xff;
335 * after we've emptied the FIFO in status mode, turn
336 * status mode back off
338 if (sGetRxCnt(cp
) == 0) {
339 #ifdef ROCKET_DEBUG_RECEIVE
340 printk(KERN_INFO
"Status mode off.\n");
342 sDisRxStatusMode(cp
);
346 * we aren't in status mode, so read down the FIFO two
347 * characters at time by doing repeated word IO
352 sInStrW(sGetTxRxDataIO(cp
), (unsigned short *) cbuf
, wRecv
);
354 cbuf
[ToRecv
- 1] = sInB(sGetTxRxDataIO(cp
));
355 memset(fbuf
, 0, ToRecv
);
360 /* Push the data up to the tty layer */
361 ld
->receive_buf(tty
, tty
->flip
.char_buf
, tty
->flip
.flag_buf
, count
);
366 * Serial port transmit data function. Called from the timer polling loop as a
367 * result of a bit set in xmit_flags[], indicating data (from the tty layer) is ready
368 * to be sent out the serial port. Data is buffered in rp_table[line].xmit_buf, it is
369 * moved to the port's xmit FIFO. *info is critical data, protected by spinlocks.
371 static void rp_do_transmit(struct r_port
*info
)
374 CHANNEL_t
*cp
= &info
->channel
;
375 struct tty_struct
*tty
;
378 #ifdef ROCKET_DEBUG_INTR
379 printk(KERN_INFO
"rp_do_transmit ");
384 printk(KERN_INFO
"rp: WARNING rp_do_transmit called with info->tty==NULL\n");
385 clear_bit((info
->aiop
* 8) + info
->chan
, (void *) &xmit_flags
[info
->board
]);
389 spin_lock_irqsave(&info
->slock
, flags
);
391 info
->xmit_fifo_room
= TXFIFO_SIZE
- sGetTxCnt(cp
);
393 /* Loop sending data to FIFO until done or FIFO full */
395 if (tty
->stopped
|| tty
->hw_stopped
)
397 c
= min(info
->xmit_fifo_room
, min(info
->xmit_cnt
, XMIT_BUF_SIZE
- info
->xmit_tail
));
398 if (c
<= 0 || info
->xmit_fifo_room
<= 0)
400 sOutStrW(sGetTxRxDataIO(cp
), (unsigned short *) (info
->xmit_buf
+ info
->xmit_tail
), c
/ 2);
402 sOutB(sGetTxRxDataIO(cp
), info
->xmit_buf
[info
->xmit_tail
+ c
- 1]);
403 info
->xmit_tail
+= c
;
404 info
->xmit_tail
&= XMIT_BUF_SIZE
- 1;
406 info
->xmit_fifo_room
-= c
;
407 #ifdef ROCKET_DEBUG_INTR
408 printk(KERN_INFO
"tx %d chars...", c
);
412 if (info
->xmit_cnt
== 0)
413 clear_bit((info
->aiop
* 8) + info
->chan
, (void *) &xmit_flags
[info
->board
]);
415 if (info
->xmit_cnt
< WAKEUP_CHARS
) {
417 wake_up_interruptible(&tty
->write_wait
);
418 #ifdef ROCKETPORT_HAVE_POLL_WAIT
419 wake_up_interruptible(&tty
->poll_wait
);
423 spin_unlock_irqrestore(&info
->slock
, flags
);
425 #ifdef ROCKET_DEBUG_INTR
426 printk(KERN_INFO
"(%d,%d,%d,%d)...", info
->xmit_cnt
, info
->xmit_head
,
427 info
->xmit_tail
, info
->xmit_fifo_room
);
432 * Called when a serial port signals it has read data in it's RX FIFO.
433 * It checks what interrupts are pending and services them, including
434 * receiving serial data.
436 static void rp_handle_port(struct r_port
*info
)
439 struct tty_struct
*tty
;
440 unsigned int IntMask
, ChanStatus
;
445 if ((info
->flags
& ROCKET_INITIALIZED
) == 0) {
446 printk(KERN_INFO
"rp: WARNING: rp_handle_port called with info->flags & NOT_INIT\n");
450 printk(KERN_INFO
"rp: WARNING: rp_handle_port called with info->tty==NULL\n");
456 IntMask
= sGetChanIntID(cp
) & info
->intmask
;
457 #ifdef ROCKET_DEBUG_INTR
458 printk(KERN_INFO
"rp_interrupt %02x...", IntMask
);
460 ChanStatus
= sGetChanStatus(cp
);
461 if (IntMask
& RXF_TRIG
) { /* Rx FIFO trigger level */
462 rp_do_receive(info
, tty
, cp
, ChanStatus
);
464 if (IntMask
& DELTA_CD
) { /* CD change */
465 #if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_INTR) || defined(ROCKET_DEBUG_HANGUP))
466 printk(KERN_INFO
"ttyR%d CD now %s...", info
->line
,
467 (ChanStatus
& CD_ACT
) ? "on" : "off");
469 if (!(ChanStatus
& CD_ACT
) && info
->cd_status
) {
470 #ifdef ROCKET_DEBUG_HANGUP
471 printk(KERN_INFO
"CD drop, calling hangup.\n");
475 info
->cd_status
= (ChanStatus
& CD_ACT
) ? 1 : 0;
476 wake_up_interruptible(&info
->open_wait
);
478 #ifdef ROCKET_DEBUG_INTR
479 if (IntMask
& DELTA_CTS
) { /* CTS change */
480 printk(KERN_INFO
"CTS change...\n");
482 if (IntMask
& DELTA_DSR
) { /* DSR change */
483 printk(KERN_INFO
"DSR change...\n");
489 * The top level polling routine. Repeats every 1/100 HZ (10ms).
491 static void rp_do_poll(unsigned long dummy
)
494 int ctrl
, aiop
, ch
, line
, i
;
495 unsigned int xmitmask
;
496 unsigned int CtlMask
;
497 unsigned char AiopMask
;
500 /* Walk through all the boards (ctrl's) */
501 for (ctrl
= 0; ctrl
< max_board
; ctrl
++) {
502 if (rcktpt_io_addr
[ctrl
] <= 0)
505 /* Get a ptr to the board's control struct */
506 ctlp
= sCtlNumToCtlPtr(ctrl
);
508 /* Get the interupt status from the board */
510 if (ctlp
->BusType
== isPCI
)
511 CtlMask
= sPCIGetControllerIntStatus(ctlp
);
514 CtlMask
= sGetControllerIntStatus(ctlp
);
516 /* Check if any AIOP read bits are set */
517 for (aiop
= 0; CtlMask
; aiop
++) {
518 bit
= ctlp
->AiopIntrBits
[aiop
];
521 AiopMask
= sGetAiopIntStatus(ctlp
, aiop
);
523 /* Check if any port read bits are set */
524 for (ch
= 0; AiopMask
; AiopMask
>>= 1, ch
++) {
527 /* Get the line number (/dev/ttyRx number). */
528 /* Read the data from the port. */
529 line
= GetLineNumber(ctrl
, aiop
, ch
);
530 rp_handle_port(rp_table
[line
]);
536 xmitmask
= xmit_flags
[ctrl
];
539 * xmit_flags contains bit-significant flags, indicating there is data
540 * to xmit on the port. Bit 0 is port 0 on this board, bit 1 is port
541 * 1, ... (32 total possible). The variable i has the aiop and ch
542 * numbers encoded in it (port 0-7 are aiop0, 8-15 are aiop1, etc).
545 for (i
= 0; i
< rocketModel
[ctrl
].numPorts
; i
++) {
546 if (xmitmask
& (1 << i
)) {
547 aiop
= (i
& 0x18) >> 3;
549 line
= GetLineNumber(ctrl
, aiop
, ch
);
550 rp_do_transmit(rp_table
[line
]);
557 * Reset the timer so we get called at the next clock tick (10ms).
559 if (atomic_read(&rp_num_ports_open
))
560 mod_timer(&rocket_timer
, jiffies
+ POLL_PERIOD
);
564 * Initializes the r_port structure for a port, as well as enabling the port on
566 * Inputs: board, aiop, chan numbers
568 static void init_r_port(int board
, int aiop
, int chan
, struct pci_dev
*pci_dev
)
575 /* Get the next available line number */
576 line
= SetLineNumber(board
, aiop
, chan
);
578 ctlp
= sCtlNumToCtlPtr(board
);
580 /* Get a r_port struct for the port, fill it in and save it globally, indexed by line number */
581 info
= kmalloc(sizeof (struct r_port
), GFP_KERNEL
);
583 printk(KERN_INFO
"Couldn't allocate info struct for line #%d\n", line
);
586 memset(info
, 0, sizeof (struct r_port
));
588 info
->magic
= RPORT_MAGIC
;
594 info
->closing_wait
= 3000;
595 info
->close_delay
= 50;
596 init_waitqueue_head(&info
->open_wait
);
597 init_waitqueue_head(&info
->close_wait
);
598 info
->flags
&= ~ROCKET_MODE_MASK
;
599 switch (pc104
[board
][line
]) {
601 info
->flags
|= ROCKET_MODE_RS422
;
604 info
->flags
|= ROCKET_MODE_RS485
;
608 info
->flags
|= ROCKET_MODE_RS232
;
612 info
->intmask
= RXF_TRIG
| TXFIFO_MT
| SRC_INT
| DELTA_CD
| DELTA_CTS
| DELTA_DSR
;
613 if (sInitChan(ctlp
, &info
->channel
, aiop
, chan
) == 0) {
614 printk(KERN_INFO
"RocketPort sInitChan(%d, %d, %d) failed!\n", board
, aiop
, chan
);
619 rocketMode
= info
->flags
& ROCKET_MODE_MASK
;
621 if ((info
->flags
& ROCKET_RTS_TOGGLE
) || (rocketMode
== ROCKET_MODE_RS485
))
622 sEnRTSToggle(&info
->channel
);
624 sDisRTSToggle(&info
->channel
);
626 if (ctlp
->boardType
== ROCKET_TYPE_PC104
) {
627 switch (rocketMode
) {
628 case ROCKET_MODE_RS485
:
629 sSetInterfaceMode(&info
->channel
, InterfaceModeRS485
);
631 case ROCKET_MODE_RS422
:
632 sSetInterfaceMode(&info
->channel
, InterfaceModeRS422
);
634 case ROCKET_MODE_RS232
:
636 if (info
->flags
& ROCKET_RTS_TOGGLE
)
637 sSetInterfaceMode(&info
->channel
, InterfaceModeRS232T
);
639 sSetInterfaceMode(&info
->channel
, InterfaceModeRS232
);
643 spin_lock_init(&info
->slock
);
644 sema_init(&info
->write_sem
, 1);
645 rp_table
[line
] = info
;
647 tty_register_device(rocket_driver
, line
, &pci_dev
->dev
);
651 * Configures a rocketport port according to its termio settings. Called from
652 * user mode into the driver (exception handler). *info CD manipulation is spinlock protected.
654 static void configure_r_port(struct r_port
*info
,
655 struct termios
*old_termios
)
660 int bits
, baud
, divisor
;
663 if (!info
->tty
|| !info
->tty
->termios
)
666 cflag
= info
->tty
->termios
->c_cflag
;
668 /* Byte size and parity */
669 if ((cflag
& CSIZE
) == CS8
) {
676 if (cflag
& CSTOPB
) {
683 if (cflag
& PARENB
) {
686 if (cflag
& PARODD
) {
696 baud
= tty_get_baud_rate(info
->tty
);
699 divisor
= ((rp_baud_base
[info
->board
] + (baud
>> 1)) / baud
) - 1;
700 if ((divisor
>= 8192 || divisor
< 0) && old_termios
) {
701 info
->tty
->termios
->c_cflag
&= ~CBAUD
;
702 info
->tty
->termios
->c_cflag
|=
703 (old_termios
->c_cflag
& CBAUD
);
704 baud
= tty_get_baud_rate(info
->tty
);
707 divisor
= (rp_baud_base
[info
->board
] / baud
) - 1;
709 if (divisor
>= 8192 || divisor
< 0) {
711 divisor
= (rp_baud_base
[info
->board
] / baud
) - 1;
713 info
->cps
= baud
/ bits
;
714 sSetBaud(cp
, divisor
);
716 if (cflag
& CRTSCTS
) {
717 info
->intmask
|= DELTA_CTS
;
720 info
->intmask
&= ~DELTA_CTS
;
723 if (cflag
& CLOCAL
) {
724 info
->intmask
&= ~DELTA_CD
;
726 spin_lock_irqsave(&info
->slock
, flags
);
727 if (sGetChanStatus(cp
) & CD_ACT
)
731 info
->intmask
|= DELTA_CD
;
732 spin_unlock_irqrestore(&info
->slock
, flags
);
736 * Handle software flow control in the board
738 #ifdef ROCKET_SOFT_FLOW
739 if (I_IXON(info
->tty
)) {
740 sEnTxSoftFlowCtl(cp
);
741 if (I_IXANY(info
->tty
)) {
746 sSetTxXONChar(cp
, START_CHAR(info
->tty
));
747 sSetTxXOFFChar(cp
, STOP_CHAR(info
->tty
));
749 sDisTxSoftFlowCtl(cp
);
756 * Set up ignore/read mask words
758 info
->read_status_mask
= STMRCVROVRH
| 0xFF;
759 if (I_INPCK(info
->tty
))
760 info
->read_status_mask
|= STMFRAMEH
| STMPARITYH
;
761 if (I_BRKINT(info
->tty
) || I_PARMRK(info
->tty
))
762 info
->read_status_mask
|= STMBREAKH
;
765 * Characters to ignore
767 info
->ignore_status_mask
= 0;
768 if (I_IGNPAR(info
->tty
))
769 info
->ignore_status_mask
|= STMFRAMEH
| STMPARITYH
;
770 if (I_IGNBRK(info
->tty
)) {
771 info
->ignore_status_mask
|= STMBREAKH
;
773 * If we're ignoring parity and break indicators,
774 * ignore overruns too. (For real raw support).
776 if (I_IGNPAR(info
->tty
))
777 info
->ignore_status_mask
|= STMRCVROVRH
;
780 rocketMode
= info
->flags
& ROCKET_MODE_MASK
;
782 if ((info
->flags
& ROCKET_RTS_TOGGLE
)
783 || (rocketMode
== ROCKET_MODE_RS485
))
788 sSetRTS(&info
->channel
);
790 if (cp
->CtlP
->boardType
== ROCKET_TYPE_PC104
) {
791 switch (rocketMode
) {
792 case ROCKET_MODE_RS485
:
793 sSetInterfaceMode(cp
, InterfaceModeRS485
);
795 case ROCKET_MODE_RS422
:
796 sSetInterfaceMode(cp
, InterfaceModeRS422
);
798 case ROCKET_MODE_RS232
:
800 if (info
->flags
& ROCKET_RTS_TOGGLE
)
801 sSetInterfaceMode(cp
, InterfaceModeRS232T
);
803 sSetInterfaceMode(cp
, InterfaceModeRS232
);
809 /* info->count is considered critical, protected by spinlocks. */
810 static int block_til_ready(struct tty_struct
*tty
, struct file
*filp
,
813 DECLARE_WAITQUEUE(wait
, current
);
815 int do_clocal
= 0, extra_count
= 0;
819 * If the device is in the middle of being closed, then block
820 * until it's done, and then try again.
822 if (tty_hung_up_p(filp
))
823 return ((info
->flags
& ROCKET_HUP_NOTIFY
) ? -EAGAIN
: -ERESTARTSYS
);
824 if (info
->flags
& ROCKET_CLOSING
) {
825 interruptible_sleep_on(&info
->close_wait
);
826 return ((info
->flags
& ROCKET_HUP_NOTIFY
) ? -EAGAIN
: -ERESTARTSYS
);
830 * If non-blocking mode is set, or the port is not enabled,
831 * then make the check up front and then exit.
833 if ((filp
->f_flags
& O_NONBLOCK
) || (tty
->flags
& (1 << TTY_IO_ERROR
))) {
834 info
->flags
|= ROCKET_NORMAL_ACTIVE
;
837 if (tty
->termios
->c_cflag
& CLOCAL
)
841 * Block waiting for the carrier detect and the line to become free. While we are in
842 * this loop, info->count is dropped by one, so that rp_close() knows when to free things.
843 * We restore it upon exit, either normal or abnormal.
846 add_wait_queue(&info
->open_wait
, &wait
);
847 #ifdef ROCKET_DEBUG_OPEN
848 printk(KERN_INFO
"block_til_ready before block: ttyR%d, count = %d\n", info
->line
, info
->count
);
850 spin_lock_irqsave(&info
->slock
, flags
);
852 #ifdef ROCKET_DISABLE_SIMUSAGE
853 info
->flags
|= ROCKET_NORMAL_ACTIVE
;
855 if (!tty_hung_up_p(filp
)) {
860 info
->blocked_open
++;
862 spin_unlock_irqrestore(&info
->slock
, flags
);
865 if (tty
->termios
->c_cflag
& CBAUD
) {
866 sSetDTR(&info
->channel
);
867 sSetRTS(&info
->channel
);
869 set_current_state(TASK_INTERRUPTIBLE
);
870 if (tty_hung_up_p(filp
) || !(info
->flags
& ROCKET_INITIALIZED
)) {
871 if (info
->flags
& ROCKET_HUP_NOTIFY
)
874 retval
= -ERESTARTSYS
;
877 if (!(info
->flags
& ROCKET_CLOSING
) && (do_clocal
|| (sGetChanStatusLo(&info
->channel
) & CD_ACT
)))
879 if (signal_pending(current
)) {
880 retval
= -ERESTARTSYS
;
883 #ifdef ROCKET_DEBUG_OPEN
884 printk(KERN_INFO
"block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n",
885 info
->line
, info
->count
, info
->flags
);
887 schedule(); /* Don't hold spinlock here, will hang PC */
889 current
->state
= TASK_RUNNING
;
890 remove_wait_queue(&info
->open_wait
, &wait
);
892 spin_lock_irqsave(&info
->slock
, flags
);
896 info
->blocked_open
--;
898 spin_unlock_irqrestore(&info
->slock
, flags
);
900 #ifdef ROCKET_DEBUG_OPEN
901 printk(KERN_INFO
"block_til_ready after blocking: ttyR%d, count = %d\n",
902 info
->line
, info
->count
);
906 info
->flags
|= ROCKET_NORMAL_ACTIVE
;
911 * Exception handler that opens a serial port. Creates xmit_buf storage, fills in
912 * port's r_port struct. Initializes the port hardware.
914 static int rp_open(struct tty_struct
*tty
, struct file
*filp
)
917 int line
= 0, retval
;
921 line
= TTY_GET_LINE(tty
);
922 if ((line
< 0) || (line
>= MAX_RP_PORTS
) || ((info
= rp_table
[line
]) == NULL
))
925 page
= __get_free_page(GFP_KERNEL
);
929 if (info
->flags
& ROCKET_CLOSING
) {
930 interruptible_sleep_on(&info
->close_wait
);
932 return ((info
->flags
& ROCKET_HUP_NOTIFY
) ? -EAGAIN
: -ERESTARTSYS
);
936 * We must not sleep from here until the port is marked fully in use.
941 info
->xmit_buf
= (unsigned char *) page
;
943 tty
->driver_data
= info
;
946 if (info
->count
++ == 0) {
947 atomic_inc(&rp_num_ports_open
);
949 #ifdef ROCKET_DEBUG_OPEN
950 printk(KERN_INFO
"rocket mod++ = %d...", atomic_read(&rp_num_ports_open
));
953 #ifdef ROCKET_DEBUG_OPEN
954 printk(KERN_INFO
"rp_open ttyR%d, count=%d\n", info
->line
, info
->count
);
958 * Info->count is now 1; so it's safe to sleep now.
960 info
->session
= current
->signal
->session
;
961 info
->pgrp
= process_group(current
);
963 if ((info
->flags
& ROCKET_INITIALIZED
) == 0) {
965 sSetRxTrigger(cp
, TRIG_1
);
966 if (sGetChanStatus(cp
) & CD_ACT
)
970 sDisRxStatusMode(cp
);
974 sEnInterrupts(cp
, (TXINT_EN
| MCINT_EN
| RXINT_EN
| SRCINT_EN
| CHANINT_EN
));
975 sSetRxTrigger(cp
, TRIG_1
);
978 sDisRxStatusMode(cp
);
982 sDisTxSoftFlowCtl(cp
);
987 info
->flags
|= ROCKET_INITIALIZED
;
990 * Set up the tty->alt_speed kludge
992 if ((info
->flags
& ROCKET_SPD_MASK
) == ROCKET_SPD_HI
)
993 info
->tty
->alt_speed
= 57600;
994 if ((info
->flags
& ROCKET_SPD_MASK
) == ROCKET_SPD_VHI
)
995 info
->tty
->alt_speed
= 115200;
996 if ((info
->flags
& ROCKET_SPD_MASK
) == ROCKET_SPD_SHI
)
997 info
->tty
->alt_speed
= 230400;
998 if ((info
->flags
& ROCKET_SPD_MASK
) == ROCKET_SPD_WARP
)
999 info
->tty
->alt_speed
= 460800;
1001 configure_r_port(info
, NULL
);
1002 if (tty
->termios
->c_cflag
& CBAUD
) {
1007 /* Starts (or resets) the maint polling loop */
1008 mod_timer(&rocket_timer
, jiffies
+ POLL_PERIOD
);
1010 retval
= block_til_ready(tty
, filp
, info
);
1012 #ifdef ROCKET_DEBUG_OPEN
1013 printk(KERN_INFO
"rp_open returning after block_til_ready with %d\n", retval
);
1021 * Exception handler that closes a serial port. info->count is considered critical.
1023 static void rp_close(struct tty_struct
*tty
, struct file
*filp
)
1025 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1026 unsigned long flags
;
1030 if (rocket_paranoia_check(info
, "rp_close"))
1033 #ifdef ROCKET_DEBUG_OPEN
1034 printk(KERN_INFO
"rp_close ttyR%d, count = %d\n", info
->line
, info
->count
);
1037 if (tty_hung_up_p(filp
))
1039 spin_lock_irqsave(&info
->slock
, flags
);
1041 if ((tty
->count
== 1) && (info
->count
!= 1)) {
1043 * Uh, oh. tty->count is 1, which means that the tty
1044 * structure will be freed. Info->count should always
1045 * be one in these conditions. If it's greater than
1046 * one, we've got real problems, since it means the
1047 * serial port won't be shutdown.
1049 printk(KERN_INFO
"rp_close: bad serial port count; tty->count is 1, "
1050 "info->count is %d\n", info
->count
);
1053 if (--info
->count
< 0) {
1054 printk(KERN_INFO
"rp_close: bad serial port count for ttyR%d: %d\n",
1055 info
->line
, info
->count
);
1059 spin_unlock_irqrestore(&info
->slock
, flags
);
1062 info
->flags
|= ROCKET_CLOSING
;
1063 spin_unlock_irqrestore(&info
->slock
, flags
);
1065 cp
= &info
->channel
;
1068 * Notify the line discpline to only process XON/XOFF characters
1073 * If transmission was throttled by the application request,
1074 * just flush the xmit buffer.
1076 if (tty
->flow_stopped
)
1077 rp_flush_buffer(tty
);
1080 * Wait for the transmit buffer to clear
1082 if (info
->closing_wait
!= ROCKET_CLOSING_WAIT_NONE
)
1083 tty_wait_until_sent(tty
, info
->closing_wait
);
1085 * Before we drop DTR, make sure the UART transmitter
1086 * has completely drained; this is especially
1087 * important if there is a transmit FIFO!
1089 timeout
= (sGetTxCnt(cp
) + 1) * HZ
/ info
->cps
;
1092 rp_wait_until_sent(tty
, timeout
);
1093 clear_bit((info
->aiop
* 8) + info
->chan
, (void *) &xmit_flags
[info
->board
]);
1096 sDisInterrupts(cp
, (TXINT_EN
| MCINT_EN
| RXINT_EN
| SRCINT_EN
| CHANINT_EN
));
1098 sDisTxSoftFlowCtl(cp
);
1106 if (TTY_DRIVER_FLUSH_BUFFER_EXISTS(tty
))
1107 TTY_DRIVER_FLUSH_BUFFER(tty
);
1109 tty_ldisc_flush(tty
);
1111 clear_bit((info
->aiop
* 8) + info
->chan
, (void *) &xmit_flags
[info
->board
]);
1113 if (info
->blocked_open
) {
1114 if (info
->close_delay
) {
1115 msleep_interruptible(jiffies_to_msecs(info
->close_delay
));
1117 wake_up_interruptible(&info
->open_wait
);
1119 if (info
->xmit_buf
) {
1120 free_page((unsigned long) info
->xmit_buf
);
1121 info
->xmit_buf
= NULL
;
1124 info
->flags
&= ~(ROCKET_INITIALIZED
| ROCKET_CLOSING
| ROCKET_NORMAL_ACTIVE
);
1126 wake_up_interruptible(&info
->close_wait
);
1127 atomic_dec(&rp_num_ports_open
);
1129 #ifdef ROCKET_DEBUG_OPEN
1130 printk(KERN_INFO
"rocket mod-- = %d...", atomic_read(&rp_num_ports_open
));
1131 printk(KERN_INFO
"rp_close ttyR%d complete shutdown\n", info
->line
);
1136 static void rp_set_termios(struct tty_struct
*tty
,
1137 struct termios
*old_termios
)
1139 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1143 if (rocket_paranoia_check(info
, "rp_set_termios"))
1146 cflag
= tty
->termios
->c_cflag
;
1148 if (cflag
== old_termios
->c_cflag
)
1152 * This driver doesn't support CS5 or CS6
1154 if (((cflag
& CSIZE
) == CS5
) || ((cflag
& CSIZE
) == CS6
))
1155 tty
->termios
->c_cflag
=
1156 ((cflag
& ~CSIZE
) | (old_termios
->c_cflag
& CSIZE
));
1158 configure_r_port(info
, old_termios
);
1160 cp
= &info
->channel
;
1162 /* Handle transition to B0 status */
1163 if ((old_termios
->c_cflag
& CBAUD
) && !(tty
->termios
->c_cflag
& CBAUD
)) {
1168 /* Handle transition away from B0 status */
1169 if (!(old_termios
->c_cflag
& CBAUD
) && (tty
->termios
->c_cflag
& CBAUD
)) {
1170 if (!tty
->hw_stopped
|| !(tty
->termios
->c_cflag
& CRTSCTS
))
1175 if ((old_termios
->c_cflag
& CRTSCTS
) && !(tty
->termios
->c_cflag
& CRTSCTS
)) {
1176 tty
->hw_stopped
= 0;
1181 static void rp_break(struct tty_struct
*tty
, int break_state
)
1183 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1184 unsigned long flags
;
1186 if (rocket_paranoia_check(info
, "rp_break"))
1189 spin_lock_irqsave(&info
->slock
, flags
);
1190 if (break_state
== -1)
1191 sSendBreak(&info
->channel
);
1193 sClrBreak(&info
->channel
);
1194 spin_unlock_irqrestore(&info
->slock
, flags
);
1198 * sGetChanRI used to be a macro in rocket_int.h. When the functionality for
1199 * the UPCI boards was added, it was decided to make this a function because
1200 * the macro was getting too complicated. All cases except the first one
1201 * (UPCIRingInd) are taken directly from the original macro.
1203 static int sGetChanRI(CHANNEL_T
* ChP
)
1205 CONTROLLER_t
*CtlP
= ChP
->CtlP
;
1206 int ChanNum
= ChP
->ChanNum
;
1209 if (CtlP
->UPCIRingInd
)
1210 RingInd
= !(sInB(CtlP
->UPCIRingInd
) & sBitMapSetTbl
[ChanNum
]);
1211 else if (CtlP
->AltChanRingIndicator
)
1212 RingInd
= sInB((ByteIO_t
) (ChP
->ChanStat
+ 8)) & DSR_ACT
;
1213 else if (CtlP
->boardType
== ROCKET_TYPE_PC104
)
1214 RingInd
= !(sInB(CtlP
->AiopIO
[3]) & sBitMapSetTbl
[ChanNum
]);
1219 /********************************************************************************************/
1220 /* Here are the routines used by rp_ioctl. These are all called from exception handlers. */
1223 * Returns the state of the serial modem control lines. These next 2 functions
1224 * are the way kernel versions > 2.5 handle modem control lines rather than IOCTLs.
1226 static int rp_tiocmget(struct tty_struct
*tty
, struct file
*file
)
1228 struct r_port
*info
= (struct r_port
*)tty
->driver_data
;
1229 unsigned int control
, result
, ChanStatus
;
1231 ChanStatus
= sGetChanStatusLo(&info
->channel
);
1232 control
= info
->channel
.TxControl
[3];
1233 result
= ((control
& SET_RTS
) ? TIOCM_RTS
: 0) |
1234 ((control
& SET_DTR
) ? TIOCM_DTR
: 0) |
1235 ((ChanStatus
& CD_ACT
) ? TIOCM_CAR
: 0) |
1236 (sGetChanRI(&info
->channel
) ? TIOCM_RNG
: 0) |
1237 ((ChanStatus
& DSR_ACT
) ? TIOCM_DSR
: 0) |
1238 ((ChanStatus
& CTS_ACT
) ? TIOCM_CTS
: 0);
1244 * Sets the modem control lines
1246 static int rp_tiocmset(struct tty_struct
*tty
, struct file
*file
,
1247 unsigned int set
, unsigned int clear
)
1249 struct r_port
*info
= (struct r_port
*)tty
->driver_data
;
1251 if (set
& TIOCM_RTS
)
1252 info
->channel
.TxControl
[3] |= SET_RTS
;
1253 if (set
& TIOCM_DTR
)
1254 info
->channel
.TxControl
[3] |= SET_DTR
;
1255 if (clear
& TIOCM_RTS
)
1256 info
->channel
.TxControl
[3] &= ~SET_RTS
;
1257 if (clear
& TIOCM_DTR
)
1258 info
->channel
.TxControl
[3] &= ~SET_DTR
;
1260 sOutDW(info
->channel
.IndexAddr
, *(DWord_t
*) & (info
->channel
.TxControl
[0]));
1264 static int get_config(struct r_port
*info
, struct rocket_config __user
*retinfo
)
1266 struct rocket_config tmp
;
1270 memset(&tmp
, 0, sizeof (tmp
));
1271 tmp
.line
= info
->line
;
1272 tmp
.flags
= info
->flags
;
1273 tmp
.close_delay
= info
->close_delay
;
1274 tmp
.closing_wait
= info
->closing_wait
;
1275 tmp
.port
= rcktpt_io_addr
[(info
->line
>> 5) & 3];
1277 if (copy_to_user(retinfo
, &tmp
, sizeof (*retinfo
)))
1282 static int set_config(struct r_port
*info
, struct rocket_config __user
*new_info
)
1284 struct rocket_config new_serial
;
1286 if (copy_from_user(&new_serial
, new_info
, sizeof (new_serial
)))
1289 if (!capable(CAP_SYS_ADMIN
))
1291 if ((new_serial
.flags
& ~ROCKET_USR_MASK
) != (info
->flags
& ~ROCKET_USR_MASK
))
1293 info
->flags
= ((info
->flags
& ~ROCKET_USR_MASK
) | (new_serial
.flags
& ROCKET_USR_MASK
));
1294 configure_r_port(info
, NULL
);
1298 info
->flags
= ((info
->flags
& ~ROCKET_FLAGS
) | (new_serial
.flags
& ROCKET_FLAGS
));
1299 info
->close_delay
= new_serial
.close_delay
;
1300 info
->closing_wait
= new_serial
.closing_wait
;
1302 if ((info
->flags
& ROCKET_SPD_MASK
) == ROCKET_SPD_HI
)
1303 info
->tty
->alt_speed
= 57600;
1304 if ((info
->flags
& ROCKET_SPD_MASK
) == ROCKET_SPD_VHI
)
1305 info
->tty
->alt_speed
= 115200;
1306 if ((info
->flags
& ROCKET_SPD_MASK
) == ROCKET_SPD_SHI
)
1307 info
->tty
->alt_speed
= 230400;
1308 if ((info
->flags
& ROCKET_SPD_MASK
) == ROCKET_SPD_WARP
)
1309 info
->tty
->alt_speed
= 460800;
1311 configure_r_port(info
, NULL
);
1316 * This function fills in a rocket_ports struct with information
1317 * about what boards/ports are in the system. This info is passed
1318 * to user space. See setrocket.c where the info is used to create
1319 * the /dev/ttyRx ports.
1321 static int get_ports(struct r_port
*info
, struct rocket_ports __user
*retports
)
1323 struct rocket_ports tmp
;
1328 memset(&tmp
, 0, sizeof (tmp
));
1329 tmp
.tty_major
= rocket_driver
->major
;
1331 for (board
= 0; board
< 4; board
++) {
1332 tmp
.rocketModel
[board
].model
= rocketModel
[board
].model
;
1333 strcpy(tmp
.rocketModel
[board
].modelString
, rocketModel
[board
].modelString
);
1334 tmp
.rocketModel
[board
].numPorts
= rocketModel
[board
].numPorts
;
1335 tmp
.rocketModel
[board
].loadrm2
= rocketModel
[board
].loadrm2
;
1336 tmp
.rocketModel
[board
].startingPortNumber
= rocketModel
[board
].startingPortNumber
;
1338 if (copy_to_user(retports
, &tmp
, sizeof (*retports
)))
1343 static int reset_rm2(struct r_port
*info
, void __user
*arg
)
1347 if (copy_from_user(&reset
, arg
, sizeof (int)))
1352 if (rcktpt_type
[info
->board
] != ROCKET_TYPE_MODEMII
&&
1353 rcktpt_type
[info
->board
] != ROCKET_TYPE_MODEMIII
)
1356 if (info
->ctlp
->BusType
== isISA
)
1357 sModemReset(info
->ctlp
, info
->chan
, reset
);
1359 sPCIModemReset(info
->ctlp
, info
->chan
, reset
);
1364 static int get_version(struct r_port
*info
, struct rocket_version __user
*retvers
)
1366 if (copy_to_user(retvers
, &driver_version
, sizeof (*retvers
)))
1371 /* IOCTL call handler into the driver */
1372 static int rp_ioctl(struct tty_struct
*tty
, struct file
*file
,
1373 unsigned int cmd
, unsigned long arg
)
1375 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1376 void __user
*argp
= (void __user
*)arg
;
1378 if (cmd
!= RCKP_GET_PORTS
&& rocket_paranoia_check(info
, "rp_ioctl"))
1382 case RCKP_GET_STRUCT
:
1383 if (copy_to_user(argp
, info
, sizeof (struct r_port
)))
1386 case RCKP_GET_CONFIG
:
1387 return get_config(info
, argp
);
1388 case RCKP_SET_CONFIG
:
1389 return set_config(info
, argp
);
1390 case RCKP_GET_PORTS
:
1391 return get_ports(info
, argp
);
1392 case RCKP_RESET_RM2
:
1393 return reset_rm2(info
, argp
);
1394 case RCKP_GET_VERSION
:
1395 return get_version(info
, argp
);
1397 return -ENOIOCTLCMD
;
1402 static void rp_send_xchar(struct tty_struct
*tty
, char ch
)
1404 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1407 if (rocket_paranoia_check(info
, "rp_send_xchar"))
1410 cp
= &info
->channel
;
1412 sWriteTxPrioByte(cp
, ch
);
1414 sWriteTxByte(sGetTxRxDataIO(cp
), ch
);
1417 static void rp_throttle(struct tty_struct
*tty
)
1419 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1422 #ifdef ROCKET_DEBUG_THROTTLE
1423 printk(KERN_INFO
"throttle %s: %d....\n", tty
->name
,
1424 tty
->ldisc
.chars_in_buffer(tty
));
1427 if (rocket_paranoia_check(info
, "rp_throttle"))
1430 cp
= &info
->channel
;
1432 rp_send_xchar(tty
, STOP_CHAR(tty
));
1434 sClrRTS(&info
->channel
);
1437 static void rp_unthrottle(struct tty_struct
*tty
)
1439 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1441 #ifdef ROCKET_DEBUG_THROTTLE
1442 printk(KERN_INFO
"unthrottle %s: %d....\n", tty
->name
,
1443 tty
->ldisc
.chars_in_buffer(tty
));
1446 if (rocket_paranoia_check(info
, "rp_throttle"))
1449 cp
= &info
->channel
;
1451 rp_send_xchar(tty
, START_CHAR(tty
));
1453 sSetRTS(&info
->channel
);
1457 * ------------------------------------------------------------
1458 * rp_stop() and rp_start()
1460 * This routines are called before setting or resetting tty->stopped.
1461 * They enable or disable transmitter interrupts, as necessary.
1462 * ------------------------------------------------------------
1464 static void rp_stop(struct tty_struct
*tty
)
1466 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1468 #ifdef ROCKET_DEBUG_FLOW
1469 printk(KERN_INFO
"stop %s: %d %d....\n", tty
->name
,
1470 info
->xmit_cnt
, info
->xmit_fifo_room
);
1473 if (rocket_paranoia_check(info
, "rp_stop"))
1476 if (sGetTxCnt(&info
->channel
))
1477 sDisTransmit(&info
->channel
);
1480 static void rp_start(struct tty_struct
*tty
)
1482 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1484 #ifdef ROCKET_DEBUG_FLOW
1485 printk(KERN_INFO
"start %s: %d %d....\n", tty
->name
,
1486 info
->xmit_cnt
, info
->xmit_fifo_room
);
1489 if (rocket_paranoia_check(info
, "rp_stop"))
1492 sEnTransmit(&info
->channel
);
1493 set_bit((info
->aiop
* 8) + info
->chan
,
1494 (void *) &xmit_flags
[info
->board
]);
1498 * rp_wait_until_sent() --- wait until the transmitter is empty
1500 static void rp_wait_until_sent(struct tty_struct
*tty
, int timeout
)
1502 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1504 unsigned long orig_jiffies
;
1505 int check_time
, exit_time
;
1508 if (rocket_paranoia_check(info
, "rp_wait_until_sent"))
1511 cp
= &info
->channel
;
1513 orig_jiffies
= jiffies
;
1514 #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1515 printk(KERN_INFO
"In RP_wait_until_sent(%d) (jiff=%lu)...", timeout
,
1517 printk(KERN_INFO
"cps=%d...", info
->cps
);
1520 txcnt
= sGetTxCnt(cp
);
1522 if (sGetChanStatusLo(cp
) & TXSHRMT
)
1524 check_time
= (HZ
/ info
->cps
) / 5;
1526 check_time
= HZ
* txcnt
/ info
->cps
;
1529 exit_time
= orig_jiffies
+ timeout
- jiffies
;
1532 if (exit_time
< check_time
)
1533 check_time
= exit_time
;
1535 if (check_time
== 0)
1537 #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1538 printk(KERN_INFO
"txcnt = %d (jiff=%lu,check=%d)...", txcnt
, jiffies
, check_time
);
1540 msleep_interruptible(jiffies_to_msecs(check_time
));
1541 if (signal_pending(current
))
1544 current
->state
= TASK_RUNNING
;
1545 #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1546 printk(KERN_INFO
"txcnt = %d (jiff=%lu)...done\n", txcnt
, jiffies
);
1551 * rp_hangup() --- called by tty_hangup() when a hangup is signaled.
1553 static void rp_hangup(struct tty_struct
*tty
)
1556 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1558 if (rocket_paranoia_check(info
, "rp_hangup"))
1561 #if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_HANGUP))
1562 printk(KERN_INFO
"rp_hangup of ttyR%d...", info
->line
);
1564 rp_flush_buffer(tty
);
1565 if (info
->flags
& ROCKET_CLOSING
)
1568 atomic_dec(&rp_num_ports_open
);
1569 clear_bit((info
->aiop
* 8) + info
->chan
, (void *) &xmit_flags
[info
->board
]);
1572 info
->flags
&= ~ROCKET_NORMAL_ACTIVE
;
1575 cp
= &info
->channel
;
1578 sDisInterrupts(cp
, (TXINT_EN
| MCINT_EN
| RXINT_EN
| SRCINT_EN
| CHANINT_EN
));
1580 sDisTxSoftFlowCtl(cp
);
1582 info
->flags
&= ~ROCKET_INITIALIZED
;
1584 wake_up_interruptible(&info
->open_wait
);
1588 * Exception handler - write char routine. The RocketPort driver uses a
1589 * double-buffering strategy, with the twist that if the in-memory CPU
1590 * buffer is empty, and there's space in the transmit FIFO, the
1591 * writing routines will write directly to transmit FIFO.
1592 * Write buffer and counters protected by spinlocks
1594 static void rp_put_char(struct tty_struct
*tty
, unsigned char ch
)
1596 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1598 unsigned long flags
;
1600 if (rocket_paranoia_check(info
, "rp_put_char"))
1603 /* Grab the port write semaphore, locking out other processes that try to write to this port */
1604 down(&info
->write_sem
);
1606 #ifdef ROCKET_DEBUG_WRITE
1607 printk(KERN_INFO
"rp_put_char %c...", ch
);
1610 spin_lock_irqsave(&info
->slock
, flags
);
1611 cp
= &info
->channel
;
1613 if (!tty
->stopped
&& !tty
->hw_stopped
&& info
->xmit_fifo_room
== 0)
1614 info
->xmit_fifo_room
= TXFIFO_SIZE
- sGetTxCnt(cp
);
1616 if (tty
->stopped
|| tty
->hw_stopped
|| info
->xmit_fifo_room
== 0 || info
->xmit_cnt
!= 0) {
1617 info
->xmit_buf
[info
->xmit_head
++] = ch
;
1618 info
->xmit_head
&= XMIT_BUF_SIZE
- 1;
1620 set_bit((info
->aiop
* 8) + info
->chan
, (void *) &xmit_flags
[info
->board
]);
1622 sOutB(sGetTxRxDataIO(cp
), ch
);
1623 info
->xmit_fifo_room
--;
1625 spin_unlock_irqrestore(&info
->slock
, flags
);
1626 up(&info
->write_sem
);
1630 * Exception handler - write routine, called when user app writes to the device.
1631 * A per port write semaphore is used to protect from another process writing to
1632 * this port at the same time. This other process could be running on the other CPU
1633 * or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out).
1634 * Spinlocks protect the info xmit members.
1636 static int rp_write(struct tty_struct
*tty
,
1637 const unsigned char *buf
, int count
)
1639 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1641 const unsigned char *b
;
1643 unsigned long flags
;
1645 if (count
<= 0 || rocket_paranoia_check(info
, "rp_write"))
1648 down_interruptible(&info
->write_sem
);
1650 #ifdef ROCKET_DEBUG_WRITE
1651 printk(KERN_INFO
"rp_write %d chars...", count
);
1653 cp
= &info
->channel
;
1655 if (!tty
->stopped
&& !tty
->hw_stopped
&& info
->xmit_fifo_room
< count
)
1656 info
->xmit_fifo_room
= TXFIFO_SIZE
- sGetTxCnt(cp
);
1659 * If the write queue for the port is empty, and there is FIFO space, stuff bytes
1660 * into FIFO. Use the write queue for temp storage.
1662 if (!tty
->stopped
&& !tty
->hw_stopped
&& info
->xmit_cnt
== 0 && info
->xmit_fifo_room
> 0) {
1663 c
= min(count
, info
->xmit_fifo_room
);
1666 /* Push data into FIFO, 2 bytes at a time */
1667 sOutStrW(sGetTxRxDataIO(cp
), (unsigned short *) b
, c
/ 2);
1669 /* If there is a byte remaining, write it */
1671 sOutB(sGetTxRxDataIO(cp
), b
[c
- 1]);
1677 spin_lock_irqsave(&info
->slock
, flags
);
1678 info
->xmit_fifo_room
-= c
;
1679 spin_unlock_irqrestore(&info
->slock
, flags
);
1682 /* If count is zero, we wrote it all and are done */
1686 /* Write remaining data into the port's xmit_buf */
1688 if (info
->tty
== 0) /* Seemingly obligatory check... */
1691 c
= min(count
, min(XMIT_BUF_SIZE
- info
->xmit_cnt
- 1, XMIT_BUF_SIZE
- info
->xmit_head
));
1696 memcpy(info
->xmit_buf
+ info
->xmit_head
, b
, c
);
1698 spin_lock_irqsave(&info
->slock
, flags
);
1700 (info
->xmit_head
+ c
) & (XMIT_BUF_SIZE
- 1);
1701 info
->xmit_cnt
+= c
;
1702 spin_unlock_irqrestore(&info
->slock
, flags
);
1709 if ((retval
> 0) && !tty
->stopped
&& !tty
->hw_stopped
)
1710 set_bit((info
->aiop
* 8) + info
->chan
, (void *) &xmit_flags
[info
->board
]);
1713 if (info
->xmit_cnt
< WAKEUP_CHARS
) {
1715 wake_up_interruptible(&tty
->write_wait
);
1716 #ifdef ROCKETPORT_HAVE_POLL_WAIT
1717 wake_up_interruptible(&tty
->poll_wait
);
1720 up(&info
->write_sem
);
1725 * Return the number of characters that can be sent. We estimate
1726 * only using the in-memory transmit buffer only, and ignore the
1727 * potential space in the transmit FIFO.
1729 static int rp_write_room(struct tty_struct
*tty
)
1731 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1734 if (rocket_paranoia_check(info
, "rp_write_room"))
1737 ret
= XMIT_BUF_SIZE
- info
->xmit_cnt
- 1;
1740 #ifdef ROCKET_DEBUG_WRITE
1741 printk(KERN_INFO
"rp_write_room returns %d...", ret
);
1747 * Return the number of characters in the buffer. Again, this only
1748 * counts those characters in the in-memory transmit buffer.
1750 static int rp_chars_in_buffer(struct tty_struct
*tty
)
1752 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1755 if (rocket_paranoia_check(info
, "rp_chars_in_buffer"))
1758 cp
= &info
->channel
;
1760 #ifdef ROCKET_DEBUG_WRITE
1761 printk(KERN_INFO
"rp_chars_in_buffer returns %d...", info
->xmit_cnt
);
1763 return info
->xmit_cnt
;
1767 * Flushes the TX fifo for a port, deletes data in the xmit_buf stored in the
1768 * r_port struct for the port. Note that spinlock are used to protect info members,
1769 * do not call this function if the spinlock is already held.
1771 static void rp_flush_buffer(struct tty_struct
*tty
)
1773 struct r_port
*info
= (struct r_port
*) tty
->driver_data
;
1775 unsigned long flags
;
1777 if (rocket_paranoia_check(info
, "rp_flush_buffer"))
1780 spin_lock_irqsave(&info
->slock
, flags
);
1781 info
->xmit_cnt
= info
->xmit_head
= info
->xmit_tail
= 0;
1782 spin_unlock_irqrestore(&info
->slock
, flags
);
1784 wake_up_interruptible(&tty
->write_wait
);
1785 #ifdef ROCKETPORT_HAVE_POLL_WAIT
1786 wake_up_interruptible(&tty
->poll_wait
);
1790 cp
= &info
->channel
;
1797 * Called when a PCI card is found. Retrieves and stores model information,
1798 * init's aiopic and serial port hardware.
1799 * Inputs: i is the board number (0-n)
1801 __init
int register_PCI(int i
, struct pci_dev
*dev
)
1803 int num_aiops
, aiop
, max_num_aiops
, num_chan
, chan
;
1804 unsigned int aiopio
[MAX_AIOPS_PER_BOARD
];
1805 char *str
, *board_type
;
1809 int altChanRingIndicator
= 0;
1810 int ports_per_aiop
= 8;
1812 unsigned int class_rev
;
1813 WordIO_t ConfigIO
= 0;
1814 ByteIO_t UPCIRingInd
= 0;
1816 if (!dev
|| pci_enable_device(dev
))
1819 rcktpt_io_addr
[i
] = pci_resource_start(dev
, 0);
1820 ret
= pci_read_config_dword(dev
, PCI_CLASS_REVISION
, &class_rev
);
1823 printk(KERN_INFO
" Error during register_PCI(), unable to read config dword \n");
1827 rcktpt_type
[i
] = ROCKET_TYPE_NORMAL
;
1828 rocketModel
[i
].loadrm2
= 0;
1829 rocketModel
[i
].startingPortNumber
= nextLineNumber
;
1831 /* Depending on the model, set up some config variables */
1832 switch (dev
->device
) {
1833 case PCI_DEVICE_ID_RP4QUAD
:
1837 rocketModel
[i
].model
= MODEL_RP4QUAD
;
1838 strcpy(rocketModel
[i
].modelString
, "RocketPort 4 port w/quad cable");
1839 rocketModel
[i
].numPorts
= 4;
1841 case PCI_DEVICE_ID_RP8OCTA
:
1844 rocketModel
[i
].model
= MODEL_RP8OCTA
;
1845 strcpy(rocketModel
[i
].modelString
, "RocketPort 8 port w/octa cable");
1846 rocketModel
[i
].numPorts
= 8;
1848 case PCI_DEVICE_ID_URP8OCTA
:
1851 rocketModel
[i
].model
= MODEL_UPCI_RP8OCTA
;
1852 strcpy(rocketModel
[i
].modelString
, "RocketPort UPCI 8 port w/octa cable");
1853 rocketModel
[i
].numPorts
= 8;
1855 case PCI_DEVICE_ID_RP8INTF
:
1858 rocketModel
[i
].model
= MODEL_RP8INTF
;
1859 strcpy(rocketModel
[i
].modelString
, "RocketPort 8 port w/external I/F");
1860 rocketModel
[i
].numPorts
= 8;
1862 case PCI_DEVICE_ID_URP8INTF
:
1865 rocketModel
[i
].model
= MODEL_UPCI_RP8INTF
;
1866 strcpy(rocketModel
[i
].modelString
, "RocketPort UPCI 8 port w/external I/F");
1867 rocketModel
[i
].numPorts
= 8;
1869 case PCI_DEVICE_ID_RP8J
:
1872 rocketModel
[i
].model
= MODEL_RP8J
;
1873 strcpy(rocketModel
[i
].modelString
, "RocketPort 8 port w/RJ11 connectors");
1874 rocketModel
[i
].numPorts
= 8;
1876 case PCI_DEVICE_ID_RP4J
:
1880 rocketModel
[i
].model
= MODEL_RP4J
;
1881 strcpy(rocketModel
[i
].modelString
, "RocketPort 4 port w/RJ45 connectors");
1882 rocketModel
[i
].numPorts
= 4;
1884 case PCI_DEVICE_ID_RP8SNI
:
1885 str
= "8 (DB78 Custom)";
1887 rocketModel
[i
].model
= MODEL_RP8SNI
;
1888 strcpy(rocketModel
[i
].modelString
, "RocketPort 8 port w/ custom DB78");
1889 rocketModel
[i
].numPorts
= 8;
1891 case PCI_DEVICE_ID_RP16SNI
:
1892 str
= "16 (DB78 Custom)";
1894 rocketModel
[i
].model
= MODEL_RP16SNI
;
1895 strcpy(rocketModel
[i
].modelString
, "RocketPort 16 port w/ custom DB78");
1896 rocketModel
[i
].numPorts
= 16;
1898 case PCI_DEVICE_ID_RP16INTF
:
1901 rocketModel
[i
].model
= MODEL_RP16INTF
;
1902 strcpy(rocketModel
[i
].modelString
, "RocketPort 16 port w/external I/F");
1903 rocketModel
[i
].numPorts
= 16;
1905 case PCI_DEVICE_ID_URP16INTF
:
1908 rocketModel
[i
].model
= MODEL_UPCI_RP16INTF
;
1909 strcpy(rocketModel
[i
].modelString
, "RocketPort UPCI 16 port w/external I/F");
1910 rocketModel
[i
].numPorts
= 16;
1912 case PCI_DEVICE_ID_CRP16INTF
:
1915 rocketModel
[i
].model
= MODEL_CPCI_RP16INTF
;
1916 strcpy(rocketModel
[i
].modelString
, "RocketPort Compact PCI 16 port w/external I/F");
1917 rocketModel
[i
].numPorts
= 16;
1919 case PCI_DEVICE_ID_RP32INTF
:
1922 rocketModel
[i
].model
= MODEL_RP32INTF
;
1923 strcpy(rocketModel
[i
].modelString
, "RocketPort 32 port w/external I/F");
1924 rocketModel
[i
].numPorts
= 32;
1926 case PCI_DEVICE_ID_URP32INTF
:
1929 rocketModel
[i
].model
= MODEL_UPCI_RP32INTF
;
1930 strcpy(rocketModel
[i
].modelString
, "RocketPort UPCI 32 port w/external I/F");
1931 rocketModel
[i
].numPorts
= 32;
1933 case PCI_DEVICE_ID_RPP4
:
1934 str
= "Plus Quadcable";
1937 altChanRingIndicator
++;
1939 rocketModel
[i
].model
= MODEL_RPP4
;
1940 strcpy(rocketModel
[i
].modelString
, "RocketPort Plus 4 port");
1941 rocketModel
[i
].numPorts
= 4;
1943 case PCI_DEVICE_ID_RPP8
:
1944 str
= "Plus Octacable";
1947 altChanRingIndicator
++;
1949 rocketModel
[i
].model
= MODEL_RPP8
;
1950 strcpy(rocketModel
[i
].modelString
, "RocketPort Plus 8 port");
1951 rocketModel
[i
].numPorts
= 8;
1953 case PCI_DEVICE_ID_RP2_232
:
1954 str
= "Plus 2 (RS-232)";
1957 altChanRingIndicator
++;
1959 rocketModel
[i
].model
= MODEL_RP2_232
;
1960 strcpy(rocketModel
[i
].modelString
, "RocketPort Plus 2 port RS232");
1961 rocketModel
[i
].numPorts
= 2;
1963 case PCI_DEVICE_ID_RP2_422
:
1964 str
= "Plus 2 (RS-422)";
1967 altChanRingIndicator
++;
1969 rocketModel
[i
].model
= MODEL_RP2_422
;
1970 strcpy(rocketModel
[i
].modelString
, "RocketPort Plus 2 port RS422");
1971 rocketModel
[i
].numPorts
= 2;
1973 case PCI_DEVICE_ID_RP6M
:
1979 /* If class_rev is 1, the rocketmodem flash must be loaded. If it is 2 it is a "socketed" version. */
1980 if ((class_rev
& 0xFF) == 1) {
1981 rcktpt_type
[i
] = ROCKET_TYPE_MODEMII
;
1982 rocketModel
[i
].loadrm2
= 1;
1984 rcktpt_type
[i
] = ROCKET_TYPE_MODEM
;
1987 rocketModel
[i
].model
= MODEL_RP6M
;
1988 strcpy(rocketModel
[i
].modelString
, "RocketModem 6 port");
1989 rocketModel
[i
].numPorts
= 6;
1991 case PCI_DEVICE_ID_RP4M
:
1995 if ((class_rev
& 0xFF) == 1) {
1996 rcktpt_type
[i
] = ROCKET_TYPE_MODEMII
;
1997 rocketModel
[i
].loadrm2
= 1;
1999 rcktpt_type
[i
] = ROCKET_TYPE_MODEM
;
2002 rocketModel
[i
].model
= MODEL_RP4M
;
2003 strcpy(rocketModel
[i
].modelString
, "RocketModem 4 port");
2004 rocketModel
[i
].numPorts
= 4;
2007 str
= "(unknown/unsupported)";
2013 * Check for UPCI boards.
2016 switch (dev
->device
) {
2017 case PCI_DEVICE_ID_URP32INTF
:
2018 case PCI_DEVICE_ID_URP8INTF
:
2019 case PCI_DEVICE_ID_URP16INTF
:
2020 case PCI_DEVICE_ID_CRP16INTF
:
2021 case PCI_DEVICE_ID_URP8OCTA
:
2022 rcktpt_io_addr
[i
] = pci_resource_start(dev
, 2);
2023 ConfigIO
= pci_resource_start(dev
, 1);
2024 if (dev
->device
== PCI_DEVICE_ID_URP8OCTA
) {
2025 UPCIRingInd
= rcktpt_io_addr
[i
] + _PCI_9030_RING_IND
;
2028 * Check for octa or quad cable.
2031 (sInW(ConfigIO
+ _PCI_9030_GPIO_CTRL
) &
2032 PCI_GPIO_CTRL_8PORT
)) {
2035 rocketModel
[i
].numPorts
= 4;
2039 case PCI_DEVICE_ID_UPCI_RM3_8PORT
:
2042 rocketModel
[i
].model
= MODEL_UPCI_RM3_8PORT
;
2043 strcpy(rocketModel
[i
].modelString
, "RocketModem III 8 port");
2044 rocketModel
[i
].numPorts
= 8;
2045 rcktpt_io_addr
[i
] = pci_resource_start(dev
, 2);
2046 UPCIRingInd
= rcktpt_io_addr
[i
] + _PCI_9030_RING_IND
;
2047 ConfigIO
= pci_resource_start(dev
, 1);
2048 rcktpt_type
[i
] = ROCKET_TYPE_MODEMIII
;
2050 case PCI_DEVICE_ID_UPCI_RM3_4PORT
:
2053 rocketModel
[i
].model
= MODEL_UPCI_RM3_4PORT
;
2054 strcpy(rocketModel
[i
].modelString
, "RocketModem III 4 port");
2055 rocketModel
[i
].numPorts
= 4;
2056 rcktpt_io_addr
[i
] = pci_resource_start(dev
, 2);
2057 UPCIRingInd
= rcktpt_io_addr
[i
] + _PCI_9030_RING_IND
;
2058 ConfigIO
= pci_resource_start(dev
, 1);
2059 rcktpt_type
[i
] = ROCKET_TYPE_MODEMIII
;
2065 switch (rcktpt_type
[i
]) {
2066 case ROCKET_TYPE_MODEM
:
2067 board_type
= "RocketModem";
2069 case ROCKET_TYPE_MODEMII
:
2070 board_type
= "RocketModem II";
2072 case ROCKET_TYPE_MODEMIII
:
2073 board_type
= "RocketModem III";
2076 board_type
= "RocketPort";
2081 sClockPrescale
= 0x12; /* mod 2 (divide by 3) */
2082 rp_baud_base
[i
] = 921600;
2085 * If support_low_speed is set, use the slow clock
2086 * prescale, which supports 50 bps
2088 if (support_low_speed
) {
2089 /* mod 9 (divide by 10) prescale */
2090 sClockPrescale
= 0x19;
2091 rp_baud_base
[i
] = 230400;
2093 /* mod 4 (devide by 5) prescale */
2094 sClockPrescale
= 0x14;
2095 rp_baud_base
[i
] = 460800;
2099 for (aiop
= 0; aiop
< max_num_aiops
; aiop
++)
2100 aiopio
[aiop
] = rcktpt_io_addr
[i
] + (aiop
* 0x40);
2101 ctlp
= sCtlNumToCtlPtr(i
);
2102 num_aiops
= sPCIInitController(ctlp
, i
, aiopio
, max_num_aiops
, ConfigIO
, 0, FREQ_DIS
, 0, altChanRingIndicator
, UPCIRingInd
);
2103 for (aiop
= 0; aiop
< max_num_aiops
; aiop
++)
2104 ctlp
->AiopNumChan
[aiop
] = ports_per_aiop
;
2106 printk("Comtrol PCI controller #%d ID 0x%x found in bus:slot:fn %s at address %04lx, "
2107 "%d AIOP(s) (%s)\n", i
, dev
->device
, pci_name(dev
),
2108 rcktpt_io_addr
[i
], num_aiops
, rocketModel
[i
].modelString
);
2109 printk(KERN_INFO
"Installing %s, creating /dev/ttyR%d - %ld\n",
2110 rocketModel
[i
].modelString
,
2111 rocketModel
[i
].startingPortNumber
,
2112 rocketModel
[i
].startingPortNumber
+
2113 rocketModel
[i
].numPorts
- 1);
2115 if (num_aiops
<= 0) {
2116 rcktpt_io_addr
[i
] = 0;
2121 /* Reset the AIOPIC, init the serial ports */
2122 for (aiop
= 0; aiop
< num_aiops
; aiop
++) {
2123 sResetAiopByNum(ctlp
, aiop
);
2124 num_chan
= ports_per_aiop
;
2125 for (chan
= 0; chan
< num_chan
; chan
++)
2126 init_r_port(i
, aiop
, chan
, dev
);
2129 /* Rocket modems must be reset */
2130 if ((rcktpt_type
[i
] == ROCKET_TYPE_MODEM
) ||
2131 (rcktpt_type
[i
] == ROCKET_TYPE_MODEMII
) ||
2132 (rcktpt_type
[i
] == ROCKET_TYPE_MODEMIII
)) {
2133 num_chan
= ports_per_aiop
;
2134 for (chan
= 0; chan
< num_chan
; chan
++)
2135 sPCIModemReset(ctlp
, chan
, 1);
2137 for (chan
= 0; chan
< num_chan
; chan
++)
2138 sPCIModemReset(ctlp
, chan
, 0);
2140 rmSpeakerReset(ctlp
, rocketModel
[i
].model
);
2146 * Probes for PCI cards, inits them if found
2147 * Input: board_found = number of ISA boards already found, or the
2148 * starting board number
2149 * Returns: Number of PCI boards found
2151 static int __init
init_PCI(int boards_found
)
2153 struct pci_dev
*dev
= NULL
;
2156 /* Work through the PCI device list, pulling out ours */
2157 while ((dev
= pci_find_device(PCI_VENDOR_ID_RP
, PCI_ANY_ID
, dev
))) {
2158 if (register_PCI(count
+ boards_found
, dev
))
2164 #endif /* CONFIG_PCI */
2167 * Probes for ISA cards
2168 * Input: i = the board number to look for
2169 * Returns: 1 if board found, 0 else
2171 static int __init
init_ISA(int i
)
2173 int num_aiops
, num_chan
= 0, total_num_chan
= 0;
2175 unsigned int aiopio
[MAX_AIOPS_PER_BOARD
];
2179 /* If io_addr is zero, no board configured */
2180 if (rcktpt_io_addr
[i
] == 0)
2183 /* Reserve the IO region */
2184 if (!request_region(rcktpt_io_addr
[i
], 64, "Comtrol RocketPort")) {
2185 printk(KERN_INFO
"Unable to reserve IO region for configured ISA RocketPort at address 0x%lx, board not installed...\n", rcktpt_io_addr
[i
]);
2186 rcktpt_io_addr
[i
] = 0;
2190 ctlp
= sCtlNumToCtlPtr(i
);
2192 ctlp
->boardType
= rcktpt_type
[i
];
2194 switch (rcktpt_type
[i
]) {
2195 case ROCKET_TYPE_PC104
:
2196 type_string
= "(PC104)";
2198 case ROCKET_TYPE_MODEM
:
2199 type_string
= "(RocketModem)";
2201 case ROCKET_TYPE_MODEMII
:
2202 type_string
= "(RocketModem II)";
2210 * If support_low_speed is set, use the slow clock prescale,
2211 * which supports 50 bps
2213 if (support_low_speed
) {
2214 sClockPrescale
= 0x19; /* mod 9 (divide by 10) prescale */
2215 rp_baud_base
[i
] = 230400;
2217 sClockPrescale
= 0x14; /* mod 4 (devide by 5) prescale */
2218 rp_baud_base
[i
] = 460800;
2221 for (aiop
= 0; aiop
< MAX_AIOPS_PER_BOARD
; aiop
++)
2222 aiopio
[aiop
] = rcktpt_io_addr
[i
] + (aiop
* 0x400);
2224 num_aiops
= sInitController(ctlp
, i
, controller
+ (i
* 0x400), aiopio
, MAX_AIOPS_PER_BOARD
, 0, FREQ_DIS
, 0);
2226 if (ctlp
->boardType
== ROCKET_TYPE_PC104
) {
2227 sEnAiop(ctlp
, 2); /* only one AIOPIC, but these */
2228 sEnAiop(ctlp
, 3); /* CSels used for other stuff */
2231 /* If something went wrong initing the AIOP's release the ISA IO memory */
2232 if (num_aiops
<= 0) {
2233 release_region(rcktpt_io_addr
[i
], 64);
2234 rcktpt_io_addr
[i
] = 0;
2238 rocketModel
[i
].startingPortNumber
= nextLineNumber
;
2240 for (aiop
= 0; aiop
< num_aiops
; aiop
++) {
2241 sResetAiopByNum(ctlp
, aiop
);
2242 sEnAiop(ctlp
, aiop
);
2243 num_chan
= sGetAiopNumChan(ctlp
, aiop
);
2244 total_num_chan
+= num_chan
;
2245 for (chan
= 0; chan
< num_chan
; chan
++)
2246 init_r_port(i
, aiop
, chan
, NULL
);
2249 if ((rcktpt_type
[i
] == ROCKET_TYPE_MODEM
) || (rcktpt_type
[i
] == ROCKET_TYPE_MODEMII
)) {
2250 num_chan
= sGetAiopNumChan(ctlp
, 0);
2251 total_num_chan
= num_chan
;
2252 for (chan
= 0; chan
< num_chan
; chan
++)
2253 sModemReset(ctlp
, chan
, 1);
2255 for (chan
= 0; chan
< num_chan
; chan
++)
2256 sModemReset(ctlp
, chan
, 0);
2258 strcpy(rocketModel
[i
].modelString
, "RocketModem ISA");
2260 strcpy(rocketModel
[i
].modelString
, "RocketPort ISA");
2262 rocketModel
[i
].numPorts
= total_num_chan
;
2263 rocketModel
[i
].model
= MODEL_ISA
;
2265 printk(KERN_INFO
"RocketPort ISA card #%d found at 0x%lx - %d AIOPs %s\n",
2266 i
, rcktpt_io_addr
[i
], num_aiops
, type_string
);
2268 printk(KERN_INFO
"Installing %s, creating /dev/ttyR%d - %ld\n",
2269 rocketModel
[i
].modelString
,
2270 rocketModel
[i
].startingPortNumber
,
2271 rocketModel
[i
].startingPortNumber
+
2272 rocketModel
[i
].numPorts
- 1);
2277 static struct tty_operations rocket_ops
= {
2281 .put_char
= rp_put_char
,
2282 .write_room
= rp_write_room
,
2283 .chars_in_buffer
= rp_chars_in_buffer
,
2284 .flush_buffer
= rp_flush_buffer
,
2286 .throttle
= rp_throttle
,
2287 .unthrottle
= rp_unthrottle
,
2288 .set_termios
= rp_set_termios
,
2291 .hangup
= rp_hangup
,
2292 .break_ctl
= rp_break
,
2293 .send_xchar
= rp_send_xchar
,
2294 .wait_until_sent
= rp_wait_until_sent
,
2295 .tiocmget
= rp_tiocmget
,
2296 .tiocmset
= rp_tiocmset
,
2300 * The module "startup" routine; it's run when the module is loaded.
2302 int __init
rp_init(void)
2304 int retval
, pci_boards_found
, isa_boards_found
, i
;
2306 printk(KERN_INFO
"RocketPort device driver module, version %s, %s\n",
2307 ROCKET_VERSION
, ROCKET_DATE
);
2309 rocket_driver
= alloc_tty_driver(MAX_RP_PORTS
);
2314 * Set up the timer channel.
2316 init_timer(&rocket_timer
);
2317 rocket_timer
.function
= rp_do_poll
;
2320 * Initialize the array of pointers to our own internal state
2323 memset(rp_table
, 0, sizeof (rp_table
));
2324 memset(xmit_flags
, 0, sizeof (xmit_flags
));
2326 for (i
= 0; i
< MAX_RP_PORTS
; i
++)
2329 memset(rocketModel
, 0, sizeof (rocketModel
));
2332 * If board 1 is non-zero, there is at least one ISA configured. If controller is
2333 * zero, use the default controller IO address of board1 + 0x40.
2336 if (controller
== 0)
2337 controller
= board1
+ 0x40;
2339 controller
= 0; /* Used as a flag, meaning no ISA boards */
2342 /* If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */
2343 if (controller
&& (!request_region(controller
, 4, "Comtrol RocketPort"))) {
2344 printk(KERN_INFO
"Unable to reserve IO region for first configured ISA RocketPort controller 0x%lx. Driver exiting \n", controller
);
2348 /* Store ISA variable retrieved from command line or .conf file. */
2349 rcktpt_io_addr
[0] = board1
;
2350 rcktpt_io_addr
[1] = board2
;
2351 rcktpt_io_addr
[2] = board3
;
2352 rcktpt_io_addr
[3] = board4
;
2354 rcktpt_type
[0] = modem1
? ROCKET_TYPE_MODEM
: ROCKET_TYPE_NORMAL
;
2355 rcktpt_type
[0] = pc104_1
[0] ? ROCKET_TYPE_PC104
: rcktpt_type
[0];
2356 rcktpt_type
[1] = modem2
? ROCKET_TYPE_MODEM
: ROCKET_TYPE_NORMAL
;
2357 rcktpt_type
[1] = pc104_2
[0] ? ROCKET_TYPE_PC104
: rcktpt_type
[1];
2358 rcktpt_type
[2] = modem3
? ROCKET_TYPE_MODEM
: ROCKET_TYPE_NORMAL
;
2359 rcktpt_type
[2] = pc104_3
[0] ? ROCKET_TYPE_PC104
: rcktpt_type
[2];
2360 rcktpt_type
[3] = modem4
? ROCKET_TYPE_MODEM
: ROCKET_TYPE_NORMAL
;
2361 rcktpt_type
[3] = pc104_4
[0] ? ROCKET_TYPE_PC104
: rcktpt_type
[3];
2364 * Set up the tty driver structure and then register this
2365 * driver with the tty layer.
2368 rocket_driver
->owner
= THIS_MODULE
;
2369 rocket_driver
->flags
= TTY_DRIVER_NO_DEVFS
;
2370 rocket_driver
->devfs_name
= "tts/R";
2371 rocket_driver
->name
= "ttyR";
2372 rocket_driver
->driver_name
= "Comtrol RocketPort";
2373 rocket_driver
->major
= TTY_ROCKET_MAJOR
;
2374 rocket_driver
->minor_start
= 0;
2375 rocket_driver
->type
= TTY_DRIVER_TYPE_SERIAL
;
2376 rocket_driver
->subtype
= SERIAL_TYPE_NORMAL
;
2377 rocket_driver
->init_termios
= tty_std_termios
;
2378 rocket_driver
->init_termios
.c_cflag
=
2379 B9600
| CS8
| CREAD
| HUPCL
| CLOCAL
;
2380 #ifdef ROCKET_SOFT_FLOW
2381 rocket_driver
->flags
|= TTY_DRIVER_REAL_RAW
| TTY_DRIVER_NO_DEVFS
;
2383 tty_set_operations(rocket_driver
, &rocket_ops
);
2385 retval
= tty_register_driver(rocket_driver
);
2387 printk(KERN_INFO
"Couldn't install tty RocketPort driver (error %d)\n", -retval
);
2388 put_tty_driver(rocket_driver
);
2392 #ifdef ROCKET_DEBUG_OPEN
2393 printk(KERN_INFO
"RocketPort driver is major %d\n", rocket_driver
.major
);
2397 * OK, let's probe each of the controllers looking for boards. Any boards found
2398 * will be initialized here.
2400 isa_boards_found
= 0;
2401 pci_boards_found
= 0;
2403 for (i
= 0; i
< NUM_BOARDS
; i
++) {
2409 if (isa_boards_found
< NUM_BOARDS
)
2410 pci_boards_found
= init_PCI(isa_boards_found
);
2413 max_board
= pci_boards_found
+ isa_boards_found
;
2415 if (max_board
== 0) {
2416 printk(KERN_INFO
"No rocketport ports found; unloading driver.\n");
2417 del_timer_sync(&rocket_timer
);
2418 tty_unregister_driver(rocket_driver
);
2419 put_tty_driver(rocket_driver
);
2428 static void rp_cleanup_module(void)
2433 del_timer_sync(&rocket_timer
);
2435 retval
= tty_unregister_driver(rocket_driver
);
2437 printk(KERN_INFO
"Error %d while trying to unregister "
2438 "rocketport driver\n", -retval
);
2439 put_tty_driver(rocket_driver
);
2441 for (i
= 0; i
< MAX_RP_PORTS
; i
++) {
2446 for (i
= 0; i
< NUM_BOARDS
; i
++) {
2447 if (rcktpt_io_addr
[i
] <= 0 || is_PCI
[i
])
2449 release_region(rcktpt_io_addr
[i
], 64);
2452 release_region(controller
, 4);
2464 static Byte_t RData
[RDATASIZE
] = {
2465 0x00, 0x09, 0xf6, 0x82,
2466 0x02, 0x09, 0x86, 0xfb,
2467 0x04, 0x09, 0x00, 0x0a,
2468 0x06, 0x09, 0x01, 0x0a,
2469 0x08, 0x09, 0x8a, 0x13,
2470 0x0a, 0x09, 0xc5, 0x11,
2471 0x0c, 0x09, 0x86, 0x85,
2472 0x0e, 0x09, 0x20, 0x0a,
2473 0x10, 0x09, 0x21, 0x0a,
2474 0x12, 0x09, 0x41, 0xff,
2475 0x14, 0x09, 0x82, 0x00,
2476 0x16, 0x09, 0x82, 0x7b,
2477 0x18, 0x09, 0x8a, 0x7d,
2478 0x1a, 0x09, 0x88, 0x81,
2479 0x1c, 0x09, 0x86, 0x7a,
2480 0x1e, 0x09, 0x84, 0x81,
2481 0x20, 0x09, 0x82, 0x7c,
2482 0x22, 0x09, 0x0a, 0x0a
2485 static Byte_t RRegData
[RREGDATASIZE
] = {
2486 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */
2487 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */
2488 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */
2489 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */
2490 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */
2491 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */
2492 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */
2493 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */
2494 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */
2495 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */
2496 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */
2497 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */
2498 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */
2501 CONTROLLER_T sController
[CTL_SIZE
] = {
2502 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
2503 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
2504 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
2505 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
2506 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
2507 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
2508 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
2509 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
2512 Byte_t sBitMapClrTbl
[8] = {
2513 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
2516 Byte_t sBitMapSetTbl
[8] = {
2517 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
2520 int sClockPrescale
= 0x14;
2522 /***************************************************************************
2523 Function: sInitController
2524 Purpose: Initialization of controller global registers and controller
2526 Call: sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize,
2527 IRQNum,Frequency,PeriodicOnly)
2528 CONTROLLER_T *CtlP; Ptr to controller structure
2529 int CtlNum; Controller number
2530 ByteIO_t MudbacIO; Mudbac base I/O address.
2531 ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
2532 This list must be in the order the AIOPs will be found on the
2533 controller. Once an AIOP in the list is not found, it is
2534 assumed that there are no more AIOPs on the controller.
2535 int AiopIOListSize; Number of addresses in AiopIOList
2536 int IRQNum; Interrupt Request number. Can be any of the following:
2537 0: Disable global interrupts
2546 Byte_t Frequency: A flag identifying the frequency
2547 of the periodic interrupt, can be any one of the following:
2548 FREQ_DIS - periodic interrupt disabled
2549 FREQ_137HZ - 137 Hertz
2550 FREQ_69HZ - 69 Hertz
2551 FREQ_34HZ - 34 Hertz
2552 FREQ_17HZ - 17 Hertz
2555 If IRQNum is set to 0 the Frequency parameter is
2556 overidden, it is forced to a value of FREQ_DIS.
2557 int PeriodicOnly: TRUE if all interrupts except the periodic
2558 interrupt are to be blocked.
2559 FALSE is both the periodic interrupt and
2560 other channel interrupts are allowed.
2561 If IRQNum is set to 0 the PeriodicOnly parameter is
2562 overidden, it is forced to a value of FALSE.
2563 Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
2564 initialization failed.
2567 If periodic interrupts are to be disabled but AIOP interrupts
2568 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.
2570 If interrupts are to be completely disabled set IRQNum to 0.
2572 Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
2573 invalid combination.
2575 This function performs initialization of global interrupt modes,
2576 but it does not actually enable global interrupts. To enable
2577 and disable global interrupts use functions sEnGlobalInt() and
2578 sDisGlobalInt(). Enabling of global interrupts is normally not
2579 done until all other initializations are complete.
2581 Even if interrupts are globally enabled, they must also be
2582 individually enabled for each channel that is to generate
2585 Warnings: No range checking on any of the parameters is done.
2587 No context switches are allowed while executing this function.
2589 After this function all AIOPs on the controller are disabled,
2590 they can be enabled with sEnAiop().
2592 int sInitController(CONTROLLER_T
* CtlP
, int CtlNum
, ByteIO_t MudbacIO
,
2593 ByteIO_t
* AiopIOList
, int AiopIOListSize
, int IRQNum
,
2594 Byte_t Frequency
, int PeriodicOnly
)
2600 CtlP
->AiopIntrBits
= aiop_intr_bits
;
2601 CtlP
->AltChanRingIndicator
= 0;
2602 CtlP
->CtlNum
= CtlNum
;
2603 CtlP
->CtlID
= CTLID_0001
; /* controller release 1 */
2604 CtlP
->BusType
= isISA
;
2605 CtlP
->MBaseIO
= MudbacIO
;
2606 CtlP
->MReg1IO
= MudbacIO
+ 1;
2607 CtlP
->MReg2IO
= MudbacIO
+ 2;
2608 CtlP
->MReg3IO
= MudbacIO
+ 3;
2610 CtlP
->MReg2
= 0; /* interrupt disable */
2611 CtlP
->MReg3
= 0; /* no periodic interrupts */
2613 if (sIRQMap
[IRQNum
] == 0) { /* interrupts globally disabled */
2614 CtlP
->MReg2
= 0; /* interrupt disable */
2615 CtlP
->MReg3
= 0; /* no periodic interrupts */
2617 CtlP
->MReg2
= sIRQMap
[IRQNum
]; /* set IRQ number */
2618 CtlP
->MReg3
= Frequency
; /* set frequency */
2619 if (PeriodicOnly
) { /* periodic interrupt only */
2620 CtlP
->MReg3
|= PERIODIC_ONLY
;
2624 sOutB(CtlP
->MReg2IO
, CtlP
->MReg2
);
2625 sOutB(CtlP
->MReg3IO
, CtlP
->MReg3
);
2626 sControllerEOI(CtlP
); /* clear EOI if warm init */
2629 for (i
= done
= 0; i
< AiopIOListSize
; i
++) {
2631 CtlP
->AiopIO
[i
] = (WordIO_t
) io
;
2632 CtlP
->AiopIntChanIO
[i
] = io
+ _INT_CHAN
;
2633 sOutB(CtlP
->MReg2IO
, CtlP
->MReg2
| (i
& 0x03)); /* AIOP index */
2634 sOutB(MudbacIO
, (Byte_t
) (io
>> 6)); /* set up AIOP I/O in MUDBAC */
2637 sEnAiop(CtlP
, i
); /* enable the AIOP */
2638 CtlP
->AiopID
[i
] = sReadAiopID(io
); /* read AIOP ID */
2639 if (CtlP
->AiopID
[i
] == AIOPID_NULL
) /* if AIOP does not exist */
2640 done
= 1; /* done looking for AIOPs */
2642 CtlP
->AiopNumChan
[i
] = sReadAiopNumChan((WordIO_t
) io
); /* num channels in AIOP */
2643 sOutW((WordIO_t
) io
+ _INDX_ADDR
, _CLK_PRE
); /* clock prescaler */
2644 sOutB(io
+ _INDX_DATA
, sClockPrescale
);
2645 CtlP
->NumAiop
++; /* bump count of AIOPs */
2647 sDisAiop(CtlP
, i
); /* disable AIOP */
2650 if (CtlP
->NumAiop
== 0)
2653 return (CtlP
->NumAiop
);
2656 /***************************************************************************
2657 Function: sPCIInitController
2658 Purpose: Initialization of controller global registers and controller
2660 Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize,
2661 IRQNum,Frequency,PeriodicOnly)
2662 CONTROLLER_T *CtlP; Ptr to controller structure
2663 int CtlNum; Controller number
2664 ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
2665 This list must be in the order the AIOPs will be found on the
2666 controller. Once an AIOP in the list is not found, it is
2667 assumed that there are no more AIOPs on the controller.
2668 int AiopIOListSize; Number of addresses in AiopIOList
2669 int IRQNum; Interrupt Request number. Can be any of the following:
2670 0: Disable global interrupts
2679 Byte_t Frequency: A flag identifying the frequency
2680 of the periodic interrupt, can be any one of the following:
2681 FREQ_DIS - periodic interrupt disabled
2682 FREQ_137HZ - 137 Hertz
2683 FREQ_69HZ - 69 Hertz
2684 FREQ_34HZ - 34 Hertz
2685 FREQ_17HZ - 17 Hertz
2688 If IRQNum is set to 0 the Frequency parameter is
2689 overidden, it is forced to a value of FREQ_DIS.
2690 int PeriodicOnly: TRUE if all interrupts except the periodic
2691 interrupt are to be blocked.
2692 FALSE is both the periodic interrupt and
2693 other channel interrupts are allowed.
2694 If IRQNum is set to 0 the PeriodicOnly parameter is
2695 overidden, it is forced to a value of FALSE.
2696 Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
2697 initialization failed.
2700 If periodic interrupts are to be disabled but AIOP interrupts
2701 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.
2703 If interrupts are to be completely disabled set IRQNum to 0.
2705 Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
2706 invalid combination.
2708 This function performs initialization of global interrupt modes,
2709 but it does not actually enable global interrupts. To enable
2710 and disable global interrupts use functions sEnGlobalInt() and
2711 sDisGlobalInt(). Enabling of global interrupts is normally not
2712 done until all other initializations are complete.
2714 Even if interrupts are globally enabled, they must also be
2715 individually enabled for each channel that is to generate
2718 Warnings: No range checking on any of the parameters is done.
2720 No context switches are allowed while executing this function.
2722 After this function all AIOPs on the controller are disabled,
2723 they can be enabled with sEnAiop().
2725 int sPCIInitController(CONTROLLER_T
* CtlP
, int CtlNum
,
2726 ByteIO_t
* AiopIOList
, int AiopIOListSize
,
2727 WordIO_t ConfigIO
, int IRQNum
, Byte_t Frequency
,
2728 int PeriodicOnly
, int altChanRingIndicator
,
2734 CtlP
->AltChanRingIndicator
= altChanRingIndicator
;
2735 CtlP
->UPCIRingInd
= UPCIRingInd
;
2736 CtlP
->CtlNum
= CtlNum
;
2737 CtlP
->CtlID
= CTLID_0001
; /* controller release 1 */
2738 CtlP
->BusType
= isPCI
; /* controller release 1 */
2742 CtlP
->PCIIO
= ConfigIO
+ _PCI_9030_INT_CTRL
;
2743 CtlP
->PCIIO2
= ConfigIO
+ _PCI_9030_GPIO_CTRL
;
2744 CtlP
->AiopIntrBits
= upci_aiop_intr_bits
;
2748 (WordIO_t
) ((ByteIO_t
) AiopIOList
[0] + _PCI_INT_FUNC
);
2749 CtlP
->AiopIntrBits
= aiop_intr_bits
;
2752 sPCIControllerEOI(CtlP
); /* clear EOI if warm init */
2755 for (i
= 0; i
< AiopIOListSize
; i
++) {
2757 CtlP
->AiopIO
[i
] = (WordIO_t
) io
;
2758 CtlP
->AiopIntChanIO
[i
] = io
+ _INT_CHAN
;
2760 CtlP
->AiopID
[i
] = sReadAiopID(io
); /* read AIOP ID */
2761 if (CtlP
->AiopID
[i
] == AIOPID_NULL
) /* if AIOP does not exist */
2762 break; /* done looking for AIOPs */
2764 CtlP
->AiopNumChan
[i
] = sReadAiopNumChan((WordIO_t
) io
); /* num channels in AIOP */
2765 sOutW((WordIO_t
) io
+ _INDX_ADDR
, _CLK_PRE
); /* clock prescaler */
2766 sOutB(io
+ _INDX_DATA
, sClockPrescale
);
2767 CtlP
->NumAiop
++; /* bump count of AIOPs */
2770 if (CtlP
->NumAiop
== 0)
2773 return (CtlP
->NumAiop
);
2776 /***************************************************************************
2777 Function: sReadAiopID
2778 Purpose: Read the AIOP idenfication number directly from an AIOP.
2779 Call: sReadAiopID(io)
2780 ByteIO_t io: AIOP base I/O address
2781 Return: int: Flag AIOPID_XXXX if a valid AIOP is found, where X
2782 is replace by an identifying number.
2783 Flag AIOPID_NULL if no valid AIOP is found
2784 Warnings: No context switches are allowed while executing this function.
2787 int sReadAiopID(ByteIO_t io
)
2789 Byte_t AiopID
; /* ID byte from AIOP */
2791 sOutB(io
+ _CMD_REG
, RESET_ALL
); /* reset AIOP */
2792 sOutB(io
+ _CMD_REG
, 0x0);
2793 AiopID
= sInW(io
+ _CHN_STAT0
) & 0x07;
2796 else /* AIOP does not exist */
2800 /***************************************************************************
2801 Function: sReadAiopNumChan
2802 Purpose: Read the number of channels available in an AIOP directly from
2804 Call: sReadAiopNumChan(io)
2805 WordIO_t io: AIOP base I/O address
2806 Return: int: The number of channels available
2807 Comments: The number of channels is determined by write/reads from identical
2808 offsets within the SRAM address spaces for channels 0 and 4.
2809 If the channel 4 space is mirrored to channel 0 it is a 4 channel
2810 AIOP, otherwise it is an 8 channel.
2811 Warnings: No context switches are allowed while executing this function.
2813 int sReadAiopNumChan(WordIO_t io
)
2816 static Byte_t R
[4] = { 0x00, 0x00, 0x34, 0x12 };
2818 /* write to chan 0 SRAM */
2819 sOutDW((DWordIO_t
) io
+ _INDX_ADDR
, *((DWord_t
*) & R
[0]));
2820 sOutW(io
+ _INDX_ADDR
, 0); /* read from SRAM, chan 0 */
2821 x
= sInW(io
+ _INDX_DATA
);
2822 sOutW(io
+ _INDX_ADDR
, 0x4000); /* read from SRAM, chan 4 */
2823 if (x
!= sInW(io
+ _INDX_DATA
)) /* if different must be 8 chan */
2829 /***************************************************************************
2831 Purpose: Initialization of a channel and channel structure
2832 Call: sInitChan(CtlP,ChP,AiopNum,ChanNum)
2833 CONTROLLER_T *CtlP; Ptr to controller structure
2834 CHANNEL_T *ChP; Ptr to channel structure
2835 int AiopNum; AIOP number within controller
2836 int ChanNum; Channel number within AIOP
2837 Return: int: TRUE if initialization succeeded, FALSE if it fails because channel
2838 number exceeds number of channels available in AIOP.
2839 Comments: This function must be called before a channel can be used.
2840 Warnings: No range checking on any of the parameters is done.
2842 No context switches are allowed while executing this function.
2844 int sInitChan(CONTROLLER_T
* CtlP
, CHANNEL_T
* ChP
, int AiopNum
,
2855 if (ChanNum
>= CtlP
->AiopNumChan
[AiopNum
])
2856 return (FALSE
); /* exceeds num chans in AIOP */
2858 /* Channel, AIOP, and controller identifiers */
2860 ChP
->ChanID
= CtlP
->AiopID
[AiopNum
];
2861 ChP
->AiopNum
= AiopNum
;
2862 ChP
->ChanNum
= ChanNum
;
2864 /* Global direct addresses */
2865 AiopIO
= CtlP
->AiopIO
[AiopNum
];
2866 ChP
->Cmd
= (ByteIO_t
) AiopIO
+ _CMD_REG
;
2867 ChP
->IntChan
= (ByteIO_t
) AiopIO
+ _INT_CHAN
;
2868 ChP
->IntMask
= (ByteIO_t
) AiopIO
+ _INT_MASK
;
2869 ChP
->IndexAddr
= (DWordIO_t
) AiopIO
+ _INDX_ADDR
;
2870 ChP
->IndexData
= AiopIO
+ _INDX_DATA
;
2872 /* Channel direct addresses */
2873 ChIOOff
= AiopIO
+ ChP
->ChanNum
* 2;
2874 ChP
->TxRxData
= ChIOOff
+ _TD0
;
2875 ChP
->ChanStat
= ChIOOff
+ _CHN_STAT0
;
2876 ChP
->TxRxCount
= ChIOOff
+ _FIFO_CNT0
;
2877 ChP
->IntID
= (ByteIO_t
) AiopIO
+ ChP
->ChanNum
+ _INT_ID0
;
2879 /* Initialize the channel from the RData array */
2880 for (i
= 0; i
< RDATASIZE
; i
+= 4) {
2882 R
[1] = RData
[i
+ 1] + 0x10 * ChanNum
;
2883 R
[2] = RData
[i
+ 2];
2884 R
[3] = RData
[i
+ 3];
2885 sOutDW(ChP
->IndexAddr
, *((DWord_t
*) & R
[0]));
2889 for (i
= 0; i
< RREGDATASIZE
; i
+= 4) {
2890 ChR
[i
] = RRegData
[i
];
2891 ChR
[i
+ 1] = RRegData
[i
+ 1] + 0x10 * ChanNum
;
2892 ChR
[i
+ 2] = RRegData
[i
+ 2];
2893 ChR
[i
+ 3] = RRegData
[i
+ 3];
2896 /* Indexed registers */
2897 ChOff
= (Word_t
) ChanNum
*0x1000;
2899 if (sClockPrescale
== 0x14)
2904 ChP
->BaudDiv
[0] = (Byte_t
) (ChOff
+ _BAUD
);
2905 ChP
->BaudDiv
[1] = (Byte_t
) ((ChOff
+ _BAUD
) >> 8);
2906 ChP
->BaudDiv
[2] = (Byte_t
) brd9600
;
2907 ChP
->BaudDiv
[3] = (Byte_t
) (brd9600
>> 8);
2908 sOutDW(ChP
->IndexAddr
, *(DWord_t
*) & ChP
->BaudDiv
[0]);
2910 ChP
->TxControl
[0] = (Byte_t
) (ChOff
+ _TX_CTRL
);
2911 ChP
->TxControl
[1] = (Byte_t
) ((ChOff
+ _TX_CTRL
) >> 8);
2912 ChP
->TxControl
[2] = 0;
2913 ChP
->TxControl
[3] = 0;
2914 sOutDW(ChP
->IndexAddr
, *(DWord_t
*) & ChP
->TxControl
[0]);
2916 ChP
->RxControl
[0] = (Byte_t
) (ChOff
+ _RX_CTRL
);
2917 ChP
->RxControl
[1] = (Byte_t
) ((ChOff
+ _RX_CTRL
) >> 8);
2918 ChP
->RxControl
[2] = 0;
2919 ChP
->RxControl
[3] = 0;
2920 sOutDW(ChP
->IndexAddr
, *(DWord_t
*) & ChP
->RxControl
[0]);
2922 ChP
->TxEnables
[0] = (Byte_t
) (ChOff
+ _TX_ENBLS
);
2923 ChP
->TxEnables
[1] = (Byte_t
) ((ChOff
+ _TX_ENBLS
) >> 8);
2924 ChP
->TxEnables
[2] = 0;
2925 ChP
->TxEnables
[3] = 0;
2926 sOutDW(ChP
->IndexAddr
, *(DWord_t
*) & ChP
->TxEnables
[0]);
2928 ChP
->TxCompare
[0] = (Byte_t
) (ChOff
+ _TXCMP1
);
2929 ChP
->TxCompare
[1] = (Byte_t
) ((ChOff
+ _TXCMP1
) >> 8);
2930 ChP
->TxCompare
[2] = 0;
2931 ChP
->TxCompare
[3] = 0;
2932 sOutDW(ChP
->IndexAddr
, *(DWord_t
*) & ChP
->TxCompare
[0]);
2934 ChP
->TxReplace1
[0] = (Byte_t
) (ChOff
+ _TXREP1B1
);
2935 ChP
->TxReplace1
[1] = (Byte_t
) ((ChOff
+ _TXREP1B1
) >> 8);
2936 ChP
->TxReplace1
[2] = 0;
2937 ChP
->TxReplace1
[3] = 0;
2938 sOutDW(ChP
->IndexAddr
, *(DWord_t
*) & ChP
->TxReplace1
[0]);
2940 ChP
->TxReplace2
[0] = (Byte_t
) (ChOff
+ _TXREP2
);
2941 ChP
->TxReplace2
[1] = (Byte_t
) ((ChOff
+ _TXREP2
) >> 8);
2942 ChP
->TxReplace2
[2] = 0;
2943 ChP
->TxReplace2
[3] = 0;
2944 sOutDW(ChP
->IndexAddr
, *(DWord_t
*) & ChP
->TxReplace2
[0]);
2946 ChP
->TxFIFOPtrs
= ChOff
+ _TXF_OUTP
;
2947 ChP
->TxFIFO
= ChOff
+ _TX_FIFO
;
2949 sOutB(ChP
->Cmd
, (Byte_t
) ChanNum
| RESTXFCNT
); /* apply reset Tx FIFO count */
2950 sOutB(ChP
->Cmd
, (Byte_t
) ChanNum
); /* remove reset Tx FIFO count */
2951 sOutW((WordIO_t
) ChP
->IndexAddr
, ChP
->TxFIFOPtrs
); /* clear Tx in/out ptrs */
2952 sOutW(ChP
->IndexData
, 0);
2953 ChP
->RxFIFOPtrs
= ChOff
+ _RXF_OUTP
;
2954 ChP
->RxFIFO
= ChOff
+ _RX_FIFO
;
2956 sOutB(ChP
->Cmd
, (Byte_t
) ChanNum
| RESRXFCNT
); /* apply reset Rx FIFO count */
2957 sOutB(ChP
->Cmd
, (Byte_t
) ChanNum
); /* remove reset Rx FIFO count */
2958 sOutW((WordIO_t
) ChP
->IndexAddr
, ChP
->RxFIFOPtrs
); /* clear Rx out ptr */
2959 sOutW(ChP
->IndexData
, 0);
2960 sOutW((WordIO_t
) ChP
->IndexAddr
, ChP
->RxFIFOPtrs
+ 2); /* clear Rx in ptr */
2961 sOutW(ChP
->IndexData
, 0);
2962 ChP
->TxPrioCnt
= ChOff
+ _TXP_CNT
;
2963 sOutW((WordIO_t
) ChP
->IndexAddr
, ChP
->TxPrioCnt
);
2964 sOutB(ChP
->IndexData
, 0);
2965 ChP
->TxPrioPtr
= ChOff
+ _TXP_PNTR
;
2966 sOutW((WordIO_t
) ChP
->IndexAddr
, ChP
->TxPrioPtr
);
2967 sOutB(ChP
->IndexData
, 0);
2968 ChP
->TxPrioBuf
= ChOff
+ _TXP_BUF
;
2969 sEnRxProcessor(ChP
); /* start the Rx processor */
2974 /***************************************************************************
2975 Function: sStopRxProcessor
2976 Purpose: Stop the receive processor from processing a channel.
2977 Call: sStopRxProcessor(ChP)
2978 CHANNEL_T *ChP; Ptr to channel structure
2980 Comments: The receive processor can be started again with sStartRxProcessor().
2981 This function causes the receive processor to skip over the
2982 stopped channel. It does not stop it from processing other channels.
2984 Warnings: No context switches are allowed while executing this function.
2986 Do not leave the receive processor stopped for more than one
2989 After calling this function a delay of 4 uS is required to ensure
2990 that the receive processor is no longer processing this channel.
2992 void sStopRxProcessor(CHANNEL_T
* ChP
)
3000 sOutDW(ChP
->IndexAddr
, *(DWord_t
*) & R
[0]);
3003 /***************************************************************************
3004 Function: sFlushRxFIFO
3005 Purpose: Flush the Rx FIFO
3006 Call: sFlushRxFIFO(ChP)
3007 CHANNEL_T *ChP; Ptr to channel structure
3009 Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
3010 while it is being flushed the receive processor is stopped
3011 and the transmitter is disabled. After these operations a
3012 4 uS delay is done before clearing the pointers to allow
3013 the receive processor to stop. These items are handled inside
3015 Warnings: No context switches are allowed while executing this function.
3017 void sFlushRxFIFO(CHANNEL_T
* ChP
)
3020 Byte_t Ch
; /* channel number within AIOP */
3021 int RxFIFOEnabled
; /* TRUE if Rx FIFO enabled */
3023 if (sGetRxCnt(ChP
) == 0) /* Rx FIFO empty */
3024 return; /* don't need to flush */
3026 RxFIFOEnabled
= FALSE
;
3027 if (ChP
->R
[0x32] == 0x08) { /* Rx FIFO is enabled */
3028 RxFIFOEnabled
= TRUE
;
3029 sDisRxFIFO(ChP
); /* disable it */
3030 for (i
= 0; i
< 2000 / 200; i
++) /* delay 2 uS to allow proc to disable FIFO */
3031 sInB(ChP
->IntChan
); /* depends on bus i/o timing */
3033 sGetChanStatus(ChP
); /* clear any pending Rx errors in chan stat */
3034 Ch
= (Byte_t
) sGetChanNum(ChP
);
3035 sOutB(ChP
->Cmd
, Ch
| RESRXFCNT
); /* apply reset Rx FIFO count */
3036 sOutB(ChP
->Cmd
, Ch
); /* remove reset Rx FIFO count */
3037 sOutW((WordIO_t
) ChP
->IndexAddr
, ChP
->RxFIFOPtrs
); /* clear Rx out ptr */
3038 sOutW(ChP
->IndexData
, 0);
3039 sOutW((WordIO_t
) ChP
->IndexAddr
, ChP
->RxFIFOPtrs
+ 2); /* clear Rx in ptr */
3040 sOutW(ChP
->IndexData
, 0);
3042 sEnRxFIFO(ChP
); /* enable Rx FIFO */
3045 /***************************************************************************
3046 Function: sFlushTxFIFO
3047 Purpose: Flush the Tx FIFO
3048 Call: sFlushTxFIFO(ChP)
3049 CHANNEL_T *ChP; Ptr to channel structure
3051 Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
3052 while it is being flushed the receive processor is stopped
3053 and the transmitter is disabled. After these operations a
3054 4 uS delay is done before clearing the pointers to allow
3055 the receive processor to stop. These items are handled inside
3057 Warnings: No context switches are allowed while executing this function.
3059 void sFlushTxFIFO(CHANNEL_T
* ChP
)
3062 Byte_t Ch
; /* channel number within AIOP */
3063 int TxEnabled
; /* TRUE if transmitter enabled */
3065 if (sGetTxCnt(ChP
) == 0) /* Tx FIFO empty */
3066 return; /* don't need to flush */
3069 if (ChP
->TxControl
[3] & TX_ENABLE
) {
3071 sDisTransmit(ChP
); /* disable transmitter */
3073 sStopRxProcessor(ChP
); /* stop Rx processor */
3074 for (i
= 0; i
< 4000 / 200; i
++) /* delay 4 uS to allow proc to stop */
3075 sInB(ChP
->IntChan
); /* depends on bus i/o timing */
3076 Ch
= (Byte_t
) sGetChanNum(ChP
);
3077 sOutB(ChP
->Cmd
, Ch
| RESTXFCNT
); /* apply reset Tx FIFO count */
3078 sOutB(ChP
->Cmd
, Ch
); /* remove reset Tx FIFO count */
3079 sOutW((WordIO_t
) ChP
->IndexAddr
, ChP
->TxFIFOPtrs
); /* clear Tx in/out ptrs */
3080 sOutW(ChP
->IndexData
, 0);
3082 sEnTransmit(ChP
); /* enable transmitter */
3083 sStartRxProcessor(ChP
); /* restart Rx processor */
3086 /***************************************************************************
3087 Function: sWriteTxPrioByte
3088 Purpose: Write a byte of priority transmit data to a channel
3089 Call: sWriteTxPrioByte(ChP,Data)
3090 CHANNEL_T *ChP; Ptr to channel structure
3091 Byte_t Data; The transmit data byte
3093 Return: int: 1 if the bytes is successfully written, otherwise 0.
3095 Comments: The priority byte is transmitted before any data in the Tx FIFO.
3097 Warnings: No context switches are allowed while executing this function.
3099 int sWriteTxPrioByte(CHANNEL_T
* ChP
, Byte_t Data
)
3101 Byte_t DWBuf
[4]; /* buffer for double word writes */
3102 Word_t
*WordPtr
; /* must be far because Win SS != DS */
3103 register DWordIO_t IndexAddr
;
3105 if (sGetTxCnt(ChP
) > 1) { /* write it to Tx priority buffer */
3106 IndexAddr
= ChP
->IndexAddr
;
3107 sOutW((WordIO_t
) IndexAddr
, ChP
->TxPrioCnt
); /* get priority buffer status */
3108 if (sInB((ByteIO_t
) ChP
->IndexData
) & PRI_PEND
) /* priority buffer busy */
3109 return (0); /* nothing sent */
3111 WordPtr
= (Word_t
*) (&DWBuf
[0]);
3112 *WordPtr
= ChP
->TxPrioBuf
; /* data byte address */
3114 DWBuf
[2] = Data
; /* data byte value */
3115 sOutDW(IndexAddr
, *((DWord_t
*) (&DWBuf
[0]))); /* write it out */
3117 *WordPtr
= ChP
->TxPrioCnt
; /* Tx priority count address */
3119 DWBuf
[2] = PRI_PEND
+ 1; /* indicate 1 byte pending */
3120 DWBuf
[3] = 0; /* priority buffer pointer */
3121 sOutDW(IndexAddr
, *((DWord_t
*) (&DWBuf
[0]))); /* write it out */
3122 } else { /* write it to Tx FIFO */
3124 sWriteTxByte(sGetTxRxDataIO(ChP
), Data
);
3126 return (1); /* 1 byte sent */
3129 /***************************************************************************
3130 Function: sEnInterrupts
3131 Purpose: Enable one or more interrupts for a channel
3132 Call: sEnInterrupts(ChP,Flags)
3133 CHANNEL_T *ChP; Ptr to channel structure
3134 Word_t Flags: Interrupt enable flags, can be any combination
3135 of the following flags:
3136 TXINT_EN: Interrupt on Tx FIFO empty
3137 RXINT_EN: Interrupt on Rx FIFO at trigger level (see
3139 SRCINT_EN: Interrupt on SRC (Special Rx Condition)
3140 MCINT_EN: Interrupt on modem input change
3141 CHANINT_EN: Allow channel interrupt signal to the AIOP's
3142 Interrupt Channel Register.
3144 Comments: If an interrupt enable flag is set in Flags, that interrupt will be
3145 enabled. If an interrupt enable flag is not set in Flags, that
3146 interrupt will not be changed. Interrupts can be disabled with
3147 function sDisInterrupts().
3149 This function sets the appropriate bit for the channel in the AIOP's
3150 Interrupt Mask Register if the CHANINT_EN flag is set. This allows
3151 this channel's bit to be set in the AIOP's Interrupt Channel Register.
3153 Interrupts must also be globally enabled before channel interrupts
3154 will be passed on to the host. This is done with function
3157 In some cases it may be desirable to disable interrupts globally but
3158 enable channel interrupts. This would allow the global interrupt
3159 status register to be used to determine which AIOPs need service.
3161 void sEnInterrupts(CHANNEL_T
* ChP
, Word_t Flags
)
3163 Byte_t Mask
; /* Interrupt Mask Register */
3165 ChP
->RxControl
[2] |=
3166 ((Byte_t
) Flags
& (RXINT_EN
| SRCINT_EN
| MCINT_EN
));
3168 sOutDW(ChP
->IndexAddr
, *(DWord_t
*) & ChP
->RxControl
[0]);
3170 ChP
->TxControl
[2] |= ((Byte_t
) Flags
& TXINT_EN
);
3172 sOutDW(ChP
->IndexAddr
, *(DWord_t
*) & ChP
->TxControl
[0]);
3174 if (Flags
& CHANINT_EN
) {
3175 Mask
= sInB(ChP
->IntMask
) | sBitMapSetTbl
[ChP
->ChanNum
];
3176 sOutB(ChP
->IntMask
, Mask
);
3180 /***************************************************************************
3181 Function: sDisInterrupts
3182 Purpose: Disable one or more interrupts for a channel
3183 Call: sDisInterrupts(ChP,Flags)
3184 CHANNEL_T *ChP; Ptr to channel structure
3185 Word_t Flags: Interrupt flags, can be any combination
3186 of the following flags:
3187 TXINT_EN: Interrupt on Tx FIFO empty
3188 RXINT_EN: Interrupt on Rx FIFO at trigger level (see
3190 SRCINT_EN: Interrupt on SRC (Special Rx Condition)
3191 MCINT_EN: Interrupt on modem input change
3192 CHANINT_EN: Disable channel interrupt signal to the
3193 AIOP's Interrupt Channel Register.
3195 Comments: If an interrupt flag is set in Flags, that interrupt will be
3196 disabled. If an interrupt flag is not set in Flags, that
3197 interrupt will not be changed. Interrupts can be enabled with
3198 function sEnInterrupts().
3200 This function clears the appropriate bit for the channel in the AIOP's
3201 Interrupt Mask Register if the CHANINT_EN flag is set. This blocks
3202 this channel's bit from being set in the AIOP's Interrupt Channel
3205 void sDisInterrupts(CHANNEL_T
* ChP
, Word_t Flags
)
3207 Byte_t Mask
; /* Interrupt Mask Register */
3209 ChP
->RxControl
[2] &=
3210 ~((Byte_t
) Flags
& (RXINT_EN
| SRCINT_EN
| MCINT_EN
));
3211 sOutDW(ChP
->IndexAddr
, *(DWord_t
*) & ChP
->RxControl
[0]);
3212 ChP
->TxControl
[2] &= ~((Byte_t
) Flags
& TXINT_EN
);
3213 sOutDW(ChP
->IndexAddr
, *(DWord_t
*) & ChP
->TxControl
[0]);
3215 if (Flags
& CHANINT_EN
) {
3216 Mask
= sInB(ChP
->IntMask
) & sBitMapClrTbl
[ChP
->ChanNum
];
3217 sOutB(ChP
->IntMask
, Mask
);
3221 void sSetInterfaceMode(CHANNEL_T
* ChP
, Byte_t mode
)
3223 sOutB(ChP
->CtlP
->AiopIO
[2], (mode
& 0x18) | ChP
->ChanNum
);
3227 * Not an official SSCI function, but how to reset RocketModems.
3230 void sModemReset(CONTROLLER_T
* CtlP
, int chan
, int on
)
3235 addr
= CtlP
->AiopIO
[0] + 0x400;
3236 val
= sInB(CtlP
->MReg3IO
);
3237 /* if AIOP[1] is not enabled, enable it */
3238 if ((val
& 2) == 0) {
3239 val
= sInB(CtlP
->MReg2IO
);
3240 sOutB(CtlP
->MReg2IO
, (val
& 0xfc) | (1 & 0x03));
3241 sOutB(CtlP
->MBaseIO
, (unsigned char) (addr
>> 6));
3247 sOutB(addr
+ chan
, 0); /* apply or remove reset */
3252 * Not an official SSCI function, but how to reset RocketModems.
3255 void sPCIModemReset(CONTROLLER_T
* CtlP
, int chan
, int on
)
3259 addr
= CtlP
->AiopIO
[0] + 0x40; /* 2nd AIOP */
3262 sOutB(addr
+ chan
, 0); /* apply or remove reset */
3265 /* Resets the speaker controller on RocketModem II and III devices */
3266 static void rmSpeakerReset(CONTROLLER_T
* CtlP
, unsigned long model
)
3270 /* RocketModem II speaker control is at the 8th port location of offset 0x40 */
3271 if ((model
== MODEL_RP4M
) || (model
== MODEL_RP6M
)) {
3272 addr
= CtlP
->AiopIO
[0] + 0x4F;
3276 /* RocketModem III speaker control is at the 1st port location of offset 0x80 */
3277 if ((model
== MODEL_UPCI_RM3_8PORT
)
3278 || (model
== MODEL_UPCI_RM3_4PORT
)) {
3279 addr
= CtlP
->AiopIO
[0] + 0x88;
3284 /* Returns the line number given the controller (board), aiop and channel number */
3285 static unsigned char GetLineNumber(int ctrl
, int aiop
, int ch
)
3287 return lineNumbers
[(ctrl
<< 5) | (aiop
<< 3) | ch
];
3291 * Stores the line number associated with a given controller (board), aiop
3292 * and channel number.
3293 * Returns: The line number assigned
3295 static unsigned char SetLineNumber(int ctrl
, int aiop
, int ch
)
3297 lineNumbers
[(ctrl
<< 5) | (aiop
<< 3) | ch
] = nextLineNumber
++;
3298 return (nextLineNumber
- 1);