fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / s390 / char / sclp_tty.c
index a1ad375..2d173e5 100644 (file)
@@ -8,11 +8,11 @@
  *              Martin Schwidefsky <schwidefsky@de.ibm.com>
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kmod.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/slab.h>
@@ -60,8 +60,6 @@ static unsigned short int sclp_tty_chars_count;
 
 struct tty_driver *sclp_tty_driver;
 
-extern struct termios  tty_std_termios;
-
 static struct sclp_ioctls sclp_ioctls;
 static struct sclp_ioctls sclp_ioctls_init =
 {
@@ -255,32 +253,26 @@ static void
 sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc)
 {
        unsigned long flags;
-       struct sclp_buffer *next;
        void *page;
 
-       /* Ignore return code - because tty-writes aren't critical,
-          we do without a sophisticated error recovery mechanism.  */
-       page = sclp_unmake_buffer(buffer);
-       spin_lock_irqsave(&sclp_tty_lock, flags);
-       /* Remove buffer from outqueue */
-       list_del(&buffer->list);
-       sclp_tty_buffer_count--;
-       list_add_tail((struct list_head *) page, &sclp_tty_pages);
-       /* Check if there is a pending buffer on the out queue. */
-       next = NULL;
-       if (!list_empty(&sclp_tty_outqueue))
-               next = list_entry(sclp_tty_outqueue.next,
-                                 struct sclp_buffer, list);
-       spin_unlock_irqrestore(&sclp_tty_lock, flags);
-       if (next != NULL)
-               sclp_emit_buffer(next, sclp_ttybuf_callback);
+       do {
+               page = sclp_unmake_buffer(buffer);
+               spin_lock_irqsave(&sclp_tty_lock, flags);
+               /* Remove buffer from outqueue */
+               list_del(&buffer->list);
+               sclp_tty_buffer_count--;
+               list_add_tail((struct list_head *) page, &sclp_tty_pages);
+               /* Check if there is a pending buffer on the out queue. */
+               buffer = NULL;
+               if (!list_empty(&sclp_tty_outqueue))
+                       buffer = list_entry(sclp_tty_outqueue.next,
+                                           struct sclp_buffer, list);
+               spin_unlock_irqrestore(&sclp_tty_lock, flags);
+       } while (buffer && sclp_emit_buffer(buffer, sclp_ttybuf_callback));
        wake_up(&sclp_tty_waitq);
        /* check if the tty needs a wake up call */
        if (sclp_tty != NULL) {
-               if ((sclp_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                   sclp_tty->ldisc.write_wakeup)
-                       (sclp_tty->ldisc.write_wakeup)(sclp_tty);
-               wake_up_interruptible(&sclp_tty->write_wait);
+               tty_wakeup(sclp_tty);
        }
 }
 
@@ -289,14 +281,17 @@ __sclp_ttybuf_emit(struct sclp_buffer *buffer)
 {
        unsigned long flags;
        int count;
+       int rc;
 
        spin_lock_irqsave(&sclp_tty_lock, flags);
        list_add_tail(&buffer->list, &sclp_tty_outqueue);
        count = sclp_tty_buffer_count++;
        spin_unlock_irqrestore(&sclp_tty_lock, flags);
-
-       if (count == 0)
-               sclp_emit_buffer(buffer, sclp_ttybuf_callback);
+       if (count)
+               return;
+       rc = sclp_emit_buffer(buffer, sclp_ttybuf_callback);
+       if (rc)
+               sclp_ttybuf_callback(buffer, rc);
 }
 
 /*
@@ -398,36 +393,14 @@ sclp_tty_write_string(const unsigned char *str, int count)
  * routine will return the number of characters actually accepted for writing.
  */
 static int
-sclp_tty_write(struct tty_struct *tty, int from_user,
-              const unsigned char *buf, int count)
+sclp_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
-       int length, ret;
-
        if (sclp_tty_chars_count > 0) {
                sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count);
                sclp_tty_chars_count = 0;
        }
-       if (!from_user) {
-               sclp_tty_write_string(buf, count);
-               return count;
-       }
-       ret = 0;
-       while (count > 0) {
-               length = count < SCLP_TTY_BUF_SIZE ?
-                       count : SCLP_TTY_BUF_SIZE;
-               length -= copy_from_user(sclp_tty_chars,
-                               (const unsigned char __user *)buf, length);
-               if (length == 0) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               sclp_tty_write_string(sclp_tty_chars, length);
-               buf += length;
-               count -= length;
-               ret += length;
-       }
-       return ret;
+       sclp_tty_write_string(buf, count);
+       return count;
 }
 
 /*
@@ -521,25 +494,19 @@ sclp_tty_input(unsigned char* buf, unsigned int count)
        case CTRLCHAR_SYSRQ:
                break;
        case CTRLCHAR_CTRL:
-               sclp_tty->flip.count++;
-               *sclp_tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-               *sclp_tty->flip.char_buf_ptr++ = cchar;
+               tty_insert_flip_char(sclp_tty, cchar, TTY_NORMAL);
                tty_flip_buffer_push(sclp_tty);
                break;
        case CTRLCHAR_NONE:
                /* send (normal) input to line discipline */
-               memcpy(sclp_tty->flip.char_buf_ptr, buf, count);
                if (count < 2 ||
-                   (strncmp ((const char *) buf + count - 2, "^n", 2) &&
-                    strncmp ((const char *) buf + count - 2, "\0252n", 2))) {
-                       sclp_tty->flip.char_buf_ptr[count] = '\n';
-                       count++;
+                   (strncmp((const char *) buf + count - 2, "^n", 2) &&
+                    strncmp((const char *) buf + count - 2, "\252n", 2))) {
+                       /* add the auto \n */
+                       tty_insert_flip_string(sclp_tty, buf, count);
+                       tty_insert_flip_char(sclp_tty, '\n', TTY_NORMAL);
                } else
-                       count -= 2;
-               memset(sclp_tty->flip.flag_buf_ptr, TTY_NORMAL, count);
-               sclp_tty->flip.char_buf_ptr += count;
-               sclp_tty->flip.flag_buf_ptr += count;
-               sclp_tty->flip.count += count;
+                       tty_insert_flip_string(sclp_tty, buf, count - 2);
                tty_flip_buffer_push(sclp_tty);
                break;
        }
@@ -626,7 +593,7 @@ sclp_get_input(unsigned char *start, unsigned char *end)
 
        /* if set in ioctl write operators input to console  */
        if (sclp_ioctls.echo)
-               sclp_tty_write(sclp_tty, 0, start, count);
+               sclp_tty_write(sclp_tty, start, count);
 
        /* transfer input to high level driver */
        sclp_tty_input(start, count);
@@ -742,7 +709,7 @@ static struct sclp_register sclp_input_event =
        .receiver_fn = sclp_tty_receiver
 };
 
-static struct tty_operations sclp_ops = {
+static const struct tty_operations sclp_ops = {
        .open = sclp_tty_open,
        .close = sclp_tty_close,
        .write = sclp_tty_write,