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

Configure Feed

Select the types of activity you want to include in your feed.

8250: Fix oops from setserial

If you setserial a port which has never been initialised we change the type
but don't update the I/O method pointers. The same problem is true if you
change the io type of a port - but nobody ever does that so nobody noticed!

Remember the old type and when attaching if the type has changed reload the
port accessor pointers. We can't do it blindly as some 8250 drivers load custom
accessors and we must not stomp those.

Tested-by: Victor Seryodkin <vvscore@gmail.com>
Closes-bug: #13367
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Alan Cox and committed by
Linus Torvalds
b8e7e40a 715fe7af

+15
+15
drivers/serial/8250.c
··· 137 137 unsigned char mcr; 138 138 unsigned char mcr_mask; /* mask of user bits */ 139 139 unsigned char mcr_force; /* mask of forced bits */ 140 + unsigned char cur_iotype; /* Running I/O type */ 140 141 141 142 /* 142 143 * Some bits in registers are cleared on a read, so they must ··· 472 471 473 472 static void set_io_from_upio(struct uart_port *p) 474 473 { 474 + struct uart_8250_port *up = (struct uart_8250_port *)p; 475 475 switch (p->iotype) { 476 476 case UPIO_HUB6: 477 477 p->serial_in = hub6_serial_in; ··· 511 509 p->serial_out = io_serial_out; 512 510 break; 513 511 } 512 + /* Remember loaded iotype */ 513 + up->cur_iotype = p->iotype; 514 514 } 515 515 516 516 static void ··· 1941 1937 up->capabilities = uart_config[up->port.type].flags; 1942 1938 up->mcr = 0; 1943 1939 1940 + if (up->port.iotype != up->cur_iotype) 1941 + set_io_from_upio(port); 1942 + 1944 1943 if (up->port.type == PORT_16C950) { 1945 1944 /* Wake up and initialize UART */ 1946 1945 up->acr = 0; ··· 2570 2563 if (ret < 0) 2571 2564 probeflags &= ~PROBE_RSA; 2572 2565 2566 + if (up->port.iotype != up->cur_iotype) 2567 + set_io_from_upio(port); 2568 + 2573 2569 if (flags & UART_CONFIG_TYPE) 2574 2570 autoconfig(up, probeflags); 2575 2571 if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) ··· 2680 2670 serial8250_register_ports(struct uart_driver *drv, struct device *dev) 2681 2671 { 2682 2672 int i; 2673 + 2674 + for (i = 0; i < nr_uarts; i++) { 2675 + struct uart_8250_port *up = &serial8250_ports[i]; 2676 + up->cur_iotype = 0xFF; 2677 + } 2683 2678 2684 2679 serial8250_isa_init_ports(); 2685 2680