/* ---- 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);
        }
 }
 }
 
 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);
 {
        DECLARE_WAITQUEUE(wait, current);
        struct hci_request req;
+       struct sk_buff *skb;
        int err = 0;
 
        BT_DBG("%s", hdev->name);
        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);
        }
 
        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);
 
        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;