diff -rU 6 linux.source.2.6.15-orig/drivers/bluetooth/hci_usb.c linux.source.2.6.15/drivers/bluetooth/hci_usb.c --- linux.source.2.6.15-orig/drivers/bluetooth/hci_usb.c 2006-05-02 01:01:55.000000000 -0400 +++ linux.source.2.6.15/drivers/bluetooth/hci_usb.c 2006-10-14 10:43:59.000000000 -0400 @@ -771,23 +771,49 @@ _urb->type, err); unlock: read_unlock(&husb->completion_lock); } +static inline int __sco_notify(struct hci_dev *hdev, void *handlep) +{ + struct sk_buff *skb; + unsigned char *p; + static const unsigned char data[] = {0x13, 0x05, 0x01, 0x00, 0x00, 0x01, 0x00}; + + skb = bt_skb_alloc(sizeof data, GFP_ATOMIC); + if (!skb) { + BT_ERR("%s no memory for the packet", hdev->name); + return -ENOMEM; + } + skb->dev = (void *) hdev; + + BT_DBG("sco_notify handle: %x", *((__le16 *) handlep)); + /* add handle to data */ + p = skb_put(skb, sizeof(data)); + memcpy(p, data, sizeof(data)); + memcpy(p+3, handlep, sizeof(__le16)); + + bt_cb(skb)->pkt_type = HCI_EVENT_PKT; + hci_recv_frame(skb); + return 0; +} + static void hci_usb_tx_complete(struct urb *urb, struct pt_regs *regs) { struct _urb *_urb = container_of(urb, struct _urb, urb); struct hci_usb *husb = (void *) urb->context; struct hci_dev *hdev = husb->hdev; BT_DBG("%s urb %p status %d flags %x", hdev->name, urb, urb->status, urb->transfer_flags); atomic_dec(__pending_tx(husb, _urb->type)); + if (_urb->type == HCI_SCODATA_PKT) + __sco_notify(hdev, ((struct sk_buff *)_urb->priv)->data); urb->transfer_buffer = NULL; kfree_skb((struct sk_buff *) _urb->priv); if (!test_bit(HCI_RUNNING, &hdev->flags)) return; diff -rU 6 linux.source.2.6.15-orig/net/bluetooth/hci_core.c linux.source.2.6.15/net/bluetooth/hci_core.c --- linux.source.2.6.15-orig/net/bluetooth/hci_core.c 2006-10-14 10:30:52.000000000 -0400 +++ linux.source.2.6.15/net/bluetooth/hci_core.c 2006-10-14 10:44:18.000000000 -0400 @@ -1242,14 +1242,13 @@ while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { BT_DBG("skb %p len %d", skb, skb->len); hci_send_frame(skb); conn->sent++; - if (conn->sent == ~0) - conn->sent = 0; + hdev->sco_cnt--; } } } static void hci_tx_task(unsigned long arg) {