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