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/module.h>
81 #include <linux/kernel.h>
82 #include <linux/sched.h>
83 #include <linux/ioport.h>
84 #include <linux/interrupt.h>
85 #include <linux/errno.h>
86 #include <linux/tty.h>
87 #include <linux/tty_flip.h>
89 #include <linux/serial.h>
90 #include <linux/fcntl.h>
91 #include <linux/major.h>
92 #include <linux/delay.h>
93 #include <linux/pci.h>
94 #include <linux/init.h>
95 #include <asm/uaccess.h>
97 #include "specialix_io8.h"
102 This driver can spew a whole lot of debugging output at you. If you
103 need maximum performance, you should disable the DEBUG define. To
104 aid in debugging in the field, I'm leaving the compile-time debug
105 features enabled, and disable them "runtime". That allows me to
106 instruct people with problems to enable debugging without requiring
112 static int sx_rxfifo = SPECIALIX_RXFIFO;
115 #define dprintk(f, str...) if (sx_debug & f) printk (str)
117 #define dprintk(f, str...) /* nothing */
120 #define SX_DEBUG_FLOW 0x0001
121 #define SX_DEBUG_DATA 0x0002
122 #define SX_DEBUG_PROBE 0x0004
123 #define SX_DEBUG_CHAN 0x0008
124 #define SX_DEBUG_INIT 0x0010
125 #define SX_DEBUG_RX 0x0020
126 #define SX_DEBUG_TX 0x0040
127 #define SX_DEBUG_IRQ 0x0080
128 #define SX_DEBUG_OPEN 0x0100
129 #define SX_DEBUG_TERMIOS 0x0200
130 #define SX_DEBUG_SIGNALS 0x0400
131 #define SX_DEBUG_FIFO 0x0800
134 #define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__FUNCTION__)
135 #define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __FUNCTION__)
137 #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
140 /* Configurable options: */
142 /* Am I paranoid or not ? ;-) */
143 #define SPECIALIX_PARANOIA_CHECK
145 /* Do I trust the IRQ from the card? (enabeling it doesn't seem to help)
146 When the IRQ routine leaves the chip in a state that is keeps on
147 requiring attention, the timer doesn't help either. */
148 #undef SPECIALIX_TIMER
150 #ifdef SPECIALIX_TIMER
151 static int sx_poll = HZ;
157 * The following defines are mostly for testing purposes. But if you need
158 * some nice reporting in your syslog, you can define them also.
160 #undef SX_REPORT_FIFO
161 #undef SX_REPORT_OVERRUN
165 #ifdef CONFIG_SPECIALIX_RTSCTS
166 #define SX_CRTSCTS(bla) 1
168 #define SX_CRTSCTS(tty) C_CRTSCTS(tty)
172 /* Used to be outb (0xff, 0x80); */
173 #define short_pause() udelay (1)
176 #define SPECIALIX_LEGAL_FLAGS \
177 (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \
178 ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \
179 ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
181 #undef RS_EVENT_WRITE_WAKEUP
182 #define RS_EVENT_WRITE_WAKEUP 0
184 static struct tty_driver *specialix_driver;
185 static unsigned char * tmp_buf;
187 static unsigned long baud_table[] = {
188 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
189 9600, 19200, 38400, 57600, 115200, 0,
192 static struct specialix_board sx_board[SX_NBOARD] = {
193 { 0, SX_IOBASE1, 9, },
194 { 0, SX_IOBASE2, 11, },
195 { 0, SX_IOBASE3, 12, },
196 { 0, SX_IOBASE4, 15, },
199 static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
202 #ifdef SPECIALIX_TIMER
203 static struct timer_list missed_irq_timer;
204 static irqreturn_t sx_interrupt(int irq, void * dev_id, struct pt_regs * regs);
209 static inline int sx_paranoia_check(struct specialix_port const * port,
210 char *name, const char *routine)
212 #ifdef SPECIALIX_PARANOIA_CHECK
213 static const char *badmagic =
214 KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
215 static const char *badinfo =
216 KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
219 printk(badinfo, name, routine);
222 if (port->magic != SPECIALIX_MAGIC) {
223 printk(badmagic, name, routine);
233 * Service functions for specialix IO8+ driver.
237 /* Get board number from pointer */
238 static inline int board_No (struct specialix_board * bp)
240 return bp - sx_board;
244 /* Get port number from pointer */
245 static inline int port_No (struct specialix_port const * port)
247 return SX_PORT(port - sx_port);
251 /* Get pointer to board from pointer to port */
252 static inline struct specialix_board * port_Board(struct specialix_port const * port)
254 return &sx_board[SX_BOARD(port - sx_port)];
258 /* Input Byte from CL CD186x register */
259 static inline unsigned char sx_in(struct specialix_board * bp, unsigned short reg)
261 bp->reg = reg | 0x80;
262 outb (reg | 0x80, bp->base + SX_ADDR_REG);
263 return inb (bp->base + SX_DATA_REG);
267 /* Output Byte to CL CD186x register */
268 static inline void sx_out(struct specialix_board * bp, unsigned short reg,
271 bp->reg = reg | 0x80;
272 outb (reg | 0x80, bp->base + SX_ADDR_REG);
273 outb (val, bp->base + SX_DATA_REG);
277 /* Input Byte from CL CD186x register */
278 static inline unsigned char sx_in_off(struct specialix_board * bp, unsigned short reg)
281 outb (reg, bp->base + SX_ADDR_REG);
282 return inb (bp->base + SX_DATA_REG);
286 /* Output Byte to CL CD186x register */
287 static inline void sx_out_off(struct specialix_board * bp, unsigned short reg,
291 outb (reg, bp->base + SX_ADDR_REG);
292 outb (val, bp->base + SX_DATA_REG);
296 /* Wait for Channel Command Register ready */
297 static inline void sx_wait_CCR(struct specialix_board * bp)
299 unsigned long delay, flags;
302 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
303 spin_lock_irqsave(&bp->lock, flags);
304 ccr = sx_in(bp, CD186x_CCR);
305 spin_unlock_irqrestore(&bp->lock, flags);
311 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
315 /* Wait for Channel Command Register ready */
316 static inline void sx_wait_CCR_off(struct specialix_board * bp)
322 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
323 spin_lock_irqsave(&bp->lock, flags);
324 crr = sx_in_off(bp, CD186x_CCR);
325 spin_unlock_irqrestore(&bp->lock, flags);
331 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
336 * specialix IO8+ IO range functions.
339 static inline int sx_request_io_range(struct specialix_board * bp)
341 return request_region(bp->base,
342 bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
343 "specialix IO8+") == NULL;
347 static inline void sx_release_io_range(struct specialix_board * bp)
349 release_region(bp->base,
350 bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
354 /* Must be called with enabled interrupts */
355 /* Ugly. Very ugly. Don't use this for anything else than initialization
357 static inline void sx_long_delay(unsigned long delay)
361 for (i = jiffies + delay; time_after(i, jiffies); ) ;
366 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
367 static int sx_set_irq ( struct specialix_board *bp)
373 if (bp->flags & SX_BOARD_IS_PCI)
376 /* In the same order as in the docs... */
377 case 15: virq = 0;break;
378 case 12: virq = 1;break;
379 case 11: virq = 2;break;
380 case 9: virq = 3;break;
381 default: printk (KERN_ERR "Speclialix: cannot set irq to %d.\n", bp->irq);
384 spin_lock_irqsave(&bp->lock, flags);
386 sx_out(bp, CD186x_CAR, i);
387 sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
389 spin_unlock_irqrestore(&bp->lock, flags);
394 /* Reset and setup CD186x chip */
395 static int sx_init_CD186x(struct specialix_board * bp)
402 sx_wait_CCR_off(bp); /* Wait for CCR ready */
403 spin_lock_irqsave(&bp->lock, flags);
404 sx_out_off(bp, CD186x_CCR, CCR_HARDRESET); /* Reset CD186x chip */
405 spin_unlock_irqrestore(&bp->lock, flags);
406 sx_long_delay(HZ/20); /* Delay 0.05 sec */
407 spin_lock_irqsave(&bp->lock, flags);
408 sx_out_off(bp, CD186x_GIVR, SX_ID); /* Set ID for this chip */
409 sx_out_off(bp, CD186x_GICR, 0); /* Clear all bits */
410 sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT); /* Prio for modem intr */
411 sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */
412 sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
414 sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
416 /* Setting up prescaler. We need 4 ticks per 1 ms */
417 scaler = SX_OSCFREQ/SPECIALIX_TPS;
419 sx_out_off(bp, CD186x_PPRH, scaler >> 8);
420 sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
421 spin_unlock_irqrestore(&bp->lock, flags);
423 if (!sx_set_irq (bp)) {
424 /* Figure out how to pass this along... */
425 printk (KERN_ERR "Cannot set irq to %d.\n", bp->irq);
434 static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
440 spin_lock_irqsave(&bp->lock, flags);
441 for (i=0, t=0;i<8;i++) {
442 sx_out_off (bp, CD186x_CAR, i);
443 if (sx_in_off (bp, reg) & bit)
446 spin_unlock_irqrestore(&bp->lock, flags);
452 #ifdef SPECIALIX_TIMER
453 void missed_irq (unsigned long data)
457 struct specialix_board *bp = (struct specialix_board *)data;
459 spin_lock_irqsave(&bp->lock, flags);
460 irq = sx_in ((struct specialix_board *)data, CD186x_SRSR) &
464 spin_unlock_irqrestore(&bp->lock, flags);
466 printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
467 sx_interrupt (((struct specialix_board *)data)->irq,
470 missed_irq_timer.expires = jiffies + sx_poll;
471 add_timer (&missed_irq_timer);
477 /* Main probing routine, also sets irq. */
478 static int sx_probe(struct specialix_board *bp)
480 unsigned char val1, val2;
490 if (sx_request_io_range(bp)) {
495 /* Are the I/O ports here ? */
496 sx_out_off(bp, CD186x_PPRL, 0x5a);
498 val1 = sx_in_off(bp, CD186x_PPRL);
500 sx_out_off(bp, CD186x_PPRL, 0xa5);
502 val2 = sx_in_off(bp, CD186x_PPRL);
505 if ((val1 != 0x5a) || (val2 != 0xa5)) {
506 printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
507 board_No(bp), bp->base);
508 sx_release_io_range(bp);
513 /* Check the DSR lines that Specialix uses as board
515 val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
516 val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
517 dprintk (SX_DEBUG_INIT, "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
518 board_No(bp), val1, val2);
520 /* They managed to switch the bit order between the docs and
521 the IO8+ card. The new PCI card now conforms to old docs.
522 They changed the PCI docs to reflect the situation on the
524 val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
526 printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
527 board_No(bp), val2, bp->base, val1);
528 sx_release_io_range(bp);
535 /* It's time to find IRQ for this board */
536 for (retries = 0; retries < 5 && irqs <= 0; retries++) {
537 irqs = probe_irq_on();
538 sx_init_CD186x(bp); /* Reset CD186x chip */
539 sx_out(bp, CD186x_CAR, 2); /* Select port 2 */
541 sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */
542 sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */
543 sx_long_delay(HZ/20);
544 irqs = probe_irq_off(irqs);
546 dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
547 dprintk (SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR));
548 dprintk (SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR));
549 dprintk (SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR));
550 dprintk (SX_DEBUG_INIT, "\n");
552 /* Reset CD186x again */
553 if (!sx_init_CD186x(bp)) {
554 /* Hmmm. This is dead code anyway. */
557 dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
564 printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
565 board_No(bp), bp->base);
566 sx_release_io_range(bp);
571 printk (KERN_INFO "Started with irq=%d, but now have irq=%d.\n", bp->irq, irqs);
575 /* Reset CD186x again */
576 if (!sx_init_CD186x(bp)) {
577 sx_release_io_range(bp);
582 sx_request_io_range(bp);
583 bp->flags |= SX_BOARD_PRESENT;
585 /* Chip revcode pkgtype
590 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
592 -- Thanks to Gwen Wang, Cirrus Logic.
595 switch (sx_in_off(bp, CD186x_GFRCR)) {
596 case 0x82:chip = 1864;rev='A';break;
597 case 0x83:chip = 1865;rev='A';break;
598 case 0x84:chip = 1865;rev='B';break;
599 case 0x85:chip = 1865;rev='C';break; /* Does not exist at this time */
600 default:chip=-1;rev='x';
603 dprintk (SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR) );
605 #ifdef SPECIALIX_TIMER
606 init_timer (&missed_irq_timer);
607 missed_irq_timer.function = missed_irq;
608 missed_irq_timer.data = (unsigned long) bp;
609 missed_irq_timer.expires = jiffies + sx_poll;
610 add_timer (&missed_irq_timer);
613 printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
624 * Interrupt processing routines.
627 static inline void sx_mark_event(struct specialix_port * port, int event)
631 set_bit(event, &port->event);
632 schedule_work(&port->tqueue);
638 static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
639 unsigned char const * what)
641 unsigned char channel;
642 struct specialix_port * port = NULL;
644 channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
645 dprintk (SX_DEBUG_CHAN, "channel: %d\n", channel);
646 if (channel < CD186x_NCH) {
647 port = &sx_port[board_No(bp) * SX_NPORT + channel];
648 dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%x\n",board_No(bp) * SX_NPORT + channel, port, port->flags & ASYNC_INITIALIZED);
650 if (port->flags & ASYNC_INITIALIZED) {
651 dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
656 printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
657 board_No(bp), what, channel);
662 static inline void sx_receive_exc(struct specialix_board * bp)
664 struct specialix_port *port;
665 struct tty_struct *tty;
666 unsigned char status;
667 unsigned char ch, flag;
671 port = sx_get_port(bp, "Receive");
673 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
679 status = sx_in(bp, CD186x_RCSR);
681 dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
682 if (status & RCSR_OE) {
684 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Overrun. Total %ld overruns.\n",
685 board_No(bp), port_No(port), port->overrun);
687 status &= port->mark_mask;
689 /* This flip buffer check needs to be below the reading of the
690 status register to reset the chip's IRQ.... */
691 if (tty_buffer_request_room(tty, 1) == 0) {
692 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n",
693 board_No(bp), port_No(port));
698 ch = sx_in(bp, CD186x_RDR);
703 if (status & RCSR_TOUT) {
704 printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
705 board_No(bp), port_No(port));
709 } else if (status & RCSR_BREAK) {
710 dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
711 board_No(bp), port_No(port));
713 if (port->flags & ASYNC_SAK)
716 } else if (status & RCSR_PE)
719 else if (status & RCSR_FE)
722 else if (status & RCSR_OE)
728 if(tty_insert_flip_char(tty, ch, flag))
729 tty_flip_buffer_push(tty);
734 static inline void sx_receive(struct specialix_board * bp)
736 struct specialix_port *port;
737 struct tty_struct *tty;
742 if (!(port = sx_get_port(bp, "Receive"))) {
743 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
749 count = sx_in(bp, CD186x_RDCR);
750 dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
751 port->hits[count > 8 ? 9 : count]++;
753 tty_buffer_request_room(tty, count);
756 tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL);
757 tty_flip_buffer_push(tty);
762 static inline void sx_transmit(struct specialix_board * bp)
764 struct specialix_port *port;
765 struct tty_struct *tty;
769 if (!(port = sx_get_port(bp, "Transmit"))) {
773 dprintk (SX_DEBUG_TX, "port: %p\n", port);
776 if (port->IER & IER_TXEMPTY) {
778 sx_out(bp, CD186x_CAR, port_No(port));
779 port->IER &= ~IER_TXEMPTY;
780 sx_out(bp, CD186x_IER, port->IER);
785 if ((port->xmit_cnt <= 0 && !port->break_length)
786 || tty->stopped || tty->hw_stopped) {
787 sx_out(bp, CD186x_CAR, port_No(port));
788 port->IER &= ~IER_TXRDY;
789 sx_out(bp, CD186x_IER, port->IER);
794 if (port->break_length) {
795 if (port->break_length > 0) {
796 if (port->COR2 & COR2_ETC) {
797 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
798 sx_out(bp, CD186x_TDR, CD186x_C_SBRK);
799 port->COR2 &= ~COR2_ETC;
801 count = min_t(int, port->break_length, 0xff);
802 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
803 sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
804 sx_out(bp, CD186x_TDR, count);
805 if (!(port->break_length -= count))
806 port->break_length--;
808 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
809 sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
810 sx_out(bp, CD186x_COR2, port->COR2);
812 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
813 port->break_length = 0;
820 count = CD186x_NFIFO;
822 sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
823 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
824 if (--port->xmit_cnt <= 0)
826 } while (--count > 0);
828 if (port->xmit_cnt <= 0) {
829 sx_out(bp, CD186x_CAR, port_No(port));
830 port->IER &= ~IER_TXRDY;
831 sx_out(bp, CD186x_IER, port->IER);
833 if (port->xmit_cnt <= port->wakeup_chars)
834 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
840 static inline void sx_check_modem(struct specialix_board * bp)
842 struct specialix_port *port;
843 struct tty_struct *tty;
847 dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
848 if (!(port = sx_get_port(bp, "Modem")))
853 mcr = sx_in(bp, CD186x_MCR);
854 printk ("mcr = %02x.\n", mcr);
856 if ((mcr & MCR_CDCHG)) {
857 dprintk (SX_DEBUG_SIGNALS, "CD just changed... ");
858 msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
860 dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
861 wake_up_interruptible(&port->open_wait);
863 dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n");
864 schedule_work(&port->tqueue_hangup);
868 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
869 if (mcr & MCR_CTSCHG) {
870 if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
872 port->IER |= IER_TXRDY;
873 if (port->xmit_cnt <= port->wakeup_chars)
874 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
877 port->IER &= ~IER_TXRDY;
879 sx_out(bp, CD186x_IER, port->IER);
881 if (mcr & MCR_DSSXHG) {
882 if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
884 port->IER |= IER_TXRDY;
885 if (port->xmit_cnt <= port->wakeup_chars)
886 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
889 port->IER &= ~IER_TXRDY;
891 sx_out(bp, CD186x_IER, port->IER);
893 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
895 /* Clear change bits */
896 sx_out(bp, CD186x_MCR, 0);
900 /* The main interrupt processing routine */
901 static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
903 unsigned char status;
905 struct specialix_board *bp;
906 unsigned long loop = 0;
913 spin_lock_irqsave(&bp->lock, flags);
915 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);
916 if (!bp || !(bp->flags & SX_BOARD_ACTIVE)) {
917 dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq);
918 spin_unlock_irqrestore(&bp->lock, flags);
925 while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
929 if (status & SRSR_RREQint) {
930 ack = sx_in(bp, CD186x_RRAR);
932 if (ack == (SX_ID | GIVR_IT_RCV))
934 else if (ack == (SX_ID | GIVR_IT_REXC))
937 printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
938 board_No(bp), status, ack);
940 } else if (status & SRSR_TREQint) {
941 ack = sx_in(bp, CD186x_TRAR);
943 if (ack == (SX_ID | GIVR_IT_TX))
946 printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
947 board_No(bp), status, ack, port_No (sx_get_port (bp, "Int")));
948 } else if (status & SRSR_MREQint) {
949 ack = sx_in(bp, CD186x_MRAR);
951 if (ack == (SX_ID | GIVR_IT_MODEM))
954 printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
955 board_No(bp), status, ack);
959 sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
962 outb (bp->reg, bp->base + SX_ADDR_REG);
963 spin_unlock_irqrestore(&bp->lock, flags);
970 * Routines for open & close processing.
973 static void turn_ints_off (struct specialix_board *bp)
978 if (bp->flags & SX_BOARD_IS_PCI) {
979 /* This was intended for enabeling the interrupt on the
980 * PCI card. However it seems that it's already enabled
981 * and as PCI interrupts can be shared, there is no real
982 * reason to have to turn it off. */
985 spin_lock_irqsave(&bp->lock, flags);
986 (void) sx_in_off (bp, 0); /* Turn off interrupts. */
987 spin_unlock_irqrestore(&bp->lock, flags);
992 static void turn_ints_on (struct specialix_board *bp)
998 if (bp->flags & SX_BOARD_IS_PCI) {
999 /* play with the PCI chip. See comment above. */
1001 spin_lock_irqsave(&bp->lock, flags);
1002 (void) sx_in (bp, 0); /* Turn ON interrupts. */
1003 spin_unlock_irqrestore(&bp->lock, flags);
1009 /* Called with disabled interrupts */
1010 static inline int sx_setup_board(struct specialix_board * bp)
1014 if (bp->flags & SX_BOARD_ACTIVE)
1017 if (bp->flags & SX_BOARD_IS_PCI)
1018 error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp);
1020 error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED, "specialix IO8+", bp);
1026 bp->flags |= SX_BOARD_ACTIVE;
1032 /* Called with disabled interrupts */
1033 static inline void sx_shutdown_board(struct specialix_board *bp)
1037 if (!(bp->flags & SX_BOARD_ACTIVE)) {
1042 bp->flags &= ~SX_BOARD_ACTIVE;
1044 dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
1045 bp->irq, board_No (bp));
1046 free_irq(bp->irq, bp);
1056 * Setting up port characteristics.
1057 * Must be called with disabled interrupts
1059 static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
1061 struct tty_struct *tty;
1064 unsigned char cor1 = 0, cor3 = 0;
1065 unsigned char mcor1 = 0, mcor2 = 0;
1066 static unsigned long again;
1067 unsigned long flags;
1071 if (!(tty = port->tty) || !tty->termios) {
1078 /* Select port on the board */
1079 spin_lock_irqsave(&bp->lock, flags);
1080 sx_out(bp, CD186x_CAR, port_No(port));
1082 /* The Specialix board doens't implement the RTS lines.
1083 They are used to set the IRQ level. Don't touch them. */
1084 if (SX_CRTSCTS(tty))
1085 port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1087 port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1088 spin_unlock_irqrestore(&bp->lock, flags);
1089 dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
1090 baud = tty_get_baud_rate(tty);
1092 if (baud == 38400) {
1093 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1095 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1100 /* Drop DTR & exit */
1101 dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
1102 if (!SX_CRTSCTS (tty)) {
1103 port -> MSVR &= ~ MSVR_DTR;
1104 spin_lock_irqsave(&bp->lock, flags);
1105 sx_out(bp, CD186x_MSVR, port->MSVR );
1106 spin_unlock_irqrestore(&bp->lock, flags);
1109 dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1113 if (!SX_CRTSCTS (tty)) {
1114 port ->MSVR |= MSVR_DTR;
1119 * Now we must calculate some speed depended things
1122 /* Set baud rate for port */
1123 tmp = port->custom_divisor ;
1125 printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n"
1126 "This is an untested option, please be carefull.\n",
1127 port_No (port), tmp);
1129 tmp = (((SX_OSCFREQ + baud/2) / baud +
1130 CD186x_TPC/2) / CD186x_TPC);
1132 if ((tmp < 0x10) && time_before(again, jiffies)) {
1133 again = jiffies + HZ * 60;
1134 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1136 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1137 "Performance degradation is possible.\n"
1138 "Read specialix.txt for more info.\n",
1139 port_No (port), tmp);
1141 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1142 "Warning: overstressing Cirrus chip. "
1143 "This might not work.\n"
1144 "Read specialix.txt for more info.\n",
1145 port_No (port), tmp);
1148 spin_lock_irqsave(&bp->lock, flags);
1149 sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1150 sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1151 sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1152 sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1153 spin_unlock_irqrestore(&bp->lock, flags);
1154 if (port->custom_divisor) {
1155 baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
1156 baud = ( baud + 5 ) / 10;
1158 baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */
1160 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1161 tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1162 port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1163 SERIAL_XMIT_SIZE - 1 : tmp);
1165 /* Receiver timeout will be transmission time for 1.5 chars */
1166 tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1167 tmp = (tmp > 0xff) ? 0xff : tmp;
1168 spin_lock_irqsave(&bp->lock, flags);
1169 sx_out(bp, CD186x_RTPR, tmp);
1170 spin_unlock_irqrestore(&bp->lock, flags);
1171 switch (C_CSIZE(tty)) {
1189 cor1 |= COR1_IGNORE;
1190 if (C_PARENB(tty)) {
1191 cor1 |= COR1_NORMPAR;
1195 cor1 &= ~COR1_IGNORE;
1197 /* Set marking of some errors */
1198 port->mark_mask = RCSR_OE | RCSR_TOUT;
1200 port->mark_mask |= RCSR_FE | RCSR_PE;
1201 if (I_BRKINT(tty) || I_PARMRK(tty))
1202 port->mark_mask |= RCSR_BREAK;
1204 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1205 if (I_IGNBRK(tty)) {
1206 port->mark_mask &= ~RCSR_BREAK;
1208 /* Real raw mode. Ignore all */
1209 port->mark_mask &= ~RCSR_OE;
1211 /* Enable Hardware Flow Control */
1212 if (C_CRTSCTS(tty)) {
1213 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1214 port->IER |= IER_DSR | IER_CTS;
1215 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1216 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1217 spin_lock_irqsave(&bp->lock, flags);
1218 tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
1219 spin_unlock_irqrestore(&bp->lock, flags);
1221 port->COR2 |= COR2_CTSAE;
1224 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1225 /* Some people reported that it works, but I still doubt it */
1227 port->COR2 |= COR2_TXIBE;
1228 cor3 |= (COR3_FCT | COR3_SCDE);
1230 port->COR2 |= COR2_IXM;
1231 spin_lock_irqsave(&bp->lock, flags);
1232 sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1233 sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1234 sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1235 sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1236 spin_unlock_irqrestore(&bp->lock, flags);
1238 if (!C_CLOCAL(tty)) {
1239 /* Enable CD check */
1240 port->IER |= IER_CD;
1241 mcor1 |= MCOR1_CDZD;
1242 mcor2 |= MCOR2_CDOD;
1246 /* Enable receiver */
1247 port->IER |= IER_RXD;
1249 /* Set input FIFO size (1-8 bytes) */
1251 /* Setting up CD186x channel registers */
1252 spin_lock_irqsave(&bp->lock, flags);
1253 sx_out(bp, CD186x_COR1, cor1);
1254 sx_out(bp, CD186x_COR2, port->COR2);
1255 sx_out(bp, CD186x_COR3, cor3);
1256 spin_unlock_irqrestore(&bp->lock, flags);
1257 /* Make CD186x know about registers change */
1259 spin_lock_irqsave(&bp->lock, flags);
1260 sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1261 /* Setting up modem option registers */
1262 dprintk (SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2);
1263 sx_out(bp, CD186x_MCOR1, mcor1);
1264 sx_out(bp, CD186x_MCOR2, mcor2);
1265 spin_unlock_irqrestore(&bp->lock, flags);
1266 /* Enable CD186x transmitter & receiver */
1268 spin_lock_irqsave(&bp->lock, flags);
1269 sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1270 /* Enable interrupts */
1271 sx_out(bp, CD186x_IER, port->IER);
1272 /* And finally set the modem lines... */
1273 sx_out(bp, CD186x_MSVR, port->MSVR);
1274 spin_unlock_irqrestore(&bp->lock, flags);
1280 /* Must be called with interrupts enabled */
1281 static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port)
1283 unsigned long flags;
1287 if (port->flags & ASYNC_INITIALIZED) {
1292 if (!port->xmit_buf) {
1293 /* We may sleep in get_zeroed_page() */
1296 if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
1301 if (port->xmit_buf) {
1304 return -ERESTARTSYS;
1306 port->xmit_buf = (unsigned char *) tmp;
1309 spin_lock_irqsave(&port->lock, flags);
1312 clear_bit(TTY_IO_ERROR, &port->tty->flags);
1314 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1315 sx_change_speed(bp, port);
1316 port->flags |= ASYNC_INITIALIZED;
1318 spin_unlock_irqrestore(&port->lock, flags);
1326 /* Must be called with interrupts disabled */
1327 static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port)
1329 struct tty_struct *tty;
1331 unsigned long flags;
1335 if (!(port->flags & ASYNC_INITIALIZED)) {
1340 if (sx_debug & SX_DEBUG_FIFO) {
1341 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
1342 board_No(bp), port_No(port), port->overrun);
1343 for (i = 0; i < 10; i++) {
1344 dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1346 dprintk(SX_DEBUG_FIFO, "].\n");
1349 if (port->xmit_buf) {
1350 free_page((unsigned long) port->xmit_buf);
1351 port->xmit_buf = NULL;
1355 spin_lock_irqsave(&bp->lock, flags);
1356 sx_out(bp, CD186x_CAR, port_No(port));
1358 if (!(tty = port->tty) || C_HUPCL(tty)) {
1360 sx_out(bp, CD186x_MSVDTR, 0);
1362 spin_unlock_irqrestore(&bp->lock, flags);
1365 spin_lock_irqsave(&bp->lock, flags);
1366 sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1367 /* Disable all interrupts from this port */
1369 sx_out(bp, CD186x_IER, port->IER);
1370 spin_unlock_irqrestore(&bp->lock, flags);
1372 set_bit(TTY_IO_ERROR, &tty->flags);
1373 port->flags &= ~ASYNC_INITIALIZED;
1376 sx_shutdown_board(bp);
1381 static int block_til_ready(struct tty_struct *tty, struct file * filp,
1382 struct specialix_port *port)
1384 DECLARE_WAITQUEUE(wait, current);
1385 struct specialix_board *bp = port_Board(port);
1389 unsigned long flags;
1394 * If the device is in the middle of being closed, then block
1395 * until it's done, and then try again.
1397 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
1398 interruptible_sleep_on(&port->close_wait);
1399 if (port->flags & ASYNC_HUP_NOTIFY) {
1404 return -ERESTARTSYS;
1409 * If non-blocking mode is set, or the port is not enabled,
1410 * then make the check up front and then exit.
1412 if ((filp->f_flags & O_NONBLOCK) ||
1413 (tty->flags & (1 << TTY_IO_ERROR))) {
1414 port->flags |= ASYNC_NORMAL_ACTIVE;
1423 * Block waiting for the carrier detect and the line to become
1424 * free (i.e., not in use by the callout). While we are in
1425 * this loop, info->count is dropped by one, so that
1426 * rs_close() knows when to free things. We restore it upon
1427 * exit, either normal or abnormal.
1430 add_wait_queue(&port->open_wait, &wait);
1431 spin_lock_irqsave(&port->lock, flags);
1432 if (!tty_hung_up_p(filp)) {
1435 spin_unlock_irqrestore(&port->lock, flags);
1436 port->blocked_open++;
1438 spin_lock_irqsave(&bp->lock, flags);
1439 sx_out(bp, CD186x_CAR, port_No(port));
1440 CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1441 if (SX_CRTSCTS (tty)) {
1443 port->MSVR |= MSVR_DTR; /* WTF? */
1444 sx_out (bp, CD186x_MSVR, port->MSVR);
1447 port->MSVR |= MSVR_DTR;
1448 sx_out (bp, CD186x_MSVR, port->MSVR);
1450 spin_unlock_irqrestore(&bp->lock, flags);
1451 set_current_state(TASK_INTERRUPTIBLE);
1452 if (tty_hung_up_p(filp) ||
1453 !(port->flags & ASYNC_INITIALIZED)) {
1454 if (port->flags & ASYNC_HUP_NOTIFY)
1457 retval = -ERESTARTSYS;
1460 if (!(port->flags & ASYNC_CLOSING) &&
1463 if (signal_pending(current)) {
1464 retval = -ERESTARTSYS;
1470 set_current_state(TASK_RUNNING);
1471 remove_wait_queue(&port->open_wait, &wait);
1472 spin_lock_irqsave(&port->lock, flags);
1473 if (!tty_hung_up_p(filp)) {
1476 port->blocked_open--;
1477 spin_unlock_irqrestore(&port->lock, flags);
1483 port->flags |= ASYNC_NORMAL_ACTIVE;
1489 static int sx_open(struct tty_struct * tty, struct file * filp)
1493 struct specialix_port * port;
1494 struct specialix_board * bp;
1496 unsigned long flags;
1500 board = SX_BOARD(tty->index);
1502 if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1507 bp = &sx_board[board];
1508 port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1510 for (i = 0; i < 10; i++)
1513 dprintk (SX_DEBUG_OPEN, "Board = %d, bp = %p, port = %p, portno = %d.\n",
1514 board, bp, port, SX_PORT(tty->index));
1516 if (sx_paranoia_check(port, tty->name, "sx_open")) {
1521 if ((error = sx_setup_board(bp))) {
1526 spin_lock_irqsave(&bp->lock, flags);
1529 tty->driver_data = port;
1531 spin_unlock_irqrestore(&bp->lock, flags);
1533 if ((error = sx_setup_port(bp, port))) {
1538 if ((error = block_til_ready(tty, filp, port))) {
1548 static void sx_close(struct tty_struct * tty, struct file * filp)
1550 struct specialix_port *port = (struct specialix_port *) tty->driver_data;
1551 struct specialix_board *bp;
1552 unsigned long flags;
1553 unsigned long timeout;
1556 if (!port || sx_paranoia_check(port, tty->name, "close")) {
1560 spin_lock_irqsave(&port->lock, flags);
1562 if (tty_hung_up_p(filp)) {
1563 spin_unlock_irqrestore(&port->lock, flags);
1568 bp = port_Board(port);
1569 if ((tty->count == 1) && (port->count != 1)) {
1570 printk(KERN_ERR "sx%d: sx_close: bad port count;"
1571 " tty->count is 1, port count is %d\n",
1572 board_No(bp), port->count);
1576 if (port->count > 1) {
1580 spin_unlock_irqrestore(&port->lock, flags);
1585 port->flags |= ASYNC_CLOSING;
1587 * Now we wait for the transmit buffer to clear; and we notify
1588 * the line discipline to only process XON/XOFF characters.
1591 spin_unlock_irqrestore(&port->lock, flags);
1592 dprintk (SX_DEBUG_OPEN, "Closing\n");
1593 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
1594 tty_wait_until_sent(tty, port->closing_wait);
1597 * At this point we stop accepting input. To do this, we
1598 * disable the receive line status interrupts, and tell the
1599 * interrupt driver to stop checking the data ready bit in the
1600 * line status register.
1602 dprintk (SX_DEBUG_OPEN, "Closed\n");
1603 port->IER &= ~IER_RXD;
1604 if (port->flags & ASYNC_INITIALIZED) {
1605 port->IER &= ~IER_TXRDY;
1606 port->IER |= IER_TXEMPTY;
1607 spin_lock_irqsave(&bp->lock, flags);
1608 sx_out(bp, CD186x_CAR, port_No(port));
1609 sx_out(bp, CD186x_IER, port->IER);
1610 spin_unlock_irqrestore(&bp->lock, flags);
1612 * Before we drop DTR, make sure the UART transmitter
1613 * has completely drained; this is especially
1614 * important if there is a transmit FIFO!
1616 timeout = jiffies+HZ;
1617 while(port->IER & IER_TXEMPTY) {
1618 set_current_state (TASK_INTERRUPTIBLE);
1619 msleep_interruptible(jiffies_to_msecs(port->timeout));
1620 if (time_after(jiffies, timeout)) {
1621 printk (KERN_INFO "Timeout waiting for close\n");
1628 if (--bp->count < 0) {
1629 printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1630 board_No(bp), bp->count, tty->index);
1633 if (--port->count < 0) {
1634 printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n",
1635 board_No(bp), port_No(port), port->count);
1639 sx_shutdown_port(bp, port);
1640 if (tty->driver->flush_buffer)
1641 tty->driver->flush_buffer(tty);
1642 tty_ldisc_flush(tty);
1643 spin_lock_irqsave(&port->lock, flags);
1647 spin_unlock_irqrestore(&port->lock, flags);
1648 if (port->blocked_open) {
1649 if (port->close_delay) {
1650 msleep_interruptible(jiffies_to_msecs(port->close_delay));
1652 wake_up_interruptible(&port->open_wait);
1654 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1655 wake_up_interruptible(&port->close_wait);
1661 static int sx_write(struct tty_struct * tty,
1662 const unsigned char *buf, int count)
1664 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1665 struct specialix_board *bp;
1667 unsigned long flags;
1670 if (sx_paranoia_check(port, tty->name, "sx_write")) {
1675 bp = port_Board(port);
1677 if (!port->xmit_buf || !tmp_buf) {
1683 spin_lock_irqsave(&port->lock, flags);
1684 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1685 SERIAL_XMIT_SIZE - port->xmit_head));
1687 spin_unlock_irqrestore(&port->lock, flags);
1690 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1691 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1692 port->xmit_cnt += c;
1693 spin_unlock_irqrestore(&port->lock, flags);
1700 spin_lock_irqsave(&bp->lock, flags);
1701 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1702 !(port->IER & IER_TXRDY)) {
1703 port->IER |= IER_TXRDY;
1704 sx_out(bp, CD186x_CAR, port_No(port));
1705 sx_out(bp, CD186x_IER, port->IER);
1707 spin_unlock_irqrestore(&bp->lock, flags);
1714 static void sx_put_char(struct tty_struct * tty, unsigned char ch)
1716 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1717 unsigned long flags;
1718 struct specialix_board * bp;
1722 if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1726 dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1727 if (!port->xmit_buf) {
1731 bp = port_Board(port);
1732 spin_lock_irqsave(&port->lock, flags);
1734 dprintk (SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", port->xmit_cnt, port->xmit_buf);
1735 if ((port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) || (!port->xmit_buf)) {
1736 spin_unlock_irqrestore(&port->lock, flags);
1737 dprintk (SX_DEBUG_TX, "Exit size\n");
1741 dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
1742 port->xmit_buf[port->xmit_head++] = ch;
1743 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1745 spin_unlock_irqrestore(&port->lock, flags);
1751 static void sx_flush_chars(struct tty_struct * tty)
1753 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1754 unsigned long flags;
1755 struct specialix_board * bp = port_Board(port);
1759 if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1763 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1768 spin_lock_irqsave(&bp->lock, flags);
1769 port->IER |= IER_TXRDY;
1770 sx_out(port_Board(port), CD186x_CAR, port_No(port));
1771 sx_out(port_Board(port), CD186x_IER, port->IER);
1772 spin_unlock_irqrestore(&bp->lock, flags);
1778 static int sx_write_room(struct tty_struct * tty)
1780 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1785 if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1790 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1799 static int sx_chars_in_buffer(struct tty_struct *tty)
1801 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1805 if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
1810 return port->xmit_cnt;
1814 static void sx_flush_buffer(struct tty_struct *tty)
1816 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1817 unsigned long flags;
1818 struct specialix_board * bp;
1822 if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
1827 bp = port_Board(port);
1828 spin_lock_irqsave(&port->lock, flags);
1829 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1830 spin_unlock_irqrestore(&port->lock, flags);
1837 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1839 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1840 struct specialix_board * bp;
1841 unsigned char status;
1842 unsigned int result;
1843 unsigned long flags;
1847 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1852 bp = port_Board(port);
1853 spin_lock_irqsave (&bp->lock, flags);
1854 sx_out(bp, CD186x_CAR, port_No(port));
1855 status = sx_in(bp, CD186x_MSVR);
1856 spin_unlock_irqrestore(&bp->lock, flags);
1857 dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1858 port_No(port), status, sx_in (bp, CD186x_CAR));
1859 dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1860 if (SX_CRTSCTS(port->tty)) {
1861 result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
1862 | ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1863 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1864 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1865 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1867 result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
1868 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1869 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1870 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1871 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1880 static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1881 unsigned int set, unsigned int clear)
1883 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1884 unsigned long flags;
1885 struct specialix_board *bp;
1889 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1894 bp = port_Board(port);
1896 spin_lock_irqsave(&port->lock, flags);
1897 /* if (set & TIOCM_RTS)
1898 port->MSVR |= MSVR_RTS; */
1899 /* if (set & TIOCM_DTR)
1900 port->MSVR |= MSVR_DTR; */
1902 if (SX_CRTSCTS(port->tty)) {
1903 if (set & TIOCM_RTS)
1904 port->MSVR |= MSVR_DTR;
1906 if (set & TIOCM_DTR)
1907 port->MSVR |= MSVR_DTR;
1910 /* if (clear & TIOCM_RTS)
1911 port->MSVR &= ~MSVR_RTS; */
1912 /* if (clear & TIOCM_DTR)
1913 port->MSVR &= ~MSVR_DTR; */
1914 if (SX_CRTSCTS(port->tty)) {
1915 if (clear & TIOCM_RTS)
1916 port->MSVR &= ~MSVR_DTR;
1918 if (clear & TIOCM_DTR)
1919 port->MSVR &= ~MSVR_DTR;
1921 spin_lock_irqsave(&bp->lock, flags);
1922 sx_out(bp, CD186x_CAR, port_No(port));
1923 sx_out(bp, CD186x_MSVR, port->MSVR);
1924 spin_unlock_irqrestore(&bp->lock, flags);
1925 spin_unlock_irqrestore(&port->lock, flags);
1931 static inline void sx_send_break(struct specialix_port * port, unsigned long length)
1933 struct specialix_board *bp = port_Board(port);
1934 unsigned long flags;
1938 spin_lock_irqsave (&port->lock, flags);
1939 port->break_length = SPECIALIX_TPS / HZ * length;
1940 port->COR2 |= COR2_ETC;
1941 port->IER |= IER_TXRDY;
1942 spin_lock_irqsave(&bp->lock, flags);
1943 sx_out(bp, CD186x_CAR, port_No(port));
1944 sx_out(bp, CD186x_COR2, port->COR2);
1945 sx_out(bp, CD186x_IER, port->IER);
1946 spin_unlock_irqrestore(&bp->lock, flags);
1947 spin_unlock_irqrestore (&port->lock, flags);
1949 spin_lock_irqsave(&bp->lock, flags);
1950 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1951 spin_unlock_irqrestore(&bp->lock, flags);
1958 static inline int sx_set_serial_info(struct specialix_port * port,
1959 struct serial_struct __user * newinfo)
1961 struct serial_struct tmp;
1962 struct specialix_board *bp = port_Board(port);
1967 if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1972 if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
1978 if ((tmp.irq != bp->irq) ||
1979 (tmp.port != bp->base) ||
1980 (tmp.type != PORT_CIRRUS) ||
1981 (tmp.baud_base != (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) ||
1982 (tmp.custom_divisor != 0) ||
1983 (tmp.xmit_fifo_size != CD186x_NFIFO) ||
1984 (tmp.flags & ~SPECIALIX_LEGAL_FLAGS)) {
1990 change_speed = ((port->flags & ASYNC_SPD_MASK) !=
1991 (tmp.flags & ASYNC_SPD_MASK));
1992 change_speed |= (tmp.custom_divisor != port->custom_divisor);
1994 if (!capable(CAP_SYS_ADMIN)) {
1995 if ((tmp.close_delay != port->close_delay) ||
1996 (tmp.closing_wait != port->closing_wait) ||
1997 ((tmp.flags & ~ASYNC_USR_MASK) !=
1998 (port->flags & ~ASYNC_USR_MASK))) {
2002 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
2003 (tmp.flags & ASYNC_USR_MASK));
2004 port->custom_divisor = tmp.custom_divisor;
2006 port->flags = ((port->flags & ~ASYNC_FLAGS) |
2007 (tmp.flags & ASYNC_FLAGS));
2008 port->close_delay = tmp.close_delay;
2009 port->closing_wait = tmp.closing_wait;
2010 port->custom_divisor = tmp.custom_divisor;
2013 sx_change_speed(bp, port);
2020 static inline int sx_get_serial_info(struct specialix_port * port,
2021 struct serial_struct __user *retinfo)
2023 struct serial_struct tmp;
2024 struct specialix_board *bp = port_Board(port);
2029 if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
2033 memset(&tmp, 0, sizeof(tmp));
2034 tmp.type = PORT_CIRRUS;
2035 tmp.line = port - sx_port;
2036 tmp.port = bp->base;
2038 tmp.flags = port->flags;
2039 tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
2040 tmp.close_delay = port->close_delay * HZ/100;
2041 tmp.closing_wait = port->closing_wait * HZ/100;
2042 tmp.custom_divisor = port->custom_divisor;
2043 tmp.xmit_fifo_size = CD186x_NFIFO;
2044 if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
2054 static int sx_ioctl(struct tty_struct * tty, struct file * filp,
2055 unsigned int cmd, unsigned long arg)
2057 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2059 void __user *argp = (void __user *)arg;
2063 if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
2069 case TCSBRK: /* SVID version: non-zero arg --> no break */
2070 retval = tty_check_change(tty);
2075 tty_wait_until_sent(tty, 0);
2077 sx_send_break(port, HZ/4); /* 1/4 second */
2079 case TCSBRKP: /* support for POSIX tcsendbreak() */
2080 retval = tty_check_change(tty);
2085 tty_wait_until_sent(tty, 0);
2086 sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
2090 if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) {
2097 if (get_user(arg, (unsigned long __user *) argp)) {
2101 tty->termios->c_cflag =
2102 ((tty->termios->c_cflag & ~CLOCAL) |
2103 (arg ? CLOCAL : 0));
2108 return sx_get_serial_info(port, argp);
2111 return sx_set_serial_info(port, argp);
2114 return -ENOIOCTLCMD;
2121 static void sx_throttle(struct tty_struct * tty)
2123 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2124 struct specialix_board *bp;
2125 unsigned long flags;
2129 if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
2134 bp = port_Board(port);
2136 /* Use DTR instead of RTS ! */
2137 if (SX_CRTSCTS (tty))
2138 port->MSVR &= ~MSVR_DTR;
2140 /* Auch!!! I think the system shouldn't call this then. */
2141 /* Or maybe we're supposed (allowed?) to do our side of hw
2142 handshake anyway, even when hardware handshake is off.
2143 When you see this in your logs, please report.... */
2144 printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
2147 spin_lock_irqsave(&bp->lock, flags);
2148 sx_out(bp, CD186x_CAR, port_No(port));
2149 spin_unlock_irqrestore(&bp->lock, flags);
2151 spin_unlock_irqrestore(&bp->lock, flags);
2153 spin_lock_irqsave(&bp->lock, flags);
2154 sx_out(bp, CD186x_CCR, CCR_SSCH2);
2155 spin_unlock_irqrestore(&bp->lock, flags);
2158 spin_lock_irqsave(&bp->lock, flags);
2159 sx_out(bp, CD186x_MSVR, port->MSVR);
2160 spin_unlock_irqrestore(&bp->lock, flags);
2166 static void sx_unthrottle(struct tty_struct * tty)
2168 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2169 struct specialix_board *bp;
2170 unsigned long flags;
2174 if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
2179 bp = port_Board(port);
2181 spin_lock_irqsave(&port->lock, flags);
2182 /* XXXX Use DTR INSTEAD???? */
2183 if (SX_CRTSCTS(tty)) {
2184 port->MSVR |= MSVR_DTR;
2185 } /* Else clause: see remark in "sx_throttle"... */
2186 spin_lock_irqsave(&bp->lock, flags);
2187 sx_out(bp, CD186x_CAR, port_No(port));
2188 spin_unlock_irqrestore(&bp->lock, flags);
2190 spin_unlock_irqrestore(&port->lock, flags);
2192 spin_lock_irqsave(&bp->lock, flags);
2193 sx_out(bp, CD186x_CCR, CCR_SSCH1);
2194 spin_unlock_irqrestore(&bp->lock, flags);
2196 spin_lock_irqsave(&port->lock, flags);
2198 spin_lock_irqsave(&bp->lock, flags);
2199 sx_out(bp, CD186x_MSVR, port->MSVR);
2200 spin_unlock_irqrestore(&bp->lock, flags);
2201 spin_unlock_irqrestore(&port->lock, flags);
2207 static void sx_stop(struct tty_struct * tty)
2209 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2210 struct specialix_board *bp;
2211 unsigned long flags;
2215 if (sx_paranoia_check(port, tty->name, "sx_stop")) {
2220 bp = port_Board(port);
2222 spin_lock_irqsave(&port->lock, flags);
2223 port->IER &= ~IER_TXRDY;
2224 spin_lock_irqsave(&bp->lock, flags);
2225 sx_out(bp, CD186x_CAR, port_No(port));
2226 sx_out(bp, CD186x_IER, port->IER);
2227 spin_unlock_irqrestore(&bp->lock, flags);
2228 spin_unlock_irqrestore(&port->lock, flags);
2234 static void sx_start(struct tty_struct * tty)
2236 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2237 struct specialix_board *bp;
2238 unsigned long flags;
2242 if (sx_paranoia_check(port, tty->name, "sx_start")) {
2247 bp = port_Board(port);
2249 spin_lock_irqsave(&port->lock, flags);
2250 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2251 port->IER |= IER_TXRDY;
2252 spin_lock_irqsave(&bp->lock, flags);
2253 sx_out(bp, CD186x_CAR, port_No(port));
2254 sx_out(bp, CD186x_IER, port->IER);
2255 spin_unlock_irqrestore(&bp->lock, flags);
2257 spin_unlock_irqrestore(&port->lock, flags);
2264 * This routine is called from the work-queue when the interrupt
2265 * routine has signalled that a hangup has occurred. The path of
2266 * hangup processing is:
2268 * serial interrupt routine -> (workqueue) ->
2269 * do_sx_hangup() -> tty->hangup() -> sx_hangup()
2272 static void do_sx_hangup(void *private_)
2274 struct specialix_port *port = (struct specialix_port *) private_;
2275 struct tty_struct *tty;
2281 tty_hangup(tty); /* FIXME: module removal race here */
2287 static void sx_hangup(struct tty_struct * tty)
2289 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2290 struct specialix_board *bp;
2291 unsigned long flags;
2295 if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2300 bp = port_Board(port);
2302 sx_shutdown_port(bp, port);
2303 spin_lock_irqsave(&port->lock, flags);
2305 bp->count -= port->count;
2306 if (bp->count < 0) {
2307 printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n",
2308 board_No(bp), bp->count, tty->index);
2312 port->flags &= ~ASYNC_NORMAL_ACTIVE;
2314 spin_unlock_irqrestore(&port->lock, flags);
2315 wake_up_interruptible(&port->open_wait);
2321 static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios)
2323 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2324 unsigned long flags;
2325 struct specialix_board * bp;
2327 if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2330 if (tty->termios->c_cflag == old_termios->c_cflag &&
2331 tty->termios->c_iflag == old_termios->c_iflag)
2334 bp = port_Board(port);
2335 spin_lock_irqsave(&port->lock, flags);
2336 sx_change_speed(port_Board(port), port);
2337 spin_unlock_irqrestore(&port->lock, flags);
2339 if ((old_termios->c_cflag & CRTSCTS) &&
2340 !(tty->termios->c_cflag & CRTSCTS)) {
2341 tty->hw_stopped = 0;
2347 static void do_softint(void *private_)
2349 struct specialix_port *port = (struct specialix_port *) private_;
2350 struct tty_struct *tty;
2354 if(!(tty = port->tty)) {
2359 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
2361 //wake_up_interruptible(&tty->write_wait);
2367 static struct tty_operations sx_ops = {
2371 .put_char = sx_put_char,
2372 .flush_chars = sx_flush_chars,
2373 .write_room = sx_write_room,
2374 .chars_in_buffer = sx_chars_in_buffer,
2375 .flush_buffer = sx_flush_buffer,
2377 .throttle = sx_throttle,
2378 .unthrottle = sx_unthrottle,
2379 .set_termios = sx_set_termios,
2382 .hangup = sx_hangup,
2383 .tiocmget = sx_tiocmget,
2384 .tiocmset = sx_tiocmset,
2387 static int sx_init_drivers(void)
2394 specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT);
2395 if (!specialix_driver) {
2396 printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n");
2401 if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
2402 printk(KERN_ERR "sx: Couldn't get free page.\n");
2403 put_tty_driver(specialix_driver);
2407 specialix_driver->owner = THIS_MODULE;
2408 specialix_driver->name = "ttyW";
2409 specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
2410 specialix_driver->type = TTY_DRIVER_TYPE_SERIAL;
2411 specialix_driver->subtype = SERIAL_TYPE_NORMAL;
2412 specialix_driver->init_termios = tty_std_termios;
2413 specialix_driver->init_termios.c_cflag =
2414 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2415 specialix_driver->flags = TTY_DRIVER_REAL_RAW;
2416 tty_set_operations(specialix_driver, &sx_ops);
2418 if ((error = tty_register_driver(specialix_driver))) {
2419 put_tty_driver(specialix_driver);
2420 free_page((unsigned long)tmp_buf);
2421 printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2426 memset(sx_port, 0, sizeof(sx_port));
2427 for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2428 sx_port[i].magic = SPECIALIX_MAGIC;
2429 INIT_WORK(&sx_port[i].tqueue, do_softint, &sx_port[i]);
2430 INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup, &sx_port[i]);
2431 sx_port[i].close_delay = 50 * HZ/100;
2432 sx_port[i].closing_wait = 3000 * HZ/100;
2433 init_waitqueue_head(&sx_port[i].open_wait);
2434 init_waitqueue_head(&sx_port[i].close_wait);
2435 spin_lock_init(&sx_port[i].lock);
2442 static void sx_release_drivers(void)
2446 free_page((unsigned long)tmp_buf);
2447 tty_unregister_driver(specialix_driver);
2448 put_tty_driver(specialix_driver);
2453 * This routine must be called by kernel at boot time
2455 static int __init specialix_init(void)
2462 printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
2463 printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2464 #ifdef CONFIG_SPECIALIX_RTSCTS
2465 printk (KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
2467 printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2470 for (i = 0; i < SX_NBOARD; i++)
2471 spin_lock_init(&sx_board[i].lock);
2473 if (sx_init_drivers()) {
2478 for (i = 0; i < SX_NBOARD; i++)
2479 if (sx_board[i].base && !sx_probe(&sx_board[i]))
2484 struct pci_dev *pdev = NULL;
2487 while (i < SX_NBOARD) {
2488 if (sx_board[i].flags & SX_BOARD_PRESENT) {
2492 pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
2493 PCI_DEVICE_ID_SPECIALIX_IO8,
2497 if (pci_enable_device(pdev))
2500 sx_board[i].irq = pdev->irq;
2502 sx_board[i].base = pci_resource_start (pdev, 2);
2504 sx_board[i].flags |= SX_BOARD_IS_PCI;
2505 if (!sx_probe(&sx_board[i]))
2512 sx_release_drivers();
2513 printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
2522 static int iobase[SX_NBOARD] = {0,};
2524 static int irq [SX_NBOARD] = {0,};
2526 module_param_array(iobase, int, NULL, 0);
2527 module_param_array(irq, int, NULL, 0);
2528 module_param(sx_debug, int, 0);
2529 module_param(sx_rxfifo, int, 0);
2530 #ifdef SPECIALIX_TIMER
2531 module_param(sx_poll, int, 0);
2535 * You can setup up to 4 boards.
2536 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2537 * You should specify the IRQs too in that case "irq=....,...".
2539 * More than 4 boards in one computer is not possible, as the card can
2540 * only use 4 different interrupts.
2543 static int __init specialix_init_module(void)
2549 if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2550 for(i = 0; i < SX_NBOARD; i++) {
2551 sx_board[i].base = iobase[i];
2552 sx_board[i].irq = irq[i];
2553 sx_board[i].count= 0;
2559 return specialix_init();
2562 static void __exit specialix_exit_module(void)
2568 sx_release_drivers();
2569 for (i = 0; i < SX_NBOARD; i++)
2570 if (sx_board[i].flags & SX_BOARD_PRESENT)
2571 sx_release_io_range(&sx_board[i]);
2572 #ifdef SPECIALIX_TIMER
2573 del_timer (&missed_irq_timer);
2579 static struct pci_device_id specialx_pci_tbl[] __devinitdata = {
2580 { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) },
2583 MODULE_DEVICE_TABLE(pci, specialx_pci_tbl);
2585 module_init(specialix_init_module);
2586 module_exit(specialix_exit_module);
2588 MODULE_LICENSE("GPL");