Skip to content

Commit 4da81fa

Browse files
committed
Merge tag 'tty-5.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial fixes from Greg KH: "Here are three small tty/serial fixes for 5.11-rc5 to resolve reported problems: - two patches to fix up writing to ttys with splice - mvebu-uart driver fix for reported problem All of these have been in linux-next with no reported problems" * tag 'tty-5.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: tty: fix up hung_up_tty_write() conversion tty: implement write_iter serial: mvebu-uart: fix tx lost characters at power off
2 parents 8f3bfd2 + 1774985 commit 4da81fa

File tree

2 files changed

+37
-24
lines changed

2 files changed

+37
-24
lines changed

drivers/tty/serial/mvebu-uart.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,14 @@ static void wait_for_xmitr(struct uart_port *port)
648648
(val & STAT_TX_RDY(port)), 1, 10000);
649649
}
650650

651+
static void wait_for_xmite(struct uart_port *port)
652+
{
653+
u32 val;
654+
655+
readl_poll_timeout_atomic(port->membase + UART_STAT, val,
656+
(val & STAT_TX_EMP), 1, 10000);
657+
}
658+
651659
static void mvebu_uart_console_putchar(struct uart_port *port, int ch)
652660
{
653661
wait_for_xmitr(port);
@@ -675,7 +683,7 @@ static void mvebu_uart_console_write(struct console *co, const char *s,
675683

676684
uart_console_write(port, s, count, mvebu_uart_console_putchar);
677685

678-
wait_for_xmitr(port);
686+
wait_for_xmite(port);
679687

680688
if (ier)
681689
writel(ier, port->membase + UART_CTRL(port));

drivers/tty/tty_io.c

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,8 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */
143143
DEFINE_MUTEX(tty_mutex);
144144

145145
static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
146-
static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
147-
ssize_t redirected_tty_write(struct file *, const char __user *,
148-
size_t, loff_t *);
146+
static ssize_t tty_write(struct kiocb *, struct iov_iter *);
147+
ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *);
149148
static __poll_t tty_poll(struct file *, poll_table *);
150149
static int tty_open(struct inode *, struct file *);
151150
long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
@@ -438,8 +437,7 @@ static ssize_t hung_up_tty_read(struct file *file, char __user *buf,
438437
return 0;
439438
}
440439

441-
static ssize_t hung_up_tty_write(struct file *file, const char __user *buf,
442-
size_t count, loff_t *ppos)
440+
static ssize_t hung_up_tty_write(struct kiocb *iocb, struct iov_iter *from)
443441
{
444442
return -EIO;
445443
}
@@ -478,7 +476,8 @@ static void tty_show_fdinfo(struct seq_file *m, struct file *file)
478476
static const struct file_operations tty_fops = {
479477
.llseek = no_llseek,
480478
.read = tty_read,
481-
.write = tty_write,
479+
.write_iter = tty_write,
480+
.splice_write = iter_file_splice_write,
482481
.poll = tty_poll,
483482
.unlocked_ioctl = tty_ioctl,
484483
.compat_ioctl = tty_compat_ioctl,
@@ -491,7 +490,8 @@ static const struct file_operations tty_fops = {
491490
static const struct file_operations console_fops = {
492491
.llseek = no_llseek,
493492
.read = tty_read,
494-
.write = redirected_tty_write,
493+
.write_iter = redirected_tty_write,
494+
.splice_write = iter_file_splice_write,
495495
.poll = tty_poll,
496496
.unlocked_ioctl = tty_ioctl,
497497
.compat_ioctl = tty_compat_ioctl,
@@ -503,7 +503,7 @@ static const struct file_operations console_fops = {
503503
static const struct file_operations hung_up_tty_fops = {
504504
.llseek = no_llseek,
505505
.read = hung_up_tty_read,
506-
.write = hung_up_tty_write,
506+
.write_iter = hung_up_tty_write,
507507
.poll = hung_up_tty_poll,
508508
.unlocked_ioctl = hung_up_tty_ioctl,
509509
.compat_ioctl = hung_up_tty_compat_ioctl,
@@ -606,9 +606,9 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session)
606606
/* This breaks for file handles being sent over AF_UNIX sockets ? */
607607
list_for_each_entry(priv, &tty->tty_files, list) {
608608
filp = priv->file;
609-
if (filp->f_op->write == redirected_tty_write)
609+
if (filp->f_op->write_iter == redirected_tty_write)
610610
cons_filp = filp;
611-
if (filp->f_op->write != tty_write)
611+
if (filp->f_op->write_iter != tty_write)
612612
continue;
613613
closecount++;
614614
__tty_fasync(-1, filp, 0); /* can't block */
@@ -901,9 +901,9 @@ static inline ssize_t do_tty_write(
901901
ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t),
902902
struct tty_struct *tty,
903903
struct file *file,
904-
const char __user *buf,
905-
size_t count)
904+
struct iov_iter *from)
906905
{
906+
size_t count = iov_iter_count(from);
907907
ssize_t ret, written = 0;
908908
unsigned int chunk;
909909

@@ -955,14 +955,20 @@ static inline ssize_t do_tty_write(
955955
size_t size = count;
956956
if (size > chunk)
957957
size = chunk;
958+
958959
ret = -EFAULT;
959-
if (copy_from_user(tty->write_buf, buf, size))
960+
if (copy_from_iter(tty->write_buf, size, from) != size)
960961
break;
962+
961963
ret = write(tty, file, tty->write_buf, size);
962964
if (ret <= 0)
963965
break;
966+
967+
/* FIXME! Have Al check this! */
968+
if (ret != size)
969+
iov_iter_revert(from, size-ret);
970+
964971
written += ret;
965-
buf += ret;
966972
count -= ret;
967973
if (!count)
968974
break;
@@ -1022,9 +1028,9 @@ void tty_write_message(struct tty_struct *tty, char *msg)
10221028
* write method will not be invoked in parallel for each device.
10231029
*/
10241030

1025-
static ssize_t tty_write(struct file *file, const char __user *buf,
1026-
size_t count, loff_t *ppos)
1031+
static ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from)
10271032
{
1033+
struct file *file = iocb->ki_filp;
10281034
struct tty_struct *tty = file_tty(file);
10291035
struct tty_ldisc *ld;
10301036
ssize_t ret;
@@ -1038,17 +1044,16 @@ static ssize_t tty_write(struct file *file, const char __user *buf,
10381044
tty_err(tty, "missing write_room method\n");
10391045
ld = tty_ldisc_ref_wait(tty);
10401046
if (!ld)
1041-
return hung_up_tty_write(file, buf, count, ppos);
1047+
return hung_up_tty_write(iocb, from);
10421048
if (!ld->ops->write)
10431049
ret = -EIO;
10441050
else
1045-
ret = do_tty_write(ld->ops->write, tty, file, buf, count);
1051+
ret = do_tty_write(ld->ops->write, tty, file, from);
10461052
tty_ldisc_deref(ld);
10471053
return ret;
10481054
}
10491055

1050-
ssize_t redirected_tty_write(struct file *file, const char __user *buf,
1051-
size_t count, loff_t *ppos)
1056+
ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter)
10521057
{
10531058
struct file *p = NULL;
10541059

@@ -1059,11 +1064,11 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf,
10591064

10601065
if (p) {
10611066
ssize_t res;
1062-
res = vfs_write(p, buf, count, &p->f_pos);
1067+
res = vfs_iocb_iter_write(p, iocb, iter);
10631068
fput(p);
10641069
return res;
10651070
}
1066-
return tty_write(file, buf, count, ppos);
1071+
return tty_write(iocb, iter);
10671072
}
10681073

10691074
/*
@@ -2295,7 +2300,7 @@ static int tioccons(struct file *file)
22952300
{
22962301
if (!capable(CAP_SYS_ADMIN))
22972302
return -EPERM;
2298-
if (file->f_op->write == redirected_tty_write) {
2303+
if (file->f_op->write_iter == redirected_tty_write) {
22992304
struct file *f;
23002305
spin_lock(&redirect_lock);
23012306
f = redirect;

0 commit comments

Comments
 (0)