Commit 6e406121 authored by Jason Wessel's avatar Jason Wessel Committed by Greg Kroah-Hartman

USB: console: Fix regression in usb console on kernel boot

The commit 335f8514 introduced a
regression which stopped usb consoles from working correctly as a
kernel boot console as well as interactive login device.

The addition of the serial_close() which in turn calls
tty_port_close_start() will change the reference count of port.count
and warn about it.  The usb console code had previously incremented
the port.count to indicate it was making use of the device as a
console and the forced change causes a double open on the usb device
which leads to a non obvious kernel oops later on when the tty is
freed.

To fix the problem instead make use of port->console to track if the
port is in fact an active console port to avoid double initialization
of the usb serial device.  The port.count is incremented and
decremented only with in the scope of usb_console_setup() for the
purpose of the low level driver initialization.
Signed-off-by: default avatarJason Wessel <jason.wessel@windriver.com>
Acked-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent bf7fbb02
...@@ -169,9 +169,11 @@ static int usb_console_setup(struct console *co, char *options) ...@@ -169,9 +169,11 @@ static int usb_console_setup(struct console *co, char *options)
kfree(tty); kfree(tty);
} }
} }
/* So we know not to kill the hardware on a hangup on this /* Now that any required fake tty operations are completed restore
port. We have also bumped the use count by one so it won't go * the tty port count */
idle */ --port->port.count;
/* The console is special in terms of closing the device so
* indicate this port is now acting as a system console. */
port->console = 1; port->console = 1;
retval = 0; retval = 0;
...@@ -204,7 +206,7 @@ static void usb_console_write(struct console *co, ...@@ -204,7 +206,7 @@ static void usb_console_write(struct console *co,
dbg("%s - port %d, %d byte(s)", __func__, port->number, count); dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
if (!port->port.count) { if (!port->console) {
dbg("%s - port not opened", __func__); dbg("%s - port not opened", __func__);
return; return;
} }
...@@ -300,8 +302,7 @@ void usb_serial_console_exit(void) ...@@ -300,8 +302,7 @@ void usb_serial_console_exit(void)
{ {
if (usbcons_info.port) { if (usbcons_info.port) {
unregister_console(&usbcons); unregister_console(&usbcons);
if (usbcons_info.port->port.count) usbcons_info.port->console = 0;
usbcons_info.port->port.count--;
usbcons_info.port = NULL; usbcons_info.port = NULL;
} }
} }
......
...@@ -220,7 +220,8 @@ static int serial_open (struct tty_struct *tty, struct file *filp) ...@@ -220,7 +220,8 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
tty->driver_data = port; tty->driver_data = port;
tty_port_tty_set(&port->port, tty); tty_port_tty_set(&port->port, tty);
if (port->port.count == 1) { /* If the console is attached, the device is already open */
if (port->port.count == 1 && !port->console) {
/* lock this module before we call it /* lock this module before we call it
* this may fail, which means we must bail out, * this may fail, which means we must bail out,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment