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