[SLIP]: trivial sparse warning fix
[pohmelfs.git] / drivers / char / specialix.c
blob455855631aeff70f441e26be40f3a745a4cb5609
1 /*
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)
10 * first.
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,
35 * USA.
37 * Revision history:
39 * Revision 1.0: April 1st 1997.
40 * Initial release for alpha testing.
41 * Revision 1.1: April 14th 1997.
42 * Incorporated Richard Hudsons suggestions,
43 * removed some debugging printk's.
44 * Revision 1.2: April 15th 1997.
45 * Ported to 2.1.x kernels.
46 * Revision 1.3: April 17th 1997
47 * Backported to 2.0. (Compatibility macros).
48 * Revision 1.4: April 18th 1997
49 * Fixed DTR/RTS bug that caused the card to indicate
50 * "don't send data" to a modem after the password prompt.
51 * Fixed bug for premature (fake) interrupts.
52 * Revision 1.5: April 19th 1997
53 * fixed a minor typo in the header file, cleanup a little.
54 * performance warnings are now MAXed at once per minute.
55 * Revision 1.6: May 23 1997
56 * Changed the specialix=... format to include interrupt.
57 * Revision 1.7: May 27 1997
58 * Made many more debug printk's a compile time option.
59 * Revision 1.8: Jul 1 1997
60 * port to linux-2.1.43 kernel.
61 * Revision 1.9: Oct 9 1998
62 * Added stuff for the IO8+/PCI version.
63 * Revision 1.10: Oct 22 1999 / Jan 21 2000.
64 * Added stuff for setserial.
65 * Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr)
69 #define VERSION "1.11"
73 * There is a bunch of documentation about the card, jumpers, config
74 * settings, restrictions, cables, device names and numbers in
75 * Documentation/specialix.txt
78 #include <linux/module.h>
80 #include <asm/io.h>
81 #include <linux/kernel.h>
82 #include <linux/sched.h>
83 #include <linux/ioport.h>
84 #include <linux/interrupt.h>
85 #include <linux/errno.h>
86 #include <linux/tty.h>
87 #include <linux/tty_flip.h>
88 #include <linux/mm.h>
89 #include <linux/serial.h>
90 #include <linux/fcntl.h>
91 #include <linux/major.h>
92 #include <linux/delay.h>
93 #include <linux/pci.h>
94 #include <linux/init.h>
95 #include <asm/uaccess.h>
97 #include "specialix_io8.h"
98 #include "cd1865.h"
102 This driver can spew a whole lot of debugging output at you. If you
103 need maximum performance, you should disable the DEBUG define. To
104 aid in debugging in the field, I'm leaving the compile-time debug
105 features enabled, and disable them "runtime". That allows me to
106 instruct people with problems to enable debugging without requiring
107 them to recompile...
109 #define DEBUG
111 static int sx_debug;
112 static int sx_rxfifo = SPECIALIX_RXFIFO;
114 #ifdef DEBUG
115 #define dprintk(f, str...) if (sx_debug & f) printk (str)
116 #else
117 #define dprintk(f, str...) /* nothing */
118 #endif
120 #define SX_DEBUG_FLOW 0x0001
121 #define SX_DEBUG_DATA 0x0002
122 #define SX_DEBUG_PROBE 0x0004
123 #define SX_DEBUG_CHAN 0x0008
124 #define SX_DEBUG_INIT 0x0010
125 #define SX_DEBUG_RX 0x0020
126 #define SX_DEBUG_TX 0x0040
127 #define SX_DEBUG_IRQ 0x0080
128 #define SX_DEBUG_OPEN 0x0100
129 #define SX_DEBUG_TERMIOS 0x0200
130 #define SX_DEBUG_SIGNALS 0x0400
131 #define SX_DEBUG_FIFO 0x0800
134 #define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__FUNCTION__)
135 #define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __FUNCTION__)
137 #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
140 /* Configurable options: */
142 /* Am I paranoid or not ? ;-) */
143 #define SPECIALIX_PARANOIA_CHECK
145 /* Do I trust the IRQ from the card? (enabeling it doesn't seem to help)
146 When the IRQ routine leaves the chip in a state that is keeps on
147 requiring attention, the timer doesn't help either. */
148 #undef SPECIALIX_TIMER
150 #ifdef SPECIALIX_TIMER
151 static int sx_poll = HZ;
152 #endif
157 * The following defines are mostly for testing purposes. But if you need
158 * some nice reporting in your syslog, you can define them also.
160 #undef SX_REPORT_FIFO
161 #undef SX_REPORT_OVERRUN
165 #ifdef CONFIG_SPECIALIX_RTSCTS
166 #define SX_CRTSCTS(bla) 1
167 #else
168 #define SX_CRTSCTS(tty) C_CRTSCTS(tty)
169 #endif
172 /* Used to be outb (0xff, 0x80); */
173 #define short_pause() udelay (1)
176 #define SPECIALIX_LEGAL_FLAGS \
177 (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \
178 ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \
179 ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
181 #undef RS_EVENT_WRITE_WAKEUP
182 #define RS_EVENT_WRITE_WAKEUP 0
184 static struct tty_driver *specialix_driver;
186 static struct specialix_board sx_board[SX_NBOARD] = {
187 { 0, SX_IOBASE1, 9, },
188 { 0, SX_IOBASE2, 11, },
189 { 0, SX_IOBASE3, 12, },
190 { 0, SX_IOBASE4, 15, },
193 static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
196 #ifdef SPECIALIX_TIMER
197 static struct timer_list missed_irq_timer;
198 static irqreturn_t sx_interrupt(int irq, void * dev_id);
199 #endif
203 static inline int sx_paranoia_check(struct specialix_port const * port,
204 char *name, const char *routine)
206 #ifdef SPECIALIX_PARANOIA_CHECK
207 static const char *badmagic =
208 KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
209 static const char *badinfo =
210 KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
212 if (!port) {
213 printk(badinfo, name, routine);
214 return 1;
216 if (port->magic != SPECIALIX_MAGIC) {
217 printk(badmagic, name, routine);
218 return 1;
220 #endif
221 return 0;
227 * Service functions for specialix IO8+ driver.
231 /* Get board number from pointer */
232 static inline int board_No (struct specialix_board * bp)
234 return bp - sx_board;
238 /* Get port number from pointer */
239 static inline int port_No (struct specialix_port const * port)
241 return SX_PORT(port - sx_port);
245 /* Get pointer to board from pointer to port */
246 static inline struct specialix_board * port_Board(struct specialix_port const * port)
248 return &sx_board[SX_BOARD(port - sx_port)];
252 /* Input Byte from CL CD186x register */
253 static inline unsigned char sx_in(struct specialix_board * bp, unsigned short reg)
255 bp->reg = reg | 0x80;
256 outb (reg | 0x80, bp->base + SX_ADDR_REG);
257 return inb (bp->base + SX_DATA_REG);
261 /* Output Byte to CL CD186x register */
262 static inline void sx_out(struct specialix_board * bp, unsigned short reg,
263 unsigned char val)
265 bp->reg = reg | 0x80;
266 outb (reg | 0x80, bp->base + SX_ADDR_REG);
267 outb (val, bp->base + SX_DATA_REG);
271 /* Input Byte from CL CD186x register */
272 static inline unsigned char sx_in_off(struct specialix_board * bp, unsigned short reg)
274 bp->reg = reg;
275 outb (reg, bp->base + SX_ADDR_REG);
276 return inb (bp->base + SX_DATA_REG);
280 /* Output Byte to CL CD186x register */
281 static inline void sx_out_off(struct specialix_board * bp, unsigned short reg,
282 unsigned char val)
284 bp->reg = reg;
285 outb (reg, bp->base + SX_ADDR_REG);
286 outb (val, bp->base + SX_DATA_REG);
290 /* Wait for Channel Command Register ready */
291 static inline void sx_wait_CCR(struct specialix_board * bp)
293 unsigned long delay, flags;
294 unsigned char ccr;
296 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
297 spin_lock_irqsave(&bp->lock, flags);
298 ccr = sx_in(bp, CD186x_CCR);
299 spin_unlock_irqrestore(&bp->lock, flags);
300 if (!ccr)
301 return;
302 udelay (1);
305 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
309 /* Wait for Channel Command Register ready */
310 static inline void sx_wait_CCR_off(struct specialix_board * bp)
312 unsigned long delay;
313 unsigned char crr;
314 unsigned long flags;
316 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
317 spin_lock_irqsave(&bp->lock, flags);
318 crr = sx_in_off(bp, CD186x_CCR);
319 spin_unlock_irqrestore(&bp->lock, flags);
320 if (!crr)
321 return;
322 udelay (1);
325 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
330 * specialix IO8+ IO range functions.
333 static inline int sx_request_io_range(struct specialix_board * bp)
335 return request_region(bp->base,
336 bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
337 "specialix IO8+") == NULL;
341 static inline void sx_release_io_range(struct specialix_board * bp)
343 release_region(bp->base,
344 bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
348 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
349 static int sx_set_irq ( struct specialix_board *bp)
351 int virq;
352 int i;
353 unsigned long flags;
355 if (bp->flags & SX_BOARD_IS_PCI)
356 return 1;
357 switch (bp->irq) {
358 /* In the same order as in the docs... */
359 case 15: virq = 0;break;
360 case 12: virq = 1;break;
361 case 11: virq = 2;break;
362 case 9: virq = 3;break;
363 default: printk (KERN_ERR "Speclialix: cannot set irq to %d.\n", bp->irq);
364 return 0;
366 spin_lock_irqsave(&bp->lock, flags);
367 for (i=0;i<2;i++) {
368 sx_out(bp, CD186x_CAR, i);
369 sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
371 spin_unlock_irqrestore(&bp->lock, flags);
372 return 1;
376 /* Reset and setup CD186x chip */
377 static int sx_init_CD186x(struct specialix_board * bp)
379 unsigned long flags;
380 int scaler;
381 int rv = 1;
383 func_enter();
384 sx_wait_CCR_off(bp); /* Wait for CCR ready */
385 spin_lock_irqsave(&bp->lock, flags);
386 sx_out_off(bp, CD186x_CCR, CCR_HARDRESET); /* Reset CD186x chip */
387 spin_unlock_irqrestore(&bp->lock, flags);
388 msleep(50); /* Delay 0.05 sec */
389 spin_lock_irqsave(&bp->lock, flags);
390 sx_out_off(bp, CD186x_GIVR, SX_ID); /* Set ID for this chip */
391 sx_out_off(bp, CD186x_GICR, 0); /* Clear all bits */
392 sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT); /* Prio for modem intr */
393 sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */
394 sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
395 /* Set RegAckEn */
396 sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
398 /* Setting up prescaler. We need 4 ticks per 1 ms */
399 scaler = SX_OSCFREQ/SPECIALIX_TPS;
401 sx_out_off(bp, CD186x_PPRH, scaler >> 8);
402 sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
403 spin_unlock_irqrestore(&bp->lock, flags);
405 if (!sx_set_irq (bp)) {
406 /* Figure out how to pass this along... */
407 printk (KERN_ERR "Cannot set irq to %d.\n", bp->irq);
408 rv = 0;
411 func_exit();
412 return rv;
416 static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
418 int i;
419 int t;
420 unsigned long flags;
422 spin_lock_irqsave(&bp->lock, flags);
423 for (i=0, t=0;i<8;i++) {
424 sx_out_off (bp, CD186x_CAR, i);
425 if (sx_in_off (bp, reg) & bit)
426 t |= 1 << i;
428 spin_unlock_irqrestore(&bp->lock, flags);
430 return t;
434 #ifdef SPECIALIX_TIMER
435 void missed_irq (unsigned long data)
437 unsigned char irq;
438 unsigned long flags;
439 struct specialix_board *bp = (struct specialix_board *)data;
441 spin_lock_irqsave(&bp->lock, flags);
442 irq = sx_in ((struct specialix_board *)data, CD186x_SRSR) &
443 (SRSR_RREQint |
444 SRSR_TREQint |
445 SRSR_MREQint);
446 spin_unlock_irqrestore(&bp->lock, flags);
447 if (irq) {
448 printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
449 sx_interrupt (((struct specialix_board *)data)->irq,
450 (void*)data);
452 mod_timer(&missed_irq_timer, jiffies + sx_poll);
454 #endif
458 /* Main probing routine, also sets irq. */
459 static int sx_probe(struct specialix_board *bp)
461 unsigned char val1, val2;
462 #if 0
463 int irqs = 0;
464 int retries;
465 #endif
466 int rev;
467 int chip;
469 func_enter();
471 if (sx_request_io_range(bp)) {
472 func_exit();
473 return 1;
476 /* Are the I/O ports here ? */
477 sx_out_off(bp, CD186x_PPRL, 0x5a);
478 short_pause ();
479 val1 = sx_in_off(bp, CD186x_PPRL);
481 sx_out_off(bp, CD186x_PPRL, 0xa5);
482 short_pause ();
483 val2 = sx_in_off(bp, CD186x_PPRL);
486 if ((val1 != 0x5a) || (val2 != 0xa5)) {
487 printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
488 board_No(bp), bp->base);
489 sx_release_io_range(bp);
490 func_exit();
491 return 1;
494 /* Check the DSR lines that Specialix uses as board
495 identification */
496 val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
497 val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
498 dprintk (SX_DEBUG_INIT, "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
499 board_No(bp), val1, val2);
501 /* They managed to switch the bit order between the docs and
502 the IO8+ card. The new PCI card now conforms to old docs.
503 They changed the PCI docs to reflect the situation on the
504 old card. */
505 val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
506 if (val1 != val2) {
507 printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
508 board_No(bp), val2, bp->base, val1);
509 sx_release_io_range(bp);
510 func_exit();
511 return 1;
515 #if 0
516 /* It's time to find IRQ for this board */
517 for (retries = 0; retries < 5 && irqs <= 0; retries++) {
518 irqs = probe_irq_on();
519 sx_init_CD186x(bp); /* Reset CD186x chip */
520 sx_out(bp, CD186x_CAR, 2); /* Select port 2 */
521 sx_wait_CCR(bp);
522 sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */
523 sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */
524 msleep(50);
525 irqs = probe_irq_off(irqs);
527 dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
528 dprintk (SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR));
529 dprintk (SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR));
530 dprintk (SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR));
531 dprintk (SX_DEBUG_INIT, "\n");
533 /* Reset CD186x again */
534 if (!sx_init_CD186x(bp)) {
535 /* Hmmm. This is dead code anyway. */
538 dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
539 val1, val2, val3);
543 #if 0
544 if (irqs <= 0) {
545 printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
546 board_No(bp), bp->base);
547 sx_release_io_range(bp);
548 func_exit();
549 return 1;
551 #endif
552 printk (KERN_INFO "Started with irq=%d, but now have irq=%d.\n", bp->irq, irqs);
553 if (irqs > 0)
554 bp->irq = irqs;
555 #endif
556 /* Reset CD186x again */
557 if (!sx_init_CD186x(bp)) {
558 sx_release_io_range(bp);
559 func_exit();
560 return 1;
563 sx_request_io_range(bp);
564 bp->flags |= SX_BOARD_PRESENT;
566 /* Chip revcode pkgtype
567 GFRCR SRCR bit 7
568 CD180 rev B 0x81 0
569 CD180 rev C 0x82 0
570 CD1864 rev A 0x82 1
571 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
572 CD1865 rev B 0x84 1
573 -- Thanks to Gwen Wang, Cirrus Logic.
576 switch (sx_in_off(bp, CD186x_GFRCR)) {
577 case 0x82:chip = 1864;rev='A';break;
578 case 0x83:chip = 1865;rev='A';break;
579 case 0x84:chip = 1865;rev='B';break;
580 case 0x85:chip = 1865;rev='C';break; /* Does not exist at this time */
581 default:chip=-1;rev='x';
584 dprintk (SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR) );
586 #ifdef SPECIALIX_TIMER
587 setup_timer(&missed_irq_timer, missed_irq, (unsigned long)bp);
588 mod_timer(&missed_irq_timer, jiffies + sx_poll);
589 #endif
591 printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
592 board_No(bp),
593 bp->base, bp->irq,
594 chip, rev);
596 func_exit();
597 return 0;
602 * Interrupt processing routines.
603 * */
605 static inline void sx_mark_event(struct specialix_port * port, int event)
607 func_enter();
609 set_bit(event, &port->event);
610 schedule_work(&port->tqueue);
612 func_exit();
616 static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
617 unsigned char const * what)
619 unsigned char channel;
620 struct specialix_port * port = NULL;
622 channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
623 dprintk (SX_DEBUG_CHAN, "channel: %d\n", channel);
624 if (channel < CD186x_NCH) {
625 port = &sx_port[board_No(bp) * SX_NPORT + channel];
626 dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%x\n",board_No(bp) * SX_NPORT + channel, port, port->flags & ASYNC_INITIALIZED);
628 if (port->flags & ASYNC_INITIALIZED) {
629 dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
630 func_exit();
631 return port;
634 printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
635 board_No(bp), what, channel);
636 return NULL;
640 static inline void sx_receive_exc(struct specialix_board * bp)
642 struct specialix_port *port;
643 struct tty_struct *tty;
644 unsigned char status;
645 unsigned char ch, flag;
647 func_enter();
649 port = sx_get_port(bp, "Receive");
650 if (!port) {
651 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
652 func_exit();
653 return;
655 tty = port->tty;
657 status = sx_in(bp, CD186x_RCSR);
659 dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
660 if (status & RCSR_OE) {
661 port->overrun++;
662 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Overrun. Total %ld overruns.\n",
663 board_No(bp), port_No(port), port->overrun);
665 status &= port->mark_mask;
667 /* This flip buffer check needs to be below the reading of the
668 status register to reset the chip's IRQ.... */
669 if (tty_buffer_request_room(tty, 1) == 0) {
670 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n",
671 board_No(bp), port_No(port));
672 func_exit();
673 return;
676 ch = sx_in(bp, CD186x_RDR);
677 if (!status) {
678 func_exit();
679 return;
681 if (status & RCSR_TOUT) {
682 printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
683 board_No(bp), port_No(port));
684 func_exit();
685 return;
687 } else if (status & RCSR_BREAK) {
688 dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
689 board_No(bp), port_No(port));
690 flag = TTY_BREAK;
691 if (port->flags & ASYNC_SAK)
692 do_SAK(tty);
694 } else if (status & RCSR_PE)
695 flag = TTY_PARITY;
697 else if (status & RCSR_FE)
698 flag = TTY_FRAME;
700 else if (status & RCSR_OE)
701 flag = TTY_OVERRUN;
703 else
704 flag = TTY_NORMAL;
706 if(tty_insert_flip_char(tty, ch, flag))
707 tty_flip_buffer_push(tty);
708 func_exit();
712 static inline void sx_receive(struct specialix_board * bp)
714 struct specialix_port *port;
715 struct tty_struct *tty;
716 unsigned char count;
718 func_enter();
720 if (!(port = sx_get_port(bp, "Receive"))) {
721 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
722 func_exit();
723 return;
725 tty = port->tty;
727 count = sx_in(bp, CD186x_RDCR);
728 dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
729 port->hits[count > 8 ? 9 : count]++;
731 tty_buffer_request_room(tty, count);
733 while (count--)
734 tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL);
735 tty_flip_buffer_push(tty);
736 func_exit();
740 static inline void sx_transmit(struct specialix_board * bp)
742 struct specialix_port *port;
743 struct tty_struct *tty;
744 unsigned char count;
746 func_enter();
747 if (!(port = sx_get_port(bp, "Transmit"))) {
748 func_exit();
749 return;
751 dprintk (SX_DEBUG_TX, "port: %p\n", port);
752 tty = port->tty;
754 if (port->IER & IER_TXEMPTY) {
755 /* FIFO drained */
756 sx_out(bp, CD186x_CAR, port_No(port));
757 port->IER &= ~IER_TXEMPTY;
758 sx_out(bp, CD186x_IER, port->IER);
759 func_exit();
760 return;
763 if ((port->xmit_cnt <= 0 && !port->break_length)
764 || tty->stopped || tty->hw_stopped) {
765 sx_out(bp, CD186x_CAR, port_No(port));
766 port->IER &= ~IER_TXRDY;
767 sx_out(bp, CD186x_IER, port->IER);
768 func_exit();
769 return;
772 if (port->break_length) {
773 if (port->break_length > 0) {
774 if (port->COR2 & COR2_ETC) {
775 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
776 sx_out(bp, CD186x_TDR, CD186x_C_SBRK);
777 port->COR2 &= ~COR2_ETC;
779 count = min_t(int, port->break_length, 0xff);
780 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
781 sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
782 sx_out(bp, CD186x_TDR, count);
783 if (!(port->break_length -= count))
784 port->break_length--;
785 } else {
786 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
787 sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
788 sx_out(bp, CD186x_COR2, port->COR2);
789 sx_wait_CCR(bp);
790 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
791 port->break_length = 0;
794 func_exit();
795 return;
798 count = CD186x_NFIFO;
799 do {
800 sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
801 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
802 if (--port->xmit_cnt <= 0)
803 break;
804 } while (--count > 0);
806 if (port->xmit_cnt <= 0) {
807 sx_out(bp, CD186x_CAR, port_No(port));
808 port->IER &= ~IER_TXRDY;
809 sx_out(bp, CD186x_IER, port->IER);
811 if (port->xmit_cnt <= port->wakeup_chars)
812 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
814 func_exit();
818 static inline void sx_check_modem(struct specialix_board * bp)
820 struct specialix_port *port;
821 struct tty_struct *tty;
822 unsigned char mcr;
823 int msvr_cd;
825 dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
826 if (!(port = sx_get_port(bp, "Modem")))
827 return;
829 tty = port->tty;
831 mcr = sx_in(bp, CD186x_MCR);
832 printk ("mcr = %02x.\n", mcr);
834 if ((mcr & MCR_CDCHG)) {
835 dprintk (SX_DEBUG_SIGNALS, "CD just changed... ");
836 msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
837 if (msvr_cd) {
838 dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
839 wake_up_interruptible(&port->open_wait);
840 } else {
841 dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n");
842 schedule_work(&port->tqueue_hangup);
846 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
847 if (mcr & MCR_CTSCHG) {
848 if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
849 tty->hw_stopped = 0;
850 port->IER |= IER_TXRDY;
851 if (port->xmit_cnt <= port->wakeup_chars)
852 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
853 } else {
854 tty->hw_stopped = 1;
855 port->IER &= ~IER_TXRDY;
857 sx_out(bp, CD186x_IER, port->IER);
859 if (mcr & MCR_DSSXHG) {
860 if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
861 tty->hw_stopped = 0;
862 port->IER |= IER_TXRDY;
863 if (port->xmit_cnt <= port->wakeup_chars)
864 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
865 } else {
866 tty->hw_stopped = 1;
867 port->IER &= ~IER_TXRDY;
869 sx_out(bp, CD186x_IER, port->IER);
871 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
873 /* Clear change bits */
874 sx_out(bp, CD186x_MCR, 0);
878 /* The main interrupt processing routine */
879 static irqreturn_t sx_interrupt(int irq, void *dev_id)
881 unsigned char status;
882 unsigned char ack;
883 struct specialix_board *bp;
884 unsigned long loop = 0;
885 int saved_reg;
886 unsigned long flags;
888 func_enter();
890 bp = dev_id;
891 spin_lock_irqsave(&bp->lock, flags);
893 dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __FUNCTION__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
894 if (!(bp->flags & SX_BOARD_ACTIVE)) {
895 dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq);
896 spin_unlock_irqrestore(&bp->lock, flags);
897 func_exit();
898 return IRQ_NONE;
901 saved_reg = bp->reg;
903 while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
904 (SRSR_RREQint |
905 SRSR_TREQint |
906 SRSR_MREQint)))) {
907 if (status & SRSR_RREQint) {
908 ack = sx_in(bp, CD186x_RRAR);
910 if (ack == (SX_ID | GIVR_IT_RCV))
911 sx_receive(bp);
912 else if (ack == (SX_ID | GIVR_IT_REXC))
913 sx_receive_exc(bp);
914 else
915 printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
916 board_No(bp), status, ack);
918 } else if (status & SRSR_TREQint) {
919 ack = sx_in(bp, CD186x_TRAR);
921 if (ack == (SX_ID | GIVR_IT_TX))
922 sx_transmit(bp);
923 else
924 printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
925 board_No(bp), status, ack, port_No (sx_get_port (bp, "Int")));
926 } else if (status & SRSR_MREQint) {
927 ack = sx_in(bp, CD186x_MRAR);
929 if (ack == (SX_ID | GIVR_IT_MODEM))
930 sx_check_modem(bp);
931 else
932 printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
933 board_No(bp), status, ack);
937 sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
939 bp->reg = saved_reg;
940 outb (bp->reg, bp->base + SX_ADDR_REG);
941 spin_unlock_irqrestore(&bp->lock, flags);
942 func_exit();
943 return IRQ_HANDLED;
948 * Routines for open & close processing.
951 static void turn_ints_off (struct specialix_board *bp)
953 unsigned long flags;
955 func_enter();
956 if (bp->flags & SX_BOARD_IS_PCI) {
957 /* This was intended for enabeling the interrupt on the
958 * PCI card. However it seems that it's already enabled
959 * and as PCI interrupts can be shared, there is no real
960 * reason to have to turn it off. */
963 spin_lock_irqsave(&bp->lock, flags);
964 (void) sx_in_off (bp, 0); /* Turn off interrupts. */
965 spin_unlock_irqrestore(&bp->lock, flags);
967 func_exit();
970 static void turn_ints_on (struct specialix_board *bp)
972 unsigned long flags;
974 func_enter();
976 if (bp->flags & SX_BOARD_IS_PCI) {
977 /* play with the PCI chip. See comment above. */
979 spin_lock_irqsave(&bp->lock, flags);
980 (void) sx_in (bp, 0); /* Turn ON interrupts. */
981 spin_unlock_irqrestore(&bp->lock, flags);
983 func_exit();
987 /* Called with disabled interrupts */
988 static inline int sx_setup_board(struct specialix_board * bp)
990 int error;
992 if (bp->flags & SX_BOARD_ACTIVE)
993 return 0;
995 if (bp->flags & SX_BOARD_IS_PCI)
996 error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp);
997 else
998 error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED, "specialix IO8+", bp);
1000 if (error)
1001 return error;
1003 turn_ints_on (bp);
1004 bp->flags |= SX_BOARD_ACTIVE;
1006 return 0;
1010 /* Called with disabled interrupts */
1011 static inline void sx_shutdown_board(struct specialix_board *bp)
1013 func_enter();
1015 if (!(bp->flags & SX_BOARD_ACTIVE)) {
1016 func_exit();
1017 return;
1020 bp->flags &= ~SX_BOARD_ACTIVE;
1022 dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
1023 bp->irq, board_No (bp));
1024 free_irq(bp->irq, bp);
1026 turn_ints_off (bp);
1029 func_exit();
1034 * Setting up port characteristics.
1035 * Must be called with disabled interrupts
1037 static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
1039 struct tty_struct *tty;
1040 unsigned long baud;
1041 long tmp;
1042 unsigned char cor1 = 0, cor3 = 0;
1043 unsigned char mcor1 = 0, mcor2 = 0;
1044 static unsigned long again;
1045 unsigned long flags;
1047 func_enter();
1049 if (!(tty = port->tty) || !tty->termios) {
1050 func_exit();
1051 return;
1054 port->IER = 0;
1055 port->COR2 = 0;
1056 /* Select port on the board */
1057 spin_lock_irqsave(&bp->lock, flags);
1058 sx_out(bp, CD186x_CAR, port_No(port));
1060 /* The Specialix board doens't implement the RTS lines.
1061 They are used to set the IRQ level. Don't touch them. */
1062 if (SX_CRTSCTS(tty))
1063 port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1064 else
1065 port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1066 spin_unlock_irqrestore(&bp->lock, flags);
1067 dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
1068 baud = tty_get_baud_rate(tty);
1070 if (baud == 38400) {
1071 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1072 baud = 57600;
1073 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1074 baud = 115200;
1077 if (!baud) {
1078 /* Drop DTR & exit */
1079 dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
1080 if (!SX_CRTSCTS (tty)) {
1081 port -> MSVR &= ~ MSVR_DTR;
1082 spin_lock_irqsave(&bp->lock, flags);
1083 sx_out(bp, CD186x_MSVR, port->MSVR );
1084 spin_unlock_irqrestore(&bp->lock, flags);
1086 else
1087 dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1088 return;
1089 } else {
1090 /* Set DTR on */
1091 if (!SX_CRTSCTS (tty)) {
1092 port ->MSVR |= MSVR_DTR;
1097 * Now we must calculate some speed depended things
1100 /* Set baud rate for port */
1101 tmp = port->custom_divisor ;
1102 if ( tmp )
1103 printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n"
1104 "This is an untested option, please be carefull.\n",
1105 port_No (port), tmp);
1106 else
1107 tmp = (((SX_OSCFREQ + baud/2) / baud +
1108 CD186x_TPC/2) / CD186x_TPC);
1110 if ((tmp < 0x10) && time_before(again, jiffies)) {
1111 again = jiffies + HZ * 60;
1112 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1113 if (tmp >= 12) {
1114 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1115 "Performance degradation is possible.\n"
1116 "Read specialix.txt for more info.\n",
1117 port_No (port), tmp);
1118 } else {
1119 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1120 "Warning: overstressing Cirrus chip. "
1121 "This might not work.\n"
1122 "Read specialix.txt for more info.\n",
1123 port_No (port), tmp);
1126 spin_lock_irqsave(&bp->lock, flags);
1127 sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1128 sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1129 sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1130 sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1131 spin_unlock_irqrestore(&bp->lock, flags);
1132 if (port->custom_divisor)
1133 baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
1134 baud = (baud + 5) / 10; /* Estimated CPS */
1136 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1137 tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1138 port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1139 SERIAL_XMIT_SIZE - 1 : tmp);
1141 /* Receiver timeout will be transmission time for 1.5 chars */
1142 tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1143 tmp = (tmp > 0xff) ? 0xff : tmp;
1144 spin_lock_irqsave(&bp->lock, flags);
1145 sx_out(bp, CD186x_RTPR, tmp);
1146 spin_unlock_irqrestore(&bp->lock, flags);
1147 switch (C_CSIZE(tty)) {
1148 case CS5:
1149 cor1 |= COR1_5BITS;
1150 break;
1151 case CS6:
1152 cor1 |= COR1_6BITS;
1153 break;
1154 case CS7:
1155 cor1 |= COR1_7BITS;
1156 break;
1157 case CS8:
1158 cor1 |= COR1_8BITS;
1159 break;
1162 if (C_CSTOPB(tty))
1163 cor1 |= COR1_2SB;
1165 cor1 |= COR1_IGNORE;
1166 if (C_PARENB(tty)) {
1167 cor1 |= COR1_NORMPAR;
1168 if (C_PARODD(tty))
1169 cor1 |= COR1_ODDP;
1170 if (I_INPCK(tty))
1171 cor1 &= ~COR1_IGNORE;
1173 /* Set marking of some errors */
1174 port->mark_mask = RCSR_OE | RCSR_TOUT;
1175 if (I_INPCK(tty))
1176 port->mark_mask |= RCSR_FE | RCSR_PE;
1177 if (I_BRKINT(tty) || I_PARMRK(tty))
1178 port->mark_mask |= RCSR_BREAK;
1179 if (I_IGNPAR(tty))
1180 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1181 if (I_IGNBRK(tty)) {
1182 port->mark_mask &= ~RCSR_BREAK;
1183 if (I_IGNPAR(tty))
1184 /* Real raw mode. Ignore all */
1185 port->mark_mask &= ~RCSR_OE;
1187 /* Enable Hardware Flow Control */
1188 if (C_CRTSCTS(tty)) {
1189 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1190 port->IER |= IER_DSR | IER_CTS;
1191 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1192 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1193 spin_lock_irqsave(&bp->lock, flags);
1194 tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
1195 spin_unlock_irqrestore(&bp->lock, flags);
1196 #else
1197 port->COR2 |= COR2_CTSAE;
1198 #endif
1200 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1201 /* Some people reported that it works, but I still doubt it */
1202 if (I_IXON(tty)) {
1203 port->COR2 |= COR2_TXIBE;
1204 cor3 |= (COR3_FCT | COR3_SCDE);
1205 if (I_IXANY(tty))
1206 port->COR2 |= COR2_IXM;
1207 spin_lock_irqsave(&bp->lock, flags);
1208 sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1209 sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1210 sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1211 sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1212 spin_unlock_irqrestore(&bp->lock, flags);
1214 if (!C_CLOCAL(tty)) {
1215 /* Enable CD check */
1216 port->IER |= IER_CD;
1217 mcor1 |= MCOR1_CDZD;
1218 mcor2 |= MCOR2_CDOD;
1221 if (C_CREAD(tty))
1222 /* Enable receiver */
1223 port->IER |= IER_RXD;
1225 /* Set input FIFO size (1-8 bytes) */
1226 cor3 |= sx_rxfifo;
1227 /* Setting up CD186x channel registers */
1228 spin_lock_irqsave(&bp->lock, flags);
1229 sx_out(bp, CD186x_COR1, cor1);
1230 sx_out(bp, CD186x_COR2, port->COR2);
1231 sx_out(bp, CD186x_COR3, cor3);
1232 spin_unlock_irqrestore(&bp->lock, flags);
1233 /* Make CD186x know about registers change */
1234 sx_wait_CCR(bp);
1235 spin_lock_irqsave(&bp->lock, flags);
1236 sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1237 /* Setting up modem option registers */
1238 dprintk (SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2);
1239 sx_out(bp, CD186x_MCOR1, mcor1);
1240 sx_out(bp, CD186x_MCOR2, mcor2);
1241 spin_unlock_irqrestore(&bp->lock, flags);
1242 /* Enable CD186x transmitter & receiver */
1243 sx_wait_CCR(bp);
1244 spin_lock_irqsave(&bp->lock, flags);
1245 sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1246 /* Enable interrupts */
1247 sx_out(bp, CD186x_IER, port->IER);
1248 /* And finally set the modem lines... */
1249 sx_out(bp, CD186x_MSVR, port->MSVR);
1250 spin_unlock_irqrestore(&bp->lock, flags);
1252 func_exit();
1256 /* Must be called with interrupts enabled */
1257 static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port)
1259 unsigned long flags;
1261 func_enter();
1263 if (port->flags & ASYNC_INITIALIZED) {
1264 func_exit();
1265 return 0;
1268 if (!port->xmit_buf) {
1269 /* We may sleep in get_zeroed_page() */
1270 unsigned long tmp;
1272 if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
1273 func_exit();
1274 return -ENOMEM;
1277 if (port->xmit_buf) {
1278 free_page(tmp);
1279 func_exit();
1280 return -ERESTARTSYS;
1282 port->xmit_buf = (unsigned char *) tmp;
1285 spin_lock_irqsave(&port->lock, flags);
1287 if (port->tty)
1288 clear_bit(TTY_IO_ERROR, &port->tty->flags);
1290 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1291 sx_change_speed(bp, port);
1292 port->flags |= ASYNC_INITIALIZED;
1294 spin_unlock_irqrestore(&port->lock, flags);
1297 func_exit();
1298 return 0;
1302 /* Must be called with interrupts disabled */
1303 static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port)
1305 struct tty_struct *tty;
1306 int i;
1307 unsigned long flags;
1309 func_enter();
1311 if (!(port->flags & ASYNC_INITIALIZED)) {
1312 func_exit();
1313 return;
1316 if (sx_debug & SX_DEBUG_FIFO) {
1317 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
1318 board_No(bp), port_No(port), port->overrun);
1319 for (i = 0; i < 10; i++) {
1320 dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1322 dprintk(SX_DEBUG_FIFO, "].\n");
1325 if (port->xmit_buf) {
1326 free_page((unsigned long) port->xmit_buf);
1327 port->xmit_buf = NULL;
1330 /* Select port */
1331 spin_lock_irqsave(&bp->lock, flags);
1332 sx_out(bp, CD186x_CAR, port_No(port));
1334 if (!(tty = port->tty) || C_HUPCL(tty)) {
1335 /* Drop DTR */
1336 sx_out(bp, CD186x_MSVDTR, 0);
1338 spin_unlock_irqrestore(&bp->lock, flags);
1339 /* Reset port */
1340 sx_wait_CCR(bp);
1341 spin_lock_irqsave(&bp->lock, flags);
1342 sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1343 /* Disable all interrupts from this port */
1344 port->IER = 0;
1345 sx_out(bp, CD186x_IER, port->IER);
1346 spin_unlock_irqrestore(&bp->lock, flags);
1347 if (tty)
1348 set_bit(TTY_IO_ERROR, &tty->flags);
1349 port->flags &= ~ASYNC_INITIALIZED;
1351 if (!bp->count)
1352 sx_shutdown_board(bp);
1353 func_exit();
1357 static int block_til_ready(struct tty_struct *tty, struct file * filp,
1358 struct specialix_port *port)
1360 DECLARE_WAITQUEUE(wait, current);
1361 struct specialix_board *bp = port_Board(port);
1362 int retval;
1363 int do_clocal = 0;
1364 int CD;
1365 unsigned long flags;
1367 func_enter();
1370 * If the device is in the middle of being closed, then block
1371 * until it's done, and then try again.
1373 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
1374 interruptible_sleep_on(&port->close_wait);
1375 if (port->flags & ASYNC_HUP_NOTIFY) {
1376 func_exit();
1377 return -EAGAIN;
1378 } else {
1379 func_exit();
1380 return -ERESTARTSYS;
1385 * If non-blocking mode is set, or the port is not enabled,
1386 * then make the check up front and then exit.
1388 if ((filp->f_flags & O_NONBLOCK) ||
1389 (tty->flags & (1 << TTY_IO_ERROR))) {
1390 port->flags |= ASYNC_NORMAL_ACTIVE;
1391 func_exit();
1392 return 0;
1395 if (C_CLOCAL(tty))
1396 do_clocal = 1;
1399 * Block waiting for the carrier detect and the line to become
1400 * free (i.e., not in use by the callout). While we are in
1401 * this loop, info->count is dropped by one, so that
1402 * rs_close() knows when to free things. We restore it upon
1403 * exit, either normal or abnormal.
1405 retval = 0;
1406 add_wait_queue(&port->open_wait, &wait);
1407 spin_lock_irqsave(&port->lock, flags);
1408 if (!tty_hung_up_p(filp)) {
1409 port->count--;
1411 spin_unlock_irqrestore(&port->lock, flags);
1412 port->blocked_open++;
1413 while (1) {
1414 spin_lock_irqsave(&bp->lock, flags);
1415 sx_out(bp, CD186x_CAR, port_No(port));
1416 CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1417 if (SX_CRTSCTS (tty)) {
1418 /* Activate RTS */
1419 port->MSVR |= MSVR_DTR; /* WTF? */
1420 sx_out (bp, CD186x_MSVR, port->MSVR);
1421 } else {
1422 /* Activate DTR */
1423 port->MSVR |= MSVR_DTR;
1424 sx_out (bp, CD186x_MSVR, port->MSVR);
1426 spin_unlock_irqrestore(&bp->lock, flags);
1427 set_current_state(TASK_INTERRUPTIBLE);
1428 if (tty_hung_up_p(filp) ||
1429 !(port->flags & ASYNC_INITIALIZED)) {
1430 if (port->flags & ASYNC_HUP_NOTIFY)
1431 retval = -EAGAIN;
1432 else
1433 retval = -ERESTARTSYS;
1434 break;
1436 if (!(port->flags & ASYNC_CLOSING) &&
1437 (do_clocal || CD))
1438 break;
1439 if (signal_pending(current)) {
1440 retval = -ERESTARTSYS;
1441 break;
1443 schedule();
1446 set_current_state(TASK_RUNNING);
1447 remove_wait_queue(&port->open_wait, &wait);
1448 spin_lock_irqsave(&port->lock, flags);
1449 if (!tty_hung_up_p(filp)) {
1450 port->count++;
1452 port->blocked_open--;
1453 spin_unlock_irqrestore(&port->lock, flags);
1454 if (retval) {
1455 func_exit();
1456 return retval;
1459 port->flags |= ASYNC_NORMAL_ACTIVE;
1460 func_exit();
1461 return 0;
1465 static int sx_open(struct tty_struct * tty, struct file * filp)
1467 int board;
1468 int error;
1469 struct specialix_port * port;
1470 struct specialix_board * bp;
1471 int i;
1472 unsigned long flags;
1474 func_enter();
1476 board = SX_BOARD(tty->index);
1478 if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1479 func_exit();
1480 return -ENODEV;
1483 bp = &sx_board[board];
1484 port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1485 port->overrun = 0;
1486 for (i = 0; i < 10; i++)
1487 port->hits[i]=0;
1489 dprintk (SX_DEBUG_OPEN, "Board = %d, bp = %p, port = %p, portno = %d.\n",
1490 board, bp, port, SX_PORT(tty->index));
1492 if (sx_paranoia_check(port, tty->name, "sx_open")) {
1493 func_enter();
1494 return -ENODEV;
1497 if ((error = sx_setup_board(bp))) {
1498 func_exit();
1499 return error;
1502 spin_lock_irqsave(&bp->lock, flags);
1503 port->count++;
1504 bp->count++;
1505 tty->driver_data = port;
1506 port->tty = tty;
1507 spin_unlock_irqrestore(&bp->lock, flags);
1509 if ((error = sx_setup_port(bp, port))) {
1510 func_enter();
1511 return error;
1514 if ((error = block_til_ready(tty, filp, port))) {
1515 func_enter();
1516 return error;
1519 func_exit();
1520 return 0;
1524 static void sx_close(struct tty_struct * tty, struct file * filp)
1526 struct specialix_port *port = (struct specialix_port *) tty->driver_data;
1527 struct specialix_board *bp;
1528 unsigned long flags;
1529 unsigned long timeout;
1531 func_enter();
1532 if (!port || sx_paranoia_check(port, tty->name, "close")) {
1533 func_exit();
1534 return;
1536 spin_lock_irqsave(&port->lock, flags);
1538 if (tty_hung_up_p(filp)) {
1539 spin_unlock_irqrestore(&port->lock, flags);
1540 func_exit();
1541 return;
1544 bp = port_Board(port);
1545 if ((tty->count == 1) && (port->count != 1)) {
1546 printk(KERN_ERR "sx%d: sx_close: bad port count;"
1547 " tty->count is 1, port count is %d\n",
1548 board_No(bp), port->count);
1549 port->count = 1;
1552 if (port->count > 1) {
1553 port->count--;
1554 bp->count--;
1556 spin_unlock_irqrestore(&port->lock, flags);
1558 func_exit();
1559 return;
1561 port->flags |= ASYNC_CLOSING;
1563 * Now we wait for the transmit buffer to clear; and we notify
1564 * the line discipline to only process XON/XOFF characters.
1566 tty->closing = 1;
1567 spin_unlock_irqrestore(&port->lock, flags);
1568 dprintk (SX_DEBUG_OPEN, "Closing\n");
1569 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
1570 tty_wait_until_sent(tty, port->closing_wait);
1573 * At this point we stop accepting input. To do this, we
1574 * disable the receive line status interrupts, and tell the
1575 * interrupt driver to stop checking the data ready bit in the
1576 * line status register.
1578 dprintk (SX_DEBUG_OPEN, "Closed\n");
1579 port->IER &= ~IER_RXD;
1580 if (port->flags & ASYNC_INITIALIZED) {
1581 port->IER &= ~IER_TXRDY;
1582 port->IER |= IER_TXEMPTY;
1583 spin_lock_irqsave(&bp->lock, flags);
1584 sx_out(bp, CD186x_CAR, port_No(port));
1585 sx_out(bp, CD186x_IER, port->IER);
1586 spin_unlock_irqrestore(&bp->lock, flags);
1588 * Before we drop DTR, make sure the UART transmitter
1589 * has completely drained; this is especially
1590 * important if there is a transmit FIFO!
1592 timeout = jiffies+HZ;
1593 while(port->IER & IER_TXEMPTY) {
1594 set_current_state (TASK_INTERRUPTIBLE);
1595 msleep_interruptible(jiffies_to_msecs(port->timeout));
1596 if (time_after(jiffies, timeout)) {
1597 printk (KERN_INFO "Timeout waiting for close\n");
1598 break;
1604 if (--bp->count < 0) {
1605 printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1606 board_No(bp), bp->count, tty->index);
1607 bp->count = 0;
1609 if (--port->count < 0) {
1610 printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n",
1611 board_No(bp), port_No(port), port->count);
1612 port->count = 0;
1615 sx_shutdown_port(bp, port);
1616 if (tty->driver->flush_buffer)
1617 tty->driver->flush_buffer(tty);
1618 tty_ldisc_flush(tty);
1619 spin_lock_irqsave(&port->lock, flags);
1620 tty->closing = 0;
1621 port->event = 0;
1622 port->tty = NULL;
1623 spin_unlock_irqrestore(&port->lock, flags);
1624 if (port->blocked_open) {
1625 if (port->close_delay) {
1626 msleep_interruptible(jiffies_to_msecs(port->close_delay));
1628 wake_up_interruptible(&port->open_wait);
1630 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1631 wake_up_interruptible(&port->close_wait);
1633 func_exit();
1637 static int sx_write(struct tty_struct * tty,
1638 const unsigned char *buf, int count)
1640 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1641 struct specialix_board *bp;
1642 int c, total = 0;
1643 unsigned long flags;
1645 func_enter();
1646 if (sx_paranoia_check(port, tty->name, "sx_write")) {
1647 func_exit();
1648 return 0;
1651 bp = port_Board(port);
1653 if (!port->xmit_buf) {
1654 func_exit();
1655 return 0;
1658 while (1) {
1659 spin_lock_irqsave(&port->lock, flags);
1660 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1661 SERIAL_XMIT_SIZE - port->xmit_head));
1662 if (c <= 0) {
1663 spin_unlock_irqrestore(&port->lock, flags);
1664 break;
1666 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1667 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1668 port->xmit_cnt += c;
1669 spin_unlock_irqrestore(&port->lock, flags);
1671 buf += c;
1672 count -= c;
1673 total += c;
1676 spin_lock_irqsave(&bp->lock, flags);
1677 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1678 !(port->IER & IER_TXRDY)) {
1679 port->IER |= IER_TXRDY;
1680 sx_out(bp, CD186x_CAR, port_No(port));
1681 sx_out(bp, CD186x_IER, port->IER);
1683 spin_unlock_irqrestore(&bp->lock, flags);
1684 func_exit();
1686 return total;
1690 static void sx_put_char(struct tty_struct * tty, unsigned char ch)
1692 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1693 unsigned long flags;
1694 struct specialix_board * bp;
1696 func_enter();
1698 if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1699 func_exit();
1700 return;
1702 dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1703 if (!port->xmit_buf) {
1704 func_exit();
1705 return;
1707 bp = port_Board(port);
1708 spin_lock_irqsave(&port->lock, flags);
1710 dprintk (SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", port->xmit_cnt, port->xmit_buf);
1711 if ((port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) || (!port->xmit_buf)) {
1712 spin_unlock_irqrestore(&port->lock, flags);
1713 dprintk (SX_DEBUG_TX, "Exit size\n");
1714 func_exit();
1715 return;
1717 dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
1718 port->xmit_buf[port->xmit_head++] = ch;
1719 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1720 port->xmit_cnt++;
1721 spin_unlock_irqrestore(&port->lock, flags);
1723 func_exit();
1727 static void sx_flush_chars(struct tty_struct * tty)
1729 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1730 unsigned long flags;
1731 struct specialix_board * bp = port_Board(port);
1733 func_enter();
1735 if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1736 func_exit();
1737 return;
1739 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1740 !port->xmit_buf) {
1741 func_exit();
1742 return;
1744 spin_lock_irqsave(&bp->lock, flags);
1745 port->IER |= IER_TXRDY;
1746 sx_out(port_Board(port), CD186x_CAR, port_No(port));
1747 sx_out(port_Board(port), CD186x_IER, port->IER);
1748 spin_unlock_irqrestore(&bp->lock, flags);
1750 func_exit();
1754 static int sx_write_room(struct tty_struct * tty)
1756 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1757 int ret;
1759 func_enter();
1761 if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1762 func_exit();
1763 return 0;
1766 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1767 if (ret < 0)
1768 ret = 0;
1770 func_exit();
1771 return ret;
1775 static int sx_chars_in_buffer(struct tty_struct *tty)
1777 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1779 func_enter();
1781 if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
1782 func_exit();
1783 return 0;
1785 func_exit();
1786 return port->xmit_cnt;
1790 static void sx_flush_buffer(struct tty_struct *tty)
1792 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1793 unsigned long flags;
1794 struct specialix_board * bp;
1796 func_enter();
1798 if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
1799 func_exit();
1800 return;
1803 bp = port_Board(port);
1804 spin_lock_irqsave(&port->lock, flags);
1805 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1806 spin_unlock_irqrestore(&port->lock, flags);
1807 tty_wakeup(tty);
1809 func_exit();
1813 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1815 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1816 struct specialix_board * bp;
1817 unsigned char status;
1818 unsigned int result;
1819 unsigned long flags;
1821 func_enter();
1823 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1824 func_exit();
1825 return -ENODEV;
1828 bp = port_Board(port);
1829 spin_lock_irqsave (&bp->lock, flags);
1830 sx_out(bp, CD186x_CAR, port_No(port));
1831 status = sx_in(bp, CD186x_MSVR);
1832 spin_unlock_irqrestore(&bp->lock, flags);
1833 dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1834 port_No(port), status, sx_in (bp, CD186x_CAR));
1835 dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1836 if (SX_CRTSCTS(port->tty)) {
1837 result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
1838 | ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1839 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1840 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1841 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1842 } else {
1843 result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
1844 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1845 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1846 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1847 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1850 func_exit();
1852 return result;
1856 static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1857 unsigned int set, unsigned int clear)
1859 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1860 unsigned long flags;
1861 struct specialix_board *bp;
1863 func_enter();
1865 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1866 func_exit();
1867 return -ENODEV;
1870 bp = port_Board(port);
1872 spin_lock_irqsave(&port->lock, flags);
1873 /* if (set & TIOCM_RTS)
1874 port->MSVR |= MSVR_RTS; */
1875 /* if (set & TIOCM_DTR)
1876 port->MSVR |= MSVR_DTR; */
1878 if (SX_CRTSCTS(port->tty)) {
1879 if (set & TIOCM_RTS)
1880 port->MSVR |= MSVR_DTR;
1881 } else {
1882 if (set & TIOCM_DTR)
1883 port->MSVR |= MSVR_DTR;
1886 /* if (clear & TIOCM_RTS)
1887 port->MSVR &= ~MSVR_RTS; */
1888 /* if (clear & TIOCM_DTR)
1889 port->MSVR &= ~MSVR_DTR; */
1890 if (SX_CRTSCTS(port->tty)) {
1891 if (clear & TIOCM_RTS)
1892 port->MSVR &= ~MSVR_DTR;
1893 } else {
1894 if (clear & TIOCM_DTR)
1895 port->MSVR &= ~MSVR_DTR;
1897 spin_lock_irqsave(&bp->lock, flags);
1898 sx_out(bp, CD186x_CAR, port_No(port));
1899 sx_out(bp, CD186x_MSVR, port->MSVR);
1900 spin_unlock_irqrestore(&bp->lock, flags);
1901 spin_unlock_irqrestore(&port->lock, flags);
1902 func_exit();
1903 return 0;
1907 static inline void sx_send_break(struct specialix_port * port, unsigned long length)
1909 struct specialix_board *bp = port_Board(port);
1910 unsigned long flags;
1912 func_enter();
1914 spin_lock_irqsave (&port->lock, flags);
1915 port->break_length = SPECIALIX_TPS / HZ * length;
1916 port->COR2 |= COR2_ETC;
1917 port->IER |= IER_TXRDY;
1918 spin_lock_irqsave(&bp->lock, flags);
1919 sx_out(bp, CD186x_CAR, port_No(port));
1920 sx_out(bp, CD186x_COR2, port->COR2);
1921 sx_out(bp, CD186x_IER, port->IER);
1922 spin_unlock_irqrestore(&bp->lock, flags);
1923 spin_unlock_irqrestore (&port->lock, flags);
1924 sx_wait_CCR(bp);
1925 spin_lock_irqsave(&bp->lock, flags);
1926 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1927 spin_unlock_irqrestore(&bp->lock, flags);
1928 sx_wait_CCR(bp);
1930 func_exit();
1934 static inline int sx_set_serial_info(struct specialix_port * port,
1935 struct serial_struct __user * newinfo)
1937 struct serial_struct tmp;
1938 struct specialix_board *bp = port_Board(port);
1939 int change_speed;
1941 func_enter();
1943 if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1944 func_exit();
1945 return -EFAULT;
1948 if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
1949 func_enter();
1950 return -EFAULT;
1953 #if 0
1954 if ((tmp.irq != bp->irq) ||
1955 (tmp.port != bp->base) ||
1956 (tmp.type != PORT_CIRRUS) ||
1957 (tmp.baud_base != (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) ||
1958 (tmp.custom_divisor != 0) ||
1959 (tmp.xmit_fifo_size != CD186x_NFIFO) ||
1960 (tmp.flags & ~SPECIALIX_LEGAL_FLAGS)) {
1961 func_exit();
1962 return -EINVAL;
1964 #endif
1966 change_speed = ((port->flags & ASYNC_SPD_MASK) !=
1967 (tmp.flags & ASYNC_SPD_MASK));
1968 change_speed |= (tmp.custom_divisor != port->custom_divisor);
1970 if (!capable(CAP_SYS_ADMIN)) {
1971 if ((tmp.close_delay != port->close_delay) ||
1972 (tmp.closing_wait != port->closing_wait) ||
1973 ((tmp.flags & ~ASYNC_USR_MASK) !=
1974 (port->flags & ~ASYNC_USR_MASK))) {
1975 func_exit();
1976 return -EPERM;
1978 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
1979 (tmp.flags & ASYNC_USR_MASK));
1980 port->custom_divisor = tmp.custom_divisor;
1981 } else {
1982 port->flags = ((port->flags & ~ASYNC_FLAGS) |
1983 (tmp.flags & ASYNC_FLAGS));
1984 port->close_delay = tmp.close_delay;
1985 port->closing_wait = tmp.closing_wait;
1986 port->custom_divisor = tmp.custom_divisor;
1988 if (change_speed) {
1989 sx_change_speed(bp, port);
1991 func_exit();
1992 return 0;
1996 static inline int sx_get_serial_info(struct specialix_port * port,
1997 struct serial_struct __user *retinfo)
1999 struct serial_struct tmp;
2000 struct specialix_board *bp = port_Board(port);
2002 func_enter();
2005 if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
2006 return -EFAULT;
2009 memset(&tmp, 0, sizeof(tmp));
2010 tmp.type = PORT_CIRRUS;
2011 tmp.line = port - sx_port;
2012 tmp.port = bp->base;
2013 tmp.irq = bp->irq;
2014 tmp.flags = port->flags;
2015 tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
2016 tmp.close_delay = port->close_delay * HZ/100;
2017 tmp.closing_wait = port->closing_wait * HZ/100;
2018 tmp.custom_divisor = port->custom_divisor;
2019 tmp.xmit_fifo_size = CD186x_NFIFO;
2020 if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
2021 func_exit();
2022 return -EFAULT;
2025 func_exit();
2026 return 0;
2030 static int sx_ioctl(struct tty_struct * tty, struct file * filp,
2031 unsigned int cmd, unsigned long arg)
2033 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2034 int retval;
2035 void __user *argp = (void __user *)arg;
2037 func_enter();
2039 if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
2040 func_exit();
2041 return -ENODEV;
2044 switch (cmd) {
2045 case TCSBRK: /* SVID version: non-zero arg --> no break */
2046 retval = tty_check_change(tty);
2047 if (retval) {
2048 func_exit();
2049 return retval;
2051 tty_wait_until_sent(tty, 0);
2052 if (!arg)
2053 sx_send_break(port, HZ/4); /* 1/4 second */
2054 return 0;
2055 case TCSBRKP: /* support for POSIX tcsendbreak() */
2056 retval = tty_check_change(tty);
2057 if (retval) {
2058 func_exit();
2059 return retval;
2061 tty_wait_until_sent(tty, 0);
2062 sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
2063 func_exit();
2064 return 0;
2065 case TIOCGSOFTCAR:
2066 if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) {
2067 func_exit();
2068 return -EFAULT;
2070 func_exit();
2071 return 0;
2072 case TIOCSSOFTCAR:
2073 if (get_user(arg, (unsigned long __user *) argp)) {
2074 func_exit();
2075 return -EFAULT;
2077 tty->termios->c_cflag =
2078 ((tty->termios->c_cflag & ~CLOCAL) |
2079 (arg ? CLOCAL : 0));
2080 func_exit();
2081 return 0;
2082 case TIOCGSERIAL:
2083 func_exit();
2084 return sx_get_serial_info(port, argp);
2085 case TIOCSSERIAL:
2086 func_exit();
2087 return sx_set_serial_info(port, argp);
2088 default:
2089 func_exit();
2090 return -ENOIOCTLCMD;
2092 func_exit();
2093 return 0;
2097 static void sx_throttle(struct tty_struct * tty)
2099 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2100 struct specialix_board *bp;
2101 unsigned long flags;
2103 func_enter();
2105 if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
2106 func_exit();
2107 return;
2110 bp = port_Board(port);
2112 /* Use DTR instead of RTS ! */
2113 if (SX_CRTSCTS (tty))
2114 port->MSVR &= ~MSVR_DTR;
2115 else {
2116 /* Auch!!! I think the system shouldn't call this then. */
2117 /* Or maybe we're supposed (allowed?) to do our side of hw
2118 handshake anyway, even when hardware handshake is off.
2119 When you see this in your logs, please report.... */
2120 printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
2121 port_No (port));
2123 spin_lock_irqsave(&bp->lock, flags);
2124 sx_out(bp, CD186x_CAR, port_No(port));
2125 spin_unlock_irqrestore(&bp->lock, flags);
2126 if (I_IXOFF(tty)) {
2127 spin_unlock_irqrestore(&bp->lock, flags);
2128 sx_wait_CCR(bp);
2129 spin_lock_irqsave(&bp->lock, flags);
2130 sx_out(bp, CD186x_CCR, CCR_SSCH2);
2131 spin_unlock_irqrestore(&bp->lock, flags);
2132 sx_wait_CCR(bp);
2134 spin_lock_irqsave(&bp->lock, flags);
2135 sx_out(bp, CD186x_MSVR, port->MSVR);
2136 spin_unlock_irqrestore(&bp->lock, flags);
2138 func_exit();
2142 static void sx_unthrottle(struct tty_struct * tty)
2144 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2145 struct specialix_board *bp;
2146 unsigned long flags;
2148 func_enter();
2150 if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
2151 func_exit();
2152 return;
2155 bp = port_Board(port);
2157 spin_lock_irqsave(&port->lock, flags);
2158 /* XXXX Use DTR INSTEAD???? */
2159 if (SX_CRTSCTS(tty)) {
2160 port->MSVR |= MSVR_DTR;
2161 } /* Else clause: see remark in "sx_throttle"... */
2162 spin_lock_irqsave(&bp->lock, flags);
2163 sx_out(bp, CD186x_CAR, port_No(port));
2164 spin_unlock_irqrestore(&bp->lock, flags);
2165 if (I_IXOFF(tty)) {
2166 spin_unlock_irqrestore(&port->lock, flags);
2167 sx_wait_CCR(bp);
2168 spin_lock_irqsave(&bp->lock, flags);
2169 sx_out(bp, CD186x_CCR, CCR_SSCH1);
2170 spin_unlock_irqrestore(&bp->lock, flags);
2171 sx_wait_CCR(bp);
2172 spin_lock_irqsave(&port->lock, flags);
2174 spin_lock_irqsave(&bp->lock, flags);
2175 sx_out(bp, CD186x_MSVR, port->MSVR);
2176 spin_unlock_irqrestore(&bp->lock, flags);
2177 spin_unlock_irqrestore(&port->lock, flags);
2179 func_exit();
2183 static void sx_stop(struct tty_struct * tty)
2185 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2186 struct specialix_board *bp;
2187 unsigned long flags;
2189 func_enter();
2191 if (sx_paranoia_check(port, tty->name, "sx_stop")) {
2192 func_exit();
2193 return;
2196 bp = port_Board(port);
2198 spin_lock_irqsave(&port->lock, flags);
2199 port->IER &= ~IER_TXRDY;
2200 spin_lock_irqsave(&bp->lock, flags);
2201 sx_out(bp, CD186x_CAR, port_No(port));
2202 sx_out(bp, CD186x_IER, port->IER);
2203 spin_unlock_irqrestore(&bp->lock, flags);
2204 spin_unlock_irqrestore(&port->lock, flags);
2206 func_exit();
2210 static void sx_start(struct tty_struct * tty)
2212 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2213 struct specialix_board *bp;
2214 unsigned long flags;
2216 func_enter();
2218 if (sx_paranoia_check(port, tty->name, "sx_start")) {
2219 func_exit();
2220 return;
2223 bp = port_Board(port);
2225 spin_lock_irqsave(&port->lock, flags);
2226 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2227 port->IER |= IER_TXRDY;
2228 spin_lock_irqsave(&bp->lock, flags);
2229 sx_out(bp, CD186x_CAR, port_No(port));
2230 sx_out(bp, CD186x_IER, port->IER);
2231 spin_unlock_irqrestore(&bp->lock, flags);
2233 spin_unlock_irqrestore(&port->lock, flags);
2235 func_exit();
2240 * This routine is called from the work-queue when the interrupt
2241 * routine has signalled that a hangup has occurred. The path of
2242 * hangup processing is:
2244 * serial interrupt routine -> (workqueue) ->
2245 * do_sx_hangup() -> tty->hangup() -> sx_hangup()
2248 static void do_sx_hangup(struct work_struct *work)
2250 struct specialix_port *port =
2251 container_of(work, struct specialix_port, tqueue_hangup);
2252 struct tty_struct *tty;
2254 func_enter();
2256 tty = port->tty;
2257 if (tty)
2258 tty_hangup(tty); /* FIXME: module removal race here */
2260 func_exit();
2264 static void sx_hangup(struct tty_struct * tty)
2266 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2267 struct specialix_board *bp;
2268 unsigned long flags;
2270 func_enter();
2272 if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2273 func_exit();
2274 return;
2277 bp = port_Board(port);
2279 sx_shutdown_port(bp, port);
2280 spin_lock_irqsave(&port->lock, flags);
2281 port->event = 0;
2282 bp->count -= port->count;
2283 if (bp->count < 0) {
2284 printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n",
2285 board_No(bp), bp->count, tty->index);
2286 bp->count = 0;
2288 port->count = 0;
2289 port->flags &= ~ASYNC_NORMAL_ACTIVE;
2290 port->tty = NULL;
2291 spin_unlock_irqrestore(&port->lock, flags);
2292 wake_up_interruptible(&port->open_wait);
2294 func_exit();
2298 static void sx_set_termios(struct tty_struct * tty, struct ktermios * old_termios)
2300 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2301 unsigned long flags;
2302 struct specialix_board * bp;
2304 if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2305 return;
2307 if (tty->termios->c_cflag == old_termios->c_cflag &&
2308 tty->termios->c_iflag == old_termios->c_iflag)
2309 return;
2311 bp = port_Board(port);
2312 spin_lock_irqsave(&port->lock, flags);
2313 sx_change_speed(port_Board(port), port);
2314 spin_unlock_irqrestore(&port->lock, flags);
2316 if ((old_termios->c_cflag & CRTSCTS) &&
2317 !(tty->termios->c_cflag & CRTSCTS)) {
2318 tty->hw_stopped = 0;
2319 sx_start(tty);
2324 static void do_softint(struct work_struct *work)
2326 struct specialix_port *port =
2327 container_of(work, struct specialix_port, tqueue);
2328 struct tty_struct *tty;
2330 func_enter();
2332 if(!(tty = port->tty)) {
2333 func_exit();
2334 return;
2337 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event))
2338 tty_wakeup(tty);
2340 func_exit();
2343 static const struct tty_operations sx_ops = {
2344 .open = sx_open,
2345 .close = sx_close,
2346 .write = sx_write,
2347 .put_char = sx_put_char,
2348 .flush_chars = sx_flush_chars,
2349 .write_room = sx_write_room,
2350 .chars_in_buffer = sx_chars_in_buffer,
2351 .flush_buffer = sx_flush_buffer,
2352 .ioctl = sx_ioctl,
2353 .throttle = sx_throttle,
2354 .unthrottle = sx_unthrottle,
2355 .set_termios = sx_set_termios,
2356 .stop = sx_stop,
2357 .start = sx_start,
2358 .hangup = sx_hangup,
2359 .tiocmget = sx_tiocmget,
2360 .tiocmset = sx_tiocmset,
2363 static int sx_init_drivers(void)
2365 int error;
2366 int i;
2368 func_enter();
2370 specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT);
2371 if (!specialix_driver) {
2372 printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n");
2373 func_exit();
2374 return 1;
2377 specialix_driver->owner = THIS_MODULE;
2378 specialix_driver->name = "ttyW";
2379 specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
2380 specialix_driver->type = TTY_DRIVER_TYPE_SERIAL;
2381 specialix_driver->subtype = SERIAL_TYPE_NORMAL;
2382 specialix_driver->init_termios = tty_std_termios;
2383 specialix_driver->init_termios.c_cflag =
2384 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2385 specialix_driver->init_termios.c_ispeed = 9600;
2386 specialix_driver->init_termios.c_ospeed = 9600;
2387 specialix_driver->flags = TTY_DRIVER_REAL_RAW;
2388 tty_set_operations(specialix_driver, &sx_ops);
2390 if ((error = tty_register_driver(specialix_driver))) {
2391 put_tty_driver(specialix_driver);
2392 printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2393 error);
2394 func_exit();
2395 return 1;
2397 memset(sx_port, 0, sizeof(sx_port));
2398 for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2399 sx_port[i].magic = SPECIALIX_MAGIC;
2400 INIT_WORK(&sx_port[i].tqueue, do_softint);
2401 INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup);
2402 sx_port[i].close_delay = 50 * HZ/100;
2403 sx_port[i].closing_wait = 3000 * HZ/100;
2404 init_waitqueue_head(&sx_port[i].open_wait);
2405 init_waitqueue_head(&sx_port[i].close_wait);
2406 spin_lock_init(&sx_port[i].lock);
2409 func_exit();
2410 return 0;
2413 static void sx_release_drivers(void)
2415 func_enter();
2417 tty_unregister_driver(specialix_driver);
2418 put_tty_driver(specialix_driver);
2419 func_exit();
2423 * This routine must be called by kernel at boot time
2425 static int __init specialix_init(void)
2427 int i;
2428 int found = 0;
2430 func_enter();
2432 printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
2433 printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2434 #ifdef CONFIG_SPECIALIX_RTSCTS
2435 printk (KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
2436 #else
2437 printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2438 #endif
2440 for (i = 0; i < SX_NBOARD; i++)
2441 spin_lock_init(&sx_board[i].lock);
2443 if (sx_init_drivers()) {
2444 func_exit();
2445 return -EIO;
2448 for (i = 0; i < SX_NBOARD; i++)
2449 if (sx_board[i].base && !sx_probe(&sx_board[i]))
2450 found++;
2452 #ifdef CONFIG_PCI
2454 struct pci_dev *pdev = NULL;
2456 i=0;
2457 while (i < SX_NBOARD) {
2458 if (sx_board[i].flags & SX_BOARD_PRESENT) {
2459 i++;
2460 continue;
2462 pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,
2463 PCI_DEVICE_ID_SPECIALIX_IO8,
2464 pdev);
2465 if (!pdev) break;
2467 if (pci_enable_device(pdev))
2468 continue;
2470 sx_board[i].irq = pdev->irq;
2472 sx_board[i].base = pci_resource_start (pdev, 2);
2474 sx_board[i].flags |= SX_BOARD_IS_PCI;
2475 if (!sx_probe(&sx_board[i]))
2476 found ++;
2478 /* May exit pci_get sequence early with lots of boards */
2479 if (pdev != NULL)
2480 pci_dev_put(pdev);
2482 #endif
2484 if (!found) {
2485 sx_release_drivers();
2486 printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
2487 func_exit();
2488 return -EIO;
2491 func_exit();
2492 return 0;
2495 static int iobase[SX_NBOARD] = {0,};
2497 static int irq [SX_NBOARD] = {0,};
2499 module_param_array(iobase, int, NULL, 0);
2500 module_param_array(irq, int, NULL, 0);
2501 module_param(sx_debug, int, 0);
2502 module_param(sx_rxfifo, int, 0);
2503 #ifdef SPECIALIX_TIMER
2504 module_param(sx_poll, int, 0);
2505 #endif
2508 * You can setup up to 4 boards.
2509 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2510 * You should specify the IRQs too in that case "irq=....,...".
2512 * More than 4 boards in one computer is not possible, as the card can
2513 * only use 4 different interrupts.
2516 static int __init specialix_init_module(void)
2518 int i;
2520 func_enter();
2522 if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2523 for(i = 0; i < SX_NBOARD; i++) {
2524 sx_board[i].base = iobase[i];
2525 sx_board[i].irq = irq[i];
2526 sx_board[i].count= 0;
2530 func_exit();
2532 return specialix_init();
2535 static void __exit specialix_exit_module(void)
2537 int i;
2539 func_enter();
2541 sx_release_drivers();
2542 for (i = 0; i < SX_NBOARD; i++)
2543 if (sx_board[i].flags & SX_BOARD_PRESENT)
2544 sx_release_io_range(&sx_board[i]);
2545 #ifdef SPECIALIX_TIMER
2546 del_timer_sync(&missed_irq_timer);
2547 #endif
2549 func_exit();
2552 static struct pci_device_id specialx_pci_tbl[] __devinitdata = {
2553 { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) },
2556 MODULE_DEVICE_TABLE(pci, specialx_pci_tbl);
2558 module_init(specialix_init_module);
2559 module_exit(specialix_exit_module);
2561 MODULE_LICENSE("GPL");