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