Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+37 -24
+9 -1
drivers/tty/serial/mvebu-uart.c
··· 648 648 (val & STAT_TX_RDY(port)), 1, 10000); 649 649 } 650 650 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 + 651 659 static void mvebu_uart_console_putchar(struct uart_port *port, int ch) 652 660 { 653 661 wait_for_xmitr(port); ··· 683 675 684 676 uart_console_write(port, s, count, mvebu_uart_console_putchar); 685 677 686 - wait_for_xmitr(port); 678 + wait_for_xmite(port); 687 679 688 680 if (ier) 689 681 writel(ier, port->membase + UART_CTRL(port));
+28 -23
drivers/tty/tty_io.c
··· 143 143 DEFINE_MUTEX(tty_mutex); 144 144 145 145 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 *); 149 148 static __poll_t tty_poll(struct file *, poll_table *); 150 149 static int tty_open(struct inode *, struct file *); 151 150 long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg); ··· 437 438 return 0; 438 439 } 439 440 440 - static ssize_t hung_up_tty_write(struct file *file, const char __user *buf, 441 - size_t count, loff_t *ppos) 441 + static ssize_t hung_up_tty_write(struct kiocb *iocb, struct iov_iter *from) 442 442 { 443 443 return -EIO; 444 444 } ··· 476 478 static const struct file_operations tty_fops = { 477 479 .llseek = no_llseek, 478 480 .read = tty_read, 479 - .write = tty_write, 481 + .write_iter = tty_write, 482 + .splice_write = iter_file_splice_write, 480 483 .poll = tty_poll, 481 484 .unlocked_ioctl = tty_ioctl, 482 485 .compat_ioctl = tty_compat_ioctl, ··· 490 491 static const struct file_operations console_fops = { 491 492 .llseek = no_llseek, 492 493 .read = tty_read, 493 - .write = redirected_tty_write, 494 + .write_iter = redirected_tty_write, 495 + .splice_write = iter_file_splice_write, 494 496 .poll = tty_poll, 495 497 .unlocked_ioctl = tty_ioctl, 496 498 .compat_ioctl = tty_compat_ioctl, ··· 503 503 static const struct file_operations hung_up_tty_fops = { 504 504 .llseek = no_llseek, 505 505 .read = hung_up_tty_read, 506 - .write = hung_up_tty_write, 506 + .write_iter = hung_up_tty_write, 507 507 .poll = hung_up_tty_poll, 508 508 .unlocked_ioctl = hung_up_tty_ioctl, 509 509 .compat_ioctl = hung_up_tty_compat_ioctl, ··· 606 606 /* This breaks for file handles being sent over AF_UNIX sockets ? */ 607 607 list_for_each_entry(priv, &tty->tty_files, list) { 608 608 filp = priv->file; 609 - if (filp->f_op->write == redirected_tty_write) 609 + if (filp->f_op->write_iter == redirected_tty_write) 610 610 cons_filp = filp; 611 - if (filp->f_op->write != tty_write) 611 + if (filp->f_op->write_iter != tty_write) 612 612 continue; 613 613 closecount++; 614 614 __tty_fasync(-1, filp, 0); /* can't block */ ··· 901 901 ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t), 902 902 struct tty_struct *tty, 903 903 struct file *file, 904 - const char __user *buf, 905 - size_t count) 904 + struct iov_iter *from) 906 905 { 906 + size_t count = iov_iter_count(from); 907 907 ssize_t ret, written = 0; 908 908 unsigned int chunk; 909 909 ··· 955 955 size_t size = count; 956 956 if (size > chunk) 957 957 size = chunk; 958 + 958 959 ret = -EFAULT; 959 - if (copy_from_user(tty->write_buf, buf, size)) 960 + if (copy_from_iter(tty->write_buf, size, from) != size) 960 961 break; 962 + 961 963 ret = write(tty, file, tty->write_buf, size); 962 964 if (ret <= 0) 963 965 break; 966 + 967 + /* FIXME! Have Al check this! */ 968 + if (ret != size) 969 + iov_iter_revert(from, size-ret); 970 + 964 971 written += ret; 965 - buf += ret; 966 972 count -= ret; 967 973 if (!count) 968 974 break; ··· 1028 1022 * write method will not be invoked in parallel for each device. 1029 1023 */ 1030 1024 1031 - static ssize_t tty_write(struct file *file, const char __user *buf, 1032 - size_t count, loff_t *ppos) 1025 + static ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from) 1033 1026 { 1027 + struct file *file = iocb->ki_filp; 1034 1028 struct tty_struct *tty = file_tty(file); 1035 1029 struct tty_ldisc *ld; 1036 1030 ssize_t ret; ··· 1044 1038 tty_err(tty, "missing write_room method\n"); 1045 1039 ld = tty_ldisc_ref_wait(tty); 1046 1040 if (!ld) 1047 - return hung_up_tty_write(file, buf, count, ppos); 1041 + return hung_up_tty_write(iocb, from); 1048 1042 if (!ld->ops->write) 1049 1043 ret = -EIO; 1050 1044 else 1051 - ret = do_tty_write(ld->ops->write, tty, file, buf, count); 1045 + ret = do_tty_write(ld->ops->write, tty, file, from); 1052 1046 tty_ldisc_deref(ld); 1053 1047 return ret; 1054 1048 } 1055 1049 1056 - ssize_t redirected_tty_write(struct file *file, const char __user *buf, 1057 - size_t count, loff_t *ppos) 1050 + ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter) 1058 1051 { 1059 1052 struct file *p = NULL; 1060 1053 ··· 1064 1059 1065 1060 if (p) { 1066 1061 ssize_t res; 1067 - res = vfs_write(p, buf, count, &p->f_pos); 1062 + res = vfs_iocb_iter_write(p, iocb, iter); 1068 1063 fput(p); 1069 1064 return res; 1070 1065 } 1071 - return tty_write(file, buf, count, ppos); 1066 + return tty_write(iocb, iter); 1072 1067 } 1073 1068 1074 1069 /* ··· 2300 2295 { 2301 2296 if (!capable(CAP_SYS_ADMIN)) 2302 2297 return -EPERM; 2303 - if (file->f_op->write == redirected_tty_write) { 2298 + if (file->f_op->write_iter == redirected_tty_write) { 2304 2299 struct file *f; 2305 2300 spin_lock(&redirect_lock); 2306 2301 f = redirect;