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 static struct tty_driver
*specialix_driver
;
183 static struct specialix_board sx_board
[SX_NBOARD
] = {
184 { 0, SX_IOBASE1
, 9, },
185 { 0, SX_IOBASE2
, 11, },
186 { 0, SX_IOBASE3
, 12, },
187 { 0, SX_IOBASE4
, 15, },
190 static struct specialix_port sx_port
[SX_NBOARD
* SX_NPORT
];
193 #ifdef SPECIALIX_TIMER
194 static struct timer_list missed_irq_timer
;
195 static irqreturn_t
sx_interrupt(int irq
, void * dev_id
);
200 static inline int sx_paranoia_check(struct specialix_port
const * port
,
201 char *name
, const char *routine
)
203 #ifdef SPECIALIX_PARANOIA_CHECK
204 static const char *badmagic
=
205 KERN_ERR
"sx: Warning: bad specialix port magic number for device %s in %s\n";
206 static const char *badinfo
=
207 KERN_ERR
"sx: Warning: null specialix port for device %s in %s\n";
210 printk(badinfo
, name
, routine
);
213 if (port
->magic
!= SPECIALIX_MAGIC
) {
214 printk(badmagic
, name
, routine
);
224 * Service functions for specialix IO8+ driver.
228 /* Get board number from pointer */
229 static inline int board_No (struct specialix_board
* bp
)
231 return bp
- sx_board
;
235 /* Get port number from pointer */
236 static inline int port_No (struct specialix_port
const * port
)
238 return SX_PORT(port
- sx_port
);
242 /* Get pointer to board from pointer to port */
243 static inline struct specialix_board
* port_Board(struct specialix_port
const * port
)
245 return &sx_board
[SX_BOARD(port
- sx_port
)];
249 /* Input Byte from CL CD186x register */
250 static inline unsigned char sx_in(struct specialix_board
* bp
, unsigned short reg
)
252 bp
->reg
= reg
| 0x80;
253 outb (reg
| 0x80, bp
->base
+ SX_ADDR_REG
);
254 return inb (bp
->base
+ SX_DATA_REG
);
258 /* Output Byte to CL CD186x register */
259 static inline void sx_out(struct specialix_board
* bp
, unsigned short reg
,
262 bp
->reg
= reg
| 0x80;
263 outb (reg
| 0x80, bp
->base
+ SX_ADDR_REG
);
264 outb (val
, bp
->base
+ SX_DATA_REG
);
268 /* Input Byte from CL CD186x register */
269 static inline unsigned char sx_in_off(struct specialix_board
* bp
, unsigned short reg
)
272 outb (reg
, bp
->base
+ SX_ADDR_REG
);
273 return inb (bp
->base
+ SX_DATA_REG
);
277 /* Output Byte to CL CD186x register */
278 static inline void sx_out_off(struct specialix_board
* bp
, unsigned short reg
,
282 outb (reg
, bp
->base
+ SX_ADDR_REG
);
283 outb (val
, bp
->base
+ SX_DATA_REG
);
287 /* Wait for Channel Command Register ready */
288 static inline void sx_wait_CCR(struct specialix_board
* bp
)
290 unsigned long delay
, flags
;
293 for (delay
= SX_CCR_TIMEOUT
; delay
; delay
--) {
294 spin_lock_irqsave(&bp
->lock
, flags
);
295 ccr
= sx_in(bp
, CD186x_CCR
);
296 spin_unlock_irqrestore(&bp
->lock
, flags
);
302 printk(KERN_ERR
"sx%d: Timeout waiting for CCR.\n", board_No(bp
));
306 /* Wait for Channel Command Register ready */
307 static inline void sx_wait_CCR_off(struct specialix_board
* bp
)
313 for (delay
= SX_CCR_TIMEOUT
; delay
; delay
--) {
314 spin_lock_irqsave(&bp
->lock
, flags
);
315 crr
= sx_in_off(bp
, CD186x_CCR
);
316 spin_unlock_irqrestore(&bp
->lock
, flags
);
322 printk(KERN_ERR
"sx%d: Timeout waiting for CCR.\n", board_No(bp
));
327 * specialix IO8+ IO range functions.
330 static inline int sx_request_io_range(struct specialix_board
* bp
)
332 return request_region(bp
->base
,
333 bp
->flags
& SX_BOARD_IS_PCI
? SX_PCI_IO_SPACE
: SX_IO_SPACE
,
334 "specialix IO8+") == NULL
;
338 static inline void sx_release_io_range(struct specialix_board
* bp
)
340 release_region(bp
->base
,
341 bp
->flags
&SX_BOARD_IS_PCI
?SX_PCI_IO_SPACE
:SX_IO_SPACE
);
345 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
346 static int sx_set_irq ( struct specialix_board
*bp
)
352 if (bp
->flags
& SX_BOARD_IS_PCI
)
355 /* In the same order as in the docs... */
356 case 15: virq
= 0;break;
357 case 12: virq
= 1;break;
358 case 11: virq
= 2;break;
359 case 9: virq
= 3;break;
360 default: printk (KERN_ERR
"Speclialix: cannot set irq to %d.\n", bp
->irq
);
363 spin_lock_irqsave(&bp
->lock
, flags
);
365 sx_out(bp
, CD186x_CAR
, i
);
366 sx_out(bp
, CD186x_MSVRTS
, ((virq
>> i
) & 0x1)? MSVR_RTS
:0);
368 spin_unlock_irqrestore(&bp
->lock
, flags
);
373 /* Reset and setup CD186x chip */
374 static int sx_init_CD186x(struct specialix_board
* bp
)
381 sx_wait_CCR_off(bp
); /* Wait for CCR ready */
382 spin_lock_irqsave(&bp
->lock
, flags
);
383 sx_out_off(bp
, CD186x_CCR
, CCR_HARDRESET
); /* Reset CD186x chip */
384 spin_unlock_irqrestore(&bp
->lock
, flags
);
385 msleep(50); /* Delay 0.05 sec */
386 spin_lock_irqsave(&bp
->lock
, flags
);
387 sx_out_off(bp
, CD186x_GIVR
, SX_ID
); /* Set ID for this chip */
388 sx_out_off(bp
, CD186x_GICR
, 0); /* Clear all bits */
389 sx_out_off(bp
, CD186x_PILR1
, SX_ACK_MINT
); /* Prio for modem intr */
390 sx_out_off(bp
, CD186x_PILR2
, SX_ACK_TINT
); /* Prio for transmitter intr */
391 sx_out_off(bp
, CD186x_PILR3
, SX_ACK_RINT
); /* Prio for receiver intr */
393 sx_out_off(bp
, CD186x_SRCR
, sx_in (bp
, CD186x_SRCR
) | SRCR_REGACKEN
);
395 /* Setting up prescaler. We need 4 ticks per 1 ms */
396 scaler
= SX_OSCFREQ
/SPECIALIX_TPS
;
398 sx_out_off(bp
, CD186x_PPRH
, scaler
>> 8);
399 sx_out_off(bp
, CD186x_PPRL
, scaler
& 0xff);
400 spin_unlock_irqrestore(&bp
->lock
, flags
);
402 if (!sx_set_irq (bp
)) {
403 /* Figure out how to pass this along... */
404 printk (KERN_ERR
"Cannot set irq to %d.\n", bp
->irq
);
413 static int read_cross_byte (struct specialix_board
*bp
, int reg
, int bit
)
419 spin_lock_irqsave(&bp
->lock
, flags
);
420 for (i
=0, t
=0;i
<8;i
++) {
421 sx_out_off (bp
, CD186x_CAR
, i
);
422 if (sx_in_off (bp
, reg
) & bit
)
425 spin_unlock_irqrestore(&bp
->lock
, flags
);
431 #ifdef SPECIALIX_TIMER
432 void missed_irq (unsigned long data
)
436 struct specialix_board
*bp
= (struct specialix_board
*)data
;
438 spin_lock_irqsave(&bp
->lock
, flags
);
439 irq
= sx_in ((struct specialix_board
*)data
, CD186x_SRSR
) &
443 spin_unlock_irqrestore(&bp
->lock
, flags
);
445 printk (KERN_INFO
"Missed interrupt... Calling int from timer. \n");
446 sx_interrupt (((struct specialix_board
*)data
)->irq
,
449 mod_timer(&missed_irq_timer
, jiffies
+ sx_poll
);
455 /* Main probing routine, also sets irq. */
456 static int sx_probe(struct specialix_board
*bp
)
458 unsigned char val1
, val2
;
468 if (sx_request_io_range(bp
)) {
473 /* Are the I/O ports here ? */
474 sx_out_off(bp
, CD186x_PPRL
, 0x5a);
476 val1
= sx_in_off(bp
, CD186x_PPRL
);
478 sx_out_off(bp
, CD186x_PPRL
, 0xa5);
480 val2
= sx_in_off(bp
, CD186x_PPRL
);
483 if ((val1
!= 0x5a) || (val2
!= 0xa5)) {
484 printk(KERN_INFO
"sx%d: specialix IO8+ Board at 0x%03x not found.\n",
485 board_No(bp
), bp
->base
);
486 sx_release_io_range(bp
);
491 /* Check the DSR lines that Specialix uses as board
493 val1
= read_cross_byte (bp
, CD186x_MSVR
, MSVR_DSR
);
494 val2
= read_cross_byte (bp
, CD186x_MSVR
, MSVR_RTS
);
495 dprintk (SX_DEBUG_INIT
, "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
496 board_No(bp
), val1
, val2
);
498 /* They managed to switch the bit order between the docs and
499 the IO8+ card. The new PCI card now conforms to old docs.
500 They changed the PCI docs to reflect the situation on the
502 val2
= (bp
->flags
& SX_BOARD_IS_PCI
)?0x4d : 0xb2;
504 printk(KERN_INFO
"sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
505 board_No(bp
), val2
, bp
->base
, val1
);
506 sx_release_io_range(bp
);
513 /* It's time to find IRQ for this board */
514 for (retries
= 0; retries
< 5 && irqs
<= 0; retries
++) {
515 irqs
= probe_irq_on();
516 sx_init_CD186x(bp
); /* Reset CD186x chip */
517 sx_out(bp
, CD186x_CAR
, 2); /* Select port 2 */
519 sx_out(bp
, CD186x_CCR
, CCR_TXEN
); /* Enable transmitter */
520 sx_out(bp
, CD186x_IER
, IER_TXRDY
); /* Enable tx empty intr */
522 irqs
= probe_irq_off(irqs
);
524 dprintk (SX_DEBUG_INIT
, "SRSR = %02x, ", sx_in(bp
, CD186x_SRSR
));
525 dprintk (SX_DEBUG_INIT
, "TRAR = %02x, ", sx_in(bp
, CD186x_TRAR
));
526 dprintk (SX_DEBUG_INIT
, "GIVR = %02x, ", sx_in(bp
, CD186x_GIVR
));
527 dprintk (SX_DEBUG_INIT
, "GICR = %02x, ", sx_in(bp
, CD186x_GICR
));
528 dprintk (SX_DEBUG_INIT
, "\n");
530 /* Reset CD186x again */
531 if (!sx_init_CD186x(bp
)) {
532 /* Hmmm. This is dead code anyway. */
535 dprintk (SX_DEBUG_INIT
"val1 = %02x, val2 = %02x, val3 = %02x.\n",
542 printk(KERN_ERR
"sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
543 board_No(bp
), bp
->base
);
544 sx_release_io_range(bp
);
549 printk (KERN_INFO
"Started with irq=%d, but now have irq=%d.\n", bp
->irq
, irqs
);
553 /* Reset CD186x again */
554 if (!sx_init_CD186x(bp
)) {
555 sx_release_io_range(bp
);
560 sx_request_io_range(bp
);
561 bp
->flags
|= SX_BOARD_PRESENT
;
563 /* Chip revcode pkgtype
568 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
570 -- Thanks to Gwen Wang, Cirrus Logic.
573 switch (sx_in_off(bp
, CD186x_GFRCR
)) {
574 case 0x82:chip
= 1864;rev
='A';break;
575 case 0x83:chip
= 1865;rev
='A';break;
576 case 0x84:chip
= 1865;rev
='B';break;
577 case 0x85:chip
= 1865;rev
='C';break; /* Does not exist at this time */
578 default:chip
=-1;rev
='x';
581 dprintk (SX_DEBUG_INIT
, " GFCR = 0x%02x\n", sx_in_off(bp
, CD186x_GFRCR
) );
583 #ifdef SPECIALIX_TIMER
584 setup_timer(&missed_irq_timer
, missed_irq
, (unsigned long)bp
);
585 mod_timer(&missed_irq_timer
, jiffies
+ sx_poll
);
588 printk(KERN_INFO
"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
599 * Interrupt processing routines.
602 static inline struct specialix_port
* sx_get_port(struct specialix_board
* bp
,
603 unsigned char const * what
)
605 unsigned char channel
;
606 struct specialix_port
* port
= NULL
;
608 channel
= sx_in(bp
, CD186x_GICR
) >> GICR_CHAN_OFF
;
609 dprintk (SX_DEBUG_CHAN
, "channel: %d\n", channel
);
610 if (channel
< CD186x_NCH
) {
611 port
= &sx_port
[board_No(bp
) * SX_NPORT
+ channel
];
612 dprintk (SX_DEBUG_CHAN
, "port: %d %p flags: 0x%x\n",board_No(bp
) * SX_NPORT
+ channel
, port
, port
->flags
& ASYNC_INITIALIZED
);
614 if (port
->flags
& ASYNC_INITIALIZED
) {
615 dprintk (SX_DEBUG_CHAN
, "port: %d %p\n", channel
, port
);
620 printk(KERN_INFO
"sx%d: %s interrupt from invalid port %d\n",
621 board_No(bp
), what
, channel
);
626 static inline void sx_receive_exc(struct specialix_board
* bp
)
628 struct specialix_port
*port
;
629 struct tty_struct
*tty
;
630 unsigned char status
;
631 unsigned char ch
, flag
;
635 port
= sx_get_port(bp
, "Receive");
637 dprintk (SX_DEBUG_RX
, "Hmm, couldn't find port.\n");
643 status
= sx_in(bp
, CD186x_RCSR
);
645 dprintk (SX_DEBUG_RX
, "status: 0x%x\n", status
);
646 if (status
& RCSR_OE
) {
648 dprintk(SX_DEBUG_FIFO
, "sx%d: port %d: Overrun. Total %ld overruns.\n",
649 board_No(bp
), port_No(port
), port
->overrun
);
651 status
&= port
->mark_mask
;
653 /* This flip buffer check needs to be below the reading of the
654 status register to reset the chip's IRQ.... */
655 if (tty_buffer_request_room(tty
, 1) == 0) {
656 dprintk(SX_DEBUG_FIFO
, "sx%d: port %d: Working around flip buffer overflow.\n",
657 board_No(bp
), port_No(port
));
662 ch
= sx_in(bp
, CD186x_RDR
);
667 if (status
& RCSR_TOUT
) {
668 printk(KERN_INFO
"sx%d: port %d: Receiver timeout. Hardware problems ?\n",
669 board_No(bp
), port_No(port
));
673 } else if (status
& RCSR_BREAK
) {
674 dprintk(SX_DEBUG_RX
, "sx%d: port %d: Handling break...\n",
675 board_No(bp
), port_No(port
));
677 if (port
->flags
& ASYNC_SAK
)
680 } else if (status
& RCSR_PE
)
683 else if (status
& RCSR_FE
)
686 else if (status
& RCSR_OE
)
692 if(tty_insert_flip_char(tty
, ch
, flag
))
693 tty_flip_buffer_push(tty
);
698 static inline void sx_receive(struct specialix_board
* bp
)
700 struct specialix_port
*port
;
701 struct tty_struct
*tty
;
706 if (!(port
= sx_get_port(bp
, "Receive"))) {
707 dprintk (SX_DEBUG_RX
, "Hmm, couldn't find port.\n");
713 count
= sx_in(bp
, CD186x_RDCR
);
714 dprintk (SX_DEBUG_RX
, "port: %p: count: %d\n", port
, count
);
715 port
->hits
[count
> 8 ? 9 : count
]++;
717 tty_buffer_request_room(tty
, count
);
720 tty_insert_flip_char(tty
, sx_in(bp
, CD186x_RDR
), TTY_NORMAL
);
721 tty_flip_buffer_push(tty
);
726 static inline void sx_transmit(struct specialix_board
* bp
)
728 struct specialix_port
*port
;
729 struct tty_struct
*tty
;
733 if (!(port
= sx_get_port(bp
, "Transmit"))) {
737 dprintk (SX_DEBUG_TX
, "port: %p\n", port
);
740 if (port
->IER
& IER_TXEMPTY
) {
742 sx_out(bp
, CD186x_CAR
, port_No(port
));
743 port
->IER
&= ~IER_TXEMPTY
;
744 sx_out(bp
, CD186x_IER
, port
->IER
);
749 if ((port
->xmit_cnt
<= 0 && !port
->break_length
)
750 || tty
->stopped
|| tty
->hw_stopped
) {
751 sx_out(bp
, CD186x_CAR
, port_No(port
));
752 port
->IER
&= ~IER_TXRDY
;
753 sx_out(bp
, CD186x_IER
, port
->IER
);
758 if (port
->break_length
) {
759 if (port
->break_length
> 0) {
760 if (port
->COR2
& COR2_ETC
) {
761 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
762 sx_out(bp
, CD186x_TDR
, CD186x_C_SBRK
);
763 port
->COR2
&= ~COR2_ETC
;
765 count
= min_t(int, port
->break_length
, 0xff);
766 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
767 sx_out(bp
, CD186x_TDR
, CD186x_C_DELAY
);
768 sx_out(bp
, CD186x_TDR
, count
);
769 if (!(port
->break_length
-= count
))
770 port
->break_length
--;
772 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
773 sx_out(bp
, CD186x_TDR
, CD186x_C_EBRK
);
774 sx_out(bp
, CD186x_COR2
, port
->COR2
);
776 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
777 port
->break_length
= 0;
784 count
= CD186x_NFIFO
;
786 sx_out(bp
, CD186x_TDR
, port
->xmit_buf
[port
->xmit_tail
++]);
787 port
->xmit_tail
= port
->xmit_tail
& (SERIAL_XMIT_SIZE
-1);
788 if (--port
->xmit_cnt
<= 0)
790 } while (--count
> 0);
792 if (port
->xmit_cnt
<= 0) {
793 sx_out(bp
, CD186x_CAR
, port_No(port
));
794 port
->IER
&= ~IER_TXRDY
;
795 sx_out(bp
, CD186x_IER
, port
->IER
);
797 if (port
->xmit_cnt
<= port
->wakeup_chars
)
804 static inline void sx_check_modem(struct specialix_board
* bp
)
806 struct specialix_port
*port
;
807 struct tty_struct
*tty
;
811 dprintk (SX_DEBUG_SIGNALS
, "Modem intr. ");
812 if (!(port
= sx_get_port(bp
, "Modem")))
817 mcr
= sx_in(bp
, CD186x_MCR
);
818 printk ("mcr = %02x.\n", mcr
);
820 if ((mcr
& MCR_CDCHG
)) {
821 dprintk (SX_DEBUG_SIGNALS
, "CD just changed... ");
822 msvr_cd
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
824 dprintk (SX_DEBUG_SIGNALS
, "Waking up guys in open.\n");
825 wake_up_interruptible(&port
->open_wait
);
827 dprintk (SX_DEBUG_SIGNALS
, "Sending HUP.\n");
832 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
833 if (mcr
& MCR_CTSCHG
) {
834 if (sx_in(bp
, CD186x_MSVR
) & MSVR_CTS
) {
836 port
->IER
|= IER_TXRDY
;
837 if (port
->xmit_cnt
<= port
->wakeup_chars
)
841 port
->IER
&= ~IER_TXRDY
;
843 sx_out(bp
, CD186x_IER
, port
->IER
);
845 if (mcr
& MCR_DSSXHG
) {
846 if (sx_in(bp
, CD186x_MSVR
) & MSVR_DSR
) {
848 port
->IER
|= IER_TXRDY
;
849 if (port
->xmit_cnt
<= port
->wakeup_chars
)
853 port
->IER
&= ~IER_TXRDY
;
855 sx_out(bp
, CD186x_IER
, port
->IER
);
857 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
859 /* Clear change bits */
860 sx_out(bp
, CD186x_MCR
, 0);
864 /* The main interrupt processing routine */
865 static irqreturn_t
sx_interrupt(int irq
, void *dev_id
)
867 unsigned char status
;
869 struct specialix_board
*bp
;
870 unsigned long loop
= 0;
877 spin_lock_irqsave(&bp
->lock
, flags
);
879 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);
880 if (!(bp
->flags
& SX_BOARD_ACTIVE
)) {
881 dprintk (SX_DEBUG_IRQ
, "sx: False interrupt. irq %d.\n", irq
);
882 spin_unlock_irqrestore(&bp
->lock
, flags
);
889 while ((++loop
< 16) && (status
= (sx_in(bp
, CD186x_SRSR
) &
893 if (status
& SRSR_RREQint
) {
894 ack
= sx_in(bp
, CD186x_RRAR
);
896 if (ack
== (SX_ID
| GIVR_IT_RCV
))
898 else if (ack
== (SX_ID
| GIVR_IT_REXC
))
901 printk(KERN_ERR
"sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
902 board_No(bp
), status
, ack
);
904 } else if (status
& SRSR_TREQint
) {
905 ack
= sx_in(bp
, CD186x_TRAR
);
907 if (ack
== (SX_ID
| GIVR_IT_TX
))
910 printk(KERN_ERR
"sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
911 board_No(bp
), status
, ack
, port_No (sx_get_port (bp
, "Int")));
912 } else if (status
& SRSR_MREQint
) {
913 ack
= sx_in(bp
, CD186x_MRAR
);
915 if (ack
== (SX_ID
| GIVR_IT_MODEM
))
918 printk(KERN_ERR
"sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
919 board_No(bp
), status
, ack
);
923 sx_out(bp
, CD186x_EOIR
, 0); /* Mark end of interrupt */
926 outb (bp
->reg
, bp
->base
+ SX_ADDR_REG
);
927 spin_unlock_irqrestore(&bp
->lock
, flags
);
934 * Routines for open & close processing.
937 static void turn_ints_off (struct specialix_board
*bp
)
942 if (bp
->flags
& SX_BOARD_IS_PCI
) {
943 /* This was intended for enabeling the interrupt on the
944 * PCI card. However it seems that it's already enabled
945 * and as PCI interrupts can be shared, there is no real
946 * reason to have to turn it off. */
949 spin_lock_irqsave(&bp
->lock
, flags
);
950 (void) sx_in_off (bp
, 0); /* Turn off interrupts. */
951 spin_unlock_irqrestore(&bp
->lock
, flags
);
956 static void turn_ints_on (struct specialix_board
*bp
)
962 if (bp
->flags
& SX_BOARD_IS_PCI
) {
963 /* play with the PCI chip. See comment above. */
965 spin_lock_irqsave(&bp
->lock
, flags
);
966 (void) sx_in (bp
, 0); /* Turn ON interrupts. */
967 spin_unlock_irqrestore(&bp
->lock
, flags
);
973 /* Called with disabled interrupts */
974 static inline int sx_setup_board(struct specialix_board
* bp
)
978 if (bp
->flags
& SX_BOARD_ACTIVE
)
981 if (bp
->flags
& SX_BOARD_IS_PCI
)
982 error
= request_irq(bp
->irq
, sx_interrupt
, IRQF_DISABLED
| IRQF_SHARED
, "specialix IO8+", bp
);
984 error
= request_irq(bp
->irq
, sx_interrupt
, IRQF_DISABLED
, "specialix IO8+", bp
);
990 bp
->flags
|= SX_BOARD_ACTIVE
;
996 /* Called with disabled interrupts */
997 static inline void sx_shutdown_board(struct specialix_board
*bp
)
1001 if (!(bp
->flags
& SX_BOARD_ACTIVE
)) {
1006 bp
->flags
&= ~SX_BOARD_ACTIVE
;
1008 dprintk (SX_DEBUG_IRQ
, "Freeing IRQ%d for board %d.\n",
1009 bp
->irq
, board_No (bp
));
1010 free_irq(bp
->irq
, bp
);
1020 * Setting up port characteristics.
1021 * Must be called with disabled interrupts
1023 static void sx_change_speed(struct specialix_board
*bp
, struct specialix_port
*port
)
1025 struct tty_struct
*tty
;
1028 unsigned char cor1
= 0, cor3
= 0;
1029 unsigned char mcor1
= 0, mcor2
= 0;
1030 static unsigned long again
;
1031 unsigned long flags
;
1035 if (!(tty
= port
->tty
) || !tty
->termios
) {
1042 /* Select port on the board */
1043 spin_lock_irqsave(&bp
->lock
, flags
);
1044 sx_out(bp
, CD186x_CAR
, port_No(port
));
1046 /* The Specialix board doens't implement the RTS lines.
1047 They are used to set the IRQ level. Don't touch them. */
1048 if (SX_CRTSCTS(tty
))
1049 port
->MSVR
= MSVR_DTR
| (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
1051 port
->MSVR
= (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
1052 spin_unlock_irqrestore(&bp
->lock
, flags
);
1053 dprintk (SX_DEBUG_TERMIOS
, "sx: got MSVR=%02x.\n", port
->MSVR
);
1054 baud
= tty_get_baud_rate(tty
);
1056 if (baud
== 38400) {
1057 if ((port
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_HI
)
1059 if ((port
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_VHI
)
1064 /* Drop DTR & exit */
1065 dprintk (SX_DEBUG_TERMIOS
, "Dropping DTR... Hmm....\n");
1066 if (!SX_CRTSCTS (tty
)) {
1067 port
-> MSVR
&= ~ MSVR_DTR
;
1068 spin_lock_irqsave(&bp
->lock
, flags
);
1069 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1070 spin_unlock_irqrestore(&bp
->lock
, flags
);
1073 dprintk (SX_DEBUG_TERMIOS
, "Can't drop DTR: no DTR.\n");
1077 if (!SX_CRTSCTS (tty
)) {
1078 port
->MSVR
|= MSVR_DTR
;
1083 * Now we must calculate some speed depended things
1086 /* Set baud rate for port */
1087 tmp
= port
->custom_divisor
;
1089 printk (KERN_INFO
"sx%d: Using custom baud rate divisor %ld. \n"
1090 "This is an untested option, please be carefull.\n",
1091 port_No (port
), tmp
);
1093 tmp
= (((SX_OSCFREQ
+ baud
/2) / baud
+
1094 CD186x_TPC
/2) / CD186x_TPC
);
1096 if ((tmp
< 0x10) && time_before(again
, jiffies
)) {
1097 again
= jiffies
+ HZ
* 60;
1098 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1100 printk (KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1101 "Performance degradation is possible.\n"
1102 "Read specialix.txt for more info.\n",
1103 port_No (port
), tmp
);
1105 printk (KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1106 "Warning: overstressing Cirrus chip. "
1107 "This might not work.\n"
1108 "Read specialix.txt for more info.\n",
1109 port_No (port
), tmp
);
1112 spin_lock_irqsave(&bp
->lock
, flags
);
1113 sx_out(bp
, CD186x_RBPRH
, (tmp
>> 8) & 0xff);
1114 sx_out(bp
, CD186x_TBPRH
, (tmp
>> 8) & 0xff);
1115 sx_out(bp
, CD186x_RBPRL
, tmp
& 0xff);
1116 sx_out(bp
, CD186x_TBPRL
, tmp
& 0xff);
1117 spin_unlock_irqrestore(&bp
->lock
, flags
);
1118 if (port
->custom_divisor
)
1119 baud
= (SX_OSCFREQ
+ port
->custom_divisor
/2) / port
->custom_divisor
;
1120 baud
= (baud
+ 5) / 10; /* Estimated CPS */
1122 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1123 tmp
= ((baud
+ HZ
/2) / HZ
) * 2 - CD186x_NFIFO
;
1124 port
->wakeup_chars
= (tmp
< 0) ? 0 : ((tmp
>= SERIAL_XMIT_SIZE
) ?
1125 SERIAL_XMIT_SIZE
- 1 : tmp
);
1127 /* Receiver timeout will be transmission time for 1.5 chars */
1128 tmp
= (SPECIALIX_TPS
+ SPECIALIX_TPS
/2 + baud
/2) / baud
;
1129 tmp
= (tmp
> 0xff) ? 0xff : tmp
;
1130 spin_lock_irqsave(&bp
->lock
, flags
);
1131 sx_out(bp
, CD186x_RTPR
, tmp
);
1132 spin_unlock_irqrestore(&bp
->lock
, flags
);
1133 switch (C_CSIZE(tty
)) {
1151 cor1
|= COR1_IGNORE
;
1152 if (C_PARENB(tty
)) {
1153 cor1
|= COR1_NORMPAR
;
1157 cor1
&= ~COR1_IGNORE
;
1159 /* Set marking of some errors */
1160 port
->mark_mask
= RCSR_OE
| RCSR_TOUT
;
1162 port
->mark_mask
|= RCSR_FE
| RCSR_PE
;
1163 if (I_BRKINT(tty
) || I_PARMRK(tty
))
1164 port
->mark_mask
|= RCSR_BREAK
;
1166 port
->mark_mask
&= ~(RCSR_FE
| RCSR_PE
);
1167 if (I_IGNBRK(tty
)) {
1168 port
->mark_mask
&= ~RCSR_BREAK
;
1170 /* Real raw mode. Ignore all */
1171 port
->mark_mask
&= ~RCSR_OE
;
1173 /* Enable Hardware Flow Control */
1174 if (C_CRTSCTS(tty
)) {
1175 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1176 port
->IER
|= IER_DSR
| IER_CTS
;
1177 mcor1
|= MCOR1_DSRZD
| MCOR1_CTSZD
;
1178 mcor2
|= MCOR2_DSROD
| MCOR2_CTSOD
;
1179 spin_lock_irqsave(&bp
->lock
, flags
);
1180 tty
->hw_stopped
= !(sx_in(bp
, CD186x_MSVR
) & (MSVR_CTS
|MSVR_DSR
));
1181 spin_unlock_irqrestore(&bp
->lock
, flags
);
1183 port
->COR2
|= COR2_CTSAE
;
1186 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1187 /* Some people reported that it works, but I still doubt it */
1189 port
->COR2
|= COR2_TXIBE
;
1190 cor3
|= (COR3_FCT
| COR3_SCDE
);
1192 port
->COR2
|= COR2_IXM
;
1193 spin_lock_irqsave(&bp
->lock
, flags
);
1194 sx_out(bp
, CD186x_SCHR1
, START_CHAR(tty
));
1195 sx_out(bp
, CD186x_SCHR2
, STOP_CHAR(tty
));
1196 sx_out(bp
, CD186x_SCHR3
, START_CHAR(tty
));
1197 sx_out(bp
, CD186x_SCHR4
, STOP_CHAR(tty
));
1198 spin_unlock_irqrestore(&bp
->lock
, flags
);
1200 if (!C_CLOCAL(tty
)) {
1201 /* Enable CD check */
1202 port
->IER
|= IER_CD
;
1203 mcor1
|= MCOR1_CDZD
;
1204 mcor2
|= MCOR2_CDOD
;
1208 /* Enable receiver */
1209 port
->IER
|= IER_RXD
;
1211 /* Set input FIFO size (1-8 bytes) */
1213 /* Setting up CD186x channel registers */
1214 spin_lock_irqsave(&bp
->lock
, flags
);
1215 sx_out(bp
, CD186x_COR1
, cor1
);
1216 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1217 sx_out(bp
, CD186x_COR3
, cor3
);
1218 spin_unlock_irqrestore(&bp
->lock
, flags
);
1219 /* Make CD186x know about registers change */
1221 spin_lock_irqsave(&bp
->lock
, flags
);
1222 sx_out(bp
, CD186x_CCR
, CCR_CORCHG1
| CCR_CORCHG2
| CCR_CORCHG3
);
1223 /* Setting up modem option registers */
1224 dprintk (SX_DEBUG_TERMIOS
, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1
, mcor2
);
1225 sx_out(bp
, CD186x_MCOR1
, mcor1
);
1226 sx_out(bp
, CD186x_MCOR2
, mcor2
);
1227 spin_unlock_irqrestore(&bp
->lock
, flags
);
1228 /* Enable CD186x transmitter & receiver */
1230 spin_lock_irqsave(&bp
->lock
, flags
);
1231 sx_out(bp
, CD186x_CCR
, CCR_TXEN
| CCR_RXEN
);
1232 /* Enable interrupts */
1233 sx_out(bp
, CD186x_IER
, port
->IER
);
1234 /* And finally set the modem lines... */
1235 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1236 spin_unlock_irqrestore(&bp
->lock
, flags
);
1242 /* Must be called with interrupts enabled */
1243 static int sx_setup_port(struct specialix_board
*bp
, struct specialix_port
*port
)
1245 unsigned long flags
;
1249 if (port
->flags
& ASYNC_INITIALIZED
) {
1254 if (!port
->xmit_buf
) {
1255 /* We may sleep in get_zeroed_page() */
1258 if (!(tmp
= get_zeroed_page(GFP_KERNEL
))) {
1263 if (port
->xmit_buf
) {
1266 return -ERESTARTSYS
;
1268 port
->xmit_buf
= (unsigned char *) tmp
;
1271 spin_lock_irqsave(&port
->lock
, flags
);
1274 clear_bit(TTY_IO_ERROR
, &port
->tty
->flags
);
1276 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1277 sx_change_speed(bp
, port
);
1278 port
->flags
|= ASYNC_INITIALIZED
;
1280 spin_unlock_irqrestore(&port
->lock
, flags
);
1288 /* Must be called with interrupts disabled */
1289 static void sx_shutdown_port(struct specialix_board
*bp
, struct specialix_port
*port
)
1291 struct tty_struct
*tty
;
1293 unsigned long flags
;
1297 if (!(port
->flags
& ASYNC_INITIALIZED
)) {
1302 if (sx_debug
& SX_DEBUG_FIFO
) {
1303 dprintk(SX_DEBUG_FIFO
, "sx%d: port %d: %ld overruns, FIFO hits [ ",
1304 board_No(bp
), port_No(port
), port
->overrun
);
1305 for (i
= 0; i
< 10; i
++) {
1306 dprintk(SX_DEBUG_FIFO
, "%ld ", port
->hits
[i
]);
1308 dprintk(SX_DEBUG_FIFO
, "].\n");
1311 if (port
->xmit_buf
) {
1312 free_page((unsigned long) port
->xmit_buf
);
1313 port
->xmit_buf
= NULL
;
1317 spin_lock_irqsave(&bp
->lock
, flags
);
1318 sx_out(bp
, CD186x_CAR
, port_No(port
));
1320 if (!(tty
= port
->tty
) || C_HUPCL(tty
)) {
1322 sx_out(bp
, CD186x_MSVDTR
, 0);
1324 spin_unlock_irqrestore(&bp
->lock
, flags
);
1327 spin_lock_irqsave(&bp
->lock
, flags
);
1328 sx_out(bp
, CD186x_CCR
, CCR_SOFTRESET
);
1329 /* Disable all interrupts from this port */
1331 sx_out(bp
, CD186x_IER
, port
->IER
);
1332 spin_unlock_irqrestore(&bp
->lock
, flags
);
1334 set_bit(TTY_IO_ERROR
, &tty
->flags
);
1335 port
->flags
&= ~ASYNC_INITIALIZED
;
1338 sx_shutdown_board(bp
);
1343 static int block_til_ready(struct tty_struct
*tty
, struct file
* filp
,
1344 struct specialix_port
*port
)
1346 DECLARE_WAITQUEUE(wait
, current
);
1347 struct specialix_board
*bp
= port_Board(port
);
1351 unsigned long flags
;
1356 * If the device is in the middle of being closed, then block
1357 * until it's done, and then try again.
1359 if (tty_hung_up_p(filp
) || port
->flags
& ASYNC_CLOSING
) {
1360 interruptible_sleep_on(&port
->close_wait
);
1361 if (port
->flags
& ASYNC_HUP_NOTIFY
) {
1366 return -ERESTARTSYS
;
1371 * If non-blocking mode is set, or the port is not enabled,
1372 * then make the check up front and then exit.
1374 if ((filp
->f_flags
& O_NONBLOCK
) ||
1375 (tty
->flags
& (1 << TTY_IO_ERROR
))) {
1376 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
1385 * Block waiting for the carrier detect and the line to become
1386 * free (i.e., not in use by the callout). While we are in
1387 * this loop, info->count is dropped by one, so that
1388 * rs_close() knows when to free things. We restore it upon
1389 * exit, either normal or abnormal.
1392 add_wait_queue(&port
->open_wait
, &wait
);
1393 spin_lock_irqsave(&port
->lock
, flags
);
1394 if (!tty_hung_up_p(filp
)) {
1397 spin_unlock_irqrestore(&port
->lock
, flags
);
1398 port
->blocked_open
++;
1400 spin_lock_irqsave(&bp
->lock
, flags
);
1401 sx_out(bp
, CD186x_CAR
, port_No(port
));
1402 CD
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
1403 if (SX_CRTSCTS (tty
)) {
1405 port
->MSVR
|= MSVR_DTR
; /* WTF? */
1406 sx_out (bp
, CD186x_MSVR
, port
->MSVR
);
1409 port
->MSVR
|= MSVR_DTR
;
1410 sx_out (bp
, CD186x_MSVR
, port
->MSVR
);
1412 spin_unlock_irqrestore(&bp
->lock
, flags
);
1413 set_current_state(TASK_INTERRUPTIBLE
);
1414 if (tty_hung_up_p(filp
) ||
1415 !(port
->flags
& ASYNC_INITIALIZED
)) {
1416 if (port
->flags
& ASYNC_HUP_NOTIFY
)
1419 retval
= -ERESTARTSYS
;
1422 if (!(port
->flags
& ASYNC_CLOSING
) &&
1425 if (signal_pending(current
)) {
1426 retval
= -ERESTARTSYS
;
1432 set_current_state(TASK_RUNNING
);
1433 remove_wait_queue(&port
->open_wait
, &wait
);
1434 spin_lock_irqsave(&port
->lock
, flags
);
1435 if (!tty_hung_up_p(filp
)) {
1438 port
->blocked_open
--;
1439 spin_unlock_irqrestore(&port
->lock
, flags
);
1445 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
1451 static int sx_open(struct tty_struct
* tty
, struct file
* filp
)
1455 struct specialix_port
* port
;
1456 struct specialix_board
* bp
;
1458 unsigned long flags
;
1462 board
= SX_BOARD(tty
->index
);
1464 if (board
>= SX_NBOARD
|| !(sx_board
[board
].flags
& SX_BOARD_PRESENT
)) {
1469 bp
= &sx_board
[board
];
1470 port
= sx_port
+ board
* SX_NPORT
+ SX_PORT(tty
->index
);
1472 for (i
= 0; i
< 10; i
++)
1475 dprintk (SX_DEBUG_OPEN
, "Board = %d, bp = %p, port = %p, portno = %d.\n",
1476 board
, bp
, port
, SX_PORT(tty
->index
));
1478 if (sx_paranoia_check(port
, tty
->name
, "sx_open")) {
1483 if ((error
= sx_setup_board(bp
))) {
1488 spin_lock_irqsave(&bp
->lock
, flags
);
1491 tty
->driver_data
= port
;
1493 spin_unlock_irqrestore(&bp
->lock
, flags
);
1495 if ((error
= sx_setup_port(bp
, port
))) {
1500 if ((error
= block_til_ready(tty
, filp
, port
))) {
1510 static void sx_close(struct tty_struct
* tty
, struct file
* filp
)
1512 struct specialix_port
*port
= (struct specialix_port
*) tty
->driver_data
;
1513 struct specialix_board
*bp
;
1514 unsigned long flags
;
1515 unsigned long timeout
;
1518 if (!port
|| sx_paranoia_check(port
, tty
->name
, "close")) {
1522 spin_lock_irqsave(&port
->lock
, flags
);
1524 if (tty_hung_up_p(filp
)) {
1525 spin_unlock_irqrestore(&port
->lock
, flags
);
1530 bp
= port_Board(port
);
1531 if ((tty
->count
== 1) && (port
->count
!= 1)) {
1532 printk(KERN_ERR
"sx%d: sx_close: bad port count;"
1533 " tty->count is 1, port count is %d\n",
1534 board_No(bp
), port
->count
);
1538 if (port
->count
> 1) {
1542 spin_unlock_irqrestore(&port
->lock
, flags
);
1547 port
->flags
|= ASYNC_CLOSING
;
1549 * Now we wait for the transmit buffer to clear; and we notify
1550 * the line discipline to only process XON/XOFF characters.
1553 spin_unlock_irqrestore(&port
->lock
, flags
);
1554 dprintk (SX_DEBUG_OPEN
, "Closing\n");
1555 if (port
->closing_wait
!= ASYNC_CLOSING_WAIT_NONE
) {
1556 tty_wait_until_sent(tty
, port
->closing_wait
);
1559 * At this point we stop accepting input. To do this, we
1560 * disable the receive line status interrupts, and tell the
1561 * interrupt driver to stop checking the data ready bit in the
1562 * line status register.
1564 dprintk (SX_DEBUG_OPEN
, "Closed\n");
1565 port
->IER
&= ~IER_RXD
;
1566 if (port
->flags
& ASYNC_INITIALIZED
) {
1567 port
->IER
&= ~IER_TXRDY
;
1568 port
->IER
|= IER_TXEMPTY
;
1569 spin_lock_irqsave(&bp
->lock
, flags
);
1570 sx_out(bp
, CD186x_CAR
, port_No(port
));
1571 sx_out(bp
, CD186x_IER
, port
->IER
);
1572 spin_unlock_irqrestore(&bp
->lock
, flags
);
1574 * Before we drop DTR, make sure the UART transmitter
1575 * has completely drained; this is especially
1576 * important if there is a transmit FIFO!
1578 timeout
= jiffies
+HZ
;
1579 while(port
->IER
& IER_TXEMPTY
) {
1580 set_current_state (TASK_INTERRUPTIBLE
);
1581 msleep_interruptible(jiffies_to_msecs(port
->timeout
));
1582 if (time_after(jiffies
, timeout
)) {
1583 printk (KERN_INFO
"Timeout waiting for close\n");
1590 if (--bp
->count
< 0) {
1591 printk(KERN_ERR
"sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1592 board_No(bp
), bp
->count
, tty
->index
);
1595 if (--port
->count
< 0) {
1596 printk(KERN_ERR
"sx%d: sx_close: bad port count for tty%d: %d\n",
1597 board_No(bp
), port_No(port
), port
->count
);
1601 sx_shutdown_port(bp
, port
);
1602 if (tty
->driver
->flush_buffer
)
1603 tty
->driver
->flush_buffer(tty
);
1604 tty_ldisc_flush(tty
);
1605 spin_lock_irqsave(&port
->lock
, flags
);
1608 spin_unlock_irqrestore(&port
->lock
, flags
);
1609 if (port
->blocked_open
) {
1610 if (port
->close_delay
) {
1611 msleep_interruptible(jiffies_to_msecs(port
->close_delay
));
1613 wake_up_interruptible(&port
->open_wait
);
1615 port
->flags
&= ~(ASYNC_NORMAL_ACTIVE
|ASYNC_CLOSING
);
1616 wake_up_interruptible(&port
->close_wait
);
1622 static int sx_write(struct tty_struct
* tty
,
1623 const unsigned char *buf
, int count
)
1625 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1626 struct specialix_board
*bp
;
1628 unsigned long flags
;
1631 if (sx_paranoia_check(port
, tty
->name
, "sx_write")) {
1636 bp
= port_Board(port
);
1638 if (!port
->xmit_buf
) {
1644 spin_lock_irqsave(&port
->lock
, flags
);
1645 c
= min_t(int, count
, min(SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1,
1646 SERIAL_XMIT_SIZE
- port
->xmit_head
));
1648 spin_unlock_irqrestore(&port
->lock
, flags
);
1651 memcpy(port
->xmit_buf
+ port
->xmit_head
, buf
, c
);
1652 port
->xmit_head
= (port
->xmit_head
+ c
) & (SERIAL_XMIT_SIZE
-1);
1653 port
->xmit_cnt
+= c
;
1654 spin_unlock_irqrestore(&port
->lock
, flags
);
1661 spin_lock_irqsave(&bp
->lock
, flags
);
1662 if (port
->xmit_cnt
&& !tty
->stopped
&& !tty
->hw_stopped
&&
1663 !(port
->IER
& IER_TXRDY
)) {
1664 port
->IER
|= IER_TXRDY
;
1665 sx_out(bp
, CD186x_CAR
, port_No(port
));
1666 sx_out(bp
, CD186x_IER
, port
->IER
);
1668 spin_unlock_irqrestore(&bp
->lock
, flags
);
1675 static void sx_put_char(struct tty_struct
* tty
, unsigned char ch
)
1677 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1678 unsigned long flags
;
1679 struct specialix_board
* bp
;
1683 if (sx_paranoia_check(port
, tty
->name
, "sx_put_char")) {
1687 dprintk (SX_DEBUG_TX
, "check tty: %p %p\n", tty
, port
->xmit_buf
);
1688 if (!port
->xmit_buf
) {
1692 bp
= port_Board(port
);
1693 spin_lock_irqsave(&port
->lock
, flags
);
1695 dprintk (SX_DEBUG_TX
, "xmit_cnt: %d xmit_buf: %p\n", port
->xmit_cnt
, port
->xmit_buf
);
1696 if ((port
->xmit_cnt
>= SERIAL_XMIT_SIZE
- 1) || (!port
->xmit_buf
)) {
1697 spin_unlock_irqrestore(&port
->lock
, flags
);
1698 dprintk (SX_DEBUG_TX
, "Exit size\n");
1702 dprintk (SX_DEBUG_TX
, "Handle xmit: %p %p\n", port
, port
->xmit_buf
);
1703 port
->xmit_buf
[port
->xmit_head
++] = ch
;
1704 port
->xmit_head
&= SERIAL_XMIT_SIZE
- 1;
1706 spin_unlock_irqrestore(&port
->lock
, flags
);
1712 static void sx_flush_chars(struct tty_struct
* tty
)
1714 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1715 unsigned long flags
;
1716 struct specialix_board
* bp
= port_Board(port
);
1720 if (sx_paranoia_check(port
, tty
->name
, "sx_flush_chars")) {
1724 if (port
->xmit_cnt
<= 0 || tty
->stopped
|| tty
->hw_stopped
||
1729 spin_lock_irqsave(&bp
->lock
, flags
);
1730 port
->IER
|= IER_TXRDY
;
1731 sx_out(port_Board(port
), CD186x_CAR
, port_No(port
));
1732 sx_out(port_Board(port
), CD186x_IER
, port
->IER
);
1733 spin_unlock_irqrestore(&bp
->lock
, flags
);
1739 static int sx_write_room(struct tty_struct
* tty
)
1741 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1746 if (sx_paranoia_check(port
, tty
->name
, "sx_write_room")) {
1751 ret
= SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1;
1760 static int sx_chars_in_buffer(struct tty_struct
*tty
)
1762 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1766 if (sx_paranoia_check(port
, tty
->name
, "sx_chars_in_buffer")) {
1771 return port
->xmit_cnt
;
1775 static void sx_flush_buffer(struct tty_struct
*tty
)
1777 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1778 unsigned long flags
;
1779 struct specialix_board
* bp
;
1783 if (sx_paranoia_check(port
, tty
->name
, "sx_flush_buffer")) {
1788 bp
= port_Board(port
);
1789 spin_lock_irqsave(&port
->lock
, flags
);
1790 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1791 spin_unlock_irqrestore(&port
->lock
, flags
);
1798 static int sx_tiocmget(struct tty_struct
*tty
, struct file
*file
)
1800 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1801 struct specialix_board
* bp
;
1802 unsigned char status
;
1803 unsigned int result
;
1804 unsigned long flags
;
1808 if (sx_paranoia_check(port
, tty
->name
, __FUNCTION__
)) {
1813 bp
= port_Board(port
);
1814 spin_lock_irqsave (&bp
->lock
, flags
);
1815 sx_out(bp
, CD186x_CAR
, port_No(port
));
1816 status
= sx_in(bp
, CD186x_MSVR
);
1817 spin_unlock_irqrestore(&bp
->lock
, flags
);
1818 dprintk (SX_DEBUG_INIT
, "Got msvr[%d] = %02x, car = %d.\n",
1819 port_No(port
), status
, sx_in (bp
, CD186x_CAR
));
1820 dprintk (SX_DEBUG_INIT
, "sx_port = %p, port = %p\n", sx_port
, port
);
1821 if (SX_CRTSCTS(port
->tty
)) {
1822 result
= /* (status & MSVR_RTS) ? */ TIOCM_DTR
/* : 0) */
1823 | ((status
& MSVR_DTR
) ? TIOCM_RTS
: 0)
1824 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1825 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR
/* : 0) */
1826 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1828 result
= /* (status & MSVR_RTS) ? */ TIOCM_RTS
/* : 0) */
1829 | ((status
& MSVR_DTR
) ? TIOCM_DTR
: 0)
1830 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1831 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR
/* : 0) */
1832 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1841 static int sx_tiocmset(struct tty_struct
*tty
, struct file
*file
,
1842 unsigned int set
, unsigned int clear
)
1844 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1845 unsigned long flags
;
1846 struct specialix_board
*bp
;
1850 if (sx_paranoia_check(port
, tty
->name
, __FUNCTION__
)) {
1855 bp
= port_Board(port
);
1857 spin_lock_irqsave(&port
->lock
, flags
);
1858 /* if (set & TIOCM_RTS)
1859 port->MSVR |= MSVR_RTS; */
1860 /* if (set & TIOCM_DTR)
1861 port->MSVR |= MSVR_DTR; */
1863 if (SX_CRTSCTS(port
->tty
)) {
1864 if (set
& TIOCM_RTS
)
1865 port
->MSVR
|= MSVR_DTR
;
1867 if (set
& TIOCM_DTR
)
1868 port
->MSVR
|= MSVR_DTR
;
1871 /* if (clear & TIOCM_RTS)
1872 port->MSVR &= ~MSVR_RTS; */
1873 /* if (clear & TIOCM_DTR)
1874 port->MSVR &= ~MSVR_DTR; */
1875 if (SX_CRTSCTS(port
->tty
)) {
1876 if (clear
& TIOCM_RTS
)
1877 port
->MSVR
&= ~MSVR_DTR
;
1879 if (clear
& TIOCM_DTR
)
1880 port
->MSVR
&= ~MSVR_DTR
;
1882 spin_lock_irqsave(&bp
->lock
, flags
);
1883 sx_out(bp
, CD186x_CAR
, port_No(port
));
1884 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1885 spin_unlock_irqrestore(&bp
->lock
, flags
);
1886 spin_unlock_irqrestore(&port
->lock
, flags
);
1892 static inline void sx_send_break(struct specialix_port
* port
, unsigned long length
)
1894 struct specialix_board
*bp
= port_Board(port
);
1895 unsigned long flags
;
1899 spin_lock_irqsave (&port
->lock
, flags
);
1900 port
->break_length
= SPECIALIX_TPS
/ HZ
* length
;
1901 port
->COR2
|= COR2_ETC
;
1902 port
->IER
|= IER_TXRDY
;
1903 spin_lock_irqsave(&bp
->lock
, flags
);
1904 sx_out(bp
, CD186x_CAR
, port_No(port
));
1905 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1906 sx_out(bp
, CD186x_IER
, port
->IER
);
1907 spin_unlock_irqrestore(&bp
->lock
, flags
);
1908 spin_unlock_irqrestore (&port
->lock
, flags
);
1910 spin_lock_irqsave(&bp
->lock
, flags
);
1911 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
1912 spin_unlock_irqrestore(&bp
->lock
, flags
);
1919 static inline int sx_set_serial_info(struct specialix_port
* port
,
1920 struct serial_struct __user
* newinfo
)
1922 struct serial_struct tmp
;
1923 struct specialix_board
*bp
= port_Board(port
);
1928 if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1933 if (copy_from_user(&tmp
, newinfo
, sizeof(tmp
))) {
1939 if ((tmp
.irq
!= bp
->irq
) ||
1940 (tmp
.port
!= bp
->base
) ||
1941 (tmp
.type
!= PORT_CIRRUS
) ||
1942 (tmp
.baud_base
!= (SX_OSCFREQ
+ CD186x_TPC
/2) / CD186x_TPC
) ||
1943 (tmp
.custom_divisor
!= 0) ||
1944 (tmp
.xmit_fifo_size
!= CD186x_NFIFO
) ||
1945 (tmp
.flags
& ~SPECIALIX_LEGAL_FLAGS
)) {
1951 change_speed
= ((port
->flags
& ASYNC_SPD_MASK
) !=
1952 (tmp
.flags
& ASYNC_SPD_MASK
));
1953 change_speed
|= (tmp
.custom_divisor
!= port
->custom_divisor
);
1955 if (!capable(CAP_SYS_ADMIN
)) {
1956 if ((tmp
.close_delay
!= port
->close_delay
) ||
1957 (tmp
.closing_wait
!= port
->closing_wait
) ||
1958 ((tmp
.flags
& ~ASYNC_USR_MASK
) !=
1959 (port
->flags
& ~ASYNC_USR_MASK
))) {
1963 port
->flags
= ((port
->flags
& ~ASYNC_USR_MASK
) |
1964 (tmp
.flags
& ASYNC_USR_MASK
));
1965 port
->custom_divisor
= tmp
.custom_divisor
;
1967 port
->flags
= ((port
->flags
& ~ASYNC_FLAGS
) |
1968 (tmp
.flags
& ASYNC_FLAGS
));
1969 port
->close_delay
= tmp
.close_delay
;
1970 port
->closing_wait
= tmp
.closing_wait
;
1971 port
->custom_divisor
= tmp
.custom_divisor
;
1974 sx_change_speed(bp
, port
);
1981 static inline int sx_get_serial_info(struct specialix_port
* port
,
1982 struct serial_struct __user
*retinfo
)
1984 struct serial_struct tmp
;
1985 struct specialix_board
*bp
= port_Board(port
);
1990 if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
1994 memset(&tmp
, 0, sizeof(tmp
));
1995 tmp
.type
= PORT_CIRRUS
;
1996 tmp
.line
= port
- sx_port
;
1997 tmp
.port
= bp
->base
;
1999 tmp
.flags
= port
->flags
;
2000 tmp
.baud_base
= (SX_OSCFREQ
+ CD186x_TPC
/2) / CD186x_TPC
;
2001 tmp
.close_delay
= port
->close_delay
* HZ
/100;
2002 tmp
.closing_wait
= port
->closing_wait
* HZ
/100;
2003 tmp
.custom_divisor
= port
->custom_divisor
;
2004 tmp
.xmit_fifo_size
= CD186x_NFIFO
;
2005 if (copy_to_user(retinfo
, &tmp
, sizeof(tmp
))) {
2015 static int sx_ioctl(struct tty_struct
* tty
, struct file
* filp
,
2016 unsigned int cmd
, unsigned long arg
)
2018 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2020 void __user
*argp
= (void __user
*)arg
;
2024 if (sx_paranoia_check(port
, tty
->name
, "sx_ioctl")) {
2030 case TCSBRK
: /* SVID version: non-zero arg --> no break */
2031 retval
= tty_check_change(tty
);
2036 tty_wait_until_sent(tty
, 0);
2038 sx_send_break(port
, HZ
/4); /* 1/4 second */
2040 case TCSBRKP
: /* support for POSIX tcsendbreak() */
2041 retval
= tty_check_change(tty
);
2046 tty_wait_until_sent(tty
, 0);
2047 sx_send_break(port
, arg
? arg
*(HZ
/10) : HZ
/4);
2051 if (put_user(C_CLOCAL(tty
)?1:0, (unsigned long __user
*)argp
)) {
2058 if (get_user(arg
, (unsigned long __user
*) argp
)) {
2062 tty
->termios
->c_cflag
=
2063 ((tty
->termios
->c_cflag
& ~CLOCAL
) |
2064 (arg
? CLOCAL
: 0));
2069 return sx_get_serial_info(port
, argp
);
2072 return sx_set_serial_info(port
, argp
);
2075 return -ENOIOCTLCMD
;
2082 static void sx_throttle(struct tty_struct
* tty
)
2084 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2085 struct specialix_board
*bp
;
2086 unsigned long flags
;
2090 if (sx_paranoia_check(port
, tty
->name
, "sx_throttle")) {
2095 bp
= port_Board(port
);
2097 /* Use DTR instead of RTS ! */
2098 if (SX_CRTSCTS (tty
))
2099 port
->MSVR
&= ~MSVR_DTR
;
2101 /* Auch!!! I think the system shouldn't call this then. */
2102 /* Or maybe we're supposed (allowed?) to do our side of hw
2103 handshake anyway, even when hardware handshake is off.
2104 When you see this in your logs, please report.... */
2105 printk (KERN_ERR
"sx%d: Need to throttle, but can't (hardware hs is off)\n",
2108 spin_lock_irqsave(&bp
->lock
, flags
);
2109 sx_out(bp
, CD186x_CAR
, port_No(port
));
2110 spin_unlock_irqrestore(&bp
->lock
, flags
);
2113 spin_lock_irqsave(&bp
->lock
, flags
);
2114 sx_out(bp
, CD186x_CCR
, CCR_SSCH2
);
2115 spin_unlock_irqrestore(&bp
->lock
, flags
);
2118 spin_lock_irqsave(&bp
->lock
, flags
);
2119 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2120 spin_unlock_irqrestore(&bp
->lock
, flags
);
2126 static void sx_unthrottle(struct tty_struct
* tty
)
2128 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2129 struct specialix_board
*bp
;
2130 unsigned long flags
;
2134 if (sx_paranoia_check(port
, tty
->name
, "sx_unthrottle")) {
2139 bp
= port_Board(port
);
2141 spin_lock_irqsave(&port
->lock
, flags
);
2142 /* XXXX Use DTR INSTEAD???? */
2143 if (SX_CRTSCTS(tty
)) {
2144 port
->MSVR
|= MSVR_DTR
;
2145 } /* Else clause: see remark in "sx_throttle"... */
2146 spin_lock_irqsave(&bp
->lock
, flags
);
2147 sx_out(bp
, CD186x_CAR
, port_No(port
));
2148 spin_unlock_irqrestore(&bp
->lock
, flags
);
2150 spin_unlock_irqrestore(&port
->lock
, flags
);
2152 spin_lock_irqsave(&bp
->lock
, flags
);
2153 sx_out(bp
, CD186x_CCR
, CCR_SSCH1
);
2154 spin_unlock_irqrestore(&bp
->lock
, flags
);
2156 spin_lock_irqsave(&port
->lock
, flags
);
2158 spin_lock_irqsave(&bp
->lock
, flags
);
2159 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2160 spin_unlock_irqrestore(&bp
->lock
, flags
);
2161 spin_unlock_irqrestore(&port
->lock
, flags
);
2167 static void sx_stop(struct tty_struct
* tty
)
2169 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2170 struct specialix_board
*bp
;
2171 unsigned long flags
;
2175 if (sx_paranoia_check(port
, tty
->name
, "sx_stop")) {
2180 bp
= port_Board(port
);
2182 spin_lock_irqsave(&port
->lock
, flags
);
2183 port
->IER
&= ~IER_TXRDY
;
2184 spin_lock_irqsave(&bp
->lock
, flags
);
2185 sx_out(bp
, CD186x_CAR
, port_No(port
));
2186 sx_out(bp
, CD186x_IER
, port
->IER
);
2187 spin_unlock_irqrestore(&bp
->lock
, flags
);
2188 spin_unlock_irqrestore(&port
->lock
, flags
);
2194 static void sx_start(struct tty_struct
* tty
)
2196 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2197 struct specialix_board
*bp
;
2198 unsigned long flags
;
2202 if (sx_paranoia_check(port
, tty
->name
, "sx_start")) {
2207 bp
= port_Board(port
);
2209 spin_lock_irqsave(&port
->lock
, flags
);
2210 if (port
->xmit_cnt
&& port
->xmit_buf
&& !(port
->IER
& IER_TXRDY
)) {
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
);
2217 spin_unlock_irqrestore(&port
->lock
, flags
);
2222 static void sx_hangup(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_hangup")) {
2235 bp
= port_Board(port
);
2237 sx_shutdown_port(bp
, port
);
2238 spin_lock_irqsave(&port
->lock
, flags
);
2239 bp
->count
-= port
->count
;
2240 if (bp
->count
< 0) {
2241 printk(KERN_ERR
"sx%d: sx_hangup: bad board count: %d port: %d\n",
2242 board_No(bp
), bp
->count
, tty
->index
);
2246 port
->flags
&= ~ASYNC_NORMAL_ACTIVE
;
2248 spin_unlock_irqrestore(&port
->lock
, flags
);
2249 wake_up_interruptible(&port
->open_wait
);
2255 static void sx_set_termios(struct tty_struct
* tty
, struct ktermios
* old_termios
)
2257 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2258 unsigned long flags
;
2259 struct specialix_board
* bp
;
2261 if (sx_paranoia_check(port
, tty
->name
, "sx_set_termios"))
2264 if (tty
->termios
->c_cflag
== old_termios
->c_cflag
&&
2265 tty
->termios
->c_iflag
== old_termios
->c_iflag
)
2268 bp
= port_Board(port
);
2269 spin_lock_irqsave(&port
->lock
, flags
);
2270 sx_change_speed(port_Board(port
), port
);
2271 spin_unlock_irqrestore(&port
->lock
, flags
);
2273 if ((old_termios
->c_cflag
& CRTSCTS
) &&
2274 !(tty
->termios
->c_cflag
& CRTSCTS
)) {
2275 tty
->hw_stopped
= 0;
2280 static const struct tty_operations sx_ops
= {
2284 .put_char
= sx_put_char
,
2285 .flush_chars
= sx_flush_chars
,
2286 .write_room
= sx_write_room
,
2287 .chars_in_buffer
= sx_chars_in_buffer
,
2288 .flush_buffer
= sx_flush_buffer
,
2290 .throttle
= sx_throttle
,
2291 .unthrottle
= sx_unthrottle
,
2292 .set_termios
= sx_set_termios
,
2295 .hangup
= sx_hangup
,
2296 .tiocmget
= sx_tiocmget
,
2297 .tiocmset
= sx_tiocmset
,
2300 static int sx_init_drivers(void)
2307 specialix_driver
= alloc_tty_driver(SX_NBOARD
* SX_NPORT
);
2308 if (!specialix_driver
) {
2309 printk(KERN_ERR
"sx: Couldn't allocate tty_driver.\n");
2314 specialix_driver
->owner
= THIS_MODULE
;
2315 specialix_driver
->name
= "ttyW";
2316 specialix_driver
->major
= SPECIALIX_NORMAL_MAJOR
;
2317 specialix_driver
->type
= TTY_DRIVER_TYPE_SERIAL
;
2318 specialix_driver
->subtype
= SERIAL_TYPE_NORMAL
;
2319 specialix_driver
->init_termios
= tty_std_termios
;
2320 specialix_driver
->init_termios
.c_cflag
=
2321 B9600
| CS8
| CREAD
| HUPCL
| CLOCAL
;
2322 specialix_driver
->init_termios
.c_ispeed
= 9600;
2323 specialix_driver
->init_termios
.c_ospeed
= 9600;
2324 specialix_driver
->flags
= TTY_DRIVER_REAL_RAW
;
2325 tty_set_operations(specialix_driver
, &sx_ops
);
2327 if ((error
= tty_register_driver(specialix_driver
))) {
2328 put_tty_driver(specialix_driver
);
2329 printk(KERN_ERR
"sx: Couldn't register specialix IO8+ driver, error = %d\n",
2334 memset(sx_port
, 0, sizeof(sx_port
));
2335 for (i
= 0; i
< SX_NPORT
* SX_NBOARD
; i
++) {
2336 sx_port
[i
].magic
= SPECIALIX_MAGIC
;
2337 sx_port
[i
].close_delay
= 50 * HZ
/100;
2338 sx_port
[i
].closing_wait
= 3000 * HZ
/100;
2339 init_waitqueue_head(&sx_port
[i
].open_wait
);
2340 init_waitqueue_head(&sx_port
[i
].close_wait
);
2341 spin_lock_init(&sx_port
[i
].lock
);
2348 static void sx_release_drivers(void)
2352 tty_unregister_driver(specialix_driver
);
2353 put_tty_driver(specialix_driver
);
2358 * This routine must be called by kernel at boot time
2360 static int __init
specialix_init(void)
2367 printk(KERN_INFO
"sx: Specialix IO8+ driver v" VERSION
", (c) R.E.Wolff 1997/1998.\n");
2368 printk(KERN_INFO
"sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2369 #ifdef CONFIG_SPECIALIX_RTSCTS
2370 printk (KERN_INFO
"sx: DTR/RTS pin is always RTS.\n");
2372 printk (KERN_INFO
"sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2375 for (i
= 0; i
< SX_NBOARD
; i
++)
2376 spin_lock_init(&sx_board
[i
].lock
);
2378 if (sx_init_drivers()) {
2383 for (i
= 0; i
< SX_NBOARD
; i
++)
2384 if (sx_board
[i
].base
&& !sx_probe(&sx_board
[i
]))
2389 struct pci_dev
*pdev
= NULL
;
2392 while (i
< SX_NBOARD
) {
2393 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
) {
2397 pdev
= pci_get_device (PCI_VENDOR_ID_SPECIALIX
,
2398 PCI_DEVICE_ID_SPECIALIX_IO8
,
2402 if (pci_enable_device(pdev
))
2405 sx_board
[i
].irq
= pdev
->irq
;
2407 sx_board
[i
].base
= pci_resource_start (pdev
, 2);
2409 sx_board
[i
].flags
|= SX_BOARD_IS_PCI
;
2410 if (!sx_probe(&sx_board
[i
]))
2413 /* May exit pci_get sequence early with lots of boards */
2420 sx_release_drivers();
2421 printk(KERN_INFO
"sx: No specialix IO8+ boards detected.\n");
2430 static int iobase
[SX_NBOARD
] = {0,};
2432 static int irq
[SX_NBOARD
] = {0,};
2434 module_param_array(iobase
, int, NULL
, 0);
2435 module_param_array(irq
, int, NULL
, 0);
2436 module_param(sx_debug
, int, 0);
2437 module_param(sx_rxfifo
, int, 0);
2438 #ifdef SPECIALIX_TIMER
2439 module_param(sx_poll
, int, 0);
2443 * You can setup up to 4 boards.
2444 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2445 * You should specify the IRQs too in that case "irq=....,...".
2447 * More than 4 boards in one computer is not possible, as the card can
2448 * only use 4 different interrupts.
2451 static int __init
specialix_init_module(void)
2457 if (iobase
[0] || iobase
[1] || iobase
[2] || iobase
[3]) {
2458 for(i
= 0; i
< SX_NBOARD
; i
++) {
2459 sx_board
[i
].base
= iobase
[i
];
2460 sx_board
[i
].irq
= irq
[i
];
2461 sx_board
[i
].count
= 0;
2467 return specialix_init();
2470 static void __exit
specialix_exit_module(void)
2476 sx_release_drivers();
2477 for (i
= 0; i
< SX_NBOARD
; i
++)
2478 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
)
2479 sx_release_io_range(&sx_board
[i
]);
2480 #ifdef SPECIALIX_TIMER
2481 del_timer_sync(&missed_irq_timer
);
2487 static struct pci_device_id specialx_pci_tbl
[] __devinitdata
= {
2488 { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX
, PCI_DEVICE_ID_SPECIALIX_IO8
) },
2491 MODULE_DEVICE_TABLE(pci
, specialx_pci_tbl
);
2493 module_init(specialix_init_module
);
2494 module_exit(specialix_exit_module
);
2496 MODULE_LICENSE("GPL");