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