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