diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/char/sclp_vt220.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index ae67386c03d3..68d6ee7ae504 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -12,6 +12,7 @@ #include <linux/wait.h> #include <linux/timer.h> #include <linux/kernel.h> +#include <linux/sysrq.h> #include <linux/tty.h> #include <linux/tty_driver.h> #include <linux/tty_flip.h> @@ -27,6 +28,7 @@ #include <asm/uaccess.h> #include "sclp.h" +#include "ctrlchar.h" #define SCLP_VT220_MAJOR TTY_MAJOR #define SCLP_VT220_MINOR 65 @@ -477,6 +479,53 @@ sclp_vt220_write(struct tty_struct *tty, const unsigned char *buf, int count) #define SCLP_VT220_SESSION_STARTED 0x80 #define SCLP_VT220_SESSION_DATA 0x00 +#ifdef CONFIG_MAGIC_SYSRQ + +static int sysrq_pressed; +static struct sysrq_work sysrq; + +static void sclp_vt220_reset_session(void) +{ + sysrq_pressed = 0; +} + +static void sclp_vt220_handle_input(const char *buffer, unsigned int count) +{ + int i; + + for (i = 0; i < count; i++) { + /* Handle magic sys request */ + if (buffer[i] == ('O' ^ 0100)) { /* CTRL-O */ + /* + * If pressed again, reset sysrq_pressed + * and flip CTRL-O character + */ + sysrq_pressed = !sysrq_pressed; + if (sysrq_pressed) + continue; + } else if (sysrq_pressed) { + sysrq.key = buffer[i]; + schedule_sysrq_work(&sysrq); + sysrq_pressed = 0; + continue; + } + tty_insert_flip_char(&sclp_vt220_port, buffer[i], 0); + } +} + +#else + +static void sclp_vt220_reset_session(void) +{ +} + +static void sclp_vt220_handle_input(const char *buffer, unsigned int count) +{ + tty_insert_flip_string(&sclp_vt220_port, buffer, count); +} + +#endif + /* * Called by the SCLP to report incoming event buffers. */ @@ -492,12 +541,13 @@ sclp_vt220_receiver_fn(struct evbuf_header *evbuf) switch (*buffer) { case SCLP_VT220_SESSION_ENDED: case SCLP_VT220_SESSION_STARTED: + sclp_vt220_reset_session(); break; case SCLP_VT220_SESSION_DATA: /* Send input to line discipline */ buffer++; count--; - tty_insert_flip_string(&sclp_vt220_port, buffer, count); + sclp_vt220_handle_input(buffer, count); tty_flip_buffer_push(&sclp_vt220_port); break; } |