Commit 606185b20caf4c57d7e41e5a5ea4aff460aef2ab

Authored by Dan Carpenter
Committed by Jiri Kosina
1 parent 2bacedada6

HID: roccat: potential out of bounds in pyra_sysfs_write_settings()

This is a static checker fix.  We write some binary settings to the
sysfs file.  One of the settings is the "->startup_profile".  There
isn't any checking to make sure it fits into the
pyra->profile_settings[] array in the profile_activated() function.

I added a check to pyra_sysfs_write_settings() in both places because
I wasn't positive that the other callers were correct.

Cc: <stable@vger.kernel.org>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

Showing 1 changed file with 6 additions and 2 deletions Inline Diff

drivers/hid/hid-roccat-pyra.c
1 /* 1 /*
2 * Roccat Pyra driver for Linux 2 * Roccat Pyra driver for Linux
3 * 3 *
4 * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net> 4 * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
5 */ 5 */
6 6
7 /* 7 /*
8 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free 9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option) 10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version. 11 * any later version.
12 */ 12 */
13 13
14 /* 14 /*
15 * Roccat Pyra is a mobile gamer mouse which comes in wired and wireless 15 * Roccat Pyra is a mobile gamer mouse which comes in wired and wireless
16 * variant. Wireless variant is not tested. 16 * variant. Wireless variant is not tested.
17 * Userland tools can be found at http://sourceforge.net/projects/roccat 17 * Userland tools can be found at http://sourceforge.net/projects/roccat
18 */ 18 */
19 19
20 #include <linux/device.h> 20 #include <linux/device.h>
21 #include <linux/input.h> 21 #include <linux/input.h>
22 #include <linux/hid.h> 22 #include <linux/hid.h>
23 #include <linux/module.h> 23 #include <linux/module.h>
24 #include <linux/slab.h> 24 #include <linux/slab.h>
25 #include <linux/hid-roccat.h> 25 #include <linux/hid-roccat.h>
26 #include "hid-ids.h" 26 #include "hid-ids.h"
27 #include "hid-roccat-common.h" 27 #include "hid-roccat-common.h"
28 #include "hid-roccat-pyra.h" 28 #include "hid-roccat-pyra.h"
29 29
30 static uint profile_numbers[5] = {0, 1, 2, 3, 4}; 30 static uint profile_numbers[5] = {0, 1, 2, 3, 4};
31 31
32 /* pyra_class is used for creating sysfs attributes via roccat char device */ 32 /* pyra_class is used for creating sysfs attributes via roccat char device */
33 static struct class *pyra_class; 33 static struct class *pyra_class;
34 34
35 static void profile_activated(struct pyra_device *pyra, 35 static void profile_activated(struct pyra_device *pyra,
36 unsigned int new_profile) 36 unsigned int new_profile)
37 { 37 {
38 if (new_profile >= ARRAY_SIZE(pyra->profile_settings))
39 return;
38 pyra->actual_profile = new_profile; 40 pyra->actual_profile = new_profile;
39 pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi; 41 pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;
40 } 42 }
41 43
42 static int pyra_send_control(struct usb_device *usb_dev, int value, 44 static int pyra_send_control(struct usb_device *usb_dev, int value,
43 enum pyra_control_requests request) 45 enum pyra_control_requests request)
44 { 46 {
45 struct roccat_common2_control control; 47 struct roccat_common2_control control;
46 48
47 if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS || 49 if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS ||
48 request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) && 50 request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) &&
49 (value < 0 || value > 4)) 51 (value < 0 || value > 4))
50 return -EINVAL; 52 return -EINVAL;
51 53
52 control.command = ROCCAT_COMMON_COMMAND_CONTROL; 54 control.command = ROCCAT_COMMON_COMMAND_CONTROL;
53 control.value = value; 55 control.value = value;
54 control.request = request; 56 control.request = request;
55 57
56 return roccat_common2_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL, 58 return roccat_common2_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL,
57 &control, sizeof(struct roccat_common2_control)); 59 &control, sizeof(struct roccat_common2_control));
58 } 60 }
59 61
60 static int pyra_get_profile_settings(struct usb_device *usb_dev, 62 static int pyra_get_profile_settings(struct usb_device *usb_dev,
61 struct pyra_profile_settings *buf, int number) 63 struct pyra_profile_settings *buf, int number)
62 { 64 {
63 int retval; 65 int retval;
64 retval = pyra_send_control(usb_dev, number, 66 retval = pyra_send_control(usb_dev, number,
65 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS); 67 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
66 if (retval) 68 if (retval)
67 return retval; 69 return retval;
68 return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, 70 return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS,
69 buf, PYRA_SIZE_PROFILE_SETTINGS); 71 buf, PYRA_SIZE_PROFILE_SETTINGS);
70 } 72 }
71 73
72 static int pyra_get_settings(struct usb_device *usb_dev, 74 static int pyra_get_settings(struct usb_device *usb_dev,
73 struct pyra_settings *buf) 75 struct pyra_settings *buf)
74 { 76 {
75 return roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS, 77 return roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS,
76 buf, PYRA_SIZE_SETTINGS); 78 buf, PYRA_SIZE_SETTINGS);
77 } 79 }
78 80
79 static int pyra_set_settings(struct usb_device *usb_dev, 81 static int pyra_set_settings(struct usb_device *usb_dev,
80 struct pyra_settings const *settings) 82 struct pyra_settings const *settings)
81 { 83 {
82 return roccat_common2_send_with_status(usb_dev, 84 return roccat_common2_send_with_status(usb_dev,
83 PYRA_COMMAND_SETTINGS, settings, 85 PYRA_COMMAND_SETTINGS, settings,
84 PYRA_SIZE_SETTINGS); 86 PYRA_SIZE_SETTINGS);
85 } 87 }
86 88
87 static ssize_t pyra_sysfs_read(struct file *fp, struct kobject *kobj, 89 static ssize_t pyra_sysfs_read(struct file *fp, struct kobject *kobj,
88 char *buf, loff_t off, size_t count, 90 char *buf, loff_t off, size_t count,
89 size_t real_size, uint command) 91 size_t real_size, uint command)
90 { 92 {
91 struct device *dev = 93 struct device *dev =
92 container_of(kobj, struct device, kobj)->parent->parent; 94 container_of(kobj, struct device, kobj)->parent->parent;
93 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); 95 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
94 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 96 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
95 int retval; 97 int retval;
96 98
97 if (off >= real_size) 99 if (off >= real_size)
98 return 0; 100 return 0;
99 101
100 if (off != 0 || count != real_size) 102 if (off != 0 || count != real_size)
101 return -EINVAL; 103 return -EINVAL;
102 104
103 mutex_lock(&pyra->pyra_lock); 105 mutex_lock(&pyra->pyra_lock);
104 retval = roccat_common2_receive(usb_dev, command, buf, real_size); 106 retval = roccat_common2_receive(usb_dev, command, buf, real_size);
105 mutex_unlock(&pyra->pyra_lock); 107 mutex_unlock(&pyra->pyra_lock);
106 108
107 if (retval) 109 if (retval)
108 return retval; 110 return retval;
109 111
110 return real_size; 112 return real_size;
111 } 113 }
112 114
113 static ssize_t pyra_sysfs_write(struct file *fp, struct kobject *kobj, 115 static ssize_t pyra_sysfs_write(struct file *fp, struct kobject *kobj,
114 void const *buf, loff_t off, size_t count, 116 void const *buf, loff_t off, size_t count,
115 size_t real_size, uint command) 117 size_t real_size, uint command)
116 { 118 {
117 struct device *dev = 119 struct device *dev =
118 container_of(kobj, struct device, kobj)->parent->parent; 120 container_of(kobj, struct device, kobj)->parent->parent;
119 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); 121 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
120 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 122 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
121 int retval; 123 int retval;
122 124
123 if (off != 0 || count != real_size) 125 if (off != 0 || count != real_size)
124 return -EINVAL; 126 return -EINVAL;
125 127
126 mutex_lock(&pyra->pyra_lock); 128 mutex_lock(&pyra->pyra_lock);
127 retval = roccat_common2_send_with_status(usb_dev, command, (void *)buf, real_size); 129 retval = roccat_common2_send_with_status(usb_dev, command, (void *)buf, real_size);
128 mutex_unlock(&pyra->pyra_lock); 130 mutex_unlock(&pyra->pyra_lock);
129 131
130 if (retval) 132 if (retval)
131 return retval; 133 return retval;
132 134
133 return real_size; 135 return real_size;
134 } 136 }
135 137
136 #define PYRA_SYSFS_W(thingy, THINGY) \ 138 #define PYRA_SYSFS_W(thingy, THINGY) \
137 static ssize_t pyra_sysfs_write_ ## thingy(struct file *fp, \ 139 static ssize_t pyra_sysfs_write_ ## thingy(struct file *fp, \
138 struct kobject *kobj, struct bin_attribute *attr, char *buf, \ 140 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
139 loff_t off, size_t count) \ 141 loff_t off, size_t count) \
140 { \ 142 { \
141 return pyra_sysfs_write(fp, kobj, buf, off, count, \ 143 return pyra_sysfs_write(fp, kobj, buf, off, count, \
142 PYRA_SIZE_ ## THINGY, PYRA_COMMAND_ ## THINGY); \ 144 PYRA_SIZE_ ## THINGY, PYRA_COMMAND_ ## THINGY); \
143 } 145 }
144 146
145 #define PYRA_SYSFS_R(thingy, THINGY) \ 147 #define PYRA_SYSFS_R(thingy, THINGY) \
146 static ssize_t pyra_sysfs_read_ ## thingy(struct file *fp, \ 148 static ssize_t pyra_sysfs_read_ ## thingy(struct file *fp, \
147 struct kobject *kobj, struct bin_attribute *attr, char *buf, \ 149 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
148 loff_t off, size_t count) \ 150 loff_t off, size_t count) \
149 { \ 151 { \
150 return pyra_sysfs_read(fp, kobj, buf, off, count, \ 152 return pyra_sysfs_read(fp, kobj, buf, off, count, \
151 PYRA_SIZE_ ## THINGY, PYRA_COMMAND_ ## THINGY); \ 153 PYRA_SIZE_ ## THINGY, PYRA_COMMAND_ ## THINGY); \
152 } 154 }
153 155
154 #define PYRA_SYSFS_RW(thingy, THINGY) \ 156 #define PYRA_SYSFS_RW(thingy, THINGY) \
155 PYRA_SYSFS_W(thingy, THINGY) \ 157 PYRA_SYSFS_W(thingy, THINGY) \
156 PYRA_SYSFS_R(thingy, THINGY) 158 PYRA_SYSFS_R(thingy, THINGY)
157 159
158 #define PYRA_BIN_ATTRIBUTE_RW(thingy, THINGY) \ 160 #define PYRA_BIN_ATTRIBUTE_RW(thingy, THINGY) \
159 PYRA_SYSFS_RW(thingy, THINGY); \ 161 PYRA_SYSFS_RW(thingy, THINGY); \
160 static struct bin_attribute bin_attr_##thingy = { \ 162 static struct bin_attribute bin_attr_##thingy = { \
161 .attr = { .name = #thingy, .mode = 0660 }, \ 163 .attr = { .name = #thingy, .mode = 0660 }, \
162 .size = PYRA_SIZE_ ## THINGY, \ 164 .size = PYRA_SIZE_ ## THINGY, \
163 .read = pyra_sysfs_read_ ## thingy, \ 165 .read = pyra_sysfs_read_ ## thingy, \
164 .write = pyra_sysfs_write_ ## thingy \ 166 .write = pyra_sysfs_write_ ## thingy \
165 } 167 }
166 168
167 #define PYRA_BIN_ATTRIBUTE_R(thingy, THINGY) \ 169 #define PYRA_BIN_ATTRIBUTE_R(thingy, THINGY) \
168 PYRA_SYSFS_R(thingy, THINGY); \ 170 PYRA_SYSFS_R(thingy, THINGY); \
169 static struct bin_attribute bin_attr_##thingy = { \ 171 static struct bin_attribute bin_attr_##thingy = { \
170 .attr = { .name = #thingy, .mode = 0440 }, \ 172 .attr = { .name = #thingy, .mode = 0440 }, \
171 .size = PYRA_SIZE_ ## THINGY, \ 173 .size = PYRA_SIZE_ ## THINGY, \
172 .read = pyra_sysfs_read_ ## thingy, \ 174 .read = pyra_sysfs_read_ ## thingy, \
173 } 175 }
174 176
175 #define PYRA_BIN_ATTRIBUTE_W(thingy, THINGY) \ 177 #define PYRA_BIN_ATTRIBUTE_W(thingy, THINGY) \
176 PYRA_SYSFS_W(thingy, THINGY); \ 178 PYRA_SYSFS_W(thingy, THINGY); \
177 static struct bin_attribute bin_attr_##thingy = { \ 179 static struct bin_attribute bin_attr_##thingy = { \
178 .attr = { .name = #thingy, .mode = 0220 }, \ 180 .attr = { .name = #thingy, .mode = 0220 }, \
179 .size = PYRA_SIZE_ ## THINGY, \ 181 .size = PYRA_SIZE_ ## THINGY, \
180 .write = pyra_sysfs_write_ ## thingy \ 182 .write = pyra_sysfs_write_ ## thingy \
181 } 183 }
182 184
183 PYRA_BIN_ATTRIBUTE_W(control, CONTROL); 185 PYRA_BIN_ATTRIBUTE_W(control, CONTROL);
184 PYRA_BIN_ATTRIBUTE_RW(info, INFO); 186 PYRA_BIN_ATTRIBUTE_RW(info, INFO);
185 PYRA_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS); 187 PYRA_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS);
186 PYRA_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS); 188 PYRA_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS);
187 189
188 static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, 190 static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
189 struct kobject *kobj, struct bin_attribute *attr, char *buf, 191 struct kobject *kobj, struct bin_attribute *attr, char *buf,
190 loff_t off, size_t count) 192 loff_t off, size_t count)
191 { 193 {
192 struct device *dev = 194 struct device *dev =
193 container_of(kobj, struct device, kobj)->parent->parent; 195 container_of(kobj, struct device, kobj)->parent->parent;
194 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 196 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
195 ssize_t retval; 197 ssize_t retval;
196 198
197 retval = pyra_send_control(usb_dev, *(uint *)(attr->private), 199 retval = pyra_send_control(usb_dev, *(uint *)(attr->private),
198 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS); 200 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
199 if (retval) 201 if (retval)
200 return retval; 202 return retval;
201 203
202 return pyra_sysfs_read(fp, kobj, buf, off, count, 204 return pyra_sysfs_read(fp, kobj, buf, off, count,
203 PYRA_SIZE_PROFILE_SETTINGS, 205 PYRA_SIZE_PROFILE_SETTINGS,
204 PYRA_COMMAND_PROFILE_SETTINGS); 206 PYRA_COMMAND_PROFILE_SETTINGS);
205 } 207 }
206 208
207 static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, 209 static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
208 struct kobject *kobj, struct bin_attribute *attr, char *buf, 210 struct kobject *kobj, struct bin_attribute *attr, char *buf,
209 loff_t off, size_t count) 211 loff_t off, size_t count)
210 { 212 {
211 struct device *dev = 213 struct device *dev =
212 container_of(kobj, struct device, kobj)->parent->parent; 214 container_of(kobj, struct device, kobj)->parent->parent;
213 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 215 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
214 ssize_t retval; 216 ssize_t retval;
215 217
216 retval = pyra_send_control(usb_dev, *(uint *)(attr->private), 218 retval = pyra_send_control(usb_dev, *(uint *)(attr->private),
217 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS); 219 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
218 if (retval) 220 if (retval)
219 return retval; 221 return retval;
220 222
221 return pyra_sysfs_read(fp, kobj, buf, off, count, 223 return pyra_sysfs_read(fp, kobj, buf, off, count,
222 PYRA_SIZE_PROFILE_BUTTONS, 224 PYRA_SIZE_PROFILE_BUTTONS,
223 PYRA_COMMAND_PROFILE_BUTTONS); 225 PYRA_COMMAND_PROFILE_BUTTONS);
224 } 226 }
225 227
226 #define PROFILE_ATTR(number) \ 228 #define PROFILE_ATTR(number) \
227 static struct bin_attribute bin_attr_profile##number##_settings = { \ 229 static struct bin_attribute bin_attr_profile##number##_settings = { \
228 .attr = { .name = "profile" #number "_settings", .mode = 0440 }, \ 230 .attr = { .name = "profile" #number "_settings", .mode = 0440 }, \
229 .size = PYRA_SIZE_PROFILE_SETTINGS, \ 231 .size = PYRA_SIZE_PROFILE_SETTINGS, \
230 .read = pyra_sysfs_read_profilex_settings, \ 232 .read = pyra_sysfs_read_profilex_settings, \
231 .private = &profile_numbers[number-1], \ 233 .private = &profile_numbers[number-1], \
232 }; \ 234 }; \
233 static struct bin_attribute bin_attr_profile##number##_buttons = { \ 235 static struct bin_attribute bin_attr_profile##number##_buttons = { \
234 .attr = { .name = "profile" #number "_buttons", .mode = 0440 }, \ 236 .attr = { .name = "profile" #number "_buttons", .mode = 0440 }, \
235 .size = PYRA_SIZE_PROFILE_BUTTONS, \ 237 .size = PYRA_SIZE_PROFILE_BUTTONS, \
236 .read = pyra_sysfs_read_profilex_buttons, \ 238 .read = pyra_sysfs_read_profilex_buttons, \
237 .private = &profile_numbers[number-1], \ 239 .private = &profile_numbers[number-1], \
238 }; 240 };
239 PROFILE_ATTR(1); 241 PROFILE_ATTR(1);
240 PROFILE_ATTR(2); 242 PROFILE_ATTR(2);
241 PROFILE_ATTR(3); 243 PROFILE_ATTR(3);
242 PROFILE_ATTR(4); 244 PROFILE_ATTR(4);
243 PROFILE_ATTR(5); 245 PROFILE_ATTR(5);
244 246
245 static ssize_t pyra_sysfs_write_settings(struct file *fp, 247 static ssize_t pyra_sysfs_write_settings(struct file *fp,
246 struct kobject *kobj, struct bin_attribute *attr, char *buf, 248 struct kobject *kobj, struct bin_attribute *attr, char *buf,
247 loff_t off, size_t count) 249 loff_t off, size_t count)
248 { 250 {
249 struct device *dev = 251 struct device *dev =
250 container_of(kobj, struct device, kobj)->parent->parent; 252 container_of(kobj, struct device, kobj)->parent->parent;
251 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); 253 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
252 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 254 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
253 int retval = 0; 255 int retval = 0;
254 struct pyra_roccat_report roccat_report; 256 struct pyra_roccat_report roccat_report;
255 struct pyra_settings const *settings; 257 struct pyra_settings const *settings;
256 258
257 if (off != 0 || count != PYRA_SIZE_SETTINGS) 259 if (off != 0 || count != PYRA_SIZE_SETTINGS)
258 return -EINVAL; 260 return -EINVAL;
259 261
260 mutex_lock(&pyra->pyra_lock);
261
262 settings = (struct pyra_settings const *)buf; 262 settings = (struct pyra_settings const *)buf;
263 if (settings->startup_profile >= ARRAY_SIZE(pyra->profile_settings))
264 return -EINVAL;
265
266 mutex_lock(&pyra->pyra_lock);
263 267
264 retval = pyra_set_settings(usb_dev, settings); 268 retval = pyra_set_settings(usb_dev, settings);
265 if (retval) { 269 if (retval) {
266 mutex_unlock(&pyra->pyra_lock); 270 mutex_unlock(&pyra->pyra_lock);
267 return retval; 271 return retval;
268 } 272 }
269 273
270 profile_activated(pyra, settings->startup_profile); 274 profile_activated(pyra, settings->startup_profile);
271 275
272 roccat_report.type = PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2; 276 roccat_report.type = PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2;
273 roccat_report.value = settings->startup_profile + 1; 277 roccat_report.value = settings->startup_profile + 1;
274 roccat_report.key = 0; 278 roccat_report.key = 0;
275 roccat_report_event(pyra->chrdev_minor, 279 roccat_report_event(pyra->chrdev_minor,
276 (uint8_t const *)&roccat_report); 280 (uint8_t const *)&roccat_report);
277 281
278 mutex_unlock(&pyra->pyra_lock); 282 mutex_unlock(&pyra->pyra_lock);
279 return PYRA_SIZE_SETTINGS; 283 return PYRA_SIZE_SETTINGS;
280 } 284 }
281 285
282 PYRA_SYSFS_R(settings, SETTINGS); 286 PYRA_SYSFS_R(settings, SETTINGS);
283 static struct bin_attribute bin_attr_settings = 287 static struct bin_attribute bin_attr_settings =
284 __BIN_ATTR(settings, (S_IWUSR | S_IRUGO), 288 __BIN_ATTR(settings, (S_IWUSR | S_IRUGO),
285 pyra_sysfs_read_settings, pyra_sysfs_write_settings, 289 pyra_sysfs_read_settings, pyra_sysfs_write_settings,
286 PYRA_SIZE_SETTINGS); 290 PYRA_SIZE_SETTINGS);
287 291
288 static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev, 292 static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev,
289 struct device_attribute *attr, char *buf) 293 struct device_attribute *attr, char *buf)
290 { 294 {
291 struct pyra_device *pyra = 295 struct pyra_device *pyra =
292 hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); 296 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
293 return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi); 297 return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi);
294 } 298 }
295 static DEVICE_ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL); 299 static DEVICE_ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL);
296 300
297 static ssize_t pyra_sysfs_show_actual_profile(struct device *dev, 301 static ssize_t pyra_sysfs_show_actual_profile(struct device *dev,
298 struct device_attribute *attr, char *buf) 302 struct device_attribute *attr, char *buf)
299 { 303 {
300 struct pyra_device *pyra = 304 struct pyra_device *pyra =
301 hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); 305 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
302 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 306 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
303 struct pyra_settings settings; 307 struct pyra_settings settings;
304 308
305 mutex_lock(&pyra->pyra_lock); 309 mutex_lock(&pyra->pyra_lock);
306 roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS, 310 roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS,
307 &settings, PYRA_SIZE_SETTINGS); 311 &settings, PYRA_SIZE_SETTINGS);
308 mutex_unlock(&pyra->pyra_lock); 312 mutex_unlock(&pyra->pyra_lock);
309 313
310 return snprintf(buf, PAGE_SIZE, "%d\n", settings.startup_profile); 314 return snprintf(buf, PAGE_SIZE, "%d\n", settings.startup_profile);
311 } 315 }
312 static DEVICE_ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL); 316 static DEVICE_ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL);
313 static DEVICE_ATTR(startup_profile, 0440, pyra_sysfs_show_actual_profile, NULL); 317 static DEVICE_ATTR(startup_profile, 0440, pyra_sysfs_show_actual_profile, NULL);
314 318
315 static ssize_t pyra_sysfs_show_firmware_version(struct device *dev, 319 static ssize_t pyra_sysfs_show_firmware_version(struct device *dev,
316 struct device_attribute *attr, char *buf) 320 struct device_attribute *attr, char *buf)
317 { 321 {
318 struct pyra_device *pyra; 322 struct pyra_device *pyra;
319 struct usb_device *usb_dev; 323 struct usb_device *usb_dev;
320 struct pyra_info info; 324 struct pyra_info info;
321 325
322 dev = dev->parent->parent; 326 dev = dev->parent->parent;
323 pyra = hid_get_drvdata(dev_get_drvdata(dev)); 327 pyra = hid_get_drvdata(dev_get_drvdata(dev));
324 usb_dev = interface_to_usbdev(to_usb_interface(dev)); 328 usb_dev = interface_to_usbdev(to_usb_interface(dev));
325 329
326 mutex_lock(&pyra->pyra_lock); 330 mutex_lock(&pyra->pyra_lock);
327 roccat_common2_receive(usb_dev, PYRA_COMMAND_INFO, 331 roccat_common2_receive(usb_dev, PYRA_COMMAND_INFO,
328 &info, PYRA_SIZE_INFO); 332 &info, PYRA_SIZE_INFO);
329 mutex_unlock(&pyra->pyra_lock); 333 mutex_unlock(&pyra->pyra_lock);
330 334
331 return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version); 335 return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version);
332 } 336 }
333 static DEVICE_ATTR(firmware_version, 0440, pyra_sysfs_show_firmware_version, 337 static DEVICE_ATTR(firmware_version, 0440, pyra_sysfs_show_firmware_version,
334 NULL); 338 NULL);
335 339
336 static struct attribute *pyra_attrs[] = { 340 static struct attribute *pyra_attrs[] = {
337 &dev_attr_actual_cpi.attr, 341 &dev_attr_actual_cpi.attr,
338 &dev_attr_actual_profile.attr, 342 &dev_attr_actual_profile.attr,
339 &dev_attr_firmware_version.attr, 343 &dev_attr_firmware_version.attr,
340 &dev_attr_startup_profile.attr, 344 &dev_attr_startup_profile.attr,
341 NULL, 345 NULL,
342 }; 346 };
343 347
344 static struct bin_attribute *pyra_bin_attributes[] = { 348 static struct bin_attribute *pyra_bin_attributes[] = {
345 &bin_attr_control, 349 &bin_attr_control,
346 &bin_attr_info, 350 &bin_attr_info,
347 &bin_attr_profile_settings, 351 &bin_attr_profile_settings,
348 &bin_attr_profile_buttons, 352 &bin_attr_profile_buttons,
349 &bin_attr_settings, 353 &bin_attr_settings,
350 &bin_attr_profile1_settings, 354 &bin_attr_profile1_settings,
351 &bin_attr_profile2_settings, 355 &bin_attr_profile2_settings,
352 &bin_attr_profile3_settings, 356 &bin_attr_profile3_settings,
353 &bin_attr_profile4_settings, 357 &bin_attr_profile4_settings,
354 &bin_attr_profile5_settings, 358 &bin_attr_profile5_settings,
355 &bin_attr_profile1_buttons, 359 &bin_attr_profile1_buttons,
356 &bin_attr_profile2_buttons, 360 &bin_attr_profile2_buttons,
357 &bin_attr_profile3_buttons, 361 &bin_attr_profile3_buttons,
358 &bin_attr_profile4_buttons, 362 &bin_attr_profile4_buttons,
359 &bin_attr_profile5_buttons, 363 &bin_attr_profile5_buttons,
360 NULL, 364 NULL,
361 }; 365 };
362 366
363 static const struct attribute_group pyra_group = { 367 static const struct attribute_group pyra_group = {
364 .attrs = pyra_attrs, 368 .attrs = pyra_attrs,
365 .bin_attrs = pyra_bin_attributes, 369 .bin_attrs = pyra_bin_attributes,
366 }; 370 };
367 371
368 static const struct attribute_group *pyra_groups[] = { 372 static const struct attribute_group *pyra_groups[] = {
369 &pyra_group, 373 &pyra_group,
370 NULL, 374 NULL,
371 }; 375 };
372 376
373 static int pyra_init_pyra_device_struct(struct usb_device *usb_dev, 377 static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
374 struct pyra_device *pyra) 378 struct pyra_device *pyra)
375 { 379 {
376 struct pyra_settings settings; 380 struct pyra_settings settings;
377 int retval, i; 381 int retval, i;
378 382
379 mutex_init(&pyra->pyra_lock); 383 mutex_init(&pyra->pyra_lock);
380 384
381 retval = pyra_get_settings(usb_dev, &settings); 385 retval = pyra_get_settings(usb_dev, &settings);
382 if (retval) 386 if (retval)
383 return retval; 387 return retval;
384 388
385 for (i = 0; i < 5; ++i) { 389 for (i = 0; i < 5; ++i) {
386 retval = pyra_get_profile_settings(usb_dev, 390 retval = pyra_get_profile_settings(usb_dev,
387 &pyra->profile_settings[i], i); 391 &pyra->profile_settings[i], i);
388 if (retval) 392 if (retval)
389 return retval; 393 return retval;
390 } 394 }
391 395
392 profile_activated(pyra, settings.startup_profile); 396 profile_activated(pyra, settings.startup_profile);
393 397
394 return 0; 398 return 0;
395 } 399 }
396 400
397 static int pyra_init_specials(struct hid_device *hdev) 401 static int pyra_init_specials(struct hid_device *hdev)
398 { 402 {
399 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 403 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
400 struct usb_device *usb_dev = interface_to_usbdev(intf); 404 struct usb_device *usb_dev = interface_to_usbdev(intf);
401 struct pyra_device *pyra; 405 struct pyra_device *pyra;
402 int retval; 406 int retval;
403 407
404 if (intf->cur_altsetting->desc.bInterfaceProtocol 408 if (intf->cur_altsetting->desc.bInterfaceProtocol
405 == USB_INTERFACE_PROTOCOL_MOUSE) { 409 == USB_INTERFACE_PROTOCOL_MOUSE) {
406 410
407 pyra = kzalloc(sizeof(*pyra), GFP_KERNEL); 411 pyra = kzalloc(sizeof(*pyra), GFP_KERNEL);
408 if (!pyra) { 412 if (!pyra) {
409 hid_err(hdev, "can't alloc device descriptor\n"); 413 hid_err(hdev, "can't alloc device descriptor\n");
410 return -ENOMEM; 414 return -ENOMEM;
411 } 415 }
412 hid_set_drvdata(hdev, pyra); 416 hid_set_drvdata(hdev, pyra);
413 417
414 retval = pyra_init_pyra_device_struct(usb_dev, pyra); 418 retval = pyra_init_pyra_device_struct(usb_dev, pyra);
415 if (retval) { 419 if (retval) {
416 hid_err(hdev, "couldn't init struct pyra_device\n"); 420 hid_err(hdev, "couldn't init struct pyra_device\n");
417 goto exit_free; 421 goto exit_free;
418 } 422 }
419 423
420 retval = roccat_connect(pyra_class, hdev, 424 retval = roccat_connect(pyra_class, hdev,
421 sizeof(struct pyra_roccat_report)); 425 sizeof(struct pyra_roccat_report));
422 if (retval < 0) { 426 if (retval < 0) {
423 hid_err(hdev, "couldn't init char dev\n"); 427 hid_err(hdev, "couldn't init char dev\n");
424 } else { 428 } else {
425 pyra->chrdev_minor = retval; 429 pyra->chrdev_minor = retval;
426 pyra->roccat_claimed = 1; 430 pyra->roccat_claimed = 1;
427 } 431 }
428 } else { 432 } else {
429 hid_set_drvdata(hdev, NULL); 433 hid_set_drvdata(hdev, NULL);
430 } 434 }
431 435
432 return 0; 436 return 0;
433 exit_free: 437 exit_free:
434 kfree(pyra); 438 kfree(pyra);
435 return retval; 439 return retval;
436 } 440 }
437 441
438 static void pyra_remove_specials(struct hid_device *hdev) 442 static void pyra_remove_specials(struct hid_device *hdev)
439 { 443 {
440 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 444 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
441 struct pyra_device *pyra; 445 struct pyra_device *pyra;
442 446
443 if (intf->cur_altsetting->desc.bInterfaceProtocol 447 if (intf->cur_altsetting->desc.bInterfaceProtocol
444 == USB_INTERFACE_PROTOCOL_MOUSE) { 448 == USB_INTERFACE_PROTOCOL_MOUSE) {
445 pyra = hid_get_drvdata(hdev); 449 pyra = hid_get_drvdata(hdev);
446 if (pyra->roccat_claimed) 450 if (pyra->roccat_claimed)
447 roccat_disconnect(pyra->chrdev_minor); 451 roccat_disconnect(pyra->chrdev_minor);
448 kfree(hid_get_drvdata(hdev)); 452 kfree(hid_get_drvdata(hdev));
449 } 453 }
450 } 454 }
451 455
452 static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id) 456 static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id)
453 { 457 {
454 int retval; 458 int retval;
455 459
456 retval = hid_parse(hdev); 460 retval = hid_parse(hdev);
457 if (retval) { 461 if (retval) {
458 hid_err(hdev, "parse failed\n"); 462 hid_err(hdev, "parse failed\n");
459 goto exit; 463 goto exit;
460 } 464 }
461 465
462 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 466 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
463 if (retval) { 467 if (retval) {
464 hid_err(hdev, "hw start failed\n"); 468 hid_err(hdev, "hw start failed\n");
465 goto exit; 469 goto exit;
466 } 470 }
467 471
468 retval = pyra_init_specials(hdev); 472 retval = pyra_init_specials(hdev);
469 if (retval) { 473 if (retval) {
470 hid_err(hdev, "couldn't install mouse\n"); 474 hid_err(hdev, "couldn't install mouse\n");
471 goto exit_stop; 475 goto exit_stop;
472 } 476 }
473 return 0; 477 return 0;
474 478
475 exit_stop: 479 exit_stop:
476 hid_hw_stop(hdev); 480 hid_hw_stop(hdev);
477 exit: 481 exit:
478 return retval; 482 return retval;
479 } 483 }
480 484
481 static void pyra_remove(struct hid_device *hdev) 485 static void pyra_remove(struct hid_device *hdev)
482 { 486 {
483 pyra_remove_specials(hdev); 487 pyra_remove_specials(hdev);
484 hid_hw_stop(hdev); 488 hid_hw_stop(hdev);
485 } 489 }
486 490
487 static void pyra_keep_values_up_to_date(struct pyra_device *pyra, 491 static void pyra_keep_values_up_to_date(struct pyra_device *pyra,
488 u8 const *data) 492 u8 const *data)
489 { 493 {
490 struct pyra_mouse_event_button const *button_event; 494 struct pyra_mouse_event_button const *button_event;
491 495
492 switch (data[0]) { 496 switch (data[0]) {
493 case PYRA_MOUSE_REPORT_NUMBER_BUTTON: 497 case PYRA_MOUSE_REPORT_NUMBER_BUTTON:
494 button_event = (struct pyra_mouse_event_button const *)data; 498 button_event = (struct pyra_mouse_event_button const *)data;
495 switch (button_event->type) { 499 switch (button_event->type) {
496 case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2: 500 case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
497 profile_activated(pyra, button_event->data1 - 1); 501 profile_activated(pyra, button_event->data1 - 1);
498 break; 502 break;
499 case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI: 503 case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
500 pyra->actual_cpi = button_event->data1; 504 pyra->actual_cpi = button_event->data1;
501 break; 505 break;
502 } 506 }
503 break; 507 break;
504 } 508 }
505 } 509 }
506 510
507 static void pyra_report_to_chrdev(struct pyra_device const *pyra, 511 static void pyra_report_to_chrdev(struct pyra_device const *pyra,
508 u8 const *data) 512 u8 const *data)
509 { 513 {
510 struct pyra_roccat_report roccat_report; 514 struct pyra_roccat_report roccat_report;
511 struct pyra_mouse_event_button const *button_event; 515 struct pyra_mouse_event_button const *button_event;
512 516
513 if (data[0] != PYRA_MOUSE_REPORT_NUMBER_BUTTON) 517 if (data[0] != PYRA_MOUSE_REPORT_NUMBER_BUTTON)
514 return; 518 return;
515 519
516 button_event = (struct pyra_mouse_event_button const *)data; 520 button_event = (struct pyra_mouse_event_button const *)data;
517 521
518 switch (button_event->type) { 522 switch (button_event->type) {
519 case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2: 523 case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
520 case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI: 524 case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
521 roccat_report.type = button_event->type; 525 roccat_report.type = button_event->type;
522 roccat_report.value = button_event->data1; 526 roccat_report.value = button_event->data1;
523 roccat_report.key = 0; 527 roccat_report.key = 0;
524 roccat_report_event(pyra->chrdev_minor, 528 roccat_report_event(pyra->chrdev_minor,
525 (uint8_t const *)&roccat_report); 529 (uint8_t const *)&roccat_report);
526 break; 530 break;
527 case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO: 531 case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO:
528 case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT: 532 case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT:
529 case PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH: 533 case PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH:
530 if (button_event->data2 == PYRA_MOUSE_EVENT_BUTTON_PRESS) { 534 if (button_event->data2 == PYRA_MOUSE_EVENT_BUTTON_PRESS) {
531 roccat_report.type = button_event->type; 535 roccat_report.type = button_event->type;
532 roccat_report.key = button_event->data1; 536 roccat_report.key = button_event->data1;
533 /* 537 /*
534 * pyra reports profile numbers with range 1-5. 538 * pyra reports profile numbers with range 1-5.
535 * Keeping this behaviour. 539 * Keeping this behaviour.
536 */ 540 */
537 roccat_report.value = pyra->actual_profile + 1; 541 roccat_report.value = pyra->actual_profile + 1;
538 roccat_report_event(pyra->chrdev_minor, 542 roccat_report_event(pyra->chrdev_minor,
539 (uint8_t const *)&roccat_report); 543 (uint8_t const *)&roccat_report);
540 } 544 }
541 break; 545 break;
542 } 546 }
543 } 547 }
544 548
545 static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report, 549 static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report,
546 u8 *data, int size) 550 u8 *data, int size)
547 { 551 {
548 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 552 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
549 struct pyra_device *pyra = hid_get_drvdata(hdev); 553 struct pyra_device *pyra = hid_get_drvdata(hdev);
550 554
551 if (intf->cur_altsetting->desc.bInterfaceProtocol 555 if (intf->cur_altsetting->desc.bInterfaceProtocol
552 != USB_INTERFACE_PROTOCOL_MOUSE) 556 != USB_INTERFACE_PROTOCOL_MOUSE)
553 return 0; 557 return 0;
554 558
555 if (pyra == NULL) 559 if (pyra == NULL)
556 return 0; 560 return 0;
557 561
558 pyra_keep_values_up_to_date(pyra, data); 562 pyra_keep_values_up_to_date(pyra, data);
559 563
560 if (pyra->roccat_claimed) 564 if (pyra->roccat_claimed)
561 pyra_report_to_chrdev(pyra, data); 565 pyra_report_to_chrdev(pyra, data);
562 566
563 return 0; 567 return 0;
564 } 568 }
565 569
566 static const struct hid_device_id pyra_devices[] = { 570 static const struct hid_device_id pyra_devices[] = {
567 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, 571 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT,
568 USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, 572 USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
569 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, 573 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT,
570 USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) }, 574 USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) },
571 { } 575 { }
572 }; 576 };
573 577
574 MODULE_DEVICE_TABLE(hid, pyra_devices); 578 MODULE_DEVICE_TABLE(hid, pyra_devices);
575 579
576 static struct hid_driver pyra_driver = { 580 static struct hid_driver pyra_driver = {
577 .name = "pyra", 581 .name = "pyra",
578 .id_table = pyra_devices, 582 .id_table = pyra_devices,
579 .probe = pyra_probe, 583 .probe = pyra_probe,
580 .remove = pyra_remove, 584 .remove = pyra_remove,
581 .raw_event = pyra_raw_event 585 .raw_event = pyra_raw_event
582 }; 586 };
583 587
584 static int __init pyra_init(void) 588 static int __init pyra_init(void)
585 { 589 {
586 int retval; 590 int retval;
587 591
588 /* class name has to be same as driver name */ 592 /* class name has to be same as driver name */
589 pyra_class = class_create(THIS_MODULE, "pyra"); 593 pyra_class = class_create(THIS_MODULE, "pyra");
590 if (IS_ERR(pyra_class)) 594 if (IS_ERR(pyra_class))
591 return PTR_ERR(pyra_class); 595 return PTR_ERR(pyra_class);
592 pyra_class->dev_groups = pyra_groups; 596 pyra_class->dev_groups = pyra_groups;
593 597
594 retval = hid_register_driver(&pyra_driver); 598 retval = hid_register_driver(&pyra_driver);
595 if (retval) 599 if (retval)
596 class_destroy(pyra_class); 600 class_destroy(pyra_class);
597 return retval; 601 return retval;
598 } 602 }
599 603
600 static void __exit pyra_exit(void) 604 static void __exit pyra_exit(void)
601 { 605 {
602 hid_unregister_driver(&pyra_driver); 606 hid_unregister_driver(&pyra_driver);
603 class_destroy(pyra_class); 607 class_destroy(pyra_class);
604 } 608 }
605 609
606 module_init(pyra_init); 610 module_init(pyra_init);
607 module_exit(pyra_exit); 611 module_exit(pyra_exit);
608 612
609 MODULE_AUTHOR("Stefan Achatz"); 613 MODULE_AUTHOR("Stefan Achatz");
610 MODULE_DESCRIPTION("USB Roccat Pyra driver"); 614 MODULE_DESCRIPTION("USB Roccat Pyra driver");