Commit 611b30f7 authored by Marcel Holtmann's avatar Marcel Holtmann

Bluetooth: Add native RFKILL soft-switch support for all devices

With the re-write of the RFKILL subsystem it is now possible to easily
integrate RFKILL soft-switch support into the Bluetooth subsystem. All
Bluetooth devices will now get automatically RFKILL support.
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 092b8585
...@@ -137,6 +137,8 @@ struct hci_dev { ...@@ -137,6 +137,8 @@ struct hci_dev {
struct device *parent; struct device *parent;
struct device dev; struct device dev;
struct rfkill *rfkill;
struct module *owner; struct module *owner;
int (*open)(struct hci_dev *hdev); int (*open)(struct hci_dev *hdev);
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/rfkill.h>
#include <net/sock.h> #include <net/sock.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -476,6 +477,11 @@ int hci_dev_open(__u16 dev) ...@@ -476,6 +477,11 @@ int hci_dev_open(__u16 dev)
hci_req_lock(hdev); hci_req_lock(hdev);
if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
ret = -ERFKILL;
goto done;
}
if (test_bit(HCI_UP, &hdev->flags)) { if (test_bit(HCI_UP, &hdev->flags)) {
ret = -EALREADY; ret = -EALREADY;
goto done; goto done;
...@@ -813,6 +819,24 @@ int hci_get_dev_info(void __user *arg) ...@@ -813,6 +819,24 @@ int hci_get_dev_info(void __user *arg)
/* ---- Interface to HCI drivers ---- */ /* ---- Interface to HCI drivers ---- */
static int hci_rfkill_set_block(void *data, bool blocked)
{
struct hci_dev *hdev = data;
BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
if (!blocked)
return 0;
hci_dev_do_close(hdev);
return 0;
}
static const struct rfkill_ops hci_rfkill_ops = {
.set_block = hci_rfkill_set_block,
};
/* Alloc HCI device */ /* Alloc HCI device */
struct hci_dev *hci_alloc_dev(void) struct hci_dev *hci_alloc_dev(void)
{ {
...@@ -844,7 +868,8 @@ int hci_register_dev(struct hci_dev *hdev) ...@@ -844,7 +868,8 @@ int hci_register_dev(struct hci_dev *hdev)
struct list_head *head = &hci_dev_list, *p; struct list_head *head = &hci_dev_list, *p;
int i, id = 0; int i, id = 0;
BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, hdev->type, hdev->owner); BT_DBG("%p name %s type %d owner %p", hdev, hdev->name,
hdev->type, hdev->owner);
if (!hdev->open || !hdev->close || !hdev->destruct) if (!hdev->open || !hdev->close || !hdev->destruct)
return -EINVAL; return -EINVAL;
...@@ -900,6 +925,15 @@ int hci_register_dev(struct hci_dev *hdev) ...@@ -900,6 +925,15 @@ int hci_register_dev(struct hci_dev *hdev)
hci_register_sysfs(hdev); hci_register_sysfs(hdev);
hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev);
if (hdev->rfkill) {
if (rfkill_register(hdev->rfkill) < 0) {
rfkill_destroy(hdev->rfkill);
hdev->rfkill = NULL;
}
}
hci_notify(hdev, HCI_DEV_REG); hci_notify(hdev, HCI_DEV_REG);
return id; return id;
...@@ -924,6 +958,11 @@ int hci_unregister_dev(struct hci_dev *hdev) ...@@ -924,6 +958,11 @@ int hci_unregister_dev(struct hci_dev *hdev)
hci_notify(hdev, HCI_DEV_UNREG); hci_notify(hdev, HCI_DEV_UNREG);
if (hdev->rfkill) {
rfkill_unregister(hdev->rfkill);
rfkill_destroy(hdev->rfkill);
}
hci_unregister_sysfs(hdev); hci_unregister_sysfs(hdev);
__hci_dev_put(hdev); __hci_dev_put(hdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment