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>
This commit is contained in:
Alan Cox 2012-02-28 14:49:23 +00:00 committed by Greg Kroah-Hartman
commit 079c9534a9
10 changed files with 660 additions and 377 deletions

View file

@ -7,8 +7,6 @@
extern struct tasklet_struct keyboard_tasklet;
extern int shift_state;
extern char *func_table[MAX_NR_FUNC];
extern char func_buf[];
extern char *funcbufptr;
@ -65,8 +63,6 @@ struct kbd_struct {
#define VC_META 4 /* 0 - meta, 1 - meta=prefix with ESC */
};
extern struct kbd_struct kbd_table[];
extern int kbd_init(void);
extern unsigned char getledstate(void);
@ -79,6 +75,7 @@ extern void (*kbd_ledfunc)(unsigned int led);
extern int set_console(int nr);
extern void schedule_console_callback(void);
/* FIXME: review locking for vt.c callers */
static inline void set_leds(void)
{
tasklet_schedule(&keyboard_tasklet);
@ -142,8 +139,6 @@ static inline void chg_vc_kbd_led(struct kbd_struct * kbd, int flag)
struct console;
int getkeycode(unsigned int scancode);
int setkeycode(unsigned int scancode, unsigned int keycode);
void compute_shiftstate(void);
/* defkeymap.c */

View file

@ -24,8 +24,6 @@
#ifdef __KERNEL__
struct notifier_block;
extern const int NR_TYPES;
extern const int max_vals[];
extern unsigned short *key_maps[MAX_NR_KEYMAPS];
extern unsigned short plain_map[NR_KEYS];

View file

@ -169,5 +169,28 @@ extern void hide_boot_cursor(bool hide);
/* keyboard provided interfaces */
extern int vt_do_diacrit(unsigned int cmd, void __user *up, int eperm);
extern int vt_do_kdskbmode(int console, unsigned int arg);
extern int vt_do_kdskbmeta(int console, unsigned int arg);
extern int vt_do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc,
int perm);
extern int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe,
int perm, int console);
extern int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb,
int perm);
extern int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm);
extern int vt_do_kdgkbmode(int console);
extern int vt_do_kdgkbmeta(int console);
extern void vt_reset_unicode(int console);
extern int vt_get_shift_state(void);
extern void vt_reset_keyboard(int console);
extern int vt_get_leds(int console, int flag);
extern int vt_get_kbd_mode_bit(int console, int bit);
extern void vt_set_kbd_mode_bit(int console, int bit);
extern void vt_clr_kbd_mode_bit(int console, int bit);
extern void vt_set_led_state(int console, int leds);
extern void vt_set_led_state(int console, int leds);
extern void vt_kbd_con_start(int console);
extern void vt_kbd_con_stop(int console);
#endif /* _VT_KERN_H */