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