8960_BT : Block the tasklets to schedule
Block the tasklets to schedule when there
is no event/data available on the SMD channels
Change-Id: Icc93aad85addc128ff5ad0650989132ebd8d6399
Signed-off-by: Bhasker Neti <bneti@codeaurora.org>
diff --git a/drivers/bluetooth/hci_smd.c b/drivers/bluetooth/hci_smd.c
index 118bbb3..a321849 100644
--- a/drivers/bluetooth/hci_smd.c
+++ b/drivers/bluetooth/hci_smd.c
@@ -140,20 +140,20 @@
wake_lock(&hs.wake_lock_rx);
len = smd_read_avail(hsmd->data_channel);
- if (len <= 0) {
- BT_ERR("Nothing to read from SMD channel\n");
+ if (len > HCI_MAX_FRAME_SIZE) {
+ BT_ERR("Frame larger than the allowed size");
goto out_data;
}
while (len > 0) {
skb = bt_skb_alloc(len, GFP_ATOMIC);
if (!skb) {
- BT_ERR("Error in allocating socket buffer\n");
+ BT_ERR("Error in allocating socket buffer");
goto out_data;
}
buf = kmalloc(len, GFP_ATOMIC);
if (!buf) {
- BT_ERR("Error in allocating buffer\n");
+ BT_ERR("Error in allocating buffer");
rc = -ENOMEM;
goto out_data;
}
@@ -188,7 +188,7 @@
* Start the timer to monitor whether the Rx queue is
* empty for releasing the Rx wake lock
*/
- BT_DBG("Rx Timer is starting\n");
+ BT_DBG("Rx Timer is starting");
mod_timer(&hsmd->rx_q_timer,
jiffies + msecs_to_jiffies(RX_Q_MONITOR));
}
@@ -214,20 +214,17 @@
if (len > HCI_MAX_FRAME_SIZE) {
BT_ERR("Frame larger than the allowed size");
goto out_event;
- } else if (len <= 0) {
- BT_ERR("Nothing to read from SMD channel\n");
- goto out_event;
}
while (len > 0) {
skb = bt_skb_alloc(len, GFP_ATOMIC);
if (!skb) {
- BT_ERR("Error in allocating socket buffer\n");
+ BT_ERR("Error in allocating socket buffer");
goto out_event;
}
buf = kmalloc(len, GFP_ATOMIC);
if (!buf) {
- BT_ERR("Error in allocating buffer\n");
+ BT_ERR("Error in allocating buffer");
rc = -ENOMEM;
goto out_event;
}
@@ -261,7 +258,7 @@
* Start the timer to monitor whether the Rx queue is
* empty for releasing the Rx wake lock
*/
- BT_DBG("Rx Timer is starting\n");
+ BT_DBG("Rx Timer is starting");
mod_timer(&hsmd->rx_q_timer,
jiffies + msecs_to_jiffies(RX_Q_MONITOR));
}
@@ -308,7 +305,7 @@
}
break;
default:
- BT_ERR("Uknown packet type\n");
+ BT_ERR("Uknown packet type");
ret = -ENODEV;
break;
}
@@ -322,6 +319,8 @@
static void hci_smd_notify_event(void *data, unsigned int event)
{
struct hci_dev *hdev = hs.hdev;
+ struct hci_smd_data *hsmd = &hs;
+ int len = 0;
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
@@ -330,12 +329,19 @@
switch (event) {
case SMD_EVENT_DATA:
- tasklet_hi_schedule(&hs.hci_event_task);
+ len = smd_read_avail(hsmd->event_channel);
+ if (len > 0)
+ tasklet_hi_schedule(&hs.hci_event_task);
+ else if (len < 0)
+ BT_ERR("Failed to read event from smd %d", len);
+
break;
case SMD_EVENT_OPEN:
+ BT_INFO("opening HCI-SMD channel :%s", EVENT_CHANNEL);
hci_smd_open(hdev);
break;
case SMD_EVENT_CLOSE:
+ BT_INFO("Closing HCI-SMD channel :%s", EVENT_CHANNEL);
hci_smd_close(hdev);
break;
default:
@@ -346,6 +352,9 @@
static void hci_smd_notify_data(void *data, unsigned int event)
{
struct hci_dev *hdev = hs.hdev;
+ struct hci_smd_data *hsmd = &hs;
+ int len = 0;
+
if (!hdev) {
BT_ERR("HCI device (hdev=NULL)");
return;
@@ -353,12 +362,18 @@
switch (event) {
case SMD_EVENT_DATA:
- tasklet_hi_schedule(&hs.hci_data_task);
+ len = smd_read_avail(hsmd->data_channel);
+ if (len > 0)
+ tasklet_hi_schedule(&hs.hci_data_task);
+ else if (len < 0)
+ BT_ERR("Failed to read data from smd %d", len);
break;
case SMD_EVENT_OPEN:
+ BT_INFO("opening HCI-SMD channel :%s", DATA_CHANNEL);
hci_smd_open(hdev);
break;
case SMD_EVENT_CLOSE:
+ BT_INFO("Closing HCI-SMD channel :%s", DATA_CHANNEL);
hci_smd_close(hdev);
break;
default:
@@ -419,7 +434,7 @@
rc = smd_named_open_on_edge(DATA_CHANNEL, SMD_APPS_WCNSS,
&hsmd->data_channel, hdev, hci_smd_notify_data);
if (rc < 0) {
- BT_ERR("Failed to open the Data channel\n");
+ BT_ERR("Failed to open the Data channel");
hci_free_dev(hdev);
return -ENODEV;
}