aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/hci.h3
-rw-r--r--include/net/bluetooth/hci_core.h2
-rw-r--r--net/bluetooth/hci_core.c22
-rw-r--r--net/bluetooth/hci_event.c6
4 files changed, 26 insertions, 7 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index e756f82a29e5..6d4e11624fef 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -119,6 +119,7 @@ enum {
119#define HCI_PAIRING_TIMEOUT (60000) /* 60 seconds */ 119#define HCI_PAIRING_TIMEOUT (60000) /* 60 seconds */
120#define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */ 120#define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */
121#define HCI_INIT_TIMEOUT (10000) /* 10 seconds */ 121#define HCI_INIT_TIMEOUT (10000) /* 10 seconds */
122#define HCI_CMD_TIMEOUT (1000) /* 1 seconds */
122 123
123/* HCI data types */ 124/* HCI data types */
124#define HCI_COMMAND_PKT 0x01 125#define HCI_COMMAND_PKT 0x01
@@ -244,6 +245,8 @@ enum {
244#define HCI_AT_GENERAL_BONDING_MITM 0x05 245#define HCI_AT_GENERAL_BONDING_MITM 0x05
245 246
246/* ----- HCI Commands ---- */ 247/* ----- HCI Commands ---- */
248#define HCI_OP_NOP 0x0000
249
247#define HCI_OP_INQUIRY 0x0401 250#define HCI_OP_INQUIRY 0x0401
248struct hci_cp_inquiry { 251struct hci_cp_inquiry {
249 __u8 lap[3]; 252 __u8 lap[3];
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index d30b93c82fd4..ecd2acf24420 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -132,7 +132,6 @@ struct hci_dev {
132 unsigned int sco_pkts; 132 unsigned int sco_pkts;
133 unsigned int le_pkts; 133 unsigned int le_pkts;
134 134
135 unsigned long cmd_last_tx;
136 unsigned long acl_last_tx; 135 unsigned long acl_last_tx;
137 unsigned long sco_last_tx; 136 unsigned long sco_last_tx;
138 unsigned long le_last_tx; 137 unsigned long le_last_tx;
@@ -143,6 +142,7 @@ struct hci_dev {
143 struct work_struct power_off; 142 struct work_struct power_off;
144 struct timer_list off_timer; 143 struct timer_list off_timer;
145 144
145 struct timer_list cmd_timer;
146 struct tasklet_struct cmd_task; 146 struct tasklet_struct cmd_task;
147 struct tasklet_struct rx_task; 147 struct tasklet_struct rx_task;
148 struct tasklet_struct tx_task; 148 struct tasklet_struct tx_task;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index c01415bc8946..702d5651c656 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -41,6 +41,7 @@
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/notifier.h> 42#include <linux/notifier.h>
43#include <linux/rfkill.h> 43#include <linux/rfkill.h>
44#include <linux/timer.h>
44#include <net/sock.h> 45#include <net/sock.h>
45 46
46#include <asm/system.h> 47#include <asm/system.h>
@@ -623,6 +624,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
623 624
624 /* Drop last sent command */ 625 /* Drop last sent command */
625 if (hdev->sent_cmd) { 626 if (hdev->sent_cmd) {
627 del_timer_sync(&hdev->cmd_timer);
626 kfree_skb(hdev->sent_cmd); 628 kfree_skb(hdev->sent_cmd);
627 hdev->sent_cmd = NULL; 629 hdev->sent_cmd = NULL;
628 } 630 }
@@ -1066,6 +1068,16 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
1066 return 0; 1068 return 0;
1067} 1069}
1068 1070
1071/* HCI command timer function */
1072static void hci_cmd_timer(unsigned long arg)
1073{
1074 struct hci_dev *hdev = (void *) arg;
1075
1076 BT_ERR("%s command tx timeout", hdev->name);
1077 atomic_set(&hdev->cmd_cnt, 1);
1078 tasklet_schedule(&hdev->cmd_task);
1079}
1080
1069/* Register HCI device */ 1081/* Register HCI device */
1070int hci_register_dev(struct hci_dev *hdev) 1082int hci_register_dev(struct hci_dev *hdev)
1071{ 1083{
@@ -1112,6 +1124,8 @@ int hci_register_dev(struct hci_dev *hdev)
1112 skb_queue_head_init(&hdev->cmd_q); 1124 skb_queue_head_init(&hdev->cmd_q);
1113 skb_queue_head_init(&hdev->raw_q); 1125 skb_queue_head_init(&hdev->raw_q);
1114 1126
1127 setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);
1128
1115 for (i = 0; i < NUM_REASSEMBLY; i++) 1129 for (i = 0; i < NUM_REASSEMBLY; i++)
1116 hdev->reassembly[i] = NULL; 1130 hdev->reassembly[i] = NULL;
1117 1131
@@ -2004,11 +2018,6 @@ static void hci_cmd_task(unsigned long arg)
2004 2018
2005 BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); 2019 BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
2006 2020
2007 if (!atomic_read(&hdev->cmd_cnt) && time_after(jiffies, hdev->cmd_last_tx + HZ)) {
2008 BT_ERR("%s command tx timeout", hdev->name);
2009 atomic_set(&hdev->cmd_cnt, 1);
2010 }
2011
2012 /* Send queued commands */ 2021 /* Send queued commands */
2013 if (atomic_read(&hdev->cmd_cnt)) { 2022 if (atomic_read(&hdev->cmd_cnt)) {
2014 skb = skb_dequeue(&hdev->cmd_q); 2023 skb = skb_dequeue(&hdev->cmd_q);
@@ -2021,7 +2030,8 @@ static void hci_cmd_task(unsigned long arg)
2021 if (hdev->sent_cmd) { 2030 if (hdev->sent_cmd) {
2022 atomic_dec(&hdev->cmd_cnt); 2031 atomic_dec(&hdev->cmd_cnt);
2023 hci_send_frame(skb); 2032 hci_send_frame(skb);
2024 hdev->cmd_last_tx = jiffies; 2033 mod_timer(&hdev->cmd_timer,
2034 jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
2025 } else { 2035 } else {
2026 skb_queue_head(&hdev->cmd_q, skb); 2036 skb_queue_head(&hdev->cmd_q, skb);
2027 tasklet_schedule(&hdev->cmd_task); 2037 tasklet_schedule(&hdev->cmd_task);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 74f04a27734d..09cb29e8713a 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1732,6 +1732,9 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
1732 break; 1732 break;
1733 } 1733 }
1734 1734
1735 if (ev->opcode != HCI_OP_NOP)
1736 del_timer(&hdev->cmd_timer);
1737
1735 if (ev->ncmd) { 1738 if (ev->ncmd) {
1736 atomic_set(&hdev->cmd_cnt, 1); 1739 atomic_set(&hdev->cmd_cnt, 1);
1737 if (!skb_queue_empty(&hdev->cmd_q)) 1740 if (!skb_queue_empty(&hdev->cmd_q))
@@ -1807,6 +1810,9 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1807 break; 1810 break;
1808 } 1811 }
1809 1812
1813 if (ev->opcode != HCI_OP_NOP)
1814 del_timer(&hdev->cmd_timer);
1815
1810 if (ev->ncmd) { 1816 if (ev->ncmd) {
1811 atomic_set(&hdev->cmd_cnt, 1); 1817 atomic_set(&hdev->cmd_cnt, 1);
1812 if (!skb_queue_empty(&hdev->cmd_q)) 1818 if (!skb_queue_empty(&hdev->cmd_q))