- Kai Germaschewski: ymfpci cleanups and resource leak fixes
[davej-history.git] / drivers / char / riscom8.c
blobb60df303b11c004127fa3be97b7779cd0c7870b0
1 /*
2 * linux/drivers/char/riscom.c -- RISCom/8 multiport serial driver.
4 * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com)
6 * This code is loosely based on the Linux serial driver, written by
7 * Linus Torvalds, Theodore T'so and others. The RISCom/8 card
8 * programming info was obtained from various drivers for other OSes
9 * (FreeBSD, ISC, etc), but no source code from those drivers were
10 * directly included in this driver.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * Revision 1.0
30 #include <linux/module.h>
32 #include <asm/io.h>
33 #include <linux/kernel.h>
34 #include <linux/sched.h>
35 #include <linux/ioport.h>
36 #include <linux/interrupt.h>
37 #include <linux/errno.h>
38 #include <linux/tty.h>
39 #include <linux/mm.h>
40 #include <linux/serial.h>
41 #include <linux/fcntl.h>
42 #include <linux/major.h>
43 #include <linux/init.h>
45 #include <asm/uaccess.h>
47 #include "riscom8.h"
48 #include "riscom8_reg.h"
50 /* Am I paranoid or not ? ;-) */
51 #define RISCOM_PARANOIA_CHECK
53 /*
54 * Crazy InteliCom/8 boards sometimes has swapped CTS & DSR signals.
55 * You can slightly speed up things by #undefing the following option,
56 * if you are REALLY sure that your board is correct one.
59 #define RISCOM_BRAIN_DAMAGED_CTS
61 /*
62 * The following defines are mostly for testing purposes. But if you need
63 * some nice reporting in your syslog, you can define them also.
65 #undef RC_REPORT_FIFO
66 #undef RC_REPORT_OVERRUN
69 #define RISCOM_LEGAL_FLAGS \
70 (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \
71 ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \
72 ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
74 #ifndef MIN
75 #define MIN(a,b) ((a) < (b) ? (a) : (b))
76 #endif
78 #define RS_EVENT_WRITE_WAKEUP 0
80 static DECLARE_TASK_QUEUE(tq_riscom);
82 #define RISCOM_TYPE_NORMAL 1
83 #define RISCOM_TYPE_CALLOUT 2
85 static struct riscom_board * IRQ_to_board[16];
86 static struct tty_driver riscom_driver, riscom_callout_driver;
87 static int riscom_refcount;
88 static struct tty_struct * riscom_table[RC_NBOARD * RC_NPORT];
89 static struct termios * riscom_termios[RC_NBOARD * RC_NPORT];
90 static struct termios * riscom_termios_locked[RC_NBOARD * RC_NPORT];
91 static unsigned char * tmp_buf;
92 static DECLARE_MUTEX(tmp_buf_sem);
94 static unsigned long baud_table[] = {
95 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
96 9600, 19200, 38400, 57600, 76800, 0,
99 static struct riscom_board rc_board[RC_NBOARD] = {
100 { 0, RC_IOBASE1, 0, },
101 { 0, RC_IOBASE2, 0, },
102 { 0, RC_IOBASE3, 0, },
103 { 0, RC_IOBASE4, 0, },
106 static struct riscom_port rc_port[RC_NBOARD * RC_NPORT];
108 /* RISCom/8 I/O ports addresses (without address translation) */
109 static unsigned short rc_ioport[] = {
110 #if 1
111 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c,
112 #else
113 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, 0x10,
114 0x11, 0x12, 0x18, 0x28, 0x31, 0x32, 0x39, 0x3a, 0x40, 0x41, 0x61, 0x62,
115 0x63, 0x64, 0x6b, 0x70, 0x71, 0x78, 0x7a, 0x7b, 0x7f, 0x100, 0x101
116 #endif
118 #define RC_NIOPORT (sizeof(rc_ioport) / sizeof(rc_ioport[0]))
121 static inline int rc_paranoia_check(struct riscom_port const * port,
122 kdev_t device, const char *routine)
124 #ifdef RISCOM_PARANOIA_CHECK
125 static const char *badmagic =
126 "rc: Warning: bad riscom port magic number for device %s in %s\n";
127 static const char *badinfo =
128 "rc: Warning: null riscom port for device %s in %s\n";
130 if (!port) {
131 printk(badinfo, kdevname(device), routine);
132 return 1;
134 if (port->magic != RISCOM8_MAGIC) {
135 printk(badmagic, kdevname(device), routine);
136 return 1;
138 #endif
139 return 0;
144 * Service functions for RISCom/8 driver.
148 /* Get board number from pointer */
149 static inline int board_No (struct riscom_board const * bp)
151 return bp - rc_board;
154 /* Get port number from pointer */
155 static inline int port_No (struct riscom_port const * port)
157 return RC_PORT(port - rc_port);
160 /* Get pointer to board from pointer to port */
161 static inline struct riscom_board * port_Board(struct riscom_port const * port)
163 return &rc_board[RC_BOARD(port - rc_port)];
166 /* Input Byte from CL CD180 register */
167 static inline unsigned char rc_in(struct riscom_board const * bp, unsigned short reg)
169 return inb(bp->base + RC_TO_ISA(reg));
172 /* Output Byte to CL CD180 register */
173 static inline void rc_out(struct riscom_board const * bp, unsigned short reg,
174 unsigned char val)
176 outb(val, bp->base + RC_TO_ISA(reg));
179 /* Wait for Channel Command Register ready */
180 static inline void rc_wait_CCR(struct riscom_board const * bp)
182 unsigned long delay;
184 /* FIXME: need something more descriptive then 100000 :) */
185 for (delay = 100000; delay; delay--)
186 if (!rc_in(bp, CD180_CCR))
187 return;
189 printk("rc%d: Timeout waiting for CCR.\n", board_No(bp));
193 * RISCom/8 probe functions.
196 static inline int rc_check_io_range(struct riscom_board * const bp)
198 int i;
200 for (i = 0; i < RC_NIOPORT; i++)
201 if (check_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1)) {
202 printk("rc%d: Skipping probe at 0x%03x. I/O address in use.\n",
203 board_No(bp), bp->base);
204 return 1;
206 return 0;
209 static inline void rc_request_io_range(struct riscom_board * const bp)
211 int i;
213 for (i = 0; i < RC_NIOPORT; i++)
214 request_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1, "RISCom/8" );
217 static inline void rc_release_io_range(struct riscom_board * const bp)
219 int i;
221 for (i = 0; i < RC_NIOPORT; i++)
222 release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1);
226 /* Must be called with enabled interrupts */
227 static inline void rc_long_delay(unsigned long delay)
229 unsigned long i;
231 for (i = jiffies + delay; time_after(i,jiffies); ) ;
234 /* Reset and setup CD180 chip */
235 static void __init rc_init_CD180(struct riscom_board const * bp)
237 unsigned long flags;
239 save_flags(flags); cli();
240 rc_out(bp, RC_CTOUT, 0); /* Clear timeout */
241 rc_wait_CCR(bp); /* Wait for CCR ready */
242 rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */
243 sti();
244 rc_long_delay(HZ/20); /* Delay 0.05 sec */
245 cli();
246 rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */
247 rc_out(bp, CD180_GICR, 0); /* Clear all bits */
248 rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */
249 rc_out(bp, CD180_PILR2, RC_ACK_TINT); /* Prio for transmitter intr */
250 rc_out(bp, CD180_PILR3, RC_ACK_RINT); /* Prio for receiver intr */
252 /* Setting up prescaler. We need 4 ticks per 1 ms */
253 rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8);
254 rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff);
256 restore_flags(flags);
259 /* Main probing routine, also sets irq. */
260 static int __init rc_probe(struct riscom_board *bp)
262 unsigned char val1, val2;
263 int irqs = 0;
264 int retries;
266 bp->irq = 0;
268 if (rc_check_io_range(bp))
269 return 1;
271 /* Are the I/O ports here ? */
272 rc_out(bp, CD180_PPRL, 0x5a);
273 outb(0xff, 0x80);
274 val1 = rc_in(bp, CD180_PPRL);
275 rc_out(bp, CD180_PPRL, 0xa5);
276 outb(0x00, 0x80);
277 val2 = rc_in(bp, CD180_PPRL);
279 if ((val1 != 0x5a) || (val2 != 0xa5)) {
280 printk("rc%d: RISCom/8 Board at 0x%03x not found.\n",
281 board_No(bp), bp->base);
282 return 1;
285 /* It's time to find IRQ for this board */
286 for (retries = 0; retries < 5 && irqs <= 0; retries++) {
287 irqs = probe_irq_on();
288 rc_init_CD180(bp); /* Reset CD180 chip */
289 rc_out(bp, CD180_CAR, 2); /* Select port 2 */
290 rc_wait_CCR(bp);
291 rc_out(bp, CD180_CCR, CCR_TXEN); /* Enable transmitter */
292 rc_out(bp, CD180_IER, IER_TXRDY); /* Enable tx empty intr */
293 rc_long_delay(HZ/20);
294 irqs = probe_irq_off(irqs);
295 val1 = rc_in(bp, RC_BSR); /* Get Board Status reg */
296 val2 = rc_in(bp, RC_ACK_TINT); /* ACK interrupt */
297 rc_init_CD180(bp); /* Reset CD180 again */
299 if ((val1 & RC_BSR_TINT) || (val2 != (RC_ID | GIVR_IT_TX))) {
300 printk("rc%d: RISCom/8 Board at 0x%03x not found.\n",
301 board_No(bp), bp->base);
302 return 1;
306 if (irqs <= 0) {
307 printk("rc%d: Can't find IRQ for RISCom/8 board at 0x%03x.\n",
308 board_No(bp), bp->base);
309 return 1;
311 rc_request_io_range(bp);
312 bp->irq = irqs;
313 bp->flags |= RC_BOARD_PRESENT;
315 printk("rc%d: RISCom/8 Rev. %c board detected at 0x%03x, IRQ %d.\n",
316 board_No(bp),
317 (rc_in(bp, CD180_GFRCR) & 0x0f) + 'A', /* Board revision */
318 bp->base, bp->irq);
320 return 0;
325 * Interrupt processing routines.
329 static inline void rc_mark_event(struct riscom_port * port, int event)
332 * I'm not quite happy with current scheme all serial
333 * drivers use their own BH routine.
334 * It seems this easily can be done with one BH routine
335 * serving for all serial drivers.
336 * For now I must introduce another one - RISCOM8_BH.
337 * Still hope this will be changed in near future.
339 set_bit(event, &port->event);
340 queue_task(&port->tqueue, &tq_riscom);
341 mark_bh(RISCOM8_BH);
344 static inline struct riscom_port * rc_get_port(struct riscom_board const * bp,
345 unsigned char const * what)
347 unsigned char channel;
348 struct riscom_port * port;
350 channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF;
351 if (channel < CD180_NCH) {
352 port = &rc_port[board_No(bp) * RC_NPORT + channel];
353 if (port->flags & ASYNC_INITIALIZED) {
354 return port;
357 printk("rc%d: %s interrupt from invalid port %d\n",
358 board_No(bp), what, channel);
359 return NULL;
362 static inline void rc_receive_exc(struct riscom_board const * bp)
364 struct riscom_port *port;
365 struct tty_struct *tty;
366 unsigned char status;
367 unsigned char ch;
369 if (!(port = rc_get_port(bp, "Receive")))
370 return;
372 tty = port->tty;
373 if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
374 printk("rc%d: port %d: Working around flip buffer overflow.\n",
375 board_No(bp), port_No(port));
376 return;
379 #ifdef RC_REPORT_OVERRUN
380 status = rc_in(bp, CD180_RCSR);
381 if (status & RCSR_OE) {
382 port->overrun++;
383 #if 0
384 printk("rc%d: port %d: Overrun. Total %ld overruns.\n",
385 board_No(bp), port_No(port), port->overrun);
386 #endif
388 status &= port->mark_mask;
389 #else
390 status = rc_in(bp, CD180_RCSR) & port->mark_mask;
391 #endif
392 ch = rc_in(bp, CD180_RDR);
393 if (!status) {
394 return;
396 if (status & RCSR_TOUT) {
397 printk("rc%d: port %d: Receiver timeout. Hardware problems ?\n",
398 board_No(bp), port_No(port));
399 return;
401 } else if (status & RCSR_BREAK) {
402 printk("rc%d: port %d: Handling break...\n",
403 board_No(bp), port_No(port));
404 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
405 if (port->flags & ASYNC_SAK)
406 do_SAK(tty);
408 } else if (status & RCSR_PE)
409 *tty->flip.flag_buf_ptr++ = TTY_PARITY;
411 else if (status & RCSR_FE)
412 *tty->flip.flag_buf_ptr++ = TTY_FRAME;
414 else if (status & RCSR_OE)
415 *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
417 else
418 *tty->flip.flag_buf_ptr++ = 0;
420 *tty->flip.char_buf_ptr++ = ch;
421 tty->flip.count++;
422 queue_task(&tty->flip.tqueue, &tq_timer);
425 static inline void rc_receive(struct riscom_board const * bp)
427 struct riscom_port *port;
428 struct tty_struct *tty;
429 unsigned char count;
431 if (!(port = rc_get_port(bp, "Receive")))
432 return;
434 tty = port->tty;
436 count = rc_in(bp, CD180_RDCR);
438 #ifdef RC_REPORT_FIFO
439 port->hits[count > 8 ? 9 : count]++;
440 #endif
442 while (count--) {
443 if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
444 printk("rc%d: port %d: Working around flip buffer overflow.\n",
445 board_No(bp), port_No(port));
446 break;
448 *tty->flip.char_buf_ptr++ = rc_in(bp, CD180_RDR);
449 *tty->flip.flag_buf_ptr++ = 0;
450 tty->flip.count++;
452 queue_task(&tty->flip.tqueue, &tq_timer);
455 static inline void rc_transmit(struct riscom_board const * bp)
457 struct riscom_port *port;
458 struct tty_struct *tty;
459 unsigned char count;
462 if (!(port = rc_get_port(bp, "Transmit")))
463 return;
465 tty = port->tty;
467 if (port->IER & IER_TXEMPTY) {
468 /* FIFO drained */
469 rc_out(bp, CD180_CAR, port_No(port));
470 port->IER &= ~IER_TXEMPTY;
471 rc_out(bp, CD180_IER, port->IER);
472 return;
475 if ((port->xmit_cnt <= 0 && !port->break_length)
476 || tty->stopped || tty->hw_stopped) {
477 rc_out(bp, CD180_CAR, port_No(port));
478 port->IER &= ~IER_TXRDY;
479 rc_out(bp, CD180_IER, port->IER);
480 return;
483 if (port->break_length) {
484 if (port->break_length > 0) {
485 if (port->COR2 & COR2_ETC) {
486 rc_out(bp, CD180_TDR, CD180_C_ESC);
487 rc_out(bp, CD180_TDR, CD180_C_SBRK);
488 port->COR2 &= ~COR2_ETC;
490 count = MIN(port->break_length, 0xff);
491 rc_out(bp, CD180_TDR, CD180_C_ESC);
492 rc_out(bp, CD180_TDR, CD180_C_DELAY);
493 rc_out(bp, CD180_TDR, count);
494 if (!(port->break_length -= count))
495 port->break_length--;
496 } else {
497 rc_out(bp, CD180_TDR, CD180_C_ESC);
498 rc_out(bp, CD180_TDR, CD180_C_EBRK);
499 rc_out(bp, CD180_COR2, port->COR2);
500 rc_wait_CCR(bp);
501 rc_out(bp, CD180_CCR, CCR_CORCHG2);
502 port->break_length = 0;
504 return;
507 count = CD180_NFIFO;
508 do {
509 rc_out(bp, CD180_TDR, port->xmit_buf[port->xmit_tail++]);
510 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
511 if (--port->xmit_cnt <= 0)
512 break;
513 } while (--count > 0);
515 if (port->xmit_cnt <= 0) {
516 rc_out(bp, CD180_CAR, port_No(port));
517 port->IER &= ~IER_TXRDY;
518 rc_out(bp, CD180_IER, port->IER);
520 if (port->xmit_cnt <= port->wakeup_chars)
521 rc_mark_event(port, RS_EVENT_WRITE_WAKEUP);
524 static inline void rc_check_modem(struct riscom_board const * bp)
526 struct riscom_port *port;
527 struct tty_struct *tty;
528 unsigned char mcr;
530 if (!(port = rc_get_port(bp, "Modem")))
531 return;
533 tty = port->tty;
535 mcr = rc_in(bp, CD180_MCR);
536 if (mcr & MCR_CDCHG) {
537 if (rc_in(bp, CD180_MSVR) & MSVR_CD)
538 wake_up_interruptible(&port->open_wait);
539 else if (!((port->flags & ASYNC_CALLOUT_ACTIVE) &&
540 (port->flags & ASYNC_CALLOUT_NOHUP))) {
541 MOD_INC_USE_COUNT;
542 if (schedule_task(&port->tqueue_hangup) == 0)
543 MOD_DEC_USE_COUNT;
547 #ifdef RISCOM_BRAIN_DAMAGED_CTS
548 if (mcr & MCR_CTSCHG) {
549 if (rc_in(bp, CD180_MSVR) & MSVR_CTS) {
550 tty->hw_stopped = 0;
551 port->IER |= IER_TXRDY;
552 if (port->xmit_cnt <= port->wakeup_chars)
553 rc_mark_event(port, RS_EVENT_WRITE_WAKEUP);
554 } else {
555 tty->hw_stopped = 1;
556 port->IER &= ~IER_TXRDY;
558 rc_out(bp, CD180_IER, port->IER);
560 if (mcr & MCR_DSRCHG) {
561 if (rc_in(bp, CD180_MSVR) & MSVR_DSR) {
562 tty->hw_stopped = 0;
563 port->IER |= IER_TXRDY;
564 if (port->xmit_cnt <= port->wakeup_chars)
565 rc_mark_event(port, RS_EVENT_WRITE_WAKEUP);
566 } else {
567 tty->hw_stopped = 1;
568 port->IER &= ~IER_TXRDY;
570 rc_out(bp, CD180_IER, port->IER);
572 #endif /* RISCOM_BRAIN_DAMAGED_CTS */
574 /* Clear change bits */
575 rc_out(bp, CD180_MCR, 0);
578 /* The main interrupt processing routine */
579 static void rc_interrupt(int irq, void * dev_id, struct pt_regs * regs)
581 unsigned char status;
582 unsigned char ack;
583 struct riscom_board *bp;
584 unsigned long loop = 0;
586 bp = IRQ_to_board[irq];
588 if (!bp || !(bp->flags & RC_BOARD_ACTIVE)) {
589 return;
592 while ((++loop < 16) && ((status = ~(rc_in(bp, RC_BSR))) &
593 (RC_BSR_TOUT | RC_BSR_TINT |
594 RC_BSR_MINT | RC_BSR_RINT))) {
596 if (status & RC_BSR_TOUT)
597 printk("rc%d: Got timeout. Hardware error ?\n", board_No(bp));
599 else if (status & RC_BSR_RINT) {
600 ack = rc_in(bp, RC_ACK_RINT);
602 if (ack == (RC_ID | GIVR_IT_RCV))
603 rc_receive(bp);
604 else if (ack == (RC_ID | GIVR_IT_REXC))
605 rc_receive_exc(bp);
606 else
607 printk("rc%d: Bad receive ack 0x%02x.\n",
608 board_No(bp), ack);
610 } else if (status & RC_BSR_TINT) {
611 ack = rc_in(bp, RC_ACK_TINT);
613 if (ack == (RC_ID | GIVR_IT_TX))
614 rc_transmit(bp);
615 else
616 printk("rc%d: Bad transmit ack 0x%02x.\n",
617 board_No(bp), ack);
619 } else /* if (status & RC_BSR_MINT) */ {
620 ack = rc_in(bp, RC_ACK_MINT);
622 if (ack == (RC_ID | GIVR_IT_MODEM))
623 rc_check_modem(bp);
624 else
625 printk("rc%d: Bad modem ack 0x%02x.\n",
626 board_No(bp), ack);
630 rc_out(bp, CD180_EOIR, 0); /* Mark end of interrupt */
631 rc_out(bp, RC_CTOUT, 0); /* Clear timeout flag */
636 * Routines for open & close processing.
639 /* Called with disabled interrupts */
640 static inline int rc_setup_board(struct riscom_board * bp)
642 int error;
644 if (bp->flags & RC_BOARD_ACTIVE)
645 return 0;
647 error = request_irq(bp->irq, rc_interrupt, SA_INTERRUPT, "RISCom/8", NULL);
648 if (error)
649 return error;
651 rc_out(bp, RC_CTOUT, 0); /* Just in case */
652 bp->DTR = ~0;
653 rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */
655 IRQ_to_board[bp->irq] = bp;
656 bp->flags |= RC_BOARD_ACTIVE;
658 MOD_INC_USE_COUNT;
659 return 0;
662 /* Called with disabled interrupts */
663 static inline void rc_shutdown_board(struct riscom_board *bp)
665 if (!(bp->flags & RC_BOARD_ACTIVE))
666 return;
668 bp->flags &= ~RC_BOARD_ACTIVE;
670 free_irq(bp->irq, NULL);
671 IRQ_to_board[bp->irq] = NULL;
673 bp->DTR = ~0;
674 rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */
676 MOD_DEC_USE_COUNT;
680 * Setting up port characteristics.
681 * Must be called with disabled interrupts
683 static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
685 struct tty_struct *tty;
686 unsigned long baud;
687 long tmp;
688 unsigned char cor1 = 0, cor3 = 0;
689 unsigned char mcor1 = 0, mcor2 = 0;
691 if (!(tty = port->tty) || !tty->termios)
692 return;
694 port->IER = 0;
695 port->COR2 = 0;
696 port->MSVR = MSVR_RTS;
698 baud = C_BAUD(tty);
700 if (baud & CBAUDEX) {
701 baud &= ~CBAUDEX;
702 if (baud < 1 || baud > 2)
703 port->tty->termios->c_cflag &= ~CBAUDEX;
704 else
705 baud += 15;
707 if (baud == 15) {
708 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
709 baud ++;
710 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
711 baud += 2;
714 /* Select port on the board */
715 rc_out(bp, CD180_CAR, port_No(port));
717 if (!baud_table[baud]) {
718 /* Drop DTR & exit */
719 bp->DTR |= (1u << port_No(port));
720 rc_out(bp, RC_DTR, bp->DTR);
721 return;
722 } else {
723 /* Set DTR on */
724 bp->DTR &= ~(1u << port_No(port));
725 rc_out(bp, RC_DTR, bp->DTR);
729 * Now we must calculate some speed depended things
732 /* Set baud rate for port */
733 tmp = (((RC_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
734 CD180_TPC/2) / CD180_TPC);
736 rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff);
737 rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff);
738 rc_out(bp, CD180_RBPRL, tmp & 0xff);
739 rc_out(bp, CD180_TBPRL, tmp & 0xff);
741 baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */
743 /* Two timer ticks seems enough to wakeup something like SLIP driver */
744 tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;
745 port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
746 SERIAL_XMIT_SIZE - 1 : tmp);
748 /* Receiver timeout will be transmission time for 1.5 chars */
749 tmp = (RISCOM_TPS + RISCOM_TPS/2 + baud/2) / baud;
750 tmp = (tmp > 0xff) ? 0xff : tmp;
751 rc_out(bp, CD180_RTPR, tmp);
753 switch (C_CSIZE(tty)) {
754 case CS5:
755 cor1 |= COR1_5BITS;
756 break;
757 case CS6:
758 cor1 |= COR1_6BITS;
759 break;
760 case CS7:
761 cor1 |= COR1_7BITS;
762 break;
763 case CS8:
764 cor1 |= COR1_8BITS;
765 break;
768 if (C_CSTOPB(tty))
769 cor1 |= COR1_2SB;
771 cor1 |= COR1_IGNORE;
772 if (C_PARENB(tty)) {
773 cor1 |= COR1_NORMPAR;
774 if (C_PARODD(tty))
775 cor1 |= COR1_ODDP;
776 if (I_INPCK(tty))
777 cor1 &= ~COR1_IGNORE;
779 /* Set marking of some errors */
780 port->mark_mask = RCSR_OE | RCSR_TOUT;
781 if (I_INPCK(tty))
782 port->mark_mask |= RCSR_FE | RCSR_PE;
783 if (I_BRKINT(tty) || I_PARMRK(tty))
784 port->mark_mask |= RCSR_BREAK;
785 if (I_IGNPAR(tty))
786 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
787 if (I_IGNBRK(tty)) {
788 port->mark_mask &= ~RCSR_BREAK;
789 if (I_IGNPAR(tty))
790 /* Real raw mode. Ignore all */
791 port->mark_mask &= ~RCSR_OE;
793 /* Enable Hardware Flow Control */
794 if (C_CRTSCTS(tty)) {
795 #ifdef RISCOM_BRAIN_DAMAGED_CTS
796 port->IER |= IER_DSR | IER_CTS;
797 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
798 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
799 tty->hw_stopped = !(rc_in(bp, CD180_MSVR) & (MSVR_CTS|MSVR_DSR));
800 #else
801 port->COR2 |= COR2_CTSAE;
802 #endif
804 /* Enable Software Flow Control. FIXME: I'm not sure about this */
805 /* Some people reported that it works, but I still doubt */
806 if (I_IXON(tty)) {
807 port->COR2 |= COR2_TXIBE;
808 cor3 |= (COR3_FCT | COR3_SCDE);
809 if (I_IXANY(tty))
810 port->COR2 |= COR2_IXM;
811 rc_out(bp, CD180_SCHR1, START_CHAR(tty));
812 rc_out(bp, CD180_SCHR2, STOP_CHAR(tty));
813 rc_out(bp, CD180_SCHR3, START_CHAR(tty));
814 rc_out(bp, CD180_SCHR4, STOP_CHAR(tty));
816 if (!C_CLOCAL(tty)) {
817 /* Enable CD check */
818 port->IER |= IER_CD;
819 mcor1 |= MCOR1_CDZD;
820 mcor2 |= MCOR2_CDOD;
823 if (C_CREAD(tty))
824 /* Enable receiver */
825 port->IER |= IER_RXD;
827 /* Set input FIFO size (1-8 bytes) */
828 cor3 |= RISCOM_RXFIFO;
829 /* Setting up CD180 channel registers */
830 rc_out(bp, CD180_COR1, cor1);
831 rc_out(bp, CD180_COR2, port->COR2);
832 rc_out(bp, CD180_COR3, cor3);
833 /* Make CD180 know about registers change */
834 rc_wait_CCR(bp);
835 rc_out(bp, CD180_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
836 /* Setting up modem option registers */
837 rc_out(bp, CD180_MCOR1, mcor1);
838 rc_out(bp, CD180_MCOR2, mcor2);
839 /* Enable CD180 transmitter & receiver */
840 rc_wait_CCR(bp);
841 rc_out(bp, CD180_CCR, CCR_TXEN | CCR_RXEN);
842 /* Enable interrupts */
843 rc_out(bp, CD180_IER, port->IER);
844 /* And finally set RTS on */
845 rc_out(bp, CD180_MSVR, port->MSVR);
848 /* Must be called with interrupts enabled */
849 static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
851 unsigned long flags;
853 if (port->flags & ASYNC_INITIALIZED)
854 return 0;
856 if (!port->xmit_buf) {
857 /* We may sleep in get_free_page() */
858 unsigned long tmp;
860 if (!(tmp = get_free_page(GFP_KERNEL)))
861 return -ENOMEM;
863 if (port->xmit_buf) {
864 free_page(tmp);
865 return -ERESTARTSYS;
867 port->xmit_buf = (unsigned char *) tmp;
870 save_flags(flags); cli();
872 if (port->tty)
873 clear_bit(TTY_IO_ERROR, &port->tty->flags);
875 if (port->count == 1)
876 bp->count++;
878 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
879 rc_change_speed(bp, port);
880 port->flags |= ASYNC_INITIALIZED;
882 restore_flags(flags);
883 return 0;
886 /* Must be called with interrupts disabled */
887 static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
889 struct tty_struct *tty;
891 if (!(port->flags & ASYNC_INITIALIZED))
892 return;
894 #ifdef RC_REPORT_OVERRUN
895 printk("rc%d: port %d: Total %ld overruns were detected.\n",
896 board_No(bp), port_No(port), port->overrun);
897 #endif
898 #ifdef RC_REPORT_FIFO
900 int i;
902 printk("rc%d: port %d: FIFO hits [ ",
903 board_No(bp), port_No(port));
904 for (i = 0; i < 10; i++) {
905 printk("%ld ", port->hits[i]);
907 printk("].\n");
909 #endif
910 if (port->xmit_buf) {
911 free_page((unsigned long) port->xmit_buf);
912 port->xmit_buf = NULL;
915 if (!(tty = port->tty) || C_HUPCL(tty)) {
916 /* Drop DTR */
917 bp->DTR |= (1u << port_No(port));
918 rc_out(bp, RC_DTR, bp->DTR);
921 /* Select port */
922 rc_out(bp, CD180_CAR, port_No(port));
923 /* Reset port */
924 rc_wait_CCR(bp);
925 rc_out(bp, CD180_CCR, CCR_SOFTRESET);
926 /* Disable all interrupts from this port */
927 port->IER = 0;
928 rc_out(bp, CD180_IER, port->IER);
930 if (tty)
931 set_bit(TTY_IO_ERROR, &tty->flags);
932 port->flags &= ~ASYNC_INITIALIZED;
934 if (--bp->count < 0) {
935 printk("rc%d: rc_shutdown_port: bad board count: %d\n",
936 board_No(bp), bp->count);
937 bp->count = 0;
941 * If this is the last opened port on the board
942 * shutdown whole board
944 if (!bp->count)
945 rc_shutdown_board(bp);
949 static int block_til_ready(struct tty_struct *tty, struct file * filp,
950 struct riscom_port *port)
952 DECLARE_WAITQUEUE(wait, current);
953 struct riscom_board *bp = port_Board(port);
954 int retval;
955 int do_clocal = 0;
956 int CD;
959 * If the device is in the middle of being closed, then block
960 * until it's done, and then try again.
962 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
963 interruptible_sleep_on(&port->close_wait);
964 if (port->flags & ASYNC_HUP_NOTIFY)
965 return -EAGAIN;
966 else
967 return -ERESTARTSYS;
971 * If this is a callout device, then just make sure the normal
972 * device isn't being used.
974 if (tty->driver.subtype == RISCOM_TYPE_CALLOUT) {
975 if (port->flags & ASYNC_NORMAL_ACTIVE)
976 return -EBUSY;
977 if ((port->flags & ASYNC_CALLOUT_ACTIVE) &&
978 (port->flags & ASYNC_SESSION_LOCKOUT) &&
979 (port->session != current->session))
980 return -EBUSY;
981 if ((port->flags & ASYNC_CALLOUT_ACTIVE) &&
982 (port->flags & ASYNC_PGRP_LOCKOUT) &&
983 (port->pgrp != current->pgrp))
984 return -EBUSY;
985 port->flags |= ASYNC_CALLOUT_ACTIVE;
986 return 0;
990 * If non-blocking mode is set, or the port is not enabled,
991 * then make the check up front and then exit.
993 if ((filp->f_flags & O_NONBLOCK) ||
994 (tty->flags & (1 << TTY_IO_ERROR))) {
995 if (port->flags & ASYNC_CALLOUT_ACTIVE)
996 return -EBUSY;
997 port->flags |= ASYNC_NORMAL_ACTIVE;
998 return 0;
1001 if (port->flags & ASYNC_CALLOUT_ACTIVE) {
1002 if (port->normal_termios.c_cflag & CLOCAL)
1003 do_clocal = 1;
1004 } else {
1005 if (C_CLOCAL(tty))
1006 do_clocal = 1;
1010 * Block waiting for the carrier detect and the line to become
1011 * free (i.e., not in use by the callout). While we are in
1012 * this loop, info->count is dropped by one, so that
1013 * rs_close() knows when to free things. We restore it upon
1014 * exit, either normal or abnormal.
1016 retval = 0;
1017 add_wait_queue(&port->open_wait, &wait);
1018 cli();
1019 if (!tty_hung_up_p(filp))
1020 port->count--;
1021 sti();
1022 port->blocked_open++;
1023 while (1) {
1024 cli();
1025 rc_out(bp, CD180_CAR, port_No(port));
1026 CD = rc_in(bp, CD180_MSVR) & MSVR_CD;
1027 if (!(port->flags & ASYNC_CALLOUT_ACTIVE)) {
1028 rc_out(bp, CD180_MSVR, MSVR_RTS);
1029 bp->DTR &= ~(1u << port_No(port));
1030 rc_out(bp, RC_DTR, bp->DTR);
1032 sti();
1033 set_current_state(TASK_INTERRUPTIBLE);
1034 if (tty_hung_up_p(filp) ||
1035 !(port->flags & ASYNC_INITIALIZED)) {
1036 if (port->flags & ASYNC_HUP_NOTIFY)
1037 retval = -EAGAIN;
1038 else
1039 retval = -ERESTARTSYS;
1040 break;
1042 if (!(port->flags & ASYNC_CALLOUT_ACTIVE) &&
1043 !(port->flags & ASYNC_CLOSING) &&
1044 (do_clocal || CD))
1045 break;
1046 if (signal_pending(current)) {
1047 retval = -ERESTARTSYS;
1048 break;
1050 schedule();
1052 current->state = TASK_RUNNING;
1053 remove_wait_queue(&port->open_wait, &wait);
1054 if (!tty_hung_up_p(filp))
1055 port->count++;
1056 port->blocked_open--;
1057 if (retval)
1058 return retval;
1060 port->flags |= ASYNC_NORMAL_ACTIVE;
1061 return 0;
1064 static int rc_open(struct tty_struct * tty, struct file * filp)
1066 int board;
1067 int error;
1068 struct riscom_port * port;
1069 struct riscom_board * bp;
1070 unsigned long flags;
1072 board = RC_BOARD(MINOR(tty->device));
1073 if (board > RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT))
1074 return -ENODEV;
1076 bp = &rc_board[board];
1077 port = rc_port + board * RC_NPORT + RC_PORT(MINOR(tty->device));
1078 if (rc_paranoia_check(port, tty->device, "rc_open"))
1079 return -ENODEV;
1081 if ((error = rc_setup_board(bp)))
1082 return error;
1084 port->count++;
1085 tty->driver_data = port;
1086 port->tty = tty;
1088 if ((error = rc_setup_port(bp, port)))
1089 return error;
1091 if ((error = block_til_ready(tty, filp, port)))
1092 return error;
1094 if ((port->count == 1) && (port->flags & ASYNC_SPLIT_TERMIOS)) {
1095 if (tty->driver.subtype == RISCOM_TYPE_NORMAL)
1096 *tty->termios = port->normal_termios;
1097 else
1098 *tty->termios = port->callout_termios;
1099 save_flags(flags); cli();
1100 rc_change_speed(bp, port);
1101 restore_flags(flags);
1104 port->session = current->session;
1105 port->pgrp = current->pgrp;
1107 return 0;
1110 static void rc_close(struct tty_struct * tty, struct file * filp)
1112 struct riscom_port *port = (struct riscom_port *) tty->driver_data;
1113 struct riscom_board *bp;
1114 unsigned long flags;
1115 unsigned long timeout;
1117 if (!port || rc_paranoia_check(port, tty->device, "close"))
1118 return;
1120 save_flags(flags); cli();
1121 if (tty_hung_up_p(filp)) {
1122 restore_flags(flags);
1123 return;
1126 bp = port_Board(port);
1127 if ((tty->count == 1) && (port->count != 1)) {
1128 printk("rc%d: rc_close: bad port count;"
1129 " tty->count is 1, port count is %d\n",
1130 board_No(bp), port->count);
1131 port->count = 1;
1133 if (--port->count < 0) {
1134 printk("rc%d: rc_close: bad port count for tty%d: %d\n",
1135 board_No(bp), port_No(port), port->count);
1136 port->count = 0;
1138 if (port->count) {
1139 restore_flags(flags);
1140 return;
1142 port->flags |= ASYNC_CLOSING;
1144 * Save the termios structure, since this port may have
1145 * separate termios for callout and dialin.
1147 if (port->flags & ASYNC_NORMAL_ACTIVE)
1148 port->normal_termios = *tty->termios;
1149 if (port->flags & ASYNC_CALLOUT_ACTIVE)
1150 port->callout_termios = *tty->termios;
1152 * Now we wait for the transmit buffer to clear; and we notify
1153 * the line discipline to only process XON/XOFF characters.
1155 tty->closing = 1;
1156 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1157 tty_wait_until_sent(tty, port->closing_wait);
1159 * At this point we stop accepting input. To do this, we
1160 * disable the receive line status interrupts, and tell the
1161 * interrupt driver to stop checking the data ready bit in the
1162 * line status register.
1164 port->IER &= ~IER_RXD;
1165 if (port->flags & ASYNC_INITIALIZED) {
1166 port->IER &= ~IER_TXRDY;
1167 port->IER |= IER_TXEMPTY;
1168 rc_out(bp, CD180_CAR, port_No(port));
1169 rc_out(bp, CD180_IER, port->IER);
1171 * Before we drop DTR, make sure the UART transmitter
1172 * has completely drained; this is especially
1173 * important if there is a transmit FIFO!
1175 timeout = jiffies+HZ;
1176 while(port->IER & IER_TXEMPTY) {
1177 current->state = TASK_INTERRUPTIBLE;
1178 schedule_timeout(port->timeout);
1179 if (time_after(jiffies, timeout))
1180 break;
1183 rc_shutdown_port(bp, port);
1184 if (tty->driver.flush_buffer)
1185 tty->driver.flush_buffer(tty);
1186 if (tty->ldisc.flush_buffer)
1187 tty->ldisc.flush_buffer(tty);
1188 tty->closing = 0;
1189 port->event = 0;
1190 port->tty = 0;
1191 if (port->blocked_open) {
1192 if (port->close_delay) {
1193 current->state = TASK_INTERRUPTIBLE;
1194 schedule_timeout(port->close_delay);
1196 wake_up_interruptible(&port->open_wait);
1198 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
1199 ASYNC_CLOSING);
1200 wake_up_interruptible(&port->close_wait);
1201 restore_flags(flags);
1204 static int rc_write(struct tty_struct * tty, int from_user,
1205 const unsigned char *buf, int count)
1207 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1208 struct riscom_board *bp;
1209 int c, total = 0;
1210 unsigned long flags;
1212 if (rc_paranoia_check(port, tty->device, "rc_write"))
1213 return 0;
1215 bp = port_Board(port);
1217 if (!tty || !port->xmit_buf || !tmp_buf)
1218 return 0;
1220 if (from_user)
1221 down(&tmp_buf_sem);
1223 save_flags(flags);
1224 while (1) {
1225 cli();
1226 c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1227 SERIAL_XMIT_SIZE - port->xmit_head));
1228 if (c <= 0)
1229 break;
1231 if (from_user) {
1232 copy_from_user(tmp_buf, buf, c);
1233 c = MIN(c, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1234 SERIAL_XMIT_SIZE - port->xmit_head));
1235 memcpy(port->xmit_buf + port->xmit_head, tmp_buf, c);
1236 } else
1237 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1238 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1239 port->xmit_cnt += c;
1240 restore_flags(flags);
1241 buf += c;
1242 count -= c;
1243 total += c;
1245 if (from_user)
1246 up(&tmp_buf_sem);
1247 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1248 !(port->IER & IER_TXRDY)) {
1249 port->IER |= IER_TXRDY;
1250 rc_out(bp, CD180_CAR, port_No(port));
1251 rc_out(bp, CD180_IER, port->IER);
1253 restore_flags(flags);
1254 return total;
1257 static void rc_put_char(struct tty_struct * tty, unsigned char ch)
1259 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1260 unsigned long flags;
1262 if (rc_paranoia_check(port, tty->device, "rc_put_char"))
1263 return;
1265 if (!tty || !port->xmit_buf)
1266 return;
1268 save_flags(flags); cli();
1270 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
1271 restore_flags(flags);
1272 return;
1275 port->xmit_buf[port->xmit_head++] = ch;
1276 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1277 port->xmit_cnt++;
1278 restore_flags(flags);
1281 static void rc_flush_chars(struct tty_struct * tty)
1283 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1284 unsigned long flags;
1286 if (rc_paranoia_check(port, tty->device, "rc_flush_chars"))
1287 return;
1289 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1290 !port->xmit_buf)
1291 return;
1293 save_flags(flags); cli();
1294 port->IER |= IER_TXRDY;
1295 rc_out(port_Board(port), CD180_CAR, port_No(port));
1296 rc_out(port_Board(port), CD180_IER, port->IER);
1297 restore_flags(flags);
1300 static int rc_write_room(struct tty_struct * tty)
1302 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1303 int ret;
1305 if (rc_paranoia_check(port, tty->device, "rc_write_room"))
1306 return 0;
1308 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1309 if (ret < 0)
1310 ret = 0;
1311 return ret;
1314 static int rc_chars_in_buffer(struct tty_struct *tty)
1316 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1318 if (rc_paranoia_check(port, tty->device, "rc_chars_in_buffer"))
1319 return 0;
1321 return port->xmit_cnt;
1324 static void rc_flush_buffer(struct tty_struct *tty)
1326 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1327 unsigned long flags;
1329 if (rc_paranoia_check(port, tty->device, "rc_flush_buffer"))
1330 return;
1332 save_flags(flags); cli();
1333 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1334 restore_flags(flags);
1336 wake_up_interruptible(&tty->write_wait);
1337 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
1338 tty->ldisc.write_wakeup)
1339 (tty->ldisc.write_wakeup)(tty);
1342 static int rc_get_modem_info(struct riscom_port * port, unsigned int *value)
1344 struct riscom_board * bp;
1345 unsigned char status;
1346 unsigned int result;
1347 unsigned long flags;
1349 bp = port_Board(port);
1350 save_flags(flags); cli();
1351 rc_out(bp, CD180_CAR, port_No(port));
1352 status = rc_in(bp, CD180_MSVR);
1353 result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG;
1354 restore_flags(flags);
1355 result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0)
1356 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1357 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1358 | ((status & MSVR_DSR) ? TIOCM_DSR : 0)
1359 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1360 put_user(result, value);
1361 return 0;
1364 static int rc_set_modem_info(struct riscom_port * port, unsigned int cmd,
1365 unsigned int *value)
1367 int error;
1368 unsigned int arg;
1369 unsigned long flags;
1370 struct riscom_board *bp = port_Board(port);
1372 error = get_user(arg, value);
1373 if (error)
1374 return error;
1375 switch (cmd) {
1376 case TIOCMBIS:
1377 if (arg & TIOCM_RTS)
1378 port->MSVR |= MSVR_RTS;
1379 if (arg & TIOCM_DTR)
1380 bp->DTR &= ~(1u << port_No(port));
1381 break;
1382 case TIOCMBIC:
1383 if (arg & TIOCM_RTS)
1384 port->MSVR &= ~MSVR_RTS;
1385 if (arg & TIOCM_DTR)
1386 bp->DTR |= (1u << port_No(port));
1387 break;
1388 case TIOCMSET:
1389 port->MSVR = (arg & TIOCM_RTS) ? (port->MSVR | MSVR_RTS) :
1390 (port->MSVR & ~MSVR_RTS);
1391 bp->DTR = arg & TIOCM_DTR ? (bp->DTR &= ~(1u << port_No(port))) :
1392 (bp->DTR |= (1u << port_No(port)));
1393 break;
1394 default:
1395 return -EINVAL;
1397 save_flags(flags); cli();
1398 rc_out(bp, CD180_CAR, port_No(port));
1399 rc_out(bp, CD180_MSVR, port->MSVR);
1400 rc_out(bp, RC_DTR, bp->DTR);
1401 restore_flags(flags);
1402 return 0;
1405 static inline void rc_send_break(struct riscom_port * port, unsigned long length)
1407 struct riscom_board *bp = port_Board(port);
1408 unsigned long flags;
1410 save_flags(flags); cli();
1411 port->break_length = RISCOM_TPS / HZ * length;
1412 port->COR2 |= COR2_ETC;
1413 port->IER |= IER_TXRDY;
1414 rc_out(bp, CD180_CAR, port_No(port));
1415 rc_out(bp, CD180_COR2, port->COR2);
1416 rc_out(bp, CD180_IER, port->IER);
1417 rc_wait_CCR(bp);
1418 rc_out(bp, CD180_CCR, CCR_CORCHG2);
1419 rc_wait_CCR(bp);
1420 restore_flags(flags);
1423 static inline int rc_set_serial_info(struct riscom_port * port,
1424 struct serial_struct * newinfo)
1426 struct serial_struct tmp;
1427 struct riscom_board *bp = port_Board(port);
1428 int change_speed;
1429 unsigned long flags;
1430 int error;
1432 error = verify_area(VERIFY_READ, (void *) newinfo, sizeof(tmp));
1433 if (error)
1434 return error;
1435 copy_from_user(&tmp, newinfo, sizeof(tmp));
1437 #if 0
1438 if ((tmp.irq != bp->irq) ||
1439 (tmp.port != bp->base) ||
1440 (tmp.type != PORT_CIRRUS) ||
1441 (tmp.baud_base != (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC) ||
1442 (tmp.custom_divisor != 0) ||
1443 (tmp.xmit_fifo_size != CD180_NFIFO) ||
1444 (tmp.flags & ~RISCOM_LEGAL_FLAGS))
1445 return -EINVAL;
1446 #endif
1448 change_speed = ((port->flags & ASYNC_SPD_MASK) !=
1449 (tmp.flags & ASYNC_SPD_MASK));
1451 if (!capable(CAP_SYS_ADMIN)) {
1452 if ((tmp.close_delay != port->close_delay) ||
1453 (tmp.closing_wait != port->closing_wait) ||
1454 ((tmp.flags & ~ASYNC_USR_MASK) !=
1455 (port->flags & ~ASYNC_USR_MASK)))
1456 return -EPERM;
1457 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
1458 (tmp.flags & ASYNC_USR_MASK));
1459 } else {
1460 port->flags = ((port->flags & ~ASYNC_FLAGS) |
1461 (tmp.flags & ASYNC_FLAGS));
1462 port->close_delay = tmp.close_delay;
1463 port->closing_wait = tmp.closing_wait;
1465 if (change_speed) {
1466 save_flags(flags); cli();
1467 rc_change_speed(bp, port);
1468 restore_flags(flags);
1470 return 0;
1473 static inline int rc_get_serial_info(struct riscom_port * port,
1474 struct serial_struct * retinfo)
1476 struct serial_struct tmp;
1477 struct riscom_board *bp = port_Board(port);
1478 int error;
1480 error = verify_area(VERIFY_WRITE, (void *) retinfo, sizeof(tmp));
1481 if (error)
1482 return error;
1484 memset(&tmp, 0, sizeof(tmp));
1485 tmp.type = PORT_CIRRUS;
1486 tmp.line = port - rc_port;
1487 tmp.port = bp->base;
1488 tmp.irq = bp->irq;
1489 tmp.flags = port->flags;
1490 tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC;
1491 tmp.close_delay = port->close_delay * HZ/100;
1492 tmp.closing_wait = port->closing_wait * HZ/100;
1493 tmp.xmit_fifo_size = CD180_NFIFO;
1494 copy_to_user(retinfo, &tmp, sizeof(tmp));
1495 return 0;
1498 static int rc_ioctl(struct tty_struct * tty, struct file * filp,
1499 unsigned int cmd, unsigned long arg)
1502 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1503 int error;
1504 int retval;
1506 if (rc_paranoia_check(port, tty->device, "rc_ioctl"))
1507 return -ENODEV;
1509 switch (cmd) {
1510 case TCSBRK: /* SVID version: non-zero arg --> no break */
1511 retval = tty_check_change(tty);
1512 if (retval)
1513 return retval;
1514 tty_wait_until_sent(tty, 0);
1515 if (!arg)
1516 rc_send_break(port, HZ/4); /* 1/4 second */
1517 return 0;
1518 case TCSBRKP: /* support for POSIX tcsendbreak() */
1519 retval = tty_check_change(tty);
1520 if (retval)
1521 return retval;
1522 tty_wait_until_sent(tty, 0);
1523 rc_send_break(port, arg ? arg*(HZ/10) : HZ/4);
1524 return 0;
1525 case TIOCGSOFTCAR:
1526 return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned int *) arg);
1527 case TIOCSSOFTCAR:
1528 retval = get_user(arg,(unsigned int *) arg);
1529 if (retval)
1530 return retval;
1531 tty->termios->c_cflag =
1532 ((tty->termios->c_cflag & ~CLOCAL) |
1533 (arg ? CLOCAL : 0));
1534 return 0;
1535 case TIOCMGET:
1536 error = verify_area(VERIFY_WRITE, (void *) arg,
1537 sizeof(unsigned int));
1538 if (error)
1539 return error;
1540 return rc_get_modem_info(port, (unsigned int *) arg);
1541 case TIOCMBIS:
1542 case TIOCMBIC:
1543 case TIOCMSET:
1544 return rc_set_modem_info(port, cmd, (unsigned int *) arg);
1545 case TIOCGSERIAL:
1546 return rc_get_serial_info(port, (struct serial_struct *) arg);
1547 case TIOCSSERIAL:
1548 return rc_set_serial_info(port, (struct serial_struct *) arg);
1549 default:
1550 return -ENOIOCTLCMD;
1552 return 0;
1555 static void rc_throttle(struct tty_struct * tty)
1557 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1558 struct riscom_board *bp;
1559 unsigned long flags;
1561 if (rc_paranoia_check(port, tty->device, "rc_throttle"))
1562 return;
1564 bp = port_Board(port);
1566 save_flags(flags); cli();
1567 port->MSVR &= ~MSVR_RTS;
1568 rc_out(bp, CD180_CAR, port_No(port));
1569 if (I_IXOFF(tty)) {
1570 rc_wait_CCR(bp);
1571 rc_out(bp, CD180_CCR, CCR_SSCH2);
1572 rc_wait_CCR(bp);
1574 rc_out(bp, CD180_MSVR, port->MSVR);
1575 restore_flags(flags);
1578 static void rc_unthrottle(struct tty_struct * tty)
1580 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1581 struct riscom_board *bp;
1582 unsigned long flags;
1584 if (rc_paranoia_check(port, tty->device, "rc_unthrottle"))
1585 return;
1587 bp = port_Board(port);
1589 save_flags(flags); cli();
1590 port->MSVR |= MSVR_RTS;
1591 rc_out(bp, CD180_CAR, port_No(port));
1592 if (I_IXOFF(tty)) {
1593 rc_wait_CCR(bp);
1594 rc_out(bp, CD180_CCR, CCR_SSCH1);
1595 rc_wait_CCR(bp);
1597 rc_out(bp, CD180_MSVR, port->MSVR);
1598 restore_flags(flags);
1601 static void rc_stop(struct tty_struct * tty)
1603 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1604 struct riscom_board *bp;
1605 unsigned long flags;
1607 if (rc_paranoia_check(port, tty->device, "rc_stop"))
1608 return;
1610 bp = port_Board(port);
1612 save_flags(flags); cli();
1613 port->IER &= ~IER_TXRDY;
1614 rc_out(bp, CD180_CAR, port_No(port));
1615 rc_out(bp, CD180_IER, port->IER);
1616 restore_flags(flags);
1619 static void rc_start(struct tty_struct * tty)
1621 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1622 struct riscom_board *bp;
1623 unsigned long flags;
1625 if (rc_paranoia_check(port, tty->device, "rc_start"))
1626 return;
1628 bp = port_Board(port);
1630 save_flags(flags); cli();
1631 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
1632 port->IER |= IER_TXRDY;
1633 rc_out(bp, CD180_CAR, port_No(port));
1634 rc_out(bp, CD180_IER, port->IER);
1636 restore_flags(flags);
1640 * This routine is called from the scheduler tqueue when the interrupt
1641 * routine has signalled that a hangup has occurred. The path of
1642 * hangup processing is:
1644 * serial interrupt routine -> (scheduler tqueue) ->
1645 * do_rc_hangup() -> tty->hangup() -> rc_hangup()
1648 static void do_rc_hangup(void *private_)
1650 struct riscom_port *port = (struct riscom_port *) private_;
1651 struct tty_struct *tty;
1653 tty = port->tty;
1654 if (tty)
1655 tty_hangup(tty); /* FIXME: module removal race still here */
1656 MOD_DEC_USE_COUNT;
1659 static void rc_hangup(struct tty_struct * tty)
1661 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1662 struct riscom_board *bp;
1664 if (rc_paranoia_check(port, tty->device, "rc_hangup"))
1665 return;
1667 bp = port_Board(port);
1669 rc_shutdown_port(bp, port);
1670 port->event = 0;
1671 port->count = 0;
1672 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
1673 port->tty = 0;
1674 wake_up_interruptible(&port->open_wait);
1677 static void rc_set_termios(struct tty_struct * tty, struct termios * old_termios)
1679 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1680 unsigned long flags;
1682 if (rc_paranoia_check(port, tty->device, "rc_set_termios"))
1683 return;
1685 if (tty->termios->c_cflag == old_termios->c_cflag &&
1686 tty->termios->c_iflag == old_termios->c_iflag)
1687 return;
1689 save_flags(flags); cli();
1690 rc_change_speed(port_Board(port), port);
1691 restore_flags(flags);
1693 if ((old_termios->c_cflag & CRTSCTS) &&
1694 !(tty->termios->c_cflag & CRTSCTS)) {
1695 tty->hw_stopped = 0;
1696 rc_start(tty);
1700 static void do_riscom_bh(void)
1702 run_task_queue(&tq_riscom);
1705 static void do_softint(void *private_)
1707 struct riscom_port *port = (struct riscom_port *) private_;
1708 struct tty_struct *tty;
1710 if(!(tty = port->tty))
1711 return;
1713 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
1714 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
1715 tty->ldisc.write_wakeup)
1716 (tty->ldisc.write_wakeup)(tty);
1717 wake_up_interruptible(&tty->write_wait);
1721 static inline int rc_init_drivers(void)
1723 int error;
1724 int i;
1727 if (!(tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL))) {
1728 printk("rc: Couldn't get free page.\n");
1729 return 1;
1731 init_bh(RISCOM8_BH, do_riscom_bh);
1732 memset(IRQ_to_board, 0, sizeof(IRQ_to_board));
1733 memset(&riscom_driver, 0, sizeof(riscom_driver));
1734 riscom_driver.magic = TTY_DRIVER_MAGIC;
1735 riscom_driver.name = "ttyL";
1736 riscom_driver.major = RISCOM8_NORMAL_MAJOR;
1737 riscom_driver.num = RC_NBOARD * RC_NPORT;
1738 riscom_driver.type = TTY_DRIVER_TYPE_SERIAL;
1739 riscom_driver.subtype = RISCOM_TYPE_NORMAL;
1740 riscom_driver.init_termios = tty_std_termios;
1741 riscom_driver.init_termios.c_cflag =
1742 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1743 riscom_driver.flags = TTY_DRIVER_REAL_RAW;
1744 riscom_driver.refcount = &riscom_refcount;
1745 riscom_driver.table = riscom_table;
1746 riscom_driver.termios = riscom_termios;
1747 riscom_driver.termios_locked = riscom_termios_locked;
1749 riscom_driver.open = rc_open;
1750 riscom_driver.close = rc_close;
1751 riscom_driver.write = rc_write;
1752 riscom_driver.put_char = rc_put_char;
1753 riscom_driver.flush_chars = rc_flush_chars;
1754 riscom_driver.write_room = rc_write_room;
1755 riscom_driver.chars_in_buffer = rc_chars_in_buffer;
1756 riscom_driver.flush_buffer = rc_flush_buffer;
1757 riscom_driver.ioctl = rc_ioctl;
1758 riscom_driver.throttle = rc_throttle;
1759 riscom_driver.unthrottle = rc_unthrottle;
1760 riscom_driver.set_termios = rc_set_termios;
1761 riscom_driver.stop = rc_stop;
1762 riscom_driver.start = rc_start;
1763 riscom_driver.hangup = rc_hangup;
1765 riscom_callout_driver = riscom_driver;
1766 riscom_callout_driver.name = "cul";
1767 riscom_callout_driver.major = RISCOM8_CALLOUT_MAJOR;
1768 riscom_callout_driver.subtype = RISCOM_TYPE_CALLOUT;
1770 if ((error = tty_register_driver(&riscom_driver))) {
1771 free_page((unsigned long)tmp_buf);
1772 printk("rc: Couldn't register RISCom/8 driver, error = %d\n",
1773 error);
1774 return 1;
1776 if ((error = tty_register_driver(&riscom_callout_driver))) {
1777 free_page((unsigned long)tmp_buf);
1778 tty_unregister_driver(&riscom_driver);
1779 printk("rc: Couldn't register RISCom/8 callout driver, error = %d\n",
1780 error);
1781 return 1;
1784 memset(rc_port, 0, sizeof(rc_port));
1785 for (i = 0; i < RC_NPORT * RC_NBOARD; i++) {
1786 rc_port[i].callout_termios = riscom_callout_driver.init_termios;
1787 rc_port[i].normal_termios = riscom_driver.init_termios;
1788 rc_port[i].magic = RISCOM8_MAGIC;
1789 rc_port[i].tqueue.routine = do_softint;
1790 rc_port[i].tqueue.data = &rc_port[i];
1791 rc_port[i].tqueue_hangup.routine = do_rc_hangup;
1792 rc_port[i].tqueue_hangup.data = &rc_port[i];
1793 rc_port[i].close_delay = 50 * HZ/100;
1794 rc_port[i].closing_wait = 3000 * HZ/100;
1795 init_waitqueue_head(&rc_port[i].open_wait);
1796 init_waitqueue_head(&rc_port[i].close_wait);
1799 return 0;
1802 static void rc_release_drivers(void)
1804 unsigned long flags;
1806 save_flags(flags);
1807 cli();
1808 remove_bh(RISCOM8_BH);
1809 free_page((unsigned long)tmp_buf);
1810 tty_unregister_driver(&riscom_driver);
1811 tty_unregister_driver(&riscom_callout_driver);
1812 restore_flags(flags);
1815 #ifndef MODULE
1817 * Called at boot time.
1819 * You can specify IO base for up to RC_NBOARD cards,
1820 * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt.
1821 * Note that there will be no probing at default
1822 * addresses in this case.
1825 static void __init riscom8_setup(char *str, int * ints)
1827 int i;
1829 for (i = 0; i < RC_NBOARD; i++) {
1830 if (i < ints[0])
1831 rc_board[i].base = ints[i+1];
1832 else
1833 rc_board[i].base = 0;
1837 __setup("riscom8=", riscom8_setup);
1838 #endif
1841 * This routine must be called by kernel at boot time
1843 static int __init riscom8_init(void)
1845 int i;
1846 int found = 0;
1848 printk("rc: SDL RISCom/8 card driver v1.0, (c) D.Gorodchanin 1994-1996.\n");
1850 if (rc_init_drivers())
1851 return -EIO;
1853 for (i = 0; i < RC_NBOARD; i++)
1854 if (rc_board[i].base && !rc_probe(&rc_board[i]))
1855 found++;
1857 if (!found) {
1858 rc_release_drivers();
1859 printk("rc: No RISCom/8 boards detected.\n");
1860 return -EIO;
1862 return 0;
1865 #ifdef MODULE
1866 static int iobase;
1867 static int iobase1;
1868 static int iobase2;
1869 static int iobase3;
1870 MODULE_PARM(iobase, "i");
1871 MODULE_PARM(iobase1, "i");
1872 MODULE_PARM(iobase2, "i");
1873 MODULE_PARM(iobase3, "i");
1874 #endif /* MODULE */
1877 * You can setup up to 4 boards (current value of RC_NBOARD)
1878 * by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter.
1881 static int __init riscom8_init_module (void)
1883 #ifdef MODULE
1884 int i;
1886 if (iobase || iobase1 || iobase2 || iobase3) {
1887 for(i = 0; i < RC_NBOARD; i++)
1888 rc_board[0].base = 0;
1891 if (iobase)
1892 rc_board[0].base = iobase;
1893 if (iobase1)
1894 rc_board[1].base = iobase1;
1895 if (iobase2)
1896 rc_board[2].base = iobase2;
1897 if (iobase3)
1898 rc_board[3].base = iobase3;
1899 #endif /* MODULE */
1901 return riscom8_init();
1904 static void __exit riscom8_exit_module (void)
1906 int i;
1908 rc_release_drivers();
1909 for (i = 0; i < RC_NBOARD; i++)
1910 if (rc_board[i].flags & RC_BOARD_PRESENT)
1911 rc_release_io_range(&rc_board[i]);
1915 module_init(riscom8_init_module);
1916 module_exit(riscom8_exit_module);