summaryrefslogtreecommitdiff
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2015-04-02 13:41:09 +0300
committerMarcel Holtmann <marcel@holtmann.org>2015-04-02 16:09:27 +0200
commitf60cb30579d3401cab1ed36b42df5c0568ae0ba7 (patch)
tree27f3b73ea066bb1053857cbee1c5c938c2564fd1 /net/bluetooth
parente6214487492566b15ff24e97c6747bb2e5d9e040 (diff)
downloadlinux-f60cb30579d3401cab1ed36b42df5c0568ae0ba7.tar.gz
Bluetooth: Convert hci_req_sync family of function to new request API
Now that there's an API in place that allows passing the resulting skb to the request callback we can conveniently convert the hci_req_sync and related functions to use it. Since we still need to get the skb from the async callback into the sleeping _sync() function the patch adds another req_skb variable to hci_dev where the sync request state is tracked. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_core.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8af3af324eee..5cbb0957edc7 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -141,13 +141,16 @@ static const struct file_operations dut_mode_fops = {
/* ---- HCI requests ---- */
-static void hci_req_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode)
+static void hci_req_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode,
+ struct sk_buff *skb)
{
BT_DBG("%s result 0x%2.2x", hdev->name, result);
if (hdev->req_status == HCI_REQ_PEND) {
hdev->req_result = result;
hdev->req_status = HCI_REQ_DONE;
+ if (skb)
+ hdev->req_skb = skb_get(skb);
wake_up_interruptible(&hdev->req_wait_q);
}
}
@@ -164,18 +167,10 @@ static void hci_req_cancel(struct hci_dev *hdev, int err)
}
static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
- u8 event)
+ u8 event, struct sk_buff *skb)
{
struct hci_ev_cmd_complete *ev;
struct hci_event_hdr *hdr;
- struct sk_buff *skb;
-
- hci_dev_lock(hdev);
-
- skb = hdev->recv_evt;
- hdev->recv_evt = NULL;
-
- hci_dev_unlock(hdev);
if (!skb)
return ERR_PTR(-ENODATA);
@@ -223,6 +218,7 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
{
DECLARE_WAITQUEUE(wait, current);
struct hci_request req;
+ struct sk_buff *skb;
int err = 0;
BT_DBG("%s", hdev->name);
@@ -236,7 +232,7 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
add_wait_queue(&hdev->req_wait_q, &wait);
set_current_state(TASK_INTERRUPTIBLE);
- err = hci_req_run(&req, hci_req_sync_complete);
+ err = hci_req_run_skb(&req, hci_req_sync_complete);
if (err < 0) {
remove_wait_queue(&hdev->req_wait_q, &wait);
set_current_state(TASK_RUNNING);
@@ -265,13 +261,17 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
}
hdev->req_status = hdev->req_result = 0;
+ skb = hdev->req_skb;
+ hdev->req_skb = NULL;
BT_DBG("%s end: err %d", hdev->name, err);
- if (err < 0)
+ if (err < 0) {
+ kfree_skb(skb);
return ERR_PTR(err);
+ }
- return hci_get_cmd_complete(hdev, opcode, event);
+ return hci_get_cmd_complete(hdev, opcode, event, skb);
}
EXPORT_SYMBOL(__hci_cmd_sync_ev);
@@ -303,7 +303,7 @@ static int __hci_req_sync(struct hci_dev *hdev,
add_wait_queue(&hdev->req_wait_q, &wait);
set_current_state(TASK_INTERRUPTIBLE);
- err = hci_req_run(&req, hci_req_sync_complete);
+ err = hci_req_run_skb(&req, hci_req_sync_complete);
if (err < 0) {
hdev->req_status = 0;