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. .
70 * There is a bunch of documentation about the card, jumpers, config
71 * settings, restrictions, cables, device names and numbers in
72 * ../../Documentation/specialix.txt
75 #include <linux/config.h>
76 #include <linux/module.h>
79 #include <linux/kernel.h>
80 #include <linux/sched.h>
81 #include <linux/ioport.h>
82 #include <linux/interrupt.h>
83 #include <linux/errno.h>
84 #include <linux/tty.h>
86 #include <linux/serial.h>
87 #include <linux/fcntl.h>
88 #include <linux/major.h>
89 #include <linux/delay.h>
90 #include <linux/tqueue.h>
91 #include <linux/version.h>
92 #include <linux/pci.h>
95 /* ************************************************************** */
96 /* * This section can be removed when 2.0 becomes outdated.... * */
97 /* ************************************************************** */
99 #if LINUX_VERSION_CODE < 131328 /* Less than 2.1.0 */
102 #if LINUX_VERSION_CODE < 131371 /* less than 2.1.43 */
103 /* This has not been extensively tested yet. Sorry. */
104 #warning "You're on your own between 2.1.0 and 2.1.43.... "
105 #warning "Please use a recent kernel."
111 #define Get_user(a,b) a = get_user(b)
112 #define copy_from_user(a,b,c) memcpy_fromfs(a,b,c)
113 #define copy_to_user(a,b,c) memcpy_tofs(a,b,c)
114 #define queue_task queue_task_irq_off
116 #define Get_user(a,b) get_user(a,b)
119 /* ************************************************************** */
120 /* * End of compatibility section.. * */
121 /* ************************************************************** */
125 #include <asm/uaccess.h>
128 #include "specialix_io8.h"
133 /* Configurable options: */
135 /* Am I paranoid or not ? ;-) */
136 #define SPECIALIX_PARANOIA_CHECK
138 /* Do I trust the IRQ from the card? (enabeling it doesn't seem to help)
139 When the IRQ routine leaves the chip in a state that is keeps on
140 requiring attention, the timer doesn't help either. */
141 #undef SPECIALIX_TIMER
144 * The following defines are mostly for testing purposes. But if you need
145 * some nice reporting in your syslog, you can define them also.
147 #undef SX_REPORT_FIFO
148 #undef SX_REPORT_OVERRUN
152 #ifdef CONFIG_SPECIALIX_RTSCTS
153 #define SX_CRTSCTS(bla) 1
155 #define SX_CRTSCTS(tty) C_CRTSCTS(tty)
159 /* Used to be outb (0xff, 0x80); */
160 #define short_pause() udelay (1)
163 #define SPECIALIX_LEGAL_FLAGS \
164 (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \
165 ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \
166 ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
169 #define MIN(a,b) ((a) < (b) ? (a) : (b))
172 DECLARE_TASK_QUEUE(tq_specialix
);
174 #undef RS_EVENT_WRITE_WAKEUP
175 #define RS_EVENT_WRITE_WAKEUP 0
177 #define SPECIALIX_TYPE_NORMAL 1
178 #define SPECIALIX_TYPE_CALLOUT 2
180 static struct tty_driver specialix_driver
, specialix_callout_driver
;
181 static int specialix_refcount
= 0;
182 static struct tty_struct
* specialix_table
[SX_NBOARD
* SX_NPORT
] = { NULL
, };
183 static struct termios
* specialix_termios
[SX_NBOARD
* SX_NPORT
] = { NULL
, };
184 static struct termios
* specialix_termios_locked
[SX_NBOARD
* SX_NPORT
] = { NULL
, };
185 static unsigned char * tmp_buf
= NULL
;
186 static DECLARE_MUTEX(tmp_buf_sem
);
188 static unsigned long baud_table
[] = {
189 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
190 9600, 19200, 38400, 57600, 115200, 0,
193 static struct specialix_board sx_board
[SX_NBOARD
] = {
194 { 0, SX_IOBASE1
, 9, },
195 { 0, SX_IOBASE2
, 11, },
196 { 0, SX_IOBASE3
, 12, },
197 { 0, SX_IOBASE4
, 15, },
200 static struct specialix_port sx_port
[SX_NBOARD
* SX_NPORT
] = {
205 #ifdef SPECIALIX_TIMER
206 static struct timer_list missed_irq_timer
;
207 static void sx_interrupt(int irq
, void * dev_id
, struct pt_regs
* regs
);
212 static inline int sx_paranoia_check(struct specialix_port
const * port
,
213 kdev_t device
, const char *routine
)
215 #ifdef SPECIALIX_PARANOIA_CHECK
216 static const char *badmagic
=
217 KERN_ERR
"sx: Warning: bad specialix port magic number for device %s in %s\n";
218 static const char *badinfo
=
219 KERN_ERR
"sx: Warning: null specialix port for device %s in %s\n";
222 printk(badinfo
, kdevname(device
), routine
);
225 if (port
->magic
!= SPECIALIX_MAGIC
) {
226 printk(badmagic
, kdevname(device
), routine
);
236 * Service functions for specialix IO8+ driver.
240 /* Get board number from pointer */
241 extern inline int board_No (struct specialix_board
* bp
)
243 return bp
- sx_board
;
247 /* Get port number from pointer */
248 extern inline int port_No (struct specialix_port
const * port
)
250 return SX_PORT(port
- sx_port
);
254 /* Get pointer to board from pointer to port */
255 extern inline struct specialix_board
* port_Board(struct specialix_port
const * port
)
257 return &sx_board
[SX_BOARD(port
- sx_port
)];
261 /* Input Byte from CL CD186x register */
262 extern inline unsigned char sx_in(struct specialix_board
* bp
, unsigned short reg
)
264 bp
->reg
= reg
| 0x80;
265 outb (reg
| 0x80, bp
->base
+ SX_ADDR_REG
);
266 return inb (bp
->base
+ SX_DATA_REG
);
270 /* Output Byte to CL CD186x register */
271 extern inline void sx_out(struct specialix_board
* bp
, unsigned short reg
,
274 bp
->reg
= reg
| 0x80;
275 outb (reg
| 0x80, bp
->base
+ SX_ADDR_REG
);
276 outb (val
, bp
->base
+ SX_DATA_REG
);
280 /* Input Byte from CL CD186x register */
281 extern inline unsigned char sx_in_off(struct specialix_board
* bp
, unsigned short reg
)
284 outb (reg
, bp
->base
+ SX_ADDR_REG
);
285 return inb (bp
->base
+ SX_DATA_REG
);
289 /* Output Byte to CL CD186x register */
290 extern inline void sx_out_off(struct specialix_board
* bp
, unsigned short reg
,
294 outb (reg
, bp
->base
+ SX_ADDR_REG
);
295 outb (val
, bp
->base
+ SX_DATA_REG
);
299 /* Wait for Channel Command Register ready */
300 extern inline void sx_wait_CCR(struct specialix_board
* bp
)
304 for (delay
= SX_CCR_TIMEOUT
; delay
; delay
--)
305 if (!sx_in(bp
, CD186x_CCR
))
308 printk(KERN_ERR
"sx%d: Timeout waiting for CCR.\n", board_No(bp
));
312 /* Wait for Channel Command Register ready */
313 extern inline void sx_wait_CCR_off(struct specialix_board
* bp
)
317 for (delay
= SX_CCR_TIMEOUT
; delay
; delay
--)
318 if (!sx_in_off(bp
, CD186x_CCR
))
321 printk(KERN_ERR
"sx%d: Timeout waiting for CCR.\n", board_No(bp
));
326 * specialix IO8+ IO range functions.
329 extern inline int sx_check_io_range(struct specialix_board
* bp
)
331 return check_region (bp
->base
, SX_IO_SPACE
);
335 extern inline void sx_request_io_range(struct specialix_board
* bp
)
337 request_region(bp
->base
,
338 bp
->flags
&SX_BOARD_IS_PCI
?SX_PCI_IO_SPACE
:SX_IO_SPACE
,
343 extern inline void sx_release_io_range(struct specialix_board
* bp
)
345 release_region(bp
->base
,
346 bp
->flags
&SX_BOARD_IS_PCI
?SX_PCI_IO_SPACE
:SX_IO_SPACE
);
350 /* Must be called with enabled interrupts */
351 /* Ugly. Very ugly. Don't use this for anything else than initialization
353 extern inline void sx_long_delay(unsigned long delay
)
357 for (i
= jiffies
+ delay
; time_after(i
, jiffies
); ) ;
362 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
363 int sx_set_irq ( struct specialix_board
*bp
)
368 if (bp
->flags
& SX_BOARD_IS_PCI
)
371 /* In the same order as in the docs... */
372 case 15: virq
= 0;break;
373 case 12: virq
= 1;break;
374 case 11: virq
= 2;break;
375 case 9: virq
= 3;break;
376 default: printk (KERN_ERR
"Speclialix: cannot set irq to %d.\n", bp
->irq
);
381 sx_out(bp
, CD186x_CAR
, i
);
382 sx_out(bp
, CD186x_MSVRTS
, ((virq
>> i
) & 0x1)? MSVR_RTS
:0);
388 /* Reset and setup CD186x chip */
389 static int sx_init_CD186x(struct specialix_board
* bp
)
395 save_flags(flags
); cli();
397 sx_wait_CCR_off(bp
); /* Wait for CCR ready */
398 sx_out_off(bp
, CD186x_CCR
, CCR_HARDRESET
); /* Reset CD186x chip */
400 sx_long_delay(HZ
/20); /* Delay 0.05 sec */
402 sx_out_off(bp
, CD186x_GIVR
, SX_ID
); /* Set ID for this chip */
403 sx_out_off(bp
, CD186x_GICR
, 0); /* Clear all bits */
404 sx_out_off(bp
, CD186x_PILR1
, SX_ACK_MINT
); /* Prio for modem intr */
405 sx_out_off(bp
, CD186x_PILR2
, SX_ACK_TINT
); /* Prio for transmitter intr */
406 sx_out_off(bp
, CD186x_PILR3
, SX_ACK_RINT
); /* Prio for receiver intr */
408 sx_out_off(bp
, CD186x_SRCR
, sx_in (bp
, CD186x_SRCR
) | SRCR_REGACKEN
);
410 /* Setting up prescaler. We need 4 ticks per 1 ms */
411 scaler
= SX_OSCFREQ
/SPECIALIX_TPS
;
413 sx_out_off(bp
, CD186x_PPRH
, scaler
>> 8);
414 sx_out_off(bp
, CD186x_PPRL
, scaler
& 0xff);
416 if (!sx_set_irq (bp
)) {
417 /* Figure out how to pass this along... */
418 printk (KERN_ERR
"Cannot set irq to %d.\n", bp
->irq
);
422 restore_flags(flags
);
427 int read_cross_byte (struct specialix_board
*bp
, int reg
, int bit
)
432 for (i
=0, t
=0;i
<8;i
++) {
433 sx_out_off (bp
, CD186x_CAR
, i
);
434 if (sx_in_off (bp
, reg
) & bit
)
441 #ifdef SPECIALIX_TIMER
442 void missed_irq (unsigned long data
)
444 if (sx_in ((struct specialix_board
*)data
, CD186x_SRSR
) &
448 printk (KERN_INFO
"Missed interrupt... Calling int from timer. \n");
449 sx_interrupt (((struct specialix_board
*)data
)->irq
,
452 missed_irq_timer
.expires
= jiffies
+ HZ
;
453 add_timer (&missed_irq_timer
);
459 /* Main probing routine, also sets irq. */
460 static int sx_probe(struct specialix_board
*bp
)
462 unsigned char val1
, val2
;
470 if (sx_check_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
);
489 /* Check the DSR lines that Specialix uses as board
491 val1
= read_cross_byte (bp
, CD186x_MSVR
, MSVR_DSR
);
492 val2
= read_cross_byte (bp
, CD186x_MSVR
, MSVR_RTS
);
493 #ifdef SPECIALIX_DEBUG
494 printk (KERN_DEBUG
"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
);
510 /* It's time to find IRQ for this board */
511 for (retries
= 0; retries
< 5 && irqs
<= 0; retries
++) {
512 irqs
= probe_irq_on();
513 sx_init_CD186x(bp
); /* Reset CD186x chip */
514 sx_out(bp
, CD186x_CAR
, 2); /* Select port 2 */
516 sx_out(bp
, CD186x_CCR
, CCR_TXEN
); /* Enable transmitter */
517 sx_out(bp
, CD186x_IER
, IER_TXRDY
); /* Enable tx empty intr */
518 sx_long_delay(HZ
/20);
519 irqs
= probe_irq_off(irqs
);
521 #if SPECIALIX_DEBUG > 2
522 printk (KERN_DEBUG
"SRSR = %02x, ", sx_in(bp
, CD186x_SRSR
));
523 printk ( "TRAR = %02x, ", sx_in(bp
, CD186x_TRAR
));
524 printk ( "GIVR = %02x, ", sx_in(bp
, CD186x_GIVR
));
525 printk ( "GICR = %02x, ", sx_in(bp
, CD186x_GICR
));
528 /* Reset CD186x again */
529 if (!sx_init_CD186x(bp
)) {
530 /* Hmmm. This is dead code anyway. */
532 #if SPECIALIX_DEBUG > 2
533 printk (KERN_DEBUG
"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
);
546 printk (KERN_INFO
"Started with irq=%d, but now have irq=%d.\n", bp
->irq
, irqs
);
550 /* Reset CD186x again */
551 if (!sx_init_CD186x(bp
)) {
555 sx_request_io_range(bp
);
556 bp
->flags
|= SX_BOARD_PRESENT
;
558 /* Chip revcode pkgtype
563 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
565 -- Thanks to Gwen Wang, Cirrus Logic.
568 switch (sx_in_off(bp
, CD186x_GFRCR
)) {
569 case 0x82:chip
= 1864;rev
='A';break;
570 case 0x83:chip
= 1865;rev
='A';break;
571 case 0x84:chip
= 1865;rev
='B';break;
572 case 0x85:chip
= 1865;rev
='C';break; /* Does not exist at this time */
573 default:chip
=-1;rev
='x';
576 #if SPECIALIX_DEBUG > 2
577 printk (KERN_DEBUG
" GFCR = 0x%02x\n", sx_in_off(bp
, CD186x_GFRCR
) );
580 #ifdef SPECIALIX_TIMER
581 init_timer (&missed_irq_timer
);
582 missed_irq_timer
.function
= missed_irq
;
583 missed_irq_timer
.data
= (unsigned long) bp
;
584 missed_irq_timer
.expires
= jiffies
+ HZ
;
585 add_timer (&missed_irq_timer
);
588 printk(KERN_INFO
"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
598 * Interrupt processing routines.
601 extern inline void sx_mark_event(struct specialix_port
* port
, int event
)
604 * I'm not quite happy with current scheme all serial
605 * drivers use their own BH routine.
606 * It seems this easily can be done with one BH routine
607 * serving for all serial drivers.
608 * For now I must introduce another one - SPECIALIX_BH.
609 * Still hope this will be changed in near future.
612 set_bit(event
, &port
->event
);
613 queue_task(&port
->tqueue
, &tq_specialix
);
614 mark_bh(SPECIALIX_BH
);
618 extern inline struct specialix_port
* sx_get_port(struct specialix_board
* bp
,
619 unsigned char const * what
)
621 unsigned char channel
;
622 struct specialix_port
* port
;
624 channel
= sx_in(bp
, CD186x_GICR
) >> GICR_CHAN_OFF
;
625 if (channel
< CD186x_NCH
) {
626 port
= &sx_port
[board_No(bp
) * SX_NPORT
+ channel
];
627 if (port
->flags
& ASYNC_INITIALIZED
) {
631 printk(KERN_INFO
"sx%d: %s interrupt from invalid port %d\n",
632 board_No(bp
), what
, channel
);
637 extern inline void sx_receive_exc(struct specialix_board
* bp
)
639 struct specialix_port
*port
;
640 struct tty_struct
*tty
;
641 unsigned char status
;
644 if (!(port
= sx_get_port(bp
, "Receive")))
648 if (tty
->flip
.count
>= TTY_FLIPBUF_SIZE
) {
649 printk(KERN_INFO
"sx%d: port %d: Working around flip buffer overflow.\n",
650 board_No(bp
), port_No(port
));
654 #ifdef SX_REPORT_OVERRUN
655 status
= sx_in(bp
, CD186x_RCSR
);
656 if (status
& RCSR_OE
) {
659 printk(KERN_DEBUG
"sx%d: port %d: Overrun. Total %ld overruns.\n",
660 board_No(bp
), port_No(port
), port
->overrun
);
663 status
&= port
->mark_mask
;
665 status
= sx_in(bp
, CD186x_RCSR
) & port
->mark_mask
;
667 ch
= sx_in(bp
, CD186x_RDR
);
671 if (status
& RCSR_TOUT
) {
672 printk(KERN_INFO
"sx%d: port %d: Receiver timeout. Hardware problems ?\n",
673 board_No(bp
), port_No(port
));
676 } else if (status
& RCSR_BREAK
) {
677 #ifdef SPECIALIX_DEBUG
678 printk(KERN_DEBUG
"sx%d: port %d: Handling break...\n",
679 board_No(bp
), port_No(port
));
681 *tty
->flip
.flag_buf_ptr
++ = TTY_BREAK
;
682 if (port
->flags
& ASYNC_SAK
)
685 } else if (status
& RCSR_PE
)
686 *tty
->flip
.flag_buf_ptr
++ = TTY_PARITY
;
688 else if (status
& RCSR_FE
)
689 *tty
->flip
.flag_buf_ptr
++ = TTY_FRAME
;
691 else if (status
& RCSR_OE
)
692 *tty
->flip
.flag_buf_ptr
++ = TTY_OVERRUN
;
695 *tty
->flip
.flag_buf_ptr
++ = 0;
697 *tty
->flip
.char_buf_ptr
++ = ch
;
699 queue_task(&tty
->flip
.tqueue
, &tq_timer
);
703 extern inline void sx_receive(struct specialix_board
* bp
)
705 struct specialix_port
*port
;
706 struct tty_struct
*tty
;
709 if (!(port
= sx_get_port(bp
, "Receive")))
714 count
= sx_in(bp
, CD186x_RDCR
);
716 #ifdef SX_REPORT_FIFO
717 port
->hits
[count
> 8 ? 9 : count
]++;
721 if (tty
->flip
.count
>= TTY_FLIPBUF_SIZE
) {
722 printk(KERN_INFO
"sx%d: port %d: Working around flip buffer overflow.\n",
723 board_No(bp
), port_No(port
));
726 *tty
->flip
.char_buf_ptr
++ = sx_in(bp
, CD186x_RDR
);
727 *tty
->flip
.flag_buf_ptr
++ = 0;
730 queue_task(&tty
->flip
.tqueue
, &tq_timer
);
734 extern inline void sx_transmit(struct specialix_board
* bp
)
736 struct specialix_port
*port
;
737 struct tty_struct
*tty
;
741 if (!(port
= sx_get_port(bp
, "Transmit")))
746 if (port
->IER
& IER_TXEMPTY
) {
748 sx_out(bp
, CD186x_CAR
, port_No(port
));
749 port
->IER
&= ~IER_TXEMPTY
;
750 sx_out(bp
, CD186x_IER
, port
->IER
);
754 if ((port
->xmit_cnt
<= 0 && !port
->break_length
)
755 || tty
->stopped
|| tty
->hw_stopped
) {
756 sx_out(bp
, CD186x_CAR
, port_No(port
));
757 port
->IER
&= ~IER_TXRDY
;
758 sx_out(bp
, CD186x_IER
, port
->IER
);
762 if (port
->break_length
) {
763 if (port
->break_length
> 0) {
764 if (port
->COR2
& COR2_ETC
) {
765 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
766 sx_out(bp
, CD186x_TDR
, CD186x_C_SBRK
);
767 port
->COR2
&= ~COR2_ETC
;
769 count
= MIN(port
->break_length
, 0xff);
770 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
771 sx_out(bp
, CD186x_TDR
, CD186x_C_DELAY
);
772 sx_out(bp
, CD186x_TDR
, count
);
773 if (!(port
->break_length
-= count
))
774 port
->break_length
--;
776 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
777 sx_out(bp
, CD186x_TDR
, CD186x_C_EBRK
);
778 sx_out(bp
, CD186x_COR2
, port
->COR2
);
780 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
781 port
->break_length
= 0;
786 count
= CD186x_NFIFO
;
788 sx_out(bp
, CD186x_TDR
, port
->xmit_buf
[port
->xmit_tail
++]);
789 port
->xmit_tail
= port
->xmit_tail
& (SERIAL_XMIT_SIZE
-1);
790 if (--port
->xmit_cnt
<= 0)
792 } while (--count
> 0);
794 if (port
->xmit_cnt
<= 0) {
795 sx_out(bp
, CD186x_CAR
, port_No(port
));
796 port
->IER
&= ~IER_TXRDY
;
797 sx_out(bp
, CD186x_IER
, port
->IER
);
799 if (port
->xmit_cnt
<= port
->wakeup_chars
)
800 sx_mark_event(port
, RS_EVENT_WRITE_WAKEUP
);
804 extern inline void sx_check_modem(struct specialix_board
* bp
)
806 struct specialix_port
*port
;
807 struct tty_struct
*tty
;
810 #ifdef SPECIALIX_DEBUG
811 printk (KERN_DEBUG
"Modem intr. ");
813 if (!(port
= sx_get_port(bp
, "Modem")))
818 mcr
= sx_in(bp
, CD186x_MCR
);
819 printk ("mcr = %02x.\n", mcr
);
821 if ((mcr
& MCR_CDCHG
)) {
822 #ifdef SPECIALIX_DEBUG
823 printk (KERN_DEBUG
"CD just changed... ");
825 if (sx_in(bp
, CD186x_MSVR
) & MSVR_CD
) {
826 #ifdef SPECIALIX_DEBUG
827 printk ( "Waking up guys in open.\n");
829 wake_up_interruptible(&port
->open_wait
);
831 else if (!((port
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
832 (port
->flags
& ASYNC_CALLOUT_NOHUP
))) {
833 #ifdef SPECIALIX_DEBUG
834 printk ( "Sending HUP.\n");
836 queue_task(&port
->tqueue_hangup
,
839 #ifdef SPECIALIX_DEBUG
840 printk ( "Don't need to send HUP.\n");
845 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
846 if (mcr
& MCR_CTSCHG
) {
847 if (sx_in(bp
, CD186x_MSVR
) & MSVR_CTS
) {
849 port
->IER
|= IER_TXRDY
;
850 if (port
->xmit_cnt
<= port
->wakeup_chars
)
851 sx_mark_event(port
, RS_EVENT_WRITE_WAKEUP
);
854 port
->IER
&= ~IER_TXRDY
;
856 sx_out(bp
, CD186x_IER
, port
->IER
);
858 if (mcr
& MCR_DSSXHG
) {
859 if (sx_in(bp
, CD186x_MSVR
) & MSVR_DSR
) {
861 port
->IER
|= IER_TXRDY
;
862 if (port
->xmit_cnt
<= port
->wakeup_chars
)
863 sx_mark_event(port
, RS_EVENT_WRITE_WAKEUP
);
866 port
->IER
&= ~IER_TXRDY
;
868 sx_out(bp
, CD186x_IER
, port
->IER
);
870 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
872 /* Clear change bits */
873 sx_out(bp
, CD186x_MCR
, 0);
877 /* The main interrupt processing routine */
878 static void sx_interrupt(int irq
, void * dev_id
, struct pt_regs
* regs
)
880 unsigned char status
;
882 struct specialix_board
*bp
;
883 unsigned long loop
= 0;
888 if (!bp
|| !(bp
->flags
& SX_BOARD_ACTIVE
)) {
889 #ifdef SPECIALIX_DEBUG
890 printk (KERN_DEBUG
"sx: False interrupt. irq %d.\n", irq
);
897 while ((++loop
< 16) && (status
= (sx_in(bp
, CD186x_SRSR
) &
901 if (status
& SRSR_RREQint
) {
902 ack
= sx_in(bp
, CD186x_RRAR
);
904 if (ack
== (SX_ID
| GIVR_IT_RCV
))
906 else if (ack
== (SX_ID
| GIVR_IT_REXC
))
909 printk(KERN_ERR
"sx%d: Bad receive ack 0x%02x.\n",
912 } else if (status
& SRSR_TREQint
) {
913 ack
= sx_in(bp
, CD186x_TRAR
);
915 if (ack
== (SX_ID
| GIVR_IT_TX
))
918 printk(KERN_ERR
"sx%d: Bad transmit ack 0x%02x.\n",
920 } else if (status
& SRSR_MREQint
) {
921 ack
= sx_in(bp
, CD186x_MRAR
);
923 if (ack
== (SX_ID
| GIVR_IT_MODEM
))
926 printk(KERN_ERR
"sx%d: Bad modem ack 0x%02x.\n",
931 sx_out(bp
, CD186x_EOIR
, 0); /* Mark end of interrupt */
934 outb (bp
->reg
, bp
->base
+ SX_ADDR_REG
);
939 * Routines for open & close processing.
942 void turn_ints_off (struct specialix_board
*bp
)
944 if (bp
->flags
& SX_BOARD_IS_PCI
) {
945 /* This was intended for enabeling the interrupt on the
946 * PCI card. However it seems that it's already enabled
947 * and as PCI interrupts can be shared, there is no real
948 * reason to have to turn it off. */
950 (void) sx_in_off (bp
, 0); /* Turn off interrupts. */
953 void turn_ints_on (struct specialix_board
*bp
)
955 if (bp
->flags
& SX_BOARD_IS_PCI
) {
956 /* play with the PCI chip. See comment above. */
958 (void) sx_in (bp
, 0); /* Turn ON interrupts. */
962 /* Called with disabled interrupts */
963 extern inline int sx_setup_board(struct specialix_board
* bp
)
967 if (bp
->flags
& SX_BOARD_ACTIVE
)
970 error
= request_irq(bp
->irq
, sx_interrupt
, SA_INTERRUPT
, "specialix IO8+", bp
);
976 bp
->flags
|= SX_BOARD_ACTIVE
;
983 /* Called with disabled interrupts */
984 extern inline void sx_shutdown_board(struct specialix_board
*bp
)
986 if (!(bp
->flags
& SX_BOARD_ACTIVE
))
989 bp
->flags
&= ~SX_BOARD_ACTIVE
;
991 #if SPECIALIX_DEBUG > 2
992 printk ("Freeing IRQ%d for board %d.\n", bp
->irq
, board_No (bp
));
994 free_irq(bp
->irq
, bp
);
1003 * Setting up port characteristics.
1004 * Must be called with disabled interrupts
1006 static void sx_change_speed(struct specialix_board
*bp
, struct specialix_port
*port
)
1008 struct tty_struct
*tty
;
1011 unsigned char cor1
= 0, cor3
= 0;
1012 unsigned char mcor1
= 0, mcor2
= 0;
1015 if (!(tty
= port
->tty
) || !tty
->termios
)
1020 /* Select port on the board */
1021 sx_out(bp
, CD186x_CAR
, port_No(port
));
1023 /* The Specialix board doens't implement the RTS lines.
1024 They are used to set the IRQ level. Don't touch them. */
1025 if (SX_CRTSCTS(tty
))
1026 port
->MSVR
= MSVR_DTR
| (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
1028 port
->MSVR
= (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
1029 #ifdef DEBUG_SPECIALIX
1030 printk (KERN_DEBUG
"sx: got MSVR=%02x.\n", port
->MSVR
);
1034 if (baud
& CBAUDEX
) {
1036 if (baud
< 1 || baud
> 2)
1037 port
->tty
->termios
->c_cflag
&= ~CBAUDEX
;
1042 if ((port
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_HI
)
1044 if ((port
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_VHI
)
1049 if (!baud_table
[baud
]) {
1050 /* Drop DTR & exit */
1051 #ifdef SPECIALIX_DEBUG
1052 printk (KERN_DEBUG
"Dropping DTR... Hmm....\n");
1054 if (!SX_CRTSCTS (tty
)) {
1055 port
-> MSVR
&= ~ MSVR_DTR
;
1056 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1058 #ifdef DEBUG_SPECIALIX
1060 printk (KERN_DEBUG
"Can't drop DTR: no DTR.\n");
1065 if (!SX_CRTSCTS (tty
)) {
1066 port
->MSVR
|= MSVR_DTR
;
1071 * Now we must calculate some speed depended things
1074 /* Set baud rate for port */
1075 tmp
= (((SX_OSCFREQ
+ baud_table
[baud
]/2) / baud_table
[baud
] +
1076 CD186x_TPC
/2) / CD186x_TPC
);
1077 if ((tmp
< 0x10) && time_before(again
, jiffies
)) {
1078 again
= jiffies
+ HZ
* 60;
1079 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1081 printk (KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1082 "Performance degradation is possible.\n"
1083 "Read specialix.txt for more info.\n",
1084 port_No (port
), tmp
);
1086 printk (KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1087 "Warning: overstressing Cirrus chip. "
1088 "This might not work.\n"
1089 "Read specialix.txt for more info.\n",
1090 port_No (port
), tmp
);
1094 sx_out(bp
, CD186x_RBPRH
, (tmp
>> 8) & 0xff);
1095 sx_out(bp
, CD186x_TBPRH
, (tmp
>> 8) & 0xff);
1096 sx_out(bp
, CD186x_RBPRL
, tmp
& 0xff);
1097 sx_out(bp
, CD186x_TBPRL
, tmp
& 0xff);
1099 baud
= (baud_table
[baud
] + 5) / 10; /* Estimated CPS */
1101 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1102 tmp
= ((baud
+ HZ
/2) / HZ
) * 2 - CD186x_NFIFO
;
1103 port
->wakeup_chars
= (tmp
< 0) ? 0 : ((tmp
>= SERIAL_XMIT_SIZE
) ?
1104 SERIAL_XMIT_SIZE
- 1 : tmp
);
1106 /* Receiver timeout will be transmission time for 1.5 chars */
1107 tmp
= (SPECIALIX_TPS
+ SPECIALIX_TPS
/2 + baud
/2) / baud
;
1108 tmp
= (tmp
> 0xff) ? 0xff : tmp
;
1109 sx_out(bp
, CD186x_RTPR
, tmp
);
1111 switch (C_CSIZE(tty
)) {
1129 cor1
|= COR1_IGNORE
;
1130 if (C_PARENB(tty
)) {
1131 cor1
|= COR1_NORMPAR
;
1135 cor1
&= ~COR1_IGNORE
;
1137 /* Set marking of some errors */
1138 port
->mark_mask
= RCSR_OE
| RCSR_TOUT
;
1140 port
->mark_mask
|= RCSR_FE
| RCSR_PE
;
1141 if (I_BRKINT(tty
) || I_PARMRK(tty
))
1142 port
->mark_mask
|= RCSR_BREAK
;
1144 port
->mark_mask
&= ~(RCSR_FE
| RCSR_PE
);
1145 if (I_IGNBRK(tty
)) {
1146 port
->mark_mask
&= ~RCSR_BREAK
;
1148 /* Real raw mode. Ignore all */
1149 port
->mark_mask
&= ~RCSR_OE
;
1151 /* Enable Hardware Flow Control */
1152 if (C_CRTSCTS(tty
)) {
1153 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1154 port
->IER
|= IER_DSR
| IER_CTS
;
1155 mcor1
|= MCOR1_DSRZD
| MCOR1_CTSZD
;
1156 mcor2
|= MCOR2_DSROD
| MCOR2_CTSOD
;
1157 tty
->hw_stopped
= !(sx_in(bp
, CD186x_MSVR
) & (MSVR_CTS
|MSVR_DSR
));
1159 port
->COR2
|= COR2_CTSAE
;
1162 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1163 /* Some people reported that it works, but I still doubt it */
1165 port
->COR2
|= COR2_TXIBE
;
1166 cor3
|= (COR3_FCT
| COR3_SCDE
);
1168 port
->COR2
|= COR2_IXM
;
1169 sx_out(bp
, CD186x_SCHR1
, START_CHAR(tty
));
1170 sx_out(bp
, CD186x_SCHR2
, STOP_CHAR(tty
));
1171 sx_out(bp
, CD186x_SCHR3
, START_CHAR(tty
));
1172 sx_out(bp
, CD186x_SCHR4
, STOP_CHAR(tty
));
1174 if (!C_CLOCAL(tty
)) {
1175 /* Enable CD check */
1176 port
->IER
|= IER_CD
;
1177 mcor1
|= MCOR1_CDZD
;
1178 mcor2
|= MCOR2_CDOD
;
1182 /* Enable receiver */
1183 port
->IER
|= IER_RXD
;
1185 /* Set input FIFO size (1-8 bytes) */
1186 cor3
|= SPECIALIX_RXFIFO
;
1187 /* Setting up CD186x channel registers */
1188 sx_out(bp
, CD186x_COR1
, cor1
);
1189 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1190 sx_out(bp
, CD186x_COR3
, cor3
);
1191 /* Make CD186x know about registers change */
1193 sx_out(bp
, CD186x_CCR
, CCR_CORCHG1
| CCR_CORCHG2
| CCR_CORCHG3
);
1194 /* Setting up modem option registers */
1195 #ifdef DEBUG_SPECIALIX
1196 printk ("Mcor1 = %02x, mcor2 = %02x.\n", mcor1
, mcor2
);
1198 sx_out(bp
, CD186x_MCOR1
, mcor1
);
1199 sx_out(bp
, CD186x_MCOR2
, mcor2
);
1200 /* Enable CD186x transmitter & receiver */
1202 sx_out(bp
, CD186x_CCR
, CCR_TXEN
| CCR_RXEN
);
1203 /* Enable interrupts */
1204 sx_out(bp
, CD186x_IER
, port
->IER
);
1205 /* And finally set the modem lines... */
1206 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1210 /* Must be called with interrupts enabled */
1211 static int sx_setup_port(struct specialix_board
*bp
, struct specialix_port
*port
)
1213 unsigned long flags
;
1215 if (port
->flags
& ASYNC_INITIALIZED
)
1218 if (!port
->xmit_buf
) {
1219 /* We may sleep in get_free_page() */
1222 if (!(tmp
= get_free_page(GFP_KERNEL
)))
1225 if (port
->xmit_buf
) {
1227 return -ERESTARTSYS
;
1229 port
->xmit_buf
= (unsigned char *) tmp
;
1232 save_flags(flags
); cli();
1235 clear_bit(TTY_IO_ERROR
, &port
->tty
->flags
);
1237 if (port
->count
== 1)
1240 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1241 sx_change_speed(bp
, port
);
1242 port
->flags
|= ASYNC_INITIALIZED
;
1244 restore_flags(flags
);
1249 /* Must be called with interrupts disabled */
1250 static void sx_shutdown_port(struct specialix_board
*bp
, struct specialix_port
*port
)
1252 struct tty_struct
*tty
;
1254 if (!(port
->flags
& ASYNC_INITIALIZED
))
1257 #ifdef SX_REPORT_OVERRUN
1258 printk(KERN_INFO
"sx%d: port %d: Total %ld overruns were detected.\n",
1259 board_No(bp
), port_No(port
), port
->overrun
);
1261 #ifdef SX_REPORT_FIFO
1265 printk(KERN_INFO
"sx%d: port %d: FIFO hits [ ",
1266 board_No(bp
), port_No(port
));
1267 for (i
= 0; i
< 10; i
++) {
1268 printk("%ld ", port
->hits
[i
]);
1273 if (port
->xmit_buf
) {
1274 free_page((unsigned long) port
->xmit_buf
);
1275 port
->xmit_buf
= NULL
;
1279 sx_out(bp
, CD186x_CAR
, port_No(port
));
1281 if (!(tty
= port
->tty
) || C_HUPCL(tty
)) {
1283 sx_out(bp
, CD186x_MSVDTR
, 0);
1288 sx_out(bp
, CD186x_CCR
, CCR_SOFTRESET
);
1289 /* Disable all interrupts from this port */
1291 sx_out(bp
, CD186x_IER
, port
->IER
);
1294 set_bit(TTY_IO_ERROR
, &tty
->flags
);
1295 port
->flags
&= ~ASYNC_INITIALIZED
;
1297 if (--bp
->count
< 0) {
1298 printk(KERN_ERR
"sx%d: sx_shutdown_port: bad board count: %d\n",
1299 board_No(bp
), bp
->count
);
1304 * If this is the last opened port on the board
1305 * shutdown whole board
1308 sx_shutdown_board(bp
);
1312 static int block_til_ready(struct tty_struct
*tty
, struct file
* filp
,
1313 struct specialix_port
*port
)
1315 DECLARE_WAITQUEUE(wait
, current
);
1316 struct specialix_board
*bp
= port_Board(port
);
1322 * If the device is in the middle of being closed, then block
1323 * until it's done, and then try again.
1325 if (tty_hung_up_p(filp
) || port
->flags
& ASYNC_CLOSING
) {
1326 interruptible_sleep_on(&port
->close_wait
);
1327 if (port
->flags
& ASYNC_HUP_NOTIFY
)
1330 return -ERESTARTSYS
;
1334 * If this is a callout device, then just make sure the normal
1335 * device isn't being used.
1337 if (tty
->driver
.subtype
== SPECIALIX_TYPE_CALLOUT
) {
1338 if (port
->flags
& ASYNC_NORMAL_ACTIVE
)
1340 if ((port
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
1341 (port
->flags
& ASYNC_SESSION_LOCKOUT
) &&
1342 (port
->session
!= current
->session
))
1344 if ((port
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
1345 (port
->flags
& ASYNC_PGRP_LOCKOUT
) &&
1346 (port
->pgrp
!= current
->pgrp
))
1348 port
->flags
|= ASYNC_CALLOUT_ACTIVE
;
1353 * If non-blocking mode is set, or the port is not enabled,
1354 * then make the check up front and then exit.
1356 if ((filp
->f_flags
& O_NONBLOCK
) ||
1357 (tty
->flags
& (1 << TTY_IO_ERROR
))) {
1358 if (port
->flags
& ASYNC_CALLOUT_ACTIVE
)
1360 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
1364 if (port
->flags
& ASYNC_CALLOUT_ACTIVE
) {
1365 if (port
->normal_termios
.c_cflag
& CLOCAL
)
1373 * Block waiting for the carrier detect and the line to become
1374 * free (i.e., not in use by the callout). While we are in
1375 * this loop, info->count is dropped by one, so that
1376 * rs_close() knows when to free things. We restore it upon
1377 * exit, either normal or abnormal.
1380 add_wait_queue(&port
->open_wait
, &wait
);
1382 if (!tty_hung_up_p(filp
))
1385 port
->blocked_open
++;
1388 sx_out(bp
, CD186x_CAR
, port_No(port
));
1389 CD
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
1390 if (!(port
->flags
& ASYNC_CALLOUT_ACTIVE
)) {
1391 if (SX_CRTSCTS (tty
)) {
1393 port
->MSVR
|= MSVR_DTR
;
1394 sx_out (bp
, CD186x_MSVR
, port
->MSVR
);
1397 port
->MSVR
|= MSVR_DTR
;
1398 sx_out (bp
, CD186x_MSVR
, port
->MSVR
);
1402 set_current_state(TASK_INTERRUPTIBLE
);
1403 if (tty_hung_up_p(filp
) ||
1404 !(port
->flags
& ASYNC_INITIALIZED
)) {
1405 if (port
->flags
& ASYNC_HUP_NOTIFY
)
1408 retval
= -ERESTARTSYS
;
1411 if (!(port
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
1412 !(port
->flags
& ASYNC_CLOSING
) &&
1415 if (signal_pending(current
)) {
1416 retval
= -ERESTARTSYS
;
1421 current
->state
= TASK_RUNNING
;
1422 remove_wait_queue(&port
->open_wait
, &wait
);
1423 if (!tty_hung_up_p(filp
))
1425 port
->blocked_open
--;
1429 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
1434 static int sx_open(struct tty_struct
* tty
, struct file
* filp
)
1438 struct specialix_port
* port
;
1439 struct specialix_board
* bp
;
1440 unsigned long flags
;
1442 board
= SX_BOARD(MINOR(tty
->device
));
1444 if (board
> SX_NBOARD
|| !(sx_board
[board
].flags
& SX_BOARD_PRESENT
))
1447 bp
= &sx_board
[board
];
1448 port
= sx_port
+ board
* SX_NPORT
+ SX_PORT(MINOR(tty
->device
));
1450 #ifdef DEBUG_SPECIALIX
1451 printk (KERN_DEBUG
"Board = %d, bp = %p, port = %p, portno = %d.\n",
1452 board
, bp
, port
, SX_PORT(MINOR(tty
->device
)));
1455 if (sx_paranoia_check(port
, tty
->device
, "sx_open"))
1458 if ((error
= sx_setup_board(bp
)))
1462 tty
->driver_data
= port
;
1465 if ((error
= sx_setup_port(bp
, port
)))
1468 if ((error
= block_til_ready(tty
, filp
, port
)))
1471 if ((port
->count
== 1) && (port
->flags
& ASYNC_SPLIT_TERMIOS
)) {
1472 if (tty
->driver
.subtype
== SPECIALIX_TYPE_NORMAL
)
1473 *tty
->termios
= port
->normal_termios
;
1475 *tty
->termios
= port
->callout_termios
;
1476 save_flags(flags
); cli();
1477 sx_change_speed(bp
, port
);
1478 restore_flags(flags
);
1481 port
->session
= current
->session
;
1482 port
->pgrp
= current
->pgrp
;
1487 static void sx_close(struct tty_struct
* tty
, struct file
* filp
)
1489 struct specialix_port
*port
= (struct specialix_port
*) tty
->driver_data
;
1490 struct specialix_board
*bp
;
1491 unsigned long flags
;
1492 unsigned long timeout
;
1494 if (!port
|| sx_paranoia_check(port
, tty
->device
, "close"))
1497 save_flags(flags
); cli();
1498 if (tty_hung_up_p(filp
)) {
1499 restore_flags(flags
);
1503 bp
= port_Board(port
);
1504 if ((tty
->count
== 1) && (port
->count
!= 1)) {
1505 printk(KERN_ERR
"sx%d: sx_close: bad port count;"
1506 " tty->count is 1, port count is %d\n",
1507 board_No(bp
), port
->count
);
1510 if (--port
->count
< 0) {
1511 printk(KERN_ERR
"sx%d: sx_close: bad port count for tty%d: %d\n",
1512 board_No(bp
), port_No(port
), port
->count
);
1516 restore_flags(flags
);
1519 port
->flags
|= ASYNC_CLOSING
;
1521 * Save the termios structure, since this port may have
1522 * separate termios for callout and dialin.
1524 if (port
->flags
& ASYNC_NORMAL_ACTIVE
)
1525 port
->normal_termios
= *tty
->termios
;
1526 if (port
->flags
& ASYNC_CALLOUT_ACTIVE
)
1527 port
->callout_termios
= *tty
->termios
;
1529 * Now we wait for the transmit buffer to clear; and we notify
1530 * the line discipline to only process XON/XOFF characters.
1533 if (port
->closing_wait
!= ASYNC_CLOSING_WAIT_NONE
)
1534 tty_wait_until_sent(tty
, port
->closing_wait
);
1536 * At this point we stop accepting input. To do this, we
1537 * disable the receive line status interrupts, and tell the
1538 * interrupt driver to stop checking the data ready bit in the
1539 * line status register.
1541 port
->IER
&= ~IER_RXD
;
1542 if (port
->flags
& ASYNC_INITIALIZED
) {
1543 port
->IER
&= ~IER_TXRDY
;
1544 port
->IER
|= IER_TXEMPTY
;
1545 sx_out(bp
, CD186x_CAR
, port_No(port
));
1546 sx_out(bp
, CD186x_IER
, port
->IER
);
1548 * Before we drop DTR, make sure the UART transmitter
1549 * has completely drained; this is especially
1550 * important if there is a transmit FIFO!
1552 timeout
= jiffies
+HZ
;
1553 while(port
->IER
& IER_TXEMPTY
) {
1554 current
->state
= TASK_INTERRUPTIBLE
;
1555 schedule_timeout(port
->timeout
);
1556 if (time_after(jiffies
, timeout
)) {
1557 printk (KERN_INFO
"Timeout waiting for close\n");
1563 sx_shutdown_port(bp
, port
);
1564 if (tty
->driver
.flush_buffer
)
1565 tty
->driver
.flush_buffer(tty
);
1566 if (tty
->ldisc
.flush_buffer
)
1567 tty
->ldisc
.flush_buffer(tty
);
1571 if (port
->blocked_open
) {
1572 if (port
->close_delay
) {
1573 current
->state
= TASK_INTERRUPTIBLE
;
1574 schedule_timeout(port
->close_delay
);
1576 wake_up_interruptible(&port
->open_wait
);
1578 port
->flags
&= ~(ASYNC_NORMAL_ACTIVE
|ASYNC_CALLOUT_ACTIVE
|
1580 wake_up_interruptible(&port
->close_wait
);
1581 restore_flags(flags
);
1585 static int sx_write(struct tty_struct
* tty
, int from_user
,
1586 const unsigned char *buf
, int count
)
1588 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1589 struct specialix_board
*bp
;
1591 unsigned long flags
;
1593 if (sx_paranoia_check(port
, tty
->device
, "sx_write"))
1596 bp
= port_Board(port
);
1598 if (!tty
|| !port
->xmit_buf
|| !tmp_buf
)
1607 c
= MIN(count
, MIN(SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1,
1608 SERIAL_XMIT_SIZE
- port
->xmit_head
));
1613 copy_from_user(tmp_buf
, buf
, c
);
1614 c
= MIN(c
, MIN(SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1,
1615 SERIAL_XMIT_SIZE
- port
->xmit_head
));
1616 memcpy(port
->xmit_buf
+ port
->xmit_head
, tmp_buf
, c
);
1618 memcpy(port
->xmit_buf
+ port
->xmit_head
, buf
, c
);
1619 port
->xmit_head
= (port
->xmit_head
+ c
) & (SERIAL_XMIT_SIZE
-1);
1620 port
->xmit_cnt
+= c
;
1621 restore_flags(flags
);
1628 if (port
->xmit_cnt
&& !tty
->stopped
&& !tty
->hw_stopped
&&
1629 !(port
->IER
& IER_TXRDY
)) {
1630 port
->IER
|= IER_TXRDY
;
1631 sx_out(bp
, CD186x_CAR
, port_No(port
));
1632 sx_out(bp
, CD186x_IER
, port
->IER
);
1634 restore_flags(flags
);
1639 static void sx_put_char(struct tty_struct
* tty
, unsigned char ch
)
1641 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1642 unsigned long flags
;
1644 if (sx_paranoia_check(port
, tty
->device
, "sx_put_char"))
1647 if (!tty
|| !port
->xmit_buf
)
1650 save_flags(flags
); cli();
1652 if (port
->xmit_cnt
>= SERIAL_XMIT_SIZE
- 1) {
1653 restore_flags(flags
);
1657 port
->xmit_buf
[port
->xmit_head
++] = ch
;
1658 port
->xmit_head
&= SERIAL_XMIT_SIZE
- 1;
1660 restore_flags(flags
);
1664 static void sx_flush_chars(struct tty_struct
* tty
)
1666 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1667 unsigned long flags
;
1669 if (sx_paranoia_check(port
, tty
->device
, "sx_flush_chars"))
1672 if (port
->xmit_cnt
<= 0 || tty
->stopped
|| tty
->hw_stopped
||
1676 save_flags(flags
); cli();
1677 port
->IER
|= IER_TXRDY
;
1678 sx_out(port_Board(port
), CD186x_CAR
, port_No(port
));
1679 sx_out(port_Board(port
), CD186x_IER
, port
->IER
);
1680 restore_flags(flags
);
1684 static int sx_write_room(struct tty_struct
* tty
)
1686 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1689 if (sx_paranoia_check(port
, tty
->device
, "sx_write_room"))
1692 ret
= SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1;
1699 static int sx_chars_in_buffer(struct tty_struct
*tty
)
1701 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1703 if (sx_paranoia_check(port
, tty
->device
, "sx_chars_in_buffer"))
1706 return port
->xmit_cnt
;
1710 static void sx_flush_buffer(struct tty_struct
*tty
)
1712 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1713 unsigned long flags
;
1715 if (sx_paranoia_check(port
, tty
->device
, "sx_flush_buffer"))
1718 save_flags(flags
); cli();
1719 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1720 restore_flags(flags
);
1722 wake_up_interruptible(&tty
->write_wait
);
1723 if ((tty
->flags
& (1 << TTY_DO_WRITE_WAKEUP
)) &&
1724 tty
->ldisc
.write_wakeup
)
1725 (tty
->ldisc
.write_wakeup
)(tty
);
1729 static int sx_get_modem_info(struct specialix_port
* port
, unsigned int *value
)
1731 struct specialix_board
* bp
;
1732 unsigned char status
;
1733 unsigned int result
;
1734 unsigned long flags
;
1736 bp
= port_Board(port
);
1737 save_flags(flags
); cli();
1738 sx_out(bp
, CD186x_CAR
, port_No(port
));
1739 status
= sx_in(bp
, CD186x_MSVR
);
1740 restore_flags(flags
);
1741 #ifdef DEBUG_SPECIALIX
1742 printk (KERN_DEBUG
"Got msvr[%d] = %02x, car = %d.\n",
1743 port_No(port
), status
, sx_in (bp
, CD186x_CAR
));
1744 printk (KERN_DEBUG
"sx_port = %p, port = %p\n", sx_port
, port
);
1746 if (SX_CRTSCTS(port
->tty
)) {
1747 result
= /* (status & MSVR_RTS) ? */ TIOCM_DTR
/* : 0) */
1748 | ((status
& MSVR_DTR
) ? TIOCM_RTS
: 0)
1749 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1750 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR
/* : 0) */
1751 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1753 result
= /* (status & MSVR_RTS) ? */ TIOCM_RTS
/* : 0) */
1754 | ((status
& MSVR_DTR
) ? TIOCM_DTR
: 0)
1755 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1756 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR
/* : 0) */
1757 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1759 put_user(result
,(unsigned int *) value
);
1764 static int sx_set_modem_info(struct specialix_port
* port
, unsigned int cmd
,
1765 unsigned int *value
)
1769 unsigned long flags
;
1770 struct specialix_board
*bp
= port_Board(port
);
1772 error
= verify_area(VERIFY_READ
, value
, sizeof(int));
1776 Get_user(arg
, (unsigned long *) value
);
1779 /* if (arg & TIOCM_RTS)
1780 port->MSVR |= MSVR_RTS; */
1781 /* if (arg & TIOCM_DTR)
1782 port->MSVR |= MSVR_DTR; */
1784 if (SX_CRTSCTS(port
->tty
)) {
1785 if (arg
& TIOCM_RTS
)
1786 port
->MSVR
|= MSVR_DTR
;
1788 if (arg
& TIOCM_DTR
)
1789 port
->MSVR
|= MSVR_DTR
;
1793 /* if (arg & TIOCM_RTS)
1794 port->MSVR &= ~MSVR_RTS; */
1795 /* if (arg & TIOCM_DTR)
1796 port->MSVR &= ~MSVR_DTR; */
1797 if (SX_CRTSCTS(port
->tty
)) {
1798 if (arg
& TIOCM_RTS
)
1799 port
->MSVR
&= ~MSVR_DTR
;
1801 if (arg
& TIOCM_DTR
)
1802 port
->MSVR
&= ~MSVR_DTR
;
1806 /* port->MSVR = (arg & TIOCM_RTS) ? (port->MSVR | MSVR_RTS) :
1807 (port->MSVR & ~MSVR_RTS); */
1808 /* port->MSVR = (arg & TIOCM_DTR) ? (port->MSVR | MSVR_DTR) :
1809 (port->MSVR & ~MSVR_DTR); */
1810 if (SX_CRTSCTS(port
->tty
)) {
1811 port
->MSVR
= (arg
& TIOCM_RTS
) ?
1812 (port
->MSVR
| MSVR_DTR
) :
1813 (port
->MSVR
& ~MSVR_DTR
);
1815 port
->MSVR
= (arg
& TIOCM_DTR
) ?
1816 (port
->MSVR
| MSVR_DTR
):
1817 (port
->MSVR
& ~MSVR_DTR
);
1823 save_flags(flags
); cli();
1824 sx_out(bp
, CD186x_CAR
, port_No(port
));
1825 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1826 restore_flags(flags
);
1831 extern inline void sx_send_break(struct specialix_port
* port
, unsigned long length
)
1833 struct specialix_board
*bp
= port_Board(port
);
1834 unsigned long flags
;
1836 save_flags(flags
); cli();
1837 port
->break_length
= SPECIALIX_TPS
/ HZ
* length
;
1838 port
->COR2
|= COR2_ETC
;
1839 port
->IER
|= IER_TXRDY
;
1840 sx_out(bp
, CD186x_CAR
, port_No(port
));
1841 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1842 sx_out(bp
, CD186x_IER
, port
->IER
);
1844 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
1846 restore_flags(flags
);
1850 extern inline int sx_set_serial_info(struct specialix_port
* port
,
1851 struct serial_struct
* newinfo
)
1853 struct serial_struct tmp
;
1854 struct specialix_board
*bp
= port_Board(port
);
1856 unsigned long flags
;
1859 error
= verify_area(VERIFY_READ
, (void *) newinfo
, sizeof(tmp
));
1863 copy_from_user(&tmp
, newinfo
, sizeof(tmp
));
1866 if ((tmp
.irq
!= bp
->irq
) ||
1867 (tmp
.port
!= bp
->base
) ||
1868 (tmp
.type
!= PORT_CIRRUS
) ||
1869 (tmp
.baud_base
!= (SX_OSCFREQ
+ CD186x_TPC
/2) / CD186x_TPC
) ||
1870 (tmp
.custom_divisor
!= 0) ||
1871 (tmp
.xmit_fifo_size
!= CD186x_NFIFO
) ||
1872 (tmp
.flags
& ~SPECIALIX_LEGAL_FLAGS
))
1876 change_speed
= ((port
->flags
& ASYNC_SPD_MASK
) !=
1877 (tmp
.flags
& ASYNC_SPD_MASK
));
1879 if (!capable(CAP_SYS_ADMIN
)) {
1880 if ((tmp
.close_delay
!= port
->close_delay
) ||
1881 (tmp
.closing_wait
!= port
->closing_wait
) ||
1882 ((tmp
.flags
& ~ASYNC_USR_MASK
) !=
1883 (port
->flags
& ~ASYNC_USR_MASK
)))
1885 port
->flags
= ((port
->flags
& ~ASYNC_USR_MASK
) |
1886 (tmp
.flags
& ASYNC_USR_MASK
));
1888 port
->flags
= ((port
->flags
& ~ASYNC_FLAGS
) |
1889 (tmp
.flags
& ASYNC_FLAGS
));
1890 port
->close_delay
= tmp
.close_delay
;
1891 port
->closing_wait
= tmp
.closing_wait
;
1894 save_flags(flags
); cli();
1895 sx_change_speed(bp
, port
);
1896 restore_flags(flags
);
1902 extern inline int sx_get_serial_info(struct specialix_port
* port
,
1903 struct serial_struct
* retinfo
)
1905 struct serial_struct tmp
;
1906 struct specialix_board
*bp
= port_Board(port
);
1909 error
= verify_area(VERIFY_WRITE
, (void *) retinfo
, sizeof(tmp
));
1913 memset(&tmp
, 0, sizeof(tmp
));
1914 tmp
.type
= PORT_CIRRUS
;
1915 tmp
.line
= port
- sx_port
;
1916 tmp
.port
= bp
->base
;
1918 tmp
.flags
= port
->flags
;
1919 tmp
.baud_base
= (SX_OSCFREQ
+ CD186x_TPC
/2) / CD186x_TPC
;
1920 tmp
.close_delay
= port
->close_delay
* HZ
/100;
1921 tmp
.closing_wait
= port
->closing_wait
* HZ
/100;
1922 tmp
.xmit_fifo_size
= CD186x_NFIFO
;
1923 copy_to_user(retinfo
, &tmp
, sizeof(tmp
));
1928 static int sx_ioctl(struct tty_struct
* tty
, struct file
* filp
,
1929 unsigned int cmd
, unsigned long arg
)
1931 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1935 if (sx_paranoia_check(port
, tty
->device
, "sx_ioctl"))
1939 case TCSBRK
: /* SVID version: non-zero arg --> no break */
1940 retval
= tty_check_change(tty
);
1943 tty_wait_until_sent(tty
, 0);
1945 sx_send_break(port
, HZ
/4); /* 1/4 second */
1947 case TCSBRKP
: /* support for POSIX tcsendbreak() */
1948 retval
= tty_check_change(tty
);
1951 tty_wait_until_sent(tty
, 0);
1952 sx_send_break(port
, arg
? arg
*(HZ
/10) : HZ
/4);
1955 error
= verify_area(VERIFY_WRITE
, (void *) arg
, sizeof(long));
1958 put_user(C_CLOCAL(tty
) ? 1 : 0,
1959 (unsigned long *) arg
);
1962 Get_user(arg
, (unsigned long *) arg
);
1963 tty
->termios
->c_cflag
=
1964 ((tty
->termios
->c_cflag
& ~CLOCAL
) |
1965 (arg
? CLOCAL
: 0));
1968 error
= verify_area(VERIFY_WRITE
, (void *) arg
,
1969 sizeof(unsigned int));
1972 return sx_get_modem_info(port
, (unsigned int *) arg
);
1976 return sx_set_modem_info(port
, cmd
, (unsigned int *) arg
);
1978 return sx_get_serial_info(port
, (struct serial_struct
*) arg
);
1980 return sx_set_serial_info(port
, (struct serial_struct
*) arg
);
1982 return -ENOIOCTLCMD
;
1988 static void sx_throttle(struct tty_struct
* tty
)
1990 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1991 struct specialix_board
*bp
;
1992 unsigned long flags
;
1994 if (sx_paranoia_check(port
, tty
->device
, "sx_throttle"))
1997 bp
= port_Board(port
);
1999 save_flags(flags
); cli();
2001 /* Use DTR instead of RTS ! */
2002 if (SX_CRTSCTS (tty
))
2003 port
->MSVR
&= ~MSVR_DTR
;
2005 /* Auch!!! I think the system shouldn't call this then. */
2006 /* Or maybe we're supposed (allowed?) to do our side of hw
2007 handshake anyway, even when hardware handshake is off.
2008 When you see this in your logs, please report.... */
2009 printk (KERN_ERR
"sx%d: Need to throttle, but can't (hardware hs is off)\n",
2012 sx_out(bp
, CD186x_CAR
, port_No(port
));
2015 sx_out(bp
, CD186x_CCR
, CCR_SSCH2
);
2018 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2019 restore_flags(flags
);
2023 static void sx_unthrottle(struct tty_struct
* tty
)
2025 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2026 struct specialix_board
*bp
;
2027 unsigned long flags
;
2029 if (sx_paranoia_check(port
, tty
->device
, "sx_unthrottle"))
2032 bp
= port_Board(port
);
2034 save_flags(flags
); cli();
2035 /* XXXX Use DTR INSTEAD???? */
2036 if (SX_CRTSCTS(tty
)) {
2037 port
->MSVR
|= MSVR_DTR
;
2038 } /* Else clause: see remark in "sx_throttle"... */
2040 sx_out(bp
, CD186x_CAR
, port_No(port
));
2043 sx_out(bp
, CD186x_CCR
, CCR_SSCH1
);
2046 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2047 restore_flags(flags
);
2051 static void sx_stop(struct tty_struct
* tty
)
2053 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2054 struct specialix_board
*bp
;
2055 unsigned long flags
;
2057 if (sx_paranoia_check(port
, tty
->device
, "sx_stop"))
2060 bp
= port_Board(port
);
2062 save_flags(flags
); cli();
2063 port
->IER
&= ~IER_TXRDY
;
2064 sx_out(bp
, CD186x_CAR
, port_No(port
));
2065 sx_out(bp
, CD186x_IER
, port
->IER
);
2066 restore_flags(flags
);
2070 static void sx_start(struct tty_struct
* tty
)
2072 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2073 struct specialix_board
*bp
;
2074 unsigned long flags
;
2076 if (sx_paranoia_check(port
, tty
->device
, "sx_start"))
2079 bp
= port_Board(port
);
2081 save_flags(flags
); cli();
2082 if (port
->xmit_cnt
&& port
->xmit_buf
&& !(port
->IER
& IER_TXRDY
)) {
2083 port
->IER
|= IER_TXRDY
;
2084 sx_out(bp
, CD186x_CAR
, port_No(port
));
2085 sx_out(bp
, CD186x_IER
, port
->IER
);
2087 restore_flags(flags
);
2092 * This routine is called from the scheduler tqueue when the interrupt
2093 * routine has signalled that a hangup has occurred. The path of
2094 * hangup processing is:
2096 * serial interrupt routine -> (scheduler tqueue) ->
2097 * do_sx_hangup() -> tty->hangup() -> sx_hangup()
2100 static void do_sx_hangup(void *private_
)
2102 struct specialix_port
*port
= (struct specialix_port
*) private_
;
2103 struct tty_struct
*tty
;
2113 static void sx_hangup(struct tty_struct
* tty
)
2115 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2116 struct specialix_board
*bp
;
2118 if (sx_paranoia_check(port
, tty
->device
, "sx_hangup"))
2121 bp
= port_Board(port
);
2123 sx_shutdown_port(bp
, port
);
2126 port
->flags
&= ~(ASYNC_NORMAL_ACTIVE
|ASYNC_CALLOUT_ACTIVE
);
2128 wake_up_interruptible(&port
->open_wait
);
2132 static void sx_set_termios(struct tty_struct
* tty
, struct termios
* old_termios
)
2134 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2135 unsigned long flags
;
2137 if (sx_paranoia_check(port
, tty
->device
, "sx_set_termios"))
2140 if (tty
->termios
->c_cflag
== old_termios
->c_cflag
&&
2141 tty
->termios
->c_iflag
== old_termios
->c_iflag
)
2144 save_flags(flags
); cli();
2145 sx_change_speed(port_Board(port
), port
);
2146 restore_flags(flags
);
2148 if ((old_termios
->c_cflag
& CRTSCTS
) &&
2149 !(tty
->termios
->c_cflag
& CRTSCTS
)) {
2150 tty
->hw_stopped
= 0;
2156 static void do_specialix_bh(void)
2158 run_task_queue(&tq_specialix
);
2162 static void do_softint(void *private_
)
2164 struct specialix_port
*port
= (struct specialix_port
*) private_
;
2165 struct tty_struct
*tty
;
2167 if(!(tty
= port
->tty
))
2170 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP
, &port
->event
)) {
2171 if ((tty
->flags
& (1 << TTY_DO_WRITE_WAKEUP
)) &&
2172 tty
->ldisc
.write_wakeup
)
2173 (tty
->ldisc
.write_wakeup
)(tty
);
2174 wake_up_interruptible(&tty
->write_wait
);
2179 static int sx_init_drivers(void)
2185 if (!(tmp_buf
= (unsigned char *) get_free_page(GFP_KERNEL
))) {
2186 printk(KERN_ERR
"sx: Couldn't get free page.\n");
2189 init_bh(SPECIALIX_BH
, do_specialix_bh
);
2190 memset(&specialix_driver
, 0, sizeof(specialix_driver
));
2191 specialix_driver
.magic
= TTY_DRIVER_MAGIC
;
2192 specialix_driver
.name
= "ttyW";
2193 specialix_driver
.major
= SPECIALIX_NORMAL_MAJOR
;
2194 specialix_driver
.num
= SX_NBOARD
* SX_NPORT
;
2195 specialix_driver
.type
= TTY_DRIVER_TYPE_SERIAL
;
2196 specialix_driver
.subtype
= SPECIALIX_TYPE_NORMAL
;
2197 specialix_driver
.init_termios
= tty_std_termios
;
2198 specialix_driver
.init_termios
.c_cflag
=
2199 B9600
| CS8
| CREAD
| HUPCL
| CLOCAL
;
2200 specialix_driver
.flags
= TTY_DRIVER_REAL_RAW
;
2201 specialix_driver
.refcount
= &specialix_refcount
;
2202 specialix_driver
.table
= specialix_table
;
2203 specialix_driver
.termios
= specialix_termios
;
2204 specialix_driver
.termios_locked
= specialix_termios_locked
;
2206 specialix_driver
.open
= sx_open
;
2207 specialix_driver
.close
= sx_close
;
2208 specialix_driver
.write
= sx_write
;
2209 specialix_driver
.put_char
= sx_put_char
;
2210 specialix_driver
.flush_chars
= sx_flush_chars
;
2211 specialix_driver
.write_room
= sx_write_room
;
2212 specialix_driver
.chars_in_buffer
= sx_chars_in_buffer
;
2213 specialix_driver
.flush_buffer
= sx_flush_buffer
;
2214 specialix_driver
.ioctl
= sx_ioctl
;
2215 specialix_driver
.throttle
= sx_throttle
;
2216 specialix_driver
.unthrottle
= sx_unthrottle
;
2217 specialix_driver
.set_termios
= sx_set_termios
;
2218 specialix_driver
.stop
= sx_stop
;
2219 specialix_driver
.start
= sx_start
;
2220 specialix_driver
.hangup
= sx_hangup
;
2222 specialix_callout_driver
= specialix_driver
;
2223 specialix_callout_driver
.name
= "cuw";
2224 specialix_callout_driver
.major
= SPECIALIX_CALLOUT_MAJOR
;
2225 specialix_callout_driver
.subtype
= SPECIALIX_TYPE_CALLOUT
;
2227 if ((error
= tty_register_driver(&specialix_driver
))) {
2228 free_page((unsigned long)tmp_buf
);
2229 printk(KERN_ERR
"sx: Couldn't register specialix IO8+ driver, error = %d\n",
2233 if ((error
= tty_register_driver(&specialix_callout_driver
))) {
2234 free_page((unsigned long)tmp_buf
);
2235 tty_unregister_driver(&specialix_driver
);
2236 printk(KERN_ERR
"sx: Couldn't register specialix IO8+ callout driver, error = %d\n",
2241 memset(sx_port
, 0, sizeof(sx_port
));
2242 for (i
= 0; i
< SX_NPORT
* SX_NBOARD
; i
++) {
2243 sx_port
[i
].callout_termios
= specialix_callout_driver
.init_termios
;
2244 sx_port
[i
].normal_termios
= specialix_driver
.init_termios
;
2245 sx_port
[i
].magic
= SPECIALIX_MAGIC
;
2246 sx_port
[i
].tqueue
.routine
= do_softint
;
2247 sx_port
[i
].tqueue
.data
= &sx_port
[i
];
2248 sx_port
[i
].tqueue_hangup
.routine
= do_sx_hangup
;
2249 sx_port
[i
].tqueue_hangup
.data
= &sx_port
[i
];
2250 sx_port
[i
].close_delay
= 50 * HZ
/100;
2251 sx_port
[i
].closing_wait
= 3000 * HZ
/100;
2252 init_waitqueue_head(&sx_port
[i
].open_wait
);
2253 init_waitqueue_head(&sx_port
[i
].close_wait
);
2260 static void sx_release_drivers(void)
2262 free_page((unsigned long)tmp_buf
);
2263 tty_unregister_driver(&specialix_driver
);
2264 tty_unregister_driver(&specialix_callout_driver
);
2270 * Called at boot time.
2272 * You can specify IO base for up to SX_NBOARD cards,
2273 * using line "specialix=0xiobase1,0xiobase2,.." at LILO prompt.
2274 * Note that there will be no probing at default
2275 * addresses in this case.
2278 void specialix_setup(char *str
, int * ints
)
2282 for (i
=0;i
<SX_NBOARD
;i
++) {
2283 sx_board
[i
].base
= 0;
2286 for (i
= 1; i
<= ints
[0]; i
++) {
2288 sx_board
[i
/2].base
= ints
[i
];
2290 sx_board
[i
/2 -1].irq
= ints
[i
];
2296 * This routine must be called by kernel at boot time
2298 int specialix_init(void)
2303 printk(KERN_INFO
"sx: Specialix IO8+ driver v" VERSION
", (c) R.E.Wolff 1997/1998.\n");
2304 printk(KERN_INFO
"sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2305 #ifdef CONFIG_SPECIALIX_RTSCTS
2306 printk (KERN_INFO
"sx: DTR/RTS pin is always RTS.\n");
2308 printk (KERN_INFO
"sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2311 if (sx_init_drivers())
2314 for (i
= 0; i
< SX_NBOARD
; i
++)
2315 if (sx_board
[i
].base
&& !sx_probe(&sx_board
[i
]))
2319 if (pci_present()) {
2320 struct pci_dev
*pdev
= NULL
;
2324 while (i
<= SX_NBOARD
) {
2325 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
) {
2329 pdev
= pci_find_device (PCI_VENDOR_ID_SPECIALIX
,
2330 PCI_DEVICE_ID_SPECIALIX_IO8
,
2334 sx_board
[i
].irq
= pdev
->irq
;
2336 pci_read_config_dword(pdev
, PCI_BASE_ADDRESS_2
, &tint
);
2337 /* Mask out the fact that it's IO-space */
2338 sx_board
[i
].base
= tint
& PCI_BASE_ADDRESS_IO_MASK
;
2340 sx_board
[i
].flags
|= SX_BOARD_IS_PCI
;
2341 if (!sx_probe(&sx_board
[i
]))
2348 sx_release_drivers();
2349 printk(KERN_INFO
"sx: No specialix IO8+ boards detected.\n");
2357 int iobase
[SX_NBOARD
] = {0,};
2359 int irq
[SX_NBOARD
] = {0,};
2361 MODULE_PARM(iobase
,"1-" __MODULE_STRING(SX_NBOARD
) "i");
2362 MODULE_PARM(irq
,"1-" __MODULE_STRING(SX_NBOARD
) "i");
2365 * You can setup up to 4 boards.
2366 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2367 * You should specify the IRQs too in that case "irq=....,...".
2369 * More than 4 boards in one computer is not possible, as the card can
2370 * only use 4 different interrupts.
2373 int init_module(void)
2377 if (iobase
[0] || iobase
[1] || iobase
[2] || iobase
[3]) {
2378 for(i
= 0; i
< SX_NBOARD
; i
++) {
2379 sx_board
[i
].base
= iobase
[i
];
2380 sx_board
[i
].irq
= irq
[i
];
2384 return specialix_init();
2388 void cleanup_module(void)
2392 sx_release_drivers();
2393 for (i
= 0; i
< SX_NBOARD
; i
++)
2394 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
)
2395 sx_release_io_range(&sx_board
[i
]);
2396 #ifdef SPECIALIX_TIMER
2397 del_timer (&missed_irq_timer
);