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