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