diff options
author | Alan Cox <alan@linux.intel.com> | 2012-02-28 09:49:23 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-03-08 13:50:35 -0500 |
commit | 079c9534a96da9a85a2a2f9715851050fbfbf749 (patch) | |
tree | 0e3782ff6d341f38c6f0b3840cb3c8f2bc922df8 /drivers/tty/vt/vt.c | |
parent | 0fb8379dab9f97e4c56de8f9ea772c10eda27561 (diff) |
vt:tackle kbd_table
Keyboard struct lifetime is easy, but the locking is not and is completely
ignored by the existing code. Tackle this one head on
- Make the kbd_table private so we can run down all direct users
- Hoick the relevant ioctl handlers into the keyboard layer
- Lock them with the keyboard lock so they don't change mid keypress
- Add helpers for things like console stop/start so we isolate the poking
around properly
- Tweak the braille console so it still builds
There are a couple of FIXME locking cases left for ioctls that are so hideous
they should be addressed in a later patch. After this patch the kbd_table is
private and all the keyboard jiggery pokery is in one place.
This update fixes speakup and also a memory leak in the original.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/vt/vt.c')
-rw-r--r-- | drivers/tty/vt/vt.c | 27 |
1 files changed, 8 insertions, 19 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index e716839fab6e..ecdcc8a8f0ca 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -1028,9 +1028,9 @@ void vc_deallocate(unsigned int currcons) | |||
1028 | * VT102 emulator | 1028 | * VT102 emulator |
1029 | */ | 1029 | */ |
1030 | 1030 | ||
1031 | #define set_kbd(vc, x) set_vc_kbd_mode(kbd_table + (vc)->vc_num, (x)) | 1031 | #define set_kbd(vc, x) vt_set_kbd_mode_bit((vc)->vc_num, (x)) |
1032 | #define clr_kbd(vc, x) clr_vc_kbd_mode(kbd_table + (vc)->vc_num, (x)) | 1032 | #define clr_kbd(vc, x) vt_clr_kbd_mode_bit((vc)->vc_num, (x)) |
1033 | #define is_kbd(vc, x) vc_kbd_mode(kbd_table + (vc)->vc_num, (x)) | 1033 | #define is_kbd(vc, x) vt_get_kbd_mode_bit((vc)->vc_num, (x)) |
1034 | 1034 | ||
1035 | #define decarm VC_REPEAT | 1035 | #define decarm VC_REPEAT |
1036 | #define decckm VC_CKMODE | 1036 | #define decckm VC_CKMODE |
@@ -1652,16 +1652,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear) | |||
1652 | vc->vc_deccm = global_cursor_default; | 1652 | vc->vc_deccm = global_cursor_default; |
1653 | vc->vc_decim = 0; | 1653 | vc->vc_decim = 0; |
1654 | 1654 | ||
1655 | set_kbd(vc, decarm); | 1655 | vt_reset_keyboard(vc->vc_num); |
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 */ | ||
1665 | 1656 | ||
1666 | vc->vc_cursor_type = cur_default; | 1657 | vc->vc_cursor_type = cur_default; |
1667 | vc->vc_complement_mask = vc->vc_s_complement_mask; | 1658 | vc->vc_complement_mask = vc->vc_s_complement_mask; |
@@ -1979,7 +1970,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) | |||
1979 | case 'q': /* DECLL - but only 3 leds */ | 1970 | case 'q': /* DECLL - but only 3 leds */ |
1980 | /* map 0,1,2,3 to 0,1,2,4 */ | 1971 | /* map 0,1,2,3 to 0,1,2,4 */ |
1981 | if (vc->vc_par[0] < 4) | 1972 | if (vc->vc_par[0] < 4) |
1982 | setledstate(kbd_table + vc->vc_num, | 1973 | vt_set_led_state(vc->vc_num, |
1983 | (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4); | 1974 | (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4); |
1984 | return; | 1975 | return; |
1985 | case 'r': | 1976 | case 'r': |
@@ -2642,7 +2633,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2642 | * kernel-internal variable; programs not closely | 2633 | * kernel-internal variable; programs not closely |
2643 | * related to the kernel should not use this. | 2634 | * related to the kernel should not use this. |
2644 | */ | 2635 | */ |
2645 | data = shift_state; | 2636 | data = vt_get_shift_state(); |
2646 | ret = __put_user(data, p); | 2637 | ret = __put_user(data, p); |
2647 | break; | 2638 | break; |
2648 | case TIOCL_GETMOUSEREPORTING: | 2639 | case TIOCL_GETMOUSEREPORTING: |
@@ -2753,8 +2744,7 @@ static void con_stop(struct tty_struct *tty) | |||
2753 | console_num = tty->index; | 2744 | console_num = tty->index; |
2754 | if (!vc_cons_allocated(console_num)) | 2745 | if (!vc_cons_allocated(console_num)) |
2755 | return; | 2746 | return; |
2756 | set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK); | 2747 | vt_kbd_con_stop(console_num); |
2757 | set_leds(); | ||
2758 | } | 2748 | } |
2759 | 2749 | ||
2760 | /* | 2750 | /* |
@@ -2768,8 +2758,7 @@ static void con_start(struct tty_struct *tty) | |||
2768 | console_num = tty->index; | 2758 | console_num = tty->index; |
2769 | if (!vc_cons_allocated(console_num)) | 2759 | if (!vc_cons_allocated(console_num)) |
2770 | return; | 2760 | return; |
2771 | clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK); | 2761 | vt_kbd_con_start(console_num); |
2772 | set_leds(); | ||
2773 | } | 2762 | } |
2774 | 2763 | ||
2775 | static void con_flush_chars(struct tty_struct *tty) | 2764 | static void con_flush_chars(struct tty_struct *tty) |