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