2.5.40 s390 (27/27): control characters.

2.5.40 s390 (27/27): control characters.

Post by Martin Schwidefsk » Sat, 05 Oct 2002 17:10:03



Replace IMMEDIATE_BH bottom half by tasklets in helper functions for
console control characters. Fix a race condition and make it look nicer.

diff -urN linux-2.5.40/drivers/s390/char/con3215.c linux-2.5.40-s390/drivers/s390/char/con3215.c
--- linux-2.5.40/drivers/s390/char/con3215.c    Fri Oct  4 16:16:50 2002
+++ linux-2.5.40-s390/drivers/s390/char/con3215.c       Fri Oct  4 16:17:01 2002
@@ -455,7 +455,7 @@
                 if ((raw = req->info) == NULL)
                         return;              /* That shouldn't happen ... */
                if (req->type == RAW3215_READ && raw->tty != NULL) {
-                       char *cchar;
+                       unsigned int cchar;

                        tty = raw->tty;
                         count = 160 - req->residual;
@@ -467,14 +467,19 @@
                        if (count >= TTY_FLIPBUF_SIZE - tty->flip.count)
                                count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
                        EBCASC(raw->inbuf, count);
-                       if ((cchar = ctrlchar_handle(raw->inbuf, count, tty))) {
-                               if (cchar == (char *)-1)
-                                       goto in_out;
+                       cchar = ctrlchar_handle(raw->inbuf, count, tty);
+                       switch (cchar & CTRLCHAR_MASK) {
+                       case CTRLCHAR_SYSRQ:
+                               break;
+
+                       case CTRLCHAR_CTRL:
                                tty->flip.count++;
                                *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-                               *tty->flip.char_buf_ptr++ = *cchar;
+                               *tty->flip.char_buf_ptr++ = cchar;
                                tty_flip_buffer_push(raw->tty);
-                       } else {
+                               break;
+
+                       case CTRLCHAR_NONE:
                                memcpy(tty->flip.char_buf_ptr,
                                       raw->inbuf, count);
                                if (count < 2 ||
@@ -491,12 +496,13 @@
                                tty->flip.flag_buf_ptr += count;
                                tty->flip.count += count;
                                tty_flip_buffer_push(raw->tty);
+                               break;
                        }
                } else if (req->type == RAW3215_WRITE) {
                        raw->count -= req->len;
                         raw->written -= req->len;
                }
-in_out:
+
                raw->flags &= ~RAW3215_WORKING;
                raw3215_free_req(req);
                /* check for empty wait */
@@ -1095,8 +1101,6 @@
                raw3215_freelist = req;
        }

-       ctrlchar_init();
-
 #ifdef CONFIG_TN3215_CONSOLE
         raw3215[0] = raw = (raw3215_info *)
                 alloc_bootmem_low(sizeof(raw3215_info));
diff -urN linux-2.5.40/drivers/s390/char/ctrlchar.c linux-2.5.40-s390/drivers/s390/char/ctrlchar.c
--- linux-2.5.40/drivers/s390/char/ctrlchar.c   Fri Oct  4 16:14:52 2002
+++ linux-2.5.40-s390/drivers/s390/char/ctrlchar.c      Fri Oct  4 16:17:01 2002
@@ -8,39 +8,27 @@
  */

 #include <linux/config.h>
-#include <linux/types.h>
-#include <linux/tty.h>
-#include <linux/interrupt.h>
-
+#include <linux/stddef.h>
 #include <linux/sysrq.h>
+#include <linux/ctype.h>

-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/delay.h>
-#include <asm/cpcmd.h>
-#include <asm/irq.h>
+#include "ctrlchar.h"

 #ifdef CONFIG_MAGIC_SYSRQ
 static int ctrlchar_sysrq_key;
-static struct tq_struct ctrlchar_tq;

 static void
-ctrlchar_handle_sysrq(struct tty_struct *tty) {
+ctrlchar_handle_sysrq(void *tty)
+{
        handle_sysrq(ctrlchar_sysrq_key, NULL, tty);
 }
-#endif
-
-void ctrlchar_init(void) {
-#ifdef CONFIG_MAGIC_SYSRQ
-       static int init_done = 0;

-       if (init_done++)
-               return;
-       INIT_LIST_HEAD(&ctrlchar_tq.list);
-       ctrlchar_tq.sync = 0;
-       ctrlchar_tq.routine = (void (*)(void *)) ctrlchar_handle_sysrq;
+static struct tq_struct ctrlchar_tq = {
+       .list = LIST_HEAD_INIT(ctrlchar_tq.list),
+       .routine = ctrlchar_handle_sysrq,
+};
 #endif
-}
+

 /**
  * Check for special chars at start of input.
@@ -48,49 +36,42 @@
  * @param buf Console input buffer.
  * @param len Length of valid data in buffer.
  * @param tty The tty struct for this console.
- * @return NULL, if nothing matched, (char *)-1, if buffer contents
- *         should be ignored, otherwise pointer to char to be inserted.
+ * @return CTRLCHAR_NONE, if nothing matched,
+ *         CTRLCHAR_SYSRQ, if sysrq was encountered
+ *         otherwise char to be inserted logically or'ed
+ *         with CTRLCHAR_CTRL
  */
-char *ctrlchar_handle(const char *buf, int len, struct tty_struct *tty) {
-
-       static char ret;
-
+unsigned int
+ctrlchar_handle(const char *buf, int len, struct tty_struct *tty)
+{
        if ((len < 2) || (len > 3))
-               return NULL;
+               return CTRLCHAR_NONE;
+
        /* hat is 0xb1 in codepage 037 (US etc.) and thus */
        /* converted to 0x5e in ascii ('^') */
        if ((buf[0] != '^') && (buf[0] != '\252'))
-               return NULL;
-       switch (buf[1]) {
+               return CTRLCHAR_NONE;
+
 #ifdef CONFIG_MAGIC_SYSRQ
-               case '-':
-                       if (len == 3) {
-                               ctrlchar_sysrq_key = buf[2];
-                               ctrlchar_tq.data = tty;
-                               queue_task(&ctrlchar_tq, &tq_immediate);
-                               mark_bh(IMMEDIATE_BH);
-                               return (char *)-1;
-                       }
-                       break;
+       /* racy */
+       if (len == 3 && buf[1] == '-') {
+               ctrlchar_sysrq_key = buf[2];
+               ctrlchar_tq.data = tty;
+               schedule_task(&ctrlchar_tq);
+               return CTRLCHAR_SYSRQ;
+       }
 #endif
-               case 'c':
-                       if (len == 2) {
-                               ret = INTR_CHAR(tty);
-                               return &ret;
-                       }
-                       break;
-               case 'd':
-                       if (len == 2) {
-                               ret = EOF_CHAR(tty);
-                               return &ret;
-                       }
-                       break;
-               case 'z':
-                       if (len == 2) {
-                               ret = SUSP_CHAR(tty);
-                               return &ret;
-                       }
-                       break;
+
+       if (len != 2)
+               return CTRLCHAR_NONE;
+
+       switch (tolower(buf[1])) {
+       case 'c':
+               return INTR_CHAR(tty) | CTRLCHAR_CTRL;
+       case 'd':
+               return EOF_CHAR(tty)  | CTRLCHAR_CTRL;
+       case 'z':
+               return SUSP_CHAR(tty) | CTRLCHAR_CTRL;
        }
-       return NULL;
+       return CTRLCHAR_NONE;
 }
diff -urN linux-2.5.40/drivers/s390/char/ctrlchar.h linux-2.5.40-s390/drivers/s390/char/ctrlchar.h
--- linux-2.5.40/drivers/s390/char/ctrlchar.h   Tue Oct  1 09:07:44 2002
+++ linux-2.5.40-s390/drivers/s390/char/ctrlchar.h      Fri Oct  4 16:17:01 2002
@@ -7,9 +7,14 @@
  *
  */

-#include <linux/config.h>
-#include <linux/types.h>
 #include <linux/tty.h>

-extern void ctrlchar_init(void);
-extern char *ctrlchar_handle(const char *buf, int len, struct tty_struct *tty);
+extern unsigned int
+ctrlchar_handle(const char *buf, int len, struct tty_struct *tty);
+
+
+#define CTRLCHAR_NONE  (1 << 8)
+#define CTRLCHAR_CTRL  (2 << 8)
+#define CTRLCHAR_SYSRQ (3 << 8)
+
+#define CTRLCHAR_MASK (~0xffu)
diff -urN linux-2.5.40/drivers/s390/char/hwc_tty.c linux-2.5.40-s390/drivers/s390/char/hwc_tty.c
--- linux-2.5.40/drivers/s390/char/hwc_tty.c    Tue Oct  1 09:06:30 2002
+++ linux-2.5.40-s390/drivers/s390/char/hwc_tty.c       Fri Oct  4 16:17:01 2002
@@ -188,15 +188,19 @@
        struct tty_struct *tty = hwc_tty_data.tty;

        if (tty != NULL) {
-               char *cchar;
-               if ((cchar = ctrlchar_handle (buf, count, tty))) {
-                       if (cchar == (char *) -1)
-                               return;
+               unsigned int cchar = ctrlchar_handle(buf, count, tty);
+
+               switch (cchar & CTRLCHAR_MASK) {
+               case CTRLCHAR_SYSRQ:
+                       return;
+
+               case CTRLCHAR_CTRL:
                        tty->flip.count++;
                        *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-                       *tty->flip.char_buf_ptr++ = *cchar;
-               } else {
+                       *tty->flip.char_buf_ptr++ = cchar;
+                       break;

+               case CTRLCHAR_NONE:
                        memcpy (tty->flip.char_buf_ptr, buf, count);
                        if (count < 2 || (
                                         strncmp (buf + count - 2, "^n", 2) ||
@@ -209,6 +213,7 @@
                        tty->flip.char_buf_ptr += count;
                        tty->flip.flag_buf_ptr += count;
                        tty->flip.count += count;
+                       break;
                }
                tty_flip_buffer_push (tty);
                hwc_tty_wake_up ();
@@ -221,8 +226,6 @@
        if (!CONSOLE_IS_HWC)
                return;

-       ctrlchar_init ();
-
        memset (&hwc_tty_driver, 0, sizeof (struct tty_driver));
        memset (&hwc_tty_data, 0, sizeof (hwc_tty_data_struct));
        hwc_tty_driver.magic = TTY_DRIVER_MAGIC;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/