Bluetooth: btmrvl: add surprise_removed flag
authorAmitkumar Karwar <akarwar@marvell.com>
Thu, 1 Jan 2015 08:13:41 +0000 (00:13 -0800)
committerMarcel Holtmann <marcel@holtmann.org>
Tue, 6 Jan 2015 15:19:35 +0000 (16:19 +0100)
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 <akarwar@marvell.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
drivers/bluetooth/btmrvl_drv.h
drivers/bluetooth/btmrvl_main.c
drivers/bluetooth/btmrvl_sdio.c

index 330f8f84928d4d883be8b246eb78b90bad7f6159..5513204c8bb2e0b59389b558926cff2bbcf3be86 100644 (file)
@@ -104,6 +104,7 @@ struct btmrvl_private {
 #ifdef CONFIG_DEBUG_FS
        void *debugfs_data;
 #endif
+       bool surprise_removed;
 };
 
 #define MRVL_VENDOR_PKT                        0xFE
index c435b58db5974c09d54d3fa3263b3a66abe7703d..c4a542cc3214910deaeb808508816c83fb1c12ac 100644 (file)
@@ -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;
                }
index 0057c0b7a7761e4053e1183f467502b37dbc93a1..80ec2008bd7cc82c5ff21140df8fe0c8e99fc8e3 100644 (file)
@@ -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);
                }