diff options
-rw-r--r-- | Documentation/specialix.txt | 8 | ||||
-rw-r--r-- | drivers/char/Kconfig | 10 | ||||
-rw-r--r-- | drivers/char/specialix.c | 216 |
3 files changed, 47 insertions, 187 deletions
diff --git a/Documentation/specialix.txt b/Documentation/specialix.txt index 4a4b428ce8f6..6eb6f3a3331c 100644 --- a/Documentation/specialix.txt +++ b/Documentation/specialix.txt | |||
@@ -270,8 +270,8 @@ The pinout of the connectors on the IO8+ is: | |||
270 | Hardware handshaking issues. | 270 | Hardware handshaking issues. |
271 | ============================ | 271 | ============================ |
272 | 272 | ||
273 | The driver can be compiled in two different ways. The default | 273 | The driver can be told to operate in two different ways. The default |
274 | ("Specialix DTR/RTS pin is RTS" is off) the pin behaves as DTR when | 274 | behaviour is specialix.sx_rtscts = 0 where the pin behaves as DTR when |
275 | hardware handshaking is off. It behaves as the RTS hardware | 275 | hardware handshaking is off. It behaves as the RTS hardware |
276 | handshaking signal when hardware handshaking is selected. | 276 | handshaking signal when hardware handshaking is selected. |
277 | 277 | ||
@@ -280,7 +280,7 @@ cable will either be compatible with hardware handshaking or with | |||
280 | software handshaking. So switching on the fly is not really an | 280 | software handshaking. So switching on the fly is not really an |
281 | option. | 281 | option. |
282 | 282 | ||
283 | I actually prefer to use the "Specialix DTR/RTS pin is RTS" option. | 283 | I actually prefer to use the "specialix.sx_rtscts=1" option. |
284 | This makes the DTR/RTS pin always an RTS pin, and ioctls to | 284 | This makes the DTR/RTS pin always an RTS pin, and ioctls to |
285 | change DTR are always ignored. I have a cable that is configured | 285 | change DTR are always ignored. I have a cable that is configured |
286 | for this. | 286 | for this. |
@@ -379,7 +379,5 @@ it doesn't fit in your computer, bring back the card. | |||
379 | You have to WRITE to the address register to even | 379 | You have to WRITE to the address register to even |
380 | read-probe a CD186x register. Disable autodetection? | 380 | read-probe a CD186x register. Disable autodetection? |
381 | -- Specialix: any suggestions? | 381 | -- Specialix: any suggestions? |
382 | - Arbitrary baud rates are not implemented yet. | ||
383 | If you need this, bug me about it. | ||
384 | 382 | ||
385 | 383 | ||
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 650e6b44ce65..e0bbbfb6a36b 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -300,16 +300,6 @@ config SPECIALIX | |||
300 | and compile this driver as kernel loadable module which will be | 300 | and compile this driver as kernel loadable module which will be |
301 | called specialix. | 301 | called specialix. |
302 | 302 | ||
303 | config SPECIALIX_RTSCTS | ||
304 | bool "Specialix DTR/RTS pin is RTS" | ||
305 | depends on SPECIALIX | ||
306 | help | ||
307 | The Specialix IO8+ card can only support either RTS or DTR. If you | ||
308 | say N here, the driver will use the pin as "DTR" when the tty is in | ||
309 | software handshake mode. If you say Y here or hardware handshake is | ||
310 | on, it will always be RTS. Read the file | ||
311 | <file:Documentation/specialix.txt> for more information. | ||
312 | |||
313 | config SX | 303 | config SX |
314 | tristate "Specialix SX (and SI) card support" | 304 | tristate "Specialix SX (and SI) card support" |
315 | depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) | 305 | depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index c390c6cc030e..f3184a8a75d6 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -110,6 +110,7 @@ | |||
110 | 110 | ||
111 | static int sx_debug; | 111 | static int sx_debug; |
112 | static int sx_rxfifo = SPECIALIX_RXFIFO; | 112 | static int sx_rxfifo = SPECIALIX_RXFIFO; |
113 | static int sx_rtscts; | ||
113 | 114 | ||
114 | #ifdef DEBUG | 115 | #ifdef DEBUG |
115 | #define dprintk(f, str...) if (sx_debug & f) printk(str) | 116 | #define dprintk(f, str...) if (sx_debug & f) printk(str) |
@@ -134,25 +135,12 @@ static int sx_rxfifo = SPECIALIX_RXFIFO; | |||
134 | #define func_enter() dprintk(SX_DEBUG_FLOW, "io8: enter %s\n", __func__) | 135 | #define func_enter() dprintk(SX_DEBUG_FLOW, "io8: enter %s\n", __func__) |
135 | #define func_exit() dprintk(SX_DEBUG_FLOW, "io8: exit %s\n", __func__) | 136 | #define func_exit() dprintk(SX_DEBUG_FLOW, "io8: exit %s\n", __func__) |
136 | 137 | ||
137 | #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1) | ||
138 | |||
139 | 138 | ||
140 | /* Configurable options: */ | 139 | /* Configurable options: */ |
141 | 140 | ||
142 | /* Am I paranoid or not ? ;-) */ | 141 | /* Am I paranoid or not ? ;-) */ |
143 | #define SPECIALIX_PARANOIA_CHECK | 142 | #define SPECIALIX_PARANOIA_CHECK |
144 | 143 | ||
145 | /* Do I trust the IRQ from the card? (enabeling it doesn't seem to help) | ||
146 | When the IRQ routine leaves the chip in a state that is keeps on | ||
147 | requiring attention, the timer doesn't help either. */ | ||
148 | #undef SPECIALIX_TIMER | ||
149 | |||
150 | #ifdef SPECIALIX_TIMER | ||
151 | static int sx_poll = HZ; | ||
152 | #endif | ||
153 | |||
154 | |||
155 | |||
156 | /* | 144 | /* |
157 | * The following defines are mostly for testing purposes. But if you need | 145 | * The following defines are mostly for testing purposes. But if you need |
158 | * some nice reporting in your syslog, you can define them also. | 146 | * some nice reporting in your syslog, you can define them also. |
@@ -162,16 +150,6 @@ static int sx_poll = HZ; | |||
162 | 150 | ||
163 | 151 | ||
164 | 152 | ||
165 | #ifdef CONFIG_SPECIALIX_RTSCTS | ||
166 | #define SX_CRTSCTS(bla) 1 | ||
167 | #else | ||
168 | #define SX_CRTSCTS(tty) C_CRTSCTS(tty) | ||
169 | #endif | ||
170 | |||
171 | |||
172 | /* Used to be outb(0xff, 0x80); */ | ||
173 | #define short_pause() udelay(1) | ||
174 | |||
175 | 153 | ||
176 | #define SPECIALIX_LEGAL_FLAGS \ | 154 | #define SPECIALIX_LEGAL_FLAGS \ |
177 | (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \ | 155 | (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \ |
@@ -190,14 +168,7 @@ static struct specialix_board sx_board[SX_NBOARD] = { | |||
190 | static struct specialix_port sx_port[SX_NBOARD * SX_NPORT]; | 168 | static struct specialix_port sx_port[SX_NBOARD * SX_NPORT]; |
191 | 169 | ||
192 | 170 | ||
193 | #ifdef SPECIALIX_TIMER | 171 | static int sx_paranoia_check(struct specialix_port const *port, |
194 | static struct timer_list missed_irq_timer; | ||
195 | static irqreturn_t sx_interrupt(int irq, void *dev_id); | ||
196 | #endif | ||
197 | |||
198 | |||
199 | |||
200 | static inline int sx_paranoia_check(struct specialix_port const *port, | ||
201 | char *name, const char *routine) | 172 | char *name, const char *routine) |
202 | { | 173 | { |
203 | #ifdef SPECIALIX_PARANOIA_CHECK | 174 | #ifdef SPECIALIX_PARANOIA_CHECK |
@@ -288,7 +259,7 @@ static inline void sx_out_off(struct specialix_board *bp, | |||
288 | 259 | ||
289 | 260 | ||
290 | /* Wait for Channel Command Register ready */ | 261 | /* Wait for Channel Command Register ready */ |
291 | static inline void sx_wait_CCR(struct specialix_board *bp) | 262 | static void sx_wait_CCR(struct specialix_board *bp) |
292 | { | 263 | { |
293 | unsigned long delay, flags; | 264 | unsigned long delay, flags; |
294 | unsigned char ccr; | 265 | unsigned char ccr; |
@@ -307,7 +278,7 @@ static inline void sx_wait_CCR(struct specialix_board *bp) | |||
307 | 278 | ||
308 | 279 | ||
309 | /* Wait for Channel Command Register ready */ | 280 | /* Wait for Channel Command Register ready */ |
310 | static inline void sx_wait_CCR_off(struct specialix_board *bp) | 281 | static void sx_wait_CCR_off(struct specialix_board *bp) |
311 | { | 282 | { |
312 | unsigned long delay; | 283 | unsigned long delay; |
313 | unsigned char crr; | 284 | unsigned char crr; |
@@ -330,7 +301,7 @@ static inline void sx_wait_CCR_off(struct specialix_board *bp) | |||
330 | * specialix IO8+ IO range functions. | 301 | * specialix IO8+ IO range functions. |
331 | */ | 302 | */ |
332 | 303 | ||
333 | static inline int sx_request_io_range(struct specialix_board *bp) | 304 | static int sx_request_io_range(struct specialix_board *bp) |
334 | { | 305 | { |
335 | return request_region(bp->base, | 306 | return request_region(bp->base, |
336 | bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE, | 307 | bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE, |
@@ -338,7 +309,7 @@ static inline int sx_request_io_range(struct specialix_board *bp) | |||
338 | } | 309 | } |
339 | 310 | ||
340 | 311 | ||
341 | static inline void sx_release_io_range(struct specialix_board *bp) | 312 | static void sx_release_io_range(struct specialix_board *bp) |
342 | { | 313 | { |
343 | release_region(bp->base, bp->flags & SX_BOARD_IS_PCI ? | 314 | release_region(bp->base, bp->flags & SX_BOARD_IS_PCI ? |
344 | SX_PCI_IO_SPACE : SX_IO_SPACE); | 315 | SX_PCI_IO_SPACE : SX_IO_SPACE); |
@@ -440,36 +411,10 @@ static int read_cross_byte(struct specialix_board *bp, int reg, int bit) | |||
440 | } | 411 | } |
441 | 412 | ||
442 | 413 | ||
443 | #ifdef SPECIALIX_TIMER | ||
444 | void missed_irq(unsigned long data) | ||
445 | { | ||
446 | unsigned char irq; | ||
447 | unsigned long flags; | ||
448 | struct specialix_board *bp = (struct specialix_board *)data; | ||
449 | |||
450 | spin_lock_irqsave(&bp->lock, flags); | ||
451 | irq = sx_in((struct specialix_board *)data, CD186x_SRSR) & | ||
452 | (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint); | ||
453 | spin_unlock_irqrestore(&bp->lock, flags); | ||
454 | if (irq) { | ||
455 | printk(KERN_INFO | ||
456 | "Missed interrupt... Calling int from timer. \n"); | ||
457 | sx_interrupt(-1, bp); | ||
458 | } | ||
459 | mod_timer(&missed_irq_timer, jiffies + sx_poll); | ||
460 | } | ||
461 | #endif | ||
462 | |||
463 | |||
464 | |||
465 | /* Main probing routine, also sets irq. */ | 414 | /* Main probing routine, also sets irq. */ |
466 | static int sx_probe(struct specialix_board *bp) | 415 | static int sx_probe(struct specialix_board *bp) |
467 | { | 416 | { |
468 | unsigned char val1, val2; | 417 | unsigned char val1, val2; |
469 | #if 0 | ||
470 | int irqs = 0; | ||
471 | int retries; | ||
472 | #endif | ||
473 | int rev; | 418 | int rev; |
474 | int chip; | 419 | int chip; |
475 | 420 | ||
@@ -482,15 +427,15 @@ static int sx_probe(struct specialix_board *bp) | |||
482 | 427 | ||
483 | /* Are the I/O ports here ? */ | 428 | /* Are the I/O ports here ? */ |
484 | sx_out_off(bp, CD186x_PPRL, 0x5a); | 429 | sx_out_off(bp, CD186x_PPRL, 0x5a); |
485 | short_pause(); | 430 | udelay(1); |
486 | val1 = sx_in_off(bp, CD186x_PPRL); | 431 | val1 = sx_in_off(bp, CD186x_PPRL); |
487 | 432 | ||
488 | sx_out_off(bp, CD186x_PPRL, 0xa5); | 433 | sx_out_off(bp, CD186x_PPRL, 0xa5); |
489 | short_pause(); | 434 | udelay(1); |
490 | val2 = sx_in_off(bp, CD186x_PPRL); | 435 | val2 = sx_in_off(bp, CD186x_PPRL); |
491 | 436 | ||
492 | 437 | ||
493 | if ((val1 != 0x5a) || (val2 != 0xa5)) { | 438 | if (val1 != 0x5a || val2 != 0xa5) { |
494 | printk(KERN_INFO | 439 | printk(KERN_INFO |
495 | "sx%d: specialix IO8+ Board at 0x%03x not found.\n", | 440 | "sx%d: specialix IO8+ Board at 0x%03x not found.\n", |
496 | board_No(bp), bp->base); | 441 | board_No(bp), bp->base); |
@@ -522,50 +467,6 @@ static int sx_probe(struct specialix_board *bp) | |||
522 | } | 467 | } |
523 | 468 | ||
524 | 469 | ||
525 | #if 0 | ||
526 | /* It's time to find IRQ for this board */ | ||
527 | for (retries = 0; retries < 5 && irqs <= 0; retries++) { | ||
528 | irqs = probe_irq_on(); | ||
529 | sx_init_CD186x(bp); /* Reset CD186x chip */ | ||
530 | sx_out(bp, CD186x_CAR, 2); /* Select port 2 */ | ||
531 | sx_wait_CCR(bp); | ||
532 | sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */ | ||
533 | sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */ | ||
534 | msleep(50); | ||
535 | irqs = probe_irq_off(irqs); | ||
536 | |||
537 | dprintk(SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR)); | ||
538 | dprintk(SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR)); | ||
539 | dprintk(SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR)); | ||
540 | dprintk(SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR)); | ||
541 | dprintk(SX_DEBUG_INIT, "\n"); | ||
542 | |||
543 | /* Reset CD186x again */ | ||
544 | if (!sx_init_CD186x(bp)) { | ||
545 | /* Hmmm. This is dead code anyway. */ | ||
546 | } | ||
547 | |||
548 | dprintk(SX_DEBUG_INIT | ||
549 | "val1 = %02x, val2 = %02x, val3 = %02x.\n", | ||
550 | val1, val2, val3); | ||
551 | |||
552 | } | ||
553 | |||
554 | #if 0 | ||
555 | if (irqs <= 0) { | ||
556 | printk(KERN_ERR | ||
557 | "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n", | ||
558 | board_No(bp), bp->base); | ||
559 | sx_release_io_range(bp); | ||
560 | func_exit(); | ||
561 | return 1; | ||
562 | } | ||
563 | #endif | ||
564 | printk(KERN_INFO "Started with irq=%d, but now have irq=%d.\n", | ||
565 | bp->irq, irqs); | ||
566 | if (irqs > 0) | ||
567 | bp->irq = irqs; | ||
568 | #endif | ||
569 | /* Reset CD186x again */ | 470 | /* Reset CD186x again */ |
570 | if (!sx_init_CD186x(bp)) { | 471 | if (!sx_init_CD186x(bp)) { |
571 | sx_release_io_range(bp); | 472 | sx_release_io_range(bp); |
@@ -610,11 +511,6 @@ static int sx_probe(struct specialix_board *bp) | |||
610 | 511 | ||
611 | dprintk(SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR)); | 512 | dprintk(SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR)); |
612 | 513 | ||
613 | #ifdef SPECIALIX_TIMER | ||
614 | setup_timer(&missed_irq_timer, missed_irq, (unsigned long)bp); | ||
615 | mod_timer(&missed_irq_timer, jiffies + sx_poll); | ||
616 | #endif | ||
617 | |||
618 | printk(KERN_INFO | 514 | printk(KERN_INFO |
619 | "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n", | 515 | "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n", |
620 | board_No(bp), bp->base, bp->irq, chip, rev); | 516 | board_No(bp), bp->base, bp->irq, chip, rev); |
@@ -628,7 +524,7 @@ static int sx_probe(struct specialix_board *bp) | |||
628 | * Interrupt processing routines. | 524 | * Interrupt processing routines. |
629 | * */ | 525 | * */ |
630 | 526 | ||
631 | static inline struct specialix_port *sx_get_port(struct specialix_board *bp, | 527 | static struct specialix_port *sx_get_port(struct specialix_board *bp, |
632 | unsigned char const *what) | 528 | unsigned char const *what) |
633 | { | 529 | { |
634 | unsigned char channel; | 530 | unsigned char channel; |
@@ -654,7 +550,7 @@ static inline struct specialix_port *sx_get_port(struct specialix_board *bp, | |||
654 | } | 550 | } |
655 | 551 | ||
656 | 552 | ||
657 | static inline void sx_receive_exc(struct specialix_board *bp) | 553 | static void sx_receive_exc(struct specialix_board *bp) |
658 | { | 554 | { |
659 | struct specialix_port *port; | 555 | struct specialix_port *port; |
660 | struct tty_struct *tty; | 556 | struct tty_struct *tty; |
@@ -729,7 +625,7 @@ static inline void sx_receive_exc(struct specialix_board *bp) | |||
729 | } | 625 | } |
730 | 626 | ||
731 | 627 | ||
732 | static inline void sx_receive(struct specialix_board *bp) | 628 | static void sx_receive(struct specialix_board *bp) |
733 | { | 629 | { |
734 | struct specialix_port *port; | 630 | struct specialix_port *port; |
735 | struct tty_struct *tty; | 631 | struct tty_struct *tty; |
@@ -758,7 +654,7 @@ static inline void sx_receive(struct specialix_board *bp) | |||
758 | } | 654 | } |
759 | 655 | ||
760 | 656 | ||
761 | static inline void sx_transmit(struct specialix_board *bp) | 657 | static void sx_transmit(struct specialix_board *bp) |
762 | { | 658 | { |
763 | struct specialix_port *port; | 659 | struct specialix_port *port; |
764 | struct tty_struct *tty; | 660 | struct tty_struct *tty; |
@@ -838,7 +734,7 @@ static inline void sx_transmit(struct specialix_board *bp) | |||
838 | } | 734 | } |
839 | 735 | ||
840 | 736 | ||
841 | static inline void sx_check_modem(struct specialix_board *bp) | 737 | static void sx_check_modem(struct specialix_board *bp) |
842 | { | 738 | { |
843 | struct specialix_port *port; | 739 | struct specialix_port *port; |
844 | struct tty_struct *tty; | 740 | struct tty_struct *tty; |
@@ -853,7 +749,6 @@ static inline void sx_check_modem(struct specialix_board *bp) | |||
853 | tty = port->port.tty; | 749 | tty = port->port.tty; |
854 | 750 | ||
855 | mcr = sx_in(bp, CD186x_MCR); | 751 | mcr = sx_in(bp, CD186x_MCR); |
856 | printk("mcr = %02x.\n", mcr); /* FIXME */ | ||
857 | 752 | ||
858 | if ((mcr & MCR_CDCHG)) { | 753 | if ((mcr & MCR_CDCHG)) { |
859 | dprintk(SX_DEBUG_SIGNALS, "CD just changed... "); | 754 | dprintk(SX_DEBUG_SIGNALS, "CD just changed... "); |
@@ -983,13 +878,6 @@ static void turn_ints_off(struct specialix_board *bp) | |||
983 | unsigned long flags; | 878 | unsigned long flags; |
984 | 879 | ||
985 | func_enter(); | 880 | func_enter(); |
986 | if (bp->flags & SX_BOARD_IS_PCI) { | ||
987 | /* This was intended for enabeling the interrupt on the | ||
988 | * PCI card. However it seems that it's already enabled | ||
989 | * and as PCI interrupts can be shared, there is no real | ||
990 | * reason to have to turn it off. */ | ||
991 | } | ||
992 | |||
993 | spin_lock_irqsave(&bp->lock, flags); | 881 | spin_lock_irqsave(&bp->lock, flags); |
994 | (void) sx_in_off(bp, 0); /* Turn off interrupts. */ | 882 | (void) sx_in_off(bp, 0); /* Turn off interrupts. */ |
995 | spin_unlock_irqrestore(&bp->lock, flags); | 883 | spin_unlock_irqrestore(&bp->lock, flags); |
@@ -1003,9 +891,6 @@ static void turn_ints_on(struct specialix_board *bp) | |||
1003 | 891 | ||
1004 | func_enter(); | 892 | func_enter(); |
1005 | 893 | ||
1006 | if (bp->flags & SX_BOARD_IS_PCI) { | ||
1007 | /* play with the PCI chip. See comment above. */ | ||
1008 | } | ||
1009 | spin_lock_irqsave(&bp->lock, flags); | 894 | spin_lock_irqsave(&bp->lock, flags); |
1010 | (void) sx_in(bp, 0); /* Turn ON interrupts. */ | 895 | (void) sx_in(bp, 0); /* Turn ON interrupts. */ |
1011 | spin_unlock_irqrestore(&bp->lock, flags); | 896 | spin_unlock_irqrestore(&bp->lock, flags); |
@@ -1015,7 +900,7 @@ static void turn_ints_on(struct specialix_board *bp) | |||
1015 | 900 | ||
1016 | 901 | ||
1017 | /* Called with disabled interrupts */ | 902 | /* Called with disabled interrupts */ |
1018 | static inline int sx_setup_board(struct specialix_board *bp) | 903 | static int sx_setup_board(struct specialix_board *bp) |
1019 | { | 904 | { |
1020 | int error; | 905 | int error; |
1021 | 906 | ||
@@ -1040,7 +925,7 @@ static inline int sx_setup_board(struct specialix_board *bp) | |||
1040 | 925 | ||
1041 | 926 | ||
1042 | /* Called with disabled interrupts */ | 927 | /* Called with disabled interrupts */ |
1043 | static inline void sx_shutdown_board(struct specialix_board *bp) | 928 | static void sx_shutdown_board(struct specialix_board *bp) |
1044 | { | 929 | { |
1045 | func_enter(); | 930 | func_enter(); |
1046 | 931 | ||
@@ -1058,6 +943,12 @@ static inline void sx_shutdown_board(struct specialix_board *bp) | |||
1058 | func_exit(); | 943 | func_exit(); |
1059 | } | 944 | } |
1060 | 945 | ||
946 | static unsigned int sx_crtscts(struct tty_struct *tty) | ||
947 | { | ||
948 | if (sx_rtscts) | ||
949 | return C_CRTSCTS(tty); | ||
950 | return 1; | ||
951 | } | ||
1061 | 952 | ||
1062 | /* | 953 | /* |
1063 | * Setting up port characteristics. | 954 | * Setting up port characteristics. |
@@ -1090,7 +981,7 @@ static void sx_change_speed(struct specialix_board *bp, | |||
1090 | 981 | ||
1091 | /* The Specialix board doens't implement the RTS lines. | 982 | /* The Specialix board doens't implement the RTS lines. |
1092 | They are used to set the IRQ level. Don't touch them. */ | 983 | They are used to set the IRQ level. Don't touch them. */ |
1093 | if (SX_CRTSCTS(tty)) | 984 | if (sx_crtscts(tty)) |
1094 | port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS); | 985 | port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS); |
1095 | else | 986 | else |
1096 | port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS); | 987 | port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS); |
@@ -1108,7 +999,7 @@ static void sx_change_speed(struct specialix_board *bp, | |||
1108 | if (!baud) { | 999 | if (!baud) { |
1109 | /* Drop DTR & exit */ | 1000 | /* Drop DTR & exit */ |
1110 | dprintk(SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n"); | 1001 | dprintk(SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n"); |
1111 | if (!SX_CRTSCTS(tty)) { | 1002 | if (!sx_crtscts(tty)) { |
1112 | port->MSVR &= ~MSVR_DTR; | 1003 | port->MSVR &= ~MSVR_DTR; |
1113 | spin_lock_irqsave(&bp->lock, flags); | 1004 | spin_lock_irqsave(&bp->lock, flags); |
1114 | sx_out(bp, CD186x_MSVR, port->MSVR); | 1005 | sx_out(bp, CD186x_MSVR, port->MSVR); |
@@ -1118,7 +1009,7 @@ static void sx_change_speed(struct specialix_board *bp, | |||
1118 | return; | 1009 | return; |
1119 | } else { | 1010 | } else { |
1120 | /* Set DTR on */ | 1011 | /* Set DTR on */ |
1121 | if (!SX_CRTSCTS(tty)) | 1012 | if (!sx_crtscts(tty)) |
1122 | port->MSVR |= MSVR_DTR; | 1013 | port->MSVR |= MSVR_DTR; |
1123 | } | 1014 | } |
1124 | 1015 | ||
@@ -1448,7 +1339,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
1448 | spin_lock_irqsave(&bp->lock, flags); | 1339 | spin_lock_irqsave(&bp->lock, flags); |
1449 | sx_out(bp, CD186x_CAR, port_No(port)); | 1340 | sx_out(bp, CD186x_CAR, port_No(port)); |
1450 | CD = sx_in(bp, CD186x_MSVR) & MSVR_CD; | 1341 | CD = sx_in(bp, CD186x_MSVR) & MSVR_CD; |
1451 | if (SX_CRTSCTS(tty)) { | 1342 | if (sx_crtscts(tty)) { |
1452 | /* Activate RTS */ | 1343 | /* Activate RTS */ |
1453 | port->MSVR |= MSVR_DTR; /* WTF? */ | 1344 | port->MSVR |= MSVR_DTR; /* WTF? */ |
1454 | sx_out(bp, CD186x_MSVR, port->MSVR); | 1345 | sx_out(bp, CD186x_MSVR, port->MSVR); |
@@ -1600,7 +1491,7 @@ static void sx_close(struct tty_struct *tty, struct file *filp) | |||
1600 | } | 1491 | } |
1601 | 1492 | ||
1602 | bp = port_Board(port); | 1493 | bp = port_Board(port); |
1603 | if ((tty->count == 1) && (port->port.count != 1)) { | 1494 | if (tty->count == 1 && port->port.count != 1) { |
1604 | printk(KERN_ERR "sx%d: sx_close: bad port count;" | 1495 | printk(KERN_ERR "sx%d: sx_close: bad port count;" |
1605 | " tty->count is 1, port count is %d\n", | 1496 | " tty->count is 1, port count is %d\n", |
1606 | board_No(bp), port->port.count); | 1497 | board_No(bp), port->port.count); |
@@ -1868,17 +1759,15 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file) | |||
1868 | dprintk(SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n", | 1759 | dprintk(SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n", |
1869 | port_No(port), status, sx_in(bp, CD186x_CAR)); | 1760 | port_No(port), status, sx_in(bp, CD186x_CAR)); |
1870 | dprintk(SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port); | 1761 | dprintk(SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port); |
1871 | if (SX_CRTSCTS(port->port.tty)) { | 1762 | if (sx_crtscts(port->port.tty)) { |
1872 | result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */ | 1763 | result = TIOCM_DTR | TIOCM_DSR |
1873 | | ((status & MSVR_DTR) ? TIOCM_RTS : 0) | 1764 | | ((status & MSVR_DTR) ? TIOCM_RTS : 0) |
1874 | | ((status & MSVR_CD) ? TIOCM_CAR : 0) | 1765 | | ((status & MSVR_CD) ? TIOCM_CAR : 0) |
1875 | |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */ | ||
1876 | | ((status & MSVR_CTS) ? TIOCM_CTS : 0); | 1766 | | ((status & MSVR_CTS) ? TIOCM_CTS : 0); |
1877 | } else { | 1767 | } else { |
1878 | result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */ | 1768 | result = TIOCM_RTS | TIOCM_DSR |
1879 | | ((status & MSVR_DTR) ? TIOCM_DTR : 0) | 1769 | | ((status & MSVR_DTR) ? TIOCM_DTR : 0) |
1880 | | ((status & MSVR_CD) ? TIOCM_CAR : 0) | 1770 | | ((status & MSVR_CD) ? TIOCM_CAR : 0) |
1881 | |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */ | ||
1882 | | ((status & MSVR_CTS) ? TIOCM_CTS : 0); | 1771 | | ((status & MSVR_CTS) ? TIOCM_CTS : 0); |
1883 | } | 1772 | } |
1884 | 1773 | ||
@@ -1905,24 +1794,14 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file, | |||
1905 | bp = port_Board(port); | 1794 | bp = port_Board(port); |
1906 | 1795 | ||
1907 | spin_lock_irqsave(&port->lock, flags); | 1796 | spin_lock_irqsave(&port->lock, flags); |
1908 | /* if (set & TIOCM_RTS) | 1797 | if (sx_crtscts(port->port.tty)) { |
1909 | port->MSVR |= MSVR_RTS; */ | ||
1910 | /* if (set & TIOCM_DTR) | ||
1911 | port->MSVR |= MSVR_DTR; */ | ||
1912 | |||
1913 | if (SX_CRTSCTS(port->port.tty)) { | ||
1914 | if (set & TIOCM_RTS) | 1798 | if (set & TIOCM_RTS) |
1915 | port->MSVR |= MSVR_DTR; | 1799 | port->MSVR |= MSVR_DTR; |
1916 | } else { | 1800 | } else { |
1917 | if (set & TIOCM_DTR) | 1801 | if (set & TIOCM_DTR) |
1918 | port->MSVR |= MSVR_DTR; | 1802 | port->MSVR |= MSVR_DTR; |
1919 | } | 1803 | } |
1920 | 1804 | if (sx_crtscts(port->port.tty)) { | |
1921 | /* if (clear & TIOCM_RTS) | ||
1922 | port->MSVR &= ~MSVR_RTS; */ | ||
1923 | /* if (clear & TIOCM_DTR) | ||
1924 | port->MSVR &= ~MSVR_DTR; */ | ||
1925 | if (SX_CRTSCTS(port->port.tty)) { | ||
1926 | if (clear & TIOCM_RTS) | 1805 | if (clear & TIOCM_RTS) |
1927 | port->MSVR &= ~MSVR_DTR; | 1806 | port->MSVR &= ~MSVR_DTR; |
1928 | } else { | 1807 | } else { |
@@ -1939,7 +1818,7 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file, | |||
1939 | } | 1818 | } |
1940 | 1819 | ||
1941 | 1820 | ||
1942 | static inline void sx_send_break(struct specialix_port *port, | 1821 | static void sx_send_break(struct specialix_port *port, |
1943 | unsigned long length) | 1822 | unsigned long length) |
1944 | { | 1823 | { |
1945 | struct specialix_board *bp = port_Board(port); | 1824 | struct specialix_board *bp = port_Board(port); |
@@ -1967,7 +1846,7 @@ static inline void sx_send_break(struct specialix_port *port, | |||
1967 | } | 1846 | } |
1968 | 1847 | ||
1969 | 1848 | ||
1970 | static inline int sx_set_serial_info(struct specialix_port *port, | 1849 | static int sx_set_serial_info(struct specialix_port *port, |
1971 | struct serial_struct __user *newinfo) | 1850 | struct serial_struct __user *newinfo) |
1972 | { | 1851 | { |
1973 | struct serial_struct tmp; | 1852 | struct serial_struct tmp; |
@@ -2015,7 +1894,7 @@ static inline int sx_set_serial_info(struct specialix_port *port, | |||
2015 | } | 1894 | } |
2016 | 1895 | ||
2017 | 1896 | ||
2018 | static inline int sx_get_serial_info(struct specialix_port *port, | 1897 | static int sx_get_serial_info(struct specialix_port *port, |
2019 | struct serial_struct __user *retinfo) | 1898 | struct serial_struct __user *retinfo) |
2020 | { | 1899 | { |
2021 | struct serial_struct tmp; | 1900 | struct serial_struct tmp; |
@@ -2112,7 +1991,7 @@ static void sx_throttle(struct tty_struct *tty) | |||
2112 | bp = port_Board(port); | 1991 | bp = port_Board(port); |
2113 | 1992 | ||
2114 | /* Use DTR instead of RTS ! */ | 1993 | /* Use DTR instead of RTS ! */ |
2115 | if (SX_CRTSCTS(tty)) | 1994 | if (sx_crtscts(tty)) |
2116 | port->MSVR &= ~MSVR_DTR; | 1995 | port->MSVR &= ~MSVR_DTR; |
2117 | else { | 1996 | else { |
2118 | /* Auch!!! I think the system shouldn't call this then. */ | 1997 | /* Auch!!! I think the system shouldn't call this then. */ |
@@ -2158,7 +2037,7 @@ static void sx_unthrottle(struct tty_struct *tty) | |||
2158 | 2037 | ||
2159 | spin_lock_irqsave(&port->lock, flags); | 2038 | spin_lock_irqsave(&port->lock, flags); |
2160 | /* XXXX Use DTR INSTEAD???? */ | 2039 | /* XXXX Use DTR INSTEAD???? */ |
2161 | if (SX_CRTSCTS(tty)) | 2040 | if (sx_crtscts(tty)) |
2162 | port->MSVR |= MSVR_DTR; | 2041 | port->MSVR |= MSVR_DTR; |
2163 | /* Else clause: see remark in "sx_throttle"... */ | 2042 | /* Else clause: see remark in "sx_throttle"... */ |
2164 | spin_lock_irqsave(&bp->lock, flags); | 2043 | spin_lock_irqsave(&bp->lock, flags); |
@@ -2381,11 +2260,11 @@ static int __init specialix_init(void) | |||
2381 | 2260 | ||
2382 | printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n"); | 2261 | printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n"); |
2383 | printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n"); | 2262 | printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n"); |
2384 | #ifdef CONFIG_SPECIALIX_RTSCTS | 2263 | if (sx_rtscts) |
2385 | printk(KERN_INFO "sx: DTR/RTS pin is always RTS.\n"); | 2264 | printk(KERN_INFO |
2386 | #else | 2265 | "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n"); |
2387 | printk(KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n"); | 2266 | else |
2388 | #endif | 2267 | printk(KERN_INFO "sx: DTR/RTS pin is always RTS.\n"); |
2389 | 2268 | ||
2390 | for (i = 0; i < SX_NBOARD; i++) | 2269 | for (i = 0; i < SX_NBOARD; i++) |
2391 | spin_lock_init(&sx_board[i].lock); | 2270 | spin_lock_init(&sx_board[i].lock); |
@@ -2443,16 +2322,13 @@ static int __init specialix_init(void) | |||
2443 | } | 2322 | } |
2444 | 2323 | ||
2445 | static int iobase[SX_NBOARD] = {0,}; | 2324 | static int iobase[SX_NBOARD] = {0,}; |
2446 | 2325 | static int irq[SX_NBOARD] = {0,}; | |
2447 | static int irq [SX_NBOARD] = {0,}; | ||
2448 | 2326 | ||
2449 | module_param_array(iobase, int, NULL, 0); | 2327 | module_param_array(iobase, int, NULL, 0); |
2450 | module_param_array(irq, int, NULL, 0); | 2328 | module_param_array(irq, int, NULL, 0); |
2451 | module_param(sx_debug, int, 0); | 2329 | module_param(sx_debug, int, 0); |
2330 | module_param(sx_rtscts, int, 0); | ||
2452 | module_param(sx_rxfifo, int, 0); | 2331 | module_param(sx_rxfifo, int, 0); |
2453 | #ifdef SPECIALIX_TIMER | ||
2454 | module_param(sx_poll, int, 0); | ||
2455 | #endif | ||
2456 | 2332 | ||
2457 | /* | 2333 | /* |
2458 | * You can setup up to 4 boards. | 2334 | * You can setup up to 4 boards. |
@@ -2492,10 +2368,6 @@ static void __exit specialix_exit_module(void) | |||
2492 | for (i = 0; i < SX_NBOARD; i++) | 2368 | for (i = 0; i < SX_NBOARD; i++) |
2493 | if (sx_board[i].flags & SX_BOARD_PRESENT) | 2369 | if (sx_board[i].flags & SX_BOARD_PRESENT) |
2494 | sx_release_io_range(&sx_board[i]); | 2370 | sx_release_io_range(&sx_board[i]); |
2495 | #ifdef SPECIALIX_TIMER | ||
2496 | del_timer_sync(&missed_irq_timer); | ||
2497 | #endif | ||
2498 | |||
2499 | func_exit(); | 2371 | func_exit(); |
2500 | } | 2372 | } |
2501 | 2373 | ||