1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/debugfs.h>
17#include <linux/netdevice.h>
18#include <linux/module.h>
19#include <linux/devcoredump.h>
20
21#include <brcmu_wifi.h>
22#include <brcmu_utils.h>
23#include "core.h"
24#include "bus.h"
25#include "fweh.h"
26#include "debug.h"
27
28static struct dentry *root_folder;
29
30int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
31 size_t len)
32{
33 void *dump;
34 size_t ramsize;
35 int err;
36
37 ramsize = brcmf_bus_get_ramsize(bus);
38 if (!ramsize)
39 return -ENOTSUPP;
40
41 dump = vzalloc(len + ramsize);
42 if (!dump)
43 return -ENOMEM;
44
45 memcpy(dump, data, len);
46 err = brcmf_bus_get_memdump(bus, dump + len, ramsize);
47 if (err) {
48 vfree(dump);
49 return err;
50 }
51
52 dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL);
53
54 return 0;
55}
56
57void brcmf_debugfs_init(void)
58{
59 root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
60 if (IS_ERR(root_folder))
61 root_folder = NULL;
62}
63
64void brcmf_debugfs_exit(void)
65{
66 if (!root_folder)
67 return;
68
69 debugfs_remove_recursive(root_folder);
70 root_folder = NULL;
71}
72
73int brcmf_debug_attach(struct brcmf_pub *drvr)
74{
75 struct device *dev = drvr->bus_if->dev;
76
77 if (!root_folder)
78 return -ENODEV;
79
80 drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
81 return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
82}
83
84void brcmf_debug_detach(struct brcmf_pub *drvr)
85{
86 brcmf_fweh_unregister(drvr, BRCMF_E_PSM_WATCHDOG);
87
88 if (!IS_ERR_OR_NULL(drvr->dbgfs_dir))
89 debugfs_remove_recursive(drvr->dbgfs_dir);
90}
91
92struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr)
93{
94 return drvr->dbgfs_dir;
95}
96
97int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
98 int (*read_fn)(struct seq_file *seq, void *data))
99{
100 struct dentry *e;
101
102 e = debugfs_create_devm_seqfile(drvr->bus_if->dev, fn,
103 drvr->dbgfs_dir, read_fn);
104 return PTR_ERR_OR_ZERO(e);
105}
106