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