summaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2013-04-03 21:54:47 +0300
committerJohan Hedberg <johan.hedberg@intel.com>2013-04-04 19:16:10 +0300
commit7b1abbbed0f2a1bc19bb8c0d48a284466043092a (patch)
tree2f79924c7a5dc4c128a9a8c45fa4671c062a0efe /net/bluetooth
parent02350a725f5bc44490c30a10e7e04a12a5ecd406 (diff)
Bluetooth: Add __hci_cmd_sync_ev function
This patch adds a __hci_cmd_sync_ev function, analogous to __hci_cmd_sync except that it also takes an event parameter to indicate that the command completes with a special event instead of command complete. Internally this new function takes advantage of the hci_req_add_ev function introduced in the previous patch. The primary expected user of this new function are the setup routines of HCI drivers which may want to send custom commands and return only when they have completed. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_core.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 7f1413cae2c..9567e32a1f0 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -79,7 +79,7 @@ static void hci_req_cancel(struct hci_dev *hdev, int err)
}
}
-struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode)
+struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 event)
{
struct hci_ev_cmd_complete *ev;
struct hci_event_hdr *hdr;
@@ -103,6 +103,12 @@ struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode)
hdr = (void *) skb->data;
skb_pull(skb, HCI_EVENT_HDR_SIZE);
+ if (event) {
+ if (hdr->evt != event)
+ goto failed;
+ return skb;
+ }
+
if (hdr->evt != HCI_EV_CMD_COMPLETE) {
BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
goto failed;
@@ -127,8 +133,8 @@ failed:
return ERR_PTR(-ENODATA);
}
-struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
- void *param, u32 timeout)
+struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
+ void *param, u8 event, u32 timeout)
{
DECLARE_WAITQUEUE(wait, current);
struct hci_request req;
@@ -138,7 +144,7 @@ struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
hci_req_init(&req, hdev);
- hci_req_add(&req, opcode, plen, param);
+ hci_req_add_ev(&req, opcode, plen, param, event);
hdev->req_status = HCI_REQ_PEND;
@@ -177,7 +183,14 @@ struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
if (err < 0)
return ERR_PTR(err);
- return hci_get_cmd_complete(hdev, opcode);
+ return hci_get_cmd_complete(hdev, opcode, event);
+}
+EXPORT_SYMBOL(__hci_cmd_sync_ev);
+
+struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
+ void *param, u32 timeout)
+{
+ return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
}
EXPORT_SYMBOL(__hci_cmd_sync);