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