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