diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 3418d7b964a1..62469dba9e63 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1466,7 +1466,7 @@ static void hci_cmd_timeout(struct work_struct *work) if (hdev->req_skb) { u16 opcode = hci_skb_opcode(hdev->req_skb); - bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode); + bt_dev_err(hdev, "command 0x%4.4x skb: %p tx timeout", opcode, hdev->req_skb); hci_cmd_sync_cancel_sync(hdev, ETIMEDOUT); } else { diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index 6e76798ec786..cfa3e799a212 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -133,6 +133,8 @@ static int hci_req_sync_run(struct hci_request *req) return -ENODATA; skb = skb_peek_tail(&req->cmd_q); + printk("status: %u, result: %u, skb: %p, %s\n", + hdev->req_status, hdev->req_result, skb, __func__); bt_cb(skb)->hci.req_complete_skb = hci_cmd_sync_complete; bt_cb(skb)->hci.req_flags |= HCI_REQ_SKB; @@ -160,6 +162,7 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen, struct hci_request req; struct sk_buff *skb; int err = 0; + unsigned long flags; bt_dev_dbg(hdev, "Opcode 0x%4.4x", opcode); @@ -201,18 +204,33 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen, bt_dev_dbg(hdev, "end: err %d", err); + printk("err: %d, status: %u, result: %u, skb: %p, %s\n", + err, hdev->req_status, hdev->req_result, skb, __func__); if (err < 0) { kfree_skb(skb); - return ERR_PTR(err); + + goto out; } /* If command return a status event skb will be set to NULL as there are * no parameters. */ - if (!skb) - return ERR_PTR(-ENODATA); + if (!skb) { + err = -ENODATA; + goto out; + } return skb; + +out: + spin_lock_irqsave(&hdev->cmd_q.lock, flags); + skb = __skb_dequeue_tail(&hdev->cmd_q); + spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); + printk("remove skb: %p, %s\n", skb, __func__); + kfree_skb(skb); + + return ERR_PTR(err); + } EXPORT_SYMBOL(__hci_cmd_sync_sk);