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