TTY/Serial fixes for 4.4-rc6
Here are some tty/serial driver fixes for 4.4-rc6 that resolve some reported problems. All of these have been in linux-next. The details are in the shortlog. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iEYEABECAAYFAlZ19rAACgkQMUfUDdst+ykBQQCeKSU7YZFKPTEFbGKS2UfFgMJd EokAoIJp4lXqhLHKtI7TNwVFlMQAaDYj =2I3R -----END PGP SIGNATURE----- Merge tag 'tty-4.4-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty Pull tty/serial fixes from Greg KH: "Here are some tty/serial driver fixes for 4.4-rc6 that resolve some reported problems. All of these have been in linux-next. The details are in the shortlog" * tag 'tty-4.4-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: tty: Fix GPF in flush_to_ldisc() serial: earlycon: Add missing spinlock initialization serial: sh-sci: Fix length of scatterlist n_tty: Fix poll() after buffer-limited eof push read serial: 8250_uniphier: fix dl_read and dl_write functions
This commit is contained in:
commit
69c37a92dd
@ -2054,13 +2054,13 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
|
|||||||
size_t eol;
|
size_t eol;
|
||||||
size_t tail;
|
size_t tail;
|
||||||
int ret, found = 0;
|
int ret, found = 0;
|
||||||
bool eof_push = 0;
|
|
||||||
|
|
||||||
/* N.B. avoid overrun if nr == 0 */
|
/* N.B. avoid overrun if nr == 0 */
|
||||||
n = min(*nr, smp_load_acquire(&ldata->canon_head) - ldata->read_tail);
|
if (!*nr)
|
||||||
if (!n)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
n = min(*nr + 1, smp_load_acquire(&ldata->canon_head) - ldata->read_tail);
|
||||||
|
|
||||||
tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
|
tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
|
||||||
size = min_t(size_t, tail + n, N_TTY_BUF_SIZE);
|
size = min_t(size_t, tail + n, N_TTY_BUF_SIZE);
|
||||||
|
|
||||||
@ -2081,12 +2081,11 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
|
|||||||
n = eol - tail;
|
n = eol - tail;
|
||||||
if (n > N_TTY_BUF_SIZE)
|
if (n > N_TTY_BUF_SIZE)
|
||||||
n += N_TTY_BUF_SIZE;
|
n += N_TTY_BUF_SIZE;
|
||||||
n += found;
|
c = n + found;
|
||||||
c = n;
|
|
||||||
|
|
||||||
if (found && !ldata->push && read_buf(ldata, eol) == __DISABLED_CHAR) {
|
if (!found || read_buf(ldata, eol) != __DISABLED_CHAR) {
|
||||||
n--;
|
c = min(*nr, c);
|
||||||
eof_push = !n && ldata->read_tail != ldata->line_start;
|
n = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu size:%zu more:%zu\n",
|
n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu size:%zu more:%zu\n",
|
||||||
@ -2116,7 +2115,7 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
|
|||||||
ldata->push = 0;
|
ldata->push = 0;
|
||||||
tty_audit_push(tty);
|
tty_audit_push(tty);
|
||||||
}
|
}
|
||||||
return eof_push ? -EAGAIN : 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern ssize_t redirected_tty_write(struct file *, const char __user *,
|
extern ssize_t redirected_tty_write(struct file *, const char __user *,
|
||||||
@ -2273,10 +2272,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
|
|||||||
|
|
||||||
if (ldata->icanon && !L_EXTPROC(tty)) {
|
if (ldata->icanon && !L_EXTPROC(tty)) {
|
||||||
retval = canon_copy_from_read_buf(tty, &b, &nr);
|
retval = canon_copy_from_read_buf(tty, &b, &nr);
|
||||||
if (retval == -EAGAIN) {
|
if (retval)
|
||||||
retval = 0;
|
|
||||||
continue;
|
|
||||||
} else if (retval)
|
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
int uncopied;
|
int uncopied;
|
||||||
|
@ -115,12 +115,16 @@ static void uniphier_serial_out(struct uart_port *p, int offset, int value)
|
|||||||
*/
|
*/
|
||||||
static int uniphier_serial_dl_read(struct uart_8250_port *up)
|
static int uniphier_serial_dl_read(struct uart_8250_port *up)
|
||||||
{
|
{
|
||||||
return readl(up->port.membase + UNIPHIER_UART_DLR);
|
int offset = UNIPHIER_UART_DLR << up->port.regshift;
|
||||||
|
|
||||||
|
return readl(up->port.membase + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uniphier_serial_dl_write(struct uart_8250_port *up, int value)
|
static void uniphier_serial_dl_write(struct uart_8250_port *up, int value)
|
||||||
{
|
{
|
||||||
writel(value, up->port.membase + UNIPHIER_UART_DLR);
|
int offset = UNIPHIER_UART_DLR << up->port.regshift;
|
||||||
|
|
||||||
|
writel(value, up->port.membase + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port,
|
static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port,
|
||||||
|
@ -115,6 +115,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match)
|
|||||||
if (buf && !parse_options(&early_console_dev, buf))
|
if (buf && !parse_options(&early_console_dev, buf))
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
|
|
||||||
|
spin_lock_init(&port->lock);
|
||||||
port->uartclk = BASE_BAUD * 16;
|
port->uartclk = BASE_BAUD * 16;
|
||||||
if (port->mapbase)
|
if (port->mapbase)
|
||||||
port->membase = earlycon_map(port->mapbase, 64);
|
port->membase = earlycon_map(port->mapbase, 64);
|
||||||
@ -202,6 +203,7 @@ int __init of_setup_earlycon(unsigned long addr,
|
|||||||
int err;
|
int err;
|
||||||
struct uart_port *port = &early_console_dev.port;
|
struct uart_port *port = &early_console_dev.port;
|
||||||
|
|
||||||
|
spin_lock_init(&port->lock);
|
||||||
port->iotype = UPIO_MEM;
|
port->iotype = UPIO_MEM;
|
||||||
port->mapbase = addr;
|
port->mapbase = addr;
|
||||||
port->uartclk = BASE_BAUD * 16;
|
port->uartclk = BASE_BAUD * 16;
|
||||||
|
@ -1437,7 +1437,7 @@ static void sci_request_dma(struct uart_port *port)
|
|||||||
sg_init_table(sg, 1);
|
sg_init_table(sg, 1);
|
||||||
s->rx_buf[i] = buf;
|
s->rx_buf[i] = buf;
|
||||||
sg_dma_address(sg) = dma;
|
sg_dma_address(sg) = dma;
|
||||||
sg->length = s->buf_len_rx;
|
sg_dma_len(sg) = s->buf_len_rx;
|
||||||
|
|
||||||
buf += s->buf_len_rx;
|
buf += s->buf_len_rx;
|
||||||
dma += s->buf_len_rx;
|
dma += s->buf_len_rx;
|
||||||
|
@ -450,7 +450,7 @@ receive_buf(struct tty_struct *tty, struct tty_buffer *head, int count)
|
|||||||
count = disc->ops->receive_buf2(tty, p, f, count);
|
count = disc->ops->receive_buf2(tty, p, f, count);
|
||||||
else {
|
else {
|
||||||
count = min_t(int, count, tty->receive_room);
|
count = min_t(int, count, tty->receive_room);
|
||||||
if (count)
|
if (count && disc->ops->receive_buf)
|
||||||
disc->ops->receive_buf(tty, p, f, count);
|
disc->ops->receive_buf(tty, p, f, count);
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user