[PATCH] TTY layer buffering revamp
[deliverable/linux.git] / drivers / char / riscom8.c
CommitLineData
1da177e4
LT
1/*
2 * linux/drivers/char/riscom.c -- RISCom/8 multiport serial driver.
3 *
4 * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com)
5 *
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.
11 *
12 *
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.
17 *
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.
22 *
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.
26 *
27 * Revision 1.1
28 *
29 * ChangeLog:
30 * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 27-Jun-2001
31 * - get rid of check_region and several cleanups
32 */
33
34#include <linux/module.h>
35
36#include <asm/io.h>
37#include <linux/kernel.h>
38#include <linux/sched.h>
39#include <linux/ioport.h>
40#include <linux/interrupt.h>
41#include <linux/errno.h>
42#include <linux/tty.h>
43#include <linux/mm.h>
44#include <linux/serial.h>
45#include <linux/fcntl.h>
46#include <linux/major.h>
47#include <linux/init.h>
48#include <linux/delay.h>
33f0f88f 49#include <linux/tty_flip.h>
1da177e4
LT
50
51#include <asm/uaccess.h>
52
53#include "riscom8.h"
54#include "riscom8_reg.h"
55
56/* Am I paranoid or not ? ;-) */
57#define RISCOM_PARANOIA_CHECK
58
59/*
60 * Crazy InteliCom/8 boards sometimes has swapped CTS & DSR signals.
61 * You can slightly speed up things by #undefing the following option,
62 * if you are REALLY sure that your board is correct one.
63 */
64
65#define RISCOM_BRAIN_DAMAGED_CTS
66
67/*
68 * The following defines are mostly for testing purposes. But if you need
69 * some nice reporting in your syslog, you can define them also.
70 */
71#undef RC_REPORT_FIFO
72#undef RC_REPORT_OVERRUN
73
74
75#define RISCOM_LEGAL_FLAGS \
76 (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \
77 ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \
78 ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
79
80#define RS_EVENT_WRITE_WAKEUP 0
81
82static struct riscom_board * IRQ_to_board[16];
83static struct tty_driver *riscom_driver;
84static unsigned char * tmp_buf;
85static DECLARE_MUTEX(tmp_buf_sem);
86
87static unsigned long baud_table[] = {
88 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
89 9600, 19200, 38400, 57600, 76800, 0,
90};
91
92static struct riscom_board rc_board[RC_NBOARD] = {
93 {
94 .base = RC_IOBASE1,
95 },
96 {
97 .base = RC_IOBASE2,
98 },
99 {
100 .base = RC_IOBASE3,
101 },
102 {
103 .base = RC_IOBASE4,
104 },
105};
106
107static struct riscom_port rc_port[RC_NBOARD * RC_NPORT];
108
109/* RISCom/8 I/O ports addresses (without address translation) */
110static unsigned short rc_ioport[] = {
fe971071 111#if 1
1da177e4 112 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c,
fe971071 113#else
1da177e4
LT
114 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, 0x10,
115 0x11, 0x12, 0x18, 0x28, 0x31, 0x32, 0x39, 0x3a, 0x40, 0x41, 0x61, 0x62,
116 0x63, 0x64, 0x6b, 0x70, 0x71, 0x78, 0x7a, 0x7b, 0x7f, 0x100, 0x101
fe971071 117#endif
1da177e4 118};
fe971071 119#define RC_NIOPORT ARRAY_SIZE(rc_ioport)
1da177e4
LT
120
121
122static inline int rc_paranoia_check(struct riscom_port const * port,
123 char *name, const char *routine)
124{
125#ifdef RISCOM_PARANOIA_CHECK
126 static const char badmagic[] = KERN_INFO
127 "rc: Warning: bad riscom port magic number for device %s in %s\n";
128 static const char badinfo[] = KERN_INFO
129 "rc: Warning: null riscom port for device %s in %s\n";
130
131 if (!port) {
132 printk(badinfo, name, routine);
133 return 1;
134 }
135 if (port->magic != RISCOM8_MAGIC) {
136 printk(badmagic, name, routine);
137 return 1;
138 }
139#endif
140 return 0;
141}
142
143/*
144 *
145 * Service functions for RISCom/8 driver.
146 *
147 */
148
149/* Get board number from pointer */
150static inline int board_No (struct riscom_board const * bp)
151{
152 return bp - rc_board;
153}
154
155/* Get port number from pointer */
156static inline int port_No (struct riscom_port const * port)
157{
158 return RC_PORT(port - rc_port);
159}
160
161/* Get pointer to board from pointer to port */
162static inline struct riscom_board * port_Board(struct riscom_port const * port)
163{
164 return &rc_board[RC_BOARD(port - rc_port)];
165}
166
167/* Input Byte from CL CD180 register */
168static inline unsigned char rc_in(struct riscom_board const * bp, unsigned short reg)
169{
170 return inb(bp->base + RC_TO_ISA(reg));
171}
172
173/* Output Byte to CL CD180 register */
174static inline void rc_out(struct riscom_board const * bp, unsigned short reg,
175 unsigned char val)
176{
177 outb(val, bp->base + RC_TO_ISA(reg));
178}
179
180/* Wait for Channel Command Register ready */
181static inline void rc_wait_CCR(struct riscom_board const * bp)
182{
183 unsigned long delay;
184
185 /* FIXME: need something more descriptive then 100000 :) */
186 for (delay = 100000; delay; delay--)
187 if (!rc_in(bp, CD180_CCR))
188 return;
189
190 printk(KERN_INFO "rc%d: Timeout waiting for CCR.\n", board_No(bp));
191}
192
193/*
194 * RISCom/8 probe functions.
195 */
196
197static inline int rc_request_io_range(struct riscom_board * const bp)
198{
199 int i;
200
201 for (i = 0; i < RC_NIOPORT; i++)
202 if (!request_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1,
203 "RISCom/8")) {
204 goto out_release;
205 }
206 return 0;
207out_release:
208 printk(KERN_INFO "rc%d: Skipping probe at 0x%03x. IO address in use.\n",
209 board_No(bp), bp->base);
210 while(--i >= 0)
211 release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1);
212 return 1;
213}
214
215static inline void rc_release_io_range(struct riscom_board * const bp)
216{
217 int i;
218
219 for (i = 0; i < RC_NIOPORT; i++)
220 release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1);
221}
222
223/* Must be called with enabled interrupts */
224static inline void rc_long_delay(unsigned long delay)
225{
226 unsigned long i;
227
228 for (i = jiffies + delay; time_after(i,jiffies); ) ;
229}
230
231/* Reset and setup CD180 chip */
232static void __init rc_init_CD180(struct riscom_board const * bp)
233{
234 unsigned long flags;
235
236 save_flags(flags); cli();
237 rc_out(bp, RC_CTOUT, 0); /* Clear timeout */
238 rc_wait_CCR(bp); /* Wait for CCR ready */
239 rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */
240 sti();
241 rc_long_delay(HZ/20); /* Delay 0.05 sec */
242 cli();
243 rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */
244 rc_out(bp, CD180_GICR, 0); /* Clear all bits */
245 rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */
246 rc_out(bp, CD180_PILR2, RC_ACK_TINT); /* Prio for transmitter intr */
247 rc_out(bp, CD180_PILR3, RC_ACK_RINT); /* Prio for receiver intr */
248
249 /* Setting up prescaler. We need 4 ticks per 1 ms */
250 rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8);
251 rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff);
252
253 restore_flags(flags);
254}
255
256/* Main probing routine, also sets irq. */
257static int __init rc_probe(struct riscom_board *bp)
258{
259 unsigned char val1, val2;
260 int irqs = 0;
261 int retries;
262
263 bp->irq = 0;
264
265 if (rc_request_io_range(bp))
266 return 1;
267
268 /* Are the I/O ports here ? */
269 rc_out(bp, CD180_PPRL, 0x5a);
270 outb(0xff, 0x80);
271 val1 = rc_in(bp, CD180_PPRL);
272 rc_out(bp, CD180_PPRL, 0xa5);
273 outb(0x00, 0x80);
274 val2 = rc_in(bp, CD180_PPRL);
275
276 if ((val1 != 0x5a) || (val2 != 0xa5)) {
277 printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not found.\n",
278 board_No(bp), bp->base);
279 goto out_release;
280 }
281
282 /* It's time to find IRQ for this board */
283 for (retries = 0; retries < 5 && irqs <= 0; retries++) {
284 irqs = probe_irq_on();
285 rc_init_CD180(bp); /* Reset CD180 chip */
286 rc_out(bp, CD180_CAR, 2); /* Select port 2 */
287 rc_wait_CCR(bp);
288 rc_out(bp, CD180_CCR, CCR_TXEN); /* Enable transmitter */
289 rc_out(bp, CD180_IER, IER_TXRDY); /* Enable tx empty intr */
290 rc_long_delay(HZ/20);
291 irqs = probe_irq_off(irqs);
292 val1 = rc_in(bp, RC_BSR); /* Get Board Status reg */
293 val2 = rc_in(bp, RC_ACK_TINT); /* ACK interrupt */
294 rc_init_CD180(bp); /* Reset CD180 again */
295
296 if ((val1 & RC_BSR_TINT) || (val2 != (RC_ID | GIVR_IT_TX))) {
297 printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not "
298 "found.\n", board_No(bp), bp->base);
299 goto out_release;
300 }
301 }
302
303 if (irqs <= 0) {
304 printk(KERN_ERR "rc%d: Can't find IRQ for RISCom/8 board "
305 "at 0x%03x.\n", board_No(bp), bp->base);
306 goto out_release;
307 }
308 bp->irq = irqs;
309 bp->flags |= RC_BOARD_PRESENT;
310
311 printk(KERN_INFO "rc%d: RISCom/8 Rev. %c board detected at "
312 "0x%03x, IRQ %d.\n",
313 board_No(bp),
314 (rc_in(bp, CD180_GFRCR) & 0x0f) + 'A', /* Board revision */
315 bp->base, bp->irq);
316
317 return 0;
318out_release:
319 rc_release_io_range(bp);
320 return 1;
321}
322
323/*
324 *
325 * Interrupt processing routines.
326 *
327 */
328
329static inline void rc_mark_event(struct riscom_port * port, int event)
330{
331 set_bit(event, &port->event);
332 schedule_work(&port->tqueue);
333}
334
335static inline struct riscom_port * rc_get_port(struct riscom_board const * bp,
336 unsigned char const * what)
337{
338 unsigned char channel;
339 struct riscom_port * port;
340
341 channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF;
342 if (channel < CD180_NCH) {
343 port = &rc_port[board_No(bp) * RC_NPORT + channel];
344 if (port->flags & ASYNC_INITIALIZED) {
345 return port;
346 }
347 }
348 printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n",
349 board_No(bp), what, channel);
350 return NULL;
351}
352
353static inline void rc_receive_exc(struct riscom_board const * bp)
354{
355 struct riscom_port *port;
356 struct tty_struct *tty;
357 unsigned char status;
33f0f88f 358 unsigned char ch, flag;
1da177e4
LT
359
360 if (!(port = rc_get_port(bp, "Receive")))
361 return;
362
363 tty = port->tty;
1da177e4
LT
364
365#ifdef RC_REPORT_OVERRUN
366 status = rc_in(bp, CD180_RCSR);
33f0f88f 367 if (status & RCSR_OE)
1da177e4 368 port->overrun++;
1da177e4
LT
369 status &= port->mark_mask;
370#else
371 status = rc_in(bp, CD180_RCSR) & port->mark_mask;
372#endif
373 ch = rc_in(bp, CD180_RDR);
374 if (!status) {
375 return;
376 }
377 if (status & RCSR_TOUT) {
378 printk(KERN_WARNING "rc%d: port %d: Receiver timeout. "
379 "Hardware problems ?\n",
380 board_No(bp), port_No(port));
381 return;
382
383 } else if (status & RCSR_BREAK) {
384 printk(KERN_INFO "rc%d: port %d: Handling break...\n",
385 board_No(bp), port_No(port));
33f0f88f 386 flag = TTY_BREAK;
1da177e4
LT
387 if (port->flags & ASYNC_SAK)
388 do_SAK(tty);
389
390 } else if (status & RCSR_PE)
33f0f88f 391 flag = TTY_PARITY;
1da177e4
LT
392
393 else if (status & RCSR_FE)
33f0f88f 394 flag = TTY_FRAME;
1da177e4
LT
395
396 else if (status & RCSR_OE)
33f0f88f 397 flag = TTY_OVERRUN;
1da177e4
LT
398
399 else
33f0f88f 400 flag = TTY_NORMAL;
1da177e4 401
33f0f88f
AC
402 tty_insert_flip_char(tty, ch, flag);
403 tty_flip_buffer_push(tty);
1da177e4
LT
404}
405
406static inline void rc_receive(struct riscom_board const * bp)
407{
408 struct riscom_port *port;
409 struct tty_struct *tty;
410 unsigned char count;
411
412 if (!(port = rc_get_port(bp, "Receive")))
413 return;
414
415 tty = port->tty;
416
417 count = rc_in(bp, CD180_RDCR);
418
419#ifdef RC_REPORT_FIFO
420 port->hits[count > 8 ? 9 : count]++;
421#endif
422
423 while (count--) {
33f0f88f 424 if (tty_buffer_request_room(tty, 1) == 0) {
1da177e4
LT
425 printk(KERN_WARNING "rc%d: port %d: Working around "
426 "flip buffer overflow.\n",
427 board_No(bp), port_No(port));
428 break;
429 }
33f0f88f 430 tty_insert_flip_char(tty, rc_in(bp, CD180_RDR), TTY_NORMAL);
1da177e4 431 }
33f0f88f 432 tty_flip_buffer_push(tty);
1da177e4
LT
433}
434
435static inline void rc_transmit(struct riscom_board const * bp)
436{
437 struct riscom_port *port;
438 struct tty_struct *tty;
439 unsigned char count;
440
441
442 if (!(port = rc_get_port(bp, "Transmit")))
443 return;
444
445 tty = port->tty;
446
447 if (port->IER & IER_TXEMPTY) {
448 /* FIFO drained */
449 rc_out(bp, CD180_CAR, port_No(port));
450 port->IER &= ~IER_TXEMPTY;
451 rc_out(bp, CD180_IER, port->IER);
452 return;
453 }
454
455 if ((port->xmit_cnt <= 0 && !port->break_length)
456 || tty->stopped || tty->hw_stopped) {
457 rc_out(bp, CD180_CAR, port_No(port));
458 port->IER &= ~IER_TXRDY;
459 rc_out(bp, CD180_IER, port->IER);
460 return;
461 }
462
463 if (port->break_length) {
464 if (port->break_length > 0) {
465 if (port->COR2 & COR2_ETC) {
466 rc_out(bp, CD180_TDR, CD180_C_ESC);
467 rc_out(bp, CD180_TDR, CD180_C_SBRK);
468 port->COR2 &= ~COR2_ETC;
469 }
470 count = min_t(int, port->break_length, 0xff);
471 rc_out(bp, CD180_TDR, CD180_C_ESC);
472 rc_out(bp, CD180_TDR, CD180_C_DELAY);
473 rc_out(bp, CD180_TDR, count);
474 if (!(port->break_length -= count))
475 port->break_length--;
476 } else {
477 rc_out(bp, CD180_TDR, CD180_C_ESC);
478 rc_out(bp, CD180_TDR, CD180_C_EBRK);
479 rc_out(bp, CD180_COR2, port->COR2);
480 rc_wait_CCR(bp);
481 rc_out(bp, CD180_CCR, CCR_CORCHG2);
482 port->break_length = 0;
483 }
484 return;
485 }
486
487 count = CD180_NFIFO;
488 do {
489 rc_out(bp, CD180_TDR, port->xmit_buf[port->xmit_tail++]);
490 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
491 if (--port->xmit_cnt <= 0)
492 break;
493 } while (--count > 0);
494
495 if (port->xmit_cnt <= 0) {
496 rc_out(bp, CD180_CAR, port_No(port));
497 port->IER &= ~IER_TXRDY;
498 rc_out(bp, CD180_IER, port->IER);
499 }
500 if (port->xmit_cnt <= port->wakeup_chars)
501 rc_mark_event(port, RS_EVENT_WRITE_WAKEUP);
502}
503
504static inline void rc_check_modem(struct riscom_board const * bp)
505{
506 struct riscom_port *port;
507 struct tty_struct *tty;
508 unsigned char mcr;
509
510 if (!(port = rc_get_port(bp, "Modem")))
511 return;
512
513 tty = port->tty;
514
515 mcr = rc_in(bp, CD180_MCR);
516 if (mcr & MCR_CDCHG) {
517 if (rc_in(bp, CD180_MSVR) & MSVR_CD)
518 wake_up_interruptible(&port->open_wait);
519 else
520 schedule_work(&port->tqueue_hangup);
521 }
522
523#ifdef RISCOM_BRAIN_DAMAGED_CTS
524 if (mcr & MCR_CTSCHG) {
525 if (rc_in(bp, CD180_MSVR) & MSVR_CTS) {
526 tty->hw_stopped = 0;
527 port->IER |= IER_TXRDY;
528 if (port->xmit_cnt <= port->wakeup_chars)
529 rc_mark_event(port, RS_EVENT_WRITE_WAKEUP);
530 } else {
531 tty->hw_stopped = 1;
532 port->IER &= ~IER_TXRDY;
533 }
534 rc_out(bp, CD180_IER, port->IER);
535 }
536 if (mcr & MCR_DSRCHG) {
537 if (rc_in(bp, CD180_MSVR) & MSVR_DSR) {
538 tty->hw_stopped = 0;
539 port->IER |= IER_TXRDY;
540 if (port->xmit_cnt <= port->wakeup_chars)
541 rc_mark_event(port, RS_EVENT_WRITE_WAKEUP);
542 } else {
543 tty->hw_stopped = 1;
544 port->IER &= ~IER_TXRDY;
545 }
546 rc_out(bp, CD180_IER, port->IER);
547 }
548#endif /* RISCOM_BRAIN_DAMAGED_CTS */
549
550 /* Clear change bits */
551 rc_out(bp, CD180_MCR, 0);
552}
553
554/* The main interrupt processing routine */
555static irqreturn_t rc_interrupt(int irq, void * dev_id, struct pt_regs * regs)
556{
557 unsigned char status;
558 unsigned char ack;
559 struct riscom_board *bp;
560 unsigned long loop = 0;
561 int handled = 0;
562
563 bp = IRQ_to_board[irq];
564
565 if (!bp || !(bp->flags & RC_BOARD_ACTIVE)) {
566 return IRQ_NONE;
567 }
568
569 while ((++loop < 16) && ((status = ~(rc_in(bp, RC_BSR))) &
570 (RC_BSR_TOUT | RC_BSR_TINT |
571 RC_BSR_MINT | RC_BSR_RINT))) {
572 handled = 1;
573 if (status & RC_BSR_TOUT)
574 printk(KERN_WARNING "rc%d: Got timeout. Hardware "
575 "error?\n", board_No(bp));
576
577 else if (status & RC_BSR_RINT) {
578 ack = rc_in(bp, RC_ACK_RINT);
579
580 if (ack == (RC_ID | GIVR_IT_RCV))
581 rc_receive(bp);
582 else if (ack == (RC_ID | GIVR_IT_REXC))
583 rc_receive_exc(bp);
584 else
585 printk(KERN_WARNING "rc%d: Bad receive ack "
586 "0x%02x.\n",
587 board_No(bp), ack);
588
589 } else if (status & RC_BSR_TINT) {
590 ack = rc_in(bp, RC_ACK_TINT);
591
592 if (ack == (RC_ID | GIVR_IT_TX))
593 rc_transmit(bp);
594 else
595 printk(KERN_WARNING "rc%d: Bad transmit ack "
596 "0x%02x.\n",
597 board_No(bp), ack);
598
599 } else /* if (status & RC_BSR_MINT) */ {
600 ack = rc_in(bp, RC_ACK_MINT);
601
602 if (ack == (RC_ID | GIVR_IT_MODEM))
603 rc_check_modem(bp);
604 else
605 printk(KERN_WARNING "rc%d: Bad modem ack "
606 "0x%02x.\n",
607 board_No(bp), ack);
608
609 }
610
611 rc_out(bp, CD180_EOIR, 0); /* Mark end of interrupt */
612 rc_out(bp, RC_CTOUT, 0); /* Clear timeout flag */
613 }
614 return IRQ_RETVAL(handled);
615}
616
617/*
618 * Routines for open & close processing.
619 */
620
621/* Called with disabled interrupts */
622static inline int rc_setup_board(struct riscom_board * bp)
623{
624 int error;
625
626 if (bp->flags & RC_BOARD_ACTIVE)
627 return 0;
628
629 error = request_irq(bp->irq, rc_interrupt, SA_INTERRUPT,
630 "RISCom/8", NULL);
631 if (error)
632 return error;
633
634 rc_out(bp, RC_CTOUT, 0); /* Just in case */
635 bp->DTR = ~0;
636 rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */
637
638 IRQ_to_board[bp->irq] = bp;
639 bp->flags |= RC_BOARD_ACTIVE;
640
641 return 0;
642}
643
644/* Called with disabled interrupts */
645static inline void rc_shutdown_board(struct riscom_board *bp)
646{
647 if (!(bp->flags & RC_BOARD_ACTIVE))
648 return;
649
650 bp->flags &= ~RC_BOARD_ACTIVE;
651
652 free_irq(bp->irq, NULL);
653 IRQ_to_board[bp->irq] = NULL;
654
655 bp->DTR = ~0;
656 rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */
657
658}
659
660/*
661 * Setting up port characteristics.
662 * Must be called with disabled interrupts
663 */
664static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
665{
666 struct tty_struct *tty;
667 unsigned long baud;
668 long tmp;
669 unsigned char cor1 = 0, cor3 = 0;
670 unsigned char mcor1 = 0, mcor2 = 0;
671
672 if (!(tty = port->tty) || !tty->termios)
673 return;
674
675 port->IER = 0;
676 port->COR2 = 0;
677 port->MSVR = MSVR_RTS;
678
679 baud = C_BAUD(tty);
680
681 if (baud & CBAUDEX) {
682 baud &= ~CBAUDEX;
683 if (baud < 1 || baud > 2)
684 port->tty->termios->c_cflag &= ~CBAUDEX;
685 else
686 baud += 15;
687 }
688 if (baud == 15) {
689 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
690 baud ++;
691 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
692 baud += 2;
693 }
694
695 /* Select port on the board */
696 rc_out(bp, CD180_CAR, port_No(port));
697
698 if (!baud_table[baud]) {
699 /* Drop DTR & exit */
700 bp->DTR |= (1u << port_No(port));
701 rc_out(bp, RC_DTR, bp->DTR);
702 return;
703 } else {
704 /* Set DTR on */
705 bp->DTR &= ~(1u << port_No(port));
706 rc_out(bp, RC_DTR, bp->DTR);
707 }
708
709 /*
710 * Now we must calculate some speed depended things
711 */
712
713 /* Set baud rate for port */
714 tmp = (((RC_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
715 CD180_TPC/2) / CD180_TPC);
716
717 rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff);
718 rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff);
719 rc_out(bp, CD180_RBPRL, tmp & 0xff);
720 rc_out(bp, CD180_TBPRL, tmp & 0xff);
721
722 baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */
723
724 /* Two timer ticks seems enough to wakeup something like SLIP driver */
725 tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;
726 port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
727 SERIAL_XMIT_SIZE - 1 : tmp);
728
729 /* Receiver timeout will be transmission time for 1.5 chars */
730 tmp = (RISCOM_TPS + RISCOM_TPS/2 + baud/2) / baud;
731 tmp = (tmp > 0xff) ? 0xff : tmp;
732 rc_out(bp, CD180_RTPR, tmp);
733
734 switch (C_CSIZE(tty)) {
735 case CS5:
736 cor1 |= COR1_5BITS;
737 break;
738 case CS6:
739 cor1 |= COR1_6BITS;
740 break;
741 case CS7:
742 cor1 |= COR1_7BITS;
743 break;
744 case CS8:
745 cor1 |= COR1_8BITS;
746 break;
747 }
748
749 if (C_CSTOPB(tty))
750 cor1 |= COR1_2SB;
751
752 cor1 |= COR1_IGNORE;
753 if (C_PARENB(tty)) {
754 cor1 |= COR1_NORMPAR;
755 if (C_PARODD(tty))
756 cor1 |= COR1_ODDP;
757 if (I_INPCK(tty))
758 cor1 &= ~COR1_IGNORE;
759 }
760 /* Set marking of some errors */
761 port->mark_mask = RCSR_OE | RCSR_TOUT;
762 if (I_INPCK(tty))
763 port->mark_mask |= RCSR_FE | RCSR_PE;
764 if (I_BRKINT(tty) || I_PARMRK(tty))
765 port->mark_mask |= RCSR_BREAK;
766 if (I_IGNPAR(tty))
767 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
768 if (I_IGNBRK(tty)) {
769 port->mark_mask &= ~RCSR_BREAK;
770 if (I_IGNPAR(tty))
771 /* Real raw mode. Ignore all */
772 port->mark_mask &= ~RCSR_OE;
773 }
774 /* Enable Hardware Flow Control */
775 if (C_CRTSCTS(tty)) {
776#ifdef RISCOM_BRAIN_DAMAGED_CTS
777 port->IER |= IER_DSR | IER_CTS;
778 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
779 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
780 tty->hw_stopped = !(rc_in(bp, CD180_MSVR) & (MSVR_CTS|MSVR_DSR));
781#else
782 port->COR2 |= COR2_CTSAE;
783#endif
784 }
785 /* Enable Software Flow Control. FIXME: I'm not sure about this */
786 /* Some people reported that it works, but I still doubt */
787 if (I_IXON(tty)) {
788 port->COR2 |= COR2_TXIBE;
789 cor3 |= (COR3_FCT | COR3_SCDE);
790 if (I_IXANY(tty))
791 port->COR2 |= COR2_IXM;
792 rc_out(bp, CD180_SCHR1, START_CHAR(tty));
793 rc_out(bp, CD180_SCHR2, STOP_CHAR(tty));
794 rc_out(bp, CD180_SCHR3, START_CHAR(tty));
795 rc_out(bp, CD180_SCHR4, STOP_CHAR(tty));
796 }
797 if (!C_CLOCAL(tty)) {
798 /* Enable CD check */
799 port->IER |= IER_CD;
800 mcor1 |= MCOR1_CDZD;
801 mcor2 |= MCOR2_CDOD;
802 }
803
804 if (C_CREAD(tty))
805 /* Enable receiver */
806 port->IER |= IER_RXD;
807
808 /* Set input FIFO size (1-8 bytes) */
809 cor3 |= RISCOM_RXFIFO;
810 /* Setting up CD180 channel registers */
811 rc_out(bp, CD180_COR1, cor1);
812 rc_out(bp, CD180_COR2, port->COR2);
813 rc_out(bp, CD180_COR3, cor3);
814 /* Make CD180 know about registers change */
815 rc_wait_CCR(bp);
816 rc_out(bp, CD180_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
817 /* Setting up modem option registers */
818 rc_out(bp, CD180_MCOR1, mcor1);
819 rc_out(bp, CD180_MCOR2, mcor2);
820 /* Enable CD180 transmitter & receiver */
821 rc_wait_CCR(bp);
822 rc_out(bp, CD180_CCR, CCR_TXEN | CCR_RXEN);
823 /* Enable interrupts */
824 rc_out(bp, CD180_IER, port->IER);
825 /* And finally set RTS on */
826 rc_out(bp, CD180_MSVR, port->MSVR);
827}
828
829/* Must be called with interrupts enabled */
830static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
831{
832 unsigned long flags;
833
834 if (port->flags & ASYNC_INITIALIZED)
835 return 0;
836
837 if (!port->xmit_buf) {
838 /* We may sleep in get_zeroed_page() */
839 unsigned long tmp;
840
841 if (!(tmp = get_zeroed_page(GFP_KERNEL)))
842 return -ENOMEM;
843
844 if (port->xmit_buf) {
845 free_page(tmp);
846 return -ERESTARTSYS;
847 }
848 port->xmit_buf = (unsigned char *) tmp;
849 }
850
851 save_flags(flags); cli();
852
853 if (port->tty)
854 clear_bit(TTY_IO_ERROR, &port->tty->flags);
855
856 if (port->count == 1)
857 bp->count++;
858
859 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
860 rc_change_speed(bp, port);
861 port->flags |= ASYNC_INITIALIZED;
862
863 restore_flags(flags);
864 return 0;
865}
866
867/* Must be called with interrupts disabled */
868static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
869{
870 struct tty_struct *tty;
871
872 if (!(port->flags & ASYNC_INITIALIZED))
873 return;
874
875#ifdef RC_REPORT_OVERRUN
876 printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n",
877 board_No(bp), port_No(port), port->overrun);
878#endif
879#ifdef RC_REPORT_FIFO
880 {
881 int i;
882
883 printk(KERN_INFO "rc%d: port %d: FIFO hits [ ",
884 board_No(bp), port_No(port));
885 for (i = 0; i < 10; i++) {
886 printk("%ld ", port->hits[i]);
887 }
888 printk("].\n");
889 }
890#endif
891 if (port->xmit_buf) {
892 free_page((unsigned long) port->xmit_buf);
893 port->xmit_buf = NULL;
894 }
895
896 if (!(tty = port->tty) || C_HUPCL(tty)) {
897 /* Drop DTR */
898 bp->DTR |= (1u << port_No(port));
899 rc_out(bp, RC_DTR, bp->DTR);
900 }
901
902 /* Select port */
903 rc_out(bp, CD180_CAR, port_No(port));
904 /* Reset port */
905 rc_wait_CCR(bp);
906 rc_out(bp, CD180_CCR, CCR_SOFTRESET);
907 /* Disable all interrupts from this port */
908 port->IER = 0;
909 rc_out(bp, CD180_IER, port->IER);
910
911 if (tty)
912 set_bit(TTY_IO_ERROR, &tty->flags);
913 port->flags &= ~ASYNC_INITIALIZED;
914
915 if (--bp->count < 0) {
916 printk(KERN_INFO "rc%d: rc_shutdown_port: "
917 "bad board count: %d\n",
918 board_No(bp), bp->count);
919 bp->count = 0;
920 }
921
922 /*
923 * If this is the last opened port on the board
924 * shutdown whole board
925 */
926 if (!bp->count)
927 rc_shutdown_board(bp);
928}
929
930
931static int block_til_ready(struct tty_struct *tty, struct file * filp,
932 struct riscom_port *port)
933{
934 DECLARE_WAITQUEUE(wait, current);
935 struct riscom_board *bp = port_Board(port);
936 int retval;
937 int do_clocal = 0;
938 int CD;
939
940 /*
941 * If the device is in the middle of being closed, then block
942 * until it's done, and then try again.
943 */
944 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
945 interruptible_sleep_on(&port->close_wait);
946 if (port->flags & ASYNC_HUP_NOTIFY)
947 return -EAGAIN;
948 else
949 return -ERESTARTSYS;
950 }
951
952 /*
953 * If non-blocking mode is set, or the port is not enabled,
954 * then make the check up front and then exit.
955 */
956 if ((filp->f_flags & O_NONBLOCK) ||
957 (tty->flags & (1 << TTY_IO_ERROR))) {
958 port->flags |= ASYNC_NORMAL_ACTIVE;
959 return 0;
960 }
961
962 if (C_CLOCAL(tty))
963 do_clocal = 1;
964
965 /*
966 * Block waiting for the carrier detect and the line to become
967 * free (i.e., not in use by the callout). While we are in
968 * this loop, info->count is dropped by one, so that
969 * rs_close() knows when to free things. We restore it upon
970 * exit, either normal or abnormal.
971 */
972 retval = 0;
973 add_wait_queue(&port->open_wait, &wait);
974 cli();
975 if (!tty_hung_up_p(filp))
976 port->count--;
977 sti();
978 port->blocked_open++;
979 while (1) {
980 cli();
981 rc_out(bp, CD180_CAR, port_No(port));
982 CD = rc_in(bp, CD180_MSVR) & MSVR_CD;
983 rc_out(bp, CD180_MSVR, MSVR_RTS);
984 bp->DTR &= ~(1u << port_No(port));
985 rc_out(bp, RC_DTR, bp->DTR);
986 sti();
987 set_current_state(TASK_INTERRUPTIBLE);
988 if (tty_hung_up_p(filp) ||
989 !(port->flags & ASYNC_INITIALIZED)) {
990 if (port->flags & ASYNC_HUP_NOTIFY)
991 retval = -EAGAIN;
992 else
993 retval = -ERESTARTSYS;
994 break;
995 }
996 if (!(port->flags & ASYNC_CLOSING) &&
997 (do_clocal || CD))
998 break;
999 if (signal_pending(current)) {
1000 retval = -ERESTARTSYS;
1001 break;
1002 }
1003 schedule();
1004 }
1005 current->state = TASK_RUNNING;
1006 remove_wait_queue(&port->open_wait, &wait);
1007 if (!tty_hung_up_p(filp))
1008 port->count++;
1009 port->blocked_open--;
1010 if (retval)
1011 return retval;
1012
1013 port->flags |= ASYNC_NORMAL_ACTIVE;
1014 return 0;
1015}
1016
1017static int rc_open(struct tty_struct * tty, struct file * filp)
1018{
1019 int board;
1020 int error;
1021 struct riscom_port * port;
1022 struct riscom_board * bp;
1023
1024 board = RC_BOARD(tty->index);
1025 if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT))
1026 return -ENODEV;
1027
1028 bp = &rc_board[board];
1029 port = rc_port + board * RC_NPORT + RC_PORT(tty->index);
1030 if (rc_paranoia_check(port, tty->name, "rc_open"))
1031 return -ENODEV;
1032
1033 if ((error = rc_setup_board(bp)))
1034 return error;
1035
1036 port->count++;
1037 tty->driver_data = port;
1038 port->tty = tty;
1039
1040 if ((error = rc_setup_port(bp, port)))
1041 return error;
1042
1043 if ((error = block_til_ready(tty, filp, port)))
1044 return error;
1045
1046 return 0;
1047}
1048
1049static void rc_close(struct tty_struct * tty, struct file * filp)
1050{
1051 struct riscom_port *port = (struct riscom_port *) tty->driver_data;
1052 struct riscom_board *bp;
1053 unsigned long flags;
1054 unsigned long timeout;
1055
1056 if (!port || rc_paranoia_check(port, tty->name, "close"))
1057 return;
1058
1059 save_flags(flags); cli();
1060 if (tty_hung_up_p(filp))
1061 goto out;
1062
1063 bp = port_Board(port);
1064 if ((tty->count == 1) && (port->count != 1)) {
1065 printk(KERN_INFO "rc%d: rc_close: bad port count;"
1066 " tty->count is 1, port count is %d\n",
1067 board_No(bp), port->count);
1068 port->count = 1;
1069 }
1070 if (--port->count < 0) {
1071 printk(KERN_INFO "rc%d: rc_close: bad port count "
1072 "for tty%d: %d\n",
1073 board_No(bp), port_No(port), port->count);
1074 port->count = 0;
1075 }
1076 if (port->count)
1077 goto out;
1078 port->flags |= ASYNC_CLOSING;
1079 /*
1080 * Now we wait for the transmit buffer to clear; and we notify
1081 * the line discipline to only process XON/XOFF characters.
1082 */
1083 tty->closing = 1;
1084 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1085 tty_wait_until_sent(tty, port->closing_wait);
1086 /*
1087 * At this point we stop accepting input. To do this, we
1088 * disable the receive line status interrupts, and tell the
1089 * interrupt driver to stop checking the data ready bit in the
1090 * line status register.
1091 */
1092 port->IER &= ~IER_RXD;
1093 if (port->flags & ASYNC_INITIALIZED) {
1094 port->IER &= ~IER_TXRDY;
1095 port->IER |= IER_TXEMPTY;
1096 rc_out(bp, CD180_CAR, port_No(port));
1097 rc_out(bp, CD180_IER, port->IER);
1098 /*
1099 * Before we drop DTR, make sure the UART transmitter
1100 * has completely drained; this is especially
1101 * important if there is a transmit FIFO!
1102 */
1103 timeout = jiffies+HZ;
1104 while(port->IER & IER_TXEMPTY) {
1105 msleep_interruptible(jiffies_to_msecs(port->timeout));
1106 if (time_after(jiffies, timeout))
1107 break;
1108 }
1109 }
1110 rc_shutdown_port(bp, port);
1111 if (tty->driver->flush_buffer)
1112 tty->driver->flush_buffer(tty);
1113 tty_ldisc_flush(tty);
1114
1115 tty->closing = 0;
1116 port->event = 0;
1117 port->tty = NULL;
1118 if (port->blocked_open) {
1119 if (port->close_delay) {
1120 msleep_interruptible(jiffies_to_msecs(port->close_delay));
1121 }
1122 wake_up_interruptible(&port->open_wait);
1123 }
1124 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1125 wake_up_interruptible(&port->close_wait);
1126out: restore_flags(flags);
1127}
1128
1129static int rc_write(struct tty_struct * tty,
1130 const unsigned char *buf, int count)
1131{
1132 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1133 struct riscom_board *bp;
1134 int c, total = 0;
1135 unsigned long flags;
1136
1137 if (rc_paranoia_check(port, tty->name, "rc_write"))
1138 return 0;
1139
1140 bp = port_Board(port);
1141
1142 if (!tty || !port->xmit_buf || !tmp_buf)
1143 return 0;
1144
1145 save_flags(flags);
1146 while (1) {
1147 cli();
1148 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1149 SERIAL_XMIT_SIZE - port->xmit_head));
1150 if (c <= 0) {
1151 restore_flags(flags);
1152 break;
1153 }
1154
1155 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1156 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1157 port->xmit_cnt += c;
1158 restore_flags(flags);
1159
1160 buf += c;
1161 count -= c;
1162 total += c;
1163 }
1164
1165 cli();
1166 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1167 !(port->IER & IER_TXRDY)) {
1168 port->IER |= IER_TXRDY;
1169 rc_out(bp, CD180_CAR, port_No(port));
1170 rc_out(bp, CD180_IER, port->IER);
1171 }
1172 restore_flags(flags);
1173
1174 return total;
1175}
1176
1177static void rc_put_char(struct tty_struct * tty, unsigned char ch)
1178{
1179 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1180 unsigned long flags;
1181
1182 if (rc_paranoia_check(port, tty->name, "rc_put_char"))
1183 return;
1184
1185 if (!tty || !port->xmit_buf)
1186 return;
1187
1188 save_flags(flags); cli();
1189
1190 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
1191 goto out;
1192
1193 port->xmit_buf[port->xmit_head++] = ch;
1194 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1195 port->xmit_cnt++;
1196out: restore_flags(flags);
1197}
1198
1199static void rc_flush_chars(struct tty_struct * tty)
1200{
1201 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1202 unsigned long flags;
1203
1204 if (rc_paranoia_check(port, tty->name, "rc_flush_chars"))
1205 return;
1206
1207 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1208 !port->xmit_buf)
1209 return;
1210
1211 save_flags(flags); cli();
1212 port->IER |= IER_TXRDY;
1213 rc_out(port_Board(port), CD180_CAR, port_No(port));
1214 rc_out(port_Board(port), CD180_IER, port->IER);
1215 restore_flags(flags);
1216}
1217
1218static int rc_write_room(struct tty_struct * tty)
1219{
1220 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1221 int ret;
1222
1223 if (rc_paranoia_check(port, tty->name, "rc_write_room"))
1224 return 0;
1225
1226 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1227 if (ret < 0)
1228 ret = 0;
1229 return ret;
1230}
1231
1232static int rc_chars_in_buffer(struct tty_struct *tty)
1233{
1234 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1235
1236 if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer"))
1237 return 0;
1238
1239 return port->xmit_cnt;
1240}
1241
1242static void rc_flush_buffer(struct tty_struct *tty)
1243{
1244 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1245 unsigned long flags;
1246
1247 if (rc_paranoia_check(port, tty->name, "rc_flush_buffer"))
1248 return;
1249
1250 save_flags(flags); cli();
1251 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1252 restore_flags(flags);
1253
1254 wake_up_interruptible(&tty->write_wait);
1255 tty_wakeup(tty);
1256}
1257
1258static int rc_tiocmget(struct tty_struct *tty, struct file *file)
1259{
1260 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1261 struct riscom_board * bp;
1262 unsigned char status;
1263 unsigned int result;
1264 unsigned long flags;
1265
1266 if (rc_paranoia_check(port, tty->name, __FUNCTION__))
1267 return -ENODEV;
1268
1269 bp = port_Board(port);
1270 save_flags(flags); cli();
1271 rc_out(bp, CD180_CAR, port_No(port));
1272 status = rc_in(bp, CD180_MSVR);
1273 result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG;
1274 restore_flags(flags);
1275 result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0)
1276 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1277 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1278 | ((status & MSVR_DSR) ? TIOCM_DSR : 0)
1279 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1280 return result;
1281}
1282
1283static int rc_tiocmset(struct tty_struct *tty, struct file *file,
1284 unsigned int set, unsigned int clear)
1285{
1286 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1287 unsigned long flags;
1288 struct riscom_board *bp;
1289
1290 if (rc_paranoia_check(port, tty->name, __FUNCTION__))
1291 return -ENODEV;
1292
1293 bp = port_Board(port);
1294
1295 save_flags(flags); cli();
1296 if (set & TIOCM_RTS)
1297 port->MSVR |= MSVR_RTS;
1298 if (set & TIOCM_DTR)
1299 bp->DTR &= ~(1u << port_No(port));
1300
1301 if (clear & TIOCM_RTS)
1302 port->MSVR &= ~MSVR_RTS;
1303 if (clear & TIOCM_DTR)
1304 bp->DTR |= (1u << port_No(port));
1305
1306 rc_out(bp, CD180_CAR, port_No(port));
1307 rc_out(bp, CD180_MSVR, port->MSVR);
1308 rc_out(bp, RC_DTR, bp->DTR);
1309 restore_flags(flags);
1310 return 0;
1311}
1312
1313static inline void rc_send_break(struct riscom_port * port, unsigned long length)
1314{
1315 struct riscom_board *bp = port_Board(port);
1316 unsigned long flags;
1317
1318 save_flags(flags); cli();
1319 port->break_length = RISCOM_TPS / HZ * length;
1320 port->COR2 |= COR2_ETC;
1321 port->IER |= IER_TXRDY;
1322 rc_out(bp, CD180_CAR, port_No(port));
1323 rc_out(bp, CD180_COR2, port->COR2);
1324 rc_out(bp, CD180_IER, port->IER);
1325 rc_wait_CCR(bp);
1326 rc_out(bp, CD180_CCR, CCR_CORCHG2);
1327 rc_wait_CCR(bp);
1328 restore_flags(flags);
1329}
1330
1331static inline int rc_set_serial_info(struct riscom_port * port,
1332 struct serial_struct __user * newinfo)
1333{
1334 struct serial_struct tmp;
1335 struct riscom_board *bp = port_Board(port);
1336 int change_speed;
1337 unsigned long flags;
1338
1339 if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
1340 return -EFAULT;
1341
1342#if 0
1343 if ((tmp.irq != bp->irq) ||
1344 (tmp.port != bp->base) ||
1345 (tmp.type != PORT_CIRRUS) ||
1346 (tmp.baud_base != (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC) ||
1347 (tmp.custom_divisor != 0) ||
1348 (tmp.xmit_fifo_size != CD180_NFIFO) ||
1349 (tmp.flags & ~RISCOM_LEGAL_FLAGS))
1350 return -EINVAL;
1351#endif
1352
1353 change_speed = ((port->flags & ASYNC_SPD_MASK) !=
1354 (tmp.flags & ASYNC_SPD_MASK));
1355
1356 if (!capable(CAP_SYS_ADMIN)) {
1357 if ((tmp.close_delay != port->close_delay) ||
1358 (tmp.closing_wait != port->closing_wait) ||
1359 ((tmp.flags & ~ASYNC_USR_MASK) !=
1360 (port->flags & ~ASYNC_USR_MASK)))
1361 return -EPERM;
1362 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
1363 (tmp.flags & ASYNC_USR_MASK));
1364 } else {
1365 port->flags = ((port->flags & ~ASYNC_FLAGS) |
1366 (tmp.flags & ASYNC_FLAGS));
1367 port->close_delay = tmp.close_delay;
1368 port->closing_wait = tmp.closing_wait;
1369 }
1370 if (change_speed) {
1371 save_flags(flags); cli();
1372 rc_change_speed(bp, port);
1373 restore_flags(flags);
1374 }
1375 return 0;
1376}
1377
1378static inline int rc_get_serial_info(struct riscom_port * port,
1379 struct serial_struct __user *retinfo)
1380{
1381 struct serial_struct tmp;
1382 struct riscom_board *bp = port_Board(port);
1383
1384 memset(&tmp, 0, sizeof(tmp));
1385 tmp.type = PORT_CIRRUS;
1386 tmp.line = port - rc_port;
1387 tmp.port = bp->base;
1388 tmp.irq = bp->irq;
1389 tmp.flags = port->flags;
1390 tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC;
1391 tmp.close_delay = port->close_delay * HZ/100;
1392 tmp.closing_wait = port->closing_wait * HZ/100;
1393 tmp.xmit_fifo_size = CD180_NFIFO;
1394 return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0;
1395}
1396
1397static int rc_ioctl(struct tty_struct * tty, struct file * filp,
1398 unsigned int cmd, unsigned long arg)
1399
1400{
1401 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1402 void __user *argp = (void __user *)arg;
1403 int retval;
1404
1405 if (rc_paranoia_check(port, tty->name, "rc_ioctl"))
1406 return -ENODEV;
1407
1408 switch (cmd) {
1409 case TCSBRK: /* SVID version: non-zero arg --> no break */
1410 retval = tty_check_change(tty);
1411 if (retval)
1412 return retval;
1413 tty_wait_until_sent(tty, 0);
1414 if (!arg)
1415 rc_send_break(port, HZ/4); /* 1/4 second */
1416 break;
1417 case TCSBRKP: /* support for POSIX tcsendbreak() */
1418 retval = tty_check_change(tty);
1419 if (retval)
1420 return retval;
1421 tty_wait_until_sent(tty, 0);
1422 rc_send_break(port, arg ? arg*(HZ/10) : HZ/4);
1423 break;
1424 case TIOCGSOFTCAR:
1425 return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned __user *)argp);
1426 case TIOCSSOFTCAR:
1427 if (get_user(arg,(unsigned __user *) argp))
1428 return -EFAULT;
1429 tty->termios->c_cflag =
1430 ((tty->termios->c_cflag & ~CLOCAL) |
1431 (arg ? CLOCAL : 0));
1432 break;
1433 case TIOCGSERIAL:
1434 return rc_get_serial_info(port, argp);
1435 case TIOCSSERIAL:
1436 return rc_set_serial_info(port, argp);
1437 default:
1438 return -ENOIOCTLCMD;
1439 }
1440 return 0;
1441}
1442
1443static void rc_throttle(struct tty_struct * tty)
1444{
1445 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1446 struct riscom_board *bp;
1447 unsigned long flags;
1448
1449 if (rc_paranoia_check(port, tty->name, "rc_throttle"))
1450 return;
1451
1452 bp = port_Board(port);
1453
1454 save_flags(flags); cli();
1455 port->MSVR &= ~MSVR_RTS;
1456 rc_out(bp, CD180_CAR, port_No(port));
1457 if (I_IXOFF(tty)) {
1458 rc_wait_CCR(bp);
1459 rc_out(bp, CD180_CCR, CCR_SSCH2);
1460 rc_wait_CCR(bp);
1461 }
1462 rc_out(bp, CD180_MSVR, port->MSVR);
1463 restore_flags(flags);
1464}
1465
1466static void rc_unthrottle(struct tty_struct * tty)
1467{
1468 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1469 struct riscom_board *bp;
1470 unsigned long flags;
1471
1472 if (rc_paranoia_check(port, tty->name, "rc_unthrottle"))
1473 return;
1474
1475 bp = port_Board(port);
1476
1477 save_flags(flags); cli();
1478 port->MSVR |= MSVR_RTS;
1479 rc_out(bp, CD180_CAR, port_No(port));
1480 if (I_IXOFF(tty)) {
1481 rc_wait_CCR(bp);
1482 rc_out(bp, CD180_CCR, CCR_SSCH1);
1483 rc_wait_CCR(bp);
1484 }
1485 rc_out(bp, CD180_MSVR, port->MSVR);
1486 restore_flags(flags);
1487}
1488
1489static void rc_stop(struct tty_struct * tty)
1490{
1491 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1492 struct riscom_board *bp;
1493 unsigned long flags;
1494
1495 if (rc_paranoia_check(port, tty->name, "rc_stop"))
1496 return;
1497
1498 bp = port_Board(port);
1499
1500 save_flags(flags); cli();
1501 port->IER &= ~IER_TXRDY;
1502 rc_out(bp, CD180_CAR, port_No(port));
1503 rc_out(bp, CD180_IER, port->IER);
1504 restore_flags(flags);
1505}
1506
1507static void rc_start(struct tty_struct * tty)
1508{
1509 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1510 struct riscom_board *bp;
1511 unsigned long flags;
1512
1513 if (rc_paranoia_check(port, tty->name, "rc_start"))
1514 return;
1515
1516 bp = port_Board(port);
1517
1518 save_flags(flags); cli();
1519 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
1520 port->IER |= IER_TXRDY;
1521 rc_out(bp, CD180_CAR, port_No(port));
1522 rc_out(bp, CD180_IER, port->IER);
1523 }
1524 restore_flags(flags);
1525}
1526
1527/*
1528 * This routine is called from the work queue when the interrupt
1529 * routine has signalled that a hangup has occurred. The path of
1530 * hangup processing is:
1531 *
1532 * serial interrupt routine -> (workqueue) ->
1533 * do_rc_hangup() -> tty->hangup() -> rc_hangup()
1534 *
1535 */
1536static void do_rc_hangup(void *private_)
1537{
1538 struct riscom_port *port = (struct riscom_port *) private_;
1539 struct tty_struct *tty;
1540
1541 tty = port->tty;
1542 if (tty)
1543 tty_hangup(tty); /* FIXME: module removal race still here */
1544}
1545
1546static void rc_hangup(struct tty_struct * tty)
1547{
1548 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1549 struct riscom_board *bp;
1550
1551 if (rc_paranoia_check(port, tty->name, "rc_hangup"))
1552 return;
1553
1554 bp = port_Board(port);
1555
1556 rc_shutdown_port(bp, port);
1557 port->event = 0;
1558 port->count = 0;
1559 port->flags &= ~ASYNC_NORMAL_ACTIVE;
1560 port->tty = NULL;
1561 wake_up_interruptible(&port->open_wait);
1562}
1563
1564static void rc_set_termios(struct tty_struct * tty, struct termios * old_termios)
1565{
1566 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1567 unsigned long flags;
1568
1569 if (rc_paranoia_check(port, tty->name, "rc_set_termios"))
1570 return;
1571
1572 if (tty->termios->c_cflag == old_termios->c_cflag &&
1573 tty->termios->c_iflag == old_termios->c_iflag)
1574 return;
1575
1576 save_flags(flags); cli();
1577 rc_change_speed(port_Board(port), port);
1578 restore_flags(flags);
1579
1580 if ((old_termios->c_cflag & CRTSCTS) &&
1581 !(tty->termios->c_cflag & CRTSCTS)) {
1582 tty->hw_stopped = 0;
1583 rc_start(tty);
1584 }
1585}
1586
1587static void do_softint(void *private_)
1588{
1589 struct riscom_port *port = (struct riscom_port *) private_;
1590 struct tty_struct *tty;
1591
1592 if(!(tty = port->tty))
1593 return;
1594
1595 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
1596 tty_wakeup(tty);
1597 wake_up_interruptible(&tty->write_wait);
1598 }
1599}
1600
1601static struct tty_operations riscom_ops = {
1602 .open = rc_open,
1603 .close = rc_close,
1604 .write = rc_write,
1605 .put_char = rc_put_char,
1606 .flush_chars = rc_flush_chars,
1607 .write_room = rc_write_room,
1608 .chars_in_buffer = rc_chars_in_buffer,
1609 .flush_buffer = rc_flush_buffer,
1610 .ioctl = rc_ioctl,
1611 .throttle = rc_throttle,
1612 .unthrottle = rc_unthrottle,
1613 .set_termios = rc_set_termios,
1614 .stop = rc_stop,
1615 .start = rc_start,
1616 .hangup = rc_hangup,
1617 .tiocmget = rc_tiocmget,
1618 .tiocmset = rc_tiocmset,
1619};
1620
1621static inline int rc_init_drivers(void)
1622{
1623 int error;
1624 int i;
1625
1626 riscom_driver = alloc_tty_driver(RC_NBOARD * RC_NPORT);
1627 if (!riscom_driver)
1628 return -ENOMEM;
1629
1630 if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
1631 printk(KERN_ERR "rc: Couldn't get free page.\n");
1632 put_tty_driver(riscom_driver);
1633 return 1;
1634 }
1635 memset(IRQ_to_board, 0, sizeof(IRQ_to_board));
1636 riscom_driver->owner = THIS_MODULE;
1637 riscom_driver->name = "ttyL";
1638 riscom_driver->devfs_name = "tts/L";
1639 riscom_driver->major = RISCOM8_NORMAL_MAJOR;
1640 riscom_driver->type = TTY_DRIVER_TYPE_SERIAL;
1641 riscom_driver->subtype = SERIAL_TYPE_NORMAL;
1642 riscom_driver->init_termios = tty_std_termios;
1643 riscom_driver->init_termios.c_cflag =
1644 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1645 riscom_driver->flags = TTY_DRIVER_REAL_RAW;
1646 tty_set_operations(riscom_driver, &riscom_ops);
1647 if ((error = tty_register_driver(riscom_driver))) {
1648 free_page((unsigned long)tmp_buf);
1649 put_tty_driver(riscom_driver);
1650 printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, "
1651 "error = %d\n",
1652 error);
1653 return 1;
1654 }
1655
1656 memset(rc_port, 0, sizeof(rc_port));
1657 for (i = 0; i < RC_NPORT * RC_NBOARD; i++) {
1658 rc_port[i].magic = RISCOM8_MAGIC;
1659 INIT_WORK(&rc_port[i].tqueue, do_softint, &rc_port[i]);
1660 INIT_WORK(&rc_port[i].tqueue_hangup, do_rc_hangup, &rc_port[i]);
1661 rc_port[i].close_delay = 50 * HZ/100;
1662 rc_port[i].closing_wait = 3000 * HZ/100;
1663 init_waitqueue_head(&rc_port[i].open_wait);
1664 init_waitqueue_head(&rc_port[i].close_wait);
1665 }
1666
1667 return 0;
1668}
1669
1670static void rc_release_drivers(void)
1671{
1672 unsigned long flags;
1673
1674 save_flags(flags);
1675 cli();
1676 free_page((unsigned long)tmp_buf);
1677 tty_unregister_driver(riscom_driver);
1678 put_tty_driver(riscom_driver);
1679 restore_flags(flags);
1680}
1681
1682#ifndef MODULE
1683/*
1684 * Called at boot time.
1685 *
1686 * You can specify IO base for up to RC_NBOARD cards,
1687 * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt.
1688 * Note that there will be no probing at default
1689 * addresses in this case.
1690 *
1691 */
1692static int __init riscom8_setup(char *str)
1693{
1694 int ints[RC_NBOARD];
1695 int i;
1696
1697 str = get_options(str, ARRAY_SIZE(ints), ints);
1698
1699 for (i = 0; i < RC_NBOARD; i++) {
1700 if (i < ints[0])
1701 rc_board[i].base = ints[i+1];
1702 else
1703 rc_board[i].base = 0;
1704 }
1705 return 1;
1706}
1707
1708__setup("riscom8=", riscom8_setup);
1709#endif
1710
1711static char banner[] __initdata =
1712 KERN_INFO "rc: SDL RISCom/8 card driver v1.1, (c) D.Gorodchanin "
1713 "1994-1996.\n";
1714static char no_boards_msg[] __initdata =
1715 KERN_INFO "rc: No RISCom/8 boards detected.\n";
1716
1717/*
1718 * This routine must be called by kernel at boot time
1719 */
1720static int __init riscom8_init(void)
1721{
1722 int i;
1723 int found = 0;
1724
1725 printk(banner);
1726
1727 if (rc_init_drivers())
1728 return -EIO;
1729
1730 for (i = 0; i < RC_NBOARD; i++)
1731 if (rc_board[i].base && !rc_probe(&rc_board[i]))
1732 found++;
1733
1734 if (!found) {
1735 rc_release_drivers();
1736 printk(no_boards_msg);
1737 return -EIO;
1738 }
1739 return 0;
1740}
1741
1742#ifdef MODULE
1743static int iobase;
1744static int iobase1;
1745static int iobase2;
1746static int iobase3;
1747MODULE_PARM(iobase, "i");
1748MODULE_PARM(iobase1, "i");
1749MODULE_PARM(iobase2, "i");
1750MODULE_PARM(iobase3, "i");
1751
1752MODULE_LICENSE("GPL");
1753#endif /* MODULE */
1754
1755/*
1756 * You can setup up to 4 boards (current value of RC_NBOARD)
1757 * by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter.
1758 *
1759 */
1760static int __init riscom8_init_module (void)
1761{
1762#ifdef MODULE
1763 int i;
1764
1765 if (iobase || iobase1 || iobase2 || iobase3) {
1766 for(i = 0; i < RC_NBOARD; i++)
1767 rc_board[0].base = 0;
1768 }
1769
1770 if (iobase)
1771 rc_board[0].base = iobase;
1772 if (iobase1)
1773 rc_board[1].base = iobase1;
1774 if (iobase2)
1775 rc_board[2].base = iobase2;
1776 if (iobase3)
1777 rc_board[3].base = iobase3;
1778#endif /* MODULE */
1779
1780 return riscom8_init();
1781}
1782
1783static void __exit riscom8_exit_module (void)
1784{
1785 int i;
1786
1787 rc_release_drivers();
1788 for (i = 0; i < RC_NBOARD; i++)
1789 if (rc_board[i].flags & RC_BOARD_PRESENT)
1790 rc_release_io_range(&rc_board[i]);
1791
1792}
1793
1794module_init(riscom8_init_module);
1795module_exit(riscom8_exit_module);
1796
This page took 0.185187 seconds and 5 git commands to generate.