aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>2004-11-12 14:52:50 +0000
committercl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>2004-11-12 14:52:50 +0000
commitcf942f9391b763f0344f5c78cbb5fb0a42be5f7c (patch)
tree29a03e2c6d49358f7ca5bdae40281bf2fc8340b3
parent543642d9857ce565925402dfaa3557be8ea86813 (diff)
downloadxen-cf942f9391b763f0344f5c78cbb5fb0a42be5f7c.tar.gz
xen-cf942f9391b763f0344f5c78cbb5fb0a42be5f7c.tar.bz2
xen-cf942f9391b763f0344f5c78cbb5fb0a42be5f7c.zip
bitkeeper revision 1.1159.172.1 (4194ce42z4ANVXzSMk0doSVOCKrA1g)
Add no-defer keyhandlers which get called from interrupt context and get access to the registers saved on interrupt entry.
-rw-r--r--xen/common/keyhandler.c25
-rw-r--r--xen/drivers/char/console.c2
-rw-r--r--xen/include/xen/keyhandler.h7
3 files changed, 26 insertions, 8 deletions
diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c
index d52aabd771..045f861880 100644
--- a/xen/common/keyhandler.c
+++ b/xen/common/keyhandler.c
@@ -11,10 +11,13 @@
#define STR_MAX 64
static struct {
- key_handler *handler;
+ key_handler *handler;
+ int flags;
char desc[STR_MAX];
} key_table[KEY_MAX];
+#define KEYHANDLER_NO_DEFER 0x1
+
static unsigned char keypress_key;
void keypress_softirq(void)
@@ -25,19 +28,33 @@ void keypress_softirq(void)
(*h)(key);
}
-void handle_keypress(unsigned char key)
+void handle_keypress(unsigned char key, struct xen_regs *regs)
{
+ key_handler *h;
+
keypress_key = key;
- raise_softirq(KEYPRESS_SOFTIRQ);
+ if ( (key_table[key].flags & KEYHANDLER_NO_DEFER) &&
+ ((h = key_table[key].handler) != NULL) )
+ ((void (*)(unsigned char, struct xen_regs *))*h)(key, regs);
+ else
+ raise_softirq(KEYPRESS_SOFTIRQ);
}
void add_key_handler(unsigned char key, key_handler *handler, char *desc)
{
- key_table[key].handler = handler;
+ key_table[key].handler = handler;
+ key_table[key].flags = 0;
strncpy(key_table[key].desc, desc, STR_MAX);
key_table[key].desc[STR_MAX-1] = '\0';
}
+void add_key_handler_no_defer(unsigned char key, key_handler *handler,
+ char *desc)
+{
+ add_key_handler(key, handler, desc);
+ key_table[key].flags |= KEYHANDLER_NO_DEFER;
+}
+
static void show_handlers(unsigned char key)
{
int i;
diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
index 51e97fc82f..7a706b2e2c 100644
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -247,7 +247,7 @@ static void __serial_rx(unsigned char c, struct xen_regs *regs)
{
if ( xen_rx )
{
- handle_keypress(c);
+ handle_keypress(c, regs);
}
else if ( (serial_rx_prod-serial_rx_cons) != SERIAL_RX_SIZE )
{
diff --git a/xen/include/xen/keyhandler.h b/xen/include/xen/keyhandler.h
index d12621ef33..09e2f234ad 100644
--- a/xen/include/xen/keyhandler.h
+++ b/xen/include/xen/keyhandler.h
@@ -4,12 +4,13 @@
** debug flag, dump registers, reboot, etc) to be hooked in in a slightly
** nicer fashion than just editing the serial/keyboard drivers.
*/
-#include <xen/sched.h>
+struct xen_regs;
typedef void key_handler(unsigned char key);
extern void add_key_handler(unsigned char key,
key_handler *handler, char *desc);
+extern void add_key_handler_no_defer(unsigned char key,
+ key_handler *handler, char *desc);
-extern void handle_keypress(unsigned char key);
-
+extern void handle_keypress(unsigned char key, struct xen_regs *regs);