Merge branches 'bugzilla-14668' and 'misc-2.6.35' into release
[linux-drm-fsl-dcu.git] / net / bluetooth / hci_core.c
index 4ad23192c7a52dfd5ce76734c12d6541b8295c5d..2f768de8701178091008cca90346647790fe6706 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/fcntl.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
+#include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/notifier.h>
 #include <linux/rfkill.h>
@@ -928,6 +929,10 @@ int hci_register_dev(struct hci_dev *hdev)
 
        write_unlock_bh(&hci_dev_list_lock);
 
+       hdev->workqueue = create_singlethread_workqueue(hdev->name);
+       if (!hdev->workqueue)
+               goto nomem;
+
        hci_register_sysfs(hdev);
 
        hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
@@ -942,6 +947,13 @@ int hci_register_dev(struct hci_dev *hdev)
        hci_notify(hdev, HCI_DEV_REG);
 
        return id;
+
+nomem:
+       write_lock_bh(&hci_dev_list_lock);
+       list_del(&hdev->list);
+       write_unlock_bh(&hci_dev_list_lock);
+
+       return -ENOMEM;
 }
 EXPORT_SYMBOL(hci_register_dev);
 
@@ -970,6 +982,8 @@ int hci_unregister_dev(struct hci_dev *hdev)
 
        hci_unregister_sysfs(hdev);
 
+       destroy_workqueue(hdev->workqueue);
+
        __hci_dev_put(hdev);
 
        return 0;
@@ -1260,7 +1274,7 @@ static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
        hdr->dlen   = cpu_to_le16(len);
 }
 
-int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
+void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
 {
        struct hci_dev *hdev = conn->hdev;
        struct sk_buff *list;
@@ -1302,24 +1316,17 @@ int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
        }
 
        tasklet_schedule(&hdev->tx_task);
-
-       return 0;
 }
 EXPORT_SYMBOL(hci_send_acl);
 
 /* Send SCO data */
-int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
+void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
 {
        struct hci_dev *hdev = conn->hdev;
        struct hci_sco_hdr hdr;
 
        BT_DBG("%s len %d", hdev->name, skb->len);
 
-       if (skb->len > hdev->sco_mtu) {
-               kfree_skb(skb);
-               return -EINVAL;
-       }
-
        hdr.handle = cpu_to_le16(conn->handle);
        hdr.dlen   = skb->len;
 
@@ -1332,8 +1339,6 @@ int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
 
        skb_queue_tail(&conn->data_q, skb);
        tasklet_schedule(&hdev->tx_task);
-
-       return 0;
 }
 EXPORT_SYMBOL(hci_send_sco);