aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_event.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2013-04-03 14:50:29 -0400
committerJohan Hedberg <johan.hedberg@intel.com>2013-04-04 12:16:08 -0400
commit02350a725f5bc44490c30a10e7e04a12a5ecd406 (patch)
tree243d09f74edf36d79d50db5d470d340c733f38b1 /net/bluetooth/hci_event.c
parent75e84b7c522c6e07964cd1f5bf28535768a1e9fa (diff)
Bluetooth: Add support for custom event terminated commands
This patch adds support for having commands within HCI requests that do not result in a command complete but some other event. This is at least needed for some vendor specific commands to be issued in the hdev->setup() procecure, but might also be useful for other commands. The way that the support is implemented is by extending the skb control buffer to have a field to indicate that the command is expected to terminate with a special event. After sending the command each received event can then be compared against this field through hdev->sent_cmd. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r--net/bluetooth/hci_event.c11
1 files changed, 10 insertions, 1 deletions
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);