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