Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzi...
[deliverable/linux.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
85f8f810 345 tty = port->port.tty;
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)
1da177e4 357 return;
1da177e4
LT
358 if (status & RCSR_TOUT) {
359 printk(KERN_WARNING "rc%d: port %d: Receiver timeout. "
9492e135 360 "Hardware problems ?\n",
1da177e4
LT
361 board_No(bp), port_No(port));
362 return;
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;
85f8f810 368 if (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
33f0f88f
AC
382 tty_insert_flip_char(tty, ch, flag);
383 tty_flip_buffer_push(tty);
1da177e4
LT
384}
385
9492e135 386static void rc_receive(struct riscom_board const *bp)
1da177e4
LT
387{
388 struct riscom_port *port;
389 struct tty_struct *tty;
390 unsigned char count;
9492e135
AC
391
392 port = rc_get_port(bp, "Receive");
393 if (port == NULL)
1da177e4 394 return;
9492e135 395
85f8f810 396 tty = port->port.tty;
9492e135 397
1da177e4 398 count = rc_in(bp, CD180_RDCR);
9492e135 399
1da177e4
LT
400#ifdef RC_REPORT_FIFO
401 port->hits[count > 8 ? 9 : count]++;
9492e135
AC
402#endif
403
1da177e4 404 while (count--) {
33f0f88f 405 if (tty_buffer_request_room(tty, 1) == 0) {
1da177e4
LT
406 printk(KERN_WARNING "rc%d: port %d: Working around "
407 "flip buffer overflow.\n",
408 board_No(bp), port_No(port));
409 break;
410 }
33f0f88f 411 tty_insert_flip_char(tty, rc_in(bp, CD180_RDR), TTY_NORMAL);
1da177e4 412 }
33f0f88f 413 tty_flip_buffer_push(tty);
1da177e4
LT
414}
415
9492e135 416static void rc_transmit(struct riscom_board const *bp)
1da177e4
LT
417{
418 struct riscom_port *port;
419 struct tty_struct *tty;
420 unsigned char count;
9492e135
AC
421
422 port = rc_get_port(bp, "Transmit");
423 if (port == NULL)
1da177e4 424 return;
9492e135 425
85f8f810 426 tty = port->port.tty;
9492e135
AC
427
428 if (port->IER & IER_TXEMPTY) {
1da177e4
LT
429 /* FIFO drained */
430 rc_out(bp, CD180_CAR, port_No(port));
431 port->IER &= ~IER_TXEMPTY;
432 rc_out(bp, CD180_IER, port->IER);
433 return;
434 }
9492e135 435
1da177e4
LT
436 if ((port->xmit_cnt <= 0 && !port->break_length)
437 || tty->stopped || tty->hw_stopped) {
438 rc_out(bp, CD180_CAR, port_No(port));
439 port->IER &= ~IER_TXRDY;
440 rc_out(bp, CD180_IER, port->IER);
441 return;
442 }
9492e135 443
1da177e4
LT
444 if (port->break_length) {
445 if (port->break_length > 0) {
446 if (port->COR2 & COR2_ETC) {
447 rc_out(bp, CD180_TDR, CD180_C_ESC);
448 rc_out(bp, CD180_TDR, CD180_C_SBRK);
449 port->COR2 &= ~COR2_ETC;
450 }
451 count = min_t(int, port->break_length, 0xff);
452 rc_out(bp, CD180_TDR, CD180_C_ESC);
453 rc_out(bp, CD180_TDR, CD180_C_DELAY);
454 rc_out(bp, CD180_TDR, count);
9492e135
AC
455 port->break_length -= count;
456 if (port->break_length == 0)
1da177e4
LT
457 port->break_length--;
458 } else {
459 rc_out(bp, CD180_TDR, CD180_C_ESC);
460 rc_out(bp, CD180_TDR, CD180_C_EBRK);
461 rc_out(bp, CD180_COR2, port->COR2);
462 rc_wait_CCR(bp);
463 rc_out(bp, CD180_CCR, CCR_CORCHG2);
464 port->break_length = 0;
465 }
466 return;
467 }
9492e135 468
1da177e4
LT
469 count = CD180_NFIFO;
470 do {
85f8f810 471 rc_out(bp, CD180_TDR, port->port.xmit_buf[port->xmit_tail++]);
1da177e4
LT
472 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
473 if (--port->xmit_cnt <= 0)
474 break;
475 } while (--count > 0);
9492e135 476
1da177e4
LT
477 if (port->xmit_cnt <= 0) {
478 rc_out(bp, CD180_CAR, port_No(port));
479 port->IER &= ~IER_TXRDY;
480 rc_out(bp, CD180_IER, port->IER);
481 }
482 if (port->xmit_cnt <= port->wakeup_chars)
b98e70de 483 tty_wakeup(tty);
1da177e4
LT
484}
485
9492e135 486static void rc_check_modem(struct riscom_board const *bp)
1da177e4
LT
487{
488 struct riscom_port *port;
489 struct tty_struct *tty;
490 unsigned char mcr;
9492e135
AC
491
492 port = rc_get_port(bp, "Modem");
493 if (port == NULL)
1da177e4 494 return;
9492e135 495
85f8f810 496 tty = port->port.tty;
9492e135 497
1da177e4 498 mcr = rc_in(bp, CD180_MCR);
9492e135
AC
499 if (mcr & MCR_CDCHG) {
500 if (rc_in(bp, CD180_MSVR) & MSVR_CD)
85f8f810 501 wake_up_interruptible(&port->port.open_wait);
1da177e4 502 else
b98e70de 503 tty_hangup(tty);
1da177e4 504 }
9492e135 505
1da177e4
LT
506#ifdef RISCOM_BRAIN_DAMAGED_CTS
507 if (mcr & MCR_CTSCHG) {
508 if (rc_in(bp, CD180_MSVR) & MSVR_CTS) {
509 tty->hw_stopped = 0;
510 port->IER |= IER_TXRDY;
511 if (port->xmit_cnt <= port->wakeup_chars)
b98e70de 512 tty_wakeup(tty);
1da177e4
LT
513 } else {
514 tty->hw_stopped = 1;
515 port->IER &= ~IER_TXRDY;
516 }
517 rc_out(bp, CD180_IER, port->IER);
518 }
519 if (mcr & MCR_DSRCHG) {
520 if (rc_in(bp, CD180_MSVR) & MSVR_DSR) {
521 tty->hw_stopped = 0;
522 port->IER |= IER_TXRDY;
523 if (port->xmit_cnt <= port->wakeup_chars)
b98e70de 524 tty_wakeup(tty);
1da177e4
LT
525 } else {
526 tty->hw_stopped = 1;
527 port->IER &= ~IER_TXRDY;
528 }
529 rc_out(bp, CD180_IER, port->IER);
530 }
531#endif /* RISCOM_BRAIN_DAMAGED_CTS */
9492e135 532
1da177e4
LT
533 /* Clear change bits */
534 rc_out(bp, CD180_MCR, 0);
535}
536
537/* The main interrupt processing routine */
9492e135 538static irqreturn_t rc_interrupt(int dummy, void *dev_id)
1da177e4
LT
539{
540 unsigned char status;
541 unsigned char ack;
f07ef395 542 struct riscom_board *bp = dev_id;
1da177e4
LT
543 unsigned long loop = 0;
544 int handled = 0;
545
c7bec5ab 546 if (!(bp->flags & RC_BOARD_ACTIVE))
1da177e4 547 return IRQ_NONE;
c7bec5ab 548
1da177e4
LT
549 while ((++loop < 16) && ((status = ~(rc_in(bp, RC_BSR))) &
550 (RC_BSR_TOUT | RC_BSR_TINT |
551 RC_BSR_MINT | RC_BSR_RINT))) {
552 handled = 1;
9492e135 553 if (status & RC_BSR_TOUT)
1da177e4
LT
554 printk(KERN_WARNING "rc%d: Got timeout. Hardware "
555 "error?\n", board_No(bp));
1da177e4
LT
556 else if (status & RC_BSR_RINT) {
557 ack = rc_in(bp, RC_ACK_RINT);
1da177e4
LT
558 if (ack == (RC_ID | GIVR_IT_RCV))
559 rc_receive(bp);
560 else if (ack == (RC_ID | GIVR_IT_REXC))
561 rc_receive_exc(bp);
562 else
563 printk(KERN_WARNING "rc%d: Bad receive ack "
564 "0x%02x.\n",
565 board_No(bp), ack);
1da177e4
LT
566 } else if (status & RC_BSR_TINT) {
567 ack = rc_in(bp, RC_ACK_TINT);
1da177e4
LT
568 if (ack == (RC_ID | GIVR_IT_TX))
569 rc_transmit(bp);
570 else
571 printk(KERN_WARNING "rc%d: Bad transmit ack "
572 "0x%02x.\n",
573 board_No(bp), ack);
1da177e4
LT
574 } else /* if (status & RC_BSR_MINT) */ {
575 ack = rc_in(bp, RC_ACK_MINT);
9492e135 576 if (ack == (RC_ID | GIVR_IT_MODEM))
1da177e4
LT
577 rc_check_modem(bp);
578 else
579 printk(KERN_WARNING "rc%d: Bad modem ack "
580 "0x%02x.\n",
581 board_No(bp), ack);
9492e135 582 }
1da177e4
LT
583 rc_out(bp, CD180_EOIR, 0); /* Mark end of interrupt */
584 rc_out(bp, RC_CTOUT, 0); /* Clear timeout flag */
585 }
586 return IRQ_RETVAL(handled);
587}
588
589/*
590 * Routines for open & close processing.
591 */
592
593/* Called with disabled interrupts */
9492e135 594static int rc_setup_board(struct riscom_board *bp)
1da177e4
LT
595{
596 int error;
597
9492e135 598 if (bp->flags & RC_BOARD_ACTIVE)
1da177e4 599 return 0;
9492e135 600
0f2ed4c6 601 error = request_irq(bp->irq, rc_interrupt, IRQF_DISABLED,
f07ef395 602 "RISCom/8", bp);
9492e135 603 if (error)
1da177e4 604 return error;
9492e135 605
1da177e4
LT
606 rc_out(bp, RC_CTOUT, 0); /* Just in case */
607 bp->DTR = ~0;
608 rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */
9492e135 609
1da177e4 610 bp->flags |= RC_BOARD_ACTIVE;
9492e135 611
1da177e4
LT
612 return 0;
613}
614
615/* Called with disabled interrupts */
f07ef395 616static void rc_shutdown_board(struct riscom_board *bp)
1da177e4
LT
617{
618 if (!(bp->flags & RC_BOARD_ACTIVE))
619 return;
9492e135 620
1da177e4 621 bp->flags &= ~RC_BOARD_ACTIVE;
9492e135 622
1da177e4 623 free_irq(bp->irq, NULL);
9492e135 624
1da177e4
LT
625 bp->DTR = ~0;
626 rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */
9492e135 627
1da177e4
LT
628}
629
630/*
9492e135 631 * Setting up port characteristics.
1da177e4
LT
632 * Must be called with disabled interrupts
633 */
634static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
635{
85f8f810 636 struct tty_struct *tty = port->port.tty;
1da177e4
LT
637 unsigned long baud;
638 long tmp;
639 unsigned char cor1 = 0, cor3 = 0;
640 unsigned char mcor1 = 0, mcor2 = 0;
9492e135 641
1da177e4
LT
642 port->IER = 0;
643 port->COR2 = 0;
644 port->MSVR = MSVR_RTS;
9492e135 645
c7bce309 646 baud = tty_get_baud_rate(tty);
9492e135 647
1da177e4
LT
648 /* Select port on the board */
649 rc_out(bp, CD180_CAR, port_No(port));
9492e135 650
c7bce309 651 if (!baud) {
1da177e4
LT
652 /* Drop DTR & exit */
653 bp->DTR |= (1u << port_No(port));
654 rc_out(bp, RC_DTR, bp->DTR);
655 return;
656 } else {
657 /* Set DTR on */
658 bp->DTR &= ~(1u << port_No(port));
659 rc_out(bp, RC_DTR, bp->DTR);
660 }
9492e135 661
1da177e4 662 /*
9492e135 663 * Now we must calculate some speed depended things
1da177e4 664 */
9492e135 665
1da177e4 666 /* Set baud rate for port */
c7bce309 667 tmp = (((RC_OSCFREQ + baud/2) / baud +
1da177e4
LT
668 CD180_TPC/2) / CD180_TPC);
669
9492e135
AC
670 rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff);
671 rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff);
672 rc_out(bp, CD180_RBPRL, tmp & 0xff);
1da177e4 673 rc_out(bp, CD180_TBPRL, tmp & 0xff);
9492e135 674
c7bce309 675 baud = (baud + 5) / 10; /* Estimated CPS */
9492e135 676
1da177e4 677 /* Two timer ticks seems enough to wakeup something like SLIP driver */
9492e135 678 tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;
1da177e4
LT
679 port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
680 SERIAL_XMIT_SIZE - 1 : tmp);
9492e135 681
1da177e4
LT
682 /* Receiver timeout will be transmission time for 1.5 chars */
683 tmp = (RISCOM_TPS + RISCOM_TPS/2 + baud/2) / baud;
684 tmp = (tmp > 0xff) ? 0xff : tmp;
685 rc_out(bp, CD180_RTPR, tmp);
9492e135
AC
686
687 switch (C_CSIZE(tty)) {
688 case CS5:
1da177e4
LT
689 cor1 |= COR1_5BITS;
690 break;
9492e135 691 case CS6:
1da177e4
LT
692 cor1 |= COR1_6BITS;
693 break;
9492e135 694 case CS7:
1da177e4
LT
695 cor1 |= COR1_7BITS;
696 break;
9492e135 697 case CS8:
1da177e4
LT
698 cor1 |= COR1_8BITS;
699 break;
700 }
9492e135 701 if (C_CSTOPB(tty))
1da177e4 702 cor1 |= COR1_2SB;
9492e135 703
1da177e4 704 cor1 |= COR1_IGNORE;
9492e135 705 if (C_PARENB(tty)) {
1da177e4 706 cor1 |= COR1_NORMPAR;
9492e135 707 if (C_PARODD(tty))
1da177e4 708 cor1 |= COR1_ODDP;
9492e135 709 if (I_INPCK(tty))
1da177e4
LT
710 cor1 &= ~COR1_IGNORE;
711 }
712 /* Set marking of some errors */
713 port->mark_mask = RCSR_OE | RCSR_TOUT;
9492e135 714 if (I_INPCK(tty))
1da177e4 715 port->mark_mask |= RCSR_FE | RCSR_PE;
9492e135 716 if (I_BRKINT(tty) || I_PARMRK(tty))
1da177e4 717 port->mark_mask |= RCSR_BREAK;
9492e135 718 if (I_IGNPAR(tty))
1da177e4 719 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
9492e135 720 if (I_IGNBRK(tty)) {
1da177e4 721 port->mark_mask &= ~RCSR_BREAK;
9492e135 722 if (I_IGNPAR(tty))
1da177e4
LT
723 /* Real raw mode. Ignore all */
724 port->mark_mask &= ~RCSR_OE;
725 }
726 /* Enable Hardware Flow Control */
727 if (C_CRTSCTS(tty)) {
728#ifdef RISCOM_BRAIN_DAMAGED_CTS
729 port->IER |= IER_DSR | IER_CTS;
730 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
731 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
9492e135
AC
732 tty->hw_stopped = !(rc_in(bp, CD180_MSVR) &
733 (MSVR_CTS|MSVR_DSR));
1da177e4
LT
734#else
735 port->COR2 |= COR2_CTSAE;
736#endif
737 }
738 /* Enable Software Flow Control. FIXME: I'm not sure about this */
739 /* Some people reported that it works, but I still doubt */
740 if (I_IXON(tty)) {
741 port->COR2 |= COR2_TXIBE;
742 cor3 |= (COR3_FCT | COR3_SCDE);
743 if (I_IXANY(tty))
744 port->COR2 |= COR2_IXM;
745 rc_out(bp, CD180_SCHR1, START_CHAR(tty));
746 rc_out(bp, CD180_SCHR2, STOP_CHAR(tty));
747 rc_out(bp, CD180_SCHR3, START_CHAR(tty));
748 rc_out(bp, CD180_SCHR4, STOP_CHAR(tty));
749 }
750 if (!C_CLOCAL(tty)) {
751 /* Enable CD check */
752 port->IER |= IER_CD;
753 mcor1 |= MCOR1_CDZD;
754 mcor2 |= MCOR2_CDOD;
755 }
9492e135
AC
756
757 if (C_CREAD(tty))
1da177e4
LT
758 /* Enable receiver */
759 port->IER |= IER_RXD;
9492e135 760
1da177e4 761 /* Set input FIFO size (1-8 bytes) */
9492e135 762 cor3 |= RISCOM_RXFIFO;
1da177e4
LT
763 /* Setting up CD180 channel registers */
764 rc_out(bp, CD180_COR1, cor1);
765 rc_out(bp, CD180_COR2, port->COR2);
766 rc_out(bp, CD180_COR3, cor3);
767 /* Make CD180 know about registers change */
768 rc_wait_CCR(bp);
769 rc_out(bp, CD180_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
770 /* Setting up modem option registers */
771 rc_out(bp, CD180_MCOR1, mcor1);
772 rc_out(bp, CD180_MCOR2, mcor2);
773 /* Enable CD180 transmitter & receiver */
774 rc_wait_CCR(bp);
775 rc_out(bp, CD180_CCR, CCR_TXEN | CCR_RXEN);
776 /* Enable interrupts */
777 rc_out(bp, CD180_IER, port->IER);
778 /* And finally set RTS on */
779 rc_out(bp, CD180_MSVR, port->MSVR);
780}
781
782/* Must be called with interrupts enabled */
783static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
784{
785 unsigned long flags;
9492e135 786
85f8f810 787 if (port->port.flags & ASYNC_INITIALIZED)
1da177e4 788 return 0;
9492e135 789
85f8f810
AC
790 if (tty_port_alloc_xmit_buf(&port->port) < 0)
791 return -ENOMEM;
792
d9afa435
JG
793 spin_lock_irqsave(&riscom_lock, flags);
794
d99101fd 795 clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
85f8f810 796 if (port->port.count == 1)
1da177e4 797 bp->count++;
1da177e4
LT
798 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
799 rc_change_speed(bp, port);
85f8f810 800 port->port.flags |= ASYNC_INITIALIZED;
9492e135 801
d9afa435 802 spin_unlock_irqrestore(&riscom_lock, flags);
1da177e4
LT
803 return 0;
804}
805
806/* Must be called with interrupts disabled */
d99101fd
AC
807static void rc_shutdown_port(struct tty_struct *tty,
808 struct riscom_board *bp, struct riscom_port *port)
1da177e4 809{
85f8f810 810 if (!(port->port.flags & ASYNC_INITIALIZED))
1da177e4 811 return;
9492e135 812
1da177e4
LT
813#ifdef RC_REPORT_OVERRUN
814 printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n",
815 board_No(bp), port_No(port), port->overrun);
9492e135 816#endif
1da177e4
LT
817#ifdef RC_REPORT_FIFO
818 {
819 int i;
9492e135 820
1da177e4
LT
821 printk(KERN_INFO "rc%d: port %d: FIFO hits [ ",
822 board_No(bp), port_No(port));
9492e135 823 for (i = 0; i < 10; i++)
1da177e4 824 printk("%ld ", port->hits[i]);
1da177e4
LT
825 printk("].\n");
826 }
9492e135 827#endif
85f8f810 828 tty_port_free_xmit_buf(&port->port);
d99101fd 829 if (C_HUPCL(tty)) {
1da177e4
LT
830 /* Drop DTR */
831 bp->DTR |= (1u << port_No(port));
832 rc_out(bp, RC_DTR, bp->DTR);
833 }
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);
85f8f810 845 port->port.flags &= ~ASYNC_INITIALIZED;
9492e135 846
1da177e4
LT
847 if (--bp->count < 0) {
848 printk(KERN_INFO "rc%d: rc_shutdown_port: "
849 "bad board count: %d\n",
850 board_No(bp), bp->count);
851 bp->count = 0;
852 }
1da177e4
LT
853 /*
854 * If this is the last opened port on the board
855 * shutdown whole board
856 */
9492e135 857 if (!bp->count)
1da177e4
LT
858 rc_shutdown_board(bp);
859}
860
31f35939
AC
861static int carrier_raised(struct tty_port *port)
862{
863 struct riscom_port *p = container_of(port, struct riscom_port, port);
864 struct riscom_board *bp = port_Board(p);
865 unsigned long flags;
866 int CD;
867
868 spin_lock_irqsave(&riscom_lock, flags);
869 rc_out(bp, CD180_CAR, port_No(p));
870 CD = rc_in(bp, CD180_MSVR) & MSVR_CD;
871 rc_out(bp, CD180_MSVR, MSVR_RTS);
872 bp->DTR &= ~(1u << port_No(p));
873 rc_out(bp, RC_DTR, bp->DTR);
874 spin_unlock_irqrestore(&riscom_lock, flags);
875 return CD;
876}
877
9492e135 878static int rc_open(struct tty_struct *tty, struct file *filp)
1da177e4
LT
879{
880 int board;
881 int error;
9492e135
AC
882 struct riscom_port *port;
883 struct riscom_board *bp;
884
1da177e4
LT
885 board = RC_BOARD(tty->index);
886 if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT))
887 return -ENODEV;
9492e135 888
1da177e4
LT
889 bp = &rc_board[board];
890 port = rc_port + board * RC_NPORT + RC_PORT(tty->index);
891 if (rc_paranoia_check(port, tty->name, "rc_open"))
892 return -ENODEV;
9492e135
AC
893
894 error = rc_setup_board(bp);
895 if (error)
1da177e4 896 return error;
9492e135 897
85f8f810 898 port->port.count++;
1da177e4 899 tty->driver_data = port;
85f8f810 900 port->port.tty = tty;
9492e135
AC
901
902 error = rc_setup_port(bp, port);
903 if (error == 0)
36c621d8 904 error = tty_port_block_til_ready(&port->port, tty, filp);
9492e135 905 return error;
1da177e4
LT
906}
907
978e595f
AC
908static void rc_flush_buffer(struct tty_struct *tty)
909{
c9f19e96 910 struct riscom_port *port = tty->driver_data;
978e595f
AC
911 unsigned long flags;
912
913 if (rc_paranoia_check(port, tty->name, "rc_flush_buffer"))
914 return;
915
916 spin_lock_irqsave(&riscom_lock, flags);
978e595f 917 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
978e595f
AC
918 spin_unlock_irqrestore(&riscom_lock, flags);
919
920 tty_wakeup(tty);
921}
922
9492e135 923static void rc_close(struct tty_struct *tty, struct file *filp)
1da177e4 924{
c9f19e96 925 struct riscom_port *port = tty->driver_data;
1da177e4
LT
926 struct riscom_board *bp;
927 unsigned long flags;
928 unsigned long timeout;
9492e135 929
1da177e4
LT
930 if (!port || rc_paranoia_check(port, tty->name, "close"))
931 return;
d9afa435 932
1da177e4 933 bp = port_Board(port);
a6614999
AC
934
935 if (tty_port_close_start(&port->port, tty, filp) == 0)
936 return;
937
1da177e4
LT
938 /*
939 * At this point we stop accepting input. To do this, we
940 * disable the receive line status interrupts, and tell the
941 * interrupt driver to stop checking the data ready bit in the
942 * line status register.
943 */
c2ba38cd
AC
944
945 spin_lock_irqsave(&riscom_lock, flags);
1da177e4 946 port->IER &= ~IER_RXD;
85f8f810 947 if (port->port.flags & ASYNC_INITIALIZED) {
1da177e4
LT
948 port->IER &= ~IER_TXRDY;
949 port->IER |= IER_TXEMPTY;
950 rc_out(bp, CD180_CAR, port_No(port));
951 rc_out(bp, CD180_IER, port->IER);
952 /*
953 * Before we drop DTR, make sure the UART transmitter
954 * has completely drained; this is especially
955 * important if there is a transmit FIFO!
956 */
9492e135
AC
957 timeout = jiffies + HZ;
958 while (port->IER & IER_TXEMPTY) {
c2ba38cd 959 spin_unlock_irqrestore(&riscom_lock, flags);
1da177e4 960 msleep_interruptible(jiffies_to_msecs(port->timeout));
c2ba38cd 961 spin_lock_irqsave(&riscom_lock, flags);
1da177e4
LT
962 if (time_after(jiffies, timeout))
963 break;
964 }
965 }
d99101fd 966 rc_shutdown_port(tty, bp, port);
978e595f 967 rc_flush_buffer(tty);
c2ba38cd 968 spin_unlock_irqrestore(&riscom_lock, flags);
d9afa435 969
a6614999 970 tty_port_close_end(&port->port, tty);
1da177e4
LT
971}
972
9492e135 973static int rc_write(struct tty_struct *tty,
1da177e4
LT
974 const unsigned char *buf, int count)
975{
c9f19e96 976 struct riscom_port *port = tty->driver_data;
1da177e4
LT
977 struct riscom_board *bp;
978 int c, total = 0;
979 unsigned long flags;
9492e135 980
1da177e4
LT
981 if (rc_paranoia_check(port, tty->name, "rc_write"))
982 return 0;
9492e135 983
1da177e4
LT
984 bp = port_Board(port);
985
1da177e4 986 while (1) {
d9afa435
JG
987 spin_lock_irqsave(&riscom_lock, flags);
988
1da177e4
LT
989 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
990 SERIAL_XMIT_SIZE - port->xmit_head));
d9afa435
JG
991 if (c <= 0)
992 break; /* lock continues to be held */
1da177e4 993
85f8f810 994 memcpy(port->port.xmit_buf + port->xmit_head, buf, c);
1da177e4
LT
995 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
996 port->xmit_cnt += c;
d9afa435
JG
997
998 spin_unlock_irqrestore(&riscom_lock, flags);
1da177e4
LT
999
1000 buf += c;
1001 count -= c;
1002 total += c;
1003 }
1004
1da177e4
LT
1005 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1006 !(port->IER & IER_TXRDY)) {
1007 port->IER |= IER_TXRDY;
1008 rc_out(bp, CD180_CAR, port_No(port));
1009 rc_out(bp, CD180_IER, port->IER);
1010 }
d9afa435
JG
1011
1012 spin_unlock_irqrestore(&riscom_lock, flags);
1da177e4
LT
1013
1014 return total;
1015}
1016
9492e135 1017static int rc_put_char(struct tty_struct *tty, unsigned char ch)
1da177e4 1018{
c9f19e96 1019 struct riscom_port *port = tty->driver_data;
1da177e4 1020 unsigned long flags;
bbbbb96f 1021 int ret = 0;
1da177e4
LT
1022
1023 if (rc_paranoia_check(port, tty->name, "rc_put_char"))
bbbbb96f 1024 return 0;
1da177e4 1025
d9afa435 1026 spin_lock_irqsave(&riscom_lock, flags);
9492e135 1027
1da177e4
LT
1028 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
1029 goto out;
1030
85f8f810 1031 port->port.xmit_buf[port->xmit_head++] = ch;
1da177e4
LT
1032 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1033 port->xmit_cnt++;
bbbbb96f 1034 ret = 1;
d9afa435
JG
1035
1036out:
1037 spin_unlock_irqrestore(&riscom_lock, flags);
bbbbb96f 1038 return ret;
1da177e4
LT
1039}
1040
9492e135 1041static void rc_flush_chars(struct tty_struct *tty)
1da177e4 1042{
c9f19e96 1043 struct riscom_port *port = tty->driver_data;
1da177e4 1044 unsigned long flags;
9492e135 1045
1da177e4
LT
1046 if (rc_paranoia_check(port, tty->name, "rc_flush_chars"))
1047 return;
9492e135 1048
d99101fd 1049 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped)
1da177e4
LT
1050 return;
1051
d9afa435
JG
1052 spin_lock_irqsave(&riscom_lock, flags);
1053
1da177e4
LT
1054 port->IER |= IER_TXRDY;
1055 rc_out(port_Board(port), CD180_CAR, port_No(port));
1056 rc_out(port_Board(port), CD180_IER, port->IER);
d9afa435
JG
1057
1058 spin_unlock_irqrestore(&riscom_lock, flags);
1da177e4
LT
1059}
1060
9492e135 1061static int rc_write_room(struct tty_struct *tty)
1da177e4 1062{
c9f19e96 1063 struct riscom_port *port = tty->driver_data;
1da177e4 1064 int ret;
9492e135 1065
1da177e4
LT
1066 if (rc_paranoia_check(port, tty->name, "rc_write_room"))
1067 return 0;
1068
1069 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1070 if (ret < 0)
1071 ret = 0;
1072 return ret;
1073}
1074
1075static int rc_chars_in_buffer(struct tty_struct *tty)
1076{
c9f19e96 1077 struct riscom_port *port = tty->driver_data;
9492e135 1078
1da177e4
LT
1079 if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer"))
1080 return 0;
9492e135 1081
1da177e4
LT
1082 return port->xmit_cnt;
1083}
1084
1da177e4
LT
1085static int rc_tiocmget(struct tty_struct *tty, struct file *file)
1086{
c9f19e96 1087 struct riscom_port *port = tty->driver_data;
9492e135 1088 struct riscom_board *bp;
1da177e4
LT
1089 unsigned char status;
1090 unsigned int result;
1091 unsigned long flags;
1092
bf9d8929 1093 if (rc_paranoia_check(port, tty->name, __func__))
1da177e4
LT
1094 return -ENODEV;
1095
1096 bp = port_Board(port);
d9afa435
JG
1097
1098 spin_lock_irqsave(&riscom_lock, flags);
1099
1da177e4
LT
1100 rc_out(bp, CD180_CAR, port_No(port));
1101 status = rc_in(bp, CD180_MSVR);
1102 result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG;
d9afa435
JG
1103
1104 spin_unlock_irqrestore(&riscom_lock, flags);
1105
1da177e4
LT
1106 result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0)
1107 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1108 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1109 | ((status & MSVR_DSR) ? TIOCM_DSR : 0)
1110 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1111 return result;
1112}
1113
1114static int rc_tiocmset(struct tty_struct *tty, struct file *file,
1115 unsigned int set, unsigned int clear)
1116{
c9f19e96 1117 struct riscom_port *port = tty->driver_data;
1da177e4
LT
1118 unsigned long flags;
1119 struct riscom_board *bp;
1120
bf9d8929 1121 if (rc_paranoia_check(port, tty->name, __func__))
1da177e4
LT
1122 return -ENODEV;
1123
1124 bp = port_Board(port);
1125
d9afa435
JG
1126 spin_lock_irqsave(&riscom_lock, flags);
1127
1da177e4
LT
1128 if (set & TIOCM_RTS)
1129 port->MSVR |= MSVR_RTS;
1130 if (set & TIOCM_DTR)
1131 bp->DTR &= ~(1u << port_No(port));
1132
1133 if (clear & TIOCM_RTS)
1134 port->MSVR &= ~MSVR_RTS;
1135 if (clear & TIOCM_DTR)
1136 bp->DTR |= (1u << port_No(port));
1137
1138 rc_out(bp, CD180_CAR, port_No(port));
1139 rc_out(bp, CD180_MSVR, port->MSVR);
1140 rc_out(bp, RC_DTR, bp->DTR);
d9afa435
JG
1141
1142 spin_unlock_irqrestore(&riscom_lock, flags);
1143
1da177e4
LT
1144 return 0;
1145}
1146
781cff5c 1147static int rc_send_break(struct tty_struct *tty, int length)
1da177e4 1148{
c9f19e96 1149 struct riscom_port *port = tty->driver_data;
1da177e4
LT
1150 struct riscom_board *bp = port_Board(port);
1151 unsigned long flags;
9492e135 1152
781cff5c
AC
1153 if (length == 0 || length == -1)
1154 return -EOPNOTSUPP;
1155
d9afa435
JG
1156 spin_lock_irqsave(&riscom_lock, flags);
1157
1da177e4
LT
1158 port->break_length = RISCOM_TPS / HZ * length;
1159 port->COR2 |= COR2_ETC;
1160 port->IER |= IER_TXRDY;
1161 rc_out(bp, CD180_CAR, port_No(port));
1162 rc_out(bp, CD180_COR2, port->COR2);
1163 rc_out(bp, CD180_IER, port->IER);
1164 rc_wait_CCR(bp);
1165 rc_out(bp, CD180_CCR, CCR_CORCHG2);
1166 rc_wait_CCR(bp);
d9afa435
JG
1167
1168 spin_unlock_irqrestore(&riscom_lock, flags);
781cff5c 1169 return 0;
1da177e4
LT
1170}
1171
9492e135
AC
1172static int rc_set_serial_info(struct riscom_port *port,
1173 struct serial_struct __user *newinfo)
1da177e4
LT
1174{
1175 struct serial_struct tmp;
1176 struct riscom_board *bp = port_Board(port);
1177 int change_speed;
9492e135 1178
1da177e4
LT
1179 if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
1180 return -EFAULT;
9492e135
AC
1181
1182#if 0
1da177e4
LT
1183 if ((tmp.irq != bp->irq) ||
1184 (tmp.port != bp->base) ||
1185 (tmp.type != PORT_CIRRUS) ||
1186 (tmp.baud_base != (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC) ||
1187 (tmp.custom_divisor != 0) ||
1188 (tmp.xmit_fifo_size != CD180_NFIFO) ||
1189 (tmp.flags & ~RISCOM_LEGAL_FLAGS))
1190 return -EINVAL;
9492e135
AC
1191#endif
1192
85f8f810 1193 change_speed = ((port->port.flags & ASYNC_SPD_MASK) !=
1da177e4 1194 (tmp.flags & ASYNC_SPD_MASK));
9492e135 1195
1da177e4 1196 if (!capable(CAP_SYS_ADMIN)) {
44b7d1b3
AC
1197 if ((tmp.close_delay != port->port.close_delay) ||
1198 (tmp.closing_wait != port->port.closing_wait) ||
1da177e4 1199 ((tmp.flags & ~ASYNC_USR_MASK) !=
85f8f810 1200 (port->port.flags & ~ASYNC_USR_MASK)))
1da177e4 1201 return -EPERM;
85f8f810 1202 port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1da177e4
LT
1203 (tmp.flags & ASYNC_USR_MASK));
1204 } else {
85f8f810 1205 port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1da177e4 1206 (tmp.flags & ASYNC_FLAGS));
44b7d1b3
AC
1207 port->port.close_delay = tmp.close_delay;
1208 port->port.closing_wait = tmp.closing_wait;
1da177e4
LT
1209 }
1210 if (change_speed) {
d9afa435
JG
1211 unsigned long flags;
1212
1213 spin_lock_irqsave(&riscom_lock, flags);
1da177e4 1214 rc_change_speed(bp, port);
d9afa435 1215 spin_unlock_irqrestore(&riscom_lock, flags);
1da177e4
LT
1216 }
1217 return 0;
1218}
1219
9492e135 1220static int rc_get_serial_info(struct riscom_port *port,
1da177e4
LT
1221 struct serial_struct __user *retinfo)
1222{
1223 struct serial_struct tmp;
1224 struct riscom_board *bp = port_Board(port);
9492e135 1225
1da177e4
LT
1226 memset(&tmp, 0, sizeof(tmp));
1227 tmp.type = PORT_CIRRUS;
1228 tmp.line = port - rc_port;
1229 tmp.port = bp->base;
1230 tmp.irq = bp->irq;
85f8f810 1231 tmp.flags = port->port.flags;
1da177e4 1232 tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC;
44b7d1b3
AC
1233 tmp.close_delay = port->port.close_delay * HZ/100;
1234 tmp.closing_wait = port->port.closing_wait * HZ/100;
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
AC
1250 case TIOCGSERIAL:
1251 lock_kernel();
eb174552
AC
1252 retval = rc_get_serial_info(port, argp);
1253 unlock_kernel();
1da177e4 1254 break;
9492e135
AC
1255 case TIOCSSERIAL:
1256 lock_kernel();
eb174552
AC
1257 retval = rc_set_serial_info(port, argp);
1258 unlock_kernel();
1259 break;
9492e135 1260 default:
eb174552 1261 retval = -ENOIOCTLCMD;
1da177e4 1262 }
eb174552 1263 return retval;
1da177e4
LT
1264}
1265
9492e135 1266static void rc_throttle(struct tty_struct *tty)
1da177e4 1267{
c9f19e96 1268 struct riscom_port *port = tty->driver_data;
1da177e4
LT
1269 struct riscom_board *bp;
1270 unsigned long flags;
9492e135 1271
1da177e4
LT
1272 if (rc_paranoia_check(port, tty->name, "rc_throttle"))
1273 return;
1da177e4 1274 bp = port_Board(port);
d9afa435
JG
1275
1276 spin_lock_irqsave(&riscom_lock, flags);
1da177e4
LT
1277 port->MSVR &= ~MSVR_RTS;
1278 rc_out(bp, CD180_CAR, port_No(port));
d9afa435 1279 if (I_IXOFF(tty)) {
1da177e4
LT
1280 rc_wait_CCR(bp);
1281 rc_out(bp, CD180_CCR, CCR_SSCH2);
1282 rc_wait_CCR(bp);
1283 }
1284 rc_out(bp, CD180_MSVR, port->MSVR);
d9afa435 1285 spin_unlock_irqrestore(&riscom_lock, flags);
1da177e4
LT
1286}
1287
9492e135 1288static void rc_unthrottle(struct tty_struct *tty)
1da177e4 1289{
c9f19e96 1290 struct riscom_port *port = tty->driver_data;
1da177e4
LT
1291 struct riscom_board *bp;
1292 unsigned long flags;
9492e135 1293
1da177e4
LT
1294 if (rc_paranoia_check(port, tty->name, "rc_unthrottle"))
1295 return;
1da177e4 1296 bp = port_Board(port);
d9afa435 1297
9492e135 1298 spin_lock_irqsave(&riscom_lock, flags);
1da177e4
LT
1299 port->MSVR |= MSVR_RTS;
1300 rc_out(bp, CD180_CAR, port_No(port));
1301 if (I_IXOFF(tty)) {
1302 rc_wait_CCR(bp);
1303 rc_out(bp, CD180_CCR, CCR_SSCH1);
1304 rc_wait_CCR(bp);
1305 }
1306 rc_out(bp, CD180_MSVR, port->MSVR);
d9afa435 1307 spin_unlock_irqrestore(&riscom_lock, flags);
1da177e4
LT
1308}
1309
9492e135 1310static void rc_stop(struct tty_struct *tty)
1da177e4 1311{
c9f19e96 1312 struct riscom_port *port = tty->driver_data;
1da177e4
LT
1313 struct riscom_board *bp;
1314 unsigned long flags;
9492e135 1315
1da177e4
LT
1316 if (rc_paranoia_check(port, tty->name, "rc_stop"))
1317 return;
9492e135 1318
1da177e4 1319 bp = port_Board(port);
d9afa435 1320
9492e135 1321 spin_lock_irqsave(&riscom_lock, flags);
1da177e4
LT
1322 port->IER &= ~IER_TXRDY;
1323 rc_out(bp, CD180_CAR, port_No(port));
1324 rc_out(bp, CD180_IER, port->IER);
d9afa435 1325 spin_unlock_irqrestore(&riscom_lock, flags);
1da177e4
LT
1326}
1327
9492e135 1328static void rc_start(struct tty_struct *tty)
1da177e4 1329{
c9f19e96 1330 struct riscom_port *port = tty->driver_data;
1da177e4
LT
1331 struct riscom_board *bp;
1332 unsigned long flags;
9492e135 1333
1da177e4
LT
1334 if (rc_paranoia_check(port, tty->name, "rc_start"))
1335 return;
9492e135 1336
1da177e4 1337 bp = port_Board(port);
9492e135 1338
d9afa435
JG
1339 spin_lock_irqsave(&riscom_lock, flags);
1340
85f8f810 1341 if (port->xmit_cnt && port->port.xmit_buf && !(port->IER & IER_TXRDY)) {
1da177e4
LT
1342 port->IER |= IER_TXRDY;
1343 rc_out(bp, CD180_CAR, port_No(port));
1344 rc_out(bp, CD180_IER, port->IER);
1345 }
d9afa435 1346 spin_unlock_irqrestore(&riscom_lock, flags);
1da177e4
LT
1347}
1348
9492e135 1349static void rc_hangup(struct tty_struct *tty)
1da177e4 1350{
c9f19e96 1351 struct riscom_port *port = tty->driver_data;
1da177e4 1352 struct riscom_board *bp;
c2ba38cd 1353 unsigned long flags;
9492e135 1354
1da177e4
LT
1355 if (rc_paranoia_check(port, tty->name, "rc_hangup"))
1356 return;
9492e135 1357
1da177e4 1358 bp = port_Board(port);
9492e135 1359
d99101fd 1360 rc_shutdown_port(tty, bp, port);
c2ba38cd 1361 spin_lock_irqsave(&port->port.lock, flags);
85f8f810
AC
1362 port->port.count = 0;
1363 port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1364 port->port.tty = NULL;
1365 wake_up_interruptible(&port->port.open_wait);
c2ba38cd 1366 spin_unlock_irqrestore(&port->port.lock, flags);
1da177e4
LT
1367}
1368
9492e135
AC
1369static void rc_set_termios(struct tty_struct *tty,
1370 struct ktermios *old_termios)
1da177e4 1371{
c9f19e96 1372 struct riscom_port *port = tty->driver_data;
1da177e4 1373 unsigned long flags;
9492e135 1374
1da177e4
LT
1375 if (rc_paranoia_check(port, tty->name, "rc_set_termios"))
1376 return;
1da177e4 1377
d9afa435 1378 spin_lock_irqsave(&riscom_lock, flags);
1da177e4 1379 rc_change_speed(port_Board(port), port);
d9afa435 1380 spin_unlock_irqrestore(&riscom_lock, flags);
1da177e4
LT
1381
1382 if ((old_termios->c_cflag & CRTSCTS) &&
1383 !(tty->termios->c_cflag & CRTSCTS)) {
1384 tty->hw_stopped = 0;
1385 rc_start(tty);
1386 }
1387}
1388
b68e31d0 1389static const struct tty_operations riscom_ops = {
1da177e4
LT
1390 .open = rc_open,
1391 .close = rc_close,
1392 .write = rc_write,
1393 .put_char = rc_put_char,
1394 .flush_chars = rc_flush_chars,
1395 .write_room = rc_write_room,
1396 .chars_in_buffer = rc_chars_in_buffer,
1397 .flush_buffer = rc_flush_buffer,
1398 .ioctl = rc_ioctl,
1399 .throttle = rc_throttle,
1400 .unthrottle = rc_unthrottle,
1401 .set_termios = rc_set_termios,
1402 .stop = rc_stop,
1403 .start = rc_start,
1404 .hangup = rc_hangup,
1405 .tiocmget = rc_tiocmget,
1406 .tiocmset = rc_tiocmset,
781cff5c 1407 .break_ctl = rc_send_break,
1da177e4
LT
1408};
1409
31f35939
AC
1410static const struct tty_port_operations riscom_port_ops = {
1411 .carrier_raised = carrier_raised,
1412};
1413
1414
1386a820 1415static int __init rc_init_drivers(void)
1da177e4
LT
1416{
1417 int error;
1418 int i;
1419
1420 riscom_driver = alloc_tty_driver(RC_NBOARD * RC_NPORT);
9492e135 1421 if (!riscom_driver)
1da177e4 1422 return -ENOMEM;
9492e135 1423
1da177e4
LT
1424 riscom_driver->owner = THIS_MODULE;
1425 riscom_driver->name = "ttyL";
1da177e4
LT
1426 riscom_driver->major = RISCOM8_NORMAL_MAJOR;
1427 riscom_driver->type = TTY_DRIVER_TYPE_SERIAL;
1428 riscom_driver->subtype = SERIAL_TYPE_NORMAL;
1429 riscom_driver->init_termios = tty_std_termios;
1430 riscom_driver->init_termios.c_cflag =
1431 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
606d099c
AC
1432 riscom_driver->init_termios.c_ispeed = 9600;
1433 riscom_driver->init_termios.c_ospeed = 9600;
781cff5c 1434 riscom_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_HARDWARE_BREAK;
1da177e4 1435 tty_set_operations(riscom_driver, &riscom_ops);
9492e135
AC
1436 error = tty_register_driver(riscom_driver);
1437 if (error != 0) {
1da177e4
LT
1438 put_tty_driver(riscom_driver);
1439 printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, "
9492e135 1440 "error = %d\n", error);
1da177e4
LT
1441 return 1;
1442 }
1da177e4
LT
1443 memset(rc_port, 0, sizeof(rc_port));
1444 for (i = 0; i < RC_NPORT * RC_NBOARD; i++) {
85f8f810 1445 tty_port_init(&rc_port[i].port);
31f35939 1446 rc_port[i].port.ops = &riscom_port_ops;
44b7d1b3 1447 rc_port[i].magic = RISCOM8_MAGIC;
1da177e4 1448 }
1da177e4
LT
1449 return 0;
1450}
1451
1452static void rc_release_drivers(void)
1453{
1da177e4
LT
1454 tty_unregister_driver(riscom_driver);
1455 put_tty_driver(riscom_driver);
1da177e4
LT
1456}
1457
1458#ifndef MODULE
1459/*
1460 * Called at boot time.
9492e135 1461 *
1da177e4
LT
1462 * You can specify IO base for up to RC_NBOARD cards,
1463 * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt.
1464 * Note that there will be no probing at default
1465 * addresses in this case.
1466 *
9492e135 1467 */
1da177e4
LT
1468static int __init riscom8_setup(char *str)
1469{
1470 int ints[RC_NBOARD];
1471 int i;
1472
1473 str = get_options(str, ARRAY_SIZE(ints), ints);
1474
1475 for (i = 0; i < RC_NBOARD; i++) {
1476 if (i < ints[0])
1477 rc_board[i].base = ints[i+1];
9492e135 1478 else
1da177e4
LT
1479 rc_board[i].base = 0;
1480 }
1481 return 1;
1482}
1483
1484__setup("riscom8=", riscom8_setup);
1485#endif
1486
1487static char banner[] __initdata =
1488 KERN_INFO "rc: SDL RISCom/8 card driver v1.1, (c) D.Gorodchanin "
1489 "1994-1996.\n";
1490static char no_boards_msg[] __initdata =
1491 KERN_INFO "rc: No RISCom/8 boards detected.\n";
1492
9492e135
AC
1493/*
1494 * This routine must be called by kernel at boot time
1da177e4
LT
1495 */
1496static int __init riscom8_init(void)
1497{
1498 int i;
1499 int found = 0;
1500
1501 printk(banner);
1502
9492e135 1503 if (rc_init_drivers())
1da177e4
LT
1504 return -EIO;
1505
9492e135
AC
1506 for (i = 0; i < RC_NBOARD; i++)
1507 if (rc_board[i].base && !rc_probe(&rc_board[i]))
1da177e4 1508 found++;
1da177e4
LT
1509 if (!found) {
1510 rc_release_drivers();
1511 printk(no_boards_msg);
1512 return -EIO;
1513 }
1514 return 0;
1515}
1516
1517#ifdef MODULE
1518static int iobase;
1519static int iobase1;
1520static int iobase2;
1521static int iobase3;
8d3b33f6
RR
1522module_param(iobase, int, 0);
1523module_param(iobase1, int, 0);
1524module_param(iobase2, int, 0);
1525module_param(iobase3, int, 0);
1da177e4
LT
1526
1527MODULE_LICENSE("GPL");
5c9f5806 1528MODULE_ALIAS_CHARDEV_MAJOR(RISCOM8_NORMAL_MAJOR);
1da177e4
LT
1529#endif /* MODULE */
1530
1531/*
1532 * You can setup up to 4 boards (current value of RC_NBOARD)
1533 * by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter.
1534 *
1535 */
9492e135 1536static int __init riscom8_init_module(void)
1da177e4
LT
1537{
1538#ifdef MODULE
1539 int i;
1540
1541 if (iobase || iobase1 || iobase2 || iobase3) {
9492e135 1542 for (i = 0; i < RC_NBOARD; i++)
9efda797 1543 rc_board[i].base = 0;
1da177e4
LT
1544 }
1545
1546 if (iobase)
1547 rc_board[0].base = iobase;
1548 if (iobase1)
1549 rc_board[1].base = iobase1;
1550 if (iobase2)
1551 rc_board[2].base = iobase2;
1552 if (iobase3)
1553 rc_board[3].base = iobase3;
1554#endif /* MODULE */
1555
1556 return riscom8_init();
1557}
9492e135
AC
1558
1559static void __exit riscom8_exit_module(void)
1da177e4
LT
1560{
1561 int i;
9492e135 1562
1da177e4 1563 rc_release_drivers();
9492e135
AC
1564 for (i = 0; i < RC_NBOARD; i++)
1565 if (rc_board[i].flags & RC_BOARD_PRESENT)
1da177e4 1566 rc_release_io_range(&rc_board[i]);
9492e135 1567
1da177e4
LT
1568}
1569
1570module_init(riscom8_init_module);
1571module_exit(riscom8_exit_module);
This page took 0.529371 seconds and 5 git commands to generate.