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