Import 2.1.89
[davej-history.git] / drivers / char / riscom8.c
blobbed251b19ec9d360652fc9f77263c4fab33f2778
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 DECLARE_TASK_QUEUE(tq_riscom);
80 #define RISCOM_TYPE_NORMAL 1
81 #define RISCOM_TYPE_CALLOUT 2
83 static struct riscom_board * IRQ_to_board[16] = { NULL, } ;
84 static struct tty_driver riscom_driver, riscom_callout_driver;
85 static int riscom_refcount =0;
86 static struct tty_struct * riscom_table[RC_NBOARD * RC_NPORT] = { NULL, };
87 static struct termios * riscom_termios[RC_NBOARD * RC_NPORT] = { NULL, };
88 static struct termios * riscom_termios_locked[RC_NBOARD * RC_NPORT] = { NULL, };
89 static unsigned char* tmp_buf = NULL;
90 static struct semaphore tmp_buf_sem = MUTEX;
92 static unsigned long baud_table[] = {
93 0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,
94 9600,19200,38400,57600,76800,0,
97 static struct riscom_board rc_board[RC_NBOARD] = {
98 {0, RC_IOBASE1,0, },
99 {0, RC_IOBASE2,0, },
100 {0, RC_IOBASE3,0, },
101 {0, RC_IOBASE4,0, },
104 static struct riscom_port rc_port[RC_NBOARD * RC_NPORT] = {
105 {0, },
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 staticinlineintrc_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 return1;
134 if(port->magic != RISCOM8_MAGIC) {
135 printk(badmagic,kdevname(device), routine);
136 return1;
138 #endif
139 return0;
144 * Service functions for RISCom/8 driver.
148 /* Get board number from pointer */
149 extern inlineintboard_No(struct riscom_board const* bp)
151 return bp - rc_board;
154 /* Get port number from pointer */
155 extern inlineintport_No(struct riscom_port const* port)
157 returnRC_PORT(port - rc_port);
160 /* Get pointer to board from pointer to port */
161 extern inlinestruct 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 extern inlineunsigned charrc_in(struct riscom_board const* bp,unsigned short reg)
169 returninb(bp->base +RC_TO_ISA(reg));
172 /* Output Byte to CL CD180 register */
173 extern inlinevoidrc_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 extern inlinevoidrc_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 extern inlineintrc_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 return1;
206 return0;
209 extern inlinevoidrc_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 extern inlinevoidrc_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 extern inlinevoidrc_long_delay(unsigned long delay)
229 unsigned long i;
231 for(i = jiffies + delay; i > jiffies; ) ;
234 /* Reset and setup CD180 chip */
235 __initfunc(static voidrc_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 __initfunc(static intrc_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 return1;
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 return1;
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 return1;
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 return1;
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 return0;
325 * Interrupt processing routines.
329 extern inlinevoidrc_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 extern inlinestruct 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 extern inlinevoidrc_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 extern inlinevoidrc_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 extern inlinevoidrc_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;
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 extern inlinevoidrc_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 queue_task(&port->tqueue_hangup, &tq_scheduler);
544 #ifdef RISCOM_BRAIN_DAMAGED_CTS
545 if(mcr & MCR_CTSCHG) {
546 if(rc_in(bp, CD180_MSVR) & MSVR_CTS) {
547 tty->hw_stopped =0;
548 port->IER |= IER_TXRDY;
549 if(port->xmit_cnt <= port->wakeup_chars)
550 rc_mark_event(port, RS_EVENT_WRITE_WAKEUP);
551 }else{
552 tty->hw_stopped =1;
553 port->IER &= ~IER_TXRDY;
555 rc_out(bp, CD180_IER, port->IER);
557 if(mcr & MCR_DSRCHG) {
558 if(rc_in(bp, CD180_MSVR) & MSVR_DSR) {
559 tty->hw_stopped =0;
560 port->IER |= IER_TXRDY;
561 if(port->xmit_cnt <= port->wakeup_chars)
562 rc_mark_event(port, RS_EVENT_WRITE_WAKEUP);
563 }else{
564 tty->hw_stopped =1;
565 port->IER &= ~IER_TXRDY;
567 rc_out(bp, CD180_IER, port->IER);
569 #endif/* RISCOM_BRAIN_DAMAGED_CTS */
571 /* Clear change bits */
572 rc_out(bp, CD180_MCR,0);
575 /* The main interrupt processing routine */
576 static voidrc_interrupt(int irq,void* dev_id,struct pt_regs * regs)
578 unsigned char status;
579 unsigned char ack;
580 struct riscom_board *bp;
581 unsigned long loop =0;
583 bp = IRQ_to_board[irq];
585 if(!bp || !(bp->flags & RC_BOARD_ACTIVE)) {
586 return;
589 while((++loop <16) && ((status = ~(rc_in(bp, RC_BSR))) &
590 (RC_BSR_TOUT | RC_BSR_TINT |
591 RC_BSR_MINT | RC_BSR_RINT))) {
593 if(status & RC_BSR_TOUT)
594 printk("rc%d: Got timeout. Hardware error ?\n",board_No(bp));
596 else if(status & RC_BSR_RINT) {
597 ack =rc_in(bp, RC_ACK_RINT);
599 if(ack == (RC_ID | GIVR_IT_RCV))
600 rc_receive(bp);
601 else if(ack == (RC_ID | GIVR_IT_REXC))
602 rc_receive_exc(bp);
603 else
604 printk("rc%d: Bad receive ack 0x%02x.\n",
605 board_No(bp), ack);
607 }else if(status & RC_BSR_TINT) {
608 ack =rc_in(bp, RC_ACK_TINT);
610 if(ack == (RC_ID | GIVR_IT_TX))
611 rc_transmit(bp);
612 else
613 printk("rc%d: Bad transmit ack 0x%02x.\n",
614 board_No(bp), ack);
616 }else/* if (status & RC_BSR_MINT) */{
617 ack =rc_in(bp, RC_ACK_MINT);
619 if(ack == (RC_ID | GIVR_IT_MODEM))
620 rc_check_modem(bp);
621 else
622 printk("rc%d: Bad modem ack 0x%02x.\n",
623 board_No(bp), ack);
627 rc_out(bp, CD180_EOIR,0);/* Mark end of interrupt */
628 rc_out(bp, RC_CTOUT,0);/* Clear timeout flag */
633 * Routines for open & close processing.
636 /* Called with disabled interrupts */
637 extern inlineintrc_setup_board(struct riscom_board * bp)
639 int error;
641 if(bp->flags & RC_BOARD_ACTIVE)
642 return0;
644 error =request_irq(bp->irq, rc_interrupt, SA_INTERRUPT,"RISCom/8", NULL);
645 if(error)
646 return error;
648 rc_out(bp, RC_CTOUT,0);/* Just in case */
649 bp->DTR = ~0;
650 rc_out(bp, RC_DTR, bp->DTR);/* Drop DTR on all ports */
652 IRQ_to_board[bp->irq] = bp;
653 bp->flags |= RC_BOARD_ACTIVE;
655 MOD_INC_USE_COUNT;
656 return0;
659 /* Called with disabled interrupts */
660 extern inlinevoidrc_shutdown_board(struct riscom_board *bp)
662 if(!(bp->flags & RC_BOARD_ACTIVE))
663 return;
665 bp->flags &= ~RC_BOARD_ACTIVE;
667 free_irq(bp->irq, NULL);
668 IRQ_to_board[bp->irq] = NULL;
670 bp->DTR = ~0;
671 rc_out(bp, RC_DTR, bp->DTR);/* Drop DTR on all ports */
673 MOD_DEC_USE_COUNT;
677 * Setting up port characteristics.
678 * Must be called with disabled interrupts
680 static voidrc_change_speed(struct riscom_board *bp,struct riscom_port *port)
682 struct tty_struct *tty;
683 unsigned long baud;
684 long tmp;
685 unsigned char cor1 =0, cor3 =0;
686 unsigned char mcor1 =0, mcor2 =0;
688 if(!(tty = port->tty) || !tty->termios)
689 return;
691 port->IER =0;
692 port->COR2 =0;
693 port->MSVR = MSVR_RTS;
695 baud =C_BAUD(tty);
697 if(baud & CBAUDEX) {
698 baud &= ~CBAUDEX;
699 if(baud <1|| baud >2)
700 port->tty->termios->c_cflag &= ~CBAUDEX;
701 else
702 baud +=15;
704 if(baud ==15) {
705 if((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
706 baud ++;
707 if((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
708 baud +=2;
711 /* Select port on the board */
712 rc_out(bp, CD180_CAR,port_No(port));
714 if(!baud_table[baud]) {
715 /* Drop DTR & exit */
716 bp->DTR |= (1u<<port_No(port));
717 rc_out(bp, RC_DTR, bp->DTR);
718 return;
719 }else{
720 /* Set DTR on */
721 bp->DTR &= ~(1u<<port_No(port));
722 rc_out(bp, RC_DTR, bp->DTR);
726 * Now we must calculate some speed depended things
729 /* Set baud rate for port */
730 tmp = (((RC_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
731 CD180_TPC/2) / CD180_TPC);
733 rc_out(bp, CD180_RBPRH, (tmp >>8) &0xff);
734 rc_out(bp, CD180_TBPRH, (tmp >>8) &0xff);
735 rc_out(bp, CD180_RBPRL, tmp &0xff);
736 rc_out(bp, CD180_TBPRL, tmp &0xff);
738 baud = (baud_table[baud] +5) /10;/* Estimated CPS */
740 /* Two timer ticks seems enough to wakeup something like SLIP driver */
741 tmp = ((baud + HZ/2) / HZ) *2- CD180_NFIFO;
742 port->wakeup_chars = (tmp <0) ?0: ((tmp >= SERIAL_XMIT_SIZE) ?
743 SERIAL_XMIT_SIZE -1: tmp);
745 /* Receiver timeout will be transmission time for 1.5 chars */
746 tmp = (RISCOM_TPS + RISCOM_TPS/2+ baud/2) / baud;
747 tmp = (tmp >0xff) ?0xff: tmp;
748 rc_out(bp, CD180_RTPR, tmp);
750 switch(C_CSIZE(tty)) {
751 case CS5:
752 cor1 |= COR1_5BITS;
753 break;
754 case CS6:
755 cor1 |= COR1_6BITS;
756 break;
757 case CS7:
758 cor1 |= COR1_7BITS;
759 break;
760 case CS8:
761 cor1 |= COR1_8BITS;
762 break;
765 if(C_CSTOPB(tty))
766 cor1 |= COR1_2SB;
768 cor1 |= COR1_IGNORE;
769 if(C_PARENB(tty)) {
770 cor1 |= COR1_NORMPAR;
771 if(C_PARODD(tty))
772 cor1 |= COR1_ODDP;
773 if(I_INPCK(tty))
774 cor1 &= ~COR1_IGNORE;
776 /* Set marking of some errors */
777 port->mark_mask = RCSR_OE | RCSR_TOUT;
778 if(I_INPCK(tty))
779 port->mark_mask |= RCSR_FE | RCSR_PE;
780 if(I_BRKINT(tty) ||I_PARMRK(tty))
781 port->mark_mask |= RCSR_BREAK;
782 if(I_IGNPAR(tty))
783 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
784 if(I_IGNBRK(tty)) {
785 port->mark_mask &= ~RCSR_BREAK;
786 if(I_IGNPAR(tty))
787 /* Real raw mode. Ignore all */
788 port->mark_mask &= ~RCSR_OE;
790 /* Enable Hardware Flow Control */
791 if(C_CRTSCTS(tty)) {
792 #ifdef RISCOM_BRAIN_DAMAGED_CTS
793 port->IER |= IER_DSR | IER_CTS;
794 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
795 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
796 tty->hw_stopped = !(rc_in(bp, CD180_MSVR) & (MSVR_CTS|MSVR_DSR));
797 #else
798 port->COR2 |= COR2_CTSAE;
799 #endif
801 /* Enable Software Flow Control. FIXME: I'm not sure about this */
802 /* Some people reported that it works, but I still doubt */
803 if(I_IXON(tty)) {
804 port->COR2 |= COR2_TXIBE;
805 cor3 |= (COR3_FCT | COR3_SCDE);
806 if(I_IXANY(tty))
807 port->COR2 |= COR2_IXM;
808 rc_out(bp, CD180_SCHR1,START_CHAR(tty));
809 rc_out(bp, CD180_SCHR2,STOP_CHAR(tty));
810 rc_out(bp, CD180_SCHR3,START_CHAR(tty));
811 rc_out(bp, CD180_SCHR4,STOP_CHAR(tty));
813 if(!C_CLOCAL(tty)) {
814 /* Enable CD check */
815 port->IER |= IER_CD;
816 mcor1 |= MCOR1_CDZD;
817 mcor2 |= MCOR2_CDOD;
820 if(C_CREAD(tty))
821 /* Enable receiver */
822 port->IER |= IER_RXD;
824 /* Set input FIFO size (1-8 bytes) */
825 cor3 |= RISCOM_RXFIFO;
826 /* Setting up CD180 channel registers */
827 rc_out(bp, CD180_COR1, cor1);
828 rc_out(bp, CD180_COR2, port->COR2);
829 rc_out(bp, CD180_COR3, cor3);
830 /* Make CD180 know about registers change */
831 rc_wait_CCR(bp);
832 rc_out(bp, CD180_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
833 /* Setting up modem option registers */
834 rc_out(bp, CD180_MCOR1, mcor1);
835 rc_out(bp, CD180_MCOR2, mcor2);
836 /* Enable CD180 transmitter & receiver */
837 rc_wait_CCR(bp);
838 rc_out(bp, CD180_CCR, CCR_TXEN | CCR_RXEN);
839 /* Enable interrupts */
840 rc_out(bp, CD180_IER, port->IER);
841 /* And finally set RTS on */
842 rc_out(bp, CD180_MSVR, port->MSVR);
845 /* Must be called with interrupts enabled */
846 static intrc_setup_port(struct riscom_board *bp,struct riscom_port *port)
848 unsigned long flags;
850 if(port->flags & ASYNC_INITIALIZED)
851 return0;
853 if(!port->xmit_buf) {
854 /* We may sleep in get_free_page() */
855 unsigned long tmp;
857 if(!(tmp =get_free_page(GFP_KERNEL)))
858 return-ENOMEM;
860 if(port->xmit_buf) {
861 free_page(tmp);
862 return-ERESTARTSYS;
864 port->xmit_buf = (unsigned char*) tmp;
867 save_flags(flags);cli();
869 if(port->tty)
870 clear_bit(TTY_IO_ERROR, &port->tty->flags);
872 if(port->count ==1)
873 bp->count++;
875 port->xmit_cnt = port->xmit_head = port->xmit_tail =0;
876 rc_change_speed(bp, port);
877 port->flags |= ASYNC_INITIALIZED;
879 restore_flags(flags);
880 return0;
883 /* Must be called with interrupts disabled */
884 static voidrc_shutdown_port(struct riscom_board *bp,struct riscom_port *port)
886 struct tty_struct *tty;
888 if(!(port->flags & ASYNC_INITIALIZED))
889 return;
891 #ifdef RC_REPORT_OVERRUN
892 printk("rc%d: port %d: Total %ld overruns were detected.\n",
893 board_No(bp),port_No(port), port->overrun);
894 #endif
895 #ifdef RC_REPORT_FIFO
897 int i;
899 printk("rc%d: port %d: FIFO hits [ ",
900 board_No(bp),port_No(port));
901 for(i =0; i <10; i++) {
902 printk("%ld ", port->hits[i]);
904 printk("].\n");
906 #endif
907 if(port->xmit_buf) {
908 free_page((unsigned long) port->xmit_buf);
909 port->xmit_buf = NULL;
912 if(!(tty = port->tty) ||C_HUPCL(tty)) {
913 /* Drop DTR */
914 bp->DTR |= (1u<<port_No(port));
915 rc_out(bp, RC_DTR, bp->DTR);
918 /* Select port */
919 rc_out(bp, CD180_CAR,port_No(port));
920 /* Reset port */
921 rc_wait_CCR(bp);
922 rc_out(bp, CD180_CCR, CCR_SOFTRESET);
923 /* Disable all interrupts from this port */
924 port->IER =0;
925 rc_out(bp, CD180_IER, port->IER);
927 if(tty)
928 set_bit(TTY_IO_ERROR, &tty->flags);
929 port->flags &= ~ASYNC_INITIALIZED;
931 if(--bp->count <0) {
932 printk("rc%d: rc_shutdown_port: bad board count: %d\n",
933 board_No(bp), bp->count);
934 bp->count =0;
938 * If this is the last opened port on the board
939 * shutdown whole board
941 if(!bp->count)
942 rc_shutdown_board(bp);
946 static intblock_til_ready(struct tty_struct *tty,struct file * filp,
947 struct riscom_port *port)
949 struct wait_queue wait = { current, NULL };
950 struct riscom_board *bp =port_Board(port);
951 int retval;
952 int do_clocal =0;
953 int CD;
956 * If the device is in the middle of being closed, then block
957 * until it's done, and then try again.
959 if(tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
960 interruptible_sleep_on(&port->close_wait);
961 if(port->flags & ASYNC_HUP_NOTIFY)
962 return-EAGAIN;
963 else
964 return-ERESTARTSYS;
968 * If this is a callout device, then just make sure the normal
969 * device isn't being used.
971 if(tty->driver.subtype == RISCOM_TYPE_CALLOUT) {
972 if(port->flags & ASYNC_NORMAL_ACTIVE)
973 return-EBUSY;
974 if((port->flags & ASYNC_CALLOUT_ACTIVE) &&
975 (port->flags & ASYNC_SESSION_LOCKOUT) &&
976 (port->session != current->session))
977 return-EBUSY;
978 if((port->flags & ASYNC_CALLOUT_ACTIVE) &&
979 (port->flags & ASYNC_PGRP_LOCKOUT) &&
980 (port->pgrp != current->pgrp))
981 return-EBUSY;
982 port->flags |= ASYNC_CALLOUT_ACTIVE;
983 return0;
987 * If non-blocking mode is set, or the port is not enabled,
988 * then make the check up front and then exit.
990 if((filp->f_flags & O_NONBLOCK) ||
991 (tty->flags & (1<< TTY_IO_ERROR))) {
992 if(port->flags & ASYNC_CALLOUT_ACTIVE)
993 return-EBUSY;
994 port->flags |= ASYNC_NORMAL_ACTIVE;
995 return0;
998 if(port->flags & ASYNC_CALLOUT_ACTIVE) {
999 if(port->normal_termios.c_cflag & CLOCAL)
1000 do_clocal =1;
1001 }else{
1002 if(C_CLOCAL(tty))
1003 do_clocal =1;
1007 * Block waiting for the carrier detect and the line to become
1008 * free (i.e., not in use by the callout). While we are in
1009 * this loop, info->count is dropped by one, so that
1010 * rs_close() knows when to free things. We restore it upon
1011 * exit, either normal or abnormal.
1013 retval =0;
1014 add_wait_queue(&port->open_wait, &wait);
1015 cli();
1016 if(!tty_hung_up_p(filp))
1017 port->count--;
1018 sti();
1019 port->blocked_open++;
1020 while(1) {
1021 cli();
1022 rc_out(bp, CD180_CAR,port_No(port));
1023 CD =rc_in(bp, CD180_MSVR) & MSVR_CD;
1024 if(!(port->flags & ASYNC_CALLOUT_ACTIVE)) {
1025 rc_out(bp, CD180_MSVR, MSVR_RTS);
1026 bp->DTR &= ~(1u<<port_No(port));
1027 rc_out(bp, RC_DTR, bp->DTR);
1029 sti();
1030 current->state = TASK_INTERRUPTIBLE;
1031 if(tty_hung_up_p(filp) ||
1032 !(port->flags & ASYNC_INITIALIZED)) {
1033 if(port->flags & ASYNC_HUP_NOTIFY)
1034 retval = -EAGAIN;
1035 else
1036 retval = -ERESTARTSYS;
1037 break;
1039 if(!(port->flags & ASYNC_CALLOUT_ACTIVE) &&
1040 !(port->flags & ASYNC_CLOSING) &&
1041 (do_clocal || CD))
1042 break;
1043 if(signal_pending(current)) {
1044 retval = -ERESTARTSYS;
1045 break;
1047 schedule();
1049 current->state = TASK_RUNNING;
1050 remove_wait_queue(&port->open_wait, &wait);
1051 if(!tty_hung_up_p(filp))
1052 port->count++;
1053 port->blocked_open--;
1054 if(retval)
1055 return retval;
1057 port->flags |= ASYNC_NORMAL_ACTIVE;
1058 return0;
1061 static intrc_open(struct tty_struct * tty,struct file * filp)
1063 int board;
1064 int error;
1065 struct riscom_port * port;
1066 struct riscom_board * bp;
1067 unsigned long flags;
1069 board =RC_BOARD(MINOR(tty->device));
1070 if(board > RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT))
1071 return-ENODEV;
1073 bp = &rc_board[board];
1074 port = rc_port + board * RC_NPORT +RC_PORT(MINOR(tty->device));
1075 if(rc_paranoia_check(port, tty->device,"rc_open"))
1076 return-ENODEV;
1078 if((error =rc_setup_board(bp)))
1079 return error;
1081 port->count++;
1082 tty->driver_data = port;
1083 port->tty = tty;
1085 if((error =rc_setup_port(bp, port)))
1086 return error;
1088 if((error =block_til_ready(tty, filp, port)))
1089 return error;
1091 if((port->count ==1) && (port->flags & ASYNC_SPLIT_TERMIOS)) {
1092 if(tty->driver.subtype == RISCOM_TYPE_NORMAL)
1093 *tty->termios = port->normal_termios;
1094 else
1095 *tty->termios = port->callout_termios;
1096 save_flags(flags);cli();
1097 rc_change_speed(bp, port);
1098 restore_flags(flags);
1101 port->session = current->session;
1102 port->pgrp = current->pgrp;
1104 return0;
1107 static voidrc_close(struct tty_struct * tty,struct file * filp)
1109 struct riscom_port *port = (struct riscom_port *) tty->driver_data;
1110 struct riscom_board *bp;
1111 unsigned long flags;
1112 unsigned long timeout;
1114 if(!port ||rc_paranoia_check(port, tty->device,"close"))
1115 return;
1117 save_flags(flags);cli();
1118 if(tty_hung_up_p(filp)) {
1119 restore_flags(flags);
1120 return;
1123 bp =port_Board(port);
1124 if((tty->count ==1) && (port->count !=1)) {
1125 printk("rc%d: rc_close: bad port count;"
1126 " tty->count is 1, port count is %d\n",
1127 board_No(bp), port->count);
1128 port->count =1;
1130 if(--port->count <0) {
1131 printk("rc%d: rc_close: bad port count for tty%d: %d\n",
1132 board_No(bp),port_No(port), port->count);
1133 port->count =0;
1135 if(port->count) {
1136 restore_flags(flags);
1137 return;
1139 port->flags |= ASYNC_CLOSING;
1141 * Save the termios structure, since this port may have
1142 * separate termios for callout and dialin.
1144 if(port->flags & ASYNC_NORMAL_ACTIVE)
1145 port->normal_termios = *tty->termios;
1146 if(port->flags & ASYNC_CALLOUT_ACTIVE)
1147 port->callout_termios = *tty->termios;
1149 * Now we wait for the transmit buffer to clear; and we notify
1150 * the line discipline to only process XON/XOFF characters.
1152 tty->closing =1;
1153 if(port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1154 tty_wait_until_sent(tty, port->closing_wait);
1156 * At this point we stop accepting input. To do this, we
1157 * disable the receive line status interrupts, and tell the
1158 * interrupt driver to stop checking the data ready bit in the
1159 * line status register.
1161 port->IER &= ~IER_RXD;
1162 if(port->flags & ASYNC_INITIALIZED) {
1163 port->IER &= ~IER_TXRDY;
1164 port->IER |= IER_TXEMPTY;
1165 rc_out(bp, CD180_CAR,port_No(port));
1166 rc_out(bp, CD180_IER, port->IER);
1168 * Before we drop DTR, make sure the UART transmitter
1169 * has completely drained; this is especially
1170 * important if there is a transmit FIFO!
1172 timeout = jiffies+HZ;
1173 while(port->IER & IER_TXEMPTY) {
1174 current->state = TASK_INTERRUPTIBLE;
1175 current->timeout = jiffies + port->timeout;
1176 schedule();
1177 if(jiffies > timeout)
1178 break;
1181 rc_shutdown_port(bp, port);
1182 if(tty->driver.flush_buffer)
1183 tty->driver.flush_buffer(tty);
1184 if(tty->ldisc.flush_buffer)
1185 tty->ldisc.flush_buffer(tty);
1186 tty->closing =0;
1187 port->event =0;
1188 port->tty =0;
1189 if(port->blocked_open) {
1190 if(port->close_delay) {
1191 current->state = TASK_INTERRUPTIBLE;
1192 current->timeout = jiffies + port->close_delay;
1193 schedule();
1195 wake_up_interruptible(&port->open_wait);
1197 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
1198 ASYNC_CLOSING);
1199 wake_up_interruptible(&port->close_wait);
1200 restore_flags(flags);
1203 static intrc_write(struct tty_struct * tty,int from_user,
1204 const unsigned char*buf,int count)
1206 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1207 struct riscom_board *bp;
1208 int c, total =0;
1209 unsigned long flags;
1211 if(rc_paranoia_check(port, tty->device,"rc_write"))
1212 return0;
1214 bp =port_Board(port);
1216 if(!tty || !port->xmit_buf || !tmp_buf)
1217 return0;
1219 if(from_user)
1220 down(&tmp_buf_sem);
1222 save_flags(flags);
1223 while(1) {
1224 cli();
1225 c =MIN(count,MIN(SERIAL_XMIT_SIZE - port->xmit_cnt -1,
1226 SERIAL_XMIT_SIZE - port->xmit_head));
1227 if(c <=0)
1228 break;
1230 if(from_user) {
1231 copy_from_user(tmp_buf, buf, c);
1232 c =MIN(c,MIN(SERIAL_XMIT_SIZE - port->xmit_cnt -1,
1233 SERIAL_XMIT_SIZE - port->xmit_head));
1234 memcpy(port->xmit_buf + port->xmit_head, tmp_buf, c);
1235 }else
1236 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1237 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1238 port->xmit_cnt += c;
1239 restore_flags(flags);
1240 buf += c;
1241 count -= c;
1242 total += c;
1244 if(from_user)
1245 up(&tmp_buf_sem);
1246 if(port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1247 !(port->IER & IER_TXRDY)) {
1248 port->IER |= IER_TXRDY;
1249 rc_out(bp, CD180_CAR,port_No(port));
1250 rc_out(bp, CD180_IER, port->IER);
1252 restore_flags(flags);
1253 return total;
1256 static voidrc_put_char(struct tty_struct * tty,unsigned char ch)
1258 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1259 unsigned long flags;
1261 if(rc_paranoia_check(port, tty->device,"rc_put_char"))
1262 return;
1264 if(!tty || !port->xmit_buf)
1265 return;
1267 save_flags(flags);cli();
1269 if(port->xmit_cnt >= SERIAL_XMIT_SIZE -1) {
1270 restore_flags(flags);
1271 return;
1274 port->xmit_buf[port->xmit_head++] = ch;
1275 port->xmit_head &= SERIAL_XMIT_SIZE -1;
1276 port->xmit_cnt++;
1277 restore_flags(flags);
1280 static voidrc_flush_chars(struct tty_struct * tty)
1282 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1283 unsigned long flags;
1285 if(rc_paranoia_check(port, tty->device,"rc_flush_chars"))
1286 return;
1288 if(port->xmit_cnt <=0|| tty->stopped || tty->hw_stopped ||
1289 !port->xmit_buf)
1290 return;
1292 save_flags(flags);cli();
1293 port->IER |= IER_TXRDY;
1294 rc_out(port_Board(port), CD180_CAR,port_No(port));
1295 rc_out(port_Board(port), CD180_IER, port->IER);
1296 restore_flags(flags);
1299 static intrc_write_room(struct tty_struct * tty)
1301 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1302 int ret;
1304 if(rc_paranoia_check(port, tty->device,"rc_write_room"))
1305 return0;
1307 ret = SERIAL_XMIT_SIZE - port->xmit_cnt -1;
1308 if(ret <0)
1309 ret =0;
1310 return ret;
1313 static intrc_chars_in_buffer(struct tty_struct *tty)
1315 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1317 if(rc_paranoia_check(port, tty->device,"rc_chars_in_buffer"))
1318 return0;
1320 return port->xmit_cnt;
1323 static voidrc_flush_buffer(struct tty_struct *tty)
1325 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1326 unsigned long flags;
1328 if(rc_paranoia_check(port, tty->device,"rc_flush_buffer"))
1329 return;
1331 save_flags(flags);cli();
1332 port->xmit_cnt = port->xmit_head = port->xmit_tail =0;
1333 restore_flags(flags);
1335 wake_up_interruptible(&tty->write_wait);
1336 if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP)) &&
1337 tty->ldisc.write_wakeup)
1338 (tty->ldisc.write_wakeup)(tty);
1341 static intrc_get_modem_info(struct riscom_port * port,unsigned int*value)
1343 struct riscom_board * bp;
1344 unsigned char status;
1345 unsigned int result;
1346 unsigned long flags;
1348 bp =port_Board(port);
1349 save_flags(flags);cli();
1350 rc_out(bp, CD180_CAR,port_No(port));
1351 status =rc_in(bp, CD180_MSVR);
1352 result =rc_in(bp, RC_RI) & (1u<<port_No(port)) ?0: TIOCM_RNG;
1353 restore_flags(flags);
1354 result |= ((status & MSVR_RTS) ? TIOCM_RTS :0)
1355 | ((status & MSVR_DTR) ? TIOCM_DTR :0)
1356 | ((status & MSVR_CD) ? TIOCM_CAR :0)
1357 | ((status & MSVR_DSR) ? TIOCM_DSR :0)
1358 | ((status & MSVR_CTS) ? TIOCM_CTS :0);
1359 put_user(result, value);
1360 return0;
1363 static intrc_set_modem_info(struct riscom_port * port,unsigned int cmd,
1364 unsigned int*value)
1366 int error;
1367 unsigned int arg;
1368 unsigned long flags;
1369 struct riscom_board *bp =port_Board(port);
1371 error =get_user(arg, value);
1372 if(error)
1373 return error;
1374 switch(cmd) {
1375 case TIOCMBIS:
1376 if(arg & TIOCM_RTS)
1377 port->MSVR |= MSVR_RTS;
1378 if(arg & TIOCM_DTR)
1379 bp->DTR &= ~(1u<<port_No(port));
1380 break;
1381 case TIOCMBIC:
1382 if(arg & TIOCM_RTS)
1383 port->MSVR &= ~MSVR_RTS;
1384 if(arg & TIOCM_DTR)
1385 bp->DTR |= (1u<<port_No(port));
1386 break;
1387 case TIOCMSET:
1388 port->MSVR = (arg & TIOCM_RTS) ? (port->MSVR | MSVR_RTS) :
1389 (port->MSVR & ~MSVR_RTS);
1390 bp->DTR = arg & TIOCM_DTR ? (bp->DTR &= ~(1u<<port_No(port))) :
1391 (bp->DTR |= (1u<<port_No(port)));
1392 break;
1393 default:
1394 return-EINVAL;
1396 save_flags(flags);cli();
1397 rc_out(bp, CD180_CAR,port_No(port));
1398 rc_out(bp, CD180_MSVR, port->MSVR);
1399 rc_out(bp, RC_DTR, bp->DTR);
1400 restore_flags(flags);
1401 return0;
1404 extern inlinevoidrc_send_break(struct riscom_port * port,unsigned long length)
1406 struct riscom_board *bp =port_Board(port);
1407 unsigned long flags;
1409 save_flags(flags);cli();
1410 port->break_length = RISCOM_TPS / HZ * length;
1411 port->COR2 |= COR2_ETC;
1412 port->IER |= IER_TXRDY;
1413 rc_out(bp, CD180_CAR,port_No(port));
1414 rc_out(bp, CD180_COR2, port->COR2);
1415 rc_out(bp, CD180_IER, port->IER);
1416 rc_wait_CCR(bp);
1417 rc_out(bp, CD180_CCR, CCR_CORCHG2);
1418 rc_wait_CCR(bp);
1419 restore_flags(flags);
1422 extern inlineintrc_set_serial_info(struct riscom_port * port,
1423 struct serial_struct * newinfo)
1425 struct serial_struct tmp;
1426 struct riscom_board *bp =port_Board(port);
1427 int change_speed;
1428 unsigned long flags;
1429 int error;
1431 error =verify_area(VERIFY_READ, (void*) newinfo,sizeof(tmp));
1432 if(error)
1433 return error;
1434 copy_from_user(&tmp, newinfo,sizeof(tmp));
1436 #if 0
1437 if((tmp.irq != bp->irq) ||
1438 (tmp.port != bp->base) ||
1439 (tmp.type != PORT_CIRRUS) ||
1440 (tmp.baud_base != (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC) ||
1441 (tmp.custom_divisor !=0) ||
1442 (tmp.xmit_fifo_size != CD180_NFIFO) ||
1443 (tmp.flags & ~RISCOM_LEGAL_FLAGS))
1444 return-EINVAL;
1445 #endif
1447 change_speed = ((port->flags & ASYNC_SPD_MASK) !=
1448 (tmp.flags & ASYNC_SPD_MASK));
1450 if(!suser()) {
1451 if((tmp.close_delay != port->close_delay) ||
1452 (tmp.closing_wait != port->closing_wait) ||
1453 ((tmp.flags & ~ASYNC_USR_MASK) !=
1454 (port->flags & ~ASYNC_USR_MASK)))
1455 return-EPERM;
1456 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
1457 (tmp.flags & ASYNC_USR_MASK));
1458 }else{
1459 port->flags = ((port->flags & ~ASYNC_FLAGS) |
1460 (tmp.flags & ASYNC_FLAGS));
1461 port->close_delay = tmp.close_delay;
1462 port->closing_wait = tmp.closing_wait;
1464 if(change_speed) {
1465 save_flags(flags);cli();
1466 rc_change_speed(bp, port);
1467 restore_flags(flags);
1469 return0;
1472 extern inlineintrc_get_serial_info(struct riscom_port * port,
1473 struct serial_struct * retinfo)
1475 struct serial_struct tmp;
1476 struct riscom_board *bp =port_Board(port);
1477 int error;
1479 error =verify_area(VERIFY_WRITE, (void*) retinfo,sizeof(tmp));
1480 if(error)
1481 return error;
1483 memset(&tmp,0,sizeof(tmp));
1484 tmp.type = PORT_CIRRUS;
1485 tmp.line = port - rc_port;
1486 tmp.port = bp->base;
1487 tmp.irq = bp->irq;
1488 tmp.flags = port->flags;
1489 tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC;
1490 tmp.close_delay = port->close_delay * HZ/100;
1491 tmp.closing_wait = port->closing_wait * HZ/100;
1492 tmp.xmit_fifo_size = CD180_NFIFO;
1493 copy_to_user(retinfo, &tmp,sizeof(tmp));
1494 return0;
1497 static intrc_ioctl(struct tty_struct * tty,struct file * filp,
1498 unsigned int cmd,unsigned long arg)
1501 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1502 int error;
1503 int retval;
1505 if(rc_paranoia_check(port, tty->device,"rc_ioctl"))
1506 return-ENODEV;
1508 switch(cmd) {
1509 case TCSBRK:/* SVID version: non-zero arg --> no break */
1510 retval =tty_check_change(tty);
1511 if(retval)
1512 return retval;
1513 tty_wait_until_sent(tty,0);
1514 if(!arg)
1515 rc_send_break(port, HZ/4);/* 1/4 second */
1516 return0;
1517 case TCSBRKP:/* support for POSIX tcsendbreak() */
1518 retval =tty_check_change(tty);
1519 if(retval)
1520 return retval;
1521 tty_wait_until_sent(tty,0);
1522 rc_send_break(port, arg ? arg*(HZ/10) : HZ/4);
1523 return0;
1524 case TIOCGSOFTCAR:
1525 returnput_user(C_CLOCAL(tty) ?1:0, (unsigned int*) arg);
1526 case TIOCSSOFTCAR:
1527 retval =get_user(arg,(unsigned int*) arg);
1528 if(retval)
1529 return retval;
1530 tty->termios->c_cflag =
1531 ((tty->termios->c_cflag & ~CLOCAL) |
1532 (arg ? CLOCAL :0));
1533 return0;
1534 case TIOCMGET:
1535 error =verify_area(VERIFY_WRITE, (void*) arg,
1536 sizeof(unsigned int));
1537 if(error)
1538 return error;
1539 returnrc_get_modem_info(port, (unsigned int*) arg);
1540 case TIOCMBIS:
1541 case TIOCMBIC:
1542 case TIOCMSET:
1543 returnrc_set_modem_info(port, cmd, (unsigned int*) arg);
1544 case TIOCGSERIAL:
1545 returnrc_get_serial_info(port, (struct serial_struct *) arg);
1546 case TIOCSSERIAL:
1547 returnrc_set_serial_info(port, (struct serial_struct *) arg);
1548 default:
1549 return-ENOIOCTLCMD;
1551 return0;
1554 static voidrc_throttle(struct tty_struct * tty)
1556 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1557 struct riscom_board *bp;
1558 unsigned long flags;
1560 if(rc_paranoia_check(port, tty->device,"rc_throttle"))
1561 return;
1563 bp =port_Board(port);
1565 save_flags(flags);cli();
1566 port->MSVR &= ~MSVR_RTS;
1567 rc_out(bp, CD180_CAR,port_No(port));
1568 if(I_IXOFF(tty)) {
1569 rc_wait_CCR(bp);
1570 rc_out(bp, CD180_CCR, CCR_SSCH2);
1571 rc_wait_CCR(bp);
1573 rc_out(bp, CD180_MSVR, port->MSVR);
1574 restore_flags(flags);
1577 static voidrc_unthrottle(struct tty_struct * tty)
1579 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1580 struct riscom_board *bp;
1581 unsigned long flags;
1583 if(rc_paranoia_check(port, tty->device,"rc_unthrottle"))
1584 return;
1586 bp =port_Board(port);
1588 save_flags(flags);cli();
1589 port->MSVR |= MSVR_RTS;
1590 rc_out(bp, CD180_CAR,port_No(port));
1591 if(I_IXOFF(tty)) {
1592 rc_wait_CCR(bp);
1593 rc_out(bp, CD180_CCR, CCR_SSCH1);
1594 rc_wait_CCR(bp);
1596 rc_out(bp, CD180_MSVR, port->MSVR);
1597 restore_flags(flags);
1600 static voidrc_stop(struct tty_struct * tty)
1602 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1603 struct riscom_board *bp;
1604 unsigned long flags;
1606 if(rc_paranoia_check(port, tty->device,"rc_stop"))
1607 return;
1609 bp =port_Board(port);
1611 save_flags(flags);cli();
1612 port->IER &= ~IER_TXRDY;
1613 rc_out(bp, CD180_CAR,port_No(port));
1614 rc_out(bp, CD180_IER, port->IER);
1615 restore_flags(flags);
1618 static voidrc_start(struct tty_struct * tty)
1620 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1621 struct riscom_board *bp;
1622 unsigned long flags;
1624 if(rc_paranoia_check(port, tty->device,"rc_start"))
1625 return;
1627 bp =port_Board(port);
1629 save_flags(flags);cli();
1630 if(port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
1631 port->IER |= IER_TXRDY;
1632 rc_out(bp, CD180_CAR,port_No(port));
1633 rc_out(bp, CD180_IER, port->IER);
1635 restore_flags(flags);
1639 * This routine is called from the scheduler tqueue when the interrupt
1640 * routine has signalled that a hangup has occurred. The path of
1641 * hangup processing is:
1643 * serial interrupt routine -> (scheduler tqueue) ->
1644 * do_rc_hangup() -> tty->hangup() -> rc_hangup()
1647 static voiddo_rc_hangup(void*private_)
1649 struct riscom_port *port = (struct riscom_port *) private_;
1650 struct tty_struct *tty;
1652 tty = port->tty;
1653 if(!tty)
1654 return;
1656 tty_hangup(tty);
1659 static voidrc_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 voidrc_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 voiddo_riscom_bh(void)
1702 run_task_queue(&tq_riscom);
1705 static voiddo_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 staticinlineintrc_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 return1;
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 return1;
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 return1;
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;
1797 return0;
1800 static voidrc_release_drivers(void)
1802 unsigned long flags;
1804 save_flags(flags);
1805 cli();
1806 remove_bh(RISCOM8_BH);
1807 free_page((unsigned long)tmp_buf);
1808 tty_unregister_driver(&riscom_driver);
1809 tty_unregister_driver(&riscom_callout_driver);
1810 restore_flags(flags);
1813 #ifndef MODULE
1815 * Called at boot time.
1817 * You can specify IO base for up to RC_NBOARD cards,
1818 * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt.
1819 * Note that there will be no probing at default
1820 * addresses in this case.
1823 __initfunc(voidriscom8_setup(char*str,int* ints))
1825 int i;
1827 for(i =0; i < RC_NBOARD; i++) {
1828 if(i < ints[0])
1829 rc_board[i].base = ints[i+1];
1830 else
1831 rc_board[i].base =0;
1834 #endif
1837 * This routine must be called by kernel at boot time
1839 __initfunc(intriscom8_init(void))
1841 int i;
1842 int found =0;
1844 printk("rc: SDL RISCom/8 card driver v1.0, (c) D.Gorodchanin 1994-1996.\n");
1846 if(rc_init_drivers())
1847 return-EIO;
1849 for(i =0; i < RC_NBOARD; i++)
1850 if(rc_board[i].base && !rc_probe(&rc_board[i]))
1851 found++;
1853 if(!found) {
1854 rc_release_drivers();
1855 printk("rc: No RISCom/8 boards detected.\n");
1856 return-EIO;
1858 return0;
1861 #ifdef MODULE
1862 int iobase =0;
1863 int iobase1 =0;
1864 int iobase2 =0;
1865 int iobase3 =0;
1866 MODULE_PARM(iobase,"i");
1867 MODULE_PARM(iobase1,"i");
1868 MODULE_PARM(iobase2,"i");
1869 MODULE_PARM(iobase3,"i");
1872 * You can setup up to 4 boards (current value of RC_NBOARD)
1873 * by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter.
1876 intinit_module(void)
1878 int i;
1880 if(iobase || iobase1 || iobase2 || iobase3) {
1881 for(i =0; i < RC_NBOARD; i++)
1882 rc_board[0].base =0;
1885 if(iobase)
1886 rc_board[0].base = iobase;
1887 if(iobase1)
1888 rc_board[1].base = iobase1;
1889 if(iobase2)
1890 rc_board[2].base = iobase2;
1891 if(iobase3)
1892 rc_board[3].base = iobase3;
1894 returnriscom8_init();
1897 voidcleanup_module(void)
1899 int i;
1901 rc_release_drivers();
1902 for(i =0; i < RC_NBOARD; i++)
1903 if(rc_board[i].flags & RC_BOARD_PRESENT)
1904 rc_release_io_range(&rc_board[i]);
1907 #endif/* MODULE */
close