aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2011-01-10 06:28:59 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-02-07 22:40:06 -0500
commita5040efa2017f3e4f1b4d5f40fd989567f3994c1 (patch)
tree451984186e4504665bff2ed0b74a9510a0d32d13
parent03b555e119de8288a16e086e1fbd223d9b429d3d (diff)
Bluetooth: Add special handling with __hci_request and HCI_INIT
To support a more dynamic HCI initialization sequence the __hci_request behavior requires some more changes. Particularly, the init sequence should be able to have conditionals in it (sending some HCI commands depending on the outcome of a previous command) instead of being a fixed list as it is right now. The reasons for these additional requirements are the moving all previously user space driven initialization commands to the kernel side as well as the support the Low Energy controllers. To fulfull these requirements the init sequence is made the only special case for multi-command requests and req_last_cmd is renamed to init_last_cmd. The hci_send_cmd function is changed to update init_last_cmd as long as the HCI_INIT flag is set. Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r--include/net/bluetooth/hci_core.h3
-rw-r--r--net/bluetooth/hci_core.c17
2 files changed, 11 insertions, 9 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index dc8084a139ed..0dbdcc5f44e4 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -139,7 +139,8 @@ struct hci_dev {
139 wait_queue_head_t req_wait_q; 139 wait_queue_head_t req_wait_q;
140 __u32 req_status; 140 __u32 req_status;
141 __u32 req_result; 141 __u32 req_result;
142 __u16 req_last_cmd; 142
143 __u16 init_last_cmd;
143 144
144 struct inquiry_cache inq_cache; 145 struct inquiry_cache inq_cache;
145 struct hci_conn_hash conn_hash; 146 struct hci_conn_hash conn_hash;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b99248d4a5b2..183ce81f7a5c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -97,11 +97,10 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
97{ 97{
98 BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result); 98 BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result);
99 99
100 /* If the request has set req_last_cmd (typical for multi-HCI 100 /* If this is the init phase check if the completed command matches
101 * command requests) check if the completed command matches 101 * the last init command, and if not just return.
102 * this, and if not just return. Single HCI command requests 102 */
103 * typically leave req_last_cmd as 0 */ 103 if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd)
104 if (hdev->req_last_cmd && cmd != hdev->req_last_cmd)
105 return; 104 return;
106 105
107 if (hdev->req_status == HCI_REQ_PEND) { 106 if (hdev->req_status == HCI_REQ_PEND) {
@@ -158,7 +157,7 @@ static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev,
158 break; 157 break;
159 } 158 }
160 159
161 hdev->req_last_cmd = hdev->req_status = hdev->req_result = 0; 160 hdev->req_status = hdev->req_result = 0;
162 161
163 BT_DBG("%s end: err %d", hdev->name, err); 162 BT_DBG("%s end: err %d", hdev->name, err);
164 163
@@ -261,8 +260,6 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
261 /* Connection accept timeout ~20 secs */ 260 /* Connection accept timeout ~20 secs */
262 param = cpu_to_le16(0x7d00); 261 param = cpu_to_le16(0x7d00);
263 hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param); 262 hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
264
265 hdev->req_last_cmd = HCI_OP_WRITE_CA_TIMEOUT;
266} 263}
267 264
268static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) 265static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
@@ -523,6 +520,7 @@ int hci_dev_open(__u16 dev)
523 if (!test_bit(HCI_RAW, &hdev->flags)) { 520 if (!test_bit(HCI_RAW, &hdev->flags)) {
524 atomic_set(&hdev->cmd_cnt, 1); 521 atomic_set(&hdev->cmd_cnt, 1);
525 set_bit(HCI_INIT, &hdev->flags); 522 set_bit(HCI_INIT, &hdev->flags);
523 hdev->init_last_cmd = 0;
526 524
527 //__hci_request(hdev, hci_reset_req, 0, HZ); 525 //__hci_request(hdev, hci_reset_req, 0, HZ);
528 ret = __hci_request(hdev, hci_init_req, 0, 526 ret = __hci_request(hdev, hci_init_req, 0,
@@ -1442,6 +1440,9 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
1442 bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; 1440 bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
1443 skb->dev = (void *) hdev; 1441 skb->dev = (void *) hdev;
1444 1442
1443 if (test_bit(HCI_INIT, &hdev->flags))
1444 hdev->init_last_cmd = opcode;
1445
1445 skb_queue_tail(&hdev->cmd_q, skb); 1446 skb_queue_tail(&hdev->cmd_q, skb);
1446 tasklet_schedule(&hdev->cmd_task); 1447 tasklet_schedule(&hdev->cmd_task);
1447 1448