Skip to content

Commit

Permalink
Merge tag 'tty-5.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/gregkh/tty

Pull tty/serial driver fixes from Greg KH:
 "Here are a number of small tty core and serial driver fixes for
  5.0-rc4 to resolve some reported issues.

  Nothing major, the small serial driver fixes, a tty core fixup for a
  crash that was reported, and some good vt fixes from Nicolas Pitre as
  he seems to be auditing that chunk of code a lot lately.

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'tty-5.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  serial: fsl_lpuart: fix maximum acceptable baud rate with over-sampling
  tty: serial: qcom_geni_serial: Allow mctrl when flow control is disabled
  tty: Handle problem if line discipline does not have receive_buf
  vgacon: unconfuse vc_origin when using soft scrollback
  vt: invoke notifier on screen size change
  vt: always call notifier with the console lock held
  vt: make vt_console_print() compatible with the unicode screen buffer
  tty/n_hdlc: fix __might_sleep warning
  serial: 8250: Fix serial8250 initialization crash
  uart: Fix crash in uart_write and uart_put_char
  • Loading branch information
Linus Torvalds committed Jan 25, 2019
2 parents b48cef3 + 815d835 commit 473721f
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 52 deletions.
1 change: 1 addition & 0 deletions drivers/tty/n_hdlc.c
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
/* too large for caller's buffer */
ret = -EOVERFLOW;
} else {
__set_current_state(TASK_RUNNING);
if (copy_to_user(buf, rbuf->buf, rbuf->count))
ret = -EFAULT;
else
Expand Down
17 changes: 9 additions & 8 deletions drivers/tty/serial/8250/8250_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1070,15 +1070,16 @@ int serial8250_register_8250_port(struct uart_8250_port *up)

ret = 0;
}
}

/* Initialise interrupt backoff work if required */
if (up->overrun_backoff_time_ms > 0) {
uart->overrun_backoff_time_ms = up->overrun_backoff_time_ms;
INIT_DELAYED_WORK(&uart->overrun_backoff,
serial_8250_overrun_backoff_work);
} else {
uart->overrun_backoff_time_ms = 0;
/* Initialise interrupt backoff work if required */
if (up->overrun_backoff_time_ms > 0) {
uart->overrun_backoff_time_ms =
up->overrun_backoff_time_ms;
INIT_DELAYED_WORK(&uart->overrun_backoff,
serial_8250_overrun_backoff_work);
} else {
uart->overrun_backoff_time_ms = 0;
}
}

mutex_unlock(&serial_mutex);
Expand Down
2 changes: 1 addition & 1 deletion drivers/tty/serial/fsl_lpuart.c
Original file line number Diff line number Diff line change
Expand Up @@ -1697,7 +1697,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
}

/* ask the core to calculate the divisor */
baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16);
baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 4);

spin_lock_irqsave(&sport->port.lock, flags);

Expand Down
4 changes: 2 additions & 2 deletions drivers/tty/serial/qcom_geni_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ static unsigned int qcom_geni_serial_get_mctrl(struct uart_port *uport)
unsigned int mctrl = TIOCM_DSR | TIOCM_CAR;
u32 geni_ios;

