1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43#define ROCKET_PARANOIA_CHECK
44#define ROCKET_DISABLE_SIMUSAGE
45
46#undef ROCKET_SOFT_FLOW
47#undef ROCKET_DEBUG_OPEN
48#undef ROCKET_DEBUG_INTR
49#undef ROCKET_DEBUG_WRITE
50#undef ROCKET_DEBUG_FLOW
51#undef ROCKET_DEBUG_THROTTLE
52#undef ROCKET_DEBUG_WAIT_UNTIL_SENT
53#undef ROCKET_DEBUG_RECEIVE
54#undef ROCKET_DEBUG_HANGUP
55#undef REV_PCI_ORDER
56#undef ROCKET_DEBUG_IO
57
58#define POLL_PERIOD HZ/100
59
60
61
62#include <linux/module.h>
63#include <linux/errno.h>
64#include <linux/major.h>
65#include <linux/kernel.h>
66#include <linux/signal.h>
67#include <linux/slab.h>
68#include <linux/mm.h>
69#include <linux/sched.h>
70#include <linux/timer.h>
71#include <linux/interrupt.h>
72#include <linux/tty.h>
73#include <linux/tty_driver.h>
74#include <linux/tty_flip.h>
75#include <linux/serial.h>
76#include <linux/smp_lock.h>
77#include <linux/string.h>
78#include <linux/fcntl.h>
79#include <linux/ptrace.h>
80#include <linux/mutex.h>
81#include <linux/ioport.h>
82#include <linux/delay.h>
83#include <linux/completion.h>
84#include <linux/wait.h>
85#include <linux/pci.h>
86#include <linux/uaccess.h>
87#include <asm/atomic.h>
88#include <asm/unaligned.h>
89#include <linux/bitops.h>
90#include <linux/spinlock.h>
91#include <linux/init.h>
92
93
94
95#include "rocket_int.h"
96#include "rocket.h"
97
98#define ROCKET_VERSION "2.09"
99#define ROCKET_DATE "12-June-2003"
100
101
102
103static void rp_do_poll(unsigned long dummy);
104
105static struct tty_driver *rocket_driver;
106
107static struct rocket_version driver_version = {
108 ROCKET_VERSION, ROCKET_DATE
109};
110
111static struct r_port *rp_table[MAX_RP_PORTS];
112static unsigned int xmit_flags[NUM_BOARDS];
113
114static atomic_t rp_num_ports_open;
115static DEFINE_TIMER(rocket_timer, rp_do_poll, 0, 0);
116
117static unsigned long board1;
118static unsigned long board2;
119static unsigned long board3;
120static unsigned long board4;
121static unsigned long controller;
122static int support_low_speed;
123static unsigned long modem1;
124static unsigned long modem2;
125static unsigned long modem3;
126static unsigned long modem4;
127static unsigned long pc104_1[8];
128static unsigned long pc104_2[8];
129static unsigned long pc104_3[8];
130static unsigned long pc104_4[8];
131static unsigned long *pc104[4] = { pc104_1, pc104_2, pc104_3, pc104_4 };
132
133static int rp_baud_base[NUM_BOARDS];
134static unsigned long rcktpt_io_addr[NUM_BOARDS];
135static int rcktpt_type[NUM_BOARDS];
136static int is_PCI[NUM_BOARDS];
137static rocketModel_t rocketModel[NUM_BOARDS];
138static int max_board;
139static const struct tty_port_operations rocket_port_ops;
140
141
142
143
144
145
146
147static Word_t aiop_intr_bits[AIOP_CTL_SIZE] = {
148 AIOP_INTR_BIT_0,
149 AIOP_INTR_BIT_1,
150 AIOP_INTR_BIT_2,
151 AIOP_INTR_BIT_3
152};
153
154static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = {
155 UPCI_AIOP_INTR_BIT_0,
156 UPCI_AIOP_INTR_BIT_1,
157 UPCI_AIOP_INTR_BIT_2,
158 UPCI_AIOP_INTR_BIT_3
159};
160
161static Byte_t RData[RDATASIZE] = {
162 0x00, 0x09, 0xf6, 0x82,
163 0x02, 0x09, 0x86, 0xfb,
164 0x04, 0x09, 0x00, 0x0a,
165 0x06, 0x09, 0x01, 0x0a,
166 0x08, 0x09, 0x8a, 0x13,
167 0x0a, 0x09, 0xc5, 0x11,
168 0x0c, 0x09, 0x86, 0x85,
169 0x0e, 0x09, 0x20, 0x0a,
170 0x10, 0x09, 0x21, 0x0a,
171 0x12, 0x09, 0x41, 0xff,
172 0x14, 0x09, 0x82, 0x00,
173 0x16, 0x09, 0x82, 0x7b,
174 0x18, 0x09, 0x8a, 0x7d,
175 0x1a, 0x09, 0x88, 0x81,
176 0x1c, 0x09, 0x86, 0x7a,
177 0x1e, 0x09, 0x84, 0x81,
178 0x20, 0x09, 0x82, 0x7c,
179 0x22, 0x09, 0x0a, 0x0a
180};
181
182static Byte_t RRegData[RREGDATASIZE] = {
183 0x00, 0x09, 0xf6, 0x82,
184 0x08, 0x09, 0x8a, 0x13,
185 0x0a, 0x09, 0xc5, 0x11,
186 0x0c, 0x09, 0x86, 0x85,
187 0x12, 0x09, 0x41, 0xff,
188 0x14, 0x09, 0x82, 0x00,
189 0x16, 0x09, 0x82, 0x7b,
190 0x18, 0x09, 0x8a, 0x7d,
191 0x1a, 0x09, 0x88, 0x81,
192 0x1c, 0x09, 0x86, 0x7a,
193 0x1e, 0x09, 0x84, 0x81,
194 0x20, 0x09, 0x82, 0x7c,
195 0x22, 0x09, 0x0a, 0x0a
196};
197
198static CONTROLLER_T sController[CTL_SIZE] = {
199 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
200 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
201 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
202 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
203 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
204 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
205 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
206 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
207};
208
209static Byte_t sBitMapClrTbl[8] = {
210 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
211};
212
213static Byte_t sBitMapSetTbl[8] = {
214 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
215};
216
217static int sClockPrescale = 0x14;
218
219
220
221
222
223
224static unsigned char lineNumbers[MAX_RP_PORTS];
225static unsigned long nextLineNumber;
226
227
228static int __init init_ISA(int i);
229static void rp_wait_until_sent(struct tty_struct *tty, int timeout);
230static void rp_flush_buffer(struct tty_struct *tty);
231static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model);
232static unsigned char GetLineNumber(int ctrl, int aiop, int ch);
233static unsigned char SetLineNumber(int ctrl, int aiop, int ch);
234static void rp_start(struct tty_struct *tty);
235static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
236 int ChanNum);
237static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
238static void sFlushRxFIFO(CHANNEL_T * ChP);
239static void sFlushTxFIFO(CHANNEL_T * ChP);
240static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
241static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
242static void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
243static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
244static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
245static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
246 ByteIO_t * AiopIOList, int AiopIOListSize,
247 WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
248 int PeriodicOnly, int altChanRingIndicator,
249 int UPCIRingInd);
250static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
251 ByteIO_t * AiopIOList, int AiopIOListSize,
252 int IRQNum, Byte_t Frequency, int PeriodicOnly);
253static int sReadAiopID(ByteIO_t io);
254static int sReadAiopNumChan(WordIO_t io);
255
256MODULE_AUTHOR("Theodore Ts'o");
257MODULE_DESCRIPTION("Comtrol RocketPort driver");
258module_param(board1, ulong, 0);
259MODULE_PARM_DESC(board1, "I/O port for (ISA) board #1");
260module_param(board2, ulong, 0);
261MODULE_PARM_DESC(board2, "I/O port for (ISA) board #2");
262module_param(board3, ulong, 0);
263MODULE_PARM_DESC(board3, "I/O port for (ISA) board #3");
264module_param(board4, ulong, 0);
265MODULE_PARM_DESC(board4, "I/O port for (ISA) board #4");
266module_param(controller, ulong, 0);
267MODULE_PARM_DESC(controller, "I/O port for (ISA) rocketport controller");
268module_param(support_low_speed, bool, 0);
269MODULE_PARM_DESC(support_low_speed, "1 means support 50 baud, 0 means support 460400 baud");
270module_param(modem1, ulong, 0);
271MODULE_PARM_DESC(modem1, "1 means (ISA) board #1 is a RocketModem");
272module_param(modem2, ulong, 0);
273MODULE_PARM_DESC(modem2, "1 means (ISA) board #2 is a RocketModem");
274module_param(modem3, ulong, 0);
275MODULE_PARM_DESC(modem3, "1 means (ISA) board #3 is a RocketModem");
276module_param(modem4, ulong, 0);
277MODULE_PARM_DESC(modem4, "1 means (ISA) board #4 is a RocketModem");
278module_param_array(pc104_1, ulong, NULL, 0);
279MODULE_PARM_DESC(pc104_1, "set interface types for ISA(PC104) board #1 (e.g. pc104_1=232,232,485,485,...");
280module_param_array(pc104_2, ulong, NULL, 0);
281MODULE_PARM_DESC(pc104_2, "set interface types for ISA(PC104) board #2 (e.g. pc104_2=232,232,485,485,...");
282module_param_array(pc104_3, ulong, NULL, 0);
283MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc104_3=232,232,485,485,...");
284module_param_array(pc104_4, ulong, NULL, 0);
285MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,...");
286
287static int rp_init(void);
288static void rp_cleanup_module(void);
289
290module_init(rp_init);
291module_exit(rp_cleanup_module);
292
293
294MODULE_LICENSE("Dual BSD/GPL");
295
296
297
298
299static inline int rocket_paranoia_check(struct r_port *info,
300 const char *routine)
301{
302#ifdef ROCKET_PARANOIA_CHECK
303 if (!info)
304 return 1;
305 if (info->magic != RPORT_MAGIC) {
306 printk(KERN_WARNING "Warning: bad magic number for rocketport "
307 "struct in %s\n", routine);
308 return 1;
309 }
310#endif
311 return 0;
312}
313
314
315
316
317
318
319static void rp_do_receive(struct r_port *info,
320 struct tty_struct *tty,
321 CHANNEL_t * cp, unsigned int ChanStatus)
322{
323 unsigned int CharNStat;
324 int ToRecv, wRecv, space;
325 unsigned char *cbuf;
326
327 ToRecv = sGetRxCnt(cp);
328#ifdef ROCKET_DEBUG_INTR
329 printk(KERN_INFO "rp_do_receive(%d)...\n", ToRecv);
330#endif
331 if (ToRecv == 0)
332 return;
333
334
335
336
337
338
339 if (ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) {
340 if (!(ChanStatus & STATMODE)) {
341#ifdef ROCKET_DEBUG_RECEIVE
342 printk(KERN_INFO "Entering STATMODE...\n");
343#endif
344 ChanStatus |= STATMODE;
345 sEnRxStatusMode(cp);
346 }
347 }
348
349
350
351
352
353
354 if (ChanStatus & STATMODE) {
355#ifdef ROCKET_DEBUG_RECEIVE
356 printk(KERN_INFO "Ignore %x, read %x...\n",
357 info->ignore_status_mask, info->read_status_mask);
358#endif
359 while (ToRecv) {
360 char flag;
361
362 CharNStat = sInW(sGetTxRxDataIO(cp));
363#ifdef ROCKET_DEBUG_RECEIVE
364 printk(KERN_INFO "%x...\n", CharNStat);
365#endif
366 if (CharNStat & STMBREAKH)
367 CharNStat &= ~(STMFRAMEH | STMPARITYH);
368 if (CharNStat & info->ignore_status_mask) {
369 ToRecv--;
370 continue;
371 }
372 CharNStat &= info->read_status_mask;
373 if (CharNStat & STMBREAKH)
374 flag = TTY_BREAK;
375 else if (CharNStat & STMPARITYH)
376 flag = TTY_PARITY;
377 else if (CharNStat & STMFRAMEH)
378 flag = TTY_FRAME;
379 else if (CharNStat & STMRCVROVRH)
380 flag = TTY_OVERRUN;
381 else
382 flag = TTY_NORMAL;
383 tty_insert_flip_char(tty, CharNStat & 0xff, flag);
384 ToRecv--;
385 }
386
387
388
389
390
391 if (sGetRxCnt(cp) == 0) {
392#ifdef ROCKET_DEBUG_RECEIVE
393 printk(KERN_INFO "Status mode off.\n");
394#endif
395 sDisRxStatusMode(cp);
396 }
397 } else {
398
399
400
401
402
403 space = tty_prepare_flip_string(tty, &cbuf, ToRecv);
404 if (space < ToRecv) {
405#ifdef ROCKET_DEBUG_RECEIVE
406 printk(KERN_INFO "rp_do_receive:insufficient space ToRecv=%d space=%d\n", ToRecv, space);
407#endif
408 if (space <= 0)
409 return;
410 ToRecv = space;
411 }
412 wRecv = ToRecv >> 1;
413 if (wRecv)
414 sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv);
415 if (ToRecv & 1)
416 cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp));
417 }
418
419 tty_flip_buffer_push(tty);
420}
421
422
423
424
425
426
427
428static void rp_do_transmit(struct r_port *info)
429{
430 int c;
431 CHANNEL_t *cp = &info->channel;
432 struct tty_struct *tty;
433 unsigned long flags;
434
435#ifdef ROCKET_DEBUG_INTR
436 printk(KERN_DEBUG "%s\n", __func__);
437#endif
438 if (!info)
439 return;
440 tty = tty_port_tty_get(&info->port);
441
442 if (tty == NULL) {
443 printk(KERN_WARNING "rp: WARNING %s called with tty==NULL\n", __func__);
444 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
445 return;
446 }
447
448 spin_lock_irqsave(&info->slock, flags);
449 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
450
451
452 while (1) {
453 if (tty->stopped || tty->hw_stopped)
454 break;
455 c = min(info->xmit_fifo_room, info->xmit_cnt);
456 c = min(c, XMIT_BUF_SIZE - info->xmit_tail);
457 if (c <= 0 || info->xmit_fifo_room <= 0)
458 break;
459 sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) (info->xmit_buf + info->xmit_tail), c / 2);
460 if (c & 1)
461 sOutB(sGetTxRxDataIO(cp), info->xmit_buf[info->xmit_tail + c - 1]);
462 info->xmit_tail += c;
463 info->xmit_tail &= XMIT_BUF_SIZE - 1;
464 info->xmit_cnt -= c;
465 info->xmit_fifo_room -= c;
466#ifdef ROCKET_DEBUG_INTR
467 printk(KERN_INFO "tx %d chars...\n", c);
468#endif
469 }
470
471 if (info->xmit_cnt == 0)
472 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
473
474 if (info->xmit_cnt < WAKEUP_CHARS) {
475 tty_wakeup(tty);
476#ifdef ROCKETPORT_HAVE_POLL_WAIT
477 wake_up_interruptible(&tty->poll_wait);
478#endif
479 }
480
481 spin_unlock_irqrestore(&info->slock, flags);
482 tty_kref_put(tty);
483
484#ifdef ROCKET_DEBUG_INTR
485 printk(KERN_DEBUG "(%d,%d,%d,%d)...\n", info->xmit_cnt, info->xmit_head,
486 info->xmit_tail, info->xmit_fifo_room);
487#endif
488}
489
490
491
492
493
494
495static void rp_handle_port(struct r_port *info)
496{
497 CHANNEL_t *cp;
498 struct tty_struct *tty;
499 unsigned int IntMask, ChanStatus;
500
501 if (!info)
502 return;
503
504 if ((info->port.flags & ASYNC_INITIALIZED) == 0) {
505 printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
506 "info->flags & NOT_INIT\n");
507 return;
508 }
509 tty = tty_port_tty_get(&info->port);
510 if (!tty) {
511 printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
512 "tty==NULL\n");
513 return;
514 }
515 cp = &info->channel;
516
517 IntMask = sGetChanIntID(cp) & info->intmask;
518#ifdef ROCKET_DEBUG_INTR
519 printk(KERN_INFO "rp_interrupt %02x...\n", IntMask);
520#endif
521 ChanStatus = sGetChanStatus(cp);
522 if (IntMask & RXF_TRIG) {
523 rp_do_receive(info, tty, cp, ChanStatus);
524 }
525 if (IntMask & DELTA_CD) {
526#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_INTR) || defined(ROCKET_DEBUG_HANGUP))
527 printk(KERN_INFO "ttyR%d CD now %s...\n", info->line,
528 (ChanStatus & CD_ACT) ? "on" : "off");
529#endif
530 if (!(ChanStatus & CD_ACT) && info->cd_status) {
531#ifdef ROCKET_DEBUG_HANGUP
532 printk(KERN_INFO "CD drop, calling hangup.\n");
533#endif
534 tty_hangup(tty);
535 }
536 info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0;
537 wake_up_interruptible(&info->port.open_wait);
538 }
539#ifdef ROCKET_DEBUG_INTR
540 if (IntMask & DELTA_CTS) {
541 printk(KERN_INFO "CTS change...\n");
542 }
543 if (IntMask & DELTA_DSR) {
544 printk(KERN_INFO "DSR change...\n");
545 }
546#endif
547 tty_kref_put(tty);
548}
549
550
551
552
553static void rp_do_poll(unsigned long dummy)
554{
555 CONTROLLER_t *ctlp;
556 int ctrl, aiop, ch, line;
557 unsigned int xmitmask, i;
558 unsigned int CtlMask;
559 unsigned char AiopMask;
560 Word_t bit;
561
562
563 for (ctrl = 0; ctrl < max_board; ctrl++) {
564 if (rcktpt_io_addr[ctrl] <= 0)
565 continue;
566
567
568 ctlp = sCtlNumToCtlPtr(ctrl);
569
570
571#ifdef CONFIG_PCI
572 if (ctlp->BusType == isPCI)
573 CtlMask = sPCIGetControllerIntStatus(ctlp);
574 else
575#endif
576 CtlMask = sGetControllerIntStatus(ctlp);
577
578
579 for (aiop = 0; CtlMask; aiop++) {
580 bit = ctlp->AiopIntrBits[aiop];
581 if (CtlMask & bit) {
582 CtlMask &= ~bit;
583 AiopMask = sGetAiopIntStatus(ctlp, aiop);
584
585
586 for (ch = 0; AiopMask; AiopMask >>= 1, ch++) {
587 if (AiopMask & 1) {
588
589
590
591 line = GetLineNumber(ctrl, aiop, ch);
592 rp_handle_port(rp_table[line]);
593 }
594 }
595 }
596 }
597
598 xmitmask = xmit_flags[ctrl];
599
600
601
602
603
604
605
606 if (xmitmask) {
607 for (i = 0; i < rocketModel[ctrl].numPorts; i++) {
608 if (xmitmask & (1 << i)) {
609 aiop = (i & 0x18) >> 3;
610 ch = i & 0x07;
611 line = GetLineNumber(ctrl, aiop, ch);
612 rp_do_transmit(rp_table[line]);
613 }
614 }
615 }
616 }
617
618
619
620
621 if (atomic_read(&rp_num_ports_open))
622 mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
623}
624
625
626
627
628
629
630static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
631{
632 unsigned rocketMode;
633 struct r_port *info;
634 int line;
635 CONTROLLER_T *ctlp;
636
637
638 line = SetLineNumber(board, aiop, chan);
639
640 ctlp = sCtlNumToCtlPtr(board);
641
642
643 info = kzalloc(sizeof (struct r_port), GFP_KERNEL);
644 if (!info) {
645 printk(KERN_ERR "Couldn't allocate info struct for line #%d\n",
646 line);
647 return;
648 }
649
650 info->magic = RPORT_MAGIC;
651 info->line = line;
652 info->ctlp = ctlp;
653 info->board = board;
654 info->aiop = aiop;
655 info->chan = chan;
656 tty_port_init(&info->port);
657 info->port.ops = &rocket_port_ops;
658 init_completion(&info->close_wait);
659 info->flags &= ~ROCKET_MODE_MASK;
660 switch (pc104[board][line]) {
661 case 422:
662 info->flags |= ROCKET_MODE_RS422;
663 break;
664 case 485:
665 info->flags |= ROCKET_MODE_RS485;
666 break;
667 case 232:
668 default:
669 info->flags |= ROCKET_MODE_RS232;
670 break;
671 }
672
673 info->intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR;
674 if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) {
675 printk(KERN_ERR "RocketPort sInitChan(%d, %d, %d) failed!\n",
676 board, aiop, chan);
677 kfree(info);
678 return;
679 }
680
681 rocketMode = info->flags & ROCKET_MODE_MASK;
682
683 if ((info->flags & ROCKET_RTS_TOGGLE) || (rocketMode == ROCKET_MODE_RS485))
684 sEnRTSToggle(&info->channel);
685 else
686 sDisRTSToggle(&info->channel);
687
688 if (ctlp->boardType == ROCKET_TYPE_PC104) {
689 switch (rocketMode) {
690 case ROCKET_MODE_RS485:
691 sSetInterfaceMode(&info->channel, InterfaceModeRS485);
692 break;
693 case ROCKET_MODE_RS422:
694 sSetInterfaceMode(&info->channel, InterfaceModeRS422);
695 break;
696 case ROCKET_MODE_RS232:
697 default:
698 if (info->flags & ROCKET_RTS_TOGGLE)
699 sSetInterfaceMode(&info->channel, InterfaceModeRS232T);
700 else
701 sSetInterfaceMode(&info->channel, InterfaceModeRS232);
702 break;
703 }
704 }
705 spin_lock_init(&info->slock);
706 mutex_init(&info->write_mtx);
707 rp_table[line] = info;
708 tty_register_device(rocket_driver, line, pci_dev ? &pci_dev->dev :
709 NULL);
710}
711
712
713
714
715
716static void configure_r_port(struct tty_struct *tty, struct r_port *info,
717 struct ktermios *old_termios)
718{
719 unsigned cflag;
720 unsigned long flags;
721 unsigned rocketMode;
722 int bits, baud, divisor;
723 CHANNEL_t *cp;
724 struct ktermios *t = tty->termios;
725
726 cp = &info->channel;
727 cflag = t->c_cflag;
728
729
730 if ((cflag & CSIZE) == CS8) {
731 sSetData8(cp);
732 bits = 10;
733 } else {
734 sSetData7(cp);
735 bits = 9;
736 }
737 if (cflag & CSTOPB) {
738 sSetStop2(cp);
739 bits++;
740 } else {
741 sSetStop1(cp);
742 }
743
744 if (cflag & PARENB) {
745 sEnParity(cp);
746 bits++;
747 if (cflag & PARODD) {
748 sSetOddParity(cp);
749 } else {
750 sSetEvenParity(cp);
751 }
752 } else {
753 sDisParity(cp);
754 }
755
756
757 baud = tty_get_baud_rate(tty);
758 if (!baud)
759 baud = 9600;
760 divisor = ((rp_baud_base[info->board] + (baud >> 1)) / baud) - 1;
761 if ((divisor >= 8192 || divisor < 0) && old_termios) {
762 baud = tty_termios_baud_rate(old_termios);
763 if (!baud)
764 baud = 9600;
765 divisor = (rp_baud_base[info->board] / baud) - 1;
766 }
767 if (divisor >= 8192 || divisor < 0) {
768 baud = 9600;
769 divisor = (rp_baud_base[info->board] / baud) - 1;
770 }
771 info->cps = baud / bits;
772 sSetBaud(cp, divisor);
773
774
775 tty_encode_baud_rate(tty, baud, baud);
776
777 if (cflag & CRTSCTS) {
778 info->intmask |= DELTA_CTS;
779 sEnCTSFlowCtl(cp);
780 } else {
781 info->intmask &= ~DELTA_CTS;
782 sDisCTSFlowCtl(cp);
783 }
784 if (cflag & CLOCAL) {
785 info->intmask &= ~DELTA_CD;
786 } else {
787 spin_lock_irqsave(&info->slock, flags);
788 if (sGetChanStatus(cp) & CD_ACT)
789 info->cd_status = 1;
790 else
791 info->cd_status = 0;
792 info->intmask |= DELTA_CD;
793 spin_unlock_irqrestore(&info->slock, flags);
794 }
795
796
797
798
799#ifdef ROCKET_SOFT_FLOW
800 if (I_IXON(tty)) {
801 sEnTxSoftFlowCtl(cp);
802 if (I_IXANY(tty)) {
803 sEnIXANY(cp);
804 } else {
805 sDisIXANY(cp);
806 }
807 sSetTxXONChar(cp, START_CHAR(tty));
808 sSetTxXOFFChar(cp, STOP_CHAR(tty));
809 } else {
810 sDisTxSoftFlowCtl(cp);
811 sDisIXANY(cp);
812 sClrTxXOFF(cp);
813 }
814#endif
815
816
817
818
819 info->read_status_mask = STMRCVROVRH | 0xFF;
820 if (I_INPCK(tty))
821 info->read_status_mask |= STMFRAMEH | STMPARITYH;
822 if (I_BRKINT(tty) || I_PARMRK(tty))
823 info->read_status_mask |= STMBREAKH;
824
825
826
827
828 info->ignore_status_mask = 0;
829 if (I_IGNPAR(tty))
830 info->ignore_status_mask |= STMFRAMEH | STMPARITYH;
831 if (I_IGNBRK(tty)) {
832 info->ignore_status_mask |= STMBREAKH;
833
834
835
836
837 if (I_IGNPAR(tty))
838 info->ignore_status_mask |= STMRCVROVRH;
839 }
840
841 rocketMode = info->flags & ROCKET_MODE_MASK;
842
843 if ((info->flags & ROCKET_RTS_TOGGLE)
844 || (rocketMode == ROCKET_MODE_RS485))
845 sEnRTSToggle(cp);
846 else
847 sDisRTSToggle(cp);
848
849 sSetRTS(&info->channel);
850
851 if (cp->CtlP->boardType == ROCKET_TYPE_PC104) {
852 switch (rocketMode) {
853 case ROCKET_MODE_RS485:
854 sSetInterfaceMode(cp, InterfaceModeRS485);
855 break;
856 case ROCKET_MODE_RS422:
857 sSetInterfaceMode(cp, InterfaceModeRS422);
858 break;
859 case ROCKET_MODE_RS232:
860 default:
861 if (info->flags & ROCKET_RTS_TOGGLE)
862 sSetInterfaceMode(cp, InterfaceModeRS232T);
863 else
864 sSetInterfaceMode(cp, InterfaceModeRS232);
865 break;
866 }
867 }
868}
869
870static int carrier_raised(struct tty_port *port)
871{
872 struct r_port *info = container_of(port, struct r_port, port);
873 return (sGetChanStatusLo(&info->channel) & CD_ACT) ? 1 : 0;
874}
875
876static void dtr_rts(struct tty_port *port, int on)
877{
878 struct r_port *info = container_of(port, struct r_port, port);
879 if (on) {
880 sSetDTR(&info->channel);
881 sSetRTS(&info->channel);
882 } else {
883 sClrDTR(&info->channel);
884 sClrRTS(&info->channel);
885 }
886}
887
888
889
890
891
892static int rp_open(struct tty_struct *tty, struct file *filp)
893{
894 struct r_port *info;
895 struct tty_port *port;
896 int line = 0, retval;
897 CHANNEL_t *cp;
898 unsigned long page;
899
900 line = tty->index;
901 if (line < 0 || line >= MAX_RP_PORTS || ((info = rp_table[line]) == NULL))
902 return -ENXIO;
903 port = &info->port;
904
905 page = __get_free_page(GFP_KERNEL);
906 if (!page)
907 return -ENOMEM;
908
909 if (port->flags & ASYNC_CLOSING) {
910 retval = wait_for_completion_interruptible(&info->close_wait);
911 free_page(page);
912 if (retval)
913 return retval;
914 return ((port->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
915 }
916
917
918
919
920 if (info->xmit_buf)
921 free_page(page);
922 else
923 info->xmit_buf = (unsigned char *) page;
924
925 tty->driver_data = info;
926 tty_port_tty_set(port, tty);
927
928 if (port->count++ == 0) {
929 atomic_inc(&rp_num_ports_open);
930
931#ifdef ROCKET_DEBUG_OPEN
932 printk(KERN_INFO "rocket mod++ = %d...\n",
933 atomic_read(&rp_num_ports_open));
934#endif
935 }
936#ifdef ROCKET_DEBUG_OPEN
937 printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->port.count);
938#endif
939
940
941
942
943 if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
944 cp = &info->channel;
945 sSetRxTrigger(cp, TRIG_1);
946 if (sGetChanStatus(cp) & CD_ACT)
947 info->cd_status = 1;
948 else
949 info->cd_status = 0;
950 sDisRxStatusMode(cp);
951 sFlushRxFIFO(cp);
952 sFlushTxFIFO(cp);
953
954 sEnInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
955 sSetRxTrigger(cp, TRIG_1);
956
957 sGetChanStatus(cp);
958 sDisRxStatusMode(cp);
959 sClrTxXOFF(cp);
960
961 sDisCTSFlowCtl(cp);
962 sDisTxSoftFlowCtl(cp);
963
964 sEnRxFIFO(cp);
965 sEnTransmit(cp);
966
967 set_bit(ASYNCB_INITIALIZED, &info->port.flags);
968
969
970
971
972 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
973 tty->alt_speed = 57600;
974 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
975 tty->alt_speed = 115200;
976 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
977 tty->alt_speed = 230400;
978 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
979 tty->alt_speed = 460800;
980
981 configure_r_port(tty, info, NULL);
982 if (tty->termios->c_cflag & CBAUD) {
983 sSetDTR(cp);
984 sSetRTS(cp);
985 }
986 }
987
988 mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
989
990 retval = tty_port_block_til_ready(port, tty, filp);
991 if (retval) {
992#ifdef ROCKET_DEBUG_OPEN
993 printk(KERN_INFO "rp_open returning after block_til_ready with %d\n", retval);
994#endif
995 return retval;
996 }
997 return 0;
998}
999
1000
1001
1002
1003static void rp_close(struct tty_struct *tty, struct file *filp)
1004{
1005 struct r_port *info = tty->driver_data;
1006 struct tty_port *port = &info->port;
1007 int timeout;
1008 CHANNEL_t *cp;
1009
1010 if (rocket_paranoia_check(info, "rp_close"))
1011 return;
1012
1013#ifdef ROCKET_DEBUG_OPEN
1014 printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->port.count);
1015#endif
1016
1017 if (tty_port_close_start(port, tty, filp) == 0)
1018 return;
1019
1020 cp = &info->channel;
1021
1022
1023
1024
1025
1026 timeout = (sGetTxCnt(cp) + 1) * HZ / info->cps;
1027 if (timeout == 0)
1028 timeout = 1;
1029 rp_wait_until_sent(tty, timeout);
1030 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1031
1032 sDisTransmit(cp);
1033 sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
1034 sDisCTSFlowCtl(cp);
1035 sDisTxSoftFlowCtl(cp);
1036 sClrTxXOFF(cp);
1037 sFlushRxFIFO(cp);
1038 sFlushTxFIFO(cp);
1039 sClrRTS(cp);
1040 if (C_HUPCL(tty))
1041 sClrDTR(cp);
1042
1043 rp_flush_buffer(tty);
1044
1045 tty_ldisc_flush(tty);
1046
1047 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1048
1049
1050
1051
1052 if (port->blocked_open) {
1053 if (port->close_delay) {
1054 msleep_interruptible(jiffies_to_msecs(port->close_delay));
1055 }
1056 wake_up_interruptible(&port->open_wait);
1057 } else {
1058 if (info->xmit_buf) {
1059 free_page((unsigned long) info->xmit_buf);
1060 info->xmit_buf = NULL;
1061 }
1062 }
1063 info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE);
1064 tty->closing = 0;
1065 tty_port_tty_set(port, NULL);
1066 wake_up_interruptible(&port->close_wait);
1067 complete_all(&info->close_wait);
1068 atomic_dec(&rp_num_ports_open);
1069
1070#ifdef ROCKET_DEBUG_OPEN
1071 printk(KERN_INFO "rocket mod-- = %d...\n",
1072 atomic_read(&rp_num_ports_open));
1073 printk(KERN_INFO "rp_close ttyR%d complete shutdown\n", info->line);
1074#endif
1075
1076}
1077
1078static void rp_set_termios(struct tty_struct *tty,
1079 struct ktermios *old_termios)
1080{
1081 struct r_port *info = tty->driver_data;
1082 CHANNEL_t *cp;
1083 unsigned cflag;
1084
1085 if (rocket_paranoia_check(info, "rp_set_termios"))
1086 return;
1087
1088 cflag = tty->termios->c_cflag;
1089
1090
1091
1092
1093 if (((cflag & CSIZE) == CS5) || ((cflag & CSIZE) == CS6))
1094 tty->termios->c_cflag =
1095 ((cflag & ~CSIZE) | (old_termios->c_cflag & CSIZE));
1096
1097 tty->termios->c_cflag &= ~CMSPAR;
1098
1099 configure_r_port(tty, info, old_termios);
1100
1101 cp = &info->channel;
1102
1103
1104 if ((old_termios->c_cflag & CBAUD) && !(tty->termios->c_cflag & CBAUD)) {
1105 sClrDTR(cp);
1106 sClrRTS(cp);
1107 }
1108
1109
1110 if (!(old_termios->c_cflag & CBAUD) && (tty->termios->c_cflag & CBAUD)) {
1111 if (!tty->hw_stopped || !(tty->termios->c_cflag & CRTSCTS))
1112 sSetRTS(cp);
1113 sSetDTR(cp);
1114 }
1115
1116 if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
1117 tty->hw_stopped = 0;
1118 rp_start(tty);
1119 }
1120}
1121
1122static int rp_break(struct tty_struct *tty, int break_state)
1123{
1124 struct r_port *info = tty->driver_data;
1125 unsigned long flags;
1126
1127 if (rocket_paranoia_check(info, "rp_break"))
1128 return -EINVAL;
1129
1130 spin_lock_irqsave(&info->slock, flags);
1131 if (break_state == -1)
1132 sSendBreak(&info->channel);
1133 else
1134 sClrBreak(&info->channel);
1135 spin_unlock_irqrestore(&info->slock, flags);
1136 return 0;
1137}
1138
1139
1140
1141
1142
1143
1144
1145static int sGetChanRI(CHANNEL_T * ChP)
1146{
1147 CONTROLLER_t *CtlP = ChP->CtlP;
1148 int ChanNum = ChP->ChanNum;
1149 int RingInd = 0;
1150
1151 if (CtlP->UPCIRingInd)
1152 RingInd = !(sInB(CtlP->UPCIRingInd) & sBitMapSetTbl[ChanNum]);
1153 else if (CtlP->AltChanRingIndicator)
1154 RingInd = sInB((ByteIO_t) (ChP->ChanStat + 8)) & DSR_ACT;
1155 else if (CtlP->boardType == ROCKET_TYPE_PC104)
1156 RingInd = !(sInB(CtlP->AiopIO[3]) & sBitMapSetTbl[ChanNum]);
1157
1158 return RingInd;
1159}
1160
1161
1162
1163
1164
1165
1166
1167
1168static int rp_tiocmget(struct tty_struct *tty, struct file *file)
1169{
1170 struct r_port *info = tty->driver_data;
1171 unsigned int control, result, ChanStatus;
1172
1173 ChanStatus = sGetChanStatusLo(&info->channel);
1174 control = info->channel.TxControl[3];
1175 result = ((control & SET_RTS) ? TIOCM_RTS : 0) |
1176 ((control & SET_DTR) ? TIOCM_DTR : 0) |
1177 ((ChanStatus & CD_ACT) ? TIOCM_CAR : 0) |
1178 (sGetChanRI(&info->channel) ? TIOCM_RNG : 0) |
1179 ((ChanStatus & DSR_ACT) ? TIOCM_DSR : 0) |
1180 ((ChanStatus & CTS_ACT) ? TIOCM_CTS : 0);
1181
1182 return result;
1183}
1184
1185
1186
1187
1188static int rp_tiocmset(struct tty_struct *tty, struct file *file,
1189 unsigned int set, unsigned int clear)
1190{
1191 struct r_port *info = tty->driver_data;
1192
1193 if (set & TIOCM_RTS)
1194 info->channel.TxControl[3] |= SET_RTS;
1195 if (set & TIOCM_DTR)
1196 info->channel.TxControl[3] |= SET_DTR;
1197 if (clear & TIOCM_RTS)
1198 info->channel.TxControl[3] &= ~SET_RTS;
1199 if (clear & TIOCM_DTR)
1200 info->channel.TxControl[3] &= ~SET_DTR;
1201
1202 out32(info->channel.IndexAddr, info->channel.TxControl);
1203 return 0;
1204}
1205
1206static int get_config(struct r_port *info, struct rocket_config __user *retinfo)
1207{
1208 struct rocket_config tmp;
1209
1210 if (!retinfo)
1211 return -EFAULT;
1212 memset(&tmp, 0, sizeof (tmp));
1213 tmp.line = info->line;
1214 tmp.flags = info->flags;
1215 tmp.close_delay = info->port.close_delay;
1216 tmp.closing_wait = info->port.closing_wait;
1217 tmp.port = rcktpt_io_addr[(info->line >> 5) & 3];
1218
1219 if (copy_to_user(retinfo, &tmp, sizeof (*retinfo)))
1220 return -EFAULT;
1221 return 0;
1222}
1223
1224static int set_config(struct tty_struct *tty, struct r_port *info,
1225 struct rocket_config __user *new_info)
1226{
1227 struct rocket_config new_serial;
1228
1229 if (copy_from_user(&new_serial, new_info, sizeof (new_serial)))
1230 return -EFAULT;
1231
1232 if (!capable(CAP_SYS_ADMIN))
1233 {
1234 if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK))
1235 return -EPERM;
1236 info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK));
1237 configure_r_port(tty, info, NULL);
1238 return 0;
1239 }
1240
1241 info->flags = ((info->flags & ~ROCKET_FLAGS) | (new_serial.flags & ROCKET_FLAGS));
1242 info->port.close_delay = new_serial.close_delay;
1243 info->port.closing_wait = new_serial.closing_wait;
1244
1245 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
1246 tty->alt_speed = 57600;
1247 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
1248 tty->alt_speed = 115200;
1249 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
1250 tty->alt_speed = 230400;
1251 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
1252 tty->alt_speed = 460800;
1253
1254 configure_r_port(tty, info, NULL);
1255 return 0;
1256}
1257
1258
1259
1260
1261
1262
1263
1264static int get_ports(struct r_port *info, struct rocket_ports __user *retports)
1265{
1266 struct rocket_ports tmp;
1267 int board;
1268
1269 if (!retports)
1270 return -EFAULT;
1271 memset(&tmp, 0, sizeof (tmp));
1272 tmp.tty_major = rocket_driver->major;
1273
1274 for (board = 0; board < 4; board++) {
1275 tmp.rocketModel[board].model = rocketModel[board].model;
1276 strcpy(tmp.rocketModel[board].modelString, rocketModel[board].modelString);
1277 tmp.rocketModel[board].numPorts = rocketModel[board].numPorts;
1278 tmp.rocketModel[board].loadrm2 = rocketModel[board].loadrm2;
1279 tmp.rocketModel[board].startingPortNumber = rocketModel[board].startingPortNumber;
1280 }
1281 if (copy_to_user(retports, &tmp, sizeof (*retports)))
1282 return -EFAULT;
1283 return 0;
1284}
1285
1286static int reset_rm2(struct r_port *info, void __user *arg)
1287{
1288 int reset;
1289
1290 if (!capable(CAP_SYS_ADMIN))
1291 return -EPERM;
1292
1293 if (copy_from_user(&reset, arg, sizeof (int)))
1294 return -EFAULT;
1295 if (reset)
1296 reset = 1;
1297
1298 if (rcktpt_type[info->board] != ROCKET_TYPE_MODEMII &&
1299 rcktpt_type[info->board] != ROCKET_TYPE_MODEMIII)
1300 return -EINVAL;
1301
1302 if (info->ctlp->BusType == isISA)
1303 sModemReset(info->ctlp, info->chan, reset);
1304 else
1305 sPCIModemReset(info->ctlp, info->chan, reset);
1306
1307 return 0;
1308}
1309
1310static int get_version(struct r_port *info, struct rocket_version __user *retvers)
1311{
1312 if (copy_to_user(retvers, &driver_version, sizeof (*retvers)))
1313 return -EFAULT;
1314 return 0;
1315}
1316
1317
1318static int rp_ioctl(struct tty_struct *tty, struct file *file,
1319 unsigned int cmd, unsigned long arg)
1320{
1321 struct r_port *info = tty->driver_data;
1322 void __user *argp = (void __user *)arg;
1323 int ret = 0;
1324
1325 if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl"))
1326 return -ENXIO;
1327
1328 lock_kernel();
1329
1330 switch (cmd) {
1331 case RCKP_GET_STRUCT:
1332 if (copy_to_user(argp, info, sizeof (struct r_port)))
1333 ret = -EFAULT;
1334 break;
1335 case RCKP_GET_CONFIG:
1336 ret = get_config(info, argp);
1337 break;
1338 case RCKP_SET_CONFIG:
1339 ret = set_config(tty, info, argp);
1340 break;
1341 case RCKP_GET_PORTS:
1342 ret = get_ports(info, argp);
1343 break;
1344 case RCKP_RESET_RM2:
1345 ret = reset_rm2(info, argp);
1346 break;
1347 case RCKP_GET_VERSION:
1348 ret = get_version(info, argp);
1349 break;
1350 default:
1351 ret = -ENOIOCTLCMD;
1352 }
1353 unlock_kernel();
1354 return ret;
1355}
1356
1357static void rp_send_xchar(struct tty_struct *tty, char ch)
1358{
1359 struct r_port *info = tty->driver_data;
1360 CHANNEL_t *cp;
1361
1362 if (rocket_paranoia_check(info, "rp_send_xchar"))
1363 return;
1364
1365 cp = &info->channel;
1366 if (sGetTxCnt(cp))
1367 sWriteTxPrioByte(cp, ch);
1368 else
1369 sWriteTxByte(sGetTxRxDataIO(cp), ch);
1370}
1371
1372static void rp_throttle(struct tty_struct *tty)
1373{
1374 struct r_port *info = tty->driver_data;
1375 CHANNEL_t *cp;
1376
1377#ifdef ROCKET_DEBUG_THROTTLE
1378 printk(KERN_INFO "throttle %s: %d....\n", tty->name,
1379 tty->ldisc.chars_in_buffer(tty));
1380#endif
1381
1382 if (rocket_paranoia_check(info, "rp_throttle"))
1383 return;
1384
1385 cp = &info->channel;
1386 if (I_IXOFF(tty))
1387 rp_send_xchar(tty, STOP_CHAR(tty));
1388
1389 sClrRTS(&info->channel);
1390}
1391
1392static void rp_unthrottle(struct tty_struct *tty)
1393{
1394 struct r_port *info = tty->driver_data;
1395 CHANNEL_t *cp;
1396#ifdef ROCKET_DEBUG_THROTTLE
1397 printk(KERN_INFO "unthrottle %s: %d....\n", tty->name,
1398 tty->ldisc.chars_in_buffer(tty));
1399#endif
1400
1401 if (rocket_paranoia_check(info, "rp_throttle"))
1402 return;
1403
1404 cp = &info->channel;
1405 if (I_IXOFF(tty))
1406 rp_send_xchar(tty, START_CHAR(tty));
1407
1408 sSetRTS(&info->channel);
1409}
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419static void rp_stop(struct tty_struct *tty)
1420{
1421 struct r_port *info = tty->driver_data;
1422
1423#ifdef ROCKET_DEBUG_FLOW
1424 printk(KERN_INFO "stop %s: %d %d....\n", tty->name,
1425 info->xmit_cnt, info->xmit_fifo_room);
1426#endif
1427
1428 if (rocket_paranoia_check(info, "rp_stop"))
1429 return;
1430
1431 if (sGetTxCnt(&info->channel))
1432 sDisTransmit(&info->channel);
1433}
1434
1435static void rp_start(struct tty_struct *tty)
1436{
1437 struct r_port *info = tty->driver_data;
1438
1439#ifdef ROCKET_DEBUG_FLOW
1440 printk(KERN_INFO "start %s: %d %d....\n", tty->name,
1441 info->xmit_cnt, info->xmit_fifo_room);
1442#endif
1443
1444 if (rocket_paranoia_check(info, "rp_stop"))
1445 return;
1446
1447 sEnTransmit(&info->channel);
1448 set_bit((info->aiop * 8) + info->chan,
1449 (void *) &xmit_flags[info->board]);
1450}
1451
1452
1453
1454
1455static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
1456{
1457 struct r_port *info = tty->driver_data;
1458 CHANNEL_t *cp;
1459 unsigned long orig_jiffies;
1460 int check_time, exit_time;
1461 int txcnt;
1462
1463 if (rocket_paranoia_check(info, "rp_wait_until_sent"))
1464 return;
1465
1466 cp = &info->channel;
1467
1468 orig_jiffies = jiffies;
1469#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1470 printk(KERN_INFO "In RP_wait_until_sent(%d) (jiff=%lu)...\n", timeout,
1471 jiffies);
1472 printk(KERN_INFO "cps=%d...\n", info->cps);
1473#endif
1474 lock_kernel();
1475 while (1) {
1476 txcnt = sGetTxCnt(cp);
1477 if (!txcnt) {
1478 if (sGetChanStatusLo(cp) & TXSHRMT)
1479 break;
1480 check_time = (HZ / info->cps) / 5;
1481 } else {
1482 check_time = HZ * txcnt / info->cps;
1483 }
1484 if (timeout) {
1485 exit_time = orig_jiffies + timeout - jiffies;
1486 if (exit_time <= 0)
1487 break;
1488 if (exit_time < check_time)
1489 check_time = exit_time;
1490 }
1491 if (check_time == 0)
1492 check_time = 1;
1493#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1494 printk(KERN_INFO "txcnt = %d (jiff=%lu,check=%d)...\n", txcnt,
1495 jiffies, check_time);
1496#endif
1497 msleep_interruptible(jiffies_to_msecs(check_time));
1498 if (signal_pending(current))
1499 break;
1500 }
1501 __set_current_state(TASK_RUNNING);
1502 unlock_kernel();
1503#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1504 printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
1505#endif
1506}
1507
1508
1509
1510
1511static void rp_hangup(struct tty_struct *tty)
1512{
1513 CHANNEL_t *cp;
1514 struct r_port *info = tty->driver_data;
1515
1516 if (rocket_paranoia_check(info, "rp_hangup"))
1517 return;
1518
1519#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_HANGUP))
1520 printk(KERN_INFO "rp_hangup of ttyR%d...\n", info->line);
1521#endif
1522 rp_flush_buffer(tty);
1523 if (info->port.flags & ASYNC_CLOSING)
1524 return;
1525 if (info->port.count)
1526 atomic_dec(&rp_num_ports_open);
1527 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1528
1529 tty_port_hangup(&info->port);
1530
1531 cp = &info->channel;
1532 sDisRxFIFO(cp);
1533 sDisTransmit(cp);
1534 sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
1535 sDisCTSFlowCtl(cp);
1536 sDisTxSoftFlowCtl(cp);
1537 sClrTxXOFF(cp);
1538 info->port.flags &= ~ASYNC_INITIALIZED;
1539
1540 wake_up_interruptible(&info->port.open_wait);
1541}
1542
1543
1544
1545
1546
1547
1548
1549
1550static int rp_put_char(struct tty_struct *tty, unsigned char ch)
1551{
1552 struct r_port *info = tty->driver_data;
1553 CHANNEL_t *cp;
1554 unsigned long flags;
1555
1556 if (rocket_paranoia_check(info, "rp_put_char"))
1557 return 0;
1558
1559
1560
1561
1562
1563 mutex_lock(&info->write_mtx);
1564
1565#ifdef ROCKET_DEBUG_WRITE
1566 printk(KERN_INFO "rp_put_char %c...\n", ch);
1567#endif
1568
1569 spin_lock_irqsave(&info->slock, flags);
1570 cp = &info->channel;
1571
1572 if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room == 0)
1573 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
1574
1575 if (tty->stopped || tty->hw_stopped || info->xmit_fifo_room == 0 || info->xmit_cnt != 0) {
1576 info->xmit_buf[info->xmit_head++] = ch;
1577 info->xmit_head &= XMIT_BUF_SIZE - 1;
1578 info->xmit_cnt++;
1579 set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1580 } else {
1581 sOutB(sGetTxRxDataIO(cp), ch);
1582 info->xmit_fifo_room--;
1583 }
1584 spin_unlock_irqrestore(&info->slock, flags);
1585 mutex_unlock(&info->write_mtx);
1586 return 1;
1587}
1588
1589
1590
1591
1592
1593
1594
1595
1596static int rp_write(struct tty_struct *tty,
1597 const unsigned char *buf, int count)
1598{
1599 struct r_port *info = tty->driver_data;
1600 CHANNEL_t *cp;
1601 const unsigned char *b;
1602 int c, retval = 0;
1603 unsigned long flags;
1604
1605 if (count <= 0 || rocket_paranoia_check(info, "rp_write"))
1606 return 0;
1607
1608 if (mutex_lock_interruptible(&info->write_mtx))
1609 return -ERESTARTSYS;
1610
1611#ifdef ROCKET_DEBUG_WRITE
1612 printk(KERN_INFO "rp_write %d chars...\n", count);
1613#endif
1614 cp = &info->channel;
1615
1616 if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room < count)
1617 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
1618
1619
1620
1621
1622
1623 if (!tty->stopped && !tty->hw_stopped && info->xmit_cnt == 0 && info->xmit_fifo_room > 0) {
1624 c = min(count, info->xmit_fifo_room);
1625 b = buf;
1626
1627
1628 sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) b, c / 2);
1629
1630
1631 if (c & 1)
1632 sOutB(sGetTxRxDataIO(cp), b[c - 1]);
1633
1634 retval += c;
1635 buf += c;
1636 count -= c;
1637
1638 spin_lock_irqsave(&info->slock, flags);
1639 info->xmit_fifo_room -= c;
1640 spin_unlock_irqrestore(&info->slock, flags);
1641 }
1642
1643
1644 if (!count)
1645 goto end;
1646
1647
1648 while (1) {
1649
1650 if (!test_bit(ASYNCB_NORMAL_ACTIVE, &info->port.flags))
1651 goto end;
1652 c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
1653 c = min(c, XMIT_BUF_SIZE - info->xmit_head);
1654 if (c <= 0)
1655 break;
1656
1657 b = buf;
1658 memcpy(info->xmit_buf + info->xmit_head, b, c);
1659
1660 spin_lock_irqsave(&info->slock, flags);
1661 info->xmit_head =
1662 (info->xmit_head + c) & (XMIT_BUF_SIZE - 1);
1663 info->xmit_cnt += c;
1664 spin_unlock_irqrestore(&info->slock, flags);
1665
1666 buf += c;
1667 count -= c;
1668 retval += c;
1669 }
1670
1671 if ((retval > 0) && !tty->stopped && !tty->hw_stopped)
1672 set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1673
1674end:
1675 if (info->xmit_cnt < WAKEUP_CHARS) {
1676 tty_wakeup(tty);
1677#ifdef ROCKETPORT_HAVE_POLL_WAIT
1678 wake_up_interruptible(&tty->poll_wait);
1679#endif
1680 }
1681 mutex_unlock(&info->write_mtx);
1682 return retval;
1683}
1684
1685
1686
1687
1688
1689
1690static int rp_write_room(struct tty_struct *tty)
1691{
1692 struct r_port *info = tty->driver_data;
1693 int ret;
1694
1695 if (rocket_paranoia_check(info, "rp_write_room"))
1696 return 0;
1697
1698 ret = XMIT_BUF_SIZE - info->xmit_cnt - 1;
1699 if (ret < 0)
1700 ret = 0;
1701#ifdef ROCKET_DEBUG_WRITE
1702 printk(KERN_INFO "rp_write_room returns %d...\n", ret);
1703#endif
1704 return ret;
1705}
1706
1707
1708
1709
1710
1711static int rp_chars_in_buffer(struct tty_struct *tty)
1712{
1713 struct r_port *info = tty->driver_data;
1714 CHANNEL_t *cp;
1715
1716 if (rocket_paranoia_check(info, "rp_chars_in_buffer"))
1717 return 0;
1718
1719 cp = &info->channel;
1720
1721#ifdef ROCKET_DEBUG_WRITE
1722 printk(KERN_INFO "rp_chars_in_buffer returns %d...\n", info->xmit_cnt);
1723#endif
1724 return info->xmit_cnt;
1725}
1726
1727
1728
1729
1730
1731
1732static void rp_flush_buffer(struct tty_struct *tty)
1733{
1734 struct r_port *info = tty->driver_data;
1735 CHANNEL_t *cp;
1736 unsigned long flags;
1737
1738 if (rocket_paranoia_check(info, "rp_flush_buffer"))
1739 return;
1740
1741 spin_lock_irqsave(&info->slock, flags);
1742 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1743 spin_unlock_irqrestore(&info->slock, flags);
1744
1745#ifdef ROCKETPORT_HAVE_POLL_WAIT
1746 wake_up_interruptible(&tty->poll_wait);
1747#endif
1748 tty_wakeup(tty);
1749
1750 cp = &info->channel;
1751 sFlushTxFIFO(cp);
1752}
1753
1754#ifdef CONFIG_PCI
1755
1756static struct pci_device_id __devinitdata rocket_pci_ids[] = {
1757 { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) },
1758 { }
1759};
1760MODULE_DEVICE_TABLE(pci, rocket_pci_ids);
1761
1762
1763
1764
1765
1766
1767static __init int register_PCI(int i, struct pci_dev *dev)
1768{
1769 int num_aiops, aiop, max_num_aiops, num_chan, chan;
1770 unsigned int aiopio[MAX_AIOPS_PER_BOARD];
1771 char *str, *board_type;
1772 CONTROLLER_t *ctlp;
1773
1774 int fast_clock = 0;
1775 int altChanRingIndicator = 0;
1776 int ports_per_aiop = 8;
1777 WordIO_t ConfigIO = 0;
1778 ByteIO_t UPCIRingInd = 0;
1779
1780 if (!dev || pci_enable_device(dev))
1781 return 0;
1782
1783 rcktpt_io_addr[i] = pci_resource_start(dev, 0);
1784
1785 rcktpt_type[i] = ROCKET_TYPE_NORMAL;
1786 rocketModel[i].loadrm2 = 0;
1787 rocketModel[i].startingPortNumber = nextLineNumber;
1788
1789
1790 switch (dev->device) {
1791 case PCI_DEVICE_ID_RP4QUAD:
1792 str = "Quadcable";
1793 max_num_aiops = 1;
1794 ports_per_aiop = 4;
1795 rocketModel[i].model = MODEL_RP4QUAD;
1796 strcpy(rocketModel[i].modelString, "RocketPort 4 port w/quad cable");
1797 rocketModel[i].numPorts = 4;
1798 break;
1799 case PCI_DEVICE_ID_RP8OCTA:
1800 str = "Octacable";
1801 max_num_aiops = 1;
1802 rocketModel[i].model = MODEL_RP8OCTA;
1803 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/octa cable");
1804 rocketModel[i].numPorts = 8;
1805 break;
1806 case PCI_DEVICE_ID_URP8OCTA:
1807 str = "Octacable";
1808 max_num_aiops = 1;
1809 rocketModel[i].model = MODEL_UPCI_RP8OCTA;
1810 strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/octa cable");
1811 rocketModel[i].numPorts = 8;
1812 break;
1813 case PCI_DEVICE_ID_RP8INTF:
1814 str = "8";
1815 max_num_aiops = 1;
1816 rocketModel[i].model = MODEL_RP8INTF;
1817 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/external I/F");
1818 rocketModel[i].numPorts = 8;
1819 break;
1820 case PCI_DEVICE_ID_URP8INTF:
1821 str = "8";
1822 max_num_aiops = 1;
1823 rocketModel[i].model = MODEL_UPCI_RP8INTF;
1824 strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/external I/F");
1825 rocketModel[i].numPorts = 8;
1826 break;
1827 case PCI_DEVICE_ID_RP8J:
1828 str = "8J";
1829 max_num_aiops = 1;
1830 rocketModel[i].model = MODEL_RP8J;
1831 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/RJ11 connectors");
1832 rocketModel[i].numPorts = 8;
1833 break;
1834 case PCI_DEVICE_ID_RP4J:
1835 str = "4J";
1836 max_num_aiops = 1;
1837 ports_per_aiop = 4;
1838 rocketModel[i].model = MODEL_RP4J;
1839 strcpy(rocketModel[i].modelString, "RocketPort 4 port w/RJ45 connectors");
1840 rocketModel[i].numPorts = 4;
1841 break;
1842 case PCI_DEVICE_ID_RP8SNI:
1843 str = "8 (DB78 Custom)";
1844 max_num_aiops = 1;
1845 rocketModel[i].model = MODEL_RP8SNI;
1846 strcpy(rocketModel[i].modelString, "RocketPort 8 port w/ custom DB78");
1847 rocketModel[i].numPorts = 8;
1848 break;
1849 case PCI_DEVICE_ID_RP16SNI:
1850 str = "16 (DB78 Custom)";
1851 max_num_aiops = 2;
1852 rocketModel[i].model = MODEL_RP16SNI;
1853 strcpy(rocketModel[i].modelString, "RocketPort 16 port w/ custom DB78");
1854 rocketModel[i].numPorts = 16;
1855 break;
1856 case PCI_DEVICE_ID_RP16INTF:
1857 str = "16";
1858 max_num_aiops = 2;
1859 rocketModel[i].model = MODEL_RP16INTF;
1860 strcpy(rocketModel[i].modelString, "RocketPort 16 port w/external I/F");
1861 rocketModel[i].numPorts = 16;
1862 break;
1863 case PCI_DEVICE_ID_URP16INTF:
1864 str = "16";
1865 max_num_aiops = 2;
1866 rocketModel[i].model = MODEL_UPCI_RP16INTF;
1867 strcpy(rocketModel[i].modelString, "RocketPort UPCI 16 port w/external I/F");
1868 rocketModel[i].numPorts = 16;
1869 break;
1870 case PCI_DEVICE_ID_CRP16INTF:
1871 str = "16";
1872 max_num_aiops = 2;
1873 rocketModel[i].model = MODEL_CPCI_RP16INTF;
1874 strcpy(rocketModel[i].modelString, "RocketPort Compact PCI 16 port w/external I/F");
1875 rocketModel[i].numPorts = 16;
1876 break;
1877 case PCI_DEVICE_ID_RP32INTF:
1878 str = "32";
1879 max_num_aiops = 4;
1880 rocketModel[i].model = MODEL_RP32INTF;
1881 strcpy(rocketModel[i].modelString, "RocketPort 32 port w/external I/F");
1882 rocketModel[i].numPorts = 32;
1883 break;
1884 case PCI_DEVICE_ID_URP32INTF:
1885 str = "32";
1886 max_num_aiops = 4;
1887 rocketModel[i].model = MODEL_UPCI_RP32INTF;
1888 strcpy(rocketModel[i].modelString, "RocketPort UPCI 32 port w/external I/F");
1889 rocketModel[i].numPorts = 32;
1890 break;
1891 case PCI_DEVICE_ID_RPP4:
1892 str = "Plus Quadcable";
1893 max_num_aiops = 1;
1894 ports_per_aiop = 4;
1895 altChanRingIndicator++;
1896 fast_clock++;
1897 rocketModel[i].model = MODEL_RPP4;
1898 strcpy(rocketModel[i].modelString, "RocketPort Plus 4 port");
1899 rocketModel[i].numPorts = 4;
1900 break;
1901 case PCI_DEVICE_ID_RPP8:
1902 str = "Plus Octacable";
1903 max_num_aiops = 2;
1904 ports_per_aiop = 4;
1905 altChanRingIndicator++;
1906 fast_clock++;
1907 rocketModel[i].model = MODEL_RPP8;
1908 strcpy(rocketModel[i].modelString, "RocketPort Plus 8 port");
1909 rocketModel[i].numPorts = 8;
1910 break;
1911 case PCI_DEVICE_ID_RP2_232:
1912 str = "Plus 2 (RS-232)";
1913 max_num_aiops = 1;
1914 ports_per_aiop = 2;
1915 altChanRingIndicator++;
1916 fast_clock++;
1917 rocketModel[i].model = MODEL_RP2_232;
1918 strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS232");
1919 rocketModel[i].numPorts = 2;
1920 break;
1921 case PCI_DEVICE_ID_RP2_422:
1922 str = "Plus 2 (RS-422)";
1923 max_num_aiops = 1;
1924 ports_per_aiop = 2;
1925 altChanRingIndicator++;
1926 fast_clock++;
1927 rocketModel[i].model = MODEL_RP2_422;
1928 strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS422");
1929 rocketModel[i].numPorts = 2;
1930 break;
1931 case PCI_DEVICE_ID_RP6M:
1932
1933 max_num_aiops = 1;
1934 ports_per_aiop = 6;
1935 str = "6-port";
1936
1937
1938
1939 if (dev->revision == 1) {
1940 rcktpt_type[i] = ROCKET_TYPE_MODEMII;
1941 rocketModel[i].loadrm2 = 1;
1942 } else {
1943 rcktpt_type[i] = ROCKET_TYPE_MODEM;
1944 }
1945
1946 rocketModel[i].model = MODEL_RP6M;
1947 strcpy(rocketModel[i].modelString, "RocketModem 6 port");
1948 rocketModel[i].numPorts = 6;
1949 break;
1950 case PCI_DEVICE_ID_RP4M:
1951 max_num_aiops = 1;
1952 ports_per_aiop = 4;
1953 str = "4-port";
1954 if (dev->revision == 1) {
1955 rcktpt_type[i] = ROCKET_TYPE_MODEMII;
1956 rocketModel[i].loadrm2 = 1;
1957 } else {
1958 rcktpt_type[i] = ROCKET_TYPE_MODEM;
1959 }
1960
1961 rocketModel[i].model = MODEL_RP4M;
1962 strcpy(rocketModel[i].modelString, "RocketModem 4 port");
1963 rocketModel[i].numPorts = 4;
1964 break;
1965 default:
1966 str = "(unknown/unsupported)";
1967 max_num_aiops = 0;
1968 break;
1969 }
1970
1971
1972
1973
1974
1975 switch (dev->device) {
1976 case PCI_DEVICE_ID_URP32INTF:
1977 case PCI_DEVICE_ID_URP8INTF:
1978 case PCI_DEVICE_ID_URP16INTF:
1979 case PCI_DEVICE_ID_CRP16INTF:
1980 case PCI_DEVICE_ID_URP8OCTA:
1981 rcktpt_io_addr[i] = pci_resource_start(dev, 2);
1982 ConfigIO = pci_resource_start(dev, 1);
1983 if (dev->device == PCI_DEVICE_ID_URP8OCTA) {
1984 UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
1985
1986
1987
1988
1989 if (!
1990 (sInW(ConfigIO + _PCI_9030_GPIO_CTRL) &
1991 PCI_GPIO_CTRL_8PORT)) {
1992 str = "Quadcable";
1993 ports_per_aiop = 4;
1994 rocketModel[i].numPorts = 4;
1995 }
1996 }
1997 break;
1998 case PCI_DEVICE_ID_UPCI_RM3_8PORT:
1999 str = "8 ports";
2000 max_num_aiops = 1;
2001 rocketModel[i].model = MODEL_UPCI_RM3_8PORT;
2002 strcpy(rocketModel[i].modelString, "RocketModem III 8 port");
2003 rocketModel[i].numPorts = 8;
2004 rcktpt_io_addr[i] = pci_resource_start(dev, 2);
2005 UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
2006 ConfigIO = pci_resource_start(dev, 1);
2007 rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
2008 break;
2009 case PCI_DEVICE_ID_UPCI_RM3_4PORT:
2010 str = "4 ports";
2011 max_num_aiops = 1;
2012 rocketModel[i].model = MODEL_UPCI_RM3_4PORT;
2013 strcpy(rocketModel[i].modelString, "RocketModem III 4 port");
2014 rocketModel[i].numPorts = 4;
2015 rcktpt_io_addr[i] = pci_resource_start(dev, 2);
2016 UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
2017 ConfigIO = pci_resource_start(dev, 1);
2018 rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
2019 break;
2020 default:
2021 break;
2022 }
2023
2024 switch (rcktpt_type[i]) {
2025 case ROCKET_TYPE_MODEM:
2026 board_type = "RocketModem";
2027 break;
2028 case ROCKET_TYPE_MODEMII:
2029 board_type = "RocketModem II";
2030 break;
2031 case ROCKET_TYPE_MODEMIII:
2032 board_type = "RocketModem III";
2033 break;
2034 default:
2035 board_type = "RocketPort";
2036 break;
2037 }
2038
2039 if (fast_clock) {
2040 sClockPrescale = 0x12;
2041 rp_baud_base[i] = 921600;
2042 } else {
2043
2044
2045
2046
2047 if (support_low_speed) {
2048
2049 sClockPrescale = 0x19;
2050 rp_baud_base[i] = 230400;
2051 } else {
2052
2053 sClockPrescale = 0x14;
2054 rp_baud_base[i] = 460800;
2055 }
2056 }
2057
2058 for (aiop = 0; aiop < max_num_aiops; aiop++)
2059 aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x40);
2060 ctlp = sCtlNumToCtlPtr(i);
2061 num_aiops = sPCIInitController(ctlp, i, aiopio, max_num_aiops, ConfigIO, 0, FREQ_DIS, 0, altChanRingIndicator, UPCIRingInd);
2062 for (aiop = 0; aiop < max_num_aiops; aiop++)
2063 ctlp->AiopNumChan[aiop] = ports_per_aiop;
2064
2065 dev_info(&dev->dev, "comtrol PCI controller #%d found at "
2066 "address %04lx, %d AIOP(s) (%s), creating ttyR%d - %ld\n",
2067 i, rcktpt_io_addr[i], num_aiops, rocketModel[i].modelString,
2068 rocketModel[i].startingPortNumber,
2069 rocketModel[i].startingPortNumber + rocketModel[i].numPorts-1);
2070
2071 if (num_aiops <= 0) {
2072 rcktpt_io_addr[i] = 0;
2073 return (0);
2074 }
2075 is_PCI[i] = 1;
2076
2077
2078 for (aiop = 0; aiop < num_aiops; aiop++) {
2079 sResetAiopByNum(ctlp, aiop);
2080 num_chan = ports_per_aiop;
2081 for (chan = 0; chan < num_chan; chan++)
2082 init_r_port(i, aiop, chan, dev);
2083 }
2084
2085
2086 if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) ||
2087 (rcktpt_type[i] == ROCKET_TYPE_MODEMII) ||
2088 (rcktpt_type[i] == ROCKET_TYPE_MODEMIII)) {
2089 num_chan = ports_per_aiop;
2090 for (chan = 0; chan < num_chan; chan++)
2091 sPCIModemReset(ctlp, chan, 1);
2092 msleep(500);
2093 for (chan = 0; chan < num_chan; chan++)
2094 sPCIModemReset(ctlp, chan, 0);
2095 msleep(500);
2096 rmSpeakerReset(ctlp, rocketModel[i].model);
2097 }
2098 return (1);
2099}
2100
2101
2102
2103
2104
2105
2106
2107static int __init init_PCI(int boards_found)
2108{
2109 struct pci_dev *dev = NULL;
2110 int count = 0;
2111
2112
2113 while ((dev = pci_get_device(PCI_VENDOR_ID_RP, PCI_ANY_ID, dev))) {
2114 if (register_PCI(count + boards_found, dev))
2115 count++;
2116 }
2117 return (count);
2118}
2119
2120#endif
2121
2122
2123
2124
2125
2126
2127static int __init init_ISA(int i)
2128{
2129 int num_aiops, num_chan = 0, total_num_chan = 0;
2130 int aiop, chan;
2131 unsigned int aiopio[MAX_AIOPS_PER_BOARD];
2132 CONTROLLER_t *ctlp;
2133 char *type_string;
2134
2135
2136 if (rcktpt_io_addr[i] == 0)
2137 return (0);
2138
2139
2140 if (!request_region(rcktpt_io_addr[i], 64, "Comtrol RocketPort")) {
2141 printk(KERN_ERR "Unable to reserve IO region for configured "
2142 "ISA RocketPort at address 0x%lx, board not "
2143 "installed...\n", rcktpt_io_addr[i]);
2144 rcktpt_io_addr[i] = 0;
2145 return (0);
2146 }
2147
2148 ctlp = sCtlNumToCtlPtr(i);
2149
2150 ctlp->boardType = rcktpt_type[i];
2151
2152 switch (rcktpt_type[i]) {
2153 case ROCKET_TYPE_PC104:
2154 type_string = "(PC104)";
2155 break;
2156 case ROCKET_TYPE_MODEM:
2157 type_string = "(RocketModem)";
2158 break;
2159 case ROCKET_TYPE_MODEMII:
2160 type_string = "(RocketModem II)";
2161 break;
2162 default:
2163 type_string = "";
2164 break;
2165 }
2166
2167
2168
2169
2170
2171 if (support_low_speed) {
2172 sClockPrescale = 0x19;
2173 rp_baud_base[i] = 230400;
2174 } else {
2175 sClockPrescale = 0x14;
2176 rp_baud_base[i] = 460800;
2177 }
2178
2179 for (aiop = 0; aiop < MAX_AIOPS_PER_BOARD; aiop++)
2180 aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x400);
2181
2182 num_aiops = sInitController(ctlp, i, controller + (i * 0x400), aiopio, MAX_AIOPS_PER_BOARD, 0, FREQ_DIS, 0);
2183
2184 if (ctlp->boardType == ROCKET_TYPE_PC104) {
2185 sEnAiop(ctlp, 2);
2186 sEnAiop(ctlp, 3);
2187 }
2188
2189
2190 if (num_aiops <= 0) {
2191 release_region(rcktpt_io_addr[i], 64);
2192 rcktpt_io_addr[i] = 0;
2193 return (0);
2194 }
2195
2196 rocketModel[i].startingPortNumber = nextLineNumber;
2197
2198 for (aiop = 0; aiop < num_aiops; aiop++) {
2199 sResetAiopByNum(ctlp, aiop);
2200 sEnAiop(ctlp, aiop);
2201 num_chan = sGetAiopNumChan(ctlp, aiop);
2202 total_num_chan += num_chan;
2203 for (chan = 0; chan < num_chan; chan++)
2204 init_r_port(i, aiop, chan, NULL);
2205 }
2206 is_PCI[i] = 0;
2207 if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) || (rcktpt_type[i] == ROCKET_TYPE_MODEMII)) {
2208 num_chan = sGetAiopNumChan(ctlp, 0);
2209 total_num_chan = num_chan;
2210 for (chan = 0; chan < num_chan; chan++)
2211 sModemReset(ctlp, chan, 1);
2212 msleep(500);
2213 for (chan = 0; chan < num_chan; chan++)
2214 sModemReset(ctlp, chan, 0);
2215 msleep(500);
2216 strcpy(rocketModel[i].modelString, "RocketModem ISA");
2217 } else {
2218 strcpy(rocketModel[i].modelString, "RocketPort ISA");
2219 }
2220 rocketModel[i].numPorts = total_num_chan;
2221 rocketModel[i].model = MODEL_ISA;
2222
2223 printk(KERN_INFO "RocketPort ISA card #%d found at 0x%lx - %d AIOPs %s\n",
2224 i, rcktpt_io_addr[i], num_aiops, type_string);
2225
2226 printk(KERN_INFO "Installing %s, creating /dev/ttyR%d - %ld\n",
2227 rocketModel[i].modelString,
2228 rocketModel[i].startingPortNumber,
2229 rocketModel[i].startingPortNumber +
2230 rocketModel[i].numPorts - 1);
2231
2232 return (1);
2233}
2234
2235static const struct tty_operations rocket_ops = {
2236 .open = rp_open,
2237 .close = rp_close,
2238 .write = rp_write,
2239 .put_char = rp_put_char,
2240 .write_room = rp_write_room,
2241 .chars_in_buffer = rp_chars_in_buffer,
2242 .flush_buffer = rp_flush_buffer,
2243 .ioctl = rp_ioctl,
2244 .throttle = rp_throttle,
2245 .unthrottle = rp_unthrottle,
2246 .set_termios = rp_set_termios,
2247 .stop = rp_stop,
2248 .start = rp_start,
2249 .hangup = rp_hangup,
2250 .break_ctl = rp_break,
2251 .send_xchar = rp_send_xchar,
2252 .wait_until_sent = rp_wait_until_sent,
2253 .tiocmget = rp_tiocmget,
2254 .tiocmset = rp_tiocmset,
2255};
2256
2257static const struct tty_port_operations rocket_port_ops = {
2258 .carrier_raised = carrier_raised,
2259 .dtr_rts = dtr_rts,
2260};
2261
2262
2263
2264
2265static int __init rp_init(void)
2266{
2267 int ret = -ENOMEM, pci_boards_found, isa_boards_found, i;
2268
2269 printk(KERN_INFO "RocketPort device driver module, version %s, %s\n",
2270 ROCKET_VERSION, ROCKET_DATE);
2271
2272 rocket_driver = alloc_tty_driver(MAX_RP_PORTS);
2273 if (!rocket_driver)
2274 goto err;
2275
2276
2277
2278
2279
2280 if (board1) {
2281 if (controller == 0)
2282 controller = board1 + 0x40;
2283 } else {
2284 controller = 0;
2285 }
2286
2287
2288 if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) {
2289 printk(KERN_ERR "Unable to reserve IO region for first "
2290 "configured ISA RocketPort controller 0x%lx. "
2291 "Driver exiting\n", controller);
2292 ret = -EBUSY;
2293 goto err_tty;
2294 }
2295
2296
2297 rcktpt_io_addr[0] = board1;
2298 rcktpt_io_addr[1] = board2;
2299 rcktpt_io_addr[2] = board3;
2300 rcktpt_io_addr[3] = board4;
2301
2302 rcktpt_type[0] = modem1 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2303 rcktpt_type[0] = pc104_1[0] ? ROCKET_TYPE_PC104 : rcktpt_type[0];
2304 rcktpt_type[1] = modem2 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2305 rcktpt_type[1] = pc104_2[0] ? ROCKET_TYPE_PC104 : rcktpt_type[1];
2306 rcktpt_type[2] = modem3 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2307 rcktpt_type[2] = pc104_3[0] ? ROCKET_TYPE_PC104 : rcktpt_type[2];
2308 rcktpt_type[3] = modem4 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
2309 rcktpt_type[3] = pc104_4[0] ? ROCKET_TYPE_PC104 : rcktpt_type[3];
2310
2311
2312
2313
2314
2315
2316 rocket_driver->owner = THIS_MODULE;
2317 rocket_driver->flags = TTY_DRIVER_DYNAMIC_DEV;
2318 rocket_driver->name = "ttyR";
2319 rocket_driver->driver_name = "Comtrol RocketPort";
2320 rocket_driver->major = TTY_ROCKET_MAJOR;
2321 rocket_driver->minor_start = 0;
2322 rocket_driver->type = TTY_DRIVER_TYPE_SERIAL;
2323 rocket_driver->subtype = SERIAL_TYPE_NORMAL;
2324 rocket_driver->init_termios = tty_std_termios;
2325 rocket_driver->init_termios.c_cflag =
2326 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2327 rocket_driver->init_termios.c_ispeed = 9600;
2328 rocket_driver->init_termios.c_ospeed = 9600;
2329#ifdef ROCKET_SOFT_FLOW
2330 rocket_driver->flags |= TTY_DRIVER_REAL_RAW;
2331#endif
2332 tty_set_operations(rocket_driver, &rocket_ops);
2333
2334 ret = tty_register_driver(rocket_driver);
2335 if (ret < 0) {
2336 printk(KERN_ERR "Couldn't install tty RocketPort driver\n");
2337 goto err_tty;
2338 }
2339
2340#ifdef ROCKET_DEBUG_OPEN
2341 printk(KERN_INFO "RocketPort driver is major %d\n", rocket_driver.major);
2342#endif
2343
2344
2345
2346
2347
2348 isa_boards_found = 0;
2349 pci_boards_found = 0;
2350
2351 for (i = 0; i < NUM_BOARDS; i++) {
2352 if (init_ISA(i))
2353 isa_boards_found++;
2354 }
2355
2356#ifdef CONFIG_PCI
2357 if (isa_boards_found < NUM_BOARDS)
2358 pci_boards_found = init_PCI(isa_boards_found);
2359#endif
2360
2361 max_board = pci_boards_found + isa_boards_found;
2362
2363 if (max_board == 0) {
2364 printk(KERN_ERR "No rocketport ports found; unloading driver\n");
2365 ret = -ENXIO;
2366 goto err_ttyu;
2367 }
2368
2369 return 0;
2370err_ttyu:
2371 tty_unregister_driver(rocket_driver);
2372err_tty:
2373 put_tty_driver(rocket_driver);
2374err:
2375 return ret;
2376}
2377
2378
2379static void rp_cleanup_module(void)
2380{
2381 int retval;
2382 int i;
2383
2384 del_timer_sync(&rocket_timer);
2385
2386 retval = tty_unregister_driver(rocket_driver);
2387 if (retval)
2388 printk(KERN_ERR "Error %d while trying to unregister "
2389 "rocketport driver\n", -retval);
2390
2391 for (i = 0; i < MAX_RP_PORTS; i++)
2392 if (rp_table[i]) {
2393 tty_unregister_device(rocket_driver, i);
2394 kfree(rp_table[i]);
2395 }
2396
2397 put_tty_driver(rocket_driver);
2398
2399 for (i = 0; i < NUM_BOARDS; i++) {
2400 if (rcktpt_io_addr[i] <= 0 || is_PCI[i])
2401 continue;
2402 release_region(rcktpt_io_addr[i], 64);
2403 }
2404 if (controller)
2405 release_region(controller, 4);
2406}
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
2479 ByteIO_t * AiopIOList, int AiopIOListSize,
2480 int IRQNum, Byte_t Frequency, int PeriodicOnly)
2481{
2482 int i;
2483 ByteIO_t io;
2484 int done;
2485
2486 CtlP->AiopIntrBits = aiop_intr_bits;
2487 CtlP->AltChanRingIndicator = 0;
2488 CtlP->CtlNum = CtlNum;
2489 CtlP->CtlID = CTLID_0001;
2490 CtlP->BusType = isISA;
2491 CtlP->MBaseIO = MudbacIO;
2492 CtlP->MReg1IO = MudbacIO + 1;
2493 CtlP->MReg2IO = MudbacIO + 2;
2494 CtlP->MReg3IO = MudbacIO + 3;
2495#if 1
2496 CtlP->MReg2 = 0;
2497 CtlP->MReg3 = 0;
2498#else
2499 if (sIRQMap[IRQNum] == 0) {
2500 CtlP->MReg2 = 0;
2501 CtlP->MReg3 = 0;
2502 } else {
2503 CtlP->MReg2 = sIRQMap[IRQNum];
2504 CtlP->MReg3 = Frequency;
2505 if (PeriodicOnly) {
2506 CtlP->MReg3 |= PERIODIC_ONLY;
2507 }
2508 }
2509#endif
2510 sOutB(CtlP->MReg2IO, CtlP->MReg2);
2511 sOutB(CtlP->MReg3IO, CtlP->MReg3);
2512 sControllerEOI(CtlP);
2513
2514 CtlP->NumAiop = 0;
2515 for (i = done = 0; i < AiopIOListSize; i++) {
2516 io = AiopIOList[i];
2517 CtlP->AiopIO[i] = (WordIO_t) io;
2518 CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
2519 sOutB(CtlP->MReg2IO, CtlP->MReg2 | (i & 0x03));
2520 sOutB(MudbacIO, (Byte_t) (io >> 6));
2521 if (done)
2522 continue;
2523 sEnAiop(CtlP, i);
2524 CtlP->AiopID[i] = sReadAiopID(io);
2525 if (CtlP->AiopID[i] == AIOPID_NULL)
2526 done = 1;
2527 else {
2528 CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io);
2529 sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE);
2530 sOutB(io + _INDX_DATA, sClockPrescale);
2531 CtlP->NumAiop++;
2532 }
2533 sDisAiop(CtlP, i);
2534 }
2535
2536 if (CtlP->NumAiop == 0)
2537 return (-1);
2538 else
2539 return (CtlP->NumAiop);
2540}
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
2612 ByteIO_t * AiopIOList, int AiopIOListSize,
2613 WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
2614 int PeriodicOnly, int altChanRingIndicator,
2615 int UPCIRingInd)
2616{
2617 int i;
2618 ByteIO_t io;
2619
2620 CtlP->AltChanRingIndicator = altChanRingIndicator;
2621 CtlP->UPCIRingInd = UPCIRingInd;
2622 CtlP->CtlNum = CtlNum;
2623 CtlP->CtlID = CTLID_0001;
2624 CtlP->BusType = isPCI;
2625
2626 if (ConfigIO) {
2627 CtlP->isUPCI = 1;
2628 CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL;
2629 CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL;
2630 CtlP->AiopIntrBits = upci_aiop_intr_bits;
2631 } else {
2632 CtlP->isUPCI = 0;
2633 CtlP->PCIIO =
2634 (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC);
2635 CtlP->AiopIntrBits = aiop_intr_bits;
2636 }
2637
2638 sPCIControllerEOI(CtlP);
2639
2640 CtlP->NumAiop = 0;
2641 for (i = 0; i < AiopIOListSize; i++) {
2642 io = AiopIOList[i];
2643 CtlP->AiopIO[i] = (WordIO_t) io;
2644 CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
2645
2646 CtlP->AiopID[i] = sReadAiopID(io);
2647 if (CtlP->AiopID[i] == AIOPID_NULL)
2648 break;
2649
2650 CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io);
2651 sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE);
2652 sOutB(io + _INDX_DATA, sClockPrescale);
2653 CtlP->NumAiop++;
2654 }
2655
2656 if (CtlP->NumAiop == 0)
2657 return (-1);
2658 else
2659 return (CtlP->NumAiop);
2660}
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673static int sReadAiopID(ByteIO_t io)
2674{
2675 Byte_t AiopID;
2676
2677 sOutB(io + _CMD_REG, RESET_ALL);
2678 sOutB(io + _CMD_REG, 0x0);
2679 AiopID = sInW(io + _CHN_STAT0) & 0x07;
2680 if (AiopID == 0x06)
2681 return (1);
2682 else
2683 return (-1);
2684}
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699static int sReadAiopNumChan(WordIO_t io)
2700{
2701 Word_t x;
2702 static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 };
2703
2704
2705 out32((DWordIO_t) io + _INDX_ADDR, R);
2706 sOutW(io + _INDX_ADDR, 0);
2707 x = sInW(io + _INDX_DATA);
2708 sOutW(io + _INDX_ADDR, 0x4000);
2709 if (x != sInW(io + _INDX_DATA))
2710 return (8);
2711 else
2712 return (4);
2713}
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
2731 int ChanNum)
2732{
2733 int i;
2734 WordIO_t AiopIO;
2735 WordIO_t ChIOOff;
2736 Byte_t *ChR;
2737 Word_t ChOff;
2738 static Byte_t R[4];
2739 int brd9600;
2740
2741 if (ChanNum >= CtlP->AiopNumChan[AiopNum])
2742 return 0;
2743
2744
2745 ChP->CtlP = CtlP;
2746 ChP->ChanID = CtlP->AiopID[AiopNum];
2747 ChP->AiopNum = AiopNum;
2748 ChP->ChanNum = ChanNum;
2749
2750
2751 AiopIO = CtlP->AiopIO[AiopNum];
2752 ChP->Cmd = (ByteIO_t) AiopIO + _CMD_REG;
2753 ChP->IntChan = (ByteIO_t) AiopIO + _INT_CHAN;
2754 ChP->IntMask = (ByteIO_t) AiopIO + _INT_MASK;
2755 ChP->IndexAddr = (DWordIO_t) AiopIO + _INDX_ADDR;
2756 ChP->IndexData = AiopIO + _INDX_DATA;
2757
2758
2759 ChIOOff = AiopIO + ChP->ChanNum * 2;
2760 ChP->TxRxData = ChIOOff + _TD0;
2761 ChP->ChanStat = ChIOOff + _CHN_STAT0;
2762 ChP->TxRxCount = ChIOOff + _FIFO_CNT0;
2763 ChP->IntID = (ByteIO_t) AiopIO + ChP->ChanNum + _INT_ID0;
2764
2765
2766 for (i = 0; i < RDATASIZE; i += 4) {
2767 R[0] = RData[i];
2768 R[1] = RData[i + 1] + 0x10 * ChanNum;
2769 R[2] = RData[i + 2];
2770 R[3] = RData[i + 3];
2771 out32(ChP->IndexAddr, R);
2772 }
2773
2774 ChR = ChP->R;
2775 for (i = 0; i < RREGDATASIZE; i += 4) {
2776 ChR[i] = RRegData[i];
2777 ChR[i + 1] = RRegData[i + 1] + 0x10 * ChanNum;
2778 ChR[i + 2] = RRegData[i + 2];
2779 ChR[i + 3] = RRegData[i + 3];
2780 }
2781
2782
2783 ChOff = (Word_t) ChanNum *0x1000;
2784
2785 if (sClockPrescale == 0x14)
2786 brd9600 = 47;
2787 else
2788 brd9600 = 23;
2789
2790 ChP->BaudDiv[0] = (Byte_t) (ChOff + _BAUD);
2791 ChP->BaudDiv[1] = (Byte_t) ((ChOff + _BAUD) >> 8);
2792 ChP->BaudDiv[2] = (Byte_t) brd9600;
2793 ChP->BaudDiv[3] = (Byte_t) (brd9600 >> 8);
2794 out32(ChP->IndexAddr, ChP->BaudDiv);
2795
2796 ChP->TxControl[0] = (Byte_t) (ChOff + _TX_CTRL);
2797 ChP->TxControl[1] = (Byte_t) ((ChOff + _TX_CTRL) >> 8);
2798 ChP->TxControl[2] = 0;
2799 ChP->TxControl[3] = 0;
2800 out32(ChP->IndexAddr, ChP->TxControl);
2801
2802 ChP->RxControl[0] = (Byte_t) (ChOff + _RX_CTRL);
2803 ChP->RxControl[1] = (Byte_t) ((ChOff + _RX_CTRL) >> 8);
2804 ChP->RxControl[2] = 0;
2805 ChP->RxControl[3] = 0;
2806 out32(ChP->IndexAddr, ChP->RxControl);
2807
2808 ChP->TxEnables[0] = (Byte_t) (ChOff + _TX_ENBLS);
2809 ChP->TxEnables[1] = (Byte_t) ((ChOff + _TX_ENBLS) >> 8);
2810 ChP->TxEnables[2] = 0;
2811 ChP->TxEnables[3] = 0;
2812 out32(ChP->IndexAddr, ChP->TxEnables);
2813
2814 ChP->TxCompare[0] = (Byte_t) (ChOff + _TXCMP1);
2815 ChP->TxCompare[1] = (Byte_t) ((ChOff + _TXCMP1) >> 8);
2816 ChP->TxCompare[2] = 0;
2817 ChP->TxCompare[3] = 0;
2818 out32(ChP->IndexAddr, ChP->TxCompare);
2819
2820 ChP->TxReplace1[0] = (Byte_t) (ChOff + _TXREP1B1);
2821 ChP->TxReplace1[1] = (Byte_t) ((ChOff + _TXREP1B1) >> 8);
2822 ChP->TxReplace1[2] = 0;
2823 ChP->TxReplace1[3] = 0;
2824 out32(ChP->IndexAddr, ChP->TxReplace1);
2825
2826 ChP->TxReplace2[0] = (Byte_t) (ChOff + _TXREP2);
2827 ChP->TxReplace2[1] = (Byte_t) ((ChOff + _TXREP2) >> 8);
2828 ChP->TxReplace2[2] = 0;
2829 ChP->TxReplace2[3] = 0;
2830 out32(ChP->IndexAddr, ChP->TxReplace2);
2831
2832 ChP->TxFIFOPtrs = ChOff + _TXF_OUTP;
2833 ChP->TxFIFO = ChOff + _TX_FIFO;
2834
2835 sOutB(ChP->Cmd, (Byte_t) ChanNum | RESTXFCNT);
2836 sOutB(ChP->Cmd, (Byte_t) ChanNum);
2837 sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs);
2838 sOutW(ChP->IndexData, 0);
2839 ChP->RxFIFOPtrs = ChOff + _RXF_OUTP;
2840 ChP->RxFIFO = ChOff + _RX_FIFO;
2841
2842 sOutB(ChP->Cmd, (Byte_t) ChanNum | RESRXFCNT);
2843 sOutB(ChP->Cmd, (Byte_t) ChanNum);
2844 sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs);
2845 sOutW(ChP->IndexData, 0);
2846 sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2);
2847 sOutW(ChP->IndexData, 0);
2848 ChP->TxPrioCnt = ChOff + _TXP_CNT;
2849 sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioCnt);
2850 sOutB(ChP->IndexData, 0);
2851 ChP->TxPrioPtr = ChOff + _TXP_PNTR;
2852 sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioPtr);
2853 sOutB(ChP->IndexData, 0);
2854 ChP->TxPrioBuf = ChOff + _TXP_BUF;
2855 sEnRxProcessor(ChP);
2856
2857 return 1;
2858}
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878static void sStopRxProcessor(CHANNEL_T * ChP)
2879{
2880 Byte_t R[4];
2881
2882 R[0] = ChP->R[0];
2883 R[1] = ChP->R[1];
2884 R[2] = 0x0a;
2885 R[3] = ChP->R[3];
2886 out32(ChP->IndexAddr, R);
2887}
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903static void sFlushRxFIFO(CHANNEL_T * ChP)
2904{
2905 int i;
2906 Byte_t Ch;
2907 int RxFIFOEnabled;
2908
2909 if (sGetRxCnt(ChP) == 0)
2910 return;
2911
2912 RxFIFOEnabled = 0;
2913 if (ChP->R[0x32] == 0x08) {
2914 RxFIFOEnabled = 1;
2915 sDisRxFIFO(ChP);
2916 for (i = 0; i < 2000 / 200; i++)
2917 sInB(ChP->IntChan);
2918 }
2919 sGetChanStatus(ChP);
2920 Ch = (Byte_t) sGetChanNum(ChP);
2921 sOutB(ChP->Cmd, Ch | RESRXFCNT);
2922 sOutB(ChP->Cmd, Ch);
2923 sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs);
2924 sOutW(ChP->IndexData, 0);
2925 sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2);
2926 sOutW(ChP->IndexData, 0);
2927 if (RxFIFOEnabled)
2928 sEnRxFIFO(ChP);
2929}
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945static void sFlushTxFIFO(CHANNEL_T * ChP)
2946{
2947 int i;
2948 Byte_t Ch;
2949 int TxEnabled;
2950
2951 if (sGetTxCnt(ChP) == 0)
2952 return;
2953
2954 TxEnabled = 0;
2955 if (ChP->TxControl[3] & TX_ENABLE) {
2956 TxEnabled = 1;
2957 sDisTransmit(ChP);
2958 }
2959 sStopRxProcessor(ChP);
2960 for (i = 0; i < 4000 / 200; i++)
2961 sInB(ChP->IntChan);
2962 Ch = (Byte_t) sGetChanNum(ChP);
2963 sOutB(ChP->Cmd, Ch | RESTXFCNT);
2964 sOutB(ChP->Cmd, Ch);
2965 sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs);
2966 sOutW(ChP->IndexData, 0);
2967 if (TxEnabled)
2968 sEnTransmit(ChP);
2969 sStartRxProcessor(ChP);
2970}
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
2986{
2987 Byte_t DWBuf[4];
2988 Word_t *WordPtr;
2989 register DWordIO_t IndexAddr;
2990
2991 if (sGetTxCnt(ChP) > 1) {
2992 IndexAddr = ChP->IndexAddr;
2993 sOutW((WordIO_t) IndexAddr, ChP->TxPrioCnt);
2994 if (sInB((ByteIO_t) ChP->IndexData) & PRI_PEND)
2995 return (0);
2996
2997 WordPtr = (Word_t *) (&DWBuf[0]);
2998 *WordPtr = ChP->TxPrioBuf;
2999
3000 DWBuf[2] = Data;
3001 out32(IndexAddr, DWBuf);
3002
3003 *WordPtr = ChP->TxPrioCnt;
3004
3005 DWBuf[2] = PRI_PEND + 1;
3006 DWBuf[3] = 0;
3007 out32(IndexAddr, DWBuf);
3008 } else {
3009
3010 sWriteTxByte(sGetTxRxDataIO(ChP), Data);
3011 }
3012 return (1);
3013}
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
3048{
3049 Byte_t Mask;
3050
3051 ChP->RxControl[2] |=
3052 ((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
3053
3054 out32(ChP->IndexAddr, ChP->RxControl);
3055
3056 ChP->TxControl[2] |= ((Byte_t) Flags & TXINT_EN);
3057
3058 out32(ChP->IndexAddr, ChP->TxControl);
3059
3060 if (Flags & CHANINT_EN) {
3061 Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum];
3062 sOutB(ChP->IntMask, Mask);
3063 }
3064}
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
3092{
3093 Byte_t Mask;
3094
3095 ChP->RxControl[2] &=
3096 ~((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
3097 out32(ChP->IndexAddr, ChP->RxControl);
3098 ChP->TxControl[2] &= ~((Byte_t) Flags & TXINT_EN);
3099 out32(ChP->IndexAddr, ChP->TxControl);
3100
3101 if (Flags & CHANINT_EN) {
3102 Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum];
3103 sOutB(ChP->IntMask, Mask);
3104 }
3105}
3106
3107static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
3108{
3109 sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum);
3110}
3111
3112
3113
3114
3115
3116static void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
3117{
3118 ByteIO_t addr;
3119 Byte_t val;
3120
3121 addr = CtlP->AiopIO[0] + 0x400;
3122 val = sInB(CtlP->MReg3IO);
3123
3124 if ((val & 2) == 0) {
3125 val = sInB(CtlP->MReg2IO);
3126 sOutB(CtlP->MReg2IO, (val & 0xfc) | (1 & 0x03));
3127 sOutB(CtlP->MBaseIO, (unsigned char) (addr >> 6));
3128 }
3129
3130 sEnAiop(CtlP, 1);
3131 if (!on)
3132 addr += 8;
3133 sOutB(addr + chan, 0);
3134 sDisAiop(CtlP, 1);
3135}
3136
3137
3138
3139
3140
3141static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
3142{
3143 ByteIO_t addr;
3144
3145 addr = CtlP->AiopIO[0] + 0x40;
3146 if (!on)
3147 addr += 8;
3148 sOutB(addr + chan, 0);
3149}
3150
3151
3152static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model)
3153{
3154 ByteIO_t addr;
3155
3156
3157 if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) {
3158 addr = CtlP->AiopIO[0] + 0x4F;
3159 sOutB(addr, 0);
3160 }
3161
3162
3163 if ((model == MODEL_UPCI_RM3_8PORT)
3164 || (model == MODEL_UPCI_RM3_4PORT)) {
3165 addr = CtlP->AiopIO[0] + 0x88;
3166 sOutB(addr, 0);
3167 }
3168}
3169
3170
3171static unsigned char GetLineNumber(int ctrl, int aiop, int ch)
3172{
3173 return lineNumbers[(ctrl << 5) | (aiop << 3) | ch];
3174}
3175
3176
3177
3178
3179
3180
3181static unsigned char SetLineNumber(int ctrl, int aiop, int ch)
3182{
3183 lineNumbers[(ctrl << 5) | (aiop << 3) | ch] = nextLineNumber++;
3184 return (nextLineNumber - 1);
3185}
3186