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