if (uart_console(uport) || !uart_cts_enabled(uport)) {
if (uart_console(uport)) {
mctrl |= TIOCM_CTS;
} else {
geni_ios = readl_relaxed(uport->membase + SE_GENI_IOS);
Expand All @@ -241,7 +241,7 @@ static void qcom_geni_serial_set_mctrl(struct uart_port *uport,
{
u32 uart_manual_rfr = 0;

if (uart_console(uport) || !uart_cts_enabled(uport))
if (uart_console(uport))
return;

if (!(mctrl & TIOCM_RTS))
Expand Down
12 changes: 8 additions & 4 deletions drivers/tty/serial/serial_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,10 +550,12 @@ static int uart_put_char(struct tty_struct *tty, unsigned char c)
int ret = 0;

circ = &state->xmit;
if (!circ->buf)
port = uart_port_lock(state, flags);
if (!circ->buf) {
uart_port_unlock(port, flags);
return 0;
}

port = uart_port_lock(state, flags);
if (port && uart_circ_chars_free(circ) != 0) {
circ->buf[circ->head] = c;
circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1);
Expand Down Expand Up @@ -586,11 +588,13 @@ static int uart_write(struct tty_struct *tty,
return -EL3HLT;
}

port = uart_port_lock(state, flags);
circ = &state->xmit;
if (!circ->buf)
if (!circ->buf) {
uart_port_unlock(port, flags);
return 0;
}

port = uart_port_lock(state, flags);
while (port) {
c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
if (count < c)
Expand Down
3 changes: 2 additions & 1 deletion drivers/tty/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -2189,7 +2189,8 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
ld = tty_ldisc_ref_wait(tty);
if (!ld)
return -EIO;
ld->ops->receive_buf(tty, &ch, &mbz, 1);
if (ld->ops->receive_buf)
ld->ops->receive_buf(tty, &ch, &mbz, 1);
tty_ldisc_deref(ld);
return 0;
}
Expand Down
50 changes: 17 additions & 33 deletions drivers/tty/vt/vt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1272,6 +1272,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
if (con_is_visible(vc))
update_screen(vc);
vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num);
notify_update(vc);
return err;
}

Expand Down Expand Up @@ -2764,8 +2765,8 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
con_flush(vc, draw_from, draw_to, &draw_x);
vc_uniscr_debug_check(vc);
console_conditional_schedule();
console_unlock();
notify_update(vc);
console_unlock();
return n;
}

Expand Down Expand Up @@ -2884,8 +2885,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
unsigned char c;
static DEFINE_SPINLOCK(printing_lock);
const ushort *start;
ushort cnt = 0;
ushort myx;
ushort start_x, cnt;
int kmsg_console;

/* console busy or not yet initialized */
Expand All @@ -2898,10 +2898,6 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
if (kmsg_console && vc_cons_allocated(kmsg_console - 1))
vc = vc_cons[kmsg_console - 1].d;

/* read `x' only after setting currcons properly (otherwise
the `x' macro will read the x of the foreground console). */
myx = vc->vc_x;

if (!vc_cons_allocated(fg_console)) {
/* impossible */
/* printk("vt_console_print: tty %d not allocated ??\n", currcons+1); */
Expand All @@ -2916,53 +2912,41 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
hide_cursor(vc);

start = (ushort *)vc->vc_pos;

/* Contrived structure to try to emulate original need_wrap behaviour
* Problems caused when we have need_wrap set on '\n' character */
start_x = vc->vc_x;
cnt = 0;
while (count--) {
c = *b++;
if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
if (cnt > 0) {
if (con_is_visible(vc))
vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
vc->vc_x += cnt;
if (vc->vc_need_wrap)
vc->vc_x--;
cnt = 0;
}
if (cnt && con_is_visible(vc))
vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x);
cnt = 0;
if (c == 8) { /* backspace */
bs(vc);
start = (ushort *)vc->vc_pos;
myx = vc->vc_x;
start_x = vc->vc_x;
continue;
}
if (c != 13)
lf(vc);
cr(vc);
start = (ushort *)vc->vc_pos;
myx = vc->vc_x;
start_x = vc->vc_x;
if (c == 10 || c == 13)
continue;
}
vc_uniscr_putc(vc, c);
scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
notify_write(vc, c);
cnt++;
if (myx == vc->vc_cols - 1) {
vc->vc_need_wrap = 1;
continue;
}
vc->vc_pos += 2;
myx++;
}
if (cnt > 0) {
if (con_is_visible(vc))
vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
vc->vc_x += cnt;
if (vc->vc_x == vc->vc_cols) {
vc->vc_x--;
if (vc->vc_x == vc->vc_cols - 1) {
vc->vc_need_wrap = 1;
} else {
vc->vc_pos += 2;
vc->vc_x++;
}
}
if (cnt && con_is_visible(vc))
vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x);
set_cursor(vc);
notify_update(vc);

Expand Down
7 changes: 4 additions & 3 deletions drivers/video/console/vgacon.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count)

static void vgacon_restore_screen(struct vc_data *c)
{
c->vc_origin = c->vc_visible_origin;
vgacon_scrollback_cur->save = 0;

if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
Expand All @@ -287,8 +288,7 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
int start, end, count, soff;

if (!lines) {
c->vc_visible_origin = c->vc_origin;
vga_set_mem_top(c);
vgacon_restore_screen(c);
return;
}

Expand All @@ -298,6 +298,7 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
if (!vgacon_scrollback_cur->save) {
vgacon_cursor(c, CM_ERASE);
vgacon_save_screen(c);
c->vc_origin = (unsigned long)c->vc_screenbuf;
vgacon_scrollback_cur->save = 1;
}

Expand Down Expand Up @@ -335,7 +336,7 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
int copysize;

int diff = c->vc_rows - count;
void *d = (void *) c->vc_origin;
void *d = (void *) c->vc_visible_origin;
void *s = (void *) c->vc_screenbuf;

count *= c->vc_size_row;
Expand Down

0 comments on commit 473721f

Please sign in to comment.