diff options
author | cl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk> | 2004-11-12 14:52:50 +0000 |
---|---|---|
committer | cl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk> | 2004-11-12 14:52:50 +0000 |
commit | cf942f9391b763f0344f5c78cbb5fb0a42be5f7c (patch) | |
tree | 29a03e2c6d49358f7ca5bdae40281bf2fc8340b3 | |
parent | 543642d9857ce565925402dfaa3557be8ea86813 (diff) | |
download | xen-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.c | 25 | ||||
-rw-r--r-- | xen/drivers/char/console.c | 2 | ||||
-rw-r--r-- | xen/include/xen/keyhandler.h | 7 |
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); |