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