X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fs390%2Fchar%2Fsclp_tty.c;h=2d173e5c8a098514d5f23f136bbe775122bc920e;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=cd11cb171d15678c29c7587fd161f8d61780734c;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index cd11cb171..2d173e5c8 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -8,11 +8,11 @@ * Martin Schwidefsky */ -#include #include #include #include #include +#include #include #include #include @@ -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,25 +253,22 @@ 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) { @@ -286,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); } /* @@ -395,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; } /* @@ -518,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; } @@ -623,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); @@ -739,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,