Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/bluetooth/btmrvl_debugfs.c
15112 views
1
/**
2
* Marvell Bluetooth driver: debugfs related functions
3
*
4
* Copyright (C) 2009, Marvell International Ltd.
5
*
6
* This software file (the "File") is distributed by Marvell International
7
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
8
* (the "License"). You may use, redistribute and/or modify this File in
9
* accordance with the terms and conditions of the License, a copy of which
10
* is available by writing to the Free Software Foundation, Inc.,
11
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12
* worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13
*
14
*
15
* THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
17
* ARE EXPRESSLY DISCLAIMED. The License provides additional details about
18
* this warranty disclaimer.
19
**/
20
21
#include <linux/debugfs.h>
22
#include <linux/slab.h>
23
24
#include <net/bluetooth/bluetooth.h>
25
#include <net/bluetooth/hci_core.h>
26
27
#include "btmrvl_drv.h"
28
29
struct btmrvl_debugfs_data {
30
struct dentry *config_dir;
31
struct dentry *status_dir;
32
33
/* config */
34
struct dentry *psmode;
35
struct dentry *pscmd;
36
struct dentry *hsmode;
37
struct dentry *hscmd;
38
struct dentry *gpiogap;
39
struct dentry *hscfgcmd;
40
41
/* status */
42
struct dentry *curpsmode;
43
struct dentry *hsstate;
44
struct dentry *psstate;
45
struct dentry *txdnldready;
46
};
47
48
static int btmrvl_open_generic(struct inode *inode, struct file *file)
49
{
50
file->private_data = inode->i_private;
51
return 0;
52
}
53
54
static ssize_t btmrvl_hscfgcmd_write(struct file *file,
55
const char __user *ubuf, size_t count, loff_t *ppos)
56
{
57
struct btmrvl_private *priv = file->private_data;
58
char buf[16];
59
long result, ret;
60
61
memset(buf, 0, sizeof(buf));
62
63
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
64
return -EFAULT;
65
66
ret = strict_strtol(buf, 10, &result);
67
if (ret)
68
return ret;
69
70
priv->btmrvl_dev.hscfgcmd = result;
71
72
if (priv->btmrvl_dev.hscfgcmd) {
73
btmrvl_prepare_command(priv);
74
wake_up_interruptible(&priv->main_thread.wait_q);
75
}
76
77
return count;
78
}
79
80
static ssize_t btmrvl_hscfgcmd_read(struct file *file, char __user *userbuf,
81
size_t count, loff_t *ppos)
82
{
83
struct btmrvl_private *priv = file->private_data;
84
char buf[16];
85
int ret;
86
87
ret = snprintf(buf, sizeof(buf) - 1, "%d\n",
88
priv->btmrvl_dev.hscfgcmd);
89
90
return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
91
}
92
93
static const struct file_operations btmrvl_hscfgcmd_fops = {
94
.read = btmrvl_hscfgcmd_read,
95
.write = btmrvl_hscfgcmd_write,
96
.open = btmrvl_open_generic,
97
.llseek = default_llseek,
98
};
99
100
static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf,
101
size_t count, loff_t *ppos)
102
{
103
struct btmrvl_private *priv = file->private_data;
104
char buf[16];
105
long result, ret;
106
107
memset(buf, 0, sizeof(buf));
108
109
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
110
return -EFAULT;
111
112
ret = strict_strtol(buf, 10, &result);
113
if (ret)
114
return ret;
115
116
priv->btmrvl_dev.psmode = result;
117
118
return count;
119
}
120
121
static ssize_t btmrvl_psmode_read(struct file *file, char __user *userbuf,
122
size_t count, loff_t *ppos)
123
{
124
struct btmrvl_private *priv = file->private_data;
125
char buf[16];
126
int ret;
127
128
ret = snprintf(buf, sizeof(buf) - 1, "%d\n",
129
priv->btmrvl_dev.psmode);
130
131
return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
132
}
133
134
static const struct file_operations btmrvl_psmode_fops = {
135
.read = btmrvl_psmode_read,
136
.write = btmrvl_psmode_write,
137
.open = btmrvl_open_generic,
138
.llseek = default_llseek,
139
};
140
141
static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf,
142
size_t count, loff_t *ppos)
143
{
144
struct btmrvl_private *priv = file->private_data;
145
char buf[16];
146
long result, ret;
147
148
memset(buf, 0, sizeof(buf));
149
150
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
151
return -EFAULT;
152
153
ret = strict_strtol(buf, 10, &result);
154
if (ret)
155
return ret;
156
157
priv->btmrvl_dev.pscmd = result;
158
159
if (priv->btmrvl_dev.pscmd) {
160
btmrvl_prepare_command(priv);
161
wake_up_interruptible(&priv->main_thread.wait_q);
162
}
163
164
return count;
165
166
}
167
168
static ssize_t btmrvl_pscmd_read(struct file *file, char __user *userbuf,
169
size_t count, loff_t *ppos)
170
{
171
struct btmrvl_private *priv = file->private_data;
172
char buf[16];
173
int ret;
174
175
ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.pscmd);
176
177
return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
178
}
179
180
static const struct file_operations btmrvl_pscmd_fops = {
181
.read = btmrvl_pscmd_read,
182
.write = btmrvl_pscmd_write,
183
.open = btmrvl_open_generic,
184
.llseek = default_llseek,
185
};
186
187
static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf,
188
size_t count, loff_t *ppos)
189
{
190
struct btmrvl_private *priv = file->private_data;
191
char buf[16];
192
long result, ret;
193
194
memset(buf, 0, sizeof(buf));
195
196
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
197
return -EFAULT;
198
199
ret = strict_strtol(buf, 16, &result);
200
if (ret)
201
return ret;
202
203
priv->btmrvl_dev.gpio_gap = result;
204
205
return count;
206
}
207
208
static ssize_t btmrvl_gpiogap_read(struct file *file, char __user *userbuf,
209
size_t count, loff_t *ppos)
210
{
211
struct btmrvl_private *priv = file->private_data;
212
char buf[16];
213
int ret;
214
215
ret = snprintf(buf, sizeof(buf) - 1, "0x%x\n",
216
priv->btmrvl_dev.gpio_gap);
217
218
return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
219
}
220
221
static const struct file_operations btmrvl_gpiogap_fops = {
222
.read = btmrvl_gpiogap_read,
223
.write = btmrvl_gpiogap_write,
224
.open = btmrvl_open_generic,
225
.llseek = default_llseek,
226
};
227
228
static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf,
229
size_t count, loff_t *ppos)
230
{
231
struct btmrvl_private *priv = file->private_data;
232
char buf[16];
233
long result, ret;
234
235
memset(buf, 0, sizeof(buf));
236
237
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
238
return -EFAULT;
239
240
ret = strict_strtol(buf, 10, &result);
241
if (ret)
242
return ret;
243
244
priv->btmrvl_dev.hscmd = result;
245
if (priv->btmrvl_dev.hscmd) {
246
btmrvl_prepare_command(priv);
247
wake_up_interruptible(&priv->main_thread.wait_q);
248
}
249
250
return count;
251
}
252
253
static ssize_t btmrvl_hscmd_read(struct file *file, char __user *userbuf,
254
size_t count, loff_t *ppos)
255
{
256
struct btmrvl_private *priv = file->private_data;
257
char buf[16];
258
int ret;
259
260
ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.hscmd);
261
262
return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
263
}
264
265
static const struct file_operations btmrvl_hscmd_fops = {
266
.read = btmrvl_hscmd_read,
267
.write = btmrvl_hscmd_write,
268
.open = btmrvl_open_generic,
269
.llseek = default_llseek,
270
};
271
272
static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf,
273
size_t count, loff_t *ppos)
274
{
275
struct btmrvl_private *priv = file->private_data;
276
char buf[16];
277
long result, ret;
278
279
memset(buf, 0, sizeof(buf));
280
281
if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
282
return -EFAULT;
283
284
ret = strict_strtol(buf, 10, &result);
285
if (ret)
286
return ret;
287
288
priv->btmrvl_dev.hsmode = result;
289
290
return count;
291
}
292
293
static ssize_t btmrvl_hsmode_read(struct file *file, char __user * userbuf,
294
size_t count, loff_t *ppos)
295
{
296
struct btmrvl_private *priv = file->private_data;
297
char buf[16];
298
int ret;
299
300
ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.hsmode);
301
302
return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
303
}
304
305
static const struct file_operations btmrvl_hsmode_fops = {
306
.read = btmrvl_hsmode_read,
307
.write = btmrvl_hsmode_write,
308
.open = btmrvl_open_generic,
309
.llseek = default_llseek,
310
};
311
312
static ssize_t btmrvl_curpsmode_read(struct file *file, char __user *userbuf,
313
size_t count, loff_t *ppos)
314
{
315
struct btmrvl_private *priv = file->private_data;
316
char buf[16];
317
int ret;
318
319
ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->psmode);
320
321
return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
322
}
323
324
static const struct file_operations btmrvl_curpsmode_fops = {
325
.read = btmrvl_curpsmode_read,
326
.open = btmrvl_open_generic,
327
.llseek = default_llseek,
328
};
329
330
static ssize_t btmrvl_psstate_read(struct file *file, char __user * userbuf,
331
size_t count, loff_t *ppos)
332
{
333
struct btmrvl_private *priv = file->private_data;
334
char buf[16];
335
int ret;
336
337
ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->ps_state);
338
339
return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
340
}
341
342
static const struct file_operations btmrvl_psstate_fops = {
343
.read = btmrvl_psstate_read,
344
.open = btmrvl_open_generic,
345
.llseek = default_llseek,
346
};
347
348
static ssize_t btmrvl_hsstate_read(struct file *file, char __user *userbuf,
349
size_t count, loff_t *ppos)
350
{
351
struct btmrvl_private *priv = file->private_data;
352
char buf[16];
353
int ret;
354
355
ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->hs_state);
356
357
return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
358
}
359
360
static const struct file_operations btmrvl_hsstate_fops = {
361
.read = btmrvl_hsstate_read,
362
.open = btmrvl_open_generic,
363
.llseek = default_llseek,
364
};
365
366
static ssize_t btmrvl_txdnldready_read(struct file *file, char __user *userbuf,
367
size_t count, loff_t *ppos)
368
{
369
struct btmrvl_private *priv = file->private_data;
370
char buf[16];
371
int ret;
372
373
ret = snprintf(buf, sizeof(buf) - 1, "%d\n",
374
priv->btmrvl_dev.tx_dnld_rdy);
375
376
return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
377
}
378
379
static const struct file_operations btmrvl_txdnldready_fops = {
380
.read = btmrvl_txdnldready_read,
381
.open = btmrvl_open_generic,
382
.llseek = default_llseek,
383
};
384
385
void btmrvl_debugfs_init(struct hci_dev *hdev)
386
{
387
struct btmrvl_private *priv = hdev->driver_data;
388
struct btmrvl_debugfs_data *dbg;
389
390
if (!hdev->debugfs)
391
return;
392
393
dbg = kzalloc(sizeof(*dbg), GFP_KERNEL);
394
priv->debugfs_data = dbg;
395
396
if (!dbg) {
397
BT_ERR("Can not allocate memory for btmrvl_debugfs_data.");
398
return;
399
}
400
401
dbg->config_dir = debugfs_create_dir("config", hdev->debugfs);
402
403
dbg->psmode = debugfs_create_file("psmode", 0644, dbg->config_dir,
404
hdev->driver_data, &btmrvl_psmode_fops);
405
dbg->pscmd = debugfs_create_file("pscmd", 0644, dbg->config_dir,
406
hdev->driver_data, &btmrvl_pscmd_fops);
407
dbg->gpiogap = debugfs_create_file("gpiogap", 0644, dbg->config_dir,
408
hdev->driver_data, &btmrvl_gpiogap_fops);
409
dbg->hsmode = debugfs_create_file("hsmode", 0644, dbg->config_dir,
410
hdev->driver_data, &btmrvl_hsmode_fops);
411
dbg->hscmd = debugfs_create_file("hscmd", 0644, dbg->config_dir,
412
hdev->driver_data, &btmrvl_hscmd_fops);
413
dbg->hscfgcmd = debugfs_create_file("hscfgcmd", 0644, dbg->config_dir,
414
hdev->driver_data, &btmrvl_hscfgcmd_fops);
415
416
dbg->status_dir = debugfs_create_dir("status", hdev->debugfs);
417
dbg->curpsmode = debugfs_create_file("curpsmode", 0444,
418
dbg->status_dir,
419
hdev->driver_data,
420
&btmrvl_curpsmode_fops);
421
dbg->psstate = debugfs_create_file("psstate", 0444, dbg->status_dir,
422
hdev->driver_data, &btmrvl_psstate_fops);
423
dbg->hsstate = debugfs_create_file("hsstate", 0444, dbg->status_dir,
424
hdev->driver_data, &btmrvl_hsstate_fops);
425
dbg->txdnldready = debugfs_create_file("txdnldready", 0444,
426
dbg->status_dir,
427
hdev->driver_data,
428
&btmrvl_txdnldready_fops);
429
}
430
431
void btmrvl_debugfs_remove(struct hci_dev *hdev)
432
{
433
struct btmrvl_private *priv = hdev->driver_data;
434
struct btmrvl_debugfs_data *dbg = priv->debugfs_data;
435
436
if (!dbg)
437
return;
438
439
debugfs_remove(dbg->psmode);
440
debugfs_remove(dbg->pscmd);
441
debugfs_remove(dbg->gpiogap);
442
debugfs_remove(dbg->hsmode);
443
debugfs_remove(dbg->hscmd);
444
debugfs_remove(dbg->hscfgcmd);
445
debugfs_remove(dbg->config_dir);
446
447
debugfs_remove(dbg->curpsmode);
448
debugfs_remove(dbg->psstate);
449
debugfs_remove(dbg->hsstate);
450
debugfs_remove(dbg->txdnldready);
451
debugfs_remove(dbg->status_dir);
452
453
kfree(dbg);
454
}
455
456