hwmon: (adm1025) Various cleanups
[linux-2.6/mini2440.git] / drivers / char / specialix.c
blobc0e08c7bca2f4ef713c966eeed532164d33282e6
1 /*
2 * specialix.c -- specialix IO8+ multiport serial driver.
4 * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl)
5 * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com)
7 * Specialix pays for the development and support of this driver.
8 * Please DO contact io8-linux@specialix.co.uk if you require
9 * support. But please read the documentation (specialix.txt)
10 * first.
12 * This driver was developped in the BitWizard linux device
13 * driver service. If you require a linux device driver for your
14 * product, please contact devices@BitWizard.nl for a quote.
16 * This code is firmly based on the riscom/8 serial driver,
17 * written by Dmitry Gorodchanin. The specialix IO8+ card
18 * programming information was obtained from the CL-CD1865 Data
19 * Book, and Specialix document number 6200059: IO8+ Hardware
20 * Functional Specification.
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License as
24 * published by the Free Software Foundation; either version 2 of
25 * the License, or (at your option) any later version.
27 * This program is distributed in the hope that it will be
28 * useful, but WITHOUT ANY WARRANTY; without even the implied
29 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
30 * PURPOSE. See the GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public
33 * License along with this program; if not, write to the Free
34 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
35 * USA.
37 * Revision history:
39 * Revision 1.0: April 1st 1997.
40 * Initial release for alpha testing.
41 * Revision 1.1: April 14th 1997.
42 * Incorporated Richard Hudsons suggestions,
43 * removed some debugging printk's.
44 * Revision 1.2: April 15th 1997.
45 * Ported to 2.1.x kernels.
46 * Revision 1.3: April 17th 1997
47 * Backported to 2.0. (Compatibility macros).
48 * Revision 1.4: April 18th 1997
49 * Fixed DTR/RTS bug that caused the card to indicate
50 * "don't send data" to a modem after the password prompt.
51 * Fixed bug for premature (fake) interrupts.
52 * Revision 1.5: April 19th 1997
53 * fixed a minor typo in the header file, cleanup a little.
54 * performance warnings are now MAXed at once per minute.
55 * Revision 1.6: May 23 1997
56 * Changed the specialix=... format to include interrupt.
57 * Revision 1.7: May 27 1997
58 * Made many more debug printk's a compile time option.
59 * Revision 1.8: Jul 1 1997
60 * port to linux-2.1.43 kernel.
61 * Revision 1.9: Oct 9 1998
62 * Added stuff for the IO8+/PCI version.
63 * Revision 1.10: Oct 22 1999 / Jan 21 2000.
64 * Added stuff for setserial.
65 * Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr)
69 #define VERSION "1.11"
73 * There is a bunch of documentation about the card, jumpers, config
74 * settings, restrictions, cables, device names and numbers in
75 * Documentation/specialix.txt
78 #include <linux/module.h>
80 #include <asm/io.h>
81 #include <linux/kernel.h>
82 #include <linux/sched.h>
83 #include <linux/ioport.h>
84 #include <linux/interrupt.h>
85 #include <linux/errno.h>
86 #include <linux/tty.h>
87 #include <linux/tty_flip.h>
88 #include <linux/mm.h>
89 #include <linux/serial.h>
90 #include <linux/fcntl.h>
91 #include <linux/major.h>
92 #include <linux/delay.h>
93 #include <linux/pci.h>
94 #include <linux/init.h>
95 #include <asm/uaccess.h>
97 #include "specialix_io8.h"
98 #include "cd1865.h"
102 This driver can spew a whole lot of debugging output at you. If you
103 need maximum performance, you should disable the DEBUG define. To
104 aid in debugging in the field, I'm leaving the compile-time debug
105 features enabled, and disable them "runtime". That allows me to
106 instruct people with problems to enable debugging without requiring
107 them to recompile...
109 #define DEBUG
111 static int sx_debug;
112 static int sx_rxfifo = SPECIALIX_RXFIFO;
114 #ifdef DEBUG
115 #define dprintk(f, str...) if (sx_debug & f) printk (str)
116 #else
117 #define dprintk(f, str...) /* nothing */
118 #endif
120 #define SX_DEBUG_FLOW 0x0001
121 #define SX_DEBUG_DATA 0x0002
122 #define SX_DEBUG_PROBE 0x0004
123 #define SX_DEBUG_CHAN 0x0008
124 #define SX_DEBUG_INIT 0x0010
125 #define SX_DEBUG_RX 0x0020
126 #define SX_DEBUG_TX 0x0040
127 #define SX_DEBUG_IRQ 0x0080
128 #define SX_DEBUG_OPEN 0x0100
129 #define SX_DEBUG_TERMIOS 0x0200
130 #define SX_DEBUG_SIGNALS 0x0400
131 #define SX_DEBUG_FIFO 0x0800
134 #define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__FUNCTION__)
135 #define func_exit() dprintk (SX_DEBUG_FLOW, "io8: exit %s\n", __FUNCTION__)
137 #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
140 /* Configurable options: */
142 /* Am I paranoid or not ? ;-) */
143 #define SPECIALIX_PARANOIA_CHECK
145 /* Do I trust the IRQ from the card? (enabeling it doesn't seem to help)
146 When the IRQ routine leaves the chip in a state that is keeps on
147 requiring attention, the timer doesn't help either. */
148 #undef SPECIALIX_TIMER
150 #ifdef SPECIALIX_TIMER
151 static int sx_poll = HZ;
152 #endif
157 * The following defines are mostly for testing purposes. But if you need
158 * some nice reporting in your syslog, you can define them also.
160 #undef SX_REPORT_FIFO
161 #undef SX_REPORT_OVERRUN
165 #ifdef CONFIG_SPECIALIX_RTSCTS
166 #define SX_CRTSCTS(bla) 1
167 #else
168 #define SX_CRTSCTS(tty) C_CRTSCTS(tty)
169 #endif
172 /* Used to be outb (0xff, 0x80); */
173 #define short_pause() udelay (1)
176 #define SPECIALIX_LEGAL_FLAGS \
177 (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \
178 ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \
179 ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
181 static struct tty_driver *specialix_driver;
183 static struct specialix_board sx_board[SX_NBOARD] = {
184 { 0, SX_IOBASE1, 9, },
185 { 0, SX_IOBASE2, 11, },
186 { 0, SX_IOBASE3, 12, },
187 { 0, SX_IOBASE4, 15, },
190 static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
193 #ifdef SPECIALIX_TIMER
194 static struct timer_list missed_irq_timer;
195 static irqreturn_t sx_interrupt(int irq, void * dev_id);
196 #endif
200 static inline int sx_paranoia_check(struct specialix_port const * port,
201 char *name, const char *routine)
203 #ifdef SPECIALIX_PARANOIA_CHECK
204 static const char *badmagic =
205 KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
206 static const char *badinfo =
207 KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
209 if (!port) {
210 printk(badinfo, name, routine);
211 return 1;
213 if (port->magic != SPECIALIX_MAGIC) {
214 printk(badmagic, name, routine);
215 return 1;
217 #endif
218 return 0;
224 * Service functions for specialix IO8+ driver.
228 /* Get board number from pointer */
229 static inline int board_No (struct specialix_board * bp)
231 return bp - sx_board;
235 /* Get port number from pointer */
236 static inline int port_No (struct specialix_port const * port)
238 return SX_PORT(port - sx_port);
242 /* Get pointer to board from pointer to port */
243 static inline struct specialix_board * port_Board(struct specialix_port const * port)
245 return &sx_board[SX_BOARD(port - sx_port)];
249 /* Input Byte from CL CD186x register */
250 static inline unsigned char sx_in(struct specialix_board * bp, unsigned short reg)
252 bp->reg = reg | 0x80;
253 outb (reg | 0x80, bp->base + SX_ADDR_REG);
254 return inb (bp->base + SX_DATA_REG);
258 /* Output Byte to CL CD186x register */
259 static inline void sx_out(struct specialix_board * bp, unsigned short reg,
260 unsigned char val)
262 bp->reg = reg | 0x80;
263 outb (reg | 0x80, bp->base + SX_ADDR_REG);
264 outb (val, bp->base + SX_DATA_REG);
268 /* Input Byte from CL CD186x register */
269 static inline unsigned char sx_in_off(struct specialix_board * bp, unsigned short reg)
271 bp->reg = reg;
272 outb (reg, bp->base + SX_ADDR_REG);
273 return inb (bp->base + SX_DATA_REG);
277 /* Output Byte to CL CD186x register */
278 static inline void sx_out_off(struct specialix_board * bp, unsigned short reg,
279 unsigned char val)
281 bp->reg = reg;
282 outb (reg, bp->base + SX_ADDR_REG);
283 outb (val, bp->base + SX_DATA_REG);
287 /* Wait for Channel Command Register ready */
288 static inline void sx_wait_CCR(struct specialix_board * bp)
290 unsigned long delay, flags;
291 unsigned char ccr;
293 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
294 spin_lock_irqsave(&bp->lock, flags);
295 ccr = sx_in(bp, CD186x_CCR);
296 spin_unlock_irqrestore(&bp->lock, flags);
297 if (!ccr)
298 return;
299 udelay (1);
302 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
306 /* Wait for Channel Command Register ready */
307 static inline void sx_wait_CCR_off(struct specialix_board * bp)
309 unsigned long delay;
310 unsigned char crr;
311 unsigned long flags;
313 for (delay = SX_CCR_TIMEOUT; delay; delay--) {
314 spin_lock_irqsave(&bp->lock, flags);
315 crr = sx_in_off(bp, CD186x_CCR);
316 spin_unlock_irqrestore(&bp->lock, flags);
317 if (!crr)
318 return;
319 udelay (1);
322 printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
327 * specialix IO8+ IO range functions.
330 static inline int sx_request_io_range(struct specialix_board * bp)
332 return request_region(bp->base,
333 bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
334 "specialix IO8+") == NULL;
338 static inline void sx_release_io_range(struct specialix_board * bp)
340 release_region(bp->base,
341 bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
345 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
346 static int sx_set_irq ( struct specialix_board *bp)
348 int virq;
349 int i;
350 unsigned long flags;
352 if (bp->flags & SX_BOARD_IS_PCI)
353 return 1;
354 switch (bp->irq) {
355 /* In the same order as in the docs... */
356 case 15: virq = 0;break;
357 case 12: virq = 1;break;
358 case 11: virq = 2;break;
359 case 9: virq = 3;break;
360 default: printk (KERN_ERR "Speclialix: cannot set irq to %d.\n", bp->irq);
361 return 0;
363 spin_lock_irqsave(&bp->lock, flags);
364 for (i=0;i<2;i++) {
365 sx_out(bp, CD186x_CAR, i);
366 sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
368 spin_unlock_irqrestore(&bp->lock, flags);
369 return 1;
373 /* Reset and setup CD186x chip */
374 static int sx_init_CD186x(struct specialix_board * bp)
376 unsigned long flags;
377 int scaler;
378 int rv = 1;
380 func_enter();
381 sx_wait_CCR_off(bp); /* Wait for CCR ready */
382 spin_lock_irqsave(&bp->lock, flags);
383 sx_out_off(bp, CD186x_CCR, CCR_HARDRESET); /* Reset CD186x chip */
384 spin_unlock_irqrestore(&bp->lock, flags);
385 msleep(50); /* Delay 0.05 sec */
386 spin_lock_irqsave(&bp->lock, flags);
387 sx_out_off(bp, CD186x_GIVR, SX_ID); /* Set ID for this chip */
388 sx_out_off(bp, CD186x_GICR, 0); /* Clear all bits */
389 sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT); /* Prio for modem intr */
390 sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */
391 sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */
392 /* Set RegAckEn */
393 sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
395 /* Setting up prescaler. We need 4 ticks per 1 ms */
396 scaler = SX_OSCFREQ/SPECIALIX_TPS;
398 sx_out_off(bp, CD186x_PPRH, scaler >> 8);
399 sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
400 spin_unlock_irqrestore(&bp->lock, flags);
402 if (!sx_set_irq (bp)) {
403 /* Figure out how to pass this along... */
404 printk (KERN_ERR "Cannot set irq to %d.\n", bp->irq);
405 rv = 0;
408 func_exit();
409 return rv;
413 static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
415 int i;
416 int t;
417 unsigned long flags;
419 spin_lock_irqsave(&bp->lock, flags);
420 for (i=0, t=0;i<8;i++) {
421 sx_out_off (bp, CD186x_CAR, i);
422 if (sx_in_off (bp, reg) & bit)
423 t |= 1 << i;
425 spin_unlock_irqrestore(&bp->lock, flags);
427 return t;
431 #ifdef SPECIALIX_TIMER
432 void missed_irq (unsigned long data)
434 unsigned char irq;
435 unsigned long flags;
436 struct specialix_board *bp = (struct specialix_board *)data;
438 spin_lock_irqsave(&bp->lock, flags);
439 irq = sx_in ((struct specialix_board *)data, CD186x_SRSR) &
440 (SRSR_RREQint |
441 SRSR_TREQint |
442 SRSR_MREQint);
443 spin_unlock_irqrestore(&bp->lock, flags);
444 if (irq) {
445 printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
446 sx_interrupt (((struct specialix_board *)data)->irq,
447 (void*)data);
449 mod_timer(&missed_irq_timer, jiffies + sx_poll);
451 #endif
455 /* Main probing routine, also sets irq. */
456 static int sx_probe(struct specialix_board *bp)
458 unsigned char val1, val2;
459 #if 0
460 int irqs = 0;
461 int retries;
462 #endif
463 int rev;
464 int chip;
466 func_enter();
468 if (sx_request_io_range(bp)) {
469 func_exit();
470 return 1;
473 /* Are the I/O ports here ? */
474 sx_out_off(bp, CD186x_PPRL, 0x5a);
475 short_pause ();
476 val1 = sx_in_off(bp, CD186x_PPRL);
478 sx_out_off(bp, CD186x_PPRL, 0xa5);
479 short_pause ();
480 val2 = sx_in_off(bp, CD186x_PPRL);
483 if ((val1 != 0x5a) || (val2 != 0xa5)) {
484 printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
485 board_No(bp), bp->base);
486 sx_release_io_range(bp);
487 func_exit();
488 return 1;
491 /* Check the DSR lines that Specialix uses as board
492 identification */
493 val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
494 val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
495 dprintk (SX_DEBUG_INIT, "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
496 board_No(bp), val1, val2);
498 /* They managed to switch the bit order between the docs and
499 the IO8+ card. The new PCI card now conforms to old docs.
500 They changed the PCI docs to reflect the situation on the
501 old card. */
502 val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
503 if (val1 != val2) {
504 printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
505 board_No(bp), val2, bp->base, val1);
506 sx_release_io_range(bp);
507 func_exit();
508 return 1;
512 #if 0
513 /* It's time to find IRQ for this board */
514 for (retries = 0; retries < 5 && irqs <= 0; retries++) {
515 irqs = probe_irq_on();
516 sx_init_CD186x(bp); /* Reset CD186x chip */
517 sx_out(bp, CD186x_CAR, 2); /* Select port 2 */
518 sx_wait_CCR(bp);
519 sx_out(bp, CD186x_CCR, CCR_TXEN); /* Enable transmitter */
520 sx_out(bp, CD186x_IER, IER_TXRDY); /* Enable tx empty intr */
521 msleep(50);
522 irqs = probe_irq_off(irqs);
524 dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
525 dprintk (SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR));
526 dprintk (SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR));
527 dprintk (SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR));
528 dprintk (SX_DEBUG_INIT, "\n");
530 /* Reset CD186x again */
531 if (!sx_init_CD186x(bp)) {
532 /* Hmmm. This is dead code anyway. */
535 dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
536 val1, val2, val3);
540 #if 0
541 if (irqs <= 0) {
542 printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
543 board_No(bp), bp->base);
544 sx_release_io_range(bp);
545 func_exit();
546 return 1;
548 #endif
549 printk (KERN_INFO "Started with irq=%d, but now have irq=%d.\n", bp->irq, irqs);
550 if (irqs > 0)
551 bp->irq = irqs;
552 #endif
553 /* Reset CD186x again */
554 if (!sx_init_CD186x(bp)) {
555 sx_release_io_range(bp);
556 func_exit();
557 return 1;
560 sx_request_io_range(bp);
561 bp->flags |= SX_BOARD_PRESENT;
563 /* Chip revcode pkgtype
564 GFRCR SRCR bit 7
565 CD180 rev B 0x81 0
566 CD180 rev C 0x82 0
567 CD1864 rev A 0x82 1
568 CD1865 rev A 0x83 1 -- Do not use!!! Does not work.
569 CD1865 rev B 0x84 1
570 -- Thanks to Gwen Wang, Cirrus Logic.
573 switch (sx_in_off(bp, CD186x_GFRCR)) {
574 case 0x82:chip = 1864;rev='A';break;
575 case 0x83:chip = 1865;rev='A';break;
576 case 0x84:chip = 1865;rev='B';break;
577 case 0x85:chip = 1865;rev='C';break; /* Does not exist at this time */
578 default:chip=-1;rev='x';
581 dprintk (SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR) );
583 #ifdef SPECIALIX_TIMER
584 setup_timer(&missed_irq_timer, missed_irq, (unsigned long)bp);
585 mod_timer(&missed_irq_timer, jiffies + sx_poll);
586 #endif
588 printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
589 board_No(bp),
590 bp->base, bp->irq,
591 chip, rev);
593 func_exit();
594 return 0;
599 * Interrupt processing routines.
600 * */
602 static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
603 unsigned char const * what)
605 unsigned char channel;
606 struct specialix_port * port = NULL;
608 channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
609 dprintk (SX_DEBUG_CHAN, "channel: %d\n", channel);
610 if (channel < CD186x_NCH) {
611 port = &sx_port[board_No(bp) * SX_NPORT + channel];
612 dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%x\n",board_No(bp) * SX_NPORT + channel, port, port->flags & ASYNC_INITIALIZED);
614 if (port->flags & ASYNC_INITIALIZED) {
615 dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
616 func_exit();
617 return port;
620 printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
621 board_No(bp), what, channel);
622 return NULL;
626 static inline void sx_receive_exc(struct specialix_board * bp)
628 struct specialix_port *port;
629 struct tty_struct *tty;
630 unsigned char status;
631 unsigned char ch, flag;
633 func_enter();
635 port = sx_get_port(bp, "Receive");
636 if (!port) {
637 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
638 func_exit();
639 return;
641 tty = port->tty;
643 status = sx_in(bp, CD186x_RCSR);
645 dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
646 if (status & RCSR_OE) {
647 port->overrun++;
648 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Overrun. Total %ld overruns.\n",
649 board_No(bp), port_No(port), port->overrun);
651 status &= port->mark_mask;
653 /* This flip buffer check needs to be below the reading of the
654 status register to reset the chip's IRQ.... */
655 if (tty_buffer_request_room(tty, 1) == 0) {
656 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n",
657 board_No(bp), port_No(port));
658 func_exit();
659 return;
662 ch = sx_in(bp, CD186x_RDR);
663 if (!status) {
664 func_exit();
665 return;
667 if (status & RCSR_TOUT) {
668 printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
669 board_No(bp), port_No(port));
670 func_exit();
671 return;
673 } else if (status & RCSR_BREAK) {
674 dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
675 board_No(bp), port_No(port));
676 flag = TTY_BREAK;
677 if (port->flags & ASYNC_SAK)
678 do_SAK(tty);
680 } else if (status & RCSR_PE)
681 flag = TTY_PARITY;
683 else if (status & RCSR_FE)
684 flag = TTY_FRAME;
686 else if (status & RCSR_OE)
687 flag = TTY_OVERRUN;
689 else
690 flag = TTY_NORMAL;
692 if(tty_insert_flip_char(tty, ch, flag))
693 tty_flip_buffer_push(tty);
694 func_exit();
698 static inline void sx_receive(struct specialix_board * bp)
700 struct specialix_port *port;
701 struct tty_struct *tty;
702 unsigned char count;
704 func_enter();
706 if (!(port = sx_get_port(bp, "Receive"))) {
707 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
708 func_exit();
709 return;
711 tty = port->tty;
713 count = sx_in(bp, CD186x_RDCR);
714 dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
715 port->hits[count > 8 ? 9 : count]++;
717 tty_buffer_request_room(tty, count);
719 while (count--)
720 tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL);
721 tty_flip_buffer_push(tty);
722 func_exit();
726 static inline void sx_transmit(struct specialix_board * bp)
728 struct specialix_port *port;
729 struct tty_struct *tty;
730 unsigned char count;
732 func_enter();
733 if (!(port = sx_get_port(bp, "Transmit"))) {
734 func_exit();
735 return;
737 dprintk (SX_DEBUG_TX, "port: %p\n", port);
738 tty = port->tty;
740 if (port->IER & IER_TXEMPTY) {
741 /* FIFO drained */
742 sx_out(bp, CD186x_CAR, port_No(port));
743 port->IER &= ~IER_TXEMPTY;
744 sx_out(bp, CD186x_IER, port->IER);
745 func_exit();
746 return;
749 if ((port->xmit_cnt <= 0 && !port->break_length)
750 || tty->stopped || tty->hw_stopped) {
751 sx_out(bp, CD186x_CAR, port_No(port));
752 port->IER &= ~IER_TXRDY;
753 sx_out(bp, CD186x_IER, port->IER);
754 func_exit();
755 return;
758 if (port->break_length) {
759 if (port->break_length > 0) {
760 if (port->COR2 & COR2_ETC) {
761 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
762 sx_out(bp, CD186x_TDR, CD186x_C_SBRK);
763 port->COR2 &= ~COR2_ETC;
765 count = min_t(int, port->break_length, 0xff);
766 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
767 sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
768 sx_out(bp, CD186x_TDR, count);
769 if (!(port->break_length -= count))
770 port->break_length--;
771 } else {
772 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
773 sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
774 sx_out(bp, CD186x_COR2, port->COR2);
775 sx_wait_CCR(bp);
776 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
777 port->break_length = 0;
780 func_exit();
781 return;
784 count = CD186x_NFIFO;
785 do {
786 sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
787 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
788 if (--port->xmit_cnt <= 0)
789 break;
790 } while (--count > 0);
792 if (port->xmit_cnt <= 0) {
793 sx_out(bp, CD186x_CAR, port_No(port));
794 port->IER &= ~IER_TXRDY;
795 sx_out(bp, CD186x_IER, port->IER);
797 if (port->xmit_cnt <= port->wakeup_chars)
798 tty_wakeup(tty);
800 func_exit();
804 static inline void sx_check_modem(struct specialix_board * bp)
806 struct specialix_port *port;
807 struct tty_struct *tty;
808 unsigned char mcr;
809 int msvr_cd;
811 dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
812 if (!(port = sx_get_port(bp, "Modem")))
813 return;
815 tty = port->tty;
817 mcr = sx_in(bp, CD186x_MCR);
818 printk ("mcr = %02x.\n", mcr);
820 if ((mcr & MCR_CDCHG)) {
821 dprintk (SX_DEBUG_SIGNALS, "CD just changed... ");
822 msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
823 if (msvr_cd) {
824 dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
825 wake_up_interruptible(&port->open_wait);
826 } else {
827 dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n");
828 tty_hangup(tty);
832 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
833 if (mcr & MCR_CTSCHG) {
834 if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
835 tty->hw_stopped = 0;
836 port->IER |= IER_TXRDY;
837 if (port->xmit_cnt <= port->wakeup_chars)
838 tty_wakeup(tty);
839 } else {
840 tty->hw_stopped = 1;
841 port->IER &= ~IER_TXRDY;
843 sx_out(bp, CD186x_IER, port->IER);
845 if (mcr & MCR_DSSXHG) {
846 if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
847 tty->hw_stopped = 0;
848 port->IER |= IER_TXRDY;
849 if (port->xmit_cnt <= port->wakeup_chars)
850 tty_wakeup(tty);
851 } else {
852 tty->hw_stopped = 1;
853 port->IER &= ~IER_TXRDY;
855 sx_out(bp, CD186x_IER, port->IER);
857 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
859 /* Clear change bits */
860 sx_out(bp, CD186x_MCR, 0);
864 /* The main interrupt processing routine */
865 static irqreturn_t sx_interrupt(int irq, void *dev_id)
867 unsigned char status;
868 unsigned char ack;
869 struct specialix_board *bp;
870 unsigned long loop = 0;
871 int saved_reg;
872 unsigned long flags;
874 func_enter();
876 bp = dev_id;
877 spin_lock_irqsave(&bp->lock, flags);
879 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);
880 if (!(bp->flags & SX_BOARD_ACTIVE)) {
881 dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq);
882 spin_unlock_irqrestore(&bp->lock, flags);
883 func_exit();
884 return IRQ_NONE;
887 saved_reg = bp->reg;
889 while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
890 (SRSR_RREQint |
891 SRSR_TREQint |
892 SRSR_MREQint)))) {
893 if (status & SRSR_RREQint) {
894 ack = sx_in(bp, CD186x_RRAR);
896 if (ack == (SX_ID | GIVR_IT_RCV))
897 sx_receive(bp);
898 else if (ack == (SX_ID | GIVR_IT_REXC))
899 sx_receive_exc(bp);
900 else
901 printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
902 board_No(bp), status, ack);
904 } else if (status & SRSR_TREQint) {
905 ack = sx_in(bp, CD186x_TRAR);
907 if (ack == (SX_ID | GIVR_IT_TX))
908 sx_transmit(bp);
909 else
910 printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
911 board_No(bp), status, ack, port_No (sx_get_port (bp, "Int")));
912 } else if (status & SRSR_MREQint) {
913 ack = sx_in(bp, CD186x_MRAR);
915 if (ack == (SX_ID | GIVR_IT_MODEM))
916 sx_check_modem(bp);
917 else
918 printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
919 board_No(bp), status, ack);
923 sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */
925 bp->reg = saved_reg;
926 outb (bp->reg, bp->base + SX_ADDR_REG);
927 spin_unlock_irqrestore(&bp->lock, flags);
928 func_exit();
929 return IRQ_HANDLED;
934 * Routines for open & close processing.
937 static void turn_ints_off (struct specialix_board *bp)
939 unsigned long flags;
941 func_enter();
942 if (bp->flags & SX_BOARD_IS_PCI) {
943 /* This was intended for enabeling the interrupt on the
944 * PCI card. However it seems that it's already enabled
945 * and as PCI interrupts can be shared, there is no real
946 * reason to have to turn it off. */
949 spin_lock_irqsave(&bp->lock, flags);
950 (void) sx_in_off (bp, 0); /* Turn off interrupts. */
951 spin_unlock_irqrestore(&bp->lock, flags);
953 func_exit();
956 static void turn_ints_on (struct specialix_board *bp)
958 unsigned long flags;
960 func_enter();
962 if (bp->flags & SX_BOARD_IS_PCI) {
963 /* play with the PCI chip. See comment above. */
965 spin_lock_irqsave(&bp->lock, flags);
966 (void) sx_in (bp, 0); /* Turn ON interrupts. */
967 spin_unlock_irqrestore(&bp->lock, flags);
969 func_exit();
973 /* Called with disabled interrupts */
974 static inline int sx_setup_board(struct specialix_board * bp)
976 int error;
978 if (bp->flags & SX_BOARD_ACTIVE)
979 return 0;
981 if (bp->flags & SX_BOARD_IS_PCI)
982 error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp);
983 else
984 error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED, "specialix IO8+", bp);
986 if (error)
987 return error;
989 turn_ints_on (bp);
990 bp->flags |= SX_BOARD_ACTIVE;
992 return 0;
996 /* Called with disabled interrupts */
997 static inline void sx_shutdown_board(struct specialix_board *bp)
999 func_enter();
1001 if (!(bp->flags & SX_BOARD_ACTIVE)) {
1002 func_exit();
1003 return;
1006 bp->flags &= ~SX_BOARD_ACTIVE;
1008 dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
1009 bp->irq, board_No (bp));
1010 free_irq(bp->irq, bp);
1012 turn_ints_off (bp);
1015 func_exit();
1020 * Setting up port characteristics.
1021 * Must be called with disabled interrupts
1023 static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
1025 struct tty_struct *tty;
1026 unsigned long baud;
1027 long tmp;
1028 unsigned char cor1 = 0, cor3 = 0;
1029 unsigned char mcor1 = 0, mcor2 = 0;
1030 static unsigned long again;
1031 unsigned long flags;
1033 func_enter();
1035 if (!(tty = port->tty) || !tty->termios) {
1036 func_exit();
1037 return;
1040 port->IER = 0;
1041 port->COR2 = 0;
1042 /* Select port on the board */
1043 spin_lock_irqsave(&bp->lock, flags);
1044 sx_out(bp, CD186x_CAR, port_No(port));
1046 /* The Specialix board doens't implement the RTS lines.
1047 They are used to set the IRQ level. Don't touch them. */
1048 if (SX_CRTSCTS(tty))
1049 port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1050 else
1051 port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1052 spin_unlock_irqrestore(&bp->lock, flags);
1053 dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
1054 baud = tty_get_baud_rate(tty);
1056 if (baud == 38400) {
1057 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1058 baud = 57600;
1059 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1060 baud = 115200;
1063 if (!baud) {
1064 /* Drop DTR & exit */
1065 dprintk (SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n");
1066 if (!SX_CRTSCTS (tty)) {
1067 port -> MSVR &= ~ MSVR_DTR;
1068 spin_lock_irqsave(&bp->lock, flags);
1069 sx_out(bp, CD186x_MSVR, port->MSVR );
1070 spin_unlock_irqrestore(&bp->lock, flags);
1072 else
1073 dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1074 return;
1075 } else {
1076 /* Set DTR on */
1077 if (!SX_CRTSCTS (tty)) {
1078 port ->MSVR |= MSVR_DTR;
1083 * Now we must calculate some speed depended things
1086 /* Set baud rate for port */
1087 tmp = port->custom_divisor ;
1088 if ( tmp )
1089 printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n"
1090 "This is an untested option, please be carefull.\n",
1091 port_No (port), tmp);
1092 else
1093 tmp = (((SX_OSCFREQ + baud/2) / baud +
1094 CD186x_TPC/2) / CD186x_TPC);
1096 if ((tmp < 0x10) && time_before(again, jiffies)) {
1097 again = jiffies + HZ * 60;
1098 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1099 if (tmp >= 12) {
1100 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1101 "Performance degradation is possible.\n"
1102 "Read specialix.txt for more info.\n",
1103 port_No (port), tmp);
1104 } else {
1105 printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1106 "Warning: overstressing Cirrus chip. "
1107 "This might not work.\n"
1108 "Read specialix.txt for more info.\n",
1109 port_No (port), tmp);
1112 spin_lock_irqsave(&bp->lock, flags);
1113 sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1114 sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1115 sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1116 sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1117 spin_unlock_irqrestore(&bp->lock, flags);
1118 if (port->custom_divisor)
1119 baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
1120 baud = (baud + 5) / 10; /* Estimated CPS */
1122 /* Two timer ticks seems enough to wakeup something like SLIP driver */
1123 tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1124 port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1125 SERIAL_XMIT_SIZE - 1 : tmp);
1127 /* Receiver timeout will be transmission time for 1.5 chars */
1128 tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1129 tmp = (tmp > 0xff) ? 0xff : tmp;
1130 spin_lock_irqsave(&bp->lock, flags);
1131 sx_out(bp, CD186x_RTPR, tmp);
1132 spin_unlock_irqrestore(&bp->lock, flags);
1133 switch (C_CSIZE(tty)) {
1134 case CS5:
1135 cor1 |= COR1_5BITS;
1136 break;
1137 case CS6:
1138 cor1 |= COR1_6BITS;
1139 break;
1140 case CS7:
1141 cor1 |= COR1_7BITS;
1142 break;
1143 case CS8:
1144 cor1 |= COR1_8BITS;
1145 break;
1148 if (C_CSTOPB(tty))
1149 cor1 |= COR1_2SB;
1151 cor1 |= COR1_IGNORE;
1152 if (C_PARENB(tty)) {
1153 cor1 |= COR1_NORMPAR;
1154 if (C_PARODD(tty))
1155 cor1 |= COR1_ODDP;
1156 if (I_INPCK(tty))
1157 cor1 &= ~COR1_IGNORE;
1159 /* Set marking of some errors */
1160 port->mark_mask = RCSR_OE | RCSR_TOUT;
1161 if (I_INPCK(tty))
1162 port->mark_mask |= RCSR_FE | RCSR_PE;
1163 if (I_BRKINT(tty) || I_PARMRK(tty))
1164 port->mark_mask |= RCSR_BREAK;
1165 if (I_IGNPAR(tty))
1166 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1167 if (I_IGNBRK(tty)) {
1168 port->mark_mask &= ~RCSR_BREAK;
1169 if (I_IGNPAR(tty))
1170 /* Real raw mode. Ignore all */
1171 port->mark_mask &= ~RCSR_OE;
1173 /* Enable Hardware Flow Control */
1174 if (C_CRTSCTS(tty)) {
1175 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1176 port->IER |= IER_DSR | IER_CTS;
1177 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1178 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1179 spin_lock_irqsave(&bp->lock, flags);
1180 tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
1181 spin_unlock_irqrestore(&bp->lock, flags);
1182 #else
1183 port->COR2 |= COR2_CTSAE;
1184 #endif
1186 /* Enable Software Flow Control. FIXME: I'm not sure about this */
1187 /* Some people reported that it works, but I still doubt it */
1188 if (I_IXON(tty)) {
1189 port->COR2 |= COR2_TXIBE;
1190 cor3 |= (COR3_FCT | COR3_SCDE);
1191 if (I_IXANY(tty))
1192 port->COR2 |= COR2_IXM;
1193 spin_lock_irqsave(&bp->lock, flags);
1194 sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1195 sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1196 sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1197 sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1198 spin_unlock_irqrestore(&bp->lock, flags);
1200 if (!C_CLOCAL(tty)) {
1201 /* Enable CD check */
1202 port->IER |= IER_CD;
1203 mcor1 |= MCOR1_CDZD;
1204 mcor2 |= MCOR2_CDOD;
1207 if (C_CREAD(tty))
1208 /* Enable receiver */
1209 port->IER |= IER_RXD;
1211 /* Set input FIFO size (1-8 bytes) */
1212 cor3 |= sx_rxfifo;
1213 /* Setting up CD186x channel registers */
1214 spin_lock_irqsave(&bp->lock, flags);
1215 sx_out(bp, CD186x_COR1, cor1);
1216 sx_out(bp, CD186x_COR2, port->COR2);
1217 sx_out(bp, CD186x_COR3, cor3);
1218 spin_unlock_irqrestore(&bp->lock, flags);
1219 /* Make CD186x know about registers change */
1220 sx_wait_CCR(bp);
1221 spin_lock_irqsave(&bp->lock, flags);
1222 sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1223 /* Setting up modem option registers */
1224 dprintk (SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2);
1225 sx_out(bp, CD186x_MCOR1, mcor1);
1226 sx_out(bp, CD186x_MCOR2, mcor2);
1227 spin_unlock_irqrestore(&bp->lock, flags);
1228 /* Enable CD186x transmitter & receiver */
1229 sx_wait_CCR(bp);
1230 spin_lock_irqsave(&bp->lock, flags);
1231 sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1232 /* Enable interrupts */
1233 sx_out(bp, CD186x_IER, port->IER);
1234 /* And finally set the modem lines... */
1235 sx_out(bp, CD186x_MSVR, port->MSVR);
1236 spin_unlock_irqrestore(&bp->lock, flags);
1238 func_exit();
1242 /* Must be called with interrupts enabled */
1243 static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port)
1245 unsigned long flags;
1247 func_enter();
1249 if (port->flags & ASYNC_INITIALIZED) {
1250 func_exit();
1251 return 0;
1254 if (!port->xmit_buf) {
1255 /* We may sleep in get_zeroed_page() */
1256 unsigned long tmp;
1258 if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
1259 func_exit();
1260 return -ENOMEM;
1263 if (port->xmit_buf) {
1264 free_page(tmp);
1265 func_exit();
1266 return -ERESTARTSYS;
1268 port->xmit_buf = (unsigned char *) tmp;
1271 spin_lock_irqsave(&port->lock, flags);
1273 if (port->tty)
1274 clear_bit(TTY_IO_ERROR, &port->tty->flags);
1276 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1277 sx_change_speed(bp, port);
1278 port->flags |= ASYNC_INITIALIZED;
1280 spin_unlock_irqrestore(&port->lock, flags);
1283 func_exit();
1284 return 0;
1288 /* Must be called with interrupts disabled */
1289 static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port)
1291 struct tty_struct *tty;
1292 int i;
1293 unsigned long flags;
1295 func_enter();
1297 if (!(port->flags & ASYNC_INITIALIZED)) {
1298 func_exit();
1299 return;
1302 if (sx_debug & SX_DEBUG_FIFO) {
1303 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
1304 board_No(bp), port_No(port), port->overrun);
1305 for (i = 0; i < 10; i++) {
1306 dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1308 dprintk(SX_DEBUG_FIFO, "].\n");
1311 if (port->xmit_buf) {
1312 free_page((unsigned long) port->xmit_buf);
1313 port->xmit_buf = NULL;
1316 /* Select port */
1317 spin_lock_irqsave(&bp->lock, flags);
1318 sx_out(bp, CD186x_CAR, port_No(port));
1320 if (!(tty = port->tty) || C_HUPCL(tty)) {
1321 /* Drop DTR */
1322 sx_out(bp, CD186x_MSVDTR, 0);
1324 spin_unlock_irqrestore(&bp->lock, flags);
1325 /* Reset port */
1326 sx_wait_CCR(bp);
1327 spin_lock_irqsave(&bp->lock, flags);
1328 sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1329 /* Disable all interrupts from this port */
1330 port->IER = 0;
1331 sx_out(bp, CD186x_IER, port->IER);
1332 spin_unlock_irqrestore(&bp->lock, flags);
1333 if (tty)
1334 set_bit(TTY_IO_ERROR, &tty->flags);
1335 port->flags &= ~ASYNC_INITIALIZED;
1337 if (!bp->count)
1338 sx_shutdown_board(bp);
1339 func_exit();
1343 static int block_til_ready(struct tty_struct *tty, struct file * filp,
1344 struct specialix_port *port)
1346 DECLARE_WAITQUEUE(wait, current);
1347 struct specialix_board *bp = port_Board(port);
1348 int retval;
1349 int do_clocal = 0;
1350 int CD;
1351 unsigned long flags;
1353 func_enter();
1356 * If the device is in the middle of being closed, then block
1357 * until it's done, and then try again.
1359 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
1360 interruptible_sleep_on(&port->close_wait);
1361 if (port->flags & ASYNC_HUP_NOTIFY) {
1362 func_exit();
1363 return -EAGAIN;
1364 } else {
1365 func_exit();
1366 return -ERESTARTSYS;
1371 * If non-blocking mode is set, or the port is not enabled,
1372 * then make the check up front and then exit.
1374 if ((filp->f_flags & O_NONBLOCK) ||
1375 (tty->flags & (1 << TTY_IO_ERROR))) {
1376 port->flags |= ASYNC_NORMAL_ACTIVE;
1377 func_exit();
1378 return 0;
1381 if (C_CLOCAL(tty))
1382 do_clocal = 1;
1385 * Block waiting for the carrier detect and the line to become
1386 * free (i.e., not in use by the callout). While we are in
1387 * this loop, info->count is dropped by one, so that
1388 * rs_close() knows when to free things. We restore it upon
1389 * exit, either normal or abnormal.
1391 retval = 0;
1392 add_wait_queue(&port->open_wait, &wait);
1393 spin_lock_irqsave(&port->lock, flags);
1394 if (!tty_hung_up_p(filp)) {
1395 port->count--;
1397 spin_unlock_irqrestore(&port->lock, flags);
1398 port->blocked_open++;
1399 while (1) {
1400 spin_lock_irqsave(&bp->lock, flags);
1401 sx_out(bp, CD186x_CAR, port_No(port));
1402 CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1403 if (SX_CRTSCTS (tty)) {
1404 /* Activate RTS */
1405 port->MSVR |= MSVR_DTR; /* WTF? */
1406 sx_out (bp, CD186x_MSVR, port->MSVR);
1407 } else {
1408 /* Activate DTR */
1409 port->MSVR |= MSVR_DTR;
1410 sx_out (bp, CD186x_MSVR, port->MSVR);
1412 spin_unlock_irqrestore(&bp->lock, flags);
1413 set_current_state(TASK_INTERRUPTIBLE);
1414 if (tty_hung_up_p(filp) ||
1415 !(port->flags & ASYNC_INITIALIZED)) {
1416 if (port->flags & ASYNC_HUP_NOTIFY)
1417 retval = -EAGAIN;
1418 else
1419 retval = -ERESTARTSYS;
1420 break;
1422 if (!(port->flags & ASYNC_CLOSING) &&
1423 (do_clocal || CD))
1424 break;
1425 if (signal_pending(current)) {
1426 retval = -ERESTARTSYS;
1427 break;
1429 schedule();
1432 set_current_state(TASK_RUNNING);
1433 remove_wait_queue(&port->open_wait, &wait);
1434 spin_lock_irqsave(&port->lock, flags);
1435 if (!tty_hung_up_p(filp)) {
1436 port->count++;
1438 port->blocked_open--;
1439 spin_unlock_irqrestore(&port->lock, flags);
1440 if (retval) {
1441 func_exit();
1442 return retval;
1445 port->flags |= ASYNC_NORMAL_ACTIVE;
1446 func_exit();
1447 return 0;
1451 static int sx_open(struct tty_struct * tty, struct file * filp)
1453 int board;
1454 int error;
1455 struct specialix_port * port;
1456 struct specialix_board * bp;
1457 int i;
1458 unsigned long flags;
1460 func_enter();
1462 board = SX_BOARD(tty->index);
1464 if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1465 func_exit();
1466 return -ENODEV;
1469 bp = &sx_board[board];
1470 port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1471 port->overrun = 0;
1472 for (i = 0; i < 10; i++)
1473 port->hits[i]=0;
1475 dprintk (SX_DEBUG_OPEN, "Board = %d, bp = %p, port = %p, portno = %d.\n",
1476 board, bp, port, SX_PORT(tty->index));
1478 if (sx_paranoia_check(port, tty->name, "sx_open")) {
1479 func_enter();
1480 return -ENODEV;
1483 if ((error = sx_setup_board(bp))) {
1484 func_exit();
1485 return error;
1488 spin_lock_irqsave(&bp->lock, flags);
1489 port->count++;
1490 bp->count++;
1491 tty->driver_data = port;
1492 port->tty = tty;
1493 spin_unlock_irqrestore(&bp->lock, flags);
1495 if ((error = sx_setup_port(bp, port))) {
1496 func_enter();
1497 return error;
1500 if ((error = block_til_ready(tty, filp, port))) {
1501 func_enter();
1502 return error;
1505 func_exit();
1506 return 0;
1510 static void sx_close(struct tty_struct * tty, struct file * filp)
1512 struct specialix_port *port = (struct specialix_port *) tty->driver_data;
1513 struct specialix_board *bp;
1514 unsigned long flags;
1515 unsigned long timeout;
1517 func_enter();
1518 if (!port || sx_paranoia_check(port, tty->name, "close")) {
1519 func_exit();
1520 return;
1522 spin_lock_irqsave(&port->lock, flags);
1524 if (tty_hung_up_p(filp)) {
1525 spin_unlock_irqrestore(&port->lock, flags);
1526 func_exit();
1527 return;
1530 bp = port_Board(port);
1531 if ((tty->count == 1) && (port->count != 1)) {
1532 printk(KERN_ERR "sx%d: sx_close: bad port count;"
1533 " tty->count is 1, port count is %d\n",
1534 board_No(bp), port->count);
1535 port->count = 1;
1538 if (port->count > 1) {
1539 port->count--;
1540 bp->count--;
1542 spin_unlock_irqrestore(&port->lock, flags);
1544 func_exit();
1545 return;
1547 port->flags |= ASYNC_CLOSING;
1549 * Now we wait for the transmit buffer to clear; and we notify
1550 * the line discipline to only process XON/XOFF characters.
1552 tty->closing = 1;
1553 spin_unlock_irqrestore(&port->lock, flags);
1554 dprintk (SX_DEBUG_OPEN, "Closing\n");
1555 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
1556 tty_wait_until_sent(tty, port->closing_wait);
1559 * At this point we stop accepting input. To do this, we
1560 * disable the receive line status interrupts, and tell the
1561 * interrupt driver to stop checking the data ready bit in the
1562 * line status register.
1564 dprintk (SX_DEBUG_OPEN, "Closed\n");
1565 port->IER &= ~IER_RXD;
1566 if (port->flags & ASYNC_INITIALIZED) {
1567 port->IER &= ~IER_TXRDY;
1568 port->IER |= IER_TXEMPTY;
1569 spin_lock_irqsave(&bp->lock, flags);
1570 sx_out(bp, CD186x_CAR, port_No(port));
1571 sx_out(bp, CD186x_IER, port->IER);
1572 spin_unlock_irqrestore(&bp->lock, flags);
1574 * Before we drop DTR, make sure the UART transmitter
1575 * has completely drained; this is especially
1576 * important if there is a transmit FIFO!
1578 timeout = jiffies+HZ;
1579 while(port->IER & IER_TXEMPTY) {
1580 set_current_state (TASK_INTERRUPTIBLE);
1581 msleep_interruptible(jiffies_to_msecs(port->timeout));
1582 if (time_after(jiffies, timeout)) {
1583 printk (KERN_INFO "Timeout waiting for close\n");
1584 break;
1590 if (--bp->count < 0) {
1591 printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1592 board_No(bp), bp->count, tty->index);
1593 bp->count = 0;
1595 if (--port->count < 0) {
1596 printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n",
1597 board_No(bp), port_No(port), port->count);
1598 port->count = 0;
1601 sx_shutdown_port(bp, port);
1602 if (tty->driver->flush_buffer)
1603 tty->driver->flush_buffer(tty);
1604 tty_ldisc_flush(tty);
1605 spin_lock_irqsave(&port->lock, flags);
1606 tty->closing = 0;
1607 port->tty = NULL;
1608 spin_unlock_irqrestore(&port->lock, flags);
1609 if (port->blocked_open) {
1610 if (port->close_delay) {
1611 msleep_interruptible(jiffies_to_msecs(port->close_delay));
1613 wake_up_interruptible(&port->open_wait);
1615 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1616 wake_up_interruptible(&port->close_wait);
1618 func_exit();
1622 static int sx_write(struct tty_struct * tty,
1623 const unsigned char *buf, int count)
1625 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1626 struct specialix_board *bp;
1627 int c, total = 0;
1628 unsigned long flags;
1630 func_enter();
1631 if (sx_paranoia_check(port, tty->name, "sx_write")) {
1632 func_exit();
1633 return 0;
1636 bp = port_Board(port);
1638 if (!port->xmit_buf) {
1639 func_exit();
1640 return 0;
1643 while (1) {
1644 spin_lock_irqsave(&port->lock, flags);
1645 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1646 SERIAL_XMIT_SIZE - port->xmit_head));
1647 if (c <= 0) {
1648 spin_unlock_irqrestore(&port->lock, flags);
1649 break;
1651 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1652 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1653 port->xmit_cnt += c;
1654 spin_unlock_irqrestore(&port->lock, flags);
1656 buf += c;
1657 count -= c;
1658 total += c;
1661 spin_lock_irqsave(&bp->lock, flags);
1662 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1663 !(port->IER & IER_TXRDY)) {
1664 port->IER |= IER_TXRDY;
1665 sx_out(bp, CD186x_CAR, port_No(port));
1666 sx_out(bp, CD186x_IER, port->IER);
1668 spin_unlock_irqrestore(&bp->lock, flags);
1669 func_exit();
1671 return total;
1675 static void sx_put_char(struct tty_struct * tty, unsigned char ch)
1677 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1678 unsigned long flags;
1679 struct specialix_board * bp;
1681 func_enter();
1683 if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1684 func_exit();
1685 return;
1687 dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1688 if (!port->xmit_buf) {
1689 func_exit();
1690 return;
1692 bp = port_Board(port);
1693 spin_lock_irqsave(&port->lock, flags);
1695 dprintk (SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", port->xmit_cnt, port->xmit_buf);
1696 if ((port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) || (!port->xmit_buf)) {
1697 spin_unlock_irqrestore(&port->lock, flags);
1698 dprintk (SX_DEBUG_TX, "Exit size\n");
1699 func_exit();
1700 return;
1702 dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
1703 port->xmit_buf[port->xmit_head++] = ch;
1704 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1705 port->xmit_cnt++;
1706 spin_unlock_irqrestore(&port->lock, flags);
1708 func_exit();
1712 static void sx_flush_chars(struct tty_struct * tty)
1714 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1715 unsigned long flags;
1716 struct specialix_board * bp = port_Board(port);
1718 func_enter();
1720 if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1721 func_exit();
1722 return;
1724 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1725 !port->xmit_buf) {
1726 func_exit();
1727 return;
1729 spin_lock_irqsave(&bp->lock, flags);
1730 port->IER |= IER_TXRDY;
1731 sx_out(port_Board(port), CD186x_CAR, port_No(port));
1732 sx_out(port_Board(port), CD186x_IER, port->IER);
1733 spin_unlock_irqrestore(&bp->lock, flags);
1735 func_exit();
1739 static int sx_write_room(struct tty_struct * tty)
1741 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1742 int ret;
1744 func_enter();
1746 if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1747 func_exit();
1748 return 0;
1751 ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1752 if (ret < 0)
1753 ret = 0;
1755 func_exit();
1756 return ret;
1760 static int sx_chars_in_buffer(struct tty_struct *tty)
1762 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1764 func_enter();
1766 if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
1767 func_exit();
1768 return 0;
1770 func_exit();
1771 return port->xmit_cnt;
1775 static void sx_flush_buffer(struct tty_struct *tty)
1777 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1778 unsigned long flags;
1779 struct specialix_board * bp;
1781 func_enter();
1783 if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
1784 func_exit();
1785 return;
1788 bp = port_Board(port);
1789 spin_lock_irqsave(&port->lock, flags);
1790 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1791 spin_unlock_irqrestore(&port->lock, flags);
1792 tty_wakeup(tty);
1794 func_exit();
1798 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1800 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1801 struct specialix_board * bp;
1802 unsigned char status;
1803 unsigned int result;
1804 unsigned long flags;
1806 func_enter();
1808 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1809 func_exit();
1810 return -ENODEV;
1813 bp = port_Board(port);
1814 spin_lock_irqsave (&bp->lock, flags);
1815 sx_out(bp, CD186x_CAR, port_No(port));
1816 status = sx_in(bp, CD186x_MSVR);
1817 spin_unlock_irqrestore(&bp->lock, flags);
1818 dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1819 port_No(port), status, sx_in (bp, CD186x_CAR));
1820 dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1821 if (SX_CRTSCTS(port->tty)) {
1822 result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
1823 | ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1824 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1825 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1826 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1827 } else {
1828 result = /* (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
1829 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1830 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
1831 |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1832 | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1835 func_exit();
1837 return result;
1841 static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1842 unsigned int set, unsigned int clear)
1844 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1845 unsigned long flags;
1846 struct specialix_board *bp;
1848 func_enter();
1850 if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1851 func_exit();
1852 return -ENODEV;
1855 bp = port_Board(port);
1857 spin_lock_irqsave(&port->lock, flags);
1858 /* if (set & TIOCM_RTS)
1859 port->MSVR |= MSVR_RTS; */
1860 /* if (set & TIOCM_DTR)
1861 port->MSVR |= MSVR_DTR; */
1863 if (SX_CRTSCTS(port->tty)) {
1864 if (set & TIOCM_RTS)
1865 port->MSVR |= MSVR_DTR;
1866 } else {
1867 if (set & TIOCM_DTR)
1868 port->MSVR |= MSVR_DTR;
1871 /* if (clear & TIOCM_RTS)
1872 port->MSVR &= ~MSVR_RTS; */
1873 /* if (clear & TIOCM_DTR)
1874 port->MSVR &= ~MSVR_DTR; */
1875 if (SX_CRTSCTS(port->tty)) {
1876 if (clear & TIOCM_RTS)
1877 port->MSVR &= ~MSVR_DTR;
1878 } else {
1879 if (clear & TIOCM_DTR)
1880 port->MSVR &= ~MSVR_DTR;
1882 spin_lock_irqsave(&bp->lock, flags);
1883 sx_out(bp, CD186x_CAR, port_No(port));
1884 sx_out(bp, CD186x_MSVR, port->MSVR);
1885 spin_unlock_irqrestore(&bp->lock, flags);
1886 spin_unlock_irqrestore(&port->lock, flags);
1887 func_exit();
1888 return 0;
1892 static inline void sx_send_break(struct specialix_port * port, unsigned long length)
1894 struct specialix_board *bp = port_Board(port);
1895 unsigned long flags;
1897 func_enter();
1899 spin_lock_irqsave (&port->lock, flags);
1900 port->break_length = SPECIALIX_TPS / HZ * length;
1901 port->COR2 |= COR2_ETC;
1902 port->IER |= IER_TXRDY;
1903 spin_lock_irqsave(&bp->lock, flags);
1904 sx_out(bp, CD186x_CAR, port_No(port));
1905 sx_out(bp, CD186x_COR2, port->COR2);
1906 sx_out(bp, CD186x_IER, port->IER);
1907 spin_unlock_irqrestore(&bp->lock, flags);
1908 spin_unlock_irqrestore (&port->lock, flags);
1909 sx_wait_CCR(bp);
1910 spin_lock_irqsave(&bp->lock, flags);
1911 sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1912 spin_unlock_irqrestore(&bp->lock, flags);
1913 sx_wait_CCR(bp);
1915 func_exit();
1919 static inline int sx_set_serial_info(struct specialix_port * port,
1920 struct serial_struct __user * newinfo)
1922 struct serial_struct tmp;
1923 struct specialix_board *bp = port_Board(port);
1924 int change_speed;
1926 func_enter();
1928 if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1929 func_exit();
1930 return -EFAULT;
1933 if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
1934 func_enter();
1935 return -EFAULT;
1938 #if 0
1939 if ((tmp.irq != bp->irq) ||
1940 (tmp.port != bp->base) ||
1941 (tmp.type != PORT_CIRRUS) ||
1942 (tmp.baud_base != (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) ||
1943 (tmp.custom_divisor != 0) ||
1944 (tmp.xmit_fifo_size != CD186x_NFIFO) ||
1945 (tmp.flags & ~SPECIALIX_LEGAL_FLAGS)) {
1946 func_exit();
1947 return -EINVAL;
1949 #endif
1951 change_speed = ((port->flags & ASYNC_SPD_MASK) !=
1952 (tmp.flags & ASYNC_SPD_MASK));
1953 change_speed |= (tmp.custom_divisor != port->custom_divisor);
1955 if (!capable(CAP_SYS_ADMIN)) {
1956 if ((tmp.close_delay != port->close_delay) ||
1957 (tmp.closing_wait != port->closing_wait) ||
1958 ((tmp.flags & ~ASYNC_USR_MASK) !=
1959 (port->flags & ~ASYNC_USR_MASK))) {
1960 func_exit();
1961 return -EPERM;
1963 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
1964 (tmp.flags & ASYNC_USR_MASK));
1965 port->custom_divisor = tmp.custom_divisor;
1966 } else {
1967 port->flags = ((port->flags & ~ASYNC_FLAGS) |
1968 (tmp.flags & ASYNC_FLAGS));
1969 port->close_delay = tmp.close_delay;
1970 port->closing_wait = tmp.closing_wait;
1971 port->custom_divisor = tmp.custom_divisor;
1973 if (change_speed) {
1974 sx_change_speed(bp, port);
1976 func_exit();
1977 return 0;
1981 static inline int sx_get_serial_info(struct specialix_port * port,
1982 struct serial_struct __user *retinfo)
1984 struct serial_struct tmp;
1985 struct specialix_board *bp = port_Board(port);
1987 func_enter();
1990 if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
1991 return -EFAULT;
1994 memset(&tmp, 0, sizeof(tmp));
1995 tmp.type = PORT_CIRRUS;
1996 tmp.line = port - sx_port;
1997 tmp.port = bp->base;
1998 tmp.irq = bp->irq;
1999 tmp.flags = port->flags;
2000 tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
2001 tmp.close_delay = port->close_delay * HZ/100;
2002 tmp.closing_wait = port->closing_wait * HZ/100;
2003 tmp.custom_divisor = port->custom_divisor;
2004 tmp.xmit_fifo_size = CD186x_NFIFO;
2005 if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
2006 func_exit();
2007 return -EFAULT;
2010 func_exit();
2011 return 0;
2015 static int sx_ioctl(struct tty_struct * tty, struct file * filp,
2016 unsigned int cmd, unsigned long arg)
2018 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2019 int retval;
2020 void __user *argp = (void __user *)arg;
2022 func_enter();
2024 if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
2025 func_exit();
2026 return -ENODEV;
2029 switch (cmd) {
2030 case TCSBRK: /* SVID version: non-zero arg --> no break */
2031 retval = tty_check_change(tty);
2032 if (retval) {
2033 func_exit();
2034 return retval;
2036 tty_wait_until_sent(tty, 0);
2037 if (!arg)
2038 sx_send_break(port, HZ/4); /* 1/4 second */
2039 return 0;
2040 case TCSBRKP: /* support for POSIX tcsendbreak() */
2041 retval = tty_check_change(tty);
2042 if (retval) {
2043 func_exit();
2044 return retval;
2046 tty_wait_until_sent(tty, 0);
2047 sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
2048 func_exit();
2049 return 0;
2050 case TIOCGSOFTCAR:
2051 if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) {
2052 func_exit();
2053 return -EFAULT;
2055 func_exit();
2056 return 0;
2057 case TIOCSSOFTCAR:
2058 if (get_user(arg, (unsigned long __user *) argp)) {
2059 func_exit();
2060 return -EFAULT;
2062 tty->termios->c_cflag =
2063 ((tty->termios->c_cflag & ~CLOCAL) |
2064 (arg ? CLOCAL : 0));
2065 func_exit();
2066 return 0;
2067 case TIOCGSERIAL:
2068 func_exit();
2069 return sx_get_serial_info(port, argp);
2070 case TIOCSSERIAL:
2071 func_exit();
2072 return sx_set_serial_info(port, argp);
2073 default:
2074 func_exit();
2075 return -ENOIOCTLCMD;
2077 func_exit();
2078 return 0;
2082 static void sx_throttle(struct tty_struct * tty)
2084 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2085 struct specialix_board *bp;
2086 unsigned long flags;
2088 func_enter();
2090 if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
2091 func_exit();
2092 return;
2095 bp = port_Board(port);
2097 /* Use DTR instead of RTS ! */
2098 if (SX_CRTSCTS (tty))
2099 port->MSVR &= ~MSVR_DTR;
2100 else {
2101 /* Auch!!! I think the system shouldn't call this then. */
2102 /* Or maybe we're supposed (allowed?) to do our side of hw
2103 handshake anyway, even when hardware handshake is off.
2104 When you see this in your logs, please report.... */
2105 printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
2106 port_No (port));
2108 spin_lock_irqsave(&bp->lock, flags);
2109 sx_out(bp, CD186x_CAR, port_No(port));
2110 spin_unlock_irqrestore(&bp->lock, flags);
2111 if (I_IXOFF(tty)) {
2112 spin_unlock_irqrestore(&bp->lock, flags);
2113 sx_wait_CCR(bp);
2114 spin_lock_irqsave(&bp->lock, flags);
2115 sx_out(bp, CD186x_CCR, CCR_SSCH2);
2116 spin_unlock_irqrestore(&bp->lock, flags);
2117 sx_wait_CCR(bp);
2119 spin_lock_irqsave(&bp->lock, flags);
2120 sx_out(bp, CD186x_MSVR, port->MSVR);
2121 spin_unlock_irqrestore(&bp->lock, flags);
2123 func_exit();
2127 static void sx_unthrottle(struct tty_struct * tty)
2129 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2130 struct specialix_board *bp;
2131 unsigned long flags;
2133 func_enter();
2135 if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
2136 func_exit();
2137 return;
2140 bp = port_Board(port);
2142 spin_lock_irqsave(&port->lock, flags);
2143 /* XXXX Use DTR INSTEAD???? */
2144 if (SX_CRTSCTS(tty)) {
2145 port->MSVR |= MSVR_DTR;
2146 } /* Else clause: see remark in "sx_throttle"... */
2147 spin_lock_irqsave(&bp->lock, flags);
2148 sx_out(bp, CD186x_CAR, port_No(port));
2149 spin_unlock_irqrestore(&bp->lock, flags);
2150 if (I_IXOFF(tty)) {
2151 spin_unlock_irqrestore(&port->lock, flags);
2152 sx_wait_CCR(bp);
2153 spin_lock_irqsave(&bp->lock, flags);
2154 sx_out(bp, CD186x_CCR, CCR_SSCH1);
2155 spin_unlock_irqrestore(&bp->lock, flags);
2156 sx_wait_CCR(bp);
2157 spin_lock_irqsave(&port->lock, flags);
2159 spin_lock_irqsave(&bp->lock, flags);
2160 sx_out(bp, CD186x_MSVR, port->MSVR);
2161 spin_unlock_irqrestore(&bp->lock, flags);
2162 spin_unlock_irqrestore(&port->lock, flags);
2164 func_exit();
2168 static void sx_stop(struct tty_struct * tty)
2170 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2171 struct specialix_board *bp;
2172 unsigned long flags;
2174 func_enter();
2176 if (sx_paranoia_check(port, tty->name, "sx_stop")) {
2177 func_exit();
2178 return;
2181 bp = port_Board(port);
2183 spin_lock_irqsave(&port->lock, flags);
2184 port->IER &= ~IER_TXRDY;
2185 spin_lock_irqsave(&bp->lock, flags);
2186 sx_out(bp, CD186x_CAR, port_No(port));
2187 sx_out(bp, CD186x_IER, port->IER);
2188 spin_unlock_irqrestore(&bp->lock, flags);
2189 spin_unlock_irqrestore(&port->lock, flags);
2191 func_exit();
2195 static void sx_start(struct tty_struct * tty)
2197 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2198 struct specialix_board *bp;
2199 unsigned long flags;
2201 func_enter();
2203 if (sx_paranoia_check(port, tty->name, "sx_start")) {
2204 func_exit();
2205 return;
2208 bp = port_Board(port);
2210 spin_lock_irqsave(&port->lock, flags);
2211 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2212 port->IER |= IER_TXRDY;
2213 spin_lock_irqsave(&bp->lock, flags);
2214 sx_out(bp, CD186x_CAR, port_No(port));
2215 sx_out(bp, CD186x_IER, port->IER);
2216 spin_unlock_irqrestore(&bp->lock, flags);
2218 spin_unlock_irqrestore(&port->lock, flags);
2220 func_exit();
2223 static void sx_hangup(struct tty_struct * tty)
2225 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2226 struct specialix_board *bp;
2227 unsigned long flags;
2229 func_enter();
2231 if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2232 func_exit();
2233 return;
2236 bp = port_Board(port);
2238 sx_shutdown_port(bp, port);
2239 spin_lock_irqsave(&port->lock, flags);
2240 bp->count -= port->count;
2241 if (bp->count < 0) {
2242 printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n",
2243 board_No(bp), bp->count, tty->index);
2244 bp->count = 0;
2246 port->count = 0;
2247 port->flags &= ~ASYNC_NORMAL_ACTIVE;
2248 port->tty = NULL;
2249 spin_unlock_irqrestore(&port->lock, flags);
2250 wake_up_interruptible(&port->open_wait);
2252 func_exit();
2256 static void sx_set_termios(struct tty_struct * tty, struct ktermios * old_termios)
2258 struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2259 unsigned long flags;
2260 struct specialix_board * bp;
2262 if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2263 return;
2265 if (tty->termios->c_cflag == old_termios->c_cflag &&
2266 tty->termios->c_iflag == old_termios->c_iflag)
2267 return;
2269 bp = port_Board(port);
2270 spin_lock_irqsave(&port->lock, flags);
2271 sx_change_speed(port_Board(port), port);
2272 spin_unlock_irqrestore(&port->lock, flags);
2274 if ((old_termios->c_cflag & CRTSCTS) &&
2275 !(tty->termios->c_cflag & CRTSCTS)) {
2276 tty->hw_stopped = 0;
2277 sx_start(tty);
2281 static const struct tty_operations sx_ops = {
2282 .open = sx_open,
2283 .close = sx_close,
2284 .write = sx_write,
2285 .put_char = sx_put_char,
2286 .flush_chars = sx_flush_chars,
2287 .write_room = sx_write_room,
2288 .chars_in_buffer = sx_chars_in_buffer,
2289 .flush_buffer = sx_flush_buffer,
2290 .ioctl = sx_ioctl,
2291 .throttle = sx_throttle,
2292 .unthrottle = sx_unthrottle,
2293 .set_termios = sx_set_termios,
2294 .stop = sx_stop,
2295 .start = sx_start,
2296 .hangup = sx_hangup,
2297 .tiocmget = sx_tiocmget,
2298 .tiocmset = sx_tiocmset,
2301 static int sx_init_drivers(void)
2303 int error;
2304 int i;
2306 func_enter();
2308 specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT);
2309 if (!specialix_driver) {
2310 printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n");
2311 func_exit();
2312 return 1;
2315 specialix_driver->owner = THIS_MODULE;
2316 specialix_driver->name = "ttyW";
2317 specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
2318 specialix_driver->type = TTY_DRIVER_TYPE_SERIAL;
2319 specialix_driver->subtype = SERIAL_TYPE_NORMAL;
2320 specialix_driver->init_termios = tty_std_termios;
2321 specialix_driver->init_termios.c_cflag =
2322 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2323 specialix_driver->init_termios.c_ispeed = 9600;
2324 specialix_driver->init_termios.c_ospeed = 9600;
2325 specialix_driver->flags = TTY_DRIVER_REAL_RAW;
2326 tty_set_operations(specialix_driver, &sx_ops);
2328 if ((error = tty_register_driver(specialix_driver))) {
2329 put_tty_driver(specialix_driver);
2330 printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2331 error);
2332 func_exit();
2333 return 1;
2335 memset(sx_port, 0, sizeof(sx_port));
2336 for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2337 sx_port[i].magic = SPECIALIX_MAGIC;
2338 sx_port[i].close_delay = 50 * HZ/100;
2339 sx_port[i].closing_wait = 3000 * HZ/100;
2340 init_waitqueue_head(&sx_port[i].open_wait);
2341 init_waitqueue_head(&sx_port[i].close_wait);
2342 spin_lock_init(&sx_port[i].lock);
2345 func_exit();
2346 return 0;
2349 static void sx_release_drivers(void)
2351 func_enter();
2353 tty_unregister_driver(specialix_driver);
2354 put_tty_driver(specialix_driver);
2355 func_exit();
2359 * This routine must be called by kernel at boot time
2361 static int __init specialix_init(void)
2363 int i;
2364 int found = 0;
2366 func_enter();
2368 printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
2369 printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2370 #ifdef CONFIG_SPECIALIX_RTSCTS
2371 printk (KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
2372 #else
2373 printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2374 #endif
2376 for (i = 0; i < SX_NBOARD; i++)
2377 spin_lock_init(&sx_board[i].lock);
2379 if (sx_init_drivers()) {
2380 func_exit();
2381 return -EIO;
2384 for (i = 0; i < SX_NBOARD; i++)
2385 if (sx_board[i].base && !sx_probe(&sx_board[i]))
2386 found++;
2388 #ifdef CONFIG_PCI
2390 struct pci_dev *pdev = NULL;
2392 i=0;
2393 while (i < SX_NBOARD) {
2394 if (sx_board[i].flags & SX_BOARD_PRESENT) {
2395 i++;
2396 continue;
2398 pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,
2399 PCI_DEVICE_ID_SPECIALIX_IO8,
2400 pdev);
2401 if (!pdev) break;
2403 if (pci_enable_device(pdev))
2404 continue;
2406 sx_board[i].irq = pdev->irq;
2408 sx_board[i].base = pci_resource_start (pdev, 2);
2410 sx_board[i].flags |= SX_BOARD_IS_PCI;
2411 if (!sx_probe(&sx_board[i]))
2412 found ++;
2414 /* May exit pci_get sequence early with lots of boards */
2415 if (pdev != NULL)
2416 pci_dev_put(pdev);
2418 #endif
2420 if (!found) {
2421 sx_release_drivers();
2422 printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
2423 func_exit();
2424 return -EIO;
2427 func_exit();
2428 return 0;
2431 static int iobase[SX_NBOARD] = {0,};
2433 static int irq [SX_NBOARD] = {0,};
2435 module_param_array(iobase, int, NULL, 0);
2436 module_param_array(irq, int, NULL, 0);
2437 module_param(sx_debug, int, 0);
2438 module_param(sx_rxfifo, int, 0);
2439 #ifdef SPECIALIX_TIMER
2440 module_param(sx_poll, int, 0);
2441 #endif
2444 * You can setup up to 4 boards.
2445 * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2446 * You should specify the IRQs too in that case "irq=....,...".
2448 * More than 4 boards in one computer is not possible, as the card can
2449 * only use 4 different interrupts.
2452 static int __init specialix_init_module(void)
2454 int i;
2456 func_enter();
2458 if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2459 for(i = 0; i < SX_NBOARD; i++) {
2460 sx_board[i].base = iobase[i];
2461 sx_board[i].irq = irq[i];
2462 sx_board[i].count= 0;
2466 func_exit();
2468 return specialix_init();
2471 static void __exit specialix_exit_module(void)
2473 int i;
2475 func_enter();
2477 sx_release_drivers();
2478 for (i = 0; i < SX_NBOARD; i++)
2479 if (sx_board[i].flags & SX_BOARD_PRESENT)
2480 sx_release_io_range(&sx_board[i]);
2481 #ifdef SPECIALIX_TIMER
2482 del_timer_sync(&missed_irq_timer);
2483 #endif
2485 func_exit();
2488 static struct pci_device_id specialx_pci_tbl[] __devinitdata = {
2489 { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) },
2492 MODULE_DEVICE_TABLE(pci, specialx_pci_tbl);
2494 module_init(specialix_init_module);
2495 module_exit(specialix_exit_module);
2497 MODULE_LICENSE("GPL");