diff options
author | Par-Gunnar Hjalmdahl <par-gunnar.p.hjalmdahl@stericsson.com> | 2011-08-29 09:29:05 +0530 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@linaro.org> | 2012-03-19 09:01:12 +0100 |
commit | 2014ff8d6d2cf226f44bd012726f646e6d29832e (patch) | |
tree | 8097f8514fd384555dad860b88bd9ac28552fbe6 /drivers/staging/cg2900/bluetooth/cg2900_uart.c | |
parent | 2b80e55125b02a3ceb199a64c782b8456d59db77 (diff) |
cg2900: Fix crash when transport is closed
This patch fixes crashes caused by transport being removed
while users of the CG2900 driver still exist.
ST-Ericsson Linux next: Not tested, ER 336652
ST-Ericsson ID: 336652
ST-Ericsson FOSS-OUT ID: Trivial
Change-Id: I6318ce1086097a4fa63a1793b6795b01ea939715
Signed-off-by: Par-Gunnar Hjalmdahl <par-gunnar.p.hjalmdahl@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/21781
Reviewed-by: QATEST
Reviewed-by: Lukasz RYMANOWSKI <lukasz.rymanowski@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/29795
Reviewed-by: Virupax SADASHIVPETIMATH <virupax.sadashivpetimath@stericsson.com>
Tested-by: Virupax SADASHIVPETIMATH <virupax.sadashivpetimath@stericsson.com>
Diffstat (limited to 'drivers/staging/cg2900/bluetooth/cg2900_uart.c')
-rw-r--r-- | drivers/staging/cg2900/bluetooth/cg2900_uart.c | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/drivers/staging/cg2900/bluetooth/cg2900_uart.c b/drivers/staging/cg2900/bluetooth/cg2900_uart.c index 4417525306a..d7a1fb1044f 100644 --- a/drivers/staging/cg2900/bluetooth/cg2900_uart.c +++ b/drivers/staging/cg2900/bluetooth/cg2900_uart.c @@ -333,9 +333,10 @@ static void wake_up_chip(struct uart_info *uart_info); */ static bool is_chip_flow_off(struct uart_info *uart_info) { - int lines; + int lines = 0; - lines = hci_uart_tiocmget(uart_info->hu); + if (uart_info->hu) + lines = hci_uart_tiocmget(uart_info->hu); if (lines & TIOCM_CTS) return false; @@ -577,6 +578,11 @@ static void wake_up_chip(struct uart_info *uart_info) if (!timeout_jiffies && uart_info->sleep_state != CHIP_RESUMING) return; + if (!uart_info->hu) { + dev_err(MAIN_DEV, "wake_up_chip: UART not open\n"); + return; + } + mutex_lock(&(uart_info->sleep_state_lock)); /* @@ -602,7 +608,7 @@ static void wake_up_chip(struct uart_info *uart_info) /* Disable IRQ only when it was enabled. */ unset_cts_irq(uart_info); (void)hci_uart_set_baudrate(uart_info->hu, - uart_info->baud_rate); + uart_info->baud_rate); enable_uart_pins(uart_info); @@ -650,6 +656,11 @@ static void set_chip_sleep_mode(struct work_struct *work) if (!timeout_jiffies) return; + if (!uart_info->hu) { + dev_err(MAIN_DEV, "set_chip_sleep_mode: UART not open\n"); + return; + } + if (uart_info->tx_in_progress || uart_info->rx_in_progress) { dev_dbg(MAIN_DEV, "Not going to sleep, TX/RX in progress\n"); return; @@ -674,13 +685,12 @@ static void set_chip_sleep_mode(struct work_struct *work) * Set baud zero. * This cause shut off UART clock as well. */ - (void)hci_uart_set_baudrate(uart_info->hu, - ZERO_BAUD_RATE); + (void)hci_uart_set_baudrate(uart_info->hu, ZERO_BAUD_RATE); err = set_cts_irq(uart_info); if (err < 0) { enable_uart_pins(uart_info); (void)hci_uart_set_baudrate(uart_info->hu, - uart_info->baud_rate); + uart_info->baud_rate); hci_uart_flow_ctrl(uart_info->hu, FLOW_ON); hci_uart_set_break(uart_info->hu, BREAK_OFF); @@ -1060,6 +1070,11 @@ static void work_do_transmit(struct work_struct *work) kfree(current_work); + if (!uart_info->hu) { + dev_err(MAIN_DEV, "work_do_transmit: UART not open\n"); + return; + } + spin_lock_bh(&(uart_info->transmission_lock)); /* Mark that there is an ongoing transfer. */ uart_info->tx_in_progress = true; @@ -1129,6 +1144,11 @@ static int set_baud_rate(struct hci_uart *hu, int baud) return -EALREADY; } + if (!uart_info->hu) { + dev_err(MAIN_DEV, "set_baud_rate: UART not open\n"); + return -EFAULT; + } + /* * Wait some time to be sure that any RX process has finished (which * flows on RTS in the end) before flowing off the RTS. @@ -1244,6 +1264,11 @@ static int uart_open(struct cg2900_chip_dev *dev) struct hci_command_hdr *cmd; struct uart_info *uart_info = dev_get_drvdata(dev->dev); + if (!uart_info->hu) { + dev_err(MAIN_DEV, "uart_open: UART not open\n"); + return -EACCES; + } + /* * Chip has just been started up. It has a system to autodetect * exact baud rate and transport to use. There are only a few commands |