rework UIHV init/deinit
[kernel/swap-modules.git] / uihv / uihv_debugfs.c
1 #include <linux/fs.h>
2 #include <linux/slab.h>
3 #include <linux/debugfs.h>
4 #include <linux/module.h>
5 #include <asm/uaccess.h>
6 #include <master/swap_debugfs.h>
7 #include "uihv.h"
8 #include "uihv_module.h"
9
10 static const char UIHV_FOLDER[] = "uihv";
11 static const char UIHV_PATH[] = "path";
12 static const char UIHV_APP_INFO[] = "app_info";
13 static const char UIHV_ENABLE[] = "enable";
14
15 static struct dentry *uihv_root;
16
17
18
19 /* ===========================================================================
20  * =                           UI VIEWER PATH                                =
21  * ===========================================================================
22  */
23
24
25 static ssize_t uihv_path_write(struct file *file, const char __user *buf,
26                                size_t len, loff_t *ppos)
27 {
28         ssize_t ret;
29         char *path;
30
31         path = kmalloc(len, GFP_KERNEL);
32         if (path == NULL) {
33                 ret = -ENOMEM;
34                 goto uihv_path_write_out;
35         }
36
37         if (copy_from_user(path, buf, len)) {
38                 ret = -EINVAL;
39                 goto uihv_path_write_out;
40         }
41
42         path[len - 1] = '\0';
43
44         if (uihv_set_handler(path) != 0) {
45                 printk(UIHV_PREFIX "Cannot set ui viewer path %s\n", path);
46                 ret = -EINVAL;
47                 goto uihv_path_write_out;
48         }
49
50         ret = len;
51
52         printk(UIHV_PREFIX "Set ui viewer path %s\n", path);
53
54 uihv_path_write_out:
55         kfree(path);
56
57         return ret;
58 }
59
60 static const struct file_operations uihv_path_file_ops = {
61         .owner = THIS_MODULE,
62         .write = uihv_path_write,
63 };
64
65
66 /*
67  * format:
68  *      main:app_path
69  *
70  * sample:
71  *      0x00000d60:/bin/app_sample
72  */
73 static int uihv_add_app_info(const char *buf, size_t len)
74 {
75         int n, ret;
76         char *app_path;
77         unsigned long main_addr;
78         const char fmt[] = "%%lx:/%%%ds";
79         char fmt_buf[64];
80
81         n = snprintf(fmt_buf, sizeof(fmt_buf), fmt, PATH_MAX - 2);
82         if (n <= 0)
83                 return -EINVAL;
84
85         app_path = kmalloc(PATH_MAX, GFP_KERNEL);
86         if (app_path == NULL)
87                 return -ENOMEM;
88
89         n = sscanf(buf, fmt_buf, &main_addr, app_path + 1);
90         if (n != 2) {
91                 ret = -EINVAL;
92                 goto free_app_path;
93         }
94         app_path[0] = '/';
95
96         printk(UIHV_PREFIX "Set ui viewer app path %s, main offset 0x%lx\n", app_path, main_addr);
97
98         ret = uihv_data_set(app_path, main_addr);
99
100 free_app_path:
101         kfree(app_path);
102         return ret;
103 }
104
105 static ssize_t write_uihv_app_info(struct file *file,
106                                         const char __user *user_buf,
107                                         size_t len, loff_t *ppos)
108 {
109         ssize_t ret = len;
110         char *buf;
111
112         buf = kmalloc(len, GFP_KERNEL);
113         if (buf == NULL) {
114                 ret = -ENOMEM;
115                 goto free_buf;
116         }
117
118         if (copy_from_user(buf, user_buf, len)) {
119                 ret = -EINVAL;
120                 goto free_buf;
121         }
122
123         buf[len - 1] = '\0';
124
125         if (uihv_add_app_info(buf, len))
126                 ret = -EINVAL;
127
128 free_buf:
129         kfree(buf);
130
131         return ret;
132 }
133
134 static const struct file_operations uihv_app_info_file_ops = {
135         .owner = THIS_MODULE,
136         .write = write_uihv_app_info,
137 };
138
139 static ssize_t write_uihv_enable(struct file *file,
140                                  const char __user *user_buf,
141                                  size_t len, loff_t *ppos)
142 {
143         ssize_t ret = len;
144         char *buf;
145
146         buf = kmalloc(len, GFP_KERNEL);
147         if (!buf) {
148                 ret = -ENOMEM;
149                 goto out;
150         }
151
152         if (copy_from_user(buf, user_buf, len)) {
153                 ret = -EINVAL;
154                 goto free_buf;
155         }
156
157         buf[len - 1] = '\0';
158
159         if (buf[0] == '0')
160                 ret = uihv_disable();
161         else
162                 ret = uihv_enable();
163
164 free_buf:
165         kfree(buf);
166
167 out:
168         return ret;
169 }
170
171 static const struct file_operations uihv_enable_file_ops = {
172         .owner = THIS_MODULE,
173         .write = write_uihv_enable,
174 };
175
176 int uihv_dfs_init(void)
177 {
178         struct dentry *swap_dentry, *root, *path, *app_info, *uihv_enable;
179         int ret;
180
181         ret = -ENODEV;
182         if (!debugfs_initialized())
183                 goto fail;
184
185         ret = -ENOENT;
186         swap_dentry = swap_debugfs_getdir();
187         if (!swap_dentry)
188                 goto fail;
189
190         ret = -ENOMEM;
191         root = debugfs_create_dir(UIHV_FOLDER, swap_dentry);
192         if (IS_ERR_OR_NULL(root))
193                 goto fail;
194
195         uihv_root = root;
196
197         path = debugfs_create_file(UIHV_PATH, UIHV_DEFAULT_PERMS, root,
198                             NULL, &uihv_path_file_ops);
199         if (IS_ERR_OR_NULL(path)) {
200                 ret = -ENOMEM;
201                 goto remove;
202         }
203
204         app_info = debugfs_create_file(UIHV_APP_INFO, UIHV_DEFAULT_PERMS,
205                                 root, NULL, &uihv_app_info_file_ops);
206         if (IS_ERR_OR_NULL(app_info)) {
207                 ret = -ENOMEM;
208                 goto remove;
209         }
210
211         uihv_enable = debugfs_create_file(UIHV_ENABLE, UIHV_DEFAULT_PERMS,
212                                           root, NULL, &uihv_enable_file_ops);
213         if (IS_ERR_OR_NULL(uihv_enable)) {
214                 ret = -ENOMEM;
215                 goto remove;
216         }
217
218         return 0;
219
220 remove:
221         debugfs_remove_recursive(root);
222
223 fail:
224         printk(UIHV_PREFIX "Debugfs initialization failure: %d\n", ret);
225
226         return ret;
227 }
228
229 void uihv_dfs_exit(void)
230 {
231         if (uihv_root)
232                 debugfs_remove_recursive(uihv_root);
233
234         uihv_root = NULL;
235 }