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;
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", __func__)
135 #define func_exit() dprintk(SX_DEBUG_FLOW, "io8: exit %s\n", __func__)
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 static struct tty_driver *specialix_driver;
183 static struct specialix_board sx_board[SX_NBOARD] = {
184 { 0, SX_IOBASE1, 9, },
185 { 0, SX_IOBASE2, 11, },
186 { 0, SX_IOBASE3, 12, },
187 { 0, SX_IOBASE4, 15, },
190 static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
193 #ifdef SPECIALIX_TIMER
194 static struct timer_list missed_irq_timer;
195 static irqreturn_t sx_interrupt(int irq, void *dev_id);
200 static inline int sx_paranoia_check(struct specialix_port const *port,
201 char *name, const char *routine)
203 #ifdef SPECIALIX_PARANOIA_CHECK
204 static const char *badmagic = KERN_ERR
205 "sx: Warning: bad specialix port magic number for device %s in %s\n";
206 static const char *badinfo = KERN_ERR
207 "sx: Warning: null specialix port for device %s in %s\n";
210 printk(badinfo, name, routine);
213 if (port->magic != SPECIALIX_MAGIC) {
214 printk(badmagic, name, routine);
224 * Service functions for specialix IO8+ driver.
228 /* Get board number from pointer */
229 static inline int board_No(struct specialix_board *bp)
231 return bp - sx_board;
235 /* Get port number from pointer */
236 static inline int port_No(struct specialix_port const *port)
238 return SX_PORT(port - sx_port);
242 /* Get pointer to board from pointer to port */
243 static inline struct specialix_board *port_Board(
244 struct specialix_port const *port)
246 return &sx_board[SX_BOARD(port - sx_port)];
250 /* Input Byte from CL CD186x register */
251 static inline unsigned char sx_in(struct specialix_board *bp,
254 bp->reg = reg | 0x80;
255 outb(reg | 0x80, bp->base + SX_ADDR_REG);
256 return inb(bp->base + SX_DATA_REG);
260 /* Output Byte to CL CD186x register */
261 static inline void sx_out(struct specialix_board *bp, unsigned short reg,
264 bp->reg = reg | 0x80;
265 outb(reg | 0x80, bp->base + SX_ADDR_REG);
266 outb(val, bp->base + SX_DATA_REG);
270 /* Input Byte from CL CD186x register */
271 static inline unsigned char sx_in_off(struct specialix_board *bp,
275 outb(reg, bp->base + SX_ADDR_REG);
276 return inb(bp->base + SX_DATA_REG);
280 /* Output Byte to CL CD186x register */
281 static inline void sx_out_off(struct specialix_board *bp,
282 unsigned short reg, unsigned char val)
285 outb(reg, bp->base + SX_ADDR_REG);
286 outb(val, bp->base + SX_DATA_REG);
290 /* Wait for Channel Command Register ready */
291 static inline void sx_wait_CCR(struct specialix_board *bp)
293 unsigned long delay, flags;
296 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
297 spin_lock_irqsave(&bp->lock, flags);
298 ccr = sx_in(bp, CD186x_CCR);
299 spin_unlock_irqrestore(&bp->lock, flags);
305 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
309 /* Wait for Channel Command Register ready */
310 static inline void sx_wait_CCR_off(struct specialix_board *bp)
316 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
317 spin_lock_irqsave(&bp->lock, flags);
318 crr = sx_in_off(bp, CD186x_CCR);
319 spin_unlock_irqrestore(&bp->lock, flags);
325 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
330 * specialix IO8+ IO range functions.
333 static inline int sx_request_io_range(struct specialix_board *bp)
335 return request_region(bp->base,
336 bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
337 "specialix IO8+") == NULL;
341 static inline void sx_release_io_range(struct specialix_board *bp)
343 release_region(bp->base, bp->flags & SX_BOARD_IS_PCI ?
344 SX_PCI_IO_SPACE : SX_IO_SPACE);
348 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
349 static int sx_set_irq(struct specialix_board *bp)
355 if (bp->flags & SX_BOARD_IS_PCI)
358 /* In the same order as in the docs... */
371 default:printk(KERN_ERR
372 "Speclialix: cannot set irq to %d.\n", bp->irq);
375 spin_lock_irqsave(&bp->lock, flags);
376 for (i = 0; i < 2; i++) {
377 sx_out(bp, CD186x_CAR, i);
378 sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
380 spin_unlock_irqrestore(&bp->lock, flags);
385 /* Reset and setup CD186x chip */
386 static int sx_init_CD186x(struct specialix_board *bp)
393 sx_wait_CCR_off(bp); /* Wait for CCR ready */
394 spin_lock_irqsave(&bp->lock, flags);
395 sx_out_off(bp, CD186x_CCR, CCR_HARDRESET); /* Reset CD186x chip */
396 spin_unlock_irqrestore(&bp->lock, flags);
397 msleep(50); /* Delay 0.05 sec */
398 spin_lock_irqsave(&bp->lock, flags);
399 sx_out_off(bp, CD186x_GIVR, SX_ID); /* Set ID for this chip */
400 sx_out_off(bp, CD186x_GICR, 0); /* Clear all bits */
401 sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT); /* Prio for modem intr */
402 sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */
403 sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
405 sx_out_off(bp, CD186x_SRCR, sx_in(bp, CD186x_SRCR) | SRCR_REGACKEN);
407 /* Setting up prescaler. We need 4 ticks per 1 ms */
408 scaler = SX_OSCFREQ/SPECIALIX_TPS;
410 sx_out_off(bp, CD186x_PPRH, scaler >> 8);
411 sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
412 spin_unlock_irqrestore(&bp->lock, flags);
414 if (!sx_set_irq(bp)) {
415 /* Figure out how to pass this along... */
416 printk(KERN_ERR "Cannot set irq to %d.\n", bp->irq);
425 static int read_cross_byte(struct specialix_board *bp, int reg, int bit)
431 spin_lock_irqsave(&bp->lock, flags);
432 for (i = 0, t = 0; i < 8; i++) {
433 sx_out_off(bp, CD186x_CAR, i);
434 if (sx_in_off(bp, reg) & bit)
437 spin_unlock_irqrestore(&bp->lock, flags);
443 #ifdef SPECIALIX_TIMER
444 void missed_irq(unsigned long data)
448 struct specialix_board *bp = (struct specialix_board *)data;
450 spin_lock_irqsave(&bp->lock, flags);
451 irq = sx_in((struct specialix_board *)data, CD186x_SRSR) &
452 (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint);
453 spin_unlock_irqrestore(&bp->lock, flags);
456 "Missed interrupt... Calling int from timer. \n");
457 sx_interrupt(-1, bp);
459 mod_timer(&missed_irq_timer, jiffies + sx_poll);
465 /* Main probing routine, also sets irq. */
466 static int sx_probe(struct specialix_board *bp)
468 unsigned char val1, val2;
478 if (sx_request_io_range(bp)) {
483 /* Are the I/O ports here ? */
484 sx_out_off(bp, CD186x_PPRL, 0x5a);
486 val1 = sx_in_off(bp, CD186x_PPRL);
488 sx_out_off(bp, CD186x_PPRL, 0xa5);
490 val2 = sx_in_off(bp, CD186x_PPRL);
493 if ((val1 != 0x5a) || (val2 != 0xa5)) {
495 "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
496 board_No(bp), bp->base);
497 sx_release_io_range(bp);
502 /* Check the DSR lines that Specialix uses as board
504 val1 = read_cross_byte(bp, CD186x_MSVR, MSVR_DSR);
505 val2 = read_cross_byte(bp, CD186x_MSVR, MSVR_RTS);
506 dprintk(SX_DEBUG_INIT,
507 "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
508 board_No(bp), val1, val2);
510 /* They managed to switch the bit order between the docs and
511 the IO8+ card. The new PCI card now conforms to old docs.
512 They changed the PCI docs to reflect the situation on the
514 val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
517 "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
518 board_No(bp), val2, bp->base, val1);
519 sx_release_io_range(bp);
526 /* It's time to find IRQ for this board */
527 for (retries = 0; retries < 5 && irqs <= 0; retries++) {
528 irqs = probe_irq_on();
529 sx_init_CD186x(bp); /* Reset CD186x chip */
530 sx_out(bp, CD186x_CAR, 2); /* Select port 2 */
532 sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */
533 sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */
535 irqs = probe_irq_off(irqs);
537 dprintk(SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
538 dprintk(SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR));
539 dprintk(SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR));
540 dprintk(SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR));
541 dprintk(SX_DEBUG_INIT, "\n");
543 /* Reset CD186x again */
544 if (!sx_init_CD186x(bp)) {
545 /* Hmmm. This is dead code anyway. */
548 dprintk(SX_DEBUG_INIT
549 "val1 = %02x, val2 = %02x, val3 = %02x.\n",
557 "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
558 board_No(bp), bp->base);
559 sx_release_io_range(bp);
564 printk(KERN_INFO "Started with irq=%d, but now have irq=%d.\n",
569 /* Reset CD186x again */
570 if (!sx_init_CD186x(bp)) {
571 sx_release_io_range(bp);
576 sx_request_io_range(bp);
577 bp->flags |= SX_BOARD_PRESENT;
579 /* Chip revcode pkgtype
584 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
586 -- Thanks to Gwen Wang, Cirrus Logic.
589 switch (sx_in_off(bp, CD186x_GFRCR)) {
605 break; /* Does not exist at this time */
611 dprintk(SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR));
613 #ifdef SPECIALIX_TIMER
614 setup_timer(&missed_irq_timer, missed_irq, (unsigned long)bp);
615 mod_timer(&missed_irq_timer, jiffies + sx_poll);
619 "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
620 board_No(bp), bp->base, bp->irq, chip, rev);
628 * Interrupt processing routines.
631 static inline struct specialix_port *sx_get_port(struct specialix_board *bp,
632 unsigned char const *what)
634 unsigned char channel;
635 struct specialix_port *port = NULL;
637 channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
638 dprintk(SX_DEBUG_CHAN, "channel: %d\n", channel);
639 if (channel < CD186x_NCH) {
640 port = &sx_port[board_No(bp) * SX_NPORT + channel];
641 dprintk(SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n",
642 board_No(bp) * SX_NPORT + channel, port,
643 port->port.flags & ASYNC_INITIALIZED);
645 if (port->port.flags & ASYNC_INITIALIZED) {
646 dprintk(SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
651 printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
652 board_No(bp), what, channel);
657 static inline void sx_receive_exc(struct specialix_board *bp)
659 struct specialix_port *port;
660 struct tty_struct *tty;
661 unsigned char status;
662 unsigned char ch, flag;
666 port = sx_get_port(bp, "Receive");
668 dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n");
672 tty = port->port.tty;
674 status = sx_in(bp, CD186x_RCSR);
676 dprintk(SX_DEBUG_RX, "status: 0x%x\n", status);
677 if (status & RCSR_OE) {
679 dprintk(SX_DEBUG_FIFO,
680 "sx%d: port %d: Overrun. Total %ld overruns.\n",
681 board_No(bp), port_No(port), port->overrun);
683 status &= port->mark_mask;
685 /* This flip buffer check needs to be below the reading of the
686 status register to reset the chip's IRQ.... */
687 if (tty_buffer_request_room(tty, 1) == 0) {
688 dprintk(SX_DEBUG_FIFO,
689 "sx%d: port %d: Working around flip buffer overflow.\n",
690 board_No(bp), port_No(port));
695 ch = sx_in(bp, CD186x_RDR);
700 if (status & RCSR_TOUT) {
702 "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
703 board_No(bp), port_No(port));
707 } else if (status & RCSR_BREAK) {
708 dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
709 board_No(bp), port_No(port));
711 if (port->port.flags & ASYNC_SAK)
714 } else if (status & RCSR_PE)
717 else if (status & RCSR_FE)
720 else if (status & RCSR_OE)
726 if (tty_insert_flip_char(tty, ch, flag))
727 tty_flip_buffer_push(tty);
732 static inline void sx_receive(struct specialix_board *bp)
734 struct specialix_port *port;
735 struct tty_struct *tty;
740 port = sx_get_port(bp, "Receive");
742 dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n");
746 tty = port->port.tty;
748 count = sx_in(bp, CD186x_RDCR);
749 dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
750 port->hits[count > 8 ? 9 : count]++;
752 tty_buffer_request_room(tty, count);
755 tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL);
756 tty_flip_buffer_push(tty);
761 static inline void sx_transmit(struct specialix_board *bp)
763 struct specialix_port *port;
764 struct tty_struct *tty;
768 port = sx_get_port(bp, "Transmit");
773 dprintk(SX_DEBUG_TX, "port: %p\n", port);
774 tty = port->port.tty;
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 port->break_length -= count;
806 if (port->break_length == 0)
807 port->break_length--;
809 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
810 sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
811 sx_out(bp, CD186x_COR2, port->COR2);
813 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
814 port->break_length = 0;
821 count = CD186x_NFIFO;
823 sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
824 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
825 if (--port->xmit_cnt <= 0)
827 } while (--count > 0);
829 if (port->xmit_cnt <= 0) {
830 sx_out(bp, CD186x_CAR, port_No(port));
831 port->IER &= ~IER_TXRDY;
832 sx_out(bp, CD186x_IER, port->IER);
834 if (port->xmit_cnt <= port->wakeup_chars)
841 static inline void sx_check_modem(struct specialix_board *bp)
843 struct specialix_port *port;
844 struct tty_struct *tty;
848 dprintk(SX_DEBUG_SIGNALS, "Modem intr. ");
849 port = sx_get_port(bp, "Modem");
853 tty = port->port.tty;
855 mcr = sx_in(bp, CD186x_MCR);
856 printk("mcr = %02x.\n", mcr); /* FIXME */
858 if ((mcr & MCR_CDCHG)) {
859 dprintk(SX_DEBUG_SIGNALS, "CD just changed... ");
860 msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
862 dprintk(SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
863 wake_up_interruptible(&port->port.open_wait);
865 dprintk(SX_DEBUG_SIGNALS, "Sending HUP.\n");
870 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
871 if (mcr & MCR_CTSCHG) {
872 if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
874 port->IER |= IER_TXRDY;
875 if (port->xmit_cnt <= port->wakeup_chars)
879 port->IER &= ~IER_TXRDY;
881 sx_out(bp, CD186x_IER, port->IER);
883 if (mcr & MCR_DSSXHG) {
884 if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
886 port->IER |= IER_TXRDY;
887 if (port->xmit_cnt <= port->wakeup_chars)
891 port->IER &= ~IER_TXRDY;
893 sx_out(bp, CD186x_IER, port->IER);
895 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
897 /* Clear change bits */
898 sx_out(bp, CD186x_MCR, 0);
902 /* The main interrupt processing routine */
903 static irqreturn_t sx_interrupt(int dummy, void *dev_id)
905 unsigned char status;
907 struct specialix_board *bp = dev_id;
908 unsigned long loop = 0;
914 spin_lock_irqsave(&bp->lock, flags);
916 dprintk(SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__,
917 port_No(sx_get_port(bp, "INT")),
918 SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
919 if (!(bp->flags & SX_BOARD_ACTIVE)) {
920 dprintk(SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n",
922 spin_unlock_irqrestore(&bp->lock, flags);
929 while (++loop < 16) {
930 status = sx_in(bp, CD186x_SRSR) &
931 (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint);
934 if (status & SRSR_RREQint) {
935 ack = sx_in(bp, CD186x_RRAR);
937 if (ack == (SX_ID | GIVR_IT_RCV))
939 else if (ack == (SX_ID | GIVR_IT_REXC))
943 "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
944 board_No(bp), status, ack);
946 } else if (status & SRSR_TREQint) {
947 ack = sx_in(bp, CD186x_TRAR);
949 if (ack == (SX_ID | GIVR_IT_TX))
952 printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
953 board_No(bp), status, ack,
954 port_No(sx_get_port(bp, "Int")));
955 } else if (status & SRSR_MREQint) {
956 ack = sx_in(bp, CD186x_MRAR);
958 if (ack == (SX_ID | GIVR_IT_MODEM))
962 "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
963 board_No(bp), status, ack);
967 sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
970 outb(bp->reg, bp->base + SX_ADDR_REG);
971 spin_unlock_irqrestore(&bp->lock, flags);
978 * Routines for open & close processing.
981 static void turn_ints_off(struct specialix_board *bp)
986 if (bp->flags & SX_BOARD_IS_PCI) {
987 /* This was intended for enabeling the interrupt on the
988 * PCI card. However it seems that it's already enabled
989 * and as PCI interrupts can be shared, there is no real
990 * reason to have to turn it off. */
993 spin_lock_irqsave(&bp->lock, flags);
994 (void) sx_in_off(bp, 0); /* Turn off interrupts. */
995 spin_unlock_irqrestore(&bp->lock, flags);
1000 static void turn_ints_on(struct specialix_board *bp)
1002 unsigned long flags;
1006 if (bp->flags & SX_BOARD_IS_PCI) {
1007 /* play with the PCI chip. See comment above. */
1009 spin_lock_irqsave(&bp->lock, flags);
1010 (void) sx_in(bp, 0); /* Turn ON interrupts. */
1011 spin_unlock_irqrestore(&bp->lock, flags);
1017 /* Called with disabled interrupts */
1018 static inline int sx_setup_board(struct specialix_board *bp)
1022 if (bp->flags & SX_BOARD_ACTIVE)
1025 if (bp->flags & SX_BOARD_IS_PCI)
1026 error = request_irq(bp->irq, sx_interrupt,
1027 IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp);
1029 error = request_irq(bp->irq, sx_interrupt,
1030 IRQF_DISABLED, "specialix IO8+", bp);
1036 bp->flags |= SX_BOARD_ACTIVE;
1042 /* Called with disabled interrupts */
1043 static inline void sx_shutdown_board(struct specialix_board *bp)
1047 if (!(bp->flags & SX_BOARD_ACTIVE)) {
1052 bp->flags &= ~SX_BOARD_ACTIVE;
1054 dprintk(SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
1055 bp->irq, board_No(bp));
1056 free_irq(bp->irq, bp);
1063 * Setting up port characteristics.
1064 * Must be called with disabled interrupts
1066 static void sx_change_speed(struct specialix_board *bp,
1067 struct specialix_port *port)
1069 struct tty_struct *tty;
1072 unsigned char cor1 = 0, cor3 = 0;
1073 unsigned char mcor1 = 0, mcor2 = 0;
1074 static unsigned long again;
1075 unsigned long flags;
1079 tty = port->port.tty;
1080 if (!tty || !tty->termios) {
1087 /* Select port on the board */
1088 spin_lock_irqsave(&bp->lock, flags);
1089 sx_out(bp, CD186x_CAR, port_No(port));
1091 /* The Specialix board doens't implement the RTS lines.
1092 They are used to set the IRQ level. Don't touch them. */
1093 if (SX_CRTSCTS(tty))
1094 port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1096 port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1097 spin_unlock_irqrestore(&bp->lock, flags);
1098 dprintk(SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
1099 baud = tty_get_baud_rate(tty);
1101 if (baud == 38400) {
1102 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1104 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1109 /* Drop DTR & exit */
1110 dprintk(SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
1111 if (!SX_CRTSCTS(tty)) {
1112 port->MSVR &= ~MSVR_DTR;
1113 spin_lock_irqsave(&bp->lock, flags);
1114 sx_out(bp, CD186x_MSVR, port->MSVR);
1115 spin_unlock_irqrestore(&bp->lock, flags);
1117 dprintk(SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1121 if (!SX_CRTSCTS(tty))
1122 port->MSVR |= MSVR_DTR;
1126 * Now we must calculate some speed depended things
1129 /* Set baud rate for port */
1130 tmp = port->custom_divisor ;
1133 "sx%d: Using custom baud rate divisor %ld. \n"
1134 "This is an untested option, please be careful.\n",
1135 port_No(port), tmp);
1137 tmp = (((SX_OSCFREQ + baud/2) / baud + CD186x_TPC/2) /
1140 if (tmp < 0x10 && time_before(again, jiffies)) {
1141 again = jiffies + HZ * 60;
1142 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1144 printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1145 "Performance degradation is possible.\n"
1146 "Read specialix.txt for more info.\n",
1147 port_No(port), tmp);
1149 printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1150 "Warning: overstressing Cirrus chip. This might not work.\n"
1151 "Read specialix.txt for more info.\n", port_No(port), tmp);
1154 spin_lock_irqsave(&bp->lock, flags);
1155 sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1156 sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1157 sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1158 sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1159 spin_unlock_irqrestore(&bp->lock, flags);
1160 if (port->custom_divisor)
1161 baud = (SX_OSCFREQ + port->custom_divisor/2) /
1162 port->custom_divisor;
1163 baud = (baud + 5) / 10; /* Estimated CPS */
1165 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1166 tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1167 port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1168 SERIAL_XMIT_SIZE - 1 : tmp);
1170 /* Receiver timeout will be transmission time for 1.5 chars */
1171 tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1172 tmp = (tmp > 0xff) ? 0xff : tmp;
1173 spin_lock_irqsave(&bp->lock, flags);
1174 sx_out(bp, CD186x_RTPR, tmp);
1175 spin_unlock_irqrestore(&bp->lock, flags);
1176 switch (C_CSIZE(tty)) {
1194 cor1 |= COR1_IGNORE;
1195 if (C_PARENB(tty)) {
1196 cor1 |= COR1_NORMPAR;
1200 cor1 &= ~COR1_IGNORE;
1202 /* Set marking of some errors */
1203 port->mark_mask = RCSR_OE | RCSR_TOUT;
1205 port->mark_mask |= RCSR_FE | RCSR_PE;
1206 if (I_BRKINT(tty) || I_PARMRK(tty))
1207 port->mark_mask |= RCSR_BREAK;
1209 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1210 if (I_IGNBRK(tty)) {
1211 port->mark_mask &= ~RCSR_BREAK;
1213 /* Real raw mode. Ignore all */
1214 port->mark_mask &= ~RCSR_OE;
1216 /* Enable Hardware Flow Control */
1217 if (C_CRTSCTS(tty)) {
1218 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1219 port->IER |= IER_DSR | IER_CTS;
1220 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1221 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1222 spin_lock_irqsave(&bp->lock, flags);
1223 tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) &
1224 (MSVR_CTS|MSVR_DSR));
1225 spin_unlock_irqrestore(&bp->lock, flags);
1227 port->COR2 |= COR2_CTSAE;
1230 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1231 /* Some people reported that it works, but I still doubt it */
1233 port->COR2 |= COR2_TXIBE;
1234 cor3 |= (COR3_FCT | COR3_SCDE);
1236 port->COR2 |= COR2_IXM;
1237 spin_lock_irqsave(&bp->lock, flags);
1238 sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1239 sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1240 sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1241 sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1242 spin_unlock_irqrestore(&bp->lock, flags);
1244 if (!C_CLOCAL(tty)) {
1245 /* Enable CD check */
1246 port->IER |= IER_CD;
1247 mcor1 |= MCOR1_CDZD;
1248 mcor2 |= MCOR2_CDOD;
1252 /* Enable receiver */
1253 port->IER |= IER_RXD;
1255 /* Set input FIFO size (1-8 bytes) */
1257 /* Setting up CD186x channel registers */
1258 spin_lock_irqsave(&bp->lock, flags);
1259 sx_out(bp, CD186x_COR1, cor1);
1260 sx_out(bp, CD186x_COR2, port->COR2);
1261 sx_out(bp, CD186x_COR3, cor3);
1262 spin_unlock_irqrestore(&bp->lock, flags);
1263 /* Make CD186x know about registers change */
1265 spin_lock_irqsave(&bp->lock, flags);
1266 sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1267 /* Setting up modem option registers */
1268 dprintk(SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n",
1270 sx_out(bp, CD186x_MCOR1, mcor1);
1271 sx_out(bp, CD186x_MCOR2, mcor2);
1272 spin_unlock_irqrestore(&bp->lock, flags);
1273 /* Enable CD186x transmitter & receiver */
1275 spin_lock_irqsave(&bp->lock, flags);
1276 sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1277 /* Enable interrupts */
1278 sx_out(bp, CD186x_IER, port->IER);
1279 /* And finally set the modem lines... */
1280 sx_out(bp, CD186x_MSVR, port->MSVR);
1281 spin_unlock_irqrestore(&bp->lock, flags);
1287 /* Must be called with interrupts enabled */
1288 static int sx_setup_port(struct specialix_board *bp,
1289 struct specialix_port *port)
1291 unsigned long flags;
1295 if (port->port.flags & ASYNC_INITIALIZED) {
1300 if (!port->xmit_buf) {
1301 /* We may sleep in get_zeroed_page() */
1304 tmp = get_zeroed_page(GFP_KERNEL);
1310 if (port->xmit_buf) {
1313 return -ERESTARTSYS;
1315 port->xmit_buf = (unsigned char *) tmp;
1318 spin_lock_irqsave(&port->lock, flags);
1321 clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
1323 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1324 sx_change_speed(bp, port);
1325 port->port.flags |= ASYNC_INITIALIZED;
1327 spin_unlock_irqrestore(&port->lock, flags);
1335 /* Must be called with interrupts disabled */
1336 static void sx_shutdown_port(struct specialix_board *bp,
1337 struct specialix_port *port)
1339 struct tty_struct *tty;
1341 unsigned long flags;
1345 if (!(port->port.flags & ASYNC_INITIALIZED)) {
1350 if (sx_debug & SX_DEBUG_FIFO) {
1351 dprintk(SX_DEBUG_FIFO,
1352 "sx%d: port %d: %ld overruns, FIFO hits [ ",
1353 board_No(bp), port_No(port), port->overrun);
1354 for (i = 0; i < 10; i++)
1355 dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1356 dprintk(SX_DEBUG_FIFO, "].\n");
1359 if (port->xmit_buf) {
1360 free_page((unsigned long) port->xmit_buf);
1361 port->xmit_buf = NULL;
1365 spin_lock_irqsave(&bp->lock, flags);
1366 sx_out(bp, CD186x_CAR, port_No(port));
1368 tty = port->port.tty;
1369 if (tty == NULL || C_HUPCL(tty)) {
1371 sx_out(bp, CD186x_MSVDTR, 0);
1373 spin_unlock_irqrestore(&bp->lock, flags);
1376 spin_lock_irqsave(&bp->lock, flags);
1377 sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1378 /* Disable all interrupts from this port */
1380 sx_out(bp, CD186x_IER, port->IER);
1381 spin_unlock_irqrestore(&bp->lock, flags);
1383 set_bit(TTY_IO_ERROR, &tty->flags);
1384 port->port.flags &= ~ASYNC_INITIALIZED;
1387 sx_shutdown_board(bp);
1392 static int block_til_ready(struct tty_struct *tty, struct file *filp,
1393 struct specialix_port *port)
1395 DECLARE_WAITQUEUE(wait, current);
1396 struct specialix_board *bp = port_Board(port);
1400 unsigned long flags;
1405 * If the device is in the middle of being closed, then block
1406 * until it's done, and then try again.
1408 if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
1409 interruptible_sleep_on(&port->port.close_wait);
1410 if (port->port.flags & ASYNC_HUP_NOTIFY) {
1415 return -ERESTARTSYS;
1420 * If non-blocking mode is set, or the port is not enabled,
1421 * then make the check up front and then exit.
1423 if ((filp->f_flags & O_NONBLOCK) ||
1424 (tty->flags & (1 << TTY_IO_ERROR))) {
1425 port->port.flags |= ASYNC_NORMAL_ACTIVE;
1434 * Block waiting for the carrier detect and the line to become
1435 * free (i.e., not in use by the callout). While we are in
1436 * this loop, info->count is dropped by one, so that
1437 * rs_close() knows when to free things. We restore it upon
1438 * exit, either normal or abnormal.
1441 add_wait_queue(&port->port.open_wait, &wait);
1442 spin_lock_irqsave(&port->lock, flags);
1443 if (!tty_hung_up_p(filp))
1445 spin_unlock_irqrestore(&port->lock, flags);
1446 port->port.blocked_open++;
1448 spin_lock_irqsave(&bp->lock, flags);
1449 sx_out(bp, CD186x_CAR, port_No(port));
1450 CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1451 if (SX_CRTSCTS(tty)) {
1453 port->MSVR |= MSVR_DTR; /* WTF? */
1454 sx_out(bp, CD186x_MSVR, port->MSVR);
1457 port->MSVR |= MSVR_DTR;
1458 sx_out(bp, CD186x_MSVR, port->MSVR);
1460 spin_unlock_irqrestore(&bp->lock, flags);
1461 set_current_state(TASK_INTERRUPTIBLE);
1462 if (tty_hung_up_p(filp) ||
1463 !(port->port.flags & ASYNC_INITIALIZED)) {
1464 if (port->port.flags & ASYNC_HUP_NOTIFY)
1467 retval = -ERESTARTSYS;
1470 if (!(port->port.flags & ASYNC_CLOSING) &&
1473 if (signal_pending(current)) {
1474 retval = -ERESTARTSYS;
1480 set_current_state(TASK_RUNNING);
1481 remove_wait_queue(&port->port.open_wait, &wait);
1482 spin_lock_irqsave(&port->lock, flags);
1483 if (!tty_hung_up_p(filp))
1485 port->port.blocked_open--;
1486 spin_unlock_irqrestore(&port->lock, flags);
1492 port->port.flags |= ASYNC_NORMAL_ACTIVE;
1498 static int sx_open(struct tty_struct *tty, struct file *filp)
1502 struct specialix_port *port;
1503 struct specialix_board *bp;
1505 unsigned long flags;
1509 board = SX_BOARD(tty->index);
1511 if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1516 bp = &sx_board[board];
1517 port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1519 for (i = 0; i < 10; i++)
1522 dprintk(SX_DEBUG_OPEN,
1523 "Board = %d, bp = %p, port = %p, portno = %d.\n",
1524 board, bp, port, SX_PORT(tty->index));
1526 if (sx_paranoia_check(port, tty->name, "sx_open")) {
1531 error = sx_setup_board(bp);
1537 spin_lock_irqsave(&bp->lock, flags);
1540 tty->driver_data = port;
1541 port->port.tty = tty;
1542 spin_unlock_irqrestore(&bp->lock, flags);
1544 error = sx_setup_port(bp, port);
1550 error = block_til_ready(tty, filp, port);
1560 static void sx_flush_buffer(struct tty_struct *tty)
1562 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1563 unsigned long flags;
1564 struct specialix_board *bp;
1568 if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
1573 bp = port_Board(port);
1574 spin_lock_irqsave(&port->lock, flags);
1575 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1576 spin_unlock_irqrestore(&port->lock, flags);
1582 static void sx_close(struct tty_struct *tty, struct file *filp)
1584 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1585 struct specialix_board *bp;
1586 unsigned long flags;
1587 unsigned long timeout;
1590 if (!port || sx_paranoia_check(port, tty->name, "close")) {
1594 spin_lock_irqsave(&port->lock, flags);
1596 if (tty_hung_up_p(filp)) {
1597 spin_unlock_irqrestore(&port->lock, flags);
1602 bp = port_Board(port);
1603 if ((tty->count == 1) && (port->port.count != 1)) {
1604 printk(KERN_ERR "sx%d: sx_close: bad port count;"
1605 " tty->count is 1, port count is %d\n",
1606 board_No(bp), port->port.count);
1607 port->port.count = 1;
1610 if (port->port.count > 1) {
1614 spin_unlock_irqrestore(&port->lock, flags);
1619 port->port.flags |= ASYNC_CLOSING;
1621 * Now we wait for the transmit buffer to clear; and we notify
1622 * the line discipline to only process XON/XOFF characters.
1625 spin_unlock_irqrestore(&port->lock, flags);
1626 dprintk(SX_DEBUG_OPEN, "Closing\n");
1627 if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1628 tty_wait_until_sent(tty, port->port.closing_wait);
1630 * At this point we stop accepting input. To do this, we
1631 * disable the receive line status interrupts, and tell the
1632 * interrupt driver to stop checking the data ready bit in the
1633 * line status register.
1635 dprintk(SX_DEBUG_OPEN, "Closed\n");
1636 port->IER &= ~IER_RXD;
1637 if (port->port.flags & ASYNC_INITIALIZED) {
1638 port->IER &= ~IER_TXRDY;
1639 port->IER |= IER_TXEMPTY;
1640 spin_lock_irqsave(&bp->lock, flags);
1641 sx_out(bp, CD186x_CAR, port_No(port));
1642 sx_out(bp, CD186x_IER, port->IER);
1643 spin_unlock_irqrestore(&bp->lock, flags);
1645 * Before we drop DTR, make sure the UART transmitter
1646 * has completely drained; this is especially
1647 * important if there is a transmit FIFO!
1649 timeout = jiffies+HZ;
1650 while (port->IER & IER_TXEMPTY) {
1651 set_current_state(TASK_INTERRUPTIBLE);
1652 msleep_interruptible(jiffies_to_msecs(port->timeout));
1653 if (time_after(jiffies, timeout)) {
1654 printk(KERN_INFO "Timeout waiting for close\n");
1661 if (--bp->count < 0) {
1663 "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1664 board_No(bp), bp->count, tty->index);
1667 if (--port->port.count < 0) {
1669 "sx%d: sx_close: bad port count for tty%d: %d\n",
1670 board_No(bp), port_No(port), port->port.count);
1671 port->port.count = 0;
1674 sx_shutdown_port(bp, port);
1675 sx_flush_buffer(tty);
1676 tty_ldisc_flush(tty);
1677 spin_lock_irqsave(&port->lock, flags);
1679 port->port.tty = NULL;
1680 spin_unlock_irqrestore(&port->lock, flags);
1681 if (port->port.blocked_open) {
1682 if (port->port.close_delay)
1683 msleep_interruptible(
1684 jiffies_to_msecs(port->port.close_delay));
1685 wake_up_interruptible(&port->port.open_wait);
1687 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1688 wake_up_interruptible(&port->port.close_wait);
1694 static int sx_write(struct tty_struct *tty,
1695 const unsigned char *buf, int count)
1697 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1698 struct specialix_board *bp;
1700 unsigned long flags;
1703 if (sx_paranoia_check(port, tty->name, "sx_write")) {
1708 bp = port_Board(port);
1710 if (!port->xmit_buf) {
1716 spin_lock_irqsave(&port->lock, flags);
1717 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1718 SERIAL_XMIT_SIZE - port->xmit_head));
1720 spin_unlock_irqrestore(&port->lock, flags);
1723 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1724 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1725 port->xmit_cnt += c;
1726 spin_unlock_irqrestore(&port->lock, flags);
1733 spin_lock_irqsave(&bp->lock, flags);
1734 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1735 !(port->IER & IER_TXRDY)) {
1736 port->IER |= IER_TXRDY;
1737 sx_out(bp, CD186x_CAR, port_No(port));
1738 sx_out(bp, CD186x_IER, port->IER);
1740 spin_unlock_irqrestore(&bp->lock, flags);
1747 static int sx_put_char(struct tty_struct *tty, unsigned char ch)
1749 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1750 unsigned long flags;
1751 struct specialix_board *bp;
1755 if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1759 dprintk(SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1760 if (!port->xmit_buf) {
1764 bp = port_Board(port);
1765 spin_lock_irqsave(&port->lock, flags);
1767 dprintk(SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n",
1768 port->xmit_cnt, port->xmit_buf);
1769 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1 || !port->xmit_buf) {
1770 spin_unlock_irqrestore(&port->lock, flags);
1771 dprintk(SX_DEBUG_TX, "Exit size\n");
1775 dprintk(SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
1776 port->xmit_buf[port->xmit_head++] = ch;
1777 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1779 spin_unlock_irqrestore(&port->lock, flags);
1786 static void sx_flush_chars(struct tty_struct *tty)
1788 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1789 unsigned long flags;
1790 struct specialix_board *bp = port_Board(port);
1794 if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1798 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1803 spin_lock_irqsave(&bp->lock, flags);
1804 port->IER |= IER_TXRDY;
1805 sx_out(port_Board(port), CD186x_CAR, port_No(port));
1806 sx_out(port_Board(port), CD186x_IER, port->IER);
1807 spin_unlock_irqrestore(&bp->lock, flags);
1813 static int sx_write_room(struct tty_struct *tty)
1815 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1820 if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1825 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1834 static int sx_chars_in_buffer(struct tty_struct *tty)
1836 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1840 if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
1845 return port->xmit_cnt;
1848 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1850 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1851 struct specialix_board *bp;
1852 unsigned char status;
1853 unsigned int result;
1854 unsigned long flags;
1858 if (sx_paranoia_check(port, tty->name, __func__)) {
1863 bp = port_Board(port);
1864 spin_lock_irqsave(&bp->lock, flags);
1865 sx_out(bp, CD186x_CAR, port_No(port));
1866 status = sx_in(bp, CD186x_MSVR);
1867 spin_unlock_irqrestore(&bp->lock, flags);
1868 dprintk(SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1869 port_No(port), status, sx_in(bp, CD186x_CAR));
1870 dprintk(SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1871 if (SX_CRTSCTS(port->port.tty)) {
1872 result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
1873 | ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1874 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1875 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1876 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1878 result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
1879 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1880 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1881 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1882 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1891 static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1892 unsigned int set, unsigned int clear)
1894 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1895 unsigned long flags;
1896 struct specialix_board *bp;
1900 if (sx_paranoia_check(port, tty->name, __func__)) {
1905 bp = port_Board(port);
1907 spin_lock_irqsave(&port->lock, flags);
1908 /* if (set & TIOCM_RTS)
1909 port->MSVR |= MSVR_RTS; */
1910 /* if (set & TIOCM_DTR)
1911 port->MSVR |= MSVR_DTR; */
1913 if (SX_CRTSCTS(port->port.tty)) {
1914 if (set & TIOCM_RTS)
1915 port->MSVR |= MSVR_DTR;
1917 if (set & TIOCM_DTR)
1918 port->MSVR |= MSVR_DTR;
1921 /* if (clear & TIOCM_RTS)
1922 port->MSVR &= ~MSVR_RTS; */
1923 /* if (clear & TIOCM_DTR)
1924 port->MSVR &= ~MSVR_DTR; */
1925 if (SX_CRTSCTS(port->port.tty)) {
1926 if (clear & TIOCM_RTS)
1927 port->MSVR &= ~MSVR_DTR;
1929 if (clear & TIOCM_DTR)
1930 port->MSVR &= ~MSVR_DTR;
1932 spin_lock_irqsave(&bp->lock, flags);
1933 sx_out(bp, CD186x_CAR, port_No(port));
1934 sx_out(bp, CD186x_MSVR, port->MSVR);
1935 spin_unlock_irqrestore(&bp->lock, flags);
1936 spin_unlock_irqrestore(&port->lock, flags);
1942 static inline void sx_send_break(struct specialix_port *port,
1943 unsigned long length)
1945 struct specialix_board *bp = port_Board(port);
1946 unsigned long flags;
1950 spin_lock_irqsave(&port->lock, flags);
1951 port->break_length = SPECIALIX_TPS / HZ * length;
1952 port->COR2 |= COR2_ETC;
1953 port->IER |= IER_TXRDY;
1954 spin_lock_irqsave(&bp->lock, flags);
1955 sx_out(bp, CD186x_CAR, port_No(port));
1956 sx_out(bp, CD186x_COR2, port->COR2);
1957 sx_out(bp, CD186x_IER, port->IER);
1958 spin_unlock_irqrestore(&bp->lock, flags);
1959 spin_unlock_irqrestore(&port->lock, flags);
1961 spin_lock_irqsave(&bp->lock, flags);
1962 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1963 spin_unlock_irqrestore(&bp->lock, flags);
1970 static inline int sx_set_serial_info(struct specialix_port *port,
1971 struct serial_struct __user *newinfo)
1973 struct serial_struct tmp;
1974 struct specialix_board *bp = port_Board(port);
1979 if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
1986 change_speed = ((port->port.flags & ASYNC_SPD_MASK) !=
1987 (tmp.flags & ASYNC_SPD_MASK));
1988 change_speed |= (tmp.custom_divisor != port->custom_divisor);
1990 if (!capable(CAP_SYS_ADMIN)) {
1991 if ((tmp.close_delay != port->port.close_delay) ||
1992 (tmp.closing_wait != port->port.closing_wait) ||
1993 ((tmp.flags & ~ASYNC_USR_MASK) !=
1994 (port->port.flags & ~ASYNC_USR_MASK))) {
1999 port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
2000 (tmp.flags & ASYNC_USR_MASK));
2001 port->custom_divisor = tmp.custom_divisor;
2003 port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
2004 (tmp.flags & ASYNC_FLAGS));
2005 port->port.close_delay = tmp.close_delay;
2006 port->port.closing_wait = tmp.closing_wait;
2007 port->custom_divisor = tmp.custom_divisor;
2010 sx_change_speed(bp, port);
2018 static inline int sx_get_serial_info(struct specialix_port *port,
2019 struct serial_struct __user *retinfo)
2021 struct serial_struct tmp;
2022 struct specialix_board *bp = port_Board(port);
2026 memset(&tmp, 0, sizeof(tmp));
2028 tmp.type = PORT_CIRRUS;
2029 tmp.line = port - sx_port;
2030 tmp.port = bp->base;
2032 tmp.flags = port->port.flags;
2033 tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
2034 tmp.close_delay = port->port.close_delay * HZ/100;
2035 tmp.closing_wait = port->port.closing_wait * HZ/100;
2036 tmp.custom_divisor = port->custom_divisor;
2037 tmp.xmit_fifo_size = CD186x_NFIFO;
2039 if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
2049 static int sx_ioctl(struct tty_struct *tty, struct file *filp,
2050 unsigned int cmd, unsigned long arg)
2052 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2054 void __user *argp = (void __user *)arg;
2058 if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
2064 case TCSBRK: /* SVID version: non-zero arg --> no break */
2065 retval = tty_check_change(tty);
2070 tty_wait_until_sent(tty, 0);
2072 sx_send_break(port, HZ/4); /* 1/4 second */
2074 case TCSBRKP: /* support for POSIX tcsendbreak() */
2075 retval = tty_check_change(tty);
2080 tty_wait_until_sent(tty, 0);
2081 sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
2086 return sx_get_serial_info(port, argp);
2089 return sx_set_serial_info(port, argp);
2092 return -ENOIOCTLCMD;
2099 static void sx_throttle(struct tty_struct *tty)
2101 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2102 struct specialix_board *bp;
2103 unsigned long flags;
2107 if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
2112 bp = port_Board(port);
2114 /* Use DTR instead of RTS ! */
2115 if (SX_CRTSCTS(tty))
2116 port->MSVR &= ~MSVR_DTR;
2118 /* Auch!!! I think the system shouldn't call this then. */
2119 /* Or maybe we're supposed (allowed?) to do our side of hw
2120 handshake anyway, even when hardware handshake is off.
2121 When you see this in your logs, please report.... */
2123 "sx%d: Need to throttle, but can't (hardware hs is off)\n",
2126 spin_lock_irqsave(&bp->lock, flags);
2127 sx_out(bp, CD186x_CAR, port_No(port));
2128 spin_unlock_irqrestore(&bp->lock, flags);
2131 spin_lock_irqsave(&bp->lock, flags);
2132 sx_out(bp, CD186x_CCR, CCR_SSCH2);
2133 spin_unlock_irqrestore(&bp->lock, flags);
2136 spin_lock_irqsave(&bp->lock, flags);
2137 sx_out(bp, CD186x_MSVR, port->MSVR);
2138 spin_unlock_irqrestore(&bp->lock, flags);
2144 static void sx_unthrottle(struct tty_struct *tty)
2146 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2147 struct specialix_board *bp;
2148 unsigned long flags;
2152 if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
2157 bp = port_Board(port);
2159 spin_lock_irqsave(&port->lock, flags);
2160 /* XXXX Use DTR INSTEAD???? */
2161 if (SX_CRTSCTS(tty))
2162 port->MSVR |= MSVR_DTR;
2163 /* Else clause: see remark in "sx_throttle"... */
2164 spin_lock_irqsave(&bp->lock, flags);
2165 sx_out(bp, CD186x_CAR, port_No(port));
2166 spin_unlock_irqrestore(&bp->lock, flags);
2168 spin_unlock_irqrestore(&port->lock, flags);
2170 spin_lock_irqsave(&bp->lock, flags);
2171 sx_out(bp, CD186x_CCR, CCR_SSCH1);
2172 spin_unlock_irqrestore(&bp->lock, flags);
2174 spin_lock_irqsave(&port->lock, flags);
2176 spin_lock_irqsave(&bp->lock, flags);
2177 sx_out(bp, CD186x_MSVR, port->MSVR);
2178 spin_unlock_irqrestore(&bp->lock, flags);
2179 spin_unlock_irqrestore(&port->lock, flags);
2185 static void sx_stop(struct tty_struct *tty)
2187 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2188 struct specialix_board *bp;
2189 unsigned long flags;
2193 if (sx_paranoia_check(port, tty->name, "sx_stop")) {
2198 bp = port_Board(port);
2200 spin_lock_irqsave(&port->lock, flags);
2201 port->IER &= ~IER_TXRDY;
2202 spin_lock_irqsave(&bp->lock, flags);
2203 sx_out(bp, CD186x_CAR, port_No(port));
2204 sx_out(bp, CD186x_IER, port->IER);
2205 spin_unlock_irqrestore(&bp->lock, flags);
2206 spin_unlock_irqrestore(&port->lock, flags);
2212 static void sx_start(struct tty_struct *tty)
2214 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2215 struct specialix_board *bp;
2216 unsigned long flags;
2220 if (sx_paranoia_check(port, tty->name, "sx_start")) {
2225 bp = port_Board(port);
2227 spin_lock_irqsave(&port->lock, flags);
2228 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2229 port->IER |= IER_TXRDY;
2230 spin_lock_irqsave(&bp->lock, flags);
2231 sx_out(bp, CD186x_CAR, port_No(port));
2232 sx_out(bp, CD186x_IER, port->IER);
2233 spin_unlock_irqrestore(&bp->lock, flags);
2235 spin_unlock_irqrestore(&port->lock, flags);
2240 static void sx_hangup(struct tty_struct *tty)
2242 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2243 struct specialix_board *bp;
2244 unsigned long flags;
2248 if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2253 bp = port_Board(port);
2255 sx_shutdown_port(bp, port);
2256 spin_lock_irqsave(&port->lock, flags);
2257 bp->count -= port->port.count;
2258 if (bp->count < 0) {
2260 "sx%d: sx_hangup: bad board count: %d port: %d\n",
2261 board_No(bp), bp->count, tty->index);
2264 port->port.count = 0;
2265 port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
2266 port->port.tty = NULL;
2267 spin_unlock_irqrestore(&port->lock, flags);
2268 wake_up_interruptible(&port->port.open_wait);
2274 static void sx_set_termios(struct tty_struct *tty,
2275 struct ktermios *old_termios)
2277 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2278 unsigned long flags;
2279 struct specialix_board *bp;
2281 if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2284 bp = port_Board(port);
2285 spin_lock_irqsave(&port->lock, flags);
2286 sx_change_speed(port_Board(port), port);
2287 spin_unlock_irqrestore(&port->lock, flags);
2289 if ((old_termios->c_cflag & CRTSCTS) &&
2290 !(tty->termios->c_cflag & CRTSCTS)) {
2291 tty->hw_stopped = 0;
2296 static const struct tty_operations sx_ops = {
2300 .put_char = sx_put_char,
2301 .flush_chars = sx_flush_chars,
2302 .write_room = sx_write_room,
2303 .chars_in_buffer = sx_chars_in_buffer,
2304 .flush_buffer = sx_flush_buffer,
2306 .throttle = sx_throttle,
2307 .unthrottle = sx_unthrottle,
2308 .set_termios = sx_set_termios,
2311 .hangup = sx_hangup,
2312 .tiocmget = sx_tiocmget,
2313 .tiocmset = sx_tiocmset,
2316 static int sx_init_drivers(void)
2323 specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT);
2324 if (!specialix_driver) {
2325 printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n");
2330 specialix_driver->owner = THIS_MODULE;
2331 specialix_driver->name = "ttyW";
2332 specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
2333 specialix_driver->type = TTY_DRIVER_TYPE_SERIAL;
2334 specialix_driver->subtype = SERIAL_TYPE_NORMAL;
2335 specialix_driver->init_termios = tty_std_termios;
2336 specialix_driver->init_termios.c_cflag =
2337 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2338 specialix_driver->init_termios.c_ispeed = 9600;
2339 specialix_driver->init_termios.c_ospeed = 9600;
2340 specialix_driver->flags = TTY_DRIVER_REAL_RAW;
2341 tty_set_operations(specialix_driver, &sx_ops);
2343 error = tty_register_driver(specialix_driver);
2345 put_tty_driver(specialix_driver);
2347 "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2352 memset(sx_port, 0, sizeof(sx_port));
2353 for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2354 sx_port[i].magic = SPECIALIX_MAGIC;
2355 tty_port_init(&sx_port[i].port);
2356 spin_lock_init(&sx_port[i].lock);
2363 static void sx_release_drivers(void)
2367 tty_unregister_driver(specialix_driver);
2368 put_tty_driver(specialix_driver);
2373 * This routine must be called by kernel at boot time
2375 static int __init specialix_init(void)
2382 printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
2383 printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2384 #ifdef CONFIG_SPECIALIX_RTSCTS
2385 printk(KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
2387 printk(KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2390 for (i = 0; i < SX_NBOARD; i++)
2391 spin_lock_init(&sx_board[i].lock);
2393 if (sx_init_drivers()) {
2398 for (i = 0; i < SX_NBOARD; i++)
2399 if (sx_board[i].base && !sx_probe(&sx_board[i]))
2404 struct pci_dev *pdev = NULL;
2407 while (i < SX_NBOARD) {
2408 if (sx_board[i].flags & SX_BOARD_PRESENT) {
2412 pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX,
2413 PCI_DEVICE_ID_SPECIALIX_IO8, pdev);
2417 if (pci_enable_device(pdev))
2420 sx_board[i].irq = pdev->irq;
2422 sx_board[i].base = pci_resource_start(pdev, 2);
2424 sx_board[i].flags |= SX_BOARD_IS_PCI;
2425 if (!sx_probe(&sx_board[i]))
2428 /* May exit pci_get sequence early with lots of boards */
2435 sx_release_drivers();
2436 printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
2445 static int iobase[SX_NBOARD] = {0,};
2447 static int irq [SX_NBOARD] = {0,};
2449 module_param_array(iobase, int, NULL, 0);
2450 module_param_array(irq, int, NULL, 0);
2451 module_param(sx_debug, int, 0);
2452 module_param(sx_rxfifo, int, 0);
2453 #ifdef SPECIALIX_TIMER
2454 module_param(sx_poll, int, 0);
2458 * You can setup up to 4 boards.
2459 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2460 * You should specify the IRQs too in that case "irq=....,...".
2462 * More than 4 boards in one computer is not possible, as the card can
2463 * only use 4 different interrupts.
2466 static int __init specialix_init_module(void)
2472 if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2473 for (i = 0; i < SX_NBOARD; i++) {
2474 sx_board[i].base = iobase[i];
2475 sx_board[i].irq = irq[i];
2476 sx_board[i].count = 0;
2482 return specialix_init();
2485 static void __exit specialix_exit_module(void)
2491 sx_release_drivers();
2492 for (i = 0; i < SX_NBOARD; i++)
2493 if (sx_board[i].flags & SX_BOARD_PRESENT)
2494 sx_release_io_range(&sx_board[i]);
2495 #ifdef SPECIALIX_TIMER
2496 del_timer_sync(&missed_irq_timer);
2502 static struct pci_device_id specialx_pci_tbl[] __devinitdata = {
2503 { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) },
2506 MODULE_DEVICE_TABLE(pci, specialx_pci_tbl);
2508 module_init(specialix_init_module);
2509 module_exit(specialix_exit_module);
2511 MODULE_LICENSE("GPL");