2 * specialix.c -- specialix IO8+ multiport serial driver.
4 * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl)
5 * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com)
7 * Specialix pays for the development and support of this driver.
8 * Please DO contact io8-linux@specialix.co.uk if you require
9 * support. But please read the documentation (specialix.txt)
12 * This driver was developped in the BitWizard linux device
13 * driver service. If you require a linux device driver for your
14 * product, please contact devices@BitWizard.nl for a quote.
16 * This code is firmly based on the riscom/8 serial driver,
17 * written by Dmitry Gorodchanin. The specialix IO8+ card
18 * programming information was obtained from the CL-CD1865 Data
19 * Book, and Specialix document number 6200059: IO8+ Hardware
20 * Functional Specification.
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License as
24 * published by the Free Software Foundation; either version 2 of
25 * the License, or (at your option) any later version.
27 * This program is distributed in the hope that it will be
28 * useful, but WITHOUT ANY WARRANTY; without even the implied
29 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
30 * PURPOSE. See the GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public
33 * License along with this program; if not, write to the Free
34 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
39 * Revision 1.0: April 1st 1997.
40 * Initial release for alpha testing.
41 * Revision 1.1: April 14th 1997.
42 * Incorporated Richard Hudsons suggestions,
43 * removed some debugging printk's.
44 * Revision 1.2: April 15th 1997.
45 * Ported to 2.1.x kernels.
46 * Revision 1.3: April 17th 1997
47 * Backported to 2.0. (Compatibility macros).
48 * Revision 1.4: April 18th 1997
49 * Fixed DTR/RTS bug that caused the card to indicate
50 * "don't send data" to a modem after the password prompt.
51 * Fixed bug for premature (fake) interrupts.
52 * Revision 1.5: April 19th 1997
53 * fixed a minor typo in the header file, cleanup a little.
54 * performance warnings are now MAXed at once per minute.
55 * Revision 1.6: May 23 1997
56 * Changed the specialix=... format to include interrupt.
57 * Revision 1.7: May 27 1997
58 * Made many more debug printk's a compile time option.
59 * Revision 1.8: Jul 1 1997
60 * port to linux-2.1.43 kernel.
61 * Revision 1.9: Oct 9 1998
62 * Added stuff for the IO8+/PCI version.
63 * Revision 1.10: Oct 22 1999 / Jan 21 2000.
64 * Added stuff for setserial.
65 * Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr)
69 #define VERSION "1.11"
73 * There is a bunch of documentation about the card, jumpers, config
74 * settings, restrictions, cables, device names and numbers in
75 * Documentation/specialix.txt
78 #include <linux/config.h>
79 #include <linux/module.h>
82 #include <linux/kernel.h>
83 #include <linux/sched.h>
84 #include <linux/ioport.h>
85 #include <linux/interrupt.h>
86 #include <linux/errno.h>
87 #include <linux/tty.h>
89 #include <linux/serial.h>
90 #include <linux/fcntl.h>
91 #include <linux/major.h>
92 #include <linux/delay.h>
93 #include <linux/pci.h>
94 #include <linux/init.h>
95 #include <asm/uaccess.h>
97 #include "specialix_io8.h"
102 This driver can spew a whole lot of debugging output at you. If you
103 need maximum performance, you should disable the DEBUG define. To
104 aid in debugging in the field, I'm leaving the compile-time debug
105 features enabled, and disable them "runtime". That allows me to
106 instruct people with problems to enable debugging without requiring
112 static int sx_rxfifo
= SPECIALIX_RXFIFO
;
115 #define dprintk(f, str...) if (sx_debug & f) printk (str)
117 #define dprintk(f, str...) /* nothing */
120 #define SX_DEBUG_FLOW 0x0001
121 #define SX_DEBUG_DATA 0x0002
122 #define SX_DEBUG_PROBE 0x0004
123 #define SX_DEBUG_CHAN 0x0008
124 #define SX_DEBUG_INIT 0x0010
125 #define SX_DEBUG_RX 0x0020
126 #define SX_DEBUG_TX 0x0040
127 #define SX_DEBUG_IRQ 0x0080
128 #define SX_DEBUG_OPEN 0x0100
129 #define SX_DEBUG_TERMIOS 0x0200
130 #define SX_DEBUG_SIGNALS 0x0400
131 #define SX_DEBUG_FIFO 0x0800
134 #define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__FUNCTION__)
135 #define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __FUNCTION__)
137 #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
140 /* Configurable options: */
142 /* Am I paranoid or not ? ;-) */
143 #define SPECIALIX_PARANOIA_CHECK
145 /* Do I trust the IRQ from the card? (enabeling it doesn't seem to help)
146 When the IRQ routine leaves the chip in a state that is keeps on
147 requiring attention, the timer doesn't help either. */
148 #undef SPECIALIX_TIMER
150 #ifdef SPECIALIX_TIMER
151 static int sx_poll
= HZ
;
157 * The following defines are mostly for testing purposes. But if you need
158 * some nice reporting in your syslog, you can define them also.
160 #undef SX_REPORT_FIFO
161 #undef SX_REPORT_OVERRUN
165 #ifdef CONFIG_SPECIALIX_RTSCTS
166 #define SX_CRTSCTS(bla) 1
168 #define SX_CRTSCTS(tty) C_CRTSCTS(tty)
172 /* Used to be outb (0xff, 0x80); */
173 #define short_pause() udelay (1)
176 #define SPECIALIX_LEGAL_FLAGS \
177 (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \
178 ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \
179 ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
181 #undef RS_EVENT_WRITE_WAKEUP
182 #define RS_EVENT_WRITE_WAKEUP 0
184 static struct tty_driver
*specialix_driver
;
185 static unsigned char * tmp_buf
;
186 static DECLARE_MUTEX(tmp_buf_sem
);
188 static unsigned long baud_table
[] = {
189 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
190 9600, 19200, 38400, 57600, 115200, 0,
193 static struct specialix_board sx_board
[SX_NBOARD
] = {
194 { 0, SX_IOBASE1
, 9, },
195 { 0, SX_IOBASE2
, 11, },
196 { 0, SX_IOBASE3
, 12, },
197 { 0, SX_IOBASE4
, 15, },
200 static struct specialix_port sx_port
[SX_NBOARD
* SX_NPORT
];
203 #ifdef SPECIALIX_TIMER
204 static struct timer_list missed_irq_timer
;
205 static irqreturn_t
sx_interrupt(int irq
, void * dev_id
, struct pt_regs
* regs
);
210 static inline int sx_paranoia_check(struct specialix_port
const * port
,
211 char *name
, const char *routine
)
213 #ifdef SPECIALIX_PARANOIA_CHECK
214 static const char *badmagic
=
215 KERN_ERR
"sx: Warning: bad specialix port magic number for device %s in %s\n";
216 static const char *badinfo
=
217 KERN_ERR
"sx: Warning: null specialix port for device %s in %s\n";
220 printk(badinfo
, name
, routine
);
223 if (port
->magic
!= SPECIALIX_MAGIC
) {
224 printk(badmagic
, name
, routine
);
234 * Service functions for specialix IO8+ driver.
238 /* Get board number from pointer */
239 static inline int board_No (struct specialix_board
* bp
)
241 return bp
- sx_board
;
245 /* Get port number from pointer */
246 static inline int port_No (struct specialix_port
const * port
)
248 return SX_PORT(port
- sx_port
);
252 /* Get pointer to board from pointer to port */
253 static inline struct specialix_board
* port_Board(struct specialix_port
const * port
)
255 return &sx_board
[SX_BOARD(port
- sx_port
)];
259 /* Input Byte from CL CD186x register */
260 static inline unsigned char sx_in(struct specialix_board
* bp
, unsigned short reg
)
262 bp
->reg
= reg
| 0x80;
263 outb (reg
| 0x80, bp
->base
+ SX_ADDR_REG
);
264 return inb (bp
->base
+ SX_DATA_REG
);
268 /* Output Byte to CL CD186x register */
269 static inline void sx_out(struct specialix_board
* bp
, unsigned short reg
,
272 bp
->reg
= reg
| 0x80;
273 outb (reg
| 0x80, bp
->base
+ SX_ADDR_REG
);
274 outb (val
, bp
->base
+ SX_DATA_REG
);
278 /* Input Byte from CL CD186x register */
279 static inline unsigned char sx_in_off(struct specialix_board
* bp
, unsigned short reg
)
282 outb (reg
, bp
->base
+ SX_ADDR_REG
);
283 return inb (bp
->base
+ SX_DATA_REG
);
287 /* Output Byte to CL CD186x register */
288 static inline void sx_out_off(struct specialix_board
* bp
, unsigned short reg
,
292 outb (reg
, bp
->base
+ SX_ADDR_REG
);
293 outb (val
, bp
->base
+ SX_DATA_REG
);
297 /* Wait for Channel Command Register ready */
298 static inline void sx_wait_CCR(struct specialix_board
* bp
)
300 unsigned long delay
, flags
;
303 for (delay
= SX_CCR_TIMEOUT
; delay
; delay
--) {
304 spin_lock_irqsave(&bp
->lock
, flags
);
305 ccr
= sx_in(bp
, CD186x_CCR
);
306 spin_unlock_irqrestore(&bp
->lock
, flags
);
312 printk(KERN_ERR
"sx%d: Timeout waiting for CCR.\n", board_No(bp
));
316 /* Wait for Channel Command Register ready */
317 static inline void sx_wait_CCR_off(struct specialix_board
* bp
)
323 for (delay
= SX_CCR_TIMEOUT
; delay
; delay
--) {
324 spin_lock_irqsave(&bp
->lock
, flags
);
325 crr
= sx_in_off(bp
, CD186x_CCR
);
326 spin_unlock_irqrestore(&bp
->lock
, flags
);
332 printk(KERN_ERR
"sx%d: Timeout waiting for CCR.\n", board_No(bp
));
337 * specialix IO8+ IO range functions.
340 static inline int sx_request_io_range(struct specialix_board
* bp
)
342 return request_region(bp
->base
,
343 bp
->flags
& SX_BOARD_IS_PCI
? SX_PCI_IO_SPACE
: SX_IO_SPACE
,
344 "specialix IO8+") == NULL
;
348 static inline void sx_release_io_range(struct specialix_board
* bp
)
350 release_region(bp
->base
,
351 bp
->flags
&SX_BOARD_IS_PCI
?SX_PCI_IO_SPACE
:SX_IO_SPACE
);
355 /* Must be called with enabled interrupts */
356 /* Ugly. Very ugly. Don't use this for anything else than initialization
358 static inline void sx_long_delay(unsigned long delay
)
362 for (i
= jiffies
+ delay
; time_after(i
, jiffies
); ) ;
367 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
368 static int sx_set_irq ( struct specialix_board
*bp
)
374 if (bp
->flags
& SX_BOARD_IS_PCI
)
377 /* In the same order as in the docs... */
378 case 15: virq
= 0;break;
379 case 12: virq
= 1;break;
380 case 11: virq
= 2;break;
381 case 9: virq
= 3;break;
382 default: printk (KERN_ERR
"Speclialix: cannot set irq to %d.\n", bp
->irq
);
385 spin_lock_irqsave(&bp
->lock
, flags
);
387 sx_out(bp
, CD186x_CAR
, i
);
388 sx_out(bp
, CD186x_MSVRTS
, ((virq
>> i
) & 0x1)? MSVR_RTS
:0);
390 spin_unlock_irqrestore(&bp
->lock
, flags
);
395 /* Reset and setup CD186x chip */
396 static int sx_init_CD186x(struct specialix_board
* bp
)
403 sx_wait_CCR_off(bp
); /* Wait for CCR ready */
404 spin_lock_irqsave(&bp
->lock
, flags
);
405 sx_out_off(bp
, CD186x_CCR
, CCR_HARDRESET
); /* Reset CD186x chip */
406 spin_unlock_irqrestore(&bp
->lock
, flags
);
407 sx_long_delay(HZ
/20); /* Delay 0.05 sec */
408 spin_lock_irqsave(&bp
->lock
, flags
);
409 sx_out_off(bp
, CD186x_GIVR
, SX_ID
); /* Set ID for this chip */
410 sx_out_off(bp
, CD186x_GICR
, 0); /* Clear all bits */
411 sx_out_off(bp
, CD186x_PILR1
, SX_ACK_MINT
); /* Prio for modem intr */
412 sx_out_off(bp
, CD186x_PILR2
, SX_ACK_TINT
); /* Prio for transmitter intr */
413 sx_out_off(bp
, CD186x_PILR3
, SX_ACK_RINT
); /* Prio for receiver intr */
415 sx_out_off(bp
, CD186x_SRCR
, sx_in (bp
, CD186x_SRCR
) | SRCR_REGACKEN
);
417 /* Setting up prescaler. We need 4 ticks per 1 ms */
418 scaler
= SX_OSCFREQ
/SPECIALIX_TPS
;
420 sx_out_off(bp
, CD186x_PPRH
, scaler
>> 8);
421 sx_out_off(bp
, CD186x_PPRL
, scaler
& 0xff);
422 spin_unlock_irqrestore(&bp
->lock
, flags
);
424 if (!sx_set_irq (bp
)) {
425 /* Figure out how to pass this along... */
426 printk (KERN_ERR
"Cannot set irq to %d.\n", bp
->irq
);
435 static int read_cross_byte (struct specialix_board
*bp
, int reg
, int bit
)
441 spin_lock_irqsave(&bp
->lock
, flags
);
442 for (i
=0, t
=0;i
<8;i
++) {
443 sx_out_off (bp
, CD186x_CAR
, i
);
444 if (sx_in_off (bp
, reg
) & bit
)
447 spin_unlock_irqrestore(&bp
->lock
, flags
);
453 #ifdef SPECIALIX_TIMER
454 void missed_irq (unsigned long data
)
458 struct specialix_board
*bp
= (struct specialix_board
*)data
;
460 spin_lock_irqsave(&bp
->lock
, flags
);
461 irq
= sx_in ((struct specialix_board
*)data
, CD186x_SRSR
) &
465 spin_unlock_irqrestore(&bp
->lock
, flags
);
467 printk (KERN_INFO
"Missed interrupt... Calling int from timer. \n");
468 sx_interrupt (((struct specialix_board
*)data
)->irq
,
471 missed_irq_timer
.expires
= jiffies
+ sx_poll
;
472 add_timer (&missed_irq_timer
);
478 /* Main probing routine, also sets irq. */
479 static int sx_probe(struct specialix_board
*bp
)
481 unsigned char val1
, val2
;
491 if (sx_request_io_range(bp
)) {
496 /* Are the I/O ports here ? */
497 sx_out_off(bp
, CD186x_PPRL
, 0x5a);
499 val1
= sx_in_off(bp
, CD186x_PPRL
);
501 sx_out_off(bp
, CD186x_PPRL
, 0xa5);
503 val2
= sx_in_off(bp
, CD186x_PPRL
);
506 if ((val1
!= 0x5a) || (val2
!= 0xa5)) {
507 printk(KERN_INFO
"sx%d: specialix IO8+ Board at 0x%03x not found.\n",
508 board_No(bp
), bp
->base
);
509 sx_release_io_range(bp
);
514 /* Check the DSR lines that Specialix uses as board
516 val1
= read_cross_byte (bp
, CD186x_MSVR
, MSVR_DSR
);
517 val2
= read_cross_byte (bp
, CD186x_MSVR
, MSVR_RTS
);
518 dprintk (SX_DEBUG_INIT
, "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
519 board_No(bp
), val1
, val2
);
521 /* They managed to switch the bit order between the docs and
522 the IO8+ card. The new PCI card now conforms to old docs.
523 They changed the PCI docs to reflect the situation on the
525 val2
= (bp
->flags
& SX_BOARD_IS_PCI
)?0x4d : 0xb2;
527 printk(KERN_INFO
"sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
528 board_No(bp
), val2
, bp
->base
, val1
);
529 sx_release_io_range(bp
);
536 /* It's time to find IRQ for this board */
537 for (retries
= 0; retries
< 5 && irqs
<= 0; retries
++) {
538 irqs
= probe_irq_on();
539 sx_init_CD186x(bp
); /* Reset CD186x chip */
540 sx_out(bp
, CD186x_CAR
, 2); /* Select port 2 */
542 sx_out(bp
, CD186x_CCR
, CCR_TXEN
); /* Enable transmitter */
543 sx_out(bp
, CD186x_IER
, IER_TXRDY
); /* Enable tx empty intr */
544 sx_long_delay(HZ
/20);
545 irqs
= probe_irq_off(irqs
);
547 dprintk (SX_DEBUG_INIT
, "SRSR = %02x, ", sx_in(bp
, CD186x_SRSR
));
548 dprintk (SX_DEBUG_INIT
, "TRAR = %02x, ", sx_in(bp
, CD186x_TRAR
));
549 dprintk (SX_DEBUG_INIT
, "GIVR = %02x, ", sx_in(bp
, CD186x_GIVR
));
550 dprintk (SX_DEBUG_INIT
, "GICR = %02x, ", sx_in(bp
, CD186x_GICR
));
551 dprintk (SX_DEBUG_INIT
, "\n");
553 /* Reset CD186x again */
554 if (!sx_init_CD186x(bp
)) {
555 /* Hmmm. This is dead code anyway. */
558 dprintk (SX_DEBUG_INIT
"val1 = %02x, val2 = %02x, val3 = %02x.\n",
565 printk(KERN_ERR
"sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
566 board_No(bp
), bp
->base
);
567 sx_release_io_range(bp
);
572 printk (KERN_INFO
"Started with irq=%d, but now have irq=%d.\n", bp
->irq
, irqs
);
576 /* Reset CD186x again */
577 if (!sx_init_CD186x(bp
)) {
578 sx_release_io_range(bp
);
583 sx_request_io_range(bp
);
584 bp
->flags
|= SX_BOARD_PRESENT
;
586 /* Chip revcode pkgtype
591 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
593 -- Thanks to Gwen Wang, Cirrus Logic.
596 switch (sx_in_off(bp
, CD186x_GFRCR
)) {
597 case 0x82:chip
= 1864;rev
='A';break;
598 case 0x83:chip
= 1865;rev
='A';break;
599 case 0x84:chip
= 1865;rev
='B';break;
600 case 0x85:chip
= 1865;rev
='C';break; /* Does not exist at this time */
601 default:chip
=-1;rev
='x';
604 dprintk (SX_DEBUG_INIT
, " GFCR = 0x%02x\n", sx_in_off(bp
, CD186x_GFRCR
) );
606 #ifdef SPECIALIX_TIMER
607 init_timer (&missed_irq_timer
);
608 missed_irq_timer
.function
= missed_irq
;
609 missed_irq_timer
.data
= (unsigned long) bp
;
610 missed_irq_timer
.expires
= jiffies
+ sx_poll
;
611 add_timer (&missed_irq_timer
);
614 printk(KERN_INFO
"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
625 * Interrupt processing routines.
628 static inline void sx_mark_event(struct specialix_port
* port
, int event
)
632 set_bit(event
, &port
->event
);
633 schedule_work(&port
->tqueue
);
639 static inline struct specialix_port
* sx_get_port(struct specialix_board
* bp
,
640 unsigned char const * what
)
642 unsigned char channel
;
643 struct specialix_port
* port
= NULL
;
645 channel
= sx_in(bp
, CD186x_GICR
) >> GICR_CHAN_OFF
;
646 dprintk (SX_DEBUG_CHAN
, "channel: %d\n", channel
);
647 if (channel
< CD186x_NCH
) {
648 port
= &sx_port
[board_No(bp
) * SX_NPORT
+ channel
];
649 dprintk (SX_DEBUG_CHAN
, "port: %d %p flags: 0x%x\n",board_No(bp
) * SX_NPORT
+ channel
, port
, port
->flags
& ASYNC_INITIALIZED
);
651 if (port
->flags
& ASYNC_INITIALIZED
) {
652 dprintk (SX_DEBUG_CHAN
, "port: %d %p\n", channel
, port
);
657 printk(KERN_INFO
"sx%d: %s interrupt from invalid port %d\n",
658 board_No(bp
), what
, channel
);
663 static inline void sx_receive_exc(struct specialix_board
* bp
)
665 struct specialix_port
*port
;
666 struct tty_struct
*tty
;
667 unsigned char status
;
672 port
= sx_get_port(bp
, "Receive");
674 dprintk (SX_DEBUG_RX
, "Hmm, couldn't find port.\n");
679 dprintk (SX_DEBUG_RX
, "port: %p count: %d BUFF_SIZE: %d\n",
680 port
, tty
->flip
.count
, TTY_FLIPBUF_SIZE
);
682 status
= sx_in(bp
, CD186x_RCSR
);
684 dprintk (SX_DEBUG_RX
, "status: 0x%x\n", status
);
685 if (status
& RCSR_OE
) {
687 dprintk(SX_DEBUG_FIFO
, "sx%d: port %d: Overrun. Total %ld overruns.\n",
688 board_No(bp
), port_No(port
), port
->overrun
);
690 status
&= port
->mark_mask
;
692 /* This flip buffer check needs to be below the reading of the
693 status register to reset the chip's IRQ.... */
694 if (tty
->flip
.count
>= TTY_FLIPBUF_SIZE
) {
695 dprintk(SX_DEBUG_FIFO
, "sx%d: port %d: Working around flip buffer overflow.\n",
696 board_No(bp
), port_No(port
));
701 ch
= sx_in(bp
, CD186x_RDR
);
706 if (status
& RCSR_TOUT
) {
707 printk(KERN_INFO
"sx%d: port %d: Receiver timeout. Hardware problems ?\n",
708 board_No(bp
), port_No(port
));
712 } else if (status
& RCSR_BREAK
) {
713 dprintk(SX_DEBUG_RX
, "sx%d: port %d: Handling break...\n",
714 board_No(bp
), port_No(port
));
715 *tty
->flip
.flag_buf_ptr
++ = TTY_BREAK
;
716 if (port
->flags
& ASYNC_SAK
)
719 } else if (status
& RCSR_PE
)
720 *tty
->flip
.flag_buf_ptr
++ = TTY_PARITY
;
722 else if (status
& RCSR_FE
)
723 *tty
->flip
.flag_buf_ptr
++ = TTY_FRAME
;
725 else if (status
& RCSR_OE
)
726 *tty
->flip
.flag_buf_ptr
++ = TTY_OVERRUN
;
729 *tty
->flip
.flag_buf_ptr
++ = 0;
731 *tty
->flip
.char_buf_ptr
++ = ch
;
733 schedule_delayed_work(&tty
->flip
.work
, 1);
739 static inline void sx_receive(struct specialix_board
* bp
)
741 struct specialix_port
*port
;
742 struct tty_struct
*tty
;
747 if (!(port
= sx_get_port(bp
, "Receive"))) {
748 dprintk (SX_DEBUG_RX
, "Hmm, couldn't find port.\n");
754 count
= sx_in(bp
, CD186x_RDCR
);
755 dprintk (SX_DEBUG_RX
, "port: %p: count: %d\n", port
, count
);
756 port
->hits
[count
> 8 ? 9 : count
]++;
759 if (tty
->flip
.count
>= TTY_FLIPBUF_SIZE
) {
760 printk(KERN_INFO
"sx%d: port %d: Working around flip buffer overflow.\n",
761 board_No(bp
), port_No(port
));
764 *tty
->flip
.char_buf_ptr
++ = sx_in(bp
, CD186x_RDR
);
765 *tty
->flip
.flag_buf_ptr
++ = 0;
768 schedule_delayed_work(&tty
->flip
.work
, 1);
774 static inline void sx_transmit(struct specialix_board
* bp
)
776 struct specialix_port
*port
;
777 struct tty_struct
*tty
;
781 if (!(port
= sx_get_port(bp
, "Transmit"))) {
785 dprintk (SX_DEBUG_TX
, "port: %p\n", port
);
788 if (port
->IER
& IER_TXEMPTY
) {
790 sx_out(bp
, CD186x_CAR
, port_No(port
));
791 port
->IER
&= ~IER_TXEMPTY
;
792 sx_out(bp
, CD186x_IER
, port
->IER
);
797 if ((port
->xmit_cnt
<= 0 && !port
->break_length
)
798 || tty
->stopped
|| tty
->hw_stopped
) {
799 sx_out(bp
, CD186x_CAR
, port_No(port
));
800 port
->IER
&= ~IER_TXRDY
;
801 sx_out(bp
, CD186x_IER
, port
->IER
);
806 if (port
->break_length
) {
807 if (port
->break_length
> 0) {
808 if (port
->COR2
& COR2_ETC
) {
809 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
810 sx_out(bp
, CD186x_TDR
, CD186x_C_SBRK
);
811 port
->COR2
&= ~COR2_ETC
;
813 count
= min_t(int, port
->break_length
, 0xff);
814 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
815 sx_out(bp
, CD186x_TDR
, CD186x_C_DELAY
);
816 sx_out(bp
, CD186x_TDR
, count
);
817 if (!(port
->break_length
-= count
))
818 port
->break_length
--;
820 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
821 sx_out(bp
, CD186x_TDR
, CD186x_C_EBRK
);
822 sx_out(bp
, CD186x_COR2
, port
->COR2
);
824 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
825 port
->break_length
= 0;
832 count
= CD186x_NFIFO
;
834 sx_out(bp
, CD186x_TDR
, port
->xmit_buf
[port
->xmit_tail
++]);
835 port
->xmit_tail
= port
->xmit_tail
& (SERIAL_XMIT_SIZE
-1);
836 if (--port
->xmit_cnt
<= 0)
838 } while (--count
> 0);
840 if (port
->xmit_cnt
<= 0) {
841 sx_out(bp
, CD186x_CAR
, port_No(port
));
842 port
->IER
&= ~IER_TXRDY
;
843 sx_out(bp
, CD186x_IER
, port
->IER
);
845 if (port
->xmit_cnt
<= port
->wakeup_chars
)
846 sx_mark_event(port
, RS_EVENT_WRITE_WAKEUP
);
852 static inline void sx_check_modem(struct specialix_board
* bp
)
854 struct specialix_port
*port
;
855 struct tty_struct
*tty
;
859 dprintk (SX_DEBUG_SIGNALS
, "Modem intr. ");
860 if (!(port
= sx_get_port(bp
, "Modem")))
865 mcr
= sx_in(bp
, CD186x_MCR
);
866 printk ("mcr = %02x.\n", mcr
);
868 if ((mcr
& MCR_CDCHG
)) {
869 dprintk (SX_DEBUG_SIGNALS
, "CD just changed... ");
870 msvr_cd
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
872 dprintk (SX_DEBUG_SIGNALS
, "Waking up guys in open.\n");
873 wake_up_interruptible(&port
->open_wait
);
875 dprintk (SX_DEBUG_SIGNALS
, "Sending HUP.\n");
876 schedule_work(&port
->tqueue_hangup
);
880 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
881 if (mcr
& MCR_CTSCHG
) {
882 if (sx_in(bp
, CD186x_MSVR
) & MSVR_CTS
) {
884 port
->IER
|= IER_TXRDY
;
885 if (port
->xmit_cnt
<= port
->wakeup_chars
)
886 sx_mark_event(port
, RS_EVENT_WRITE_WAKEUP
);
889 port
->IER
&= ~IER_TXRDY
;
891 sx_out(bp
, CD186x_IER
, port
->IER
);
893 if (mcr
& MCR_DSSXHG
) {
894 if (sx_in(bp
, CD186x_MSVR
) & MSVR_DSR
) {
896 port
->IER
|= IER_TXRDY
;
897 if (port
->xmit_cnt
<= port
->wakeup_chars
)
898 sx_mark_event(port
, RS_EVENT_WRITE_WAKEUP
);
901 port
->IER
&= ~IER_TXRDY
;
903 sx_out(bp
, CD186x_IER
, port
->IER
);
905 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
907 /* Clear change bits */
908 sx_out(bp
, CD186x_MCR
, 0);
912 /* The main interrupt processing routine */
913 static irqreturn_t
sx_interrupt(int irq
, void *dev_id
, struct pt_regs
*regs
)
915 unsigned char status
;
917 struct specialix_board
*bp
;
918 unsigned long loop
= 0;
925 spin_lock_irqsave(&bp
->lock
, flags
);
927 dprintk (SX_DEBUG_FLOW
, "enter %s port %d room: %ld\n", __FUNCTION__
, port_No(sx_get_port(bp
, "INT")), SERIAL_XMIT_SIZE
- sx_get_port(bp
, "ITN")->xmit_cnt
- 1);
928 if (!bp
|| !(bp
->flags
& SX_BOARD_ACTIVE
)) {
929 dprintk (SX_DEBUG_IRQ
, "sx: False interrupt. irq %d.\n", irq
);
930 spin_unlock_irqrestore(&bp
->lock
, flags
);
937 while ((++loop
< 16) && (status
= (sx_in(bp
, CD186x_SRSR
) &
941 if (status
& SRSR_RREQint
) {
942 ack
= sx_in(bp
, CD186x_RRAR
);
944 if (ack
== (SX_ID
| GIVR_IT_RCV
))
946 else if (ack
== (SX_ID
| GIVR_IT_REXC
))
949 printk(KERN_ERR
"sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
950 board_No(bp
), status
, ack
);
952 } else if (status
& SRSR_TREQint
) {
953 ack
= sx_in(bp
, CD186x_TRAR
);
955 if (ack
== (SX_ID
| GIVR_IT_TX
))
958 printk(KERN_ERR
"sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
959 board_No(bp
), status
, ack
, port_No (sx_get_port (bp
, "Int")));
960 } else if (status
& SRSR_MREQint
) {
961 ack
= sx_in(bp
, CD186x_MRAR
);
963 if (ack
== (SX_ID
| GIVR_IT_MODEM
))
966 printk(KERN_ERR
"sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
967 board_No(bp
), status
, ack
);
971 sx_out(bp
, CD186x_EOIR
, 0); /* Mark end of interrupt */
974 outb (bp
->reg
, bp
->base
+ SX_ADDR_REG
);
975 spin_unlock_irqrestore(&bp
->lock
, flags
);
982 * Routines for open & close processing.
985 static void turn_ints_off (struct specialix_board
*bp
)
990 if (bp
->flags
& SX_BOARD_IS_PCI
) {
991 /* This was intended for enabeling the interrupt on the
992 * PCI card. However it seems that it's already enabled
993 * and as PCI interrupts can be shared, there is no real
994 * reason to have to turn it off. */
997 spin_lock_irqsave(&bp
->lock
, flags
);
998 (void) sx_in_off (bp
, 0); /* Turn off interrupts. */
999 spin_unlock_irqrestore(&bp
->lock
, flags
);
1004 static void turn_ints_on (struct specialix_board
*bp
)
1006 unsigned long flags
;
1010 if (bp
->flags
& SX_BOARD_IS_PCI
) {
1011 /* play with the PCI chip. See comment above. */
1013 spin_lock_irqsave(&bp
->lock
, flags
);
1014 (void) sx_in (bp
, 0); /* Turn ON interrupts. */
1015 spin_unlock_irqrestore(&bp
->lock
, flags
);
1021 /* Called with disabled interrupts */
1022 static inline int sx_setup_board(struct specialix_board
* bp
)
1026 if (bp
->flags
& SX_BOARD_ACTIVE
)
1029 if (bp
->flags
& SX_BOARD_IS_PCI
)
1030 error
= request_irq(bp
->irq
, sx_interrupt
, SA_INTERRUPT
| SA_SHIRQ
, "specialix IO8+", bp
);
1032 error
= request_irq(bp
->irq
, sx_interrupt
, SA_INTERRUPT
, "specialix IO8+", bp
);
1038 bp
->flags
|= SX_BOARD_ACTIVE
;
1044 /* Called with disabled interrupts */
1045 static inline void sx_shutdown_board(struct specialix_board
*bp
)
1049 if (!(bp
->flags
& SX_BOARD_ACTIVE
)) {
1054 bp
->flags
&= ~SX_BOARD_ACTIVE
;
1056 dprintk (SX_DEBUG_IRQ
, "Freeing IRQ%d for board %d.\n",
1057 bp
->irq
, board_No (bp
));
1058 free_irq(bp
->irq
, bp
);
1068 * Setting up port characteristics.
1069 * Must be called with disabled interrupts
1071 static void sx_change_speed(struct specialix_board
*bp
, struct specialix_port
*port
)
1073 struct tty_struct
*tty
;
1076 unsigned char cor1
= 0, cor3
= 0;
1077 unsigned char mcor1
= 0, mcor2
= 0;
1078 static unsigned long again
;
1079 unsigned long flags
;
1083 if (!(tty
= port
->tty
) || !tty
->termios
) {
1090 /* Select port on the board */
1091 spin_lock_irqsave(&bp
->lock
, flags
);
1092 sx_out(bp
, CD186x_CAR
, port_No(port
));
1094 /* The Specialix board doens't implement the RTS lines.
1095 They are used to set the IRQ level. Don't touch them. */
1096 if (SX_CRTSCTS(tty
))
1097 port
->MSVR
= MSVR_DTR
| (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
1099 port
->MSVR
= (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
1100 spin_unlock_irqrestore(&bp
->lock
, flags
);
1101 dprintk (SX_DEBUG_TERMIOS
, "sx: got MSVR=%02x.\n", port
->MSVR
);
1104 if (baud
& CBAUDEX
) {
1106 if (baud
< 1 || baud
> 2)
1107 port
->tty
->termios
->c_cflag
&= ~CBAUDEX
;
1112 if ((port
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_HI
)
1114 if ((port
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_VHI
)
1119 if (!baud_table
[baud
]) {
1120 /* Drop DTR & exit */
1121 dprintk (SX_DEBUG_TERMIOS
, "Dropping DTR... Hmm....\n");
1122 if (!SX_CRTSCTS (tty
)) {
1123 port
-> MSVR
&= ~ MSVR_DTR
;
1124 spin_lock_irqsave(&bp
->lock
, flags
);
1125 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1126 spin_unlock_irqrestore(&bp
->lock
, flags
);
1129 dprintk (SX_DEBUG_TERMIOS
, "Can't drop DTR: no DTR.\n");
1133 if (!SX_CRTSCTS (tty
)) {
1134 port
->MSVR
|= MSVR_DTR
;
1139 * Now we must calculate some speed depended things
1142 /* Set baud rate for port */
1143 tmp
= port
->custom_divisor
;
1145 printk (KERN_INFO
"sx%d: Using custom baud rate divisor %ld. \n"
1146 "This is an untested option, please be carefull.\n",
1147 port_No (port
), tmp
);
1149 tmp
= (((SX_OSCFREQ
+ baud_table
[baud
]/2) / baud_table
[baud
] +
1150 CD186x_TPC
/2) / CD186x_TPC
);
1152 if ((tmp
< 0x10) && time_before(again
, jiffies
)) {
1153 again
= jiffies
+ HZ
* 60;
1154 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1156 printk (KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1157 "Performance degradation is possible.\n"
1158 "Read specialix.txt for more info.\n",
1159 port_No (port
), tmp
);
1161 printk (KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1162 "Warning: overstressing Cirrus chip. "
1163 "This might not work.\n"
1164 "Read specialix.txt for more info.\n",
1165 port_No (port
), tmp
);
1168 spin_lock_irqsave(&bp
->lock
, flags
);
1169 sx_out(bp
, CD186x_RBPRH
, (tmp
>> 8) & 0xff);
1170 sx_out(bp
, CD186x_TBPRH
, (tmp
>> 8) & 0xff);
1171 sx_out(bp
, CD186x_RBPRL
, tmp
& 0xff);
1172 sx_out(bp
, CD186x_TBPRL
, tmp
& 0xff);
1173 spin_unlock_irqrestore(&bp
->lock
, flags
);
1174 if (port
->custom_divisor
) {
1175 baud
= (SX_OSCFREQ
+ port
->custom_divisor
/2) / port
->custom_divisor
;
1176 baud
= ( baud
+ 5 ) / 10;
1178 baud
= (baud_table
[baud
] + 5) / 10; /* Estimated CPS */
1180 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1181 tmp
= ((baud
+ HZ
/2) / HZ
) * 2 - CD186x_NFIFO
;
1182 port
->wakeup_chars
= (tmp
< 0) ? 0 : ((tmp
>= SERIAL_XMIT_SIZE
) ?
1183 SERIAL_XMIT_SIZE
- 1 : tmp
);
1185 /* Receiver timeout will be transmission time for 1.5 chars */
1186 tmp
= (SPECIALIX_TPS
+ SPECIALIX_TPS
/2 + baud
/2) / baud
;
1187 tmp
= (tmp
> 0xff) ? 0xff : tmp
;
1188 spin_lock_irqsave(&bp
->lock
, flags
);
1189 sx_out(bp
, CD186x_RTPR
, tmp
);
1190 spin_unlock_irqrestore(&bp
->lock
, flags
);
1191 switch (C_CSIZE(tty
)) {
1209 cor1
|= COR1_IGNORE
;
1210 if (C_PARENB(tty
)) {
1211 cor1
|= COR1_NORMPAR
;
1215 cor1
&= ~COR1_IGNORE
;
1217 /* Set marking of some errors */
1218 port
->mark_mask
= RCSR_OE
| RCSR_TOUT
;
1220 port
->mark_mask
|= RCSR_FE
| RCSR_PE
;
1221 if (I_BRKINT(tty
) || I_PARMRK(tty
))
1222 port
->mark_mask
|= RCSR_BREAK
;
1224 port
->mark_mask
&= ~(RCSR_FE
| RCSR_PE
);
1225 if (I_IGNBRK(tty
)) {
1226 port
->mark_mask
&= ~RCSR_BREAK
;
1228 /* Real raw mode. Ignore all */
1229 port
->mark_mask
&= ~RCSR_OE
;
1231 /* Enable Hardware Flow Control */
1232 if (C_CRTSCTS(tty
)) {
1233 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1234 port
->IER
|= IER_DSR
| IER_CTS
;
1235 mcor1
|= MCOR1_DSRZD
| MCOR1_CTSZD
;
1236 mcor2
|= MCOR2_DSROD
| MCOR2_CTSOD
;
1237 spin_lock_irqsave(&bp
->lock
, flags
);
1238 tty
->hw_stopped
= !(sx_in(bp
, CD186x_MSVR
) & (MSVR_CTS
|MSVR_DSR
));
1239 spin_unlock_irqrestore(&bp
->lock
, flags
);
1241 port
->COR2
|= COR2_CTSAE
;
1244 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1245 /* Some people reported that it works, but I still doubt it */
1247 port
->COR2
|= COR2_TXIBE
;
1248 cor3
|= (COR3_FCT
| COR3_SCDE
);
1250 port
->COR2
|= COR2_IXM
;
1251 spin_lock_irqsave(&bp
->lock
, flags
);
1252 sx_out(bp
, CD186x_SCHR1
, START_CHAR(tty
));
1253 sx_out(bp
, CD186x_SCHR2
, STOP_CHAR(tty
));
1254 sx_out(bp
, CD186x_SCHR3
, START_CHAR(tty
));
1255 sx_out(bp
, CD186x_SCHR4
, STOP_CHAR(tty
));
1256 spin_unlock_irqrestore(&bp
->lock
, flags
);
1258 if (!C_CLOCAL(tty
)) {
1259 /* Enable CD check */
1260 port
->IER
|= IER_CD
;
1261 mcor1
|= MCOR1_CDZD
;
1262 mcor2
|= MCOR2_CDOD
;
1266 /* Enable receiver */
1267 port
->IER
|= IER_RXD
;
1269 /* Set input FIFO size (1-8 bytes) */
1271 /* Setting up CD186x channel registers */
1272 spin_lock_irqsave(&bp
->lock
, flags
);
1273 sx_out(bp
, CD186x_COR1
, cor1
);
1274 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1275 sx_out(bp
, CD186x_COR3
, cor3
);
1276 spin_unlock_irqrestore(&bp
->lock
, flags
);
1277 /* Make CD186x know about registers change */
1279 spin_lock_irqsave(&bp
->lock
, flags
);
1280 sx_out(bp
, CD186x_CCR
, CCR_CORCHG1
| CCR_CORCHG2
| CCR_CORCHG3
);
1281 /* Setting up modem option registers */
1282 dprintk (SX_DEBUG_TERMIOS
, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1
, mcor2
);
1283 sx_out(bp
, CD186x_MCOR1
, mcor1
);
1284 sx_out(bp
, CD186x_MCOR2
, mcor2
);
1285 spin_unlock_irqrestore(&bp
->lock
, flags
);
1286 /* Enable CD186x transmitter & receiver */
1288 spin_lock_irqsave(&bp
->lock
, flags
);
1289 sx_out(bp
, CD186x_CCR
, CCR_TXEN
| CCR_RXEN
);
1290 /* Enable interrupts */
1291 sx_out(bp
, CD186x_IER
, port
->IER
);
1292 /* And finally set the modem lines... */
1293 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1294 spin_unlock_irqrestore(&bp
->lock
, flags
);
1300 /* Must be called with interrupts enabled */
1301 static int sx_setup_port(struct specialix_board
*bp
, struct specialix_port
*port
)
1303 unsigned long flags
;
1307 if (port
->flags
& ASYNC_INITIALIZED
) {
1312 if (!port
->xmit_buf
) {
1313 /* We may sleep in get_zeroed_page() */
1316 if (!(tmp
= get_zeroed_page(GFP_KERNEL
))) {
1321 if (port
->xmit_buf
) {
1324 return -ERESTARTSYS
;
1326 port
->xmit_buf
= (unsigned char *) tmp
;
1329 spin_lock_irqsave(&port
->lock
, flags
);
1332 clear_bit(TTY_IO_ERROR
, &port
->tty
->flags
);
1334 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1335 sx_change_speed(bp
, port
);
1336 port
->flags
|= ASYNC_INITIALIZED
;
1338 spin_unlock_irqrestore(&port
->lock
, flags
);
1346 /* Must be called with interrupts disabled */
1347 static void sx_shutdown_port(struct specialix_board
*bp
, struct specialix_port
*port
)
1349 struct tty_struct
*tty
;
1351 unsigned long flags
;
1355 if (!(port
->flags
& ASYNC_INITIALIZED
)) {
1360 if (sx_debug
& SX_DEBUG_FIFO
) {
1361 dprintk(SX_DEBUG_FIFO
, "sx%d: port %d: %ld overruns, FIFO hits [ ",
1362 board_No(bp
), port_No(port
), port
->overrun
);
1363 for (i
= 0; i
< 10; i
++) {
1364 dprintk(SX_DEBUG_FIFO
, "%ld ", port
->hits
[i
]);
1366 dprintk(SX_DEBUG_FIFO
, "].\n");
1369 if (port
->xmit_buf
) {
1370 free_page((unsigned long) port
->xmit_buf
);
1371 port
->xmit_buf
= NULL
;
1375 spin_lock_irqsave(&bp
->lock
, flags
);
1376 sx_out(bp
, CD186x_CAR
, port_No(port
));
1378 if (!(tty
= port
->tty
) || C_HUPCL(tty
)) {
1380 sx_out(bp
, CD186x_MSVDTR
, 0);
1382 spin_unlock_irqrestore(&bp
->lock
, flags
);
1385 spin_lock_irqsave(&bp
->lock
, flags
);
1386 sx_out(bp
, CD186x_CCR
, CCR_SOFTRESET
);
1387 /* Disable all interrupts from this port */
1389 sx_out(bp
, CD186x_IER
, port
->IER
);
1390 spin_unlock_irqrestore(&bp
->lock
, flags
);
1392 set_bit(TTY_IO_ERROR
, &tty
->flags
);
1393 port
->flags
&= ~ASYNC_INITIALIZED
;
1396 sx_shutdown_board(bp
);
1401 static int block_til_ready(struct tty_struct
*tty
, struct file
* filp
,
1402 struct specialix_port
*port
)
1404 DECLARE_WAITQUEUE(wait
, current
);
1405 struct specialix_board
*bp
= port_Board(port
);
1409 unsigned long flags
;
1414 * If the device is in the middle of being closed, then block
1415 * until it's done, and then try again.
1417 if (tty_hung_up_p(filp
) || port
->flags
& ASYNC_CLOSING
) {
1418 interruptible_sleep_on(&port
->close_wait
);
1419 if (port
->flags
& ASYNC_HUP_NOTIFY
) {
1424 return -ERESTARTSYS
;
1429 * If non-blocking mode is set, or the port is not enabled,
1430 * then make the check up front and then exit.
1432 if ((filp
->f_flags
& O_NONBLOCK
) ||
1433 (tty
->flags
& (1 << TTY_IO_ERROR
))) {
1434 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
1443 * Block waiting for the carrier detect and the line to become
1444 * free (i.e., not in use by the callout). While we are in
1445 * this loop, info->count is dropped by one, so that
1446 * rs_close() knows when to free things. We restore it upon
1447 * exit, either normal or abnormal.
1450 add_wait_queue(&port
->open_wait
, &wait
);
1451 spin_lock_irqsave(&port
->lock
, flags
);
1452 if (!tty_hung_up_p(filp
)) {
1455 spin_unlock_irqrestore(&port
->lock
, flags
);
1456 port
->blocked_open
++;
1458 spin_lock_irqsave(&bp
->lock
, flags
);
1459 sx_out(bp
, CD186x_CAR
, port_No(port
));
1460 CD
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
1461 if (SX_CRTSCTS (tty
)) {
1463 port
->MSVR
|= MSVR_DTR
; /* WTF? */
1464 sx_out (bp
, CD186x_MSVR
, port
->MSVR
);
1467 port
->MSVR
|= MSVR_DTR
;
1468 sx_out (bp
, CD186x_MSVR
, port
->MSVR
);
1470 spin_unlock_irqrestore(&bp
->lock
, flags
);
1471 set_current_state(TASK_INTERRUPTIBLE
);
1472 if (tty_hung_up_p(filp
) ||
1473 !(port
->flags
& ASYNC_INITIALIZED
)) {
1474 if (port
->flags
& ASYNC_HUP_NOTIFY
)
1477 retval
= -ERESTARTSYS
;
1480 if (!(port
->flags
& ASYNC_CLOSING
) &&
1483 if (signal_pending(current
)) {
1484 retval
= -ERESTARTSYS
;
1490 set_current_state(TASK_RUNNING
);
1491 remove_wait_queue(&port
->open_wait
, &wait
);
1492 spin_lock_irqsave(&port
->lock
, flags
);
1493 if (!tty_hung_up_p(filp
)) {
1496 port
->blocked_open
--;
1497 spin_unlock_irqrestore(&port
->lock
, flags
);
1503 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
1509 static int sx_open(struct tty_struct
* tty
, struct file
* filp
)
1513 struct specialix_port
* port
;
1514 struct specialix_board
* bp
;
1516 unsigned long flags
;
1520 board
= SX_BOARD(tty
->index
);
1522 if (board
>= SX_NBOARD
|| !(sx_board
[board
].flags
& SX_BOARD_PRESENT
)) {
1527 bp
= &sx_board
[board
];
1528 port
= sx_port
+ board
* SX_NPORT
+ SX_PORT(tty
->index
);
1530 for (i
= 0; i
< 10; i
++)
1533 dprintk (SX_DEBUG_OPEN
, "Board = %d, bp = %p, port = %p, portno = %d.\n",
1534 board
, bp
, port
, SX_PORT(tty
->index
));
1536 if (sx_paranoia_check(port
, tty
->name
, "sx_open")) {
1541 if ((error
= sx_setup_board(bp
))) {
1546 spin_lock_irqsave(&bp
->lock
, flags
);
1549 tty
->driver_data
= port
;
1551 spin_unlock_irqrestore(&bp
->lock
, flags
);
1553 if ((error
= sx_setup_port(bp
, port
))) {
1558 if ((error
= block_til_ready(tty
, filp
, port
))) {
1568 static void sx_close(struct tty_struct
* tty
, struct file
* filp
)
1570 struct specialix_port
*port
= (struct specialix_port
*) tty
->driver_data
;
1571 struct specialix_board
*bp
;
1572 unsigned long flags
;
1573 unsigned long timeout
;
1576 if (!port
|| sx_paranoia_check(port
, tty
->name
, "close")) {
1580 spin_lock_irqsave(&port
->lock
, flags
);
1582 if (tty_hung_up_p(filp
)) {
1583 spin_unlock_irqrestore(&port
->lock
, flags
);
1588 bp
= port_Board(port
);
1589 if ((tty
->count
== 1) && (port
->count
!= 1)) {
1590 printk(KERN_ERR
"sx%d: sx_close: bad port count;"
1591 " tty->count is 1, port count is %d\n",
1592 board_No(bp
), port
->count
);
1596 if (port
->count
> 1) {
1600 spin_unlock_irqrestore(&port
->lock
, flags
);
1605 port
->flags
|= ASYNC_CLOSING
;
1607 * Now we wait for the transmit buffer to clear; and we notify
1608 * the line discipline to only process XON/XOFF characters.
1611 spin_unlock_irqrestore(&port
->lock
, flags
);
1612 dprintk (SX_DEBUG_OPEN
, "Closing\n");
1613 if (port
->closing_wait
!= ASYNC_CLOSING_WAIT_NONE
) {
1614 tty_wait_until_sent(tty
, port
->closing_wait
);
1617 * At this point we stop accepting input. To do this, we
1618 * disable the receive line status interrupts, and tell the
1619 * interrupt driver to stop checking the data ready bit in the
1620 * line status register.
1622 dprintk (SX_DEBUG_OPEN
, "Closed\n");
1623 port
->IER
&= ~IER_RXD
;
1624 if (port
->flags
& ASYNC_INITIALIZED
) {
1625 port
->IER
&= ~IER_TXRDY
;
1626 port
->IER
|= IER_TXEMPTY
;
1627 spin_lock_irqsave(&bp
->lock
, flags
);
1628 sx_out(bp
, CD186x_CAR
, port_No(port
));
1629 sx_out(bp
, CD186x_IER
, port
->IER
);
1630 spin_unlock_irqrestore(&bp
->lock
, flags
);
1632 * Before we drop DTR, make sure the UART transmitter
1633 * has completely drained; this is especially
1634 * important if there is a transmit FIFO!
1636 timeout
= jiffies
+HZ
;
1637 while(port
->IER
& IER_TXEMPTY
) {
1638 set_current_state (TASK_INTERRUPTIBLE
);
1639 msleep_interruptible(jiffies_to_msecs(port
->timeout
));
1640 if (time_after(jiffies
, timeout
)) {
1641 printk (KERN_INFO
"Timeout waiting for close\n");
1648 if (--bp
->count
< 0) {
1649 printk(KERN_ERR
"sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1650 board_No(bp
), bp
->count
, tty
->index
);
1653 if (--port
->count
< 0) {
1654 printk(KERN_ERR
"sx%d: sx_close: bad port count for tty%d: %d\n",
1655 board_No(bp
), port_No(port
), port
->count
);
1659 sx_shutdown_port(bp
, port
);
1660 if (tty
->driver
->flush_buffer
)
1661 tty
->driver
->flush_buffer(tty
);
1662 tty_ldisc_flush(tty
);
1663 spin_lock_irqsave(&port
->lock
, flags
);
1667 spin_unlock_irqrestore(&port
->lock
, flags
);
1668 if (port
->blocked_open
) {
1669 if (port
->close_delay
) {
1670 msleep_interruptible(jiffies_to_msecs(port
->close_delay
));
1672 wake_up_interruptible(&port
->open_wait
);
1674 port
->flags
&= ~(ASYNC_NORMAL_ACTIVE
|ASYNC_CLOSING
);
1675 wake_up_interruptible(&port
->close_wait
);
1681 static int sx_write(struct tty_struct
* tty
,
1682 const unsigned char *buf
, int count
)
1684 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1685 struct specialix_board
*bp
;
1687 unsigned long flags
;
1690 if (sx_paranoia_check(port
, tty
->name
, "sx_write")) {
1695 bp
= port_Board(port
);
1697 if (!tty
|| !port
->xmit_buf
|| !tmp_buf
) {
1703 spin_lock_irqsave(&port
->lock
, flags
);
1704 c
= min_t(int, count
, min(SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1,
1705 SERIAL_XMIT_SIZE
- port
->xmit_head
));
1707 spin_unlock_irqrestore(&port
->lock
, flags
);
1710 memcpy(port
->xmit_buf
+ port
->xmit_head
, buf
, c
);
1711 port
->xmit_head
= (port
->xmit_head
+ c
) & (SERIAL_XMIT_SIZE
-1);
1712 port
->xmit_cnt
+= c
;
1713 spin_unlock_irqrestore(&port
->lock
, flags
);
1720 spin_lock_irqsave(&bp
->lock
, flags
);
1721 if (port
->xmit_cnt
&& !tty
->stopped
&& !tty
->hw_stopped
&&
1722 !(port
->IER
& IER_TXRDY
)) {
1723 port
->IER
|= IER_TXRDY
;
1724 sx_out(bp
, CD186x_CAR
, port_No(port
));
1725 sx_out(bp
, CD186x_IER
, port
->IER
);
1727 spin_unlock_irqrestore(&bp
->lock
, flags
);
1734 static void sx_put_char(struct tty_struct
* tty
, unsigned char ch
)
1736 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1737 unsigned long flags
;
1738 struct specialix_board
* bp
;
1742 if (sx_paranoia_check(port
, tty
->name
, "sx_put_char")) {
1746 dprintk (SX_DEBUG_TX
, "check tty: %p %p\n", tty
, port
->xmit_buf
);
1747 if (!tty
|| !port
->xmit_buf
) {
1751 bp
= port_Board(port
);
1752 spin_lock_irqsave(&port
->lock
, flags
);
1754 dprintk (SX_DEBUG_TX
, "xmit_cnt: %d xmit_buf: %p\n", port
->xmit_cnt
, port
->xmit_buf
);
1755 if ((port
->xmit_cnt
>= SERIAL_XMIT_SIZE
- 1) || (!port
->xmit_buf
)) {
1756 spin_unlock_irqrestore(&port
->lock
, flags
);
1757 dprintk (SX_DEBUG_TX
, "Exit size\n");
1761 dprintk (SX_DEBUG_TX
, "Handle xmit: %p %p\n", port
, port
->xmit_buf
);
1762 port
->xmit_buf
[port
->xmit_head
++] = ch
;
1763 port
->xmit_head
&= SERIAL_XMIT_SIZE
- 1;
1765 spin_unlock_irqrestore(&port
->lock
, flags
);
1771 static void sx_flush_chars(struct tty_struct
* tty
)
1773 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1774 unsigned long flags
;
1775 struct specialix_board
* bp
= port_Board(port
);
1779 if (sx_paranoia_check(port
, tty
->name
, "sx_flush_chars")) {
1783 if (port
->xmit_cnt
<= 0 || tty
->stopped
|| tty
->hw_stopped
||
1788 spin_lock_irqsave(&bp
->lock
, flags
);
1789 port
->IER
|= IER_TXRDY
;
1790 sx_out(port_Board(port
), CD186x_CAR
, port_No(port
));
1791 sx_out(port_Board(port
), CD186x_IER
, port
->IER
);
1792 spin_unlock_irqrestore(&bp
->lock
, flags
);
1798 static int sx_write_room(struct tty_struct
* tty
)
1800 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1805 if (sx_paranoia_check(port
, tty
->name
, "sx_write_room")) {
1810 ret
= SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1;
1819 static int sx_chars_in_buffer(struct tty_struct
*tty
)
1821 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1825 if (sx_paranoia_check(port
, tty
->name
, "sx_chars_in_buffer")) {
1830 return port
->xmit_cnt
;
1834 static void sx_flush_buffer(struct tty_struct
*tty
)
1836 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1837 unsigned long flags
;
1838 struct specialix_board
* bp
;
1842 if (sx_paranoia_check(port
, tty
->name
, "sx_flush_buffer")) {
1847 bp
= port_Board(port
);
1848 spin_lock_irqsave(&port
->lock
, flags
);
1849 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1850 spin_unlock_irqrestore(&port
->lock
, flags
);
1857 static int sx_tiocmget(struct tty_struct
*tty
, struct file
*file
)
1859 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1860 struct specialix_board
* bp
;
1861 unsigned char status
;
1862 unsigned int result
;
1863 unsigned long flags
;
1867 if (sx_paranoia_check(port
, tty
->name
, __FUNCTION__
)) {
1872 bp
= port_Board(port
);
1873 spin_lock_irqsave (&bp
->lock
, flags
);
1874 sx_out(bp
, CD186x_CAR
, port_No(port
));
1875 status
= sx_in(bp
, CD186x_MSVR
);
1876 spin_unlock_irqrestore(&bp
->lock
, flags
);
1877 dprintk (SX_DEBUG_INIT
, "Got msvr[%d] = %02x, car = %d.\n",
1878 port_No(port
), status
, sx_in (bp
, CD186x_CAR
));
1879 dprintk (SX_DEBUG_INIT
, "sx_port = %p, port = %p\n", sx_port
, port
);
1880 if (SX_CRTSCTS(port
->tty
)) {
1881 result
= /* (status & MSVR_RTS) ? */ TIOCM_DTR
/* : 0) */
1882 | ((status
& MSVR_DTR
) ? TIOCM_RTS
: 0)
1883 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1884 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR
/* : 0) */
1885 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1887 result
= /* (status & MSVR_RTS) ? */ TIOCM_RTS
/* : 0) */
1888 | ((status
& MSVR_DTR
) ? TIOCM_DTR
: 0)
1889 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1890 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR
/* : 0) */
1891 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1900 static int sx_tiocmset(struct tty_struct
*tty
, struct file
*file
,
1901 unsigned int set
, unsigned int clear
)
1903 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1904 unsigned long flags
;
1905 struct specialix_board
*bp
;
1909 if (sx_paranoia_check(port
, tty
->name
, __FUNCTION__
)) {
1914 bp
= port_Board(port
);
1916 spin_lock_irqsave(&port
->lock
, flags
);
1917 /* if (set & TIOCM_RTS)
1918 port->MSVR |= MSVR_RTS; */
1919 /* if (set & TIOCM_DTR)
1920 port->MSVR |= MSVR_DTR; */
1922 if (SX_CRTSCTS(port
->tty
)) {
1923 if (set
& TIOCM_RTS
)
1924 port
->MSVR
|= MSVR_DTR
;
1926 if (set
& TIOCM_DTR
)
1927 port
->MSVR
|= MSVR_DTR
;
1930 /* if (clear & TIOCM_RTS)
1931 port->MSVR &= ~MSVR_RTS; */
1932 /* if (clear & TIOCM_DTR)
1933 port->MSVR &= ~MSVR_DTR; */
1934 if (SX_CRTSCTS(port
->tty
)) {
1935 if (clear
& TIOCM_RTS
)
1936 port
->MSVR
&= ~MSVR_DTR
;
1938 if (clear
& TIOCM_DTR
)
1939 port
->MSVR
&= ~MSVR_DTR
;
1941 spin_lock_irqsave(&bp
->lock
, flags
);
1942 sx_out(bp
, CD186x_CAR
, port_No(port
));
1943 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1944 spin_unlock_irqrestore(&bp
->lock
, flags
);
1945 spin_unlock_irqrestore(&port
->lock
, flags
);
1951 static inline void sx_send_break(struct specialix_port
* port
, unsigned long length
)
1953 struct specialix_board
*bp
= port_Board(port
);
1954 unsigned long flags
;
1958 spin_lock_irqsave (&port
->lock
, flags
);
1959 port
->break_length
= SPECIALIX_TPS
/ HZ
* length
;
1960 port
->COR2
|= COR2_ETC
;
1961 port
->IER
|= IER_TXRDY
;
1962 spin_lock_irqsave(&bp
->lock
, flags
);
1963 sx_out(bp
, CD186x_CAR
, port_No(port
));
1964 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1965 sx_out(bp
, CD186x_IER
, port
->IER
);
1966 spin_unlock_irqrestore(&bp
->lock
, flags
);
1967 spin_unlock_irqrestore (&port
->lock
, flags
);
1969 spin_lock_irqsave(&bp
->lock
, flags
);
1970 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
1971 spin_unlock_irqrestore(&bp
->lock
, flags
);
1978 static inline int sx_set_serial_info(struct specialix_port
* port
,
1979 struct serial_struct __user
* newinfo
)
1981 struct serial_struct tmp
;
1982 struct specialix_board
*bp
= port_Board(port
);
1987 if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1992 if (copy_from_user(&tmp
, newinfo
, sizeof(tmp
))) {
1998 if ((tmp
.irq
!= bp
->irq
) ||
1999 (tmp
.port
!= bp
->base
) ||
2000 (tmp
.type
!= PORT_CIRRUS
) ||
2001 (tmp
.baud_base
!= (SX_OSCFREQ
+ CD186x_TPC
/2) / CD186x_TPC
) ||
2002 (tmp
.custom_divisor
!= 0) ||
2003 (tmp
.xmit_fifo_size
!= CD186x_NFIFO
) ||
2004 (tmp
.flags
& ~SPECIALIX_LEGAL_FLAGS
)) {
2010 change_speed
= ((port
->flags
& ASYNC_SPD_MASK
) !=
2011 (tmp
.flags
& ASYNC_SPD_MASK
));
2012 change_speed
|= (tmp
.custom_divisor
!= port
->custom_divisor
);
2014 if (!capable(CAP_SYS_ADMIN
)) {
2015 if ((tmp
.close_delay
!= port
->close_delay
) ||
2016 (tmp
.closing_wait
!= port
->closing_wait
) ||
2017 ((tmp
.flags
& ~ASYNC_USR_MASK
) !=
2018 (port
->flags
& ~ASYNC_USR_MASK
))) {
2022 port
->flags
= ((port
->flags
& ~ASYNC_USR_MASK
) |
2023 (tmp
.flags
& ASYNC_USR_MASK
));
2024 port
->custom_divisor
= tmp
.custom_divisor
;
2026 port
->flags
= ((port
->flags
& ~ASYNC_FLAGS
) |
2027 (tmp
.flags
& ASYNC_FLAGS
));
2028 port
->close_delay
= tmp
.close_delay
;
2029 port
->closing_wait
= tmp
.closing_wait
;
2030 port
->custom_divisor
= tmp
.custom_divisor
;
2033 sx_change_speed(bp
, port
);
2040 static inline int sx_get_serial_info(struct specialix_port
* port
,
2041 struct serial_struct __user
*retinfo
)
2043 struct serial_struct tmp
;
2044 struct specialix_board
*bp
= port_Board(port
);
2049 if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
2053 memset(&tmp
, 0, sizeof(tmp
));
2054 tmp
.type
= PORT_CIRRUS
;
2055 tmp
.line
= port
- sx_port
;
2056 tmp
.port
= bp
->base
;
2058 tmp
.flags
= port
->flags
;
2059 tmp
.baud_base
= (SX_OSCFREQ
+ CD186x_TPC
/2) / CD186x_TPC
;
2060 tmp
.close_delay
= port
->close_delay
* HZ
/100;
2061 tmp
.closing_wait
= port
->closing_wait
* HZ
/100;
2062 tmp
.custom_divisor
= port
->custom_divisor
;
2063 tmp
.xmit_fifo_size
= CD186x_NFIFO
;
2064 if (copy_to_user(retinfo
, &tmp
, sizeof(tmp
))) {
2074 static int sx_ioctl(struct tty_struct
* tty
, struct file
* filp
,
2075 unsigned int cmd
, unsigned long arg
)
2077 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2079 void __user
*argp
= (void __user
*)arg
;
2083 if (sx_paranoia_check(port
, tty
->name
, "sx_ioctl")) {
2089 case TCSBRK
: /* SVID version: non-zero arg --> no break */
2090 retval
= tty_check_change(tty
);
2095 tty_wait_until_sent(tty
, 0);
2097 sx_send_break(port
, HZ
/4); /* 1/4 second */
2099 case TCSBRKP
: /* support for POSIX tcsendbreak() */
2100 retval
= tty_check_change(tty
);
2105 tty_wait_until_sent(tty
, 0);
2106 sx_send_break(port
, arg
? arg
*(HZ
/10) : HZ
/4);
2110 if (put_user(C_CLOCAL(tty
)?1:0, (unsigned long __user
*)argp
)) {
2117 if (get_user(arg
, (unsigned long __user
*) argp
)) {
2121 tty
->termios
->c_cflag
=
2122 ((tty
->termios
->c_cflag
& ~CLOCAL
) |
2123 (arg
? CLOCAL
: 0));
2128 return sx_get_serial_info(port
, argp
);
2131 return sx_set_serial_info(port
, argp
);
2134 return -ENOIOCTLCMD
;
2141 static void sx_throttle(struct tty_struct
* tty
)
2143 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2144 struct specialix_board
*bp
;
2145 unsigned long flags
;
2149 if (sx_paranoia_check(port
, tty
->name
, "sx_throttle")) {
2154 bp
= port_Board(port
);
2156 /* Use DTR instead of RTS ! */
2157 if (SX_CRTSCTS (tty
))
2158 port
->MSVR
&= ~MSVR_DTR
;
2160 /* Auch!!! I think the system shouldn't call this then. */
2161 /* Or maybe we're supposed (allowed?) to do our side of hw
2162 handshake anyway, even when hardware handshake is off.
2163 When you see this in your logs, please report.... */
2164 printk (KERN_ERR
"sx%d: Need to throttle, but can't (hardware hs is off)\n",
2167 spin_lock_irqsave(&bp
->lock
, flags
);
2168 sx_out(bp
, CD186x_CAR
, port_No(port
));
2169 spin_unlock_irqrestore(&bp
->lock
, flags
);
2171 spin_unlock_irqrestore(&bp
->lock
, flags
);
2173 spin_lock_irqsave(&bp
->lock
, flags
);
2174 sx_out(bp
, CD186x_CCR
, CCR_SSCH2
);
2175 spin_unlock_irqrestore(&bp
->lock
, flags
);
2178 spin_lock_irqsave(&bp
->lock
, flags
);
2179 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2180 spin_unlock_irqrestore(&bp
->lock
, flags
);
2186 static void sx_unthrottle(struct tty_struct
* tty
)
2188 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2189 struct specialix_board
*bp
;
2190 unsigned long flags
;
2194 if (sx_paranoia_check(port
, tty
->name
, "sx_unthrottle")) {
2199 bp
= port_Board(port
);
2201 spin_lock_irqsave(&port
->lock
, flags
);
2202 /* XXXX Use DTR INSTEAD???? */
2203 if (SX_CRTSCTS(tty
)) {
2204 port
->MSVR
|= MSVR_DTR
;
2205 } /* Else clause: see remark in "sx_throttle"... */
2206 spin_lock_irqsave(&bp
->lock
, flags
);
2207 sx_out(bp
, CD186x_CAR
, port_No(port
));
2208 spin_unlock_irqrestore(&bp
->lock
, flags
);
2210 spin_unlock_irqrestore(&port
->lock
, flags
);
2212 spin_lock_irqsave(&bp
->lock
, flags
);
2213 sx_out(bp
, CD186x_CCR
, CCR_SSCH1
);
2214 spin_unlock_irqrestore(&bp
->lock
, flags
);
2216 spin_lock_irqsave(&port
->lock
, flags
);
2218 spin_lock_irqsave(&bp
->lock
, flags
);
2219 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2220 spin_unlock_irqrestore(&bp
->lock
, flags
);
2221 spin_unlock_irqrestore(&port
->lock
, flags
);
2227 static void sx_stop(struct tty_struct
* tty
)
2229 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2230 struct specialix_board
*bp
;
2231 unsigned long flags
;
2235 if (sx_paranoia_check(port
, tty
->name
, "sx_stop")) {
2240 bp
= port_Board(port
);
2242 spin_lock_irqsave(&port
->lock
, flags
);
2243 port
->IER
&= ~IER_TXRDY
;
2244 spin_lock_irqsave(&bp
->lock
, flags
);
2245 sx_out(bp
, CD186x_CAR
, port_No(port
));
2246 sx_out(bp
, CD186x_IER
, port
->IER
);
2247 spin_unlock_irqrestore(&bp
->lock
, flags
);
2248 spin_unlock_irqrestore(&port
->lock
, flags
);
2254 static void sx_start(struct tty_struct
* tty
)
2256 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2257 struct specialix_board
*bp
;
2258 unsigned long flags
;
2262 if (sx_paranoia_check(port
, tty
->name
, "sx_start")) {
2267 bp
= port_Board(port
);
2269 spin_lock_irqsave(&port
->lock
, flags
);
2270 if (port
->xmit_cnt
&& port
->xmit_buf
&& !(port
->IER
& IER_TXRDY
)) {
2271 port
->IER
|= IER_TXRDY
;
2272 spin_lock_irqsave(&bp
->lock
, flags
);
2273 sx_out(bp
, CD186x_CAR
, port_No(port
));
2274 sx_out(bp
, CD186x_IER
, port
->IER
);
2275 spin_unlock_irqrestore(&bp
->lock
, flags
);
2277 spin_unlock_irqrestore(&port
->lock
, flags
);
2284 * This routine is called from the work-queue when the interrupt
2285 * routine has signalled that a hangup has occurred. The path of
2286 * hangup processing is:
2288 * serial interrupt routine -> (workqueue) ->
2289 * do_sx_hangup() -> tty->hangup() -> sx_hangup()
2292 static void do_sx_hangup(void *private_
)
2294 struct specialix_port
*port
= (struct specialix_port
*) private_
;
2295 struct tty_struct
*tty
;
2301 tty_hangup(tty
); /* FIXME: module removal race here */
2307 static void sx_hangup(struct tty_struct
* tty
)
2309 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2310 struct specialix_board
*bp
;
2311 unsigned long flags
;
2315 if (sx_paranoia_check(port
, tty
->name
, "sx_hangup")) {
2320 bp
= port_Board(port
);
2322 sx_shutdown_port(bp
, port
);
2323 spin_lock_irqsave(&port
->lock
, flags
);
2325 bp
->count
-= port
->count
;
2326 if (bp
->count
< 0) {
2327 printk(KERN_ERR
"sx%d: sx_hangup: bad board count: %d port: %d\n",
2328 board_No(bp
), bp
->count
, tty
->index
);
2332 port
->flags
&= ~ASYNC_NORMAL_ACTIVE
;
2334 spin_unlock_irqrestore(&port
->lock
, flags
);
2335 wake_up_interruptible(&port
->open_wait
);
2341 static void sx_set_termios(struct tty_struct
* tty
, struct termios
* old_termios
)
2343 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2344 unsigned long flags
;
2345 struct specialix_board
* bp
;
2347 if (sx_paranoia_check(port
, tty
->name
, "sx_set_termios"))
2350 if (tty
->termios
->c_cflag
== old_termios
->c_cflag
&&
2351 tty
->termios
->c_iflag
== old_termios
->c_iflag
)
2354 bp
= port_Board(port
);
2355 spin_lock_irqsave(&port
->lock
, flags
);
2356 sx_change_speed(port_Board(port
), port
);
2357 spin_unlock_irqrestore(&port
->lock
, flags
);
2359 if ((old_termios
->c_cflag
& CRTSCTS
) &&
2360 !(tty
->termios
->c_cflag
& CRTSCTS
)) {
2361 tty
->hw_stopped
= 0;
2367 static void do_softint(void *private_
)
2369 struct specialix_port
*port
= (struct specialix_port
*) private_
;
2370 struct tty_struct
*tty
;
2374 if(!(tty
= port
->tty
)) {
2379 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP
, &port
->event
)) {
2381 //wake_up_interruptible(&tty->write_wait);
2387 static struct tty_operations sx_ops
= {
2391 .put_char
= sx_put_char
,
2392 .flush_chars
= sx_flush_chars
,
2393 .write_room
= sx_write_room
,
2394 .chars_in_buffer
= sx_chars_in_buffer
,
2395 .flush_buffer
= sx_flush_buffer
,
2397 .throttle
= sx_throttle
,
2398 .unthrottle
= sx_unthrottle
,
2399 .set_termios
= sx_set_termios
,
2402 .hangup
= sx_hangup
,
2403 .tiocmget
= sx_tiocmget
,
2404 .tiocmset
= sx_tiocmset
,
2407 static int sx_init_drivers(void)
2414 specialix_driver
= alloc_tty_driver(SX_NBOARD
* SX_NPORT
);
2415 if (!specialix_driver
) {
2416 printk(KERN_ERR
"sx: Couldn't allocate tty_driver.\n");
2421 if (!(tmp_buf
= (unsigned char *) get_zeroed_page(GFP_KERNEL
))) {
2422 printk(KERN_ERR
"sx: Couldn't get free page.\n");
2423 put_tty_driver(specialix_driver
);
2427 specialix_driver
->owner
= THIS_MODULE
;
2428 specialix_driver
->name
= "ttyW";
2429 specialix_driver
->major
= SPECIALIX_NORMAL_MAJOR
;
2430 specialix_driver
->type
= TTY_DRIVER_TYPE_SERIAL
;
2431 specialix_driver
->subtype
= SERIAL_TYPE_NORMAL
;
2432 specialix_driver
->init_termios
= tty_std_termios
;
2433 specialix_driver
->init_termios
.c_cflag
=
2434 B9600
| CS8
| CREAD
| HUPCL
| CLOCAL
;
2435 specialix_driver
->flags
= TTY_DRIVER_REAL_RAW
;
2436 tty_set_operations(specialix_driver
, &sx_ops
);
2438 if ((error
= tty_register_driver(specialix_driver
))) {
2439 put_tty_driver(specialix_driver
);
2440 free_page((unsigned long)tmp_buf
);
2441 printk(KERN_ERR
"sx: Couldn't register specialix IO8+ driver, error = %d\n",
2446 memset(sx_port
, 0, sizeof(sx_port
));
2447 for (i
= 0; i
< SX_NPORT
* SX_NBOARD
; i
++) {
2448 sx_port
[i
].magic
= SPECIALIX_MAGIC
;
2449 INIT_WORK(&sx_port
[i
].tqueue
, do_softint
, &sx_port
[i
]);
2450 INIT_WORK(&sx_port
[i
].tqueue_hangup
, do_sx_hangup
, &sx_port
[i
]);
2451 sx_port
[i
].close_delay
= 50 * HZ
/100;
2452 sx_port
[i
].closing_wait
= 3000 * HZ
/100;
2453 init_waitqueue_head(&sx_port
[i
].open_wait
);
2454 init_waitqueue_head(&sx_port
[i
].close_wait
);
2455 spin_lock_init(&sx_port
[i
].lock
);
2462 static void sx_release_drivers(void)
2466 free_page((unsigned long)tmp_buf
);
2467 tty_unregister_driver(specialix_driver
);
2468 put_tty_driver(specialix_driver
);
2473 * This routine must be called by kernel at boot time
2475 static int __init
specialix_init(void)
2482 printk(KERN_INFO
"sx: Specialix IO8+ driver v" VERSION
", (c) R.E.Wolff 1997/1998.\n");
2483 printk(KERN_INFO
"sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2484 #ifdef CONFIG_SPECIALIX_RTSCTS
2485 printk (KERN_INFO
"sx: DTR/RTS pin is always RTS.\n");
2487 printk (KERN_INFO
"sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2490 for (i
= 0; i
< SX_NBOARD
; i
++)
2491 sx_board
[i
].lock
= SPIN_LOCK_UNLOCKED
;
2493 if (sx_init_drivers()) {
2498 for (i
= 0; i
< SX_NBOARD
; i
++)
2499 if (sx_board
[i
].base
&& !sx_probe(&sx_board
[i
]))
2504 struct pci_dev
*pdev
= NULL
;
2507 while (i
< SX_NBOARD
) {
2508 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
) {
2512 pdev
= pci_find_device (PCI_VENDOR_ID_SPECIALIX
,
2513 PCI_DEVICE_ID_SPECIALIX_IO8
,
2517 if (pci_enable_device(pdev
))
2520 sx_board
[i
].irq
= pdev
->irq
;
2522 sx_board
[i
].base
= pci_resource_start (pdev
, 2);
2524 sx_board
[i
].flags
|= SX_BOARD_IS_PCI
;
2525 if (!sx_probe(&sx_board
[i
]))
2532 sx_release_drivers();
2533 printk(KERN_INFO
"sx: No specialix IO8+ boards detected.\n");
2542 static int iobase
[SX_NBOARD
] = {0,};
2544 static int irq
[SX_NBOARD
] = {0,};
2546 module_param_array(iobase
, int, NULL
, 0);
2547 module_param_array(irq
, int, NULL
, 0);
2548 module_param(sx_debug
, int, 0);
2549 module_param(sx_rxfifo
, int, 0);
2550 #ifdef SPECIALIX_TIMER
2551 module_param(sx_poll
, int, 0);
2555 * You can setup up to 4 boards.
2556 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2557 * You should specify the IRQs too in that case "irq=....,...".
2559 * More than 4 boards in one computer is not possible, as the card can
2560 * only use 4 different interrupts.
2563 static int __init
specialix_init_module(void)
2569 init_MUTEX(&tmp_buf_sem
); /* Init de the semaphore - pvdl */
2571 if (iobase
[0] || iobase
[1] || iobase
[2] || iobase
[3]) {
2572 for(i
= 0; i
< SX_NBOARD
; i
++) {
2573 sx_board
[i
].base
= iobase
[i
];
2574 sx_board
[i
].irq
= irq
[i
];
2575 sx_board
[i
].count
= 0;
2581 return specialix_init();
2584 static void __exit
specialix_exit_module(void)
2590 sx_release_drivers();
2591 for (i
= 0; i
< SX_NBOARD
; i
++)
2592 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
)
2593 sx_release_io_range(&sx_board
[i
]);
2594 #ifdef SPECIALIX_TIMER
2595 del_timer (&missed_irq_timer
);
2601 module_init(specialix_init_module
);
2602 module_exit(specialix_exit_module
);
2604 MODULE_LICENSE("GPL");