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_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,
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
365 static inline void sx_long_delay(unsigned long delay)
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)
381 if (bp->flags & SX_BOARD_IS_PCI)
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);
392 spin_lock_irqsave(&bp->lock, flags);
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);
402 /* Reset and setup CD186x chip */
403 static int sx_init_CD186x(struct specialix_board * bp)
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 */
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);
442 static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
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)
454 spin_unlock_irqrestore(&bp->lock, flags);
460 #ifdef SPECIALIX_TIMER
461 void missed_irq (unsigned long data)
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) &
472 spin_unlock_irqrestore(&bp->lock, flags);
474 printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
475 sx_interrupt (((struct specialix_board *)data)->irq,
478 missed_irq_timer.expires = jiffies + sx_poll;
479 add_timer (&missed_irq_timer);
485 /* Main probing routine, also sets irq. */
486 static int sx_probe(struct specialix_board *bp)
488 unsigned char val1, val2;
498 if (sx_check_io_range(bp)) {
503 /* Are the I/O ports here ? */
504 sx_out_off(bp, CD186x_PPRL, 0x5a);
506 val1 = sx_in_off(bp, CD186x_PPRL);
508 sx_out_off(bp, CD186x_PPRL, 0xa5);
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);
520 /* Check the DSR lines that Specialix uses as board
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
531 val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
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);
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 */
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",
570 printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
571 board_No(bp), bp->base);
576 printk (KERN_INFO "Started with irq=%d, but now have irq=%d.\n", bp->irq, irqs);
580 /* Reset CD186x again */
581 if (!sx_init_CD186x(bp)) {
586 sx_request_io_range(bp);
587 bp->flags |= SX_BOARD_PRESENT;
589 /* Chip revcode pkgtype
594 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
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);
617 printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
628 * Interrupt processing routines.
631 static inline void sx_mark_event(struct specialix_port * port, int event)
635 set_bit(event, &port->event);
636 schedule_work(&port->tqueue);
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);
660 printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
661 board_No(bp), what, channel);
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;
675 port = sx_get_port(bp, "Receive");
677 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
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) {
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));
704 ch = sx_in(bp, CD186x_RDR);
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));
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)
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;
732 *tty->flip.flag_buf_ptr++ = 0;
734 *tty->flip.char_buf_ptr++ = ch;
736 schedule_delayed_work(&tty->flip.work, 1);
742 static inline void sx_receive(struct specialix_board * bp)
744 struct specialix_port *port;
745 struct tty_struct *tty;
750 if (!(port = sx_get_port(bp, "Receive"))) {
751 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
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]++;
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));
767 *tty->flip.char_buf_ptr++ = sx_in(bp, CD186x_RDR);
768 *tty->flip.flag_buf_ptr++ = 0;
771 schedule_delayed_work(&tty->flip.work, 1);
777 static inline void sx_transmit(struct specialix_board * bp)
779 struct specialix_port *port;
780 struct tty_struct *tty;
784 if (!(port = sx_get_port(bp, "Transmit"))) {
788 dprintk (SX_DEBUG_TX, "port: %p\n", port);
791 if (port->IER & IER_TXEMPTY) {
793 sx_out(bp, CD186x_CAR, port_No(port));
794 port->IER &= ~IER_TXEMPTY;
795 sx_out(bp, CD186x_IER, port->IER);
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);
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--;
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);
827 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
828 port->break_length = 0;
835 count = CD186x_NFIFO;
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)
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);
855 static inline void sx_check_modem(struct specialix_board * bp)
857 struct specialix_port *port;
858 struct tty_struct *tty;
862 dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
863 if (!(port = sx_get_port(bp, "Modem")))
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;
875 dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
876 wake_up_interruptible(&port->open_wait);
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) {
887 port->IER |= IER_TXRDY;
888 if (port->xmit_cnt <= port->wakeup_chars)
889 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
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) {
899 port->IER |= IER_TXRDY;
900 if (port->xmit_cnt <= port->wakeup_chars)
901 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
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;
920 struct specialix_board *bp;
921 unsigned long loop = 0;
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);
940 while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
944 if (status & SRSR_RREQint) {
945 ack = sx_in(bp, CD186x_RRAR);
947 if (ack == (SX_ID | GIVR_IT_RCV))
949 else if (ack == (SX_ID | GIVR_IT_REXC))
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))
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))
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 */
977 outb (bp->reg, bp->base + SX_ADDR_REG);
978 spin_unlock_irqrestore(&bp->lock, flags);
985 * Routines for open & close processing.
988 static void turn_ints_off (struct specialix_board *bp)
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);
1007 static void turn_ints_on (struct specialix_board *bp)
1009 unsigned long flags;
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);
1024 /* Called with disabled interrupts */
1025 static inline int sx_setup_board(struct specialix_board * bp)
1029 if (bp->flags & SX_BOARD_ACTIVE)
1032 if (bp->flags & SX_BOARD_IS_PCI)
1033 error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT | SA_SHIRQ, "specialix IO8+", bp);
1035 error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT, "specialix IO8+", bp);
1041 bp->flags |= SX_BOARD_ACTIVE;
1047 /* Called with disabled interrupts */
1048 static inline void sx_shutdown_board(struct specialix_board *bp)
1052 if (!(bp->flags & SX_BOARD_ACTIVE)) {
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);
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;
1079 unsigned char cor1 = 0, cor3 = 0;
1080 unsigned char mcor1 = 0, mcor2 = 0;
1081 static unsigned long again;
1082 unsigned long flags;
1086 if (!(tty = port->tty) || !tty->termios) {
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);
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);
1107 if (baud & CBAUDEX) {
1109 if (baud < 1 || baud > 2)
1110 port->tty->termios->c_cflag &= ~CBAUDEX;
1115 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1117 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
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);
1132 dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
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 ;
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);
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 */
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);
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;
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)) {
1212 cor1 |= COR1_IGNORE;
1213 if (C_PARENB(tty)) {
1214 cor1 |= COR1_NORMPAR;
1218 cor1 &= ~COR1_IGNORE;
1220 /* Set marking of some errors */
1221 port->mark_mask = RCSR_OE | RCSR_TOUT;
1223 port->mark_mask |= RCSR_FE | RCSR_PE;
1224 if (I_BRKINT(tty) || I_PARMRK(tty))
1225 port->mark_mask |= RCSR_BREAK;
1227 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1228 if (I_IGNBRK(tty)) {
1229 port->mark_mask &= ~RCSR_BREAK;
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);
1244 port->COR2 |= COR2_CTSAE;
1247 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1248 /* Some people reported that it works, but I still doubt it */
1250 port->COR2 |= COR2_TXIBE;
1251 cor3 |= (COR3_FCT | COR3_SCDE);
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;
1269 /* Enable receiver */
1270 port->IER |= IER_RXD;
1272 /* Set input FIFO size (1-8 bytes) */
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 */
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 */
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);
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;
1310 if (port->flags & ASYNC_INITIALIZED) {
1315 if (!port->xmit_buf) {
1316 /* We may sleep in get_zeroed_page() */
1319 if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
1324 if (port->xmit_buf) {
1327 return -ERESTARTSYS;
1329 port->xmit_buf = (unsigned char *) tmp;
1332 spin_lock_irqsave(&port->lock, flags);
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);
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;
1354 unsigned long flags;
1358 if (!(port->flags & ASYNC_INITIALIZED)) {
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;
1378 spin_lock_irqsave(&bp->lock, flags);
1379 sx_out(bp, CD186x_CAR, port_No(port));
1381 if (!(tty = port->tty) || C_HUPCL(tty)) {
1383 sx_out(bp, CD186x_MSVDTR, 0);
1385 spin_unlock_irqrestore(&bp->lock, flags);
1388 spin_lock_irqsave(&bp->lock, flags);
1389 sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1390 /* Disable all interrupts from this port */
1392 sx_out(bp, CD186x_IER, port->IER);
1393 spin_unlock_irqrestore(&bp->lock, flags);
1395 set_bit(TTY_IO_ERROR, &tty->flags);
1396 port->flags &= ~ASYNC_INITIALIZED;
1399 sx_shutdown_board(bp);
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);
1412 unsigned long flags;
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) {
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;
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.
1453 add_wait_queue(&port->open_wait, &wait);
1454 spin_lock_irqsave(&port->lock, flags);
1455 if (!tty_hung_up_p(filp)) {
1458 spin_unlock_irqrestore(&port->lock, flags);
1459 port->blocked_open++;
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)) {
1466 port->MSVR |= MSVR_DTR; /* WTF? */
1467 sx_out (bp, CD186x_MSVR, port->MSVR);
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)
1480 retval = -ERESTARTSYS;
1483 if (!(port->flags & ASYNC_CLOSING) &&
1486 if (signal_pending(current)) {
1487 retval = -ERESTARTSYS;
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)) {
1499 port->blocked_open--;
1500 spin_unlock_irqrestore(&port->lock, flags);
1506 port->flags |= ASYNC_NORMAL_ACTIVE;
1512 static int sx_open(struct tty_struct * tty, struct file * filp)
1516 struct specialix_port * port;
1517 struct specialix_board * bp;
1519 unsigned long flags;
1523 board = SX_BOARD(tty->index);
1525 if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1530 bp = &sx_board[board];
1531 port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1533 for (i = 0; i < 10; i++)
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")) {
1544 if ((error = sx_setup_board(bp))) {
1549 spin_lock_irqsave(&bp->lock, flags);
1552 tty->driver_data = port;
1554 spin_unlock_irqrestore(&bp->lock, flags);
1556 if ((error = sx_setup_port(bp, port))) {
1561 if ((error = block_til_ready(tty, filp, port))) {
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;
1579 if (!port || sx_paranoia_check(port, tty->name, "close")) {
1583 spin_lock_irqsave(&port->lock, flags);
1585 if (tty_hung_up_p(filp)) {
1586 spin_unlock_irqrestore(&port->lock, flags);
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);
1599 if (port->count > 1) {
1603 spin_unlock_irqrestore(&port->lock, flags);
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.
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");
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);
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);
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);
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);
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;
1690 unsigned long flags;
1693 if (sx_paranoia_check(port, tty->name, "sx_write")) {
1698 bp = port_Board(port);
1700 if (!tty || !port->xmit_buf || !tmp_buf) {
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));
1710 spin_unlock_irqrestore(&port->lock, flags);
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);
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);
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;
1745 if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1749 dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1750 if (!tty || !port->xmit_buf) {
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");
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;
1768 spin_unlock_irqrestore(&port->lock, flags);
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);
1782 if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1786 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
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);
1801 static int sx_write_room(struct tty_struct * tty)
1803 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1808 if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1813 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1822 static int sx_chars_in_buffer(struct tty_struct *tty)
1824 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1828 if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
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;
1845 if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
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);
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;
1870 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
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);
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);
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;
1912 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
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;
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;
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);
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;
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);
1972 spin_lock_irqsave(&bp->lock, flags);
1973 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1974 spin_unlock_irqrestore(&bp->lock, flags);
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);
1990 if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1995 if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
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)) {
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))) {
2025 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
2026 (tmp.flags & ASYNC_USR_MASK));
2027 port->custom_divisor = tmp.custom_divisor;
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;
2036 sx_change_speed(bp, port);
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);
2052 if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
2056 memset(&tmp, 0, sizeof(tmp));
2057 tmp.type = PORT_CIRRUS;
2058 tmp.line = port - sx_port;
2059 tmp.port = bp->base;
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))) {
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;
2082 void __user *argp = (void __user *)arg;
2086 if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
2092 case TCSBRK: /* SVID version: non-zero arg --> no break */
2093 retval = tty_check_change(tty);
2098 tty_wait_until_sent(tty, 0);
2100 sx_send_break(port, HZ/4); /* 1/4 second */
2102 case TCSBRKP: /* support for POSIX tcsendbreak() */
2103 retval = tty_check_change(tty);
2108 tty_wait_until_sent(tty, 0);
2109 sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
2113 if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) {
2120 if (get_user(arg, (unsigned long __user *) argp)) {
2124 tty->termios->c_cflag =
2125 ((tty->termios->c_cflag & ~CLOCAL) |
2126 (arg ? CLOCAL : 0));
2131 return sx_get_serial_info(port, argp);
2134 return sx_set_serial_info(port, argp);
2137 return -ENOIOCTLCMD;
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;
2152 if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
2157 bp = port_Board(port);
2159 /* Use DTR instead of RTS ! */
2160 if (SX_CRTSCTS (tty))
2161 port->MSVR &= ~MSVR_DTR;
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",
2170 spin_lock_irqsave(&bp->lock, flags);
2171 sx_out(bp, CD186x_CAR, port_No(port));
2172 spin_unlock_irqrestore(&bp->lock, flags);
2174 spin_unlock_irqrestore(&bp->lock, flags);
2176 spin_lock_irqsave(&bp->lock, flags);
2177 sx_out(bp, CD186x_CCR, CCR_SSCH2);
2178 spin_unlock_irqrestore(&bp->lock, flags);
2181 spin_lock_irqsave(&bp->lock, flags);
2182 sx_out(bp, CD186x_MSVR, port->MSVR);
2183 spin_unlock_irqrestore(&bp->lock, flags);
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;
2197 if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
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);
2213 spin_unlock_irqrestore(&port->lock, flags);
2215 spin_lock_irqsave(&bp->lock, flags);
2216 sx_out(bp, CD186x_CCR, CCR_SSCH1);
2217 spin_unlock_irqrestore(&bp->lock, flags);
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);
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;
2238 if (sx_paranoia_check(port, tty->name, "sx_stop")) {
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);
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;
2265 if (sx_paranoia_check(port, tty->name, "sx_start")) {
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);
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;
2304 tty_hangup(tty); /* FIXME: module removal race here */
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;
2318 if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2323 bp = port_Board(port);
2325 sx_shutdown_port(bp, port);
2326 spin_lock_irqsave(&port->lock, flags);
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);
2335 port->flags &= ~ASYNC_NORMAL_ACTIVE;
2337 spin_unlock_irqrestore(&port->lock, flags);
2338 wake_up_interruptible(&port->open_wait);
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"))
2353 if (tty->termios->c_cflag == old_termios->c_cflag &&
2354 tty->termios->c_iflag == old_termios->c_iflag)
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;
2370 static void do_softint(void *private_)
2372 struct specialix_port *port = (struct specialix_port *) private_;
2373 struct tty_struct *tty;
2377 if(!(tty = port->tty)) {
2382 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
2384 //wake_up_interruptible(&tty->write_wait);
2390 static struct tty_operations sx_ops = {
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,
2400 .throttle = sx_throttle,
2401 .unthrottle = sx_unthrottle,
2402 .set_termios = sx_set_termios,
2405 .hangup = sx_hangup,
2406 .tiocmget = sx_tiocmget,
2407 .tiocmset = sx_tiocmset,
2410 static int sx_init_drivers(void)
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");
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);
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",
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);
2465 static void sx_release_drivers(void)
2469 free_page((unsigned long)tmp_buf);
2470 tty_unregister_driver(specialix_driver);
2471 put_tty_driver(specialix_driver);
2476 * This routine must be called by kernel at boot time
2478 static int __init specialix_init(void)
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");
2490 printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2493 for (i = 0; i < SX_NBOARD; i++)
2494 sx_board[i].lock = SPIN_LOCK_UNLOCKED;
2496 if (sx_init_drivers()) {
2501 for (i = 0; i < SX_NBOARD; i++)
2502 if (sx_board[i].base && !sx_probe(&sx_board[i]))
2507 struct pci_dev *pdev = NULL;
2510 while (i < SX_NBOARD) {
2511 if (sx_board[i].flags & SX_BOARD_PRESENT) {
2515 pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
2516 PCI_DEVICE_ID_SPECIALIX_IO8,
2520 if (pci_enable_device(pdev))
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]))
2535 sx_release_drivers();
2536 printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
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);
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)
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;
2584 return specialix_init();
2587 static void __exit specialix_exit_module(void)
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);
2604 module_init(specialix_init_module);
2605 module_exit(specialix_exit_module);
2607 MODULE_LICENSE("GPL");