Commit 23bb57633df97ede067ea26f3cdc8a7ba2cd8109

Authored by Johan Hedberg
Committed by Gustavo F. Padovan
1 parent c71e97bfaa

Bluetooth: Fix __hci_request synchronization for hci_open_dev

The initialization function used by hci_open_dev (hci_init_req) sends
many different HCI commands. The __hci_request function should only
return when all of these commands have completed (or a timeout occurs).
Several of these commands cause hci_req_complete to be called which
causes __hci_request to return prematurely.

This patch fixes the issue by adding a new hdev->req_last_cmd variable
which is set during the initialization procedure. The hci_req_complete
function will no longer mark the request as complete until the command
matching hdev->req_last_cmd completes.

Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>

Showing 3 changed files with 37 additions and 14 deletions Side-by-side Diff

include/net/bluetooth/hci_core.h
... ... @@ -129,6 +129,7 @@
129 129 wait_queue_head_t req_wait_q;
130 130 __u32 req_status;
131 131 __u32 req_result;
  132 + __u16 req_last_cmd;
132 133  
133 134 struct inquiry_cache inq_cache;
134 135 struct hci_conn_hash conn_hash;
... ... @@ -693,7 +694,7 @@
693 694 #define hci_req_lock(d) mutex_lock(&d->req_lock)
694 695 #define hci_req_unlock(d) mutex_unlock(&d->req_lock)
695 696  
696   -void hci_req_complete(struct hci_dev *hdev, int result);
  697 +void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result);
697 698  
698 699 #endif /* __HCI_CORE_H */
net/bluetooth/hci_core.c
... ... @@ -91,10 +91,17 @@
91 91  
92 92 /* ---- HCI requests ---- */
93 93  
94   -void hci_req_complete(struct hci_dev *hdev, int result)
  94 +void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
95 95 {
96   - BT_DBG("%s result 0x%2.2x", hdev->name, result);
  96 + BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result);
97 97  
  98 + /* If the request has set req_last_cmd (typical for multi-HCI
  99 + * command requests) check if the completed command matches
  100 + * this, and if not just return. Single HCI command requests
  101 + * typically leave req_last_cmd as 0 */
  102 + if (hdev->req_last_cmd && cmd != hdev->req_last_cmd)
  103 + return;
  104 +
98 105 if (hdev->req_status == HCI_REQ_PEND) {
99 106 hdev->req_result = result;
100 107 hdev->req_status = HCI_REQ_DONE;
... ... @@ -149,7 +156,7 @@
149 156 break;
150 157 }
151 158  
152   - hdev->req_status = hdev->req_result = 0;
  159 + hdev->req_last_cmd = hdev->req_status = hdev->req_result = 0;
153 160  
154 161 BT_DBG("%s end: err %d", hdev->name, err);
155 162  
... ... @@ -252,6 +259,8 @@
252 259 /* Connection accept timeout ~20 secs */
253 260 param = cpu_to_le16(0x7d00);
254 261 hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
  262 +
  263 + hdev->req_last_cmd = HCI_OP_WRITE_CA_TIMEOUT;
255 264 }
256 265  
257 266 static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
net/bluetooth/hci_event.c
... ... @@ -58,7 +58,7 @@
58 58  
59 59 clear_bit(HCI_INQUIRY, &hdev->flags);
60 60  
61   - hci_req_complete(hdev, status);
  61 + hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
62 62  
63 63 hci_conn_check_pending(hdev);
64 64 }
... ... @@ -174,7 +174,7 @@
174 174 if (!status)
175 175 hdev->link_policy = get_unaligned_le16(sent);
176 176  
177   - hci_req_complete(hdev, status);
  177 + hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
178 178 }
179 179  
180 180 static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
... ... @@ -183,7 +183,7 @@
183 183  
184 184 BT_DBG("%s status 0x%x", hdev->name, status);
185 185  
186   - hci_req_complete(hdev, status);
  186 + hci_req_complete(hdev, HCI_OP_RESET, status);
187 187 }
188 188  
189 189 static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
... ... @@ -235,7 +235,7 @@
235 235 clear_bit(HCI_AUTH, &hdev->flags);
236 236 }
237 237  
238   - hci_req_complete(hdev, status);
  238 + hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
239 239 }
240 240  
241 241 static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
... ... @@ -258,7 +258,7 @@
258 258 clear_bit(HCI_ENCRYPT, &hdev->flags);
259 259 }
260 260  
261   - hci_req_complete(hdev, status);
  261 + hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
262 262 }
263 263  
264 264 static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
... ... @@ -285,7 +285,7 @@
285 285 set_bit(HCI_PSCAN, &hdev->flags);
286 286 }
287 287  
288   - hci_req_complete(hdev, status);
  288 + hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
289 289 }
290 290  
291 291 static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
... ... @@ -383,7 +383,7 @@
383 383  
384 384 BT_DBG("%s status 0x%x", hdev->name, status);
385 385  
386   - hci_req_complete(hdev, status);
  386 + hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
387 387 }
388 388  
389 389 static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
390 390  
391 391  
... ... @@ -536,15 +536,24 @@
536 536 if (!rp->status)
537 537 bacpy(&hdev->bdaddr, &rp->bdaddr);
538 538  
539   - hci_req_complete(hdev, rp->status);
  539 + hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
540 540 }
541 541  
  542 +static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
  543 +{
  544 + __u8 status = *((__u8 *) skb->data);
  545 +
  546 + BT_DBG("%s status 0x%x", hdev->name, status);
  547 +
  548 + hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
  549 +}
  550 +
542 551 static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
543 552 {
544 553 BT_DBG("%s status 0x%x", hdev->name, status);
545 554  
546 555 if (status) {
547   - hci_req_complete(hdev, status);
  556 + hci_req_complete(hdev, HCI_OP_INQUIRY, status);
548 557  
549 558 hci_conn_check_pending(hdev);
550 559 } else
... ... @@ -871,7 +880,7 @@
871 880  
872 881 clear_bit(HCI_INQUIRY, &hdev->flags);
873 882  
874   - hci_req_complete(hdev, status);
  883 + hci_req_complete(hdev, HCI_OP_INQUIRY, status);
875 884  
876 885 hci_conn_check_pending(hdev);
877 886 }
... ... @@ -1377,6 +1386,10 @@
1377 1386  
1378 1387 case HCI_OP_READ_BD_ADDR:
1379 1388 hci_cc_read_bd_addr(hdev, skb);
  1389 + break;
  1390 +
  1391 + case HCI_OP_WRITE_CA_TIMEOUT:
  1392 + hci_cc_write_ca_timeout(hdev, skb);
1380 1393 break;
1381 1394  
1382 1395 default: