diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-08-13 12:01:30 +0200 |
---|---|---|
committer | Zefan Li <lizefan@huawei.com> | 2015-04-14 17:34:03 +0800 |
commit | 9493ef4e311954d800e494196dccc423e5f1cfa5 (patch) | |
tree | 9cd0d49871dc835e303361d746934d88ce589237 | |
parent | 56a59c3ea2fc70fc8288ca4407277bf53044cd82 (diff) |
s390/3215: fix tty output containing tabs
commit e512d56c799517f33b301d81e9a5e0ebf30c2d1e upstream.
git commit 37f81fa1f63ad38e16125526bb2769ae0ea8d332
"n_tty: do O_ONLCR translation as a single write"
surfaced a bug in the 3215 device driver. In combination this
broke tab expansion for tty ouput.
The cause is an asymmetry in the behaviour of tty3215_ops->write
vs tty3215_ops->put_char. The put_char function scans for '\t'
but the write function does not.
As the driver has logic for the '\t' expansion remove XTABS
from c_oflag of the initial termios as well.
Reported-by: Stephen Powell <zlinuxman@wowway.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Zefan Li <lizefan@huawei.com>
-rw-r--r-- | drivers/s390/char/con3215.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 4f9f1dcc1551..fa47d8de304a 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -997,12 +997,26 @@ static int tty3215_write(struct tty_struct * tty, const unsigned char *buf, int count) { struct raw3215_info *raw; + int i, written; if (!tty) return 0; raw = (struct raw3215_info *) tty->driver_data; - raw3215_write(raw, buf, count); - return count; + written = count; + while (count > 0) { + for (i = 0; i < count; i++) + if (buf[i] == '\t' || buf[i] == '\n') + break; + raw3215_write(raw, buf, i); + count -= i; + buf += i; + if (count > 0) { + raw3215_putchar(raw, *buf); + count--; + buf++; + } + } + return written; } /* @@ -1149,7 +1163,7 @@ static int __init tty3215_init(void) driver->subtype = SYSTEM_TYPE_TTY; driver->init_termios = tty_std_termios; driver->init_termios.c_iflag = IGNBRK | IGNPAR; - driver->init_termios.c_oflag = ONLCR | XTABS; + driver->init_termios.c_oflag = ONLCR; driver->init_termios.c_lflag = ISIG; driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(driver, &tty3215_ops); |