aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorStefan Achatz <erazor_de@users.sourceforge.net>2011-01-30 07:38:23 -0500
committerJiri Kosina <jkosina@suse.cz>2011-02-03 10:37:27 -0500
commit5772f63613ce0a6777e82a7e8fb553e49da27719 (patch)
tree83c066e175d38323bccd4fd511c45dada6ba8ec0 /drivers/hid
parenta28764ef80dd5aef657f810a9c295ccda421c823 (diff)
HID: roccat: Introduce module hid-roccat-common
Module hid-roccat-common contains functions used by roccat device driver modules to reduce code duplication. At the moment it contains just two wrapper methods for usb_control_msg that ensure that the buffer used for transfer is dma capable which wasn't the case before. The kconfig option is not visible to the user but will be selected by the device specific drivers. Signed-off-by: Stefan Achatz <erazor_de@users.sourceforge.net> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/Kconfig7
-rw-r--r--drivers/hid/Makefile1
-rw-r--r--drivers/hid/hid-roccat-arvo.c148
-rw-r--r--drivers/hid/hid-roccat-common.c62
-rw-r--r--drivers/hid/hid-roccat-common.h23
-rw-r--r--drivers/hid/hid-roccat-kone.c143
-rw-r--r--drivers/hid/hid-roccat-koneplus.c135
-rw-r--r--drivers/hid/hid-roccat-pyra.c161
8 files changed, 254 insertions, 426 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 539865a07546..795236963066 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -417,10 +417,14 @@ config HID_ROCCAT
417 Say Y here if you have a Roccat mouse or keyboard and want OSD or 417 Say Y here if you have a Roccat mouse or keyboard and want OSD or
418 macro execution support. 418 macro execution support.
419 419
420config HID_ROCCAT_COMMON
421 tristate
422
420config HID_ROCCAT_ARVO 423config HID_ROCCAT_ARVO
421 tristate "Roccat Arvo keyboard support" 424 tristate "Roccat Arvo keyboard support"
422 depends on USB_HID 425 depends on USB_HID
423 select HID_ROCCAT 426 select HID_ROCCAT
427 select HID_ROCCAT_COMMON
424 ---help--- 428 ---help---
425 Support for Roccat Arvo keyboard. 429 Support for Roccat Arvo keyboard.
426 430
@@ -428,6 +432,7 @@ config HID_ROCCAT_KONE
428 tristate "Roccat Kone Mouse support" 432 tristate "Roccat Kone Mouse support"
429 depends on USB_HID 433 depends on USB_HID
430 select HID_ROCCAT 434 select HID_ROCCAT
435 select HID_ROCCAT_COMMON
431 ---help--- 436 ---help---
432 Support for Roccat Kone mouse. 437 Support for Roccat Kone mouse.
433 438
@@ -435,6 +440,7 @@ config HID_ROCCAT_KONEPLUS
435 tristate "Roccat Kone[+] mouse support" 440 tristate "Roccat Kone[+] mouse support"
436 depends on USB_HID 441 depends on USB_HID
437 select HID_ROCCAT 442 select HID_ROCCAT
443 select HID_ROCCAT_COMMON
438 ---help--- 444 ---help---
439 Support for Roccat Kone[+] mouse. 445 Support for Roccat Kone[+] mouse.
440 446
@@ -442,6 +448,7 @@ config HID_ROCCAT_PYRA
442 tristate "Roccat Pyra mouse support" 448 tristate "Roccat Pyra mouse support"
443 depends on USB_HID 449 depends on USB_HID
444 select HID_ROCCAT 450 select HID_ROCCAT
451 select HID_ROCCAT_COMMON
445 ---help--- 452 ---help---
446 Support for Roccat Pyra mouse. 453 Support for Roccat Pyra mouse.
447 454
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index fea4eb8c9301..086cf62184eb 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
56obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o 56obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
57obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o 57obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
58obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o 58obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o
59obj-$(CONFIG_HID_ROCCAT_COMMON) += hid-roccat-common.o
59obj-$(CONFIG_HID_ROCCAT_ARVO) += hid-roccat-arvo.o 60obj-$(CONFIG_HID_ROCCAT_ARVO) += hid-roccat-arvo.o
60obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o 61obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o
61obj-$(CONFIG_HID_ROCCAT_KONEPLUS) += hid-roccat-koneplus.o 62obj-$(CONFIG_HID_ROCCAT_KONEPLUS) += hid-roccat-koneplus.o
diff --git a/drivers/hid/hid-roccat-arvo.c b/drivers/hid/hid-roccat-arvo.c
index ebf3c15f1a7e..d72ee4186d11 100644
--- a/drivers/hid/hid-roccat-arvo.c
+++ b/drivers/hid/hid-roccat-arvo.c
@@ -19,41 +19,15 @@
19#include <linux/device.h> 19#include <linux/device.h>
20#include <linux/input.h> 20#include <linux/input.h>
21#include <linux/hid.h> 21#include <linux/hid.h>
22#include <linux/usb.h>
23#include <linux/module.h> 22#include <linux/module.h>
24#include <linux/slab.h> 23#include <linux/slab.h>
25#include "hid-ids.h" 24#include "hid-ids.h"
26#include "hid-roccat.h" 25#include "hid-roccat.h"
26#include "hid-roccat-common.h"
27#include "hid-roccat-arvo.h" 27#include "hid-roccat-arvo.h"
28 28
29static struct class *arvo_class; 29static struct class *arvo_class;
30 30
31static int arvo_receive(struct usb_device *usb_dev, uint usb_command,
32 void *buf, uint size)
33{
34 int len;
35
36 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
37 USB_REQ_CLEAR_FEATURE,
38 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
39 usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
40
41 return (len != size) ? -EIO : 0;
42}
43
44static int arvo_send(struct usb_device *usb_dev, uint usb_command,
45 void const *buf, uint size)
46{
47 int len;
48
49 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
50 USB_REQ_SET_CONFIGURATION,
51 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
52 usb_command, 0, (void *)buf, size, USB_CTRL_SET_TIMEOUT);
53
54 return (len != size) ? -EIO : 0;
55}
56
57static ssize_t arvo_sysfs_show_mode_key(struct device *dev, 31static ssize_t arvo_sysfs_show_mode_key(struct device *dev,
58 struct device_attribute *attr, char *buf) 32 struct device_attribute *attr, char *buf)
59{ 33{
@@ -61,24 +35,17 @@ static ssize_t arvo_sysfs_show_mode_key(struct device *dev,
61 hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); 35 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
62 struct usb_device *usb_dev = 36 struct usb_device *usb_dev =
63 interface_to_usbdev(to_usb_interface(dev->parent->parent)); 37 interface_to_usbdev(to_usb_interface(dev->parent->parent));
64 struct arvo_mode_key *temp_buf; 38 struct arvo_mode_key temp_buf;
65 int retval; 39 int retval;
66 40
67 temp_buf = kmalloc(sizeof(struct arvo_mode_key), GFP_KERNEL);
68 if (!temp_buf)
69 return -ENOMEM;
70
71 mutex_lock(&arvo->arvo_lock); 41 mutex_lock(&arvo->arvo_lock);
72 retval = arvo_receive(usb_dev, ARVO_USB_COMMAND_MODE_KEY, 42 retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_MODE_KEY,
73 temp_buf, sizeof(struct arvo_mode_key)); 43 &temp_buf, sizeof(struct arvo_mode_key));
74 mutex_unlock(&arvo->arvo_lock); 44 mutex_unlock(&arvo->arvo_lock);
75 if (retval) 45 if (retval)
76 goto out; 46 return retval;
77 47
78 retval = snprintf(buf, PAGE_SIZE, "%d\n", temp_buf->state); 48 return snprintf(buf, PAGE_SIZE, "%d\n", temp_buf.state);
79out:
80 kfree(temp_buf);
81 return retval;
82} 49}
83 50
84static ssize_t arvo_sysfs_set_mode_key(struct device *dev, 51static ssize_t arvo_sysfs_set_mode_key(struct device *dev,
@@ -88,32 +55,25 @@ static ssize_t arvo_sysfs_set_mode_key(struct device *dev,
88 hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); 55 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
89 struct usb_device *usb_dev = 56 struct usb_device *usb_dev =
90 interface_to_usbdev(to_usb_interface(dev->parent->parent)); 57 interface_to_usbdev(to_usb_interface(dev->parent->parent));
91 struct arvo_mode_key *temp_buf; 58 struct arvo_mode_key temp_buf;
92 unsigned long state; 59 unsigned long state;
93 int retval; 60 int retval;
94 61
95 temp_buf = kmalloc(sizeof(struct arvo_mode_key), GFP_KERNEL);
96 if (!temp_buf)
97 return -ENOMEM;
98
99 retval = strict_strtoul(buf, 10, &state); 62 retval = strict_strtoul(buf, 10, &state);
100 if (retval) 63 if (retval)
101 goto out; 64 return retval;
102 65
103 temp_buf->command = ARVO_COMMAND_MODE_KEY; 66 temp_buf.command = ARVO_COMMAND_MODE_KEY;
104 temp_buf->state = state; 67 temp_buf.state = state;
105 68
106 mutex_lock(&arvo->arvo_lock); 69 mutex_lock(&arvo->arvo_lock);
107 retval = arvo_send(usb_dev, ARVO_USB_COMMAND_MODE_KEY, 70 retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_MODE_KEY,
108 temp_buf, sizeof(struct arvo_mode_key)); 71 &temp_buf, sizeof(struct arvo_mode_key));
109 mutex_unlock(&arvo->arvo_lock); 72 mutex_unlock(&arvo->arvo_lock);
110 if (retval) 73 if (retval)
111 goto out; 74 return retval;
112 75
113 retval = size; 76 return size;
114out:
115 kfree(temp_buf);
116 return retval;
117} 77}
118 78
119static ssize_t arvo_sysfs_show_key_mask(struct device *dev, 79static ssize_t arvo_sysfs_show_key_mask(struct device *dev,
@@ -123,24 +83,17 @@ static ssize_t arvo_sysfs_show_key_mask(struct device *dev,
123 hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); 83 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
124 struct usb_device *usb_dev = 84 struct usb_device *usb_dev =
125 interface_to_usbdev(to_usb_interface(dev->parent->parent)); 85 interface_to_usbdev(to_usb_interface(dev->parent->parent));
126 struct arvo_key_mask *temp_buf; 86 struct arvo_key_mask temp_buf;
127 int retval; 87 int retval;
128 88
129 temp_buf = kmalloc(sizeof(struct arvo_key_mask), GFP_KERNEL);
130 if (!temp_buf)
131 return -ENOMEM;
132
133 mutex_lock(&arvo->arvo_lock); 89 mutex_lock(&arvo->arvo_lock);
134 retval = arvo_receive(usb_dev, ARVO_USB_COMMAND_KEY_MASK, 90 retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_KEY_MASK,
135 temp_buf, sizeof(struct arvo_key_mask)); 91 &temp_buf, sizeof(struct arvo_key_mask));
136 mutex_unlock(&arvo->arvo_lock); 92 mutex_unlock(&arvo->arvo_lock);
137 if (retval) 93 if (retval)
138 goto out; 94 return retval;
139 95
140 retval = snprintf(buf, PAGE_SIZE, "%d\n", temp_buf->key_mask); 96 return snprintf(buf, PAGE_SIZE, "%d\n", temp_buf.key_mask);
141out:
142 kfree(temp_buf);
143 return retval;
144} 97}
145 98
146static ssize_t arvo_sysfs_set_key_mask(struct device *dev, 99static ssize_t arvo_sysfs_set_key_mask(struct device *dev,
@@ -150,52 +103,40 @@ static ssize_t arvo_sysfs_set_key_mask(struct device *dev,
150 hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); 103 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
151 struct usb_device *usb_dev = 104 struct usb_device *usb_dev =
152 interface_to_usbdev(to_usb_interface(dev->parent->parent)); 105 interface_to_usbdev(to_usb_interface(dev->parent->parent));
153 struct arvo_key_mask *temp_buf; 106 struct arvo_key_mask temp_buf;
154 unsigned long key_mask; 107 unsigned long key_mask;
155 int retval; 108 int retval;
156 109
157 temp_buf = kmalloc(sizeof(struct arvo_key_mask), GFP_KERNEL);
158 if (!temp_buf)
159 return -ENOMEM;
160
161 retval = strict_strtoul(buf, 10, &key_mask); 110 retval = strict_strtoul(buf, 10, &key_mask);
162 if (retval) 111 if (retval)
163 goto out; 112 return retval;
164 113
165 temp_buf->command = ARVO_COMMAND_KEY_MASK; 114 temp_buf.command = ARVO_COMMAND_KEY_MASK;
166 temp_buf->key_mask = key_mask; 115 temp_buf.key_mask = key_mask;
167 116
168 mutex_lock(&arvo->arvo_lock); 117 mutex_lock(&arvo->arvo_lock);
169 retval = arvo_send(usb_dev, ARVO_USB_COMMAND_KEY_MASK, 118 retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_KEY_MASK,
170 temp_buf, sizeof(struct arvo_key_mask)); 119 &temp_buf, sizeof(struct arvo_key_mask));
171 mutex_unlock(&arvo->arvo_lock); 120 mutex_unlock(&arvo->arvo_lock);
172 if (retval) 121 if (retval)
173 goto out; 122 return retval;
174 123
175 retval = size; 124 return size;
176out:
177 kfree(temp_buf);
178 return retval;
179} 125}
180 126
181/* retval is 1-5 on success, < 0 on error */ 127/* retval is 1-5 on success, < 0 on error */
182static int arvo_get_actual_profile(struct usb_device *usb_dev) 128static int arvo_get_actual_profile(struct usb_device *usb_dev)
183{ 129{
184 struct arvo_actual_profile *temp_buf; 130 struct arvo_actual_profile temp_buf;
185 int retval; 131 int retval;
186 132
187 temp_buf = kmalloc(sizeof(struct arvo_actual_profile), GFP_KERNEL); 133 retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE,
188 if (!temp_buf) 134 &temp_buf, sizeof(struct arvo_actual_profile));
189 return -ENOMEM;
190
191 retval = arvo_receive(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE,
192 temp_buf, sizeof(struct arvo_actual_profile));
193 135
194 if (!retval) 136 if (retval)
195 retval = temp_buf->actual_profile; 137 return retval;
196 138
197 kfree(temp_buf); 139 return temp_buf.actual_profile;
198 return retval;
199} 140}
200 141
201static ssize_t arvo_sysfs_show_actual_profile(struct device *dev, 142static ssize_t arvo_sysfs_show_actual_profile(struct device *dev,
@@ -214,32 +155,25 @@ static ssize_t arvo_sysfs_set_actual_profile(struct device *dev,
214 hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); 155 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
215 struct usb_device *usb_dev = 156 struct usb_device *usb_dev =
216 interface_to_usbdev(to_usb_interface(dev->parent->parent)); 157 interface_to_usbdev(to_usb_interface(dev->parent->parent));
217 struct arvo_actual_profile *temp_buf; 158 struct arvo_actual_profile temp_buf;
218 unsigned long profile; 159 unsigned long profile;
219 int retval; 160 int retval;
220 161
221 temp_buf = kmalloc(sizeof(struct arvo_actual_profile), GFP_KERNEL);
222 if (!temp_buf)
223 return -ENOMEM;
224
225 retval = strict_strtoul(buf, 10, &profile); 162 retval = strict_strtoul(buf, 10, &profile);
226 if (retval) 163 if (retval)
227 goto out; 164 return retval;
228 165
229 temp_buf->command = ARVO_COMMAND_ACTUAL_PROFILE; 166 temp_buf.command = ARVO_COMMAND_ACTUAL_PROFILE;
230 temp_buf->actual_profile = profile; 167 temp_buf.actual_profile = profile;
231 168
232 mutex_lock(&arvo->arvo_lock); 169 mutex_lock(&arvo->arvo_lock);
233 retval = arvo_send(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE, 170 retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE,
234 temp_buf, sizeof(struct arvo_actual_profile)); 171 &temp_buf, sizeof(struct arvo_actual_profile));
235 if (!retval) { 172 if (!retval) {
236 arvo->actual_profile = profile; 173 arvo->actual_profile = profile;
237 retval = size; 174 retval = size;
238 } 175 }
239 mutex_unlock(&arvo->arvo_lock); 176 mutex_unlock(&arvo->arvo_lock);
240
241out:
242 kfree(temp_buf);
243 return retval; 177 return retval;
244} 178}
245 179
@@ -257,7 +191,7 @@ static ssize_t arvo_sysfs_write(struct file *fp,
257 return -EINVAL; 191 return -EINVAL;
258 192
259 mutex_lock(&arvo->arvo_lock); 193 mutex_lock(&arvo->arvo_lock);
260 retval = arvo_send(usb_dev, command, buf, real_size); 194 retval = roccat_common_send(usb_dev, command, buf, real_size);
261 mutex_unlock(&arvo->arvo_lock); 195 mutex_unlock(&arvo->arvo_lock);
262 196
263 return (retval ? retval : real_size); 197 return (retval ? retval : real_size);
@@ -280,7 +214,7 @@ static ssize_t arvo_sysfs_read(struct file *fp,
280 return -EINVAL; 214 return -EINVAL;
281 215
282 mutex_lock(&arvo->arvo_lock); 216 mutex_lock(&arvo->arvo_lock);
283 retval = arvo_receive(usb_dev, command, buf, real_size); 217 retval = roccat_common_receive(usb_dev, command, buf, real_size);
284 mutex_unlock(&arvo->arvo_lock); 218 mutex_unlock(&arvo->arvo_lock);
285 219
286 return (retval ? retval : real_size); 220 return (retval ? retval : real_size);
diff --git a/drivers/hid/hid-roccat-common.c b/drivers/hid/hid-roccat-common.c
new file mode 100644
index 000000000000..13b1eb0c8c65
--- /dev/null
+++ b/drivers/hid/hid-roccat-common.c
@@ -0,0 +1,62 @@
1/*
2 * Roccat common functions for device specific drivers
3 *
4 * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
5 */
6
7/*
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
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
14#include <linux/slab.h>
15#include "hid-roccat-common.h"
16
17int roccat_common_receive(struct usb_device *usb_dev, uint usb_command,
18 void *data, uint size)
19{
20 char *buf;
21 int len;
22
23 buf = kmalloc(size, GFP_KERNEL);
24 if (buf == NULL)
25 return -ENOMEM;
26
27 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
28 USB_REQ_CLEAR_FEATURE,
29 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
30 usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
31
32 memcpy(data, buf, size);
33 kfree(buf);
34 return ((len < 0) ? len : ((len != size) ? -EIO : 0));
35}
36EXPORT_SYMBOL_GPL(roccat_common_receive);
37
38int roccat_common_send(struct usb_device *usb_dev, uint usb_command,
39 void const *data, uint size)
40{
41 char *buf;
42 int len;
43
44 buf = kmalloc(size, GFP_KERNEL);
45 if (buf == NULL)
46 return -ENOMEM;
47
48 memcpy(buf, data, size);
49
50 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
51 USB_REQ_SET_CONFIGURATION,
52 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
53 usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
54
55 kfree(buf);
56 return ((len < 0) ? len : ((len != size) ? -EIO : 0));
57}
58EXPORT_SYMBOL_GPL(roccat_common_send);
59
60MODULE_AUTHOR("Stefan Achatz");
61MODULE_DESCRIPTION("USB Roccat common driver");
62MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-common.h b/drivers/hid/hid-roccat-common.h
new file mode 100644
index 000000000000..fe45fae05bb9
--- /dev/null
+++ b/drivers/hid/hid-roccat-common.h
@@ -0,0 +1,23 @@
1#ifndef __HID_ROCCAT_COMMON_H
2#define __HID_ROCCAT_COMMON_H
3
4/*
5 * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
6 */
7
8/*
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 */
14
15#include <linux/usb.h>
16#include <linux/types.h>
17
18int roccat_common_receive(struct usb_device *usb_dev, uint usb_command,
19 void *data, uint size);
20int roccat_common_send(struct usb_device *usb_dev, uint usb_command,
21 void const *data, uint size);
22
23#endif
diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c
index cbd8cc42e75a..551665359eba 100644
--- a/drivers/hid/hid-roccat-kone.c
+++ b/drivers/hid/hid-roccat-kone.c
@@ -28,11 +28,11 @@
28#include <linux/device.h> 28#include <linux/device.h>
29#include <linux/input.h> 29#include <linux/input.h>
30#include <linux/hid.h> 30#include <linux/hid.h>
31#include <linux/usb.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/slab.h> 32#include <linux/slab.h>
34#include "hid-ids.h" 33#include "hid-ids.h"
35#include "hid-roccat.h" 34#include "hid-roccat.h"
35#include "hid-roccat-common.h"
36#include "hid-roccat-kone.h" 36#include "hid-roccat-kone.h"
37 37
38static uint profile_numbers[5] = {0, 1, 2, 3, 4}; 38static uint profile_numbers[5] = {0, 1, 2, 3, 4};
@@ -58,12 +58,8 @@ static void kone_set_settings_checksum(struct kone_settings *settings)
58 */ 58 */
59static int kone_check_write(struct usb_device *usb_dev) 59static int kone_check_write(struct usb_device *usb_dev)
60{ 60{
61 int len; 61 int retval;
62 unsigned char *data; 62 uint8_t data;
63
64 data = kmalloc(1, GFP_KERNEL);
65 if (!data)
66 return -ENOMEM;
67 63
68 do { 64 do {
69 /* 65 /*
@@ -72,56 +68,36 @@ static int kone_check_write(struct usb_device *usb_dev)
72 */ 68 */
73 msleep(80); 69 msleep(80);
74 70
75 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 71 retval = roccat_common_receive(usb_dev,
76 USB_REQ_CLEAR_FEATURE, 72 kone_command_confirm_write, &data, 1);
77 USB_TYPE_CLASS | USB_RECIP_INTERFACE | 73 if (retval)
78 USB_DIR_IN, 74 return retval;
79 kone_command_confirm_write, 0, data, 1,
80 USB_CTRL_SET_TIMEOUT);
81
82 if (len != 1) {
83 kfree(data);
84 return -EIO;
85 }
86 75
87 /* 76 /*
88 * value of 3 seems to mean something like 77 * value of 3 seems to mean something like
89 * "not finished yet, but it looks good" 78 * "not finished yet, but it looks good"
90 * So check again after a moment. 79 * So check again after a moment.
91 */ 80 */
92 } while (*data == 3); 81 } while (data == 3);
93 82
94 if (*data == 1) { /* everything alright */ 83 if (data == 1) /* everything alright */
95 kfree(data);
96 return 0; 84 return 0;
97 } else { /* unknown answer */ 85
98 hid_err(usb_dev, "got retval %d when checking write\n", *data); 86 /* unknown answer */
99 kfree(data); 87 hid_err(usb_dev, "got retval %d when checking write\n", data);
100 return -EIO; 88 return -EIO;
101 }
102} 89}
103 90
104/* 91/*
105 * Reads settings from mouse and stores it in @buf 92 * Reads settings from mouse and stores it in @buf
106 * @buf has to be alloced with GFP_KERNEL
107 * On success returns 0 93 * On success returns 0
108 * On failure returns errno 94 * On failure returns errno
109 */ 95 */
110static int kone_get_settings(struct usb_device *usb_dev, 96static int kone_get_settings(struct usb_device *usb_dev,
111 struct kone_settings *buf) 97 struct kone_settings *buf)
112{ 98{
113 int len; 99 return roccat_common_receive(usb_dev, kone_command_settings, buf,
114 100 sizeof(struct kone_settings));
115 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
116 USB_REQ_CLEAR_FEATURE,
117 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
118 kone_command_settings, 0, buf,
119 sizeof(struct kone_settings), USB_CTRL_SET_TIMEOUT);
120
121 if (len != sizeof(struct kone_settings))
122 return -EIO;
123
124 return 0;
125} 101}
126 102
127/* 103/*
@@ -132,22 +108,12 @@ static int kone_get_settings(struct usb_device *usb_dev,
132static int kone_set_settings(struct usb_device *usb_dev, 108static int kone_set_settings(struct usb_device *usb_dev,
133 struct kone_settings const *settings) 109 struct kone_settings const *settings)
134{ 110{
135 int len; 111 int retval;
136 112 retval = roccat_common_send(usb_dev, kone_command_settings,
137 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 113 settings, sizeof(struct kone_settings));
138 USB_REQ_SET_CONFIGURATION, 114 if (retval)
139 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 115 return retval;
140 kone_command_settings, 0, (char *)settings, 116 return kone_check_write(usb_dev);
141 sizeof(struct kone_settings),
142 USB_CTRL_SET_TIMEOUT);
143
144 if (len != sizeof(struct kone_settings))
145 return -EIO;
146
147 if (kone_check_write(usb_dev))
148 return -EIO;
149
150 return 0;
151} 117}
152 118
153/* 119/*
@@ -193,7 +159,7 @@ static int kone_set_profile(struct usb_device *usb_dev,
193 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 159 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
194 USB_REQ_SET_CONFIGURATION, 160 USB_REQ_SET_CONFIGURATION,
195 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 161 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
196 kone_command_profile, number, (char *)profile, 162 kone_command_profile, number, (void *)profile,
197 sizeof(struct kone_profile), 163 sizeof(struct kone_profile),
198 USB_CTRL_SET_TIMEOUT); 164 USB_CTRL_SET_TIMEOUT);
199 165
@@ -213,24 +179,15 @@ static int kone_set_profile(struct usb_device *usb_dev,
213 */ 179 */
214static int kone_get_weight(struct usb_device *usb_dev, int *result) 180static int kone_get_weight(struct usb_device *usb_dev, int *result)
215{ 181{
216 int len; 182 int retval;
217 uint8_t *data; 183 uint8_t data;
218 184
219 data = kmalloc(1, GFP_KERNEL); 185 retval = roccat_common_receive(usb_dev, kone_command_weight, &data, 1);
220 if (!data)
221 return -ENOMEM;
222 186
223 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 187 if (retval)
224 USB_REQ_CLEAR_FEATURE, 188 return retval;
225 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
226 kone_command_weight, 0, data, 1, USB_CTRL_SET_TIMEOUT);
227 189
228 if (len != 1) { 190 *result = (int)data;
229 kfree(data);
230 return -EIO;
231 }
232 *result = (int)*data;
233 kfree(data);
234 return 0; 191 return 0;
235} 192}
236 193
@@ -241,25 +198,15 @@ static int kone_get_weight(struct usb_device *usb_dev, int *result)
241 */ 198 */
242static int kone_get_firmware_version(struct usb_device *usb_dev, int *result) 199static int kone_get_firmware_version(struct usb_device *usb_dev, int *result)
243{ 200{
244 int len; 201 int retval;
245 unsigned char *data; 202 uint16_t data;
246
247 data = kmalloc(2, GFP_KERNEL);
248 if (!data)
249 return -ENOMEM;
250 203
251 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 204 retval = roccat_common_receive(usb_dev, kone_command_firmware_version,
252 USB_REQ_CLEAR_FEATURE, 205 &data, 2);
253 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 206 if (retval)
254 kone_command_firmware_version, 0, data, 2, 207 return retval;
255 USB_CTRL_SET_TIMEOUT);
256 208
257 if (len != 2) { 209 *result = le16_to_cpu(data);
258 kfree(data);
259 return -EIO;
260 }
261 *result = le16_to_cpu(*data);
262 kfree(data);
263 return 0; 210 return 0;
264} 211}
265 212
@@ -435,23 +382,9 @@ static ssize_t kone_sysfs_show_tcu(struct device *dev,
435 382
436static int kone_tcu_command(struct usb_device *usb_dev, int number) 383static int kone_tcu_command(struct usb_device *usb_dev, int number)
437{ 384{
438 int len; 385 unsigned char value;
439 char *value; 386 value = number;
440 387 return roccat_common_send(usb_dev, kone_command_calibrate, &value, 1);
441 value = kmalloc(1, GFP_KERNEL);
442 if (!value)
443 return -ENOMEM;
444
445 *value = number;
446
447 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
448 USB_REQ_SET_CONFIGURATION,
449 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
450 kone_command_calibrate, 0, value, 1,
451 USB_CTRL_SET_TIMEOUT);
452
453 kfree(value);
454 return ((len != 1) ? -EIO : 0);
455} 388}
456 389
457/* 390/*
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c
index c826c0d6c872..d1c3a02109a8 100644
--- a/drivers/hid/hid-roccat-koneplus.c
+++ b/drivers/hid/hid-roccat-koneplus.c
@@ -19,11 +19,11 @@
19#include <linux/device.h> 19#include <linux/device.h>
20#include <linux/input.h> 20#include <linux/input.h>
21#include <linux/hid.h> 21#include <linux/hid.h>
22#include <linux/usb.h>
23#include <linux/module.h> 22#include <linux/module.h>
24#include <linux/slab.h> 23#include <linux/slab.h>
25#include "hid-ids.h" 24#include "hid-ids.h"
26#include "hid-roccat.h" 25#include "hid-roccat.h"
26#include "hid-roccat-common.h"
27#include "hid-roccat-koneplus.h" 27#include "hid-roccat-koneplus.h"
28 28
29static uint profile_numbers[5] = {0, 1, 2, 3, 4}; 29static uint profile_numbers[5] = {0, 1, 2, 3, 4};
@@ -39,110 +39,63 @@ static void koneplus_profile_activated(struct koneplus_device *koneplus,
39static int koneplus_send_control(struct usb_device *usb_dev, uint value, 39static int koneplus_send_control(struct usb_device *usb_dev, uint value,
40 enum koneplus_control_requests request) 40 enum koneplus_control_requests request)
41{ 41{
42 int len; 42 struct koneplus_control control;
43 struct koneplus_control *control;
44 43
45 if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || 44 if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS ||
46 request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && 45 request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) &&
47 value > 4) 46 value > 4)
48 return -EINVAL; 47 return -EINVAL;
49 48
50 control = kmalloc(sizeof(struct koneplus_control), GFP_KERNEL); 49 control.command = KONEPLUS_COMMAND_CONTROL;
51 if (!control) 50 control.value = value;
52 return -ENOMEM; 51 control.request = request;
53 52
54 control->command = KONEPLUS_COMMAND_CONTROL; 53 return roccat_common_send(usb_dev, KONEPLUS_USB_COMMAND_CONTROL,
55 control->value = value; 54 &control, sizeof(struct koneplus_control));
56 control->request = request;
57
58 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
59 USB_REQ_SET_CONFIGURATION,
60 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
61 KONEPLUS_USB_COMMAND_CONTROL, 0, control,
62 sizeof(struct koneplus_control),
63 USB_CTRL_SET_TIMEOUT);
64
65 kfree(control);
66
67 if (len != sizeof(struct koneplus_control))
68 return len;
69
70 return 0;
71}
72
73static int koneplus_receive(struct usb_device *usb_dev, uint usb_command,
74 void *buf, uint size) {
75 int len;
76
77 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
78 USB_REQ_CLEAR_FEATURE,
79 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
80 usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
81
82 return (len != size) ? -EIO : 0;
83} 55}
84 56
85static int koneplus_receive_control_status(struct usb_device *usb_dev) 57static int koneplus_receive_control_status(struct usb_device *usb_dev)
86{ 58{
87 int retval; 59 int retval;
88 struct koneplus_control *control; 60 struct koneplus_control control;
89
90 control = kmalloc(sizeof(struct koneplus_control), GFP_KERNEL);
91 if (!control)
92 return -ENOMEM;
93 61
94 do { 62 do {
95 retval = koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_CONTROL, 63 retval = roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_CONTROL,
96 control, sizeof(struct koneplus_control)); 64 &control, sizeof(struct koneplus_control));
97 65
98 /* check if we get a completely wrong answer */ 66 /* check if we get a completely wrong answer */
99 if (retval) 67 if (retval)
100 goto out; 68 return retval;
101 69
102 if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_OK) { 70 if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OK)
103 retval = 0; 71 return 0;
104 goto out;
105 }
106 72
107 /* indicates that hardware needs some more time to complete action */ 73 /* indicates that hardware needs some more time to complete action */
108 if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_WAIT) { 74 if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_WAIT) {
109 msleep(500); /* windows driver uses 1000 */ 75 msleep(500); /* windows driver uses 1000 */
110 continue; 76 continue;
111 } 77 }
112 78
113 /* seems to be critical - replug necessary */ 79 /* seems to be critical - replug necessary */
114 if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD) { 80 if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD)
115 retval = -EINVAL; 81 return -EINVAL;
116 goto out;
117 }
118 82
119 hid_err(usb_dev, "koneplus_receive_control_status: " 83 hid_err(usb_dev, "koneplus_receive_control_status: "
120 "unknown response value 0x%x\n", control->value); 84 "unknown response value 0x%x\n", control.value);
121 retval = -EINVAL; 85 return -EINVAL;
122 goto out;
123
124 } while (1); 86 } while (1);
125out:
126 kfree(control);
127 return retval;
128} 87}
129 88
130static int koneplus_send(struct usb_device *usb_dev, uint command, 89static int koneplus_send(struct usb_device *usb_dev, uint command,
131 void *buf, uint size) { 90 void const *buf, uint size)
132 int len; 91{
133 92 int retval;
134 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
135 USB_REQ_SET_CONFIGURATION,
136 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
137 command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
138
139 if (len != size)
140 return -EIO;
141 93
142 if (koneplus_receive_control_status(usb_dev)) 94 retval = roccat_common_send(usb_dev, command, buf, size);
143 return -EIO; 95 if (retval)
96 return retval;
144 97
145 return 0; 98 return koneplus_receive_control_status(usb_dev);
146} 99}
147 100
148static int koneplus_select_profile(struct usb_device *usb_dev, uint number, 101static int koneplus_select_profile(struct usb_device *usb_dev, uint number,
@@ -167,7 +120,7 @@ static int koneplus_select_profile(struct usb_device *usb_dev, uint number,
167static int koneplus_get_info(struct usb_device *usb_dev, 120static int koneplus_get_info(struct usb_device *usb_dev,
168 struct koneplus_info *buf) 121 struct koneplus_info *buf)
169{ 122{
170 return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_INFO, 123 return roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_INFO,
171 buf, sizeof(struct koneplus_info)); 124 buf, sizeof(struct koneplus_info));
172} 125}
173 126
@@ -181,7 +134,7 @@ static int koneplus_get_profile_settings(struct usb_device *usb_dev,
181 if (retval) 134 if (retval)
182 return retval; 135 return retval;
183 136
184 return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS, 137 return roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS,
185 buf, sizeof(struct koneplus_profile_settings)); 138 buf, sizeof(struct koneplus_profile_settings));
186} 139}
187 140
@@ -189,7 +142,7 @@ static int koneplus_set_profile_settings(struct usb_device *usb_dev,
189 struct koneplus_profile_settings const *settings) 142 struct koneplus_profile_settings const *settings)
190{ 143{
191 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS, 144 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS,
192 (void *)settings, sizeof(struct koneplus_profile_settings)); 145 settings, sizeof(struct koneplus_profile_settings));
193} 146}
194 147
195static int koneplus_get_profile_buttons(struct usb_device *usb_dev, 148static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
@@ -202,7 +155,7 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
202 if (retval) 155 if (retval)
203 return retval; 156 return retval;
204 157
205 return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS, 158 return roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS,
206 buf, sizeof(struct koneplus_profile_buttons)); 159 buf, sizeof(struct koneplus_profile_buttons));
207} 160}
208 161
@@ -210,29 +163,19 @@ static int koneplus_set_profile_buttons(struct usb_device *usb_dev,
210 struct koneplus_profile_buttons const *buttons) 163 struct koneplus_profile_buttons const *buttons)
211{ 164{
212 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS, 165 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS,
213 (void *)buttons, sizeof(struct koneplus_profile_buttons)); 166 buttons, sizeof(struct koneplus_profile_buttons));
214} 167}
215 168
216/* retval is 0-4 on success, < 0 on error */ 169/* retval is 0-4 on success, < 0 on error */
217static int koneplus_get_startup_profile(struct usb_device *usb_dev) 170static int koneplus_get_startup_profile(struct usb_device *usb_dev)
218{ 171{
219 struct koneplus_startup_profile *buf; 172 struct koneplus_startup_profile buf;
220 int retval; 173 int retval;
221 174
222 buf = kmalloc(sizeof(struct koneplus_startup_profile), GFP_KERNEL); 175 retval = roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE,
223 if (buf == NULL) 176 &buf, sizeof(struct koneplus_startup_profile));
224 return -ENOMEM;
225
226 retval = koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE,
227 buf, sizeof(struct koneplus_startup_profile));
228 177
229 if (retval) 178 return retval ? retval : buf.startup_profile;
230 goto out;
231
232 retval = buf->startup_profile;
233out:
234 kfree(buf);
235 return retval;
236} 179}
237 180
238static int koneplus_set_startup_profile(struct usb_device *usb_dev, 181static int koneplus_set_startup_profile(struct usb_device *usb_dev,
@@ -245,7 +188,7 @@ static int koneplus_set_startup_profile(struct usb_device *usb_dev,
245 buf.startup_profile = startup_profile; 188 buf.startup_profile = startup_profile;
246 189
247 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE, 190 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE,
248 (char *)&buf, sizeof(struct koneplus_profile_buttons)); 191 &buf, sizeof(struct koneplus_profile_buttons));
249} 192}
250 193
251static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, 194static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj,
@@ -265,7 +208,7 @@ static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj,
265 return -EINVAL; 208 return -EINVAL;
266 209
267 mutex_lock(&koneplus->koneplus_lock); 210 mutex_lock(&koneplus->koneplus_lock);
268 retval = koneplus_receive(usb_dev, command, buf, real_size); 211 retval = roccat_common_receive(usb_dev, command, buf, real_size);
269 mutex_unlock(&koneplus->koneplus_lock); 212 mutex_unlock(&koneplus->koneplus_lock);
270 213
271 if (retval) 214 if (retval)
@@ -288,7 +231,7 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj,
288 return -EINVAL; 231 return -EINVAL;
289 232
290 mutex_lock(&koneplus->koneplus_lock); 233 mutex_lock(&koneplus->koneplus_lock);
291 retval = koneplus_send(usb_dev, command, (void *)buf, real_size); 234 retval = koneplus_send(usb_dev, command, buf, real_size);
292 mutex_unlock(&koneplus->koneplus_lock); 235 mutex_unlock(&koneplus->koneplus_lock);
293 236
294 if (retval) 237 if (retval)
@@ -352,7 +295,7 @@ static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp,
352 count = sizeof(struct koneplus_profile_settings) - off; 295 count = sizeof(struct koneplus_profile_settings) - off;
353 296
354 mutex_lock(&koneplus->koneplus_lock); 297 mutex_lock(&koneplus->koneplus_lock);
355 memcpy(buf, ((void const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off, 298 memcpy(buf, ((char const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off,
356 count); 299 count);
357 mutex_unlock(&koneplus->koneplus_lock); 300 mutex_unlock(&koneplus->koneplus_lock);
358 301
@@ -411,7 +354,7 @@ static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp,
411 count = sizeof(struct koneplus_profile_buttons) - off; 354 count = sizeof(struct koneplus_profile_buttons) - off;
412 355
413 mutex_lock(&koneplus->koneplus_lock); 356 mutex_lock(&koneplus->koneplus_lock);
414 memcpy(buf, ((void const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off, 357 memcpy(buf, ((char const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off,
415 count); 358 count);
416 mutex_unlock(&koneplus->koneplus_lock); 359 mutex_unlock(&koneplus->koneplus_lock);
417 360
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c
index 02c58e015bee..abe77d3e6d8b 100644
--- a/drivers/hid/hid-roccat-pyra.c
+++ b/drivers/hid/hid-roccat-pyra.c
@@ -20,11 +20,11 @@
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/usb.h>
24#include <linux/module.h> 23#include <linux/module.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
26#include "hid-ids.h" 25#include "hid-ids.h"
27#include "hid-roccat.h" 26#include "hid-roccat.h"
27#include "hid-roccat-common.h"
28#include "hid-roccat-pyra.h" 28#include "hid-roccat-pyra.h"
29 29
30static uint profile_numbers[5] = {0, 1, 2, 3, 4}; 30static uint profile_numbers[5] = {0, 1, 2, 3, 4};
@@ -42,7 +42,6 @@ static void profile_activated(struct pyra_device *pyra,
42static int pyra_send_control(struct usb_device *usb_dev, int value, 42static int pyra_send_control(struct usb_device *usb_dev, int value,
43 enum pyra_control_requests request) 43 enum pyra_control_requests request)
44{ 44{
45 int len;
46 struct pyra_control control; 45 struct pyra_control control;
47 46
48 if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS || 47 if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS ||
@@ -54,47 +53,31 @@ static int pyra_send_control(struct usb_device *usb_dev, int value,
54 control.value = value; 53 control.value = value;
55 control.request = request; 54 control.request = request;
56 55
57 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 56 return roccat_common_send(usb_dev, PYRA_USB_COMMAND_CONTROL,
58 USB_REQ_SET_CONFIGURATION, 57 &control, sizeof(struct pyra_control));
59 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
60 PYRA_USB_COMMAND_CONTROL, 0, (char *)&control,
61 sizeof(struct pyra_control),
62 USB_CTRL_SET_TIMEOUT);
63
64 if (len != sizeof(struct pyra_control))
65 return len;
66
67 return 0;
68} 58}
69 59
70static int pyra_receive_control_status(struct usb_device *usb_dev) 60static int pyra_receive_control_status(struct usb_device *usb_dev)
71{ 61{
72 int len; 62 int retval;
73 struct pyra_control control; 63 struct pyra_control control;
74 64
75 do { 65 do {
76 msleep(10); 66 msleep(10);
77 67 retval = roccat_common_receive(usb_dev, PYRA_USB_COMMAND_CONTROL,
78 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 68 &control, sizeof(struct pyra_control));
79 USB_REQ_CLEAR_FEATURE,
80 USB_TYPE_CLASS | USB_RECIP_INTERFACE |
81 USB_DIR_IN,
82 PYRA_USB_COMMAND_CONTROL, 0, (char *)&control,
83 sizeof(struct pyra_control),
84 USB_CTRL_SET_TIMEOUT);
85 69
86 /* requested too early, try again */ 70 /* requested too early, try again */
87 } while (len == -EPROTO); 71 } while (retval == -EPROTO);
88 72
89 if (len == sizeof(struct pyra_control) && 73 if (!retval && control.command == PYRA_COMMAND_CONTROL &&
90 control.command == PYRA_COMMAND_CONTROL &&
91 control.request == PYRA_CONTROL_REQUEST_STATUS && 74 control.request == PYRA_CONTROL_REQUEST_STATUS &&
92 control.value == 1) 75 control.value == 1)
93 return 0; 76 return 0;
94 else { 77 else {
95 hid_err(usb_dev, "receive control status: unknown response 0x%x 0x%x\n", 78 hid_err(usb_dev, "receive control status: unknown response 0x%x 0x%x\n",
96 control.request, control.value); 79 control.request, control.value);
97 return -EINVAL; 80 return retval ? retval : -EINVAL;
98 } 81 }
99} 82}
100 83
@@ -102,125 +85,72 @@ static int pyra_get_profile_settings(struct usb_device *usb_dev,
102 struct pyra_profile_settings *buf, int number) 85 struct pyra_profile_settings *buf, int number)
103{ 86{
104 int retval; 87 int retval;
105
106 retval = pyra_send_control(usb_dev, number, 88 retval = pyra_send_control(usb_dev, number,
107 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS); 89 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
108
109 if (retval) 90 if (retval)
110 return retval; 91 return retval;
111 92 return roccat_common_receive(usb_dev, PYRA_USB_COMMAND_PROFILE_SETTINGS,
112 retval = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 93 buf, sizeof(struct pyra_profile_settings));
113 USB_REQ_CLEAR_FEATURE,
114 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
115 PYRA_USB_COMMAND_PROFILE_SETTINGS, 0, (char *)buf,
116 sizeof(struct pyra_profile_settings),
117 USB_CTRL_SET_TIMEOUT);
118
119 if (retval != sizeof(struct pyra_profile_settings))
120 return retval;
121
122 return 0;
123} 94}
124 95
125static int pyra_get_profile_buttons(struct usb_device *usb_dev, 96static int pyra_get_profile_buttons(struct usb_device *usb_dev,
126 struct pyra_profile_buttons *buf, int number) 97 struct pyra_profile_buttons *buf, int number)
127{ 98{
128 int retval; 99 int retval;
129
130 retval = pyra_send_control(usb_dev, number, 100 retval = pyra_send_control(usb_dev, number,
131 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS); 101 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
132
133 if (retval) 102 if (retval)
134 return retval; 103 return retval;
135 104 return roccat_common_receive(usb_dev, PYRA_USB_COMMAND_PROFILE_BUTTONS,
136 retval = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 105 buf, sizeof(struct pyra_profile_buttons));
137 USB_REQ_CLEAR_FEATURE,
138 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
139 PYRA_USB_COMMAND_PROFILE_BUTTONS, 0, (char *)buf,
140 sizeof(struct pyra_profile_buttons),
141 USB_CTRL_SET_TIMEOUT);
142
143 if (retval != sizeof(struct pyra_profile_buttons))
144 return retval;
145
146 return 0;
147} 106}
148 107
149static int pyra_get_settings(struct usb_device *usb_dev, 108static int pyra_get_settings(struct usb_device *usb_dev,
150 struct pyra_settings *buf) 109 struct pyra_settings *buf)
151{ 110{
152 int len; 111 return roccat_common_receive(usb_dev, PYRA_USB_COMMAND_SETTINGS,
153 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 112 buf, sizeof(struct pyra_settings));
154 USB_REQ_CLEAR_FEATURE,
155 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
156 PYRA_USB_COMMAND_SETTINGS, 0, buf,
157 sizeof(struct pyra_settings), USB_CTRL_SET_TIMEOUT);
158 if (len != sizeof(struct pyra_settings))
159 return -EIO;
160 return 0;
161} 113}
162 114
163static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf) 115static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf)
164{ 116{
165 int len; 117 return roccat_common_receive(usb_dev, PYRA_USB_COMMAND_INFO,
166 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 118 buf, sizeof(struct pyra_info));
167 USB_REQ_CLEAR_FEATURE, 119}
168 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 120
169 PYRA_USB_COMMAND_INFO, 0, buf, 121static int pyra_send(struct usb_device *usb_dev, uint command,
170 sizeof(struct pyra_info), USB_CTRL_SET_TIMEOUT); 122 void const *buf, uint size)
171 if (len != sizeof(struct pyra_info)) 123{
172 return -EIO; 124 int retval;
173 return 0; 125 retval = roccat_common_send(usb_dev, command, buf, size);
126 if (retval)
127 return retval;
128 return pyra_receive_control_status(usb_dev);
174} 129}
175 130
176static int pyra_set_profile_settings(struct usb_device *usb_dev, 131static int pyra_set_profile_settings(struct usb_device *usb_dev,
177 struct pyra_profile_settings const *settings) 132 struct pyra_profile_settings const *settings)
178{ 133{
179 int len; 134 return pyra_send(usb_dev, PYRA_USB_COMMAND_PROFILE_SETTINGS, settings,
180 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 135 sizeof(struct pyra_profile_settings));
181 USB_REQ_SET_CONFIGURATION,
182 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
183 PYRA_USB_COMMAND_PROFILE_SETTINGS, 0, (char *)settings,
184 sizeof(struct pyra_profile_settings),
185 USB_CTRL_SET_TIMEOUT);
186 if (len != sizeof(struct pyra_profile_settings))
187 return -EIO;
188 if (pyra_receive_control_status(usb_dev))
189 return -EIO;
190 return 0;
191} 136}
192 137
193static int pyra_set_profile_buttons(struct usb_device *usb_dev, 138static int pyra_set_profile_buttons(struct usb_device *usb_dev,
194 struct pyra_profile_buttons const *buttons) 139 struct pyra_profile_buttons const *buttons)
195{ 140{
196 int len; 141 return pyra_send(usb_dev, PYRA_USB_COMMAND_PROFILE_BUTTONS, buttons,
197 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 142 sizeof(struct pyra_profile_buttons));
198 USB_REQ_SET_CONFIGURATION,
199 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
200 PYRA_USB_COMMAND_PROFILE_BUTTONS, 0, (char *)buttons,
201 sizeof(struct pyra_profile_buttons),
202 USB_CTRL_SET_TIMEOUT);
203 if (len != sizeof(struct pyra_profile_buttons))
204 return -EIO;
205 if (pyra_receive_control_status(usb_dev))
206 return -EIO;
207 return 0;
208} 143}
209 144
210static int pyra_set_settings(struct usb_device *usb_dev, 145static int pyra_set_settings(struct usb_device *usb_dev,
211 struct pyra_settings const *settings) 146 struct pyra_settings const *settings)
212{ 147{
213 int len; 148 int retval;
214 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 149 retval = roccat_common_send(usb_dev, PYRA_USB_COMMAND_SETTINGS, settings,
215 USB_REQ_SET_CONFIGURATION, 150 sizeof(struct pyra_settings));
216 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 151 if (retval)
217 PYRA_USB_COMMAND_SETTINGS, 0, (char *)settings, 152 return retval;
218 sizeof(struct pyra_settings), USB_CTRL_SET_TIMEOUT); 153 return pyra_receive_control_status(usb_dev);
219 if (len != sizeof(struct pyra_settings))
220 return -EIO;
221 if (pyra_receive_control_status(usb_dev))
222 return -EIO;
223 return 0;
224} 154}
225 155
226static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, 156static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
@@ -521,21 +451,16 @@ static struct bin_attribute pyra_bin_attributes[] = {
521static int pyra_init_pyra_device_struct(struct usb_device *usb_dev, 451static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
522 struct pyra_device *pyra) 452 struct pyra_device *pyra)
523{ 453{
524 struct pyra_info *info; 454 struct pyra_info info;
525 int retval, i; 455 int retval, i;
526 456
527 mutex_init(&pyra->pyra_lock); 457 mutex_init(&pyra->pyra_lock);
528 458
529 info = kmalloc(sizeof(struct pyra_info), GFP_KERNEL); 459 retval = pyra_get_info(usb_dev, &info);
530 if (!info) 460 if (retval)
531 return -ENOMEM;
532 retval = pyra_get_info(usb_dev, info);
533 if (retval) {
534 kfree(info);
535 return retval; 461 return retval;
536 } 462
537 pyra->firmware_version = info->firmware_version; 463 pyra->firmware_version = info.firmware_version;
538 kfree(info);
539 464
540 retval = pyra_get_settings(usb_dev, &pyra->settings); 465 retval = pyra_get_settings(usb_dev, &pyra->settings);
541 if (retval) 466 if (retval)