[PATCH] aic7xxx_osm build fix
[cris-mirror.git] / drivers / char / specialix.c
blob50e0b612a8a2980242b648c06a908d1f6a687a00
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/config.h>
79 #include <linux/module.h>
81 #include <asm/io.h>
82 #include <linux/kernel.h>
83 #include <linux/sched.h>
84 #include <linux/ioport.h>
85 #include <linux/interrupt.h>
86 #include <linux/errno.h>
87 #include <linux/tty.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/version.h>
94 #include <linux/pci.h>
95 #include <linux/init.h>
96 #include <asm/uaccess.h>
98 #include "specialix_io8.h"
99 #include "cd1865.h"
103 This driver can spew a whole lot of debugging output at you. If you
104 need maximum performance, you should disable the DEBUG define. To
105 aid in debugging in the field, I'm leaving the compile-time debug
106 features enabled, and disable them "runtime". That allows me to
107 instruct people with problems to enable debugging without requiring
108 them to recompile...
110 #define DEBUG
112 static int sx_debug;
113 static int sx_rxfifo = SPECIALIX_RXFIFO;
115 #ifdef DEBUG
116 #define dprintk(f, str...) if (sx_debug & f) printk (str)
117 #else
118 #define dprintk(f, str...) /* nothing */
119 #endif
121 #define SX_DEBUG_FLOW 0x0001
122 #define SX_DEBUG_DATA 0x0002
123 #define SX_DEBUG_PROBE 0x0004
124 #define SX_DEBUG_CHAN 0x0008
125 #define SX_DEBUG_INIT 0x0010
126 #define SX_DEBUG_RX 0x0020
127 #define SX_DEBUG_TX 0x0040
128 #define SX_DEBUG_IRQ 0x0080
129 #define SX_DEBUG_OPEN 0x0100
130 #define SX_DEBUG_TERMIOS 0x0200
131 #define SX_DEBUG_SIGNALS 0x0400
132 #define SX_DEBUG_FIFO 0x0800
135 #define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__FUNCTION__)
136 #define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __FUNCTION__)
138 #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
141 /* Configurable options: */
143 /* Am I paranoid or not ? ;-) */
144 #define SPECIALIX_PARANOIA_CHECK
146 /* Do I trust the IRQ from the card? (enabeling it doesn't seem to help)
147 When the IRQ routine leaves the chip in a state that is keeps on
148 requiring attention, the timer doesn't help either. */
149 #undef SPECIALIX_TIMER
151 #ifdef SPECIALIX_TIMER
152 static int sx_poll = HZ;
153 #endif
158 * The following defines are mostly for testing purposes. But if you need
159 * some nice reporting in your syslog, you can define them also.
161 #undef SX_REPORT_FIFO
162 #undef SX_REPORT_OVERRUN
166 #ifdef CONFIG_SPECIALIX_RTSCTS
167 #define SX_CRTSCTS(bla) 1
168 #else
169 #define SX_CRTSCTS(tty) C_CRTSCTS(tty)
170 #endif
173 /* Used to be outb (0xff, 0x80); */
174 #define short_pause() udelay (1)
177 #define SPECIALIX_LEGAL_FLAGS \
178 (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \
179 ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \
180 ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
182 #undef RS_EVENT_WRITE_WAKEUP
183 #define RS_EVENT_WRITE_WAKEUP 0
185 static struct tty_driver *specialix_driver;
186 static unsigned char * tmp_buf;
187 static DECLARE_MUTEX(tmp_buf_sem);
189 static unsigned long baud_table[] = {
190 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
191 9600, 19200, 38400, 57600, 115200, 0,
194 static struct specialix_board sx_board[SX_NBOARD] = {
195 { 0, SX_IOBASE1, 9, },
196 { 0, SX_IOBASE2, 11, },
197 { 0, SX_IOBASE3, 12, },
198 { 0, SX_IOBASE4, 15, },
201 static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
204 #ifdef SPECIALIX_TIMER
205 static struct timer_list missed_irq_timer;
206 static irqreturn_t sx_interrupt(int irq, void * dev_id, struct pt_regs * regs);
207 #endif
211 static inline int sx_paranoia_check(struct specialix_port const * port,
212 char *name, const char *routine)
214 #ifdef SPECIALIX_PARANOIA_CHECK
215 static const char *badmagic =
216 KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
217 static const char *badinfo =
218 KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
220 if (!port) {
221 printk(badinfo, name, routine);
222 return 1;
224 if (port->magic != SPECIALIX_MAGIC) {
225 printk(badmagic, name, routine);
226 return 1;
228 #endif
229 return 0;
235 * Service functions for specialix IO8+ driver.
239 /* Get board number from pointer */
240 static inline int board_No (struct specialix_board * bp)
242 return bp - sx_board;
246 /* Get port number from pointer */
247 static inline int port_No (struct specialix_port const * port)
249 return SX_PORT(port - sx_port);
253 /* Get pointer to board from pointer to port */
254 static inline struct specialix_board * port_Board(struct specialix_port const * port)
256 return &sx_board[SX_BOARD(port - sx_port)];
260 /* Input Byte from CL CD186x register */
261 static inline unsigned char sx_in(struct specialix_board * bp, unsigned short reg)
263 bp->reg = reg | 0x80;
264 outb (reg | 0x80, bp->base + SX_ADDR_REG);
265 return inb (bp->base + SX_DATA_REG);
269 /* Output Byte to CL CD186x register */
270 static inline void sx_out(struct specialix_board * bp, unsigned short reg,
271 unsigned char val)
273 bp->reg = reg | 0x80;
274 outb (reg | 0x80, bp->base + SX_ADDR_REG);
275 outb (val, bp->base + SX_DATA_REG);
279 /* Input Byte from CL CD186x register */
280 static inline unsigned char sx_in_off(struct specialix_board * bp, unsigned short reg)
282 bp->reg = reg;
283 outb (reg, bp->base + SX_ADDR_REG);
284 return inb (bp->base + SX_DATA_REG);
288 /* Output Byte to CL CD186x register */
289 static inline void sx_out_off(struct specialix_board * bp, unsigned short reg,
290 unsigned char val)
292 bp->reg = reg;
293 outb (reg, bp->base + SX_ADDR_REG);
294 outb (val, bp->base + SX_DATA_REG);
298 /* Wait for Channel Command Register ready */
299 static inline void sx_wait_CCR(struct specialix_board * bp)
301 unsigned long delay, flags;
302 unsigned char ccr;
304 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
305 spin_lock_irqsave(&bp->lock, flags);
306 ccr = sx_in(bp, CD186x_CCR);
307 spin_unlock_irqrestore(&bp->lock, flags);
308 if (!ccr)
309 return;
310 udelay (1);
313 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
317 /* Wait for Channel Command Register ready */
318 static inline void sx_wait_CCR_off(struct specialix_board * bp)
320 unsigned long delay;
321 unsigned char crr;
322 unsigned long flags;
324 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
325 spin_lock_irqsave(&bp->lock, flags);
326 crr = sx_in_off(bp, CD186x_CCR);
327 spin_unlock_irqrestore(&bp->lock, flags);
328 if (!crr)
329 return;
330 udelay (1);
333 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
338 * specialix IO8+ IO range functions.
341 static inline int sx_check_io_range(struct specialix_board * bp)
343 return check_region (bp->base, SX_IO_SPACE);
347 static inline void sx_request_io_range(struct specialix_board * bp)
349 request_region(bp->base,
350 bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE,
351 "specialix IO8+" );
355 static inline void sx_release_io_range(struct specialix_board * bp)
357 release_region(bp->base,
358 bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
362 /* Must be called with enabled interrupts */
363 /* Ugly. Very ugly. Don't use this for anything else than initialization
364 code */
365 static inline void sx_long_delay(unsigned long delay)
367 unsigned long i;
369 for (i = jiffies + delay; time_after(i, jiffies); ) ;
374 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
375 static int sx_set_irq ( struct specialix_board *bp)
377 int virq;
378 int i;
379 unsigned long flags;
381 if (bp->flags & SX_BOARD_IS_PCI)
382 return 1;
383 switch (bp->irq) {
384 /* In the same order as in the docs... */
385 case 15: virq = 0;break;
386 case 12: virq = 1;break;
387 case 11: virq = 2;break;
388 case 9: virq = 3;break;
389 default: printk (KERN_ERR "Speclialix: cannot set irq to %d.\n", bp->irq);
390 return 0;
392 spin_lock_irqsave(&bp->lock, flags);
393 for (i=0;i<2;i++) {
394 sx_out(bp, CD186x_CAR, i);
395 sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
397 spin_unlock_irqrestore(&bp->lock, flags);
398 return 1;
402 /* Reset and setup CD186x chip */
403 static int sx_init_CD186x(struct specialix_board * bp)
405 unsigned long flags;
406 int scaler;
407 int rv = 1;
409 func_enter();
410 sx_wait_CCR_off(bp); /* Wait for CCR ready */
411 spin_lock_irqsave(&bp->lock, flags);
412 sx_out_off(bp, CD186x_CCR, CCR_HARDRESET); /* Reset CD186x chip */
413 spin_unlock_irqrestore(&bp->lock, flags);
414 sx_long_delay(HZ/20); /* Delay 0.05 sec */
415 spin_lock_irqsave(&bp->lock, flags);
416 sx_out_off(bp, CD186x_GIVR, SX_ID); /* Set ID for this chip */
417 sx_out_off(bp, CD186x_GICR, 0); /* Clear all bits */
418 sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT); /* Prio for modem intr */
419 sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */
420 sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
421 /* Set RegAckEn */
422 sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
424 /* Setting up prescaler. We need 4 ticks per 1 ms */
425 scaler = SX_OSCFREQ/SPECIALIX_TPS;
427 sx_out_off(bp, CD186x_PPRH, scaler >> 8);
428 sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
429 spin_unlock_irqrestore(&bp->lock, flags);
431 if (!sx_set_irq (bp)) {
432 /* Figure out how to pass this along... */
433 printk (KERN_ERR "Cannot set irq to %d.\n", bp->irq);
434 rv = 0;
437 func_exit();
438 return rv;
442 static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
444 int i;
445 int t;
446 unsigned long flags;
448 spin_lock_irqsave(&bp->lock, flags);
449 for (i=0, t=0;i<8;i++) {
450 sx_out_off (bp, CD186x_CAR, i);
451 if (sx_in_off (bp, reg) & bit)
452 t |= 1 << i;
454 spin_unlock_irqrestore(&bp->lock, flags);
456 return t;
460 #ifdef SPECIALIX_TIMER
461 void missed_irq (unsigned long data)
463 unsigned char irq;
464 unsigned long flags;
465 struct specialix_board *bp = (struct specialix_board *)data;
467 spin_lock_irqsave(&bp->lock, flags);
468 irq = sx_in ((struct specialix_board *)data, CD186x_SRSR) &
469 (SRSR_RREQint |
470 SRSR_TREQint |
471 SRSR_MREQint);
472 spin_unlock_irqrestore(&bp->lock, flags);
473 if (irq) {
474 printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
475 sx_interrupt (((struct specialix_board *)data)->irq,
476 (void*)data, NULL);
478 missed_irq_timer.expires = jiffies + sx_poll;
479 add_timer (&missed_irq_timer);
481 #endif
485 /* Main probing routine, also sets irq. */
486 static int sx_probe(struct specialix_board *bp)
488 unsigned char val1, val2;
489 #if 0
490 int irqs = 0;
491 int retries;
492 #endif
493 int rev;
494 int chip;
496 func_enter();
498 if (sx_check_io_range(bp)) {
499 func_exit();
500 return 1;
503 /* Are the I/O ports here ? */
504 sx_out_off(bp, CD186x_PPRL, 0x5a);
505 short_pause ();
506 val1 = sx_in_off(bp, CD186x_PPRL);
508 sx_out_off(bp, CD186x_PPRL, 0xa5);
509 short_pause ();
510 val2 = sx_in_off(bp, CD186x_PPRL);
513 if ((val1 != 0x5a) || (val2 != 0xa5)) {
514 printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
515 board_No(bp), bp->base);
516 func_exit();
517 return 1;
520 /* Check the DSR lines that Specialix uses as board
521 identification */
522 val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
523 val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
524 dprintk (SX_DEBUG_INIT, "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
525 board_No(bp), val1, val2);
527 /* They managed to switch the bit order between the docs and
528 the IO8+ card. The new PCI card now conforms to old docs.
529 They changed the PCI docs to reflect the situation on the
530 old card. */
531 val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
532 if (val1 != val2) {
533 printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
534 board_No(bp), val2, bp->base, val1);
535 func_exit();
536 return 1;
540 #if 0
541 /* It's time to find IRQ for this board */
542 for (retries = 0; retries < 5 && irqs <= 0; retries++) {
543 irqs = probe_irq_on();
544 sx_init_CD186x(bp); /* Reset CD186x chip */
545 sx_out(bp, CD186x_CAR, 2); /* Select port 2 */
546 sx_wait_CCR(bp);
547 sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */
548 sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */
549 sx_long_delay(HZ/20);
550 irqs = probe_irq_off(irqs);
552 dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
553 dprintk (SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR));
554 dprintk (SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR));
555 dprintk (SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR));
556 dprintk (SX_DEBUG_INIT, "\n");
558 /* Reset CD186x again */
559 if (!sx_init_CD186x(bp)) {
560 /* Hmmm. This is dead code anyway. */
563 dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
564 val1, val2, val3);
568 #if 0
569 if (irqs <= 0) {
570 printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
571 board_No(bp), bp->base);
572 func_exit();
573 return 1;
575 #endif
576 printk (KERN_INFO "Started with irq=%d, but now have irq=%d.\n", bp->irq, irqs);
577 if (irqs > 0)
578 bp->irq = irqs;
579 #endif
580 /* Reset CD186x again */
581 if (!sx_init_CD186x(bp)) {
582 func_exit();
583 return -EIO;
586 sx_request_io_range(bp);
587 bp->flags |= SX_BOARD_PRESENT;
589 /* Chip revcode pkgtype
590 GFRCR SRCR bit 7
591 CD180 rev B 0x81 0
592 CD180 rev C 0x82 0
593 CD1864 rev A 0x82 1
594 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
595 CD1865 rev B 0x84 1
596 -- Thanks to Gwen Wang, Cirrus Logic.
599 switch (sx_in_off(bp, CD186x_GFRCR)) {
600 case 0x82:chip = 1864;rev='A';break;
601 case 0x83:chip = 1865;rev='A';break;
602 case 0x84:chip = 1865;rev='B';break;
603 case 0x85:chip = 1865;rev='C';break; /* Does not exist at this time */
604 default:chip=-1;rev='x';
607 dprintk (SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR) );
609 #ifdef SPECIALIX_TIMER
610 init_timer (&missed_irq_timer);
611 missed_irq_timer.function = missed_irq;
612 missed_irq_timer.data = (unsigned long) bp;
613 missed_irq_timer.expires = jiffies + sx_poll;
614 add_timer (&missed_irq_timer);
615 #endif
617 printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
618 board_No(bp),
619 bp->base, bp->irq,
620 chip, rev);
622 func_exit();
623 return 0;
628 * Interrupt processing routines.
629 * */
631 static inline void sx_mark_event(struct specialix_port * port, int event)
633 func_enter();
635 set_bit(event, &port->event);
636 schedule_work(&port->tqueue);
638 func_exit();
642 static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
643 unsigned char const * what)
645 unsigned char channel;
646 struct specialix_port * port = NULL;
648 channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
649 dprintk (SX_DEBUG_CHAN, "channel: %d\n", channel);
650 if (channel < CD186x_NCH) {
651 port = &sx_port[board_No(bp) * SX_NPORT + channel];
652 dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%x\n",board_No(bp) * SX_NPORT + channel, port, port->flags & ASYNC_INITIALIZED);
654 if (port->flags & ASYNC_INITIALIZED) {
655 dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
656 func_exit();
657 return port;
660 printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
661 board_No(bp), what, channel);
662 return NULL;
666 static inline void sx_receive_exc(struct specialix_board * bp)
668 struct specialix_port *port;
669 struct tty_struct *tty;
670 unsigned char status;
671 unsigned char ch;
673 func_enter();
675 port = sx_get_port(bp, "Receive");
676 if (!port) {
677 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
678 func_exit();
679 return;
681 tty = port->tty;
682 dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n",
683 port, tty->flip.count, TTY_FLIPBUF_SIZE);
685 status = sx_in(bp, CD186x_RCSR);
687 dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
688 if (status & RCSR_OE) {
689 port->overrun++;
690 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Overrun. Total %ld overruns.\n",
691 board_No(bp), port_No(port), port->overrun);
693 status &= port->mark_mask;
695 /* This flip buffer check needs to be below the reading of the
696 status register to reset the chip's IRQ.... */
697 if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
698 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n",
699 board_No(bp), port_No(port));
700 func_exit();
701 return;
704 ch = sx_in(bp, CD186x_RDR);
705 if (!status) {
706 func_exit();
707 return;
709 if (status & RCSR_TOUT) {
710 printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
711 board_No(bp), port_No(port));
712 func_exit();
713 return;
715 } else if (status & RCSR_BREAK) {
716 dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
717 board_No(bp), port_No(port));
718 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
719 if (port->flags & ASYNC_SAK)
720 do_SAK(tty);
722 } else if (status & RCSR_PE)
723 *tty->flip.flag_buf_ptr++ = TTY_PARITY;
725 else if (status & RCSR_FE)
726 *tty->flip.flag_buf_ptr++ = TTY_FRAME;
728 else if (status & RCSR_OE)
729 *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
731 else
732 *tty->flip.flag_buf_ptr++ = 0;
734 *tty->flip.char_buf_ptr++ = ch;
735 tty->flip.count++;
736 schedule_delayed_work(&tty->flip.work, 1);
738 func_exit();
742 static inline void sx_receive(struct specialix_board * bp)
744 struct specialix_port *port;
745 struct tty_struct *tty;
746 unsigned char count;
748 func_enter();
750 if (!(port = sx_get_port(bp, "Receive"))) {
751 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
752 func_exit();
753 return;
755 tty = port->tty;
757 count = sx_in(bp, CD186x_RDCR);
758 dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
759 port->hits[count > 8 ? 9 : count]++;
761 while (count--) {
762 if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
763 printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n",
764 board_No(bp), port_No(port));
765 break;
767 *tty->flip.char_buf_ptr++ = sx_in(bp, CD186x_RDR);
768 *tty->flip.flag_buf_ptr++ = 0;
769 tty->flip.count++;
771 schedule_delayed_work(&tty->flip.work, 1);
773 func_exit();
777 static inline void sx_transmit(struct specialix_board * bp)
779 struct specialix_port *port;
780 struct tty_struct *tty;
781 unsigned char count;
783 func_enter();
784 if (!(port = sx_get_port(bp, "Transmit"))) {
785 func_exit();
786 return;
788 dprintk (SX_DEBUG_TX, "port: %p\n", port);
789 tty = port->tty;
791 if (port->IER & IER_TXEMPTY) {
792 /* FIFO drained */
793 sx_out(bp, CD186x_CAR, port_No(port));
794 port->IER &= ~IER_TXEMPTY;
795 sx_out(bp, CD186x_IER, port->IER);
796 func_exit();
797 return;
800 if ((port->xmit_cnt <= 0 && !port->break_length)
801 || tty->stopped || tty->hw_stopped) {
802 sx_out(bp, CD186x_CAR, port_No(port));
803 port->IER &= ~IER_TXRDY;
804 sx_out(bp, CD186x_IER, port->IER);
805 func_exit();
806 return;
809 if (port->break_length) {
810 if (port->break_length > 0) {
811 if (port->COR2 & COR2_ETC) {
812 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
813 sx_out(bp, CD186x_TDR, CD186x_C_SBRK);
814 port->COR2 &= ~COR2_ETC;
816 count = min_t(int, port->break_length, 0xff);
817 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
818 sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
819 sx_out(bp, CD186x_TDR, count);
820 if (!(port->break_length -= count))
821 port->break_length--;
822 } else {
823 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
824 sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
825 sx_out(bp, CD186x_COR2, port->COR2);
826 sx_wait_CCR(bp);
827 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
828 port->break_length = 0;
831 func_exit();
832 return;
835 count = CD186x_NFIFO;
836 do {
837 sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
838 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
839 if (--port->xmit_cnt <= 0)
840 break;
841 } while (--count > 0);
843 if (port->xmit_cnt <= 0) {
844 sx_out(bp, CD186x_CAR, port_No(port));
845 port->IER &= ~IER_TXRDY;
846 sx_out(bp, CD186x_IER, port->IER);
848 if (port->xmit_cnt <= port->wakeup_chars)
849 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
851 func_exit();
855 static inline void sx_check_modem(struct specialix_board * bp)
857 struct specialix_port *port;
858 struct tty_struct *tty;
859 unsigned char mcr;
860 int msvr_cd;
862 dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
863 if (!(port = sx_get_port(bp, "Modem")))
864 return;
866 tty = port->tty;
868 mcr = sx_in(bp, CD186x_MCR);
869 printk ("mcr = %02x.\n", mcr);
871 if ((mcr & MCR_CDCHG)) {
872 dprintk (SX_DEBUG_SIGNALS, "CD just changed... ");
873 msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
874 if (msvr_cd) {
875 dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
876 wake_up_interruptible(&port->open_wait);
877 } else {
878 dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n");
879 schedule_work(&port->tqueue_hangup);
883 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
884 if (mcr & MCR_CTSCHG) {
885 if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
886 tty->hw_stopped = 0;
887 port->IER |= IER_TXRDY;
888 if (port->xmit_cnt <= port->wakeup_chars)
889 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
890 } else {
891 tty->hw_stopped = 1;
892 port->IER &= ~IER_TXRDY;
894 sx_out(bp, CD186x_IER, port->IER);
896 if (mcr & MCR_DSSXHG) {
897 if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
898 tty->hw_stopped = 0;
899 port->IER |= IER_TXRDY;
900 if (port->xmit_cnt <= port->wakeup_chars)
901 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
902 } else {
903 tty->hw_stopped = 1;
904 port->IER &= ~IER_TXRDY;
906 sx_out(bp, CD186x_IER, port->IER);
908 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
910 /* Clear change bits */
911 sx_out(bp, CD186x_MCR, 0);
915 /* The main interrupt processing routine */
916 static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
918 unsigned char status;
919 unsigned char ack;
920 struct specialix_board *bp;
921 unsigned long loop = 0;
922 int saved_reg;
923 unsigned long flags;
925 func_enter();
927 bp = dev_id;
928 spin_lock_irqsave(&bp->lock, flags);
930 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);
931 if (!bp || !(bp->flags & SX_BOARD_ACTIVE)) {
932 dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq);
933 spin_unlock_irqrestore(&bp->lock, flags);
934 func_exit();
935 return IRQ_NONE;
938 saved_reg = bp->reg;
940 while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
941 (SRSR_RREQint |
942 SRSR_TREQint |
943 SRSR_MREQint)))) {
944 if (status & SRSR_RREQint) {
945 ack = sx_in(bp, CD186x_RRAR);
947 if (ack == (SX_ID | GIVR_IT_RCV))
948 sx_receive(bp);
949 else if (ack == (SX_ID | GIVR_IT_REXC))
950 sx_receive_exc(bp);
951 else
952 printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
953 board_No(bp), status, ack);
955 } else if (status & SRSR_TREQint) {
956 ack = sx_in(bp, CD186x_TRAR);
958 if (ack == (SX_ID | GIVR_IT_TX))
959 sx_transmit(bp);
960 else
961 printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
962 board_No(bp), status, ack, port_No (sx_get_port (bp, "Int")));
963 } else if (status & SRSR_MREQint) {
964 ack = sx_in(bp, CD186x_MRAR);
966 if (ack == (SX_ID | GIVR_IT_MODEM))
967 sx_check_modem(bp);
968 else
969 printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
970 board_No(bp), status, ack);
974 sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
976 bp->reg = saved_reg;
977 outb (bp->reg, bp->base + SX_ADDR_REG);
978 spin_unlock_irqrestore(&bp->lock, flags);
979 func_exit();
980 return IRQ_HANDLED;
985 * Routines for open & close processing.
988 static void turn_ints_off (struct specialix_board *bp)
990 unsigned long flags;
992 func_enter();
993 if (bp->flags & SX_BOARD_IS_PCI) {
994 /* This was intended for enabeling the interrupt on the
995 * PCI card. However it seems that it's already enabled
996 * and as PCI interrupts can be shared, there is no real
997 * reason to have to turn it off. */
1000 spin_lock_irqsave(&bp->lock, flags);
1001 (void) sx_in_off (bp, 0); /* Turn off interrupts. */
1002 spin_unlock_irqrestore(&bp->lock, flags);
1004 func_exit();
1007 static void turn_ints_on (struct specialix_board *bp)
1009 unsigned long flags;
1011 func_enter();
1013 if (bp->flags & SX_BOARD_IS_PCI) {
1014 /* play with the PCI chip. See comment above. */
1016 spin_lock_irqsave(&bp->lock, flags);
1017 (void) sx_in (bp, 0); /* Turn ON interrupts. */
1018 spin_unlock_irqrestore(&bp->lock, flags);
1020 func_exit();
1024 /* Called with disabled interrupts */
1025 static inline int sx_setup_board(struct specialix_board * bp)
1027 int error;
1029 if (bp->flags & SX_BOARD_ACTIVE)
1030 return 0;
1032 if (bp->flags & SX_BOARD_IS_PCI)
1033 error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT | SA_SHIRQ, "specialix IO8+", bp);
1034 else
1035 error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT, "specialix IO8+", bp);
1037 if (error)
1038 return error;
1040 turn_ints_on (bp);
1041 bp->flags |= SX_BOARD_ACTIVE;
1043 return 0;
1047 /* Called with disabled interrupts */
1048 static inline void sx_shutdown_board(struct specialix_board *bp)
1050 func_enter();
1052 if (!(bp->flags & SX_BOARD_ACTIVE)) {
1053 func_exit();
1054 return;
1057 bp->flags &= ~SX_BOARD_ACTIVE;
1059 dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
1060 bp->irq, board_No (bp));
1061 free_irq(bp->irq, bp);
1063 turn_ints_off (bp);
1066 func_exit();
1071 * Setting up port characteristics.
1072 * Must be called with disabled interrupts
1074 static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
1076 struct tty_struct *tty;
1077 unsigned long baud;
1078 long tmp;
1079 unsigned char cor1 = 0, cor3 = 0;
1080 unsigned char mcor1 = 0, mcor2 = 0;
1081 static unsigned long again;
1082 unsigned long flags;
1084 func_enter();
1086 if (!(tty = port->tty) || !tty->termios) {
1087 func_exit();
1088 return;
1091 port->IER = 0;
1092 port->COR2 = 0;
1093 /* Select port on the board */
1094 spin_lock_irqsave(&bp->lock, flags);
1095 sx_out(bp, CD186x_CAR, port_No(port));
1097 /* The Specialix board doens't implement the RTS lines.
1098 They are used to set the IRQ level. Don't touch them. */
1099 if (SX_CRTSCTS(tty))
1100 port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1101 else
1102 port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1103 spin_unlock_irqrestore(&bp->lock, flags);
1104 dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
1105 baud = C_BAUD(tty);
1107 if (baud & CBAUDEX) {
1108 baud &= ~CBAUDEX;
1109 if (baud < 1 || baud > 2)
1110 port->tty->termios->c_cflag &= ~CBAUDEX;
1111 else
1112 baud += 15;
1114 if (baud == 15) {
1115 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1116 baud ++;
1117 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1118 baud += 2;
1122 if (!baud_table[baud]) {
1123 /* Drop DTR & exit */
1124 dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
1125 if (!SX_CRTSCTS (tty)) {
1126 port -> MSVR &= ~ MSVR_DTR;
1127 spin_lock_irqsave(&bp->lock, flags);
1128 sx_out(bp, CD186x_MSVR, port->MSVR );
1129 spin_unlock_irqrestore(&bp->lock, flags);
1131 else
1132 dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1133 return;
1134 } else {
1135 /* Set DTR on */
1136 if (!SX_CRTSCTS (tty)) {
1137 port ->MSVR |= MSVR_DTR;
1142 * Now we must calculate some speed depended things
1145 /* Set baud rate for port */
1146 tmp = port->custom_divisor ;
1147 if ( tmp )
1148 printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n"
1149 "This is an untested option, please be carefull.\n",
1150 port_No (port), tmp);
1151 else
1152 tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
1153 CD186x_TPC/2) / CD186x_TPC);
1155 if ((tmp < 0x10) && time_before(again, jiffies)) {
1156 again = jiffies + HZ * 60;
1157 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1158 if (tmp >= 12) {
1159 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1160 "Performance degradation is possible.\n"
1161 "Read specialix.txt for more info.\n",
1162 port_No (port), tmp);
1163 } else {
1164 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1165 "Warning: overstressing Cirrus chip. "
1166 "This might not work.\n"
1167 "Read specialix.txt for more info.\n",
1168 port_No (port), tmp);
1171 spin_lock_irqsave(&bp->lock, flags);
1172 sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1173 sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1174 sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1175 sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1176 spin_unlock_irqrestore(&bp->lock, flags);
1177 if (port->custom_divisor) {
1178 baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
1179 baud = ( baud + 5 ) / 10;
1180 } else
1181 baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */
1183 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1184 tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1185 port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1186 SERIAL_XMIT_SIZE - 1 : tmp);
1188 /* Receiver timeout will be transmission time for 1.5 chars */
1189 tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1190 tmp = (tmp > 0xff) ? 0xff : tmp;
1191 spin_lock_irqsave(&bp->lock, flags);
1192 sx_out(bp, CD186x_RTPR, tmp);
1193 spin_unlock_irqrestore(&bp->lock, flags);
1194 switch (C_CSIZE(tty)) {
1195 case CS5:
1196 cor1 |= COR1_5BITS;
1197 break;
1198 case CS6:
1199 cor1 |= COR1_6BITS;
1200 break;
1201 case CS7:
1202 cor1 |= COR1_7BITS;
1203 break;
1204 case CS8:
1205 cor1 |= COR1_8BITS;
1206 break;
1209 if (C_CSTOPB(tty))
1210 cor1 |= COR1_2SB;
1212 cor1 |= COR1_IGNORE;
1213 if (C_PARENB(tty)) {
1214 cor1 |= COR1_NORMPAR;
1215 if (C_PARODD(tty))
1216 cor1 |= COR1_ODDP;
1217 if (I_INPCK(tty))
1218 cor1 &= ~COR1_IGNORE;
1220 /* Set marking of some errors */
1221 port->mark_mask = RCSR_OE | RCSR_TOUT;
1222 if (I_INPCK(tty))
1223 port->mark_mask |= RCSR_FE | RCSR_PE;
1224 if (I_BRKINT(tty) || I_PARMRK(tty))
1225 port->mark_mask |= RCSR_BREAK;
1226 if (I_IGNPAR(tty))
1227 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1228 if (I_IGNBRK(tty)) {
1229 port->mark_mask &= ~RCSR_BREAK;
1230 if (I_IGNPAR(tty))
1231 /* Real raw mode. Ignore all */
1232 port->mark_mask &= ~RCSR_OE;
1234 /* Enable Hardware Flow Control */
1235 if (C_CRTSCTS(tty)) {
1236 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1237 port->IER |= IER_DSR | IER_CTS;
1238 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1239 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1240 spin_lock_irqsave(&bp->lock, flags);
1241 tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
1242 spin_unlock_irqrestore(&bp->lock, flags);
1243 #else
1244 port->COR2 |= COR2_CTSAE;
1245 #endif
1247 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1248 /* Some people reported that it works, but I still doubt it */
1249 if (I_IXON(tty)) {
1250 port->COR2 |= COR2_TXIBE;
1251 cor3 |= (COR3_FCT | COR3_SCDE);
1252 if (I_IXANY(tty))
1253 port->COR2 |= COR2_IXM;
1254 spin_lock_irqsave(&bp->lock, flags);
1255 sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1256 sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1257 sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1258 sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1259 spin_unlock_irqrestore(&bp->lock, flags);
1261 if (!C_CLOCAL(tty)) {
1262 /* Enable CD check */
1263 port->IER |= IER_CD;
1264 mcor1 |= MCOR1_CDZD;
1265 mcor2 |= MCOR2_CDOD;
1268 if (C_CREAD(tty))
1269 /* Enable receiver */
1270 port->IER |= IER_RXD;
1272 /* Set input FIFO size (1-8 bytes) */
1273 cor3 |= sx_rxfifo;
1274 /* Setting up CD186x channel registers */
1275 spin_lock_irqsave(&bp->lock, flags);
1276 sx_out(bp, CD186x_COR1, cor1);
1277 sx_out(bp, CD186x_COR2, port->COR2);
1278 sx_out(bp, CD186x_COR3, cor3);
1279 spin_unlock_irqrestore(&bp->lock, flags);
1280 /* Make CD186x know about registers change */
1281 sx_wait_CCR(bp);
1282 spin_lock_irqsave(&bp->lock, flags);
1283 sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1284 /* Setting up modem option registers */
1285 dprintk (SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2);
1286 sx_out(bp, CD186x_MCOR1, mcor1);
1287 sx_out(bp, CD186x_MCOR2, mcor2);
1288 spin_unlock_irqrestore(&bp->lock, flags);
1289 /* Enable CD186x transmitter & receiver */
1290 sx_wait_CCR(bp);
1291 spin_lock_irqsave(&bp->lock, flags);
1292 sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1293 /* Enable interrupts */
1294 sx_out(bp, CD186x_IER, port->IER);
1295 /* And finally set the modem lines... */
1296 sx_out(bp, CD186x_MSVR, port->MSVR);
1297 spin_unlock_irqrestore(&bp->lock, flags);
1299 func_exit();
1303 /* Must be called with interrupts enabled */
1304 static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port)
1306 unsigned long flags;
1308 func_enter();
1310 if (port->flags & ASYNC_INITIALIZED) {
1311 func_exit();
1312 return 0;
1315 if (!port->xmit_buf) {
1316 /* We may sleep in get_zeroed_page() */
1317 unsigned long tmp;
1319 if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
1320 func_exit();
1321 return -ENOMEM;
1324 if (port->xmit_buf) {
1325 free_page(tmp);
1326 func_exit();
1327 return -ERESTARTSYS;
1329 port->xmit_buf = (unsigned char *) tmp;
1332 spin_lock_irqsave(&port->lock, flags);
1334 if (port->tty)
1335 clear_bit(TTY_IO_ERROR, &port->tty->flags);
1337 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1338 sx_change_speed(bp, port);
1339 port->flags |= ASYNC_INITIALIZED;
1341 spin_unlock_irqrestore(&port->lock, flags);
1344 func_exit();
1345 return 0;
1349 /* Must be called with interrupts disabled */
1350 static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port)
1352 struct tty_struct *tty;
1353 int i;
1354 unsigned long flags;
1356 func_enter();
1358 if (!(port->flags & ASYNC_INITIALIZED)) {
1359 func_exit();
1360 return;
1363 if (sx_debug & SX_DEBUG_FIFO) {
1364 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
1365 board_No(bp), port_No(port), port->overrun);
1366 for (i = 0; i < 10; i++) {
1367 dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1369 dprintk(SX_DEBUG_FIFO, "].\n");
1372 if (port->xmit_buf) {
1373 free_page((unsigned long) port->xmit_buf);
1374 port->xmit_buf = NULL;
1377 /* Select port */
1378 spin_lock_irqsave(&bp->lock, flags);
1379 sx_out(bp, CD186x_CAR, port_No(port));
1381 if (!(tty = port->tty) || C_HUPCL(tty)) {
1382 /* Drop DTR */
1383 sx_out(bp, CD186x_MSVDTR, 0);
1385 spin_unlock_irqrestore(&bp->lock, flags);
1386 /* Reset port */
1387 sx_wait_CCR(bp);
1388 spin_lock_irqsave(&bp->lock, flags);
1389 sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1390 /* Disable all interrupts from this port */
1391 port->IER = 0;
1392 sx_out(bp, CD186x_IER, port->IER);
1393 spin_unlock_irqrestore(&bp->lock, flags);
1394 if (tty)
1395 set_bit(TTY_IO_ERROR, &tty->flags);
1396 port->flags &= ~ASYNC_INITIALIZED;
1398 if (!bp->count)
1399 sx_shutdown_board(bp);
1400 func_exit();
1404 static int block_til_ready(struct tty_struct *tty, struct file * filp,
1405 struct specialix_port *port)
1407 DECLARE_WAITQUEUE(wait, current);
1408 struct specialix_board *bp = port_Board(port);
1409 int retval;
1410 int do_clocal = 0;
1411 int CD;
1412 unsigned long flags;
1414 func_enter();
1417 * If the device is in the middle of being closed, then block
1418 * until it's done, and then try again.
1420 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
1421 interruptible_sleep_on(&port->close_wait);
1422 if (port->flags & ASYNC_HUP_NOTIFY) {
1423 func_exit();
1424 return -EAGAIN;
1425 } else {
1426 func_exit();
1427 return -ERESTARTSYS;
1432 * If non-blocking mode is set, or the port is not enabled,
1433 * then make the check up front and then exit.
1435 if ((filp->f_flags & O_NONBLOCK) ||
1436 (tty->flags & (1 << TTY_IO_ERROR))) {
1437 port->flags |= ASYNC_NORMAL_ACTIVE;
1438 func_exit();
1439 return 0;
1442 if (C_CLOCAL(tty))
1443 do_clocal = 1;
1446 * Block waiting for the carrier detect and the line to become
1447 * free (i.e., not in use by the callout). While we are in
1448 * this loop, info->count is dropped by one, so that
1449 * rs_close() knows when to free things. We restore it upon
1450 * exit, either normal or abnormal.
1452 retval = 0;
1453 add_wait_queue(&port->open_wait, &wait);
1454 spin_lock_irqsave(&port->lock, flags);
1455 if (!tty_hung_up_p(filp)) {
1456 port->count--;
1458 spin_unlock_irqrestore(&port->lock, flags);
1459 port->blocked_open++;
1460 while (1) {
1461 spin_lock_irqsave(&bp->lock, flags);
1462 sx_out(bp, CD186x_CAR, port_No(port));
1463 CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1464 if (SX_CRTSCTS (tty)) {
1465 /* Activate RTS */
1466 port->MSVR |= MSVR_DTR; /* WTF? */
1467 sx_out (bp, CD186x_MSVR, port->MSVR);
1468 } else {
1469 /* Activate DTR */
1470 port->MSVR |= MSVR_DTR;
1471 sx_out (bp, CD186x_MSVR, port->MSVR);
1473 spin_unlock_irqrestore(&bp->lock, flags);
1474 set_current_state(TASK_INTERRUPTIBLE);
1475 if (tty_hung_up_p(filp) ||
1476 !(port->flags & ASYNC_INITIALIZED)) {
1477 if (port->flags & ASYNC_HUP_NOTIFY)
1478 retval = -EAGAIN;
1479 else
1480 retval = -ERESTARTSYS;
1481 break;
1483 if (!(port->flags & ASYNC_CLOSING) &&
1484 (do_clocal || CD))
1485 break;
1486 if (signal_pending(current)) {
1487 retval = -ERESTARTSYS;
1488 break;
1490 schedule();
1493 set_current_state(TASK_RUNNING);
1494 remove_wait_queue(&port->open_wait, &wait);
1495 spin_lock_irqsave(&port->lock, flags);
1496 if (!tty_hung_up_p(filp)) {
1497 port->count++;
1499 port->blocked_open--;
1500 spin_unlock_irqrestore(&port->lock, flags);
1501 if (retval) {
1502 func_exit();
1503 return retval;
1506 port->flags |= ASYNC_NORMAL_ACTIVE;
1507 func_exit();
1508 return 0;
1512 static int sx_open(struct tty_struct * tty, struct file * filp)
1514 int board;
1515 int error;
1516 struct specialix_port * port;
1517 struct specialix_board * bp;
1518 int i;
1519 unsigned long flags;
1521 func_enter();
1523 board = SX_BOARD(tty->index);
1525 if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1526 func_exit();
1527 return -ENODEV;
1530 bp = &sx_board[board];
1531 port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1532 port->overrun = 0;
1533 for (i = 0; i < 10; i++)
1534 port->hits[i]=0;
1536 dprintk (SX_DEBUG_OPEN, "Board = %d, bp = %p, port = %p, portno = %d.\n",
1537 board, bp, port, SX_PORT(tty->index));
1539 if (sx_paranoia_check(port, tty->name, "sx_open")) {
1540 func_enter();
1541 return -ENODEV;
1544 if ((error = sx_setup_board(bp))) {
1545 func_exit();
1546 return error;
1549 spin_lock_irqsave(&bp->lock, flags);
1550 port->count++;
1551 bp->count++;
1552 tty->driver_data = port;
1553 port->tty = tty;
1554 spin_unlock_irqrestore(&bp->lock, flags);
1556 if ((error = sx_setup_port(bp, port))) {
1557 func_enter();
1558 return error;
1561 if ((error = block_til_ready(tty, filp, port))) {
1562 func_enter();
1563 return error;
1566 func_exit();
1567 return 0;
1571 static void sx_close(struct tty_struct * tty, struct file * filp)
1573 struct specialix_port *port = (struct specialix_port *) tty->driver_data;
1574 struct specialix_board *bp;
1575 unsigned long flags;
1576 unsigned long timeout;
1578 func_enter();
1579 if (!port || sx_paranoia_check(port, tty->name, "close")) {
1580 func_exit();
1581 return;
1583 spin_lock_irqsave(&port->lock, flags);
1585 if (tty_hung_up_p(filp)) {
1586 spin_unlock_irqrestore(&port->lock, flags);
1587 func_exit();
1588 return;
1591 bp = port_Board(port);
1592 if ((tty->count == 1) && (port->count != 1)) {
1593 printk(KERN_ERR "sx%d: sx_close: bad port count;"
1594 " tty->count is 1, port count is %d\n",
1595 board_No(bp), port->count);
1596 port->count = 1;
1599 if (port->count > 1) {
1600 port->count--;
1601 bp->count--;
1603 spin_unlock_irqrestore(&port->lock, flags);
1605 func_exit();
1606 return;
1608 port->flags |= ASYNC_CLOSING;
1610 * Now we wait for the transmit buffer to clear; and we notify
1611 * the line discipline to only process XON/XOFF characters.
1613 tty->closing = 1;
1614 spin_unlock_irqrestore(&port->lock, flags);
1615 dprintk (SX_DEBUG_OPEN, "Closing\n");
1616 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
1617 tty_wait_until_sent(tty, port->closing_wait);
1620 * At this point we stop accepting input. To do this, we
1621 * disable the receive line status interrupts, and tell the
1622 * interrupt driver to stop checking the data ready bit in the
1623 * line status register.
1625 dprintk (SX_DEBUG_OPEN, "Closed\n");
1626 port->IER &= ~IER_RXD;
1627 if (port->flags & ASYNC_INITIALIZED) {
1628 port->IER &= ~IER_TXRDY;
1629 port->IER |= IER_TXEMPTY;
1630 spin_lock_irqsave(&bp->lock, flags);
1631 sx_out(bp, CD186x_CAR, port_No(port));
1632 sx_out(bp, CD186x_IER, port->IER);
1633 spin_unlock_irqrestore(&bp->lock, flags);
1635 * Before we drop DTR, make sure the UART transmitter
1636 * has completely drained; this is especially
1637 * important if there is a transmit FIFO!
1639 timeout = jiffies+HZ;
1640 while(port->IER & IER_TXEMPTY) {
1641 set_current_state (TASK_INTERRUPTIBLE);
1642 msleep_interruptible(jiffies_to_msecs(port->timeout));
1643 if (time_after(jiffies, timeout)) {
1644 printk (KERN_INFO "Timeout waiting for close\n");
1645 break;
1651 if (--bp->count < 0) {
1652 printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1653 board_No(bp), bp->count, tty->index);
1654 bp->count = 0;
1656 if (--port->count < 0) {
1657 printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n",
1658 board_No(bp), port_No(port), port->count);
1659 port->count = 0;
1662 sx_shutdown_port(bp, port);
1663 if (tty->driver->flush_buffer)
1664 tty->driver->flush_buffer(tty);
1665 tty_ldisc_flush(tty);
1666 spin_lock_irqsave(&port->lock, flags);
1667 tty->closing = 0;
1668 port->event = 0;
1669 port->tty = NULL;
1670 spin_unlock_irqrestore(&port->lock, flags);
1671 if (port->blocked_open) {
1672 if (port->close_delay) {
1673 msleep_interruptible(jiffies_to_msecs(port->close_delay));
1675 wake_up_interruptible(&port->open_wait);
1677 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1678 wake_up_interruptible(&port->close_wait);
1680 func_exit();
1684 static int sx_write(struct tty_struct * tty,
1685 const unsigned char *buf, int count)
1687 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1688 struct specialix_board *bp;
1689 int c, total = 0;
1690 unsigned long flags;
1692 func_enter();
1693 if (sx_paranoia_check(port, tty->name, "sx_write")) {
1694 func_exit();
1695 return 0;
1698 bp = port_Board(port);
1700 if (!tty || !port->xmit_buf || !tmp_buf) {
1701 func_exit();
1702 return 0;
1705 while (1) {
1706 spin_lock_irqsave(&port->lock, flags);
1707 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1708 SERIAL_XMIT_SIZE - port->xmit_head));
1709 if (c <= 0) {
1710 spin_unlock_irqrestore(&port->lock, flags);
1711 break;
1713 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1714 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1715 port->xmit_cnt += c;
1716 spin_unlock_irqrestore(&port->lock, flags);
1718 buf += c;
1719 count -= c;
1720 total += c;
1723 spin_lock_irqsave(&bp->lock, flags);
1724 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1725 !(port->IER & IER_TXRDY)) {
1726 port->IER |= IER_TXRDY;
1727 sx_out(bp, CD186x_CAR, port_No(port));
1728 sx_out(bp, CD186x_IER, port->IER);
1730 spin_unlock_irqrestore(&bp->lock, flags);
1731 func_exit();
1733 return total;
1737 static void sx_put_char(struct tty_struct * tty, unsigned char ch)
1739 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1740 unsigned long flags;
1741 struct specialix_board * bp;
1743 func_enter();
1745 if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1746 func_exit();
1747 return;
1749 dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1750 if (!tty || !port->xmit_buf) {
1751 func_exit();
1752 return;
1754 bp = port_Board(port);
1755 spin_lock_irqsave(&port->lock, flags);
1757 dprintk (SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", port->xmit_cnt, port->xmit_buf);
1758 if ((port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) || (!port->xmit_buf)) {
1759 spin_unlock_irqrestore(&port->lock, flags);
1760 dprintk (SX_DEBUG_TX, "Exit size\n");
1761 func_exit();
1762 return;
1764 dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
1765 port->xmit_buf[port->xmit_head++] = ch;
1766 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1767 port->xmit_cnt++;
1768 spin_unlock_irqrestore(&port->lock, flags);
1770 func_exit();
1774 static void sx_flush_chars(struct tty_struct * tty)
1776 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1777 unsigned long flags;
1778 struct specialix_board * bp = port_Board(port);
1780 func_enter();
1782 if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1783 func_exit();
1784 return;
1786 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1787 !port->xmit_buf) {
1788 func_exit();
1789 return;
1791 spin_lock_irqsave(&bp->lock, flags);
1792 port->IER |= IER_TXRDY;
1793 sx_out(port_Board(port), CD186x_CAR, port_No(port));
1794 sx_out(port_Board(port), CD186x_IER, port->IER);
1795 spin_unlock_irqrestore(&bp->lock, flags);
1797 func_exit();
1801 static int sx_write_room(struct tty_struct * tty)
1803 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1804 int ret;
1806 func_enter();
1808 if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1809 func_exit();
1810 return 0;
1813 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1814 if (ret < 0)
1815 ret = 0;
1817 func_exit();
1818 return ret;
1822 static int sx_chars_in_buffer(struct tty_struct *tty)
1824 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1826 func_enter();
1828 if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
1829 func_exit();
1830 return 0;
1832 func_exit();
1833 return port->xmit_cnt;
1837 static void sx_flush_buffer(struct tty_struct *tty)
1839 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1840 unsigned long flags;
1841 struct specialix_board * bp;
1843 func_enter();
1845 if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
1846 func_exit();
1847 return;
1850 bp = port_Board(port);
1851 spin_lock_irqsave(&port->lock, flags);
1852 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1853 spin_unlock_irqrestore(&port->lock, flags);
1854 tty_wakeup(tty);
1856 func_exit();
1860 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1862 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1863 struct specialix_board * bp;
1864 unsigned char status;
1865 unsigned int result;
1866 unsigned long flags;
1868 func_enter();
1870 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1871 func_exit();
1872 return -ENODEV;
1875 bp = port_Board(port);
1876 spin_lock_irqsave (&bp->lock, flags);
1877 sx_out(bp, CD186x_CAR, port_No(port));
1878 status = sx_in(bp, CD186x_MSVR);
1879 spin_unlock_irqrestore(&bp->lock, flags);
1880 dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1881 port_No(port), status, sx_in (bp, CD186x_CAR));
1882 dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1883 if (SX_CRTSCTS(port->tty)) {
1884 result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
1885 | ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1886 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1887 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1888 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1889 } else {
1890 result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
1891 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1892 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1893 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1894 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1897 func_exit();
1899 return result;
1903 static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1904 unsigned int set, unsigned int clear)
1906 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1907 unsigned long flags;
1908 struct specialix_board *bp;
1910 func_enter();
1912 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1913 func_exit();
1914 return -ENODEV;
1917 bp = port_Board(port);
1919 spin_lock_irqsave(&port->lock, flags);
1920 /* if (set & TIOCM_RTS)
1921 port->MSVR |= MSVR_RTS; */
1922 /* if (set & TIOCM_DTR)
1923 port->MSVR |= MSVR_DTR; */
1925 if (SX_CRTSCTS(port->tty)) {
1926 if (set & TIOCM_RTS)
1927 port->MSVR |= MSVR_DTR;
1928 } else {
1929 if (set & TIOCM_DTR)
1930 port->MSVR |= MSVR_DTR;
1933 /* if (clear & TIOCM_RTS)
1934 port->MSVR &= ~MSVR_RTS; */
1935 /* if (clear & TIOCM_DTR)
1936 port->MSVR &= ~MSVR_DTR; */
1937 if (SX_CRTSCTS(port->tty)) {
1938 if (clear & TIOCM_RTS)
1939 port->MSVR &= ~MSVR_DTR;
1940 } else {
1941 if (clear & TIOCM_DTR)
1942 port->MSVR &= ~MSVR_DTR;
1944 spin_lock_irqsave(&bp->lock, flags);
1945 sx_out(bp, CD186x_CAR, port_No(port));
1946 sx_out(bp, CD186x_MSVR, port->MSVR);
1947 spin_unlock_irqrestore(&bp->lock, flags);
1948 spin_unlock_irqrestore(&port->lock, flags);
1949 func_exit();
1950 return 0;
1954 static inline void sx_send_break(struct specialix_port * port, unsigned long length)
1956 struct specialix_board *bp = port_Board(port);
1957 unsigned long flags;
1959 func_enter();
1961 spin_lock_irqsave (&port->lock, flags);
1962 port->break_length = SPECIALIX_TPS / HZ * length;
1963 port->COR2 |= COR2_ETC;
1964 port->IER |= IER_TXRDY;
1965 spin_lock_irqsave(&bp->lock, flags);
1966 sx_out(bp, CD186x_CAR, port_No(port));
1967 sx_out(bp, CD186x_COR2, port->COR2);
1968 sx_out(bp, CD186x_IER, port->IER);
1969 spin_unlock_irqrestore(&bp->lock, flags);
1970 spin_unlock_irqrestore (&port->lock, flags);
1971 sx_wait_CCR(bp);
1972 spin_lock_irqsave(&bp->lock, flags);
1973 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1974 spin_unlock_irqrestore(&bp->lock, flags);
1975 sx_wait_CCR(bp);
1977 func_exit();
1981 static inline int sx_set_serial_info(struct specialix_port * port,
1982 struct serial_struct __user * newinfo)
1984 struct serial_struct tmp;
1985 struct specialix_board *bp = port_Board(port);
1986 int change_speed;
1988 func_enter();
1990 if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1991 func_exit();
1992 return -EFAULT;
1995 if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
1996 func_enter();
1997 return -EFAULT;
2000 #if 0
2001 if ((tmp.irq != bp->irq) ||
2002 (tmp.port != bp->base) ||
2003 (tmp.type != PORT_CIRRUS) ||
2004 (tmp.baud_base != (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) ||
2005 (tmp.custom_divisor != 0) ||
2006 (tmp.xmit_fifo_size != CD186x_NFIFO) ||
2007 (tmp.flags & ~SPECIALIX_LEGAL_FLAGS)) {
2008 func_exit();
2009 return -EINVAL;
2011 #endif
2013 change_speed = ((port->flags & ASYNC_SPD_MASK) !=
2014 (tmp.flags & ASYNC_SPD_MASK));
2015 change_speed |= (tmp.custom_divisor != port->custom_divisor);
2017 if (!capable(CAP_SYS_ADMIN)) {
2018 if ((tmp.close_delay != port->close_delay) ||
2019 (tmp.closing_wait != port->closing_wait) ||
2020 ((tmp.flags & ~ASYNC_USR_MASK) !=
2021 (port->flags & ~ASYNC_USR_MASK))) {
2022 func_exit();
2023 return -EPERM;
2025 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
2026 (tmp.flags & ASYNC_USR_MASK));
2027 port->custom_divisor = tmp.custom_divisor;
2028 } else {
2029 port->flags = ((port->flags & ~ASYNC_FLAGS) |
2030 (tmp.flags & ASYNC_FLAGS));
2031 port->close_delay = tmp.close_delay;
2032 port->closing_wait = tmp.closing_wait;
2033 port->custom_divisor = tmp.custom_divisor;
2035 if (change_speed) {
2036 sx_change_speed(bp, port);
2038 func_exit();
2039 return 0;
2043 static inline int sx_get_serial_info(struct specialix_port * port,
2044 struct serial_struct __user *retinfo)
2046 struct serial_struct tmp;
2047 struct specialix_board *bp = port_Board(port);
2049 func_enter();
2052 if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
2053 return -EFAULT;
2056 memset(&tmp, 0, sizeof(tmp));
2057 tmp.type = PORT_CIRRUS;
2058 tmp.line = port - sx_port;
2059 tmp.port = bp->base;
2060 tmp.irq = bp->irq;
2061 tmp.flags = port->flags;
2062 tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
2063 tmp.close_delay = port->close_delay * HZ/100;
2064 tmp.closing_wait = port->closing_wait * HZ/100;
2065 tmp.custom_divisor = port->custom_divisor;
2066 tmp.xmit_fifo_size = CD186x_NFIFO;
2067 if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
2068 func_exit();
2069 return -EFAULT;
2072 func_exit();
2073 return 0;
2077 static int sx_ioctl(struct tty_struct * tty, struct file * filp,
2078 unsigned int cmd, unsigned long arg)
2080 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2081 int retval;
2082 void __user *argp = (void __user *)arg;
2084 func_enter();
2086 if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
2087 func_exit();
2088 return -ENODEV;
2091 switch (cmd) {
2092 case TCSBRK: /* SVID version: non-zero arg --> no break */
2093 retval = tty_check_change(tty);
2094 if (retval) {
2095 func_exit();
2096 return retval;
2098 tty_wait_until_sent(tty, 0);
2099 if (!arg)
2100 sx_send_break(port, HZ/4); /* 1/4 second */
2101 return 0;
2102 case TCSBRKP: /* support for POSIX tcsendbreak() */
2103 retval = tty_check_change(tty);
2104 if (retval) {
2105 func_exit();
2106 return retval;
2108 tty_wait_until_sent(tty, 0);
2109 sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
2110 func_exit();
2111 return 0;
2112 case TIOCGSOFTCAR:
2113 if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) {
2114 func_exit();
2115 return -EFAULT;
2117 func_exit();
2118 return 0;
2119 case TIOCSSOFTCAR:
2120 if (get_user(arg, (unsigned long __user *) argp)) {
2121 func_exit();
2122 return -EFAULT;
2124 tty->termios->c_cflag =
2125 ((tty->termios->c_cflag & ~CLOCAL) |
2126 (arg ? CLOCAL : 0));
2127 func_exit();
2128 return 0;
2129 case TIOCGSERIAL:
2130 func_exit();
2131 return sx_get_serial_info(port, argp);
2132 case TIOCSSERIAL:
2133 func_exit();
2134 return sx_set_serial_info(port, argp);
2135 default:
2136 func_exit();
2137 return -ENOIOCTLCMD;
2139 func_exit();
2140 return 0;
2144 static void sx_throttle(struct tty_struct * tty)
2146 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2147 struct specialix_board *bp;
2148 unsigned long flags;
2150 func_enter();
2152 if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
2153 func_exit();
2154 return;
2157 bp = port_Board(port);
2159 /* Use DTR instead of RTS ! */
2160 if (SX_CRTSCTS (tty))
2161 port->MSVR &= ~MSVR_DTR;
2162 else {
2163 /* Auch!!! I think the system shouldn't call this then. */
2164 /* Or maybe we're supposed (allowed?) to do our side of hw
2165 handshake anyway, even when hardware handshake is off.
2166 When you see this in your logs, please report.... */
2167 printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
2168 port_No (port));
2170 spin_lock_irqsave(&bp->lock, flags);
2171 sx_out(bp, CD186x_CAR, port_No(port));
2172 spin_unlock_irqrestore(&bp->lock, flags);
2173 if (I_IXOFF(tty)) {
2174 spin_unlock_irqrestore(&bp->lock, flags);
2175 sx_wait_CCR(bp);
2176 spin_lock_irqsave(&bp->lock, flags);
2177 sx_out(bp, CD186x_CCR, CCR_SSCH2);
2178 spin_unlock_irqrestore(&bp->lock, flags);
2179 sx_wait_CCR(bp);
2181 spin_lock_irqsave(&bp->lock, flags);
2182 sx_out(bp, CD186x_MSVR, port->MSVR);
2183 spin_unlock_irqrestore(&bp->lock, flags);
2185 func_exit();
2189 static void sx_unthrottle(struct tty_struct * tty)
2191 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2192 struct specialix_board *bp;
2193 unsigned long flags;
2195 func_enter();
2197 if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
2198 func_exit();
2199 return;
2202 bp = port_Board(port);
2204 spin_lock_irqsave(&port->lock, flags);
2205 /* XXXX Use DTR INSTEAD???? */
2206 if (SX_CRTSCTS(tty)) {
2207 port->MSVR |= MSVR_DTR;
2208 } /* Else clause: see remark in "sx_throttle"... */
2209 spin_lock_irqsave(&bp->lock, flags);
2210 sx_out(bp, CD186x_CAR, port_No(port));
2211 spin_unlock_irqrestore(&bp->lock, flags);
2212 if (I_IXOFF(tty)) {
2213 spin_unlock_irqrestore(&port->lock, flags);
2214 sx_wait_CCR(bp);
2215 spin_lock_irqsave(&bp->lock, flags);
2216 sx_out(bp, CD186x_CCR, CCR_SSCH1);
2217 spin_unlock_irqrestore(&bp->lock, flags);
2218 sx_wait_CCR(bp);
2219 spin_lock_irqsave(&port->lock, flags);
2221 spin_lock_irqsave(&bp->lock, flags);
2222 sx_out(bp, CD186x_MSVR, port->MSVR);
2223 spin_unlock_irqrestore(&bp->lock, flags);
2224 spin_unlock_irqrestore(&port->lock, flags);
2226 func_exit();
2230 static void sx_stop(struct tty_struct * tty)
2232 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2233 struct specialix_board *bp;
2234 unsigned long flags;
2236 func_enter();
2238 if (sx_paranoia_check(port, tty->name, "sx_stop")) {
2239 func_exit();
2240 return;
2243 bp = port_Board(port);
2245 spin_lock_irqsave(&port->lock, flags);
2246 port->IER &= ~IER_TXRDY;
2247 spin_lock_irqsave(&bp->lock, flags);
2248 sx_out(bp, CD186x_CAR, port_No(port));
2249 sx_out(bp, CD186x_IER, port->IER);
2250 spin_unlock_irqrestore(&bp->lock, flags);
2251 spin_unlock_irqrestore(&port->lock, flags);
2253 func_exit();
2257 static void sx_start(struct tty_struct * tty)
2259 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2260 struct specialix_board *bp;
2261 unsigned long flags;
2263 func_enter();
2265 if (sx_paranoia_check(port, tty->name, "sx_start")) {
2266 func_exit();
2267 return;
2270 bp = port_Board(port);
2272 spin_lock_irqsave(&port->lock, flags);
2273 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2274 port->IER |= IER_TXRDY;
2275 spin_lock_irqsave(&bp->lock, flags);
2276 sx_out(bp, CD186x_CAR, port_No(port));
2277 sx_out(bp, CD186x_IER, port->IER);
2278 spin_unlock_irqrestore(&bp->lock, flags);
2280 spin_unlock_irqrestore(&port->lock, flags);
2282 func_exit();
2287 * This routine is called from the work-queue when the interrupt
2288 * routine has signalled that a hangup has occurred. The path of
2289 * hangup processing is:
2291 * serial interrupt routine -> (workqueue) ->
2292 * do_sx_hangup() -> tty->hangup() -> sx_hangup()
2295 static void do_sx_hangup(void *private_)
2297 struct specialix_port *port = (struct specialix_port *) private_;
2298 struct tty_struct *tty;
2300 func_enter();
2302 tty = port->tty;
2303 if (tty)
2304 tty_hangup(tty); /* FIXME: module removal race here */
2306 func_exit();
2310 static void sx_hangup(struct tty_struct * tty)
2312 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2313 struct specialix_board *bp;
2314 unsigned long flags;
2316 func_enter();
2318 if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2319 func_exit();
2320 return;
2323 bp = port_Board(port);
2325 sx_shutdown_port(bp, port);
2326 spin_lock_irqsave(&port->lock, flags);
2327 port->event = 0;
2328 bp->count -= port->count;
2329 if (bp->count < 0) {
2330 printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n",
2331 board_No(bp), bp->count, tty->index);
2332 bp->count = 0;
2334 port->count = 0;
2335 port->flags &= ~ASYNC_NORMAL_ACTIVE;
2336 port->tty = NULL;
2337 spin_unlock_irqrestore(&port->lock, flags);
2338 wake_up_interruptible(&port->open_wait);
2340 func_exit();
2344 static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios)
2346 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2347 unsigned long flags;
2348 struct specialix_board * bp;
2350 if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2351 return;
2353 if (tty->termios->c_cflag == old_termios->c_cflag &&
2354 tty->termios->c_iflag == old_termios->c_iflag)
2355 return;
2357 bp = port_Board(port);
2358 spin_lock_irqsave(&port->lock, flags);
2359 sx_change_speed(port_Board(port), port);
2360 spin_unlock_irqrestore(&port->lock, flags);
2362 if ((old_termios->c_cflag & CRTSCTS) &&
2363 !(tty->termios->c_cflag & CRTSCTS)) {
2364 tty->hw_stopped = 0;
2365 sx_start(tty);
2370 static void do_softint(void *private_)
2372 struct specialix_port *port = (struct specialix_port *) private_;
2373 struct tty_struct *tty;
2375 func_enter();
2377 if(!(tty = port->tty)) {
2378 func_exit();
2379 return;
2382 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
2383 tty_wakeup(tty);
2384 //wake_up_interruptible(&tty->write_wait);
2387 func_exit();
2390 static struct tty_operations sx_ops = {
2391 .open = sx_open,
2392 .close = sx_close,
2393 .write = sx_write,
2394 .put_char = sx_put_char,
2395 .flush_chars = sx_flush_chars,
2396 .write_room = sx_write_room,
2397 .chars_in_buffer = sx_chars_in_buffer,
2398 .flush_buffer = sx_flush_buffer,
2399 .ioctl = sx_ioctl,
2400 .throttle = sx_throttle,
2401 .unthrottle = sx_unthrottle,
2402 .set_termios = sx_set_termios,
2403 .stop = sx_stop,
2404 .start = sx_start,
2405 .hangup = sx_hangup,
2406 .tiocmget = sx_tiocmget,
2407 .tiocmset = sx_tiocmset,
2410 static int sx_init_drivers(void)
2412 int error;
2413 int i;
2415 func_enter();
2417 specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT);
2418 if (!specialix_driver) {
2419 printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n");
2420 func_exit();
2421 return 1;
2424 if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
2425 printk(KERN_ERR "sx: Couldn't get free page.\n");
2426 put_tty_driver(specialix_driver);
2427 func_exit();
2428 return 1;
2430 specialix_driver->owner = THIS_MODULE;
2431 specialix_driver->name = "ttyW";
2432 specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
2433 specialix_driver->type = TTY_DRIVER_TYPE_SERIAL;
2434 specialix_driver->subtype = SERIAL_TYPE_NORMAL;
2435 specialix_driver->init_termios = tty_std_termios;
2436 specialix_driver->init_termios.c_cflag =
2437 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2438 specialix_driver->flags = TTY_DRIVER_REAL_RAW;
2439 tty_set_operations(specialix_driver, &sx_ops);
2441 if ((error = tty_register_driver(specialix_driver))) {
2442 put_tty_driver(specialix_driver);
2443 free_page((unsigned long)tmp_buf);
2444 printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2445 error);
2446 func_exit();
2447 return 1;
2449 memset(sx_port, 0, sizeof(sx_port));
2450 for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2451 sx_port[i].magic = SPECIALIX_MAGIC;
2452 INIT_WORK(&sx_port[i].tqueue, do_softint, &sx_port[i]);
2453 INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup, &sx_port[i]);
2454 sx_port[i].close_delay = 50 * HZ/100;
2455 sx_port[i].closing_wait = 3000 * HZ/100;
2456 init_waitqueue_head(&sx_port[i].open_wait);
2457 init_waitqueue_head(&sx_port[i].close_wait);
2458 spin_lock_init(&sx_port[i].lock);
2461 func_exit();
2462 return 0;
2465 static void sx_release_drivers(void)
2467 func_enter();
2469 free_page((unsigned long)tmp_buf);
2470 tty_unregister_driver(specialix_driver);
2471 put_tty_driver(specialix_driver);
2472 func_exit();
2476 * This routine must be called by kernel at boot time
2478 static int __init specialix_init(void)
2480 int i;
2481 int found = 0;
2483 func_enter();
2485 printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
2486 printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2487 #ifdef CONFIG_SPECIALIX_RTSCTS
2488 printk (KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
2489 #else
2490 printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2491 #endif
2493 for (i = 0; i < SX_NBOARD; i++)
2494 sx_board[i].lock = SPIN_LOCK_UNLOCKED;
2496 if (sx_init_drivers()) {
2497 func_exit();
2498 return -EIO;
2501 for (i = 0; i < SX_NBOARD; i++)
2502 if (sx_board[i].base && !sx_probe(&sx_board[i]))
2503 found++;
2505 #ifdef CONFIG_PCI
2507 struct pci_dev *pdev = NULL;
2509 i=0;
2510 while (i < SX_NBOARD) {
2511 if (sx_board[i].flags & SX_BOARD_PRESENT) {
2512 i++;
2513 continue;
2515 pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
2516 PCI_DEVICE_ID_SPECIALIX_IO8,
2517 pdev);
2518 if (!pdev) break;
2520 if (pci_enable_device(pdev))
2521 continue;
2523 sx_board[i].irq = pdev->irq;
2525 sx_board[i].base = pci_resource_start (pdev, 2);
2527 sx_board[i].flags |= SX_BOARD_IS_PCI;
2528 if (!sx_probe(&sx_board[i]))
2529 found ++;
2532 #endif
2534 if (!found) {
2535 sx_release_drivers();
2536 printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
2537 func_exit();
2538 return -EIO;
2541 func_exit();
2542 return 0;
2545 static int iobase[SX_NBOARD] = {0,};
2547 static int irq [SX_NBOARD] = {0,};
2549 module_param_array(iobase, int, NULL, 0);
2550 module_param_array(irq, int, NULL, 0);
2551 module_param(sx_debug, int, 0);
2552 module_param(sx_rxfifo, int, 0);
2553 #ifdef SPECIALIX_TIMER
2554 module_param(sx_poll, int, 0);
2555 #endif
2558 * You can setup up to 4 boards.
2559 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2560 * You should specify the IRQs too in that case "irq=....,...".
2562 * More than 4 boards in one computer is not possible, as the card can
2563 * only use 4 different interrupts.
2566 static int __init specialix_init_module(void)
2568 int i;
2570 func_enter();
2572 init_MUTEX(&tmp_buf_sem); /* Init de the semaphore - pvdl */
2574 if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2575 for(i = 0; i < SX_NBOARD; i++) {
2576 sx_board[i].base = iobase[i];
2577 sx_board[i].irq = irq[i];
2578 sx_board[i].count= 0;
2582 func_exit();
2584 return specialix_init();
2587 static void __exit specialix_exit_module(void)
2589 int i;
2591 func_enter();
2593 sx_release_drivers();
2594 for (i = 0; i < SX_NBOARD; i++)
2595 if (sx_board[i].flags & SX_BOARD_PRESENT)
2596 sx_release_io_range(&sx_board[i]);
2597 #ifdef SPECIALIX_TIMER
2598 del_timer (&missed_irq_timer);
2599 #endif
2601 func_exit();
2604 module_init(specialix_init_module);
2605 module_exit(specialix_exit_module);
2607 MODULE_LICENSE("GPL");