[PATCH] remove unused tmp_buf_sem's
[linux-2.6/suspend2-2.6.18.git] / drivers / char / specialix.c
blob5343e9fc6ab7e721dc1a578e6a6e81e044549490
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/tty_flip.h>
89 #include <linux/mm.h>
90 #include <linux/serial.h>
91 #include <linux/fcntl.h>
92 #include <linux/major.h>
93 #include <linux/delay.h>
94 #include <linux/pci.h>
95 #include <linux/init.h>
96 #include <asm/uaccess.h>
98 #include "specialix_io8.h"
99 #include "cd1865.h"
103 This driver can spew a whole lot of debugging output at you. If you
104 need maximum performance, you should disable the DEBUG define. To
105 aid in debugging in the field, I'm leaving the compile-time debug
106 features enabled, and disable them "runtime". That allows me to
107 instruct people with problems to enable debugging without requiring
108 them to recompile...
110 #define DEBUG
112 static int sx_debug;
113 static int sx_rxfifo = SPECIALIX_RXFIFO;
115 #ifdef DEBUG
116 #define dprintk(f, str...) if (sx_debug & f) printk (str)
117 #else
118 #define dprintk(f, str...) /* nothing */
119 #endif
121 #define SX_DEBUG_FLOW 0x0001
122 #define SX_DEBUG_DATA 0x0002
123 #define SX_DEBUG_PROBE 0x0004
124 #define SX_DEBUG_CHAN 0x0008
125 #define SX_DEBUG_INIT 0x0010
126 #define SX_DEBUG_RX 0x0020
127 #define SX_DEBUG_TX 0x0040
128 #define SX_DEBUG_IRQ 0x0080
129 #define SX_DEBUG_OPEN 0x0100
130 #define SX_DEBUG_TERMIOS 0x0200
131 #define SX_DEBUG_SIGNALS 0x0400
132 #define SX_DEBUG_FIFO 0x0800
135 #define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__FUNCTION__)
136 #define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __FUNCTION__)
138 #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
141 /* Configurable options: */
143 /* Am I paranoid or not ? ;-) */
144 #define SPECIALIX_PARANOIA_CHECK
146 /* Do I trust the IRQ from the card? (enabeling it doesn't seem to help)
147 When the IRQ routine leaves the chip in a state that is keeps on
148 requiring attention, the timer doesn't help either. */
149 #undef SPECIALIX_TIMER
151 #ifdef SPECIALIX_TIMER
152 static int sx_poll = HZ;
153 #endif
158 * The following defines are mostly for testing purposes. But if you need
159 * some nice reporting in your syslog, you can define them also.
161 #undef SX_REPORT_FIFO
162 #undef SX_REPORT_OVERRUN
166 #ifdef CONFIG_SPECIALIX_RTSCTS
167 #define SX_CRTSCTS(bla) 1
168 #else
169 #define SX_CRTSCTS(tty) C_CRTSCTS(tty)
170 #endif
173 /* Used to be outb (0xff, 0x80); */
174 #define short_pause() udelay (1)
177 #define SPECIALIX_LEGAL_FLAGS \
178 (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \
179 ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \
180 ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
182 #undef RS_EVENT_WRITE_WAKEUP
183 #define RS_EVENT_WRITE_WAKEUP 0
185 static struct tty_driver *specialix_driver;
186 static unsigned char * tmp_buf;
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, flag;
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;
680 status = sx_in(bp, CD186x_RCSR);
682 dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
683 if (status & RCSR_OE) {
684 port->overrun++;
685 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Overrun. Total %ld overruns.\n",
686 board_No(bp), port_No(port), port->overrun);
688 status &= port->mark_mask;
690 /* This flip buffer check needs to be below the reading of the
691 status register to reset the chip's IRQ.... */
692 if (tty_buffer_request_room(tty, 1) == 0) {
693 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n",
694 board_No(bp), port_No(port));
695 func_exit();
696 return;
699 ch = sx_in(bp, CD186x_RDR);
700 if (!status) {
701 func_exit();
702 return;
704 if (status & RCSR_TOUT) {
705 printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
706 board_No(bp), port_No(port));
707 func_exit();
708 return;
710 } else if (status & RCSR_BREAK) {
711 dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
712 board_No(bp), port_No(port));
713 flag = TTY_BREAK;
714 if (port->flags & ASYNC_SAK)
715 do_SAK(tty);
717 } else if (status & RCSR_PE)
718 flag = TTY_PARITY;
720 else if (status & RCSR_FE)
721 flag = TTY_FRAME;
723 else if (status & RCSR_OE)
724 flag = TTY_OVERRUN;
726 else
727 flag = TTY_NORMAL;
729 if(tty_insert_flip_char(tty, ch, flag))
730 tty_flip_buffer_push(tty);
731 func_exit();
735 static inline void sx_receive(struct specialix_board * bp)
737 struct specialix_port *port;
738 struct tty_struct *tty;
739 unsigned char count;
741 func_enter();
743 if (!(port = sx_get_port(bp, "Receive"))) {
744 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
745 func_exit();
746 return;
748 tty = port->tty;
750 count = sx_in(bp, CD186x_RDCR);
751 dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
752 port->hits[count > 8 ? 9 : count]++;
754 tty_buffer_request_room(tty, count);
756 while (count--)
757 tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL);
758 tty_flip_buffer_push(tty);
759 func_exit();
763 static inline void sx_transmit(struct specialix_board * bp)
765 struct specialix_port *port;
766 struct tty_struct *tty;
767 unsigned char count;
769 func_enter();
770 if (!(port = sx_get_port(bp, "Transmit"))) {
771 func_exit();
772 return;
774 dprintk (SX_DEBUG_TX, "port: %p\n", port);
775 tty = port->tty;
777 if (port->IER & IER_TXEMPTY) {
778 /* FIFO drained */
779 sx_out(bp, CD186x_CAR, port_No(port));
780 port->IER &= ~IER_TXEMPTY;
781 sx_out(bp, CD186x_IER, port->IER);
782 func_exit();
783 return;
786 if ((port->xmit_cnt <= 0 && !port->break_length)
787 || tty->stopped || tty->hw_stopped) {
788 sx_out(bp, CD186x_CAR, port_No(port));
789 port->IER &= ~IER_TXRDY;
790 sx_out(bp, CD186x_IER, port->IER);
791 func_exit();
792 return;
795 if (port->break_length) {
796 if (port->break_length > 0) {
797 if (port->COR2 & COR2_ETC) {
798 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
799 sx_out(bp, CD186x_TDR, CD186x_C_SBRK);
800 port->COR2 &= ~COR2_ETC;
802 count = min_t(int, port->break_length, 0xff);
803 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
804 sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
805 sx_out(bp, CD186x_TDR, count);
806 if (!(port->break_length -= count))
807 port->break_length--;
808 } else {
809 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
810 sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
811 sx_out(bp, CD186x_COR2, port->COR2);
812 sx_wait_CCR(bp);
813 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
814 port->break_length = 0;
817 func_exit();
818 return;
821 count = CD186x_NFIFO;
822 do {
823 sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
824 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
825 if (--port->xmit_cnt <= 0)
826 break;
827 } while (--count > 0);
829 if (port->xmit_cnt <= 0) {
830 sx_out(bp, CD186x_CAR, port_No(port));
831 port->IER &= ~IER_TXRDY;
832 sx_out(bp, CD186x_IER, port->IER);
834 if (port->xmit_cnt <= port->wakeup_chars)
835 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
837 func_exit();
841 static inline void sx_check_modem(struct specialix_board * bp)
843 struct specialix_port *port;
844 struct tty_struct *tty;
845 unsigned char mcr;
846 int msvr_cd;
848 dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
849 if (!(port = sx_get_port(bp, "Modem")))
850 return;
852 tty = port->tty;
854 mcr = sx_in(bp, CD186x_MCR);
855 printk ("mcr = %02x.\n", mcr);
857 if ((mcr & MCR_CDCHG)) {
858 dprintk (SX_DEBUG_SIGNALS, "CD just changed... ");
859 msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
860 if (msvr_cd) {
861 dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
862 wake_up_interruptible(&port->open_wait);
863 } else {
864 dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n");
865 schedule_work(&port->tqueue_hangup);
869 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
870 if (mcr & MCR_CTSCHG) {
871 if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
872 tty->hw_stopped = 0;
873 port->IER |= IER_TXRDY;
874 if (port->xmit_cnt <= port->wakeup_chars)
875 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
876 } else {
877 tty->hw_stopped = 1;
878 port->IER &= ~IER_TXRDY;
880 sx_out(bp, CD186x_IER, port->IER);
882 if (mcr & MCR_DSSXHG) {
883 if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
884 tty->hw_stopped = 0;
885 port->IER |= IER_TXRDY;
886 if (port->xmit_cnt <= port->wakeup_chars)
887 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
888 } else {
889 tty->hw_stopped = 1;
890 port->IER &= ~IER_TXRDY;
892 sx_out(bp, CD186x_IER, port->IER);
894 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
896 /* Clear change bits */
897 sx_out(bp, CD186x_MCR, 0);
901 /* The main interrupt processing routine */
902 static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
904 unsigned char status;
905 unsigned char ack;
906 struct specialix_board *bp;
907 unsigned long loop = 0;
908 int saved_reg;
909 unsigned long flags;
911 func_enter();
913 bp = dev_id;
914 spin_lock_irqsave(&bp->lock, flags);
916 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);
917 if (!bp || !(bp->flags & SX_BOARD_ACTIVE)) {
918 dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq);
919 spin_unlock_irqrestore(&bp->lock, flags);
920 func_exit();
921 return IRQ_NONE;
924 saved_reg = bp->reg;
926 while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
927 (SRSR_RREQint |
928 SRSR_TREQint |
929 SRSR_MREQint)))) {
930 if (status & SRSR_RREQint) {
931 ack = sx_in(bp, CD186x_RRAR);
933 if (ack == (SX_ID | GIVR_IT_RCV))
934 sx_receive(bp);
935 else if (ack == (SX_ID | GIVR_IT_REXC))
936 sx_receive_exc(bp);
937 else
938 printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
939 board_No(bp), status, ack);
941 } else if (status & SRSR_TREQint) {
942 ack = sx_in(bp, CD186x_TRAR);
944 if (ack == (SX_ID | GIVR_IT_TX))
945 sx_transmit(bp);
946 else
947 printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
948 board_No(bp), status, ack, port_No (sx_get_port (bp, "Int")));
949 } else if (status & SRSR_MREQint) {
950 ack = sx_in(bp, CD186x_MRAR);
952 if (ack == (SX_ID | GIVR_IT_MODEM))
953 sx_check_modem(bp);
954 else
955 printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
956 board_No(bp), status, ack);
960 sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
962 bp->reg = saved_reg;
963 outb (bp->reg, bp->base + SX_ADDR_REG);
964 spin_unlock_irqrestore(&bp->lock, flags);
965 func_exit();
966 return IRQ_HANDLED;
971 * Routines for open & close processing.
974 static void turn_ints_off (struct specialix_board *bp)
976 unsigned long flags;
978 func_enter();
979 if (bp->flags & SX_BOARD_IS_PCI) {
980 /* This was intended for enabeling the interrupt on the
981 * PCI card. However it seems that it's already enabled
982 * and as PCI interrupts can be shared, there is no real
983 * reason to have to turn it off. */
986 spin_lock_irqsave(&bp->lock, flags);
987 (void) sx_in_off (bp, 0); /* Turn off interrupts. */
988 spin_unlock_irqrestore(&bp->lock, flags);
990 func_exit();
993 static void turn_ints_on (struct specialix_board *bp)
995 unsigned long flags;
997 func_enter();
999 if (bp->flags & SX_BOARD_IS_PCI) {
1000 /* play with the PCI chip. See comment above. */
1002 spin_lock_irqsave(&bp->lock, flags);
1003 (void) sx_in (bp, 0); /* Turn ON interrupts. */
1004 spin_unlock_irqrestore(&bp->lock, flags);
1006 func_exit();
1010 /* Called with disabled interrupts */
1011 static inline int sx_setup_board(struct specialix_board * bp)
1013 int error;
1015 if (bp->flags & SX_BOARD_ACTIVE)
1016 return 0;
1018 if (bp->flags & SX_BOARD_IS_PCI)
1019 error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT | SA_SHIRQ, "specialix IO8+", bp);
1020 else
1021 error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT, "specialix IO8+", bp);
1023 if (error)
1024 return error;
1026 turn_ints_on (bp);
1027 bp->flags |= SX_BOARD_ACTIVE;
1029 return 0;
1033 /* Called with disabled interrupts */
1034 static inline void sx_shutdown_board(struct specialix_board *bp)
1036 func_enter();
1038 if (!(bp->flags & SX_BOARD_ACTIVE)) {
1039 func_exit();
1040 return;
1043 bp->flags &= ~SX_BOARD_ACTIVE;
1045 dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
1046 bp->irq, board_No (bp));
1047 free_irq(bp->irq, bp);
1049 turn_ints_off (bp);
1052 func_exit();
1057 * Setting up port characteristics.
1058 * Must be called with disabled interrupts
1060 static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
1062 struct tty_struct *tty;
1063 unsigned long baud;
1064 long tmp;
1065 unsigned char cor1 = 0, cor3 = 0;
1066 unsigned char mcor1 = 0, mcor2 = 0;
1067 static unsigned long again;
1068 unsigned long flags;
1070 func_enter();
1072 if (!(tty = port->tty) || !tty->termios) {
1073 func_exit();
1074 return;
1077 port->IER = 0;
1078 port->COR2 = 0;
1079 /* Select port on the board */
1080 spin_lock_irqsave(&bp->lock, flags);
1081 sx_out(bp, CD186x_CAR, port_No(port));
1083 /* The Specialix board doens't implement the RTS lines.
1084 They are used to set the IRQ level. Don't touch them. */
1085 if (SX_CRTSCTS(tty))
1086 port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1087 else
1088 port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1089 spin_unlock_irqrestore(&bp->lock, flags);
1090 dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
1091 baud = C_BAUD(tty);
1093 if (baud & CBAUDEX) {
1094 baud &= ~CBAUDEX;
1095 if (baud < 1 || baud > 2)
1096 port->tty->termios->c_cflag &= ~CBAUDEX;
1097 else
1098 baud += 15;
1100 if (baud == 15) {
1101 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1102 baud ++;
1103 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1104 baud += 2;
1108 if (!baud_table[baud]) {
1109 /* Drop DTR & exit */
1110 dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
1111 if (!SX_CRTSCTS (tty)) {
1112 port -> MSVR &= ~ MSVR_DTR;
1113 spin_lock_irqsave(&bp->lock, flags);
1114 sx_out(bp, CD186x_MSVR, port->MSVR );
1115 spin_unlock_irqrestore(&bp->lock, flags);
1117 else
1118 dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1119 return;
1120 } else {
1121 /* Set DTR on */
1122 if (!SX_CRTSCTS (tty)) {
1123 port ->MSVR |= MSVR_DTR;
1128 * Now we must calculate some speed depended things
1131 /* Set baud rate for port */
1132 tmp = port->custom_divisor ;
1133 if ( tmp )
1134 printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n"
1135 "This is an untested option, please be carefull.\n",
1136 port_No (port), tmp);
1137 else
1138 tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
1139 CD186x_TPC/2) / CD186x_TPC);
1141 if ((tmp < 0x10) && time_before(again, jiffies)) {
1142 again = jiffies + HZ * 60;
1143 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1144 if (tmp >= 12) {
1145 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1146 "Performance degradation is possible.\n"
1147 "Read specialix.txt for more info.\n",
1148 port_No (port), tmp);
1149 } else {
1150 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1151 "Warning: overstressing Cirrus chip. "
1152 "This might not work.\n"
1153 "Read specialix.txt for more info.\n",
1154 port_No (port), tmp);
1157 spin_lock_irqsave(&bp->lock, flags);
1158 sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1159 sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1160 sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1161 sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1162 spin_unlock_irqrestore(&bp->lock, flags);
1163 if (port->custom_divisor) {
1164 baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
1165 baud = ( baud + 5 ) / 10;
1166 } else
1167 baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */
1169 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1170 tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1171 port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1172 SERIAL_XMIT_SIZE - 1 : tmp);
1174 /* Receiver timeout will be transmission time for 1.5 chars */
1175 tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1176 tmp = (tmp > 0xff) ? 0xff : tmp;
1177 spin_lock_irqsave(&bp->lock, flags);
1178 sx_out(bp, CD186x_RTPR, tmp);
1179 spin_unlock_irqrestore(&bp->lock, flags);
1180 switch (C_CSIZE(tty)) {
1181 case CS5:
1182 cor1 |= COR1_5BITS;
1183 break;
1184 case CS6:
1185 cor1 |= COR1_6BITS;
1186 break;
1187 case CS7:
1188 cor1 |= COR1_7BITS;
1189 break;
1190 case CS8:
1191 cor1 |= COR1_8BITS;
1192 break;
1195 if (C_CSTOPB(tty))
1196 cor1 |= COR1_2SB;
1198 cor1 |= COR1_IGNORE;
1199 if (C_PARENB(tty)) {
1200 cor1 |= COR1_NORMPAR;
1201 if (C_PARODD(tty))
1202 cor1 |= COR1_ODDP;
1203 if (I_INPCK(tty))
1204 cor1 &= ~COR1_IGNORE;
1206 /* Set marking of some errors */
1207 port->mark_mask = RCSR_OE | RCSR_TOUT;
1208 if (I_INPCK(tty))
1209 port->mark_mask |= RCSR_FE | RCSR_PE;
1210 if (I_BRKINT(tty) || I_PARMRK(tty))
1211 port->mark_mask |= RCSR_BREAK;
1212 if (I_IGNPAR(tty))
1213 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1214 if (I_IGNBRK(tty)) {
1215 port->mark_mask &= ~RCSR_BREAK;
1216 if (I_IGNPAR(tty))
1217 /* Real raw mode. Ignore all */
1218 port->mark_mask &= ~RCSR_OE;
1220 /* Enable Hardware Flow Control */
1221 if (C_CRTSCTS(tty)) {
1222 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1223 port->IER |= IER_DSR | IER_CTS;
1224 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1225 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1226 spin_lock_irqsave(&bp->lock, flags);
1227 tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
1228 spin_unlock_irqrestore(&bp->lock, flags);
1229 #else
1230 port->COR2 |= COR2_CTSAE;
1231 #endif
1233 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1234 /* Some people reported that it works, but I still doubt it */
1235 if (I_IXON(tty)) {
1236 port->COR2 |= COR2_TXIBE;
1237 cor3 |= (COR3_FCT | COR3_SCDE);
1238 if (I_IXANY(tty))
1239 port->COR2 |= COR2_IXM;
1240 spin_lock_irqsave(&bp->lock, flags);
1241 sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1242 sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1243 sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1244 sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1245 spin_unlock_irqrestore(&bp->lock, flags);
1247 if (!C_CLOCAL(tty)) {
1248 /* Enable CD check */
1249 port->IER |= IER_CD;
1250 mcor1 |= MCOR1_CDZD;
1251 mcor2 |= MCOR2_CDOD;
1254 if (C_CREAD(tty))
1255 /* Enable receiver */
1256 port->IER |= IER_RXD;
1258 /* Set input FIFO size (1-8 bytes) */
1259 cor3 |= sx_rxfifo;
1260 /* Setting up CD186x channel registers */
1261 spin_lock_irqsave(&bp->lock, flags);
1262 sx_out(bp, CD186x_COR1, cor1);
1263 sx_out(bp, CD186x_COR2, port->COR2);
1264 sx_out(bp, CD186x_COR3, cor3);
1265 spin_unlock_irqrestore(&bp->lock, flags);
1266 /* Make CD186x know about registers change */
1267 sx_wait_CCR(bp);
1268 spin_lock_irqsave(&bp->lock, flags);
1269 sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1270 /* Setting up modem option registers */
1271 dprintk (SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2);
1272 sx_out(bp, CD186x_MCOR1, mcor1);
1273 sx_out(bp, CD186x_MCOR2, mcor2);
1274 spin_unlock_irqrestore(&bp->lock, flags);
1275 /* Enable CD186x transmitter & receiver */
1276 sx_wait_CCR(bp);
1277 spin_lock_irqsave(&bp->lock, flags);
1278 sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1279 /* Enable interrupts */
1280 sx_out(bp, CD186x_IER, port->IER);
1281 /* And finally set the modem lines... */
1282 sx_out(bp, CD186x_MSVR, port->MSVR);
1283 spin_unlock_irqrestore(&bp->lock, flags);
1285 func_exit();
1289 /* Must be called with interrupts enabled */
1290 static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port)
1292 unsigned long flags;
1294 func_enter();
1296 if (port->flags & ASYNC_INITIALIZED) {
1297 func_exit();
1298 return 0;
1301 if (!port->xmit_buf) {
1302 /* We may sleep in get_zeroed_page() */
1303 unsigned long tmp;
1305 if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
1306 func_exit();
1307 return -ENOMEM;
1310 if (port->xmit_buf) {
1311 free_page(tmp);
1312 func_exit();
1313 return -ERESTARTSYS;
1315 port->xmit_buf = (unsigned char *) tmp;
1318 spin_lock_irqsave(&port->lock, flags);
1320 if (port->tty)
1321 clear_bit(TTY_IO_ERROR, &port->tty->flags);
1323 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1324 sx_change_speed(bp, port);
1325 port->flags |= ASYNC_INITIALIZED;
1327 spin_unlock_irqrestore(&port->lock, flags);
1330 func_exit();
1331 return 0;
1335 /* Must be called with interrupts disabled */
1336 static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port)
1338 struct tty_struct *tty;
1339 int i;
1340 unsigned long flags;
1342 func_enter();
1344 if (!(port->flags & ASYNC_INITIALIZED)) {
1345 func_exit();
1346 return;
1349 if (sx_debug & SX_DEBUG_FIFO) {
1350 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
1351 board_No(bp), port_No(port), port->overrun);
1352 for (i = 0; i < 10; i++) {
1353 dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1355 dprintk(SX_DEBUG_FIFO, "].\n");
1358 if (port->xmit_buf) {
1359 free_page((unsigned long) port->xmit_buf);
1360 port->xmit_buf = NULL;
1363 /* Select port */
1364 spin_lock_irqsave(&bp->lock, flags);
1365 sx_out(bp, CD186x_CAR, port_No(port));
1367 if (!(tty = port->tty) || C_HUPCL(tty)) {
1368 /* Drop DTR */
1369 sx_out(bp, CD186x_MSVDTR, 0);
1371 spin_unlock_irqrestore(&bp->lock, flags);
1372 /* Reset port */
1373 sx_wait_CCR(bp);
1374 spin_lock_irqsave(&bp->lock, flags);
1375 sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1376 /* Disable all interrupts from this port */
1377 port->IER = 0;
1378 sx_out(bp, CD186x_IER, port->IER);
1379 spin_unlock_irqrestore(&bp->lock, flags);
1380 if (tty)
1381 set_bit(TTY_IO_ERROR, &tty->flags);
1382 port->flags &= ~ASYNC_INITIALIZED;
1384 if (!bp->count)
1385 sx_shutdown_board(bp);
1386 func_exit();
1390 static int block_til_ready(struct tty_struct *tty, struct file * filp,
1391 struct specialix_port *port)
1393 DECLARE_WAITQUEUE(wait, current);
1394 struct specialix_board *bp = port_Board(port);
1395 int retval;
1396 int do_clocal = 0;
1397 int CD;
1398 unsigned long flags;
1400 func_enter();
1403 * If the device is in the middle of being closed, then block
1404 * until it's done, and then try again.
1406 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
1407 interruptible_sleep_on(&port->close_wait);
1408 if (port->flags & ASYNC_HUP_NOTIFY) {
1409 func_exit();
1410 return -EAGAIN;
1411 } else {
1412 func_exit();
1413 return -ERESTARTSYS;
1418 * If non-blocking mode is set, or the port is not enabled,
1419 * then make the check up front and then exit.
1421 if ((filp->f_flags & O_NONBLOCK) ||
1422 (tty->flags & (1 << TTY_IO_ERROR))) {
1423 port->flags |= ASYNC_NORMAL_ACTIVE;
1424 func_exit();
1425 return 0;
1428 if (C_CLOCAL(tty))
1429 do_clocal = 1;
1432 * Block waiting for the carrier detect and the line to become
1433 * free (i.e., not in use by the callout). While we are in
1434 * this loop, info->count is dropped by one, so that
1435 * rs_close() knows when to free things. We restore it upon
1436 * exit, either normal or abnormal.
1438 retval = 0;
1439 add_wait_queue(&port->open_wait, &wait);
1440 spin_lock_irqsave(&port->lock, flags);
1441 if (!tty_hung_up_p(filp)) {
1442 port->count--;
1444 spin_unlock_irqrestore(&port->lock, flags);
1445 port->blocked_open++;
1446 while (1) {
1447 spin_lock_irqsave(&bp->lock, flags);
1448 sx_out(bp, CD186x_CAR, port_No(port));
1449 CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1450 if (SX_CRTSCTS (tty)) {
1451 /* Activate RTS */
1452 port->MSVR |= MSVR_DTR; /* WTF? */
1453 sx_out (bp, CD186x_MSVR, port->MSVR);
1454 } else {
1455 /* Activate DTR */
1456 port->MSVR |= MSVR_DTR;
1457 sx_out (bp, CD186x_MSVR, port->MSVR);
1459 spin_unlock_irqrestore(&bp->lock, flags);
1460 set_current_state(TASK_INTERRUPTIBLE);
1461 if (tty_hung_up_p(filp) ||
1462 !(port->flags & ASYNC_INITIALIZED)) {
1463 if (port->flags & ASYNC_HUP_NOTIFY)
1464 retval = -EAGAIN;
1465 else
1466 retval = -ERESTARTSYS;
1467 break;
1469 if (!(port->flags & ASYNC_CLOSING) &&
1470 (do_clocal || CD))
1471 break;
1472 if (signal_pending(current)) {
1473 retval = -ERESTARTSYS;
1474 break;
1476 schedule();
1479 set_current_state(TASK_RUNNING);
1480 remove_wait_queue(&port->open_wait, &wait);
1481 spin_lock_irqsave(&port->lock, flags);
1482 if (!tty_hung_up_p(filp)) {
1483 port->count++;
1485 port->blocked_open--;
1486 spin_unlock_irqrestore(&port->lock, flags);
1487 if (retval) {
1488 func_exit();
1489 return retval;
1492 port->flags |= ASYNC_NORMAL_ACTIVE;
1493 func_exit();
1494 return 0;
1498 static int sx_open(struct tty_struct * tty, struct file * filp)
1500 int board;
1501 int error;
1502 struct specialix_port * port;
1503 struct specialix_board * bp;
1504 int i;
1505 unsigned long flags;
1507 func_enter();
1509 board = SX_BOARD(tty->index);
1511 if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1512 func_exit();
1513 return -ENODEV;
1516 bp = &sx_board[board];
1517 port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1518 port->overrun = 0;
1519 for (i = 0; i < 10; i++)
1520 port->hits[i]=0;
1522 dprintk (SX_DEBUG_OPEN, "Board = %d, bp = %p, port = %p, portno = %d.\n",
1523 board, bp, port, SX_PORT(tty->index));
1525 if (sx_paranoia_check(port, tty->name, "sx_open")) {
1526 func_enter();
1527 return -ENODEV;
1530 if ((error = sx_setup_board(bp))) {
1531 func_exit();
1532 return error;
1535 spin_lock_irqsave(&bp->lock, flags);
1536 port->count++;
1537 bp->count++;
1538 tty->driver_data = port;
1539 port->tty = tty;
1540 spin_unlock_irqrestore(&bp->lock, flags);
1542 if ((error = sx_setup_port(bp, port))) {
1543 func_enter();
1544 return error;
1547 if ((error = block_til_ready(tty, filp, port))) {
1548 func_enter();
1549 return error;
1552 func_exit();
1553 return 0;
1557 static void sx_close(struct tty_struct * tty, struct file * filp)
1559 struct specialix_port *port = (struct specialix_port *) tty->driver_data;
1560 struct specialix_board *bp;
1561 unsigned long flags;
1562 unsigned long timeout;
1564 func_enter();
1565 if (!port || sx_paranoia_check(port, tty->name, "close")) {
1566 func_exit();
1567 return;
1569 spin_lock_irqsave(&port->lock, flags);
1571 if (tty_hung_up_p(filp)) {
1572 spin_unlock_irqrestore(&port->lock, flags);
1573 func_exit();
1574 return;
1577 bp = port_Board(port);
1578 if ((tty->count == 1) && (port->count != 1)) {
1579 printk(KERN_ERR "sx%d: sx_close: bad port count;"
1580 " tty->count is 1, port count is %d\n",
1581 board_No(bp), port->count);
1582 port->count = 1;
1585 if (port->count > 1) {
1586 port->count--;
1587 bp->count--;
1589 spin_unlock_irqrestore(&port->lock, flags);
1591 func_exit();
1592 return;
1594 port->flags |= ASYNC_CLOSING;
1596 * Now we wait for the transmit buffer to clear; and we notify
1597 * the line discipline to only process XON/XOFF characters.
1599 tty->closing = 1;
1600 spin_unlock_irqrestore(&port->lock, flags);
1601 dprintk (SX_DEBUG_OPEN, "Closing\n");
1602 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
1603 tty_wait_until_sent(tty, port->closing_wait);
1606 * At this point we stop accepting input. To do this, we
1607 * disable the receive line status interrupts, and tell the
1608 * interrupt driver to stop checking the data ready bit in the
1609 * line status register.
1611 dprintk (SX_DEBUG_OPEN, "Closed\n");
1612 port->IER &= ~IER_RXD;
1613 if (port->flags & ASYNC_INITIALIZED) {
1614 port->IER &= ~IER_TXRDY;
1615 port->IER |= IER_TXEMPTY;
1616 spin_lock_irqsave(&bp->lock, flags);
1617 sx_out(bp, CD186x_CAR, port_No(port));
1618 sx_out(bp, CD186x_IER, port->IER);
1619 spin_unlock_irqrestore(&bp->lock, flags);
1621 * Before we drop DTR, make sure the UART transmitter
1622 * has completely drained; this is especially
1623 * important if there is a transmit FIFO!
1625 timeout = jiffies+HZ;
1626 while(port->IER & IER_TXEMPTY) {
1627 set_current_state (TASK_INTERRUPTIBLE);
1628 msleep_interruptible(jiffies_to_msecs(port->timeout));
1629 if (time_after(jiffies, timeout)) {
1630 printk (KERN_INFO "Timeout waiting for close\n");
1631 break;
1637 if (--bp->count < 0) {
1638 printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1639 board_No(bp), bp->count, tty->index);
1640 bp->count = 0;
1642 if (--port->count < 0) {
1643 printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n",
1644 board_No(bp), port_No(port), port->count);
1645 port->count = 0;
1648 sx_shutdown_port(bp, port);
1649 if (tty->driver->flush_buffer)
1650 tty->driver->flush_buffer(tty);
1651 tty_ldisc_flush(tty);
1652 spin_lock_irqsave(&port->lock, flags);
1653 tty->closing = 0;
1654 port->event = 0;
1655 port->tty = NULL;
1656 spin_unlock_irqrestore(&port->lock, flags);
1657 if (port->blocked_open) {
1658 if (port->close_delay) {
1659 msleep_interruptible(jiffies_to_msecs(port->close_delay));
1661 wake_up_interruptible(&port->open_wait);
1663 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1664 wake_up_interruptible(&port->close_wait);
1666 func_exit();
1670 static int sx_write(struct tty_struct * tty,
1671 const unsigned char *buf, int count)
1673 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1674 struct specialix_board *bp;
1675 int c, total = 0;
1676 unsigned long flags;
1678 func_enter();
1679 if (sx_paranoia_check(port, tty->name, "sx_write")) {
1680 func_exit();
1681 return 0;
1684 bp = port_Board(port);
1686 if (!tty || !port->xmit_buf || !tmp_buf) {
1687 func_exit();
1688 return 0;
1691 while (1) {
1692 spin_lock_irqsave(&port->lock, flags);
1693 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1694 SERIAL_XMIT_SIZE - port->xmit_head));
1695 if (c <= 0) {
1696 spin_unlock_irqrestore(&port->lock, flags);
1697 break;
1699 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1700 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1701 port->xmit_cnt += c;
1702 spin_unlock_irqrestore(&port->lock, flags);
1704 buf += c;
1705 count -= c;
1706 total += c;
1709 spin_lock_irqsave(&bp->lock, flags);
1710 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1711 !(port->IER & IER_TXRDY)) {
1712 port->IER |= IER_TXRDY;
1713 sx_out(bp, CD186x_CAR, port_No(port));
1714 sx_out(bp, CD186x_IER, port->IER);
1716 spin_unlock_irqrestore(&bp->lock, flags);
1717 func_exit();
1719 return total;
1723 static void sx_put_char(struct tty_struct * tty, unsigned char ch)
1725 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1726 unsigned long flags;
1727 struct specialix_board * bp;
1729 func_enter();
1731 if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1732 func_exit();
1733 return;
1735 dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1736 if (!tty || !port->xmit_buf) {
1737 func_exit();
1738 return;
1740 bp = port_Board(port);
1741 spin_lock_irqsave(&port->lock, flags);
1743 dprintk (SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", port->xmit_cnt, port->xmit_buf);
1744 if ((port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) || (!port->xmit_buf)) {
1745 spin_unlock_irqrestore(&port->lock, flags);
1746 dprintk (SX_DEBUG_TX, "Exit size\n");
1747 func_exit();
1748 return;
1750 dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
1751 port->xmit_buf[port->xmit_head++] = ch;
1752 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1753 port->xmit_cnt++;
1754 spin_unlock_irqrestore(&port->lock, flags);
1756 func_exit();
1760 static void sx_flush_chars(struct tty_struct * tty)
1762 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1763 unsigned long flags;
1764 struct specialix_board * bp = port_Board(port);
1766 func_enter();
1768 if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1769 func_exit();
1770 return;
1772 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1773 !port->xmit_buf) {
1774 func_exit();
1775 return;
1777 spin_lock_irqsave(&bp->lock, flags);
1778 port->IER |= IER_TXRDY;
1779 sx_out(port_Board(port), CD186x_CAR, port_No(port));
1780 sx_out(port_Board(port), CD186x_IER, port->IER);
1781 spin_unlock_irqrestore(&bp->lock, flags);
1783 func_exit();
1787 static int sx_write_room(struct tty_struct * tty)
1789 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1790 int ret;
1792 func_enter();
1794 if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1795 func_exit();
1796 return 0;
1799 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1800 if (ret < 0)
1801 ret = 0;
1803 func_exit();
1804 return ret;
1808 static int sx_chars_in_buffer(struct tty_struct *tty)
1810 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1812 func_enter();
1814 if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
1815 func_exit();
1816 return 0;
1818 func_exit();
1819 return port->xmit_cnt;
1823 static void sx_flush_buffer(struct tty_struct *tty)
1825 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1826 unsigned long flags;
1827 struct specialix_board * bp;
1829 func_enter();
1831 if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
1832 func_exit();
1833 return;
1836 bp = port_Board(port);
1837 spin_lock_irqsave(&port->lock, flags);
1838 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1839 spin_unlock_irqrestore(&port->lock, flags);
1840 tty_wakeup(tty);
1842 func_exit();
1846 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1848 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1849 struct specialix_board * bp;
1850 unsigned char status;
1851 unsigned int result;
1852 unsigned long flags;
1854 func_enter();
1856 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1857 func_exit();
1858 return -ENODEV;
1861 bp = port_Board(port);
1862 spin_lock_irqsave (&bp->lock, flags);
1863 sx_out(bp, CD186x_CAR, port_No(port));
1864 status = sx_in(bp, CD186x_MSVR);
1865 spin_unlock_irqrestore(&bp->lock, flags);
1866 dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1867 port_No(port), status, sx_in (bp, CD186x_CAR));
1868 dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1869 if (SX_CRTSCTS(port->tty)) {
1870 result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
1871 | ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1872 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1873 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1874 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1875 } else {
1876 result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
1877 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1878 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1879 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1880 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1883 func_exit();
1885 return result;
1889 static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1890 unsigned int set, unsigned int clear)
1892 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1893 unsigned long flags;
1894 struct specialix_board *bp;
1896 func_enter();
1898 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1899 func_exit();
1900 return -ENODEV;
1903 bp = port_Board(port);
1905 spin_lock_irqsave(&port->lock, flags);
1906 /* if (set & TIOCM_RTS)
1907 port->MSVR |= MSVR_RTS; */
1908 /* if (set & TIOCM_DTR)
1909 port->MSVR |= MSVR_DTR; */
1911 if (SX_CRTSCTS(port->tty)) {
1912 if (set & TIOCM_RTS)
1913 port->MSVR |= MSVR_DTR;
1914 } else {
1915 if (set & TIOCM_DTR)
1916 port->MSVR |= MSVR_DTR;
1919 /* if (clear & TIOCM_RTS)
1920 port->MSVR &= ~MSVR_RTS; */
1921 /* if (clear & TIOCM_DTR)
1922 port->MSVR &= ~MSVR_DTR; */
1923 if (SX_CRTSCTS(port->tty)) {
1924 if (clear & TIOCM_RTS)
1925 port->MSVR &= ~MSVR_DTR;
1926 } else {
1927 if (clear & TIOCM_DTR)
1928 port->MSVR &= ~MSVR_DTR;
1930 spin_lock_irqsave(&bp->lock, flags);
1931 sx_out(bp, CD186x_CAR, port_No(port));
1932 sx_out(bp, CD186x_MSVR, port->MSVR);
1933 spin_unlock_irqrestore(&bp->lock, flags);
1934 spin_unlock_irqrestore(&port->lock, flags);
1935 func_exit();
1936 return 0;
1940 static inline void sx_send_break(struct specialix_port * port, unsigned long length)
1942 struct specialix_board *bp = port_Board(port);
1943 unsigned long flags;
1945 func_enter();
1947 spin_lock_irqsave (&port->lock, flags);
1948 port->break_length = SPECIALIX_TPS / HZ * length;
1949 port->COR2 |= COR2_ETC;
1950 port->IER |= IER_TXRDY;
1951 spin_lock_irqsave(&bp->lock, flags);
1952 sx_out(bp, CD186x_CAR, port_No(port));
1953 sx_out(bp, CD186x_COR2, port->COR2);
1954 sx_out(bp, CD186x_IER, port->IER);
1955 spin_unlock_irqrestore(&bp->lock, flags);
1956 spin_unlock_irqrestore (&port->lock, flags);
1957 sx_wait_CCR(bp);
1958 spin_lock_irqsave(&bp->lock, flags);
1959 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1960 spin_unlock_irqrestore(&bp->lock, flags);
1961 sx_wait_CCR(bp);
1963 func_exit();
1967 static inline int sx_set_serial_info(struct specialix_port * port,
1968 struct serial_struct __user * newinfo)
1970 struct serial_struct tmp;
1971 struct specialix_board *bp = port_Board(port);
1972 int change_speed;
1974 func_enter();
1976 if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1977 func_exit();
1978 return -EFAULT;
1981 if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
1982 func_enter();
1983 return -EFAULT;
1986 #if 0
1987 if ((tmp.irq != bp->irq) ||
1988 (tmp.port != bp->base) ||
1989 (tmp.type != PORT_CIRRUS) ||
1990 (tmp.baud_base != (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) ||
1991 (tmp.custom_divisor != 0) ||
1992 (tmp.xmit_fifo_size != CD186x_NFIFO) ||
1993 (tmp.flags & ~SPECIALIX_LEGAL_FLAGS)) {
1994 func_exit();
1995 return -EINVAL;
1997 #endif
1999 change_speed = ((port->flags & ASYNC_SPD_MASK) !=
2000 (tmp.flags & ASYNC_SPD_MASK));
2001 change_speed |= (tmp.custom_divisor != port->custom_divisor);
2003 if (!capable(CAP_SYS_ADMIN)) {
2004 if ((tmp.close_delay != port->close_delay) ||
2005 (tmp.closing_wait != port->closing_wait) ||
2006 ((tmp.flags & ~ASYNC_USR_MASK) !=
2007 (port->flags & ~ASYNC_USR_MASK))) {
2008 func_exit();
2009 return -EPERM;
2011 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
2012 (tmp.flags & ASYNC_USR_MASK));
2013 port->custom_divisor = tmp.custom_divisor;
2014 } else {
2015 port->flags = ((port->flags & ~ASYNC_FLAGS) |
2016 (tmp.flags & ASYNC_FLAGS));
2017 port->close_delay = tmp.close_delay;
2018 port->closing_wait = tmp.closing_wait;
2019 port->custom_divisor = tmp.custom_divisor;
2021 if (change_speed) {
2022 sx_change_speed(bp, port);
2024 func_exit();
2025 return 0;
2029 static inline int sx_get_serial_info(struct specialix_port * port,
2030 struct serial_struct __user *retinfo)
2032 struct serial_struct tmp;
2033 struct specialix_board *bp = port_Board(port);
2035 func_enter();
2038 if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
2039 return -EFAULT;
2042 memset(&tmp, 0, sizeof(tmp));
2043 tmp.type = PORT_CIRRUS;
2044 tmp.line = port - sx_port;
2045 tmp.port = bp->base;
2046 tmp.irq = bp->irq;
2047 tmp.flags = port->flags;
2048 tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
2049 tmp.close_delay = port->close_delay * HZ/100;
2050 tmp.closing_wait = port->closing_wait * HZ/100;
2051 tmp.custom_divisor = port->custom_divisor;
2052 tmp.xmit_fifo_size = CD186x_NFIFO;
2053 if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
2054 func_exit();
2055 return -EFAULT;
2058 func_exit();
2059 return 0;
2063 static int sx_ioctl(struct tty_struct * tty, struct file * filp,
2064 unsigned int cmd, unsigned long arg)
2066 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2067 int retval;
2068 void __user *argp = (void __user *)arg;
2070 func_enter();
2072 if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
2073 func_exit();
2074 return -ENODEV;
2077 switch (cmd) {
2078 case TCSBRK: /* SVID version: non-zero arg --> no break */
2079 retval = tty_check_change(tty);
2080 if (retval) {
2081 func_exit();
2082 return retval;
2084 tty_wait_until_sent(tty, 0);
2085 if (!arg)
2086 sx_send_break(port, HZ/4); /* 1/4 second */
2087 return 0;
2088 case TCSBRKP: /* support for POSIX tcsendbreak() */
2089 retval = tty_check_change(tty);
2090 if (retval) {
2091 func_exit();
2092 return retval;
2094 tty_wait_until_sent(tty, 0);
2095 sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
2096 func_exit();
2097 return 0;
2098 case TIOCGSOFTCAR:
2099 if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) {
2100 func_exit();
2101 return -EFAULT;
2103 func_exit();
2104 return 0;
2105 case TIOCSSOFTCAR:
2106 if (get_user(arg, (unsigned long __user *) argp)) {
2107 func_exit();
2108 return -EFAULT;
2110 tty->termios->c_cflag =
2111 ((tty->termios->c_cflag & ~CLOCAL) |
2112 (arg ? CLOCAL : 0));
2113 func_exit();
2114 return 0;
2115 case TIOCGSERIAL:
2116 func_exit();
2117 return sx_get_serial_info(port, argp);
2118 case TIOCSSERIAL:
2119 func_exit();
2120 return sx_set_serial_info(port, argp);
2121 default:
2122 func_exit();
2123 return -ENOIOCTLCMD;
2125 func_exit();
2126 return 0;
2130 static void sx_throttle(struct tty_struct * tty)
2132 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2133 struct specialix_board *bp;
2134 unsigned long flags;
2136 func_enter();
2138 if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
2139 func_exit();
2140 return;
2143 bp = port_Board(port);
2145 /* Use DTR instead of RTS ! */
2146 if (SX_CRTSCTS (tty))
2147 port->MSVR &= ~MSVR_DTR;
2148 else {
2149 /* Auch!!! I think the system shouldn't call this then. */
2150 /* Or maybe we're supposed (allowed?) to do our side of hw
2151 handshake anyway, even when hardware handshake is off.
2152 When you see this in your logs, please report.... */
2153 printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
2154 port_No (port));
2156 spin_lock_irqsave(&bp->lock, flags);
2157 sx_out(bp, CD186x_CAR, port_No(port));
2158 spin_unlock_irqrestore(&bp->lock, flags);
2159 if (I_IXOFF(tty)) {
2160 spin_unlock_irqrestore(&bp->lock, flags);
2161 sx_wait_CCR(bp);
2162 spin_lock_irqsave(&bp->lock, flags);
2163 sx_out(bp, CD186x_CCR, CCR_SSCH2);
2164 spin_unlock_irqrestore(&bp->lock, flags);
2165 sx_wait_CCR(bp);
2167 spin_lock_irqsave(&bp->lock, flags);
2168 sx_out(bp, CD186x_MSVR, port->MSVR);
2169 spin_unlock_irqrestore(&bp->lock, flags);
2171 func_exit();
2175 static void sx_unthrottle(struct tty_struct * tty)
2177 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2178 struct specialix_board *bp;
2179 unsigned long flags;
2181 func_enter();
2183 if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
2184 func_exit();
2185 return;
2188 bp = port_Board(port);
2190 spin_lock_irqsave(&port->lock, flags);
2191 /* XXXX Use DTR INSTEAD???? */
2192 if (SX_CRTSCTS(tty)) {
2193 port->MSVR |= MSVR_DTR;
2194 } /* Else clause: see remark in "sx_throttle"... */
2195 spin_lock_irqsave(&bp->lock, flags);
2196 sx_out(bp, CD186x_CAR, port_No(port));
2197 spin_unlock_irqrestore(&bp->lock, flags);
2198 if (I_IXOFF(tty)) {
2199 spin_unlock_irqrestore(&port->lock, flags);
2200 sx_wait_CCR(bp);
2201 spin_lock_irqsave(&bp->lock, flags);
2202 sx_out(bp, CD186x_CCR, CCR_SSCH1);
2203 spin_unlock_irqrestore(&bp->lock, flags);
2204 sx_wait_CCR(bp);
2205 spin_lock_irqsave(&port->lock, flags);
2207 spin_lock_irqsave(&bp->lock, flags);
2208 sx_out(bp, CD186x_MSVR, port->MSVR);
2209 spin_unlock_irqrestore(&bp->lock, flags);
2210 spin_unlock_irqrestore(&port->lock, flags);
2212 func_exit();
2216 static void sx_stop(struct tty_struct * tty)
2218 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2219 struct specialix_board *bp;
2220 unsigned long flags;
2222 func_enter();
2224 if (sx_paranoia_check(port, tty->name, "sx_stop")) {
2225 func_exit();
2226 return;
2229 bp = port_Board(port);
2231 spin_lock_irqsave(&port->lock, flags);
2232 port->IER &= ~IER_TXRDY;
2233 spin_lock_irqsave(&bp->lock, flags);
2234 sx_out(bp, CD186x_CAR, port_No(port));
2235 sx_out(bp, CD186x_IER, port->IER);
2236 spin_unlock_irqrestore(&bp->lock, flags);
2237 spin_unlock_irqrestore(&port->lock, flags);
2239 func_exit();
2243 static void sx_start(struct tty_struct * tty)
2245 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2246 struct specialix_board *bp;
2247 unsigned long flags;
2249 func_enter();
2251 if (sx_paranoia_check(port, tty->name, "sx_start")) {
2252 func_exit();
2253 return;
2256 bp = port_Board(port);
2258 spin_lock_irqsave(&port->lock, flags);
2259 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2260 port->IER |= IER_TXRDY;
2261 spin_lock_irqsave(&bp->lock, flags);
2262 sx_out(bp, CD186x_CAR, port_No(port));
2263 sx_out(bp, CD186x_IER, port->IER);
2264 spin_unlock_irqrestore(&bp->lock, flags);
2266 spin_unlock_irqrestore(&port->lock, flags);
2268 func_exit();
2273 * This routine is called from the work-queue when the interrupt
2274 * routine has signalled that a hangup has occurred. The path of
2275 * hangup processing is:
2277 * serial interrupt routine -> (workqueue) ->
2278 * do_sx_hangup() -> tty->hangup() -> sx_hangup()
2281 static void do_sx_hangup(void *private_)
2283 struct specialix_port *port = (struct specialix_port *) private_;
2284 struct tty_struct *tty;
2286 func_enter();
2288 tty = port->tty;
2289 if (tty)
2290 tty_hangup(tty); /* FIXME: module removal race here */
2292 func_exit();
2296 static void sx_hangup(struct tty_struct * tty)
2298 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2299 struct specialix_board *bp;
2300 unsigned long flags;
2302 func_enter();
2304 if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2305 func_exit();
2306 return;
2309 bp = port_Board(port);
2311 sx_shutdown_port(bp, port);
2312 spin_lock_irqsave(&port->lock, flags);
2313 port->event = 0;
2314 bp->count -= port->count;
2315 if (bp->count < 0) {
2316 printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n",
2317 board_No(bp), bp->count, tty->index);
2318 bp->count = 0;
2320 port->count = 0;
2321 port->flags &= ~ASYNC_NORMAL_ACTIVE;
2322 port->tty = NULL;
2323 spin_unlock_irqrestore(&port->lock, flags);
2324 wake_up_interruptible(&port->open_wait);
2326 func_exit();
2330 static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios)
2332 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2333 unsigned long flags;
2334 struct specialix_board * bp;
2336 if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2337 return;
2339 if (tty->termios->c_cflag == old_termios->c_cflag &&
2340 tty->termios->c_iflag == old_termios->c_iflag)
2341 return;
2343 bp = port_Board(port);
2344 spin_lock_irqsave(&port->lock, flags);
2345 sx_change_speed(port_Board(port), port);
2346 spin_unlock_irqrestore(&port->lock, flags);
2348 if ((old_termios->c_cflag & CRTSCTS) &&
2349 !(tty->termios->c_cflag & CRTSCTS)) {
2350 tty->hw_stopped = 0;
2351 sx_start(tty);
2356 static void do_softint(void *private_)
2358 struct specialix_port *port = (struct specialix_port *) private_;
2359 struct tty_struct *tty;
2361 func_enter();
2363 if(!(tty = port->tty)) {
2364 func_exit();
2365 return;
2368 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
2369 tty_wakeup(tty);
2370 //wake_up_interruptible(&tty->write_wait);
2373 func_exit();
2376 static struct tty_operations sx_ops = {
2377 .open = sx_open,
2378 .close = sx_close,
2379 .write = sx_write,
2380 .put_char = sx_put_char,
2381 .flush_chars = sx_flush_chars,
2382 .write_room = sx_write_room,
2383 .chars_in_buffer = sx_chars_in_buffer,
2384 .flush_buffer = sx_flush_buffer,
2385 .ioctl = sx_ioctl,
2386 .throttle = sx_throttle,
2387 .unthrottle = sx_unthrottle,
2388 .set_termios = sx_set_termios,
2389 .stop = sx_stop,
2390 .start = sx_start,
2391 .hangup = sx_hangup,
2392 .tiocmget = sx_tiocmget,
2393 .tiocmset = sx_tiocmset,
2396 static int sx_init_drivers(void)
2398 int error;
2399 int i;
2401 func_enter();
2403 specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT);
2404 if (!specialix_driver) {
2405 printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n");
2406 func_exit();
2407 return 1;
2410 if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
2411 printk(KERN_ERR "sx: Couldn't get free page.\n");
2412 put_tty_driver(specialix_driver);
2413 func_exit();
2414 return 1;
2416 specialix_driver->owner = THIS_MODULE;
2417 specialix_driver->name = "ttyW";
2418 specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
2419 specialix_driver->type = TTY_DRIVER_TYPE_SERIAL;
2420 specialix_driver->subtype = SERIAL_TYPE_NORMAL;
2421 specialix_driver->init_termios = tty_std_termios;
2422 specialix_driver->init_termios.c_cflag =
2423 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2424 specialix_driver->flags = TTY_DRIVER_REAL_RAW;
2425 tty_set_operations(specialix_driver, &sx_ops);
2427 if ((error = tty_register_driver(specialix_driver))) {
2428 put_tty_driver(specialix_driver);
2429 free_page((unsigned long)tmp_buf);
2430 printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2431 error);
2432 func_exit();
2433 return 1;
2435 memset(sx_port, 0, sizeof(sx_port));
2436 for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2437 sx_port[i].magic = SPECIALIX_MAGIC;
2438 INIT_WORK(&sx_port[i].tqueue, do_softint, &sx_port[i]);
2439 INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup, &sx_port[i]);
2440 sx_port[i].close_delay = 50 * HZ/100;
2441 sx_port[i].closing_wait = 3000 * HZ/100;
2442 init_waitqueue_head(&sx_port[i].open_wait);
2443 init_waitqueue_head(&sx_port[i].close_wait);
2444 spin_lock_init(&sx_port[i].lock);
2447 func_exit();
2448 return 0;
2451 static void sx_release_drivers(void)
2453 func_enter();
2455 free_page((unsigned long)tmp_buf);
2456 tty_unregister_driver(specialix_driver);
2457 put_tty_driver(specialix_driver);
2458 func_exit();
2462 * This routine must be called by kernel at boot time
2464 static int __init specialix_init(void)
2466 int i;
2467 int found = 0;
2469 func_enter();
2471 printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
2472 printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2473 #ifdef CONFIG_SPECIALIX_RTSCTS
2474 printk (KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
2475 #else
2476 printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2477 #endif
2479 for (i = 0; i < SX_NBOARD; i++)
2480 sx_board[i].lock = SPIN_LOCK_UNLOCKED;
2482 if (sx_init_drivers()) {
2483 func_exit();
2484 return -EIO;
2487 for (i = 0; i < SX_NBOARD; i++)
2488 if (sx_board[i].base && !sx_probe(&sx_board[i]))
2489 found++;
2491 #ifdef CONFIG_PCI
2493 struct pci_dev *pdev = NULL;
2495 i=0;
2496 while (i < SX_NBOARD) {
2497 if (sx_board[i].flags & SX_BOARD_PRESENT) {
2498 i++;
2499 continue;
2501 pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
2502 PCI_DEVICE_ID_SPECIALIX_IO8,
2503 pdev);
2504 if (!pdev) break;
2506 if (pci_enable_device(pdev))
2507 continue;
2509 sx_board[i].irq = pdev->irq;
2511 sx_board[i].base = pci_resource_start (pdev, 2);
2513 sx_board[i].flags |= SX_BOARD_IS_PCI;
2514 if (!sx_probe(&sx_board[i]))
2515 found ++;
2518 #endif
2520 if (!found) {
2521 sx_release_drivers();
2522 printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
2523 func_exit();
2524 return -EIO;
2527 func_exit();
2528 return 0;
2531 static int iobase[SX_NBOARD] = {0,};
2533 static int irq [SX_NBOARD] = {0,};
2535 module_param_array(iobase, int, NULL, 0);
2536 module_param_array(irq, int, NULL, 0);
2537 module_param(sx_debug, int, 0);
2538 module_param(sx_rxfifo, int, 0);
2539 #ifdef SPECIALIX_TIMER
2540 module_param(sx_poll, int, 0);
2541 #endif
2544 * You can setup up to 4 boards.
2545 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2546 * You should specify the IRQs too in that case "irq=....,...".
2548 * More than 4 boards in one computer is not possible, as the card can
2549 * only use 4 different interrupts.
2552 static int __init specialix_init_module(void)
2554 int i;
2556 func_enter();
2558 if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2559 for(i = 0; i < SX_NBOARD; i++) {
2560 sx_board[i].base = iobase[i];
2561 sx_board[i].irq = irq[i];
2562 sx_board[i].count= 0;
2566 func_exit();
2568 return specialix_init();
2571 static void __exit specialix_exit_module(void)
2573 int i;
2575 func_enter();
2577 sx_release_drivers();
2578 for (i = 0; i < SX_NBOARD; i++)
2579 if (sx_board[i].flags & SX_BOARD_PRESENT)
2580 sx_release_io_range(&sx_board[i]);
2581 #ifdef SPECIALIX_TIMER
2582 del_timer (&missed_irq_timer);
2583 #endif
2585 func_exit();
2588 module_init(specialix_init_module);
2589 module_exit(specialix_exit_module);
2591 MODULE_LICENSE("GPL");