2 * specialix.c -- specialix IO8+ multiport serial driver.
4 * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl)
5 * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com)
7 * Specialix pays for the development and support of this driver.
8 * Please DO contact io8-linux@specialix.co.uk if you require
9 * support. But please read the documentation (specialix.txt)
12 * This driver was developped in the BitWizard linux device
13 * driver service. If you require a linux device driver for your
14 * product, please contact devices@BitWizard.nl for a quote.
16 * This code is firmly based on the riscom/8 serial driver,
17 * written by Dmitry Gorodchanin. The specialix IO8+ card
18 * programming information was obtained from the CL-CD1865 Data
19 * Book, and Specialix document number 6200059: IO8+ Hardware
20 * Functional Specification.
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License as
24 * published by the Free Software Foundation; either version 2 of
25 * the License, or (at your option) any later version.
27 * This program is distributed in the hope that it will be
28 * useful, but WITHOUT ANY WARRANTY; without even the implied
29 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
30 * PURPOSE. See the GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public
33 * License along with this program; if not, write to the Free
34 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
39 * Revision 1.0: April 1st 1997.
40 * Initial release for alpha testing.
41 * Revision 1.1: April 14th 1997.
42 * Incorporated Richard Hudsons suggestions,
43 * removed some debugging printk's.
44 * Revision 1.2: April 15th 1997.
45 * Ported to 2.1.x kernels.
46 * Revision 1.3: April 17th 1997
47 * Backported to 2.0. (Compatibility macros).
48 * Revision 1.4: April 18th 1997
49 * Fixed DTR/RTS bug that caused the card to indicate
50 * "don't send data" to a modem after the password prompt.
51 * Fixed bug for premature (fake) interrupts.
52 * Revision 1.5: April 19th 1997
53 * fixed a minor typo in the header file, cleanup a little.
54 * performance warnings are now MAXed at once per minute.
55 * Revision 1.6: May 23 1997
56 * Changed the specialix=... format to include interrupt.
57 * Revision 1.7: May 27 1997
58 * Made many more debug printk's a compile time option.
59 * Revision 1.8: Jul 1 1997
60 * port to linux-2.1.43 kernel.
61 * Revision 1.9: Oct 9 1998
62 * Added stuff for the IO8+/PCI version.
63 * Revision 1.10: Oct 22 1999 / Jan 21 2000.
64 * Added stuff for setserial.
65 * Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr)
69 #define VERSION "1.11"
73 * There is a bunch of documentation about the card, jumpers, config
74 * settings, restrictions, cables, device names and numbers in
75 * Documentation/specialix.txt
78 #include <linux/module.h>
81 #include <linux/kernel.h>
82 #include <linux/sched.h>
83 #include <linux/ioport.h>
84 #include <linux/interrupt.h>
85 #include <linux/errno.h>
86 #include <linux/tty.h>
87 #include <linux/tty_flip.h>
89 #include <linux/serial.h>
90 #include <linux/fcntl.h>
91 #include <linux/major.h>
92 #include <linux/delay.h>
93 #include <linux/pci.h>
94 #include <linux/init.h>
95 #include <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
;
186 static struct specialix_board sx_board
[SX_NBOARD
] = {
187 { 0, SX_IOBASE1
, 9, },
188 { 0, SX_IOBASE2
, 11, },
189 { 0, SX_IOBASE3
, 12, },
190 { 0, SX_IOBASE4
, 15, },
193 static struct specialix_port sx_port
[SX_NBOARD
* SX_NPORT
];
196 #ifdef SPECIALIX_TIMER
197 static struct timer_list missed_irq_timer
;
198 static irqreturn_t
sx_interrupt(int irq
, void * dev_id
);
203 static inline int sx_paranoia_check(struct specialix_port
const * port
,
204 char *name
, const char *routine
)
206 #ifdef SPECIALIX_PARANOIA_CHECK
207 static const char *badmagic
=
208 KERN_ERR
"sx: Warning: bad specialix port magic number for device %s in %s\n";
209 static const char *badinfo
=
210 KERN_ERR
"sx: Warning: null specialix port for device %s in %s\n";
213 printk(badinfo
, name
, routine
);
216 if (port
->magic
!= SPECIALIX_MAGIC
) {
217 printk(badmagic
, name
, routine
);
227 * Service functions for specialix IO8+ driver.
231 /* Get board number from pointer */
232 static inline int board_No (struct specialix_board
* bp
)
234 return bp
- sx_board
;
238 /* Get port number from pointer */
239 static inline int port_No (struct specialix_port
const * port
)
241 return SX_PORT(port
- sx_port
);
245 /* Get pointer to board from pointer to port */
246 static inline struct specialix_board
* port_Board(struct specialix_port
const * port
)
248 return &sx_board
[SX_BOARD(port
- sx_port
)];
252 /* Input Byte from CL CD186x register */
253 static inline unsigned char sx_in(struct specialix_board
* bp
, unsigned short reg
)
255 bp
->reg
= reg
| 0x80;
256 outb (reg
| 0x80, bp
->base
+ SX_ADDR_REG
);
257 return inb (bp
->base
+ SX_DATA_REG
);
261 /* Output Byte to CL CD186x register */
262 static inline void sx_out(struct specialix_board
* bp
, unsigned short reg
,
265 bp
->reg
= reg
| 0x80;
266 outb (reg
| 0x80, bp
->base
+ SX_ADDR_REG
);
267 outb (val
, bp
->base
+ SX_DATA_REG
);
271 /* Input Byte from CL CD186x register */
272 static inline unsigned char sx_in_off(struct specialix_board
* bp
, unsigned short reg
)
275 outb (reg
, bp
->base
+ SX_ADDR_REG
);
276 return inb (bp
->base
+ SX_DATA_REG
);
280 /* Output Byte to CL CD186x register */
281 static inline void sx_out_off(struct specialix_board
* bp
, unsigned short reg
,
285 outb (reg
, bp
->base
+ SX_ADDR_REG
);
286 outb (val
, bp
->base
+ SX_DATA_REG
);
290 /* Wait for Channel Command Register ready */
291 static inline void sx_wait_CCR(struct specialix_board
* bp
)
293 unsigned long delay
, flags
;
296 for (delay
= SX_CCR_TIMEOUT
; delay
; delay
--) {
297 spin_lock_irqsave(&bp
->lock
, flags
);
298 ccr
= sx_in(bp
, CD186x_CCR
);
299 spin_unlock_irqrestore(&bp
->lock
, flags
);
305 printk(KERN_ERR
"sx%d: Timeout waiting for CCR.\n", board_No(bp
));
309 /* Wait for Channel Command Register ready */
310 static inline void sx_wait_CCR_off(struct specialix_board
* bp
)
316 for (delay
= SX_CCR_TIMEOUT
; delay
; delay
--) {
317 spin_lock_irqsave(&bp
->lock
, flags
);
318 crr
= sx_in_off(bp
, CD186x_CCR
);
319 spin_unlock_irqrestore(&bp
->lock
, flags
);
325 printk(KERN_ERR
"sx%d: Timeout waiting for CCR.\n", board_No(bp
));
330 * specialix IO8+ IO range functions.
333 static inline int sx_request_io_range(struct specialix_board
* bp
)
335 return request_region(bp
->base
,
336 bp
->flags
& SX_BOARD_IS_PCI
? SX_PCI_IO_SPACE
: SX_IO_SPACE
,
337 "specialix IO8+") == NULL
;
341 static inline void sx_release_io_range(struct specialix_board
* bp
)
343 release_region(bp
->base
,
344 bp
->flags
&SX_BOARD_IS_PCI
?SX_PCI_IO_SPACE
:SX_IO_SPACE
);
348 /* Must be called with enabled interrupts */
349 /* Ugly. Very ugly. Don't use this for anything else than initialization
351 static inline void sx_long_delay(unsigned long delay
)
355 for (i
= jiffies
+ delay
; time_after(i
, jiffies
); ) ;
360 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
361 static int sx_set_irq ( struct specialix_board
*bp
)
367 if (bp
->flags
& SX_BOARD_IS_PCI
)
370 /* In the same order as in the docs... */
371 case 15: virq
= 0;break;
372 case 12: virq
= 1;break;
373 case 11: virq
= 2;break;
374 case 9: virq
= 3;break;
375 default: printk (KERN_ERR
"Speclialix: cannot set irq to %d.\n", bp
->irq
);
378 spin_lock_irqsave(&bp
->lock
, flags
);
380 sx_out(bp
, CD186x_CAR
, i
);
381 sx_out(bp
, CD186x_MSVRTS
, ((virq
>> i
) & 0x1)? MSVR_RTS
:0);
383 spin_unlock_irqrestore(&bp
->lock
, flags
);
388 /* Reset and setup CD186x chip */
389 static int sx_init_CD186x(struct specialix_board
* bp
)
396 sx_wait_CCR_off(bp
); /* Wait for CCR ready */
397 spin_lock_irqsave(&bp
->lock
, flags
);
398 sx_out_off(bp
, CD186x_CCR
, CCR_HARDRESET
); /* Reset CD186x chip */
399 spin_unlock_irqrestore(&bp
->lock
, flags
);
400 sx_long_delay(HZ
/20); /* Delay 0.05 sec */
401 spin_lock_irqsave(&bp
->lock
, flags
);
402 sx_out_off(bp
, CD186x_GIVR
, SX_ID
); /* Set ID for this chip */
403 sx_out_off(bp
, CD186x_GICR
, 0); /* Clear all bits */
404 sx_out_off(bp
, CD186x_PILR1
, SX_ACK_MINT
); /* Prio for modem intr */
405 sx_out_off(bp
, CD186x_PILR2
, SX_ACK_TINT
); /* Prio for transmitter intr */
406 sx_out_off(bp
, CD186x_PILR3
, SX_ACK_RINT
); /* Prio for receiver intr */
408 sx_out_off(bp
, CD186x_SRCR
, sx_in (bp
, CD186x_SRCR
) | SRCR_REGACKEN
);
410 /* Setting up prescaler. We need 4 ticks per 1 ms */
411 scaler
= SX_OSCFREQ
/SPECIALIX_TPS
;
413 sx_out_off(bp
, CD186x_PPRH
, scaler
>> 8);
414 sx_out_off(bp
, CD186x_PPRL
, scaler
& 0xff);
415 spin_unlock_irqrestore(&bp
->lock
, flags
);
417 if (!sx_set_irq (bp
)) {
418 /* Figure out how to pass this along... */
419 printk (KERN_ERR
"Cannot set irq to %d.\n", bp
->irq
);
428 static int read_cross_byte (struct specialix_board
*bp
, int reg
, int bit
)
434 spin_lock_irqsave(&bp
->lock
, flags
);
435 for (i
=0, t
=0;i
<8;i
++) {
436 sx_out_off (bp
, CD186x_CAR
, i
);
437 if (sx_in_off (bp
, reg
) & bit
)
440 spin_unlock_irqrestore(&bp
->lock
, flags
);
446 #ifdef SPECIALIX_TIMER
447 void missed_irq (unsigned long data
)
451 struct specialix_board
*bp
= (struct specialix_board
*)data
;
453 spin_lock_irqsave(&bp
->lock
, flags
);
454 irq
= sx_in ((struct specialix_board
*)data
, CD186x_SRSR
) &
458 spin_unlock_irqrestore(&bp
->lock
, flags
);
460 printk (KERN_INFO
"Missed interrupt... Calling int from timer. \n");
461 sx_interrupt (((struct specialix_board
*)data
)->irq
,
464 mod_timer(&missed_irq_timer
, jiffies
+ sx_poll
);
470 /* Main probing routine, also sets irq. */
471 static int sx_probe(struct specialix_board
*bp
)
473 unsigned char val1
, val2
;
483 if (sx_request_io_range(bp
)) {
488 /* Are the I/O ports here ? */
489 sx_out_off(bp
, CD186x_PPRL
, 0x5a);
491 val1
= sx_in_off(bp
, CD186x_PPRL
);
493 sx_out_off(bp
, CD186x_PPRL
, 0xa5);
495 val2
= sx_in_off(bp
, CD186x_PPRL
);
498 if ((val1
!= 0x5a) || (val2
!= 0xa5)) {
499 printk(KERN_INFO
"sx%d: specialix IO8+ Board at 0x%03x not found.\n",
500 board_No(bp
), bp
->base
);
501 sx_release_io_range(bp
);
506 /* Check the DSR lines that Specialix uses as board
508 val1
= read_cross_byte (bp
, CD186x_MSVR
, MSVR_DSR
);
509 val2
= read_cross_byte (bp
, CD186x_MSVR
, MSVR_RTS
);
510 dprintk (SX_DEBUG_INIT
, "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
511 board_No(bp
), val1
, val2
);
513 /* They managed to switch the bit order between the docs and
514 the IO8+ card. The new PCI card now conforms to old docs.
515 They changed the PCI docs to reflect the situation on the
517 val2
= (bp
->flags
& SX_BOARD_IS_PCI
)?0x4d : 0xb2;
519 printk(KERN_INFO
"sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
520 board_No(bp
), val2
, bp
->base
, val1
);
521 sx_release_io_range(bp
);
528 /* It's time to find IRQ for this board */
529 for (retries
= 0; retries
< 5 && irqs
<= 0; retries
++) {
530 irqs
= probe_irq_on();
531 sx_init_CD186x(bp
); /* Reset CD186x chip */
532 sx_out(bp
, CD186x_CAR
, 2); /* Select port 2 */
534 sx_out(bp
, CD186x_CCR
, CCR_TXEN
); /* Enable transmitter */
535 sx_out(bp
, CD186x_IER
, IER_TXRDY
); /* Enable tx empty intr */
536 sx_long_delay(HZ
/20);
537 irqs
= probe_irq_off(irqs
);
539 dprintk (SX_DEBUG_INIT
, "SRSR = %02x, ", sx_in(bp
, CD186x_SRSR
));
540 dprintk (SX_DEBUG_INIT
, "TRAR = %02x, ", sx_in(bp
, CD186x_TRAR
));
541 dprintk (SX_DEBUG_INIT
, "GIVR = %02x, ", sx_in(bp
, CD186x_GIVR
));
542 dprintk (SX_DEBUG_INIT
, "GICR = %02x, ", sx_in(bp
, CD186x_GICR
));
543 dprintk (SX_DEBUG_INIT
, "\n");
545 /* Reset CD186x again */
546 if (!sx_init_CD186x(bp
)) {
547 /* Hmmm. This is dead code anyway. */
550 dprintk (SX_DEBUG_INIT
"val1 = %02x, val2 = %02x, val3 = %02x.\n",
557 printk(KERN_ERR
"sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
558 board_No(bp
), bp
->base
);
559 sx_release_io_range(bp
);
564 printk (KERN_INFO
"Started with irq=%d, but now have irq=%d.\n", bp
->irq
, irqs
);
568 /* Reset CD186x again */
569 if (!sx_init_CD186x(bp
)) {
570 sx_release_io_range(bp
);
575 sx_request_io_range(bp
);
576 bp
->flags
|= SX_BOARD_PRESENT
;
578 /* Chip revcode pkgtype
583 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
585 -- Thanks to Gwen Wang, Cirrus Logic.
588 switch (sx_in_off(bp
, CD186x_GFRCR
)) {
589 case 0x82:chip
= 1864;rev
='A';break;
590 case 0x83:chip
= 1865;rev
='A';break;
591 case 0x84:chip
= 1865;rev
='B';break;
592 case 0x85:chip
= 1865;rev
='C';break; /* Does not exist at this time */
593 default:chip
=-1;rev
='x';
596 dprintk (SX_DEBUG_INIT
, " GFCR = 0x%02x\n", sx_in_off(bp
, CD186x_GFRCR
) );
598 #ifdef SPECIALIX_TIMER
599 setup_timer(&missed_irq_timer
, missed_irq
, (unsigned long)bp
);
600 mod_timer(&missed_irq_timer
, jiffies
+ sx_poll
);
603 printk(KERN_INFO
"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
614 * Interrupt processing routines.
617 static inline void sx_mark_event(struct specialix_port
* port
, int event
)
621 set_bit(event
, &port
->event
);
622 schedule_work(&port
->tqueue
);
628 static inline struct specialix_port
* sx_get_port(struct specialix_board
* bp
,
629 unsigned char const * what
)
631 unsigned char channel
;
632 struct specialix_port
* port
= NULL
;
634 channel
= sx_in(bp
, CD186x_GICR
) >> GICR_CHAN_OFF
;
635 dprintk (SX_DEBUG_CHAN
, "channel: %d\n", channel
);
636 if (channel
< CD186x_NCH
) {
637 port
= &sx_port
[board_No(bp
) * SX_NPORT
+ channel
];
638 dprintk (SX_DEBUG_CHAN
, "port: %d %p flags: 0x%x\n",board_No(bp
) * SX_NPORT
+ channel
, port
, port
->flags
& ASYNC_INITIALIZED
);
640 if (port
->flags
& ASYNC_INITIALIZED
) {
641 dprintk (SX_DEBUG_CHAN
, "port: %d %p\n", channel
, port
);
646 printk(KERN_INFO
"sx%d: %s interrupt from invalid port %d\n",
647 board_No(bp
), what
, channel
);
652 static inline void sx_receive_exc(struct specialix_board
* bp
)
654 struct specialix_port
*port
;
655 struct tty_struct
*tty
;
656 unsigned char status
;
657 unsigned char ch
, flag
;
661 port
= sx_get_port(bp
, "Receive");
663 dprintk (SX_DEBUG_RX
, "Hmm, couldn't find port.\n");
669 status
= sx_in(bp
, CD186x_RCSR
);
671 dprintk (SX_DEBUG_RX
, "status: 0x%x\n", status
);
672 if (status
& RCSR_OE
) {
674 dprintk(SX_DEBUG_FIFO
, "sx%d: port %d: Overrun. Total %ld overruns.\n",
675 board_No(bp
), port_No(port
), port
->overrun
);
677 status
&= port
->mark_mask
;
679 /* This flip buffer check needs to be below the reading of the
680 status register to reset the chip's IRQ.... */
681 if (tty_buffer_request_room(tty
, 1) == 0) {
682 dprintk(SX_DEBUG_FIFO
, "sx%d: port %d: Working around flip buffer overflow.\n",
683 board_No(bp
), port_No(port
));
688 ch
= sx_in(bp
, CD186x_RDR
);
693 if (status
& RCSR_TOUT
) {
694 printk(KERN_INFO
"sx%d: port %d: Receiver timeout. Hardware problems ?\n",
695 board_No(bp
), port_No(port
));
699 } else if (status
& RCSR_BREAK
) {
700 dprintk(SX_DEBUG_RX
, "sx%d: port %d: Handling break...\n",
701 board_No(bp
), port_No(port
));
703 if (port
->flags
& ASYNC_SAK
)
706 } else if (status
& RCSR_PE
)
709 else if (status
& RCSR_FE
)
712 else if (status
& RCSR_OE
)
718 if(tty_insert_flip_char(tty
, ch
, flag
))
719 tty_flip_buffer_push(tty
);
724 static inline void sx_receive(struct specialix_board
* bp
)
726 struct specialix_port
*port
;
727 struct tty_struct
*tty
;
732 if (!(port
= sx_get_port(bp
, "Receive"))) {
733 dprintk (SX_DEBUG_RX
, "Hmm, couldn't find port.\n");
739 count
= sx_in(bp
, CD186x_RDCR
);
740 dprintk (SX_DEBUG_RX
, "port: %p: count: %d\n", port
, count
);
741 port
->hits
[count
> 8 ? 9 : count
]++;
743 tty_buffer_request_room(tty
, count
);
746 tty_insert_flip_char(tty
, sx_in(bp
, CD186x_RDR
), TTY_NORMAL
);
747 tty_flip_buffer_push(tty
);
752 static inline void sx_transmit(struct specialix_board
* bp
)
754 struct specialix_port
*port
;
755 struct tty_struct
*tty
;
759 if (!(port
= sx_get_port(bp
, "Transmit"))) {
763 dprintk (SX_DEBUG_TX
, "port: %p\n", port
);
766 if (port
->IER
& IER_TXEMPTY
) {
768 sx_out(bp
, CD186x_CAR
, port_No(port
));
769 port
->IER
&= ~IER_TXEMPTY
;
770 sx_out(bp
, CD186x_IER
, port
->IER
);
775 if ((port
->xmit_cnt
<= 0 && !port
->break_length
)
776 || tty
->stopped
|| tty
->hw_stopped
) {
777 sx_out(bp
, CD186x_CAR
, port_No(port
));
778 port
->IER
&= ~IER_TXRDY
;
779 sx_out(bp
, CD186x_IER
, port
->IER
);
784 if (port
->break_length
) {
785 if (port
->break_length
> 0) {
786 if (port
->COR2
& COR2_ETC
) {
787 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
788 sx_out(bp
, CD186x_TDR
, CD186x_C_SBRK
);
789 port
->COR2
&= ~COR2_ETC
;
791 count
= min_t(int, port
->break_length
, 0xff);
792 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
793 sx_out(bp
, CD186x_TDR
, CD186x_C_DELAY
);
794 sx_out(bp
, CD186x_TDR
, count
);
795 if (!(port
->break_length
-= count
))
796 port
->break_length
--;
798 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
799 sx_out(bp
, CD186x_TDR
, CD186x_C_EBRK
);
800 sx_out(bp
, CD186x_COR2
, port
->COR2
);
802 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
803 port
->break_length
= 0;
810 count
= CD186x_NFIFO
;
812 sx_out(bp
, CD186x_TDR
, port
->xmit_buf
[port
->xmit_tail
++]);
813 port
->xmit_tail
= port
->xmit_tail
& (SERIAL_XMIT_SIZE
-1);
814 if (--port
->xmit_cnt
<= 0)
816 } while (--count
> 0);
818 if (port
->xmit_cnt
<= 0) {
819 sx_out(bp
, CD186x_CAR
, port_No(port
));
820 port
->IER
&= ~IER_TXRDY
;
821 sx_out(bp
, CD186x_IER
, port
->IER
);
823 if (port
->xmit_cnt
<= port
->wakeup_chars
)
824 sx_mark_event(port
, RS_EVENT_WRITE_WAKEUP
);
830 static inline void sx_check_modem(struct specialix_board
* bp
)
832 struct specialix_port
*port
;
833 struct tty_struct
*tty
;
837 dprintk (SX_DEBUG_SIGNALS
, "Modem intr. ");
838 if (!(port
= sx_get_port(bp
, "Modem")))
843 mcr
= sx_in(bp
, CD186x_MCR
);
844 printk ("mcr = %02x.\n", mcr
);
846 if ((mcr
& MCR_CDCHG
)) {
847 dprintk (SX_DEBUG_SIGNALS
, "CD just changed... ");
848 msvr_cd
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
850 dprintk (SX_DEBUG_SIGNALS
, "Waking up guys in open.\n");
851 wake_up_interruptible(&port
->open_wait
);
853 dprintk (SX_DEBUG_SIGNALS
, "Sending HUP.\n");
854 schedule_work(&port
->tqueue_hangup
);
858 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
859 if (mcr
& MCR_CTSCHG
) {
860 if (sx_in(bp
, CD186x_MSVR
) & MSVR_CTS
) {
862 port
->IER
|= IER_TXRDY
;
863 if (port
->xmit_cnt
<= port
->wakeup_chars
)
864 sx_mark_event(port
, RS_EVENT_WRITE_WAKEUP
);
867 port
->IER
&= ~IER_TXRDY
;
869 sx_out(bp
, CD186x_IER
, port
->IER
);
871 if (mcr
& MCR_DSSXHG
) {
872 if (sx_in(bp
, CD186x_MSVR
) & MSVR_DSR
) {
874 port
->IER
|= IER_TXRDY
;
875 if (port
->xmit_cnt
<= port
->wakeup_chars
)
876 sx_mark_event(port
, RS_EVENT_WRITE_WAKEUP
);
879 port
->IER
&= ~IER_TXRDY
;
881 sx_out(bp
, CD186x_IER
, port
->IER
);
883 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
885 /* Clear change bits */
886 sx_out(bp
, CD186x_MCR
, 0);
890 /* The main interrupt processing routine */
891 static irqreturn_t
sx_interrupt(int irq
, void *dev_id
)
893 unsigned char status
;
895 struct specialix_board
*bp
;
896 unsigned long loop
= 0;
903 spin_lock_irqsave(&bp
->lock
, flags
);
905 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);
906 if (!(bp
->flags
& SX_BOARD_ACTIVE
)) {
907 dprintk (SX_DEBUG_IRQ
, "sx: False interrupt. irq %d.\n", irq
);
908 spin_unlock_irqrestore(&bp
->lock
, flags
);
915 while ((++loop
< 16) && (status
= (sx_in(bp
, CD186x_SRSR
) &
919 if (status
& SRSR_RREQint
) {
920 ack
= sx_in(bp
, CD186x_RRAR
);
922 if (ack
== (SX_ID
| GIVR_IT_RCV
))
924 else if (ack
== (SX_ID
| GIVR_IT_REXC
))
927 printk(KERN_ERR
"sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
928 board_No(bp
), status
, ack
);
930 } else if (status
& SRSR_TREQint
) {
931 ack
= sx_in(bp
, CD186x_TRAR
);
933 if (ack
== (SX_ID
| GIVR_IT_TX
))
936 printk(KERN_ERR
"sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
937 board_No(bp
), status
, ack
, port_No (sx_get_port (bp
, "Int")));
938 } else if (status
& SRSR_MREQint
) {
939 ack
= sx_in(bp
, CD186x_MRAR
);
941 if (ack
== (SX_ID
| GIVR_IT_MODEM
))
944 printk(KERN_ERR
"sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
945 board_No(bp
), status
, ack
);
949 sx_out(bp
, CD186x_EOIR
, 0); /* Mark end of interrupt */
952 outb (bp
->reg
, bp
->base
+ SX_ADDR_REG
);
953 spin_unlock_irqrestore(&bp
->lock
, flags
);
960 * Routines for open & close processing.
963 static void turn_ints_off (struct specialix_board
*bp
)
968 if (bp
->flags
& SX_BOARD_IS_PCI
) {
969 /* This was intended for enabeling the interrupt on the
970 * PCI card. However it seems that it's already enabled
971 * and as PCI interrupts can be shared, there is no real
972 * reason to have to turn it off. */
975 spin_lock_irqsave(&bp
->lock
, flags
);
976 (void) sx_in_off (bp
, 0); /* Turn off interrupts. */
977 spin_unlock_irqrestore(&bp
->lock
, flags
);
982 static void turn_ints_on (struct specialix_board
*bp
)
988 if (bp
->flags
& SX_BOARD_IS_PCI
) {
989 /* play with the PCI chip. See comment above. */
991 spin_lock_irqsave(&bp
->lock
, flags
);
992 (void) sx_in (bp
, 0); /* Turn ON interrupts. */
993 spin_unlock_irqrestore(&bp
->lock
, flags
);
999 /* Called with disabled interrupts */
1000 static inline int sx_setup_board(struct specialix_board
* bp
)
1004 if (bp
->flags
& SX_BOARD_ACTIVE
)
1007 if (bp
->flags
& SX_BOARD_IS_PCI
)
1008 error
= request_irq(bp
->irq
, sx_interrupt
, IRQF_DISABLED
| IRQF_SHARED
, "specialix IO8+", bp
);
1010 error
= request_irq(bp
->irq
, sx_interrupt
, IRQF_DISABLED
, "specialix IO8+", bp
);
1016 bp
->flags
|= SX_BOARD_ACTIVE
;
1022 /* Called with disabled interrupts */
1023 static inline void sx_shutdown_board(struct specialix_board
*bp
)
1027 if (!(bp
->flags
& SX_BOARD_ACTIVE
)) {
1032 bp
->flags
&= ~SX_BOARD_ACTIVE
;
1034 dprintk (SX_DEBUG_IRQ
, "Freeing IRQ%d for board %d.\n",
1035 bp
->irq
, board_No (bp
));
1036 free_irq(bp
->irq
, bp
);
1046 * Setting up port characteristics.
1047 * Must be called with disabled interrupts
1049 static void sx_change_speed(struct specialix_board
*bp
, struct specialix_port
*port
)
1051 struct tty_struct
*tty
;
1054 unsigned char cor1
= 0, cor3
= 0;
1055 unsigned char mcor1
= 0, mcor2
= 0;
1056 static unsigned long again
;
1057 unsigned long flags
;
1061 if (!(tty
= port
->tty
) || !tty
->termios
) {
1068 /* Select port on the board */
1069 spin_lock_irqsave(&bp
->lock
, flags
);
1070 sx_out(bp
, CD186x_CAR
, port_No(port
));
1072 /* The Specialix board doens't implement the RTS lines.
1073 They are used to set the IRQ level. Don't touch them. */
1074 if (SX_CRTSCTS(tty
))
1075 port
->MSVR
= MSVR_DTR
| (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
1077 port
->MSVR
= (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
1078 spin_unlock_irqrestore(&bp
->lock
, flags
);
1079 dprintk (SX_DEBUG_TERMIOS
, "sx: got MSVR=%02x.\n", port
->MSVR
);
1080 baud
= tty_get_baud_rate(tty
);
1082 if (baud
== 38400) {
1083 if ((port
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_HI
)
1085 if ((port
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_VHI
)
1090 /* Drop DTR & exit */
1091 dprintk (SX_DEBUG_TERMIOS
, "Dropping DTR... Hmm....\n");
1092 if (!SX_CRTSCTS (tty
)) {
1093 port
-> MSVR
&= ~ MSVR_DTR
;
1094 spin_lock_irqsave(&bp
->lock
, flags
);
1095 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1096 spin_unlock_irqrestore(&bp
->lock
, flags
);
1099 dprintk (SX_DEBUG_TERMIOS
, "Can't drop DTR: no DTR.\n");
1103 if (!SX_CRTSCTS (tty
)) {
1104 port
->MSVR
|= MSVR_DTR
;
1109 * Now we must calculate some speed depended things
1112 /* Set baud rate for port */
1113 tmp
= port
->custom_divisor
;
1115 printk (KERN_INFO
"sx%d: Using custom baud rate divisor %ld. \n"
1116 "This is an untested option, please be carefull.\n",
1117 port_No (port
), tmp
);
1119 tmp
= (((SX_OSCFREQ
+ baud
/2) / baud
+
1120 CD186x_TPC
/2) / CD186x_TPC
);
1122 if ((tmp
< 0x10) && time_before(again
, jiffies
)) {
1123 again
= jiffies
+ HZ
* 60;
1124 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1126 printk (KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1127 "Performance degradation is possible.\n"
1128 "Read specialix.txt for more info.\n",
1129 port_No (port
), tmp
);
1131 printk (KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1132 "Warning: overstressing Cirrus chip. "
1133 "This might not work.\n"
1134 "Read specialix.txt for more info.\n",
1135 port_No (port
), tmp
);
1138 spin_lock_irqsave(&bp
->lock
, flags
);
1139 sx_out(bp
, CD186x_RBPRH
, (tmp
>> 8) & 0xff);
1140 sx_out(bp
, CD186x_TBPRH
, (tmp
>> 8) & 0xff);
1141 sx_out(bp
, CD186x_RBPRL
, tmp
& 0xff);
1142 sx_out(bp
, CD186x_TBPRL
, tmp
& 0xff);
1143 spin_unlock_irqrestore(&bp
->lock
, flags
);
1144 if (port
->custom_divisor
)
1145 baud
= (SX_OSCFREQ
+ port
->custom_divisor
/2) / port
->custom_divisor
;
1146 baud
= (baud
+ 5) / 10; /* Estimated CPS */
1148 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1149 tmp
= ((baud
+ HZ
/2) / HZ
) * 2 - CD186x_NFIFO
;
1150 port
->wakeup_chars
= (tmp
< 0) ? 0 : ((tmp
>= SERIAL_XMIT_SIZE
) ?
1151 SERIAL_XMIT_SIZE
- 1 : tmp
);
1153 /* Receiver timeout will be transmission time for 1.5 chars */
1154 tmp
= (SPECIALIX_TPS
+ SPECIALIX_TPS
/2 + baud
/2) / baud
;
1155 tmp
= (tmp
> 0xff) ? 0xff : tmp
;
1156 spin_lock_irqsave(&bp
->lock
, flags
);
1157 sx_out(bp
, CD186x_RTPR
, tmp
);
1158 spin_unlock_irqrestore(&bp
->lock
, flags
);
1159 switch (C_CSIZE(tty
)) {
1177 cor1
|= COR1_IGNORE
;
1178 if (C_PARENB(tty
)) {
1179 cor1
|= COR1_NORMPAR
;
1183 cor1
&= ~COR1_IGNORE
;
1185 /* Set marking of some errors */
1186 port
->mark_mask
= RCSR_OE
| RCSR_TOUT
;
1188 port
->mark_mask
|= RCSR_FE
| RCSR_PE
;
1189 if (I_BRKINT(tty
) || I_PARMRK(tty
))
1190 port
->mark_mask
|= RCSR_BREAK
;
1192 port
->mark_mask
&= ~(RCSR_FE
| RCSR_PE
);
1193 if (I_IGNBRK(tty
)) {
1194 port
->mark_mask
&= ~RCSR_BREAK
;
1196 /* Real raw mode. Ignore all */
1197 port
->mark_mask
&= ~RCSR_OE
;
1199 /* Enable Hardware Flow Control */
1200 if (C_CRTSCTS(tty
)) {
1201 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1202 port
->IER
|= IER_DSR
| IER_CTS
;
1203 mcor1
|= MCOR1_DSRZD
| MCOR1_CTSZD
;
1204 mcor2
|= MCOR2_DSROD
| MCOR2_CTSOD
;
1205 spin_lock_irqsave(&bp
->lock
, flags
);
1206 tty
->hw_stopped
= !(sx_in(bp
, CD186x_MSVR
) & (MSVR_CTS
|MSVR_DSR
));
1207 spin_unlock_irqrestore(&bp
->lock
, flags
);
1209 port
->COR2
|= COR2_CTSAE
;
1212 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1213 /* Some people reported that it works, but I still doubt it */
1215 port
->COR2
|= COR2_TXIBE
;
1216 cor3
|= (COR3_FCT
| COR3_SCDE
);
1218 port
->COR2
|= COR2_IXM
;
1219 spin_lock_irqsave(&bp
->lock
, flags
);
1220 sx_out(bp
, CD186x_SCHR1
, START_CHAR(tty
));
1221 sx_out(bp
, CD186x_SCHR2
, STOP_CHAR(tty
));
1222 sx_out(bp
, CD186x_SCHR3
, START_CHAR(tty
));
1223 sx_out(bp
, CD186x_SCHR4
, STOP_CHAR(tty
));
1224 spin_unlock_irqrestore(&bp
->lock
, flags
);
1226 if (!C_CLOCAL(tty
)) {
1227 /* Enable CD check */
1228 port
->IER
|= IER_CD
;
1229 mcor1
|= MCOR1_CDZD
;
1230 mcor2
|= MCOR2_CDOD
;
1234 /* Enable receiver */
1235 port
->IER
|= IER_RXD
;
1237 /* Set input FIFO size (1-8 bytes) */
1239 /* Setting up CD186x channel registers */
1240 spin_lock_irqsave(&bp
->lock
, flags
);
1241 sx_out(bp
, CD186x_COR1
, cor1
);
1242 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1243 sx_out(bp
, CD186x_COR3
, cor3
);
1244 spin_unlock_irqrestore(&bp
->lock
, flags
);
1245 /* Make CD186x know about registers change */
1247 spin_lock_irqsave(&bp
->lock
, flags
);
1248 sx_out(bp
, CD186x_CCR
, CCR_CORCHG1
| CCR_CORCHG2
| CCR_CORCHG3
);
1249 /* Setting up modem option registers */
1250 dprintk (SX_DEBUG_TERMIOS
, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1
, mcor2
);
1251 sx_out(bp
, CD186x_MCOR1
, mcor1
);
1252 sx_out(bp
, CD186x_MCOR2
, mcor2
);
1253 spin_unlock_irqrestore(&bp
->lock
, flags
);
1254 /* Enable CD186x transmitter & receiver */
1256 spin_lock_irqsave(&bp
->lock
, flags
);
1257 sx_out(bp
, CD186x_CCR
, CCR_TXEN
| CCR_RXEN
);
1258 /* Enable interrupts */
1259 sx_out(bp
, CD186x_IER
, port
->IER
);
1260 /* And finally set the modem lines... */
1261 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1262 spin_unlock_irqrestore(&bp
->lock
, flags
);
1268 /* Must be called with interrupts enabled */
1269 static int sx_setup_port(struct specialix_board
*bp
, struct specialix_port
*port
)
1271 unsigned long flags
;
1275 if (port
->flags
& ASYNC_INITIALIZED
) {
1280 if (!port
->xmit_buf
) {
1281 /* We may sleep in get_zeroed_page() */
1284 if (!(tmp
= get_zeroed_page(GFP_KERNEL
))) {
1289 if (port
->xmit_buf
) {
1292 return -ERESTARTSYS
;
1294 port
->xmit_buf
= (unsigned char *) tmp
;
1297 spin_lock_irqsave(&port
->lock
, flags
);
1300 clear_bit(TTY_IO_ERROR
, &port
->tty
->flags
);
1302 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1303 sx_change_speed(bp
, port
);
1304 port
->flags
|= ASYNC_INITIALIZED
;
1306 spin_unlock_irqrestore(&port
->lock
, flags
);
1314 /* Must be called with interrupts disabled */
1315 static void sx_shutdown_port(struct specialix_board
*bp
, struct specialix_port
*port
)
1317 struct tty_struct
*tty
;
1319 unsigned long flags
;
1323 if (!(port
->flags
& ASYNC_INITIALIZED
)) {
1328 if (sx_debug
& SX_DEBUG_FIFO
) {
1329 dprintk(SX_DEBUG_FIFO
, "sx%d: port %d: %ld overruns, FIFO hits [ ",
1330 board_No(bp
), port_No(port
), port
->overrun
);
1331 for (i
= 0; i
< 10; i
++) {
1332 dprintk(SX_DEBUG_FIFO
, "%ld ", port
->hits
[i
]);
1334 dprintk(SX_DEBUG_FIFO
, "].\n");
1337 if (port
->xmit_buf
) {
1338 free_page((unsigned long) port
->xmit_buf
);
1339 port
->xmit_buf
= NULL
;
1343 spin_lock_irqsave(&bp
->lock
, flags
);
1344 sx_out(bp
, CD186x_CAR
, port_No(port
));
1346 if (!(tty
= port
->tty
) || C_HUPCL(tty
)) {
1348 sx_out(bp
, CD186x_MSVDTR
, 0);
1350 spin_unlock_irqrestore(&bp
->lock
, flags
);
1353 spin_lock_irqsave(&bp
->lock
, flags
);
1354 sx_out(bp
, CD186x_CCR
, CCR_SOFTRESET
);
1355 /* Disable all interrupts from this port */
1357 sx_out(bp
, CD186x_IER
, port
->IER
);
1358 spin_unlock_irqrestore(&bp
->lock
, flags
);
1360 set_bit(TTY_IO_ERROR
, &tty
->flags
);
1361 port
->flags
&= ~ASYNC_INITIALIZED
;
1364 sx_shutdown_board(bp
);
1369 static int block_til_ready(struct tty_struct
*tty
, struct file
* filp
,
1370 struct specialix_port
*port
)
1372 DECLARE_WAITQUEUE(wait
, current
);
1373 struct specialix_board
*bp
= port_Board(port
);
1377 unsigned long flags
;
1382 * If the device is in the middle of being closed, then block
1383 * until it's done, and then try again.
1385 if (tty_hung_up_p(filp
) || port
->flags
& ASYNC_CLOSING
) {
1386 interruptible_sleep_on(&port
->close_wait
);
1387 if (port
->flags
& ASYNC_HUP_NOTIFY
) {
1392 return -ERESTARTSYS
;
1397 * If non-blocking mode is set, or the port is not enabled,
1398 * then make the check up front and then exit.
1400 if ((filp
->f_flags
& O_NONBLOCK
) ||
1401 (tty
->flags
& (1 << TTY_IO_ERROR
))) {
1402 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
1411 * Block waiting for the carrier detect and the line to become
1412 * free (i.e., not in use by the callout). While we are in
1413 * this loop, info->count is dropped by one, so that
1414 * rs_close() knows when to free things. We restore it upon
1415 * exit, either normal or abnormal.
1418 add_wait_queue(&port
->open_wait
, &wait
);
1419 spin_lock_irqsave(&port
->lock
, flags
);
1420 if (!tty_hung_up_p(filp
)) {
1423 spin_unlock_irqrestore(&port
->lock
, flags
);
1424 port
->blocked_open
++;
1426 spin_lock_irqsave(&bp
->lock
, flags
);
1427 sx_out(bp
, CD186x_CAR
, port_No(port
));
1428 CD
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
1429 if (SX_CRTSCTS (tty
)) {
1431 port
->MSVR
|= MSVR_DTR
; /* WTF? */
1432 sx_out (bp
, CD186x_MSVR
, port
->MSVR
);
1435 port
->MSVR
|= MSVR_DTR
;
1436 sx_out (bp
, CD186x_MSVR
, port
->MSVR
);
1438 spin_unlock_irqrestore(&bp
->lock
, flags
);
1439 set_current_state(TASK_INTERRUPTIBLE
);
1440 if (tty_hung_up_p(filp
) ||
1441 !(port
->flags
& ASYNC_INITIALIZED
)) {
1442 if (port
->flags
& ASYNC_HUP_NOTIFY
)
1445 retval
= -ERESTARTSYS
;
1448 if (!(port
->flags
& ASYNC_CLOSING
) &&
1451 if (signal_pending(current
)) {
1452 retval
= -ERESTARTSYS
;
1458 set_current_state(TASK_RUNNING
);
1459 remove_wait_queue(&port
->open_wait
, &wait
);
1460 spin_lock_irqsave(&port
->lock
, flags
);
1461 if (!tty_hung_up_p(filp
)) {
1464 port
->blocked_open
--;
1465 spin_unlock_irqrestore(&port
->lock
, flags
);
1471 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
1477 static int sx_open(struct tty_struct
* tty
, struct file
* filp
)
1481 struct specialix_port
* port
;
1482 struct specialix_board
* bp
;
1484 unsigned long flags
;
1488 board
= SX_BOARD(tty
->index
);
1490 if (board
>= SX_NBOARD
|| !(sx_board
[board
].flags
& SX_BOARD_PRESENT
)) {
1495 bp
= &sx_board
[board
];
1496 port
= sx_port
+ board
* SX_NPORT
+ SX_PORT(tty
->index
);
1498 for (i
= 0; i
< 10; i
++)
1501 dprintk (SX_DEBUG_OPEN
, "Board = %d, bp = %p, port = %p, portno = %d.\n",
1502 board
, bp
, port
, SX_PORT(tty
->index
));
1504 if (sx_paranoia_check(port
, tty
->name
, "sx_open")) {
1509 if ((error
= sx_setup_board(bp
))) {
1514 spin_lock_irqsave(&bp
->lock
, flags
);
1517 tty
->driver_data
= port
;
1519 spin_unlock_irqrestore(&bp
->lock
, flags
);
1521 if ((error
= sx_setup_port(bp
, port
))) {
1526 if ((error
= block_til_ready(tty
, filp
, port
))) {
1536 static void sx_close(struct tty_struct
* tty
, struct file
* filp
)
1538 struct specialix_port
*port
= (struct specialix_port
*) tty
->driver_data
;
1539 struct specialix_board
*bp
;
1540 unsigned long flags
;
1541 unsigned long timeout
;
1544 if (!port
|| sx_paranoia_check(port
, tty
->name
, "close")) {
1548 spin_lock_irqsave(&port
->lock
, flags
);
1550 if (tty_hung_up_p(filp
)) {
1551 spin_unlock_irqrestore(&port
->lock
, flags
);
1556 bp
= port_Board(port
);
1557 if ((tty
->count
== 1) && (port
->count
!= 1)) {
1558 printk(KERN_ERR
"sx%d: sx_close: bad port count;"
1559 " tty->count is 1, port count is %d\n",
1560 board_No(bp
), port
->count
);
1564 if (port
->count
> 1) {
1568 spin_unlock_irqrestore(&port
->lock
, flags
);
1573 port
->flags
|= ASYNC_CLOSING
;
1575 * Now we wait for the transmit buffer to clear; and we notify
1576 * the line discipline to only process XON/XOFF characters.
1579 spin_unlock_irqrestore(&port
->lock
, flags
);
1580 dprintk (SX_DEBUG_OPEN
, "Closing\n");
1581 if (port
->closing_wait
!= ASYNC_CLOSING_WAIT_NONE
) {
1582 tty_wait_until_sent(tty
, port
->closing_wait
);
1585 * At this point we stop accepting input. To do this, we
1586 * disable the receive line status interrupts, and tell the
1587 * interrupt driver to stop checking the data ready bit in the
1588 * line status register.
1590 dprintk (SX_DEBUG_OPEN
, "Closed\n");
1591 port
->IER
&= ~IER_RXD
;
1592 if (port
->flags
& ASYNC_INITIALIZED
) {
1593 port
->IER
&= ~IER_TXRDY
;
1594 port
->IER
|= IER_TXEMPTY
;
1595 spin_lock_irqsave(&bp
->lock
, flags
);
1596 sx_out(bp
, CD186x_CAR
, port_No(port
));
1597 sx_out(bp
, CD186x_IER
, port
->IER
);
1598 spin_unlock_irqrestore(&bp
->lock
, flags
);
1600 * Before we drop DTR, make sure the UART transmitter
1601 * has completely drained; this is especially
1602 * important if there is a transmit FIFO!
1604 timeout
= jiffies
+HZ
;
1605 while(port
->IER
& IER_TXEMPTY
) {
1606 set_current_state (TASK_INTERRUPTIBLE
);
1607 msleep_interruptible(jiffies_to_msecs(port
->timeout
));
1608 if (time_after(jiffies
, timeout
)) {
1609 printk (KERN_INFO
"Timeout waiting for close\n");
1616 if (--bp
->count
< 0) {
1617 printk(KERN_ERR
"sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1618 board_No(bp
), bp
->count
, tty
->index
);
1621 if (--port
->count
< 0) {
1622 printk(KERN_ERR
"sx%d: sx_close: bad port count for tty%d: %d\n",
1623 board_No(bp
), port_No(port
), port
->count
);
1627 sx_shutdown_port(bp
, port
);
1628 if (tty
->driver
->flush_buffer
)
1629 tty
->driver
->flush_buffer(tty
);
1630 tty_ldisc_flush(tty
);
1631 spin_lock_irqsave(&port
->lock
, flags
);
1635 spin_unlock_irqrestore(&port
->lock
, flags
);
1636 if (port
->blocked_open
) {
1637 if (port
->close_delay
) {
1638 msleep_interruptible(jiffies_to_msecs(port
->close_delay
));
1640 wake_up_interruptible(&port
->open_wait
);
1642 port
->flags
&= ~(ASYNC_NORMAL_ACTIVE
|ASYNC_CLOSING
);
1643 wake_up_interruptible(&port
->close_wait
);
1649 static int sx_write(struct tty_struct
* tty
,
1650 const unsigned char *buf
, int count
)
1652 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1653 struct specialix_board
*bp
;
1655 unsigned long flags
;
1658 if (sx_paranoia_check(port
, tty
->name
, "sx_write")) {
1663 bp
= port_Board(port
);
1665 if (!port
->xmit_buf
) {
1671 spin_lock_irqsave(&port
->lock
, flags
);
1672 c
= min_t(int, count
, min(SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1,
1673 SERIAL_XMIT_SIZE
- port
->xmit_head
));
1675 spin_unlock_irqrestore(&port
->lock
, flags
);
1678 memcpy(port
->xmit_buf
+ port
->xmit_head
, buf
, c
);
1679 port
->xmit_head
= (port
->xmit_head
+ c
) & (SERIAL_XMIT_SIZE
-1);
1680 port
->xmit_cnt
+= c
;
1681 spin_unlock_irqrestore(&port
->lock
, flags
);
1688 spin_lock_irqsave(&bp
->lock
, flags
);
1689 if (port
->xmit_cnt
&& !tty
->stopped
&& !tty
->hw_stopped
&&
1690 !(port
->IER
& IER_TXRDY
)) {
1691 port
->IER
|= IER_TXRDY
;
1692 sx_out(bp
, CD186x_CAR
, port_No(port
));
1693 sx_out(bp
, CD186x_IER
, port
->IER
);
1695 spin_unlock_irqrestore(&bp
->lock
, flags
);
1702 static void sx_put_char(struct tty_struct
* tty
, unsigned char ch
)
1704 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1705 unsigned long flags
;
1706 struct specialix_board
* bp
;
1710 if (sx_paranoia_check(port
, tty
->name
, "sx_put_char")) {
1714 dprintk (SX_DEBUG_TX
, "check tty: %p %p\n", tty
, port
->xmit_buf
);
1715 if (!port
->xmit_buf
) {
1719 bp
= port_Board(port
);
1720 spin_lock_irqsave(&port
->lock
, flags
);
1722 dprintk (SX_DEBUG_TX
, "xmit_cnt: %d xmit_buf: %p\n", port
->xmit_cnt
, port
->xmit_buf
);
1723 if ((port
->xmit_cnt
>= SERIAL_XMIT_SIZE
- 1) || (!port
->xmit_buf
)) {
1724 spin_unlock_irqrestore(&port
->lock
, flags
);
1725 dprintk (SX_DEBUG_TX
, "Exit size\n");
1729 dprintk (SX_DEBUG_TX
, "Handle xmit: %p %p\n", port
, port
->xmit_buf
);
1730 port
->xmit_buf
[port
->xmit_head
++] = ch
;
1731 port
->xmit_head
&= SERIAL_XMIT_SIZE
- 1;
1733 spin_unlock_irqrestore(&port
->lock
, flags
);
1739 static void sx_flush_chars(struct tty_struct
* tty
)
1741 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1742 unsigned long flags
;
1743 struct specialix_board
* bp
= port_Board(port
);
1747 if (sx_paranoia_check(port
, tty
->name
, "sx_flush_chars")) {
1751 if (port
->xmit_cnt
<= 0 || tty
->stopped
|| tty
->hw_stopped
||
1756 spin_lock_irqsave(&bp
->lock
, flags
);
1757 port
->IER
|= IER_TXRDY
;
1758 sx_out(port_Board(port
), CD186x_CAR
, port_No(port
));
1759 sx_out(port_Board(port
), CD186x_IER
, port
->IER
);
1760 spin_unlock_irqrestore(&bp
->lock
, flags
);
1766 static int sx_write_room(struct tty_struct
* tty
)
1768 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1773 if (sx_paranoia_check(port
, tty
->name
, "sx_write_room")) {
1778 ret
= SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1;
1787 static int sx_chars_in_buffer(struct tty_struct
*tty
)
1789 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1793 if (sx_paranoia_check(port
, tty
->name
, "sx_chars_in_buffer")) {
1798 return port
->xmit_cnt
;
1802 static void sx_flush_buffer(struct tty_struct
*tty
)
1804 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1805 unsigned long flags
;
1806 struct specialix_board
* bp
;
1810 if (sx_paranoia_check(port
, tty
->name
, "sx_flush_buffer")) {
1815 bp
= port_Board(port
);
1816 spin_lock_irqsave(&port
->lock
, flags
);
1817 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1818 spin_unlock_irqrestore(&port
->lock
, flags
);
1825 static int sx_tiocmget(struct tty_struct
*tty
, struct file
*file
)
1827 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1828 struct specialix_board
* bp
;
1829 unsigned char status
;
1830 unsigned int result
;
1831 unsigned long flags
;
1835 if (sx_paranoia_check(port
, tty
->name
, __FUNCTION__
)) {
1840 bp
= port_Board(port
);
1841 spin_lock_irqsave (&bp
->lock
, flags
);
1842 sx_out(bp
, CD186x_CAR
, port_No(port
));
1843 status
= sx_in(bp
, CD186x_MSVR
);
1844 spin_unlock_irqrestore(&bp
->lock
, flags
);
1845 dprintk (SX_DEBUG_INIT
, "Got msvr[%d] = %02x, car = %d.\n",
1846 port_No(port
), status
, sx_in (bp
, CD186x_CAR
));
1847 dprintk (SX_DEBUG_INIT
, "sx_port = %p, port = %p\n", sx_port
, port
);
1848 if (SX_CRTSCTS(port
->tty
)) {
1849 result
= /* (status & MSVR_RTS) ? */ TIOCM_DTR
/* : 0) */
1850 | ((status
& MSVR_DTR
) ? TIOCM_RTS
: 0)
1851 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1852 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR
/* : 0) */
1853 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1855 result
= /* (status & MSVR_RTS) ? */ TIOCM_RTS
/* : 0) */
1856 | ((status
& MSVR_DTR
) ? TIOCM_DTR
: 0)
1857 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1858 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR
/* : 0) */
1859 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1868 static int sx_tiocmset(struct tty_struct
*tty
, struct file
*file
,
1869 unsigned int set
, unsigned int clear
)
1871 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1872 unsigned long flags
;
1873 struct specialix_board
*bp
;
1877 if (sx_paranoia_check(port
, tty
->name
, __FUNCTION__
)) {
1882 bp
= port_Board(port
);
1884 spin_lock_irqsave(&port
->lock
, flags
);
1885 /* if (set & TIOCM_RTS)
1886 port->MSVR |= MSVR_RTS; */
1887 /* if (set & TIOCM_DTR)
1888 port->MSVR |= MSVR_DTR; */
1890 if (SX_CRTSCTS(port
->tty
)) {
1891 if (set
& TIOCM_RTS
)
1892 port
->MSVR
|= MSVR_DTR
;
1894 if (set
& TIOCM_DTR
)
1895 port
->MSVR
|= MSVR_DTR
;
1898 /* if (clear & TIOCM_RTS)
1899 port->MSVR &= ~MSVR_RTS; */
1900 /* if (clear & TIOCM_DTR)
1901 port->MSVR &= ~MSVR_DTR; */
1902 if (SX_CRTSCTS(port
->tty
)) {
1903 if (clear
& TIOCM_RTS
)
1904 port
->MSVR
&= ~MSVR_DTR
;
1906 if (clear
& TIOCM_DTR
)
1907 port
->MSVR
&= ~MSVR_DTR
;
1909 spin_lock_irqsave(&bp
->lock
, flags
);
1910 sx_out(bp
, CD186x_CAR
, port_No(port
));
1911 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1912 spin_unlock_irqrestore(&bp
->lock
, flags
);
1913 spin_unlock_irqrestore(&port
->lock
, flags
);
1919 static inline void sx_send_break(struct specialix_port
* port
, unsigned long length
)
1921 struct specialix_board
*bp
= port_Board(port
);
1922 unsigned long flags
;
1926 spin_lock_irqsave (&port
->lock
, flags
);
1927 port
->break_length
= SPECIALIX_TPS
/ HZ
* length
;
1928 port
->COR2
|= COR2_ETC
;
1929 port
->IER
|= IER_TXRDY
;
1930 spin_lock_irqsave(&bp
->lock
, flags
);
1931 sx_out(bp
, CD186x_CAR
, port_No(port
));
1932 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1933 sx_out(bp
, CD186x_IER
, port
->IER
);
1934 spin_unlock_irqrestore(&bp
->lock
, flags
);
1935 spin_unlock_irqrestore (&port
->lock
, flags
);
1937 spin_lock_irqsave(&bp
->lock
, flags
);
1938 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
1939 spin_unlock_irqrestore(&bp
->lock
, flags
);
1946 static inline int sx_set_serial_info(struct specialix_port
* port
,
1947 struct serial_struct __user
* newinfo
)
1949 struct serial_struct tmp
;
1950 struct specialix_board
*bp
= port_Board(port
);
1955 if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1960 if (copy_from_user(&tmp
, newinfo
, sizeof(tmp
))) {
1966 if ((tmp
.irq
!= bp
->irq
) ||
1967 (tmp
.port
!= bp
->base
) ||
1968 (tmp
.type
!= PORT_CIRRUS
) ||
1969 (tmp
.baud_base
!= (SX_OSCFREQ
+ CD186x_TPC
/2) / CD186x_TPC
) ||
1970 (tmp
.custom_divisor
!= 0) ||
1971 (tmp
.xmit_fifo_size
!= CD186x_NFIFO
) ||
1972 (tmp
.flags
& ~SPECIALIX_LEGAL_FLAGS
)) {
1978 change_speed
= ((port
->flags
& ASYNC_SPD_MASK
) !=
1979 (tmp
.flags
& ASYNC_SPD_MASK
));
1980 change_speed
|= (tmp
.custom_divisor
!= port
->custom_divisor
);
1982 if (!capable(CAP_SYS_ADMIN
)) {
1983 if ((tmp
.close_delay
!= port
->close_delay
) ||
1984 (tmp
.closing_wait
!= port
->closing_wait
) ||
1985 ((tmp
.flags
& ~ASYNC_USR_MASK
) !=
1986 (port
->flags
& ~ASYNC_USR_MASK
))) {
1990 port
->flags
= ((port
->flags
& ~ASYNC_USR_MASK
) |
1991 (tmp
.flags
& ASYNC_USR_MASK
));
1992 port
->custom_divisor
= tmp
.custom_divisor
;
1994 port
->flags
= ((port
->flags
& ~ASYNC_FLAGS
) |
1995 (tmp
.flags
& ASYNC_FLAGS
));
1996 port
->close_delay
= tmp
.close_delay
;
1997 port
->closing_wait
= tmp
.closing_wait
;
1998 port
->custom_divisor
= tmp
.custom_divisor
;
2001 sx_change_speed(bp
, port
);
2008 static inline int sx_get_serial_info(struct specialix_port
* port
,
2009 struct serial_struct __user
*retinfo
)
2011 struct serial_struct tmp
;
2012 struct specialix_board
*bp
= port_Board(port
);
2017 if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
2021 memset(&tmp
, 0, sizeof(tmp
));
2022 tmp
.type
= PORT_CIRRUS
;
2023 tmp
.line
= port
- sx_port
;
2024 tmp
.port
= bp
->base
;
2026 tmp
.flags
= port
->flags
;
2027 tmp
.baud_base
= (SX_OSCFREQ
+ CD186x_TPC
/2) / CD186x_TPC
;
2028 tmp
.close_delay
= port
->close_delay
* HZ
/100;
2029 tmp
.closing_wait
= port
->closing_wait
* HZ
/100;
2030 tmp
.custom_divisor
= port
->custom_divisor
;
2031 tmp
.xmit_fifo_size
= CD186x_NFIFO
;
2032 if (copy_to_user(retinfo
, &tmp
, sizeof(tmp
))) {
2042 static int sx_ioctl(struct tty_struct
* tty
, struct file
* filp
,
2043 unsigned int cmd
, unsigned long arg
)
2045 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2047 void __user
*argp
= (void __user
*)arg
;
2051 if (sx_paranoia_check(port
, tty
->name
, "sx_ioctl")) {
2057 case TCSBRK
: /* SVID version: non-zero arg --> no break */
2058 retval
= tty_check_change(tty
);
2063 tty_wait_until_sent(tty
, 0);
2065 sx_send_break(port
, HZ
/4); /* 1/4 second */
2067 case TCSBRKP
: /* support for POSIX tcsendbreak() */
2068 retval
= tty_check_change(tty
);
2073 tty_wait_until_sent(tty
, 0);
2074 sx_send_break(port
, arg
? arg
*(HZ
/10) : HZ
/4);
2078 if (put_user(C_CLOCAL(tty
)?1:0, (unsigned long __user
*)argp
)) {
2085 if (get_user(arg
, (unsigned long __user
*) argp
)) {
2089 tty
->termios
->c_cflag
=
2090 ((tty
->termios
->c_cflag
& ~CLOCAL
) |
2091 (arg
? CLOCAL
: 0));
2096 return sx_get_serial_info(port
, argp
);
2099 return sx_set_serial_info(port
, argp
);
2102 return -ENOIOCTLCMD
;
2109 static void sx_throttle(struct tty_struct
* tty
)
2111 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2112 struct specialix_board
*bp
;
2113 unsigned long flags
;
2117 if (sx_paranoia_check(port
, tty
->name
, "sx_throttle")) {
2122 bp
= port_Board(port
);
2124 /* Use DTR instead of RTS ! */
2125 if (SX_CRTSCTS (tty
))
2126 port
->MSVR
&= ~MSVR_DTR
;
2128 /* Auch!!! I think the system shouldn't call this then. */
2129 /* Or maybe we're supposed (allowed?) to do our side of hw
2130 handshake anyway, even when hardware handshake is off.
2131 When you see this in your logs, please report.... */
2132 printk (KERN_ERR
"sx%d: Need to throttle, but can't (hardware hs is off)\n",
2135 spin_lock_irqsave(&bp
->lock
, flags
);
2136 sx_out(bp
, CD186x_CAR
, port_No(port
));
2137 spin_unlock_irqrestore(&bp
->lock
, flags
);
2139 spin_unlock_irqrestore(&bp
->lock
, flags
);
2141 spin_lock_irqsave(&bp
->lock
, flags
);
2142 sx_out(bp
, CD186x_CCR
, CCR_SSCH2
);
2143 spin_unlock_irqrestore(&bp
->lock
, flags
);
2146 spin_lock_irqsave(&bp
->lock
, flags
);
2147 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2148 spin_unlock_irqrestore(&bp
->lock
, flags
);
2154 static void sx_unthrottle(struct tty_struct
* tty
)
2156 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2157 struct specialix_board
*bp
;
2158 unsigned long flags
;
2162 if (sx_paranoia_check(port
, tty
->name
, "sx_unthrottle")) {
2167 bp
= port_Board(port
);
2169 spin_lock_irqsave(&port
->lock
, flags
);
2170 /* XXXX Use DTR INSTEAD???? */
2171 if (SX_CRTSCTS(tty
)) {
2172 port
->MSVR
|= MSVR_DTR
;
2173 } /* Else clause: see remark in "sx_throttle"... */
2174 spin_lock_irqsave(&bp
->lock
, flags
);
2175 sx_out(bp
, CD186x_CAR
, port_No(port
));
2176 spin_unlock_irqrestore(&bp
->lock
, flags
);
2178 spin_unlock_irqrestore(&port
->lock
, flags
);
2180 spin_lock_irqsave(&bp
->lock
, flags
);
2181 sx_out(bp
, CD186x_CCR
, CCR_SSCH1
);
2182 spin_unlock_irqrestore(&bp
->lock
, flags
);
2184 spin_lock_irqsave(&port
->lock
, flags
);
2186 spin_lock_irqsave(&bp
->lock
, flags
);
2187 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2188 spin_unlock_irqrestore(&bp
->lock
, flags
);
2189 spin_unlock_irqrestore(&port
->lock
, flags
);
2195 static void sx_stop(struct tty_struct
* tty
)
2197 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2198 struct specialix_board
*bp
;
2199 unsigned long flags
;
2203 if (sx_paranoia_check(port
, tty
->name
, "sx_stop")) {
2208 bp
= port_Board(port
);
2210 spin_lock_irqsave(&port
->lock
, flags
);
2211 port
->IER
&= ~IER_TXRDY
;
2212 spin_lock_irqsave(&bp
->lock
, flags
);
2213 sx_out(bp
, CD186x_CAR
, port_No(port
));
2214 sx_out(bp
, CD186x_IER
, port
->IER
);
2215 spin_unlock_irqrestore(&bp
->lock
, flags
);
2216 spin_unlock_irqrestore(&port
->lock
, flags
);
2222 static void sx_start(struct tty_struct
* tty
)
2224 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2225 struct specialix_board
*bp
;
2226 unsigned long flags
;
2230 if (sx_paranoia_check(port
, tty
->name
, "sx_start")) {
2235 bp
= port_Board(port
);
2237 spin_lock_irqsave(&port
->lock
, flags
);
2238 if (port
->xmit_cnt
&& port
->xmit_buf
&& !(port
->IER
& IER_TXRDY
)) {
2239 port
->IER
|= IER_TXRDY
;
2240 spin_lock_irqsave(&bp
->lock
, flags
);
2241 sx_out(bp
, CD186x_CAR
, port_No(port
));
2242 sx_out(bp
, CD186x_IER
, port
->IER
);
2243 spin_unlock_irqrestore(&bp
->lock
, flags
);
2245 spin_unlock_irqrestore(&port
->lock
, flags
);
2252 * This routine is called from the work-queue when the interrupt
2253 * routine has signalled that a hangup has occurred. The path of
2254 * hangup processing is:
2256 * serial interrupt routine -> (workqueue) ->
2257 * do_sx_hangup() -> tty->hangup() -> sx_hangup()
2260 static void do_sx_hangup(struct work_struct
*work
)
2262 struct specialix_port
*port
=
2263 container_of(work
, struct specialix_port
, tqueue_hangup
);
2264 struct tty_struct
*tty
;
2270 tty_hangup(tty
); /* FIXME: module removal race here */
2276 static void sx_hangup(struct tty_struct
* tty
)
2278 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2279 struct specialix_board
*bp
;
2280 unsigned long flags
;
2284 if (sx_paranoia_check(port
, tty
->name
, "sx_hangup")) {
2289 bp
= port_Board(port
);
2291 sx_shutdown_port(bp
, port
);
2292 spin_lock_irqsave(&port
->lock
, flags
);
2294 bp
->count
-= port
->count
;
2295 if (bp
->count
< 0) {
2296 printk(KERN_ERR
"sx%d: sx_hangup: bad board count: %d port: %d\n",
2297 board_No(bp
), bp
->count
, tty
->index
);
2301 port
->flags
&= ~ASYNC_NORMAL_ACTIVE
;
2303 spin_unlock_irqrestore(&port
->lock
, flags
);
2304 wake_up_interruptible(&port
->open_wait
);
2310 static void sx_set_termios(struct tty_struct
* tty
, struct ktermios
* old_termios
)
2312 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2313 unsigned long flags
;
2314 struct specialix_board
* bp
;
2316 if (sx_paranoia_check(port
, tty
->name
, "sx_set_termios"))
2319 if (tty
->termios
->c_cflag
== old_termios
->c_cflag
&&
2320 tty
->termios
->c_iflag
== old_termios
->c_iflag
)
2323 bp
= port_Board(port
);
2324 spin_lock_irqsave(&port
->lock
, flags
);
2325 sx_change_speed(port_Board(port
), port
);
2326 spin_unlock_irqrestore(&port
->lock
, flags
);
2328 if ((old_termios
->c_cflag
& CRTSCTS
) &&
2329 !(tty
->termios
->c_cflag
& CRTSCTS
)) {
2330 tty
->hw_stopped
= 0;
2336 static void do_softint(struct work_struct
*work
)
2338 struct specialix_port
*port
=
2339 container_of(work
, struct specialix_port
, tqueue
);
2340 struct tty_struct
*tty
;
2344 if(!(tty
= port
->tty
)) {
2349 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP
, &port
->event
))
2355 static const struct tty_operations sx_ops
= {
2359 .put_char
= sx_put_char
,
2360 .flush_chars
= sx_flush_chars
,
2361 .write_room
= sx_write_room
,
2362 .chars_in_buffer
= sx_chars_in_buffer
,
2363 .flush_buffer
= sx_flush_buffer
,
2365 .throttle
= sx_throttle
,
2366 .unthrottle
= sx_unthrottle
,
2367 .set_termios
= sx_set_termios
,
2370 .hangup
= sx_hangup
,
2371 .tiocmget
= sx_tiocmget
,
2372 .tiocmset
= sx_tiocmset
,
2375 static int sx_init_drivers(void)
2382 specialix_driver
= alloc_tty_driver(SX_NBOARD
* SX_NPORT
);
2383 if (!specialix_driver
) {
2384 printk(KERN_ERR
"sx: Couldn't allocate tty_driver.\n");
2389 specialix_driver
->owner
= THIS_MODULE
;
2390 specialix_driver
->name
= "ttyW";
2391 specialix_driver
->major
= SPECIALIX_NORMAL_MAJOR
;
2392 specialix_driver
->type
= TTY_DRIVER_TYPE_SERIAL
;
2393 specialix_driver
->subtype
= SERIAL_TYPE_NORMAL
;
2394 specialix_driver
->init_termios
= tty_std_termios
;
2395 specialix_driver
->init_termios
.c_cflag
=
2396 B9600
| CS8
| CREAD
| HUPCL
| CLOCAL
;
2397 specialix_driver
->init_termios
.c_ispeed
= 9600;
2398 specialix_driver
->init_termios
.c_ospeed
= 9600;
2399 specialix_driver
->flags
= TTY_DRIVER_REAL_RAW
;
2400 tty_set_operations(specialix_driver
, &sx_ops
);
2402 if ((error
= tty_register_driver(specialix_driver
))) {
2403 put_tty_driver(specialix_driver
);
2404 printk(KERN_ERR
"sx: Couldn't register specialix IO8+ driver, error = %d\n",
2409 memset(sx_port
, 0, sizeof(sx_port
));
2410 for (i
= 0; i
< SX_NPORT
* SX_NBOARD
; i
++) {
2411 sx_port
[i
].magic
= SPECIALIX_MAGIC
;
2412 INIT_WORK(&sx_port
[i
].tqueue
, do_softint
);
2413 INIT_WORK(&sx_port
[i
].tqueue_hangup
, do_sx_hangup
);
2414 sx_port
[i
].close_delay
= 50 * HZ
/100;
2415 sx_port
[i
].closing_wait
= 3000 * HZ
/100;
2416 init_waitqueue_head(&sx_port
[i
].open_wait
);
2417 init_waitqueue_head(&sx_port
[i
].close_wait
);
2418 spin_lock_init(&sx_port
[i
].lock
);
2425 static void sx_release_drivers(void)
2429 tty_unregister_driver(specialix_driver
);
2430 put_tty_driver(specialix_driver
);
2435 * This routine must be called by kernel at boot time
2437 static int __init
specialix_init(void)
2444 printk(KERN_INFO
"sx: Specialix IO8+ driver v" VERSION
", (c) R.E.Wolff 1997/1998.\n");
2445 printk(KERN_INFO
"sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2446 #ifdef CONFIG_SPECIALIX_RTSCTS
2447 printk (KERN_INFO
"sx: DTR/RTS pin is always RTS.\n");
2449 printk (KERN_INFO
"sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2452 for (i
= 0; i
< SX_NBOARD
; i
++)
2453 spin_lock_init(&sx_board
[i
].lock
);
2455 if (sx_init_drivers()) {
2460 for (i
= 0; i
< SX_NBOARD
; i
++)
2461 if (sx_board
[i
].base
&& !sx_probe(&sx_board
[i
]))
2466 struct pci_dev
*pdev
= NULL
;
2469 while (i
< SX_NBOARD
) {
2470 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
) {
2474 pdev
= pci_get_device (PCI_VENDOR_ID_SPECIALIX
,
2475 PCI_DEVICE_ID_SPECIALIX_IO8
,
2479 if (pci_enable_device(pdev
))
2482 sx_board
[i
].irq
= pdev
->irq
;
2484 sx_board
[i
].base
= pci_resource_start (pdev
, 2);
2486 sx_board
[i
].flags
|= SX_BOARD_IS_PCI
;
2487 if (!sx_probe(&sx_board
[i
]))
2490 /* May exit pci_get sequence early with lots of boards */
2497 sx_release_drivers();
2498 printk(KERN_INFO
"sx: No specialix IO8+ boards detected.\n");
2507 static int iobase
[SX_NBOARD
] = {0,};
2509 static int irq
[SX_NBOARD
] = {0,};
2511 module_param_array(iobase
, int, NULL
, 0);
2512 module_param_array(irq
, int, NULL
, 0);
2513 module_param(sx_debug
, int, 0);
2514 module_param(sx_rxfifo
, int, 0);
2515 #ifdef SPECIALIX_TIMER
2516 module_param(sx_poll
, int, 0);
2520 * You can setup up to 4 boards.
2521 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2522 * You should specify the IRQs too in that case "irq=....,...".
2524 * More than 4 boards in one computer is not possible, as the card can
2525 * only use 4 different interrupts.
2528 static int __init
specialix_init_module(void)
2534 if (iobase
[0] || iobase
[1] || iobase
[2] || iobase
[3]) {
2535 for(i
= 0; i
< SX_NBOARD
; i
++) {
2536 sx_board
[i
].base
= iobase
[i
];
2537 sx_board
[i
].irq
= irq
[i
];
2538 sx_board
[i
].count
= 0;
2544 return specialix_init();
2547 static void __exit
specialix_exit_module(void)
2553 sx_release_drivers();
2554 for (i
= 0; i
< SX_NBOARD
; i
++)
2555 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
)
2556 sx_release_io_range(&sx_board
[i
]);
2557 #ifdef SPECIALIX_TIMER
2558 del_timer_sync(&missed_irq_timer
);
2564 static struct pci_device_id specialx_pci_tbl
[] __devinitdata
= {
2565 { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX
, PCI_DEVICE_ID_SPECIALIX_IO8
) },
2568 MODULE_DEVICE_TABLE(pci
, specialx_pci_tbl
);
2570 module_init(specialix_init_module
);
2571 module_exit(specialix_exit_module
);
2573 MODULE_LICENSE("GPL");