mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 20:54:10 +08:00
TTY/Serial fixes for 5.11-rc5
Here are 3 small tty/serial fixes for 5.11-rc5 to resolve reported problems: - 2 patches from you 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. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCYA1tkQ8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ym9nwCZAfiPNV9eSh0A92RMAYfl9gjndGAAn1P/LWTb PkmO1htDe/IDadsvPUWq =1vln -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
4da81fa210
@ -648,6 +648,14 @@ static void wait_for_xmitr(struct uart_port *port)
|
||||
(val & STAT_TX_RDY(port)), 1, 10000);
|
||||
}
|
||||
|
||||
static void wait_for_xmite(struct uart_port *port)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
readl_poll_timeout_atomic(port->membase + UART_STAT, val,
|
||||
(val & STAT_TX_EMP), 1, 10000);
|
||||
}
|
||||
|
||||
static void mvebu_uart_console_putchar(struct uart_port *port, int ch)
|
||||
{
|
||||
wait_for_xmitr(port);
|
||||
@ -675,7 +683,7 @@ static void mvebu_uart_console_write(struct console *co, const char *s,
|
||||
|
||||
uart_console_write(port, s, count, mvebu_uart_console_putchar);
|
||||
|
||||
wait_for_xmitr(port);
|
||||
wait_for_xmite(port);
|
||||
|
||||
if (ier)
|
||||
writel(ier, port->membase + UART_CTRL(port));
|
||||
|
@ -143,9 +143,8 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */
|
||||
DEFINE_MUTEX(tty_mutex);
|
||||
|
||||
static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
|
||||
static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
|
||||
ssize_t redirected_tty_write(struct file *, const char __user *,
|
||||
size_t, loff_t *);
|
||||
static ssize_t tty_write(struct kiocb *, struct iov_iter *);
|
||||
ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *);
|
||||
static __poll_t tty_poll(struct file *, poll_table *);
|
||||
static int tty_open(struct inode *, struct file *);
|
||||
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,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t hung_up_tty_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
static ssize_t hung_up_tty_write(struct kiocb *iocb, struct iov_iter *from)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
@ -478,7 +476,8 @@ static void tty_show_fdinfo(struct seq_file *m, struct file *file)
|
||||
static const struct file_operations tty_fops = {
|
||||
.llseek = no_llseek,
|
||||
.read = tty_read,
|
||||
.write = tty_write,
|
||||
.write_iter = tty_write,
|
||||
.splice_write = iter_file_splice_write,
|
||||
.poll = tty_poll,
|
||||
.unlocked_ioctl = tty_ioctl,
|
||||
.compat_ioctl = tty_compat_ioctl,
|
||||
@ -491,7 +490,8 @@ static const struct file_operations tty_fops = {
|
||||
static const struct file_operations console_fops = {
|
||||
.llseek = no_llseek,
|
||||
.read = tty_read,
|
||||
.write = redirected_tty_write,
|
||||
.write_iter = redirected_tty_write,
|
||||
.splice_write = iter_file_splice_write,
|
||||
.poll = tty_poll,
|
||||
.unlocked_ioctl = tty_ioctl,
|
||||
.compat_ioctl = tty_compat_ioctl,
|
||||
@ -503,7 +503,7 @@ static const struct file_operations console_fops = {
|
||||
static const struct file_operations hung_up_tty_fops = {
|
||||
.llseek = no_llseek,
|
||||
.read = hung_up_tty_read,
|
||||
.write = hung_up_tty_write,
|
||||
.write_iter = hung_up_tty_write,
|
||||
.poll = hung_up_tty_poll,
|
||||
.unlocked_ioctl = hung_up_tty_ioctl,
|
||||
.compat_ioctl = hung_up_tty_compat_ioctl,
|
||||
@ -606,9 +606,9 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session)
|
||||
/* This breaks for file handles being sent over AF_UNIX sockets ? */
|
||||
list_for_each_entry(priv, &tty->tty_files, list) {
|
||||
filp = priv->file;
|
||||
if (filp->f_op->write == redirected_tty_write)
|
||||
if (filp->f_op->write_iter == redirected_tty_write)
|
||||
cons_filp = filp;
|
||||
if (filp->f_op->write != tty_write)
|
||||
if (filp->f_op->write_iter != tty_write)
|
||||
continue;
|
||||
closecount++;
|
||||
__tty_fasync(-1, filp, 0); /* can't block */
|
||||
@ -901,9 +901,9 @@ static inline ssize_t do_tty_write(
|
||||
ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t),
|
||||
struct tty_struct *tty,
|
||||
struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count)
|
||||
struct iov_iter *from)
|
||||
{
|
||||
size_t count = iov_iter_count(from);
|
||||
ssize_t ret, written = 0;
|
||||
unsigned int chunk;
|
||||
|
||||
@ -955,14 +955,20 @@ static inline ssize_t do_tty_write(
|
||||
size_t size = count;
|
||||
if (size > chunk)
|
||||
size = chunk;
|
||||
|
||||
ret = -EFAULT;
|
||||
if (copy_from_user(tty->write_buf, buf, size))
|
||||
if (copy_from_iter(tty->write_buf, size, from) != size)
|
||||
break;
|
||||
|
||||
ret = write(tty, file, tty->write_buf, size);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
|
||||
/* FIXME! Have Al check this! */
|
||||
if (ret != size)
|
||||
iov_iter_revert(from, size-ret);
|
||||
|
||||
written += ret;
|
||||
buf += ret;
|
||||
count -= ret;
|
||||
if (!count)
|
||||
break;
|
||||
@ -1022,9 +1028,9 @@ void tty_write_message(struct tty_struct *tty, char *msg)
|
||||
* write method will not be invoked in parallel for each device.
|
||||
*/
|
||||
|
||||
static ssize_t tty_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
static ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from)
|
||||
{
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct tty_struct *tty = file_tty(file);
|
||||
struct tty_ldisc *ld;
|
||||
ssize_t ret;
|
||||
@ -1038,17 +1044,16 @@ static ssize_t tty_write(struct file *file, const char __user *buf,
|
||||
tty_err(tty, "missing write_room method\n");
|
||||
ld = tty_ldisc_ref_wait(tty);
|
||||
if (!ld)
|
||||
return hung_up_tty_write(file, buf, count, ppos);
|
||||
return hung_up_tty_write(iocb, from);
|
||||
if (!ld->ops->write)
|
||||
ret = -EIO;
|
||||
else
|
||||
ret = do_tty_write(ld->ops->write, tty, file, buf, count);
|
||||
ret = do_tty_write(ld->ops->write, tty, file, from);
|
||||
tty_ldisc_deref(ld);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t redirected_tty_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter)
|
||||
{
|
||||
struct file *p = NULL;
|
||||
|
||||
@ -1059,11 +1064,11 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf,
|
||||
|
||||
if (p) {
|
||||
ssize_t res;
|
||||
res = vfs_write(p, buf, count, &p->f_pos);
|
||||
res = vfs_iocb_iter_write(p, iocb, iter);
|
||||
fput(p);
|
||||
return res;
|
||||
}
|
||||
return tty_write(file, buf, count, ppos);
|
||||
return tty_write(iocb, iter);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2295,7 +2300,7 @@ static int tioccons(struct file *file)
|
||||
{
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
if (file->f_op->write == redirected_tty_write) {
|
||||
if (file->f_op->write_iter == redirected_tty_write) {
|
||||
struct file *f;
|
||||
spin_lock(&redirect_lock);
|
||||
f = redirect;
|
||||
|
Loading…
Reference in New Issue
Block a user