diff options
-rw-r--r-- | drivers/bluetooth/btmrvl_drv.h | 1 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_main.c | 11 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_sdio.c | 3 |
3 files changed, 12 insertions, 3 deletions
diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h index 27a9aac25583..05904732e6f1 100644 --- a/drivers/bluetooth/btmrvl_drv.h +++ b/drivers/bluetooth/btmrvl_drv.h @@ -89,6 +89,7 @@ struct btmrvl_adapter { wait_queue_head_t event_hs_wait_q; u8 cmd_complete; bool is_suspended; + bool is_suspending; }; struct btmrvl_private { diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index b2a567bb1b46..f25a825a693f 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -436,6 +436,11 @@ static int btmrvl_send_frame(struct hci_dev *hdev, struct sk_buff *skb) BT_DBG("type=%d, len=%d", hci_skb_pkt_type(skb), skb->len); + if (priv->adapter->is_suspending || priv->adapter->is_suspended) { + BT_ERR("%s: Device is suspending or suspended", __func__); + return -EBUSY; + } + switch (hci_skb_pkt_type(skb)) { case HCI_COMMAND_PKT: hdev->stat.cmd_tx++; @@ -452,7 +457,8 @@ static int btmrvl_send_frame(struct hci_dev *hdev, struct sk_buff *skb) skb_queue_tail(&priv->adapter->tx_queue, skb); - wake_up_interruptible(&priv->main_thread.wait_q); + if (!priv->adapter->is_suspended) + wake_up_interruptible(&priv->main_thread.wait_q); return 0; } @@ -643,7 +649,8 @@ static int btmrvl_service_main_thread(void *data) if (adapter->ps_state == PS_SLEEP) continue; - if (!priv->btmrvl_dev.tx_dnld_rdy) + if (!priv->btmrvl_dev.tx_dnld_rdy || + priv->adapter->is_suspended) continue; skb = skb_dequeue(&adapter->tx_queue); diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 73a1c2779969..6ed8acfcfa9c 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -1545,10 +1545,10 @@ static int btmrvl_sdio_suspend(struct device *dev) } priv = card->priv; + priv->adapter->is_suspending = true; hcidev = priv->btmrvl_dev.hcidev; BT_DBG("%s: SDIO suspend", hcidev->name); hci_suspend_dev(hcidev); - skb_queue_purge(&priv->adapter->tx_queue); if (priv->adapter->hs_state != HS_ACTIVATED) { if (btmrvl_enable_hs(priv)) { @@ -1557,6 +1557,7 @@ static int btmrvl_sdio_suspend(struct device *dev) } } + priv->adapter->is_suspending = false; priv->adapter->is_suspended = true; /* We will keep the power when hs enabled successfully */ |