Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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
...

+1846 -1612
+3 -1
Documentation/devicetree/bindings/serial/st,stm32-uart.yaml
··· 35 35 description: label associated with this uart 36 36 37 37 st,hw-flow-ctrl: 38 - description: enable hardware flow control 38 + description: enable hardware flow control (deprecated) 39 39 $ref: /schemas/types.yaml#/definitions/flag 40 + 41 + uart-has-rtscts: true 40 42 41 43 dmas: 42 44 minItems: 1
+1 -1
Documentation/driver-api/serial/n_gsm.rst
··· 5 5 This line discipline implements the GSM 07.10 multiplexing protocol 6 6 detailed in the following 3GPP document: 7 7 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 9 9 10 10 This document give some hints on how to use this driver with GPRS and 3G 11 11 modems connected to a physical serial port.
+6
MAINTAINERS
··· 4386 4386 S: Maintained 4387 4387 F: drivers/connector/ 4388 4388 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 + 4389 4395 CONTROL GROUP (CGROUP) 4390 4396 M: Tejun Heo <tj@kernel.org> 4391 4397 M: Li Zefan <lizefan@huawei.com>
-5
arch/um/drivers/line.c
··· 184 184 line_flush_buffer(tty); 185 185 } 186 186 187 - int line_put_char(struct tty_struct *tty, unsigned char ch) 188 - { 189 - return line_write(tty, &ch, sizeof(ch)); 190 - } 191 - 192 187 int line_write(struct tty_struct *tty, const unsigned char *buf, int len) 193 188 { 194 189 struct line *line = tty->driver_data;
-1
arch/um/drivers/line.h
··· 66 66 char *init, char *name); 67 67 extern int line_write(struct tty_struct *tty, const unsigned char *buf, 68 68 int len); 69 - extern int line_put_char(struct tty_struct *tty, unsigned char ch); 70 69 extern void line_set_termios(struct tty_struct *tty, struct ktermios * old); 71 70 extern int line_chars_in_buffer(struct tty_struct *tty); 72 71 extern void line_flush_buffer(struct tty_struct *tty);
-1
arch/um/drivers/ssl.c
··· 95 95 .open = line_open, 96 96 .close = line_close, 97 97 .write = line_write, 98 - .put_char = line_put_char, 99 98 .write_room = line_write_room, 100 99 .chars_in_buffer = line_chars_in_buffer, 101 100 .flush_buffer = line_flush_buffer,
-1
arch/um/drivers/stdio_console.c
··· 102 102 .install = con_install, 103 103 .close = line_close, 104 104 .write = line_write, 105 - .put_char = line_put_char, 106 105 .write_room = line_write_room, 107 106 .chars_in_buffer = line_chars_in_buffer, 108 107 .flush_buffer = line_flush_buffer,
+5 -5
drivers/accessibility/braille/braille_console.c
··· 109 109 /* Follow the VC cursor*/ 110 110 static void vc_follow_cursor(struct vc_data *vc) 111 111 { 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; 116 116 } 117 117 118 118 /* Maybe the VC cursor moved, if so follow it */ 119 119 static void vc_maybe_cursor_moved(struct vc_data *vc) 120 120 { 121 - if (vc->vc_x != lastvc_x || vc->vc_y != lastvc_y) 121 + if (vc->state.x != lastvc_x || vc->state.y != lastvc_y) 122 122 vc_follow_cursor(vc); 123 123 } 124 124
+14 -14
drivers/accessibility/speakup/main.c
··· 263 263 264 264 static void speakup_date(struct vc_data *vc) 265 265 { 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; 268 268 spk_pos = spk_cp = vc->vc_pos; 269 269 spk_old_attr = spk_attr; 270 270 spk_attr = get_attributes(vc, (u_short *)spk_pos); ··· 1551 1551 */ 1552 1552 is_cursor = value + 1; 1553 1553 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; 1557 1557 cursor_con = vc->vc_num; 1558 1558 if (cursor_track == CT_Highlight) 1559 1559 reset_highlight_buffers(vc); ··· 1574 1574 i = 0; 1575 1575 if (speakup_console[vc_num]->ht.highsize[bi] == 0) { 1576 1576 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; 1579 1579 } 1580 1580 while ((hi < COLOR_BUFFER_SIZE) && (i < len)) { 1581 1581 if (ic[i] > 32) { ··· 1664 1664 return 0; 1665 1665 hc = get_highlight_color(vc); 1666 1666 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; 1668 1668 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) 1670 1670 return 0; 1671 1671 spk_parked |= 0x01; 1672 1672 spk_do_flush(); ··· 1693 1693 } 1694 1694 speakup_date(vc); 1695 1695 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) { 1698 1698 spk_keydown = 0; 1699 1699 is_cursor = 0; 1700 1700 goto out; ··· 1757 1757 if (!spin_trylock_irqsave(&speakup_info.spinlock, flags)) 1758 1758 /* Speakup output, discard */ 1759 1759 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)) 1761 1761 bleep(3); 1762 1762 if ((is_cursor) || (cursor_track == read_all_mode)) { 1763 1763 if (cursor_track == CT_Highlight) ··· 1766 1766 return; 1767 1767 } 1768 1768 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) { 1771 1771 spin_unlock_irqrestore(&speakup_info.spinlock, flags); 1772 1772 return; 1773 1773 }
+1 -1
drivers/tty/moxa.h
··· 138 138 #define IntrQuit 0x40 /* received QUIT code */ 139 139 #define IntrEOF 0x80 /* received EOF code */ 140 140 141 - #define IntrRxTrigger 0x100 /* rx data count reach tigger value */ 141 + #define IntrRxTrigger 0x100 /* rx data count reach trigger value */ 142 142 #define IntrTxTrigger 0x200 /* tx data count below trigger value */ 143 143 144 144 #define Magic_no (Config_base + 0)
+106 -14
drivers/tty/serial/8250/8250_dw.c
··· 19 19 #include <linux/of_irq.h> 20 20 #include <linux/of_platform.h> 21 21 #include <linux/platform_device.h> 22 + #include <linux/workqueue.h> 23 + #include <linux/notifier.h> 22 24 #include <linux/slab.h> 23 25 #include <linux/acpi.h> 24 26 #include <linux/clk.h> ··· 45 43 int msr_mask_off; 46 44 struct clk *clk; 47 45 struct clk *pclk; 46 + struct notifier_block clk_notifier; 47 + struct work_struct clk_work; 48 48 struct reset_control *rst; 49 49 50 50 unsigned int skip_autocfg:1; ··· 56 52 static inline struct dw8250_data *to_dw8250_data(struct dw8250_port_data *data) 57 53 { 58 54 return container_of(data, struct dw8250_data, data); 55 + } 56 + 57 + static inline struct dw8250_data *clk_to_dw8250_data(struct notifier_block *nb) 58 + { 59 + return container_of(nb, struct dw8250_data, clk_notifier); 60 + } 61 + 62 + static inline struct dw8250_data *work_to_dw8250_data(struct work_struct *work) 63 + { 64 + return container_of(work, struct dw8250_data, clk_work); 59 65 } 60 66 61 67 static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value) ··· 274 260 return 0; 275 261 } 276 262 263 + static void dw8250_clk_work_cb(struct work_struct *work) 264 + { 265 + struct dw8250_data *d = work_to_dw8250_data(work); 266 + struct uart_8250_port *up; 267 + unsigned long rate; 268 + 269 + rate = clk_get_rate(d->clk); 270 + if (rate <= 0) 271 + return; 272 + 273 + up = serial8250_get_port(d->data.line); 274 + 275 + serial8250_update_uartclk(&up->port, rate); 276 + } 277 + 278 + static int dw8250_clk_notifier_cb(struct notifier_block *nb, 279 + unsigned long event, void *data) 280 + { 281 + struct dw8250_data *d = clk_to_dw8250_data(nb); 282 + 283 + /* 284 + * We have no choice but to defer the uartclk update due to two 285 + * deadlocks. First one is caused by a recursive mutex lock which 286 + * happens when clk_set_rate() is called from dw8250_set_termios(). 287 + * Second deadlock is more tricky and is caused by an inverted order of 288 + * the clk and tty-port mutexes lock. It happens if clock rate change 289 + * is requested asynchronously while set_termios() is executed between 290 + * tty-port mutex lock and clk_set_rate() function invocation and 291 + * vise-versa. Anyway if we didn't have the reference clock alteration 292 + * in the dw8250_set_termios() method we wouldn't have needed this 293 + * deferred event handling complication. 294 + */ 295 + if (event == POST_RATE_CHANGE) { 296 + queue_work(system_unbound_wq, &d->clk_work); 297 + return NOTIFY_OK; 298 + } 299 + 300 + return NOTIFY_DONE; 301 + } 302 + 277 303 static void 278 304 dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) 279 305 { ··· 329 275 static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios, 330 276 struct ktermios *old) 331 277 { 332 - unsigned int baud = tty_termios_baud_rate(termios); 278 + unsigned long newrate = tty_termios_baud_rate(termios) * 16; 333 279 struct dw8250_data *d = to_dw8250_data(p->private_data); 334 280 long rate; 335 281 int ret; 336 282 337 283 clk_disable_unprepare(d->clk); 338 - rate = clk_round_rate(d->clk, baud * 16); 339 - if (rate < 0) 340 - ret = rate; 341 - else if (rate == 0) 342 - ret = -ENOENT; 343 - else 344 - ret = clk_set_rate(d->clk, rate); 284 + rate = clk_round_rate(d->clk, newrate); 285 + if (rate > 0) { 286 + /* 287 + * Premilinary set the uartclk to the new clock rate so the 288 + * clock update event handler caused by the clk_set_rate() 289 + * calling wouldn't actually update the UART divisor since 290 + * we about to do this anyway. 291 + */ 292 + swap(p->uartclk, rate); 293 + ret = clk_set_rate(d->clk, newrate); 294 + if (ret) 295 + swap(p->uartclk, rate); 296 + } 345 297 clk_prepare_enable(d->clk); 346 298 347 - if (ret) 348 - goto out; 349 - 350 - p->uartclk = rate; 351 - 352 - out: 353 299 p->status &= ~UPSTAT_AUTOCTS; 354 300 if (termios->c_cflag & CRTSCTS) 355 301 p->status |= UPSTAT_AUTOCTS; ··· 371 317 p->serial_out(p, UART_MCR, mcr); 372 318 } 373 319 serial8250_do_set_ldisc(p, termios); 320 + } 321 + 322 + static int dw8250_startup(struct uart_port *p) 323 + { 324 + struct dw8250_data *d = to_dw8250_data(p->private_data); 325 + int ret; 326 + 327 + /* 328 + * Some platforms may provide a reference clock shared between several 329 + * devices. In this case before using the serial port first we have to 330 + * make sure that any clock state change is known to the UART port at 331 + * least post factum. 332 + */ 333 + if (d->clk) { 334 + ret = clk_notifier_register(d->clk, &d->clk_notifier); 335 + if (ret) 336 + dev_warn(p->dev, "Failed to set the clock notifier\n"); 337 + } 338 + 339 + return serial8250_do_startup(p); 340 + } 341 + 342 + static void dw8250_shutdown(struct uart_port *p) 343 + { 344 + struct dw8250_data *d = to_dw8250_data(p->private_data); 345 + 346 + serial8250_do_shutdown(p); 347 + 348 + if (d->clk) { 349 + clk_notifier_unregister(d->clk, &d->clk_notifier); 350 + 351 + flush_work(&d->clk_work); 352 + } 374 353 } 375 354 376 355 /* ··· 501 414 p->serial_out = dw8250_serial_out; 502 415 p->set_ldisc = dw8250_set_ldisc; 503 416 p->set_termios = dw8250_set_termios; 417 + p->startup = dw8250_startup; 418 + p->shutdown = dw8250_shutdown; 504 419 505 420 p->membase = devm_ioremap(dev, regs->start, resource_size(regs)); 506 421 if (!p->membase) ··· 563 474 data->clk = devm_clk_get_optional(dev, NULL); 564 475 if (IS_ERR(data->clk)) 565 476 return PTR_ERR(data->clk); 477 + 478 + INIT_WORK(&data->clk_work, dw8250_clk_work_cb); 479 + data->clk_notifier.notifier_call = dw8250_clk_notifier_cb; 566 480 567 481 err = clk_prepare_enable(data->clk); 568 482 if (err)
+10 -6
drivers/tty/serial/8250/8250_em.c
··· 78 78 79 79 static int serial8250_em_probe(struct platform_device *pdev) 80 80 { 81 - struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 82 - struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 83 81 struct serial8250_em_priv *priv; 84 82 struct uart_8250_port up; 85 - int ret; 83 + struct resource *regs; 84 + int irq, ret; 86 85 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"); 89 93 return -EINVAL; 90 94 } 91 95 ··· 105 101 106 102 memset(&up, 0, sizeof(up)); 107 103 up.port.mapbase = regs->start; 108 - up.port.irq = irq->start; 104 + up.port.irq = irq; 109 105 up.port.type = PORT_UNKNOWN; 110 106 up.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_IOREMAP; 111 107 up.port.dev = &pdev->dev;
+10 -6
drivers/tty/serial/8250/8250_ingenic.c
··· 207 207 static int ingenic_uart_probe(struct platform_device *pdev) 208 208 { 209 209 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); 212 210 struct ingenic_uart_data *data; 213 211 const struct ingenic_uart_config *cdata; 214 212 const struct of_device_id *match; 215 - int err, line; 213 + struct resource *regs; 214 + int irq, err, line; 216 215 217 216 match = of_match_device(of_match, &pdev->dev); 218 217 if (!match) { ··· 220 221 } 221 222 cdata = match->data; 222 223 223 - if (!regs || !irq) { 224 - dev_err(&pdev->dev, "no registers/irq defined\n"); 224 + irq = platform_get_irq(pdev, 0); 225 + if (irq < 0) 226 + return irq; 227 + 228 + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 229 + if (!regs) { 230 + dev_err(&pdev->dev, "no registers defined\n"); 225 231 return -EINVAL; 226 232 } 227 233 ··· 242 238 uart.port.regshift = 2; 243 239 uart.port.serial_out = ingenic_uart_serial_out; 244 240 uart.port.serial_in = ingenic_uart_serial_in; 245 - uart.port.irq = irq->start; 241 + uart.port.irq = irq; 246 242 uart.port.dev = &pdev->dev; 247 243 uart.port.fifosize = cdata->fifosize; 248 244 uart.tx_loadsz = cdata->tx_loadsz;
+2 -2
drivers/tty/serial/8250/8250_men_mcb.c
··· 51 51 return clkval; 52 52 } 53 53 54 - static unsigned int get_num_ports(struct mcb_device *mdev, 54 + static int get_num_ports(struct mcb_device *mdev, 55 55 void __iomem *membase) 56 56 { 57 57 switch (mdev->id) { ··· 140 140 return; 141 141 142 142 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) { 144 144 dev_err(&mdev->dev, "error retrieving number of ports!\n"); 145 145 return; 146 146 }
+10 -6
drivers/tty/serial/8250/8250_mtk.c
··· 512 512 static int mtk8250_probe(struct platform_device *pdev) 513 513 { 514 514 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); 517 515 struct mtk8250_data *data; 518 - int err; 516 + struct resource *regs; 517 + int irq, err; 519 518 520 - if (!regs || !irq) { 521 - dev_err(&pdev->dev, "no registers/irq defined\n"); 519 + irq = platform_get_irq(pdev, 0); 520 + if (irq < 0) 521 + return irq; 522 + 523 + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 524 + if (!regs) { 525 + dev_err(&pdev->dev, "no registers defined\n"); 522 526 return -EINVAL; 523 527 } 524 528 ··· 546 542 547 543 spin_lock_init(&uart.port.lock); 548 544 uart.port.mapbase = regs->start; 549 - uart.port.irq = irq->start; 545 + uart.port.irq = irq; 550 546 uart.port.pm = mtk8250_do_pm; 551 547 uart.port.type = PORT_16550; 552 548 uart.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;
+10 -6
drivers/tty/serial/8250/8250_omap.c
··· 1209 1209 1210 1210 static int omap8250_probe(struct platform_device *pdev) 1211 1211 { 1212 - struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1213 - struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 1214 1212 struct device_node *np = pdev->dev.of_node; 1215 1213 struct omap8250_priv *priv; 1216 1214 const struct omap8250_platdata *pdata; 1217 1215 struct uart_8250_port up; 1218 - int ret; 1216 + struct resource *regs; 1219 1217 void __iomem *membase; 1218 + int irq, ret; 1220 1219 1221 - if (!regs || !irq) { 1222 - dev_err(&pdev->dev, "missing registers or irq\n"); 1220 + irq = platform_get_irq(pdev, 0); 1221 + if (irq < 0) 1222 + return irq; 1223 + 1224 + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1225 + if (!regs) { 1226 + dev_err(&pdev->dev, "missing registers\n"); 1223 1227 return -EINVAL; 1224 1228 } 1225 1229 ··· 1240 1236 up.port.dev = &pdev->dev; 1241 1237 up.port.mapbase = regs->start; 1242 1238 up.port.membase = membase; 1243 - up.port.irq = irq->start; 1239 + up.port.irq = irq; 1244 1240 /* 1245 1241 * It claims to be 16C750 compatible however it is a little different. 1246 1242 * It has EFR and has no FCR7_64byte bit. The AFE (which it claims to
+41
drivers/tty/serial/8250/8250_port.c
··· 16 16 #include <linux/ioport.h> 17 17 #include <linux/init.h> 18 18 #include <linux/console.h> 19 + #include <linux/gpio/consumer.h> 19 20 #include <linux/sysrq.h> 20 21 #include <linux/delay.h> 21 22 #include <linux/platform_device.h> ··· 2631 2630 port->uartclk / 16 / UART_DIV_MAX, 2632 2631 (port->uartclk + tolerance) / 16); 2633 2632 } 2633 + 2634 + /* 2635 + * Note in order to avoid the tty port mutex deadlock don't use the next method 2636 + * within the uart port callbacks. Primarily it's supposed to be utilized to 2637 + * handle a sudden reference clock rate change. 2638 + */ 2639 + void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk) 2640 + { 2641 + struct uart_8250_port *up = up_to_u8250p(port); 2642 + unsigned int baud, quot, frac = 0; 2643 + struct ktermios *termios; 2644 + unsigned long flags; 2645 + 2646 + mutex_lock(&port->state->port.mutex); 2647 + 2648 + if (port->uartclk == uartclk) 2649 + goto out_lock; 2650 + 2651 + port->uartclk = uartclk; 2652 + termios = &port->state->port.tty->termios; 2653 + 2654 + baud = serial8250_get_baud_rate(port, termios, NULL); 2655 + quot = serial8250_get_divisor(port, baud, &frac); 2656 + 2657 + serial8250_rpm_get(up); 2658 + spin_lock_irqsave(&port->lock, flags); 2659 + 2660 + uart_update_timeout(port, termios->c_cflag, baud); 2661 + 2662 + serial8250_set_divisor(port, baud, quot, frac); 2663 + serial_port_out(port, UART_LCR, up->lcr); 2664 + serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS); 2665 + 2666 + spin_unlock_irqrestore(&port->lock, flags); 2667 + serial8250_rpm_put(up); 2668 + 2669 + out_lock: 2670 + mutex_unlock(&port->state->port.mutex); 2671 + } 2672 + EXPORT_SYMBOL_GPL(serial8250_update_uartclk); 2634 2673 2635 2674 void 2636 2675 serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
+8 -6
drivers/tty/serial/8250/8250_pxa.c
··· 18 18 #include <linux/serial_core.h> 19 19 #include <linux/serial_reg.h> 20 20 #include <linux/of.h> 21 - #include <linux/of_irq.h> 22 21 #include <linux/of_platform.h> 23 22 #include <linux/platform_device.h> 24 23 #include <linux/slab.h> ··· 92 93 { 93 94 struct uart_8250_port uart = {}; 94 95 struct pxa8250_data *data; 95 - struct resource *mmres, *irqres; 96 - int ret; 96 + struct resource *mmres; 97 + int irq, ret; 98 + 99 + irq = platform_get_irq(pdev, 0); 100 + if (irq < 0) 101 + return irq; 97 102 98 103 mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); 99 - irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 100 - if (!mmres || !irqres) 104 + if (!mmres) 101 105 return -ENODEV; 102 106 103 107 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); ··· 123 121 uart.port.iotype = UPIO_MEM32; 124 122 uart.port.mapbase = mmres->start; 125 123 uart.port.regshift = 2; 126 - uart.port.irq = irqres->start; 124 + uart.port.irq = irq; 127 125 uart.port.fifosize = 64; 128 126 uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST | UPF_FIXED_TYPE; 129 127 uart.port.dev = &pdev->dev;
+2 -2
drivers/tty/serial/8250/Kconfig
··· 222 222 Say Y here if you have dumb serial boards other than the four 223 223 standard COM 1/2/3/4 ports. This may happen if you have an AST 224 224 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 226 226 serial port hardware which acts similar to standard serial port 227 227 hardware. If you only use the standard COM 1/2/3/4 ports, you can 228 228 say N here to save some memory. You can also say Y if you have an ··· 266 266 depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS 267 267 help 268 268 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> 270 270 271 271 To compile this driver as a module, choose M here: the module 272 272 will be called 8250_boca.
+12 -5
drivers/tty/serial/Kconfig
··· 502 502 can enable its onboard serial port by enabling this option. 503 503 504 504 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 507 507 select SERIAL_CORE_CONSOLE 508 - select SERIAL_EARLYCON if OF 509 508 help 510 509 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. 512 511 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 514 513 (/dev/tty0) will still be used as the system console by default, but 515 514 you can alter that using a kernel command line option such as 516 515 "console=ttymxc0". (Try "man bootparam" or see the documentation of 517 516 your bootloader about how to pass options to the kernel at boot time.) 517 + 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. 518 525 519 526 config SERIAL_UARTLITE 520 527 tristate "Xilinx uartlite serial port support"
+1 -1
drivers/tty/serial/altera_jtaguart.c
··· 27 27 28 28 /* 29 29 * 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 31 31 */ 32 32 33 33 #define ALTERA_JTAGUART_SIZE 8
-1
drivers/tty/serial/amba-pl011.c
··· 2607 2607 uap->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_AMBA_PL011_CONSOLE); 2608 2608 uap->port.flags = UPF_BOOT_AUTOCONF; 2609 2609 uap->port.line = index; 2610 - spin_lock_init(&uap->port.lock); 2611 2610 2612 2611 amba_ports[index] = uap; 2613 2612
+3
drivers/tty/serial/fsl_lpuart.c
··· 1925 1925 tmp_sbr++; 1926 1926 } 1927 1927 1928 + if (tmp_sbr > UARTBAUD_SBR_MASK) 1929 + continue; 1930 + 1928 1931 if (tmp_diff <= baud_diff) { 1929 1932 baud_diff = tmp_diff; 1930 1933 osr = tmp_osr;
+134 -75
drivers/tty/serial/imx.c
··· 20 20 #include <linux/serial.h> 21 21 #include <linux/clk.h> 22 22 #include <linux/delay.h> 23 + #include <linux/ktime.h> 23 24 #include <linux/pinctrl/consumer.h> 24 25 #include <linux/rational.h> 25 26 #include <linux/slab.h> ··· 189 188 enum imx_uart_type devtype; 190 189 }; 191 190 191 + enum imx_tx_state { 192 + OFF, 193 + WAIT_AFTER_RTS, 194 + SEND, 195 + WAIT_AFTER_SEND, 196 + }; 197 + 192 198 struct imx_port { 193 199 struct uart_port port; 194 200 struct timer_list timer; ··· 232 224 unsigned int dma_tx_nents; 233 225 unsigned int saved_reg[10]; 234 226 bool context_saved; 227 + 228 + enum imx_tx_state tx_state; 229 + struct hrtimer trigger_start_tx; 230 + struct hrtimer trigger_stop_tx; 235 231 }; 236 232 237 233 struct imx_port_ucrs { ··· 373 361 /* 374 362 * Save and restore functions for UCR1, UCR2 and UCR3 registers 375 363 */ 376 - #if defined(CONFIG_SERIAL_IMX_CONSOLE) 364 + #if IS_ENABLED(CONFIG_SERIAL_IMX_CONSOLE) 377 365 static void imx_uart_ucrs_save(struct imx_port *sport, 378 366 struct imx_port_ucrs *ucr) 379 367 { ··· 412 400 mctrl_gpio_set(sport->gpios, sport->port.mctrl); 413 401 } 414 402 403 + static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec) 404 + { 405 + long sec = msec / MSEC_PER_SEC; 406 + long nsec = (msec % MSEC_PER_SEC) * 1000000; 407 + ktime_t t = ktime_set(sec, nsec); 408 + 409 + hrtimer_start(hrt, t, HRTIMER_MODE_REL); 410 + } 411 + 415 412 /* called with port.lock taken and irqs off */ 416 413 static void imx_uart_start_rx(struct uart_port *port) 417 414 { ··· 448 427 static void imx_uart_stop_tx(struct uart_port *port) 449 428 { 450 429 struct imx_port *sport = (struct imx_port *)port; 451 - u32 ucr1; 430 + u32 ucr1, ucr4, usr2; 431 + 432 + if (sport->tx_state == OFF) 433 + return; 452 434 453 435 /* 454 436 * We are maybe in the SMP context, so if the DMA TX thread is running ··· 463 439 ucr1 = imx_uart_readl(sport, UCR1); 464 440 imx_uart_writel(sport, ucr1 & ~UCR1_TRDYEN, UCR1); 465 441 466 - /* in rs485 mode disable transmitter if shifter is empty */ 467 - if (port->rs485.flags & SER_RS485_ENABLED && 468 - imx_uart_readl(sport, USR2) & USR2_TXDC) { 469 - u32 ucr2 = imx_uart_readl(sport, UCR2), ucr4; 470 - if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) 471 - imx_uart_rts_active(sport, &ucr2); 472 - else 473 - imx_uart_rts_inactive(sport, &ucr2); 474 - imx_uart_writel(sport, ucr2, UCR2); 442 + usr2 = imx_uart_readl(sport, USR2); 443 + if (!(usr2 & USR2_TXDC)) { 444 + /* The shifter is still busy, so retry once TC triggers */ 445 + return; 446 + } 475 447 476 - imx_uart_start_rx(port); 448 + ucr4 = imx_uart_readl(sport, UCR4); 449 + ucr4 &= ~UCR4_TCEN; 450 + imx_uart_writel(sport, ucr4, UCR4); 477 451 478 - ucr4 = imx_uart_readl(sport, UCR4); 479 - ucr4 &= ~UCR4_TCEN; 480 - imx_uart_writel(sport, ucr4, UCR4); 452 + /* in rs485 mode disable transmitter */ 453 + if (port->rs485.flags & SER_RS485_ENABLED) { 454 + if (sport->tx_state == SEND) { 455 + sport->tx_state = WAIT_AFTER_SEND; 456 + start_hrtimer_ms(&sport->trigger_stop_tx, 457 + port->rs485.delay_rts_after_send); 458 + return; 459 + } 460 + 461 + if (sport->tx_state == WAIT_AFTER_RTS || 462 + sport->tx_state == WAIT_AFTER_SEND) { 463 + u32 ucr2; 464 + 465 + hrtimer_try_to_cancel(&sport->trigger_start_tx); 466 + 467 + ucr2 = imx_uart_readl(sport, UCR2); 468 + if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) 469 + imx_uart_rts_active(sport, &ucr2); 470 + else 471 + imx_uart_rts_inactive(sport, &ucr2); 472 + imx_uart_writel(sport, ucr2, UCR2); 473 + 474 + imx_uart_start_rx(port); 475 + 476 + sport->tx_state = OFF; 477 + } 478 + } else { 479 + sport->tx_state = OFF; 481 480 } 482 481 } 483 482 ··· 698 651 if (!sport->port.x_char && uart_circ_empty(&port->state->xmit)) 699 652 return; 700 653 654 + /* 655 + * We cannot simply do nothing here if sport->tx_state == SEND already 656 + * because UCR1_TXMPTYEN might already have been cleared in 657 + * imx_uart_stop_tx(), but tx_state is still SEND. 658 + */ 659 + 701 660 if (port->rs485.flags & SER_RS485_ENABLED) { 702 - u32 ucr2; 661 + if (sport->tx_state == OFF) { 662 + u32 ucr2 = imx_uart_readl(sport, UCR2); 663 + if (port->rs485.flags & SER_RS485_RTS_ON_SEND) 664 + imx_uart_rts_active(sport, &ucr2); 665 + else 666 + imx_uart_rts_inactive(sport, &ucr2); 667 + imx_uart_writel(sport, ucr2, UCR2); 703 668 704 - ucr2 = imx_uart_readl(sport, UCR2); 705 - if (port->rs485.flags & SER_RS485_RTS_ON_SEND) 706 - imx_uart_rts_active(sport, &ucr2); 707 - else 708 - imx_uart_rts_inactive(sport, &ucr2); 709 - imx_uart_writel(sport, ucr2, UCR2); 669 + if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) 670 + imx_uart_stop_rx(port); 710 671 711 - if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) 712 - imx_uart_stop_rx(port); 713 - 714 - /* 715 - * Enable transmitter and shifter empty irq only if DMA is off. 716 - * In the DMA case this is done in the tx-callback. 717 - */ 718 - if (!sport->dma_is_enabled) { 719 - u32 ucr4 = imx_uart_readl(sport, UCR4); 720 - ucr4 |= UCR4_TCEN; 721 - imx_uart_writel(sport, ucr4, UCR4); 672 + sport->tx_state = WAIT_AFTER_RTS; 673 + start_hrtimer_ms(&sport->trigger_start_tx, 674 + port->rs485.delay_rts_before_send); 675 + return; 722 676 } 677 + 678 + if (sport->tx_state == WAIT_AFTER_SEND 679 + || sport->tx_state == WAIT_AFTER_RTS) { 680 + 681 + hrtimer_try_to_cancel(&sport->trigger_stop_tx); 682 + 683 + /* 684 + * Enable transmitter and shifter empty irq only if DMA 685 + * is off. In the DMA case this is done in the 686 + * tx-callback. 687 + */ 688 + if (!sport->dma_is_enabled) { 689 + u32 ucr4 = imx_uart_readl(sport, UCR4); 690 + ucr4 |= UCR4_TCEN; 691 + imx_uart_writel(sport, ucr4, UCR4); 692 + } 693 + 694 + sport->tx_state = SEND; 695 + } 696 + } else { 697 + sport->tx_state = SEND; 723 698 } 724 699 725 700 if (!sport->dma_is_enabled) { ··· 1699 1630 1700 1631 if (termios->c_cflag & CRTSCTS) 1701 1632 ucr2 &= ~UCR2_IRTS; 1702 - 1703 1633 if (termios->c_cflag & CSTOPB) 1704 1634 ucr2 |= UCR2_STPB; 1705 1635 if (termios->c_cflag & PARENB) { ··· 1925 1857 struct imx_port *sport = (struct imx_port *)port; 1926 1858 u32 ucr2; 1927 1859 1928 - /* unimplemented */ 1929 - rs485conf->delay_rts_before_send = 0; 1930 - rs485conf->delay_rts_after_send = 0; 1931 - 1932 1860 /* RTS is required to control the transmitter */ 1933 1861 if (!sport->have_rtscts && !sport->have_rtsgpio) 1934 1862 rs485conf->flags &= ~SER_RS485_ENABLED; ··· 1979 1915 1980 1916 static struct imx_port *imx_uart_ports[UART_NR]; 1981 1917 1982 - #ifdef CONFIG_SERIAL_IMX_CONSOLE 1918 + #if IS_ENABLED(CONFIG_SERIAL_IMX_CONSOLE) 1983 1919 static void imx_uart_console_putchar(struct uart_port *port, int ch) 1984 1920 { 1985 1921 struct imx_port *sport = (struct imx_port *)port; ··· 2176 2112 2177 2113 #define IMX_CONSOLE &imx_uart_console 2178 2114 2179 - #ifdef CONFIG_OF 2180 - static void imx_uart_console_early_putchar(struct uart_port *port, int ch) 2181 - { 2182 - struct imx_port *sport = (struct imx_port *)port; 2183 - 2184 - while (imx_uart_readl(sport, IMX21_UTS) & UTS_TXFULL) 2185 - cpu_relax(); 2186 - 2187 - imx_uart_writel(sport, ch, URTX0); 2188 - } 2189 - 2190 - static void imx_uart_console_early_write(struct console *con, const char *s, 2191 - unsigned count) 2192 - { 2193 - struct earlycon_device *dev = con->data; 2194 - 2195 - uart_console_write(&dev->port, s, count, imx_uart_console_early_putchar); 2196 - } 2197 - 2198 - static int __init 2199 - imx_console_early_setup(struct earlycon_device *dev, const char *opt) 2200 - { 2201 - if (!dev->port.membase) 2202 - return -ENODEV; 2203 - 2204 - dev->con->write = imx_uart_console_early_write; 2205 - 2206 - return 0; 2207 - } 2208 - OF_EARLYCON_DECLARE(ec_imx6q, "fsl,imx6q-uart", imx_console_early_setup); 2209 - OF_EARLYCON_DECLARE(ec_imx21, "fsl,imx21-uart", imx_console_early_setup); 2210 - #endif 2211 - 2212 2115 #else 2213 2116 #define IMX_CONSOLE NULL 2214 2117 #endif ··· 2252 2221 2253 2222 if (pdata->flags & IMXUART_HAVE_RTSCTS) 2254 2223 sport->have_rtscts = 1; 2224 + } 2225 + 2226 + static enum hrtimer_restart imx_trigger_start_tx(struct hrtimer *t) 2227 + { 2228 + struct imx_port *sport = container_of(t, struct imx_port, trigger_start_tx); 2229 + unsigned long flags; 2230 + 2231 + spin_lock_irqsave(&sport->port.lock, flags); 2232 + if (sport->tx_state == WAIT_AFTER_RTS) 2233 + imx_uart_start_tx(&sport->port); 2234 + spin_unlock_irqrestore(&sport->port.lock, flags); 2235 + 2236 + return HRTIMER_NORESTART; 2237 + } 2238 + 2239 + static enum hrtimer_restart imx_trigger_stop_tx(struct hrtimer *t) 2240 + { 2241 + struct imx_port *sport = container_of(t, struct imx_port, trigger_stop_tx); 2242 + unsigned long flags; 2243 + 2244 + spin_lock_irqsave(&sport->port.lock, flags); 2245 + if (sport->tx_state == WAIT_AFTER_SEND) 2246 + imx_uart_stop_tx(&sport->port); 2247 + spin_unlock_irqrestore(&sport->port.lock, flags); 2248 + 2249 + return HRTIMER_NORESTART; 2255 2250 } 2256 2251 2257 2252 static int imx_uart_probe(struct platform_device *pdev) ··· 2426 2369 2427 2370 clk_disable_unprepare(sport->clk_ipg); 2428 2371 2372 + hrtimer_init(&sport->trigger_start_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 2373 + hrtimer_init(&sport->trigger_stop_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 2374 + sport->trigger_start_tx.function = imx_trigger_start_tx; 2375 + sport->trigger_stop_tx.function = imx_trigger_stop_tx; 2376 + 2429 2377 /* 2430 2378 * Allocate the IRQ(s) i.MX1 has three interrupts whereas later 2431 2379 * chips only have one interrupt. ··· 2467 2405 return ret; 2468 2406 } 2469 2407 } 2470 - 2471 - /* We need to initialize lock even for non-registered console */ 2472 - spin_lock_init(&sport->port.lock); 2473 2408 2474 2409 imx_uart_ports[sport->port.line] = sport; 2475 2410
+50
drivers/tty/serial/imx_earlycon.c
··· 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");
+1 -1
drivers/tty/serial/jsm/jsm_driver.c
··· 16 16 17 17 #include "jsm.h" 18 18 19 - MODULE_AUTHOR("Digi International, http://www.digi.com"); 19 + MODULE_AUTHOR("Digi International, https://www.digi.com"); 20 20 MODULE_DESCRIPTION("Driver for the Digi International Neo and Classic PCI based product line"); 21 21 MODULE_LICENSE("GPL"); 22 22 MODULE_SUPPORTED_DEVICE("jsm");
+2 -1
drivers/tty/serial/kgdboc.c
··· 538 538 539 539 if (!con) { 540 540 /* 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 542 543 * in first and, in any case, on ACPI systems earlycon may 543 544 * defer its own initialization (usually to somewhere within 544 545 * setup_arch() ). To cope with either of these situations
+2
drivers/tty/serial/msm_serial.c
··· 696 696 } 697 697 698 698 static void msm_handle_rx_dm(struct uart_port *port, unsigned int misr) 699 + __must_hold(&port->lock) 699 700 { 700 701 struct tty_port *tport = &port->state->port; 701 702 unsigned int sr; ··· 772 771 } 773 772 774 773 static void msm_handle_rx(struct uart_port *port) 774 + __must_hold(&port->lock) 775 775 { 776 776 struct tty_port *tport = &port->state->port; 777 777 unsigned int sr;
+10 -24
drivers/tty/serial/pch_uart.c
··· 1857 1857 kfree(priv); 1858 1858 return; 1859 1859 } 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) 1862 1862 { 1863 - struct eg20t_port *priv = pci_get_drvdata(pdev); 1863 + struct eg20t_port *priv = dev_get_drvdata(dev); 1864 1864 1865 1865 uart_suspend_port(&pch_uart_driver, &priv->port); 1866 1866 1867 - pci_save_state(pdev); 1868 - pci_set_power_state(pdev, pci_choose_state(pdev, state)); 1869 1867 return 0; 1870 1868 } 1871 1869 1872 - static int pch_uart_pci_resume(struct pci_dev *pdev) 1870 + static int __maybe_unused pch_uart_pci_resume(struct device *dev) 1873 1871 { 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); 1886 1873 1887 1874 uart_resume_port(&pch_uart_driver, &priv->port); 1888 1875 1889 1876 return 0; 1890 1877 } 1891 - #else 1892 - #define pch_uart_pci_suspend NULL 1893 - #define pch_uart_pci_resume NULL 1894 - #endif 1895 1878 1896 1879 static const struct pci_device_id pch_uart_pci_id[] = { 1897 1880 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8811), ··· 1928 1945 return ret; 1929 1946 } 1930 1947 1948 + static SIMPLE_DEV_PM_OPS(pch_uart_pci_pm_ops, 1949 + pch_uart_pci_suspend, 1950 + pch_uart_pci_resume); 1951 + 1931 1952 static struct pci_driver pch_uart_pci_driver = { 1932 1953 .name = "pch_uart", 1933 1954 .id_table = pch_uart_pci_id, 1934 1955 .probe = pch_uart_pci_probe, 1935 1956 .remove = pch_uart_pci_remove, 1936 - .suspend = pch_uart_pci_suspend, 1937 - .resume = pch_uart_pci_resume, 1957 + .driver.pm = &pch_uart_pci_pm_ops, 1938 1958 }; 1939 1959 1940 1960 static int __init pch_uart_module_init(void)
+1
drivers/tty/serial/pmac_zilog.c
··· 213 213 } 214 214 215 215 static bool pmz_receive_chars(struct uart_pmac_port *uap) 216 + __must_hold(&uap->port.lock) 216 217 { 217 218 struct tty_port *port; 218 219 unsigned char ch, r1, drop, flag;
+1 -1
drivers/tty/serial/qcom_geni_serial.c
··· 768 768 u8 buf[sizeof(u32)]; 769 769 int c; 770 770 771 - memset(buf, 0, ARRAY_SIZE(buf)); 771 + memset(buf, 0, sizeof(buf)); 772 772 tx_bytes = min_t(size_t, remaining, BYTES_PER_FIFO_WORD); 773 773 774 774 for (c = 0; c < tx_bytes ; c++) {
+10 -14
drivers/tty/serial/samsung_tty.c
··· 6 6 * http://armlinux.simtec.co.uk/ 7 7 */ 8 8 9 - /* Hote on 2410 error handling 9 + /* Note on 2410 error handling 10 10 * 11 11 * The s3c2410 manual has a love/hate affair with the contents of the 12 12 * UERSTAT register in the UART blocks, and keeps marking some of the ··· 327 327 unsigned long flags; 328 328 int count; 329 329 330 - 331 330 dmaengine_tx_status(dma->tx_chan, dma->tx_cookie, &state); 332 331 count = dma->tx_bytes_requested - state.residue; 333 332 async_tx_ack(dma->tx_desc); ··· 407 408 struct uart_port *port = &ourport->port; 408 409 struct circ_buf *xmit = &port->state->xmit; 409 410 struct s3c24xx_uart_dma *dma = ourport->dma; 410 - 411 411 412 412 if (ourport->tx_mode != S3C24XX_TX_DMA) 413 413 enable_tx_dma(ourport); ··· 814 816 return IRQ_HANDLED; 815 817 } 816 818 817 - 818 819 static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id) 819 820 { 820 821 struct s3c24xx_uart_port *ourport = dev_id; ··· 839 842 count >= ourport->min_dma_size) { 840 843 int align = dma_get_cache_alignment() - 841 844 (xmit->tail & (dma_get_cache_alignment() - 1)); 842 - if (count-align >= ourport->min_dma_size) { 843 - dma_count = count-align; 845 + if (count - align >= ourport->min_dma_size) { 846 + dma_count = count - align; 844 847 count = align; 845 848 } 846 849 } ··· 1586 1589 return 0; 1587 1590 } 1588 1591 1589 - 1590 1592 #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE 1591 1593 1592 1594 static struct console s3c24xx_serial_console; ··· 1668 1672 } 1669 1673 }, 1670 1674 #if CONFIG_SERIAL_SAMSUNG_UARTS > 2 1671 - 1672 1675 [2] = { 1673 1676 .port = { 1674 1677 .lock = __PORT_LOCK_UNLOCKED(2), ··· 1722 1727 /* some delay is required after fifo reset */ 1723 1728 udelay(1); 1724 1729 } 1725 - 1726 1730 1727 1731 #ifdef CONFIG_ARM_S3C24XX_CPUFREQ 1728 1732 ··· 1897 1903 1898 1904 port->mapbase = res->start; 1899 1905 ret = platform_get_irq(platdev, 0); 1900 - if (ret < 0) 1906 + if (ret < 0) { 1901 1907 port->irq = 0; 1902 - else { 1908 + } else { 1903 1909 port->irq = ret; 1904 1910 ourport->rx_irq = ret; 1905 1911 ourport->tx_irq = ret + 1; ··· 1971 1977 1972 1978 static int probe_index; 1973 1979 1974 - static inline struct s3c24xx_serial_drv_data *s3c24xx_get_driver_data( 1975 - struct platform_device *pdev) 1980 + static inline struct s3c24xx_serial_drv_data * 1981 + s3c24xx_get_driver_data(struct platform_device *pdev) 1976 1982 { 1977 1983 #ifdef CONFIG_OF 1978 1984 if (pdev->dev.of_node) { ··· 2323 2329 *baud = rate / (16 * (ubrdiv + 1)); 2324 2330 dev_dbg(port->dev, "calculated baud %d\n", *baud); 2325 2331 } 2326 - 2327 2332 } 2328 2333 2329 2334 static int __init ··· 2689 2696 device->port.private_data = &s3c2410_early_console_data; 2690 2697 return samsung_early_console_setup(device, opt); 2691 2698 } 2699 + 2692 2700 OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart", 2693 2701 s3c2410_early_console_setup); 2694 2702 ··· 2704 2710 device->port.private_data = &s3c2440_early_console_data; 2705 2711 return samsung_early_console_setup(device, opt); 2706 2712 } 2713 + 2707 2714 OF_EARLYCON_DECLARE(s3c2412, "samsung,s3c2412-uart", 2708 2715 s3c2440_early_console_setup); 2709 2716 OF_EARLYCON_DECLARE(s3c2440, "samsung,s3c2440-uart", ··· 2723 2728 device->port.private_data = &s5pv210_early_console_data; 2724 2729 return samsung_early_console_setup(device, opt); 2725 2730 } 2731 + 2726 2732 OF_EARLYCON_DECLARE(s5pv210, "samsung,s5pv210-uart", 2727 2733 s5pv210_early_console_setup); 2728 2734 OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart",
+3 -3
drivers/tty/serial/serial-tegra.c
··· 439 439 /* Overrrun error */ 440 440 flag = TTY_OVERRUN; 441 441 tup->uport.icount.overrun++; 442 - dev_err(tup->uport.dev, "Got overrun errors\n"); 442 + dev_dbg(tup->uport.dev, "Got overrun errors\n"); 443 443 } else if (lsr & UART_LSR_PE) { 444 444 /* Parity error */ 445 445 flag = TTY_PARITY; 446 446 tup->uport.icount.parity++; 447 - dev_err(tup->uport.dev, "Got Parity errors\n"); 447 + dev_dbg(tup->uport.dev, "Got Parity errors\n"); 448 448 } else if (lsr & UART_LSR_FE) { 449 449 flag = TTY_FRAME; 450 450 tup->uport.icount.frame++; 451 - dev_err(tup->uport.dev, "Got frame errors\n"); 451 + dev_dbg(tup->uport.dev, "Got frame errors\n"); 452 452 } else if (lsr & UART_LSR_BI) { 453 453 /* 454 454 * Break error
+4 -1
drivers/tty/serial/serial_core.c
··· 14 14 #include <linux/sched/signal.h> 15 15 #include <linux/init.h> 16 16 #include <linux/console.h> 17 + #include <linux/gpio/consumer.h> 17 18 #include <linux/of.h> 18 19 #include <linux/proc_fs.h> 19 20 #include <linux/seq_file.h> ··· 1121 1120 return ret; 1122 1121 } 1123 1122 1124 - static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state) 1123 + static int uart_do_autoconfig(struct tty_struct *tty, struct uart_state *state) 1125 1124 { 1126 1125 struct tty_port *port = &state->port; 1127 1126 struct uart_port *uport; ··· 1524 1523 /* Handle transition away from B0 status */ 1525 1524 else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { 1526 1525 unsigned int mask = TIOCM_DTR; 1526 + 1527 1527 if (!(cflag & CRTSCTS) || !tty_throttled(tty)) 1528 1528 mask |= TIOCM_RTS; 1529 1529 uart_set_mctrl(uport, mask); ··· 2281 2279 if (console_suspend_enabled || !uart_console(uport)) { 2282 2280 /* Protected by port mutex for now */ 2283 2281 struct tty_struct *tty = port->tty; 2282 + 2284 2283 ret = ops->startup(uport); 2285 2284 if (ret == 0) { 2286 2285 if (tty)
-3
drivers/tty/serial/sh-sci.c
··· 3301 3301 sciport->port.flags |= UPF_HARD_FLOW; 3302 3302 } 3303 3303 3304 - if (sci_uart_driver.cons->index == sciport->port.line) 3305 - spin_lock_init(&sciport->port.lock); 3306 - 3307 3304 ret = uart_add_one_port(&sci_uart_driver, &sciport->port); 3308 3305 if (ret) { 3309 3306 sci_cleanup_single(sciport);
-1
drivers/tty/serial/sifive.c
··· 883 883 884 884 static void __ssp_add_console_port(struct sifive_serial_port *ssp) 885 885 { 886 - spin_lock_init(&ssp->port.lock); 887 886 sifive_serial_console_ports[ssp->port.line] = ssp; 888 887 } 889 888
+11 -2
drivers/tty/serial/stm32-usart.c
··· 129 129 if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { 130 130 cr3 &= ~USART_CR3_DEP; 131 131 rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND; 132 + mctrl_gpio_set(stm32_port->gpios, 133 + stm32_port->port.mctrl & ~TIOCM_RTS); 132 134 } else { 133 135 cr3 |= USART_CR3_DEP; 134 136 rs485conf->flags |= SER_RS485_RTS_AFTER_SEND; 137 + mctrl_gpio_set(stm32_port->gpios, 138 + stm32_port->port.mctrl | TIOCM_RTS); 135 139 } 136 140 137 141 writel_relaxed(cr3, port->membase + ofs->cr3); ··· 851 847 if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { 852 848 cr3 &= ~USART_CR3_DEP; 853 849 rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND; 850 + mctrl_gpio_set(stm32_port->gpios, 851 + stm32_port->port.mctrl & ~TIOCM_RTS); 854 852 } else { 855 853 cr3 |= USART_CR3_DEP; 856 854 rs485conf->flags |= SER_RS485_RTS_AFTER_SEND; 855 + mctrl_gpio_set(stm32_port->gpios, 856 + stm32_port->port.mctrl | TIOCM_RTS); 857 857 } 858 858 859 859 } else { ··· 1041 1033 if (WARN_ON(id >= STM32_MAX_PORTS)) 1042 1034 return NULL; 1043 1035 1044 - stm32_ports[id].hw_flow_control = of_property_read_bool(np, 1045 - "st,hw-flow-ctrl"); 1036 + stm32_ports[id].hw_flow_control = 1037 + of_property_read_bool (np, "st,hw-flow-ctrl") /*deprecated*/ || 1038 + of_property_read_bool (np, "uart-has-rtscts"); 1046 1039 stm32_ports[id].port.line = id; 1047 1040 stm32_ports[id].cr1_irq = USART_CR1_RXNEIE; 1048 1041 stm32_ports[id].cr3_irq = 0;
-3
drivers/tty/serial/sunhv.c
··· 567 567 sunserial_console_match(&sunhv_console, op->dev.of_node, 568 568 &sunhv_reg, port->line, false); 569 569 570 - /* We need to initialize lock even for non-registered console */ 571 - spin_lock_init(&port->lock); 572 - 573 570 err = uart_add_one_port(&sunhv_reg, port); 574 571 if (err) 575 572 goto out_unregister_driver;
+1 -1
drivers/tty/serial/uartlite.c
··· 32 32 * Register definitions 33 33 * 34 34 * 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 36 36 */ 37 37 38 38 #define ULITE_RX 0x00
+109 -241
drivers/tty/synclink.c
··· 252 252 253 253 char device_name[25]; /* device instance name */ 254 254 255 - unsigned int bus_type; /* expansion bus type (ISA,EISA,PCI) */ 256 255 unsigned char bus; /* expansion bus number (zero based) */ 257 256 unsigned char function; /* PCI device number */ 258 257 ··· 3431 3432 char stat_buf[30]; 3432 3433 unsigned long flags; 3433 3434 3434 - if (info->bus_type == MGSL_BUS_TYPE_PCI) { 3435 - seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X", 3436 - info->device_name, info->io_base, info->irq_level, 3437 - info->phys_memory_base, info->phys_lcr_base); 3438 - } else { 3439 - seq_printf(m, "%s:(E)ISA io:%04X irq:%d dma:%d", 3440 - info->device_name, info->io_base, 3441 - info->irq_level, info->dma_level); 3442 - } 3435 + seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X", 3436 + info->device_name, info->io_base, info->irq_level, 3437 + info->phys_memory_base, info->phys_lcr_base); 3443 3438 3444 3439 /* output current serial signal states */ 3445 3440 spin_lock_irqsave(&info->irq_spinlock,flags); ··· 3549 3556 if ( info->max_frame_size % DMABUFFERSIZE ) 3550 3557 BuffersPerFrame++; 3551 3558 3552 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { 3553 - /* 3554 - * The PCI adapter has 256KBytes of shared memory to use. 3555 - * This is 64 PAGE_SIZE buffers. 3556 - * 3557 - * The first page is used for padding at this time so the 3558 - * buffer list does not begin at offset 0 of the PCI 3559 - * adapter's shared memory. 3560 - * 3561 - * The 2nd page is used for the buffer list. A 4K buffer 3562 - * list can hold 128 DMA_BUFFER structures at 32 bytes 3563 - * each. 3564 - * 3565 - * This leaves 62 4K pages. 3566 - * 3567 - * The next N pages are used for transmit frame(s). We 3568 - * reserve enough 4K page blocks to hold the required 3569 - * number of transmit dma buffers (num_tx_dma_buffers), 3570 - * each of MaxFrameSize size. 3571 - * 3572 - * Of the remaining pages (62-N), determine how many can 3573 - * be used to receive full MaxFrameSize inbound frames 3574 - */ 3575 - info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame; 3576 - info->rx_buffer_count = 62 - info->tx_buffer_count; 3577 - } else { 3578 - /* Calculate the number of PAGE_SIZE buffers needed for */ 3579 - /* receive and transmit DMA buffers. */ 3580 - 3581 - 3582 - /* Calculate the number of DMA buffers necessary to */ 3583 - /* hold 7 max size receive frames and one max size transmit frame. */ 3584 - /* The receive buffer count is bumped by one so we avoid an */ 3585 - /* End of List condition if all receive buffers are used when */ 3586 - /* using linked list DMA buffers. */ 3587 - 3588 - info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame; 3589 - info->rx_buffer_count = (BuffersPerFrame * MAXRXFRAMES) + 6; 3590 - 3591 - /* 3592 - * limit total TxBuffers & RxBuffers to 62 4K total 3593 - * (ala PCI Allocation) 3594 - */ 3595 - 3596 - if ( (info->tx_buffer_count + info->rx_buffer_count) > 62 ) 3597 - info->rx_buffer_count = 62 - info->tx_buffer_count; 3598 - 3599 - } 3559 + /* 3560 + * The PCI adapter has 256KBytes of shared memory to use. This is 64 3561 + * PAGE_SIZE buffers. 3562 + * 3563 + * The first page is used for padding at this time so the buffer list 3564 + * does not begin at offset 0 of the PCI adapter's shared memory. 3565 + * 3566 + * The 2nd page is used for the buffer list. A 4K buffer list can hold 3567 + * 128 DMA_BUFFER structures at 32 bytes each. 3568 + * 3569 + * This leaves 62 4K pages. 3570 + * 3571 + * The next N pages are used for transmit frame(s). We reserve enough 3572 + * 4K page blocks to hold the required number of transmit dma buffers 3573 + * (num_tx_dma_buffers), each of MaxFrameSize size. 3574 + * 3575 + * Of the remaining pages (62-N), determine how many can be used to 3576 + * receive full MaxFrameSize inbound frames 3577 + */ 3578 + info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame; 3579 + info->rx_buffer_count = 62 - info->tx_buffer_count; 3600 3580 3601 3581 if ( debug_level >= DEBUG_LEVEL_INFO ) 3602 3582 printk("%s(%d):Allocating %d TX and %d RX DMA buffers.\n", ··· 3618 3652 { 3619 3653 unsigned int i; 3620 3654 3621 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { 3622 - /* PCI adapter uses shared memory. */ 3623 - info->buffer_list = info->memory_base + info->last_mem_alloc; 3624 - info->buffer_list_phys = info->last_mem_alloc; 3625 - info->last_mem_alloc += BUFFERLISTSIZE; 3626 - } else { 3627 - /* ISA adapter uses system memory. */ 3628 - /* The buffer lists are allocated as a common buffer that both */ 3629 - /* the processor and adapter can access. This allows the driver to */ 3630 - /* inspect portions of the buffer while other portions are being */ 3631 - /* updated by the adapter using Bus Master DMA. */ 3632 - 3633 - info->buffer_list = dma_alloc_coherent(NULL, BUFFERLISTSIZE, &info->buffer_list_dma_addr, GFP_KERNEL); 3634 - if (info->buffer_list == NULL) 3635 - return -ENOMEM; 3636 - info->buffer_list_phys = (u32)(info->buffer_list_dma_addr); 3637 - } 3655 + /* PCI adapter uses shared memory. */ 3656 + info->buffer_list = info->memory_base + info->last_mem_alloc; 3657 + info->buffer_list_phys = info->last_mem_alloc; 3658 + info->last_mem_alloc += BUFFERLISTSIZE; 3638 3659 3639 3660 /* We got the memory for the buffer entry lists. */ 3640 3661 /* Initialize the memory block to all zeros. */ ··· 3687 3734 */ 3688 3735 static void mgsl_free_buffer_list_memory( struct mgsl_struct *info ) 3689 3736 { 3690 - if (info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI) 3691 - dma_free_coherent(NULL, BUFFERLISTSIZE, info->buffer_list, info->buffer_list_dma_addr); 3692 - 3693 3737 info->buffer_list = NULL; 3694 3738 info->rx_buffer_list = NULL; 3695 3739 info->tx_buffer_list = NULL; ··· 3712 3762 static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *BufferList,int Buffercount) 3713 3763 { 3714 3764 int i; 3715 - u32 phys_addr; 3716 3765 3717 3766 /* Allocate page sized buffers for the receive buffer list */ 3718 3767 3719 3768 for ( i = 0; i < Buffercount; i++ ) { 3720 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { 3721 - /* PCI adapter uses shared memory buffers. */ 3722 - BufferList[i].virt_addr = info->memory_base + info->last_mem_alloc; 3723 - phys_addr = info->last_mem_alloc; 3724 - info->last_mem_alloc += DMABUFFERSIZE; 3725 - } else { 3726 - /* ISA adapter uses system memory. */ 3727 - BufferList[i].virt_addr = dma_alloc_coherent(NULL, DMABUFFERSIZE, &BufferList[i].dma_addr, GFP_KERNEL); 3728 - if (BufferList[i].virt_addr == NULL) 3729 - return -ENOMEM; 3730 - phys_addr = (u32)(BufferList[i].dma_addr); 3731 - } 3732 - BufferList[i].phys_addr = phys_addr; 3769 + BufferList[i].virt_addr = info->memory_base + info->last_mem_alloc; 3770 + BufferList[i].phys_addr = info->last_mem_alloc; 3771 + info->last_mem_alloc += DMABUFFERSIZE; 3733 3772 } 3734 3773 3735 3774 return 0; ··· 3746 3807 if ( BufferList ) { 3747 3808 for ( i = 0 ; i < Buffercount ; i++ ) { 3748 3809 if ( BufferList[i].virt_addr ) { 3749 - if ( info->bus_type != MGSL_BUS_TYPE_PCI ) 3750 - dma_free_coherent(NULL, DMABUFFERSIZE, BufferList[i].virt_addr, BufferList[i].dma_addr); 3751 3810 BufferList[i].virt_addr = NULL; 3752 3811 } 3753 3812 } ··· 3977 4040 } 3978 4041 info->irq_requested = true; 3979 4042 3980 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { 3981 - if (request_mem_region(info->phys_memory_base,0x40000,"synclink") == NULL) { 3982 - printk( "%s(%d):mem addr conflict device %s Addr=%08X\n", 3983 - __FILE__,__LINE__,info->device_name, info->phys_memory_base); 3984 - goto errout; 3985 - } 3986 - info->shared_mem_requested = true; 3987 - if (request_mem_region(info->phys_lcr_base + info->lcr_offset,128,"synclink") == NULL) { 3988 - printk( "%s(%d):lcr mem addr conflict device %s Addr=%08X\n", 3989 - __FILE__,__LINE__,info->device_name, info->phys_lcr_base + info->lcr_offset); 3990 - goto errout; 3991 - } 3992 - info->lcr_mem_requested = true; 3993 - 3994 - info->memory_base = ioremap(info->phys_memory_base, 3995 - 0x40000); 3996 - if (!info->memory_base) { 3997 - printk( "%s(%d):Can't map shared memory on device %s MemAddr=%08X\n", 3998 - __FILE__,__LINE__,info->device_name, info->phys_memory_base ); 3999 - goto errout; 4000 - } 4001 - 4002 - if ( !mgsl_memory_test(info) ) { 4003 - printk( "%s(%d):Failed shared memory test %s MemAddr=%08X\n", 4004 - __FILE__,__LINE__,info->device_name, info->phys_memory_base ); 4005 - goto errout; 4006 - } 4007 - 4008 - info->lcr_base = ioremap(info->phys_lcr_base, 4009 - PAGE_SIZE); 4010 - if (!info->lcr_base) { 4011 - printk( "%s(%d):Can't map LCR memory on device %s MemAddr=%08X\n", 4012 - __FILE__,__LINE__,info->device_name, info->phys_lcr_base ); 4013 - goto errout; 4014 - } 4015 - info->lcr_base += info->lcr_offset; 4016 - 4017 - } else { 4018 - /* claim DMA channel */ 4019 - 4020 - if (request_dma(info->dma_level,info->device_name) < 0){ 4021 - printk( "%s(%d):Can't request DMA channel on device %s DMA=%d\n", 4022 - __FILE__,__LINE__,info->device_name, info->dma_level ); 4023 - goto errout; 4024 - } 4025 - info->dma_requested = true; 4026 - 4027 - /* ISA adapter uses bus master DMA */ 4028 - set_dma_mode(info->dma_level,DMA_MODE_CASCADE); 4029 - enable_dma(info->dma_level); 4043 + if (request_mem_region(info->phys_memory_base,0x40000,"synclink") == NULL) { 4044 + printk( "%s(%d):mem addr conflict device %s Addr=%08X\n", 4045 + __FILE__,__LINE__,info->device_name, info->phys_memory_base); 4046 + goto errout; 4030 4047 } 4031 - 4048 + info->shared_mem_requested = true; 4049 + if (request_mem_region(info->phys_lcr_base + info->lcr_offset,128,"synclink") == NULL) { 4050 + printk( "%s(%d):lcr mem addr conflict device %s Addr=%08X\n", 4051 + __FILE__,__LINE__,info->device_name, info->phys_lcr_base + info->lcr_offset); 4052 + goto errout; 4053 + } 4054 + info->lcr_mem_requested = true; 4055 + 4056 + info->memory_base = ioremap(info->phys_memory_base, 0x40000); 4057 + if (!info->memory_base) { 4058 + printk( "%s(%d):Can't map shared memory on device %s MemAddr=%08X\n", 4059 + __FILE__,__LINE__,info->device_name, info->phys_memory_base ); 4060 + goto errout; 4061 + } 4062 + 4063 + if ( !mgsl_memory_test(info) ) { 4064 + printk( "%s(%d):Failed shared memory test %s MemAddr=%08X\n", 4065 + __FILE__,__LINE__,info->device_name, info->phys_memory_base ); 4066 + goto errout; 4067 + } 4068 + 4069 + info->lcr_base = ioremap(info->phys_lcr_base, PAGE_SIZE); 4070 + if (!info->lcr_base) { 4071 + printk( "%s(%d):Can't map LCR memory on device %s MemAddr=%08X\n", 4072 + __FILE__,__LINE__,info->device_name, info->phys_lcr_base ); 4073 + goto errout; 4074 + } 4075 + info->lcr_base += info->lcr_offset; 4076 + 4032 4077 if ( mgsl_allocate_dma_buffers(info) < 0 ) { 4033 4078 printk( "%s(%d):Can't allocate DMA buffers on device %s DMA=%d\n", 4034 4079 __FILE__,__LINE__,info->device_name, info->dma_level ); ··· 4119 4200 else if ( info->max_frame_size > 65535 ) 4120 4201 info->max_frame_size = 65535; 4121 4202 4122 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { 4123 - printk( "SyncLink PCI v%d %s: IO=%04X IRQ=%d Mem=%08X,%08X MaxFrameSize=%u\n", 4124 - info->hw_version + 1, info->device_name, info->io_base, info->irq_level, 4125 - info->phys_memory_base, info->phys_lcr_base, 4126 - info->max_frame_size ); 4127 - } else { 4128 - printk( "SyncLink ISA %s: IO=%04X IRQ=%d DMA=%d MaxFrameSize=%u\n", 4129 - info->device_name, info->io_base, info->irq_level, info->dma_level, 4130 - info->max_frame_size ); 4131 - } 4203 + printk( "SyncLink PCI v%d %s: IO=%04X IRQ=%d Mem=%08X,%08X MaxFrameSize=%u\n", 4204 + info->hw_version + 1, info->device_name, info->io_base, info->irq_level, 4205 + info->phys_memory_base, info->phys_lcr_base, 4206 + info->max_frame_size ); 4132 4207 4133 4208 #if SYNCLINK_GENERIC_HDLC 4134 4209 hdlcdev_init(info); ··· 4333 4420 outw( Cmd + info->loopback_bits, info->io_base + CCAR ); 4334 4421 4335 4422 /* Read to flush write to CCAR */ 4336 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) 4337 - inw( info->io_base + CCAR ); 4423 + inw( info->io_base + CCAR ); 4338 4424 4339 4425 } /* end of usc_RTCmd() */ 4340 4426 ··· 4357 4445 outw( Cmd + info->mbre_bit, info->io_base ); 4358 4446 4359 4447 /* Read to flush write to DCAR */ 4360 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) 4361 - inw( info->io_base ); 4448 + inw( info->io_base ); 4362 4449 4363 4450 } /* end of usc_DmaCmd() */ 4364 4451 ··· 4386 4475 outw( RegValue, info->io_base ); 4387 4476 4388 4477 /* Read to flush write to DCAR */ 4389 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) 4390 - inw( info->io_base ); 4478 + inw( info->io_base ); 4391 4479 4392 4480 } /* end of usc_OutDmaReg() */ 4393 4481 ··· 4438 4528 outw( RegValue, info->io_base + CCAR ); 4439 4529 4440 4530 /* Read to flush write to CCAR */ 4441 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) 4442 - inw( info->io_base + CCAR ); 4531 + inw( info->io_base + CCAR ); 4443 4532 4444 4533 } /* end of usc_OutReg() */ 4445 4534 ··· 4637 4728 4638 4729 RegValue = usc_InReg( info, RICR ) & 0xc0; 4639 4730 4640 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) 4641 - usc_OutReg( info, RICR, (u16)(0x030a | RegValue) ); 4642 - else 4643 - usc_OutReg( info, RICR, (u16)(0x140a | RegValue) ); 4731 + usc_OutReg( info, RICR, (u16)(0x030a | RegValue) ); 4644 4732 4645 4733 /* Unlatch all Rx status bits and clear Rx status IRQ Pending */ 4646 4734 ··· 4698 4792 * 0000 0000 0011 0110 = 0x0036 4699 4793 */ 4700 4794 4701 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) 4702 - usc_OutReg( info, TICR, 0x0736 ); 4703 - else 4704 - usc_OutReg( info, TICR, 0x1436 ); 4795 + usc_OutReg( info, TICR, 0x0736 ); 4705 4796 4706 4797 usc_UnlatchTxstatusBits( info, TXSTATUS_ALL ); 4707 4798 usc_ClearIrqPendingBits( info, TRANSMIT_STATUS ); ··· 4788 4885 /* DPLL is enabled. Use BRG1 to provide continuous reference clock */ 4789 4886 /* for DPLL. DPLL mode in HCR is dependent on the encoding used. */ 4790 4887 4791 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) 4792 - XtalSpeed = 11059200; 4793 - else 4794 - XtalSpeed = 14745600; 4888 + XtalSpeed = 11059200; 4795 4889 4796 4890 if ( info->params.flags & HDLC_FLAG_DPLL_DIV16 ) { 4797 4891 DpllDivisor = 16; ··· 4911 5011 * 0110 0000 0000 1011 = 0x600b 4912 5012 */ 4913 5013 4914 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { 4915 - /* PCI adapter does not need DMA wait state */ 4916 - usc_OutDmaReg( info, DCR, 0xa00b ); 4917 - } 4918 - else 4919 - usc_OutDmaReg( info, DCR, 0x800b ); 4920 - 5014 + /* PCI adapter does not need DMA wait state */ 5015 + usc_OutDmaReg( info, DCR, 0xa00b ); 4921 5016 4922 5017 /* Receive DMA mode Register (RDMR) 4923 5018 * ··· 5004 5109 * <7..0> 0x00 Maximum number of clock cycles per bus grant 5005 5110 */ 5006 5111 5007 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { 5008 - /* don't limit bus occupancy on PCI adapter */ 5009 - usc_OutDmaReg( info, BDCR, 0x0000 ); 5010 - } 5011 - else 5012 - usc_OutDmaReg( info, BDCR, 0x2000 ); 5112 + /* don't limit bus occupancy on PCI adapter */ 5113 + usc_OutDmaReg( info, BDCR, 0x0000 ); 5013 5114 5014 5115 usc_stop_transmitter(info); 5015 5116 usc_stop_receiver(info); ··· 5046 5155 /* Write 16-bit Time Constant for BRG0 */ 5047 5156 /* use clock speed if available, otherwise use 8 for diagnostics */ 5048 5157 if (info->params.clock_speed) { 5049 - if (info->bus_type == MGSL_BUS_TYPE_PCI) 5050 - usc_OutReg(info, TC0R, (u16)((11059200/info->params.clock_speed)-1)); 5051 - else 5052 - usc_OutReg(info, TC0R, (u16)((14745600/info->params.clock_speed)-1)); 5158 + usc_OutReg(info, TC0R, (u16)((11059200/info->params.clock_speed)-1)); 5053 5159 } else 5054 5160 usc_OutReg(info, TC0R, (u16)8); 5055 5161 ··· 5089 5201 u16 Tc; 5090 5202 5091 5203 if ( data_rate ) { 5092 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) 5093 - XtalSpeed = 11059200; 5094 - else 5095 - XtalSpeed = 14745600; 5204 + XtalSpeed = 11059200; 5096 5205 5097 5206 5098 5207 /* Tc = (Xtal/Speed) - 1 */ ··· 5567 5682 */ 5568 5683 static void usc_reset( struct mgsl_struct *info ) 5569 5684 { 5570 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { 5571 - int i; 5572 - u32 readval; 5685 + int i; 5686 + u32 readval; 5573 5687 5574 - /* Set BIT30 of Misc Control Register */ 5575 - /* (Local Control Register 0x50) to force reset of USC. */ 5688 + /* Set BIT30 of Misc Control Register */ 5689 + /* (Local Control Register 0x50) to force reset of USC. */ 5576 5690 5577 - volatile u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50); 5578 - u32 *LCR0BRDR = (u32 *)(info->lcr_base + 0x28); 5691 + volatile u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50); 5692 + u32 *LCR0BRDR = (u32 *)(info->lcr_base + 0x28); 5579 5693 5580 - info->misc_ctrl_value |= BIT30; 5581 - *MiscCtrl = info->misc_ctrl_value; 5694 + info->misc_ctrl_value |= BIT30; 5695 + *MiscCtrl = info->misc_ctrl_value; 5582 5696 5583 - /* 5584 - * Force at least 170ns delay before clearing 5585 - * reset bit. Each read from LCR takes at least 5586 - * 30ns so 10 times for 300ns to be safe. 5587 - */ 5588 - for(i=0;i<10;i++) 5589 - readval = *MiscCtrl; 5697 + /* 5698 + * Force at least 170ns delay before clearing reset bit. Each read from 5699 + * LCR takes at least 30ns so 10 times for 300ns to be safe. 5700 + */ 5701 + for(i=0;i<10;i++) 5702 + readval = *MiscCtrl; 5590 5703 5591 - info->misc_ctrl_value &= ~BIT30; 5592 - *MiscCtrl = info->misc_ctrl_value; 5704 + info->misc_ctrl_value &= ~BIT30; 5705 + *MiscCtrl = info->misc_ctrl_value; 5593 5706 5594 - *LCR0BRDR = BUS_DESCRIPTOR( 5595 - 1, // Write Strobe Hold (0-3) 5596 - 2, // Write Strobe Delay (0-3) 5597 - 2, // Read Strobe Delay (0-3) 5598 - 0, // NWDD (Write data-data) (0-3) 5599 - 4, // NWAD (Write Addr-data) (0-31) 5600 - 0, // NXDA (Read/Write Data-Addr) (0-3) 5601 - 0, // NRDD (Read Data-Data) (0-3) 5602 - 5 // NRAD (Read Addr-Data) (0-31) 5603 - ); 5604 - } else { 5605 - /* do HW reset */ 5606 - outb( 0,info->io_base + 8 ); 5607 - } 5707 + *LCR0BRDR = BUS_DESCRIPTOR( 5708 + 1, // Write Strobe Hold (0-3) 5709 + 2, // Write Strobe Delay (0-3) 5710 + 2, // Read Strobe Delay (0-3) 5711 + 0, // NWDD (Write data-data) (0-3) 5712 + 4, // NWAD (Write Addr-data) (0-31) 5713 + 0, // NXDA (Read/Write Data-Addr) (0-3) 5714 + 0, // NRDD (Read Data-Data) (0-3) 5715 + 5 // NRAD (Read Addr-Data) (0-31) 5716 + ); 5608 5717 5609 5718 info->mbre_bit = 0; 5610 5719 info->loopback_bits = 0; ··· 6107 6228 * ClkSpeed = 921600 (ISA), 691200 (PCI) 6108 6229 */ 6109 6230 6110 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) 6111 - usc_OutReg( info, TC0R, (u16)((691200/data_rate) - 1) ); 6112 - else 6113 - usc_OutReg( info, TC0R, (u16)((921600/data_rate) - 1) ); 6114 - 6231 + usc_OutReg( info, TC0R, (u16)((691200/data_rate) - 1) ); 6115 6232 6116 6233 /* 6117 6234 * Hardware Configuration Register (HCR) ··· 6712 6837 6713 6838 /* Actually copy data from source buffer to DMA buffer. */ 6714 6839 /* Also set the data count for this individual DMA buffer. */ 6715 - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) 6716 - mgsl_load_pci_memory(pBufEntry->virt_addr, Buffer,Copycount); 6717 - else 6718 - memcpy(pBufEntry->virt_addr, Buffer, Copycount); 6840 + mgsl_load_pci_memory(pBufEntry->virt_addr, Buffer,Copycount); 6719 6841 6720 6842 pBufEntry->count = Copycount; 6721 6843 ··· 7186 7314 unsigned long i; 7187 7315 unsigned long TestLimit = SHARED_MEM_ADDRESS_SIZE/sizeof(unsigned long); 7188 7316 unsigned long * TestAddr; 7189 - 7190 - if ( info->bus_type != MGSL_BUS_TYPE_PCI ) 7191 - return true; 7192 7317 7193 7318 TestAddr = (unsigned long *)info->memory_base; 7194 7319 ··· 7872 8003 info->lcr_offset = info->phys_lcr_base & (PAGE_SIZE-1); 7873 8004 info->phys_lcr_base &= ~(PAGE_SIZE-1); 7874 8005 7875 - info->bus_type = MGSL_BUS_TYPE_PCI; 7876 8006 info->io_addr_size = 8; 7877 8007 info->irq_flags = IRQF_SHARED; 7878 8008
+26 -26
drivers/tty/tty_io.c
··· 1405 1405 /* Stash the termios data */ 1406 1406 tp = tty->driver->termios[idx]; 1407 1407 if (tp == NULL) { 1408 - tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); 1408 + tp = kmalloc(sizeof(*tp), GFP_KERNEL); 1409 1409 if (tp == NULL) 1410 1410 return; 1411 1411 tty->driver->termios[idx] = tp; ··· 2489 2489 struct serial_struct v; 2490 2490 int flags; 2491 2491 2492 - if (copy_from_user(&v, ss, sizeof(struct serial_struct))) 2492 + if (copy_from_user(&v, ss, sizeof(*ss))) 2493 2493 return -EFAULT; 2494 2494 2495 2495 flags = v.flags & ASYNC_DEPRECATED; ··· 2507 2507 struct serial_struct v; 2508 2508 int err; 2509 2509 2510 - memset(&v, 0, sizeof(struct serial_struct)); 2510 + memset(&v, 0, sizeof(v)); 2511 2511 if (!tty->ops->get_serial) 2512 2512 return -ENOTTY; 2513 2513 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))) 2515 2515 err = -EFAULT; 2516 2516 return err; 2517 2517 } ··· 2673 2673 #ifdef CONFIG_COMPAT 2674 2674 2675 2675 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; 2695 2695 }; 2696 2696 2697 2697 static int compat_tty_tiocsserial(struct tty_struct *tty, ··· 2705 2705 struct serial_struct v; 2706 2706 int flags; 2707 2707 2708 - if (copy_from_user(&v32, ss, sizeof(struct serial_struct32))) 2708 + if (copy_from_user(&v32, ss, sizeof(*ss))) 2709 2709 return -EFAULT; 2710 2710 2711 2711 memcpy(&v, &v32, offsetof(struct serial_struct32, iomem_base)); ··· 2743 2743 0xfffffff : ptr_to_compat(v.iomem_base); 2744 2744 v32.iomem_reg_shift = v.iomem_reg_shift; 2745 2745 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))) 2747 2747 err = -EFAULT; 2748 2748 } 2749 2749 return err; ··· 3215 3215 if (!lines || (flags & TTY_DRIVER_UNNUMBERED_NODE && lines > 1)) 3216 3216 return ERR_PTR(-EINVAL); 3217 3217 3218 - driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); 3218 + driver = kzalloc(sizeof(*driver), GFP_KERNEL); 3219 3219 if (!driver) 3220 3220 return ERR_PTR(-ENOMEM); 3221 3221
+1 -1
drivers/tty/vt/consolemap.c
··· 542 542 if (!ct) 543 543 return 0; 544 544 545 - unilist = vmemdup_user(list, ct * sizeof(struct unipair)); 545 + unilist = vmemdup_user(list, array_size(sizeof(struct unipair), ct)); 546 546 if (IS_ERR(unilist)) 547 547 return PTR_ERR(unilist); 548 548
+2 -1
drivers/tty/vt/keyboard.c
··· 32 32 #include <linux/tty.h> 33 33 #include <linux/tty_flip.h> 34 34 #include <linux/mm.h> 35 + #include <linux/nospec.h> 35 36 #include <linux/string.h> 36 37 #include <linux/init.h> 37 38 #include <linux/slab.h> ··· 2020 2019 goto reterr; 2021 2020 } 2022 2021 kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0'; 2023 - i = kbs->kb_func; 2022 + i = array_index_nospec(kbs->kb_func, MAX_NR_FUNC); 2024 2023 2025 2024 switch (cmd) { 2026 2025 case KDGKBSENT:
+1 -1
drivers/tty/vt/selection.c
··· 193 193 /* Allocate a new buffer before freeing the old one ... */ 194 194 /* chars can take up to 4 bytes with unicode */ 195 195 bp = kmalloc_array((vc_sel.end - vc_sel.start) / 2 + 1, unicode ? 4 : 1, 196 - GFP_KERNEL); 196 + GFP_KERNEL | __GFP_NOWARN); 197 197 if (!bp) { 198 198 printk(KERN_WARNING "selection: kmalloc() failed\n"); 199 199 clear_selection();
+533 -449
drivers/tty/vt/vt.c
··· 127 127 static struct con_driver registered_con_driver[MAX_NR_CON_DRIVER]; 128 128 const struct consw *conswitchp; 129 129 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 - 138 130 /* 139 131 * Here is the default bell parameters: 750HZ, 1/8th of a second 140 132 */ ··· 163 171 int global_cursor_default = -1; 164 172 module_param(global_cursor_default, int, S_IRUGO | S_IWUSR); 165 173 166 - static int cur_default = CUR_DEFAULT; 174 + static int cur_default = CUR_UNDERLINE; 167 175 module_param(cur_default, int, S_IRUGO | S_IWUSR); 168 176 169 177 /* ··· 373 381 struct uni_screen *uniscr = get_vc_uniscr(vc); 374 382 375 383 if (uniscr) 376 - uniscr->lines[vc->vc_y][vc->vc_x] = uc; 384 + uniscr->lines[vc->state.y][vc->state.x] = uc; 377 385 } 378 386 379 387 static void vc_uniscr_insert(struct vc_data *vc, unsigned int nr) ··· 381 389 struct uni_screen *uniscr = get_vc_uniscr(vc); 382 390 383 391 if (uniscr) { 384 - char32_t *ln = uniscr->lines[vc->vc_y]; 385 - unsigned int x = vc->vc_x, cols = vc->vc_cols; 392 + char32_t *ln = uniscr->lines[vc->state.y]; 393 + unsigned int x = vc->state.x, cols = vc->vc_cols; 386 394 387 395 memmove(&ln[x + nr], &ln[x], (cols - x - nr) * sizeof(*ln)); 388 396 memset32(&ln[x], ' ', nr); ··· 394 402 struct uni_screen *uniscr = get_vc_uniscr(vc); 395 403 396 404 if (uniscr) { 397 - char32_t *ln = uniscr->lines[vc->vc_y]; 398 - unsigned int x = vc->vc_x, cols = vc->vc_cols; 405 + char32_t *ln = uniscr->lines[vc->state.y]; 406 + unsigned int x = vc->state.x, cols = vc->vc_cols; 399 407 400 408 memcpy(&ln[x], &ln[x + nr], (cols - x - nr) * sizeof(*ln)); 401 409 memset32(&ln[cols - nr], ' ', nr); ··· 408 416 struct uni_screen *uniscr = get_vc_uniscr(vc); 409 417 410 418 if (uniscr) { 411 - char32_t *ln = uniscr->lines[vc->vc_y]; 419 + char32_t *ln = uniscr->lines[vc->state.y]; 412 420 413 421 memset32(&ln[x], ' ', nr); 414 422 } ··· 697 705 698 706 /* Structure of attributes is hardware-dependent */ 699 707 700 - static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, 701 - u8 _underline, u8 _reverse, u8 _italic) 708 + static u8 build_attr(struct vc_data *vc, u8 _color, 709 + enum vc_intensity _intensity, bool _blink, bool _underline, 710 + bool _reverse, bool _italic) 702 711 { 703 712 if (vc->vc_sw->con_build_attr) 704 713 return vc->vc_sw->con_build_attr(vc, _color, _intensity, ··· 719 726 u8 a = _color; 720 727 if (!vc->vc_can_do_color) 721 728 return _intensity | 722 - (_italic ? 2 : 0) | 723 - (_underline ? 4 : 0) | 724 - (_reverse ? 8 : 0) | 725 - (_blink ? 0x80 : 0); 729 + (_italic << 1) | 730 + (_underline << 2) | 731 + (_reverse << 3) | 732 + (_blink << 7); 726 733 if (_italic) 727 734 a = (a & 0xF0) | vc->vc_itcolor; 728 735 else if (_underline) 729 736 a = (a & 0xf0) | vc->vc_ulcolor; 730 - else if (_intensity == 0) 737 + else if (_intensity == VCI_HALF_BRIGHT) 731 738 a = (a & 0xf0) | vc->vc_halfcolor; 732 739 if (_reverse) 733 - a = ((a) & 0x88) | ((((a) >> 4) | ((a) << 4)) & 0x77); 740 + a = (a & 0x88) | (((a >> 4) | (a << 4)) & 0x77); 734 741 if (_blink) 735 742 a ^= 0x80; 736 - if (_intensity == 2) 743 + if (_intensity == VCI_BOLD) 737 744 a ^= 0x08; 738 745 if (vc->vc_hi_font_mask == 0x100) 739 746 a <<= 1; ··· 743 750 744 751 static void update_attr(struct vc_data *vc) 745 752 { 746 - vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity, 747 - vc->vc_blink, vc->vc_underline, 748 - vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic); 749 - vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' '; 753 + vc->vc_attr = build_attr(vc, vc->state.color, vc->state.intensity, 754 + vc->state.blink, vc->state.underline, 755 + vc->state.reverse ^ vc->vc_decscnm, vc->state.italic); 756 + vc->vc_video_erase_char = ' ' | (build_attr(vc, vc->state.color, 757 + VCI_NORMAL, vc->state.blink, false, 758 + vc->vc_decscnm, false) << 8); 750 759 } 751 760 752 761 /* Note: inverting the screen twice should revert to the original state */ ··· 777 782 } else if (vc->vc_hi_font_mask == 0x100) { 778 783 while (cnt--) { 779 784 a = scr_readw(q); 780 - a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4); 785 + a = (a & 0x11ff) | 786 + ((a & 0xe000) >> 4) | 787 + ((a & 0x0e00) << 4); 781 788 scr_writew(a, q); 782 789 q++; 783 790 } 784 791 } else { 785 792 while (cnt--) { 786 793 a = scr_readw(q); 787 - a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4); 794 + a = (a & 0x88ff) | 795 + ((a & 0x7000) >> 4) | 796 + ((a & 0x0700) << 4); 788 797 scr_writew(a, q); 789 798 q++; 790 799 } ··· 841 842 unsigned short *p = (unsigned short *) vc->vc_pos; 842 843 843 844 vc_uniscr_insert(vc, nr); 844 - scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x - nr) * 2); 845 + scr_memmovew(p + nr, p, (vc->vc_cols - vc->state.x - nr) * 2); 845 846 scr_memsetw(p, vc->vc_video_erase_char, nr * 2); 846 847 vc->vc_need_wrap = 0; 847 848 if (con_should_update(vc)) 848 849 do_update_region(vc, (unsigned long) p, 849 - vc->vc_cols - vc->vc_x); 850 + vc->vc_cols - vc->state.x); 850 851 } 851 852 852 853 static void delete_char(struct vc_data *vc, unsigned int nr) ··· 854 855 unsigned short *p = (unsigned short *) vc->vc_pos; 855 856 856 857 vc_uniscr_delete(vc, nr); 857 - scr_memcpyw(p, p + nr, (vc->vc_cols - vc->vc_x - nr) * 2); 858 - scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char, 858 + scr_memcpyw(p, p + nr, (vc->vc_cols - vc->state.x - nr) * 2); 859 + scr_memsetw(p + vc->vc_cols - vc->state.x - nr, vc->vc_video_erase_char, 859 860 nr * 2); 860 861 vc->vc_need_wrap = 0; 861 862 if (con_should_update(vc)) 862 863 do_update_region(vc, (unsigned long) p, 863 - vc->vc_cols - vc->vc_x); 864 + vc->vc_cols - vc->state.x); 864 865 } 865 866 866 867 static int softcursor_original = -1; ··· 870 871 int i = scr_readw((u16 *) vc->vc_pos); 871 872 u32 type = vc->vc_cursor_type; 872 873 873 - if (! (type & 0x10)) return; 874 - if (softcursor_original != -1) return; 874 + if (!(type & CUR_SW)) 875 + return; 876 + if (softcursor_original != -1) 877 + return; 875 878 softcursor_original = i; 876 - i |= ((type >> 8) & 0xff00 ); 877 - i ^= ((type) & 0xff00 ); 878 - if ((type & 0x20) && ((softcursor_original & 0x7000) == (i & 0x7000))) i ^= 0x7000; 879 - if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700; 880 - scr_writew(i, (u16 *) vc->vc_pos); 879 + i |= CUR_SET(type); 880 + i ^= CUR_CHANGE(type); 881 + if ((type & CUR_ALWAYS_BG) && 882 + (softcursor_original & CUR_BG) == (i & CUR_BG)) 883 + i ^= CUR_BG; 884 + if ((type & CUR_INVERT_FG_BG) && (i & CUR_FG) == ((i & CUR_BG) >> 4)) 885 + i ^= CUR_FG; 886 + scr_writew(i, (u16 *)vc->vc_pos); 881 887 if (con_should_update(vc)) 882 - vc->vc_sw->con_putc(vc, i, vc->vc_y, vc->vc_x); 888 + vc->vc_sw->con_putc(vc, i, vc->state.y, vc->state.x); 883 889 } 884 890 885 891 static void hide_softcursor(struct vc_data *vc) ··· 893 889 scr_writew(softcursor_original, (u16 *)vc->vc_pos); 894 890 if (con_should_update(vc)) 895 891 vc->vc_sw->con_putc(vc, softcursor_original, 896 - vc->vc_y, vc->vc_x); 892 + vc->state.y, vc->state.x); 897 893 softcursor_original = -1; 898 894 } 899 895 } ··· 915 911 if (vc_is_sel(vc)) 916 912 clear_selection(); 917 913 add_softcursor(vc); 918 - if ((vc->vc_cursor_type & 0x0f) != 1) 914 + if (CUR_SIZE(vc->vc_cursor_type) != CUR_NONE) 919 915 vc->vc_sw->con_cursor(vc, CM_DRAW); 920 916 } else 921 917 hide_cursor(vc); ··· 931 927 vc->vc_origin = (unsigned long)vc->vc_screenbuf; 932 928 vc->vc_visible_origin = vc->vc_origin; 933 929 vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size; 934 - vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 2 * vc->vc_x; 930 + vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->state.y + 931 + 2 * vc->state.x; 935 932 } 936 933 937 934 static void save_screen(struct vc_data *vc) ··· 1261 1256 new_origin = (long) newscreen; 1262 1257 new_scr_end = new_origin + new_screen_size; 1263 1258 1264 - if (vc->vc_y > new_rows) { 1265 - if (old_rows - vc->vc_y < new_rows) { 1259 + if (vc->state.y > new_rows) { 1260 + if (old_rows - vc->state.y < new_rows) { 1266 1261 /* 1267 1262 * Cursor near the bottom, copy contents from the 1268 1263 * bottom of buffer ··· 1273 1268 * Cursor is in no man's land, copy 1/2 screenful 1274 1269 * from the top and bottom of cursor position 1275 1270 */ 1276 - first_copied_row = (vc->vc_y - new_rows/2); 1271 + first_copied_row = (vc->state.y - new_rows/2); 1277 1272 } 1278 1273 old_origin += first_copied_row * old_row_size; 1279 1274 } else ··· 1307 1302 /* do part of a reset_terminal() */ 1308 1303 vc->vc_top = 0; 1309 1304 vc->vc_bottom = vc->vc_rows; 1310 - gotoxy(vc, vc->vc_x, vc->vc_y); 1305 + gotoxy(vc, vc->state.x, vc->state.y); 1311 1306 save_cur(vc); 1312 1307 1313 1308 if (tty) { ··· 1404 1399 #define kbdapplic VC_APPLIC 1405 1400 #define lnm VC_CRLF 1406 1401 1407 - /* 1408 - * this is what the terminal answers to a ESC-Z or csi0c query. 1409 - */ 1410 - #define VT100ID "\033[?1;2c" 1411 - #define VT102ID "\033[?6c" 1412 - 1413 1402 const unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7, 1414 1403 8,12,10,14, 9,13,11,15 }; 1415 1404 ··· 1436 1437 int min_y, max_y; 1437 1438 1438 1439 if (new_x < 0) 1439 - vc->vc_x = 0; 1440 + vc->state.x = 0; 1440 1441 else { 1441 1442 if (new_x >= vc->vc_cols) 1442 - vc->vc_x = vc->vc_cols - 1; 1443 + vc->state.x = vc->vc_cols - 1; 1443 1444 else 1444 - vc->vc_x = new_x; 1445 + vc->state.x = new_x; 1445 1446 } 1446 1447 1447 1448 if (vc->vc_decom) { ··· 1452 1453 max_y = vc->vc_rows; 1453 1454 } 1454 1455 if (new_y < min_y) 1455 - vc->vc_y = min_y; 1456 + vc->state.y = min_y; 1456 1457 else if (new_y >= max_y) 1457 - vc->vc_y = max_y - 1; 1458 + vc->state.y = max_y - 1; 1458 1459 else 1459 - vc->vc_y = new_y; 1460 - vc->vc_pos = vc->vc_origin + vc->vc_y * vc->vc_size_row + (vc->vc_x<<1); 1460 + vc->state.y = new_y; 1461 + vc->vc_pos = vc->vc_origin + vc->state.y * vc->vc_size_row + 1462 + (vc->state.x << 1); 1461 1463 vc->vc_need_wrap = 0; 1462 1464 } 1463 1465 ··· 1485 1485 /* don't scroll if above bottom of scrolling region, or 1486 1486 * if below scrolling region 1487 1487 */ 1488 - if (vc->vc_y + 1 == vc->vc_bottom) 1488 + if (vc->state.y + 1 == vc->vc_bottom) 1489 1489 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++; 1492 1492 vc->vc_pos += vc->vc_size_row; 1493 1493 } 1494 1494 vc->vc_need_wrap = 0; ··· 1500 1500 /* don't scroll if below top of scrolling region, or 1501 1501 * if above scrolling region 1502 1502 */ 1503 - if (vc->vc_y == vc->vc_top) 1503 + if (vc->state.y == vc->vc_top) 1504 1504 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--; 1507 1507 vc->vc_pos -= vc->vc_size_row; 1508 1508 } 1509 1509 vc->vc_need_wrap = 0; ··· 1511 1511 1512 1512 static inline void cr(struct vc_data *vc) 1513 1513 { 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; 1516 1516 notify_write(vc, '\r'); 1517 1517 } 1518 1518 1519 1519 static inline void bs(struct vc_data *vc) 1520 1520 { 1521 - if (vc->vc_x) { 1521 + if (vc->state.x) { 1522 1522 vc->vc_pos -= 2; 1523 - vc->vc_x--; 1523 + vc->state.x--; 1524 1524 vc->vc_need_wrap = 0; 1525 1525 notify_write(vc, '\b'); 1526 1526 } ··· 1538 1538 1539 1539 switch (vpar) { 1540 1540 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); 1545 1545 count = (vc->vc_scr_end - vc->vc_pos) >> 1; 1546 1546 start = (unsigned short *)vc->vc_pos; 1547 1547 break; 1548 1548 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); 1551 1551 count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1; 1552 1552 start = (unsigned short *)vc->vc_origin; 1553 1553 break; ··· 1577 1577 switch (vpar) { 1578 1578 case 0: /* erase from cursor to end of line */ 1579 1579 offset = 0; 1580 - count = vc->vc_cols - vc->vc_x; 1580 + count = vc->vc_cols - vc->state.x; 1581 1581 break; 1582 1582 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; 1585 1585 break; 1586 1586 case 2: /* erase whole line */ 1587 - offset = -vc->vc_x; 1587 + offset = -vc->state.x; 1588 1588 count = vc->vc_cols; 1589 1589 break; 1590 1590 default: 1591 1591 return; 1592 1592 } 1593 - vc_uniscr_clear_line(vc, vc->vc_x + offset, count); 1593 + vc_uniscr_clear_line(vc, vc->state.x + offset, count); 1594 1594 scr_memsetw(start + offset, vc->vc_video_erase_char, 2 * count); 1595 1595 vc->vc_need_wrap = 0; 1596 1596 if (con_should_update(vc)) 1597 1597 do_update_region(vc, (unsigned long)(start + offset), count); 1598 1598 } 1599 1599 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) 1601 1602 { /* not vt100? */ 1602 - int count; 1603 + unsigned int count; 1603 1604 1604 1605 if (!vpar) 1605 1606 vpar++; 1606 - count = (vpar > vc->vc_cols - vc->vc_x) ? (vc->vc_cols - vc->vc_x) : vpar; 1607 1607 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); 1609 1611 scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count); 1610 1612 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); 1612 1614 vc->vc_need_wrap = 0; 1613 1615 } 1614 1616 1615 1617 static void default_attr(struct vc_data *vc) 1616 1618 { 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; 1623 1625 } 1624 1626 1625 1627 struct rgb { u8 r; u8 g; u8 b; }; ··· 1657 1655 1658 1656 if (hue == 7 && max <= 0x55) { 1659 1657 hue = 0; 1660 - vc->vc_intensity = 2; 1658 + vc->state.intensity = VCI_BOLD; 1661 1659 } else if (max > 0xaa) 1662 - vc->vc_intensity = 2; 1660 + vc->state.intensity = VCI_BOLD; 1663 1661 else 1664 - vc->vc_intensity = 1; 1662 + vc->state.intensity = VCI_NORMAL; 1665 1663 1666 - vc->vc_color = (vc->vc_color & 0xf0) | hue; 1664 + vc->state.color = (vc->state.color & 0xf0) | hue; 1667 1665 } 1668 1666 1669 1667 static void rgb_background(struct vc_data *vc, const struct rgb *c) 1670 1668 { 1671 1669 /* For backgrounds, err on the dark side. */ 1672 - vc->vc_color = (vc->vc_color & 0x0f) 1670 + vc->state.color = (vc->state.color & 0x0f) 1673 1671 | (c->r&0x80) >> 1 | (c->g&0x80) >> 2 | (c->b&0x80) >> 3; 1674 1672 } 1675 1673 ··· 1720 1718 default_attr(vc); 1721 1719 break; 1722 1720 case 1: 1723 - vc->vc_intensity = 2; 1721 + vc->state.intensity = VCI_BOLD; 1724 1722 break; 1725 1723 case 2: 1726 - vc->vc_intensity = 0; 1724 + vc->state.intensity = VCI_HALF_BRIGHT; 1727 1725 break; 1728 1726 case 3: 1729 - vc->vc_italic = 1; 1727 + vc->state.italic = true; 1730 1728 break; 1731 1729 case 21: 1732 1730 /* ··· 1734 1732 * convert it to a single underline. 1735 1733 */ 1736 1734 case 4: 1737 - vc->vc_underline = 1; 1735 + vc->state.underline = true; 1738 1736 break; 1739 1737 case 5: 1740 - vc->vc_blink = 1; 1738 + vc->state.blink = true; 1741 1739 break; 1742 1740 case 7: 1743 - vc->vc_reverse = 1; 1741 + vc->state.reverse = true; 1744 1742 break; 1745 1743 case 10: /* ANSI X3.64-1979 (SCO-ish?) 1746 1744 * Select primary font, don't display control chars if 1747 1745 * defined, don't set bit 8 on output. 1748 1746 */ 1749 - vc->vc_translate = set_translate(vc->vc_charset == 0 1750 - ? vc->vc_G0_charset 1751 - : vc->vc_G1_charset, vc); 1747 + vc->vc_translate = set_translate(vc->state.Gx_charset[vc->state.charset], vc); 1752 1748 vc->vc_disp_ctrl = 0; 1753 1749 vc->vc_toggle_meta = 0; 1754 1750 break; ··· 1767 1767 vc->vc_toggle_meta = 1; 1768 1768 break; 1769 1769 case 22: 1770 - vc->vc_intensity = 1; 1770 + vc->state.intensity = VCI_NORMAL; 1771 1771 break; 1772 1772 case 23: 1773 - vc->vc_italic = 0; 1773 + vc->state.italic = false; 1774 1774 break; 1775 1775 case 24: 1776 - vc->vc_underline = 0; 1776 + vc->state.underline = false; 1777 1777 break; 1778 1778 case 25: 1779 - vc->vc_blink = 0; 1779 + vc->state.blink = false; 1780 1780 break; 1781 1781 case 27: 1782 - vc->vc_reverse = 0; 1782 + vc->state.reverse = false; 1783 1783 break; 1784 1784 case 38: 1785 1785 i = vc_t416_color(vc, i, rgb_foreground); ··· 1788 1788 i = vc_t416_color(vc, i, rgb_background); 1789 1789 break; 1790 1790 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); 1793 1793 break; 1794 1794 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); 1797 1797 break; 1798 1798 default: 1799 1799 if (vc->vc_par[i] >= 90 && vc->vc_par[i] <= 107) { 1800 1800 if (vc->vc_par[i] < 100) 1801 - vc->vc_intensity = 2; 1801 + vc->state.intensity = VCI_BOLD; 1802 1802 vc->vc_par[i] -= 60; 1803 1803 } 1804 1804 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); 1807 1807 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); 1810 1810 break; 1811 1811 } 1812 1812 update_attr(vc); 1813 1813 } 1814 1814 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) 1816 1816 { 1817 - while (*p) { 1818 - tty_insert_flip_char(port, *p, 0); 1819 - p++; 1820 - } 1817 + tty_insert_flip_string(port, p, len); 1821 1818 tty_schedule_flip(port); 1822 1819 } 1823 1820 1824 1821 static void cursor_report(struct vc_data *vc, struct tty_struct *tty) 1825 1822 { 1826 1823 char buf[40]; 1824 + int len; 1827 1825 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); 1830 1830 } 1831 1831 1832 1832 static inline void status_report(struct tty_struct *tty) 1833 1833 { 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); 1835 1837 } 1836 1838 1837 1839 static inline void respond_ID(struct tty_struct *tty) 1838 1840 { 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); 1840 1845 } 1841 1846 1842 1847 void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry) 1843 1848 { 1844 1849 char buf[8]; 1850 + int len; 1845 1851 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); 1849 1855 } 1850 1856 1851 1857 /* invoked via ioctl(TIOCLINUX) and through set_selection_user */ ··· 1936 1930 case 1: /* set color for underline mode */ 1937 1931 if (vc->vc_can_do_color && vc->vc_par[1] < 16) { 1938 1932 vc->vc_ulcolor = color_table[vc->vc_par[1]]; 1939 - if (vc->vc_underline) 1933 + if (vc->state.underline) 1940 1934 update_attr(vc); 1941 1935 } 1942 1936 break; 1943 1937 case 2: /* set color for half intensity mode */ 1944 1938 if (vc->vc_can_do_color && vc->vc_par[1] < 16) { 1945 1939 vc->vc_halfcolor = color_table[vc->vc_par[1]]; 1946 - if (vc->vc_intensity == 0) 1940 + if (vc->state.intensity == VCI_HALF_BRIGHT) 1947 1941 update_attr(vc); 1948 1942 } 1949 1943 break; ··· 1997 1991 /* console_lock is held */ 1998 1992 static void csi_at(struct vc_data *vc, unsigned int nr) 1999 1993 { 2000 - if (nr > vc->vc_cols - vc->vc_x) 2001 - nr = vc->vc_cols - vc->vc_x; 1994 + if (nr > vc->vc_cols - vc->state.x) 1995 + nr = vc->vc_cols - vc->state.x; 2002 1996 else if (!nr) 2003 1997 nr = 1; 2004 1998 insert_char(vc, nr); ··· 2007 2001 /* console_lock is held */ 2008 2002 static void csi_L(struct vc_data *vc, unsigned int nr) 2009 2003 { 2010 - if (nr > vc->vc_rows - vc->vc_y) 2011 - nr = vc->vc_rows - vc->vc_y; 2004 + if (nr > vc->vc_rows - vc->state.y) 2005 + nr = vc->vc_rows - vc->state.y; 2012 2006 else if (!nr) 2013 2007 nr = 1; 2014 - con_scroll(vc, vc->vc_y, vc->vc_bottom, SM_DOWN, nr); 2008 + con_scroll(vc, vc->state.y, vc->vc_bottom, SM_DOWN, nr); 2015 2009 vc->vc_need_wrap = 0; 2016 2010 } 2017 2011 2018 2012 /* console_lock is held */ 2019 2013 static void csi_P(struct vc_data *vc, unsigned int nr) 2020 2014 { 2021 - if (nr > vc->vc_cols - vc->vc_x) 2022 - nr = vc->vc_cols - vc->vc_x; 2015 + if (nr > vc->vc_cols - vc->state.x) 2016 + nr = vc->vc_cols - vc->state.x; 2023 2017 else if (!nr) 2024 2018 nr = 1; 2025 2019 delete_char(vc, nr); ··· 2028 2022 /* console_lock is held */ 2029 2023 static void csi_M(struct vc_data *vc, unsigned int nr) 2030 2024 { 2031 - if (nr > vc->vc_rows - vc->vc_y) 2032 - nr = vc->vc_rows - vc->vc_y; 2025 + if (nr > vc->vc_rows - vc->state.y) 2026 + nr = vc->vc_rows - vc->state.y; 2033 2027 else if (!nr) 2034 2028 nr=1; 2035 - con_scroll(vc, vc->vc_y, vc->vc_bottom, SM_UP, nr); 2029 + con_scroll(vc, vc->state.y, vc->vc_bottom, SM_UP, nr); 2036 2030 vc->vc_need_wrap = 0; 2037 2031 } 2038 2032 2039 2033 /* console_lock is held (except via vc_init->reset_terminal */ 2040 2034 static void save_cur(struct vc_data *vc) 2041 2035 { 2042 - vc->vc_saved_x = vc->vc_x; 2043 - vc->vc_saved_y = vc->vc_y; 2044 - vc->vc_s_intensity = vc->vc_intensity; 2045 - vc->vc_s_italic = vc->vc_italic; 2046 - vc->vc_s_underline = vc->vc_underline; 2047 - vc->vc_s_blink = vc->vc_blink; 2048 - vc->vc_s_reverse = vc->vc_reverse; 2049 - vc->vc_s_charset = vc->vc_charset; 2050 - vc->vc_s_color = vc->vc_color; 2051 - vc->vc_saved_G0 = vc->vc_G0_charset; 2052 - vc->vc_saved_G1 = vc->vc_G1_charset; 2036 + memcpy(&vc->saved_state, &vc->state, sizeof(vc->state)); 2053 2037 } 2054 2038 2055 2039 /* console_lock is held */ 2056 2040 static void restore_cur(struct vc_data *vc) 2057 2041 { 2058 - gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y); 2059 - vc->vc_intensity = vc->vc_s_intensity; 2060 - vc->vc_italic = vc->vc_s_italic; 2061 - vc->vc_underline = vc->vc_s_underline; 2062 - vc->vc_blink = vc->vc_s_blink; 2063 - vc->vc_reverse = vc->vc_s_reverse; 2064 - vc->vc_charset = vc->vc_s_charset; 2065 - vc->vc_color = vc->vc_s_color; 2066 - vc->vc_G0_charset = vc->vc_saved_G0; 2067 - vc->vc_G1_charset = vc->vc_saved_G1; 2068 - vc->vc_translate = set_translate(vc->vc_charset ? vc->vc_G1_charset : vc->vc_G0_charset, vc); 2042 + memcpy(&vc->state, &vc->saved_state, sizeof(vc->state)); 2043 + 2044 + gotoxy(vc, vc->state.x, vc->state.y); 2045 + vc->vc_translate = set_translate(vc->state.Gx_charset[vc->state.charset], 2046 + vc); 2069 2047 update_attr(vc); 2070 2048 vc->vc_need_wrap = 0; 2071 2049 } ··· 2061 2071 /* console_lock is held (except via vc_init()) */ 2062 2072 static void reset_terminal(struct vc_data *vc, int do_clear) 2063 2073 { 2074 + unsigned int i; 2075 + 2064 2076 vc->vc_top = 0; 2065 2077 vc->vc_bottom = vc->vc_rows; 2066 2078 vc->vc_state = ESnormal; 2067 2079 vc->vc_priv = EPecma; 2068 2080 vc->vc_translate = set_translate(LAT1_MAP, vc); 2069 - vc->vc_G0_charset = LAT1_MAP; 2070 - vc->vc_G1_charset = GRAF_MAP; 2071 - vc->vc_charset = 0; 2081 + vc->state.Gx_charset[0] = LAT1_MAP; 2082 + vc->state.Gx_charset[1] = GRAF_MAP; 2083 + vc->state.charset = 0; 2072 2084 vc->vc_need_wrap = 0; 2073 2085 vc->vc_report_mouse = 0; 2074 2086 vc->vc_utf = default_utf8; ··· 2093 2101 default_attr(vc); 2094 2102 update_attr(vc); 2095 2103 2096 - vc->vc_tab_stop[0] = 2097 - vc->vc_tab_stop[1] = 2098 - vc->vc_tab_stop[2] = 2099 - vc->vc_tab_stop[3] = 2100 - vc->vc_tab_stop[4] = 2101 - vc->vc_tab_stop[5] = 2102 - vc->vc_tab_stop[6] = 2103 - vc->vc_tab_stop[7] = 0x01010101; 2104 + bitmap_zero(vc->vc_tab_stop, VC_TABSTOPS_COUNT); 2105 + for (i = 0; i < VC_TABSTOPS_COUNT; i += 8) 2106 + set_bit(i, vc->vc_tab_stop); 2104 2107 2105 2108 vc->vc_bell_pitch = DEFAULT_BELL_PITCH; 2106 2109 vc->vc_bell_duration = DEFAULT_BELL_DURATION; ··· 2105 2118 save_cur(vc); 2106 2119 if (do_clear) 2107 2120 csi_J(vc, 2); 2121 + } 2122 + 2123 + static void vc_setGx(struct vc_data *vc, unsigned int which, int c) 2124 + { 2125 + unsigned char *charset = &vc->state.Gx_charset[which]; 2126 + 2127 + switch (c) { 2128 + case '0': 2129 + *charset = GRAF_MAP; 2130 + break; 2131 + case 'B': 2132 + *charset = LAT1_MAP; 2133 + break; 2134 + case 'U': 2135 + *charset = IBMPC_MAP; 2136 + break; 2137 + case 'K': 2138 + *charset = USER_MAP; 2139 + break; 2140 + } 2141 + 2142 + if (vc->state.charset == which) 2143 + vc->vc_translate = set_translate(*charset, vc); 2108 2144 } 2109 2145 2110 2146 /* console_lock is held */ ··· 2152 2142 bs(vc); 2153 2143 return; 2154 2144 case 9: 2155 - vc->vc_pos -= (vc->vc_x << 1); 2156 - while (vc->vc_x < vc->vc_cols - 1) { 2157 - vc->vc_x++; 2158 - if (vc->vc_tab_stop[7 & (vc->vc_x >> 5)] & (1 << (vc->vc_x & 31))) 2159 - break; 2160 - } 2161 - vc->vc_pos += (vc->vc_x << 1); 2145 + vc->vc_pos -= (vc->state.x << 1); 2146 + 2147 + vc->state.x = find_next_bit(vc->vc_tab_stop, 2148 + min(vc->vc_cols - 1, VC_TABSTOPS_COUNT), 2149 + vc->state.x + 1); 2150 + if (vc->state.x >= VC_TABSTOPS_COUNT) 2151 + vc->state.x = vc->vc_cols - 1; 2152 + 2153 + vc->vc_pos += (vc->state.x << 1); 2162 2154 notify_write(vc, '\t'); 2163 2155 return; 2164 2156 case 10: case 11: case 12: ··· 2172 2160 cr(vc); 2173 2161 return; 2174 2162 case 14: 2175 - vc->vc_charset = 1; 2176 - vc->vc_translate = set_translate(vc->vc_G1_charset, vc); 2163 + vc->state.charset = 1; 2164 + vc->vc_translate = set_translate(vc->state.Gx_charset[1], vc); 2177 2165 vc->vc_disp_ctrl = 1; 2178 2166 return; 2179 2167 case 15: 2180 - vc->vc_charset = 0; 2181 - vc->vc_translate = set_translate(vc->vc_G0_charset, vc); 2168 + vc->state.charset = 0; 2169 + vc->vc_translate = set_translate(vc->state.Gx_charset[0], vc); 2182 2170 vc->vc_disp_ctrl = 0; 2183 2171 return; 2184 2172 case 24: case 26: ··· 2218 2206 lf(vc); 2219 2207 return; 2220 2208 case 'H': 2221 - vc->vc_tab_stop[7 & (vc->vc_x >> 5)] |= (1 << (vc->vc_x & 31)); 2209 + if (vc->state.x < VC_TABSTOPS_COUNT) 2210 + set_bit(vc->state.x, vc->vc_tab_stop); 2222 2211 return; 2223 2212 case 'Z': 2224 2213 respond_ID(tty); ··· 2333 2320 case 'c': 2334 2321 if (vc->vc_priv == EPdec) { 2335 2322 if (vc->vc_par[0]) 2336 - vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16); 2323 + vc->vc_cursor_type = 2324 + CUR_MAKE(vc->vc_par[0], 2325 + vc->vc_par[1], 2326 + vc->vc_par[2]); 2337 2327 else 2338 2328 vc->vc_cursor_type = cur_default; 2339 2329 return; ··· 2369 2353 case 'G': case '`': 2370 2354 if (vc->vc_par[0]) 2371 2355 vc->vc_par[0]--; 2372 - gotoxy(vc, vc->vc_par[0], vc->vc_y); 2356 + gotoxy(vc, vc->vc_par[0], vc->state.y); 2373 2357 return; 2374 2358 case 'A': 2375 2359 if (!vc->vc_par[0]) 2376 2360 vc->vc_par[0]++; 2377 - gotoxy(vc, vc->vc_x, vc->vc_y - vc->vc_par[0]); 2361 + gotoxy(vc, vc->state.x, vc->state.y - vc->vc_par[0]); 2378 2362 return; 2379 2363 case 'B': case 'e': 2380 2364 if (!vc->vc_par[0]) 2381 2365 vc->vc_par[0]++; 2382 - gotoxy(vc, vc->vc_x, vc->vc_y + vc->vc_par[0]); 2366 + gotoxy(vc, vc->state.x, vc->state.y + vc->vc_par[0]); 2383 2367 return; 2384 2368 case 'C': case 'a': 2385 2369 if (!vc->vc_par[0]) 2386 2370 vc->vc_par[0]++; 2387 - gotoxy(vc, vc->vc_x + vc->vc_par[0], vc->vc_y); 2371 + gotoxy(vc, vc->state.x + vc->vc_par[0], vc->state.y); 2388 2372 return; 2389 2373 case 'D': 2390 2374 if (!vc->vc_par[0]) 2391 2375 vc->vc_par[0]++; 2392 - gotoxy(vc, vc->vc_x - vc->vc_par[0], vc->vc_y); 2376 + gotoxy(vc, vc->state.x - vc->vc_par[0], vc->state.y); 2393 2377 return; 2394 2378 case 'E': 2395 2379 if (!vc->vc_par[0]) 2396 2380 vc->vc_par[0]++; 2397 - gotoxy(vc, 0, vc->vc_y + vc->vc_par[0]); 2381 + gotoxy(vc, 0, vc->state.y + vc->vc_par[0]); 2398 2382 return; 2399 2383 case 'F': 2400 2384 if (!vc->vc_par[0]) 2401 2385 vc->vc_par[0]++; 2402 - gotoxy(vc, 0, vc->vc_y - vc->vc_par[0]); 2386 + gotoxy(vc, 0, vc->state.y - vc->vc_par[0]); 2403 2387 return; 2404 2388 case 'd': 2405 2389 if (vc->vc_par[0]) 2406 2390 vc->vc_par[0]--; 2407 - gotoxay(vc, vc->vc_x ,vc->vc_par[0]); 2391 + gotoxay(vc, vc->state.x ,vc->vc_par[0]); 2408 2392 return; 2409 2393 case 'H': case 'f': 2410 2394 if (vc->vc_par[0]) ··· 2433 2417 respond_ID(tty); 2434 2418 return; 2435 2419 case 'g': 2436 - if (!vc->vc_par[0]) 2437 - vc->vc_tab_stop[7 & (vc->vc_x >> 5)] &= ~(1 << (vc->vc_x & 31)); 2438 - else if (vc->vc_par[0] == 3) { 2439 - vc->vc_tab_stop[0] = 2440 - vc->vc_tab_stop[1] = 2441 - vc->vc_tab_stop[2] = 2442 - vc->vc_tab_stop[3] = 2443 - vc->vc_tab_stop[4] = 2444 - vc->vc_tab_stop[5] = 2445 - vc->vc_tab_stop[6] = 2446 - vc->vc_tab_stop[7] = 0; 2447 - } 2420 + if (!vc->vc_par[0] && vc->state.x < VC_TABSTOPS_COUNT) 2421 + set_bit(vc->state.x, vc->vc_tab_stop); 2422 + else if (vc->vc_par[0] == 3) 2423 + bitmap_zero(vc->vc_tab_stop, VC_TABSTOPS_COUNT); 2448 2424 return; 2449 2425 case 'm': 2450 2426 csi_m(vc); ··· 2510 2502 } 2511 2503 return; 2512 2504 case ESsetG0: 2513 - if (c == '0') 2514 - vc->vc_G0_charset = GRAF_MAP; 2515 - else if (c == 'B') 2516 - vc->vc_G0_charset = LAT1_MAP; 2517 - else if (c == 'U') 2518 - vc->vc_G0_charset = IBMPC_MAP; 2519 - else if (c == 'K') 2520 - vc->vc_G0_charset = USER_MAP; 2521 - if (vc->vc_charset == 0) 2522 - vc->vc_translate = set_translate(vc->vc_G0_charset, vc); 2505 + vc_setGx(vc, 0, c); 2523 2506 vc->vc_state = ESnormal; 2524 2507 return; 2525 2508 case ESsetG1: 2526 - if (c == '0') 2527 - vc->vc_G1_charset = GRAF_MAP; 2528 - else if (c == 'B') 2529 - vc->vc_G1_charset = LAT1_MAP; 2530 - else if (c == 'U') 2531 - vc->vc_G1_charset = IBMPC_MAP; 2532 - else if (c == 'K') 2533 - vc->vc_G1_charset = USER_MAP; 2534 - if (vc->vc_charset == 1) 2535 - vc->vc_translate = set_translate(vc->vc_G1_charset, vc); 2509 + vc_setGx(vc, 1, c); 2536 2510 vc->vc_state = ESnormal; 2537 2511 return; 2538 2512 case ESosc: ··· 2526 2536 2527 2537 /* is_double_width() is based on the wcwidth() implementation by 2528 2538 * Markus Kuhn -- 2007-05-26 (Unicode 5.0) 2529 - * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c 2539 + * Latest version: https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c 2530 2540 */ 2531 2541 struct interval { 2532 2542 uint32_t first; ··· 2561 2571 sizeof(struct interval), ucs_cmp) != NULL; 2562 2572 } 2563 2573 2564 - static void con_flush(struct vc_data *vc, unsigned long draw_from, 2565 - unsigned long draw_to, int *draw_x) 2574 + struct vc_draw_region { 2575 + unsigned long from, to; 2576 + int x; 2577 + }; 2578 + 2579 + static void con_flush(struct vc_data *vc, struct vc_draw_region *draw) 2566 2580 { 2567 - if (*draw_x < 0) 2581 + if (draw->x < 0) 2568 2582 return; 2569 2583 2570 - vc->vc_sw->con_putcs(vc, (u16 *)draw_from, 2571 - (u16 *)draw_to - (u16 *)draw_from, vc->vc_y, *draw_x); 2572 - *draw_x = -1; 2584 + vc->vc_sw->con_putcs(vc, (u16 *)draw->from, 2585 + (u16 *)draw->to - (u16 *)draw->from, vc->state.y, 2586 + draw->x); 2587 + draw->x = -1; 2588 + } 2589 + 2590 + static inline int vc_translate_ascii(const struct vc_data *vc, int c) 2591 + { 2592 + if (IS_ENABLED(CONFIG_CONSOLE_TRANSLATIONS)) { 2593 + if (vc->vc_toggle_meta) 2594 + c |= 0x80; 2595 + 2596 + return vc->vc_translate[c]; 2597 + } 2598 + 2599 + return c; 2600 + } 2601 + 2602 + 2603 + /** 2604 + * vc_sanitize_unicode -- Replace invalid Unicode code points with U+FFFD 2605 + * @c: the received character, or U+FFFD for invalid sequences. 2606 + */ 2607 + static inline int vc_sanitize_unicode(const int c) 2608 + { 2609 + if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff) 2610 + return 0xfffd; 2611 + 2612 + return c; 2613 + } 2614 + 2615 + /** 2616 + * vc_translate_unicode -- Combine UTF-8 into Unicode in @vc_utf_char 2617 + * 2618 + * @vc_utf_char is the being-constructed unicode character. 2619 + * @vc_utf_count is the number of continuation bytes still expected to arrive. 2620 + * @vc_npar is the number of continuation bytes arrived so far. 2621 + */ 2622 + static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan) 2623 + { 2624 + static const u32 utf8_length_changes[] = { 2625 + 0x0000007f, 0x000007ff, 0x0000ffff, 2626 + 0x001fffff, 0x03ffffff, 0x7fffffff 2627 + }; 2628 + 2629 + /* Continuation byte received */ 2630 + if ((c & 0xc0) == 0x80) { 2631 + /* Unexpected continuation byte? */ 2632 + if (!vc->vc_utf_count) 2633 + return 0xfffd; 2634 + 2635 + vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f); 2636 + vc->vc_npar++; 2637 + if (--vc->vc_utf_count) 2638 + goto need_more_bytes; 2639 + 2640 + /* Got a whole character */ 2641 + c = vc->vc_utf_char; 2642 + /* Reject overlong sequences */ 2643 + if (c <= utf8_length_changes[vc->vc_npar - 1] || 2644 + c > utf8_length_changes[vc->vc_npar]) 2645 + return 0xfffd; 2646 + 2647 + return vc_sanitize_unicode(c); 2648 + } 2649 + 2650 + /* Single ASCII byte or first byte of a sequence received */ 2651 + if (vc->vc_utf_count) { 2652 + /* Continuation byte expected */ 2653 + *rescan = true; 2654 + vc->vc_utf_count = 0; 2655 + return 0xfffd; 2656 + } 2657 + 2658 + /* Nothing to do if an ASCII byte was received */ 2659 + if (c <= 0x7f) 2660 + return c; 2661 + 2662 + /* First byte of a multibyte sequence received */ 2663 + vc->vc_npar = 0; 2664 + if ((c & 0xe0) == 0xc0) { 2665 + vc->vc_utf_count = 1; 2666 + vc->vc_utf_char = (c & 0x1f); 2667 + } else if ((c & 0xf0) == 0xe0) { 2668 + vc->vc_utf_count = 2; 2669 + vc->vc_utf_char = (c & 0x0f); 2670 + } else if ((c & 0xf8) == 0xf0) { 2671 + vc->vc_utf_count = 3; 2672 + vc->vc_utf_char = (c & 0x07); 2673 + } else if ((c & 0xfc) == 0xf8) { 2674 + vc->vc_utf_count = 4; 2675 + vc->vc_utf_char = (c & 0x03); 2676 + } else if ((c & 0xfe) == 0xfc) { 2677 + vc->vc_utf_count = 5; 2678 + vc->vc_utf_char = (c & 0x01); 2679 + } else { 2680 + /* 254 and 255 are invalid */ 2681 + return 0xfffd; 2682 + } 2683 + 2684 + need_more_bytes: 2685 + return -1; 2686 + } 2687 + 2688 + static int vc_translate(struct vc_data *vc, int *c, bool *rescan) 2689 + { 2690 + /* Do no translation at all in control states */ 2691 + if (vc->vc_state != ESnormal) 2692 + return *c; 2693 + 2694 + if (vc->vc_utf && !vc->vc_disp_ctrl) 2695 + return *c = vc_translate_unicode(vc, *c, rescan); 2696 + 2697 + /* no utf or alternate charset mode */ 2698 + return vc_translate_ascii(vc, *c); 2699 + } 2700 + 2701 + static inline unsigned char vc_invert_attr(const struct vc_data *vc) 2702 + { 2703 + if (!vc->vc_can_do_color) 2704 + return vc->vc_attr ^ 0x08; 2705 + 2706 + if (vc->vc_hi_font_mask == 0x100) 2707 + return (vc->vc_attr & 0x11) | 2708 + ((vc->vc_attr & 0xe0) >> 4) | 2709 + ((vc->vc_attr & 0x0e) << 4); 2710 + 2711 + return (vc->vc_attr & 0x88) | 2712 + ((vc->vc_attr & 0x70) >> 4) | 2713 + ((vc->vc_attr & 0x07) << 4); 2714 + } 2715 + 2716 + static bool vc_is_control(struct vc_data *vc, int tc, int c) 2717 + { 2718 + /* 2719 + * A bitmap for codes <32. A bit of 1 indicates that the code 2720 + * corresponding to that bit number invokes some special action (such 2721 + * as cursor movement) and should not be displayed as a glyph unless 2722 + * the disp_ctrl mode is explicitly enabled. 2723 + */ 2724 + static const u32 CTRL_ACTION = 0x0d00ff81; 2725 + /* Cannot be overridden by disp_ctrl */ 2726 + static const u32 CTRL_ALWAYS = 0x0800f501; 2727 + 2728 + if (vc->vc_state != ESnormal) 2729 + return true; 2730 + 2731 + if (!tc) 2732 + return true; 2733 + 2734 + /* 2735 + * If the original code was a control character we only allow a glyph 2736 + * to be displayed if the code is not normally used (such as for cursor 2737 + * movement) or if the disp_ctrl mode has been explicitly enabled. 2738 + * Certain characters (as given by the CTRL_ALWAYS bitmap) are always 2739 + * displayed as control characters, as the console would be pretty 2740 + * useless without them; to display an arbitrary font position use the 2741 + * direct-to-font zone in UTF-8 mode. 2742 + */ 2743 + if (c < 32) { 2744 + if (vc->vc_disp_ctrl) 2745 + return CTRL_ALWAYS & BIT(c); 2746 + else 2747 + return vc->vc_utf || (CTRL_ACTION & BIT(c)); 2748 + } 2749 + 2750 + if (c == 127 && !vc->vc_disp_ctrl) 2751 + return true; 2752 + 2753 + if (c == 128 + 27) 2754 + return true; 2755 + 2756 + return false; 2757 + } 2758 + 2759 + static int vc_con_write_normal(struct vc_data *vc, int tc, int c, 2760 + struct vc_draw_region *draw) 2761 + { 2762 + int next_c; 2763 + unsigned char vc_attr = vc->vc_attr; 2764 + u16 himask = vc->vc_hi_font_mask, charmask = himask ? 0x1ff : 0xff; 2765 + u8 width = 1; 2766 + bool inverse = false; 2767 + 2768 + if (vc->vc_utf && !vc->vc_disp_ctrl) { 2769 + if (is_double_width(c)) 2770 + width = 2; 2771 + } 2772 + 2773 + /* Now try to find out how to display it */ 2774 + tc = conv_uni_to_pc(vc, tc); 2775 + if (tc & ~charmask) { 2776 + if (tc == -1 || tc == -2) 2777 + return -1; /* nothing to display */ 2778 + 2779 + /* Glyph not found */ 2780 + if ((!vc->vc_utf || vc->vc_disp_ctrl || c < 128) && 2781 + !(c & ~charmask)) { 2782 + /* 2783 + * In legacy mode use the glyph we get by a 1:1 2784 + * mapping. 2785 + * This would make absolutely no sense with Unicode in 2786 + * mind, but do this for ASCII characters since a font 2787 + * may lack Unicode mapping info and we don't want to 2788 + * end up with having question marks only. 2789 + */ 2790 + tc = c; 2791 + } else { 2792 + /* 2793 + * Display U+FFFD. If it's not found, display an inverse 2794 + * question mark. 2795 + */ 2796 + tc = conv_uni_to_pc(vc, 0xfffd); 2797 + if (tc < 0) { 2798 + inverse = true; 2799 + tc = conv_uni_to_pc(vc, '?'); 2800 + if (tc < 0) 2801 + tc = '?'; 2802 + 2803 + vc_attr = vc_invert_attr(vc); 2804 + con_flush(vc, draw); 2805 + } 2806 + } 2807 + } 2808 + 2809 + next_c = c; 2810 + while (1) { 2811 + if (vc->vc_need_wrap || vc->vc_decim) 2812 + con_flush(vc, draw); 2813 + if (vc->vc_need_wrap) { 2814 + cr(vc); 2815 + lf(vc); 2816 + } 2817 + if (vc->vc_decim) 2818 + insert_char(vc, 1); 2819 + vc_uniscr_putc(vc, next_c); 2820 + 2821 + if (himask) 2822 + tc = ((tc & 0x100) ? himask : 0) | 2823 + (tc & 0xff); 2824 + tc |= (vc_attr << 8) & ~himask; 2825 + 2826 + scr_writew(tc, (u16 *)vc->vc_pos); 2827 + 2828 + if (con_should_update(vc) && draw->x < 0) { 2829 + draw->x = vc->state.x; 2830 + draw->from = vc->vc_pos; 2831 + } 2832 + if (vc->state.x == vc->vc_cols - 1) { 2833 + vc->vc_need_wrap = vc->vc_decawm; 2834 + draw->to = vc->vc_pos + 2; 2835 + } else { 2836 + vc->state.x++; 2837 + draw->to = (vc->vc_pos += 2); 2838 + } 2839 + 2840 + if (!--width) 2841 + break; 2842 + 2843 + /* A space is printed in the second column */ 2844 + tc = conv_uni_to_pc(vc, ' '); 2845 + if (tc < 0) 2846 + tc = ' '; 2847 + next_c = ' '; 2848 + } 2849 + notify_write(vc, c); 2850 + 2851 + if (inverse) 2852 + con_flush(vc, draw); 2853 + 2854 + return 0; 2573 2855 } 2574 2856 2575 2857 /* acquires console_lock */ 2576 2858 static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count) 2577 2859 { 2578 - int c, next_c, tc, ok, n = 0, draw_x = -1; 2860 + struct vc_draw_region draw = { 2861 + .x = -1, 2862 + }; 2863 + int c, tc, n = 0; 2579 2864 unsigned int currcons; 2580 - unsigned long draw_from = 0, draw_to = 0; 2581 2865 struct vc_data *vc; 2582 - unsigned char vc_attr; 2583 2866 struct vt_notifier_param param; 2584 - uint8_t rescan; 2585 - uint8_t inverse; 2586 - uint8_t width; 2587 - u16 himask, charmask; 2867 + bool rescan; 2588 2868 2589 2869 if (in_interrupt()) 2590 2870 return count; ··· 2875 2615 return 0; 2876 2616 } 2877 2617 2878 - himask = vc->vc_hi_font_mask; 2879 - charmask = himask ? 0x1ff : 0xff; 2880 2618 2881 2619 /* undraw cursor first */ 2882 2620 if (con_is_fg(vc)) ··· 2884 2626 2885 2627 while (!tty->stopped && count) { 2886 2628 int orig = *buf; 2887 - c = orig; 2888 2629 buf++; 2889 2630 n++; 2890 2631 count--; 2891 - rescan = 0; 2892 - inverse = 0; 2893 - width = 1; 2894 - 2895 - /* Do no translation at all in control states */ 2896 - if (vc->vc_state != ESnormal) { 2897 - tc = c; 2898 - } else if (vc->vc_utf && !vc->vc_disp_ctrl) { 2899 - /* Combine UTF-8 into Unicode in vc_utf_char. 2900 - * vc_utf_count is the number of continuation bytes still 2901 - * expected to arrive. 2902 - * vc_npar is the number of continuation bytes arrived so 2903 - * far 2904 - */ 2905 2632 rescan_last_byte: 2906 - if ((c & 0xc0) == 0x80) { 2907 - /* Continuation byte received */ 2908 - static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff }; 2909 - if (vc->vc_utf_count) { 2910 - vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f); 2911 - vc->vc_npar++; 2912 - if (--vc->vc_utf_count) { 2913 - /* Still need some bytes */ 2914 - continue; 2915 - } 2916 - /* Got a whole character */ 2917 - c = vc->vc_utf_char; 2918 - /* Reject overlong sequences */ 2919 - if (c <= utf8_length_changes[vc->vc_npar - 1] || 2920 - c > utf8_length_changes[vc->vc_npar]) 2921 - c = 0xfffd; 2922 - } else { 2923 - /* Unexpected continuation byte */ 2924 - vc->vc_utf_count = 0; 2925 - c = 0xfffd; 2926 - } 2927 - } else { 2928 - /* Single ASCII byte or first byte of a sequence received */ 2929 - if (vc->vc_utf_count) { 2930 - /* Continuation byte expected */ 2931 - rescan = 1; 2932 - vc->vc_utf_count = 0; 2933 - c = 0xfffd; 2934 - } else if (c > 0x7f) { 2935 - /* First byte of a multibyte sequence received */ 2936 - vc->vc_npar = 0; 2937 - if ((c & 0xe0) == 0xc0) { 2938 - vc->vc_utf_count = 1; 2939 - vc->vc_utf_char = (c & 0x1f); 2940 - } else if ((c & 0xf0) == 0xe0) { 2941 - vc->vc_utf_count = 2; 2942 - vc->vc_utf_char = (c & 0x0f); 2943 - } else if ((c & 0xf8) == 0xf0) { 2944 - vc->vc_utf_count = 3; 2945 - vc->vc_utf_char = (c & 0x07); 2946 - } else if ((c & 0xfc) == 0xf8) { 2947 - vc->vc_utf_count = 4; 2948 - vc->vc_utf_char = (c & 0x03); 2949 - } else if ((c & 0xfe) == 0xfc) { 2950 - vc->vc_utf_count = 5; 2951 - vc->vc_utf_char = (c & 0x01); 2952 - } else { 2953 - /* 254 and 255 are invalid */ 2954 - c = 0xfffd; 2955 - } 2956 - if (vc->vc_utf_count) { 2957 - /* Still need some bytes */ 2958 - continue; 2959 - } 2960 - } 2961 - /* Nothing to do if an ASCII byte was received */ 2962 - } 2963 - /* End of UTF-8 decoding. */ 2964 - /* c is the received character, or U+FFFD for invalid sequences. */ 2965 - /* Replace invalid Unicode code points with U+FFFD too */ 2966 - if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff) 2967 - c = 0xfffd; 2968 - tc = c; 2969 - } else { /* no utf or alternate charset mode */ 2970 - tc = vc_translate(vc, c); 2971 - } 2633 + c = orig; 2634 + rescan = false; 2635 + 2636 + tc = vc_translate(vc, &c, &rescan); 2637 + if (tc == -1) 2638 + continue; 2972 2639 2973 2640 param.c = tc; 2974 2641 if (atomic_notifier_call_chain(&vt_notifier_list, VT_PREWRITE, 2975 2642 &param) == NOTIFY_STOP) 2976 2643 continue; 2977 2644 2978 - /* If the original code was a control character we 2979 - * only allow a glyph to be displayed if the code is 2980 - * not normally used (such as for cursor movement) or 2981 - * if the disp_ctrl mode has been explicitly enabled. 2982 - * Certain characters (as given by the CTRL_ALWAYS 2983 - * bitmap) are always displayed as control characters, 2984 - * as the console would be pretty useless without 2985 - * them; to display an arbitrary font position use the 2986 - * direct-to-font zone in UTF-8 mode. 2987 - */ 2988 - ok = tc && (c >= 32 || 2989 - !(vc->vc_disp_ctrl ? (CTRL_ALWAYS >> c) & 1 : 2990 - vc->vc_utf || ((CTRL_ACTION >> c) & 1))) 2991 - && (c != 127 || vc->vc_disp_ctrl) 2992 - && (c != 128+27); 2993 - 2994 - if (vc->vc_state == ESnormal && ok) { 2995 - if (vc->vc_utf && !vc->vc_disp_ctrl) { 2996 - if (is_double_width(c)) 2997 - width = 2; 2998 - } 2999 - /* Now try to find out how to display it */ 3000 - tc = conv_uni_to_pc(vc, tc); 3001 - if (tc & ~charmask) { 3002 - if (tc == -1 || tc == -2) { 3003 - continue; /* nothing to display */ 3004 - } 3005 - /* Glyph not found */ 3006 - if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) && !(c & ~charmask)) { 3007 - /* In legacy mode use the glyph we get by a 1:1 mapping. 3008 - This would make absolutely no sense with Unicode in mind, 3009 - but do this for ASCII characters since a font may lack 3010 - Unicode mapping info and we don't want to end up with 3011 - having question marks only. */ 3012 - tc = c; 3013 - } else { 3014 - /* Display U+FFFD. If it's not found, display an inverse question mark. */ 3015 - tc = conv_uni_to_pc(vc, 0xfffd); 3016 - if (tc < 0) { 3017 - inverse = 1; 3018 - tc = conv_uni_to_pc(vc, '?'); 3019 - if (tc < 0) tc = '?'; 3020 - } 3021 - } 3022 - } 3023 - 3024 - if (!inverse) { 3025 - vc_attr = vc->vc_attr; 3026 - } else { 3027 - /* invert vc_attr */ 3028 - if (!vc->vc_can_do_color) { 3029 - vc_attr = (vc->vc_attr) ^ 0x08; 3030 - } else if (vc->vc_hi_font_mask == 0x100) { 3031 - vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) & 0x0e) << 4); 3032 - } else { 3033 - vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4); 3034 - } 3035 - con_flush(vc, draw_from, draw_to, &draw_x); 3036 - } 3037 - 3038 - next_c = c; 3039 - while (1) { 3040 - if (vc->vc_need_wrap || vc->vc_decim) 3041 - con_flush(vc, draw_from, draw_to, 3042 - &draw_x); 3043 - if (vc->vc_need_wrap) { 3044 - cr(vc); 3045 - lf(vc); 3046 - } 3047 - if (vc->vc_decim) 3048 - insert_char(vc, 1); 3049 - vc_uniscr_putc(vc, next_c); 3050 - scr_writew(himask ? 3051 - ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) : 3052 - (vc_attr << 8) + tc, 3053 - (u16 *) vc->vc_pos); 3054 - if (con_should_update(vc) && draw_x < 0) { 3055 - draw_x = vc->vc_x; 3056 - draw_from = vc->vc_pos; 3057 - } 3058 - if (vc->vc_x == vc->vc_cols - 1) { 3059 - vc->vc_need_wrap = vc->vc_decawm; 3060 - draw_to = vc->vc_pos + 2; 3061 - } else { 3062 - vc->vc_x++; 3063 - draw_to = (vc->vc_pos += 2); 3064 - } 3065 - 3066 - if (!--width) break; 3067 - 3068 - tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */ 3069 - if (tc < 0) tc = ' '; 3070 - next_c = ' '; 3071 - } 3072 - notify_write(vc, c); 3073 - 3074 - if (inverse) 3075 - con_flush(vc, draw_from, draw_to, &draw_x); 3076 - 3077 - if (rescan) { 3078 - rescan = 0; 3079 - inverse = 0; 3080 - width = 1; 3081 - c = orig; 3082 - goto rescan_last_byte; 3083 - } 2645 + if (vc_is_control(vc, tc, c)) { 2646 + con_flush(vc, &draw); 2647 + do_con_trol(tty, vc, orig); 3084 2648 continue; 3085 2649 } 3086 - con_flush(vc, draw_from, draw_to, &draw_x); 3087 - do_con_trol(tty, vc, orig); 2650 + 2651 + if (vc_con_write_normal(vc, tc, c, &draw) < 0) 2652 + continue; 2653 + 2654 + if (rescan) 2655 + goto rescan_last_byte; 3088 2656 } 3089 - con_flush(vc, draw_from, draw_to, &draw_x); 2657 + con_flush(vc, &draw); 3090 2658 vc_uniscr_debug_check(vc); 3091 2659 console_conditional_schedule(); 3092 2660 notify_update(vc); ··· 3062 2978 hide_cursor(vc); 3063 2979 3064 2980 start = (ushort *)vc->vc_pos; 3065 - start_x = vc->vc_x; 2981 + start_x = vc->state.x; 3066 2982 cnt = 0; 3067 2983 while (count--) { 3068 2984 c = *b++; 3069 2985 if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) { 3070 2986 if (cnt && con_is_visible(vc)) 3071 - vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x); 2987 + vc->vc_sw->con_putcs(vc, start, cnt, vc->state.y, start_x); 3072 2988 cnt = 0; 3073 2989 if (c == 8) { /* backspace */ 3074 2990 bs(vc); 3075 2991 start = (ushort *)vc->vc_pos; 3076 - start_x = vc->vc_x; 2992 + start_x = vc->state.x; 3077 2993 continue; 3078 2994 } 3079 2995 if (c != 13) 3080 2996 lf(vc); 3081 2997 cr(vc); 3082 2998 start = (ushort *)vc->vc_pos; 3083 - start_x = vc->vc_x; 2999 + start_x = vc->state.x; 3084 3000 if (c == 10 || c == 13) 3085 3001 continue; 3086 3002 } ··· 3088 3004 scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos); 3089 3005 notify_write(vc, c); 3090 3006 cnt++; 3091 - if (vc->vc_x == vc->vc_cols - 1) { 3007 + if (vc->state.x == vc->vc_cols - 1) { 3092 3008 vc->vc_need_wrap = 1; 3093 3009 } else { 3094 3010 vc->vc_pos += 2; 3095 - vc->vc_x++; 3011 + vc->state.x++; 3096 3012 } 3097 3013 } 3098 3014 if (cnt && con_is_visible(vc)) 3099 - vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x); 3015 + vc->vc_sw->con_putcs(vc, start, cnt, vc->state.y, start_x); 3100 3016 set_cursor(vc); 3101 3017 notify_update(vc); 3102 3018 ··· 3492 3408 master_display_fg = vc = vc_cons[currcons].d; 3493 3409 set_origin(vc); 3494 3410 save_screen(vc); 3495 - gotoxy(vc, vc->vc_x, vc->vc_y); 3411 + gotoxy(vc, vc->state.x, vc->state.y); 3496 3412 csi_J(vc, 0); 3497 3413 update_screen(vc); 3498 3414 pr_info("Console: %s %s %dx%d\n", ··· 4771 4687 void getconsxy(struct vc_data *vc, unsigned char *p) 4772 4688 { 4773 4689 /* clamp values if they don't fit */ 4774 - p[0] = min(vc->vc_x, 0xFFu); 4775 - p[1] = min(vc->vc_y, 0xFFu); 4690 + p[0] = min(vc->state.x, 0xFFu); 4691 + p[1] = min(vc->state.y, 0xFFu); 4776 4692 } 4777 4693 4778 4694 void putconsxy(struct vc_data *vc, unsigned char *p)
+555 -550
drivers/tty/vt/vt_ioctl.c
··· 241 241 #define GPLAST 0x3df 242 242 #define GPNUM (GPLAST - GPFIRST + 1) 243 243 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) 252 + { 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; 264 + } 244 265 266 + /* FIXME: this needs the console lock extending */ 267 + if (vc->vc_mode == mode) 268 + return 0; 245 269 246 - static inline int 247 - do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op) 270 + vc->vc_mode = mode; 271 + if (vc->vc_num != fg_console) 272 + return 0; 273 + 274 + /* explicitly blank/unblank the screen if switching modes */ 275 + console_lock(); 276 + if (mode == KD_TEXT) 277 + do_unblank_screen(1); 278 + else 279 + do_blank_screen(1); 280 + console_unlock(); 281 + 282 + return 0; 283 + } 284 + 285 + static int vt_k_ioctl(struct tty_struct *tty, unsigned int cmd, 286 + unsigned long arg, bool perm) 287 + { 288 + struct vc_data *vc = tty->driver_data; 289 + void __user *up = (void __user *)arg; 290 + unsigned int console = vc->vc_num; 291 + int ret; 292 + 293 + switch (cmd) { 294 + case KIOCSOUND: 295 + if (!perm) 296 + return -EPERM; 297 + /* 298 + * The use of PIT_TICK_RATE is historic, it used to be 299 + * the platform-dependent CLOCK_TICK_RATE between 2.6.12 300 + * and 2.6.36, which was a minor but unfortunate ABI 301 + * change. kd_mksound is locked by the input layer. 302 + */ 303 + if (arg) 304 + arg = PIT_TICK_RATE / arg; 305 + kd_mksound(arg, 0); 306 + break; 307 + 308 + case KDMKTONE: 309 + if (!perm) 310 + return -EPERM; 311 + { 312 + unsigned int ticks, count; 313 + 314 + /* 315 + * Generate the tone for the appropriate number of ticks. 316 + * If the time is zero, turn off sound ourselves. 317 + */ 318 + ticks = msecs_to_jiffies((arg >> 16) & 0xffff); 319 + count = ticks ? (arg & 0xffff) : 0; 320 + if (count) 321 + count = PIT_TICK_RATE / count; 322 + kd_mksound(count, ticks); 323 + break; 324 + } 325 + 326 + case KDGKBTYPE: 327 + /* 328 + * this is naïve. 329 + */ 330 + return put_user(KB_101, (char __user *)arg); 331 + 332 + /* 333 + * These cannot be implemented on any machine that implements 334 + * ioperm() in user level (such as Alpha PCs) or not at all. 335 + * 336 + * XXX: you should never use these, just call ioperm directly.. 337 + */ 338 + #ifdef CONFIG_X86 339 + case KDADDIO: 340 + case KDDELIO: 341 + /* 342 + * KDADDIO and KDDELIO may be able to add ports beyond what 343 + * we reject here, but to be safe... 344 + * 345 + * These are locked internally via sys_ioperm 346 + */ 347 + if (arg < GPFIRST || arg > GPLAST) 348 + return -EINVAL; 349 + 350 + return ksys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0; 351 + 352 + case KDENABIO: 353 + case KDDISABIO: 354 + return ksys_ioperm(GPFIRST, GPNUM, 355 + (cmd == KDENABIO)) ? -ENXIO : 0; 356 + #endif 357 + 358 + /* Linux m68k/i386 interface for setting the keyboard delay/repeat rate */ 359 + 360 + case KDKBDREP: 361 + { 362 + struct kbd_repeat kbrep; 363 + 364 + if (!capable(CAP_SYS_TTY_CONFIG)) 365 + return -EPERM; 366 + 367 + if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) 368 + return -EFAULT; 369 + 370 + ret = kbd_rate(&kbrep); 371 + if (ret) 372 + return ret; 373 + if (copy_to_user(up, &kbrep, sizeof(struct kbd_repeat))) 374 + return -EFAULT; 375 + break; 376 + } 377 + 378 + case KDSETMODE: 379 + if (!perm) 380 + return -EPERM; 381 + 382 + return vt_kdsetmode(vc, arg); 383 + 384 + case KDGETMODE: 385 + return put_user(vc->vc_mode, (int __user *)arg); 386 + 387 + case KDMAPDISP: 388 + case KDUNMAPDISP: 389 + /* 390 + * these work like a combination of mmap and KDENABIO. 391 + * this could be easily finished. 392 + */ 393 + return -EINVAL; 394 + 395 + case KDSKBMODE: 396 + if (!perm) 397 + return -EPERM; 398 + ret = vt_do_kdskbmode(console, arg); 399 + if (ret) 400 + return ret; 401 + tty_ldisc_flush(tty); 402 + break; 403 + 404 + case KDGKBMODE: 405 + return put_user(vt_do_kdgkbmode(console), (int __user *)arg); 406 + 407 + /* this could be folded into KDSKBMODE, but for compatibility 408 + reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */ 409 + case KDSKBMETA: 410 + return vt_do_kdskbmeta(console, arg); 411 + 412 + case KDGKBMETA: 413 + /* FIXME: should review whether this is worth locking */ 414 + return put_user(vt_do_kdgkbmeta(console), (int __user *)arg); 415 + 416 + case KDGETKEYCODE: 417 + case KDSETKEYCODE: 418 + if(!capable(CAP_SYS_TTY_CONFIG)) 419 + perm = 0; 420 + return vt_do_kbkeycode_ioctl(cmd, up, perm); 421 + 422 + case KDGKBENT: 423 + case KDSKBENT: 424 + return vt_do_kdsk_ioctl(cmd, up, perm, console); 425 + 426 + case KDGKBSENT: 427 + case KDSKBSENT: 428 + return vt_do_kdgkb_ioctl(cmd, up, perm); 429 + 430 + /* Diacritical processing. Handled in keyboard.c as it has 431 + to operate on the keyboard locks and structures */ 432 + case KDGKBDIACR: 433 + case KDGKBDIACRUC: 434 + case KDSKBDIACR: 435 + case KDSKBDIACRUC: 436 + return vt_do_diacrit(cmd, up, perm); 437 + 438 + /* the ioctls below read/set the flags usually shown in the leds */ 439 + /* don't use them - they will go away without warning */ 440 + case KDGKBLED: 441 + case KDSKBLED: 442 + case KDGETLED: 443 + case KDSETLED: 444 + return vt_do_kdskled(console, cmd, arg, perm); 445 + 446 + /* 447 + * A process can indicate its willingness to accept signals 448 + * generated by pressing an appropriate key combination. 449 + * Thus, one can have a daemon that e.g. spawns a new console 450 + * upon a keypress and then changes to it. 451 + * See also the kbrequest field of inittab(5). 452 + */ 453 + case KDSIGACCEPT: 454 + if (!perm || !capable(CAP_KILL)) 455 + return -EPERM; 456 + if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) 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); 464 + break; 465 + 466 + case KDFONTOP: { 467 + struct console_font_op op; 468 + 469 + if (copy_from_user(&op, up, sizeof(op))) 470 + return -EFAULT; 471 + if (!perm && op.op != KD_FONT_OP_GET) 472 + return -EPERM; 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; 478 + break; 479 + } 480 + 481 + default: 482 + return -ENOIOCTLCMD; 483 + } 484 + 485 + return 0; 486 + } 487 + 488 + static inline int do_fontx_ioctl(int cmd, 489 + struct consolefontdesc __user *user_cfd, 490 + struct console_font_op *op) 248 491 { 249 492 struct consolefontdesc cfdarg; 250 493 int i; 251 494 252 - if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc))) 495 + if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc))) 253 496 return -EFAULT; 254 - 497 + 255 498 switch (cmd) { 256 499 case PIO_FONTX: 257 - if (!perm) 258 - return -EPERM; 259 500 op->op = KD_FONT_OP_SET; 260 501 op->flags = KD_FONT_FLAG_OLD; 261 502 op->width = 8; ··· 524 283 return -EINVAL; 525 284 } 526 285 527 - static inline int 528 - do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_data *vc) 286 + static int vt_io_fontreset(struct console_font_op *op) 287 + { 288 + int ret; 289 + 290 + if (__is_defined(BROKEN_GRAPHICS_PROGRAMS)) { 291 + /* 292 + * With BROKEN_GRAPHICS_PROGRAMS defined, the default font is 293 + * not saved. 294 + */ 295 + return -ENOSYS; 296 + } 297 + 298 + op->op = KD_FONT_OP_SET_DEFAULT; 299 + op->data = NULL; 300 + ret = con_font_op(vc_cons[fg_console].d, op); 301 + if (ret) 302 + return ret; 303 + 304 + console_lock(); 305 + con_set_default_unimap(vc_cons[fg_console].d); 306 + console_unlock(); 307 + 308 + return 0; 309 + } 310 + 311 + static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, 312 + struct vc_data *vc) 529 313 { 530 314 struct unimapdesc tmp; 531 315 ··· 558 292 return -EFAULT; 559 293 switch (cmd) { 560 294 case PIO_UNIMAP: 561 - if (!perm) 562 - return -EPERM; 563 295 return con_set_unimap(vc, tmp.entry_ct, tmp.entries); 564 296 case GIO_UNIMAP: 565 - if (!perm && fg_console != vc->vc_num) 297 + if (fg_console != vc->vc_num) 566 298 return -EPERM; 567 - return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp.entries); 299 + return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), 300 + tmp.entries); 568 301 } 302 + return 0; 303 + } 304 + 305 + static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up, 306 + bool perm) 307 + { 308 + struct console_font_op op; /* used in multiple places here */ 309 + 310 + switch (cmd) { 311 + case PIO_FONT: 312 + if (!perm) 313 + return -EPERM; 314 + op.op = KD_FONT_OP_SET; 315 + op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */ 316 + op.width = 8; 317 + op.height = 0; 318 + op.charcount = 256; 319 + op.data = up; 320 + return con_font_op(vc_cons[fg_console].d, &op); 321 + 322 + case GIO_FONT: 323 + op.op = KD_FONT_OP_GET; 324 + op.flags = KD_FONT_FLAG_OLD; 325 + op.width = 8; 326 + op.height = 32; 327 + op.charcount = 256; 328 + op.data = up; 329 + return con_font_op(vc_cons[fg_console].d, &op); 330 + 331 + case PIO_CMAP: 332 + if (!perm) 333 + return -EPERM; 334 + return con_set_cmap(up); 335 + 336 + case GIO_CMAP: 337 + return con_get_cmap(up); 338 + 339 + case PIO_FONTX: 340 + if (!perm) 341 + return -EPERM; 342 + 343 + fallthrough; 344 + case GIO_FONTX: 345 + return do_fontx_ioctl(cmd, up, &op); 346 + 347 + case PIO_FONTRESET: 348 + if (!perm) 349 + return -EPERM; 350 + 351 + return vt_io_fontreset(&op); 352 + 353 + case PIO_SCRNMAP: 354 + if (!perm) 355 + return -EPERM; 356 + return con_set_trans_old(up); 357 + 358 + case GIO_SCRNMAP: 359 + return con_get_trans_old(up); 360 + 361 + case PIO_UNISCRNMAP: 362 + if (!perm) 363 + return -EPERM; 364 + return con_set_trans_new(up); 365 + 366 + case GIO_UNISCRNMAP: 367 + return con_get_trans_new(up); 368 + 369 + case PIO_UNIMAPCLR: 370 + if (!perm) 371 + return -EPERM; 372 + con_clear_unimap(vc); 373 + break; 374 + 375 + case PIO_UNIMAP: 376 + case GIO_UNIMAP: 377 + if (!perm) 378 + return -EPERM; 379 + 380 + return do_unimap_ioctl(cmd, up, vc); 381 + 382 + default: 383 + return -ENOIOCTLCMD; 384 + } 385 + 386 + return 0; 387 + } 388 + 389 + static int vt_reldisp(struct vc_data *vc, unsigned int swtch) 390 + { 391 + int newvt, ret; 392 + 393 + if (vc->vt_mode.mode != VT_PROCESS) 394 + return -EINVAL; 395 + 396 + /* Switched-to response */ 397 + if (vc->vt_newvt < 0) { 398 + /* If it's just an ACK, ignore it */ 399 + return swtch == VT_ACKACQ ? 0 : -EINVAL; 400 + } 401 + 402 + /* Switching-from response */ 403 + if (swtch == 0) { 404 + /* Switch disallowed, so forget we were trying to do it. */ 405 + vc->vt_newvt = -1; 406 + return 0; 407 + } 408 + 409 + /* The current vt has been released, so complete the switch. */ 410 + newvt = vc->vt_newvt; 411 + vc->vt_newvt = -1; 412 + ret = vc_allocate(newvt); 413 + if (ret) 414 + return ret; 415 + 416 + /* 417 + * When we actually do the console switch, make sure we are atomic with 418 + * respect to other console switches.. 419 + */ 420 + complete_change_console(vc_cons[newvt].d); 421 + 422 + return 0; 423 + } 424 + 425 + static int vt_setactivate(struct vt_setactivate __user *sa) 426 + { 427 + struct vt_setactivate vsa; 428 + struct vc_data *nvc; 429 + int ret; 430 + 431 + if (copy_from_user(&vsa, sa, sizeof(vsa))) 432 + return -EFAULT; 433 + if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES) 434 + return -ENXIO; 435 + 436 + vsa.console = array_index_nospec(vsa.console, MAX_NR_CONSOLES + 1); 437 + vsa.console--; 438 + console_lock(); 439 + ret = vc_allocate(vsa.console); 440 + if (ret) { 441 + console_unlock(); 442 + return ret; 443 + } 444 + 445 + /* 446 + * This is safe providing we don't drop the console sem between 447 + * vc_allocate and finishing referencing nvc. 448 + */ 449 + nvc = vc_cons[vsa.console].d; 450 + nvc->vt_mode = vsa.mode; 451 + nvc->vt_mode.frsig = 0; 452 + put_pid(nvc->vt_pid); 453 + nvc->vt_pid = get_pid(task_pid(current)); 454 + console_unlock(); 455 + 456 + /* Commence switch and lock */ 457 + /* Review set_console locks */ 458 + set_console(vsa.console); 459 + 569 460 return 0; 570 461 } 571 462 ··· 765 342 } 766 343 } 767 344 345 + static int vt_resizex(struct vc_data *vc, struct vt_consize __user *cs) 346 + { 347 + struct vt_consize v; 348 + int i; 349 + 350 + if (copy_from_user(&v, cs, sizeof(struct vt_consize))) 351 + return -EFAULT; 352 + 353 + /* FIXME: Should check the copies properly */ 354 + if (!v.v_vlin) 355 + v.v_vlin = vc->vc_scan_lines; 356 + 357 + if (v.v_clin) { 358 + int rows = v.v_vlin / v.v_clin; 359 + if (v.v_rows != rows) { 360 + if (v.v_rows) /* Parameters don't add up */ 361 + return -EINVAL; 362 + v.v_rows = rows; 363 + } 364 + } 365 + 366 + if (v.v_vcol && v.v_ccol) { 367 + int cols = v.v_vcol / v.v_ccol; 368 + if (v.v_cols != cols) { 369 + if (v.v_cols) 370 + return -EINVAL; 371 + v.v_cols = cols; 372 + } 373 + } 374 + 375 + if (v.v_clin > 32) 376 + return -EINVAL; 377 + 378 + for (i = 0; i < MAX_NR_CONSOLES; i++) { 379 + struct vc_data *vcp; 380 + 381 + if (!vc_cons[i].d) 382 + continue; 383 + console_lock(); 384 + vcp = vc_cons[i].d; 385 + if (vcp) { 386 + if (v.v_vlin) 387 + vcp->vc_scan_lines = v.v_vlin; 388 + if (v.v_clin) 389 + vcp->vc_font.height = v.v_clin; 390 + vcp->vc_resize_user = 1; 391 + vc_resize(vcp, v.v_cols, v.v_rows); 392 + } 393 + console_unlock(); 394 + } 395 + 396 + return 0; 397 + } 768 398 769 399 /* 770 400 * We handle the console-specific ioctl's here. We allow the 771 - * capability to modify any console, not just the fg_console. 401 + * capability to modify any console, not just the fg_console. 772 402 */ 773 403 int vt_ioctl(struct tty_struct *tty, 774 404 unsigned int cmd, unsigned long arg) 775 405 { 776 406 struct vc_data *vc = tty->driver_data; 777 - struct console_font_op op; /* used in multiple places here */ 778 - unsigned int console = vc->vc_num; 779 - unsigned char ucval; 780 - unsigned int uival; 781 407 void __user *up = (void __user *)arg; 782 408 int i, perm; 783 - int ret = 0; 409 + int ret; 784 410 785 411 /* 786 412 * To have permissions to do most of the vt ioctls, we either have ··· 838 366 perm = 0; 839 367 if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG)) 840 368 perm = 1; 841 - 369 + 370 + ret = vt_k_ioctl(tty, cmd, arg, perm); 371 + if (ret != -ENOIOCTLCMD) 372 + return ret; 373 + 374 + ret = vt_io_ioctl(vc, cmd, up, perm); 375 + if (ret != -ENOIOCTLCMD) 376 + return ret; 377 + 842 378 switch (cmd) { 843 379 case TIOCLINUX: 844 - ret = tioclinux(tty, arg); 845 - break; 846 - case KIOCSOUND: 847 - if (!perm) 848 - return -EPERM; 849 - /* 850 - * The use of PIT_TICK_RATE is historic, it used to be 851 - * the platform-dependent CLOCK_TICK_RATE between 2.6.12 852 - * and 2.6.36, which was a minor but unfortunate ABI 853 - * change. kd_mksound is locked by the input layer. 854 - */ 855 - if (arg) 856 - arg = PIT_TICK_RATE / arg; 857 - kd_mksound(arg, 0); 858 - break; 859 - 860 - case KDMKTONE: 861 - if (!perm) 862 - return -EPERM; 863 - { 864 - unsigned int ticks, count; 865 - 866 - /* 867 - * Generate the tone for the appropriate number of ticks. 868 - * If the time is zero, turn off sound ourselves. 869 - */ 870 - ticks = msecs_to_jiffies((arg >> 16) & 0xffff); 871 - count = ticks ? (arg & 0xffff) : 0; 872 - if (count) 873 - count = PIT_TICK_RATE / count; 874 - kd_mksound(count, ticks); 875 - break; 876 - } 877 - 878 - case KDGKBTYPE: 879 - /* 880 - * this is naïve. 881 - */ 882 - ucval = KB_101; 883 - ret = put_user(ucval, (char __user *)arg); 884 - break; 885 - 886 - /* 887 - * These cannot be implemented on any machine that implements 888 - * ioperm() in user level (such as Alpha PCs) or not at all. 889 - * 890 - * XXX: you should never use these, just call ioperm directly.. 891 - */ 892 - #ifdef CONFIG_X86 893 - case KDADDIO: 894 - case KDDELIO: 895 - /* 896 - * KDADDIO and KDDELIO may be able to add ports beyond what 897 - * we reject here, but to be safe... 898 - * 899 - * These are locked internally via sys_ioperm 900 - */ 901 - if (arg < GPFIRST || arg > GPLAST) { 902 - ret = -EINVAL; 903 - break; 904 - } 905 - ret = ksys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0; 906 - break; 907 - 908 - case KDENABIO: 909 - case KDDISABIO: 910 - ret = ksys_ioperm(GPFIRST, GPNUM, 911 - (cmd == KDENABIO)) ? -ENXIO : 0; 912 - break; 913 - #endif 914 - 915 - /* Linux m68k/i386 interface for setting the keyboard delay/repeat rate */ 916 - 917 - case KDKBDREP: 918 - { 919 - struct kbd_repeat kbrep; 920 - 921 - if (!capable(CAP_SYS_TTY_CONFIG)) 922 - return -EPERM; 923 - 924 - if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) { 925 - ret = -EFAULT; 926 - break; 927 - } 928 - ret = kbd_rate(&kbrep); 929 - if (ret) 930 - break; 931 - if (copy_to_user(up, &kbrep, sizeof(struct kbd_repeat))) 932 - ret = -EFAULT; 933 - break; 934 - } 935 - 936 - case KDSETMODE: 937 - /* 938 - * currently, setting the mode from KD_TEXT to KD_GRAPHICS 939 - * doesn't do a whole lot. i'm not sure if it should do any 940 - * restoration of modes or what... 941 - * 942 - * XXX It should at least call into the driver, fbdev's definitely 943 - * need to restore their engine state. --BenH 944 - */ 945 - if (!perm) 946 - return -EPERM; 947 - switch (arg) { 948 - case KD_GRAPHICS: 949 - break; 950 - case KD_TEXT0: 951 - case KD_TEXT1: 952 - arg = KD_TEXT; 953 - case KD_TEXT: 954 - break; 955 - default: 956 - ret = -EINVAL; 957 - goto out; 958 - } 959 - /* FIXME: this needs the console lock extending */ 960 - if (vc->vc_mode == (unsigned char) arg) 961 - break; 962 - vc->vc_mode = (unsigned char) arg; 963 - if (console != fg_console) 964 - break; 965 - /* 966 - * explicitly blank/unblank the screen if switching modes 967 - */ 968 - console_lock(); 969 - if (arg == KD_TEXT) 970 - do_unblank_screen(1); 971 - else 972 - do_blank_screen(1); 973 - console_unlock(); 974 - break; 975 - 976 - case KDGETMODE: 977 - uival = vc->vc_mode; 978 - goto setint; 979 - 980 - case KDMAPDISP: 981 - case KDUNMAPDISP: 982 - /* 983 - * these work like a combination of mmap and KDENABIO. 984 - * this could be easily finished. 985 - */ 986 - ret = -EINVAL; 987 - break; 988 - 989 - case KDSKBMODE: 990 - if (!perm) 991 - return -EPERM; 992 - ret = vt_do_kdskbmode(console, arg); 993 - if (ret == 0) 994 - tty_ldisc_flush(tty); 995 - break; 996 - 997 - case KDGKBMODE: 998 - uival = vt_do_kdgkbmode(console); 999 - ret = put_user(uival, (int __user *)arg); 1000 - break; 1001 - 1002 - /* this could be folded into KDSKBMODE, but for compatibility 1003 - reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */ 1004 - case KDSKBMETA: 1005 - ret = vt_do_kdskbmeta(console, arg); 1006 - break; 1007 - 1008 - case KDGKBMETA: 1009 - /* FIXME: should review whether this is worth locking */ 1010 - uival = vt_do_kdgkbmeta(console); 1011 - setint: 1012 - ret = put_user(uival, (int __user *)arg); 1013 - break; 1014 - 1015 - case KDGETKEYCODE: 1016 - case KDSETKEYCODE: 1017 - if(!capable(CAP_SYS_TTY_CONFIG)) 1018 - perm = 0; 1019 - ret = vt_do_kbkeycode_ioctl(cmd, up, perm); 1020 - break; 1021 - 1022 - case KDGKBENT: 1023 - case KDSKBENT: 1024 - ret = vt_do_kdsk_ioctl(cmd, up, perm, console); 1025 - break; 1026 - 1027 - case KDGKBSENT: 1028 - case KDSKBSENT: 1029 - ret = vt_do_kdgkb_ioctl(cmd, up, perm); 1030 - break; 1031 - 1032 - /* Diacritical processing. Handled in keyboard.c as it has 1033 - to operate on the keyboard locks and structures */ 1034 - case KDGKBDIACR: 1035 - case KDGKBDIACRUC: 1036 - case KDSKBDIACR: 1037 - case KDSKBDIACRUC: 1038 - ret = vt_do_diacrit(cmd, up, perm); 1039 - break; 1040 - 1041 - /* the ioctls below read/set the flags usually shown in the leds */ 1042 - /* don't use them - they will go away without warning */ 1043 - case KDGKBLED: 1044 - case KDSKBLED: 1045 - case KDGETLED: 1046 - case KDSETLED: 1047 - ret = vt_do_kdskled(console, cmd, arg, perm); 1048 - break; 1049 - 1050 - /* 1051 - * A process can indicate its willingness to accept signals 1052 - * generated by pressing an appropriate key combination. 1053 - * Thus, one can have a daemon that e.g. spawns a new console 1054 - * upon a keypress and then changes to it. 1055 - * See also the kbrequest field of inittab(5). 1056 - */ 1057 - case KDSIGACCEPT: 1058 - { 1059 - if (!perm || !capable(CAP_KILL)) 1060 - return -EPERM; 1061 - if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) 1062 - ret = -EINVAL; 1063 - else { 1064 - spin_lock_irq(&vt_spawn_con.lock); 1065 - put_pid(vt_spawn_con.pid); 1066 - vt_spawn_con.pid = get_pid(task_pid(current)); 1067 - vt_spawn_con.sig = arg; 1068 - spin_unlock_irq(&vt_spawn_con.lock); 1069 - } 1070 - break; 1071 - } 1072 - 380 + return tioclinux(tty, arg); 1073 381 case VT_SETMODE: 1074 382 { 1075 383 struct vt_mode tmp; 1076 384 1077 385 if (!perm) 1078 386 return -EPERM; 1079 - if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) { 1080 - ret = -EFAULT; 1081 - goto out; 1082 - } 1083 - if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) { 1084 - ret = -EINVAL; 1085 - goto out; 1086 - } 387 + if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) 388 + return -EFAULT; 389 + if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) 390 + return -EINVAL; 391 + 1087 392 console_lock(); 1088 393 vc->vt_mode = tmp; 1089 394 /* the frsig is ignored, so we set it to 0 */ ··· 884 635 885 636 rc = copy_to_user(up, &tmp, sizeof(struct vt_mode)); 886 637 if (rc) 887 - ret = -EFAULT; 638 + return -EFAULT; 888 639 break; 889 640 } 890 641 ··· 899 650 unsigned short state, mask; 900 651 901 652 if (put_user(fg_console + 1, &vtstat->v_active)) 902 - ret = -EFAULT; 903 - else { 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 - ret = put_user(state, &vtstat->v_state); 912 - } 913 - break; 653 + return -EFAULT; 654 + 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 + return put_user(state, &vtstat->v_state); 914 663 } 915 664 916 665 /* ··· 920 673 if (!vt_in_use(i)) 921 674 break; 922 675 console_unlock(); 923 - uival = i < MAX_NR_CONSOLES ? (i+1) : -1; 924 - goto setint; 676 + i = i < MAX_NR_CONSOLES ? (i+1) : -1; 677 + return put_user(i, (int __user *)arg); 925 678 926 679 /* 927 680 * ioctl(fd, VT_ACTIVATE, num) will cause us to switch to vt # num, ··· 932 685 if (!perm) 933 686 return -EPERM; 934 687 if (arg == 0 || arg > MAX_NR_CONSOLES) 935 - ret = -ENXIO; 936 - else { 937 - arg--; 938 - console_lock(); 939 - ret = vc_allocate(arg); 940 - console_unlock(); 941 - if (ret) 942 - break; 943 - set_console(arg); 944 - } 688 + return -ENXIO; 689 + 690 + arg--; 691 + console_lock(); 692 + ret = vc_allocate(arg); 693 + console_unlock(); 694 + if (ret) 695 + return ret; 696 + set_console(arg); 945 697 break; 946 698 947 699 case VT_SETACTIVATE: 948 - { 949 - struct vt_setactivate vsa; 950 - 951 700 if (!perm) 952 701 return -EPERM; 953 702 954 - if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg, 955 - sizeof(struct vt_setactivate))) { 956 - ret = -EFAULT; 957 - goto out; 958 - } 959 - if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES) 960 - ret = -ENXIO; 961 - else { 962 - vsa.console = array_index_nospec(vsa.console, 963 - MAX_NR_CONSOLES + 1); 964 - vsa.console--; 965 - console_lock(); 966 - ret = vc_allocate(vsa.console); 967 - if (ret == 0) { 968 - struct vc_data *nvc; 969 - /* This is safe providing we don't drop the 970 - console sem between vc_allocate and 971 - finishing referencing nvc */ 972 - nvc = vc_cons[vsa.console].d; 973 - nvc->vt_mode = vsa.mode; 974 - nvc->vt_mode.frsig = 0; 975 - put_pid(nvc->vt_pid); 976 - nvc->vt_pid = get_pid(task_pid(current)); 977 - } 978 - console_unlock(); 979 - if (ret) 980 - break; 981 - /* Commence switch and lock */ 982 - /* Review set_console locks */ 983 - set_console(vsa.console); 984 - } 985 - break; 986 - } 703 + return vt_setactivate(up); 987 704 988 705 /* 989 706 * wait until the specified VT has been activated ··· 956 745 if (!perm) 957 746 return -EPERM; 958 747 if (arg == 0 || arg > MAX_NR_CONSOLES) 959 - ret = -ENXIO; 960 - else 961 - ret = vt_waitactive(arg); 962 - break; 748 + return -ENXIO; 749 + return vt_waitactive(arg); 963 750 964 751 /* 965 752 * If a vt is under process control, the kernel will not switch to it ··· 974 765 return -EPERM; 975 766 976 767 console_lock(); 977 - if (vc->vt_mode.mode != VT_PROCESS) { 978 - console_unlock(); 979 - ret = -EINVAL; 980 - break; 981 - } 982 - /* 983 - * Switching-from response 984 - */ 985 - if (vc->vt_newvt >= 0) { 986 - if (arg == 0) 987 - /* 988 - * Switch disallowed, so forget we were trying 989 - * to do it. 990 - */ 991 - vc->vt_newvt = -1; 992 - 993 - else { 994 - /* 995 - * The current vt has been released, so 996 - * complete the switch. 997 - */ 998 - int newvt; 999 - newvt = vc->vt_newvt; 1000 - vc->vt_newvt = -1; 1001 - ret = vc_allocate(newvt); 1002 - if (ret) { 1003 - console_unlock(); 1004 - break; 1005 - } 1006 - /* 1007 - * When we actually do the console switch, 1008 - * make sure we are atomic with respect to 1009 - * other console switches.. 1010 - */ 1011 - complete_change_console(vc_cons[newvt].d); 1012 - } 1013 - } else { 1014 - /* 1015 - * Switched-to response 1016 - */ 1017 - /* 1018 - * If it's just an ACK, ignore it 1019 - */ 1020 - if (arg != VT_ACKACQ) 1021 - ret = -EINVAL; 1022 - } 768 + ret = vt_reldisp(vc, arg); 1023 769 console_unlock(); 1024 - break; 770 + 771 + return ret; 772 + 1025 773 1026 774 /* 1027 775 * Disallocate memory associated to VT (but leave VT1) 1028 776 */ 1029 777 case VT_DISALLOCATE: 1030 - if (arg > MAX_NR_CONSOLES) { 1031 - ret = -ENXIO; 1032 - break; 1033 - } 778 + if (arg > MAX_NR_CONSOLES) 779 + return -ENXIO; 780 + 1034 781 if (arg == 0) 1035 782 vt_disallocate_all(); 1036 783 else 1037 - ret = vt_disallocate(--arg); 784 + return vt_disallocate(--arg); 1038 785 break; 1039 786 1040 787 case VT_RESIZE: 1041 788 { 1042 789 struct vt_sizes __user *vtsizes = up; 1043 790 struct vc_data *vc; 1044 - 1045 791 ushort ll,cc; 792 + 1046 793 if (!perm) 1047 794 return -EPERM; 1048 795 if (get_user(ll, &vtsizes->v_rows) || 1049 796 get_user(cc, &vtsizes->v_cols)) 1050 - ret = -EFAULT; 1051 - else { 1052 - console_lock(); 1053 - for (i = 0; i < MAX_NR_CONSOLES; i++) { 1054 - vc = vc_cons[i].d; 797 + return -EFAULT; 1055 798 1056 - if (vc) { 1057 - vc->vc_resize_user = 1; 1058 - /* FIXME: review v tty lock */ 1059 - vc_resize(vc_cons[i].d, cc, ll); 1060 - } 799 + console_lock(); 800 + for (i = 0; i < MAX_NR_CONSOLES; i++) { 801 + vc = vc_cons[i].d; 802 + 803 + if (vc) { 804 + vc->vc_resize_user = 1; 805 + /* FIXME: review v tty lock */ 806 + vc_resize(vc_cons[i].d, cc, ll); 1061 807 } 1062 - console_unlock(); 1063 808 } 809 + console_unlock(); 1064 810 break; 1065 811 } 1066 812 1067 813 case VT_RESIZEX: 1068 - { 1069 - struct vt_consize v; 1070 - if (!perm) 1071 - return -EPERM; 1072 - if (copy_from_user(&v, up, sizeof(struct vt_consize))) 1073 - return -EFAULT; 1074 - /* FIXME: Should check the copies properly */ 1075 - if (!v.v_vlin) 1076 - v.v_vlin = vc->vc_scan_lines; 1077 - if (v.v_clin) { 1078 - int rows = v.v_vlin/v.v_clin; 1079 - if (v.v_rows != rows) { 1080 - if (v.v_rows) /* Parameters don't add up */ 1081 - return -EINVAL; 1082 - v.v_rows = rows; 1083 - } 1084 - } 1085 - if (v.v_vcol && v.v_ccol) { 1086 - int cols = v.v_vcol/v.v_ccol; 1087 - if (v.v_cols != cols) { 1088 - if (v.v_cols) 1089 - return -EINVAL; 1090 - v.v_cols = cols; 1091 - } 1092 - } 1093 - 1094 - if (v.v_clin > 32) 1095 - return -EINVAL; 1096 - 1097 - for (i = 0; i < MAX_NR_CONSOLES; i++) { 1098 - struct vc_data *vcp; 1099 - 1100 - if (!vc_cons[i].d) 1101 - continue; 1102 - console_lock(); 1103 - vcp = vc_cons[i].d; 1104 - if (vcp) { 1105 - if (v.v_vlin) 1106 - vcp->vc_scan_lines = v.v_vlin; 1107 - if (v.v_clin) 1108 - vcp->vc_font.height = v.v_clin; 1109 - vcp->vc_resize_user = 1; 1110 - vc_resize(vcp, v.v_cols, v.v_rows); 1111 - } 1112 - console_unlock(); 1113 - } 1114 - break; 1115 - } 1116 - 1117 - case PIO_FONT: { 1118 - if (!perm) 1119 - return -EPERM; 1120 - op.op = KD_FONT_OP_SET; 1121 - op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */ 1122 - op.width = 8; 1123 - op.height = 0; 1124 - op.charcount = 256; 1125 - op.data = up; 1126 - ret = con_font_op(vc_cons[fg_console].d, &op); 1127 - break; 1128 - } 1129 - 1130 - case GIO_FONT: { 1131 - op.op = KD_FONT_OP_GET; 1132 - op.flags = KD_FONT_FLAG_OLD; 1133 - op.width = 8; 1134 - op.height = 32; 1135 - op.charcount = 256; 1136 - op.data = up; 1137 - ret = con_font_op(vc_cons[fg_console].d, &op); 1138 - break; 1139 - } 1140 - 1141 - case PIO_CMAP: 1142 - if (!perm) 1143 - ret = -EPERM; 1144 - else 1145 - ret = con_set_cmap(up); 1146 - break; 1147 - 1148 - case GIO_CMAP: 1149 - ret = con_get_cmap(up); 1150 - break; 1151 - 1152 - case PIO_FONTX: 1153 - case GIO_FONTX: 1154 - ret = do_fontx_ioctl(cmd, up, perm, &op); 1155 - break; 1156 - 1157 - case PIO_FONTRESET: 1158 - { 1159 814 if (!perm) 1160 815 return -EPERM; 1161 816 1162 - #ifdef BROKEN_GRAPHICS_PROGRAMS 1163 - /* With BROKEN_GRAPHICS_PROGRAMS defined, the default 1164 - font is not saved. */ 1165 - ret = -ENOSYS; 1166 - break; 1167 - #else 1168 - { 1169 - op.op = KD_FONT_OP_SET_DEFAULT; 1170 - op.data = NULL; 1171 - ret = con_font_op(vc_cons[fg_console].d, &op); 1172 - if (ret) 1173 - break; 1174 - console_lock(); 1175 - con_set_default_unimap(vc_cons[fg_console].d); 1176 - console_unlock(); 1177 - break; 1178 - } 1179 - #endif 1180 - } 1181 - 1182 - case KDFONTOP: { 1183 - if (copy_from_user(&op, up, sizeof(op))) { 1184 - ret = -EFAULT; 1185 - break; 1186 - } 1187 - if (!perm && op.op != KD_FONT_OP_GET) 1188 - return -EPERM; 1189 - ret = con_font_op(vc, &op); 1190 - if (ret) 1191 - break; 1192 - if (copy_to_user(up, &op, sizeof(op))) 1193 - ret = -EFAULT; 1194 - break; 1195 - } 1196 - 1197 - case PIO_SCRNMAP: 1198 - if (!perm) 1199 - ret = -EPERM; 1200 - else 1201 - ret = con_set_trans_old(up); 1202 - break; 1203 - 1204 - case GIO_SCRNMAP: 1205 - ret = con_get_trans_old(up); 1206 - break; 1207 - 1208 - case PIO_UNISCRNMAP: 1209 - if (!perm) 1210 - ret = -EPERM; 1211 - else 1212 - ret = con_set_trans_new(up); 1213 - break; 1214 - 1215 - case GIO_UNISCRNMAP: 1216 - ret = con_get_trans_new(up); 1217 - break; 1218 - 1219 - case PIO_UNIMAPCLR: 1220 - if (!perm) 1221 - return -EPERM; 1222 - con_clear_unimap(vc); 1223 - break; 1224 - 1225 - case PIO_UNIMAP: 1226 - case GIO_UNIMAP: 1227 - ret = do_unimap_ioctl(cmd, up, perm, vc); 1228 - break; 817 + return vt_resizex(vc, up); 1229 818 1230 819 case VT_LOCKSWITCH: 1231 820 if (!capable(CAP_SYS_TTY_CONFIG)) ··· 1036 1029 vt_dont_switch = false; 1037 1030 break; 1038 1031 case VT_GETHIFONTMASK: 1039 - ret = put_user(vc->vc_hi_font_mask, 1032 + return put_user(vc->vc_hi_font_mask, 1040 1033 (unsigned short __user *)arg); 1041 - break; 1042 1034 case VT_WAITEVENT: 1043 - ret = vt_event_wait_ioctl((struct vt_event __user *)arg); 1044 - break; 1035 + return vt_event_wait_ioctl((struct vt_event __user *)arg); 1045 1036 default: 1046 - ret = -ENOIOCTLCMD; 1037 + return -ENOIOCTLCMD; 1047 1038 } 1048 - out: 1049 - return ret; 1039 + 1040 + return 0; 1050 1041 } 1051 1042 1052 1043 void reset_vc(struct vc_data *vc)
+6 -5
drivers/usb/misc/sisusbvga/sisusb_con.c
··· 302 302 303 303 /* interface routine */ 304 304 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) 307 308 { 308 309 u8 attr = color; 309 310 310 311 if (underline) 311 312 attr = (attr & 0xf0) | c->vc_ulcolor; 312 - else if (intensity == 0) 313 + else if (intensity == VCI_HALF_BRIGHT) 313 314 attr = (attr & 0xf0) | c->vc_halfcolor; 314 315 315 316 if (reverse) ··· 321 320 if (blink) 322 321 attr ^= 0x80; 323 322 324 - if (intensity == 2) 323 + if (intensity == VCI_BOLD) 325 324 attr ^= 0x08; 326 325 327 326 return attr; ··· 727 726 728 727 baseline = c->vc_font.height - (c->vc_font.height < 10 ? 1 : 2); 729 728 730 - switch (c->vc_cursor_type & 0x0f) { 729 + switch (CUR_SIZE(c->vc_cursor_type)) { 731 730 case CUR_BLOCK: from = 1; 732 731 to = c->vc_font.height; 733 732 break;
+11 -9
drivers/video/console/mdacon.c
··· 394 394 (ch & 0x00ff) | attr; 395 395 } 396 396 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) 399 401 { 400 402 /* The attribute is just a bit vector: 401 403 * ··· 407 405 * Bit 7 : blink 408 406 */ 409 407 410 - return (intensity & 3) | 411 - ((underline & 1) << 2) | 412 - ((reverse & 1) << 3) | 413 - (!!italic << 4) | 414 - ((blink & 1) << 7); 408 + return (intensity & VCI_MASK) | 409 + (underline << 2) | 410 + (reverse << 3) | 411 + (italic << 4) | 412 + (blink << 7); 415 413 } 416 414 417 415 static void mdacon_invert_region(struct vc_data *c, u16 *p, int count) ··· 490 488 return; 491 489 } 492 490 493 - mda_set_cursor(c->vc_y*mda_num_columns*2 + c->vc_x*2); 491 + mda_set_cursor(c->state.y * mda_num_columns * 2 + c->state.x * 2); 494 492 495 - switch (c->vc_cursor_type & 0x0f) { 493 + switch (CUR_SIZE(c->vc_cursor_type)) { 496 494 497 495 case CUR_LOWER_THIRD: mda_set_cursor_size(10, 13); break; 498 496 case CUR_LOWER_HALF: mda_set_cursor_size(7, 13); break;
+5 -5
drivers/video/console/newport_con.c
··· 362 362 363 363 if (ystart < yend) { 364 364 newport_clear_screen(sx << 3, ystart, xend, yend, 365 - (vc->vc_color & 0xf0) >> 4); 365 + (vc->state.color & 0xf0) >> 4); 366 366 } else { 367 367 newport_clear_screen(sx << 3, ystart, xend, 1023, 368 - (vc->vc_color & 0xf0) >> 4); 368 + (vc->state.color & 0xf0) >> 4); 369 369 newport_clear_screen(sx << 3, 0, xend, yend, 370 - (vc->vc_color & 0xf0) >> 4); 370 + (vc->state.color & 0xf0) >> 4); 371 371 } 372 372 } 373 373 ··· 591 591 topscan = (topscan + (lines << 4)) & 0x3ff; 592 592 newport_clear_lines(vc->vc_rows - lines, 593 593 vc->vc_rows - 1, 594 - (vc->vc_color & 0xf0) >> 4); 594 + (vc->state.color & 0xf0) >> 4); 595 595 } else { 596 596 topscan = (topscan + (-lines << 4)) & 0x3ff; 597 597 newport_clear_lines(0, lines - 1, 598 - (vc->vc_color & 0xf0) >> 4); 598 + (vc->state.color & 0xf0) >> 4); 599 599 } 600 600 npregs->cset.topscan = (topscan - 1) & 0x3ff; 601 601 return false;
+8 -6
drivers/video/console/sticon.c
··· 132 132 { 133 133 unsigned short car1; 134 134 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]; 136 136 switch (mode) { 137 137 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); 139 139 break; 140 140 case CM_MOVE: 141 141 case CM_DRAW: 142 - switch (conp->vc_cursor_type & 0x0f) { 142 + switch (CUR_SIZE(conp->vc_cursor_type)) { 143 143 case CUR_UNDERLINE: 144 144 case CUR_LOWER_THIRD: 145 145 case CUR_LOWER_HALF: 146 146 case CUR_TWO_THIRDS: 147 147 case CUR_BLOCK: 148 148 sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11), 149 - conp->vc_y, conp->vc_x); 149 + conp->state.y, conp->state.x); 150 150 break; 151 151 } 152 152 break; ··· 288 288 return ret; 289 289 } 290 290 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) 293 295 { 294 296 u8 attr = ((color & 0x70) >> 1) | ((color & 7)); 295 297
+23 -17
drivers/video/console/vgacon.c
··· 251 251 p = (void *) (c->vc_origin + t * c->vc_size_row); 252 252 253 253 while (count--) { 254 + if ((vgacon_scrollback_cur->tail + c->vc_size_row) > 255 + vgacon_scrollback_cur->size) 256 + vgacon_scrollback_cur->tail = 0; 257 + 254 258 scr_memcpyw(vgacon_scrollback_cur->data + 255 259 vgacon_scrollback_cur->tail, 256 260 p, c->vc_size_row); ··· 633 629 con_set_default_unimap(c); 634 630 } 635 631 636 - static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, 637 - u8 blink, u8 underline, u8 reverse, u8 italic) 632 + static u8 vgacon_build_attr(struct vc_data *c, u8 color, 633 + enum vc_intensity intensity, 634 + bool blink, bool underline, bool reverse, 635 + bool italic) 638 636 { 639 637 u8 attr = color; 640 638 ··· 645 639 attr = (attr & 0xF0) | c->vc_itcolor; 646 640 else if (underline) 647 641 attr = (attr & 0xf0) | c->vc_ulcolor; 648 - else if (intensity == 0) 642 + else if (intensity == VCI_HALF_BRIGHT) 649 643 attr = (attr & 0xf0) | c->vc_halfcolor; 650 644 } 651 645 if (reverse) ··· 654 648 0x77); 655 649 if (blink) 656 650 attr ^= 0x80; 657 - if (intensity == 2) 651 + if (intensity == VCI_BOLD) 658 652 attr ^= 0x08; 659 653 if (!vga_can_do_color) { 660 654 if (italic) 661 655 attr = (attr & 0xF8) | 0x02; 662 656 else if (underline) 663 657 attr = (attr & 0xf8) | 0x01; 664 - else if (intensity == 0) 658 + else if (intensity == VCI_HALF_BRIGHT) 665 659 attr = (attr & 0xf0) | 0x08; 666 660 } 667 661 return attr; ··· 724 718 case CM_ERASE: 725 719 write_vga(14, (c->vc_pos - vga_vram_base) / 2); 726 720 if (vga_video_type >= VIDEO_TYPE_VGAC) 727 - vgacon_set_cursor_size(c->vc_x, 31, 30); 721 + vgacon_set_cursor_size(c->state.x, 31, 30); 728 722 else 729 - vgacon_set_cursor_size(c->vc_x, 31, 31); 723 + vgacon_set_cursor_size(c->state.x, 31, 31); 730 724 break; 731 725 732 726 case CM_MOVE: 733 727 case CM_DRAW: 734 728 write_vga(14, (c->vc_pos - vga_vram_base) / 2); 735 - switch (c->vc_cursor_type & 0x0f) { 729 + switch (CUR_SIZE(c->vc_cursor_type)) { 736 730 case CUR_UNDERLINE: 737 - vgacon_set_cursor_size(c->vc_x, 731 + vgacon_set_cursor_size(c->state.x, 738 732 c->vc_font.height - 739 733 (c->vc_font.height < 740 734 10 ? 2 : 3), ··· 743 737 10 ? 1 : 2)); 744 738 break; 745 739 case CUR_TWO_THIRDS: 746 - vgacon_set_cursor_size(c->vc_x, 740 + vgacon_set_cursor_size(c->state.x, 747 741 c->vc_font.height / 3, 748 742 c->vc_font.height - 749 743 (c->vc_font.height < 750 744 10 ? 1 : 2)); 751 745 break; 752 746 case CUR_LOWER_THIRD: 753 - vgacon_set_cursor_size(c->vc_x, 747 + vgacon_set_cursor_size(c->state.x, 754 748 (c->vc_font.height * 2) / 3, 755 749 c->vc_font.height - 756 750 (c->vc_font.height < 757 751 10 ? 1 : 2)); 758 752 break; 759 753 case CUR_LOWER_HALF: 760 - vgacon_set_cursor_size(c->vc_x, 754 + vgacon_set_cursor_size(c->state.x, 761 755 c->vc_font.height / 2, 762 756 c->vc_font.height - 763 757 (c->vc_font.height < ··· 765 759 break; 766 760 case CUR_NONE: 767 761 if (vga_video_type >= VIDEO_TYPE_VGAC) 768 - vgacon_set_cursor_size(c->vc_x, 31, 30); 762 + vgacon_set_cursor_size(c->state.x, 31, 30); 769 763 else 770 - vgacon_set_cursor_size(c->vc_x, 31, 31); 764 + vgacon_set_cursor_size(c->state.x, 31, 31); 771 765 break; 772 766 default: 773 - vgacon_set_cursor_size(c->vc_x, 1, 767 + vgacon_set_cursor_size(c->state.x, 1, 774 768 c->vc_font.height); 775 769 break; 776 770 } ··· 1358 1352 * console initialization routines. 1359 1353 */ 1360 1354 vga_bootup_console = 1; 1361 - c->vc_x = screen_info.orig_x; 1362 - c->vc_y = screen_info.orig_y; 1355 + c->state.x = screen_info.orig_x; 1356 + c->state.y = screen_info.orig_y; 1363 1357 } 1364 1358 1365 1359 /* We can't copy in more than the size of the video buffer,
+5 -5
drivers/video/fbdev/core/bitblit.c
··· 240 240 struct fbcon_ops *ops = info->fbcon_par; 241 241 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; 242 242 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; 245 245 int err = 1; 246 246 char *src; 247 247 ··· 286 286 cursor.set |= FB_CUR_SETCMAP; 287 287 } 288 288 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)) || 290 290 (ops->cursor_state.image.dy != (vc->vc_font.height * y)) || 291 291 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; 293 293 ops->cursor_state.image.dy = vc->vc_font.height * y; 294 294 cursor.set |= FB_CUR_SETPOS; 295 295 } ··· 325 325 ops->p->cursor_shape = vc->vc_cursor_type; 326 326 cursor.set |= FB_CUR_SETSHAPE; 327 327 328 - switch (ops->p->cursor_shape & CUR_HWMASK) { 328 + switch (CUR_SIZE(ops->p->cursor_shape)) { 329 329 case CUR_NONE: 330 330 cur_height = 0; 331 331 break;
+5 -5
drivers/video/fbdev/core/fbcon.c
··· 655 655 } 656 656 if (!save) { 657 657 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; 660 660 else 661 661 lines = logo_lines; 662 - vc->vc_y += lines; 662 + vc->state.y += lines; 663 663 vc->vc_pos += lines * vc->vc_size_row; 664 664 } 665 665 } ··· 677 677 vc->vc_size_row * 678 678 rows); 679 679 scr_memcpyw(q, save, array3_size(logo_lines, new_cols, 2)); 680 - vc->vc_y += logo_lines; 680 + vc->state.y += logo_lines; 681 681 vc->vc_pos += logo_lines * vc->vc_size_row; 682 682 kfree(save); 683 683 } ··· 1393 1393 if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1) 1394 1394 return; 1395 1395 1396 - if (vc->vc_cursor_type & 0x10) 1396 + if (vc->vc_cursor_type & CUR_SW) 1397 1397 fbcon_del_cursor_timer(info); 1398 1398 else 1399 1399 fbcon_add_cursor_timer(info);
+4 -4
drivers/video/fbdev/core/fbcon_ccw.c
··· 225 225 struct fbcon_ops *ops = info->fbcon_par; 226 226 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; 227 227 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; 230 230 int err = 1, dx, dy; 231 231 char *src; 232 232 u32 vyres = GETVYRES(ops->p->scrollmode, info); ··· 284 284 } 285 285 286 286 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); 288 288 289 289 if (ops->cursor_state.image.dx != dx || 290 290 ops->cursor_state.image.dy != dy || ··· 325 325 ops->p->cursor_shape = vc->vc_cursor_type; 326 326 cursor.set |= FB_CUR_SETSHAPE; 327 327 328 - switch (ops->p->cursor_shape & CUR_HWMASK) { 328 + switch (CUR_SIZE(ops->p->cursor_shape)) { 329 329 case CUR_NONE: 330 330 cur_height = 0; 331 331 break;
+4 -4
drivers/video/fbdev/core/fbcon_cw.c
··· 208 208 struct fbcon_ops *ops = info->fbcon_par; 209 209 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; 210 210 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; 213 213 int err = 1, dx, dy; 214 214 char *src; 215 215 u32 vxres = GETVXRES(ops->p->scrollmode, info); ··· 267 267 } 268 268 269 269 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; 271 271 272 272 if (ops->cursor_state.image.dx != dx || 273 273 ops->cursor_state.image.dy != dy || ··· 308 308 ops->p->cursor_shape = vc->vc_cursor_type; 309 309 cursor.set |= FB_CUR_SETSHAPE; 310 310 311 - switch (ops->p->cursor_shape & CUR_HWMASK) { 311 + switch (CUR_SIZE(ops->p->cursor_shape)) { 312 312 case CUR_NONE: 313 313 cur_height = 0; 314 314 break;
+4 -4
drivers/video/fbdev/core/fbcon_ud.c
··· 255 255 struct fbcon_ops *ops = info->fbcon_par; 256 256 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; 257 257 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; 260 260 int err = 1, dx, dy; 261 261 char *src; 262 262 u32 vyres = GETVYRES(ops->p->scrollmode, info); ··· 315 315 } 316 316 317 317 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); 319 319 320 320 if (ops->cursor_state.image.dx != dx || 321 321 ops->cursor_state.image.dy != dy || ··· 348 348 ops->p->cursor_shape = vc->vc_cursor_type; 349 349 cursor.set |= FB_CUR_SETSHAPE; 350 350 351 - switch (ops->p->cursor_shape & CUR_HWMASK) { 351 + switch (CUR_SIZE(ops->p->cursor_shape)) { 352 352 case CUR_NONE: 353 353 cur_height = 0; 354 354 break;
+3 -3
drivers/video/fbdev/core/tileblit.c
··· 83 83 int softback_lines, int fg, int bg) 84 84 { 85 85 struct fb_tilecursor cursor; 86 - int use_sw = (vc->vc_cursor_type & 0x10); 86 + int use_sw = vc->vc_cursor_type & CUR_SW; 87 87 88 - cursor.sx = vc->vc_x; 89 - cursor.sy = vc->vc_y; 88 + cursor.sx = vc->state.x; 89 + cursor.sy = vc->state.y; 90 90 cursor.mode = (mode == CM_ERASE || use_sw) ? 0 : 1; 91 91 cursor.fg = fg; 92 92 cursor.bg = bg;
+5 -8
include/linux/console.h
··· 24 24 struct tty_struct; 25 25 struct notifier_block; 26 26 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 - 33 27 enum con_scroll { 34 28 SM_UP, 35 29 SM_DOWN, 36 30 }; 31 + 32 + enum vc_intensity; 37 33 38 34 /** 39 35 * struct consw - callbacks for consoles ··· 70 74 void (*con_scrolldelta)(struct vc_data *vc, int lines); 71 75 int (*con_set_origin)(struct vc_data *vc); 72 76 void (*con_save_screen)(struct vc_data *vc); 73 - u8 (*con_build_attr)(struct vc_data *vc, u8 color, u8 intensity, 74 - u8 blink, u8 underline, u8 reverse, u8 italic); 77 + u8 (*con_build_attr)(struct vc_data *vc, u8 color, 78 + enum vc_intensity intensity, 79 + bool blink, bool underline, bool reverse, bool italic); 75 80 void (*con_invert_region)(struct vc_data *vc, u16 *p, int count); 76 81 u16 *(*con_screen_pos)(struct vc_data *vc, int offset); 77 82 unsigned long (*con_getxy)(struct vc_data *vc, unsigned long position,
+58 -35
include/linux/console_struct.h
··· 21 21 struct uni_screen; 22 22 23 23 #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 + }; 24 61 25 62 /* 26 63 * Example: vc_data of a console that was scrolled 3 lines down. ··· 94 57 struct vc_data { 95 58 struct tty_port port; /* Upper level data */ 96 59 60 + struct vc_state state, saved_state; 61 + 97 62 unsigned short vc_num; /* Console number */ 98 63 unsigned int vc_cols; /* [#] Console size */ 99 64 unsigned int vc_rows; ··· 112 73 /* attributes for all characters on screen */ 113 74 unsigned char vc_attr; /* Current attributes */ 114 75 unsigned char vc_def_color; /* Default colors */ 115 - unsigned char vc_color; /* Foreground & background */ 116 - unsigned char vc_s_color; /* Saved foreground & background */ 117 76 unsigned char vc_ulcolor; /* Color for underline mode */ 118 77 unsigned char vc_itcolor; 119 78 unsigned char vc_halfcolor; /* Color for half intensity mode */ ··· 119 82 unsigned int vc_cursor_type; 120 83 unsigned short vc_complement_mask; /* [#] Xor mask for mouse pointer */ 121 84 unsigned short vc_s_complement_mask; /* Saved mouse pointer mask */ 122 - unsigned int vc_x, vc_y; /* Cursor position */ 123 - unsigned int vc_saved_x, vc_saved_y; 124 85 unsigned long vc_pos; /* Cursor address */ 125 86 /* fonts */ 126 87 unsigned short vc_hi_font_mask; /* [#] Attribute set for upper 256 chars of font or 0 if not supported */ ··· 133 98 int vt_newvt; 134 99 wait_queue_head_t paste_wait; 135 100 /* mode flags */ 136 - unsigned int vc_charset : 1; /* Character set G0 / G1 */ 137 - unsigned int vc_s_charset : 1; /* Saved character set */ 138 101 unsigned int vc_disp_ctrl : 1; /* Display chars < 32? */ 139 102 unsigned int vc_toggle_meta : 1; /* Toggle high bit? */ 140 103 unsigned int vc_decscnm : 1; /* Screen Mode */ ··· 140 107 unsigned int vc_decawm : 1; /* Autowrap Mode */ 141 108 unsigned int vc_deccm : 1; /* Cursor Visible */ 142 109 unsigned int vc_decim : 1; /* Insert Mode */ 143 - /* attribute flags */ 144 - unsigned int vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */ 145 - unsigned int vc_italic:1; 146 - unsigned int vc_underline : 1; 147 - unsigned int vc_blink : 1; 148 - unsigned int vc_reverse : 1; 149 - unsigned int vc_s_intensity : 2; /* saved rendition */ 150 - unsigned int vc_s_italic:1; 151 - unsigned int vc_s_underline : 1; 152 - unsigned int vc_s_blink : 1; 153 - unsigned int vc_s_reverse : 1; 154 110 /* misc */ 155 111 unsigned int vc_priv : 3; 156 112 unsigned int vc_need_wrap : 1; ··· 148 126 unsigned char vc_utf : 1; /* Unicode UTF-8 encoding */ 149 127 unsigned char vc_utf_count; 150 128 int vc_utf_char; 151 - unsigned int vc_tab_stop[8]; /* Tab stops. 256 columns. */ 129 + DECLARE_BITMAP(vc_tab_stop, VC_TABSTOPS_COUNT); /* Tab stops. 256 columns. */ 152 130 unsigned char vc_palette[16*3]; /* Colour palette for VGA+ */ 153 131 unsigned short * vc_translate; 154 - unsigned char vc_G0_charset; 155 - unsigned char vc_G1_charset; 156 - unsigned char vc_saved_G0; 157 - unsigned char vc_saved_G1; 158 132 unsigned int vc_resize_user; /* resize request from user */ 159 133 unsigned int vc_bell_pitch; /* Console bell pitch */ 160 134 unsigned int vc_bell_duration; /* Console bell duration */ ··· 167 149 struct work_struct SAK_work; 168 150 169 151 /* might add scrmem, kbd at some time, 170 - to have everything in one place - the disadvantage 171 - would be that vc_cons etc can no longer be static */ 152 + to have everything in one place */ 172 153 }; 173 154 174 155 extern struct vc vc_cons [MAX_NR_CONSOLES]; 175 156 extern void vc_SAK(struct work_struct *work); 176 157 177 - #define CUR_DEF 0 178 - #define CUR_NONE 1 179 - #define CUR_UNDERLINE 2 180 - #define CUR_LOWER_THIRD 3 181 - #define CUR_LOWER_HALF 4 182 - #define CUR_TWO_THIRDS 5 183 - #define CUR_BLOCK 6 184 - #define CUR_HWMASK 0x0f 185 - #define CUR_SWMASK 0xfff0 186 - 187 - #define CUR_DEFAULT CUR_UNDERLINE 158 + #define CUR_MAKE(size, change, set) ((size) | ((change) << 8) | \ 159 + ((set) << 16)) 160 + #define CUR_SIZE(c) ((c) & 0x00000f) 161 + # define CUR_DEF 0 162 + # define CUR_NONE 1 163 + # define CUR_UNDERLINE 2 164 + # define CUR_LOWER_THIRD 3 165 + # define CUR_LOWER_HALF 4 166 + # define CUR_TWO_THIRDS 5 167 + # define CUR_BLOCK 6 168 + #define CUR_SW 0x000010 169 + #define CUR_ALWAYS_BG 0x000020 170 + #define CUR_INVERT_FG_BG 0x000040 171 + #define CUR_FG 0x000700 172 + #define CUR_BG 0x007000 173 + #define CUR_CHANGE(c) ((c) & 0x00ff00) 174 + #define CUR_SET(c) (((c) & 0xff0000) >> 8) 188 175 189 176 bool con_is_visible(const struct vc_data *vc); 190 177
+2
include/linux/serial_8250.h
··· 155 155 156 156 extern int early_serial8250_setup(struct earlycon_device *device, 157 157 const char *options); 158 + extern void serial8250_update_uartclk(struct uart_port *port, 159 + unsigned int uartclk); 158 160 extern void serial8250_do_set_termios(struct uart_port *port, 159 161 struct ktermios *termios, struct ktermios *old); 160 162 extern void serial8250_do_set_ldisc(struct uart_port *port,
+1 -1
include/linux/serial_core.h
··· 10 10 #include <linux/bitops.h> 11 11 #include <linux/compiler.h> 12 12 #include <linux/console.h> 13 - #include <linux/gpio/consumer.h> 14 13 #include <linux/interrupt.h> 15 14 #include <linux/circ_buf.h> 16 15 #include <linux/spinlock.h> ··· 29 30 struct uart_port; 30 31 struct serial_struct; 31 32 struct device; 33 + struct gpio_desc; 32 34 33 35 /* 34 36 * This structure describes all the operations that can be done on the
-3
include/linux/vt_kern.h
··· 74 74 void con_free_unimap(struct vc_data *vc); 75 75 int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc); 76 76 77 - #define vc_translate(vc, c) ((vc)->vc_translate[(c) | \ 78 - ((vc)->vc_toggle_meta ? 0x80 : 0)]) 79 77 #else 80 78 static inline int con_set_trans_old(unsigned char __user *table) 81 79 { ··· 122 124 return 0; 123 125 } 124 126 125 - #define vc_translate(vc, c) (c) 126 127 #endif 127 128 128 129 /* vt.c */
-14
include/uapi/linux/serial_core.h
··· 26 26 /* 27 27 * The type definitions. These are from Ted Ts'o's serial.h 28 28 */ 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 43 29 #define PORT_NS16550A 14 44 30 #define PORT_XSCALE 15 45 31 #define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */