diff options
Diffstat (limited to 'drivers/hid/hid-wiimote-debug.c')
-rw-r--r-- | drivers/hid/hid-wiimote-debug.c | 76 |
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 | ||
17 | struct wiimote_debug { | 19 | struct wiimote_debug { |
18 | struct wiimote_data *wdata; | 20 | struct wiimote_data *wdata; |
21 | struct dentry *eeprom; | ||
22 | }; | ||
23 | |||
24 | static int wiidebug_eeprom_open(struct inode *i, struct file *f) | ||
25 | { | ||
26 | f->private_data = i->i_private; | ||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | static 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 | |||
82 | static 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 | ||
21 | int wiidebug_init(struct wiimote_data *wdata) | 89 | int 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 | } |