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