1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#include <linux/types.h>
34#include <linux/major.h>
35#include <linux/errno.h>
36#include <linux/signal.h>
37#include <linux/fcntl.h>
38#include <linux/sched.h>
39#include <linux/interrupt.h>
40#include <linux/tty.h>
41#include <linux/timer.h>
42#include <linux/ctype.h>
43#include <linux/kd.h>
44#include <linux/mm.h>
45#include <linux/string.h>
46#include <linux/slab.h>
47#include <linux/poll.h>
48
49#include <asm/uaccess.h>
50#include <asm/system.h>
51#include <asm/bitops.h>
52
53#define CONSOLE_DEV MKDEV(TTY_MAJOR,0)
54#define SYSCONS_DEV MKDEV(TTYAUX_MAJOR,1)
55
56#ifndef MIN
57#define MIN(a,b) ((a) < (b) ? (a) : (b))
58#endif
59
60
61#define WAKEUP_CHARS 256
62
63
64
65
66
67
68#define TTY_THRESHOLD_THROTTLE 128
69#define TTY_THRESHOLD_UNTHROTTLE 128
70
71static inline unsigned char *alloc_buf(void)
72{
73 unsigned char *p;
74 int prio = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
75
76 if (PAGE_SIZE != N_TTY_BUF_SIZE) {
77 p = kmalloc(N_TTY_BUF_SIZE, prio);
78 if (p)
79 memset(p, 0, N_TTY_BUF_SIZE);
80 } else
81 p = (unsigned char *)get_zeroed_page(prio);
82
83 return p;
84}
85
86static inline void free_buf(unsigned char *buf)
87{
88 if (PAGE_SIZE != N_TTY_BUF_SIZE)
89 kfree(buf);
90 else
91 free_page((unsigned long) buf);
92}
93
94static inline void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
95{
96 if (tty->read_cnt < N_TTY_BUF_SIZE) {
97 tty->read_buf[tty->read_head] = c;
98 tty->read_head = (tty->read_head + 1) & (N_TTY_BUF_SIZE-1);
99 tty->read_cnt++;
100 }
101}
102
103static inline void put_tty_queue(unsigned char c, struct tty_struct *tty)
104{
105 unsigned long flags;
106
107
108
109
110 spin_lock_irqsave(&tty->read_lock, flags);
111 put_tty_queue_nolock(c, tty);
112 spin_unlock_irqrestore(&tty->read_lock, flags);
113}
114
115
116
117
118
119
120static void check_unthrottle(struct tty_struct * tty)
121{
122 if (tty->count &&
123 test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
124 tty->driver.unthrottle)
125 tty->driver.unthrottle(tty);
126}
127
128
129
130
131
132
133static void reset_buffer_flags(struct tty_struct *tty)
134{
135 unsigned long flags;
136
137 spin_lock_irqsave(&tty->read_lock, flags);
138 tty->read_head = tty->read_tail = tty->read_cnt = 0;
139 spin_unlock_irqrestore(&tty->read_lock, flags);
140 tty->canon_head = tty->canon_data = tty->erasing = 0;
141 memset(&tty->read_flags, 0, sizeof tty->read_flags);
142 check_unthrottle(tty);
143}
144
145
146
147
148void n_tty_flush_buffer(struct tty_struct * tty)
149{
150
151 reset_buffer_flags(tty);
152
153 if (!tty->link)
154 return;
155
156 if (tty->link->packet) {
157 tty->ctrl_status |= TIOCPKT_FLUSHREAD;
158 wake_up_interruptible(&tty->link->read_wait);
159 }
160}
161
162
163
164
165ssize_t n_tty_chars_in_buffer(struct tty_struct *tty)
166{
167 unsigned long flags;
168 ssize_t n = 0;
169
170 spin_lock_irqsave(&tty->read_lock, flags);
171 if (!tty->icanon) {
172 n = tty->read_cnt;
173 } else if (tty->canon_data) {
174 n = (tty->canon_head > tty->read_tail) ?
175 tty->canon_head - tty->read_tail :
176 tty->canon_head + (N_TTY_BUF_SIZE - tty->read_tail);
177 }
178 spin_unlock_irqrestore(&tty->read_lock, flags);
179 return n;
180}
181
182
183
184
185
186static int opost(unsigned char c, struct tty_struct *tty)
187{
188 int space, spaces;
189
190 space = tty->driver.write_room(tty);
191 if (!space)
192 return -1;
193
194 if (O_OPOST(tty)) {
195 switch (c) {
196 case '\n':
197 if (O_ONLRET(tty))
198 tty->column = 0;
199 if (O_ONLCR(tty)) {
200 if (space < 2)
201 return -1;
202 tty->driver.put_char(tty, '\r');
203 tty->column = 0;
204 }
205 tty->canon_column = tty->column;
206 break;
207 case '\r':
208 if (O_ONOCR(tty) && tty->column == 0)
209 return 0;
210 if (O_OCRNL(tty)) {
211 c = '\n';
212 if (O_ONLRET(tty))
213 tty->canon_column = tty->column = 0;
214 break;
215 }
216 tty->canon_column = tty->column = 0;
217 break;
218 case '\t':
219 spaces = 8 - (tty->column & 7);
220 if (O_TABDLY(tty) == XTABS) {
221 if (space < spaces)
222 return -1;
223 tty->column += spaces;
224 tty->driver.write(tty, 0, " ", spaces);
225 return 0;
226 }
227 tty->column += spaces;
228 break;
229 case '\b':
230 if (tty->column > 0)
231 tty->column--;
232 break;
233 default:
234 if (O_OLCUC(tty))
235 c = toupper(c);
236 if (!iscntrl(c))
237 tty->column++;
238 break;
239 }
240 }
241 tty->driver.put_char(tty, c);
242 return 0;
243}
244
245
246
247
248
249static ssize_t opost_block(struct tty_struct * tty,
250 const unsigned char * inbuf, unsigned int nr)
251{
252 char buf[80];
253 int space;
254 int i;
255 char *cp;
256
257 space = tty->driver.write_room(tty);
258 if (!space)
259 return 0;
260 if (nr > space)
261 nr = space;
262 if (nr > sizeof(buf))
263 nr = sizeof(buf);
264
265 if (copy_from_user(buf, inbuf, nr))
266 return -EFAULT;
267
268 for (i = 0, cp = buf; i < nr; i++, cp++) {
269 switch (*cp) {
270 case '\n':
271 if (O_ONLRET(tty))
272 tty->column = 0;
273 if (O_ONLCR(tty))
274 goto break_out;
275 tty->canon_column = tty->column;
276 break;
277 case '\r':
278 if (O_ONOCR(tty) && tty->column == 0)
279 goto break_out;
280 if (O_OCRNL(tty)) {
281 *cp = '\n';
282 if (O_ONLRET(tty))
283 tty->canon_column = tty->column = 0;
284 break;
285 }
286 tty->canon_column = tty->column = 0;
287 break;
288 case '\t':
289 goto break_out;
290 case '\b':
291 if (tty->column > 0)
292 tty->column--;
293 break;
294 default:
295 if (O_OLCUC(tty))
296 *cp = toupper(*cp);
297 if (!iscntrl(*cp))
298 tty->column++;
299 break;
300 }
301 }
302break_out:
303 if (tty->driver.flush_chars)
304 tty->driver.flush_chars(tty);
305 i = tty->driver.write(tty, 0, buf, i);
306 return i;
307}
308
309
310
311static inline void put_char(unsigned char c, struct tty_struct *tty)
312{
313 tty->driver.put_char(tty, c);
314}
315
316
317
318static void echo_char(unsigned char c, struct tty_struct *tty)
319{
320 if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t') {
321 put_char('^', tty);
322 put_char(c ^ 0100, tty);
323 tty->column += 2;
324 } else
325 opost(c, tty);
326}
327
328static inline void finish_erasing(struct tty_struct *tty)
329{
330 if (tty->erasing) {
331 put_char('/', tty);
332 tty->column += 2;
333 tty->erasing = 0;
334 }
335}
336
337static void eraser(unsigned char c, struct tty_struct *tty)
338{
339 enum { ERASE, WERASE, KILL } kill_type;
340 int head, seen_alnums;
341 unsigned long flags;
342
343 if (tty->read_head == tty->canon_head) {
344
345 return;
346 }
347 if (c == ERASE_CHAR(tty))
348 kill_type = ERASE;
349 else if (c == WERASE_CHAR(tty))
350 kill_type = WERASE;
351 else {
352 if (!L_ECHO(tty)) {
353 spin_lock_irqsave(&tty->read_lock, flags);
354 tty->read_cnt -= ((tty->read_head - tty->canon_head) &
355 (N_TTY_BUF_SIZE - 1));
356 tty->read_head = tty->canon_head;
357 spin_unlock_irqrestore(&tty->read_lock, flags);
358 return;
359 }
360 if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) {
361 spin_lock_irqsave(&tty->read_lock, flags);
362 tty->read_cnt -= ((tty->read_head - tty->canon_head) &
363 (N_TTY_BUF_SIZE - 1));
364 tty->read_head = tty->canon_head;
365 spin_unlock_irqrestore(&tty->read_lock, flags);
366 finish_erasing(tty);
367 echo_char(KILL_CHAR(tty), tty);
368
369 if (L_ECHOK(tty))
370 opost('\n', tty);
371 return;
372 }
373 kill_type = KILL;
374 }
375
376 seen_alnums = 0;
377 while (tty->read_head != tty->canon_head) {
378 head = (tty->read_head - 1) & (N_TTY_BUF_SIZE-1);
379 c = tty->read_buf[head];
380 if (kill_type == WERASE) {
381
382 if (isalnum(c) || c == '_')
383 seen_alnums++;
384 else if (seen_alnums)
385 break;
386 }
387 spin_lock_irqsave(&tty->read_lock, flags);
388 tty->read_head = head;
389 tty->read_cnt--;
390 spin_unlock_irqrestore(&tty->read_lock, flags);
391 if (L_ECHO(tty)) {
392 if (L_ECHOPRT(tty)) {
393 if (!tty->erasing) {
394 put_char('\\', tty);
395 tty->column++;
396 tty->erasing = 1;
397 }
398 echo_char(c, tty);
399 } else if (kill_type == ERASE && !L_ECHOE(tty)) {
400 echo_char(ERASE_CHAR(tty), tty);
401 } else if (c == '\t') {
402 unsigned int col = tty->canon_column;
403 unsigned long tail = tty->canon_head;
404
405
406 while (tail != tty->read_head) {
407 c = tty->read_buf[tail];
408 if (c == '\t')
409 col = (col | 7) + 1;
410 else if (iscntrl(c)) {
411 if (L_ECHOCTL(tty))
412 col += 2;
413 } else
414 col++;
415 tail = (tail+1) & (N_TTY_BUF_SIZE-1);
416 }
417
418
419 if (tty->column > 0x80000000)
420 tty->column = 0;
421
422
423 while (tty->column > col) {
424
425 put_char('\b', tty);
426 if (tty->column > 0)
427 tty->column--;
428 }
429 } else {
430 if (iscntrl(c) && L_ECHOCTL(tty)) {
431 put_char('\b', tty);
432 put_char(' ', tty);
433 put_char('\b', tty);
434 if (tty->column > 0)
435 tty->column--;
436 }
437 if (!iscntrl(c) || L_ECHOCTL(tty)) {
438 put_char('\b', tty);
439 put_char(' ', tty);
440 put_char('\b', tty);
441 if (tty->column > 0)
442 tty->column--;
443 }
444 }
445 }
446 if (kill_type == ERASE)
447 break;
448 }
449 if (tty->read_head == tty->canon_head)
450 finish_erasing(tty);
451}
452
453static inline void isig(int sig, struct tty_struct *tty, int flush)
454{
455 if (tty->pgrp > 0)
456 kill_pg(tty->pgrp, sig, 1);
457 if (flush || !L_NOFLSH(tty)) {
458 n_tty_flush_buffer(tty);
459 if (tty->driver.flush_buffer)
460 tty->driver.flush_buffer(tty);
461 }
462}
463
464static inline void n_tty_receive_break(struct tty_struct *tty)
465{
466 if (I_IGNBRK(tty))
467 return;
468 if (I_BRKINT(tty)) {
469 isig(SIGINT, tty, 1);
470 return;
471 }
472 if (I_PARMRK(tty)) {
473 put_tty_queue('\377', tty);
474 put_tty_queue('\0', tty);
475 }
476 put_tty_queue('\0', tty);
477 wake_up_interruptible(&tty->read_wait);
478}
479
480static inline void n_tty_receive_overrun(struct tty_struct *tty)
481{
482 char buf[64];
483
484 tty->num_overrun++;
485 if (time_before(tty->overrun_time, jiffies - HZ)) {
486 printk("%s: %d input overrun(s)\n", tty_name(tty, buf),
487 tty->num_overrun);
488 tty->overrun_time = jiffies;
489 tty->num_overrun = 0;
490 }
491}
492
493static inline void n_tty_receive_parity_error(struct tty_struct *tty,
494 unsigned char c)
495{
496 if (I_IGNPAR(tty)) {
497 return;
498 }
499 if (I_PARMRK(tty)) {
500 put_tty_queue('\377', tty);
501 put_tty_queue('\0', tty);
502 put_tty_queue(c, tty);
503 } else if (I_INPCK(tty))
504 put_tty_queue('\0', tty);
505 else
506 put_tty_queue(c, tty);
507 wake_up_interruptible(&tty->read_wait);
508}
509
510static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
511{
512 unsigned long flags;
513
514 if (tty->raw) {
515 put_tty_queue(c, tty);
516 return;
517 }
518
519 if (tty->stopped && !tty->flow_stopped &&
520 I_IXON(tty) && I_IXANY(tty)) {
521 start_tty(tty);
522 return;
523 }
524
525 if (I_ISTRIP(tty))
526 c &= 0x7f;
527 if (I_IUCLC(tty) && L_IEXTEN(tty))
528 c=tolower(c);
529
530 if (tty->closing) {
531 if (I_IXON(tty)) {
532 if (c == START_CHAR(tty))
533 start_tty(tty);
534 else if (c == STOP_CHAR(tty))
535 stop_tty(tty);
536 }
537 return;
538 }
539
540
541
542
543
544
545
546 if (!test_bit(c, &tty->process_char_map) || tty->lnext) {
547 finish_erasing(tty);
548 tty->lnext = 0;
549 if (L_ECHO(tty)) {
550 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
551 put_char('\a', tty);
552 return;
553 }
554
555 if (tty->canon_head == tty->read_head)
556 tty->canon_column = tty->column;
557 echo_char(c, tty);
558 }
559 if (I_PARMRK(tty) && c == (unsigned char) '\377')
560 put_tty_queue(c, tty);
561 put_tty_queue(c, tty);
562 return;
563 }
564
565 if (c == '\r') {
566 if (I_IGNCR(tty))
567 return;
568 if (I_ICRNL(tty))
569 c = '\n';
570 } else if (c == '\n' && I_INLCR(tty))
571 c = '\r';
572 if (I_IXON(tty)) {
573 if (c == START_CHAR(tty)) {
574 start_tty(tty);
575 return;
576 }
577 if (c == STOP_CHAR(tty)) {
578 stop_tty(tty);
579 return;
580 }
581 }
582 if (L_ISIG(tty)) {
583 int signal;
584 signal = SIGINT;
585 if (c == INTR_CHAR(tty))
586 goto send_signal;
587 signal = SIGQUIT;
588 if (c == QUIT_CHAR(tty))
589 goto send_signal;
590 signal = SIGTSTP;
591 if (c == SUSP_CHAR(tty)) {
592send_signal:
593 isig(signal, tty, 0);
594 return;
595 }
596 }
597 if (tty->icanon) {
598 if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) ||
599 (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) {
600 eraser(c, tty);
601 return;
602 }
603 if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) {
604 tty->lnext = 1;
605 if (L_ECHO(tty)) {
606 finish_erasing(tty);
607 if (L_ECHOCTL(tty)) {
608 put_char('^', tty);
609 put_char('\b', tty);
610 }
611 }
612 return;
613 }
614 if (c == REPRINT_CHAR(tty) && L_ECHO(tty) &&
615 L_IEXTEN(tty)) {
616 unsigned long tail = tty->canon_head;
617
618 finish_erasing(tty);
619 echo_char(c, tty);
620 opost('\n', tty);
621 while (tail != tty->read_head) {
622 echo_char(tty->read_buf[tail], tty);
623 tail = (tail+1) & (N_TTY_BUF_SIZE-1);
624 }
625 return;
626 }
627 if (c == '\n') {
628 if (L_ECHO(tty) || L_ECHONL(tty)) {
629 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
630 put_char('\a', tty);
631 return;
632 }
633 opost('\n', tty);
634 }
635 goto handle_newline;
636 }
637 if (c == EOF_CHAR(tty)) {
638 if (tty->canon_head != tty->read_head)
639 set_bit(TTY_PUSH, &tty->flags);
640 c = __DISABLED_CHAR;
641 goto handle_newline;
642 }
643 if ((c == EOL_CHAR(tty)) ||
644 (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) {
645
646
647
648 if (L_ECHO(tty)) {
649 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
650 put_char('\a', tty);
651 return;
652 }
653
654 if (tty->canon_head == tty->read_head)
655 tty->canon_column = tty->column;
656 echo_char(c, tty);
657 }
658
659
660
661
662 if (I_PARMRK(tty) && c == (unsigned char) '\377')
663 put_tty_queue(c, tty);
664
665 handle_newline:
666 spin_lock_irqsave(&tty->read_lock, flags);
667 set_bit(tty->read_head, &tty->read_flags);
668 put_tty_queue_nolock(c, tty);
669 tty->canon_head = tty->read_head;
670 tty->canon_data++;
671 spin_unlock_irqrestore(&tty->read_lock, flags);
672 kill_fasync(&tty->fasync, SIGIO, POLL_IN);
673 if (waitqueue_active(&tty->read_wait))
674 wake_up_interruptible(&tty->read_wait);
675 return;
676 }
677 }
678
679 finish_erasing(tty);
680 if (L_ECHO(tty)) {
681 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
682 put_char('\a', tty);
683 return;
684 }
685 if (c == '\n')
686 opost('\n', tty);
687 else {
688
689 if (tty->canon_head == tty->read_head)
690 tty->canon_column = tty->column;
691 echo_char(c, tty);
692 }
693 }
694
695 if (I_PARMRK(tty) && c == (unsigned char) '\377')
696 put_tty_queue(c, tty);
697
698 put_tty_queue(c, tty);
699}
700
701static int n_tty_receive_room(struct tty_struct *tty)
702{
703 int left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
704
705
706
707
708
709
710
711 if (tty->icanon && !tty->canon_data)
712 return N_TTY_BUF_SIZE;
713
714 if (left > 0)
715 return left;
716 return 0;
717}
718
719
720
721
722
723
724
725static void n_tty_write_wakeup(struct tty_struct *tty)
726{
727 if (tty->fasync)
728 {
729 set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
730 kill_fasync(&tty->fasync, SIGIO, POLL_OUT);
731 }
732 return;
733}
734
735static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
736 char *fp, int count)
737{
738 const unsigned char *p;
739 char *f, flags = TTY_NORMAL;
740 int i;
741 char buf[64];
742 unsigned long cpuflags;
743
744 if (!tty->read_buf)
745 return;
746
747 if (tty->real_raw) {
748 spin_lock_irqsave(&tty->read_lock, cpuflags);
749 i = MIN(count, MIN(N_TTY_BUF_SIZE - tty->read_cnt,
750 N_TTY_BUF_SIZE - tty->read_head));
751 memcpy(tty->read_buf + tty->read_head, cp, i);
752 tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
753 tty->read_cnt += i;
754 cp += i;
755 count -= i;
756
757 i = MIN(count, MIN(N_TTY_BUF_SIZE - tty->read_cnt,
758 N_TTY_BUF_SIZE - tty->read_head));
759 memcpy(tty->read_buf + tty->read_head, cp, i);
760 tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
761 tty->read_cnt += i;
762 spin_unlock_irqrestore(&tty->read_lock, cpuflags);
763 } else {
764 for (i=count, p = cp, f = fp; i; i--, p++) {
765 if (f)
766 flags = *f++;
767 switch (flags) {
768 case TTY_NORMAL:
769 n_tty_receive_char(tty, *p);
770 break;
771 case TTY_BREAK:
772 n_tty_receive_break(tty);
773 break;
774 case TTY_PARITY:
775 case TTY_FRAME:
776 n_tty_receive_parity_error(tty, *p);
777 break;
778 case TTY_OVERRUN:
779 n_tty_receive_overrun(tty);
780 break;
781 default:
782 printk("%s: unknown flag %d\n",
783 tty_name(tty, buf), flags);
784 break;
785 }
786 }
787 if (tty->driver.flush_chars)
788 tty->driver.flush_chars(tty);
789 }
790
791 if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) {
792 kill_fasync(&tty->fasync, SIGIO, POLL_IN);
793 if (waitqueue_active(&tty->read_wait))
794 wake_up_interruptible(&tty->read_wait);
795 }
796
797
798
799
800
801
802 if (n_tty_receive_room(tty) < TTY_THRESHOLD_THROTTLE) {
803
804 if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
805 tty->driver.throttle)
806 tty->driver.throttle(tty);
807 }
808}
809
810int is_ignored(int sig)
811{
812 return (sigismember(¤t->blocked, sig) ||
813 current->sig->action[sig-1].sa.sa_handler == SIG_IGN);
814}
815
816static void n_tty_set_termios(struct tty_struct *tty, struct termios * old)
817{
818 if (!tty)
819 return;
820
821 tty->icanon = (L_ICANON(tty) != 0);
822 if (test_bit(TTY_HW_COOK_IN, &tty->flags)) {
823 tty->raw = 1;
824 tty->real_raw = 1;
825 return;
826 }
827 if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
828 I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) ||
829 I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) ||
830 I_PARMRK(tty)) {
831 cli();
832 memset(tty->process_char_map, 0, 256/8);
833
834 if (I_IGNCR(tty) || I_ICRNL(tty))
835 set_bit('\r', &tty->process_char_map);
836 if (I_INLCR(tty))
837 set_bit('\n', &tty->process_char_map);
838
839 if (L_ICANON(tty)) {
840 set_bit(ERASE_CHAR(tty), &tty->process_char_map);
841 set_bit(KILL_CHAR(tty), &tty->process_char_map);
842 set_bit(EOF_CHAR(tty), &tty->process_char_map);
843 set_bit('\n', &tty->process_char_map);
844 set_bit(EOL_CHAR(tty), &tty->process_char_map);
845 if (L_IEXTEN(tty)) {
846 set_bit(WERASE_CHAR(tty),
847 &tty->process_char_map);
848 set_bit(LNEXT_CHAR(tty),
849 &tty->process_char_map);
850 set_bit(EOL2_CHAR(tty),
851 &tty->process_char_map);
852 if (L_ECHO(tty))
853 set_bit(REPRINT_CHAR(tty),
854 &tty->process_char_map);
855 }
856 }
857 if (I_IXON(tty)) {
858 set_bit(START_CHAR(tty), &tty->process_char_map);
859 set_bit(STOP_CHAR(tty), &tty->process_char_map);
860 }
861 if (L_ISIG(tty)) {
862 set_bit(INTR_CHAR(tty), &tty->process_char_map);
863 set_bit(QUIT_CHAR(tty), &tty->process_char_map);
864 set_bit(SUSP_CHAR(tty), &tty->process_char_map);
865 }
866 clear_bit(__DISABLED_CHAR, &tty->process_char_map);
867 sti();
868 tty->raw = 0;
869 tty->real_raw = 0;
870 } else {
871 tty->raw = 1;
872 if ((I_IGNBRK(tty) || (!I_BRKINT(tty) && !I_PARMRK(tty))) &&
873 (I_IGNPAR(tty) || !I_INPCK(tty)) &&
874 (tty->driver.flags & TTY_DRIVER_REAL_RAW))
875 tty->real_raw = 1;
876 else
877 tty->real_raw = 0;
878 }
879}
880
881static void n_tty_close(struct tty_struct *tty)
882{
883 n_tty_flush_buffer(tty);
884 if (tty->read_buf) {
885 free_buf(tty->read_buf);
886 tty->read_buf = 0;
887 }
888}
889
890static int n_tty_open(struct tty_struct *tty)
891{
892 if (!tty)
893 return -EINVAL;
894
895 if (!tty->read_buf) {
896 tty->read_buf = alloc_buf();
897 if (!tty->read_buf)
898 return -ENOMEM;
899 }
900 memset(tty->read_buf, 0, N_TTY_BUF_SIZE);
901 reset_buffer_flags(tty);
902 tty->column = 0;
903 n_tty_set_termios(tty, 0);
904 tty->minimum_to_wake = 1;
905 tty->closing = 0;
906 return 0;
907}
908
909static inline int input_available_p(struct tty_struct *tty, int amt)
910{
911 if (tty->icanon) {
912 if (tty->canon_data)
913 return 1;
914 } else if (tty->read_cnt >= (amt ? amt : 1))
915 return 1;
916
917 return 0;
918}
919
920
921
922
923
924
925
926
927
928static inline int copy_from_read_buf(struct tty_struct *tty,
929 unsigned char **b,
930 size_t *nr)
931
932{
933 int retval;
934 ssize_t n;
935 unsigned long flags;
936
937 retval = 0;
938 spin_lock_irqsave(&tty->read_lock, flags);
939 n = MIN(*nr, MIN(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail));
940 spin_unlock_irqrestore(&tty->read_lock, flags);
941 if (n) {
942 mb();
943 retval = copy_to_user(*b, &tty->read_buf[tty->read_tail], n);
944 n -= retval;
945 spin_lock_irqsave(&tty->read_lock, flags);
946 tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1);
947 tty->read_cnt -= n;
948 spin_unlock_irqrestore(&tty->read_lock, flags);
949 *b += n;
950 *nr -= n;
951 }
952 return retval;
953}
954
955static ssize_t read_chan(struct tty_struct *tty, struct file *file,
956 unsigned char *buf, size_t nr)
957{
958 unsigned char *b = buf;
959 DECLARE_WAITQUEUE(wait, current);
960 int c;
961 int minimum, time;
962 ssize_t retval = 0;
963 ssize_t size;
964 long timeout;
965 unsigned long flags;
966
967do_it_again:
968
969 if (!tty->read_buf) {
970 printk("n_tty_read_chan: called with read_buf == NULL?!?\n");
971 return -EIO;
972 }
973
974
975
976
977
978
979 if (file->f_dentry->d_inode->i_rdev != CONSOLE_DEV &&
980 file->f_dentry->d_inode->i_rdev != SYSCONS_DEV &&
981 current->tty == tty) {
982 if (tty->pgrp <= 0)
983 printk("read_chan: tty->pgrp <= 0!\n");
984 else if (current->pgrp != tty->pgrp) {
985 if (is_ignored(SIGTTIN) ||
986 is_orphaned_pgrp(current->pgrp))
987 return -EIO;
988 kill_pg(current->pgrp, SIGTTIN, 1);
989 return -ERESTARTSYS;
990 }
991 }
992
993 minimum = time = 0;
994 timeout = MAX_SCHEDULE_TIMEOUT;
995 if (!tty->icanon) {
996 time = (HZ / 10) * TIME_CHAR(tty);
997 minimum = MIN_CHAR(tty);
998 if (minimum) {
999 if (time)
1000 tty->minimum_to_wake = 1;
1001 else if (!waitqueue_active(&tty->read_wait) ||
1002 (tty->minimum_to_wake > minimum))
1003 tty->minimum_to_wake = minimum;
1004 } else {
1005 timeout = 0;
1006 if (time) {
1007 timeout = time;
1008 time = 0;
1009 }
1010 tty->minimum_to_wake = minimum = 1;
1011 }
1012 }
1013
1014 if (file->f_flags & O_NONBLOCK) {
1015 if (down_trylock(&tty->atomic_read))
1016 return -EAGAIN;
1017 }
1018 else {
1019 if (down_interruptible(&tty->atomic_read))
1020 return -ERESTARTSYS;
1021 }
1022
1023 add_wait_queue(&tty->read_wait, &wait);
1024 set_bit(TTY_DONT_FLIP, &tty->flags);
1025 while (nr) {
1026
1027 if (tty->packet && tty->link->ctrl_status) {
1028 unsigned char cs;
1029 if (b != buf)
1030 break;
1031 cs = tty->link->ctrl_status;
1032 tty->link->ctrl_status = 0;
1033 put_user(cs, b++);
1034 nr--;
1035 break;
1036 }
1037
1038
1039
1040 set_current_state(TASK_INTERRUPTIBLE);
1041
1042 if (((minimum - (b - buf)) < tty->minimum_to_wake) &&
1043 ((minimum - (b - buf)) >= 1))
1044 tty->minimum_to_wake = (minimum - (b - buf));
1045
1046 if (!input_available_p(tty, 0)) {
1047 if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
1048 retval = -EIO;
1049 break;
1050 }
1051 if (tty_hung_up_p(file))
1052 break;
1053 if (!timeout)
1054 break;
1055 if (file->f_flags & O_NONBLOCK) {
1056 retval = -EAGAIN;
1057 break;
1058 }
1059 if (signal_pending(current)) {
1060 retval = -ERESTARTSYS;
1061 break;
1062 }
1063 clear_bit(TTY_DONT_FLIP, &tty->flags);
1064 timeout = schedule_timeout(timeout);
1065 set_bit(TTY_DONT_FLIP, &tty->flags);
1066 continue;
1067 }
1068 current->state = TASK_RUNNING;
1069
1070
1071 if (tty->packet && b == buf) {
1072 put_user(TIOCPKT_DATA, b++);
1073 nr--;
1074 }
1075
1076 if (tty->icanon) {
1077
1078 while (nr && tty->read_cnt) {
1079 int eol;
1080
1081 eol = test_and_clear_bit(tty->read_tail,
1082 &tty->read_flags);
1083 c = tty->read_buf[tty->read_tail];
1084 spin_lock_irqsave(&tty->read_lock, flags);
1085 tty->read_tail = ((tty->read_tail+1) &
1086 (N_TTY_BUF_SIZE-1));
1087 tty->read_cnt--;
1088 if (eol) {
1089
1090
1091
1092
1093 if (--tty->canon_data < 0)
1094 tty->canon_data = 0;
1095 }
1096 spin_unlock_irqrestore(&tty->read_lock, flags);
1097
1098 if (!eol || (c != __DISABLED_CHAR)) {
1099 put_user(c, b++);
1100 nr--;
1101 }
1102 if (eol)
1103 break;
1104 }
1105 } else {
1106 int uncopied;
1107 uncopied = copy_from_read_buf(tty, &b, &nr);
1108 uncopied += copy_from_read_buf(tty, &b, &nr);
1109 if (uncopied) {
1110 retval = -EFAULT;
1111 break;
1112 }
1113 }
1114
1115
1116
1117
1118
1119
1120
1121
1122 if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE)
1123 check_unthrottle(tty);
1124
1125 if (b - buf >= minimum)
1126 break;
1127 if (time)
1128 timeout = time;
1129 }
1130 clear_bit(TTY_DONT_FLIP, &tty->flags);
1131 up(&tty->atomic_read);
1132 remove_wait_queue(&tty->read_wait, &wait);
1133
1134 if (!waitqueue_active(&tty->read_wait))
1135 tty->minimum_to_wake = minimum;
1136
1137 current->state = TASK_RUNNING;
1138 size = b - buf;
1139 if (size) {
1140 retval = size;
1141 if (nr)
1142 clear_bit(TTY_PUSH, &tty->flags);
1143 } else if (test_and_clear_bit(TTY_PUSH, &tty->flags))
1144 goto do_it_again;
1145
1146 return retval;
1147}
1148
1149static ssize_t write_chan(struct tty_struct * tty, struct file * file,
1150 const unsigned char * buf, size_t nr)
1151{
1152 const unsigned char *b = buf;
1153 DECLARE_WAITQUEUE(wait, current);
1154 int c;
1155 ssize_t retval = 0;
1156
1157
1158 if (L_TOSTOP(tty) &&
1159 file->f_dentry->d_inode->i_rdev != CONSOLE_DEV &&
1160 file->f_dentry->d_inode->i_rdev != SYSCONS_DEV) {
1161 retval = tty_check_change(tty);
1162 if (retval)
1163 return retval;
1164 }
1165
1166 add_wait_queue(&tty->write_wait, &wait);
1167 while (1) {
1168 set_current_state(TASK_INTERRUPTIBLE);
1169 if (signal_pending(current)) {
1170 retval = -ERESTARTSYS;
1171 break;
1172 }
1173 if (tty_hung_up_p(file) || (tty->link && !tty->link->count)) {
1174 retval = -EIO;
1175 break;
1176 }
1177 if (O_OPOST(tty) && !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {
1178 while (nr > 0) {
1179 ssize_t num = opost_block(tty, b, nr);
1180 if (num < 0) {
1181 if (num == -EAGAIN)
1182 break;
1183 retval = num;
1184 goto break_out;
1185 }
1186 b += num;
1187 nr -= num;
1188 if (nr == 0)
1189 break;
1190 get_user(c, b);
1191 if (opost(c, tty) < 0)
1192 break;
1193 b++; nr--;
1194 }
1195 if (tty->driver.flush_chars)
1196 tty->driver.flush_chars(tty);
1197 } else {
1198 c = tty->driver.write(tty, 1, b, nr);
1199 if (c < 0) {
1200 retval = c;
1201 goto break_out;
1202 }
1203 b += c;
1204 nr -= c;
1205 }
1206 if (!nr)
1207 break;
1208 if (file->f_flags & O_NONBLOCK) {
1209 retval = -EAGAIN;
1210 break;
1211 }
1212 schedule();
1213 }
1214break_out:
1215 current->state = TASK_RUNNING;
1216 remove_wait_queue(&tty->write_wait, &wait);
1217 return (b - buf) ? b - buf : retval;
1218}
1219
1220
1221static unsigned int normal_poll(struct tty_struct * tty, struct file * file, poll_table *wait)
1222{
1223 unsigned int mask = 0;
1224
1225 poll_wait(file, &tty->read_wait, wait);
1226 poll_wait(file, &tty->write_wait, wait);
1227 if (input_available_p(tty, TIME_CHAR(tty) ? 0 : MIN_CHAR(tty)))
1228 mask |= POLLIN | POLLRDNORM;
1229 if (tty->packet && tty->link->ctrl_status)
1230 mask |= POLLPRI | POLLIN | POLLRDNORM;
1231 if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
1232 mask |= POLLHUP;
1233 if (tty_hung_up_p(file))
1234 mask |= POLLHUP;
1235 if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) {
1236 if (MIN_CHAR(tty) && !TIME_CHAR(tty))
1237 tty->minimum_to_wake = MIN_CHAR(tty);
1238 else
1239 tty->minimum_to_wake = 1;
1240 }
1241 if (tty->driver.chars_in_buffer(tty) < WAKEUP_CHARS &&
1242 tty->driver.write_room(tty) > 0)
1243 mask |= POLLOUT | POLLWRNORM;
1244 return mask;
1245}
1246
1247struct tty_ldisc tty_ldisc_N_TTY = {
1248 TTY_LDISC_MAGIC,
1249 "n_tty",
1250 0,
1251 0,
1252 n_tty_open,
1253 n_tty_close,
1254 n_tty_flush_buffer,
1255 n_tty_chars_in_buffer,
1256 read_chan,
1257 write_chan,
1258 n_tty_ioctl,
1259 n_tty_set_termios,
1260 normal_poll,
1261 n_tty_receive_buf,
1262 n_tty_receive_room,
1263 n_tty_write_wakeup
1264};
1265
1266