aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_core.c
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2011-10-08 08:58:49 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-10-14 14:22:44 -0400
commit33ca954daf1ac03c86237b73235d8b0856d84981 (patch)
tree6898afeb560eb56f5ef9442b0ea6dece577e2ea9 /net/bluetooth/hci_core.c
parentce242970f0934869483221c410d09c00bc8967e7 (diff)
Bluetooth: Forward errors from hci_register_dev
We need to catch errors when calling hci_add_sysfs() and return them to the caller to avoid kernel oopses on device_add() failure. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/hci_core.c')
-rw-r--r--net/bluetooth/hci_core.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 49755785a680..fdcbf8fc26ad 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1426,7 +1426,7 @@ int hci_add_adv_entry(struct hci_dev *hdev,
1426int hci_register_dev(struct hci_dev *hdev) 1426int hci_register_dev(struct hci_dev *hdev)
1427{ 1427{
1428 struct list_head *head = &hci_dev_list, *p; 1428 struct list_head *head = &hci_dev_list, *p;
1429 int i, id = 0; 1429 int i, id = 0, error;
1430 1430
1431 BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name, 1431 BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name,
1432 hdev->bus, hdev->owner); 1432 hdev->bus, hdev->owner);
@@ -1503,10 +1503,14 @@ int hci_register_dev(struct hci_dev *hdev)
1503 write_unlock_bh(&hci_dev_list_lock); 1503 write_unlock_bh(&hci_dev_list_lock);
1504 1504
1505 hdev->workqueue = create_singlethread_workqueue(hdev->name); 1505 hdev->workqueue = create_singlethread_workqueue(hdev->name);
1506 if (!hdev->workqueue) 1506 if (!hdev->workqueue) {
1507 goto nomem; 1507 error = -ENOMEM;
1508 goto err;
1509 }
1508 1510
1509 hci_add_sysfs(hdev); 1511 error = hci_add_sysfs(hdev);
1512 if (error < 0)
1513 goto err_wqueue;
1510 1514
1511 hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, 1515 hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1512 RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); 1516 RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev);
@@ -1525,12 +1529,14 @@ int hci_register_dev(struct hci_dev *hdev)
1525 1529
1526 return id; 1530 return id;
1527 1531
1528nomem: 1532err_wqueue:
1533 destroy_workqueue(hdev->workqueue);
1534err:
1529 write_lock_bh(&hci_dev_list_lock); 1535 write_lock_bh(&hci_dev_list_lock);
1530 list_del(&hdev->list); 1536 list_del(&hdev->list);
1531 write_unlock_bh(&hci_dev_list_lock); 1537 write_unlock_bh(&hci_dev_list_lock);
1532 1538
1533 return -ENOMEM; 1539 return error;
1534} 1540}
1535EXPORT_SYMBOL(hci_register_dev); 1541EXPORT_SYMBOL(hci_register_dev);
1536 1542