aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikolai Kondrashov <spbnick@gmail.com>2010-08-06 15:03:06 -0400
committerJiri Kosina <jkosina@suse.cz>2010-08-09 13:52:42 -0400
commit73e4008ddddc84d5f2499c17012b340a0dae153e (patch)
treed3adfa8c5792e71c21cb7a9cd18517cce9c92685
parent3cfc2c42c1cbc8e238bb9c0612c0df4565e3a8b4 (diff)
HID: allow resizing and replacing report descriptors
Update hid_driver's report_fixup prototype to allow changing report descriptor size and/or returning completely different report descriptor. Update existing usage accordingly. This is to give more freedom in descriptor fixup and to allow having a whole fixed descriptor in the code for the sake of readability. Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-apple.c7
-rw-r--r--drivers/hid/hid-cherry.c7
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-cypress.c9
-rw-r--r--drivers/hid/hid-elecom.c7
-rw-r--r--drivers/hid/hid-kye.c7
-rw-r--r--drivers/hid/hid-lg.c9
-rw-r--r--drivers/hid/hid-microsoft.c7
-rw-r--r--drivers/hid/hid-monterey.c7
-rw-r--r--drivers/hid/hid-ortek.c7
-rw-r--r--drivers/hid/hid-petalynx.c7
-rw-r--r--drivers/hid/hid-prodikeys.c7
-rw-r--r--drivers/hid/hid-samsung.c20
-rw-r--r--drivers/hid/hid-sony.c7
-rw-r--r--drivers/hid/hid-sunplus.c7
-rw-r--r--drivers/hid/hid-zydacron.c7
-rw-r--r--include/linux/hid.h4
17 files changed, 72 insertions, 56 deletions
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index bba05d0a8980..eaeca564a8d3 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -246,17 +246,18 @@ static int apple_event(struct hid_device *hdev, struct hid_field *field,
246/* 246/*
247 * MacBook JIS keyboard has wrong logical maximum 247 * MacBook JIS keyboard has wrong logical maximum
248 */ 248 */
249static void apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, 249static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
250 unsigned int rsize) 250 unsigned int *rsize)
251{ 251{
252 struct apple_sc *asc = hid_get_drvdata(hdev); 252 struct apple_sc *asc = hid_get_drvdata(hdev);
253 253
254 if ((asc->quirks & APPLE_RDESC_JIS) && rsize >= 60 && 254 if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 &&
255 rdesc[53] == 0x65 && rdesc[59] == 0x65) { 255 rdesc[53] == 0x65 && rdesc[59] == 0x65) {
256 dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report " 256 dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report "
257 "descriptor\n"); 257 "descriptor\n");
258 rdesc[53] = rdesc[59] = 0xe7; 258 rdesc[53] = rdesc[59] = 0xe7;
259 } 259 }
260 return rdesc;
260} 261}
261 262
262static void apple_setup_input(struct input_dev *input) 263static void apple_setup_input(struct input_dev *input)
diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c
index 24663a8717b1..e880086c2311 100644
--- a/drivers/hid/hid-cherry.c
+++ b/drivers/hid/hid-cherry.c
@@ -26,15 +26,16 @@
26 * Cherry Cymotion keyboard have an invalid HID report descriptor, 26 * Cherry Cymotion keyboard have an invalid HID report descriptor,
27 * that needs fixing before we can parse it. 27 * that needs fixing before we can parse it.
28 */ 28 */
29static void ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, 29static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc,
30 unsigned int rsize) 30 unsigned int *rsize)
31{ 31{
32 if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { 32 if (*rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
33 dev_info(&hdev->dev, "fixing up Cherry Cymotion report " 33 dev_info(&hdev->dev, "fixing up Cherry Cymotion report "
34 "descriptor\n"); 34 "descriptor\n");
35 rdesc[11] = rdesc[16] = 0xff; 35 rdesc[11] = rdesc[16] = 0xff;
36 rdesc[12] = rdesc[17] = 0x03; 36 rdesc[12] = rdesc[17] = 0x03;
37 } 37 }
38 return rdesc;
38} 39}
39 40
40#define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 41#define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index e635199a0cd2..ec20e83cbd61 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -651,7 +651,7 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
651 }; 651 };
652 652
653 if (device->driver->report_fixup) 653 if (device->driver->report_fixup)
654 device->driver->report_fixup(device, start, size); 654 start = device->driver->report_fixup(device, start, &size);
655 655
656 device->rdesc = kmemdup(start, size, GFP_KERNEL); 656 device->rdesc = kmemdup(start, size, GFP_KERNEL);
657 if (device->rdesc == NULL) 657 if (device->rdesc == NULL)
diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
index 998b6f443d7d..4cd0e2345991 100644
--- a/drivers/hid/hid-cypress.c
+++ b/drivers/hid/hid-cypress.c
@@ -31,16 +31,16 @@
31 * Some USB barcode readers from cypress have usage min and usage max in 31 * Some USB barcode readers from cypress have usage min and usage max in
32 * the wrong order 32 * the wrong order
33 */ 33 */
34static void cp_report_fixup(struct hid_device *hdev, __u8 *rdesc, 34static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
35 unsigned int rsize) 35 unsigned int *rsize)
36{ 36{
37 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); 37 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
38 unsigned int i; 38 unsigned int i;
39 39
40 if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX)) 40 if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX))
41 return; 41 return rdesc;
42 42
43 for (i = 0; i < rsize - 4; i++) 43 for (i = 0; i < *rsize - 4; i++)
44 if (rdesc[i] == 0x29 && rdesc[i + 2] == 0x19) { 44 if (rdesc[i] == 0x29 && rdesc[i + 2] == 0x19) {
45 __u8 tmp; 45 __u8 tmp;
46 46
@@ -50,6 +50,7 @@ static void cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
50 rdesc[i + 3] = rdesc[i + 1]; 50 rdesc[i + 3] = rdesc[i + 1];
51 rdesc[i + 1] = tmp; 51 rdesc[i + 1] = tmp;
52 } 52 }
53 return rdesc;
53} 54}
54 55
55static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi, 56static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi,
diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c
index 7a40878f46b4..6e31f305397d 100644
--- a/drivers/hid/hid-elecom.c
+++ b/drivers/hid/hid-elecom.c
@@ -20,14 +20,15 @@
20 20
21#include "hid-ids.h" 21#include "hid-ids.h"
22 22
23static void elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, 23static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
24 unsigned int rsize) 24 unsigned int *rsize)
25{ 25{
26 if (rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) { 26 if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
27 dev_info(&hdev->dev, "Fixing up Elecom BM084 " 27 dev_info(&hdev->dev, "Fixing up Elecom BM084 "
28 "report descriptor.\n"); 28 "report descriptor.\n");
29 rdesc[47] = 0x00; 29 rdesc[47] = 0x00;
30 } 30 }
31 return rdesc;
31} 32}
32 33
33static const struct hid_device_id elecom_devices[] = { 34static const struct hid_device_id elecom_devices[] = {
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c
index f8871712b7b5..817247ee006c 100644
--- a/drivers/hid/hid-kye.c
+++ b/drivers/hid/hid-kye.c
@@ -23,10 +23,10 @@
23 * - report size 8 count 1 must be size 1 count 8 for button bitfield 23 * - report size 8 count 1 must be size 1 count 8 for button bitfield
24 * - change the button usage range to 4-7 for the extra buttons 24 * - change the button usage range to 4-7 for the extra buttons
25 */ 25 */
26static void kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, 26static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
27 unsigned int rsize) 27 unsigned int *rsize)
28{ 28{
29 if (rsize >= 74 && 29 if (*rsize >= 74 &&
30 rdesc[61] == 0x05 && rdesc[62] == 0x08 && 30 rdesc[61] == 0x05 && rdesc[62] == 0x08 &&
31 rdesc[63] == 0x19 && rdesc[64] == 0x08 && 31 rdesc[63] == 0x19 && rdesc[64] == 0x08 &&
32 rdesc[65] == 0x29 && rdesc[66] == 0x0f && 32 rdesc[65] == 0x29 && rdesc[66] == 0x0f &&
@@ -40,6 +40,7 @@ static void kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
40 rdesc[72] = 0x01; 40 rdesc[72] = 0x01;
41 rdesc[74] = 0x08; 41 rdesc[74] = 0x08;
42 } 42 }
43 return rdesc;
43} 44}
44 45
45static const struct hid_device_id kye_devices[] = { 46static const struct hid_device_id kye_devices[] = {
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index f6433d8050a9..68c0b68856c7 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -41,25 +41,26 @@
41 * above the logical maximum described in descriptor. This extends 41 * above the logical maximum described in descriptor. This extends
42 * the original value of 0x28c of logical maximum to 0x104d 42 * the original value of 0x28c of logical maximum to 0x104d
43 */ 43 */
44static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, 44static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
45 unsigned int rsize) 45 unsigned int *rsize)
46{ 46{
47 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); 47 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
48 48
49 if ((quirks & LG_RDESC) && rsize >= 90 && rdesc[83] == 0x26 && 49 if ((quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 &&
50 rdesc[84] == 0x8c && rdesc[85] == 0x02) { 50 rdesc[84] == 0x8c && rdesc[85] == 0x02) {
51 dev_info(&hdev->dev, "fixing up Logitech keyboard report " 51 dev_info(&hdev->dev, "fixing up Logitech keyboard report "
52 "descriptor\n"); 52 "descriptor\n");
53 rdesc[84] = rdesc[89] = 0x4d; 53 rdesc[84] = rdesc[89] = 0x4d;
54 rdesc[85] = rdesc[90] = 0x10; 54 rdesc[85] = rdesc[90] = 0x10;
55 } 55 }
56 if ((quirks & LG_RDESC_REL_ABS) && rsize >= 50 && 56 if ((quirks & LG_RDESC_REL_ABS) && *rsize >= 50 &&
57 rdesc[32] == 0x81 && rdesc[33] == 0x06 && 57 rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
58 rdesc[49] == 0x81 && rdesc[50] == 0x06) { 58 rdesc[49] == 0x81 && rdesc[50] == 0x06) {
59 dev_info(&hdev->dev, "fixing up rel/abs in Logitech " 59 dev_info(&hdev->dev, "fixing up rel/abs in Logitech "
60 "report descriptor\n"); 60 "report descriptor\n");
61 rdesc[33] = rdesc[50] = 0x02; 61 rdesc[33] = rdesc[50] = 0x02;
62 } 62 }
63 return rdesc;
63} 64}
64 65
65#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 66#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 359cc447c6c6..dc618c33d0a2 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -33,18 +33,19 @@
33 * Microsoft Wireless Desktop Receiver (Model 1028) has 33 * Microsoft Wireless Desktop Receiver (Model 1028) has
34 * 'Usage Min/Max' where it ought to have 'Physical Min/Max' 34 * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
35 */ 35 */
36static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, 36static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
37 unsigned int rsize) 37 unsigned int *rsize)
38{ 38{
39 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); 39 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
40 40
41 if ((quirks & MS_RDESC) && rsize == 571 && rdesc[557] == 0x19 && 41 if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 &&
42 rdesc[559] == 0x29) { 42 rdesc[559] == 0x29) {
43 dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver " 43 dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver "
44 "Model 1028 report descriptor\n"); 44 "Model 1028 report descriptor\n");
45 rdesc[557] = 0x35; 45 rdesc[557] = 0x35;
46 rdesc[559] = 0x45; 46 rdesc[559] = 0x45;
47 } 47 }
48 return rdesc;
48} 49}
49 50
50#define ms_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 51#define ms_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c
index 2cd05aa244b9..c95c31e2d869 100644
--- a/drivers/hid/hid-monterey.c
+++ b/drivers/hid/hid-monterey.c
@@ -22,14 +22,15 @@
22 22
23#include "hid-ids.h" 23#include "hid-ids.h"
24 24
25static void mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, 25static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
26 unsigned int rsize) 26 unsigned int *rsize)
27{ 27{
28 if (rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { 28 if (*rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) {
29 dev_info(&hdev->dev, "fixing up button/consumer in HID report " 29 dev_info(&hdev->dev, "fixing up button/consumer in HID report "
30 "descriptor\n"); 30 "descriptor\n");
31 rdesc[30] = 0x0c; 31 rdesc[30] = 0x0c;
32 } 32 }
33 return rdesc;
33} 34}
34 35
35#define mr_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 36#define mr_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-ortek.c b/drivers/hid/hid-ortek.c
index aa9a960f73a4..2e79716dca31 100644
--- a/drivers/hid/hid-ortek.c
+++ b/drivers/hid/hid-ortek.c
@@ -19,14 +19,15 @@
19 19
20#include "hid-ids.h" 20#include "hid-ids.h"
21 21
22static void ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc, 22static __u8 *ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
23 unsigned int rsize) 23 unsigned int *rsize)
24{ 24{
25 if (rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x01) { 25 if (*rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x01) {
26 dev_info(&hdev->dev, "Fixing up Ortek WKB-2000 " 26 dev_info(&hdev->dev, "Fixing up Ortek WKB-2000 "
27 "report descriptor.\n"); 27 "report descriptor.\n");
28 rdesc[55] = 0x92; 28 rdesc[55] = 0x92;
29 } 29 }
30 return rdesc;
30} 31}
31 32
32static const struct hid_device_id ortek_devices[] = { 33static const struct hid_device_id ortek_devices[] = {
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c
index 500fbd0652dc..308d6ae48a3e 100644
--- a/drivers/hid/hid-petalynx.c
+++ b/drivers/hid/hid-petalynx.c
@@ -23,10 +23,10 @@
23#include "hid-ids.h" 23#include "hid-ids.h"
24 24
25/* Petalynx Maxter Remote has maximum for consumer page set too low */ 25/* Petalynx Maxter Remote has maximum for consumer page set too low */
26static void pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, 26static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc,
27 unsigned int rsize) 27 unsigned int *rsize)
28{ 28{
29 if (rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && 29 if (*rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 &&
30 rdesc[41] == 0x00 && rdesc[59] == 0x26 && 30 rdesc[41] == 0x00 && rdesc[59] == 0x26 &&
31 rdesc[60] == 0xf9 && rdesc[61] == 0x00) { 31 rdesc[60] == 0xf9 && rdesc[61] == 0x00) {
32 dev_info(&hdev->dev, "fixing up Petalynx Maxter Remote report " 32 dev_info(&hdev->dev, "fixing up Petalynx Maxter Remote report "
@@ -34,6 +34,7 @@ static void pl_report_fixup(struct hid_device *hdev, __u8 *rdesc,
34 rdesc[60] = 0xfa; 34 rdesc[60] = 0xfa;
35 rdesc[40] = 0xfa; 35 rdesc[40] = 0xfa;
36 } 36 }
37 return rdesc;
37} 38}
38 39
39#define pl_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 40#define pl_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c
index 845f428b8090..48eab84f53b5 100644
--- a/drivers/hid/hid-prodikeys.c
+++ b/drivers/hid/hid-prodikeys.c
@@ -740,10 +740,10 @@ int pcmidi_snd_terminate(struct pcmidi_snd *pm)
740/* 740/*
741 * PC-MIDI report descriptor for report id is wrong. 741 * PC-MIDI report descriptor for report id is wrong.
742 */ 742 */
743static void pk_report_fixup(struct hid_device *hdev, __u8 *rdesc, 743static __u8 *pk_report_fixup(struct hid_device *hdev, __u8 *rdesc,
744 unsigned int rsize) 744 unsigned int *rsize)
745{ 745{
746 if (rsize == 178 && 746 if (*rsize == 178 &&
747 rdesc[111] == 0x06 && rdesc[112] == 0x00 && 747 rdesc[111] == 0x06 && rdesc[112] == 0x00 &&
748 rdesc[113] == 0xff) { 748 rdesc[113] == 0xff) {
749 dev_info(&hdev->dev, "fixing up pc-midi keyboard report " 749 dev_info(&hdev->dev, "fixing up pc-midi keyboard report "
@@ -751,6 +751,7 @@ static void pk_report_fixup(struct hid_device *hdev, __u8 *rdesc,
751 751
752 rdesc[144] = 0x18; /* report 4: was 0x10 report count */ 752 rdesc[144] = 0x18; /* report 4: was 0x10 report count */
753 } 753 }
754 return rdesc;
754} 755}
755 756
756static int pk_input_mapping(struct hid_device *hdev, struct hid_input *hi, 757static int pk_input_mapping(struct hid_device *hdev, struct hid_input *hi,
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
index bda0fd60c98d..35894444e000 100644
--- a/drivers/hid/hid-samsung.c
+++ b/drivers/hid/hid-samsung.c
@@ -61,10 +61,10 @@ static inline void samsung_irda_dev_trace(struct hid_device *hdev,
61 "descriptor\n", rsize); 61 "descriptor\n", rsize);
62} 62}
63 63
64static void samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc, 64static __u8 *samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,
65 unsigned int rsize) 65 unsigned int *rsize)
66{ 66{
67 if (rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 && 67 if (*rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 &&
68 rdesc[177] == 0x75 && rdesc[178] == 0x30 && 68 rdesc[177] == 0x75 && rdesc[178] == 0x30 &&
69 rdesc[179] == 0x95 && rdesc[180] == 0x01 && 69 rdesc[179] == 0x95 && rdesc[180] == 0x01 &&
70 rdesc[182] == 0x40) { 70 rdesc[182] == 0x40) {
@@ -74,24 +74,25 @@ static void samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,
74 rdesc[180] = 0x06; 74 rdesc[180] = 0x06;
75 rdesc[182] = 0x42; 75 rdesc[182] = 0x42;
76 } else 76 } else
77 if (rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 && 77 if (*rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
78 rdesc[194] == 0x25 && rdesc[195] == 0x12) { 78 rdesc[194] == 0x25 && rdesc[195] == 0x12) {
79 samsung_irda_dev_trace(hdev, 203); 79 samsung_irda_dev_trace(hdev, 203);
80 rdesc[193] = 0x1; 80 rdesc[193] = 0x1;
81 rdesc[195] = 0xf; 81 rdesc[195] = 0xf;
82 } else 82 } else
83 if (rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 && 83 if (*rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
84 rdesc[126] == 0x25 && rdesc[127] == 0x11) { 84 rdesc[126] == 0x25 && rdesc[127] == 0x11) {
85 samsung_irda_dev_trace(hdev, 135); 85 samsung_irda_dev_trace(hdev, 135);
86 rdesc[125] = 0x1; 86 rdesc[125] = 0x1;
87 rdesc[127] = 0xe; 87 rdesc[127] = 0xe;
88 } else 88 } else
89 if (rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 && 89 if (*rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 &&
90 rdesc[162] == 0x25 && rdesc[163] == 0x01) { 90 rdesc[162] == 0x25 && rdesc[163] == 0x01) {
91 samsung_irda_dev_trace(hdev, 171); 91 samsung_irda_dev_trace(hdev, 171);
92 rdesc[161] = 0x1; 92 rdesc[161] = 0x1;
93 rdesc[163] = 0x3; 93 rdesc[163] = 0x3;
94 } 94 }
95 return rdesc;
95} 96}
96 97
97#define samsung_kbd_mouse_map_key_clear(c) \ 98#define samsung_kbd_mouse_map_key_clear(c) \
@@ -130,11 +131,12 @@ static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev,
130 return 1; 131 return 1;
131} 132}
132 133
133static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, 134static __u8 *samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
134 unsigned int rsize) 135 unsigned int *rsize)
135{ 136{
136 if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product) 137 if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product)
137 samsung_irda_report_fixup(hdev, rdesc, rsize); 138 rdesc = samsung_irda_report_fixup(hdev, rdesc, rsize);
139 return rdesc;
138} 140}
139 141
140static int samsung_input_mapping(struct hid_device *hdev, struct hid_input *hi, 142static int samsung_input_mapping(struct hid_device *hdev, struct hid_input *hi,
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 402d5574b574..9fa034915185 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -31,17 +31,18 @@ struct sony_sc {
31}; 31};
32 32
33/* Sony Vaio VGX has wrongly mouse pointer declared as constant */ 33/* Sony Vaio VGX has wrongly mouse pointer declared as constant */
34static void sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, 34static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
35 unsigned int rsize) 35 unsigned int *rsize)
36{ 36{
37 struct sony_sc *sc = hid_get_drvdata(hdev); 37 struct sony_sc *sc = hid_get_drvdata(hdev);
38 38
39 if ((sc->quirks & VAIO_RDESC_CONSTANT) && 39 if ((sc->quirks & VAIO_RDESC_CONSTANT) &&
40 rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) { 40 *rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) {
41 dev_info(&hdev->dev, "Fixing up Sony Vaio VGX report " 41 dev_info(&hdev->dev, "Fixing up Sony Vaio VGX report "
42 "descriptor\n"); 42 "descriptor\n");
43 rdesc[55] = 0x06; 43 rdesc[55] = 0x06;
44 } 44 }
45 return rdesc;
45} 46}
46 47
47/* 48/*
diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c
index 438107d9f1b2..164ed568f6cf 100644
--- a/drivers/hid/hid-sunplus.c
+++ b/drivers/hid/hid-sunplus.c
@@ -22,16 +22,17 @@
22 22
23#include "hid-ids.h" 23#include "hid-ids.h"
24 24
25static void sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, 25static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
26 unsigned int rsize) 26 unsigned int *rsize)
27{ 27{
28 if (rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && 28 if (*rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 &&
29 rdesc[106] == 0x03) { 29 rdesc[106] == 0x03) {
30 dev_info(&hdev->dev, "fixing up Sunplus Wireless Desktop " 30 dev_info(&hdev->dev, "fixing up Sunplus Wireless Desktop "
31 "report descriptor\n"); 31 "report descriptor\n");
32 rdesc[105] = rdesc[110] = 0x03; 32 rdesc[105] = rdesc[110] = 0x03;
33 rdesc[106] = rdesc[111] = 0x21; 33 rdesc[106] = rdesc[111] = 0x21;
34 } 34 }
35 return rdesc;
35} 36}
36 37
37#define sp_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 38#define sp_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-zydacron.c b/drivers/hid/hid-zydacron.c
index 9e8d35a203e4..aac1f9273149 100644
--- a/drivers/hid/hid-zydacron.c
+++ b/drivers/hid/hid-zydacron.c
@@ -27,10 +27,10 @@ struct zc_device {
27* Zydacron remote control has an invalid HID report descriptor, 27* Zydacron remote control has an invalid HID report descriptor,
28* that needs fixing before we can parse it. 28* that needs fixing before we can parse it.
29*/ 29*/
30static void zc_report_fixup(struct hid_device *hdev, __u8 *rdesc, 30static __u8 *zc_report_fixup(struct hid_device *hdev, __u8 *rdesc,
31 unsigned int rsize) 31 unsigned int *rsize)
32{ 32{
33 if (rsize >= 253 && 33 if (*rsize >= 253 &&
34 rdesc[0x96] == 0xbc && rdesc[0x97] == 0xff && 34 rdesc[0x96] == 0xbc && rdesc[0x97] == 0xff &&
35 rdesc[0xca] == 0xbc && rdesc[0xcb] == 0xff && 35 rdesc[0xca] == 0xbc && rdesc[0xcb] == 0xff &&
36 rdesc[0xe1] == 0xbc && rdesc[0xe2] == 0xff) { 36 rdesc[0xe1] == 0xbc && rdesc[0xe2] == 0xff) {
@@ -40,6 +40,7 @@ static void zc_report_fixup(struct hid_device *hdev, __u8 *rdesc,
40 rdesc[0x96] = rdesc[0xca] = rdesc[0xe1] = 0x0c; 40 rdesc[0x96] = rdesc[0xca] = rdesc[0xe1] = 0x0c;
41 rdesc[0x97] = rdesc[0xcb] = rdesc[0xe2] = 0x00; 41 rdesc[0x97] = rdesc[0xcb] = rdesc[0xe2] = 0x00;
42 } 42 }
43 return rdesc;
43} 44}
44 45
45#define zc_map_key_clear(c) \ 46#define zc_map_key_clear(c) \
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 42a0f1d11365..0a34fb071379 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -626,8 +626,8 @@ struct hid_driver {
626 int (*event)(struct hid_device *hdev, struct hid_field *field, 626 int (*event)(struct hid_device *hdev, struct hid_field *field,
627 struct hid_usage *usage, __s32 value); 627 struct hid_usage *usage, __s32 value);
628 628
629 void (*report_fixup)(struct hid_device *hdev, __u8 *buf, 629 __u8 *(*report_fixup)(struct hid_device *hdev, __u8 *buf,
630 unsigned int size); 630 unsigned int *size);
631 631
632 int (*input_mapping)(struct hid_device *hdev, 632 int (*input_mapping)(struct hid_device *hdev,
633 struct hid_input *hidinput, struct hid_field *field, 633 struct hid_input *hidinput, struct hid_field *field,