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