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)
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,
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>
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>
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"
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
113 static int sx_rxfifo = SPECIALIX_RXFIFO;
116 #define dprintk(f, str...) if (sx_debug & f) printk (str)
118 #define dprintk(f, str...) /* nothing */
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;
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
169 #define SX_CRTSCTS(tty) C_CRTSCTS(tty)
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);
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";
221 printk(badinfo, name, routine);
224 if (port->magic != SPECIALIX_MAGIC) {
225 printk(badmagic, name, routine);
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,
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)
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,
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;
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);
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)
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);
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_request_io_range(struct specialix_board * bp)
343 return request_region(bp->base,
344 bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
345 "specialix IO8+") == NULL;
349 static inline void sx_release_io_range(struct specialix_board * bp)
351 release_region(bp->base,
352 bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
356 /* Must be called with enabled interrupts */
357 /* Ugly. Very ugly. Don't use this for anything else than initialization
359 static inline void sx_long_delay(unsigned long delay)
363 for (i = jiffies + delay; time_after(i, jiffies); ) ;
368 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
369 static int sx_set_irq ( struct specialix_board *bp)
375 if (bp->flags & SX_BOARD_IS_PCI)
378 /* In the same order as in the docs... */
379 case 15: virq = 0;break;
380 case 12: virq = 1;break;
381 case 11: virq = 2;break;
382 case 9: virq = 3;break;
383 default: printk (KERN_ERR "Speclialix: cannot set irq to %d.\n", bp->irq);
386 spin_lock_irqsave(&bp->lock, flags);
388 sx_out(bp, CD186x_CAR, i);
389 sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
391 spin_unlock_irqrestore(&bp->lock, flags);
396 /* Reset and setup CD186x chip */
397 static int sx_init_CD186x(struct specialix_board * bp)
404 sx_wait_CCR_off(bp); /* Wait for CCR ready */
405 spin_lock_irqsave(&bp->lock, flags);
406 sx_out_off(bp, CD186x_CCR, CCR_HARDRESET); /* Reset CD186x chip */
407 spin_unlock_irqrestore(&bp->lock, flags);
408 sx_long_delay(HZ/20); /* Delay 0.05 sec */
409 spin_lock_irqsave(&bp->lock, flags);
410 sx_out_off(bp, CD186x_GIVR, SX_ID); /* Set ID for this chip */
411 sx_out_off(bp, CD186x_GICR, 0); /* Clear all bits */
412 sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT); /* Prio for modem intr */
413 sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */
414 sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
416 sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
418 /* Setting up prescaler. We need 4 ticks per 1 ms */
419 scaler = SX_OSCFREQ/SPECIALIX_TPS;
421 sx_out_off(bp, CD186x_PPRH, scaler >> 8);
422 sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
423 spin_unlock_irqrestore(&bp->lock, flags);
425 if (!sx_set_irq (bp)) {
426 /* Figure out how to pass this along... */
427 printk (KERN_ERR "Cannot set irq to %d.\n", bp->irq);
436 static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
442 spin_lock_irqsave(&bp->lock, flags);
443 for (i=0, t=0;i<8;i++) {
444 sx_out_off (bp, CD186x_CAR, i);
445 if (sx_in_off (bp, reg) & bit)
448 spin_unlock_irqrestore(&bp->lock, flags);
454 #ifdef SPECIALIX_TIMER
455 void missed_irq (unsigned long data)
459 struct specialix_board *bp = (struct specialix_board *)data;
461 spin_lock_irqsave(&bp->lock, flags);
462 irq = sx_in ((struct specialix_board *)data, CD186x_SRSR) &
466 spin_unlock_irqrestore(&bp->lock, flags);
468 printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
469 sx_interrupt (((struct specialix_board *)data)->irq,
472 missed_irq_timer.expires = jiffies + sx_poll;
473 add_timer (&missed_irq_timer);
479 /* Main probing routine, also sets irq. */
480 static int sx_probe(struct specialix_board *bp)
482 unsigned char val1, val2;
492 if (sx_request_io_range(bp)) {
497 /* Are the I/O ports here ? */
498 sx_out_off(bp, CD186x_PPRL, 0x5a);
500 val1 = sx_in_off(bp, CD186x_PPRL);
502 sx_out_off(bp, CD186x_PPRL, 0xa5);
504 val2 = sx_in_off(bp, CD186x_PPRL);
507 if ((val1 != 0x5a) || (val2 != 0xa5)) {
508 printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
509 board_No(bp), bp->base);
510 sx_release_io_range(bp);
515 /* Check the DSR lines that Specialix uses as board
517 val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
518 val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
519 dprintk (SX_DEBUG_INIT, "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
520 board_No(bp), val1, val2);
522 /* They managed to switch the bit order between the docs and
523 the IO8+ card. The new PCI card now conforms to old docs.
524 They changed the PCI docs to reflect the situation on the
526 val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
528 printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
529 board_No(bp), val2, bp->base, val1);
530 sx_release_io_range(bp);
537 /* It's time to find IRQ for this board */
538 for (retries = 0; retries < 5 && irqs <= 0; retries++) {
539 irqs = probe_irq_on();
540 sx_init_CD186x(bp); /* Reset CD186x chip */
541 sx_out(bp, CD186x_CAR, 2); /* Select port 2 */
543 sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */
544 sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */
545 sx_long_delay(HZ/20);
546 irqs = probe_irq_off(irqs);
548 dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
549 dprintk (SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR));
550 dprintk (SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR));
551 dprintk (SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR));
552 dprintk (SX_DEBUG_INIT, "\n");
554 /* Reset CD186x again */
555 if (!sx_init_CD186x(bp)) {
556 /* Hmmm. This is dead code anyway. */
559 dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
566 printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
567 board_No(bp), bp->base);
568 sx_release_io_range(bp);
573 printk (KERN_INFO "Started with irq=%d, but now have irq=%d.\n", bp->irq, irqs);
577 /* Reset CD186x again */
578 if (!sx_init_CD186x(bp)) {
579 sx_release_io_range(bp);
584 sx_request_io_range(bp);
585 bp->flags |= SX_BOARD_PRESENT;
587 /* Chip revcode pkgtype
592 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
594 -- Thanks to Gwen Wang, Cirrus Logic.
597 switch (sx_in_off(bp, CD186x_GFRCR)) {
598 case 0x82:chip = 1864;rev='A';break;
599 case 0x83:chip = 1865;rev='A';break;
600 case 0x84:chip = 1865;rev='B';break;
601 case 0x85:chip = 1865;rev='C';break; /* Does not exist at this time */
602 default:chip=-1;rev='x';
605 dprintk (SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR) );
607 #ifdef SPECIALIX_TIMER
608 init_timer (&missed_irq_timer);
609 missed_irq_timer.function = missed_irq;
610 missed_irq_timer.data = (unsigned long) bp;
611 missed_irq_timer.expires = jiffies + sx_poll;
612 add_timer (&missed_irq_timer);
615 printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
626 * Interrupt processing routines.
629 static inline void sx_mark_event(struct specialix_port * port, int event)
633 set_bit(event, &port->event);
634 schedule_work(&port->tqueue);
640 static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
641 unsigned char const * what)
643 unsigned char channel;
644 struct specialix_port * port = NULL;
646 channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
647 dprintk (SX_DEBUG_CHAN, "channel: %d\n", channel);
648 if (channel < CD186x_NCH) {
649 port = &sx_port[board_No(bp) * SX_NPORT + channel];
650 dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%x\n",board_No(bp) * SX_NPORT + channel, port, port->flags & ASYNC_INITIALIZED);
652 if (port->flags & ASYNC_INITIALIZED) {
653 dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
658 printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
659 board_No(bp), what, channel);
664 static inline void sx_receive_exc(struct specialix_board * bp)
666 struct specialix_port *port;
667 struct tty_struct *tty;
668 unsigned char status;
673 port = sx_get_port(bp, "Receive");
675 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
680 dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n",
681 port, tty->flip.count, TTY_FLIPBUF_SIZE);
683 status = sx_in(bp, CD186x_RCSR);
685 dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
686 if (status & RCSR_OE) {
688 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Overrun. Total %ld overruns.\n",
689 board_No(bp), port_No(port), port->overrun);
691 status &= port->mark_mask;
693 /* This flip buffer check needs to be below the reading of the
694 status register to reset the chip's IRQ.... */
695 if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
696 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n",
697 board_No(bp), port_No(port));
702 ch = sx_in(bp, CD186x_RDR);
707 if (status & RCSR_TOUT) {
708 printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
709 board_No(bp), port_No(port));
713 } else if (status & RCSR_BREAK) {
714 dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
715 board_No(bp), port_No(port));
716 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
717 if (port->flags & ASYNC_SAK)
720 } else if (status & RCSR_PE)
721 *tty->flip.flag_buf_ptr++ = TTY_PARITY;
723 else if (status & RCSR_FE)
724 *tty->flip.flag_buf_ptr++ = TTY_FRAME;
726 else if (status & RCSR_OE)
727 *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
730 *tty->flip.flag_buf_ptr++ = 0;
732 *tty->flip.char_buf_ptr++ = ch;
734 schedule_delayed_work(&tty->flip.work, 1);
740 static inline void sx_receive(struct specialix_board * bp)
742 struct specialix_port *port;
743 struct tty_struct *tty;
748 if (!(port = sx_get_port(bp, "Receive"))) {
749 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
755 count = sx_in(bp, CD186x_RDCR);
756 dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
757 port->hits[count > 8 ? 9 : count]++;
760 if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
761 printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n",
762 board_No(bp), port_No(port));
765 *tty->flip.char_buf_ptr++ = sx_in(bp, CD186x_RDR);
766 *tty->flip.flag_buf_ptr++ = 0;
769 schedule_delayed_work(&tty->flip.work, 1);
775 static inline void sx_transmit(struct specialix_board * bp)
777 struct specialix_port *port;
778 struct tty_struct *tty;
782 if (!(port = sx_get_port(bp, "Transmit"))) {
786 dprintk (SX_DEBUG_TX, "port: %p\n", port);
789 if (port->IER & IER_TXEMPTY) {
791 sx_out(bp, CD186x_CAR, port_No(port));
792 port->IER &= ~IER_TXEMPTY;
793 sx_out(bp, CD186x_IER, port->IER);
798 if ((port->xmit_cnt <= 0 && !port->break_length)
799 || tty->stopped || tty->hw_stopped) {
800 sx_out(bp, CD186x_CAR, port_No(port));
801 port->IER &= ~IER_TXRDY;
802 sx_out(bp, CD186x_IER, port->IER);
807 if (port->break_length) {
808 if (port->break_length > 0) {
809 if (port->COR2 & COR2_ETC) {
810 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
811 sx_out(bp, CD186x_TDR, CD186x_C_SBRK);
812 port->COR2 &= ~COR2_ETC;
814 count = min_t(int, port->break_length, 0xff);
815 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
816 sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
817 sx_out(bp, CD186x_TDR, count);
818 if (!(port->break_length -= count))
819 port->break_length--;
821 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
822 sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
823 sx_out(bp, CD186x_COR2, port->COR2);
825 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
826 port->break_length = 0;
833 count = CD186x_NFIFO;
835 sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
836 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
837 if (--port->xmit_cnt <= 0)
839 } while (--count > 0);
841 if (port->xmit_cnt <= 0) {
842 sx_out(bp, CD186x_CAR, port_No(port));
843 port->IER &= ~IER_TXRDY;
844 sx_out(bp, CD186x_IER, port->IER);
846 if (port->xmit_cnt <= port->wakeup_chars)
847 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
853 static inline void sx_check_modem(struct specialix_board * bp)
855 struct specialix_port *port;
856 struct tty_struct *tty;
860 dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
861 if (!(port = sx_get_port(bp, "Modem")))
866 mcr = sx_in(bp, CD186x_MCR);
867 printk ("mcr = %02x.\n", mcr);
869 if ((mcr & MCR_CDCHG)) {
870 dprintk (SX_DEBUG_SIGNALS, "CD just changed... ");
871 msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
873 dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
874 wake_up_interruptible(&port->open_wait);
876 dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n");
877 schedule_work(&port->tqueue_hangup);
881 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
882 if (mcr & MCR_CTSCHG) {
883 if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
885 port->IER |= IER_TXRDY;
886 if (port->xmit_cnt <= port->wakeup_chars)
887 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
890 port->IER &= ~IER_TXRDY;
892 sx_out(bp, CD186x_IER, port->IER);
894 if (mcr & MCR_DSSXHG) {
895 if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
897 port->IER |= IER_TXRDY;
898 if (port->xmit_cnt <= port->wakeup_chars)
899 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
902 port->IER &= ~IER_TXRDY;
904 sx_out(bp, CD186x_IER, port->IER);
906 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
908 /* Clear change bits */
909 sx_out(bp, CD186x_MCR, 0);
913 /* The main interrupt processing routine */
914 static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
916 unsigned char status;
918 struct specialix_board *bp;
919 unsigned long loop = 0;
926 spin_lock_irqsave(&bp->lock, flags);
928 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);
929 if (!bp || !(bp->flags & SX_BOARD_ACTIVE)) {
930 dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq);
931 spin_unlock_irqrestore(&bp->lock, flags);
938 while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
942 if (status & SRSR_RREQint) {
943 ack = sx_in(bp, CD186x_RRAR);
945 if (ack == (SX_ID | GIVR_IT_RCV))
947 else if (ack == (SX_ID | GIVR_IT_REXC))
950 printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
951 board_No(bp), status, ack);
953 } else if (status & SRSR_TREQint) {
954 ack = sx_in(bp, CD186x_TRAR);
956 if (ack == (SX_ID | GIVR_IT_TX))
959 printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
960 board_No(bp), status, ack, port_No (sx_get_port (bp, "Int")));
961 } else if (status & SRSR_MREQint) {
962 ack = sx_in(bp, CD186x_MRAR);
964 if (ack == (SX_ID | GIVR_IT_MODEM))
967 printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
968 board_No(bp), status, ack);
972 sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
975 outb (bp->reg, bp->base + SX_ADDR_REG);
976 spin_unlock_irqrestore(&bp->lock, flags);
983 * Routines for open & close processing.
986 static void turn_ints_off (struct specialix_board *bp)
991 if (bp->flags & SX_BOARD_IS_PCI) {
992 /* This was intended for enabeling the interrupt on the
993 * PCI card. However it seems that it's already enabled
994 * and as PCI interrupts can be shared, there is no real
995 * reason to have to turn it off. */
998 spin_lock_irqsave(&bp->lock, flags);
999 (void) sx_in_off (bp, 0); /* Turn off interrupts. */
1000 spin_unlock_irqrestore(&bp->lock, flags);
1005 static void turn_ints_on (struct specialix_board *bp)
1007 unsigned long flags;
1011 if (bp->flags & SX_BOARD_IS_PCI) {
1012 /* play with the PCI chip. See comment above. */
1014 spin_lock_irqsave(&bp->lock, flags);
1015 (void) sx_in (bp, 0); /* Turn ON interrupts. */
1016 spin_unlock_irqrestore(&bp->lock, flags);
1022 /* Called with disabled interrupts */
1023 static inline int sx_setup_board(struct specialix_board * bp)
1027 if (bp->flags & SX_BOARD_ACTIVE)
1030 if (bp->flags & SX_BOARD_IS_PCI)
1031 error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT | SA_SHIRQ, "specialix IO8+", bp);
1033 error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT, "specialix IO8+", bp);
1039 bp->flags |= SX_BOARD_ACTIVE;
1045 /* Called with disabled interrupts */
1046 static inline void sx_shutdown_board(struct specialix_board *bp)
1050 if (!(bp->flags & SX_BOARD_ACTIVE)) {
1055 bp->flags &= ~SX_BOARD_ACTIVE;
1057 dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
1058 bp->irq, board_No (bp));
1059 free_irq(bp->irq, bp);
1069 * Setting up port characteristics.
1070 * Must be called with disabled interrupts
1072 static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
1074 struct tty_struct *tty;
1077 unsigned char cor1 = 0, cor3 = 0;
1078 unsigned char mcor1 = 0, mcor2 = 0;
1079 static unsigned long again;
1080 unsigned long flags;
1084 if (!(tty = port->tty) || !tty->termios) {
1091 /* Select port on the board */
1092 spin_lock_irqsave(&bp->lock, flags);
1093 sx_out(bp, CD186x_CAR, port_No(port));
1095 /* The Specialix board doens't implement the RTS lines.
1096 They are used to set the IRQ level. Don't touch them. */
1097 if (SX_CRTSCTS(tty))
1098 port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1100 port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1101 spin_unlock_irqrestore(&bp->lock, flags);
1102 dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
1105 if (baud & CBAUDEX) {
1107 if (baud < 1 || baud > 2)
1108 port->tty->termios->c_cflag &= ~CBAUDEX;
1113 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1115 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1120 if (!baud_table[baud]) {
1121 /* Drop DTR & exit */
1122 dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
1123 if (!SX_CRTSCTS (tty)) {
1124 port -> MSVR &= ~ MSVR_DTR;
1125 spin_lock_irqsave(&bp->lock, flags);
1126 sx_out(bp, CD186x_MSVR, port->MSVR );
1127 spin_unlock_irqrestore(&bp->lock, flags);
1130 dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1134 if (!SX_CRTSCTS (tty)) {
1135 port ->MSVR |= MSVR_DTR;
1140 * Now we must calculate some speed depended things
1143 /* Set baud rate for port */
1144 tmp = port->custom_divisor ;
1146 printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n"
1147 "This is an untested option, please be carefull.\n",
1148 port_No (port), tmp);
1150 tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
1151 CD186x_TPC/2) / CD186x_TPC);
1153 if ((tmp < 0x10) && time_before(again, jiffies)) {
1154 again = jiffies + HZ * 60;
1155 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1157 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1158 "Performance degradation is possible.\n"
1159 "Read specialix.txt for more info.\n",
1160 port_No (port), tmp);
1162 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1163 "Warning: overstressing Cirrus chip. "
1164 "This might not work.\n"
1165 "Read specialix.txt for more info.\n",
1166 port_No (port), tmp);
1169 spin_lock_irqsave(&bp->lock, flags);
1170 sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1171 sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1172 sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1173 sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1174 spin_unlock_irqrestore(&bp->lock, flags);
1175 if (port->custom_divisor) {
1176 baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
1177 baud = ( baud + 5 ) / 10;
1179 baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */
1181 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1182 tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1183 port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1184 SERIAL_XMIT_SIZE - 1 : tmp);
1186 /* Receiver timeout will be transmission time for 1.5 chars */
1187 tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1188 tmp = (tmp > 0xff) ? 0xff : tmp;
1189 spin_lock_irqsave(&bp->lock, flags);
1190 sx_out(bp, CD186x_RTPR, tmp);
1191 spin_unlock_irqrestore(&bp->lock, flags);
1192 switch (C_CSIZE(tty)) {
1210 cor1 |= COR1_IGNORE;
1211 if (C_PARENB(tty)) {
1212 cor1 |= COR1_NORMPAR;
1216 cor1 &= ~COR1_IGNORE;
1218 /* Set marking of some errors */
1219 port->mark_mask = RCSR_OE | RCSR_TOUT;
1221 port->mark_mask |= RCSR_FE | RCSR_PE;
1222 if (I_BRKINT(tty) || I_PARMRK(tty))
1223 port->mark_mask |= RCSR_BREAK;
1225 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1226 if (I_IGNBRK(tty)) {
1227 port->mark_mask &= ~RCSR_BREAK;
1229 /* Real raw mode. Ignore all */
1230 port->mark_mask &= ~RCSR_OE;
1232 /* Enable Hardware Flow Control */
1233 if (C_CRTSCTS(tty)) {
1234 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1235 port->IER |= IER_DSR | IER_CTS;
1236 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1237 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1238 spin_lock_irqsave(&bp->lock, flags);
1239 tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
1240 spin_unlock_irqrestore(&bp->lock, flags);
1242 port->COR2 |= COR2_CTSAE;
1245 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1246 /* Some people reported that it works, but I still doubt it */
1248 port->COR2 |= COR2_TXIBE;
1249 cor3 |= (COR3_FCT | COR3_SCDE);
1251 port->COR2 |= COR2_IXM;
1252 spin_lock_irqsave(&bp->lock, flags);
1253 sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1254 sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1255 sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1256 sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1257 spin_unlock_irqrestore(&bp->lock, flags);
1259 if (!C_CLOCAL(tty)) {
1260 /* Enable CD check */
1261 port->IER |= IER_CD;
1262 mcor1 |= MCOR1_CDZD;
1263 mcor2 |= MCOR2_CDOD;
1267 /* Enable receiver */
1268 port->IER |= IER_RXD;
1270 /* Set input FIFO size (1-8 bytes) */
1272 /* Setting up CD186x channel registers */
1273 spin_lock_irqsave(&bp->lock, flags);
1274 sx_out(bp, CD186x_COR1, cor1);
1275 sx_out(bp, CD186x_COR2, port->COR2);
1276 sx_out(bp, CD186x_COR3, cor3);
1277 spin_unlock_irqrestore(&bp->lock, flags);
1278 /* Make CD186x know about registers change */
1280 spin_lock_irqsave(&bp->lock, flags);
1281 sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1282 /* Setting up modem option registers */
1283 dprintk (SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2);
1284 sx_out(bp, CD186x_MCOR1, mcor1);
1285 sx_out(bp, CD186x_MCOR2, mcor2);
1286 spin_unlock_irqrestore(&bp->lock, flags);
1287 /* Enable CD186x transmitter & receiver */
1289 spin_lock_irqsave(&bp->lock, flags);
1290 sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1291 /* Enable interrupts */
1292 sx_out(bp, CD186x_IER, port->IER);
1293 /* And finally set the modem lines... */
1294 sx_out(bp, CD186x_MSVR, port->MSVR);
1295 spin_unlock_irqrestore(&bp->lock, flags);
1301 /* Must be called with interrupts enabled */
1302 static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port)
1304 unsigned long flags;
1308 if (port->flags & ASYNC_INITIALIZED) {
1313 if (!port->xmit_buf) {
1314 /* We may sleep in get_zeroed_page() */
1317 if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
1322 if (port->xmit_buf) {
1325 return -ERESTARTSYS;
1327 port->xmit_buf = (unsigned char *) tmp;
1330 spin_lock_irqsave(&port->lock, flags);
1333 clear_bit(TTY_IO_ERROR, &port->tty->flags);
1335 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1336 sx_change_speed(bp, port);
1337 port->flags |= ASYNC_INITIALIZED;
1339 spin_unlock_irqrestore(&port->lock, flags);
1347 /* Must be called with interrupts disabled */
1348 static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port)
1350 struct tty_struct *tty;
1352 unsigned long flags;
1356 if (!(port->flags & ASYNC_INITIALIZED)) {
1361 if (sx_debug & SX_DEBUG_FIFO) {
1362 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
1363 board_No(bp), port_No(port), port->overrun);
1364 for (i = 0; i < 10; i++) {
1365 dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1367 dprintk(SX_DEBUG_FIFO, "].\n");
1370 if (port->xmit_buf) {
1371 free_page((unsigned long) port->xmit_buf);
1372 port->xmit_buf = NULL;
1376 spin_lock_irqsave(&bp->lock, flags);
1377 sx_out(bp, CD186x_CAR, port_No(port));
1379 if (!(tty = port->tty) || C_HUPCL(tty)) {
1381 sx_out(bp, CD186x_MSVDTR, 0);
1383 spin_unlock_irqrestore(&bp->lock, flags);
1386 spin_lock_irqsave(&bp->lock, flags);
1387 sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1388 /* Disable all interrupts from this port */
1390 sx_out(bp, CD186x_IER, port->IER);
1391 spin_unlock_irqrestore(&bp->lock, flags);
1393 set_bit(TTY_IO_ERROR, &tty->flags);
1394 port->flags &= ~ASYNC_INITIALIZED;
1397 sx_shutdown_board(bp);
1402 static int block_til_ready(struct tty_struct *tty, struct file * filp,
1403 struct specialix_port *port)
1405 DECLARE_WAITQUEUE(wait, current);
1406 struct specialix_board *bp = port_Board(port);
1410 unsigned long flags;
1415 * If the device is in the middle of being closed, then block
1416 * until it's done, and then try again.
1418 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
1419 interruptible_sleep_on(&port->close_wait);
1420 if (port->flags & ASYNC_HUP_NOTIFY) {
1425 return -ERESTARTSYS;
1430 * If non-blocking mode is set, or the port is not enabled,
1431 * then make the check up front and then exit.
1433 if ((filp->f_flags & O_NONBLOCK) ||
1434 (tty->flags & (1 << TTY_IO_ERROR))) {
1435 port->flags |= ASYNC_NORMAL_ACTIVE;
1444 * Block waiting for the carrier detect and the line to become
1445 * free (i.e., not in use by the callout). While we are in
1446 * this loop, info->count is dropped by one, so that
1447 * rs_close() knows when to free things. We restore it upon
1448 * exit, either normal or abnormal.
1451 add_wait_queue(&port->open_wait, &wait);
1452 spin_lock_irqsave(&port->lock, flags);
1453 if (!tty_hung_up_p(filp)) {
1456 spin_unlock_irqrestore(&port->lock, flags);
1457 port->blocked_open++;
1459 spin_lock_irqsave(&bp->lock, flags);
1460 sx_out(bp, CD186x_CAR, port_No(port));
1461 CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1462 if (SX_CRTSCTS (tty)) {
1464 port->MSVR |= MSVR_DTR; /* WTF? */
1465 sx_out (bp, CD186x_MSVR, port->MSVR);
1468 port->MSVR |= MSVR_DTR;
1469 sx_out (bp, CD186x_MSVR, port->MSVR);
1471 spin_unlock_irqrestore(&bp->lock, flags);
1472 set_current_state(TASK_INTERRUPTIBLE);
1473 if (tty_hung_up_p(filp) ||
1474 !(port->flags & ASYNC_INITIALIZED)) {
1475 if (port->flags & ASYNC_HUP_NOTIFY)
1478 retval = -ERESTARTSYS;
1481 if (!(port->flags & ASYNC_CLOSING) &&
1484 if (signal_pending(current)) {
1485 retval = -ERESTARTSYS;
1491 set_current_state(TASK_RUNNING);
1492 remove_wait_queue(&port->open_wait, &wait);
1493 spin_lock_irqsave(&port->lock, flags);
1494 if (!tty_hung_up_p(filp)) {
1497 port->blocked_open--;
1498 spin_unlock_irqrestore(&port->lock, flags);
1504 port->flags |= ASYNC_NORMAL_ACTIVE;
1510 static int sx_open(struct tty_struct * tty, struct file * filp)
1514 struct specialix_port * port;
1515 struct specialix_board * bp;
1517 unsigned long flags;
1521 board = SX_BOARD(tty->index);
1523 if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1528 bp = &sx_board[board];
1529 port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1531 for (i = 0; i < 10; i++)
1534 dprintk (SX_DEBUG_OPEN, "Board = %d, bp = %p, port = %p, portno = %d.\n",
1535 board, bp, port, SX_PORT(tty->index));
1537 if (sx_paranoia_check(port, tty->name, "sx_open")) {
1542 if ((error = sx_setup_board(bp))) {
1547 spin_lock_irqsave(&bp->lock, flags);
1550 tty->driver_data = port;
1552 spin_unlock_irqrestore(&bp->lock, flags);
1554 if ((error = sx_setup_port(bp, port))) {
1559 if ((error = block_til_ready(tty, filp, port))) {
1569 static void sx_close(struct tty_struct * tty, struct file * filp)
1571 struct specialix_port *port = (struct specialix_port *) tty->driver_data;
1572 struct specialix_board *bp;
1573 unsigned long flags;
1574 unsigned long timeout;
1577 if (!port || sx_paranoia_check(port, tty->name, "close")) {
1581 spin_lock_irqsave(&port->lock, flags);
1583 if (tty_hung_up_p(filp)) {
1584 spin_unlock_irqrestore(&port->lock, flags);
1589 bp = port_Board(port);
1590 if ((tty->count == 1) && (port->count != 1)) {
1591 printk(KERN_ERR "sx%d: sx_close: bad port count;"
1592 " tty->count is 1, port count is %d\n",
1593 board_No(bp), port->count);
1597 if (port->count > 1) {
1601 spin_unlock_irqrestore(&port->lock, flags);
1606 port->flags |= ASYNC_CLOSING;
1608 * Now we wait for the transmit buffer to clear; and we notify
1609 * the line discipline to only process XON/XOFF characters.
1612 spin_unlock_irqrestore(&port->lock, flags);
1613 dprintk (SX_DEBUG_OPEN, "Closing\n");
1614 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
1615 tty_wait_until_sent(tty, port->closing_wait);
1618 * At this point we stop accepting input. To do this, we
1619 * disable the receive line status interrupts, and tell the
1620 * interrupt driver to stop checking the data ready bit in the
1621 * line status register.
1623 dprintk (SX_DEBUG_OPEN, "Closed\n");
1624 port->IER &= ~IER_RXD;
1625 if (port->flags & ASYNC_INITIALIZED) {
1626 port->IER &= ~IER_TXRDY;
1627 port->IER |= IER_TXEMPTY;
1628 spin_lock_irqsave(&bp->lock, flags);
1629 sx_out(bp, CD186x_CAR, port_No(port));
1630 sx_out(bp, CD186x_IER, port->IER);
1631 spin_unlock_irqrestore(&bp->lock, flags);
1633 * Before we drop DTR, make sure the UART transmitter
1634 * has completely drained; this is especially
1635 * important if there is a transmit FIFO!
1637 timeout = jiffies+HZ;
1638 while(port->IER & IER_TXEMPTY) {
1639 set_current_state (TASK_INTERRUPTIBLE);
1640 msleep_interruptible(jiffies_to_msecs(port->timeout));
1641 if (time_after(jiffies, timeout)) {
1642 printk (KERN_INFO "Timeout waiting for close\n");
1649 if (--bp->count < 0) {
1650 printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1651 board_No(bp), bp->count, tty->index);
1654 if (--port->count < 0) {
1655 printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n",
1656 board_No(bp), port_No(port), port->count);
1660 sx_shutdown_port(bp, port);
1661 if (tty->driver->flush_buffer)
1662 tty->driver->flush_buffer(tty);
1663 tty_ldisc_flush(tty);
1664 spin_lock_irqsave(&port->lock, flags);
1668 spin_unlock_irqrestore(&port->lock, flags);
1669 if (port->blocked_open) {
1670 if (port->close_delay) {
1671 msleep_interruptible(jiffies_to_msecs(port->close_delay));
1673 wake_up_interruptible(&port->open_wait);
1675 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1676 wake_up_interruptible(&port->close_wait);
1682 static int sx_write(struct tty_struct * tty,
1683 const unsigned char *buf, int count)
1685 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1686 struct specialix_board *bp;
1688 unsigned long flags;
1691 if (sx_paranoia_check(port, tty->name, "sx_write")) {
1696 bp = port_Board(port);
1698 if (!tty || !port->xmit_buf || !tmp_buf) {
1704 spin_lock_irqsave(&port->lock, flags);
1705 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1706 SERIAL_XMIT_SIZE - port->xmit_head));
1708 spin_unlock_irqrestore(&port->lock, flags);
1711 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1712 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1713 port->xmit_cnt += c;
1714 spin_unlock_irqrestore(&port->lock, flags);
1721 spin_lock_irqsave(&bp->lock, flags);
1722 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1723 !(port->IER & IER_TXRDY)) {
1724 port->IER |= IER_TXRDY;
1725 sx_out(bp, CD186x_CAR, port_No(port));
1726 sx_out(bp, CD186x_IER, port->IER);
1728 spin_unlock_irqrestore(&bp->lock, flags);
1735 static void sx_put_char(struct tty_struct * tty, unsigned char ch)
1737 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1738 unsigned long flags;
1739 struct specialix_board * bp;
1743 if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1747 dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1748 if (!tty || !port->xmit_buf) {
1752 bp = port_Board(port);
1753 spin_lock_irqsave(&port->lock, flags);
1755 dprintk (SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", port->xmit_cnt, port->xmit_buf);
1756 if ((port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) || (!port->xmit_buf)) {
1757 spin_unlock_irqrestore(&port->lock, flags);
1758 dprintk (SX_DEBUG_TX, "Exit size\n");
1762 dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
1763 port->xmit_buf[port->xmit_head++] = ch;
1764 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1766 spin_unlock_irqrestore(&port->lock, flags);
1772 static void sx_flush_chars(struct tty_struct * tty)
1774 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1775 unsigned long flags;
1776 struct specialix_board * bp = port_Board(port);
1780 if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1784 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1789 spin_lock_irqsave(&bp->lock, flags);
1790 port->IER |= IER_TXRDY;
1791 sx_out(port_Board(port), CD186x_CAR, port_No(port));
1792 sx_out(port_Board(port), CD186x_IER, port->IER);
1793 spin_unlock_irqrestore(&bp->lock, flags);
1799 static int sx_write_room(struct tty_struct * tty)
1801 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1806 if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1811 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1820 static int sx_chars_in_buffer(struct tty_struct *tty)
1822 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1826 if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
1831 return port->xmit_cnt;
1835 static void sx_flush_buffer(struct tty_struct *tty)
1837 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1838 unsigned long flags;
1839 struct specialix_board * bp;
1843 if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
1848 bp = port_Board(port);
1849 spin_lock_irqsave(&port->lock, flags);
1850 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1851 spin_unlock_irqrestore(&port->lock, flags);
1858 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1860 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1861 struct specialix_board * bp;
1862 unsigned char status;
1863 unsigned int result;
1864 unsigned long flags;
1868 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1873 bp = port_Board(port);
1874 spin_lock_irqsave (&bp->lock, flags);
1875 sx_out(bp, CD186x_CAR, port_No(port));
1876 status = sx_in(bp, CD186x_MSVR);
1877 spin_unlock_irqrestore(&bp->lock, flags);
1878 dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1879 port_No(port), status, sx_in (bp, CD186x_CAR));
1880 dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1881 if (SX_CRTSCTS(port->tty)) {
1882 result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
1883 | ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1884 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1885 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1886 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1888 result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
1889 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1890 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1891 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1892 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1901 static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1902 unsigned int set, unsigned int clear)
1904 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1905 unsigned long flags;
1906 struct specialix_board *bp;
1910 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1915 bp = port_Board(port);
1917 spin_lock_irqsave(&port->lock, flags);
1918 /* if (set & TIOCM_RTS)
1919 port->MSVR |= MSVR_RTS; */
1920 /* if (set & TIOCM_DTR)
1921 port->MSVR |= MSVR_DTR; */
1923 if (SX_CRTSCTS(port->tty)) {
1924 if (set & TIOCM_RTS)
1925 port->MSVR |= MSVR_DTR;
1927 if (set & TIOCM_DTR)
1928 port->MSVR |= MSVR_DTR;
1931 /* if (clear & TIOCM_RTS)
1932 port->MSVR &= ~MSVR_RTS; */
1933 /* if (clear & TIOCM_DTR)
1934 port->MSVR &= ~MSVR_DTR; */
1935 if (SX_CRTSCTS(port->tty)) {
1936 if (clear & TIOCM_RTS)
1937 port->MSVR &= ~MSVR_DTR;
1939 if (clear & TIOCM_DTR)
1940 port->MSVR &= ~MSVR_DTR;
1942 spin_lock_irqsave(&bp->lock, flags);
1943 sx_out(bp, CD186x_CAR, port_No(port));
1944 sx_out(bp, CD186x_MSVR, port->MSVR);
1945 spin_unlock_irqrestore(&bp->lock, flags);
1946 spin_unlock_irqrestore(&port->lock, flags);
1952 static inline void sx_send_break(struct specialix_port * port, unsigned long length)
1954 struct specialix_board *bp = port_Board(port);
1955 unsigned long flags;
1959 spin_lock_irqsave (&port->lock, flags);
1960 port->break_length = SPECIALIX_TPS / HZ * length;
1961 port->COR2 |= COR2_ETC;
1962 port->IER |= IER_TXRDY;
1963 spin_lock_irqsave(&bp->lock, flags);
1964 sx_out(bp, CD186x_CAR, port_No(port));
1965 sx_out(bp, CD186x_COR2, port->COR2);
1966 sx_out(bp, CD186x_IER, port->IER);
1967 spin_unlock_irqrestore(&bp->lock, flags);
1968 spin_unlock_irqrestore (&port->lock, flags);
1970 spin_lock_irqsave(&bp->lock, flags);
1971 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1972 spin_unlock_irqrestore(&bp->lock, flags);
1979 static inline int sx_set_serial_info(struct specialix_port * port,
1980 struct serial_struct __user * newinfo)
1982 struct serial_struct tmp;
1983 struct specialix_board *bp = port_Board(port);
1988 if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1993 if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
1999 if ((tmp.irq != bp->irq) ||
2000 (tmp.port != bp->base) ||
2001 (tmp.type != PORT_CIRRUS) ||
2002 (tmp.baud_base != (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) ||
2003 (tmp.custom_divisor != 0) ||
2004 (tmp.xmit_fifo_size != CD186x_NFIFO) ||
2005 (tmp.flags & ~SPECIALIX_LEGAL_FLAGS)) {
2011 change_speed = ((port->flags & ASYNC_SPD_MASK) !=
2012 (tmp.flags & ASYNC_SPD_MASK));
2013 change_speed |= (tmp.custom_divisor != port->custom_divisor);
2015 if (!capable(CAP_SYS_ADMIN)) {
2016 if ((tmp.close_delay != port->close_delay) ||
2017 (tmp.closing_wait != port->closing_wait) ||
2018 ((tmp.flags & ~ASYNC_USR_MASK) !=
2019 (port->flags & ~ASYNC_USR_MASK))) {
2023 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
2024 (tmp.flags & ASYNC_USR_MASK));
2025 port->custom_divisor = tmp.custom_divisor;
2027 port->flags = ((port->flags & ~ASYNC_FLAGS) |
2028 (tmp.flags & ASYNC_FLAGS));
2029 port->close_delay = tmp.close_delay;
2030 port->closing_wait = tmp.closing_wait;
2031 port->custom_divisor = tmp.custom_divisor;
2034 sx_change_speed(bp, port);
2041 static inline int sx_get_serial_info(struct specialix_port * port,
2042 struct serial_struct __user *retinfo)
2044 struct serial_struct tmp;
2045 struct specialix_board *bp = port_Board(port);
2050 if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
2054 memset(&tmp, 0, sizeof(tmp));
2055 tmp.type = PORT_CIRRUS;
2056 tmp.line = port - sx_port;
2057 tmp.port = bp->base;
2059 tmp.flags = port->flags;
2060 tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
2061 tmp.close_delay = port->close_delay * HZ/100;
2062 tmp.closing_wait = port->closing_wait * HZ/100;
2063 tmp.custom_divisor = port->custom_divisor;
2064 tmp.xmit_fifo_size = CD186x_NFIFO;
2065 if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
2075 static int sx_ioctl(struct tty_struct * tty, struct file * filp,
2076 unsigned int cmd, unsigned long arg)
2078 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2080 void __user *argp = (void __user *)arg;
2084 if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
2090 case TCSBRK: /* SVID version: non-zero arg --> no break */
2091 retval = tty_check_change(tty);
2096 tty_wait_until_sent(tty, 0);
2098 sx_send_break(port, HZ/4); /* 1/4 second */
2100 case TCSBRKP: /* support for POSIX tcsendbreak() */
2101 retval = tty_check_change(tty);
2106 tty_wait_until_sent(tty, 0);
2107 sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
2111 if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) {
2118 if (get_user(arg, (unsigned long __user *) argp)) {
2122 tty->termios->c_cflag =
2123 ((tty->termios->c_cflag & ~CLOCAL) |
2124 (arg ? CLOCAL : 0));
2129 return sx_get_serial_info(port, argp);
2132 return sx_set_serial_info(port, argp);
2135 return -ENOIOCTLCMD;
2142 static void sx_throttle(struct tty_struct * tty)
2144 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2145 struct specialix_board *bp;
2146 unsigned long flags;
2150 if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
2155 bp = port_Board(port);
2157 /* Use DTR instead of RTS ! */
2158 if (SX_CRTSCTS (tty))
2159 port->MSVR &= ~MSVR_DTR;
2161 /* Auch!!! I think the system shouldn't call this then. */
2162 /* Or maybe we're supposed (allowed?) to do our side of hw
2163 handshake anyway, even when hardware handshake is off.
2164 When you see this in your logs, please report.... */
2165 printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
2168 spin_lock_irqsave(&bp->lock, flags);
2169 sx_out(bp, CD186x_CAR, port_No(port));
2170 spin_unlock_irqrestore(&bp->lock, flags);
2172 spin_unlock_irqrestore(&bp->lock, flags);
2174 spin_lock_irqsave(&bp->lock, flags);
2175 sx_out(bp, CD186x_CCR, CCR_SSCH2);
2176 spin_unlock_irqrestore(&bp->lock, flags);
2179 spin_lock_irqsave(&bp->lock, flags);
2180 sx_out(bp, CD186x_MSVR, port->MSVR);
2181 spin_unlock_irqrestore(&bp->lock, flags);
2187 static void sx_unthrottle(struct tty_struct * tty)
2189 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2190 struct specialix_board *bp;
2191 unsigned long flags;
2195 if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
2200 bp = port_Board(port);
2202 spin_lock_irqsave(&port->lock, flags);
2203 /* XXXX Use DTR INSTEAD???? */
2204 if (SX_CRTSCTS(tty)) {
2205 port->MSVR |= MSVR_DTR;
2206 } /* Else clause: see remark in "sx_throttle"... */
2207 spin_lock_irqsave(&bp->lock, flags);
2208 sx_out(bp, CD186x_CAR, port_No(port));
2209 spin_unlock_irqrestore(&bp->lock, flags);
2211 spin_unlock_irqrestore(&port->lock, flags);
2213 spin_lock_irqsave(&bp->lock, flags);
2214 sx_out(bp, CD186x_CCR, CCR_SSCH1);
2215 spin_unlock_irqrestore(&bp->lock, flags);
2217 spin_lock_irqsave(&port->lock, flags);
2219 spin_lock_irqsave(&bp->lock, flags);
2220 sx_out(bp, CD186x_MSVR, port->MSVR);
2221 spin_unlock_irqrestore(&bp->lock, flags);
2222 spin_unlock_irqrestore(&port->lock, flags);
2228 static void sx_stop(struct tty_struct * tty)
2230 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2231 struct specialix_board *bp;
2232 unsigned long flags;
2236 if (sx_paranoia_check(port, tty->name, "sx_stop")) {
2241 bp = port_Board(port);
2243 spin_lock_irqsave(&port->lock, flags);
2244 port->IER &= ~IER_TXRDY;
2245 spin_lock_irqsave(&bp->lock, flags);
2246 sx_out(bp, CD186x_CAR, port_No(port));
2247 sx_out(bp, CD186x_IER, port->IER);
2248 spin_unlock_irqrestore(&bp->lock, flags);
2249 spin_unlock_irqrestore(&port->lock, flags);
2255 static void sx_start(struct tty_struct * tty)
2257 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2258 struct specialix_board *bp;
2259 unsigned long flags;
2263 if (sx_paranoia_check(port, tty->name, "sx_start")) {
2268 bp = port_Board(port);
2270 spin_lock_irqsave(&port->lock, flags);
2271 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2272 port->IER |= IER_TXRDY;
2273 spin_lock_irqsave(&bp->lock, flags);
2274 sx_out(bp, CD186x_CAR, port_No(port));
2275 sx_out(bp, CD186x_IER, port->IER);
2276 spin_unlock_irqrestore(&bp->lock, flags);
2278 spin_unlock_irqrestore(&port->lock, flags);
2285 * This routine is called from the work-queue when the interrupt
2286 * routine has signalled that a hangup has occurred. The path of
2287 * hangup processing is:
2289 * serial interrupt routine -> (workqueue) ->
2290 * do_sx_hangup() -> tty->hangup() -> sx_hangup()
2293 static void do_sx_hangup(void *private_)
2295 struct specialix_port *port = (struct specialix_port *) private_;
2296 struct tty_struct *tty;
2302 tty_hangup(tty); /* FIXME: module removal race here */
2308 static void sx_hangup(struct tty_struct * tty)
2310 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2311 struct specialix_board *bp;
2312 unsigned long flags;
2316 if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2321 bp = port_Board(port);
2323 sx_shutdown_port(bp, port);
2324 spin_lock_irqsave(&port->lock, flags);
2326 bp->count -= port->count;
2327 if (bp->count < 0) {
2328 printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n",
2329 board_No(bp), bp->count, tty->index);
2333 port->flags &= ~ASYNC_NORMAL_ACTIVE;
2335 spin_unlock_irqrestore(&port->lock, flags);
2336 wake_up_interruptible(&port->open_wait);
2342 static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios)
2344 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2345 unsigned long flags;
2346 struct specialix_board * bp;
2348 if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2351 if (tty->termios->c_cflag == old_termios->c_cflag &&
2352 tty->termios->c_iflag == old_termios->c_iflag)
2355 bp = port_Board(port);
2356 spin_lock_irqsave(&port->lock, flags);
2357 sx_change_speed(port_Board(port), port);
2358 spin_unlock_irqrestore(&port->lock, flags);
2360 if ((old_termios->c_cflag & CRTSCTS) &&
2361 !(tty->termios->c_cflag & CRTSCTS)) {
2362 tty->hw_stopped = 0;
2368 static void do_softint(void *private_)
2370 struct specialix_port *port = (struct specialix_port *) private_;
2371 struct tty_struct *tty;
2375 if(!(tty = port->tty)) {
2380 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
2382 //wake_up_interruptible(&tty->write_wait);
2388 static struct tty_operations sx_ops = {
2392 .put_char = sx_put_char,
2393 .flush_chars = sx_flush_chars,
2394 .write_room = sx_write_room,
2395 .chars_in_buffer = sx_chars_in_buffer,
2396 .flush_buffer = sx_flush_buffer,
2398 .throttle = sx_throttle,
2399 .unthrottle = sx_unthrottle,
2400 .set_termios = sx_set_termios,
2403 .hangup = sx_hangup,
2404 .tiocmget = sx_tiocmget,
2405 .tiocmset = sx_tiocmset,
2408 static int sx_init_drivers(void)
2415 specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT);
2416 if (!specialix_driver) {
2417 printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n");
2422 if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
2423 printk(KERN_ERR "sx: Couldn't get free page.\n");
2424 put_tty_driver(specialix_driver);
2428 specialix_driver->owner = THIS_MODULE;
2429 specialix_driver->name = "ttyW";
2430 specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
2431 specialix_driver->type = TTY_DRIVER_TYPE_SERIAL;
2432 specialix_driver->subtype = SERIAL_TYPE_NORMAL;
2433 specialix_driver->init_termios = tty_std_termios;
2434 specialix_driver->init_termios.c_cflag =
2435 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2436 specialix_driver->flags = TTY_DRIVER_REAL_RAW;
2437 tty_set_operations(specialix_driver, &sx_ops);
2439 if ((error = tty_register_driver(specialix_driver))) {
2440 put_tty_driver(specialix_driver);
2441 free_page((unsigned long)tmp_buf);
2442 printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2447 memset(sx_port, 0, sizeof(sx_port));
2448 for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2449 sx_port[i].magic = SPECIALIX_MAGIC;
2450 INIT_WORK(&sx_port[i].tqueue, do_softint, &sx_port[i]);
2451 INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup, &sx_port[i]);
2452 sx_port[i].close_delay = 50 * HZ/100;
2453 sx_port[i].closing_wait = 3000 * HZ/100;
2454 init_waitqueue_head(&sx_port[i].open_wait);
2455 init_waitqueue_head(&sx_port[i].close_wait);
2456 spin_lock_init(&sx_port[i].lock);
2463 static void sx_release_drivers(void)
2467 free_page((unsigned long)tmp_buf);
2468 tty_unregister_driver(specialix_driver);
2469 put_tty_driver(specialix_driver);
2474 * This routine must be called by kernel at boot time
2476 static int __init specialix_init(void)
2483 printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
2484 printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2485 #ifdef CONFIG_SPECIALIX_RTSCTS
2486 printk (KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
2488 printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2491 for (i = 0; i < SX_NBOARD; i++)
2492 sx_board[i].lock = SPIN_LOCK_UNLOCKED;
2494 if (sx_init_drivers()) {
2499 for (i = 0; i < SX_NBOARD; i++)
2500 if (sx_board[i].base && !sx_probe(&sx_board[i]))
2505 struct pci_dev *pdev = NULL;
2508 while (i < SX_NBOARD) {
2509 if (sx_board[i].flags & SX_BOARD_PRESENT) {
2513 pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
2514 PCI_DEVICE_ID_SPECIALIX_IO8,
2518 if (pci_enable_device(pdev))
2521 sx_board[i].irq = pdev->irq;
2523 sx_board[i].base = pci_resource_start (pdev, 2);
2525 sx_board[i].flags |= SX_BOARD_IS_PCI;
2526 if (!sx_probe(&sx_board[i]))
2533 sx_release_drivers();
2534 printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
2543 static int iobase[SX_NBOARD] = {0,};
2545 static int irq [SX_NBOARD] = {0,};
2547 module_param_array(iobase, int, NULL, 0);
2548 module_param_array(irq, int, NULL, 0);
2549 module_param(sx_debug, int, 0);
2550 module_param(sx_rxfifo, int, 0);
2551 #ifdef SPECIALIX_TIMER
2552 module_param(sx_poll, int, 0);
2556 * You can setup up to 4 boards.
2557 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2558 * You should specify the IRQs too in that case "irq=....,...".
2560 * More than 4 boards in one computer is not possible, as the card can
2561 * only use 4 different interrupts.
2564 static int __init specialix_init_module(void)
2570 init_MUTEX(&tmp_buf_sem); /* Init de the semaphore - pvdl */
2572 if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2573 for(i = 0; i < SX_NBOARD; i++) {
2574 sx_board[i].base = iobase[i];
2575 sx_board[i].irq = irq[i];
2576 sx_board[i].count= 0;
2582 return specialix_init();
2585 static void __exit specialix_exit_module(void)
2591 sx_release_drivers();
2592 for (i = 0; i < SX_NBOARD; i++)
2593 if (sx_board[i].flags & SX_BOARD_PRESENT)
2594 sx_release_io_range(&sx_board[i]);
2595 #ifdef SPECIALIX_TIMER
2596 del_timer (&missed_irq_timer);
2602 module_init(specialix_init_module);
2603 module_exit(specialix_exit_module);
2605 MODULE_LICENSE("GPL");