[PATCH] specialix - remove private speed decoding
[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 = tty_get_baud_rate(tty);
1091
1092         if (baud == 38400) {
1093                 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1094                         baud ++;
1095                 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1096                         baud += 2;
1097         }
1098
1099         if (!baud) {
1100                 /* Drop DTR & exit */
1101                 dprintk (SX_DEBUG_TERMIOS, "Dropping DTR...  Hmm....\n");
1102                 if (!SX_CRTSCTS (tty)) {
1103                         port -> MSVR &= ~ MSVR_DTR;
1104                         spin_lock_irqsave(&bp->lock, flags);
1105                         sx_out(bp, CD186x_MSVR, port->MSVR );
1106                         spin_unlock_irqrestore(&bp->lock, flags);
1107                 }
1108                 else
1109                         dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
1110                 return;
1111         } else {
1112                 /* Set DTR on */
1113                 if (!SX_CRTSCTS (tty)) {
1114                         port ->MSVR |= MSVR_DTR;
1115                 }
1116         }
1117
1118         /*
1119          * Now we must calculate some speed depended things
1120          */
1121
1122         /* Set baud rate for port */
1123         tmp = port->custom_divisor ;
1124         if ( tmp )
1125                 printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n"
1126                                   "This is an untested option, please be carefull.\n",
1127                                   port_No (port), tmp);
1128         else
1129                 tmp = (((SX_OSCFREQ + baud/2) / baud +
1130                          CD186x_TPC/2) / CD186x_TPC);
1131
1132         if ((tmp < 0x10) && time_before(again, jiffies)) {
1133                 again = jiffies + HZ * 60;
1134                 /* Page 48 of version 2.0 of the CL-CD1865 databook */
1135                 if (tmp >= 12) {
1136                         printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1137                                 "Performance degradation is possible.\n"
1138                                 "Read specialix.txt for more info.\n",
1139                                 port_No (port), tmp);
1140                 } else {
1141                         printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
1142                                 "Warning: overstressing Cirrus chip. "
1143                                 "This might not work.\n"
1144                                 "Read specialix.txt for more info.\n",
1145                                 port_No (port), tmp);
1146                 }
1147         }
1148         spin_lock_irqsave(&bp->lock, flags);
1149         sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
1150         sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
1151         sx_out(bp, CD186x_RBPRL, tmp & 0xff);
1152         sx_out(bp, CD186x_TBPRL, tmp & 0xff);
1153         spin_unlock_irqrestore(&bp->lock, flags);
1154         if (port->custom_divisor) {
1155                 baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
1156                 baud = ( baud + 5 ) / 10;
1157         } else
1158                 baud = (baud_table[baud] + 5) / 10;   /* Estimated CPS */
1159
1160         /* Two timer ticks seems enough to wakeup something like SLIP driver */
1161         tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
1162         port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
1163                                               SERIAL_XMIT_SIZE - 1 : tmp);
1164
1165         /* Receiver timeout will be transmission time for 1.5 chars */
1166         tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
1167         tmp = (tmp > 0xff) ? 0xff : tmp;
1168         spin_lock_irqsave(&bp->lock, flags);
1169         sx_out(bp, CD186x_RTPR, tmp);
1170         spin_unlock_irqrestore(&bp->lock, flags);
1171         switch (C_CSIZE(tty)) {
1172          case CS5:
1173                 cor1 |= COR1_5BITS;
1174                 break;
1175          case CS6:
1176                 cor1 |= COR1_6BITS;
1177                 break;
1178          case CS7:
1179                 cor1 |= COR1_7BITS;
1180                 break;
1181          case CS8:
1182                 cor1 |= COR1_8BITS;
1183                 break;
1184         }
1185
1186         if (C_CSTOPB(tty))
1187                 cor1 |= COR1_2SB;
1188
1189         cor1 |= COR1_IGNORE;
1190         if (C_PARENB(tty)) {
1191                 cor1 |= COR1_NORMPAR;
1192                 if (C_PARODD(tty))
1193                         cor1 |= COR1_ODDP;
1194                 if (I_INPCK(tty))
1195                         cor1 &= ~COR1_IGNORE;
1196         }
1197         /* Set marking of some errors */
1198         port->mark_mask = RCSR_OE | RCSR_TOUT;
1199         if (I_INPCK(tty))
1200                 port->mark_mask |= RCSR_FE | RCSR_PE;
1201         if (I_BRKINT(tty) || I_PARMRK(tty))
1202                 port->mark_mask |= RCSR_BREAK;
1203         if (I_IGNPAR(tty))
1204                 port->mark_mask &= ~(RCSR_FE | RCSR_PE);
1205         if (I_IGNBRK(tty)) {
1206                 port->mark_mask &= ~RCSR_BREAK;
1207                 if (I_IGNPAR(tty))
1208                         /* Real raw mode. Ignore all */
1209                         port->mark_mask &= ~RCSR_OE;
1210         }
1211         /* Enable Hardware Flow Control */
1212         if (C_CRTSCTS(tty)) {
1213 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
1214                 port->IER |= IER_DSR | IER_CTS;
1215                 mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
1216                 mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
1217                 spin_lock_irqsave(&bp->lock, flags);
1218                 tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
1219                 spin_unlock_irqrestore(&bp->lock, flags);
1220 #else
1221                 port->COR2 |= COR2_CTSAE;
1222 #endif
1223         }
1224         /* Enable Software Flow Control. FIXME: I'm not sure about this */
1225         /* Some people reported that it works, but I still doubt it */
1226         if (I_IXON(tty)) {
1227                 port->COR2 |= COR2_TXIBE;
1228                 cor3 |= (COR3_FCT | COR3_SCDE);
1229                 if (I_IXANY(tty))
1230                         port->COR2 |= COR2_IXM;
1231                 spin_lock_irqsave(&bp->lock, flags);
1232                 sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
1233                 sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
1234                 sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
1235                 sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
1236                 spin_unlock_irqrestore(&bp->lock, flags);
1237         }
1238         if (!C_CLOCAL(tty)) {
1239                 /* Enable CD check */
1240                 port->IER |= IER_CD;
1241                 mcor1 |= MCOR1_CDZD;
1242                 mcor2 |= MCOR2_CDOD;
1243         }
1244
1245         if (C_CREAD(tty))
1246                 /* Enable receiver */
1247                 port->IER |= IER_RXD;
1248
1249         /* Set input FIFO size (1-8 bytes) */
1250         cor3 |= sx_rxfifo;
1251         /* Setting up CD186x channel registers */
1252         spin_lock_irqsave(&bp->lock, flags);
1253         sx_out(bp, CD186x_COR1, cor1);
1254         sx_out(bp, CD186x_COR2, port->COR2);
1255         sx_out(bp, CD186x_COR3, cor3);
1256         spin_unlock_irqrestore(&bp->lock, flags);
1257         /* Make CD186x know about registers change */
1258         sx_wait_CCR(bp);
1259         spin_lock_irqsave(&bp->lock, flags);
1260         sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
1261         /* Setting up modem option registers */
1262         dprintk (SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2);
1263         sx_out(bp, CD186x_MCOR1, mcor1);
1264         sx_out(bp, CD186x_MCOR2, mcor2);
1265         spin_unlock_irqrestore(&bp->lock, flags);
1266         /* Enable CD186x transmitter & receiver */
1267         sx_wait_CCR(bp);
1268         spin_lock_irqsave(&bp->lock, flags);
1269         sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
1270         /* Enable interrupts */
1271         sx_out(bp, CD186x_IER, port->IER);
1272         /* And finally set the modem lines... */
1273         sx_out(bp, CD186x_MSVR, port->MSVR);
1274         spin_unlock_irqrestore(&bp->lock, flags);
1275
1276         func_exit();
1277 }
1278
1279
1280 /* Must be called with interrupts enabled */
1281 static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port)
1282 {
1283         unsigned long flags;
1284
1285         func_enter();
1286
1287         if (port->flags & ASYNC_INITIALIZED) {
1288                 func_exit();
1289                 return 0;
1290         }
1291
1292         if (!port->xmit_buf) {
1293                 /* We may sleep in get_zeroed_page() */
1294                 unsigned long tmp;
1295
1296                 if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
1297                         func_exit();
1298                         return -ENOMEM;
1299                 }
1300
1301                 if (port->xmit_buf) {
1302                         free_page(tmp);
1303                         func_exit();
1304                         return -ERESTARTSYS;
1305                 }
1306                 port->xmit_buf = (unsigned char *) tmp;
1307         }
1308
1309         spin_lock_irqsave(&port->lock, flags);
1310
1311         if (port->tty)
1312                 clear_bit(TTY_IO_ERROR, &port->tty->flags);
1313
1314         port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1315         sx_change_speed(bp, port);
1316         port->flags |= ASYNC_INITIALIZED;
1317
1318         spin_unlock_irqrestore(&port->lock, flags);
1319
1320
1321         func_exit();
1322         return 0;
1323 }
1324
1325
1326 /* Must be called with interrupts disabled */
1327 static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port)
1328 {
1329         struct tty_struct *tty;
1330         int i;
1331         unsigned long flags;
1332
1333         func_enter();
1334
1335         if (!(port->flags & ASYNC_INITIALIZED)) {
1336                 func_exit();
1337                 return;
1338         }
1339
1340         if (sx_debug & SX_DEBUG_FIFO) {
1341                 dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
1342                         board_No(bp), port_No(port), port->overrun);
1343                 for (i = 0; i < 10; i++) {
1344                         dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
1345                 }
1346                 dprintk(SX_DEBUG_FIFO, "].\n");
1347         }
1348
1349         if (port->xmit_buf) {
1350                 free_page((unsigned long) port->xmit_buf);
1351                 port->xmit_buf = NULL;
1352         }
1353
1354         /* Select port */
1355         spin_lock_irqsave(&bp->lock, flags);
1356         sx_out(bp, CD186x_CAR, port_No(port));
1357
1358         if (!(tty = port->tty) || C_HUPCL(tty)) {
1359                 /* Drop DTR */
1360                 sx_out(bp, CD186x_MSVDTR, 0);
1361         }
1362         spin_unlock_irqrestore(&bp->lock, flags);
1363         /* Reset port */
1364         sx_wait_CCR(bp);
1365         spin_lock_irqsave(&bp->lock, flags);
1366         sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
1367         /* Disable all interrupts from this port */
1368         port->IER = 0;
1369         sx_out(bp, CD186x_IER, port->IER);
1370         spin_unlock_irqrestore(&bp->lock, flags);
1371         if (tty)
1372                 set_bit(TTY_IO_ERROR, &tty->flags);
1373         port->flags &= ~ASYNC_INITIALIZED;
1374
1375         if (!bp->count)
1376                 sx_shutdown_board(bp);
1377         func_exit();
1378 }
1379
1380
1381 static int block_til_ready(struct tty_struct *tty, struct file * filp,
1382                            struct specialix_port *port)
1383 {
1384         DECLARE_WAITQUEUE(wait,  current);
1385         struct specialix_board *bp = port_Board(port);
1386         int    retval;
1387         int    do_clocal = 0;
1388         int    CD;
1389         unsigned long flags;
1390
1391         func_enter();
1392
1393         /*
1394          * If the device is in the middle of being closed, then block
1395          * until it's done, and then try again.
1396          */
1397         if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
1398                 interruptible_sleep_on(&port->close_wait);
1399                 if (port->flags & ASYNC_HUP_NOTIFY) {
1400                         func_exit();
1401                         return -EAGAIN;
1402                 } else {
1403                         func_exit();
1404                         return -ERESTARTSYS;
1405                 }
1406         }
1407
1408         /*
1409          * If non-blocking mode is set, or the port is not enabled,
1410          * then make the check up front and then exit.
1411          */
1412         if ((filp->f_flags & O_NONBLOCK) ||
1413             (tty->flags & (1 << TTY_IO_ERROR))) {
1414                 port->flags |= ASYNC_NORMAL_ACTIVE;
1415                 func_exit();
1416                 return 0;
1417         }
1418
1419         if (C_CLOCAL(tty))
1420                 do_clocal = 1;
1421
1422         /*
1423          * Block waiting for the carrier detect and the line to become
1424          * free (i.e., not in use by the callout).  While we are in
1425          * this loop, info->count is dropped by one, so that
1426          * rs_close() knows when to free things.  We restore it upon
1427          * exit, either normal or abnormal.
1428          */
1429         retval = 0;
1430         add_wait_queue(&port->open_wait, &wait);
1431         spin_lock_irqsave(&port->lock, flags);
1432         if (!tty_hung_up_p(filp)) {
1433                 port->count--;
1434         }
1435         spin_unlock_irqrestore(&port->lock, flags);
1436         port->blocked_open++;
1437         while (1) {
1438                 spin_lock_irqsave(&bp->lock, flags);
1439                 sx_out(bp, CD186x_CAR, port_No(port));
1440                 CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
1441                 if (SX_CRTSCTS (tty)) {
1442                         /* Activate RTS */
1443                         port->MSVR |= MSVR_DTR;         /* WTF? */
1444                         sx_out (bp, CD186x_MSVR, port->MSVR);
1445                 } else {
1446                         /* Activate DTR */
1447                         port->MSVR |= MSVR_DTR;
1448                         sx_out (bp, CD186x_MSVR, port->MSVR);
1449                 }
1450                 spin_unlock_irqrestore(&bp->lock, flags);
1451                 set_current_state(TASK_INTERRUPTIBLE);
1452                 if (tty_hung_up_p(filp) ||
1453                     !(port->flags & ASYNC_INITIALIZED)) {
1454                         if (port->flags & ASYNC_HUP_NOTIFY)
1455                                 retval = -EAGAIN;
1456                         else
1457                                 retval = -ERESTARTSYS;
1458                         break;
1459                 }
1460                 if (!(port->flags & ASYNC_CLOSING) &&
1461                     (do_clocal || CD))
1462                         break;
1463                 if (signal_pending(current)) {
1464                         retval = -ERESTARTSYS;
1465                         break;
1466                 }
1467                 schedule();
1468         }
1469
1470         set_current_state(TASK_RUNNING);
1471         remove_wait_queue(&port->open_wait, &wait);
1472         spin_lock_irqsave(&port->lock, flags);
1473         if (!tty_hung_up_p(filp)) {
1474                 port->count++;
1475         }
1476         port->blocked_open--;
1477         spin_unlock_irqrestore(&port->lock, flags);
1478         if (retval) {
1479                 func_exit();
1480                 return retval;
1481         }
1482
1483         port->flags |= ASYNC_NORMAL_ACTIVE;
1484         func_exit();
1485         return 0;
1486 }
1487
1488
1489 static int sx_open(struct tty_struct * tty, struct file * filp)
1490 {
1491         int board;
1492         int error;
1493         struct specialix_port * port;
1494         struct specialix_board * bp;
1495         int i;
1496         unsigned long flags;
1497
1498         func_enter();
1499
1500         board = SX_BOARD(tty->index);
1501
1502         if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) {
1503                 func_exit();
1504                 return -ENODEV;
1505         }
1506
1507         bp = &sx_board[board];
1508         port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
1509         port->overrun = 0;
1510         for (i = 0; i < 10; i++)
1511                 port->hits[i]=0;
1512
1513         dprintk (SX_DEBUG_OPEN, "Board = %d, bp = %p, port = %p, portno = %d.\n",
1514                 board, bp, port, SX_PORT(tty->index));
1515
1516         if (sx_paranoia_check(port, tty->name, "sx_open")) {
1517                 func_enter();
1518                 return -ENODEV;
1519         }
1520
1521         if ((error = sx_setup_board(bp))) {
1522                 func_exit();
1523                 return error;
1524         }
1525
1526         spin_lock_irqsave(&bp->lock, flags);
1527         port->count++;
1528         bp->count++;
1529         tty->driver_data = port;
1530         port->tty = tty;
1531         spin_unlock_irqrestore(&bp->lock, flags);
1532
1533         if ((error = sx_setup_port(bp, port))) {
1534                 func_enter();
1535                 return error;
1536         }
1537
1538         if ((error = block_til_ready(tty, filp, port))) {
1539                 func_enter();
1540                 return error;
1541         }
1542
1543         func_exit();
1544         return 0;
1545 }
1546
1547
1548 static void sx_close(struct tty_struct * tty, struct file * filp)
1549 {
1550         struct specialix_port *port = (struct specialix_port *) tty->driver_data;
1551         struct specialix_board *bp;
1552         unsigned long flags;
1553         unsigned long timeout;
1554
1555         func_enter();
1556         if (!port || sx_paranoia_check(port, tty->name, "close")) {
1557                 func_exit();
1558                 return;
1559         }
1560         spin_lock_irqsave(&port->lock, flags);
1561
1562         if (tty_hung_up_p(filp)) {
1563                 spin_unlock_irqrestore(&port->lock, flags);
1564                 func_exit();
1565                 return;
1566         }
1567
1568         bp = port_Board(port);
1569         if ((tty->count == 1) && (port->count != 1)) {
1570                 printk(KERN_ERR "sx%d: sx_close: bad port count;"
1571                        " tty->count is 1, port count is %d\n",
1572                        board_No(bp), port->count);
1573                 port->count = 1;
1574         }
1575
1576         if (port->count > 1) {
1577                 port->count--;
1578                 bp->count--;
1579
1580                 spin_unlock_irqrestore(&port->lock, flags);
1581
1582                 func_exit();
1583                 return;
1584         }
1585         port->flags |= ASYNC_CLOSING;
1586         /*
1587          * Now we wait for the transmit buffer to clear; and we notify
1588          * the line discipline to only process XON/XOFF characters.
1589          */
1590         tty->closing = 1;
1591         spin_unlock_irqrestore(&port->lock, flags);
1592         dprintk (SX_DEBUG_OPEN, "Closing\n");
1593         if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
1594                 tty_wait_until_sent(tty, port->closing_wait);
1595         }
1596         /*
1597          * At this point we stop accepting input.  To do this, we
1598          * disable the receive line status interrupts, and tell the
1599          * interrupt driver to stop checking the data ready bit in the
1600          * line status register.
1601          */
1602         dprintk (SX_DEBUG_OPEN, "Closed\n");
1603         port->IER &= ~IER_RXD;
1604         if (port->flags & ASYNC_INITIALIZED) {
1605                 port->IER &= ~IER_TXRDY;
1606                 port->IER |= IER_TXEMPTY;
1607                 spin_lock_irqsave(&bp->lock, flags);
1608                 sx_out(bp, CD186x_CAR, port_No(port));
1609                 sx_out(bp, CD186x_IER, port->IER);
1610                 spin_unlock_irqrestore(&bp->lock, flags);
1611                 /*
1612                  * Before we drop DTR, make sure the UART transmitter
1613                  * has completely drained; this is especially
1614                  * important if there is a transmit FIFO!
1615                  */
1616                 timeout = jiffies+HZ;
1617                 while(port->IER & IER_TXEMPTY) {
1618                         set_current_state (TASK_INTERRUPTIBLE);
1619                         msleep_interruptible(jiffies_to_msecs(port->timeout));
1620                         if (time_after(jiffies, timeout)) {
1621                                 printk (KERN_INFO "Timeout waiting for close\n");
1622                                 break;
1623                         }
1624                 }
1625
1626         }
1627
1628         if (--bp->count < 0) {
1629                 printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
1630                        board_No(bp), bp->count, tty->index);
1631                 bp->count = 0;
1632         }
1633         if (--port->count < 0) {
1634                 printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n",
1635                        board_No(bp), port_No(port), port->count);
1636                 port->count = 0;
1637         }
1638
1639         sx_shutdown_port(bp, port);
1640         if (tty->driver->flush_buffer)
1641                 tty->driver->flush_buffer(tty);
1642         tty_ldisc_flush(tty);
1643         spin_lock_irqsave(&port->lock, flags);
1644         tty->closing = 0;
1645         port->event = 0;
1646         port->tty = NULL;
1647         spin_unlock_irqrestore(&port->lock, flags);
1648         if (port->blocked_open) {
1649                 if (port->close_delay) {
1650                         msleep_interruptible(jiffies_to_msecs(port->close_delay));
1651                 }
1652                 wake_up_interruptible(&port->open_wait);
1653         }
1654         port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1655         wake_up_interruptible(&port->close_wait);
1656
1657         func_exit();
1658 }
1659
1660
1661 static int sx_write(struct tty_struct * tty,
1662                     const unsigned char *buf, int count)
1663 {
1664         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1665         struct specialix_board *bp;
1666         int c, total = 0;
1667         unsigned long flags;
1668
1669         func_enter();
1670         if (sx_paranoia_check(port, tty->name, "sx_write")) {
1671                 func_exit();
1672                 return 0;
1673         }
1674
1675         bp = port_Board(port);
1676
1677         if (!port->xmit_buf || !tmp_buf) {
1678                 func_exit();
1679                 return 0;
1680         }
1681
1682         while (1) {
1683                 spin_lock_irqsave(&port->lock, flags);
1684                 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1685                                    SERIAL_XMIT_SIZE - port->xmit_head));
1686                 if (c <= 0) {
1687                         spin_unlock_irqrestore(&port->lock, flags);
1688                         break;
1689                 }
1690                 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1691                 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1692                 port->xmit_cnt += c;
1693                 spin_unlock_irqrestore(&port->lock, flags);
1694
1695                 buf += c;
1696                 count -= c;
1697                 total += c;
1698         }
1699
1700         spin_lock_irqsave(&bp->lock, flags);
1701         if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1702             !(port->IER & IER_TXRDY)) {
1703                 port->IER |= IER_TXRDY;
1704                 sx_out(bp, CD186x_CAR, port_No(port));
1705                 sx_out(bp, CD186x_IER, port->IER);
1706         }
1707         spin_unlock_irqrestore(&bp->lock, flags);
1708         func_exit();
1709
1710         return total;
1711 }
1712
1713
1714 static void sx_put_char(struct tty_struct * tty, unsigned char ch)
1715 {
1716         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1717         unsigned long flags;
1718         struct specialix_board  * bp;
1719
1720         func_enter();
1721
1722         if (sx_paranoia_check(port, tty->name, "sx_put_char")) {
1723                 func_exit();
1724                 return;
1725         }
1726         dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
1727         if (!port->xmit_buf) {
1728                 func_exit();
1729                 return;
1730         }
1731         bp = port_Board(port);
1732         spin_lock_irqsave(&port->lock, flags);
1733
1734         dprintk (SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", port->xmit_cnt, port->xmit_buf);
1735         if ((port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) || (!port->xmit_buf)) {
1736                 spin_unlock_irqrestore(&port->lock, flags);
1737                 dprintk (SX_DEBUG_TX, "Exit size\n");
1738                 func_exit();
1739                 return;
1740         }
1741         dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
1742         port->xmit_buf[port->xmit_head++] = ch;
1743         port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1744         port->xmit_cnt++;
1745         spin_unlock_irqrestore(&port->lock, flags);
1746
1747         func_exit();
1748 }
1749
1750
1751 static void sx_flush_chars(struct tty_struct * tty)
1752 {
1753         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1754         unsigned long flags;
1755         struct specialix_board  * bp = port_Board(port);
1756
1757         func_enter();
1758
1759         if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) {
1760                 func_exit();
1761                 return;
1762         }
1763         if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1764             !port->xmit_buf) {
1765                 func_exit();
1766                 return;
1767         }
1768         spin_lock_irqsave(&bp->lock, flags);
1769         port->IER |= IER_TXRDY;
1770         sx_out(port_Board(port), CD186x_CAR, port_No(port));
1771         sx_out(port_Board(port), CD186x_IER, port->IER);
1772         spin_unlock_irqrestore(&bp->lock, flags);
1773
1774         func_exit();
1775 }
1776
1777
1778 static int sx_write_room(struct tty_struct * tty)
1779 {
1780         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1781         int     ret;
1782
1783         func_enter();
1784
1785         if (sx_paranoia_check(port, tty->name, "sx_write_room")) {
1786                 func_exit();
1787                 return 0;
1788         }
1789
1790         ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
1791         if (ret < 0)
1792                 ret = 0;
1793
1794         func_exit();
1795         return ret;
1796 }
1797
1798
1799 static int sx_chars_in_buffer(struct tty_struct *tty)
1800 {
1801         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1802
1803         func_enter();
1804
1805         if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
1806                 func_exit();
1807                 return 0;
1808         }
1809         func_exit();
1810         return port->xmit_cnt;
1811 }
1812
1813
1814 static void sx_flush_buffer(struct tty_struct *tty)
1815 {
1816         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1817         unsigned long flags;
1818         struct specialix_board  * bp;
1819
1820         func_enter();
1821
1822         if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) {
1823                 func_exit();
1824                 return;
1825         }
1826
1827         bp = port_Board(port);
1828         spin_lock_irqsave(&port->lock, flags);
1829         port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1830         spin_unlock_irqrestore(&port->lock, flags);
1831         tty_wakeup(tty);
1832
1833         func_exit();
1834 }
1835
1836
1837 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1838 {
1839         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1840         struct specialix_board * bp;
1841         unsigned char status;
1842         unsigned int result;
1843         unsigned long flags;
1844
1845         func_enter();
1846
1847         if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1848                 func_exit();
1849                 return -ENODEV;
1850         }
1851
1852         bp = port_Board(port);
1853         spin_lock_irqsave (&bp->lock, flags);
1854         sx_out(bp, CD186x_CAR, port_No(port));
1855         status = sx_in(bp, CD186x_MSVR);
1856         spin_unlock_irqrestore(&bp->lock, flags);
1857         dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1858                 port_No(port), status, sx_in (bp, CD186x_CAR));
1859         dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1860         if (SX_CRTSCTS(port->tty)) {
1861                 result  = /*   (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
1862                           |   ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1863                           |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
1864                           |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1865                           |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1866         } else {
1867                 result  = /*   (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
1868                           |   ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1869                           |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
1870                           |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
1871                           |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
1872         }
1873
1874         func_exit();
1875
1876         return result;
1877 }
1878
1879
1880 static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1881                        unsigned int set, unsigned int clear)
1882 {
1883         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
1884         unsigned long flags;
1885         struct specialix_board *bp;
1886
1887         func_enter();
1888
1889         if (sx_paranoia_check(port, tty->name, __FUNCTION__)) {
1890                 func_exit();
1891                 return -ENODEV;
1892         }
1893
1894         bp = port_Board(port);
1895
1896         spin_lock_irqsave(&port->lock, flags);
1897    /*   if (set & TIOCM_RTS)
1898                 port->MSVR |= MSVR_RTS; */
1899    /*   if (set & TIOCM_DTR)
1900                 port->MSVR |= MSVR_DTR; */
1901
1902         if (SX_CRTSCTS(port->tty)) {
1903                 if (set & TIOCM_RTS)
1904                         port->MSVR |= MSVR_DTR;
1905         } else {
1906                 if (set & TIOCM_DTR)
1907                         port->MSVR |= MSVR_DTR;
1908         }
1909
1910   /*    if (clear & TIOCM_RTS)
1911                 port->MSVR &= ~MSVR_RTS; */
1912   /*    if (clear & TIOCM_DTR)
1913                 port->MSVR &= ~MSVR_DTR; */
1914         if (SX_CRTSCTS(port->tty)) {
1915                 if (clear & TIOCM_RTS)
1916                         port->MSVR &= ~MSVR_DTR;
1917         } else {
1918                 if (clear & TIOCM_DTR)
1919                         port->MSVR &= ~MSVR_DTR;
1920         }
1921         spin_lock_irqsave(&bp->lock, flags);
1922         sx_out(bp, CD186x_CAR, port_No(port));
1923         sx_out(bp, CD186x_MSVR, port->MSVR);
1924         spin_unlock_irqrestore(&bp->lock, flags);
1925         spin_unlock_irqrestore(&port->lock, flags);
1926         func_exit();
1927         return 0;
1928 }
1929
1930
1931 static inline void sx_send_break(struct specialix_port * port, unsigned long length)
1932 {
1933         struct specialix_board *bp = port_Board(port);
1934         unsigned long flags;
1935
1936         func_enter();
1937
1938         spin_lock_irqsave (&port->lock, flags);
1939         port->break_length = SPECIALIX_TPS / HZ * length;
1940         port->COR2 |= COR2_ETC;
1941         port->IER  |= IER_TXRDY;
1942         spin_lock_irqsave(&bp->lock, flags);
1943         sx_out(bp, CD186x_CAR, port_No(port));
1944         sx_out(bp, CD186x_COR2, port->COR2);
1945         sx_out(bp, CD186x_IER, port->IER);
1946         spin_unlock_irqrestore(&bp->lock, flags);
1947         spin_unlock_irqrestore (&port->lock, flags);
1948         sx_wait_CCR(bp);
1949         spin_lock_irqsave(&bp->lock, flags);
1950         sx_out(bp, CD186x_CCR, CCR_CORCHG2);
1951         spin_unlock_irqrestore(&bp->lock, flags);
1952         sx_wait_CCR(bp);
1953
1954         func_exit();
1955 }
1956
1957
1958 static inline int sx_set_serial_info(struct specialix_port * port,
1959                                      struct serial_struct __user * newinfo)
1960 {
1961         struct serial_struct tmp;
1962         struct specialix_board *bp = port_Board(port);
1963         int change_speed;
1964
1965         func_enter();
1966         /*
1967         if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) {
1968                 func_exit();
1969                 return -EFAULT;
1970         }
1971         */
1972         if (copy_from_user(&tmp, newinfo, sizeof(tmp))) {
1973                 func_enter();
1974                 return -EFAULT;
1975         }
1976
1977 #if 0
1978         if ((tmp.irq != bp->irq) ||
1979             (tmp.port != bp->base) ||
1980             (tmp.type != PORT_CIRRUS) ||
1981             (tmp.baud_base != (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) ||
1982             (tmp.custom_divisor != 0) ||
1983             (tmp.xmit_fifo_size != CD186x_NFIFO) ||
1984             (tmp.flags & ~SPECIALIX_LEGAL_FLAGS)) {
1985                 func_exit();
1986                 return -EINVAL;
1987         }
1988 #endif
1989
1990         change_speed = ((port->flags & ASYNC_SPD_MASK) !=
1991                         (tmp.flags & ASYNC_SPD_MASK));
1992         change_speed |= (tmp.custom_divisor != port->custom_divisor);
1993
1994         if (!capable(CAP_SYS_ADMIN)) {
1995                 if ((tmp.close_delay != port->close_delay) ||
1996                     (tmp.closing_wait != port->closing_wait) ||
1997                     ((tmp.flags & ~ASYNC_USR_MASK) !=
1998                      (port->flags & ~ASYNC_USR_MASK))) {
1999                         func_exit();
2000                         return -EPERM;
2001                 }
2002                 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
2003                                   (tmp.flags & ASYNC_USR_MASK));
2004                 port->custom_divisor = tmp.custom_divisor;
2005         } else {
2006                 port->flags = ((port->flags & ~ASYNC_FLAGS) |
2007                                   (tmp.flags & ASYNC_FLAGS));
2008                 port->close_delay = tmp.close_delay;
2009                 port->closing_wait = tmp.closing_wait;
2010                 port->custom_divisor = tmp.custom_divisor;
2011         }
2012         if (change_speed) {
2013                 sx_change_speed(bp, port);
2014         }
2015         func_exit();
2016         return 0;
2017 }
2018
2019
2020 static inline int sx_get_serial_info(struct specialix_port * port,
2021                                      struct serial_struct __user *retinfo)
2022 {
2023         struct serial_struct tmp;
2024         struct specialix_board *bp = port_Board(port);
2025
2026         func_enter();
2027
2028         /*
2029         if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
2030                 return -EFAULT;
2031         */
2032
2033         memset(&tmp, 0, sizeof(tmp));
2034         tmp.type = PORT_CIRRUS;
2035         tmp.line = port - sx_port;
2036         tmp.port = bp->base;
2037         tmp.irq  = bp->irq;
2038         tmp.flags = port->flags;
2039         tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
2040         tmp.close_delay = port->close_delay * HZ/100;
2041         tmp.closing_wait = port->closing_wait * HZ/100;
2042         tmp.custom_divisor =  port->custom_divisor;
2043         tmp.xmit_fifo_size = CD186x_NFIFO;
2044         if (copy_to_user(retinfo, &tmp, sizeof(tmp))) {
2045                 func_exit();
2046                 return -EFAULT;
2047         }
2048
2049         func_exit();
2050         return 0;
2051 }
2052
2053
2054 static int sx_ioctl(struct tty_struct * tty, struct file * filp,
2055                     unsigned int cmd, unsigned long arg)
2056 {
2057         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2058         int retval;
2059         void __user *argp = (void __user *)arg;
2060
2061         func_enter();
2062
2063         if (sx_paranoia_check(port, tty->name, "sx_ioctl")) {
2064                 func_exit();
2065                 return -ENODEV;
2066         }
2067
2068         switch (cmd) {
2069          case TCSBRK:   /* SVID version: non-zero arg --> no break */
2070                 retval = tty_check_change(tty);
2071                 if (retval) {
2072                         func_exit();
2073                         return retval;
2074                 }
2075                 tty_wait_until_sent(tty, 0);
2076                 if (!arg)
2077                         sx_send_break(port, HZ/4);      /* 1/4 second */
2078                 return 0;
2079          case TCSBRKP:  /* support for POSIX tcsendbreak() */
2080                 retval = tty_check_change(tty);
2081                 if (retval) {
2082                         func_exit();
2083                         return retval;
2084                 }
2085                 tty_wait_until_sent(tty, 0);
2086                 sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
2087                 func_exit();
2088                 return 0;
2089          case TIOCGSOFTCAR:
2090                  if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)argp)) {
2091                          func_exit();
2092                          return -EFAULT;
2093                  }
2094                  func_exit();
2095                 return 0;
2096          case TIOCSSOFTCAR:
2097                  if (get_user(arg, (unsigned long __user *) argp)) {
2098                          func_exit();
2099                          return -EFAULT;
2100                  }
2101                 tty->termios->c_cflag =
2102                         ((tty->termios->c_cflag & ~CLOCAL) |
2103                         (arg ? CLOCAL : 0));
2104                 func_exit();
2105                 return 0;
2106          case TIOCGSERIAL:
2107                  func_exit();
2108                 return sx_get_serial_info(port, argp);
2109          case TIOCSSERIAL:
2110                  func_exit();
2111                 return sx_set_serial_info(port, argp);
2112          default:
2113                  func_exit();
2114                 return -ENOIOCTLCMD;
2115         }
2116         func_exit();
2117         return 0;
2118 }
2119
2120
2121 static void sx_throttle(struct tty_struct * tty)
2122 {
2123         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2124         struct specialix_board *bp;
2125         unsigned long flags;
2126
2127         func_enter();
2128
2129         if (sx_paranoia_check(port, tty->name, "sx_throttle")) {
2130                 func_exit();
2131                 return;
2132         }
2133
2134         bp = port_Board(port);
2135
2136         /* Use DTR instead of RTS ! */
2137         if (SX_CRTSCTS (tty))
2138                 port->MSVR &= ~MSVR_DTR;
2139         else {
2140                 /* Auch!!! I think the system shouldn't call this then. */
2141                 /* Or maybe we're supposed (allowed?) to do our side of hw
2142                    handshake anyway, even when hardware handshake is off.
2143                    When you see this in your logs, please report.... */
2144                 printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
2145                          port_No (port));
2146         }
2147         spin_lock_irqsave(&bp->lock, flags);
2148         sx_out(bp, CD186x_CAR, port_No(port));
2149         spin_unlock_irqrestore(&bp->lock, flags);
2150         if (I_IXOFF(tty)) {
2151                 spin_unlock_irqrestore(&bp->lock, flags);
2152                 sx_wait_CCR(bp);
2153                 spin_lock_irqsave(&bp->lock, flags);
2154                 sx_out(bp, CD186x_CCR, CCR_SSCH2);
2155                 spin_unlock_irqrestore(&bp->lock, flags);
2156                 sx_wait_CCR(bp);
2157         }
2158         spin_lock_irqsave(&bp->lock, flags);
2159         sx_out(bp, CD186x_MSVR, port->MSVR);
2160         spin_unlock_irqrestore(&bp->lock, flags);
2161
2162         func_exit();
2163 }
2164
2165
2166 static void sx_unthrottle(struct tty_struct * tty)
2167 {
2168         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2169         struct specialix_board *bp;
2170         unsigned long flags;
2171
2172         func_enter();
2173
2174         if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
2175                 func_exit();
2176                 return;
2177         }
2178
2179         bp = port_Board(port);
2180
2181         spin_lock_irqsave(&port->lock, flags);
2182         /* XXXX Use DTR INSTEAD???? */
2183         if (SX_CRTSCTS(tty)) {
2184                 port->MSVR |= MSVR_DTR;
2185         } /* Else clause: see remark in "sx_throttle"... */
2186         spin_lock_irqsave(&bp->lock, flags);
2187         sx_out(bp, CD186x_CAR, port_No(port));
2188         spin_unlock_irqrestore(&bp->lock, flags);
2189         if (I_IXOFF(tty)) {
2190                 spin_unlock_irqrestore(&port->lock, flags);
2191                 sx_wait_CCR(bp);
2192                 spin_lock_irqsave(&bp->lock, flags);
2193                 sx_out(bp, CD186x_CCR, CCR_SSCH1);
2194                 spin_unlock_irqrestore(&bp->lock, flags);
2195                 sx_wait_CCR(bp);
2196                 spin_lock_irqsave(&port->lock, flags);
2197         }
2198         spin_lock_irqsave(&bp->lock, flags);
2199         sx_out(bp, CD186x_MSVR, port->MSVR);
2200         spin_unlock_irqrestore(&bp->lock, flags);
2201         spin_unlock_irqrestore(&port->lock, flags);
2202
2203         func_exit();
2204 }
2205
2206
2207 static void sx_stop(struct tty_struct * tty)
2208 {
2209         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2210         struct specialix_board *bp;
2211         unsigned long flags;
2212
2213         func_enter();
2214
2215         if (sx_paranoia_check(port, tty->name, "sx_stop")) {
2216                 func_exit();
2217                 return;
2218         }
2219
2220         bp = port_Board(port);
2221
2222         spin_lock_irqsave(&port->lock, flags);
2223         port->IER &= ~IER_TXRDY;
2224         spin_lock_irqsave(&bp->lock, flags);
2225         sx_out(bp, CD186x_CAR, port_No(port));
2226         sx_out(bp, CD186x_IER, port->IER);
2227         spin_unlock_irqrestore(&bp->lock, flags);
2228         spin_unlock_irqrestore(&port->lock, flags);
2229
2230         func_exit();
2231 }
2232
2233
2234 static void sx_start(struct tty_struct * tty)
2235 {
2236         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2237         struct specialix_board *bp;
2238         unsigned long flags;
2239
2240         func_enter();
2241
2242         if (sx_paranoia_check(port, tty->name, "sx_start")) {
2243                 func_exit();
2244                 return;
2245         }
2246
2247         bp = port_Board(port);
2248
2249         spin_lock_irqsave(&port->lock, flags);
2250         if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
2251                 port->IER |= IER_TXRDY;
2252                 spin_lock_irqsave(&bp->lock, flags);
2253                 sx_out(bp, CD186x_CAR, port_No(port));
2254                 sx_out(bp, CD186x_IER, port->IER);
2255                 spin_unlock_irqrestore(&bp->lock, flags);
2256         }
2257         spin_unlock_irqrestore(&port->lock, flags);
2258
2259         func_exit();
2260 }
2261
2262
2263 /*
2264  * This routine is called from the work-queue when the interrupt
2265  * routine has signalled that a hangup has occurred.  The path of
2266  * hangup processing is:
2267  *
2268  *      serial interrupt routine -> (workqueue) ->
2269  *      do_sx_hangup() -> tty->hangup() -> sx_hangup()
2270  *
2271  */
2272 static void do_sx_hangup(void *private_)
2273 {
2274         struct specialix_port   *port = (struct specialix_port *) private_;
2275         struct tty_struct       *tty;
2276
2277         func_enter();
2278
2279         tty = port->tty;
2280         if (tty)
2281                 tty_hangup(tty);        /* FIXME: module removal race here */
2282
2283         func_exit();
2284 }
2285
2286
2287 static void sx_hangup(struct tty_struct * tty)
2288 {
2289         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2290         struct specialix_board *bp;
2291         unsigned long flags;
2292
2293         func_enter();
2294
2295         if (sx_paranoia_check(port, tty->name, "sx_hangup")) {
2296                 func_exit();
2297                 return;
2298         }
2299
2300         bp = port_Board(port);
2301
2302         sx_shutdown_port(bp, port);
2303         spin_lock_irqsave(&port->lock, flags);
2304         port->event = 0;
2305         bp->count -= port->count;
2306         if (bp->count < 0) {
2307                 printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n",
2308                         board_No(bp), bp->count, tty->index);
2309                 bp->count = 0;
2310         }
2311         port->count = 0;
2312         port->flags &= ~ASYNC_NORMAL_ACTIVE;
2313         port->tty = NULL;
2314         spin_unlock_irqrestore(&port->lock, flags);
2315         wake_up_interruptible(&port->open_wait);
2316
2317         func_exit();
2318 }
2319
2320
2321 static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios)
2322 {
2323         struct specialix_port *port = (struct specialix_port *)tty->driver_data;
2324         unsigned long flags;
2325         struct specialix_board  * bp;
2326
2327         if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2328                 return;
2329
2330         if (tty->termios->c_cflag == old_termios->c_cflag &&
2331             tty->termios->c_iflag == old_termios->c_iflag)
2332                 return;
2333
2334         bp = port_Board(port);
2335         spin_lock_irqsave(&port->lock, flags);
2336         sx_change_speed(port_Board(port), port);
2337         spin_unlock_irqrestore(&port->lock, flags);
2338
2339         if ((old_termios->c_cflag & CRTSCTS) &&
2340             !(tty->termios->c_cflag & CRTSCTS)) {
2341                 tty->hw_stopped = 0;
2342                 sx_start(tty);
2343         }
2344 }
2345
2346
2347 static void do_softint(void *private_)
2348 {
2349         struct specialix_port   *port = (struct specialix_port *) private_;
2350         struct tty_struct       *tty;
2351
2352         func_enter();
2353
2354         if(!(tty = port->tty)) {
2355                 func_exit();
2356                 return;
2357         }
2358
2359         if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
2360                 tty_wakeup(tty);
2361                 //wake_up_interruptible(&tty->write_wait);
2362         }
2363
2364         func_exit();
2365 }
2366
2367 static struct tty_operations sx_ops = {
2368         .open  = sx_open,
2369         .close = sx_close,
2370         .write = sx_write,
2371         .put_char = sx_put_char,
2372         .flush_chars = sx_flush_chars,
2373         .write_room = sx_write_room,
2374         .chars_in_buffer = sx_chars_in_buffer,
2375         .flush_buffer = sx_flush_buffer,
2376         .ioctl = sx_ioctl,
2377         .throttle = sx_throttle,
2378         .unthrottle = sx_unthrottle,
2379         .set_termios = sx_set_termios,
2380         .stop = sx_stop,
2381         .start = sx_start,
2382         .hangup = sx_hangup,
2383         .tiocmget = sx_tiocmget,
2384         .tiocmset = sx_tiocmset,
2385 };
2386
2387 static int sx_init_drivers(void)
2388 {
2389         int error;
2390         int i;
2391
2392         func_enter();
2393
2394         specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT);
2395         if (!specialix_driver) {
2396                 printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n");
2397                 func_exit();
2398                 return 1;
2399         }
2400
2401         if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
2402                 printk(KERN_ERR "sx: Couldn't get free page.\n");
2403                 put_tty_driver(specialix_driver);
2404                 func_exit();
2405                 return 1;
2406         }
2407         specialix_driver->owner = THIS_MODULE;
2408         specialix_driver->name = "ttyW";
2409         specialix_driver->major = SPECIALIX_NORMAL_MAJOR;
2410         specialix_driver->type = TTY_DRIVER_TYPE_SERIAL;
2411         specialix_driver->subtype = SERIAL_TYPE_NORMAL;
2412         specialix_driver->init_termios = tty_std_termios;
2413         specialix_driver->init_termios.c_cflag =
2414                 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
2415         specialix_driver->flags = TTY_DRIVER_REAL_RAW;
2416         tty_set_operations(specialix_driver, &sx_ops);
2417
2418         if ((error = tty_register_driver(specialix_driver))) {
2419                 put_tty_driver(specialix_driver);
2420                 free_page((unsigned long)tmp_buf);
2421                 printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
2422                        error);
2423                 func_exit();
2424                 return 1;
2425         }
2426         memset(sx_port, 0, sizeof(sx_port));
2427         for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2428                 sx_port[i].magic = SPECIALIX_MAGIC;
2429                 INIT_WORK(&sx_port[i].tqueue, do_softint, &sx_port[i]);
2430                 INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup, &sx_port[i]);
2431                 sx_port[i].close_delay = 50 * HZ/100;
2432                 sx_port[i].closing_wait = 3000 * HZ/100;
2433                 init_waitqueue_head(&sx_port[i].open_wait);
2434                 init_waitqueue_head(&sx_port[i].close_wait);
2435                 spin_lock_init(&sx_port[i].lock);
2436         }
2437
2438         func_exit();
2439         return 0;
2440 }
2441
2442 static void sx_release_drivers(void)
2443 {
2444         func_enter();
2445
2446         free_page((unsigned long)tmp_buf);
2447         tty_unregister_driver(specialix_driver);
2448         put_tty_driver(specialix_driver);
2449         func_exit();
2450 }
2451
2452 /*
2453  * This routine must be called by kernel at boot time
2454  */
2455 static int __init specialix_init(void)
2456 {
2457         int i;
2458         int found = 0;
2459
2460         func_enter();
2461
2462         printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
2463         printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
2464 #ifdef CONFIG_SPECIALIX_RTSCTS
2465         printk (KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
2466 #else
2467         printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
2468 #endif
2469
2470         for (i = 0; i < SX_NBOARD; i++)
2471                 spin_lock_init(&sx_board[i].lock);
2472
2473         if (sx_init_drivers()) {
2474                 func_exit();
2475                 return -EIO;
2476         }
2477
2478         for (i = 0; i < SX_NBOARD; i++)
2479                 if (sx_board[i].base && !sx_probe(&sx_board[i]))
2480                         found++;
2481
2482 #ifdef CONFIG_PCI
2483         {
2484                 struct pci_dev *pdev = NULL;
2485
2486                 i=0;
2487                 while (i < SX_NBOARD) {
2488                         if (sx_board[i].flags & SX_BOARD_PRESENT) {
2489                                 i++;
2490                                 continue;
2491                         }
2492                         pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
2493                                                 PCI_DEVICE_ID_SPECIALIX_IO8,
2494                                                 pdev);
2495                         if (!pdev) break;
2496
2497                         if (pci_enable_device(pdev))
2498                                 continue;
2499
2500                         sx_board[i].irq = pdev->irq;
2501
2502                         sx_board[i].base = pci_resource_start (pdev, 2);
2503
2504                         sx_board[i].flags |= SX_BOARD_IS_PCI;
2505                         if (!sx_probe(&sx_board[i]))
2506                                 found ++;
2507                 }
2508         }
2509 #endif
2510
2511         if (!found) {
2512                 sx_release_drivers();
2513                 printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n");
2514                 func_exit();
2515                 return -EIO;
2516         }
2517
2518         func_exit();
2519         return 0;
2520 }
2521
2522 static int iobase[SX_NBOARD]  = {0,};
2523
2524 static int irq [SX_NBOARD] = {0,};
2525
2526 module_param_array(iobase, int, NULL, 0);
2527 module_param_array(irq, int, NULL, 0);
2528 module_param(sx_debug, int, 0);
2529 module_param(sx_rxfifo, int, 0);
2530 #ifdef SPECIALIX_TIMER
2531 module_param(sx_poll, int, 0);
2532 #endif
2533
2534 /*
2535  * You can setup up to 4 boards.
2536  * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
2537  * You should specify the IRQs too in that case "irq=....,...".
2538  *
2539  * More than 4 boards in one computer is not possible, as the card can
2540  * only use 4 different interrupts.
2541  *
2542  */
2543 static int __init specialix_init_module(void)
2544 {
2545         int i;
2546
2547         func_enter();
2548
2549         if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
2550                 for(i = 0; i < SX_NBOARD; i++) {
2551                         sx_board[i].base = iobase[i];
2552                         sx_board[i].irq = irq[i];
2553                         sx_board[i].count= 0;
2554                 }
2555         }
2556
2557         func_exit();
2558
2559         return specialix_init();
2560 }
2561
2562 static void __exit specialix_exit_module(void)
2563 {
2564         int i;
2565
2566         func_enter();
2567
2568         sx_release_drivers();
2569         for (i = 0; i < SX_NBOARD; i++)
2570                 if (sx_board[i].flags & SX_BOARD_PRESENT)
2571                         sx_release_io_range(&sx_board[i]);
2572 #ifdef SPECIALIX_TIMER
2573         del_timer (&missed_irq_timer);
2574 #endif
2575
2576         func_exit();
2577 }
2578
2579 static struct pci_device_id specialx_pci_tbl[] __devinitdata = {
2580         { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) },
2581         { }
2582 };
2583 MODULE_DEVICE_TABLE(pci, specialx_pci_tbl);
2584
2585 module_init(specialix_init_module);
2586 module_exit(specialix_exit_module);
2587
2588 MODULE_LICENSE("GPL");