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 <akarwar@marvell.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
Amitkumar Karwar 2015-01-01 00:13:41 -08:00 committed by Marcel Holtmann
parent 9b89fdfee4
commit 7b4b8740c6
3 changed files with 12 additions and 2 deletions

View File

@ -104,6 +104,7 @@ struct btmrvl_private {
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
void *debugfs_data; void *debugfs_data;
#endif #endif
bool surprise_removed;
}; };
#define MRVL_VENDOR_PKT 0xFE #define MRVL_VENDOR_PKT 0xFE

View File

@ -178,6 +178,11 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode,
struct sk_buff *skb; struct sk_buff *skb;
struct hci_command_hdr *hdr; 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); skb = bt_skb_alloc(HCI_COMMAND_HDR_SIZE + len, GFP_ATOMIC);
if (skb == NULL) { if (skb == NULL) {
BT_ERR("No free skb"); BT_ERR("No free skb");
@ -600,7 +605,7 @@ static int btmrvl_service_main_thread(void *data)
add_wait_queue(&thread->wait_q, &wait); add_wait_queue(&thread->wait_q, &wait);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if (kthread_should_stop()) { if (kthread_should_stop() || priv->surprise_removed) {
BT_DBG("main_thread: break from main thread"); BT_DBG("main_thread: break from main thread");
break; break;
} }
@ -619,7 +624,7 @@ static int btmrvl_service_main_thread(void *data)
BT_DBG("main_thread woke up"); 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"); BT_DBG("main_thread: break from main thread");
break; break;
} }

View File

@ -798,6 +798,9 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func)
priv = card->priv; priv = card->priv;
if (priv->surprise_removed)
return;
if (card->reg->int_read_to_clear) if (card->reg->int_read_to_clear)
ret = btmrvl_sdio_read_to_clear(card, &ireg); ret = btmrvl_sdio_read_to_clear(card, &ireg);
else else
@ -1466,6 +1469,7 @@ static void btmrvl_sdio_remove(struct sdio_func *func)
btmrvl_sdio_disable_host_int(card); btmrvl_sdio_disable_host_int(card);
} }
BT_DBG("unregester dev"); BT_DBG("unregester dev");
card->priv->surprise_removed = true;
btmrvl_sdio_unregister_dev(card); btmrvl_sdio_unregister_dev(card);
btmrvl_remove_card(card->priv); btmrvl_remove_card(card->priv);
} }