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>
97 #include <linux/gfp.h>
99 #include "specialix_io8.h"
104 This driver can spew a whole lot of debugging output at you. If you
105 need maximum performance, you should disable the DEBUG define. To
106 aid in debugging in the field, I'm leaving the compile-time debug
107 features enabled, and disable them "runtime". That allows me to
108 instruct people with problems to enable debugging without requiring
114 static int sx_rxfifo
= SPECIALIX_RXFIFO
;
115 static int sx_rtscts
;
118 #define dprintk(f, str...) if (sx_debug & f) printk(str)
120 #define dprintk(f, str...) /* nothing */
123 #define SX_DEBUG_FLOW 0x0001
124 #define SX_DEBUG_DATA 0x0002
125 #define SX_DEBUG_PROBE 0x0004
126 #define SX_DEBUG_CHAN 0x0008
127 #define SX_DEBUG_INIT 0x0010
128 #define SX_DEBUG_RX 0x0020
129 #define SX_DEBUG_TX 0x0040
130 #define SX_DEBUG_IRQ 0x0080
131 #define SX_DEBUG_OPEN 0x0100
132 #define SX_DEBUG_TERMIOS 0x0200
133 #define SX_DEBUG_SIGNALS 0x0400
134 #define SX_DEBUG_FIFO 0x0800
137 #define func_enter() dprintk(SX_DEBUG_FLOW, "io8: enter %s\n", __func__)
138 #define func_exit() dprintk(SX_DEBUG_FLOW, "io8: exit %s\n", __func__)
141 /* Configurable options: */
143 /* Am I paranoid or not ? ;-) */
144 #define SPECIALIX_PARANOIA_CHECK
147 * The following defines are mostly for testing purposes. But if you need
148 * some nice reporting in your syslog, you can define them also.
150 #undef SX_REPORT_FIFO
151 #undef SX_REPORT_OVERRUN
156 #define SPECIALIX_LEGAL_FLAGS \
157 (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \
158 ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \
159 ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
161 static struct tty_driver
*specialix_driver
;
163 static struct specialix_board sx_board
[SX_NBOARD
] = {
164 { 0, SX_IOBASE1
, 9, },
165 { 0, SX_IOBASE2
, 11, },
166 { 0, SX_IOBASE3
, 12, },
167 { 0, SX_IOBASE4
, 15, },
170 static struct specialix_port sx_port
[SX_NBOARD
* SX_NPORT
];
173 static int sx_paranoia_check(struct specialix_port
const *port
,
174 char *name
, const char *routine
)
176 #ifdef SPECIALIX_PARANOIA_CHECK
177 static const char *badmagic
= KERN_ERR
178 "sx: Warning: bad specialix port magic number for device %s in %s\n";
179 static const char *badinfo
= KERN_ERR
180 "sx: Warning: null specialix port for device %s in %s\n";
183 printk(badinfo
, name
, routine
);
186 if (port
->magic
!= SPECIALIX_MAGIC
) {
187 printk(badmagic
, name
, routine
);
197 * Service functions for specialix IO8+ driver.
201 /* Get board number from pointer */
202 static inline int board_No(struct specialix_board
*bp
)
204 return bp
- sx_board
;
208 /* Get port number from pointer */
209 static inline int port_No(struct specialix_port
const *port
)
211 return SX_PORT(port
- sx_port
);
215 /* Get pointer to board from pointer to port */
216 static inline struct specialix_board
*port_Board(
217 struct specialix_port
const *port
)
219 return &sx_board
[SX_BOARD(port
- sx_port
)];
223 /* Input Byte from CL CD186x register */
224 static inline unsigned char sx_in(struct specialix_board
*bp
,
227 bp
->reg
= reg
| 0x80;
228 outb(reg
| 0x80, bp
->base
+ SX_ADDR_REG
);
229 return inb(bp
->base
+ SX_DATA_REG
);
233 /* Output Byte to CL CD186x register */
234 static inline void sx_out(struct specialix_board
*bp
, unsigned short reg
,
237 bp
->reg
= reg
| 0x80;
238 outb(reg
| 0x80, bp
->base
+ SX_ADDR_REG
);
239 outb(val
, bp
->base
+ SX_DATA_REG
);
243 /* Input Byte from CL CD186x register */
244 static inline unsigned char sx_in_off(struct specialix_board
*bp
,
248 outb(reg
, bp
->base
+ SX_ADDR_REG
);
249 return inb(bp
->base
+ SX_DATA_REG
);
253 /* Output Byte to CL CD186x register */
254 static inline void sx_out_off(struct specialix_board
*bp
,
255 unsigned short reg
, unsigned char val
)
258 outb(reg
, bp
->base
+ SX_ADDR_REG
);
259 outb(val
, bp
->base
+ SX_DATA_REG
);
263 /* Wait for Channel Command Register ready */
264 static void sx_wait_CCR(struct specialix_board
*bp
)
266 unsigned long delay
, flags
;
269 for (delay
= SX_CCR_TIMEOUT
; delay
; delay
--) {
270 spin_lock_irqsave(&bp
->lock
, flags
);
271 ccr
= sx_in(bp
, CD186x_CCR
);
272 spin_unlock_irqrestore(&bp
->lock
, flags
);
278 printk(KERN_ERR
"sx%d: Timeout waiting for CCR.\n", board_No(bp
));
282 /* Wait for Channel Command Register ready */
283 static void sx_wait_CCR_off(struct specialix_board
*bp
)
289 for (delay
= SX_CCR_TIMEOUT
; delay
; delay
--) {
290 spin_lock_irqsave(&bp
->lock
, flags
);
291 crr
= sx_in_off(bp
, CD186x_CCR
);
292 spin_unlock_irqrestore(&bp
->lock
, flags
);
298 printk(KERN_ERR
"sx%d: Timeout waiting for CCR.\n", board_No(bp
));
303 * specialix IO8+ IO range functions.
306 static int sx_request_io_range(struct specialix_board
*bp
)
308 return request_region(bp
->base
,
309 bp
->flags
& SX_BOARD_IS_PCI
? SX_PCI_IO_SPACE
: SX_IO_SPACE
,
310 "specialix IO8+") == NULL
;
314 static void sx_release_io_range(struct specialix_board
*bp
)
316 release_region(bp
->base
, bp
->flags
& SX_BOARD_IS_PCI
?
317 SX_PCI_IO_SPACE
: SX_IO_SPACE
);
321 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
322 static int sx_set_irq(struct specialix_board
*bp
)
328 if (bp
->flags
& SX_BOARD_IS_PCI
)
331 /* In the same order as in the docs... */
344 default:printk(KERN_ERR
345 "Speclialix: cannot set irq to %d.\n", bp
->irq
);
348 spin_lock_irqsave(&bp
->lock
, flags
);
349 for (i
= 0; i
< 2; i
++) {
350 sx_out(bp
, CD186x_CAR
, i
);
351 sx_out(bp
, CD186x_MSVRTS
, ((virq
>> i
) & 0x1)? MSVR_RTS
:0);
353 spin_unlock_irqrestore(&bp
->lock
, flags
);
358 /* Reset and setup CD186x chip */
359 static int sx_init_CD186x(struct specialix_board
*bp
)
366 sx_wait_CCR_off(bp
); /* Wait for CCR ready */
367 spin_lock_irqsave(&bp
->lock
, flags
);
368 sx_out_off(bp
, CD186x_CCR
, CCR_HARDRESET
); /* Reset CD186x chip */
369 spin_unlock_irqrestore(&bp
->lock
, flags
);
370 msleep(50); /* Delay 0.05 sec */
371 spin_lock_irqsave(&bp
->lock
, flags
);
372 sx_out_off(bp
, CD186x_GIVR
, SX_ID
); /* Set ID for this chip */
373 sx_out_off(bp
, CD186x_GICR
, 0); /* Clear all bits */
374 sx_out_off(bp
, CD186x_PILR1
, SX_ACK_MINT
); /* Prio for modem intr */
375 sx_out_off(bp
, CD186x_PILR2
, SX_ACK_TINT
); /* Prio for transmitter intr */
376 sx_out_off(bp
, CD186x_PILR3
, SX_ACK_RINT
); /* Prio for receiver intr */
378 sx_out_off(bp
, CD186x_SRCR
, sx_in(bp
, CD186x_SRCR
) | SRCR_REGACKEN
);
380 /* Setting up prescaler. We need 4 ticks per 1 ms */
381 scaler
= SX_OSCFREQ
/SPECIALIX_TPS
;
383 sx_out_off(bp
, CD186x_PPRH
, scaler
>> 8);
384 sx_out_off(bp
, CD186x_PPRL
, scaler
& 0xff);
385 spin_unlock_irqrestore(&bp
->lock
, flags
);
387 if (!sx_set_irq(bp
)) {
388 /* Figure out how to pass this along... */
389 printk(KERN_ERR
"Cannot set irq to %d.\n", bp
->irq
);
398 static int read_cross_byte(struct specialix_board
*bp
, int reg
, int bit
)
404 spin_lock_irqsave(&bp
->lock
, flags
);
405 for (i
= 0, t
= 0; i
< 8; i
++) {
406 sx_out_off(bp
, CD186x_CAR
, i
);
407 if (sx_in_off(bp
, reg
) & bit
)
410 spin_unlock_irqrestore(&bp
->lock
, flags
);
416 /* Main probing routine, also sets irq. */
417 static int sx_probe(struct specialix_board
*bp
)
419 unsigned char val1
, val2
;
425 if (sx_request_io_range(bp
)) {
430 /* Are the I/O ports here ? */
431 sx_out_off(bp
, CD186x_PPRL
, 0x5a);
433 val1
= sx_in_off(bp
, CD186x_PPRL
);
435 sx_out_off(bp
, CD186x_PPRL
, 0xa5);
437 val2
= sx_in_off(bp
, CD186x_PPRL
);
440 if (val1
!= 0x5a || val2
!= 0xa5) {
442 "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
443 board_No(bp
), bp
->base
);
444 sx_release_io_range(bp
);
449 /* Check the DSR lines that Specialix uses as board
451 val1
= read_cross_byte(bp
, CD186x_MSVR
, MSVR_DSR
);
452 val2
= read_cross_byte(bp
, CD186x_MSVR
, MSVR_RTS
);
453 dprintk(SX_DEBUG_INIT
,
454 "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
455 board_No(bp
), val1
, val2
);
457 /* They managed to switch the bit order between the docs and
458 the IO8+ card. The new PCI card now conforms to old docs.
459 They changed the PCI docs to reflect the situation on the
461 val2
= (bp
->flags
& SX_BOARD_IS_PCI
)?0x4d : 0xb2;
464 "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
465 board_No(bp
), val2
, bp
->base
, val1
);
466 sx_release_io_range(bp
);
472 /* Reset CD186x again */
473 if (!sx_init_CD186x(bp
)) {
474 sx_release_io_range(bp
);
479 sx_request_io_range(bp
);
480 bp
->flags
|= SX_BOARD_PRESENT
;
482 /* Chip revcode pkgtype
487 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
489 -- Thanks to Gwen Wang, Cirrus Logic.
492 switch (sx_in_off(bp
, CD186x_GFRCR
)) {
508 break; /* Does not exist at this time */
514 dprintk(SX_DEBUG_INIT
, " GFCR = 0x%02x\n", sx_in_off(bp
, CD186x_GFRCR
));
517 "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
518 board_No(bp
), bp
->base
, bp
->irq
, chip
, rev
);
526 * Interrupt processing routines.
529 static struct specialix_port
*sx_get_port(struct specialix_board
*bp
,
530 unsigned char const *what
)
532 unsigned char channel
;
533 struct specialix_port
*port
= NULL
;
535 channel
= sx_in(bp
, CD186x_GICR
) >> GICR_CHAN_OFF
;
536 dprintk(SX_DEBUG_CHAN
, "channel: %d\n", channel
);
537 if (channel
< CD186x_NCH
) {
538 port
= &sx_port
[board_No(bp
) * SX_NPORT
+ channel
];
539 dprintk(SX_DEBUG_CHAN
, "port: %d %p flags: 0x%lx\n",
540 board_No(bp
) * SX_NPORT
+ channel
, port
,
541 port
->port
.flags
& ASYNC_INITIALIZED
);
543 if (port
->port
.flags
& ASYNC_INITIALIZED
) {
544 dprintk(SX_DEBUG_CHAN
, "port: %d %p\n", channel
, port
);
549 printk(KERN_INFO
"sx%d: %s interrupt from invalid port %d\n",
550 board_No(bp
), what
, channel
);
555 static void sx_receive_exc(struct specialix_board
*bp
)
557 struct specialix_port
*port
;
558 struct tty_struct
*tty
;
559 unsigned char status
;
560 unsigned char ch
, flag
;
564 port
= sx_get_port(bp
, "Receive");
566 dprintk(SX_DEBUG_RX
, "Hmm, couldn't find port.\n");
570 tty
= port
->port
.tty
;
572 status
= sx_in(bp
, CD186x_RCSR
);
574 dprintk(SX_DEBUG_RX
, "status: 0x%x\n", status
);
575 if (status
& RCSR_OE
) {
577 dprintk(SX_DEBUG_FIFO
,
578 "sx%d: port %d: Overrun. Total %ld overruns.\n",
579 board_No(bp
), port_No(port
), port
->overrun
);
581 status
&= port
->mark_mask
;
583 /* This flip buffer check needs to be below the reading of the
584 status register to reset the chip's IRQ.... */
585 if (tty_buffer_request_room(tty
, 1) == 0) {
586 dprintk(SX_DEBUG_FIFO
,
587 "sx%d: port %d: Working around flip buffer overflow.\n",
588 board_No(bp
), port_No(port
));
593 ch
= sx_in(bp
, CD186x_RDR
);
598 if (status
& RCSR_TOUT
) {
600 "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
601 board_No(bp
), port_No(port
));
605 } else if (status
& RCSR_BREAK
) {
606 dprintk(SX_DEBUG_RX
, "sx%d: port %d: Handling break...\n",
607 board_No(bp
), port_No(port
));
609 if (port
->port
.flags
& ASYNC_SAK
)
612 } else if (status
& RCSR_PE
)
615 else if (status
& RCSR_FE
)
618 else if (status
& RCSR_OE
)
624 if (tty_insert_flip_char(tty
, ch
, flag
))
625 tty_flip_buffer_push(tty
);
630 static void sx_receive(struct specialix_board
*bp
)
632 struct specialix_port
*port
;
633 struct tty_struct
*tty
;
638 port
= sx_get_port(bp
, "Receive");
640 dprintk(SX_DEBUG_RX
, "Hmm, couldn't find port.\n");
644 tty
= port
->port
.tty
;
646 count
= sx_in(bp
, CD186x_RDCR
);
647 dprintk(SX_DEBUG_RX
, "port: %p: count: %d\n", port
, count
);
648 port
->hits
[count
> 8 ? 9 : count
]++;
651 tty_insert_flip_char(tty
, sx_in(bp
, CD186x_RDR
), TTY_NORMAL
);
652 tty_flip_buffer_push(tty
);
657 static void sx_transmit(struct specialix_board
*bp
)
659 struct specialix_port
*port
;
660 struct tty_struct
*tty
;
664 port
= sx_get_port(bp
, "Transmit");
669 dprintk(SX_DEBUG_TX
, "port: %p\n", port
);
670 tty
= port
->port
.tty
;
672 if (port
->IER
& IER_TXEMPTY
) {
674 sx_out(bp
, CD186x_CAR
, port_No(port
));
675 port
->IER
&= ~IER_TXEMPTY
;
676 sx_out(bp
, CD186x_IER
, port
->IER
);
681 if ((port
->xmit_cnt
<= 0 && !port
->break_length
)
682 || tty
->stopped
|| tty
->hw_stopped
) {
683 sx_out(bp
, CD186x_CAR
, port_No(port
));
684 port
->IER
&= ~IER_TXRDY
;
685 sx_out(bp
, CD186x_IER
, port
->IER
);
690 if (port
->break_length
) {
691 if (port
->break_length
> 0) {
692 if (port
->COR2
& COR2_ETC
) {
693 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
694 sx_out(bp
, CD186x_TDR
, CD186x_C_SBRK
);
695 port
->COR2
&= ~COR2_ETC
;
697 count
= min_t(int, port
->break_length
, 0xff);
698 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
699 sx_out(bp
, CD186x_TDR
, CD186x_C_DELAY
);
700 sx_out(bp
, CD186x_TDR
, count
);
701 port
->break_length
-= count
;
702 if (port
->break_length
== 0)
703 port
->break_length
--;
705 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
706 sx_out(bp
, CD186x_TDR
, CD186x_C_EBRK
);
707 sx_out(bp
, CD186x_COR2
, port
->COR2
);
709 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
710 port
->break_length
= 0;
717 count
= CD186x_NFIFO
;
719 sx_out(bp
, CD186x_TDR
, port
->xmit_buf
[port
->xmit_tail
++]);
720 port
->xmit_tail
= port
->xmit_tail
& (SERIAL_XMIT_SIZE
-1);
721 if (--port
->xmit_cnt
<= 0)
723 } while (--count
> 0);
725 if (port
->xmit_cnt
<= 0) {
726 sx_out(bp
, CD186x_CAR
, port_No(port
));
727 port
->IER
&= ~IER_TXRDY
;
728 sx_out(bp
, CD186x_IER
, port
->IER
);
730 if (port
->xmit_cnt
<= port
->wakeup_chars
)
737 static void sx_check_modem(struct specialix_board
*bp
)
739 struct specialix_port
*port
;
740 struct tty_struct
*tty
;
744 dprintk(SX_DEBUG_SIGNALS
, "Modem intr. ");
745 port
= sx_get_port(bp
, "Modem");
749 tty
= port
->port
.tty
;
751 mcr
= sx_in(bp
, CD186x_MCR
);
753 if ((mcr
& MCR_CDCHG
)) {
754 dprintk(SX_DEBUG_SIGNALS
, "CD just changed... ");
755 msvr_cd
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
757 dprintk(SX_DEBUG_SIGNALS
, "Waking up guys in open.\n");
758 wake_up_interruptible(&port
->port
.open_wait
);
760 dprintk(SX_DEBUG_SIGNALS
, "Sending HUP.\n");
765 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
766 if (mcr
& MCR_CTSCHG
) {
767 if (sx_in(bp
, CD186x_MSVR
) & MSVR_CTS
) {
769 port
->IER
|= IER_TXRDY
;
770 if (port
->xmit_cnt
<= port
->wakeup_chars
)
774 port
->IER
&= ~IER_TXRDY
;
776 sx_out(bp
, CD186x_IER
, port
->IER
);
778 if (mcr
& MCR_DSSXHG
) {
779 if (sx_in(bp
, CD186x_MSVR
) & MSVR_DSR
) {
781 port
->IER
|= IER_TXRDY
;
782 if (port
->xmit_cnt
<= port
->wakeup_chars
)
786 port
->IER
&= ~IER_TXRDY
;
788 sx_out(bp
, CD186x_IER
, port
->IER
);
790 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
792 /* Clear change bits */
793 sx_out(bp
, CD186x_MCR
, 0);
797 /* The main interrupt processing routine */
798 static irqreturn_t
sx_interrupt(int dummy
, void *dev_id
)
800 unsigned char status
;
802 struct specialix_board
*bp
= dev_id
;
803 unsigned long loop
= 0;
809 spin_lock_irqsave(&bp
->lock
, flags
);
811 dprintk(SX_DEBUG_FLOW
, "enter %s port %d room: %ld\n", __func__
,
812 port_No(sx_get_port(bp
, "INT")),
813 SERIAL_XMIT_SIZE
- sx_get_port(bp
, "ITN")->xmit_cnt
- 1);
814 if (!(bp
->flags
& SX_BOARD_ACTIVE
)) {
815 dprintk(SX_DEBUG_IRQ
, "sx: False interrupt. irq %d.\n",
817 spin_unlock_irqrestore(&bp
->lock
, flags
);
824 while (++loop
< 16) {
825 status
= sx_in(bp
, CD186x_SRSR
) &
826 (SRSR_RREQint
| SRSR_TREQint
| SRSR_MREQint
);
829 if (status
& SRSR_RREQint
) {
830 ack
= sx_in(bp
, CD186x_RRAR
);
832 if (ack
== (SX_ID
| GIVR_IT_RCV
))
834 else if (ack
== (SX_ID
| GIVR_IT_REXC
))
838 "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
839 board_No(bp
), status
, ack
);
841 } else if (status
& SRSR_TREQint
) {
842 ack
= sx_in(bp
, CD186x_TRAR
);
844 if (ack
== (SX_ID
| GIVR_IT_TX
))
847 printk(KERN_ERR
"sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
848 board_No(bp
), status
, ack
,
849 port_No(sx_get_port(bp
, "Int")));
850 } else if (status
& SRSR_MREQint
) {
851 ack
= sx_in(bp
, CD186x_MRAR
);
853 if (ack
== (SX_ID
| GIVR_IT_MODEM
))
857 "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
858 board_No(bp
), status
, ack
);
862 sx_out(bp
, CD186x_EOIR
, 0); /* Mark end of interrupt */
865 outb(bp
->reg
, bp
->base
+ SX_ADDR_REG
);
866 spin_unlock_irqrestore(&bp
->lock
, flags
);
873 * Routines for open & close processing.
876 static void turn_ints_off(struct specialix_board
*bp
)
881 spin_lock_irqsave(&bp
->lock
, flags
);
882 (void) sx_in_off(bp
, 0); /* Turn off interrupts. */
883 spin_unlock_irqrestore(&bp
->lock
, flags
);
888 static void turn_ints_on(struct specialix_board
*bp
)
894 spin_lock_irqsave(&bp
->lock
, flags
);
895 (void) sx_in(bp
, 0); /* Turn ON interrupts. */
896 spin_unlock_irqrestore(&bp
->lock
, flags
);
902 /* Called with disabled interrupts */
903 static int sx_setup_board(struct specialix_board
*bp
)
907 if (bp
->flags
& SX_BOARD_ACTIVE
)
910 if (bp
->flags
& SX_BOARD_IS_PCI
)
911 error
= request_irq(bp
->irq
, sx_interrupt
,
912 IRQF_DISABLED
| IRQF_SHARED
, "specialix IO8+", bp
);
914 error
= request_irq(bp
->irq
, sx_interrupt
,
915 IRQF_DISABLED
, "specialix IO8+", bp
);
921 bp
->flags
|= SX_BOARD_ACTIVE
;
927 /* Called with disabled interrupts */
928 static void sx_shutdown_board(struct specialix_board
*bp
)
932 if (!(bp
->flags
& SX_BOARD_ACTIVE
)) {
937 bp
->flags
&= ~SX_BOARD_ACTIVE
;
939 dprintk(SX_DEBUG_IRQ
, "Freeing IRQ%d for board %d.\n",
940 bp
->irq
, board_No(bp
));
941 free_irq(bp
->irq
, bp
);
946 static unsigned int sx_crtscts(struct tty_struct
*tty
)
949 return C_CRTSCTS(tty
);
954 * Setting up port characteristics.
955 * Must be called with disabled interrupts
957 static void sx_change_speed(struct specialix_board
*bp
,
958 struct specialix_port
*port
)
960 struct tty_struct
*tty
;
963 unsigned char cor1
= 0, cor3
= 0;
964 unsigned char mcor1
= 0, mcor2
= 0;
965 static unsigned long again
;
970 tty
= port
->port
.tty
;
971 if (!tty
|| !tty
->termios
) {
978 /* Select port on the board */
979 spin_lock_irqsave(&bp
->lock
, flags
);
980 sx_out(bp
, CD186x_CAR
, port_No(port
));
982 /* The Specialix board doens't implement the RTS lines.
983 They are used to set the IRQ level. Don't touch them. */
985 port
->MSVR
= MSVR_DTR
| (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
987 port
->MSVR
= (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
988 spin_unlock_irqrestore(&bp
->lock
, flags
);
989 dprintk(SX_DEBUG_TERMIOS
, "sx: got MSVR=%02x.\n", port
->MSVR
);
990 baud
= tty_get_baud_rate(tty
);
993 if ((port
->port
.flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_HI
)
995 if ((port
->port
.flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_VHI
)
1000 /* Drop DTR & exit */
1001 dprintk(SX_DEBUG_TERMIOS
, "Dropping DTR... Hmm....\n");
1002 if (!sx_crtscts(tty
)) {
1003 port
->MSVR
&= ~MSVR_DTR
;
1004 spin_lock_irqsave(&bp
->lock
, flags
);
1005 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1006 spin_unlock_irqrestore(&bp
->lock
, flags
);
1008 dprintk(SX_DEBUG_TERMIOS
, "Can't drop DTR: no DTR.\n");
1012 if (!sx_crtscts(tty
))
1013 port
->MSVR
|= MSVR_DTR
;
1017 * Now we must calculate some speed depended things
1020 /* Set baud rate for port */
1021 tmp
= port
->custom_divisor
;
1024 "sx%d: Using custom baud rate divisor %ld. \n"
1025 "This is an untested option, please be careful.\n",
1026 port_No(port
), tmp
);
1028 tmp
= (((SX_OSCFREQ
+ baud
/2) / baud
+ CD186x_TPC
/2) /
1031 if (tmp
< 0x10 && time_before(again
, jiffies
)) {
1032 again
= jiffies
+ HZ
* 60;
1033 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1035 printk(KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1036 "Performance degradation is possible.\n"
1037 "Read specialix.txt for more info.\n",
1038 port_No(port
), tmp
);
1040 printk(KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1041 "Warning: overstressing Cirrus chip. This might not work.\n"
1042 "Read specialix.txt for more info.\n", port_No(port
), tmp
);
1045 spin_lock_irqsave(&bp
->lock
, flags
);
1046 sx_out(bp
, CD186x_RBPRH
, (tmp
>> 8) & 0xff);
1047 sx_out(bp
, CD186x_TBPRH
, (tmp
>> 8) & 0xff);
1048 sx_out(bp
, CD186x_RBPRL
, tmp
& 0xff);
1049 sx_out(bp
, CD186x_TBPRL
, tmp
& 0xff);
1050 spin_unlock_irqrestore(&bp
->lock
, flags
);
1051 if (port
->custom_divisor
)
1052 baud
= (SX_OSCFREQ
+ port
->custom_divisor
/2) /
1053 port
->custom_divisor
;
1054 baud
= (baud
+ 5) / 10; /* Estimated CPS */
1056 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1057 tmp
= ((baud
+ HZ
/2) / HZ
) * 2 - CD186x_NFIFO
;
1058 port
->wakeup_chars
= (tmp
< 0) ? 0 : ((tmp
>= SERIAL_XMIT_SIZE
) ?
1059 SERIAL_XMIT_SIZE
- 1 : tmp
);
1061 /* Receiver timeout will be transmission time for 1.5 chars */
1062 tmp
= (SPECIALIX_TPS
+ SPECIALIX_TPS
/2 + baud
/2) / baud
;
1063 tmp
= (tmp
> 0xff) ? 0xff : tmp
;
1064 spin_lock_irqsave(&bp
->lock
, flags
);
1065 sx_out(bp
, CD186x_RTPR
, tmp
);
1066 spin_unlock_irqrestore(&bp
->lock
, flags
);
1067 switch (C_CSIZE(tty
)) {
1085 cor1
|= COR1_IGNORE
;
1086 if (C_PARENB(tty
)) {
1087 cor1
|= COR1_NORMPAR
;
1091 cor1
&= ~COR1_IGNORE
;
1093 /* Set marking of some errors */
1094 port
->mark_mask
= RCSR_OE
| RCSR_TOUT
;
1096 port
->mark_mask
|= RCSR_FE
| RCSR_PE
;
1097 if (I_BRKINT(tty
) || I_PARMRK(tty
))
1098 port
->mark_mask
|= RCSR_BREAK
;
1100 port
->mark_mask
&= ~(RCSR_FE
| RCSR_PE
);
1101 if (I_IGNBRK(tty
)) {
1102 port
->mark_mask
&= ~RCSR_BREAK
;
1104 /* Real raw mode. Ignore all */
1105 port
->mark_mask
&= ~RCSR_OE
;
1107 /* Enable Hardware Flow Control */
1108 if (C_CRTSCTS(tty
)) {
1109 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1110 port
->IER
|= IER_DSR
| IER_CTS
;
1111 mcor1
|= MCOR1_DSRZD
| MCOR1_CTSZD
;
1112 mcor2
|= MCOR2_DSROD
| MCOR2_CTSOD
;
1113 spin_lock_irqsave(&bp
->lock
, flags
);
1114 tty
->hw_stopped
= !(sx_in(bp
, CD186x_MSVR
) &
1115 (MSVR_CTS
|MSVR_DSR
));
1116 spin_unlock_irqrestore(&bp
->lock
, flags
);
1118 port
->COR2
|= COR2_CTSAE
;
1121 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1122 /* Some people reported that it works, but I still doubt it */
1124 port
->COR2
|= COR2_TXIBE
;
1125 cor3
|= (COR3_FCT
| COR3_SCDE
);
1127 port
->COR2
|= COR2_IXM
;
1128 spin_lock_irqsave(&bp
->lock
, flags
);
1129 sx_out(bp
, CD186x_SCHR1
, START_CHAR(tty
));
1130 sx_out(bp
, CD186x_SCHR2
, STOP_CHAR(tty
));
1131 sx_out(bp
, CD186x_SCHR3
, START_CHAR(tty
));
1132 sx_out(bp
, CD186x_SCHR4
, STOP_CHAR(tty
));
1133 spin_unlock_irqrestore(&bp
->lock
, flags
);
1135 if (!C_CLOCAL(tty
)) {
1136 /* Enable CD check */
1137 port
->IER
|= IER_CD
;
1138 mcor1
|= MCOR1_CDZD
;
1139 mcor2
|= MCOR2_CDOD
;
1143 /* Enable receiver */
1144 port
->IER
|= IER_RXD
;
1146 /* Set input FIFO size (1-8 bytes) */
1148 /* Setting up CD186x channel registers */
1149 spin_lock_irqsave(&bp
->lock
, flags
);
1150 sx_out(bp
, CD186x_COR1
, cor1
);
1151 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1152 sx_out(bp
, CD186x_COR3
, cor3
);
1153 spin_unlock_irqrestore(&bp
->lock
, flags
);
1154 /* Make CD186x know about registers change */
1156 spin_lock_irqsave(&bp
->lock
, flags
);
1157 sx_out(bp
, CD186x_CCR
, CCR_CORCHG1
| CCR_CORCHG2
| CCR_CORCHG3
);
1158 /* Setting up modem option registers */
1159 dprintk(SX_DEBUG_TERMIOS
, "Mcor1 = %02x, mcor2 = %02x.\n",
1161 sx_out(bp
, CD186x_MCOR1
, mcor1
);
1162 sx_out(bp
, CD186x_MCOR2
, mcor2
);
1163 spin_unlock_irqrestore(&bp
->lock
, flags
);
1164 /* Enable CD186x transmitter & receiver */
1166 spin_lock_irqsave(&bp
->lock
, flags
);
1167 sx_out(bp
, CD186x_CCR
, CCR_TXEN
| CCR_RXEN
);
1168 /* Enable interrupts */
1169 sx_out(bp
, CD186x_IER
, port
->IER
);
1170 /* And finally set the modem lines... */
1171 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1172 spin_unlock_irqrestore(&bp
->lock
, flags
);
1178 /* Must be called with interrupts enabled */
1179 static int sx_setup_port(struct specialix_board
*bp
,
1180 struct specialix_port
*port
)
1182 unsigned long flags
;
1186 if (port
->port
.flags
& ASYNC_INITIALIZED
) {
1191 if (!port
->xmit_buf
) {
1192 /* We may sleep in get_zeroed_page() */
1195 tmp
= get_zeroed_page(GFP_KERNEL
);
1201 if (port
->xmit_buf
) {
1204 return -ERESTARTSYS
;
1206 port
->xmit_buf
= (unsigned char *) tmp
;
1209 spin_lock_irqsave(&port
->lock
, flags
);
1212 clear_bit(TTY_IO_ERROR
, &port
->port
.tty
->flags
);
1214 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1215 sx_change_speed(bp
, port
);
1216 port
->port
.flags
|= ASYNC_INITIALIZED
;
1218 spin_unlock_irqrestore(&port
->lock
, flags
);
1226 /* Must be called with interrupts disabled */
1227 static void sx_shutdown_port(struct specialix_board
*bp
,
1228 struct specialix_port
*port
)
1230 struct tty_struct
*tty
;
1232 unsigned long flags
;
1236 if (!(port
->port
.flags
& ASYNC_INITIALIZED
)) {
1241 if (sx_debug
& SX_DEBUG_FIFO
) {
1242 dprintk(SX_DEBUG_FIFO
,
1243 "sx%d: port %d: %ld overruns, FIFO hits [ ",
1244 board_No(bp
), port_No(port
), port
->overrun
);
1245 for (i
= 0; i
< 10; i
++)
1246 dprintk(SX_DEBUG_FIFO
, "%ld ", port
->hits
[i
]);
1247 dprintk(SX_DEBUG_FIFO
, "].\n");
1250 if (port
->xmit_buf
) {
1251 free_page((unsigned long) port
->xmit_buf
);
1252 port
->xmit_buf
= NULL
;
1256 spin_lock_irqsave(&bp
->lock
, flags
);
1257 sx_out(bp
, CD186x_CAR
, port_No(port
));
1259 tty
= port
->port
.tty
;
1260 if (tty
== NULL
|| C_HUPCL(tty
)) {
1262 sx_out(bp
, CD186x_MSVDTR
, 0);
1264 spin_unlock_irqrestore(&bp
->lock
, flags
);
1267 spin_lock_irqsave(&bp
->lock
, flags
);
1268 sx_out(bp
, CD186x_CCR
, CCR_SOFTRESET
);
1269 /* Disable all interrupts from this port */
1271 sx_out(bp
, CD186x_IER
, port
->IER
);
1272 spin_unlock_irqrestore(&bp
->lock
, flags
);
1274 set_bit(TTY_IO_ERROR
, &tty
->flags
);
1275 port
->port
.flags
&= ~ASYNC_INITIALIZED
;
1278 sx_shutdown_board(bp
);
1283 static int block_til_ready(struct tty_struct
*tty
, struct file
*filp
,
1284 struct specialix_port
*port
)
1286 DECLARE_WAITQUEUE(wait
, current
);
1287 struct specialix_board
*bp
= port_Board(port
);
1291 unsigned long flags
;
1296 * If the device is in the middle of being closed, then block
1297 * until it's done, and then try again.
1299 if (tty_hung_up_p(filp
) || port
->port
.flags
& ASYNC_CLOSING
) {
1300 interruptible_sleep_on(&port
->port
.close_wait
);
1301 if (port
->port
.flags
& ASYNC_HUP_NOTIFY
) {
1306 return -ERESTARTSYS
;
1311 * If non-blocking mode is set, or the port is not enabled,
1312 * then make the check up front and then exit.
1314 if ((filp
->f_flags
& O_NONBLOCK
) ||
1315 (tty
->flags
& (1 << TTY_IO_ERROR
))) {
1316 port
->port
.flags
|= ASYNC_NORMAL_ACTIVE
;
1325 * Block waiting for the carrier detect and the line to become
1326 * free (i.e., not in use by the callout). While we are in
1327 * this loop, info->count is dropped by one, so that
1328 * rs_close() knows when to free things. We restore it upon
1329 * exit, either normal or abnormal.
1332 add_wait_queue(&port
->port
.open_wait
, &wait
);
1333 spin_lock_irqsave(&port
->lock
, flags
);
1334 if (!tty_hung_up_p(filp
))
1336 spin_unlock_irqrestore(&port
->lock
, flags
);
1337 port
->port
.blocked_open
++;
1339 spin_lock_irqsave(&bp
->lock
, flags
);
1340 sx_out(bp
, CD186x_CAR
, port_No(port
));
1341 CD
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
1342 if (sx_crtscts(tty
)) {
1344 port
->MSVR
|= MSVR_DTR
; /* WTF? */
1345 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1348 port
->MSVR
|= MSVR_DTR
;
1349 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1351 spin_unlock_irqrestore(&bp
->lock
, flags
);
1352 set_current_state(TASK_INTERRUPTIBLE
);
1353 if (tty_hung_up_p(filp
) ||
1354 !(port
->port
.flags
& ASYNC_INITIALIZED
)) {
1355 if (port
->port
.flags
& ASYNC_HUP_NOTIFY
)
1358 retval
= -ERESTARTSYS
;
1361 if (!(port
->port
.flags
& ASYNC_CLOSING
) &&
1364 if (signal_pending(current
)) {
1365 retval
= -ERESTARTSYS
;
1373 set_current_state(TASK_RUNNING
);
1374 remove_wait_queue(&port
->port
.open_wait
, &wait
);
1375 spin_lock_irqsave(&port
->lock
, flags
);
1376 if (!tty_hung_up_p(filp
))
1378 port
->port
.blocked_open
--;
1379 spin_unlock_irqrestore(&port
->lock
, flags
);
1385 port
->port
.flags
|= ASYNC_NORMAL_ACTIVE
;
1391 static int sx_open(struct tty_struct
*tty
, struct file
*filp
)
1395 struct specialix_port
*port
;
1396 struct specialix_board
*bp
;
1398 unsigned long flags
;
1402 board
= SX_BOARD(tty
->index
);
1404 if (board
>= SX_NBOARD
|| !(sx_board
[board
].flags
& SX_BOARD_PRESENT
)) {
1409 bp
= &sx_board
[board
];
1410 port
= sx_port
+ board
* SX_NPORT
+ SX_PORT(tty
->index
);
1412 for (i
= 0; i
< 10; i
++)
1415 dprintk(SX_DEBUG_OPEN
,
1416 "Board = %d, bp = %p, port = %p, portno = %d.\n",
1417 board
, bp
, port
, SX_PORT(tty
->index
));
1419 if (sx_paranoia_check(port
, tty
->name
, "sx_open")) {
1424 error
= sx_setup_board(bp
);
1430 spin_lock_irqsave(&bp
->lock
, flags
);
1433 tty
->driver_data
= port
;
1434 port
->port
.tty
= tty
;
1435 spin_unlock_irqrestore(&bp
->lock
, flags
);
1437 error
= sx_setup_port(bp
, port
);
1443 error
= block_til_ready(tty
, filp
, port
);
1453 static void sx_flush_buffer(struct tty_struct
*tty
)
1455 struct specialix_port
*port
= tty
->driver_data
;
1456 unsigned long flags
;
1457 struct specialix_board
*bp
;
1461 if (sx_paranoia_check(port
, tty
->name
, "sx_flush_buffer")) {
1466 bp
= port_Board(port
);
1467 spin_lock_irqsave(&port
->lock
, flags
);
1468 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1469 spin_unlock_irqrestore(&port
->lock
, flags
);
1475 static void sx_close(struct tty_struct
*tty
, struct file
*filp
)
1477 struct specialix_port
*port
= tty
->driver_data
;
1478 struct specialix_board
*bp
;
1479 unsigned long flags
;
1480 unsigned long timeout
;
1483 if (!port
|| sx_paranoia_check(port
, tty
->name
, "close")) {
1487 spin_lock_irqsave(&port
->lock
, flags
);
1489 if (tty_hung_up_p(filp
)) {
1490 spin_unlock_irqrestore(&port
->lock
, flags
);
1495 bp
= port_Board(port
);
1496 if (tty
->count
== 1 && port
->port
.count
!= 1) {
1497 printk(KERN_ERR
"sx%d: sx_close: bad port count;"
1498 " tty->count is 1, port count is %d\n",
1499 board_No(bp
), port
->port
.count
);
1500 port
->port
.count
= 1;
1503 if (port
->port
.count
> 1) {
1507 spin_unlock_irqrestore(&port
->lock
, flags
);
1512 port
->port
.flags
|= ASYNC_CLOSING
;
1514 * Now we wait for the transmit buffer to clear; and we notify
1515 * the line discipline to only process XON/XOFF characters.
1518 spin_unlock_irqrestore(&port
->lock
, flags
);
1519 dprintk(SX_DEBUG_OPEN
, "Closing\n");
1520 if (port
->port
.closing_wait
!= ASYNC_CLOSING_WAIT_NONE
)
1521 tty_wait_until_sent(tty
, port
->port
.closing_wait
);
1523 * At this point we stop accepting input. To do this, we
1524 * disable the receive line status interrupts, and tell the
1525 * interrupt driver to stop checking the data ready bit in the
1526 * line status register.
1528 dprintk(SX_DEBUG_OPEN
, "Closed\n");
1529 port
->IER
&= ~IER_RXD
;
1530 if (port
->port
.flags
& ASYNC_INITIALIZED
) {
1531 port
->IER
&= ~IER_TXRDY
;
1532 port
->IER
|= IER_TXEMPTY
;
1533 spin_lock_irqsave(&bp
->lock
, flags
);
1534 sx_out(bp
, CD186x_CAR
, port_No(port
));
1535 sx_out(bp
, CD186x_IER
, port
->IER
);
1536 spin_unlock_irqrestore(&bp
->lock
, flags
);
1538 * Before we drop DTR, make sure the UART transmitter
1539 * has completely drained; this is especially
1540 * important if there is a transmit FIFO!
1542 timeout
= jiffies
+HZ
;
1543 while (port
->IER
& IER_TXEMPTY
) {
1544 set_current_state(TASK_INTERRUPTIBLE
);
1545 msleep_interruptible(jiffies_to_msecs(port
->timeout
));
1546 if (time_after(jiffies
, timeout
)) {
1547 printk(KERN_INFO
"Timeout waiting for close\n");
1554 if (--bp
->count
< 0) {
1556 "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1557 board_No(bp
), bp
->count
, tty
->index
);
1560 if (--port
->port
.count
< 0) {
1562 "sx%d: sx_close: bad port count for tty%d: %d\n",
1563 board_No(bp
), port_No(port
), port
->port
.count
);
1564 port
->port
.count
= 0;
1567 sx_shutdown_port(bp
, port
);
1568 sx_flush_buffer(tty
);
1569 tty_ldisc_flush(tty
);
1570 spin_lock_irqsave(&port
->lock
, flags
);
1572 port
->port
.tty
= NULL
;
1573 spin_unlock_irqrestore(&port
->lock
, flags
);
1574 if (port
->port
.blocked_open
) {
1575 if (port
->port
.close_delay
)
1576 msleep_interruptible(
1577 jiffies_to_msecs(port
->port
.close_delay
));
1578 wake_up_interruptible(&port
->port
.open_wait
);
1580 port
->port
.flags
&= ~(ASYNC_NORMAL_ACTIVE
|ASYNC_CLOSING
);
1581 wake_up_interruptible(&port
->port
.close_wait
);
1587 static int sx_write(struct tty_struct
*tty
,
1588 const unsigned char *buf
, int count
)
1590 struct specialix_port
*port
= tty
->driver_data
;
1591 struct specialix_board
*bp
;
1593 unsigned long flags
;
1596 if (sx_paranoia_check(port
, tty
->name
, "sx_write")) {
1601 bp
= port_Board(port
);
1603 if (!port
->xmit_buf
) {
1609 spin_lock_irqsave(&port
->lock
, flags
);
1610 c
= min_t(int, count
, min(SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1,
1611 SERIAL_XMIT_SIZE
- port
->xmit_head
));
1613 spin_unlock_irqrestore(&port
->lock
, flags
);
1616 memcpy(port
->xmit_buf
+ port
->xmit_head
, buf
, c
);
1617 port
->xmit_head
= (port
->xmit_head
+ c
) & (SERIAL_XMIT_SIZE
-1);
1618 port
->xmit_cnt
+= c
;
1619 spin_unlock_irqrestore(&port
->lock
, flags
);
1626 spin_lock_irqsave(&bp
->lock
, flags
);
1627 if (port
->xmit_cnt
&& !tty
->stopped
&& !tty
->hw_stopped
&&
1628 !(port
->IER
& IER_TXRDY
)) {
1629 port
->IER
|= IER_TXRDY
;
1630 sx_out(bp
, CD186x_CAR
, port_No(port
));
1631 sx_out(bp
, CD186x_IER
, port
->IER
);
1633 spin_unlock_irqrestore(&bp
->lock
, flags
);
1640 static int sx_put_char(struct tty_struct
*tty
, unsigned char ch
)
1642 struct specialix_port
*port
= tty
->driver_data
;
1643 unsigned long flags
;
1644 struct specialix_board
*bp
;
1648 if (sx_paranoia_check(port
, tty
->name
, "sx_put_char")) {
1652 dprintk(SX_DEBUG_TX
, "check tty: %p %p\n", tty
, port
->xmit_buf
);
1653 if (!port
->xmit_buf
) {
1657 bp
= port_Board(port
);
1658 spin_lock_irqsave(&port
->lock
, flags
);
1660 dprintk(SX_DEBUG_TX
, "xmit_cnt: %d xmit_buf: %p\n",
1661 port
->xmit_cnt
, port
->xmit_buf
);
1662 if (port
->xmit_cnt
>= SERIAL_XMIT_SIZE
- 1 || !port
->xmit_buf
) {
1663 spin_unlock_irqrestore(&port
->lock
, flags
);
1664 dprintk(SX_DEBUG_TX
, "Exit size\n");
1668 dprintk(SX_DEBUG_TX
, "Handle xmit: %p %p\n", port
, port
->xmit_buf
);
1669 port
->xmit_buf
[port
->xmit_head
++] = ch
;
1670 port
->xmit_head
&= SERIAL_XMIT_SIZE
- 1;
1672 spin_unlock_irqrestore(&port
->lock
, flags
);
1679 static void sx_flush_chars(struct tty_struct
*tty
)
1681 struct specialix_port
*port
= tty
->driver_data
;
1682 unsigned long flags
;
1683 struct specialix_board
*bp
= port_Board(port
);
1687 if (sx_paranoia_check(port
, tty
->name
, "sx_flush_chars")) {
1691 if (port
->xmit_cnt
<= 0 || tty
->stopped
|| tty
->hw_stopped
||
1696 spin_lock_irqsave(&bp
->lock
, flags
);
1697 port
->IER
|= IER_TXRDY
;
1698 sx_out(port_Board(port
), CD186x_CAR
, port_No(port
));
1699 sx_out(port_Board(port
), CD186x_IER
, port
->IER
);
1700 spin_unlock_irqrestore(&bp
->lock
, flags
);
1706 static int sx_write_room(struct tty_struct
*tty
)
1708 struct specialix_port
*port
= tty
->driver_data
;
1713 if (sx_paranoia_check(port
, tty
->name
, "sx_write_room")) {
1718 ret
= SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1;
1727 static int sx_chars_in_buffer(struct tty_struct
*tty
)
1729 struct specialix_port
*port
= tty
->driver_data
;
1733 if (sx_paranoia_check(port
, tty
->name
, "sx_chars_in_buffer")) {
1738 return port
->xmit_cnt
;
1741 static int sx_tiocmget(struct tty_struct
*tty
, struct file
*file
)
1743 struct specialix_port
*port
= tty
->driver_data
;
1744 struct specialix_board
*bp
;
1745 unsigned char status
;
1746 unsigned int result
;
1747 unsigned long flags
;
1751 if (sx_paranoia_check(port
, tty
->name
, __func__
)) {
1756 bp
= port_Board(port
);
1757 spin_lock_irqsave(&bp
->lock
, flags
);
1758 sx_out(bp
, CD186x_CAR
, port_No(port
));
1759 status
= sx_in(bp
, CD186x_MSVR
);
1760 spin_unlock_irqrestore(&bp
->lock
, flags
);
1761 dprintk(SX_DEBUG_INIT
, "Got msvr[%d] = %02x, car = %d.\n",
1762 port_No(port
), status
, sx_in(bp
, CD186x_CAR
));
1763 dprintk(SX_DEBUG_INIT
, "sx_port = %p, port = %p\n", sx_port
, port
);
1764 if (sx_crtscts(port
->port
.tty
)) {
1765 result
= TIOCM_DTR
| TIOCM_DSR
1766 | ((status
& MSVR_DTR
) ? TIOCM_RTS
: 0)
1767 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1768 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1770 result
= TIOCM_RTS
| TIOCM_DSR
1771 | ((status
& MSVR_DTR
) ? TIOCM_DTR
: 0)
1772 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1773 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1782 static int sx_tiocmset(struct tty_struct
*tty
, struct file
*file
,
1783 unsigned int set
, unsigned int clear
)
1785 struct specialix_port
*port
= tty
->driver_data
;
1786 unsigned long flags
;
1787 struct specialix_board
*bp
;
1791 if (sx_paranoia_check(port
, tty
->name
, __func__
)) {
1796 bp
= port_Board(port
);
1798 spin_lock_irqsave(&port
->lock
, flags
);
1799 if (sx_crtscts(port
->port
.tty
)) {
1800 if (set
& TIOCM_RTS
)
1801 port
->MSVR
|= MSVR_DTR
;
1803 if (set
& TIOCM_DTR
)
1804 port
->MSVR
|= MSVR_DTR
;
1806 if (sx_crtscts(port
->port
.tty
)) {
1807 if (clear
& TIOCM_RTS
)
1808 port
->MSVR
&= ~MSVR_DTR
;
1810 if (clear
& TIOCM_DTR
)
1811 port
->MSVR
&= ~MSVR_DTR
;
1813 spin_lock(&bp
->lock
);
1814 sx_out(bp
, CD186x_CAR
, port_No(port
));
1815 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1816 spin_unlock(&bp
->lock
);
1817 spin_unlock_irqrestore(&port
->lock
, flags
);
1823 static int sx_send_break(struct tty_struct
*tty
, int length
)
1825 struct specialix_port
*port
= tty
->driver_data
;
1826 struct specialix_board
*bp
= port_Board(port
);
1827 unsigned long flags
;
1830 if (length
== 0 || length
== -1)
1833 spin_lock_irqsave(&port
->lock
, flags
);
1834 port
->break_length
= SPECIALIX_TPS
/ HZ
* length
;
1835 port
->COR2
|= COR2_ETC
;
1836 port
->IER
|= IER_TXRDY
;
1837 spin_lock(&bp
->lock
);
1838 sx_out(bp
, CD186x_CAR
, port_No(port
));
1839 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1840 sx_out(bp
, CD186x_IER
, port
->IER
);
1841 spin_unlock(&bp
->lock
);
1842 spin_unlock_irqrestore(&port
->lock
, flags
);
1844 spin_lock_irqsave(&bp
->lock
, flags
);
1845 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
1846 spin_unlock_irqrestore(&bp
->lock
, flags
);
1854 static int sx_set_serial_info(struct specialix_port
*port
,
1855 struct serial_struct __user
*newinfo
)
1857 struct serial_struct tmp
;
1858 struct specialix_board
*bp
= port_Board(port
);
1863 if (copy_from_user(&tmp
, newinfo
, sizeof(tmp
))) {
1868 mutex_lock(&port
->port
.mutex
);
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
))) {
1879 mutex_unlock(&port
->port
.mutex
);
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
);
1896 mutex_unlock(&port
->port
.mutex
);
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
));
1910 mutex_lock(&port
->port
.mutex
);
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
;
1921 mutex_unlock(&port
->port
.mutex
);
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
);