diff options
author | David Herrmann <dh.herrmann@googlemail.com> | 2011-10-08 08:58:49 -0400 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-10-14 14:22:44 -0400 |
commit | 33ca954daf1ac03c86237b73235d8b0856d84981 (patch) | |
tree | 6898afeb560eb56f5ef9442b0ea6dece577e2ea9 /net/bluetooth/hci_core.c | |
parent | ce242970f0934869483221c410d09c00bc8967e7 (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.c | 18 |
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, | |||
1426 | int hci_register_dev(struct hci_dev *hdev) | 1426 | int 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 | ||
1528 | nomem: | 1532 | err_wqueue: |
1533 | destroy_workqueue(hdev->workqueue); | ||
1534 | err: | ||
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 | } |
1535 | EXPORT_SYMBOL(hci_register_dev); | 1541 | EXPORT_SYMBOL(hci_register_dev); |
1536 | 1542 | ||