提交 d5f735e5 编写于 作者: P Pavel Machek 提交者: Linus Torvalds

[PATCH] serial core: work around sub-driver bugs

We're presently getting oopses because Bluetooth (and possibly other) drivers
are calling core functions after things have been shut down.

So rather than oopsing, let's drop a warning then take avoiding action, so the
machine survives.  Once all the sub-drivers are fixed up we can remove the
take-avoiding-action part.
Signed-off-by: NPavel Machek <pavel@suse.cz>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 1c6cc5fd
...@@ -71,6 +71,11 @@ static void uart_change_pm(struct uart_state *state, int pm_state); ...@@ -71,6 +71,11 @@ static void uart_change_pm(struct uart_state *state, int pm_state);
void uart_write_wakeup(struct uart_port *port) void uart_write_wakeup(struct uart_port *port)
{ {
struct uart_info *info = port->info; struct uart_info *info = port->info;
/*
* This means you called this function _after_ the port was
* closed. No cookie for you.
*/
BUG_ON(!info);
tasklet_schedule(&info->tlet); tasklet_schedule(&info->tlet);
} }
...@@ -471,14 +476,26 @@ static void uart_flush_chars(struct tty_struct *tty) ...@@ -471,14 +476,26 @@ static void uart_flush_chars(struct tty_struct *tty)
} }
static int static int
uart_write(struct tty_struct *tty, const unsigned char * buf, int count) uart_write(struct tty_struct *tty, const unsigned char *buf, int count)
{ {
struct uart_state *state = tty->driver_data; struct uart_state *state = tty->driver_data;
struct uart_port *port = state->port; struct uart_port *port;
struct circ_buf *circ = &state->info->xmit; struct circ_buf *circ;
unsigned long flags; unsigned long flags;
int c, ret = 0; int c, ret = 0;
/*
* This means you called this function _after_ the port was
* closed. No cookie for you.
*/
if (!state || !state->info) {
WARN_ON(1);
return -EL3HLT;
}
port = state->port;
circ = &state->info->xmit;
if (!circ->buf) if (!circ->buf)
return 0; return 0;
...@@ -521,6 +538,15 @@ static void uart_flush_buffer(struct tty_struct *tty) ...@@ -521,6 +538,15 @@ static void uart_flush_buffer(struct tty_struct *tty)
struct uart_port *port = state->port; struct uart_port *port = state->port;
unsigned long flags; unsigned long flags;
/*
* This means you called this function _after_ the port was
* closed. No cookie for you.
*/
if (!state || !state->info) {
WARN_ON(1);
return;
}
DPRINTK("uart_flush_buffer(%d) called\n", tty->index); DPRINTK("uart_flush_buffer(%d) called\n", tty->index);
spin_lock_irqsave(&port->lock, flags); spin_lock_irqsave(&port->lock, flags);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册