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
);
176 #define SPECIALIX_TYPE_NORMAL 1
177 #define SPECIALIX_TYPE_CALLOUT 2
179 static struct tty_driver specialix_driver
, specialix_callout_driver
;
180 static int specialix_refcount
= 0;
181 static struct tty_struct
* specialix_table
[SX_NBOARD
* SX_NPORT
] = { NULL
, };
182 static struct termios
* specialix_termios
[SX_NBOARD
* SX_NPORT
] = { NULL
, };
183 static struct termios
* specialix_termios_locked
[SX_NBOARD
* SX_NPORT
] = { NULL
, };
184 static unsigned char * tmp_buf
= NULL
;
185 static DECLARE_MUTEX(tmp_buf_sem
);
187 static unsigned long baud_table
[] = {
188 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
189 9600, 19200, 38400, 57600, 115200, 0,
192 static struct specialix_board sx_board
[SX_NBOARD
] = {
193 { 0, SX_IOBASE1
, 9, },
194 { 0, SX_IOBASE2
, 11, },
195 { 0, SX_IOBASE3
, 12, },
196 { 0, SX_IOBASE4
, 15, },
199 static struct specialix_port sx_port
[SX_NBOARD
* SX_NPORT
] = {
204 #ifdef SPECIALIX_TIMER
205 static struct timer_list missed_irq_timer
;
206 static void sx_interrupt(int irq
, void * dev_id
, struct pt_regs
* regs
);
211 static inline int sx_paranoia_check(struct specialix_port
const * port
,
212 kdev_t device
, const char *routine
)
214 #ifdef SPECIALIX_PARANOIA_CHECK
215 static const char *badmagic
=
216 KERN_ERR
"sx: Warning: bad specialix port magic number for device %s in %s\n";
217 static const char *badinfo
=
218 KERN_ERR
"sx: Warning: null specialix port for device %s in %s\n";
221 printk(badinfo
, kdevname(device
), routine
);
224 if (port
->magic
!= SPECIALIX_MAGIC
) {
225 printk(badmagic
, kdevname(device
), routine
);
235 * Service functions for specialix IO8+ driver.
239 /* Get board number from pointer */
240 extern inline int board_No (struct specialix_board
* bp
)
242 return bp
- sx_board
;
246 /* Get port number from pointer */
247 extern inline int port_No (struct specialix_port
const * port
)
249 return SX_PORT(port
- sx_port
);
253 /* Get pointer to board from pointer to port */
254 extern inline struct specialix_board
* port_Board(struct specialix_port
const * port
)
256 return &sx_board
[SX_BOARD(port
- sx_port
)];
260 /* Input Byte from CL CD186x register */
261 extern inline unsigned char sx_in(struct specialix_board
* bp
, unsigned short reg
)
263 bp
->reg
= reg
| 0x80;
264 outb (reg
| 0x80, bp
->base
+ SX_ADDR_REG
);
265 return inb (bp
->base
+ SX_DATA_REG
);
269 /* Output Byte to CL CD186x register */
270 extern inline void sx_out(struct specialix_board
* bp
, unsigned short reg
,
273 bp
->reg
= reg
| 0x80;
274 outb (reg
| 0x80, bp
->base
+ SX_ADDR_REG
);
275 outb (val
, bp
->base
+ SX_DATA_REG
);
279 /* Input Byte from CL CD186x register */
280 extern inline unsigned char sx_in_off(struct specialix_board
* bp
, unsigned short reg
)
283 outb (reg
, bp
->base
+ SX_ADDR_REG
);
284 return inb (bp
->base
+ SX_DATA_REG
);
288 /* Output Byte to CL CD186x register */
289 extern inline void sx_out_off(struct specialix_board
* bp
, unsigned short reg
,
293 outb (reg
, bp
->base
+ SX_ADDR_REG
);
294 outb (val
, bp
->base
+ SX_DATA_REG
);
298 /* Wait for Channel Command Register ready */
299 extern inline void sx_wait_CCR(struct specialix_board
* bp
)
303 for (delay
= SX_CCR_TIMEOUT
; delay
; delay
--)
304 if (!sx_in(bp
, CD186x_CCR
))
307 printk(KERN_ERR
"sx%d: Timeout waiting for CCR.\n", board_No(bp
));
311 /* Wait for Channel Command Register ready */
312 extern inline void sx_wait_CCR_off(struct specialix_board
* bp
)
316 for (delay
= SX_CCR_TIMEOUT
; delay
; delay
--)
317 if (!sx_in_off(bp
, CD186x_CCR
))
320 printk(KERN_ERR
"sx%d: Timeout waiting for CCR.\n", board_No(bp
));
325 * specialix IO8+ IO range functions.
328 extern inline int sx_check_io_range(struct specialix_board
* bp
)
330 return check_region (bp
->base
, SX_IO_SPACE
);
334 extern inline void sx_request_io_range(struct specialix_board
* bp
)
336 request_region(bp
->base
,
337 bp
->flags
&SX_BOARD_IS_PCI
?SX_PCI_IO_SPACE
:SX_IO_SPACE
,
342 extern inline void sx_release_io_range(struct specialix_board
* bp
)
344 release_region(bp
->base
,
345 bp
->flags
&SX_BOARD_IS_PCI
?SX_PCI_IO_SPACE
:SX_IO_SPACE
);
349 /* Must be called with enabled interrupts */
350 /* Ugly. Very ugly. Don't use this for anything else than initialization
352 extern inline void sx_long_delay(unsigned long delay
)
356 for (i
= jiffies
+ delay
; time_after(i
, jiffies
); ) ;
361 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
362 int sx_set_irq ( struct specialix_board
*bp
)
367 if (bp
->flags
& SX_BOARD_IS_PCI
)
370 /* In the same order as in the docs... */
371 case 15: virq
= 0;break;
372 case 12: virq
= 1;break;
373 case 11: virq
= 2;break;
374 case 9: virq
= 3;break;
375 default: printk (KERN_ERR
"Speclialix: cannot set irq to %d.\n", bp
->irq
);
380 sx_out(bp
, CD186x_CAR
, i
);
381 sx_out(bp
, CD186x_MSVRTS
, ((virq
>> i
) & 0x1)? MSVR_RTS
:0);
387 /* Reset and setup CD186x chip */
388 static int sx_init_CD186x(struct specialix_board
* bp
)
394 save_flags(flags
); cli();
396 sx_wait_CCR_off(bp
); /* Wait for CCR ready */
397 sx_out_off(bp
, CD186x_CCR
, CCR_HARDRESET
); /* Reset CD186x chip */
399 sx_long_delay(HZ
/20); /* Delay 0.05 sec */
401 sx_out_off(bp
, CD186x_GIVR
, SX_ID
); /* Set ID for this chip */
402 sx_out_off(bp
, CD186x_GICR
, 0); /* Clear all bits */
403 sx_out_off(bp
, CD186x_PILR1
, SX_ACK_MINT
); /* Prio for modem intr */
404 sx_out_off(bp
, CD186x_PILR2
, SX_ACK_TINT
); /* Prio for transmitter intr */
405 sx_out_off(bp
, CD186x_PILR3
, SX_ACK_RINT
); /* Prio for receiver intr */
407 sx_out_off(bp
, CD186x_SRCR
, sx_in (bp
, CD186x_SRCR
) | SRCR_REGACKEN
);
409 /* Setting up prescaler. We need 4 ticks per 1 ms */
410 scaler
= SX_OSCFREQ
/SPECIALIX_TPS
;
412 sx_out_off(bp
, CD186x_PPRH
, scaler
>> 8);
413 sx_out_off(bp
, CD186x_PPRL
, scaler
& 0xff);
415 if (!sx_set_irq (bp
)) {
416 /* Figure out how to pass this along... */
417 printk (KERN_ERR
"Cannot set irq to %d.\n", bp
->irq
);
421 restore_flags(flags
);
426 int read_cross_byte (struct specialix_board
*bp
, int reg
, int bit
)
431 for (i
=0, t
=0;i
<8;i
++) {
432 sx_out_off (bp
, CD186x_CAR
, i
);
433 if (sx_in_off (bp
, reg
) & bit
)
440 #ifdef SPECIALIX_TIMER
441 void missed_irq (unsigned long data
)
443 if (sx_in ((struct specialix_board
*)data
, CD186x_SRSR
) &
447 printk (KERN_INFO
"Missed interrupt... Calling int from timer. \n");
448 sx_interrupt (((struct specialix_board
*)data
)->irq
,
451 missed_irq_timer
.expires
= jiffies
+ HZ
;
452 add_timer (&missed_irq_timer
);
458 /* Main probing routine, also sets irq. */
459 static int sx_probe(struct specialix_board
*bp
)
461 unsigned char val1
, val2
;
469 if (sx_check_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
);
488 /* Check the DSR lines that Specialix uses as board
490 val1
= read_cross_byte (bp
, CD186x_MSVR
, MSVR_DSR
);
491 val2
= read_cross_byte (bp
, CD186x_MSVR
, MSVR_RTS
);
492 #ifdef SPECIALIX_DEBUG
493 printk (KERN_DEBUG
"sx%d: DSR lines are: %02x, rts lines are: %02x\n",
494 board_No(bp
), val1
, val2
);
496 /* They managed to switch the bit order between the docs and
497 the IO8+ card. The new PCI card now conforms to old docs.
498 They changed the PCI docs to reflect the situation on the
500 val2
= (bp
->flags
& SX_BOARD_IS_PCI
)?0x4d : 0xb2;
502 printk(KERN_INFO
"sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
503 board_No(bp
), val2
, bp
->base
, val1
);
509 /* It's time to find IRQ for this board */
510 for (retries
= 0; retries
< 5 && irqs
<= 0; retries
++) {
511 irqs
= probe_irq_on();
512 sx_init_CD186x(bp
); /* Reset CD186x chip */
513 sx_out(bp
, CD186x_CAR
, 2); /* Select port 2 */
515 sx_out(bp
, CD186x_CCR
, CCR_TXEN
); /* Enable transmitter */
516 sx_out(bp
, CD186x_IER
, IER_TXRDY
); /* Enable tx empty intr */
517 sx_long_delay(HZ
/20);
518 irqs
= probe_irq_off(irqs
);
520 #if SPECIALIX_DEBUG > 2
521 printk (KERN_DEBUG
"SRSR = %02x, ", sx_in(bp
, CD186x_SRSR
));
522 printk ( "TRAR = %02x, ", sx_in(bp
, CD186x_TRAR
));
523 printk ( "GIVR = %02x, ", sx_in(bp
, CD186x_GIVR
));
524 printk ( "GICR = %02x, ", sx_in(bp
, CD186x_GICR
));
527 /* Reset CD186x again */
528 if (!sx_init_CD186x(bp
)) {
529 /* Hmmm. This is dead code anyway. */
531 #if SPECIALIX_DEBUG > 2
532 printk (KERN_DEBUG
"val1 = %02x, val2 = %02x, val3 = %02x.\n",
540 printk(KERN_ERR
"sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
541 board_No(bp
), bp
->base
);
545 printk (KERN_INFO
"Started with irq=%d, but now have irq=%d.\n", bp
->irq
, irqs
);
549 /* Reset CD186x again */
550 if (!sx_init_CD186x(bp
)) {
554 sx_request_io_range(bp
);
555 bp
->flags
|= SX_BOARD_PRESENT
;
557 /* Chip revcode pkgtype
562 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
564 -- Thanks to Gwen Wang, Cirrus Logic.
567 switch (sx_in_off(bp
, CD186x_GFRCR
)) {
568 case 0x82:chip
= 1864;rev
='A';break;
569 case 0x83:chip
= 1865;rev
='A';break;
570 case 0x84:chip
= 1865;rev
='B';break;
571 case 0x85:chip
= 1865;rev
='C';break; /* Does not exist at this time */
572 default:chip
=-1;rev
='x';
575 #if SPECIALIX_DEBUG > 2
576 printk (KERN_DEBUG
" GFCR = 0x%02x\n", sx_in_off(bp
, CD186x_GFRCR
) );
579 #ifdef SPECIALIX_TIMER
580 init_timer (&missed_irq_timer
);
581 missed_irq_timer
.function
= missed_irq
;
582 missed_irq_timer
.data
= (unsigned long) bp
;
583 missed_irq_timer
.expires
= jiffies
+ HZ
;
584 add_timer (&missed_irq_timer
);
587 printk(KERN_INFO
"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
597 * Interrupt processing routines.
600 extern inline void sx_mark_event(struct specialix_port
* port
, int event
)
603 * I'm not quite happy with current scheme all serial
604 * drivers use their own BH routine.
605 * It seems this easily can be done with one BH routine
606 * serving for all serial drivers.
607 * For now I must introduce another one - SPECIALIX_BH.
608 * Still hope this will be changed in near future.
611 set_bit(event
, &port
->event
);
612 queue_task(&port
->tqueue
, &tq_specialix
);
613 mark_bh(SPECIALIX_BH
);
617 extern inline struct specialix_port
* sx_get_port(struct specialix_board
* bp
,
618 unsigned char const * what
)
620 unsigned char channel
;
621 struct specialix_port
* port
;
623 channel
= sx_in(bp
, CD186x_GICR
) >> GICR_CHAN_OFF
;
624 if (channel
< CD186x_NCH
) {
625 port
= &sx_port
[board_No(bp
) * SX_NPORT
+ channel
];
626 if (port
->flags
& ASYNC_INITIALIZED
) {
630 printk(KERN_INFO
"sx%d: %s interrupt from invalid port %d\n",
631 board_No(bp
), what
, channel
);
636 extern inline void sx_receive_exc(struct specialix_board
* bp
)
638 struct specialix_port
*port
;
639 struct tty_struct
*tty
;
640 unsigned char status
;
643 if (!(port
= sx_get_port(bp
, "Receive")))
647 if (tty
->flip
.count
>= TTY_FLIPBUF_SIZE
) {
648 printk(KERN_INFO
"sx%d: port %d: Working around flip buffer overflow.\n",
649 board_No(bp
), port_No(port
));
653 #ifdef SX_REPORT_OVERRUN
654 status
= sx_in(bp
, CD186x_RCSR
);
655 if (status
& RCSR_OE
) {
658 printk(KERN_DEBUG
"sx%d: port %d: Overrun. Total %ld overruns.\n",
659 board_No(bp
), port_No(port
), port
->overrun
);
662 status
&= port
->mark_mask
;
664 status
= sx_in(bp
, CD186x_RCSR
) & port
->mark_mask
;
666 ch
= sx_in(bp
, CD186x_RDR
);
670 if (status
& RCSR_TOUT
) {
671 printk(KERN_INFO
"sx%d: port %d: Receiver timeout. Hardware problems ?\n",
672 board_No(bp
), port_No(port
));
675 } else if (status
& RCSR_BREAK
) {
676 #ifdef SPECIALIX_DEBUG
677 printk(KERN_DEBUG
"sx%d: port %d: Handling break...\n",
678 board_No(bp
), port_No(port
));
680 *tty
->flip
.flag_buf_ptr
++ = TTY_BREAK
;
681 if (port
->flags
& ASYNC_SAK
)
684 } else if (status
& RCSR_PE
)
685 *tty
->flip
.flag_buf_ptr
++ = TTY_PARITY
;
687 else if (status
& RCSR_FE
)
688 *tty
->flip
.flag_buf_ptr
++ = TTY_FRAME
;
690 else if (status
& RCSR_OE
)
691 *tty
->flip
.flag_buf_ptr
++ = TTY_OVERRUN
;
694 *tty
->flip
.flag_buf_ptr
++ = 0;
696 *tty
->flip
.char_buf_ptr
++ = ch
;
698 queue_task(&tty
->flip
.tqueue
, &tq_timer
);
702 extern inline void sx_receive(struct specialix_board
* bp
)
704 struct specialix_port
*port
;
705 struct tty_struct
*tty
;
708 if (!(port
= sx_get_port(bp
, "Receive")))
713 count
= sx_in(bp
, CD186x_RDCR
);
715 #ifdef SX_REPORT_FIFO
716 port
->hits
[count
> 8 ? 9 : count
]++;
720 if (tty
->flip
.count
>= TTY_FLIPBUF_SIZE
) {
721 printk(KERN_INFO
"sx%d: port %d: Working around flip buffer overflow.\n",
722 board_No(bp
), port_No(port
));
725 *tty
->flip
.char_buf_ptr
++ = sx_in(bp
, CD186x_RDR
);
726 *tty
->flip
.flag_buf_ptr
++ = 0;
729 queue_task(&tty
->flip
.tqueue
, &tq_timer
);
733 extern inline void sx_transmit(struct specialix_board
* bp
)
735 struct specialix_port
*port
;
736 struct tty_struct
*tty
;
740 if (!(port
= sx_get_port(bp
, "Transmit")))
745 if (port
->IER
& IER_TXEMPTY
) {
747 sx_out(bp
, CD186x_CAR
, port_No(port
));
748 port
->IER
&= ~IER_TXEMPTY
;
749 sx_out(bp
, CD186x_IER
, port
->IER
);
753 if ((port
->xmit_cnt
<= 0 && !port
->break_length
)
754 || tty
->stopped
|| tty
->hw_stopped
) {
755 sx_out(bp
, CD186x_CAR
, port_No(port
));
756 port
->IER
&= ~IER_TXRDY
;
757 sx_out(bp
, CD186x_IER
, port
->IER
);
761 if (port
->break_length
) {
762 if (port
->break_length
> 0) {
763 if (port
->COR2
& COR2_ETC
) {
764 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
765 sx_out(bp
, CD186x_TDR
, CD186x_C_SBRK
);
766 port
->COR2
&= ~COR2_ETC
;
768 count
= MIN(port
->break_length
, 0xff);
769 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
770 sx_out(bp
, CD186x_TDR
, CD186x_C_DELAY
);
771 sx_out(bp
, CD186x_TDR
, count
);
772 if (!(port
->break_length
-= count
))
773 port
->break_length
--;
775 sx_out(bp
, CD186x_TDR
, CD186x_C_ESC
);
776 sx_out(bp
, CD186x_TDR
, CD186x_C_EBRK
);
777 sx_out(bp
, CD186x_COR2
, port
->COR2
);
779 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
780 port
->break_length
= 0;
785 count
= CD186x_NFIFO
;
787 sx_out(bp
, CD186x_TDR
, port
->xmit_buf
[port
->xmit_tail
++]);
788 port
->xmit_tail
= port
->xmit_tail
& (SERIAL_XMIT_SIZE
-1);
789 if (--port
->xmit_cnt
<= 0)
791 } while (--count
> 0);
793 if (port
->xmit_cnt
<= 0) {
794 sx_out(bp
, CD186x_CAR
, port_No(port
));
795 port
->IER
&= ~IER_TXRDY
;
796 sx_out(bp
, CD186x_IER
, port
->IER
);
798 if (port
->xmit_cnt
<= port
->wakeup_chars
)
799 sx_mark_event(port
, RS_EVENT_WRITE_WAKEUP
);
803 extern inline void sx_check_modem(struct specialix_board
* bp
)
805 struct specialix_port
*port
;
806 struct tty_struct
*tty
;
809 #ifdef SPECIALIX_DEBUG
810 printk (KERN_DEBUG
"Modem intr. ");
812 if (!(port
= sx_get_port(bp
, "Modem")))
817 mcr
= sx_in(bp
, CD186x_MCR
);
818 printk ("mcr = %02x.\n", mcr
);
820 if ((mcr
& MCR_CDCHG
)) {
821 #ifdef SPECIALIX_DEBUG
822 printk (KERN_DEBUG
"CD just changed... ");
824 if (sx_in(bp
, CD186x_MSVR
) & MSVR_CD
) {
825 #ifdef SPECIALIX_DEBUG
826 printk ( "Waking up guys in open.\n");
828 wake_up_interruptible(&port
->open_wait
);
830 else if (!((port
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
831 (port
->flags
& ASYNC_CALLOUT_NOHUP
))) {
832 #ifdef SPECIALIX_DEBUG
833 printk ( "Sending HUP.\n");
835 queue_task(&port
->tqueue_hangup
,
838 #ifdef SPECIALIX_DEBUG
839 printk ( "Don't need to send HUP.\n");
844 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
845 if (mcr
& MCR_CTSCHG
) {
846 if (sx_in(bp
, CD186x_MSVR
) & MSVR_CTS
) {
848 port
->IER
|= IER_TXRDY
;
849 if (port
->xmit_cnt
<= port
->wakeup_chars
)
850 sx_mark_event(port
, RS_EVENT_WRITE_WAKEUP
);
853 port
->IER
&= ~IER_TXRDY
;
855 sx_out(bp
, CD186x_IER
, port
->IER
);
857 if (mcr
& MCR_DSSXHG
) {
858 if (sx_in(bp
, CD186x_MSVR
) & MSVR_DSR
) {
860 port
->IER
|= IER_TXRDY
;
861 if (port
->xmit_cnt
<= port
->wakeup_chars
)
862 sx_mark_event(port
, RS_EVENT_WRITE_WAKEUP
);
865 port
->IER
&= ~IER_TXRDY
;
867 sx_out(bp
, CD186x_IER
, port
->IER
);
869 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
871 /* Clear change bits */
872 sx_out(bp
, CD186x_MCR
, 0);
876 /* The main interrupt processing routine */
877 static void sx_interrupt(int irq
, void * dev_id
, struct pt_regs
* regs
)
879 unsigned char status
;
881 struct specialix_board
*bp
;
882 unsigned long loop
= 0;
887 if (!bp
|| !(bp
->flags
& SX_BOARD_ACTIVE
)) {
888 #ifdef SPECIALIX_DEBUG
889 printk (KERN_DEBUG
"sx: False interrupt. irq %d.\n", irq
);
896 while ((++loop
< 16) && (status
= (sx_in(bp
, CD186x_SRSR
) &
900 if (status
& SRSR_RREQint
) {
901 ack
= sx_in(bp
, CD186x_RRAR
);
903 if (ack
== (SX_ID
| GIVR_IT_RCV
))
905 else if (ack
== (SX_ID
| GIVR_IT_REXC
))
908 printk(KERN_ERR
"sx%d: Bad receive ack 0x%02x.\n",
911 } else if (status
& SRSR_TREQint
) {
912 ack
= sx_in(bp
, CD186x_TRAR
);
914 if (ack
== (SX_ID
| GIVR_IT_TX
))
917 printk(KERN_ERR
"sx%d: Bad transmit ack 0x%02x.\n",
919 } else if (status
& SRSR_MREQint
) {
920 ack
= sx_in(bp
, CD186x_MRAR
);
922 if (ack
== (SX_ID
| GIVR_IT_MODEM
))
925 printk(KERN_ERR
"sx%d: Bad modem ack 0x%02x.\n",
930 sx_out(bp
, CD186x_EOIR
, 0); /* Mark end of interrupt */
933 outb (bp
->reg
, bp
->base
+ SX_ADDR_REG
);
938 * Routines for open & close processing.
941 void turn_ints_off (struct specialix_board
*bp
)
943 if (bp
->flags
& SX_BOARD_IS_PCI
) {
944 /* This was intended for enabeling the interrupt on the
945 * PCI card. However it seems that it's already enabled
946 * and as PCI interrupts can be shared, there is no real
947 * reason to have to turn it off. */
949 (void) sx_in_off (bp
, 0); /* Turn off interrupts. */
952 void turn_ints_on (struct specialix_board
*bp
)
954 if (bp
->flags
& SX_BOARD_IS_PCI
) {
955 /* play with the PCI chip. See comment above. */
957 (void) sx_in (bp
, 0); /* Turn ON interrupts. */
961 /* Called with disabled interrupts */
962 extern inline int sx_setup_board(struct specialix_board
* bp
)
966 if (bp
->flags
& SX_BOARD_ACTIVE
)
969 error
= request_irq(bp
->irq
, sx_interrupt
, SA_INTERRUPT
, "specialix IO8+", bp
);
975 bp
->flags
|= SX_BOARD_ACTIVE
;
982 /* Called with disabled interrupts */
983 extern inline void sx_shutdown_board(struct specialix_board
*bp
)
985 if (!(bp
->flags
& SX_BOARD_ACTIVE
))
988 bp
->flags
&= ~SX_BOARD_ACTIVE
;
990 #if SPECIALIX_DEBUG > 2
991 printk ("Freeing IRQ%d for board %d.\n", bp
->irq
, board_No (bp
));
993 free_irq(bp
->irq
, bp
);
1002 * Setting up port characteristics.
1003 * Must be called with disabled interrupts
1005 static void sx_change_speed(struct specialix_board
*bp
, struct specialix_port
*port
)
1007 struct tty_struct
*tty
;
1010 unsigned char cor1
= 0, cor3
= 0;
1011 unsigned char mcor1
= 0, mcor2
= 0;
1014 if (!(tty
= port
->tty
) || !tty
->termios
)
1019 /* Select port on the board */
1020 sx_out(bp
, CD186x_CAR
, port_No(port
));
1022 /* The Specialix board doens't implement the RTS lines.
1023 They are used to set the IRQ level. Don't touch them. */
1024 if (SX_CRTSCTS(tty
))
1025 port
->MSVR
= MSVR_DTR
| (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
1027 port
->MSVR
= (sx_in(bp
, CD186x_MSVR
) & MSVR_RTS
);
1028 #ifdef DEBUG_SPECIALIX
1029 printk (KERN_DEBUG
"sx: got MSVR=%02x.\n", port
->MSVR
);
1033 if (baud
& CBAUDEX
) {
1035 if (baud
< 1 || baud
> 2)
1036 port
->tty
->termios
->c_cflag
&= ~CBAUDEX
;
1041 if ((port
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_HI
)
1043 if ((port
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_VHI
)
1048 if (!baud_table
[baud
]) {
1049 /* Drop DTR & exit */
1050 #ifdef SPECIALIX_DEBUG
1051 printk (KERN_DEBUG
"Dropping DTR... Hmm....\n");
1053 if (!SX_CRTSCTS (tty
)) {
1054 port
-> MSVR
&= ~ MSVR_DTR
;
1055 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1057 #ifdef DEBUG_SPECIALIX
1059 printk (KERN_DEBUG
"Can't drop DTR: no DTR.\n");
1064 if (!SX_CRTSCTS (tty
)) {
1065 port
->MSVR
|= MSVR_DTR
;
1070 * Now we must calculate some speed depended things
1073 /* Set baud rate for port */
1074 tmp
= (((SX_OSCFREQ
+ baud_table
[baud
]/2) / baud_table
[baud
] +
1075 CD186x_TPC
/2) / CD186x_TPC
);
1076 if ((tmp
< 0x10) && time_before(again
, jiffies
)) {
1077 again
= jiffies
+ HZ
* 60;
1078 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1080 printk (KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1081 "Performance degradation is possible.\n"
1082 "Read specialix.txt for more info.\n",
1083 port_No (port
), tmp
);
1085 printk (KERN_INFO
"sx%d: Baud rate divisor is %ld. \n"
1086 "Warning: overstressing Cirrus chip. "
1087 "This might not work.\n"
1088 "Read specialix.txt for more info.\n",
1089 port_No (port
), tmp
);
1093 sx_out(bp
, CD186x_RBPRH
, (tmp
>> 8) & 0xff);
1094 sx_out(bp
, CD186x_TBPRH
, (tmp
>> 8) & 0xff);
1095 sx_out(bp
, CD186x_RBPRL
, tmp
& 0xff);
1096 sx_out(bp
, CD186x_TBPRL
, tmp
& 0xff);
1098 baud
= (baud_table
[baud
] + 5) / 10; /* Estimated CPS */
1100 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1101 tmp
= ((baud
+ HZ
/2) / HZ
) * 2 - CD186x_NFIFO
;
1102 port
->wakeup_chars
= (tmp
< 0) ? 0 : ((tmp
>= SERIAL_XMIT_SIZE
) ?
1103 SERIAL_XMIT_SIZE
- 1 : tmp
);
1105 /* Receiver timeout will be transmission time for 1.5 chars */
1106 tmp
= (SPECIALIX_TPS
+ SPECIALIX_TPS
/2 + baud
/2) / baud
;
1107 tmp
= (tmp
> 0xff) ? 0xff : tmp
;
1108 sx_out(bp
, CD186x_RTPR
, tmp
);
1110 switch (C_CSIZE(tty
)) {
1128 cor1
|= COR1_IGNORE
;
1129 if (C_PARENB(tty
)) {
1130 cor1
|= COR1_NORMPAR
;
1134 cor1
&= ~COR1_IGNORE
;
1136 /* Set marking of some errors */
1137 port
->mark_mask
= RCSR_OE
| RCSR_TOUT
;
1139 port
->mark_mask
|= RCSR_FE
| RCSR_PE
;
1140 if (I_BRKINT(tty
) || I_PARMRK(tty
))
1141 port
->mark_mask
|= RCSR_BREAK
;
1143 port
->mark_mask
&= ~(RCSR_FE
| RCSR_PE
);
1144 if (I_IGNBRK(tty
)) {
1145 port
->mark_mask
&= ~RCSR_BREAK
;
1147 /* Real raw mode. Ignore all */
1148 port
->mark_mask
&= ~RCSR_OE
;
1150 /* Enable Hardware Flow Control */
1151 if (C_CRTSCTS(tty
)) {
1152 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1153 port
->IER
|= IER_DSR
| IER_CTS
;
1154 mcor1
|= MCOR1_DSRZD
| MCOR1_CTSZD
;
1155 mcor2
|= MCOR2_DSROD
| MCOR2_CTSOD
;
1156 tty
->hw_stopped
= !(sx_in(bp
, CD186x_MSVR
) & (MSVR_CTS
|MSVR_DSR
));
1158 port
->COR2
|= COR2_CTSAE
;
1161 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1162 /* Some people reported that it works, but I still doubt it */
1164 port
->COR2
|= COR2_TXIBE
;
1165 cor3
|= (COR3_FCT
| COR3_SCDE
);
1167 port
->COR2
|= COR2_IXM
;
1168 sx_out(bp
, CD186x_SCHR1
, START_CHAR(tty
));
1169 sx_out(bp
, CD186x_SCHR2
, STOP_CHAR(tty
));
1170 sx_out(bp
, CD186x_SCHR3
, START_CHAR(tty
));
1171 sx_out(bp
, CD186x_SCHR4
, STOP_CHAR(tty
));
1173 if (!C_CLOCAL(tty
)) {
1174 /* Enable CD check */
1175 port
->IER
|= IER_CD
;
1176 mcor1
|= MCOR1_CDZD
;
1177 mcor2
|= MCOR2_CDOD
;
1181 /* Enable receiver */
1182 port
->IER
|= IER_RXD
;
1184 /* Set input FIFO size (1-8 bytes) */
1185 cor3
|= SPECIALIX_RXFIFO
;
1186 /* Setting up CD186x channel registers */
1187 sx_out(bp
, CD186x_COR1
, cor1
);
1188 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1189 sx_out(bp
, CD186x_COR3
, cor3
);
1190 /* Make CD186x know about registers change */
1192 sx_out(bp
, CD186x_CCR
, CCR_CORCHG1
| CCR_CORCHG2
| CCR_CORCHG3
);
1193 /* Setting up modem option registers */
1194 #ifdef DEBUG_SPECIALIX
1195 printk ("Mcor1 = %02x, mcor2 = %02x.\n", mcor1
, mcor2
);
1197 sx_out(bp
, CD186x_MCOR1
, mcor1
);
1198 sx_out(bp
, CD186x_MCOR2
, mcor2
);
1199 /* Enable CD186x transmitter & receiver */
1201 sx_out(bp
, CD186x_CCR
, CCR_TXEN
| CCR_RXEN
);
1202 /* Enable interrupts */
1203 sx_out(bp
, CD186x_IER
, port
->IER
);
1204 /* And finally set the modem lines... */
1205 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1209 /* Must be called with interrupts enabled */
1210 static int sx_setup_port(struct specialix_board
*bp
, struct specialix_port
*port
)
1212 unsigned long flags
;
1214 if (port
->flags
& ASYNC_INITIALIZED
)
1217 if (!port
->xmit_buf
) {
1218 /* We may sleep in get_free_page() */
1221 if (!(tmp
= get_free_page(GFP_KERNEL
)))
1224 if (port
->xmit_buf
) {
1226 return -ERESTARTSYS
;
1228 port
->xmit_buf
= (unsigned char *) tmp
;
1231 save_flags(flags
); cli();
1234 clear_bit(TTY_IO_ERROR
, &port
->tty
->flags
);
1236 if (port
->count
== 1)
1239 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1240 sx_change_speed(bp
, port
);
1241 port
->flags
|= ASYNC_INITIALIZED
;
1243 restore_flags(flags
);
1248 /* Must be called with interrupts disabled */
1249 static void sx_shutdown_port(struct specialix_board
*bp
, struct specialix_port
*port
)
1251 struct tty_struct
*tty
;
1253 if (!(port
->flags
& ASYNC_INITIALIZED
))
1256 #ifdef SX_REPORT_OVERRUN
1257 printk(KERN_INFO
"sx%d: port %d: Total %ld overruns were detected.\n",
1258 board_No(bp
), port_No(port
), port
->overrun
);
1260 #ifdef SX_REPORT_FIFO
1264 printk(KERN_INFO
"sx%d: port %d: FIFO hits [ ",
1265 board_No(bp
), port_No(port
));
1266 for (i
= 0; i
< 10; i
++) {
1267 printk("%ld ", port
->hits
[i
]);
1272 if (port
->xmit_buf
) {
1273 free_page((unsigned long) port
->xmit_buf
);
1274 port
->xmit_buf
= NULL
;
1278 sx_out(bp
, CD186x_CAR
, port_No(port
));
1280 if (!(tty
= port
->tty
) || C_HUPCL(tty
)) {
1282 sx_out(bp
, CD186x_MSVDTR
, 0);
1287 sx_out(bp
, CD186x_CCR
, CCR_SOFTRESET
);
1288 /* Disable all interrupts from this port */
1290 sx_out(bp
, CD186x_IER
, port
->IER
);
1293 set_bit(TTY_IO_ERROR
, &tty
->flags
);
1294 port
->flags
&= ~ASYNC_INITIALIZED
;
1296 if (--bp
->count
< 0) {
1297 printk(KERN_ERR
"sx%d: sx_shutdown_port: bad board count: %d\n",
1298 board_No(bp
), bp
->count
);
1303 * If this is the last opened port on the board
1304 * shutdown whole board
1307 sx_shutdown_board(bp
);
1311 static int block_til_ready(struct tty_struct
*tty
, struct file
* filp
,
1312 struct specialix_port
*port
)
1314 DECLARE_WAITQUEUE(wait
, current
);
1315 struct specialix_board
*bp
= port_Board(port
);
1321 * If the device is in the middle of being closed, then block
1322 * until it's done, and then try again.
1324 if (tty_hung_up_p(filp
) || port
->flags
& ASYNC_CLOSING
) {
1325 interruptible_sleep_on(&port
->close_wait
);
1326 if (port
->flags
& ASYNC_HUP_NOTIFY
)
1329 return -ERESTARTSYS
;
1333 * If this is a callout device, then just make sure the normal
1334 * device isn't being used.
1336 if (tty
->driver
.subtype
== SPECIALIX_TYPE_CALLOUT
) {
1337 if (port
->flags
& ASYNC_NORMAL_ACTIVE
)
1339 if ((port
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
1340 (port
->flags
& ASYNC_SESSION_LOCKOUT
) &&
1341 (port
->session
!= current
->session
))
1343 if ((port
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
1344 (port
->flags
& ASYNC_PGRP_LOCKOUT
) &&
1345 (port
->pgrp
!= current
->pgrp
))
1347 port
->flags
|= ASYNC_CALLOUT_ACTIVE
;
1352 * If non-blocking mode is set, or the port is not enabled,
1353 * then make the check up front and then exit.
1355 if ((filp
->f_flags
& O_NONBLOCK
) ||
1356 (tty
->flags
& (1 << TTY_IO_ERROR
))) {
1357 if (port
->flags
& ASYNC_CALLOUT_ACTIVE
)
1359 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
1363 if (port
->flags
& ASYNC_CALLOUT_ACTIVE
) {
1364 if (port
->normal_termios
.c_cflag
& CLOCAL
)
1372 * Block waiting for the carrier detect and the line to become
1373 * free (i.e., not in use by the callout). While we are in
1374 * this loop, info->count is dropped by one, so that
1375 * rs_close() knows when to free things. We restore it upon
1376 * exit, either normal or abnormal.
1379 add_wait_queue(&port
->open_wait
, &wait
);
1381 if (!tty_hung_up_p(filp
))
1384 port
->blocked_open
++;
1387 sx_out(bp
, CD186x_CAR
, port_No(port
));
1388 CD
= sx_in(bp
, CD186x_MSVR
) & MSVR_CD
;
1389 if (!(port
->flags
& ASYNC_CALLOUT_ACTIVE
)) {
1390 if (SX_CRTSCTS (tty
)) {
1392 port
->MSVR
|= MSVR_DTR
;
1393 sx_out (bp
, CD186x_MSVR
, port
->MSVR
);
1396 port
->MSVR
|= MSVR_DTR
;
1397 sx_out (bp
, CD186x_MSVR
, port
->MSVR
);
1401 set_current_state(TASK_INTERRUPTIBLE
);
1402 if (tty_hung_up_p(filp
) ||
1403 !(port
->flags
& ASYNC_INITIALIZED
)) {
1404 if (port
->flags
& ASYNC_HUP_NOTIFY
)
1407 retval
= -ERESTARTSYS
;
1410 if (!(port
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
1411 !(port
->flags
& ASYNC_CLOSING
) &&
1414 if (signal_pending(current
)) {
1415 retval
= -ERESTARTSYS
;
1420 current
->state
= TASK_RUNNING
;
1421 remove_wait_queue(&port
->open_wait
, &wait
);
1422 if (!tty_hung_up_p(filp
))
1424 port
->blocked_open
--;
1428 port
->flags
|= ASYNC_NORMAL_ACTIVE
;
1433 static int sx_open(struct tty_struct
* tty
, struct file
* filp
)
1437 struct specialix_port
* port
;
1438 struct specialix_board
* bp
;
1439 unsigned long flags
;
1441 board
= SX_BOARD(MINOR(tty
->device
));
1443 if (board
> SX_NBOARD
|| !(sx_board
[board
].flags
& SX_BOARD_PRESENT
))
1446 bp
= &sx_board
[board
];
1447 port
= sx_port
+ board
* SX_NPORT
+ SX_PORT(MINOR(tty
->device
));
1449 #ifdef DEBUG_SPECIALIX
1450 printk (KERN_DEBUG
"Board = %d, bp = %p, port = %p, portno = %d.\n",
1451 board
, bp
, port
, SX_PORT(MINOR(tty
->device
)));
1454 if (sx_paranoia_check(port
, tty
->device
, "sx_open"))
1457 if ((error
= sx_setup_board(bp
)))
1461 tty
->driver_data
= port
;
1464 if ((error
= sx_setup_port(bp
, port
)))
1467 if ((error
= block_til_ready(tty
, filp
, port
)))
1470 if ((port
->count
== 1) && (port
->flags
& ASYNC_SPLIT_TERMIOS
)) {
1471 if (tty
->driver
.subtype
== SPECIALIX_TYPE_NORMAL
)
1472 *tty
->termios
= port
->normal_termios
;
1474 *tty
->termios
= port
->callout_termios
;
1475 save_flags(flags
); cli();
1476 sx_change_speed(bp
, port
);
1477 restore_flags(flags
);
1480 port
->session
= current
->session
;
1481 port
->pgrp
= current
->pgrp
;
1486 static void sx_close(struct tty_struct
* tty
, struct file
* filp
)
1488 struct specialix_port
*port
= (struct specialix_port
*) tty
->driver_data
;
1489 struct specialix_board
*bp
;
1490 unsigned long flags
;
1491 unsigned long timeout
;
1493 if (!port
|| sx_paranoia_check(port
, tty
->device
, "close"))
1496 save_flags(flags
); cli();
1497 if (tty_hung_up_p(filp
)) {
1498 restore_flags(flags
);
1502 bp
= port_Board(port
);
1503 if ((tty
->count
== 1) && (port
->count
!= 1)) {
1504 printk(KERN_ERR
"sx%d: sx_close: bad port count;"
1505 " tty->count is 1, port count is %d\n",
1506 board_No(bp
), port
->count
);
1509 if (--port
->count
< 0) {
1510 printk(KERN_ERR
"sx%d: sx_close: bad port count for tty%d: %d\n",
1511 board_No(bp
), port_No(port
), port
->count
);
1515 restore_flags(flags
);
1518 port
->flags
|= ASYNC_CLOSING
;
1520 * Save the termios structure, since this port may have
1521 * separate termios for callout and dialin.
1523 if (port
->flags
& ASYNC_NORMAL_ACTIVE
)
1524 port
->normal_termios
= *tty
->termios
;
1525 if (port
->flags
& ASYNC_CALLOUT_ACTIVE
)
1526 port
->callout_termios
= *tty
->termios
;
1528 * Now we wait for the transmit buffer to clear; and we notify
1529 * the line discipline to only process XON/XOFF characters.
1532 if (port
->closing_wait
!= ASYNC_CLOSING_WAIT_NONE
)
1533 tty_wait_until_sent(tty
, port
->closing_wait
);
1535 * At this point we stop accepting input. To do this, we
1536 * disable the receive line status interrupts, and tell the
1537 * interrupt driver to stop checking the data ready bit in the
1538 * line status register.
1540 port
->IER
&= ~IER_RXD
;
1541 if (port
->flags
& ASYNC_INITIALIZED
) {
1542 port
->IER
&= ~IER_TXRDY
;
1543 port
->IER
|= IER_TXEMPTY
;
1544 sx_out(bp
, CD186x_CAR
, port_No(port
));
1545 sx_out(bp
, CD186x_IER
, port
->IER
);
1547 * Before we drop DTR, make sure the UART transmitter
1548 * has completely drained; this is especially
1549 * important if there is a transmit FIFO!
1551 timeout
= jiffies
+HZ
;
1552 while(port
->IER
& IER_TXEMPTY
) {
1553 current
->state
= TASK_INTERRUPTIBLE
;
1554 schedule_timeout(port
->timeout
);
1555 if (time_after(jiffies
, timeout
)) {
1556 printk (KERN_INFO
"Timeout waiting for close\n");
1562 sx_shutdown_port(bp
, port
);
1563 if (tty
->driver
.flush_buffer
)
1564 tty
->driver
.flush_buffer(tty
);
1565 if (tty
->ldisc
.flush_buffer
)
1566 tty
->ldisc
.flush_buffer(tty
);
1570 if (port
->blocked_open
) {
1571 if (port
->close_delay
) {
1572 current
->state
= TASK_INTERRUPTIBLE
;
1573 schedule_timeout(port
->close_delay
);
1575 wake_up_interruptible(&port
->open_wait
);
1577 port
->flags
&= ~(ASYNC_NORMAL_ACTIVE
|ASYNC_CALLOUT_ACTIVE
|
1579 wake_up_interruptible(&port
->close_wait
);
1580 restore_flags(flags
);
1584 static int sx_write(struct tty_struct
* tty
, int from_user
,
1585 const unsigned char *buf
, int count
)
1587 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1588 struct specialix_board
*bp
;
1590 unsigned long flags
;
1592 if (sx_paranoia_check(port
, tty
->device
, "sx_write"))
1595 bp
= port_Board(port
);
1597 if (!tty
|| !port
->xmit_buf
|| !tmp_buf
)
1606 c
= MIN(count
, MIN(SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1,
1607 SERIAL_XMIT_SIZE
- port
->xmit_head
));
1612 copy_from_user(tmp_buf
, buf
, c
);
1613 c
= MIN(c
, MIN(SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1,
1614 SERIAL_XMIT_SIZE
- port
->xmit_head
));
1615 memcpy(port
->xmit_buf
+ port
->xmit_head
, tmp_buf
, c
);
1617 memcpy(port
->xmit_buf
+ port
->xmit_head
, buf
, c
);
1618 port
->xmit_head
= (port
->xmit_head
+ c
) & (SERIAL_XMIT_SIZE
-1);
1619 port
->xmit_cnt
+= c
;
1620 restore_flags(flags
);
1627 if (port
->xmit_cnt
&& !tty
->stopped
&& !tty
->hw_stopped
&&
1628 !(port
->IER
& IER_TXRDY
)) {
1629 port
->IER
|= IER_TXRDY
;
1630 sx_out(bp
, CD186x_CAR
, port_No(port
));
1631 sx_out(bp
, CD186x_IER
, port
->IER
);
1633 restore_flags(flags
);
1638 static void sx_put_char(struct tty_struct
* tty
, unsigned char ch
)
1640 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1641 unsigned long flags
;
1643 if (sx_paranoia_check(port
, tty
->device
, "sx_put_char"))
1646 if (!tty
|| !port
->xmit_buf
)
1649 save_flags(flags
); cli();
1651 if (port
->xmit_cnt
>= SERIAL_XMIT_SIZE
- 1) {
1652 restore_flags(flags
);
1656 port
->xmit_buf
[port
->xmit_head
++] = ch
;
1657 port
->xmit_head
&= SERIAL_XMIT_SIZE
- 1;
1659 restore_flags(flags
);
1663 static void sx_flush_chars(struct tty_struct
* tty
)
1665 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1666 unsigned long flags
;
1668 if (sx_paranoia_check(port
, tty
->device
, "sx_flush_chars"))
1671 if (port
->xmit_cnt
<= 0 || tty
->stopped
|| tty
->hw_stopped
||
1675 save_flags(flags
); cli();
1676 port
->IER
|= IER_TXRDY
;
1677 sx_out(port_Board(port
), CD186x_CAR
, port_No(port
));
1678 sx_out(port_Board(port
), CD186x_IER
, port
->IER
);
1679 restore_flags(flags
);
1683 static int sx_write_room(struct tty_struct
* tty
)
1685 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1688 if (sx_paranoia_check(port
, tty
->device
, "sx_write_room"))
1691 ret
= SERIAL_XMIT_SIZE
- port
->xmit_cnt
- 1;
1698 static int sx_chars_in_buffer(struct tty_struct
*tty
)
1700 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1702 if (sx_paranoia_check(port
, tty
->device
, "sx_chars_in_buffer"))
1705 return port
->xmit_cnt
;
1709 static void sx_flush_buffer(struct tty_struct
*tty
)
1711 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1712 unsigned long flags
;
1714 if (sx_paranoia_check(port
, tty
->device
, "sx_flush_buffer"))
1717 save_flags(flags
); cli();
1718 port
->xmit_cnt
= port
->xmit_head
= port
->xmit_tail
= 0;
1719 restore_flags(flags
);
1721 wake_up_interruptible(&tty
->write_wait
);
1722 if ((tty
->flags
& (1 << TTY_DO_WRITE_WAKEUP
)) &&
1723 tty
->ldisc
.write_wakeup
)
1724 (tty
->ldisc
.write_wakeup
)(tty
);
1728 static int sx_get_modem_info(struct specialix_port
* port
, unsigned int *value
)
1730 struct specialix_board
* bp
;
1731 unsigned char status
;
1732 unsigned int result
;
1733 unsigned long flags
;
1735 bp
= port_Board(port
);
1736 save_flags(flags
); cli();
1737 sx_out(bp
, CD186x_CAR
, port_No(port
));
1738 status
= sx_in(bp
, CD186x_MSVR
);
1739 restore_flags(flags
);
1740 #ifdef DEBUG_SPECIALIX
1741 printk (KERN_DEBUG
"Got msvr[%d] = %02x, car = %d.\n",
1742 port_No(port
), status
, sx_in (bp
, CD186x_CAR
));
1743 printk (KERN_DEBUG
"sx_port = %p, port = %p\n", sx_port
, port
);
1745 if (SX_CRTSCTS(port
->tty
)) {
1746 result
= /* (status & MSVR_RTS) ? */ TIOCM_DTR
/* : 0) */
1747 | ((status
& MSVR_DTR
) ? TIOCM_RTS
: 0)
1748 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1749 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR
/* : 0) */
1750 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1752 result
= /* (status & MSVR_RTS) ? */ TIOCM_RTS
/* : 0) */
1753 | ((status
& MSVR_DTR
) ? TIOCM_DTR
: 0)
1754 | ((status
& MSVR_CD
) ? TIOCM_CAR
: 0)
1755 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR
/* : 0) */
1756 | ((status
& MSVR_CTS
) ? TIOCM_CTS
: 0);
1758 put_user(result
,(unsigned int *) value
);
1763 static int sx_set_modem_info(struct specialix_port
* port
, unsigned int cmd
,
1764 unsigned int *value
)
1768 unsigned long flags
;
1769 struct specialix_board
*bp
= port_Board(port
);
1771 error
= verify_area(VERIFY_READ
, value
, sizeof(int));
1775 Get_user(arg
, (unsigned long *) value
);
1778 /* if (arg & TIOCM_RTS)
1779 port->MSVR |= MSVR_RTS; */
1780 /* if (arg & TIOCM_DTR)
1781 port->MSVR |= MSVR_DTR; */
1783 if (SX_CRTSCTS(port
->tty
)) {
1784 if (arg
& TIOCM_RTS
)
1785 port
->MSVR
|= MSVR_DTR
;
1787 if (arg
& TIOCM_DTR
)
1788 port
->MSVR
|= MSVR_DTR
;
1792 /* if (arg & TIOCM_RTS)
1793 port->MSVR &= ~MSVR_RTS; */
1794 /* if (arg & TIOCM_DTR)
1795 port->MSVR &= ~MSVR_DTR; */
1796 if (SX_CRTSCTS(port
->tty
)) {
1797 if (arg
& TIOCM_RTS
)
1798 port
->MSVR
&= ~MSVR_DTR
;
1800 if (arg
& TIOCM_DTR
)
1801 port
->MSVR
&= ~MSVR_DTR
;
1805 /* port->MSVR = (arg & TIOCM_RTS) ? (port->MSVR | MSVR_RTS) :
1806 (port->MSVR & ~MSVR_RTS); */
1807 /* port->MSVR = (arg & TIOCM_DTR) ? (port->MSVR | MSVR_DTR) :
1808 (port->MSVR & ~MSVR_DTR); */
1809 if (SX_CRTSCTS(port
->tty
)) {
1810 port
->MSVR
= (arg
& TIOCM_RTS
) ?
1811 (port
->MSVR
| MSVR_DTR
) :
1812 (port
->MSVR
& ~MSVR_DTR
);
1814 port
->MSVR
= (arg
& TIOCM_DTR
) ?
1815 (port
->MSVR
| MSVR_DTR
):
1816 (port
->MSVR
& ~MSVR_DTR
);
1822 save_flags(flags
); cli();
1823 sx_out(bp
, CD186x_CAR
, port_No(port
));
1824 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
1825 restore_flags(flags
);
1830 extern inline void sx_send_break(struct specialix_port
* port
, unsigned long length
)
1832 struct specialix_board
*bp
= port_Board(port
);
1833 unsigned long flags
;
1835 save_flags(flags
); cli();
1836 port
->break_length
= SPECIALIX_TPS
/ HZ
* length
;
1837 port
->COR2
|= COR2_ETC
;
1838 port
->IER
|= IER_TXRDY
;
1839 sx_out(bp
, CD186x_CAR
, port_No(port
));
1840 sx_out(bp
, CD186x_COR2
, port
->COR2
);
1841 sx_out(bp
, CD186x_IER
, port
->IER
);
1843 sx_out(bp
, CD186x_CCR
, CCR_CORCHG2
);
1845 restore_flags(flags
);
1849 extern inline int sx_set_serial_info(struct specialix_port
* port
,
1850 struct serial_struct
* newinfo
)
1852 struct serial_struct tmp
;
1853 struct specialix_board
*bp
= port_Board(port
);
1855 unsigned long flags
;
1858 error
= verify_area(VERIFY_READ
, (void *) newinfo
, sizeof(tmp
));
1862 copy_from_user(&tmp
, newinfo
, sizeof(tmp
));
1865 if ((tmp
.irq
!= bp
->irq
) ||
1866 (tmp
.port
!= bp
->base
) ||
1867 (tmp
.type
!= PORT_CIRRUS
) ||
1868 (tmp
.baud_base
!= (SX_OSCFREQ
+ CD186x_TPC
/2) / CD186x_TPC
) ||
1869 (tmp
.custom_divisor
!= 0) ||
1870 (tmp
.xmit_fifo_size
!= CD186x_NFIFO
) ||
1871 (tmp
.flags
& ~SPECIALIX_LEGAL_FLAGS
))
1875 change_speed
= ((port
->flags
& ASYNC_SPD_MASK
) !=
1876 (tmp
.flags
& ASYNC_SPD_MASK
));
1878 if (!capable(CAP_SYS_ADMIN
)) {
1879 if ((tmp
.close_delay
!= port
->close_delay
) ||
1880 (tmp
.closing_wait
!= port
->closing_wait
) ||
1881 ((tmp
.flags
& ~ASYNC_USR_MASK
) !=
1882 (port
->flags
& ~ASYNC_USR_MASK
)))
1884 port
->flags
= ((port
->flags
& ~ASYNC_USR_MASK
) |
1885 (tmp
.flags
& ASYNC_USR_MASK
));
1887 port
->flags
= ((port
->flags
& ~ASYNC_FLAGS
) |
1888 (tmp
.flags
& ASYNC_FLAGS
));
1889 port
->close_delay
= tmp
.close_delay
;
1890 port
->closing_wait
= tmp
.closing_wait
;
1893 save_flags(flags
); cli();
1894 sx_change_speed(bp
, port
);
1895 restore_flags(flags
);
1901 extern inline int sx_get_serial_info(struct specialix_port
* port
,
1902 struct serial_struct
* retinfo
)
1904 struct serial_struct tmp
;
1905 struct specialix_board
*bp
= port_Board(port
);
1908 error
= verify_area(VERIFY_WRITE
, (void *) retinfo
, sizeof(tmp
));
1912 memset(&tmp
, 0, sizeof(tmp
));
1913 tmp
.type
= PORT_CIRRUS
;
1914 tmp
.line
= port
- sx_port
;
1915 tmp
.port
= bp
->base
;
1917 tmp
.flags
= port
->flags
;
1918 tmp
.baud_base
= (SX_OSCFREQ
+ CD186x_TPC
/2) / CD186x_TPC
;
1919 tmp
.close_delay
= port
->close_delay
* HZ
/100;
1920 tmp
.closing_wait
= port
->closing_wait
* HZ
/100;
1921 tmp
.xmit_fifo_size
= CD186x_NFIFO
;
1922 copy_to_user(retinfo
, &tmp
, sizeof(tmp
));
1927 static int sx_ioctl(struct tty_struct
* tty
, struct file
* filp
,
1928 unsigned int cmd
, unsigned long arg
)
1930 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1934 if (sx_paranoia_check(port
, tty
->device
, "sx_ioctl"))
1938 case TCSBRK
: /* SVID version: non-zero arg --> no break */
1939 retval
= tty_check_change(tty
);
1942 tty_wait_until_sent(tty
, 0);
1944 sx_send_break(port
, HZ
/4); /* 1/4 second */
1946 case TCSBRKP
: /* support for POSIX tcsendbreak() */
1947 retval
= tty_check_change(tty
);
1950 tty_wait_until_sent(tty
, 0);
1951 sx_send_break(port
, arg
? arg
*(HZ
/10) : HZ
/4);
1954 error
= verify_area(VERIFY_WRITE
, (void *) arg
, sizeof(long));
1957 put_user(C_CLOCAL(tty
) ? 1 : 0,
1958 (unsigned long *) arg
);
1961 Get_user(arg
, (unsigned long *) arg
);
1962 tty
->termios
->c_cflag
=
1963 ((tty
->termios
->c_cflag
& ~CLOCAL
) |
1964 (arg
? CLOCAL
: 0));
1967 error
= verify_area(VERIFY_WRITE
, (void *) arg
,
1968 sizeof(unsigned int));
1971 return sx_get_modem_info(port
, (unsigned int *) arg
);
1975 return sx_set_modem_info(port
, cmd
, (unsigned int *) arg
);
1977 return sx_get_serial_info(port
, (struct serial_struct
*) arg
);
1979 return sx_set_serial_info(port
, (struct serial_struct
*) arg
);
1981 return -ENOIOCTLCMD
;
1987 static void sx_throttle(struct tty_struct
* tty
)
1989 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
1990 struct specialix_board
*bp
;
1991 unsigned long flags
;
1993 if (sx_paranoia_check(port
, tty
->device
, "sx_throttle"))
1996 bp
= port_Board(port
);
1998 save_flags(flags
); cli();
2000 /* Use DTR instead of RTS ! */
2001 if (SX_CRTSCTS (tty
))
2002 port
->MSVR
&= ~MSVR_DTR
;
2004 /* Auch!!! I think the system shouldn't call this then. */
2005 /* Or maybe we're supposed (allowed?) to do our side of hw
2006 handshake anyway, even when hardware handshake is off.
2007 When you see this in your logs, please report.... */
2008 printk (KERN_ERR
"sx%d: Need to throttle, but can't (hardware hs is off)\n",
2011 sx_out(bp
, CD186x_CAR
, port_No(port
));
2014 sx_out(bp
, CD186x_CCR
, CCR_SSCH2
);
2017 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2018 restore_flags(flags
);
2022 static void sx_unthrottle(struct tty_struct
* tty
)
2024 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2025 struct specialix_board
*bp
;
2026 unsigned long flags
;
2028 if (sx_paranoia_check(port
, tty
->device
, "sx_unthrottle"))
2031 bp
= port_Board(port
);
2033 save_flags(flags
); cli();
2034 /* XXXX Use DTR INSTEAD???? */
2035 if (SX_CRTSCTS(tty
)) {
2036 port
->MSVR
|= MSVR_DTR
;
2037 } /* Else clause: see remark in "sx_throttle"... */
2039 sx_out(bp
, CD186x_CAR
, port_No(port
));
2042 sx_out(bp
, CD186x_CCR
, CCR_SSCH1
);
2045 sx_out(bp
, CD186x_MSVR
, port
->MSVR
);
2046 restore_flags(flags
);
2050 static void sx_stop(struct tty_struct
* tty
)
2052 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2053 struct specialix_board
*bp
;
2054 unsigned long flags
;
2056 if (sx_paranoia_check(port
, tty
->device
, "sx_stop"))
2059 bp
= port_Board(port
);
2061 save_flags(flags
); cli();
2062 port
->IER
&= ~IER_TXRDY
;
2063 sx_out(bp
, CD186x_CAR
, port_No(port
));
2064 sx_out(bp
, CD186x_IER
, port
->IER
);
2065 restore_flags(flags
);
2069 static void sx_start(struct tty_struct
* tty
)
2071 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2072 struct specialix_board
*bp
;
2073 unsigned long flags
;
2075 if (sx_paranoia_check(port
, tty
->device
, "sx_start"))
2078 bp
= port_Board(port
);
2080 save_flags(flags
); cli();
2081 if (port
->xmit_cnt
&& port
->xmit_buf
&& !(port
->IER
& IER_TXRDY
)) {
2082 port
->IER
|= IER_TXRDY
;
2083 sx_out(bp
, CD186x_CAR
, port_No(port
));
2084 sx_out(bp
, CD186x_IER
, port
->IER
);
2086 restore_flags(flags
);
2091 * This routine is called from the scheduler tqueue when the interrupt
2092 * routine has signalled that a hangup has occurred. The path of
2093 * hangup processing is:
2095 * serial interrupt routine -> (scheduler tqueue) ->
2096 * do_sx_hangup() -> tty->hangup() -> sx_hangup()
2099 static void do_sx_hangup(void *private_
)
2101 struct specialix_port
*port
= (struct specialix_port
*) private_
;
2102 struct tty_struct
*tty
;
2112 static void sx_hangup(struct tty_struct
* tty
)
2114 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2115 struct specialix_board
*bp
;
2117 if (sx_paranoia_check(port
, tty
->device
, "sx_hangup"))
2120 bp
= port_Board(port
);
2122 sx_shutdown_port(bp
, port
);
2125 port
->flags
&= ~(ASYNC_NORMAL_ACTIVE
|ASYNC_CALLOUT_ACTIVE
);
2127 wake_up_interruptible(&port
->open_wait
);
2131 static void sx_set_termios(struct tty_struct
* tty
, struct termios
* old_termios
)
2133 struct specialix_port
*port
= (struct specialix_port
*)tty
->driver_data
;
2134 unsigned long flags
;
2136 if (sx_paranoia_check(port
, tty
->device
, "sx_set_termios"))
2139 if (tty
->termios
->c_cflag
== old_termios
->c_cflag
&&
2140 tty
->termios
->c_iflag
== old_termios
->c_iflag
)
2143 save_flags(flags
); cli();
2144 sx_change_speed(port_Board(port
), port
);
2145 restore_flags(flags
);
2147 if ((old_termios
->c_cflag
& CRTSCTS
) &&
2148 !(tty
->termios
->c_cflag
& CRTSCTS
)) {
2149 tty
->hw_stopped
= 0;
2155 static void do_specialix_bh(void)
2157 run_task_queue(&tq_specialix
);
2161 static void do_softint(void *private_
)
2163 struct specialix_port
*port
= (struct specialix_port
*) private_
;
2164 struct tty_struct
*tty
;
2166 if(!(tty
= port
->tty
))
2169 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP
, &port
->event
)) {
2170 if ((tty
->flags
& (1 << TTY_DO_WRITE_WAKEUP
)) &&
2171 tty
->ldisc
.write_wakeup
)
2172 (tty
->ldisc
.write_wakeup
)(tty
);
2173 wake_up_interruptible(&tty
->write_wait
);
2178 static int sx_init_drivers(void)
2184 if (!(tmp_buf
= (unsigned char *) get_free_page(GFP_KERNEL
))) {
2185 printk(KERN_ERR
"sx: Couldn't get free page.\n");
2188 init_bh(SPECIALIX_BH
, do_specialix_bh
);
2189 memset(&specialix_driver
, 0, sizeof(specialix_driver
));
2190 specialix_driver
.magic
= TTY_DRIVER_MAGIC
;
2191 specialix_driver
.name
= "ttyW";
2192 specialix_driver
.major
= SPECIALIX_NORMAL_MAJOR
;
2193 specialix_driver
.num
= SX_NBOARD
* SX_NPORT
;
2194 specialix_driver
.type
= TTY_DRIVER_TYPE_SERIAL
;
2195 specialix_driver
.subtype
= SPECIALIX_TYPE_NORMAL
;
2196 specialix_driver
.init_termios
= tty_std_termios
;
2197 specialix_driver
.init_termios
.c_cflag
=
2198 B9600
| CS8
| CREAD
| HUPCL
| CLOCAL
;
2199 specialix_driver
.flags
= TTY_DRIVER_REAL_RAW
;
2200 specialix_driver
.refcount
= &specialix_refcount
;
2201 specialix_driver
.table
= specialix_table
;
2202 specialix_driver
.termios
= specialix_termios
;
2203 specialix_driver
.termios_locked
= specialix_termios_locked
;
2205 specialix_driver
.open
= sx_open
;
2206 specialix_driver
.close
= sx_close
;
2207 specialix_driver
.write
= sx_write
;
2208 specialix_driver
.put_char
= sx_put_char
;
2209 specialix_driver
.flush_chars
= sx_flush_chars
;
2210 specialix_driver
.write_room
= sx_write_room
;
2211 specialix_driver
.chars_in_buffer
= sx_chars_in_buffer
;
2212 specialix_driver
.flush_buffer
= sx_flush_buffer
;
2213 specialix_driver
.ioctl
= sx_ioctl
;
2214 specialix_driver
.throttle
= sx_throttle
;
2215 specialix_driver
.unthrottle
= sx_unthrottle
;
2216 specialix_driver
.set_termios
= sx_set_termios
;
2217 specialix_driver
.stop
= sx_stop
;
2218 specialix_driver
.start
= sx_start
;
2219 specialix_driver
.hangup
= sx_hangup
;
2221 specialix_callout_driver
= specialix_driver
;
2222 specialix_callout_driver
.name
= "cuw";
2223 specialix_callout_driver
.major
= SPECIALIX_CALLOUT_MAJOR
;
2224 specialix_callout_driver
.subtype
= SPECIALIX_TYPE_CALLOUT
;
2226 if ((error
= tty_register_driver(&specialix_driver
))) {
2227 free_page((unsigned long)tmp_buf
);
2228 printk(KERN_ERR
"sx: Couldn't register specialix IO8+ driver, error = %d\n",
2232 if ((error
= tty_register_driver(&specialix_callout_driver
))) {
2233 free_page((unsigned long)tmp_buf
);
2234 tty_unregister_driver(&specialix_driver
);
2235 printk(KERN_ERR
"sx: Couldn't register specialix IO8+ callout driver, error = %d\n",
2240 memset(sx_port
, 0, sizeof(sx_port
));
2241 for (i
= 0; i
< SX_NPORT
* SX_NBOARD
; i
++) {
2242 sx_port
[i
].callout_termios
= specialix_callout_driver
.init_termios
;
2243 sx_port
[i
].normal_termios
= specialix_driver
.init_termios
;
2244 sx_port
[i
].magic
= SPECIALIX_MAGIC
;
2245 sx_port
[i
].tqueue
.routine
= do_softint
;
2246 sx_port
[i
].tqueue
.data
= &sx_port
[i
];
2247 sx_port
[i
].tqueue_hangup
.routine
= do_sx_hangup
;
2248 sx_port
[i
].tqueue_hangup
.data
= &sx_port
[i
];
2249 sx_port
[i
].close_delay
= 50 * HZ
/100;
2250 sx_port
[i
].closing_wait
= 3000 * HZ
/100;
2251 init_waitqueue_head(&sx_port
[i
].open_wait
);
2252 init_waitqueue_head(&sx_port
[i
].close_wait
);
2259 static void sx_release_drivers(void)
2261 free_page((unsigned long)tmp_buf
);
2262 tty_unregister_driver(&specialix_driver
);
2263 tty_unregister_driver(&specialix_callout_driver
);
2269 * Called at boot time.
2271 * You can specify IO base for up to SX_NBOARD cards,
2272 * using line "specialix=0xiobase1,0xiobase2,.." at LILO prompt.
2273 * Note that there will be no probing at default
2274 * addresses in this case.
2277 void specialix_setup(char *str
, int * ints
)
2281 for (i
=0;i
<SX_NBOARD
;i
++) {
2282 sx_board
[i
].base
= 0;
2285 for (i
= 1; i
<= ints
[0]; i
++) {
2287 sx_board
[i
/2].base
= ints
[i
];
2289 sx_board
[i
/2 -1].irq
= ints
[i
];
2295 * This routine must be called by kernel at boot time
2297 int specialix_init(void)
2302 printk(KERN_INFO
"sx: Specialix IO8+ driver v" VERSION
", (c) R.E.Wolff 1997/1998.\n");
2303 printk(KERN_INFO
"sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2304 #ifdef CONFIG_SPECIALIX_RTSCTS
2305 printk (KERN_INFO
"sx: DTR/RTS pin is always RTS.\n");
2307 printk (KERN_INFO
"sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2310 if (sx_init_drivers())
2313 for (i
= 0; i
< SX_NBOARD
; i
++)
2314 if (sx_board
[i
].base
&& !sx_probe(&sx_board
[i
]))
2318 if (pci_present()) {
2319 struct pci_dev
*pdev
= NULL
;
2323 while (i
<= SX_NBOARD
) {
2324 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
) {
2328 pdev
= pci_find_device (PCI_VENDOR_ID_SPECIALIX
,
2329 PCI_DEVICE_ID_SPECIALIX_IO8
,
2333 sx_board
[i
].irq
= pdev
->irq
;
2335 pci_read_config_dword(pdev
, PCI_BASE_ADDRESS_2
, &tint
);
2336 /* Mask out the fact that it's IO-space */
2337 sx_board
[i
].base
= tint
& PCI_BASE_ADDRESS_IO_MASK
;
2339 sx_board
[i
].flags
|= SX_BOARD_IS_PCI
;
2340 if (!sx_probe(&sx_board
[i
]))
2347 sx_release_drivers();
2348 printk(KERN_INFO
"sx: No specialix IO8+ boards detected.\n");
2356 int iobase
[SX_NBOARD
] = {0,};
2358 int irq
[SX_NBOARD
] = {0,};
2360 MODULE_PARM(iobase
,"1-" __MODULE_STRING(SX_NBOARD
) "i");
2361 MODULE_PARM(irq
,"1-" __MODULE_STRING(SX_NBOARD
) "i");
2364 * You can setup up to 4 boards.
2365 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2366 * You should specify the IRQs too in that case "irq=....,...".
2368 * More than 4 boards in one computer is not possible, as the card can
2369 * only use 4 different interrupts.
2372 int init_module(void)
2376 if (iobase
[0] || iobase
[1] || iobase
[2] || iobase
[3]) {
2377 for(i
= 0; i
< SX_NBOARD
; i
++) {
2378 sx_board
[i
].base
= iobase
[i
];
2379 sx_board
[i
].irq
= irq
[i
];
2383 return specialix_init();
2387 void cleanup_module(void)
2391 sx_release_drivers();
2392 for (i
= 0; i
< SX_NBOARD
; i
++)
2393 if (sx_board
[i
].flags
& SX_BOARD_PRESENT
)
2394 sx_release_io_range(&sx_board
[i
]);
2395 #ifdef SPECIALIX_TIMER
2396 del_timer (&missed_irq_timer
);