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