This source file includes following definitions.
- send_break
- rs_sched_event
- UART_ISR_proc
- send_intr
- receive_intr
- line_status_intr
- modem_status_intr
- UART_ISR_proc
- FourPort_ISR_proc
- rs_interrupt
- rs_probe
- rs_timer
- rs_write
- rs_throttle
- rs_close
- startup
- shutdown
- change_speed
- get_serial_info
- set_serial_info
- get_modem_info
- set_modem_info
- rs_ioctl
- rs_open
- show_serial_version
- init
- rs_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <linux/errno.h>
24 #include <linux/signal.h>
25 #include <linux/sched.h>
26 #include <linux/timer.h>
27 #include <linux/tty.h>
28 #include <linux/serial.h>
29 #include <linux/config.h>
30
31 #include <asm/system.h>
32 #include <asm/io.h>
33 #include <asm/segment.h>
34 #include <asm/bitops.h>
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 #undef NEW_INTERRUPT_ROUTINE
63
64 #define WAKEUP_CHARS (3*TTY_BUF_SIZE/4)
65
66
67
68
69
70
71
72
73
74
75
76 static unsigned long rs_event = 0;
77 static unsigned long rs_write_active = 0;
78
79 static async_ISR IRQ_ISR[16];
80
81 static void UART_ISR_proc(async_ISR ISR, int line);
82
83 struct struct_ISR COM1_ISR = { 4, 0x3f8, UART_ISR_proc, 0, };
84 struct struct_ISR COM2_ISR = { 3, 0x2f8, UART_ISR_proc, 0, };
85 struct struct_ISR COM3_ISR = { 4, 0x3e8, UART_ISR_proc, 0, };
86 struct struct_ISR COM4_ISR = { 3, 0x2e8, UART_ISR_proc, 0, };
87
88 #ifdef CONFIG_AST_FOURPORT
89 static void FourPort_ISR_proc(async_ISR ISR, int line);
90
91 struct struct_ISR FourPort1_ISR = { 2, 0x1bf, FourPort_ISR_proc, 0, };
92 struct struct_ISR FourPort2_ISR = { 5, 0x2bf, FourPort_ISR_proc, 0, };
93 #endif
94
95 #ifdef CONFIG_ACCENT_ASYNC
96 struct struct_ISR Accent3_ISR = { 4, 0x330, UART_ISR_proc, 0, };
97 struct struct_ISR Accent4_ISR = { 4, 0x338, UART_ISR_proc, 0, };
98 #endif
99
100
101
102
103
104
105
106
107 #define BASE_BAUD ( 1843200 / 16 )
108
109 struct async_struct rs_table[] = {
110 { BASE_BAUD, 0x3F8, &COM1_ISR, 0, },
111 { BASE_BAUD, 0x2F8, &COM2_ISR, 0, },
112 { BASE_BAUD, 0x3E8, &COM3_ISR, 0, },
113 { BASE_BAUD, 0x2E8, &COM4_ISR, 0, },
114 #ifdef CONFIG_AST_FOURPORT
115 { BASE_BAUD, 0x1A0, &FourPort1_ISR, ASYNC_FOURPORT },
116 { BASE_BAUD, 0x1A8, &FourPort1_ISR, ASYNC_FOURPORT },
117 { BASE_BAUD, 0x1B0, &FourPort1_ISR, ASYNC_FOURPORT },
118 { BASE_BAUD, 0x1B8, &FourPort1_ISR, ASYNC_FOURPORT | ASYNC_NOSCRATCH },
119
120 { BASE_BAUD, 0x2A0, &FourPort2_ISR, ASYNC_FOURPORT },
121 { BASE_BAUD, 0x2A8, &FourPort2_ISR, ASYNC_FOURPORT },
122 { BASE_BAUD, 0x2B0, &FourPort2_ISR, ASYNC_FOURPORT },
123 { BASE_BAUD, 0x2B8, &FourPort2_ISR, ASYNC_FOURPORT | ASYNC_NOSCRATCH },
124 #else
125 { BASE_BAUD, 0x000 },
126 { BASE_BAUD, 0x000 },
127 { BASE_BAUD, 0x000 },
128 { BASE_BAUD, 0x000 },
129
130 { BASE_BAUD, 0x000 },
131 { BASE_BAUD, 0x000 },
132 { BASE_BAUD, 0x000 },
133 { BASE_BAUD, 0x000 },
134 #endif
135
136 #ifdef CONFIG_ACCENT_ASYNC
137 { BASE_BAUD, 0x330, &Accent3_ISR, 0 },
138 { BASE_BAUD, 0x338, &Accent4_ISR, 0 },
139 #else
140 { BASE_BAUD, 0x000 },
141 { BASE_BAUD, 0x000 },
142 #endif
143 { BASE_BAUD, 0x000 },
144 { BASE_BAUD, 0x000 },
145
146 };
147
148 #define NR_PORTS (sizeof(rs_table)/sizeof(struct async_struct))
149
150
151
152
153 static int baud_table[] = {
154 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
155 9600, 19200, 38400, 56000, 115200, 0 };
156
157 static void startup(struct async_struct * info);
158 static void shutdown(struct async_struct * info);
159 static void rs_throttle(struct tty_struct * tty, int status);
160
161 static void send_break( struct async_struct * info)
162 {
163 unsigned short port;
164
165 if (!(port = info->port))
166 return;
167 port += UART_LCR;
168 current->state = TASK_INTERRUPTIBLE;
169 current->timeout = jiffies + 25;
170 outb_p(inb_p(port) | UART_LCR_SBC, port);
171 schedule();
172 outb(inb_p(port) & ~UART_LCR_SBC, port);
173 }
174
175 static inline void rs_sched_event(int line,
176 struct async_struct *info,
177 int event)
178 {
179 info->event |= 1 << event;
180 rs_event |= 1 << line;
181 timer_table[RS_TIMER].expires = 0;
182 timer_active |= 1 << RS_TIMER;
183 }
184
185 #ifdef NEW_INTERRUPT_ROUTINE
186
187
188
189
190
191
192
193
194
195
196
197
198 static void UART_ISR_proc(async_ISR ISR, int line)
199 {
200 unsigned char status;
201 struct async_struct * info = rs_table + line;
202 struct tty_queue * queue;
203 int head, tail, count, ch;
204 int cflag, iflag;
205
206
207
208
209
210 #define VLEFT ((tail-head-1)&(TTY_BUF_SIZE-1))
211
212 if (!info || !info->tty || !info->port)
213 return;
214 cflag = info->tty->termios->c_cflag;
215 iflag = info->tty->termios->c_iflag;
216
217 do {
218 restart:
219 status = inb_p(UART_LSR + info->port);
220 if (status & UART_LSR_DR) {
221 queue = &info->tty->read_q;
222 head = queue->head;
223 tail = queue->tail;
224 do {
225 ch = inb(UART_RX + info->port);
226
227
228
229
230 if (VLEFT < 3)
231 continue;
232 if (status & (UART_LSR_BI |
233 UART_LSR_FE |
234 UART_LSR_PE)) {
235 if (status & (UART_LSR_BI)) {
236 if (info->flags & ASYNC_SAK)
237 rs_sched_event(line, info, RS_EVENT_DO_SAK);
238 else if (iflag & IGNBRK)
239 continue;
240 else if (iflag & BRKINT)
241 rs_sched_event(line, info, RS_EVENT_BREAK_INT);
242 else
243 ch = 0;
244 } else if (iflag & IGNPAR)
245 continue;
246 if (iflag & PARMRK) {
247 queue->buf[head++] = 0xff;
248 head &= TTY_BUF_SIZE-1;
249 queue->buf[head++] = 0;
250 head &= TTY_BUF_SIZE-1;
251 } else
252 ch = 0;
253 } else if ((iflag & PARMRK) && (ch == 0xff)) {
254 queue->buf[head++] = 0xff;
255 head &= TTY_BUF_SIZE-1;
256 }
257 queue->buf[head++] = ch;
258 head &= TTY_BUF_SIZE-1;
259 } while ((status = inb_p(UART_LSR + info->port)) &
260 UART_LSR_DR);
261 queue->head = head;
262 if ((VLEFT < RQ_THRESHOLD_LW)
263 && !set_bit(TTY_RQ_THROTTLED, &info->tty->flags))
264 rs_throttle(info->tty, TTY_THROTTLE_RQ_FULL);
265 rs_sched_event(line, info, RS_EVENT_READ_PROCESS);
266 }
267 if ((status & UART_LSR_THRE) &&
268 !info->tty->stopped) {
269 queue = &info->tty->write_q;
270 head = queue->head;
271 tail = queue->tail;
272 if (head==tail && !info->x_char)
273 goto no_xmit;
274 if (info->x_char) {
275 outb_p(info->x_char, UART_TX + info->port);
276 info->x_char = 0;
277 } else {
278 count = info->xmit_fifo_size;
279 while (count--) {
280 if (tail == head)
281 break;
282 outb_p(queue->buf[tail++],
283 UART_TX + info->port);
284 tail &= TTY_BUF_SIZE-1;
285 }
286 }
287 queue->tail = tail;
288 if (VLEFT > WAKEUP_CHARS)
289 rs_sched_event(line, info,
290 RS_EVENT_WRITE_WAKEUP);
291 info->timer = jiffies + info->timeout;
292 if (info->timer < timer_table[RS_TIMER].expires)
293 timer_table[RS_TIMER].expires = info->timer;
294 #ifdef i386
295 rs_write_active |= 1 << line;
296 #else
297 set_bit(line, &rs_write_active);
298 #endif
299 timer_active |= 1 << RS_TIMER;
300 }
301 no_xmit:
302 status = inb(UART_MSR + info->port);
303
304 if (!(cflag & CLOCAL) && (status & UART_MSR_DDCD)) {
305 if (!(status & UART_MSR_DCD))
306 rs_sched_event(line, info, RS_EVENT_HUP_PGRP);
307 }
308
309
310
311
312
313 if (cflag & CRTSCTS) {
314 if (info->tty->stopped) {
315 if (status & UART_MSR_CTS) {
316 info->tty->stopped = 0;
317 goto restart;
318 }
319 } else
320 info->tty->stopped = !(status & UART_MSR_CTS);
321 }
322 } while (!(inb_p(UART_IIR + info->port) & UART_IIR_NO_INT));
323 }
324 #else
325
326
327
328
329
330
331
332
333
334
335 static void send_intr(struct async_struct * info)
336 {
337 unsigned short port = info->port;
338 int line = info->line;
339 struct tty_queue * queue = &info->tty->write_q;
340 int c, count = 0;
341
342 if (info->tty->stopped)
343 return;
344
345 if (info->type == PORT_16550A)
346 count = 16;
347 else
348 count = 1;
349
350 rs_write_active &= ~(1 << line);
351
352 if (inb_p(UART_LSR + info->port) & UART_LSR_THRE) {
353 while (count-- && !info->tty->stopped) {
354 if (queue->tail == queue->head)
355 goto end_send;
356 c = queue->buf[queue->tail];
357 queue->tail++;
358 queue->tail &= TTY_BUF_SIZE-1;
359 outb(c, UART_TX + port);
360 }
361 }
362 info->timer = jiffies + info->timeout;
363 if (info->timer < timer_table[RS_TIMER].expires)
364 timer_table[RS_TIMER].expires = info->timer;
365 rs_write_active |= 1 << line;
366 timer_active |= 1 << RS_TIMER;
367 end_send:
368 if (LEFT(queue) > WAKEUP_CHARS)
369 wake_up(&queue->proc_list);
370 }
371
372 static void receive_intr(struct async_struct * info)
373 {
374 unsigned short port = info->port;
375 struct tty_queue * queue = &info->tty->read_q;
376 int head = queue->head;
377 int maxhead = (queue->tail-1) & (TTY_BUF_SIZE-1);
378 int count = 0;
379
380 do {
381 count++;
382 queue->buf[head] = inb(UART_TX + port);
383 if (head != maxhead) {
384 head++;
385 head &= TTY_BUF_SIZE-1;
386 }
387 } while (inb(UART_LSR + port) & UART_LSR_DR);
388 queue->head = head;
389 rs_sched_event(info->line, info, RS_EVENT_READ_PROCESS);
390 }
391
392 static void line_status_intr(struct async_struct * info)
393 {
394 unsigned char status = inb(UART_LSR + info->port);
395
396
397 }
398
399 static void modem_status_intr(struct async_struct * info)
400 {
401 unsigned char status = inb(UART_MSR + info->port);
402
403 if (!(info->tty->termios->c_cflag & CLOCAL)) {
404 if ((status & (UART_MSR_DCD|UART_MSR_DDCD)) == UART_MSR_DDCD)
405 tty_hangup(info->tty);
406
407 if (info->tty->termios->c_cflag & CRTSCTS)
408 info->tty->stopped = !(status & UART_MSR_CTS);
409
410 if (!info->tty->stopped)
411 send_intr(info);
412 }
413 }
414
415 static void (*jmp_table[4])(struct async_struct *) = {
416 modem_status_intr,
417 send_intr,
418 receive_intr,
419 line_status_intr
420 };
421
422
423
424
425
426
427
428 static void UART_ISR_proc(async_ISR ISR, int line)
429 {
430 unsigned char ident;
431 struct async_struct * info = rs_table + line;
432
433 if (!info || !info->tty || !info->port)
434 return;
435 while (1) {
436 ident = inb(UART_IIR + info->port) & 7;
437 if (ident & 1)
438 return;
439 ident = ident >> 1;
440 jmp_table[ident](info);
441 }
442 }
443 #endif
444
445 #ifdef CONFIG_AST_FOURPORT
446
447
448
449 static void FourPort_ISR_proc(async_ISR ISR, int line)
450 {
451 int i;
452 unsigned char ivec;
453
454 ivec = ~inb(ISR->port) & 0x0F;
455 do {
456 for (i = line; ivec; i++) {
457 if (ivec & 1)
458 UART_ISR_proc(ISR, i);
459 ivec = ivec >> 1;
460 }
461 ivec = ~inb(ISR->port) & 0x0F;
462 } while (ivec);
463 }
464 #endif
465
466
467
468
469 static void rs_interrupt(int irq)
470 {
471 async_ISR p = IRQ_ISR[irq];
472
473 while (p) {
474 (p->ISR_proc)(p, p->line);
475 p = p->next_ISR;
476 }
477 }
478
479 #ifdef CONFIG_AUTO_IRQ
480
481
482
483
484 static volatile int rs_irq_triggered;
485 static volatile int rs_triggered;
486
487 static void rs_probe(int irq)
488 {
489 rs_irq_triggered = irq;
490 rs_triggered |= 1 << irq;
491 return;
492 }
493 #endif
494
495
496
497
498
499
500 #define END_OF_TIME 0xffffffff
501 static void rs_timer(void)
502 {
503 unsigned long mask;
504 struct async_struct *info;
505 unsigned long next_timeout;
506
507 info = rs_table;
508 next_timeout = END_OF_TIME;
509 for (mask = 1 ; mask ; info++, mask <<= 1) {
510 if ((mask > rs_event) &&
511 (mask > rs_write_active))
512 break;
513 if (!info->tty) {
514 rs_event &= ~mask;
515 rs_write_active &= ~mask;
516 continue;
517 }
518 if (mask & rs_event) {
519 if (!clear_bit(RS_EVENT_READ_PROCESS, &info->event)) {
520 TTY_READ_FLUSH(info->tty);
521 }
522 if (!clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
523 wake_up_interruptible(&info->tty->write_q.proc_list);
524 }
525 if (!clear_bit(RS_EVENT_HUP_PGRP, &info->event))
526 tty_hangup(info->tty);
527 if (!clear_bit(RS_EVENT_BREAK_INT, &info->event)) {
528 flush_input(info->tty);
529 flush_output(info->tty);
530 if (info->tty->pgrp > 0)
531 kill_pg(info->tty->pgrp,SIGINT,1);
532 }
533 if (!clear_bit(RS_EVENT_DO_SAK, &info->event)) {
534 do_SAK(info->tty);
535 }
536 cli();
537 if (info->event)
538 next_timeout = 0;
539 else
540 rs_event &= ~mask;
541 sti();
542 }
543 if (mask & rs_write_active) {
544 if (info->timer <= jiffies) {
545 #ifdef i386
546 rs_write_active &= ~mask;
547 #else
548 clear_bit(info->line, &rs_write_active);
549 #endif
550 rs_write(info->tty);
551 }
552 if ((mask & rs_write_active) &&
553 (info->timer < next_timeout))
554 next_timeout = info->timer;
555 }
556 }
557 if (next_timeout != END_OF_TIME) {
558 timer_table[RS_TIMER].expires = next_timeout;
559 #ifdef i386
560
561
562
563
564
565 timer_active |= 1 << RS_TIMER;
566 #else
567 set_bit(RS_TIMER, &timer_active);
568 #endif
569 }
570 }
571
572
573
574
575
576
577 void rs_write(struct tty_struct * tty)
578 {
579 struct async_struct *info;
580
581 if (!tty || tty->stopped || EMPTY(&tty->write_q))
582 return;
583 info = rs_table + DEV_TO_SL(tty->line);
584 if (!test_bit(info->line, &rs_write_active)) {
585 cli();
586 #ifdef NEW_INTERRUPT_ROUTINE
587 UART_ISR_proc(info->ISR, info->line);
588 #else
589 send_intr(info);
590 #endif
591 sti();
592 }
593
594 }
595
596 static void rs_throttle(struct tty_struct * tty, int status)
597 {
598 struct async_struct *info;
599 unsigned char mcr;
600
601 #ifdef notdef
602 printk("throttle tty%d: %d (%d, %d)....\n", DEV_TO_SL(tty->line),
603 status, LEFT(&tty->read_q), LEFT(&tty->secondary));
604 #endif
605 switch (status) {
606 case TTY_THROTTLE_RQ_FULL:
607 info = rs_table + DEV_TO_SL(tty->line);
608 if (tty->termios->c_iflag & IXOFF) {
609 info->x_char = STOP_CHAR(tty);
610 } else {
611 mcr = inb_p(UART_MCR + info->port);
612 mcr &= ~UART_MCR_RTS;
613 outb(mcr, UART_MCR + info->port);
614 }
615 break;
616 case TTY_THROTTLE_RQ_AVAIL:
617 info = rs_table + DEV_TO_SL(tty->line);
618 if (tty->termios->c_iflag & IXOFF) {
619 cli();
620 if (info->x_char)
621 info->x_char = 0;
622 else
623 info->x_char = START_CHAR(tty);
624 sti();
625 } else {
626 mcr = inb(UART_MCR + info->port);
627 mcr |= UART_MCR_RTS;
628 outb_p(mcr, UART_MCR + info->port);
629 }
630 break;
631 }
632 }
633
634
635
636
637
638
639
640 static void rs_close(struct tty_struct *tty, struct file * filp)
641 {
642 struct async_struct * info;
643 async_ISR ISR;
644 int irq, line;
645
646 line = DEV_TO_SL(tty->line);
647 if ((line < 0) || (line >= NR_PORTS))
648 return;
649 tty->stopped = 0;
650 wait_until_sent(tty);
651 info = rs_table + line;
652 if (!info->port)
653 return;
654 shutdown(info);
655 #ifdef i386
656 rs_write_active &= ~(1 << line);
657 rs_event &= ~(1 << line);
658 #else
659 clear_bit(line, &rs_write_active);
660 clear_bit(line, &rs_event);
661 #endif
662 info->event = 0;
663 info->tty = 0;
664 ISR = info->ISR;
665 irq = ISR->irq;
666 if (irq == 2)
667 irq = 9;
668 if (--ISR->refcnt == 0) {
669 if (ISR->next_ISR)
670 ISR->next_ISR->prev_ISR = ISR->prev_ISR;
671 if (ISR->prev_ISR)
672 ISR->prev_ISR->next_ISR = ISR->next_ISR;
673 else
674 IRQ_ISR[irq] = ISR->next_ISR;
675 if (!IRQ_ISR[irq])
676 free_irq(irq);
677 }
678 }
679
680 static void startup(struct async_struct * info)
681 {
682 unsigned short port = info->port;
683 unsigned short ICP;
684
685
686
687
688 if (info->type == PORT_16550A)
689 outb_p(UART_FCR_CLEAR_CMD, UART_FCR + port);
690
691
692
693
694 (void)inb_p(UART_LSR + port);
695 (void)inb_p(UART_RX + port);
696 (void)inb_p(UART_IIR + port);
697 (void)inb_p(UART_MSR + port);
698
699
700
701
702 outb_p(UART_LCR_WLEN8, UART_LCR + port);
703 if (info->flags & ASYNC_FOURPORT)
704 outb_p(UART_MCR_DTR | UART_MCR_RTS,
705 UART_MCR + port);
706 else
707 outb_p(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2,
708 UART_MCR + port);
709
710
711
712
713 if (info->type == PORT_16550A) {
714 outb_p(UART_FCR_SETUP_CMD, UART_FCR + port);
715 info->xmit_fifo_size = 16;
716 } else {
717 info->xmit_fifo_size = 1;
718 }
719
720
721
722
723 outb_p(0x0f,UART_IER + port);
724 if (info->flags & ASYNC_FOURPORT) {
725
726 ICP = (port & 0xFE0) | 0x01F;
727 outb_p(0x80, ICP);
728 (void) inb(ICP);
729 }
730
731
732
733
734 (void)inb_p(UART_LSR + port);
735 (void)inb_p(UART_RX + port);
736 (void)inb_p(UART_IIR + port);
737 (void)inb_p(UART_MSR + port);
738 }
739
740 static void shutdown(struct async_struct * info)
741 {
742 unsigned short port = info->port;
743
744 outb_p(0x00, UART_IER + port);
745 if (info->tty && !(info->tty->termios->c_cflag & HUPCL))
746 outb_p(UART_MCR_DTR, UART_MCR + port);
747 else
748
749 outb_p(0x00, UART_MCR + port);
750 outb_p(UART_FCR_CLEAR_CMD, UART_FCR + info->port);
751 (void)inb(UART_RX + port);
752 }
753
754 void change_speed(unsigned int line)
755 {
756 struct async_struct * info;
757 unsigned short port;
758 int quot = 0;
759 unsigned cflag,cval,mcr;
760 int i;
761
762 if (line >= NR_PORTS)
763 return;
764 info = rs_table + line;
765 if (!info->tty || !info->tty->termios)
766 return;
767 cflag = info->tty->termios->c_cflag;
768 if (!(port = info->port))
769 return;
770 i = cflag & CBAUD;
771 if (i == 15) {
772 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
773 i += 1;
774 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
775 i += 2;
776 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
777 quot = info->custom_divisor;
778 }
779 if (quot) {
780 info->timeout = ((info->xmit_fifo_size*HZ*15*quot) /
781 info->baud_base) + 2;
782 } else if (baud_table[i] == 134) {
783 quot = (2*info->baud_base / 269);
784 info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
785 } else if (baud_table[i]) {
786 quot = info->baud_base / baud_table[i];
787 info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
788 } else {
789 quot = 0;
790 info->timeout = 0;
791 }
792 mcr = inb(UART_MCR + port);
793 if (quot)
794 outb(mcr | UART_MCR_DTR, UART_MCR + port);
795 else {
796 outb(mcr & ~UART_MCR_DTR, UART_MCR + port);
797 return;
798 }
799
800 cval = cflag & (CSIZE | CSTOPB);
801 cval >>= 4;
802 if (cflag & PARENB)
803 cval |= 8;
804 if (!(cflag & PARODD))
805 cval |= 16;
806 cli();
807 outb_p(cval | UART_LCR_DLAB, UART_LCR + port);
808 outb_p(quot & 0xff, UART_DLL + port);
809 outb_p(quot >> 8, UART_DLM + port);
810 outb(cval, UART_LCR + port);
811 sti();
812 }
813
814 static int get_serial_info(struct async_struct * info,
815 struct serial_struct * retinfo)
816 {
817 struct serial_struct tmp;
818
819 if (!retinfo)
820 return -EFAULT;
821 tmp.type = info->type;
822 tmp.line = info->line;
823 tmp.port = info->port;
824 tmp.irq = info->ISR->irq;
825
826 memcpy_tofs(retinfo,&tmp,sizeof(*retinfo));
827 return 0;
828 }
829
830 static int set_serial_info(struct async_struct * info,
831 struct serial_struct * new_info)
832 {
833 struct serial_struct tmp;
834 async_ISR ISR;
835 unsigned int new_port;
836 unsigned int irq,new_irq;
837 int retval;
838 struct sigaction sa;
839
840 if (!suser())
841 return -EPERM;
842 if (!new_info)
843 return -EFAULT;
844 memcpy_fromfs(&tmp,new_info,sizeof(tmp));
845
846 info->flags = tmp.flags & ASYNC_FLAGS;
847
848 if ( (tmp.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
849 info->custom_divisor = tmp.custom_divisor;
850
851 if ((tmp.type >= PORT_UNKNOWN) && (tmp.type <= PORT_MAX))
852 info->type = tmp.type;
853
854 new_port = tmp.port;
855 new_irq = tmp.irq;
856 if (new_irq > 15 || new_port > 0xffff)
857 return -EINVAL;
858 if (new_irq == 2)
859 new_irq = 9;
860 ISR = info->ISR;
861 irq = ISR->irq;
862 if (irq == 2)
863 irq = 9;
864 if (irq != new_irq) {
865
866
867
868
869
870 if (!IRQ_ISR[new_irq]) {
871 sa.sa_handler = rs_interrupt;
872 sa.sa_flags = (SA_INTERRUPT);
873 sa.sa_mask = 0;
874 sa.sa_restorer = NULL;
875 retval = irqaction(new_irq,&sa);
876 if (retval)
877 return retval;
878 }
879
880
881
882
883
884 if (ISR->next_ISR)
885 ISR->next_ISR->prev_ISR = ISR->prev_ISR;
886 if (ISR->prev_ISR)
887 ISR->prev_ISR->next_ISR = ISR->next_ISR;
888 else
889 IRQ_ISR[irq] = ISR->next_ISR;
890 if (!IRQ_ISR[irq])
891 free_irq(irq);
892
893
894
895
896 ISR->prev_ISR = 0;
897 ISR->next_ISR = IRQ_ISR[new_irq];
898 if (ISR->next_ISR)
899 ISR->next_ISR->prev_ISR = ISR;
900 IRQ_ISR[new_irq] = ISR;
901 ISR->irq = new_irq;
902 }
903 cli();
904 if (new_port != info->port) {
905 shutdown(info);
906 info->port = new_port;
907 startup(info);
908 change_speed(info->line);
909 }
910 sti();
911 return 0;
912 }
913
914 static int get_modem_info(struct async_struct * info, unsigned int *value)
915 {
916 unsigned port;
917 unsigned char control, status;
918 unsigned int result;
919
920 port = info->port;
921 control = inb(UART_MCR + port);
922 status = inb(UART_MSR + port);
923 result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
924 | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
925 | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)
926 | ((status & UART_MSR_RI) ? TIOCM_RNG : 0)
927 | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0)
928 | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
929 put_fs_long(result,(unsigned long *) value);
930 return 0;
931 }
932
933 static int set_modem_info(struct async_struct * info, unsigned int cmd,
934 unsigned int *value)
935 {
936 unsigned port;
937 unsigned char control;
938 unsigned int arg = get_fs_long((unsigned long *) value);
939
940 port = info->port;
941 control = inb(UART_MCR + port);
942
943 switch (cmd) {
944 case TIOCMBIS:
945 if (arg & TIOCM_RTS)
946 control |= UART_MCR_RTS;
947 if (arg & TIOCM_DTR)
948 control |= UART_MCR_DTR;
949 break;
950 case TIOCMBIC:
951 if (arg & TIOCM_RTS)
952 control &= ~UART_MCR_RTS;
953 if (arg & TIOCM_DTR)
954 control &= ~UART_MCR_DTR;
955 break;
956 case TIOCMSET:
957 control = (control & ~0x03)
958 | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
959 | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0);
960 break;
961 default:
962 return -EINVAL;
963 }
964 outb(control, UART_MCR + port);
965 return 0;
966 }
967
968 static int rs_ioctl(struct tty_struct *tty, struct file * file,
969 unsigned int cmd, unsigned int arg)
970 {
971 int line;
972 struct async_struct * info;
973
974 line = DEV_TO_SL(tty->line);
975 if (line < 0 || line >= NR_PORTS)
976 return -ENODEV;
977 info = rs_table + line;
978
979 switch (cmd) {
980 case TCSBRK:
981 wait_until_sent(tty);
982 if (!arg)
983 send_break(info);
984 return 0;
985 case TIOCMGET:
986 verify_area((void *) arg,sizeof(unsigned int *));
987 return get_modem_info(info, (unsigned int *) arg);
988 case TIOCMBIS:
989 case TIOCMBIC:
990 case TIOCMSET:
991 return set_modem_info(info, cmd, (unsigned int *) arg);
992 case TIOCGSERIAL:
993 verify_area((void *) arg,sizeof(struct serial_struct));
994 return get_serial_info(info,
995 (struct serial_struct *) arg);
996 case TIOCSSERIAL:
997 return set_serial_info(info,
998 (struct serial_struct *) arg);
999
1000 default:
1001 return -EINVAL;
1002 }
1003 return 0;
1004 }
1005
1006
1007
1008
1009
1010
1011
1012 int rs_open(struct tty_struct *tty, struct file * filp)
1013 {
1014 struct async_struct *info;
1015 async_ISR ISR;
1016 int irq, retval, line;
1017 struct sigaction sa;
1018
1019 if (!tty)
1020 return -ENODEV;
1021 if (tty->count > 1)
1022 return 0;
1023 line = DEV_TO_SL(tty->line);
1024 if ((line < 0) || (line >= NR_PORTS))
1025 return -ENODEV;
1026 info = rs_table + line;
1027 if (!info->port || !info->ISR->irq)
1028 return -ENODEV;
1029 info->tty = tty;
1030 tty->write = rs_write;
1031 tty->close = rs_close;
1032 tty->ioctl = rs_ioctl;
1033 tty->throttle = rs_throttle;
1034 ISR = info->ISR;
1035 irq = ISR->irq;
1036 if (irq == 2)
1037 irq = 9;
1038 if (!IRQ_ISR[irq]) {
1039 sa.sa_handler = rs_interrupt;
1040 sa.sa_flags = (SA_INTERRUPT);
1041 sa.sa_mask = 0;
1042 sa.sa_restorer = NULL;
1043 retval = irqaction(irq,&sa);
1044 if (retval)
1045 return retval;
1046 }
1047 if (!ISR->refcnt++) {
1048
1049
1050
1051
1052 ISR->prev_ISR = 0;
1053 ISR->next_ISR = IRQ_ISR[irq];
1054 if (ISR->next_ISR)
1055 ISR->next_ISR->prev_ISR = ISR;
1056 IRQ_ISR[irq] = ISR;
1057 }
1058 startup(info);
1059 change_speed(info->line);
1060 return 0;
1061 }
1062
1063 static void show_serial_version()
1064 {
1065 printk("Serial driver version 3.1 with");
1066 #ifdef CONFIG_AST_FOURPORT
1067 printk(" AST_FOURPORT");
1068 #define SERIAL_OPT
1069 #endif
1070 #ifdef CONFIG_ACCENT_ASYNC
1071 printk(" ACCENT_ASYNC");
1072 #define SERIAL_OPT
1073 #endif
1074 #ifdef CONFIG_AUTO_IRQ
1075 printk (" AUTO_IRQ");
1076 #define SERIAL_OPT
1077 #endif
1078 #ifdef NEW_INTERRUPT_ROUTINE
1079 printk(" NEW_INTERRUPT_ROUTINE");
1080 #define SERIAL_OPT
1081 #endif
1082 #ifdef SERIAL_OPT
1083 printk(" enabled\n");
1084 #else
1085 printk(" no serial options enabled\n");
1086 #endif
1087 #undef SERIAL_OPT
1088 }
1089
1090
1091 static void init(struct async_struct * info)
1092 {
1093 #ifdef CONFIG_AUTO_IRQ
1094 unsigned char status1, status2, scratch, save_ICP=0;
1095 unsigned short ICP=0, port = info->port;
1096 unsigned long timeout;
1097
1098
1099
1100
1101 rs_irq_triggered = 0;
1102 scratch = inb_p(UART_IER + port);
1103 status1 = inb_p(UART_MCR + port);
1104 if (info->flags & ASYNC_FOURPORT) {
1105 outb_p(UART_MCR_DTR | UART_MCR_RTS, UART_MCR + port);
1106 outb_p(0x0f,UART_IER + port);
1107 ICP = (port & 0xFE0) | 0x01F;
1108 save_ICP = inb_p(ICP);
1109 outb_p(0x80, ICP);
1110 (void) inb(ICP);
1111 } else {
1112 outb_p(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2,
1113 UART_MCR + port);
1114 outb_p(0x0f,UART_IER + port);
1115 }
1116
1117
1118
1119 (void)inb_p(UART_LSR + port);
1120 (void)inb_p(UART_RX + port);
1121 (void)inb_p(UART_IIR + port);
1122 (void)inb_p(UART_MSR + port);
1123 timeout = jiffies+2;
1124 while (timeout >= jiffies) {
1125 if (rs_irq_triggered)
1126 break;
1127 }
1128
1129
1130
1131 if (rs_irq_triggered) {
1132 outb_p(0, UART_IER + port);
1133 info->ISR->irq = rs_irq_triggered;
1134 } else {
1135 outb_p(scratch, UART_IER + port);
1136 outb_p(status1, UART_MCR + port);
1137 if (info->flags & ASYNC_FOURPORT)
1138 outb_p(save_ICP, ICP);
1139 info->type = PORT_UNKNOWN;
1140 return;
1141 }
1142 #else
1143 unsigned char status1, status2, scratch, scratch2;
1144 unsigned short port = info->port;
1145
1146
1147
1148
1149 scratch = inb_p(UART_MCR + port);
1150 outb_p(UART_MCR_LOOP | scratch, UART_MCR + port);
1151 scratch2 = inb_p(UART_MSR + port);
1152 outb_p(UART_MCR_LOOP | 0x0A, UART_MCR + port);
1153 status1 = inb_p(UART_MSR + port) & 0xF0;
1154 outb_p(scratch, UART_MCR + port);
1155 outb_p(scratch2, UART_MSR + port);
1156 if (status1 != 0x90) {
1157 info->type = PORT_UNKNOWN;
1158 return;
1159 }
1160 #endif
1161
1162 if (!(info->flags & ASYNC_NOSCRATCH)) {
1163 scratch = inb(UART_SCR + port);
1164 outb_p(0xa5, UART_SCR + port);
1165 status1 = inb(UART_SCR + port);
1166 outb_p(0x5a, UART_SCR + port);
1167 status2 = inb(UART_SCR + port);
1168 outb_p(scratch, UART_SCR + port);
1169 } else {
1170 status1 = 0xa5;
1171 status2 = 0x5a;
1172 }
1173 if (status1 == 0xa5 && status2 == 0x5a) {
1174 outb_p(UART_FCR_ENABLE_FIFO, UART_FCR + port);
1175 scratch = inb(UART_IIR + port) >> 6;
1176 info->xmit_fifo_size = 1;
1177 switch (scratch) {
1178 case 0:
1179 info->type = PORT_16450;
1180 break;
1181 case 1:
1182 info->type = PORT_UNKNOWN;
1183 break;
1184 case 2:
1185 info->type = PORT_16550;
1186 break;
1187 case 3:
1188 info->type = PORT_16550A;
1189 info->xmit_fifo_size = 16;
1190 break;
1191 }
1192 } else
1193 info->type = PORT_8250;
1194 shutdown(info);
1195 }
1196
1197 long rs_init(long kmem_start)
1198 {
1199 int i;
1200 struct async_struct * info;
1201 #ifdef CONFIG_AUTO_IRQ
1202 int irq_lines = 0;
1203 struct sigaction sa;
1204 unsigned long timeout;
1205
1206
1207
1208
1209 sti();
1210
1211 rs_triggered = 0;
1212 sa.sa_handler = rs_probe;
1213 sa.sa_flags = (SA_INTERRUPT);
1214 sa.sa_mask = 0;
1215 sa.sa_restorer = NULL;
1216 #endif
1217 timer_table[RS_TIMER].fn = rs_timer;
1218 timer_table[RS_TIMER].expires = 0;
1219
1220 for (i = 0; i < 16; i++) {
1221 IRQ_ISR[i] = 0;
1222 #ifdef CONFIG_AUTO_IRQ
1223 if (!irqaction(i, &sa))
1224 irq_lines |= 1 << i;
1225 #endif
1226 }
1227 #ifdef CONFIG_AUTO_IRQ
1228 timeout = jiffies+5;
1229 while (timeout >= jiffies)
1230 ;
1231 for (i = 0; i < 16; i++) {
1232 if ((rs_triggered & (1 << i)) &&
1233 (irq_lines & (1 << i))) {
1234 irq_lines &= ~(1 << i);
1235 printk("Wild interrupt? (IRQ %d)\n", i);
1236 free_irq(i);
1237 }
1238 }
1239 #endif
1240 show_serial_version();
1241 for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
1242 if (!info->port)
1243 continue;
1244 info->line = i;
1245 info->tty = 0;
1246 info->type = PORT_UNKNOWN;
1247 info->timer = 0;
1248 info->custom_divisor = 0;
1249 info->x_char = 0;
1250 info->event = 0;
1251 if (!info->ISR->line) {
1252 info->ISR->line = i;
1253 info->ISR->refcnt = 0;
1254 info->ISR->next_ISR = 0;
1255 info->ISR->prev_ISR = 0;
1256 }
1257 init(info);
1258 if (info->type == PORT_UNKNOWN)
1259 continue;
1260 printk("ttys%d%s at 0x%04x (irq = %d)", info->line,
1261 (info->flags & ASYNC_FOURPORT) ? " FourPort" : "",
1262 info->port, info->ISR->irq);
1263 switch (info->type) {
1264 case PORT_8250:
1265 printk(" is a 8250\n");
1266 break;
1267 case PORT_16450:
1268 printk(" is a 16450\n");
1269 break;
1270 case PORT_16550:
1271 printk(" is a 16550\n");
1272 break;
1273 case PORT_16550A:
1274 printk(" is a 16550A\n");
1275 break;
1276 default:
1277 printk("\n");
1278 break;
1279 }
1280 }
1281 #ifdef CONFIG_AUTO_IRQ
1282
1283
1284
1285
1286 cli();
1287 for (i = 0; i < 16; i++) {
1288 if (irq_lines & (1 << i))
1289 free_irq(i);
1290 }
1291 #endif
1292 return kmem_start;
1293 }
1294