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