aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_core.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index cd061510b6bd..406ad07cdea1 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -39,6 +39,7 @@
39#include <linux/skbuff.h> 39#include <linux/skbuff.h>
40#include <linux/interrupt.h> 40#include <linux/interrupt.h>
41#include <linux/notifier.h> 41#include <linux/notifier.h>
42#include <linux/rfkill.h>
42#include <net/sock.h> 43#include <net/sock.h>
43 44
44#include <asm/system.h> 45#include <asm/system.h>
@@ -476,6 +477,11 @@ int hci_dev_open(__u16 dev)
476 477
477 hci_req_lock(hdev); 478 hci_req_lock(hdev);
478 479
480 if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
481 ret = -ERFKILL;
482 goto done;
483 }
484
479 if (test_bit(HCI_UP, &hdev->flags)) { 485 if (test_bit(HCI_UP, &hdev->flags)) {
480 ret = -EALREADY; 486 ret = -EALREADY;
481 goto done; 487 goto done;
@@ -813,6 +819,24 @@ int hci_get_dev_info(void __user *arg)
813 819
814/* ---- Interface to HCI drivers ---- */ 820/* ---- Interface to HCI drivers ---- */
815 821
822static int hci_rfkill_set_block(void *data, bool blocked)
823{
824 struct hci_dev *hdev = data;
825
826 BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
827
828 if (!blocked)
829 return 0;
830
831 hci_dev_do_close(hdev);
832
833 return 0;
834}
835
836static const struct rfkill_ops hci_rfkill_ops = {
837 .set_block = hci_rfkill_set_block,
838};
839
816/* Alloc HCI device */ 840/* Alloc HCI device */
817struct hci_dev *hci_alloc_dev(void) 841struct hci_dev *hci_alloc_dev(void)
818{ 842{
@@ -844,7 +868,8 @@ int hci_register_dev(struct hci_dev *hdev)
844 struct list_head *head = &hci_dev_list, *p; 868 struct list_head *head = &hci_dev_list, *p;
845 int i, id = 0; 869 int i, id = 0;
846 870
847 BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, hdev->type, hdev->owner); 871 BT_DBG("%p name %s type %d owner %p", hdev, hdev->name,
872 hdev->type, hdev->owner);
848 873
849 if (!hdev->open || !hdev->close || !hdev->destruct) 874 if (!hdev->open || !hdev->close || !hdev->destruct)
850 return -EINVAL; 875 return -EINVAL;
@@ -900,6 +925,15 @@ int hci_register_dev(struct hci_dev *hdev)
900 925
901 hci_register_sysfs(hdev); 926 hci_register_sysfs(hdev);
902 927
928 hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
929 RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev);
930 if (hdev->rfkill) {
931 if (rfkill_register(hdev->rfkill) < 0) {
932 rfkill_destroy(hdev->rfkill);
933 hdev->rfkill = NULL;
934 }
935 }
936
903 hci_notify(hdev, HCI_DEV_REG); 937 hci_notify(hdev, HCI_DEV_REG);
904 938
905 return id; 939 return id;
@@ -924,6 +958,11 @@ int hci_unregister_dev(struct hci_dev *hdev)
924 958
925 hci_notify(hdev, HCI_DEV_UNREG); 959 hci_notify(hdev, HCI_DEV_UNREG);
926 960
961 if (hdev->rfkill) {
962 rfkill_unregister(hdev->rfkill);
963 rfkill_destroy(hdev->rfkill);
964 }
965
927 hci_unregister_sysfs(hdev); 966 hci_unregister_sysfs(hdev);
928 967
929 __hci_dev_put(hdev); 968 __hci_dev_put(hdev);