aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/hci_core.c')
-rw-r--r--net/bluetooth/hci_core.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 4ad23192c7a5..2f768de87011 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -37,6 +37,7 @@
37#include <linux/fcntl.h> 37#include <linux/fcntl.h>
38#include <linux/init.h> 38#include <linux/init.h>
39#include <linux/skbuff.h> 39#include <linux/skbuff.h>
40#include <linux/workqueue.h>
40#include <linux/interrupt.h> 41#include <linux/interrupt.h>
41#include <linux/notifier.h> 42#include <linux/notifier.h>
42#include <linux/rfkill.h> 43#include <linux/rfkill.h>
@@ -928,6 +929,10 @@ int hci_register_dev(struct hci_dev *hdev)
928 929
929 write_unlock_bh(&hci_dev_list_lock); 930 write_unlock_bh(&hci_dev_list_lock);
930 931
932 hdev->workqueue = create_singlethread_workqueue(hdev->name);
933 if (!hdev->workqueue)
934 goto nomem;
935
931 hci_register_sysfs(hdev); 936 hci_register_sysfs(hdev);
932 937
933 hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 938 hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
@@ -942,6 +947,13 @@ int hci_register_dev(struct hci_dev *hdev)
942 hci_notify(hdev, HCI_DEV_REG); 947 hci_notify(hdev, HCI_DEV_REG);
943 948
944 return id; 949 return id;
950
951nomem:
952 write_lock_bh(&hci_dev_list_lock);
953 list_del(&hdev->list);
954 write_unlock_bh(&hci_dev_list_lock);
955
956 return -ENOMEM;
945} 957}
946EXPORT_SYMBOL(hci_register_dev); 958EXPORT_SYMBOL(hci_register_dev);
947 959
@@ -970,6 +982,8 @@ int hci_unregister_dev(struct hci_dev *hdev)
970 982
971 hci_unregister_sysfs(hdev); 983 hci_unregister_sysfs(hdev);
972 984
985 destroy_workqueue(hdev->workqueue);
986
973 __hci_dev_put(hdev); 987 __hci_dev_put(hdev);
974 988
975 return 0; 989 return 0;
@@ -1260,7 +1274,7 @@ static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
1260 hdr->dlen = cpu_to_le16(len); 1274 hdr->dlen = cpu_to_le16(len);
1261} 1275}
1262 1276
1263int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags) 1277void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
1264{ 1278{
1265 struct hci_dev *hdev = conn->hdev; 1279 struct hci_dev *hdev = conn->hdev;
1266 struct sk_buff *list; 1280 struct sk_buff *list;
@@ -1302,24 +1316,17 @@ int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
1302 } 1316 }
1303 1317
1304 tasklet_schedule(&hdev->tx_task); 1318 tasklet_schedule(&hdev->tx_task);
1305
1306 return 0;
1307} 1319}
1308EXPORT_SYMBOL(hci_send_acl); 1320EXPORT_SYMBOL(hci_send_acl);
1309 1321
1310/* Send SCO data */ 1322/* Send SCO data */
1311int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 1323void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
1312{ 1324{
1313 struct hci_dev *hdev = conn->hdev; 1325 struct hci_dev *hdev = conn->hdev;
1314 struct hci_sco_hdr hdr; 1326 struct hci_sco_hdr hdr;
1315 1327
1316 BT_DBG("%s len %d", hdev->name, skb->len); 1328 BT_DBG("%s len %d", hdev->name, skb->len);
1317 1329
1318 if (skb->len > hdev->sco_mtu) {
1319 kfree_skb(skb);
1320 return -EINVAL;
1321 }
1322
1323 hdr.handle = cpu_to_le16(conn->handle); 1330 hdr.handle = cpu_to_le16(conn->handle);
1324 hdr.dlen = skb->len; 1331 hdr.dlen = skb->len;
1325 1332
@@ -1332,8 +1339,6 @@ int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
1332 1339
1333 skb_queue_tail(&conn->data_q, skb); 1340 skb_queue_tail(&conn->data_q, skb);
1334 tasklet_schedule(&hdev->tx_task); 1341 tasklet_schedule(&hdev->tx_task);
1335
1336 return 0;
1337} 1342}
1338EXPORT_SYMBOL(hci_send_sco); 1343EXPORT_SYMBOL(hci_send_sco);
1339 1344