History

Merge tag 'tty-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

Pull tty/serial updates from Greg KH: "Here is the large set of TTY and Serial driver patches for 5.9-rc1. Lots of bugfixes in here, thanks to syzbot fuzzing for serial and vt and console code. Other highlights include: - much needed vt/vc code cleanup from Jiri Slaby - 8250 driver fixes and additions - various serial driver updates and feature enhancements - locking cleanup for serial/console initializations - other minor cleanups All of these have been in linux-next with no reported issues" * tag 'tty-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (90 commits) MAINTAINERS: enlist Greg formally for console stuff vgacon: Fix for missing check in scrollback handling Revert "serial: 8250: Let serial core initialise spin lock" serial: 8250: Let serial core initialise spin lock tty: keyboard, do not speculate on func_table index serial: stm32: Add RS485 RTS GPIO control serial: 8250_dw: Fix common clocks usage race condition serial: 8250_dw: Pass the same rate to the clk round and set rate methods serial: 8250_dw: Simplify the ref clock rate setting procedure serial: 8250: Add 8250 port clock update method tty: serial: imx: add imx earlycon driver tty: serial: imx: enable imx serial console port as module tty/synclink: remove leftover bits of non-PCI card support tty: Use the preferred form for passing the size of a structure type tty: Fix identation issues in struct serial_struct32 tty: Avoid the use of one-element arrays serial: msm_serial: add sparse context annotation serial: pmac_zilog: add sparse context annotation newport_con: vc_color is now in state serial: imx: use hrtimers for rs485 delays ...

Linus Torvalds committed 6 years ago

Commit d6efb3a2 parents c0c419c f6c6eb263 files · +1847 −1613Browse files

Unified · Split

63 files
  1. Documentation/devicetree/bindings/serial/st,stm32-uart.yaml +3 −1
  2. Documentation/driver-api/serial/n_gsm.rst +1 −1
  3. MAINTAINERS +6 −0
  4. arch/um/drivers/line.c +0 −5
  5. arch/um/drivers/line.h +0 −1
  6. arch/um/drivers/ssl.c +0 −1
  7. arch/um/drivers/stdio_console.c +0 −1
  8. drivers/accessibility/braille/braille_console.c +5 −5
  9. drivers/accessibility/speakup/main.c +14 −14
  10. drivers/tty/moxa.h +1 −1
  11. drivers/tty/serial/8250/8250_dw.c +106 −14
  12. drivers/tty/serial/8250/8250_em.c +10 −6
  13. drivers/tty/serial/8250/8250_ingenic.c +10 −6
  14. drivers/tty/serial/8250/8250_men_mcb.c +2 −2
  15. drivers/tty/serial/8250/8250_mtk.c +10 −6
  16. drivers/tty/serial/8250/8250_omap.c +10 −6
  17. drivers/tty/serial/8250/8250_port.c +41 −0
  18. drivers/tty/serial/8250/8250_pxa.c +8 −6
  19. drivers/tty/serial/8250/Kconfig +2 −2
  20. drivers/tty/serial/Kconfig +12 −5
  21. drivers/tty/serial/altera_jtaguart.c +1 −1
  22. drivers/tty/serial/amba-pl011.c +0 −1
  23. drivers/tty/serial/fsl_lpuart.c +3 −0
  24. drivers/tty/serial/imx.c +133 −74
  25. drivers/tty/serial/imx_earlycon.c +50 −0
  26. drivers/tty/serial/jsm/jsm_driver.c +1 −1
  27. drivers/tty/serial/kgdboc.c +2 −1
  28. drivers/tty/serial/msm_serial.c +2 −0
  29. drivers/tty/serial/pch_uart.c +10 −24
  30. drivers/tty/serial/pmac_zilog.c +1 −0
  31. drivers/tty/serial/qcom_geni_serial.c +1 −1
  32. drivers/tty/serial/samsung_tty.c +10 −14
  33. drivers/tty/serial/serial-tegra.c +3 −3
  34. drivers/tty/serial/serial_core.c +4 −1
  35. drivers/tty/serial/sh-sci.c +0 −3
  36. drivers/tty/serial/sifive.c +0 −1
  37. drivers/tty/serial/stm32-usart.c +11 −2
  38. drivers/tty/serial/sunhv.c +0 −3
  39. drivers/tty/serial/uartlite.c +1 −1
  40. drivers/tty/synclink.c +109 −241
  41. drivers/tty/tty_io.c +26 −26
  42. drivers/tty/vt/consolemap.c +1 −1
  43. drivers/tty/vt/keyboard.c +2 −1
  44. drivers/tty/vt/selection.c +1 −1
  45. drivers/tty/vt/vt.c +533 −449
  46. drivers/tty/vt/vt_ioctl.c +557 −552
  47. drivers/usb/misc/sisusbvga/sisusb_con.c +6 −5
  48. drivers/video/console/mdacon.c +11 −9
  49. drivers/video/console/newport_con.c +5 −5
  50. drivers/video/console/sticon.c +8 −6
  51. drivers/video/console/vgacon.c +23 −17
  52. drivers/video/fbdev/core/bitblit.c +5 −5
  53. drivers/video/fbdev/core/fbcon.c +5 −5
  54. drivers/video/fbdev/core/fbcon_ccw.c +4 −4
  55. drivers/video/fbdev/core/fbcon_cw.c +4 −4
  56. drivers/video/fbdev/core/fbcon_ud.c +4 −4
  57. drivers/video/fbdev/core/tileblit.c +3 −3
  58. include/linux/console.h +5 −8
  59. include/linux/console_struct.h +58 −35
  60. include/linux/serial_8250.h +2 −0
  61. include/linux/serial_core.h +1 −1
  62. include/linux/vt_kern.h +0 −3
  63. include/uapi/linux/serial_core.h +0 −14
