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/serial/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/smp_lock.h>
91 #include <linux/fcntl.h>
92 #include <linux/major.h>
93 #include <linux/delay.h>
94 #include <linux/pci.h>
95 #include <linux/init.h>
96 #include <linux/uaccess.h>
98 #include "specialix_io8.h"
103 This driver can spew a whole lot of debugging output at you. If you
104 need maximum performance, you should disable the DEBUG define. To
105 aid in debugging in the field, I'm leaving the compile-time debug
106 features enabled, and disable them "runtime". That allows me to
107 instruct people with problems to enable debugging without requiring
113 static int sx_rxfifo
= SPECIALIX_RXFIFO
;
114 static int sx_rtscts
;
117 #define dprintk(f, str...) if (sx_debug & f) printk(str)
119 #define dprintk(f, str...) /* nothing */
122 #define SX_DEBUG_FLOW 0x0001
123 #define SX_DEBUG_DATA 0x0002
124 #define SX_DEBUG_PROBE 0x0004
125 #define SX_DEBUG_CHAN 0x0008
126 #define SX_DEBUG_INIT 0x0010
127 #define SX_DEBUG_RX 0x0020
128 #define SX_DEBUG_TX 0x0040
129 #define SX_DEBUG_IRQ 0x0080
130 #define SX_DEBUG_OPEN 0x0100
131 #define SX_DEBUG_TERMIOS 0x0200
132 #define SX_DEBUG_SIGNALS 0x0400
133 #define SX_DEBUG_FIFO 0x0800
136 #define func_enter() dprintk(SX_DEBUG_FLOW, "io8: enter %s\n", __func__)
137 #define func_exit() dprintk(SX_DEBUG_FLOW, "io8: exit %s\n", __func__)
140 /* Configurable options: */
142 /* Am I paranoid or not ? ;-) */
143 #define SPECIALIX_PARANOIA_CHECK
146 * The following defines are mostly for testing purposes. But if you need
147 * some nice reporting in your syslog, you can define them also.
149 #undef SX_REPORT_FIFO
150 #undef SX_REPORT_OVERRUN
155 #define SPECIALIX_LEGAL_FLAGS \
156 (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \
157 ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \
158 ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
160 static struct tty_driver
*specialix_driver
;
162 static struct specialix_board sx_board
[SX_NBOARD
] = {
163 { 0, SX_IOBASE1
, 9, },
164 { 0, SX_IOBASE2
, 11, },
165 { 0, SX_IOBASE3
, 12, },
166 { 0, SX_IOBASE4
, 15, },
169 static struct specialix_port sx_port
[SX_NBOARD
* SX_NPORT
];
172 static int sx_paranoia_check(struct specialix_port
const *port
,
173 char *name
, const char *routine
)
175 #ifdef SPECIALIX_PARANOIA_CHECK
176 static const char *badmagic
= KERN_ERR
177 "sx: Warning: bad specialix port magic number for device %s in %s\n";
178 static const char *badinfo
= KERN_ERR
179 "sx: Warning: null specialix port for device %s in %s\n";
182 printk(badinfo
, name
, routine
);
185 if (port
->magic
!= SPECIALIX_MAGIC
) {
186 printk(badmagic
, name
, routine
);
196 * Service functions for specialix IO8+ driver.
200 /* Get board number from pointer */
201 static inline int board_No(struct specialix_board
*bp
)
203 return bp
- sx_board
;
207 /* Get port number from pointer */
208 static inline int port_No(struct specialix_port
const *port
)
210 return SX_PORT(port
- sx_port
);
214 /* Get pointer to board from pointer to port */
215 static inline struct specialix_board
*port_Board(
216 struct specialix_port
const *port
)
218 return &sx_board
[SX_BOARD(port
- sx_port
)];
222 /* Input Byte from CL CD186x register */
223 static inline unsigned char sx_in(struct specialix_board
*bp
,
226 bp
->reg
= reg
| 0x80;
227 outb(reg
| 0x80, bp
->base
+ SX_ADDR_REG
);
228 return inb(bp
->base
+ SX_DATA_REG
);
232 /* Output Byte to CL CD186x register */
233 static inline void sx_out(struct specialix_board
*bp
, unsigned short reg
,
236 bp
->reg
= reg
| 0x80;
237 outb(reg
| 0x80, bp
->base
+ SX_ADDR_REG
);
238 outb(val
, bp
->base
+ SX_DATA_REG
);
242 /* Input Byte from CL CD186x register */
243 static inline unsigned char sx_in_off(struct specialix_board
*bp
,
247 outb(reg
, bp
->base
+ SX_ADDR_REG
);
248 return inb(bp
->base
+ SX_DATA_REG
);
252 /* Output Byte to CL CD186x register */
253 static inline void sx_out_off(struct specialix_board
*bp
,
254 unsigned short reg
, unsigned char val
)
257 outb(reg
, bp
->base
+ SX_ADDR_REG
);
258 outb(val
, bp
->base
+ SX_DATA_REG
);
262 /* Wait for Channel Command Register ready */
263 static void sx_wait_CCR(struct specialix_board
*bp
)
265 unsigned long delay
, flags
;
268 for (delay
= SX_CCR_TIMEOUT
; delay
; delay
--) {
269 spin_lock_irqsave(&bp
->lock
, flags
);
270 ccr
= sx_in(bp
, CD186x_CCR
);
271 spin_unlock_irqrestore(&bp
->lock
, flags
);
277 printk(KERN_ERR
"sx%d: Timeout waiting for CCR.\n", board_No(bp
));
281 /* Wait for Channel Command Register ready */
282 static void sx_wait_CCR_off(struct specialix_board
*bp
)
288 for (delay
= SX_CCR_TIMEOUT
; delay
; delay
--) {
289 spin_lock_irqsave(&bp
->lock
, flags
);
290 crr
= sx_in_off(bp
, CD186x_CCR
);
291 spin_unlock_irqrestore(&bp
->lock
, flags
);
297 printk(KERN_ERR
"sx%d: Timeout waiting for CCR.\n", board_No(bp
));
302 * specialix IO8+ IO range functions.
305 static int sx_request_io_range(struct specialix_board
*bp
)
307 return request_region(bp
->base
,
308 bp
->flags
& SX_BOARD_IS_PCI
? SX_PCI_IO_SPACE
: SX_IO_SPACE
,
309 "specialix IO8+") == NULL
;
313 static void sx_release_io_range(struct specialix_board
*bp
)
315 release_region(bp
->base
, bp
->flags
& SX_BOARD_IS_PCI
?
316 SX_PCI_IO_SPACE
: SX_IO_SPACE
);
320 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
321 static int sx_set_irq(struct specialix_board
*bp
)
327 if (bp
->flags
& SX_BOARD_IS_PCI
)
330 /* In the same order as in the docs... */
343 default:printk(KERN_ERR
344 "Speclialix: cannot set irq to %d.\n", bp
->irq
);
347 spin_lock_irqsave(&bp
->lock
, flags
);
348 for (i
= 0; i
< 2; i
++) {
349 sx_out(bp
, CD186x_CAR
, i
);
350 sx_out(bp
, CD186x_MSVRTS
, ((virq
>> i
) & 0x1)? MSVR_RTS
:0);
352 spin_unlock_irqrestore(&bp
->lock
, flags
);
357 /* Reset and setup CD186x chip */
358 static int sx_init_CD186x(struct specialix_board
*bp
)
365 sx_wait_CCR_off(bp
); /* Wait for CCR ready */
366 spin_lock_irqsave(&bp
->lock
, flags
);
367 sx_out_off(bp
, CD186x_CCR
, CCR_HARDRESET
); /* Reset CD186x chip */
368 spin_unlock_irqrestore(&bp
->lock
, flags
);
369 msleep(50); /* Delay 0.05 sec */
370 spin_lock_irqsave(&bp
->lock
, flags
);
371 sx_out_off(bp
, CD186x_GIVR
, SX_ID
); /* Set ID for this chip */
372 sx_out_off(bp
, CD186x_GICR
, 0); /* Clear all bits */
373 sx_out_off(bp
, CD186x_PILR1
, SX_ACK_MINT
); /* Prio for modem intr */
374 sx_out_off(bp
, CD186x_PILR2
, SX_ACK_TINT
); /* Prio for transmitter intr */
375 sx_out_off(bp
, CD186x_PILR3
, SX_ACK_RINT
); /* Prio for receiver intr */
377 sx_out_off(bp
, CD186x_SRCR
, sx_in(bp
, CD186x_SRCR
) | SRCR_REGACKEN
);
379 /* Setting up prescaler. We need 4 ticks per 1 ms */
380 scaler
= SX_OSCFREQ
/SPECIALIX_TPS
;
382 sx_out_off(bp
, CD186x_PPRH
, scaler
>> 8);
383 sx_out_off(bp
, CD186x_PPRL
, scaler
& 0xff);
384 spin_unlock_irqrestore(&bp
->lock
, flags
);
386 if (!sx_set_irq(bp
)) {
387 /* Figure out how to pass this along... */
388 printk(KERN_ERR
"Cannot set irq to %d.\n", bp
->irq
);
397 static int read_cross_byte(struct specialix_board
*bp
, int reg
, int bit
)
403 spin_lock_irqsave(&bp
->lock
, flags
);
404 for (i
= 0, t
= 0; i
< 8; i
++) {
405 sx_out_off(bp
, CD186x_CAR
, i
);
406 if (sx_in_off(bp
, reg
) & bit
)
409 spin_unlock_irqrestore(&bp
->lock
, flags
);
415 /* Main probing routine, also sets irq. */
416 static int sx_probe(struct specialix_board
*bp
)
418 unsigned char val1
, val2
;
424 if (sx_request_io_range(bp
)) {
429 /* Are the I/O ports here ? */
430 sx_out_off(bp
, CD186x_PPRL
, 0x5a);
432 val1
= sx_in_off(bp
, CD186x_PPRL
);
434 sx_out_off(bp
, CD186x_PPRL
, 0xa5);
436 val2
= sx_in_off(bp
, CD186x_PPRL
);
439 if (val1
!= 0x5a || val2
!= 0xa5) {
441 "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
442 board_No(bp
), bp
->base
);
443 sx_release_io_range(bp
);
448 /* Check the DSR lines that Specialix uses as board
450 val1
= read_cross_byte(bp
, CD186x_MSVR
, MSVR_DSR
);
451 val2
= read_cross_byte(bp
, CD186x_MSVR
, MSVR_RTS
);
452 dprintk(SX_DEBUG_INIT
,
453 "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
454 board_No(bp
), val1
, val2
);
456 /* They managed to switch the bit order between the docs and
457 the IO8+ card. The new PCI card now conforms to old docs.
458 They changed the PCI docs to reflect the situation on the
460 val2
= (bp
->flags
& SX_BOARD_IS_PCI
)?0x4d : 0xb2;
463 "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
464 board_No(bp
), val2
, bp
->base
, val1
);
465 sx_release_io_range(bp
);
471 /* Reset CD186x again */
472 if (!sx_init_CD186x(bp
)) {
473 sx_release_io_range(bp
);
478 sx_request_io_range(bp
);
479 bp
->flags
|= SX_BOARD_PRESENT
;
481 /* Chip revcode pkgtype
486 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
488 -- Thanks to Gwen Wang, Cirrus Logic.
491 switch (sx_in_off(bp
, CD186x_GFRCR
)) {
507 break; /* Does not exist at this time */
513 dprintk(SX_DEBUG_INIT
, " GFCR = 0x%02x\n", sx_in_off(bp
, CD186x_GFRCR
));
516 "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
517 board_No(bp
), bp
->base
, bp
->irq
, chip
, rev
);
525 * Interrupt processing routines.
528 static struct specialix_port
*sx_get_port(struct specialix_board
*bp
,
529 unsigned char const *what
)
531 unsigned char channel
;
532 struct specialix_port
*port
= NULL
;
534 channel
= sx_in(bp
, CD186x_GICR
) >> GICR_CHAN_OFF
;
535 dprintk(SX_DEBUG_CHAN
, "channel: %d\n", channel
);
536 if (channel
< CD186x_NCH
) {
537 port
= &sx_port
[board_No(bp
) * SX_NPORT
+ channel
];
538 dprintk(SX_DEBUG_CHAN
, "port: %d %p flags: 0x%lx\n",
539 board_No(bp
) * SX_NPORT
+ channel
, port
,
540 port
->port
.flags
& ASYNC_INITIALIZED
);
542 if (port
->port
.flags
& ASYNC_INITIALIZED
) {
543 dprintk(SX_DEBUG_CHAN
, "port: %d %p\n", channel
, port
);
548 printk(KERN_INFO
"sx%d: %s interrupt from invalid port %d\n",
549 board_No(bp
), what
, channel
);
554 static void sx_receive_exc(struct specialix_board
*bp
)
556 struct specialix_port
*port
;
557 struct tty_struct
*tty
;
558 unsigned char status
;
559 unsigned char ch
, flag
;
563 port
= sx_get_port(bp
, "Receive");
565 dprintk(SX_DEBUG_RX
, "Hmm, couldn't find port.\n");
569 tty
= port
->port
.tty
;
571 status
= sx_in(bp
, CD186x_RCSR
);
573 dprintk(SX_DEBUG_RX
, "status: 0x%x\n", status
);
574 if (status
& RCSR_OE
) {
576 dprintk(SX_DEBUG_FIFO
,
577 "sx%d: port %d: Overrun. Total %ld overruns.\n",
578 board_No(bp
), port_No(port
), port
->overrun
);
580 status
&= port
->mark_mask
;
582 /* This flip buffer check needs to be below the reading of the
583 status register to reset the chip's IRQ.... */
584 if (tty_buffer_request_room(tty
, 1) == 0) {
585 dprintk(SX_DEBUG_FIFO
,
586 "sx%d: port %d: Working around flip buffer overflow.\n",
587 board_No(bp
), port_No(port
));
592 ch
= sx_in(bp
, CD186x_RDR
);
597 if (status
& RCSR_TOUT
) {
599 "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
600 board_No(bp
), port_No(port
));
604 } else if (status
& RCSR_BREAK
) {
605 dprintk(SX_DEBUG_RX
, "sx%d: port %d: Handling break...\n",
606 board_No(bp
), port_No(port
));
608 if (port
->port
.flags
& ASYNC_SAK
)
611 } else if (status
& RCSR_PE
)
614 else if (status
& RCSR_FE
)
617 else if (status
& RCSR_OE
)
623 if (tty_insert_flip_char(tty
, ch
, flag
))
624 tty_flip_buffer_push(tty
);
629 static void sx_receive(struct specialix_board
*bp
)
631 struct specialix_port
*port
;
632 struct tty_struct
*tty
;
637 port
= sx_get_port(bp
, "Receive");
639 dprintk(SX_DEBUG_RX
, "Hmm, couldn't find port.\n");
643 tty
= port
->port
.tty
;
645 count
= sx_in(bp
, CD186x_RDCR
);
646 dprintk(SX_DEBUG_RX
, "port: %p: count: %d\n", port
, count
);
647 port
->hits
[count
> 8 ? 9 : count
]++;
649 tty_buffer_request_room(tty
, count
);
652 tty_insert_flip_char(tty
, sx_in(bp
, CD186x_RDR
), TTY_NORMAL
);
653 tty_flip_buffer_push(tty
);
658 static void sx_transmit(struct specialix_board
*bp
)
660 struct specialix_port
*port
;
661 struct tty_struct
*tty
;
665 port
= sx_get_port(bp
, "Transmit");
670 dprintk(SX_DEBUG_TX
, "port: %p\n", port
);
671 tty
= port
->port
.tty
;
673 if (port
->IER
& IER_TXEMPTY
) {
675 sx_out(bp
, CD186x_CAR
, port_No(port
));
676 port
->IER
&= ~IER_TXEMPTY
;
677 sx_out(bp
, CD186x_IER
, port
->IER
);
682 if ((port
->xmit_cnt
<= 0 && !port
->break_length
)
683 || tty
->stopped
|| tty
->hw_stopped
) {
684 sx_out(bp
, CD186x_CAR
, port_No(port
));
685 port
->IER
&= ~IER_TXRDY
;
686 sx_out(bp
, CD186x_IER
, port
->IER
);
691 if (port
->break_length
) {
692 if (port
->break_length
> 0) {
693 if (port
->COR2
& COR2_ETC
) {
694 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
695 sx_out(bp
, CD186x_TDR
, CD186x_C_SBRK
);
696 port
->COR2
&= ~COR2_ETC
;
698 count
= min_t(int, port
->break_length
, 0xff);
699 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
700 sx_out(bp
, CD186x_TDR
, CD186x_C_DELAY
);
701 sx_out(bp
, CD186x_TDR
, count
);
702 port
->break_length
-= count
;
703 if (port
->break_length
== 0)
704 port
->break_length
--;
706 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
707 sx_out(bp
, CD186x_TDR
, CD186x_C_EBRK
);
708 sx_out(bp
, CD186x_COR2
, port
->COR2
);
710 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
711 port
->break_length
= 0;
718 count
= CD186x_NFIFO
;
720 sx_out(bp
, CD186x_TDR
, port
->xmit_buf
[port
->xmit_tail
++]);
721 port
->xmit_tail
= port
->xmit_tail
& (SERIAL_XMIT_SIZE
-1);
722 if (--port
->xmit_cnt
<= 0)
724 } while (--count
> 0);
726 if (port
->xmit_cnt
<= 0) {
727 sx_out(bp
, CD186x_CAR
, port_No(port
));
728 port
->IER
&= ~IER_TXRDY
;
729 sx_out(bp
, CD186x_IER
, port
->IER
);
731 if (port
->xmit_cnt
<= port
->wakeup_chars
)
738 static void sx_check_modem(struct specialix_board
*bp
)
740 struct specialix_port
*port
;
741 struct tty_struct
*tty
;
745 dprintk(SX_DEBUG_SIGNALS
, "Modem intr. ");
746 port
= sx_get_port(bp
, "Modem");
750 tty
= port
->port
.tty
;
752 mcr
= sx_in(bp
, CD186x_MCR
);
754 if ((mcr
& MCR_CDCHG
)) {
755 dprintk(SX_DEBUG_SIGNALS
, "CD just changed... ");
756 msvr_cd
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
758 dprintk(SX_DEBUG_SIGNALS
, "Waking up guys in open.\n");
759 wake_up_interruptible(&port
->port
.open_wait
);
761 dprintk(SX_DEBUG_SIGNALS
, "Sending HUP.\n");
766 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
767 if (mcr
& MCR_CTSCHG
) {
768 if (sx_in(bp
, CD186x_MSVR
) & MSVR_CTS
) {
770 port
->IER
|= IER_TXRDY
;
771 if (port
->xmit_cnt
<= port
->wakeup_chars
)
775 port
->IER
&= ~IER_TXRDY
;
777 sx_out(bp
, CD186x_IER
, port
->IER
);
779 if (mcr
& MCR_DSSXHG
) {
780 if (sx_in(bp
, CD186x_MSVR
) & MSVR_DSR
) {
782 port
->IER
|= IER_TXRDY
;
783 if (port
->xmit_cnt
<= port
->wakeup_chars
)
787 port
->IER
&= ~IER_TXRDY
;
789 sx_out(bp
, CD186x_IER
, port
->IER
);
791 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
793 /* Clear change bits */
794 sx_out(bp
, CD186x_MCR
, 0);
798 /* The main interrupt processing routine */
799 static irqreturn_t
sx_interrupt(int dummy
, void *dev_id
)
801 unsigned char status
;
803 struct specialix_board
*bp
= dev_id
;
804 unsigned long loop
= 0;
810 spin_lock_irqsave(&bp
->lock
, flags
);
812 dprintk(SX_DEBUG_FLOW
, "enter %s port %d room: %ld\n", __func__
,
813 port_No(sx_get_port(bp
, "INT")),
814 SERIAL_XMIT_SIZE
- sx_get_port(bp
, "ITN")->xmit_cnt
- 1);
815 if (!(bp
->flags
& SX_BOARD_ACTIVE
)) {
816 dprintk(SX_DEBUG_IRQ
, "sx: False interrupt. irq %d.\n",
818 spin_unlock_irqrestore(&bp
->lock
, flags
);
825 while (++loop
< 16) {
826 status
= sx_in(bp
, CD186x_SRSR
) &
827 (SRSR_RREQint
| SRSR_TREQint
| SRSR_MREQint
);
830 if (status
& SRSR_RREQint
) {
831 ack
= sx_in(bp
, CD186x_RRAR
);
833 if (ack
== (SX_ID
| GIVR_IT_RCV
))
835 else if (ack
== (SX_ID
| GIVR_IT_REXC
))
839 "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
840 board_No(bp
), status
, ack
);
842 } else if (status
& SRSR_TREQint
) {
843 ack
= sx_in(bp
, CD186x_TRAR
);
845 if (ack
== (SX_ID
| GIVR_IT_TX
))
848 printk(KERN_ERR
"sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
849 board_No(bp
), status
, ack
,
850 port_No(sx_get_port(bp
, "Int")));
851 } else if (status
& SRSR_MREQint
) {
852 ack
= sx_in(bp
, CD186x_MRAR
);
854 if (ack
== (SX_ID
| GIVR_IT_MODEM
))
858 "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
859 board_No(bp
), status
, ack
);
863 sx_out(bp
, CD186x_EOIR
, 0); /* Mark end of interrupt */
866 outb(bp
->reg
, bp
->base
+ SX_ADDR_REG
);
867 spin_unlock_irqrestore(&bp
->lock
, flags
);
874 * Routines for open & close processing.
877 static void turn_ints_off(struct specialix_board
*bp
)
882 spin_lock_irqsave(&bp
->lock
, flags
);
883 (void) sx_in_off(bp
, 0); /* Turn off interrupts. */
884 spin_unlock_irqrestore(&bp
->lock
, flags
);
889 static void turn_ints_on(struct specialix_board
*bp
)
895 spin_lock_irqsave(&bp
->lock
, flags
);
896 (void) sx_in(bp
, 0); /* Turn ON interrupts. */
897 spin_unlock_irqrestore(&bp
->lock
, flags
);
903 /* Called with disabled interrupts */
904 static int sx_setup_board(struct specialix_board
*bp
)
908 if (bp
->flags
& SX_BOARD_ACTIVE
)
911 if (bp
->flags
& SX_BOARD_IS_PCI
)
912 error
= request_irq(bp
->irq
, sx_interrupt
,
913 IRQF_DISABLED
| IRQF_SHARED
, "specialix IO8+", bp
);
915 error
= request_irq(bp
->irq
, sx_interrupt
,
916 IRQF_DISABLED
, "specialix IO8+", bp
);
922 bp
->flags
|= SX_BOARD_ACTIVE
;
928 /* Called with disabled interrupts */
929 static void sx_shutdown_board(struct specialix_board
*bp
)
933 if (!(bp
->flags
& SX_BOARD_ACTIVE
)) {
938 bp
->flags
&= ~SX_BOARD_ACTIVE
;
940 dprintk(SX_DEBUG_IRQ
, "Freeing IRQ%d for board %d.\n",
941 bp
->irq
, board_No(bp
));
942 free_irq(bp
->irq
, bp
);
947 static unsigned int sx_crtscts(struct tty_struct
*tty
)
950 return C_CRTSCTS(tty
);
955 * Setting up port characteristics.
956 * Must be called with disabled interrupts
958 static void sx_change_speed(struct specialix_board
*bp
,
959 struct specialix_port
*port
)
961 struct tty_struct
*tty
;
964 unsigned char cor1
= 0, cor3
= 0;
965 unsigned char mcor1
= 0, mcor2
= 0;
966 static unsigned long again
;
971 tty
= port
->port
.tty
;
972 if (!tty
|| !tty
->termios
) {
979 /* Select port on the board */
980 spin_lock_irqsave(&bp
->lock
, flags
);
981 sx_out(bp
, CD186x_CAR
, port_No(port
));
983 /* The Specialix board doens't implement the RTS lines.
984 They are used to set the IRQ level. Don't touch them. */
986 port
->MSVR
= MSVR_DTR
| (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
988 port
->MSVR
= (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
989 spin_unlock_irqrestore(&bp
->lock
, flags
);
990 dprintk(SX_DEBUG_TERMIOS
, "sx: got MSVR=%02x.\n", port
->MSVR
);
991 baud
= tty_get_baud_rate(tty
);
994 if ((port
->port
.flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_HI
)
996 if ((port
->port
.flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_VHI
)
1001 /* Drop DTR & exit */
1002 dprintk(SX_DEBUG_TERMIOS
, "Dropping DTR... Hmm....\n");
1003 if (!sx_crtscts(tty
)) {
1004 port
->MSVR
&= ~MSVR_DTR
;
1005 spin_lock_irqsave(&bp
->lock
, flags
);
1006 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1007 spin_unlock_irqrestore(&bp
->lock
, flags
);
1009 dprintk(SX_DEBUG_TERMIOS
, "Can't drop DTR: no DTR.\n");
1013 if (!sx_crtscts(tty
))
1014 port
->MSVR
|= MSVR_DTR
;
1018 * Now we must calculate some speed depended things
1021 /* Set baud rate for port */
1022 tmp
= port
->custom_divisor
;
1025 "sx%d: Using custom baud rate divisor %ld. \n"
1026 "This is an untested option, please be careful.\n",
1027 port_No(port
), tmp
);
1029 tmp
= (((SX_OSCFREQ
+ baud
/2) / baud
+ CD186x_TPC
/2) /
1032 if (tmp
< 0x10 && time_before(again
, jiffies
)) {
1033 again
= jiffies
+ HZ
* 60;
1034 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1036 printk(KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1037 "Performance degradation is possible.\n"
1038 "Read specialix.txt for more info.\n",
1039 port_No(port
), tmp
);
1041 printk(KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1042 "Warning: overstressing Cirrus chip. This might not work.\n"
1043 "Read specialix.txt for more info.\n", port_No(port
), tmp
);
1046 spin_lock_irqsave(&bp
->lock
, flags
);
1047 sx_out(bp
, CD186x_RBPRH
, (tmp
>> 8) & 0xff);
1048 sx_out(bp
, CD186x_TBPRH
, (tmp
>> 8) & 0xff);
1049 sx_out(bp
, CD186x_RBPRL
, tmp
& 0xff);
1050 sx_out(bp
, CD186x_TBPRL
, tmp
& 0xff);
1051 spin_unlock_irqrestore(&bp
->lock
, flags
);
1052 if (port
->custom_divisor
)
1053 baud
= (SX_OSCFREQ
+ port
->custom_divisor
/2) /
1054 port
->custom_divisor
;
1055 baud
= (baud
+ 5) / 10; /* Estimated CPS */
1057 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1058 tmp
= ((baud
+ HZ
/2) / HZ
) * 2 - CD186x_NFIFO
;
1059 port
->wakeup_chars
= (tmp
< 0) ? 0 : ((tmp
>= SERIAL_XMIT_SIZE
) ?
1060 SERIAL_XMIT_SIZE
- 1 : tmp
);
1062 /* Receiver timeout will be transmission time for 1.5 chars */
1063 tmp
= (SPECIALIX_TPS
+ SPECIALIX_TPS
/2 + baud
/2) / baud
;
1064 tmp
= (tmp
> 0xff) ? 0xff : tmp
;
1065 spin_lock_irqsave(&bp
->lock
, flags
);
1066 sx_out(bp
, CD186x_RTPR
, tmp
);
1067 spin_unlock_irqrestore(&bp
->lock
, flags
);
1068 switch (C_CSIZE(tty
)) {
1086 cor1
|= COR1_IGNORE
;
1087 if (C_PARENB(tty
)) {
1088 cor1
|= COR1_NORMPAR
;
1092 cor1
&= ~COR1_IGNORE
;
1094 /* Set marking of some errors */
1095 port
->mark_mask
= RCSR_OE
| RCSR_TOUT
;
1097 port
->mark_mask
|= RCSR_FE
| RCSR_PE
;
1098 if (I_BRKINT(tty
) || I_PARMRK(tty
))
1099 port
->mark_mask
|= RCSR_BREAK
;
1101 port
->mark_mask
&= ~(RCSR_FE
| RCSR_PE
);
1102 if (I_IGNBRK(tty
)) {
1103 port
->mark_mask
&= ~RCSR_BREAK
;
1105 /* Real raw mode. Ignore all */
1106 port
->mark_mask
&= ~RCSR_OE
;
1108 /* Enable Hardware Flow Control */
1109 if (C_CRTSCTS(tty
)) {
1110 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1111 port
->IER
|= IER_DSR
| IER_CTS
;
1112 mcor1
|= MCOR1_DSRZD
| MCOR1_CTSZD
;
1113 mcor2
|= MCOR2_DSROD
| MCOR2_CTSOD
;
1114 spin_lock_irqsave(&bp
->lock
, flags
);
1115 tty
->hw_stopped
= !(sx_in(bp
, CD186x_MSVR
) &
1116 (MSVR_CTS
|MSVR_DSR
));
1117 spin_unlock_irqrestore(&bp
->lock
, flags
);
1119 port
->COR2
|= COR2_CTSAE
;
1122 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1123 /* Some people reported that it works, but I still doubt it */
1125 port
->COR2
|= COR2_TXIBE
;
1126 cor3
|= (COR3_FCT
| COR3_SCDE
);
1128 port
->COR2
|= COR2_IXM
;
1129 spin_lock_irqsave(&bp
->lock
, flags
);
1130 sx_out(bp
, CD186x_SCHR1
, START_CHAR(tty
));
1131 sx_out(bp
, CD186x_SCHR2
, STOP_CHAR(tty
));
1132 sx_out(bp
, CD186x_SCHR3
, START_CHAR(tty
));
1133 sx_out(bp
, CD186x_SCHR4
, STOP_CHAR(tty
));
1134 spin_unlock_irqrestore(&bp
->lock
, flags
);
1136 if (!C_CLOCAL(tty
)) {
1137 /* Enable CD check */
1138 port
->IER
|= IER_CD
;
1139 mcor1
|= MCOR1_CDZD
;
1140 mcor2
|= MCOR2_CDOD
;
1144 /* Enable receiver */
1145 port
->IER
|= IER_RXD
;
1147 /* Set input FIFO size (1-8 bytes) */
1149 /* Setting up CD186x channel registers */
1150 spin_lock_irqsave(&bp
->lock
, flags
);
1151 sx_out(bp
, CD186x_COR1
, cor1
);
1152 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1153 sx_out(bp
, CD186x_COR3
, cor3
);
1154 spin_unlock_irqrestore(&bp
->lock
, flags
);
1155 /* Make CD186x know about registers change */
1157 spin_lock_irqsave(&bp
->lock
, flags
);
1158 sx_out(bp
, CD186x_CCR
, CCR_CORCHG1
| CCR_CORCHG2
| CCR_CORCHG3
);
1159 /* Setting up modem option registers */
1160 dprintk(SX_DEBUG_TERMIOS
, "Mcor1 = %02x, mcor2 = %02x.\n",
1162 sx_out(bp
, CD186x_MCOR1
, mcor1
);
1163 sx_out(bp
, CD186x_MCOR2
, mcor2
);
1164 spin_unlock_irqrestore(&bp
->lock
, flags
);
1165 /* Enable CD186x transmitter & receiver */
1167 spin_lock_irqsave(&bp
->lock
, flags
);
1168 sx_out(bp
, CD186x_CCR
, CCR_TXEN
| CCR_RXEN
);
1169 /* Enable interrupts */
1170 sx_out(bp
, CD186x_IER
, port
->IER
);
1171 /* And finally set the modem lines... */
1172 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1173 spin_unlock_irqrestore(&bp
->lock
, flags
);
1179 /* Must be called with interrupts enabled */
1180 static int sx_setup_port(struct specialix_board
*bp
,
1181 struct specialix_port
*port
)
1183 unsigned long flags
;
1187 if (port
->port
.flags
& ASYNC_INITIALIZED
) {
1192 if (!port
->xmit_buf
) {
1193 /* We may sleep in get_zeroed_page() */
1196 tmp
= get_zeroed_page(GFP_KERNEL
);
1202 if (port
->xmit_buf
) {
1205 return -ERESTARTSYS
;
1207 port
->xmit_buf
= (unsigned char *) tmp
;
1210 spin_lock_irqsave(&port
->lock
, flags
);
1213 clear_bit(TTY_IO_ERROR
, &port
->port
.tty
->flags
);
1215 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1216 sx_change_speed(bp
, port
);
1217 port
->port
.flags
|= ASYNC_INITIALIZED
;
1219 spin_unlock_irqrestore(&port
->lock
, flags
);
1227 /* Must be called with interrupts disabled */
1228 static void sx_shutdown_port(struct specialix_board
*bp
,
1229 struct specialix_port
*port
)
1231 struct tty_struct
*tty
;
1233 unsigned long flags
;
1237 if (!(port
->port
.flags
& ASYNC_INITIALIZED
)) {
1242 if (sx_debug
& SX_DEBUG_FIFO
) {
1243 dprintk(SX_DEBUG_FIFO
,
1244 "sx%d: port %d: %ld overruns, FIFO hits [ ",
1245 board_No(bp
), port_No(port
), port
->overrun
);
1246 for (i
= 0; i
< 10; i
++)
1247 dprintk(SX_DEBUG_FIFO
, "%ld ", port
->hits
[i
]);
1248 dprintk(SX_DEBUG_FIFO
, "].\n");
1251 if (port
->xmit_buf
) {
1252 free_page((unsigned long) port
->xmit_buf
);
1253 port
->xmit_buf
= NULL
;
1257 spin_lock_irqsave(&bp
->lock
, flags
);
1258 sx_out(bp
, CD186x_CAR
, port_No(port
));
1260 tty
= port
->port
.tty
;
1261 if (tty
== NULL
|| C_HUPCL(tty
)) {
1263 sx_out(bp
, CD186x_MSVDTR
, 0);
1265 spin_unlock_irqrestore(&bp
->lock
, flags
);
1268 spin_lock_irqsave(&bp
->lock
, flags
);
1269 sx_out(bp
, CD186x_CCR
, CCR_SOFTRESET
);
1270 /* Disable all interrupts from this port */
1272 sx_out(bp
, CD186x_IER
, port
->IER
);
1273 spin_unlock_irqrestore(&bp
->lock
, flags
);
1275 set_bit(TTY_IO_ERROR
, &tty
->flags
);
1276 port
->port
.flags
&= ~ASYNC_INITIALIZED
;
1279 sx_shutdown_board(bp
);
1284 static int block_til_ready(struct tty_struct
*tty
, struct file
*filp
,
1285 struct specialix_port
*port
)
1287 DECLARE_WAITQUEUE(wait
, current
);
1288 struct specialix_board
*bp
= port_Board(port
);
1292 unsigned long flags
;
1297 * If the device is in the middle of being closed, then block
1298 * until it's done, and then try again.
1300 if (tty_hung_up_p(filp
) || port
->port
.flags
& ASYNC_CLOSING
) {
1301 interruptible_sleep_on(&port
->port
.close_wait
);
1302 if (port
->port
.flags
& ASYNC_HUP_NOTIFY
) {
1307 return -ERESTARTSYS
;
1312 * If non-blocking mode is set, or the port is not enabled,
1313 * then make the check up front and then exit.
1315 if ((filp
->f_flags
& O_NONBLOCK
) ||
1316 (tty
->flags
& (1 << TTY_IO_ERROR
))) {
1317 port
->port
.flags
|= ASYNC_NORMAL_ACTIVE
;
1326 * Block waiting for the carrier detect and the line to become
1327 * free (i.e., not in use by the callout). While we are in
1328 * this loop, info->count is dropped by one, so that
1329 * rs_close() knows when to free things. We restore it upon
1330 * exit, either normal or abnormal.
1333 add_wait_queue(&port
->port
.open_wait
, &wait
);
1334 spin_lock_irqsave(&port
->lock
, flags
);
1335 if (!tty_hung_up_p(filp
))
1337 spin_unlock_irqrestore(&port
->lock
, flags
);
1338 port
->port
.blocked_open
++;
1340 spin_lock_irqsave(&bp
->lock
, flags
);
1341 sx_out(bp
, CD186x_CAR
, port_No(port
));
1342 CD
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
1343 if (sx_crtscts(tty
)) {
1345 port
->MSVR
|= MSVR_DTR
; /* WTF? */
1346 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1349 port
->MSVR
|= MSVR_DTR
;
1350 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1352 spin_unlock_irqrestore(&bp
->lock
, flags
);
1353 set_current_state(TASK_INTERRUPTIBLE
);
1354 if (tty_hung_up_p(filp
) ||
1355 !(port
->port
.flags
& ASYNC_INITIALIZED
)) {
1356 if (port
->port
.flags
& ASYNC_HUP_NOTIFY
)
1359 retval
= -ERESTARTSYS
;
1362 if (!(port
->port
.flags
& ASYNC_CLOSING
) &&
1365 if (signal_pending(current
)) {
1366 retval
= -ERESTARTSYS
;
1372 set_current_state(TASK_RUNNING
);
1373 remove_wait_queue(&port
->port
.open_wait
, &wait
);
1374 spin_lock_irqsave(&port
->lock
, flags
);
1375 if (!tty_hung_up_p(filp
))
1377 port
->port
.blocked_open
--;
1378 spin_unlock_irqrestore(&port
->lock
, flags
);
1384 port
->port
.flags
|= ASYNC_NORMAL_ACTIVE
;
1390 static int sx_open(struct tty_struct
*tty
, struct file
*filp
)
1394 struct specialix_port
*port
;
1395 struct specialix_board
*bp
;
1397 unsigned long flags
;
1401 board
= SX_BOARD(tty
->index
);
1403 if (board
>= SX_NBOARD
|| !(sx_board
[board
].flags
& SX_BOARD_PRESENT
)) {
1408 bp
= &sx_board
[board
];
1409 port
= sx_port
+ board
* SX_NPORT
+ SX_PORT(tty
->index
);
1411 for (i
= 0; i
< 10; i
++)
1414 dprintk(SX_DEBUG_OPEN
,
1415 "Board = %d, bp = %p, port = %p, portno = %d.\n",
1416 board
, bp
, port
, SX_PORT(tty
->index
));
1418 if (sx_paranoia_check(port
, tty
->name
, "sx_open")) {
1423 error
= sx_setup_board(bp
);
1429 spin_lock_irqsave(&bp
->lock
, flags
);
1432 tty
->driver_data
= port
;
1433 port
->port
.tty
= tty
;
1434 spin_unlock_irqrestore(&bp
->lock
, flags
);
1436 error
= sx_setup_port(bp
, port
);
1442 error
= block_til_ready(tty
, filp
, port
);
1452 static void sx_flush_buffer(struct tty_struct
*tty
)
1454 struct specialix_port
*port
= tty
->driver_data
;
1455 unsigned long flags
;
1456 struct specialix_board
*bp
;
1460 if (sx_paranoia_check(port
, tty
->name
, "sx_flush_buffer")) {
1465 bp
= port_Board(port
);
1466 spin_lock_irqsave(&port
->lock
, flags
);
1467 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1468 spin_unlock_irqrestore(&port
->lock
, flags
);
1474 static void sx_close(struct tty_struct
*tty
, struct file
*filp
)
1476 struct specialix_port
*port
= tty
->driver_data
;
1477 struct specialix_board
*bp
;
1478 unsigned long flags
;
1479 unsigned long timeout
;
1482 if (!port
|| sx_paranoia_check(port
, tty
->name
, "close")) {
1486 spin_lock_irqsave(&port
->lock
, flags
);
1488 if (tty_hung_up_p(filp
)) {
1489 spin_unlock_irqrestore(&port
->lock
, flags
);
1494 bp
= port_Board(port
);
1495 if (tty
->count
== 1 && port
->port
.count
!= 1) {
1496 printk(KERN_ERR
"sx%d: sx_close: bad port count;"
1497 " tty->count is 1, port count is %d\n",
1498 board_No(bp
), port
->port
.count
);
1499 port
->port
.count
= 1;
1502 if (port
->port
.count
> 1) {
1506 spin_unlock_irqrestore(&port
->lock
, flags
);
1511 port
->port
.flags
|= ASYNC_CLOSING
;
1513 * Now we wait for the transmit buffer to clear; and we notify
1514 * the line discipline to only process XON/XOFF characters.
1517 spin_unlock_irqrestore(&port
->lock
, flags
);
1518 dprintk(SX_DEBUG_OPEN
, "Closing\n");
1519 if (port
->port
.closing_wait
!= ASYNC_CLOSING_WAIT_NONE
)
1520 tty_wait_until_sent(tty
, port
->port
.closing_wait
);
1522 * At this point we stop accepting input. To do this, we
1523 * disable the receive line status interrupts, and tell the
1524 * interrupt driver to stop checking the data ready bit in the
1525 * line status register.
1527 dprintk(SX_DEBUG_OPEN
, "Closed\n");
1528 port
->IER
&= ~IER_RXD
;
1529 if (port
->port
.flags
& ASYNC_INITIALIZED
) {
1530 port
->IER
&= ~IER_TXRDY
;
1531 port
->IER
|= IER_TXEMPTY
;
1532 spin_lock_irqsave(&bp
->lock
, flags
);
1533 sx_out(bp
, CD186x_CAR
, port_No(port
));
1534 sx_out(bp
, CD186x_IER
, port
->IER
);
1535 spin_unlock_irqrestore(&bp
->lock
, flags
);
1537 * Before we drop DTR, make sure the UART transmitter
1538 * has completely drained; this is especially
1539 * important if there is a transmit FIFO!
1541 timeout
= jiffies
+HZ
;
1542 while (port
->IER
& IER_TXEMPTY
) {
1543 set_current_state(TASK_INTERRUPTIBLE
);
1544 msleep_interruptible(jiffies_to_msecs(port
->timeout
));
1545 if (time_after(jiffies
, timeout
)) {
1546 printk(KERN_INFO
"Timeout waiting for close\n");
1553 if (--bp
->count
< 0) {
1555 "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1556 board_No(bp
), bp
->count
, tty
->index
);
1559 if (--port
->port
.count
< 0) {
1561 "sx%d: sx_close: bad port count for tty%d: %d\n",
1562 board_No(bp
), port_No(port
), port
->port
.count
);
1563 port
->port
.count
= 0;
1566 sx_shutdown_port(bp
, port
);
1567 sx_flush_buffer(tty
);
1568 tty_ldisc_flush(tty
);
1569 spin_lock_irqsave(&port
->lock
, flags
);
1571 port
->port
.tty
= NULL
;
1572 spin_unlock_irqrestore(&port
->lock
, flags
);
1573 if (port
->port
.blocked_open
) {
1574 if (port
->port
.close_delay
)
1575 msleep_interruptible(
1576 jiffies_to_msecs(port
->port
.close_delay
));
1577 wake_up_interruptible(&port
->port
.open_wait
);
1579 port
->port
.flags
&= ~(ASYNC_NORMAL_ACTIVE
|ASYNC_CLOSING
);
1580 wake_up_interruptible(&port
->port
.close_wait
);
1586 static int sx_write(struct tty_struct
*tty
,
1587 const unsigned char *buf
, int count
)
1589 struct specialix_port
*port
= tty
->driver_data
;
1590 struct specialix_board
*bp
;
1592 unsigned long flags
;
1595 if (sx_paranoia_check(port
, tty
->name
, "sx_write")) {
1600 bp
= port_Board(port
);
1602 if (!port
->xmit_buf
) {
1608 spin_lock_irqsave(&port
->lock
, flags
);
1609 c
= min_t(int, count
, min(SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1,
1610 SERIAL_XMIT_SIZE
- port
->xmit_head
));
1612 spin_unlock_irqrestore(&port
->lock
, flags
);
1615 memcpy(port
->xmit_buf
+ port
->xmit_head
, buf
, c
);
1616 port
->xmit_head
= (port
->xmit_head
+ c
) & (SERIAL_XMIT_SIZE
-1);
1617 port
->xmit_cnt
+= c
;
1618 spin_unlock_irqrestore(&port
->lock
, flags
);
1625 spin_lock_irqsave(&bp
->lock
, flags
);
1626 if (port
->xmit_cnt
&& !tty
->stopped
&& !tty
->hw_stopped
&&
1627 !(port
->IER
& IER_TXRDY
)) {
1628 port
->IER
|= IER_TXRDY
;
1629 sx_out(bp
, CD186x_CAR
, port_No(port
));
1630 sx_out(bp
, CD186x_IER
, port
->IER
);
1632 spin_unlock_irqrestore(&bp
->lock
, flags
);
1639 static int sx_put_char(struct tty_struct
*tty
, unsigned char ch
)
1641 struct specialix_port
*port
= tty
->driver_data
;
1642 unsigned long flags
;
1643 struct specialix_board
*bp
;
1647 if (sx_paranoia_check(port
, tty
->name
, "sx_put_char")) {
1651 dprintk(SX_DEBUG_TX
, "check tty: %p %p\n", tty
, port
->xmit_buf
);
1652 if (!port
->xmit_buf
) {
1656 bp
= port_Board(port
);
1657 spin_lock_irqsave(&port
->lock
, flags
);
1659 dprintk(SX_DEBUG_TX
, "xmit_cnt: %d xmit_buf: %p\n",
1660 port
->xmit_cnt
, port
->xmit_buf
);
1661 if (port
->xmit_cnt
>= SERIAL_XMIT_SIZE
- 1 || !port
->xmit_buf
) {
1662 spin_unlock_irqrestore(&port
->lock
, flags
);
1663 dprintk(SX_DEBUG_TX
, "Exit size\n");
1667 dprintk(SX_DEBUG_TX
, "Handle xmit: %p %p\n", port
, port
->xmit_buf
);
1668 port
->xmit_buf
[port
->xmit_head
++] = ch
;
1669 port
->xmit_head
&= SERIAL_XMIT_SIZE
- 1;
1671 spin_unlock_irqrestore(&port
->lock
, flags
);
1678 static void sx_flush_chars(struct tty_struct
*tty
)
1680 struct specialix_port
*port
= tty
->driver_data
;
1681 unsigned long flags
;
1682 struct specialix_board
*bp
= port_Board(port
);
1686 if (sx_paranoia_check(port
, tty
->name
, "sx_flush_chars")) {
1690 if (port
->xmit_cnt
<= 0 || tty
->stopped
|| tty
->hw_stopped
||
1695 spin_lock_irqsave(&bp
->lock
, flags
);
1696 port
->IER
|= IER_TXRDY
;
1697 sx_out(port_Board(port
), CD186x_CAR
, port_No(port
));
1698 sx_out(port_Board(port
), CD186x_IER
, port
->IER
);
1699 spin_unlock_irqrestore(&bp
->lock
, flags
);
1705 static int sx_write_room(struct tty_struct
*tty
)
1707 struct specialix_port
*port
= tty
->driver_data
;
1712 if (sx_paranoia_check(port
, tty
->name
, "sx_write_room")) {
1717 ret
= SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1;
1726 static int sx_chars_in_buffer(struct tty_struct
*tty
)
1728 struct specialix_port
*port
= tty
->driver_data
;
1732 if (sx_paranoia_check(port
, tty
->name
, "sx_chars_in_buffer")) {
1737 return port
->xmit_cnt
;
1740 static int sx_tiocmget(struct tty_struct
*tty
, struct file
*file
)
1742 struct specialix_port
*port
= tty
->driver_data
;
1743 struct specialix_board
*bp
;
1744 unsigned char status
;
1745 unsigned int result
;
1746 unsigned long flags
;
1750 if (sx_paranoia_check(port
, tty
->name
, __func__
)) {
1755 bp
= port_Board(port
);
1756 spin_lock_irqsave(&bp
->lock
, flags
);
1757 sx_out(bp
, CD186x_CAR
, port_No(port
));
1758 status
= sx_in(bp
, CD186x_MSVR
);
1759 spin_unlock_irqrestore(&bp
->lock
, flags
);
1760 dprintk(SX_DEBUG_INIT
, "Got msvr[%d] = %02x, car = %d.\n",
1761 port_No(port
), status
, sx_in(bp
, CD186x_CAR
));
1762 dprintk(SX_DEBUG_INIT
, "sx_port = %p, port = %p\n", sx_port
, port
);
1763 if (sx_crtscts(port
->port
.tty
)) {
1764 result
= TIOCM_DTR
| TIOCM_DSR
1765 | ((status
& MSVR_DTR
) ? TIOCM_RTS
: 0)
1766 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1767 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1769 result
= TIOCM_RTS
| TIOCM_DSR
1770 | ((status
& MSVR_DTR
) ? TIOCM_DTR
: 0)
1771 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1772 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1781 static int sx_tiocmset(struct tty_struct
*tty
, struct file
*file
,
1782 unsigned int set
, unsigned int clear
)
1784 struct specialix_port
*port
= tty
->driver_data
;
1785 unsigned long flags
;
1786 struct specialix_board
*bp
;
1790 if (sx_paranoia_check(port
, tty
->name
, __func__
)) {
1795 bp
= port_Board(port
);
1797 spin_lock_irqsave(&port
->lock
, flags
);
1798 if (sx_crtscts(port
->port
.tty
)) {
1799 if (set
& TIOCM_RTS
)
1800 port
->MSVR
|= MSVR_DTR
;
1802 if (set
& TIOCM_DTR
)
1803 port
->MSVR
|= MSVR_DTR
;
1805 if (sx_crtscts(port
->port
.tty
)) {
1806 if (clear
& TIOCM_RTS
)
1807 port
->MSVR
&= ~MSVR_DTR
;
1809 if (clear
& TIOCM_DTR
)
1810 port
->MSVR
&= ~MSVR_DTR
;
1812 spin_lock(&bp
->lock
);
1813 sx_out(bp
, CD186x_CAR
, port_No(port
));
1814 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1815 spin_unlock(&bp
->lock
);
1816 spin_unlock_irqrestore(&port
->lock
, flags
);
1822 static int sx_send_break(struct tty_struct
*tty
, int length
)
1824 struct specialix_port
*port
= tty
->driver_data
;
1825 struct specialix_board
*bp
= port_Board(port
);
1826 unsigned long flags
;
1829 if (length
== 0 || length
== -1)
1832 spin_lock_irqsave(&port
->lock
, flags
);
1833 port
->break_length
= SPECIALIX_TPS
/ HZ
* length
;
1834 port
->COR2
|= COR2_ETC
;
1835 port
->IER
|= IER_TXRDY
;
1836 spin_lock(&bp
->lock
);
1837 sx_out(bp
, CD186x_CAR
, port_No(port
));
1838 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1839 sx_out(bp
, CD186x_IER
, port
->IER
);
1840 spin_unlock(&bp
->lock
);
1841 spin_unlock_irqrestore(&port
->lock
, flags
);
1843 spin_lock_irqsave(&bp
->lock
, flags
);
1844 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
1845 spin_unlock_irqrestore(&bp
->lock
, flags
);
1853 static int sx_set_serial_info(struct specialix_port
*port
,
1854 struct serial_struct __user
*newinfo
)
1856 struct serial_struct tmp
;
1857 struct specialix_board
*bp
= port_Board(port
);
1862 if (copy_from_user(&tmp
, newinfo
, sizeof(tmp
))) {
1869 change_speed
= ((port
->port
.flags
& ASYNC_SPD_MASK
) !=
1870 (tmp
.flags
& ASYNC_SPD_MASK
));
1871 change_speed
|= (tmp
.custom_divisor
!= port
->custom_divisor
);
1873 if (!capable(CAP_SYS_ADMIN
)) {
1874 if ((tmp
.close_delay
!= port
->port
.close_delay
) ||
1875 (tmp
.closing_wait
!= port
->port
.closing_wait
) ||
1876 ((tmp
.flags
& ~ASYNC_USR_MASK
) !=
1877 (port
->port
.flags
& ~ASYNC_USR_MASK
))) {
1882 port
->port
.flags
= ((port
->port
.flags
& ~ASYNC_USR_MASK
) |
1883 (tmp
.flags
& ASYNC_USR_MASK
));
1884 port
->custom_divisor
= tmp
.custom_divisor
;
1886 port
->port
.flags
= ((port
->port
.flags
& ~ASYNC_FLAGS
) |
1887 (tmp
.flags
& ASYNC_FLAGS
));
1888 port
->port
.close_delay
= tmp
.close_delay
;
1889 port
->port
.closing_wait
= tmp
.closing_wait
;
1890 port
->custom_divisor
= tmp
.custom_divisor
;
1893 sx_change_speed(bp
, port
);
1901 static int sx_get_serial_info(struct specialix_port
*port
,
1902 struct serial_struct __user
*retinfo
)
1904 struct serial_struct tmp
;
1905 struct specialix_board
*bp
= port_Board(port
);
1909 memset(&tmp
, 0, sizeof(tmp
));
1911 tmp
.type
= PORT_CIRRUS
;
1912 tmp
.line
= port
- sx_port
;
1913 tmp
.port
= bp
->base
;
1915 tmp
.flags
= port
->port
.flags
;
1916 tmp
.baud_base
= (SX_OSCFREQ
+ CD186x_TPC
/2) / CD186x_TPC
;
1917 tmp
.close_delay
= port
->port
.close_delay
* HZ
/100;
1918 tmp
.closing_wait
= port
->port
.closing_wait
* HZ
/100;
1919 tmp
.custom_divisor
= port
->custom_divisor
;
1920 tmp
.xmit_fifo_size
= CD186x_NFIFO
;
1922 if (copy_to_user(retinfo
, &tmp
, sizeof(tmp
))) {
1932 static int sx_ioctl(struct tty_struct
*tty
, struct file
*filp
,
1933 unsigned int cmd
, unsigned long arg
)
1935 struct specialix_port
*port
= tty
->driver_data
;
1936 void __user
*argp
= (void __user
*)arg
;
1940 if (sx_paranoia_check(port
, tty
->name
, "sx_ioctl")) {
1948 return sx_get_serial_info(port
, argp
);
1951 return sx_set_serial_info(port
, argp
);
1954 return -ENOIOCTLCMD
;
1961 static void sx_throttle(struct tty_struct
*tty
)
1963 struct specialix_port
*port
= tty
->driver_data
;
1964 struct specialix_board
*bp
;
1965 unsigned long flags
;
1969 if (sx_paranoia_check(port
, tty
->name
, "sx_throttle")) {
1974 bp
= port_Board(port
);
1976 /* Use DTR instead of RTS ! */
1977 if (sx_crtscts(tty
))
1978 port
->MSVR
&= ~MSVR_DTR
;
1980 /* Auch!!! I think the system shouldn't call this then. */
1981 /* Or maybe we're supposed (allowed?) to do our side of hw
1982 handshake anyway, even when hardware handshake is off.
1983 When you see this in your logs, please report.... */
1985 "sx%d: Need to throttle, but can't (hardware hs is off)\n",
1988 spin_lock_irqsave(&bp
->lock
, flags
);
1989 sx_out(bp
, CD186x_CAR
, port_No(port
));
1990 spin_unlock_irqrestore(&bp
->lock
, flags
);
1993 spin_lock_irqsave(&bp
->lock
, flags
);
1994 sx_out(bp
, CD186x_CCR
, CCR_SSCH2
);
1995 spin_unlock_irqrestore(&bp
->lock
, flags
);
1998 spin_lock_irqsave(&bp
->lock
, flags
);
1999 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2000 spin_unlock_irqrestore(&bp
->lock
, flags
);
2006 static void sx_unthrottle(struct tty_struct
*tty
)
2008 struct specialix_port
*port
= tty
->driver_data
;
2009 struct specialix_board
*bp
;
2010 unsigned long flags
;
2014 if (sx_paranoia_check(port
, tty
->name
, "sx_unthrottle")) {
2019 bp
= port_Board(port
);
2021 spin_lock_irqsave(&port
->lock
, flags
);
2022 /* XXXX Use DTR INSTEAD???? */
2023 if (sx_crtscts(tty
))
2024 port
->MSVR
|= MSVR_DTR
;
2025 /* Else clause: see remark in "sx_throttle"... */
2026 spin_lock(&bp
->lock
);
2027 sx_out(bp
, CD186x_CAR
, port_No(port
));
2028 spin_unlock(&bp
->lock
);
2030 spin_unlock_irqrestore(&port
->lock
, flags
);
2032 spin_lock_irqsave(&bp
->lock
, flags
);
2033 sx_out(bp
, CD186x_CCR
, CCR_SSCH1
);
2034 spin_unlock_irqrestore(&bp
->lock
, flags
);
2036 spin_lock_irqsave(&port
->lock
, flags
);
2038 spin_lock(&bp
->lock
);
2039 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2040 spin_unlock(&bp
->lock
);
2041 spin_unlock_irqrestore(&port
->lock
, flags
);
2047 static void sx_stop(struct tty_struct
*tty
)
2049 struct specialix_port
*port
= tty
->driver_data
;
2050 struct specialix_board
*bp
;
2051 unsigned long flags
;
2055 if (sx_paranoia_check(port
, tty
->name
, "sx_stop")) {
2060 bp
= port_Board(port
);
2062 spin_lock_irqsave(&port
->lock
, flags
);
2063 port
->IER
&= ~IER_TXRDY
;
2064 spin_lock(&bp
->lock
);
2065 sx_out(bp
, CD186x_CAR
, port_No(port
));
2066 sx_out(bp
, CD186x_IER
, port
->IER
);
2067 spin_unlock(&bp
->lock
);
2068 spin_unlock_irqrestore(&port
->lock
, flags
);
2074 static void sx_start(struct tty_struct
*tty
)
2076 struct specialix_port
*port
= tty
->driver_data
;
2077 struct specialix_board
*bp
;
2078 unsigned long flags
;
2082 if (sx_paranoia_check(port
, tty
->name
, "sx_start")) {
2087 bp
= port_Board(port
);
2089 spin_lock_irqsave(&port
->lock
, flags
);
2090 if (port
->xmit_cnt
&& port
->xmit_buf
&& !(port
->IER
& IER_TXRDY
)) {
2091 port
->IER
|= IER_TXRDY
;
2092 spin_lock(&bp
->lock
);
2093 sx_out(bp
, CD186x_CAR
, port_No(port
));
2094 sx_out(bp
, CD186x_IER
, port
->IER
);
2095 spin_unlock(&bp
->lock
);
2097 spin_unlock_irqrestore(&port
->lock
, flags
);
2102 static void sx_hangup(struct tty_struct
*tty
)
2104 struct specialix_port
*port
= tty
->driver_data
;
2105 struct specialix_board
*bp
;
2106 unsigned long flags
;
2110 if (sx_paranoia_check(port
, tty
->name
, "sx_hangup")) {
2115 bp
= port_Board(port
);
2117 sx_shutdown_port(bp
, port
);
2118 spin_lock_irqsave(&port
->lock
, flags
);
2119 bp
->count
-= port
->port
.count
;
2120 if (bp
->count
< 0) {
2122 "sx%d: sx_hangup: bad board count: %d port: %d\n",
2123 board_No(bp
), bp
->count
, tty
->index
);
2126 port
->port
.count
= 0;
2127 port
->port
.flags
&= ~ASYNC_NORMAL_ACTIVE
;
2128 port
->port
.tty
= NULL
;
2129 spin_unlock_irqrestore(&port
->lock
, flags
);
2130 wake_up_interruptible(&port
->port
.open_wait
);
2136 static void sx_set_termios(struct tty_struct
*tty
,
2137 struct ktermios
*old_termios
)
2139 struct specialix_port
*port
= tty
->driver_data
;
2140 unsigned long flags
;
2141 struct specialix_board
*bp
;
2143 if (sx_paranoia_check(port
, tty
->name
, "sx_set_termios"))
2146 bp
= port_Board(port
);
2147 spin_lock_irqsave(&port
->lock
, flags
);
2148 sx_change_speed(port_Board(port
), port
);
2149 spin_unlock_irqrestore(&port
->lock
, flags
);
2151 if ((old_termios
->c_cflag
& CRTSCTS
) &&
2152 !(tty
->termios
->c_cflag
& CRTSCTS
)) {
2153 tty
->hw_stopped
= 0;
2158 static const struct tty_operations sx_ops
= {
2162 .put_char
= sx_put_char
,
2163 .flush_chars
= sx_flush_chars
,
2164 .write_room
= sx_write_room
,
2165 .chars_in_buffer
= sx_chars_in_buffer
,
2166 .flush_buffer
= sx_flush_buffer
,
2168 .throttle
= sx_throttle
,
2169 .unthrottle
= sx_unthrottle
,
2170 .set_termios
= sx_set_termios
,
2173 .hangup
= sx_hangup
,
2174 .tiocmget
= sx_tiocmget
,
2175 .tiocmset
= sx_tiocmset
,
2176 .break_ctl
= sx_send_break
,
2179 static int sx_init_drivers(void)
2186 specialix_driver
= alloc_tty_driver(SX_NBOARD
* SX_NPORT
);
2187 if (!specialix_driver
) {
2188 printk(KERN_ERR
"sx: Couldn't allocate tty_driver.\n");
2193 specialix_driver
->owner
= THIS_MODULE
;
2194 specialix_driver
->name
= "ttyW";
2195 specialix_driver
->major
= SPECIALIX_NORMAL_MAJOR
;
2196 specialix_driver
->type
= TTY_DRIVER_TYPE_SERIAL
;
2197 specialix_driver
->subtype
= SERIAL_TYPE_NORMAL
;
2198 specialix_driver
->init_termios
= tty_std_termios
;
2199 specialix_driver
->init_termios
.c_cflag
=
2200 B9600
| CS8
| CREAD
| HUPCL
| CLOCAL
;
2201 specialix_driver
->init_termios
.c_ispeed
= 9600;
2202 specialix_driver
->init_termios
.c_ospeed
= 9600;
2203 specialix_driver
->flags
= TTY_DRIVER_REAL_RAW
|
2204 TTY_DRIVER_HARDWARE_BREAK
;
2205 tty_set_operations(specialix_driver
, &sx_ops
);
2207 error
= tty_register_driver(specialix_driver
);
2209 put_tty_driver(specialix_driver
);
2211 "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2216 memset(sx_port
, 0, sizeof(sx_port
));
2217 for (i
= 0; i
< SX_NPORT
* SX_NBOARD
; i
++) {
2218 sx_port
[i
].magic
= SPECIALIX_MAGIC
;
2219 tty_port_init(&sx_port
[i
].port
);
2220 spin_lock_init(&sx_port
[i
].lock
);
2227 static void sx_release_drivers(void)
2231 tty_unregister_driver(specialix_driver
);
2232 put_tty_driver(specialix_driver
);
2237 * This routine must be called by kernel at boot time
2239 static int __init
specialix_init(void)
2246 printk(KERN_INFO
"sx: Specialix IO8+ driver v" VERSION
", (c) R.E.Wolff 1997/1998.\n");
2247 printk(KERN_INFO
"sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2250 "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2252 printk(KERN_INFO
"sx: DTR/RTS pin is always RTS.\n");
2254 for (i
= 0; i
< SX_NBOARD
; i
++)
2255 spin_lock_init(&sx_board
[i
].lock
);
2257 if (sx_init_drivers()) {
2262 for (i
= 0; i
< SX_NBOARD
; i
++)
2263 if (sx_board
[i
].base
&& !sx_probe(&sx_board
[i
]))
2268 struct pci_dev
*pdev
= NULL
;
2271 while (i
< SX_NBOARD
) {
2272 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
) {
2276 pdev
= pci_get_device(PCI_VENDOR_ID_SPECIALIX
,
2277 PCI_DEVICE_ID_SPECIALIX_IO8
, pdev
);
2281 if (pci_enable_device(pdev
))
2284 sx_board
[i
].irq
= pdev
->irq
;
2286 sx_board
[i
].base
= pci_resource_start(pdev
, 2);
2288 sx_board
[i
].flags
|= SX_BOARD_IS_PCI
;
2289 if (!sx_probe(&sx_board
[i
]))
2292 /* May exit pci_get sequence early with lots of boards */
2299 sx_release_drivers();
2300 printk(KERN_INFO
"sx: No specialix IO8+ boards detected.\n");
2309 static int iobase
[SX_NBOARD
] = {0,};
2310 static int irq
[SX_NBOARD
] = {0,};
2312 module_param_array(iobase
, int, NULL
, 0);
2313 module_param_array(irq
, int, NULL
, 0);
2314 module_param(sx_debug
, int, 0);
2315 module_param(sx_rtscts
, int, 0);
2316 module_param(sx_rxfifo
, int, 0);
2319 * You can setup up to 4 boards.
2320 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2321 * You should specify the IRQs too in that case "irq=....,...".
2323 * More than 4 boards in one computer is not possible, as the card can
2324 * only use 4 different interrupts.
2327 static int __init
specialix_init_module(void)
2333 if (iobase
[0] || iobase
[1] || iobase
[2] || iobase
[3]) {
2334 for (i
= 0; i
< SX_NBOARD
; i
++) {
2335 sx_board
[i
].base
= iobase
[i
];
2336 sx_board
[i
].irq
= irq
[i
];
2337 sx_board
[i
].count
= 0;
2343 return specialix_init();
2346 static void __exit
specialix_exit_module(void)
2352 sx_release_drivers();
2353 for (i
= 0; i
< SX_NBOARD
; i
++)
2354 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
)
2355 sx_release_io_range(&sx_board
[i
]);
2359 static struct pci_device_id specialx_pci_tbl
[] __devinitdata
= {
2360 { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX
, PCI_DEVICE_ID_SPECIALIX_IO8
) },
2363 MODULE_DEVICE_TABLE(pci
, specialx_pci_tbl
);
2365 module_init(specialix_init_module
);
2366 module_exit(specialix_exit_module
);
2368 MODULE_LICENSE("GPL");
2369 MODULE_ALIAS_CHARDEV_MAJOR(SPECIALIX_NORMAL_MAJOR
);