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