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 (-1, bp
);
448 mod_timer(&missed_irq_timer
, jiffies
+ sx_poll
);
454 /* Main probing routine, also sets irq. */
455 static int sx_probe(struct specialix_board
*bp
)
457 unsigned char val1
, val2
;
467 if (sx_request_io_range(bp
)) {
472 /* Are the I/O ports here ? */
473 sx_out_off(bp
, CD186x_PPRL
, 0x5a);
475 val1
= sx_in_off(bp
, CD186x_PPRL
);
477 sx_out_off(bp
, CD186x_PPRL
, 0xa5);
479 val2
= sx_in_off(bp
, CD186x_PPRL
);
482 if ((val1
!= 0x5a) || (val2
!= 0xa5)) {
483 printk(KERN_INFO
"sx%d: specialix IO8+ Board at 0x%03x not found.\n",
484 board_No(bp
), bp
->base
);
485 sx_release_io_range(bp
);
490 /* Check the DSR lines that Specialix uses as board
492 val1
= read_cross_byte (bp
, CD186x_MSVR
, MSVR_DSR
);
493 val2
= read_cross_byte (bp
, CD186x_MSVR
, MSVR_RTS
);
494 dprintk (SX_DEBUG_INIT
, "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
495 board_No(bp
), val1
, val2
);
497 /* They managed to switch the bit order between the docs and
498 the IO8+ card. The new PCI card now conforms to old docs.
499 They changed the PCI docs to reflect the situation on the
501 val2
= (bp
->flags
& SX_BOARD_IS_PCI
)?0x4d : 0xb2;
503 printk(KERN_INFO
"sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
504 board_No(bp
), val2
, bp
->base
, val1
);
505 sx_release_io_range(bp
);
512 /* It's time to find IRQ for this board */
513 for (retries
= 0; retries
< 5 && irqs
<= 0; retries
++) {
514 irqs
= probe_irq_on();
515 sx_init_CD186x(bp
); /* Reset CD186x chip */
516 sx_out(bp
, CD186x_CAR
, 2); /* Select port 2 */
518 sx_out(bp
, CD186x_CCR
, CCR_TXEN
); /* Enable transmitter */
519 sx_out(bp
, CD186x_IER
, IER_TXRDY
); /* Enable tx empty intr */
521 irqs
= probe_irq_off(irqs
);
523 dprintk (SX_DEBUG_INIT
, "SRSR = %02x, ", sx_in(bp
, CD186x_SRSR
));
524 dprintk (SX_DEBUG_INIT
, "TRAR = %02x, ", sx_in(bp
, CD186x_TRAR
));
525 dprintk (SX_DEBUG_INIT
, "GIVR = %02x, ", sx_in(bp
, CD186x_GIVR
));
526 dprintk (SX_DEBUG_INIT
, "GICR = %02x, ", sx_in(bp
, CD186x_GICR
));
527 dprintk (SX_DEBUG_INIT
, "\n");
529 /* Reset CD186x again */
530 if (!sx_init_CD186x(bp
)) {
531 /* Hmmm. This is dead code anyway. */
534 dprintk (SX_DEBUG_INIT
"val1 = %02x, val2 = %02x, val3 = %02x.\n",
541 printk(KERN_ERR
"sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
542 board_No(bp
), bp
->base
);
543 sx_release_io_range(bp
);
548 printk (KERN_INFO
"Started with irq=%d, but now have irq=%d.\n", bp
->irq
, irqs
);
552 /* Reset CD186x again */
553 if (!sx_init_CD186x(bp
)) {
554 sx_release_io_range(bp
);
559 sx_request_io_range(bp
);
560 bp
->flags
|= SX_BOARD_PRESENT
;
562 /* Chip revcode pkgtype
567 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
569 -- Thanks to Gwen Wang, Cirrus Logic.
572 switch (sx_in_off(bp
, CD186x_GFRCR
)) {
573 case 0x82:chip
= 1864;rev
='A';break;
574 case 0x83:chip
= 1865;rev
='A';break;
575 case 0x84:chip
= 1865;rev
='B';break;
576 case 0x85:chip
= 1865;rev
='C';break; /* Does not exist at this time */
577 default:chip
=-1;rev
='x';
580 dprintk (SX_DEBUG_INIT
, " GFCR = 0x%02x\n", sx_in_off(bp
, CD186x_GFRCR
) );
582 #ifdef SPECIALIX_TIMER
583 setup_timer(&missed_irq_timer
, missed_irq
, (unsigned long)bp
);
584 mod_timer(&missed_irq_timer
, jiffies
+ sx_poll
);
587 printk(KERN_INFO
"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
598 * Interrupt processing routines.
601 static inline struct specialix_port
* sx_get_port(struct specialix_board
* bp
,
602 unsigned char const * what
)
604 unsigned char channel
;
605 struct specialix_port
* port
= NULL
;
607 channel
= sx_in(bp
, CD186x_GICR
) >> GICR_CHAN_OFF
;
608 dprintk (SX_DEBUG_CHAN
, "channel: %d\n", channel
);
609 if (channel
< CD186x_NCH
) {
610 port
= &sx_port
[board_No(bp
) * SX_NPORT
+ channel
];
611 dprintk (SX_DEBUG_CHAN
, "port: %d %p flags: 0x%x\n",board_No(bp
) * SX_NPORT
+ channel
, port
, port
->flags
& ASYNC_INITIALIZED
);
613 if (port
->flags
& ASYNC_INITIALIZED
) {
614 dprintk (SX_DEBUG_CHAN
, "port: %d %p\n", channel
, port
);
619 printk(KERN_INFO
"sx%d: %s interrupt from invalid port %d\n",
620 board_No(bp
), what
, channel
);
625 static inline void sx_receive_exc(struct specialix_board
* bp
)
627 struct specialix_port
*port
;
628 struct tty_struct
*tty
;
629 unsigned char status
;
630 unsigned char ch
, flag
;
634 port
= sx_get_port(bp
, "Receive");
636 dprintk (SX_DEBUG_RX
, "Hmm, couldn't find port.\n");
642 status
= sx_in(bp
, CD186x_RCSR
);
644 dprintk (SX_DEBUG_RX
, "status: 0x%x\n", status
);
645 if (status
& RCSR_OE
) {
647 dprintk(SX_DEBUG_FIFO
, "sx%d: port %d: Overrun. Total %ld overruns.\n",
648 board_No(bp
), port_No(port
), port
->overrun
);
650 status
&= port
->mark_mask
;
652 /* This flip buffer check needs to be below the reading of the
653 status register to reset the chip's IRQ.... */
654 if (tty_buffer_request_room(tty
, 1) == 0) {
655 dprintk(SX_DEBUG_FIFO
, "sx%d: port %d: Working around flip buffer overflow.\n",
656 board_No(bp
), port_No(port
));
661 ch
= sx_in(bp
, CD186x_RDR
);
666 if (status
& RCSR_TOUT
) {
667 printk(KERN_INFO
"sx%d: port %d: Receiver timeout. Hardware problems ?\n",
668 board_No(bp
), port_No(port
));
672 } else if (status
& RCSR_BREAK
) {
673 dprintk(SX_DEBUG_RX
, "sx%d: port %d: Handling break...\n",
674 board_No(bp
), port_No(port
));
676 if (port
->flags
& ASYNC_SAK
)
679 } else if (status
& RCSR_PE
)
682 else if (status
& RCSR_FE
)
685 else if (status
& RCSR_OE
)
691 if(tty_insert_flip_char(tty
, ch
, flag
))
692 tty_flip_buffer_push(tty
);
697 static inline void sx_receive(struct specialix_board
* bp
)
699 struct specialix_port
*port
;
700 struct tty_struct
*tty
;
705 if (!(port
= sx_get_port(bp
, "Receive"))) {
706 dprintk (SX_DEBUG_RX
, "Hmm, couldn't find port.\n");
712 count
= sx_in(bp
, CD186x_RDCR
);
713 dprintk (SX_DEBUG_RX
, "port: %p: count: %d\n", port
, count
);
714 port
->hits
[count
> 8 ? 9 : count
]++;
716 tty_buffer_request_room(tty
, count
);
719 tty_insert_flip_char(tty
, sx_in(bp
, CD186x_RDR
), TTY_NORMAL
);
720 tty_flip_buffer_push(tty
);
725 static inline void sx_transmit(struct specialix_board
* bp
)
727 struct specialix_port
*port
;
728 struct tty_struct
*tty
;
732 if (!(port
= sx_get_port(bp
, "Transmit"))) {
736 dprintk (SX_DEBUG_TX
, "port: %p\n", port
);
739 if (port
->IER
& IER_TXEMPTY
) {
741 sx_out(bp
, CD186x_CAR
, port_No(port
));
742 port
->IER
&= ~IER_TXEMPTY
;
743 sx_out(bp
, CD186x_IER
, port
->IER
);
748 if ((port
->xmit_cnt
<= 0 && !port
->break_length
)
749 || tty
->stopped
|| tty
->hw_stopped
) {
750 sx_out(bp
, CD186x_CAR
, port_No(port
));
751 port
->IER
&= ~IER_TXRDY
;
752 sx_out(bp
, CD186x_IER
, port
->IER
);
757 if (port
->break_length
) {
758 if (port
->break_length
> 0) {
759 if (port
->COR2
& COR2_ETC
) {
760 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
761 sx_out(bp
, CD186x_TDR
, CD186x_C_SBRK
);
762 port
->COR2
&= ~COR2_ETC
;
764 count
= min_t(int, port
->break_length
, 0xff);
765 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
766 sx_out(bp
, CD186x_TDR
, CD186x_C_DELAY
);
767 sx_out(bp
, CD186x_TDR
, count
);
768 if (!(port
->break_length
-= count
))
769 port
->break_length
--;
771 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
772 sx_out(bp
, CD186x_TDR
, CD186x_C_EBRK
);
773 sx_out(bp
, CD186x_COR2
, port
->COR2
);
775 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
776 port
->break_length
= 0;
783 count
= CD186x_NFIFO
;
785 sx_out(bp
, CD186x_TDR
, port
->xmit_buf
[port
->xmit_tail
++]);
786 port
->xmit_tail
= port
->xmit_tail
& (SERIAL_XMIT_SIZE
-1);
787 if (--port
->xmit_cnt
<= 0)
789 } while (--count
> 0);
791 if (port
->xmit_cnt
<= 0) {
792 sx_out(bp
, CD186x_CAR
, port_No(port
));
793 port
->IER
&= ~IER_TXRDY
;
794 sx_out(bp
, CD186x_IER
, port
->IER
);
796 if (port
->xmit_cnt
<= port
->wakeup_chars
)
803 static inline void sx_check_modem(struct specialix_board
* bp
)
805 struct specialix_port
*port
;
806 struct tty_struct
*tty
;
810 dprintk (SX_DEBUG_SIGNALS
, "Modem intr. ");
811 if (!(port
= sx_get_port(bp
, "Modem")))
816 mcr
= sx_in(bp
, CD186x_MCR
);
817 printk ("mcr = %02x.\n", mcr
);
819 if ((mcr
& MCR_CDCHG
)) {
820 dprintk (SX_DEBUG_SIGNALS
, "CD just changed... ");
821 msvr_cd
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
823 dprintk (SX_DEBUG_SIGNALS
, "Waking up guys in open.\n");
824 wake_up_interruptible(&port
->open_wait
);
826 dprintk (SX_DEBUG_SIGNALS
, "Sending HUP.\n");
831 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
832 if (mcr
& MCR_CTSCHG
) {
833 if (sx_in(bp
, CD186x_MSVR
) & MSVR_CTS
) {
835 port
->IER
|= IER_TXRDY
;
836 if (port
->xmit_cnt
<= port
->wakeup_chars
)
840 port
->IER
&= ~IER_TXRDY
;
842 sx_out(bp
, CD186x_IER
, port
->IER
);
844 if (mcr
& MCR_DSSXHG
) {
845 if (sx_in(bp
, CD186x_MSVR
) & MSVR_DSR
) {
847 port
->IER
|= IER_TXRDY
;
848 if (port
->xmit_cnt
<= port
->wakeup_chars
)
852 port
->IER
&= ~IER_TXRDY
;
854 sx_out(bp
, CD186x_IER
, port
->IER
);
856 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
858 /* Clear change bits */
859 sx_out(bp
, CD186x_MCR
, 0);
863 /* The main interrupt processing routine */
864 static irqreturn_t
sx_interrupt(int dummy
, void *dev_id
)
866 unsigned char status
;
868 struct specialix_board
*bp
= dev_id
;
869 unsigned long loop
= 0;
875 spin_lock_irqsave(&bp
->lock
, flags
);
877 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);
878 if (!(bp
->flags
& SX_BOARD_ACTIVE
)) {
879 dprintk (SX_DEBUG_IRQ
, "sx: False interrupt. irq %d.\n", bp
->irq
);
880 spin_unlock_irqrestore(&bp
->lock
, flags
);
887 while ((++loop
< 16) && (status
= (sx_in(bp
, CD186x_SRSR
) &
891 if (status
& SRSR_RREQint
) {
892 ack
= sx_in(bp
, CD186x_RRAR
);
894 if (ack
== (SX_ID
| GIVR_IT_RCV
))
896 else if (ack
== (SX_ID
| GIVR_IT_REXC
))
899 printk(KERN_ERR
"sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
900 board_No(bp
), status
, ack
);
902 } else if (status
& SRSR_TREQint
) {
903 ack
= sx_in(bp
, CD186x_TRAR
);
905 if (ack
== (SX_ID
| GIVR_IT_TX
))
908 printk(KERN_ERR
"sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
909 board_No(bp
), status
, ack
, port_No (sx_get_port (bp
, "Int")));
910 } else if (status
& SRSR_MREQint
) {
911 ack
= sx_in(bp
, CD186x_MRAR
);
913 if (ack
== (SX_ID
| GIVR_IT_MODEM
))
916 printk(KERN_ERR
"sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
917 board_No(bp
), status
, ack
);
921 sx_out(bp
, CD186x_EOIR
, 0); /* Mark end of interrupt */
924 outb (bp
->reg
, bp
->base
+ SX_ADDR_REG
);
925 spin_unlock_irqrestore(&bp
->lock
, flags
);
932 * Routines for open & close processing.
935 static void turn_ints_off (struct specialix_board
*bp
)
940 if (bp
->flags
& SX_BOARD_IS_PCI
) {
941 /* This was intended for enabeling the interrupt on the
942 * PCI card. However it seems that it's already enabled
943 * and as PCI interrupts can be shared, there is no real
944 * reason to have to turn it off. */
947 spin_lock_irqsave(&bp
->lock
, flags
);
948 (void) sx_in_off (bp
, 0); /* Turn off interrupts. */
949 spin_unlock_irqrestore(&bp
->lock
, flags
);
954 static void turn_ints_on (struct specialix_board
*bp
)
960 if (bp
->flags
& SX_BOARD_IS_PCI
) {
961 /* play with the PCI chip. See comment above. */
963 spin_lock_irqsave(&bp
->lock
, flags
);
964 (void) sx_in (bp
, 0); /* Turn ON interrupts. */
965 spin_unlock_irqrestore(&bp
->lock
, flags
);
971 /* Called with disabled interrupts */
972 static inline int sx_setup_board(struct specialix_board
* bp
)
976 if (bp
->flags
& SX_BOARD_ACTIVE
)
979 if (bp
->flags
& SX_BOARD_IS_PCI
)
980 error
= request_irq(bp
->irq
, sx_interrupt
, IRQF_DISABLED
| IRQF_SHARED
, "specialix IO8+", bp
);
982 error
= request_irq(bp
->irq
, sx_interrupt
, IRQF_DISABLED
, "specialix IO8+", bp
);
988 bp
->flags
|= SX_BOARD_ACTIVE
;
994 /* Called with disabled interrupts */
995 static inline void sx_shutdown_board(struct specialix_board
*bp
)
999 if (!(bp
->flags
& SX_BOARD_ACTIVE
)) {
1004 bp
->flags
&= ~SX_BOARD_ACTIVE
;
1006 dprintk (SX_DEBUG_IRQ
, "Freeing IRQ%d for board %d.\n",
1007 bp
->irq
, board_No (bp
));
1008 free_irq(bp
->irq
, bp
);
1018 * Setting up port characteristics.
1019 * Must be called with disabled interrupts
1021 static void sx_change_speed(struct specialix_board
*bp
, struct specialix_port
*port
)
1023 struct tty_struct
*tty
;
1026 unsigned char cor1
= 0, cor3
= 0;
1027 unsigned char mcor1
= 0, mcor2
= 0;
1028 static unsigned long again
;
1029 unsigned long flags
;
1033 if (!(tty
= port
->tty
) || !tty
->termios
) {
1040 /* Select port on the board */
1041 spin_lock_irqsave(&bp
->lock
, flags
);
1042 sx_out(bp
, CD186x_CAR
, port_No(port
));
1044 /* The Specialix board doens't implement the RTS lines.
1045 They are used to set the IRQ level. Don't touch them. */
1046 if (SX_CRTSCTS(tty
))
1047 port
->MSVR
= MSVR_DTR
| (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
1049 port
->MSVR
= (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
1050 spin_unlock_irqrestore(&bp
->lock
, flags
);
1051 dprintk (SX_DEBUG_TERMIOS
, "sx: got MSVR=%02x.\n", port
->MSVR
);
1052 baud
= tty_get_baud_rate(tty
);
1054 if (baud
== 38400) {
1055 if ((port
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_HI
)
1057 if ((port
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_VHI
)
1062 /* Drop DTR & exit */
1063 dprintk (SX_DEBUG_TERMIOS
, "Dropping DTR... Hmm....\n");
1064 if (!SX_CRTSCTS (tty
)) {
1065 port
-> MSVR
&= ~ MSVR_DTR
;
1066 spin_lock_irqsave(&bp
->lock
, flags
);
1067 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1068 spin_unlock_irqrestore(&bp
->lock
, flags
);
1071 dprintk (SX_DEBUG_TERMIOS
, "Can't drop DTR: no DTR.\n");
1075 if (!SX_CRTSCTS (tty
)) {
1076 port
->MSVR
|= MSVR_DTR
;
1081 * Now we must calculate some speed depended things
1084 /* Set baud rate for port */
1085 tmp
= port
->custom_divisor
;
1087 printk (KERN_INFO
"sx%d: Using custom baud rate divisor %ld. \n"
1088 "This is an untested option, please be carefull.\n",
1089 port_No (port
), tmp
);
1091 tmp
= (((SX_OSCFREQ
+ baud
/2) / baud
+
1092 CD186x_TPC
/2) / CD186x_TPC
);
1094 if ((tmp
< 0x10) && time_before(again
, jiffies
)) {
1095 again
= jiffies
+ HZ
* 60;
1096 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1098 printk (KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1099 "Performance degradation is possible.\n"
1100 "Read specialix.txt for more info.\n",
1101 port_No (port
), tmp
);
1103 printk (KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1104 "Warning: overstressing Cirrus chip. "
1105 "This might not work.\n"
1106 "Read specialix.txt for more info.\n",
1107 port_No (port
), tmp
);
1110 spin_lock_irqsave(&bp
->lock
, flags
);
1111 sx_out(bp
, CD186x_RBPRH
, (tmp
>> 8) & 0xff);
1112 sx_out(bp
, CD186x_TBPRH
, (tmp
>> 8) & 0xff);
1113 sx_out(bp
, CD186x_RBPRL
, tmp
& 0xff);
1114 sx_out(bp
, CD186x_TBPRL
, tmp
& 0xff);
1115 spin_unlock_irqrestore(&bp
->lock
, flags
);
1116 if (port
->custom_divisor
)
1117 baud
= (SX_OSCFREQ
+ port
->custom_divisor
/2) / port
->custom_divisor
;
1118 baud
= (baud
+ 5) / 10; /* Estimated CPS */
1120 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1121 tmp
= ((baud
+ HZ
/2) / HZ
) * 2 - CD186x_NFIFO
;
1122 port
->wakeup_chars
= (tmp
< 0) ? 0 : ((tmp
>= SERIAL_XMIT_SIZE
) ?
1123 SERIAL_XMIT_SIZE
- 1 : tmp
);
1125 /* Receiver timeout will be transmission time for 1.5 chars */
1126 tmp
= (SPECIALIX_TPS
+ SPECIALIX_TPS
/2 + baud
/2) / baud
;
1127 tmp
= (tmp
> 0xff) ? 0xff : tmp
;
1128 spin_lock_irqsave(&bp
->lock
, flags
);
1129 sx_out(bp
, CD186x_RTPR
, tmp
);
1130 spin_unlock_irqrestore(&bp
->lock
, flags
);
1131 switch (C_CSIZE(tty
)) {
1149 cor1
|= COR1_IGNORE
;
1150 if (C_PARENB(tty
)) {
1151 cor1
|= COR1_NORMPAR
;
1155 cor1
&= ~COR1_IGNORE
;
1157 /* Set marking of some errors */
1158 port
->mark_mask
= RCSR_OE
| RCSR_TOUT
;
1160 port
->mark_mask
|= RCSR_FE
| RCSR_PE
;
1161 if (I_BRKINT(tty
) || I_PARMRK(tty
))
1162 port
->mark_mask
|= RCSR_BREAK
;
1164 port
->mark_mask
&= ~(RCSR_FE
| RCSR_PE
);
1165 if (I_IGNBRK(tty
)) {
1166 port
->mark_mask
&= ~RCSR_BREAK
;
1168 /* Real raw mode. Ignore all */
1169 port
->mark_mask
&= ~RCSR_OE
;
1171 /* Enable Hardware Flow Control */
1172 if (C_CRTSCTS(tty
)) {
1173 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1174 port
->IER
|= IER_DSR
| IER_CTS
;
1175 mcor1
|= MCOR1_DSRZD
| MCOR1_CTSZD
;
1176 mcor2
|= MCOR2_DSROD
| MCOR2_CTSOD
;
1177 spin_lock_irqsave(&bp
->lock
, flags
);
1178 tty
->hw_stopped
= !(sx_in(bp
, CD186x_MSVR
) & (MSVR_CTS
|MSVR_DSR
));
1179 spin_unlock_irqrestore(&bp
->lock
, flags
);
1181 port
->COR2
|= COR2_CTSAE
;
1184 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1185 /* Some people reported that it works, but I still doubt it */
1187 port
->COR2
|= COR2_TXIBE
;
1188 cor3
|= (COR3_FCT
| COR3_SCDE
);
1190 port
->COR2
|= COR2_IXM
;
1191 spin_lock_irqsave(&bp
->lock
, flags
);
1192 sx_out(bp
, CD186x_SCHR1
, START_CHAR(tty
));
1193 sx_out(bp
, CD186x_SCHR2
, STOP_CHAR(tty
));
1194 sx_out(bp
, CD186x_SCHR3
, START_CHAR(tty
));
1195 sx_out(bp
, CD186x_SCHR4
, STOP_CHAR(tty
));
1196 spin_unlock_irqrestore(&bp
->lock
, flags
);
1198 if (!C_CLOCAL(tty
)) {
1199 /* Enable CD check */
1200 port
->IER
|= IER_CD
;
1201 mcor1
|= MCOR1_CDZD
;
1202 mcor2
|= MCOR2_CDOD
;
1206 /* Enable receiver */
1207 port
->IER
|= IER_RXD
;
1209 /* Set input FIFO size (1-8 bytes) */
1211 /* Setting up CD186x channel registers */
1212 spin_lock_irqsave(&bp
->lock
, flags
);
1213 sx_out(bp
, CD186x_COR1
, cor1
);
1214 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1215 sx_out(bp
, CD186x_COR3
, cor3
);
1216 spin_unlock_irqrestore(&bp
->lock
, flags
);
1217 /* Make CD186x know about registers change */
1219 spin_lock_irqsave(&bp
->lock
, flags
);
1220 sx_out(bp
, CD186x_CCR
, CCR_CORCHG1
| CCR_CORCHG2
| CCR_CORCHG3
);
1221 /* Setting up modem option registers */
1222 dprintk (SX_DEBUG_TERMIOS
, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1
, mcor2
);
1223 sx_out(bp
, CD186x_MCOR1
, mcor1
);
1224 sx_out(bp
, CD186x_MCOR2
, mcor2
);
1225 spin_unlock_irqrestore(&bp
->lock
, flags
);
1226 /* Enable CD186x transmitter & receiver */
1228 spin_lock_irqsave(&bp
->lock
, flags
);
1229 sx_out(bp
, CD186x_CCR
, CCR_TXEN
| CCR_RXEN
);
1230 /* Enable interrupts */
1231 sx_out(bp
, CD186x_IER
, port
->IER
);
1232 /* And finally set the modem lines... */
1233 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1234 spin_unlock_irqrestore(&bp
->lock
, flags
);
1240 /* Must be called with interrupts enabled */
1241 static int sx_setup_port(struct specialix_board
*bp
, struct specialix_port
*port
)
1243 unsigned long flags
;
1247 if (port
->flags
& ASYNC_INITIALIZED
) {
1252 if (!port
->xmit_buf
) {
1253 /* We may sleep in get_zeroed_page() */
1256 if (!(tmp
= get_zeroed_page(GFP_KERNEL
))) {
1261 if (port
->xmit_buf
) {
1264 return -ERESTARTSYS
;
1266 port
->xmit_buf
= (unsigned char *) tmp
;
1269 spin_lock_irqsave(&port
->lock
, flags
);
1272 clear_bit(TTY_IO_ERROR
, &port
->tty
->flags
);
1274 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1275 sx_change_speed(bp
, port
);
1276 port
->flags
|= ASYNC_INITIALIZED
;
1278 spin_unlock_irqrestore(&port
->lock
, flags
);
1286 /* Must be called with interrupts disabled */
1287 static void sx_shutdown_port(struct specialix_board
*bp
, struct specialix_port
*port
)
1289 struct tty_struct
*tty
;
1291 unsigned long flags
;
1295 if (!(port
->flags
& ASYNC_INITIALIZED
)) {
1300 if (sx_debug
& SX_DEBUG_FIFO
) {
1301 dprintk(SX_DEBUG_FIFO
, "sx%d: port %d: %ld overruns, FIFO hits [ ",
1302 board_No(bp
), port_No(port
), port
->overrun
);
1303 for (i
= 0; i
< 10; i
++) {
1304 dprintk(SX_DEBUG_FIFO
, "%ld ", port
->hits
[i
]);
1306 dprintk(SX_DEBUG_FIFO
, "].\n");
1309 if (port
->xmit_buf
) {
1310 free_page((unsigned long) port
->xmit_buf
);
1311 port
->xmit_buf
= NULL
;
1315 spin_lock_irqsave(&bp
->lock
, flags
);
1316 sx_out(bp
, CD186x_CAR
, port_No(port
));
1318 if (!(tty
= port
->tty
) || C_HUPCL(tty
)) {
1320 sx_out(bp
, CD186x_MSVDTR
, 0);
1322 spin_unlock_irqrestore(&bp
->lock
, flags
);
1325 spin_lock_irqsave(&bp
->lock
, flags
);
1326 sx_out(bp
, CD186x_CCR
, CCR_SOFTRESET
);
1327 /* Disable all interrupts from this port */
1329 sx_out(bp
, CD186x_IER
, port
->IER
);
1330 spin_unlock_irqrestore(&bp
->lock
, flags
);
1332 set_bit(TTY_IO_ERROR
, &tty
->flags
);
1333 port
->flags
&= ~ASYNC_INITIALIZED
;
1336 sx_shutdown_board(bp
);
1341 static int block_til_ready(struct tty_struct
*tty
, struct file
* filp
,
1342 struct specialix_port
*port
)
1344 DECLARE_WAITQUEUE(wait
, current
);
1345 struct specialix_board
*bp
= port_Board(port
);
1349 unsigned long flags
;
1354 * If the device is in the middle of being closed, then block
1355 * until it's done, and then try again.
1357 if (tty_hung_up_p(filp
) || port
->flags
& ASYNC_CLOSING
) {
1358 interruptible_sleep_on(&port
->close_wait
);
1359 if (port
->flags
& ASYNC_HUP_NOTIFY
) {
1364 return -ERESTARTSYS
;
1369 * If non-blocking mode is set, or the port is not enabled,
1370 * then make the check up front and then exit.
1372 if ((filp
->f_flags
& O_NONBLOCK
) ||
1373 (tty
->flags
& (1 << TTY_IO_ERROR
))) {
1374 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
1383 * Block waiting for the carrier detect and the line to become
1384 * free (i.e., not in use by the callout). While we are in
1385 * this loop, info->count is dropped by one, so that
1386 * rs_close() knows when to free things. We restore it upon
1387 * exit, either normal or abnormal.
1390 add_wait_queue(&port
->open_wait
, &wait
);
1391 spin_lock_irqsave(&port
->lock
, flags
);
1392 if (!tty_hung_up_p(filp
)) {
1395 spin_unlock_irqrestore(&port
->lock
, flags
);
1396 port
->blocked_open
++;
1398 spin_lock_irqsave(&bp
->lock
, flags
);
1399 sx_out(bp
, CD186x_CAR
, port_No(port
));
1400 CD
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
1401 if (SX_CRTSCTS (tty
)) {
1403 port
->MSVR
|= MSVR_DTR
; /* WTF? */
1404 sx_out (bp
, CD186x_MSVR
, port
->MSVR
);
1407 port
->MSVR
|= MSVR_DTR
;
1408 sx_out (bp
, CD186x_MSVR
, port
->MSVR
);
1410 spin_unlock_irqrestore(&bp
->lock
, flags
);
1411 set_current_state(TASK_INTERRUPTIBLE
);
1412 if (tty_hung_up_p(filp
) ||
1413 !(port
->flags
& ASYNC_INITIALIZED
)) {
1414 if (port
->flags
& ASYNC_HUP_NOTIFY
)
1417 retval
= -ERESTARTSYS
;
1420 if (!(port
->flags
& ASYNC_CLOSING
) &&
1423 if (signal_pending(current
)) {
1424 retval
= -ERESTARTSYS
;
1430 set_current_state(TASK_RUNNING
);
1431 remove_wait_queue(&port
->open_wait
, &wait
);
1432 spin_lock_irqsave(&port
->lock
, flags
);
1433 if (!tty_hung_up_p(filp
)) {
1436 port
->blocked_open
--;
1437 spin_unlock_irqrestore(&port
->lock
, flags
);
1443 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
1449 static int sx_open(struct tty_struct
* tty
, struct file
* filp
)
1453 struct specialix_port
* port
;
1454 struct specialix_board
* bp
;
1456 unsigned long flags
;
1460 board
= SX_BOARD(tty
->index
);
1462 if (board
>= SX_NBOARD
|| !(sx_board
[board
].flags
& SX_BOARD_PRESENT
)) {
1467 bp
= &sx_board
[board
];
1468 port
= sx_port
+ board
* SX_NPORT
+ SX_PORT(tty
->index
);
1470 for (i
= 0; i
< 10; i
++)
1473 dprintk (SX_DEBUG_OPEN
, "Board = %d, bp = %p, port = %p, portno = %d.\n",
1474 board
, bp
, port
, SX_PORT(tty
->index
));
1476 if (sx_paranoia_check(port
, tty
->name
, "sx_open")) {
1481 if ((error
= sx_setup_board(bp
))) {
1486 spin_lock_irqsave(&bp
->lock
, flags
);
1489 tty
->driver_data
= port
;
1491 spin_unlock_irqrestore(&bp
->lock
, flags
);
1493 if ((error
= sx_setup_port(bp
, port
))) {
1498 if ((error
= block_til_ready(tty
, filp
, port
))) {
1508 static void sx_close(struct tty_struct
* tty
, struct file
* filp
)
1510 struct specialix_port
*port
= (struct specialix_port
*) tty
->driver_data
;
1511 struct specialix_board
*bp
;
1512 unsigned long flags
;
1513 unsigned long timeout
;
1516 if (!port
|| sx_paranoia_check(port
, tty
->name
, "close")) {
1520 spin_lock_irqsave(&port
->lock
, flags
);
1522 if (tty_hung_up_p(filp
)) {
1523 spin_unlock_irqrestore(&port
->lock
, flags
);
1528 bp
= port_Board(port
);
1529 if ((tty
->count
== 1) && (port
->count
!= 1)) {
1530 printk(KERN_ERR
"sx%d: sx_close: bad port count;"
1531 " tty->count is 1, port count is %d\n",
1532 board_No(bp
), port
->count
);
1536 if (port
->count
> 1) {
1540 spin_unlock_irqrestore(&port
->lock
, flags
);
1545 port
->flags
|= ASYNC_CLOSING
;
1547 * Now we wait for the transmit buffer to clear; and we notify
1548 * the line discipline to only process XON/XOFF characters.
1551 spin_unlock_irqrestore(&port
->lock
, flags
);
1552 dprintk (SX_DEBUG_OPEN
, "Closing\n");
1553 if (port
->closing_wait
!= ASYNC_CLOSING_WAIT_NONE
) {
1554 tty_wait_until_sent(tty
, port
->closing_wait
);
1557 * At this point we stop accepting input. To do this, we
1558 * disable the receive line status interrupts, and tell the
1559 * interrupt driver to stop checking the data ready bit in the
1560 * line status register.
1562 dprintk (SX_DEBUG_OPEN
, "Closed\n");
1563 port
->IER
&= ~IER_RXD
;
1564 if (port
->flags
& ASYNC_INITIALIZED
) {
1565 port
->IER
&= ~IER_TXRDY
;
1566 port
->IER
|= IER_TXEMPTY
;
1567 spin_lock_irqsave(&bp
->lock
, flags
);
1568 sx_out(bp
, CD186x_CAR
, port_No(port
));
1569 sx_out(bp
, CD186x_IER
, port
->IER
);
1570 spin_unlock_irqrestore(&bp
->lock
, flags
);
1572 * Before we drop DTR, make sure the UART transmitter
1573 * has completely drained; this is especially
1574 * important if there is a transmit FIFO!
1576 timeout
= jiffies
+HZ
;
1577 while(port
->IER
& IER_TXEMPTY
) {
1578 set_current_state (TASK_INTERRUPTIBLE
);
1579 msleep_interruptible(jiffies_to_msecs(port
->timeout
));
1580 if (time_after(jiffies
, timeout
)) {
1581 printk (KERN_INFO
"Timeout waiting for close\n");
1588 if (--bp
->count
< 0) {
1589 printk(KERN_ERR
"sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1590 board_No(bp
), bp
->count
, tty
->index
);
1593 if (--port
->count
< 0) {
1594 printk(KERN_ERR
"sx%d: sx_close: bad port count for tty%d: %d\n",
1595 board_No(bp
), port_No(port
), port
->count
);
1599 sx_shutdown_port(bp
, port
);
1600 if (tty
->driver
->flush_buffer
)
1601 tty
->driver
->flush_buffer(tty
);
1602 tty_ldisc_flush(tty
);
1603 spin_lock_irqsave(&port
->lock
, flags
);
1606 spin_unlock_irqrestore(&port
->lock
, flags
);
1607 if (port
->blocked_open
) {
1608 if (port
->close_delay
) {
1609 msleep_interruptible(jiffies_to_msecs(port
->close_delay
));
1611 wake_up_interruptible(&port
->open_wait
);
1613 port
->flags
&= ~(ASYNC_NORMAL_ACTIVE
|ASYNC_CLOSING
);
1614 wake_up_interruptible(&port
->close_wait
);
1620 static int sx_write(struct tty_struct
* tty
,
1621 const unsigned char *buf
, int count
)
1623 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1624 struct specialix_board
*bp
;
1626 unsigned long flags
;
1629 if (sx_paranoia_check(port
, tty
->name
, "sx_write")) {
1634 bp
= port_Board(port
);
1636 if (!port
->xmit_buf
) {
1642 spin_lock_irqsave(&port
->lock
, flags
);
1643 c
= min_t(int, count
, min(SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1,
1644 SERIAL_XMIT_SIZE
- port
->xmit_head
));
1646 spin_unlock_irqrestore(&port
->lock
, flags
);
1649 memcpy(port
->xmit_buf
+ port
->xmit_head
, buf
, c
);
1650 port
->xmit_head
= (port
->xmit_head
+ c
) & (SERIAL_XMIT_SIZE
-1);
1651 port
->xmit_cnt
+= c
;
1652 spin_unlock_irqrestore(&port
->lock
, flags
);
1659 spin_lock_irqsave(&bp
->lock
, flags
);
1660 if (port
->xmit_cnt
&& !tty
->stopped
&& !tty
->hw_stopped
&&
1661 !(port
->IER
& IER_TXRDY
)) {
1662 port
->IER
|= IER_TXRDY
;
1663 sx_out(bp
, CD186x_CAR
, port_No(port
));
1664 sx_out(bp
, CD186x_IER
, port
->IER
);
1666 spin_unlock_irqrestore(&bp
->lock
, flags
);
1673 static void sx_put_char(struct tty_struct
* tty
, unsigned char ch
)
1675 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1676 unsigned long flags
;
1677 struct specialix_board
* bp
;
1681 if (sx_paranoia_check(port
, tty
->name
, "sx_put_char")) {
1685 dprintk (SX_DEBUG_TX
, "check tty: %p %p\n", tty
, port
->xmit_buf
);
1686 if (!port
->xmit_buf
) {
1690 bp
= port_Board(port
);
1691 spin_lock_irqsave(&port
->lock
, flags
);
1693 dprintk (SX_DEBUG_TX
, "xmit_cnt: %d xmit_buf: %p\n", port
->xmit_cnt
, port
->xmit_buf
);
1694 if ((port
->xmit_cnt
>= SERIAL_XMIT_SIZE
- 1) || (!port
->xmit_buf
)) {
1695 spin_unlock_irqrestore(&port
->lock
, flags
);
1696 dprintk (SX_DEBUG_TX
, "Exit size\n");
1700 dprintk (SX_DEBUG_TX
, "Handle xmit: %p %p\n", port
, port
->xmit_buf
);
1701 port
->xmit_buf
[port
->xmit_head
++] = ch
;
1702 port
->xmit_head
&= SERIAL_XMIT_SIZE
- 1;
1704 spin_unlock_irqrestore(&port
->lock
, flags
);
1710 static void sx_flush_chars(struct tty_struct
* tty
)
1712 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1713 unsigned long flags
;
1714 struct specialix_board
* bp
= port_Board(port
);
1718 if (sx_paranoia_check(port
, tty
->name
, "sx_flush_chars")) {
1722 if (port
->xmit_cnt
<= 0 || tty
->stopped
|| tty
->hw_stopped
||
1727 spin_lock_irqsave(&bp
->lock
, flags
);
1728 port
->IER
|= IER_TXRDY
;
1729 sx_out(port_Board(port
), CD186x_CAR
, port_No(port
));
1730 sx_out(port_Board(port
), CD186x_IER
, port
->IER
);
1731 spin_unlock_irqrestore(&bp
->lock
, flags
);
1737 static int sx_write_room(struct tty_struct
* tty
)
1739 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1744 if (sx_paranoia_check(port
, tty
->name
, "sx_write_room")) {
1749 ret
= SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1;
1758 static int sx_chars_in_buffer(struct tty_struct
*tty
)
1760 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1764 if (sx_paranoia_check(port
, tty
->name
, "sx_chars_in_buffer")) {
1769 return port
->xmit_cnt
;
1773 static void sx_flush_buffer(struct tty_struct
*tty
)
1775 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1776 unsigned long flags
;
1777 struct specialix_board
* bp
;
1781 if (sx_paranoia_check(port
, tty
->name
, "sx_flush_buffer")) {
1786 bp
= port_Board(port
);
1787 spin_lock_irqsave(&port
->lock
, flags
);
1788 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1789 spin_unlock_irqrestore(&port
->lock
, flags
);
1796 static int sx_tiocmget(struct tty_struct
*tty
, struct file
*file
)
1798 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1799 struct specialix_board
* bp
;
1800 unsigned char status
;
1801 unsigned int result
;
1802 unsigned long flags
;
1806 if (sx_paranoia_check(port
, tty
->name
, __FUNCTION__
)) {
1811 bp
= port_Board(port
);
1812 spin_lock_irqsave (&bp
->lock
, flags
);
1813 sx_out(bp
, CD186x_CAR
, port_No(port
));
1814 status
= sx_in(bp
, CD186x_MSVR
);
1815 spin_unlock_irqrestore(&bp
->lock
, flags
);
1816 dprintk (SX_DEBUG_INIT
, "Got msvr[%d] = %02x, car = %d.\n",
1817 port_No(port
), status
, sx_in (bp
, CD186x_CAR
));
1818 dprintk (SX_DEBUG_INIT
, "sx_port = %p, port = %p\n", sx_port
, port
);
1819 if (SX_CRTSCTS(port
->tty
)) {
1820 result
= /* (status & MSVR_RTS) ? */ TIOCM_DTR
/* : 0) */
1821 | ((status
& MSVR_DTR
) ? TIOCM_RTS
: 0)
1822 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1823 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR
/* : 0) */
1824 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1826 result
= /* (status & MSVR_RTS) ? */ TIOCM_RTS
/* : 0) */
1827 | ((status
& MSVR_DTR
) ? TIOCM_DTR
: 0)
1828 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1829 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR
/* : 0) */
1830 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1839 static int sx_tiocmset(struct tty_struct
*tty
, struct file
*file
,
1840 unsigned int set
, unsigned int clear
)
1842 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1843 unsigned long flags
;
1844 struct specialix_board
*bp
;
1848 if (sx_paranoia_check(port
, tty
->name
, __FUNCTION__
)) {
1853 bp
= port_Board(port
);
1855 spin_lock_irqsave(&port
->lock
, flags
);
1856 /* if (set & TIOCM_RTS)
1857 port->MSVR |= MSVR_RTS; */
1858 /* if (set & TIOCM_DTR)
1859 port->MSVR |= MSVR_DTR; */
1861 if (SX_CRTSCTS(port
->tty
)) {
1862 if (set
& TIOCM_RTS
)
1863 port
->MSVR
|= MSVR_DTR
;
1865 if (set
& TIOCM_DTR
)
1866 port
->MSVR
|= MSVR_DTR
;
1869 /* if (clear & TIOCM_RTS)
1870 port->MSVR &= ~MSVR_RTS; */
1871 /* if (clear & TIOCM_DTR)
1872 port->MSVR &= ~MSVR_DTR; */
1873 if (SX_CRTSCTS(port
->tty
)) {
1874 if (clear
& TIOCM_RTS
)
1875 port
->MSVR
&= ~MSVR_DTR
;
1877 if (clear
& TIOCM_DTR
)
1878 port
->MSVR
&= ~MSVR_DTR
;
1880 spin_lock_irqsave(&bp
->lock
, flags
);
1881 sx_out(bp
, CD186x_CAR
, port_No(port
));
1882 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1883 spin_unlock_irqrestore(&bp
->lock
, flags
);
1884 spin_unlock_irqrestore(&port
->lock
, flags
);
1890 static inline void sx_send_break(struct specialix_port
* port
, unsigned long length
)
1892 struct specialix_board
*bp
= port_Board(port
);
1893 unsigned long flags
;
1897 spin_lock_irqsave (&port
->lock
, flags
);
1898 port
->break_length
= SPECIALIX_TPS
/ HZ
* length
;
1899 port
->COR2
|= COR2_ETC
;
1900 port
->IER
|= IER_TXRDY
;
1901 spin_lock_irqsave(&bp
->lock
, flags
);
1902 sx_out(bp
, CD186x_CAR
, port_No(port
));
1903 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1904 sx_out(bp
, CD186x_IER
, port
->IER
);
1905 spin_unlock_irqrestore(&bp
->lock
, flags
);
1906 spin_unlock_irqrestore (&port
->lock
, flags
);
1908 spin_lock_irqsave(&bp
->lock
, flags
);
1909 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
1910 spin_unlock_irqrestore(&bp
->lock
, flags
);
1917 static inline int sx_set_serial_info(struct specialix_port
* port
,
1918 struct serial_struct __user
* newinfo
)
1920 struct serial_struct tmp
;
1921 struct specialix_board
*bp
= port_Board(port
);
1926 if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1931 if (copy_from_user(&tmp
, newinfo
, sizeof(tmp
))) {
1937 if ((tmp
.irq
!= bp
->irq
) ||
1938 (tmp
.port
!= bp
->base
) ||
1939 (tmp
.type
!= PORT_CIRRUS
) ||
1940 (tmp
.baud_base
!= (SX_OSCFREQ
+ CD186x_TPC
/2) / CD186x_TPC
) ||
1941 (tmp
.custom_divisor
!= 0) ||
1942 (tmp
.xmit_fifo_size
!= CD186x_NFIFO
) ||
1943 (tmp
.flags
& ~SPECIALIX_LEGAL_FLAGS
)) {
1949 change_speed
= ((port
->flags
& ASYNC_SPD_MASK
) !=
1950 (tmp
.flags
& ASYNC_SPD_MASK
));
1951 change_speed
|= (tmp
.custom_divisor
!= port
->custom_divisor
);
1953 if (!capable(CAP_SYS_ADMIN
)) {
1954 if ((tmp
.close_delay
!= port
->close_delay
) ||
1955 (tmp
.closing_wait
!= port
->closing_wait
) ||
1956 ((tmp
.flags
& ~ASYNC_USR_MASK
) !=
1957 (port
->flags
& ~ASYNC_USR_MASK
))) {
1961 port
->flags
= ((port
->flags
& ~ASYNC_USR_MASK
) |
1962 (tmp
.flags
& ASYNC_USR_MASK
));
1963 port
->custom_divisor
= tmp
.custom_divisor
;
1965 port
->flags
= ((port
->flags
& ~ASYNC_FLAGS
) |
1966 (tmp
.flags
& ASYNC_FLAGS
));
1967 port
->close_delay
= tmp
.close_delay
;
1968 port
->closing_wait
= tmp
.closing_wait
;
1969 port
->custom_divisor
= tmp
.custom_divisor
;
1972 sx_change_speed(bp
, port
);
1979 static inline int sx_get_serial_info(struct specialix_port
* port
,
1980 struct serial_struct __user
*retinfo
)
1982 struct serial_struct tmp
;
1983 struct specialix_board
*bp
= port_Board(port
);
1988 if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
1992 memset(&tmp
, 0, sizeof(tmp
));
1993 tmp
.type
= PORT_CIRRUS
;
1994 tmp
.line
= port
- sx_port
;
1995 tmp
.port
= bp
->base
;
1997 tmp
.flags
= port
->flags
;
1998 tmp
.baud_base
= (SX_OSCFREQ
+ CD186x_TPC
/2) / CD186x_TPC
;
1999 tmp
.close_delay
= port
->close_delay
* HZ
/100;
2000 tmp
.closing_wait
= port
->closing_wait
* HZ
/100;
2001 tmp
.custom_divisor
= port
->custom_divisor
;
2002 tmp
.xmit_fifo_size
= CD186x_NFIFO
;
2003 if (copy_to_user(retinfo
, &tmp
, sizeof(tmp
))) {
2013 static int sx_ioctl(struct tty_struct
* tty
, struct file
* filp
,
2014 unsigned int cmd
, unsigned long arg
)
2016 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2018 void __user
*argp
= (void __user
*)arg
;
2022 if (sx_paranoia_check(port
, tty
->name
, "sx_ioctl")) {
2028 case TCSBRK
: /* SVID version: non-zero arg --> no break */
2029 retval
= tty_check_change(tty
);
2034 tty_wait_until_sent(tty
, 0);
2036 sx_send_break(port
, HZ
/4); /* 1/4 second */
2038 case TCSBRKP
: /* support for POSIX tcsendbreak() */
2039 retval
= tty_check_change(tty
);
2044 tty_wait_until_sent(tty
, 0);
2045 sx_send_break(port
, arg
? arg
*(HZ
/10) : HZ
/4);
2049 if (put_user(C_CLOCAL(tty
)?1:0, (unsigned long __user
*)argp
)) {
2056 if (get_user(arg
, (unsigned long __user
*) argp
)) {
2060 tty
->termios
->c_cflag
=
2061 ((tty
->termios
->c_cflag
& ~CLOCAL
) |
2062 (arg
? CLOCAL
: 0));
2067 return sx_get_serial_info(port
, argp
);
2070 return sx_set_serial_info(port
, argp
);
2073 return -ENOIOCTLCMD
;
2080 static void sx_throttle(struct tty_struct
* tty
)
2082 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2083 struct specialix_board
*bp
;
2084 unsigned long flags
;
2088 if (sx_paranoia_check(port
, tty
->name
, "sx_throttle")) {
2093 bp
= port_Board(port
);
2095 /* Use DTR instead of RTS ! */
2096 if (SX_CRTSCTS (tty
))
2097 port
->MSVR
&= ~MSVR_DTR
;
2099 /* Auch!!! I think the system shouldn't call this then. */
2100 /* Or maybe we're supposed (allowed?) to do our side of hw
2101 handshake anyway, even when hardware handshake is off.
2102 When you see this in your logs, please report.... */
2103 printk (KERN_ERR
"sx%d: Need to throttle, but can't (hardware hs is off)\n",
2106 spin_lock_irqsave(&bp
->lock
, flags
);
2107 sx_out(bp
, CD186x_CAR
, port_No(port
));
2108 spin_unlock_irqrestore(&bp
->lock
, flags
);
2111 spin_lock_irqsave(&bp
->lock
, flags
);
2112 sx_out(bp
, CD186x_CCR
, CCR_SSCH2
);
2113 spin_unlock_irqrestore(&bp
->lock
, flags
);
2116 spin_lock_irqsave(&bp
->lock
, flags
);
2117 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2118 spin_unlock_irqrestore(&bp
->lock
, flags
);
2124 static void sx_unthrottle(struct tty_struct
* tty
)
2126 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2127 struct specialix_board
*bp
;
2128 unsigned long flags
;
2132 if (sx_paranoia_check(port
, tty
->name
, "sx_unthrottle")) {
2137 bp
= port_Board(port
);
2139 spin_lock_irqsave(&port
->lock
, flags
);
2140 /* XXXX Use DTR INSTEAD???? */
2141 if (SX_CRTSCTS(tty
)) {
2142 port
->MSVR
|= MSVR_DTR
;
2143 } /* Else clause: see remark in "sx_throttle"... */
2144 spin_lock_irqsave(&bp
->lock
, flags
);
2145 sx_out(bp
, CD186x_CAR
, port_No(port
));
2146 spin_unlock_irqrestore(&bp
->lock
, flags
);
2148 spin_unlock_irqrestore(&port
->lock
, flags
);
2150 spin_lock_irqsave(&bp
->lock
, flags
);
2151 sx_out(bp
, CD186x_CCR
, CCR_SSCH1
);
2152 spin_unlock_irqrestore(&bp
->lock
, flags
);
2154 spin_lock_irqsave(&port
->lock
, flags
);
2156 spin_lock_irqsave(&bp
->lock
, flags
);
2157 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2158 spin_unlock_irqrestore(&bp
->lock
, flags
);
2159 spin_unlock_irqrestore(&port
->lock
, flags
);
2165 static void sx_stop(struct tty_struct
* tty
)
2167 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2168 struct specialix_board
*bp
;
2169 unsigned long flags
;
2173 if (sx_paranoia_check(port
, tty
->name
, "sx_stop")) {
2178 bp
= port_Board(port
);
2180 spin_lock_irqsave(&port
->lock
, flags
);
2181 port
->IER
&= ~IER_TXRDY
;
2182 spin_lock_irqsave(&bp
->lock
, flags
);
2183 sx_out(bp
, CD186x_CAR
, port_No(port
));
2184 sx_out(bp
, CD186x_IER
, port
->IER
);
2185 spin_unlock_irqrestore(&bp
->lock
, flags
);
2186 spin_unlock_irqrestore(&port
->lock
, flags
);
2192 static void sx_start(struct tty_struct
* tty
)
2194 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2195 struct specialix_board
*bp
;
2196 unsigned long flags
;
2200 if (sx_paranoia_check(port
, tty
->name
, "sx_start")) {
2205 bp
= port_Board(port
);
2207 spin_lock_irqsave(&port
->lock
, flags
);
2208 if (port
->xmit_cnt
&& port
->xmit_buf
&& !(port
->IER
& IER_TXRDY
)) {
2209 port
->IER
|= IER_TXRDY
;
2210 spin_lock_irqsave(&bp
->lock
, flags
);
2211 sx_out(bp
, CD186x_CAR
, port_No(port
));
2212 sx_out(bp
, CD186x_IER
, port
->IER
);
2213 spin_unlock_irqrestore(&bp
->lock
, flags
);
2215 spin_unlock_irqrestore(&port
->lock
, flags
);
2220 static void sx_hangup(struct tty_struct
* tty
)
2222 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2223 struct specialix_board
*bp
;
2224 unsigned long flags
;
2228 if (sx_paranoia_check(port
, tty
->name
, "sx_hangup")) {
2233 bp
= port_Board(port
);
2235 sx_shutdown_port(bp
, port
);
2236 spin_lock_irqsave(&port
->lock
, flags
);
2237 bp
->count
-= port
->count
;
2238 if (bp
->count
< 0) {
2239 printk(KERN_ERR
"sx%d: sx_hangup: bad board count: %d port: %d\n",
2240 board_No(bp
), bp
->count
, tty
->index
);
2244 port
->flags
&= ~ASYNC_NORMAL_ACTIVE
;
2246 spin_unlock_irqrestore(&port
->lock
, flags
);
2247 wake_up_interruptible(&port
->open_wait
);
2253 static void sx_set_termios(struct tty_struct
* tty
, struct ktermios
* old_termios
)
2255 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2256 unsigned long flags
;
2257 struct specialix_board
* bp
;
2259 if (sx_paranoia_check(port
, tty
->name
, "sx_set_termios"))
2262 if (tty
->termios
->c_cflag
== old_termios
->c_cflag
&&
2263 tty
->termios
->c_iflag
== old_termios
->c_iflag
)
2266 bp
= port_Board(port
);
2267 spin_lock_irqsave(&port
->lock
, flags
);
2268 sx_change_speed(port_Board(port
), port
);
2269 spin_unlock_irqrestore(&port
->lock
, flags
);
2271 if ((old_termios
->c_cflag
& CRTSCTS
) &&
2272 !(tty
->termios
->c_cflag
& CRTSCTS
)) {
2273 tty
->hw_stopped
= 0;
2278 static const struct tty_operations sx_ops
= {
2282 .put_char
= sx_put_char
,
2283 .flush_chars
= sx_flush_chars
,
2284 .write_room
= sx_write_room
,
2285 .chars_in_buffer
= sx_chars_in_buffer
,
2286 .flush_buffer
= sx_flush_buffer
,
2288 .throttle
= sx_throttle
,
2289 .unthrottle
= sx_unthrottle
,
2290 .set_termios
= sx_set_termios
,
2293 .hangup
= sx_hangup
,
2294 .tiocmget
= sx_tiocmget
,
2295 .tiocmset
= sx_tiocmset
,
2298 static int sx_init_drivers(void)
2305 specialix_driver
= alloc_tty_driver(SX_NBOARD
* SX_NPORT
);
2306 if (!specialix_driver
) {
2307 printk(KERN_ERR
"sx: Couldn't allocate tty_driver.\n");
2312 specialix_driver
->owner
= THIS_MODULE
;
2313 specialix_driver
->name
= "ttyW";
2314 specialix_driver
->major
= SPECIALIX_NORMAL_MAJOR
;
2315 specialix_driver
->type
= TTY_DRIVER_TYPE_SERIAL
;
2316 specialix_driver
->subtype
= SERIAL_TYPE_NORMAL
;
2317 specialix_driver
->init_termios
= tty_std_termios
;
2318 specialix_driver
->init_termios
.c_cflag
=
2319 B9600
| CS8
| CREAD
| HUPCL
| CLOCAL
;
2320 specialix_driver
->init_termios
.c_ispeed
= 9600;
2321 specialix_driver
->init_termios
.c_ospeed
= 9600;
2322 specialix_driver
->flags
= TTY_DRIVER_REAL_RAW
;
2323 tty_set_operations(specialix_driver
, &sx_ops
);
2325 if ((error
= tty_register_driver(specialix_driver
))) {
2326 put_tty_driver(specialix_driver
);
2327 printk(KERN_ERR
"sx: Couldn't register specialix IO8+ driver, error = %d\n",
2332 memset(sx_port
, 0, sizeof(sx_port
));
2333 for (i
= 0; i
< SX_NPORT
* SX_NBOARD
; i
++) {
2334 sx_port
[i
].magic
= SPECIALIX_MAGIC
;
2335 sx_port
[i
].close_delay
= 50 * HZ
/100;
2336 sx_port
[i
].closing_wait
= 3000 * HZ
/100;
2337 init_waitqueue_head(&sx_port
[i
].open_wait
);
2338 init_waitqueue_head(&sx_port
[i
].close_wait
);
2339 spin_lock_init(&sx_port
[i
].lock
);
2346 static void sx_release_drivers(void)
2350 tty_unregister_driver(specialix_driver
);
2351 put_tty_driver(specialix_driver
);
2356 * This routine must be called by kernel at boot time
2358 static int __init
specialix_init(void)
2365 printk(KERN_INFO
"sx: Specialix IO8+ driver v" VERSION
", (c) R.E.Wolff 1997/1998.\n");
2366 printk(KERN_INFO
"sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2367 #ifdef CONFIG_SPECIALIX_RTSCTS
2368 printk (KERN_INFO
"sx: DTR/RTS pin is always RTS.\n");
2370 printk (KERN_INFO
"sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2373 for (i
= 0; i
< SX_NBOARD
; i
++)
2374 spin_lock_init(&sx_board
[i
].lock
);
2376 if (sx_init_drivers()) {
2381 for (i
= 0; i
< SX_NBOARD
; i
++)
2382 if (sx_board
[i
].base
&& !sx_probe(&sx_board
[i
]))
2387 struct pci_dev
*pdev
= NULL
;
2390 while (i
< SX_NBOARD
) {
2391 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
) {
2395 pdev
= pci_get_device (PCI_VENDOR_ID_SPECIALIX
,
2396 PCI_DEVICE_ID_SPECIALIX_IO8
,
2400 if (pci_enable_device(pdev
))
2403 sx_board
[i
].irq
= pdev
->irq
;
2405 sx_board
[i
].base
= pci_resource_start (pdev
, 2);
2407 sx_board
[i
].flags
|= SX_BOARD_IS_PCI
;
2408 if (!sx_probe(&sx_board
[i
]))
2411 /* May exit pci_get sequence early with lots of boards */
2418 sx_release_drivers();
2419 printk(KERN_INFO
"sx: No specialix IO8+ boards detected.\n");
2428 static int iobase
[SX_NBOARD
] = {0,};
2430 static int irq
[SX_NBOARD
] = {0,};
2432 module_param_array(iobase
, int, NULL
, 0);
2433 module_param_array(irq
, int, NULL
, 0);
2434 module_param(sx_debug
, int, 0);
2435 module_param(sx_rxfifo
, int, 0);
2436 #ifdef SPECIALIX_TIMER
2437 module_param(sx_poll
, int, 0);
2441 * You can setup up to 4 boards.
2442 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2443 * You should specify the IRQs too in that case "irq=....,...".
2445 * More than 4 boards in one computer is not possible, as the card can
2446 * only use 4 different interrupts.
2449 static int __init
specialix_init_module(void)
2455 if (iobase
[0] || iobase
[1] || iobase
[2] || iobase
[3]) {
2456 for(i
= 0; i
< SX_NBOARD
; i
++) {
2457 sx_board
[i
].base
= iobase
[i
];
2458 sx_board
[i
].irq
= irq
[i
];
2459 sx_board
[i
].count
= 0;
2465 return specialix_init();
2468 static void __exit
specialix_exit_module(void)
2474 sx_release_drivers();
2475 for (i
= 0; i
< SX_NBOARD
; i
++)
2476 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
)
2477 sx_release_io_range(&sx_board
[i
]);
2478 #ifdef SPECIALIX_TIMER
2479 del_timer_sync(&missed_irq_timer
);
2485 static struct pci_device_id specialx_pci_tbl
[] __devinitdata
= {
2486 { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX
, PCI_DEVICE_ID_SPECIALIX_IO8
) },
2489 MODULE_DEVICE_TABLE(pci
, specialx_pci_tbl
);
2491 module_init(specialix_init_module
);
2492 module_exit(specialix_exit_module
);
2494 MODULE_LICENSE("GPL");