[NET_SCHED]: Fix endless loops caused by inaccurate qlen counters (part 1)
[hh.org.git] / drivers / char / specialix.c
blob7e1bd9562c2ac3c2e63b40fb50dc92019b5231f8
1 /*
2 * specialix.c -- specialix IO8+ multiport serial driver.
4 * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl)
5 * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com)
7 * Specialix pays for the development and support of this driver.
8 * Please DO contact io8-linux@specialix.co.uk if you require
9 * support. But please read the documentation (specialix.txt)
10 * first.
12 * This driver was developped in the BitWizard linux device
13 * driver service. If you require a linux device driver for your
14 * product, please contact devices@BitWizard.nl for a quote.
16 * This code is firmly based on the riscom/8 serial driver,
17 * written by Dmitry Gorodchanin. The specialix IO8+ card
18 * programming information was obtained from the CL-CD1865 Data
19 * Book, and Specialix document number 6200059: IO8+ Hardware
20 * Functional Specification.
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License as
24 * published by the Free Software Foundation; either version 2 of
25 * the License, or (at your option) any later version.
27 * This program is distributed in the hope that it will be
28 * useful, but WITHOUT ANY WARRANTY; without even the implied
29 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
30 * PURPOSE. See the GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public
33 * License along with this program; if not, write to the Free
34 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
35 * USA.
37 * Revision history:
39 * Revision 1.0: April 1st 1997.
40 * Initial release for alpha testing.
41 * Revision 1.1: April 14th 1997.
42 * Incorporated Richard Hudsons suggestions,
43 * removed some debugging printk's.
44 * Revision 1.2: April 15th 1997.
45 * Ported to 2.1.x kernels.
46 * Revision 1.3: April 17th 1997
47 * Backported to 2.0. (Compatibility macros).
48 * Revision 1.4: April 18th 1997
49 * Fixed DTR/RTS bug that caused the card to indicate
50 * "don't send data" to a modem after the password prompt.
51 * Fixed bug for premature (fake) interrupts.
52 * Revision 1.5: April 19th 1997
53 * fixed a minor typo in the header file, cleanup a little.
54 * performance warnings are now MAXed at once per minute.
55 * Revision 1.6: May 23 1997
56 * Changed the specialix=... format to include interrupt.
57 * Revision 1.7: May 27 1997
58 * Made many more debug printk's a compile time option.
59 * Revision 1.8: Jul 1 1997
60 * port to linux-2.1.43 kernel.
61 * Revision 1.9: Oct 9 1998
62 * Added stuff for the IO8+/PCI version.
63 * Revision 1.10: Oct 22 1999 / Jan 21 2000.
64 * Added stuff for setserial.
65 * Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr)
69 #define VERSION "1.11"
73 * There is a bunch of documentation about the card, jumpers, config
74 * settings, restrictions, cables, device names and numbers in
75 * Documentation/specialix.txt
78 #include <linux/module.h>
80 #include <asm/io.h>
81 #include <linux/kernel.h>
82 #include <linux/sched.h>
83 #include <linux/ioport.h>
84 #include <linux/interrupt.h>
85 #include <linux/errno.h>
86 #include <linux/tty.h>
87 #include <linux/tty_flip.h>
88 #include <linux/mm.h>
89 #include <linux/serial.h>
90 #include <linux/fcntl.h>
91 #include <linux/major.h>
92 #include <linux/delay.h>
93 #include <linux/pci.h>
94 #include <linux/init.h>
95 #include <asm/uaccess.h>
97 #include "specialix_io8.h"
98 #include "cd1865.h"
102 This driver can spew a whole lot of debugging output at you. If you
103 need maximum performance, you should disable the DEBUG define. To
104 aid in debugging in the field, I'm leaving the compile-time debug
105 features enabled, and disable them "runtime". That allows me to
106 instruct people with problems to enable debugging without requiring
107 them to recompile...
109 #define DEBUG
111 static int sx_debug;
112 static int sx_rxfifo = SPECIALIX_RXFIFO;
114 #ifdef DEBUG
115 #define dprintk(f, str...) if (sx_debug & f) printk (str)
116 #else
117 #define dprintk(f, str...) /* nothing */
118 #endif
120 #define SX_DEBUG_FLOW 0x0001
121 #define SX_DEBUG_DATA 0x0002
122 #define SX_DEBUG_PROBE 0x0004
123 #define SX_DEBUG_CHAN 0x0008
124 #define SX_DEBUG_INIT 0x0010
125 #define SX_DEBUG_RX 0x0020
126 #define SX_DEBUG_TX 0x0040
127 #define SX_DEBUG_IRQ 0x0080
128 #define SX_DEBUG_OPEN 0x0100
129 #define SX_DEBUG_TERMIOS 0x0200
130 #define SX_DEBUG_SIGNALS 0x0400
131 #define SX_DEBUG_FIFO 0x0800
134 #define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__FUNCTION__)
135 #define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __FUNCTION__)
137 #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
140 /* Configurable options: */
142 /* Am I paranoid or not ? ;-) */
143 #define SPECIALIX_PARANOIA_CHECK
145 /* Do I trust the IRQ from the card? (enabeling it doesn't seem to help)
146 When the IRQ routine leaves the chip in a state that is keeps on
147 requiring attention, the timer doesn't help either. */
148 #undef SPECIALIX_TIMER
150 #ifdef SPECIALIX_TIMER
151 static int sx_poll = HZ;
152 #endif
157 * The following defines are mostly for testing purposes. But if you need
158 * some nice reporting in your syslog, you can define them also.
160 #undef SX_REPORT_FIFO
161 #undef SX_REPORT_OVERRUN
165 #ifdef CONFIG_SPECIALIX_RTSCTS
166 #define SX_CRTSCTS(bla) 1
167 #else
168 #define SX_CRTSCTS(tty) C_CRTSCTS(tty)
169 #endif
172 /* Used to be outb (0xff, 0x80); */
173 #define short_pause() udelay (1)
176 #define SPECIALIX_LEGAL_FLAGS \
177 (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \
178 ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \
179 ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
181 #undef RS_EVENT_WRITE_WAKEUP
182 #define RS_EVENT_WRITE_WAKEUP 0
184 static struct tty_driver *specialix_driver;
186 static struct specialix_board sx_board[SX_NBOARD] = {
187 { 0, SX_IOBASE1, 9, },
188 { 0, SX_IOBASE2, 11, },
189 { 0, SX_IOBASE3, 12, },
190 { 0, SX_IOBASE4, 15, },
193 static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
196 #ifdef SPECIALIX_TIMER
197 static struct timer_list missed_irq_timer;
198 static irqreturn_t sx_interrupt(int irq, void * dev_id);
199 #endif
203 static inline int sx_paranoia_check(struct specialix_port const * port,
204 char *name, const char *routine)
206 #ifdef SPECIALIX_PARANOIA_CHECK
207 static const char *badmagic =
208 KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
209 static const char *badinfo =
210 KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
212 if (!port) {
213 printk(badinfo, name, routine);
214 return 1;
216 if (port->magic != SPECIALIX_MAGIC) {
217 printk(badmagic, name, routine);
218 return 1;
220 #endif
221 return 0;
227 * Service functions for specialix IO8+ driver.
231 /* Get board number from pointer */
232 static inline int board_No (struct specialix_board * bp)
234 return bp - sx_board;
238 /* Get port number from pointer */
239 static inline int port_No (struct specialix_port const * port)
241 return SX_PORT(port - sx_port);
245 /* Get pointer to board from pointer to port */
246 static inline struct specialix_board * port_Board(struct specialix_port const * port)
248 return &sx_board[SX_BOARD(port - sx_port)];
252 /* Input Byte from CL CD186x register */
253 static inline unsigned char sx_in(struct specialix_board * bp, unsigned short reg)
255 bp->reg = reg | 0x80;
256 outb (reg | 0x80, bp->base + SX_ADDR_REG);
257 return inb (bp->base + SX_DATA_REG);
261 /* Output Byte to CL CD186x register */
262 static inline void sx_out(struct specialix_board * bp, unsigned short reg,
263 unsigned char val)
265 bp->reg = reg | 0x80;
266 outb (reg | 0x80, bp->base + SX_ADDR_REG);
267 outb (val, bp->base + SX_DATA_REG);
271 /* Input Byte from CL CD186x register */
272 static inline unsigned char sx_in_off(struct specialix_board * bp, unsigned short reg)
274 bp->reg = reg;
275 outb (reg, bp->base + SX_ADDR_REG);
276 return inb (bp->base + SX_DATA_REG);
280 /* Output Byte to CL CD186x register */
281 static inline void sx_out_off(struct specialix_board * bp, unsigned short reg,
282 unsigned char val)
284 bp->reg = reg;
285 outb (reg, bp->base + SX_ADDR_REG);
286 outb (val, bp->base + SX_DATA_REG);
290 /* Wait for Channel Command Register ready */
291 static inline void sx_wait_CCR(struct specialix_board * bp)
293 unsigned long delay, flags;
294 unsigned char ccr;
296 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
297 spin_lock_irqsave(&bp->lock, flags);
298 ccr = sx_in(bp, CD186x_CCR);
299 spin_unlock_irqrestore(&bp->lock, flags);
300 if (!ccr)
301 return;
302 udelay (1);
305 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
309 /* Wait for Channel Command Register ready */
310 static inline void sx_wait_CCR_off(struct specialix_board * bp)
312 unsigned long delay;
313 unsigned char crr;
314 unsigned long flags;
316 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
317 spin_lock_irqsave(&bp->lock, flags);
318 crr = sx_in_off(bp, CD186x_CCR);
319 spin_unlock_irqrestore(&bp->lock, flags);
320 if (!crr)
321 return;
322 udelay (1);
325 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
330 * specialix IO8+ IO range functions.
333 static inline int sx_request_io_range(struct specialix_board * bp)
335 return request_region(bp->base,
336 bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
337 "specialix IO8+") == NULL;
341 static inline void sx_release_io_range(struct specialix_board * bp)
343 release_region(bp->base,
344 bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
348 /* Must be called with enabled interrupts */
349 /* Ugly. Very ugly. Don't use this for anything else than initialization
350 code */
351 static inline void sx_long_delay(unsigned long delay)
353 unsigned long i;
355 for (i = jiffies + delay; time_after(i, jiffies); ) ;
360 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
361 static int sx_set_irq ( struct specialix_board *bp)
363 int virq;
364 int i;
365 unsigned long flags;
367 if (bp->flags & SX_BOARD_IS_PCI)
368 return 1;
369 switch (bp->irq) {
370 /* In the same order as in the docs... */
371 case 15: virq = 0;break;
372 case 12: virq = 1;break;
373 case 11: virq = 2;break;
374 case 9: virq = 3;break;
375 default: printk (KERN_ERR "Speclialix: cannot set irq to %d.\n", bp->irq);
376 return 0;
378 spin_lock_irqsave(&bp->lock, flags);
379 for (i=0;i<2;i++) {
380 sx_out(bp, CD186x_CAR, i);
381 sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
383 spin_unlock_irqrestore(&bp->lock, flags);
384 return 1;
388 /* Reset and setup CD186x chip */
389 static int sx_init_CD186x(struct specialix_board * bp)
391 unsigned long flags;
392 int scaler;
393 int rv = 1;
395 func_enter();
396 sx_wait_CCR_off(bp); /* Wait for CCR ready */
397 spin_lock_irqsave(&bp->lock, flags);
398 sx_out_off(bp, CD186x_CCR, CCR_HARDRESET); /* Reset CD186x chip */
399 spin_unlock_irqrestore(&bp->lock, flags);
400 sx_long_delay(HZ/20); /* Delay 0.05 sec */
401 spin_lock_irqsave(&bp->lock, flags);
402 sx_out_off(bp, CD186x_GIVR, SX_ID); /* Set ID for this chip */
403 sx_out_off(bp, CD186x_GICR, 0); /* Clear all bits */
404 sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT); /* Prio for modem intr */
405 sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */
406 sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
407 /* Set RegAckEn */
408 sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
410 /* Setting up prescaler. We need 4 ticks per 1 ms */
411 scaler = SX_OSCFREQ/SPECIALIX_TPS;
413 sx_out_off(bp, CD186x_PPRH, scaler >> 8);
414 sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
415 spin_unlock_irqrestore(&bp->lock, flags);
417 if (!sx_set_irq (bp)) {
418 /* Figure out how to pass this along... */
419 printk (KERN_ERR "Cannot set irq to %d.\n", bp->irq);
420 rv = 0;
423 func_exit();
424 return rv;
428 static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
430 int i;
431 int t;
432 unsigned long flags;
434 spin_lock_irqsave(&bp->lock, flags);
435 for (i=0, t=0;i<8;i++) {
436 sx_out_off (bp, CD186x_CAR, i);
437 if (sx_in_off (bp, reg) & bit)
438 t |= 1 << i;
440 spin_unlock_irqrestore(&bp->lock, flags);
442 return t;
446 #ifdef SPECIALIX_TIMER
447 void missed_irq (unsigned long data)
449 unsigned char irq;
450 unsigned long flags;
451 struct specialix_board *bp = (struct specialix_board *)data;
453 spin_lock_irqsave(&bp->lock, flags);
454 irq = sx_in ((struct specialix_board *)data, CD186x_SRSR) &
455 (SRSR_RREQint |
456 SRSR_TREQint |
457 SRSR_MREQint);
458 spin_unlock_irqrestore(&bp->lock, flags);
459 if (irq) {
460 printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
461 sx_interrupt (((struct specialix_board *)data)->irq,
462 (void*)data, NULL);
464 missed_irq_timer.expires = jiffies + sx_poll;
465 add_timer (&missed_irq_timer);
467 #endif
471 /* Main probing routine, also sets irq. */
472 static int sx_probe(struct specialix_board *bp)
474 unsigned char val1, val2;
475 #if 0
476 int irqs = 0;
477 int retries;
478 #endif
479 int rev;
480 int chip;
482 func_enter();
484 if (sx_request_io_range(bp)) {
485 func_exit();
486 return 1;
489 /* Are the I/O ports here ? */
490 sx_out_off(bp, CD186x_PPRL, 0x5a);
491 short_pause ();
492 val1 = sx_in_off(bp, CD186x_PPRL);
494 sx_out_off(bp, CD186x_PPRL, 0xa5);
495 short_pause ();
496 val2 = sx_in_off(bp, CD186x_PPRL);
499 if ((val1 != 0x5a) || (val2 != 0xa5)) {
500 printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
501 board_No(bp), bp->base);
502 sx_release_io_range(bp);
503 func_exit();
504 return 1;
507 /* Check the DSR lines that Specialix uses as board
508 identification */
509 val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
510 val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
511 dprintk (SX_DEBUG_INIT, "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
512 board_No(bp), val1, val2);
514 /* They managed to switch the bit order between the docs and
515 the IO8+ card. The new PCI card now conforms to old docs.
516 They changed the PCI docs to reflect the situation on the
517 old card. */
518 val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
519 if (val1 != val2) {
520 printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
521 board_No(bp), val2, bp->base, val1);
522 sx_release_io_range(bp);
523 func_exit();
524 return 1;
528 #if 0
529 /* It's time to find IRQ for this board */
530 for (retries = 0; retries < 5 && irqs <= 0; retries++) {
531 irqs = probe_irq_on();
532 sx_init_CD186x(bp); /* Reset CD186x chip */
533 sx_out(bp, CD186x_CAR, 2); /* Select port 2 */
534 sx_wait_CCR(bp);
535 sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */
536 sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */
537 sx_long_delay(HZ/20);
538 irqs = probe_irq_off(irqs);
540 dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
541 dprintk (SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR));
542 dprintk (SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR));
543 dprintk (SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR));
544 dprintk (SX_DEBUG_INIT, "\n");
546 /* Reset CD186x again */
547 if (!sx_init_CD186x(bp)) {
548 /* Hmmm. This is dead code anyway. */
551 dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
552 val1, val2, val3);
556 #if 0
557 if (irqs <= 0) {
558 printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
559 board_No(bp), bp->base);
560 sx_release_io_range(bp);
561 func_exit();
562 return 1;
564 #endif
565 printk (KERN_INFO "Started with irq=%d, but now have irq=%d.\n", bp->irq, irqs);
566 if (irqs > 0)
567 bp->irq = irqs;
568 #endif
569 /* Reset CD186x again */
570 if (!sx_init_CD186x(bp)) {
571 sx_release_io_range(bp);
572 func_exit();
573 return 1;
576 sx_request_io_range(bp);
577 bp->flags |= SX_BOARD_PRESENT;
579 /* Chip revcode pkgtype
580 GFRCR SRCR bit 7
581 CD180 rev B 0x81 0
582 CD180 rev C 0x82 0
583 CD1864 rev A 0x82 1
584 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
585 CD1865 rev B 0x84 1
586 -- Thanks to Gwen Wang, Cirrus Logic.
589 switch (sx_in_off(bp, CD186x_GFRCR)) {
590 case 0x82:chip = 1864;rev='A';break;
591 case 0x83:chip = 1865;rev='A';break;
592 case 0x84:chip = 1865;rev='B';break;
593 case 0x85:chip = 1865;rev='C';break; /* Does not exist at this time */
594 default:chip=-1;rev='x';
597 dprintk (SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR) );
599 #ifdef SPECIALIX_TIMER
600 init_timer (&missed_irq_timer);
601 missed_irq_timer.function = missed_irq;
602 missed_irq_timer.data = (unsigned long) bp;
603 missed_irq_timer.expires = jiffies + sx_poll;
604 add_timer (&missed_irq_timer);
605 #endif
607 printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
608 board_No(bp),
609 bp->base, bp->irq,
610 chip, rev);
612 func_exit();
613 return 0;
618 * Interrupt processing routines.
619 * */
621 static inline void sx_mark_event(struct specialix_port * port, int event)
623 func_enter();
625 set_bit(event, &port->event);
626 schedule_work(&port->tqueue);
628 func_exit();
632 static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
633 unsigned char const * what)
635 unsigned char channel;
636 struct specialix_port * port = NULL;
638 channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
639 dprintk (SX_DEBUG_CHAN, "channel: %d\n", channel);
640 if (channel < CD186x_NCH) {
641 port = &sx_port[board_No(bp) * SX_NPORT + channel];
642 dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%x\n",board_No(bp) * SX_NPORT + channel, port, port->flags & ASYNC_INITIALIZED);
644 if (port->flags & ASYNC_INITIALIZED) {
645 dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
646 func_exit();
647 return port;
650 printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
651 board_No(bp), what, channel);
652 return NULL;
656 static inline void sx_receive_exc(struct specialix_board * bp)
658 struct specialix_port *port;
659 struct tty_struct *tty;
660 unsigned char status;
661 unsigned char ch, flag;
663 func_enter();
665 port = sx_get_port(bp, "Receive");
666 if (!port) {
667 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
668 func_exit();
669 return;
671 tty = port->tty;
673 status = sx_in(bp, CD186x_RCSR);
675 dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
676 if (status & RCSR_OE) {
677 port->overrun++;
678 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Overrun. Total %ld overruns.\n",
679 board_No(bp), port_No(port), port->overrun);
681 status &= port->mark_mask;
683 /* This flip buffer check needs to be below the reading of the
684 status register to reset the chip's IRQ.... */
685 if (tty_buffer_request_room(tty, 1) == 0) {
686 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n",
687 board_No(bp), port_No(port));
688 func_exit();
689 return;
692 ch = sx_in(bp, CD186x_RDR);
693 if (!status) {
694 func_exit();
695 return;
697 if (status & RCSR_TOUT) {
698 printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
699 board_No(bp), port_No(port));
700 func_exit();
701 return;
703 } else if (status & RCSR_BREAK) {
704 dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
705 board_No(bp), port_No(port));
706 flag = TTY_BREAK;
707 if (port->flags & ASYNC_SAK)
708 do_SAK(tty);
710 } else if (status & RCSR_PE)
711 flag = TTY_PARITY;
713 else if (status & RCSR_FE)
714 flag = TTY_FRAME;
716 else if (status & RCSR_OE)
717 flag = TTY_OVERRUN;
719 else
720 flag = TTY_NORMAL;
722 if(tty_insert_flip_char(tty, ch, flag))
723 tty_flip_buffer_push(tty);
724 func_exit();
728 static inline void sx_receive(struct specialix_board * bp)
730 struct specialix_port *port;
731 struct tty_struct *tty;
732 unsigned char count;
734 func_enter();
736 if (!(port = sx_get_port(bp, "Receive"))) {
737 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
738 func_exit();
739 return;
741 tty = port->tty;
743 count = sx_in(bp, CD186x_RDCR);
744 dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
745 port->hits[count > 8 ? 9 : count]++;
747 tty_buffer_request_room(tty, count);
749 while (count--)
750 tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL);
751 tty_flip_buffer_push(tty);
752 func_exit();
756 static inline void sx_transmit(struct specialix_board * bp)
758 struct specialix_port *port;
759 struct tty_struct *tty;
760 unsigned char count;
762 func_enter();
763 if (!(port = sx_get_port(bp, "Transmit"))) {
764 func_exit();
765 return;
767 dprintk (SX_DEBUG_TX, "port: %p\n", port);
768 tty = port->tty;
770 if (port->IER & IER_TXEMPTY) {
771 /* FIFO drained */
772 sx_out(bp, CD186x_CAR, port_No(port));
773 port->IER &= ~IER_TXEMPTY;
774 sx_out(bp, CD186x_IER, port->IER);
775 func_exit();
776 return;
779 if ((port->xmit_cnt <= 0 && !port->break_length)
780 || tty->stopped || tty->hw_stopped) {
781 sx_out(bp, CD186x_CAR, port_No(port));
782 port->IER &= ~IER_TXRDY;
783 sx_out(bp, CD186x_IER, port->IER);
784 func_exit();
785 return;
788 if (port->break_length) {
789 if (port->break_length > 0) {
790 if (port->COR2 & COR2_ETC) {
791 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
792 sx_out(bp, CD186x_TDR, CD186x_C_SBRK);
793 port->COR2 &= ~COR2_ETC;
795 count = min_t(int, port->break_length, 0xff);
796 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
797 sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
798 sx_out(bp, CD186x_TDR, count);
799 if (!(port->break_length -= count))
800 port->break_length--;
801 } else {
802 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
803 sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
804 sx_out(bp, CD186x_COR2, port->COR2);
805 sx_wait_CCR(bp);
806 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
807 port->break_length = 0;
810 func_exit();
811 return;
814 count = CD186x_NFIFO;
815 do {
816 sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
817 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
818 if (--port->xmit_cnt <= 0)
819 break;
820 } while (--count > 0);
822 if (port->xmit_cnt <= 0) {
823 sx_out(bp, CD186x_CAR, port_No(port));
824 port->IER &= ~IER_TXRDY;
825 sx_out(bp, CD186x_IER, port->IER);
827 if (port->xmit_cnt <= port->wakeup_chars)
828 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
830 func_exit();
834 static inline void sx_check_modem(struct specialix_board * bp)
836 struct specialix_port *port;
837 struct tty_struct *tty;
838 unsigned char mcr;
839 int msvr_cd;
841 dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
842 if (!(port = sx_get_port(bp, "Modem")))
843 return;
845 tty = port->tty;
847 mcr = sx_in(bp, CD186x_MCR);
848 printk ("mcr = %02x.\n", mcr);
850 if ((mcr & MCR_CDCHG)) {
851 dprintk (SX_DEBUG_SIGNALS, "CD just changed... ");
852 msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
853 if (msvr_cd) {
854 dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
855 wake_up_interruptible(&port->open_wait);
856 } else {
857 dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n");
858 schedule_work(&port->tqueue_hangup);
862 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
863 if (mcr & MCR_CTSCHG) {
864 if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
865 tty->hw_stopped = 0;
866 port->IER |= IER_TXRDY;
867 if (port->xmit_cnt <= port->wakeup_chars)
868 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
869 } else {
870 tty->hw_stopped = 1;
871 port->IER &= ~IER_TXRDY;
873 sx_out(bp, CD186x_IER, port->IER);
875 if (mcr & MCR_DSSXHG) {
876 if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
877 tty->hw_stopped = 0;
878 port->IER |= IER_TXRDY;
879 if (port->xmit_cnt <= port->wakeup_chars)
880 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
881 } else {
882 tty->hw_stopped = 1;
883 port->IER &= ~IER_TXRDY;
885 sx_out(bp, CD186x_IER, port->IER);
887 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
889 /* Clear change bits */
890 sx_out(bp, CD186x_MCR, 0);
894 /* The main interrupt processing routine */
895 static irqreturn_t sx_interrupt(int irq, void *dev_id)
897 unsigned char status;
898 unsigned char ack;
899 struct specialix_board *bp;
900 unsigned long loop = 0;
901 int saved_reg;
902 unsigned long flags;
904 func_enter();
906 bp = dev_id;
907 spin_lock_irqsave(&bp->lock, flags);
909 dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __FUNCTION__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
910 if (!(bp->flags & SX_BOARD_ACTIVE)) {
911 dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq);
912 spin_unlock_irqrestore(&bp->lock, flags);
913 func_exit();
914 return IRQ_NONE;
917 saved_reg = bp->reg;
919 while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
920 (SRSR_RREQint |
921 SRSR_TREQint |
922 SRSR_MREQint)))) {
923 if (status & SRSR_RREQint) {
924 ack = sx_in(bp, CD186x_RRAR);
926 if (ack == (SX_ID | GIVR_IT_RCV))
927 sx_receive(bp);
928 else if (ack == (SX_ID | GIVR_IT_REXC))
929 sx_receive_exc(bp);
930 else
931 printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
932 board_No(bp), status, ack);
934 } else if (status & SRSR_TREQint) {
935 ack = sx_in(bp, CD186x_TRAR);
937 if (ack == (SX_ID | GIVR_IT_TX))
938 sx_transmit(bp);
939 else
940 printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
941 board_No(bp), status, ack, port_No (sx_get_port (bp, "Int")));
942 } else if (status & SRSR_MREQint) {
943 ack = sx_in(bp, CD186x_MRAR);
945 if (ack == (SX_ID | GIVR_IT_MODEM))
946 sx_check_modem(bp);
947 else
948 printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
949 board_No(bp), status, ack);
953 sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
955 bp->reg = saved_reg;
956 outb (bp->reg, bp->base + SX_ADDR_REG);
957 spin_unlock_irqrestore(&bp->lock, flags);
958 func_exit();
959 return IRQ_HANDLED;
964 * Routines for open & close processing.
967 static void turn_ints_off (struct specialix_board *bp)
969 unsigned long flags;
971 func_enter();
972 if (bp->flags & SX_BOARD_IS_PCI) {
973 /* This was intended for enabeling the interrupt on the
974 * PCI card. However it seems that it's already enabled
975 * and as PCI interrupts can be shared, there is no real
976 * reason to have to turn it off. */
979 spin_lock_irqsave(&bp->lock, flags);
980 (void) sx_in_off (bp, 0); /* Turn off interrupts. */
981 spin_unlock_irqrestore(&bp->lock, flags);
983 func_exit();
986 static void turn_ints_on (struct specialix_board *bp)
988 unsigned long flags;
990 func_enter();
992 if (bp->flags & SX_BOARD_IS_PCI) {
993 /* play with the PCI chip. See comment above. */
995 spin_lock_irqsave(&bp->lock, flags);
996 (void) sx_in (bp, 0); /* Turn ON interrupts. */
997 spin_unlock_irqrestore(&bp->lock, flags);
999 func_exit();
1003 /* Called with disabled interrupts */
1004 static inline int sx_setup_board(struct specialix_board * bp)
1006 int error;
1008 if (bp->flags & SX_BOARD_ACTIVE)
1009 return 0;
1011 if (bp->flags & SX_BOARD_IS_PCI)
1012 error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp);
1013 else
1014 error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED, "specialix IO8+", bp);
1016 if (error)
1017 return error;
1019 turn_ints_on (bp);
1020 bp->flags |= SX_BOARD_ACTIVE;
1022 return 0;
1026 /* Called with disabled interrupts */
1027 static inline void sx_shutdown_board(struct specialix_board *bp)
1029 func_enter();
1031 if (!(bp->flags & SX_BOARD_ACTIVE)) {
1032 func_exit();
1033 return;
1036 bp->flags &= ~SX_BOARD_ACTIVE;
1038 dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
1039 bp->irq, board_No (bp));
1040 free_irq(bp->irq, bp);
1042 turn_ints_off (bp);
1045 func_exit();
1050 * Setting up port characteristics.
1051 * Must be called with disabled interrupts
1053 static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
1055 struct tty_struct *tty;
1056 unsigned long baud;
1057 long tmp;
1058 unsigned char cor1 = 0, cor3 = 0;
1059 unsigned char mcor1 = 0, mcor2 = 0;
1060 static unsigned long again;
1061 unsigned long flags;
1063 func_enter();
1065 if (!(tty = port->tty) || !tty->termios) {
1066 func_exit();
1067 return;
1070 port->IER = 0;
1071 port->COR2 = 0;
1072 /* Select port on the board */
1073 spin_lock_irqsave(&bp->lock, flags);
1074 sx_out(bp, CD186x_CAR, port_No(port));
1076 /* The Specialix board doens't implement the RTS lines.
1077 They are used to set the IRQ level. Don't touch them. */
1078 if (SX_CRTSCTS(tty))
1079 port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1080 else
1081 port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1082 spin_unlock_irqrestore(&bp->lock, flags);
1083 dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
1084 baud = tty_get_baud_rate(tty);
1086 if (baud == 38400) {
1087 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1088 baud = 57600;
1089 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1090 baud = 115200;
1093 if (!baud) {
1094 /* Drop DTR & exit */
1095 dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
1096 if (!SX_CRTSCTS (tty)) {
1097 port -> MSVR &= ~ MSVR_DTR;
1098 spin_lock_irqsave(&bp->lock, flags);
1099 sx_out(bp, CD186x_MSVR, port->MSVR );
1100 spin_unlock_irqrestore(&bp->lock, flags);
1102 else
1103 dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1104 return;
1105 } else {
1106 /* Set DTR on */
1107 if (!SX_CRTSCTS (tty)) {
1108 port ->MSVR |= MSVR_DTR;
1113 * Now we must calculate some speed depended things
1116 /* Set baud rate for port */
1117 tmp = port->custom_divisor ;
1118 if ( tmp )
1119 printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n"
1120 "This is an untested option, please be carefull.\n",
1121 port_No (port), tmp);
1122 else
1123 tmp = (((SX_OSCFREQ + baud/2) / baud +
1124 CD186x_TPC/2) / CD186x_TPC);
1126 if ((tmp < 0x10) && time_before(again, jiffies)) {
1127 again = jiffies + HZ * 60;
1128 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1129 if (tmp >= 12) {
1130 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1131 "Performance degradation is possible.\n"
1132 "Read specialix.txt for more info.\n",
1133 port_No (port), tmp);
1134 } else {
1135 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1136 "Warning: overstressing Cirrus chip. "
1137 "This might not work.\n"
1138 "Read specialix.txt for more info.\n",
1139 port_No (port), tmp);
1142 spin_lock_irqsave(&bp->lock, flags);
1143 sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1144 sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1145 sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1146 sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1147 spin_unlock_irqrestore(&bp->lock, flags);
1148 if (port->custom_divisor)
1149 baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
1150 baud = (baud + 5) / 10; /* Estimated CPS */
1152 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1153 tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1154 port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1155 SERIAL_XMIT_SIZE - 1 : tmp);
1157 /* Receiver timeout will be transmission time for 1.5 chars */
1158 tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1159 tmp = (tmp > 0xff) ? 0xff : tmp;
1160 spin_lock_irqsave(&bp->lock, flags);
1161 sx_out(bp, CD186x_RTPR, tmp);
1162 spin_unlock_irqrestore(&bp->lock, flags);
1163 switch (C_CSIZE(tty)) {
1164 case CS5:
1165 cor1 |= COR1_5BITS;
1166 break;
1167 case CS6:
1168 cor1 |= COR1_6BITS;
1169 break;
1170 case CS7:
1171 cor1 |= COR1_7BITS;
1172 break;
1173 case CS8:
1174 cor1 |= COR1_8BITS;
1175 break;
1178 if (C_CSTOPB(tty))
1179 cor1 |= COR1_2SB;
1181 cor1 |= COR1_IGNORE;
1182 if (C_PARENB(tty)) {
1183 cor1 |= COR1_NORMPAR;
1184 if (C_PARODD(tty))
1185 cor1 |= COR1_ODDP;
1186 if (I_INPCK(tty))
1187 cor1 &= ~COR1_IGNORE;
1189 /* Set marking of some errors */
1190 port->mark_mask = RCSR_OE | RCSR_TOUT;
1191 if (I_INPCK(tty))
1192 port->mark_mask |= RCSR_FE | RCSR_PE;
1193 if (I_BRKINT(tty) || I_PARMRK(tty))
1194 port->mark_mask |= RCSR_BREAK;
1195 if (I_IGNPAR(tty))
1196 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1197 if (I_IGNBRK(tty)) {
1198 port->mark_mask &= ~RCSR_BREAK;
1199 if (I_IGNPAR(tty))
1200 /* Real raw mode. Ignore all */
1201 port->mark_mask &= ~RCSR_OE;
1203 /* Enable Hardware Flow Control */
1204 if (C_CRTSCTS(tty)) {
1205 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1206 port->IER |= IER_DSR | IER_CTS;
1207 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1208 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1209 spin_lock_irqsave(&bp->lock, flags);
1210 tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
1211 spin_unlock_irqrestore(&bp->lock, flags);
1212 #else
1213 port->COR2 |= COR2_CTSAE;
1214 #endif
1216 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1217 /* Some people reported that it works, but I still doubt it */
1218 if (I_IXON(tty)) {
1219 port->COR2 |= COR2_TXIBE;
1220 cor3 |= (COR3_FCT | COR3_SCDE);
1221 if (I_IXANY(tty))
1222 port->COR2 |= COR2_IXM;
1223 spin_lock_irqsave(&bp->lock, flags);
1224 sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1225 sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1226 sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1227 sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1228 spin_unlock_irqrestore(&bp->lock, flags);
1230 if (!C_CLOCAL(tty)) {
1231 /* Enable CD check */
1232 port->IER |= IER_CD;
1233 mcor1 |= MCOR1_CDZD;
1234 mcor2 |= MCOR2_CDOD;
1237 if (C_CREAD(tty))
1238 /* Enable receiver */
1239 port->IER |= IER_RXD;
1241 /* Set input FIFO size (1-8 bytes) */
1242 cor3 |= sx_rxfifo;
1243 /* Setting up CD186x channel registers */
1244 spin_lock_irqsave(&bp->lock, flags);
1245 sx_out(bp, CD186x_COR1, cor1);
1246 sx_out(bp, CD186x_COR2, port->COR2);
1247 sx_out(bp, CD186x_COR3, cor3);
1248 spin_unlock_irqrestore(&bp->lock, flags);
1249 /* Make CD186x know about registers change */
1250 sx_wait_CCR(bp);
1251 spin_lock_irqsave(&bp->lock, flags);
1252 sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1253 /* Setting up modem option registers */
1254 dprintk (SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2);
1255 sx_out(bp, CD186x_MCOR1, mcor1);
1256 sx_out(bp, CD186x_MCOR2, mcor2);
1257 spin_unlock_irqrestore(&bp->lock, flags);
1258 /* Enable CD186x transmitter & receiver */
1259 sx_wait_CCR(bp);
1260 spin_lock_irqsave(&bp->lock, flags);
1261 sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1262 /* Enable interrupts */
1263 sx_out(bp, CD186x_IER, port->IER);
1264 /* And finally set the modem lines... */
1265 sx_out(bp, CD186x_MSVR, port->MSVR);
1266 spin_unlock_irqrestore(&bp->lock, flags);
1268 func_exit();
1272 /* Must be called with interrupts enabled */
1273 static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port)
1275 unsigned long flags;
1277 func_enter();
1279 if (port->flags & ASYNC_INITIALIZED) {
1280 func_exit();
1281 return 0;
1284 if (!port->xmit_buf) {
1285 /* We may sleep in get_zeroed_page() */
1286 unsigned long tmp;
1288 if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
1289 func_exit();
1290 return -ENOMEM;
1293 if (port->xmit_buf) {
1294 free_page(tmp);
1295 func_exit();
1296 return -ERESTARTSYS;
1298 port->xmit_buf = (unsigned char *) tmp;
1301 spin_lock_irqsave(&port->lock, flags);
1303 if (port->tty)
1304 clear_bit(TTY_IO_ERROR, &port->tty->flags);
1306 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1307 sx_change_speed(bp, port);
1308 port->flags |= ASYNC_INITIALIZED;
1310 spin_unlock_irqrestore(&port->lock, flags);
1313 func_exit();
1314 return 0;
1318 /* Must be called with interrupts disabled */
1319 static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port)
1321 struct tty_struct *tty;
1322 int i;
1323 unsigned long flags;
1325 func_enter();
1327 if (!(port->flags & ASYNC_INITIALIZED)) {
1328 func_exit();
1329 return;
1332 if (sx_debug & SX_DEBUG_FIFO) {
1333 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
1334 board_No(bp), port_No(port), port->overrun);
1335 for (i = 0; i < 10; i++) {
1336 dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1338 dprintk(SX_DEBUG_FIFO, "].\n");
1341 if (port->xmit_buf) {
1342 free_page((unsigned long) port->xmit_buf);
1343 port->xmit_buf = NULL;
1346 /* Select port */
1347 spin_lock_irqsave(&bp->lock, flags);
1348 sx_out(bp, CD186x_CAR, port_No(port));
1350 if (!(tty = port->tty) || C_HUPCL(tty)) {
1351 /* Drop DTR */
1352 sx_out(bp, CD186x_MSVDTR, 0);
1354 spin_unlock_irqrestore(&bp->lock, flags);
1355 /* Reset port */
1356 sx_wait_CCR(bp);
1357 spin_lock_irqsave(&bp->lock, flags);
1358 sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1359 /* Disable all interrupts from this port */
1360 port->IER = 0;
1361 sx_out(bp, CD186x_IER, port->IER);
1362 spin_unlock_irqrestore(&bp->lock, flags);
1363 if (tty)
1364 set_bit(TTY_IO_ERROR, &tty->flags);
1365 port->flags &= ~ASYNC_INITIALIZED;
1367 if (!bp->count)
1368 sx_shutdown_board(bp);
1369 func_exit();
1373 static int block_til_ready(struct tty_struct *tty, struct file * filp,
1374 struct specialix_port *port)
1376 DECLARE_WAITQUEUE(wait, current);
1377 struct specialix_board *bp = port_Board(port);
1378 int retval;
1379 int do_clocal = 0;
1380 int CD;
1381 unsigned long flags;
1383 func_enter();
1386 * If the device is in the middle of being closed, then block
1387 * until it's done, and then try again.
1389 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
1390 interruptible_sleep_on(&port->close_wait);
1391 if (port->flags & ASYNC_HUP_NOTIFY) {
1392 func_exit();
1393 return -EAGAIN;
1394 } else {
1395 func_exit();
1396 return -ERESTARTSYS;
1401 * If non-blocking mode is set, or the port is not enabled,
1402 * then make the check up front and then exit.
1404 if ((filp->f_flags & O_NONBLOCK) ||
1405 (tty->flags & (1 << TTY_IO_ERROR))) {
1406 port->flags |= ASYNC_NORMAL_ACTIVE;
1407 func_exit();
1408 return 0;
1411 if (C_CLOCAL(tty))
1412 do_clocal = 1;
1415 * Block waiting for the carrier detect and the line to become
1416 * free (i.e., not in use by the callout). While we are in
1417 * this loop, info->count is dropped by one, so that
1418 * rs_close() knows when to free things. We restore it upon
1419 * exit, either normal or abnormal.
1421 retval = 0;
1422 add_wait_queue(&port->open_wait, &wait);
1423 spin_lock_irqsave(&port->lock, flags);
1424 if (!tty_hung_up_p(filp)) {
1425 port->count--;
1427 spin_unlock_irqrestore(&port->lock, flags);
1428 port->blocked_open++;
1429 while (1) {
1430 spin_lock_irqsave(&bp->lock, flags);
1431 sx_out(bp, CD186x_CAR, port_No(port));
1432 CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1433 if (SX_CRTSCTS (tty)) {
1434 /* Activate RTS */
1435 port->MSVR |= MSVR_DTR; /* WTF? */
1436 sx_out (bp, CD186x_MSVR, port->MSVR);
1437 } else {
1438 /* Activate DTR */
1439 port->MSVR |= MSVR_DTR;
1440 sx_out (bp, CD186x_MSVR, port->MSVR);
1442 spin_unlock_irqrestore(&bp->lock, flags);
1443 set_current_state(TASK_INTERRUPTIBLE);
1444 if (tty_hung_up_p(filp) ||
1445 !(port->flags & ASYNC_INITIALIZED)) {
1446 if (port->flags & ASYNC_HUP_NOTIFY)
1447 retval = -EAGAIN;
1448 else
1449 retval = -ERESTARTSYS;
1450 break;
1452 if (!(port->flags & ASYNC_CLOSING) &&
1453 (do_clocal || CD))
1454 break;
1455 if (signal_pending(current)) {
1456 retval = -ERESTARTSYS;
1457 break;
1459 schedule();
1462 set_current_state(TASK_RUNNING);
1463 remove_wait_queue(&port->open_wait, &wait);
1464 spin_lock_irqsave(&port->lock, flags);
1465 if (!tty_hung_up_p(filp)) {
1466 port->count++;
1468 port->blocked_open--;
1469 spin_unlock_irqrestore(&port->lock, flags);
1470 if (retval) {
1471 func_exit();
1472 return retval;
1475 port->flags |= ASYNC_NORMAL_ACTIVE;
1476 func_exit();
1477 return 0;
1481 static int sx_open(struct tty_struct * tty, struct file * filp)
1483 int board;
1484 int error;
1485 struct specialix_port * port;
1486 struct specialix_board * bp;
1487 int i;
1488 unsigned long flags;
1490 func_enter();
1492 board = SX_BOARD(tty->index);
1494 if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1495 func_exit();
1496 return -ENODEV;
1499 bp = &sx_board[board];
1500 port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1501 port->overrun = 0;
1502 for (i = 0; i < 10; i++)
1503 port->hits[i]=0;
1505 dprintk (SX_DEBUG_OPEN, "Board = %d, bp = %p, port = %p, portno = %d.\n",
1506 board, bp, port, SX_PORT(tty->index));
1508 if (sx_paranoia_check(port, tty->name, "sx_open")) {
1509 func_enter();
1510 return -ENODEV;
1513 if ((error = sx_setup_board(bp))) {
1514 func_exit();
1515 return error;
1518 spin_lock_irqsave(&bp->lock, flags);
1519 port->count++;
1520 bp->count++;
1521 tty->driver_data = port;
1522 port->tty = tty;
1523 spin_unlock_irqrestore(&bp->lock, flags);
1525 if ((error = sx_setup_port(bp, port))) {
1526 func_enter();
1527 return error;
1530 if ((error = block_til_ready(tty, filp, port))) {
1531 func_enter();
1532 return error;
1535 func_exit();
1536 return 0;
1540 static void sx_close(struct tty_struct * tty, struct file * filp)
1542 struct specialix_port *port = (struct specialix_port *) tty->driver_data;
1543 struct specialix_board *bp;
1544 unsigned long flags;
1545 unsigned long timeout;
1547 func_enter();
1548 if (!port || sx_paranoia_check(port, tty->name, "close")) {
1549 func_exit();
1550 return;
1552 spin_lock_irqsave(&port->lock, flags);
1554 if (tty_hung_up_p(filp)) {
1555 spin_unlock_irqrestore(&port->lock, flags);
1556 func_exit();
1557 return;
1560 bp = port_Board(port);
1561 if ((tty->count == 1) && (port->count != 1)) {
1562 printk(KERN_ERR "sx%d: sx_close: bad port count;"
1563 " tty->count is 1, port count is %d\n",
1564 board_No(bp), port->count);
1565 port->count = 1;
1568 if (port->count > 1) {
1569 port->count--;
1570 bp->count--;
1572 spin_unlock_irqrestore(&port->lock, flags);
1574 func_exit();
1575 return;
1577 port->flags |= ASYNC_CLOSING;
1579 * Now we wait for the transmit buffer to clear; and we notify
1580 * the line discipline to only process XON/XOFF characters.
1582 tty->closing = 1;
1583 spin_unlock_irqrestore(&port->lock, flags);
1584 dprintk (SX_DEBUG_OPEN, "Closing\n");
1585 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
1586 tty_wait_until_sent(tty, port->closing_wait);
1589 * At this point we stop accepting input. To do this, we
1590 * disable the receive line status interrupts, and tell the
1591 * interrupt driver to stop checking the data ready bit in the
1592 * line status register.
1594 dprintk (SX_DEBUG_OPEN, "Closed\n");
1595 port->IER &= ~IER_RXD;
1596 if (port->flags & ASYNC_INITIALIZED) {
1597 port->IER &= ~IER_TXRDY;
1598 port->IER |= IER_TXEMPTY;
1599 spin_lock_irqsave(&bp->lock, flags);
1600 sx_out(bp, CD186x_CAR, port_No(port));
1601 sx_out(bp, CD186x_IER, port->IER);
1602 spin_unlock_irqrestore(&bp->lock, flags);
1604 * Before we drop DTR, make sure the UART transmitter
1605 * has completely drained; this is especially
1606 * important if there is a transmit FIFO!
1608 timeout = jiffies+HZ;
1609 while(port->IER & IER_TXEMPTY) {
1610 set_current_state (TASK_INTERRUPTIBLE);
1611 msleep_interruptible(jiffies_to_msecs(port->timeout));
1612 if (time_after(jiffies, timeout)) {
1613 printk (KERN_INFO "Timeout waiting for close\n");
1614 break;
1620 if (--bp->count < 0) {
1621 printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1622 board_No(bp), bp->count, tty->index);
1623 bp->count = 0;
1625 if (--port->count < 0) {
1626 printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n",
1627 board_No(bp), port_No(port), port->count);
1628 port->count = 0;
1631 sx_shutdown_port(bp, port);
1632 if (tty->driver->flush_buffer)
1633 tty->driver->flush_buffer(tty);
1634 tty_ldisc_flush(tty);
1635 spin_lock_irqsave(&port->lock, flags);
1636 tty->closing = 0;
1637 port->event = 0;
1638 port->tty = NULL;
1639 spin_unlock_irqrestore(&port->lock, flags);
1640 if (port->blocked_open) {
1641 if (port->close_delay) {
1642 msleep_interruptible(jiffies_to_msecs(port->close_delay));
1644 wake_up_interruptible(&port->open_wait);
1646 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1647 wake_up_interruptible(&port->close_wait);
1649 func_exit();
1653 static int sx_write(struct tty_struct * tty,
1654 const unsigned char *buf, int count)
1656 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1657 struct specialix_board *bp;
1658 int c, total = 0;
1659 unsigned long flags;
1661 func_enter();
1662 if (sx_paranoia_check(port, tty->name, "sx_write")) {
1663 func_exit();
1664 return 0;
1667 bp = port_Board(port);
1669 if (!port->xmit_buf) {
1670 func_exit();
1671 return 0;
1674 while (1) {
1675 spin_lock_irqsave(&port->lock, flags);
1676 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1677 SERIAL_XMIT_SIZE - port->xmit_head));
1678 if (c <= 0) {
1679 spin_unlock_irqrestore(&port->lock, flags);
1680 break;
1682 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1683 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1684 port->xmit_cnt += c;
1685 spin_unlock_irqrestore(&port->lock, flags);
1687 buf += c;
1688 count -= c;
1689 total += c;
1692 spin_lock_irqsave(&bp->lock, flags);
1693 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1694 !(port->IER & IER_TXRDY)) {
1695 port->IER |= IER_TXRDY;
1696 sx_out(bp, CD186x_CAR, port_No(port));
1697 sx_out(bp, CD186x_IER, port->IER);
1699 spin_unlock_irqrestore(&bp->lock, flags);
1700 func_exit();
1702 return total;
1706 static void sx_put_char(struct tty_struct * tty, unsigned char ch)
1708 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1709 unsigned long flags;
1710 struct specialix_board * bp;
1712 func_enter();
1714 if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1715 func_exit();
1716 return;
1718 dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1719 if (!port->xmit_buf) {
1720 func_exit();
1721 return;
1723 bp = port_Board(port);
1724 spin_lock_irqsave(&port->lock, flags);
1726 dprintk (SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", port->xmit_cnt, port->xmit_buf);
1727 if ((port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) || (!port->xmit_buf)) {
1728 spin_unlock_irqrestore(&port->lock, flags);
1729 dprintk (SX_DEBUG_TX, "Exit size\n");
1730 func_exit();
1731 return;
1733 dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
1734 port->xmit_buf[port->xmit_head++] = ch;
1735 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1736 port->xmit_cnt++;
1737 spin_unlock_irqrestore(&port->lock, flags);
1739 func_exit();
1743 static void sx_flush_chars(struct tty_struct * tty)
1745 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1746 unsigned long flags;
1747 struct specialix_board * bp = port_Board(port);
1749 func_enter();
1751 if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1752 func_exit();
1753 return;
1755 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1756 !port->xmit_buf) {
1757 func_exit();
1758 return;
1760 spin_lock_irqsave(&bp->lock, flags);
1761 port->IER |= IER_TXRDY;
1762 sx_out(port_Board(port), CD186x_CAR, port_No(port));
1763 sx_out(port_Board(port), CD186x_IER, port->IER);
1764 spin_unlock_irqrestore(&bp->lock, flags);
1766 func_exit();
1770 static int sx_write_room(struct tty_struct * tty)
1772 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1773 int ret;
1775 func_enter();
1777 if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1778 func_exit();
1779 return 0;
1782 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1783 if (ret < 0)
1784 ret = 0;
1786 func_exit();
1787 return ret;
1791 static int sx_chars_in_buffer(struct tty_struct *tty)
1793 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1795 func_enter();
1797 if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
1798 func_exit();
1799 return 0;
1801 func_exit();
1802 return port->xmit_cnt;
1806 static void sx_flush_buffer(struct tty_struct *tty)
1808 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1809 unsigned long flags;
1810 struct specialix_board * bp;
1812 func_enter();
1814 if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
1815 func_exit();
1816 return;
1819 bp = port_Board(port);
1820 spin_lock_irqsave(&port->lock, flags);
1821 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1822 spin_unlock_irqrestore(&port->lock, flags);
1823 tty_wakeup(tty);
1825 func_exit();
1829 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1831 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1832 struct specialix_board * bp;
1833 unsigned char status;
1834 unsigned int result;
1835 unsigned long flags;
1837 func_enter();
1839 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1840 func_exit();
1841 return -ENODEV;
1844 bp = port_Board(port);
1845 spin_lock_irqsave (&bp->lock, flags);
1846 sx_out(bp, CD186x_CAR, port_No(port));
1847 status = sx_in(bp, CD186x_MSVR);
1848 spin_unlock_irqrestore(&bp->lock, flags);
1849 dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1850 port_No(port), status, sx_in (bp, CD186x_CAR));
1851 dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1852 if (SX_CRTSCTS(port->tty)) {
1853 result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
1854 | ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1855 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1856 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1857 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1858 } else {
1859 result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
1860 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1861 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1862 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1863 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1866 func_exit();
1868 return result;
1872 static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1873 unsigned int set, unsigned int clear)
1875 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1876 unsigned long flags;
1877 struct specialix_board *bp;
1879 func_enter();
1881 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1882 func_exit();
1883 return -ENODEV;
1886 bp = port_Board(port);
1888 spin_lock_irqsave(&port->lock, flags);
1889 /* if (set & TIOCM_RTS)
1890 port->MSVR |= MSVR_RTS; */
1891 /* if (set & TIOCM_DTR)
1892 port->MSVR |= MSVR_DTR; */
1894 if (SX_CRTSCTS(port->tty)) {
1895 if (set & TIOCM_RTS)
1896 port->MSVR |= MSVR_DTR;
1897 } else {
1898 if (set & TIOCM_DTR)
1899 port->MSVR |= MSVR_DTR;
1902 /* if (clear & TIOCM_RTS)
1903 port->MSVR &= ~MSVR_RTS; */
1904 /* if (clear & TIOCM_DTR)
1905 port->MSVR &= ~MSVR_DTR; */
1906 if (SX_CRTSCTS(port->tty)) {
1907 if (clear & TIOCM_RTS)
1908 port->MSVR &= ~MSVR_DTR;
1909 } else {
1910 if (clear & TIOCM_DTR)
1911 port->MSVR &= ~MSVR_DTR;
1913 spin_lock_irqsave(&bp->lock, flags);
1914 sx_out(bp, CD186x_CAR, port_No(port));
1915 sx_out(bp, CD186x_MSVR, port->MSVR);
1916 spin_unlock_irqrestore(&bp->lock, flags);
1917 spin_unlock_irqrestore(&port->lock, flags);
1918 func_exit();
1919 return 0;
1923 static inline void sx_send_break(struct specialix_port * port, unsigned long length)
1925 struct specialix_board *bp = port_Board(port);
1926 unsigned long flags;
1928 func_enter();
1930 spin_lock_irqsave (&port->lock, flags);
1931 port->break_length = SPECIALIX_TPS / HZ * length;
1932 port->COR2 |= COR2_ETC;
1933 port->IER |= IER_TXRDY;
1934 spin_lock_irqsave(&bp->lock, flags);
1935 sx_out(bp, CD186x_CAR, port_No(port));
1936 sx_out(bp, CD186x_COR2, port->COR2);
1937 sx_out(bp, CD186x_IER, port->IER);
1938 spin_unlock_irqrestore(&bp->lock, flags);
1939 spin_unlock_irqrestore (&port->lock, flags);
1940 sx_wait_CCR(bp);
1941 spin_lock_irqsave(&bp->lock, flags);
1942 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1943 spin_unlock_irqrestore(&bp->lock, flags);
1944 sx_wait_CCR(bp);
1946 func_exit();
1950 static inline int sx_set_serial_info(struct specialix_port * port,
1951 struct serial_struct __user * newinfo)
1953 struct serial_struct tmp;
1954 struct specialix_board *bp = port_Board(port);
1955 int change_speed;
1957 func_enter();
1959 if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1960 func_exit();
1961 return -EFAULT;
1964 if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
1965 func_enter();
1966 return -EFAULT;
1969 #if 0
1970 if ((tmp.irq != bp->irq) ||
1971 (tmp.port != bp->base) ||
1972 (tmp.type != PORT_CIRRUS) ||
1973 (tmp.baud_base != (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) ||
1974 (tmp.custom_divisor != 0) ||
1975 (tmp.xmit_fifo_size != CD186x_NFIFO) ||
1976 (tmp.flags & ~SPECIALIX_LEGAL_FLAGS)) {
1977 func_exit();
1978 return -EINVAL;
1980 #endif
1982 change_speed = ((port->flags & ASYNC_SPD_MASK) !=
1983 (tmp.flags & ASYNC_SPD_MASK));
1984 change_speed |= (tmp.custom_divisor != port->custom_divisor);
1986 if (!capable(CAP_SYS_ADMIN)) {
1987 if ((tmp.close_delay != port->close_delay) ||
1988 (tmp.closing_wait != port->closing_wait) ||
1989 ((tmp.flags & ~ASYNC_USR_MASK) !=
1990 (port->flags & ~ASYNC_USR_MASK))) {
1991 func_exit();
1992 return -EPERM;
1994 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
1995 (tmp.flags & ASYNC_USR_MASK));
1996 port->custom_divisor = tmp.custom_divisor;
1997 } else {
1998 port->flags = ((port->flags & ~ASYNC_FLAGS) |
1999 (tmp.flags & ASYNC_FLAGS));
2000 port->close_delay = tmp.close_delay;
2001 port->closing_wait = tmp.closing_wait;
2002 port->custom_divisor = tmp.custom_divisor;
2004 if (change_speed) {
2005 sx_change_speed(bp, port);
2007 func_exit();
2008 return 0;
2012 static inline int sx_get_serial_info(struct specialix_port * port,
2013 struct serial_struct __user *retinfo)
2015 struct serial_struct tmp;
2016 struct specialix_board *bp = port_Board(port);
2018 func_enter();
2021 if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
2022 return -EFAULT;
2025 memset(&tmp, 0, sizeof(tmp));
2026 tmp.type = PORT_CIRRUS;
2027 tmp.line = port - sx_port;
2028 tmp.port = bp->base;
2029 tmp.irq = bp->irq;
2030 tmp.flags = port->flags;
2031 tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
2032 tmp.close_delay = port->close_delay * HZ/100;
2033 tmp.closing_wait = port->closing_wait * HZ/100;
2034 tmp.custom_divisor = port->custom_divisor;
2035 tmp.xmit_fifo_size = CD186x_NFIFO;
2036 if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
2037 func_exit();
2038 return -EFAULT;
2041 func_exit();
2042 return 0;
2046 static int sx_ioctl(struct tty_struct * tty, struct file * filp,
2047 unsigned int cmd, unsigned long arg)
2049 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2050 int retval;
2051 void __user *argp = (void __user *)arg;
2053 func_enter();
2055 if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
2056 func_exit();
2057 return -ENODEV;
2060 switch (cmd) {
2061 case TCSBRK: /* SVID version: non-zero arg --> no break */
2062 retval = tty_check_change(tty);
2063 if (retval) {
2064 func_exit();
2065 return retval;
2067 tty_wait_until_sent(tty, 0);
2068 if (!arg)
2069 sx_send_break(port, HZ/4); /* 1/4 second */
2070 return 0;
2071 case TCSBRKP: /* support for POSIX tcsendbreak() */
2072 retval = tty_check_change(tty);
2073 if (retval) {
2074 func_exit();
2075 return retval;
2077 tty_wait_until_sent(tty, 0);
2078 sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
2079 func_exit();
2080 return 0;
2081 case TIOCGSOFTCAR:
2082 if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) {
2083 func_exit();
2084 return -EFAULT;
2086 func_exit();
2087 return 0;
2088 case TIOCSSOFTCAR:
2089 if (get_user(arg, (unsigned long __user *) argp)) {
2090 func_exit();
2091 return -EFAULT;
2093 tty->termios->c_cflag =
2094 ((tty->termios->c_cflag & ~CLOCAL) |
2095 (arg ? CLOCAL : 0));
2096 func_exit();
2097 return 0;
2098 case TIOCGSERIAL:
2099 func_exit();
2100 return sx_get_serial_info(port, argp);
2101 case TIOCSSERIAL:
2102 func_exit();
2103 return sx_set_serial_info(port, argp);
2104 default:
2105 func_exit();
2106 return -ENOIOCTLCMD;
2108 func_exit();
2109 return 0;
2113 static void sx_throttle(struct tty_struct * tty)
2115 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2116 struct specialix_board *bp;
2117 unsigned long flags;
2119 func_enter();
2121 if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
2122 func_exit();
2123 return;
2126 bp = port_Board(port);
2128 /* Use DTR instead of RTS ! */
2129 if (SX_CRTSCTS (tty))
2130 port->MSVR &= ~MSVR_DTR;
2131 else {
2132 /* Auch!!! I think the system shouldn't call this then. */
2133 /* Or maybe we're supposed (allowed?) to do our side of hw
2134 handshake anyway, even when hardware handshake is off.
2135 When you see this in your logs, please report.... */
2136 printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
2137 port_No (port));
2139 spin_lock_irqsave(&bp->lock, flags);
2140 sx_out(bp, CD186x_CAR, port_No(port));
2141 spin_unlock_irqrestore(&bp->lock, flags);
2142 if (I_IXOFF(tty)) {
2143 spin_unlock_irqrestore(&bp->lock, flags);
2144 sx_wait_CCR(bp);
2145 spin_lock_irqsave(&bp->lock, flags);
2146 sx_out(bp, CD186x_CCR, CCR_SSCH2);
2147 spin_unlock_irqrestore(&bp->lock, flags);
2148 sx_wait_CCR(bp);
2150 spin_lock_irqsave(&bp->lock, flags);
2151 sx_out(bp, CD186x_MSVR, port->MSVR);
2152 spin_unlock_irqrestore(&bp->lock, flags);
2154 func_exit();
2158 static void sx_unthrottle(struct tty_struct * tty)
2160 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2161 struct specialix_board *bp;
2162 unsigned long flags;
2164 func_enter();
2166 if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
2167 func_exit();
2168 return;
2171 bp = port_Board(port);
2173 spin_lock_irqsave(&port->lock, flags);
2174 /* XXXX Use DTR INSTEAD???? */
2175 if (SX_CRTSCTS(tty)) {
2176 port->MSVR |= MSVR_DTR;
2177 } /* Else clause: see remark in "sx_throttle"... */
2178 spin_lock_irqsave(&bp->lock, flags);
2179 sx_out(bp, CD186x_CAR, port_No(port));
2180 spin_unlock_irqrestore(&bp->lock, flags);
2181 if (I_IXOFF(tty)) {
2182 spin_unlock_irqrestore(&port->lock, flags);
2183 sx_wait_CCR(bp);
2184 spin_lock_irqsave(&bp->lock, flags);
2185 sx_out(bp, CD186x_CCR, CCR_SSCH1);
2186 spin_unlock_irqrestore(&bp->lock, flags);
2187 sx_wait_CCR(bp);
2188 spin_lock_irqsave(&port->lock, flags);
2190 spin_lock_irqsave(&bp->lock, flags);
2191 sx_out(bp, CD186x_MSVR, port->MSVR);
2192 spin_unlock_irqrestore(&bp->lock, flags);
2193 spin_unlock_irqrestore(&port->lock, flags);
2195 func_exit();
2199 static void sx_stop(struct tty_struct * tty)
2201 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2202 struct specialix_board *bp;
2203 unsigned long flags;
2205 func_enter();
2207 if (sx_paranoia_check(port, tty->name, "sx_stop")) {
2208 func_exit();
2209 return;
2212 bp = port_Board(port);
2214 spin_lock_irqsave(&port->lock, flags);
2215 port->IER &= ~IER_TXRDY;
2216 spin_lock_irqsave(&bp->lock, flags);
2217 sx_out(bp, CD186x_CAR, port_No(port));
2218 sx_out(bp, CD186x_IER, port->IER);
2219 spin_unlock_irqrestore(&bp->lock, flags);
2220 spin_unlock_irqrestore(&port->lock, flags);
2222 func_exit();
2226 static void sx_start(struct tty_struct * tty)
2228 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2229 struct specialix_board *bp;
2230 unsigned long flags;
2232 func_enter();
2234 if (sx_paranoia_check(port, tty->name, "sx_start")) {
2235 func_exit();
2236 return;
2239 bp = port_Board(port);
2241 spin_lock_irqsave(&port->lock, flags);
2242 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2243 port->IER |= IER_TXRDY;
2244 spin_lock_irqsave(&bp->lock, flags);
2245 sx_out(bp, CD186x_CAR, port_No(port));
2246 sx_out(bp, CD186x_IER, port->IER);
2247 spin_unlock_irqrestore(&bp->lock, flags);
2249 spin_unlock_irqrestore(&port->lock, flags);
2251 func_exit();
2256 * This routine is called from the work-queue when the interrupt
2257 * routine has signalled that a hangup has occurred. The path of
2258 * hangup processing is:
2260 * serial interrupt routine -> (workqueue) ->
2261 * do_sx_hangup() -> tty->hangup() -> sx_hangup()
2264 static void do_sx_hangup(void *private_)
2266 struct specialix_port *port = (struct specialix_port *) private_;
2267 struct tty_struct *tty;
2269 func_enter();
2271 tty = port->tty;
2272 if (tty)
2273 tty_hangup(tty); /* FIXME: module removal race here */
2275 func_exit();
2279 static void sx_hangup(struct tty_struct * tty)
2281 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2282 struct specialix_board *bp;
2283 unsigned long flags;
2285 func_enter();
2287 if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2288 func_exit();
2289 return;
2292 bp = port_Board(port);
2294 sx_shutdown_port(bp, port);
2295 spin_lock_irqsave(&port->lock, flags);
2296 port->event = 0;
2297 bp->count -= port->count;
2298 if (bp->count < 0) {
2299 printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n",
2300 board_No(bp), bp->count, tty->index);
2301 bp->count = 0;
2303 port->count = 0;
2304 port->flags &= ~ASYNC_NORMAL_ACTIVE;
2305 port->tty = NULL;
2306 spin_unlock_irqrestore(&port->lock, flags);
2307 wake_up_interruptible(&port->open_wait);
2309 func_exit();
2313 static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios)
2315 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2316 unsigned long flags;
2317 struct specialix_board * bp;
2319 if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2320 return;
2322 if (tty->termios->c_cflag == old_termios->c_cflag &&
2323 tty->termios->c_iflag == old_termios->c_iflag)
2324 return;
2326 bp = port_Board(port);
2327 spin_lock_irqsave(&port->lock, flags);
2328 sx_change_speed(port_Board(port), port);
2329 spin_unlock_irqrestore(&port->lock, flags);
2331 if ((old_termios->c_cflag & CRTSCTS) &&
2332 !(tty->termios->c_cflag & CRTSCTS)) {
2333 tty->hw_stopped = 0;
2334 sx_start(tty);
2339 static void do_softint(void *private_)
2341 struct specialix_port *port = (struct specialix_port *) private_;
2342 struct tty_struct *tty;
2344 func_enter();
2346 if(!(tty = port->tty)) {
2347 func_exit();
2348 return;
2351 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
2352 tty_wakeup(tty);
2353 //wake_up_interruptible(&tty->write_wait);
2356 func_exit();
2359 static const struct tty_operations sx_ops = {
2360 .open = sx_open,
2361 .close = sx_close,
2362 .write = sx_write,
2363 .put_char = sx_put_char,
2364 .flush_chars = sx_flush_chars,
2365 .write_room = sx_write_room,
2366 .chars_in_buffer = sx_chars_in_buffer,
2367 .flush_buffer = sx_flush_buffer,
2368 .ioctl = sx_ioctl,
2369 .throttle = sx_throttle,
2370 .unthrottle = sx_unthrottle,
2371 .set_termios = sx_set_termios,
2372 .stop = sx_stop,
2373 .start = sx_start,
2374 .hangup = sx_hangup,
2375 .tiocmget = sx_tiocmget,
2376 .tiocmset = sx_tiocmset,
2379 static int sx_init_drivers(void)
2381 int error;
2382 int i;
2384 func_enter();
2386 specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT);
2387 if (!specialix_driver) {
2388 printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n");
2389 func_exit();
2390 return 1;
2393 specialix_driver->owner = THIS_MODULE;
2394 specialix_driver->name = "ttyW";
2395 specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
2396 specialix_driver->type = TTY_DRIVER_TYPE_SERIAL;
2397 specialix_driver->subtype = SERIAL_TYPE_NORMAL;
2398 specialix_driver->init_termios = tty_std_termios;
2399 specialix_driver->init_termios.c_cflag =
2400 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2401 specialix_driver->flags = TTY_DRIVER_REAL_RAW;
2402 tty_set_operations(specialix_driver, &sx_ops);
2404 if ((error = tty_register_driver(specialix_driver))) {
2405 put_tty_driver(specialix_driver);
2406 printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2407 error);
2408 func_exit();
2409 return 1;
2411 memset(sx_port, 0, sizeof(sx_port));
2412 for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2413 sx_port[i].magic = SPECIALIX_MAGIC;
2414 INIT_WORK(&sx_port[i].tqueue, do_softint, &sx_port[i]);
2415 INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup, &sx_port[i]);
2416 sx_port[i].close_delay = 50 * HZ/100;
2417 sx_port[i].closing_wait = 3000 * HZ/100;
2418 init_waitqueue_head(&sx_port[i].open_wait);
2419 init_waitqueue_head(&sx_port[i].close_wait);
2420 spin_lock_init(&sx_port[i].lock);
2423 func_exit();
2424 return 0;
2427 static void sx_release_drivers(void)
2429 func_enter();
2431 tty_unregister_driver(specialix_driver);
2432 put_tty_driver(specialix_driver);
2433 func_exit();
2437 * This routine must be called by kernel at boot time
2439 static int __init specialix_init(void)
2441 int i;
2442 int found = 0;
2444 func_enter();
2446 printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
2447 printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2448 #ifdef CONFIG_SPECIALIX_RTSCTS
2449 printk (KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
2450 #else
2451 printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2452 #endif
2454 for (i = 0; i < SX_NBOARD; i++)
2455 spin_lock_init(&sx_board[i].lock);
2457 if (sx_init_drivers()) {
2458 func_exit();
2459 return -EIO;
2462 for (i = 0; i < SX_NBOARD; i++)
2463 if (sx_board[i].base && !sx_probe(&sx_board[i]))
2464 found++;
2466 #ifdef CONFIG_PCI
2468 struct pci_dev *pdev = NULL;
2470 i=0;
2471 while (i < SX_NBOARD) {
2472 if (sx_board[i].flags & SX_BOARD_PRESENT) {
2473 i++;
2474 continue;
2476 pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
2477 PCI_DEVICE_ID_SPECIALIX_IO8,
2478 pdev);
2479 if (!pdev) break;
2481 if (pci_enable_device(pdev))
2482 continue;
2484 sx_board[i].irq = pdev->irq;
2486 sx_board[i].base = pci_resource_start (pdev, 2);
2488 sx_board[i].flags |= SX_BOARD_IS_PCI;
2489 if (!sx_probe(&sx_board[i]))
2490 found ++;
2493 #endif
2495 if (!found) {
2496 sx_release_drivers();
2497 printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
2498 func_exit();
2499 return -EIO;
2502 func_exit();
2503 return 0;
2506 static int iobase[SX_NBOARD] = {0,};
2508 static int irq [SX_NBOARD] = {0,};
2510 module_param_array(iobase, int, NULL, 0);
2511 module_param_array(irq, int, NULL, 0);
2512 module_param(sx_debug, int, 0);
2513 module_param(sx_rxfifo, int, 0);
2514 #ifdef SPECIALIX_TIMER
2515 module_param(sx_poll, int, 0);
2516 #endif
2519 * You can setup up to 4 boards.
2520 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2521 * You should specify the IRQs too in that case "irq=....,...".
2523 * More than 4 boards in one computer is not possible, as the card can
2524 * only use 4 different interrupts.
2527 static int __init specialix_init_module(void)
2529 int i;
2531 func_enter();
2533 if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2534 for(i = 0; i < SX_NBOARD; i++) {
2535 sx_board[i].base = iobase[i];
2536 sx_board[i].irq = irq[i];
2537 sx_board[i].count= 0;
2541 func_exit();
2543 return specialix_init();
2546 static void __exit specialix_exit_module(void)
2548 int i;
2550 func_enter();
2552 sx_release_drivers();
2553 for (i = 0; i < SX_NBOARD; i++)
2554 if (sx_board[i].flags & SX_BOARD_PRESENT)
2555 sx_release_io_range(&sx_board[i]);
2556 #ifdef SPECIALIX_TIMER
2557 del_timer (&missed_irq_timer);
2558 #endif
2560 func_exit();
2563 static struct pci_device_id specialx_pci_tbl[] __devinitdata = {
2564 { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) },
2567 MODULE_DEVICE_TABLE(pci, specialx_pci_tbl);
2569 module_init(specialix_init_module);
2570 module_exit(specialix_exit_module);
2572 MODULE_LICENSE("GPL");