Merge branch 'master'
[pandora-kernel.git] / drivers / char / specialix.c
1 /*
2  *      specialix.c  -- specialix IO8+ multiport serial driver.
3  *
4  *      Copyright (C) 1997  Roger Wolff (R.E.Wolff@BitWizard.nl)
5  *      Copyright (C) 1994-1996  Dmitry Gorodchanin (pgmdsg@ibi.com)
6  *
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.
11  *
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.
15  *
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.
21  *
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.
26  *
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.
31  *
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.
36  *
37  * Revision history:
38  *
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)
66  *
67  */
68
69 #define VERSION "1.11"
70
71
72 /*
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
76  */
77
78 #include <linux/config.h>
79 #include <linux/module.h>
80
81 #include <asm/io.h>
82 #include <linux/kernel.h>
83 #include <linux/sched.h>
84 #include <linux/ioport.h>
85 #include <linux/interrupt.h>
86 #include <linux/errno.h>
87 #include <linux/tty.h>
88 #include <linux/mm.h>
89 #include <linux/serial.h>
90 #include <linux/fcntl.h>
91 #include <linux/major.h>
92 #include <linux/delay.h>
93 #include <linux/pci.h>
94 #include <linux/init.h>
95 #include <asm/uaccess.h>
96
97 #include "specialix_io8.h"
98 #include "cd1865.h"
99
100
101 /*
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...
108 */
109 #define DEBUG
110
111 static int sx_debug;
112 static int sx_rxfifo = SPECIALIX_RXFIFO;
113
114 #ifdef DEBUG
115 #define dprintk(f, str...) if (sx_debug & f) printk (str)
116 #else
117 #define dprintk(f, str...) /* nothing */
118 #endif
119
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
132
133
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__)
136
137 #define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
138
139
140 /* Configurable options: */
141
142 /* Am I paranoid or not ? ;-) */
143 #define SPECIALIX_PARANOIA_CHECK
144
145 /* Do I trust the IRQ from the card? (enabeling it doesn't seem to help)
146    When the IRQ routine leaves the chip in a state that is keeps on
147    requiring attention, the timer doesn't help either. */
148 #undef SPECIALIX_TIMER
149
150 #ifdef SPECIALIX_TIMER
151 static int sx_poll = HZ;
152 #endif
153
154
155
156 /*
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.
159  */
160 #undef SX_REPORT_FIFO
161 #undef SX_REPORT_OVERRUN
162
163
164
165 #ifdef CONFIG_SPECIALIX_RTSCTS
166 #define SX_CRTSCTS(bla) 1
167 #else
168 #define SX_CRTSCTS(tty) C_CRTSCTS(tty)
169 #endif
170
171
172 /* Used to be outb (0xff, 0x80); */
173 #define short_pause() udelay (1)
174
175
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)
180
181 #undef RS_EVENT_WRITE_WAKEUP
182 #define RS_EVENT_WRITE_WAKEUP   0
183
184 static struct tty_driver *specialix_driver;
185 static unsigned char * tmp_buf;
186 static DECLARE_MUTEX(tmp_buf_sem);
187
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,
191 };
192
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, },
198 };
199
200 static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
201
202
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
207
208
209
210 static inline int sx_paranoia_check(struct specialix_port const * port,
211                                     char *name, const char *routine)
212 {
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";
218
219         if (!port) {
220                 printk(badinfo, name, routine);
221                 return 1;
222         }
223         if (port->magic != SPECIALIX_MAGIC) {
224                 printk(badmagic, name, routine);
225                 return 1;
226         }
227 #endif
228         return 0;
229 }
230
231
232 /*
233  *
234  *  Service functions for specialix IO8+ driver.
235  *
236  */
237
238 /* Get board number from pointer */
239 static inline int board_No (struct specialix_board * bp)
240 {
241         return bp - sx_board;
242 }
243
244
245 /* Get port number from pointer */
246 static inline int port_No (struct specialix_port const * port)
247 {
248         return SX_PORT(port - sx_port);
249 }
250
251
252 /* Get pointer to board from pointer to port */
253 static inline struct specialix_board * port_Board(struct specialix_port const * port)
254 {
255         return &sx_board[SX_BOARD(port - sx_port)];
256 }
257
258
259 /* Input Byte from CL CD186x register */
260 static inline unsigned char sx_in(struct specialix_board  * bp, unsigned short reg)
261 {
262         bp->reg = reg | 0x80;
263         outb (reg | 0x80, bp->base + SX_ADDR_REG);
264         return inb  (bp->base + SX_DATA_REG);
265 }
266
267
268 /* Output Byte to CL CD186x register */
269 static inline void sx_out(struct specialix_board  * bp, unsigned short reg,
270                           unsigned char val)
271 {
272         bp->reg = reg | 0x80;
273         outb (reg | 0x80, bp->base + SX_ADDR_REG);
274         outb (val, bp->base + SX_DATA_REG);
275 }
276
277
278 /* Input Byte from CL CD186x register */
279 static inline unsigned char sx_in_off(struct specialix_board  * bp, unsigned short reg)
280 {
281         bp->reg = reg;
282         outb (reg, bp->base + SX_ADDR_REG);
283         return inb  (bp->base + SX_DATA_REG);
284 }
285
286
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)
290 {
291         bp->reg = reg;
292         outb (reg, bp->base + SX_ADDR_REG);
293         outb (val, bp->base + SX_DATA_REG);
294 }
295
296
297 /* Wait for Channel Command Register ready */
298 static inline void sx_wait_CCR(struct specialix_board  * bp)
299 {
300         unsigned long delay, flags;
301         unsigned char ccr;
302
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);
310         }
311
312         printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
313 }
314
315
316 /* Wait for Channel Command Register ready */
317 static inline void sx_wait_CCR_off(struct specialix_board  * bp)
318 {
319         unsigned long delay;
320         unsigned char crr;
321         unsigned long flags;
322
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);
330         }
331
332         printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
333 }
334
335
336 /*
337  *  specialix IO8+ IO range functions.
338  */
339
340 static inline int sx_request_io_range(struct specialix_board * bp)
341 {
342         return request_region(bp->base,
343                 bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
344                 "specialix IO8+") == NULL;
345 }
346
347
348 static inline void sx_release_io_range(struct specialix_board * bp)
349 {
350         release_region(bp->base,
351                        bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
352 }
353
354
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)
359 {
360         unsigned long i;
361
362         for (i = jiffies + delay; time_after(i, jiffies); ) ;
363 }
364
365
366
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)
369 {
370         int virq;
371         int i;
372         unsigned long flags;
373
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;
384         }
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);
389         }
390         spin_unlock_irqrestore(&bp->lock, flags);
391         return 1;
392 }
393
394
395 /* Reset and setup CD186x chip */
396 static int sx_init_CD186x(struct specialix_board  * bp)
397 {
398         unsigned long flags;
399         int scaler;
400         int rv = 1;
401
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);
416
417         /* Setting up prescaler. We need 4 ticks per 1 ms */
418         scaler =  SX_OSCFREQ/SPECIALIX_TPS;
419
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);
423
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;
428         }
429
430         func_exit();
431         return rv;
432 }
433
434
435 static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
436 {
437         int i;
438         int t;
439         unsigned long flags;
440
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;
446         }
447         spin_unlock_irqrestore(&bp->lock, flags);
448
449         return t;
450 }
451
452
453 #ifdef SPECIALIX_TIMER
454 void missed_irq (unsigned long data)
455 {
456         unsigned char irq;
457         unsigned long flags;
458         struct specialix_board  *bp = (struct specialix_board *)data;
459
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);
470         }
471         missed_irq_timer.expires = jiffies + sx_poll;
472         add_timer (&missed_irq_timer);
473 }
474 #endif
475
476
477
478 /* Main probing routine, also sets irq. */
479 static int sx_probe(struct specialix_board *bp)
480 {
481         unsigned char val1, val2;
482 #if 0
483         int irqs = 0;
484         int retries;
485 #endif
486         int rev;
487         int chip;
488
489         func_enter();
490
491         if (sx_request_io_range(bp)) {
492                 func_exit();
493                 return 1;
494         }
495
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);
500
501         sx_out_off(bp, CD186x_PPRL, 0xa5);
502         short_pause ();
503         val2 = sx_in_off(bp, CD186x_PPRL);
504
505
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;
512         }
513
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);
520
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;
532         }
533
534
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);
546
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");
552
553                 /* Reset CD186x again      */
554                 if (!sx_init_CD186x(bp)) {
555                         /* Hmmm. This is dead code anyway. */
556                 }
557
558                 dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
559                         val1, val2, val3);
560
561         }
562
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;
570         }
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;
581         }
582
583         sx_request_io_range(bp);
584         bp->flags |= SX_BOARD_PRESENT;
585
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.
594          */
595
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';
602         }
603
604         dprintk (SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR) );
605
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
613
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);
618
619         func_exit();
620         return 0;
621 }
622
623 /*
624  *
625  *  Interrupt processing routines.
626  * */
627
628 static inline void sx_mark_event(struct specialix_port * port, int event)
629 {
630         func_enter();
631
632         set_bit(event, &port->event);
633         schedule_work(&port->tqueue);
634
635         func_exit();
636 }
637
638
639 static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
640                                                unsigned char const * what)
641 {
642         unsigned char channel;
643         struct specialix_port * port = NULL;
644
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);
650
651                 if (port->flags & ASYNC_INITIALIZED) {
652                         dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
653                         func_exit();
654                         return port;
655                 }
656         }
657         printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
658                board_No(bp), what, channel);
659         return NULL;
660 }
661
662
663 static inline void sx_receive_exc(struct specialix_board * bp)
664 {
665         struct specialix_port *port;
666         struct tty_struct *tty;
667         unsigned char status;
668         unsigned char ch;
669
670         func_enter();
671
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;
677         }
678         tty = port->tty;
679         dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n",
680                  port,  tty->flip.count, TTY_FLIPBUF_SIZE);
681
682         status = sx_in(bp, CD186x_RCSR);
683
684         dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
685         if (status & RCSR_OE) {
686                 port->overrun++;
687                 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Overrun. Total %ld overruns.\n",
688                        board_No(bp), port_No(port), port->overrun);
689         }
690         status &= port->mark_mask;
691
692         /* This flip buffer check needs to be below the reading of the
693            status register to reset the chip's IRQ.... */
694         if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
695                 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n",
696                        board_No(bp), port_No(port));
697                 func_exit();
698                 return;
699         }
700
701         ch = sx_in(bp, CD186x_RDR);
702         if (!status) {
703                 func_exit();
704                 return;
705         }
706         if (status & RCSR_TOUT) {
707                 printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
708                        board_No(bp), port_No(port));
709                 func_exit();
710                 return;
711
712         } else if (status & RCSR_BREAK) {
713                 dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
714                        board_No(bp), port_No(port));
715                 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
716                 if (port->flags & ASYNC_SAK)
717                         do_SAK(tty);
718
719         } else if (status & RCSR_PE)
720                 *tty->flip.flag_buf_ptr++ = TTY_PARITY;
721
722         else if (status & RCSR_FE)
723                 *tty->flip.flag_buf_ptr++ = TTY_FRAME;
724
725         else if (status & RCSR_OE)
726                 *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
727
728         else
729                 *tty->flip.flag_buf_ptr++ = 0;
730
731         *tty->flip.char_buf_ptr++ = ch;
732         tty->flip.count++;
733         schedule_delayed_work(&tty->flip.work, 1);
734
735         func_exit();
736 }
737
738
739 static inline void sx_receive(struct specialix_board * bp)
740 {
741         struct specialix_port *port;
742         struct tty_struct *tty;
743         unsigned char count;
744
745         func_enter();
746
747         if (!(port = sx_get_port(bp, "Receive"))) {
748                 dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
749                 func_exit();
750                 return;
751         }
752         tty = port->tty;
753
754         count = sx_in(bp, CD186x_RDCR);
755         dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
756         port->hits[count > 8 ? 9 : count]++;
757
758         while (count--) {
759                 if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
760                         printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n",
761                                board_No(bp), port_No(port));
762                         break;
763                 }
764                 *tty->flip.char_buf_ptr++ = sx_in(bp, CD186x_RDR);
765                 *tty->flip.flag_buf_ptr++ = 0;
766                 tty->flip.count++;
767         }
768         schedule_delayed_work(&tty->flip.work, 1);
769
770         func_exit();
771 }
772
773
774 static inline void sx_transmit(struct specialix_board * bp)
775 {
776         struct specialix_port *port;
777         struct tty_struct *tty;
778         unsigned char count;
779
780         func_enter();
781         if (!(port = sx_get_port(bp, "Transmit"))) {
782                 func_exit();
783                 return;
784         }
785         dprintk (SX_DEBUG_TX, "port: %p\n", port);
786         tty = port->tty;
787
788         if (port->IER & IER_TXEMPTY) {
789                 /* FIFO drained */
790                 sx_out(bp, CD186x_CAR, port_No(port));
791                 port->IER &= ~IER_TXEMPTY;
792                 sx_out(bp, CD186x_IER, port->IER);
793                 func_exit();
794                 return;
795         }
796
797         if ((port->xmit_cnt <= 0 && !port->break_length)
798             || tty->stopped || tty->hw_stopped) {
799                 sx_out(bp, CD186x_CAR, port_No(port));
800                 port->IER &= ~IER_TXRDY;
801                 sx_out(bp, CD186x_IER, port->IER);
802                 func_exit();
803                 return;
804         }
805
806         if (port->break_length) {
807                 if (port->break_length > 0) {
808                         if (port->COR2 & COR2_ETC) {
809                                 sx_out(bp, CD186x_TDR, CD186x_C_ESC);
810                                 sx_out(bp, CD186x_TDR, CD186x_C_SBRK);
811                                 port->COR2 &= ~COR2_ETC;
812                         }
813                         count = min_t(int, port->break_length, 0xff);
814                         sx_out(bp, CD186x_TDR, CD186x_C_ESC);
815                         sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
816                         sx_out(bp, CD186x_TDR, count);
817                         if (!(port->break_length -= count))
818                                 port->break_length--;
819                 } else {
820                         sx_out(bp, CD186x_TDR, CD186x_C_ESC);
821                         sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
822                         sx_out(bp, CD186x_COR2, port->COR2);
823                         sx_wait_CCR(bp);
824                         sx_out(bp, CD186x_CCR, CCR_CORCHG2);
825                         port->break_length = 0;
826                 }
827
828                 func_exit();
829                 return;
830         }
831
832         count = CD186x_NFIFO;
833         do {
834                 sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
835                 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
836                 if (--port->xmit_cnt <= 0)
837                         break;
838         } while (--count > 0);
839
840         if (port->xmit_cnt <= 0) {
841                 sx_out(bp, CD186x_CAR, port_No(port));
842                 port->IER &= ~IER_TXRDY;
843                 sx_out(bp, CD186x_IER, port->IER);
844         }
845         if (port->xmit_cnt <= port->wakeup_chars)
846                 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
847
848         func_exit();
849 }
850
851
852 static inline void sx_check_modem(struct specialix_board * bp)
853 {
854         struct specialix_port *port;
855         struct tty_struct *tty;
856         unsigned char mcr;
857         int msvr_cd;
858
859         dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
860         if (!(port = sx_get_port(bp, "Modem")))
861                 return;
862
863         tty = port->tty;
864
865         mcr = sx_in(bp, CD186x_MCR);
866         printk ("mcr = %02x.\n", mcr);
867
868         if ((mcr & MCR_CDCHG)) {
869                 dprintk (SX_DEBUG_SIGNALS, "CD just changed... ");
870                 msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
871                 if (msvr_cd) {
872                         dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
873                         wake_up_interruptible(&port->open_wait);
874                 } else {
875                         dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n");
876                         schedule_work(&port->tqueue_hangup);
877                 }
878         }
879
880 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
881         if (mcr & MCR_CTSCHG) {
882                 if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
883                         tty->hw_stopped = 0;
884                         port->IER |= IER_TXRDY;
885                         if (port->xmit_cnt <= port->wakeup_chars)
886                                 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
887                 } else {
888                         tty->hw_stopped = 1;
889                         port->IER &= ~IER_TXRDY;
890                 }
891                 sx_out(bp, CD186x_IER, port->IER);
892         }
893         if (mcr & MCR_DSSXHG) {
894                 if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
895                         tty->hw_stopped = 0;
896                         port->IER |= IER_TXRDY;
897                         if (port->xmit_cnt <= port->wakeup_chars)
898                                 sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
899                 } else {
900                         tty->hw_stopped = 1;
901                         port->IER &= ~IER_TXRDY;
902                 }
903                 sx_out(bp, CD186x_IER, port->IER);
904         }
905 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
906
907         /* Clear change bits */
908         sx_out(bp, CD186x_MCR, 0);
909 }
910
911
912 /* The main interrupt processing routine */
913 static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
914 {
915         unsigned char status;
916         unsigned char ack;
917         struct specialix_board *bp;
918         unsigned long loop = 0;
919         int saved_reg;
920         unsigned long flags;
921
922         func_enter();
923
924         bp = dev_id;
925         spin_lock_irqsave(&bp->lock, flags);
926
927         dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __FUNCTION__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
928         if (!bp || !(bp->flags & SX_BOARD_ACTIVE)) {
929                 dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq);
930                 spin_unlock_irqrestore(&bp->lock, flags);
931                 func_exit();
932                 return IRQ_NONE;
933         }
934
935         saved_reg = bp->reg;
936
937         while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
938                                            (SRSR_RREQint |
939                                             SRSR_TREQint |
940                                             SRSR_MREQint)))) {
941                 if (status & SRSR_RREQint) {
942                         ack = sx_in(bp, CD186x_RRAR);
943
944                         if (ack == (SX_ID | GIVR_IT_RCV))
945                                 sx_receive(bp);
946                         else if (ack == (SX_ID | GIVR_IT_REXC))
947                                 sx_receive_exc(bp);
948                         else
949                                 printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
950                                        board_No(bp), status, ack);
951
952                 } else if (status & SRSR_TREQint) {
953                         ack = sx_in(bp, CD186x_TRAR);
954
955                         if (ack == (SX_ID | GIVR_IT_TX))
956                                 sx_transmit(bp);
957                         else
958                                 printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
959                                        board_No(bp), status, ack, port_No (sx_get_port (bp, "Int")));
960                 } else if (status & SRSR_MREQint) {
961                         ack = sx_in(bp, CD186x_MRAR);
962
963                         if (ack == (SX_ID | GIVR_IT_MODEM))
964                                 sx_check_modem(bp);
965                         else
966                                 printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
967                                        board_No(bp), status, ack);
968
969                 }
970
971                 sx_out(bp, CD186x_EOIR, 0);   /* Mark end of interrupt */
972         }
973         bp->reg = saved_reg;
974         outb (bp->reg, bp->base + SX_ADDR_REG);
975         spin_unlock_irqrestore(&bp->lock, flags);
976         func_exit();
977         return IRQ_HANDLED;
978 }
979
980
981 /*
982  *  Routines for open & close processing.
983  */
984
985 static void turn_ints_off (struct specialix_board *bp)
986 {
987         unsigned long flags;
988
989         func_enter();
990         if (bp->flags & SX_BOARD_IS_PCI) {
991                 /* This was intended for enabeling the interrupt on the
992                  * PCI card. However it seems that it's already enabled
993                  * and as PCI interrupts can be shared, there is no real
994                  * reason to have to turn it off. */
995         }
996
997         spin_lock_irqsave(&bp->lock, flags);
998         (void) sx_in_off (bp, 0); /* Turn off interrupts. */
999         spin_unlock_irqrestore(&bp->lock, flags);
1000
1001         func_exit();
1002 }
1003
1004 static void turn_ints_on (struct specialix_board *bp)
1005 {
1006         unsigned long flags;
1007
1008         func_enter();
1009
1010         if (bp->flags & SX_BOARD_IS_PCI) {
1011                 /* play with the PCI chip. See comment above. */
1012         }
1013         spin_lock_irqsave(&bp->lock, flags);
1014         (void) sx_in (bp, 0); /* Turn ON interrupts. */
1015         spin_unlock_irqrestore(&bp->lock, flags);
1016
1017         func_exit();
1018 }
1019
1020
1021 /* Called with disabled interrupts */
1022 static inline int sx_setup_board(struct specialix_board * bp)
1023 {
1024         int error;
1025
1026         if (bp->flags & SX_BOARD_ACTIVE)
1027                 return 0;
1028
1029         if (bp->flags & SX_BOARD_IS_PCI)
1030                 error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT | SA_SHIRQ, "specialix IO8+", bp);
1031         else
1032                 error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT, "specialix IO8+", bp);
1033
1034         if (error)
1035                 return error;
1036
1037         turn_ints_on (bp);
1038         bp->flags |= SX_BOARD_ACTIVE;
1039
1040         return 0;
1041 }
1042
1043
1044 /* Called with disabled interrupts */
1045 static inline void sx_shutdown_board(struct specialix_board *bp)
1046 {
1047         func_enter();
1048
1049         if (!(bp->flags & SX_BOARD_ACTIVE)) {
1050                 func_exit();
1051                 return;
1052         }
1053
1054         bp->flags &= ~SX_BOARD_ACTIVE;
1055
1056         dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
1057                  bp->irq, board_No (bp));
1058         free_irq(bp->irq, bp);
1059
1060         turn_ints_off (bp);
1061
1062
1063         func_exit();
1064 }
1065
1066
1067 /*
1068  * Setting up port characteristics.
1069  * Must be called with disabled interrupts
1070  */
1071 static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
1072 {
1073         struct tty_struct *tty;
1074         unsigned long baud;
1075         long tmp;
1076         unsigned char cor1 = 0, cor3 = 0;
1077         unsigned char mcor1 = 0, mcor2 = 0;
1078         static unsigned long again;
1079         unsigned long flags;
1080
1081         func_enter();
1082
1083         if (!(tty = port->tty) || !tty->termios) {
1084                 func_exit();
1085                 return;
1086         }
1087
1088         port->IER  = 0;
1089         port->COR2 = 0;
1090         /* Select port on the board */
1091         spin_lock_irqsave(&bp->lock, flags);
1092         sx_out(bp, CD186x_CAR, port_No(port));
1093
1094         /* The Specialix board doens't implement the RTS lines.
1095            They are used to set the IRQ level. Don't touch them. */
1096         if (SX_CRTSCTS(tty))
1097                 port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1098         else
1099                 port->MSVR =  (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
1100         spin_unlock_irqrestore(&bp->lock, flags);
1101         dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
1102         baud = C_BAUD(tty);
1103
1104         if (baud & CBAUDEX) {
1105                 baud &= ~CBAUDEX;
1106                 if (baud < 1 || baud > 2)
1107                         port->tty->termios->c_cflag &= ~CBAUDEX;
1108                 else
1109                         baud += 15;
1110         }
1111         if (baud == 15) {
1112                 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1113                         baud ++;
1114                 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1115                         baud += 2;
1116         }
1117
1118
1119         if (!baud_table[baud]) {
1120                 /* Drop DTR & exit */
1121                 dprintk (SX_DEBUG_TERMIOS, "Dropping DTR...  Hmm....\n");
1122                 if (!SX_CRTSCTS (tty)) {
1123                         port -> MSVR &= ~ MSVR_DTR;
1124                         spin_lock_irqsave(&bp->lock, flags);
1125                         sx_out(bp, CD186x_MSVR, port->MSVR );
1126                         spin_unlock_irqrestore(&bp->lock, flags);
1127                 }
1128                 else
1129                         dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1130                 return;
1131         } else {
1132                 /* Set DTR on */
1133                 if (!SX_CRTSCTS (tty)) {
1134                         port ->MSVR |= MSVR_DTR;
1135                 }
1136         }
1137
1138         /*
1139          * Now we must calculate some speed depended things
1140          */
1141
1142         /* Set baud rate for port */
1143         tmp = port->custom_divisor ;
1144         if ( tmp )
1145                 printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n"
1146                                   "This is an untested option, please be carefull.\n",
1147                                   port_No (port), tmp);
1148         else
1149                 tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
1150                          CD186x_TPC/2) / CD186x_TPC);
1151
1152         if ((tmp < 0x10) && time_before(again, jiffies)) {
1153                 again = jiffies + HZ * 60;
1154                 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1155                 if (tmp >= 12) {
1156                         printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1157                                 "Performance degradation is possible.\n"
1158                                 "Read specialix.txt for more info.\n",
1159                                 port_No (port), tmp);
1160                 } else {
1161                         printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1162                                 "Warning: overstressing Cirrus chip. "
1163                                 "This might not work.\n"
1164                                 "Read specialix.txt for more info.\n",
1165                                 port_No (port), tmp);
1166                 }
1167         }
1168         spin_lock_irqsave(&bp->lock, flags);
1169         sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1170         sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1171         sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1172         sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1173         spin_unlock_irqrestore(&bp->lock, flags);
1174         if (port->custom_divisor) {
1175                 baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
1176                 baud = ( baud + 5 ) / 10;
1177         } else
1178                 baud = (baud_table[baud] + 5) / 10;   /* Estimated CPS */
1179
1180         /* Two timer ticks seems enough to wakeup something like SLIP driver */
1181         tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1182         port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1183                                               SERIAL_XMIT_SIZE - 1 : tmp);
1184
1185         /* Receiver timeout will be transmission time for 1.5 chars */
1186         tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1187         tmp = (tmp > 0xff) ? 0xff : tmp;
1188         spin_lock_irqsave(&bp->lock, flags);
1189         sx_out(bp, CD186x_RTPR, tmp);
1190         spin_unlock_irqrestore(&bp->lock, flags);
1191         switch (C_CSIZE(tty)) {
1192          case CS5:
1193                 cor1 |= COR1_5BITS;
1194                 break;
1195          case CS6:
1196                 cor1 |= COR1_6BITS;
1197                 break;
1198          case CS7:
1199                 cor1 |= COR1_7BITS;
1200                 break;
1201          case CS8:
1202                 cor1 |= COR1_8BITS;
1203                 break;
1204         }
1205
1206         if (C_CSTOPB(tty))
1207                 cor1 |= COR1_2SB;
1208
1209         cor1 |= COR1_IGNORE;
1210         if (C_PARENB(tty)) {
1211                 cor1 |= COR1_NORMPAR;
1212                 if (C_PARODD(tty))
1213                         cor1 |= COR1_ODDP;
1214                 if (I_INPCK(tty))
1215                         cor1 &= ~COR1_IGNORE;
1216         }
1217         /* Set marking of some errors */
1218         port->mark_mask = RCSR_OE | RCSR_TOUT;
1219         if (I_INPCK(tty))
1220                 port->mark_mask |= RCSR_FE | RCSR_PE;
1221         if (I_BRKINT(tty) || I_PARMRK(tty))
1222                 port->mark_mask |= RCSR_BREAK;
1223         if (I_IGNPAR(tty))
1224                 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1225         if (I_IGNBRK(tty)) {
1226                 port->mark_mask &= ~RCSR_BREAK;
1227                 if (I_IGNPAR(tty))
1228                         /* Real raw mode. Ignore all */
1229                         port->mark_mask &= ~RCSR_OE;
1230         }
1231         /* Enable Hardware Flow Control */
1232         if (C_CRTSCTS(tty)) {
1233 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1234                 port->IER |= IER_DSR | IER_CTS;
1235                 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1236                 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1237                 spin_lock_irqsave(&bp->lock, flags);
1238                 tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
1239                 spin_unlock_irqrestore(&bp->lock, flags);
1240 #else
1241                 port->COR2 |= COR2_CTSAE;
1242 #endif
1243         }
1244         /* Enable Software Flow Control. FIXME: I'm not sure about this */
1245         /* Some people reported that it works, but I still doubt it */
1246         if (I_IXON(tty)) {
1247                 port->COR2 |= COR2_TXIBE;
1248                 cor3 |= (COR3_FCT | COR3_SCDE);
1249                 if (I_IXANY(tty))
1250                         port->COR2 |= COR2_IXM;
1251                 spin_lock_irqsave(&bp->lock, flags);
1252                 sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1253                 sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1254                 sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1255                 sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1256                 spin_unlock_irqrestore(&bp->lock, flags);
1257         }
1258         if (!C_CLOCAL(tty)) {
1259                 /* Enable CD check */
1260                 port->IER |= IER_CD;
1261                 mcor1 |= MCOR1_CDZD;
1262                 mcor2 |= MCOR2_CDOD;
1263         }
1264
1265         if (C_CREAD(tty))
1266                 /* Enable receiver */
1267                 port->IER |= IER_RXD;
1268
1269         /* Set input FIFO size (1-8 bytes) */
1270         cor3 |= sx_rxfifo;
1271         /* Setting up CD186x channel registers */
1272         spin_lock_irqsave(&bp->lock, flags);
1273         sx_out(bp, CD186x_COR1, cor1);
1274         sx_out(bp, CD186x_COR2, port->COR2);
1275         sx_out(bp, CD186x_COR3, cor3);
1276         spin_unlock_irqrestore(&bp->lock, flags);
1277         /* Make CD186x know about registers change */
1278         sx_wait_CCR(bp);
1279         spin_lock_irqsave(&bp->lock, flags);
1280         sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1281         /* Setting up modem option registers */
1282         dprintk (SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2);
1283         sx_out(bp, CD186x_MCOR1, mcor1);
1284         sx_out(bp, CD186x_MCOR2, mcor2);
1285         spin_unlock_irqrestore(&bp->lock, flags);
1286         /* Enable CD186x transmitter & receiver */
1287         sx_wait_CCR(bp);
1288         spin_lock_irqsave(&bp->lock, flags);
1289         sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1290         /* Enable interrupts */
1291         sx_out(bp, CD186x_IER, port->IER);
1292         /* And finally set the modem lines... */
1293         sx_out(bp, CD186x_MSVR, port->MSVR);
1294         spin_unlock_irqrestore(&bp->lock, flags);
1295
1296         func_exit();
1297 }
1298
1299
1300 /* Must be called with interrupts enabled */
1301 static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port)
1302 {
1303         unsigned long flags;
1304
1305         func_enter();
1306
1307         if (port->flags & ASYNC_INITIALIZED) {
1308                 func_exit();
1309                 return 0;
1310         }
1311
1312         if (!port->xmit_buf) {
1313                 /* We may sleep in get_zeroed_page() */
1314                 unsigned long tmp;
1315
1316                 if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
1317                         func_exit();
1318                         return -ENOMEM;
1319                 }
1320
1321                 if (port->xmit_buf) {
1322                         free_page(tmp);
1323                         func_exit();
1324                         return -ERESTARTSYS;
1325                 }
1326                 port->xmit_buf = (unsigned char *) tmp;
1327         }
1328
1329         spin_lock_irqsave(&port->lock, flags);
1330
1331         if (port->tty)
1332                 clear_bit(TTY_IO_ERROR, &port->tty->flags);
1333
1334         port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1335         sx_change_speed(bp, port);
1336         port->flags |= ASYNC_INITIALIZED;
1337
1338         spin_unlock_irqrestore(&port->lock, flags);
1339
1340
1341         func_exit();
1342         return 0;
1343 }
1344
1345
1346 /* Must be called with interrupts disabled */
1347 static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port)
1348 {
1349         struct tty_struct *tty;
1350         int i;
1351         unsigned long flags;
1352
1353         func_enter();
1354
1355         if (!(port->flags & ASYNC_INITIALIZED)) {
1356                 func_exit();
1357                 return;
1358         }
1359
1360         if (sx_debug & SX_DEBUG_FIFO) {
1361                 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
1362                         board_No(bp), port_No(port), port->overrun);
1363                 for (i = 0; i < 10; i++) {
1364                         dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1365                 }
1366                 dprintk(SX_DEBUG_FIFO, "].\n");
1367         }
1368
1369         if (port->xmit_buf) {
1370                 free_page((unsigned long) port->xmit_buf);
1371                 port->xmit_buf = NULL;
1372         }
1373
1374         /* Select port */
1375         spin_lock_irqsave(&bp->lock, flags);
1376         sx_out(bp, CD186x_CAR, port_No(port));
1377
1378         if (!(tty = port->tty) || C_HUPCL(tty)) {
1379                 /* Drop DTR */
1380                 sx_out(bp, CD186x_MSVDTR, 0);
1381         }
1382         spin_unlock_irqrestore(&bp->lock, flags);
1383         /* Reset port */
1384         sx_wait_CCR(bp);
1385         spin_lock_irqsave(&bp->lock, flags);
1386         sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1387         /* Disable all interrupts from this port */
1388         port->IER = 0;
1389         sx_out(bp, CD186x_IER, port->IER);
1390         spin_unlock_irqrestore(&bp->lock, flags);
1391         if (tty)
1392                 set_bit(TTY_IO_ERROR, &tty->flags);
1393         port->flags &= ~ASYNC_INITIALIZED;
1394
1395         if (!bp->count)
1396                 sx_shutdown_board(bp);
1397         func_exit();
1398 }
1399
1400
1401 static int block_til_ready(struct tty_struct *tty, struct file * filp,
1402                            struct specialix_port *port)
1403 {
1404         DECLARE_WAITQUEUE(wait,  current);
1405         struct specialix_board *bp = port_Board(port);
1406         int    retval;
1407         int    do_clocal = 0;
1408         int    CD;
1409         unsigned long flags;
1410
1411         func_enter();
1412
1413         /*
1414          * If the device is in the middle of being closed, then block
1415          * until it's done, and then try again.
1416          */
1417         if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
1418                 interruptible_sleep_on(&port->close_wait);
1419                 if (port->flags & ASYNC_HUP_NOTIFY) {
1420                         func_exit();
1421                         return -EAGAIN;
1422                 } else {
1423                         func_exit();
1424                         return -ERESTARTSYS;
1425                 }
1426         }
1427
1428         /*
1429          * If non-blocking mode is set, or the port is not enabled,
1430          * then make the check up front and then exit.
1431          */
1432         if ((filp->f_flags & O_NONBLOCK) ||
1433             (tty->flags & (1 << TTY_IO_ERROR))) {
1434                 port->flags |= ASYNC_NORMAL_ACTIVE;
1435                 func_exit();
1436                 return 0;
1437         }
1438
1439         if (C_CLOCAL(tty))
1440                 do_clocal = 1;
1441
1442         /*
1443          * Block waiting for the carrier detect and the line to become
1444          * free (i.e., not in use by the callout).  While we are in
1445          * this loop, info->count is dropped by one, so that
1446          * rs_close() knows when to free things.  We restore it upon
1447          * exit, either normal or abnormal.
1448          */
1449         retval = 0;
1450         add_wait_queue(&port->open_wait, &wait);
1451         spin_lock_irqsave(&port->lock, flags);
1452         if (!tty_hung_up_p(filp)) {
1453                 port->count--;
1454         }
1455         spin_unlock_irqrestore(&port->lock, flags);
1456         port->blocked_open++;
1457         while (1) {
1458                 spin_lock_irqsave(&bp->lock, flags);
1459                 sx_out(bp, CD186x_CAR, port_No(port));
1460                 CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1461                 if (SX_CRTSCTS (tty)) {
1462                         /* Activate RTS */
1463                         port->MSVR |= MSVR_DTR;         /* WTF? */
1464                         sx_out (bp, CD186x_MSVR, port->MSVR);
1465                 } else {
1466                         /* Activate DTR */
1467                         port->MSVR |= MSVR_DTR;
1468                         sx_out (bp, CD186x_MSVR, port->MSVR);
1469                 }
1470                 spin_unlock_irqrestore(&bp->lock, flags);
1471                 set_current_state(TASK_INTERRUPTIBLE);
1472                 if (tty_hung_up_p(filp) ||
1473                     !(port->flags & ASYNC_INITIALIZED)) {
1474                         if (port->flags & ASYNC_HUP_NOTIFY)
1475                                 retval = -EAGAIN;
1476                         else
1477                                 retval = -ERESTARTSYS;
1478                         break;
1479                 }
1480                 if (!(port->flags & ASYNC_CLOSING) &&
1481                     (do_clocal || CD))
1482                         break;
1483                 if (signal_pending(current)) {
1484                         retval = -ERESTARTSYS;
1485                         break;
1486                 }
1487                 schedule();
1488         }
1489
1490         set_current_state(TASK_RUNNING);
1491         remove_wait_queue(&port->open_wait, &wait);
1492         spin_lock_irqsave(&port->lock, flags);
1493         if (!tty_hung_up_p(filp)) {
1494                 port->count++;
1495         }
1496         port->blocked_open--;
1497         spin_unlock_irqrestore(&port->lock, flags);
1498         if (retval) {
1499                 func_exit();
1500                 return retval;
1501         }
1502
1503         port->flags |= ASYNC_NORMAL_ACTIVE;
1504         func_exit();
1505         return 0;
1506 }
1507
1508
1509 static int sx_open(struct tty_struct * tty, struct file * filp)
1510 {
1511         int board;
1512         int error;
1513         struct specialix_port * port;
1514         struct specialix_board * bp;
1515         int i;
1516         unsigned long flags;
1517
1518         func_enter();
1519
1520         board = SX_BOARD(tty->index);
1521
1522         if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1523                 func_exit();
1524                 return -ENODEV;
1525         }
1526
1527         bp = &sx_board[board];
1528         port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1529         port->overrun = 0;
1530         for (i = 0; i < 10; i++)
1531                 port->hits[i]=0;
1532
1533         dprintk (SX_DEBUG_OPEN, "Board = %d, bp = %p, port = %p, portno = %d.\n",
1534                 board, bp, port, SX_PORT(tty->index));
1535
1536         if (sx_paranoia_check(port, tty->name, "sx_open")) {
1537                 func_enter();
1538                 return -ENODEV;
1539         }
1540
1541         if ((error = sx_setup_board(bp))) {
1542                 func_exit();
1543                 return error;
1544         }
1545
1546         spin_lock_irqsave(&bp->lock, flags);
1547         port->count++;
1548         bp->count++;
1549         tty->driver_data = port;
1550         port->tty = tty;
1551         spin_unlock_irqrestore(&bp->lock, flags);
1552
1553         if ((error = sx_setup_port(bp, port))) {
1554                 func_enter();
1555                 return error;
1556         }
1557
1558         if ((error = block_til_ready(tty, filp, port))) {
1559                 func_enter();
1560                 return error;
1561         }
1562
1563         func_exit();
1564         return 0;
1565 }
1566
1567
1568 static void sx_close(struct tty_struct * tty, struct file * filp)
1569 {
1570         struct specialix_port *port = (struct specialix_port *) tty->driver_data;
1571         struct specialix_board *bp;
1572         unsigned long flags;
1573         unsigned long timeout;
1574
1575         func_enter();
1576         if (!port || sx_paranoia_check(port, tty->name, "close")) {
1577                 func_exit();
1578                 return;
1579         }
1580         spin_lock_irqsave(&port->lock, flags);
1581
1582         if (tty_hung_up_p(filp)) {
1583                 spin_unlock_irqrestore(&port->lock, flags);
1584                 func_exit();
1585                 return;
1586         }
1587
1588         bp = port_Board(port);
1589         if ((tty->count == 1) && (port->count != 1)) {
1590                 printk(KERN_ERR "sx%d: sx_close: bad port count;"
1591                        " tty->count is 1, port count is %d\n",
1592                        board_No(bp), port->count);
1593                 port->count = 1;
1594         }
1595
1596         if (port->count > 1) {
1597                 port->count--;
1598                 bp->count--;
1599
1600                 spin_unlock_irqrestore(&port->lock, flags);
1601
1602                 func_exit();
1603                 return;
1604         }
1605         port->flags |= ASYNC_CLOSING;
1606         /*
1607          * Now we wait for the transmit buffer to clear; and we notify
1608          * the line discipline to only process XON/XOFF characters.
1609          */
1610         tty->closing = 1;
1611         spin_unlock_irqrestore(&port->lock, flags);
1612         dprintk (SX_DEBUG_OPEN, "Closing\n");
1613         if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
1614                 tty_wait_until_sent(tty, port->closing_wait);
1615         }
1616         /*
1617          * At this point we stop accepting input.  To do this, we
1618          * disable the receive line status interrupts, and tell the
1619          * interrupt driver to stop checking the data ready bit in the
1620          * line status register.
1621          */
1622         dprintk (SX_DEBUG_OPEN, "Closed\n");
1623         port->IER &= ~IER_RXD;
1624         if (port->flags & ASYNC_INITIALIZED) {
1625                 port->IER &= ~IER_TXRDY;
1626                 port->IER |= IER_TXEMPTY;
1627                 spin_lock_irqsave(&bp->lock, flags);
1628                 sx_out(bp, CD186x_CAR, port_No(port));
1629                 sx_out(bp, CD186x_IER, port->IER);
1630                 spin_unlock_irqrestore(&bp->lock, flags);
1631                 /*
1632                  * Before we drop DTR, make sure the UART transmitter
1633                  * has completely drained; this is especially
1634                  * important if there is a transmit FIFO!
1635                  */
1636                 timeout = jiffies+HZ;
1637                 while(port->IER & IER_TXEMPTY) {
1638                         set_current_state (TASK_INTERRUPTIBLE);
1639                         msleep_interruptible(jiffies_to_msecs(port->timeout));
1640                         if (time_after(jiffies, timeout)) {
1641                                 printk (KERN_INFO "Timeout waiting for close\n");
1642                                 break;
1643                         }
1644                 }
1645
1646         }
1647
1648         if (--bp->count < 0) {
1649                 printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1650                        board_No(bp), bp->count, tty->index);
1651                 bp->count = 0;
1652         }
1653         if (--port->count < 0) {
1654                 printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n",
1655                        board_No(bp), port_No(port), port->count);
1656                 port->count = 0;
1657         }
1658
1659         sx_shutdown_port(bp, port);
1660         if (tty->driver->flush_buffer)
1661                 tty->driver->flush_buffer(tty);
1662         tty_ldisc_flush(tty);
1663         spin_lock_irqsave(&port->lock, flags);
1664         tty->closing = 0;
1665         port->event = 0;
1666         port->tty = NULL;
1667         spin_unlock_irqrestore(&port->lock, flags);
1668         if (port->blocked_open) {
1669                 if (port->close_delay) {
1670                         msleep_interruptible(jiffies_to_msecs(port->close_delay));
1671                 }
1672                 wake_up_interruptible(&port->open_wait);
1673         }
1674         port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1675         wake_up_interruptible(&port->close_wait);
1676
1677         func_exit();
1678 }
1679
1680
1681 static int sx_write(struct tty_struct * tty,
1682                     const unsigned char *buf, int count)
1683 {
1684         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1685         struct specialix_board *bp;
1686         int c, total = 0;
1687         unsigned long flags;
1688
1689         func_enter();
1690         if (sx_paranoia_check(port, tty->name, "sx_write")) {
1691                 func_exit();
1692                 return 0;
1693         }
1694
1695         bp = port_Board(port);
1696
1697         if (!tty || !port->xmit_buf || !tmp_buf) {
1698                 func_exit();
1699                 return 0;
1700         }
1701
1702         while (1) {
1703                 spin_lock_irqsave(&port->lock, flags);
1704                 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1705                                    SERIAL_XMIT_SIZE - port->xmit_head));
1706                 if (c <= 0) {
1707                         spin_unlock_irqrestore(&port->lock, flags);
1708                         break;
1709                 }
1710                 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1711                 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1712                 port->xmit_cnt += c;
1713                 spin_unlock_irqrestore(&port->lock, flags);
1714
1715                 buf += c;
1716                 count -= c;
1717                 total += c;
1718         }
1719
1720         spin_lock_irqsave(&bp->lock, flags);
1721         if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1722             !(port->IER & IER_TXRDY)) {
1723                 port->IER |= IER_TXRDY;
1724                 sx_out(bp, CD186x_CAR, port_No(port));
1725                 sx_out(bp, CD186x_IER, port->IER);
1726         }
1727         spin_unlock_irqrestore(&bp->lock, flags);
1728         func_exit();
1729
1730         return total;
1731 }
1732
1733
1734 static void sx_put_char(struct tty_struct * tty, unsigned char ch)
1735 {
1736         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1737         unsigned long flags;
1738         struct specialix_board  * bp;
1739
1740         func_enter();
1741
1742         if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1743                 func_exit();
1744                 return;
1745         }
1746         dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1747         if (!tty || !port->xmit_buf) {
1748                 func_exit();
1749                 return;
1750         }
1751         bp = port_Board(port);
1752         spin_lock_irqsave(&port->lock, flags);
1753
1754         dprintk (SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", port->xmit_cnt, port->xmit_buf);
1755         if ((port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) || (!port->xmit_buf)) {
1756                 spin_unlock_irqrestore(&port->lock, flags);
1757                 dprintk (SX_DEBUG_TX, "Exit size\n");
1758                 func_exit();
1759                 return;
1760         }
1761         dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
1762         port->xmit_buf[port->xmit_head++] = ch;
1763         port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1764         port->xmit_cnt++;
1765         spin_unlock_irqrestore(&port->lock, flags);
1766
1767         func_exit();
1768 }
1769
1770
1771 static void sx_flush_chars(struct tty_struct * tty)
1772 {
1773         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1774         unsigned long flags;
1775         struct specialix_board  * bp = port_Board(port);
1776
1777         func_enter();
1778
1779         if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1780                 func_exit();
1781                 return;
1782         }
1783         if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1784             !port->xmit_buf) {
1785                 func_exit();
1786                 return;
1787         }
1788         spin_lock_irqsave(&bp->lock, flags);
1789         port->IER |= IER_TXRDY;
1790         sx_out(port_Board(port), CD186x_CAR, port_No(port));
1791         sx_out(port_Board(port), CD186x_IER, port->IER);
1792         spin_unlock_irqrestore(&bp->lock, flags);
1793
1794         func_exit();
1795 }
1796
1797
1798 static int sx_write_room(struct tty_struct * tty)
1799 {
1800         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1801         int     ret;
1802
1803         func_enter();
1804
1805         if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1806                 func_exit();
1807                 return 0;
1808         }
1809
1810         ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1811         if (ret < 0)
1812                 ret = 0;
1813
1814         func_exit();
1815         return ret;
1816 }
1817
1818
1819 static int sx_chars_in_buffer(struct tty_struct *tty)
1820 {
1821         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1822
1823         func_enter();
1824
1825         if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
1826                 func_exit();
1827                 return 0;
1828         }
1829         func_exit();
1830         return port->xmit_cnt;
1831 }
1832
1833
1834 static void sx_flush_buffer(struct tty_struct *tty)
1835 {
1836         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1837         unsigned long flags;
1838         struct specialix_board  * bp;
1839
1840         func_enter();
1841
1842         if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
1843                 func_exit();
1844                 return;
1845         }
1846
1847         bp = port_Board(port);
1848         spin_lock_irqsave(&port->lock, flags);
1849         port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1850         spin_unlock_irqrestore(&port->lock, flags);
1851         tty_wakeup(tty);
1852
1853         func_exit();
1854 }
1855
1856
1857 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1858 {
1859         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1860         struct specialix_board * bp;
1861         unsigned char status;
1862         unsigned int result;
1863         unsigned long flags;
1864
1865         func_enter();
1866
1867         if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1868                 func_exit();
1869                 return -ENODEV;
1870         }
1871
1872         bp = port_Board(port);
1873         spin_lock_irqsave (&bp->lock, flags);
1874         sx_out(bp, CD186x_CAR, port_No(port));
1875         status = sx_in(bp, CD186x_MSVR);
1876         spin_unlock_irqrestore(&bp->lock, flags);
1877         dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1878                 port_No(port), status, sx_in (bp, CD186x_CAR));
1879         dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1880         if (SX_CRTSCTS(port->tty)) {
1881                 result  = /*   (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
1882                           |   ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1883                           |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
1884                           |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1885                           |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1886         } else {
1887                 result  = /*   (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
1888                           |   ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1889                           |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
1890                           |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1891                           |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1892         }
1893
1894         func_exit();
1895
1896         return result;
1897 }
1898
1899
1900 static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1901                        unsigned int set, unsigned int clear)
1902 {
1903         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1904         unsigned long flags;
1905         struct specialix_board *bp;
1906
1907         func_enter();
1908
1909         if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1910                 func_exit();
1911                 return -ENODEV;
1912         }
1913
1914         bp = port_Board(port);
1915
1916         spin_lock_irqsave(&port->lock, flags);
1917    /*   if (set & TIOCM_RTS)
1918                 port->MSVR |= MSVR_RTS; */
1919    /*   if (set & TIOCM_DTR)
1920                 port->MSVR |= MSVR_DTR; */
1921
1922         if (SX_CRTSCTS(port->tty)) {
1923                 if (set & TIOCM_RTS)
1924                         port->MSVR |= MSVR_DTR;
1925         } else {
1926                 if (set & TIOCM_DTR)
1927                         port->MSVR |= MSVR_DTR;
1928         }
1929
1930   /*    if (clear & TIOCM_RTS)
1931                 port->MSVR &= ~MSVR_RTS; */
1932   /*    if (clear & TIOCM_DTR)
1933                 port->MSVR &= ~MSVR_DTR; */
1934         if (SX_CRTSCTS(port->tty)) {
1935                 if (clear & TIOCM_RTS)
1936                         port->MSVR &= ~MSVR_DTR;
1937         } else {
1938                 if (clear & TIOCM_DTR)
1939                         port->MSVR &= ~MSVR_DTR;
1940         }
1941         spin_lock_irqsave(&bp->lock, flags);
1942         sx_out(bp, CD186x_CAR, port_No(port));
1943         sx_out(bp, CD186x_MSVR, port->MSVR);
1944         spin_unlock_irqrestore(&bp->lock, flags);
1945         spin_unlock_irqrestore(&port->lock, flags);
1946         func_exit();
1947         return 0;
1948 }
1949
1950
1951 static inline void sx_send_break(struct specialix_port * port, unsigned long length)
1952 {
1953         struct specialix_board *bp = port_Board(port);
1954         unsigned long flags;
1955
1956         func_enter();
1957
1958         spin_lock_irqsave (&port->lock, flags);
1959         port->break_length = SPECIALIX_TPS / HZ * length;
1960         port->COR2 |= COR2_ETC;
1961         port->IER  |= IER_TXRDY;
1962         spin_lock_irqsave(&bp->lock, flags);
1963         sx_out(bp, CD186x_CAR, port_No(port));
1964         sx_out(bp, CD186x_COR2, port->COR2);
1965         sx_out(bp, CD186x_IER, port->IER);
1966         spin_unlock_irqrestore(&bp->lock, flags);
1967         spin_unlock_irqrestore (&port->lock, flags);
1968         sx_wait_CCR(bp);
1969         spin_lock_irqsave(&bp->lock, flags);
1970         sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1971         spin_unlock_irqrestore(&bp->lock, flags);
1972         sx_wait_CCR(bp);
1973
1974         func_exit();
1975 }
1976
1977
1978 static inline int sx_set_serial_info(struct specialix_port * port,
1979                                      struct serial_struct __user * newinfo)
1980 {
1981         struct serial_struct tmp;
1982         struct specialix_board *bp = port_Board(port);
1983         int change_speed;
1984
1985         func_enter();
1986         /*
1987         if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1988                 func_exit();
1989                 return -EFAULT;
1990         }
1991         */
1992         if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
1993                 func_enter();
1994                 return -EFAULT;
1995         }
1996
1997 #if 0
1998         if ((tmp.irq != bp->irq) ||
1999             (tmp.port != bp->base) ||
2000             (tmp.type != PORT_CIRRUS) ||
2001             (tmp.baud_base != (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) ||
2002             (tmp.custom_divisor != 0) ||
2003             (tmp.xmit_fifo_size != CD186x_NFIFO) ||
2004             (tmp.flags & ~SPECIALIX_LEGAL_FLAGS)) {
2005                 func_exit();
2006                 return -EINVAL;
2007         }
2008 #endif
2009
2010         change_speed = ((port->flags & ASYNC_SPD_MASK) !=
2011                         (tmp.flags & ASYNC_SPD_MASK));
2012         change_speed |= (tmp.custom_divisor != port->custom_divisor);
2013
2014         if (!capable(CAP_SYS_ADMIN)) {
2015                 if ((tmp.close_delay != port->close_delay) ||
2016                     (tmp.closing_wait != port->closing_wait) ||
2017                     ((tmp.flags & ~ASYNC_USR_MASK) !=
2018                      (port->flags & ~ASYNC_USR_MASK))) {
2019                         func_exit();
2020                         return -EPERM;
2021                 }
2022                 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
2023                                   (tmp.flags & ASYNC_USR_MASK));
2024                 port->custom_divisor = tmp.custom_divisor;
2025         } else {
2026                 port->flags = ((port->flags & ~ASYNC_FLAGS) |
2027                                   (tmp.flags & ASYNC_FLAGS));
2028                 port->close_delay = tmp.close_delay;
2029                 port->closing_wait = tmp.closing_wait;
2030                 port->custom_divisor = tmp.custom_divisor;
2031         }
2032         if (change_speed) {
2033                 sx_change_speed(bp, port);
2034         }
2035         func_exit();
2036         return 0;
2037 }
2038
2039
2040 static inline int sx_get_serial_info(struct specialix_port * port,
2041                                      struct serial_struct __user *retinfo)
2042 {
2043         struct serial_struct tmp;
2044         struct specialix_board *bp = port_Board(port);
2045
2046         func_enter();
2047
2048         /*
2049         if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
2050                 return -EFAULT;
2051         */
2052
2053         memset(&tmp, 0, sizeof(tmp));
2054         tmp.type = PORT_CIRRUS;
2055         tmp.line = port - sx_port;
2056         tmp.port = bp->base;
2057         tmp.irq  = bp->irq;
2058         tmp.flags = port->flags;
2059         tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
2060         tmp.close_delay = port->close_delay * HZ/100;
2061         tmp.closing_wait = port->closing_wait * HZ/100;
2062         tmp.custom_divisor =  port->custom_divisor;
2063         tmp.xmit_fifo_size = CD186x_NFIFO;
2064         if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
2065                 func_exit();
2066                 return -EFAULT;
2067         }
2068
2069         func_exit();
2070         return 0;
2071 }
2072
2073
2074 static int sx_ioctl(struct tty_struct * tty, struct file * filp,
2075                     unsigned int cmd, unsigned long arg)
2076 {
2077         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2078         int retval;
2079         void __user *argp = (void __user *)arg;
2080
2081         func_enter();
2082
2083         if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
2084                 func_exit();
2085                 return -ENODEV;
2086         }
2087
2088         switch (cmd) {
2089          case TCSBRK:   /* SVID version: non-zero arg --> no break */
2090                 retval = tty_check_change(tty);
2091                 if (retval) {
2092                         func_exit();
2093                         return retval;
2094                 }
2095                 tty_wait_until_sent(tty, 0);
2096                 if (!arg)
2097                         sx_send_break(port, HZ/4);      /* 1/4 second */
2098                 return 0;
2099          case TCSBRKP:  /* support for POSIX tcsendbreak() */
2100                 retval = tty_check_change(tty);
2101                 if (retval) {
2102                         func_exit();
2103                         return retval;
2104                 }
2105                 tty_wait_until_sent(tty, 0);
2106                 sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
2107                 func_exit();
2108                 return 0;
2109          case TIOCGSOFTCAR:
2110                  if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) {
2111                          func_exit();
2112                          return -EFAULT;
2113                  }
2114                  func_exit();
2115                 return 0;
2116          case TIOCSSOFTCAR:
2117                  if (get_user(arg, (unsigned long __user *) argp)) {
2118                          func_exit();
2119                          return -EFAULT;
2120                  }
2121                 tty->termios->c_cflag =
2122                         ((tty->termios->c_cflag & ~CLOCAL) |
2123                         (arg ? CLOCAL : 0));
2124                 func_exit();
2125                 return 0;
2126          case TIOCGSERIAL:
2127                  func_exit();
2128                 return sx_get_serial_info(port, argp);
2129          case TIOCSSERIAL:
2130                  func_exit();
2131                 return sx_set_serial_info(port, argp);
2132          default:
2133                  func_exit();
2134                 return -ENOIOCTLCMD;
2135         }
2136         func_exit();
2137         return 0;
2138 }
2139
2140
2141 static void sx_throttle(struct tty_struct * tty)
2142 {
2143         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2144         struct specialix_board *bp;
2145         unsigned long flags;
2146
2147         func_enter();
2148
2149         if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
2150                 func_exit();
2151                 return;
2152         }
2153
2154         bp = port_Board(port);
2155
2156         /* Use DTR instead of RTS ! */
2157         if (SX_CRTSCTS (tty))
2158                 port->MSVR &= ~MSVR_DTR;
2159         else {
2160                 /* Auch!!! I think the system shouldn't call this then. */
2161                 /* Or maybe we're supposed (allowed?) to do our side of hw
2162                    handshake anyway, even when hardware handshake is off.
2163                    When you see this in your logs, please report.... */
2164                 printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
2165                          port_No (port));
2166         }
2167         spin_lock_irqsave(&bp->lock, flags);
2168         sx_out(bp, CD186x_CAR, port_No(port));
2169         spin_unlock_irqrestore(&bp->lock, flags);
2170         if (I_IXOFF(tty)) {
2171                 spin_unlock_irqrestore(&bp->lock, flags);
2172                 sx_wait_CCR(bp);
2173                 spin_lock_irqsave(&bp->lock, flags);
2174                 sx_out(bp, CD186x_CCR, CCR_SSCH2);
2175                 spin_unlock_irqrestore(&bp->lock, flags);
2176                 sx_wait_CCR(bp);
2177         }
2178         spin_lock_irqsave(&bp->lock, flags);
2179         sx_out(bp, CD186x_MSVR, port->MSVR);
2180         spin_unlock_irqrestore(&bp->lock, flags);
2181
2182         func_exit();
2183 }
2184
2185
2186 static void sx_unthrottle(struct tty_struct * tty)
2187 {
2188         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2189         struct specialix_board *bp;
2190         unsigned long flags;
2191
2192         func_enter();
2193
2194         if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
2195                 func_exit();
2196                 return;
2197         }
2198
2199         bp = port_Board(port);
2200
2201         spin_lock_irqsave(&port->lock, flags);
2202         /* XXXX Use DTR INSTEAD???? */
2203         if (SX_CRTSCTS(tty)) {
2204                 port->MSVR |= MSVR_DTR;
2205         } /* Else clause: see remark in "sx_throttle"... */
2206         spin_lock_irqsave(&bp->lock, flags);
2207         sx_out(bp, CD186x_CAR, port_No(port));
2208         spin_unlock_irqrestore(&bp->lock, flags);
2209         if (I_IXOFF(tty)) {
2210                 spin_unlock_irqrestore(&port->lock, flags);
2211                 sx_wait_CCR(bp);
2212                 spin_lock_irqsave(&bp->lock, flags);
2213                 sx_out(bp, CD186x_CCR, CCR_SSCH1);
2214                 spin_unlock_irqrestore(&bp->lock, flags);
2215                 sx_wait_CCR(bp);
2216                 spin_lock_irqsave(&port->lock, flags);
2217         }
2218         spin_lock_irqsave(&bp->lock, flags);
2219         sx_out(bp, CD186x_MSVR, port->MSVR);
2220         spin_unlock_irqrestore(&bp->lock, flags);
2221         spin_unlock_irqrestore(&port->lock, flags);
2222
2223         func_exit();
2224 }
2225
2226
2227 static void sx_stop(struct tty_struct * tty)
2228 {
2229         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2230         struct specialix_board *bp;
2231         unsigned long flags;
2232
2233         func_enter();
2234
2235         if (sx_paranoia_check(port, tty->name, "sx_stop")) {
2236                 func_exit();
2237                 return;
2238         }
2239
2240         bp = port_Board(port);
2241
2242         spin_lock_irqsave(&port->lock, flags);
2243         port->IER &= ~IER_TXRDY;
2244         spin_lock_irqsave(&bp->lock, flags);
2245         sx_out(bp, CD186x_CAR, port_No(port));
2246         sx_out(bp, CD186x_IER, port->IER);
2247         spin_unlock_irqrestore(&bp->lock, flags);
2248         spin_unlock_irqrestore(&port->lock, flags);
2249
2250         func_exit();
2251 }
2252
2253
2254 static void sx_start(struct tty_struct * tty)
2255 {
2256         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2257         struct specialix_board *bp;
2258         unsigned long flags;
2259
2260         func_enter();
2261
2262         if (sx_paranoia_check(port, tty->name, "sx_start")) {
2263                 func_exit();
2264                 return;
2265         }
2266
2267         bp = port_Board(port);
2268
2269         spin_lock_irqsave(&port->lock, flags);
2270         if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2271                 port->IER |= IER_TXRDY;
2272                 spin_lock_irqsave(&bp->lock, flags);
2273                 sx_out(bp, CD186x_CAR, port_No(port));
2274                 sx_out(bp, CD186x_IER, port->IER);
2275                 spin_unlock_irqrestore(&bp->lock, flags);
2276         }
2277         spin_unlock_irqrestore(&port->lock, flags);
2278
2279         func_exit();
2280 }
2281
2282
2283 /*
2284  * This routine is called from the work-queue when the interrupt
2285  * routine has signalled that a hangup has occurred.  The path of
2286  * hangup processing is:
2287  *
2288  *      serial interrupt routine -> (workqueue) ->
2289  *      do_sx_hangup() -> tty->hangup() -> sx_hangup()
2290  *
2291  */
2292 static void do_sx_hangup(void *private_)
2293 {
2294         struct specialix_port   *port = (struct specialix_port *) private_;
2295         struct tty_struct       *tty;
2296
2297         func_enter();
2298
2299         tty = port->tty;
2300         if (tty)
2301                 tty_hangup(tty);        /* FIXME: module removal race here */
2302
2303         func_exit();
2304 }
2305
2306
2307 static void sx_hangup(struct tty_struct * tty)
2308 {
2309         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2310         struct specialix_board *bp;
2311         unsigned long flags;
2312
2313         func_enter();
2314
2315         if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2316                 func_exit();
2317                 return;
2318         }
2319
2320         bp = port_Board(port);
2321
2322         sx_shutdown_port(bp, port);
2323         spin_lock_irqsave(&port->lock, flags);
2324         port->event = 0;
2325         bp->count -= port->count;
2326         if (bp->count < 0) {
2327                 printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n",
2328                         board_No(bp), bp->count, tty->index);
2329                 bp->count = 0;
2330         }
2331         port->count = 0;
2332         port->flags &= ~ASYNC_NORMAL_ACTIVE;
2333         port->tty = NULL;
2334         spin_unlock_irqrestore(&port->lock, flags);
2335         wake_up_interruptible(&port->open_wait);
2336
2337         func_exit();
2338 }
2339
2340
2341 static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios)
2342 {
2343         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2344         unsigned long flags;
2345         struct specialix_board  * bp;
2346
2347         if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2348                 return;
2349
2350         if (tty->termios->c_cflag == old_termios->c_cflag &&
2351             tty->termios->c_iflag == old_termios->c_iflag)
2352                 return;
2353
2354         bp = port_Board(port);
2355         spin_lock_irqsave(&port->lock, flags);
2356         sx_change_speed(port_Board(port), port);
2357         spin_unlock_irqrestore(&port->lock, flags);
2358
2359         if ((old_termios->c_cflag & CRTSCTS) &&
2360             !(tty->termios->c_cflag & CRTSCTS)) {
2361                 tty->hw_stopped = 0;
2362                 sx_start(tty);
2363         }
2364 }
2365
2366
2367 static void do_softint(void *private_)
2368 {
2369         struct specialix_port   *port = (struct specialix_port *) private_;
2370         struct tty_struct       *tty;
2371
2372         func_enter();
2373
2374         if(!(tty = port->tty)) {
2375                 func_exit();
2376                 return;
2377         }
2378
2379         if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
2380                 tty_wakeup(tty);
2381                 //wake_up_interruptible(&tty->write_wait);
2382         }
2383
2384         func_exit();
2385 }
2386
2387 static struct tty_operations sx_ops = {
2388         .open  = sx_open,
2389         .close = sx_close,
2390         .write = sx_write,
2391         .put_char = sx_put_char,
2392         .flush_chars = sx_flush_chars,
2393         .write_room = sx_write_room,
2394         .chars_in_buffer = sx_chars_in_buffer,
2395         .flush_buffer = sx_flush_buffer,
2396         .ioctl = sx_ioctl,
2397         .throttle = sx_throttle,
2398         .unthrottle = sx_unthrottle,
2399         .set_termios = sx_set_termios,
2400         .stop = sx_stop,
2401         .start = sx_start,
2402         .hangup = sx_hangup,
2403         .tiocmget = sx_tiocmget,
2404         .tiocmset = sx_tiocmset,
2405 };
2406
2407 static int sx_init_drivers(void)
2408 {
2409         int error;
2410         int i;
2411
2412         func_enter();
2413
2414         specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT);
2415         if (!specialix_driver) {
2416                 printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n");
2417                 func_exit();
2418                 return 1;
2419         }
2420
2421         if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
2422                 printk(KERN_ERR "sx: Couldn't get free page.\n");
2423                 put_tty_driver(specialix_driver);
2424                 func_exit();
2425                 return 1;
2426         }
2427         specialix_driver->owner = THIS_MODULE;
2428         specialix_driver->name = "ttyW";
2429         specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
2430         specialix_driver->type = TTY_DRIVER_TYPE_SERIAL;
2431         specialix_driver->subtype = SERIAL_TYPE_NORMAL;
2432         specialix_driver->init_termios = tty_std_termios;
2433         specialix_driver->init_termios.c_cflag =
2434                 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2435         specialix_driver->flags = TTY_DRIVER_REAL_RAW;
2436         tty_set_operations(specialix_driver, &sx_ops);
2437
2438         if ((error = tty_register_driver(specialix_driver))) {
2439                 put_tty_driver(specialix_driver);
2440                 free_page((unsigned long)tmp_buf);
2441                 printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2442                        error);
2443                 func_exit();
2444                 return 1;
2445         }
2446         memset(sx_port, 0, sizeof(sx_port));
2447         for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2448                 sx_port[i].magic = SPECIALIX_MAGIC;
2449                 INIT_WORK(&sx_port[i].tqueue, do_softint, &sx_port[i]);
2450                 INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup, &sx_port[i]);
2451                 sx_port[i].close_delay = 50 * HZ/100;
2452                 sx_port[i].closing_wait = 3000 * HZ/100;
2453                 init_waitqueue_head(&sx_port[i].open_wait);
2454                 init_waitqueue_head(&sx_port[i].close_wait);
2455                 spin_lock_init(&sx_port[i].lock);
2456         }
2457
2458         func_exit();
2459         return 0;
2460 }
2461
2462 static void sx_release_drivers(void)
2463 {
2464         func_enter();
2465
2466         free_page((unsigned long)tmp_buf);
2467         tty_unregister_driver(specialix_driver);
2468         put_tty_driver(specialix_driver);
2469         func_exit();
2470 }
2471
2472 /*
2473  * This routine must be called by kernel at boot time
2474  */
2475 static int __init specialix_init(void)
2476 {
2477         int i;
2478         int found = 0;
2479
2480         func_enter();
2481
2482         printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
2483         printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2484 #ifdef CONFIG_SPECIALIX_RTSCTS
2485         printk (KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
2486 #else
2487         printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2488 #endif
2489
2490         for (i = 0; i < SX_NBOARD; i++)
2491                 sx_board[i].lock = SPIN_LOCK_UNLOCKED;
2492
2493         if (sx_init_drivers()) {
2494                 func_exit();
2495                 return -EIO;
2496         }
2497
2498         for (i = 0; i < SX_NBOARD; i++)
2499                 if (sx_board[i].base && !sx_probe(&sx_board[i]))
2500                         found++;
2501
2502 #ifdef CONFIG_PCI
2503         {
2504                 struct pci_dev *pdev = NULL;
2505
2506                 i=0;
2507                 while (i < SX_NBOARD) {
2508                         if (sx_board[i].flags & SX_BOARD_PRESENT) {
2509                                 i++;
2510                                 continue;
2511                         }
2512                         pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
2513                                                 PCI_DEVICE_ID_SPECIALIX_IO8,
2514                                                 pdev);
2515                         if (!pdev) break;
2516
2517                         if (pci_enable_device(pdev))
2518                                 continue;
2519
2520                         sx_board[i].irq = pdev->irq;
2521
2522                         sx_board[i].base = pci_resource_start (pdev, 2);
2523
2524                         sx_board[i].flags |= SX_BOARD_IS_PCI;
2525                         if (!sx_probe(&sx_board[i]))
2526                                 found ++;
2527                 }
2528         }
2529 #endif
2530
2531         if (!found) {
2532                 sx_release_drivers();
2533                 printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
2534                 func_exit();
2535                 return -EIO;
2536         }
2537
2538         func_exit();
2539         return 0;
2540 }
2541
2542 static int iobase[SX_NBOARD]  = {0,};
2543
2544 static int irq [SX_NBOARD] = {0,};
2545
2546 module_param_array(iobase, int, NULL, 0);
2547 module_param_array(irq, int, NULL, 0);
2548 module_param(sx_debug, int, 0);
2549 module_param(sx_rxfifo, int, 0);
2550 #ifdef SPECIALIX_TIMER
2551 module_param(sx_poll, int, 0);
2552 #endif
2553
2554 /*
2555  * You can setup up to 4 boards.
2556  * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2557  * You should specify the IRQs too in that case "irq=....,...".
2558  *
2559  * More than 4 boards in one computer is not possible, as the card can
2560  * only use 4 different interrupts.
2561  *
2562  */
2563 static int __init specialix_init_module(void)
2564 {
2565         int i;
2566
2567         func_enter();
2568
2569         init_MUTEX(&tmp_buf_sem); /* Init de the semaphore - pvdl */
2570
2571         if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2572                 for(i = 0; i < SX_NBOARD; i++) {
2573                         sx_board[i].base = iobase[i];
2574                         sx_board[i].irq = irq[i];
2575                         sx_board[i].count= 0;
2576                 }
2577         }
2578
2579         func_exit();
2580
2581         return specialix_init();
2582 }
2583
2584 static void __exit specialix_exit_module(void)
2585 {
2586         int i;
2587
2588         func_enter();
2589
2590         sx_release_drivers();
2591         for (i = 0; i < SX_NBOARD; i++)
2592                 if (sx_board[i].flags & SX_BOARD_PRESENT)
2593                         sx_release_io_range(&sx_board[i]);
2594 #ifdef SPECIALIX_TIMER
2595         del_timer (&missed_irq_timer);
2596 #endif
2597
2598         func_exit();
2599 }
2600
2601 module_init(specialix_init_module);
2602 module_exit(specialix_exit_module);
2603
2604 MODULE_LICENSE("GPL");