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