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