blob: 214d850112fde66bcbff652fc2561926fcd16923 [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
Thomas Gleixner0f2ed4c2006-07-01 19:29:33 -0700628 error = request_irq(bp->irq, rc_interrupt, IRQF_DISABLED,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 "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
Alan Coxc7bce302006-09-30 23:27:24 -0700678 baud = tty_get_baud_rate(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679
680 /* Select port on the board */
681 rc_out(bp, CD180_CAR, port_No(port));
682
Alan Coxc7bce302006-09-30 23:27:24 -0700683 if (!baud) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 /* Drop DTR & exit */
685 bp->DTR |= (1u << port_No(port));
686 rc_out(bp, RC_DTR, bp->DTR);
687 return;
688 } else {
689 /* Set DTR on */
690 bp->DTR &= ~(1u << port_No(port));
691 rc_out(bp, RC_DTR, bp->DTR);
692 }
693
694 /*
695 * Now we must calculate some speed depended things
696 */
697
698 /* Set baud rate for port */
Alan Coxc7bce302006-09-30 23:27:24 -0700699 tmp = (((RC_OSCFREQ + baud/2) / baud +
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 CD180_TPC/2) / CD180_TPC);
701
702 rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff);
703 rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff);
704 rc_out(bp, CD180_RBPRL, tmp & 0xff);
705 rc_out(bp, CD180_TBPRL, tmp & 0xff);
706
Alan Coxc7bce302006-09-30 23:27:24 -0700707 baud = (baud + 5) / 10; /* Estimated CPS */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708
709 /* Two timer ticks seems enough to wakeup something like SLIP driver */
710 tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;
711 port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
712 SERIAL_XMIT_SIZE - 1 : tmp);
713
714 /* Receiver timeout will be transmission time for 1.5 chars */
715 tmp = (RISCOM_TPS + RISCOM_TPS/2 + baud/2) / baud;
716 tmp = (tmp > 0xff) ? 0xff : tmp;
717 rc_out(bp, CD180_RTPR, tmp);
718
719 switch (C_CSIZE(tty)) {
720 case CS5:
721 cor1 |= COR1_5BITS;
722 break;
723 case CS6:
724 cor1 |= COR1_6BITS;
725 break;
726 case CS7:
727 cor1 |= COR1_7BITS;
728 break;
729 case CS8:
730 cor1 |= COR1_8BITS;
731 break;
732 }
733
734 if (C_CSTOPB(tty))
735 cor1 |= COR1_2SB;
736
737 cor1 |= COR1_IGNORE;
738 if (C_PARENB(tty)) {
739 cor1 |= COR1_NORMPAR;
740 if (C_PARODD(tty))
741 cor1 |= COR1_ODDP;
742 if (I_INPCK(tty))
743 cor1 &= ~COR1_IGNORE;
744 }
745 /* Set marking of some errors */
746 port->mark_mask = RCSR_OE | RCSR_TOUT;
747 if (I_INPCK(tty))
748 port->mark_mask |= RCSR_FE | RCSR_PE;
749 if (I_BRKINT(tty) || I_PARMRK(tty))
750 port->mark_mask |= RCSR_BREAK;
751 if (I_IGNPAR(tty))
752 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
753 if (I_IGNBRK(tty)) {
754 port->mark_mask &= ~RCSR_BREAK;
755 if (I_IGNPAR(tty))
756 /* Real raw mode. Ignore all */
757 port->mark_mask &= ~RCSR_OE;
758 }
759 /* Enable Hardware Flow Control */
760 if (C_CRTSCTS(tty)) {
761#ifdef RISCOM_BRAIN_DAMAGED_CTS
762 port->IER |= IER_DSR | IER_CTS;
763 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
764 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
765 tty->hw_stopped = !(rc_in(bp, CD180_MSVR) & (MSVR_CTS|MSVR_DSR));
766#else
767 port->COR2 |= COR2_CTSAE;
768#endif
769 }
770 /* Enable Software Flow Control. FIXME: I'm not sure about this */
771 /* Some people reported that it works, but I still doubt */
772 if (I_IXON(tty)) {
773 port->COR2 |= COR2_TXIBE;
774 cor3 |= (COR3_FCT | COR3_SCDE);
775 if (I_IXANY(tty))
776 port->COR2 |= COR2_IXM;
777 rc_out(bp, CD180_SCHR1, START_CHAR(tty));
778 rc_out(bp, CD180_SCHR2, STOP_CHAR(tty));
779 rc_out(bp, CD180_SCHR3, START_CHAR(tty));
780 rc_out(bp, CD180_SCHR4, STOP_CHAR(tty));
781 }
782 if (!C_CLOCAL(tty)) {
783 /* Enable CD check */
784 port->IER |= IER_CD;
785 mcor1 |= MCOR1_CDZD;
786 mcor2 |= MCOR2_CDOD;
787 }
788
789 if (C_CREAD(tty))
790 /* Enable receiver */
791 port->IER |= IER_RXD;
792
793 /* Set input FIFO size (1-8 bytes) */
794 cor3 |= RISCOM_RXFIFO;
795 /* Setting up CD180 channel registers */
796 rc_out(bp, CD180_COR1, cor1);
797 rc_out(bp, CD180_COR2, port->COR2);
798 rc_out(bp, CD180_COR3, cor3);
799 /* Make CD180 know about registers change */
800 rc_wait_CCR(bp);
801 rc_out(bp, CD180_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
802 /* Setting up modem option registers */
803 rc_out(bp, CD180_MCOR1, mcor1);
804 rc_out(bp, CD180_MCOR2, mcor2);
805 /* Enable CD180 transmitter & receiver */
806 rc_wait_CCR(bp);
807 rc_out(bp, CD180_CCR, CCR_TXEN | CCR_RXEN);
808 /* Enable interrupts */
809 rc_out(bp, CD180_IER, port->IER);
810 /* And finally set RTS on */
811 rc_out(bp, CD180_MSVR, port->MSVR);
812}
813
814/* Must be called with interrupts enabled */
815static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
816{
817 unsigned long flags;
818
819 if (port->flags & ASYNC_INITIALIZED)
820 return 0;
821
822 if (!port->xmit_buf) {
823 /* We may sleep in get_zeroed_page() */
824 unsigned long tmp;
825
826 if (!(tmp = get_zeroed_page(GFP_KERNEL)))
827 return -ENOMEM;
828
829 if (port->xmit_buf) {
830 free_page(tmp);
831 return -ERESTARTSYS;
832 }
833 port->xmit_buf = (unsigned char *) tmp;
834 }
835
836 save_flags(flags); cli();
837
838 if (port->tty)
839 clear_bit(TTY_IO_ERROR, &port->tty->flags);
840
841 if (port->count == 1)
842 bp->count++;
843
844 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
845 rc_change_speed(bp, port);
846 port->flags |= ASYNC_INITIALIZED;
847
848 restore_flags(flags);
849 return 0;
850}
851
852/* Must be called with interrupts disabled */
853static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
854{
855 struct tty_struct *tty;
856
857 if (!(port->flags & ASYNC_INITIALIZED))
858 return;
859
860#ifdef RC_REPORT_OVERRUN
861 printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n",
862 board_No(bp), port_No(port), port->overrun);
863#endif
864#ifdef RC_REPORT_FIFO
865 {
866 int i;
867
868 printk(KERN_INFO "rc%d: port %d: FIFO hits [ ",
869 board_No(bp), port_No(port));
870 for (i = 0; i < 10; i++) {
871 printk("%ld ", port->hits[i]);
872 }
873 printk("].\n");
874 }
875#endif
876 if (port->xmit_buf) {
877 free_page((unsigned long) port->xmit_buf);
878 port->xmit_buf = NULL;
879 }
880
881 if (!(tty = port->tty) || C_HUPCL(tty)) {
882 /* Drop DTR */
883 bp->DTR |= (1u << port_No(port));
884 rc_out(bp, RC_DTR, bp->DTR);
885 }
886
887 /* Select port */
888 rc_out(bp, CD180_CAR, port_No(port));
889 /* Reset port */
890 rc_wait_CCR(bp);
891 rc_out(bp, CD180_CCR, CCR_SOFTRESET);
892 /* Disable all interrupts from this port */
893 port->IER = 0;
894 rc_out(bp, CD180_IER, port->IER);
895
896 if (tty)
897 set_bit(TTY_IO_ERROR, &tty->flags);
898 port->flags &= ~ASYNC_INITIALIZED;
899
900 if (--bp->count < 0) {
901 printk(KERN_INFO "rc%d: rc_shutdown_port: "
902 "bad board count: %d\n",
903 board_No(bp), bp->count);
904 bp->count = 0;
905 }
906
907 /*
908 * If this is the last opened port on the board
909 * shutdown whole board
910 */
911 if (!bp->count)
912 rc_shutdown_board(bp);
913}
914
915
916static int block_til_ready(struct tty_struct *tty, struct file * filp,
917 struct riscom_port *port)
918{
919 DECLARE_WAITQUEUE(wait, current);
920 struct riscom_board *bp = port_Board(port);
921 int retval;
922 int do_clocal = 0;
923 int CD;
924
925 /*
926 * If the device is in the middle of being closed, then block
927 * until it's done, and then try again.
928 */
929 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
930 interruptible_sleep_on(&port->close_wait);
931 if (port->flags & ASYNC_HUP_NOTIFY)
932 return -EAGAIN;
933 else
934 return -ERESTARTSYS;
935 }
936
937 /*
938 * If non-blocking mode is set, or the port is not enabled,
939 * then make the check up front and then exit.
940 */
941 if ((filp->f_flags & O_NONBLOCK) ||
942 (tty->flags & (1 << TTY_IO_ERROR))) {
943 port->flags |= ASYNC_NORMAL_ACTIVE;
944 return 0;
945 }
946
947 if (C_CLOCAL(tty))
948 do_clocal = 1;
949
950 /*
951 * Block waiting for the carrier detect and the line to become
952 * free (i.e., not in use by the callout). While we are in
953 * this loop, info->count is dropped by one, so that
954 * rs_close() knows when to free things. We restore it upon
955 * exit, either normal or abnormal.
956 */
957 retval = 0;
958 add_wait_queue(&port->open_wait, &wait);
959 cli();
960 if (!tty_hung_up_p(filp))
961 port->count--;
962 sti();
963 port->blocked_open++;
964 while (1) {
965 cli();
966 rc_out(bp, CD180_CAR, port_No(port));
967 CD = rc_in(bp, CD180_MSVR) & MSVR_CD;
968 rc_out(bp, CD180_MSVR, MSVR_RTS);
969 bp->DTR &= ~(1u << port_No(port));
970 rc_out(bp, RC_DTR, bp->DTR);
971 sti();
972 set_current_state(TASK_INTERRUPTIBLE);
973 if (tty_hung_up_p(filp) ||
974 !(port->flags & ASYNC_INITIALIZED)) {
975 if (port->flags & ASYNC_HUP_NOTIFY)
976 retval = -EAGAIN;
977 else
978 retval = -ERESTARTSYS;
979 break;
980 }
981 if (!(port->flags & ASYNC_CLOSING) &&
982 (do_clocal || CD))
983 break;
984 if (signal_pending(current)) {
985 retval = -ERESTARTSYS;
986 break;
987 }
988 schedule();
989 }
990 current->state = TASK_RUNNING;
991 remove_wait_queue(&port->open_wait, &wait);
992 if (!tty_hung_up_p(filp))
993 port->count++;
994 port->blocked_open--;
995 if (retval)
996 return retval;
997
998 port->flags |= ASYNC_NORMAL_ACTIVE;
999 return 0;
1000}
1001
1002static int rc_open(struct tty_struct * tty, struct file * filp)
1003{
1004 int board;
1005 int error;
1006 struct riscom_port * port;
1007 struct riscom_board * bp;
1008
1009 board = RC_BOARD(tty->index);
1010 if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT))
1011 return -ENODEV;
1012
1013 bp = &rc_board[board];
1014 port = rc_port + board * RC_NPORT + RC_PORT(tty->index);
1015 if (rc_paranoia_check(port, tty->name, "rc_open"))
1016 return -ENODEV;
1017
1018 if ((error = rc_setup_board(bp)))
1019 return error;
1020
1021 port->count++;
1022 tty->driver_data = port;
1023 port->tty = tty;
1024
1025 if ((error = rc_setup_port(bp, port)))
1026 return error;
1027
1028 if ((error = block_til_ready(tty, filp, port)))
1029 return error;
1030
1031 return 0;
1032}
1033
1034static void rc_close(struct tty_struct * tty, struct file * filp)
1035{
1036 struct riscom_port *port = (struct riscom_port *) tty->driver_data;
1037 struct riscom_board *bp;
1038 unsigned long flags;
1039 unsigned long timeout;
1040
1041 if (!port || rc_paranoia_check(port, tty->name, "close"))
1042 return;
1043
1044 save_flags(flags); cli();
1045 if (tty_hung_up_p(filp))
1046 goto out;
1047
1048 bp = port_Board(port);
1049 if ((tty->count == 1) && (port->count != 1)) {
1050 printk(KERN_INFO "rc%d: rc_close: bad port count;"
1051 " tty->count is 1, port count is %d\n",
1052 board_No(bp), port->count);
1053 port->count = 1;
1054 }
1055 if (--port->count < 0) {
1056 printk(KERN_INFO "rc%d: rc_close: bad port count "
1057 "for tty%d: %d\n",
1058 board_No(bp), port_No(port), port->count);
1059 port->count = 0;
1060 }
1061 if (port->count)
1062 goto out;
1063 port->flags |= ASYNC_CLOSING;
1064 /*
1065 * Now we wait for the transmit buffer to clear; and we notify
1066 * the line discipline to only process XON/XOFF characters.
1067 */
1068 tty->closing = 1;
1069 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1070 tty_wait_until_sent(tty, port->closing_wait);
1071 /*
1072 * At this point we stop accepting input. To do this, we
1073 * disable the receive line status interrupts, and tell the
1074 * interrupt driver to stop checking the data ready bit in the
1075 * line status register.
1076 */
1077 port->IER &= ~IER_RXD;
1078 if (port->flags & ASYNC_INITIALIZED) {
1079 port->IER &= ~IER_TXRDY;
1080 port->IER |= IER_TXEMPTY;
1081 rc_out(bp, CD180_CAR, port_No(port));
1082 rc_out(bp, CD180_IER, port->IER);
1083 /*
1084 * Before we drop DTR, make sure the UART transmitter
1085 * has completely drained; this is especially
1086 * important if there is a transmit FIFO!
1087 */
1088 timeout = jiffies+HZ;
1089 while(port->IER & IER_TXEMPTY) {
1090 msleep_interruptible(jiffies_to_msecs(port->timeout));
1091 if (time_after(jiffies, timeout))
1092 break;
1093 }
1094 }
1095 rc_shutdown_port(bp, port);
1096 if (tty->driver->flush_buffer)
1097 tty->driver->flush_buffer(tty);
1098 tty_ldisc_flush(tty);
1099
1100 tty->closing = 0;
1101 port->event = 0;
1102 port->tty = NULL;
1103 if (port->blocked_open) {
1104 if (port->close_delay) {
1105 msleep_interruptible(jiffies_to_msecs(port->close_delay));
1106 }
1107 wake_up_interruptible(&port->open_wait);
1108 }
1109 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1110 wake_up_interruptible(&port->close_wait);
1111out: restore_flags(flags);
1112}
1113
1114static int rc_write(struct tty_struct * tty,
1115 const unsigned char *buf, int count)
1116{
1117 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1118 struct riscom_board *bp;
1119 int c, total = 0;
1120 unsigned long flags;
1121
1122 if (rc_paranoia_check(port, tty->name, "rc_write"))
1123 return 0;
1124
1125 bp = port_Board(port);
1126
1127 if (!tty || !port->xmit_buf || !tmp_buf)
1128 return 0;
1129
1130 save_flags(flags);
1131 while (1) {
1132 cli();
1133 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1134 SERIAL_XMIT_SIZE - port->xmit_head));
1135 if (c <= 0) {
1136 restore_flags(flags);
1137 break;
1138 }
1139
1140 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1141 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1142 port->xmit_cnt += c;
1143 restore_flags(flags);
1144
1145 buf += c;
1146 count -= c;
1147 total += c;
1148 }
1149
1150 cli();
1151 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1152 !(port->IER & IER_TXRDY)) {
1153 port->IER |= IER_TXRDY;
1154 rc_out(bp, CD180_CAR, port_No(port));
1155 rc_out(bp, CD180_IER, port->IER);
1156 }
1157 restore_flags(flags);
1158
1159 return total;
1160}
1161
1162static void rc_put_char(struct tty_struct * tty, unsigned char ch)
1163{
1164 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1165 unsigned long flags;
1166
1167 if (rc_paranoia_check(port, tty->name, "rc_put_char"))
1168 return;
1169
1170 if (!tty || !port->xmit_buf)
1171 return;
1172
1173 save_flags(flags); cli();
1174
1175 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
1176 goto out;
1177
1178 port->xmit_buf[port->xmit_head++] = ch;
1179 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1180 port->xmit_cnt++;
1181out: restore_flags(flags);
1182}
1183
1184static void rc_flush_chars(struct tty_struct * tty)
1185{
1186 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1187 unsigned long flags;
1188
1189 if (rc_paranoia_check(port, tty->name, "rc_flush_chars"))
1190 return;
1191
1192 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1193 !port->xmit_buf)
1194 return;
1195
1196 save_flags(flags); cli();
1197 port->IER |= IER_TXRDY;
1198 rc_out(port_Board(port), CD180_CAR, port_No(port));
1199 rc_out(port_Board(port), CD180_IER, port->IER);
1200 restore_flags(flags);
1201}
1202
1203static int rc_write_room(struct tty_struct * tty)
1204{
1205 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1206 int ret;
1207
1208 if (rc_paranoia_check(port, tty->name, "rc_write_room"))
1209 return 0;
1210
1211 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1212 if (ret < 0)
1213 ret = 0;
1214 return ret;
1215}
1216
1217static int rc_chars_in_buffer(struct tty_struct *tty)
1218{
1219 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1220
1221 if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer"))
1222 return 0;
1223
1224 return port->xmit_cnt;
1225}
1226
1227static void rc_flush_buffer(struct tty_struct *tty)
1228{
1229 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1230 unsigned long flags;
1231
1232 if (rc_paranoia_check(port, tty->name, "rc_flush_buffer"))
1233 return;
1234
1235 save_flags(flags); cli();
1236 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1237 restore_flags(flags);
1238
1239 wake_up_interruptible(&tty->write_wait);
1240 tty_wakeup(tty);
1241}
1242
1243static int rc_tiocmget(struct tty_struct *tty, struct file *file)
1244{
1245 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1246 struct riscom_board * bp;
1247 unsigned char status;
1248 unsigned int result;
1249 unsigned long flags;
1250
1251 if (rc_paranoia_check(port, tty->name, __FUNCTION__))
1252 return -ENODEV;
1253
1254 bp = port_Board(port);
1255 save_flags(flags); cli();
1256 rc_out(bp, CD180_CAR, port_No(port));
1257 status = rc_in(bp, CD180_MSVR);
1258 result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG;
1259 restore_flags(flags);
1260 result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0)
1261 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1262 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1263 | ((status & MSVR_DSR) ? TIOCM_DSR : 0)
1264 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1265 return result;
1266}
1267
1268static int rc_tiocmset(struct tty_struct *tty, struct file *file,
1269 unsigned int set, unsigned int clear)
1270{
1271 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1272 unsigned long flags;
1273 struct riscom_board *bp;
1274
1275 if (rc_paranoia_check(port, tty->name, __FUNCTION__))
1276 return -ENODEV;
1277
1278 bp = port_Board(port);
1279
1280 save_flags(flags); cli();
1281 if (set & TIOCM_RTS)
1282 port->MSVR |= MSVR_RTS;
1283 if (set & TIOCM_DTR)
1284 bp->DTR &= ~(1u << port_No(port));
1285
1286 if (clear & TIOCM_RTS)
1287 port->MSVR &= ~MSVR_RTS;
1288 if (clear & TIOCM_DTR)
1289 bp->DTR |= (1u << port_No(port));
1290
1291 rc_out(bp, CD180_CAR, port_No(port));
1292 rc_out(bp, CD180_MSVR, port->MSVR);
1293 rc_out(bp, RC_DTR, bp->DTR);
1294 restore_flags(flags);
1295 return 0;
1296}
1297
1298static inline void rc_send_break(struct riscom_port * port, unsigned long length)
1299{
1300 struct riscom_board *bp = port_Board(port);
1301 unsigned long flags;
1302
1303 save_flags(flags); cli();
1304 port->break_length = RISCOM_TPS / HZ * length;
1305 port->COR2 |= COR2_ETC;
1306 port->IER |= IER_TXRDY;
1307 rc_out(bp, CD180_CAR, port_No(port));
1308 rc_out(bp, CD180_COR2, port->COR2);
1309 rc_out(bp, CD180_IER, port->IER);
1310 rc_wait_CCR(bp);
1311 rc_out(bp, CD180_CCR, CCR_CORCHG2);
1312 rc_wait_CCR(bp);
1313 restore_flags(flags);
1314}
1315
1316static inline int rc_set_serial_info(struct riscom_port * port,
1317 struct serial_struct __user * newinfo)
1318{
1319 struct serial_struct tmp;
1320 struct riscom_board *bp = port_Board(port);
1321 int change_speed;
1322 unsigned long flags;
1323
1324 if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
1325 return -EFAULT;
1326
1327#if 0
1328 if ((tmp.irq != bp->irq) ||
1329 (tmp.port != bp->base) ||
1330 (tmp.type != PORT_CIRRUS) ||
1331 (tmp.baud_base != (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC) ||
1332 (tmp.custom_divisor != 0) ||
1333 (tmp.xmit_fifo_size != CD180_NFIFO) ||
1334 (tmp.flags & ~RISCOM_LEGAL_FLAGS))
1335 return -EINVAL;
1336#endif
1337
1338 change_speed = ((port->flags & ASYNC_SPD_MASK) !=
1339 (tmp.flags & ASYNC_SPD_MASK));
1340
1341 if (!capable(CAP_SYS_ADMIN)) {
1342 if ((tmp.close_delay != port->close_delay) ||
1343 (tmp.closing_wait != port->closing_wait) ||
1344 ((tmp.flags & ~ASYNC_USR_MASK) !=
1345 (port->flags & ~ASYNC_USR_MASK)))
1346 return -EPERM;
1347 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
1348 (tmp.flags & ASYNC_USR_MASK));
1349 } else {
1350 port->flags = ((port->flags & ~ASYNC_FLAGS) |
1351 (tmp.flags & ASYNC_FLAGS));
1352 port->close_delay = tmp.close_delay;
1353 port->closing_wait = tmp.closing_wait;
1354 }
1355 if (change_speed) {
1356 save_flags(flags); cli();
1357 rc_change_speed(bp, port);
1358 restore_flags(flags);
1359 }
1360 return 0;
1361}
1362
1363static inline int rc_get_serial_info(struct riscom_port * port,
1364 struct serial_struct __user *retinfo)
1365{
1366 struct serial_struct tmp;
1367 struct riscom_board *bp = port_Board(port);
1368
1369 memset(&tmp, 0, sizeof(tmp));
1370 tmp.type = PORT_CIRRUS;
1371 tmp.line = port - rc_port;
1372 tmp.port = bp->base;
1373 tmp.irq = bp->irq;
1374 tmp.flags = port->flags;
1375 tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC;
1376 tmp.close_delay = port->close_delay * HZ/100;
1377 tmp.closing_wait = port->closing_wait * HZ/100;
1378 tmp.xmit_fifo_size = CD180_NFIFO;
1379 return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0;
1380}
1381
1382static int rc_ioctl(struct tty_struct * tty, struct file * filp,
1383 unsigned int cmd, unsigned long arg)
1384
1385{
1386 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1387 void __user *argp = (void __user *)arg;
1388 int retval;
1389
1390 if (rc_paranoia_check(port, tty->name, "rc_ioctl"))
1391 return -ENODEV;
1392
1393 switch (cmd) {
1394 case TCSBRK: /* SVID version: non-zero arg --> no break */
1395 retval = tty_check_change(tty);
1396 if (retval)
1397 return retval;
1398 tty_wait_until_sent(tty, 0);
1399 if (!arg)
1400 rc_send_break(port, HZ/4); /* 1/4 second */
1401 break;
1402 case TCSBRKP: /* support for POSIX tcsendbreak() */
1403 retval = tty_check_change(tty);
1404 if (retval)
1405 return retval;
1406 tty_wait_until_sent(tty, 0);
1407 rc_send_break(port, arg ? arg*(HZ/10) : HZ/4);
1408 break;
1409 case TIOCGSOFTCAR:
1410 return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned __user *)argp);
1411 case TIOCSSOFTCAR:
1412 if (get_user(arg,(unsigned __user *) argp))
1413 return -EFAULT;
1414 tty->termios->c_cflag =
1415 ((tty->termios->c_cflag & ~CLOCAL) |
1416 (arg ? CLOCAL : 0));
1417 break;
1418 case TIOCGSERIAL:
1419 return rc_get_serial_info(port, argp);
1420 case TIOCSSERIAL:
1421 return rc_set_serial_info(port, argp);
1422 default:
1423 return -ENOIOCTLCMD;
1424 }
1425 return 0;
1426}
1427
1428static void rc_throttle(struct tty_struct * tty)
1429{
1430 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1431 struct riscom_board *bp;
1432 unsigned long flags;
1433
1434 if (rc_paranoia_check(port, tty->name, "rc_throttle"))
1435 return;
1436
1437 bp = port_Board(port);
1438
1439 save_flags(flags); cli();
1440 port->MSVR &= ~MSVR_RTS;
1441 rc_out(bp, CD180_CAR, port_No(port));
1442 if (I_IXOFF(tty)) {
1443 rc_wait_CCR(bp);
1444 rc_out(bp, CD180_CCR, CCR_SSCH2);
1445 rc_wait_CCR(bp);
1446 }
1447 rc_out(bp, CD180_MSVR, port->MSVR);
1448 restore_flags(flags);
1449}
1450
1451static void rc_unthrottle(struct tty_struct * tty)
1452{
1453 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1454 struct riscom_board *bp;
1455 unsigned long flags;
1456
1457 if (rc_paranoia_check(port, tty->name, "rc_unthrottle"))
1458 return;
1459
1460 bp = port_Board(port);
1461
1462 save_flags(flags); cli();
1463 port->MSVR |= MSVR_RTS;
1464 rc_out(bp, CD180_CAR, port_No(port));
1465 if (I_IXOFF(tty)) {
1466 rc_wait_CCR(bp);
1467 rc_out(bp, CD180_CCR, CCR_SSCH1);
1468 rc_wait_CCR(bp);
1469 }
1470 rc_out(bp, CD180_MSVR, port->MSVR);
1471 restore_flags(flags);
1472}
1473
1474static void rc_stop(struct tty_struct * tty)
1475{
1476 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1477 struct riscom_board *bp;
1478 unsigned long flags;
1479
1480 if (rc_paranoia_check(port, tty->name, "rc_stop"))
1481 return;
1482
1483 bp = port_Board(port);
1484
1485 save_flags(flags); cli();
1486 port->IER &= ~IER_TXRDY;
1487 rc_out(bp, CD180_CAR, port_No(port));
1488 rc_out(bp, CD180_IER, port->IER);
1489 restore_flags(flags);
1490}
1491
1492static void rc_start(struct tty_struct * tty)
1493{
1494 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1495 struct riscom_board *bp;
1496 unsigned long flags;
1497
1498 if (rc_paranoia_check(port, tty->name, "rc_start"))
1499 return;
1500
1501 bp = port_Board(port);
1502
1503 save_flags(flags); cli();
1504 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
1505 port->IER |= IER_TXRDY;
1506 rc_out(bp, CD180_CAR, port_No(port));
1507 rc_out(bp, CD180_IER, port->IER);
1508 }
1509 restore_flags(flags);
1510}
1511
1512/*
1513 * This routine is called from the work queue when the interrupt
1514 * routine has signalled that a hangup has occurred. The path of
1515 * hangup processing is:
1516 *
1517 * serial interrupt routine -> (workqueue) ->
1518 * do_rc_hangup() -> tty->hangup() -> rc_hangup()
1519 *
1520 */
1521static void do_rc_hangup(void *private_)
1522{
1523 struct riscom_port *port = (struct riscom_port *) private_;
1524 struct tty_struct *tty;
1525
1526 tty = port->tty;
1527 if (tty)
1528 tty_hangup(tty); /* FIXME: module removal race still here */
1529}
1530
1531static void rc_hangup(struct tty_struct * tty)
1532{
1533 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1534 struct riscom_board *bp;
1535
1536 if (rc_paranoia_check(port, tty->name, "rc_hangup"))
1537 return;
1538
1539 bp = port_Board(port);
1540
1541 rc_shutdown_port(bp, port);
1542 port->event = 0;
1543 port->count = 0;
1544 port->flags &= ~ASYNC_NORMAL_ACTIVE;
1545 port->tty = NULL;
1546 wake_up_interruptible(&port->open_wait);
1547}
1548
1549static void rc_set_termios(struct tty_struct * tty, struct termios * old_termios)
1550{
1551 struct riscom_port *port = (struct riscom_port *)tty->driver_data;
1552 unsigned long flags;
1553
1554 if (rc_paranoia_check(port, tty->name, "rc_set_termios"))
1555 return;
1556
1557 if (tty->termios->c_cflag == old_termios->c_cflag &&
1558 tty->termios->c_iflag == old_termios->c_iflag)
1559 return;
1560
1561 save_flags(flags); cli();
1562 rc_change_speed(port_Board(port), port);
1563 restore_flags(flags);
1564
1565 if ((old_termios->c_cflag & CRTSCTS) &&
1566 !(tty->termios->c_cflag & CRTSCTS)) {
1567 tty->hw_stopped = 0;
1568 rc_start(tty);
1569 }
1570}
1571
1572static void do_softint(void *private_)
1573{
1574 struct riscom_port *port = (struct riscom_port *) private_;
1575 struct tty_struct *tty;
1576
1577 if(!(tty = port->tty))
1578 return;
1579
1580 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
1581 tty_wakeup(tty);
1582 wake_up_interruptible(&tty->write_wait);
1583 }
1584}
1585
Jeff Dikeb68e31d2006-10-02 02:17:18 -07001586static const struct tty_operations riscom_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 .open = rc_open,
1588 .close = rc_close,
1589 .write = rc_write,
1590 .put_char = rc_put_char,
1591 .flush_chars = rc_flush_chars,
1592 .write_room = rc_write_room,
1593 .chars_in_buffer = rc_chars_in_buffer,
1594 .flush_buffer = rc_flush_buffer,
1595 .ioctl = rc_ioctl,
1596 .throttle = rc_throttle,
1597 .unthrottle = rc_unthrottle,
1598 .set_termios = rc_set_termios,
1599 .stop = rc_stop,
1600 .start = rc_start,
1601 .hangup = rc_hangup,
1602 .tiocmget = rc_tiocmget,
1603 .tiocmset = rc_tiocmset,
1604};
1605
1606static inline int rc_init_drivers(void)
1607{
1608 int error;
1609 int i;
1610
1611 riscom_driver = alloc_tty_driver(RC_NBOARD * RC_NPORT);
1612 if (!riscom_driver)
1613 return -ENOMEM;
1614
1615 if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
1616 printk(KERN_ERR "rc: Couldn't get free page.\n");
1617 put_tty_driver(riscom_driver);
1618 return 1;
1619 }
1620 memset(IRQ_to_board, 0, sizeof(IRQ_to_board));
1621 riscom_driver->owner = THIS_MODULE;
1622 riscom_driver->name = "ttyL";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623 riscom_driver->major = RISCOM8_NORMAL_MAJOR;
1624 riscom_driver->type = TTY_DRIVER_TYPE_SERIAL;
1625 riscom_driver->subtype = SERIAL_TYPE_NORMAL;
1626 riscom_driver->init_termios = tty_std_termios;
1627 riscom_driver->init_termios.c_cflag =
1628 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1629 riscom_driver->flags = TTY_DRIVER_REAL_RAW;
1630 tty_set_operations(riscom_driver, &riscom_ops);
1631 if ((error = tty_register_driver(riscom_driver))) {
1632 free_page((unsigned long)tmp_buf);
1633 put_tty_driver(riscom_driver);
1634 printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, "
1635 "error = %d\n",
1636 error);
1637 return 1;
1638 }
1639
1640 memset(rc_port, 0, sizeof(rc_port));
1641 for (i = 0; i < RC_NPORT * RC_NBOARD; i++) {
1642 rc_port[i].magic = RISCOM8_MAGIC;
1643 INIT_WORK(&rc_port[i].tqueue, do_softint, &rc_port[i]);
1644 INIT_WORK(&rc_port[i].tqueue_hangup, do_rc_hangup, &rc_port[i]);
1645 rc_port[i].close_delay = 50 * HZ/100;
1646 rc_port[i].closing_wait = 3000 * HZ/100;
1647 init_waitqueue_head(&rc_port[i].open_wait);
1648 init_waitqueue_head(&rc_port[i].close_wait);
1649 }
1650
1651 return 0;
1652}
1653
1654static void rc_release_drivers(void)
1655{
1656 unsigned long flags;
1657
1658 save_flags(flags);
1659 cli();
1660 free_page((unsigned long)tmp_buf);
1661 tty_unregister_driver(riscom_driver);
1662 put_tty_driver(riscom_driver);
1663 restore_flags(flags);
1664}
1665
1666#ifndef MODULE
1667/*
1668 * Called at boot time.
1669 *
1670 * You can specify IO base for up to RC_NBOARD cards,
1671 * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt.
1672 * Note that there will be no probing at default
1673 * addresses in this case.
1674 *
1675 */
1676static int __init riscom8_setup(char *str)
1677{
1678 int ints[RC_NBOARD];
1679 int i;
1680
1681 str = get_options(str, ARRAY_SIZE(ints), ints);
1682
1683 for (i = 0; i < RC_NBOARD; i++) {
1684 if (i < ints[0])
1685 rc_board[i].base = ints[i+1];
1686 else
1687 rc_board[i].base = 0;
1688 }
1689 return 1;
1690}
1691
1692__setup("riscom8=", riscom8_setup);
1693#endif
1694
1695static char banner[] __initdata =
1696 KERN_INFO "rc: SDL RISCom/8 card driver v1.1, (c) D.Gorodchanin "
1697 "1994-1996.\n";
1698static char no_boards_msg[] __initdata =
1699 KERN_INFO "rc: No RISCom/8 boards detected.\n";
1700
1701/*
1702 * This routine must be called by kernel at boot time
1703 */
1704static int __init riscom8_init(void)
1705{
1706 int i;
1707 int found = 0;
1708
1709 printk(banner);
1710
1711 if (rc_init_drivers())
1712 return -EIO;
1713
1714 for (i = 0; i < RC_NBOARD; i++)
1715 if (rc_board[i].base && !rc_probe(&rc_board[i]))
1716 found++;
1717
1718 if (!found) {
1719 rc_release_drivers();
1720 printk(no_boards_msg);
1721 return -EIO;
1722 }
1723 return 0;
1724}
1725
1726#ifdef MODULE
1727static int iobase;
1728static int iobase1;
1729static int iobase2;
1730static int iobase3;
Rusty Russell8d3b33f2006-03-25 03:07:05 -08001731module_param(iobase, int, 0);
1732module_param(iobase1, int, 0);
1733module_param(iobase2, int, 0);
1734module_param(iobase3, int, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735
1736MODULE_LICENSE("GPL");
1737#endif /* MODULE */
1738
1739/*
1740 * You can setup up to 4 boards (current value of RC_NBOARD)
1741 * by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter.
1742 *
1743 */
1744static int __init riscom8_init_module (void)
1745{
1746#ifdef MODULE
1747 int i;
1748
1749 if (iobase || iobase1 || iobase2 || iobase3) {
1750 for(i = 0; i < RC_NBOARD; i++)
1751 rc_board[0].base = 0;
1752 }
1753
1754 if (iobase)
1755 rc_board[0].base = iobase;
1756 if (iobase1)
1757 rc_board[1].base = iobase1;
1758 if (iobase2)
1759 rc_board[2].base = iobase2;
1760 if (iobase3)
1761 rc_board[3].base = iobase3;
1762#endif /* MODULE */
1763
1764 return riscom8_init();
1765}
1766
1767static void __exit riscom8_exit_module (void)
1768{
1769 int i;
1770
1771 rc_release_drivers();
1772 for (i = 0; i < RC_NBOARD; i++)
1773 if (rc_board[i].flags & RC_BOARD_PRESENT)
1774 rc_release_io_range(&rc_board[i]);
1775
1776}
1777
1778module_init(riscom8_init_module);
1779module_exit(riscom8_exit_module);
1780