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 <linux/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;
113 static int sx_rtscts;
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", __func__)
136 #define func_exit() dprintk(SX_DEBUG_FLOW, "io8: exit %s\n", __func__)
139 /* Configurable options: */
141 /* Am I paranoid or not ? ;-) */
142 #define SPECIALIX_PARANOIA_CHECK
145 * The following defines are mostly for testing purposes. But if you need
146 * some nice reporting in your syslog, you can define them also.
148 #undef SX_REPORT_FIFO
149 #undef SX_REPORT_OVERRUN
154 #define SPECIALIX_LEGAL_FLAGS \
155 (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \
156 ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \
157 ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
159 static struct tty_driver *specialix_driver;
161 static struct specialix_board sx_board[SX_NBOARD] = {
162 { 0, SX_IOBASE1, 9, },
163 { 0, SX_IOBASE2, 11, },
164 { 0, SX_IOBASE3, 12, },
165 { 0, SX_IOBASE4, 15, },
168 static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
171 static int sx_paranoia_check(struct specialix_port const *port,
172 char *name, const char *routine)
174 #ifdef SPECIALIX_PARANOIA_CHECK
175 static const char *badmagic = KERN_ERR
176 "sx: Warning: bad specialix port magic number for device %s in %s\n";
177 static const char *badinfo = KERN_ERR
178 "sx: Warning: null specialix port for device %s in %s\n";
181 printk(badinfo, name, routine);
184 if (port->magic != SPECIALIX_MAGIC) {
185 printk(badmagic, name, routine);
195 * Service functions for specialix IO8+ driver.
199 /* Get board number from pointer */
200 static inline int board_No(struct specialix_board *bp)
202 return bp - sx_board;
206 /* Get port number from pointer */
207 static inline int port_No(struct specialix_port const *port)
209 return SX_PORT(port - sx_port);
213 /* Get pointer to board from pointer to port */
214 static inline struct specialix_board *port_Board(
215 struct specialix_port const *port)
217 return &sx_board[SX_BOARD(port - sx_port)];
221 /* Input Byte from CL CD186x register */
222 static inline unsigned char sx_in(struct specialix_board *bp,
225 bp->reg = reg | 0x80;
226 outb(reg | 0x80, bp->base + SX_ADDR_REG);
227 return inb(bp->base + SX_DATA_REG);
231 /* Output Byte to CL CD186x register */
232 static inline void sx_out(struct specialix_board *bp, unsigned short reg,
235 bp->reg = reg | 0x80;
236 outb(reg | 0x80, bp->base + SX_ADDR_REG);
237 outb(val, bp->base + SX_DATA_REG);
241 /* Input Byte from CL CD186x register */
242 static inline unsigned char sx_in_off(struct specialix_board *bp,
246 outb(reg, bp->base + SX_ADDR_REG);
247 return inb(bp->base + SX_DATA_REG);
251 /* Output Byte to CL CD186x register */
252 static inline void sx_out_off(struct specialix_board *bp,
253 unsigned short reg, unsigned char val)
256 outb(reg, bp->base + SX_ADDR_REG);
257 outb(val, bp->base + SX_DATA_REG);
261 /* Wait for Channel Command Register ready */
262 static void sx_wait_CCR(struct specialix_board *bp)
264 unsigned long delay, flags;
267 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
268 spin_lock_irqsave(&bp->lock, flags);
269 ccr = sx_in(bp, CD186x_CCR);
270 spin_unlock_irqrestore(&bp->lock, flags);
276 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
280 /* Wait for Channel Command Register ready */
281 static void sx_wait_CCR_off(struct specialix_board *bp)
287 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
288 spin_lock_irqsave(&bp->lock, flags);
289 crr = sx_in_off(bp, CD186x_CCR);
290 spin_unlock_irqrestore(&bp->lock, flags);
296 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
301 * specialix IO8+ IO range functions.
304 static int sx_request_io_range(struct specialix_board *bp)
306 return request_region(bp->base,
307 bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
308 "specialix IO8+") == NULL;
312 static void sx_release_io_range(struct specialix_board *bp)
314 release_region(bp->base, bp->flags & SX_BOARD_IS_PCI ?
315 SX_PCI_IO_SPACE : SX_IO_SPACE);
319 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
320 static int sx_set_irq(struct specialix_board *bp)
326 if (bp->flags & SX_BOARD_IS_PCI)
329 /* In the same order as in the docs... */
342 default:printk(KERN_ERR
343 "Speclialix: cannot set irq to %d.\n", bp->irq);
346 spin_lock_irqsave(&bp->lock, flags);
347 for (i = 0; i < 2; i++) {
348 sx_out(bp, CD186x_CAR, i);
349 sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
351 spin_unlock_irqrestore(&bp->lock, flags);
356 /* Reset and setup CD186x chip */
357 static int sx_init_CD186x(struct specialix_board *bp)
364 sx_wait_CCR_off(bp); /* Wait for CCR ready */
365 spin_lock_irqsave(&bp->lock, flags);
366 sx_out_off(bp, CD186x_CCR, CCR_HARDRESET); /* Reset CD186x chip */
367 spin_unlock_irqrestore(&bp->lock, flags);
368 msleep(50); /* Delay 0.05 sec */
369 spin_lock_irqsave(&bp->lock, flags);
370 sx_out_off(bp, CD186x_GIVR, SX_ID); /* Set ID for this chip */
371 sx_out_off(bp, CD186x_GICR, 0); /* Clear all bits */
372 sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT); /* Prio for modem intr */
373 sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */
374 sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
376 sx_out_off(bp, CD186x_SRCR, sx_in(bp, CD186x_SRCR) | SRCR_REGACKEN);
378 /* Setting up prescaler. We need 4 ticks per 1 ms */
379 scaler = SX_OSCFREQ/SPECIALIX_TPS;
381 sx_out_off(bp, CD186x_PPRH, scaler >> 8);
382 sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
383 spin_unlock_irqrestore(&bp->lock, flags);
385 if (!sx_set_irq(bp)) {
386 /* Figure out how to pass this along... */
387 printk(KERN_ERR "Cannot set irq to %d.\n", bp->irq);
396 static int read_cross_byte(struct specialix_board *bp, int reg, int bit)
402 spin_lock_irqsave(&bp->lock, flags);
403 for (i = 0, t = 0; i < 8; i++) {
404 sx_out_off(bp, CD186x_CAR, i);
405 if (sx_in_off(bp, reg) & bit)
408 spin_unlock_irqrestore(&bp->lock, flags);
414 /* Main probing routine, also sets irq. */
415 static int sx_probe(struct specialix_board *bp)
417 unsigned char val1, val2;
423 if (sx_request_io_range(bp)) {
428 /* Are the I/O ports here ? */
429 sx_out_off(bp, CD186x_PPRL, 0x5a);
431 val1 = sx_in_off(bp, CD186x_PPRL);
433 sx_out_off(bp, CD186x_PPRL, 0xa5);
435 val2 = sx_in_off(bp, CD186x_PPRL);
438 if (val1 != 0x5a || val2 != 0xa5) {
440 "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
441 board_No(bp), bp->base);
442 sx_release_io_range(bp);
447 /* Check the DSR lines that Specialix uses as board
449 val1 = read_cross_byte(bp, CD186x_MSVR, MSVR_DSR);
450 val2 = read_cross_byte(bp, CD186x_MSVR, MSVR_RTS);
451 dprintk(SX_DEBUG_INIT,
452 "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
453 board_No(bp), val1, val2);
455 /* They managed to switch the bit order between the docs and
456 the IO8+ card. The new PCI card now conforms to old docs.
457 They changed the PCI docs to reflect the situation on the
459 val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
462 "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
463 board_No(bp), val2, bp->base, val1);
464 sx_release_io_range(bp);
470 /* Reset CD186x again */
471 if (!sx_init_CD186x(bp)) {
472 sx_release_io_range(bp);
477 sx_request_io_range(bp);
478 bp->flags |= SX_BOARD_PRESENT;
480 /* Chip revcode pkgtype
485 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
487 -- Thanks to Gwen Wang, Cirrus Logic.
490 switch (sx_in_off(bp, CD186x_GFRCR)) {
506 break; /* Does not exist at this time */
512 dprintk(SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR));
515 "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
516 board_No(bp), bp->base, bp->irq, chip, rev);
524 * Interrupt processing routines.
527 static struct specialix_port *sx_get_port(struct specialix_board *bp,
528 unsigned char const *what)
530 unsigned char channel;
531 struct specialix_port *port = NULL;
533 channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
534 dprintk(SX_DEBUG_CHAN, "channel: %d\n", channel);
535 if (channel < CD186x_NCH) {
536 port = &sx_port[board_No(bp) * SX_NPORT + channel];
537 dprintk(SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n",
538 board_No(bp) * SX_NPORT + channel, port,
539 port->port.flags & ASYNC_INITIALIZED);
541 if (port->port.flags & ASYNC_INITIALIZED) {
542 dprintk(SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
547 printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
548 board_No(bp), what, channel);
553 static void sx_receive_exc(struct specialix_board *bp)
555 struct specialix_port *port;
556 struct tty_struct *tty;
557 unsigned char status;
558 unsigned char ch, flag;
562 port = sx_get_port(bp, "Receive");
564 dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n");
568 tty = port->port.tty;
570 status = sx_in(bp, CD186x_RCSR);
572 dprintk(SX_DEBUG_RX, "status: 0x%x\n", status);
573 if (status & RCSR_OE) {
575 dprintk(SX_DEBUG_FIFO,
576 "sx%d: port %d: Overrun. Total %ld overruns.\n",
577 board_No(bp), port_No(port), port->overrun);
579 status &= port->mark_mask;
581 /* This flip buffer check needs to be below the reading of the
582 status register to reset the chip's IRQ.... */
583 if (tty_buffer_request_room(tty, 1) == 0) {
584 dprintk(SX_DEBUG_FIFO,
585 "sx%d: port %d: Working around flip buffer overflow.\n",
586 board_No(bp), port_No(port));
591 ch = sx_in(bp, CD186x_RDR);
596 if (status & RCSR_TOUT) {
598 "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
599 board_No(bp), port_No(port));
603 } else if (status & RCSR_BREAK) {
604 dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
605 board_No(bp), port_No(port));
607 if (port->port.flags & ASYNC_SAK)
610 } else if (status & RCSR_PE)
613 else if (status & RCSR_FE)
616 else if (status & RCSR_OE)
622 if (tty_insert_flip_char(tty, ch, flag))
623 tty_flip_buffer_push(tty);
628 static void sx_receive(struct specialix_board *bp)
630 struct specialix_port *port;
631 struct tty_struct *tty;
636 port = sx_get_port(bp, "Receive");
638 dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n");
642 tty = port->port.tty;
644 count = sx_in(bp, CD186x_RDCR);
645 dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
646 port->hits[count > 8 ? 9 : count]++;
648 tty_buffer_request_room(tty, count);
651 tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL);
652 tty_flip_buffer_push(tty);
657 static void sx_transmit(struct specialix_board *bp)
659 struct specialix_port *port;
660 struct tty_struct *tty;
664 port = sx_get_port(bp, "Transmit");
669 dprintk(SX_DEBUG_TX, "port: %p\n", port);
670 tty = port->port.tty;
672 if (port->IER & IER_TXEMPTY) {
674 sx_out(bp, CD186x_CAR, port_No(port));
675 port->IER &= ~IER_TXEMPTY;
676 sx_out(bp, CD186x_IER, port->IER);
681 if ((port->xmit_cnt <= 0 && !port->break_length)
682 || tty->stopped || tty->hw_stopped) {
683 sx_out(bp, CD186x_CAR, port_No(port));
684 port->IER &= ~IER_TXRDY;
685 sx_out(bp, CD186x_IER, port->IER);
690 if (port->break_length) {
691 if (port->break_length > 0) {
692 if (port->COR2 & COR2_ETC) {
693 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
694 sx_out(bp, CD186x_TDR, CD186x_C_SBRK);
695 port->COR2 &= ~COR2_ETC;
697 count = min_t(int, port->break_length, 0xff);
698 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
699 sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
700 sx_out(bp, CD186x_TDR, count);
701 port->break_length -= count;
702 if (port->break_length == 0)
703 port->break_length--;
705 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
706 sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
707 sx_out(bp, CD186x_COR2, port->COR2);
709 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
710 port->break_length = 0;
717 count = CD186x_NFIFO;
719 sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
720 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
721 if (--port->xmit_cnt <= 0)
723 } while (--count > 0);
725 if (port->xmit_cnt <= 0) {
726 sx_out(bp, CD186x_CAR, port_No(port));
727 port->IER &= ~IER_TXRDY;
728 sx_out(bp, CD186x_IER, port->IER);
730 if (port->xmit_cnt <= port->wakeup_chars)
737 static void sx_check_modem(struct specialix_board *bp)
739 struct specialix_port *port;
740 struct tty_struct *tty;
744 dprintk(SX_DEBUG_SIGNALS, "Modem intr. ");
745 port = sx_get_port(bp, "Modem");
749 tty = port->port.tty;
751 mcr = sx_in(bp, CD186x_MCR);
753 if ((mcr & MCR_CDCHG)) {
754 dprintk(SX_DEBUG_SIGNALS, "CD just changed... ");
755 msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
757 dprintk(SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
758 wake_up_interruptible(&port->port.open_wait);
760 dprintk(SX_DEBUG_SIGNALS, "Sending HUP.\n");
765 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
766 if (mcr & MCR_CTSCHG) {
767 if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
769 port->IER |= IER_TXRDY;
770 if (port->xmit_cnt <= port->wakeup_chars)
774 port->IER &= ~IER_TXRDY;
776 sx_out(bp, CD186x_IER, port->IER);
778 if (mcr & MCR_DSSXHG) {
779 if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
781 port->IER |= IER_TXRDY;
782 if (port->xmit_cnt <= port->wakeup_chars)
786 port->IER &= ~IER_TXRDY;
788 sx_out(bp, CD186x_IER, port->IER);
790 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
792 /* Clear change bits */
793 sx_out(bp, CD186x_MCR, 0);
797 /* The main interrupt processing routine */
798 static irqreturn_t sx_interrupt(int dummy, void *dev_id)
800 unsigned char status;
802 struct specialix_board *bp = dev_id;
803 unsigned long loop = 0;
809 spin_lock_irqsave(&bp->lock, flags);
811 dprintk(SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__,
812 port_No(sx_get_port(bp, "INT")),
813 SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
814 if (!(bp->flags & SX_BOARD_ACTIVE)) {
815 dprintk(SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n",
817 spin_unlock_irqrestore(&bp->lock, flags);
824 while (++loop < 16) {
825 status = sx_in(bp, CD186x_SRSR) &
826 (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint);
829 if (status & SRSR_RREQint) {
830 ack = sx_in(bp, CD186x_RRAR);
832 if (ack == (SX_ID | GIVR_IT_RCV))
834 else if (ack == (SX_ID | GIVR_IT_REXC))
838 "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
839 board_No(bp), status, ack);
841 } else if (status & SRSR_TREQint) {
842 ack = sx_in(bp, CD186x_TRAR);
844 if (ack == (SX_ID | GIVR_IT_TX))
847 printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
848 board_No(bp), status, ack,
849 port_No(sx_get_port(bp, "Int")));
850 } else if (status & SRSR_MREQint) {
851 ack = sx_in(bp, CD186x_MRAR);
853 if (ack == (SX_ID | GIVR_IT_MODEM))
857 "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
858 board_No(bp), status, ack);
862 sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
865 outb(bp->reg, bp->base + SX_ADDR_REG);
866 spin_unlock_irqrestore(&bp->lock, flags);
873 * Routines for open & close processing.
876 static void turn_ints_off(struct specialix_board *bp)
881 spin_lock_irqsave(&bp->lock, flags);
882 (void) sx_in_off(bp, 0); /* Turn off interrupts. */
883 spin_unlock_irqrestore(&bp->lock, flags);
888 static void turn_ints_on(struct specialix_board *bp)
894 spin_lock_irqsave(&bp->lock, flags);
895 (void) sx_in(bp, 0); /* Turn ON interrupts. */
896 spin_unlock_irqrestore(&bp->lock, flags);
902 /* Called with disabled interrupts */
903 static int sx_setup_board(struct specialix_board *bp)
907 if (bp->flags & SX_BOARD_ACTIVE)
910 if (bp->flags & SX_BOARD_IS_PCI)
911 error = request_irq(bp->irq, sx_interrupt,
912 IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp);
914 error = request_irq(bp->irq, sx_interrupt,
915 IRQF_DISABLED, "specialix IO8+", bp);
921 bp->flags |= SX_BOARD_ACTIVE;
927 /* Called with disabled interrupts */
928 static void sx_shutdown_board(struct specialix_board *bp)
932 if (!(bp->flags & SX_BOARD_ACTIVE)) {
937 bp->flags &= ~SX_BOARD_ACTIVE;
939 dprintk(SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
940 bp->irq, board_No(bp));
941 free_irq(bp->irq, bp);
946 static unsigned int sx_crtscts(struct tty_struct *tty)
949 return C_CRTSCTS(tty);
954 * Setting up port characteristics.
955 * Must be called with disabled interrupts
957 static void sx_change_speed(struct specialix_board *bp,
958 struct specialix_port *port)
960 struct tty_struct *tty;
963 unsigned char cor1 = 0, cor3 = 0;
964 unsigned char mcor1 = 0, mcor2 = 0;
965 static unsigned long again;
970 tty = port->port.tty;
971 if (!tty || !tty->termios) {
978 /* Select port on the board */
979 spin_lock_irqsave(&bp->lock, flags);
980 sx_out(bp, CD186x_CAR, port_No(port));
982 /* The Specialix board doens't implement the RTS lines.
983 They are used to set the IRQ level. Don't touch them. */
985 port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
987 port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
988 spin_unlock_irqrestore(&bp->lock, flags);
989 dprintk(SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
990 baud = tty_get_baud_rate(tty);
993 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
995 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1000 /* Drop DTR & exit */
1001 dprintk(SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
1002 if (!sx_crtscts(tty)) {
1003 port->MSVR &= ~MSVR_DTR;
1004 spin_lock_irqsave(&bp->lock, flags);
1005 sx_out(bp, CD186x_MSVR, port->MSVR);
1006 spin_unlock_irqrestore(&bp->lock, flags);
1008 dprintk(SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1012 if (!sx_crtscts(tty))
1013 port->MSVR |= MSVR_DTR;
1017 * Now we must calculate some speed depended things
1020 /* Set baud rate for port */
1021 tmp = port->custom_divisor ;
1024 "sx%d: Using custom baud rate divisor %ld. \n"
1025 "This is an untested option, please be careful.\n",
1026 port_No(port), tmp);
1028 tmp = (((SX_OSCFREQ + baud/2) / baud + CD186x_TPC/2) /
1031 if (tmp < 0x10 && time_before(again, jiffies)) {
1032 again = jiffies + HZ * 60;
1033 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1035 printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1036 "Performance degradation is possible.\n"
1037 "Read specialix.txt for more info.\n",
1038 port_No(port), tmp);
1040 printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1041 "Warning: overstressing Cirrus chip. This might not work.\n"
1042 "Read specialix.txt for more info.\n", port_No(port), tmp);
1045 spin_lock_irqsave(&bp->lock, flags);
1046 sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1047 sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1048 sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1049 sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1050 spin_unlock_irqrestore(&bp->lock, flags);
1051 if (port->custom_divisor)
1052 baud = (SX_OSCFREQ + port->custom_divisor/2) /
1053 port->custom_divisor;
1054 baud = (baud + 5) / 10; /* Estimated CPS */
1056 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1057 tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1058 port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1059 SERIAL_XMIT_SIZE - 1 : tmp);
1061 /* Receiver timeout will be transmission time for 1.5 chars */
1062 tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1063 tmp = (tmp > 0xff) ? 0xff : tmp;
1064 spin_lock_irqsave(&bp->lock, flags);
1065 sx_out(bp, CD186x_RTPR, tmp);
1066 spin_unlock_irqrestore(&bp->lock, flags);
1067 switch (C_CSIZE(tty)) {
1085 cor1 |= COR1_IGNORE;
1086 if (C_PARENB(tty)) {
1087 cor1 |= COR1_NORMPAR;
1091 cor1 &= ~COR1_IGNORE;
1093 /* Set marking of some errors */
1094 port->mark_mask = RCSR_OE | RCSR_TOUT;
1096 port->mark_mask |= RCSR_FE | RCSR_PE;
1097 if (I_BRKINT(tty) || I_PARMRK(tty))
1098 port->mark_mask |= RCSR_BREAK;
1100 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1101 if (I_IGNBRK(tty)) {
1102 port->mark_mask &= ~RCSR_BREAK;
1104 /* Real raw mode. Ignore all */
1105 port->mark_mask &= ~RCSR_OE;
1107 /* Enable Hardware Flow Control */
1108 if (C_CRTSCTS(tty)) {
1109 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1110 port->IER |= IER_DSR | IER_CTS;
1111 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1112 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1113 spin_lock_irqsave(&bp->lock, flags);
1114 tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) &
1115 (MSVR_CTS|MSVR_DSR));
1116 spin_unlock_irqrestore(&bp->lock, flags);
1118 port->COR2 |= COR2_CTSAE;
1121 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1122 /* Some people reported that it works, but I still doubt it */
1124 port->COR2 |= COR2_TXIBE;
1125 cor3 |= (COR3_FCT | COR3_SCDE);
1127 port->COR2 |= COR2_IXM;
1128 spin_lock_irqsave(&bp->lock, flags);
1129 sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1130 sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1131 sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1132 sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1133 spin_unlock_irqrestore(&bp->lock, flags);
1135 if (!C_CLOCAL(tty)) {
1136 /* Enable CD check */
1137 port->IER |= IER_CD;
1138 mcor1 |= MCOR1_CDZD;
1139 mcor2 |= MCOR2_CDOD;
1143 /* Enable receiver */
1144 port->IER |= IER_RXD;
1146 /* Set input FIFO size (1-8 bytes) */
1148 /* Setting up CD186x channel registers */
1149 spin_lock_irqsave(&bp->lock, flags);
1150 sx_out(bp, CD186x_COR1, cor1);
1151 sx_out(bp, CD186x_COR2, port->COR2);
1152 sx_out(bp, CD186x_COR3, cor3);
1153 spin_unlock_irqrestore(&bp->lock, flags);
1154 /* Make CD186x know about registers change */
1156 spin_lock_irqsave(&bp->lock, flags);
1157 sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1158 /* Setting up modem option registers */
1159 dprintk(SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n",
1161 sx_out(bp, CD186x_MCOR1, mcor1);
1162 sx_out(bp, CD186x_MCOR2, mcor2);
1163 spin_unlock_irqrestore(&bp->lock, flags);
1164 /* Enable CD186x transmitter & receiver */
1166 spin_lock_irqsave(&bp->lock, flags);
1167 sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1168 /* Enable interrupts */
1169 sx_out(bp, CD186x_IER, port->IER);
1170 /* And finally set the modem lines... */
1171 sx_out(bp, CD186x_MSVR, port->MSVR);
1172 spin_unlock_irqrestore(&bp->lock, flags);
1178 /* Must be called with interrupts enabled */
1179 static int sx_setup_port(struct specialix_board *bp,
1180 struct specialix_port *port)
1182 unsigned long flags;
1186 if (port->port.flags & ASYNC_INITIALIZED) {
1191 if (!port->xmit_buf) {
1192 /* We may sleep in get_zeroed_page() */
1195 tmp = get_zeroed_page(GFP_KERNEL);
1201 if (port->xmit_buf) {
1204 return -ERESTARTSYS;
1206 port->xmit_buf = (unsigned char *) tmp;
1209 spin_lock_irqsave(&port->lock, flags);
1212 clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
1214 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1215 sx_change_speed(bp, port);
1216 port->port.flags |= ASYNC_INITIALIZED;
1218 spin_unlock_irqrestore(&port->lock, flags);
1226 /* Must be called with interrupts disabled */
1227 static void sx_shutdown_port(struct specialix_board *bp,
1228 struct specialix_port *port)
1230 struct tty_struct *tty;
1232 unsigned long flags;
1236 if (!(port->port.flags & ASYNC_INITIALIZED)) {
1241 if (sx_debug & SX_DEBUG_FIFO) {
1242 dprintk(SX_DEBUG_FIFO,
1243 "sx%d: port %d: %ld overruns, FIFO hits [ ",
1244 board_No(bp), port_No(port), port->overrun);
1245 for (i = 0; i < 10; i++)
1246 dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1247 dprintk(SX_DEBUG_FIFO, "].\n");
1250 if (port->xmit_buf) {
1251 free_page((unsigned long) port->xmit_buf);
1252 port->xmit_buf = NULL;
1256 spin_lock_irqsave(&bp->lock, flags);
1257 sx_out(bp, CD186x_CAR, port_No(port));
1259 tty = port->port.tty;
1260 if (tty == NULL || C_HUPCL(tty)) {
1262 sx_out(bp, CD186x_MSVDTR, 0);
1264 spin_unlock_irqrestore(&bp->lock, flags);
1267 spin_lock_irqsave(&bp->lock, flags);
1268 sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1269 /* Disable all interrupts from this port */
1271 sx_out(bp, CD186x_IER, port->IER);
1272 spin_unlock_irqrestore(&bp->lock, flags);
1274 set_bit(TTY_IO_ERROR, &tty->flags);
1275 port->port.flags &= ~ASYNC_INITIALIZED;
1278 sx_shutdown_board(bp);
1283 static int block_til_ready(struct tty_struct *tty, struct file *filp,
1284 struct specialix_port *port)
1286 DECLARE_WAITQUEUE(wait, current);
1287 struct specialix_board *bp = port_Board(port);
1291 unsigned long flags;
1296 * If the device is in the middle of being closed, then block
1297 * until it's done, and then try again.
1299 if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
1300 interruptible_sleep_on(&port->port.close_wait);
1301 if (port->port.flags & ASYNC_HUP_NOTIFY) {
1306 return -ERESTARTSYS;
1311 * If non-blocking mode is set, or the port is not enabled,
1312 * then make the check up front and then exit.
1314 if ((filp->f_flags & O_NONBLOCK) ||
1315 (tty->flags & (1 << TTY_IO_ERROR))) {
1316 port->port.flags |= ASYNC_NORMAL_ACTIVE;
1325 * Block waiting for the carrier detect and the line to become
1326 * free (i.e., not in use by the callout). While we are in
1327 * this loop, info->count is dropped by one, so that
1328 * rs_close() knows when to free things. We restore it upon
1329 * exit, either normal or abnormal.
1332 add_wait_queue(&port->port.open_wait, &wait);
1333 spin_lock_irqsave(&port->lock, flags);
1334 if (!tty_hung_up_p(filp))
1336 spin_unlock_irqrestore(&port->lock, flags);
1337 port->port.blocked_open++;
1339 spin_lock_irqsave(&bp->lock, flags);
1340 sx_out(bp, CD186x_CAR, port_No(port));
1341 CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1342 if (sx_crtscts(tty)) {
1344 port->MSVR |= MSVR_DTR; /* WTF? */
1345 sx_out(bp, CD186x_MSVR, port->MSVR);
1348 port->MSVR |= MSVR_DTR;
1349 sx_out(bp, CD186x_MSVR, port->MSVR);
1351 spin_unlock_irqrestore(&bp->lock, flags);
1352 set_current_state(TASK_INTERRUPTIBLE);
1353 if (tty_hung_up_p(filp) ||
1354 !(port->port.flags & ASYNC_INITIALIZED)) {
1355 if (port->port.flags & ASYNC_HUP_NOTIFY)
1358 retval = -ERESTARTSYS;
1361 if (!(port->port.flags & ASYNC_CLOSING) &&
1364 if (signal_pending(current)) {
1365 retval = -ERESTARTSYS;
1371 set_current_state(TASK_RUNNING);
1372 remove_wait_queue(&port->port.open_wait, &wait);
1373 spin_lock_irqsave(&port->lock, flags);
1374 if (!tty_hung_up_p(filp))
1376 port->port.blocked_open--;
1377 spin_unlock_irqrestore(&port->lock, flags);
1383 port->port.flags |= ASYNC_NORMAL_ACTIVE;
1389 static int sx_open(struct tty_struct *tty, struct file *filp)
1393 struct specialix_port *port;
1394 struct specialix_board *bp;
1396 unsigned long flags;
1400 board = SX_BOARD(tty->index);
1402 if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1407 bp = &sx_board[board];
1408 port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1410 for (i = 0; i < 10; i++)
1413 dprintk(SX_DEBUG_OPEN,
1414 "Board = %d, bp = %p, port = %p, portno = %d.\n",
1415 board, bp, port, SX_PORT(tty->index));
1417 if (sx_paranoia_check(port, tty->name, "sx_open")) {
1422 error = sx_setup_board(bp);
1428 spin_lock_irqsave(&bp->lock, flags);
1431 tty->driver_data = port;
1432 port->port.tty = tty;
1433 spin_unlock_irqrestore(&bp->lock, flags);
1435 error = sx_setup_port(bp, port);
1441 error = block_til_ready(tty, filp, port);
1451 static void sx_flush_buffer(struct tty_struct *tty)
1453 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1454 unsigned long flags;
1455 struct specialix_board *bp;
1459 if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
1464 bp = port_Board(port);
1465 spin_lock_irqsave(&port->lock, flags);
1466 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1467 spin_unlock_irqrestore(&port->lock, flags);
1473 static void sx_close(struct tty_struct *tty, struct file *filp)
1475 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1476 struct specialix_board *bp;
1477 unsigned long flags;
1478 unsigned long timeout;
1481 if (!port || sx_paranoia_check(port, tty->name, "close")) {
1485 spin_lock_irqsave(&port->lock, flags);
1487 if (tty_hung_up_p(filp)) {
1488 spin_unlock_irqrestore(&port->lock, flags);
1493 bp = port_Board(port);
1494 if (tty->count == 1 && port->port.count != 1) {
1495 printk(KERN_ERR "sx%d: sx_close: bad port count;"
1496 " tty->count is 1, port count is %d\n",
1497 board_No(bp), port->port.count);
1498 port->port.count = 1;
1501 if (port->port.count > 1) {
1505 spin_unlock_irqrestore(&port->lock, flags);
1510 port->port.flags |= ASYNC_CLOSING;
1512 * Now we wait for the transmit buffer to clear; and we notify
1513 * the line discipline to only process XON/XOFF characters.
1516 spin_unlock_irqrestore(&port->lock, flags);
1517 dprintk(SX_DEBUG_OPEN, "Closing\n");
1518 if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1519 tty_wait_until_sent(tty, port->port.closing_wait);
1521 * At this point we stop accepting input. To do this, we
1522 * disable the receive line status interrupts, and tell the
1523 * interrupt driver to stop checking the data ready bit in the
1524 * line status register.
1526 dprintk(SX_DEBUG_OPEN, "Closed\n");
1527 port->IER &= ~IER_RXD;
1528 if (port->port.flags & ASYNC_INITIALIZED) {
1529 port->IER &= ~IER_TXRDY;
1530 port->IER |= IER_TXEMPTY;
1531 spin_lock_irqsave(&bp->lock, flags);
1532 sx_out(bp, CD186x_CAR, port_No(port));
1533 sx_out(bp, CD186x_IER, port->IER);
1534 spin_unlock_irqrestore(&bp->lock, flags);
1536 * Before we drop DTR, make sure the UART transmitter
1537 * has completely drained; this is especially
1538 * important if there is a transmit FIFO!
1540 timeout = jiffies+HZ;
1541 while (port->IER & IER_TXEMPTY) {
1542 set_current_state(TASK_INTERRUPTIBLE);
1543 msleep_interruptible(jiffies_to_msecs(port->timeout));
1544 if (time_after(jiffies, timeout)) {
1545 printk(KERN_INFO "Timeout waiting for close\n");
1552 if (--bp->count < 0) {
1554 "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1555 board_No(bp), bp->count, tty->index);
1558 if (--port->port.count < 0) {
1560 "sx%d: sx_close: bad port count for tty%d: %d\n",
1561 board_No(bp), port_No(port), port->port.count);
1562 port->port.count = 0;
1565 sx_shutdown_port(bp, port);
1566 sx_flush_buffer(tty);
1567 tty_ldisc_flush(tty);
1568 spin_lock_irqsave(&port->lock, flags);
1570 port->port.tty = NULL;
1571 spin_unlock_irqrestore(&port->lock, flags);
1572 if (port->port.blocked_open) {
1573 if (port->port.close_delay)
1574 msleep_interruptible(
1575 jiffies_to_msecs(port->port.close_delay));
1576 wake_up_interruptible(&port->port.open_wait);
1578 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1579 wake_up_interruptible(&port->port.close_wait);
1585 static int sx_write(struct tty_struct *tty,
1586 const unsigned char *buf, int count)
1588 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1589 struct specialix_board *bp;
1591 unsigned long flags;
1594 if (sx_paranoia_check(port, tty->name, "sx_write")) {
1599 bp = port_Board(port);
1601 if (!port->xmit_buf) {
1607 spin_lock_irqsave(&port->lock, flags);
1608 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1609 SERIAL_XMIT_SIZE - port->xmit_head));
1611 spin_unlock_irqrestore(&port->lock, flags);
1614 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1615 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1616 port->xmit_cnt += c;
1617 spin_unlock_irqrestore(&port->lock, flags);
1624 spin_lock_irqsave(&bp->lock, flags);
1625 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1626 !(port->IER & IER_TXRDY)) {
1627 port->IER |= IER_TXRDY;
1628 sx_out(bp, CD186x_CAR, port_No(port));
1629 sx_out(bp, CD186x_IER, port->IER);
1631 spin_unlock_irqrestore(&bp->lock, flags);
1638 static int sx_put_char(struct tty_struct *tty, unsigned char ch)
1640 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1641 unsigned long flags;
1642 struct specialix_board *bp;
1646 if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1650 dprintk(SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1651 if (!port->xmit_buf) {
1655 bp = port_Board(port);
1656 spin_lock_irqsave(&port->lock, flags);
1658 dprintk(SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n",
1659 port->xmit_cnt, port->xmit_buf);
1660 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1 || !port->xmit_buf) {
1661 spin_unlock_irqrestore(&port->lock, flags);
1662 dprintk(SX_DEBUG_TX, "Exit size\n");
1666 dprintk(SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
1667 port->xmit_buf[port->xmit_head++] = ch;
1668 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1670 spin_unlock_irqrestore(&port->lock, flags);
1677 static void sx_flush_chars(struct tty_struct *tty)
1679 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1680 unsigned long flags;
1681 struct specialix_board *bp = port_Board(port);
1685 if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1689 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1694 spin_lock_irqsave(&bp->lock, flags);
1695 port->IER |= IER_TXRDY;
1696 sx_out(port_Board(port), CD186x_CAR, port_No(port));
1697 sx_out(port_Board(port), CD186x_IER, port->IER);
1698 spin_unlock_irqrestore(&bp->lock, flags);
1704 static int sx_write_room(struct tty_struct *tty)
1706 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1711 if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1716 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1725 static int sx_chars_in_buffer(struct tty_struct *tty)
1727 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1731 if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
1736 return port->xmit_cnt;
1739 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1741 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1742 struct specialix_board *bp;
1743 unsigned char status;
1744 unsigned int result;
1745 unsigned long flags;
1749 if (sx_paranoia_check(port, tty->name, __func__)) {
1754 bp = port_Board(port);
1755 spin_lock_irqsave(&bp->lock, flags);
1756 sx_out(bp, CD186x_CAR, port_No(port));
1757 status = sx_in(bp, CD186x_MSVR);
1758 spin_unlock_irqrestore(&bp->lock, flags);
1759 dprintk(SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1760 port_No(port), status, sx_in(bp, CD186x_CAR));
1761 dprintk(SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1762 if (sx_crtscts(port->port.tty)) {
1763 result = TIOCM_DTR | TIOCM_DSR
1764 | ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1765 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1766 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1768 result = TIOCM_RTS | TIOCM_DSR
1769 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1770 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1771 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1780 static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1781 unsigned int set, unsigned int clear)
1783 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1784 unsigned long flags;
1785 struct specialix_board *bp;
1789 if (sx_paranoia_check(port, tty->name, __func__)) {
1794 bp = port_Board(port);
1796 spin_lock_irqsave(&port->lock, flags);
1797 if (sx_crtscts(port->port.tty)) {
1798 if (set & TIOCM_RTS)
1799 port->MSVR |= MSVR_DTR;
1801 if (set & TIOCM_DTR)
1802 port->MSVR |= MSVR_DTR;
1804 if (sx_crtscts(port->port.tty)) {
1805 if (clear & TIOCM_RTS)
1806 port->MSVR &= ~MSVR_DTR;
1808 if (clear & TIOCM_DTR)
1809 port->MSVR &= ~MSVR_DTR;
1811 spin_lock_irqsave(&bp->lock, flags);
1812 sx_out(bp, CD186x_CAR, port_No(port));
1813 sx_out(bp, CD186x_MSVR, port->MSVR);
1814 spin_unlock_irqrestore(&bp->lock, flags);
1815 spin_unlock_irqrestore(&port->lock, flags);
1821 static void sx_send_break(struct specialix_port *port,
1822 unsigned long length)
1824 struct specialix_board *bp = port_Board(port);
1825 unsigned long flags;
1829 spin_lock_irqsave(&port->lock, flags);
1830 port->break_length = SPECIALIX_TPS / HZ * length;
1831 port->COR2 |= COR2_ETC;
1832 port->IER |= IER_TXRDY;
1833 spin_lock_irqsave(&bp->lock, flags);
1834 sx_out(bp, CD186x_CAR, port_No(port));
1835 sx_out(bp, CD186x_COR2, port->COR2);
1836 sx_out(bp, CD186x_IER, port->IER);
1837 spin_unlock_irqrestore(&bp->lock, flags);
1838 spin_unlock_irqrestore(&port->lock, flags);
1840 spin_lock_irqsave(&bp->lock, flags);
1841 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1842 spin_unlock_irqrestore(&bp->lock, flags);
1849 static int sx_set_serial_info(struct specialix_port *port,
1850 struct serial_struct __user *newinfo)
1852 struct serial_struct tmp;
1853 struct specialix_board *bp = port_Board(port);
1858 if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
1865 change_speed = ((port->port.flags & ASYNC_SPD_MASK) !=
1866 (tmp.flags & ASYNC_SPD_MASK));
1867 change_speed |= (tmp.custom_divisor != port->custom_divisor);
1869 if (!capable(CAP_SYS_ADMIN)) {
1870 if ((tmp.close_delay != port->port.close_delay) ||
1871 (tmp.closing_wait != port->port.closing_wait) ||
1872 ((tmp.flags & ~ASYNC_USR_MASK) !=
1873 (port->port.flags & ~ASYNC_USR_MASK))) {
1878 port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1879 (tmp.flags & ASYNC_USR_MASK));
1880 port->custom_divisor = tmp.custom_divisor;
1882 port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1883 (tmp.flags & ASYNC_FLAGS));
1884 port->port.close_delay = tmp.close_delay;
1885 port->port.closing_wait = tmp.closing_wait;
1886 port->custom_divisor = tmp.custom_divisor;
1889 sx_change_speed(bp, port);
1897 static int sx_get_serial_info(struct specialix_port *port,
1898 struct serial_struct __user *retinfo)
1900 struct serial_struct tmp;
1901 struct specialix_board *bp = port_Board(port);
1905 memset(&tmp, 0, sizeof(tmp));
1907 tmp.type = PORT_CIRRUS;
1908 tmp.line = port - sx_port;
1909 tmp.port = bp->base;
1911 tmp.flags = port->port.flags;
1912 tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
1913 tmp.close_delay = port->port.close_delay * HZ/100;
1914 tmp.closing_wait = port->port.closing_wait * HZ/100;
1915 tmp.custom_divisor = port->custom_divisor;
1916 tmp.xmit_fifo_size = CD186x_NFIFO;
1918 if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
1928 static int sx_ioctl(struct tty_struct *tty, struct file *filp,
1929 unsigned int cmd, unsigned long arg)
1931 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1933 void __user *argp = (void __user *)arg;
1937 if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
1943 case TCSBRK: /* SVID version: non-zero arg --> no break */
1944 retval = tty_check_change(tty);
1949 tty_wait_until_sent(tty, 0);
1951 sx_send_break(port, HZ/4); /* 1/4 second */
1953 case TCSBRKP: /* support for POSIX tcsendbreak() */
1954 retval = tty_check_change(tty);
1959 tty_wait_until_sent(tty, 0);
1960 sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
1965 return sx_get_serial_info(port, argp);
1968 return sx_set_serial_info(port, argp);
1971 return -ENOIOCTLCMD;
1978 static void sx_throttle(struct tty_struct *tty)
1980 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1981 struct specialix_board *bp;
1982 unsigned long flags;
1986 if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
1991 bp = port_Board(port);
1993 /* Use DTR instead of RTS ! */
1994 if (sx_crtscts(tty))
1995 port->MSVR &= ~MSVR_DTR;
1997 /* Auch!!! I think the system shouldn't call this then. */
1998 /* Or maybe we're supposed (allowed?) to do our side of hw
1999 handshake anyway, even when hardware handshake is off.
2000 When you see this in your logs, please report.... */
2002 "sx%d: Need to throttle, but can't (hardware hs is off)\n",
2005 spin_lock_irqsave(&bp->lock, flags);
2006 sx_out(bp, CD186x_CAR, port_No(port));
2007 spin_unlock_irqrestore(&bp->lock, flags);
2010 spin_lock_irqsave(&bp->lock, flags);
2011 sx_out(bp, CD186x_CCR, CCR_SSCH2);
2012 spin_unlock_irqrestore(&bp->lock, flags);
2015 spin_lock_irqsave(&bp->lock, flags);
2016 sx_out(bp, CD186x_MSVR, port->MSVR);
2017 spin_unlock_irqrestore(&bp->lock, flags);
2023 static void sx_unthrottle(struct tty_struct *tty)
2025 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2026 struct specialix_board *bp;
2027 unsigned long flags;
2031 if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
2036 bp = port_Board(port);
2038 spin_lock_irqsave(&port->lock, flags);
2039 /* XXXX Use DTR INSTEAD???? */
2040 if (sx_crtscts(tty))
2041 port->MSVR |= MSVR_DTR;
2042 /* Else clause: see remark in "sx_throttle"... */
2043 spin_lock_irqsave(&bp->lock, flags);
2044 sx_out(bp, CD186x_CAR, port_No(port));
2045 spin_unlock_irqrestore(&bp->lock, flags);
2047 spin_unlock_irqrestore(&port->lock, flags);
2049 spin_lock_irqsave(&bp->lock, flags);
2050 sx_out(bp, CD186x_CCR, CCR_SSCH1);
2051 spin_unlock_irqrestore(&bp->lock, flags);
2053 spin_lock_irqsave(&port->lock, flags);
2055 spin_lock_irqsave(&bp->lock, flags);
2056 sx_out(bp, CD186x_MSVR, port->MSVR);
2057 spin_unlock_irqrestore(&bp->lock, flags);
2058 spin_unlock_irqrestore(&port->lock, flags);
2064 static void sx_stop(struct tty_struct *tty)
2066 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2067 struct specialix_board *bp;
2068 unsigned long flags;
2072 if (sx_paranoia_check(port, tty->name, "sx_stop")) {
2077 bp = port_Board(port);
2079 spin_lock_irqsave(&port->lock, flags);
2080 port->IER &= ~IER_TXRDY;
2081 spin_lock_irqsave(&bp->lock, flags);
2082 sx_out(bp, CD186x_CAR, port_No(port));
2083 sx_out(bp, CD186x_IER, port->IER);
2084 spin_unlock_irqrestore(&bp->lock, flags);
2085 spin_unlock_irqrestore(&port->lock, flags);
2091 static void sx_start(struct tty_struct *tty)
2093 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2094 struct specialix_board *bp;
2095 unsigned long flags;
2099 if (sx_paranoia_check(port, tty->name, "sx_start")) {
2104 bp = port_Board(port);
2106 spin_lock_irqsave(&port->lock, flags);
2107 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2108 port->IER |= IER_TXRDY;
2109 spin_lock_irqsave(&bp->lock, flags);
2110 sx_out(bp, CD186x_CAR, port_No(port));
2111 sx_out(bp, CD186x_IER, port->IER);
2112 spin_unlock_irqrestore(&bp->lock, flags);
2114 spin_unlock_irqrestore(&port->lock, flags);
2119 static void sx_hangup(struct tty_struct *tty)
2121 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2122 struct specialix_board *bp;
2123 unsigned long flags;
2127 if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2132 bp = port_Board(port);
2134 sx_shutdown_port(bp, port);
2135 spin_lock_irqsave(&port->lock, flags);
2136 bp->count -= port->port.count;
2137 if (bp->count < 0) {
2139 "sx%d: sx_hangup: bad board count: %d port: %d\n",
2140 board_No(bp), bp->count, tty->index);
2143 port->port.count = 0;
2144 port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
2145 port->port.tty = NULL;
2146 spin_unlock_irqrestore(&port->lock, flags);
2147 wake_up_interruptible(&port->port.open_wait);
2153 static void sx_set_termios(struct tty_struct *tty,
2154 struct ktermios *old_termios)
2156 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2157 unsigned long flags;
2158 struct specialix_board *bp;
2160 if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2163 bp = port_Board(port);
2164 spin_lock_irqsave(&port->lock, flags);
2165 sx_change_speed(port_Board(port), port);
2166 spin_unlock_irqrestore(&port->lock, flags);
2168 if ((old_termios->c_cflag & CRTSCTS) &&
2169 !(tty->termios->c_cflag & CRTSCTS)) {
2170 tty->hw_stopped = 0;
2175 static const struct tty_operations sx_ops = {
2179 .put_char = sx_put_char,
2180 .flush_chars = sx_flush_chars,
2181 .write_room = sx_write_room,
2182 .chars_in_buffer = sx_chars_in_buffer,
2183 .flush_buffer = sx_flush_buffer,
2185 .throttle = sx_throttle,
2186 .unthrottle = sx_unthrottle,
2187 .set_termios = sx_set_termios,
2190 .hangup = sx_hangup,
2191 .tiocmget = sx_tiocmget,
2192 .tiocmset = sx_tiocmset,
2195 static int sx_init_drivers(void)
2202 specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT);
2203 if (!specialix_driver) {
2204 printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n");
2209 specialix_driver->owner = THIS_MODULE;
2210 specialix_driver->name = "ttyW";
2211 specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
2212 specialix_driver->type = TTY_DRIVER_TYPE_SERIAL;
2213 specialix_driver->subtype = SERIAL_TYPE_NORMAL;
2214 specialix_driver->init_termios = tty_std_termios;
2215 specialix_driver->init_termios.c_cflag =
2216 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2217 specialix_driver->init_termios.c_ispeed = 9600;
2218 specialix_driver->init_termios.c_ospeed = 9600;
2219 specialix_driver->flags = TTY_DRIVER_REAL_RAW;
2220 tty_set_operations(specialix_driver, &sx_ops);
2222 error = tty_register_driver(specialix_driver);
2224 put_tty_driver(specialix_driver);
2226 "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2231 memset(sx_port, 0, sizeof(sx_port));
2232 for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2233 sx_port[i].magic = SPECIALIX_MAGIC;
2234 tty_port_init(&sx_port[i].port);
2235 spin_lock_init(&sx_port[i].lock);
2242 static void sx_release_drivers(void)
2246 tty_unregister_driver(specialix_driver);
2247 put_tty_driver(specialix_driver);
2252 * This routine must be called by kernel at boot time
2254 static int __init specialix_init(void)
2261 printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
2262 printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2265 "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2267 printk(KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
2269 for (i = 0; i < SX_NBOARD; i++)
2270 spin_lock_init(&sx_board[i].lock);
2272 if (sx_init_drivers()) {
2277 for (i = 0; i < SX_NBOARD; i++)
2278 if (sx_board[i].base && !sx_probe(&sx_board[i]))
2283 struct pci_dev *pdev = NULL;
2286 while (i < SX_NBOARD) {
2287 if (sx_board[i].flags & SX_BOARD_PRESENT) {
2291 pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX,
2292 PCI_DEVICE_ID_SPECIALIX_IO8, pdev);
2296 if (pci_enable_device(pdev))
2299 sx_board[i].irq = pdev->irq;
2301 sx_board[i].base = pci_resource_start(pdev, 2);
2303 sx_board[i].flags |= SX_BOARD_IS_PCI;
2304 if (!sx_probe(&sx_board[i]))
2307 /* May exit pci_get sequence early with lots of boards */
2314 sx_release_drivers();
2315 printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
2324 static int iobase[SX_NBOARD] = {0,};
2325 static int irq[SX_NBOARD] = {0,};
2327 module_param_array(iobase, int, NULL, 0);
2328 module_param_array(irq, int, NULL, 0);
2329 module_param(sx_debug, int, 0);
2330 module_param(sx_rtscts, int, 0);
2331 module_param(sx_rxfifo, int, 0);
2334 * You can setup up to 4 boards.
2335 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2336 * You should specify the IRQs too in that case "irq=....,...".
2338 * More than 4 boards in one computer is not possible, as the card can
2339 * only use 4 different interrupts.
2342 static int __init specialix_init_module(void)
2348 if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2349 for (i = 0; i < SX_NBOARD; i++) {
2350 sx_board[i].base = iobase[i];
2351 sx_board[i].irq = irq[i];
2352 sx_board[i].count = 0;
2358 return specialix_init();
2361 static void __exit specialix_exit_module(void)
2367 sx_release_drivers();
2368 for (i = 0; i < SX_NBOARD; i++)
2369 if (sx_board[i].flags & SX_BOARD_PRESENT)
2370 sx_release_io_range(&sx_board[i]);
2374 static struct pci_device_id specialx_pci_tbl[] __devinitdata = {
2375 { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) },
2378 MODULE_DEVICE_TABLE(pci, specialx_pci_tbl);
2380 module_init(specialix_init_module);
2381 module_exit(specialix_exit_module);
2383 MODULE_LICENSE("GPL");