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