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