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