aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/rocket.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/rocket.c')
-rw-r--r--drivers/char/rocket.c3299
1 files changed, 3299 insertions, 0 deletions
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
new file mode 100644
index 000000000000..5bcbeb0cb9ae
--- /dev/null
+++ b/drivers/char/rocket.c
@@ -0,0 +1,3299 @@
1/*
2 * RocketPort device driver for Linux
3 *
4 * Written by Theodore Ts'o, 1995, 1996, 1997, 1998, 1999, 2000.
5 *
6 * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2003 by Comtrol, Inc.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
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.
17 *
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.
21 */
22
23/*
24 * Kernel Synchronization:
25 *
26 * This driver has 2 kernel control paths - exception handlers (calls into the driver
27 * from user mode) and the timer bottom half (tasklet). This is a polled driver, interrupts
28 * are not used.
29 *
30 * Critical data:
31 * - rp_table[], accessed through passed "info" pointers, is a global (static) array of
32 * serial port state information and the xmit_buf circular buffer. Protected by
33 * a per port spinlock.
34 * - xmit_flags[], an array of ints indexed by line (port) number, indicating that there
35 * is data to be transmitted. Protected by atomic bit operations.
36 * - rp_num_ports, int indicating number of open ports, protected by atomic operations.
37 *
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.
40 */
41
42/****** Defines ******/
43#ifdef PCI_NUM_RESOURCES
44#define PCI_BASE_ADDRESS(dev, r) ((dev)->resource[r].start)
45#else
46#define PCI_BASE_ADDRESS(dev, r) ((dev)->base_address[r])
47#endif
48
49#define ROCKET_PARANOIA_CHECK
50#define ROCKET_DISABLE_SIMUSAGE
51
52#undef ROCKET_SOFT_FLOW
53#undef ROCKET_DEBUG_OPEN
54#undef ROCKET_DEBUG_INTR
55#undef ROCKET_DEBUG_WRITE
56#undef ROCKET_DEBUG_FLOW
57#undef ROCKET_DEBUG_THROTTLE
58#undef ROCKET_DEBUG_WAIT_UNTIL_SENT
59#undef ROCKET_DEBUG_RECEIVE
60#undef ROCKET_DEBUG_HANGUP
61#undef REV_PCI_ORDER
62#undef ROCKET_DEBUG_IO
63
64#define POLL_PERIOD HZ/100 /* Polling period .01 seconds (10ms) */
65
66/****** Kernel includes ******/
67
68#ifdef MODVERSIONS
69#include <config/modversions.h>
70#endif
71
72#include <linux/module.h>
73#include <linux/errno.h>
74#include <linux/major.h>
75#include <linux/kernel.h>
76#include <linux/signal.h>
77#include <linux/slab.h>
78#include <linux/mm.h>
79#include <linux/sched.h>
80#include <linux/timer.h>
81#include <linux/interrupt.h>
82#include <linux/tty.h>
83#include <linux/tty_driver.h>
84#include <linux/tty_flip.h>
85#include <linux/string.h>
86#include <linux/fcntl.h>
87#include <linux/ptrace.h>
88#include <linux/ioport.h>
89#include <linux/delay.h>
90#include <linux/wait.h>
91#include <linux/pci.h>
92#include <asm/uaccess.h>
93#include <asm/atomic.h>
94#include <linux/bitops.h>
95#include <linux/spinlock.h>
96#include <asm/semaphore.h>
97#include <linux/init.h>
98
99/****** RocketPort includes ******/
100
101#include "rocket_int.h"
102#include "rocket.h"
103
104#define ROCKET_VERSION "2.09"
105#define ROCKET_DATE "12-June-2003"
106
107/****** RocketPort Local Variables ******/
108
109static struct tty_driver *rocket_driver;
110
111static struct rocket_version driver_version = {
112 ROCKET_VERSION, ROCKET_DATE
113};
114
115static struct r_port *rp_table[MAX_RP_PORTS]; /* The main repository of serial port state information. */
116static unsigned int xmit_flags[NUM_BOARDS]; /* Bit significant, indicates port had data to transmit. */
117 /* eg. Bit 0 indicates port 0 has xmit data, ... */
118static atomic_t rp_num_ports_open; /* Number of serial ports open */
119static struct timer_list rocket_timer;
120
121static unsigned long board1; /* ISA addresses, retrieved from rocketport.conf */
122static unsigned long board2;
123static unsigned long board3;
124static unsigned long board4;
125static unsigned long controller;
126static int support_low_speed;
127static unsigned long modem1;
128static unsigned long modem2;
129static unsigned long modem3;
130static unsigned long modem4;
131static unsigned long pc104_1[8];
132static unsigned long pc104_2[8];
133static unsigned long pc104_3[8];
134static unsigned long pc104_4[8];
135static unsigned long *pc104[4] = { pc104_1, pc104_2, pc104_3, pc104_4 };
136
137static int rp_baud_base[NUM_BOARDS]; /* Board config info (Someday make a per-board structure) */
138static unsigned long rcktpt_io_addr[NUM_BOARDS];
139static int rcktpt_type[NUM_BOARDS];
140static int is_PCI[NUM_BOARDS];
141static rocketModel_t rocketModel[NUM_BOARDS];
142static int max_board;
143
144/*
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.
148 */
149
150static Word_t aiop_intr_bits[AIOP_CTL_SIZE] = {
151 AIOP_INTR_BIT_0,
152 AIOP_INTR_BIT_1,
153 AIOP_INTR_BIT_2,
154 AIOP_INTR_BIT_3
155};
156
157static 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,
161 UPCI_AIOP_INTR_BIT_3
162};
163
164/*
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.
168 */
169static unsigned char lineNumbers[MAX_RP_PORTS];
170static unsigned long nextLineNumber;
171
172/***** RocketPort Static Prototypes *********/
173static int __init init_ISA(int i);
174static void rp_wait_until_sent(struct tty_struct *tty, int timeout);
175static void rp_flush_buffer(struct tty_struct *tty);
176static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model);
177static unsigned char GetLineNumber(int ctrl, int aiop, int ch);
178static unsigned char SetLineNumber(int ctrl, int aiop, int ch);
179static void rp_start(struct tty_struct *tty);
180
181#ifdef MODULE
182MODULE_AUTHOR("Theodore Ts'o");
183MODULE_DESCRIPTION("Comtrol RocketPort driver");
184module_param(board1, ulong, 0);
185MODULE_PARM_DESC(board1, "I/O port for (ISA) board #1");
186module_param(board2, ulong, 0);
187MODULE_PARM_DESC(board2, "I/O port for (ISA) board #2");
188module_param(board3, ulong, 0);
189MODULE_PARM_DESC(board3, "I/O port for (ISA) board #3");
190module_param(board4, ulong, 0);
191MODULE_PARM_DESC(board4, "I/O port for (ISA) board #4");
192module_param(controller, ulong, 0);
193MODULE_PARM_DESC(controller, "I/O port for (ISA) rocketport controller");
194module_param(support_low_speed, bool, 0);
195MODULE_PARM_DESC(support_low_speed, "1 means support 50 baud, 0 means support 460400 baud");
196module_param(modem1, ulong, 0);
197MODULE_PARM_DESC(modem1, "1 means (ISA) board #1 is a RocketModem");
198module_param(modem2, ulong, 0);
199MODULE_PARM_DESC(modem2, "1 means (ISA) board #2 is a RocketModem");
200module_param(modem3, ulong, 0);
201MODULE_PARM_DESC(modem3, "1 means (ISA) board #3 is a RocketModem");
202module_param(modem4, ulong, 0);
203MODULE_PARM_DESC(modem4, "1 means (ISA) board #4 is a RocketModem");
204module_param_array(pc104_1, ulong, NULL, 0);
205MODULE_PARM_DESC(pc104_1, "set interface types for ISA(PC104) board #1 (e.g. pc104_1=232,232,485,485,...");
206module_param_array(pc104_2, ulong, NULL, 0);
207MODULE_PARM_DESC(pc104_2, "set interface types for ISA(PC104) board #2 (e.g. pc104_2=232,232,485,485,...");
208module_param_array(pc104_3, ulong, NULL, 0);
209MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc104_3=232,232,485,485,...");
210module_param_array(pc104_4, ulong, NULL, 0);
211MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,...");
212
213int rp_init(void);
214static void rp_cleanup_module(void);
215
216module_init(rp_init);
217module_exit(rp_cleanup_module);
218
219#endif
220
221#ifdef MODULE_LICENSE
222MODULE_LICENSE("Dual BSD/GPL");
223#endif
224
225/*************************************************************************/
226/* Module code starts here */
227
228static inline int rocket_paranoia_check(struct r_port *info,
229 const char *routine)
230{
231#ifdef ROCKET_PARANOIA_CHECK
232 if (!info)
233 return 1;
234 if (info->magic != RPORT_MAGIC) {
235 printk(KERN_INFO "Warning: bad magic number for rocketport struct in %s\n",
236 routine);
237 return 1;
238 }
239#endif
240 return 0;
241}
242
243
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
246 * tty layer.
247 */
248static void rp_do_receive(struct r_port *info,
249 struct tty_struct *tty,
250 CHANNEL_t * cp, unsigned int ChanStatus)
251{
252 unsigned int CharNStat;
253 int ToRecv, wRecv, space = 0, count;
254 unsigned char *cbuf;
255 char *fbuf;
256 struct tty_ldisc *ld;
257
258 ld = tty_ldisc_ref(tty);
259
260 ToRecv = sGetRxCnt(cp);
261 if (ld)
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;
267 count = 0;
268#ifdef ROCKET_DEBUG_INTR
269 printk(KERN_INFO "rp_do_receive(%d, %d)...", ToRecv, space);
270#endif
271
272 /*
273 * determine how many we can actually read in. If we can't
274 * read any in then we have a software overrun condition.
275 */
276 if (ToRecv > space)
277 ToRecv = space;
278
279 if (ToRecv <= 0)
280 return;
281
282 /*
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).
286 */
287 if (ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) {
288 if (!(ChanStatus & STATMODE)) {
289#ifdef ROCKET_DEBUG_RECEIVE
290 printk(KERN_INFO "Entering STATMODE...");
291#endif
292 ChanStatus |= STATMODE;
293 sEnRxStatusMode(cp);
294 }
295 }
296
297 /*
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
301 */
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);
306#endif
307 while (ToRecv) {
308 CharNStat = sInW(sGetTxRxDataIO(cp));
309#ifdef ROCKET_DEBUG_RECEIVE
310 printk(KERN_INFO "%x...", CharNStat);
311#endif
312 if (CharNStat & STMBREAKH)
313 CharNStat &= ~(STMFRAMEH | STMPARITYH);
314 if (CharNStat & info->ignore_status_mask) {
315 ToRecv--;
316 continue;
317 }
318 CharNStat &= info->read_status_mask;
319 if (CharNStat & STMBREAKH)
320 *fbuf++ = TTY_BREAK;
321 else if (CharNStat & STMPARITYH)
322 *fbuf++ = TTY_PARITY;
323 else if (CharNStat & STMFRAMEH)
324 *fbuf++ = TTY_FRAME;
325 else if (CharNStat & STMRCVROVRH)
326 *fbuf++ = TTY_OVERRUN;
327 else
328 *fbuf++ = 0;
329 *cbuf++ = CharNStat & 0xff;
330 count++;
331 ToRecv--;
332 }
333
334 /*
335 * after we've emptied the FIFO in status mode, turn
336 * status mode back off
337 */
338 if (sGetRxCnt(cp) == 0) {
339#ifdef ROCKET_DEBUG_RECEIVE
340 printk(KERN_INFO "Status mode off.\n");
341#endif
342 sDisRxStatusMode(cp);
343 }
344 } else {
345 /*
346 * we aren't in status mode, so read down the FIFO two
347 * characters at time by doing repeated word IO
348 * transfer.
349 */
350 wRecv = ToRecv >> 1;
351 if (wRecv)
352 sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv);
353 if (ToRecv & 1)
354 cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp));
355 memset(fbuf, 0, ToRecv);
356 cbuf += ToRecv;
357 fbuf += ToRecv;
358 count += ToRecv;
359 }
360 /* Push the data up to the tty layer */
361 ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count);
362 tty_ldisc_deref(ld);
363}
364
365/*
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.
370 */
371static void rp_do_transmit(struct r_port *info)
372{
373 int c;
374 CHANNEL_t *cp = &info->channel;
375 struct tty_struct *tty;
376 unsigned long flags;
377
378#ifdef ROCKET_DEBUG_INTR
379 printk(KERN_INFO "rp_do_transmit ");
380#endif
381 if (!info)
382 return;
383 if (!info->tty) {
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]);
386 return;
387 }
388
389 spin_lock_irqsave(&info->slock, flags);
390 tty = info->tty;
391 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
392
393 /* Loop sending data to FIFO until done or FIFO full */
394 while (1) {
395 if (tty->stopped || tty->hw_stopped)
396 break;
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)
399 break;
400 sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) (info->xmit_buf + info->xmit_tail), c / 2);
401 if (c & 1)
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;
405 info->xmit_cnt -= c;
406 info->xmit_fifo_room -= c;
407#ifdef ROCKET_DEBUG_INTR
408 printk(KERN_INFO "tx %d chars...", c);
409#endif
410 }
411
412 if (info->xmit_cnt == 0)
413 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
414
415 if (info->xmit_cnt < WAKEUP_CHARS) {
416 tty_wakeup(tty);
417 wake_up_interruptible(&tty->write_wait);
418#ifdef ROCKETPORT_HAVE_POLL_WAIT
419 wake_up_interruptible(&tty->poll_wait);
420#endif
421 }
422
423 spin_unlock_irqrestore(&info->slock, flags);
424
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);
428#endif
429}
430
431/*
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.
435 */
436static void rp_handle_port(struct r_port *info)
437{
438 CHANNEL_t *cp;
439 struct tty_struct *tty;
440 unsigned int IntMask, ChanStatus;
441
442 if (!info)
443 return;
444
445 if ((info->flags & ROCKET_INITIALIZED) == 0) {
446 printk(KERN_INFO "rp: WARNING: rp_handle_port called with info->flags & NOT_INIT\n");
447 return;
448 }
449 if (!info->tty) {
450 printk(KERN_INFO "rp: WARNING: rp_handle_port called with info->tty==NULL\n");
451 return;
452 }
453 cp = &info->channel;
454 tty = info->tty;
455
456 IntMask = sGetChanIntID(cp) & info->intmask;
457#ifdef ROCKET_DEBUG_INTR
458 printk(KERN_INFO "rp_interrupt %02x...", IntMask);
459#endif
460 ChanStatus = sGetChanStatus(cp);
461 if (IntMask & RXF_TRIG) { /* Rx FIFO trigger level */
462 rp_do_receive(info, tty, cp, ChanStatus);
463 }
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");
468#endif
469 if (!(ChanStatus & CD_ACT) && info->cd_status) {
470#ifdef ROCKET_DEBUG_HANGUP
471 printk(KERN_INFO "CD drop, calling hangup.\n");
472#endif
473 tty_hangup(tty);
474 }
475 info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0;
476 wake_up_interruptible(&info->open_wait);
477 }
478#ifdef ROCKET_DEBUG_INTR
479 if (IntMask & DELTA_CTS) { /* CTS change */
480 printk(KERN_INFO "CTS change...\n");
481 }
482 if (IntMask & DELTA_DSR) { /* DSR change */
483 printk(KERN_INFO "DSR change...\n");
484 }
485#endif
486}
487
488/*
489 * The top level polling routine. Repeats every 1/100 HZ (10ms).
490 */
491static void rp_do_poll(unsigned long dummy)
492{
493 CONTROLLER_t *ctlp;
494 int ctrl, aiop, ch, line, i;
495 unsigned int xmitmask;
496 unsigned int CtlMask;
497 unsigned char AiopMask;
498 Word_t bit;
499
500 /* Walk through all the boards (ctrl's) */
501 for (ctrl = 0; ctrl < max_board; ctrl++) {
502 if (rcktpt_io_addr[ctrl] <= 0)
503 continue;
504
505 /* Get a ptr to the board's control struct */
506 ctlp = sCtlNumToCtlPtr(ctrl);
507
508 /* Get the interupt status from the board */
509#ifdef CONFIG_PCI
510 if (ctlp->BusType == isPCI)
511 CtlMask = sPCIGetControllerIntStatus(ctlp);
512 else
513#endif
514 CtlMask = sGetControllerIntStatus(ctlp);
515
516 /* Check if any AIOP read bits are set */
517 for (aiop = 0; CtlMask; aiop++) {
518 bit = ctlp->AiopIntrBits[aiop];
519 if (CtlMask & bit) {
520 CtlMask &= ~bit;
521 AiopMask = sGetAiopIntStatus(ctlp, aiop);
522
523 /* Check if any port read bits are set */
524 for (ch = 0; AiopMask; AiopMask >>= 1, ch++) {
525 if (AiopMask & 1) {
526
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]);
531 }
532 }
533 }
534 }
535
536 xmitmask = xmit_flags[ctrl];
537
538 /*
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).
543 */
544 if (xmitmask) {
545 for (i = 0; i < rocketModel[ctrl].numPorts; i++) {
546 if (xmitmask & (1 << i)) {
547 aiop = (i & 0x18) >> 3;
548 ch = i & 0x07;
549 line = GetLineNumber(ctrl, aiop, ch);
550 rp_do_transmit(rp_table[line]);
551 }
552 }
553 }
554 }
555
556 /*
557 * Reset the timer so we get called at the next clock tick (10ms).
558 */
559 if (atomic_read(&rp_num_ports_open))
560 mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
561}
562
563/*
564 * Initializes the r_port structure for a port, as well as enabling the port on
565 * the board.
566 * Inputs: board, aiop, chan numbers
567 */
568static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
569{
570 unsigned rocketMode;
571 struct r_port *info;
572 int line;
573 CONTROLLER_T *ctlp;
574
575 /* Get the next available line number */
576 line = SetLineNumber(board, aiop, chan);
577
578 ctlp = sCtlNumToCtlPtr(board);
579
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);
582 if (!info) {
583 printk(KERN_INFO "Couldn't allocate info struct for line #%d\n", line);
584 return;
585 }
586 memset(info, 0, sizeof (struct r_port));
587
588 info->magic = RPORT_MAGIC;
589 info->line = line;
590 info->ctlp = ctlp;
591 info->board = board;
592 info->aiop = aiop;
593 info->chan = chan;
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]) {
600 case 422:
601 info->flags |= ROCKET_MODE_RS422;
602 break;
603 case 485:
604 info->flags |= ROCKET_MODE_RS485;
605 break;
606 case 232:
607 default:
608 info->flags |= ROCKET_MODE_RS232;
609 break;
610 }
611
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);
615 kfree(info);
616 return;
617 }
618
619 rocketMode = info->flags & ROCKET_MODE_MASK;
620
621 if ((info->flags & ROCKET_RTS_TOGGLE) || (rocketMode == ROCKET_MODE_RS485))
622 sEnRTSToggle(&info->channel);
623 else
624 sDisRTSToggle(&info->channel);
625
626 if (ctlp->boardType == ROCKET_TYPE_PC104) {
627 switch (rocketMode) {
628 case ROCKET_MODE_RS485:
629 sSetInterfaceMode(&info->channel, InterfaceModeRS485);
630 break;
631 case ROCKET_MODE_RS422:
632 sSetInterfaceMode(&info->channel, InterfaceModeRS422);
633 break;
634 case ROCKET_MODE_RS232:
635 default:
636 if (info->flags & ROCKET_RTS_TOGGLE)
637 sSetInterfaceMode(&info->channel, InterfaceModeRS232T);
638 else
639 sSetInterfaceMode(&info->channel, InterfaceModeRS232);
640 break;
641 }
642 }
643 spin_lock_init(&info->slock);
644 sema_init(&info->write_sem, 1);
645 rp_table[line] = info;
646 if (pci_dev)
647 tty_register_device(rocket_driver, line, &pci_dev->dev);
648}
649
650/*
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.
653 */
654static void configure_r_port(struct r_port *info,
655 struct termios *old_termios)
656{
657 unsigned cflag;
658 unsigned long flags;
659 unsigned rocketMode;
660 int bits, baud, divisor;
661 CHANNEL_t *cp;
662
663 if (!info->tty || !info->tty->termios)
664 return;
665 cp = &info->channel;
666 cflag = info->tty->termios->c_cflag;
667
668 /* Byte size and parity */
669 if ((cflag & CSIZE) == CS8) {
670 sSetData8(cp);
671 bits = 10;
672 } else {
673 sSetData7(cp);
674 bits = 9;
675 }
676 if (cflag & CSTOPB) {
677 sSetStop2(cp);
678 bits++;
679 } else {
680 sSetStop1(cp);
681 }
682
683 if (cflag & PARENB) {
684 sEnParity(cp);
685 bits++;
686 if (cflag & PARODD) {
687 sSetOddParity(cp);
688 } else {
689 sSetEvenParity(cp);
690 }
691 } else {
692 sDisParity(cp);
693 }
694
695 /* baud rate */
696 baud = tty_get_baud_rate(info->tty);
697 if (!baud)
698 baud = 9600;
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);
705 if (!baud)
706 baud = 9600;
707 divisor = (rp_baud_base[info->board] / baud) - 1;
708 }
709 if (divisor >= 8192 || divisor < 0) {
710 baud = 9600;
711 divisor = (rp_baud_base[info->board] / baud) - 1;
712 }
713 info->cps = baud / bits;
714 sSetBaud(cp, divisor);
715
716 if (cflag & CRTSCTS) {
717 info->intmask |= DELTA_CTS;
718 sEnCTSFlowCtl(cp);
719 } else {
720 info->intmask &= ~DELTA_CTS;
721 sDisCTSFlowCtl(cp);
722 }
723 if (cflag & CLOCAL) {
724 info->intmask &= ~DELTA_CD;
725 } else {
726 spin_lock_irqsave(&info->slock, flags);
727 if (sGetChanStatus(cp) & CD_ACT)
728 info->cd_status = 1;
729 else
730 info->cd_status = 0;
731 info->intmask |= DELTA_CD;
732 spin_unlock_irqrestore(&info->slock, flags);
733 }
734
735 /*
736 * Handle software flow control in the board
737 */
738#ifdef ROCKET_SOFT_FLOW
739 if (I_IXON(info->tty)) {
740 sEnTxSoftFlowCtl(cp);
741 if (I_IXANY(info->tty)) {
742 sEnIXANY(cp);
743 } else {
744 sDisIXANY(cp);
745 }
746 sSetTxXONChar(cp, START_CHAR(info->tty));
747 sSetTxXOFFChar(cp, STOP_CHAR(info->tty));
748 } else {
749 sDisTxSoftFlowCtl(cp);
750 sDisIXANY(cp);
751 sClrTxXOFF(cp);
752 }
753#endif
754
755 /*
756 * Set up ignore/read mask words
757 */
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;
763
764 /*
765 * Characters to ignore
766 */
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;
772 /*
773 * If we're ignoring parity and break indicators,
774 * ignore overruns too. (For real raw support).
775 */
776 if (I_IGNPAR(info->tty))
777 info->ignore_status_mask |= STMRCVROVRH;
778 }
779
780 rocketMode = info->flags & ROCKET_MODE_MASK;
781
782 if ((info->flags & ROCKET_RTS_TOGGLE)
783 || (rocketMode == ROCKET_MODE_RS485))
784 sEnRTSToggle(cp);
785 else
786 sDisRTSToggle(cp);
787
788 sSetRTS(&info->channel);
789
790 if (cp->CtlP->boardType == ROCKET_TYPE_PC104) {
791 switch (rocketMode) {
792 case ROCKET_MODE_RS485:
793 sSetInterfaceMode(cp, InterfaceModeRS485);
794 break;
795 case ROCKET_MODE_RS422:
796 sSetInterfaceMode(cp, InterfaceModeRS422);
797 break;
798 case ROCKET_MODE_RS232:
799 default:
800 if (info->flags & ROCKET_RTS_TOGGLE)
801 sSetInterfaceMode(cp, InterfaceModeRS232T);
802 else
803 sSetInterfaceMode(cp, InterfaceModeRS232);
804 break;
805 }
806 }
807}
808
809/* info->count is considered critical, protected by spinlocks. */
810static int block_til_ready(struct tty_struct *tty, struct file *filp,
811 struct r_port *info)
812{
813 DECLARE_WAITQUEUE(wait, current);
814 int retval;
815 int do_clocal = 0, extra_count = 0;
816 unsigned long flags;
817
818 /*
819 * If the device is in the middle of being closed, then block
820 * until it's done, and then try again.
821 */
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);
827 }
828
829 /*
830 * If non-blocking mode is set, or the port is not enabled,
831 * then make the check up front and then exit.
832 */
833 if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
834 info->flags |= ROCKET_NORMAL_ACTIVE;
835 return 0;
836 }
837 if (tty->termios->c_cflag & CLOCAL)
838 do_clocal = 1;
839
840 /*
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.
844 */
845 retval = 0;
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);
849#endif
850 spin_lock_irqsave(&info->slock, flags);
851
852#ifdef ROCKET_DISABLE_SIMUSAGE
853 info->flags |= ROCKET_NORMAL_ACTIVE;
854#else
855 if (!tty_hung_up_p(filp)) {
856 extra_count = 1;
857 info->count--;
858 }
859#endif
860 info->blocked_open++;
861
862 spin_unlock_irqrestore(&info->slock, flags);
863
864 while (1) {
865 if (tty->termios->c_cflag & CBAUD) {
866 sSetDTR(&info->channel);
867 sSetRTS(&info->channel);
868 }
869 set_current_state(TASK_INTERRUPTIBLE);
870 if (tty_hung_up_p(filp) || !(info->flags & ROCKET_INITIALIZED)) {
871 if (info->flags & ROCKET_HUP_NOTIFY)
872 retval = -EAGAIN;
873 else
874 retval = -ERESTARTSYS;
875 break;
876 }
877 if (!(info->flags & ROCKET_CLOSING) && (do_clocal || (sGetChanStatusLo(&info->channel) & CD_ACT)))
878 break;
879 if (signal_pending(current)) {
880 retval = -ERESTARTSYS;
881 break;
882 }
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);
886#endif
887 schedule(); /* Don't hold spinlock here, will hang PC */
888 }
889 current->state = TASK_RUNNING;
890 remove_wait_queue(&info->open_wait, &wait);
891
892 spin_lock_irqsave(&info->slock, flags);
893
894 if (extra_count)
895 info->count++;
896 info->blocked_open--;
897
898 spin_unlock_irqrestore(&info->slock, flags);
899
900#ifdef ROCKET_DEBUG_OPEN
901 printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n",
902 info->line, info->count);
903#endif
904 if (retval)
905 return retval;
906 info->flags |= ROCKET_NORMAL_ACTIVE;
907 return 0;
908}
909
910/*
911 * Exception handler that opens a serial port. Creates xmit_buf storage, fills in
912 * port's r_port struct. Initializes the port hardware.
913 */
914static int rp_open(struct tty_struct *tty, struct file *filp)
915{
916 struct r_port *info;
917 int line = 0, retval;
918 CHANNEL_t *cp;
919 unsigned long page;
920
921 line = TTY_GET_LINE(tty);
922 if ((line < 0) || (line >= MAX_RP_PORTS) || ((info = rp_table[line]) == NULL))
923 return -ENXIO;
924
925 page = __get_free_page(GFP_KERNEL);
926 if (!page)
927 return -ENOMEM;
928
929 if (info->flags & ROCKET_CLOSING) {
930 interruptible_sleep_on(&info->close_wait);
931 free_page(page);
932 return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
933 }
934
935 /*
936 * We must not sleep from here until the port is marked fully in use.
937 */
938 if (info->xmit_buf)
939 free_page(page);
940 else
941 info->xmit_buf = (unsigned char *) page;
942
943 tty->driver_data = info;
944 info->tty = tty;
945
946 if (info->count++ == 0) {
947 atomic_inc(&rp_num_ports_open);
948
949#ifdef ROCKET_DEBUG_OPEN
950 printk(KERN_INFO "rocket mod++ = %d...", atomic_read(&rp_num_ports_open));
951#endif
952 }
953#ifdef ROCKET_DEBUG_OPEN
954 printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->count);
955#endif
956
957 /*
958 * Info->count is now 1; so it's safe to sleep now.
959 */
960 info->session = current->signal->session;
961 info->pgrp = process_group(current);
962
963 if ((info->flags & ROCKET_INITIALIZED) == 0) {
964 cp = &info->channel;
965 sSetRxTrigger(cp, TRIG_1);
966 if (sGetChanStatus(cp) & CD_ACT)
967 info->cd_status = 1;
968 else
969 info->cd_status = 0;
970 sDisRxStatusMode(cp);
971 sFlushRxFIFO(cp);
972 sFlushTxFIFO(cp);
973
974 sEnInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
975 sSetRxTrigger(cp, TRIG_1);
976
977 sGetChanStatus(cp);
978 sDisRxStatusMode(cp);
979 sClrTxXOFF(cp);
980
981 sDisCTSFlowCtl(cp);
982 sDisTxSoftFlowCtl(cp);
983
984 sEnRxFIFO(cp);
985 sEnTransmit(cp);
986
987 info->flags |= ROCKET_INITIALIZED;
988
989 /*
990 * Set up the tty->alt_speed kludge
991 */
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;
1000
1001 configure_r_port(info, NULL);
1002 if (tty->termios->c_cflag & CBAUD) {
1003 sSetDTR(cp);
1004 sSetRTS(cp);
1005 }
1006 }
1007 /* Starts (or resets) the maint polling loop */
1008 mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
1009
1010 retval = block_til_ready(tty, filp, info);
1011 if (retval) {
1012#ifdef ROCKET_DEBUG_OPEN
1013 printk(KERN_INFO "rp_open returning after block_til_ready with %d\n", retval);
1014#endif
1015 return retval;
1016 }
1017 return 0;
1018}
1019
1020/*
1021 * Exception handler that closes a serial port. info->count is considered critical.
1022 */
1023static void rp_close(struct tty_struct *tty, struct file *filp)
1024{
1025 struct r_port *info = (struct r_port *) tty->driver_data;
1026 unsigned long flags;
1027 int timeout;
1028 CHANNEL_t *cp;
1029
1030 if (rocket_paranoia_check(info, "rp_close"))
1031 return;
1032
1033#ifdef ROCKET_DEBUG_OPEN
1034 printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->count);
1035#endif
1036
1037 if (tty_hung_up_p(filp))
1038 return;
1039 spin_lock_irqsave(&info->slock, flags);
1040
1041 if ((tty->count == 1) && (info->count != 1)) {
1042 /*
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.
1048 */
1049 printk(KERN_INFO "rp_close: bad serial port count; tty->count is 1, "
1050 "info->count is %d\n", info->count);
1051 info->count = 1;
1052 }
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);
1056 info->count = 0;
1057 }
1058 if (info->count) {
1059 spin_unlock_irqrestore(&info->slock, flags);
1060 return;
1061 }
1062 info->flags |= ROCKET_CLOSING;
1063 spin_unlock_irqrestore(&info->slock, flags);
1064
1065 cp = &info->channel;
1066
1067 /*
1068 * Notify the line discpline to only process XON/XOFF characters
1069 */
1070 tty->closing = 1;
1071
1072 /*
1073 * If transmission was throttled by the application request,
1074 * just flush the xmit buffer.
1075 */
1076 if (tty->flow_stopped)
1077 rp_flush_buffer(tty);
1078
1079 /*
1080 * Wait for the transmit buffer to clear
1081 */
1082 if (info->closing_wait != ROCKET_CLOSING_WAIT_NONE)
1083 tty_wait_until_sent(tty, info->closing_wait);
1084 /*
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!
1088 */
1089 timeout = (sGetTxCnt(cp) + 1) * HZ / info->cps;
1090 if (timeout == 0)
1091 timeout = 1;
1092 rp_wait_until_sent(tty, timeout);
1093 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1094
1095 sDisTransmit(cp);
1096 sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
1097 sDisCTSFlowCtl(cp);
1098 sDisTxSoftFlowCtl(cp);
1099 sClrTxXOFF(cp);
1100 sFlushRxFIFO(cp);
1101 sFlushTxFIFO(cp);
1102 sClrRTS(cp);
1103 if (C_HUPCL(tty))
1104 sClrDTR(cp);
1105
1106 if (TTY_DRIVER_FLUSH_BUFFER_EXISTS(tty))
1107 TTY_DRIVER_FLUSH_BUFFER(tty);
1108
1109 tty_ldisc_flush(tty);
1110
1111 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1112
1113 if (info->blocked_open) {
1114 if (info->close_delay) {
1115 msleep_interruptible(jiffies_to_msecs(info->close_delay));
1116 }
1117 wake_up_interruptible(&info->open_wait);
1118 } else {
1119 if (info->xmit_buf) {
1120 free_page((unsigned long) info->xmit_buf);
1121 info->xmit_buf = NULL;
1122 }
1123 }
1124 info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE);
1125 tty->closing = 0;
1126 wake_up_interruptible(&info->close_wait);
1127 atomic_dec(&rp_num_ports_open);
1128
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);
1132#endif
1133
1134}
1135
1136static void rp_set_termios(struct tty_struct *tty,
1137 struct termios *old_termios)
1138{
1139 struct r_port *info = (struct r_port *) tty->driver_data;
1140 CHANNEL_t *cp;
1141 unsigned cflag;
1142
1143 if (rocket_paranoia_check(info, "rp_set_termios"))
1144 return;
1145
1146 cflag = tty->termios->c_cflag;
1147
1148 if (cflag == old_termios->c_cflag)
1149 return;
1150
1151 /*
1152 * This driver doesn't support CS5 or CS6
1153 */
1154 if (((cflag & CSIZE) == CS5) || ((cflag & CSIZE) == CS6))
1155 tty->termios->c_cflag =
1156 ((cflag & ~CSIZE) | (old_termios->c_cflag & CSIZE));
1157
1158 configure_r_port(info, old_termios);
1159
1160 cp = &info->channel;
1161
1162 /* Handle transition to B0 status */
1163 if ((old_termios->c_cflag & CBAUD) && !(tty->termios->c_cflag & CBAUD)) {
1164 sClrDTR(cp);
1165 sClrRTS(cp);
1166 }
1167
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))
1171 sSetRTS(cp);
1172 sSetDTR(cp);
1173 }
1174
1175 if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
1176 tty->hw_stopped = 0;
1177 rp_start(tty);
1178 }
1179}
1180
1181static void rp_break(struct tty_struct *tty, int break_state)
1182{
1183 struct r_port *info = (struct r_port *) tty->driver_data;
1184 unsigned long flags;
1185
1186 if (rocket_paranoia_check(info, "rp_break"))
1187 return;
1188
1189 spin_lock_irqsave(&info->slock, flags);
1190 if (break_state == -1)
1191 sSendBreak(&info->channel);
1192 else
1193 sClrBreak(&info->channel);
1194 spin_unlock_irqrestore(&info->slock, flags);
1195}
1196
1197/*
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.
1202 */
1203static int sGetChanRI(CHANNEL_T * ChP)
1204{
1205 CONTROLLER_t *CtlP = ChP->CtlP;
1206 int ChanNum = ChP->ChanNum;
1207 int RingInd = 0;
1208
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]);
1215
1216 return RingInd;
1217}
1218
1219/********************************************************************************************/
1220/* Here are the routines used by rp_ioctl. These are all called from exception handlers. */
1221
1222/*
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.
1225 */
1226static int rp_tiocmget(struct tty_struct *tty, struct file *file)
1227{
1228 struct r_port *info = (struct r_port *)tty->driver_data;
1229 unsigned int control, result, ChanStatus;
1230
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);
1239
1240 return result;
1241}
1242
1243/*
1244 * Sets the modem control lines
1245 */
1246static int rp_tiocmset(struct tty_struct *tty, struct file *file,
1247 unsigned int set, unsigned int clear)
1248{
1249 struct r_port *info = (struct r_port *)tty->driver_data;
1250
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;
1259
1260 sOutDW(info->channel.IndexAddr, *(DWord_t *) & (info->channel.TxControl[0]));
1261 return 0;
1262}
1263
1264static int get_config(struct r_port *info, struct rocket_config __user *retinfo)
1265{
1266 struct rocket_config tmp;
1267
1268 if (!retinfo)
1269 return -EFAULT;
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];
1276
1277 if (copy_to_user(retinfo, &tmp, sizeof (*retinfo)))
1278 return -EFAULT;
1279 return 0;
1280}
1281
1282static int set_config(struct r_port *info, struct rocket_config __user *new_info)
1283{
1284 struct rocket_config new_serial;
1285
1286 if (copy_from_user(&new_serial, new_info, sizeof (new_serial)))
1287 return -EFAULT;
1288
1289 if (!capable(CAP_SYS_ADMIN))
1290 {
1291 if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK))
1292 return -EPERM;
1293 info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK));
1294 configure_r_port(info, NULL);
1295 return 0;
1296 }
1297
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;
1301
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;
1310
1311 configure_r_port(info, NULL);
1312 return 0;
1313}
1314
1315/*
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.
1320 */
1321static int get_ports(struct r_port *info, struct rocket_ports __user *retports)
1322{
1323 struct rocket_ports tmp;
1324 int board;
1325
1326 if (!retports)
1327 return -EFAULT;
1328 memset(&tmp, 0, sizeof (tmp));
1329 tmp.tty_major = rocket_driver->major;
1330
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;
1337 }
1338 if (copy_to_user(retports, &tmp, sizeof (*retports)))
1339 return -EFAULT;
1340 return 0;
1341}
1342
1343static int reset_rm2(struct r_port *info, void __user *arg)
1344{
1345 int reset;
1346
1347 if (copy_from_user(&reset, arg, sizeof (int)))
1348 return -EFAULT;
1349 if (reset)
1350 reset = 1;
1351
1352 if (rcktpt_type[info->board] != ROCKET_TYPE_MODEMII &&
1353 rcktpt_type[info->board] != ROCKET_TYPE_MODEMIII)
1354 return -EINVAL;
1355
1356 if (info->ctlp->BusType == isISA)
1357 sModemReset(info->ctlp, info->chan, reset);
1358 else
1359 sPCIModemReset(info->ctlp, info->chan, reset);
1360
1361 return 0;
1362}
1363
1364static int get_version(struct r_port *info, struct rocket_version __user *retvers)
1365{
1366 if (copy_to_user(retvers, &driver_version, sizeof (*retvers)))
1367 return -EFAULT;
1368 return 0;
1369}
1370
1371/* IOCTL call handler into the driver */
1372static int rp_ioctl(struct tty_struct *tty, struct file *file,
1373 unsigned int cmd, unsigned long arg)
1374{
1375 struct r_port *info = (struct r_port *) tty->driver_data;
1376 void __user *argp = (void __user *)arg;
1377
1378 if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl"))
1379 return -ENXIO;
1380
1381 switch (cmd) {
1382 case RCKP_GET_STRUCT:
1383 if (copy_to_user(argp, info, sizeof (struct r_port)))
1384 return -EFAULT;
1385 return 0;
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);
1396 default:
1397 return -ENOIOCTLCMD;
1398 }
1399 return 0;
1400}
1401
1402static void rp_send_xchar(struct tty_struct *tty, char ch)
1403{
1404 struct r_port *info = (struct r_port *) tty->driver_data;
1405 CHANNEL_t *cp;
1406
1407 if (rocket_paranoia_check(info, "rp_send_xchar"))
1408 return;
1409
1410 cp = &info->channel;
1411 if (sGetTxCnt(cp))
1412 sWriteTxPrioByte(cp, ch);
1413 else
1414 sWriteTxByte(sGetTxRxDataIO(cp), ch);
1415}
1416
1417static void rp_throttle(struct tty_struct *tty)
1418{
1419 struct r_port *info = (struct r_port *) tty->driver_data;
1420 CHANNEL_t *cp;
1421
1422#ifdef ROCKET_DEBUG_THROTTLE
1423 printk(KERN_INFO "throttle %s: %d....\n", tty->name,
1424 tty->ldisc.chars_in_buffer(tty));
1425#endif
1426
1427 if (rocket_paranoia_check(info, "rp_throttle"))
1428 return;
1429
1430 cp = &info->channel;
1431 if (I_IXOFF(tty))
1432 rp_send_xchar(tty, STOP_CHAR(tty));
1433
1434 sClrRTS(&info->channel);
1435}
1436
1437static void rp_unthrottle(struct tty_struct *tty)
1438{
1439 struct r_port *info = (struct r_port *) tty->driver_data;
1440 CHANNEL_t *cp;
1441#ifdef ROCKET_DEBUG_THROTTLE
1442 printk(KERN_INFO "unthrottle %s: %d....\n", tty->name,
1443 tty->ldisc.chars_in_buffer(tty));
1444#endif
1445
1446 if (rocket_paranoia_check(info, "rp_throttle"))
1447 return;
1448
1449 cp = &info->channel;
1450 if (I_IXOFF(tty))
1451 rp_send_xchar(tty, START_CHAR(tty));
1452
1453 sSetRTS(&info->channel);
1454}
1455
1456/*
1457 * ------------------------------------------------------------
1458 * rp_stop() and rp_start()
1459 *
1460 * This routines are called before setting or resetting tty->stopped.
1461 * They enable or disable transmitter interrupts, as necessary.
1462 * ------------------------------------------------------------
1463 */
1464static void rp_stop(struct tty_struct *tty)
1465{
1466 struct r_port *info = (struct r_port *) tty->driver_data;
1467
1468#ifdef ROCKET_DEBUG_FLOW
1469 printk(KERN_INFO "stop %s: %d %d....\n", tty->name,
1470 info->xmit_cnt, info->xmit_fifo_room);
1471#endif
1472
1473 if (rocket_paranoia_check(info, "rp_stop"))
1474 return;
1475
1476 if (sGetTxCnt(&info->channel))
1477 sDisTransmit(&info->channel);
1478}
1479
1480static void rp_start(struct tty_struct *tty)
1481{
1482 struct r_port *info = (struct r_port *) tty->driver_data;
1483
1484#ifdef ROCKET_DEBUG_FLOW
1485 printk(KERN_INFO "start %s: %d %d....\n", tty->name,
1486 info->xmit_cnt, info->xmit_fifo_room);
1487#endif
1488
1489 if (rocket_paranoia_check(info, "rp_stop"))
1490 return;
1491
1492 sEnTransmit(&info->channel);
1493 set_bit((info->aiop * 8) + info->chan,
1494 (void *) &xmit_flags[info->board]);
1495}
1496
1497/*
1498 * rp_wait_until_sent() --- wait until the transmitter is empty
1499 */
1500static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
1501{
1502 struct r_port *info = (struct r_port *) tty->driver_data;
1503 CHANNEL_t *cp;
1504 unsigned long orig_jiffies;
1505 int check_time, exit_time;
1506 int txcnt;
1507
1508 if (rocket_paranoia_check(info, "rp_wait_until_sent"))
1509 return;
1510
1511 cp = &info->channel;
1512
1513 orig_jiffies = jiffies;
1514#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1515 printk(KERN_INFO "In RP_wait_until_sent(%d) (jiff=%lu)...", timeout,
1516 jiffies);
1517 printk(KERN_INFO "cps=%d...", info->cps);
1518#endif
1519 while (1) {
1520 txcnt = sGetTxCnt(cp);
1521 if (!txcnt) {
1522 if (sGetChanStatusLo(cp) & TXSHRMT)
1523 break;
1524 check_time = (HZ / info->cps) / 5;
1525 } else {
1526 check_time = HZ * txcnt / info->cps;
1527 }
1528 if (timeout) {
1529 exit_time = orig_jiffies + timeout - jiffies;
1530 if (exit_time <= 0)
1531 break;
1532 if (exit_time < check_time)
1533 check_time = exit_time;
1534 }
1535 if (check_time == 0)
1536 check_time = 1;
1537#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1538 printk(KERN_INFO "txcnt = %d (jiff=%lu,check=%d)...", txcnt, jiffies, check_time);
1539#endif
1540 msleep_interruptible(jiffies_to_msecs(check_time));
1541 if (signal_pending(current))
1542 break;
1543 }
1544 current->state = TASK_RUNNING;
1545#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1546 printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
1547#endif
1548}
1549
1550/*
1551 * rp_hangup() --- called by tty_hangup() when a hangup is signaled.
1552 */
1553static void rp_hangup(struct tty_struct *tty)
1554{
1555 CHANNEL_t *cp;
1556 struct r_port *info = (struct r_port *) tty->driver_data;
1557
1558 if (rocket_paranoia_check(info, "rp_hangup"))
1559 return;
1560
1561#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_HANGUP))
1562 printk(KERN_INFO "rp_hangup of ttyR%d...", info->line);
1563#endif
1564 rp_flush_buffer(tty);
1565 if (info->flags & ROCKET_CLOSING)
1566 return;
1567 if (info->count)
1568 atomic_dec(&rp_num_ports_open);
1569 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1570
1571 info->count = 0;
1572 info->flags &= ~ROCKET_NORMAL_ACTIVE;
1573 info->tty = NULL;
1574
1575 cp = &info->channel;
1576 sDisRxFIFO(cp);
1577 sDisTransmit(cp);
1578 sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
1579 sDisCTSFlowCtl(cp);
1580 sDisTxSoftFlowCtl(cp);
1581 sClrTxXOFF(cp);
1582 info->flags &= ~ROCKET_INITIALIZED;
1583
1584 wake_up_interruptible(&info->open_wait);
1585}
1586
1587/*
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
1593 */
1594static void rp_put_char(struct tty_struct *tty, unsigned char ch)
1595{
1596 struct r_port *info = (struct r_port *) tty->driver_data;
1597 CHANNEL_t *cp;
1598 unsigned long flags;
1599
1600 if (rocket_paranoia_check(info, "rp_put_char"))
1601 return;
1602
1603 /* Grab the port write semaphore, locking out other processes that try to write to this port */
1604 down(&info->write_sem);
1605
1606#ifdef ROCKET_DEBUG_WRITE
1607 printk(KERN_INFO "rp_put_char %c...", ch);
1608#endif
1609
1610 spin_lock_irqsave(&info->slock, flags);
1611 cp = &info->channel;
1612
1613 if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room == 0)
1614 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
1615
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;
1619 info->xmit_cnt++;
1620 set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1621 } else {
1622 sOutB(sGetTxRxDataIO(cp), ch);
1623 info->xmit_fifo_room--;
1624 }
1625 spin_unlock_irqrestore(&info->slock, flags);
1626 up(&info->write_sem);
1627}
1628
1629/*
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.
1635 */
1636static int rp_write(struct tty_struct *tty,
1637 const unsigned char *buf, int count)
1638{
1639 struct r_port *info = (struct r_port *) tty->driver_data;
1640 CHANNEL_t *cp;
1641 const unsigned char *b;
1642 int c, retval = 0;
1643 unsigned long flags;
1644
1645 if (count <= 0 || rocket_paranoia_check(info, "rp_write"))
1646 return 0;
1647
1648 down_interruptible(&info->write_sem);
1649
1650#ifdef ROCKET_DEBUG_WRITE
1651 printk(KERN_INFO "rp_write %d chars...", count);
1652#endif
1653 cp = &info->channel;
1654
1655 if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room < count)
1656 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
1657
1658 /*
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.
1661 */
1662 if (!tty->stopped && !tty->hw_stopped && info->xmit_cnt == 0 && info->xmit_fifo_room > 0) {
1663 c = min(count, info->xmit_fifo_room);
1664 b = buf;
1665
1666 /* Push data into FIFO, 2 bytes at a time */
1667 sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) b, c / 2);
1668
1669 /* If there is a byte remaining, write it */
1670 if (c & 1)
1671 sOutB(sGetTxRxDataIO(cp), b[c - 1]);
1672
1673 retval += c;
1674 buf += c;
1675 count -= c;
1676
1677 spin_lock_irqsave(&info->slock, flags);
1678 info->xmit_fifo_room -= c;
1679 spin_unlock_irqrestore(&info->slock, flags);
1680 }
1681
1682 /* If count is zero, we wrote it all and are done */
1683 if (!count)
1684 goto end;
1685
1686 /* Write remaining data into the port's xmit_buf */
1687 while (1) {
1688 if (info->tty == 0) /* Seemingly obligatory check... */
1689 goto end;
1690
1691 c = min(count, min(XMIT_BUF_SIZE - info->xmit_cnt - 1, XMIT_BUF_SIZE - info->xmit_head));
1692 if (c <= 0)
1693 break;
1694
1695 b = buf;
1696 memcpy(info->xmit_buf + info->xmit_head, b, c);
1697
1698 spin_lock_irqsave(&info->slock, flags);
1699 info->xmit_head =
1700 (info->xmit_head + c) & (XMIT_BUF_SIZE - 1);
1701 info->xmit_cnt += c;
1702 spin_unlock_irqrestore(&info->slock, flags);
1703
1704 buf += c;
1705 count -= c;
1706 retval += c;
1707 }
1708
1709 if ((retval > 0) && !tty->stopped && !tty->hw_stopped)
1710 set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1711
1712end:
1713 if (info->xmit_cnt < WAKEUP_CHARS) {
1714 tty_wakeup(tty);
1715 wake_up_interruptible(&tty->write_wait);
1716#ifdef ROCKETPORT_HAVE_POLL_WAIT
1717 wake_up_interruptible(&tty->poll_wait);
1718#endif
1719 }
1720 up(&info->write_sem);
1721 return retval;
1722}
1723
1724/*
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.
1728 */
1729static int rp_write_room(struct tty_struct *tty)
1730{
1731 struct r_port *info = (struct r_port *) tty->driver_data;
1732 int ret;
1733
1734 if (rocket_paranoia_check(info, "rp_write_room"))
1735 return 0;
1736
1737 ret = XMIT_BUF_SIZE - info->xmit_cnt - 1;
1738 if (ret < 0)
1739 ret = 0;
1740#ifdef ROCKET_DEBUG_WRITE
1741 printk(KERN_INFO "rp_write_room returns %d...", ret);
1742#endif
1743 return ret;
1744}
1745
1746/*
1747 * Return the number of characters in the buffer. Again, this only
1748 * counts those characters in the in-memory transmit buffer.
1749 */
1750static int rp_chars_in_buffer(struct tty_struct *tty)
1751{
1752 struct r_port *info = (struct r_port *) tty->driver_data;
1753 CHANNEL_t *cp;
1754
1755 if (rocket_paranoia_check(info, "rp_chars_in_buffer"))
1756 return 0;
1757
1758 cp = &info->channel;
1759
1760#ifdef ROCKET_DEBUG_WRITE
1761 printk(KERN_INFO "rp_chars_in_buffer returns %d...", info->xmit_cnt);
1762#endif
1763 return info->xmit_cnt;
1764}
1765
1766/*
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.
1770 */
1771static void rp_flush_buffer(struct tty_struct *tty)
1772{
1773 struct r_port *info = (struct r_port *) tty->driver_data;
1774 CHANNEL_t *cp;
1775 unsigned long flags;
1776
1777 if (rocket_paranoia_check(info, "rp_flush_buffer"))
1778 return;
1779
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);
1783
1784 wake_up_interruptible(&tty->write_wait);
1785#ifdef ROCKETPORT_HAVE_POLL_WAIT
1786 wake_up_interruptible(&tty->poll_wait);
1787#endif
1788 tty_wakeup(tty);
1789
1790 cp = &info->channel;
1791 sFlushTxFIFO(cp);
1792}
1793
1794#ifdef CONFIG_PCI
1795
1796/*
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)
1800 */
1801__init int register_PCI(int i, struct pci_dev *dev)
1802{
1803 int num_aiops, aiop, max_num_aiops, num_chan, chan;
1804 unsigned int aiopio[MAX_AIOPS_PER_BOARD];
1805 char *str, *board_type;
1806 CONTROLLER_t *ctlp;
1807
1808 int fast_clock = 0;
1809 int altChanRingIndicator = 0;
1810 int ports_per_aiop = 8;
1811 int ret;
1812 unsigned int class_rev;
1813 WordIO_t ConfigIO = 0;
1814 ByteIO_t UPCIRingInd = 0;
1815
1816 if (!dev || pci_enable_device(dev))
1817 return 0;
1818
1819 rcktpt_io_addr[i] = pci_resource_start(dev, 0);
1820 ret = pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
1821
1822 if (ret) {
1823 printk(KERN_INFO " Error during register_PCI(), unable to read config dword \n");
1824 return 0;
1825 }
1826
1827 rcktpt_type[i] = ROCKET_TYPE_NORMAL;
1828 rocketModel[i].loadrm2 = 0;
1829 rocketModel[i].startingPortNumber = nextLineNumber;
1830
1831 /* Depending on the model, set up some config variables */
1832 switch (dev->device) {
1833 case PCI_DEVICE_ID_RP4QUAD:
1834 str = "Quadcable";
1835 max_num_aiops = 1;
1836 ports_per_aiop = 4;
1837 rocketModel[i].model = MODEL_RP4QUAD;
1838 strcpy(rocketModel[i].modelString, "RocketPort 4 port w/quad cable");
1839 rocketModel[i].numPorts = 4;
1840 break;
1841 case PCI_DEVICE_ID_RP8OCTA:
1842 str = "Octacable";
1843 max_num_aiops = 1;
1844 rocketModel[i].model = MODEL_RP8OCTA;
1845 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/octa cable");
1846 rocketModel[i].numPorts = 8;
1847 break;
1848 case PCI_DEVICE_ID_URP8OCTA:
1849 str = "Octacable";
1850 max_num_aiops = 1;
1851 rocketModel[i].model = MODEL_UPCI_RP8OCTA;
1852 strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/octa cable");
1853 rocketModel[i].numPorts = 8;
1854 break;
1855 case PCI_DEVICE_ID_RP8INTF:
1856 str = "8";
1857 max_num_aiops = 1;
1858 rocketModel[i].model = MODEL_RP8INTF;
1859 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/external I/F");
1860 rocketModel[i].numPorts = 8;
1861 break;
1862 case PCI_DEVICE_ID_URP8INTF:
1863 str = "8";
1864 max_num_aiops = 1;
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;
1868 break;
1869 case PCI_DEVICE_ID_RP8J:
1870 str = "8J";
1871 max_num_aiops = 1;
1872 rocketModel[i].model = MODEL_RP8J;
1873 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/RJ11 connectors");
1874 rocketModel[i].numPorts = 8;
1875 break;
1876 case PCI_DEVICE_ID_RP4J:
1877 str = "4J";
1878 max_num_aiops = 1;
1879 ports_per_aiop = 4;
1880 rocketModel[i].model = MODEL_RP4J;
1881 strcpy(rocketModel[i].modelString, "RocketPort 4 port w/RJ45 connectors");
1882 rocketModel[i].numPorts = 4;
1883 break;
1884 case PCI_DEVICE_ID_RP8SNI:
1885 str = "8 (DB78 Custom)";
1886 max_num_aiops = 1;
1887 rocketModel[i].model = MODEL_RP8SNI;
1888 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/ custom DB78");
1889 rocketModel[i].numPorts = 8;
1890 break;
1891 case PCI_DEVICE_ID_RP16SNI:
1892 str = "16 (DB78 Custom)";
1893 max_num_aiops = 2;
1894 rocketModel[i].model = MODEL_RP16SNI;
1895 strcpy(rocketModel[i].modelString, "RocketPort 16 port w/ custom DB78");
1896 rocketModel[i].numPorts = 16;
1897 break;
1898 case PCI_DEVICE_ID_RP16INTF:
1899 str = "16";
1900 max_num_aiops = 2;
1901 rocketModel[i].model = MODEL_RP16INTF;
1902 strcpy(rocketModel[i].modelString, "RocketPort 16 port w/external I/F");
1903 rocketModel[i].numPorts = 16;
1904 break;
1905 case PCI_DEVICE_ID_URP16INTF:
1906 str = "16";
1907 max_num_aiops = 2;
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;
1911 break;
1912 case PCI_DEVICE_ID_CRP16INTF:
1913 str = "16";
1914 max_num_aiops = 2;
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;
1918 break;
1919 case PCI_DEVICE_ID_RP32INTF:
1920 str = "32";
1921 max_num_aiops = 4;
1922 rocketModel[i].model = MODEL_RP32INTF;
1923 strcpy(rocketModel[i].modelString, "RocketPort 32 port w/external I/F");
1924 rocketModel[i].numPorts = 32;
1925 break;
1926 case PCI_DEVICE_ID_URP32INTF:
1927 str = "32";
1928 max_num_aiops = 4;
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;
1932 break;
1933 case PCI_DEVICE_ID_RPP4:
1934 str = "Plus Quadcable";
1935 max_num_aiops = 1;
1936 ports_per_aiop = 4;
1937 altChanRingIndicator++;
1938 fast_clock++;
1939 rocketModel[i].model = MODEL_RPP4;
1940 strcpy(rocketModel[i].modelString, "RocketPort Plus 4 port");
1941 rocketModel[i].numPorts = 4;
1942 break;
1943 case PCI_DEVICE_ID_RPP8:
1944 str = "Plus Octacable";
1945 max_num_aiops = 2;
1946 ports_per_aiop = 4;
1947 altChanRingIndicator++;
1948 fast_clock++;
1949 rocketModel[i].model = MODEL_RPP8;
1950 strcpy(rocketModel[i].modelString, "RocketPort Plus 8 port");
1951 rocketModel[i].numPorts = 8;
1952 break;
1953 case PCI_DEVICE_ID_RP2_232:
1954 str = "Plus 2 (RS-232)";
1955 max_num_aiops = 1;
1956 ports_per_aiop = 2;
1957 altChanRingIndicator++;
1958 fast_clock++;
1959 rocketModel[i].model = MODEL_RP2_232;
1960 strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS232");
1961 rocketModel[i].numPorts = 2;
1962 break;
1963 case PCI_DEVICE_ID_RP2_422:
1964 str = "Plus 2 (RS-422)";
1965 max_num_aiops = 1;
1966 ports_per_aiop = 2;
1967 altChanRingIndicator++;
1968 fast_clock++;
1969 rocketModel[i].model = MODEL_RP2_422;
1970 strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS422");
1971 rocketModel[i].numPorts = 2;
1972 break;
1973 case PCI_DEVICE_ID_RP6M:
1974
1975 max_num_aiops = 1;
1976 ports_per_aiop = 6;
1977 str = "6-port";
1978
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;
1983 } else {
1984 rcktpt_type[i] = ROCKET_TYPE_MODEM;
1985 }
1986
1987 rocketModel[i].model = MODEL_RP6M;
1988 strcpy(rocketModel[i].modelString, "RocketModem 6 port");
1989 rocketModel[i].numPorts = 6;
1990 break;
1991 case PCI_DEVICE_ID_RP4M:
1992 max_num_aiops = 1;
1993 ports_per_aiop = 4;
1994 str = "4-port";
1995 if ((class_rev & 0xFF) == 1) {
1996 rcktpt_type[i] = ROCKET_TYPE_MODEMII;
1997 rocketModel[i].loadrm2 = 1;
1998 } else {
1999 rcktpt_type[i] = ROCKET_TYPE_MODEM;
2000 }
2001
2002 rocketModel[i].model = MODEL_RP4M;
2003 strcpy(rocketModel[i].modelString, "RocketModem 4 port");
2004 rocketModel[i].numPorts = 4;
2005 break;
2006 default:
2007 str = "(unknown/unsupported)";
2008 max_num_aiops = 0;
2009 break;
2010 }
2011
2012 /*
2013 * Check for UPCI boards.
2014 */
2015
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;
2026
2027 /*
2028 * Check for octa or quad cable.
2029 */
2030 if (!
2031 (sInW(ConfigIO + _PCI_9030_GPIO_CTRL) &
2032 PCI_GPIO_CTRL_8PORT)) {
2033 str = "Quadcable";
2034 ports_per_aiop = 4;
2035 rocketModel[i].numPorts = 4;
2036 }
2037 }
2038 break;
2039 case PCI_DEVICE_ID_UPCI_RM3_8PORT:
2040 str = "8 ports";
2041 max_num_aiops = 1;
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;
2049 break;
2050 case PCI_DEVICE_ID_UPCI_RM3_4PORT:
2051 str = "4 ports";
2052 max_num_aiops = 1;
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;
2060 break;
2061 default:
2062 break;
2063 }
2064
2065 switch (rcktpt_type[i]) {
2066 case ROCKET_TYPE_MODEM:
2067 board_type = "RocketModem";
2068 break;
2069 case ROCKET_TYPE_MODEMII:
2070 board_type = "RocketModem II";
2071 break;
2072 case ROCKET_TYPE_MODEMIII:
2073 board_type = "RocketModem III";
2074 break;
2075 default:
2076 board_type = "RocketPort";
2077 break;
2078 }
2079
2080 if (fast_clock) {
2081 sClockPrescale = 0x12; /* mod 2 (divide by 3) */
2082 rp_baud_base[i] = 921600;
2083 } else {
2084 /*
2085 * If support_low_speed is set, use the slow clock
2086 * prescale, which supports 50 bps
2087 */
2088 if (support_low_speed) {
2089 /* mod 9 (divide by 10) prescale */
2090 sClockPrescale = 0x19;
2091 rp_baud_base[i] = 230400;
2092 } else {
2093 /* mod 4 (devide by 5) prescale */
2094 sClockPrescale = 0x14;
2095 rp_baud_base[i] = 460800;
2096 }
2097 }
2098
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;
2105
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);
2114
2115 if (num_aiops <= 0) {
2116 rcktpt_io_addr[i] = 0;
2117 return (0);
2118 }
2119 is_PCI[i] = 1;
2120
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);
2127 }
2128
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);
2136 mdelay(500);
2137 for (chan = 0; chan < num_chan; chan++)
2138 sPCIModemReset(ctlp, chan, 0);
2139 mdelay(500);
2140 rmSpeakerReset(ctlp, rocketModel[i].model);
2141 }
2142 return (1);
2143}
2144
2145/*
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
2150 */
2151static int __init init_PCI(int boards_found)
2152{
2153 struct pci_dev *dev = NULL;
2154 int count = 0;
2155
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))
2159 count++;
2160 }
2161 return (count);
2162}
2163
2164#endif /* CONFIG_PCI */
2165
2166/*
2167 * Probes for ISA cards
2168 * Input: i = the board number to look for
2169 * Returns: 1 if board found, 0 else
2170 */
2171static int __init init_ISA(int i)
2172{
2173 int num_aiops, num_chan = 0, total_num_chan = 0;
2174 int aiop, chan;
2175 unsigned int aiopio[MAX_AIOPS_PER_BOARD];
2176 CONTROLLER_t *ctlp;
2177 char *type_string;
2178
2179 /* If io_addr is zero, no board configured */
2180 if (rcktpt_io_addr[i] == 0)
2181 return (0);
2182
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;
2187 return (0);
2188 }
2189
2190 ctlp = sCtlNumToCtlPtr(i);
2191
2192 ctlp->boardType = rcktpt_type[i];
2193
2194 switch (rcktpt_type[i]) {
2195 case ROCKET_TYPE_PC104:
2196 type_string = "(PC104)";
2197 break;
2198 case ROCKET_TYPE_MODEM:
2199 type_string = "(RocketModem)";
2200 break;
2201 case ROCKET_TYPE_MODEMII:
2202 type_string = "(RocketModem II)";
2203 break;
2204 default:
2205 type_string = "";
2206 break;
2207 }
2208
2209 /*
2210 * If support_low_speed is set, use the slow clock prescale,
2211 * which supports 50 bps
2212 */
2213 if (support_low_speed) {
2214 sClockPrescale = 0x19; /* mod 9 (divide by 10) prescale */
2215 rp_baud_base[i] = 230400;
2216 } else {
2217 sClockPrescale = 0x14; /* mod 4 (devide by 5) prescale */
2218 rp_baud_base[i] = 460800;
2219 }
2220
2221 for (aiop = 0; aiop < MAX_AIOPS_PER_BOARD; aiop++)
2222 aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x400);
2223
2224 num_aiops = sInitController(ctlp, i, controller + (i * 0x400), aiopio, MAX_AIOPS_PER_BOARD, 0, FREQ_DIS, 0);
2225
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 */
2229 }
2230
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;
2235 return (0);
2236 }
2237
2238 rocketModel[i].startingPortNumber = nextLineNumber;
2239
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);
2247 }
2248 is_PCI[i] = 0;
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);
2254 mdelay(500);
2255 for (chan = 0; chan < num_chan; chan++)
2256 sModemReset(ctlp, chan, 0);
2257 mdelay(500);
2258 strcpy(rocketModel[i].modelString, "RocketModem ISA");
2259 } else {
2260 strcpy(rocketModel[i].modelString, "RocketPort ISA");
2261 }
2262 rocketModel[i].numPorts = total_num_chan;
2263 rocketModel[i].model = MODEL_ISA;
2264
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);
2267
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);
2273
2274 return (1);
2275}
2276
2277static struct tty_operations rocket_ops = {
2278 .open = rp_open,
2279 .close = rp_close,
2280 .write = rp_write,
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,
2285 .ioctl = rp_ioctl,
2286 .throttle = rp_throttle,
2287 .unthrottle = rp_unthrottle,
2288 .set_termios = rp_set_termios,
2289 .stop = rp_stop,
2290 .start = rp_start,
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,
2297};
2298
2299/*
2300 * The module "startup" routine; it's run when the module is loaded.
2301 */
2302int __init rp_init(void)
2303{
2304 int retval, pci_boards_found, isa_boards_found, i;
2305
2306 printk(KERN_INFO "RocketPort device driver module, version %s, %s\n",
2307 ROCKET_VERSION, ROCKET_DATE);
2308
2309 rocket_driver = alloc_tty_driver(MAX_RP_PORTS);
2310 if (!rocket_driver)
2311 return -ENOMEM;
2312
2313 /*
2314 * Set up the timer channel.
2315 */
2316 init_timer(&rocket_timer);
2317 rocket_timer.function = rp_do_poll;
2318
2319 /*
2320 * Initialize the array of pointers to our own internal state
2321 * structures.
2322 */
2323 memset(rp_table, 0, sizeof (rp_table));
2324 memset(xmit_flags, 0, sizeof (xmit_flags));
2325
2326 for (i = 0; i < MAX_RP_PORTS; i++)
2327 lineNumbers[i] = 0;
2328 nextLineNumber = 0;
2329 memset(rocketModel, 0, sizeof (rocketModel));
2330
2331 /*
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.
2334 */
2335 if (board1) {
2336 if (controller == 0)
2337 controller = board1 + 0x40;
2338 } else {
2339 controller = 0; /* Used as a flag, meaning no ISA boards */
2340 }
2341
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);
2345 return -EBUSY;
2346 }
2347
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;
2353
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];
2362
2363 /*
2364 * Set up the tty driver structure and then register this
2365 * driver with the tty layer.
2366 */
2367
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;
2382#endif
2383 tty_set_operations(rocket_driver, &rocket_ops);
2384
2385 retval = tty_register_driver(rocket_driver);
2386 if (retval < 0) {
2387 printk(KERN_INFO "Couldn't install tty RocketPort driver (error %d)\n", -retval);
2388 put_tty_driver(rocket_driver);
2389 return -1;
2390 }
2391
2392#ifdef ROCKET_DEBUG_OPEN
2393 printk(KERN_INFO "RocketPort driver is major %d\n", rocket_driver.major);
2394#endif
2395
2396 /*
2397 * OK, let's probe each of the controllers looking for boards. Any boards found
2398 * will be initialized here.
2399 */
2400 isa_boards_found = 0;
2401 pci_boards_found = 0;
2402
2403 for (i = 0; i < NUM_BOARDS; i++) {
2404 if (init_ISA(i))
2405 isa_boards_found++;
2406 }
2407
2408#ifdef CONFIG_PCI
2409 if (isa_boards_found < NUM_BOARDS)
2410 pci_boards_found = init_PCI(isa_boards_found);
2411#endif
2412
2413 max_board = pci_boards_found + isa_boards_found;
2414
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);
2420 return -ENXIO;
2421 }
2422
2423 return 0;
2424}
2425
2426#ifdef MODULE
2427
2428static void rp_cleanup_module(void)
2429{
2430 int retval;
2431 int i;
2432
2433 del_timer_sync(&rocket_timer);
2434
2435 retval = tty_unregister_driver(rocket_driver);
2436 if (retval)
2437 printk(KERN_INFO "Error %d while trying to unregister "
2438 "rocketport driver\n", -retval);
2439 put_tty_driver(rocket_driver);
2440
2441 for (i = 0; i < MAX_RP_PORTS; i++) {
2442 if (rp_table[i])
2443 kfree(rp_table[i]);
2444 }
2445
2446 for (i = 0; i < NUM_BOARDS; i++) {
2447 if (rcktpt_io_addr[i] <= 0 || is_PCI[i])
2448 continue;
2449 release_region(rcktpt_io_addr[i], 64);
2450 }
2451 if (controller)
2452 release_region(controller, 4);
2453}
2454#endif
2455
2456#ifndef TRUE
2457#define TRUE 1
2458#endif
2459
2460#ifndef FALSE
2461#define FALSE 0
2462#endif
2463
2464static 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
2483};
2484
2485static 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 */
2499};
2500
2501CONTROLLER_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}}
2510};
2511
2512Byte_t sBitMapClrTbl[8] = {
2513 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
2514};
2515
2516Byte_t sBitMapSetTbl[8] = {
2517 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
2518};
2519
2520int sClockPrescale = 0x14;
2521
2522/***************************************************************************
2523Function: sInitController
2524Purpose: Initialization of controller global registers and controller
2525 structure.
2526Call: 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
2538 3: IRQ 3
2539 4: IRQ 4
2540 5: IRQ 5
2541 9: IRQ 9
2542 10: IRQ 10
2543 11: IRQ 11
2544 12: IRQ 12
2545 15: IRQ 15
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
2553 FREQ_9HZ - 9 Hertz
2554 FREQ_4HZ - 4 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.
2563Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
2564 initialization failed.
2565
2566Comments:
2567 If periodic interrupts are to be disabled but AIOP interrupts
2568 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.
2569
2570 If interrupts are to be completely disabled set IRQNum to 0.
2571
2572 Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
2573 invalid combination.
2574
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.
2580
2581 Even if interrupts are globally enabled, they must also be
2582 individually enabled for each channel that is to generate
2583 interrupts.
2584
2585Warnings: No range checking on any of the parameters is done.
2586
2587 No context switches are allowed while executing this function.
2588
2589 After this function all AIOPs on the controller are disabled,
2590 they can be enabled with sEnAiop().
2591*/
2592int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
2593 ByteIO_t * AiopIOList, int AiopIOListSize, int IRQNum,
2594 Byte_t Frequency, int PeriodicOnly)
2595{
2596 int i;
2597 ByteIO_t io;
2598 int done;
2599
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;
2609#if 1
2610 CtlP->MReg2 = 0; /* interrupt disable */
2611 CtlP->MReg3 = 0; /* no periodic interrupts */
2612#else
2613 if (sIRQMap[IRQNum] == 0) { /* interrupts globally disabled */
2614 CtlP->MReg2 = 0; /* interrupt disable */
2615 CtlP->MReg3 = 0; /* no periodic interrupts */
2616 } else {
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;
2621 }
2622 }
2623#endif
2624 sOutB(CtlP->MReg2IO, CtlP->MReg2);
2625 sOutB(CtlP->MReg3IO, CtlP->MReg3);
2626 sControllerEOI(CtlP); /* clear EOI if warm init */
2627 /* Init AIOPs */
2628 CtlP->NumAiop = 0;
2629 for (i = done = 0; i < AiopIOListSize; i++) {
2630 io = AiopIOList[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 */
2635 if (done)
2636 continue;
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 */
2641 else {
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 */
2646 }
2647 sDisAiop(CtlP, i); /* disable AIOP */
2648 }
2649
2650 if (CtlP->NumAiop == 0)
2651 return (-1);
2652 else
2653 return (CtlP->NumAiop);
2654}
2655
2656/***************************************************************************
2657Function: sPCIInitController
2658Purpose: Initialization of controller global registers and controller
2659 structure.
2660Call: 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
2671 3: IRQ 3
2672 4: IRQ 4
2673 5: IRQ 5
2674 9: IRQ 9
2675 10: IRQ 10
2676 11: IRQ 11
2677 12: IRQ 12
2678 15: IRQ 15
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
2686 FREQ_9HZ - 9 Hertz
2687 FREQ_4HZ - 4 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.
2696Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
2697 initialization failed.
2698
2699Comments:
2700 If periodic interrupts are to be disabled but AIOP interrupts
2701 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.
2702
2703 If interrupts are to be completely disabled set IRQNum to 0.
2704
2705 Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
2706 invalid combination.
2707
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.
2713
2714 Even if interrupts are globally enabled, they must also be
2715 individually enabled for each channel that is to generate
2716 interrupts.
2717
2718Warnings: No range checking on any of the parameters is done.
2719
2720 No context switches are allowed while executing this function.
2721
2722 After this function all AIOPs on the controller are disabled,
2723 they can be enabled with sEnAiop().
2724*/
2725int 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,
2729 int UPCIRingInd)
2730{
2731 int i;
2732 ByteIO_t io;
2733
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 */
2739
2740 if (ConfigIO) {
2741 CtlP->isUPCI = 1;
2742 CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL;
2743 CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL;
2744 CtlP->AiopIntrBits = upci_aiop_intr_bits;
2745 } else {
2746 CtlP->isUPCI = 0;
2747 CtlP->PCIIO =
2748 (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC);
2749 CtlP->AiopIntrBits = aiop_intr_bits;
2750 }
2751
2752 sPCIControllerEOI(CtlP); /* clear EOI if warm init */
2753 /* Init AIOPs */
2754 CtlP->NumAiop = 0;
2755 for (i = 0; i < AiopIOListSize; i++) {
2756 io = AiopIOList[i];
2757 CtlP->AiopIO[i] = (WordIO_t) io;
2758 CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
2759
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 */
2763
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 */
2768 }
2769
2770 if (CtlP->NumAiop == 0)
2771 return (-1);
2772 else
2773 return (CtlP->NumAiop);
2774}
2775
2776/***************************************************************************
2777Function: sReadAiopID
2778Purpose: Read the AIOP idenfication number directly from an AIOP.
2779Call: sReadAiopID(io)
2780 ByteIO_t io: AIOP base I/O address
2781Return: 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
2784Warnings: No context switches are allowed while executing this function.
2785
2786*/
2787int sReadAiopID(ByteIO_t io)
2788{
2789 Byte_t AiopID; /* ID byte from AIOP */
2790
2791 sOutB(io + _CMD_REG, RESET_ALL); /* reset AIOP */
2792 sOutB(io + _CMD_REG, 0x0);
2793 AiopID = sInW(io + _CHN_STAT0) & 0x07;
2794 if (AiopID == 0x06)
2795 return (1);
2796 else /* AIOP does not exist */
2797 return (-1);
2798}
2799
2800/***************************************************************************
2801Function: sReadAiopNumChan
2802Purpose: Read the number of channels available in an AIOP directly from
2803 an AIOP.
2804Call: sReadAiopNumChan(io)
2805 WordIO_t io: AIOP base I/O address
2806Return: int: The number of channels available
2807Comments: 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.
2811Warnings: No context switches are allowed while executing this function.
2812*/
2813int sReadAiopNumChan(WordIO_t io)
2814{
2815 Word_t x;
2816 static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 };
2817
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 */
2824 return (8);
2825 else
2826 return (4);
2827}
2828
2829/***************************************************************************
2830Function: sInitChan
2831Purpose: Initialization of a channel and channel structure
2832Call: 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
2837Return: int: TRUE if initialization succeeded, FALSE if it fails because channel
2838 number exceeds number of channels available in AIOP.
2839Comments: This function must be called before a channel can be used.
2840Warnings: No range checking on any of the parameters is done.
2841
2842 No context switches are allowed while executing this function.
2843*/
2844int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
2845 int ChanNum)
2846{
2847 int i;
2848 WordIO_t AiopIO;
2849 WordIO_t ChIOOff;
2850 Byte_t *ChR;
2851 Word_t ChOff;
2852 static Byte_t R[4];
2853 int brd9600;
2854
2855 if (ChanNum >= CtlP->AiopNumChan[AiopNum])
2856 return (FALSE); /* exceeds num chans in AIOP */
2857
2858 /* Channel, AIOP, and controller identifiers */
2859 ChP->CtlP = CtlP;
2860 ChP->ChanID = CtlP->AiopID[AiopNum];
2861 ChP->AiopNum = AiopNum;
2862 ChP->ChanNum = ChanNum;
2863
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;
2871
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;
2878
2879 /* Initialize the channel from the RData array */
2880 for (i = 0; i < RDATASIZE; i += 4) {
2881 R[0] = RData[i];
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]));
2886 }
2887
2888 ChR = ChP->R;
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];
2894 }
2895
2896 /* Indexed registers */
2897 ChOff = (Word_t) ChanNum *0x1000;
2898
2899 if (sClockPrescale == 0x14)
2900 brd9600 = 47;
2901 else
2902 brd9600 = 23;
2903
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]);
2909
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]);
2915
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]);
2921
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]);
2927
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]);
2933
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]);
2939
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]);
2945
2946 ChP->TxFIFOPtrs = ChOff + _TXF_OUTP;
2947 ChP->TxFIFO = ChOff + _TX_FIFO;
2948
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;
2955
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 */
2970
2971 return (TRUE);
2972}
2973
2974/***************************************************************************
2975Function: sStopRxProcessor
2976Purpose: Stop the receive processor from processing a channel.
2977Call: sStopRxProcessor(ChP)
2978 CHANNEL_T *ChP; Ptr to channel structure
2979
2980Comments: 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.
2983
2984Warnings: No context switches are allowed while executing this function.
2985
2986 Do not leave the receive processor stopped for more than one
2987 character time.
2988
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.
2991*/
2992void sStopRxProcessor(CHANNEL_T * ChP)
2993{
2994 Byte_t R[4];
2995
2996 R[0] = ChP->R[0];
2997 R[1] = ChP->R[1];
2998 R[2] = 0x0a;
2999 R[3] = ChP->R[3];
3000 sOutDW(ChP->IndexAddr, *(DWord_t *) & R[0]);
3001}
3002
3003/***************************************************************************
3004Function: sFlushRxFIFO
3005Purpose: Flush the Rx FIFO
3006Call: sFlushRxFIFO(ChP)
3007 CHANNEL_T *ChP; Ptr to channel structure
3008Return: void
3009Comments: 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
3014 this function.
3015Warnings: No context switches are allowed while executing this function.
3016*/
3017void sFlushRxFIFO(CHANNEL_T * ChP)
3018{
3019 int i;
3020 Byte_t Ch; /* channel number within AIOP */
3021 int RxFIFOEnabled; /* TRUE if Rx FIFO enabled */
3022
3023 if (sGetRxCnt(ChP) == 0) /* Rx FIFO empty */
3024 return; /* don't need to flush */
3025
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 */
3032 }
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);
3041 if (RxFIFOEnabled)
3042 sEnRxFIFO(ChP); /* enable Rx FIFO */
3043}
3044
3045/***************************************************************************
3046Function: sFlushTxFIFO
3047Purpose: Flush the Tx FIFO
3048Call: sFlushTxFIFO(ChP)
3049 CHANNEL_T *ChP; Ptr to channel structure
3050Return: void
3051Comments: 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
3056 this function.
3057Warnings: No context switches are allowed while executing this function.
3058*/
3059void sFlushTxFIFO(CHANNEL_T * ChP)
3060{
3061 int i;
3062 Byte_t Ch; /* channel number within AIOP */
3063 int TxEnabled; /* TRUE if transmitter enabled */
3064
3065 if (sGetTxCnt(ChP) == 0) /* Tx FIFO empty */
3066 return; /* don't need to flush */
3067
3068 TxEnabled = FALSE;
3069 if (ChP->TxControl[3] & TX_ENABLE) {
3070 TxEnabled = TRUE;
3071 sDisTransmit(ChP); /* disable transmitter */
3072 }
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);
3081 if (TxEnabled)
3082 sEnTransmit(ChP); /* enable transmitter */
3083 sStartRxProcessor(ChP); /* restart Rx processor */
3084}
3085
3086/***************************************************************************
3087Function: sWriteTxPrioByte
3088Purpose: Write a byte of priority transmit data to a channel
3089Call: sWriteTxPrioByte(ChP,Data)
3090 CHANNEL_T *ChP; Ptr to channel structure
3091 Byte_t Data; The transmit data byte
3092
3093Return: int: 1 if the bytes is successfully written, otherwise 0.
3094
3095Comments: The priority byte is transmitted before any data in the Tx FIFO.
3096
3097Warnings: No context switches are allowed while executing this function.
3098*/
3099int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
3100{
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;
3104
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 */
3110
3111 WordPtr = (Word_t *) (&DWBuf[0]);
3112 *WordPtr = ChP->TxPrioBuf; /* data byte address */
3113
3114 DWBuf[2] = Data; /* data byte value */
3115 sOutDW(IndexAddr, *((DWord_t *) (&DWBuf[0]))); /* write it out */
3116
3117 *WordPtr = ChP->TxPrioCnt; /* Tx priority count address */
3118
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 */
3123
3124 sWriteTxByte(sGetTxRxDataIO(ChP), Data);
3125 }
3126 return (1); /* 1 byte sent */
3127}
3128
3129/***************************************************************************
3130Function: sEnInterrupts
3131Purpose: Enable one or more interrupts for a channel
3132Call: 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
3138 sSetRxTrigger())
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.
3143Return: void
3144Comments: 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().
3148
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.
3152
3153 Interrupts must also be globally enabled before channel interrupts
3154 will be passed on to the host. This is done with function
3155 sEnGlobalInt().
3156
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.
3160*/
3161void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
3162{
3163 Byte_t Mask; /* Interrupt Mask Register */
3164
3165 ChP->RxControl[2] |=
3166 ((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
3167
3168 sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->RxControl[0]);
3169
3170 ChP->TxControl[2] |= ((Byte_t) Flags & TXINT_EN);
3171
3172 sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxControl[0]);
3173
3174 if (Flags & CHANINT_EN) {
3175 Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum];
3176 sOutB(ChP->IntMask, Mask);
3177 }
3178}
3179
3180/***************************************************************************
3181Function: sDisInterrupts
3182Purpose: Disable one or more interrupts for a channel
3183Call: 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
3189 sSetRxTrigger())
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.
3194Return: void
3195Comments: 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().
3199
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
3203 Register.
3204*/
3205void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
3206{
3207 Byte_t Mask; /* Interrupt Mask Register */
3208
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]);
3214
3215 if (Flags & CHANINT_EN) {
3216 Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum];
3217 sOutB(ChP->IntMask, Mask);
3218 }
3219}
3220
3221void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
3222{
3223 sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum);
3224}
3225
3226/*
3227 * Not an official SSCI function, but how to reset RocketModems.
3228 * ISA bus version
3229 */
3230void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
3231{
3232 ByteIO_t addr;
3233 Byte_t val;
3234
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));
3242 }
3243
3244 sEnAiop(CtlP, 1);
3245 if (!on)
3246 addr += 8;
3247 sOutB(addr + chan, 0); /* apply or remove reset */
3248 sDisAiop(CtlP, 1);
3249}
3250
3251/*
3252 * Not an official SSCI function, but how to reset RocketModems.
3253 * PCI bus version
3254 */
3255void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
3256{
3257 ByteIO_t addr;
3258
3259 addr = CtlP->AiopIO[0] + 0x40; /* 2nd AIOP */
3260 if (!on)
3261 addr += 8;
3262 sOutB(addr + chan, 0); /* apply or remove reset */
3263}
3264
3265/* Resets the speaker controller on RocketModem II and III devices */
3266static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model)
3267{
3268 ByteIO_t addr;
3269
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;
3273 sOutB(addr, 0);
3274 }
3275
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;
3280 sOutB(addr, 0);
3281 }
3282}
3283
3284/* Returns the line number given the controller (board), aiop and channel number */
3285static unsigned char GetLineNumber(int ctrl, int aiop, int ch)
3286{
3287 return lineNumbers[(ctrl << 5) | (aiop << 3) | ch];
3288}
3289
3290/*
3291 * Stores the line number associated with a given controller (board), aiop
3292 * and channel number.
3293 * Returns: The line number assigned
3294 */
3295static unsigned char SetLineNumber(int ctrl, int aiop, int ch)
3296{
3297 lineNumbers[(ctrl << 5) | (aiop << 3) | ch] = nextLineNumber++;
3298 return (nextLineNumber - 1);
3299}