This source file includes following definitions.
- tty_register_ldisc
- put_tty_queue
- get_tty_queue
- tty_read_raw_data
- tty_write_flush
- tty_read_flush
- hung_up_tty_read
- hung_up_tty_write
- hung_up_tty_select
- hung_up_tty_ioctl
- tty_lseek
- do_tty_hangup
- tty_hangup
- tty_vhangup
- tty_unhangup
- tty_hung_up_p
- vt_waitactive
- complete_change_console
- change_console
- wait_for_keypress
- copy_to_cooked
- is_ignored
- wait_for_canon_input
- read_chan
- __wait_for_canon_input
- available_canon_input
- write_chan
- tty_read
- tty_write
- init_dev
- release_dev
- tty_open
- tty_release
- tty_select
- do_SAK
- tty_write_data
- tty_bh_routine
- initialize_tty_struct
- initialize_termios
- tty_init
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
34
35
36
37 #include <linux/types.h>
38 #include <linux/major.h>
39 #include <linux/errno.h>
40 #include <linux/signal.h>
41 #include <linux/fcntl.h>
42 #include <linux/sched.h>
43 #include <linux/tty.h>
44 #include <linux/timer.h>
45 #include <linux/ctype.h>
46 #include <linux/kd.h>
47 #include <linux/mm.h>
48 #include <linux/string.h>
49 #include <linux/keyboard.h>
50 #include <linux/malloc.h>
51
52 #include <asm/segment.h>
53 #include <asm/system.h>
54 #include <asm/bitops.h>
55
56 #include "vt_kern.h"
57
58 #define MAX_TTYS 256
59
60 struct tty_struct *tty_table[MAX_TTYS];
61 struct termios *tty_termios[MAX_TTYS];
62
63 struct termios *termios_locked[MAX_TTYS];
64 struct tty_ldisc ldiscs[NR_LDISCS];
65 int tty_check_write[MAX_TTYS/32];
66
67
68
69
70
71
72 int fg_console = 0;
73 struct tty_struct * redirect = NULL;
74 struct wait_queue * keypress_wait = NULL;
75
76 static void initialize_tty_struct(int line, struct tty_struct *tty);
77 static void initialize_termios(int line, struct termios *tp);
78
79 static int tty_read(struct inode *, struct file *, char *, int);
80 static int tty_write(struct inode *, struct file *, char *, int);
81 static int tty_select(struct inode *, struct file *, int, select_table *);
82 static int tty_open(struct inode *, struct file *);
83 static void tty_release(struct inode *, struct file *);
84
85 int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
86 {
87 if (disc < N_TTY || disc >= NR_LDISCS)
88 return -EINVAL;
89
90 if (new_ldisc) {
91 ldiscs[disc] = *new_ldisc;
92 ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
93 } else
94 memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc));
95
96 return 0;
97 }
98
99 void put_tty_queue(char c, struct tty_queue * queue)
100 {
101 int head;
102 unsigned long flags;
103
104 save_flags(flags);
105 cli();
106 head = (queue->head + 1) & (TTY_BUF_SIZE-1);
107 if (head != queue->tail) {
108 queue->buf[queue->head] = c;
109 queue->head = head;
110 }
111 restore_flags(flags);
112 }
113
114 int get_tty_queue(struct tty_queue * queue)
115 {
116 int result = -1;
117 unsigned long flags;
118
119 save_flags(flags);
120 cli();
121 if (queue->tail != queue->head) {
122 result = 0xff & queue->buf[queue->tail];
123 queue->tail = (queue->tail + 1) & (TTY_BUF_SIZE-1);
124 }
125 restore_flags(flags);
126 return result;
127 }
128
129
130
131
132
133
134
135
136
137 int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, int buflen)
138 {
139 int result = 0;
140 unsigned char *p = bufp;
141 unsigned long flags;
142 int head, tail;
143 int ok = 1;
144
145 save_flags(flags);
146 cli();
147 tail = tty->read_q.tail;
148 head = tty->read_q.head;
149 while ((result < buflen) && (tail!=head) && ok) {
150 ok = !clear_bit (tail, &tty->readq_flags);
151 *p++ = tty->read_q.buf[tail++];
152 tail &= TTY_BUF_SIZE-1;
153 result++;
154 }
155 tty->read_q.tail = tail;
156 restore_flags(flags);
157 return (ok) ? result : -result;
158 }
159
160
161 void tty_write_flush(struct tty_struct * tty)
162 {
163 if (!tty->write || EMPTY(&tty->write_q))
164 return;
165 if (set_bit(TTY_WRITE_BUSY,&tty->flags))
166 return;
167 tty->write(tty);
168 if (!clear_bit(TTY_WRITE_BUSY,&tty->flags))
169 printk("tty_write_flush: bit already cleared\n");
170 }
171
172 void tty_read_flush(struct tty_struct * tty)
173 {
174 if (!tty || EMPTY(&tty->read_q))
175 return;
176 if (set_bit(TTY_READ_BUSY, &tty->flags))
177 return;
178 ldiscs[tty->disc].handler(tty);
179 if (!clear_bit(TTY_READ_BUSY, &tty->flags))
180 printk("tty_read_flush: bit already cleared\n");
181 }
182
183 static int hung_up_tty_read(struct inode * inode, struct file * file, char * buf, int count)
184 {
185 return 0;
186 }
187
188 static int hung_up_tty_write(struct inode * inode, struct file * file, char * buf, int count)
189 {
190 return -EIO;
191 }
192
193 static int hung_up_tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
194 {
195 return 1;
196 }
197
198 static int hung_up_tty_ioctl(struct inode * inode, struct file * file,
199 unsigned int cmd, unsigned long arg)
200 {
201 return -EIO;
202 }
203
204 static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
205 {
206 return -ESPIPE;
207 }
208
209 static struct file_operations tty_fops = {
210 tty_lseek,
211 tty_read,
212 tty_write,
213 NULL,
214 tty_select,
215 tty_ioctl,
216 NULL,
217 tty_open,
218 tty_release
219 };
220
221 static struct file_operations hung_up_tty_fops = {
222 tty_lseek,
223 hung_up_tty_read,
224 hung_up_tty_write,
225 NULL,
226 hung_up_tty_select,
227 tty_ioctl,
228 NULL,
229 tty_open,
230 tty_release
231 };
232
233 static struct file_operations vhung_up_tty_fops = {
234 tty_lseek,
235 hung_up_tty_read,
236 hung_up_tty_write,
237 NULL,
238 hung_up_tty_select,
239 hung_up_tty_ioctl,
240 NULL,
241 tty_open,
242 tty_release
243 };
244
245 void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops)
246 {
247 int i;
248 struct file * filp;
249 struct task_struct **p;
250 int dev;
251
252 if (!tty)
253 return;
254 dev = 0x0400 + tty->line;
255 for (filp = first_file, i=0; i<nr_files; i++, filp = filp->f_next) {
256 if (!filp->f_count)
257 continue;
258 if (filp->f_rdev != dev)
259 continue;
260 if (filp->f_inode && filp->f_inode->i_rdev == 0x0400)
261 continue;
262 if (filp->f_op != &tty_fops)
263 continue;
264 filp->f_op = fops;
265 }
266 wake_up_interruptible(&tty->secondary.proc_list);
267 wake_up_interruptible(&tty->read_q.proc_list);
268 wake_up_interruptible(&tty->write_q.proc_list);
269 if (tty->session > 0)
270 kill_sl(tty->session,SIGHUP,1);
271 tty->session = 0;
272 tty->pgrp = -1;
273 for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
274 if ((*p) && (*p)->tty == tty->line)
275 (*p)->tty = -1;
276 }
277 }
278
279 void tty_hangup(struct tty_struct * tty)
280 {
281 do_tty_hangup(tty, &hung_up_tty_fops);
282 }
283
284 void tty_vhangup(struct tty_struct * tty)
285 {
286 do_tty_hangup(tty, &vhung_up_tty_fops);
287 }
288
289 void tty_unhangup(struct file *filp)
290 {
291 filp->f_op = &tty_fops;
292 }
293
294 int tty_hung_up_p(struct file * filp)
295 {
296 return ((filp->f_op == &hung_up_tty_fops) ||
297 (filp->f_op == &vhung_up_tty_fops));
298 }
299
300
301
302
303
304
305
306
307 static struct wait_queue *vt_activate_queue = NULL;
308
309
310
311
312
313 int vt_waitactive(void)
314 {
315 interruptible_sleep_on(&vt_activate_queue);
316 return (current->signal & ~current->blocked) ? -1 : 0;
317 }
318
319 #define vt_wake_waitactive() wake_up(&vt_activate_queue)
320
321 extern int kill_proc(int pid, int sig, int priv);
322
323
324
325
326 void complete_change_console(unsigned int new_console)
327 {
328 unsigned char old_vc_mode;
329
330 if (new_console == fg_console || new_console >= NR_CONSOLES)
331 return;
332
333
334
335
336
337
338 old_vc_mode = vt_cons[fg_console].vc_mode;
339 update_screen(new_console);
340
341
342
343
344
345
346 if (vt_cons[new_console].vt_mode.mode == VT_PROCESS)
347 {
348
349
350
351
352
353 if (kill_proc(vt_cons[new_console].vt_pid,
354 vt_cons[new_console].vt_mode.acqsig,
355 1) != 0)
356 {
357
358
359
360
361
362
363
364
365
366 vt_cons[new_console].vc_mode = KD_TEXT;
367 clr_vc_kbd_flag(kbd_table + new_console, VC_RAW);
368 vt_cons[new_console].vt_mode.mode = VT_AUTO;
369 vt_cons[new_console].vt_mode.waitv = 0;
370 vt_cons[new_console].vt_mode.relsig = 0;
371 vt_cons[new_console].vt_mode.acqsig = 0;
372 vt_cons[new_console].vt_mode.frsig = 0;
373 vt_cons[new_console].vt_pid = -1;
374 vt_cons[new_console].vt_newvt = -1;
375 }
376 }
377
378
379
380
381
382 if (old_vc_mode != vt_cons[new_console].vc_mode)
383 {
384 if (vt_cons[new_console].vc_mode == KD_TEXT)
385 unblank_screen();
386 else {
387 timer_active &= ~(1<<BLANK_TIMER);
388 blank_screen();
389 }
390 }
391
392
393
394
395 vt_wake_waitactive();
396 return;
397 }
398
399
400
401
402 void change_console(unsigned int new_console)
403 {
404 if (new_console == fg_console || new_console >= NR_CONSOLES)
405 return;
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422 if (vt_cons[fg_console].vt_mode.mode == VT_PROCESS)
423 {
424
425
426
427
428
429 if (kill_proc(vt_cons[fg_console].vt_pid,
430 vt_cons[fg_console].vt_mode.relsig,
431 1) == 0)
432 {
433
434
435
436
437
438 vt_cons[fg_console].vt_newvt = new_console;
439 return;
440 }
441
442
443
444
445
446
447
448
449
450
451 vt_cons[fg_console].vc_mode = KD_TEXT;
452 clr_vc_kbd_flag(kbd_table + fg_console, VC_RAW);
453 vt_cons[fg_console].vt_mode.mode = VT_AUTO;
454 vt_cons[fg_console].vt_mode.waitv = 0;
455 vt_cons[fg_console].vt_mode.relsig = 0;
456 vt_cons[fg_console].vt_mode.acqsig = 0;
457 vt_cons[fg_console].vt_mode.frsig = 0;
458 vt_cons[fg_console].vt_pid = -1;
459 vt_cons[fg_console].vt_newvt = -1;
460
461
462
463 }
464
465
466
467
468 if (vt_cons[fg_console].vc_mode == KD_GRAPHICS)
469 return;
470
471 complete_change_console(new_console);
472 }
473
474 void wait_for_keypress(void)
475 {
476 sleep_on(&keypress_wait);
477 }
478
479 void copy_to_cooked(struct tty_struct * tty)
480 {
481 int c, special_flag;
482 unsigned long flags;
483
484 if (!tty) {
485 printk("copy_to_cooked: called with NULL tty\n");
486 return;
487 }
488 if (!tty->write) {
489 printk("copy_to_cooked: tty %d has null write routine\n",
490 tty->line);
491 }
492 while (1) {
493
494
495
496
497
498 c = LEFT(&tty->secondary);
499 if (tty->throttle && (c < SQ_THRESHOLD_LW)
500 && !set_bit(TTY_SQ_THROTTLED, &tty->flags))
501 tty->throttle(tty, TTY_THROTTLE_SQ_FULL);
502 if (c == 0)
503 break;
504 save_flags(flags); cli();
505 if (tty->read_q.tail != tty->read_q.head) {
506 c = 0xff & tty->read_q.buf[tty->read_q.tail];
507 special_flag = clear_bit(tty->read_q.tail,
508 &tty->readq_flags);
509 tty->read_q.tail = (tty->read_q.tail + 1) &
510 (TTY_BUF_SIZE-1);
511 restore_flags(flags);
512 } else {
513 restore_flags(flags);
514 break;
515 }
516 if (special_flag) {
517 tty->char_error = c & 3;
518 continue;
519 }
520 if (tty->char_error) {
521 if (tty->char_error == TTY_BREAK) {
522 tty->char_error = 0;
523 if (I_IGNBRK(tty))
524 continue;
525 if (I_PARMRK(tty)) {
526 put_tty_queue('\377', &tty->secondary);
527 put_tty_queue('\0', &tty->secondary);
528 }
529 put_tty_queue('\0', &tty->secondary);
530 continue;
531 }
532
533 tty->char_error = 0;
534 if (I_IGNPAR(tty)) {
535 continue;
536 }
537 if (I_PARMRK(tty)) {
538 put_tty_queue('\377', &tty->secondary);
539 put_tty_queue('\0', &tty->secondary);
540 put_tty_queue(c, &tty->secondary);
541 } else
542 put_tty_queue('\0', &tty->secondary);
543 continue;
544 }
545 if (I_STRP(tty))
546 c &= 0x7f;
547 else if (I_PARMRK(tty) && (c == '\377'))
548 put_tty_queue('\377', &tty->secondary);
549 if (c==13) {
550 if (I_CRNL(tty))
551 c=10;
552 else if (I_NOCR(tty))
553 continue;
554 } else if (c==10 && I_NLCR(tty))
555 c=13;
556 if (I_UCLC(tty))
557 c=tolower(c);
558 if (c == __DISABLED_CHAR)
559 tty->lnext = 1;
560 if (L_CANON(tty) && !tty->lnext) {
561 if (c == KILL_CHAR(tty) || c == WERASE_CHAR(tty)) {
562 int seen_alnums =
563 (c == WERASE_CHAR(tty)) ? 0 : -1;
564
565
566 while(!(EMPTY(&tty->secondary) ||
567 (c=LAST(&tty->secondary))==10 ||
568 ((EOF_CHAR(tty) != __DISABLED_CHAR) &&
569 (c==EOF_CHAR(tty))))) {
570
571
572
573 if (seen_alnums >= 0) {
574 if (isalnum(c))
575 seen_alnums++;
576 else if (seen_alnums)
577 break;
578 }
579 if (L_ECHO(tty)) {
580 if (c<32) {
581 put_tty_queue('\b', &tty->write_q);
582 put_tty_queue(' ', &tty->write_q);
583 put_tty_queue('\b',&tty->write_q);
584 }
585 put_tty_queue('\b',&tty->write_q);
586 put_tty_queue(' ',&tty->write_q);
587 put_tty_queue('\b',&tty->write_q);
588 }
589 DEC(tty->secondary.head);
590 }
591 continue;
592 }
593 if (c == ERASE_CHAR(tty)) {
594 if (EMPTY(&tty->secondary) ||
595 (c=LAST(&tty->secondary))==10 ||
596 ((EOF_CHAR(tty) != __DISABLED_CHAR) &&
597 (c==EOF_CHAR(tty))))
598 continue;
599 if (L_ECHO(tty)) {
600 if (c<32) {
601 put_tty_queue('\b',&tty->write_q);
602 put_tty_queue(' ',&tty->write_q);
603 put_tty_queue('\b',&tty->write_q);
604 }
605 put_tty_queue('\b',&tty->write_q);
606 put_tty_queue(' ',&tty->write_q);
607 put_tty_queue('\b',&tty->write_q);
608 }
609 DEC(tty->secondary.head);
610 continue;
611 }
612 if (c == LNEXT_CHAR(tty)) {
613 tty->lnext = 1;
614 if (L_ECHO(tty)) {
615 put_tty_queue('^',&tty->write_q);
616 put_tty_queue('\b',&tty->write_q);
617 }
618 continue;
619 }
620 }
621 if (I_IXON(tty) && !tty->lnext) {
622 if (c == STOP_CHAR(tty)) {
623 tty->ctrl_status &= ~(TIOCPKT_START);
624 tty->ctrl_status |= TIOCPKT_STOP;
625 if (tty->link)
626 wake_up_interruptible(&tty->link->except_q);
627 tty->stopped=1;
628 if (tty->stop)
629 (tty->stop)(tty);
630 if (IS_A_CONSOLE(tty->line)) {
631 set_vc_kbd_flag(kbd_table + fg_console, VC_SCROLLOCK);
632 set_leds();
633 }
634 continue;
635 }
636 if (((I_IXANY(tty)) && tty->stopped) ||
637 (c == START_CHAR(tty))) {
638 tty->ctrl_status &= ~(TIOCPKT_STOP);
639 tty->ctrl_status |= TIOCPKT_START;
640 tty->stopped=0;
641 if (tty->link)
642 wake_up_interruptible(&tty->link->except_q);
643 if (tty->start)
644 (tty->start)(tty);
645 if (IS_A_CONSOLE(tty->line)) {
646 clr_vc_kbd_flag(kbd_table + fg_console, VC_SCROLLOCK);
647 set_leds();
648 }
649 continue;
650 }
651 }
652 if (L_ISIG(tty) && !tty->lnext) {
653 if (c == INTR_CHAR(tty)) {
654 kill_pg(tty->pgrp, SIGINT, 1);
655 if (! _L_FLAG(tty, NOFLSH)) {
656 flush_input(tty);
657 flush_output(tty);
658 }
659 continue;
660 }
661 if (c == QUIT_CHAR(tty)) {
662 kill_pg(tty->pgrp, SIGQUIT, 1);
663 if (! _L_FLAG(tty, NOFLSH)) {
664 flush_input(tty);
665 flush_output(tty);
666 }
667 continue;
668 }
669 if (c == SUSPEND_CHAR(tty)) {
670 if (!is_orphaned_pgrp(tty->pgrp)) {
671 kill_pg(tty->pgrp, SIGTSTP, 1);
672 if (! _L_FLAG(tty, NOFLSH)) {
673 flush_input(tty);
674 flush_output(tty);
675 }
676 }
677 continue;
678 }
679 }
680 if (c==10 || (EOF_CHAR(tty) != __DISABLED_CHAR &&
681 c==EOF_CHAR(tty)))
682 tty->secondary.data++;
683 if ((c==10) && (L_ECHO(tty) || (L_CANON(tty) && L_ECHONL(tty)))) {
684 put_tty_queue('\n',&tty->write_q);
685 put_tty_queue('\r',&tty->write_q);
686 } else if (L_ECHO(tty)) {
687 if (c<32 && L_ECHOCTL(tty)) {
688 put_tty_queue('^',&tty->write_q);
689 put_tty_queue(c+'A'-1, &tty->write_q);
690 if (EOF_CHAR(tty) != __DISABLED_CHAR &&
691 c==EOF_CHAR(tty) && !tty->lnext) {
692 put_tty_queue('\b',&tty->write_q);
693 put_tty_queue('\b',&tty->write_q);
694 }
695 } else
696 put_tty_queue(c, &tty->write_q);
697 }
698 tty->lnext = 0;
699 put_tty_queue(c, &tty->secondary);
700 }
701 TTY_WRITE_FLUSH(tty);
702 if (!EMPTY(&tty->secondary))
703 wake_up_interruptible(&tty->secondary.proc_list);
704 if (tty->write_q.proc_list && LEFT(&tty->write_q) > TTY_BUF_SIZE/2)
705 wake_up_interruptible(&tty->write_q.proc_list);
706 if (tty->throttle && (LEFT(&tty->read_q) >= RQ_THRESHOLD_HW)
707 && clear_bit(TTY_RQ_THROTTLED, &tty->flags))
708 tty->throttle(tty, TTY_THROTTLE_RQ_AVAIL);
709 if (tty->throttle && (LEFT(&tty->secondary) >= SQ_THRESHOLD_HW)
710 && clear_bit(TTY_SQ_THROTTLED, &tty->flags))
711 tty->throttle(tty, TTY_THROTTLE_SQ_AVAIL);
712 }
713
714 int is_ignored(int sig)
715 {
716 return ((current->blocked & (1<<(sig-1))) ||
717 (current->sigaction[sig-1].sa_handler == SIG_IGN));
718 }
719
720 static int available_canon_input(struct tty_struct *);
721 static void __wait_for_canon_input(struct file * file, struct tty_struct *);
722
723 static void wait_for_canon_input(struct file * file, struct tty_struct * tty)
724 {
725 if (!available_canon_input(tty)) {
726 if (current->signal & ~current->blocked)
727 return;
728 __wait_for_canon_input(file, tty);
729 }
730 }
731
732 static int read_chan(struct tty_struct * tty, struct file * file, char * buf, int nr)
733 {
734 struct wait_queue wait = { current, NULL };
735 int c;
736 char * b=buf;
737 int minimum,time;
738
739 if (L_CANON(tty))
740 minimum = time = current->timeout = 0;
741 else {
742 time = 10L*tty->termios->c_cc[VTIME];
743 minimum = tty->termios->c_cc[VMIN];
744 if (minimum)
745 current->timeout = 0xffffffff;
746 else {
747 if (time)
748 current->timeout = time + jiffies;
749 else
750 current->timeout = 0;
751 time = 0;
752 minimum = 1;
753 }
754 }
755 if (file->f_flags & O_NONBLOCK) {
756 time = current->timeout = 0;
757 if (L_CANON(tty) && !available_canon_input(tty))
758 return -EAGAIN;
759 } else if (L_CANON(tty)) {
760 wait_for_canon_input(file, tty);
761 if (current->signal & ~current->blocked)
762 return -ERESTARTSYS;
763 }
764 if (minimum>nr)
765 minimum = nr;
766
767
768 if (tty->packet && tty->link && tty->link->ctrl_status) {
769 put_fs_byte (tty->link->ctrl_status, b);
770 tty->link->ctrl_status = 0;
771 return 1;
772 }
773
774
775 if (tty->packet) {
776 put_fs_byte (0,b++);
777 nr--;
778
779
780 if (nr == 0)
781 return 1;
782 }
783 add_wait_queue(&tty->secondary.proc_list, &wait);
784 while (nr>0) {
785 if (tty_hung_up_p(file)) {
786 file->f_flags &= ~O_NONBLOCK;
787 break;
788 }
789 TTY_READ_FLUSH(tty);
790 if (tty->link)
791 TTY_WRITE_FLUSH(tty->link);
792 while (nr > 0 && ((c = get_tty_queue(&tty->secondary)) >= 0)) {
793 if ((EOF_CHAR(tty) != __DISABLED_CHAR &&
794 c==EOF_CHAR(tty)) || c==10)
795 tty->secondary.data--;
796 if ((EOF_CHAR(tty) != __DISABLED_CHAR &&
797 c==EOF_CHAR(tty)) && L_CANON(tty))
798 break;
799 put_fs_byte(c,b++);
800 nr--;
801 if (time)
802 current->timeout = time+jiffies;
803 if (c==10 && L_CANON(tty))
804 break;
805 };
806 wake_up_interruptible(&tty->read_q.proc_list);
807
808
809
810
811 if (tty->throttle && (LEFT(&tty->secondary) >= SQ_THRESHOLD_HW)
812 && clear_bit(TTY_SQ_THROTTLED, &tty->flags))
813 tty->throttle(tty, TTY_THROTTLE_SQ_AVAIL);
814 if (tty->link) {
815 if (IS_A_PTY_MASTER(tty->line)) {
816 if ((tty->flags & (1 << TTY_SLAVE_OPENED))
817 && tty->link->count <= 1) {
818 file->f_flags &= ~O_NONBLOCK;
819 break;
820 }
821 } else if (!tty->link->count) {
822 file->f_flags &= ~O_NONBLOCK;
823 break;
824 }
825 }
826 if (b-buf >= minimum || !current->timeout)
827 break;
828 if (current->signal & ~current->blocked)
829 break;
830 TTY_READ_FLUSH(tty);
831 if (tty->link)
832 TTY_WRITE_FLUSH(tty->link);
833 if (!EMPTY(&tty->secondary))
834 continue;
835 current->state = TASK_INTERRUPTIBLE;
836 if (EMPTY(&tty->secondary))
837 schedule();
838 current->state = TASK_RUNNING;
839 }
840 remove_wait_queue(&tty->secondary.proc_list, &wait);
841 TTY_READ_FLUSH(tty);
842 if (tty->link && tty->link->write)
843 TTY_WRITE_FLUSH(tty->link);
844 current->timeout = 0;
845
846
847
848 if (tty->packet) {
849 if ((b-buf) > 1)
850 return b-buf;
851 } else {
852 if (b-buf)
853 return b-buf;
854 }
855
856 if (current->signal & ~current->blocked)
857 return -ERESTARTSYS;
858 if (file->f_flags & O_NONBLOCK)
859 return -EAGAIN;
860 if (IS_A_PTY_MASTER(tty->line))
861 return -EIO;
862 return 0;
863 }
864
865 static void __wait_for_canon_input(struct file * file, struct tty_struct * tty)
866 {
867 struct wait_queue wait = { current, NULL };
868
869 add_wait_queue(&tty->secondary.proc_list, &wait);
870 while (1) {
871 current->state = TASK_INTERRUPTIBLE;
872 if (available_canon_input(tty))
873 break;
874 if (current->signal & ~current->blocked)
875 break;
876 if (tty_hung_up_p(file))
877 break;
878 schedule();
879 }
880 current->state = TASK_RUNNING;
881 remove_wait_queue(&tty->secondary.proc_list, &wait);
882 }
883
884 static int available_canon_input(struct tty_struct * tty)
885 {
886 TTY_READ_FLUSH(tty);
887 if (tty->link)
888 if (tty->link->count)
889 TTY_WRITE_FLUSH(tty->link);
890 else
891 return 1;
892 if (FULL(&tty->read_q))
893 return 1;
894 if (tty->secondary.data)
895 return 1;
896 return 0;
897 }
898
899 static int write_chan(struct tty_struct * tty, struct file * file, char * buf, int nr)
900 {
901 struct wait_queue wait = { current, NULL };
902 char c, *b=buf;
903
904 if (nr < 0)
905 return -EINVAL;
906 if (!nr)
907 return 0;
908 add_wait_queue(&tty->write_q.proc_list, &wait);
909 while (nr>0) {
910 if (current->signal & ~current->blocked)
911 break;
912 if (tty_hung_up_p(file))
913 break;
914 if (tty->link && !tty->link->count) {
915 send_sig(SIGPIPE,current,0);
916 break;
917 }
918 current->state = TASK_INTERRUPTIBLE;
919 if (FULL(&tty->write_q)) {
920 TTY_WRITE_FLUSH(tty);
921 if (FULL(&tty->write_q))
922 schedule();
923 current->state = TASK_RUNNING;
924 continue;
925 }
926 current->state = TASK_RUNNING;
927 while (nr>0 && !FULL(&tty->write_q)) {
928 c=get_fs_byte(b);
929 if (O_POST(tty)) {
930 switch (c) {
931 case '\n':
932 if (O_NLRET(tty)) {
933 tty->column = 0;
934 }
935 if (O_NLCR(tty)) {
936 if (!set_bit(TTY_CR_PENDING,&tty->flags)) {
937 c = '\r';
938 tty->column = 0;
939 b--; nr++;
940 } else {
941 clear_bit(TTY_CR_PENDING,&tty->flags);
942 }
943 }
944 break;
945 case '\r':
946 if (O_NOCR(tty) && tty->column == 0) {
947 b++; nr--;
948 continue;
949 }
950 if (O_CRNL(tty)) {
951 c = '\n';
952 if (O_NLRET(tty))
953 tty->column = 0;
954 break;
955 }
956 tty->column = 0;
957 break;
958 case '\t':
959 if (O_TABDLY(tty) == XTABS) {
960 c = ' ';
961 tty->column++;
962 if (tty->column % 8 != 0) {
963 b--; nr++;
964 }
965 }
966 break;
967 case '\b':
968 tty->column--;
969 break;
970 default:
971 if (O_LCUC(tty))
972 c = toupper(c);
973 tty->column++;
974 break;
975 }
976 }
977 b++; nr--;
978 put_tty_queue(c,&tty->write_q);
979 }
980 if (need_resched)
981 schedule();
982 }
983 remove_wait_queue(&tty->write_q.proc_list, &wait);
984 TTY_WRITE_FLUSH(tty);
985 if (b-buf)
986 return b-buf;
987 if (tty->link && !tty->link->count)
988 return -EPIPE;
989 if (current->signal & ~current->blocked)
990 return -ERESTARTSYS;
991 return 0;
992 }
993
994 static int tty_read(struct inode * inode, struct file * file, char * buf, int count)
995 {
996 int i, dev;
997 struct tty_struct * tty;
998
999 dev = file->f_rdev;
1000 if (MAJOR(dev) != TTY_MAJOR) {
1001 printk("tty_read: bad pseudo-major nr #%d\n", MAJOR(dev));
1002 return -EINVAL;
1003 }
1004 dev = MINOR(dev);
1005 tty = TTY_TABLE(dev);
1006 if (!tty || (tty->flags & (1 << TTY_IO_ERROR)))
1007 return -EIO;
1008 if ((inode->i_rdev != 0x0400) &&
1009 (tty->pgrp > 0) &&
1010 (current->tty == dev) &&
1011 (tty->pgrp != current->pgrp))
1012 if (is_ignored(SIGTTIN) || is_orphaned_pgrp(current->pgrp))
1013 return -EIO;
1014 else {
1015 (void) kill_pg(current->pgrp, SIGTTIN, 1);
1016 return -ERESTARTSYS;
1017 }
1018 if (ldiscs[tty->disc].read)
1019 i = (ldiscs[tty->disc].read)(tty,file,buf,count);
1020 else
1021 i = -EIO;
1022 if (i > 0)
1023 inode->i_atime = CURRENT_TIME;
1024 return i;
1025 }
1026
1027 static int tty_write(struct inode * inode, struct file * file, char * buf, int count)
1028 {
1029 int dev, i, is_console;
1030 struct tty_struct * tty;
1031
1032 dev = file->f_rdev;
1033 is_console = (inode->i_rdev == 0x0400);
1034 if (MAJOR(dev) != TTY_MAJOR) {
1035 printk("tty_write: pseudo-major != TTY_MAJOR\n");
1036 return -EINVAL;
1037 }
1038 dev = MINOR(dev);
1039 if (is_console && redirect)
1040 tty = redirect;
1041 else
1042 tty = TTY_TABLE(dev);
1043 if (!tty || !tty->write || (tty->flags & (1 << TTY_IO_ERROR)))
1044 return -EIO;
1045 if (!is_console && L_TOSTOP(tty) && (tty->pgrp > 0) &&
1046 (current->tty == dev) && (tty->pgrp != current->pgrp)) {
1047 if (is_orphaned_pgrp(current->pgrp))
1048 return -EIO;
1049 if (!is_ignored(SIGTTOU)) {
1050 (void) kill_pg(current->pgrp, SIGTTOU, 1);
1051 return -ERESTARTSYS;
1052 }
1053 }
1054 if (ldiscs[tty->disc].write)
1055 i = (ldiscs[tty->disc].write)(tty,file,buf,count);
1056 else
1057 i = -EIO;
1058 if (i > 0)
1059 inode->i_mtime = CURRENT_TIME;
1060 return i;
1061 }
1062
1063
1064
1065
1066
1067
1068 static int init_dev(int dev)
1069 {
1070 struct tty_struct *tty, *o_tty;
1071 struct termios *tp, *o_tp, *ltp, *o_ltp;
1072 int retval;
1073 int o_dev;
1074
1075 o_dev = PTY_OTHER(dev);
1076 tty = o_tty = NULL;
1077 tp = o_tp = NULL;
1078 ltp = o_ltp = NULL;
1079 repeat:
1080 retval = -EAGAIN;
1081 if (IS_A_PTY_MASTER(dev) && tty_table[dev] && tty_table[dev]->count)
1082 goto end_init;
1083 retval = -ENOMEM;
1084 if (!tty_table[dev] && !tty) {
1085 if (!(tty = (struct tty_struct*) get_free_page(GFP_KERNEL)))
1086 goto end_init;
1087 initialize_tty_struct(dev, tty);
1088 goto repeat;
1089 }
1090 if (!tty_termios[dev] && !tp) {
1091 tp = (struct termios *) kmalloc(sizeof(struct termios),
1092 GFP_KERNEL);
1093 if (!tp)
1094 goto end_init;
1095 initialize_termios(dev, tp);
1096 goto repeat;
1097 }
1098 if (!termios_locked[dev] && !ltp) {
1099 ltp = (struct termios *) kmalloc(sizeof(struct termios),
1100 GFP_KERNEL);
1101 if (!ltp)
1102 goto end_init;
1103 memset(ltp, 0, sizeof(struct termios));
1104 goto repeat;
1105 }
1106 if (IS_A_PTY(dev)) {
1107 if (!tty_table[o_dev] && !o_tty) {
1108 o_tty = (struct tty_struct *)
1109 get_free_page(GFP_KERNEL);
1110 if (!o_tty)
1111 goto end_init;
1112 initialize_tty_struct(o_dev, o_tty);
1113 goto repeat;
1114 }
1115 if (!tty_termios[o_dev] && !o_tp) {
1116 o_tp = (struct termios *)
1117 kmalloc(sizeof(struct termios), GFP_KERNEL);
1118 if (!o_tp)
1119 goto end_init;
1120 initialize_termios(o_dev, o_tp);
1121 goto repeat;
1122 }
1123 if (!termios_locked[o_dev] && !o_ltp) {
1124 o_ltp = (struct termios *)
1125 kmalloc(sizeof(struct termios), GFP_KERNEL);
1126 if (!o_ltp)
1127 goto end_init;
1128 memset(o_ltp, 0, sizeof(struct termios));
1129 goto repeat;
1130 }
1131
1132 }
1133
1134 if (!tty_termios[dev]) {
1135 tty_termios[dev] = tp;
1136 tp = NULL;
1137 }
1138 if (!tty_table[dev]) {
1139 tty->termios = tty_termios[dev];
1140 tty_table[dev] = tty;
1141 tty = NULL;
1142 }
1143 if (!termios_locked[dev]) {
1144 termios_locked[dev] = ltp;
1145 ltp = NULL;
1146 }
1147 if (IS_A_PTY(dev)) {
1148 if (!tty_termios[o_dev]) {
1149 tty_termios[o_dev] = o_tp;
1150 o_tp = NULL;
1151 }
1152 if (!termios_locked[o_dev]) {
1153 termios_locked[o_dev] = o_ltp;
1154 o_ltp = NULL;
1155 }
1156 if (!tty_table[o_dev]) {
1157 o_tty->termios = tty_termios[o_dev];
1158 tty_table[o_dev] = o_tty;
1159 o_tty = NULL;
1160 }
1161 tty_table[dev]->link = tty_table[o_dev];
1162 tty_table[o_dev]->link = tty_table[dev];
1163 }
1164 tty_table[dev]->count++;
1165 if (IS_A_PTY_MASTER(dev))
1166 tty_table[o_dev]->count++;
1167 retval = 0;
1168 end_init:
1169 if (tty)
1170 free_page((unsigned long) tty);
1171 if (o_tty)
1172 free_page((unsigned long) o_tty);
1173 if (tp)
1174 kfree_s(tp, sizeof(struct termios));
1175 if (o_tp)
1176 kfree_s(o_tp, sizeof(struct termios));
1177 if (ltp)
1178 kfree_s(ltp, sizeof(struct termios));
1179 if (o_ltp)
1180 kfree_s(o_ltp, sizeof(struct termios));
1181 return retval;
1182 }
1183
1184
1185
1186
1187
1188
1189 static void release_dev(int dev, struct file * filp)
1190 {
1191 struct tty_struct *tty, *o_tty;
1192 struct termios *tp, *o_tp;
1193 struct task_struct **p;
1194
1195 tty = tty_table[dev];
1196 tp = tty_termios[dev];
1197 o_tty = NULL;
1198 o_tp = NULL;
1199 if (!tty) {
1200 printk("release_dev: tty_table[%d] was NULL\n", dev);
1201 return;
1202 }
1203 if (!tp) {
1204 printk("release_dev: tty_termios[%d] was NULL\n", dev);
1205 return;
1206 }
1207 if (IS_A_PTY(dev)) {
1208 o_tty = tty_table[PTY_OTHER(dev)];
1209 o_tp = tty_termios[PTY_OTHER(dev)];
1210 if (!o_tty) {
1211 printk("release_dev: pty pair(%d) was NULL\n", dev);
1212 return;
1213 }
1214 if (!o_tp) {
1215 printk("release_dev: pty pair(%d) termios was NULL\n", dev);
1216 return;
1217 }
1218 if (tty->link != o_tty || o_tty->link != tty) {
1219 printk("release_dev: bad pty pointers\n");
1220 return;
1221 }
1222 }
1223 tty->write_data_cnt = 0;
1224 if (tty->close)
1225 tty->close(tty, filp);
1226 if (IS_A_PTY_MASTER(dev)) {
1227 if (--tty->link->count < 0) {
1228 printk("release_dev: bad tty slave count (dev = %d): %d\n",
1229 dev, tty->count);
1230 tty->link->count = 0;
1231 }
1232 }
1233 if (--tty->count < 0) {
1234 printk("release_dev: bad tty_table[%d]->count: %d\n",
1235 dev, tty->count);
1236 tty->count = 0;
1237 }
1238 if (tty->count)
1239 return;
1240
1241
1242
1243
1244
1245 for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1246 if ((*p) && (*p)->tty == tty->line)
1247 (*p)->tty = -1;
1248 }
1249
1250 if (ldiscs[tty->disc].close != NULL)
1251 ldiscs[tty->disc].close(tty);
1252
1253 if (o_tty) {
1254 if (o_tty->count)
1255 return;
1256 else {
1257 tty_table[PTY_OTHER(dev)] = NULL;
1258 tty_termios[PTY_OTHER(dev)] = NULL;
1259 }
1260 }
1261 tty_table[dev] = NULL;
1262 if (IS_A_PTY(dev)) {
1263 tty_termios[dev] = NULL;
1264 kfree_s(tp, sizeof(struct termios));
1265 }
1266 if (tty == redirect || o_tty == redirect)
1267 redirect = NULL;
1268 free_page((unsigned long) tty);
1269 if (o_tty)
1270 free_page((unsigned long) o_tty);
1271 if (o_tp)
1272 kfree_s(o_tp, sizeof(struct termios));
1273 }
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287 static int tty_open(struct inode * inode, struct file * filp)
1288 {
1289 struct tty_struct *tty;
1290 int major, minor;
1291 int noctty, retval;
1292
1293 minor = MINOR(inode->i_rdev);
1294 major = MAJOR(inode->i_rdev);
1295 noctty = filp->f_flags & O_NOCTTY;
1296 if (major == TTYAUX_MAJOR) {
1297 if (!minor) {
1298 major = TTY_MAJOR;
1299 minor = current->tty;
1300 }
1301 noctty = 1;
1302 } else if (major == TTY_MAJOR) {
1303 if (!minor) {
1304 minor = fg_console + 1;
1305 noctty = 1;
1306 }
1307 } else {
1308 printk("Bad major #%d in tty_open\n", MAJOR(inode->i_rdev));
1309 return -ENODEV;
1310 }
1311 if (minor <= 0)
1312 return -ENXIO;
1313 if (IS_A_PTY_MASTER(minor))
1314 noctty = 1;
1315 filp->f_rdev = (major << 8) | minor;
1316 retval = init_dev(minor);
1317 if (retval)
1318 return retval;
1319 tty = tty_table[minor];
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331 tty->ctrl_status = 0;
1332 tty->packet = 0;
1333
1334 if (tty->open) {
1335 retval = tty->open(tty, filp);
1336 } else {
1337 retval = -ENODEV;
1338 }
1339 if (retval) {
1340 release_dev(minor, filp);
1341 return retval;
1342 }
1343 if (!noctty &&
1344 current->leader &&
1345 current->tty<0 &&
1346 tty->session==0) {
1347 current->tty = minor;
1348 tty->session = current->session;
1349 tty->pgrp = current->pgrp;
1350 }
1351 filp->f_rdev = 0x0400 | minor;
1352 return 0;
1353 }
1354
1355
1356
1357
1358
1359
1360 static void tty_release(struct inode * inode, struct file * filp)
1361 {
1362 int dev;
1363
1364 dev = filp->f_rdev;
1365 if (MAJOR(dev) != TTY_MAJOR) {
1366 printk("tty_release: tty pseudo-major != TTY_MAJOR\n");
1367 return;
1368 }
1369 dev = MINOR(filp->f_rdev);
1370 if (!dev) {
1371 printk("tty_release: bad f_rdev\n");
1372 return;
1373 }
1374 release_dev(dev, filp);
1375 }
1376
1377 static int tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
1378 {
1379 int dev;
1380 struct tty_struct * tty;
1381
1382 dev = filp->f_rdev;
1383 if (MAJOR(dev) != TTY_MAJOR) {
1384 printk("tty_select: tty pseudo-major != TTY_MAJOR\n");
1385 return 0;
1386 }
1387 dev = MINOR(filp->f_rdev);
1388 tty = TTY_TABLE(dev);
1389 if (!tty) {
1390 printk("tty_select: tty struct for dev %d was NULL\n", dev);
1391 return 0;
1392 }
1393 switch (sel_type) {
1394 case SEL_IN:
1395 if (L_CANON(tty)) {
1396 if (available_canon_input(tty))
1397 return 1;
1398 } else if (!EMPTY(&tty->secondary))
1399 return 1;
1400 if (tty->link) {
1401 if (IS_A_PTY_MASTER(tty->line)) {
1402 if ((tty->flags & (1 << TTY_SLAVE_OPENED))
1403 && tty->link->count <= 1)
1404 return 1;
1405 } else {
1406 if (!tty->link->count)
1407 return 1;
1408 }
1409 }
1410
1411
1412 if (tty->packet && tty->link && tty->link->ctrl_status)
1413 return 1;
1414
1415 select_wait(&tty->secondary.proc_list, wait);
1416 return 0;
1417 case SEL_OUT:
1418 if (!FULL(&tty->write_q))
1419 return 1;
1420 select_wait(&tty->write_q.proc_list, wait);
1421 return 0;
1422 case SEL_EX:
1423 if (tty->link) {
1424 if (IS_A_PTY_MASTER(tty->line)) {
1425 if ((tty->flags & (1 << TTY_SLAVE_OPENED))
1426 && tty->link->count <= 1)
1427 return 1;
1428 if (tty->packet
1429 && tty->link->ctrl_status)
1430 return 1;
1431 } else {
1432 if (!tty->link->count)
1433 return 1;
1434 }
1435 }
1436 select_wait(&tty->except_q, wait);
1437 return 0;
1438 }
1439 return 0;
1440 }
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454 void do_SAK( struct tty_struct *tty)
1455 {
1456 struct task_struct **p;
1457 int line = tty->line;
1458 int session = tty->session;
1459 int i;
1460 struct file *filp;
1461
1462 flush_input(tty);
1463 flush_output(tty);
1464 for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1465 if (!(*p))
1466 continue;
1467 if (((*p)->tty == line) ||
1468 ((session > 0) && ((*p)->session == session)))
1469 send_sig(SIGKILL, *p, 1);
1470 else {
1471 for (i=0; i < NR_OPEN; i++) {
1472 filp = (*p)->filp[i];
1473 if (filp && (filp->f_op == &tty_fops) &&
1474 (MINOR(filp->f_rdev) == line)) {
1475 send_sig(SIGKILL, *p, 1);
1476 break;
1477 }
1478 }
1479 }
1480 }
1481 }
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498 int tty_write_data(struct tty_struct *tty, char *bufp, int buflen,
1499 void (*callback)(void * data), void * callarg)
1500 {
1501 int head, tail, count;
1502 unsigned long flags;
1503 char *p;
1504
1505 #define VLEFT ((tail-head-1)&(TTY_BUF_SIZE-1))
1506
1507 save_flags(flags);
1508 cli();
1509 if (tty->write_data_cnt) {
1510 restore_flags(flags);
1511 return -EBUSY;
1512 }
1513
1514 head = tty->write_q.head;
1515 tail = tty->write_q.tail;
1516 count = buflen;
1517 p = bufp;
1518
1519 while (count && VLEFT > 0) {
1520 tty->write_q.buf[head++] = *p++;
1521 head &= TTY_BUF_SIZE-1;
1522 count--;
1523 }
1524 tty->write_q.head = head;
1525 if (count) {
1526 tty->write_data_cnt = count;
1527 tty->write_data_ptr = (unsigned char *) p;
1528 tty->write_data_callback = callback;
1529 tty->write_data_arg = callarg;
1530 }
1531 restore_flags(flags);
1532 tty->write(tty);
1533 return count;
1534 }
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544 void tty_bh_routine(void * unused)
1545 {
1546 int i, j, line, mask;
1547 int head, tail, count;
1548 unsigned char * p;
1549 struct tty_struct * tty;
1550
1551 for (i = 0, line = 0; i < MAX_TTYS / 32; i++) {
1552 if (!tty_check_write[i]) {
1553 line += 32;
1554 continue;
1555 }
1556 for (j=0, mask=0; j < 32; j++, line++, mask <<= 1) {
1557 if (clear_bit(j, &tty_check_write[i])) {
1558 tty = tty_table[line];
1559 if (!tty || !tty->write_data_cnt)
1560 continue;
1561 cli();
1562 head = tty->write_q.head;
1563 tail = tty->write_q.tail;
1564 count = tty->write_data_cnt;
1565 p = tty->write_data_ptr;
1566
1567 while (count && VLEFT > 0) {
1568 tty->write_q.buf[head++] = *p++;
1569 head &= TTY_BUF_SIZE-1;
1570 count--;
1571 }
1572 tty->write_q.head = head;
1573 tty->write_data_ptr = p;
1574 tty->write_data_cnt = count;
1575 sti();
1576 if (!count)
1577 (tty->write_data_callback)
1578 (tty->write_data_arg);
1579 }
1580 }
1581 }
1582
1583 }
1584
1585
1586
1587
1588
1589 static void initialize_tty_struct(int line, struct tty_struct *tty)
1590 {
1591 memset(tty, 0, sizeof(struct tty_struct));
1592 tty->line = line;
1593 tty->disc = N_TTY;
1594 tty->pgrp = -1;
1595 tty->winsize.ws_row = 0;
1596 tty->winsize.ws_col = 0;
1597 if (IS_A_CONSOLE(line)) {
1598 tty->open = con_open;
1599 tty->winsize.ws_row = video_num_lines;
1600 tty->winsize.ws_col = video_num_columns;
1601 } else if IS_A_SERIAL(line) {
1602 tty->open = rs_open;
1603 } else if IS_A_PTY(line) {
1604 tty->open = pty_open;
1605 }
1606 tty->except_q = NULL;
1607 }
1608
1609 static void initialize_termios(int line, struct termios * tp)
1610 {
1611 memset(tp, 0, sizeof(struct termios));
1612 memcpy(tp->c_cc, INIT_C_CC, NCCS);
1613 if (IS_A_CONSOLE(line)) {
1614 tp->c_iflag = ICRNL | IXON;
1615 tp->c_oflag = OPOST | ONLCR;
1616 tp->c_cflag = B38400 | CS8 | CREAD;
1617 tp->c_lflag = ISIG | ICANON | ECHO |
1618 ECHOCTL | ECHOKE;
1619 } else if (IS_A_SERIAL(line)) {
1620 tp->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1621 tp->c_oflag = OPOST | ONLCR | XTABS;
1622 } else if (IS_A_PTY_MASTER(line)) {
1623 tp->c_cflag = B9600 | CS8 | CREAD;
1624 } else if (IS_A_PTY_SLAVE(line)) {
1625 tp->c_iflag = ICRNL | IXON;
1626 tp->c_oflag = OPOST | ONLCR;
1627 tp->c_cflag = B38400 | CS8 | CREAD;
1628 tp->c_lflag = ISIG | ICANON | ECHO |
1629 ECHOCTL | ECHOKE;
1630 }
1631 }
1632
1633 static struct tty_ldisc tty_ldisc_N_TTY = {
1634 0,
1635 NULL,
1636 NULL,
1637 read_chan,
1638 write_chan,
1639 NULL,
1640 copy_to_cooked
1641 };
1642
1643
1644 long tty_init(long kmem_start)
1645 {
1646 int i;
1647
1648 if (sizeof(struct tty_struct) > PAGE_SIZE)
1649 panic("size of tty structure > PAGE_SIZE!");
1650 if (register_chrdev(TTY_MAJOR,"tty",&tty_fops))
1651 panic("unable to get major %d for tty device", TTY_MAJOR);
1652 if (register_chrdev(TTYAUX_MAJOR,"tty",&tty_fops))
1653 panic("unable to get major %d for tty device", TTYAUX_MAJOR);
1654 for (i=0 ; i< MAX_TTYS ; i++) {
1655 tty_table[i] = 0;
1656 tty_termios[i] = 0;
1657 }
1658 memset(tty_check_write, 0, sizeof(tty_check_write));
1659 bh_base[TTY_BH].routine = tty_bh_routine;
1660
1661
1662 memset(ldiscs, 0, sizeof(ldiscs));
1663 (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
1664
1665 kmem_start = kbd_init(kmem_start);
1666 kmem_start = con_init(kmem_start);
1667 kmem_start = rs_init(kmem_start);
1668 return kmem_start;
1669 }