aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/vt
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/tty/vt
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/tty/vt')
-rw-r--r--drivers/tty/vt/consolemap.c178
-rw-r--r--drivers/tty/vt/keyboard.c848
-rw-r--r--drivers/tty/vt/selection.c65
-rw-r--r--drivers/tty/vt/vc_screen.c5
-rw-r--r--drivers/tty/vt/vt.c299
-rw-r--r--drivers/tty/vt/vt_ioctl.c523
6 files changed, 711 insertions, 1207 deletions
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c
index 248381b3072..45d3e80156d 100644
--- a/drivers/tty/vt/consolemap.c
+++ b/drivers/tty/vt/consolemap.c
@@ -19,7 +19,6 @@
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/tty.h> 20#include <linux/tty.h>
21#include <asm/uaccess.h> 21#include <asm/uaccess.h>
22#include <linux/console.h>
23#include <linux/consolemap.h> 22#include <linux/consolemap.h>
24#include <linux/vt_kern.h> 23#include <linux/vt_kern.h>
25 24
@@ -313,7 +312,6 @@ int con_set_trans_old(unsigned char __user * arg)
313 if (!access_ok(VERIFY_READ, arg, E_TABSZ)) 312 if (!access_ok(VERIFY_READ, arg, E_TABSZ))
314 return -EFAULT; 313 return -EFAULT;
315 314
316 console_lock();
317 for (i=0; i<E_TABSZ ; i++) { 315 for (i=0; i<E_TABSZ ; i++) {
318 unsigned char uc; 316 unsigned char uc;
319 __get_user(uc, arg+i); 317 __get_user(uc, arg+i);
@@ -321,7 +319,6 @@ int con_set_trans_old(unsigned char __user * arg)
321 } 319 }
322 320
323 update_user_maps(); 321 update_user_maps();
324 console_unlock();
325 return 0; 322 return 0;
326} 323}
327 324
@@ -333,13 +330,11 @@ int con_get_trans_old(unsigned char __user * arg)
333 if (!access_ok(VERIFY_WRITE, arg, E_TABSZ)) 330 if (!access_ok(VERIFY_WRITE, arg, E_TABSZ))
334 return -EFAULT; 331 return -EFAULT;
335 332
336 console_lock();
337 for (i=0; i<E_TABSZ ; i++) 333 for (i=0; i<E_TABSZ ; i++)
338 { 334 {
339 ch = conv_uni_to_pc(vc_cons[fg_console].d, p[i]); 335 ch = conv_uni_to_pc(vc_cons[fg_console].d, p[i]);
340 __put_user((ch & ~0xff) ? 0 : ch, arg+i); 336 __put_user((ch & ~0xff) ? 0 : ch, arg+i);
341 } 337 }
342 console_unlock();
343 return 0; 338 return 0;
344} 339}
345 340
@@ -351,7 +346,6 @@ int con_set_trans_new(ushort __user * arg)
351 if (!access_ok(VERIFY_READ, arg, E_TABSZ*sizeof(unsigned short))) 346 if (!access_ok(VERIFY_READ, arg, E_TABSZ*sizeof(unsigned short)))
352 return -EFAULT; 347 return -EFAULT;
353 348
354 console_lock();
355 for (i=0; i<E_TABSZ ; i++) { 349 for (i=0; i<E_TABSZ ; i++) {
356 unsigned short us; 350 unsigned short us;
357 __get_user(us, arg+i); 351 __get_user(us, arg+i);
@@ -359,7 +353,6 @@ int con_set_trans_new(ushort __user * arg)
359 } 353 }
360 354
361 update_user_maps(); 355 update_user_maps();
362 console_unlock();
363 return 0; 356 return 0;
364} 357}
365 358
@@ -371,10 +364,8 @@ int con_get_trans_new(ushort __user * arg)
371 if (!access_ok(VERIFY_WRITE, arg, E_TABSZ*sizeof(unsigned short))) 364 if (!access_ok(VERIFY_WRITE, arg, E_TABSZ*sizeof(unsigned short)))
372 return -EFAULT; 365 return -EFAULT;
373 366
374 console_lock();
375 for (i=0; i<E_TABSZ ; i++) 367 for (i=0; i<E_TABSZ ; i++)
376 __put_user(p[i], arg+i); 368 __put_user(p[i], arg+i);
377 console_unlock();
378 369
379 return 0; 370 return 0;
380} 371}
@@ -410,11 +401,12 @@ static void con_release_unimap(struct uni_pagedir *p)
410 kfree(p->inverse_translations[i]); 401 kfree(p->inverse_translations[i]);
411 p->inverse_translations[i] = NULL; 402 p->inverse_translations[i] = NULL;
412 } 403 }
413 kfree(p->inverse_trans_unicode); 404 if (p->inverse_trans_unicode) {
414 p->inverse_trans_unicode = NULL; 405 kfree(p->inverse_trans_unicode);
406 p->inverse_trans_unicode = NULL;
407 }
415} 408}
416 409
417/* Caller must hold the console lock */
418void con_free_unimap(struct vc_data *vc) 410void con_free_unimap(struct vc_data *vc)
419{ 411{
420 struct uni_pagedir *p; 412 struct uni_pagedir *p;
@@ -495,21 +487,17 @@ con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos)
495 return 0; 487 return 0;
496} 488}
497 489
498/* ui is a leftover from using a hashtable, but might be used again 490/* ui is a leftover from using a hashtable, but might be used again */
499 Caller must hold the lock */ 491int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
500static int con_do_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
501{ 492{
502 struct uni_pagedir *p, *q; 493 struct uni_pagedir *p, *q;
503 494
504 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; 495 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
505 if (p && p->readonly) 496 if (p && p->readonly) return -EIO;
506 return -EIO;
507
508 if (!p || --p->refcount) { 497 if (!p || --p->refcount) {
509 q = kzalloc(sizeof(*p), GFP_KERNEL); 498 q = kzalloc(sizeof(*p), GFP_KERNEL);
510 if (!q) { 499 if (!q) {
511 if (p) 500 if (p) p->refcount++;
512 p->refcount++;
513 return -ENOMEM; 501 return -ENOMEM;
514 } 502 }
515 q->refcount=1; 503 q->refcount=1;
@@ -523,96 +511,43 @@ static int con_do_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
523 return 0; 511 return 0;
524} 512}
525 513
526int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
527{
528 int ret;
529 console_lock();
530 ret = con_do_clear_unimap(vc, ui);
531 console_unlock();
532 return ret;
533}
534
535int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) 514int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
536{ 515{
537 int err = 0, err1, i; 516 int err = 0, err1, i;
538 struct uni_pagedir *p, *q; 517 struct uni_pagedir *p, *q;
539 518
540 console_lock();
541
542 /* Save original vc_unipagdir_loc in case we allocate a new one */
543 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; 519 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
544 if (p->readonly) { 520 if (p->readonly) return -EIO;
545 console_unlock();
546 return -EIO;
547 }
548 521
549 if (!ct) { 522 if (!ct) return 0;
550 console_unlock();
551 return 0;
552 }
553 523
554 if (p->refcount > 1) { 524 if (p->refcount > 1) {
555 int j, k; 525 int j, k;
556 u16 **p1, *p2, l; 526 u16 **p1, *p2, l;
557 527
558 err1 = con_do_clear_unimap(vc, NULL); 528 err1 = con_clear_unimap(vc, NULL);
559 if (err1) { 529 if (err1) return err1;
560 console_unlock();
561 return err1;
562 }
563 530
564 /*
565 * Since refcount was > 1, con_clear_unimap() allocated a
566 * a new uni_pagedir for this vc. Re: p != q
567 */
568 q = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; 531 q = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
569 532 for (i = 0, l = 0; i < 32; i++)
570 /*
571 * uni_pgdir is a 32*32*64 table with rows allocated
572 * when its first entry is added. The unicode value must
573 * still be incremented for empty rows. We are copying
574 * entries from "p" (old) to "q" (new).
575 */
576 l = 0; /* unicode value */
577 for (i = 0; i < 32; i++)
578 if ((p1 = p->uni_pgdir[i])) 533 if ((p1 = p->uni_pgdir[i]))
579 for (j = 0; j < 32; j++) 534 for (j = 0; j < 32; j++)
580 if ((p2 = p1[j])) { 535 if ((p2 = p1[j]))
581 for (k = 0; k < 64; k++, l++) 536 for (k = 0; k < 64; k++, l++)
582 if (p2[k] != 0xffff) { 537 if (p2[k] != 0xffff) {
583 /*
584 * Found one, copy entry for unicode
585 * l with fontpos value p2[k].
586 */
587 err1 = con_insert_unipair(q, l, p2[k]); 538 err1 = con_insert_unipair(q, l, p2[k]);
588 if (err1) { 539 if (err1) {
589 p->refcount++; 540 p->refcount++;
590 *vc->vc_uni_pagedir_loc = (unsigned long)p; 541 *vc->vc_uni_pagedir_loc = (unsigned long)p;
591 con_release_unimap(q); 542 con_release_unimap(q);
592 kfree(q); 543 kfree(q);
593 console_unlock();
594 return err1; 544 return err1;
595 } 545 }
596 } 546 }
597 } else { 547 p = q;
598 /* Account for row of 64 empty entries */ 548 } else if (p == dflt)
599 l += 64;
600 }
601 else
602 /* Account for empty table */
603 l += 32 * 64;
604
605 /*
606 * Finished copying font table, set vc_uni_pagedir to new table
607 */
608 p = q;
609 } else if (p == dflt) {
610 dflt = NULL; 549 dflt = NULL;
611 } 550
612
613 /*
614 * Insert user specified unicode pairs into new table.
615 */
616 while (ct--) { 551 while (ct--) {
617 unsigned short unicode, fontpos; 552 unsigned short unicode, fontpos;
618 __get_user(unicode, &list->unicode); 553 __get_user(unicode, &list->unicode);
@@ -622,33 +557,21 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
622 list++; 557 list++;
623 } 558 }
624 559
625 /* 560 if (con_unify_unimap(vc, p))
626 * Merge with fontmaps of any other virtual consoles.
627 */
628 if (con_unify_unimap(vc, p)) {
629 console_unlock();
630 return err; 561 return err;
631 }
632 562
633 for (i = 0; i <= 3; i++) 563 for (i = 0; i <= 3; i++)
634 set_inverse_transl(vc, p, i); /* Update inverse translations */ 564 set_inverse_transl(vc, p, i); /* Update all inverse translations */
635 set_inverse_trans_unicode(vc, p); 565 set_inverse_trans_unicode(vc, p);
636 566
637 console_unlock();
638 return err; 567 return err;
639} 568}
640 569
641/** 570/* Loads the unimap for the hardware font, as defined in uni_hash.tbl.
642 * con_set_default_unimap - set default unicode map 571 The representation used was the most compact I could come up
643 * @vc: the console we are updating 572 with. This routine is executed at sys_setup time, and when the
644 * 573 PIO_FONTRESET ioctl is called. */
645 * Loads the unimap for the hardware font, as defined in uni_hash.tbl. 574
646 * The representation used was the most compact I could come up
647 * with. This routine is executed at video setup, and when the
648 * PIO_FONTRESET ioctl is called.
649 *
650 * The caller must hold the console lock
651 */
652int con_set_default_unimap(struct vc_data *vc) 575int con_set_default_unimap(struct vc_data *vc)
653{ 576{
654 int i, j, err = 0, err1; 577 int i, j, err = 0, err1;
@@ -659,10 +582,9 @@ int con_set_default_unimap(struct vc_data *vc)
659 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; 582 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
660 if (p == dflt) 583 if (p == dflt)
661 return 0; 584 return 0;
662
663 dflt->refcount++; 585 dflt->refcount++;
664 *vc->vc_uni_pagedir_loc = (unsigned long)dflt; 586 *vc->vc_uni_pagedir_loc = (unsigned long)dflt;
665 if (p && !--p->refcount) { 587 if (p && --p->refcount) {
666 con_release_unimap(p); 588 con_release_unimap(p);
667 kfree(p); 589 kfree(p);
668 } 590 }
@@ -671,9 +593,8 @@ int con_set_default_unimap(struct vc_data *vc)
671 593
672 /* The default font is always 256 characters */ 594 /* The default font is always 256 characters */
673 595
674 err = con_do_clear_unimap(vc, NULL); 596 err = con_clear_unimap(vc, NULL);
675 if (err) 597 if (err) return err;
676 return err;
677 598
678 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; 599 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
679 q = dfont_unitable; 600 q = dfont_unitable;
@@ -698,13 +619,6 @@ int con_set_default_unimap(struct vc_data *vc)
698} 619}
699EXPORT_SYMBOL(con_set_default_unimap); 620EXPORT_SYMBOL(con_set_default_unimap);
700 621
701/**
702 * con_copy_unimap - copy unimap between two vts
703 * @dst_vc: target
704 * @src_vt: source
705 *
706 * The caller must hold the console lock when invoking this method
707 */
708int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc) 622int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
709{ 623{
710 struct uni_pagedir *q; 624 struct uni_pagedir *q;
@@ -719,23 +633,13 @@ int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
719 *dst_vc->vc_uni_pagedir_loc = (long)q; 633 *dst_vc->vc_uni_pagedir_loc = (long)q;
720 return 0; 634 return 0;
721} 635}
722EXPORT_SYMBOL(con_copy_unimap);
723 636
724/**
725 * con_get_unimap - get the unicode map
726 * @vc: the console to read from
727 *
728 * Read the console unicode data for this console. Called from the ioctl
729 * handlers.
730 */
731int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list) 637int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list)
732{ 638{
733 int i, j, k, ect; 639 int i, j, k, ect;
734 u16 **p1, *p2; 640 u16 **p1, *p2;
735 struct uni_pagedir *p; 641 struct uni_pagedir *p;
736 642
737 console_lock();
738
739 ect = 0; 643 ect = 0;
740 if (*vc->vc_uni_pagedir_loc) { 644 if (*vc->vc_uni_pagedir_loc) {
741 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; 645 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
@@ -755,19 +659,22 @@ int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct uni
755 } 659 }
756 } 660 }
757 __put_user(ect, uct); 661 __put_user(ect, uct);
758 console_unlock();
759 return ((ect <= ct) ? 0 : -ENOMEM); 662 return ((ect <= ct) ? 0 : -ENOMEM);
760} 663}
761 664
665void con_protect_unimap(struct vc_data *vc, int rdonly)
666{
667 struct uni_pagedir *p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
668
669 if (p)
670 p->readonly = rdonly;
671}
672
762/* 673/*
763 * Always use USER_MAP. These functions are used by the keyboard, 674 * Always use USER_MAP. These functions are used by the keyboard,
764 * which shouldn't be affected by G0/G1 switching, etc. 675 * which shouldn't be affected by G0/G1 switching, etc.
765 * If the user map still contains default values, i.e. the 676 * If the user map still contains default values, i.e. the
766 * direct-to-font mapping, then assume user is using Latin1. 677 * direct-to-font mapping, then assume user is using Latin1.
767 *
768 * FIXME: at some point we need to decide if we want to lock the table
769 * update element itself via the keyboard_event_lock for consistency with the
770 * keyboard driver as well as the consoles
771 */ 678 */
772/* may be called during an interrupt */ 679/* may be called during an interrupt */
773u32 conv_8bit_to_uni(unsigned char c) 680u32 conv_8bit_to_uni(unsigned char c)
@@ -835,3 +742,4 @@ console_map_init(void)
835 con_set_default_unimap(vc_cons[i].d); 742 con_set_default_unimap(vc_cons[i].d);
836} 743}
837 744
745EXPORT_SYMBOL(con_copy_unimap);
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 681765baef6..3761ccf0f34 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -33,6 +33,7 @@
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/irq.h>
36 37
37#include <linux/kbd_kern.h> 38#include <linux/kbd_kern.h>
38#include <linux/kbd_diacr.h> 39#include <linux/kbd_diacr.h>
@@ -41,9 +42,6 @@
41#include <linux/reboot.h> 42#include <linux/reboot.h>
42#include <linux/notifier.h> 43#include <linux/notifier.h>
43#include <linux/jiffies.h> 44#include <linux/jiffies.h>
44#include <linux/uaccess.h>
45
46#include <asm/irq_regs.h>
47 45
48extern void ctrl_alt_del(void); 46extern void ctrl_alt_del(void);
49 47
@@ -53,17 +51,23 @@ extern void ctrl_alt_del(void);
53 51
54#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META)) 52#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
55 53
56#if defined(CONFIG_X86) || defined(CONFIG_PARISC) 54/*
57#include <asm/kbdleds.h> 55 * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
56 * This seems a good reason to start with NumLock off. On HIL keyboards
57 * of PARISC machines however there is no NumLock key and everyone expects the keypad
58 * to be used for numbers.
59 */
60
61#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
62#define KBD_DEFLEDS (1 << VC_NUMLOCK)
58#else 63#else
59static inline int kbd_defleds(void) 64#define KBD_DEFLEDS 0
60{
61 return 0;
62}
63#endif 65#endif
64 66
65#define KBD_DEFLOCK 0 67#define KBD_DEFLOCK 0
66 68
69void compute_shiftstate(void);
70
67/* 71/*
68 * Handler Tables. 72 * Handler Tables.
69 */ 73 */
@@ -94,32 +98,37 @@ static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
94 * Variables exported for vt_ioctl.c 98 * Variables exported for vt_ioctl.c
95 */ 99 */
96 100
101/* maximum values each key_handler can handle */
102const int max_vals[] = {
103 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
104 NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
105 255, NR_LOCK - 1, 255, NR_BRL - 1
106};
107
108const int NR_TYPES = ARRAY_SIZE(max_vals);
109
110struct kbd_struct kbd_table[MAX_NR_CONSOLES];
111EXPORT_SYMBOL_GPL(kbd_table);
112static struct kbd_struct *kbd = kbd_table;
113
97struct vt_spawn_console vt_spawn_con = { 114struct vt_spawn_console vt_spawn_con = {
98 .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock), 115 .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock),
99 .pid = NULL, 116 .pid = NULL,
100 .sig = 0, 117 .sig = 0,
101}; 118};
102 119
103
104/* 120/*
105 * Internal Data. 121 * Variables exported for vt.c
106 */ 122 */
107 123
108static struct kbd_struct kbd_table[MAX_NR_CONSOLES]; 124int shift_state = 0;
109static struct kbd_struct *kbd = kbd_table;
110 125
111/* maximum values each key_handler can handle */ 126/*
112static const int max_vals[] = { 127 * Internal Data.
113 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1, 128 */
114 NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
115 255, NR_LOCK - 1, 255, NR_BRL - 1
116};
117
118static const int NR_TYPES = ARRAY_SIZE(max_vals);
119 129
120static struct input_handler kbd_handler; 130static struct input_handler kbd_handler;
121static DEFINE_SPINLOCK(kbd_event_lock); 131static DEFINE_SPINLOCK(kbd_event_lock);
122static DEFINE_SPINLOCK(led_lock);
123static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ 132static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
124static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ 133static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
125static bool dead_key_next; 134static bool dead_key_next;
@@ -127,8 +136,6 @@ static int npadch = -1; /* -1 or number assembled on pad */
127static unsigned int diacr; 136static unsigned int diacr;
128static char rep; /* flag telling character repeat */ 137static char rep; /* flag telling character repeat */
129 138
130static int shift_state = 0;
131
132static unsigned char ledstate = 0xff; /* undefined */ 139static unsigned char ledstate = 0xff; /* undefined */
133static unsigned char ledioctl; 140static unsigned char ledioctl;
134 141
@@ -179,7 +186,7 @@ static int getkeycode_helper(struct input_handle *handle, void *data)
179 return d->error == 0; /* stop as soon as we successfully get one */ 186 return d->error == 0; /* stop as soon as we successfully get one */
180} 187}
181 188
182static int getkeycode(unsigned int scancode) 189int getkeycode(unsigned int scancode)
183{ 190{
184 struct getset_keycode_data d = { 191 struct getset_keycode_data d = {
185 .ke = { 192 .ke = {
@@ -206,7 +213,7 @@ static int setkeycode_helper(struct input_handle *handle, void *data)
206 return d->error == 0; /* stop as soon as we successfully set one */ 213 return d->error == 0; /* stop as soon as we successfully set one */
207} 214}
208 215
209static int setkeycode(unsigned int scancode, unsigned int keycode) 216int setkeycode(unsigned int scancode, unsigned int keycode)
210{ 217{
211 struct getset_keycode_data d = { 218 struct getset_keycode_data d = {
212 .ke = { 219 .ke = {
@@ -311,7 +318,7 @@ static void put_queue(struct vc_data *vc, int ch)
311 318
312 if (tty) { 319 if (tty) {
313 tty_insert_flip_char(tty, ch, 0); 320 tty_insert_flip_char(tty, ch, 0);
314 tty_schedule_flip(tty); 321 con_schedule_flip(tty);
315 } 322 }
316} 323}
317 324
@@ -326,7 +333,7 @@ static void puts_queue(struct vc_data *vc, char *cp)
326 tty_insert_flip_char(tty, *cp, 0); 333 tty_insert_flip_char(tty, *cp, 0);
327 cp++; 334 cp++;
328 } 335 }
329 tty_schedule_flip(tty); 336 con_schedule_flip(tty);
330} 337}
331 338
332static void applkey(struct vc_data *vc, int key, char mode) 339static void applkey(struct vc_data *vc, int key, char mode)
@@ -374,11 +381,9 @@ static void to_utf8(struct vc_data *vc, uint c)
374/* 381/*
375 * Called after returning from RAW mode or when changing consoles - recompute 382 * Called after returning from RAW mode or when changing consoles - recompute
376 * shift_down[] and shift_state from key_down[] maybe called when keymap is 383 * shift_down[] and shift_state from key_down[] maybe called when keymap is
377 * undefined, so that shiftkey release is seen. The caller must hold the 384 * undefined, so that shiftkey release is seen
378 * kbd_event_lock.
379 */ 385 */
380 386void compute_shiftstate(void)
381static void do_compute_shiftstate(void)
382{ 387{
383 unsigned int i, j, k, sym, val; 388 unsigned int i, j, k, sym, val;
384 389
@@ -411,15 +416,6 @@ static void do_compute_shiftstate(void)
411 } 416 }
412} 417}
413 418
414/* We still have to export this method to vt.c */
415void compute_shiftstate(void)
416{
417 unsigned long flags;
418 spin_lock_irqsave(&kbd_event_lock, flags);
419 do_compute_shiftstate();
420 spin_unlock_irqrestore(&kbd_event_lock, flags);
421}
422
423/* 419/*
424 * We have a combining character DIACR here, followed by the character CH. 420 * We have a combining character DIACR here, followed by the character CH.
425 * If the combination occurs in the table, return the corresponding value. 421 * If the combination occurs in the table, return the corresponding value.
@@ -587,7 +583,7 @@ static void fn_send_intr(struct vc_data *vc)
587 if (!tty) 583 if (!tty)
588 return; 584 return;
589 tty_insert_flip_char(tty, 0, TTY_BREAK); 585 tty_insert_flip_char(tty, 0, TTY_BREAK);
590 tty_schedule_flip(tty); 586 con_schedule_flip(tty);
591} 587}
592 588
593static void fn_scroll_forw(struct vc_data *vc) 589static void fn_scroll_forw(struct vc_data *vc)
@@ -639,7 +635,7 @@ static void fn_SAK(struct vc_data *vc)
639 635
640static void fn_null(struct vc_data *vc) 636static void fn_null(struct vc_data *vc)
641{ 637{
642 do_compute_shiftstate(); 638 compute_shiftstate();
643} 639}
644 640
645/* 641/*
@@ -985,15 +981,13 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
985 * or (ii) whatever pattern of lights people want to show using KDSETLED, 981 * or (ii) whatever pattern of lights people want to show using KDSETLED,
986 * or (iii) specified bits of specified words in kernel memory. 982 * or (iii) specified bits of specified words in kernel memory.
987 */ 983 */
988static unsigned char getledstate(void) 984unsigned char getledstate(void)
989{ 985{
990 return ledstate; 986 return ledstate;
991} 987}
992 988
993void setledstate(struct kbd_struct *kbd, unsigned int led) 989void setledstate(struct kbd_struct *kbd, unsigned int led)
994{ 990{
995 unsigned long flags;
996 spin_lock_irqsave(&led_lock, flags);
997 if (!(led & ~7)) { 991 if (!(led & ~7)) {
998 ledioctl = led; 992 ledioctl = led;
999 kbd->ledmode = LED_SHOW_IOCTL; 993 kbd->ledmode = LED_SHOW_IOCTL;
@@ -1001,7 +995,6 @@ void setledstate(struct kbd_struct *kbd, unsigned int led)
1001 kbd->ledmode = LED_SHOW_FLAGS; 995 kbd->ledmode = LED_SHOW_FLAGS;
1002 996
1003 set_leds(); 997 set_leds();
1004 spin_unlock_irqrestore(&led_lock, flags);
1005} 998}
1006 999
1007static inline unsigned char getleds(void) 1000static inline unsigned char getleds(void)
@@ -1041,96 +1034,16 @@ static int kbd_update_leds_helper(struct input_handle *handle, void *data)
1041 return 0; 1034 return 0;
1042} 1035}
1043 1036
1044/**
1045 * vt_get_leds - helper for braille console
1046 * @console: console to read
1047 * @flag: flag we want to check
1048 *
1049 * Check the status of a keyboard led flag and report it back
1050 */
1051int vt_get_leds(int console, int flag)
1052{
1053 struct kbd_struct * kbd = kbd_table + console;
1054 int ret;
1055 unsigned long flags;
1056
1057 spin_lock_irqsave(&led_lock, flags);
1058 ret = vc_kbd_led(kbd, flag);
1059 spin_unlock_irqrestore(&led_lock, flags);
1060
1061 return ret;
1062}
1063EXPORT_SYMBOL_GPL(vt_get_leds);
1064
1065/**
1066 * vt_set_led_state - set LED state of a console
1067 * @console: console to set
1068 * @leds: LED bits
1069 *
1070 * Set the LEDs on a console. This is a wrapper for the VT layer
1071 * so that we can keep kbd knowledge internal
1072 */
1073void vt_set_led_state(int console, int leds)
1074{
1075 struct kbd_struct * kbd = kbd_table + console;
1076 setledstate(kbd, leds);
1077}
1078
1079/**
1080 * vt_kbd_con_start - Keyboard side of console start
1081 * @console: console
1082 *
1083 * Handle console start. This is a wrapper for the VT layer
1084 * so that we can keep kbd knowledge internal
1085 *
1086 * FIXME: We eventually need to hold the kbd lock here to protect
1087 * the LED updating. We can't do it yet because fn_hold calls stop_tty
1088 * and start_tty under the kbd_event_lock, while normal tty paths
1089 * don't hold the lock. We probably need to split out an LED lock
1090 * but not during an -rc release!
1091 */
1092void vt_kbd_con_start(int console)
1093{
1094 struct kbd_struct * kbd = kbd_table + console;
1095 unsigned long flags;
1096 spin_lock_irqsave(&led_lock, flags);
1097 clr_vc_kbd_led(kbd, VC_SCROLLOCK);
1098 set_leds();
1099 spin_unlock_irqrestore(&led_lock, flags);
1100}
1101
1102/**
1103 * vt_kbd_con_stop - Keyboard side of console stop
1104 * @console: console
1105 *
1106 * Handle console stop. This is a wrapper for the VT layer
1107 * so that we can keep kbd knowledge internal
1108 */
1109void vt_kbd_con_stop(int console)
1110{
1111 struct kbd_struct * kbd = kbd_table + console;
1112 unsigned long flags;
1113 spin_lock_irqsave(&led_lock, flags);
1114 set_vc_kbd_led(kbd, VC_SCROLLOCK);
1115 set_leds();
1116 spin_unlock_irqrestore(&led_lock, flags);
1117}
1118
1119/* 1037/*
1120 * This is the tasklet that updates LED state on all keyboards 1038 * This is the tasklet that updates LED state on all keyboards
1121 * attached to the box. The reason we use tasklet is that we 1039 * attached to the box. The reason we use tasklet is that we
1122 * need to handle the scenario when keyboard handler is not 1040 * need to handle the scenario when keyboard handler is not
1123 * registered yet but we already getting updates from the VT to 1041 * registered yet but we already getting updates form VT to
1124 * update led state. 1042 * update led state.
1125 */ 1043 */
1126static void kbd_bh(unsigned long dummy) 1044static void kbd_bh(unsigned long dummy)
1127{ 1045{
1128 unsigned char leds; 1046 unsigned char leds = getleds();
1129 unsigned long flags;
1130
1131 spin_lock_irqsave(&led_lock, flags);
1132 leds = getleds();
1133 spin_unlock_irqrestore(&led_lock, flags);
1134 1047
1135 if (leds != ledstate) { 1048 if (leds != ledstate) {
1136 input_handler_for_each_handle(&kbd_handler, &leds, 1049 input_handler_for_each_handle(&kbd_handler, &leds,
@@ -1340,7 +1253,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
1340 if (rc == NOTIFY_STOP || !key_map) { 1253 if (rc == NOTIFY_STOP || !key_map) {
1341 atomic_notifier_call_chain(&keyboard_notifier_list, 1254 atomic_notifier_call_chain(&keyboard_notifier_list,
1342 KBD_UNBOUND_KEYCODE, &param); 1255 KBD_UNBOUND_KEYCODE, &param);
1343 do_compute_shiftstate(); 1256 compute_shiftstate();
1344 kbd->slockstate = 0; 1257 kbd->slockstate = 0;
1345 return; 1258 return;
1346 } 1259 }
@@ -1490,14 +1403,14 @@ static void kbd_start(struct input_handle *handle)
1490 1403
1491static const struct input_device_id kbd_ids[] = { 1404static const struct input_device_id kbd_ids[] = {
1492 { 1405 {
1493 .flags = INPUT_DEVICE_ID_MATCH_EVBIT, 1406 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1494 .evbit = { BIT_MASK(EV_KEY) }, 1407 .evbit = { BIT_MASK(EV_KEY) },
1495 }, 1408 },
1496 1409
1497 { 1410 {
1498 .flags = INPUT_DEVICE_ID_MATCH_EVBIT, 1411 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1499 .evbit = { BIT_MASK(EV_SND) }, 1412 .evbit = { BIT_MASK(EV_SND) },
1500 }, 1413 },
1501 1414
1502 { }, /* Terminating entry */ 1415 { }, /* Terminating entry */
1503}; 1416};
@@ -1519,9 +1432,9 @@ int __init kbd_init(void)
1519 int i; 1432 int i;
1520 int error; 1433 int error;
1521 1434
1522 for (i = 0; i < MAX_NR_CONSOLES; i++) { 1435 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1523 kbd_table[i].ledflagstate = kbd_defleds(); 1436 kbd_table[i].ledflagstate = KBD_DEFLEDS;
1524 kbd_table[i].default_ledflagstate = kbd_defleds(); 1437 kbd_table[i].default_ledflagstate = KBD_DEFLEDS;
1525 kbd_table[i].ledmode = LED_SHOW_FLAGS; 1438 kbd_table[i].ledmode = LED_SHOW_FLAGS;
1526 kbd_table[i].lockstate = KBD_DEFLOCK; 1439 kbd_table[i].lockstate = KBD_DEFLOCK;
1527 kbd_table[i].slockstate = 0; 1440 kbd_table[i].slockstate = 0;
@@ -1538,660 +1451,3 @@ int __init kbd_init(void)
1538 1451
1539 return 0; 1452 return 0;
1540} 1453}
1541
1542/* Ioctl support code */
1543
1544/**
1545 * vt_do_diacrit - diacritical table updates
1546 * @cmd: ioctl request
1547 * @up: pointer to user data for ioctl
1548 * @perm: permissions check computed by caller
1549 *
1550 * Update the diacritical tables atomically and safely. Lock them
1551 * against simultaneous keypresses
1552 */
1553int vt_do_diacrit(unsigned int cmd, void __user *up, int perm)
1554{
1555 struct kbdiacrs __user *a = up;
1556 unsigned long flags;
1557 int asize;
1558 int ret = 0;
1559
1560 switch (cmd) {
1561 case KDGKBDIACR:
1562 {
1563 struct kbdiacr *diacr;
1564 int i;
1565
1566 diacr = kmalloc(MAX_DIACR * sizeof(struct kbdiacr),
1567 GFP_KERNEL);
1568 if (diacr == NULL)
1569 return -ENOMEM;
1570
1571 /* Lock the diacriticals table, make a copy and then
1572 copy it after we unlock */
1573 spin_lock_irqsave(&kbd_event_lock, flags);
1574
1575 asize = accent_table_size;
1576 for (i = 0; i < asize; i++) {
1577 diacr[i].diacr = conv_uni_to_8bit(
1578 accent_table[i].diacr);
1579 diacr[i].base = conv_uni_to_8bit(
1580 accent_table[i].base);
1581 diacr[i].result = conv_uni_to_8bit(
1582 accent_table[i].result);
1583 }
1584 spin_unlock_irqrestore(&kbd_event_lock, flags);
1585
1586 if (put_user(asize, &a->kb_cnt))
1587 ret = -EFAULT;
1588 else if (copy_to_user(a->kbdiacr, diacr,
1589 asize * sizeof(struct kbdiacr)))
1590 ret = -EFAULT;
1591 kfree(diacr);
1592 return ret;
1593 }
1594 case KDGKBDIACRUC:
1595 {
1596 struct kbdiacrsuc __user *a = up;
1597 void *buf;
1598
1599 buf = kmalloc(MAX_DIACR * sizeof(struct kbdiacruc),
1600 GFP_KERNEL);
1601 if (buf == NULL)
1602 return -ENOMEM;
1603
1604 /* Lock the diacriticals table, make a copy and then
1605 copy it after we unlock */
1606 spin_lock_irqsave(&kbd_event_lock, flags);
1607
1608 asize = accent_table_size;
1609 memcpy(buf, accent_table, asize * sizeof(struct kbdiacruc));
1610
1611 spin_unlock_irqrestore(&kbd_event_lock, flags);
1612
1613 if (put_user(asize, &a->kb_cnt))
1614 ret = -EFAULT;
1615 else if (copy_to_user(a->kbdiacruc, buf,
1616 asize*sizeof(struct kbdiacruc)))
1617 ret = -EFAULT;
1618 kfree(buf);
1619 return ret;
1620 }
1621
1622 case KDSKBDIACR:
1623 {
1624 struct kbdiacrs __user *a = up;
1625 struct kbdiacr *diacr = NULL;
1626 unsigned int ct;
1627 int i;
1628
1629 if (!perm)
1630 return -EPERM;
1631 if (get_user(ct, &a->kb_cnt))
1632 return -EFAULT;
1633 if (ct >= MAX_DIACR)
1634 return -EINVAL;
1635
1636 if (ct) {
1637 diacr = kmalloc(sizeof(struct kbdiacr) * ct,
1638 GFP_KERNEL);
1639 if (diacr == NULL)
1640 return -ENOMEM;
1641
1642 if (copy_from_user(diacr, a->kbdiacr,
1643 sizeof(struct kbdiacr) * ct)) {
1644 kfree(diacr);
1645 return -EFAULT;
1646 }
1647 }
1648
1649 spin_lock_irqsave(&kbd_event_lock, flags);
1650 accent_table_size = ct;
1651 for (i = 0; i < ct; i++) {
1652 accent_table[i].diacr =
1653 conv_8bit_to_uni(diacr[i].diacr);
1654 accent_table[i].base =
1655 conv_8bit_to_uni(diacr[i].base);
1656 accent_table[i].result =
1657 conv_8bit_to_uni(diacr[i].result);
1658 }
1659 spin_unlock_irqrestore(&kbd_event_lock, flags);
1660 kfree(diacr);
1661 return 0;
1662 }
1663
1664 case KDSKBDIACRUC:
1665 {
1666 struct kbdiacrsuc __user *a = up;
1667 unsigned int ct;
1668 void *buf = NULL;
1669
1670 if (!perm)
1671 return -EPERM;
1672
1673 if (get_user(ct, &a->kb_cnt))
1674 return -EFAULT;
1675
1676 if (ct >= MAX_DIACR)
1677 return -EINVAL;
1678
1679 if (ct) {
1680 buf = kmalloc(ct * sizeof(struct kbdiacruc),
1681 GFP_KERNEL);
1682 if (buf == NULL)
1683 return -ENOMEM;
1684
1685 if (copy_from_user(buf, a->kbdiacruc,
1686 ct * sizeof(struct kbdiacruc))) {
1687 kfree(buf);
1688 return -EFAULT;
1689 }
1690 }
1691 spin_lock_irqsave(&kbd_event_lock, flags);
1692 if (ct)
1693 memcpy(accent_table, buf,
1694 ct * sizeof(struct kbdiacruc));
1695 accent_table_size = ct;
1696 spin_unlock_irqrestore(&kbd_event_lock, flags);
1697 kfree(buf);
1698 return 0;
1699 }
1700 }
1701 return ret;
1702}
1703
1704/**
1705 * vt_do_kdskbmode - set keyboard mode ioctl
1706 * @console: the console to use
1707 * @arg: the requested mode
1708 *
1709 * Update the keyboard mode bits while holding the correct locks.
1710 * Return 0 for success or an error code.
1711 */
1712int vt_do_kdskbmode(int console, unsigned int arg)
1713{
1714 struct kbd_struct * kbd = kbd_table + console;
1715 int ret = 0;
1716 unsigned long flags;
1717
1718 spin_lock_irqsave(&kbd_event_lock, flags);
1719 switch(arg) {
1720 case K_RAW:
1721 kbd->kbdmode = VC_RAW;
1722 break;
1723 case K_MEDIUMRAW:
1724 kbd->kbdmode = VC_MEDIUMRAW;
1725 break;
1726 case K_XLATE:
1727 kbd->kbdmode = VC_XLATE;
1728 do_compute_shiftstate();
1729 break;
1730 case K_UNICODE:
1731 kbd->kbdmode = VC_UNICODE;
1732 do_compute_shiftstate();
1733 break;
1734 case K_OFF:
1735 kbd->kbdmode = VC_OFF;
1736 break;
1737 default:
1738 ret = -EINVAL;
1739 }
1740 spin_unlock_irqrestore(&kbd_event_lock, flags);
1741 return ret;
1742}
1743
1744/**
1745 * vt_do_kdskbmeta - set keyboard meta state
1746 * @console: the console to use
1747 * @arg: the requested meta state
1748 *
1749 * Update the keyboard meta bits while holding the correct locks.
1750 * Return 0 for success or an error code.
1751 */
1752int vt_do_kdskbmeta(int console, unsigned int arg)
1753{
1754 struct kbd_struct * kbd = kbd_table + console;
1755 int ret = 0;
1756 unsigned long flags;
1757
1758 spin_lock_irqsave(&kbd_event_lock, flags);
1759 switch(arg) {
1760 case K_METABIT:
1761 clr_vc_kbd_mode(kbd, VC_META);
1762 break;
1763 case K_ESCPREFIX:
1764 set_vc_kbd_mode(kbd, VC_META);
1765 break;
1766 default:
1767 ret = -EINVAL;
1768 }
1769 spin_unlock_irqrestore(&kbd_event_lock, flags);
1770 return ret;
1771}
1772
1773int vt_do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc,
1774 int perm)
1775{
1776 struct kbkeycode tmp;
1777 int kc = 0;
1778
1779 if (copy_from_user(&tmp, user_kbkc, sizeof(struct kbkeycode)))
1780 return -EFAULT;
1781 switch (cmd) {
1782 case KDGETKEYCODE:
1783 kc = getkeycode(tmp.scancode);
1784 if (kc >= 0)
1785 kc = put_user(kc, &user_kbkc->keycode);
1786 break;
1787 case KDSETKEYCODE:
1788 if (!perm)
1789 return -EPERM;
1790 kc = setkeycode(tmp.scancode, tmp.keycode);
1791 break;
1792 }
1793 return kc;
1794}
1795
1796#define i (tmp.kb_index)
1797#define s (tmp.kb_table)
1798#define v (tmp.kb_value)
1799
1800int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
1801 int console)
1802{
1803 struct kbd_struct * kbd = kbd_table + console;
1804 struct kbentry tmp;
1805 ushort *key_map, *new_map, val, ov;
1806 unsigned long flags;
1807
1808 if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
1809 return -EFAULT;
1810
1811 if (!capable(CAP_SYS_TTY_CONFIG))
1812 perm = 0;
1813
1814 switch (cmd) {
1815 case KDGKBENT:
1816 /* Ensure another thread doesn't free it under us */
1817 spin_lock_irqsave(&kbd_event_lock, flags);
1818 key_map = key_maps[s];
1819 if (key_map) {
1820 val = U(key_map[i]);
1821 if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
1822 val = K_HOLE;
1823 } else
1824 val = (i ? K_HOLE : K_NOSUCHMAP);
1825 spin_unlock_irqrestore(&kbd_event_lock, flags);
1826 return put_user(val, &user_kbe->kb_value);
1827 case KDSKBENT:
1828 if (!perm)
1829 return -EPERM;
1830 if (!i && v == K_NOSUCHMAP) {
1831 spin_lock_irqsave(&kbd_event_lock, flags);
1832 /* deallocate map */
1833 key_map = key_maps[s];
1834 if (s && key_map) {
1835 key_maps[s] = NULL;
1836 if (key_map[0] == U(K_ALLOCATED)) {
1837 kfree(key_map);
1838 keymap_count--;
1839 }
1840 }
1841 spin_unlock_irqrestore(&kbd_event_lock, flags);
1842 break;
1843 }
1844
1845 if (KTYP(v) < NR_TYPES) {
1846 if (KVAL(v) > max_vals[KTYP(v)])
1847 return -EINVAL;
1848 } else
1849 if (kbd->kbdmode != VC_UNICODE)
1850 return -EINVAL;
1851
1852 /* ++Geert: non-PC keyboards may generate keycode zero */
1853#if !defined(__mc68000__) && !defined(__powerpc__)
1854 /* assignment to entry 0 only tests validity of args */
1855 if (!i)
1856 break;
1857#endif
1858
1859 new_map = kmalloc(sizeof(plain_map), GFP_KERNEL);
1860 if (!new_map)
1861 return -ENOMEM;
1862 spin_lock_irqsave(&kbd_event_lock, flags);
1863 key_map = key_maps[s];
1864 if (key_map == NULL) {
1865 int j;
1866
1867 if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
1868 !capable(CAP_SYS_RESOURCE)) {
1869 spin_unlock_irqrestore(&kbd_event_lock, flags);
1870 kfree(new_map);
1871 return -EPERM;
1872 }
1873 key_maps[s] = new_map;
1874 key_map = new_map;
1875 key_map[0] = U(K_ALLOCATED);
1876 for (j = 1; j < NR_KEYS; j++)
1877 key_map[j] = U(K_HOLE);
1878 keymap_count++;
1879 } else
1880 kfree(new_map);
1881
1882 ov = U(key_map[i]);
1883 if (v == ov)
1884 goto out;
1885 /*
1886 * Attention Key.
1887 */
1888 if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN)) {
1889 spin_unlock_irqrestore(&kbd_event_lock, flags);
1890 return -EPERM;
1891 }
1892 key_map[i] = U(v);
1893 if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
1894 do_compute_shiftstate();
1895out:
1896 spin_unlock_irqrestore(&kbd_event_lock, flags);
1897 break;
1898 }
1899 return 0;
1900}
1901#undef i
1902#undef s
1903#undef v
1904
1905/* FIXME: This one needs untangling and locking */
1906int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
1907{
1908 struct kbsentry *kbs;
1909 char *p;
1910 u_char *q;
1911 u_char __user *up;
1912 int sz;
1913 int delta;
1914 char *first_free, *fj, *fnw;
1915 int i, j, k;
1916 int ret;
1917
1918 if (!capable(CAP_SYS_TTY_CONFIG))
1919 perm = 0;
1920
1921 kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
1922 if (!kbs) {
1923 ret = -ENOMEM;
1924 goto reterr;
1925 }
1926
1927 /* we mostly copy too much here (512bytes), but who cares ;) */
1928 if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
1929 ret = -EFAULT;
1930 goto reterr;
1931 }
1932 kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
1933 i = kbs->kb_func;
1934
1935 switch (cmd) {
1936 case KDGKBSENT:
1937 sz = sizeof(kbs->kb_string) - 1; /* sz should have been
1938 a struct member */
1939 up = user_kdgkb->kb_string;
1940 p = func_table[i];
1941 if(p)
1942 for ( ; *p && sz; p++, sz--)
1943 if (put_user(*p, up++)) {
1944 ret = -EFAULT;
1945 goto reterr;
1946 }
1947 if (put_user('\0', up)) {
1948 ret = -EFAULT;
1949 goto reterr;
1950 }
1951 kfree(kbs);
1952 return ((p && *p) ? -EOVERFLOW : 0);
1953 case KDSKBSENT:
1954 if (!perm) {
1955 ret = -EPERM;
1956 goto reterr;
1957 }
1958
1959 q = func_table[i];
1960 first_free = funcbufptr + (funcbufsize - funcbufleft);
1961 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
1962 ;
1963 if (j < MAX_NR_FUNC)
1964 fj = func_table[j];
1965 else
1966 fj = first_free;
1967
1968 delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
1969 if (delta <= funcbufleft) { /* it fits in current buf */
1970 if (j < MAX_NR_FUNC) {
1971 memmove(fj + delta, fj, first_free - fj);
1972 for (k = j; k < MAX_NR_FUNC; k++)
1973 if (func_table[k])
1974 func_table[k] += delta;
1975 }
1976 if (!q)
1977 func_table[i] = fj;
1978 funcbufleft -= delta;
1979 } else { /* allocate a larger buffer */
1980 sz = 256;
1981 while (sz < funcbufsize - funcbufleft + delta)
1982 sz <<= 1;
1983 fnw = kmalloc(sz, GFP_KERNEL);
1984 if(!fnw) {
1985 ret = -ENOMEM;
1986 goto reterr;
1987 }
1988
1989 if (!q)
1990 func_table[i] = fj;
1991 if (fj > funcbufptr)
1992 memmove(fnw, funcbufptr, fj - funcbufptr);
1993 for (k = 0; k < j; k++)
1994 if (func_table[k])
1995 func_table[k] = fnw + (func_table[k] - funcbufptr);
1996
1997 if (first_free > fj) {
1998 memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
1999 for (k = j; k < MAX_NR_FUNC; k++)
2000 if (func_table[k])
2001 func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
2002 }
2003 if (funcbufptr != func_buf)
2004 kfree(funcbufptr);
2005 funcbufptr = fnw;
2006 funcbufleft = funcbufleft - delta + sz - funcbufsize;
2007 funcbufsize = sz;
2008 }
2009 strcpy(func_table[i], kbs->kb_string);
2010 break;
2011 }
2012 ret = 0;
2013reterr:
2014 kfree(kbs);
2015 return ret;
2016}
2017
2018int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm)
2019{
2020 struct kbd_struct * kbd = kbd_table + console;
2021 unsigned long flags;
2022 unsigned char ucval;
2023
2024 switch(cmd) {
2025 /* the ioctls below read/set the flags usually shown in the leds */
2026 /* don't use them - they will go away without warning */
2027 case KDGKBLED:
2028 spin_lock_irqsave(&kbd_event_lock, flags);
2029 ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
2030 spin_unlock_irqrestore(&kbd_event_lock, flags);
2031 return put_user(ucval, (char __user *)arg);
2032
2033 case KDSKBLED:
2034 if (!perm)
2035 return -EPERM;
2036 if (arg & ~0x77)
2037 return -EINVAL;
2038 spin_lock_irqsave(&led_lock, flags);
2039 kbd->ledflagstate = (arg & 7);
2040 kbd->default_ledflagstate = ((arg >> 4) & 7);
2041 set_leds();
2042 spin_unlock_irqrestore(&led_lock, flags);
2043 return 0;
2044
2045 /* the ioctls below only set the lights, not the functions */
2046 /* for those, see KDGKBLED and KDSKBLED above */
2047 case KDGETLED:
2048 ucval = getledstate();
2049 return put_user(ucval, (char __user *)arg);
2050
2051 case KDSETLED:
2052 if (!perm)
2053 return -EPERM;
2054 setledstate(kbd, arg);
2055 return 0;
2056 }
2057 return -ENOIOCTLCMD;
2058}
2059
2060int vt_do_kdgkbmode(int console)
2061{
2062 struct kbd_struct * kbd = kbd_table + console;
2063 /* This is a spot read so needs no locking */
2064 switch (kbd->kbdmode) {
2065 case VC_RAW:
2066 return K_RAW;
2067 case VC_MEDIUMRAW:
2068 return K_MEDIUMRAW;
2069 case VC_UNICODE:
2070 return K_UNICODE;
2071 case VC_OFF:
2072 return K_OFF;
2073 default:
2074 return K_XLATE;
2075 }
2076}
2077
2078/**
2079 * vt_do_kdgkbmeta - report meta status
2080 * @console: console to report
2081 *
2082 * Report the meta flag status of this console
2083 */
2084int vt_do_kdgkbmeta(int console)
2085{
2086 struct kbd_struct * kbd = kbd_table + console;
2087 /* Again a spot read so no locking */
2088 return vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT;
2089}
2090
2091/**
2092 * vt_reset_unicode - reset the unicode status
2093 * @console: console being reset
2094 *
2095 * Restore the unicode console state to its default
2096 */
2097void vt_reset_unicode(int console)
2098{
2099 unsigned long flags;
2100
2101 spin_lock_irqsave(&kbd_event_lock, flags);
2102 kbd_table[console].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
2103 spin_unlock_irqrestore(&kbd_event_lock, flags);
2104}
2105
2106/**
2107 * vt_get_shiftstate - shift bit state
2108 *
2109 * Report the shift bits from the keyboard state. We have to export
2110 * this to support some oddities in the vt layer.
2111 */
2112int vt_get_shift_state(void)
2113{
2114 /* Don't lock as this is a transient report */
2115 return shift_state;
2116}
2117
2118/**
2119 * vt_reset_keyboard - reset keyboard state
2120 * @console: console to reset
2121 *
2122 * Reset the keyboard bits for a console as part of a general console
2123 * reset event
2124 */
2125void vt_reset_keyboard(int console)
2126{
2127 struct kbd_struct * kbd = kbd_table + console;
2128 unsigned long flags;
2129
2130 spin_lock_irqsave(&kbd_event_lock, flags);
2131 set_vc_kbd_mode(kbd, VC_REPEAT);
2132 clr_vc_kbd_mode(kbd, VC_CKMODE);
2133 clr_vc_kbd_mode(kbd, VC_APPLIC);
2134 clr_vc_kbd_mode(kbd, VC_CRLF);
2135 kbd->lockstate = 0;
2136 kbd->slockstate = 0;
2137 spin_lock(&led_lock);
2138 kbd->ledmode = LED_SHOW_FLAGS;
2139 kbd->ledflagstate = kbd->default_ledflagstate;
2140 spin_unlock(&led_lock);
2141 /* do not do set_leds here because this causes an endless tasklet loop
2142 when the keyboard hasn't been initialized yet */
2143 spin_unlock_irqrestore(&kbd_event_lock, flags);
2144}
2145
2146/**
2147 * vt_get_kbd_mode_bit - read keyboard status bits
2148 * @console: console to read from
2149 * @bit: mode bit to read
2150 *
2151 * Report back a vt mode bit. We do this without locking so the
2152 * caller must be sure that there are no synchronization needs
2153 */
2154
2155int vt_get_kbd_mode_bit(int console, int bit)
2156{
2157 struct kbd_struct * kbd = kbd_table + console;
2158 return vc_kbd_mode(kbd, bit);
2159}
2160
2161/**
2162 * vt_set_kbd_mode_bit - read keyboard status bits
2163 * @console: console to read from
2164 * @bit: mode bit to read
2165 *
2166 * Set a vt mode bit. We do this without locking so the
2167 * caller must be sure that there are no synchronization needs
2168 */
2169
2170void vt_set_kbd_mode_bit(int console, int bit)
2171{
2172 struct kbd_struct * kbd = kbd_table + console;
2173 unsigned long flags;
2174
2175 spin_lock_irqsave(&kbd_event_lock, flags);
2176 set_vc_kbd_mode(kbd, bit);
2177 spin_unlock_irqrestore(&kbd_event_lock, flags);
2178}
2179
2180/**
2181 * vt_clr_kbd_mode_bit - read keyboard status bits
2182 * @console: console to read from
2183 * @bit: mode bit to read
2184 *
2185 * Report back a vt mode bit. We do this without locking so the
2186 * caller must be sure that there are no synchronization needs
2187 */
2188
2189void vt_clr_kbd_mode_bit(int console, int bit)
2190{
2191 struct kbd_struct * kbd = kbd_table + console;
2192 unsigned long flags;
2193
2194 spin_lock_irqsave(&kbd_event_lock, flags);
2195 clr_vc_kbd_mode(kbd, bit);
2196 spin_unlock_irqrestore(&kbd_event_lock, flags);
2197}
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c
index 60b7b692605..fb864e7fcd1 100644
--- a/drivers/tty/vt/selection.c
+++ b/drivers/tty/vt/selection.c
@@ -30,7 +30,6 @@
30 30
31extern void poke_blanked_console(void); 31extern void poke_blanked_console(void);
32 32
33/* FIXME: all this needs locking */
34/* Variables for selection control. */ 33/* Variables for selection control. */
35/* Use a dynamic buffer, instead of static (Dec 1994) */ 34/* Use a dynamic buffer, instead of static (Dec 1994) */
36struct vc_data *sel_cons; /* must not be deallocated */ 35struct vc_data *sel_cons; /* must not be deallocated */
@@ -62,14 +61,10 @@ sel_pos(int n)
62 use_unicode); 61 use_unicode);
63} 62}
64 63
65/** 64/* remove the current selection highlight, if any,
66 * clear_selection - remove current selection 65 from the console holding the selection. */
67 * 66void
68 * Remove the current selection highlight, if any from the console 67clear_selection(void) {
69 * holding the selection. The caller must hold the console lock.
70 */
71void clear_selection(void)
72{
73 highlight_pointer(-1); /* hide the pointer */ 68 highlight_pointer(-1); /* hide the pointer */
74 if (sel_start != -1) { 69 if (sel_start != -1) {
75 highlight(sel_start, sel_end); 70 highlight(sel_start, sel_end);
@@ -79,7 +74,7 @@ void clear_selection(void)
79 74
80/* 75/*
81 * User settable table: what characters are to be considered alphabetic? 76 * User settable table: what characters are to be considered alphabetic?
82 * 256 bits. Locked by the console lock. 77 * 256 bits
83 */ 78 */
84static u32 inwordLut[8]={ 79static u32 inwordLut[8]={
85 0x00000000, /* control chars */ 80 0x00000000, /* control chars */
@@ -96,20 +91,10 @@ static inline int inword(const u16 c) {
96 return c > 0xff || (( inwordLut[c>>5] >> (c & 0x1F) ) & 1); 91 return c > 0xff || (( inwordLut[c>>5] >> (c & 0x1F) ) & 1);
97} 92}
98 93
99/** 94/* set inwordLut contents. Invoked by ioctl(). */
100 * set loadlut - load the LUT table
101 * @p: user table
102 *
103 * Load the LUT table from user space. The caller must hold the console
104 * lock. Make a temporary copy so a partial update doesn't make a mess.
105 */
106int sel_loadlut(char __user *p) 95int sel_loadlut(char __user *p)
107{ 96{
108 u32 tmplut[8]; 97 return copy_from_user(inwordLut, (u32 __user *)(p+4), 32) ? -EFAULT : 0;
109 if (copy_from_user(tmplut, (u32 __user *)(p+4), 32))
110 return -EFAULT;
111 memcpy(inwordLut, tmplut, 32);
112 return 0;
113} 98}
114 99
115/* does screen address p correspond to character at LH/RH edge of screen? */ 100/* does screen address p correspond to character at LH/RH edge of screen? */
@@ -145,16 +130,7 @@ static int store_utf8(u16 c, char *p)
145 } 130 }
146} 131}
147 132
148/** 133/* set the current selection. Invoked by ioctl() or by kernel code. */
149 * set_selection - set the current selection.
150 * @sel: user selection info
151 * @tty: the console tty
152 *
153 * Invoked by the ioctl handle for the vt layer.
154 *
155 * The entire selection process is managed under the console_lock. It's
156 * a lot under the lock but its hardly a performance path
157 */
158int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty) 134int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty)
159{ 135{
160 struct vc_data *vc = vc_cons[fg_console].d; 136 struct vc_data *vc = vc_cons[fg_console].d;
@@ -162,7 +138,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
162 char *bp, *obp; 138 char *bp, *obp;
163 int i, ps, pe, multiplier; 139 int i, ps, pe, multiplier;
164 u16 c; 140 u16 c;
165 int mode; 141 struct kbd_struct *kbd = kbd_table + fg_console;
166 142
167 poke_blanked_console(); 143 poke_blanked_console();
168 144
@@ -206,11 +182,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
206 clear_selection(); 182 clear_selection();
207 sel_cons = vc_cons[fg_console].d; 183 sel_cons = vc_cons[fg_console].d;
208 } 184 }
209 mode = vt_do_kdgkbmode(fg_console); 185 use_unicode = kbd && kbd->kbdmode == VC_UNICODE;
210 if (mode == K_UNICODE)
211 use_unicode = 1;
212 else
213 use_unicode = 0;
214 186
215 switch (sel_mode) 187 switch (sel_mode)
216 { 188 {
@@ -329,9 +301,6 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
329/* Insert the contents of the selection buffer into the 301/* Insert the contents of the selection buffer into the
330 * queue of the tty associated with the current console. 302 * queue of the tty associated with the current console.
331 * Invoked by ioctl(). 303 * Invoked by ioctl().
332 *
333 * Locking: called without locks. Calls the ldisc wrongly with
334 * unsafe methods,
335 */ 304 */
336int paste_selection(struct tty_struct *tty) 305int paste_selection(struct tty_struct *tty)
337{ 306{
@@ -341,13 +310,20 @@ int paste_selection(struct tty_struct *tty)
341 struct tty_ldisc *ld; 310 struct tty_ldisc *ld;
342 DECLARE_WAITQUEUE(wait, current); 311 DECLARE_WAITQUEUE(wait, current);
343 312
313 /* always called with BTM from vt_ioctl */
314 WARN_ON(!tty_locked());
315
344 console_lock(); 316 console_lock();
345 poke_blanked_console(); 317 poke_blanked_console();
346 console_unlock(); 318 console_unlock();
347 319
348 ld = tty_ldisc_ref_wait(tty); 320 ld = tty_ldisc_ref(tty);
321 if (!ld) {
322 tty_unlock();
323 ld = tty_ldisc_ref_wait(tty);
324 tty_lock();
325 }
349 326
350 /* FIXME: this is completely unsafe */
351 add_wait_queue(&vc->paste_wait, &wait); 327 add_wait_queue(&vc->paste_wait, &wait);
352 while (sel_buffer && sel_buffer_lth > pasted) { 328 while (sel_buffer && sel_buffer_lth > pasted) {
353 set_current_state(TASK_INTERRUPTIBLE); 329 set_current_state(TASK_INTERRUPTIBLE);
@@ -357,7 +333,8 @@ int paste_selection(struct tty_struct *tty)
357 } 333 }
358 count = sel_buffer_lth - pasted; 334 count = sel_buffer_lth - pasted;
359 count = min(count, tty->receive_room); 335 count = min(count, tty->receive_room);
360 ld->ops->receive_buf(tty, sel_buffer + pasted, NULL, count); 336 tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
337 NULL, count);
361 pasted += count; 338 pasted += count;
362 } 339 }
363 remove_wait_queue(&vc->paste_wait, &wait); 340 remove_wait_queue(&vc->paste_wait, &wait);
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c
index fa7268a93c0..66825c9f516 100644
--- a/drivers/tty/vt/vc_screen.c
+++ b/drivers/tty/vt/vc_screen.c
@@ -22,7 +22,6 @@
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/major.h> 23#include <linux/major.h>
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/export.h>
26#include <linux/tty.h> 25#include <linux/tty.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
28#include <linux/mm.h> 27#include <linux/mm.h>
@@ -608,10 +607,10 @@ vcs_open(struct inode *inode, struct file *filp)
608 unsigned int currcons = iminor(inode) & 127; 607 unsigned int currcons = iminor(inode) & 127;
609 int ret = 0; 608 int ret = 0;
610 609
611 console_lock(); 610 tty_lock();
612 if(currcons && !vc_cons_allocated(currcons-1)) 611 if(currcons && !vc_cons_allocated(currcons-1))
613 ret = -ENXIO; 612 ret = -ENXIO;
614 console_unlock(); 613 tty_unlock();
615 return ret; 614 return ret;
616} 615}
617 616
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 8fd89687d06..b3915b7ad3e 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -99,6 +99,7 @@
99#include <linux/notifier.h> 99#include <linux/notifier.h>
100#include <linux/device.h> 100#include <linux/device.h>
101#include <linux/io.h> 101#include <linux/io.h>
102#include <asm/system.h>
102#include <linux/uaccess.h> 103#include <linux/uaccess.h>
103#include <linux/kdb.h> 104#include <linux/kdb.h>
104#include <linux/ctype.h> 105#include <linux/ctype.h>
@@ -258,7 +259,7 @@ EXPORT_SYMBOL_GPL(unregister_vt_notifier);
258 259
259static void notify_write(struct vc_data *vc, unsigned int unicode) 260static void notify_write(struct vc_data *vc, unsigned int unicode)
260{ 261{
261 struct vt_notifier_param param = { .vc = vc, .c = unicode }; 262 struct vt_notifier_param param = { .vc = vc, unicode = unicode };
262 atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, &param); 263 atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, &param);
263} 264}
264 265
@@ -537,27 +538,45 @@ void complement_pos(struct vc_data *vc, int offset)
537 538
538static void insert_char(struct vc_data *vc, unsigned int nr) 539static void insert_char(struct vc_data *vc, unsigned int nr)
539{ 540{
540 unsigned short *p = (unsigned short *) vc->vc_pos; 541 unsigned short *p, *q = (unsigned short *)vc->vc_pos;
541 542
542 scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x) * 2); 543 p = q + vc->vc_cols - nr - vc->vc_x;
543 scr_memsetw(p, vc->vc_video_erase_char, nr * 2); 544 while (--p >= q)
545 scr_writew(scr_readw(p), p + nr);
546 scr_memsetw(q, vc->vc_video_erase_char, nr * 2);
544 vc->vc_need_wrap = 0; 547 vc->vc_need_wrap = 0;
545 if (DO_UPDATE(vc)) 548 if (DO_UPDATE(vc)) {
546 do_update_region(vc, (unsigned long) p, 549 unsigned short oldattr = vc->vc_attr;
547 vc->vc_cols - vc->vc_x); 550 vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x, vc->vc_y, vc->vc_x + nr, 1,
551 vc->vc_cols - vc->vc_x - nr);
552 vc->vc_attr = vc->vc_video_erase_char >> 8;
553 while (nr--)
554 vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y, vc->vc_x + nr);
555 vc->vc_attr = oldattr;
556 }
548} 557}
549 558
550static void delete_char(struct vc_data *vc, unsigned int nr) 559static void delete_char(struct vc_data *vc, unsigned int nr)
551{ 560{
552 unsigned short *p = (unsigned short *) vc->vc_pos; 561 unsigned int i = vc->vc_x;
562 unsigned short *p = (unsigned short *)vc->vc_pos;
553 563
554 scr_memcpyw(p, p + nr, (vc->vc_cols - vc->vc_x - nr) * 2); 564 while (++i <= vc->vc_cols - nr) {
555 scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char, 565 scr_writew(scr_readw(p+nr), p);
556 nr * 2); 566 p++;
567 }
568 scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
557 vc->vc_need_wrap = 0; 569 vc->vc_need_wrap = 0;
558 if (DO_UPDATE(vc)) 570 if (DO_UPDATE(vc)) {
559 do_update_region(vc, (unsigned long) p, 571 unsigned short oldattr = vc->vc_attr;
560 vc->vc_cols - vc->vc_x); 572 vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x + nr, vc->vc_y, vc->vc_x, 1,
573 vc->vc_cols - vc->vc_x - nr);
574 vc->vc_attr = vc->vc_video_erase_char >> 8;
575 while (nr--)
576 vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y,
577 vc->vc_cols - 1 - nr);
578 vc->vc_attr = oldattr;
579 }
561} 580}
562 581
563static int softcursor_original; 582static int softcursor_original;
@@ -779,7 +798,6 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
779 con_set_default_unimap(vc); 798 con_set_default_unimap(vc);
780 vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); 799 vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
781 if (!vc->vc_screenbuf) { 800 if (!vc->vc_screenbuf) {
782 tty_port_destroy(&vc->port);
783 kfree(vc); 801 kfree(vc);
784 vc_cons[currcons].d = NULL; 802 vc_cons[currcons].d = NULL;
785 return -ENOMEM; 803 return -ENOMEM;
@@ -1000,10 +1018,8 @@ void vc_deallocate(unsigned int currcons)
1000 put_pid(vc->vt_pid); 1018 put_pid(vc->vt_pid);
1001 module_put(vc->vc_sw->owner); 1019 module_put(vc->vc_sw->owner);
1002 kfree(vc->vc_screenbuf); 1020 kfree(vc->vc_screenbuf);
1003 if (currcons >= MIN_NR_CONSOLES) { 1021 if (currcons >= MIN_NR_CONSOLES)
1004 tty_port_destroy(&vc->port);
1005 kfree(vc); 1022 kfree(vc);
1006 }
1007 vc_cons[currcons].d = NULL; 1023 vc_cons[currcons].d = NULL;
1008 } 1024 }
1009} 1025}
@@ -1012,9 +1028,9 @@ void vc_deallocate(unsigned int currcons)
1012 * VT102 emulator 1028 * VT102 emulator
1013 */ 1029 */
1014 1030
1015#define set_kbd(vc, x) vt_set_kbd_mode_bit((vc)->vc_num, (x)) 1031#define set_kbd(vc, x) set_vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
1016#define clr_kbd(vc, x) vt_clr_kbd_mode_bit((vc)->vc_num, (x)) 1032#define clr_kbd(vc, x) clr_vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
1017#define is_kbd(vc, x) vt_get_kbd_mode_bit((vc)->vc_num, (x)) 1033#define is_kbd(vc, x) vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
1018 1034
1019#define decarm VC_REPEAT 1035#define decarm VC_REPEAT
1020#define decckm VC_CKMODE 1036#define decckm VC_CKMODE
@@ -1157,26 +1173,45 @@ static void csi_J(struct vc_data *vc, int vpar)
1157 case 0: /* erase from cursor to end of display */ 1173 case 0: /* erase from cursor to end of display */
1158 count = (vc->vc_scr_end - vc->vc_pos) >> 1; 1174 count = (vc->vc_scr_end - vc->vc_pos) >> 1;
1159 start = (unsigned short *)vc->vc_pos; 1175 start = (unsigned short *)vc->vc_pos;
1176 if (DO_UPDATE(vc)) {
1177 /* do in two stages */
1178 vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
1179 vc->vc_cols - vc->vc_x);
1180 vc->vc_sw->con_clear(vc, vc->vc_y + 1, 0,
1181 vc->vc_rows - vc->vc_y - 1,
1182 vc->vc_cols);
1183 }
1160 break; 1184 break;
1161 case 1: /* erase from start to cursor */ 1185 case 1: /* erase from start to cursor */
1162 count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1; 1186 count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1;
1163 start = (unsigned short *)vc->vc_origin; 1187 start = (unsigned short *)vc->vc_origin;
1188 if (DO_UPDATE(vc)) {
1189 /* do in two stages */
1190 vc->vc_sw->con_clear(vc, 0, 0, vc->vc_y,
1191 vc->vc_cols);
1192 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1193 vc->vc_x + 1);
1194 }
1164 break; 1195 break;
1165 case 3: /* erase scroll-back buffer (and whole display) */ 1196 case 3: /* erase scroll-back buffer (and whole display) */
1166 scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, 1197 scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
1167 vc->vc_screenbuf_size >> 1); 1198 vc->vc_screenbuf_size >> 1);
1168 set_origin(vc); 1199 set_origin(vc);
1200 if (CON_IS_VISIBLE(vc))
1201 update_screen(vc);
1169 /* fall through */ 1202 /* fall through */
1170 case 2: /* erase whole display */ 1203 case 2: /* erase whole display */
1171 count = vc->vc_cols * vc->vc_rows; 1204 count = vc->vc_cols * vc->vc_rows;
1172 start = (unsigned short *)vc->vc_origin; 1205 start = (unsigned short *)vc->vc_origin;
1206 if (DO_UPDATE(vc))
1207 vc->vc_sw->con_clear(vc, 0, 0,
1208 vc->vc_rows,
1209 vc->vc_cols);
1173 break; 1210 break;
1174 default: 1211 default:
1175 return; 1212 return;
1176 } 1213 }
1177 scr_memsetw(start, vc->vc_video_erase_char, 2 * count); 1214 scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
1178 if (DO_UPDATE(vc))
1179 do_update_region(vc, (unsigned long) start, count);
1180 vc->vc_need_wrap = 0; 1215 vc->vc_need_wrap = 0;
1181} 1216}
1182 1217
@@ -1189,22 +1224,29 @@ static void csi_K(struct vc_data *vc, int vpar)
1189 case 0: /* erase from cursor to end of line */ 1224 case 0: /* erase from cursor to end of line */
1190 count = vc->vc_cols - vc->vc_x; 1225 count = vc->vc_cols - vc->vc_x;
1191 start = (unsigned short *)vc->vc_pos; 1226 start = (unsigned short *)vc->vc_pos;
1227 if (DO_UPDATE(vc))
1228 vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
1229 vc->vc_cols - vc->vc_x);
1192 break; 1230 break;
1193 case 1: /* erase from start of line to cursor */ 1231 case 1: /* erase from start of line to cursor */
1194 start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); 1232 start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
1195 count = vc->vc_x + 1; 1233 count = vc->vc_x + 1;
1234 if (DO_UPDATE(vc))
1235 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1236 vc->vc_x + 1);
1196 break; 1237 break;
1197 case 2: /* erase whole line */ 1238 case 2: /* erase whole line */
1198 start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); 1239 start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
1199 count = vc->vc_cols; 1240 count = vc->vc_cols;
1241 if (DO_UPDATE(vc))
1242 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1243 vc->vc_cols);
1200 break; 1244 break;
1201 default: 1245 default:
1202 return; 1246 return;
1203 } 1247 }
1204 scr_memsetw(start, vc->vc_video_erase_char, 2 * count); 1248 scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
1205 vc->vc_need_wrap = 0; 1249 vc->vc_need_wrap = 0;
1206 if (DO_UPDATE(vc))
1207 do_update_region(vc, (unsigned long) start, count);
1208} 1250}
1209 1251
1210static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */ 1252static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */
@@ -1339,7 +1381,7 @@ static void respond_string(const char *p, struct tty_struct *tty)
1339 tty_insert_flip_char(tty, *p, 0); 1381 tty_insert_flip_char(tty, *p, 0);
1340 p++; 1382 p++;
1341 } 1383 }
1342 tty_schedule_flip(tty); 1384 con_schedule_flip(tty);
1343} 1385}
1344 1386
1345static void cursor_report(struct vc_data *vc, struct tty_struct *tty) 1387static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
@@ -1610,7 +1652,16 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
1610 vc->vc_deccm = global_cursor_default; 1652 vc->vc_deccm = global_cursor_default;
1611 vc->vc_decim = 0; 1653 vc->vc_decim = 0;
1612 1654
1613 vt_reset_keyboard(vc->vc_num); 1655 set_kbd(vc, decarm);
1656 clr_kbd(vc, decckm);
1657 clr_kbd(vc, kbdapplic);
1658 clr_kbd(vc, lnm);
1659 kbd_table[vc->vc_num].lockstate = 0;
1660 kbd_table[vc->vc_num].slockstate = 0;
1661 kbd_table[vc->vc_num].ledmode = LED_SHOW_FLAGS;
1662 kbd_table[vc->vc_num].ledflagstate = kbd_table[vc->vc_num].default_ledflagstate;
1663 /* do not do set_leds here because this causes an endless tasklet loop
1664 when the keyboard hasn't been initialized yet */
1614 1665
1615 vc->vc_cursor_type = cur_default; 1666 vc->vc_cursor_type = cur_default;
1616 vc->vc_complement_mask = vc->vc_s_complement_mask; 1667 vc->vc_complement_mask = vc->vc_s_complement_mask;
@@ -1928,7 +1979,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
1928 case 'q': /* DECLL - but only 3 leds */ 1979 case 'q': /* DECLL - but only 3 leds */
1929 /* map 0,1,2,3 to 0,1,2,4 */ 1980 /* map 0,1,2,3 to 0,1,2,4 */
1930 if (vc->vc_par[0] < 4) 1981 if (vc->vc_par[0] < 4)
1931 vt_set_led_state(vc->vc_num, 1982 setledstate(kbd_table + vc->vc_num,
1932 (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4); 1983 (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4);
1933 return; 1984 return;
1934 case 'r': 1985 case 'r':
@@ -2581,9 +2632,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
2581 console_unlock(); 2632 console_unlock();
2582 break; 2633 break;
2583 case TIOCL_SELLOADLUT: 2634 case TIOCL_SELLOADLUT:
2584 console_lock();
2585 ret = sel_loadlut(p); 2635 ret = sel_loadlut(p);
2586 console_unlock();
2587 break; 2636 break;
2588 case TIOCL_GETSHIFTSTATE: 2637 case TIOCL_GETSHIFTSTATE:
2589 2638
@@ -2593,19 +2642,15 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
2593 * kernel-internal variable; programs not closely 2642 * kernel-internal variable; programs not closely
2594 * related to the kernel should not use this. 2643 * related to the kernel should not use this.
2595 */ 2644 */
2596 data = vt_get_shift_state(); 2645 data = shift_state;
2597 ret = __put_user(data, p); 2646 ret = __put_user(data, p);
2598 break; 2647 break;
2599 case TIOCL_GETMOUSEREPORTING: 2648 case TIOCL_GETMOUSEREPORTING:
2600 console_lock(); /* May be overkill */
2601 data = mouse_reporting(); 2649 data = mouse_reporting();
2602 console_unlock();
2603 ret = __put_user(data, p); 2650 ret = __put_user(data, p);
2604 break; 2651 break;
2605 case TIOCL_SETVESABLANK: 2652 case TIOCL_SETVESABLANK:
2606 console_lock();
2607 ret = set_vesa_blanking(p); 2653 ret = set_vesa_blanking(p);
2608 console_unlock();
2609 break; 2654 break;
2610 case TIOCL_GETKMSGREDIRECT: 2655 case TIOCL_GETKMSGREDIRECT:
2611 data = vt_get_kmsg_redirect(); 2656 data = vt_get_kmsg_redirect();
@@ -2622,21 +2667,13 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
2622 } 2667 }
2623 break; 2668 break;
2624 case TIOCL_GETFGCONSOLE: 2669 case TIOCL_GETFGCONSOLE:
2625 /* No locking needed as this is a transiently
2626 correct return anyway if the caller hasn't
2627 disabled switching */
2628 ret = fg_console; 2670 ret = fg_console;
2629 break; 2671 break;
2630 case TIOCL_SCROLLCONSOLE: 2672 case TIOCL_SCROLLCONSOLE:
2631 if (get_user(lines, (s32 __user *)(p+4))) { 2673 if (get_user(lines, (s32 __user *)(p+4))) {
2632 ret = -EFAULT; 2674 ret = -EFAULT;
2633 } else { 2675 } else {
2634 /* Need the console lock here. Note that lots
2635 of other calls need fixing before the lock
2636 is actually useful ! */
2637 console_lock();
2638 scrollfront(vc_cons[fg_console].d, lines); 2676 scrollfront(vc_cons[fg_console].d, lines);
2639 console_unlock();
2640 ret = 0; 2677 ret = 0;
2641 } 2678 }
2642 break; 2679 break;
@@ -2716,7 +2753,8 @@ static void con_stop(struct tty_struct *tty)
2716 console_num = tty->index; 2753 console_num = tty->index;
2717 if (!vc_cons_allocated(console_num)) 2754 if (!vc_cons_allocated(console_num))
2718 return; 2755 return;
2719 vt_kbd_con_stop(console_num); 2756 set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
2757 set_leds();
2720} 2758}
2721 2759
2722/* 2760/*
@@ -2730,7 +2768,8 @@ static void con_start(struct tty_struct *tty)
2730 console_num = tty->index; 2768 console_num = tty->index;
2731 if (!vc_cons_allocated(console_num)) 2769 if (!vc_cons_allocated(console_num))
2732 return; 2770 return;
2733 vt_kbd_con_start(console_num); 2771 clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
2772 set_leds();
2734} 2773}
2735 2774
2736static void con_flush_chars(struct tty_struct *tty) 2775static void con_flush_chars(struct tty_struct *tty)
@@ -2751,52 +2790,41 @@ static void con_flush_chars(struct tty_struct *tty)
2751/* 2790/*
2752 * Allocate the console screen memory. 2791 * Allocate the console screen memory.
2753 */ 2792 */
2754static int con_install(struct tty_driver *driver, struct tty_struct *tty) 2793static int con_open(struct tty_struct *tty, struct file *filp)
2755{ 2794{
2756 unsigned int currcons = tty->index; 2795 unsigned int currcons = tty->index;
2757 struct vc_data *vc; 2796 int ret = 0;
2758 int ret;
2759 2797
2760 console_lock(); 2798 console_lock();
2761 ret = vc_allocate(currcons); 2799 if (tty->driver_data == NULL) {
2762 if (ret) 2800 ret = vc_allocate(currcons);
2763 goto unlock; 2801 if (ret == 0) {
2764 2802 struct vc_data *vc = vc_cons[currcons].d;
2765 vc = vc_cons[currcons].d;
2766
2767 /* Still being freed */
2768 if (vc->port.tty) {
2769 ret = -ERESTARTSYS;
2770 goto unlock;
2771 }
2772
2773 ret = tty_port_install(&vc->port, driver, tty);
2774 if (ret)
2775 goto unlock;
2776 2803
2777 tty->driver_data = vc; 2804 /* Still being freed */
2778 vc->port.tty = tty; 2805 if (vc->port.tty) {
2806 console_unlock();
2807 return -ERESTARTSYS;
2808 }
2809 tty->driver_data = vc;
2810 vc->port.tty = tty;
2779 2811
2780 if (!tty->winsize.ws_row && !tty->winsize.ws_col) { 2812 if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
2781 tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; 2813 tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
2782 tty->winsize.ws_col = vc_cons[currcons].d->vc_cols; 2814 tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
2815 }
2816 if (vc->vc_utf)
2817 tty->termios->c_iflag |= IUTF8;
2818 else
2819 tty->termios->c_iflag &= ~IUTF8;
2820 console_unlock();
2821 return ret;
2822 }
2783 } 2823 }
2784 if (vc->vc_utf)
2785 tty->termios.c_iflag |= IUTF8;
2786 else
2787 tty->termios.c_iflag &= ~IUTF8;
2788unlock:
2789 console_unlock(); 2824 console_unlock();
2790 return ret; 2825 return ret;
2791} 2826}
2792 2827
2793static int con_open(struct tty_struct *tty, struct file *filp)
2794{
2795 /* everything done in install */
2796 return 0;
2797}
2798
2799
2800static void con_close(struct tty_struct *tty, struct file *filp) 2828static void con_close(struct tty_struct *tty, struct file *filp)
2801{ 2829{
2802 /* Nothing to do - we defer to shutdown */ 2830 /* Nothing to do - we defer to shutdown */
@@ -2809,6 +2837,7 @@ static void con_shutdown(struct tty_struct *tty)
2809 console_lock(); 2837 console_lock();
2810 vc->port.tty = NULL; 2838 vc->port.tty = NULL;
2811 console_unlock(); 2839 console_unlock();
2840 tty_shutdown(tty);
2812} 2841}
2813 2842
2814static int default_italic_color = 2; // green (ASCII) 2843static int default_italic_color = 2; // green (ASCII)
@@ -2901,10 +2930,11 @@ static int __init con_init(void)
2901 gotoxy(vc, vc->vc_x, vc->vc_y); 2930 gotoxy(vc, vc->vc_x, vc->vc_y);
2902 csi_J(vc, 0); 2931 csi_J(vc, 0);
2903 update_screen(vc); 2932 update_screen(vc);
2904 pr_info("Console: %s %s %dx%d\n", 2933 pr_info("Console: %s %s %dx%d",
2905 vc->vc_can_do_color ? "colour" : "mono", 2934 vc->vc_can_do_color ? "colour" : "mono",
2906 display_desc, vc->vc_cols, vc->vc_rows); 2935 display_desc, vc->vc_cols, vc->vc_rows);
2907 printable = 1; 2936 printable = 1;
2937 printk("\n");
2908 2938
2909 console_unlock(); 2939 console_unlock();
2910 2940
@@ -2916,7 +2946,6 @@ static int __init con_init(void)
2916console_initcall(con_init); 2946console_initcall(con_init);
2917 2947
2918static const struct tty_operations con_ops = { 2948static const struct tty_operations con_ops = {
2919 .install = con_install,
2920 .open = con_open, 2949 .open = con_open,
2921 .close = con_close, 2950 .close = con_close,
2922 .write = con_write, 2951 .write = con_write,
@@ -2962,7 +2991,7 @@ int __init vty_init(const struct file_operations *console_fops)
2962 console_driver = alloc_tty_driver(MAX_NR_CONSOLES); 2991 console_driver = alloc_tty_driver(MAX_NR_CONSOLES);
2963 if (!console_driver) 2992 if (!console_driver)
2964 panic("Couldn't allocate console driver\n"); 2993 panic("Couldn't allocate console driver\n");
2965 2994 console_driver->owner = THIS_MODULE;
2966 console_driver->name = "tty"; 2995 console_driver->name = "tty";
2967 console_driver->name_base = 1; 2996 console_driver->name_base = 1;
2968 console_driver->major = TTY_MAJOR; 2997 console_driver->major = TTY_MAJOR;
@@ -3445,19 +3474,6 @@ int con_debug_enter(struct vc_data *vc)
3445 kdb_set(2, setargs); 3474 kdb_set(2, setargs);
3446 } 3475 }
3447 } 3476 }
3448 if (vc->vc_cols < 999) {
3449 int colcount;
3450 char cols[4];
3451 const char *setargs[3] = {
3452 "set",
3453 "COLUMNS",
3454 cols,
3455 };
3456 if (kdbgetintenv(setargs[0], &colcount)) {
3457 snprintf(cols, 4, "%i", vc->vc_cols);
3458 kdb_set(2, setargs);
3459 }
3460 }
3461#endif /* CONFIG_KGDB_KDB */ 3477#endif /* CONFIG_KGDB_KDB */
3462 return ret; 3478 return ret;
3463} 3479}
@@ -3875,6 +3891,36 @@ static void set_palette(struct vc_data *vc)
3875 vc->vc_sw->con_set_palette(vc, color_table); 3891 vc->vc_sw->con_set_palette(vc, color_table);
3876} 3892}
3877 3893
3894static int set_get_cmap(unsigned char __user *arg, int set)
3895{
3896 int i, j, k;
3897
3898 WARN_CONSOLE_UNLOCKED();
3899
3900 for (i = 0; i < 16; i++)
3901 if (set) {
3902 get_user(default_red[i], arg++);
3903 get_user(default_grn[i], arg++);
3904 get_user(default_blu[i], arg++);
3905 } else {
3906 put_user(default_red[i], arg++);
3907 put_user(default_grn[i], arg++);
3908 put_user(default_blu[i], arg++);
3909 }
3910 if (set) {
3911 for (i = 0; i < MAX_NR_CONSOLES; i++)
3912 if (vc_cons_allocated(i)) {
3913 for (j = k = 0; j < 16; j++) {
3914 vc_cons[i].d->vc_palette[k++] = default_red[j];
3915 vc_cons[i].d->vc_palette[k++] = default_grn[j];
3916 vc_cons[i].d->vc_palette[k++] = default_blu[j];
3917 }
3918 set_palette(vc_cons[i].d);
3919 }
3920 }
3921 return 0;
3922}
3923
3878/* 3924/*
3879 * Load palette into the DAC registers. arg points to a colour 3925 * Load palette into the DAC registers. arg points to a colour
3880 * map, 3 bytes per colour, 16 colours, range from 0 to 255. 3926 * map, 3 bytes per colour, 16 colours, range from 0 to 255.
@@ -3882,50 +3928,24 @@ static void set_palette(struct vc_data *vc)
3882 3928
3883int con_set_cmap(unsigned char __user *arg) 3929int con_set_cmap(unsigned char __user *arg)
3884{ 3930{
3885 int i, j, k; 3931 int rc;
3886 unsigned char colormap[3*16];
3887
3888 if (copy_from_user(colormap, arg, sizeof(colormap)))
3889 return -EFAULT;
3890 3932
3891 console_lock(); 3933 console_lock();
3892 for (i = k = 0; i < 16; i++) { 3934 rc = set_get_cmap (arg,1);
3893 default_red[i] = colormap[k++];
3894 default_grn[i] = colormap[k++];
3895 default_blu[i] = colormap[k++];
3896 }
3897 for (i = 0; i < MAX_NR_CONSOLES; i++) {
3898 if (!vc_cons_allocated(i))
3899 continue;
3900 for (j = k = 0; j < 16; j++) {
3901 vc_cons[i].d->vc_palette[k++] = default_red[j];
3902 vc_cons[i].d->vc_palette[k++] = default_grn[j];
3903 vc_cons[i].d->vc_palette[k++] = default_blu[j];
3904 }
3905 set_palette(vc_cons[i].d);
3906 }
3907 console_unlock(); 3935 console_unlock();
3908 3936
3909 return 0; 3937 return rc;
3910} 3938}
3911 3939
3912int con_get_cmap(unsigned char __user *arg) 3940int con_get_cmap(unsigned char __user *arg)
3913{ 3941{
3914 int i, k; 3942 int rc;
3915 unsigned char colormap[3*16];
3916 3943
3917 console_lock(); 3944 console_lock();
3918 for (i = k = 0; i < 16; i++) { 3945 rc = set_get_cmap (arg,0);
3919 colormap[k++] = default_red[i];
3920 colormap[k++] = default_grn[i];
3921 colormap[k++] = default_blu[i];
3922 }
3923 console_unlock(); 3946 console_unlock();
3924 3947
3925 if (copy_to_user(arg, colormap, sizeof(colormap))) 3948 return rc;
3926 return -EFAULT;
3927
3928 return 0;
3929} 3949}
3930 3950
3931void reset_palette(struct vc_data *vc) 3951void reset_palette(struct vc_data *vc)
@@ -3960,6 +3980,9 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op)
3960 int rc = -EINVAL; 3980 int rc = -EINVAL;
3961 int c; 3981 int c;
3962 3982
3983 if (vc->vc_mode != KD_TEXT)
3984 return -EINVAL;
3985
3963 if (op->data) { 3986 if (op->data) {
3964 font.data = kmalloc(max_font_size, GFP_KERNEL); 3987 font.data = kmalloc(max_font_size, GFP_KERNEL);
3965 if (!font.data) 3988 if (!font.data)
@@ -3968,9 +3991,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op)
3968 font.data = NULL; 3991 font.data = NULL;
3969 3992
3970 console_lock(); 3993 console_lock();
3971 if (vc->vc_mode != KD_TEXT) 3994 if (vc->vc_sw->con_font_get)
3972 rc = -EINVAL;
3973 else if (vc->vc_sw->con_font_get)
3974 rc = vc->vc_sw->con_font_get(vc, &font); 3995 rc = vc->vc_sw->con_font_get(vc, &font);
3975 else 3996 else
3976 rc = -ENOSYS; 3997 rc = -ENOSYS;
@@ -4052,9 +4073,7 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op)
4052 if (IS_ERR(font.data)) 4073 if (IS_ERR(font.data))
4053 return PTR_ERR(font.data); 4074 return PTR_ERR(font.data);
4054 console_lock(); 4075 console_lock();
4055 if (vc->vc_mode != KD_TEXT) 4076 if (vc->vc_sw->con_font_set)
4056 rc = -EINVAL;
4057 else if (vc->vc_sw->con_font_set)
4058 rc = vc->vc_sw->con_font_set(vc, &font, op->flags); 4077 rc = vc->vc_sw->con_font_set(vc, &font, op->flags);
4059 else 4078 else
4060 rc = -ENOSYS; 4079 rc = -ENOSYS;
@@ -4070,6 +4089,8 @@ static int con_font_default(struct vc_data *vc, struct console_font_op *op)
4070 char *s = name; 4089 char *s = name;
4071 int rc; 4090 int rc;
4072 4091
4092 if (vc->vc_mode != KD_TEXT)
4093 return -EINVAL;
4073 4094
4074 if (!op->data) 4095 if (!op->data)
4075 s = NULL; 4096 s = NULL;
@@ -4079,10 +4100,6 @@ static int con_font_default(struct vc_data *vc, struct console_font_op *op)
4079 name[MAX_FONT_NAME - 1] = 0; 4100 name[MAX_FONT_NAME - 1] = 0;
4080 4101
4081 console_lock(); 4102 console_lock();
4082 if (vc->vc_mode != KD_TEXT) {
4083 console_unlock();
4084 return -EINVAL;
4085 }
4086 if (vc->vc_sw->con_font_default) 4103 if (vc->vc_sw->con_font_default)
4087 rc = vc->vc_sw->con_font_default(vc, &font, s); 4104 rc = vc->vc_sw->con_font_default(vc, &font, s);
4088 else 4105 else
@@ -4100,11 +4117,11 @@ static int con_font_copy(struct vc_data *vc, struct console_font_op *op)
4100 int con = op->height; 4117 int con = op->height;
4101 int rc; 4118 int rc;
4102 4119
4120 if (vc->vc_mode != KD_TEXT)
4121 return -EINVAL;
4103 4122
4104 console_lock(); 4123 console_lock();
4105 if (vc->vc_mode != KD_TEXT) 4124 if (!vc->vc_sw->con_font_copy)
4106 rc = -EINVAL;
4107 else if (!vc->vc_sw->con_font_copy)
4108 rc = -ENOSYS; 4125 rc = -ENOSYS;
4109 else if (con < 0 || !vc_cons_allocated(con)) 4126 else if (con < 0 || !vc_cons_allocated(con))
4110 rc = -ENOTTY; 4127 rc = -ENOTTY;
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index 98ff1735eaf..5e096f43bce 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -25,7 +25,6 @@
25#include <linux/console.h> 25#include <linux/console.h>
26#include <linux/consolemap.h> 26#include <linux/consolemap.h>
27#include <linux/signal.h> 27#include <linux/signal.h>
28#include <linux/suspend.h>
29#include <linux/timex.h> 28#include <linux/timex.h>
30 29
31#include <asm/io.h> 30#include <asm/io.h>
@@ -111,7 +110,16 @@ void vt_event_post(unsigned int event, unsigned int old, unsigned int new)
111 wake_up_interruptible(&vt_event_waitqueue); 110 wake_up_interruptible(&vt_event_waitqueue);
112} 111}
113 112
114static void __vt_event_queue(struct vt_event_wait *vw) 113/**
114 * vt_event_wait - wait for an event
115 * @vw: our event
116 *
117 * Waits for an event to occur which completes our vt_event_wait
118 * structure. On return the structure has wv->done set to 1 for success
119 * or 0 if some event such as a signal ended the wait.
120 */
121
122static void vt_event_wait(struct vt_event_wait *vw)
115{ 123{
116 unsigned long flags; 124 unsigned long flags;
117 /* Prepare the event */ 125 /* Prepare the event */
@@ -121,18 +129,8 @@ static void __vt_event_queue(struct vt_event_wait *vw)
121 spin_lock_irqsave(&vt_event_lock, flags); 129 spin_lock_irqsave(&vt_event_lock, flags);
122 list_add(&vw->list, &vt_events); 130 list_add(&vw->list, &vt_events);
123 spin_unlock_irqrestore(&vt_event_lock, flags); 131 spin_unlock_irqrestore(&vt_event_lock, flags);
124}
125
126static void __vt_event_wait(struct vt_event_wait *vw)
127{
128 /* Wait for it to pass */ 132 /* Wait for it to pass */
129 wait_event_interruptible(vt_event_waitqueue, vw->done); 133 wait_event_interruptible_tty(vt_event_waitqueue, vw->done);
130}
131
132static void __vt_event_dequeue(struct vt_event_wait *vw)
133{
134 unsigned long flags;
135
136 /* Dequeue it */ 134 /* Dequeue it */
137 spin_lock_irqsave(&vt_event_lock, flags); 135 spin_lock_irqsave(&vt_event_lock, flags);
138 list_del(&vw->list); 136 list_del(&vw->list);
@@ -140,22 +138,6 @@ static void __vt_event_dequeue(struct vt_event_wait *vw)
140} 138}
141 139
142/** 140/**
143 * vt_event_wait - wait for an event
144 * @vw: our event
145 *
146 * Waits for an event to occur which completes our vt_event_wait
147 * structure. On return the structure has wv->done set to 1 for success
148 * or 0 if some event such as a signal ended the wait.
149 */
150
151static void vt_event_wait(struct vt_event_wait *vw)
152{
153 __vt_event_queue(vw);
154 __vt_event_wait(vw);
155 __vt_event_dequeue(vw);
156}
157
158/**
159 * vt_event_wait_ioctl - event ioctl handler 141 * vt_event_wait_ioctl - event ioctl handler
160 * @arg: argument to ioctl 142 * @arg: argument to ioctl
161 * 143 *
@@ -195,14 +177,10 @@ int vt_waitactive(int n)
195{ 177{
196 struct vt_event_wait vw; 178 struct vt_event_wait vw;
197 do { 179 do {
198 vw.event.event = VT_EVENT_SWITCH; 180 if (n == fg_console + 1)
199 __vt_event_queue(&vw);
200 if (n == fg_console + 1) {
201 __vt_event_dequeue(&vw);
202 break; 181 break;
203 } 182 vw.event.event = VT_EVENT_SWITCH;
204 __vt_event_wait(&vw); 183 vt_event_wait(&vw);
205 __vt_event_dequeue(&vw);
206 if (vw.done == 0) 184 if (vw.done == 0)
207 return -EINTR; 185 return -EINTR;
208 } while (vw.event.newev != n); 186 } while (vw.event.newev != n);
@@ -217,7 +195,232 @@ int vt_waitactive(int n)
217#define GPLAST 0x3df 195#define GPLAST 0x3df
218#define GPNUM (GPLAST - GPFIRST + 1) 196#define GPNUM (GPLAST - GPFIRST + 1)
219 197
198#define i (tmp.kb_index)
199#define s (tmp.kb_table)
200#define v (tmp.kb_value)
201static inline int
202do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_struct *kbd)
203{
204 struct kbentry tmp;
205 ushort *key_map, val, ov;
206
207 if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
208 return -EFAULT;
209
210 if (!capable(CAP_SYS_TTY_CONFIG))
211 perm = 0;
212
213 switch (cmd) {
214 case KDGKBENT:
215 key_map = key_maps[s];
216 if (key_map) {
217 val = U(key_map[i]);
218 if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
219 val = K_HOLE;
220 } else
221 val = (i ? K_HOLE : K_NOSUCHMAP);
222 return put_user(val, &user_kbe->kb_value);
223 case KDSKBENT:
224 if (!perm)
225 return -EPERM;
226 if (!i && v == K_NOSUCHMAP) {
227 /* deallocate map */
228 key_map = key_maps[s];
229 if (s && key_map) {
230 key_maps[s] = NULL;
231 if (key_map[0] == U(K_ALLOCATED)) {
232 kfree(key_map);
233 keymap_count--;
234 }
235 }
236 break;
237 }
238
239 if (KTYP(v) < NR_TYPES) {
240 if (KVAL(v) > max_vals[KTYP(v)])
241 return -EINVAL;
242 } else
243 if (kbd->kbdmode != VC_UNICODE)
244 return -EINVAL;
245
246 /* ++Geert: non-PC keyboards may generate keycode zero */
247#if !defined(__mc68000__) && !defined(__powerpc__)
248 /* assignment to entry 0 only tests validity of args */
249 if (!i)
250 break;
251#endif
252
253 if (!(key_map = key_maps[s])) {
254 int j;
255
256 if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
257 !capable(CAP_SYS_RESOURCE))
258 return -EPERM;
259
260 key_map = kmalloc(sizeof(plain_map),
261 GFP_KERNEL);
262 if (!key_map)
263 return -ENOMEM;
264 key_maps[s] = key_map;
265 key_map[0] = U(K_ALLOCATED);
266 for (j = 1; j < NR_KEYS; j++)
267 key_map[j] = U(K_HOLE);
268 keymap_count++;
269 }
270 ov = U(key_map[i]);
271 if (v == ov)
272 break; /* nothing to do */
273 /*
274 * Attention Key.
275 */
276 if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN))
277 return -EPERM;
278 key_map[i] = U(v);
279 if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
280 compute_shiftstate();
281 break;
282 }
283 return 0;
284}
285#undef i
286#undef s
287#undef v
288
289static inline int
290do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc, int perm)
291{
292 struct kbkeycode tmp;
293 int kc = 0;
294
295 if (copy_from_user(&tmp, user_kbkc, sizeof(struct kbkeycode)))
296 return -EFAULT;
297 switch (cmd) {
298 case KDGETKEYCODE:
299 kc = getkeycode(tmp.scancode);
300 if (kc >= 0)
301 kc = put_user(kc, &user_kbkc->keycode);
302 break;
303 case KDSETKEYCODE:
304 if (!perm)
305 return -EPERM;
306 kc = setkeycode(tmp.scancode, tmp.keycode);
307 break;
308 }
309 return kc;
310}
311
312static inline int
313do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
314{
315 struct kbsentry *kbs;
316 char *p;
317 u_char *q;
318 u_char __user *up;
319 int sz;
320 int delta;
321 char *first_free, *fj, *fnw;
322 int i, j, k;
323 int ret;
324
325 if (!capable(CAP_SYS_TTY_CONFIG))
326 perm = 0;
327
328 kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
329 if (!kbs) {
330 ret = -ENOMEM;
331 goto reterr;
332 }
220 333
334 /* we mostly copy too much here (512bytes), but who cares ;) */
335 if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
336 ret = -EFAULT;
337 goto reterr;
338 }
339 kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
340 i = kbs->kb_func;
341
342 switch (cmd) {
343 case KDGKBSENT:
344 sz = sizeof(kbs->kb_string) - 1; /* sz should have been
345 a struct member */
346 up = user_kdgkb->kb_string;
347 p = func_table[i];
348 if(p)
349 for ( ; *p && sz; p++, sz--)
350 if (put_user(*p, up++)) {
351 ret = -EFAULT;
352 goto reterr;
353 }
354 if (put_user('\0', up)) {
355 ret = -EFAULT;
356 goto reterr;
357 }
358 kfree(kbs);
359 return ((p && *p) ? -EOVERFLOW : 0);
360 case KDSKBSENT:
361 if (!perm) {
362 ret = -EPERM;
363 goto reterr;
364 }
365
366 q = func_table[i];
367 first_free = funcbufptr + (funcbufsize - funcbufleft);
368 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
369 ;
370 if (j < MAX_NR_FUNC)
371 fj = func_table[j];
372 else
373 fj = first_free;
374
375 delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
376 if (delta <= funcbufleft) { /* it fits in current buf */
377 if (j < MAX_NR_FUNC) {
378 memmove(fj + delta, fj, first_free - fj);
379 for (k = j; k < MAX_NR_FUNC; k++)
380 if (func_table[k])
381 func_table[k] += delta;
382 }
383 if (!q)
384 func_table[i] = fj;
385 funcbufleft -= delta;
386 } else { /* allocate a larger buffer */
387 sz = 256;
388 while (sz < funcbufsize - funcbufleft + delta)
389 sz <<= 1;
390 fnw = kmalloc(sz, GFP_KERNEL);
391 if(!fnw) {
392 ret = -ENOMEM;
393 goto reterr;
394 }
395
396 if (!q)
397 func_table[i] = fj;
398 if (fj > funcbufptr)
399 memmove(fnw, funcbufptr, fj - funcbufptr);
400 for (k = 0; k < j; k++)
401 if (func_table[k])
402 func_table[k] = fnw + (func_table[k] - funcbufptr);
403
404 if (first_free > fj) {
405 memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
406 for (k = j; k < MAX_NR_FUNC; k++)
407 if (func_table[k])
408 func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
409 }
410 if (funcbufptr != func_buf)
411 kfree(funcbufptr);
412 funcbufptr = fnw;
413 funcbufleft = funcbufleft - delta + sz - funcbufsize;
414 funcbufsize = sz;
415 }
416 strcpy(func_table[i], kbs->kb_string);
417 break;
418 }
419 ret = 0;
420reterr:
421 kfree(kbs);
422 return ret;
423}
221 424
222static inline int 425static inline int
223do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op) 426do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op)
@@ -294,6 +497,7 @@ int vt_ioctl(struct tty_struct *tty,
294{ 497{
295 struct vc_data *vc = tty->driver_data; 498 struct vc_data *vc = tty->driver_data;
296 struct console_font_op op; /* used in multiple places here */ 499 struct console_font_op op; /* used in multiple places here */
500 struct kbd_struct * kbd;
297 unsigned int console; 501 unsigned int console;
298 unsigned char ucval; 502 unsigned char ucval;
299 unsigned int uival; 503 unsigned int uival;
@@ -303,6 +507,7 @@ int vt_ioctl(struct tty_struct *tty,
303 507
304 console = vc->vc_num; 508 console = vc->vc_num;
305 509
510 tty_lock();
306 511
307 if (!vc_cons_allocated(console)) { /* impossible? */ 512 if (!vc_cons_allocated(console)) { /* impossible? */
308 ret = -ENOIOCTLCMD; 513 ret = -ENOIOCTLCMD;
@@ -318,18 +523,19 @@ int vt_ioctl(struct tty_struct *tty,
318 if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG)) 523 if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
319 perm = 1; 524 perm = 1;
320 525
526 kbd = kbd_table + console;
321 switch (cmd) { 527 switch (cmd) {
322 case TIOCLINUX: 528 case TIOCLINUX:
323 ret = tioclinux(tty, arg); 529 ret = tioclinux(tty, arg);
324 break; 530 break;
325 case KIOCSOUND: 531 case KIOCSOUND:
326 if (!perm) 532 if (!perm)
327 return -EPERM; 533 goto eperm;
328 /* 534 /*
329 * The use of PIT_TICK_RATE is historic, it used to be 535 * The use of PIT_TICK_RATE is historic, it used to be
330 * the platform-dependent CLOCK_TICK_RATE between 2.6.12 536 * the platform-dependent CLOCK_TICK_RATE between 2.6.12
331 * and 2.6.36, which was a minor but unfortunate ABI 537 * and 2.6.36, which was a minor but unfortunate ABI
332 * change. kd_mksound is locked by the input layer. 538 * change.
333 */ 539 */
334 if (arg) 540 if (arg)
335 arg = PIT_TICK_RATE / arg; 541 arg = PIT_TICK_RATE / arg;
@@ -338,7 +544,7 @@ int vt_ioctl(struct tty_struct *tty,
338 544
339 case KDMKTONE: 545 case KDMKTONE:
340 if (!perm) 546 if (!perm)
341 return -EPERM; 547 goto eperm;
342 { 548 {
343 unsigned int ticks, count; 549 unsigned int ticks, count;
344 550
@@ -356,11 +562,10 @@ int vt_ioctl(struct tty_struct *tty,
356 562
357 case KDGKBTYPE: 563 case KDGKBTYPE:
358 /* 564 /*
359 * this is naïve. 565 * this is naive.
360 */ 566 */
361 ucval = KB_101; 567 ucval = KB_101;
362 ret = put_user(ucval, (char __user *)arg); 568 goto setchar;
363 break;
364 569
365 /* 570 /*
366 * These cannot be implemented on any machine that implements 571 * These cannot be implemented on any machine that implements
@@ -374,8 +579,6 @@ int vt_ioctl(struct tty_struct *tty,
374 /* 579 /*
375 * KDADDIO and KDDELIO may be able to add ports beyond what 580 * KDADDIO and KDDELIO may be able to add ports beyond what
376 * we reject here, but to be safe... 581 * we reject here, but to be safe...
377 *
378 * These are locked internally via sys_ioperm
379 */ 582 */
380 if (arg < GPFIRST || arg > GPLAST) { 583 if (arg < GPFIRST || arg > GPLAST) {
381 ret = -EINVAL; 584 ret = -EINVAL;
@@ -398,7 +601,7 @@ int vt_ioctl(struct tty_struct *tty,
398 struct kbd_repeat kbrep; 601 struct kbd_repeat kbrep;
399 602
400 if (!capable(CAP_SYS_TTY_CONFIG)) 603 if (!capable(CAP_SYS_TTY_CONFIG))
401 return -EPERM; 604 goto eperm;
402 605
403 if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) { 606 if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) {
404 ret = -EFAULT; 607 ret = -EFAULT;
@@ -422,7 +625,7 @@ int vt_ioctl(struct tty_struct *tty,
422 * need to restore their engine state. --BenH 625 * need to restore their engine state. --BenH
423 */ 626 */
424 if (!perm) 627 if (!perm)
425 return -EPERM; 628 goto eperm;
426 switch (arg) { 629 switch (arg) {
427 case KD_GRAPHICS: 630 case KD_GRAPHICS:
428 break; 631 break;
@@ -435,7 +638,6 @@ int vt_ioctl(struct tty_struct *tty,
435 ret = -EINVAL; 638 ret = -EINVAL;
436 goto out; 639 goto out;
437 } 640 }
438 /* FIXME: this needs the console lock extending */
439 if (vc->vc_mode == (unsigned char) arg) 641 if (vc->vc_mode == (unsigned char) arg)
440 break; 642 break;
441 vc->vc_mode = (unsigned char) arg; 643 vc->vc_mode = (unsigned char) arg;
@@ -467,26 +669,69 @@ int vt_ioctl(struct tty_struct *tty,
467 669
468 case KDSKBMODE: 670 case KDSKBMODE:
469 if (!perm) 671 if (!perm)
470 return -EPERM; 672 goto eperm;
471 ret = vt_do_kdskbmode(console, arg); 673 switch(arg) {
472 if (ret == 0) 674 case K_RAW:
473 tty_ldisc_flush(tty); 675 kbd->kbdmode = VC_RAW;
676 break;
677 case K_MEDIUMRAW:
678 kbd->kbdmode = VC_MEDIUMRAW;
679 break;
680 case K_XLATE:
681 kbd->kbdmode = VC_XLATE;
682 compute_shiftstate();
683 break;
684 case K_UNICODE:
685 kbd->kbdmode = VC_UNICODE;
686 compute_shiftstate();
687 break;
688 case K_OFF:
689 kbd->kbdmode = VC_OFF;
690 break;
691 default:
692 ret = -EINVAL;
693 goto out;
694 }
695 tty_ldisc_flush(tty);
474 break; 696 break;
475 697
476 case KDGKBMODE: 698 case KDGKBMODE:
477 uival = vt_do_kdgkbmode(console); 699 switch (kbd->kbdmode) {
478 ret = put_user(uival, (int __user *)arg); 700 case VC_RAW:
479 break; 701 uival = K_RAW;
702 break;
703 case VC_MEDIUMRAW:
704 uival = K_MEDIUMRAW;
705 break;
706 case VC_UNICODE:
707 uival = K_UNICODE;
708 break;
709 case VC_OFF:
710 uival = K_OFF;
711 break;
712 default:
713 uival = K_XLATE;
714 break;
715 }
716 goto setint;
480 717
481 /* this could be folded into KDSKBMODE, but for compatibility 718 /* this could be folded into KDSKBMODE, but for compatibility
482 reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */ 719 reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
483 case KDSKBMETA: 720 case KDSKBMETA:
484 ret = vt_do_kdskbmeta(console, arg); 721 switch(arg) {
722 case K_METABIT:
723 clr_vc_kbd_mode(kbd, VC_META);
724 break;
725 case K_ESCPREFIX:
726 set_vc_kbd_mode(kbd, VC_META);
727 break;
728 default:
729 ret = -EINVAL;
730 }
485 break; 731 break;
486 732
487 case KDGKBMETA: 733 case KDGKBMETA:
488 /* FIXME: should review whether this is worth locking */ 734 uival = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT);
489 uival = vt_do_kdgkbmeta(console);
490 setint: 735 setint:
491 ret = put_user(uival, (int __user *)arg); 736 ret = put_user(uival, (int __user *)arg);
492 break; 737 break;
@@ -495,35 +740,133 @@ int vt_ioctl(struct tty_struct *tty,
495 case KDSETKEYCODE: 740 case KDSETKEYCODE:
496 if(!capable(CAP_SYS_TTY_CONFIG)) 741 if(!capable(CAP_SYS_TTY_CONFIG))
497 perm = 0; 742 perm = 0;
498 ret = vt_do_kbkeycode_ioctl(cmd, up, perm); 743 ret = do_kbkeycode_ioctl(cmd, up, perm);
499 break; 744 break;
500 745
501 case KDGKBENT: 746 case KDGKBENT:
502 case KDSKBENT: 747 case KDSKBENT:
503 ret = vt_do_kdsk_ioctl(cmd, up, perm, console); 748 ret = do_kdsk_ioctl(cmd, up, perm, kbd);
504 break; 749 break;
505 750
506 case KDGKBSENT: 751 case KDGKBSENT:
507 case KDSKBSENT: 752 case KDSKBSENT:
508 ret = vt_do_kdgkb_ioctl(cmd, up, perm); 753 ret = do_kdgkb_ioctl(cmd, up, perm);
509 break; 754 break;
510 755
511 /* Diacritical processing. Handled in keyboard.c as it has
512 to operate on the keyboard locks and structures */
513 case KDGKBDIACR: 756 case KDGKBDIACR:
757 {
758 struct kbdiacrs __user *a = up;
759 struct kbdiacr diacr;
760 int i;
761
762 if (put_user(accent_table_size, &a->kb_cnt)) {
763 ret = -EFAULT;
764 break;
765 }
766 for (i = 0; i < accent_table_size; i++) {
767 diacr.diacr = conv_uni_to_8bit(accent_table[i].diacr);
768 diacr.base = conv_uni_to_8bit(accent_table[i].base);
769 diacr.result = conv_uni_to_8bit(accent_table[i].result);
770 if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) {
771 ret = -EFAULT;
772 break;
773 }
774 }
775 break;
776 }
514 case KDGKBDIACRUC: 777 case KDGKBDIACRUC:
778 {
779 struct kbdiacrsuc __user *a = up;
780
781 if (put_user(accent_table_size, &a->kb_cnt))
782 ret = -EFAULT;
783 else if (copy_to_user(a->kbdiacruc, accent_table,
784 accent_table_size*sizeof(struct kbdiacruc)))
785 ret = -EFAULT;
786 break;
787 }
788
515 case KDSKBDIACR: 789 case KDSKBDIACR:
790 {
791 struct kbdiacrs __user *a = up;
792 struct kbdiacr diacr;
793 unsigned int ct;
794 int i;
795
796 if (!perm)
797 goto eperm;
798 if (get_user(ct,&a->kb_cnt)) {
799 ret = -EFAULT;
800 break;
801 }
802 if (ct >= MAX_DIACR) {
803 ret = -EINVAL;
804 break;
805 }
806 accent_table_size = ct;
807 for (i = 0; i < ct; i++) {
808 if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr))) {
809 ret = -EFAULT;
810 break;
811 }
812 accent_table[i].diacr = conv_8bit_to_uni(diacr.diacr);
813 accent_table[i].base = conv_8bit_to_uni(diacr.base);
814 accent_table[i].result = conv_8bit_to_uni(diacr.result);
815 }
816 break;
817 }
818
516 case KDSKBDIACRUC: 819 case KDSKBDIACRUC:
517 ret = vt_do_diacrit(cmd, up, perm); 820 {
821 struct kbdiacrsuc __user *a = up;
822 unsigned int ct;
823
824 if (!perm)
825 goto eperm;
826 if (get_user(ct,&a->kb_cnt)) {
827 ret = -EFAULT;
828 break;
829 }
830 if (ct >= MAX_DIACR) {
831 ret = -EINVAL;
832 break;
833 }
834 accent_table_size = ct;
835 if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc)))
836 ret = -EFAULT;
518 break; 837 break;
838 }
519 839
520 /* the ioctls below read/set the flags usually shown in the leds */ 840 /* the ioctls below read/set the flags usually shown in the leds */
521 /* don't use them - they will go away without warning */ 841 /* don't use them - they will go away without warning */
522 case KDGKBLED: 842 case KDGKBLED:
843 ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
844 goto setchar;
845
523 case KDSKBLED: 846 case KDSKBLED:
847 if (!perm)
848 goto eperm;
849 if (arg & ~0x77) {
850 ret = -EINVAL;
851 break;
852 }
853 kbd->ledflagstate = (arg & 7);
854 kbd->default_ledflagstate = ((arg >> 4) & 7);
855 set_leds();
856 break;
857
858 /* the ioctls below only set the lights, not the functions */
859 /* for those, see KDGKBLED and KDSKBLED above */
524 case KDGETLED: 860 case KDGETLED:
861 ucval = getledstate();
862 setchar:
863 ret = put_user(ucval, (char __user *)arg);
864 break;
865
525 case KDSETLED: 866 case KDSETLED:
526 ret = vt_do_kdskled(console, cmd, arg, perm); 867 if (!perm)
868 goto eperm;
869 setledstate(kbd, arg);
527 break; 870 break;
528 871
529 /* 872 /*
@@ -536,7 +879,7 @@ int vt_ioctl(struct tty_struct *tty,
536 case KDSIGACCEPT: 879 case KDSIGACCEPT:
537 { 880 {
538 if (!perm || !capable(CAP_KILL)) 881 if (!perm || !capable(CAP_KILL))
539 return -EPERM; 882 goto eperm;
540 if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) 883 if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
541 ret = -EINVAL; 884 ret = -EINVAL;
542 else { 885 else {
@@ -554,7 +897,7 @@ int vt_ioctl(struct tty_struct *tty,
554 struct vt_mode tmp; 897 struct vt_mode tmp;
555 898
556 if (!perm) 899 if (!perm)
557 return -EPERM; 900 goto eperm;
558 if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) { 901 if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) {
559 ret = -EFAULT; 902 ret = -EFAULT;
560 goto out; 903 goto out;
@@ -600,7 +943,6 @@ int vt_ioctl(struct tty_struct *tty,
600 struct vt_stat __user *vtstat = up; 943 struct vt_stat __user *vtstat = up;
601 unsigned short state, mask; 944 unsigned short state, mask;
602 945
603 /* Review: FIXME: Console lock ? */
604 if (put_user(fg_console + 1, &vtstat->v_active)) 946 if (put_user(fg_console + 1, &vtstat->v_active))
605 ret = -EFAULT; 947 ret = -EFAULT;
606 else { 948 else {
@@ -618,7 +960,6 @@ int vt_ioctl(struct tty_struct *tty,
618 * Returns the first available (non-opened) console. 960 * Returns the first available (non-opened) console.
619 */ 961 */
620 case VT_OPENQRY: 962 case VT_OPENQRY:
621 /* FIXME: locking ? - but then this is a stupid API */
622 for (i = 0; i < MAX_NR_CONSOLES; ++i) 963 for (i = 0; i < MAX_NR_CONSOLES; ++i)
623 if (! VT_IS_IN_USE(i)) 964 if (! VT_IS_IN_USE(i))
624 break; 965 break;
@@ -632,7 +973,7 @@ int vt_ioctl(struct tty_struct *tty,
632 */ 973 */
633 case VT_ACTIVATE: 974 case VT_ACTIVATE:
634 if (!perm) 975 if (!perm)
635 return -EPERM; 976 goto eperm;
636 if (arg == 0 || arg > MAX_NR_CONSOLES) 977 if (arg == 0 || arg > MAX_NR_CONSOLES)
637 ret = -ENXIO; 978 ret = -ENXIO;
638 else { 979 else {
@@ -651,7 +992,7 @@ int vt_ioctl(struct tty_struct *tty,
651 struct vt_setactivate vsa; 992 struct vt_setactivate vsa;
652 993
653 if (!perm) 994 if (!perm)
654 return -EPERM; 995 goto eperm;
655 996
656 if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg, 997 if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
657 sizeof(struct vt_setactivate))) { 998 sizeof(struct vt_setactivate))) {
@@ -679,7 +1020,6 @@ int vt_ioctl(struct tty_struct *tty,
679 if (ret) 1020 if (ret)
680 break; 1021 break;
681 /* Commence switch and lock */ 1022 /* Commence switch and lock */
682 /* Review set_console locks */
683 set_console(vsa.console); 1023 set_console(vsa.console);
684 } 1024 }
685 break; 1025 break;
@@ -690,7 +1030,7 @@ int vt_ioctl(struct tty_struct *tty,
690 */ 1030 */
691 case VT_WAITACTIVE: 1031 case VT_WAITACTIVE:
692 if (!perm) 1032 if (!perm)
693 return -EPERM; 1033 goto eperm;
694 if (arg == 0 || arg > MAX_NR_CONSOLES) 1034 if (arg == 0 || arg > MAX_NR_CONSOLES)
695 ret = -ENXIO; 1035 ret = -ENXIO;
696 else 1036 else
@@ -709,17 +1049,16 @@ int vt_ioctl(struct tty_struct *tty,
709 */ 1049 */
710 case VT_RELDISP: 1050 case VT_RELDISP:
711 if (!perm) 1051 if (!perm)
712 return -EPERM; 1052 goto eperm;
713 1053
714 console_lock();
715 if (vc->vt_mode.mode != VT_PROCESS) { 1054 if (vc->vt_mode.mode != VT_PROCESS) {
716 console_unlock();
717 ret = -EINVAL; 1055 ret = -EINVAL;
718 break; 1056 break;
719 } 1057 }
720 /* 1058 /*
721 * Switching-from response 1059 * Switching-from response
722 */ 1060 */
1061 console_lock();
723 if (vc->vt_newvt >= 0) { 1062 if (vc->vt_newvt >= 0) {
724 if (arg == 0) 1063 if (arg == 0)
725 /* 1064 /*
@@ -796,7 +1135,7 @@ int vt_ioctl(struct tty_struct *tty,
796 1135
797 ushort ll,cc; 1136 ushort ll,cc;
798 if (!perm) 1137 if (!perm)
799 return -EPERM; 1138 goto eperm;
800 if (get_user(ll, &vtsizes->v_rows) || 1139 if (get_user(ll, &vtsizes->v_rows) ||
801 get_user(cc, &vtsizes->v_cols)) 1140 get_user(cc, &vtsizes->v_cols))
802 ret = -EFAULT; 1141 ret = -EFAULT;
@@ -807,7 +1146,6 @@ int vt_ioctl(struct tty_struct *tty,
807 1146
808 if (vc) { 1147 if (vc) {
809 vc->vc_resize_user = 1; 1148 vc->vc_resize_user = 1;
810 /* FIXME: review v tty lock */
811 vc_resize(vc_cons[i].d, cc, ll); 1149 vc_resize(vc_cons[i].d, cc, ll);
812 } 1150 }
813 } 1151 }
@@ -821,7 +1159,7 @@ int vt_ioctl(struct tty_struct *tty,
821 struct vt_consize __user *vtconsize = up; 1159 struct vt_consize __user *vtconsize = up;
822 ushort ll,cc,vlin,clin,vcol,ccol; 1160 ushort ll,cc,vlin,clin,vcol,ccol;
823 if (!perm) 1161 if (!perm)
824 return -EPERM; 1162 goto eperm;
825 if (!access_ok(VERIFY_READ, vtconsize, 1163 if (!access_ok(VERIFY_READ, vtconsize,
826 sizeof(struct vt_consize))) { 1164 sizeof(struct vt_consize))) {
827 ret = -EFAULT; 1165 ret = -EFAULT;
@@ -877,7 +1215,7 @@ int vt_ioctl(struct tty_struct *tty,
877 1215
878 case PIO_FONT: { 1216 case PIO_FONT: {
879 if (!perm) 1217 if (!perm)
880 return -EPERM; 1218 goto eperm;
881 op.op = KD_FONT_OP_SET; 1219 op.op = KD_FONT_OP_SET;
882 op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */ 1220 op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */
883 op.width = 8; 1221 op.width = 8;
@@ -918,7 +1256,7 @@ int vt_ioctl(struct tty_struct *tty,
918 case PIO_FONTRESET: 1256 case PIO_FONTRESET:
919 { 1257 {
920 if (!perm) 1258 if (!perm)
921 return -EPERM; 1259 goto eperm;
922 1260
923#ifdef BROKEN_GRAPHICS_PROGRAMS 1261#ifdef BROKEN_GRAPHICS_PROGRAMS
924 /* With BROKEN_GRAPHICS_PROGRAMS defined, the default 1262 /* With BROKEN_GRAPHICS_PROGRAMS defined, the default
@@ -932,9 +1270,7 @@ int vt_ioctl(struct tty_struct *tty,
932 ret = con_font_op(vc_cons[fg_console].d, &op); 1270 ret = con_font_op(vc_cons[fg_console].d, &op);
933 if (ret) 1271 if (ret)
934 break; 1272 break;
935 console_lock();
936 con_set_default_unimap(vc_cons[fg_console].d); 1273 con_set_default_unimap(vc_cons[fg_console].d);
937 console_unlock();
938 break; 1274 break;
939 } 1275 }
940#endif 1276#endif
@@ -946,7 +1282,7 @@ int vt_ioctl(struct tty_struct *tty,
946 break; 1282 break;
947 } 1283 }
948 if (!perm && op.op != KD_FONT_OP_GET) 1284 if (!perm && op.op != KD_FONT_OP_GET)
949 return -EPERM; 1285 goto eperm;
950 ret = con_font_op(vc, &op); 1286 ret = con_font_op(vc, &op);
951 if (ret) 1287 if (ret)
952 break; 1288 break;
@@ -980,7 +1316,7 @@ int vt_ioctl(struct tty_struct *tty,
980 case PIO_UNIMAPCLR: 1316 case PIO_UNIMAPCLR:
981 { struct unimapinit ui; 1317 { struct unimapinit ui;
982 if (!perm) 1318 if (!perm)
983 return -EPERM; 1319 goto eperm;
984 ret = copy_from_user(&ui, up, sizeof(struct unimapinit)); 1320 ret = copy_from_user(&ui, up, sizeof(struct unimapinit));
985 if (ret) 1321 if (ret)
986 ret = -EFAULT; 1322 ret = -EFAULT;
@@ -996,12 +1332,12 @@ int vt_ioctl(struct tty_struct *tty,
996 1332
997 case VT_LOCKSWITCH: 1333 case VT_LOCKSWITCH:
998 if (!capable(CAP_SYS_TTY_CONFIG)) 1334 if (!capable(CAP_SYS_TTY_CONFIG))
999 return -EPERM; 1335 goto eperm;
1000 vt_dont_switch = 1; 1336 vt_dont_switch = 1;
1001 break; 1337 break;
1002 case VT_UNLOCKSWITCH: 1338 case VT_UNLOCKSWITCH:
1003 if (!capable(CAP_SYS_TTY_CONFIG)) 1339 if (!capable(CAP_SYS_TTY_CONFIG))
1004 return -EPERM; 1340 goto eperm;
1005 vt_dont_switch = 0; 1341 vt_dont_switch = 0;
1006 break; 1342 break;
1007 case VT_GETHIFONTMASK: 1343 case VT_GETHIFONTMASK:
@@ -1015,13 +1351,17 @@ int vt_ioctl(struct tty_struct *tty,
1015 ret = -ENOIOCTLCMD; 1351 ret = -ENOIOCTLCMD;
1016 } 1352 }
1017out: 1353out:
1354 tty_unlock();
1018 return ret; 1355 return ret;
1356eperm:
1357 ret = -EPERM;
1358 goto out;
1019} 1359}
1020 1360
1021void reset_vc(struct vc_data *vc) 1361void reset_vc(struct vc_data *vc)
1022{ 1362{
1023 vc->vc_mode = KD_TEXT; 1363 vc->vc_mode = KD_TEXT;
1024 vt_reset_unicode(vc->vc_num); 1364 kbd_table[vc->vc_num].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
1025 vc->vt_mode.mode = VT_AUTO; 1365 vc->vt_mode.mode = VT_AUTO;
1026 vc->vt_mode.waitv = 0; 1366 vc->vt_mode.waitv = 0;
1027 vc->vt_mode.relsig = 0; 1367 vc->vt_mode.relsig = 0;
@@ -1044,7 +1384,6 @@ void vc_SAK(struct work_struct *work)
1044 console_lock(); 1384 console_lock();
1045 vc = vc_con->d; 1385 vc = vc_con->d;
1046 if (vc) { 1386 if (vc) {
1047 /* FIXME: review tty ref counting */
1048 tty = vc->port.tty; 1387 tty = vc->port.tty;
1049 /* 1388 /*
1050 * SAK should also work in all raw modes and reset 1389 * SAK should also work in all raw modes and reset
@@ -1124,6 +1463,7 @@ compat_kdfontop_ioctl(struct compat_console_font_op __user *fontop,
1124 if (!perm && op->op != KD_FONT_OP_GET) 1463 if (!perm && op->op != KD_FONT_OP_GET)
1125 return -EPERM; 1464 return -EPERM;
1126 op->data = compat_ptr(((struct compat_console_font_op *)op)->data); 1465 op->data = compat_ptr(((struct compat_console_font_op *)op)->data);
1466 op->flags |= KD_FONT_FLAG_OLD;
1127 i = con_font_op(vc, op); 1467 i = con_font_op(vc, op);
1128 if (i) 1468 if (i)
1129 return i; 1469 return i;
@@ -1177,6 +1517,8 @@ long vt_compat_ioctl(struct tty_struct *tty,
1177 1517
1178 console = vc->vc_num; 1518 console = vc->vc_num;
1179 1519
1520 tty_lock();
1521
1180 if (!vc_cons_allocated(console)) { /* impossible? */ 1522 if (!vc_cons_allocated(console)) { /* impossible? */
1181 ret = -ENOIOCTLCMD; 1523 ret = -ENOIOCTLCMD;
1182 goto out; 1524 goto out;
@@ -1242,9 +1584,11 @@ long vt_compat_ioctl(struct tty_struct *tty,
1242 goto fallback; 1584 goto fallback;
1243 } 1585 }
1244out: 1586out:
1587 tty_unlock();
1245 return ret; 1588 return ret;
1246 1589
1247fallback: 1590fallback:
1591 tty_unlock();
1248 return vt_ioctl(tty, cmd, arg); 1592 return vt_ioctl(tty, cmd, arg);
1249} 1593}
1250 1594
@@ -1430,10 +1774,13 @@ int vt_move_to_console(unsigned int vt, int alloc)
1430 return -EIO; 1774 return -EIO;
1431 } 1775 }
1432 console_unlock(); 1776 console_unlock();
1777 tty_lock();
1433 if (vt_waitactive(vt + 1)) { 1778 if (vt_waitactive(vt + 1)) {
1434 pr_debug("Suspend: Can't switch VCs."); 1779 pr_debug("Suspend: Can't switch VCs.");
1780 tty_unlock();
1435 return -EINTR; 1781 return -EINTR;
1436 } 1782 }
1783 tty_unlock();
1437 return prev; 1784 return prev;
1438} 1785}
1439 1786