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