diff options
Diffstat (limited to 'drivers/hid/hid-wiimote-debug.c')
-rw-r--r-- | drivers/hid/hid-wiimote-debug.c | 107 |
1 files changed, 103 insertions, 4 deletions
diff --git a/drivers/hid/hid-wiimote-debug.c b/drivers/hid/hid-wiimote-debug.c index f81243c86790..17dabc1f339e 100644 --- a/drivers/hid/hid-wiimote-debug.c +++ b/drivers/hid/hid-wiimote-debug.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/debugfs.h> | 13 | #include <linux/debugfs.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/seq_file.h> | ||
15 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
16 | #include <linux/uaccess.h> | 17 | #include <linux/uaccess.h> |
17 | #include "hid-wiimote.h" | 18 | #include "hid-wiimote.h" |
@@ -19,6 +20,7 @@ | |||
19 | struct wiimote_debug { | 20 | struct wiimote_debug { |
20 | struct wiimote_data *wdata; | 21 | struct wiimote_data *wdata; |
21 | struct dentry *eeprom; | 22 | struct dentry *eeprom; |
23 | struct dentry *drm; | ||
22 | }; | 24 | }; |
23 | 25 | ||
24 | static int wiidebug_eeprom_open(struct inode *i, struct file *f) | 26 | static int wiidebug_eeprom_open(struct inode *i, struct file *f) |
@@ -86,10 +88,97 @@ static const struct file_operations wiidebug_eeprom_fops = { | |||
86 | .llseek = generic_file_llseek, | 88 | .llseek = generic_file_llseek, |
87 | }; | 89 | }; |
88 | 90 | ||
91 | static const char *wiidebug_drmmap[] = { | ||
92 | [WIIPROTO_REQ_NULL] = "NULL", | ||
93 | [WIIPROTO_REQ_DRM_K] = "K", | ||
94 | [WIIPROTO_REQ_DRM_KA] = "KA", | ||
95 | [WIIPROTO_REQ_DRM_KE] = "KE", | ||
96 | [WIIPROTO_REQ_DRM_KAI] = "KAI", | ||
97 | [WIIPROTO_REQ_DRM_KEE] = "KEE", | ||
98 | [WIIPROTO_REQ_DRM_KAE] = "KAE", | ||
99 | [WIIPROTO_REQ_DRM_KIE] = "KIE", | ||
100 | [WIIPROTO_REQ_DRM_KAIE] = "KAIE", | ||
101 | [WIIPROTO_REQ_DRM_E] = "E", | ||
102 | [WIIPROTO_REQ_DRM_SKAI1] = "SKAI1", | ||
103 | [WIIPROTO_REQ_DRM_SKAI2] = "SKAI2", | ||
104 | [WIIPROTO_REQ_MAX] = NULL | ||
105 | }; | ||
106 | |||
107 | static int wiidebug_drm_show(struct seq_file *f, void *p) | ||
108 | { | ||
109 | struct wiimote_debug *dbg = f->private; | ||
110 | const char *str = NULL; | ||
111 | unsigned long flags; | ||
112 | __u8 drm; | ||
113 | |||
114 | spin_lock_irqsave(&dbg->wdata->state.lock, flags); | ||
115 | drm = dbg->wdata->state.drm; | ||
116 | spin_unlock_irqrestore(&dbg->wdata->state.lock, flags); | ||
117 | |||
118 | if (drm < WIIPROTO_REQ_MAX) | ||
119 | str = wiidebug_drmmap[drm]; | ||
120 | if (!str) | ||
121 | str = "unknown"; | ||
122 | |||
123 | seq_printf(f, "%s\n", str); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static int wiidebug_drm_open(struct inode *i, struct file *f) | ||
129 | { | ||
130 | return single_open(f, wiidebug_drm_show, i->i_private); | ||
131 | } | ||
132 | |||
133 | static ssize_t wiidebug_drm_write(struct file *f, const char __user *u, | ||
134 | size_t s, loff_t *off) | ||
135 | { | ||
136 | struct wiimote_debug *dbg = f->private_data; | ||
137 | unsigned long flags; | ||
138 | char buf[16]; | ||
139 | ssize_t len; | ||
140 | int i; | ||
141 | |||
142 | if (s == 0) | ||
143 | return -EINVAL; | ||
144 | |||
145 | len = min((size_t) 15, s); | ||
146 | if (copy_from_user(buf, u, len)) | ||
147 | return -EFAULT; | ||
148 | |||
149 | buf[15] = 0; | ||
150 | |||
151 | for (i = 0; i < WIIPROTO_REQ_MAX; ++i) { | ||
152 | if (!wiidebug_drmmap[i]) | ||
153 | continue; | ||
154 | if (!strcasecmp(buf, wiidebug_drmmap[i])) | ||
155 | break; | ||
156 | } | ||
157 | |||
158 | if (i == WIIPROTO_REQ_MAX) | ||
159 | i = simple_strtoul(buf, NULL, 10); | ||
160 | |||
161 | spin_lock_irqsave(&dbg->wdata->state.lock, flags); | ||
162 | wiiproto_req_drm(dbg->wdata, (__u8) i); | ||
163 | spin_unlock_irqrestore(&dbg->wdata->state.lock, flags); | ||
164 | |||
165 | return len; | ||
166 | } | ||
167 | |||
168 | static const struct file_operations wiidebug_drm_fops = { | ||
169 | .owner = THIS_MODULE, | ||
170 | .open = wiidebug_drm_open, | ||
171 | .read = seq_read, | ||
172 | .llseek = seq_lseek, | ||
173 | .write = wiidebug_drm_write, | ||
174 | .release = single_release, | ||
175 | }; | ||
176 | |||
89 | int wiidebug_init(struct wiimote_data *wdata) | 177 | int wiidebug_init(struct wiimote_data *wdata) |
90 | { | 178 | { |
91 | struct wiimote_debug *dbg; | 179 | struct wiimote_debug *dbg; |
92 | unsigned long flags; | 180 | unsigned long flags; |
181 | int ret = -ENOMEM; | ||
93 | 182 | ||
94 | dbg = kzalloc(sizeof(*dbg), GFP_KERNEL); | 183 | dbg = kzalloc(sizeof(*dbg), GFP_KERNEL); |
95 | if (!dbg) | 184 | if (!dbg) |
@@ -99,16 +188,25 @@ int wiidebug_init(struct wiimote_data *wdata) | |||
99 | 188 | ||
100 | dbg->eeprom = debugfs_create_file("eeprom", S_IRUSR, | 189 | dbg->eeprom = debugfs_create_file("eeprom", S_IRUSR, |
101 | dbg->wdata->hdev->debug_dir, dbg, &wiidebug_eeprom_fops); | 190 | dbg->wdata->hdev->debug_dir, dbg, &wiidebug_eeprom_fops); |
102 | if (!dbg->eeprom) { | 191 | if (!dbg->eeprom) |
103 | kfree(dbg); | 192 | goto err; |
104 | return -ENOMEM; | 193 | |
105 | } | 194 | dbg->drm = debugfs_create_file("drm", S_IRUSR, |
195 | dbg->wdata->hdev->debug_dir, dbg, &wiidebug_drm_fops); | ||
196 | if (!dbg->drm) | ||
197 | goto err_drm; | ||
106 | 198 | ||
107 | spin_lock_irqsave(&wdata->state.lock, flags); | 199 | spin_lock_irqsave(&wdata->state.lock, flags); |
108 | wdata->debug = dbg; | 200 | wdata->debug = dbg; |
109 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 201 | spin_unlock_irqrestore(&wdata->state.lock, flags); |
110 | 202 | ||
111 | return 0; | 203 | return 0; |
204 | |||
205 | err_drm: | ||
206 | debugfs_remove(dbg->eeprom); | ||
207 | err: | ||
208 | kfree(dbg); | ||
209 | return ret; | ||
112 | } | 210 | } |
113 | 211 | ||
114 | void wiidebug_deinit(struct wiimote_data *wdata) | 212 | void wiidebug_deinit(struct wiimote_data *wdata) |
@@ -123,6 +221,7 @@ void wiidebug_deinit(struct wiimote_data *wdata) | |||
123 | wdata->debug = NULL; | 221 | wdata->debug = NULL; |
124 | spin_unlock_irqrestore(&wdata->state.lock, flags); | 222 | spin_unlock_irqrestore(&wdata->state.lock, flags); |
125 | 223 | ||
224 | debugfs_remove(dbg->drm); | ||
126 | debugfs_remove(dbg->eeprom); | 225 | debugfs_remove(dbg->eeprom); |
127 | kfree(dbg); | 226 | kfree(dbg); |
128 | } | 227 | } |