Documentation/devicetree/bindings/serial/st,stm32-uart.yaml+3−1
@@ -35,9 +35,11 @@ properties: · 34 unmodified lines
3535 description: label associated with this uart
3636
3737 st,hw-flow-ctrl:
38− description: enable hardware flow control
38+ description: enable hardware flow control (deprecated)
3939 $ref: /schemas/types.yaml#/definitions/flag
4040
41+ uart-has-rtscts: true
42+
4143 dmas:
4244 minItems: 1
4345 maxItems: 2
Documentation/driver-api/serial/n_gsm.rst+1−1
@@ -5,7 +5,7 @@ GSM 0710 tty multiplexor HOWTO · 4 unmodified lines
55 This line discipline implements the GSM 07.10 multiplexing protocol
66 detailed in the following 3GPP document:
77
8− http://www.3gpp.org/ftp/Specs/archive/07_series/07.10/0710-720.zip
8+ https://www.3gpp.org/ftp/Specs/archive/07_series/07.10/0710-720.zip
99
1010 This document give some hints on how to use this driver with GPRS and 3G
1111 modems connected to a physical serial port.
MAINTAINERS+6−0
@@ -4386,6 +4386,12 @@ L: netdev@vger.kernel.org · 4385 unmodified lines
43864386 S: Maintained
43874387 F: drivers/connector/
43884388
4389+CONSOLE SUBSYSTEM
4390+M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
4391+S: Supported
4392+F: drivers/video/console/
4393+F: include/linux/console*
4394+
43894395 CONTROL GROUP (CGROUP)
43904396 M: Tejun Heo <tj@kernel.org>
43914397 M: Li Zefan <lizefan@huawei.com>
arch/um/drivers/line.c+0−5
@@ -184,11 +184,6 @@ void line_flush_chars(struct tty_struct *tty) · 183 unmodified lines
184184 line_flush_buffer(tty);
185185 }
186186
187−int line_put_char(struct tty_struct *tty, unsigned char ch)
188−{
189− return line_write(tty, &ch, sizeof(ch));
190−}
191−
192187 int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
193188 {
194189 struct line *line = tty->driver_data;
arch/um/drivers/line.h+0−1
@@ -66,7 +66,6 @@ extern int line_setup(char **conf, unsigned nlines, char **def, · 65 unmodified lines
6666 char *init, char *name);
6767 extern int line_write(struct tty_struct *tty, const unsigned char *buf,
6868 int len);
69−extern int line_put_char(struct tty_struct *tty, unsigned char ch);
7069 extern void line_set_termios(struct tty_struct *tty, struct ktermios * old);
7170 extern int line_chars_in_buffer(struct tty_struct *tty);
7271 extern void line_flush_buffer(struct tty_struct *tty);
arch/um/drivers/ssl.c+0−1
@@ -95,7 +95,6 @@ static const struct tty_operations ssl_ops = { · 94 unmodified lines
9595 .open = line_open,
9696 .close = line_close,
9797 .write = line_write,
98− .put_char = line_put_char,
9998 .write_room = line_write_room,
10099 .chars_in_buffer = line_chars_in_buffer,
101100 .flush_buffer = line_flush_buffer,
arch/um/drivers/stdio_console.c+0−1
@@ -102,7 +102,6 @@ static const struct tty_operations console_ops = { · 101 unmodified lines
102102 .install = con_install,
103103 .close = line_close,
104104 .write = line_write,
105− .put_char = line_put_char,
106105 .write_room = line_write_room,
107106 .chars_in_buffer = line_chars_in_buffer,
108107 .flush_buffer = line_flush_buffer,
drivers/accessibility/braille/braille_console.c+5−5
@@ -109,16 +109,16 @@ static void braille_write(u16 *buf) · 108 unmodified lines
109109 /* Follow the VC cursor*/
110110 static void vc_follow_cursor(struct vc_data *vc)
111111 {
112− vc_x = vc->vc_x - (vc->vc_x % WIDTH);
113− vc_y = vc->vc_y;
114− lastvc_x = vc->vc_x;
115− lastvc_y = vc->vc_y;
112+ vc_x = vc->state.x - (vc->state.x % WIDTH);
113+ vc_y = vc->state.y;
114+ lastvc_x = vc->state.x;
115+ lastvc_y = vc->state.y;
116116 }
117117
118118 /* Maybe the VC cursor moved, if so follow it */
119119 static void vc_maybe_cursor_moved(struct vc_data *vc)
120120 {
121− if (vc->vc_x != lastvc_x || vc->vc_y != lastvc_y)
121+ if (vc->state.x != lastvc_x || vc->state.y != lastvc_y)
122122 vc_follow_cursor(vc);
123123 }
124124
drivers/accessibility/speakup/main.c+14−14
@@ -263,8 +263,8 @@ static unsigned char get_attributes(struct vc_data *vc, u16 *pos) · 262 unmodified lines
263263
264264 static void speakup_date(struct vc_data *vc)
265265 {
266− spk_x = spk_cx = vc->vc_x;
267− spk_y = spk_cy = vc->vc_y;
266+ spk_x = spk_cx = vc->state.x;
267+ spk_y = spk_cy = vc->state.y;
268268 spk_pos = spk_cp = vc->vc_pos;
269269 spk_old_attr = spk_attr;
270270 spk_attr = get_attributes(vc, (u_short *)spk_pos);
@@ -1551,9 +1551,9 @@ static void do_handle_cursor(struct vc_data *vc, u_char value, char up_flag) · 1280 unmodified lines
15511551 */
15521552 is_cursor = value + 1;
15531553 old_cursor_pos = vc->vc_pos;
1554− old_cursor_x = vc->vc_x;
1555− old_cursor_y = vc->vc_y;
1556− speakup_console[vc->vc_num]->ht.cy = vc->vc_y;
1554+ old_cursor_x = vc->state.x;
1555+ old_cursor_y = vc->state.y;
1556+ speakup_console[vc->vc_num]->ht.cy = vc->state.y;
15571557 cursor_con = vc->vc_num;
15581558 if (cursor_track == CT_Highlight)
15591559 reset_highlight_buffers(vc);
@@ -1574,8 +1574,8 @@ static void update_color_buffer(struct vc_data *vc, const u16 *ic, int len) · 14 unmodified lines
15741574 i = 0;
15751575 if (speakup_console[vc_num]->ht.highsize[bi] == 0) {
15761576 speakup_console[vc_num]->ht.rpos[bi] = vc->vc_pos;
1577− speakup_console[vc_num]->ht.rx[bi] = vc->vc_x;
1578− speakup_console[vc_num]->ht.ry[bi] = vc->vc_y;
1577+ speakup_console[vc_num]->ht.rx[bi] = vc->state.x;
1578+ speakup_console[vc_num]->ht.ry[bi] = vc->state.y;
15791579 }
15801580 while ((hi < COLOR_BUFFER_SIZE) && (i < len)) {
15811581 if (ic[i] > 32) {
@@ -1664,9 +1664,9 @@ static int speak_highlight(struct vc_data *vc) · 82 unmodified lines
16641664 return 0;
16651665 hc = get_highlight_color(vc);
16661666 if (hc != -1) {
1667− d = vc->vc_y - speakup_console[vc_num]->ht.cy;
1667+ d = vc->state.y - speakup_console[vc_num]->ht.cy;
16681668 if ((d == 1) || (d == -1))
1669− if (speakup_console[vc_num]->ht.ry[hc] != vc->vc_y)
1669+ if (speakup_console[vc_num]->ht.ry[hc] != vc->state.y)
16701670 return 0;
16711671 spk_parked |= 0x01;
16721672 spk_do_flush();
@@ -1693,8 +1693,8 @@ static void cursor_done(struct timer_list *unused) · 20 unmodified lines
16931693 }
16941694 speakup_date(vc);
16951695 if (win_enabled) {
1696− if (vc->vc_x >= win_left && vc->vc_x <= win_right &&
1697− vc->vc_y >= win_top && vc->vc_y <= win_bottom) {
1696+ if (vc->state.x >= win_left && vc->state.x <= win_right &&
1697+ vc->state.y >= win_top && vc->state.y <= win_bottom) {
16981698 spk_keydown = 0;
16991699 is_cursor = 0;
17001700 goto out;
@@ -1757,7 +1757,7 @@ static void speakup_con_write(struct vc_data *vc, u16 *str, int len) · 56 unmodified lines
17571757 if (!spin_trylock_irqsave(&speakup_info.spinlock, flags))
17581758 /* Speakup output, discard */
17591759 return;
1760− if (spk_bell_pos && spk_keydown && (vc->vc_x == spk_bell_pos - 1))
1760+ if (spk_bell_pos && spk_keydown && (vc->state.x == spk_bell_pos - 1))
17611761 bleep(3);
17621762 if ((is_cursor) || (cursor_track == read_all_mode)) {
17631763 if (cursor_track == CT_Highlight)
@@ -1766,8 +1766,8 @@ static void speakup_con_write(struct vc_data *vc, u16 *str, int len) · 2 unmodified lines
17661766 return;
17671767 }
17681768 if (win_enabled) {
1769− if (vc->vc_x >= win_left && vc->vc_x <= win_right &&
1770− vc->vc_y >= win_top && vc->vc_y <= win_bottom) {
1769+ if (vc->state.x >= win_left && vc->state.x <= win_right &&
1770+ vc->state.y >= win_top && vc->state.y <= win_bottom) {
17711771 spin_unlock_irqrestore(&speakup_info.spinlock, flags);
17721772 return;
17731773 }
drivers/tty/moxa.h+1−1
@@ -138,7 +138,7 @@ · 137 unmodified lines
138138 #define IntrQuit 0x40 /* received QUIT code */
139139 #define IntrEOF 0x80 /* received EOF code */
140140
141−#define IntrRxTrigger 0x100 /* rx data count reach tigger value */
141+#define IntrRxTrigger 0x100 /* rx data count reach trigger value */
142142 #define IntrTxTrigger 0x200 /* tx data count below trigger value */
143143
144144 #define Magic_no (Config_base + 0)
drivers/tty/serial/8250/8250_dw.c+106−14
@@ -19,6 +19,8 @@ · 18 unmodified lines
1919 #include <linux/of_irq.h>
2020 #include <linux/of_platform.h>
2121 #include <linux/platform_device.h>
22+#include <linux/workqueue.h>
23+#include <linux/notifier.h>
2224 #include <linux/slab.h>
2325 #include <linux/acpi.h>
2426 #include <linux/clk.h>
@@ -43,6 +45,8 @@ struct dw8250_data { · 18 unmodified lines
4345 int msr_mask_off;
4446 struct clk *clk;
4547 struct clk *pclk;
48+ struct notifier_block clk_notifier;
49+ struct work_struct clk_work;
4650 struct reset_control *rst;
4751
4852 unsigned int skip_autocfg:1;
@@ -54,6 +58,16 @@ static inline struct dw8250_data *to_dw8250_data(struct dw8250_port_data *data) · 5 unmodified lines
5458 return container_of(data, struct dw8250_data, data);
5559 }
5660
61+static inline struct dw8250_data *clk_to_dw8250_data(struct notifier_block *nb)
62+{
63+ return container_of(nb, struct dw8250_data, clk_notifier);
64+}
65+
66+static inline struct dw8250_data *work_to_dw8250_data(struct work_struct *work)
67+{
68+ return container_of(work, struct dw8250_data, clk_work);
69+}
70+
5771 static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
5872 {
5973 struct dw8250_data *d = to_dw8250_data(p->private_data);
@@ -260,6 +274,46 @@ static int dw8250_handle_irq(struct uart_port *p) · 200 unmodified lines
260274 return 0;
261275 }
262276
277+static void dw8250_clk_work_cb(struct work_struct *work)
278+{
279+ struct dw8250_data *d = work_to_dw8250_data(work);
280+ struct uart_8250_port *up;
281+ unsigned long rate;
282+
283+ rate = clk_get_rate(d->clk);
284+ if (rate <= 0)
285+ return;
286+
287+ up = serial8250_get_port(d->data.line);
288+
289+ serial8250_update_uartclk(&up->port, rate);
290+}
291+
292+static int dw8250_clk_notifier_cb(struct notifier_block *nb,
293+ unsigned long event, void *data)
294+{
295+ struct dw8250_data *d = clk_to_dw8250_data(nb);
296+
297+ /*
298+ * We have no choice but to defer the uartclk update due to two
299+ * deadlocks. First one is caused by a recursive mutex lock which
300+ * happens when clk_set_rate() is called from dw8250_set_termios().
301+ * Second deadlock is more tricky and is caused by an inverted order of
302+ * the clk and tty-port mutexes lock. It happens if clock rate change
303+ * is requested asynchronously while set_termios() is executed between
304+ * tty-port mutex lock and clk_set_rate() function invocation and
305+ * vise-versa. Anyway if we didn't have the reference clock alteration
306+ * in the dw8250_set_termios() method we wouldn't have needed this
307+ * deferred event handling complication.
308+ */
309+ if (event == POST_RATE_CHANGE) {
310+ queue_work(system_unbound_wq, &d->clk_work);
311+ return NOTIFY_OK;
312+ }
313+
314+ return NOTIFY_DONE;
315+}
316+
263317 static void
264318 dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
265319 {
@@ -275,27 +329,27 @@ dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) · 9 unmodified lines
275329 static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
276330 struct ktermios *old)
277331 {
278− unsigned int baud = tty_termios_baud_rate(termios);
332+ unsigned long newrate = tty_termios_baud_rate(termios) * 16;
279333 struct dw8250_data *d = to_dw8250_data(p->private_data);
280334 long rate;
281335 int ret;
282336
283337 clk_disable_unprepare(d->clk);
284− rate = clk_round_rate(d->clk, baud * 16);
285− if (rate < 0)
286− ret = rate;
287− else if (rate == 0)
288− ret = -ENOENT;
289− else
290− ret = clk_set_rate(d->clk, rate);
338+ rate = clk_round_rate(d->clk, newrate);
339+ if (rate > 0) {
340+ /*
341+ * Premilinary set the uartclk to the new clock rate so the
342+ * clock update event handler caused by the clk_set_rate()
343+ * calling wouldn't actually update the UART divisor since
344+ * we about to do this anyway.
345+ */
346+ swap(p->uartclk, rate);
347+ ret = clk_set_rate(d->clk, newrate);
348+ if (ret)
349+ swap(p->uartclk, rate);
350+ }
291351 clk_prepare_enable(d->clk);
292352
293− if (ret)
294− goto out;
295−
296− p->uartclk = rate;
297−
298−out:
299353 p->status &= ~UPSTAT_AUTOCTS;
300354 if (termios->c_cflag & CRTSCTS)
301355 p->status |= UPSTAT_AUTOCTS;
@@ -319,6 +373,39 @@ static void dw8250_set_ldisc(struct uart_port *p, struct ktermios *termios) · 17 unmodified lines
319373 serial8250_do_set_ldisc(p, termios);
320374 }
321375
376+static int dw8250_startup(struct uart_port *p)
377+{
378+ struct dw8250_data *d = to_dw8250_data(p->private_data);
379+ int ret;
380+
381+ /*
382+ * Some platforms may provide a reference clock shared between several
383+ * devices. In this case before using the serial port first we have to
384+ * make sure that any clock state change is known to the UART port at
385+ * least post factum.
386+ */
387+ if (d->clk) {
388+ ret = clk_notifier_register(d->clk, &d->clk_notifier);
389+ if (ret)
390+ dev_warn(p->dev, "Failed to set the clock notifier\n");
391+ }
392+
393+ return serial8250_do_startup(p);
394+}
395+
396+static void dw8250_shutdown(struct uart_port *p)
397+{
398+ struct dw8250_data *d = to_dw8250_data(p->private_data);
399+
400+ serial8250_do_shutdown(p);
401+
402+ if (d->clk) {
403+ clk_notifier_unregister(d->clk, &d->clk_notifier);
404+
405+ flush_work(&d->clk_work);
406+ }
407+}
408+
322409 /*
323410 * dw8250_fallback_dma_filter will prevent the UART from getting just any free
324411 * channel on platforms that have DMA engines, but don't have any channels
@@ -414,6 +501,8 @@ static int dw8250_probe(struct platform_device *pdev) · 89 unmodified lines
414501 p->serial_out = dw8250_serial_out;
415502 p->set_ldisc = dw8250_set_ldisc;
416503 p->set_termios = dw8250_set_termios;
504+ p->startup = dw8250_startup;
505+ p->shutdown = dw8250_shutdown;
417506
418507 p->membase = devm_ioremap(dev, regs->start, resource_size(regs));
419508 if (!p->membase)
@@ -475,6 +564,9 @@ static int dw8250_probe(struct platform_device *pdev) · 55 unmodified lines
475564 if (IS_ERR(data->clk))
476565 return PTR_ERR(data->clk);
477566
567+ INIT_WORK(&data->clk_work, dw8250_clk_work_cb);
568+ data->clk_notifier.notifier_call = dw8250_clk_notifier_cb;
569+
478570 err = clk_prepare_enable(data->clk);
479571 if (err)
480572 dev_warn(dev, "could not enable optional baudclk: %d\n", err);
drivers/tty/serial/8250/8250_em.c+10−6
@@ -78,14 +78,18 @@ static void serial8250_em_serial_dl_write(struct uart_8250_port *up, int value) · 77 unmodified lines
7878
7979 static int serial8250_em_probe(struct platform_device *pdev)
8080 {
81− struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
82− struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
8381 struct serial8250_em_priv *priv;
8482 struct uart_8250_port up;
85− int ret;
83+ struct resource *regs;
84+ int irq, ret;
8685
87− if (!regs || !irq) {
88− dev_err(&pdev->dev, "missing registers or irq\n");
86+ irq = platform_get_irq(pdev, 0);
87+ if (irq < 0)
88+ return irq;
89+
90+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
91+ if (!regs) {
92+ dev_err(&pdev->dev, "missing registers\n");
8993 return -EINVAL;
9094 }
9195
@@ -101,7 +105,7 @@ static int serial8250_em_probe(struct platform_device *pdev) · 9 unmodified lines
101105
102106 memset(&up, 0, sizeof(up));
103107 up.port.mapbase = regs->start;
104− up.port.irq = irq->start;
108+ up.port.irq = irq;
105109 up.port.type = PORT_UNKNOWN;
106110 up.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_IOREMAP;
107111 up.port.dev = &pdev->dev;
drivers/tty/serial/8250/8250_ingenic.c+10−6
@@ -207,12 +207,11 @@ static unsigned int ingenic_uart_serial_in(struct uart_port *p, int offset) · 206 unmodified lines
207207 static int ingenic_uart_probe(struct platform_device *pdev)
208208 {
209209 struct uart_8250_port uart = {};
210− struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
211− struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
212210 struct ingenic_uart_data *data;
213211 const struct ingenic_uart_config *cdata;
214212 const struct of_device_id *match;
215− int err, line;
213+ struct resource *regs;
214+ int irq, err, line;
216215
217216 match = of_match_device(of_match, &pdev->dev);
218217 if (!match) {
@@ -221,8 +220,13 @@ static int ingenic_uart_probe(struct platform_device *pdev) · 2 unmodified lines
221220 }
222221 cdata = match->data;
223222
224− if (!regs || !irq) {
225− dev_err(&pdev->dev, "no registers/irq defined\n");
223+ irq = platform_get_irq(pdev, 0);
224+ if (irq < 0)
225+ return irq;
226+
227+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
228+ if (!regs) {
229+ dev_err(&pdev->dev, "no registers defined\n");
226230 return -EINVAL;
227231 }
228232
@@ -238,7 +242,7 @@ static int ingenic_uart_probe(struct platform_device *pdev) · 9 unmodified lines
238242 uart.port.regshift = 2;
239243 uart.port.serial_out = ingenic_uart_serial_out;
240244 uart.port.serial_in = ingenic_uart_serial_in;
241− uart.port.irq = irq->start;
245+ uart.port.irq = irq;
242246 uart.port.dev = &pdev->dev;
243247 uart.port.fifosize = cdata->fifosize;
244248 uart.tx_loadsz = cdata->tx_loadsz;
drivers/tty/serial/8250/8250_men_mcb.c+2−2
@@ -51,7 +51,7 @@ static u32 men_lookup_uartclk(struct mcb_device *mdev) · 50 unmodified lines
5151 return clkval;
5252 }
5353
54−static unsigned int get_num_ports(struct mcb_device *mdev,
54+static int get_num_ports(struct mcb_device *mdev,
5555 void __iomem *membase)
5656 {
5757 switch (mdev->id) {
@@ -140,7 +140,7 @@ static void serial_8250_men_mcb_remove(struct mcb_device *mdev) · 82 unmodified lines
140140 return;
141141
142142 num_ports = get_num_ports(mdev, data[0].uart.port.membase);
143− if (num_ports < 0 || num_ports > 4) {
143+ if (num_ports <= 0 || num_ports > 4) {
144144 dev_err(&mdev->dev, "error retrieving number of ports!\n");
145145 return;
146146 }
drivers/tty/serial/8250/8250_mtk.c+10−6
@@ -512,13 +512,17 @@ static int mtk8250_probe_of(struct platform_device *pdev, struct uart_port *p, · 511 unmodified lines
512512 static int mtk8250_probe(struct platform_device *pdev)
513513 {
514514 struct uart_8250_port uart = {};
515− struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
516− struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
517515 struct mtk8250_data *data;
518− int err;
516+ struct resource *regs;
517+ int irq, err;
518+
519+ irq = platform_get_irq(pdev, 0);
520+ if (irq < 0)
521+ return irq;
519522
520− if (!regs || !irq) {
521− dev_err(&pdev->dev, "no registers/irq defined\n");
523+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
524+ if (!regs) {
525+ dev_err(&pdev->dev, "no registers defined\n");
522526 return -EINVAL;
523527 }
524528
@@ -542,7 +546,7 @@ static int mtk8250_probe(struct platform_device *pdev) · 17 unmodified lines
542546
543547 spin_lock_init(&uart.port.lock);
544548 uart.port.mapbase = regs->start;
545− uart.port.irq = irq->start;
549+ uart.port.irq = irq;
546550 uart.port.pm = mtk8250_do_pm;
547551 uart.port.type = PORT_16550;
548552 uart.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;
drivers/tty/serial/8250/8250_omap.c+10−6
@@ -1209,17 +1209,21 @@ MODULE_DEVICE_TABLE(of, omap8250_dt_ids); · 1208 unmodified lines
12091209
12101210 static int omap8250_probe(struct platform_device *pdev)
12111211 {
1212− struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1213− struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
12141212 struct device_node *np = pdev->dev.of_node;
12151213 struct omap8250_priv *priv;
12161214 const struct omap8250_platdata *pdata;
12171215 struct uart_8250_port up;
1218− int ret;
1216+ struct resource *regs;
12191217 void __iomem *membase;
1218+ int irq, ret;
1219+
1220+ irq = platform_get_irq(pdev, 0);
1221+ if (irq < 0)
1222+ return irq;
12201223
1221− if (!regs || !irq) {
1222− dev_err(&pdev->dev, "missing registers or irq\n");
1224+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1225+ if (!regs) {
1226+ dev_err(&pdev->dev, "missing registers\n");
12231227 return -EINVAL;
12241228 }
12251229
@@ -1236,7 +1240,7 @@ static int omap8250_probe(struct platform_device *pdev) · 10 unmodified lines
12361240 up.port.dev = &pdev->dev;
12371241 up.port.mapbase = regs->start;
12381242 up.port.membase = membase;
1239− up.port.irq = irq->start;
1243+ up.port.irq = irq;
12401244 /*
12411245 * It claims to be 16C750 compatible however it is a little different.
12421246 * It has EFR and has no FCR7_64byte bit. The AFE (which it claims to
drivers/tty/serial/8250/8250_port.c+41−0
@@ -16,6 +16,7 @@ · 15 unmodified lines
1616 #include <linux/ioport.h>
1717 #include <linux/init.h>
1818 #include <linux/console.h>
19+#include <linux/gpio/consumer.h>
1920 #include <linux/sysrq.h>
2021 #include <linux/delay.h>
2122 #include <linux/platform_device.h>
@@ -2631,6 +2632,46 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port, · 2609 unmodified lines
26312632 (port->uartclk + tolerance) / 16);
26322633 }
26332634
2635+/*
2636+ * Note in order to avoid the tty port mutex deadlock don't use the next method
2637+ * within the uart port callbacks. Primarily it's supposed to be utilized to
2638+ * handle a sudden reference clock rate change.
2639+ */
2640+void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk)
2641+{
2642+ struct uart_8250_port *up = up_to_u8250p(port);
2643+ unsigned int baud, quot, frac = 0;
2644+ struct ktermios *termios;
2645+ unsigned long flags;
2646+
2647+ mutex_lock(&port->state->port.mutex);
2648+
2649+ if (port->uartclk == uartclk)
2650+ goto out_lock;
2651+
2652+ port->uartclk = uartclk;
2653+ termios = &port->state->port.tty->termios;
2654+
2655+ baud = serial8250_get_baud_rate(port, termios, NULL);
2656+ quot = serial8250_get_divisor(port, baud, &frac);
2657+
2658+ serial8250_rpm_get(up);
2659+ spin_lock_irqsave(&port->lock, flags);
2660+
2661+ uart_update_timeout(port, termios->c_cflag, baud);
2662+
2663+ serial8250_set_divisor(port, baud, quot, frac);
2664+ serial_port_out(port, UART_LCR, up->lcr);
2665+ serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS);
2666+
2667+ spin_unlock_irqrestore(&port->lock, flags);
2668+ serial8250_rpm_put(up);
2669+
2670+out_lock:
2671+ mutex_unlock(&port->state->port.mutex);
2672+}
2673+EXPORT_SYMBOL_GPL(serial8250_update_uartclk);
2674+
26342675 void
26352676 serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
26362677 struct ktermios *old)
drivers/tty/serial/8250/8250_pxa.c+8−6
@@ -18,7 +18,6 @@ · 17 unmodified lines
1818 #include <linux/serial_core.h>
1919 #include <linux/serial_reg.h>
2020 #include <linux/of.h>
21−#include <linux/of_irq.h>
2221 #include <linux/of_platform.h>
2322 #include <linux/platform_device.h>
2423 #include <linux/slab.h>
@@ -93,12 +92,15 @@ static int serial_pxa_probe(struct platform_device *pdev) · 68 unmodified lines
9392 {
9493 struct uart_8250_port uart = {};
9594 struct pxa8250_data *data;
96− struct resource *mmres, *irqres;
97− int ret;
95+ struct resource *mmres;
96+ int irq, ret;
97+
98+ irq = platform_get_irq(pdev, 0);
99+ if (irq < 0)
100+ return irq;
98101
99102 mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
100− irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
101− if (!mmres || !irqres)
103+ if (!mmres)
102104 return -ENODEV;
103105
104106 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
@@ -121,7 +123,7 @@ static int serial_pxa_probe(struct platform_device *pdev) · 16 unmodified lines
121123 uart.port.iotype = UPIO_MEM32;
122124 uart.port.mapbase = mmres->start;
123125 uart.port.regshift = 2;
124− uart.port.irq = irqres->start;
126+ uart.port.irq = irq;
125127 uart.port.fifosize = 64;
126128 uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST | UPF_FIXED_TYPE;
127129 uart.port.dev = &pdev->dev;
drivers/tty/serial/8250/Kconfig+2−2
@@ -222,7 +222,7 @@ config SERIAL_8250_MANY_PORTS · 221 unmodified lines
222222 Say Y here if you have dumb serial boards other than the four
223223 standard COM 1/2/3/4 ports. This may happen if you have an AST
224224 FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available
225− from <http://www.tldp.org/docs.html#howto>), or other custom
225+ from <https://www.tldp.org/docs.html#howto>), or other custom
226226 serial port hardware which acts similar to standard serial port
227227 hardware. If you only use the standard COM 1/2/3/4 ports, you can
228228 say N here to save some memory. You can also say Y if you have an
@@ -266,7 +266,7 @@ config SERIAL_8250_BOCA · 37 unmodified lines
266266 depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
267267 help
268268 Say Y here if you have a Boca serial board. Please read the Boca
269− mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>
269+ mini-HOWTO, available from <https://www.tldp.org/docs.html#howto>
270270
271271 To compile this driver as a module, choose M here: the module
272272 will be called 8250_boca.
drivers/tty/serial/Kconfig+12−5
@@ -502,20 +502,27 @@ config SERIAL_IMX · 501 unmodified lines
502502 can enable its onboard serial port by enabling this option.
503503
504504 config SERIAL_IMX_CONSOLE
505− bool "Console on IMX serial port"
506− depends on SERIAL_IMX=y
505+ tristate "Console on IMX serial port"
506+ depends on SERIAL_IMX
507507 select SERIAL_CORE_CONSOLE
508− select SERIAL_EARLYCON if OF
509508 help
510509 If you have enabled the serial port on the Freescale IMX
511− CPU you can make it the console by answering Y to this option.
510+ CPU you can make it the console by answering Y/M to this option.
512511
513− Even if you say Y here, the currently visible virtual console
512+ Even if you say Y/M here, the currently visible virtual console
514513 (/dev/tty0) will still be used as the system console by default, but
515514 you can alter that using a kernel command line option such as
516515 "console=ttymxc0". (Try "man bootparam" or see the documentation of
517516 your bootloader about how to pass options to the kernel at boot time.)
518517
518+config SERIAL_IMX_EARLYCON
519+ bool "Earlycon on IMX serial port"
520+ depends on OF
521+ select SERIAL_EARLYCON
522+ help
523+ If you have enabled the earlycon on the Freescale IMX
524+ CPU you can make it the earlycon by answering Y to this option.
525+
519526 config SERIAL_UARTLITE
520527 tristate "Xilinx uartlite serial port support"
521528 depends on HAS_IOMEM
drivers/tty/serial/altera_jtaguart.c+1−1
@@ -27,7 +27,7 @@ · 26 unmodified lines
2727
2828 /*
2929 * Altera JTAG UART register definitions according to the Altera JTAG UART
30− * datasheet: http://www.altera.com/literature/hb/nios2/n2cpu_nii51009.pdf
30+ * datasheet: https://www.altera.com/literature/hb/nios2/n2cpu_nii51009.pdf
3131 */
3232
3333 #define ALTERA_JTAGUART_SIZE 8
drivers/tty/serial/amba-pl011.c+0−1
@@ -2607,7 +2607,6 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap, · 2606 unmodified lines
26072607 uap->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_AMBA_PL011_CONSOLE);
26082608 uap->port.flags = UPF_BOOT_AUTOCONF;
26092609 uap->port.line = index;
2610− spin_lock_init(&uap->port.lock);
26112610
26122611 amba_ports[index] = uap;
26132612
drivers/tty/serial/fsl_lpuart.c+3−0
@@ -1925,6 +1925,9 @@ static void __lpuart32_serial_setbrg(struct uart_port *port, · 1924 unmodified lines
19251925 tmp_sbr++;
19261926 }
19271927
1928+ if (tmp_sbr > UARTBAUD_SBR_MASK)
1929+ continue;
1930+
19281931 if (tmp_diff <= baud_diff) {
19291932 baud_diff = tmp_diff;
19301933 osr = tmp_osr;
drivers/tty/serial/imx.c+133−74
@@ -20,6 +20,7 @@ · 19 unmodified lines
2020 #include <linux/serial.h>
2121 #include <linux/clk.h>
2222 #include <linux/delay.h>
23+#include <linux/ktime.h>
2324 #include <linux/pinctrl/consumer.h>
2425 #include <linux/rational.h>
2526 #include <linux/slab.h>
@@ -188,6 +189,13 @@ struct imx_uart_data { · 162 unmodified lines
188189 enum imx_uart_type devtype;
189190 };
190191
192+enum imx_tx_state {
193+ OFF,
194+ WAIT_AFTER_RTS,
195+ SEND,
196+ WAIT_AFTER_SEND,
197+};
198+
191199 struct imx_port {
192200 struct uart_port port;
193201 struct timer_list timer;
@@ -224,6 +232,10 @@ struct imx_port { · 30 unmodified lines
224232 unsigned int dma_tx_nents;
225233 unsigned int saved_reg[10];
226234 bool context_saved;
235+
236+ enum imx_tx_state tx_state;
237+ struct hrtimer trigger_start_tx;
238+ struct hrtimer trigger_stop_tx;
227239 };
228240
229241 struct imx_port_ucrs {
@@ -361,7 +373,7 @@ static inline int imx_uart_is_imx6q(struct imx_port *sport) · 131 unmodified lines
361373 /*
362374 * Save and restore functions for UCR1, UCR2 and UCR3 registers
363375 */
364−#if defined(CONFIG_SERIAL_IMX_CONSOLE)
376+#if IS_ENABLED(CONFIG_SERIAL_IMX_CONSOLE)
365377 static void imx_uart_ucrs_save(struct imx_port *sport,
366378 struct imx_port_ucrs *ucr)
367379 {
@@ -400,6 +412,15 @@ static void imx_uart_rts_inactive(struct imx_port *sport, u32 *ucr2) · 32 unmodified lines
400412 mctrl_gpio_set(sport->gpios, sport->port.mctrl);
401413 }
402414
415+static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec)
416+{
417+ long sec = msec / MSEC_PER_SEC;
418+ long nsec = (msec % MSEC_PER_SEC) * 1000000;
419+ ktime_t t = ktime_set(sec, nsec);
420+
421+ hrtimer_start(hrt, t, HRTIMER_MODE_REL);
422+}
423+
403424 /* called with port.lock taken and irqs off */
404425 static void imx_uart_start_rx(struct uart_port *port)
405426 {
@@ -427,7 +448,10 @@ static void imx_uart_start_rx(struct uart_port *port) · 21 unmodified lines
427448 static void imx_uart_stop_tx(struct uart_port *port)
428449 {
429450 struct imx_port *sport = (struct imx_port *)port;
430− u32 ucr1;
451+ u32 ucr1, ucr4, usr2;
452+
453+ if (sport->tx_state == OFF)
454+ return;
431455
432456 /*
433457 * We are maybe in the SMP context, so if the DMA TX thread is running
@@ -439,21 +463,44 @@ static void imx_uart_stop_tx(struct uart_port *port) · 5 unmodified lines
439463 ucr1 = imx_uart_readl(sport, UCR1);
440464 imx_uart_writel(sport, ucr1 & ~UCR1_TRDYEN, UCR1);
441465
442− /* in rs485 mode disable transmitter if shifter is empty */
443− if (port->rs485.flags & SER_RS485_ENABLED &&
444− imx_uart_readl(sport, USR2) & USR2_TXDC) {
445− u32 ucr2 = imx_uart_readl(sport, UCR2), ucr4;
446− if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
447− imx_uart_rts_active(sport, &ucr2);
448− else
449− imx_uart_rts_inactive(sport, &ucr2);
450− imx_uart_writel(sport, ucr2, UCR2);
466+ usr2 = imx_uart_readl(sport, USR2);
467+ if (!(usr2 & USR2_TXDC)) {
468+ /* The shifter is still busy, so retry once TC triggers */
469+ return;
470+ }
451471
452− imx_uart_start_rx(port);
472+ ucr4 = imx_uart_readl(sport, UCR4);
473+ ucr4 &= ~UCR4_TCEN;
474+ imx_uart_writel(sport, ucr4, UCR4);
453475
454− ucr4 = imx_uart_readl(sport, UCR4);
455− ucr4 &= ~UCR4_TCEN;
456− imx_uart_writel(sport, ucr4, UCR4);
476+ /* in rs485 mode disable transmitter */
477+ if (port->rs485.flags & SER_RS485_ENABLED) {
478+ if (sport->tx_state == SEND) {
479+ sport->tx_state = WAIT_AFTER_SEND;
480+ start_hrtimer_ms(&sport->trigger_stop_tx,
481+ port->rs485.delay_rts_after_send);
482+ return;
483+ }
484+
485+ if (sport->tx_state == WAIT_AFTER_RTS ||
486+ sport->tx_state == WAIT_AFTER_SEND) {
487+ u32 ucr2;
488+
489+ hrtimer_try_to_cancel(&sport->trigger_start_tx);
490+
491+ ucr2 = imx_uart_readl(sport, UCR2);
492+ if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
493+ imx_uart_rts_active(sport, &ucr2);
494+ else
495+ imx_uart_rts_inactive(sport, &ucr2);
496+ imx_uart_writel(sport, ucr2, UCR2);
497+
498+ imx_uart_start_rx(port);
499+
500+ sport->tx_state = OFF;
501+ }
502+ } else {
503+ sport->tx_state = OFF;
457504 }
458505 }
459506
@@ -651,28 +698,50 @@ static void imx_uart_start_tx(struct uart_port *port) · 191 unmodified lines
651698 if (!sport->port.x_char && uart_circ_empty(&port->state->xmit))
652699 return;
653700
701+ /*
702+ * We cannot simply do nothing here if sport->tx_state == SEND already
703+ * because UCR1_TXMPTYEN might already have been cleared in
704+ * imx_uart_stop_tx(), but tx_state is still SEND.
705+ */
706+
654707 if (port->rs485.flags & SER_RS485_ENABLED) {
655− u32 ucr2;
708+ if (sport->tx_state == OFF) {
709+ u32 ucr2 = imx_uart_readl(sport, UCR2);
710+ if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
711+ imx_uart_rts_active(sport, &ucr2);
712+ else
713+ imx_uart_rts_inactive(sport, &ucr2);
714+ imx_uart_writel(sport, ucr2, UCR2);
656715
657− ucr2 = imx_uart_readl(sport, UCR2);
658− if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
659− imx_uart_rts_active(sport, &ucr2);
660− else
661− imx_uart_rts_inactive(sport, &ucr2);
662− imx_uart_writel(sport, ucr2, UCR2);
716+ if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
717+ imx_uart_stop_rx(port);
718+
719+ sport->tx_state = WAIT_AFTER_RTS;
720+ start_hrtimer_ms(&sport->trigger_start_tx,
721+ port->rs485.delay_rts_before_send);
722+ return;
723+ }
663724
664− if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
665− imx_uart_stop_rx(port);
725+ if (sport->tx_state == WAIT_AFTER_SEND
726+ || sport->tx_state == WAIT_AFTER_RTS) {
666727
667− /*
668− * Enable transmitter and shifter empty irq only if DMA is off.
669− * In the DMA case this is done in the tx-callback.
670− */
671− if (!sport->dma_is_enabled) {
672− u32 ucr4 = imx_uart_readl(sport, UCR4);
673− ucr4 |= UCR4_TCEN;
674− imx_uart_writel(sport, ucr4, UCR4);
728+ hrtimer_try_to_cancel(&sport->trigger_stop_tx);
729+
730+ /*
731+ * Enable transmitter and shifter empty irq only if DMA
732+ * is off. In the DMA case this is done in the
733+ * tx-callback.
734+ */
735+ if (!sport->dma_is_enabled) {
736+ u32 ucr4 = imx_uart_readl(sport, UCR4);
737+ ucr4 |= UCR4_TCEN;
738+ imx_uart_writel(sport, ucr4, UCR4);
739+ }
740+
741+ sport->tx_state = SEND;
675742 }
743+ } else {
744+ sport->tx_state = SEND;
676745 }
677746
678747 if (!sport->dma_is_enabled) {
@@ -1630,7 +1699,6 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios, · 951 unmodified lines
16301699
16311700 if (termios->c_cflag & CRTSCTS)
16321701 ucr2 &= ~UCR2_IRTS;
1633−
16341702 if (termios->c_cflag & CSTOPB)
16351703 ucr2 |= UCR2_STPB;
16361704 if (termios->c_cflag & PARENB) {
@@ -1857,10 +1925,6 @@ static int imx_uart_rs485_config(struct uart_port *port, · 220 unmodified lines
18571925 struct imx_port *sport = (struct imx_port *)port;
18581926 u32 ucr2;
18591927
1860− /* unimplemented */
1861− rs485conf->delay_rts_before_send = 0;
1862− rs485conf->delay_rts_after_send = 0;
1863−
18641928 /* RTS is required to control the transmitter */
18651929 if (!sport->have_rtscts && !sport->have_rtsgpio)
18661930 rs485conf->flags &= ~SER_RS485_ENABLED;
@@ -1915,7 +1979,7 @@ static const struct uart_ops imx_uart_pops = { · 48 unmodified lines
19151979
19161980 static struct imx_port *imx_uart_ports[UART_NR];
19171981
1918−#ifdef CONFIG_SERIAL_IMX_CONSOLE
1982+#if IS_ENABLED(CONFIG_SERIAL_IMX_CONSOLE)
19191983 static void imx_uart_console_putchar(struct uart_port *port, int ch)
19201984 {
19211985 struct imx_port *sport = (struct imx_port *)port;
@@ -2112,39 +2176,6 @@ static struct console imx_uart_console = { · 190 unmodified lines
21122176
21132177 #define IMX_CONSOLE &imx_uart_console
21142178
2115−#ifdef CONFIG_OF
2116−static void imx_uart_console_early_putchar(struct uart_port *port, int ch)
2117−{
2118− struct imx_port *sport = (struct imx_port *)port;
2119−
2120− while (imx_uart_readl(sport, IMX21_UTS) & UTS_TXFULL)
2121− cpu_relax();
2122−
2123− imx_uart_writel(sport, ch, URTX0);
2124−}
2125−
2126−static void imx_uart_console_early_write(struct console *con, const char *s,
2127− unsigned count)
2128−{
2129− struct earlycon_device *dev = con->data;
2130−
2131− uart_console_write(&dev->port, s, count, imx_uart_console_early_putchar);
2132−}
2133−
2134−static int __init
2135−imx_console_early_setup(struct earlycon_device *dev, const char *opt)
2136−{
2137− if (!dev->port.membase)
2138− return -ENODEV;
2139−
2140− dev->con->write = imx_uart_console_early_write;
2141−
2142− return 0;
2143−}
2144−OF_EARLYCON_DECLARE(ec_imx6q, "fsl,imx6q-uart", imx_console_early_setup);
2145−OF_EARLYCON_DECLARE(ec_imx21, "fsl,imx21-uart", imx_console_early_setup);
2146−#endif
2147−
21482179 #else
21492180 #define IMX_CONSOLE NULL
21502181 #endif
@@ -2223,6 +2254,32 @@ static void imx_uart_probe_pdata(struct imx_port *sport, · 72 unmodified lines
22232254 sport->have_rtscts = 1;
22242255 }
22252256
2257+static enum hrtimer_restart imx_trigger_start_tx(struct hrtimer *t)
2258+{
2259+ struct imx_port *sport = container_of(t, struct imx_port, trigger_start_tx);
2260+ unsigned long flags;
2261+
2262+ spin_lock_irqsave(&sport->port.lock, flags);
2263+ if (sport->tx_state == WAIT_AFTER_RTS)
2264+ imx_uart_start_tx(&sport->port);
2265+ spin_unlock_irqrestore(&sport->port.lock, flags);
2266+
2267+ return HRTIMER_NORESTART;
2268+}
2269+
2270+static enum hrtimer_restart imx_trigger_stop_tx(struct hrtimer *t)
2271+{
2272+ struct imx_port *sport = container_of(t, struct imx_port, trigger_stop_tx);
2273+ unsigned long flags;
2274+
2275+ spin_lock_irqsave(&sport->port.lock, flags);
2276+ if (sport->tx_state == WAIT_AFTER_SEND)
2277+ imx_uart_stop_tx(&sport->port);
2278+ spin_unlock_irqrestore(&sport->port.lock, flags);
2279+
2280+ return HRTIMER_NORESTART;
2281+}
2282+
22262283 static int imx_uart_probe(struct platform_device *pdev)
22272284 {
22282285 struct imx_port *sport;
@@ -2369,6 +2426,11 @@ static int imx_uart_probe(struct platform_device *pdev) · 140 unmodified lines
23692426
23702427 clk_disable_unprepare(sport->clk_ipg);
23712428
2429+ hrtimer_init(&sport->trigger_start_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
2430+ hrtimer_init(&sport->trigger_stop_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
2431+ sport->trigger_start_tx.function = imx_trigger_start_tx;
2432+ sport->trigger_stop_tx.function = imx_trigger_stop_tx;
2433+
23722434 /*
23732435 * Allocate the IRQ(s) i.MX1 has three interrupts whereas later
23742436 * chips only have one interrupt.
@@ -2406,9 +2468,6 @@ static int imx_uart_probe(struct platform_device *pdev) · 31 unmodified lines
24062468 }
24072469 }
24082470
2409− /* We need to initialize lock even for non-registered console */
2410− spin_lock_init(&sport->port.lock);
2411−
24122471 imx_uart_ports[sport->port.line] = sport;
24132472
24142473 platform_set_drvdata(pdev, sport);
drivers/tty/serial/imx_earlycon.c+50−0
@@ -0,0 +1,50 @@
1+// SPDX-License-Identifier: GPL-2.0+
2+/*
3+ * Copyright 2020 NXP
4+ */
5+
6+#include <linux/module.h>
7+#include <linux/ioport.h>
8+#include <linux/init.h>
9+#include <linux/serial_core.h>
10+#include <linux/serial.h>
11+#include <linux/delay.h>
12+#include <linux/of.h>
13+#include <linux/io.h>
14+
15+#define URTX0 0x40 /* Transmitter Register */
16+#define UTS_TXFULL (1<<4) /* TxFIFO full */
17+#define IMX21_UTS 0xb4 /* UART Test Register on all other i.mx*/
18+
19+static void imx_uart_console_early_putchar(struct uart_port *port, int ch)
20+{
21+ while (readl_relaxed(port->membase + IMX21_UTS) & UTS_TXFULL)
22+ cpu_relax();
23+
24+ writel_relaxed(ch, port->membase + URTX0);
25+}
26+
27+static void imx_uart_console_early_write(struct console *con, const char *s,
28+ unsigned count)
29+{
30+ struct earlycon_device *dev = con->data;
31+
32+ uart_console_write(&dev->port, s, count, imx_uart_console_early_putchar);
33+}
34+
35+static int __init
36+imx_console_early_setup(struct earlycon_device *dev, const char *opt)
37+{
38+ if (!dev->port.membase)
39+ return -ENODEV;
40+
41+ dev->con->write = imx_uart_console_early_write;
42+
43+ return 0;
44+}
45+OF_EARLYCON_DECLARE(ec_imx6q, "fsl,imx6q-uart", imx_console_early_setup);
46+OF_EARLYCON_DECLARE(ec_imx21, "fsl,imx21-uart", imx_console_early_setup);
47+
48+MODULE_AUTHOR("NXP");
49+MODULE_DESCRIPTION("IMX earlycon driver");
50+MODULE_LICENSE("GPL");
drivers/tty/serial/jsm/jsm_driver.c+1−1
@@ -16,7 +16,7 @@ · 15 unmodified lines
1616
1717 #include "jsm.h"
1818
19−MODULE_AUTHOR("Digi International, http://www.digi.com");
19+MODULE_AUTHOR("Digi International, https://www.digi.com");
2020 MODULE_DESCRIPTION("Driver for the Digi International Neo and Classic PCI based product line");
2121 MODULE_LICENSE("GPL");
2222 MODULE_SUPPORTED_DEVICE("jsm");
drivers/tty/serial/kgdboc.c+2−1
@@ -538,7 +538,8 @@ static int __init kgdboc_earlycon_init(char *opt) · 537 unmodified lines
538538
539539 if (!con) {
540540 /*
541− * Both earlycon and kgdboc_earlycon are initialized during * early parameter parsing. We cannot guarantee earlycon gets
541+ * Both earlycon and kgdboc_earlycon are initialized during
542+ * early parameter parsing. We cannot guarantee earlycon gets
542543 * in first and, in any case, on ACPI systems earlycon may
543544 * defer its own initialization (usually to somewhere within
544545 * setup_arch() ). To cope with either of these situations
drivers/tty/serial/msm_serial.c+2−0
@@ -696,6 +696,7 @@ static void msm_enable_ms(struct uart_port *port) · 695 unmodified lines
696696 }
697697
698698 static void msm_handle_rx_dm(struct uart_port *port, unsigned int misr)
699+ __must_hold(&port->lock)
699700 {
700701 struct tty_port *tport = &port->state->port;
701702 unsigned int sr;
@@ -771,6 +772,7 @@ static void msm_handle_rx_dm(struct uart_port *port, unsigned int misr) · 69 unmodified lines
771772 }
772773
773774 static void msm_handle_rx(struct uart_port *port)
775+ __must_hold(&port->lock)
774776 {
775777 struct tty_port *tport = &port->state->port;
776778 unsigned int sr;
drivers/tty/serial/pch_uart.c+10−24
@@ -1857,41 +1857,24 @@ static void pch_uart_pci_remove(struct pci_dev *pdev) · 1856 unmodified lines
18571857 kfree(priv);
18581858 return;
18591859 }
1860−#ifdef CONFIG_PM
1861−static int pch_uart_pci_suspend(struct pci_dev *pdev, pm_message_t state)
1860+
1861+static int __maybe_unused pch_uart_pci_suspend(struct device *dev)
18621862 {
1863− struct eg20t_port *priv = pci_get_drvdata(pdev);
1863+ struct eg20t_port *priv = dev_get_drvdata(dev);
18641864
18651865 uart_suspend_port(&pch_uart_driver, &priv->port);
18661866
1867− pci_save_state(pdev);
1868− pci_set_power_state(pdev, pci_choose_state(pdev, state));
18691867 return 0;
18701868 }
18711869
1872−static int pch_uart_pci_resume(struct pci_dev *pdev)
1870+static int __maybe_unused pch_uart_pci_resume(struct device *dev)
18731871 {
1874− struct eg20t_port *priv = pci_get_drvdata(pdev);
1875− int ret;
1876−
1877− pci_set_power_state(pdev, PCI_D0);
1878− pci_restore_state(pdev);
1879−
1880− ret = pci_enable_device(pdev);
1881− if (ret) {
1882− dev_err(&pdev->dev,
1883− "%s-pci_enable_device failed(ret=%d) ", __func__, ret);
1884− return ret;
1885− }
1872+ struct eg20t_port *priv = dev_get_drvdata(dev);
18861873
18871874 uart_resume_port(&pch_uart_driver, &priv->port);
18881875
18891876 return 0;
18901877 }
1891−#else
1892−#define pch_uart_pci_suspend NULL
1893−#define pch_uart_pci_resume NULL
1894−#endif
18951878
18961879 static const struct pci_device_id pch_uart_pci_id[] = {
18971880 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8811),
@@ -1945,13 +1928,16 @@ probe_error: · 47 unmodified lines
19451928 return ret;
19461929 }
19471930
1931+static SIMPLE_DEV_PM_OPS(pch_uart_pci_pm_ops,
1932+ pch_uart_pci_suspend,
1933+ pch_uart_pci_resume);
1934+
19481935 static struct pci_driver pch_uart_pci_driver = {
19491936 .name = "pch_uart",
19501937 .id_table = pch_uart_pci_id,
19511938 .probe = pch_uart_pci_probe,
19521939 .remove = pch_uart_pci_remove,
1953− .suspend = pch_uart_pci_suspend,
1954− .resume = pch_uart_pci_resume,
1940+ .driver.pm = &pch_uart_pci_pm_ops,
19551941 };
19561942
19571943 static int __init pch_uart_module_init(void)
drivers/tty/serial/pmac_zilog.c+1−0
@@ -213,6 +213,7 @@ static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable) · 212 unmodified lines
213213 }
214214
215215 static bool pmz_receive_chars(struct uart_pmac_port *uap)
216+ __must_hold(&uap->port.lock)
216217 {
217218 struct tty_port *port;
218219 unsigned char ch, r1, drop, flag;
drivers/tty/serial/qcom_geni_serial.c+1−1
@@ -768,7 +768,7 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done, · 767 unmodified lines
768768 u8 buf[sizeof(u32)];
769769 int c;
770770
771− memset(buf, 0, ARRAY_SIZE(buf));
771+ memset(buf, 0, sizeof(buf));
772772 tx_bytes = min_t(size_t, remaining, BYTES_PER_FIFO_WORD);
773773
774774 for (c = 0; c < tx_bytes ; c++) {
drivers/tty/serial/samsung_tty.c+10−14
@@ -6,7 +6,7 @@ · 5 unmodified lines
66 * http://armlinux.simtec.co.uk/
77 */
88
9−/* Hote on 2410 error handling
9+/* Note on 2410 error handling
1010 *
1111 * The s3c2410 manual has a love/hate affair with the contents of the
1212 * UERSTAT register in the UART blocks, and keeps marking some of the
@@ -327,7 +327,6 @@ static void s3c24xx_serial_tx_dma_complete(void *args) · 314 unmodified lines
327327 unsigned long flags;
328328 int count;
329329
330−
331330 dmaengine_tx_status(dma->tx_chan, dma->tx_cookie, &state);
332331 count = dma->tx_bytes_requested - state.residue;
333332 async_tx_ack(dma->tx_desc);
@@ -409,7 +408,6 @@ static int s3c24xx_serial_start_tx_dma(struct s3c24xx_uart_port *ourport, · 75 unmodified lines
409408 struct circ_buf *xmit = &port->state->xmit;
410409 struct s3c24xx_uart_dma *dma = ourport->dma;
411410
412−
413411 if (ourport->tx_mode != S3C24XX_TX_DMA)
414412 enable_tx_dma(ourport);
415413
@@ -816,7 +814,6 @@ static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id) · 400 unmodified lines
816814 return IRQ_HANDLED;
817815 }
818816
819−
820817 static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id)
821818 {
822819 struct s3c24xx_uart_port *ourport = dev_id;
@@ -842,8 +839,8 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) · 19 unmodified lines
842839 count >= ourport->min_dma_size) {
843840 int align = dma_get_cache_alignment() -
844841 (xmit->tail & (dma_get_cache_alignment() - 1));
845− if (count-align >= ourport->min_dma_size) {
846− dma_count = count-align;
842+ if (count - align >= ourport->min_dma_size) {
843+ dma_count = count - align;
847844 count = align;
848845 }
849846 }
@@ -1589,7 +1586,6 @@ s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser) · 739 unmodified lines
15891586 return 0;
15901587 }
15911588
1592−
15931589 #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
15941590
15951591 static struct console s3c24xx_serial_console;
@@ -1672,7 +1668,6 @@ s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = { · 76 unmodified lines
16721668 }
16731669 },
16741670 #if CONFIG_SERIAL_SAMSUNG_UARTS > 2
1675−
16761671 [2] = {
16771672 .port = {
16781673 .lock = __PORT_LOCK_UNLOCKED(2),
@@ -1728,7 +1723,6 @@ static void s3c24xx_serial_resetport(struct uart_port *port, · 49 unmodified lines
17281723 udelay(1);
17291724 }
17301725
1731−
17321726 #ifdef CONFIG_ARM_S3C24XX_CPUFREQ
17331727
17341728 static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb,
@@ -1903,9 +1897,9 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, · 168 unmodified lines
19031897
19041898 port->mapbase = res->start;
19051899 ret = platform_get_irq(platdev, 0);
1906− if (ret < 0)
1900+ if (ret < 0) {
19071901 port->irq = 0;
1908− else {
1902+ } else {
19091903 port->irq = ret;
19101904 ourport->rx_irq = ret;
19111905 ourport->tx_irq = ret + 1;
@@ -1977,8 +1971,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[]; · 65 unmodified lines
19771971
19781972 static int probe_index;
19791973
1980−static inline struct s3c24xx_serial_drv_data *s3c24xx_get_driver_data(
1981− struct platform_device *pdev)
1974+static inline struct s3c24xx_serial_drv_data *
1975+s3c24xx_get_driver_data(struct platform_device *pdev)
19821976 {
19831977 #ifdef CONFIG_OF
19841978 if (pdev->dev.of_node) {
@@ -2329,7 +2323,6 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud, · 344 unmodified lines
23292323 *baud = rate / (16 * (ubrdiv + 1));
23302324 dev_dbg(port->dev, "calculated baud %d\n", *baud);
23312325 }
2332−
23332326 }
23342327
23352328 static int __init
@@ -2696,6 +2689,7 @@ static int __init s3c2410_early_console_setup(struct earlycon_device *device, · 360 unmodified lines
26962689 device->port.private_data = &s3c2410_early_console_data;
26972690 return samsung_early_console_setup(device, opt);
26982691 }
2692+
26992693 OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart",
27002694 s3c2410_early_console_setup);
27012695
@@ -2710,6 +2704,7 @@ static int __init s3c2440_early_console_setup(struct earlycon_device *device, · 8 unmodified lines
27102704 device->port.private_data = &s3c2440_early_console_data;
27112705 return samsung_early_console_setup(device, opt);
27122706 }
2707+
27132708 OF_EARLYCON_DECLARE(s3c2412, "samsung,s3c2412-uart",
27142709 s3c2440_early_console_setup);
27152710 OF_EARLYCON_DECLARE(s3c2440, "samsung,s3c2440-uart",
@@ -2728,6 +2723,7 @@ static int __init s5pv210_early_console_setup(struct earlycon_device *device, · 12 unmodified lines
27282723 device->port.private_data = &s5pv210_early_console_data;
27292724 return samsung_early_console_setup(device, opt);
27302725 }
2726+
27312727 OF_EARLYCON_DECLARE(s5pv210, "samsung,s5pv210-uart",
27322728 s5pv210_early_console_setup);
27332729 OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart",
drivers/tty/serial/serial-tegra.c+3−3
@@ -439,16 +439,16 @@ static char tegra_uart_decode_rx_error(struct tegra_uart_port *tup, · 438 unmodified lines
439439 /* Overrrun error */
440440 flag = TTY_OVERRUN;
441441 tup->uport.icount.overrun++;
442− dev_err(tup->uport.dev, "Got overrun errors\n");
442+ dev_dbg(tup->uport.dev, "Got overrun errors\n");
443443 } else if (lsr & UART_LSR_PE) {
444444 /* Parity error */
445445 flag = TTY_PARITY;
446446 tup->uport.icount.parity++;
447− dev_err(tup->uport.dev, "Got Parity errors\n");
447+ dev_dbg(tup->uport.dev, "Got Parity errors\n");
448448 } else if (lsr & UART_LSR_FE) {
449449 flag = TTY_FRAME;
450450 tup->uport.icount.frame++;
451− dev_err(tup->uport.dev, "Got frame errors\n");
451+ dev_dbg(tup->uport.dev, "Got frame errors\n");
452452 } else if (lsr & UART_LSR_BI) {
453453 /*
454454 * Break error
drivers/tty/serial/serial_core.c+4−1
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 #include <linux/sched/signal.h>
1515 #include <linux/init.h>
1616 #include <linux/console.h>
17+#include <linux/gpio/consumer.h>
1718 #include <linux/of.h>
1819 #include <linux/proc_fs.h>
1920 #include <linux/seq_file.h>
@@ -1120,7 +1121,7 @@ out: · 1100 unmodified lines
11201121 return ret;
11211122 }
11221123
1123−static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state)
1124+static int uart_do_autoconfig(struct tty_struct *tty, struct uart_state *state)
11241125 {
11251126 struct tty_port *port = &state->port;
11261127 struct uart_port *uport;
@@ -1523,6 +1524,7 @@ static void uart_set_termios(struct tty_struct *tty, · 396 unmodified lines
15231524 /* Handle transition away from B0 status */
15241525 else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
15251526 unsigned int mask = TIOCM_DTR;
1527+
15261528 if (!(cflag & CRTSCTS) || !tty_throttled(tty))
15271529 mask |= TIOCM_RTS;
15281530 uart_set_mctrl(uport, mask);
@@ -2279,6 +2281,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) · 750 unmodified lines
22792281 if (console_suspend_enabled || !uart_console(uport)) {
22802282 /* Protected by port mutex for now */
22812283 struct tty_struct *tty = port->tty;
2284+
22822285 ret = ops->startup(uport);
22832286 if (ret == 0) {
22842287 if (tty)
drivers/tty/serial/sh-sci.c+0−3
@@ -3301,9 +3301,6 @@ static int sci_probe_single(struct platform_device *dev, · 3300 unmodified lines
33013301 sciport->port.flags |= UPF_HARD_FLOW;
33023302 }
33033303
3304− if (sci_uart_driver.cons->index == sciport->port.line)
3305− spin_lock_init(&sciport->port.lock);
3306−
33073304 ret = uart_add_one_port(&sci_uart_driver, &sciport->port);
33083305 if (ret) {
33093306 sci_cleanup_single(sciport);
drivers/tty/serial/sifive.c+0−1
@@ -883,7 +883,6 @@ console_initcall(sifive_console_init); · 882 unmodified lines
883883
884884 static void __ssp_add_console_port(struct sifive_serial_port *ssp)
885885 {
886− spin_lock_init(&ssp->port.lock);
887886 sifive_serial_console_ports[ssp->port.line] = ssp;
888887 }
889888
drivers/tty/serial/stm32-usart.c+11−2
@@ -129,9 +129,13 @@ static int stm32_config_rs485(struct uart_port *port, · 128 unmodified lines
129129 if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
130130 cr3 &= ~USART_CR3_DEP;
131131 rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
132+ mctrl_gpio_set(stm32_port->gpios,
133+ stm32_port->port.mctrl & ~TIOCM_RTS);
132134 } else {
133135 cr3 |= USART_CR3_DEP;
134136 rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
137+ mctrl_gpio_set(stm32_port->gpios,
138+ stm32_port->port.mctrl | TIOCM_RTS);
135139 }
136140
137141 writel_relaxed(cr3, port->membase + ofs->cr3);
@@ -847,9 +851,13 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios, · 709 unmodified lines
847851 if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
848852 cr3 &= ~USART_CR3_DEP;
849853 rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
854+ mctrl_gpio_set(stm32_port->gpios,
855+ stm32_port->port.mctrl & ~TIOCM_RTS);
850856 } else {
851857 cr3 |= USART_CR3_DEP;
852858 rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
859+ mctrl_gpio_set(stm32_port->gpios,
860+ stm32_port->port.mctrl | TIOCM_RTS);
853861 }
854862
855863 } else {
@@ -1033,8 +1041,9 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev) · 177 unmodified lines
10331041 if (WARN_ON(id >= STM32_MAX_PORTS))
10341042 return NULL;
10351043
1036− stm32_ports[id].hw_flow_control = of_property_read_bool(np,
1037− "st,hw-flow-ctrl");
1044+ stm32_ports[id].hw_flow_control =
1045+ of_property_read_bool (np, "st,hw-flow-ctrl") /*deprecated*/ ||
1046+ of_property_read_bool (np, "uart-has-rtscts");
10381047 stm32_ports[id].port.line = id;
10391048 stm32_ports[id].cr1_irq = USART_CR1_RXNEIE;
10401049 stm32_ports[id].cr3_irq = 0;
drivers/tty/serial/sunhv.c+0−3
@@ -567,9 +567,6 @@ static int hv_probe(struct platform_device *op) · 566 unmodified lines
567567 sunserial_console_match(&sunhv_console, op->dev.of_node,
568568 &sunhv_reg, port->line, false);
569569
570− /* We need to initialize lock even for non-registered console */
571− spin_lock_init(&port->lock);
572−
573570 err = uart_add_one_port(&sunhv_reg, port);
574571 if (err)
575572 goto out_unregister_driver;
drivers/tty/serial/uartlite.c+1−1
@@ -32,7 +32,7 @@ · 31 unmodified lines
3232 * Register definitions
3333 *
3434 * For register details see datasheet:
35− * http://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf
35+ * https://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf
3636 */
3737
3838 #define ULITE_RX 0x00
drivers/tty/synclink.c+109−241
@@ -252,7 +252,6 @@ struct mgsl_struct { · 251 unmodified lines
252252
253253 char device_name[25]; /* device instance name */
254254
255− unsigned int bus_type; /* expansion bus type (ISA,EISA,PCI) */
256255 unsigned char bus; /* expansion bus number (zero based) */
257256 unsigned char function; /* PCI device number */
258257
@@ -3432,15 +3431,9 @@ static inline void line_info(struct seq_file *m, struct mgsl_struct *info) · 3173 unmodified lines
34323431 char stat_buf[30];
34333432 unsigned long flags;
34343433
3435− if (info->bus_type == MGSL_BUS_TYPE_PCI) {
3436− seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X",
3437− info->device_name, info->io_base, info->irq_level,
3438− info->phys_memory_base, info->phys_lcr_base);
3439− } else {
3440− seq_printf(m, "%s:(E)ISA io:%04X irq:%d dma:%d",
3441− info->device_name, info->io_base,
3442− info->irq_level, info->dma_level);
3443− }
3434+ seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X",
3435+ info->device_name, info->io_base, info->irq_level,
3436+ info->phys_memory_base, info->phys_lcr_base);
34443437
34453438 /* output current serial signal states */
34463439 spin_lock_irqsave(&info->irq_spinlock,flags);
@@ -3556,54 +3549,27 @@ static int mgsl_allocate_dma_buffers(struct mgsl_struct *info) · 109 unmodified lines
35563549 if ( info->max_frame_size % DMABUFFERSIZE )
35573550 BuffersPerFrame++;
35583551
3559− if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
3560− /*
3561− * The PCI adapter has 256KBytes of shared memory to use.
3562− * This is 64 PAGE_SIZE buffers.
3563− *
3564− * The first page is used for padding at this time so the
3565− * buffer list does not begin at offset 0 of the PCI
3566− * adapter's shared memory.
3567− *
3568− * The 2nd page is used for the buffer list. A 4K buffer
3569− * list can hold 128 DMA_BUFFER structures at 32 bytes
3570− * each.
3571− *
3572− * This leaves 62 4K pages.
3573− *
3574− * The next N pages are used for transmit frame(s). We
3575− * reserve enough 4K page blocks to hold the required
3576− * number of transmit dma buffers (num_tx_dma_buffers),
3577− * each of MaxFrameSize size.
3578− *
3579− * Of the remaining pages (62-N), determine how many can
3580− * be used to receive full MaxFrameSize inbound frames
3581− */
3582− info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame;
3583− info->rx_buffer_count = 62 - info->tx_buffer_count;
3584− } else {
3585− /* Calculate the number of PAGE_SIZE buffers needed for */
3586− /* receive and transmit DMA buffers. */
3587−
3588−
3589− /* Calculate the number of DMA buffers necessary to */
3590− /* hold 7 max size receive frames and one max size transmit frame. */
3591− /* The receive buffer count is bumped by one so we avoid an */
3592− /* End of List condition if all receive buffers are used when */
3593− /* using linked list DMA buffers. */
3594−
3595− info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame;
3596− info->rx_buffer_count = (BuffersPerFrame * MAXRXFRAMES) + 6;
3597−
3598− /*
3599− * limit total TxBuffers & RxBuffers to 62 4K total
3600− * (ala PCI Allocation)
3601− */
3602−
3603− if ( (info->tx_buffer_count + info->rx_buffer_count) > 62 )
3604− info->rx_buffer_count = 62 - info->tx_buffer_count;
3605−
3606− }
3552+ /*
3553+ * The PCI adapter has 256KBytes of shared memory to use. This is 64
3554+ * PAGE_SIZE buffers.
3555+ *
3556+ * The first page is used for padding at this time so the buffer list
3557+ * does not begin at offset 0 of the PCI adapter's shared memory.
3558+ *
3559+ * The 2nd page is used for the buffer list. A 4K buffer list can hold
3560+ * 128 DMA_BUFFER structures at 32 bytes each.
3561+ *
3562+ * This leaves 62 4K pages.
3563+ *
3564+ * The next N pages are used for transmit frame(s). We reserve enough
3565+ * 4K page blocks to hold the required number of transmit dma buffers
3566+ * (num_tx_dma_buffers), each of MaxFrameSize size.
3567+ *
3568+ * Of the remaining pages (62-N), determine how many can be used to
3569+ * receive full MaxFrameSize inbound frames
3570+ */
3571+ info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame;
3572+ info->rx_buffer_count = 62 - info->tx_buffer_count;
36073573
36083574 if ( debug_level >= DEBUG_LEVEL_INFO )
36093575 printk("%s(%d):Allocating %d TX and %d RX DMA buffers.\n",
@@ -3652,23 +3618,10 @@ static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info ) · 42 unmodified lines
36523618 {
36533619 unsigned int i;
36543620
3655− if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
3656− /* PCI adapter uses shared memory. */
3657− info->buffer_list = info->memory_base + info->last_mem_alloc;
3658− info->buffer_list_phys = info->last_mem_alloc;
3659− info->last_mem_alloc += BUFFERLISTSIZE;
3660− } else {
3661− /* ISA adapter uses system memory. */
3662− /* The buffer lists are allocated as a common buffer that both */
3663− /* the processor and adapter can access. This allows the driver to */
3664− /* inspect portions of the buffer while other portions are being */
3665− /* updated by the adapter using Bus Master DMA. */
3666−
3667− info->buffer_list = dma_alloc_coherent(NULL, BUFFERLISTSIZE, &info->buffer_list_dma_addr, GFP_KERNEL);
3668− if (info->buffer_list == NULL)
3669− return -ENOMEM;
3670− info->buffer_list_phys = (u32)(info->buffer_list_dma_addr);
3671− }
3621+ /* PCI adapter uses shared memory. */
3622+ info->buffer_list = info->memory_base + info->last_mem_alloc;
3623+ info->buffer_list_phys = info->last_mem_alloc;
3624+ info->last_mem_alloc += BUFFERLISTSIZE;
36723625
36733626 /* We got the memory for the buffer entry lists. */
36743627 /* Initialize the memory block to all zeros. */
@@ -3734,9 +3687,6 @@ static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info ) · 59 unmodified lines
37343687 */
37353688 static void mgsl_free_buffer_list_memory( struct mgsl_struct *info )
37363689 {
3737− if (info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI)
3738− dma_free_coherent(NULL, BUFFERLISTSIZE, info->buffer_list, info->buffer_list_dma_addr);
3739−
37403690 info->buffer_list = NULL;
37413691 info->rx_buffer_list = NULL;
37423692 info->tx_buffer_list = NULL;
@@ -3762,24 +3712,13 @@ static void mgsl_free_buffer_list_memory( struct mgsl_struct *info ) · 19 unmodified lines
37623712 static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *BufferList,int Buffercount)
37633713 {
37643714 int i;
3765− u32 phys_addr;
37663715
37673716 /* Allocate page sized buffers for the receive buffer list */
37683717
37693718 for ( i = 0; i < Buffercount; i++ ) {
3770− if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
3771− /* PCI adapter uses shared memory buffers. */
3772− BufferList[i].virt_addr = info->memory_base + info->last_mem_alloc;
3773− phys_addr = info->last_mem_alloc;
3774− info->last_mem_alloc += DMABUFFERSIZE;
3775− } else {
3776− /* ISA adapter uses system memory. */
3777− BufferList[i].virt_addr = dma_alloc_coherent(NULL, DMABUFFERSIZE, &BufferList[i].dma_addr, GFP_KERNEL);
3778− if (BufferList[i].virt_addr == NULL)
3779− return -ENOMEM;
3780− phys_addr = (u32)(BufferList[i].dma_addr);
3781− }
3782− BufferList[i].phys_addr = phys_addr;
3719+ BufferList[i].virt_addr = info->memory_base + info->last_mem_alloc;
3720+ BufferList[i].phys_addr = info->last_mem_alloc;
3721+ info->last_mem_alloc += DMABUFFERSIZE;
37833722 }
37843723
37853724 return 0;
@@ -3807,8 +3746,6 @@ static void mgsl_free_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *Buf · 21 unmodified lines
38073746 if ( BufferList ) {
38083747 for ( i = 0 ; i < Buffercount ; i++ ) {
38093748 if ( BufferList[i].virt_addr ) {
3810− if ( info->bus_type != MGSL_BUS_TYPE_PCI )
3811− dma_free_coherent(NULL, DMABUFFERSIZE, BufferList[i].virt_addr, BufferList[i].dma_addr);
38123749 BufferList[i].virt_addr = NULL;
38133750 }
38143751 }
@@ -4040,58 +3977,40 @@ static int mgsl_claim_resources(struct mgsl_struct *info) · 225 unmodified lines
40403977 }
40413978 info->irq_requested = true;
40423979
4043− if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
4044− if (request_mem_region(info->phys_memory_base,0x40000,"synclink") == NULL) {
4045− printk( "%s(%d):mem addr conflict device %s Addr=%08X\n",
4046− __FILE__,__LINE__,info->device_name, info->phys_memory_base);
4047− goto errout;
4048− }
4049− info->shared_mem_requested = true;
4050− if (request_mem_region(info->phys_lcr_base + info->lcr_offset,128,"synclink") == NULL) {
4051− printk( "%s(%d):lcr mem addr conflict device %s Addr=%08X\n",
4052− __FILE__,__LINE__,info->device_name, info->phys_lcr_base + info->lcr_offset);
4053− goto errout;
4054− }
4055− info->lcr_mem_requested = true;
4056−
4057− info->memory_base = ioremap(info->phys_memory_base,
4058− 0x40000);
4059− if (!info->memory_base) {
4060− printk( "%s(%d):Can't map shared memory on device %s MemAddr=%08X\n",
4061− __FILE__,__LINE__,info->device_name, info->phys_memory_base );
4062− goto errout;
4063− }
4064−
4065− if ( !mgsl_memory_test(info) ) {
4066− printk( "%s(%d):Failed shared memory test %s MemAddr=%08X\n",
4067− __FILE__,__LINE__,info->device_name, info->phys_memory_base );
4068− goto errout;
4069− }
4070−
4071− info->lcr_base = ioremap(info->phys_lcr_base,
4072− PAGE_SIZE);
4073− if (!info->lcr_base) {
4074− printk( "%s(%d):Can't map LCR memory on device %s MemAddr=%08X\n",
4075− __FILE__,__LINE__,info->device_name, info->phys_lcr_base );
4076− goto errout;
4077− }
4078− info->lcr_base += info->lcr_offset;
3980+ if (request_mem_region(info->phys_memory_base,0x40000,"synclink") == NULL) {
3981+ printk( "%s(%d):mem addr conflict device %s Addr=%08X\n",
3982+ __FILE__,__LINE__,info->device_name, info->phys_memory_base);
3983+ goto errout;
3984+ }
3985+ info->shared_mem_requested = true;
3986+ if (request_mem_region(info->phys_lcr_base + info->lcr_offset,128,"synclink") == NULL) {
3987+ printk( "%s(%d):lcr mem addr conflict device %s Addr=%08X\n",
3988+ __FILE__,__LINE__,info->device_name, info->phys_lcr_base + info->lcr_offset);
3989+ goto errout;
3990+ }
3991+ info->lcr_mem_requested = true;
3992+
3993+ info->memory_base = ioremap(info->phys_memory_base, 0x40000);
3994+ if (!info->memory_base) {
3995+ printk( "%s(%d):Can't map shared memory on device %s MemAddr=%08X\n",
3996+ __FILE__,__LINE__,info->device_name, info->phys_memory_base );
3997+ goto errout;
3998+ }
40793999
4080− } else {
4081− /* claim DMA channel */
4000+ if ( !mgsl_memory_test(info) ) {
4001+ printk( "%s(%d):Failed shared memory test %s MemAddr=%08X\n",
4002+ __FILE__,__LINE__,info->device_name, info->phys_memory_base );
4003+ goto errout;
4004+ }
40824005
4083− if (request_dma(info->dma_level,info->device_name) < 0){
4084− printk( "%s(%d):Can't request DMA channel on device %s DMA=%d\n",
4085− __FILE__,__LINE__,info->device_name, info->dma_level );
4086− goto errout;
4087− }
4088− info->dma_requested = true;
4089−
4090− /* ISA adapter uses bus master DMA */
4091− set_dma_mode(info->dma_level,DMA_MODE_CASCADE);
4092− enable_dma(info->dma_level);
4006+ info->lcr_base = ioremap(info->phys_lcr_base, PAGE_SIZE);
4007+ if (!info->lcr_base) {
4008+ printk( "%s(%d):Can't map LCR memory on device %s MemAddr=%08X\n",
4009+ __FILE__,__LINE__,info->device_name, info->phys_lcr_base );
4010+ goto errout;
40934011 }
4094−
4012+ info->lcr_base += info->lcr_offset;
4013+
40954014 if ( mgsl_allocate_dma_buffers(info) < 0 ) {
40964015 printk( "%s(%d):Can't allocate DMA buffers on device %s DMA=%d\n",
40974016 __FILE__,__LINE__,info->device_name, info->dma_level );
@@ -4200,16 +4119,10 @@ static void mgsl_add_device( struct mgsl_struct *info ) · 102 unmodified lines
42004119 else if ( info->max_frame_size > 65535 )
42014120 info->max_frame_size = 65535;
42024121
4203− if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
4204− printk( "SyncLink PCI v%d %s: IO=%04X IRQ=%d Mem=%08X,%08X MaxFrameSize=%u\n",
4205− info->hw_version + 1, info->device_name, info->io_base, info->irq_level,
4206− info->phys_memory_base, info->phys_lcr_base,
4207− info->max_frame_size );
4208− } else {
4209− printk( "SyncLink ISA %s: IO=%04X IRQ=%d DMA=%d MaxFrameSize=%u\n",
4210− info->device_name, info->io_base, info->irq_level, info->dma_level,
4211− info->max_frame_size );
4212− }
4122+ printk( "SyncLink PCI v%d %s: IO=%04X IRQ=%d Mem=%08X,%08X MaxFrameSize=%u\n",
4123+ info->hw_version + 1, info->device_name, info->io_base, info->irq_level,
4124+ info->phys_memory_base, info->phys_lcr_base,
4125+ info->max_frame_size );
42134126
42144127 #if SYNCLINK_GENERIC_HDLC
42154128 hdlcdev_init(info);
@@ -4420,8 +4333,7 @@ static void usc_RTCmd( struct mgsl_struct *info, u16 Cmd ) · 204 unmodified lines
44204333 outw( Cmd + info->loopback_bits, info->io_base + CCAR );
44214334
44224335 /* Read to flush write to CCAR */
4423− if ( info->bus_type == MGSL_BUS_TYPE_PCI )
4424− inw( info->io_base + CCAR );
4336+ inw( info->io_base + CCAR );
44254337
44264338 } /* end of usc_RTCmd() */
44274339
@@ -4445,8 +4357,7 @@ static void usc_DmaCmd( struct mgsl_struct *info, u16 Cmd ) · 17 unmodified lines
44454357 outw( Cmd + info->mbre_bit, info->io_base );
44464358
44474359 /* Read to flush write to DCAR */
4448− if ( info->bus_type == MGSL_BUS_TYPE_PCI )
4449− inw( info->io_base );
4360+ inw( info->io_base );
44504361
44514362 } /* end of usc_DmaCmd() */
44524363
@@ -4475,8 +4386,7 @@ static void usc_OutDmaReg( struct mgsl_struct *info, u16 RegAddr, u16 RegValue ) · 22 unmodified lines
44754386 outw( RegValue, info->io_base );
44764387
44774388 /* Read to flush write to DCAR */
4478− if ( info->bus_type == MGSL_BUS_TYPE_PCI )
4479− inw( info->io_base );
4389+ inw( info->io_base );
44804390
44814391 } /* end of usc_OutDmaReg() */
44824392
@@ -4528,8 +4438,7 @@ static void usc_OutReg( struct mgsl_struct *info, u16 RegAddr, u16 RegValue ) · 45 unmodified lines
45284438 outw( RegValue, info->io_base + CCAR );
45294439
45304440 /* Read to flush write to CCAR */
4531− if ( info->bus_type == MGSL_BUS_TYPE_PCI )
4532− inw( info->io_base + CCAR );
4441+ inw( info->io_base + CCAR );
45334442
45344443 } /* end of usc_OutReg() */
45354444
@@ -4728,10 +4637,7 @@ static void usc_set_sdlc_mode( struct mgsl_struct *info ) · 192 unmodified lines
47284637
47294638 RegValue = usc_InReg( info, RICR ) & 0xc0;
47304639
4731− if ( info->bus_type == MGSL_BUS_TYPE_PCI )
4732− usc_OutReg( info, RICR, (u16)(0x030a | RegValue) );
4733− else
4734− usc_OutReg( info, RICR, (u16)(0x140a | RegValue) );
4640+ usc_OutReg( info, RICR, (u16)(0x030a | RegValue) );
47354641
47364642 /* Unlatch all Rx status bits and clear Rx status IRQ Pending */
47374643
@@ -4792,10 +4698,7 @@ static void usc_set_sdlc_mode( struct mgsl_struct *info ) · 54 unmodified lines
47924698 * 0000 0000 0011 0110 = 0x0036
47934699 */
47944700
4795− if ( info->bus_type == MGSL_BUS_TYPE_PCI )
4796− usc_OutReg( info, TICR, 0x0736 );
4797− else
4798− usc_OutReg( info, TICR, 0x1436 );
4701+ usc_OutReg( info, TICR, 0x0736 );
47994702
48004703 usc_UnlatchTxstatusBits( info, TXSTATUS_ALL );
48014704 usc_ClearIrqPendingBits( info, TRANSMIT_STATUS );
@@ -4885,10 +4788,7 @@ static void usc_set_sdlc_mode( struct mgsl_struct *info ) · 83 unmodified lines
48854788 /* DPLL is enabled. Use BRG1 to provide continuous reference clock */
48864789 /* for DPLL. DPLL mode in HCR is dependent on the encoding used. */
48874790
4888− if ( info->bus_type == MGSL_BUS_TYPE_PCI )
4889− XtalSpeed = 11059200;
4890− else
4891− XtalSpeed = 14745600;
4791+ XtalSpeed = 11059200;
48924792
48934793 if ( info->params.flags & HDLC_FLAG_DPLL_DIV16 ) {
48944794 DpllDivisor = 16;
@@ -5011,13 +4911,8 @@ static void usc_set_sdlc_mode( struct mgsl_struct *info ) · 116 unmodified lines
50114911 * 0110 0000 0000 1011 = 0x600b
50124912 */
50134913
5014− if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
5015− /* PCI adapter does not need DMA wait state */
5016− usc_OutDmaReg( info, DCR, 0xa00b );
5017− }
5018− else
5019− usc_OutDmaReg( info, DCR, 0x800b );
5020−
4914+ /* PCI adapter does not need DMA wait state */
4915+ usc_OutDmaReg( info, DCR, 0xa00b );
50214916
50224917 /* Receive DMA mode Register (RDMR)
50234918 *
@@ -5109,12 +5004,8 @@ static void usc_set_sdlc_mode( struct mgsl_struct *info ) · 85 unmodified lines
51095004 * <7..0> 0x00 Maximum number of clock cycles per bus grant
51105005 */
51115006
5112− if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
5113− /* don't limit bus occupancy on PCI adapter */
5114− usc_OutDmaReg( info, BDCR, 0x0000 );
5115− }
5116− else
5117− usc_OutDmaReg( info, BDCR, 0x2000 );
5007+ /* don't limit bus occupancy on PCI adapter */
5008+ usc_OutDmaReg( info, BDCR, 0x0000 );
51185009
51195010 usc_stop_transmitter(info);
51205011 usc_stop_receiver(info);
@@ -5155,10 +5046,7 @@ static void usc_enable_loopback(struct mgsl_struct *info, int enable) · 34 unmodified lines
51555046 /* Write 16-bit Time Constant for BRG0 */
51565047 /* use clock speed if available, otherwise use 8 for diagnostics */
51575048 if (info->params.clock_speed) {
5158− if (info->bus_type == MGSL_BUS_TYPE_PCI)
5159− usc_OutReg(info, TC0R, (u16)((11059200/info->params.clock_speed)-1));
5160− else
5161− usc_OutReg(info, TC0R, (u16)((14745600/info->params.clock_speed)-1));
5049+ usc_OutReg(info, TC0R, (u16)((11059200/info->params.clock_speed)-1));
51625050 } else
51635051 usc_OutReg(info, TC0R, (u16)8);
51645052
@@ -5201,10 +5089,7 @@ static void usc_enable_aux_clock( struct mgsl_struct *info, u32 data_rate ) · 36 unmodified lines
52015089 u16 Tc;
52025090
52035091 if ( data_rate ) {
5204− if ( info->bus_type == MGSL_BUS_TYPE_PCI )
5205− XtalSpeed = 11059200;
5206− else
5207− XtalSpeed = 14745600;
5092+ XtalSpeed = 11059200;
52085093
52095094
52105095 /* Tc = (Xtal/Speed) - 1 */
@@ -5682,44 +5567,38 @@ static void usc_load_txfifo( struct mgsl_struct *info ) · 471 unmodified lines
56825567 */
56835568 static void usc_reset( struct mgsl_struct *info )
56845569 {
5685− if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
5686− int i;
5687− u32 readval;
5570+ int i;
5571+ u32 readval;
56885572
5689− /* Set BIT30 of Misc Control Register */
5690− /* (Local Control Register 0x50) to force reset of USC. */
5573+ /* Set BIT30 of Misc Control Register */
5574+ /* (Local Control Register 0x50) to force reset of USC. */
56915575
5692− volatile u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50);
5693− u32 *LCR0BRDR = (u32 *)(info->lcr_base + 0x28);
5576+ volatile u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50);
5577+ u32 *LCR0BRDR = (u32 *)(info->lcr_base + 0x28);
56945578
5695− info->misc_ctrl_value |= BIT30;
5696− *MiscCtrl = info->misc_ctrl_value;
5579+ info->misc_ctrl_value |= BIT30;
5580+ *MiscCtrl = info->misc_ctrl_value;
56975581
5698− /*
5699− * Force at least 170ns delay before clearing
5700− * reset bit. Each read from LCR takes at least
5701− * 30ns so 10 times for 300ns to be safe.
5702− */
5703− for(i=0;i<10;i++)
5704− readval = *MiscCtrl;
5705−
5706− info->misc_ctrl_value &= ~BIT30;
5707− *MiscCtrl = info->misc_ctrl_value;
5708−
5709− *LCR0BRDR = BUS_DESCRIPTOR(
5710− 1, // Write Strobe Hold (0-3)
5711− 2, // Write Strobe Delay (0-3)
5712− 2, // Read Strobe Delay (0-3)
5713− 0, // NWDD (Write data-data) (0-3)
5714− 4, // NWAD (Write Addr-data) (0-31)
5715− 0, // NXDA (Read/Write Data-Addr) (0-3)
5716− 0, // NRDD (Read Data-Data) (0-3)
5717− 5 // NRAD (Read Addr-Data) (0-31)
5718− );
5719− } else {
5720− /* do HW reset */
5721− outb( 0,info->io_base + 8 );
5722− }
5582+ /*
5583+ * Force at least 170ns delay before clearing reset bit. Each read from
5584+ * LCR takes at least 30ns so 10 times for 300ns to be safe.
5585+ */
5586+ for(i=0;i<10;i++)
5587+ readval = *MiscCtrl;
5588+
5589+ info->misc_ctrl_value &= ~BIT30;
5590+ *MiscCtrl = info->misc_ctrl_value;
5591+
5592+ *LCR0BRDR = BUS_DESCRIPTOR(
5593+ 1, // Write Strobe Hold (0-3)
5594+ 2, // Write Strobe Delay (0-3)
5595+ 2, // Read Strobe Delay (0-3)
5596+ 0, // NWDD (Write data-data) (0-3)
5597+ 4, // NWAD (Write Addr-data) (0-31)
5598+ 0, // NXDA (Read/Write Data-Addr) (0-3)
5599+ 0, // NRDD (Read Data-Data) (0-3)
5600+ 5 // NRAD (Read Addr-Data) (0-31)
5601+ );
57235602
57245603 info->mbre_bit = 0;
57255604 info->loopback_bits = 0;
@@ -6228,11 +6107,7 @@ static void usc_enable_async_clock( struct mgsl_struct *info, u32 data_rate ) · 502 unmodified lines
62286107 * ClkSpeed = 921600 (ISA), 691200 (PCI)
62296108 */
62306109
6231− if ( info->bus_type == MGSL_BUS_TYPE_PCI )
6232− usc_OutReg( info, TC0R, (u16)((691200/data_rate) - 1) );
6233− else
6234− usc_OutReg( info, TC0R, (u16)((921600/data_rate) - 1) );
6235−
6110+ usc_OutReg( info, TC0R, (u16)((691200/data_rate) - 1) );
62366111
62376112 /*
62386113 * Hardware Configuration Register (HCR)
@@ -6837,10 +6712,7 @@ static void mgsl_load_tx_dma_buffer(struct mgsl_struct *info, · 598 unmodified lines
68376712
68386713 /* Actually copy data from source buffer to DMA buffer. */
68396714 /* Also set the data count for this individual DMA buffer. */
6840− if ( info->bus_type == MGSL_BUS_TYPE_PCI )
6841− mgsl_load_pci_memory(pBufEntry->virt_addr, Buffer,Copycount);
6842− else
6843− memcpy(pBufEntry->virt_addr, Buffer, Copycount);
6715+ mgsl_load_pci_memory(pBufEntry->virt_addr, Buffer,Copycount);
68446716
68456717 pBufEntry->count = Copycount;
68466718
@@ -7315,9 +7187,6 @@ static bool mgsl_memory_test( struct mgsl_struct *info ) · 468 unmodified lines
73157187 unsigned long TestLimit = SHARED_MEM_ADDRESS_SIZE/sizeof(unsigned long);
73167188 unsigned long * TestAddr;
73177189
7318− if ( info->bus_type != MGSL_BUS_TYPE_PCI )
7319− return true;
7320−
73217190 TestAddr = (unsigned long *)info->memory_base;
73227191
73237192 /* Test data lines with test pattern at one location. */
@@ -8003,7 +7872,6 @@ static int synclink_init_one (struct pci_dev *dev, · 679 unmodified lines
80037872 info->lcr_offset = info->phys_lcr_base & (PAGE_SIZE-1);
80047873 info->phys_lcr_base &= ~(PAGE_SIZE-1);
80057874
8006− info->bus_type = MGSL_BUS_TYPE_PCI;
80077875 info->io_addr_size = 8;
80087876 info->irq_flags = IRQF_SHARED;
80097877
drivers/tty/tty_io.c+26−26
@@ -1405,7 +1405,7 @@ void tty_save_termios(struct tty_struct *tty) · 1404 unmodified lines
14051405 /* Stash the termios data */
14061406 tp = tty->driver->termios[idx];
14071407 if (tp == NULL) {
1408− tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
1408+ tp = kmalloc(sizeof(*tp), GFP_KERNEL);
14091409 if (tp == NULL)
14101410 return;
14111411 tty->driver->termios[idx] = tp;
@@ -2489,7 +2489,7 @@ static int tty_tiocsserial(struct tty_struct *tty, struct serial_struct __user * · 1077 unmodified lines
24892489 struct serial_struct v;
24902490 int flags;
24912491
2492− if (copy_from_user(&v, ss, sizeof(struct serial_struct)))
2492+ if (copy_from_user(&v, ss, sizeof(*ss)))
24932493 return -EFAULT;
24942494
24952495 flags = v.flags & ASYNC_DEPRECATED;
@@ -2507,11 +2507,11 @@ static int tty_tiocgserial(struct tty_struct *tty, struct serial_struct __user * · 11 unmodified lines
25072507 struct serial_struct v;
25082508 int err;
25092509
2510− memset(&v, 0, sizeof(struct serial_struct));
2510+ memset(&v, 0, sizeof(v));
25112511 if (!tty->ops->get_serial)
25122512 return -ENOTTY;
25132513 err = tty->ops->get_serial(tty, &v);
2514− if (!err && copy_to_user(ss, &v, sizeof(struct serial_struct)))
2514+ if (!err && copy_to_user(ss, &v, sizeof(v)))
25152515 err = -EFAULT;
25162516 return err;
25172517 }
@@ -2673,25 +2673,25 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) · 155 unmodified lines
26732673 #ifdef CONFIG_COMPAT
26742674
26752675 struct serial_struct32 {
2676− compat_int_t type;
2677− compat_int_t line;
2678− compat_uint_t port;
2679− compat_int_t irq;
2680− compat_int_t flags;
2681− compat_int_t xmit_fifo_size;
2682− compat_int_t custom_divisor;
2683− compat_int_t baud_base;
2684− unsigned short close_delay;
2685− char io_type;
2686− char reserved_char[1];
2687− compat_int_t hub6;
2688− unsigned short closing_wait; /* time to wait before closing */
2689− unsigned short closing_wait2; /* no longer used... */
2690− compat_uint_t iomem_base;
2691− unsigned short iomem_reg_shift;
2692− unsigned int port_high;
2693− /* compat_ulong_t iomap_base FIXME */
2694− compat_int_t reserved[1];
2676+ compat_int_t type;
2677+ compat_int_t line;
2678+ compat_uint_t port;
2679+ compat_int_t irq;
2680+ compat_int_t flags;
2681+ compat_int_t xmit_fifo_size;
2682+ compat_int_t custom_divisor;
2683+ compat_int_t baud_base;
2684+ unsigned short close_delay;
2685+ char io_type;
2686+ char reserved_char;
2687+ compat_int_t hub6;
2688+ unsigned short closing_wait; /* time to wait before closing */
2689+ unsigned short closing_wait2; /* no longer used... */
2690+ compat_uint_t iomem_base;
2691+ unsigned short iomem_reg_shift;
2692+ unsigned int port_high;
2693+ /* compat_ulong_t iomap_base FIXME */
2694+ compat_int_t reserved;
26952695 };
26962696
26972697 static int compat_tty_tiocsserial(struct tty_struct *tty,
@@ -2705,7 +2705,7 @@ static int compat_tty_tiocsserial(struct tty_struct *tty, · 7 unmodified lines
27052705 struct serial_struct v;
27062706 int flags;
27072707
2708− if (copy_from_user(&v32, ss, sizeof(struct serial_struct32)))
2708+ if (copy_from_user(&v32, ss, sizeof(*ss)))
27092709 return -EFAULT;
27102710
27112711 memcpy(&v, &v32, offsetof(struct serial_struct32, iomem_base));
@@ -2743,7 +2743,7 @@ static int compat_tty_tiocgserial(struct tty_struct *tty, · 31 unmodified lines
27432743 0xfffffff : ptr_to_compat(v.iomem_base);
27442744 v32.iomem_reg_shift = v.iomem_reg_shift;
27452745 v32.port_high = v.port_high;
2746− if (copy_to_user(ss, &v32, sizeof(struct serial_struct32)))
2746+ if (copy_to_user(ss, &v32, sizeof(v32)))
27472747 err = -EFAULT;
27482748 }
27492749 return err;
@@ -3215,7 +3215,7 @@ struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, · 465 unmodified lines
32153215 if (!lines || (flags & TTY_DRIVER_UNNUMBERED_NODE && lines > 1))
32163216 return ERR_PTR(-EINVAL);
32173217
3218− driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL);
3218+ driver = kzalloc(sizeof(*driver), GFP_KERNEL);
32193219 if (!driver)
32203220 return ERR_PTR(-ENOMEM);
32213221
drivers/tty/vt/consolemap.c+1−1
@@ -542,7 +542,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) · 541 unmodified lines
542542 if (!ct)
543543 return 0;
544544
545− unilist = vmemdup_user(list, ct * sizeof(struct unipair));
545+ unilist = vmemdup_user(list, array_size(sizeof(struct unipair), ct));
546546 if (IS_ERR(unilist))
547547 return PTR_ERR(unilist);
548548
drivers/tty/vt/keyboard.c+2−1
@@ -32,6 +32,7 @@ · 31 unmodified lines
3232 #include <linux/tty.h>
3333 #include <linux/tty_flip.h>
3434 #include <linux/mm.h>
35+#include <linux/nospec.h>
3536 #include <linux/string.h>
3637 #include <linux/init.h>
3738 #include <linux/slab.h>
@@ -2019,7 +2020,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) · 1981 unmodified lines
20192020 goto reterr;
20202021 }
20212022 kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
2022− i = kbs->kb_func;
2023+ i = array_index_nospec(kbs->kb_func, MAX_NR_FUNC);
20232024
20242025 switch (cmd) {
20252026 case KDGKBSENT:
drivers/tty/vt/selection.c+1−1
@@ -193,7 +193,7 @@ static int vc_selection_store_chars(struct vc_data *vc, bool unicode) · 192 unmodified lines
193193 /* Allocate a new buffer before freeing the old one ... */
194194 /* chars can take up to 4 bytes with unicode */
195195 bp = kmalloc_array((vc_sel.end - vc_sel.start) / 2 + 1, unicode ? 4 : 1,
196− GFP_KERNEL);
196+ GFP_KERNEL | __GFP_NOWARN);
197197 if (!bp) {
198198 printk(KERN_WARNING "selection: kmalloc() failed\n");
199199 clear_selection();
drivers/tty/vt/vt.c+533−449
@@ -127,14 +127,6 @@ struct con_driver { · 126 unmodified lines
127127 static struct con_driver registered_con_driver[MAX_NR_CON_DRIVER];
128128 const struct consw *conswitchp;
129129
130−/* A bitmap for codes <32. A bit of 1 indicates that the code
131− * corresponding to that bit number invokes some special action
132− * (such as cursor movement) and should not be displayed as a
133− * glyph unless the disp_ctrl mode is explicitly enabled.
134− */
135−#define CTRL_ACTION 0x0d00ff81
136−#define CTRL_ALWAYS 0x0800f501 /* Cannot be overridden by disp_ctrl */
137−
138130 /*
139131 * Here is the default bell parameters: 750HZ, 1/8th of a second
140132 */
@@ -171,7 +163,7 @@ module_param(default_utf8, int, S_IRUGO | S_IWUSR); · 30 unmodified lines
171163 int global_cursor_default = -1;
172164 module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
173165
174−static int cur_default = CUR_DEFAULT;
166+static int cur_default = CUR_UNDERLINE;
175167 module_param(cur_default, int, S_IRUGO | S_IWUSR);
176168
177169 /*
@@ -381,7 +373,7 @@ static void vc_uniscr_putc(struct vc_data *vc, char32_t uc) · 203 unmodified lines
381373 struct uni_screen *uniscr = get_vc_uniscr(vc);
382374
383375 if (uniscr)
384− uniscr->lines[vc->vc_y][vc->vc_x] = uc;
376+ uniscr->lines[vc->state.y][vc->state.x] = uc;
385377 }
386378
387379 static void vc_uniscr_insert(struct vc_data *vc, unsigned int nr)
@@ -389,8 +381,8 @@ static void vc_uniscr_insert(struct vc_data *vc, unsigned int nr) · 1 unmodified line
389381 struct uni_screen *uniscr = get_vc_uniscr(vc);
390382
391383 if (uniscr) {
392− char32_t *ln = uniscr->lines[vc->vc_y];
393− unsigned int x = vc->vc_x, cols = vc->vc_cols;
384+ char32_t *ln = uniscr->lines[vc->state.y];
385+ unsigned int x = vc->state.x, cols = vc->vc_cols;
394386
395387 memmove(&ln[x + nr], &ln[x], (cols - x - nr) * sizeof(*ln));
396388 memset32(&ln[x], ' ', nr);
@@ -402,8 +394,8 @@ static void vc_uniscr_delete(struct vc_data *vc, unsigned int nr) · 5 unmodified lines
402394 struct uni_screen *uniscr = get_vc_uniscr(vc);
403395
404396 if (uniscr) {
405− char32_t *ln = uniscr->lines[vc->vc_y];
406− unsigned int x = vc->vc_x, cols = vc->vc_cols;
397+ char32_t *ln = uniscr->lines[vc->state.y];
398+ unsigned int x = vc->state.x, cols = vc->vc_cols;
407399
408400 memcpy(&ln[x], &ln[x + nr], (cols - x - nr) * sizeof(*ln));
409401 memset32(&ln[cols - nr], ' ', nr);
@@ -416,7 +408,7 @@ static void vc_uniscr_clear_line(struct vc_data *vc, unsigned int x, · 6 unmodified lines
416408 struct uni_screen *uniscr = get_vc_uniscr(vc);
417409
418410 if (uniscr) {
419− char32_t *ln = uniscr->lines[vc->vc_y];
411+ char32_t *ln = uniscr->lines[vc->state.y];
420412
421413 memset32(&ln[x], ' ', nr);
422414 }
@@ -705,8 +697,9 @@ void update_region(struct vc_data *vc, unsigned long start, int count) · 282 unmodified lines
705697
706698 /* Structure of attributes is hardware-dependent */
707699
708−static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
709− u8 _underline, u8 _reverse, u8 _italic)
700+static u8 build_attr(struct vc_data *vc, u8 _color,
701+ enum vc_intensity _intensity, bool _blink, bool _underline,
702+ bool _reverse, bool _italic)
710703 {
711704 if (vc->vc_sw->con_build_attr)
712705 return vc->vc_sw->con_build_attr(vc, _color, _intensity,
@@ -726,21 +719,21 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, · 13 unmodified lines
726719 u8 a = _color;
727720 if (!vc->vc_can_do_color)
728721 return _intensity |
729− (_italic ? 2 : 0) |
730− (_underline ? 4 : 0) |
731− (_reverse ? 8 : 0) |
732− (_blink ? 0x80 : 0);
722+ (_italic << 1) |
723+ (_underline << 2) |
724+ (_reverse << 3) |
725+ (_blink << 7);
733726 if (_italic)
734727 a = (a & 0xF0) | vc->vc_itcolor;
735728 else if (_underline)
736729 a = (a & 0xf0) | vc->vc_ulcolor;
737− else if (_intensity == 0)
730+ else if (_intensity == VCI_HALF_BRIGHT)
738731 a = (a & 0xf0) | vc->vc_halfcolor;
739732 if (_reverse)
740− a = ((a) & 0x88) | ((((a) >> 4) | ((a) << 4)) & 0x77);
733+ a = (a & 0x88) | (((a >> 4) | (a << 4)) & 0x77);
741734 if (_blink)
742735 a ^= 0x80;
743− if (_intensity == 2)
736+ if (_intensity == VCI_BOLD)
744737 a ^= 0x08;
745738 if (vc->vc_hi_font_mask == 0x100)
746739 a <<= 1;
@@ -750,10 +743,12 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, · 3 unmodified lines
750743
751744 static void update_attr(struct vc_data *vc)
752745 {
753− vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity,
754− vc->vc_blink, vc->vc_underline,
755− vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
756− vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
746+ vc->vc_attr = build_attr(vc, vc->state.color, vc->state.intensity,
747+ vc->state.blink, vc->state.underline,
748+ vc->state.reverse ^ vc->vc_decscnm, vc->state.italic);
749+ vc->vc_video_erase_char = ' ' | (build_attr(vc, vc->state.color,
750+ VCI_NORMAL, vc->state.blink, false,
751+ vc->vc_decscnm, false) << 8);
757752 }
758753
759754 /* Note: inverting the screen twice should revert to the original state */
@@ -782,14 +777,18 @@ void invert_screen(struct vc_data *vc, int offset, int count, int viewed) · 22 unmodified lines
782777 } else if (vc->vc_hi_font_mask == 0x100) {
783778 while (cnt--) {
784779 a = scr_readw(q);
785− a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
780+ a = (a & 0x11ff) |
781+ ((a & 0xe000) >> 4) |
782+ ((a & 0x0e00) << 4);
786783 scr_writew(a, q);
787784 q++;
788785 }
789786 } else {
790787 while (cnt--) {
791788 a = scr_readw(q);
792− a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
789+ a = (a & 0x88ff) |
790+ ((a & 0x7000) >> 4) |
791+ ((a & 0x0700) << 4);
793792 scr_writew(a, q);
794793 q++;
795794 }
@@ -842,12 +841,12 @@ static void insert_char(struct vc_data *vc, unsigned int nr) · 46 unmodified lines
842841 unsigned short *p = (unsigned short *) vc->vc_pos;
843842
844843 vc_uniscr_insert(vc, nr);
845− scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x - nr) * 2);
844+ scr_memmovew(p + nr, p, (vc->vc_cols - vc->state.x - nr) * 2);
846845 scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
847846 vc->vc_need_wrap = 0;
848847 if (con_should_update(vc))
849848 do_update_region(vc, (unsigned long) p,
850− vc->vc_cols - vc->vc_x);
849+ vc->vc_cols - vc->state.x);
851850 }
852851
853852 static void delete_char(struct vc_data *vc, unsigned int nr)
@@ -855,13 +854,13 @@ static void delete_char(struct vc_data *vc, unsigned int nr) · 1 unmodified line
855854 unsigned short *p = (unsigned short *) vc->vc_pos;
856855
857856 vc_uniscr_delete(vc, nr);
858− scr_memcpyw(p, p + nr, (vc->vc_cols - vc->vc_x - nr) * 2);
859− scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char,
857+ scr_memcpyw(p, p + nr, (vc->vc_cols - vc->state.x - nr) * 2);
858+ scr_memsetw(p + vc->vc_cols - vc->state.x - nr, vc->vc_video_erase_char,
860859 nr * 2);
861860 vc->vc_need_wrap = 0;
862861 if (con_should_update(vc))
863862 do_update_region(vc, (unsigned long) p,
864− vc->vc_cols - vc->vc_x);
863+ vc->vc_cols - vc->state.x);
865864 }
866865
867866 static int softcursor_original = -1;
@@ -871,16 +870,21 @@ static void add_softcursor(struct vc_data *vc) · 3 unmodified lines
871870 int i = scr_readw((u16 *) vc->vc_pos);
872871 u32 type = vc->vc_cursor_type;
873872
874− if (! (type & 0x10)) return;
875− if (softcursor_original != -1) return;
873+ if (!(type & CUR_SW))
874+ return;
875+ if (softcursor_original != -1)
876+ return;
876877 softcursor_original = i;
877− i |= ((type >> 8) & 0xff00 );
878− i ^= ((type) & 0xff00 );
879− if ((type & 0x20) && ((softcursor_original & 0x7000) == (i & 0x7000))) i ^= 0x7000;
880− if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700;
881− scr_writew(i, (u16 *) vc->vc_pos);
878+ i |= CUR_SET(type);
879+ i ^= CUR_CHANGE(type);
880+ if ((type & CUR_ALWAYS_BG) &&
881+ (softcursor_original & CUR_BG) == (i & CUR_BG))
882+ i ^= CUR_BG;
883+ if ((type & CUR_INVERT_FG_BG) && (i & CUR_FG) == ((i & CUR_BG) >> 4))
884+ i ^= CUR_FG;
885+ scr_writew(i, (u16 *)vc->vc_pos);
882886 if (con_should_update(vc))
883− vc->vc_sw->con_putc(vc, i, vc->vc_y, vc->vc_x);
887+ vc->vc_sw->con_putc(vc, i, vc->state.y, vc->state.x);
884888 }
885889
886890 static void hide_softcursor(struct vc_data *vc)
@@ -889,7 +893,7 @@ static void hide_softcursor(struct vc_data *vc) · 2 unmodified lines
889893 scr_writew(softcursor_original, (u16 *)vc->vc_pos);
890894 if (con_should_update(vc))
891895 vc->vc_sw->con_putc(vc, softcursor_original,
892− vc->vc_y, vc->vc_x);
896+ vc->state.y, vc->state.x);
893897 softcursor_original = -1;
894898 }
895899 }
@@ -911,7 +915,7 @@ static void set_cursor(struct vc_data *vc) · 15 unmodified lines
911915 if (vc_is_sel(vc))
912916 clear_selection();
913917 add_softcursor(vc);
914− if ((vc->vc_cursor_type & 0x0f) != 1)
918+ if (CUR_SIZE(vc->vc_cursor_type) != CUR_NONE)
915919 vc->vc_sw->con_cursor(vc, CM_DRAW);
916920 } else
917921 hide_cursor(vc);
@@ -927,7 +931,8 @@ static void set_origin(struct vc_data *vc) · 9 unmodified lines
927931 vc->vc_origin = (unsigned long)vc->vc_screenbuf;
928932 vc->vc_visible_origin = vc->vc_origin;
929933 vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size;
930− vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 2 * vc->vc_x;
934+ vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->state.y +
935+ 2 * vc->state.x;
931936 }
932937
933938 static void save_screen(struct vc_data *vc)
@@ -1256,8 +1261,8 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, · 322 unmodified lines
12561261 new_origin = (long) newscreen;
12571262 new_scr_end = new_origin + new_screen_size;
12581263
1259− if (vc->vc_y > new_rows) {
1260− if (old_rows - vc->vc_y < new_rows) {
1264+ if (vc->state.y > new_rows) {
1265+ if (old_rows - vc->state.y < new_rows) {
12611266 /*
12621267 * Cursor near the bottom, copy contents from the
12631268 * bottom of buffer
@@ -1268,7 +1273,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, · 4 unmodified lines
12681273 * Cursor is in no man's land, copy 1/2 screenful
12691274 * from the top and bottom of cursor position
12701275 */
1271− first_copied_row = (vc->vc_y - new_rows/2);
1276+ first_copied_row = (vc->state.y - new_rows/2);
12721277 }
12731278 old_origin += first_copied_row * old_row_size;
12741279 } else
@@ -1302,7 +1307,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, · 27 unmodified lines
13021307 /* do part of a reset_terminal() */
13031308 vc->vc_top = 0;
13041309 vc->vc_bottom = vc->vc_rows;
1305− gotoxy(vc, vc->vc_x, vc->vc_y);
1310+ gotoxy(vc, vc->state.x, vc->state.y);
13061311 save_cur(vc);
13071312
13081313 if (tty) {
@@ -1399,12 +1404,6 @@ enum { EPecma = 0, EPdec, EPeq, EPgt, EPlt}; · 90 unmodified lines
13991404 #define kbdapplic VC_APPLIC
14001405 #define lnm VC_CRLF
14011406
1402−/*
1403− * this is what the terminal answers to a ESC-Z or csi0c query.
1404− */
1405−#define VT100ID "\033[?1;2c"
1406−#define VT102ID "\033[?6c"
1407−
14081407 const unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
14091408 8,12,10,14, 9,13,11,15 };
14101409
@@ -1437,12 +1436,12 @@ static void gotoxy(struct vc_data *vc, int new_x, int new_y) · 26 unmodified lines
14371436 int min_y, max_y;
14381437
14391438 if (new_x < 0)
1440− vc->vc_x = 0;
1439+ vc->state.x = 0;
14411440 else {
14421441 if (new_x >= vc->vc_cols)
1443− vc->vc_x = vc->vc_cols - 1;
1442+ vc->state.x = vc->vc_cols - 1;
14441443 else
1445− vc->vc_x = new_x;
1444+ vc->state.x = new_x;
14461445 }
14471446
14481447 if (vc->vc_decom) {
@@ -1453,12 +1452,13 @@ static void gotoxy(struct vc_data *vc, int new_x, int new_y) · 4 unmodified lines
14531452 max_y = vc->vc_rows;
14541453 }
14551454 if (new_y < min_y)
1456− vc->vc_y = min_y;
1455+ vc->state.y = min_y;
14571456 else if (new_y >= max_y)
1458− vc->vc_y = max_y - 1;
1457+ vc->state.y = max_y - 1;
14591458 else
1460− vc->vc_y = new_y;
1461− vc->vc_pos = vc->vc_origin + vc->vc_y * vc->vc_size_row + (vc->vc_x<<1);
1459+ vc->state.y = new_y;
1460+ vc->vc_pos = vc->vc_origin + vc->state.y * vc->vc_size_row +
1461+ (vc->state.x << 1);
14621462 vc->vc_need_wrap = 0;
14631463 }
14641464
@@ -1485,10 +1485,10 @@ static void lf(struct vc_data *vc) · 20 unmodified lines
14851485 /* don't scroll if above bottom of scrolling region, or
14861486 * if below scrolling region
14871487 */
1488− if (vc->vc_y + 1 == vc->vc_bottom)
1488+ if (vc->state.y + 1 == vc->vc_bottom)
14891489 con_scroll(vc, vc->vc_top, vc->vc_bottom, SM_UP, 1);
1490− else if (vc->vc_y < vc->vc_rows - 1) {
1491− vc->vc_y++;
1490+ else if (vc->state.y < vc->vc_rows - 1) {
1491+ vc->state.y++;
14921492 vc->vc_pos += vc->vc_size_row;
14931493 }
14941494 vc->vc_need_wrap = 0;
@@ -1500,10 +1500,10 @@ static void ri(struct vc_data *vc) · 5 unmodified lines
15001500 /* don't scroll if below top of scrolling region, or
15011501 * if above scrolling region
15021502 */
1503− if (vc->vc_y == vc->vc_top)
1503+ if (vc->state.y == vc->vc_top)
15041504 con_scroll(vc, vc->vc_top, vc->vc_bottom, SM_DOWN, 1);
1505− else if (vc->vc_y > 0) {
1506− vc->vc_y--;
1505+ else if (vc->state.y > 0) {
1506+ vc->state.y--;
15071507 vc->vc_pos -= vc->vc_size_row;
15081508 }
15091509 vc->vc_need_wrap = 0;
@@ -1511,16 +1511,16 @@ static void ri(struct vc_data *vc) · 1 unmodified line
15111511
15121512 static inline void cr(struct vc_data *vc)
15131513 {
1514− vc->vc_pos -= vc->vc_x << 1;
1515− vc->vc_need_wrap = vc->vc_x = 0;
1514+ vc->vc_pos -= vc->state.x << 1;
1515+ vc->vc_need_wrap = vc->state.x = 0;
15161516 notify_write(vc, '\r');
15171517 }
15181518
15191519 static inline void bs(struct vc_data *vc)
15201520 {
1521− if (vc->vc_x) {
1521+ if (vc->state.x) {
15221522 vc->vc_pos -= 2;
1523− vc->vc_x--;
1523+ vc->state.x--;
15241524 vc->vc_need_wrap = 0;
15251525 notify_write(vc, '\b');
15261526 }
@@ -1538,16 +1538,16 @@ static void csi_J(struct vc_data *vc, int vpar) · 11 unmodified lines
15381538
15391539 switch (vpar) {
15401540 case 0: /* erase from cursor to end of display */
1541− vc_uniscr_clear_line(vc, vc->vc_x,
1542− vc->vc_cols - vc->vc_x);
1543− vc_uniscr_clear_lines(vc, vc->vc_y + 1,
1544− vc->vc_rows - vc->vc_y - 1);
1541+ vc_uniscr_clear_line(vc, vc->state.x,
1542+ vc->vc_cols - vc->state.x);
1543+ vc_uniscr_clear_lines(vc, vc->state.y + 1,
1544+ vc->vc_rows - vc->state.y - 1);
15451545 count = (vc->vc_scr_end - vc->vc_pos) >> 1;
15461546 start = (unsigned short *)vc->vc_pos;
15471547 break;
15481548 case 1: /* erase from start to cursor */
1549− vc_uniscr_clear_line(vc, 0, vc->vc_x + 1);
1550− vc_uniscr_clear_lines(vc, 0, vc->vc_y);
1549+ vc_uniscr_clear_line(vc, 0, vc->state.x + 1);
1550+ vc_uniscr_clear_lines(vc, 0, vc->state.y);
15511551 count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1;
15521552 start = (unsigned short *)vc->vc_origin;
15531553 break;
@@ -1577,49 +1577,51 @@ static void csi_K(struct vc_data *vc, int vpar) · 23 unmodified lines
15771577 switch (vpar) {
15781578 case 0: /* erase from cursor to end of line */
15791579 offset = 0;
1580− count = vc->vc_cols - vc->vc_x;
1580+ count = vc->vc_cols - vc->state.x;
15811581 break;
15821582 case 1: /* erase from start of line to cursor */
1583− offset = -vc->vc_x;
1584− count = vc->vc_x + 1;
1583+ offset = -vc->state.x;
1584+ count = vc->state.x + 1;
15851585 break;
15861586 case 2: /* erase whole line */
1587− offset = -vc->vc_x;
1587+ offset = -vc->state.x;
15881588 count = vc->vc_cols;
15891589 break;
15901590 default:
15911591 return;
15921592 }
1593− vc_uniscr_clear_line(vc, vc->vc_x + offset, count);
1593+ vc_uniscr_clear_line(vc, vc->state.x + offset, count);
15941594 scr_memsetw(start + offset, vc->vc_video_erase_char, 2 * count);
15951595 vc->vc_need_wrap = 0;
15961596 if (con_should_update(vc))
15971597 do_update_region(vc, (unsigned long)(start + offset), count);
15981598 }
15991599
1600−static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */
1600+/* erase the following vpar positions */
1601+static void csi_X(struct vc_data *vc, unsigned int vpar)
16011602 { /* not vt100? */
1602− int count;
1603+ unsigned int count;
16031604
16041605 if (!vpar)
16051606 vpar++;
1606− count = (vpar > vc->vc_cols - vc->vc_x) ? (vc->vc_cols - vc->vc_x) : vpar;
16071607
1608− vc_uniscr_clear_line(vc, vc->vc_x, count);
1608+ count = min(vpar, vc->vc_cols - vc->state.x);
1609+
1610+ vc_uniscr_clear_line(vc, vc->state.x, count);
16091611 scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count);
16101612 if (con_should_update(vc))
1611− vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, count);
1613+ vc->vc_sw->con_clear(vc, vc->state.y, vc->state.x, 1, count);
16121614 vc->vc_need_wrap = 0;
16131615 }
16141616
16151617 static void default_attr(struct vc_data *vc)
16161618 {
1617− vc->vc_intensity = 1;
1618− vc->vc_italic = 0;
1619− vc->vc_underline = 0;
1620− vc->vc_reverse = 0;
1621− vc->vc_blink = 0;
1622− vc->vc_color = vc->vc_def_color;
1619+ vc->state.intensity = VCI_NORMAL;
1620+ vc->state.italic = false;
1621+ vc->state.underline = false;
1622+ vc->state.reverse = false;
1623+ vc->state.blink = false;
1624+ vc->state.color = vc->vc_def_color;
16231625 }
16241626
16251627 struct rgb { u8 r; u8 g; u8 b; };
@@ -1655,19 +1657,19 @@ static void rgb_foreground(struct vc_data *vc, const struct rgb *c) · 29 unmodified lines
16551657
16561658 if (hue == 7 && max <= 0x55) {
16571659 hue = 0;
1658− vc->vc_intensity = 2;
1660+ vc->state.intensity = VCI_BOLD;
16591661 } else if (max > 0xaa)
1660− vc->vc_intensity = 2;
1662+ vc->state.intensity = VCI_BOLD;
16611663 else
1662− vc->vc_intensity = 1;
1664+ vc->state.intensity = VCI_NORMAL;
16631665
1664− vc->vc_color = (vc->vc_color & 0xf0) | hue;
1666+ vc->state.color = (vc->state.color & 0xf0) | hue;
16651667 }
16661668
16671669 static void rgb_background(struct vc_data *vc, const struct rgb *c)
16681670 {
16691671 /* For backgrounds, err on the dark side. */
1670− vc->vc_color = (vc->vc_color & 0x0f)
1672+ vc->state.color = (vc->state.color & 0x0f)
16711673 | (c->r&0x80) >> 1 | (c->g&0x80) >> 2 | (c->b&0x80) >> 3;
16721674 }
16731675
@@ -1718,13 +1720,13 @@ static void csi_m(struct vc_data *vc) · 44 unmodified lines
17181720 default_attr(vc);
17191721 break;
17201722 case 1:
1721− vc->vc_intensity = 2;
1723+ vc->state.intensity = VCI_BOLD;
17221724 break;
17231725 case 2:
1724− vc->vc_intensity = 0;
1726+ vc->state.intensity = VCI_HALF_BRIGHT;
17251727 break;
17261728 case 3:
1727− vc->vc_italic = 1;
1729+ vc->state.italic = true;
17281730 break;
17291731 case 21:
17301732 /*
@@ -1732,21 +1734,19 @@ static void csi_m(struct vc_data *vc) · 1 unmodified line
17321734 * convert it to a single underline.
17331735 */
17341736 case 4:
1735− vc->vc_underline = 1;
1737+ vc->state.underline = true;
17361738 break;
17371739 case 5:
1738− vc->vc_blink = 1;
1740+ vc->state.blink = true;
17391741 break;
17401742 case 7:
1741− vc->vc_reverse = 1;
1743+ vc->state.reverse = true;
17421744 break;
17431745 case 10: /* ANSI X3.64-1979 (SCO-ish?)
17441746 * Select primary font, don't display control chars if
17451747 * defined, don't set bit 8 on output.
17461748 */
1747− vc->vc_translate = set_translate(vc->vc_charset == 0
1748− ? vc->vc_G0_charset
1749− : vc->vc_G1_charset, vc);
1749+ vc->vc_translate = set_translate(vc->state.Gx_charset[vc->state.charset], vc);
17501750 vc->vc_disp_ctrl = 0;
17511751 vc->vc_toggle_meta = 0;
17521752 break;
@@ -1767,19 +1767,19 @@ static void csi_m(struct vc_data *vc) · 14 unmodified lines
17671767 vc->vc_toggle_meta = 1;
17681768 break;
17691769 case 22:
1770− vc->vc_intensity = 1;
1770+ vc->state.intensity = VCI_NORMAL;
17711771 break;
17721772 case 23:
1773− vc->vc_italic = 0;
1773+ vc->state.italic = false;
17741774 break;
17751775 case 24:
1776− vc->vc_underline = 0;
1776+ vc->state.underline = false;
17771777 break;
17781778 case 25:
1779− vc->vc_blink = 0;
1779+ vc->state.blink = false;
17801780 break;
17811781 case 27:
1782− vc->vc_reverse = 0;
1782+ vc->state.reverse = false;
17831783 break;
17841784 case 38:
17851785 i = vc_t416_color(vc, i, rgb_foreground);
@@ -1788,64 +1788,70 @@ static void csi_m(struct vc_data *vc) · 2 unmodified lines
17881788 i = vc_t416_color(vc, i, rgb_background);
17891789 break;
17901790 case 39:
1791− vc->vc_color = (vc->vc_def_color & 0x0f) |
1792− (vc->vc_color & 0xf0);
1791+ vc->state.color = (vc->vc_def_color & 0x0f) |
1792+ (vc->state.color & 0xf0);
17931793 break;
17941794 case 49:
1795− vc->vc_color = (vc->vc_def_color & 0xf0) |
1796− (vc->vc_color & 0x0f);
1795+ vc->state.color = (vc->vc_def_color & 0xf0) |
1796+ (vc->state.color & 0x0f);
17971797 break;
17981798 default:
17991799 if (vc->vc_par[i] >= 90 && vc->vc_par[i] <= 107) {
18001800 if (vc->vc_par[i] < 100)
1801− vc->vc_intensity = 2;
1801+ vc->state.intensity = VCI_BOLD;
18021802 vc->vc_par[i] -= 60;
18031803 }
18041804 if (vc->vc_par[i] >= 30 && vc->vc_par[i] <= 37)
1805− vc->vc_color = color_table[vc->vc_par[i] - 30]
1806− | (vc->vc_color & 0xf0);
1805+ vc->state.color = color_table[vc->vc_par[i] - 30]
1806+ | (vc->state.color & 0xf0);
18071807 else if (vc->vc_par[i] >= 40 && vc->vc_par[i] <= 47)
1808− vc->vc_color = (color_table[vc->vc_par[i] - 40] << 4)
1809− | (vc->vc_color & 0x0f);
1808+ vc->state.color = (color_table[vc->vc_par[i] - 40] << 4)
1809+ | (vc->state.color & 0x0f);
18101810 break;
18111811 }
18121812 update_attr(vc);
18131813 }
18141814
1815−static void respond_string(const char *p, struct tty_port *port)
1815+static void respond_string(const char *p, size_t len, struct tty_port *port)
18161816 {
1817− while (*p) {
1818− tty_insert_flip_char(port, *p, 0);
1819− p++;
1820− }
1817+ tty_insert_flip_string(port, p, len);
18211818 tty_schedule_flip(port);
18221819 }
18231820
18241821 static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
18251822 {
18261823 char buf[40];
1824+ int len;
18271825
1828− sprintf(buf, "\033[%d;%dR", vc->vc_y + (vc->vc_decom ? vc->vc_top + 1 : 1), vc->vc_x + 1);
1829− respond_string(buf, tty->port);
1826+ len = sprintf(buf, "\033[%d;%dR", vc->state.y +
1827+ (vc->vc_decom ? vc->vc_top + 1 : 1),
1828+ vc->state.x + 1);
1829+ respond_string(buf, len, tty->port);
18301830 }
18311831
18321832 static inline void status_report(struct tty_struct *tty)
18331833 {
1834− respond_string("\033[0n", tty->port); /* Terminal ok */
1834+ static const char teminal_ok[] = "\033[0n";
1835+
1836+ respond_string(teminal_ok, strlen(teminal_ok), tty->port);
18351837 }
18361838
18371839 static inline void respond_ID(struct tty_struct *tty)
18381840 {
1839− respond_string(VT102ID, tty->port);
1841+ /* terminal answer to an ESC-Z or csi0c query. */
1842+ static const char vt102_id[] = "\033[?6c";
1843+
1844+ respond_string(vt102_id, strlen(vt102_id), tty->port);
18401845 }
18411846
18421847 void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry)
18431848 {
18441849 char buf[8];
1850+ int len;
18451851
1846− sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
1847− (char)('!' + mry));
1848− respond_string(buf, tty->port);
1852+ len = sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt),
1853+ (char)('!' + mrx), (char)('!' + mry));
1854+ respond_string(buf, len, tty->port);
18491855 }
18501856
18511857 /* invoked via ioctl(TIOCLINUX) and through set_selection_user */
@@ -1930,14 +1936,14 @@ static void setterm_command(struct vc_data *vc) · 78 unmodified lines
19301936 case 1: /* set color for underline mode */
19311937 if (vc->vc_can_do_color && vc->vc_par[1] < 16) {
19321938 vc->vc_ulcolor = color_table[vc->vc_par[1]];
1933− if (vc->vc_underline)
1939+ if (vc->state.underline)
19341940 update_attr(vc);
19351941 }
19361942 break;
19371943 case 2: /* set color for half intensity mode */
19381944 if (vc->vc_can_do_color && vc->vc_par[1] < 16) {
19391945 vc->vc_halfcolor = color_table[vc->vc_par[1]];
1940− if (vc->vc_intensity == 0)
1946+ if (vc->state.intensity == VCI_HALF_BRIGHT)
19411947 update_attr(vc);
19421948 }
19431949 break;
@@ -1991,8 +1997,8 @@ static void setterm_command(struct vc_data *vc) · 47 unmodified lines
19911997 /* console_lock is held */
19921998 static void csi_at(struct vc_data *vc, unsigned int nr)
19931999 {
1994− if (nr > vc->vc_cols - vc->vc_x)
1995− nr = vc->vc_cols - vc->vc_x;
2000+ if (nr > vc->vc_cols - vc->state.x)
2001+ nr = vc->vc_cols - vc->state.x;
19962002 else if (!nr)
19972003 nr = 1;
19982004 insert_char(vc, nr);
@@ -2001,19 +2007,19 @@ static void csi_at(struct vc_data *vc, unsigned int nr) · 2 unmodified lines
20012007 /* console_lock is held */
20022008 static void csi_L(struct vc_data *vc, unsigned int nr)
20032009 {
2004− if (nr > vc->vc_rows - vc->vc_y)
2005− nr = vc->vc_rows - vc->vc_y;
2010+ if (nr > vc->vc_rows - vc->state.y)
2011+ nr = vc->vc_rows - vc->state.y;
20062012 else if (!nr)
20072013 nr = 1;
2008− con_scroll(vc, vc->vc_y, vc->vc_bottom, SM_DOWN, nr);
2014+ con_scroll(vc, vc->state.y, vc->vc_bottom, SM_DOWN, nr);
20092015 vc->vc_need_wrap = 0;
20102016 }
20112017
20122018 /* console_lock is held */
20132019 static void csi_P(struct vc_data *vc, unsigned int nr)
20142020 {
2015− if (nr > vc->vc_cols - vc->vc_x)
2016− nr = vc->vc_cols - vc->vc_x;
2021+ if (nr > vc->vc_cols - vc->state.x)
2022+ nr = vc->vc_cols - vc->state.x;
20172023 else if (!nr)
20182024 nr = 1;
20192025 delete_char(vc, nr);
@@ -2022,44 +2028,28 @@ static void csi_P(struct vc_data *vc, unsigned int nr) · 2 unmodified lines
20222028 /* console_lock is held */
20232029 static void csi_M(struct vc_data *vc, unsigned int nr)
20242030 {
2025− if (nr > vc->vc_rows - vc->vc_y)
2026− nr = vc->vc_rows - vc->vc_y;
2031+ if (nr > vc->vc_rows - vc->state.y)
2032+ nr = vc->vc_rows - vc->state.y;
20272033 else if (!nr)
20282034 nr=1;
2029− con_scroll(vc, vc->vc_y, vc->vc_bottom, SM_UP, nr);
2035+ con_scroll(vc, vc->state.y, vc->vc_bottom, SM_UP, nr);
20302036 vc->vc_need_wrap = 0;
20312037 }
20322038
20332039 /* console_lock is held (except via vc_init->reset_terminal */
20342040 static void save_cur(struct vc_data *vc)
20352041 {
2036− vc->vc_saved_x = vc->vc_x;
2037− vc->vc_saved_y = vc->vc_y;
2038− vc->vc_s_intensity = vc->vc_intensity;
2039− vc->vc_s_italic = vc->vc_italic;
2040− vc->vc_s_underline = vc->vc_underline;
2041− vc->vc_s_blink = vc->vc_blink;
2042− vc->vc_s_reverse = vc->vc_reverse;
2043− vc->vc_s_charset = vc->vc_charset;
2044− vc->vc_s_color = vc->vc_color;
2045− vc->vc_saved_G0 = vc->vc_G0_charset;
2046− vc->vc_saved_G1 = vc->vc_G1_charset;
2042+ memcpy(&vc->saved_state, &vc->state, sizeof(vc->state));
20472043 }
20482044
20492045 /* console_lock is held */
20502046 static void restore_cur(struct vc_data *vc)
20512047 {
2052− gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y);
2053− vc->vc_intensity = vc->vc_s_intensity;
2054− vc->vc_italic = vc->vc_s_italic;
2055− vc->vc_underline = vc->vc_s_underline;
2056− vc->vc_blink = vc->vc_s_blink;
2057− vc->vc_reverse = vc->vc_s_reverse;
2058− vc->vc_charset = vc->vc_s_charset;
2059− vc->vc_color = vc->vc_s_color;
2060− vc->vc_G0_charset = vc->vc_saved_G0;
2061− vc->vc_G1_charset = vc->vc_saved_G1;
2062− vc->vc_translate = set_translate(vc->vc_charset ? vc->vc_G1_charset : vc->vc_G0_charset, vc);
2048+ memcpy(&vc->state, &vc->saved_state, sizeof(vc->state));
2049+
2050+ gotoxy(vc, vc->state.x, vc->state.y);
2051+ vc->vc_translate = set_translate(vc->state.Gx_charset[vc->state.charset],
2052+ vc);
20632053 update_attr(vc);
20642054 vc->vc_need_wrap = 0;
20652055 }
@@ -2071,14 +2061,16 @@ enum { ESnormal, ESesc, ESsquare, ESgetpars, ESfunckey, · 5 unmodified lines
20712061 /* console_lock is held (except via vc_init()) */
20722062 static void reset_terminal(struct vc_data *vc, int do_clear)
20732063 {
2064+ unsigned int i;
2065+
20742066 vc->vc_top = 0;
20752067 vc->vc_bottom = vc->vc_rows;
20762068 vc->vc_state = ESnormal;
20772069 vc->vc_priv = EPecma;
20782070 vc->vc_translate = set_translate(LAT1_MAP, vc);
2079− vc->vc_G0_charset = LAT1_MAP;
2080− vc->vc_G1_charset = GRAF_MAP;
2081− vc->vc_charset = 0;
2071+ vc->state.Gx_charset[0] = LAT1_MAP;
2072+ vc->state.Gx_charset[1] = GRAF_MAP;
2073+ vc->state.charset = 0;
20822074 vc->vc_need_wrap = 0;
20832075 vc->vc_report_mouse = 0;
20842076 vc->vc_utf = default_utf8;
@@ -2101,14 +2093,9 @@ static void reset_terminal(struct vc_data *vc, int do_clear) · 16 unmodified lines
21012093 default_attr(vc);
21022094 update_attr(vc);
21032095
2104− vc->vc_tab_stop[0] =
2105− vc->vc_tab_stop[1] =
2106− vc->vc_tab_stop[2] =
2107− vc->vc_tab_stop[3] =
2108− vc->vc_tab_stop[4] =
2109− vc->vc_tab_stop[5] =
2110− vc->vc_tab_stop[6] =
2111− vc->vc_tab_stop[7] = 0x01010101;
2096+ bitmap_zero(vc->vc_tab_stop, VC_TABSTOPS_COUNT);
2097+ for (i = 0; i < VC_TABSTOPS_COUNT; i += 8)
2098+ set_bit(i, vc->vc_tab_stop);
21122099
21132100 vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
21142101 vc->vc_bell_duration = DEFAULT_BELL_DURATION;
@@ -2120,6 +2107,29 @@ static void reset_terminal(struct vc_data *vc, int do_clear) · 5 unmodified lines
21202107 csi_J(vc, 2);
21212108 }
21222109
2110+static void vc_setGx(struct vc_data *vc, unsigned int which, int c)
2111+{
2112+ unsigned char *charset = &vc->state.Gx_charset[which];
2113+
2114+ switch (c) {
2115+ case '0':
2116+ *charset = GRAF_MAP;
2117+ break;
2118+ case 'B':
2119+ *charset = LAT1_MAP;
2120+ break;
2121+ case 'U':
2122+ *charset = IBMPC_MAP;
2123+ break;
2124+ case 'K':
2125+ *charset = USER_MAP;
2126+ break;
2127+ }
2128+
2129+ if (vc->state.charset == which)
2130+ vc->vc_translate = set_translate(*charset, vc);
2131+}
2132+
21232133 /* console_lock is held */
21242134 static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
21252135 {
@@ -2142,13 +2152,15 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) · 16 unmodified lines
21422152 bs(vc);
21432153 return;
21442154 case 9:
2145− vc->vc_pos -= (vc->vc_x << 1);
2146− while (vc->vc_x < vc->vc_cols - 1) {
2147− vc->vc_x++;
2148− if (vc->vc_tab_stop[7 & (vc->vc_x >> 5)] & (1 << (vc->vc_x & 31)))
2149− break;
2150− }
2151− vc->vc_pos += (vc->vc_x << 1);
2155+ vc->vc_pos -= (vc->state.x << 1);
2156+
2157+ vc->state.x = find_next_bit(vc->vc_tab_stop,
2158+ min(vc->vc_cols - 1, VC_TABSTOPS_COUNT),
2159+ vc->state.x + 1);
2160+ if (vc->state.x >= VC_TABSTOPS_COUNT)
2161+ vc->state.x = vc->vc_cols - 1;
2162+
2163+ vc->vc_pos += (vc->state.x << 1);
21522164 notify_write(vc, '\t');
21532165 return;
21542166 case 10: case 11: case 12:
@@ -2160,13 +2172,13 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) · 5 unmodified lines
21602172 cr(vc);
21612173 return;
21622174 case 14:
2163− vc->vc_charset = 1;
2164− vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
2175+ vc->state.charset = 1;
2176+ vc->vc_translate = set_translate(vc->state.Gx_charset[1], vc);
21652177 vc->vc_disp_ctrl = 1;
21662178 return;
21672179 case 15:
2168− vc->vc_charset = 0;
2169− vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
2180+ vc->state.charset = 0;
2181+ vc->vc_translate = set_translate(vc->state.Gx_charset[0], vc);
21702182 vc->vc_disp_ctrl = 0;
21712183 return;
21722184 case 24: case 26:
@@ -2206,7 +2218,8 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) · 33 unmodified lines
22062218 lf(vc);
22072219 return;
22082220 case 'H':
2209− vc->vc_tab_stop[7 & (vc->vc_x >> 5)] |= (1 << (vc->vc_x & 31));
2221+ if (vc->state.x < VC_TABSTOPS_COUNT)
2222+ set_bit(vc->state.x, vc->vc_tab_stop);
22102223 return;
22112224 case 'Z':
22122225 respond_ID(tty);
@@ -2320,7 +2333,10 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) · 107 unmodified lines
23202333 case 'c':
23212334 if (vc->vc_priv == EPdec) {
23222335 if (vc->vc_par[0])
2323− vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16);
2336+ vc->vc_cursor_type =
2337+ CUR_MAKE(vc->vc_par[0],
2338+ vc->vc_par[1],
2339+ vc->vc_par[2]);
23242340 else
23252341 vc->vc_cursor_type = cur_default;
23262342 return;
@@ -2353,42 +2369,42 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) · 26 unmodified lines
23532369 case 'G': case '`':
23542370 if (vc->vc_par[0])
23552371 vc->vc_par[0]--;
2356− gotoxy(vc, vc->vc_par[0], vc->vc_y);
2372+ gotoxy(vc, vc->vc_par[0], vc->state.y);
23572373 return;
23582374 case 'A':
23592375 if (!vc->vc_par[0])
23602376 vc->vc_par[0]++;
2361− gotoxy(vc, vc->vc_x, vc->vc_y - vc->vc_par[0]);
2377+ gotoxy(vc, vc->state.x, vc->state.y - vc->vc_par[0]);
23622378 return;
23632379 case 'B': case 'e':
23642380 if (!vc->vc_par[0])
23652381 vc->vc_par[0]++;
2366− gotoxy(vc, vc->vc_x, vc->vc_y + vc->vc_par[0]);
2382+ gotoxy(vc, vc->state.x, vc->state.y + vc->vc_par[0]);
23672383 return;
23682384 case 'C': case 'a':
23692385 if (!vc->vc_par[0])
23702386 vc->vc_par[0]++;
2371− gotoxy(vc, vc->vc_x + vc->vc_par[0], vc->vc_y);
2387+ gotoxy(vc, vc->state.x + vc->vc_par[0], vc->state.y);
23722388 return;
23732389 case 'D':
23742390 if (!vc->vc_par[0])
23752391 vc->vc_par[0]++;
2376− gotoxy(vc, vc->vc_x - vc->vc_par[0], vc->vc_y);
2392+ gotoxy(vc, vc->state.x - vc->vc_par[0], vc->state.y);
23772393 return;
23782394 case 'E':
23792395 if (!vc->vc_par[0])
23802396 vc->vc_par[0]++;
2381− gotoxy(vc, 0, vc->vc_y + vc->vc_par[0]);
2397+ gotoxy(vc, 0, vc->state.y + vc->vc_par[0]);
23822398 return;
23832399 case 'F':
23842400 if (!vc->vc_par[0])
23852401 vc->vc_par[0]++;
2386− gotoxy(vc, 0, vc->vc_y - vc->vc_par[0]);
2402+ gotoxy(vc, 0, vc->state.y - vc->vc_par[0]);
23872403 return;
23882404 case 'd':
23892405 if (vc->vc_par[0])
23902406 vc->vc_par[0]--;
2391− gotoxay(vc, vc->vc_x ,vc->vc_par[0]);
2407+ gotoxay(vc, vc->state.x ,vc->vc_par[0]);
23922408 return;
23932409 case 'H': case 'f':
23942410 if (vc->vc_par[0])
@@ -2417,18 +2433,10 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) · 22 unmodified lines
24172433 respond_ID(tty);
24182434 return;
24192435 case 'g':
2420− if (!vc->vc_par[0])
2421− vc->vc_tab_stop[7 & (vc->vc_x >> 5)] &= ~(1 << (vc->vc_x & 31));
2422− else if (vc->vc_par[0] == 3) {
2423− vc->vc_tab_stop[0] =
2424− vc->vc_tab_stop[1] =
2425− vc->vc_tab_stop[2] =
2426− vc->vc_tab_stop[3] =
2427− vc->vc_tab_stop[4] =
2428− vc->vc_tab_stop[5] =
2429− vc->vc_tab_stop[6] =
2430− vc->vc_tab_stop[7] = 0;
2431− }
2436+ if (!vc->vc_par[0] && vc->state.x < VC_TABSTOPS_COUNT)
2437+ set_bit(vc->state.x, vc->vc_tab_stop);
2438+ else if (vc->vc_par[0] == 3)
2439+ bitmap_zero(vc->vc_tab_stop, VC_TABSTOPS_COUNT);
24322440 return;
24332441 case 'm':
24342442 csi_m(vc);
@@ -2502,29 +2510,11 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) · 67 unmodified lines
25022510 }
25032511 return;
25042512 case ESsetG0:
2505− if (c == '0')
2506− vc->vc_G0_charset = GRAF_MAP;
2507− else if (c == 'B')
2508− vc->vc_G0_charset = LAT1_MAP;
2509− else if (c == 'U')
2510− vc->vc_G0_charset = IBMPC_MAP;
2511− else if (c == 'K')
2512− vc->vc_G0_charset = USER_MAP;
2513− if (vc->vc_charset == 0)
2514− vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
2513+ vc_setGx(vc, 0, c);
25152514 vc->vc_state = ESnormal;
25162515 return;
25172516 case ESsetG1:
2518− if (c == '0')
2519− vc->vc_G1_charset = GRAF_MAP;
2520− else if (c == 'B')
2521− vc->vc_G1_charset = LAT1_MAP;
2522− else if (c == 'U')
2523− vc->vc_G1_charset = IBMPC_MAP;
2524− else if (c == 'K')
2525− vc->vc_G1_charset = USER_MAP;
2526− if (vc->vc_charset == 1)
2527− vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
2517+ vc_setGx(vc, 1, c);
25282518 vc->vc_state = ESnormal;
25292519 return;
25302520 case ESosc:
@@ -2536,7 +2526,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) · 5 unmodified lines
25362526
25372527 /* is_double_width() is based on the wcwidth() implementation by
25382528 * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
2539− * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
2529+ * Latest version: https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
25402530 */
25412531 struct interval {
25422532 uint32_t first;
@@ -2571,30 +2561,300 @@ static int is_double_width(uint32_t ucs) · 28 unmodified lines
25712561 sizeof(struct interval), ucs_cmp) != NULL;
25722562 }
25732563
2574−static void con_flush(struct vc_data *vc, unsigned long draw_from,
2575− unsigned long draw_to, int *draw_x)
2564+struct vc_draw_region {
2565+ unsigned long from, to;
2566+ int x;
2567+};
2568+
2569+static void con_flush(struct vc_data *vc, struct vc_draw_region *draw)
25762570 {
2577− if (*draw_x < 0)
2571+ if (draw->x < 0)
25782572 return;
25792573
2580− vc->vc_sw->con_putcs(vc, (u16 *)draw_from,
2581− (u16 *)draw_to - (u16 *)draw_from, vc->vc_y, *draw_x);
2582− *draw_x = -1;
2574+ vc->vc_sw->con_putcs(vc, (u16 *)draw->from,
2575+ (u16 *)draw->to - (u16 *)draw->from, vc->state.y,
2576+ draw->x);
2577+ draw->x = -1;
2578+}
2579+
2580+static inline int vc_translate_ascii(const struct vc_data *vc, int c)
2581+{
2582+ if (IS_ENABLED(CONFIG_CONSOLE_TRANSLATIONS)) {
2583+ if (vc->vc_toggle_meta)
2584+ c |= 0x80;
2585+
2586+ return vc->vc_translate[c];
2587+ }
2588+
2589+ return c;
2590+}
2591+
2592+
2593+/**
2594+ * vc_sanitize_unicode -- Replace invalid Unicode code points with U+FFFD
2595+ * @c: the received character, or U+FFFD for invalid sequences.
2596+ */
2597+static inline int vc_sanitize_unicode(const int c)
2598+{
2599+ if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
2600+ return 0xfffd;
2601+
2602+ return c;
2603+}
2604+
2605+/**
2606+ * vc_translate_unicode -- Combine UTF-8 into Unicode in @vc_utf_char
2607+ *
2608+ * @vc_utf_char is the being-constructed unicode character.
2609+ * @vc_utf_count is the number of continuation bytes still expected to arrive.
2610+ * @vc_npar is the number of continuation bytes arrived so far.
2611+ */
2612+static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan)
2613+{
2614+ static const u32 utf8_length_changes[] = {
2615+ 0x0000007f, 0x000007ff, 0x0000ffff,
2616+ 0x001fffff, 0x03ffffff, 0x7fffffff
2617+ };
2618+
2619+ /* Continuation byte received */
2620+ if ((c & 0xc0) == 0x80) {
2621+ /* Unexpected continuation byte? */
2622+ if (!vc->vc_utf_count)
2623+ return 0xfffd;
2624+
2625+ vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
2626+ vc->vc_npar++;
2627+ if (--vc->vc_utf_count)
2628+ goto need_more_bytes;
2629+
2630+ /* Got a whole character */
2631+ c = vc->vc_utf_char;
2632+ /* Reject overlong sequences */
2633+ if (c <= utf8_length_changes[vc->vc_npar - 1] ||
2634+ c > utf8_length_changes[vc->vc_npar])
2635+ return 0xfffd;
2636+
2637+ return vc_sanitize_unicode(c);
2638+ }
2639+
2640+ /* Single ASCII byte or first byte of a sequence received */
2641+ if (vc->vc_utf_count) {
2642+ /* Continuation byte expected */
2643+ *rescan = true;
2644+ vc->vc_utf_count = 0;
2645+ return 0xfffd;
2646+ }
2647+
2648+ /* Nothing to do if an ASCII byte was received */
2649+ if (c <= 0x7f)
2650+ return c;
2651+
2652+ /* First byte of a multibyte sequence received */
2653+ vc->vc_npar = 0;
2654+ if ((c & 0xe0) == 0xc0) {
2655+ vc->vc_utf_count = 1;
2656+ vc->vc_utf_char = (c & 0x1f);
2657+ } else if ((c & 0xf0) == 0xe0) {
2658+ vc->vc_utf_count = 2;
2659+ vc->vc_utf_char = (c & 0x0f);
2660+ } else if ((c & 0xf8) == 0xf0) {
2661+ vc->vc_utf_count = 3;
2662+ vc->vc_utf_char = (c & 0x07);
2663+ } else if ((c & 0xfc) == 0xf8) {
2664+ vc->vc_utf_count = 4;
2665+ vc->vc_utf_char = (c & 0x03);
2666+ } else if ((c & 0xfe) == 0xfc) {
2667+ vc->vc_utf_count = 5;
2668+ vc->vc_utf_char = (c & 0x01);
2669+ } else {
2670+ /* 254 and 255 are invalid */
2671+ return 0xfffd;
2672+ }
2673+
2674+need_more_bytes:
2675+ return -1;
2676+}
2677+
2678+static int vc_translate(struct vc_data *vc, int *c, bool *rescan)
2679+{
2680+ /* Do no translation at all in control states */
2681+ if (vc->vc_state != ESnormal)
2682+ return *c;
2683+
2684+ if (vc->vc_utf && !vc->vc_disp_ctrl)
2685+ return *c = vc_translate_unicode(vc, *c, rescan);
2686+
2687+ /* no utf or alternate charset mode */
2688+ return vc_translate_ascii(vc, *c);
2689+}
2690+
2691+static inline unsigned char vc_invert_attr(const struct vc_data *vc)
2692+{
2693+ if (!vc->vc_can_do_color)
2694+ return vc->vc_attr ^ 0x08;
2695+
2696+ if (vc->vc_hi_font_mask == 0x100)
2697+ return (vc->vc_attr & 0x11) |
2698+ ((vc->vc_attr & 0xe0) >> 4) |
2699+ ((vc->vc_attr & 0x0e) << 4);
2700+
2701+ return (vc->vc_attr & 0x88) |
2702+ ((vc->vc_attr & 0x70) >> 4) |
2703+ ((vc->vc_attr & 0x07) << 4);
2704+}
2705+
2706+static bool vc_is_control(struct vc_data *vc, int tc, int c)
2707+{
2708+ /*
2709+ * A bitmap for codes <32. A bit of 1 indicates that the code
2710+ * corresponding to that bit number invokes some special action (such
2711+ * as cursor movement) and should not be displayed as a glyph unless
2712+ * the disp_ctrl mode is explicitly enabled.
2713+ */
2714+ static const u32 CTRL_ACTION = 0x0d00ff81;
2715+ /* Cannot be overridden by disp_ctrl */
2716+ static const u32 CTRL_ALWAYS = 0x0800f501;
2717+
2718+ if (vc->vc_state != ESnormal)
2719+ return true;
2720+
2721+ if (!tc)
2722+ return true;
2723+
2724+ /*
2725+ * If the original code was a control character we only allow a glyph
2726+ * to be displayed if the code is not normally used (such as for cursor
2727+ * movement) or if the disp_ctrl mode has been explicitly enabled.
2728+ * Certain characters (as given by the CTRL_ALWAYS bitmap) are always
2729+ * displayed as control characters, as the console would be pretty
2730+ * useless without them; to display an arbitrary font position use the
2731+ * direct-to-font zone in UTF-8 mode.
2732+ */
2733+ if (c < 32) {
2734+ if (vc->vc_disp_ctrl)
2735+ return CTRL_ALWAYS & BIT(c);
2736+ else
2737+ return vc->vc_utf || (CTRL_ACTION & BIT(c));
2738+ }
2739+
2740+ if (c == 127 && !vc->vc_disp_ctrl)
2741+ return true;
2742+
2743+ if (c == 128 + 27)
2744+ return true;
2745+
2746+ return false;
2747+}
2748+
2749+static int vc_con_write_normal(struct vc_data *vc, int tc, int c,
2750+ struct vc_draw_region *draw)
2751+{
2752+ int next_c;
2753+ unsigned char vc_attr = vc->vc_attr;
2754+ u16 himask = vc->vc_hi_font_mask, charmask = himask ? 0x1ff : 0xff;
2755+ u8 width = 1;
2756+ bool inverse = false;
2757+
2758+ if (vc->vc_utf && !vc->vc_disp_ctrl) {
2759+ if (is_double_width(c))
2760+ width = 2;
2761+ }
2762+
2763+ /* Now try to find out how to display it */
2764+ tc = conv_uni_to_pc(vc, tc);
2765+ if (tc & ~charmask) {
2766+ if (tc == -1 || tc == -2)
2767+ return -1; /* nothing to display */
2768+
2769+ /* Glyph not found */
2770+ if ((!vc->vc_utf || vc->vc_disp_ctrl || c < 128) &&
2771+ !(c & ~charmask)) {
2772+ /*
2773+ * In legacy mode use the glyph we get by a 1:1
2774+ * mapping.
2775+ * This would make absolutely no sense with Unicode in
2776+ * mind, but do this for ASCII characters since a font
2777+ * may lack Unicode mapping info and we don't want to
2778+ * end up with having question marks only.
2779+ */
2780+ tc = c;
2781+ } else {
2782+ /*
2783+ * Display U+FFFD. If it's not found, display an inverse
2784+ * question mark.
2785+ */
2786+ tc = conv_uni_to_pc(vc, 0xfffd);
2787+ if (tc < 0) {
2788+ inverse = true;
2789+ tc = conv_uni_to_pc(vc, '?');
2790+ if (tc < 0)
2791+ tc = '?';
2792+
2793+ vc_attr = vc_invert_attr(vc);
2794+ con_flush(vc, draw);
2795+ }
2796+ }
2797+ }
2798+
2799+ next_c = c;
2800+ while (1) {
2801+ if (vc->vc_need_wrap || vc->vc_decim)
2802+ con_flush(vc, draw);
2803+ if (vc->vc_need_wrap) {
2804+ cr(vc);
2805+ lf(vc);
2806+ }
2807+ if (vc->vc_decim)
2808+ insert_char(vc, 1);
2809+ vc_uniscr_putc(vc, next_c);
2810+
2811+ if (himask)
2812+ tc = ((tc & 0x100) ? himask : 0) |
2813+ (tc & 0xff);
2814+ tc |= (vc_attr << 8) & ~himask;
2815+
2816+ scr_writew(tc, (u16 *)vc->vc_pos);
2817+
2818+ if (con_should_update(vc) && draw->x < 0) {
2819+ draw->x = vc->state.x;
2820+ draw->from = vc->vc_pos;
2821+ }
2822+ if (vc->state.x == vc->vc_cols - 1) {
2823+ vc->vc_need_wrap = vc->vc_decawm;
2824+ draw->to = vc->vc_pos + 2;
2825+ } else {
2826+ vc->state.x++;
2827+ draw->to = (vc->vc_pos += 2);
2828+ }
2829+
2830+ if (!--width)
2831+ break;
2832+
2833+ /* A space is printed in the second column */
2834+ tc = conv_uni_to_pc(vc, ' ');
2835+ if (tc < 0)
2836+ tc = ' ';
2837+ next_c = ' ';
2838+ }
2839+ notify_write(vc, c);
2840+
2841+ if (inverse)
2842+ con_flush(vc, draw);
2843+
2844+ return 0;
25832845 }
25842846
25852847 /* acquires console_lock */
25862848 static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
25872849 {
2588− int c, next_c, tc, ok, n = 0, draw_x = -1;
2850+ struct vc_draw_region draw = {
2851+ .x = -1,
2852+ };
2853+ int c, tc, n = 0;
25892854 unsigned int currcons;
2590− unsigned long draw_from = 0, draw_to = 0;
25912855 struct vc_data *vc;
2592− unsigned char vc_attr;
25932856 struct vt_notifier_param param;
2594− uint8_t rescan;
2595− uint8_t inverse;
2596− uint8_t width;
2597− u16 himask, charmask;
2857+ bool rescan;
25982858
25992859 if (in_interrupt())
26002860 return count;
@@ -2615,8 +2875,6 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co · 14 unmodified lines
26152875 return 0;
26162876 }
26172877
2618− himask = vc->vc_hi_font_mask;
2619− charmask = himask ? 0x1ff : 0xff;
26202878
26212879 /* undraw cursor first */
26222880 if (con_is_fg(vc))
@@ -2626,209 +2884,35 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co · 3 unmodified lines
26262884
26272885 while (!tty->stopped && count) {
26282886 int orig = *buf;
2629− c = orig;
26302887 buf++;
26312888 n++;
26322889 count--;
2633− rescan = 0;
2634− inverse = 0;
2635− width = 1;
2636−
2637− /* Do no translation at all in control states */
2638− if (vc->vc_state != ESnormal) {
2639− tc = c;
2640− } else if (vc->vc_utf && !vc->vc_disp_ctrl) {
2641− /* Combine UTF-8 into Unicode in vc_utf_char.
2642− * vc_utf_count is the number of continuation bytes still
2643− * expected to arrive.
2644− * vc_npar is the number of continuation bytes arrived so
2645− * far
2646− */
26472890 rescan_last_byte:
2648− if ((c & 0xc0) == 0x80) {
2649− /* Continuation byte received */
2650− static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff };
2651− if (vc->vc_utf_count) {
2652− vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
2653− vc->vc_npar++;
2654− if (--vc->vc_utf_count) {
2655− /* Still need some bytes */
2656− continue;
2657− }
2658− /* Got a whole character */
2659− c = vc->vc_utf_char;
2660− /* Reject overlong sequences */
2661− if (c <= utf8_length_changes[vc->vc_npar - 1] ||
2662− c > utf8_length_changes[vc->vc_npar])
2663− c = 0xfffd;
2664− } else {
2665− /* Unexpected continuation byte */
2666− vc->vc_utf_count = 0;
2667− c = 0xfffd;
2668− }
2669− } else {
2670− /* Single ASCII byte or first byte of a sequence received */
2671− if (vc->vc_utf_count) {
2672− /* Continuation byte expected */
2673− rescan = 1;
2674− vc->vc_utf_count = 0;
2675− c = 0xfffd;
2676− } else if (c > 0x7f) {
2677− /* First byte of a multibyte sequence received */
2678− vc->vc_npar = 0;
2679− if ((c & 0xe0) == 0xc0) {
2680− vc->vc_utf_count = 1;
2681− vc->vc_utf_char = (c & 0x1f);
2682− } else if ((c & 0xf0) == 0xe0) {
2683− vc->vc_utf_count = 2;
2684− vc->vc_utf_char = (c & 0x0f);
2685− } else if ((c & 0xf8) == 0xf0) {
2686− vc->vc_utf_count = 3;
2687− vc->vc_utf_char = (c & 0x07);
2688− } else if ((c & 0xfc) == 0xf8) {
2689− vc->vc_utf_count = 4;
2690− vc->vc_utf_char = (c & 0x03);
2691− } else if ((c & 0xfe) == 0xfc) {
2692− vc->vc_utf_count = 5;
2693− vc->vc_utf_char = (c & 0x01);
2694− } else {
2695− /* 254 and 255 are invalid */
2696− c = 0xfffd;
2697− }
2698− if (vc->vc_utf_count) {
2699− /* Still need some bytes */
2700− continue;
2701− }
2702− }
2703− /* Nothing to do if an ASCII byte was received */
2704− }
2705− /* End of UTF-8 decoding. */
2706− /* c is the received character, or U+FFFD for invalid sequences. */
2707− /* Replace invalid Unicode code points with U+FFFD too */
2708− if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
2709− c = 0xfffd;
2710− tc = c;
2711− } else { /* no utf or alternate charset mode */
2712− tc = vc_translate(vc, c);
2713− }
2891+ c = orig;
2892+ rescan = false;
2893+
2894+ tc = vc_translate(vc, &c, &rescan);
2895+ if (tc == -1)
2896+ continue;
27142897
27152898 param.c = tc;
27162899 if (atomic_notifier_call_chain(&vt_notifier_list, VT_PREWRITE,
27172900 &param) == NOTIFY_STOP)
27182901 continue;
27192902
2720− /* If the original code was a control character we
2721− * only allow a glyph to be displayed if the code is
2722− * not normally used (such as for cursor movement) or
2723− * if the disp_ctrl mode has been explicitly enabled.
2724− * Certain characters (as given by the CTRL_ALWAYS
2725− * bitmap) are always displayed as control characters,
2726− * as the console would be pretty useless without
2727− * them; to display an arbitrary font position use the
2728− * direct-to-font zone in UTF-8 mode.
2729− */
2730− ok = tc && (c >= 32 ||
2731− !(vc->vc_disp_ctrl ? (CTRL_ALWAYS >> c) & 1 :
2732− vc->vc_utf || ((CTRL_ACTION >> c) & 1)))
2733− && (c != 127 || vc->vc_disp_ctrl)
2734− && (c != 128+27);
2735−
2736− if (vc->vc_state == ESnormal && ok) {
2737− if (vc->vc_utf && !vc->vc_disp_ctrl) {
2738− if (is_double_width(c))
2739− width = 2;
2740− }
2741− /* Now try to find out how to display it */
2742− tc = conv_uni_to_pc(vc, tc);
2743− if (tc & ~charmask) {
2744− if (tc == -1 || tc == -2) {
2745− continue; /* nothing to display */
2746− }
2747− /* Glyph not found */
2748− if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) && !(c & ~charmask)) {
2749− /* In legacy mode use the glyph we get by a 1:1 mapping.
2750− This would make absolutely no sense with Unicode in mind,
2751− but do this for ASCII characters since a font may lack
2752− Unicode mapping info and we don't want to end up with
2753− having question marks only. */
2754− tc = c;
2755− } else {
2756− /* Display U+FFFD. If it's not found, display an inverse question mark. */
2757− tc = conv_uni_to_pc(vc, 0xfffd);
2758− if (tc < 0) {
2759− inverse = 1;
2760− tc = conv_uni_to_pc(vc, '?');
2761− if (tc < 0) tc = '?';
2762− }
2763− }
2764− }
2765−
2766− if (!inverse) {
2767− vc_attr = vc->vc_attr;
2768− } else {
2769− /* invert vc_attr */
2770− if (!vc->vc_can_do_color) {
2771− vc_attr = (vc->vc_attr) ^ 0x08;
2772− } else if (vc->vc_hi_font_mask == 0x100) {
2773− vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) & 0x0e) << 4);
2774− } else {
2775− vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4);
2776− }
2777− con_flush(vc, draw_from, draw_to, &draw_x);
2778− }
2779−
2780− next_c = c;
2781− while (1) {
2782− if (vc->vc_need_wrap || vc->vc_decim)
2783− con_flush(vc, draw_from, draw_to,
2784− &draw_x);
2785− if (vc->vc_need_wrap) {
2786− cr(vc);
2787− lf(vc);
2788− }
2789− if (vc->vc_decim)
2790− insert_char(vc, 1);
2791− vc_uniscr_putc(vc, next_c);
2792− scr_writew(himask ?
2793− ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
2794− (vc_attr << 8) + tc,
2795− (u16 *) vc->vc_pos);
2796− if (con_should_update(vc) && draw_x < 0) {
2797− draw_x = vc->vc_x;
2798− draw_from = vc->vc_pos;
2799− }
2800− if (vc->vc_x == vc->vc_cols - 1) {
2801− vc->vc_need_wrap = vc->vc_decawm;
2802− draw_to = vc->vc_pos + 2;
2803− } else {
2804− vc->vc_x++;
2805− draw_to = (vc->vc_pos += 2);
2806− }
2807−
2808− if (!--width) break;
2809−
2810− tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
2811− if (tc < 0) tc = ' ';
2812− next_c = ' ';
2813− }
2814− notify_write(vc, c);
2815−
2816− if (inverse)
2817− con_flush(vc, draw_from, draw_to, &draw_x);
2818−
2819− if (rescan) {
2820− rescan = 0;
2821− inverse = 0;
2822− width = 1;
2823− c = orig;
2824− goto rescan_last_byte;
2825− }
2903+ if (vc_is_control(vc, tc, c)) {
2904+ con_flush(vc, &draw);
2905+ do_con_trol(tty, vc, orig);
28262906 continue;
28272907 }
2828− con_flush(vc, draw_from, draw_to, &draw_x);
2829− do_con_trol(tty, vc, orig);
2908+
2909+ if (vc_con_write_normal(vc, tc, c, &draw) < 0)
2910+ continue;
2911+
2912+ if (rescan)
2913+ goto rescan_last_byte;
28302914 }
2831− con_flush(vc, draw_from, draw_to, &draw_x);
2915+ con_flush(vc, &draw);
28322916 vc_uniscr_debug_check(vc);
28332917 console_conditional_schedule();
28342918 notify_update(vc);
@@ -2978,25 +3062,25 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) · 143 unmodified lines
29783062 hide_cursor(vc);
29793063
29803064 start = (ushort *)vc->vc_pos;
2981− start_x = vc->vc_x;
3065+ start_x = vc->state.x;
29823066 cnt = 0;
29833067 while (count--) {
29843068 c = *b++;
29853069 if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
29863070 if (cnt && con_is_visible(vc))
2987− vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x);
3071+ vc->vc_sw->con_putcs(vc, start, cnt, vc->state.y, start_x);
29883072 cnt = 0;
29893073 if (c == 8) { /* backspace */
29903074 bs(vc);
29913075 start = (ushort *)vc->vc_pos;
2992− start_x = vc->vc_x;
3076+ start_x = vc->state.x;
29933077 continue;
29943078 }
29953079 if (c != 13)
29963080 lf(vc);
29973081 cr(vc);
29983082 start = (ushort *)vc->vc_pos;
2999− start_x = vc->vc_x;
3083+ start_x = vc->state.x;
30003084 if (c == 10 || c == 13)
30013085 continue;
30023086 }
@@ -3004,15 +3088,15 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) · 1 unmodified line
30043088 scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
30053089 notify_write(vc, c);
30063090 cnt++;
3007− if (vc->vc_x == vc->vc_cols - 1) {
3091+ if (vc->state.x == vc->vc_cols - 1) {
30083092 vc->vc_need_wrap = 1;
30093093 } else {
30103094 vc->vc_pos += 2;
3011− vc->vc_x++;
3095+ vc->state.x++;
30123096 }
30133097 }
30143098 if (cnt && con_is_visible(vc))
3015− vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x);
3099+ vc->vc_sw->con_putcs(vc, start, cnt, vc->state.y, start_x);
30163100 set_cursor(vc);
30173101 notify_update(vc);
30183102
@@ -3408,7 +3492,7 @@ static int __init con_init(void) · 389 unmodified lines
34083492 master_display_fg = vc = vc_cons[currcons].d;
34093493 set_origin(vc);
34103494 save_screen(vc);
3411− gotoxy(vc, vc->vc_x, vc->vc_y);
3495+ gotoxy(vc, vc->state.x, vc->state.y);
34123496 csi_J(vc, 0);
34133497 update_screen(vc);
34143498 pr_info("Console: %s %s %dx%d\n",
@@ -4687,8 +4771,8 @@ EXPORT_SYMBOL_GPL(screen_pos); · 1272 unmodified lines
46874771 void getconsxy(struct vc_data *vc, unsigned char *p)
46884772 {
46894773 /* clamp values if they don't fit */
4690− p[0] = min(vc->vc_x, 0xFFu);
4691− p[1] = min(vc->vc_y, 0xFFu);
4774+ p[0] = min(vc->state.x, 0xFFu);
4775+ p[1] = min(vc->state.y, 0xFFu);
46924776 }
46934777
46944778 void putconsxy(struct vc_data *vc, unsigned char *p)
drivers/tty/vt/vt_ioctl.c+557−552
@@ -241,136 +241,56 @@ int vt_waitactive(int n) · 240 unmodified lines
241241 #define GPLAST 0x3df
242242 #define GPNUM (GPLAST - GPFIRST + 1)
243243
244−
245−
246−static inline int
247−do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op)
248−{
249− struct consolefontdesc cfdarg;
250− int i;
251−
252− if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc)))
253− return -EFAULT;
254−
255− switch (cmd) {
256− case PIO_FONTX:
257− if (!perm)
258− return -EPERM;
259− op->op = KD_FONT_OP_SET;
260− op->flags = KD_FONT_FLAG_OLD;
261− op->width = 8;
262− op->height = cfdarg.charheight;
263− op->charcount = cfdarg.charcount;
264− op->data = cfdarg.chardata;
265− return con_font_op(vc_cons[fg_console].d, op);
266− case GIO_FONTX: {
267− op->op = KD_FONT_OP_GET;
268− op->flags = KD_FONT_FLAG_OLD;
269− op->width = 8;
270− op->height = cfdarg.charheight;
271− op->charcount = cfdarg.charcount;
272− op->data = cfdarg.chardata;
273− i = con_font_op(vc_cons[fg_console].d, op);
274− if (i)
275− return i;
276− cfdarg.charheight = op->height;
277− cfdarg.charcount = op->charcount;
278− if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc)))
279− return -EFAULT;
280− return 0;
281− }
282− }
283− return -EINVAL;
284−}
285−
286−static inline int
287−do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_data *vc)
244+/*
245+ * currently, setting the mode from KD_TEXT to KD_GRAPHICS doesn't do a whole
246+ * lot. i'm not sure if it should do any restoration of modes or what...
247+ *
248+ * XXX It should at least call into the driver, fbdev's definitely need to
249+ * restore their engine state. --BenH
250+ */
251+static int vt_kdsetmode(struct vc_data *vc, unsigned long mode)
288252 {
289− struct unimapdesc tmp;
290−
291− if (copy_from_user(&tmp, user_ud, sizeof tmp))
292− return -EFAULT;
293− switch (cmd) {
294− case PIO_UNIMAP:
295− if (!perm)
296− return -EPERM;
297− return con_set_unimap(vc, tmp.entry_ct, tmp.entries);
298− case GIO_UNIMAP:
299− if (!perm && fg_console != vc->vc_num)
300− return -EPERM;
301− return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp.entries);
253+ switch (mode) {
254+ case KD_GRAPHICS:
255+ break;
256+ case KD_TEXT0:
257+ case KD_TEXT1:
258+ mode = KD_TEXT;
259+ fallthrough;
260+ case KD_TEXT:
261+ break;
262+ default:
263+ return -EINVAL;
302264 }
303− return 0;
304−}
305−
306−/* deallocate a single console, if possible (leave 0) */
307−static int vt_disallocate(unsigned int vc_num)
308−{
309− struct vc_data *vc = NULL;
310− int ret = 0;
311−
312− console_lock();
313− if (vt_busy(vc_num))
314− ret = -EBUSY;
315− else if (vc_num)
316− vc = vc_deallocate(vc_num);
317− console_unlock();
318265
319− if (vc && vc_num >= MIN_NR_CONSOLES)
320− tty_port_put(&vc->port);
321−
322− return ret;
323−}
266+ /* FIXME: this needs the console lock extending */
267+ if (vc->vc_mode == mode)
268+ return 0;
324269
325−/* deallocate all unused consoles, but leave 0 */
326−static void vt_disallocate_all(void)
327−{
328− struct vc_data *vc[MAX_NR_CONSOLES];
329− int i;
270+ vc->vc_mode = mode;
271+ if (vc->vc_num != fg_console)
272+ return 0;
330273
274+ /* explicitly blank/unblank the screen if switching modes */
331275 console_lock();
332− for (i = 1; i < MAX_NR_CONSOLES; i++)
333− if (!vt_busy(i))
334− vc[i] = vc_deallocate(i);
335− else
336− vc[i] = NULL;
276+ if (mode == KD_TEXT)
277+ do_unblank_screen(1);
278+ else
279+ do_blank_screen(1);
337280 console_unlock();
338281
339− for (i = 1; i < MAX_NR_CONSOLES; i++) {
340− if (vc[i] && i >= MIN_NR_CONSOLES)
341− tty_port_put(&vc[i]->port);
342− }
282+ return 0;
343283 }
344284
345−
346−/*
347− * We handle the console-specific ioctl's here. We allow the
348− * capability to modify any console, not just the fg_console.
349− */
350−int vt_ioctl(struct tty_struct *tty,
351− unsigned int cmd, unsigned long arg)
285+static int vt_k_ioctl(struct tty_struct *tty, unsigned int cmd,
286+ unsigned long arg, bool perm)
352287 {
353288 struct vc_data *vc = tty->driver_data;
354− struct console_font_op op; /* used in multiple places here */
355− unsigned int console = vc->vc_num;
356− unsigned char ucval;
357− unsigned int uival;
358289 void __user *up = (void __user *)arg;
359− int i, perm;
360− int ret = 0;
290+ unsigned int console = vc->vc_num;
291+ int ret;
361292
362− /*
363− * To have permissions to do most of the vt ioctls, we either have
364− * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
365− */
366− perm = 0;
367− if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
368− perm = 1;
369−
370293 switch (cmd) {
371− case TIOCLINUX:
372− ret = tioclinux(tty, arg);
373− break;
374294 case KIOCSOUND:
375295 if (!perm)
376296 return -EPERM;
@@ -390,7 +310,7 @@ int vt_ioctl(struct tty_struct *tty, · 13 unmodified lines
390310 return -EPERM;
391311 {
392312 unsigned int ticks, count;
393−
313+
394314 /*
395315 * Generate the tone for the appropriate number of ticks.
396316 * If the time is zero, turn off sound ourselves.
@@ -407,9 +327,7 @@ int vt_ioctl(struct tty_struct *tty, · 10 unmodified lines
407327 /*
408328 * this is naïve.
409329 */
410− ucval = KB_101;
411− ret = put_user(ucval, (char __user *)arg);
412− break;
330+ return put_user(KB_101, (char __user *)arg);
413331
414332 /*
415333 * These cannot be implemented on any machine that implements
@@ -426,84 +344,45 @@ int vt_ioctl(struct tty_struct *tty, · 10 unmodified lines
426344 *
427345 * These are locked internally via sys_ioperm
428346 */
429− if (arg < GPFIRST || arg > GPLAST) {
430− ret = -EINVAL;
431− break;
432− }
433− ret = ksys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
434− break;
347+ if (arg < GPFIRST || arg > GPLAST)
348+ return -EINVAL;
349+
350+ return ksys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
435351
436352 case KDENABIO:
437353 case KDDISABIO:
438− ret = ksys_ioperm(GPFIRST, GPNUM,
354+ return ksys_ioperm(GPFIRST, GPNUM,
439355 (cmd == KDENABIO)) ? -ENXIO : 0;
440− break;
441356 #endif
442357
443358 /* Linux m68k/i386 interface for setting the keyboard delay/repeat rate */
444−
359+
445360 case KDKBDREP:
446361 {
447362 struct kbd_repeat kbrep;
448−
363+
449364 if (!capable(CAP_SYS_TTY_CONFIG))
450365 return -EPERM;
451366
452− if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) {
453− ret = -EFAULT;
454− break;
455− }
367+ if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat)))
368+ return -EFAULT;
369+
456370 ret = kbd_rate(&kbrep);
457371 if (ret)
458− break;
372+ return ret;
459373 if (copy_to_user(up, &kbrep, sizeof(struct kbd_repeat)))
460− ret = -EFAULT;
374+ return -EFAULT;
461375 break;
462376 }
463377
464378 case KDSETMODE:
465− /*
466− * currently, setting the mode from KD_TEXT to KD_GRAPHICS
467− * doesn't do a whole lot. i'm not sure if it should do any
468− * restoration of modes or what...
469− *
470− * XXX It should at least call into the driver, fbdev's definitely
471− * need to restore their engine state. --BenH
472− */
473379 if (!perm)
474380 return -EPERM;
475− switch (arg) {
476− case KD_GRAPHICS:
477− break;
478− case KD_TEXT0:
479− case KD_TEXT1:
480− arg = KD_TEXT;
481− case KD_TEXT:
482− break;
483− default:
484− ret = -EINVAL;
485− goto out;
486− }
487− /* FIXME: this needs the console lock extending */
488− if (vc->vc_mode == (unsigned char) arg)
489− break;
490− vc->vc_mode = (unsigned char) arg;
491− if (console != fg_console)
492− break;
493− /*
494− * explicitly blank/unblank the screen if switching modes
495− */
496− console_lock();
497− if (arg == KD_TEXT)
498− do_unblank_screen(1);
499− else
500− do_blank_screen(1);
501− console_unlock();
502− break;
381+
382+ return vt_kdsetmode(vc, arg);
503383
504384 case KDGETMODE:
505− uival = vc->vc_mode;
506− goto setint;
385+ return put_user(vc->vc_mode, (int __user *)arg);
507386
508387 case KDMAPDISP:
509388 case KDUNMAPDISP:
@@ -511,51 +390,42 @@ int vt_ioctl(struct tty_struct *tty, · 1 unmodified line
511390 * these work like a combination of mmap and KDENABIO.
512391 * this could be easily finished.
513392 */
514− ret = -EINVAL;
515− break;
393+ return -EINVAL;
516394
517395 case KDSKBMODE:
518396 if (!perm)
519397 return -EPERM;
520398 ret = vt_do_kdskbmode(console, arg);
521− if (ret == 0)
522− tty_ldisc_flush(tty);
399+ if (ret)
400+ return ret;
401+ tty_ldisc_flush(tty);
523402 break;
524403
525404 case KDGKBMODE:
526− uival = vt_do_kdgkbmode(console);
527− ret = put_user(uival, (int __user *)arg);
528− break;
405+ return put_user(vt_do_kdgkbmode(console), (int __user *)arg);
529406
530407 /* this could be folded into KDSKBMODE, but for compatibility
531408 reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
532409 case KDSKBMETA:
533− ret = vt_do_kdskbmeta(console, arg);
534− break;
410+ return vt_do_kdskbmeta(console, arg);
535411
536412 case KDGKBMETA:
537413 /* FIXME: should review whether this is worth locking */
538− uival = vt_do_kdgkbmeta(console);
539− setint:
540− ret = put_user(uival, (int __user *)arg);
541− break;
414+ return put_user(vt_do_kdgkbmeta(console), (int __user *)arg);
542415
543416 case KDGETKEYCODE:
544417 case KDSETKEYCODE:
545418 if(!capable(CAP_SYS_TTY_CONFIG))
546419 perm = 0;
547− ret = vt_do_kbkeycode_ioctl(cmd, up, perm);
548− break;
420+ return vt_do_kbkeycode_ioctl(cmd, up, perm);
549421
550422 case KDGKBENT:
551423 case KDSKBENT:
552− ret = vt_do_kdsk_ioctl(cmd, up, perm, console);
553− break;
424+ return vt_do_kdsk_ioctl(cmd, up, perm, console);
554425
555426 case KDGKBSENT:
556427 case KDSKBSENT:
557− ret = vt_do_kdgkb_ioctl(cmd, up, perm);
558− break;
428+ return vt_do_kdgkb_ioctl(cmd, up, perm);
559429
560430 /* Diacritical processing. Handled in keyboard.c as it has
561431 to operate on the keyboard locks and structures */
@@ -563,8 +433,7 @@ int vt_ioctl(struct tty_struct *tty, · 1 unmodified line
563433 case KDGKBDIACRUC:
564434 case KDSKBDIACR:
565435 case KDSKBDIACRUC:
566− ret = vt_do_diacrit(cmd, up, perm);
567− break;
436+ return vt_do_diacrit(cmd, up, perm);
568437
569438 /* the ioctls below read/set the flags usually shown in the leds */
570439 /* don't use them - they will go away without warning */
@@ -572,8 +441,7 @@ int vt_ioctl(struct tty_struct *tty, · 1 unmodified line
572441 case KDSKBLED:
573442 case KDGETLED:
574443 case KDSETLED:
575− ret = vt_do_kdskled(console, cmd, arg, perm);
576− break;
444+ return vt_do_kdskled(console, cmd, arg, perm);
577445
578446 /*
579447 * A process can indicate its willingness to accept signals
@@ -583,161 +451,504 @@ int vt_ioctl(struct tty_struct *tty, · 3 unmodified lines
583451 * See also the kbrequest field of inittab(5).
584452 */
585453 case KDSIGACCEPT:
586− {
587454 if (!perm || !capable(CAP_KILL))
588455 return -EPERM;
589456 if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
590− ret = -EINVAL;
591− else {
592− spin_lock_irq(&vt_spawn_con.lock);
593− put_pid(vt_spawn_con.pid);
594− vt_spawn_con.pid = get_pid(task_pid(current));
595− vt_spawn_con.sig = arg;
596− spin_unlock_irq(&vt_spawn_con.lock);
597− }
457+ return -EINVAL;
458+
459+ spin_lock_irq(&vt_spawn_con.lock);
460+ put_pid(vt_spawn_con.pid);
461+ vt_spawn_con.pid = get_pid(task_pid(current));
462+ vt_spawn_con.sig = arg;
463+ spin_unlock_irq(&vt_spawn_con.lock);
598464 break;
599− }
600465
601− case VT_SETMODE:
602− {
603− struct vt_mode tmp;
466+ case KDFONTOP: {
467+ struct console_font_op op;
604468
605− if (!perm)
469+ if (copy_from_user(&op, up, sizeof(op)))
470+ return -EFAULT;
471+ if (!perm && op.op != KD_FONT_OP_GET)
606472 return -EPERM;
607− if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) {
608− ret = -EFAULT;
609− goto out;
610− }
611− if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) {
612− ret = -EINVAL;
613− goto out;
614− }
615− console_lock();
616− vc->vt_mode = tmp;
617− /* the frsig is ignored, so we set it to 0 */
618− vc->vt_mode.frsig = 0;
619− put_pid(vc->vt_pid);
620− vc->vt_pid = get_pid(task_pid(current));
621− /* no switch is required -- saw@shade.msu.ru */
622− vc->vt_newvt = -1;
623− console_unlock();
473+ ret = con_font_op(vc, &op);
474+ if (ret)
475+ return ret;
476+ if (copy_to_user(up, &op, sizeof(op)))
477+ return -EFAULT;
624478 break;
625479 }
626480
627− case VT_GETMODE:
628− {
629− struct vt_mode tmp;
630− int rc;
481+ default:
482+ return -ENOIOCTLCMD;
483+ }
631484
632− console_lock();
633− memcpy(&tmp, &vc->vt_mode, sizeof(struct vt_mode));
634− console_unlock();
485+ return 0;
486+}
635487
636− rc = copy_to_user(up, &tmp, sizeof(struct vt_mode));
637− if (rc)
638− ret = -EFAULT;
639− break;
640− }
488+static inline int do_fontx_ioctl(int cmd,
489+ struct consolefontdesc __user *user_cfd,
490+ struct console_font_op *op)
491+{
492+ struct consolefontdesc cfdarg;
493+ int i;
641494
642− /*
643− * Returns global vt state. Note that VT 0 is always open, since
644− * it's an alias for the current VT, and people can't use it here.
645− * We cannot return state for more than 16 VTs, since v_state is short.
646− */
647− case VT_GETSTATE:
648− {
649− struct vt_stat __user *vtstat = up;
650− unsigned short state, mask;
495+ if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc)))
496+ return -EFAULT;
651497
652− if (put_user(fg_console + 1, &vtstat->v_active))
653− ret = -EFAULT;
654− else {
655− state = 1; /* /dev/tty0 is always open */
656− console_lock(); /* required by vt_in_use() */
657− for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask;
658− ++i, mask <<= 1)
659− if (vt_in_use(i))
660− state |= mask;
661− console_unlock();
662− ret = put_user(state, &vtstat->v_state);
498+ switch (cmd) {
499+ case PIO_FONTX:
500+ op->op = KD_FONT_OP_SET;
501+ op->flags = KD_FONT_FLAG_OLD;
502+ op->width = 8;
503+ op->height = cfdarg.charheight;
504+ op->charcount = cfdarg.charcount;
505+ op->data = cfdarg.chardata;
506+ return con_font_op(vc_cons[fg_console].d, op);
507+ case GIO_FONTX: {
508+ op->op = KD_FONT_OP_GET;
509+ op->flags = KD_FONT_FLAG_OLD;
510+ op->width = 8;
511+ op->height = cfdarg.charheight;
512+ op->charcount = cfdarg.charcount;
513+ op->data = cfdarg.chardata;
514+ i = con_font_op(vc_cons[fg_console].d, op);
515+ if (i)
516+ return i;
517+ cfdarg.charheight = op->height;
518+ cfdarg.charcount = op->charcount;
519+ if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc)))
520+ return -EFAULT;
521+ return 0;
663522 }
664− break;
665523 }
524+ return -EINVAL;
525+}
666526
667− /*
668− * Returns the first available (non-opened) console.
669− */
670− case VT_OPENQRY:
671− console_lock(); /* required by vt_in_use() */
672− for (i = 0; i < MAX_NR_CONSOLES; ++i)
673− if (!vt_in_use(i))
674− break;
675− console_unlock();
676− uival = i < MAX_NR_CONSOLES ? (i+1) : -1;
677− goto setint;
527+static int vt_io_fontreset(struct console_font_op *op)
528+{
529+ int ret;
678530
679− /*
680− * ioctl(fd, VT_ACTIVATE, num) will cause us to switch to vt # num,
681− * with num >= 1 (switches to vt 0, our console, are not allowed, just
682− * to preserve sanity).
683− */
684− case VT_ACTIVATE:
531+ if (__is_defined(BROKEN_GRAPHICS_PROGRAMS)) {
532+ /*
533+ * With BROKEN_GRAPHICS_PROGRAMS defined, the default font is
534+ * not saved.
535+ */
536+ return -ENOSYS;
537+ }
538+
539+ op->op = KD_FONT_OP_SET_DEFAULT;
540+ op->data = NULL;
541+ ret = con_font_op(vc_cons[fg_console].d, op);
542+ if (ret)
543+ return ret;
544+
545+ console_lock();
546+ con_set_default_unimap(vc_cons[fg_console].d);
547+ console_unlock();
548+
549+ return 0;
550+}
551+
552+static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud,
553+ struct vc_data *vc)
554+{
555+ struct unimapdesc tmp;
556+
557+ if (copy_from_user(&tmp, user_ud, sizeof tmp))
558+ return -EFAULT;
559+ switch (cmd) {
560+ case PIO_UNIMAP:
561+ return con_set_unimap(vc, tmp.entry_ct, tmp.entries);
562+ case GIO_UNIMAP:
563+ if (fg_console != vc->vc_num)
564+ return -EPERM;
565+ return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct),
566+ tmp.entries);
567+ }
568+ return 0;
569+}
570+
571+static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up,
572+ bool perm)
573+{
574+ struct console_font_op op; /* used in multiple places here */
575+
576+ switch (cmd) {
577+ case PIO_FONT:
685578 if (!perm)
686579 return -EPERM;
687− if (arg == 0 || arg > MAX_NR_CONSOLES)
688− ret = -ENXIO;
689− else {
690− arg--;
691− console_lock();
692− ret = vc_allocate(arg);
693− console_unlock();
694− if (ret)
695− break;
696− set_console(arg);
697− }
698− break;
580+ op.op = KD_FONT_OP_SET;
581+ op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */
582+ op.width = 8;
583+ op.height = 0;
584+ op.charcount = 256;
585+ op.data = up;
586+ return con_font_op(vc_cons[fg_console].d, &op);
699587
700− case VT_SETACTIVATE:
701− {
702− struct vt_setactivate vsa;
588+ case GIO_FONT:
589+ op.op = KD_FONT_OP_GET;
590+ op.flags = KD_FONT_FLAG_OLD;
591+ op.width = 8;
592+ op.height = 32;
593+ op.charcount = 256;
594+ op.data = up;
595+ return con_font_op(vc_cons[fg_console].d, &op);
596+
597+ case PIO_CMAP:
598+ if (!perm)
599+ return -EPERM;
600+ return con_set_cmap(up);
703601
602+ case GIO_CMAP:
603+ return con_get_cmap(up);
604+
605+ case PIO_FONTX:
606+ if (!perm)
607+ return -EPERM;
608+
609+ fallthrough;
610+ case GIO_FONTX:
611+ return do_fontx_ioctl(cmd, up, &op);
612+
613+ case PIO_FONTRESET:
614+ if (!perm)
615+ return -EPERM;
616+
617+ return vt_io_fontreset(&op);
618+
619+ case PIO_SCRNMAP:
620+ if (!perm)
621+ return -EPERM;
622+ return con_set_trans_old(up);
623+
624+ case GIO_SCRNMAP:
625+ return con_get_trans_old(up);
626+
627+ case PIO_UNISCRNMAP:
628+ if (!perm)
629+ return -EPERM;
630+ return con_set_trans_new(up);
631+
632+ case GIO_UNISCRNMAP:
633+ return con_get_trans_new(up);
634+
635+ case PIO_UNIMAPCLR:
704636 if (!perm)
705637 return -EPERM;
638+ con_clear_unimap(vc);
639+ break;
640+
641+ case PIO_UNIMAP:
642+ case GIO_UNIMAP:
643+ if (!perm)
644+ return -EPERM;
645+
646+ return do_unimap_ioctl(cmd, up, vc);
647+
648+ default:
649+ return -ENOIOCTLCMD;
650+ }
651+
652+ return 0;
653+}
654+
655+static int vt_reldisp(struct vc_data *vc, unsigned int swtch)
656+{
657+ int newvt, ret;
658+
659+ if (vc->vt_mode.mode != VT_PROCESS)
660+ return -EINVAL;
661+
662+ /* Switched-to response */
663+ if (vc->vt_newvt < 0) {
664+ /* If it's just an ACK, ignore it */
665+ return swtch == VT_ACKACQ ? 0 : -EINVAL;
666+ }
667+
668+ /* Switching-from response */
669+ if (swtch == 0) {
670+ /* Switch disallowed, so forget we were trying to do it. */
671+ vc->vt_newvt = -1;
672+ return 0;
673+ }
674+
675+ /* The current vt has been released, so complete the switch. */
676+ newvt = vc->vt_newvt;
677+ vc->vt_newvt = -1;
678+ ret = vc_allocate(newvt);
679+ if (ret)
680+ return ret;
706681
707− if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
708− sizeof(struct vt_setactivate))) {
709− ret = -EFAULT;
710− goto out;
682+ /*
683+ * When we actually do the console switch, make sure we are atomic with
684+ * respect to other console switches..
685+ */
686+ complete_change_console(vc_cons[newvt].d);
687+
688+ return 0;
689+}
690+
691+static int vt_setactivate(struct vt_setactivate __user *sa)
692+{
693+ struct vt_setactivate vsa;
694+ struct vc_data *nvc;
695+ int ret;
696+
697+ if (copy_from_user(&vsa, sa, sizeof(vsa)))
698+ return -EFAULT;
699+ if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
700+ return -ENXIO;
701+
702+ vsa.console = array_index_nospec(vsa.console, MAX_NR_CONSOLES + 1);
703+ vsa.console--;
704+ console_lock();
705+ ret = vc_allocate(vsa.console);
706+ if (ret) {
707+ console_unlock();
708+ return ret;
709+ }
710+
711+ /*
712+ * This is safe providing we don't drop the console sem between
713+ * vc_allocate and finishing referencing nvc.
714+ */
715+ nvc = vc_cons[vsa.console].d;
716+ nvc->vt_mode = vsa.mode;
717+ nvc->vt_mode.frsig = 0;
718+ put_pid(nvc->vt_pid);
719+ nvc->vt_pid = get_pid(task_pid(current));
720+ console_unlock();
721+
722+ /* Commence switch and lock */
723+ /* Review set_console locks */
724+ set_console(vsa.console);
725+
726+ return 0;
727+}
728+
729+/* deallocate a single console, if possible (leave 0) */
730+static int vt_disallocate(unsigned int vc_num)
731+{
732+ struct vc_data *vc = NULL;
733+ int ret = 0;
734+
735+ console_lock();
736+ if (vt_busy(vc_num))
737+ ret = -EBUSY;
738+ else if (vc_num)
739+ vc = vc_deallocate(vc_num);
740+ console_unlock();
741+
742+ if (vc && vc_num >= MIN_NR_CONSOLES)
743+ tty_port_put(&vc->port);
744+
745+ return ret;
746+}
747+
748+/* deallocate all unused consoles, but leave 0 */
749+static void vt_disallocate_all(void)
750+{
751+ struct vc_data *vc[MAX_NR_CONSOLES];
752+ int i;
753+
754+ console_lock();
755+ for (i = 1; i < MAX_NR_CONSOLES; i++)
756+ if (!vt_busy(i))
757+ vc[i] = vc_deallocate(i);
758+ else
759+ vc[i] = NULL;
760+ console_unlock();
761+
762+ for (i = 1; i < MAX_NR_CONSOLES; i++) {
763+ if (vc[i] && i >= MIN_NR_CONSOLES)
764+ tty_port_put(&vc[i]->port);
765+ }
766+}
767+
768+static int vt_resizex(struct vc_data *vc, struct vt_consize __user *cs)
769+{
770+ struct vt_consize v;
771+ int i;
772+
773+ if (copy_from_user(&v, cs, sizeof(struct vt_consize)))
774+ return -EFAULT;
775+
776+ /* FIXME: Should check the copies properly */
777+ if (!v.v_vlin)
778+ v.v_vlin = vc->vc_scan_lines;
779+
780+ if (v.v_clin) {
781+ int rows = v.v_vlin / v.v_clin;
782+ if (v.v_rows != rows) {
783+ if (v.v_rows) /* Parameters don't add up */
784+ return -EINVAL;
785+ v.v_rows = rows;
711786 }
712− if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
713− ret = -ENXIO;
714− else {
715− vsa.console = array_index_nospec(vsa.console,
716− MAX_NR_CONSOLES + 1);
717− vsa.console--;
718− console_lock();
719− ret = vc_allocate(vsa.console);
720− if (ret == 0) {
721− struct vc_data *nvc;
722− /* This is safe providing we don't drop the
723− console sem between vc_allocate and
724− finishing referencing nvc */
725− nvc = vc_cons[vsa.console].d;
726− nvc->vt_mode = vsa.mode;
727− nvc->vt_mode.frsig = 0;
728− put_pid(nvc->vt_pid);
729− nvc->vt_pid = get_pid(task_pid(current));
730− }
731− console_unlock();
732− if (ret)
733− break;
734− /* Commence switch and lock */
735− /* Review set_console locks */
736− set_console(vsa.console);
787+ }
788+
789+ if (v.v_vcol && v.v_ccol) {
790+ int cols = v.v_vcol / v.v_ccol;
791+ if (v.v_cols != cols) {
792+ if (v.v_cols)
793+ return -EINVAL;
794+ v.v_cols = cols;
737795 }
796+ }
797+
798+ if (v.v_clin > 32)
799+ return -EINVAL;
800+
801+ for (i = 0; i < MAX_NR_CONSOLES; i++) {
802+ struct vc_data *vcp;
803+
804+ if (!vc_cons[i].d)
805+ continue;
806+ console_lock();
807+ vcp = vc_cons[i].d;
808+ if (vcp) {
809+ if (v.v_vlin)
810+ vcp->vc_scan_lines = v.v_vlin;
811+ if (v.v_clin)
812+ vcp->vc_font.height = v.v_clin;
813+ vcp->vc_resize_user = 1;
814+ vc_resize(vcp, v.v_cols, v.v_rows);
815+ }
816+ console_unlock();
817+ }
818+
819+ return 0;
820+}
821+
822+/*
823+ * We handle the console-specific ioctl's here. We allow the
824+ * capability to modify any console, not just the fg_console.
825+ */
826+int vt_ioctl(struct tty_struct *tty,
827+ unsigned int cmd, unsigned long arg)
828+{
829+ struct vc_data *vc = tty->driver_data;
830+ void __user *up = (void __user *)arg;
831+ int i, perm;
832+ int ret;
833+
834+ /*
835+ * To have permissions to do most of the vt ioctls, we either have
836+ * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
837+ */
838+ perm = 0;
839+ if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
840+ perm = 1;
841+
842+ ret = vt_k_ioctl(tty, cmd, arg, perm);
843+ if (ret != -ENOIOCTLCMD)
844+ return ret;
845+
846+ ret = vt_io_ioctl(vc, cmd, up, perm);
847+ if (ret != -ENOIOCTLCMD)
848+ return ret;
849+
850+ switch (cmd) {
851+ case TIOCLINUX:
852+ return tioclinux(tty, arg);
853+ case VT_SETMODE:
854+ {
855+ struct vt_mode tmp;
856+
857+ if (!perm)
858+ return -EPERM;
859+ if (copy_from_user(&tmp, up, sizeof(struct vt_mode)))
860+ return -EFAULT;
861+ if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS)
862+ return -EINVAL;
863+
864+ console_lock();
865+ vc->vt_mode = tmp;
866+ /* the frsig is ignored, so we set it to 0 */
867+ vc->vt_mode.frsig = 0;
868+ put_pid(vc->vt_pid);
869+ vc->vt_pid = get_pid(task_pid(current));
870+ /* no switch is required -- saw@shade.msu.ru */
871+ vc->vt_newvt = -1;
872+ console_unlock();
873+ break;
874+ }
875+
876+ case VT_GETMODE:
877+ {
878+ struct vt_mode tmp;
879+ int rc;
880+
881+ console_lock();
882+ memcpy(&tmp, &vc->vt_mode, sizeof(struct vt_mode));
883+ console_unlock();
884+
885+ rc = copy_to_user(up, &tmp, sizeof(struct vt_mode));
886+ if (rc)
887+ return -EFAULT;
738888 break;
739889 }
740890
891+ /*
892+ * Returns global vt state. Note that VT 0 is always open, since
893+ * it's an alias for the current VT, and people can't use it here.
894+ * We cannot return state for more than 16 VTs, since v_state is short.
895+ */
896+ case VT_GETSTATE:
897+ {
898+ struct vt_stat __user *vtstat = up;
899+ unsigned short state, mask;
900+
901+ if (put_user(fg_console + 1, &vtstat->v_active))
902+ return -EFAULT;
903+
904+ state = 1; /* /dev/tty0 is always open */
905+ console_lock(); /* required by vt_in_use() */
906+ for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask;
907+ ++i, mask <<= 1)
908+ if (vt_in_use(i))
909+ state |= mask;
910+ console_unlock();
911+ return put_user(state, &vtstat->v_state);
912+ }
913+
914+ /*
915+ * Returns the first available (non-opened) console.
916+ */
917+ case VT_OPENQRY:
918+ console_lock(); /* required by vt_in_use() */
919+ for (i = 0; i < MAX_NR_CONSOLES; ++i)
920+ if (!vt_in_use(i))
921+ break;
922+ console_unlock();
923+ i = i < MAX_NR_CONSOLES ? (i+1) : -1;
924+ return put_user(i, (int __user *)arg);
925+
926+ /*
927+ * ioctl(fd, VT_ACTIVATE, num) will cause us to switch to vt # num,
928+ * with num >= 1 (switches to vt 0, our console, are not allowed, just
929+ * to preserve sanity).
930+ */
931+ case VT_ACTIVATE:
932+ if (!perm)
933+ return -EPERM;
934+ if (arg == 0 || arg > MAX_NR_CONSOLES)
935+ return -ENXIO;
936+
937+ arg--;
938+ console_lock();
939+ ret = vc_allocate(arg);
940+ console_unlock();
941+ if (ret)
942+ return ret;
943+ set_console(arg);
944+ break;
945+
946+ case VT_SETACTIVATE:
947+ if (!perm)
948+ return -EPERM;
949+
950+ return vt_setactivate(up);
951+
741952 /*
742953 * wait until the specified VT has been activated
743954 */
@@ -745,10 +956,8 @@ int vt_ioctl(struct tty_struct *tty, · 1 unmodified line
745956 if (!perm)
746957 return -EPERM;
747958 if (arg == 0 || arg > MAX_NR_CONSOLES)
748− ret = -ENXIO;
749− else
750− ret = vt_waitactive(arg);
751− break;
959+ return -ENXIO;
960+ return vt_waitactive(arg);
752961
753962 /*
754963 * If a vt is under process control, the kernel will not switch to it
@@ -765,258 +974,56 @@ int vt_ioctl(struct tty_struct *tty, · 10 unmodified lines
765974 return -EPERM;
766975
767976 console_lock();
768− if (vc->vt_mode.mode != VT_PROCESS) {
769− console_unlock();
770− ret = -EINVAL;
771− break;
772− }
773− /*
774− * Switching-from response
775− */
776− if (vc->vt_newvt >= 0) {
777− if (arg == 0)
778− /*
779− * Switch disallowed, so forget we were trying
780− * to do it.
781− */
782− vc->vt_newvt = -1;
783−
784− else {
785− /*
786− * The current vt has been released, so
787− * complete the switch.
788− */
789− int newvt;
790− newvt = vc->vt_newvt;
791− vc->vt_newvt = -1;
792− ret = vc_allocate(newvt);
793− if (ret) {
794− console_unlock();
795− break;
796− }
797− /*
798− * When we actually do the console switch,
799− * make sure we are atomic with respect to
800− * other console switches..
801− */
802− complete_change_console(vc_cons[newvt].d);
803− }
804− } else {
805− /*
806− * Switched-to response
807− */
808− /*
809− * If it's just an ACK, ignore it
810− */
811− if (arg != VT_ACKACQ)
812− ret = -EINVAL;
813− }
977+ ret = vt_reldisp(vc, arg);
814978 console_unlock();
815− break;
979+
980+ return ret;
981+
816982
817983 /*
818984 * Disallocate memory associated to VT (but leave VT1)
819985 */
820986 case VT_DISALLOCATE:
821− if (arg > MAX_NR_CONSOLES) {
822− ret = -ENXIO;
823− break;
824− }
987+ if (arg > MAX_NR_CONSOLES)
988+ return -ENXIO;
989+
825990 if (arg == 0)
826991 vt_disallocate_all();
827992 else
828− ret = vt_disallocate(--arg);
993+ return vt_disallocate(--arg);
829994 break;
830995
831996 case VT_RESIZE:
832997 {
833998 struct vt_sizes __user *vtsizes = up;
834999 struct vc_data *vc;
835−
8361000 ushort ll,cc;
1001+
8371002 if (!perm)
8381003 return -EPERM;
8391004 if (get_user(ll, &vtsizes->v_rows) ||
8401005 get_user(cc, &vtsizes->v_cols))
841− ret = -EFAULT;
842− else {
843− console_lock();
844− for (i = 0; i < MAX_NR_CONSOLES; i++) {
845− vc = vc_cons[i].d;
846−
847− if (vc) {
848− vc->vc_resize_user = 1;
849− /* FIXME: review v tty lock */
850− vc_resize(vc_cons[i].d, cc, ll);
851− }
852− }
853− console_unlock();
854− }
855− break;
856− }
857−
858− case VT_RESIZEX:
859− {
860− struct vt_consize v;
861− if (!perm)
862− return -EPERM;
863− if (copy_from_user(&v, up, sizeof(struct vt_consize)))
8641006 return -EFAULT;
865− /* FIXME: Should check the copies properly */
866− if (!v.v_vlin)
867− v.v_vlin = vc->vc_scan_lines;
868− if (v.v_clin) {
869− int rows = v.v_vlin/v.v_clin;
870− if (v.v_rows != rows) {
871− if (v.v_rows) /* Parameters don't add up */
872− return -EINVAL;
873− v.v_rows = rows;
874− }
875− }
876− if (v.v_vcol && v.v_ccol) {
877− int cols = v.v_vcol/v.v_ccol;
878− if (v.v_cols != cols) {
879− if (v.v_cols)
880− return -EINVAL;
881− v.v_cols = cols;
882− }
883− }
884−
885− if (v.v_clin > 32)
886− return -EINVAL;
8871007
1008+ console_lock();
8881009 for (i = 0; i < MAX_NR_CONSOLES; i++) {
889− struct vc_data *vcp;
890−
891− if (!vc_cons[i].d)
892− continue;
893− console_lock();
894− vcp = vc_cons[i].d;
895− if (vcp) {
896− if (v.v_vlin)
897− vcp->vc_scan_lines = v.v_vlin;
898− if (v.v_clin)
899− vcp->vc_font.height = v.v_clin;
900− vcp->vc_resize_user = 1;
901− vc_resize(vcp, v.v_cols, v.v_rows);
1010+ vc = vc_cons[i].d;
1011+
1012+ if (vc) {
1013+ vc->vc_resize_user = 1;
1014+ /* FIXME: review v tty lock */
1015+ vc_resize(vc_cons[i].d, cc, ll);
9021016 }
903− console_unlock();
9041017 }
905− break;
906− }
907−
908− case PIO_FONT: {
909− if (!perm)
910− return -EPERM;
911− op.op = KD_FONT_OP_SET;
912− op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */
913− op.width = 8;
914− op.height = 0;
915− op.charcount = 256;
916− op.data = up;
917− ret = con_font_op(vc_cons[fg_console].d, &op);
918− break;
919− }
920−
921− case GIO_FONT: {
922− op.op = KD_FONT_OP_GET;
923− op.flags = KD_FONT_FLAG_OLD;
924− op.width = 8;
925− op.height = 32;
926− op.charcount = 256;
927− op.data = up;
928− ret = con_font_op(vc_cons[fg_console].d, &op);
929− break;
930− }
931−
932− case PIO_CMAP:
933− if (!perm)
934− ret = -EPERM;
935− else
936− ret = con_set_cmap(up);
937− break;
938−
939− case GIO_CMAP:
940− ret = con_get_cmap(up);
941− break;
942−
943− case PIO_FONTX:
944− case GIO_FONTX:
945− ret = do_fontx_ioctl(cmd, up, perm, &op);
946− break;
947−
948− case PIO_FONTRESET:
949− {
950− if (!perm)
951− return -EPERM;
952−
953−#ifdef BROKEN_GRAPHICS_PROGRAMS
954− /* With BROKEN_GRAPHICS_PROGRAMS defined, the default
955− font is not saved. */
956− ret = -ENOSYS;
957− break;
958−#else
959− {
960− op.op = KD_FONT_OP_SET_DEFAULT;
961− op.data = NULL;
962− ret = con_font_op(vc_cons[fg_console].d, &op);
963− if (ret)
964− break;
965− console_lock();
966− con_set_default_unimap(vc_cons[fg_console].d);
9671018 console_unlock();
9681019 break;
969− }
970−#endif
971− }
972−
973− case KDFONTOP: {
974− if (copy_from_user(&op, up, sizeof(op))) {
975− ret = -EFAULT;
976− break;
977− }
978− if (!perm && op.op != KD_FONT_OP_GET)
979− return -EPERM;
980− ret = con_font_op(vc, &op);
981− if (ret)
982− break;
983− if (copy_to_user(up, &op, sizeof(op)))
984− ret = -EFAULT;
985− break;
9861020 }
9871021
988− case PIO_SCRNMAP:
989− if (!perm)
990− ret = -EPERM;
991− else
992− ret = con_set_trans_old(up);
993− break;
994−
995− case GIO_SCRNMAP:
996− ret = con_get_trans_old(up);
997− break;
998−
999− case PIO_UNISCRNMAP:
1000− if (!perm)
1001− ret = -EPERM;
1002− else
1003− ret = con_set_trans_new(up);
1004− break;
1005−
1006− case GIO_UNISCRNMAP:
1007− ret = con_get_trans_new(up);
1008− break;
1009−
1010− case PIO_UNIMAPCLR:
1022+ case VT_RESIZEX:
10111023 if (!perm)
10121024 return -EPERM;
1013− con_clear_unimap(vc);
1014− break;
10151025
1016− case PIO_UNIMAP:
1017− case GIO_UNIMAP:
1018− ret = do_unimap_ioctl(cmd, up, perm, vc);
1019− break;
1026+ return vt_resizex(vc, up);
10201027
10211028 case VT_LOCKSWITCH:
10221029 if (!capable(CAP_SYS_TTY_CONFIG))
@@ -1029,17 +1036,15 @@ int vt_ioctl(struct tty_struct *tty, · 6 unmodified lines
10291036 vt_dont_switch = false;
10301037 break;
10311038 case VT_GETHIFONTMASK:
1032− ret = put_user(vc->vc_hi_font_mask,
1039+ return put_user(vc->vc_hi_font_mask,
10331040 (unsigned short __user *)arg);
1034− break;
10351041 case VT_WAITEVENT:
1036− ret = vt_event_wait_ioctl((struct vt_event __user *)arg);
1037− break;
1042+ return vt_event_wait_ioctl((struct vt_event __user *)arg);
10381043 default:
1039− ret = -ENOIOCTLCMD;
1044+ return -ENOIOCTLCMD;
10401045 }
1041−out:
1042− return ret;
1046+
1047+ return 0;
10431048 }
10441049
10451050 void reset_vc(struct vc_data *vc)
drivers/usb/misc/sisusbvga/sisusb_con.c+6−5
@@ -302,14 +302,15 @@ sisusbcon_deinit(struct vc_data *c) · 301 unmodified lines
302302
303303 /* interface routine */
304304 static u8
305−sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity,
306− u8 blink, u8 underline, u8 reverse, u8 unused)
305+sisusbcon_build_attr(struct vc_data *c, u8 color, enum vc_intensity intensity,
306+ bool blink, bool underline, bool reverse,
307+ bool unused)
307308 {
308309 u8 attr = color;
309310
310311 if (underline)
311312 attr = (attr & 0xf0) | c->vc_ulcolor;
312− else if (intensity == 0)
313+ else if (intensity == VCI_HALF_BRIGHT)
313314 attr = (attr & 0xf0) | c->vc_halfcolor;
314315
315316 if (reverse)
@@ -320,7 +321,7 @@ sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity, · 4 unmodified lines
320321 if (blink)
321322 attr ^= 0x80;
322323
323− if (intensity == 2)
324+ if (intensity == VCI_BOLD)
324325 attr ^= 0x08;
325326
326327 return attr;
@@ -726,7 +727,7 @@ sisusbcon_cursor(struct vc_data *c, int mode) · 399 unmodified lines
726727
727728 baseline = c->vc_font.height - (c->vc_font.height < 10 ? 1 : 2);
728729
729− switch (c->vc_cursor_type & 0x0f) {
730+ switch (CUR_SIZE(c->vc_cursor_type)) {
730731 case CUR_BLOCK: from = 1;
731732 to = c->vc_font.height;
732733 break;
drivers/video/console/mdacon.c+11−9
@@ -394,8 +394,10 @@ static inline u16 mda_convert_attr(u16 ch) · 393 unmodified lines
394394 (ch & 0x00ff) | attr;
395395 }
396396
397−static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
398− u8 blink, u8 underline, u8 reverse, u8 italic)
397+static u8 mdacon_build_attr(struct vc_data *c, u8 color,
398+ enum vc_intensity intensity,
399+ bool blink, bool underline, bool reverse,
400+ bool italic)
399401 {
400402 /* The attribute is just a bit vector:
401403 *
@@ -405,11 +407,11 @@ static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity, · 3 unmodified lines
405407 * Bit 7 : blink
406408 */
407409
408− return (intensity & 3) |
409− ((underline & 1) << 2) |
410− ((reverse & 1) << 3) |
411− (!!italic << 4) |
412− ((blink & 1) << 7);
410+ return (intensity & VCI_MASK) |
411+ (underline << 2) |
412+ (reverse << 3) |
413+ (italic << 4) |
414+ (blink << 7);
413415 }
414416
415417 static void mdacon_invert_region(struct vc_data *c, u16 *p, int count)
@@ -488,9 +490,9 @@ static void mdacon_cursor(struct vc_data *c, int mode) · 72 unmodified lines
488490 return;
489491 }
490492
491− mda_set_cursor(c->vc_y*mda_num_columns*2 + c->vc_x*2);
493+ mda_set_cursor(c->state.y * mda_num_columns * 2 + c->state.x * 2);
492494
493− switch (c->vc_cursor_type & 0x0f) {
495+ switch (CUR_SIZE(c->vc_cursor_type)) {
494496
495497 case CUR_LOWER_THIRD: mda_set_cursor_size(10, 13); break;
496498 case CUR_LOWER_HALF: mda_set_cursor_size(7, 13); break;
drivers/video/console/newport_con.c+5−5
@@ -362,12 +362,12 @@ static void newport_clear(struct vc_data *vc, int sy, int sx, int height, · 361 unmodified lines
362362
363363 if (ystart < yend) {
364364 newport_clear_screen(sx << 3, ystart, xend, yend,
365− (vc->vc_color & 0xf0) >> 4);
365+ (vc->state.color & 0xf0) >> 4);
366366 } else {
367367 newport_clear_screen(sx << 3, ystart, xend, 1023,
368− (vc->vc_color & 0xf0) >> 4);
368+ (vc->state.color & 0xf0) >> 4);
369369 newport_clear_screen(sx << 3, 0, xend, yend,
370− (vc->vc_color & 0xf0) >> 4);
370+ (vc->state.color & 0xf0) >> 4);
371371 }
372372 }
373373
@@ -591,11 +591,11 @@ static bool newport_scroll(struct vc_data *vc, unsigned int t, unsigned int b, · 217 unmodified lines
591591 topscan = (topscan + (lines << 4)) & 0x3ff;
592592 newport_clear_lines(vc->vc_rows - lines,
593593 vc->vc_rows - 1,
594− (vc->vc_color & 0xf0) >> 4);
594+ (vc->state.color & 0xf0) >> 4);
595595 } else {
596596 topscan = (topscan + (-lines << 4)) & 0x3ff;
597597 newport_clear_lines(0, lines - 1,
598− (vc->vc_color & 0xf0) >> 4);
598+ (vc->state.color & 0xf0) >> 4);
599599 }
600600 npregs->cset.topscan = (topscan - 1) & 0x3ff;
601601 return false;
drivers/video/console/sticon.c+8−6
@@ -132,21 +132,21 @@ static void sticon_cursor(struct vc_data *conp, int mode) · 131 unmodified lines
132132 {
133133 unsigned short car1;
134134
135− car1 = conp->vc_screenbuf[conp->vc_x + conp->vc_y * conp->vc_cols];
135+ car1 = conp->vc_screenbuf[conp->state.x + conp->state.y * conp->vc_cols];
136136 switch (mode) {
137137 case CM_ERASE:
138− sti_putc(sticon_sti, car1, conp->vc_y, conp->vc_x);
138+ sti_putc(sticon_sti, car1, conp->state.y, conp->state.x);
139139 break;
140140 case CM_MOVE:
141141 case CM_DRAW:
142− switch (conp->vc_cursor_type & 0x0f) {
142+ switch (CUR_SIZE(conp->vc_cursor_type)) {
143143 case CUR_UNDERLINE:
144144 case CUR_LOWER_THIRD:
145145 case CUR_LOWER_HALF:
146146 case CUR_TWO_THIRDS:
147147 case CUR_BLOCK:
148148 sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11),
149− conp->vc_y, conp->vc_x);
149+ conp->state.y, conp->state.x);
150150 break;
151151 }
152152 break;
@@ -288,8 +288,10 @@ static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos, · 135 unmodified lines
288288 return ret;
289289 }
290290
291−static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens,
292− u8 blink, u8 underline, u8 reverse, u8 italic)
291+static u8 sticon_build_attr(struct vc_data *conp, u8 color,
292+ enum vc_intensity intens,
293+ bool blink, bool underline, bool reverse,
294+ bool italic)
293295 {
294296 u8 attr = ((color & 0x70) >> 1) | ((color & 7));
295297
drivers/video/console/vgacon.c+23−17
@@ -251,6 +251,10 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count) · 250 unmodified lines
251251 p = (void *) (c->vc_origin + t * c->vc_size_row);
252252
253253 while (count--) {
254+ if ((vgacon_scrollback_cur->tail + c->vc_size_row) >
255+ vgacon_scrollback_cur->size)
256+ vgacon_scrollback_cur->tail = 0;
257+
254258 scr_memcpyw(vgacon_scrollback_cur->data +
255259 vgacon_scrollback_cur->tail,
256260 p, c->vc_size_row);
@@ -629,8 +633,10 @@ static void vgacon_deinit(struct vc_data *c) · 372 unmodified lines
629633 con_set_default_unimap(c);
630634 }
631635
632−static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
633− u8 blink, u8 underline, u8 reverse, u8 italic)
636+static u8 vgacon_build_attr(struct vc_data *c, u8 color,
637+ enum vc_intensity intensity,
638+ bool blink, bool underline, bool reverse,
639+ bool italic)
634640 {
635641 u8 attr = color;
636642
@@ -639,7 +645,7 @@ static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, · 2 unmodified lines
639645 attr = (attr & 0xF0) | c->vc_itcolor;
640646 else if (underline)
641647 attr = (attr & 0xf0) | c->vc_ulcolor;
642− else if (intensity == 0)
648+ else if (intensity == VCI_HALF_BRIGHT)
643649 attr = (attr & 0xf0) | c->vc_halfcolor;
644650 }
645651 if (reverse)
@@ -648,14 +654,14 @@ static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, · 2 unmodified lines
648654 0x77);
649655 if (blink)
650656 attr ^= 0x80;
651− if (intensity == 2)
657+ if (intensity == VCI_BOLD)
652658 attr ^= 0x08;
653659 if (!vga_can_do_color) {
654660 if (italic)
655661 attr = (attr & 0xF8) | 0x02;
656662 else if (underline)
657663 attr = (attr & 0xf8) | 0x01;
658− else if (intensity == 0)
664+ else if (intensity == VCI_HALF_BRIGHT)
659665 attr = (attr & 0xf0) | 0x08;
660666 }
661667 return attr;
@@ -718,17 +724,17 @@ static void vgacon_cursor(struct vc_data *c, int mode) · 56 unmodified lines
718724 case CM_ERASE:
719725 write_vga(14, (c->vc_pos - vga_vram_base) / 2);
720726 if (vga_video_type >= VIDEO_TYPE_VGAC)
721− vgacon_set_cursor_size(c->vc_x, 31, 30);
727+ vgacon_set_cursor_size(c->state.x, 31, 30);
722728 else
723− vgacon_set_cursor_size(c->vc_x, 31, 31);
729+ vgacon_set_cursor_size(c->state.x, 31, 31);
724730 break;
725731
726732 case CM_MOVE:
727733 case CM_DRAW:
728734 write_vga(14, (c->vc_pos - vga_vram_base) / 2);
729− switch (c->vc_cursor_type & 0x0f) {
735+ switch (CUR_SIZE(c->vc_cursor_type)) {
730736 case CUR_UNDERLINE:
731− vgacon_set_cursor_size(c->vc_x,
737+ vgacon_set_cursor_size(c->state.x,
732738 c->vc_font.height -
733739 (c->vc_font.height <
734740 10 ? 2 : 3),
@@ -737,21 +743,21 @@ static void vgacon_cursor(struct vc_data *c, int mode) · 2 unmodified lines
737743 10 ? 1 : 2));
738744 break;
739745 case CUR_TWO_THIRDS:
740− vgacon_set_cursor_size(c->vc_x,
746+ vgacon_set_cursor_size(c->state.x,
741747 c->vc_font.height / 3,
742748 c->vc_font.height -
743749 (c->vc_font.height <
744750 10 ? 1 : 2));
745751 break;
746752 case CUR_LOWER_THIRD:
747− vgacon_set_cursor_size(c->vc_x,
753+ vgacon_set_cursor_size(c->state.x,
748754 (c->vc_font.height * 2) / 3,
749755 c->vc_font.height -
750756 (c->vc_font.height <
751757 10 ? 1 : 2));
752758 break;
753759 case CUR_LOWER_HALF:
754− vgacon_set_cursor_size(c->vc_x,
760+ vgacon_set_cursor_size(c->state.x,
755761 c->vc_font.height / 2,
756762 c->vc_font.height -
757763 (c->vc_font.height <
@@ -759,12 +765,12 @@ static void vgacon_cursor(struct vc_data *c, int mode) · 1 unmodified line
759765 break;
760766 case CUR_NONE:
761767 if (vga_video_type >= VIDEO_TYPE_VGAC)
762− vgacon_set_cursor_size(c->vc_x, 31, 30);
768+ vgacon_set_cursor_size(c->state.x, 31, 30);
763769 else
764− vgacon_set_cursor_size(c->vc_x, 31, 31);
770+ vgacon_set_cursor_size(c->state.x, 31, 31);
765771 break;
766772 default:
767− vgacon_set_cursor_size(c->vc_x, 1,
773+ vgacon_set_cursor_size(c->state.x, 1,
768774 c->vc_font.height);
769775 break;
770776 }
@@ -1352,8 +1358,8 @@ static void vgacon_save_screen(struct vc_data *c) · 581 unmodified lines
13521358 * console initialization routines.
13531359 */
13541360 vga_bootup_console = 1;
1355− c->vc_x = screen_info.orig_x;
1356− c->vc_y = screen_info.orig_y;
1361+ c->state.x = screen_info.orig_x;
1362+ c->state.y = screen_info.orig_y;
13571363 }
13581364
13591365 /* We can't copy in more than the size of the video buffer,
drivers/video/fbdev/core/bitblit.c+5−5
@@ -240,8 +240,8 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, · 239 unmodified lines
240240 struct fbcon_ops *ops = info->fbcon_par;
241241 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
242242 int w = DIV_ROUND_UP(vc->vc_font.width, 8), c;
243− int y = real_y(ops->p, vc->vc_y);
244− int attribute, use_sw = (vc->vc_cursor_type & 0x10);
243+ int y = real_y(ops->p, vc->state.y);
244+ int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
245245 int err = 1;
246246 char *src;
247247
@@ -286,10 +286,10 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, · 38 unmodified lines
286286 cursor.set |= FB_CUR_SETCMAP;
287287 }
288288
289− if ((ops->cursor_state.image.dx != (vc->vc_font.width * vc->vc_x)) ||
289+ if ((ops->cursor_state.image.dx != (vc->vc_font.width * vc->state.x)) ||
290290 (ops->cursor_state.image.dy != (vc->vc_font.height * y)) ||
291291 ops->cursor_reset) {
292− ops->cursor_state.image.dx = vc->vc_font.width * vc->vc_x;
292+ ops->cursor_state.image.dx = vc->vc_font.width * vc->state.x;
293293 ops->cursor_state.image.dy = vc->vc_font.height * y;
294294 cursor.set |= FB_CUR_SETPOS;
295295 }
@@ -325,7 +325,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, · 29 unmodified lines
325325 ops->p->cursor_shape = vc->vc_cursor_type;
326326 cursor.set |= FB_CUR_SETSHAPE;
327327
328− switch (ops->p->cursor_shape & CUR_HWMASK) {
328+ switch (CUR_SIZE(ops->p->cursor_shape)) {
329329 case CUR_NONE:
330330 cur_height = 0;
331331 break;
drivers/video/fbdev/core/fbcon.c+5−5
@@ -655,11 +655,11 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, · 654 unmodified lines
655655 }
656656 if (!save) {
657657 int lines;
658− if (vc->vc_y + logo_lines >= rows)
659− lines = rows - vc->vc_y - 1;
658+ if (vc->state.y + logo_lines >= rows)
659+ lines = rows - vc->state.y - 1;
660660 else
661661 lines = logo_lines;
662− vc->vc_y += lines;
662+ vc->state.y += lines;
663663 vc->vc_pos += lines * vc->vc_size_row;
664664 }
665665 }
@@ -677,7 +677,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, · 11 unmodified lines
677677 vc->vc_size_row *
678678 rows);
679679 scr_memcpyw(q, save, array3_size(logo_lines, new_cols, 2));
680− vc->vc_y += logo_lines;
680+ vc->state.y += logo_lines;
681681 vc->vc_pos += logo_lines * vc->vc_size_row;
682682 kfree(save);
683683 }
@@ -1393,7 +1393,7 @@ static void fbcon_cursor(struct vc_data *vc, int mode) · 709 unmodified lines
13931393 if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1)
13941394 return;
13951395
1396− if (vc->vc_cursor_type & 0x10)
1396+ if (vc->vc_cursor_type & CUR_SW)
13971397 fbcon_del_cursor_timer(info);
13981398 else
13991399 fbcon_add_cursor_timer(info);
drivers/video/fbdev/core/fbcon_ccw.c+4−4
@@ -225,8 +225,8 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode, · 224 unmodified lines
225225 struct fbcon_ops *ops = info->fbcon_par;
226226 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
227227 int w = (vc->vc_font.height + 7) >> 3, c;
228− int y = real_y(ops->p, vc->vc_y);
229− int attribute, use_sw = (vc->vc_cursor_type & 0x10);
228+ int y = real_y(ops->p, vc->state.y);
229+ int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
230230 int err = 1, dx, dy;
231231 char *src;
232232 u32 vyres = GETVYRES(ops->p->scrollmode, info);
@@ -284,7 +284,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode, · 51 unmodified lines
284284 }
285285
286286 dx = y * vc->vc_font.height;
287− dy = vyres - ((vc->vc_x + 1) * vc->vc_font.width);
287+ dy = vyres - ((vc->state.x + 1) * vc->vc_font.width);
288288
289289 if (ops->cursor_state.image.dx != dx ||
290290 ops->cursor_state.image.dy != dy ||
@@ -325,7 +325,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode, · 34 unmodified lines
325325 ops->p->cursor_shape = vc->vc_cursor_type;
326326 cursor.set |= FB_CUR_SETSHAPE;
327327
328− switch (ops->p->cursor_shape & CUR_HWMASK) {
328+ switch (CUR_SIZE(ops->p->cursor_shape)) {
329329 case CUR_NONE:
330330 cur_height = 0;
331331 break;
drivers/video/fbdev/core/fbcon_cw.c+4−4
@@ -208,8 +208,8 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, · 207 unmodified lines
208208 struct fbcon_ops *ops = info->fbcon_par;
209209 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
210210 int w = (vc->vc_font.height + 7) >> 3, c;
211− int y = real_y(ops->p, vc->vc_y);
212− int attribute, use_sw = (vc->vc_cursor_type & 0x10);
211+ int y = real_y(ops->p, vc->state.y);
212+ int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
213213 int err = 1, dx, dy;
214214 char *src;
215215 u32 vxres = GETVXRES(ops->p->scrollmode, info);
@@ -267,7 +267,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, · 51 unmodified lines
267267 }
268268
269269 dx = vxres - ((y * vc->vc_font.height) + vc->vc_font.height);
270− dy = vc->vc_x * vc->vc_font.width;
270+ dy = vc->state.x * vc->vc_font.width;
271271
272272 if (ops->cursor_state.image.dx != dx ||
273273 ops->cursor_state.image.dy != dy ||
@@ -308,7 +308,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, · 34 unmodified lines
308308 ops->p->cursor_shape = vc->vc_cursor_type;
309309 cursor.set |= FB_CUR_SETSHAPE;
310310
311− switch (ops->p->cursor_shape & CUR_HWMASK) {
311+ switch (CUR_SIZE(ops->p->cursor_shape)) {
312312 case CUR_NONE:
313313 cur_height = 0;
314314 break;
drivers/video/fbdev/core/fbcon_ud.c+4−4
@@ -255,8 +255,8 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode, · 254 unmodified lines
255255 struct fbcon_ops *ops = info->fbcon_par;
256256 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
257257 int w = (vc->vc_font.width + 7) >> 3, c;
258− int y = real_y(ops->p, vc->vc_y);
259− int attribute, use_sw = (vc->vc_cursor_type & 0x10);
258+ int y = real_y(ops->p, vc->state.y);
259+ int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
260260 int err = 1, dx, dy;
261261 char *src;
262262 u32 vyres = GETVYRES(ops->p->scrollmode, info);
@@ -315,7 +315,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode, · 52 unmodified lines
315315 }
316316
317317 dy = vyres - ((y * vc->vc_font.height) + vc->vc_font.height);
318− dx = vxres - ((vc->vc_x * vc->vc_font.width) + vc->vc_font.width);
318+ dx = vxres - ((vc->state.x * vc->vc_font.width) + vc->vc_font.width);
319319
320320 if (ops->cursor_state.image.dx != dx ||
321321 ops->cursor_state.image.dy != dy ||
@@ -348,7 +348,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode, · 26 unmodified lines
348348 ops->p->cursor_shape = vc->vc_cursor_type;
349349 cursor.set |= FB_CUR_SETSHAPE;
350350
351− switch (ops->p->cursor_shape & CUR_HWMASK) {
351+ switch (CUR_SIZE(ops->p->cursor_shape)) {
352352 case CUR_NONE:
353353 cur_height = 0;
354354 break;
drivers/video/fbdev/core/tileblit.c+3−3
@@ -83,10 +83,10 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode, · 82 unmodified lines
8383 int softback_lines, int fg, int bg)
8484 {
8585 struct fb_tilecursor cursor;
86− int use_sw = (vc->vc_cursor_type & 0x10);
86+ int use_sw = vc->vc_cursor_type & CUR_SW;
8787
88− cursor.sx = vc->vc_x;
89− cursor.sy = vc->vc_y;
88+ cursor.sx = vc->state.x;
89+ cursor.sy = vc->state.y;
9090 cursor.mode = (mode == CM_ERASE || use_sw) ? 0 : 1;
9191 cursor.fg = fg;
9292 cursor.bg = bg;
include/linux/console.h+5−8
@@ -24,17 +24,13 @@ struct module; · 23 unmodified lines
2424 struct tty_struct;
2525 struct notifier_block;
2626
27−/*
28− * this is what the terminal answers to a ESC-Z or csi0c query.
29− */
30−#define VT100ID "\033[?1;2c"
31−#define VT102ID "\033[?6c"
32−
3327 enum con_scroll {
3428 SM_UP,
3529 SM_DOWN,
3630 };
3731
32+enum vc_intensity;
33+
3834 /**
3935 * struct consw - callbacks for consoles
4036 *
@@ -74,8 +70,9 @@ struct consw { · 33 unmodified lines
7470 void (*con_scrolldelta)(struct vc_data *vc, int lines);
7571 int (*con_set_origin)(struct vc_data *vc);
7672 void (*con_save_screen)(struct vc_data *vc);
77− u8 (*con_build_attr)(struct vc_data *vc, u8 color, u8 intensity,
78− u8 blink, u8 underline, u8 reverse, u8 italic);
73+ u8 (*con_build_attr)(struct vc_data *vc, u8 color,
74+ enum vc_intensity intensity,
75+ bool blink, bool underline, bool reverse, bool italic);
7976 void (*con_invert_region)(struct vc_data *vc, u16 *p, int count);
8077 u16 *(*con_screen_pos)(struct vc_data *vc, int offset);
8178 unsigned long (*con_getxy)(struct vc_data *vc, unsigned long position,
include/linux/console_struct.h+58−35
@@ -21,6 +21,43 @@ struct uni_pagedir; · 20 unmodified lines
2121 struct uni_screen;
2222
2323 #define NPAR 16
24+#define VC_TABSTOPS_COUNT 256U
25+
26+enum vc_intensity {
27+ VCI_HALF_BRIGHT,
28+ VCI_NORMAL,
29+ VCI_BOLD,
30+ VCI_MASK = 0x3,
31+};
32+
33+/**
34+ * struct vc_state -- state of a VC
35+ * @x: cursor's x-position
36+ * @y: cursor's y-position
37+ * @color: foreground & background colors
38+ * @Gx_charset: what's G0/G1 slot set to (like GRAF_MAP, LAT1_MAP)
39+ * @charset: what character set to use (0=G0 or 1=G1)
40+ * @intensity: see enum vc_intensity for values
41+ * @reverse: reversed foreground/background colors
42+ *
43+ * These members are defined separately from struct vc_data as we save &
44+ * restore them at times.
45+ */
46+struct vc_state {
47+ unsigned int x, y;
48+
49+ unsigned char color;
50+
51+ unsigned char Gx_charset[2];
52+ unsigned int charset : 1;
53+
54+ /* attribute flags */
55+ enum vc_intensity intensity;
56+ bool italic;
57+ bool underline;
58+ bool blink;
59+ bool reverse;
60+};
2461
2562 /*
2663 * Example: vc_data of a console that was scrolled 3 lines down.
@@ -57,6 +94,8 @@ struct uni_screen; · 30 unmodified lines
5794 struct vc_data {
5895 struct tty_port port; /* Upper level data */
5996
97+ struct vc_state state, saved_state;
98+
6099 unsigned short vc_num; /* Console number */
61100 unsigned int vc_cols; /* [#] Console size */
62101 unsigned int vc_rows;
@@ -73,8 +112,6 @@ struct vc_data { · 10 unmodified lines
73112 /* attributes for all characters on screen */
74113 unsigned char vc_attr; /* Current attributes */
75114 unsigned char vc_def_color; /* Default colors */
76− unsigned char vc_color; /* Foreground & background */
77− unsigned char vc_s_color; /* Saved foreground & background */
78115 unsigned char vc_ulcolor; /* Color for underline mode */
79116 unsigned char vc_itcolor;
80117 unsigned char vc_halfcolor; /* Color for half intensity mode */
@@ -82,8 +119,6 @@ struct vc_data { · 1 unmodified line
82119 unsigned int vc_cursor_type;
83120 unsigned short vc_complement_mask; /* [#] Xor mask for mouse pointer */
84121 unsigned short vc_s_complement_mask; /* Saved mouse pointer mask */
85− unsigned int vc_x, vc_y; /* Cursor position */
86− unsigned int vc_saved_x, vc_saved_y;
87122 unsigned long vc_pos; /* Cursor address */
88123 /* fonts */
89124 unsigned short vc_hi_font_mask; /* [#] Attribute set for upper 256 chars of font or 0 if not supported */
@@ -98,8 +133,6 @@ struct vc_data { · 8 unmodified lines
98133 int vt_newvt;
99134 wait_queue_head_t paste_wait;
100135 /* mode flags */
101− unsigned int vc_charset : 1; /* Character set G0 / G1 */
102− unsigned int vc_s_charset : 1; /* Saved character set */
103136 unsigned int vc_disp_ctrl : 1; /* Display chars < 32? */
104137 unsigned int vc_toggle_meta : 1; /* Toggle high bit? */
105138 unsigned int vc_decscnm : 1; /* Screen Mode */
@@ -107,17 +140,6 @@ struct vc_data { · 1 unmodified line
107140 unsigned int vc_decawm : 1; /* Autowrap Mode */
108141 unsigned int vc_deccm : 1; /* Cursor Visible */
109142 unsigned int vc_decim : 1; /* Insert Mode */
110− /* attribute flags */
111− unsigned int vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */
112− unsigned int vc_italic:1;
113− unsigned int vc_underline : 1;
114− unsigned int vc_blink : 1;
115− unsigned int vc_reverse : 1;
116− unsigned int vc_s_intensity : 2; /* saved rendition */
117− unsigned int vc_s_italic:1;
118− unsigned int vc_s_underline : 1;
119− unsigned int vc_s_blink : 1;
120− unsigned int vc_s_reverse : 1;
121143 /* misc */
122144 unsigned int vc_priv : 3;
123145 unsigned int vc_need_wrap : 1;
@@ -126,13 +148,9 @@ struct vc_data { · 2 unmodified lines
126148 unsigned char vc_utf : 1; /* Unicode UTF-8 encoding */
127149 unsigned char vc_utf_count;
128150 int vc_utf_char;
129− unsigned int vc_tab_stop[8]; /* Tab stops. 256 columns. */
151+ DECLARE_BITMAP(vc_tab_stop, VC_TABSTOPS_COUNT); /* Tab stops. 256 columns. */
130152 unsigned char vc_palette[16*3]; /* Colour palette for VGA+ */
131153 unsigned short * vc_translate;
132− unsigned char vc_G0_charset;
133− unsigned char vc_G1_charset;
134− unsigned char vc_saved_G0;
135− unsigned char vc_saved_G1;
136154 unsigned int vc_resize_user; /* resize request from user */
137155 unsigned int vc_bell_pitch; /* Console bell pitch */
138156 unsigned int vc_bell_duration; /* Console bell duration */
@@ -149,24 +167,29 @@ struct vc { · 10 unmodified lines
149167 struct work_struct SAK_work;
150168
151169 /* might add scrmem, kbd at some time,
152− to have everything in one place - the disadvantage
153− would be that vc_cons etc can no longer be static */
170+ to have everything in one place */
154171 };
155172
156173 extern struct vc vc_cons [MAX_NR_CONSOLES];
157174 extern void vc_SAK(struct work_struct *work);
158175
159−#define CUR_DEF 0
160−#define CUR_NONE 1
161−#define CUR_UNDERLINE 2
162−#define CUR_LOWER_THIRD 3
163−#define CUR_LOWER_HALF 4
164−#define CUR_TWO_THIRDS 5
165−#define CUR_BLOCK 6
166−#define CUR_HWMASK 0x0f
167−#define CUR_SWMASK 0xfff0
168−
169−#define CUR_DEFAULT CUR_UNDERLINE
176+#define CUR_MAKE(size, change, set) ((size) | ((change) << 8) | \
177+ ((set) << 16))
178+#define CUR_SIZE(c) ((c) & 0x00000f)
179+# define CUR_DEF 0
180+# define CUR_NONE 1
181+# define CUR_UNDERLINE 2
182+# define CUR_LOWER_THIRD 3
183+# define CUR_LOWER_HALF 4
184+# define CUR_TWO_THIRDS 5
185+# define CUR_BLOCK 6
186+#define CUR_SW 0x000010
187+#define CUR_ALWAYS_BG 0x000020
188+#define CUR_INVERT_FG_BG 0x000040
189+#define CUR_FG 0x000700
190+#define CUR_BG 0x007000
191+#define CUR_CHANGE(c) ((c) & 0x00ff00)
192+#define CUR_SET(c) (((c) & 0xff0000) >> 8)
170193
171194 bool con_is_visible(const struct vc_data *vc);
172195
include/linux/serial_8250.h+2−0
@@ -155,6 +155,8 @@ extern int early_serial_setup(struct uart_port *port); · 154 unmodified lines
155155
156156 extern int early_serial8250_setup(struct earlycon_device *device,
157157 const char *options);
158+extern void serial8250_update_uartclk(struct uart_port *port,
159+ unsigned int uartclk);
158160 extern void serial8250_do_set_termios(struct uart_port *port,
159161 struct ktermios *termios, struct ktermios *old);
160162 extern void serial8250_do_set_ldisc(struct uart_port *port,
include/linux/serial_core.h+1−1
@@ -10,7 +10,6 @@ · 9 unmodified lines
1010 #include <linux/bitops.h>
1111 #include <linux/compiler.h>
1212 #include <linux/console.h>
13−#include <linux/gpio/consumer.h>
1413 #include <linux/interrupt.h>
1514 #include <linux/circ_buf.h>
1615 #include <linux/spinlock.h>
@@ -30,6 +29,7 @@ · 13 unmodified lines
3029 struct uart_port;
3130 struct serial_struct;
3231 struct device;
32+struct gpio_desc;
3333
3434 /*
3535 * This structure describes all the operations that can be done on the
include/linux/vt_kern.h+0−3
@@ -74,8 +74,6 @@ int con_set_default_unimap(struct vc_data *vc); · 73 unmodified lines
7474 void con_free_unimap(struct vc_data *vc);
7575 int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc);
7676
77−#define vc_translate(vc, c) ((vc)->vc_translate[(c) | \
78− ((vc)->vc_toggle_meta ? 0x80 : 0)])
7977 #else
8078 static inline int con_set_trans_old(unsigned char __user *table)
8179 {
@@ -124,7 +122,6 @@ int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc) · 42 unmodified lines
124122 return 0;
125123 }
126124
127−#define vc_translate(vc, c) (c)
128125 #endif
129126
130127 /* vt.c */
include/uapi/linux/serial_core.h+0−14
@@ -26,20 +26,6 @@ · 25 unmodified lines
2626 /*
2727 * The type definitions. These are from Ted Ts'o's serial.h
2828 */
29−#define PORT_UNKNOWN 0
30−#define PORT_8250 1
31−#define PORT_16450 2
32−#define PORT_16550 3
33−#define PORT_16550A 4
34−#define PORT_CIRRUS 5
35−#define PORT_16650 6
36−#define PORT_16650V2 7
37−#define PORT_16750 8
38−#define PORT_STARTECH 9
39−#define PORT_16C950 10
40−#define PORT_16654 11
41−#define PORT_16850 12
42−#define PORT_RSA 13
4329 #define PORT_NS16550A 14
4430 #define PORT_XSCALE 15
4531 #define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */