Commit 1d3f9094 authored by Hendrik Brueckner's avatar Hendrik Brueckner Committed by Martin Schwidefsky

s390/sclp_vt220: support magic sysrequests

Implement magic sysrequest handling for the VT220 terminal (also known as
the Integrated ASCII console on the HMC/SE).
To invoke a "magic sysrequest" function, press "Ctrl+o" followed by a
second character that designates the debugging function.

The handling of the sysrq is scheduled away from the SCLP IRQ context;
because large amounts of sysrq output might fill up the console buffers.
The console might deadlock because it cannot empty the buffers while still
in the receiving IRQ context.  This behavior is the same as for the SCLP
console.
Reported-by: default avatarHorst Weber <hweber@de.ibm.com>
Signed-off-by: default avatarHendrik Brueckner <brueckner@linux.vnet.ibm.com>
Reviewed-by: default avatarPeter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent ab7373bf
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sysrq.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/tty_driver.h> #include <linux/tty_driver.h>
#include <linux/tty_flip.h> #include <linux/tty_flip.h>
...@@ -27,6 +28,7 @@ ...@@ -27,6 +28,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "sclp.h" #include "sclp.h"
#include "ctrlchar.h"
#define SCLP_VT220_MAJOR TTY_MAJOR #define SCLP_VT220_MAJOR TTY_MAJOR
#define SCLP_VT220_MINOR 65 #define SCLP_VT220_MINOR 65
...@@ -477,6 +479,53 @@ sclp_vt220_write(struct tty_struct *tty, const unsigned char *buf, int count) ...@@ -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_STARTED 0x80
#define SCLP_VT220_SESSION_DATA 0x00 #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. * Called by the SCLP to report incoming event buffers.
*/ */
...@@ -492,12 +541,13 @@ sclp_vt220_receiver_fn(struct evbuf_header *evbuf) ...@@ -492,12 +541,13 @@ sclp_vt220_receiver_fn(struct evbuf_header *evbuf)
switch (*buffer) { switch (*buffer) {
case SCLP_VT220_SESSION_ENDED: case SCLP_VT220_SESSION_ENDED:
case SCLP_VT220_SESSION_STARTED: case SCLP_VT220_SESSION_STARTED:
sclp_vt220_reset_session();
break; break;
case SCLP_VT220_SESSION_DATA: case SCLP_VT220_SESSION_DATA:
/* Send input to line discipline */ /* Send input to line discipline */
buffer++; buffer++;
count--; count--;
tty_insert_flip_string(&sclp_vt220_port, buffer, count); sclp_vt220_handle_input(buffer, count);
tty_flip_buffer_push(&sclp_vt220_port); tty_flip_buffer_push(&sclp_vt220_port);
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment