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