From 7b4b8740c6fc153fbb24b3c1ac391cf8908ad113 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Thu, 1 Jan 2015 00:13:41 -0800 Subject: Bluetooth: btmrvl: add surprise_removed flag This flag will be set in unload path to make sure that we skip sending further commands, ignore interrupts and stop main thread when unload starts. Signed-off-by: Amitkumar Karwar Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btmrvl_drv.h | 1 + drivers/bluetooth/btmrvl_main.c | 9 +++++++-- drivers/bluetooth/btmrvl_sdio.c | 4 ++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h index 330f8f84928d..5513204c8bb2 100644 --- a/drivers/bluetooth/btmrvl_drv.h +++ b/drivers/bluetooth/btmrvl_drv.h @@ -104,6 +104,7 @@ struct btmrvl_private { #ifdef CONFIG_DEBUG_FS void *debugfs_data; #endif + bool surprise_removed; }; #define MRVL_VENDOR_PKT 0xFE diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index c435b58db597..c4a542cc3214 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -178,6 +178,11 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode, struct sk_buff *skb; struct hci_command_hdr *hdr; + if (priv->surprise_removed) { + BT_ERR("Card is removed"); + return -EFAULT; + } + skb = bt_skb_alloc(HCI_COMMAND_HDR_SIZE + len, GFP_ATOMIC); if (skb == NULL) { BT_ERR("No free skb"); @@ -600,7 +605,7 @@ static int btmrvl_service_main_thread(void *data) add_wait_queue(&thread->wait_q, &wait); set_current_state(TASK_INTERRUPTIBLE); - if (kthread_should_stop()) { + if (kthread_should_stop() || priv->surprise_removed) { BT_DBG("main_thread: break from main thread"); break; } @@ -619,7 +624,7 @@ static int btmrvl_service_main_thread(void *data) BT_DBG("main_thread woke up"); - if (kthread_should_stop()) { + if (kthread_should_stop() || priv->surprise_removed) { BT_DBG("main_thread: break from main thread"); break; } diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 0057c0b7a776..80ec2008bd7c 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -798,6 +798,9 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func) priv = card->priv; + if (priv->surprise_removed) + return; + if (card->reg->int_read_to_clear) ret = btmrvl_sdio_read_to_clear(card, &ireg); else @@ -1466,6 +1469,7 @@ static void btmrvl_sdio_remove(struct sdio_func *func) btmrvl_sdio_disable_host_int(card); } BT_DBG("unregester dev"); + card->priv->surprise_removed = true; btmrvl_sdio_unregister_dev(card); btmrvl_remove_card(card->priv); } -- cgit v1.2.3