aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-wiimote-debug.c
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2011-11-17 08:12:11 -0500
committerJiri Kosina <jkosina@suse.cz>2011-11-22 17:10:58 -0500
commit1d3452c63d4b62329d34d7634f67a3dbec21ca87 (patch)
tree5538195cda1a066e83aa5bee1da479fed004281b /drivers/hid/hid-wiimote-debug.c
parent43e5e7c60ee7039f538ccfaaa4e99829719d9bea (diff)
HID: wiimote: Allow direct eeprom access
The wiimote provides direct access to parts of its eeprom. This implements read support for small chunks of the eeprom. This isn't very fast but prevents the reader from blocking the wiimote stream for too long. Write support is not yet supported as the wiimote breaks if we overwrite its memory. Use hidraw to reverse-engineer the eeprom before implementing write support here. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-wiimote-debug.c')
-rw-r--r--drivers/hid/hid-wiimote-debug.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/drivers/hid/hid-wiimote-debug.c b/drivers/hid/hid-wiimote-debug.c
index 6282e3c1a362..f81243c86790 100644
--- a/drivers/hid/hid-wiimote-debug.c
+++ b/drivers/hid/hid-wiimote-debug.c
@@ -10,12 +10,80 @@
10 * any later version. 10 * any later version.
11 */ 11 */
12 12
13#include <linux/debugfs.h>
13#include <linux/module.h> 14#include <linux/module.h>
14#include <linux/spinlock.h> 15#include <linux/spinlock.h>
16#include <linux/uaccess.h>
15#include "hid-wiimote.h" 17#include "hid-wiimote.h"
16 18
17struct wiimote_debug { 19struct wiimote_debug {
18 struct wiimote_data *wdata; 20 struct wiimote_data *wdata;
21 struct dentry *eeprom;
22};
23
24static int wiidebug_eeprom_open(struct inode *i, struct file *f)
25{
26 f->private_data = i->i_private;
27 return 0;
28}
29
30static ssize_t wiidebug_eeprom_read(struct file *f, char __user *u, size_t s,
31 loff_t *off)
32{
33 struct wiimote_debug *dbg = f->private_data;
34 struct wiimote_data *wdata = dbg->wdata;
35 unsigned long flags;
36 ssize_t ret;
37 char buf[16];
38 __u16 size;
39
40 if (s == 0)
41 return -EINVAL;
42 if (*off > 0xffffff)
43 return 0;
44 if (s > 16)
45 s = 16;
46
47 ret = wiimote_cmd_acquire(wdata);
48 if (ret)
49 return ret;
50
51 spin_lock_irqsave(&wdata->state.lock, flags);
52 wdata->state.cmd_read_size = s;
53 wdata->state.cmd_read_buf = buf;
54 wiimote_cmd_set(wdata, WIIPROTO_REQ_RMEM, *off & 0xffff);
55 wiiproto_req_reeprom(wdata, *off, s);
56 spin_unlock_irqrestore(&wdata->state.lock, flags);
57
58 ret = wiimote_cmd_wait(wdata);
59 if (!ret)
60 size = wdata->state.cmd_read_size;
61
62 spin_lock_irqsave(&wdata->state.lock, flags);
63 wdata->state.cmd_read_buf = NULL;
64 spin_unlock_irqrestore(&wdata->state.lock, flags);
65
66 wiimote_cmd_release(wdata);
67
68 if (ret)
69 return ret;
70 else if (size == 0)
71 return -EIO;
72
73 if (copy_to_user(u, buf, size))
74 return -EFAULT;
75
76 *off += size;
77 ret = size;
78
79 return ret;
80}
81
82static const struct file_operations wiidebug_eeprom_fops = {
83 .owner = THIS_MODULE,
84 .open = wiidebug_eeprom_open,
85 .read = wiidebug_eeprom_read,
86 .llseek = generic_file_llseek,
19}; 87};
20 88
21int wiidebug_init(struct wiimote_data *wdata) 89int wiidebug_init(struct wiimote_data *wdata)
@@ -29,6 +97,13 @@ int wiidebug_init(struct wiimote_data *wdata)
29 97
30 dbg->wdata = wdata; 98 dbg->wdata = wdata;
31 99
100 dbg->eeprom = debugfs_create_file("eeprom", S_IRUSR,
101 dbg->wdata->hdev->debug_dir, dbg, &wiidebug_eeprom_fops);
102 if (!dbg->eeprom) {
103 kfree(dbg);
104 return -ENOMEM;
105 }
106
32 spin_lock_irqsave(&wdata->state.lock, flags); 107 spin_lock_irqsave(&wdata->state.lock, flags);
33 wdata->debug = dbg; 108 wdata->debug = dbg;
34 spin_unlock_irqrestore(&wdata->state.lock, flags); 109 spin_unlock_irqrestore(&wdata->state.lock, flags);
@@ -48,5 +123,6 @@ void wiidebug_deinit(struct wiimote_data *wdata)
48 wdata->debug = NULL; 123 wdata->debug = NULL;
49 spin_unlock_irqrestore(&wdata->state.lock, flags); 124 spin_unlock_irqrestore(&wdata->state.lock, flags);
50 125
126 debugfs_remove(dbg->eeprom);
51 kfree(dbg); 127 kfree(dbg);
52} 128}