Bluetooth: Convert hci_req_sync family of function to new request API
authorJohan Hedberg <johan.hedberg@intel.com>
Thu, 2 Apr 2015 10:41:09 +0000 (13:41 +0300)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 2 Apr 2015 14:09:27 +0000 (16:09 +0200)
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>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_core.c

index 540c07feece7fa4c19fcfa11e89d389b2087fd84..257ac04c00e16eccf1881c9acb9588a90404c15c 100644 (file)
@@ -334,6 +334,7 @@ struct hci_dev {
        wait_queue_head_t       req_wait_q;
        __u32                   req_status;
        __u32                   req_result;
+       struct sk_buff          *req_skb;
 
        void                    *smp_data;
        void                    *smp_bredr_data;
index 8af3af324eee437e3c0975f709ab3d6b88f24ab9..5cbb0957edc7ebd2ae36d04df1f3a09479935931 100644 (file)
@@ -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;