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