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