aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/bluetooth.h1
-rw-r--r--include/net/bluetooth/hci_core.h2
-rw-r--r--net/bluetooth/hci_core.c10
-rw-r--r--net/bluetooth/hci_event.c11
4 files changed, 22 insertions, 2 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index ed6e9552252e..591fee7d0060 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -266,6 +266,7 @@ typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status);
266 266
267struct hci_req_ctrl { 267struct hci_req_ctrl {
268 bool start; 268 bool start;
269 u8 event;
269 hci_req_complete_t complete; 270 hci_req_complete_t complete;
270}; 271};
271 272
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 755743d508aa..b85eefb230fd 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1055,6 +1055,8 @@ struct hci_request {
1055void hci_req_init(struct hci_request *req, struct hci_dev *hdev); 1055void hci_req_init(struct hci_request *req, struct hci_dev *hdev);
1056int hci_req_run(struct hci_request *req, hci_req_complete_t complete); 1056int hci_req_run(struct hci_request *req, hci_req_complete_t complete);
1057void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param); 1057void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param);
1058void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, void *param,
1059 u8 event);
1058void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); 1060void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status);
1059 1061
1060struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 1062struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8b2d543fb143..7f1413cae2cb 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2645,7 +2645,8 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
2645} 2645}
2646 2646
2647/* Queue a command to an asynchronous HCI request */ 2647/* Queue a command to an asynchronous HCI request */
2648void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param) 2648void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, void *param,
2649 u8 event)
2649{ 2650{
2650 struct hci_dev *hdev = req->hdev; 2651 struct hci_dev *hdev = req->hdev;
2651 struct sk_buff *skb; 2652 struct sk_buff *skb;
@@ -2669,9 +2670,16 @@ void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param)
2669 if (skb_queue_empty(&req->cmd_q)) 2670 if (skb_queue_empty(&req->cmd_q))
2670 bt_cb(skb)->req.start = true; 2671 bt_cb(skb)->req.start = true;
2671 2672
2673 bt_cb(skb)->req.event = event;
2674
2672 skb_queue_tail(&req->cmd_q, skb); 2675 skb_queue_tail(&req->cmd_q, skb);
2673} 2676}
2674 2677
2678void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param)
2679{
2680 hci_req_add_ev(req, opcode, plen, param, 0);
2681}
2682
2675/* Get data from the previously sent command */ 2683/* Get data from the previously sent command */
2676void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) 2684void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
2677{ 2685{
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index ed0efb7255b0..0a2b128d2cc9 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2463,7 +2463,9 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2463 if (opcode != HCI_OP_NOP) 2463 if (opcode != HCI_OP_NOP)
2464 del_timer(&hdev->cmd_timer); 2464 del_timer(&hdev->cmd_timer);
2465 2465
2466 hci_req_cmd_complete(hdev, opcode, ev->status); 2466 if (ev->status ||
2467 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2468 hci_req_cmd_complete(hdev, opcode, ev->status);
2467 2469
2468 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { 2470 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
2469 atomic_set(&hdev->cmd_cnt, 1); 2471 atomic_set(&hdev->cmd_cnt, 1);
@@ -3713,6 +3715,13 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3713 3715
3714 skb_pull(skb, HCI_EVENT_HDR_SIZE); 3716 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3715 3717
3718 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
3719 struct hci_command_hdr *hdr = (void *) hdev->sent_cmd->data;
3720 u16 opcode = __le16_to_cpu(hdr->opcode);
3721
3722 hci_req_cmd_complete(hdev, opcode, 0);
3723 }
3724
3716 switch (event) { 3725 switch (event) {
3717 case HCI_EV_INQUIRY_COMPLETE: 3726 case HCI_EV_INQUIRY_COMPLETE:
3718 hci_inquiry_complete_evt(hdev, skb); 3727 hci_inquiry_complete_evt(hdev, skb);