From patchwork Mon Mar 1 16:49:33 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Wessel X-Patchwork-Id: 82994 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o21GoMhE010119 for ; Mon, 1 Mar 2010 16:50:22 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751603Ab0CAQuI (ORCPT ); Mon, 1 Mar 2010 11:50:08 -0500 Received: from mail.windriver.com ([147.11.1.11]:45554 "EHLO mail.windriver.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751588Ab0CAQuE (ORCPT ); Mon, 1 Mar 2010 11:50:04 -0500 Received: from ALA-MAIL03.corp.ad.wrs.com (ala-mail03 [147.11.57.144]) by mail.windriver.com (8.14.3/8.14.3) with ESMTP id o21GnYeO011107; Mon, 1 Mar 2010 08:49:34 -0800 (PST) Received: from ala-mail06.corp.ad.wrs.com ([147.11.57.147]) by ALA-MAIL03.corp.ad.wrs.com with Microsoft SMTPSVC(6.0.3790.1830); Mon, 1 Mar 2010 08:49:34 -0800 Received: from [172.25.32.34] ([172.25.32.34]) by ala-mail06.corp.ad.wrs.com with Microsoft SMTPSVC(6.0.3790.1830); Mon, 1 Mar 2010 08:49:33 -0800 Message-ID: <4B8BF01D.7070507@windriver.com> Date: Mon, 01 Mar 2010 10:49:33 -0600 From: Jason Wessel User-Agent: Thunderbird 2.0.0.23 (X11/20090817) MIME-Version: 1.0 To: Dmitry Torokhov CC: linux-kernel@vger.kernel.org, kgdb-bugreport@lists.sourceforge.net, Greg Kroah-Hartman , linux-input@vger.kernel.org Subject: Re: [PATCH 23/28] keyboard, input: Add hook to input to allow low level event clear References: <1267132893-23624-1-git-send-email-jason.wessel@windriver.com> <1267132893-23624-24-git-send-email-jason.wessel@windriver.com> <20100226080329.GD17062@core.coreip.homeip.net> <4B87F17B.6040305@windriver.com> <20100227075528.GA793@core.coreip.homeip.net> <4B8B3B08.7000705@windriver.com> <20100301050437.GE765@core.coreip.homeip.net> In-Reply-To: <20100301050437.GE765@core.coreip.homeip.net> X-OriginalArrivalTime: 01 Mar 2010 16:49:33.0941 (UTC) FILETIME=[2BAF2250:01CAB95F] Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Mon, 01 Mar 2010 16:50:22 +0000 (UTC) --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -379,6 +379,32 @@ static void to_utf8(struct vc_data *vc, } } +static int kbd_dbg_clear_keys_helper(struct input_handle *handle, void *data) +{ + unsigned int *keycode = data; + input_inject_event(handle, EV_KEY, *keycode, 0); + return 0; +} + +/* Called to clear the any key presses after resuming the kernel. */ +void kbd_dbg_clear_keys(void) { + unsigned int i, j, k; + + for (i = 0; i < ARRAY_SIZE(key_down); i++) { + if (!key_down[i]) + continue; + + k = i * BITS_PER_LONG; + + for (j = 0; j < BITS_PER_LONG; j++, k++) { + if (!test_bit(k, key_down)) + continue; + input_handler_for_each_handle(&kbd_handler, &k, + kbd_dbg_clear_keys_helper); + } + } +} + /* * Called after returning from RAW mode or when changing consoles - recompute * shift_down[] and shift_state from key_down[] maybe called when keymap is @@ -1206,6 +1232,7 @@ static void kbd_keycode(unsigned int key if (sysrq_down && !down && keycode == sysrq_alt_use) sysrq_down = 0; if (sysrq_down && down && !rep) { + set_bit(keycode, key_down); handle_sysrq(kbd_sysrq_xlate[keycode], tty); return; } --- a/drivers/serial/kgdboc.c +++ b/drivers/serial/kgdboc.c @@ -17,6 +17,7 @@ #include #include #include +#include #define MAX_CONFIG_LEN 40 @@ -35,12 +36,16 @@ static struct tty_driver *kgdb_tty_drive static int kgdb_tty_line; #ifdef CONFIG_KDB_KEYBOARD +static bool kgdboc_use_kbd; + static int kgdboc_register_kbd(char **cptr) { + kgdboc_use_kbd = false; if (strncmp(*cptr, "kbd", 3) == 0) { if (kdb_poll_idx < KDB_POLL_FUNC_MAX) { kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char; kdb_poll_idx++; + kgdboc_use_kbd = true; if (cptr[0][3] == ',') *cptr += 4; else @@ -63,9 +68,16 @@ static void kgdboc_unregister_kbd(void) } } } + +static inline void kgdboc_clear_kbd(void) +{ + if (kgdboc_use_kbd) + kdb_clear_keys(); /* Release all pressed keys */ +} #else /* ! CONFIG_KDB_KEYBOARD */ #define kgdboc_register_kbd(x) 0 #define kgdboc_unregister_kbd() +#define kgdboc_clear_kbd() #endif /* ! CONFIG_KDB_KEYBOARD */ static int kgdboc_option_setup(char *opt) @@ -213,6 +225,7 @@ static void kgdboc_post_exp_handler(void /* decrement the module count when the debugger detaches */ if (!kgdb_connected) module_put(THIS_MODULE); + kgdboc_clear_kbd(); } static struct kgdb_io kgdboc_io_ops = { --- a/include/linux/kbd_kern.h +++ b/include/linux/kbd_kern.h @@ -144,6 +144,7 @@ struct console; int getkeycode(unsigned int scancode); int setkeycode(unsigned int scancode, unsigned int keycode); void compute_shiftstate(void); +void kbd_dbg_clear_keys(void); /* defkeymap.c */ --- a/include/linux/kdb.h +++ b/include/linux/kdb.h @@ -93,6 +93,9 @@ typedef int (*get_char_func)(void); extern get_char_func kdb_poll_funcs[]; extern int kdb_get_kbd_char(void); +/* KDB keyboard hooks */ +extern void kdb_clear_keys(void); + static inline int kdb_process_cpu(const struct task_struct *p) { --- a/kernel/debug/kdb/kdb_keyboard.c +++ b/kernel/debug/kdb/kdb_keyboard.c @@ -13,6 +13,7 @@ #include #include #include +#include /* Keyboard Controller Registers on normal PCs. */ @@ -210,3 +211,27 @@ int kdb_get_kbd_char(void) return keychar & 0xff; } EXPORT_SYMBOL_GPL(kdb_get_kbd_char); + +static bool dbg_keys_cleared; +/* + * input_dbg_clear_keys - Clear any keyboards if they have a call back, + * after returning from the kernel debugger + */ +static void kdb_keys_task(unsigned long not_used) +{ + if (!dbg_keys_cleared) + return; + kbd_dbg_clear_keys(); + dbg_keys_cleared = false; +} + +static DECLARE_TASKLET(kdb_keys_tasklet, kdb_keys_task, 0); + +void kdb_clear_keys(void) +{ + if (dbg_keys_cleared) + return; + dbg_keys_cleared = true; + tasklet_schedule(&kdb_keys_tasklet); +} +EXPORT_SYMBOL_GPL(kdb_clear_keys);