Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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