diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index 6e76798ec786..f3898f8b007e 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -173,6 +173,8 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen, if (err < 0) return ERR_PTR(err); + skb = skb_peek_tail(&req.cmd_q); +retry: err = wait_event_interruptible_timeout(hdev->req_wait_q, hdev->req_status != HCI_REQ_PEND, timeout); @@ -186,6 +188,11 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen, break; case HCI_REQ_CANCELED: + if (!skb_queue_empty(&hdev->cmd_q) && hdev->req_skb != skb) { + atomic_set(&hdev->cmd_cnt, 1); + queue_work(hdev->workqueue, &hdev->cmd_work); + goto retry; + } err = -hdev->req_result; break; diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 2fef08254d78..2e12615f539e 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -75,6 +75,10 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { struct vhci_data *data = hci_get_drvdata(hdev); + printk("skb: %p refcnt: %u, data inited: %d, %s\n", + skb, refcount_read(&skb->users), + atomic_read(&data->initialized), + __func__); memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1); skb_queue_tail(&data->readq, skb); @@ -587,6 +591,8 @@ static ssize_t vhci_read(struct file *file, skb = skb_dequeue(&data->readq); if (skb) { ret = vhci_put_user(data, skb, buf, count); + printk("skb: %p refcnt: %u len: %u, data: %p, ret: %ld, count: %lu, %s\n", + skb, refcount_read(&skb->users), skb->len, skb->data, ret, count, __func__); if (ret < 0) skb_queue_head(&data->readq, skb); else