These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / s390 / char / sclp_vt220.c
index ae67386..68d6ee7 100644 (file)
@@ -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;
        }