aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJakub Pawlowski <jpawlowski@google.com>2015-03-20 14:14:50 -0400
committerMarcel Holtmann <marcel@holtmann.org>2015-03-20 14:47:01 -0400
commitb55d1abf568cdf12d148ced8b82b217bff824885 (patch)
treeee5b34be828217ec4deb7d0531743eddad208bcc /net
parentdc5d82a9febb28aa9126f9a864eb212317e4ede6 (diff)
Bluetooth: Expose quirks through debugfs
This patch expose controller quirks through debugfs. It would be useful for BlueZ tests using vhci. Currently there is no way to test quirk dependent behaviour. It might be also useful for manual testing. Signed-off-by: Jakub Pawlowski <jpawlowski@google.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_debugfs.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c
index 0818fabf346a..e6255833a258 100644
--- a/net/bluetooth/hci_debugfs.c
+++ b/net/bluetooth/hci_debugfs.c
@@ -28,6 +28,54 @@
28 28
29#include "hci_debugfs.h" 29#include "hci_debugfs.h"
30 30
31#define DEFINE_QUIRK_ATTRIBUTE(__name, __quirk) \
32static ssize_t __name ## _read(struct file *file, \
33 char __user *user_buf, \
34 size_t count, loff_t *ppos) \
35{ \
36 struct hci_dev *hdev = file->private_data; \
37 char buf[3]; \
38 \
39 buf[0] = test_bit(__quirk, &hdev->quirks) ? 'Y' : 'N'; \
40 buf[1] = '\n'; \
41 buf[2] = '\0'; \
42 return simple_read_from_buffer(user_buf, count, ppos, buf, 2); \
43} \
44 \
45static ssize_t __name ## _write(struct file *file, \
46 const char __user *user_buf, \
47 size_t count, loff_t *ppos) \
48{ \
49 struct hci_dev *hdev = file->private_data; \
50 char buf[32]; \
51 size_t buf_size = min(count, (sizeof(buf) - 1)); \
52 bool enable; \
53 \
54 if (test_bit(HCI_UP, &hdev->flags)) \
55 return -EBUSY; \
56 \
57 if (copy_from_user(buf, user_buf, buf_size)) \
58 return -EFAULT; \
59 \
60 buf[buf_size] = '\0'; \
61 if (strtobool(buf, &enable)) \
62 return -EINVAL; \
63 \
64 if (enable == test_bit(__quirk, &hdev->quirks)) \
65 return -EALREADY; \
66 \
67 change_bit(__quirk, &hdev->quirks); \
68 \
69 return count; \
70} \
71 \
72static const struct file_operations __name ## _fops = { \
73 .open = simple_open, \
74 .read = __name ## _read, \
75 .write = __name ## _write, \
76 .llseek = default_llseek, \
77} \
78
31static int features_show(struct seq_file *f, void *ptr) 79static int features_show(struct seq_file *f, void *ptr)
32{ 80{
33 struct hci_dev *hdev = f->private; 81 struct hci_dev *hdev = f->private;
@@ -997,6 +1045,11 @@ static int adv_max_interval_get(void *data, u64 *val)
997DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get, 1045DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get,
998 adv_max_interval_set, "%llu\n"); 1046 adv_max_interval_set, "%llu\n");
999 1047
1048DEFINE_QUIRK_ATTRIBUTE(quirk_strict_duplicate_filter,
1049 HCI_QUIRK_STRICT_DUPLICATE_FILTER);
1050DEFINE_QUIRK_ATTRIBUTE(quirk_simultaneous_discovery,
1051 HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
1052
1000void hci_debugfs_create_le(struct hci_dev *hdev) 1053void hci_debugfs_create_le(struct hci_dev *hdev)
1001{ 1054{
1002 debugfs_create_file("identity", 0400, hdev->debugfs, hdev, 1055 debugfs_create_file("identity", 0400, hdev->debugfs, hdev,
@@ -1041,6 +1094,13 @@ void hci_debugfs_create_le(struct hci_dev *hdev)
1041 &adv_max_interval_fops); 1094 &adv_max_interval_fops);
1042 debugfs_create_u16("discov_interleaved_timeout", 0644, hdev->debugfs, 1095 debugfs_create_u16("discov_interleaved_timeout", 0644, hdev->debugfs,
1043 &hdev->discov_interleaved_timeout); 1096 &hdev->discov_interleaved_timeout);
1097
1098 debugfs_create_file("quirk_strict_duplicate_filter", 0644,
1099 hdev->debugfs, hdev,
1100 &quirk_strict_duplicate_filter_fops);
1101 debugfs_create_file("quirk_simultaneous_discovery", 0644,
1102 hdev->debugfs, hdev,
1103 &quirk_simultaneous_discovery_fops);
1044} 1104}
1045 1105
1046void hci_debugfs_create_conn(struct hci_conn *conn) 1106void hci_debugfs_create_conn(struct hci_conn *conn)