diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-25 17:58:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-25 17:58:40 -0500 |
commit | 473721f9c6494c04991b9a4cb787361d941d0d7d (patch) | |
tree | 71dee151cdf33852560a147b594490cab02cefb3 /drivers | |
parent | b48cef32b6a5103dddf52aadbeda90ab0f7ef673 (diff) | |
parent | 815d835b7ba46685c316b000013367dacb2b461b (diff) |
Merge tag 'tty-5.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/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
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/tty/n_hdlc.c | 1 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_core.c | 17 | ||||
-rw-r--r-- | drivers/tty/serial/fsl_lpuart.c | 2 | ||||
-rw-r--r-- | drivers/tty/serial/qcom_geni_serial.c | 4 | ||||
-rw-r--r-- | drivers/tty/serial/serial_core.c | 12 | ||||
-rw-r--r-- | drivers/tty/tty_io.c | 3 | ||||
-rw-r--r-- | drivers/tty/vt/vt.c | 50 | ||||
-rw-r--r-- | drivers/video/console/vgacon.c | 7 |
8 files changed, 44 insertions, 52 deletions
diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index 4164414d4c64..8bdf42bc8fc8 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c | |||
@@ -597,6 +597,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, | |||
597 | /* too large for caller's buffer */ | 597 | /* too large for caller's buffer */ |
598 | ret = -EOVERFLOW; | 598 | ret = -EOVERFLOW; |
599 | } else { | 599 | } else { |
600 | __set_current_state(TASK_RUNNING); | ||
600 | if (copy_to_user(buf, rbuf->buf, rbuf->count)) | 601 | if (copy_to_user(buf, rbuf->buf, rbuf->count)) |
601 | ret = -EFAULT; | 602 | ret = -EFAULT; |
602 | else | 603 | else |
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 189ab1212d9a..e441221e04b9 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c | |||
@@ -1070,15 +1070,16 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
1070 | 1070 | ||
1071 | ret = 0; | 1071 | ret = 0; |
1072 | } | 1072 | } |
1073 | } | ||
1074 | 1073 | ||
1075 | /* Initialise interrupt backoff work if required */ | 1074 | /* Initialise interrupt backoff work if required */ |
1076 | if (up->overrun_backoff_time_ms > 0) { | 1075 | if (up->overrun_backoff_time_ms > 0) { |
1077 | uart->overrun_backoff_time_ms = up->overrun_backoff_time_ms; | 1076 | uart->overrun_backoff_time_ms = |
1078 | INIT_DELAYED_WORK(&uart->overrun_backoff, | 1077 | up->overrun_backoff_time_ms; |
1079 | serial_8250_overrun_backoff_work); | 1078 | INIT_DELAYED_WORK(&uart->overrun_backoff, |
1080 | } else { | 1079 | serial_8250_overrun_backoff_work); |
1081 | uart->overrun_backoff_time_ms = 0; | 1080 | } else { |
1081 | uart->overrun_backoff_time_ms = 0; | ||
1082 | } | ||
1082 | } | 1083 | } |
1083 | 1084 | ||
1084 | mutex_unlock(&serial_mutex); | 1085 | mutex_unlock(&serial_mutex); |
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 241a48e5052c..debdd1b9e01a 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c | |||
@@ -1697,7 +1697,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1697 | } | 1697 | } |
1698 | 1698 | ||
1699 | /* ask the core to calculate the divisor */ | 1699 | /* ask the core to calculate the divisor */ |
1700 | baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); | 1700 | baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 4); |
1701 | 1701 | ||
1702 | spin_lock_irqsave(&sport->port.lock, flags); | 1702 | spin_lock_irqsave(&sport->port.lock, flags); |
1703 | 1703 | ||
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index a72d6d9fb983..38016609c7fa 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c | |||
@@ -225,7 +225,7 @@ static unsigned int qcom_geni_serial_get_mctrl(struct uart_port *uport) | |||
225 | unsigned int mctrl = TIOCM_DSR | TIOCM_CAR; | 225 | unsigned int mctrl = TIOCM_DSR | TIOCM_CAR; |
226 | u32 geni_ios; | 226 | u32 geni_ios; |
227 | 227 | ||
228 | if (uart_console(uport) || !uart_cts_enabled(uport)) { | 228 | if (uart_console(uport)) { |
229 | mctrl |= TIOCM_CTS; | 229 | mctrl |= TIOCM_CTS; |
230 | } else { | 230 | } else { |
231 | geni_ios = readl_relaxed(uport->membase + SE_GENI_IOS); | 231 | geni_ios = readl_relaxed(uport->membase + SE_GENI_IOS); |
@@ -241,7 +241,7 @@ static void qcom_geni_serial_set_mctrl(struct uart_port *uport, | |||
241 | { | 241 | { |
242 | u32 uart_manual_rfr = 0; | 242 | u32 uart_manual_rfr = 0; |
243 | 243 | ||
244 | if (uart_console(uport) || !uart_cts_enabled(uport)) | 244 | if (uart_console(uport)) |
245 | return; | 245 | return; |
246 | 246 | ||
247 | if (!(mctrl & TIOCM_RTS)) | 247 | if (!(mctrl & TIOCM_RTS)) |
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index d4cca5bdaf1c..5c01bb6d1c24 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -550,10 +550,12 @@ static int uart_put_char(struct tty_struct *tty, unsigned char c) | |||
550 | int ret = 0; | 550 | int ret = 0; |
551 | 551 | ||
552 | circ = &state->xmit; | 552 | circ = &state->xmit; |
553 | if (!circ->buf) | 553 | port = uart_port_lock(state, flags); |
554 | if (!circ->buf) { | ||
555 | uart_port_unlock(port, flags); | ||
554 | return 0; | 556 | return 0; |
557 | } | ||
555 | 558 | ||
556 | port = uart_port_lock(state, flags); | ||
557 | if (port && uart_circ_chars_free(circ) != 0) { | 559 | if (port && uart_circ_chars_free(circ) != 0) { |
558 | circ->buf[circ->head] = c; | 560 | circ->buf[circ->head] = c; |
559 | circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1); | 561 | circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1); |
@@ -586,11 +588,13 @@ static int uart_write(struct tty_struct *tty, | |||
586 | return -EL3HLT; | 588 | return -EL3HLT; |
587 | } | 589 | } |
588 | 590 | ||
591 | port = uart_port_lock(state, flags); | ||
589 | circ = &state->xmit; | 592 | circ = &state->xmit; |
590 | if (!circ->buf) | 593 | if (!circ->buf) { |
594 | uart_port_unlock(port, flags); | ||
591 | return 0; | 595 | return 0; |
596 | } | ||
592 | 597 | ||
593 | port = uart_port_lock(state, flags); | ||
594 | while (port) { | 598 | while (port) { |
595 | c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); | 599 | c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); |
596 | if (count < c) | 600 | if (count < c) |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 23c6fd238422..21ffcce16927 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -2189,7 +2189,8 @@ static int tiocsti(struct tty_struct *tty, char __user *p) | |||
2189 | ld = tty_ldisc_ref_wait(tty); | 2189 | ld = tty_ldisc_ref_wait(tty); |
2190 | if (!ld) | 2190 | if (!ld) |
2191 | return -EIO; | 2191 | return -EIO; |
2192 | ld->ops->receive_buf(tty, &ch, &mbz, 1); | 2192 | if (ld->ops->receive_buf) |
2193 | ld->ops->receive_buf(tty, &ch, &mbz, 1); | ||
2193 | tty_ldisc_deref(ld); | 2194 | tty_ldisc_deref(ld); |
2194 | return 0; | 2195 | return 0; |
2195 | } | 2196 | } |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 41ec8e5010f3..bba75560d11e 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -1272,6 +1272,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, | |||
1272 | if (con_is_visible(vc)) | 1272 | if (con_is_visible(vc)) |
1273 | update_screen(vc); | 1273 | update_screen(vc); |
1274 | vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num); | 1274 | vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num); |
1275 | notify_update(vc); | ||
1275 | return err; | 1276 | return err; |
1276 | } | 1277 | } |
1277 | 1278 | ||
@@ -2764,8 +2765,8 @@ rescan_last_byte: | |||
2764 | con_flush(vc, draw_from, draw_to, &draw_x); | 2765 | con_flush(vc, draw_from, draw_to, &draw_x); |
2765 | vc_uniscr_debug_check(vc); | 2766 | vc_uniscr_debug_check(vc); |
2766 | console_conditional_schedule(); | 2767 | console_conditional_schedule(); |
2767 | console_unlock(); | ||
2768 | notify_update(vc); | 2768 | notify_update(vc); |
2769 | console_unlock(); | ||
2769 | return n; | 2770 | return n; |
2770 | } | 2771 | } |
2771 | 2772 | ||
@@ -2884,8 +2885,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2884 | unsigned char c; | 2885 | unsigned char c; |
2885 | static DEFINE_SPINLOCK(printing_lock); | 2886 | static DEFINE_SPINLOCK(printing_lock); |
2886 | const ushort *start; | 2887 | const ushort *start; |
2887 | ushort cnt = 0; | 2888 | ushort start_x, cnt; |
2888 | ushort myx; | ||
2889 | int kmsg_console; | 2889 | int kmsg_console; |
2890 | 2890 | ||
2891 | /* console busy or not yet initialized */ | 2891 | /* console busy or not yet initialized */ |
@@ -2898,10 +2898,6 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2898 | if (kmsg_console && vc_cons_allocated(kmsg_console - 1)) | 2898 | if (kmsg_console && vc_cons_allocated(kmsg_console - 1)) |
2899 | vc = vc_cons[kmsg_console - 1].d; | 2899 | vc = vc_cons[kmsg_console - 1].d; |
2900 | 2900 | ||
2901 | /* read `x' only after setting currcons properly (otherwise | ||
2902 | the `x' macro will read the x of the foreground console). */ | ||
2903 | myx = vc->vc_x; | ||
2904 | |||
2905 | if (!vc_cons_allocated(fg_console)) { | 2901 | if (!vc_cons_allocated(fg_console)) { |
2906 | /* impossible */ | 2902 | /* impossible */ |
2907 | /* printk("vt_console_print: tty %d not allocated ??\n", currcons+1); */ | 2903 | /* printk("vt_console_print: tty %d not allocated ??\n", currcons+1); */ |
@@ -2916,53 +2912,41 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2916 | hide_cursor(vc); | 2912 | hide_cursor(vc); |
2917 | 2913 | ||
2918 | start = (ushort *)vc->vc_pos; | 2914 | start = (ushort *)vc->vc_pos; |
2919 | 2915 | start_x = vc->vc_x; | |
2920 | /* Contrived structure to try to emulate original need_wrap behaviour | 2916 | cnt = 0; |
2921 | * Problems caused when we have need_wrap set on '\n' character */ | ||
2922 | while (count--) { | 2917 | while (count--) { |
2923 | c = *b++; | 2918 | c = *b++; |
2924 | if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) { | 2919 | if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) { |
2925 | if (cnt > 0) { | 2920 | if (cnt && con_is_visible(vc)) |
2926 | if (con_is_visible(vc)) | 2921 | vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x); |
2927 | vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x); | 2922 | cnt = 0; |
2928 | vc->vc_x += cnt; | ||
2929 | if (vc->vc_need_wrap) | ||
2930 | vc->vc_x--; | ||
2931 | cnt = 0; | ||
2932 | } | ||
2933 | if (c == 8) { /* backspace */ | 2923 | if (c == 8) { /* backspace */ |
2934 | bs(vc); | 2924 | bs(vc); |
2935 | start = (ushort *)vc->vc_pos; | 2925 | start = (ushort *)vc->vc_pos; |
2936 | myx = vc->vc_x; | 2926 | start_x = vc->vc_x; |
2937 | continue; | 2927 | continue; |
2938 | } | 2928 | } |
2939 | if (c != 13) | 2929 | if (c != 13) |
2940 | lf(vc); | 2930 | lf(vc); |
2941 | cr(vc); | 2931 | cr(vc); |
2942 | start = (ushort *)vc->vc_pos; | 2932 | start = (ushort *)vc->vc_pos; |
2943 | myx = vc->vc_x; | 2933 | start_x = vc->vc_x; |
2944 | if (c == 10 || c == 13) | 2934 | if (c == 10 || c == 13) |
2945 | continue; | 2935 | continue; |
2946 | } | 2936 | } |
2937 | vc_uniscr_putc(vc, c); | ||
2947 | scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos); | 2938 | scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos); |
2948 | notify_write(vc, c); | 2939 | notify_write(vc, c); |
2949 | cnt++; | 2940 | cnt++; |
2950 | if (myx == vc->vc_cols - 1) { | 2941 | if (vc->vc_x == vc->vc_cols - 1) { |
2951 | vc->vc_need_wrap = 1; | ||
2952 | continue; | ||
2953 | } | ||
2954 | vc->vc_pos += 2; | ||
2955 | myx++; | ||
2956 | } | ||
2957 | if (cnt > 0) { | ||
2958 | if (con_is_visible(vc)) | ||
2959 | vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x); | ||
2960 | vc->vc_x += cnt; | ||
2961 | if (vc->vc_x == vc->vc_cols) { | ||
2962 | vc->vc_x--; | ||
2963 | vc->vc_need_wrap = 1; | 2942 | vc->vc_need_wrap = 1; |
2943 | } else { | ||
2944 | vc->vc_pos += 2; | ||
2945 | vc->vc_x++; | ||
2964 | } | 2946 | } |
2965 | } | 2947 | } |
2948 | if (cnt && con_is_visible(vc)) | ||
2949 | vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x); | ||
2966 | set_cursor(vc); | 2950 | set_cursor(vc); |
2967 | notify_update(vc); | 2951 | notify_update(vc); |
2968 | 2952 | ||
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 09731b2f6815..c6b3bdbbdbc9 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c | |||
@@ -271,6 +271,7 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count) | |||
271 | 271 | ||
272 | static void vgacon_restore_screen(struct vc_data *c) | 272 | static void vgacon_restore_screen(struct vc_data *c) |
273 | { | 273 | { |
274 | c->vc_origin = c->vc_visible_origin; | ||
274 | vgacon_scrollback_cur->save = 0; | 275 | vgacon_scrollback_cur->save = 0; |
275 | 276 | ||
276 | if (!vga_is_gfx && !vgacon_scrollback_cur->restore) { | 277 | if (!vga_is_gfx && !vgacon_scrollback_cur->restore) { |
@@ -287,8 +288,7 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) | |||
287 | int start, end, count, soff; | 288 | int start, end, count, soff; |
288 | 289 | ||
289 | if (!lines) { | 290 | if (!lines) { |
290 | c->vc_visible_origin = c->vc_origin; | 291 | vgacon_restore_screen(c); |
291 | vga_set_mem_top(c); | ||
292 | return; | 292 | return; |
293 | } | 293 | } |
294 | 294 | ||
@@ -298,6 +298,7 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) | |||
298 | if (!vgacon_scrollback_cur->save) { | 298 | if (!vgacon_scrollback_cur->save) { |
299 | vgacon_cursor(c, CM_ERASE); | 299 | vgacon_cursor(c, CM_ERASE); |
300 | vgacon_save_screen(c); | 300 | vgacon_save_screen(c); |
301 | c->vc_origin = (unsigned long)c->vc_screenbuf; | ||
301 | vgacon_scrollback_cur->save = 1; | 302 | vgacon_scrollback_cur->save = 1; |
302 | } | 303 | } |
303 | 304 | ||
@@ -335,7 +336,7 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) | |||
335 | int copysize; | 336 | int copysize; |
336 | 337 | ||
337 | int diff = c->vc_rows - count; | 338 | int diff = c->vc_rows - count; |
338 | void *d = (void *) c->vc_origin; | 339 | void *d = (void *) c->vc_visible_origin; |
339 | void *s = (void *) c->vc_screenbuf; | 340 | void *s = (void *) c->vc_screenbuf; |
340 | 341 | ||
341 | count *= c->vc_size_row; | 342 | count *= c->vc_size_row; |