aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_debugfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/hci_debugfs.c')
-rw-r--r--net/bluetooth/hci_debugfs.c98
1 files changed, 92 insertions, 6 deletions
diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c
index 65261e5d4b84..7db4220941cc 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;
@@ -66,6 +114,30 @@ static const struct file_operations features_fops = {
66 .release = single_release, 114 .release = single_release,
67}; 115};
68 116
117static int device_id_show(struct seq_file *f, void *ptr)
118{
119 struct hci_dev *hdev = f->private;
120
121 hci_dev_lock(hdev);
122 seq_printf(f, "%4.4x:%4.4x:%4.4x:%4.4x\n", hdev->devid_source,
123 hdev->devid_vendor, hdev->devid_product, hdev->devid_version);
124 hci_dev_unlock(hdev);
125
126 return 0;
127}
128
129static int device_id_open(struct inode *inode, struct file *file)
130{
131 return single_open(file, device_id_show, inode->i_private);
132}
133
134static const struct file_operations device_id_fops = {
135 .open = device_id_open,
136 .read = seq_read,
137 .llseek = seq_lseek,
138 .release = single_release,
139};
140
69static int device_list_show(struct seq_file *f, void *ptr) 141static int device_list_show(struct seq_file *f, void *ptr)
70{ 142{
71 struct hci_dev *hdev = f->private; 143 struct hci_dev *hdev = f->private;
@@ -166,7 +238,7 @@ static int remote_oob_show(struct seq_file *f, void *ptr)
166 seq_printf(f, "%pMR (type %u) %u %*phN %*phN %*phN %*phN\n", 238 seq_printf(f, "%pMR (type %u) %u %*phN %*phN %*phN %*phN\n",
167 &data->bdaddr, data->bdaddr_type, data->present, 239 &data->bdaddr, data->bdaddr_type, data->present,
168 16, data->hash192, 16, data->rand192, 240 16, data->hash192, 16, data->rand192,
169 16, data->hash256, 19, data->rand256); 241 16, data->hash256, 16, data->rand256);
170 } 242 }
171 hci_dev_unlock(hdev); 243 hci_dev_unlock(hdev);
172 244
@@ -247,7 +319,7 @@ static ssize_t use_debug_keys_read(struct file *file, char __user *user_buf,
247 struct hci_dev *hdev = file->private_data; 319 struct hci_dev *hdev = file->private_data;
248 char buf[3]; 320 char buf[3];
249 321
250 buf[0] = test_bit(HCI_USE_DEBUG_KEYS, &hdev->dev_flags) ? 'Y': 'N'; 322 buf[0] = hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS) ? 'Y': 'N';
251 buf[1] = '\n'; 323 buf[1] = '\n';
252 buf[2] = '\0'; 324 buf[2] = '\0';
253 return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 325 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
@@ -265,7 +337,7 @@ static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
265 struct hci_dev *hdev = file->private_data; 337 struct hci_dev *hdev = file->private_data;
266 char buf[3]; 338 char buf[3];
267 339
268 buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N'; 340 buf[0] = hci_dev_test_flag(hdev, HCI_SC_ONLY) ? 'Y': 'N';
269 buf[1] = '\n'; 341 buf[1] = '\n';
270 buf[2] = '\0'; 342 buf[2] = '\0';
271 return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 343 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
@@ -287,6 +359,8 @@ void hci_debugfs_create_common(struct hci_dev *hdev)
287 debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); 359 debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
288 debugfs_create_u8("hardware_error", 0444, hdev->debugfs, 360 debugfs_create_u8("hardware_error", 0444, hdev->debugfs,
289 &hdev->hw_error_code); 361 &hdev->hw_error_code);
362 debugfs_create_file("device_id", 0444, hdev->debugfs, hdev,
363 &device_id_fops);
290 364
291 debugfs_create_file("device_list", 0444, hdev->debugfs, hdev, 365 debugfs_create_file("device_list", 0444, hdev->debugfs, hdev,
292 &device_list_fops); 366 &device_list_fops);
@@ -679,7 +753,7 @@ static ssize_t force_static_address_read(struct file *file,
679 struct hci_dev *hdev = file->private_data; 753 struct hci_dev *hdev = file->private_data;
680 char buf[3]; 754 char buf[3];
681 755
682 buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ? 'Y': 'N'; 756 buf[0] = hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ? 'Y': 'N';
683 buf[1] = '\n'; 757 buf[1] = '\n';
684 buf[2] = '\0'; 758 buf[2] = '\0';
685 return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 759 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
@@ -704,10 +778,10 @@ static ssize_t force_static_address_write(struct file *file,
704 if (strtobool(buf, &enable)) 778 if (strtobool(buf, &enable))
705 return -EINVAL; 779 return -EINVAL;
706 780
707 if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags)) 781 if (enable == hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR))
708 return -EALREADY; 782 return -EALREADY;
709 783
710 change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags); 784 hci_dev_change_flag(hdev, HCI_FORCE_STATIC_ADDR);
711 785
712 return count; 786 return count;
713} 787}
@@ -997,6 +1071,11 @@ static int adv_max_interval_get(void *data, u64 *val)
997DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get, 1071DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get,
998 adv_max_interval_set, "%llu\n"); 1072 adv_max_interval_set, "%llu\n");
999 1073
1074DEFINE_QUIRK_ATTRIBUTE(quirk_strict_duplicate_filter,
1075 HCI_QUIRK_STRICT_DUPLICATE_FILTER);
1076DEFINE_QUIRK_ATTRIBUTE(quirk_simultaneous_discovery,
1077 HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
1078
1000void hci_debugfs_create_le(struct hci_dev *hdev) 1079void hci_debugfs_create_le(struct hci_dev *hdev)
1001{ 1080{
1002 debugfs_create_file("identity", 0400, hdev->debugfs, hdev, 1081 debugfs_create_file("identity", 0400, hdev->debugfs, hdev,
@@ -1041,6 +1120,13 @@ void hci_debugfs_create_le(struct hci_dev *hdev)
1041 &adv_max_interval_fops); 1120 &adv_max_interval_fops);
1042 debugfs_create_u16("discov_interleaved_timeout", 0644, hdev->debugfs, 1121 debugfs_create_u16("discov_interleaved_timeout", 0644, hdev->debugfs,
1043 &hdev->discov_interleaved_timeout); 1122 &hdev->discov_interleaved_timeout);
1123
1124 debugfs_create_file("quirk_strict_duplicate_filter", 0644,
1125 hdev->debugfs, hdev,
1126 &quirk_strict_duplicate_filter_fops);
1127 debugfs_create_file("quirk_simultaneous_discovery", 0644,
1128 hdev->debugfs, hdev,
1129 &quirk_simultaneous_discovery_fops);
1044} 1130}
1045 1131
1046void hci_debugfs_create_conn(struct hci_conn *conn) 1132void hci_debugfs_create_conn(struct hci_conn *conn)