* [PATCH 1/3] keyboard, kgdboc: Allow key release on kernel resume
2010-10-07 20:35 [PATCH 0/3] input / sysrq fixes for use with kdb Jason Wessel
@ 2010-10-07 20:35 ` Jason Wessel
2010-10-07 20:35 ` [PATCH 2/3] keyboard, kdb: inject SYN events in kbd_clear_keys_helper Jason Wessel
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Jason Wessel @ 2010-10-07 20:35 UTC (permalink / raw)
To: dmitry.torokhov
Cc: kgdb-bugreport, Jason Wessel, Greg Kroah-Hartman, linux-kernel,
linux-input
When using a keyboard with kdb, a hook point to free all the
keystrokes is required for resuming kernel operations.
This is mainly because there is no way to force the end user to hold
down the original keys that were pressed prior to entering kdb when
resuming the kernel.
The kgdboc driver will call kbd_dbg_clear_keys() just prior to
resuming the kernel execution which will schedule a callback to clear
any keys which were depressed prior to the entering the kernel
debugger.
CC: Dmitry Torokhov <dmitry.torokhov@gmail.com>
CC: Greg Kroah-Hartman <gregkh@suse.de>
CC: linux-input@vger.kernel.org
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
---
drivers/char/keyboard.c | 37 +++++++++++++++++++++++++++++++++++++
drivers/serial/kgdboc.c | 13 +++++++++++++
include/linux/kbd_kern.h | 1 +
3 files changed, 51 insertions(+), 0 deletions(-)
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index a7ca752..0c6c641 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -363,6 +363,43 @@ static void to_utf8(struct vc_data *vc, uint c)
}
}
+#ifdef CONFIG_KDB_KEYBOARD
+static int kbd_clear_keys_helper(struct input_handle *handle, void *data)
+{
+ unsigned int *keycode = data;
+ input_inject_event(handle, EV_KEY, *keycode, 0);
+ return 0;
+}
+
+static void kbd_clear_keys_callback(struct work_struct *dummy)
+{
+ 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_clear_keys_helper);
+ }
+ }
+}
+
+static DECLARE_WORK(kbd_clear_keys_work, kbd_clear_keys_callback);
+
+/* Called to clear any key presses after resuming the kernel. */
+void kbd_dbg_clear_keys(void)
+{
+ schedule_work(&kbd_clear_keys_work);
+}
+EXPORT_SYMBOL_GPL(kbd_dbg_clear_keys);
+#endif /* CONFIG_KDB_KEYBOARD */
+
/*
* Called after returning from RAW mode or when changing consoles - recompute
* shift_down[] and shift_state from key_down[] maybe called when keymap is
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
index 39f9a1a..62b6edc 100644
--- a/drivers/serial/kgdboc.c
+++ b/drivers/serial/kgdboc.c
@@ -18,6 +18,7 @@
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/vt_kern.h>
+#include <linux/kbd_kern.h>
#define MAX_CONFIG_LEN 40
@@ -37,12 +38,16 @@ static struct tty_driver *kgdb_tty_driver;
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
@@ -65,9 +70,16 @@ static void kgdboc_unregister_kbd(void)
}
}
}
+
+static inline void kgdboc_clear_kbd(void)
+{
+ if (kgdboc_use_kbd)
+ kbd_dbg_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)
@@ -231,6 +243,7 @@ static void kgdboc_post_exp_handler(void)
dbg_restore_graphics = 0;
con_debug_leave();
}
+ kgdboc_clear_kbd();
}
static struct kgdb_io kgdboc_io_ops = {
diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h
index 506ad20..ae87c0a 100644
--- 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 */
--
1.6.3.3
------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1, ECMAScript5, and DOM L2 & L3.
Spend less time writing and rewriting code and more time creating great
experiences on the web. Be a part of the beta today.
http://p.sf.net/sfu/beautyoftheweb
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] keyboard, kdb: inject SYN events in kbd_clear_keys_helper
2010-10-07 20:35 [PATCH 0/3] input / sysrq fixes for use with kdb Jason Wessel
2010-10-07 20:35 ` [PATCH 1/3] keyboard, kgdboc: Allow key release on kernel resume Jason Wessel
@ 2010-10-07 20:35 ` Jason Wessel
2010-10-07 20:35 ` [PATCH 3/3] sysrq, keyboard: properly deal with alt-sysrq in sysrq input filter Jason Wessel
2010-10-10 21:19 ` [PATCH 0/3] input / sysrq fixes for use with kdb Dmitry Torokhov
3 siblings, 0 replies; 6+ messages in thread
From: Jason Wessel @ 2010-10-07 20:35 UTC (permalink / raw)
To: dmitry.torokhov
Cc: Maxim Levitsky, kgdb-bugreport, Jason Wessel, linux-kernel,
linux-input
From: Maxim Levitsky <maximlevitsky@gmail.com>
The kbd_clear_keys_helper injects the keyup events alright, but it
doesn't inject SYN events, and therefore X evdev driver doesn't pick
these injected events untill next SYN event.
Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
---
drivers/char/keyboard.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 0c6c641..7df6af5 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -368,6 +368,7 @@ static int kbd_clear_keys_helper(struct input_handle *handle, void *data)
{
unsigned int *keycode = data;
input_inject_event(handle, EV_KEY, *keycode, 0);
+ input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
return 0;
}
--
1.6.3.3
------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1, ECMAScript5, and DOM L2 & L3.
Spend less time writing and rewriting code and more time creating great
experiences on the web. Be a part of the beta today.
http://p.sf.net/sfu/beautyoftheweb
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] sysrq, keyboard: properly deal with alt-sysrq in sysrq input filter
2010-10-07 20:35 [PATCH 0/3] input / sysrq fixes for use with kdb Jason Wessel
2010-10-07 20:35 ` [PATCH 1/3] keyboard, kgdboc: Allow key release on kernel resume Jason Wessel
2010-10-07 20:35 ` [PATCH 2/3] keyboard, kdb: inject SYN events in kbd_clear_keys_helper Jason Wessel
@ 2010-10-07 20:35 ` Jason Wessel
2010-10-10 21:19 ` [PATCH 0/3] input / sysrq fixes for use with kdb Dmitry Torokhov
3 siblings, 0 replies; 6+ messages in thread
From: Jason Wessel @ 2010-10-07 20:35 UTC (permalink / raw)
To: dmitry.torokhov
Cc: kgdb-bugreport, Jason Wessel, Greg Kroah-Hartman, linux-kernel,
linux-input
This patch addresses 2 problems:
1) You should still be able to use alt-PrintScreen to capture a grab
of a single window when the sysrq filter is active.
2) The sysrq filter should reset the low level key mask so that future
key presses will not show up as a repeated key. The problem was
that when you executed alt-sysrq g and then resumed the kernel, you
would have to press 'g' twice to get it working again.
CC: Dmitry Torokhov <dmitry.torokhov@gmail.com>
CC: Greg Kroah-Hartman <gregkh@suse.de>
CC: linux-input@vger.kernel.org
Reported-by: Maxim Levitsky <maximlevitsky@gmail.com>
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
---
drivers/char/sysrq.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index ef31bb8..b1fad74 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -566,6 +566,57 @@ static const unsigned char sysrq_xlate[KEY_MAX + 1] =
static bool sysrq_down;
static int sysrq_alt_use;
static int sysrq_alt;
+static bool sysrq_kbd_triggered;
+
+/*
+ * This function was a copy of input_pass_event but modified to allow
+ * by-passing a specific filter, to allow for injected events without
+ * filter recursion.
+ */
+static void input_pass_event_ignore(struct input_dev *dev,
+ unsigned int type, unsigned int code, int value,
+ struct input_handle *ignore_handle)
+{
+ struct input_handler *handler;
+ struct input_handle *handle;
+
+ rcu_read_lock();
+
+ handle = rcu_dereference(dev->grab);
+ if (handle)
+ handle->handler->event(handle, type, code, value);
+ else {
+ bool filtered = false;
+
+ list_for_each_entry_rcu(handle, &dev->h_list, d_node) {
+ if (!handle->open || handle == ignore_handle)
+ continue;
+ handler = handle->handler;
+ if (!handler->filter) {
+ if (filtered)
+ break;
+
+ handler->event(handle, type, code, value);
+
+ } else if (handler->filter(handle, type, code, value))
+ filtered = true;
+ }
+ }
+
+ rcu_read_unlock();
+}
+
+/*
+ * Pass along alt-print_screen, if there was no sysrq processing by
+ * sending a key press down and then passing the key up event.
+ */
+static void simulate_alt_sysrq(struct input_handle *handle)
+{
+ input_pass_event_ignore(handle->dev, EV_KEY, KEY_SYSRQ, 1, handle);
+ input_pass_event_ignore(handle->dev, EV_SYN, SYN_REPORT, 0, handle);
+ input_pass_event_ignore(handle->dev, EV_KEY, KEY_SYSRQ, 0, handle);
+ input_pass_event_ignore(handle->dev, EV_SYN, SYN_REPORT, 0, handle);
+}
static bool sysrq_filter(struct input_handle *handle, unsigned int type,
unsigned int code, int value)
@@ -580,9 +631,11 @@ static bool sysrq_filter(struct input_handle *handle, unsigned int type,
if (value)
sysrq_alt = code;
else {
- if (sysrq_down && code == sysrq_alt_use)
+ if (sysrq_down && code == sysrq_alt_use) {
sysrq_down = false;
-
+ if (!sysrq_kbd_triggered)
+ simulate_alt_sysrq(handle);
+ }
sysrq_alt = 0;
}
break;
@@ -590,13 +643,18 @@ static bool sysrq_filter(struct input_handle *handle, unsigned int type,
case KEY_SYSRQ:
if (value == 1 && sysrq_alt) {
sysrq_down = true;
+ sysrq_kbd_triggered = false;
sysrq_alt_use = sysrq_alt;
}
break;
default:
- if (sysrq_down && value && value != 2)
+ if (sysrq_down && value && value != 2 && !sysrq_kbd_triggered) {
+ sysrq_kbd_triggered = true;
__handle_sysrq(sysrq_xlate[code], true);
+ /* Clear handled keys from being flagged as a repeated stroke */
+ __clear_bit(code, handle->dev->key);
+ }
break;
}
--
1.6.3.3
------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1, ECMAScript5, and DOM L2 & L3.
Spend less time writing and rewriting code and more time creating great
experiences on the web. Be a part of the beta today.
http://p.sf.net/sfu/beautyoftheweb
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/3] input / sysrq fixes for use with kdb
2010-10-07 20:35 [PATCH 0/3] input / sysrq fixes for use with kdb Jason Wessel
` (2 preceding siblings ...)
2010-10-07 20:35 ` [PATCH 3/3] sysrq, keyboard: properly deal with alt-sysrq in sysrq input filter Jason Wessel
@ 2010-10-10 21:19 ` Dmitry Torokhov
2010-10-27 12:53 ` Jason Wessel
3 siblings, 1 reply; 6+ messages in thread
From: Dmitry Torokhov @ 2010-10-10 21:19 UTC (permalink / raw)
To: Jason Wessel; +Cc: kgdb-bugreport, linux-input, linux-kernel
On Thu, Oct 07, 2010 at 03:35:45PM -0500, Jason Wessel wrote:
> The goal of this patch set is to help eliminate the problems of
> resuming from the kernel debugger and having "stuck keys".
>
> I am completely open to moving the code chunks around if it makes more
> sense to put the function in the input.c.
>
> I had posted the first patch in the series before and never received
> an ack or acceptance into the linux-input merge queue.
>
Jason,
I am aware of the problem however I am not quite happy with the proposed
solution yet. Let me mull it over for a bit and I will get back to you.
Thanks.
--
Dmitry
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 0/3] input / sysrq fixes for use with kdb
2010-10-10 21:19 ` [PATCH 0/3] input / sysrq fixes for use with kdb Dmitry Torokhov
@ 2010-10-27 12:53 ` Jason Wessel
0 siblings, 0 replies; 6+ messages in thread
From: Jason Wessel @ 2010-10-27 12:53 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: kgdb-bugreport, linux-kernel, linux-input
On 10/10/2010 04:19 PM, Dmitry Torokhov wrote:
> On Thu, Oct 07, 2010 at 03:35:45PM -0500, Jason Wessel wrote:
>
>> The goal of this patch set is to help eliminate the problems of
>> resuming from the kernel debugger and having "stuck keys".
>>
>> I am completely open to moving the code chunks around if it makes more
>> sense to put the function in the input.c.
>>
>> I had posted the first patch in the series before and never received
>> an ack or acceptance into the linux-input merge queue.
>>
>>
>
> Jason,
>
> I am aware of the problem however I am not quite happy with the proposed
> solution yet. Let me mull it over for a bit and I will get back to you.
>
Ping :-)
The merge window for 2.6.37 is almost over, and I would really like to
fix this or make it better than it is today, given that remainder of the
atomic KMS API is now merged in 2.6.37.
Thanks,
Jason.
------------------------------------------------------------------------------
Nokia and AT&T present the 2010 Calling All Innovators-North America contest
Create new apps & games for the Nokia N8 for consumers in U.S. and Canada
$10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing
Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store
http://p.sf.net/sfu/nokia-dev2dev
^ permalink raw reply [flat|nested] 6+ messages in thread