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