diff -r 8af8ddf91078 linux-2.6-xen-sparse/drivers/xen/console/console.c --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Wed Aug 31 14:53:43 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Wed Aug 31 18:19:48 2005 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +67,11 @@ static enum { XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL } xc_mode = XC_DEFAULT; static int xc_num = -1; +#ifdef CONFIG_MAGIC_SYSRQ +static unsigned long sysrq_requested; +extern int sysrq_enabled; +#endif + static int __init xencons_setup(char *str) { char *q; @@ -296,7 +302,7 @@ static char x_char; /* Non-privileged receive callback. */ -static void xencons_rx(char *buf, unsigned len) +static void xencons_rx(char *buf, unsigned len, struct pt_regs *regs) { int i; unsigned long flags; @@ -304,8 +310,27 @@ spin_lock_irqsave(&xencons_lock, flags); if ( xencons_tty != NULL ) { - for ( i = 0; i < len; i++ ) + for ( i = 0; i < len; i++ ) { +#ifdef CONFIG_MAGIC_SYSRQ + if (sysrq_enabled) { + if (buf[i] == '\x0f') { /* ^O */ + sysrq_requested = jiffies; + continue; /* don't print the sysrq key */ + } else if (sysrq_requested) { + unsigned long sysrq_timeout = sysrq_requested + HZ*2; + sysrq_requested = 0; + /* if it's been less than a timeout, do the sysrq */ + if (time_before(jiffies, sysrq_timeout)) { + spin_unlock_irqrestore(&xencons_lock, flags); + handle_sysrq(buf[i], regs, xencons_tty); + spin_lock_irqsave(&xencons_lock, flags); + continue; + } + } + } +#endif tty_insert_flip_char(xencons_tty, buf[i], 0); + } tty_flip_buffer_push(xencons_tty); } spin_unlock_irqrestore(&xencons_lock, flags); diff -r 8af8ddf91078 linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Wed Aug 31 14:53:43 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Wed Aug 31 18:19:48 2005 @@ -82,7 +82,7 @@ while (ring->cons < ring->prod) { if (xencons_receiver != NULL) { xencons_receiver(ring->buf + XENCONS_IDX(ring->cons), - 1); + 1, regs); } ring->cons++; } diff -r 8af8ddf91078 linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h Wed Aug 31 14:53:43 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h Wed Aug 31 18:19:48 2005 @@ -7,7 +7,8 @@ int xencons_ring_init(void); int xencons_ring_send(const char *data, unsigned len); -typedef void (xencons_receiver_func)(char *buf, unsigned len); +typedef void (xencons_receiver_func)(char *buf, unsigned len, + struct pt_regs *regs); void xencons_ring_register_receiver(xencons_receiver_func *f); #endif /* _XENCONS_RING_H */