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