[PATCH] V4L: Makes needlessly global code static
[linux/fpc-iii.git] / drivers / char / specialix.c
blob0bbfce43031c9d6be2e4041db9c8fc6f1eea0203
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/config.h>
79 #include <linux/module.h>
81 #include <asm/io.h>
82 #include <linux/kernel.h>
83 #include <linux/sched.h>
84 #include <linux/ioport.h>
85 #include <linux/interrupt.h>
86 #include <linux/errno.h>
87 #include <linux/tty.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;
185 static unsigned char * tmp_buf;
186 static DECLARE_MUTEX(tmp_buf_sem);
188 static unsigned long baud_table[] = {
189 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
190 9600, 19200, 38400, 57600, 115200, 0,
193 static struct specialix_board sx_board[SX_NBOARD] = {
194 { 0, SX_IOBASE1, 9, },
195 { 0, SX_IOBASE2, 11, },
196 { 0, SX_IOBASE3, 12, },
197 { 0, SX_IOBASE4, 15, },
200 static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
203 #ifdef SPECIALIX_TIMER
204 static struct timer_list missed_irq_timer;
205 static irqreturn_t sx_interrupt(int irq, void * dev_id, struct pt_regs * regs);
206 #endif
210 static inline int sx_paranoia_check(struct specialix_port const * port,
211 char *name, const char *routine)
213 #ifdef SPECIALIX_PARANOIA_CHECK
214 static const char *badmagic =
215 KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
216 static const char *badinfo =
217 KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
219 if (!port) {
220 printk(badinfo, name, routine);
221 return 1;
223 if (port->magic != SPECIALIX_MAGIC) {
224 printk(badmagic, name, routine);
225 return 1;
227 #endif
228 return 0;
234 * Service functions for specialix IO8+ driver.
238 /* Get board number from pointer */
239 static inline int board_No (struct specialix_board * bp)
241 return bp - sx_board;
245 /* Get port number from pointer */
246 static inline int port_No (struct specialix_port const * port)
248 return SX_PORT(port - sx_port);
252 /* Get pointer to board from pointer to port */
253 static inline struct specialix_board * port_Board(struct specialix_port const * port)
255 return &sx_board[SX_BOARD(port - sx_port)];
259 /* Input Byte from CL CD186x register */
260 static inline unsigned char sx_in(struct specialix_board * bp, unsigned short reg)
262 bp->reg = reg | 0x80;
263 outb (reg | 0x80, bp->base + SX_ADDR_REG);
264 return inb (bp->base + SX_DATA_REG);
268 /* Output Byte to CL CD186x register */
269 static inline void sx_out(struct specialix_board * bp, unsigned short reg,
270 unsigned char val)
272 bp->reg = reg | 0x80;
273 outb (reg | 0x80, bp->base + SX_ADDR_REG);
274 outb (val, bp->base + SX_DATA_REG);
278 /* Input Byte from CL CD186x register */
279 static inline unsigned char sx_in_off(struct specialix_board * bp, unsigned short reg)
281 bp->reg = reg;
282 outb (reg, bp->base + SX_ADDR_REG);
283 return inb (bp->base + SX_DATA_REG);
287 /* Output Byte to CL CD186x register */
288 static inline void sx_out_off(struct specialix_board * bp, unsigned short reg,
289 unsigned char val)
291 bp->reg = reg;
292 outb (reg, bp->base + SX_ADDR_REG);
293 outb (val, bp->base + SX_DATA_REG);
297 /* Wait for Channel Command Register ready */
298 static inline void sx_wait_CCR(struct specialix_board * bp)
300 unsigned long delay, flags;
301 unsigned char ccr;
303 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
304 spin_lock_irqsave(&bp->lock, flags);
305 ccr = sx_in(bp, CD186x_CCR);
306 spin_unlock_irqrestore(&bp->lock, flags);
307 if (!ccr)
308 return;
309 udelay (1);
312 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
316 /* Wait for Channel Command Register ready */
317 static inline void sx_wait_CCR_off(struct specialix_board * bp)
319 unsigned long delay;
320 unsigned char crr;
321 unsigned long flags;
323 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
324 spin_lock_irqsave(&bp->lock, flags);
325 crr = sx_in_off(bp, CD186x_CCR);
326 spin_unlock_irqrestore(&bp->lock, flags);
327 if (!crr)
328 return;
329 udelay (1);
332 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
337 * specialix IO8+ IO range functions.
340 static inline int sx_request_io_range(struct specialix_board * bp)
342 return request_region(bp->base,
343 bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
344 "specialix IO8+") == NULL;
348 static inline void sx_release_io_range(struct specialix_board * bp)
350 release_region(bp->base,
351 bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
355 /* Must be called with enabled interrupts */
356 /* Ugly. Very ugly. Don't use this for anything else than initialization
357 code */
358 static inline void sx_long_delay(unsigned long delay)
360 unsigned long i;
362 for (i = jiffies + delay; time_after(i, jiffies); ) ;
367 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
368 static int sx_set_irq ( struct specialix_board *bp)
370 int virq;
371 int i;
372 unsigned long flags;
374 if (bp->flags & SX_BOARD_IS_PCI)
375 return 1;
376 switch (bp->irq) {
377 /* In the same order as in the docs... */
378 case 15: virq = 0;break;
379 case 12: virq = 1;break;
380 case 11: virq = 2;break;
381 case 9: virq = 3;break;
382 default: printk (KERN_ERR "Speclialix: cannot set irq to %d.\n", bp->irq);
383 return 0;
385 spin_lock_irqsave(&bp->lock, flags);
386 for (i=0;i<2;i++) {
387 sx_out(bp, CD186x_CAR, i);
388 sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
390 spin_unlock_irqrestore(&bp->lock, flags);
391 return 1;
395 /* Reset and setup CD186x chip */
396 static int sx_init_CD186x(struct specialix_board * bp)
398 unsigned long flags;
399 int scaler;
400 int rv = 1;
402 func_enter();
403 sx_wait_CCR_off(bp); /* Wait for CCR ready */
404 spin_lock_irqsave(&bp->lock, flags);
405 sx_out_off(bp, CD186x_CCR, CCR_HARDRESET); /* Reset CD186x chip */
406 spin_unlock_irqrestore(&bp->lock, flags);
407 sx_long_delay(HZ/20); /* Delay 0.05 sec */
408 spin_lock_irqsave(&bp->lock, flags);
409 sx_out_off(bp, CD186x_GIVR, SX_ID); /* Set ID for this chip */
410 sx_out_off(bp, CD186x_GICR, 0); /* Clear all bits */
411 sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT); /* Prio for modem intr */
412 sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */
413 sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
414 /* Set RegAckEn */
415 sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
417 /* Setting up prescaler. We need 4 ticks per 1 ms */
418 scaler = SX_OSCFREQ/SPECIALIX_TPS;
420 sx_out_off(bp, CD186x_PPRH, scaler >> 8);
421 sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
422 spin_unlock_irqrestore(&bp->lock, flags);
424 if (!sx_set_irq (bp)) {
425 /* Figure out how to pass this along... */
426 printk (KERN_ERR "Cannot set irq to %d.\n", bp->irq);
427 rv = 0;
430 func_exit();
431 return rv;
435 static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
437 int i;
438 int t;
439 unsigned long flags;
441 spin_lock_irqsave(&bp->lock, flags);
442 for (i=0, t=0;i<8;i++) {
443 sx_out_off (bp, CD186x_CAR, i);
444 if (sx_in_off (bp, reg) & bit)
445 t |= 1 << i;
447 spin_unlock_irqrestore(&bp->lock, flags);
449 return t;
453 #ifdef SPECIALIX_TIMER
454 void missed_irq (unsigned long data)
456 unsigned char irq;
457 unsigned long flags;
458 struct specialix_board *bp = (struct specialix_board *)data;
460 spin_lock_irqsave(&bp->lock, flags);
461 irq = sx_in ((struct specialix_board *)data, CD186x_SRSR) &
462 (SRSR_RREQint |
463 SRSR_TREQint |
464 SRSR_MREQint);
465 spin_unlock_irqrestore(&bp->lock, flags);
466 if (irq) {
467 printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
468 sx_interrupt (((struct specialix_board *)data)->irq,
469 (void*)data, NULL);
471 missed_irq_timer.expires = jiffies + sx_poll;
472 add_timer (&missed_irq_timer);
474 #endif
478 /* Main probing routine, also sets irq. */
479 static int sx_probe(struct specialix_board *bp)
481 unsigned char val1, val2;
482 #if 0
483 int irqs = 0;
484 int retries;
485 #endif
486 int rev;
487 int chip;
489 func_enter();
491 if (sx_request_io_range(bp)) {
492 func_exit();
493 return 1;
496 /* Are the I/O ports here ? */
497 sx_out_off(bp, CD186x_PPRL, 0x5a);
498 short_pause ();
499 val1 = sx_in_off(bp, CD186x_PPRL);
501 sx_out_off(bp, CD186x_PPRL, 0xa5);
502 short_pause ();
503 val2 = sx_in_off(bp, CD186x_PPRL);
506 if ((val1 != 0x5a) || (val2 != 0xa5)) {
507 printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
508 board_No(bp), bp->base);
509 sx_release_io_range(bp);
510 func_exit();
511 return 1;
514 /* Check the DSR lines that Specialix uses as board
515 identification */
516 val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
517 val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
518 dprintk (SX_DEBUG_INIT, "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
519 board_No(bp), val1, val2);
521 /* They managed to switch the bit order between the docs and
522 the IO8+ card. The new PCI card now conforms to old docs.
523 They changed the PCI docs to reflect the situation on the
524 old card. */
525 val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
526 if (val1 != val2) {
527 printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
528 board_No(bp), val2, bp->base, val1);
529 sx_release_io_range(bp);
530 func_exit();
531 return 1;
535 #if 0
536 /* It's time to find IRQ for this board */
537 for (retries = 0; retries < 5 && irqs <= 0; retries++) {
538 irqs = probe_irq_on();
539 sx_init_CD186x(bp); /* Reset CD186x chip */
540 sx_out(bp, CD186x_CAR, 2); /* Select port 2 */
541 sx_wait_CCR(bp);
542 sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */
543 sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */
544 sx_long_delay(HZ/20);
545 irqs = probe_irq_off(irqs);
547 dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
548 dprintk (SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR));
549 dprintk (SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR));
550 dprintk (SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR));
551 dprintk (SX_DEBUG_INIT, "\n");
553 /* Reset CD186x again */
554 if (!sx_init_CD186x(bp)) {
555 /* Hmmm. This is dead code anyway. */
558 dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
559 val1, val2, val3);
563 #if 0
564 if (irqs <= 0) {
565 printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
566 board_No(bp), bp->base);
567 sx_release_io_range(bp);
568 func_exit();
569 return 1;
571 #endif
572 printk (KERN_INFO "Started with irq=%d, but now have irq=%d.\n", bp->irq, irqs);
573 if (irqs > 0)
574 bp->irq = irqs;
575 #endif
576 /* Reset CD186x again */
577 if (!sx_init_CD186x(bp)) {
578 sx_release_io_range(bp);
579 func_exit();
580 return 1;
583 sx_request_io_range(bp);
584 bp->flags |= SX_BOARD_PRESENT;
586 /* Chip revcode pkgtype
587 GFRCR SRCR bit 7
588 CD180 rev B 0x81 0
589 CD180 rev C 0x82 0
590 CD1864 rev A 0x82 1
591 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
592 CD1865 rev B 0x84 1
593 -- Thanks to Gwen Wang, Cirrus Logic.
596 switch (sx_in_off(bp, CD186x_GFRCR)) {
597 case 0x82:chip = 1864;rev='A';break;
598 case 0x83:chip = 1865;rev='A';break;
599 case 0x84:chip = 1865;rev='B';break;
600 case 0x85:chip = 1865;rev='C';break; /* Does not exist at this time */
601 default:chip=-1;rev='x';
604 dprintk (SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR) );
606 #ifdef SPECIALIX_TIMER
607 init_timer (&missed_irq_timer);
608 missed_irq_timer.function = missed_irq;
609 missed_irq_timer.data = (unsigned long) bp;
610 missed_irq_timer.expires = jiffies + sx_poll;
611 add_timer (&missed_irq_timer);
612 #endif
614 printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
615 board_No(bp),
616 bp->base, bp->irq,
617 chip, rev);
619 func_exit();
620 return 0;
625 * Interrupt processing routines.
626 * */
628 static inline void sx_mark_event(struct specialix_port * port, int event)
630 func_enter();
632 set_bit(event, &port->event);
633 schedule_work(&port->tqueue);
635 func_exit();
639 static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
640 unsigned char const * what)
642 unsigned char channel;
643 struct specialix_port * port = NULL;
645 channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
646 dprintk (SX_DEBUG_CHAN, "channel: %d\n", channel);
647 if (channel < CD186x_NCH) {
648 port = &sx_port[board_No(bp) * SX_NPORT + channel];
649 dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%x\n",board_No(bp) * SX_NPORT + channel, port, port->flags & ASYNC_INITIALIZED);
651 if (port->flags & ASYNC_INITIALIZED) {
652 dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
653 func_exit();
654 return port;
657 printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
658 board_No(bp), what, channel);
659 return NULL;
663 static inline void sx_receive_exc(struct specialix_board * bp)
665 struct specialix_port *port;
666 struct tty_struct *tty;
667 unsigned char status;
668 unsigned char ch;
670 func_enter();
672 port = sx_get_port(bp, "Receive");
673 if (!port) {
674 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
675 func_exit();
676 return;
678 tty = port->tty;
679 dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n",
680 port, tty->flip.count, TTY_FLIPBUF_SIZE);
682 status = sx_in(bp, CD186x_RCSR);
684 dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
685 if (status & RCSR_OE) {
686 port->overrun++;
687 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Overrun. Total %ld overruns.\n",
688 board_No(bp), port_No(port), port->overrun);
690 status &= port->mark_mask;
692 /* This flip buffer check needs to be below the reading of the
693 status register to reset the chip's IRQ.... */
694 if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
695 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n",
696 board_No(bp), port_No(port));
697 func_exit();
698 return;
701 ch = sx_in(bp, CD186x_RDR);
702 if (!status) {
703 func_exit();
704 return;
706 if (status & RCSR_TOUT) {
707 printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
708 board_No(bp), port_No(port));
709 func_exit();
710 return;
712 } else if (status & RCSR_BREAK) {
713 dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
714 board_No(bp), port_No(port));
715 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
716 if (port->flags & ASYNC_SAK)
717 do_SAK(tty);
719 } else if (status & RCSR_PE)
720 *tty->flip.flag_buf_ptr++ = TTY_PARITY;
722 else if (status & RCSR_FE)
723 *tty->flip.flag_buf_ptr++ = TTY_FRAME;
725 else if (status & RCSR_OE)
726 *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
728 else
729 *tty->flip.flag_buf_ptr++ = 0;
731 *tty->flip.char_buf_ptr++ = ch;
732 tty->flip.count++;
733 schedule_delayed_work(&tty->flip.work, 1);
735 func_exit();
739 static inline void sx_receive(struct specialix_board * bp)
741 struct specialix_port *port;
742 struct tty_struct *tty;
743 unsigned char count;
745 func_enter();
747 if (!(port = sx_get_port(bp, "Receive"))) {
748 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
749 func_exit();
750 return;
752 tty = port->tty;
754 count = sx_in(bp, CD186x_RDCR);
755 dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
756 port->hits[count > 8 ? 9 : count]++;
758 while (count--) {
759 if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
760 printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n",
761 board_No(bp), port_No(port));
762 break;
764 *tty->flip.char_buf_ptr++ = sx_in(bp, CD186x_RDR);
765 *tty->flip.flag_buf_ptr++ = 0;
766 tty->flip.count++;
768 schedule_delayed_work(&tty->flip.work, 1);
770 func_exit();
774 static inline void sx_transmit(struct specialix_board * bp)
776 struct specialix_port *port;
777 struct tty_struct *tty;
778 unsigned char count;
780 func_enter();
781 if (!(port = sx_get_port(bp, "Transmit"))) {
782 func_exit();
783 return;
785 dprintk (SX_DEBUG_TX, "port: %p\n", port);
786 tty = port->tty;
788 if (port->IER & IER_TXEMPTY) {
789 /* FIFO drained */
790 sx_out(bp, CD186x_CAR, port_No(port));
791 port->IER &= ~IER_TXEMPTY;
792 sx_out(bp, CD186x_IER, port->IER);
793 func_exit();
794 return;
797 if ((port->xmit_cnt <= 0 && !port->break_length)
798 || tty->stopped || tty->hw_stopped) {
799 sx_out(bp, CD186x_CAR, port_No(port));
800 port->IER &= ~IER_TXRDY;
801 sx_out(bp, CD186x_IER, port->IER);
802 func_exit();
803 return;
806 if (port->break_length) {
807 if (port->break_length > 0) {
808 if (port->COR2 & COR2_ETC) {
809 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
810 sx_out(bp, CD186x_TDR, CD186x_C_SBRK);
811 port->COR2 &= ~COR2_ETC;
813 count = min_t(int, port->break_length, 0xff);
814 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
815 sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
816 sx_out(bp, CD186x_TDR, count);
817 if (!(port->break_length -= count))
818 port->break_length--;
819 } else {
820 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
821 sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
822 sx_out(bp, CD186x_COR2, port->COR2);
823 sx_wait_CCR(bp);
824 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
825 port->break_length = 0;
828 func_exit();
829 return;
832 count = CD186x_NFIFO;
833 do {
834 sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
835 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
836 if (--port->xmit_cnt <= 0)
837 break;
838 } while (--count > 0);
840 if (port->xmit_cnt <= 0) {
841 sx_out(bp, CD186x_CAR, port_No(port));
842 port->IER &= ~IER_TXRDY;
843 sx_out(bp, CD186x_IER, port->IER);
845 if (port->xmit_cnt <= port->wakeup_chars)
846 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
848 func_exit();
852 static inline void sx_check_modem(struct specialix_board * bp)
854 struct specialix_port *port;
855 struct tty_struct *tty;
856 unsigned char mcr;
857 int msvr_cd;
859 dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
860 if (!(port = sx_get_port(bp, "Modem")))
861 return;
863 tty = port->tty;
865 mcr = sx_in(bp, CD186x_MCR);
866 printk ("mcr = %02x.\n", mcr);
868 if ((mcr & MCR_CDCHG)) {
869 dprintk (SX_DEBUG_SIGNALS, "CD just changed... ");
870 msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
871 if (msvr_cd) {
872 dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
873 wake_up_interruptible(&port->open_wait);
874 } else {
875 dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n");
876 schedule_work(&port->tqueue_hangup);
880 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
881 if (mcr & MCR_CTSCHG) {
882 if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
883 tty->hw_stopped = 0;
884 port->IER |= IER_TXRDY;
885 if (port->xmit_cnt <= port->wakeup_chars)
886 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
887 } else {
888 tty->hw_stopped = 1;
889 port->IER &= ~IER_TXRDY;
891 sx_out(bp, CD186x_IER, port->IER);
893 if (mcr & MCR_DSSXHG) {
894 if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
895 tty->hw_stopped = 0;
896 port->IER |= IER_TXRDY;
897 if (port->xmit_cnt <= port->wakeup_chars)
898 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
899 } else {
900 tty->hw_stopped = 1;
901 port->IER &= ~IER_TXRDY;
903 sx_out(bp, CD186x_IER, port->IER);
905 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
907 /* Clear change bits */
908 sx_out(bp, CD186x_MCR, 0);
912 /* The main interrupt processing routine */
913 static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
915 unsigned char status;
916 unsigned char ack;
917 struct specialix_board *bp;
918 unsigned long loop = 0;
919 int saved_reg;
920 unsigned long flags;
922 func_enter();
924 bp = dev_id;
925 spin_lock_irqsave(&bp->lock, flags);
927 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);
928 if (!bp || !(bp->flags & SX_BOARD_ACTIVE)) {
929 dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq);
930 spin_unlock_irqrestore(&bp->lock, flags);
931 func_exit();
932 return IRQ_NONE;
935 saved_reg = bp->reg;
937 while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
938 (SRSR_RREQint |
939 SRSR_TREQint |
940 SRSR_MREQint)))) {
941 if (status & SRSR_RREQint) {
942 ack = sx_in(bp, CD186x_RRAR);
944 if (ack == (SX_ID | GIVR_IT_RCV))
945 sx_receive(bp);
946 else if (ack == (SX_ID | GIVR_IT_REXC))
947 sx_receive_exc(bp);
948 else
949 printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
950 board_No(bp), status, ack);
952 } else if (status & SRSR_TREQint) {
953 ack = sx_in(bp, CD186x_TRAR);
955 if (ack == (SX_ID | GIVR_IT_TX))
956 sx_transmit(bp);
957 else
958 printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
959 board_No(bp), status, ack, port_No (sx_get_port (bp, "Int")));
960 } else if (status & SRSR_MREQint) {
961 ack = sx_in(bp, CD186x_MRAR);
963 if (ack == (SX_ID | GIVR_IT_MODEM))
964 sx_check_modem(bp);
965 else
966 printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
967 board_No(bp), status, ack);
971 sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
973 bp->reg = saved_reg;
974 outb (bp->reg, bp->base + SX_ADDR_REG);
975 spin_unlock_irqrestore(&bp->lock, flags);
976 func_exit();
977 return IRQ_HANDLED;
982 * Routines for open & close processing.
985 static void turn_ints_off (struct specialix_board *bp)
987 unsigned long flags;
989 func_enter();
990 if (bp->flags & SX_BOARD_IS_PCI) {
991 /* This was intended for enabeling the interrupt on the
992 * PCI card. However it seems that it's already enabled
993 * and as PCI interrupts can be shared, there is no real
994 * reason to have to turn it off. */
997 spin_lock_irqsave(&bp->lock, flags);
998 (void) sx_in_off (bp, 0); /* Turn off interrupts. */
999 spin_unlock_irqrestore(&bp->lock, flags);
1001 func_exit();
1004 static void turn_ints_on (struct specialix_board *bp)
1006 unsigned long flags;
1008 func_enter();
1010 if (bp->flags & SX_BOARD_IS_PCI) {
1011 /* play with the PCI chip. See comment above. */
1013 spin_lock_irqsave(&bp->lock, flags);
1014 (void) sx_in (bp, 0); /* Turn ON interrupts. */
1015 spin_unlock_irqrestore(&bp->lock, flags);
1017 func_exit();
1021 /* Called with disabled interrupts */
1022 static inline int sx_setup_board(struct specialix_board * bp)
1024 int error;
1026 if (bp->flags & SX_BOARD_ACTIVE)
1027 return 0;
1029 if (bp->flags & SX_BOARD_IS_PCI)
1030 error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT | SA_SHIRQ, "specialix IO8+", bp);
1031 else
1032 error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT, "specialix IO8+", bp);
1034 if (error)
1035 return error;
1037 turn_ints_on (bp);
1038 bp->flags |= SX_BOARD_ACTIVE;
1040 return 0;
1044 /* Called with disabled interrupts */
1045 static inline void sx_shutdown_board(struct specialix_board *bp)
1047 func_enter();
1049 if (!(bp->flags & SX_BOARD_ACTIVE)) {
1050 func_exit();
1051 return;
1054 bp->flags &= ~SX_BOARD_ACTIVE;
1056 dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
1057 bp->irq, board_No (bp));
1058 free_irq(bp->irq, bp);
1060 turn_ints_off (bp);
1063 func_exit();
1068 * Setting up port characteristics.
1069 * Must be called with disabled interrupts
1071 static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
1073 struct tty_struct *tty;
1074 unsigned long baud;
1075 long tmp;
1076 unsigned char cor1 = 0, cor3 = 0;
1077 unsigned char mcor1 = 0, mcor2 = 0;
1078 static unsigned long again;
1079 unsigned long flags;
1081 func_enter();
1083 if (!(tty = port->tty) || !tty->termios) {
1084 func_exit();
1085 return;
1088 port->IER = 0;
1089 port->COR2 = 0;
1090 /* Select port on the board */
1091 spin_lock_irqsave(&bp->lock, flags);
1092 sx_out(bp, CD186x_CAR, port_No(port));
1094 /* The Specialix board doens't implement the RTS lines.
1095 They are used to set the IRQ level. Don't touch them. */
1096 if (SX_CRTSCTS(tty))
1097 port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1098 else
1099 port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1100 spin_unlock_irqrestore(&bp->lock, flags);
1101 dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
1102 baud = C_BAUD(tty);
1104 if (baud & CBAUDEX) {
1105 baud &= ~CBAUDEX;
1106 if (baud < 1 || baud > 2)
1107 port->tty->termios->c_cflag &= ~CBAUDEX;
1108 else
1109 baud += 15;
1111 if (baud == 15) {
1112 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1113 baud ++;
1114 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1115 baud += 2;
1119 if (!baud_table[baud]) {
1120 /* Drop DTR & exit */
1121 dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
1122 if (!SX_CRTSCTS (tty)) {
1123 port -> MSVR &= ~ MSVR_DTR;
1124 spin_lock_irqsave(&bp->lock, flags);
1125 sx_out(bp, CD186x_MSVR, port->MSVR );
1126 spin_unlock_irqrestore(&bp->lock, flags);
1128 else
1129 dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1130 return;
1131 } else {
1132 /* Set DTR on */
1133 if (!SX_CRTSCTS (tty)) {
1134 port ->MSVR |= MSVR_DTR;
1139 * Now we must calculate some speed depended things
1142 /* Set baud rate for port */
1143 tmp = port->custom_divisor ;
1144 if ( tmp )
1145 printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n"
1146 "This is an untested option, please be carefull.\n",
1147 port_No (port), tmp);
1148 else
1149 tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
1150 CD186x_TPC/2) / CD186x_TPC);
1152 if ((tmp < 0x10) && time_before(again, jiffies)) {
1153 again = jiffies + HZ * 60;
1154 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1155 if (tmp >= 12) {
1156 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1157 "Performance degradation is possible.\n"
1158 "Read specialix.txt for more info.\n",
1159 port_No (port), tmp);
1160 } else {
1161 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1162 "Warning: overstressing Cirrus chip. "
1163 "This might not work.\n"
1164 "Read specialix.txt for more info.\n",
1165 port_No (port), tmp);
1168 spin_lock_irqsave(&bp->lock, flags);
1169 sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1170 sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1171 sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1172 sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1173 spin_unlock_irqrestore(&bp->lock, flags);
1174 if (port->custom_divisor) {
1175 baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
1176 baud = ( baud + 5 ) / 10;
1177 } else
1178 baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */
1180 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1181 tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1182 port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1183 SERIAL_XMIT_SIZE - 1 : tmp);
1185 /* Receiver timeout will be transmission time for 1.5 chars */
1186 tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1187 tmp = (tmp > 0xff) ? 0xff : tmp;
1188 spin_lock_irqsave(&bp->lock, flags);
1189 sx_out(bp, CD186x_RTPR, tmp);
1190 spin_unlock_irqrestore(&bp->lock, flags);
1191 switch (C_CSIZE(tty)) {
1192 case CS5:
1193 cor1 |= COR1_5BITS;
1194 break;
1195 case CS6:
1196 cor1 |= COR1_6BITS;
1197 break;
1198 case CS7:
1199 cor1 |= COR1_7BITS;
1200 break;
1201 case CS8:
1202 cor1 |= COR1_8BITS;
1203 break;
1206 if (C_CSTOPB(tty))
1207 cor1 |= COR1_2SB;
1209 cor1 |= COR1_IGNORE;
1210 if (C_PARENB(tty)) {
1211 cor1 |= COR1_NORMPAR;
1212 if (C_PARODD(tty))
1213 cor1 |= COR1_ODDP;
1214 if (I_INPCK(tty))
1215 cor1 &= ~COR1_IGNORE;
1217 /* Set marking of some errors */
1218 port->mark_mask = RCSR_OE | RCSR_TOUT;
1219 if (I_INPCK(tty))
1220 port->mark_mask |= RCSR_FE | RCSR_PE;
1221 if (I_BRKINT(tty) || I_PARMRK(tty))
1222 port->mark_mask |= RCSR_BREAK;
1223 if (I_IGNPAR(tty))
1224 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1225 if (I_IGNBRK(tty)) {
1226 port->mark_mask &= ~RCSR_BREAK;
1227 if (I_IGNPAR(tty))
1228 /* Real raw mode. Ignore all */
1229 port->mark_mask &= ~RCSR_OE;
1231 /* Enable Hardware Flow Control */
1232 if (C_CRTSCTS(tty)) {
1233 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1234 port->IER |= IER_DSR | IER_CTS;
1235 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1236 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1237 spin_lock_irqsave(&bp->lock, flags);
1238 tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
1239 spin_unlock_irqrestore(&bp->lock, flags);
1240 #else
1241 port->COR2 |= COR2_CTSAE;
1242 #endif
1244 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1245 /* Some people reported that it works, but I still doubt it */
1246 if (I_IXON(tty)) {
1247 port->COR2 |= COR2_TXIBE;
1248 cor3 |= (COR3_FCT | COR3_SCDE);
1249 if (I_IXANY(tty))
1250 port->COR2 |= COR2_IXM;
1251 spin_lock_irqsave(&bp->lock, flags);
1252 sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1253 sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1254 sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1255 sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1256 spin_unlock_irqrestore(&bp->lock, flags);
1258 if (!C_CLOCAL(tty)) {
1259 /* Enable CD check */
1260 port->IER |= IER_CD;
1261 mcor1 |= MCOR1_CDZD;
1262 mcor2 |= MCOR2_CDOD;
1265 if (C_CREAD(tty))
1266 /* Enable receiver */
1267 port->IER |= IER_RXD;
1269 /* Set input FIFO size (1-8 bytes) */
1270 cor3 |= sx_rxfifo;
1271 /* Setting up CD186x channel registers */
1272 spin_lock_irqsave(&bp->lock, flags);
1273 sx_out(bp, CD186x_COR1, cor1);
1274 sx_out(bp, CD186x_COR2, port->COR2);
1275 sx_out(bp, CD186x_COR3, cor3);
1276 spin_unlock_irqrestore(&bp->lock, flags);
1277 /* Make CD186x know about registers change */
1278 sx_wait_CCR(bp);
1279 spin_lock_irqsave(&bp->lock, flags);
1280 sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1281 /* Setting up modem option registers */
1282 dprintk (SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2);
1283 sx_out(bp, CD186x_MCOR1, mcor1);
1284 sx_out(bp, CD186x_MCOR2, mcor2);
1285 spin_unlock_irqrestore(&bp->lock, flags);
1286 /* Enable CD186x transmitter & receiver */
1287 sx_wait_CCR(bp);
1288 spin_lock_irqsave(&bp->lock, flags);
1289 sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1290 /* Enable interrupts */
1291 sx_out(bp, CD186x_IER, port->IER);
1292 /* And finally set the modem lines... */
1293 sx_out(bp, CD186x_MSVR, port->MSVR);
1294 spin_unlock_irqrestore(&bp->lock, flags);
1296 func_exit();
1300 /* Must be called with interrupts enabled */
1301 static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port)
1303 unsigned long flags;
1305 func_enter();
1307 if (port->flags & ASYNC_INITIALIZED) {
1308 func_exit();
1309 return 0;
1312 if (!port->xmit_buf) {
1313 /* We may sleep in get_zeroed_page() */
1314 unsigned long tmp;
1316 if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
1317 func_exit();
1318 return -ENOMEM;
1321 if (port->xmit_buf) {
1322 free_page(tmp);
1323 func_exit();
1324 return -ERESTARTSYS;
1326 port->xmit_buf = (unsigned char *) tmp;
1329 spin_lock_irqsave(&port->lock, flags);
1331 if (port->tty)
1332 clear_bit(TTY_IO_ERROR, &port->tty->flags);
1334 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1335 sx_change_speed(bp, port);
1336 port->flags |= ASYNC_INITIALIZED;
1338 spin_unlock_irqrestore(&port->lock, flags);
1341 func_exit();
1342 return 0;
1346 /* Must be called with interrupts disabled */
1347 static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port)
1349 struct tty_struct *tty;
1350 int i;
1351 unsigned long flags;
1353 func_enter();
1355 if (!(port->flags & ASYNC_INITIALIZED)) {
1356 func_exit();
1357 return;
1360 if (sx_debug & SX_DEBUG_FIFO) {
1361 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
1362 board_No(bp), port_No(port), port->overrun);
1363 for (i = 0; i < 10; i++) {
1364 dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1366 dprintk(SX_DEBUG_FIFO, "].\n");
1369 if (port->xmit_buf) {
1370 free_page((unsigned long) port->xmit_buf);
1371 port->xmit_buf = NULL;
1374 /* Select port */
1375 spin_lock_irqsave(&bp->lock, flags);
1376 sx_out(bp, CD186x_CAR, port_No(port));
1378 if (!(tty = port->tty) || C_HUPCL(tty)) {
1379 /* Drop DTR */
1380 sx_out(bp, CD186x_MSVDTR, 0);
1382 spin_unlock_irqrestore(&bp->lock, flags);
1383 /* Reset port */
1384 sx_wait_CCR(bp);
1385 spin_lock_irqsave(&bp->lock, flags);
1386 sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1387 /* Disable all interrupts from this port */
1388 port->IER = 0;
1389 sx_out(bp, CD186x_IER, port->IER);
1390 spin_unlock_irqrestore(&bp->lock, flags);
1391 if (tty)
1392 set_bit(TTY_IO_ERROR, &tty->flags);
1393 port->flags &= ~ASYNC_INITIALIZED;
1395 if (!bp->count)
1396 sx_shutdown_board(bp);
1397 func_exit();
1401 static int block_til_ready(struct tty_struct *tty, struct file * filp,
1402 struct specialix_port *port)
1404 DECLARE_WAITQUEUE(wait, current);
1405 struct specialix_board *bp = port_Board(port);
1406 int retval;
1407 int do_clocal = 0;
1408 int CD;
1409 unsigned long flags;
1411 func_enter();
1414 * If the device is in the middle of being closed, then block
1415 * until it's done, and then try again.
1417 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
1418 interruptible_sleep_on(&port->close_wait);
1419 if (port->flags & ASYNC_HUP_NOTIFY) {
1420 func_exit();
1421 return -EAGAIN;
1422 } else {
1423 func_exit();
1424 return -ERESTARTSYS;
1429 * If non-blocking mode is set, or the port is not enabled,
1430 * then make the check up front and then exit.
1432 if ((filp->f_flags & O_NONBLOCK) ||
1433 (tty->flags & (1 << TTY_IO_ERROR))) {
1434 port->flags |= ASYNC_NORMAL_ACTIVE;
1435 func_exit();
1436 return 0;
1439 if (C_CLOCAL(tty))
1440 do_clocal = 1;
1443 * Block waiting for the carrier detect and the line to become
1444 * free (i.e., not in use by the callout). While we are in
1445 * this loop, info->count is dropped by one, so that
1446 * rs_close() knows when to free things. We restore it upon
1447 * exit, either normal or abnormal.
1449 retval = 0;
1450 add_wait_queue(&port->open_wait, &wait);
1451 spin_lock_irqsave(&port->lock, flags);
1452 if (!tty_hung_up_p(filp)) {
1453 port->count--;
1455 spin_unlock_irqrestore(&port->lock, flags);
1456 port->blocked_open++;
1457 while (1) {
1458 spin_lock_irqsave(&bp->lock, flags);
1459 sx_out(bp, CD186x_CAR, port_No(port));
1460 CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1461 if (SX_CRTSCTS (tty)) {
1462 /* Activate RTS */
1463 port->MSVR |= MSVR_DTR; /* WTF? */
1464 sx_out (bp, CD186x_MSVR, port->MSVR);
1465 } else {
1466 /* Activate DTR */
1467 port->MSVR |= MSVR_DTR;
1468 sx_out (bp, CD186x_MSVR, port->MSVR);
1470 spin_unlock_irqrestore(&bp->lock, flags);
1471 set_current_state(TASK_INTERRUPTIBLE);
1472 if (tty_hung_up_p(filp) ||
1473 !(port->flags & ASYNC_INITIALIZED)) {
1474 if (port->flags & ASYNC_HUP_NOTIFY)
1475 retval = -EAGAIN;
1476 else
1477 retval = -ERESTARTSYS;
1478 break;
1480 if (!(port->flags & ASYNC_CLOSING) &&
1481 (do_clocal || CD))
1482 break;
1483 if (signal_pending(current)) {
1484 retval = -ERESTARTSYS;
1485 break;
1487 schedule();
1490 set_current_state(TASK_RUNNING);
1491 remove_wait_queue(&port->open_wait, &wait);
1492 spin_lock_irqsave(&port->lock, flags);
1493 if (!tty_hung_up_p(filp)) {
1494 port->count++;
1496 port->blocked_open--;
1497 spin_unlock_irqrestore(&port->lock, flags);
1498 if (retval) {
1499 func_exit();
1500 return retval;
1503 port->flags |= ASYNC_NORMAL_ACTIVE;
1504 func_exit();
1505 return 0;
1509 static int sx_open(struct tty_struct * tty, struct file * filp)
1511 int board;
1512 int error;
1513 struct specialix_port * port;
1514 struct specialix_board * bp;
1515 int i;
1516 unsigned long flags;
1518 func_enter();
1520 board = SX_BOARD(tty->index);
1522 if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1523 func_exit();
1524 return -ENODEV;
1527 bp = &sx_board[board];
1528 port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1529 port->overrun = 0;
1530 for (i = 0; i < 10; i++)
1531 port->hits[i]=0;
1533 dprintk (SX_DEBUG_OPEN, "Board = %d, bp = %p, port = %p, portno = %d.\n",
1534 board, bp, port, SX_PORT(tty->index));
1536 if (sx_paranoia_check(port, tty->name, "sx_open")) {
1537 func_enter();
1538 return -ENODEV;
1541 if ((error = sx_setup_board(bp))) {
1542 func_exit();
1543 return error;
1546 spin_lock_irqsave(&bp->lock, flags);
1547 port->count++;
1548 bp->count++;
1549 tty->driver_data = port;
1550 port->tty = tty;
1551 spin_unlock_irqrestore(&bp->lock, flags);
1553 if ((error = sx_setup_port(bp, port))) {
1554 func_enter();
1555 return error;
1558 if ((error = block_til_ready(tty, filp, port))) {
1559 func_enter();
1560 return error;
1563 func_exit();
1564 return 0;
1568 static void sx_close(struct tty_struct * tty, struct file * filp)
1570 struct specialix_port *port = (struct specialix_port *) tty->driver_data;
1571 struct specialix_board *bp;
1572 unsigned long flags;
1573 unsigned long timeout;
1575 func_enter();
1576 if (!port || sx_paranoia_check(port, tty->name, "close")) {
1577 func_exit();
1578 return;
1580 spin_lock_irqsave(&port->lock, flags);
1582 if (tty_hung_up_p(filp)) {
1583 spin_unlock_irqrestore(&port->lock, flags);
1584 func_exit();
1585 return;
1588 bp = port_Board(port);
1589 if ((tty->count == 1) && (port->count != 1)) {
1590 printk(KERN_ERR "sx%d: sx_close: bad port count;"
1591 " tty->count is 1, port count is %d\n",
1592 board_No(bp), port->count);
1593 port->count = 1;
1596 if (port->count > 1) {
1597 port->count--;
1598 bp->count--;
1600 spin_unlock_irqrestore(&port->lock, flags);
1602 func_exit();
1603 return;
1605 port->flags |= ASYNC_CLOSING;
1607 * Now we wait for the transmit buffer to clear; and we notify
1608 * the line discipline to only process XON/XOFF characters.
1610 tty->closing = 1;
1611 spin_unlock_irqrestore(&port->lock, flags);
1612 dprintk (SX_DEBUG_OPEN, "Closing\n");
1613 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
1614 tty_wait_until_sent(tty, port->closing_wait);
1617 * At this point we stop accepting input. To do this, we
1618 * disable the receive line status interrupts, and tell the
1619 * interrupt driver to stop checking the data ready bit in the
1620 * line status register.
1622 dprintk (SX_DEBUG_OPEN, "Closed\n");
1623 port->IER &= ~IER_RXD;
1624 if (port->flags & ASYNC_INITIALIZED) {
1625 port->IER &= ~IER_TXRDY;
1626 port->IER |= IER_TXEMPTY;
1627 spin_lock_irqsave(&bp->lock, flags);
1628 sx_out(bp, CD186x_CAR, port_No(port));
1629 sx_out(bp, CD186x_IER, port->IER);
1630 spin_unlock_irqrestore(&bp->lock, flags);
1632 * Before we drop DTR, make sure the UART transmitter
1633 * has completely drained; this is especially
1634 * important if there is a transmit FIFO!
1636 timeout = jiffies+HZ;
1637 while(port->IER & IER_TXEMPTY) {
1638 set_current_state (TASK_INTERRUPTIBLE);
1639 msleep_interruptible(jiffies_to_msecs(port->timeout));
1640 if (time_after(jiffies, timeout)) {
1641 printk (KERN_INFO "Timeout waiting for close\n");
1642 break;
1648 if (--bp->count < 0) {
1649 printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1650 board_No(bp), bp->count, tty->index);
1651 bp->count = 0;
1653 if (--port->count < 0) {
1654 printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n",
1655 board_No(bp), port_No(port), port->count);
1656 port->count = 0;
1659 sx_shutdown_port(bp, port);
1660 if (tty->driver->flush_buffer)
1661 tty->driver->flush_buffer(tty);
1662 tty_ldisc_flush(tty);
1663 spin_lock_irqsave(&port->lock, flags);
1664 tty->closing = 0;
1665 port->event = 0;
1666 port->tty = NULL;
1667 spin_unlock_irqrestore(&port->lock, flags);
1668 if (port->blocked_open) {
1669 if (port->close_delay) {
1670 msleep_interruptible(jiffies_to_msecs(port->close_delay));
1672 wake_up_interruptible(&port->open_wait);
1674 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1675 wake_up_interruptible(&port->close_wait);
1677 func_exit();
1681 static int sx_write(struct tty_struct * tty,
1682 const unsigned char *buf, int count)
1684 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1685 struct specialix_board *bp;
1686 int c, total = 0;
1687 unsigned long flags;
1689 func_enter();
1690 if (sx_paranoia_check(port, tty->name, "sx_write")) {
1691 func_exit();
1692 return 0;
1695 bp = port_Board(port);
1697 if (!tty || !port->xmit_buf || !tmp_buf) {
1698 func_exit();
1699 return 0;
1702 while (1) {
1703 spin_lock_irqsave(&port->lock, flags);
1704 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1705 SERIAL_XMIT_SIZE - port->xmit_head));
1706 if (c <= 0) {
1707 spin_unlock_irqrestore(&port->lock, flags);
1708 break;
1710 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1711 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1712 port->xmit_cnt += c;
1713 spin_unlock_irqrestore(&port->lock, flags);
1715 buf += c;
1716 count -= c;
1717 total += c;
1720 spin_lock_irqsave(&bp->lock, flags);
1721 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1722 !(port->IER & IER_TXRDY)) {
1723 port->IER |= IER_TXRDY;
1724 sx_out(bp, CD186x_CAR, port_No(port));
1725 sx_out(bp, CD186x_IER, port->IER);
1727 spin_unlock_irqrestore(&bp->lock, flags);
1728 func_exit();
1730 return total;
1734 static void sx_put_char(struct tty_struct * tty, unsigned char ch)
1736 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1737 unsigned long flags;
1738 struct specialix_board * bp;
1740 func_enter();
1742 if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1743 func_exit();
1744 return;
1746 dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1747 if (!tty || !port->xmit_buf) {
1748 func_exit();
1749 return;
1751 bp = port_Board(port);
1752 spin_lock_irqsave(&port->lock, flags);
1754 dprintk (SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", port->xmit_cnt, port->xmit_buf);
1755 if ((port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) || (!port->xmit_buf)) {
1756 spin_unlock_irqrestore(&port->lock, flags);
1757 dprintk (SX_DEBUG_TX, "Exit size\n");
1758 func_exit();
1759 return;
1761 dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
1762 port->xmit_buf[port->xmit_head++] = ch;
1763 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1764 port->xmit_cnt++;
1765 spin_unlock_irqrestore(&port->lock, flags);
1767 func_exit();
1771 static void sx_flush_chars(struct tty_struct * tty)
1773 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1774 unsigned long flags;
1775 struct specialix_board * bp = port_Board(port);
1777 func_enter();
1779 if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1780 func_exit();
1781 return;
1783 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1784 !port->xmit_buf) {
1785 func_exit();
1786 return;
1788 spin_lock_irqsave(&bp->lock, flags);
1789 port->IER |= IER_TXRDY;
1790 sx_out(port_Board(port), CD186x_CAR, port_No(port));
1791 sx_out(port_Board(port), CD186x_IER, port->IER);
1792 spin_unlock_irqrestore(&bp->lock, flags);
1794 func_exit();
1798 static int sx_write_room(struct tty_struct * tty)
1800 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1801 int ret;
1803 func_enter();
1805 if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1806 func_exit();
1807 return 0;
1810 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1811 if (ret < 0)
1812 ret = 0;
1814 func_exit();
1815 return ret;
1819 static int sx_chars_in_buffer(struct tty_struct *tty)
1821 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1823 func_enter();
1825 if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
1826 func_exit();
1827 return 0;
1829 func_exit();
1830 return port->xmit_cnt;
1834 static void sx_flush_buffer(struct tty_struct *tty)
1836 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1837 unsigned long flags;
1838 struct specialix_board * bp;
1840 func_enter();
1842 if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
1843 func_exit();
1844 return;
1847 bp = port_Board(port);
1848 spin_lock_irqsave(&port->lock, flags);
1849 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1850 spin_unlock_irqrestore(&port->lock, flags);
1851 tty_wakeup(tty);
1853 func_exit();
1857 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1859 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1860 struct specialix_board * bp;
1861 unsigned char status;
1862 unsigned int result;
1863 unsigned long flags;
1865 func_enter();
1867 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1868 func_exit();
1869 return -ENODEV;
1872 bp = port_Board(port);
1873 spin_lock_irqsave (&bp->lock, flags);
1874 sx_out(bp, CD186x_CAR, port_No(port));
1875 status = sx_in(bp, CD186x_MSVR);
1876 spin_unlock_irqrestore(&bp->lock, flags);
1877 dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1878 port_No(port), status, sx_in (bp, CD186x_CAR));
1879 dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1880 if (SX_CRTSCTS(port->tty)) {
1881 result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
1882 | ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1883 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1884 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1885 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1886 } else {
1887 result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
1888 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1889 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1890 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1891 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1894 func_exit();
1896 return result;
1900 static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1901 unsigned int set, unsigned int clear)
1903 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1904 unsigned long flags;
1905 struct specialix_board *bp;
1907 func_enter();
1909 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1910 func_exit();
1911 return -ENODEV;
1914 bp = port_Board(port);
1916 spin_lock_irqsave(&port->lock, flags);
1917 /* if (set & TIOCM_RTS)
1918 port->MSVR |= MSVR_RTS; */
1919 /* if (set & TIOCM_DTR)
1920 port->MSVR |= MSVR_DTR; */
1922 if (SX_CRTSCTS(port->tty)) {
1923 if (set & TIOCM_RTS)
1924 port->MSVR |= MSVR_DTR;
1925 } else {
1926 if (set & TIOCM_DTR)
1927 port->MSVR |= MSVR_DTR;
1930 /* if (clear & TIOCM_RTS)
1931 port->MSVR &= ~MSVR_RTS; */
1932 /* if (clear & TIOCM_DTR)
1933 port->MSVR &= ~MSVR_DTR; */
1934 if (SX_CRTSCTS(port->tty)) {
1935 if (clear & TIOCM_RTS)
1936 port->MSVR &= ~MSVR_DTR;
1937 } else {
1938 if (clear & TIOCM_DTR)
1939 port->MSVR &= ~MSVR_DTR;
1941 spin_lock_irqsave(&bp->lock, flags);
1942 sx_out(bp, CD186x_CAR, port_No(port));
1943 sx_out(bp, CD186x_MSVR, port->MSVR);
1944 spin_unlock_irqrestore(&bp->lock, flags);
1945 spin_unlock_irqrestore(&port->lock, flags);
1946 func_exit();
1947 return 0;
1951 static inline void sx_send_break(struct specialix_port * port, unsigned long length)
1953 struct specialix_board *bp = port_Board(port);
1954 unsigned long flags;
1956 func_enter();
1958 spin_lock_irqsave (&port->lock, flags);
1959 port->break_length = SPECIALIX_TPS / HZ * length;
1960 port->COR2 |= COR2_ETC;
1961 port->IER |= IER_TXRDY;
1962 spin_lock_irqsave(&bp->lock, flags);
1963 sx_out(bp, CD186x_CAR, port_No(port));
1964 sx_out(bp, CD186x_COR2, port->COR2);
1965 sx_out(bp, CD186x_IER, port->IER);
1966 spin_unlock_irqrestore(&bp->lock, flags);
1967 spin_unlock_irqrestore (&port->lock, flags);
1968 sx_wait_CCR(bp);
1969 spin_lock_irqsave(&bp->lock, flags);
1970 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1971 spin_unlock_irqrestore(&bp->lock, flags);
1972 sx_wait_CCR(bp);
1974 func_exit();
1978 static inline int sx_set_serial_info(struct specialix_port * port,
1979 struct serial_struct __user * newinfo)
1981 struct serial_struct tmp;
1982 struct specialix_board *bp = port_Board(port);
1983 int change_speed;
1985 func_enter();
1987 if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1988 func_exit();
1989 return -EFAULT;
1992 if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
1993 func_enter();
1994 return -EFAULT;
1997 #if 0
1998 if ((tmp.irq != bp->irq) ||
1999 (tmp.port != bp->base) ||
2000 (tmp.type != PORT_CIRRUS) ||
2001 (tmp.baud_base != (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) ||
2002 (tmp.custom_divisor != 0) ||
2003 (tmp.xmit_fifo_size != CD186x_NFIFO) ||
2004 (tmp.flags & ~SPECIALIX_LEGAL_FLAGS)) {
2005 func_exit();
2006 return -EINVAL;
2008 #endif
2010 change_speed = ((port->flags & ASYNC_SPD_MASK) !=
2011 (tmp.flags & ASYNC_SPD_MASK));
2012 change_speed |= (tmp.custom_divisor != port->custom_divisor);
2014 if (!capable(CAP_SYS_ADMIN)) {
2015 if ((tmp.close_delay != port->close_delay) ||
2016 (tmp.closing_wait != port->closing_wait) ||
2017 ((tmp.flags & ~ASYNC_USR_MASK) !=
2018 (port->flags & ~ASYNC_USR_MASK))) {
2019 func_exit();
2020 return -EPERM;
2022 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
2023 (tmp.flags & ASYNC_USR_MASK));
2024 port->custom_divisor = tmp.custom_divisor;
2025 } else {
2026 port->flags = ((port->flags & ~ASYNC_FLAGS) |
2027 (tmp.flags & ASYNC_FLAGS));
2028 port->close_delay = tmp.close_delay;
2029 port->closing_wait = tmp.closing_wait;
2030 port->custom_divisor = tmp.custom_divisor;
2032 if (change_speed) {
2033 sx_change_speed(bp, port);
2035 func_exit();
2036 return 0;
2040 static inline int sx_get_serial_info(struct specialix_port * port,
2041 struct serial_struct __user *retinfo)
2043 struct serial_struct tmp;
2044 struct specialix_board *bp = port_Board(port);
2046 func_enter();
2049 if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
2050 return -EFAULT;
2053 memset(&tmp, 0, sizeof(tmp));
2054 tmp.type = PORT_CIRRUS;
2055 tmp.line = port - sx_port;
2056 tmp.port = bp->base;
2057 tmp.irq = bp->irq;
2058 tmp.flags = port->flags;
2059 tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
2060 tmp.close_delay = port->close_delay * HZ/100;
2061 tmp.closing_wait = port->closing_wait * HZ/100;
2062 tmp.custom_divisor = port->custom_divisor;
2063 tmp.xmit_fifo_size = CD186x_NFIFO;
2064 if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
2065 func_exit();
2066 return -EFAULT;
2069 func_exit();
2070 return 0;
2074 static int sx_ioctl(struct tty_struct * tty, struct file * filp,
2075 unsigned int cmd, unsigned long arg)
2077 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2078 int retval;
2079 void __user *argp = (void __user *)arg;
2081 func_enter();
2083 if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
2084 func_exit();
2085 return -ENODEV;
2088 switch (cmd) {
2089 case TCSBRK: /* SVID version: non-zero arg --> no break */
2090 retval = tty_check_change(tty);
2091 if (retval) {
2092 func_exit();
2093 return retval;
2095 tty_wait_until_sent(tty, 0);
2096 if (!arg)
2097 sx_send_break(port, HZ/4); /* 1/4 second */
2098 return 0;
2099 case TCSBRKP: /* support for POSIX tcsendbreak() */
2100 retval = tty_check_change(tty);
2101 if (retval) {
2102 func_exit();
2103 return retval;
2105 tty_wait_until_sent(tty, 0);
2106 sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
2107 func_exit();
2108 return 0;
2109 case TIOCGSOFTCAR:
2110 if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) {
2111 func_exit();
2112 return -EFAULT;
2114 func_exit();
2115 return 0;
2116 case TIOCSSOFTCAR:
2117 if (get_user(arg, (unsigned long __user *) argp)) {
2118 func_exit();
2119 return -EFAULT;
2121 tty->termios->c_cflag =
2122 ((tty->termios->c_cflag & ~CLOCAL) |
2123 (arg ? CLOCAL : 0));
2124 func_exit();
2125 return 0;
2126 case TIOCGSERIAL:
2127 func_exit();
2128 return sx_get_serial_info(port, argp);
2129 case TIOCSSERIAL:
2130 func_exit();
2131 return sx_set_serial_info(port, argp);
2132 default:
2133 func_exit();
2134 return -ENOIOCTLCMD;
2136 func_exit();
2137 return 0;
2141 static void sx_throttle(struct tty_struct * tty)
2143 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2144 struct specialix_board *bp;
2145 unsigned long flags;
2147 func_enter();
2149 if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
2150 func_exit();
2151 return;
2154 bp = port_Board(port);
2156 /* Use DTR instead of RTS ! */
2157 if (SX_CRTSCTS (tty))
2158 port->MSVR &= ~MSVR_DTR;
2159 else {
2160 /* Auch!!! I think the system shouldn't call this then. */
2161 /* Or maybe we're supposed (allowed?) to do our side of hw
2162 handshake anyway, even when hardware handshake is off.
2163 When you see this in your logs, please report.... */
2164 printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
2165 port_No (port));
2167 spin_lock_irqsave(&bp->lock, flags);
2168 sx_out(bp, CD186x_CAR, port_No(port));
2169 spin_unlock_irqrestore(&bp->lock, flags);
2170 if (I_IXOFF(tty)) {
2171 spin_unlock_irqrestore(&bp->lock, flags);
2172 sx_wait_CCR(bp);
2173 spin_lock_irqsave(&bp->lock, flags);
2174 sx_out(bp, CD186x_CCR, CCR_SSCH2);
2175 spin_unlock_irqrestore(&bp->lock, flags);
2176 sx_wait_CCR(bp);
2178 spin_lock_irqsave(&bp->lock, flags);
2179 sx_out(bp, CD186x_MSVR, port->MSVR);
2180 spin_unlock_irqrestore(&bp->lock, flags);
2182 func_exit();
2186 static void sx_unthrottle(struct tty_struct * tty)
2188 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2189 struct specialix_board *bp;
2190 unsigned long flags;
2192 func_enter();
2194 if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
2195 func_exit();
2196 return;
2199 bp = port_Board(port);
2201 spin_lock_irqsave(&port->lock, flags);
2202 /* XXXX Use DTR INSTEAD???? */
2203 if (SX_CRTSCTS(tty)) {
2204 port->MSVR |= MSVR_DTR;
2205 } /* Else clause: see remark in "sx_throttle"... */
2206 spin_lock_irqsave(&bp->lock, flags);
2207 sx_out(bp, CD186x_CAR, port_No(port));
2208 spin_unlock_irqrestore(&bp->lock, flags);
2209 if (I_IXOFF(tty)) {
2210 spin_unlock_irqrestore(&port->lock, flags);
2211 sx_wait_CCR(bp);
2212 spin_lock_irqsave(&bp->lock, flags);
2213 sx_out(bp, CD186x_CCR, CCR_SSCH1);
2214 spin_unlock_irqrestore(&bp->lock, flags);
2215 sx_wait_CCR(bp);
2216 spin_lock_irqsave(&port->lock, flags);
2218 spin_lock_irqsave(&bp->lock, flags);
2219 sx_out(bp, CD186x_MSVR, port->MSVR);
2220 spin_unlock_irqrestore(&bp->lock, flags);
2221 spin_unlock_irqrestore(&port->lock, flags);
2223 func_exit();
2227 static void sx_stop(struct tty_struct * tty)
2229 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2230 struct specialix_board *bp;
2231 unsigned long flags;
2233 func_enter();
2235 if (sx_paranoia_check(port, tty->name, "sx_stop")) {
2236 func_exit();
2237 return;
2240 bp = port_Board(port);
2242 spin_lock_irqsave(&port->lock, flags);
2243 port->IER &= ~IER_TXRDY;
2244 spin_lock_irqsave(&bp->lock, flags);
2245 sx_out(bp, CD186x_CAR, port_No(port));
2246 sx_out(bp, CD186x_IER, port->IER);
2247 spin_unlock_irqrestore(&bp->lock, flags);
2248 spin_unlock_irqrestore(&port->lock, flags);
2250 func_exit();
2254 static void sx_start(struct tty_struct * tty)
2256 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2257 struct specialix_board *bp;
2258 unsigned long flags;
2260 func_enter();
2262 if (sx_paranoia_check(port, tty->name, "sx_start")) {
2263 func_exit();
2264 return;
2267 bp = port_Board(port);
2269 spin_lock_irqsave(&port->lock, flags);
2270 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2271 port->IER |= IER_TXRDY;
2272 spin_lock_irqsave(&bp->lock, flags);
2273 sx_out(bp, CD186x_CAR, port_No(port));
2274 sx_out(bp, CD186x_IER, port->IER);
2275 spin_unlock_irqrestore(&bp->lock, flags);
2277 spin_unlock_irqrestore(&port->lock, flags);
2279 func_exit();
2284 * This routine is called from the work-queue when the interrupt
2285 * routine has signalled that a hangup has occurred. The path of
2286 * hangup processing is:
2288 * serial interrupt routine -> (workqueue) ->
2289 * do_sx_hangup() -> tty->hangup() -> sx_hangup()
2292 static void do_sx_hangup(void *private_)
2294 struct specialix_port *port = (struct specialix_port *) private_;
2295 struct tty_struct *tty;
2297 func_enter();
2299 tty = port->tty;
2300 if (tty)
2301 tty_hangup(tty); /* FIXME: module removal race here */
2303 func_exit();
2307 static void sx_hangup(struct tty_struct * tty)
2309 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2310 struct specialix_board *bp;
2311 unsigned long flags;
2313 func_enter();
2315 if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2316 func_exit();
2317 return;
2320 bp = port_Board(port);
2322 sx_shutdown_port(bp, port);
2323 spin_lock_irqsave(&port->lock, flags);
2324 port->event = 0;
2325 bp->count -= port->count;
2326 if (bp->count < 0) {
2327 printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n",
2328 board_No(bp), bp->count, tty->index);
2329 bp->count = 0;
2331 port->count = 0;
2332 port->flags &= ~ASYNC_NORMAL_ACTIVE;
2333 port->tty = NULL;
2334 spin_unlock_irqrestore(&port->lock, flags);
2335 wake_up_interruptible(&port->open_wait);
2337 func_exit();
2341 static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios)
2343 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2344 unsigned long flags;
2345 struct specialix_board * bp;
2347 if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2348 return;
2350 if (tty->termios->c_cflag == old_termios->c_cflag &&
2351 tty->termios->c_iflag == old_termios->c_iflag)
2352 return;
2354 bp = port_Board(port);
2355 spin_lock_irqsave(&port->lock, flags);
2356 sx_change_speed(port_Board(port), port);
2357 spin_unlock_irqrestore(&port->lock, flags);
2359 if ((old_termios->c_cflag & CRTSCTS) &&
2360 !(tty->termios->c_cflag & CRTSCTS)) {
2361 tty->hw_stopped = 0;
2362 sx_start(tty);
2367 static void do_softint(void *private_)
2369 struct specialix_port *port = (struct specialix_port *) private_;
2370 struct tty_struct *tty;
2372 func_enter();
2374 if(!(tty = port->tty)) {
2375 func_exit();
2376 return;
2379 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
2380 tty_wakeup(tty);
2381 //wake_up_interruptible(&tty->write_wait);
2384 func_exit();
2387 static struct tty_operations sx_ops = {
2388 .open = sx_open,
2389 .close = sx_close,
2390 .write = sx_write,
2391 .put_char = sx_put_char,
2392 .flush_chars = sx_flush_chars,
2393 .write_room = sx_write_room,
2394 .chars_in_buffer = sx_chars_in_buffer,
2395 .flush_buffer = sx_flush_buffer,
2396 .ioctl = sx_ioctl,
2397 .throttle = sx_throttle,
2398 .unthrottle = sx_unthrottle,
2399 .set_termios = sx_set_termios,
2400 .stop = sx_stop,
2401 .start = sx_start,
2402 .hangup = sx_hangup,
2403 .tiocmget = sx_tiocmget,
2404 .tiocmset = sx_tiocmset,
2407 static int sx_init_drivers(void)
2409 int error;
2410 int i;
2412 func_enter();
2414 specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT);
2415 if (!specialix_driver) {
2416 printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n");
2417 func_exit();
2418 return 1;
2421 if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
2422 printk(KERN_ERR "sx: Couldn't get free page.\n");
2423 put_tty_driver(specialix_driver);
2424 func_exit();
2425 return 1;
2427 specialix_driver->owner = THIS_MODULE;
2428 specialix_driver->name = "ttyW";
2429 specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
2430 specialix_driver->type = TTY_DRIVER_TYPE_SERIAL;
2431 specialix_driver->subtype = SERIAL_TYPE_NORMAL;
2432 specialix_driver->init_termios = tty_std_termios;
2433 specialix_driver->init_termios.c_cflag =
2434 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2435 specialix_driver->flags = TTY_DRIVER_REAL_RAW;
2436 tty_set_operations(specialix_driver, &sx_ops);
2438 if ((error = tty_register_driver(specialix_driver))) {
2439 put_tty_driver(specialix_driver);
2440 free_page((unsigned long)tmp_buf);
2441 printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2442 error);
2443 func_exit();
2444 return 1;
2446 memset(sx_port, 0, sizeof(sx_port));
2447 for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2448 sx_port[i].magic = SPECIALIX_MAGIC;
2449 INIT_WORK(&sx_port[i].tqueue, do_softint, &sx_port[i]);
2450 INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup, &sx_port[i]);
2451 sx_port[i].close_delay = 50 * HZ/100;
2452 sx_port[i].closing_wait = 3000 * HZ/100;
2453 init_waitqueue_head(&sx_port[i].open_wait);
2454 init_waitqueue_head(&sx_port[i].close_wait);
2455 spin_lock_init(&sx_port[i].lock);
2458 func_exit();
2459 return 0;
2462 static void sx_release_drivers(void)
2464 func_enter();
2466 free_page((unsigned long)tmp_buf);
2467 tty_unregister_driver(specialix_driver);
2468 put_tty_driver(specialix_driver);
2469 func_exit();
2473 * This routine must be called by kernel at boot time
2475 static int __init specialix_init(void)
2477 int i;
2478 int found = 0;
2480 func_enter();
2482 printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
2483 printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2484 #ifdef CONFIG_SPECIALIX_RTSCTS
2485 printk (KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
2486 #else
2487 printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2488 #endif
2490 for (i = 0; i < SX_NBOARD; i++)
2491 sx_board[i].lock = SPIN_LOCK_UNLOCKED;
2493 if (sx_init_drivers()) {
2494 func_exit();
2495 return -EIO;
2498 for (i = 0; i < SX_NBOARD; i++)
2499 if (sx_board[i].base && !sx_probe(&sx_board[i]))
2500 found++;
2502 #ifdef CONFIG_PCI
2504 struct pci_dev *pdev = NULL;
2506 i=0;
2507 while (i < SX_NBOARD) {
2508 if (sx_board[i].flags & SX_BOARD_PRESENT) {
2509 i++;
2510 continue;
2512 pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
2513 PCI_DEVICE_ID_SPECIALIX_IO8,
2514 pdev);
2515 if (!pdev) break;
2517 if (pci_enable_device(pdev))
2518 continue;
2520 sx_board[i].irq = pdev->irq;
2522 sx_board[i].base = pci_resource_start (pdev, 2);
2524 sx_board[i].flags |= SX_BOARD_IS_PCI;
2525 if (!sx_probe(&sx_board[i]))
2526 found ++;
2529 #endif
2531 if (!found) {
2532 sx_release_drivers();
2533 printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
2534 func_exit();
2535 return -EIO;
2538 func_exit();
2539 return 0;
2542 static int iobase[SX_NBOARD] = {0,};
2544 static int irq [SX_NBOARD] = {0,};
2546 module_param_array(iobase, int, NULL, 0);
2547 module_param_array(irq, int, NULL, 0);
2548 module_param(sx_debug, int, 0);
2549 module_param(sx_rxfifo, int, 0);
2550 #ifdef SPECIALIX_TIMER
2551 module_param(sx_poll, int, 0);
2552 #endif
2555 * You can setup up to 4 boards.
2556 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2557 * You should specify the IRQs too in that case "irq=....,...".
2559 * More than 4 boards in one computer is not possible, as the card can
2560 * only use 4 different interrupts.
2563 static int __init specialix_init_module(void)
2565 int i;
2567 func_enter();
2569 init_MUTEX(&tmp_buf_sem); /* Init de the semaphore - pvdl */
2571 if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2572 for(i = 0; i < SX_NBOARD; i++) {
2573 sx_board[i].base = iobase[i];
2574 sx_board[i].irq = irq[i];
2575 sx_board[i].count= 0;
2579 func_exit();
2581 return specialix_init();
2584 static void __exit specialix_exit_module(void)
2586 int i;
2588 func_enter();
2590 sx_release_drivers();
2591 for (i = 0; i < SX_NBOARD; i++)
2592 if (sx_board[i].flags & SX_BOARD_PRESENT)
2593 sx_release_io_range(&sx_board[i]);
2594 #ifdef SPECIALIX_TIMER
2595 del_timer (&missed_irq_timer);
2596 #endif
2598 func_exit();
2601 module_init(specialix_init_module);
2602 module_exit(specialix_exit_module);
2604 MODULE_LICENSE("GPL");