This source file includes following definitions.
- _tty_name
- tty_name
- tty_paranoia_check
- check_tty_count
- tty_register_ldisc
- tty_set_ldisc
- get_tty_driver
- tty_check_change
- 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_hung_up_p
- disassociate_ctty
- vt_waitactive
- reset_vc
- complete_change_console
- change_console
- wait_for_keypress
- stop_tty
- start_tty
- tty_read
- tty_write
- init_dev
- release_dev
- tty_open
- tty_release
- tty_select
- fasync_helper
- tty_fasync
- do_get_ps_info
- tty_ioctl
- do_SAK
- flush_to_ldisc
- initialize_tty_struct
- tty_default_put_char
- tty_register_driver
- tty_unregister_driver
- console_init
- 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
38
39
40
41
42
43 #include <linux/config.h>
44 #include <linux/types.h>
45 #include <linux/major.h>
46 #include <linux/errno.h>
47 #include <linux/signal.h>
48 #include <linux/fcntl.h>
49 #include <linux/sched.h>
50 #include <linux/interrupt.h>
51 #include <linux/tty.h>
52 #include <linux/tty_flip.h>
53 #include <linux/timer.h>
54 #include <linux/ctype.h>
55 #include <linux/kd.h>
56 #include <linux/mm.h>
57 #include <linux/string.h>
58 #include <linux/malloc.h>
59
60 #include <asm/segment.h>
61 #include <asm/system.h>
62 #include <asm/bitops.h>
63
64 #include <linux/scc.h>
65
66 #include "kbd_kern.h"
67 #include "vt_kern.h"
68 #include "selection.h"
69
70 #define CONSOLE_DEV MKDEV(TTY_MAJOR,0)
71 #define TTY_DEV MKDEV(TTYAUX_MAJOR,0)
72
73 #undef TTY_DEBUG_HANGUP
74
75 #define TTY_PARANOIA_CHECK
76 #define CHECK_TTY_COUNT
77
78 extern void do_blank_screen(int nopowersave);
79 extern void set_vesa_blanking(const unsigned long arg);
80
81 struct termios tty_std_termios;
82 struct tty_driver *tty_drivers = NULL;
83 struct tty_ldisc ldiscs[NR_LDISCS];
84
85
86
87
88
89
90
91 int fg_console = 0;
92 int last_console = 0;
93 struct tty_struct * redirect = NULL;
94 struct wait_queue * keypress_wait = NULL;
95
96 static void initialize_tty_struct(struct tty_struct *tty);
97
98 static int tty_read(struct inode *, struct file *, char *, int);
99 static int tty_write(struct inode *, struct file *, const char *, int);
100 static int tty_select(struct inode *, struct file *, int, select_table *);
101 static int tty_open(struct inode *, struct file *);
102 static void tty_release(struct inode *, struct file *);
103 static int tty_ioctl(struct inode * inode, struct file * file,
104 unsigned int cmd, unsigned long arg);
105 static int tty_fasync(struct inode * inode, struct file * filp, int on);
106
107 extern void reset_palette(int currcons) ;
108 extern void set_palette(void) ;
109
110 #ifndef MIN
111 #define MIN(a,b) ((a) < (b) ? (a) : (b))
112 #endif
113
114
115
116
117
118
119 char *_tty_name(struct tty_struct *tty, char *buf)
120 {
121 if (tty)
122 sprintf(buf, "%s%d", tty->driver.name,
123 MINOR(tty->device) - tty->driver.minor_start +
124 tty->driver.name_base);
125 else
126 strcpy(buf, "NULL tty");
127 return buf;
128 }
129
130 char *tty_name(struct tty_struct *tty)
131 {
132 static char buf[64];
133
134 return(_tty_name(tty, buf));
135 }
136
137 inline int tty_paranoia_check(struct tty_struct *tty, kdev_t device,
138 const char *routine)
139 {
140 #ifdef TTY_PARANOIA_CHECK
141 static const char *badmagic =
142 "Warning: bad magic number for tty struct (%s) in %s\n";
143 static const char *badtty =
144 "Warning: null TTY for (%s) in %s\n";
145
146 if (!tty) {
147 printk(badtty, kdevname(device), routine);
148 return 1;
149 }
150 if (tty->magic != TTY_MAGIC) {
151 printk(badmagic, kdevname(device), routine);
152 return 1;
153 }
154 #endif
155 return 0;
156 }
157
158 static int check_tty_count(struct tty_struct *tty, const char *routine)
159 {
160 #ifdef CHECK_TTY_COUNT
161 struct file *f;
162 int i, count = 0;
163
164 for (f = first_file, i=0; i<nr_files; i++, f = f->f_next) {
165 if (!f->f_count)
166 continue;
167 if (f->private_data == tty) {
168 count++;
169 }
170 }
171 if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
172 tty->driver.subtype == PTY_TYPE_SLAVE &&
173 tty->link && tty->link->count)
174 count++;
175 if (tty->count != count) {
176 printk("Warning: dev (%s) tty->count(%d) != #fd's(%d) in %s\n",
177 kdevname(tty->device), tty->count, count, routine);
178 return count;
179 }
180 #endif
181 return 0;
182 }
183
184 int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
185 {
186 if (disc < N_TTY || disc >= NR_LDISCS)
187 return -EINVAL;
188
189 if (new_ldisc) {
190 ldiscs[disc] = *new_ldisc;
191 ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
192 ldiscs[disc].num = disc;
193 } else
194 memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc));
195
196 return 0;
197 }
198
199
200 static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
201 {
202 int retval = 0;
203 struct tty_ldisc o_ldisc;
204
205 if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS) ||
206 !(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED))
207 return -EINVAL;
208
209 if (tty->ldisc.num == ldisc)
210 return 0;
211 o_ldisc = tty->ldisc;
212
213 tty_wait_until_sent(tty, 0);
214
215
216 if (tty->ldisc.close)
217 (tty->ldisc.close)(tty);
218
219
220 tty->ldisc = ldiscs[ldisc];
221 tty->termios->c_line = ldisc;
222 if (tty->ldisc.open)
223 retval = (tty->ldisc.open)(tty);
224 if (retval < 0) {
225 tty->ldisc = o_ldisc;
226 tty->termios->c_line = tty->ldisc.num;
227 if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) {
228 tty->ldisc = ldiscs[N_TTY];
229 tty->termios->c_line = N_TTY;
230 if (tty->ldisc.open) {
231 int r = tty->ldisc.open(tty);
232
233 if (r < 0)
234 panic("Couldn't open N_TTY ldisc for "
235 "%s --- error %d.",
236 tty_name(tty), r);
237 }
238 }
239 }
240 if (tty->ldisc.num != o_ldisc.num && tty->driver.set_ldisc)
241 tty->driver.set_ldisc(tty);
242 return retval;
243 }
244
245
246
247
248 struct tty_driver *get_tty_driver(kdev_t device)
249 {
250 int major, minor;
251 struct tty_driver *p;
252
253 minor = MINOR(device);
254 major = MAJOR(device);
255
256 for (p = tty_drivers; p; p = p->next) {
257 if (p->major != major)
258 continue;
259 if (minor < p->minor_start)
260 continue;
261 if (minor >= p->minor_start + p->num)
262 continue;
263 return p;
264 }
265 return NULL;
266 }
267
268
269
270
271
272
273 int tty_check_change(struct tty_struct * tty)
274 {
275 if (current->tty != tty)
276 return 0;
277 if (tty->pgrp <= 0) {
278 printk("tty_check_change: tty->pgrp <= 0!\n");
279 return 0;
280 }
281 if (current->pgrp == tty->pgrp)
282 return 0;
283 if (is_ignored(SIGTTOU))
284 return 0;
285 if (is_orphaned_pgrp(current->pgrp))
286 return -EIO;
287 (void) kill_pg(current->pgrp,SIGTTOU,1);
288 return -ERESTARTSYS;
289 }
290
291 static int hung_up_tty_read(struct inode * inode, struct file * file, char * buf, int count)
292 {
293 return 0;
294 }
295
296 static int hung_up_tty_write(struct inode * inode, struct file * file, const char * buf, int count)
297 {
298 return -EIO;
299 }
300
301 static int hung_up_tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
302 {
303 return 1;
304 }
305
306 static int hung_up_tty_ioctl(struct inode * inode, struct file * file,
307 unsigned int cmd, unsigned long arg)
308 {
309 return -EIO;
310 }
311
312 static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
313 {
314 return -ESPIPE;
315 }
316
317 static struct file_operations tty_fops = {
318 tty_lseek,
319 tty_read,
320 tty_write,
321 NULL,
322 tty_select,
323 tty_ioctl,
324 NULL,
325 tty_open,
326 tty_release,
327 NULL,
328 tty_fasync
329 };
330
331 static struct file_operations hung_up_tty_fops = {
332 tty_lseek,
333 hung_up_tty_read,
334 hung_up_tty_write,
335 NULL,
336 hung_up_tty_select,
337 hung_up_tty_ioctl,
338 NULL,
339 NULL,
340 tty_release,
341 NULL,
342 NULL
343 };
344
345 void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops)
346 {
347 int i;
348 struct file * filp;
349 struct task_struct *p;
350
351 if (!tty)
352 return;
353 check_tty_count(tty, "do_tty_hangup");
354 for (filp = first_file, i=0; i<nr_files; i++, filp = filp->f_next) {
355 if (!filp->f_count)
356 continue;
357 if (filp->private_data != tty)
358 continue;
359 if (filp->f_inode
360 && filp->f_inode->i_rdev == CONSOLE_DEV)
361 continue;
362 if (filp->f_op != &tty_fops)
363 continue;
364 tty_fasync(filp->f_inode, filp, 0);
365 filp->f_op = fops;
366 }
367
368 if (tty->ldisc.flush_buffer)
369 tty->ldisc.flush_buffer(tty);
370 if (tty->driver.flush_buffer)
371 tty->driver.flush_buffer(tty);
372 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
373 tty->ldisc.write_wakeup)
374 (tty->ldisc.write_wakeup)(tty);
375 wake_up_interruptible(&tty->write_wait);
376 wake_up_interruptible(&tty->read_wait);
377
378
379
380
381
382 if (tty->ldisc.num != ldiscs[N_TTY].num) {
383 if (tty->ldisc.close)
384 (tty->ldisc.close)(tty);
385 tty->ldisc = ldiscs[N_TTY];
386 tty->termios->c_line = N_TTY;
387 if (tty->ldisc.open) {
388 i = (tty->ldisc.open)(tty);
389 if (i < 0)
390 printk("do_tty_hangup: N_TTY open: error %d\n",
391 -i);
392 }
393 }
394
395 for_each_task(p) {
396 if ((tty->session > 0) && (p->session == tty->session) &&
397 p->leader) {
398 send_sig(SIGHUP,p,1);
399 send_sig(SIGCONT,p,1);
400 if (tty->pgrp > 0)
401 p->tty_old_pgrp = tty->pgrp;
402 }
403 if (p->tty == tty)
404 p->tty = NULL;
405 }
406 tty->flags = 0;
407 tty->session = 0;
408 tty->pgrp = -1;
409 tty->ctrl_status = 0;
410 if (tty->driver.flags & TTY_DRIVER_RESET_TERMIOS)
411 *tty->termios = tty->driver.init_termios;
412 if (tty->driver.hangup)
413 (tty->driver.hangup)(tty);
414 }
415
416 void tty_hangup(struct tty_struct * tty)
417 {
418 #ifdef TTY_DEBUG_HANGUP
419 printk("%s hangup...\n", tty_name(tty));
420 #endif
421 do_tty_hangup(tty, &hung_up_tty_fops);
422 }
423
424 void tty_vhangup(struct tty_struct * tty)
425 {
426 #ifdef TTY_DEBUG_HANGUP
427 printk("%s vhangup...\n", tty_name(tty));
428 #endif
429 do_tty_hangup(tty, &hung_up_tty_fops);
430 }
431
432 int tty_hung_up_p(struct file * filp)
433 {
434 return (filp->f_op == &hung_up_tty_fops);
435 }
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450 void disassociate_ctty(int on_exit)
451 {
452 struct tty_struct *tty = current->tty;
453 struct task_struct *p;
454
455 if (tty) {
456 if (on_exit)
457 tty_vhangup(tty);
458 } else {
459 if (current->tty_old_pgrp) {
460 kill_pg(current->tty_old_pgrp, SIGHUP, on_exit);
461 kill_pg(current->tty_old_pgrp, SIGCONT, on_exit);
462 }
463 return;
464 }
465 if (tty->pgrp > 0) {
466 kill_pg(tty->pgrp, SIGHUP, on_exit);
467 kill_pg(tty->pgrp, SIGCONT, on_exit);
468 }
469
470 current->tty_old_pgrp = 0;
471 tty->session = 0;
472 tty->pgrp = -1;
473
474 for_each_task(p)
475 if (p->session == current->session)
476 p->tty = NULL;
477 }
478
479
480
481
482
483
484
485
486 static struct wait_queue *vt_activate_queue = NULL;
487
488
489
490
491
492 int vt_waitactive(void)
493 {
494 interruptible_sleep_on(&vt_activate_queue);
495 return (current->signal & ~current->blocked) ? -1 : 0;
496 }
497
498 #define vt_wake_waitactive() wake_up(&vt_activate_queue)
499
500 void reset_vc(unsigned int new_console)
501 {
502 vt_cons[new_console]->vc_mode = KD_TEXT;
503 kbd_table[new_console].kbdmode = VC_XLATE;
504 vt_cons[new_console]->vt_mode.mode = VT_AUTO;
505 vt_cons[new_console]->vt_mode.waitv = 0;
506 vt_cons[new_console]->vt_mode.relsig = 0;
507 vt_cons[new_console]->vt_mode.acqsig = 0;
508 vt_cons[new_console]->vt_mode.frsig = 0;
509 vt_cons[new_console]->vt_pid = -1;
510 vt_cons[new_console]->vt_newvt = -1;
511 reset_palette (new_console) ;
512 }
513
514
515
516
517 void complete_change_console(unsigned int new_console)
518 {
519 unsigned char old_vc_mode;
520
521 if (new_console == fg_console)
522 return;
523 if (!vc_cons_allocated(new_console))
524 return;
525 last_console = fg_console;
526
527
528
529
530
531
532 old_vc_mode = vt_cons[fg_console]->vc_mode;
533 update_screen(new_console);
534
535
536
537
538
539
540 if (vt_cons[new_console]->vt_mode.mode == VT_PROCESS)
541 {
542
543
544
545
546
547 if (kill_proc(vt_cons[new_console]->vt_pid,
548 vt_cons[new_console]->vt_mode.acqsig,
549 1) != 0)
550 {
551
552
553
554
555
556
557
558
559
560 reset_vc(new_console);
561 }
562 }
563
564
565
566
567
568 if (old_vc_mode != vt_cons[new_console]->vc_mode)
569 {
570 if (vt_cons[new_console]->vc_mode == KD_TEXT)
571 do_unblank_screen();
572 else
573 do_blank_screen(1);
574 }
575
576
577 if (vt_cons[new_console]->vc_mode == KD_TEXT)
578 set_palette() ;
579
580
581
582
583 vt_wake_waitactive();
584 return;
585 }
586
587
588
589
590 void change_console(unsigned int new_console)
591 {
592 if (new_console == fg_console)
593 return;
594 if (!vc_cons_allocated(new_console))
595 return;
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612 if (vt_cons[fg_console]->vt_mode.mode == VT_PROCESS)
613 {
614
615
616
617
618
619 if (kill_proc(vt_cons[fg_console]->vt_pid,
620 vt_cons[fg_console]->vt_mode.relsig,
621 1) == 0)
622 {
623
624
625
626
627
628 vt_cons[fg_console]->vt_newvt = new_console;
629 return;
630 }
631
632
633
634
635
636
637
638
639
640
641 reset_vc(fg_console);
642
643
644
645
646 }
647
648
649
650
651 if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
652 return;
653
654 complete_change_console(new_console);
655 }
656
657 void wait_for_keypress(void)
658 {
659 sleep_on(&keypress_wait);
660 }
661
662 void stop_tty(struct tty_struct *tty)
663 {
664 if (tty->stopped)
665 return;
666 tty->stopped = 1;
667 if (tty->link && tty->link->packet) {
668 tty->ctrl_status &= ~TIOCPKT_START;
669 tty->ctrl_status |= TIOCPKT_STOP;
670 wake_up_interruptible(&tty->link->read_wait);
671 }
672 if (tty->driver.stop)
673 (tty->driver.stop)(tty);
674 }
675
676 void start_tty(struct tty_struct *tty)
677 {
678 if (!tty->stopped)
679 return;
680 tty->stopped = 0;
681 if (tty->link && tty->link->packet) {
682 tty->ctrl_status &= ~TIOCPKT_STOP;
683 tty->ctrl_status |= TIOCPKT_START;
684 wake_up_interruptible(&tty->link->read_wait);
685 }
686 if (tty->driver.start)
687 (tty->driver.start)(tty);
688 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
689 tty->ldisc.write_wakeup)
690 (tty->ldisc.write_wakeup)(tty);
691 wake_up_interruptible(&tty->write_wait);
692 }
693
694 static int tty_read(struct inode * inode, struct file * file, char * buf, int count)
695 {
696 int i;
697 struct tty_struct * tty;
698
699 tty = (struct tty_struct *)file->private_data;
700 if (tty_paranoia_check(tty, inode->i_rdev, "tty_read"))
701 return -EIO;
702 if (!tty || (tty->flags & (1 << TTY_IO_ERROR)))
703 return -EIO;
704
705
706
707
708
709 #if 0
710 if ((inode->i_rdev != CONSOLE_DEV) &&
711 (tty->pgrp > 0) &&
712 (current->tty == tty) &&
713 (tty->pgrp != current->pgrp))
714 if (is_ignored(SIGTTIN) || is_orphaned_pgrp(current->pgrp))
715 return -EIO;
716 else {
717 (void) kill_pg(current->pgrp, SIGTTIN, 1);
718 return -ERESTARTSYS;
719 }
720 #endif
721 if (tty->ldisc.read)
722
723 i = (tty->ldisc.read)(tty,file,(unsigned char *)buf,(unsigned int)count);
724 else
725 i = -EIO;
726 if (i > 0)
727 inode->i_atime = CURRENT_TIME;
728 return i;
729 }
730
731 static int tty_write(struct inode * inode, struct file * file, const char * buf, int count)
732 {
733 int i, is_console;
734 struct tty_struct * tty;
735
736 is_console = (inode->i_rdev == CONSOLE_DEV);
737
738 if (is_console && redirect)
739 tty = redirect;
740 else
741 tty = (struct tty_struct *)file->private_data;
742 if (tty_paranoia_check(tty, inode->i_rdev, "tty_write"))
743 return -EIO;
744 if (!tty || !tty->driver.write || (tty->flags & (1 << TTY_IO_ERROR)))
745 return -EIO;
746 #if 0
747 if (!is_console && L_TOSTOP(tty) && (tty->pgrp > 0) &&
748 (current->tty == tty) && (tty->pgrp != current->pgrp)) {
749 if (is_orphaned_pgrp(current->pgrp))
750 return -EIO;
751 if (!is_ignored(SIGTTOU)) {
752 (void) kill_pg(current->pgrp, SIGTTOU, 1);
753 return -ERESTARTSYS;
754 }
755 }
756 #endif
757 if (tty->ldisc.write)
758
759 i = (tty->ldisc.write)(tty,file,(const unsigned char *)buf,(unsigned int)count);
760 else
761 i = -EIO;
762 if (i > 0)
763 inode->i_mtime = CURRENT_TIME;
764 return i;
765 }
766
767
768
769
770
771
772 static int init_dev(kdev_t device, struct tty_struct **ret_tty)
773 {
774 struct tty_struct *tty, **tty_loc, *o_tty, **o_tty_loc;
775 struct termios *tp, **tp_loc, *o_tp, **o_tp_loc;
776 struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
777 struct tty_driver *driver;
778 int retval;
779 int idx;
780
781 driver = get_tty_driver(device);
782 if (!driver)
783 return -ENODEV;
784
785 idx = MINOR(device) - driver->minor_start;
786 tty = o_tty = NULL;
787 tp = o_tp = NULL;
788 ltp = o_ltp = NULL;
789 o_tty_loc = NULL;
790 o_tp_loc = o_ltp_loc = NULL;
791
792 tty_loc = &driver->table[idx];
793 tp_loc = &driver->termios[idx];
794 ltp_loc = &driver->termios_locked[idx];
795
796 repeat:
797 retval = -EAGAIN;
798 if (driver->type == TTY_DRIVER_TYPE_PTY &&
799 driver->subtype == PTY_TYPE_MASTER &&
800 *tty_loc && (*tty_loc)->count)
801 goto end_init;
802 retval = -ENOMEM;
803 if (!*tty_loc && !tty) {
804 if (!(tty = (struct tty_struct*) get_free_page(GFP_KERNEL)))
805 goto end_init;
806 initialize_tty_struct(tty);
807 tty->device = device;
808 tty->driver = *driver;
809 goto repeat;
810 }
811 if (!*tp_loc && !tp) {
812 tp = (struct termios *) kmalloc(sizeof(struct termios),
813 GFP_KERNEL);
814 if (!tp)
815 goto end_init;
816 *tp = driver->init_termios;
817 goto repeat;
818 }
819 if (!*ltp_loc && !ltp) {
820 ltp = (struct termios *) kmalloc(sizeof(struct termios),
821 GFP_KERNEL);
822 if (!ltp)
823 goto end_init;
824 memset(ltp, 0, sizeof(struct termios));
825 goto repeat;
826 }
827 if (driver->type == TTY_DRIVER_TYPE_PTY) {
828 o_tty_loc = &driver->other->table[idx];
829 o_tp_loc = &driver->other->termios[idx];
830 o_ltp_loc = &driver->other->termios_locked[idx];
831
832 if (!*o_tty_loc && !o_tty) {
833 kdev_t o_device;
834
835 o_tty = (struct tty_struct *)
836 get_free_page(GFP_KERNEL);
837 if (!o_tty)
838 goto end_init;
839 o_device = MKDEV(driver->other->major,
840 driver->other->minor_start + idx);
841 initialize_tty_struct(o_tty);
842 o_tty->device = o_device;
843 o_tty->driver = *driver->other;
844 goto repeat;
845 }
846 if (!*o_tp_loc && !o_tp) {
847 o_tp = (struct termios *)
848 kmalloc(sizeof(struct termios), GFP_KERNEL);
849 if (!o_tp)
850 goto end_init;
851 *o_tp = driver->other->init_termios;
852 goto repeat;
853 }
854 if (!*o_ltp_loc && !o_ltp) {
855 o_ltp = (struct termios *)
856 kmalloc(sizeof(struct termios), GFP_KERNEL);
857 if (!o_ltp)
858 goto end_init;
859 memset(o_ltp, 0, sizeof(struct termios));
860 goto repeat;
861 }
862
863 }
864
865 if (!*tp_loc) {
866 *tp_loc = tp;
867 tp = NULL;
868 }
869 if (!*ltp_loc) {
870 *ltp_loc = ltp;
871 ltp = NULL;
872 }
873 if (!*tty_loc) {
874 tty->termios = *tp_loc;
875 tty->termios_locked = *ltp_loc;
876 *tty_loc = tty;
877 (*driver->refcount)++;
878 (*tty_loc)->count++;
879 if (tty->ldisc.open) {
880 retval = (tty->ldisc.open)(tty);
881 if (retval < 0) {
882 (*tty_loc)->count--;
883 tty = NULL;
884 goto end_init;
885 }
886 }
887 tty = NULL;
888 } else {
889 if ((*tty_loc)->flags & (1 << TTY_CLOSING)) {
890 printk("Attempt to open closing tty %s.\n",
891 tty_name(*tty_loc));
892 printk("Ack!!!! This should never happen!!\n");
893 return -EINVAL;
894 }
895 (*tty_loc)->count++;
896 }
897 if (driver->type == TTY_DRIVER_TYPE_PTY) {
898 if (!*o_tp_loc) {
899 *o_tp_loc = o_tp;
900 o_tp = NULL;
901 }
902 if (!*o_ltp_loc) {
903 *o_ltp_loc = o_ltp;
904 o_ltp = NULL;
905 }
906 if (!*o_tty_loc) {
907 o_tty->termios = *o_tp_loc;
908 o_tty->termios_locked = *o_ltp_loc;
909 *o_tty_loc = o_tty;
910 (*driver->other->refcount)++;
911 if (o_tty->ldisc.open) {
912 retval = (o_tty->ldisc.open)(o_tty);
913 if (retval < 0) {
914 (*tty_loc)->count--;
915 o_tty = NULL;
916 goto end_init;
917 }
918 }
919 o_tty = NULL;
920 }
921 (*tty_loc)->link = *o_tty_loc;
922 (*o_tty_loc)->link = *tty_loc;
923 if (driver->subtype == PTY_TYPE_MASTER)
924 (*o_tty_loc)->count++;
925 }
926 (*tty_loc)->driver = *driver;
927 *ret_tty = *tty_loc;
928 retval = 0;
929 end_init:
930 if (tty)
931 free_page((unsigned long) tty);
932 if (o_tty)
933 free_page((unsigned long) o_tty);
934 if (tp)
935 kfree_s(tp, sizeof(struct termios));
936 if (o_tp)
937 kfree_s(o_tp, sizeof(struct termios));
938 if (ltp)
939 kfree_s(ltp, sizeof(struct termios));
940 if (o_ltp)
941 kfree_s(o_ltp, sizeof(struct termios));
942 return retval;
943 }
944
945
946
947
948
949
950 static void release_dev(struct file * filp)
951 {
952 struct tty_struct *tty, *o_tty;
953 struct termios *tp, *o_tp, *ltp, *o_ltp;
954 struct task_struct **p;
955 int idx;
956
957 tty = (struct tty_struct *)filp->private_data;
958 if (tty_paranoia_check(tty, filp->f_inode->i_rdev, "release_dev"))
959 return;
960
961 check_tty_count(tty, "release_dev");
962
963 tty_fasync(filp->f_inode, filp, 0);
964
965 tp = tty->termios;
966 ltp = tty->termios_locked;
967
968 idx = MINOR(tty->device) - tty->driver.minor_start;
969 #ifdef TTY_PARANOIA_CHECK
970 if (idx < 0 || idx >= tty->driver.num) {
971 printk("release_dev: bad idx when trying to free (%s)\n",
972 kdevname(tty->device));
973 return;
974 }
975 if (tty != tty->driver.table[idx]) {
976 printk("release_dev: driver.table[%d] not tty for (%s)\n",
977 idx, kdevname(tty->device));
978 return;
979 }
980 if (tp != tty->driver.termios[idx]) {
981 printk("release_dev: driver.termios[%d] not termios for ("
982 "%s)\n",
983 idx, kdevname(tty->device));
984 return;
985 }
986 if (ltp != tty->driver.termios_locked[idx]) {
987 printk("release_dev: driver.termios_locked[%d] not termios_locked for ("
988 "%s)\n",
989 idx, kdevname(tty->device));
990 return;
991 }
992 #endif
993
994 #ifdef TTY_DEBUG_HANGUP
995 printk("release_dev of %s (tty count=%d)...", tty_name(tty),
996 tty->count);
997 #endif
998
999 o_tty = tty->link;
1000 o_tp = (o_tty) ? o_tty->termios : NULL;
1001 o_ltp = (o_tty) ? o_tty->termios_locked : NULL;
1002
1003 #ifdef TTY_PARANOIA_CHECK
1004 if (tty->driver.other) {
1005 if (o_tty != tty->driver.other->table[idx]) {
1006 printk("release_dev: other->table[%d] not o_tty for ("
1007 "%s)\n",
1008 idx, kdevname(tty->device));
1009 return;
1010 }
1011 if (o_tp != tty->driver.other->termios[idx]) {
1012 printk("release_dev: other->termios[%d] not o_termios for ("
1013 "%s)\n",
1014 idx, kdevname(tty->device));
1015 return;
1016 }
1017 if (o_ltp != tty->driver.other->termios_locked[idx]) {
1018 printk("release_dev: other->termios_locked[%d] not o_termios_locked for ("
1019 "%s)\n",
1020 idx, kdevname(tty->device));
1021 return;
1022 }
1023
1024 if (o_tty->link != tty) {
1025 printk("release_dev: bad pty pointers\n");
1026 return;
1027 }
1028 }
1029 #endif
1030
1031 if (tty->driver.close)
1032 tty->driver.close(tty, filp);
1033 if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
1034 tty->driver.subtype == PTY_TYPE_MASTER) {
1035 if (--tty->link->count < 0) {
1036 printk("release_dev: bad pty slave count (%d) for %s\n",
1037 tty->count, tty_name(tty));
1038 tty->link->count = 0;
1039 }
1040 }
1041 if (--tty->count < 0) {
1042 printk("release_dev: bad tty->count (%d) for %s\n",
1043 tty->count, tty_name(tty));
1044 tty->count = 0;
1045 }
1046 if (tty->count)
1047 return;
1048
1049
1050
1051
1052 if (o_tty) {
1053 if (o_tty->count)
1054 return;
1055 tty->driver.other->table[idx] = NULL;
1056 tty->driver.other->termios[idx] = NULL;
1057 kfree_s(o_tp, sizeof(struct termios));
1058 }
1059
1060 #ifdef TTY_DEBUG_HANGUP
1061 printk("freeing tty structure...");
1062 #endif
1063 tty->flags |= (1 << TTY_CLOSING);
1064
1065
1066
1067
1068
1069 for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1070 if (*p == 0)
1071 continue;
1072 if ((*p)->tty == tty)
1073 (*p)->tty = NULL;
1074 if (o_tty && (*p)->tty == o_tty)
1075 (*p)->tty = NULL;
1076 }
1077
1078
1079
1080
1081
1082 if (tty->ldisc.close)
1083 (tty->ldisc.close)(tty);
1084 tty->ldisc = ldiscs[N_TTY];
1085 tty->termios->c_line = N_TTY;
1086 if (o_tty) {
1087 if (o_tty->ldisc.close)
1088 (o_tty->ldisc.close)(o_tty);
1089 o_tty->ldisc = ldiscs[N_TTY];
1090 }
1091
1092 tty->driver.table[idx] = NULL;
1093 if (tty->driver.flags & TTY_DRIVER_RESET_TERMIOS) {
1094 tty->driver.termios[idx] = NULL;
1095 kfree_s(tp, sizeof(struct termios));
1096 }
1097 if (tty == redirect || o_tty == redirect)
1098 redirect = NULL;
1099
1100
1101
1102
1103 cli();
1104 if (tty->flip.tqueue.sync) {
1105 struct tq_struct *tq, *prev;
1106
1107 for (tq=tq_timer, prev=0; tq; prev=tq, tq=tq->next) {
1108 if (tq == &tty->flip.tqueue) {
1109 if (prev)
1110 prev->next = tq->next;
1111 else
1112 tq_timer = tq->next;
1113 break;
1114 }
1115 }
1116 }
1117 sti();
1118 tty->magic = 0;
1119 (*tty->driver.refcount)--;
1120 free_page((unsigned long) tty);
1121 filp->private_data = 0;
1122 if (o_tty) {
1123 o_tty->magic = 0;
1124 (*o_tty->driver.refcount)--;
1125 free_page((unsigned long) o_tty);
1126 }
1127 }
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141 static int tty_open(struct inode * inode, struct file * filp)
1142 {
1143 struct tty_struct *tty;
1144 int minor;
1145 int noctty, retval;
1146 kdev_t device;
1147
1148 retry_open:
1149 noctty = filp->f_flags & O_NOCTTY;
1150 device = inode->i_rdev;
1151 if (device == TTY_DEV) {
1152 if (!current->tty)
1153 return -ENXIO;
1154 device = current->tty->device;
1155
1156 }
1157 if (device == CONSOLE_DEV) {
1158 device = MKDEV(TTY_MAJOR, fg_console+1);
1159 noctty = 1;
1160 }
1161 minor = MINOR(device);
1162
1163 retval = init_dev(device, &tty);
1164 if (retval)
1165 return retval;
1166 filp->private_data = tty;
1167 check_tty_count(tty, "tty_open");
1168 if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
1169 tty->driver.subtype == PTY_TYPE_MASTER)
1170 noctty = 1;
1171 #ifdef TTY_DEBUG_HANGUP
1172 printk("opening %s...", tty_name(tty));
1173 #endif
1174 if (tty->driver.open)
1175 retval = tty->driver.open(tty, filp);
1176 else
1177 retval = -ENODEV;
1178
1179 if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !suser())
1180 retval = -EBUSY;
1181
1182 if (retval) {
1183 #ifdef TTY_DEBUG_HANGUP
1184 printk("error %d in opening %s...", retval, tty_name(tty));
1185 #endif
1186
1187 release_dev(filp);
1188 if (retval != -ERESTARTSYS)
1189 return retval;
1190 if (current->signal & ~current->blocked)
1191 return retval;
1192 schedule();
1193
1194
1195
1196 filp->f_op = &tty_fops;
1197 goto retry_open;
1198 }
1199 if (!noctty &&
1200 current->leader &&
1201 !current->tty &&
1202 tty->session == 0) {
1203 current->tty = tty;
1204 current->tty_old_pgrp = 0;
1205 tty->session = current->session;
1206 tty->pgrp = current->pgrp;
1207 }
1208 return 0;
1209 }
1210
1211
1212
1213
1214
1215
1216 static void tty_release(struct inode * inode, struct file * filp)
1217 {
1218 release_dev(filp);
1219 }
1220
1221 static int tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
1222 {
1223 struct tty_struct * tty;
1224
1225 tty = (struct tty_struct *)filp->private_data;
1226 if (tty_paranoia_check(tty, inode->i_rdev, "tty_select"))
1227 return 0;
1228
1229 if (tty->ldisc.select)
1230 return (tty->ldisc.select)(tty, inode, filp, sel_type, wait);
1231 return 0;
1232 }
1233
1234
1235
1236
1237
1238
1239 int fasync_helper(struct inode * inode, struct file * filp, int on, struct fasync_struct **fapp)
1240 {
1241 struct fasync_struct *fa, **fp;
1242 unsigned long flags;
1243
1244 for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) {
1245 if (fa->fa_file == filp)
1246 break;
1247 }
1248
1249 if (on) {
1250 if (fa)
1251 return 0;
1252 fa = (struct fasync_struct *)kmalloc(sizeof(struct fasync_struct), GFP_KERNEL);
1253 if (!fa)
1254 return -ENOMEM;
1255 fa->magic = FASYNC_MAGIC;
1256 fa->fa_file = filp;
1257 save_flags(flags);
1258 cli();
1259 fa->fa_next = *fapp;
1260 *fapp = fa;
1261 restore_flags(flags);
1262 return 1;
1263 }
1264 if (!fa)
1265 return 0;
1266 save_flags(flags);
1267 cli();
1268 *fp = fa->fa_next;
1269 restore_flags(flags);
1270 kfree(fa);
1271 return 1;
1272 }
1273
1274 static int tty_fasync(struct inode * inode, struct file * filp, int on)
1275 {
1276 struct tty_struct * tty;
1277 int retval;
1278
1279 tty = (struct tty_struct *)filp->private_data;
1280 if (tty_paranoia_check(tty, inode->i_rdev, "tty_fasync"))
1281 return 0;
1282
1283 retval = fasync_helper(inode, filp, on, &tty->fasync);
1284 if (retval <= 0)
1285 return retval;
1286
1287 if (on) {
1288 if (!tty->read_wait)
1289 tty->minimum_to_wake = 1;
1290 if (filp->f_owner == 0) {
1291 if (tty->pgrp)
1292 filp->f_owner = -tty->pgrp;
1293 else
1294 filp->f_owner = current->pid;
1295 }
1296 } else {
1297 if (!tty->fasync && !tty->read_wait)
1298 tty->minimum_to_wake = N_TTY_BUF_SIZE;
1299 }
1300 return 0;
1301 }
1302
1303 #if 0
1304
1305
1306
1307 static int do_get_ps_info(unsigned long arg)
1308 {
1309 struct tstruct {
1310 int flag;
1311 int present[NR_TASKS];
1312 struct task_struct tasks[NR_TASKS];
1313 };
1314 struct tstruct *ts = (struct tstruct *)arg;
1315 struct task_struct **p;
1316 char *c, *d;
1317 int i, n = 0;
1318
1319 i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct tstruct));
1320 if (i)
1321 return i;
1322 for (p = &FIRST_TASK ; p <= &LAST_TASK ; p++, n++)
1323 if (*p)
1324 {
1325 c = (char *)(*p);
1326 d = (char *)(ts->tasks+n);
1327 for (i=0 ; i<sizeof(struct task_struct) ; i++)
1328 put_user(*c++, d++);
1329 put_user(1, ts->present+n);
1330 }
1331 else
1332 put_user(0, ts->present+n);
1333 return(0);
1334 }
1335 #endif
1336
1337 static int tty_ioctl(struct inode * inode, struct file * file,
1338 unsigned int cmd, unsigned long arg)
1339 {
1340 int retval;
1341 struct tty_struct * tty;
1342 struct tty_struct * real_tty;
1343 struct winsize tmp_ws;
1344 pid_t pgrp;
1345 unsigned char ch;
1346 char mbz = 0;
1347
1348 tty = (struct tty_struct *)file->private_data;
1349 if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))
1350 return -EINVAL;
1351
1352 if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
1353 tty->driver.subtype == PTY_TYPE_MASTER)
1354 real_tty = tty->link;
1355 else
1356 real_tty = tty;
1357
1358 switch (cmd) {
1359 case TIOCSTI:
1360 if ((current->tty != tty) && !suser())
1361 return -EPERM;
1362 retval = verify_area(VERIFY_READ, (void *) arg, 1);
1363 if (retval)
1364 return retval;
1365 ch = get_user((char *) arg);
1366 tty->ldisc.receive_buf(tty, &ch, &mbz, 1);
1367 return 0;
1368 case TIOCGWINSZ:
1369 retval = verify_area(VERIFY_WRITE, (void *) arg,
1370 sizeof (struct winsize));
1371 if (retval)
1372 return retval;
1373 memcpy_tofs((struct winsize *) arg, &tty->winsize,
1374 sizeof (struct winsize));
1375 return 0;
1376 case TIOCSWINSZ:
1377 retval = verify_area(VERIFY_READ, (void *) arg,
1378 sizeof (struct winsize));
1379 if (retval)
1380 return retval;
1381 memcpy_fromfs(&tmp_ws, (struct winsize *) arg,
1382 sizeof (struct winsize));
1383 if (memcmp(&tmp_ws, &tty->winsize,
1384 sizeof(struct winsize))) {
1385 if (tty->pgrp > 0)
1386 kill_pg(tty->pgrp, SIGWINCH, 1);
1387 if ((real_tty->pgrp != tty->pgrp) &&
1388 (real_tty->pgrp > 0))
1389 kill_pg(real_tty->pgrp, SIGWINCH, 1);
1390 }
1391 tty->winsize = tmp_ws;
1392 real_tty->winsize = tmp_ws;
1393 return 0;
1394 case TIOCCONS:
1395 if (tty->driver.type == TTY_DRIVER_TYPE_CONSOLE) {
1396 if (!suser())
1397 return -EPERM;
1398 redirect = NULL;
1399 return 0;
1400 }
1401 if (redirect)
1402 return -EBUSY;
1403 redirect = real_tty;
1404 return 0;
1405 case FIONBIO:
1406 retval = verify_area(VERIFY_READ, (void *) arg, sizeof(int));
1407 if (retval)
1408 return retval;
1409 arg = get_user((unsigned int *) arg);
1410 if (arg)
1411 file->f_flags |= O_NONBLOCK;
1412 else
1413 file->f_flags &= ~O_NONBLOCK;
1414 return 0;
1415 case TIOCEXCL:
1416 set_bit(TTY_EXCLUSIVE, &tty->flags);
1417 return 0;
1418 case TIOCNXCL:
1419 clear_bit(TTY_EXCLUSIVE, &tty->flags);
1420 return 0;
1421 case TIOCNOTTY:
1422 if (current->tty != tty)
1423 return -ENOTTY;
1424 if (current->leader)
1425 disassociate_ctty(0);
1426 current->tty = NULL;
1427 return 0;
1428 case TIOCSCTTY:
1429 if (current->leader &&
1430 (current->session == tty->session))
1431 return 0;
1432
1433
1434
1435
1436 if (!current->leader || current->tty)
1437 return -EPERM;
1438 if (tty->session > 0) {
1439
1440
1441
1442
1443 if ((arg == 1) && suser()) {
1444
1445
1446
1447 struct task_struct *p;
1448
1449 for_each_task(p)
1450 if (p->tty == tty)
1451 p->tty = NULL;
1452 } else
1453 return -EPERM;
1454 }
1455 current->tty = tty;
1456 current->tty_old_pgrp = 0;
1457 tty->session = current->session;
1458 tty->pgrp = current->pgrp;
1459 return 0;
1460 case TIOCGPGRP:
1461
1462
1463
1464
1465 if (tty == real_tty && current->tty != real_tty)
1466 return -ENOTTY;
1467 retval = verify_area(VERIFY_WRITE, (void *) arg,
1468 sizeof (pid_t));
1469 if (retval)
1470 return retval;
1471 put_user(real_tty->pgrp, (pid_t *) arg);
1472 return 0;
1473 case TIOCSPGRP:
1474 retval = tty_check_change(real_tty);
1475 if (retval)
1476 return retval;
1477 if (!current->tty ||
1478 (current->tty != real_tty) ||
1479 (real_tty->session != current->session))
1480 return -ENOTTY;
1481 pgrp = get_user((pid_t *) arg);
1482 if (pgrp < 0)
1483 return -EINVAL;
1484 if (session_of_pgrp(pgrp) != current->session)
1485 return -EPERM;
1486 real_tty->pgrp = pgrp;
1487 return 0;
1488 case TIOCGETD:
1489 retval = verify_area(VERIFY_WRITE, (void *) arg,
1490 sizeof (int));
1491 if (retval)
1492 return retval;
1493 put_user(tty->ldisc.num, (int *) arg);
1494 return 0;
1495 case TIOCSETD:
1496 retval = tty_check_change(tty);
1497 if (retval)
1498 return retval;
1499 arg = get_user((int *) arg);
1500 return tty_set_ldisc(tty, arg);
1501 case TIOCLINUX:
1502 if (tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
1503 return -EINVAL;
1504 if (current->tty != tty && !suser())
1505 return -EPERM;
1506 retval = verify_area(VERIFY_READ, (void *) arg, 1);
1507 if (retval)
1508 return retval;
1509 switch (retval = get_user((char *)arg))
1510 {
1511 case 0:
1512 case 8:
1513 case 9:
1514 printk("TIOCLINUX (0/8/9) ioctl is gone - use /dev/vcs\n");
1515 return -EINVAL;
1516 #if 0
1517 case 1:
1518 printk("Deprecated TIOCLINUX (1) ioctl\n");
1519 return do_get_ps_info(arg);
1520 #endif
1521 case 2:
1522 return set_selection(arg, tty);
1523 case 3:
1524 return paste_selection(tty);
1525 case 4:
1526 do_unblank_screen();
1527 return 0;
1528 case 5:
1529 return sel_loadlut(arg);
1530 case 6:
1531
1532
1533
1534
1535
1536
1537 put_user(shift_state,(char *) arg);
1538 return 0;
1539 case 7:
1540 put_user(mouse_reporting(),(char *) arg);
1541 return 0;
1542 case 10:
1543 set_vesa_blanking(arg);
1544 return 0;
1545 default:
1546 return -EINVAL;
1547 }
1548
1549 case TIOCTTYGSTRUCT:
1550 retval = verify_area(VERIFY_WRITE, (void *) arg,
1551 sizeof(struct tty_struct));
1552 if (retval)
1553 return retval;
1554 memcpy_tofs((struct tty_struct *) arg,
1555 tty, sizeof(struct tty_struct));
1556 return 0;
1557 default:
1558 if (tty->driver.ioctl) {
1559 retval = (tty->driver.ioctl)(tty, file,
1560 cmd, arg);
1561 if (retval != -ENOIOCTLCMD)
1562 return retval;
1563 }
1564 if (tty->ldisc.ioctl) {
1565 retval = (tty->ldisc.ioctl)(tty, file,
1566 cmd, arg);
1567 if (retval != -ENOIOCTLCMD)
1568 return retval;
1569 }
1570 return -EINVAL;
1571 }
1572 }
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587 void do_SAK( struct tty_struct *tty)
1588 {
1589 #ifdef TTY_SOFT_SAK
1590 tty_hangup(tty);
1591 #else
1592 struct task_struct **p;
1593 int session;
1594 int i;
1595 struct file *filp;
1596
1597 if (!tty)
1598 return;
1599 session = tty->session;
1600 if (tty->ldisc.flush_buffer)
1601 tty->ldisc.flush_buffer(tty);
1602 if (tty->driver.flush_buffer)
1603 tty->driver.flush_buffer(tty);
1604 for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1605 if (!(*p))
1606 continue;
1607 if (((*p)->tty == tty) ||
1608 ((session > 0) && ((*p)->session == session)))
1609 send_sig(SIGKILL, *p, 1);
1610 else {
1611 for (i=0; i < NR_OPEN; i++) {
1612 filp = (*p)->files->fd[i];
1613 if (filp && (filp->f_op == &tty_fops) &&
1614 (filp->private_data == tty)) {
1615 send_sig(SIGKILL, *p, 1);
1616 break;
1617 }
1618 }
1619 }
1620 }
1621 #endif
1622 }
1623
1624
1625
1626
1627
1628 static void flush_to_ldisc(void *private_)
1629 {
1630 struct tty_struct *tty = (struct tty_struct *) private_;
1631 unsigned char *cp;
1632 char *fp;
1633 int count;
1634
1635 if (tty->flip.buf_num) {
1636 cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
1637 fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
1638 tty->flip.buf_num = 0;
1639
1640 cli();
1641 tty->flip.char_buf_ptr = tty->flip.char_buf;
1642 tty->flip.flag_buf_ptr = tty->flip.flag_buf;
1643 } else {
1644 cp = tty->flip.char_buf;
1645 fp = tty->flip.flag_buf;
1646 tty->flip.buf_num = 1;
1647
1648 cli();
1649 tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
1650 tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
1651 }
1652 count = tty->flip.count;
1653 tty->flip.count = 0;
1654 sti();
1655
1656 #if 0
1657 if (count > tty->max_flip_cnt)
1658 tty->max_flip_cnt = count;
1659 #endif
1660 tty->ldisc.receive_buf(tty, cp, fp, count);
1661 }
1662
1663
1664
1665
1666 static void initialize_tty_struct(struct tty_struct *tty)
1667 {
1668 memset(tty, 0, sizeof(struct tty_struct));
1669 tty->magic = TTY_MAGIC;
1670 tty->ldisc = ldiscs[N_TTY];
1671 tty->pgrp = -1;
1672 tty->flip.char_buf_ptr = tty->flip.char_buf;
1673 tty->flip.flag_buf_ptr = tty->flip.flag_buf;
1674 tty->flip.tqueue.routine = flush_to_ldisc;
1675 tty->flip.tqueue.data = tty;
1676 }
1677
1678
1679
1680
1681 void tty_default_put_char(struct tty_struct *tty, unsigned char ch)
1682 {
1683 tty->driver.write(tty, 0, &ch, 1);
1684 }
1685
1686
1687
1688
1689 int tty_register_driver(struct tty_driver *driver)
1690 {
1691 int error;
1692
1693 if (driver->flags & TTY_DRIVER_INSTALLED)
1694 return 0;
1695
1696 error = register_chrdev(driver->major, driver->name, &tty_fops);
1697 if (error < 0)
1698 return error;
1699 else if(driver->major == 0)
1700 driver->major = error;
1701
1702 if (!driver->put_char)
1703 driver->put_char = tty_default_put_char;
1704
1705 driver->prev = 0;
1706 driver->next = tty_drivers;
1707 if (tty_drivers) tty_drivers->prev = driver;
1708 tty_drivers = driver;
1709 return error;
1710 }
1711
1712
1713
1714
1715 int tty_unregister_driver(struct tty_driver *driver)
1716 {
1717 int retval;
1718 struct tty_driver *p;
1719 int found = 0;
1720 const char *othername = NULL;
1721
1722 if (*driver->refcount)
1723 return -EBUSY;
1724
1725 for (p = tty_drivers; p; p = p->next) {
1726 if (p == driver)
1727 found++;
1728 else if (p->major == driver->major)
1729 othername = p->name;
1730 }
1731
1732 if (othername == NULL) {
1733 retval = unregister_chrdev(driver->major, driver->name);
1734 if (retval)
1735 return retval;
1736 } else
1737 register_chrdev(driver->major, othername, &tty_fops);
1738
1739 if (driver->prev)
1740 driver->prev->next = driver->next;
1741 else
1742 tty_drivers = driver->next;
1743
1744 if (driver->next)
1745 driver->next->prev = driver->prev;
1746
1747 return 0;
1748 }
1749
1750
1751
1752
1753
1754
1755
1756
1757 long console_init(long kmem_start, long kmem_end)
1758 {
1759
1760 memset(ldiscs, 0, sizeof(ldiscs));
1761 (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
1762
1763
1764
1765
1766
1767 memset(&tty_std_termios, 0, sizeof(struct termios));
1768 memcpy(tty_std_termios.c_cc, INIT_C_CC, NCCS);
1769 tty_std_termios.c_iflag = ICRNL | IXON;
1770 tty_std_termios.c_oflag = OPOST | ONLCR;
1771 tty_std_termios.c_cflag = B38400 | CS8 | CREAD;
1772 tty_std_termios.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
1773 ECHOCTL | ECHOKE | IEXTEN;
1774
1775
1776
1777
1778
1779 return con_init(kmem_start);
1780 }
1781
1782
1783
1784
1785
1786 int tty_init(void)
1787 {
1788 if (sizeof(struct tty_struct) > PAGE_SIZE)
1789 panic("size of tty structure > PAGE_SIZE!");
1790 kbd_init();
1791 rs_init();
1792 #ifdef CONFIG_SCC
1793 scc_init();
1794 #endif
1795 #ifdef CONFIG_CYCLADES
1796 cy_init();
1797 #endif
1798 #ifdef CONFIG_STALLION
1799 stl_init();
1800 #endif
1801 #ifdef CONFIG_ISTALLION
1802 stli_init();
1803 #endif
1804 pty_init();
1805 vcs_init();
1806 if (register_chrdev(TTY_MAJOR,"tty",&tty_fops))
1807 panic("unable to get major %d for tty device", TTY_MAJOR);
1808 if (register_chrdev(TTYAUX_MAJOR,"cua",&tty_fops))
1809 panic("unable to get major %d for tty device", TTYAUX_MAJOR);
1810
1811 return 0;
1812 }