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
]++;
650 tty_insert_flip_char(tty
, sx_in(bp
, CD186x_RDR
), TTY_NORMAL
);
651 tty_flip_buffer_push(tty
);
656 static void sx_transmit(struct specialix_board
*bp
)
658 struct specialix_port
*port
;
659 struct tty_struct
*tty
;
663 port
= sx_get_port(bp
, "Transmit");
668 dprintk(SX_DEBUG_TX
, "port: %p\n", port
);
669 tty
= port
->port
.tty
;
671 if (port
->IER
& IER_TXEMPTY
) {
673 sx_out(bp
, CD186x_CAR
, port_No(port
));
674 port
->IER
&= ~IER_TXEMPTY
;
675 sx_out(bp
, CD186x_IER
, port
->IER
);
680 if ((port
->xmit_cnt
<= 0 && !port
->break_length
)
681 || tty
->stopped
|| tty
->hw_stopped
) {
682 sx_out(bp
, CD186x_CAR
, port_No(port
));
683 port
->IER
&= ~IER_TXRDY
;
684 sx_out(bp
, CD186x_IER
, port
->IER
);
689 if (port
->break_length
) {
690 if (port
->break_length
> 0) {
691 if (port
->COR2
& COR2_ETC
) {
692 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
693 sx_out(bp
, CD186x_TDR
, CD186x_C_SBRK
);
694 port
->COR2
&= ~COR2_ETC
;
696 count
= min_t(int, port
->break_length
, 0xff);
697 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
698 sx_out(bp
, CD186x_TDR
, CD186x_C_DELAY
);
699 sx_out(bp
, CD186x_TDR
, count
);
700 port
->break_length
-= count
;
701 if (port
->break_length
== 0)
702 port
->break_length
--;
704 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
705 sx_out(bp
, CD186x_TDR
, CD186x_C_EBRK
);
706 sx_out(bp
, CD186x_COR2
, port
->COR2
);
708 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
709 port
->break_length
= 0;
716 count
= CD186x_NFIFO
;
718 sx_out(bp
, CD186x_TDR
, port
->xmit_buf
[port
->xmit_tail
++]);
719 port
->xmit_tail
= port
->xmit_tail
& (SERIAL_XMIT_SIZE
-1);
720 if (--port
->xmit_cnt
<= 0)
722 } while (--count
> 0);
724 if (port
->xmit_cnt
<= 0) {
725 sx_out(bp
, CD186x_CAR
, port_No(port
));
726 port
->IER
&= ~IER_TXRDY
;
727 sx_out(bp
, CD186x_IER
, port
->IER
);
729 if (port
->xmit_cnt
<= port
->wakeup_chars
)
736 static void sx_check_modem(struct specialix_board
*bp
)
738 struct specialix_port
*port
;
739 struct tty_struct
*tty
;
743 dprintk(SX_DEBUG_SIGNALS
, "Modem intr. ");
744 port
= sx_get_port(bp
, "Modem");
748 tty
= port
->port
.tty
;
750 mcr
= sx_in(bp
, CD186x_MCR
);
752 if ((mcr
& MCR_CDCHG
)) {
753 dprintk(SX_DEBUG_SIGNALS
, "CD just changed... ");
754 msvr_cd
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
756 dprintk(SX_DEBUG_SIGNALS
, "Waking up guys in open.\n");
757 wake_up_interruptible(&port
->port
.open_wait
);
759 dprintk(SX_DEBUG_SIGNALS
, "Sending HUP.\n");
764 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
765 if (mcr
& MCR_CTSCHG
) {
766 if (sx_in(bp
, CD186x_MSVR
) & MSVR_CTS
) {
768 port
->IER
|= IER_TXRDY
;
769 if (port
->xmit_cnt
<= port
->wakeup_chars
)
773 port
->IER
&= ~IER_TXRDY
;
775 sx_out(bp
, CD186x_IER
, port
->IER
);
777 if (mcr
& MCR_DSSXHG
) {
778 if (sx_in(bp
, CD186x_MSVR
) & MSVR_DSR
) {
780 port
->IER
|= IER_TXRDY
;
781 if (port
->xmit_cnt
<= port
->wakeup_chars
)
785 port
->IER
&= ~IER_TXRDY
;
787 sx_out(bp
, CD186x_IER
, port
->IER
);
789 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
791 /* Clear change bits */
792 sx_out(bp
, CD186x_MCR
, 0);
796 /* The main interrupt processing routine */
797 static irqreturn_t
sx_interrupt(int dummy
, void *dev_id
)
799 unsigned char status
;
801 struct specialix_board
*bp
= dev_id
;
802 unsigned long loop
= 0;
808 spin_lock_irqsave(&bp
->lock
, flags
);
810 dprintk(SX_DEBUG_FLOW
, "enter %s port %d room: %ld\n", __func__
,
811 port_No(sx_get_port(bp
, "INT")),
812 SERIAL_XMIT_SIZE
- sx_get_port(bp
, "ITN")->xmit_cnt
- 1);
813 if (!(bp
->flags
& SX_BOARD_ACTIVE
)) {
814 dprintk(SX_DEBUG_IRQ
, "sx: False interrupt. irq %d.\n",
816 spin_unlock_irqrestore(&bp
->lock
, flags
);
823 while (++loop
< 16) {
824 status
= sx_in(bp
, CD186x_SRSR
) &
825 (SRSR_RREQint
| SRSR_TREQint
| SRSR_MREQint
);
828 if (status
& SRSR_RREQint
) {
829 ack
= sx_in(bp
, CD186x_RRAR
);
831 if (ack
== (SX_ID
| GIVR_IT_RCV
))
833 else if (ack
== (SX_ID
| GIVR_IT_REXC
))
837 "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
838 board_No(bp
), status
, ack
);
840 } else if (status
& SRSR_TREQint
) {
841 ack
= sx_in(bp
, CD186x_TRAR
);
843 if (ack
== (SX_ID
| GIVR_IT_TX
))
846 printk(KERN_ERR
"sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
847 board_No(bp
), status
, ack
,
848 port_No(sx_get_port(bp
, "Int")));
849 } else if (status
& SRSR_MREQint
) {
850 ack
= sx_in(bp
, CD186x_MRAR
);
852 if (ack
== (SX_ID
| GIVR_IT_MODEM
))
856 "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
857 board_No(bp
), status
, ack
);
861 sx_out(bp
, CD186x_EOIR
, 0); /* Mark end of interrupt */
864 outb(bp
->reg
, bp
->base
+ SX_ADDR_REG
);
865 spin_unlock_irqrestore(&bp
->lock
, flags
);
872 * Routines for open & close processing.
875 static void turn_ints_off(struct specialix_board
*bp
)
880 spin_lock_irqsave(&bp
->lock
, flags
);
881 (void) sx_in_off(bp
, 0); /* Turn off interrupts. */
882 spin_unlock_irqrestore(&bp
->lock
, flags
);
887 static void turn_ints_on(struct specialix_board
*bp
)
893 spin_lock_irqsave(&bp
->lock
, flags
);
894 (void) sx_in(bp
, 0); /* Turn ON interrupts. */
895 spin_unlock_irqrestore(&bp
->lock
, flags
);
901 /* Called with disabled interrupts */
902 static int sx_setup_board(struct specialix_board
*bp
)
906 if (bp
->flags
& SX_BOARD_ACTIVE
)
909 if (bp
->flags
& SX_BOARD_IS_PCI
)
910 error
= request_irq(bp
->irq
, sx_interrupt
,
911 IRQF_DISABLED
| IRQF_SHARED
, "specialix IO8+", bp
);
913 error
= request_irq(bp
->irq
, sx_interrupt
,
914 IRQF_DISABLED
, "specialix IO8+", bp
);
920 bp
->flags
|= SX_BOARD_ACTIVE
;
926 /* Called with disabled interrupts */
927 static void sx_shutdown_board(struct specialix_board
*bp
)
931 if (!(bp
->flags
& SX_BOARD_ACTIVE
)) {
936 bp
->flags
&= ~SX_BOARD_ACTIVE
;
938 dprintk(SX_DEBUG_IRQ
, "Freeing IRQ%d for board %d.\n",
939 bp
->irq
, board_No(bp
));
940 free_irq(bp
->irq
, bp
);
945 static unsigned int sx_crtscts(struct tty_struct
*tty
)
948 return C_CRTSCTS(tty
);
953 * Setting up port characteristics.
954 * Must be called with disabled interrupts
956 static void sx_change_speed(struct specialix_board
*bp
,
957 struct specialix_port
*port
)
959 struct tty_struct
*tty
;
962 unsigned char cor1
= 0, cor3
= 0;
963 unsigned char mcor1
= 0, mcor2
= 0;
964 static unsigned long again
;
969 tty
= port
->port
.tty
;
970 if (!tty
|| !tty
->termios
) {
977 /* Select port on the board */
978 spin_lock_irqsave(&bp
->lock
, flags
);
979 sx_out(bp
, CD186x_CAR
, port_No(port
));
981 /* The Specialix board doens't implement the RTS lines.
982 They are used to set the IRQ level. Don't touch them. */
984 port
->MSVR
= MSVR_DTR
| (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
986 port
->MSVR
= (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
987 spin_unlock_irqrestore(&bp
->lock
, flags
);
988 dprintk(SX_DEBUG_TERMIOS
, "sx: got MSVR=%02x.\n", port
->MSVR
);
989 baud
= tty_get_baud_rate(tty
);
992 if ((port
->port
.flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_HI
)
994 if ((port
->port
.flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_VHI
)
999 /* Drop DTR & exit */
1000 dprintk(SX_DEBUG_TERMIOS
, "Dropping DTR... Hmm....\n");
1001 if (!sx_crtscts(tty
)) {
1002 port
->MSVR
&= ~MSVR_DTR
;
1003 spin_lock_irqsave(&bp
->lock
, flags
);
1004 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1005 spin_unlock_irqrestore(&bp
->lock
, flags
);
1007 dprintk(SX_DEBUG_TERMIOS
, "Can't drop DTR: no DTR.\n");
1011 if (!sx_crtscts(tty
))
1012 port
->MSVR
|= MSVR_DTR
;
1016 * Now we must calculate some speed depended things
1019 /* Set baud rate for port */
1020 tmp
= port
->custom_divisor
;
1023 "sx%d: Using custom baud rate divisor %ld. \n"
1024 "This is an untested option, please be careful.\n",
1025 port_No(port
), tmp
);
1027 tmp
= (((SX_OSCFREQ
+ baud
/2) / baud
+ CD186x_TPC
/2) /
1030 if (tmp
< 0x10 && time_before(again
, jiffies
)) {
1031 again
= jiffies
+ HZ
* 60;
1032 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1034 printk(KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1035 "Performance degradation is possible.\n"
1036 "Read specialix.txt for more info.\n",
1037 port_No(port
), tmp
);
1039 printk(KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1040 "Warning: overstressing Cirrus chip. This might not work.\n"
1041 "Read specialix.txt for more info.\n", port_No(port
), tmp
);
1044 spin_lock_irqsave(&bp
->lock
, flags
);
1045 sx_out(bp
, CD186x_RBPRH
, (tmp
>> 8) & 0xff);
1046 sx_out(bp
, CD186x_TBPRH
, (tmp
>> 8) & 0xff);
1047 sx_out(bp
, CD186x_RBPRL
, tmp
& 0xff);
1048 sx_out(bp
, CD186x_TBPRL
, tmp
& 0xff);
1049 spin_unlock_irqrestore(&bp
->lock
, flags
);
1050 if (port
->custom_divisor
)
1051 baud
= (SX_OSCFREQ
+ port
->custom_divisor
/2) /
1052 port
->custom_divisor
;
1053 baud
= (baud
+ 5) / 10; /* Estimated CPS */
1055 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1056 tmp
= ((baud
+ HZ
/2) / HZ
) * 2 - CD186x_NFIFO
;
1057 port
->wakeup_chars
= (tmp
< 0) ? 0 : ((tmp
>= SERIAL_XMIT_SIZE
) ?
1058 SERIAL_XMIT_SIZE
- 1 : tmp
);
1060 /* Receiver timeout will be transmission time for 1.5 chars */
1061 tmp
= (SPECIALIX_TPS
+ SPECIALIX_TPS
/2 + baud
/2) / baud
;
1062 tmp
= (tmp
> 0xff) ? 0xff : tmp
;
1063 spin_lock_irqsave(&bp
->lock
, flags
);
1064 sx_out(bp
, CD186x_RTPR
, tmp
);
1065 spin_unlock_irqrestore(&bp
->lock
, flags
);
1066 switch (C_CSIZE(tty
)) {
1084 cor1
|= COR1_IGNORE
;
1085 if (C_PARENB(tty
)) {
1086 cor1
|= COR1_NORMPAR
;
1090 cor1
&= ~COR1_IGNORE
;
1092 /* Set marking of some errors */
1093 port
->mark_mask
= RCSR_OE
| RCSR_TOUT
;
1095 port
->mark_mask
|= RCSR_FE
| RCSR_PE
;
1096 if (I_BRKINT(tty
) || I_PARMRK(tty
))
1097 port
->mark_mask
|= RCSR_BREAK
;
1099 port
->mark_mask
&= ~(RCSR_FE
| RCSR_PE
);
1100 if (I_IGNBRK(tty
)) {
1101 port
->mark_mask
&= ~RCSR_BREAK
;
1103 /* Real raw mode. Ignore all */
1104 port
->mark_mask
&= ~RCSR_OE
;
1106 /* Enable Hardware Flow Control */
1107 if (C_CRTSCTS(tty
)) {
1108 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1109 port
->IER
|= IER_DSR
| IER_CTS
;
1110 mcor1
|= MCOR1_DSRZD
| MCOR1_CTSZD
;
1111 mcor2
|= MCOR2_DSROD
| MCOR2_CTSOD
;
1112 spin_lock_irqsave(&bp
->lock
, flags
);
1113 tty
->hw_stopped
= !(sx_in(bp
, CD186x_MSVR
) &
1114 (MSVR_CTS
|MSVR_DSR
));
1115 spin_unlock_irqrestore(&bp
->lock
, flags
);
1117 port
->COR2
|= COR2_CTSAE
;
1120 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1121 /* Some people reported that it works, but I still doubt it */
1123 port
->COR2
|= COR2_TXIBE
;
1124 cor3
|= (COR3_FCT
| COR3_SCDE
);
1126 port
->COR2
|= COR2_IXM
;
1127 spin_lock_irqsave(&bp
->lock
, flags
);
1128 sx_out(bp
, CD186x_SCHR1
, START_CHAR(tty
));
1129 sx_out(bp
, CD186x_SCHR2
, STOP_CHAR(tty
));
1130 sx_out(bp
, CD186x_SCHR3
, START_CHAR(tty
));
1131 sx_out(bp
, CD186x_SCHR4
, STOP_CHAR(tty
));
1132 spin_unlock_irqrestore(&bp
->lock
, flags
);
1134 if (!C_CLOCAL(tty
)) {
1135 /* Enable CD check */
1136 port
->IER
|= IER_CD
;
1137 mcor1
|= MCOR1_CDZD
;
1138 mcor2
|= MCOR2_CDOD
;
1142 /* Enable receiver */
1143 port
->IER
|= IER_RXD
;
1145 /* Set input FIFO size (1-8 bytes) */
1147 /* Setting up CD186x channel registers */
1148 spin_lock_irqsave(&bp
->lock
, flags
);
1149 sx_out(bp
, CD186x_COR1
, cor1
);
1150 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1151 sx_out(bp
, CD186x_COR3
, cor3
);
1152 spin_unlock_irqrestore(&bp
->lock
, flags
);
1153 /* Make CD186x know about registers change */
1155 spin_lock_irqsave(&bp
->lock
, flags
);
1156 sx_out(bp
, CD186x_CCR
, CCR_CORCHG1
| CCR_CORCHG2
| CCR_CORCHG3
);
1157 /* Setting up modem option registers */
1158 dprintk(SX_DEBUG_TERMIOS
, "Mcor1 = %02x, mcor2 = %02x.\n",
1160 sx_out(bp
, CD186x_MCOR1
, mcor1
);
1161 sx_out(bp
, CD186x_MCOR2
, mcor2
);
1162 spin_unlock_irqrestore(&bp
->lock
, flags
);
1163 /* Enable CD186x transmitter & receiver */
1165 spin_lock_irqsave(&bp
->lock
, flags
);
1166 sx_out(bp
, CD186x_CCR
, CCR_TXEN
| CCR_RXEN
);
1167 /* Enable interrupts */
1168 sx_out(bp
, CD186x_IER
, port
->IER
);
1169 /* And finally set the modem lines... */
1170 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1171 spin_unlock_irqrestore(&bp
->lock
, flags
);
1177 /* Must be called with interrupts enabled */
1178 static int sx_setup_port(struct specialix_board
*bp
,
1179 struct specialix_port
*port
)
1181 unsigned long flags
;
1185 if (port
->port
.flags
& ASYNC_INITIALIZED
) {
1190 if (!port
->xmit_buf
) {
1191 /* We may sleep in get_zeroed_page() */
1194 tmp
= get_zeroed_page(GFP_KERNEL
);
1200 if (port
->xmit_buf
) {
1203 return -ERESTARTSYS
;
1205 port
->xmit_buf
= (unsigned char *) tmp
;
1208 spin_lock_irqsave(&port
->lock
, flags
);
1211 clear_bit(TTY_IO_ERROR
, &port
->port
.tty
->flags
);
1213 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1214 sx_change_speed(bp
, port
);
1215 port
->port
.flags
|= ASYNC_INITIALIZED
;
1217 spin_unlock_irqrestore(&port
->lock
, flags
);
1225 /* Must be called with interrupts disabled */
1226 static void sx_shutdown_port(struct specialix_board
*bp
,
1227 struct specialix_port
*port
)
1229 struct tty_struct
*tty
;
1231 unsigned long flags
;
1235 if (!(port
->port
.flags
& ASYNC_INITIALIZED
)) {
1240 if (sx_debug
& SX_DEBUG_FIFO
) {
1241 dprintk(SX_DEBUG_FIFO
,
1242 "sx%d: port %d: %ld overruns, FIFO hits [ ",
1243 board_No(bp
), port_No(port
), port
->overrun
);
1244 for (i
= 0; i
< 10; i
++)
1245 dprintk(SX_DEBUG_FIFO
, "%ld ", port
->hits
[i
]);
1246 dprintk(SX_DEBUG_FIFO
, "].\n");
1249 if (port
->xmit_buf
) {
1250 free_page((unsigned long) port
->xmit_buf
);
1251 port
->xmit_buf
= NULL
;
1255 spin_lock_irqsave(&bp
->lock
, flags
);
1256 sx_out(bp
, CD186x_CAR
, port_No(port
));
1258 tty
= port
->port
.tty
;
1259 if (tty
== NULL
|| C_HUPCL(tty
)) {
1261 sx_out(bp
, CD186x_MSVDTR
, 0);
1263 spin_unlock_irqrestore(&bp
->lock
, flags
);
1266 spin_lock_irqsave(&bp
->lock
, flags
);
1267 sx_out(bp
, CD186x_CCR
, CCR_SOFTRESET
);
1268 /* Disable all interrupts from this port */
1270 sx_out(bp
, CD186x_IER
, port
->IER
);
1271 spin_unlock_irqrestore(&bp
->lock
, flags
);
1273 set_bit(TTY_IO_ERROR
, &tty
->flags
);
1274 port
->port
.flags
&= ~ASYNC_INITIALIZED
;
1277 sx_shutdown_board(bp
);
1282 static int block_til_ready(struct tty_struct
*tty
, struct file
*filp
,
1283 struct specialix_port
*port
)
1285 DECLARE_WAITQUEUE(wait
, current
);
1286 struct specialix_board
*bp
= port_Board(port
);
1290 unsigned long flags
;
1295 * If the device is in the middle of being closed, then block
1296 * until it's done, and then try again.
1298 if (tty_hung_up_p(filp
) || port
->port
.flags
& ASYNC_CLOSING
) {
1299 interruptible_sleep_on(&port
->port
.close_wait
);
1300 if (port
->port
.flags
& ASYNC_HUP_NOTIFY
) {
1305 return -ERESTARTSYS
;
1310 * If non-blocking mode is set, or the port is not enabled,
1311 * then make the check up front and then exit.
1313 if ((filp
->f_flags
& O_NONBLOCK
) ||
1314 (tty
->flags
& (1 << TTY_IO_ERROR
))) {
1315 port
->port
.flags
|= ASYNC_NORMAL_ACTIVE
;
1324 * Block waiting for the carrier detect and the line to become
1325 * free (i.e., not in use by the callout). While we are in
1326 * this loop, info->count is dropped by one, so that
1327 * rs_close() knows when to free things. We restore it upon
1328 * exit, either normal or abnormal.
1331 add_wait_queue(&port
->port
.open_wait
, &wait
);
1332 spin_lock_irqsave(&port
->lock
, flags
);
1333 if (!tty_hung_up_p(filp
))
1335 spin_unlock_irqrestore(&port
->lock
, flags
);
1336 port
->port
.blocked_open
++;
1338 spin_lock_irqsave(&bp
->lock
, flags
);
1339 sx_out(bp
, CD186x_CAR
, port_No(port
));
1340 CD
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
1341 if (sx_crtscts(tty
)) {
1343 port
->MSVR
|= MSVR_DTR
; /* WTF? */
1344 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1347 port
->MSVR
|= MSVR_DTR
;
1348 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1350 spin_unlock_irqrestore(&bp
->lock
, flags
);
1351 set_current_state(TASK_INTERRUPTIBLE
);
1352 if (tty_hung_up_p(filp
) ||
1353 !(port
->port
.flags
& ASYNC_INITIALIZED
)) {
1354 if (port
->port
.flags
& ASYNC_HUP_NOTIFY
)
1357 retval
= -ERESTARTSYS
;
1360 if (!(port
->port
.flags
& ASYNC_CLOSING
) &&
1363 if (signal_pending(current
)) {
1364 retval
= -ERESTARTSYS
;
1370 set_current_state(TASK_RUNNING
);
1371 remove_wait_queue(&port
->port
.open_wait
, &wait
);
1372 spin_lock_irqsave(&port
->lock
, flags
);
1373 if (!tty_hung_up_p(filp
))
1375 port
->port
.blocked_open
--;
1376 spin_unlock_irqrestore(&port
->lock
, flags
);
1382 port
->port
.flags
|= ASYNC_NORMAL_ACTIVE
;
1388 static int sx_open(struct tty_struct
*tty
, struct file
*filp
)
1392 struct specialix_port
*port
;
1393 struct specialix_board
*bp
;
1395 unsigned long flags
;
1399 board
= SX_BOARD(tty
->index
);
1401 if (board
>= SX_NBOARD
|| !(sx_board
[board
].flags
& SX_BOARD_PRESENT
)) {
1406 bp
= &sx_board
[board
];
1407 port
= sx_port
+ board
* SX_NPORT
+ SX_PORT(tty
->index
);
1409 for (i
= 0; i
< 10; i
++)
1412 dprintk(SX_DEBUG_OPEN
,
1413 "Board = %d, bp = %p, port = %p, portno = %d.\n",
1414 board
, bp
, port
, SX_PORT(tty
->index
));
1416 if (sx_paranoia_check(port
, tty
->name
, "sx_open")) {
1421 error
= sx_setup_board(bp
);
1427 spin_lock_irqsave(&bp
->lock
, flags
);
1430 tty
->driver_data
= port
;
1431 port
->port
.tty
= tty
;
1432 spin_unlock_irqrestore(&bp
->lock
, flags
);
1434 error
= sx_setup_port(bp
, port
);
1440 error
= block_til_ready(tty
, filp
, port
);
1450 static void sx_flush_buffer(struct tty_struct
*tty
)
1452 struct specialix_port
*port
= tty
->driver_data
;
1453 unsigned long flags
;
1454 struct specialix_board
*bp
;
1458 if (sx_paranoia_check(port
, tty
->name
, "sx_flush_buffer")) {
1463 bp
= port_Board(port
);
1464 spin_lock_irqsave(&port
->lock
, flags
);
1465 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1466 spin_unlock_irqrestore(&port
->lock
, flags
);
1472 static void sx_close(struct tty_struct
*tty
, struct file
*filp
)
1474 struct specialix_port
*port
= tty
->driver_data
;
1475 struct specialix_board
*bp
;
1476 unsigned long flags
;
1477 unsigned long timeout
;
1480 if (!port
|| sx_paranoia_check(port
, tty
->name
, "close")) {
1484 spin_lock_irqsave(&port
->lock
, flags
);
1486 if (tty_hung_up_p(filp
)) {
1487 spin_unlock_irqrestore(&port
->lock
, flags
);
1492 bp
= port_Board(port
);
1493 if (tty
->count
== 1 && port
->port
.count
!= 1) {
1494 printk(KERN_ERR
"sx%d: sx_close: bad port count;"
1495 " tty->count is 1, port count is %d\n",
1496 board_No(bp
), port
->port
.count
);
1497 port
->port
.count
= 1;
1500 if (port
->port
.count
> 1) {
1504 spin_unlock_irqrestore(&port
->lock
, flags
);
1509 port
->port
.flags
|= ASYNC_CLOSING
;
1511 * Now we wait for the transmit buffer to clear; and we notify
1512 * the line discipline to only process XON/XOFF characters.
1515 spin_unlock_irqrestore(&port
->lock
, flags
);
1516 dprintk(SX_DEBUG_OPEN
, "Closing\n");
1517 if (port
->port
.closing_wait
!= ASYNC_CLOSING_WAIT_NONE
)
1518 tty_wait_until_sent(tty
, port
->port
.closing_wait
);
1520 * At this point we stop accepting input. To do this, we
1521 * disable the receive line status interrupts, and tell the
1522 * interrupt driver to stop checking the data ready bit in the
1523 * line status register.
1525 dprintk(SX_DEBUG_OPEN
, "Closed\n");
1526 port
->IER
&= ~IER_RXD
;
1527 if (port
->port
.flags
& ASYNC_INITIALIZED
) {
1528 port
->IER
&= ~IER_TXRDY
;
1529 port
->IER
|= IER_TXEMPTY
;
1530 spin_lock_irqsave(&bp
->lock
, flags
);
1531 sx_out(bp
, CD186x_CAR
, port_No(port
));
1532 sx_out(bp
, CD186x_IER
, port
->IER
);
1533 spin_unlock_irqrestore(&bp
->lock
, flags
);
1535 * Before we drop DTR, make sure the UART transmitter
1536 * has completely drained; this is especially
1537 * important if there is a transmit FIFO!
1539 timeout
= jiffies
+HZ
;
1540 while (port
->IER
& IER_TXEMPTY
) {
1541 set_current_state(TASK_INTERRUPTIBLE
);
1542 msleep_interruptible(jiffies_to_msecs(port
->timeout
));
1543 if (time_after(jiffies
, timeout
)) {
1544 printk(KERN_INFO
"Timeout waiting for close\n");
1551 if (--bp
->count
< 0) {
1553 "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1554 board_No(bp
), bp
->count
, tty
->index
);
1557 if (--port
->port
.count
< 0) {
1559 "sx%d: sx_close: bad port count for tty%d: %d\n",
1560 board_No(bp
), port_No(port
), port
->port
.count
);
1561 port
->port
.count
= 0;
1564 sx_shutdown_port(bp
, port
);
1565 sx_flush_buffer(tty
);
1566 tty_ldisc_flush(tty
);
1567 spin_lock_irqsave(&port
->lock
, flags
);
1569 port
->port
.tty
= NULL
;
1570 spin_unlock_irqrestore(&port
->lock
, flags
);
1571 if (port
->port
.blocked_open
) {
1572 if (port
->port
.close_delay
)
1573 msleep_interruptible(
1574 jiffies_to_msecs(port
->port
.close_delay
));
1575 wake_up_interruptible(&port
->port
.open_wait
);
1577 port
->port
.flags
&= ~(ASYNC_NORMAL_ACTIVE
|ASYNC_CLOSING
);
1578 wake_up_interruptible(&port
->port
.close_wait
);
1584 static int sx_write(struct tty_struct
*tty
,
1585 const unsigned char *buf
, int count
)
1587 struct specialix_port
*port
= tty
->driver_data
;
1588 struct specialix_board
*bp
;
1590 unsigned long flags
;
1593 if (sx_paranoia_check(port
, tty
->name
, "sx_write")) {
1598 bp
= port_Board(port
);
1600 if (!port
->xmit_buf
) {
1606 spin_lock_irqsave(&port
->lock
, flags
);
1607 c
= min_t(int, count
, min(SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1,
1608 SERIAL_XMIT_SIZE
- port
->xmit_head
));
1610 spin_unlock_irqrestore(&port
->lock
, flags
);
1613 memcpy(port
->xmit_buf
+ port
->xmit_head
, buf
, c
);
1614 port
->xmit_head
= (port
->xmit_head
+ c
) & (SERIAL_XMIT_SIZE
-1);
1615 port
->xmit_cnt
+= c
;
1616 spin_unlock_irqrestore(&port
->lock
, flags
);
1623 spin_lock_irqsave(&bp
->lock
, flags
);
1624 if (port
->xmit_cnt
&& !tty
->stopped
&& !tty
->hw_stopped
&&
1625 !(port
->IER
& IER_TXRDY
)) {
1626 port
->IER
|= IER_TXRDY
;
1627 sx_out(bp
, CD186x_CAR
, port_No(port
));
1628 sx_out(bp
, CD186x_IER
, port
->IER
);
1630 spin_unlock_irqrestore(&bp
->lock
, flags
);
1637 static int sx_put_char(struct tty_struct
*tty
, unsigned char ch
)
1639 struct specialix_port
*port
= tty
->driver_data
;
1640 unsigned long flags
;
1641 struct specialix_board
*bp
;
1645 if (sx_paranoia_check(port
, tty
->name
, "sx_put_char")) {
1649 dprintk(SX_DEBUG_TX
, "check tty: %p %p\n", tty
, port
->xmit_buf
);
1650 if (!port
->xmit_buf
) {
1654 bp
= port_Board(port
);
1655 spin_lock_irqsave(&port
->lock
, flags
);
1657 dprintk(SX_DEBUG_TX
, "xmit_cnt: %d xmit_buf: %p\n",
1658 port
->xmit_cnt
, port
->xmit_buf
);
1659 if (port
->xmit_cnt
>= SERIAL_XMIT_SIZE
- 1 || !port
->xmit_buf
) {
1660 spin_unlock_irqrestore(&port
->lock
, flags
);
1661 dprintk(SX_DEBUG_TX
, "Exit size\n");
1665 dprintk(SX_DEBUG_TX
, "Handle xmit: %p %p\n", port
, port
->xmit_buf
);
1666 port
->xmit_buf
[port
->xmit_head
++] = ch
;
1667 port
->xmit_head
&= SERIAL_XMIT_SIZE
- 1;
1669 spin_unlock_irqrestore(&port
->lock
, flags
);
1676 static void sx_flush_chars(struct tty_struct
*tty
)
1678 struct specialix_port
*port
= tty
->driver_data
;
1679 unsigned long flags
;
1680 struct specialix_board
*bp
= port_Board(port
);
1684 if (sx_paranoia_check(port
, tty
->name
, "sx_flush_chars")) {
1688 if (port
->xmit_cnt
<= 0 || tty
->stopped
|| tty
->hw_stopped
||
1693 spin_lock_irqsave(&bp
->lock
, flags
);
1694 port
->IER
|= IER_TXRDY
;
1695 sx_out(port_Board(port
), CD186x_CAR
, port_No(port
));
1696 sx_out(port_Board(port
), CD186x_IER
, port
->IER
);
1697 spin_unlock_irqrestore(&bp
->lock
, flags
);
1703 static int sx_write_room(struct tty_struct
*tty
)
1705 struct specialix_port
*port
= tty
->driver_data
;
1710 if (sx_paranoia_check(port
, tty
->name
, "sx_write_room")) {
1715 ret
= SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1;
1724 static int sx_chars_in_buffer(struct tty_struct
*tty
)
1726 struct specialix_port
*port
= tty
->driver_data
;
1730 if (sx_paranoia_check(port
, tty
->name
, "sx_chars_in_buffer")) {
1735 return port
->xmit_cnt
;
1738 static int sx_tiocmget(struct tty_struct
*tty
, struct file
*file
)
1740 struct specialix_port
*port
= tty
->driver_data
;
1741 struct specialix_board
*bp
;
1742 unsigned char status
;
1743 unsigned int result
;
1744 unsigned long flags
;
1748 if (sx_paranoia_check(port
, tty
->name
, __func__
)) {
1753 bp
= port_Board(port
);
1754 spin_lock_irqsave(&bp
->lock
, flags
);
1755 sx_out(bp
, CD186x_CAR
, port_No(port
));
1756 status
= sx_in(bp
, CD186x_MSVR
);
1757 spin_unlock_irqrestore(&bp
->lock
, flags
);
1758 dprintk(SX_DEBUG_INIT
, "Got msvr[%d] = %02x, car = %d.\n",
1759 port_No(port
), status
, sx_in(bp
, CD186x_CAR
));
1760 dprintk(SX_DEBUG_INIT
, "sx_port = %p, port = %p\n", sx_port
, port
);
1761 if (sx_crtscts(port
->port
.tty
)) {
1762 result
= TIOCM_DTR
| TIOCM_DSR
1763 | ((status
& MSVR_DTR
) ? TIOCM_RTS
: 0)
1764 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1765 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1767 result
= TIOCM_RTS
| TIOCM_DSR
1768 | ((status
& MSVR_DTR
) ? TIOCM_DTR
: 0)
1769 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1770 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1779 static int sx_tiocmset(struct tty_struct
*tty
, struct file
*file
,
1780 unsigned int set
, unsigned int clear
)
1782 struct specialix_port
*port
= tty
->driver_data
;
1783 unsigned long flags
;
1784 struct specialix_board
*bp
;
1788 if (sx_paranoia_check(port
, tty
->name
, __func__
)) {
1793 bp
= port_Board(port
);
1795 spin_lock_irqsave(&port
->lock
, flags
);
1796 if (sx_crtscts(port
->port
.tty
)) {
1797 if (set
& TIOCM_RTS
)
1798 port
->MSVR
|= MSVR_DTR
;
1800 if (set
& TIOCM_DTR
)
1801 port
->MSVR
|= MSVR_DTR
;
1803 if (sx_crtscts(port
->port
.tty
)) {
1804 if (clear
& TIOCM_RTS
)
1805 port
->MSVR
&= ~MSVR_DTR
;
1807 if (clear
& TIOCM_DTR
)
1808 port
->MSVR
&= ~MSVR_DTR
;
1810 spin_lock(&bp
->lock
);
1811 sx_out(bp
, CD186x_CAR
, port_No(port
));
1812 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1813 spin_unlock(&bp
->lock
);
1814 spin_unlock_irqrestore(&port
->lock
, flags
);
1820 static int sx_send_break(struct tty_struct
*tty
, int length
)
1822 struct specialix_port
*port
= tty
->driver_data
;
1823 struct specialix_board
*bp
= port_Board(port
);
1824 unsigned long flags
;
1827 if (length
== 0 || length
== -1)
1830 spin_lock_irqsave(&port
->lock
, flags
);
1831 port
->break_length
= SPECIALIX_TPS
/ HZ
* length
;
1832 port
->COR2
|= COR2_ETC
;
1833 port
->IER
|= IER_TXRDY
;
1834 spin_lock(&bp
->lock
);
1835 sx_out(bp
, CD186x_CAR
, port_No(port
));
1836 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1837 sx_out(bp
, CD186x_IER
, port
->IER
);
1838 spin_unlock(&bp
->lock
);
1839 spin_unlock_irqrestore(&port
->lock
, flags
);
1841 spin_lock_irqsave(&bp
->lock
, flags
);
1842 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
1843 spin_unlock_irqrestore(&bp
->lock
, flags
);
1851 static int sx_set_serial_info(struct specialix_port
*port
,
1852 struct serial_struct __user
*newinfo
)
1854 struct serial_struct tmp
;
1855 struct specialix_board
*bp
= port_Board(port
);
1860 if (copy_from_user(&tmp
, newinfo
, sizeof(tmp
))) {
1867 change_speed
= ((port
->port
.flags
& ASYNC_SPD_MASK
) !=
1868 (tmp
.flags
& ASYNC_SPD_MASK
));
1869 change_speed
|= (tmp
.custom_divisor
!= port
->custom_divisor
);
1871 if (!capable(CAP_SYS_ADMIN
)) {
1872 if ((tmp
.close_delay
!= port
->port
.close_delay
) ||
1873 (tmp
.closing_wait
!= port
->port
.closing_wait
) ||
1874 ((tmp
.flags
& ~ASYNC_USR_MASK
) !=
1875 (port
->port
.flags
& ~ASYNC_USR_MASK
))) {
1880 port
->port
.flags
= ((port
->port
.flags
& ~ASYNC_USR_MASK
) |
1881 (tmp
.flags
& ASYNC_USR_MASK
));
1882 port
->custom_divisor
= tmp
.custom_divisor
;
1884 port
->port
.flags
= ((port
->port
.flags
& ~ASYNC_FLAGS
) |
1885 (tmp
.flags
& ASYNC_FLAGS
));
1886 port
->port
.close_delay
= tmp
.close_delay
;
1887 port
->port
.closing_wait
= tmp
.closing_wait
;
1888 port
->custom_divisor
= tmp
.custom_divisor
;
1891 sx_change_speed(bp
, port
);
1899 static int sx_get_serial_info(struct specialix_port
*port
,
1900 struct serial_struct __user
*retinfo
)
1902 struct serial_struct tmp
;
1903 struct specialix_board
*bp
= port_Board(port
);
1907 memset(&tmp
, 0, sizeof(tmp
));
1909 tmp
.type
= PORT_CIRRUS
;
1910 tmp
.line
= port
- sx_port
;
1911 tmp
.port
= bp
->base
;
1913 tmp
.flags
= port
->port
.flags
;
1914 tmp
.baud_base
= (SX_OSCFREQ
+ CD186x_TPC
/2) / CD186x_TPC
;
1915 tmp
.close_delay
= port
->port
.close_delay
* HZ
/100;
1916 tmp
.closing_wait
= port
->port
.closing_wait
* HZ
/100;
1917 tmp
.custom_divisor
= port
->custom_divisor
;
1918 tmp
.xmit_fifo_size
= CD186x_NFIFO
;
1920 if (copy_to_user(retinfo
, &tmp
, sizeof(tmp
))) {
1930 static int sx_ioctl(struct tty_struct
*tty
, struct file
*filp
,
1931 unsigned int cmd
, unsigned long arg
)
1933 struct specialix_port
*port
= tty
->driver_data
;
1934 void __user
*argp
= (void __user
*)arg
;
1938 if (sx_paranoia_check(port
, tty
->name
, "sx_ioctl")) {
1946 return sx_get_serial_info(port
, argp
);
1949 return sx_set_serial_info(port
, argp
);
1952 return -ENOIOCTLCMD
;
1959 static void sx_throttle(struct tty_struct
*tty
)
1961 struct specialix_port
*port
= tty
->driver_data
;
1962 struct specialix_board
*bp
;
1963 unsigned long flags
;
1967 if (sx_paranoia_check(port
, tty
->name
, "sx_throttle")) {
1972 bp
= port_Board(port
);
1974 /* Use DTR instead of RTS ! */
1975 if (sx_crtscts(tty
))
1976 port
->MSVR
&= ~MSVR_DTR
;
1978 /* Auch!!! I think the system shouldn't call this then. */
1979 /* Or maybe we're supposed (allowed?) to do our side of hw
1980 handshake anyway, even when hardware handshake is off.
1981 When you see this in your logs, please report.... */
1983 "sx%d: Need to throttle, but can't (hardware hs is off)\n",
1986 spin_lock_irqsave(&bp
->lock
, flags
);
1987 sx_out(bp
, CD186x_CAR
, port_No(port
));
1988 spin_unlock_irqrestore(&bp
->lock
, flags
);
1991 spin_lock_irqsave(&bp
->lock
, flags
);
1992 sx_out(bp
, CD186x_CCR
, CCR_SSCH2
);
1993 spin_unlock_irqrestore(&bp
->lock
, flags
);
1996 spin_lock_irqsave(&bp
->lock
, flags
);
1997 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1998 spin_unlock_irqrestore(&bp
->lock
, flags
);
2004 static void sx_unthrottle(struct tty_struct
*tty
)
2006 struct specialix_port
*port
= tty
->driver_data
;
2007 struct specialix_board
*bp
;
2008 unsigned long flags
;
2012 if (sx_paranoia_check(port
, tty
->name
, "sx_unthrottle")) {
2017 bp
= port_Board(port
);
2019 spin_lock_irqsave(&port
->lock
, flags
);
2020 /* XXXX Use DTR INSTEAD???? */
2021 if (sx_crtscts(tty
))
2022 port
->MSVR
|= MSVR_DTR
;
2023 /* Else clause: see remark in "sx_throttle"... */
2024 spin_lock(&bp
->lock
);
2025 sx_out(bp
, CD186x_CAR
, port_No(port
));
2026 spin_unlock(&bp
->lock
);
2028 spin_unlock_irqrestore(&port
->lock
, flags
);
2030 spin_lock_irqsave(&bp
->lock
, flags
);
2031 sx_out(bp
, CD186x_CCR
, CCR_SSCH1
);
2032 spin_unlock_irqrestore(&bp
->lock
, flags
);
2034 spin_lock_irqsave(&port
->lock
, flags
);
2036 spin_lock(&bp
->lock
);
2037 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2038 spin_unlock(&bp
->lock
);
2039 spin_unlock_irqrestore(&port
->lock
, flags
);
2045 static void sx_stop(struct tty_struct
*tty
)
2047 struct specialix_port
*port
= tty
->driver_data
;
2048 struct specialix_board
*bp
;
2049 unsigned long flags
;
2053 if (sx_paranoia_check(port
, tty
->name
, "sx_stop")) {
2058 bp
= port_Board(port
);
2060 spin_lock_irqsave(&port
->lock
, flags
);
2061 port
->IER
&= ~IER_TXRDY
;
2062 spin_lock(&bp
->lock
);
2063 sx_out(bp
, CD186x_CAR
, port_No(port
));
2064 sx_out(bp
, CD186x_IER
, port
->IER
);
2065 spin_unlock(&bp
->lock
);
2066 spin_unlock_irqrestore(&port
->lock
, flags
);
2072 static void sx_start(struct tty_struct
*tty
)
2074 struct specialix_port
*port
= tty
->driver_data
;
2075 struct specialix_board
*bp
;
2076 unsigned long flags
;
2080 if (sx_paranoia_check(port
, tty
->name
, "sx_start")) {
2085 bp
= port_Board(port
);
2087 spin_lock_irqsave(&port
->lock
, flags
);
2088 if (port
->xmit_cnt
&& port
->xmit_buf
&& !(port
->IER
& IER_TXRDY
)) {
2089 port
->IER
|= IER_TXRDY
;
2090 spin_lock(&bp
->lock
);
2091 sx_out(bp
, CD186x_CAR
, port_No(port
));
2092 sx_out(bp
, CD186x_IER
, port
->IER
);
2093 spin_unlock(&bp
->lock
);
2095 spin_unlock_irqrestore(&port
->lock
, flags
);
2100 static void sx_hangup(struct tty_struct
*tty
)
2102 struct specialix_port
*port
= tty
->driver_data
;
2103 struct specialix_board
*bp
;
2104 unsigned long flags
;
2108 if (sx_paranoia_check(port
, tty
->name
, "sx_hangup")) {
2113 bp
= port_Board(port
);
2115 sx_shutdown_port(bp
, port
);
2116 spin_lock_irqsave(&port
->lock
, flags
);
2117 bp
->count
-= port
->port
.count
;
2118 if (bp
->count
< 0) {
2120 "sx%d: sx_hangup: bad board count: %d port: %d\n",
2121 board_No(bp
), bp
->count
, tty
->index
);
2124 port
->port
.count
= 0;
2125 port
->port
.flags
&= ~ASYNC_NORMAL_ACTIVE
;
2126 port
->port
.tty
= NULL
;
2127 spin_unlock_irqrestore(&port
->lock
, flags
);
2128 wake_up_interruptible(&port
->port
.open_wait
);
2134 static void sx_set_termios(struct tty_struct
*tty
,
2135 struct ktermios
*old_termios
)
2137 struct specialix_port
*port
= tty
->driver_data
;
2138 unsigned long flags
;
2139 struct specialix_board
*bp
;
2141 if (sx_paranoia_check(port
, tty
->name
, "sx_set_termios"))
2144 bp
= port_Board(port
);
2145 spin_lock_irqsave(&port
->lock
, flags
);
2146 sx_change_speed(port_Board(port
), port
);
2147 spin_unlock_irqrestore(&port
->lock
, flags
);
2149 if ((old_termios
->c_cflag
& CRTSCTS
) &&
2150 !(tty
->termios
->c_cflag
& CRTSCTS
)) {
2151 tty
->hw_stopped
= 0;
2156 static const struct tty_operations sx_ops
= {
2160 .put_char
= sx_put_char
,
2161 .flush_chars
= sx_flush_chars
,
2162 .write_room
= sx_write_room
,
2163 .chars_in_buffer
= sx_chars_in_buffer
,
2164 .flush_buffer
= sx_flush_buffer
,
2166 .throttle
= sx_throttle
,
2167 .unthrottle
= sx_unthrottle
,
2168 .set_termios
= sx_set_termios
,
2171 .hangup
= sx_hangup
,
2172 .tiocmget
= sx_tiocmget
,
2173 .tiocmset
= sx_tiocmset
,
2174 .break_ctl
= sx_send_break
,
2177 static int sx_init_drivers(void)
2184 specialix_driver
= alloc_tty_driver(SX_NBOARD
* SX_NPORT
);
2185 if (!specialix_driver
) {
2186 printk(KERN_ERR
"sx: Couldn't allocate tty_driver.\n");
2191 specialix_driver
->owner
= THIS_MODULE
;
2192 specialix_driver
->name
= "ttyW";
2193 specialix_driver
->major
= SPECIALIX_NORMAL_MAJOR
;
2194 specialix_driver
->type
= TTY_DRIVER_TYPE_SERIAL
;
2195 specialix_driver
->subtype
= SERIAL_TYPE_NORMAL
;
2196 specialix_driver
->init_termios
= tty_std_termios
;
2197 specialix_driver
->init_termios
.c_cflag
=
2198 B9600
| CS8
| CREAD
| HUPCL
| CLOCAL
;
2199 specialix_driver
->init_termios
.c_ispeed
= 9600;
2200 specialix_driver
->init_termios
.c_ospeed
= 9600;
2201 specialix_driver
->flags
= TTY_DRIVER_REAL_RAW
|
2202 TTY_DRIVER_HARDWARE_BREAK
;
2203 tty_set_operations(specialix_driver
, &sx_ops
);
2205 error
= tty_register_driver(specialix_driver
);
2207 put_tty_driver(specialix_driver
);
2209 "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2214 memset(sx_port
, 0, sizeof(sx_port
));
2215 for (i
= 0; i
< SX_NPORT
* SX_NBOARD
; i
++) {
2216 sx_port
[i
].magic
= SPECIALIX_MAGIC
;
2217 tty_port_init(&sx_port
[i
].port
);
2218 spin_lock_init(&sx_port
[i
].lock
);
2225 static void sx_release_drivers(void)
2229 tty_unregister_driver(specialix_driver
);
2230 put_tty_driver(specialix_driver
);
2235 * This routine must be called by kernel at boot time
2237 static int __init
specialix_init(void)
2244 printk(KERN_INFO
"sx: Specialix IO8+ driver v" VERSION
", (c) R.E.Wolff 1997/1998.\n");
2245 printk(KERN_INFO
"sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2248 "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2250 printk(KERN_INFO
"sx: DTR/RTS pin is always RTS.\n");
2252 for (i
= 0; i
< SX_NBOARD
; i
++)
2253 spin_lock_init(&sx_board
[i
].lock
);
2255 if (sx_init_drivers()) {
2260 for (i
= 0; i
< SX_NBOARD
; i
++)
2261 if (sx_board
[i
].base
&& !sx_probe(&sx_board
[i
]))
2266 struct pci_dev
*pdev
= NULL
;
2269 while (i
< SX_NBOARD
) {
2270 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
) {
2274 pdev
= pci_get_device(PCI_VENDOR_ID_SPECIALIX
,
2275 PCI_DEVICE_ID_SPECIALIX_IO8
, pdev
);
2279 if (pci_enable_device(pdev
))
2282 sx_board
[i
].irq
= pdev
->irq
;
2284 sx_board
[i
].base
= pci_resource_start(pdev
, 2);
2286 sx_board
[i
].flags
|= SX_BOARD_IS_PCI
;
2287 if (!sx_probe(&sx_board
[i
]))
2290 /* May exit pci_get sequence early with lots of boards */
2297 sx_release_drivers();
2298 printk(KERN_INFO
"sx: No specialix IO8+ boards detected.\n");
2307 static int iobase
[SX_NBOARD
] = {0,};
2308 static int irq
[SX_NBOARD
] = {0,};
2310 module_param_array(iobase
, int, NULL
, 0);
2311 module_param_array(irq
, int, NULL
, 0);
2312 module_param(sx_debug
, int, 0);
2313 module_param(sx_rtscts
, int, 0);
2314 module_param(sx_rxfifo
, int, 0);
2317 * You can setup up to 4 boards.
2318 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2319 * You should specify the IRQs too in that case "irq=....,...".
2321 * More than 4 boards in one computer is not possible, as the card can
2322 * only use 4 different interrupts.
2325 static int __init
specialix_init_module(void)
2331 if (iobase
[0] || iobase
[1] || iobase
[2] || iobase
[3]) {
2332 for (i
= 0; i
< SX_NBOARD
; i
++) {
2333 sx_board
[i
].base
= iobase
[i
];
2334 sx_board
[i
].irq
= irq
[i
];
2335 sx_board
[i
].count
= 0;
2341 return specialix_init();
2344 static void __exit
specialix_exit_module(void)
2350 sx_release_drivers();
2351 for (i
= 0; i
< SX_NBOARD
; i
++)
2352 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
)
2353 sx_release_io_range(&sx_board
[i
]);
2357 static struct pci_device_id specialx_pci_tbl
[] __devinitdata
= {
2358 { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX
, PCI_DEVICE_ID_SPECIALIX_IO8
) },
2361 MODULE_DEVICE_TABLE(pci
, specialx_pci_tbl
);
2363 module_init(specialix_init_module
);
2364 module_exit(specialix_exit_module
);
2366 MODULE_LICENSE("GPL");
2367 MODULE_ALIAS_CHARDEV_MAJOR(SPECIALIX_NORMAL_MAJOR
);