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